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