1
2
3
4
5
6
7#include <linux/if_vlan.h>
8#include <linux/ipv6.h>
9#include <linux/ethtool.h>
10#include <linux/interrupt.h>
11#include <linux/aer.h>
12
13#include "qlcnic.h"
14#include "qlcnic_sriov.h"
15
16static void __qlcnic_83xx_process_aen(struct qlcnic_adapter *);
17static int qlcnic_83xx_clear_lb_mode(struct qlcnic_adapter *, u8);
18static void qlcnic_83xx_configure_mac(struct qlcnic_adapter *, u8 *, u8,
19 struct qlcnic_cmd_args *);
20static int qlcnic_83xx_get_port_config(struct qlcnic_adapter *);
21static irqreturn_t qlcnic_83xx_handle_aen(int, void *);
22static pci_ers_result_t qlcnic_83xx_io_error_detected(struct pci_dev *,
23 pci_channel_state_t);
24static int qlcnic_83xx_set_port_config(struct qlcnic_adapter *);
25static pci_ers_result_t qlcnic_83xx_io_slot_reset(struct pci_dev *);
26static void qlcnic_83xx_io_resume(struct pci_dev *);
27static int qlcnic_83xx_set_lb_mode(struct qlcnic_adapter *, u8);
28static void qlcnic_83xx_set_mac_filter_count(struct qlcnic_adapter *);
29static int qlcnic_83xx_resume(struct qlcnic_adapter *);
30static int qlcnic_83xx_shutdown(struct pci_dev *);
31static void qlcnic_83xx_get_beacon_state(struct qlcnic_adapter *);
32
33#define RSS_HASHTYPE_IP_TCP 0x3
34#define QLC_83XX_FW_MBX_CMD 0
35#define QLC_SKIP_INACTIVE_PCI_REGS 7
36#define QLC_MAX_LEGACY_FUNC_SUPP 8
37
38
39#define QLC_83XX_MODULE_FIBRE_10GBASE_LRM 0x1
40#define QLC_83XX_MODULE_FIBRE_10GBASE_LR 0x2
41#define QLC_83XX_MODULE_FIBRE_10GBASE_SR 0x3
42#define QLC_83XX_MODULE_DA_10GE_PASSIVE_CP 0x4
43
44
45#define QLC_83XX_MODULE_DA_10GE_ACTIVE_CP 0x5
46
47
48#define QLC_83XX_MODULE_DA_10GE_LEGACY_CP 0x6
49
50
51#define QLC_83XX_MODULE_FIBRE_1000BASE_SX 0x7
52#define QLC_83XX_MODULE_FIBRE_1000BASE_LX 0x8
53#define QLC_83XX_MODULE_FIBRE_1000BASE_CX 0x9
54#define QLC_83XX_MODULE_TP_1000BASE_T 0xa
55#define QLC_83XX_MODULE_DA_1GE_PASSIVE_CP 0xb
56
57
58#define QLC_83XX_MODULE_UNKNOWN 0xf
59
60
61#define QLC_83XX_10_CAPABLE BIT_8
62#define QLC_83XX_100_CAPABLE BIT_9
63#define QLC_83XX_1G_CAPABLE BIT_10
64#define QLC_83XX_10G_CAPABLE BIT_11
65#define QLC_83XX_AUTONEG_ENABLE BIT_15
66
67static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = {
68 {QLCNIC_CMD_CONFIGURE_IP_ADDR, 6, 1},
69 {QLCNIC_CMD_CONFIG_INTRPT, 18, 34},
70 {QLCNIC_CMD_CREATE_RX_CTX, 136, 27},
71 {QLCNIC_CMD_DESTROY_RX_CTX, 2, 1},
72 {QLCNIC_CMD_CREATE_TX_CTX, 54, 18},
73 {QLCNIC_CMD_DESTROY_TX_CTX, 2, 1},
74 {QLCNIC_CMD_CONFIGURE_MAC_LEARNING, 2, 1},
75 {QLCNIC_CMD_INTRPT_TEST, 22, 12},
76 {QLCNIC_CMD_SET_MTU, 3, 1},
77 {QLCNIC_CMD_READ_PHY, 4, 2},
78 {QLCNIC_CMD_WRITE_PHY, 5, 1},
79 {QLCNIC_CMD_READ_HW_REG, 4, 1},
80 {QLCNIC_CMD_GET_FLOW_CTL, 4, 2},
81 {QLCNIC_CMD_SET_FLOW_CTL, 4, 1},
82 {QLCNIC_CMD_READ_MAX_MTU, 4, 2},
83 {QLCNIC_CMD_READ_MAX_LRO, 4, 2},
84 {QLCNIC_CMD_MAC_ADDRESS, 4, 3},
85 {QLCNIC_CMD_GET_PCI_INFO, 1, 129},
86 {QLCNIC_CMD_GET_NIC_INFO, 2, 19},
87 {QLCNIC_CMD_SET_NIC_INFO, 32, 1},
88 {QLCNIC_CMD_GET_ESWITCH_CAPABILITY, 4, 3},
89 {QLCNIC_CMD_TOGGLE_ESWITCH, 4, 1},
90 {QLCNIC_CMD_GET_ESWITCH_STATUS, 4, 3},
91 {QLCNIC_CMD_SET_PORTMIRRORING, 4, 1},
92 {QLCNIC_CMD_CONFIGURE_ESWITCH, 4, 1},
93 {QLCNIC_CMD_GET_ESWITCH_PORT_CONFIG, 4, 3},
94 {QLCNIC_CMD_GET_ESWITCH_STATS, 5, 1},
95 {QLCNIC_CMD_CONFIG_PORT, 4, 1},
96 {QLCNIC_CMD_TEMP_SIZE, 1, 4},
97 {QLCNIC_CMD_GET_TEMP_HDR, 5, 5},
98 {QLCNIC_CMD_GET_LINK_EVENT, 2, 1},
99 {QLCNIC_CMD_CONFIG_MAC_VLAN, 4, 3},
100 {QLCNIC_CMD_CONFIG_INTR_COAL, 6, 1},
101 {QLCNIC_CMD_CONFIGURE_RSS, 14, 1},
102 {QLCNIC_CMD_CONFIGURE_LED, 2, 1},
103 {QLCNIC_CMD_CONFIGURE_MAC_RX_MODE, 2, 1},
104 {QLCNIC_CMD_CONFIGURE_HW_LRO, 2, 1},
105 {QLCNIC_CMD_GET_STATISTICS, 2, 80},
106 {QLCNIC_CMD_SET_PORT_CONFIG, 2, 1},
107 {QLCNIC_CMD_GET_PORT_CONFIG, 2, 2},
108 {QLCNIC_CMD_GET_LINK_STATUS, 2, 4},
109 {QLCNIC_CMD_IDC_ACK, 5, 1},
110 {QLCNIC_CMD_INIT_NIC_FUNC, 3, 1},
111 {QLCNIC_CMD_STOP_NIC_FUNC, 2, 1},
112 {QLCNIC_CMD_SET_LED_CONFIG, 5, 1},
113 {QLCNIC_CMD_GET_LED_CONFIG, 1, 5},
114 {QLCNIC_CMD_83XX_SET_DRV_VER, 4, 1},
115 {QLCNIC_CMD_ADD_RCV_RINGS, 130, 26},
116 {QLCNIC_CMD_CONFIG_VPORT, 4, 4},
117 {QLCNIC_CMD_BC_EVENT_SETUP, 2, 1},
118 {QLCNIC_CMD_DCB_QUERY_CAP, 1, 2},
119 {QLCNIC_CMD_DCB_QUERY_PARAM, 1, 50},
120 {QLCNIC_CMD_SET_INGRESS_ENCAP, 2, 1},
121 {QLCNIC_CMD_83XX_EXTEND_ISCSI_DUMP_CAP, 4, 1},
122};
123
124const u32 qlcnic_83xx_ext_reg_tbl[] = {
125 0x38CC,
126 0x38F0,
127 0x38FC,
128 0x3038,
129 0x303C,
130 0x355C,
131 0x3560,
132 0x3564,
133 0x1000,
134 0x1200,
135 0x1204,
136 0x3780,
137 0x3784,
138 0x3788,
139 0x378C,
140 0x3790,
141 0x3794,
142 0x3798,
143 0x379C,
144 0x37A0,
145 0x37A4,
146 0x37A8,
147 0x37AC,
148 0x37B0,
149 0x37B4,
150 0x37B8,
151 0x37BC,
152 0x37C0,
153 0x37C4,
154 0x37C8,
155 0x37CC,
156 0x37D0,
157 0x37D4,
158 0x37D8,
159 0x37DC,
160 0x37E0,
161 0x37E4,
162 0x37F0,
163 0x37F4,
164 0x3868,
165 0x386C,
166 0x3504,
167 0x34A4,
168};
169
170const u32 qlcnic_83xx_reg_tbl[] = {
171 0x34A8,
172 0x34AC,
173 0x34B0,
174 0x3500,
175 0x3528,
176 0x3538,
177 0x3540,
178 0x3544,
179 0x3548,
180 0x354C,
181 0x3524,
182 0x3550,
183 0x3554,
184 0x3558,
185 0x359C,
186 0x35FC,
187 0x3650,
188 0x373C,
189 0x37B4,
190 0x356C,
191 0x3570,
192 0x3850,
193 0x3854,
194};
195
196static struct qlcnic_hardware_ops qlcnic_83xx_hw_ops = {
197 .read_crb = qlcnic_83xx_read_crb,
198 .write_crb = qlcnic_83xx_write_crb,
199 .read_reg = qlcnic_83xx_rd_reg_indirect,
200 .write_reg = qlcnic_83xx_wrt_reg_indirect,
201 .get_mac_address = qlcnic_83xx_get_mac_address,
202 .setup_intr = qlcnic_83xx_setup_intr,
203 .alloc_mbx_args = qlcnic_83xx_alloc_mbx_args,
204 .mbx_cmd = qlcnic_83xx_issue_cmd,
205 .get_func_no = qlcnic_83xx_get_func_no,
206 .api_lock = qlcnic_83xx_cam_lock,
207 .api_unlock = qlcnic_83xx_cam_unlock,
208 .add_sysfs = qlcnic_83xx_add_sysfs,
209 .remove_sysfs = qlcnic_83xx_remove_sysfs,
210 .process_lb_rcv_ring_diag = qlcnic_83xx_process_rcv_ring_diag,
211 .create_rx_ctx = qlcnic_83xx_create_rx_ctx,
212 .create_tx_ctx = qlcnic_83xx_create_tx_ctx,
213 .del_rx_ctx = qlcnic_83xx_del_rx_ctx,
214 .del_tx_ctx = qlcnic_83xx_del_tx_ctx,
215 .setup_link_event = qlcnic_83xx_setup_link_event,
216 .get_nic_info = qlcnic_83xx_get_nic_info,
217 .get_pci_info = qlcnic_83xx_get_pci_info,
218 .set_nic_info = qlcnic_83xx_set_nic_info,
219 .change_macvlan = qlcnic_83xx_sre_macaddr_change,
220 .napi_enable = qlcnic_83xx_napi_enable,
221 .napi_disable = qlcnic_83xx_napi_disable,
222 .config_intr_coal = qlcnic_83xx_config_intr_coal,
223 .config_rss = qlcnic_83xx_config_rss,
224 .config_hw_lro = qlcnic_83xx_config_hw_lro,
225 .config_promisc_mode = qlcnic_83xx_nic_set_promisc,
226 .change_l2_filter = qlcnic_83xx_change_l2_filter,
227 .get_board_info = qlcnic_83xx_get_port_info,
228 .set_mac_filter_count = qlcnic_83xx_set_mac_filter_count,
229 .free_mac_list = qlcnic_82xx_free_mac_list,
230 .io_error_detected = qlcnic_83xx_io_error_detected,
231 .io_slot_reset = qlcnic_83xx_io_slot_reset,
232 .io_resume = qlcnic_83xx_io_resume,
233 .get_beacon_state = qlcnic_83xx_get_beacon_state,
234 .enable_sds_intr = qlcnic_83xx_enable_sds_intr,
235 .disable_sds_intr = qlcnic_83xx_disable_sds_intr,
236 .enable_tx_intr = qlcnic_83xx_enable_tx_intr,
237 .disable_tx_intr = qlcnic_83xx_disable_tx_intr,
238 .get_saved_state = qlcnic_83xx_get_saved_state,
239 .set_saved_state = qlcnic_83xx_set_saved_state,
240 .cache_tmpl_hdr_values = qlcnic_83xx_cache_tmpl_hdr_values,
241 .get_cap_size = qlcnic_83xx_get_cap_size,
242 .set_sys_info = qlcnic_83xx_set_sys_info,
243 .store_cap_mask = qlcnic_83xx_store_cap_mask,
244 .encap_rx_offload = qlcnic_83xx_encap_rx_offload,
245 .encap_tx_offload = qlcnic_83xx_encap_tx_offload,
246};
247
248static struct qlcnic_nic_template qlcnic_83xx_ops = {
249 .config_bridged_mode = qlcnic_config_bridged_mode,
250 .config_led = qlcnic_config_led,
251 .request_reset = qlcnic_83xx_idc_request_reset,
252 .cancel_idc_work = qlcnic_83xx_idc_exit,
253 .napi_add = qlcnic_83xx_napi_add,
254 .napi_del = qlcnic_83xx_napi_del,
255 .config_ipaddr = qlcnic_83xx_config_ipaddr,
256 .clear_legacy_intr = qlcnic_83xx_clear_legacy_intr,
257 .shutdown = qlcnic_83xx_shutdown,
258 .resume = qlcnic_83xx_resume,
259};
260
261void qlcnic_83xx_register_map(struct qlcnic_hardware_context *ahw)
262{
263 ahw->hw_ops = &qlcnic_83xx_hw_ops;
264 ahw->reg_tbl = (u32 *)qlcnic_83xx_reg_tbl;
265 ahw->ext_reg_tbl = (u32 *)qlcnic_83xx_ext_reg_tbl;
266}
267
268int qlcnic_83xx_get_fw_version(struct qlcnic_adapter *adapter)
269{
270 u32 fw_major, fw_minor, fw_build;
271 struct pci_dev *pdev = adapter->pdev;
272
273 fw_major = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MAJOR);
274 fw_minor = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MINOR);
275 fw_build = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_SUB);
276 adapter->fw_version = QLCNIC_VERSION_CODE(fw_major, fw_minor, fw_build);
277
278 dev_info(&pdev->dev, "Driver v%s, firmware version %d.%d.%d\n",
279 QLCNIC_LINUX_VERSIONID, fw_major, fw_minor, fw_build);
280
281 return adapter->fw_version;
282}
283
284static int __qlcnic_set_win_base(struct qlcnic_adapter *adapter, u32 addr)
285{
286 void __iomem *base;
287 u32 val;
288
289 base = adapter->ahw->pci_base0 +
290 QLC_83XX_CRB_WIN_FUNC(adapter->ahw->pci_func);
291 writel(addr, base);
292 val = readl(base);
293 if (val != addr)
294 return -EIO;
295
296 return 0;
297}
298
299int qlcnic_83xx_rd_reg_indirect(struct qlcnic_adapter *adapter, ulong addr,
300 int *err)
301{
302 struct qlcnic_hardware_context *ahw = adapter->ahw;
303
304 *err = __qlcnic_set_win_base(adapter, (u32) addr);
305 if (!*err) {
306 return QLCRDX(ahw, QLCNIC_WILDCARD);
307 } else {
308 dev_err(&adapter->pdev->dev,
309 "%s failed, addr = 0x%lx\n", __func__, addr);
310 return -EIO;
311 }
312}
313
314int qlcnic_83xx_wrt_reg_indirect(struct qlcnic_adapter *adapter, ulong addr,
315 u32 data)
316{
317 int err;
318 struct qlcnic_hardware_context *ahw = adapter->ahw;
319
320 err = __qlcnic_set_win_base(adapter, (u32) addr);
321 if (!err) {
322 QLCWRX(ahw, QLCNIC_WILDCARD, data);
323 return 0;
324 } else {
325 dev_err(&adapter->pdev->dev,
326 "%s failed, addr = 0x%x data = 0x%x\n",
327 __func__, (int)addr, data);
328 return err;
329 }
330}
331
332static void qlcnic_83xx_enable_legacy(struct qlcnic_adapter *adapter)
333{
334 struct qlcnic_hardware_context *ahw = adapter->ahw;
335
336
337 adapter->tgt_status_reg = ahw->pci_base0 + QLC_83XX_INTX_PTR;
338 adapter->tgt_mask_reg = ahw->pci_base0 + QLC_83XX_INTX_MASK;
339 adapter->isr_int_vec = ahw->pci_base0 + QLC_83XX_INTX_TRGR;
340 adapter->msix_entries[0].vector = adapter->pdev->irq;
341 dev_info(&adapter->pdev->dev, "using legacy interrupt\n");
342}
343
344static int qlcnic_83xx_calculate_msix_vector(struct qlcnic_adapter *adapter)
345{
346 int num_msix;
347
348 num_msix = adapter->drv_sds_rings;
349
350
351 num_msix += 1;
352
353 if (!(adapter->flags & QLCNIC_TX_INTR_SHARED))
354 num_msix += adapter->drv_tx_rings;
355
356 return num_msix;
357}
358
359int qlcnic_83xx_setup_intr(struct qlcnic_adapter *adapter)
360{
361 struct qlcnic_hardware_context *ahw = adapter->ahw;
362 int err, i, num_msix;
363
364 if (adapter->flags & QLCNIC_TSS_RSS) {
365 err = qlcnic_setup_tss_rss_intr(adapter);
366 if (err < 0)
367 return err;
368 num_msix = ahw->num_msix;
369 } else {
370 num_msix = qlcnic_83xx_calculate_msix_vector(adapter);
371
372 err = qlcnic_enable_msix(adapter, num_msix);
373 if (err == -ENOMEM)
374 return err;
375
376 if (adapter->flags & QLCNIC_MSIX_ENABLED) {
377 num_msix = ahw->num_msix;
378 } else {
379 if (qlcnic_sriov_vf_check(adapter))
380 return -EINVAL;
381 num_msix = 1;
382 adapter->drv_sds_rings = QLCNIC_SINGLE_RING;
383 adapter->drv_tx_rings = QLCNIC_SINGLE_RING;
384 }
385 }
386
387
388 ahw->intr_tbl =
389 vzalloc(array_size(num_msix,
390 sizeof(struct qlcnic_intrpt_config)));
391 if (!ahw->intr_tbl)
392 return -ENOMEM;
393
394 if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) {
395 if (adapter->ahw->pci_func >= QLC_MAX_LEGACY_FUNC_SUPP) {
396 dev_err(&adapter->pdev->dev, "PCI function number 8 and higher are not supported with legacy interrupt, func 0x%x\n",
397 ahw->pci_func);
398 return -EOPNOTSUPP;
399 }
400
401 qlcnic_83xx_enable_legacy(adapter);
402 }
403
404 for (i = 0; i < num_msix; i++) {
405 if (adapter->flags & QLCNIC_MSIX_ENABLED)
406 ahw->intr_tbl[i].type = QLCNIC_INTRPT_MSIX;
407 else
408 ahw->intr_tbl[i].type = QLCNIC_INTRPT_INTX;
409 ahw->intr_tbl[i].id = i;
410 ahw->intr_tbl[i].src = 0;
411 }
412
413 return 0;
414}
415
416static inline void qlcnic_83xx_clear_legacy_intr_mask(struct qlcnic_adapter *adapter)
417{
418 writel(0, adapter->tgt_mask_reg);
419}
420
421static inline void qlcnic_83xx_set_legacy_intr_mask(struct qlcnic_adapter *adapter)
422{
423 if (adapter->tgt_mask_reg)
424 writel(1, adapter->tgt_mask_reg);
425}
426
427static inline void qlcnic_83xx_enable_legacy_msix_mbx_intr(struct qlcnic_adapter
428 *adapter)
429{
430 u32 mask;
431
432
433
434
435
436
437 mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
438 writel(0, adapter->ahw->pci_base0 + mask);
439}
440
441void qlcnic_83xx_disable_mbx_intr(struct qlcnic_adapter *adapter)
442{
443 u32 mask;
444
445 mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
446 writel(1, adapter->ahw->pci_base0 + mask);
447 QLCWRX(adapter->ahw, QLCNIC_MBX_INTR_ENBL, 0);
448}
449
450static inline void qlcnic_83xx_get_mbx_data(struct qlcnic_adapter *adapter,
451 struct qlcnic_cmd_args *cmd)
452{
453 int i;
454
455 if (cmd->op_type == QLC_83XX_MBX_POST_BC_OP)
456 return;
457
458 for (i = 0; i < cmd->rsp.num; i++)
459 cmd->rsp.arg[i] = readl(QLCNIC_MBX_FW(adapter->ahw, i));
460}
461
462irqreturn_t qlcnic_83xx_clear_legacy_intr(struct qlcnic_adapter *adapter)
463{
464 u32 intr_val;
465 struct qlcnic_hardware_context *ahw = adapter->ahw;
466 int retries = 0;
467
468 intr_val = readl(adapter->tgt_status_reg);
469
470 if (!QLC_83XX_VALID_INTX_BIT31(intr_val))
471 return IRQ_NONE;
472
473 if (QLC_83XX_INTX_FUNC(intr_val) != adapter->ahw->pci_func) {
474 adapter->stats.spurious_intr++;
475 return IRQ_NONE;
476 }
477
478 wmb();
479
480
481 writel_relaxed(0, adapter->isr_int_vec);
482 intr_val = readl(adapter->isr_int_vec);
483 do {
484 intr_val = readl(adapter->tgt_status_reg);
485 if (QLC_83XX_INTX_FUNC(intr_val) != ahw->pci_func)
486 break;
487 retries++;
488 } while (QLC_83XX_VALID_INTX_BIT30(intr_val) &&
489 (retries < QLC_83XX_LEGACY_INTX_MAX_RETRY));
490
491 return IRQ_HANDLED;
492}
493
494static inline void qlcnic_83xx_notify_mbx_response(struct qlcnic_mailbox *mbx)
495{
496 mbx->rsp_status = QLC_83XX_MBX_RESPONSE_ARRIVED;
497 complete(&mbx->completion);
498}
499
500static void qlcnic_83xx_poll_process_aen(struct qlcnic_adapter *adapter)
501{
502 u32 resp, event, rsp_status = QLC_83XX_MBX_RESPONSE_ARRIVED;
503 struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
504 unsigned long flags;
505
506 spin_lock_irqsave(&mbx->aen_lock, flags);
507 resp = QLCRDX(adapter->ahw, QLCNIC_FW_MBX_CTRL);
508 if (!(resp & QLCNIC_SET_OWNER))
509 goto out;
510
511 event = readl(QLCNIC_MBX_FW(adapter->ahw, 0));
512 if (event & QLCNIC_MBX_ASYNC_EVENT) {
513 __qlcnic_83xx_process_aen(adapter);
514 } else {
515 if (mbx->rsp_status != rsp_status)
516 qlcnic_83xx_notify_mbx_response(mbx);
517 }
518out:
519 qlcnic_83xx_enable_legacy_msix_mbx_intr(adapter);
520 spin_unlock_irqrestore(&mbx->aen_lock, flags);
521}
522
523irqreturn_t qlcnic_83xx_intr(int irq, void *data)
524{
525 struct qlcnic_adapter *adapter = data;
526 struct qlcnic_host_sds_ring *sds_ring;
527 struct qlcnic_hardware_context *ahw = adapter->ahw;
528
529 if (qlcnic_83xx_clear_legacy_intr(adapter) == IRQ_NONE)
530 return IRQ_NONE;
531
532 qlcnic_83xx_poll_process_aen(adapter);
533
534 if (ahw->diag_test) {
535 if (ahw->diag_test == QLCNIC_INTERRUPT_TEST)
536 ahw->diag_cnt++;
537 qlcnic_83xx_enable_legacy_msix_mbx_intr(adapter);
538 return IRQ_HANDLED;
539 }
540
541 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
542 qlcnic_83xx_enable_legacy_msix_mbx_intr(adapter);
543 } else {
544 sds_ring = &adapter->recv_ctx->sds_rings[0];
545 napi_schedule(&sds_ring->napi);
546 }
547
548 return IRQ_HANDLED;
549}
550
551irqreturn_t qlcnic_83xx_tmp_intr(int irq, void *data)
552{
553 struct qlcnic_host_sds_ring *sds_ring = data;
554 struct qlcnic_adapter *adapter = sds_ring->adapter;
555
556 if (adapter->flags & QLCNIC_MSIX_ENABLED)
557 goto done;
558
559 if (adapter->nic_ops->clear_legacy_intr(adapter) == IRQ_NONE)
560 return IRQ_NONE;
561
562done:
563 adapter->ahw->diag_cnt++;
564 qlcnic_enable_sds_intr(adapter, sds_ring);
565
566 return IRQ_HANDLED;
567}
568
569void qlcnic_83xx_free_mbx_intr(struct qlcnic_adapter *adapter)
570{
571 u32 num_msix;
572
573 if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
574 qlcnic_83xx_set_legacy_intr_mask(adapter);
575
576 qlcnic_83xx_disable_mbx_intr(adapter);
577
578 if (adapter->flags & QLCNIC_MSIX_ENABLED)
579 num_msix = adapter->ahw->num_msix - 1;
580 else
581 num_msix = 0;
582
583 msleep(20);
584
585 if (adapter->msix_entries) {
586 synchronize_irq(adapter->msix_entries[num_msix].vector);
587 free_irq(adapter->msix_entries[num_msix].vector, adapter);
588 }
589}
590
591int qlcnic_83xx_setup_mbx_intr(struct qlcnic_adapter *adapter)
592{
593 irq_handler_t handler;
594 u32 val;
595 int err = 0;
596 unsigned long flags = 0;
597
598 if (!(adapter->flags & QLCNIC_MSI_ENABLED) &&
599 !(adapter->flags & QLCNIC_MSIX_ENABLED))
600 flags |= IRQF_SHARED;
601
602 if (adapter->flags & QLCNIC_MSIX_ENABLED) {
603 handler = qlcnic_83xx_handle_aen;
604 val = adapter->msix_entries[adapter->ahw->num_msix - 1].vector;
605 err = request_irq(val, handler, flags, "qlcnic-MB", adapter);
606 if (err) {
607 dev_err(&adapter->pdev->dev,
608 "failed to register MBX interrupt\n");
609 return err;
610 }
611 } else {
612 handler = qlcnic_83xx_intr;
613 val = adapter->msix_entries[0].vector;
614 err = request_irq(val, handler, flags, "qlcnic", adapter);
615 if (err) {
616 dev_err(&adapter->pdev->dev,
617 "failed to register INTx interrupt\n");
618 return err;
619 }
620 qlcnic_83xx_clear_legacy_intr_mask(adapter);
621 }
622
623
624 qlcnic_83xx_enable_mbx_interrupt(adapter);
625
626 return err;
627}
628
629void qlcnic_83xx_get_func_no(struct qlcnic_adapter *adapter)
630{
631 u32 val = QLCRDX(adapter->ahw, QLCNIC_INFORMANT);
632 adapter->ahw->pci_func = (val >> 24) & 0xff;
633}
634
635int qlcnic_83xx_cam_lock(struct qlcnic_adapter *adapter)
636{
637 void __iomem *addr;
638 u32 val, limit = 0;
639
640 struct qlcnic_hardware_context *ahw = adapter->ahw;
641
642 addr = ahw->pci_base0 + QLC_83XX_SEM_LOCK_FUNC(ahw->pci_func);
643 do {
644 val = readl(addr);
645 if (val) {
646
647 QLC_SHARED_REG_WR32(adapter, QLCNIC_FLASH_LOCK_OWNER,
648 ahw->pci_func);
649 return 0;
650 }
651 usleep_range(1000, 2000);
652 } while (++limit <= QLCNIC_PCIE_SEM_TIMEOUT);
653
654 return -EIO;
655}
656
657void qlcnic_83xx_cam_unlock(struct qlcnic_adapter *adapter)
658{
659 void __iomem *addr;
660 struct qlcnic_hardware_context *ahw = adapter->ahw;
661
662 addr = ahw->pci_base0 + QLC_83XX_SEM_UNLOCK_FUNC(ahw->pci_func);
663 readl(addr);
664}
665
666void qlcnic_83xx_read_crb(struct qlcnic_adapter *adapter, char *buf,
667 loff_t offset, size_t size)
668{
669 int ret = 0;
670 u32 data;
671
672 if (qlcnic_api_lock(adapter)) {
673 dev_err(&adapter->pdev->dev,
674 "%s: failed to acquire lock. addr offset 0x%x\n",
675 __func__, (u32)offset);
676 return;
677 }
678
679 data = QLCRD32(adapter, (u32) offset, &ret);
680 qlcnic_api_unlock(adapter);
681
682 if (ret == -EIO) {
683 dev_err(&adapter->pdev->dev,
684 "%s: failed. addr offset 0x%x\n",
685 __func__, (u32)offset);
686 return;
687 }
688 memcpy(buf, &data, size);
689}
690
691void qlcnic_83xx_write_crb(struct qlcnic_adapter *adapter, char *buf,
692 loff_t offset, size_t size)
693{
694 u32 data;
695
696 memcpy(&data, buf, size);
697 qlcnic_83xx_wrt_reg_indirect(adapter, (u32) offset, data);
698}
699
700int qlcnic_83xx_get_port_info(struct qlcnic_adapter *adapter)
701{
702 struct qlcnic_hardware_context *ahw = adapter->ahw;
703 int status;
704
705 status = qlcnic_83xx_get_port_config(adapter);
706 if (status) {
707 dev_err(&adapter->pdev->dev,
708 "Get Port Info failed\n");
709 } else {
710
711 if (ahw->port_config & QLC_83XX_10G_CAPABLE) {
712 ahw->port_type = QLCNIC_XGBE;
713 } else if (ahw->port_config & QLC_83XX_10_CAPABLE ||
714 ahw->port_config & QLC_83XX_100_CAPABLE ||
715 ahw->port_config & QLC_83XX_1G_CAPABLE) {
716 ahw->port_type = QLCNIC_GBE;
717 } else {
718 ahw->port_type = QLCNIC_XGBE;
719 }
720
721 if (QLC_83XX_AUTONEG(ahw->port_config))
722 ahw->link_autoneg = AUTONEG_ENABLE;
723
724 }
725 return status;
726}
727
728static void qlcnic_83xx_set_mac_filter_count(struct qlcnic_adapter *adapter)
729{
730 struct qlcnic_hardware_context *ahw = adapter->ahw;
731 u16 act_pci_fn = ahw->total_nic_func;
732 u16 count;
733
734 ahw->max_mc_count = QLC_83XX_MAX_MC_COUNT;
735 if (act_pci_fn <= 2)
736 count = (QLC_83XX_MAX_UC_COUNT - QLC_83XX_MAX_MC_COUNT) /
737 act_pci_fn;
738 else
739 count = (QLC_83XX_LB_MAX_FILTERS - QLC_83XX_MAX_MC_COUNT) /
740 act_pci_fn;
741 ahw->max_uc_count = count;
742}
743
744void qlcnic_83xx_enable_mbx_interrupt(struct qlcnic_adapter *adapter)
745{
746 u32 val;
747
748 if (adapter->flags & QLCNIC_MSIX_ENABLED)
749 val = BIT_2 | ((adapter->ahw->num_msix - 1) << 8);
750 else
751 val = BIT_2;
752
753 QLCWRX(adapter->ahw, QLCNIC_MBX_INTR_ENBL, val);
754 qlcnic_83xx_enable_legacy_msix_mbx_intr(adapter);
755}
756
757void qlcnic_83xx_check_vf(struct qlcnic_adapter *adapter,
758 const struct pci_device_id *ent)
759{
760 u32 op_mode, priv_level;
761 struct qlcnic_hardware_context *ahw = adapter->ahw;
762
763 ahw->fw_hal_version = 2;
764 qlcnic_get_func_no(adapter);
765
766 if (qlcnic_sriov_vf_check(adapter)) {
767 qlcnic_sriov_vf_set_ops(adapter);
768 return;
769 }
770
771
772 op_mode = QLCRDX(adapter->ahw, QLC_83XX_DRV_OP_MODE);
773 if (op_mode == QLC_83XX_DEFAULT_OPMODE)
774 priv_level = QLCNIC_MGMT_FUNC;
775 else
776 priv_level = QLC_83XX_GET_FUNC_PRIVILEGE(op_mode,
777 ahw->pci_func);
778
779 if (priv_level == QLCNIC_NON_PRIV_FUNC) {
780 ahw->op_mode = QLCNIC_NON_PRIV_FUNC;
781 dev_info(&adapter->pdev->dev,
782 "HAL Version: %d Non Privileged function\n",
783 ahw->fw_hal_version);
784 adapter->nic_ops = &qlcnic_vf_ops;
785 } else {
786 if (pci_find_ext_capability(adapter->pdev,
787 PCI_EXT_CAP_ID_SRIOV))
788 set_bit(__QLCNIC_SRIOV_CAPABLE, &adapter->state);
789 adapter->nic_ops = &qlcnic_83xx_ops;
790 }
791}
792
793static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter,
794 u32 data[]);
795static void qlcnic_83xx_handle_idc_comp_aen(struct qlcnic_adapter *adapter,
796 u32 data[]);
797
798void qlcnic_dump_mbx(struct qlcnic_adapter *adapter,
799 struct qlcnic_cmd_args *cmd)
800{
801 int i;
802
803 if (cmd->op_type == QLC_83XX_MBX_POST_BC_OP)
804 return;
805
806 dev_info(&adapter->pdev->dev,
807 "Host MBX regs(%d)\n", cmd->req.num);
808 for (i = 0; i < cmd->req.num; i++) {
809 if (i && !(i % 8))
810 pr_info("\n");
811 pr_info("%08x ", cmd->req.arg[i]);
812 }
813 pr_info("\n");
814 dev_info(&adapter->pdev->dev,
815 "FW MBX regs(%d)\n", cmd->rsp.num);
816 for (i = 0; i < cmd->rsp.num; i++) {
817 if (i && !(i % 8))
818 pr_info("\n");
819 pr_info("%08x ", cmd->rsp.arg[i]);
820 }
821 pr_info("\n");
822}
823
824static void qlcnic_83xx_poll_for_mbx_completion(struct qlcnic_adapter *adapter,
825 struct qlcnic_cmd_args *cmd)
826{
827 struct qlcnic_hardware_context *ahw = adapter->ahw;
828 int opcode = LSW(cmd->req.arg[0]);
829 unsigned long max_loops;
830
831 max_loops = cmd->total_cmds * QLC_83XX_MBX_CMD_LOOP;
832
833 for (; max_loops; max_loops--) {
834 if (atomic_read(&cmd->rsp_status) ==
835 QLC_83XX_MBX_RESPONSE_ARRIVED)
836 return;
837
838 udelay(1);
839 }
840
841 dev_err(&adapter->pdev->dev,
842 "%s: Mailbox command timed out, cmd_op=0x%x, cmd_type=0x%x, pci_func=0x%x, op_mode=0x%x\n",
843 __func__, opcode, cmd->type, ahw->pci_func, ahw->op_mode);
844 flush_workqueue(ahw->mailbox->work_q);
845 return;
846}
847
848int qlcnic_83xx_issue_cmd(struct qlcnic_adapter *adapter,
849 struct qlcnic_cmd_args *cmd)
850{
851 struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
852 struct qlcnic_hardware_context *ahw = adapter->ahw;
853 int cmd_type, err, opcode;
854 unsigned long timeout;
855
856 if (!mbx)
857 return -EIO;
858
859 opcode = LSW(cmd->req.arg[0]);
860 cmd_type = cmd->type;
861 err = mbx->ops->enqueue_cmd(adapter, cmd, &timeout);
862 if (err) {
863 dev_err(&adapter->pdev->dev,
864 "%s: Mailbox not available, cmd_op=0x%x, cmd_context=0x%x, pci_func=0x%x, op_mode=0x%x\n",
865 __func__, opcode, cmd->type, ahw->pci_func,
866 ahw->op_mode);
867 return err;
868 }
869
870 switch (cmd_type) {
871 case QLC_83XX_MBX_CMD_WAIT:
872 if (!wait_for_completion_timeout(&cmd->completion, timeout)) {
873 dev_err(&adapter->pdev->dev,
874 "%s: Mailbox command timed out, cmd_op=0x%x, cmd_type=0x%x, pci_func=0x%x, op_mode=0x%x\n",
875 __func__, opcode, cmd_type, ahw->pci_func,
876 ahw->op_mode);
877 flush_workqueue(mbx->work_q);
878 }
879 break;
880 case QLC_83XX_MBX_CMD_NO_WAIT:
881 return 0;
882 case QLC_83XX_MBX_CMD_BUSY_WAIT:
883 qlcnic_83xx_poll_for_mbx_completion(adapter, cmd);
884 break;
885 default:
886 dev_err(&adapter->pdev->dev,
887 "%s: Invalid mailbox command, cmd_op=0x%x, cmd_type=0x%x, pci_func=0x%x, op_mode=0x%x\n",
888 __func__, opcode, cmd_type, ahw->pci_func,
889 ahw->op_mode);
890 qlcnic_83xx_detach_mailbox_work(adapter);
891 }
892
893 return cmd->rsp_opcode;
894}
895
896int qlcnic_83xx_alloc_mbx_args(struct qlcnic_cmd_args *mbx,
897 struct qlcnic_adapter *adapter, u32 type)
898{
899 int i, size;
900 u32 temp;
901 const struct qlcnic_mailbox_metadata *mbx_tbl;
902
903 memset(mbx, 0, sizeof(struct qlcnic_cmd_args));
904 mbx_tbl = qlcnic_83xx_mbx_tbl;
905 size = ARRAY_SIZE(qlcnic_83xx_mbx_tbl);
906 for (i = 0; i < size; i++) {
907 if (type == mbx_tbl[i].cmd) {
908 mbx->op_type = QLC_83XX_FW_MBX_CMD;
909 mbx->req.num = mbx_tbl[i].in_args;
910 mbx->rsp.num = mbx_tbl[i].out_args;
911 mbx->req.arg = kcalloc(mbx->req.num, sizeof(u32),
912 GFP_ATOMIC);
913 if (!mbx->req.arg)
914 return -ENOMEM;
915 mbx->rsp.arg = kcalloc(mbx->rsp.num, sizeof(u32),
916 GFP_ATOMIC);
917 if (!mbx->rsp.arg) {
918 kfree(mbx->req.arg);
919 mbx->req.arg = NULL;
920 return -ENOMEM;
921 }
922 temp = adapter->ahw->fw_hal_version << 29;
923 mbx->req.arg[0] = (type | (mbx->req.num << 16) | temp);
924 mbx->cmd_op = type;
925 return 0;
926 }
927 }
928
929 dev_err(&adapter->pdev->dev, "%s: Invalid mailbox command opcode 0x%x\n",
930 __func__, type);
931 return -EINVAL;
932}
933
934void qlcnic_83xx_idc_aen_work(struct work_struct *work)
935{
936 struct qlcnic_adapter *adapter;
937 struct qlcnic_cmd_args cmd;
938 int i, err = 0;
939
940 adapter = container_of(work, struct qlcnic_adapter, idc_aen_work.work);
941 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_IDC_ACK);
942 if (err)
943 return;
944
945 for (i = 1; i < QLC_83XX_MBX_AEN_CNT; i++)
946 cmd.req.arg[i] = adapter->ahw->mbox_aen[i];
947
948 err = qlcnic_issue_cmd(adapter, &cmd);
949 if (err)
950 dev_info(&adapter->pdev->dev,
951 "%s: Mailbox IDC ACK failed.\n", __func__);
952 qlcnic_free_mbx_args(&cmd);
953}
954
955static void qlcnic_83xx_handle_idc_comp_aen(struct qlcnic_adapter *adapter,
956 u32 data[])
957{
958 dev_dbg(&adapter->pdev->dev, "Completion AEN:0x%x.\n",
959 QLCNIC_MBX_RSP(data[0]));
960 clear_bit(QLC_83XX_IDC_COMP_AEN, &adapter->ahw->idc.status);
961 return;
962}
963
964static void __qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
965{
966 struct qlcnic_hardware_context *ahw = adapter->ahw;
967 u32 event[QLC_83XX_MBX_AEN_CNT];
968 int i;
969
970 for (i = 0; i < QLC_83XX_MBX_AEN_CNT; i++)
971 event[i] = readl(QLCNIC_MBX_FW(ahw, i));
972
973 switch (QLCNIC_MBX_RSP(event[0])) {
974
975 case QLCNIC_MBX_LINK_EVENT:
976 qlcnic_83xx_handle_link_aen(adapter, event);
977 break;
978 case QLCNIC_MBX_COMP_EVENT:
979 qlcnic_83xx_handle_idc_comp_aen(adapter, event);
980 break;
981 case QLCNIC_MBX_REQUEST_EVENT:
982 for (i = 0; i < QLC_83XX_MBX_AEN_CNT; i++)
983 adapter->ahw->mbox_aen[i] = QLCNIC_MBX_RSP(event[i]);
984 queue_delayed_work(adapter->qlcnic_wq,
985 &adapter->idc_aen_work, 0);
986 break;
987 case QLCNIC_MBX_TIME_EXTEND_EVENT:
988 ahw->extend_lb_time = event[1] >> 8 & 0xf;
989 break;
990 case QLCNIC_MBX_BC_EVENT:
991 qlcnic_sriov_handle_bc_event(adapter, event[1]);
992 break;
993 case QLCNIC_MBX_SFP_INSERT_EVENT:
994 dev_info(&adapter->pdev->dev, "SFP+ Insert AEN:0x%x.\n",
995 QLCNIC_MBX_RSP(event[0]));
996 break;
997 case QLCNIC_MBX_SFP_REMOVE_EVENT:
998 dev_info(&adapter->pdev->dev, "SFP Removed AEN:0x%x.\n",
999 QLCNIC_MBX_RSP(event[0]));
1000 break;
1001 case QLCNIC_MBX_DCBX_CONFIG_CHANGE_EVENT:
1002 qlcnic_dcb_aen_handler(adapter->dcb, (void *)&event[1]);
1003 break;
1004 default:
1005 dev_dbg(&adapter->pdev->dev, "Unsupported AEN:0x%x.\n",
1006 QLCNIC_MBX_RSP(event[0]));
1007 break;
1008 }
1009
1010 QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
1011}
1012
1013static void qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
1014{
1015 u32 resp, event, rsp_status = QLC_83XX_MBX_RESPONSE_ARRIVED;
1016 struct qlcnic_hardware_context *ahw = adapter->ahw;
1017 struct qlcnic_mailbox *mbx = ahw->mailbox;
1018 unsigned long flags;
1019
1020 spin_lock_irqsave(&mbx->aen_lock, flags);
1021 resp = QLCRDX(ahw, QLCNIC_FW_MBX_CTRL);
1022 if (resp & QLCNIC_SET_OWNER) {
1023 event = readl(QLCNIC_MBX_FW(ahw, 0));
1024 if (event & QLCNIC_MBX_ASYNC_EVENT) {
1025 __qlcnic_83xx_process_aen(adapter);
1026 } else {
1027 if (mbx->rsp_status != rsp_status)
1028 qlcnic_83xx_notify_mbx_response(mbx);
1029 }
1030 }
1031 spin_unlock_irqrestore(&mbx->aen_lock, flags);
1032}
1033
1034static void qlcnic_83xx_mbx_poll_work(struct work_struct *work)
1035{
1036 struct qlcnic_adapter *adapter;
1037
1038 adapter = container_of(work, struct qlcnic_adapter, mbx_poll_work.work);
1039
1040 if (!test_bit(__QLCNIC_MBX_POLL_ENABLE, &adapter->state))
1041 return;
1042
1043 qlcnic_83xx_process_aen(adapter);
1044 queue_delayed_work(adapter->qlcnic_wq, &adapter->mbx_poll_work,
1045 (HZ / 10));
1046}
1047
1048void qlcnic_83xx_enable_mbx_poll(struct qlcnic_adapter *adapter)
1049{
1050 if (test_and_set_bit(__QLCNIC_MBX_POLL_ENABLE, &adapter->state))
1051 return;
1052
1053 INIT_DELAYED_WORK(&adapter->mbx_poll_work, qlcnic_83xx_mbx_poll_work);
1054 queue_delayed_work(adapter->qlcnic_wq, &adapter->mbx_poll_work, 0);
1055}
1056
1057void qlcnic_83xx_disable_mbx_poll(struct qlcnic_adapter *adapter)
1058{
1059 if (!test_and_clear_bit(__QLCNIC_MBX_POLL_ENABLE, &adapter->state))
1060 return;
1061 cancel_delayed_work_sync(&adapter->mbx_poll_work);
1062}
1063
1064static int qlcnic_83xx_add_rings(struct qlcnic_adapter *adapter)
1065{
1066 int index, i, err, sds_mbx_size;
1067 u32 *buf, intrpt_id, intr_mask;
1068 u16 context_id;
1069 u8 num_sds;
1070 struct qlcnic_cmd_args cmd;
1071 struct qlcnic_host_sds_ring *sds;
1072 struct qlcnic_sds_mbx sds_mbx;
1073 struct qlcnic_add_rings_mbx_out *mbx_out;
1074 struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
1075 struct qlcnic_hardware_context *ahw = adapter->ahw;
1076
1077 sds_mbx_size = sizeof(struct qlcnic_sds_mbx);
1078 context_id = recv_ctx->context_id;
1079 num_sds = adapter->drv_sds_rings - QLCNIC_MAX_SDS_RINGS;
1080 ahw->hw_ops->alloc_mbx_args(&cmd, adapter,
1081 QLCNIC_CMD_ADD_RCV_RINGS);
1082 cmd.req.arg[1] = 0 | (num_sds << 8) | (context_id << 16);
1083
1084
1085 index = 2;
1086 for (i = 8; i < adapter->drv_sds_rings; i++) {
1087 memset(&sds_mbx, 0, sds_mbx_size);
1088 sds = &recv_ctx->sds_rings[i];
1089 sds->consumer = 0;
1090 memset(sds->desc_head, 0, STATUS_DESC_RINGSIZE(sds));
1091 sds_mbx.phy_addr_low = LSD(sds->phys_addr);
1092 sds_mbx.phy_addr_high = MSD(sds->phys_addr);
1093 sds_mbx.sds_ring_size = sds->num_desc;
1094
1095 if (adapter->flags & QLCNIC_MSIX_ENABLED)
1096 intrpt_id = ahw->intr_tbl[i].id;
1097 else
1098 intrpt_id = QLCRDX(ahw, QLCNIC_DEF_INT_ID);
1099
1100 if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST)
1101 sds_mbx.intrpt_id = intrpt_id;
1102 else
1103 sds_mbx.intrpt_id = 0xffff;
1104 sds_mbx.intrpt_val = 0;
1105 buf = &cmd.req.arg[index];
1106 memcpy(buf, &sds_mbx, sds_mbx_size);
1107 index += sds_mbx_size / sizeof(u32);
1108 }
1109
1110
1111 err = ahw->hw_ops->mbx_cmd(adapter, &cmd);
1112 if (err) {
1113 dev_err(&adapter->pdev->dev,
1114 "Failed to add rings %d\n", err);
1115 goto out;
1116 }
1117
1118 mbx_out = (struct qlcnic_add_rings_mbx_out *)&cmd.rsp.arg[1];
1119 index = 0;
1120
1121 for (i = 8; i < adapter->drv_sds_rings; i++) {
1122 sds = &recv_ctx->sds_rings[i];
1123 sds->crb_sts_consumer = ahw->pci_base0 +
1124 mbx_out->host_csmr[index];
1125 if (adapter->flags & QLCNIC_MSIX_ENABLED)
1126 intr_mask = ahw->intr_tbl[i].src;
1127 else
1128 intr_mask = QLCRDX(ahw, QLCNIC_DEF_INT_MASK);
1129
1130 sds->crb_intr_mask = ahw->pci_base0 + intr_mask;
1131 index++;
1132 }
1133out:
1134 qlcnic_free_mbx_args(&cmd);
1135 return err;
1136}
1137
1138void qlcnic_83xx_del_rx_ctx(struct qlcnic_adapter *adapter)
1139{
1140 int err;
1141 u32 temp = 0;
1142 struct qlcnic_cmd_args cmd;
1143 struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
1144
1145 if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_DESTROY_RX_CTX))
1146 return;
1147
1148 if (qlcnic_sriov_pf_check(adapter) || qlcnic_sriov_vf_check(adapter))
1149 cmd.req.arg[0] |= (0x3 << 29);
1150
1151 if (qlcnic_sriov_pf_check(adapter))
1152 qlcnic_pf_set_interface_id_del_rx_ctx(adapter, &temp);
1153
1154 cmd.req.arg[1] = recv_ctx->context_id | temp;
1155 err = qlcnic_issue_cmd(adapter, &cmd);
1156 if (err)
1157 dev_err(&adapter->pdev->dev,
1158 "Failed to destroy rx ctx in firmware\n");
1159
1160 recv_ctx->state = QLCNIC_HOST_CTX_STATE_FREED;
1161 qlcnic_free_mbx_args(&cmd);
1162}
1163
1164int qlcnic_83xx_create_rx_ctx(struct qlcnic_adapter *adapter)
1165{
1166 int i, err, index, sds_mbx_size, rds_mbx_size;
1167 u8 num_sds, num_rds;
1168 u32 *buf, intrpt_id, intr_mask, cap = 0;
1169 struct qlcnic_host_sds_ring *sds;
1170 struct qlcnic_host_rds_ring *rds;
1171 struct qlcnic_sds_mbx sds_mbx;
1172 struct qlcnic_rds_mbx rds_mbx;
1173 struct qlcnic_cmd_args cmd;
1174 struct qlcnic_rcv_mbx_out *mbx_out;
1175 struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
1176 struct qlcnic_hardware_context *ahw = adapter->ahw;
1177 num_rds = adapter->max_rds_rings;
1178
1179 if (adapter->drv_sds_rings <= QLCNIC_MAX_SDS_RINGS)
1180 num_sds = adapter->drv_sds_rings;
1181 else
1182 num_sds = QLCNIC_MAX_SDS_RINGS;
1183
1184 sds_mbx_size = sizeof(struct qlcnic_sds_mbx);
1185 rds_mbx_size = sizeof(struct qlcnic_rds_mbx);
1186 cap = QLCNIC_CAP0_LEGACY_CONTEXT;
1187
1188 if (adapter->flags & QLCNIC_FW_LRO_MSS_CAP)
1189 cap |= QLC_83XX_FW_CAP_LRO_MSS;
1190
1191
1192 err = qlcnic_alloc_mbx_args(&cmd, adapter,
1193 QLCNIC_CMD_CREATE_RX_CTX);
1194 if (err)
1195 return err;
1196
1197 if (qlcnic_sriov_pf_check(adapter) || qlcnic_sriov_vf_check(adapter))
1198 cmd.req.arg[0] |= (0x3 << 29);
1199
1200 cmd.req.arg[1] = cap;
1201 cmd.req.arg[5] = 1 | (num_rds << 5) | (num_sds << 8) |
1202 (QLC_83XX_HOST_RDS_MODE_UNIQUE << 16);
1203
1204 if (qlcnic_sriov_pf_check(adapter))
1205 qlcnic_pf_set_interface_id_create_rx_ctx(adapter,
1206 &cmd.req.arg[6]);
1207
1208 index = QLC_83XX_HOST_SDS_MBX_IDX;
1209 for (i = 0; i < num_sds; i++) {
1210 memset(&sds_mbx, 0, sds_mbx_size);
1211 sds = &recv_ctx->sds_rings[i];
1212 sds->consumer = 0;
1213 memset(sds->desc_head, 0, STATUS_DESC_RINGSIZE(sds));
1214 sds_mbx.phy_addr_low = LSD(sds->phys_addr);
1215 sds_mbx.phy_addr_high = MSD(sds->phys_addr);
1216 sds_mbx.sds_ring_size = sds->num_desc;
1217 if (adapter->flags & QLCNIC_MSIX_ENABLED)
1218 intrpt_id = ahw->intr_tbl[i].id;
1219 else
1220 intrpt_id = QLCRDX(ahw, QLCNIC_DEF_INT_ID);
1221 if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST)
1222 sds_mbx.intrpt_id = intrpt_id;
1223 else
1224 sds_mbx.intrpt_id = 0xffff;
1225 sds_mbx.intrpt_val = 0;
1226 buf = &cmd.req.arg[index];
1227 memcpy(buf, &sds_mbx, sds_mbx_size);
1228 index += sds_mbx_size / sizeof(u32);
1229 }
1230
1231 index = QLCNIC_HOST_RDS_MBX_IDX;
1232 rds = &recv_ctx->rds_rings[0];
1233 rds->producer = 0;
1234 memset(&rds_mbx, 0, rds_mbx_size);
1235 rds_mbx.phy_addr_reg_low = LSD(rds->phys_addr);
1236 rds_mbx.phy_addr_reg_high = MSD(rds->phys_addr);
1237 rds_mbx.reg_ring_sz = rds->dma_size;
1238 rds_mbx.reg_ring_len = rds->num_desc;
1239
1240 rds = &recv_ctx->rds_rings[1];
1241 rds->producer = 0;
1242 rds_mbx.phy_addr_jmb_low = LSD(rds->phys_addr);
1243 rds_mbx.phy_addr_jmb_high = MSD(rds->phys_addr);
1244 rds_mbx.jmb_ring_sz = rds->dma_size;
1245 rds_mbx.jmb_ring_len = rds->num_desc;
1246 buf = &cmd.req.arg[index];
1247 memcpy(buf, &rds_mbx, rds_mbx_size);
1248
1249
1250 err = ahw->hw_ops->mbx_cmd(adapter, &cmd);
1251 if (err) {
1252 dev_err(&adapter->pdev->dev,
1253 "Failed to create Rx ctx in firmware%d\n", err);
1254 goto out;
1255 }
1256 mbx_out = (struct qlcnic_rcv_mbx_out *)&cmd.rsp.arg[1];
1257 recv_ctx->context_id = mbx_out->ctx_id;
1258 recv_ctx->state = mbx_out->state;
1259 recv_ctx->virt_port = mbx_out->vport_id;
1260 dev_info(&adapter->pdev->dev, "Rx Context[%d] Created, state:0x%x\n",
1261 recv_ctx->context_id, recv_ctx->state);
1262
1263
1264 rds = &recv_ctx->rds_rings[0];
1265 rds->crb_rcv_producer = ahw->pci_base0 +
1266 mbx_out->host_prod[0].reg_buf;
1267
1268 rds = &recv_ctx->rds_rings[1];
1269 rds->crb_rcv_producer = ahw->pci_base0 +
1270 mbx_out->host_prod[0].jmb_buf;
1271
1272 for (i = 0; i < num_sds; i++) {
1273 sds = &recv_ctx->sds_rings[i];
1274 sds->crb_sts_consumer = ahw->pci_base0 +
1275 mbx_out->host_csmr[i];
1276 if (adapter->flags & QLCNIC_MSIX_ENABLED)
1277 intr_mask = ahw->intr_tbl[i].src;
1278 else
1279 intr_mask = QLCRDX(ahw, QLCNIC_DEF_INT_MASK);
1280 sds->crb_intr_mask = ahw->pci_base0 + intr_mask;
1281 }
1282
1283 if (adapter->drv_sds_rings > QLCNIC_MAX_SDS_RINGS)
1284 err = qlcnic_83xx_add_rings(adapter);
1285out:
1286 qlcnic_free_mbx_args(&cmd);
1287 return err;
1288}
1289
1290void qlcnic_83xx_del_tx_ctx(struct qlcnic_adapter *adapter,
1291 struct qlcnic_host_tx_ring *tx_ring)
1292{
1293 struct qlcnic_cmd_args cmd;
1294 u32 temp = 0;
1295
1296 if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_DESTROY_TX_CTX))
1297 return;
1298
1299 if (qlcnic_sriov_pf_check(adapter) || qlcnic_sriov_vf_check(adapter))
1300 cmd.req.arg[0] |= (0x3 << 29);
1301
1302 if (qlcnic_sriov_pf_check(adapter))
1303 qlcnic_pf_set_interface_id_del_tx_ctx(adapter, &temp);
1304
1305 cmd.req.arg[1] = tx_ring->ctx_id | temp;
1306 if (qlcnic_issue_cmd(adapter, &cmd))
1307 dev_err(&adapter->pdev->dev,
1308 "Failed to destroy tx ctx in firmware\n");
1309 qlcnic_free_mbx_args(&cmd);
1310}
1311
1312int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *adapter,
1313 struct qlcnic_host_tx_ring *tx, int ring)
1314{
1315 int err;
1316 u16 msix_id;
1317 u32 *buf, intr_mask, temp = 0;
1318 struct qlcnic_cmd_args cmd;
1319 struct qlcnic_tx_mbx mbx;
1320 struct qlcnic_tx_mbx_out *mbx_out;
1321 struct qlcnic_hardware_context *ahw = adapter->ahw;
1322 u32 msix_vector;
1323
1324
1325 tx->producer = 0;
1326 tx->sw_consumer = 0;
1327 *(tx->hw_consumer) = 0;
1328
1329 memset(&mbx, 0, sizeof(struct qlcnic_tx_mbx));
1330
1331
1332 mbx.phys_addr_low = LSD(tx->phys_addr);
1333 mbx.phys_addr_high = MSD(tx->phys_addr);
1334 mbx.cnsmr_index_low = LSD(tx->hw_cons_phys_addr);
1335 mbx.cnsmr_index_high = MSD(tx->hw_cons_phys_addr);
1336 mbx.size = tx->num_desc;
1337 if (adapter->flags & QLCNIC_MSIX_ENABLED) {
1338 if (!(adapter->flags & QLCNIC_TX_INTR_SHARED))
1339 msix_vector = adapter->drv_sds_rings + ring;
1340 else
1341 msix_vector = adapter->drv_sds_rings - 1;
1342 msix_id = ahw->intr_tbl[msix_vector].id;
1343 } else {
1344 msix_id = QLCRDX(ahw, QLCNIC_DEF_INT_ID);
1345 }
1346
1347 if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST)
1348 mbx.intr_id = msix_id;
1349 else
1350 mbx.intr_id = 0xffff;
1351 mbx.src = 0;
1352
1353 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CREATE_TX_CTX);
1354 if (err)
1355 return err;
1356
1357 if (qlcnic_sriov_pf_check(adapter) || qlcnic_sriov_vf_check(adapter))
1358 cmd.req.arg[0] |= (0x3 << 29);
1359
1360 if (qlcnic_sriov_pf_check(adapter))
1361 qlcnic_pf_set_interface_id_create_tx_ctx(adapter, &temp);
1362
1363 cmd.req.arg[1] = QLCNIC_CAP0_LEGACY_CONTEXT;
1364 cmd.req.arg[5] = QLCNIC_SINGLE_RING | temp;
1365
1366 buf = &cmd.req.arg[6];
1367 memcpy(buf, &mbx, sizeof(struct qlcnic_tx_mbx));
1368
1369 err = qlcnic_issue_cmd(adapter, &cmd);
1370 if (err) {
1371 netdev_err(adapter->netdev,
1372 "Failed to create Tx ctx in firmware 0x%x\n", err);
1373 goto out;
1374 }
1375 mbx_out = (struct qlcnic_tx_mbx_out *)&cmd.rsp.arg[2];
1376 tx->crb_cmd_producer = ahw->pci_base0 + mbx_out->host_prod;
1377 tx->ctx_id = mbx_out->ctx_id;
1378 if ((adapter->flags & QLCNIC_MSIX_ENABLED) &&
1379 !(adapter->flags & QLCNIC_TX_INTR_SHARED)) {
1380 intr_mask = ahw->intr_tbl[adapter->drv_sds_rings + ring].src;
1381 tx->crb_intr_mask = ahw->pci_base0 + intr_mask;
1382 }
1383 netdev_info(adapter->netdev,
1384 "Tx Context[0x%x] Created, state:0x%x\n",
1385 tx->ctx_id, mbx_out->state);
1386out:
1387 qlcnic_free_mbx_args(&cmd);
1388 return err;
1389}
1390
1391static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test,
1392 u8 num_sds_ring)
1393{
1394 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1395 struct qlcnic_host_sds_ring *sds_ring;
1396 struct qlcnic_host_rds_ring *rds_ring;
1397 u16 adapter_state = adapter->is_up;
1398 u8 ring;
1399 int ret;
1400
1401 netif_device_detach(netdev);
1402
1403 if (netif_running(netdev))
1404 __qlcnic_down(adapter, netdev);
1405
1406 qlcnic_detach(adapter);
1407
1408 adapter->drv_sds_rings = QLCNIC_SINGLE_RING;
1409 adapter->ahw->diag_test = test;
1410 adapter->ahw->linkup = 0;
1411
1412 ret = qlcnic_attach(adapter);
1413 if (ret) {
1414 netif_device_attach(netdev);
1415 return ret;
1416 }
1417
1418 ret = qlcnic_fw_create_ctx(adapter);
1419 if (ret) {
1420 qlcnic_detach(adapter);
1421 if (adapter_state == QLCNIC_ADAPTER_UP_MAGIC) {
1422 adapter->drv_sds_rings = num_sds_ring;
1423 qlcnic_attach(adapter);
1424 }
1425 netif_device_attach(netdev);
1426 return ret;
1427 }
1428
1429 for (ring = 0; ring < adapter->max_rds_rings; ring++) {
1430 rds_ring = &adapter->recv_ctx->rds_rings[ring];
1431 qlcnic_post_rx_buffers(adapter, rds_ring, ring);
1432 }
1433
1434 if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) {
1435 for (ring = 0; ring < adapter->drv_sds_rings; ring++) {
1436 sds_ring = &adapter->recv_ctx->sds_rings[ring];
1437 qlcnic_enable_sds_intr(adapter, sds_ring);
1438 }
1439 }
1440
1441 if (adapter->ahw->diag_test == QLCNIC_LOOPBACK_TEST) {
1442 adapter->ahw->loopback_state = 0;
1443 adapter->ahw->hw_ops->setup_link_event(adapter, 1);
1444 }
1445
1446 set_bit(__QLCNIC_DEV_UP, &adapter->state);
1447 return 0;
1448}
1449
1450static void qlcnic_83xx_diag_free_res(struct net_device *netdev,
1451 u8 drv_sds_rings)
1452{
1453 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1454 struct qlcnic_host_sds_ring *sds_ring;
1455 int ring;
1456
1457 clear_bit(__QLCNIC_DEV_UP, &adapter->state);
1458 if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) {
1459 for (ring = 0; ring < adapter->drv_sds_rings; ring++) {
1460 sds_ring = &adapter->recv_ctx->sds_rings[ring];
1461 if (adapter->flags & QLCNIC_MSIX_ENABLED)
1462 qlcnic_disable_sds_intr(adapter, sds_ring);
1463 }
1464 }
1465
1466 qlcnic_fw_destroy_ctx(adapter);
1467 qlcnic_detach(adapter);
1468
1469 adapter->ahw->diag_test = 0;
1470 adapter->drv_sds_rings = drv_sds_rings;
1471
1472 if (qlcnic_attach(adapter))
1473 goto out;
1474
1475 if (netif_running(netdev))
1476 __qlcnic_up(adapter, netdev);
1477
1478out:
1479 netif_device_attach(netdev);
1480}
1481
1482static void qlcnic_83xx_get_beacon_state(struct qlcnic_adapter *adapter)
1483{
1484 struct qlcnic_hardware_context *ahw = adapter->ahw;
1485 struct qlcnic_cmd_args cmd;
1486 u8 beacon_state;
1487 int err = 0;
1488
1489 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_LED_CONFIG);
1490 if (!err) {
1491 err = qlcnic_issue_cmd(adapter, &cmd);
1492 if (!err) {
1493 beacon_state = cmd.rsp.arg[4];
1494 if (beacon_state == QLCNIC_BEACON_DISABLE)
1495 ahw->beacon_state = QLC_83XX_BEACON_OFF;
1496 else if (beacon_state == QLC_83XX_ENABLE_BEACON)
1497 ahw->beacon_state = QLC_83XX_BEACON_ON;
1498 }
1499 } else {
1500 netdev_err(adapter->netdev, "Get beacon state failed, err=%d\n",
1501 err);
1502 }
1503
1504 qlcnic_free_mbx_args(&cmd);
1505
1506 return;
1507}
1508
1509int qlcnic_83xx_config_led(struct qlcnic_adapter *adapter, u32 state,
1510 u32 beacon)
1511{
1512 struct qlcnic_cmd_args cmd;
1513 u32 mbx_in;
1514 int i, status = 0;
1515
1516 if (state) {
1517
1518 status = qlcnic_alloc_mbx_args(&cmd, adapter,
1519 QLCNIC_CMD_GET_LED_CONFIG);
1520 if (status)
1521 return status;
1522
1523 status = qlcnic_issue_cmd(adapter, &cmd);
1524 if (status) {
1525 dev_err(&adapter->pdev->dev,
1526 "Get led config failed.\n");
1527 goto mbx_err;
1528 } else {
1529 for (i = 0; i < 4; i++)
1530 adapter->ahw->mbox_reg[i] = cmd.rsp.arg[i+1];
1531 }
1532 qlcnic_free_mbx_args(&cmd);
1533
1534 mbx_in = (LSW(QLC_83XX_LED_CONFIG) << 16) |
1535 LSW(QLC_83XX_LED_CONFIG);
1536 status = qlcnic_alloc_mbx_args(&cmd, adapter,
1537 QLCNIC_CMD_SET_LED_CONFIG);
1538 if (status)
1539 return status;
1540
1541 cmd.req.arg[1] = mbx_in;
1542 cmd.req.arg[2] = mbx_in;
1543 cmd.req.arg[3] = mbx_in;
1544 if (beacon)
1545 cmd.req.arg[4] = QLC_83XX_ENABLE_BEACON;
1546 status = qlcnic_issue_cmd(adapter, &cmd);
1547 if (status) {
1548 dev_err(&adapter->pdev->dev,
1549 "Set led config failed.\n");
1550 }
1551mbx_err:
1552 qlcnic_free_mbx_args(&cmd);
1553 return status;
1554
1555 } else {
1556
1557 status = qlcnic_alloc_mbx_args(&cmd, adapter,
1558 QLCNIC_CMD_SET_LED_CONFIG);
1559 if (status)
1560 return status;
1561
1562 cmd.req.arg[1] = adapter->ahw->mbox_reg[0];
1563 cmd.req.arg[2] = adapter->ahw->mbox_reg[1];
1564 cmd.req.arg[3] = adapter->ahw->mbox_reg[2];
1565 if (beacon)
1566 cmd.req.arg[4] = adapter->ahw->mbox_reg[3];
1567 status = qlcnic_issue_cmd(adapter, &cmd);
1568 if (status)
1569 dev_err(&adapter->pdev->dev,
1570 "Restoring led config failed.\n");
1571 qlcnic_free_mbx_args(&cmd);
1572 return status;
1573 }
1574}
1575
1576int qlcnic_83xx_set_led(struct net_device *netdev,
1577 enum ethtool_phys_id_state state)
1578{
1579 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1580 int err = -EIO, active = 1;
1581
1582 if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
1583 netdev_warn(netdev,
1584 "LED test is not supported in non-privileged mode\n");
1585 return -EOPNOTSUPP;
1586 }
1587
1588 switch (state) {
1589 case ETHTOOL_ID_ACTIVE:
1590 if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state))
1591 return -EBUSY;
1592
1593 if (test_bit(__QLCNIC_RESETTING, &adapter->state))
1594 break;
1595
1596 err = qlcnic_83xx_config_led(adapter, active, 0);
1597 if (err)
1598 netdev_err(netdev, "Failed to set LED blink state\n");
1599 break;
1600 case ETHTOOL_ID_INACTIVE:
1601 active = 0;
1602
1603 if (test_bit(__QLCNIC_RESETTING, &adapter->state))
1604 break;
1605
1606 err = qlcnic_83xx_config_led(adapter, active, 0);
1607 if (err)
1608 netdev_err(netdev, "Failed to reset LED blink state\n");
1609 break;
1610
1611 default:
1612 return -EINVAL;
1613 }
1614
1615 if (!active || err)
1616 clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
1617
1618 return err;
1619}
1620
1621void qlcnic_83xx_initialize_nic(struct qlcnic_adapter *adapter, int enable)
1622{
1623 struct qlcnic_cmd_args cmd;
1624 int status;
1625
1626 if (qlcnic_sriov_vf_check(adapter))
1627 return;
1628
1629 if (enable)
1630 status = qlcnic_alloc_mbx_args(&cmd, adapter,
1631 QLCNIC_CMD_INIT_NIC_FUNC);
1632 else
1633 status = qlcnic_alloc_mbx_args(&cmd, adapter,
1634 QLCNIC_CMD_STOP_NIC_FUNC);
1635
1636 if (status)
1637 return;
1638
1639 cmd.req.arg[1] = QLC_REGISTER_LB_IDC | QLC_INIT_FW_RESOURCES;
1640
1641 if (adapter->dcb)
1642 cmd.req.arg[1] |= QLC_REGISTER_DCB_AEN;
1643
1644 status = qlcnic_issue_cmd(adapter, &cmd);
1645 if (status)
1646 dev_err(&adapter->pdev->dev,
1647 "Failed to %s in NIC IDC function event.\n",
1648 (enable ? "register" : "unregister"));
1649
1650 qlcnic_free_mbx_args(&cmd);
1651}
1652
1653static int qlcnic_83xx_set_port_config(struct qlcnic_adapter *adapter)
1654{
1655 struct qlcnic_cmd_args cmd;
1656 int err;
1657
1658 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_PORT_CONFIG);
1659 if (err)
1660 return err;
1661
1662 cmd.req.arg[1] = adapter->ahw->port_config;
1663 err = qlcnic_issue_cmd(adapter, &cmd);
1664 if (err)
1665 dev_info(&adapter->pdev->dev, "Set Port Config failed.\n");
1666 qlcnic_free_mbx_args(&cmd);
1667 return err;
1668}
1669
1670static int qlcnic_83xx_get_port_config(struct qlcnic_adapter *adapter)
1671{
1672 struct qlcnic_cmd_args cmd;
1673 int err;
1674
1675 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_PORT_CONFIG);
1676 if (err)
1677 return err;
1678
1679 err = qlcnic_issue_cmd(adapter, &cmd);
1680 if (err)
1681 dev_info(&adapter->pdev->dev, "Get Port config failed\n");
1682 else
1683 adapter->ahw->port_config = cmd.rsp.arg[1];
1684 qlcnic_free_mbx_args(&cmd);
1685 return err;
1686}
1687
1688int qlcnic_83xx_setup_link_event(struct qlcnic_adapter *adapter, int enable)
1689{
1690 int err;
1691 u32 temp;
1692 struct qlcnic_cmd_args cmd;
1693
1694 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_LINK_EVENT);
1695 if (err)
1696 return err;
1697
1698 temp = adapter->recv_ctx->context_id << 16;
1699 cmd.req.arg[1] = (enable ? 1 : 0) | BIT_8 | temp;
1700 err = qlcnic_issue_cmd(adapter, &cmd);
1701 if (err)
1702 dev_info(&adapter->pdev->dev,
1703 "Setup linkevent mailbox failed\n");
1704 qlcnic_free_mbx_args(&cmd);
1705 return err;
1706}
1707
1708static void qlcnic_83xx_set_interface_id_promisc(struct qlcnic_adapter *adapter,
1709 u32 *interface_id)
1710{
1711 if (qlcnic_sriov_pf_check(adapter)) {
1712 qlcnic_alloc_lb_filters_mem(adapter);
1713 qlcnic_pf_set_interface_id_promisc(adapter, interface_id);
1714 adapter->rx_mac_learn = true;
1715 } else {
1716 if (!qlcnic_sriov_vf_check(adapter))
1717 *interface_id = adapter->recv_ctx->context_id << 16;
1718 }
1719}
1720
1721int qlcnic_83xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode)
1722{
1723 struct qlcnic_cmd_args *cmd = NULL;
1724 u32 temp = 0;
1725 int err;
1726
1727 if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
1728 return -EIO;
1729
1730 cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC);
1731 if (!cmd)
1732 return -ENOMEM;
1733
1734 err = qlcnic_alloc_mbx_args(cmd, adapter,
1735 QLCNIC_CMD_CONFIGURE_MAC_RX_MODE);
1736 if (err)
1737 goto out;
1738
1739 cmd->type = QLC_83XX_MBX_CMD_NO_WAIT;
1740 qlcnic_83xx_set_interface_id_promisc(adapter, &temp);
1741
1742 if (qlcnic_84xx_check(adapter) && qlcnic_sriov_pf_check(adapter))
1743 mode = VPORT_MISS_MODE_ACCEPT_ALL;
1744
1745 cmd->req.arg[1] = mode | temp;
1746 err = qlcnic_issue_cmd(adapter, cmd);
1747 if (!err)
1748 return err;
1749
1750 qlcnic_free_mbx_args(cmd);
1751
1752out:
1753 kfree(cmd);
1754 return err;
1755}
1756
1757int qlcnic_83xx_loopback_test(struct net_device *netdev, u8 mode)
1758{
1759 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1760 struct qlcnic_hardware_context *ahw = adapter->ahw;
1761 u8 drv_sds_rings = adapter->drv_sds_rings;
1762 u8 drv_tx_rings = adapter->drv_tx_rings;
1763 int ret = 0, loop = 0;
1764
1765 if (ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
1766 netdev_warn(netdev,
1767 "Loopback test not supported in non privileged mode\n");
1768 return -ENOTSUPP;
1769 }
1770
1771 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
1772 netdev_info(netdev, "Device is resetting\n");
1773 return -EBUSY;
1774 }
1775
1776 if (qlcnic_get_diag_lock(adapter)) {
1777 netdev_info(netdev, "Device is in diagnostics mode\n");
1778 return -EBUSY;
1779 }
1780
1781 netdev_info(netdev, "%s loopback test in progress\n",
1782 mode == QLCNIC_ILB_MODE ? "internal" : "external");
1783
1784 ret = qlcnic_83xx_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST,
1785 drv_sds_rings);
1786 if (ret)
1787 goto fail_diag_alloc;
1788
1789 ret = qlcnic_83xx_set_lb_mode(adapter, mode);
1790 if (ret)
1791 goto free_diag_res;
1792
1793
1794 do {
1795 msleep(QLC_83XX_LB_MSLEEP_COUNT);
1796
1797 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
1798 netdev_info(netdev,
1799 "Device is resetting, free LB test resources\n");
1800 ret = -EBUSY;
1801 goto free_diag_res;
1802 }
1803 if (loop++ > QLC_83XX_LB_WAIT_COUNT) {
1804 netdev_info(netdev,
1805 "Firmware didn't sent link up event to loopback request\n");
1806 ret = -ETIMEDOUT;
1807 qlcnic_83xx_clear_lb_mode(adapter, mode);
1808 goto free_diag_res;
1809 }
1810 } while ((adapter->ahw->linkup && ahw->has_link_events) != 1);
1811
1812 ret = qlcnic_do_lb_test(adapter, mode);
1813
1814 qlcnic_83xx_clear_lb_mode(adapter, mode);
1815
1816free_diag_res:
1817 qlcnic_83xx_diag_free_res(netdev, drv_sds_rings);
1818
1819fail_diag_alloc:
1820 adapter->drv_sds_rings = drv_sds_rings;
1821 adapter->drv_tx_rings = drv_tx_rings;
1822 qlcnic_release_diag_lock(adapter);
1823 return ret;
1824}
1825
1826static void qlcnic_extend_lb_idc_cmpltn_wait(struct qlcnic_adapter *adapter,
1827 u32 *max_wait_count)
1828{
1829 struct qlcnic_hardware_context *ahw = adapter->ahw;
1830 int temp;
1831
1832 netdev_info(adapter->netdev, "Received loopback IDC time extend event for 0x%x seconds\n",
1833 ahw->extend_lb_time);
1834 temp = ahw->extend_lb_time * 1000;
1835 *max_wait_count += temp / QLC_83XX_LB_MSLEEP_COUNT;
1836 ahw->extend_lb_time = 0;
1837}
1838
1839static int qlcnic_83xx_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
1840{
1841 struct qlcnic_hardware_context *ahw = adapter->ahw;
1842 struct net_device *netdev = adapter->netdev;
1843 u32 config, max_wait_count;
1844 int status = 0, loop = 0;
1845
1846 ahw->extend_lb_time = 0;
1847 max_wait_count = QLC_83XX_LB_WAIT_COUNT;
1848 status = qlcnic_83xx_get_port_config(adapter);
1849 if (status)
1850 return status;
1851
1852 config = ahw->port_config;
1853
1854
1855 if ((config & QLC_83XX_CFG_LOOPBACK_HSS) ||
1856 (config & QLC_83XX_CFG_LOOPBACK_EXT)) {
1857 netdev_err(netdev,
1858 "Port already in Loopback mode.\n");
1859 return -EINPROGRESS;
1860 }
1861
1862 set_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1863
1864 if (mode == QLCNIC_ILB_MODE)
1865 ahw->port_config |= QLC_83XX_CFG_LOOPBACK_HSS;
1866 if (mode == QLCNIC_ELB_MODE)
1867 ahw->port_config |= QLC_83XX_CFG_LOOPBACK_EXT;
1868
1869 status = qlcnic_83xx_set_port_config(adapter);
1870 if (status) {
1871 netdev_err(netdev,
1872 "Failed to Set Loopback Mode = 0x%x.\n",
1873 ahw->port_config);
1874 ahw->port_config = config;
1875 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1876 return status;
1877 }
1878
1879
1880 do {
1881 msleep(QLC_83XX_LB_MSLEEP_COUNT);
1882
1883 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
1884 netdev_info(netdev,
1885 "Device is resetting, free LB test resources\n");
1886 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1887 return -EBUSY;
1888 }
1889
1890 if (ahw->extend_lb_time)
1891 qlcnic_extend_lb_idc_cmpltn_wait(adapter,
1892 &max_wait_count);
1893
1894 if (loop++ > max_wait_count) {
1895 netdev_err(netdev, "%s: Did not receive loopback IDC completion AEN\n",
1896 __func__);
1897 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1898 qlcnic_83xx_clear_lb_mode(adapter, mode);
1899 return -ETIMEDOUT;
1900 }
1901 } while (test_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status));
1902
1903 qlcnic_sre_macaddr_change(adapter, adapter->mac_addr, 0,
1904 QLCNIC_MAC_ADD);
1905 return status;
1906}
1907
1908static int qlcnic_83xx_clear_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
1909{
1910 struct qlcnic_hardware_context *ahw = adapter->ahw;
1911 u32 config = ahw->port_config, max_wait_count;
1912 struct net_device *netdev = adapter->netdev;
1913 int status = 0, loop = 0;
1914
1915 ahw->extend_lb_time = 0;
1916 max_wait_count = QLC_83XX_LB_WAIT_COUNT;
1917 set_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1918 if (mode == QLCNIC_ILB_MODE)
1919 ahw->port_config &= ~QLC_83XX_CFG_LOOPBACK_HSS;
1920 if (mode == QLCNIC_ELB_MODE)
1921 ahw->port_config &= ~QLC_83XX_CFG_LOOPBACK_EXT;
1922
1923 status = qlcnic_83xx_set_port_config(adapter);
1924 if (status) {
1925 netdev_err(netdev,
1926 "Failed to Clear Loopback Mode = 0x%x.\n",
1927 ahw->port_config);
1928 ahw->port_config = config;
1929 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1930 return status;
1931 }
1932
1933
1934 do {
1935 msleep(QLC_83XX_LB_MSLEEP_COUNT);
1936
1937 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
1938 netdev_info(netdev,
1939 "Device is resetting, free LB test resources\n");
1940 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1941 return -EBUSY;
1942 }
1943
1944 if (ahw->extend_lb_time)
1945 qlcnic_extend_lb_idc_cmpltn_wait(adapter,
1946 &max_wait_count);
1947
1948 if (loop++ > max_wait_count) {
1949 netdev_err(netdev, "%s: Did not receive loopback IDC completion AEN\n",
1950 __func__);
1951 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1952 return -ETIMEDOUT;
1953 }
1954 } while (test_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status));
1955
1956 qlcnic_sre_macaddr_change(adapter, adapter->mac_addr, 0,
1957 QLCNIC_MAC_DEL);
1958 return status;
1959}
1960
1961static void qlcnic_83xx_set_interface_id_ipaddr(struct qlcnic_adapter *adapter,
1962 u32 *interface_id)
1963{
1964 if (qlcnic_sriov_pf_check(adapter)) {
1965 qlcnic_pf_set_interface_id_ipaddr(adapter, interface_id);
1966 } else {
1967 if (!qlcnic_sriov_vf_check(adapter))
1968 *interface_id = adapter->recv_ctx->context_id << 16;
1969 }
1970}
1971
1972void qlcnic_83xx_config_ipaddr(struct qlcnic_adapter *adapter, __be32 ip,
1973 int mode)
1974{
1975 int err;
1976 u32 temp = 0, temp_ip;
1977 struct qlcnic_cmd_args cmd;
1978
1979 err = qlcnic_alloc_mbx_args(&cmd, adapter,
1980 QLCNIC_CMD_CONFIGURE_IP_ADDR);
1981 if (err)
1982 return;
1983
1984 qlcnic_83xx_set_interface_id_ipaddr(adapter, &temp);
1985
1986 if (mode == QLCNIC_IP_UP)
1987 cmd.req.arg[1] = 1 | temp;
1988 else
1989 cmd.req.arg[1] = 2 | temp;
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999 temp_ip = swab32(ntohl(ip));
2000 memcpy(&cmd.req.arg[2], &temp_ip, sizeof(u32));
2001 err = qlcnic_issue_cmd(adapter, &cmd);
2002 if (err != QLCNIC_RCODE_SUCCESS)
2003 dev_err(&adapter->netdev->dev,
2004 "could not notify %s IP 0x%x request\n",
2005 (mode == QLCNIC_IP_UP) ? "Add" : "Remove", ip);
2006
2007 qlcnic_free_mbx_args(&cmd);
2008}
2009
2010int qlcnic_83xx_config_hw_lro(struct qlcnic_adapter *adapter, int mode)
2011{
2012 int err;
2013 u32 temp, arg1;
2014 struct qlcnic_cmd_args cmd;
2015 int lro_bit_mask;
2016
2017 lro_bit_mask = (mode ? (BIT_0 | BIT_1 | BIT_2 | BIT_3) : 0);
2018
2019 if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
2020 return 0;
2021
2022 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIGURE_HW_LRO);
2023 if (err)
2024 return err;
2025
2026 temp = adapter->recv_ctx->context_id << 16;
2027 arg1 = lro_bit_mask | temp;
2028 cmd.req.arg[1] = arg1;
2029
2030 err = qlcnic_issue_cmd(adapter, &cmd);
2031 if (err)
2032 dev_info(&adapter->pdev->dev, "LRO config failed\n");
2033 qlcnic_free_mbx_args(&cmd);
2034
2035 return err;
2036}
2037
2038int qlcnic_83xx_config_rss(struct qlcnic_adapter *adapter, int enable)
2039{
2040 int err;
2041 u32 word;
2042 struct qlcnic_cmd_args cmd;
2043 const u64 key[] = { 0xbeac01fa6a42b73bULL, 0x8030f20c77cb2da3ULL,
2044 0xae7b30b4d0ca2bcbULL, 0x43a38fb04167253dULL,
2045 0x255b0ec26d5a56daULL };
2046
2047 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIGURE_RSS);
2048 if (err)
2049 return err;
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059 word = ((u32)(RSS_HASHTYPE_IP_TCP & 0x3) << 4) |
2060 ((u32)(RSS_HASHTYPE_IP_TCP & 0x3) << 6) |
2061 ((u32)(enable & 0x1) << 8) |
2062 ((0x7ULL) << 16);
2063 cmd.req.arg[1] = (adapter->recv_ctx->context_id);
2064 cmd.req.arg[2] = word;
2065 memcpy(&cmd.req.arg[4], key, sizeof(key));
2066
2067 err = qlcnic_issue_cmd(adapter, &cmd);
2068
2069 if (err)
2070 dev_info(&adapter->pdev->dev, "RSS config failed\n");
2071 qlcnic_free_mbx_args(&cmd);
2072
2073 return err;
2074
2075}
2076
2077static void qlcnic_83xx_set_interface_id_macaddr(struct qlcnic_adapter *adapter,
2078 u32 *interface_id)
2079{
2080 if (qlcnic_sriov_pf_check(adapter)) {
2081 qlcnic_pf_set_interface_id_macaddr(adapter, interface_id);
2082 } else {
2083 if (!qlcnic_sriov_vf_check(adapter))
2084 *interface_id = adapter->recv_ctx->context_id << 16;
2085 }
2086}
2087
2088int qlcnic_83xx_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr,
2089 u16 vlan_id, u8 op)
2090{
2091 struct qlcnic_cmd_args *cmd = NULL;
2092 struct qlcnic_macvlan_mbx mv;
2093 u32 *buf, temp = 0;
2094 int err;
2095
2096 if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
2097 return -EIO;
2098
2099 cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC);
2100 if (!cmd)
2101 return -ENOMEM;
2102
2103 err = qlcnic_alloc_mbx_args(cmd, adapter, QLCNIC_CMD_CONFIG_MAC_VLAN);
2104 if (err)
2105 goto out;
2106
2107 cmd->type = QLC_83XX_MBX_CMD_NO_WAIT;
2108
2109 if (vlan_id)
2110 op = (op == QLCNIC_MAC_ADD || op == QLCNIC_MAC_VLAN_ADD) ?
2111 QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_VLAN_DEL;
2112
2113 cmd->req.arg[1] = op | (1 << 8);
2114 qlcnic_83xx_set_interface_id_macaddr(adapter, &temp);
2115 cmd->req.arg[1] |= temp;
2116 mv.vlan = vlan_id;
2117 mv.mac_addr0 = addr[0];
2118 mv.mac_addr1 = addr[1];
2119 mv.mac_addr2 = addr[2];
2120 mv.mac_addr3 = addr[3];
2121 mv.mac_addr4 = addr[4];
2122 mv.mac_addr5 = addr[5];
2123 buf = &cmd->req.arg[2];
2124 memcpy(buf, &mv, sizeof(struct qlcnic_macvlan_mbx));
2125 err = qlcnic_issue_cmd(adapter, cmd);
2126 if (!err)
2127 return err;
2128
2129 qlcnic_free_mbx_args(cmd);
2130out:
2131 kfree(cmd);
2132 return err;
2133}
2134
2135void qlcnic_83xx_change_l2_filter(struct qlcnic_adapter *adapter, u64 *addr,
2136 u16 vlan_id,
2137 struct qlcnic_host_tx_ring *tx_ring)
2138{
2139 u8 mac[ETH_ALEN];
2140 memcpy(&mac, addr, ETH_ALEN);
2141 qlcnic_83xx_sre_macaddr_change(adapter, mac, vlan_id, QLCNIC_MAC_ADD);
2142}
2143
2144static void qlcnic_83xx_configure_mac(struct qlcnic_adapter *adapter, u8 *mac,
2145 u8 type, struct qlcnic_cmd_args *cmd)
2146{
2147 switch (type) {
2148 case QLCNIC_SET_STATION_MAC:
2149 case QLCNIC_SET_FAC_DEF_MAC:
2150 memcpy(&cmd->req.arg[2], mac, sizeof(u32));
2151 memcpy(&cmd->req.arg[3], &mac[4], sizeof(u16));
2152 break;
2153 }
2154 cmd->req.arg[1] = type;
2155}
2156
2157int qlcnic_83xx_get_mac_address(struct qlcnic_adapter *adapter, u8 *mac,
2158 u8 function)
2159{
2160 int err, i;
2161 struct qlcnic_cmd_args cmd;
2162 u32 mac_low, mac_high;
2163
2164 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_MAC_ADDRESS);
2165 if (err)
2166 return err;
2167
2168 qlcnic_83xx_configure_mac(adapter, mac, QLCNIC_GET_CURRENT_MAC, &cmd);
2169 err = qlcnic_issue_cmd(adapter, &cmd);
2170
2171 if (err == QLCNIC_RCODE_SUCCESS) {
2172 mac_low = cmd.rsp.arg[1];
2173 mac_high = cmd.rsp.arg[2];
2174
2175 for (i = 0; i < 2; i++)
2176 mac[i] = (u8) (mac_high >> ((1 - i) * 8));
2177 for (i = 2; i < 6; i++)
2178 mac[i] = (u8) (mac_low >> ((5 - i) * 8));
2179 } else {
2180 dev_err(&adapter->pdev->dev, "Failed to get mac address%d\n",
2181 err);
2182 err = -EIO;
2183 }
2184 qlcnic_free_mbx_args(&cmd);
2185 return err;
2186}
2187
2188static int qlcnic_83xx_set_rx_intr_coal(struct qlcnic_adapter *adapter)
2189{
2190 struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal;
2191 struct qlcnic_cmd_args cmd;
2192 u16 temp;
2193 int err;
2194
2195 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTR_COAL);
2196 if (err)
2197 return err;
2198
2199 temp = adapter->recv_ctx->context_id;
2200 cmd.req.arg[1] = QLCNIC_INTR_COAL_TYPE_RX | temp << 16;
2201 temp = coal->rx_time_us;
2202 cmd.req.arg[2] = coal->rx_packets | temp << 16;
2203 cmd.req.arg[3] = coal->flag;
2204
2205 err = qlcnic_issue_cmd(adapter, &cmd);
2206 if (err != QLCNIC_RCODE_SUCCESS)
2207 netdev_err(adapter->netdev,
2208 "failed to set interrupt coalescing parameters\n");
2209
2210 qlcnic_free_mbx_args(&cmd);
2211
2212 return err;
2213}
2214
2215static int qlcnic_83xx_set_tx_intr_coal(struct qlcnic_adapter *adapter)
2216{
2217 struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal;
2218 struct qlcnic_cmd_args cmd;
2219 u16 temp;
2220 int err;
2221
2222 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTR_COAL);
2223 if (err)
2224 return err;
2225
2226 temp = adapter->tx_ring->ctx_id;
2227 cmd.req.arg[1] = QLCNIC_INTR_COAL_TYPE_TX | temp << 16;
2228 temp = coal->tx_time_us;
2229 cmd.req.arg[2] = coal->tx_packets | temp << 16;
2230 cmd.req.arg[3] = coal->flag;
2231
2232 err = qlcnic_issue_cmd(adapter, &cmd);
2233 if (err != QLCNIC_RCODE_SUCCESS)
2234 netdev_err(adapter->netdev,
2235 "failed to set interrupt coalescing parameters\n");
2236
2237 qlcnic_free_mbx_args(&cmd);
2238
2239 return err;
2240}
2241
2242int qlcnic_83xx_set_rx_tx_intr_coal(struct qlcnic_adapter *adapter)
2243{
2244 int err = 0;
2245
2246 err = qlcnic_83xx_set_rx_intr_coal(adapter);
2247 if (err)
2248 netdev_err(adapter->netdev,
2249 "failed to set Rx coalescing parameters\n");
2250
2251 err = qlcnic_83xx_set_tx_intr_coal(adapter);
2252 if (err)
2253 netdev_err(adapter->netdev,
2254 "failed to set Tx coalescing parameters\n");
2255
2256 return err;
2257}
2258
2259int qlcnic_83xx_config_intr_coal(struct qlcnic_adapter *adapter,
2260 struct ethtool_coalesce *ethcoal)
2261{
2262 struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal;
2263 u32 rx_coalesce_usecs, rx_max_frames;
2264 u32 tx_coalesce_usecs, tx_max_frames;
2265 int err;
2266
2267 if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
2268 return -EIO;
2269
2270 tx_coalesce_usecs = ethcoal->tx_coalesce_usecs;
2271 tx_max_frames = ethcoal->tx_max_coalesced_frames;
2272 rx_coalesce_usecs = ethcoal->rx_coalesce_usecs;
2273 rx_max_frames = ethcoal->rx_max_coalesced_frames;
2274 coal->flag = QLCNIC_INTR_DEFAULT;
2275
2276 if ((coal->rx_time_us == rx_coalesce_usecs) &&
2277 (coal->rx_packets == rx_max_frames)) {
2278 coal->type = QLCNIC_INTR_COAL_TYPE_TX;
2279 coal->tx_time_us = tx_coalesce_usecs;
2280 coal->tx_packets = tx_max_frames;
2281 } else if ((coal->tx_time_us == tx_coalesce_usecs) &&
2282 (coal->tx_packets == tx_max_frames)) {
2283 coal->type = QLCNIC_INTR_COAL_TYPE_RX;
2284 coal->rx_time_us = rx_coalesce_usecs;
2285 coal->rx_packets = rx_max_frames;
2286 } else {
2287 coal->type = QLCNIC_INTR_COAL_TYPE_RX_TX;
2288 coal->rx_time_us = rx_coalesce_usecs;
2289 coal->rx_packets = rx_max_frames;
2290 coal->tx_time_us = tx_coalesce_usecs;
2291 coal->tx_packets = tx_max_frames;
2292 }
2293
2294 switch (coal->type) {
2295 case QLCNIC_INTR_COAL_TYPE_RX:
2296 err = qlcnic_83xx_set_rx_intr_coal(adapter);
2297 break;
2298 case QLCNIC_INTR_COAL_TYPE_TX:
2299 err = qlcnic_83xx_set_tx_intr_coal(adapter);
2300 break;
2301 case QLCNIC_INTR_COAL_TYPE_RX_TX:
2302 err = qlcnic_83xx_set_rx_tx_intr_coal(adapter);
2303 break;
2304 default:
2305 err = -EINVAL;
2306 netdev_err(adapter->netdev,
2307 "Invalid Interrupt coalescing type\n");
2308 break;
2309 }
2310
2311 return err;
2312}
2313
2314static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter,
2315 u32 data[])
2316{
2317 struct qlcnic_hardware_context *ahw = adapter->ahw;
2318 u8 link_status, duplex;
2319
2320 link_status = LSB(data[3]) & 1;
2321 if (link_status) {
2322 ahw->link_speed = MSW(data[2]);
2323 duplex = LSB(MSW(data[3]));
2324 if (duplex)
2325 ahw->link_duplex = DUPLEX_FULL;
2326 else
2327 ahw->link_duplex = DUPLEX_HALF;
2328 } else {
2329 ahw->link_speed = SPEED_UNKNOWN;
2330 ahw->link_duplex = DUPLEX_UNKNOWN;
2331 }
2332
2333 ahw->link_autoneg = MSB(MSW(data[3]));
2334 ahw->module_type = MSB(LSW(data[3]));
2335 ahw->has_link_events = 1;
2336 ahw->lb_mode = data[4] & QLCNIC_LB_MODE_MASK;
2337 qlcnic_advert_link_change(adapter, link_status);
2338}
2339
2340static irqreturn_t qlcnic_83xx_handle_aen(int irq, void *data)
2341{
2342 u32 mask, resp, event, rsp_status = QLC_83XX_MBX_RESPONSE_ARRIVED;
2343 struct qlcnic_adapter *adapter = data;
2344 struct qlcnic_mailbox *mbx;
2345 unsigned long flags;
2346
2347 mbx = adapter->ahw->mailbox;
2348 spin_lock_irqsave(&mbx->aen_lock, flags);
2349 resp = QLCRDX(adapter->ahw, QLCNIC_FW_MBX_CTRL);
2350 if (!(resp & QLCNIC_SET_OWNER))
2351 goto out;
2352
2353 event = readl(QLCNIC_MBX_FW(adapter->ahw, 0));
2354 if (event & QLCNIC_MBX_ASYNC_EVENT) {
2355 __qlcnic_83xx_process_aen(adapter);
2356 } else {
2357 if (mbx->rsp_status != rsp_status)
2358 qlcnic_83xx_notify_mbx_response(mbx);
2359 else
2360 adapter->stats.mbx_spurious_intr++;
2361 }
2362
2363out:
2364 mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
2365 writel(0, adapter->ahw->pci_base0 + mask);
2366 spin_unlock_irqrestore(&mbx->aen_lock, flags);
2367 return IRQ_HANDLED;
2368}
2369
2370int qlcnic_83xx_set_nic_info(struct qlcnic_adapter *adapter,
2371 struct qlcnic_info *nic)
2372{
2373 int i, err = -EIO;
2374 struct qlcnic_cmd_args cmd;
2375
2376 if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) {
2377 dev_err(&adapter->pdev->dev,
2378 "%s: Error, invoked by non management func\n",
2379 __func__);
2380 return err;
2381 }
2382
2383 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_NIC_INFO);
2384 if (err)
2385 return err;
2386
2387 cmd.req.arg[1] = (nic->pci_func << 16);
2388 cmd.req.arg[2] = 0x1 << 16;
2389 cmd.req.arg[3] = nic->phys_port | (nic->switch_mode << 16);
2390 cmd.req.arg[4] = nic->capabilities;
2391 cmd.req.arg[5] = (nic->max_mac_filters & 0xFF) | ((nic->max_mtu) << 16);
2392 cmd.req.arg[6] = (nic->max_tx_ques) | ((nic->max_rx_ques) << 16);
2393 cmd.req.arg[7] = (nic->min_tx_bw) | ((nic->max_tx_bw) << 16);
2394 for (i = 8; i < 32; i++)
2395 cmd.req.arg[i] = 0;
2396
2397 err = qlcnic_issue_cmd(adapter, &cmd);
2398
2399 if (err != QLCNIC_RCODE_SUCCESS) {
2400 dev_err(&adapter->pdev->dev, "Failed to set nic info%d\n",
2401 err);
2402 err = -EIO;
2403 }
2404
2405 qlcnic_free_mbx_args(&cmd);
2406
2407 return err;
2408}
2409
2410int qlcnic_83xx_get_nic_info(struct qlcnic_adapter *adapter,
2411 struct qlcnic_info *npar_info, u8 func_id)
2412{
2413 int err;
2414 u32 temp;
2415 u8 op = 0;
2416 struct qlcnic_cmd_args cmd;
2417 struct qlcnic_hardware_context *ahw = adapter->ahw;
2418
2419 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_NIC_INFO);
2420 if (err)
2421 return err;
2422
2423 if (func_id != ahw->pci_func) {
2424 temp = func_id << 16;
2425 cmd.req.arg[1] = op | BIT_31 | temp;
2426 } else {
2427 cmd.req.arg[1] = ahw->pci_func << 16;
2428 }
2429 err = qlcnic_issue_cmd(adapter, &cmd);
2430 if (err) {
2431 dev_info(&adapter->pdev->dev,
2432 "Failed to get nic info %d\n", err);
2433 goto out;
2434 }
2435
2436 npar_info->op_type = cmd.rsp.arg[1];
2437 npar_info->pci_func = cmd.rsp.arg[2] & 0xFFFF;
2438 npar_info->op_mode = (cmd.rsp.arg[2] & 0xFFFF0000) >> 16;
2439 npar_info->phys_port = cmd.rsp.arg[3] & 0xFFFF;
2440 npar_info->switch_mode = (cmd.rsp.arg[3] & 0xFFFF0000) >> 16;
2441 npar_info->capabilities = cmd.rsp.arg[4];
2442 npar_info->max_mac_filters = cmd.rsp.arg[5] & 0xFF;
2443 npar_info->max_mtu = (cmd.rsp.arg[5] & 0xFFFF0000) >> 16;
2444 npar_info->max_tx_ques = cmd.rsp.arg[6] & 0xFFFF;
2445 npar_info->max_rx_ques = (cmd.rsp.arg[6] & 0xFFFF0000) >> 16;
2446 npar_info->min_tx_bw = cmd.rsp.arg[7] & 0xFFFF;
2447 npar_info->max_tx_bw = (cmd.rsp.arg[7] & 0xFFFF0000) >> 16;
2448 if (cmd.rsp.arg[8] & 0x1)
2449 npar_info->max_bw_reg_offset = (cmd.rsp.arg[8] & 0x7FFE) >> 1;
2450 if (cmd.rsp.arg[8] & 0x10000) {
2451 temp = (cmd.rsp.arg[8] & 0x7FFE0000) >> 17;
2452 npar_info->max_linkspeed_reg_offset = temp;
2453 }
2454
2455 memcpy(ahw->extra_capability, &cmd.rsp.arg[16],
2456 sizeof(ahw->extra_capability));
2457
2458out:
2459 qlcnic_free_mbx_args(&cmd);
2460 return err;
2461}
2462
2463int qlcnic_get_pci_func_type(struct qlcnic_adapter *adapter, u16 type,
2464 u16 *nic, u16 *fcoe, u16 *iscsi)
2465{
2466 struct device *dev = &adapter->pdev->dev;
2467 int err = 0;
2468
2469 switch (type) {
2470 case QLCNIC_TYPE_NIC:
2471 (*nic)++;
2472 break;
2473 case QLCNIC_TYPE_FCOE:
2474 (*fcoe)++;
2475 break;
2476 case QLCNIC_TYPE_ISCSI:
2477 (*iscsi)++;
2478 break;
2479 default:
2480 dev_err(dev, "%s: Unknown PCI type[%x]\n",
2481 __func__, type);
2482 err = -EIO;
2483 }
2484
2485 return err;
2486}
2487
2488int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *adapter,
2489 struct qlcnic_pci_info *pci_info)
2490{
2491 struct qlcnic_hardware_context *ahw = adapter->ahw;
2492 struct device *dev = &adapter->pdev->dev;
2493 u16 nic = 0, fcoe = 0, iscsi = 0;
2494 struct qlcnic_cmd_args cmd;
2495 int i, err = 0, j = 0;
2496 u32 temp;
2497
2498 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_PCI_INFO);
2499 if (err)
2500 return err;
2501
2502 err = qlcnic_issue_cmd(adapter, &cmd);
2503
2504 ahw->total_nic_func = 0;
2505 if (err == QLCNIC_RCODE_SUCCESS) {
2506 ahw->max_pci_func = cmd.rsp.arg[1] & 0xFF;
2507 for (i = 2, j = 0; j < ahw->max_vnic_func; j++, pci_info++) {
2508 pci_info->id = cmd.rsp.arg[i] & 0xFFFF;
2509 pci_info->active = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
2510 i++;
2511 if (!pci_info->active) {
2512 i += QLC_SKIP_INACTIVE_PCI_REGS;
2513 continue;
2514 }
2515 pci_info->type = cmd.rsp.arg[i] & 0xFFFF;
2516 err = qlcnic_get_pci_func_type(adapter, pci_info->type,
2517 &nic, &fcoe, &iscsi);
2518 temp = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
2519 pci_info->default_port = temp;
2520 i++;
2521 pci_info->tx_min_bw = cmd.rsp.arg[i] & 0xFFFF;
2522 temp = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
2523 pci_info->tx_max_bw = temp;
2524 i = i + 2;
2525 memcpy(pci_info->mac, &cmd.rsp.arg[i], ETH_ALEN - 2);
2526 i++;
2527 memcpy(pci_info->mac + sizeof(u32), &cmd.rsp.arg[i], 2);
2528 i = i + 3;
2529 }
2530 } else {
2531 dev_err(dev, "Failed to get PCI Info, error = %d\n", err);
2532 err = -EIO;
2533 }
2534
2535 ahw->total_nic_func = nic;
2536 ahw->total_pci_func = nic + fcoe + iscsi;
2537 if (ahw->total_nic_func == 0 || ahw->total_pci_func == 0) {
2538 dev_err(dev, "%s: Invalid function count: total nic func[%x], total pci func[%x]\n",
2539 __func__, ahw->total_nic_func, ahw->total_pci_func);
2540 err = -EIO;
2541 }
2542 qlcnic_free_mbx_args(&cmd);
2543
2544 return err;
2545}
2546
2547int qlcnic_83xx_config_intrpt(struct qlcnic_adapter *adapter, bool op_type)
2548{
2549 int i, index, err;
2550 u8 max_ints;
2551 u32 val, temp, type;
2552 struct qlcnic_cmd_args cmd;
2553
2554 max_ints = adapter->ahw->num_msix - 1;
2555 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTRPT);
2556 if (err)
2557 return err;
2558
2559 cmd.req.arg[1] = max_ints;
2560
2561 if (qlcnic_sriov_vf_check(adapter))
2562 cmd.req.arg[1] |= (adapter->ahw->pci_func << 8) | BIT_16;
2563
2564 for (i = 0, index = 2; i < max_ints; i++) {
2565 type = op_type ? QLCNIC_INTRPT_ADD : QLCNIC_INTRPT_DEL;
2566 val = type | (adapter->ahw->intr_tbl[i].type << 4);
2567 if (adapter->ahw->intr_tbl[i].type == QLCNIC_INTRPT_MSIX)
2568 val |= (adapter->ahw->intr_tbl[i].id << 16);
2569 cmd.req.arg[index++] = val;
2570 }
2571 err = qlcnic_issue_cmd(adapter, &cmd);
2572 if (err) {
2573 dev_err(&adapter->pdev->dev,
2574 "Failed to configure interrupts 0x%x\n", err);
2575 goto out;
2576 }
2577
2578 max_ints = cmd.rsp.arg[1];
2579 for (i = 0, index = 2; i < max_ints; i++, index += 2) {
2580 val = cmd.rsp.arg[index];
2581 if (LSB(val)) {
2582 dev_info(&adapter->pdev->dev,
2583 "Can't configure interrupt %d\n",
2584 adapter->ahw->intr_tbl[i].id);
2585 continue;
2586 }
2587 if (op_type) {
2588 adapter->ahw->intr_tbl[i].id = MSW(val);
2589 adapter->ahw->intr_tbl[i].enabled = 1;
2590 temp = cmd.rsp.arg[index + 1];
2591 adapter->ahw->intr_tbl[i].src = temp;
2592 } else {
2593 adapter->ahw->intr_tbl[i].id = i;
2594 adapter->ahw->intr_tbl[i].enabled = 0;
2595 adapter->ahw->intr_tbl[i].src = 0;
2596 }
2597 }
2598out:
2599 qlcnic_free_mbx_args(&cmd);
2600 return err;
2601}
2602
2603int qlcnic_83xx_lock_flash(struct qlcnic_adapter *adapter)
2604{
2605 int id, timeout = 0;
2606 u32 status = 0;
2607
2608 while (status == 0) {
2609 status = QLC_SHARED_REG_RD32(adapter, QLCNIC_FLASH_LOCK);
2610 if (status)
2611 break;
2612
2613 if (++timeout >= QLC_83XX_FLASH_LOCK_TIMEOUT) {
2614 id = QLC_SHARED_REG_RD32(adapter,
2615 QLCNIC_FLASH_LOCK_OWNER);
2616 dev_err(&adapter->pdev->dev,
2617 "%s: failed, lock held by %d\n", __func__, id);
2618 return -EIO;
2619 }
2620 usleep_range(1000, 2000);
2621 }
2622
2623 QLC_SHARED_REG_WR32(adapter, QLCNIC_FLASH_LOCK_OWNER, adapter->portnum);
2624 return 0;
2625}
2626
2627void qlcnic_83xx_unlock_flash(struct qlcnic_adapter *adapter)
2628{
2629 QLC_SHARED_REG_RD32(adapter, QLCNIC_FLASH_UNLOCK);
2630 QLC_SHARED_REG_WR32(adapter, QLCNIC_FLASH_LOCK_OWNER, 0xFF);
2631}
2632
2633int qlcnic_83xx_lockless_flash_read32(struct qlcnic_adapter *adapter,
2634 u32 flash_addr, u8 *p_data,
2635 int count)
2636{
2637 u32 word, range, flash_offset, addr = flash_addr, ret;
2638 ulong indirect_add, direct_window;
2639 int i, err = 0;
2640
2641 flash_offset = addr & (QLCNIC_FLASH_SECTOR_SIZE - 1);
2642 if (addr & 0x3) {
2643 dev_err(&adapter->pdev->dev, "Illegal addr = 0x%x\n", addr);
2644 return -EIO;
2645 }
2646
2647 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_DIRECT_WINDOW,
2648 (addr & 0xFFFF0000));
2649
2650 range = flash_offset + (count * sizeof(u32));
2651
2652 if (range > (QLCNIC_FLASH_SECTOR_SIZE - 1)) {
2653
2654
2655 for (i = 0; i < count; i++) {
2656 indirect_add = QLC_83XX_FLASH_DIRECT_DATA(addr);
2657 ret = QLCRD32(adapter, indirect_add, &err);
2658 if (err == -EIO)
2659 return err;
2660
2661 word = ret;
2662 *(u32 *)p_data = word;
2663 p_data = p_data + 4;
2664 addr = addr + 4;
2665 flash_offset = flash_offset + 4;
2666
2667 if (flash_offset > (QLCNIC_FLASH_SECTOR_SIZE - 1)) {
2668 direct_window = QLC_83XX_FLASH_DIRECT_WINDOW;
2669
2670 qlcnic_83xx_wrt_reg_indirect(adapter,
2671 direct_window,
2672 (addr));
2673 flash_offset = 0;
2674 }
2675 }
2676 } else {
2677
2678 for (i = 0; i < count; i++) {
2679 indirect_add = QLC_83XX_FLASH_DIRECT_DATA(addr);
2680 ret = QLCRD32(adapter, indirect_add, &err);
2681 if (err == -EIO)
2682 return err;
2683
2684 word = ret;
2685 *(u32 *)p_data = word;
2686 p_data = p_data + 4;
2687 addr = addr + 4;
2688 }
2689 }
2690
2691 return 0;
2692}
2693
2694static int qlcnic_83xx_poll_flash_status_reg(struct qlcnic_adapter *adapter)
2695{
2696 u32 status;
2697 int retries = QLC_83XX_FLASH_READ_RETRY_COUNT;
2698 int err = 0;
2699
2700 do {
2701 status = QLCRD32(adapter, QLC_83XX_FLASH_STATUS, &err);
2702 if (err == -EIO)
2703 return err;
2704
2705 if ((status & QLC_83XX_FLASH_STATUS_READY) ==
2706 QLC_83XX_FLASH_STATUS_READY)
2707 break;
2708
2709 usleep_range(1000, 1100);
2710 } while (--retries);
2711
2712 if (!retries)
2713 return -EIO;
2714
2715 return 0;
2716}
2717
2718int qlcnic_83xx_enable_flash_write(struct qlcnic_adapter *adapter)
2719{
2720 int ret;
2721 u32 cmd;
2722 cmd = adapter->ahw->fdt.write_statusreg_cmd;
2723 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2724 (QLC_83XX_FLASH_FDT_WRITE_DEF_SIG | cmd));
2725 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA,
2726 adapter->ahw->fdt.write_enable_bits);
2727 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2728 QLC_83XX_FLASH_SECOND_ERASE_MS_VAL);
2729 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2730 if (ret)
2731 return -EIO;
2732
2733 return 0;
2734}
2735
2736int qlcnic_83xx_disable_flash_write(struct qlcnic_adapter *adapter)
2737{
2738 int ret;
2739
2740 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2741 (QLC_83XX_FLASH_FDT_WRITE_DEF_SIG |
2742 adapter->ahw->fdt.write_statusreg_cmd));
2743 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA,
2744 adapter->ahw->fdt.write_disable_bits);
2745 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2746 QLC_83XX_FLASH_SECOND_ERASE_MS_VAL);
2747 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2748 if (ret)
2749 return -EIO;
2750
2751 return 0;
2752}
2753
2754int qlcnic_83xx_read_flash_mfg_id(struct qlcnic_adapter *adapter)
2755{
2756 int ret, err = 0;
2757 u32 mfg_id;
2758
2759 if (qlcnic_83xx_lock_flash(adapter))
2760 return -EIO;
2761
2762 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2763 QLC_83XX_FLASH_FDT_READ_MFG_ID_VAL);
2764 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2765 QLC_83XX_FLASH_READ_CTRL);
2766 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2767 if (ret) {
2768 qlcnic_83xx_unlock_flash(adapter);
2769 return -EIO;
2770 }
2771
2772 mfg_id = QLCRD32(adapter, QLC_83XX_FLASH_RDDATA, &err);
2773 if (err == -EIO) {
2774 qlcnic_83xx_unlock_flash(adapter);
2775 return err;
2776 }
2777
2778 adapter->flash_mfg_id = (mfg_id & 0xFF);
2779 qlcnic_83xx_unlock_flash(adapter);
2780
2781 return 0;
2782}
2783
2784int qlcnic_83xx_read_flash_descriptor_table(struct qlcnic_adapter *adapter)
2785{
2786 int count, fdt_size, ret = 0;
2787
2788 fdt_size = sizeof(struct qlcnic_fdt);
2789 count = fdt_size / sizeof(u32);
2790
2791 if (qlcnic_83xx_lock_flash(adapter))
2792 return -EIO;
2793
2794 memset(&adapter->ahw->fdt, 0, fdt_size);
2795 ret = qlcnic_83xx_lockless_flash_read32(adapter, QLCNIC_FDT_LOCATION,
2796 (u8 *)&adapter->ahw->fdt,
2797 count);
2798 qlcnic_swap32_buffer((u32 *)&adapter->ahw->fdt, count);
2799 qlcnic_83xx_unlock_flash(adapter);
2800 return ret;
2801}
2802
2803int qlcnic_83xx_erase_flash_sector(struct qlcnic_adapter *adapter,
2804 u32 sector_start_addr)
2805{
2806 u32 reversed_addr, addr1, addr2, cmd;
2807 int ret = -EIO;
2808
2809 if (qlcnic_83xx_lock_flash(adapter) != 0)
2810 return -EIO;
2811
2812 if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
2813 ret = qlcnic_83xx_enable_flash_write(adapter);
2814 if (ret) {
2815 qlcnic_83xx_unlock_flash(adapter);
2816 dev_err(&adapter->pdev->dev,
2817 "%s failed at %d\n",
2818 __func__, __LINE__);
2819 return ret;
2820 }
2821 }
2822
2823 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2824 if (ret) {
2825 qlcnic_83xx_unlock_flash(adapter);
2826 dev_err(&adapter->pdev->dev,
2827 "%s: failed at %d\n", __func__, __LINE__);
2828 return -EIO;
2829 }
2830
2831 addr1 = (sector_start_addr & 0xFF) << 16;
2832 addr2 = (sector_start_addr & 0xFF0000) >> 16;
2833 reversed_addr = addr1 | addr2 | (sector_start_addr & 0xFF00);
2834
2835 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA,
2836 reversed_addr);
2837 cmd = QLC_83XX_FLASH_FDT_ERASE_DEF_SIG | adapter->ahw->fdt.erase_cmd;
2838 if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id)
2839 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR, cmd);
2840 else
2841 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2842 QLC_83XX_FLASH_OEM_ERASE_SIG);
2843 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2844 QLC_83XX_FLASH_LAST_ERASE_MS_VAL);
2845
2846 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2847 if (ret) {
2848 qlcnic_83xx_unlock_flash(adapter);
2849 dev_err(&adapter->pdev->dev,
2850 "%s: failed at %d\n", __func__, __LINE__);
2851 return -EIO;
2852 }
2853
2854 if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
2855 ret = qlcnic_83xx_disable_flash_write(adapter);
2856 if (ret) {
2857 qlcnic_83xx_unlock_flash(adapter);
2858 dev_err(&adapter->pdev->dev,
2859 "%s: failed at %d\n", __func__, __LINE__);
2860 return ret;
2861 }
2862 }
2863
2864 qlcnic_83xx_unlock_flash(adapter);
2865
2866 return 0;
2867}
2868
2869int qlcnic_83xx_flash_write32(struct qlcnic_adapter *adapter, u32 addr,
2870 u32 *p_data)
2871{
2872 int ret = -EIO;
2873 u32 addr1 = 0x00800000 | (addr >> 2);
2874
2875 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR, addr1);
2876 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA, *p_data);
2877 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2878 QLC_83XX_FLASH_LAST_ERASE_MS_VAL);
2879 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2880 if (ret) {
2881 dev_err(&adapter->pdev->dev,
2882 "%s: failed at %d\n", __func__, __LINE__);
2883 return -EIO;
2884 }
2885
2886 return 0;
2887}
2888
2889int qlcnic_83xx_flash_bulk_write(struct qlcnic_adapter *adapter, u32 addr,
2890 u32 *p_data, int count)
2891{
2892 u32 temp;
2893 int ret = -EIO, err = 0;
2894
2895 if ((count < QLC_83XX_FLASH_WRITE_MIN) ||
2896 (count > QLC_83XX_FLASH_WRITE_MAX)) {
2897 dev_err(&adapter->pdev->dev,
2898 "%s: Invalid word count\n", __func__);
2899 return -EIO;
2900 }
2901
2902 temp = QLCRD32(adapter, QLC_83XX_FLASH_SPI_CONTROL, &err);
2903 if (err == -EIO)
2904 return err;
2905
2906 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_SPI_CONTROL,
2907 (temp | QLC_83XX_FLASH_SPI_CTRL));
2908 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2909 QLC_83XX_FLASH_ADDR_TEMP_VAL);
2910
2911
2912 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA, *p_data++);
2913 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2914 QLC_83XX_FLASH_FIRST_MS_PATTERN);
2915 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2916 if (ret) {
2917 dev_err(&adapter->pdev->dev,
2918 "%s: failed at %d\n", __func__, __LINE__);
2919 return -EIO;
2920 }
2921
2922 count--;
2923 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2924 QLC_83XX_FLASH_ADDR_SECOND_TEMP_VAL);
2925
2926 while (count != 1) {
2927 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA,
2928 *p_data++);
2929 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2930 QLC_83XX_FLASH_SECOND_MS_PATTERN);
2931 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2932 if (ret) {
2933 dev_err(&adapter->pdev->dev,
2934 "%s: failed at %d\n", __func__, __LINE__);
2935 return -EIO;
2936 }
2937 count--;
2938 }
2939
2940 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2941 QLC_83XX_FLASH_ADDR_TEMP_VAL |
2942 (addr >> 2));
2943
2944 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA, *p_data++);
2945 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2946 QLC_83XX_FLASH_LAST_MS_PATTERN);
2947 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2948 if (ret) {
2949 dev_err(&adapter->pdev->dev,
2950 "%s: failed at %d\n", __func__, __LINE__);
2951 return -EIO;
2952 }
2953
2954 ret = QLCRD32(adapter, QLC_83XX_FLASH_SPI_STATUS, &err);
2955 if (err == -EIO)
2956 return err;
2957
2958 if ((ret & QLC_83XX_FLASH_SPI_CTRL) == QLC_83XX_FLASH_SPI_CTRL) {
2959 dev_err(&adapter->pdev->dev, "%s: failed at %d\n",
2960 __func__, __LINE__);
2961
2962 temp = QLCRD32(adapter, QLC_83XX_FLASH_SPI_CONTROL, &err);
2963 if (err == -EIO)
2964 return err;
2965
2966 qlcnic_83xx_wrt_reg_indirect(adapter,
2967 QLC_83XX_FLASH_SPI_CONTROL,
2968 (temp | QLC_83XX_FLASH_SPI_CTRL));
2969 }
2970
2971 return 0;
2972}
2973
2974static void qlcnic_83xx_recover_driver_lock(struct qlcnic_adapter *adapter)
2975{
2976 u32 val, id;
2977
2978 val = QLCRDX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK);
2979
2980
2981 if ((val & QLC_83XX_DRV_LOCK_RECOVERY_STATUS_MASK) == 0) {
2982 val = val & ~0x3F;
2983 val = val | ((adapter->portnum << 2) |
2984 QLC_83XX_NEED_DRV_LOCK_RECOVERY);
2985 QLCWRX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK, val);
2986 dev_info(&adapter->pdev->dev,
2987 "%s: lock recovery initiated\n", __func__);
2988 msleep(QLC_83XX_DRV_LOCK_RECOVERY_DELAY);
2989 val = QLCRDX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK);
2990 id = ((val >> 2) & 0xF);
2991 if (id == adapter->portnum) {
2992 val = val & ~QLC_83XX_DRV_LOCK_RECOVERY_STATUS_MASK;
2993 val = val | QLC_83XX_DRV_LOCK_RECOVERY_IN_PROGRESS;
2994 QLCWRX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK, val);
2995
2996 QLCRDX(adapter->ahw, QLC_83XX_DRV_UNLOCK);
2997
2998 val = val & ~0x3F;
2999 QLCWRX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK, val);
3000 dev_info(&adapter->pdev->dev,
3001 "%s: lock recovery completed\n", __func__);
3002 } else {
3003 dev_info(&adapter->pdev->dev,
3004 "%s: func %d to resume lock recovery process\n",
3005 __func__, id);
3006 }
3007 } else {
3008 dev_info(&adapter->pdev->dev,
3009 "%s: lock recovery initiated by other functions\n",
3010 __func__);
3011 }
3012}
3013
3014int qlcnic_83xx_lock_driver(struct qlcnic_adapter *adapter)
3015{
3016 u32 lock_alive_counter, val, id, i = 0, status = 0, temp = 0;
3017 int max_attempt = 0;
3018
3019 while (status == 0) {
3020 status = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK);
3021 if (status)
3022 break;
3023
3024 msleep(QLC_83XX_DRV_LOCK_WAIT_DELAY);
3025 i++;
3026
3027 if (i == 1)
3028 temp = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
3029
3030 if (i == QLC_83XX_DRV_LOCK_WAIT_COUNTER) {
3031 val = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
3032 if (val == temp) {
3033 id = val & 0xFF;
3034 dev_info(&adapter->pdev->dev,
3035 "%s: lock to be recovered from %d\n",
3036 __func__, id);
3037 qlcnic_83xx_recover_driver_lock(adapter);
3038 i = 0;
3039 max_attempt++;
3040 } else {
3041 dev_err(&adapter->pdev->dev,
3042 "%s: failed to get lock\n", __func__);
3043 return -EIO;
3044 }
3045 }
3046
3047
3048 if (max_attempt == QLC_83XX_MAX_DRV_LOCK_RECOVERY_ATTEMPT) {
3049 dev_err(&adapter->pdev->dev,
3050 "%s: failed to get lock\n", __func__);
3051 return -EIO;
3052 }
3053 }
3054
3055 val = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
3056 lock_alive_counter = val >> 8;
3057 lock_alive_counter++;
3058 val = lock_alive_counter << 8 | adapter->portnum;
3059 QLCWRX(adapter->ahw, QLC_83XX_DRV_LOCK_ID, val);
3060
3061 return 0;
3062}
3063
3064void qlcnic_83xx_unlock_driver(struct qlcnic_adapter *adapter)
3065{
3066 u32 val, lock_alive_counter, id;
3067
3068 val = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
3069 id = val & 0xFF;
3070 lock_alive_counter = val >> 8;
3071
3072 if (id != adapter->portnum)
3073 dev_err(&adapter->pdev->dev,
3074 "%s:Warning func %d is unlocking lock owned by %d\n",
3075 __func__, adapter->portnum, id);
3076
3077 val = (lock_alive_counter << 8) | 0xFF;
3078 QLCWRX(adapter->ahw, QLC_83XX_DRV_LOCK_ID, val);
3079 QLCRDX(adapter->ahw, QLC_83XX_DRV_UNLOCK);
3080}
3081
3082int qlcnic_ms_mem_write128(struct qlcnic_adapter *adapter, u64 addr,
3083 u32 *data, u32 count)
3084{
3085 int i, j, ret = 0;
3086 u32 temp;
3087
3088
3089 if (addr & 0xF)
3090 return -EIO;
3091
3092 mutex_lock(&adapter->ahw->mem_lock);
3093 qlcnic_ind_wr(adapter, QLCNIC_MS_ADDR_HI, 0);
3094
3095 for (i = 0; i < count; i++, addr += 16) {
3096 if (!((ADDR_IN_RANGE(addr, QLCNIC_ADDR_QDR_NET,
3097 QLCNIC_ADDR_QDR_NET_MAX)) ||
3098 (ADDR_IN_RANGE(addr, QLCNIC_ADDR_DDR_NET,
3099 QLCNIC_ADDR_DDR_NET_MAX)))) {
3100 mutex_unlock(&adapter->ahw->mem_lock);
3101 return -EIO;
3102 }
3103
3104 qlcnic_ind_wr(adapter, QLCNIC_MS_ADDR_LO, addr);
3105 qlcnic_ind_wr(adapter, QLCNIC_MS_WRTDATA_LO, *data++);
3106 qlcnic_ind_wr(adapter, QLCNIC_MS_WRTDATA_HI, *data++);
3107 qlcnic_ind_wr(adapter, QLCNIC_MS_WRTDATA_ULO, *data++);
3108 qlcnic_ind_wr(adapter, QLCNIC_MS_WRTDATA_UHI, *data++);
3109 qlcnic_ind_wr(adapter, QLCNIC_MS_CTRL, QLCNIC_TA_WRITE_ENABLE);
3110 qlcnic_ind_wr(adapter, QLCNIC_MS_CTRL, QLCNIC_TA_WRITE_START);
3111
3112 for (j = 0; j < MAX_CTL_CHECK; j++) {
3113 temp = qlcnic_ind_rd(adapter, QLCNIC_MS_CTRL);
3114
3115 if ((temp & TA_CTL_BUSY) == 0)
3116 break;
3117 }
3118
3119
3120 if (j >= MAX_CTL_CHECK) {
3121 printk_ratelimited(KERN_WARNING
3122 "MS memory write failed\n");
3123 mutex_unlock(&adapter->ahw->mem_lock);
3124 return -EIO;
3125 }
3126 }
3127
3128 mutex_unlock(&adapter->ahw->mem_lock);
3129
3130 return ret;
3131}
3132
3133int qlcnic_83xx_flash_read32(struct qlcnic_adapter *adapter, u32 flash_addr,
3134 u8 *p_data, int count)
3135{
3136 u32 word, addr = flash_addr, ret;
3137 ulong indirect_addr;
3138 int i, err = 0;
3139
3140 if (qlcnic_83xx_lock_flash(adapter) != 0)
3141 return -EIO;
3142
3143 if (addr & 0x3) {
3144 dev_err(&adapter->pdev->dev, "Illegal addr = 0x%x\n", addr);
3145 qlcnic_83xx_unlock_flash(adapter);
3146 return -EIO;
3147 }
3148
3149 for (i = 0; i < count; i++) {
3150 if (qlcnic_83xx_wrt_reg_indirect(adapter,
3151 QLC_83XX_FLASH_DIRECT_WINDOW,
3152 (addr))) {
3153 qlcnic_83xx_unlock_flash(adapter);
3154 return -EIO;
3155 }
3156
3157 indirect_addr = QLC_83XX_FLASH_DIRECT_DATA(addr);
3158 ret = QLCRD32(adapter, indirect_addr, &err);
3159 if (err == -EIO) {
3160 qlcnic_83xx_unlock_flash(adapter);
3161 return err;
3162 }
3163
3164 word = ret;
3165 *(u32 *)p_data = word;
3166 p_data = p_data + 4;
3167 addr = addr + 4;
3168 }
3169
3170 qlcnic_83xx_unlock_flash(adapter);
3171
3172 return 0;
3173}
3174
3175void qlcnic_83xx_get_port_type(struct qlcnic_adapter *adapter)
3176{
3177 struct qlcnic_hardware_context *ahw = adapter->ahw;
3178 struct qlcnic_cmd_args cmd;
3179 u32 config;
3180 int err;
3181
3182 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_LINK_STATUS);
3183 if (err)
3184 return;
3185
3186 err = qlcnic_issue_cmd(adapter, &cmd);
3187 if (err) {
3188 dev_info(&adapter->pdev->dev,
3189 "Get Link Status Command failed: 0x%x\n", err);
3190 goto out;
3191 } else {
3192 config = cmd.rsp.arg[3];
3193
3194 switch (QLC_83XX_SFP_MODULE_TYPE(config)) {
3195 case QLC_83XX_MODULE_FIBRE_1000BASE_SX:
3196 case QLC_83XX_MODULE_FIBRE_1000BASE_LX:
3197 case QLC_83XX_MODULE_FIBRE_1000BASE_CX:
3198 case QLC_83XX_MODULE_TP_1000BASE_T:
3199 ahw->port_type = QLCNIC_GBE;
3200 break;
3201 default:
3202 ahw->port_type = QLCNIC_XGBE;
3203 }
3204 }
3205out:
3206 qlcnic_free_mbx_args(&cmd);
3207}
3208
3209int qlcnic_83xx_test_link(struct qlcnic_adapter *adapter)
3210{
3211 u8 pci_func;
3212 int err;
3213 u32 config = 0, state;
3214 struct qlcnic_cmd_args cmd;
3215 struct qlcnic_hardware_context *ahw = adapter->ahw;
3216
3217 if (qlcnic_sriov_vf_check(adapter))
3218 pci_func = adapter->portnum;
3219 else
3220 pci_func = ahw->pci_func;
3221
3222 state = readl(ahw->pci_base0 + QLC_83XX_LINK_STATE(pci_func));
3223 if (!QLC_83xx_FUNC_VAL(state, pci_func)) {
3224 dev_info(&adapter->pdev->dev, "link state down\n");
3225 return config;
3226 }
3227
3228 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_LINK_STATUS);
3229 if (err)
3230 return err;
3231
3232 err = qlcnic_issue_cmd(adapter, &cmd);
3233 if (err) {
3234 dev_info(&adapter->pdev->dev,
3235 "Get Link Status Command failed: 0x%x\n", err);
3236 goto out;
3237 } else {
3238 config = cmd.rsp.arg[1];
3239 switch (QLC_83XX_CURRENT_LINK_SPEED(config)) {
3240 case QLC_83XX_10M_LINK:
3241 ahw->link_speed = SPEED_10;
3242 break;
3243 case QLC_83XX_100M_LINK:
3244 ahw->link_speed = SPEED_100;
3245 break;
3246 case QLC_83XX_1G_LINK:
3247 ahw->link_speed = SPEED_1000;
3248 break;
3249 case QLC_83XX_10G_LINK:
3250 ahw->link_speed = SPEED_10000;
3251 break;
3252 default:
3253 ahw->link_speed = 0;
3254 break;
3255 }
3256 config = cmd.rsp.arg[3];
3257 switch (QLC_83XX_SFP_MODULE_TYPE(config)) {
3258 case QLC_83XX_MODULE_FIBRE_10GBASE_LRM:
3259 case QLC_83XX_MODULE_FIBRE_10GBASE_LR:
3260 case QLC_83XX_MODULE_FIBRE_10GBASE_SR:
3261 ahw->supported_type = PORT_FIBRE;
3262 ahw->port_type = QLCNIC_XGBE;
3263 break;
3264 case QLC_83XX_MODULE_FIBRE_1000BASE_SX:
3265 case QLC_83XX_MODULE_FIBRE_1000BASE_LX:
3266 case QLC_83XX_MODULE_FIBRE_1000BASE_CX:
3267 ahw->supported_type = PORT_FIBRE;
3268 ahw->port_type = QLCNIC_GBE;
3269 break;
3270 case QLC_83XX_MODULE_TP_1000BASE_T:
3271 ahw->supported_type = PORT_TP;
3272 ahw->port_type = QLCNIC_GBE;
3273 break;
3274 case QLC_83XX_MODULE_DA_10GE_PASSIVE_CP:
3275 case QLC_83XX_MODULE_DA_10GE_ACTIVE_CP:
3276 case QLC_83XX_MODULE_DA_10GE_LEGACY_CP:
3277 case QLC_83XX_MODULE_DA_1GE_PASSIVE_CP:
3278 ahw->supported_type = PORT_DA;
3279 ahw->port_type = QLCNIC_XGBE;
3280 break;
3281 default:
3282 ahw->supported_type = PORT_OTHER;
3283 ahw->port_type = QLCNIC_XGBE;
3284 }
3285 if (config & 1)
3286 err = 1;
3287 }
3288out:
3289 qlcnic_free_mbx_args(&cmd);
3290 return config;
3291}
3292
3293int qlcnic_83xx_get_link_ksettings(struct qlcnic_adapter *adapter,
3294 struct ethtool_link_ksettings *ecmd)
3295{
3296 struct qlcnic_hardware_context *ahw = adapter->ahw;
3297 u32 config = 0;
3298 int status = 0;
3299 u32 supported, advertising;
3300
3301 if (!test_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state)) {
3302
3303 status = qlcnic_83xx_get_port_info(adapter);
3304
3305 config = qlcnic_83xx_test_link(adapter);
3306 ahw->module_type = QLC_83XX_SFP_MODULE_TYPE(config);
3307 }
3308
3309
3310 ahw->board_type = QLCNIC_BRDTYPE_83XX_10G;
3311
3312 if (netif_running(adapter->netdev) && ahw->has_link_events) {
3313 ecmd->base.speed = ahw->link_speed;
3314 ecmd->base.duplex = ahw->link_duplex;
3315 ecmd->base.autoneg = ahw->link_autoneg;
3316 } else {
3317 ecmd->base.speed = SPEED_UNKNOWN;
3318 ecmd->base.duplex = DUPLEX_UNKNOWN;
3319 ecmd->base.autoneg = AUTONEG_DISABLE;
3320 }
3321
3322 supported = (SUPPORTED_10baseT_Full |
3323 SUPPORTED_100baseT_Full |
3324 SUPPORTED_1000baseT_Full |
3325 SUPPORTED_10000baseT_Full |
3326 SUPPORTED_Autoneg);
3327
3328 ethtool_convert_link_mode_to_legacy_u32(&advertising,
3329 ecmd->link_modes.advertising);
3330
3331 if (ecmd->base.autoneg == AUTONEG_ENABLE) {
3332 if (ahw->port_config & QLC_83XX_10_CAPABLE)
3333 advertising |= SUPPORTED_10baseT_Full;
3334 if (ahw->port_config & QLC_83XX_100_CAPABLE)
3335 advertising |= SUPPORTED_100baseT_Full;
3336 if (ahw->port_config & QLC_83XX_1G_CAPABLE)
3337 advertising |= SUPPORTED_1000baseT_Full;
3338 if (ahw->port_config & QLC_83XX_10G_CAPABLE)
3339 advertising |= SUPPORTED_10000baseT_Full;
3340 if (ahw->port_config & QLC_83XX_AUTONEG_ENABLE)
3341 advertising |= ADVERTISED_Autoneg;
3342 } else {
3343 switch (ahw->link_speed) {
3344 case SPEED_10:
3345 advertising = SUPPORTED_10baseT_Full;
3346 break;
3347 case SPEED_100:
3348 advertising = SUPPORTED_100baseT_Full;
3349 break;
3350 case SPEED_1000:
3351 advertising = SUPPORTED_1000baseT_Full;
3352 break;
3353 case SPEED_10000:
3354 advertising = SUPPORTED_10000baseT_Full;
3355 break;
3356 default:
3357 break;
3358 }
3359
3360 }
3361
3362 switch (ahw->supported_type) {
3363 case PORT_FIBRE:
3364 supported |= SUPPORTED_FIBRE;
3365 advertising |= ADVERTISED_FIBRE;
3366 ecmd->base.port = PORT_FIBRE;
3367 break;
3368 case PORT_TP:
3369 supported |= SUPPORTED_TP;
3370 advertising |= ADVERTISED_TP;
3371 ecmd->base.port = PORT_TP;
3372 break;
3373 case PORT_DA:
3374 supported |= SUPPORTED_FIBRE;
3375 advertising |= ADVERTISED_FIBRE;
3376 ecmd->base.port = PORT_DA;
3377 break;
3378 default:
3379 supported |= SUPPORTED_FIBRE;
3380 advertising |= ADVERTISED_FIBRE;
3381 ecmd->base.port = PORT_OTHER;
3382 break;
3383 }
3384 ecmd->base.phy_address = ahw->physical_port;
3385
3386 ethtool_convert_legacy_u32_to_link_mode(ecmd->link_modes.supported,
3387 supported);
3388 ethtool_convert_legacy_u32_to_link_mode(ecmd->link_modes.advertising,
3389 advertising);
3390
3391 return status;
3392}
3393
3394int qlcnic_83xx_set_link_ksettings(struct qlcnic_adapter *adapter,
3395 const struct ethtool_link_ksettings *ecmd)
3396{
3397 struct qlcnic_hardware_context *ahw = adapter->ahw;
3398 u32 config = adapter->ahw->port_config;
3399 int status = 0;
3400
3401
3402 if (ecmd->base.duplex == DUPLEX_HALF) {
3403 netdev_info(adapter->netdev,
3404 "Half duplex mode not supported\n");
3405 return -EINVAL;
3406 }
3407
3408 if (ecmd->base.autoneg) {
3409 ahw->port_config |= QLC_83XX_AUTONEG_ENABLE;
3410 ahw->port_config |= (QLC_83XX_100_CAPABLE |
3411 QLC_83XX_1G_CAPABLE |
3412 QLC_83XX_10G_CAPABLE);
3413 } else {
3414 ahw->port_config &= ~QLC_83XX_AUTONEG_ENABLE;
3415 switch (ecmd->base.speed) {
3416 case SPEED_10:
3417 ahw->port_config &= ~(QLC_83XX_100_CAPABLE |
3418 QLC_83XX_1G_CAPABLE |
3419 QLC_83XX_10G_CAPABLE);
3420 ahw->port_config |= QLC_83XX_10_CAPABLE;
3421 break;
3422 case SPEED_100:
3423 ahw->port_config &= ~(QLC_83XX_10_CAPABLE |
3424 QLC_83XX_1G_CAPABLE |
3425 QLC_83XX_10G_CAPABLE);
3426 ahw->port_config |= QLC_83XX_100_CAPABLE;
3427 break;
3428 case SPEED_1000:
3429 ahw->port_config &= ~(QLC_83XX_10_CAPABLE |
3430 QLC_83XX_100_CAPABLE |
3431 QLC_83XX_10G_CAPABLE);
3432 ahw->port_config |= QLC_83XX_1G_CAPABLE;
3433 break;
3434 case SPEED_10000:
3435 ahw->port_config &= ~(QLC_83XX_10_CAPABLE |
3436 QLC_83XX_100_CAPABLE |
3437 QLC_83XX_1G_CAPABLE);
3438 ahw->port_config |= QLC_83XX_10G_CAPABLE;
3439 break;
3440 default:
3441 return -EINVAL;
3442 }
3443 }
3444 status = qlcnic_83xx_set_port_config(adapter);
3445 if (status) {
3446 netdev_info(adapter->netdev,
3447 "Failed to Set Link Speed and autoneg.\n");
3448 ahw->port_config = config;
3449 }
3450
3451 return status;
3452}
3453
3454static inline u64 *qlcnic_83xx_copy_stats(struct qlcnic_cmd_args *cmd,
3455 u64 *data, int index)
3456{
3457 u32 low, hi;
3458 u64 val;
3459
3460 low = cmd->rsp.arg[index];
3461 hi = cmd->rsp.arg[index + 1];
3462 val = (((u64) low) | (((u64) hi) << 32));
3463 *data++ = val;
3464 return data;
3465}
3466
3467static u64 *qlcnic_83xx_fill_stats(struct qlcnic_adapter *adapter,
3468 struct qlcnic_cmd_args *cmd, u64 *data,
3469 int type, int *ret)
3470{
3471 int err, k, total_regs;
3472
3473 *ret = 0;
3474 err = qlcnic_issue_cmd(adapter, cmd);
3475 if (err != QLCNIC_RCODE_SUCCESS) {
3476 dev_info(&adapter->pdev->dev,
3477 "Error in get statistics mailbox command\n");
3478 *ret = -EIO;
3479 return data;
3480 }
3481 total_regs = cmd->rsp.num;
3482 switch (type) {
3483 case QLC_83XX_STAT_MAC:
3484
3485 for (k = 2; k < 28; k += 2)
3486 data = qlcnic_83xx_copy_stats(cmd, data, k);
3487
3488
3489 for (k += 6; k < 60; k += 2)
3490 data = qlcnic_83xx_copy_stats(cmd, data, k);
3491
3492
3493 for (k += 6; k < 80; k += 2)
3494 data = qlcnic_83xx_copy_stats(cmd, data, k);
3495
3496 for (; k < total_regs; k += 2)
3497 data = qlcnic_83xx_copy_stats(cmd, data, k);
3498 break;
3499 case QLC_83XX_STAT_RX:
3500 for (k = 2; k < 8; k += 2)
3501 data = qlcnic_83xx_copy_stats(cmd, data, k);
3502
3503 for (k += 2; k < 24; k += 2)
3504 data = qlcnic_83xx_copy_stats(cmd, data, k);
3505
3506 for (k += 2; k < total_regs; k += 2)
3507 data = qlcnic_83xx_copy_stats(cmd, data, k);
3508 break;
3509 case QLC_83XX_STAT_TX:
3510 for (k = 2; k < 10; k += 2)
3511 data = qlcnic_83xx_copy_stats(cmd, data, k);
3512
3513 for (k += 2; k < total_regs; k += 2)
3514 data = qlcnic_83xx_copy_stats(cmd, data, k);
3515 break;
3516 default:
3517 dev_warn(&adapter->pdev->dev, "Unknown get statistics mode\n");
3518 *ret = -EIO;
3519 }
3520 return data;
3521}
3522
3523void qlcnic_83xx_get_stats(struct qlcnic_adapter *adapter, u64 *data)
3524{
3525 struct qlcnic_cmd_args cmd;
3526 struct net_device *netdev = adapter->netdev;
3527 int ret = 0;
3528
3529 ret = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_STATISTICS);
3530 if (ret)
3531 return;
3532
3533 cmd.req.arg[1] = BIT_1 | (adapter->tx_ring->ctx_id << 16);
3534 cmd.rsp.num = QLC_83XX_TX_STAT_REGS;
3535 data = qlcnic_83xx_fill_stats(adapter, &cmd, data,
3536 QLC_83XX_STAT_TX, &ret);
3537 if (ret) {
3538 netdev_err(netdev, "Error getting Tx stats\n");
3539 goto out;
3540 }
3541
3542 cmd.req.arg[1] = BIT_2 | (adapter->portnum << 16);
3543 cmd.rsp.num = QLC_83XX_MAC_STAT_REGS;
3544 memset(cmd.rsp.arg, 0, sizeof(u32) * cmd.rsp.num);
3545 data = qlcnic_83xx_fill_stats(adapter, &cmd, data,
3546 QLC_83XX_STAT_MAC, &ret);
3547 if (ret) {
3548 netdev_err(netdev, "Error getting MAC stats\n");
3549 goto out;
3550 }
3551
3552 cmd.req.arg[1] = adapter->recv_ctx->context_id << 16;
3553 cmd.rsp.num = QLC_83XX_RX_STAT_REGS;
3554 memset(cmd.rsp.arg, 0, sizeof(u32) * cmd.rsp.num);
3555 data = qlcnic_83xx_fill_stats(adapter, &cmd, data,
3556 QLC_83XX_STAT_RX, &ret);
3557 if (ret)
3558 netdev_err(netdev, "Error getting Rx stats\n");
3559out:
3560 qlcnic_free_mbx_args(&cmd);
3561}
3562
3563#define QLCNIC_83XX_ADD_PORT0 BIT_0
3564#define QLCNIC_83XX_ADD_PORT1 BIT_1
3565#define QLCNIC_83XX_EXTENDED_MEM_SIZE 13
3566int qlcnic_83xx_extend_md_capab(struct qlcnic_adapter *adapter)
3567{
3568 struct qlcnic_cmd_args cmd;
3569 int err;
3570
3571 err = qlcnic_alloc_mbx_args(&cmd, adapter,
3572 QLCNIC_CMD_83XX_EXTEND_ISCSI_DUMP_CAP);
3573 if (err)
3574 return err;
3575
3576 cmd.req.arg[1] = (QLCNIC_83XX_ADD_PORT0 | QLCNIC_83XX_ADD_PORT1);
3577 cmd.req.arg[2] = QLCNIC_83XX_EXTENDED_MEM_SIZE;
3578 cmd.req.arg[3] = QLCNIC_83XX_EXTENDED_MEM_SIZE;
3579
3580 err = qlcnic_issue_cmd(adapter, &cmd);
3581 if (err)
3582 dev_err(&adapter->pdev->dev,
3583 "failed to issue extend iSCSI minidump capability\n");
3584
3585 return err;
3586}
3587
3588int qlcnic_83xx_reg_test(struct qlcnic_adapter *adapter)
3589{
3590 u32 major, minor, sub;
3591
3592 major = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MAJOR);
3593 minor = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MINOR);
3594 sub = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_SUB);
3595
3596 if (adapter->fw_version != QLCNIC_VERSION_CODE(major, minor, sub)) {
3597 dev_info(&adapter->pdev->dev, "%s: Reg test failed\n",
3598 __func__);
3599 return 1;
3600 }
3601 return 0;
3602}
3603
3604inline int qlcnic_83xx_get_regs_len(struct qlcnic_adapter *adapter)
3605{
3606 return (ARRAY_SIZE(qlcnic_83xx_ext_reg_tbl) *
3607 sizeof(*adapter->ahw->ext_reg_tbl)) +
3608 (ARRAY_SIZE(qlcnic_83xx_reg_tbl) *
3609 sizeof(*adapter->ahw->reg_tbl));
3610}
3611
3612int qlcnic_83xx_get_registers(struct qlcnic_adapter *adapter, u32 *regs_buff)
3613{
3614 int i, j = 0;
3615
3616 for (i = QLCNIC_DEV_INFO_SIZE + 1;
3617 j < ARRAY_SIZE(qlcnic_83xx_reg_tbl); i++, j++)
3618 regs_buff[i] = QLC_SHARED_REG_RD32(adapter, j);
3619
3620 for (j = 0; j < ARRAY_SIZE(qlcnic_83xx_ext_reg_tbl); j++)
3621 regs_buff[i++] = QLCRDX(adapter->ahw, j);
3622 return i;
3623}
3624
3625int qlcnic_83xx_interrupt_test(struct net_device *netdev)
3626{
3627 struct qlcnic_adapter *adapter = netdev_priv(netdev);
3628 struct qlcnic_hardware_context *ahw = adapter->ahw;
3629 struct qlcnic_cmd_args cmd;