cd5ae8813cb3967537bc047a475db69329993736
[linux-3.10.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         ret = qlcnic_do_lb_test(adapter, mode);
1504
1505         qlcnic_83xx_clear_lb_mode(adapter, mode);
1506
1507 free_diag_res:
1508         qlcnic_83xx_diag_free_res(netdev, max_sds_rings);
1509
1510 fail_diag_alloc:
1511         adapter->max_sds_rings = max_sds_rings;
1512         clear_bit(__QLCNIC_RESETTING, &adapter->state);
1513         return ret;
1514 }
1515
1516 int qlcnic_83xx_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
1517 {
1518         struct qlcnic_hardware_context *ahw = adapter->ahw;
1519         int status = 0, loop = 0;
1520         u32 config;
1521
1522         status = qlcnic_83xx_get_port_config(adapter);
1523         if (status)
1524                 return status;
1525
1526         config = ahw->port_config;
1527         set_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1528
1529         if (mode == QLCNIC_ILB_MODE)
1530                 ahw->port_config |= QLC_83XX_CFG_LOOPBACK_HSS;
1531         if (mode == QLCNIC_ELB_MODE)
1532                 ahw->port_config |= QLC_83XX_CFG_LOOPBACK_EXT;
1533
1534         status = qlcnic_83xx_set_port_config(adapter);
1535         if (status) {
1536                 dev_err(&adapter->pdev->dev,
1537                         "Failed to Set Loopback Mode = 0x%x.\n",
1538                         ahw->port_config);
1539                 ahw->port_config = config;
1540                 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1541                 return status;
1542         }
1543
1544         /* Wait for Link and IDC Completion AEN */
1545         do {
1546                 msleep(300);
1547                 qlcnic_83xx_process_aen(adapter);
1548                 if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) {
1549                         dev_err(&adapter->pdev->dev,
1550                                 "FW did not generate IDC completion AEN\n");
1551                         clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1552                         qlcnic_83xx_clear_lb_mode(adapter, mode);
1553                         return -EIO;
1554                 }
1555         } while (test_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status));
1556
1557         qlcnic_sre_macaddr_change(adapter, adapter->mac_addr, 0,
1558                                   QLCNIC_MAC_ADD);
1559         return status;
1560 }
1561
1562 int qlcnic_83xx_clear_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
1563 {
1564         struct qlcnic_hardware_context *ahw = adapter->ahw;
1565         int status = 0, loop = 0;
1566         u32 config = ahw->port_config;
1567
1568         set_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1569         if (mode == QLCNIC_ILB_MODE)
1570                 ahw->port_config &= ~QLC_83XX_CFG_LOOPBACK_HSS;
1571         if (mode == QLCNIC_ELB_MODE)
1572                 ahw->port_config &= ~QLC_83XX_CFG_LOOPBACK_EXT;
1573
1574         status = qlcnic_83xx_set_port_config(adapter);
1575         if (status) {
1576                 dev_err(&adapter->pdev->dev,
1577                         "Failed to Clear Loopback Mode = 0x%x.\n",
1578                         ahw->port_config);
1579                 ahw->port_config = config;
1580                 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1581                 return status;
1582         }
1583
1584         /* Wait for Link and IDC Completion AEN */
1585         do {
1586                 msleep(300);
1587                 qlcnic_83xx_process_aen(adapter);
1588                 if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) {
1589                         dev_err(&adapter->pdev->dev,
1590                                 "Firmware didn't sent IDC completion AEN\n");
1591                         clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1592                         return -EIO;
1593                 }
1594         } while (test_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status));
1595
1596         qlcnic_sre_macaddr_change(adapter, adapter->mac_addr, 0,
1597                                   QLCNIC_MAC_DEL);
1598         return status;
1599 }
1600
1601 void qlcnic_83xx_config_ipaddr(struct qlcnic_adapter *adapter, __be32 ip,
1602                                int mode)
1603 {
1604         int err;
1605         u32 temp, temp_ip;
1606         struct qlcnic_cmd_args cmd;
1607
1608         qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIGURE_IP_ADDR);
1609         if (mode == QLCNIC_IP_UP) {
1610                 temp = adapter->recv_ctx->context_id << 16;
1611                 cmd.req.arg[1] = 1 | temp;
1612         } else {
1613                 temp = adapter->recv_ctx->context_id << 16;
1614                 cmd.req.arg[1] = 2 | temp;
1615         }
1616
1617         /*
1618          * Adapter needs IP address in network byte order.
1619          * But hardware mailbox registers go through writel(), hence IP address
1620          * gets swapped on big endian architecture.
1621          * To negate swapping of writel() on big endian architecture
1622          * use swab32(value).
1623          */
1624
1625         temp_ip = swab32(ntohl(ip));
1626         memcpy(&cmd.req.arg[2], &temp_ip, sizeof(u32));
1627         err = qlcnic_issue_cmd(adapter, &cmd);
1628         if (err != QLCNIC_RCODE_SUCCESS)
1629                 dev_err(&adapter->netdev->dev,
1630                         "could not notify %s IP 0x%x request\n",
1631                         (mode == QLCNIC_IP_UP) ? "Add" : "Remove", ip);
1632         qlcnic_free_mbx_args(&cmd);
1633 }
1634
1635 int qlcnic_83xx_config_hw_lro(struct qlcnic_adapter *adapter, int mode)
1636 {
1637         int err;
1638         u32 temp, arg1;
1639         struct qlcnic_cmd_args cmd;
1640         int lro_bit_mask;
1641
1642         lro_bit_mask = (mode ? (BIT_0 | BIT_1 | BIT_2 | BIT_3) : 0);
1643
1644         if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
1645                 return 0;
1646
1647         qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIGURE_HW_LRO);
1648         temp = adapter->recv_ctx->context_id << 16;
1649         arg1 = lro_bit_mask | temp;
1650         cmd.req.arg[1] = arg1;
1651
1652         err = qlcnic_issue_cmd(adapter, &cmd);
1653         if (err)
1654                 dev_info(&adapter->pdev->dev, "LRO config failed\n");
1655         qlcnic_free_mbx_args(&cmd);
1656
1657         return err;
1658 }
1659
1660 int qlcnic_83xx_config_rss(struct qlcnic_adapter *adapter, int enable)
1661 {
1662         int err;
1663         u32 word;
1664         struct qlcnic_cmd_args cmd;
1665         const u64 key[] = { 0xbeac01fa6a42b73bULL, 0x8030f20c77cb2da3ULL,
1666                             0xae7b30b4d0ca2bcbULL, 0x43a38fb04167253dULL,
1667                             0x255b0ec26d5a56daULL };
1668
1669         qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIGURE_RSS);
1670
1671         /*
1672          * RSS request:
1673          * bits 3-0: Rsvd
1674          *      5-4: hash_type_ipv4
1675          *      7-6: hash_type_ipv6
1676          *        8: enable
1677          *        9: use indirection table
1678          *    16-31: indirection table mask
1679          */
1680         word =  ((u32)(RSS_HASHTYPE_IP_TCP & 0x3) << 4) |
1681                 ((u32)(RSS_HASHTYPE_IP_TCP & 0x3) << 6) |
1682                 ((u32)(enable & 0x1) << 8) |
1683                 ((0x7ULL) << 16);
1684         cmd.req.arg[1] = (adapter->recv_ctx->context_id);
1685         cmd.req.arg[2] = word;
1686         memcpy(&cmd.req.arg[4], key, sizeof(key));
1687
1688         err = qlcnic_issue_cmd(adapter, &cmd);
1689
1690         if (err)
1691                 dev_info(&adapter->pdev->dev, "RSS config failed\n");
1692         qlcnic_free_mbx_args(&cmd);
1693
1694         return err;
1695
1696 }
1697
1698 int qlcnic_83xx_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr,
1699                                    __le16 vlan_id, u8 op)
1700 {
1701         int err;
1702         u32 *buf;
1703         struct qlcnic_cmd_args cmd;
1704         struct qlcnic_macvlan_mbx mv;
1705
1706         if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
1707                 return -EIO;
1708
1709         err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_MAC_VLAN);
1710         if (err)
1711                 return err;
1712         cmd.req.arg[1] = op | (1 << 8) |
1713                         (adapter->recv_ctx->context_id << 16);
1714
1715         mv.vlan = le16_to_cpu(vlan_id);
1716         memcpy(&mv.mac, addr, ETH_ALEN);
1717         buf = &cmd.req.arg[2];
1718         memcpy(buf, &mv, sizeof(struct qlcnic_macvlan_mbx));
1719         err = qlcnic_issue_cmd(adapter, &cmd);
1720         if (err)
1721                 dev_err(&adapter->pdev->dev,
1722                         "MAC-VLAN %s to CAM failed, err=%d.\n",
1723                         ((op == 1) ? "add " : "delete "), err);
1724         qlcnic_free_mbx_args(&cmd);
1725         return err;
1726 }
1727
1728 void qlcnic_83xx_change_l2_filter(struct qlcnic_adapter *adapter, u64 *addr,
1729                                   __le16 vlan_id)
1730 {
1731         u8 mac[ETH_ALEN];
1732         memcpy(&mac, addr, ETH_ALEN);
1733         qlcnic_83xx_sre_macaddr_change(adapter, mac, vlan_id, QLCNIC_MAC_ADD);
1734 }
1735
1736 void qlcnic_83xx_configure_mac(struct qlcnic_adapter *adapter, u8 *mac,
1737                                u8 type, struct qlcnic_cmd_args *cmd)
1738 {
1739         switch (type) {
1740         case QLCNIC_SET_STATION_MAC:
1741         case QLCNIC_SET_FAC_DEF_MAC:
1742                 memcpy(&cmd->req.arg[2], mac, sizeof(u32));
1743                 memcpy(&cmd->req.arg[3], &mac[4], sizeof(u16));
1744                 break;
1745         }
1746         cmd->req.arg[1] = type;
1747 }
1748
1749 int qlcnic_83xx_get_mac_address(struct qlcnic_adapter *adapter, u8 *mac)
1750 {
1751         int err, i;
1752         struct qlcnic_cmd_args cmd;
1753         u32 mac_low, mac_high;
1754
1755         qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_MAC_ADDRESS);
1756         qlcnic_83xx_configure_mac(adapter, mac, QLCNIC_GET_CURRENT_MAC, &cmd);
1757         err = qlcnic_issue_cmd(adapter, &cmd);
1758
1759         if (err == QLCNIC_RCODE_SUCCESS) {
1760                 mac_low = cmd.rsp.arg[1];
1761                 mac_high = cmd.rsp.arg[2];
1762
1763                 for (i = 0; i < 2; i++)
1764                         mac[i] = (u8) (mac_high >> ((1 - i) * 8));
1765                 for (i = 2; i < 6; i++)
1766                         mac[i] = (u8) (mac_low >> ((5 - i) * 8));
1767         } else {
1768                 dev_err(&adapter->pdev->dev, "Failed to get mac address%d\n",
1769                         err);
1770                 err = -EIO;
1771         }
1772         qlcnic_free_mbx_args(&cmd);
1773         return err;
1774 }
1775
1776 void qlcnic_83xx_config_intr_coal(struct qlcnic_adapter *adapter)
1777 {
1778         int err;
1779         u32 temp;
1780         struct qlcnic_cmd_args cmd;
1781         struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal;
1782
1783         if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
1784                 return;
1785
1786         qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTR_COAL);
1787         cmd.req.arg[1] = 1 | (adapter->recv_ctx->context_id << 16);
1788         cmd.req.arg[3] = coal->flag;
1789         temp = coal->rx_time_us << 16;
1790         cmd.req.arg[2] = coal->rx_packets | temp;
1791         err = qlcnic_issue_cmd(adapter, &cmd);
1792         if (err != QLCNIC_RCODE_SUCCESS)
1793                 dev_info(&adapter->pdev->dev,
1794                          "Failed to send interrupt coalescence parameters\n");
1795         qlcnic_free_mbx_args(&cmd);
1796 }
1797
1798 static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter,
1799                                         u32 data[])
1800 {
1801         u8 link_status, duplex;
1802         /* link speed */
1803         link_status = LSB(data[3]) & 1;
1804         adapter->ahw->link_speed = MSW(data[2]);
1805         adapter->ahw->link_autoneg = MSB(MSW(data[3]));
1806         adapter->ahw->module_type = MSB(LSW(data[3]));
1807         duplex = LSB(MSW(data[3]));
1808         if (duplex)
1809                 adapter->ahw->link_duplex = DUPLEX_FULL;
1810         else
1811                 adapter->ahw->link_duplex = DUPLEX_HALF;
1812         adapter->ahw->has_link_events = 1;
1813         qlcnic_advert_link_change(adapter, link_status);
1814 }
1815
1816 irqreturn_t qlcnic_83xx_handle_aen(int irq, void *data)
1817 {
1818         struct qlcnic_adapter *adapter = data;
1819         unsigned long flags;
1820         u32 mask, resp, event;
1821
1822         spin_lock_irqsave(&adapter->ahw->mbx_lock, flags);
1823         resp = QLCRDX(adapter->ahw, QLCNIC_FW_MBX_CTRL);
1824         if (!(resp & QLCNIC_SET_OWNER))
1825                 goto out;
1826
1827         event = readl(QLCNIC_MBX_FW(adapter->ahw, 0));
1828         if (event &  QLCNIC_MBX_ASYNC_EVENT)
1829                 qlcnic_83xx_process_aen(adapter);
1830 out:
1831         mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
1832         writel(0, adapter->ahw->pci_base0 + mask);
1833         spin_unlock_irqrestore(&adapter->ahw->mbx_lock, flags);
1834
1835         return IRQ_HANDLED;
1836 }
1837
1838 int qlcnic_enable_eswitch(struct qlcnic_adapter *adapter, u8 port, u8 enable)
1839 {
1840         int err = -EIO;
1841         struct qlcnic_cmd_args cmd;
1842
1843         if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) {
1844                 dev_err(&adapter->pdev->dev,
1845                         "%s: Error, invoked by non management func\n",
1846                         __func__);
1847                 return err;
1848         }
1849
1850         qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_TOGGLE_ESWITCH);
1851         cmd.req.arg[1] = (port & 0xf) | BIT_4;
1852         err = qlcnic_issue_cmd(adapter, &cmd);
1853
1854         if (err != QLCNIC_RCODE_SUCCESS) {
1855                 dev_err(&adapter->pdev->dev, "Failed to enable eswitch%d\n",
1856                         err);
1857                 err = -EIO;
1858         }
1859         qlcnic_free_mbx_args(&cmd);
1860
1861         return err;
1862
1863 }
1864
1865 int qlcnic_83xx_set_nic_info(struct qlcnic_adapter *adapter,
1866                              struct qlcnic_info *nic)
1867 {
1868         int i, err = -EIO;
1869         struct qlcnic_cmd_args cmd;
1870
1871         if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) {
1872                 dev_err(&adapter->pdev->dev,
1873                         "%s: Error, invoked by non management func\n",
1874                         __func__);
1875                 return err;
1876         }
1877
1878         qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_NIC_INFO);
1879         cmd.req.arg[1] = (nic->pci_func << 16);
1880         cmd.req.arg[2] = 0x1 << 16;
1881         cmd.req.arg[3] = nic->phys_port | (nic->switch_mode << 16);
1882         cmd.req.arg[4] = nic->capabilities;
1883         cmd.req.arg[5] = (nic->max_mac_filters & 0xFF) | ((nic->max_mtu) << 16);
1884         cmd.req.arg[6] = (nic->max_tx_ques) | ((nic->max_rx_ques) << 16);
1885         cmd.req.arg[7] = (nic->min_tx_bw) | ((nic->max_tx_bw) << 16);
1886         for (i = 8; i < 32; i++)
1887                 cmd.req.arg[i] = 0;
1888
1889         err = qlcnic_issue_cmd(adapter, &cmd);
1890
1891         if (err != QLCNIC_RCODE_SUCCESS) {
1892                 dev_err(&adapter->pdev->dev, "Failed to set nic info%d\n",
1893                         err);
1894                 err = -EIO;
1895         }
1896
1897         qlcnic_free_mbx_args(&cmd);
1898
1899         return err;
1900 }
1901
1902 int qlcnic_83xx_get_nic_info(struct qlcnic_adapter *adapter,
1903                              struct qlcnic_info *npar_info, u8 func_id)
1904 {
1905         int err;
1906         u32 temp;
1907         u8 op = 0;
1908         struct qlcnic_cmd_args cmd;
1909
1910         qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_NIC_INFO);
1911         if (func_id != adapter->ahw->pci_func) {
1912                 temp = func_id << 16;
1913                 cmd.req.arg[1] = op | BIT_31 | temp;
1914         } else {
1915                 cmd.req.arg[1] = adapter->ahw->pci_func << 16;
1916         }
1917         err = qlcnic_issue_cmd(adapter, &cmd);
1918         if (err) {
1919                 dev_info(&adapter->pdev->dev,
1920                          "Failed to get nic info %d\n", err);
1921                 goto out;
1922         }
1923
1924         npar_info->op_type = cmd.rsp.arg[1];
1925         npar_info->pci_func = cmd.rsp.arg[2] & 0xFFFF;
1926         npar_info->op_mode = (cmd.rsp.arg[2] & 0xFFFF0000) >> 16;
1927         npar_info->phys_port = cmd.rsp.arg[3] & 0xFFFF;
1928         npar_info->switch_mode = (cmd.rsp.arg[3] & 0xFFFF0000) >> 16;
1929         npar_info->capabilities = cmd.rsp.arg[4];
1930         npar_info->max_mac_filters = cmd.rsp.arg[5] & 0xFF;
1931         npar_info->max_mtu = (cmd.rsp.arg[5] & 0xFFFF0000) >> 16;
1932         npar_info->max_tx_ques = cmd.rsp.arg[6] & 0xFFFF;
1933         npar_info->max_rx_ques = (cmd.rsp.arg[6] & 0xFFFF0000) >> 16;
1934         npar_info->min_tx_bw = cmd.rsp.arg[7] & 0xFFFF;
1935         npar_info->max_tx_bw = (cmd.rsp.arg[7] & 0xFFFF0000) >> 16;
1936         if (cmd.rsp.arg[8] & 0x1)
1937                 npar_info->max_bw_reg_offset = (cmd.rsp.arg[8] & 0x7FFE) >> 1;
1938         if (cmd.rsp.arg[8] & 0x10000) {
1939                 temp = (cmd.rsp.arg[8] & 0x7FFE0000) >> 17;
1940                 npar_info->max_linkspeed_reg_offset = temp;
1941         }
1942
1943 out:
1944         qlcnic_free_mbx_args(&cmd);
1945         return err;
1946 }
1947
1948 int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *adapter,
1949                              struct qlcnic_pci_info *pci_info)
1950 {
1951         int i, err = 0, j = 0;
1952         u32 temp;
1953         struct qlcnic_cmd_args cmd;
1954
1955         qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_PCI_INFO);
1956         err = qlcnic_issue_cmd(adapter, &cmd);
1957
1958         adapter->ahw->act_pci_func = 0;
1959         if (err == QLCNIC_RCODE_SUCCESS) {
1960                 pci_info->func_count = cmd.rsp.arg[1] & 0xFF;
1961                 dev_info(&adapter->pdev->dev,
1962                          "%s: total functions = %d\n",
1963                          __func__, pci_info->func_count);
1964                 for (i = 2, j = 0; j < QLCNIC_MAX_PCI_FUNC; j++, pci_info++) {
1965                         pci_info->id = cmd.rsp.arg[i] & 0xFFFF;
1966                         pci_info->active = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
1967                         i++;
1968                         pci_info->type = cmd.rsp.arg[i] & 0xFFFF;
1969                         if (pci_info->type == QLCNIC_TYPE_NIC)
1970                                 adapter->ahw->act_pci_func++;
1971                         temp = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
1972                         pci_info->default_port = temp;
1973                         i++;
1974                         pci_info->tx_min_bw = cmd.rsp.arg[i] & 0xFFFF;
1975                         temp = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
1976                         pci_info->tx_max_bw = temp;
1977                         i = i + 2;
1978                         memcpy(pci_info->mac, &cmd.rsp.arg[i], ETH_ALEN - 2);
1979                         i++;
1980                         memcpy(pci_info->mac + sizeof(u32), &cmd.rsp.arg[i], 2);
1981                         i = i + 3;
1982
1983                         dev_info(&adapter->pdev->dev, "%s:\n"
1984                                  "\tid = %d active = %d type = %d\n"
1985                                  "\tport = %d min bw = %d max bw = %d\n"
1986                                  "\tmac_addr =  %pM\n", __func__,
1987                                  pci_info->id, pci_info->active, pci_info->type,
1988                                  pci_info->default_port, pci_info->tx_min_bw,
1989                                  pci_info->tx_max_bw, pci_info->mac);
1990                 }
1991         } else {
1992                 dev_err(&adapter->pdev->dev, "Failed to get PCI Info%d\n",
1993                         err);
1994                 err = -EIO;
1995         }
1996
1997         qlcnic_free_mbx_args(&cmd);
1998
1999         return err;
2000 }
2001
2002 int qlcnic_83xx_config_intrpt(struct qlcnic_adapter *adapter, bool op_type)
2003 {
2004         int i, index, err;
2005         bool type;
2006         u8 max_ints;
2007         u32 val, temp;
2008         struct qlcnic_cmd_args cmd;
2009
2010         max_ints = adapter->ahw->num_msix - 1;
2011         qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTRPT);
2012         cmd.req.arg[1] = max_ints;
2013         for (i = 0, index = 2; i < max_ints; i++) {
2014                 type = op_type ? QLCNIC_INTRPT_ADD : QLCNIC_INTRPT_DEL;
2015                 val = type | (adapter->ahw->intr_tbl[i].type << 4);
2016                 if (adapter->ahw->intr_tbl[i].type == QLCNIC_INTRPT_MSIX)
2017                         val |= (adapter->ahw->intr_tbl[i].id << 16);
2018                 cmd.req.arg[index++] = val;
2019         }
2020         err = qlcnic_issue_cmd(adapter, &cmd);
2021         if (err) {
2022                 dev_err(&adapter->pdev->dev,
2023                         "Failed to configure interrupts 0x%x\n", err);
2024                 goto out;
2025         }
2026
2027         max_ints = cmd.rsp.arg[1];
2028         for (i = 0, index = 2; i < max_ints; i++, index += 2) {
2029                 val = cmd.rsp.arg[index];
2030                 if (LSB(val)) {
2031                         dev_info(&adapter->pdev->dev,
2032                                  "Can't configure interrupt %d\n",
2033                                  adapter->ahw->intr_tbl[i].id);
2034                         continue;
2035                 }
2036                 if (op_type) {
2037                         adapter->ahw->intr_tbl[i].id = MSW(val);
2038                         adapter->ahw->intr_tbl[i].enabled = 1;
2039                         temp = cmd.rsp.arg[index + 1];
2040                         adapter->ahw->intr_tbl[i].src = temp;
2041                 } else {
2042                         adapter->ahw->intr_tbl[i].id = i;
2043                         adapter->ahw->intr_tbl[i].enabled = 0;
2044                         adapter->ahw->intr_tbl[i].src = 0;
2045                 }
2046         }
2047 out:
2048         qlcnic_free_mbx_args(&cmd);
2049         return err;
2050 }
2051
2052 int qlcnic_83xx_lock_flash(struct qlcnic_adapter *adapter)
2053 {
2054         int id, timeout = 0;
2055         u32 status = 0;
2056
2057         while (status == 0) {
2058                 status = QLC_SHARED_REG_RD32(adapter, QLCNIC_FLASH_LOCK);
2059                 if (status)
2060                         break;
2061
2062                 if (++timeout >= QLC_83XX_FLASH_LOCK_TIMEOUT) {
2063                         id = QLC_SHARED_REG_RD32(adapter,
2064                                                  QLCNIC_FLASH_LOCK_OWNER);
2065                         dev_err(&adapter->pdev->dev,
2066                                 "%s: failed, lock held by %d\n", __func__, id);
2067                         return -EIO;
2068                 }
2069                 usleep_range(1000, 2000);
2070         }
2071
2072         QLC_SHARED_REG_WR32(adapter, QLCNIC_FLASH_LOCK_OWNER, adapter->portnum);
2073         return 0;
2074 }
2075
2076 void qlcnic_83xx_unlock_flash(struct qlcnic_adapter *adapter)
2077 {
2078         QLC_SHARED_REG_RD32(adapter, QLCNIC_FLASH_UNLOCK);
2079         QLC_SHARED_REG_WR32(adapter, QLCNIC_FLASH_LOCK_OWNER, 0xFF);
2080 }
2081
2082 int qlcnic_83xx_lockless_flash_read32(struct qlcnic_adapter *adapter,
2083                                       u32 flash_addr, u8 *p_data,
2084                                       int count)
2085 {
2086         int i, ret;
2087         u32 word, range, flash_offset, addr = flash_addr;
2088         ulong indirect_add, direct_window;
2089
2090         flash_offset = addr & (QLCNIC_FLASH_SECTOR_SIZE - 1);
2091         if (addr & 0x3) {
2092                 dev_err(&adapter->pdev->dev, "Illegal addr = 0x%x\n", addr);
2093                 return -EIO;
2094         }
2095
2096         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_DIRECT_WINDOW,
2097                                      (addr));
2098
2099         range = flash_offset + (count * sizeof(u32));
2100         /* Check if data is spread across multiple sectors */
2101         if (range > (QLCNIC_FLASH_SECTOR_SIZE - 1)) {
2102
2103                 /* Multi sector read */
2104                 for (i = 0; i < count; i++) {
2105                         indirect_add = QLC_83XX_FLASH_DIRECT_DATA(addr);
2106                         ret = qlcnic_83xx_rd_reg_indirect(adapter,
2107                                                           indirect_add);
2108                         if (ret == -EIO)
2109                                 return -EIO;
2110
2111                         word = ret;
2112                         *(u32 *)p_data  = word;
2113                         p_data = p_data + 4;
2114                         addr = addr + 4;
2115                         flash_offset = flash_offset + 4;
2116
2117                         if (flash_offset > (QLCNIC_FLASH_SECTOR_SIZE - 1)) {
2118                                 direct_window = QLC_83XX_FLASH_DIRECT_WINDOW;
2119                                 /* This write is needed once for each sector */
2120                                 qlcnic_83xx_wrt_reg_indirect(adapter,
2121                                                              direct_window,
2122                                                              (addr));
2123                                 flash_offset = 0;
2124                         }
2125                 }
2126         } else {
2127                 /* Single sector read */
2128                 for (i = 0; i < count; i++) {
2129                         indirect_add = QLC_83XX_FLASH_DIRECT_DATA(addr);
2130                         ret = qlcnic_83xx_rd_reg_indirect(adapter,
2131                                                           indirect_add);
2132                         if (ret == -EIO)
2133                                 return -EIO;
2134
2135                         word = ret;
2136                         *(u32 *)p_data  = word;
2137                         p_data = p_data + 4;
2138                         addr = addr + 4;
2139                 }
2140         }
2141
2142         return 0;
2143 }
2144
2145 static int qlcnic_83xx_poll_flash_status_reg(struct qlcnic_adapter *adapter)
2146 {
2147         u32 status;
2148         int retries = QLC_83XX_FLASH_READ_RETRY_COUNT;
2149
2150         do {
2151                 status = qlcnic_83xx_rd_reg_indirect(adapter,
2152                                                      QLC_83XX_FLASH_STATUS);
2153                 if ((status & QLC_83XX_FLASH_STATUS_READY) ==
2154                     QLC_83XX_FLASH_STATUS_READY)
2155                         break;
2156
2157                 msleep(QLC_83XX_FLASH_STATUS_REG_POLL_DELAY);
2158         } while (--retries);
2159
2160         if (!retries)
2161                 return -EIO;
2162
2163         return 0;
2164 }
2165
2166 static int qlcnic_83xx_enable_flash_write_op(struct qlcnic_adapter *adapter)
2167 {
2168         int ret;
2169         u32 cmd;
2170         cmd = adapter->ahw->fdt.write_statusreg_cmd;
2171         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2172                                      (QLC_83XX_FLASH_FDT_WRITE_DEF_SIG | cmd));
2173         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA,
2174                                      adapter->ahw->fdt.write_enable_bits);
2175         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2176                                      QLC_83XX_FLASH_SECOND_ERASE_MS_VAL);
2177         ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2178         if (ret)
2179                 return -EIO;
2180
2181         return 0;
2182 }
2183
2184 static int qlcnic_83xx_disable_flash_write_op(struct qlcnic_adapter *adapter)
2185 {
2186         int ret;
2187
2188         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2189                                      (QLC_83XX_FLASH_FDT_WRITE_DEF_SIG |
2190                                      adapter->ahw->fdt.write_statusreg_cmd));
2191         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA,
2192                                      adapter->ahw->fdt.write_disable_bits);
2193         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2194                                      QLC_83XX_FLASH_SECOND_ERASE_MS_VAL);
2195         ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2196         if (ret)
2197                 return -EIO;
2198
2199         return 0;
2200 }
2201
2202 int qlcnic_83xx_read_flash_mfg_id(struct qlcnic_adapter *adapter)
2203 {
2204         int ret, mfg_id;
2205
2206         if (qlcnic_83xx_lock_flash(adapter))
2207                 return -EIO;
2208
2209         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2210                                      QLC_83XX_FLASH_FDT_READ_MFG_ID_VAL);
2211         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2212                                      QLC_83XX_FLASH_READ_CTRL);
2213         ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2214         if (ret) {
2215                 qlcnic_83xx_unlock_flash(adapter);
2216                 return -EIO;
2217         }
2218
2219         mfg_id = qlcnic_83xx_rd_reg_indirect(adapter, QLC_83XX_FLASH_RDDATA);
2220         if (mfg_id == -EIO)
2221                 return -EIO;
2222
2223         adapter->flash_mfg_id = (mfg_id & 0xFF);
2224         qlcnic_83xx_unlock_flash(adapter);
2225
2226         return 0;
2227 }
2228
2229 int qlcnic_83xx_read_flash_descriptor_table(struct qlcnic_adapter *adapter)
2230 {
2231         int count, fdt_size, ret = 0;
2232
2233         fdt_size = sizeof(struct qlcnic_fdt);
2234         count = fdt_size / sizeof(u32);
2235
2236         if (qlcnic_83xx_lock_flash(adapter))
2237                 return -EIO;
2238
2239         memset(&adapter->ahw->fdt, 0, fdt_size);
2240         ret = qlcnic_83xx_lockless_flash_read32(adapter, QLCNIC_FDT_LOCATION,
2241                                                 (u8 *)&adapter->ahw->fdt,
2242                                                 count);
2243
2244         qlcnic_83xx_unlock_flash(adapter);
2245         return ret;
2246 }
2247
2248 int qlcnic_83xx_erase_flash_sector(struct qlcnic_adapter *adapter,
2249                                    u32 sector_start_addr)
2250 {
2251         u32 reversed_addr, addr1, addr2, cmd;
2252         int ret = -EIO;
2253
2254         if (qlcnic_83xx_lock_flash(adapter) != 0)
2255                 return -EIO;
2256
2257         if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
2258                 ret = qlcnic_83xx_enable_flash_write_op(adapter);
2259                 if (ret) {
2260                         qlcnic_83xx_unlock_flash(adapter);
2261                         dev_err(&adapter->pdev->dev,
2262                                 "%s failed at %d\n",
2263                                 __func__, __LINE__);
2264                         return ret;
2265                 }
2266         }
2267
2268         ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2269         if (ret) {
2270                 qlcnic_83xx_unlock_flash(adapter);
2271                 dev_err(&adapter->pdev->dev,
2272                         "%s: failed at %d\n", __func__, __LINE__);
2273                 return -EIO;
2274         }
2275
2276         addr1 = (sector_start_addr & 0xFF) << 16;
2277         addr2 = (sector_start_addr & 0xFF0000) >> 16;
2278         reversed_addr = addr1 | addr2;
2279
2280         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA,
2281                                      reversed_addr);
2282         cmd = QLC_83XX_FLASH_FDT_ERASE_DEF_SIG | adapter->ahw->fdt.erase_cmd;
2283         if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id)
2284                 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR, cmd);
2285         else
2286                 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2287                                              QLC_83XX_FLASH_OEM_ERASE_SIG);
2288         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2289                                      QLC_83XX_FLASH_LAST_ERASE_MS_VAL);
2290
2291         ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2292         if (ret) {
2293                 qlcnic_83xx_unlock_flash(adapter);
2294                 dev_err(&adapter->pdev->dev,
2295                         "%s: failed at %d\n", __func__, __LINE__);
2296                 return -EIO;
2297         }
2298
2299         if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
2300                 ret = qlcnic_83xx_disable_flash_write_op(adapter);
2301                 if (ret) {
2302                         qlcnic_83xx_unlock_flash(adapter);
2303                         dev_err(&adapter->pdev->dev,
2304                                 "%s: failed at %d\n", __func__, __LINE__);
2305                         return ret;
2306                 }
2307         }
2308
2309         qlcnic_83xx_unlock_flash(adapter);
2310
2311         return 0;
2312 }
2313
2314 int qlcnic_83xx_flash_write32(struct qlcnic_adapter *adapter, u32 addr,
2315                               u32 *p_data)
2316 {
2317         int ret = -EIO;
2318         u32 addr1 = 0x00800000 | (addr >> 2);
2319
2320         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR, addr1);
2321         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA, *p_data);
2322         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2323                                      QLC_83XX_FLASH_LAST_ERASE_MS_VAL);
2324         ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2325         if (ret) {
2326                 dev_err(&adapter->pdev->dev,
2327                         "%s: failed at %d\n", __func__, __LINE__);
2328                 return -EIO;
2329         }
2330
2331         return 0;
2332 }
2333
2334 int qlcnic_83xx_flash_bulk_write(struct qlcnic_adapter *adapter, u32 addr,
2335                                  u32 *p_data, int count)
2336 {
2337         u32 temp;
2338         int ret = -EIO;
2339
2340         if ((count < QLC_83XX_FLASH_BULK_WRITE_MIN) ||
2341             (count > QLC_83XX_FLASH_BULK_WRITE_MAX)) {
2342                 dev_err(&adapter->pdev->dev,
2343                         "%s: Invalid word count\n", __func__);
2344                 return -EIO;
2345         }
2346
2347         temp = qlcnic_83xx_rd_reg_indirect(adapter,
2348                                            QLC_83XX_FLASH_SPI_CONTROL);
2349         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_SPI_CONTROL,
2350                                      (temp | QLC_83XX_FLASH_SPI_CTRL));
2351         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2352                                      QLC_83XX_FLASH_ADDR_TEMP_VAL);
2353
2354         /* First DWORD write */
2355         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA, *p_data++);
2356         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2357                                      QLC_83XX_FLASH_FIRST_MS_PATTERN);
2358         ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2359         if (ret) {
2360                 dev_err(&adapter->pdev->dev,
2361                         "%s: failed at %d\n", __func__, __LINE__);
2362                 return -EIO;
2363         }
2364
2365         count--;
2366         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2367                                      QLC_83XX_FLASH_ADDR_SECOND_TEMP_VAL);
2368         /* Second to N-1 DWORD writes */
2369         while (count != 1) {
2370                 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA,
2371                                              *p_data++);
2372                 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2373                                              QLC_83XX_FLASH_SECOND_MS_PATTERN);
2374                 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2375                 if (ret) {
2376                         dev_err(&adapter->pdev->dev,
2377                                 "%s: failed at %d\n", __func__, __LINE__);
2378                         return -EIO;
2379                 }
2380                 count--;
2381         }
2382
2383         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2384                                      QLC_83XX_FLASH_ADDR_TEMP_VAL |
2385                                      (addr >> 2));
2386         /* Last DWORD write */
2387         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA, *p_data++);
2388         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2389                                      QLC_83XX_FLASH_LAST_MS_PATTERN);
2390         ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2391         if (ret) {
2392                 dev_err(&adapter->pdev->dev,
2393                         "%s: failed at %d\n", __func__, __LINE__);
2394                 return -EIO;
2395         }
2396
2397         ret = qlcnic_83xx_rd_reg_indirect(adapter, QLC_83XX_FLASH_SPI_STATUS);
2398         if ((ret & QLC_83XX_FLASH_SPI_CTRL) == QLC_83XX_FLASH_SPI_CTRL) {
2399                 dev_err(&adapter->pdev->dev, "%s: failed at %d\n",
2400                         __func__, __LINE__);
2401                 /* Operation failed, clear error bit */
2402                 temp = qlcnic_83xx_rd_reg_indirect(adapter,
2403                                                    QLC_83XX_FLASH_SPI_CONTROL);
2404                 qlcnic_83xx_wrt_reg_indirect(adapter,
2405                                              QLC_83XX_FLASH_SPI_CONTROL,
2406                                              (temp | QLC_83XX_FLASH_SPI_CTRL));
2407         }
2408
2409         return 0;
2410 }
2411
2412 static void qlcnic_83xx_recover_driver_lock(struct qlcnic_adapter *adapter)
2413 {
2414         u32 val, id;
2415
2416         val = QLCRDX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK);
2417
2418         /* Check if recovery need to be performed by the calling function */
2419         if ((val & QLC_83XX_DRV_LOCK_RECOVERY_STATUS_MASK) == 0) {
2420                 val = val & ~0x3F;
2421                 val = val | ((adapter->portnum << 2) |
2422                              QLC_83XX_NEED_DRV_LOCK_RECOVERY);
2423                 QLCWRX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK, val);
2424                 dev_info(&adapter->pdev->dev,
2425                          "%s: lock recovery initiated\n", __func__);
2426                 msleep(QLC_83XX_DRV_LOCK_RECOVERY_DELAY);
2427                 val = QLCRDX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK);
2428                 id = ((val >> 2) & 0xF);
2429                 if (id == adapter->portnum) {
2430                         val = val & ~QLC_83XX_DRV_LOCK_RECOVERY_STATUS_MASK;
2431                         val = val | QLC_83XX_DRV_LOCK_RECOVERY_IN_PROGRESS;
2432                         QLCWRX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK, val);
2433                         /* Force release the lock */
2434                         QLCRDX(adapter->ahw, QLC_83XX_DRV_UNLOCK);
2435                         /* Clear recovery bits */
2436                         val = val & ~0x3F;
2437                         QLCWRX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK, val);
2438                         dev_info(&adapter->pdev->dev,
2439                                  "%s: lock recovery completed\n", __func__);
2440                 } else {
2441                         dev_info(&adapter->pdev->dev,
2442                                  "%s: func %d to resume lock recovery process\n",
2443                                  __func__, id);
2444                 }
2445         } else {
2446                 dev_info(&adapter->pdev->dev,
2447                          "%s: lock recovery initiated by other functions\n",
2448                          __func__);
2449         }
2450 }
2451
2452 int qlcnic_83xx_lock_driver(struct qlcnic_adapter *adapter)
2453 {
2454         u32 lock_alive_counter, val, id, i = 0, status = 0, temp = 0;
2455         int max_attempt = 0;
2456
2457         while (status == 0) {
2458                 status = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK);
2459                 if (status)
2460                         break;
2461
2462                 msleep(QLC_83XX_DRV_LOCK_WAIT_DELAY);
2463                 i++;
2464
2465                 if (i == 1)
2466                         temp = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
2467
2468                 if (i == QLC_83XX_DRV_LOCK_WAIT_COUNTER) {
2469                         val = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
2470                         if (val == temp) {
2471                                 id = val & 0xFF;
2472                                 dev_info(&adapter->pdev->dev,
2473                                          "%s: lock to be recovered from %d\n",
2474                                          __func__, id);
2475                                 qlcnic_83xx_recover_driver_lock(adapter);
2476                                 i = 0;
2477                                 max_attempt++;
2478                         } else {
2479                                 dev_err(&adapter->pdev->dev,
2480                                         "%s: failed to get lock\n", __func__);
2481                                 return -EIO;
2482                         }
2483                 }
2484
2485                 /* Force exit from while loop after few attempts */
2486                 if (max_attempt == QLC_83XX_MAX_DRV_LOCK_RECOVERY_ATTEMPT) {
2487                         dev_err(&adapter->pdev->dev,
2488                                 "%s: failed to get lock\n", __func__);
2489                         return -EIO;
2490                 }
2491         }
2492
2493         val = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
2494         lock_alive_counter = val >> 8;
2495         lock_alive_counter++;
2496         val = lock_alive_counter << 8 | adapter->portnum;
2497         QLCWRX(adapter->ahw, QLC_83XX_DRV_LOCK_ID, val);
2498
2499         return 0;
2500 }
2501
2502 void qlcnic_83xx_unlock_driver(struct qlcnic_adapter *adapter)
2503 {
2504         u32 val, lock_alive_counter, id;
2505
2506         val = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
2507         id = val & 0xFF;
2508         lock_alive_counter = val >> 8;
2509
2510         if (id != adapter->portnum)
2511                 dev_err(&adapter->pdev->dev,
2512                         "%s:Warning func %d is unlocking lock owned by %d\n",
2513                         __func__, adapter->portnum, id);
2514
2515         val = (lock_alive_counter << 8) | 0xFF;
2516         QLCWRX(adapter->ahw, QLC_83XX_DRV_LOCK_ID, val);
2517         QLCRDX(adapter->ahw, QLC_83XX_DRV_UNLOCK);
2518 }
2519
2520 int qlcnic_83xx_ms_mem_write128(struct qlcnic_adapter *adapter, u64 addr,
2521                                 u32 *data, u32 count)
2522 {
2523         int i, j, ret = 0;
2524         u32 temp;
2525
2526         /* Check alignment */
2527         if (addr & 0xF)
2528                 return -EIO;
2529
2530         mutex_lock(&adapter->ahw->mem_lock);
2531         qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_ADDR_HI, 0);
2532
2533         for (i = 0; i < count; i++, addr += 16) {
2534                 if (!((ADDR_IN_RANGE(addr, QLCNIC_ADDR_QDR_NET,
2535                                      QLCNIC_ADDR_QDR_NET_MAX)) ||
2536                       (ADDR_IN_RANGE(addr, QLCNIC_ADDR_DDR_NET,
2537                                      QLCNIC_ADDR_DDR_NET_MAX)))) {
2538                         mutex_unlock(&adapter->ahw->mem_lock);
2539                         return -EIO;
2540                 }
2541
2542                 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_ADDR_LO, addr);
2543                 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_LO,
2544                                              *data++);
2545                 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_HI,
2546                                              *data++);
2547                 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_ULO,
2548                                              *data++);
2549                 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_UHI,
2550                                              *data++);
2551                 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_CTRL,
2552                                              QLCNIC_TA_WRITE_ENABLE);
2553                 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_CTRL,
2554                                              QLCNIC_TA_WRITE_START);
2555
2556                 for (j = 0; j < MAX_CTL_CHECK; j++) {
2557                         temp = qlcnic_83xx_rd_reg_indirect(adapter,
2558                                                            QLCNIC_MS_CTRL);
2559                         if ((temp & TA_CTL_BUSY) == 0)
2560                                 break;
2561                 }
2562
2563                 /* Status check failure */
2564                 if (j >= MAX_CTL_CHECK) {
2565                         printk_ratelimited(KERN_WARNING
2566                                            "MS memory write failed\n");
2567                         mutex_unlock(&adapter->ahw->mem_lock);
2568                         return -EIO;
2569                 }
2570         }
2571
2572         mutex_unlock(&adapter->ahw->mem_lock);
2573
2574         return ret;
2575 }
2576
2577 int qlcnic_83xx_flash_read32(struct qlcnic_adapter *adapter, u32 flash_addr,
2578                              u8 *p_data, int count)
2579 {
2580         int i, ret;
2581         u32 word, addr = flash_addr;
2582         ulong  indirect_addr;
2583
2584         if (qlcnic_83xx_lock_flash(adapter) != 0)
2585                 return -EIO;
2586
2587         if (addr & 0x3) {
2588                 dev_err(&adapter->pdev->dev, "Illegal addr = 0x%x\n", addr);
2589                 qlcnic_83xx_unlock_flash(adapter);
2590                 return -EIO;
2591         }
2592
2593         for (i = 0; i < count; i++) {
2594                 if (qlcnic_83xx_wrt_reg_indirect(adapter,
2595                                                  QLC_83XX_FLASH_DIRECT_WINDOW,
2596                                                  (addr))) {
2597                         qlcnic_83xx_unlock_flash(adapter);
2598                         return -EIO;
2599                 }
2600
2601                 indirect_addr = QLC_83XX_FLASH_DIRECT_DATA(addr);
2602                 ret = qlcnic_83xx_rd_reg_indirect(adapter,
2603                                                   indirect_addr);
2604                 if (ret == -EIO)
2605                         return -EIO;
2606                 word = ret;
2607                 *(u32 *)p_data  = word;
2608                 p_data = p_data + 4;
2609                 addr = addr + 4;
2610         }
2611
2612         qlcnic_83xx_unlock_flash(adapter);
2613
2614         return 0;
2615 }
2616
2617 int qlcnic_83xx_test_link(struct qlcnic_adapter *adapter)
2618 {
2619         int err;
2620         u32 config = 0, state;
2621         struct qlcnic_cmd_args cmd;
2622         struct qlcnic_hardware_context *ahw = adapter->ahw;
2623
2624         state = readl(ahw->pci_base0 + QLC_83XX_LINK_STATE(ahw->pci_func));
2625         if (!QLC_83xx_FUNC_VAL(state, ahw->pci_func)) {
2626                 dev_info(&adapter->pdev->dev, "link state down\n");
2627                 return config;
2628         }
2629         qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_LINK_STATUS);
2630         err = qlcnic_issue_cmd(adapter, &cmd);
2631         if (err) {
2632                 dev_info(&adapter->pdev->dev,
2633                          "Get Link Status Command failed: 0x%x\n", err);
2634                 goto out;
2635         } else {
2636                 config = cmd.rsp.arg[1];
2637                 switch (QLC_83XX_CURRENT_LINK_SPEED(config)) {
2638                 case QLC_83XX_10M_LINK:
2639                         ahw->link_speed = SPEED_10;
2640                         break;
2641                 case QLC_83XX_100M_LINK:
2642                         ahw->link_speed = SPEED_100;
2643                         break;
2644                 case QLC_83XX_1G_LINK:
2645                         ahw->link_speed = SPEED_1000;
2646                         break;
2647                 case QLC_83XX_10G_LINK:
2648                         ahw->link_speed = SPEED_10000;
2649                         break;
2650                 default:
2651                         ahw->link_speed = 0;
2652                         break;
2653                 }
2654                 config = cmd.rsp.arg[3];
2655                 if (config & 1)
2656                         err = 1;
2657         }
2658 out:
2659         qlcnic_free_mbx_args(&cmd);
2660         return config;
2661 }
2662
2663 int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter)
2664 {
2665         u32 config = 0;
2666         int status = 0;
2667         struct qlcnic_hardware_context *ahw = adapter->ahw;
2668
2669         /* Get port configuration info */
2670         status = qlcnic_83xx_get_port_info(adapter);
2671         /* Get Link Status related info */
2672         config = qlcnic_83xx_test_link(adapter);
2673         ahw->module_type = QLC_83XX_SFP_MODULE_TYPE(config);
2674         /* hard code until there is a way to get it from flash */
2675         ahw->board_type = QLCNIC_BRDTYPE_83XX_10G;
2676         return status;
2677 }
2678
2679 int qlcnic_83xx_set_settings(struct qlcnic_adapter *adapter,
2680                              struct ethtool_cmd *ecmd)
2681 {
2682         int status = 0;
2683         u32 config = adapter->ahw->port_config;
2684
2685         if (ecmd->autoneg)
2686                 adapter->ahw->port_config |= BIT_15;
2687
2688         switch (ethtool_cmd_speed(ecmd)) {
2689         case SPEED_10:
2690                 adapter->ahw->port_config |= BIT_8;
2691                 break;
2692         case SPEED_100:
2693                 adapter->ahw->port_config |= BIT_9;
2694                 break;
2695         case SPEED_1000:
2696                 adapter->ahw->port_config |= BIT_10;
2697                 break;
2698         case SPEED_10000:
2699                 adapter->ahw->port_config |= BIT_11;
2700                 break;
2701         default:
2702                 return -EINVAL;
2703         }
2704
2705         status = qlcnic_83xx_set_port_config(adapter);
2706         if (status) {
2707                 dev_info(&adapter->pdev->dev,
2708                          "Faild to Set Link Speed and autoneg.\n");
2709                 adapter->ahw->port_config = config;
2710         }
2711         return status;
2712 }
2713
2714 static inline u64 *qlcnic_83xx_copy_stats(struct qlcnic_cmd_args *cmd,
2715                                           u64 *data, int index)
2716 {
2717         u32 low, hi;
2718         u64 val;
2719
2720         low = cmd->rsp.arg[index];
2721         hi = cmd->rsp.arg[index + 1];
2722         val = (((u64) low) | (((u64) hi) << 32));
2723         *data++ = val;
2724         return data;
2725 }
2726
2727 static u64 *qlcnic_83xx_fill_stats(struct qlcnic_adapter *adapter,
2728                                    struct qlcnic_cmd_args *cmd, u64 *data,
2729                                    int type, int *ret)
2730 {
2731         int err, k, total_regs;
2732
2733         *ret = 0;
2734         err = qlcnic_issue_cmd(adapter, cmd);
2735         if (err != QLCNIC_RCODE_SUCCESS) {
2736                 dev_info(&adapter->pdev->dev,
2737                          "Error in get statistics mailbox command\n");
2738                 *ret = -EIO;
2739                 return data;
2740         }
2741         total_regs = cmd->rsp.num;
2742         switch (type) {
2743         case QLC_83XX_STAT_MAC:
2744                 /* fill in MAC tx counters */
2745                 for (k = 2; k < 28; k += 2)
2746                         data = qlcnic_83xx_copy_stats(cmd, data, k);
2747                 /* skip 24 bytes of reserved area */
2748                 /* fill in MAC rx counters */
2749                 for (k += 6; k < 60; k += 2)
2750                         data = qlcnic_83xx_copy_stats(cmd, data, k);
2751                 /* skip 24 bytes of reserved area */
2752                 /* fill in MAC rx frame stats */
2753                 for (k += 6; k < 80; k += 2)
2754                         data = qlcnic_83xx_copy_stats(cmd, data, k);
2755                 break;
2756         case QLC_83XX_STAT_RX:
2757                 for (k = 2; k < 8; k += 2)
2758                         data = qlcnic_83xx_copy_stats(cmd, data, k);
2759                 /* skip 8 bytes of reserved data */
2760                 for (k += 2; k < 24; k += 2)
2761                         data = qlcnic_83xx_copy_stats(cmd, data, k);
2762                 /* skip 8 bytes containing RE1FBQ error data */
2763                 for (k += 2; k < total_regs; k += 2)
2764                         data = qlcnic_83xx_copy_stats(cmd, data, k);
2765                 break;
2766         case QLC_83XX_STAT_TX:
2767                 for (k = 2; k < 10; k += 2)
2768                         data = qlcnic_83xx_copy_stats(cmd, data, k);
2769                 /* skip 8 bytes of reserved data */
2770                 for (k += 2; k < total_regs; k += 2)
2771                         data = qlcnic_83xx_copy_stats(cmd, data, k);
2772                 break;
2773         default:
2774                 dev_warn(&adapter->pdev->dev, "Unknown get statistics mode\n");
2775                 *ret = -EIO;
2776         }
2777         return data;
2778 }
2779
2780 void qlcnic_83xx_get_stats(struct qlcnic_adapter *adapter, u64 *data)
2781 {
2782         struct qlcnic_cmd_args cmd;
2783         int ret = 0;
2784
2785         qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_STATISTICS);
2786         /* Get Tx stats */
2787         cmd.req.arg[1] = BIT_1 | (adapter->tx_ring->ctx_id << 16);
2788         cmd.rsp.num = QLC_83XX_TX_STAT_REGS;
2789         data = qlcnic_83xx_fill_stats(adapter, &cmd, data,
2790                                       QLC_83XX_STAT_TX, &ret);
2791         if (ret) {
2792                 dev_info(&adapter->pdev->dev, "Error getting MAC stats\n");
2793                 goto out;
2794         }
2795         /* Get MAC stats */
2796         cmd.req.arg[1] = BIT_2 | (adapter->portnum << 16);
2797         cmd.rsp.num = QLC_83XX_MAC_STAT_REGS;
2798         memset(cmd.rsp.arg, 0, sizeof(u32) * cmd.rsp.num);
2799         data = qlcnic_83xx_fill_stats(adapter, &cmd, data,
2800                                       QLC_83XX_STAT_MAC, &ret);
2801         if (ret) {
2802                 dev_info(&adapter->pdev->dev,
2803                          "Error getting Rx stats\n");
2804                 goto out;
2805         }
2806         /* Get Rx stats */
2807         cmd.req.arg[1] = adapter->recv_ctx->context_id << 16;
2808         cmd.rsp.num = QLC_83XX_RX_STAT_REGS;
2809         memset(cmd.rsp.arg, 0, sizeof(u32) * cmd.rsp.num);
2810         data = qlcnic_83xx_fill_stats(adapter, &cmd, data,
2811                                       QLC_83XX_STAT_RX, &ret);
2812         if (ret)
2813                 dev_info(&adapter->pdev->dev,
2814                          "Error getting Tx stats\n");
2815 out:
2816         qlcnic_free_mbx_args(&cmd);
2817 }
2818
2819 int qlcnic_83xx_reg_test(struct qlcnic_adapter *adapter)
2820 {
2821         u32 major, minor, sub;
2822
2823         major = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MAJOR);
2824         minor = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MINOR);
2825         sub = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_SUB);
2826
2827         if (adapter->fw_version != QLCNIC_VERSION_CODE(major, minor, sub)) {
2828                 dev_info(&adapter->pdev->dev, "%s: Reg test failed\n",
2829                          __func__);
2830                 return 1;
2831         }
2832         return 0;
2833 }
2834
2835 int qlcnic_83xx_get_regs_len(struct qlcnic_adapter *adapter)
2836 {
2837         return (ARRAY_SIZE(qlcnic_83xx_ext_reg_tbl) *
2838                 sizeof(adapter->ahw->ext_reg_tbl)) +
2839                 (ARRAY_SIZE(qlcnic_83xx_reg_tbl) +
2840                 sizeof(adapter->ahw->reg_tbl));
2841 }
2842
2843 int qlcnic_83xx_get_registers(struct qlcnic_adapter *adapter, u32 *regs_buff)
2844 {
2845         int i, j = 0;
2846
2847         for (i = QLCNIC_DEV_INFO_SIZE + 1;
2848              j < ARRAY_SIZE(qlcnic_83xx_reg_tbl); i++, j++)
2849                 regs_buff[i] = QLC_SHARED_REG_RD32(adapter, j);
2850
2851         for (j = 0; j < ARRAY_SIZE(qlcnic_83xx_ext_reg_tbl); j++)
2852                 regs_buff[i++] = QLCRDX(adapter->ahw, j);
2853         return i;
2854 }
2855
2856 int qlcnic_83xx_interrupt_test(struct net_device *netdev)
2857 {
2858         struct qlcnic_adapter *adapter = netdev_priv(netdev);
2859         struct qlcnic_hardware_context *ahw = adapter->ahw;
2860         struct qlcnic_cmd_args cmd;
2861         u32 data;
2862         u16 intrpt_id, id;
2863         u8 val;
2864         int ret, max_sds_rings = adapter->max_sds_rings;
2865
2866         if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
2867                 return -EIO;
2868
2869         ret = qlcnic_83xx_diag_alloc_res(netdev, QLCNIC_INTERRUPT_TEST);
2870         if (ret)
2871                 goto fail_diag_irq;
2872
2873         ahw->diag_cnt = 0;
2874         qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_INTRPT_TEST);
2875
2876         if (adapter->flags & QLCNIC_MSIX_ENABLED)
2877                 intrpt_id = ahw->intr_tbl[0].id;
2878         else
2879                 intrpt_id = QLCRDX(ahw, QLCNIC_DEF_INT_ID);
2880
2881         cmd.req.arg[1] = 1;
2882         cmd.req.arg[2] = intrpt_id;
2883         cmd.req.arg[3] = BIT_0;
2884
2885         ret = qlcnic_issue_cmd(adapter, &cmd);
2886         data = cmd.rsp.arg[2];
2887         id = LSW(data);
2888         val = LSB(MSW(data));
2889         if (id != intrpt_id)
2890                 dev_info(&adapter->pdev->dev,
2891                          "Interrupt generated: 0x%x, requested:0x%x\n",
2892                          id, intrpt_id);
2893         if (val)
2894                 dev_err(&adapter->pdev->dev,
2895                          "Interrupt test error: 0x%x\n", val);
2896         if (ret)
2897                 goto done;
2898
2899         msleep(20);
2900         ret = !ahw->diag_cnt;
2901
2902 done:
2903         qlcnic_free_mbx_args(&cmd);
2904         qlcnic_83xx_diag_free_res(netdev, max_sds_rings);
2905
2906 fail_diag_irq:
2907         adapter->max_sds_rings = max_sds_rings;
2908         clear_bit(__QLCNIC_RESETTING, &adapter->state);
2909         return ret;
2910 }
2911
2912 void qlcnic_83xx_get_pauseparam(struct qlcnic_adapter *adapter,
2913                                 struct ethtool_pauseparam *pause)
2914 {
2915         struct qlcnic_hardware_context *ahw = adapter->ahw;
2916         int status = 0;
2917         u32 config;
2918
2919         status = qlcnic_83xx_get_port_config(adapter);
2920         if (status) {
2921                 dev_err(&adapter->pdev->dev,
2922                         "%s: Get Pause Config failed\n", __func__);
2923                 return;
2924         }
2925         config = ahw->port_config;
2926         if (config & QLC_83XX_CFG_STD_PAUSE) {
2927                 if (config & QLC_83XX_CFG_STD_TX_PAUSE)
2928                         pause->tx_pause = 1;
2929                 if (config & QLC_83XX_CFG_STD_RX_PAUSE)
2930                         pause->rx_pause = 1;
2931         }
2932
2933         if (QLC_83XX_AUTONEG(config))
2934                 pause->autoneg = 1;
2935 }
2936
2937 int qlcnic_83xx_set_pauseparam(struct qlcnic_adapter *adapter,
2938                                struct ethtool_pauseparam *pause)
2939 {
2940         struct qlcnic_hardware_context *ahw = adapter->ahw;
2941         int status = 0;
2942         u32 config;
2943
2944         status = qlcnic_83xx_get_port_config(adapter);
2945         if (status) {
2946                 dev_err(&adapter->pdev->dev,
2947                         "%s: Get Pause Config failed.\n", __func__);
2948                 return status;
2949         }
2950         config = ahw->port_config;
2951
2952         if (ahw->port_type == QLCNIC_GBE) {
2953                 if (pause->autoneg)
2954                         ahw->port_config |= QLC_83XX_ENABLE_AUTONEG;
2955                 if (!pause->autoneg)
2956                         ahw->port_config &= ~QLC_83XX_ENABLE_AUTONEG;
2957         } else if ((ahw->port_type == QLCNIC_XGBE) && (pause->autoneg)) {
2958                 return -EOPNOTSUPP;
2959         }
2960
2961         if (!(config & QLC_83XX_CFG_STD_PAUSE))
2962                 ahw->port_config |= QLC_83XX_CFG_STD_PAUSE;
2963
2964         if (pause->rx_pause && pause->tx_pause) {
2965                 ahw->port_config |= QLC_83XX_CFG_STD_TX_RX_PAUSE;
2966         } else if (pause->rx_pause && !pause->tx_pause) {
2967                 ahw->port_config &= ~QLC_83XX_CFG_STD_TX_PAUSE;
2968                 ahw->port_config |= QLC_83XX_CFG_STD_RX_PAUSE;
2969         } else if (pause->tx_pause && !pause->rx_pause) {
2970                 ahw->port_config &= ~QLC_83XX_CFG_STD_RX_PAUSE;
2971                 ahw->port_config |= QLC_83XX_CFG_STD_TX_PAUSE;
2972         } else if (!pause->rx_pause && !pause->tx_pause) {
2973                 ahw->port_config &= ~QLC_83XX_CFG_STD_TX_RX_PAUSE;
2974         }
2975         status = qlcnic_83xx_set_port_config(adapter);
2976         if (status) {
2977                 dev_err(&adapter->pdev->dev,
2978                         "%s: Set Pause Config failed.\n", __func__);
2979                 ahw->port_config = config;
2980         }
2981         return status;
2982 }
2983
2984 static int qlcnic_83xx_read_flash_status_reg(struct qlcnic_adapter *adapter)
2985 {
2986         int ret;
2987
2988         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2989                                      QLC_83XX_FLASH_OEM_READ_SIG);
2990         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2991                                      QLC_83XX_FLASH_READ_CTRL);
2992         ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2993         if (ret)
2994                 return -EIO;
2995
2996         ret = qlcnic_83xx_rd_reg_indirect(adapter, QLC_83XX_FLASH_RDDATA);
2997         return ret & 0xFF;
2998 }
2999
3000 int qlcnic_83xx_flash_test(struct qlcnic_adapter *adapter)
3001 {
3002         int status;
3003
3004         status = qlcnic_83xx_read_flash_status_reg(adapter);
3005         if (status == -EIO) {
3006                 dev_info(&adapter->pdev->dev, "%s: EEPROM test failed.\n",
3007                          __func__);
3008                 return 1;
3009         }
3010         return 0;
3011 }