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