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