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