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