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