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