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