qlcnic: 83xx CNA inter driver communication mechanism
[pandora-kernel.git] / drivers / net / ethernet / qlogic / qlcnic / qlcnic_83xx_hw.c
1 #include "qlcnic.h"
2 #include <linux/if_vlan.h>
3 #include <linux/ipv6.h>
4 #include <linux/ethtool.h>
5 #include <linux/interrupt.h>
6
7 #define QLCNIC_MAX_TX_QUEUES            1
8
9 #define QLCNIC_MBX_RSP(reg)             LSW(reg)
10 #define QLCNIC_MBX_NUM_REGS(reg)        (MSW(reg) & 0x1FF)
11 #define QLCNIC_MBX_STATUS(reg)          (((reg) >> 25) & 0x7F)
12 #define QLCNIC_MBX_HOST(ahw, i) ((ahw)->pci_base0 + ((i) * 4))
13 #define QLCNIC_MBX_FW(ahw, i)           ((ahw)->pci_base0 + 0x800 + ((i) * 4))
14
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_loopback                = qlcnic_83xx_set_lb_mode,
261         .clear_loopback                 = qlcnic_83xx_clear_lb_mode,
262         .config_promisc_mode            = qlcnic_83xx_nic_set_promisc,
263         .change_l2_filter               = qlcnic_83xx_change_l2_filter,
264         .get_board_info                 = qlcnic_83xx_get_port_info,
265 };
266
267 static struct qlcnic_nic_template qlcnic_83xx_ops = {
268         .config_bridged_mode    = qlcnic_config_bridged_mode,
269         .config_led             = qlcnic_config_led,
270         .request_reset          = qlcnic_83xx_idc_request_reset,
271         .cancel_idc_work        = qlcnic_83xx_idc_exit,
272         .napi_add               = qlcnic_83xx_napi_add,
273         .napi_del               = qlcnic_83xx_napi_del,
274         .config_ipaddr          = qlcnic_83xx_config_ipaddr,
275         .clear_legacy_intr      = qlcnic_83xx_clear_legacy_intr,
276 };
277
278 void qlcnic_83xx_register_map(struct qlcnic_hardware_context *ahw)
279 {
280         ahw->hw_ops             = &qlcnic_83xx_hw_ops;
281         ahw->reg_tbl            = (u32 *)qlcnic_83xx_reg_tbl;
282         ahw->ext_reg_tbl        = (u32 *)qlcnic_83xx_ext_reg_tbl;
283 }
284
285 int qlcnic_83xx_get_fw_version(struct qlcnic_adapter *adapter)
286 {
287         u32 fw_major, fw_minor, fw_build;
288         struct pci_dev *pdev = adapter->pdev;
289
290         fw_major = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MAJOR);
291         fw_minor = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MINOR);
292         fw_build = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_SUB);
293         adapter->fw_version = QLCNIC_VERSION_CODE(fw_major, fw_minor, fw_build);
294
295         dev_info(&pdev->dev, "Driver v%s, firmware version %d.%d.%d\n",
296                  QLCNIC_LINUX_VERSIONID, fw_major, fw_minor, fw_build);
297
298         return adapter->fw_version;
299 }
300
301 static int __qlcnic_set_win_base(struct qlcnic_adapter *adapter, u32 addr)
302 {
303         void __iomem *base;
304         u32 val;
305
306         base = adapter->ahw->pci_base0 +
307                QLC_83XX_CRB_WIN_FUNC(adapter->ahw->pci_func);
308         writel(addr, base);
309         val = readl(base);
310         if (val != addr)
311                 return -EIO;
312
313         return 0;
314 }
315
316 int qlcnic_83xx_rd_reg_indirect(struct qlcnic_adapter *adapter, ulong addr)
317 {
318         int ret;
319         struct qlcnic_hardware_context *ahw = adapter->ahw;
320
321         ret = __qlcnic_set_win_base(adapter, (u32) addr);
322         if (!ret) {
323                 return QLCRDX(ahw, QLCNIC_WILDCARD);
324         } else {
325                 dev_err(&adapter->pdev->dev,
326                         "%s failed, addr = 0x%x\n", __func__, (int)addr);
327                 return -EIO;
328         }
329 }
330
331 int qlcnic_83xx_wrt_reg_indirect(struct qlcnic_adapter *adapter, ulong addr,
332                                  u32 data)
333 {
334         int err;
335         struct qlcnic_hardware_context *ahw = adapter->ahw;
336
337         err = __qlcnic_set_win_base(adapter, (u32) addr);
338         if (!err) {
339                 QLCWRX(ahw, QLCNIC_WILDCARD, data);
340                 return 0;
341         } else {
342                 dev_err(&adapter->pdev->dev,
343                         "%s failed, addr = 0x%x data = 0x%x\n",
344                         __func__, (int)addr, data);
345                 return err;
346         }
347 }
348
349 int qlcnic_83xx_setup_intr(struct qlcnic_adapter *adapter, u8 num_intr)
350 {
351         int err, i, num_msix;
352         struct qlcnic_hardware_context *ahw = adapter->ahw;
353
354         if (!num_intr)
355                 num_intr = QLCNIC_DEF_NUM_STS_DESC_RINGS;
356         num_msix = rounddown_pow_of_two(min_t(int, num_online_cpus(),
357                                               num_intr));
358         /* account for AEN interrupt MSI-X based interrupts */
359         num_msix += 1;
360         num_msix += adapter->max_drv_tx_rings;
361         err = qlcnic_enable_msix(adapter, num_msix);
362         if (err == -ENOMEM)
363                 return err;
364         if (adapter->flags & QLCNIC_MSIX_ENABLED)
365                 num_msix = adapter->ahw->num_msix;
366         else
367                 num_msix = 1;
368         /* setup interrupt mapping table for fw */
369         ahw->intr_tbl = vzalloc(num_msix *
370                                 sizeof(struct qlcnic_intrpt_config));
371         if (!ahw->intr_tbl)
372                 return -ENOMEM;
373         if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) {
374                 /* MSI-X enablement failed, use legacy interrupt */
375                 adapter->tgt_status_reg = ahw->pci_base0 + QLC_83XX_INTX_PTR;
376                 adapter->tgt_mask_reg = ahw->pci_base0 + QLC_83XX_INTX_MASK;
377                 adapter->isr_int_vec = ahw->pci_base0 + QLC_83XX_INTX_TRGR;
378                 adapter->msix_entries[0].vector = adapter->pdev->irq;
379                 dev_info(&adapter->pdev->dev, "using legacy interrupt\n");
380         }
381
382         for (i = 0; i < num_msix; i++) {
383                 if (adapter->flags & QLCNIC_MSIX_ENABLED)
384                         ahw->intr_tbl[i].type = QLCNIC_INTRPT_MSIX;
385                 else
386                         ahw->intr_tbl[i].type = QLCNIC_INTRPT_INTX;
387                 ahw->intr_tbl[i].id = i;
388                 ahw->intr_tbl[i].src = 0;
389         }
390         return 0;
391 }
392
393 inline void qlcnic_83xx_enable_intr(struct qlcnic_adapter *adapter,
394                                     struct qlcnic_host_sds_ring *sds_ring)
395 {
396         writel(0, sds_ring->crb_intr_mask);
397         if (!QLCNIC_IS_MSI_FAMILY(adapter))
398                 writel(0, adapter->tgt_mask_reg);
399 }
400
401 static inline void qlcnic_83xx_get_mbx_data(struct qlcnic_adapter *adapter,
402                                      struct qlcnic_cmd_args *cmd)
403 {
404         int i;
405         for (i = 0; i < cmd->rsp.num; i++)
406                 cmd->rsp.arg[i] = readl(QLCNIC_MBX_FW(adapter->ahw, i));
407 }
408
409 irqreturn_t qlcnic_83xx_clear_legacy_intr(struct qlcnic_adapter *adapter)
410 {
411         u32 intr_val;
412         struct qlcnic_hardware_context *ahw = adapter->ahw;
413         int retries = 0;
414
415         intr_val = readl(adapter->tgt_status_reg);
416
417         if (!QLC_83XX_VALID_INTX_BIT31(intr_val))
418                 return IRQ_NONE;
419
420         if (QLC_83XX_INTX_FUNC(intr_val) != adapter->ahw->pci_func) {
421                 adapter->stats.spurious_intr++;
422                 return IRQ_NONE;
423         }
424         /* clear the interrupt trigger control register */
425         writel(0, adapter->isr_int_vec);
426         do {
427                 intr_val = readl(adapter->tgt_status_reg);
428                 if (QLC_83XX_INTX_FUNC(intr_val) != ahw->pci_func)
429                         break;
430                 retries++;
431         } while (QLC_83XX_VALID_INTX_BIT30(intr_val) &&
432                  (retries < QLC_83XX_LEGACY_INTX_MAX_RETRY));
433
434         if (retries == QLC_83XX_LEGACY_INTX_MAX_RETRY) {
435                 dev_info(&adapter->pdev->dev,
436                          "Reached maximum retries to clear legacy interrupt\n");
437                 return IRQ_NONE;
438         }
439
440         mdelay(QLC_83XX_LEGACY_INTX_DELAY);
441
442         return IRQ_HANDLED;
443 }
444
445 irqreturn_t qlcnic_83xx_tmp_intr(int irq, void *data)
446 {
447         struct qlcnic_host_sds_ring *sds_ring = data;
448         struct qlcnic_adapter *adapter = sds_ring->adapter;
449
450         if (adapter->flags & QLCNIC_MSIX_ENABLED)
451                 goto done;
452
453         if (adapter->nic_ops->clear_legacy_intr(adapter) == IRQ_NONE)
454                 return IRQ_NONE;
455
456 done:
457         adapter->ahw->diag_cnt++;
458         qlcnic_83xx_enable_intr(adapter, sds_ring);
459
460         return IRQ_HANDLED;
461 }
462
463 void qlcnic_83xx_free_mbx_intr(struct qlcnic_adapter *adapter)
464 {
465         u32 val = 0;
466         u32 num_msix = adapter->ahw->num_msix - 1;
467
468         val = (num_msix << 8);
469
470         QLCWRX(adapter->ahw, QLCNIC_MBX_INTR_ENBL, val);
471         if (adapter->flags & QLCNIC_MSIX_ENABLED)
472                 free_irq(adapter->msix_entries[num_msix].vector, adapter);
473 }
474
475 int qlcnic_83xx_setup_mbx_intr(struct qlcnic_adapter *adapter)
476 {
477         irq_handler_t handler;
478         u32 val;
479         char name[32];
480         int err = 0;
481         unsigned long flags = 0;
482
483         if (!(adapter->flags & QLCNIC_MSI_ENABLED) &&
484             !(adapter->flags & QLCNIC_MSIX_ENABLED))
485                 flags |= IRQF_SHARED;
486
487         if (adapter->flags & QLCNIC_MSIX_ENABLED) {
488                 handler = qlcnic_83xx_handle_aen;
489                 val = adapter->msix_entries[adapter->ahw->num_msix - 1].vector;
490                 snprintf(name, (IFNAMSIZ + 4),
491                          "%s[%s]", adapter->netdev->name, "aen");
492                 err = request_irq(val, handler, flags, name, adapter);
493                 if (err) {
494                         dev_err(&adapter->pdev->dev,
495                                 "failed to register MBX interrupt\n");
496                         return err;
497                 }
498         }
499
500         /* Enable mailbox interrupt */
501         qlcnic_83xx_enable_mbx_intrpt(adapter);
502         if (adapter->flags & QLCNIC_MSIX_ENABLED)
503                 err = qlcnic_83xx_config_intrpt(adapter, 1);
504
505         return err;
506 }
507
508 void qlcnic_83xx_get_func_no(struct qlcnic_adapter *adapter)
509 {
510         u32 val = QLCRDX(adapter->ahw, QLCNIC_INFORMANT);
511         adapter->ahw->pci_func = val & 0xf;
512 }
513
514 int qlcnic_83xx_cam_lock(struct qlcnic_adapter *adapter)
515 {
516         void __iomem *addr;
517         u32 val, limit = 0;
518
519         struct qlcnic_hardware_context *ahw = adapter->ahw;
520
521         addr = ahw->pci_base0 + QLC_83XX_SEM_LOCK_FUNC(ahw->pci_func);
522         do {
523                 val = readl(addr);
524                 if (val) {
525                         /* write the function number to register */
526                         QLC_SHARED_REG_WR32(adapter, QLCNIC_FLASH_LOCK_OWNER,
527                                             ahw->pci_func);
528                         return 0;
529                 }
530                 usleep_range(1000, 2000);
531         } while (++limit <= QLCNIC_PCIE_SEM_TIMEOUT);
532
533         return -EIO;
534 }
535
536 void qlcnic_83xx_cam_unlock(struct qlcnic_adapter *adapter)
537 {
538         void __iomem *addr;
539         u32 val;
540         struct qlcnic_hardware_context *ahw = adapter->ahw;
541
542         addr = ahw->pci_base0 + QLC_83XX_SEM_UNLOCK_FUNC(ahw->pci_func);
543         val = readl(addr);
544 }
545
546 void qlcnic_83xx_read_crb(struct qlcnic_adapter *adapter, char *buf,
547                           loff_t offset, size_t size)
548 {
549         int ret;
550         u32 data;
551
552         if (qlcnic_api_lock(adapter)) {
553                 dev_err(&adapter->pdev->dev,
554                         "%s: failed to acquire lock. addr offset 0x%x\n",
555                         __func__, (u32)offset);
556                 return;
557         }
558
559         ret = qlcnic_83xx_rd_reg_indirect(adapter, (u32) offset);
560         qlcnic_api_unlock(adapter);
561
562         if (ret == -EIO) {
563                 dev_err(&adapter->pdev->dev,
564                         "%s: failed. addr offset 0x%x\n",
565                         __func__, (u32)offset);
566                 return;
567         }
568         data = ret;
569         memcpy(buf, &data, size);
570 }
571
572 void qlcnic_83xx_write_crb(struct qlcnic_adapter *adapter, char *buf,
573                            loff_t offset, size_t size)
574 {
575         u32 data;
576
577         memcpy(&data, buf, size);
578         qlcnic_83xx_wrt_reg_indirect(adapter, (u32) offset, data);
579 }
580
581 int qlcnic_83xx_get_port_info(struct qlcnic_adapter *adapter)
582 {
583         int status;
584
585         status = qlcnic_83xx_get_port_config(adapter);
586         if (status) {
587                 dev_err(&adapter->pdev->dev,
588                         "Get Port Info failed\n");
589         } else {
590                 if (QLC_83XX_SFP_10G_CAPABLE(adapter->ahw->port_config))
591                         adapter->ahw->port_type = QLCNIC_XGBE;
592                 else
593                         adapter->ahw->port_type = QLCNIC_GBE;
594
595                 if (QLC_83XX_AUTONEG(adapter->ahw->port_config))
596                         adapter->ahw->link_autoneg = AUTONEG_ENABLE;
597         }
598         return status;
599 }
600
601 void qlcnic_83xx_enable_mbx_intrpt(struct qlcnic_adapter *adapter)
602 {
603         u32 val;
604
605         if (adapter->flags & QLCNIC_MSIX_ENABLED)
606                 val = BIT_2 | ((adapter->ahw->num_msix - 1) << 8);
607         else
608                 val = BIT_2;
609
610         QLCWRX(adapter->ahw, QLCNIC_MBX_INTR_ENBL, val);
611 }
612
613 void qlcnic_83xx_check_vf(struct qlcnic_adapter *adapter,
614                           const struct pci_device_id *ent)
615 {
616         u32 op_mode, priv_level;
617         struct qlcnic_hardware_context *ahw = adapter->ahw;
618
619         ahw->fw_hal_version = 2;
620         qlcnic_get_func_no(adapter);
621
622         /* Determine function privilege level */
623         op_mode = QLCRDX(adapter->ahw, QLC_83XX_DRV_OP_MODE);
624         if (op_mode == QLC_83XX_DEFAULT_OPMODE)
625                 priv_level = QLCNIC_MGMT_FUNC;
626         else
627                 priv_level = QLC_83XX_GET_FUNC_PRIVILEGE(op_mode,
628                                                          ahw->pci_func);
629
630         if (priv_level == QLCNIC_NON_PRIV_FUNC) {
631                 ahw->op_mode = QLCNIC_NON_PRIV_FUNC;
632                 dev_info(&adapter->pdev->dev,
633                          "HAL Version: %d Non Privileged function\n",
634                          ahw->fw_hal_version);
635                 adapter->nic_ops = &qlcnic_vf_ops;
636         } else {
637                 adapter->nic_ops = &qlcnic_83xx_ops;
638         }
639 }
640
641 static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter,
642                                         u32 data[]);
643 static void qlcnic_83xx_handle_idc_comp_aen(struct qlcnic_adapter *adapter,
644                                             u32 data[]);
645
646 static void qlcnic_dump_mbx(struct qlcnic_adapter *adapter,
647                             struct qlcnic_cmd_args *cmd)
648 {
649         int i;
650
651         dev_info(&adapter->pdev->dev,
652                  "Host MBX regs(%d)\n", cmd->req.num);
653         for (i = 0; i < cmd->req.num; i++) {
654                 if (i && !(i % 8))
655                         pr_info("\n");
656                 pr_info("%08x ", cmd->req.arg[i]);
657         }
658         pr_info("\n");
659         dev_info(&adapter->pdev->dev,
660                  "FW MBX regs(%d)\n", cmd->rsp.num);
661         for (i = 0; i < cmd->rsp.num; i++) {
662                 if (i && !(i % 8))
663                         pr_info("\n");
664                 pr_info("%08x ", cmd->rsp.arg[i]);
665         }
666         pr_info("\n");
667 }
668
669 static u32 qlcnic_83xx_mbx_poll(struct qlcnic_adapter *adapter)
670 {
671         u32 data;
672         unsigned long wait_time = 0;
673         struct qlcnic_hardware_context *ahw = adapter->ahw;
674         /* wait for mailbox completion */
675         do {
676                 data = QLCRDX(ahw, QLCNIC_FW_MBX_CTRL);
677                 if (++wait_time > QLCNIC_MBX_TIMEOUT) {
678                         data = QLCNIC_RCODE_TIMEOUT;
679                         break;
680                 }
681                 mdelay(1);
682         } while (!data);
683         return data;
684 }
685
686 int qlcnic_83xx_mbx_op(struct qlcnic_adapter *adapter,
687                        struct qlcnic_cmd_args *cmd)
688 {
689         int i;
690         u16 opcode;
691         u8 mbx_err_code, mac_cmd_rcode;
692         u32 rsp, mbx_val, fw_data, rsp_num, mbx_cmd, temp, fw[8];
693         struct qlcnic_hardware_context *ahw = adapter->ahw;
694
695         opcode = LSW(cmd->req.arg[0]);
696         if (!test_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status)) {
697                 dev_info(&adapter->pdev->dev,
698                          "Mailbox cmd attempted, 0x%x\n", opcode);
699                 dev_info(&adapter->pdev->dev, "Mailbox detached\n");
700                 return 0;
701         }
702
703         spin_lock(&ahw->mbx_lock);
704         mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
705
706         if (mbx_val) {
707                 QLCDB(adapter, DRV,
708                       "Mailbox cmd attempted, 0x%x\n", opcode);
709                 QLCDB(adapter, DRV,
710                       "Mailbox not available, 0x%x, collect FW dump\n",
711                       mbx_val);
712                 cmd->rsp.arg[0] = QLCNIC_RCODE_TIMEOUT;
713                 spin_unlock(&ahw->mbx_lock);
714                 return cmd->rsp.arg[0];
715         }
716
717         /* Fill in mailbox registers */
718         mbx_cmd = cmd->req.arg[0];
719         writel(mbx_cmd, QLCNIC_MBX_HOST(ahw, 0));
720         for (i = 1; i < cmd->req.num; i++)
721                 writel(cmd->req.arg[i], QLCNIC_MBX_HOST(ahw, i));
722
723         /* Signal FW about the impending command */
724         QLCWRX(ahw, QLCNIC_HOST_MBX_CTRL, QLCNIC_SET_OWNER);
725 poll:
726         rsp = qlcnic_83xx_mbx_poll(adapter);
727         /* Get the FW response data */
728         fw_data = readl(QLCNIC_MBX_FW(ahw, 0));
729         mbx_err_code = QLCNIC_MBX_STATUS(fw_data);
730         rsp_num = QLCNIC_MBX_NUM_REGS(fw_data);
731         opcode = QLCNIC_MBX_RSP(fw_data);
732
733         if (rsp != QLCNIC_RCODE_TIMEOUT) {
734                 if (opcode == QLCNIC_MBX_LINK_EVENT) {
735                         for (i = 0; i < rsp_num; i++) {
736                                 temp = readl(QLCNIC_MBX_FW(ahw, i));
737                                 fw[i] = temp;
738                         }
739                         qlcnic_83xx_handle_link_aen(adapter, fw);
740                         /* clear fw mbx control register */
741                         QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
742                         mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
743                         if (mbx_val)
744                                 goto poll;
745                 } else if (opcode == QLCNIC_MBX_COMP_EVENT) {
746                         for (i = 0; i < rsp_num; i++) {
747                                 temp = readl(QLCNIC_MBX_FW(ahw, i));
748                                 fw[i] = temp;
749                         }
750                         qlcnic_83xx_handle_idc_comp_aen(adapter, fw);
751                         /* clear fw mbx control register */
752                         QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
753                         mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
754                         if (mbx_val)
755                                 goto poll;
756                 } else if (opcode == QLCNIC_MBX_REQUEST_EVENT) {
757                         /* IDC Request Notification */
758                         for (i = 0; i < rsp_num; i++) {
759                                 temp = readl(QLCNIC_MBX_FW(ahw, i));
760                                 fw[i] = temp;
761                         }
762                         for (i = 0; i < QLC_83XX_MBX_AEN_CNT; i++) {
763                                 temp = QLCNIC_MBX_RSP(fw[i]);
764                                 adapter->ahw->mbox_aen[i] = temp;
765                         }
766                         queue_delayed_work(adapter->qlcnic_wq,
767                                            &adapter->idc_aen_work, 0);
768                         /* clear fw mbx control register */
769                         QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
770                         mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
771                         if (mbx_val)
772                                 goto poll;
773                 } else if ((mbx_err_code == QLCNIC_MBX_RSP_OK) ||
774                            (mbx_err_code == QLCNIC_MBX_PORT_RSP_OK)) {
775                         qlcnic_83xx_get_mbx_data(adapter, cmd);
776                         rsp = QLCNIC_RCODE_SUCCESS;
777                 } else {
778                         qlcnic_83xx_get_mbx_data(adapter, cmd);
779                         if (opcode == QLCNIC_CMD_CONFIG_MAC_VLAN) {
780                                 fw_data = readl(QLCNIC_MBX_FW(ahw, 2));
781                                 mac_cmd_rcode = (u8)fw_data;
782                                 if (mac_cmd_rcode == QLC_83XX_NO_NIC_RESOURCE ||
783                                     mac_cmd_rcode == QLC_83XX_MAC_PRESENT ||
784                                     mac_cmd_rcode == QLC_83XX_MAC_ABSENT) {
785                                         rsp = QLCNIC_RCODE_SUCCESS;
786                                         goto out;
787                                 }
788                         }
789                         dev_info(&adapter->pdev->dev,
790                                  "MBX command 0x%x failed with err:0x%x\n",
791                                  opcode, mbx_err_code);
792                         rsp = mbx_err_code;
793                         qlcnic_dump_mbx(adapter, cmd);
794                 }
795         } else {
796                 dev_info(&adapter->pdev->dev,
797                          "MBX command 0x%x timed out\n", opcode);
798                 qlcnic_dump_mbx(adapter, cmd);
799         }
800 out:
801         /* clear fw mbx control register */
802         QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
803         spin_unlock(&ahw->mbx_lock);
804         return rsp;
805 }
806
807 int qlcnic_83xx_alloc_mbx_args(struct qlcnic_cmd_args *mbx,
808                                struct qlcnic_adapter *adapter, u32 type)
809 {
810         int i, size;
811         u32 temp;
812         const struct qlcnic_mailbox_metadata *mbx_tbl;
813
814         mbx_tbl = qlcnic_83xx_mbx_tbl;
815         size = ARRAY_SIZE(qlcnic_83xx_mbx_tbl);
816         for (i = 0; i < size; i++) {
817                 if (type == mbx_tbl[i].cmd) {
818                         mbx->req.num = mbx_tbl[i].in_args;
819                         mbx->rsp.num = mbx_tbl[i].out_args;
820                         mbx->req.arg = kcalloc(mbx->req.num, sizeof(u32),
821                                                GFP_ATOMIC);
822                         if (!mbx->req.arg)
823                                 return -ENOMEM;
824                         mbx->rsp.arg = kcalloc(mbx->rsp.num, sizeof(u32),
825                                                GFP_ATOMIC);
826                         if (!mbx->rsp.arg) {
827                                 kfree(mbx->req.arg);
828                                 mbx->req.arg = NULL;
829                                 return -ENOMEM;
830                         }
831                         memset(mbx->req.arg, 0, sizeof(u32) * mbx->req.num);
832                         memset(mbx->rsp.arg, 0, sizeof(u32) * mbx->rsp.num);
833                         temp = adapter->ahw->fw_hal_version << 29;
834                         mbx->req.arg[0] = (type | (mbx->req.num << 16) | temp);
835                         break;
836                 }
837         }
838         return 0;
839 }
840
841 void qlcnic_83xx_idc_aen_work(struct work_struct *work)
842 {
843         struct qlcnic_adapter *adapter;
844         struct qlcnic_cmd_args cmd;
845         int i, err = 0;
846
847         adapter = container_of(work, struct qlcnic_adapter, idc_aen_work.work);
848         qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_IDC_ACK);
849
850         for (i = 1; i < QLC_83XX_MBX_AEN_CNT; i++)
851                 cmd.req.arg[i] = adapter->ahw->mbox_aen[i];
852
853         err = qlcnic_issue_cmd(adapter, &cmd);
854         if (err)
855                 dev_info(&adapter->pdev->dev,
856                          "%s: Mailbox IDC ACK failed.\n", __func__);
857         qlcnic_free_mbx_args(&cmd);
858 }
859
860 static void qlcnic_83xx_handle_idc_comp_aen(struct qlcnic_adapter *adapter,
861                                             u32 data[])
862 {
863         dev_dbg(&adapter->pdev->dev, "Completion AEN:0x%x.\n",
864                 QLCNIC_MBX_RSP(data[0]));
865         clear_bit(QLC_83XX_IDC_COMP_AEN, &adapter->ahw->idc.status);
866         return;
867 }
868
869 void qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
870 {
871         u32 mask, resp, event[QLC_83XX_MBX_AEN_CNT];
872         int i;
873         struct qlcnic_hardware_context *ahw = adapter->ahw;
874
875         if (!spin_trylock(&ahw->mbx_lock)) {
876                 mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
877                 writel(0, adapter->ahw->pci_base0 + mask);
878                 return;
879         }
880         resp = QLCRDX(ahw, QLCNIC_FW_MBX_CTRL);
881
882         if (!(resp & QLCNIC_SET_OWNER))
883                 goto out;
884
885         for (i = 0; i < QLC_83XX_MBX_AEN_CNT; i++)
886                 event[i] = readl(QLCNIC_MBX_FW(ahw, i));
887
888         switch (QLCNIC_MBX_RSP(event[0])) {
889
890         case QLCNIC_MBX_LINK_EVENT:
891                 qlcnic_83xx_handle_link_aen(adapter, event);
892                 break;
893         case QLCNIC_MBX_COMP_EVENT:
894                 qlcnic_83xx_handle_idc_comp_aen(adapter, event);
895                 break;
896         case QLCNIC_MBX_REQUEST_EVENT:
897                 for (i = 0; i < QLC_83XX_MBX_AEN_CNT; i++)
898                         adapter->ahw->mbox_aen[i] = QLCNIC_MBX_RSP(event[i]);
899                 queue_delayed_work(adapter->qlcnic_wq,
900                                    &adapter->idc_aen_work, 0);
901                 break;
902         case QLCNIC_MBX_TIME_EXTEND_EVENT:
903                 break;
904         case QLCNIC_MBX_SFP_INSERT_EVENT:
905                 dev_info(&adapter->pdev->dev, "SFP+ Insert AEN:0x%x.\n",
906                          QLCNIC_MBX_RSP(event[0]));
907                 break;
908         case QLCNIC_MBX_SFP_REMOVE_EVENT:
909                 dev_info(&adapter->pdev->dev, "SFP Removed AEN:0x%x.\n",
910                          QLCNIC_MBX_RSP(event[0]));
911                 break;
912         default:
913                 dev_dbg(&adapter->pdev->dev, "Unsupported AEN:0x%x.\n",
914                         QLCNIC_MBX_RSP(event[0]));
915                 break;
916         }
917
918         QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
919 out:
920         mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
921         writel(0, adapter->ahw->pci_base0 + mask);
922         spin_unlock(&ahw->mbx_lock);
923 }
924
925 static int qlcnic_83xx_add_rings(struct qlcnic_adapter *adapter)
926 {
927         int index, i, err, sds_mbx_size;
928         u32 *buf, intrpt_id, intr_mask;
929         u16 context_id;
930         u8 num_sds;
931         struct qlcnic_cmd_args cmd;
932         struct qlcnic_host_sds_ring *sds;
933         struct qlcnic_sds_mbx sds_mbx;
934         struct qlcnic_add_rings_mbx_out *mbx_out;
935         struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
936         struct qlcnic_hardware_context *ahw = adapter->ahw;
937
938         sds_mbx_size = sizeof(struct qlcnic_sds_mbx);
939         context_id = recv_ctx->context_id;
940         num_sds = (adapter->max_sds_rings - QLCNIC_MAX_RING_SETS);
941         ahw->hw_ops->alloc_mbx_args(&cmd, adapter,
942                                     QLCNIC_CMD_ADD_RCV_RINGS);
943         cmd.req.arg[1] = 0 | (num_sds << 8) | (context_id << 16);
944
945         /* set up status rings, mbx 2-81 */
946         index = 2;
947         for (i = 8; i < adapter->max_sds_rings; i++) {
948                 memset(&sds_mbx, 0, sds_mbx_size);
949                 sds = &recv_ctx->sds_rings[i];
950                 sds->consumer = 0;
951                 memset(sds->desc_head, 0, STATUS_DESC_RINGSIZE(sds));
952                 sds_mbx.phy_addr = sds->phys_addr;
953                 sds_mbx.sds_ring_size = sds->num_desc;
954
955                 if (adapter->flags & QLCNIC_MSIX_ENABLED)
956                         intrpt_id = ahw->intr_tbl[i].id;
957                 else
958                         intrpt_id = QLCRDX(ahw, QLCNIC_DEF_INT_ID);
959
960                 if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST)
961                         sds_mbx.intrpt_id = intrpt_id;
962                 else
963                         sds_mbx.intrpt_id = 0xffff;
964                 sds_mbx.intrpt_val = 0;
965                 buf = &cmd.req.arg[index];
966                 memcpy(buf, &sds_mbx, sds_mbx_size);
967                 index += sds_mbx_size / sizeof(u32);
968         }
969
970         /* send the mailbox command */
971         err = ahw->hw_ops->mbx_cmd(adapter, &cmd);
972         if (err) {
973                 dev_err(&adapter->pdev->dev,
974                         "Failed to add rings %d\n", err);
975                 goto out;
976         }
977
978         mbx_out = (struct qlcnic_add_rings_mbx_out *)&cmd.rsp.arg[1];
979         index = 0;
980         /* status descriptor ring */
981         for (i = 8; i < adapter->max_sds_rings; i++) {
982                 sds = &recv_ctx->sds_rings[i];
983                 sds->crb_sts_consumer = ahw->pci_base0 +
984                                         mbx_out->host_csmr[index];
985                 if (adapter->flags & QLCNIC_MSIX_ENABLED)
986                         intr_mask = ahw->intr_tbl[i].src;
987                 else
988                         intr_mask = QLCRDX(ahw, QLCNIC_DEF_INT_MASK);
989
990                 sds->crb_intr_mask = ahw->pci_base0 + intr_mask;
991                 index++;
992         }
993 out:
994         qlcnic_free_mbx_args(&cmd);
995         return err;
996 }
997
998 int qlcnic_83xx_create_rx_ctx(struct qlcnic_adapter *adapter)
999 {
1000         int i, err, index, sds_mbx_size, rds_mbx_size;
1001         u8 num_sds, num_rds;
1002         u32 *buf, intrpt_id, intr_mask, cap = 0;
1003         struct qlcnic_host_sds_ring *sds;
1004         struct qlcnic_host_rds_ring *rds;
1005         struct qlcnic_sds_mbx sds_mbx;
1006         struct qlcnic_rds_mbx rds_mbx;
1007         struct qlcnic_cmd_args cmd;
1008         struct qlcnic_rcv_mbx_out *mbx_out;
1009         struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
1010         struct qlcnic_hardware_context *ahw = adapter->ahw;
1011         num_rds = adapter->max_rds_rings;
1012
1013         if (adapter->max_sds_rings <= QLCNIC_MAX_RING_SETS)
1014                 num_sds = adapter->max_sds_rings;
1015         else
1016                 num_sds = QLCNIC_MAX_RING_SETS;
1017
1018         sds_mbx_size = sizeof(struct qlcnic_sds_mbx);
1019         rds_mbx_size = sizeof(struct qlcnic_rds_mbx);
1020         cap = QLCNIC_CAP0_LEGACY_CONTEXT;
1021
1022         if (adapter->flags & QLCNIC_FW_LRO_MSS_CAP)
1023                 cap |= QLC_83XX_FW_CAP_LRO_MSS;
1024
1025         /* set mailbox hdr and capabilities */
1026         qlcnic_alloc_mbx_args(&cmd, adapter,
1027                               QLCNIC_CMD_CREATE_RX_CTX);
1028         cmd.req.arg[1] = cap;
1029         cmd.req.arg[5] = 1 | (num_rds << 5) | (num_sds << 8) |
1030                          (QLC_83XX_HOST_RDS_MODE_UNIQUE << 16);
1031         /* set up status rings, mbx 8-57/87 */
1032         index = QLC_83XX_HOST_SDS_MBX_IDX;
1033         for (i = 0; i < num_sds; i++) {
1034                 memset(&sds_mbx, 0, sds_mbx_size);
1035                 sds = &recv_ctx->sds_rings[i];
1036                 sds->consumer = 0;
1037                 memset(sds->desc_head, 0, STATUS_DESC_RINGSIZE(sds));
1038                 sds_mbx.phy_addr = sds->phys_addr;
1039                 sds_mbx.sds_ring_size = sds->num_desc;
1040                 if (adapter->flags & QLCNIC_MSIX_ENABLED)
1041                         intrpt_id = ahw->intr_tbl[i].id;
1042                 else
1043                         intrpt_id = QLCRDX(ahw, QLCNIC_DEF_INT_ID);
1044                 if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST)
1045                         sds_mbx.intrpt_id = intrpt_id;
1046                 else
1047                         sds_mbx.intrpt_id = 0xffff;
1048                 sds_mbx.intrpt_val = 0;
1049                 buf = &cmd.req.arg[index];
1050                 memcpy(buf, &sds_mbx, sds_mbx_size);
1051                 index += sds_mbx_size / sizeof(u32);
1052         }
1053         /* set up receive rings, mbx 88-111/135 */
1054         index = QLCNIC_HOST_RDS_MBX_IDX;
1055         rds = &recv_ctx->rds_rings[0];
1056         rds->producer = 0;
1057         memset(&rds_mbx, 0, rds_mbx_size);
1058         rds_mbx.phy_addr_reg = rds->phys_addr;
1059         rds_mbx.reg_ring_sz = rds->dma_size;
1060         rds_mbx.reg_ring_len = rds->num_desc;
1061         /* Jumbo ring */
1062         rds = &recv_ctx->rds_rings[1];
1063         rds->producer = 0;
1064         rds_mbx.phy_addr_jmb = rds->phys_addr;
1065         rds_mbx.jmb_ring_sz = rds->dma_size;
1066         rds_mbx.jmb_ring_len = rds->num_desc;
1067         buf = &cmd.req.arg[index];
1068         memcpy(buf, &rds_mbx, rds_mbx_size);
1069
1070         /* send the mailbox command */
1071         err = ahw->hw_ops->mbx_cmd(adapter, &cmd);
1072         if (err) {
1073                 dev_err(&adapter->pdev->dev,
1074                         "Failed to create Rx ctx in firmware%d\n", err);
1075                 goto out;
1076         }
1077         mbx_out = (struct qlcnic_rcv_mbx_out *)&cmd.rsp.arg[1];
1078         recv_ctx->context_id = mbx_out->ctx_id;
1079         recv_ctx->state = mbx_out->state;
1080         recv_ctx->virt_port = mbx_out->vport_id;
1081         dev_info(&adapter->pdev->dev, "Rx Context[%d] Created, state:0x%x\n",
1082                  recv_ctx->context_id, recv_ctx->state);
1083         /* Receive descriptor ring */
1084         /* Standard ring */
1085         rds = &recv_ctx->rds_rings[0];
1086         rds->crb_rcv_producer = ahw->pci_base0 +
1087                                 mbx_out->host_prod[0].reg_buf;
1088         /* Jumbo ring */
1089         rds = &recv_ctx->rds_rings[1];
1090         rds->crb_rcv_producer = ahw->pci_base0 +
1091                                 mbx_out->host_prod[0].jmb_buf;
1092         /* status descriptor ring */
1093         for (i = 0; i < num_sds; i++) {
1094                 sds = &recv_ctx->sds_rings[i];
1095                 sds->crb_sts_consumer = ahw->pci_base0 +
1096                                         mbx_out->host_csmr[i];
1097                 if (adapter->flags & QLCNIC_MSIX_ENABLED)
1098                         intr_mask = ahw->intr_tbl[i].src;
1099                 else
1100                         intr_mask = QLCRDX(ahw, QLCNIC_DEF_INT_MASK);
1101                 sds->crb_intr_mask = ahw->pci_base0 + intr_mask;
1102         }
1103
1104         if (adapter->max_sds_rings > QLCNIC_MAX_RING_SETS)
1105                 err = qlcnic_83xx_add_rings(adapter);
1106 out:
1107         qlcnic_free_mbx_args(&cmd);
1108         return err;
1109 }
1110
1111 int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *adapter,
1112                               struct qlcnic_host_tx_ring *tx, int ring)
1113 {
1114         int err;
1115         u16 msix_id;
1116         u32 *buf, intr_mask;
1117         struct qlcnic_cmd_args cmd;
1118         struct qlcnic_tx_mbx mbx;
1119         struct qlcnic_tx_mbx_out *mbx_out;
1120         struct qlcnic_hardware_context *ahw = adapter->ahw;
1121
1122         /* Reset host resources */
1123         tx->producer = 0;
1124         tx->sw_consumer = 0;
1125         *(tx->hw_consumer) = 0;
1126
1127         memset(&mbx, 0, sizeof(struct qlcnic_tx_mbx));
1128
1129         /* setup mailbox inbox registerss */
1130         mbx.phys_addr = tx->phys_addr;
1131         mbx.cnsmr_index = tx->hw_cons_phys_addr;
1132         mbx.size = tx->num_desc;
1133         if (adapter->flags & QLCNIC_MSIX_ENABLED)
1134                 msix_id = ahw->intr_tbl[adapter->max_sds_rings + ring].id;
1135         else
1136                 msix_id = QLCRDX(ahw, QLCNIC_DEF_INT_ID);
1137         if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST)
1138                 mbx.intr_id = msix_id;
1139         else
1140                 mbx.intr_id = 0xffff;
1141         mbx.src = 0;
1142
1143         qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CREATE_TX_CTX);
1144         cmd.req.arg[1] = QLCNIC_CAP0_LEGACY_CONTEXT;
1145         cmd.req.arg[5] = QLCNIC_MAX_TX_QUEUES;
1146         buf = &cmd.req.arg[6];
1147         memcpy(buf, &mbx, sizeof(struct qlcnic_tx_mbx));
1148         /* send the mailbox command*/
1149         err = qlcnic_issue_cmd(adapter, &cmd);
1150         if (err) {
1151                 dev_err(&adapter->pdev->dev,
1152                         "Failed to create Tx ctx in firmware 0x%x\n", err);
1153                 goto out;
1154         }
1155         mbx_out = (struct qlcnic_tx_mbx_out *)&cmd.rsp.arg[2];
1156         tx->crb_cmd_producer = ahw->pci_base0 + mbx_out->host_prod;
1157         tx->ctx_id = mbx_out->ctx_id;
1158         if (adapter->flags & QLCNIC_MSIX_ENABLED) {
1159                 intr_mask = ahw->intr_tbl[adapter->max_sds_rings + ring].src;
1160                 tx->crb_intr_mask = ahw->pci_base0 + intr_mask;
1161         }
1162         dev_info(&adapter->pdev->dev, "Tx Context[0x%x] Created, state:0x%x\n",
1163                  tx->ctx_id, mbx_out->state);
1164 out:
1165         qlcnic_free_mbx_args(&cmd);
1166         return err;
1167 }
1168
1169 int qlcnic_83xx_config_led(struct qlcnic_adapter *adapter, u32 state,
1170                            u32 beacon)
1171 {
1172         struct qlcnic_cmd_args cmd;
1173         u32 mbx_in;
1174         int i, status = 0;
1175
1176         if (state) {
1177                 /* Get LED configuration */
1178                 qlcnic_alloc_mbx_args(&cmd, adapter,
1179                                       QLCNIC_CMD_GET_LED_CONFIG);
1180                 status = qlcnic_issue_cmd(adapter, &cmd);
1181                 if (status) {
1182                         dev_err(&adapter->pdev->dev,
1183                                 "Get led config failed.\n");
1184                         goto mbx_err;
1185                 } else {
1186                         for (i = 0; i < 4; i++)
1187                                 adapter->ahw->mbox_reg[i] = cmd.rsp.arg[i+1];
1188                 }
1189                 qlcnic_free_mbx_args(&cmd);
1190                 /* Set LED Configuration */
1191                 mbx_in = (LSW(QLC_83XX_LED_CONFIG) << 16) |
1192                           LSW(QLC_83XX_LED_CONFIG);
1193                 qlcnic_alloc_mbx_args(&cmd, adapter,
1194                                       QLCNIC_CMD_SET_LED_CONFIG);
1195                 cmd.req.arg[1] = mbx_in;
1196                 cmd.req.arg[2] = mbx_in;
1197                 cmd.req.arg[3] = mbx_in;
1198                 if (beacon)
1199                         cmd.req.arg[4] = QLC_83XX_ENABLE_BEACON;
1200                 status = qlcnic_issue_cmd(adapter, &cmd);
1201                 if (status) {
1202                         dev_err(&adapter->pdev->dev,
1203                                 "Set led config failed.\n");
1204                 }
1205 mbx_err:
1206                 qlcnic_free_mbx_args(&cmd);
1207                 return status;
1208
1209         } else {
1210                 /* Restoring default LED configuration */
1211                 qlcnic_alloc_mbx_args(&cmd, adapter,
1212                                       QLCNIC_CMD_SET_LED_CONFIG);
1213                 cmd.req.arg[1] = adapter->ahw->mbox_reg[0];
1214                 cmd.req.arg[2] = adapter->ahw->mbox_reg[1];
1215                 cmd.req.arg[3] = adapter->ahw->mbox_reg[2];
1216                 if (beacon)
1217                         cmd.req.arg[4] = adapter->ahw->mbox_reg[3];
1218                 status = qlcnic_issue_cmd(adapter, &cmd);
1219                 if (status)
1220                         dev_err(&adapter->pdev->dev,
1221                                 "Restoring led config failed.\n");
1222                 qlcnic_free_mbx_args(&cmd);
1223                 return status;
1224         }
1225 }
1226
1227 void qlcnic_83xx_register_nic_idc_func(struct qlcnic_adapter *adapter,
1228                                        int enable)
1229 {
1230         struct qlcnic_cmd_args cmd;
1231         int status;
1232
1233         if (enable) {
1234                 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_INIT_NIC_FUNC);
1235                 cmd.req.arg[1] = 1 | BIT_0;
1236         } else {
1237                 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_STOP_NIC_FUNC);
1238                 cmd.req.arg[1] = 0 | BIT_0;
1239         }
1240         status = qlcnic_issue_cmd(adapter, &cmd);
1241         if (status)
1242                 dev_err(&adapter->pdev->dev,
1243                         "Failed to %s in NIC IDC function event.\n",
1244                         (enable ? "register" : "unregister"));
1245
1246         qlcnic_free_mbx_args(&cmd);
1247 }
1248
1249 int qlcnic_83xx_set_port_config(struct qlcnic_adapter *adapter)
1250 {
1251         struct qlcnic_cmd_args cmd;
1252         int err;
1253
1254         qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_PORT_CONFIG);
1255         cmd.req.arg[1] = adapter->ahw->port_config;
1256         err = qlcnic_issue_cmd(adapter, &cmd);
1257         if (err)
1258                 dev_info(&adapter->pdev->dev, "Set Port Config failed.\n");
1259         qlcnic_free_mbx_args(&cmd);
1260         return err;
1261 }
1262
1263 int qlcnic_83xx_get_port_config(struct qlcnic_adapter *adapter)
1264 {
1265         struct qlcnic_cmd_args cmd;
1266         int err;
1267
1268         qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_PORT_CONFIG);
1269         err = qlcnic_issue_cmd(adapter, &cmd);
1270         if (err)
1271                 dev_info(&adapter->pdev->dev, "Get Port config failed\n");
1272         else
1273                 adapter->ahw->port_config = cmd.rsp.arg[1];
1274         qlcnic_free_mbx_args(&cmd);
1275         return err;
1276 }
1277
1278 int qlcnic_83xx_setup_link_event(struct qlcnic_adapter *adapter, int enable)
1279 {
1280         int err;
1281         u32 temp;
1282         struct qlcnic_cmd_args cmd;
1283
1284         qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_LINK_EVENT);
1285         temp = adapter->recv_ctx->context_id << 16;
1286         cmd.req.arg[1] = (enable ? 1 : 0) | BIT_8 | temp;
1287         err = qlcnic_issue_cmd(adapter, &cmd);
1288         if (err)
1289                 dev_info(&adapter->pdev->dev,
1290                          "Setup linkevent mailbox failed\n");
1291         qlcnic_free_mbx_args(&cmd);
1292         return err;
1293 }
1294
1295 int qlcnic_83xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode)
1296 {
1297         int err;
1298         u32 temp;
1299         struct qlcnic_cmd_args cmd;
1300
1301         if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
1302                 return -EIO;
1303
1304         qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIGURE_MAC_RX_MODE);
1305         temp = adapter->recv_ctx->context_id << 16;
1306         cmd.req.arg[1] = (mode ? 1 : 0) | temp;
1307         err = qlcnic_issue_cmd(adapter, &cmd);
1308         if (err)
1309                 dev_info(&adapter->pdev->dev,
1310                          "Promiscous mode config failed\n");
1311         qlcnic_free_mbx_args(&cmd);
1312
1313         return err;
1314 }
1315
1316 int qlcnic_83xx_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
1317 {
1318         struct qlcnic_hardware_context *ahw = adapter->ahw;
1319         int status = 0, loop = 0;
1320         u32 config;
1321
1322         status = qlcnic_83xx_get_port_config(adapter);
1323         if (status)
1324                 return status;
1325
1326         config = ahw->port_config;
1327         set_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1328
1329         if (mode == QLCNIC_ILB_MODE)
1330                 ahw->port_config |= QLC_83XX_CFG_LOOPBACK_HSS;
1331         if (mode == QLCNIC_ELB_MODE)
1332                 ahw->port_config |= QLC_83XX_CFG_LOOPBACK_EXT;
1333
1334         status = qlcnic_83xx_set_port_config(adapter);
1335         if (status) {
1336                 dev_err(&adapter->pdev->dev,
1337                         "Failed to Set Loopback Mode = 0x%x.\n",
1338                         ahw->port_config);
1339                 ahw->port_config = config;
1340                 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1341                 return status;
1342         }
1343
1344         /* Wait until firmware send IDC Completion AEN */
1345         do {
1346                 msleep(300);
1347                 if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) {
1348                         dev_err(&adapter->pdev->dev,
1349                                 "FW did not generate IDC completion AEN\n");
1350                         clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1351                         return -EIO;
1352                 }
1353         } while (test_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status));
1354
1355         qlcnic_sre_macaddr_change(adapter, adapter->mac_addr, 0,
1356                                   QLCNIC_MAC_ADD);
1357         return status;
1358 }
1359
1360 int qlcnic_83xx_clear_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
1361 {
1362         struct qlcnic_hardware_context *ahw = adapter->ahw;
1363         int status = 0, loop = 0;
1364         u32 config = ahw->port_config;
1365
1366         set_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1367         if (mode == QLCNIC_ILB_MODE)
1368                 ahw->port_config &= ~QLC_83XX_CFG_LOOPBACK_HSS;
1369         if (mode == QLCNIC_ELB_MODE)
1370                 ahw->port_config &= ~QLC_83XX_CFG_LOOPBACK_EXT;
1371
1372         status = qlcnic_83xx_set_port_config(adapter);
1373         if (status) {
1374                 dev_err(&adapter->pdev->dev,
1375                         "Failed to Clear Loopback Mode = 0x%x.\n",
1376                         ahw->port_config);
1377                 ahw->port_config = config;
1378                 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1379                 return status;
1380         }
1381
1382         /* Wait until firmware send IDC Completion AEN */
1383         do {
1384                 msleep(300);
1385                 if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) {
1386                         dev_err(&adapter->pdev->dev,
1387                                 "Firmware didn't sent IDC completion AEN\n");
1388                         clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1389                         return -EIO;
1390                 }
1391         } while (test_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status));
1392
1393         qlcnic_sre_macaddr_change(adapter, adapter->mac_addr, 0,
1394                                   QLCNIC_MAC_DEL);
1395         return status;
1396 }
1397
1398 void qlcnic_83xx_config_ipaddr(struct qlcnic_adapter *adapter, __be32 ip,
1399                                int mode)
1400 {
1401         int err;
1402         u32 temp;
1403         struct qlcnic_cmd_args cmd;
1404
1405         qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIGURE_IP_ADDR);
1406         if (mode == QLCNIC_IP_UP) {
1407                 temp = adapter->recv_ctx->context_id << 16;
1408                 cmd.req.arg[1] = 1 | temp;
1409         } else {
1410                 temp = adapter->recv_ctx->context_id << 16;
1411                 cmd.req.arg[1] = 2 | temp;
1412         }
1413         cmd.req.arg[2] = ntohl(ip);
1414
1415         err = qlcnic_issue_cmd(adapter, &cmd);
1416         if (err != QLCNIC_RCODE_SUCCESS)
1417                 dev_err(&adapter->netdev->dev,
1418                         "could not notify %s IP 0x%x request\n",
1419                         (mode == QLCNIC_IP_UP) ? "Add" : "Remove", ip);
1420         qlcnic_free_mbx_args(&cmd);
1421 }
1422
1423 int qlcnic_83xx_config_hw_lro(struct qlcnic_adapter *adapter, int mode)
1424 {
1425         int err;
1426         u32 temp, arg1;
1427         struct qlcnic_cmd_args cmd;
1428
1429         if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
1430                 return 0;
1431
1432         qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIGURE_HW_LRO);
1433         temp = adapter->recv_ctx->context_id << 16;
1434         arg1 = (mode ? (BIT_0 | BIT_1 | BIT_3) : 0) | temp;
1435         cmd.req.arg[1] = arg1;
1436
1437         err = qlcnic_issue_cmd(adapter, &cmd);
1438         if (err)
1439                 dev_info(&adapter->pdev->dev, "LRO config failed\n");
1440         qlcnic_free_mbx_args(&cmd);
1441
1442         return err;
1443 }
1444
1445 int qlcnic_83xx_config_rss(struct qlcnic_adapter *adapter, int enable)
1446 {
1447         int err;
1448         u32 word;
1449         struct qlcnic_cmd_args cmd;
1450         const u64 key[] = { 0xbeac01fa6a42b73bULL, 0x8030f20c77cb2da3ULL,
1451                             0xae7b30b4d0ca2bcbULL, 0x43a38fb04167253dULL,
1452                             0x255b0ec26d5a56daULL };
1453
1454         qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIGURE_RSS);
1455
1456         /*
1457          * RSS request:
1458          * bits 3-0: Rsvd
1459          *      5-4: hash_type_ipv4
1460          *      7-6: hash_type_ipv6
1461          *        8: enable
1462          *        9: use indirection table
1463          *    16-31: indirection table mask
1464          */
1465         word =  ((u32)(RSS_HASHTYPE_IP_TCP & 0x3) << 4) |
1466                 ((u32)(RSS_HASHTYPE_IP_TCP & 0x3) << 6) |
1467                 ((u32)(enable & 0x1) << 8) |
1468                 ((0x7ULL) << 16);
1469         cmd.req.arg[1] = (adapter->recv_ctx->context_id);
1470         cmd.req.arg[2] = word;
1471         memcpy(&cmd.req.arg[4], key, sizeof(key));
1472
1473         err = qlcnic_issue_cmd(adapter, &cmd);
1474
1475         if (err)
1476                 dev_info(&adapter->pdev->dev, "RSS config failed\n");
1477         qlcnic_free_mbx_args(&cmd);
1478
1479         return err;
1480
1481 }
1482
1483 int qlcnic_83xx_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr,
1484                                    __le16 vlan_id, u8 op)
1485 {
1486         int err;
1487         u32 *buf;
1488         struct qlcnic_cmd_args cmd;
1489         struct qlcnic_macvlan_mbx mv;
1490
1491         if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
1492                 return -EIO;
1493
1494         err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_MAC_VLAN);
1495         if (err)
1496                 return err;
1497         cmd.req.arg[1] = op | (1 << 8) |
1498                         (adapter->recv_ctx->context_id << 16);
1499
1500         mv.vlan = le16_to_cpu(vlan_id);
1501         memcpy(&mv.mac, addr, ETH_ALEN);
1502         buf = &cmd.req.arg[2];
1503         memcpy(buf, &mv, sizeof(struct qlcnic_macvlan_mbx));
1504         err = qlcnic_issue_cmd(adapter, &cmd);
1505         if (err)
1506                 dev_err(&adapter->pdev->dev,
1507                         "MAC-VLAN %s to CAM failed, err=%d.\n",
1508                         ((op == 1) ? "add " : "delete "), err);
1509         qlcnic_free_mbx_args(&cmd);
1510         return err;
1511 }
1512
1513 void qlcnic_83xx_change_l2_filter(struct qlcnic_adapter *adapter, u64 *addr,
1514                                   __le16 vlan_id)
1515 {
1516         u8 mac[ETH_ALEN];
1517         memcpy(&mac, addr, ETH_ALEN);
1518         qlcnic_83xx_sre_macaddr_change(adapter, mac, vlan_id, QLCNIC_MAC_ADD);
1519 }
1520
1521 void qlcnic_83xx_configure_mac(struct qlcnic_adapter *adapter, u8 *mac,
1522                                u8 type, struct qlcnic_cmd_args *cmd)
1523 {
1524         switch (type) {
1525         case QLCNIC_SET_STATION_MAC:
1526         case QLCNIC_SET_FAC_DEF_MAC:
1527                 memcpy(&cmd->req.arg[2], mac, sizeof(u32));
1528                 memcpy(&cmd->req.arg[3], &mac[4], sizeof(u16));
1529                 break;
1530         }
1531         cmd->req.arg[1] = type;
1532 }
1533
1534 int qlcnic_83xx_get_mac_address(struct qlcnic_adapter *adapter, u8 *mac)
1535 {
1536         int err, i;
1537         struct qlcnic_cmd_args cmd;
1538         u32 mac_low, mac_high;
1539
1540         qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_MAC_ADDRESS);
1541         qlcnic_83xx_configure_mac(adapter, mac, QLCNIC_GET_CURRENT_MAC, &cmd);
1542         err = qlcnic_issue_cmd(adapter, &cmd);
1543
1544         if (err == QLCNIC_RCODE_SUCCESS) {
1545                 mac_low = cmd.rsp.arg[1];
1546                 mac_high = cmd.rsp.arg[2];
1547
1548                 for (i = 0; i < 2; i++)
1549                         mac[i] = (u8) (mac_high >> ((1 - i) * 8));
1550                 for (i = 2; i < 6; i++)
1551                         mac[i] = (u8) (mac_low >> ((5 - i) * 8));
1552         } else {
1553                 dev_err(&adapter->pdev->dev, "Failed to get mac address%d\n",
1554                         err);
1555                 err = -EIO;
1556         }
1557         qlcnic_free_mbx_args(&cmd);
1558         return err;
1559 }
1560
1561 void qlcnic_83xx_config_intr_coal(struct qlcnic_adapter *adapter)
1562 {
1563         int err;
1564         u32 temp;
1565         struct qlcnic_cmd_args cmd;
1566         struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal;
1567
1568         if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
1569                 return;
1570
1571         qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTR_COAL);
1572         cmd.req.arg[1] = 1 | (adapter->recv_ctx->context_id << 16);
1573         cmd.req.arg[3] = coal->flag;
1574         temp = coal->rx_time_us << 16;
1575         cmd.req.arg[2] = coal->rx_packets | temp;
1576         err = qlcnic_issue_cmd(adapter, &cmd);
1577         if (err != QLCNIC_RCODE_SUCCESS)
1578                 dev_info(&adapter->pdev->dev,
1579                          "Failed to send interrupt coalescence parameters\n");
1580         qlcnic_free_mbx_args(&cmd);
1581 }
1582
1583 static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter,
1584                                         u32 data[])
1585 {
1586         u8 link_status, duplex;
1587         /* link speed */
1588         link_status = LSB(data[3]) & 1;
1589         adapter->ahw->link_speed = MSW(data[2]);
1590         adapter->ahw->link_autoneg = MSB(MSW(data[3]));
1591         adapter->ahw->module_type = MSB(LSW(data[3]));
1592         duplex = LSB(MSW(data[3]));
1593         if (duplex)
1594                 adapter->ahw->link_duplex = DUPLEX_FULL;
1595         else
1596                 adapter->ahw->link_duplex = DUPLEX_HALF;
1597         adapter->ahw->has_link_events = 1;
1598         qlcnic_advert_link_change(adapter, link_status);
1599 }
1600
1601 irqreturn_t qlcnic_83xx_handle_aen(int irq, void *data)
1602 {
1603         struct qlcnic_adapter *adapter = data;
1604         qlcnic_83xx_process_aen(adapter);
1605         return IRQ_HANDLED;
1606 }
1607
1608 int qlcnic_enable_eswitch(struct qlcnic_adapter *adapter, u8 port, u8 enable)
1609 {
1610         int err = -EIO;
1611         struct qlcnic_cmd_args cmd;
1612
1613         if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) {
1614                 dev_err(&adapter->pdev->dev,
1615                         "%s: Error, invoked by non management func\n",
1616                         __func__);
1617                 return err;
1618         }
1619
1620         qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_TOGGLE_ESWITCH);
1621         cmd.req.arg[1] = (port & 0xf) | BIT_4;
1622         err = qlcnic_issue_cmd(adapter, &cmd);
1623
1624         if (err != QLCNIC_RCODE_SUCCESS) {
1625                 dev_err(&adapter->pdev->dev, "Failed to enable eswitch%d\n",
1626                         err);
1627                 err = -EIO;
1628         }
1629         qlcnic_free_mbx_args(&cmd);
1630
1631         return err;
1632
1633 }
1634
1635 int qlcnic_83xx_set_nic_info(struct qlcnic_adapter *adapter,
1636                              struct qlcnic_info *nic)
1637 {
1638         int i, err = -EIO;
1639         struct qlcnic_cmd_args cmd;
1640
1641         if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) {
1642                 dev_err(&adapter->pdev->dev,
1643                         "%s: Error, invoked by non management func\n",
1644                         __func__);
1645                 return err;
1646         }
1647
1648         qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_NIC_INFO);
1649         cmd.req.arg[1] = (nic->pci_func << 16);
1650         cmd.req.arg[2] = 0x1 << 16;
1651         cmd.req.arg[3] = nic->phys_port | (nic->switch_mode << 16);
1652         cmd.req.arg[4] = nic->capabilities;
1653         cmd.req.arg[5] = (nic->max_mac_filters & 0xFF) | ((nic->max_mtu) << 16);
1654         cmd.req.arg[6] = (nic->max_tx_ques) | ((nic->max_rx_ques) << 16);
1655         cmd.req.arg[7] = (nic->min_tx_bw) | ((nic->max_tx_bw) << 16);
1656         for (i = 8; i < 32; i++)
1657                 cmd.req.arg[i] = 0;
1658
1659         err = qlcnic_issue_cmd(adapter, &cmd);
1660
1661         if (err != QLCNIC_RCODE_SUCCESS) {
1662                 dev_err(&adapter->pdev->dev, "Failed to set nic info%d\n",
1663                         err);
1664                 err = -EIO;
1665         }
1666
1667         qlcnic_free_mbx_args(&cmd);
1668
1669         return err;
1670 }
1671
1672 int qlcnic_83xx_get_nic_info(struct qlcnic_adapter *adapter,
1673                              struct qlcnic_info *npar_info, u8 func_id)
1674 {
1675         int err;
1676         u32 temp;
1677         u8 op = 0;
1678         struct qlcnic_cmd_args cmd;
1679
1680         qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_NIC_INFO);
1681         if (func_id != adapter->ahw->pci_func) {
1682                 temp = func_id << 16;
1683                 cmd.req.arg[1] = op | BIT_31 | temp;
1684         } else {
1685                 cmd.req.arg[1] = adapter->ahw->pci_func << 16;
1686         }
1687         err = qlcnic_issue_cmd(adapter, &cmd);
1688         if (err) {
1689                 dev_info(&adapter->pdev->dev,
1690                          "Failed to get nic info %d\n", err);
1691                 goto out;
1692         }
1693
1694         npar_info->op_type = cmd.rsp.arg[1];
1695         npar_info->pci_func = cmd.rsp.arg[2] & 0xFFFF;
1696         npar_info->op_mode = (cmd.rsp.arg[2] & 0xFFFF0000) >> 16;
1697         npar_info->phys_port = cmd.rsp.arg[3] & 0xFFFF;
1698         npar_info->switch_mode = (cmd.rsp.arg[3] & 0xFFFF0000) >> 16;
1699         npar_info->capabilities = cmd.rsp.arg[4];
1700         npar_info->max_mac_filters = cmd.rsp.arg[5] & 0xFF;
1701         npar_info->max_mtu = (cmd.rsp.arg[5] & 0xFFFF0000) >> 16;
1702         npar_info->max_tx_ques = cmd.rsp.arg[6] & 0xFFFF;
1703         npar_info->max_rx_ques = (cmd.rsp.arg[6] & 0xFFFF0000) >> 16;
1704         npar_info->min_tx_bw = cmd.rsp.arg[7] & 0xFFFF;
1705         npar_info->max_tx_bw = (cmd.rsp.arg[7] & 0xFFFF0000) >> 16;
1706         if (cmd.rsp.arg[8] & 0x1)
1707                 npar_info->max_bw_reg_offset = (cmd.rsp.arg[8] & 0x7FFE) >> 1;
1708         if (cmd.rsp.arg[8] & 0x10000) {
1709                 temp = (cmd.rsp.arg[8] & 0x7FFE0000) >> 17;
1710                 npar_info->max_linkspeed_reg_offset = temp;
1711         }
1712
1713 out:
1714         qlcnic_free_mbx_args(&cmd);
1715         return err;
1716 }
1717
1718 int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *adapter,
1719                              struct qlcnic_pci_info *pci_info)
1720 {
1721         int i, err = 0, j = 0;
1722         u32 temp;
1723         struct qlcnic_cmd_args cmd;
1724
1725         qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_PCI_INFO);
1726         err = qlcnic_issue_cmd(adapter, &cmd);
1727
1728         adapter->ahw->act_pci_func = 0;
1729         if (err == QLCNIC_RCODE_SUCCESS) {
1730                 pci_info->func_count = cmd.rsp.arg[1] & 0xFF;
1731                 dev_info(&adapter->pdev->dev,
1732                          "%s: total functions = %d\n",
1733                          __func__, pci_info->func_count);
1734                 for (i = 2, j = 0; j < QLCNIC_MAX_PCI_FUNC; j++, pci_info++) {
1735                         pci_info->id = cmd.rsp.arg[i] & 0xFFFF;
1736                         pci_info->active = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
1737                         i++;
1738                         pci_info->type = cmd.rsp.arg[i] & 0xFFFF;
1739                         if (pci_info->type == QLCNIC_TYPE_NIC)
1740                                 adapter->ahw->act_pci_func++;
1741                         temp = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
1742                         pci_info->default_port = temp;
1743                         i++;
1744                         pci_info->tx_min_bw = cmd.rsp.arg[i] & 0xFFFF;
1745                         temp = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
1746                         pci_info->tx_max_bw = temp;
1747                         i = i + 2;
1748                         memcpy(pci_info->mac, &cmd.rsp.arg[i], ETH_ALEN - 2);
1749                         i++;
1750                         memcpy(pci_info->mac + sizeof(u32), &cmd.rsp.arg[i], 2);
1751                         i = i + 3;
1752
1753                         dev_info(&adapter->pdev->dev, "%s:\n"
1754                                  "\tid = %d active = %d type = %d\n"
1755                                  "\tport = %d min bw = %d max bw = %d\n"
1756                                  "\tmac_addr =  %pM\n", __func__,
1757                                  pci_info->id, pci_info->active, pci_info->type,
1758                                  pci_info->default_port, pci_info->tx_min_bw,
1759                                  pci_info->tx_max_bw, pci_info->mac);
1760                 }
1761         } else {
1762                 dev_err(&adapter->pdev->dev, "Failed to get PCI Info%d\n",
1763                         err);
1764                 err = -EIO;
1765         }
1766
1767         qlcnic_free_mbx_args(&cmd);
1768
1769         return err;
1770 }
1771
1772 int qlcnic_83xx_config_intrpt(struct qlcnic_adapter *adapter, bool op_type)
1773 {
1774         int i, index, err;
1775         bool type;
1776         u8 max_ints;
1777         u32 val, temp;
1778         struct qlcnic_cmd_args cmd;
1779
1780         max_ints = adapter->ahw->num_msix;
1781         qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTRPT);
1782         cmd.req.arg[1] = max_ints;
1783         for (i = 0, index = 2; i < max_ints; i++) {
1784                 type = op_type ? QLCNIC_INTRPT_ADD : QLCNIC_INTRPT_DEL;
1785                 val = type | (adapter->ahw->intr_tbl[i].type << 4);
1786                 if (adapter->ahw->intr_tbl[i].type == QLCNIC_INTRPT_MSIX)
1787                         val |= (adapter->ahw->intr_tbl[i].id << 16);
1788                 cmd.req.arg[index++] = val;
1789         }
1790         err = qlcnic_issue_cmd(adapter, &cmd);
1791         if (err) {
1792                 dev_err(&adapter->pdev->dev,
1793                         "Failed to configure interrupts 0x%x\n", err);
1794                 goto out;
1795         }
1796
1797         max_ints = cmd.rsp.arg[1];
1798         for (i = 0, index = 2; i < max_ints; i++, index += 2) {
1799                 val = cmd.rsp.arg[index];
1800                 if (LSB(val)) {
1801                         dev_info(&adapter->pdev->dev,
1802                                  "Can't configure interrupt %d\n",
1803                                  adapter->ahw->intr_tbl[i].id);
1804                         continue;
1805                 }
1806                 if (op_type) {
1807                         adapter->ahw->intr_tbl[i].id = MSW(val);
1808                         adapter->ahw->intr_tbl[i].enabled = 1;
1809                         temp = cmd.rsp.arg[index + 1];
1810                         adapter->ahw->intr_tbl[i].src = temp;
1811                 } else {
1812                         adapter->ahw->intr_tbl[i].id = i;
1813                         adapter->ahw->intr_tbl[i].enabled = 0;
1814                         adapter->ahw->intr_tbl[i].src = 0;
1815                 }
1816         }
1817 out:
1818         qlcnic_free_mbx_args(&cmd);
1819         return err;
1820 }
1821
1822 int qlcnic_83xx_lock_flash(struct qlcnic_adapter *adapter)
1823 {
1824         int id, timeout = 0;
1825         u32 status = 0;
1826
1827         while (status == 0) {
1828                 status = QLC_SHARED_REG_RD32(adapter, QLCNIC_FLASH_LOCK);
1829                 if (status)
1830                         break;
1831
1832                 if (++timeout >= QLC_83XX_FLASH_LOCK_TIMEOUT) {
1833                         id = QLC_SHARED_REG_RD32(adapter,
1834                                                  QLCNIC_FLASH_LOCK_OWNER);
1835                         dev_err(&adapter->pdev->dev,
1836                                 "%s: failed, lock held by %d\n", __func__, id);
1837                         return -EIO;
1838                 }
1839                 usleep_range(1000, 2000);
1840         }
1841
1842         QLC_SHARED_REG_WR32(adapter, QLCNIC_FLASH_LOCK_OWNER, adapter->portnum);
1843         return 0;
1844 }
1845
1846 void qlcnic_83xx_unlock_flash(struct qlcnic_adapter *adapter)
1847 {
1848         QLC_SHARED_REG_RD32(adapter, QLCNIC_FLASH_UNLOCK);
1849         QLC_SHARED_REG_WR32(adapter, QLCNIC_FLASH_LOCK_OWNER, 0xFF);
1850 }
1851
1852 int qlcnic_83xx_lockless_flash_read32(struct qlcnic_adapter *adapter,
1853                                       u32 flash_addr, u8 *p_data,
1854                                       int count)
1855 {
1856         int i, ret;
1857         u32 word, range, flash_offset, addr = flash_addr;
1858         ulong indirect_add, direct_window;
1859
1860         flash_offset = addr & (QLCNIC_FLASH_SECTOR_SIZE - 1);
1861         if (addr & 0x3) {
1862                 dev_err(&adapter->pdev->dev, "Illegal addr = 0x%x\n", addr);
1863                 return -EIO;
1864         }
1865
1866         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_DIRECT_WINDOW,
1867                                      (addr));
1868
1869         range = flash_offset + (count * sizeof(u32));
1870         /* Check if data is spread across multiple sectors */
1871         if (range > (QLCNIC_FLASH_SECTOR_SIZE - 1)) {
1872
1873                 /* Multi sector read */
1874                 for (i = 0; i < count; i++) {
1875                         indirect_add = QLC_83XX_FLASH_DIRECT_DATA(addr);
1876                         ret = qlcnic_83xx_rd_reg_indirect(adapter,
1877                                                           indirect_add);
1878                         if (ret == -EIO)
1879                                 return -EIO;
1880
1881                         word = ret;
1882                         *(u32 *)p_data  = word;
1883                         p_data = p_data + 4;
1884                         addr = addr + 4;
1885                         flash_offset = flash_offset + 4;
1886
1887                         if (flash_offset > (QLCNIC_FLASH_SECTOR_SIZE - 1)) {
1888                                 direct_window = QLC_83XX_FLASH_DIRECT_WINDOW;
1889                                 /* This write is needed once for each sector */
1890                                 qlcnic_83xx_wrt_reg_indirect(adapter,
1891                                                              direct_window,
1892                                                              (addr));
1893                                 flash_offset = 0;
1894                         }
1895                 }
1896         } else {
1897                 /* Single sector read */
1898                 for (i = 0; i < count; i++) {
1899                         indirect_add = QLC_83XX_FLASH_DIRECT_DATA(addr);
1900                         ret = qlcnic_83xx_rd_reg_indirect(adapter,
1901                                                           indirect_add);
1902                         if (ret == -EIO)
1903                                 return -EIO;
1904
1905                         word = ret;
1906                         *(u32 *)p_data  = word;
1907                         p_data = p_data + 4;
1908                         addr = addr + 4;
1909                 }
1910         }
1911
1912         return 0;
1913 }
1914
1915 static int qlcnic_83xx_poll_flash_status_reg(struct qlcnic_adapter *adapter)
1916 {
1917         u32 status;
1918         int retries = QLC_83XX_FLASH_READ_RETRY_COUNT;
1919
1920         do {
1921                 status = qlcnic_83xx_rd_reg_indirect(adapter,
1922                                                      QLC_83XX_FLASH_STATUS);
1923                 if ((status & QLC_83XX_FLASH_STATUS_READY) ==
1924                     QLC_83XX_FLASH_STATUS_READY)
1925                         break;
1926
1927                 msleep(QLC_83XX_FLASH_STATUS_REG_POLL_DELAY);
1928         } while (--retries);
1929
1930         if (!retries)
1931                 return -EIO;
1932
1933         return 0;
1934 }
1935
1936 static int qlcnic_83xx_enable_flash_write_op(struct qlcnic_adapter *adapter)
1937 {
1938         int ret;
1939         u32 cmd;
1940         cmd = adapter->ahw->fdt.write_statusreg_cmd;
1941         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
1942                                      (QLC_83XX_FLASH_FDT_WRITE_DEF_SIG | cmd));
1943         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA,
1944                                      adapter->ahw->fdt.write_enable_bits);
1945         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
1946                                      QLC_83XX_FLASH_SECOND_ERASE_MS_VAL);
1947         ret = qlcnic_83xx_poll_flash_status_reg(adapter);
1948         if (ret)
1949                 return -EIO;
1950
1951         return 0;
1952 }
1953
1954 static int qlcnic_83xx_disable_flash_write_op(struct qlcnic_adapter *adapter)
1955 {
1956         int ret;
1957
1958         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
1959                                      (QLC_83XX_FLASH_FDT_WRITE_DEF_SIG |
1960                                      adapter->ahw->fdt.write_statusreg_cmd));
1961         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA,
1962                                      adapter->ahw->fdt.write_disable_bits);
1963         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
1964                                      QLC_83XX_FLASH_SECOND_ERASE_MS_VAL);
1965         ret = qlcnic_83xx_poll_flash_status_reg(adapter);
1966         if (ret)
1967                 return -EIO;
1968
1969         return 0;
1970 }
1971
1972 int qlcnic_83xx_read_flash_mfg_id(struct qlcnic_adapter *adapter)
1973 {
1974         int ret, mfg_id;
1975
1976         if (qlcnic_83xx_lock_flash(adapter))
1977                 return -EIO;
1978
1979         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
1980                                      QLC_83XX_FLASH_FDT_READ_MFG_ID_VAL);
1981         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
1982                                      QLC_83XX_FLASH_READ_CTRL);
1983         ret = qlcnic_83xx_poll_flash_status_reg(adapter);
1984         if (ret) {
1985                 qlcnic_83xx_unlock_flash(adapter);
1986                 return -EIO;
1987         }
1988
1989         mfg_id = qlcnic_83xx_rd_reg_indirect(adapter, QLC_83XX_FLASH_RDDATA);
1990         if (mfg_id == -EIO)
1991                 return -EIO;
1992
1993         adapter->flash_mfg_id = (mfg_id & 0xFF);
1994         qlcnic_83xx_unlock_flash(adapter);
1995
1996         return 0;
1997 }
1998
1999 int qlcnic_83xx_read_flash_descriptor_table(struct qlcnic_adapter *adapter)
2000 {
2001         int count, fdt_size, ret = 0;
2002
2003         fdt_size = sizeof(struct qlcnic_fdt);
2004         count = fdt_size / sizeof(u32);
2005
2006         if (qlcnic_83xx_lock_flash(adapter))
2007                 return -EIO;
2008
2009         memset(&adapter->ahw->fdt, 0, fdt_size);
2010         ret = qlcnic_83xx_lockless_flash_read32(adapter, QLCNIC_FDT_LOCATION,
2011                                                 (u8 *)&adapter->ahw->fdt,
2012                                                 count);
2013
2014         qlcnic_83xx_unlock_flash(adapter);
2015         return ret;
2016 }
2017
2018 int qlcnic_83xx_erase_flash_sector(struct qlcnic_adapter *adapter,
2019                                    u32 sector_start_addr)
2020 {
2021         u32 reversed_addr, addr1, addr2, cmd;
2022         int ret = -EIO;
2023
2024         if (qlcnic_83xx_lock_flash(adapter) != 0)
2025                 return -EIO;
2026
2027         if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
2028                 ret = qlcnic_83xx_enable_flash_write_op(adapter);
2029                 if (ret) {
2030                         qlcnic_83xx_unlock_flash(adapter);
2031                         dev_err(&adapter->pdev->dev,
2032                                 "%s failed at %d\n",
2033                                 __func__, __LINE__);
2034                         return ret;
2035                 }
2036         }
2037
2038         ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2039         if (ret) {
2040                 qlcnic_83xx_unlock_flash(adapter);
2041                 dev_err(&adapter->pdev->dev,
2042                         "%s: failed at %d\n", __func__, __LINE__);
2043                 return -EIO;
2044         }
2045
2046         addr1 = (sector_start_addr & 0xFF) << 16;
2047         addr2 = (sector_start_addr & 0xFF0000) >> 16;
2048         reversed_addr = addr1 | addr2;
2049
2050         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA,
2051                                      reversed_addr);
2052         cmd = QLC_83XX_FLASH_FDT_ERASE_DEF_SIG | adapter->ahw->fdt.erase_cmd;
2053         if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id)
2054                 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR, cmd);
2055         else
2056                 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2057                                              QLC_83XX_FLASH_OEM_ERASE_SIG);
2058         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2059                                      QLC_83XX_FLASH_LAST_ERASE_MS_VAL);
2060
2061         ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2062         if (ret) {
2063                 qlcnic_83xx_unlock_flash(adapter);
2064                 dev_err(&adapter->pdev->dev,
2065                         "%s: failed at %d\n", __func__, __LINE__);
2066                 return -EIO;
2067         }
2068
2069         if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
2070                 ret = qlcnic_83xx_disable_flash_write_op(adapter);
2071                 if (ret) {
2072                         qlcnic_83xx_unlock_flash(adapter);
2073                         dev_err(&adapter->pdev->dev,
2074                                 "%s: failed at %d\n", __func__, __LINE__);
2075                         return ret;
2076                 }
2077         }
2078
2079         qlcnic_83xx_unlock_flash(adapter);
2080
2081         return 0;
2082 }
2083
2084 int qlcnic_83xx_flash_write32(struct qlcnic_adapter *adapter, u32 addr,
2085                               u32 *p_data)
2086 {
2087         int ret = -EIO;
2088         u32 addr1 = 0x00800000 | (addr >> 2);
2089
2090         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR, addr1);
2091         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA, *p_data);
2092         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2093                                      QLC_83XX_FLASH_LAST_ERASE_MS_VAL);
2094         ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2095         if (ret) {
2096                 dev_err(&adapter->pdev->dev,
2097                         "%s: failed at %d\n", __func__, __LINE__);
2098                 return -EIO;
2099         }
2100
2101         return 0;
2102 }
2103
2104 int qlcnic_83xx_flash_bulk_write(struct qlcnic_adapter *adapter, u32 addr,
2105                                  u32 *p_data, int count)
2106 {
2107         u32 temp;
2108         int ret = -EIO;
2109
2110         if ((count < QLC_83XX_FLASH_BULK_WRITE_MIN) ||
2111             (count > QLC_83XX_FLASH_BULK_WRITE_MAX)) {
2112                 dev_err(&adapter->pdev->dev,
2113                         "%s: Invalid word count\n", __func__);
2114                 return -EIO;
2115         }
2116
2117         temp = qlcnic_83xx_rd_reg_indirect(adapter,
2118                                            QLC_83XX_FLASH_SPI_CONTROL);
2119         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_SPI_CONTROL,
2120                                      (temp | QLC_83XX_FLASH_SPI_CTRL));
2121         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2122                                      QLC_83XX_FLASH_ADDR_TEMP_VAL);
2123
2124         /* First DWORD write */
2125         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA, *p_data++);
2126         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2127                                      QLC_83XX_FLASH_FIRST_MS_PATTERN);
2128         ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2129         if (ret) {
2130                 dev_err(&adapter->pdev->dev,
2131                         "%s: failed at %d\n", __func__, __LINE__);
2132                 return -EIO;
2133         }
2134
2135         count--;
2136         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2137                                      QLC_83XX_FLASH_ADDR_SECOND_TEMP_VAL);
2138         /* Second to N-1 DWORD writes */
2139         while (count != 1) {
2140                 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA,
2141                                              *p_data++);
2142                 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2143                                              QLC_83XX_FLASH_SECOND_MS_PATTERN);
2144                 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2145                 if (ret) {
2146                         dev_err(&adapter->pdev->dev,
2147                                 "%s: failed at %d\n", __func__, __LINE__);
2148                         return -EIO;
2149                 }
2150                 count--;
2151         }
2152
2153         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2154                                      QLC_83XX_FLASH_ADDR_TEMP_VAL |
2155                                      (addr >> 2));
2156         /* Last DWORD write */
2157         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA, *p_data++);
2158         qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2159                                      QLC_83XX_FLASH_LAST_MS_PATTERN);
2160         ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2161         if (ret) {
2162                 dev_err(&adapter->pdev->dev,
2163                         "%s: failed at %d\n", __func__, __LINE__);
2164                 return -EIO;
2165         }
2166
2167         ret = qlcnic_83xx_rd_reg_indirect(adapter, QLC_83XX_FLASH_SPI_STATUS);
2168         if ((ret & QLC_83XX_FLASH_SPI_CTRL) == QLC_83XX_FLASH_SPI_CTRL) {
2169                 dev_err(&adapter->pdev->dev, "%s: failed at %d\n",
2170                         __func__, __LINE__);
2171                 /* Operation failed, clear error bit */
2172                 temp = qlcnic_83xx_rd_reg_indirect(adapter,
2173                                                    QLC_83XX_FLASH_SPI_CONTROL);
2174                 qlcnic_83xx_wrt_reg_indirect(adapter,
2175                                              QLC_83XX_FLASH_SPI_CONTROL,
2176                                              (temp | QLC_83XX_FLASH_SPI_CTRL));
2177         }
2178
2179         return 0;
2180 }
2181
2182 static void qlcnic_83xx_recover_driver_lock(struct qlcnic_adapter *adapter)
2183 {
2184         u32 val, id;
2185
2186         val = QLCRDX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK);
2187
2188         /* Check if recovery need to be performed by the calling function */
2189         if ((val & QLC_83XX_DRV_LOCK_RECOVERY_STATUS_MASK) == 0) {
2190                 val = val & ~0x3F;
2191                 val = val | ((adapter->portnum << 2) |
2192                              QLC_83XX_NEED_DRV_LOCK_RECOVERY);
2193                 QLCWRX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK, val);
2194                 dev_info(&adapter->pdev->dev,
2195                          "%s: lock recovery initiated\n", __func__);
2196                 msleep(QLC_83XX_DRV_LOCK_RECOVERY_DELAY);
2197                 val = QLCRDX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK);
2198                 id = ((val >> 2) & 0xF);
2199                 if (id == adapter->portnum) {
2200                         val = val & ~QLC_83XX_DRV_LOCK_RECOVERY_STATUS_MASK;
2201                         val = val | QLC_83XX_DRV_LOCK_RECOVERY_IN_PROGRESS;
2202                         QLCWRX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK, val);
2203                         /* Force release the lock */
2204                         QLCRDX(adapter->ahw, QLC_83XX_DRV_UNLOCK);
2205                         /* Clear recovery bits */
2206                         val = val & ~0x3F;
2207                         QLCWRX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK, val);
2208                         dev_info(&adapter->pdev->dev,
2209                                  "%s: lock recovery completed\n", __func__);
2210                 } else {
2211                         dev_info(&adapter->pdev->dev,
2212                                  "%s: func %d to resume lock recovery process\n",
2213                                  __func__, id);
2214                 }
2215         } else {
2216                 dev_info(&adapter->pdev->dev,
2217                          "%s: lock recovery initiated by other functions\n",
2218                          __func__);
2219         }
2220 }
2221
2222 int qlcnic_83xx_lock_driver(struct qlcnic_adapter *adapter)
2223 {
2224         u32 lock_alive_counter, val, id, i = 0, status = 0, temp = 0;
2225         int max_attempt = 0;
2226
2227         while (status == 0) {
2228                 status = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK);
2229                 if (status)
2230                         break;
2231
2232                 msleep(QLC_83XX_DRV_LOCK_WAIT_DELAY);
2233                 i++;
2234
2235                 if (i == 1)
2236                         temp = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
2237
2238                 if (i == QLC_83XX_DRV_LOCK_WAIT_COUNTER) {
2239                         val = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
2240                         if (val == temp) {
2241                                 id = val & 0xFF;
2242                                 dev_info(&adapter->pdev->dev,
2243                                          "%s: lock to be recovered from %d\n",
2244                                          __func__, id);
2245                                 qlcnic_83xx_recover_driver_lock(adapter);
2246                                 i = 0;
2247                                 max_attempt++;
2248                         } else {
2249                                 dev_err(&adapter->pdev->dev,
2250                                         "%s: failed to get lock\n", __func__);
2251                                 return -EIO;
2252                         }
2253                 }
2254
2255                 /* Force exit from while loop after few attempts */
2256                 if (max_attempt == QLC_83XX_MAX_DRV_LOCK_RECOVERY_ATTEMPT) {
2257                         dev_err(&adapter->pdev->dev,
2258                                 "%s: failed to get lock\n", __func__);
2259                         return -EIO;
2260                 }
2261         }
2262
2263         val = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
2264         lock_alive_counter = val >> 8;
2265         lock_alive_counter++;
2266         val = lock_alive_counter << 8 | adapter->portnum;
2267         QLCWRX(adapter->ahw, QLC_83XX_DRV_LOCK_ID, val);
2268
2269         return 0;
2270 }
2271
2272 void qlcnic_83xx_unlock_driver(struct qlcnic_adapter *adapter)
2273 {
2274         u32 val, lock_alive_counter, id;
2275
2276         val = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
2277         id = val & 0xFF;
2278         lock_alive_counter = val >> 8;
2279
2280         if (id != adapter->portnum)
2281                 dev_err(&adapter->pdev->dev,
2282                         "%s:Warning func %d is unlocking lock owned by %d\n",
2283                         __func__, adapter->portnum, id);
2284
2285         val = (lock_alive_counter << 8) | 0xFF;
2286         QLCWRX(adapter->ahw, QLC_83XX_DRV_LOCK_ID, val);
2287         QLCRDX(adapter->ahw, QLC_83XX_DRV_UNLOCK);
2288 }
2289
2290 int qlcnic_83xx_ms_mem_write128(struct qlcnic_adapter *adapter, u64 addr,
2291                                 u32 *data, u32 count)
2292 {
2293         int i, j, ret = 0;
2294         u32 temp;
2295
2296         /* Check alignment */
2297         if (addr & 0xF)
2298                 return -EIO;
2299
2300         mutex_lock(&adapter->ahw->mem_lock);
2301         qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_ADDR_HI, 0);
2302
2303         for (i = 0; i < count; i++, addr += 16) {
2304                 if (!((ADDR_IN_RANGE(addr, QLCNIC_ADDR_QDR_NET,
2305                                      QLCNIC_ADDR_QDR_NET_MAX)) ||
2306                       (ADDR_IN_RANGE(addr, QLCNIC_ADDR_DDR_NET,
2307                                      QLCNIC_ADDR_DDR_NET_MAX)))) {
2308                         mutex_unlock(&adapter->ahw->mem_lock);
2309                         return -EIO;
2310                 }
2311
2312                 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_ADDR_LO, addr);
2313                 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_LO,
2314                                              *data++);
2315                 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_HI,
2316                                              *data++);
2317                 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_ULO,
2318                                              *data++);
2319                 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_UHI,
2320                                              *data++);
2321                 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_CTRL,
2322                                              QLCNIC_TA_WRITE_ENABLE);
2323                 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_CTRL,
2324                                              QLCNIC_TA_WRITE_START);
2325
2326                 for (j = 0; j < MAX_CTL_CHECK; j++) {
2327                         temp = qlcnic_83xx_rd_reg_indirect(adapter,
2328                                                            QLCNIC_MS_CTRL);
2329                         if ((temp & TA_CTL_BUSY) == 0)
2330                                 break;
2331                 }
2332
2333                 /* Status check failure */
2334                 if (j >= MAX_CTL_CHECK) {
2335                         printk_ratelimited(KERN_WARNING
2336                                            "MS memory write failed\n");
2337                         mutex_unlock(&adapter->ahw->mem_lock);
2338                         return -EIO;
2339                 }
2340         }
2341
2342         mutex_unlock(&adapter->ahw->mem_lock);
2343
2344         return ret;
2345 }