xref: /linux/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c (revision 762f99f4f3cb41a775b5157dd761217beba65873)
1004b26b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2aa43c215SJeff Kirsher /*
3aa43c215SJeff Kirsher  * QLogic qlcnic NIC Driver
4577ae39dSJitendra Kalsaria  * Copyright (c) 2009-2013 QLogic Corporation
5aa43c215SJeff Kirsher  */
6aa43c215SJeff Kirsher 
7aa43c215SJeff Kirsher #include "qlcnic.h"
8a15ebd37SHimanshu Madhani #include "qlcnic_hw.h"
9aa43c215SJeff Kirsher 
10aa43c215SJeff Kirsher struct crb_addr_pair {
11aa43c215SJeff Kirsher 	u32 addr;
12aa43c215SJeff Kirsher 	u32 data;
13aa43c215SJeff Kirsher };
14aa43c215SJeff Kirsher 
15aa43c215SJeff Kirsher #define QLCNIC_MAX_CRB_XFORM 60
16aa43c215SJeff Kirsher static unsigned int crb_addr_xform[QLCNIC_MAX_CRB_XFORM];
17aa43c215SJeff Kirsher 
18aa43c215SJeff Kirsher #define crb_addr_transform(name) \
19aa43c215SJeff Kirsher 	(crb_addr_xform[QLCNIC_HW_PX_MAP_CRB_##name] = \
20aa43c215SJeff Kirsher 	QLCNIC_HW_CRB_HUB_AGT_ADR_##name << 20)
21aa43c215SJeff Kirsher 
22aa43c215SJeff Kirsher #define QLCNIC_ADDR_ERROR (0xffffffff)
23aa43c215SJeff Kirsher 
24aa43c215SJeff Kirsher static int
25aa43c215SJeff Kirsher qlcnic_check_fw_hearbeat(struct qlcnic_adapter *adapter);
26aa43c215SJeff Kirsher 
crb_addr_transform_setup(void)27aa43c215SJeff Kirsher static void crb_addr_transform_setup(void)
28aa43c215SJeff Kirsher {
29aa43c215SJeff Kirsher 	crb_addr_transform(XDMA);
30aa43c215SJeff Kirsher 	crb_addr_transform(TIMR);
31aa43c215SJeff Kirsher 	crb_addr_transform(SRE);
32aa43c215SJeff Kirsher 	crb_addr_transform(SQN3);
33aa43c215SJeff Kirsher 	crb_addr_transform(SQN2);
34aa43c215SJeff Kirsher 	crb_addr_transform(SQN1);
35aa43c215SJeff Kirsher 	crb_addr_transform(SQN0);
36aa43c215SJeff Kirsher 	crb_addr_transform(SQS3);
37aa43c215SJeff Kirsher 	crb_addr_transform(SQS2);
38aa43c215SJeff Kirsher 	crb_addr_transform(SQS1);
39aa43c215SJeff Kirsher 	crb_addr_transform(SQS0);
40aa43c215SJeff Kirsher 	crb_addr_transform(RPMX7);
41aa43c215SJeff Kirsher 	crb_addr_transform(RPMX6);
42aa43c215SJeff Kirsher 	crb_addr_transform(RPMX5);
43aa43c215SJeff Kirsher 	crb_addr_transform(RPMX4);
44aa43c215SJeff Kirsher 	crb_addr_transform(RPMX3);
45aa43c215SJeff Kirsher 	crb_addr_transform(RPMX2);
46aa43c215SJeff Kirsher 	crb_addr_transform(RPMX1);
47aa43c215SJeff Kirsher 	crb_addr_transform(RPMX0);
48aa43c215SJeff Kirsher 	crb_addr_transform(ROMUSB);
49aa43c215SJeff Kirsher 	crb_addr_transform(SN);
50aa43c215SJeff Kirsher 	crb_addr_transform(QMN);
51aa43c215SJeff Kirsher 	crb_addr_transform(QMS);
52aa43c215SJeff Kirsher 	crb_addr_transform(PGNI);
53aa43c215SJeff Kirsher 	crb_addr_transform(PGND);
54aa43c215SJeff Kirsher 	crb_addr_transform(PGN3);
55aa43c215SJeff Kirsher 	crb_addr_transform(PGN2);
56aa43c215SJeff Kirsher 	crb_addr_transform(PGN1);
57aa43c215SJeff Kirsher 	crb_addr_transform(PGN0);
58aa43c215SJeff Kirsher 	crb_addr_transform(PGSI);
59aa43c215SJeff Kirsher 	crb_addr_transform(PGSD);
60aa43c215SJeff Kirsher 	crb_addr_transform(PGS3);
61aa43c215SJeff Kirsher 	crb_addr_transform(PGS2);
62aa43c215SJeff Kirsher 	crb_addr_transform(PGS1);
63aa43c215SJeff Kirsher 	crb_addr_transform(PGS0);
64aa43c215SJeff Kirsher 	crb_addr_transform(PS);
65aa43c215SJeff Kirsher 	crb_addr_transform(PH);
66aa43c215SJeff Kirsher 	crb_addr_transform(NIU);
67aa43c215SJeff Kirsher 	crb_addr_transform(I2Q);
68aa43c215SJeff Kirsher 	crb_addr_transform(EG);
69aa43c215SJeff Kirsher 	crb_addr_transform(MN);
70aa43c215SJeff Kirsher 	crb_addr_transform(MS);
71aa43c215SJeff Kirsher 	crb_addr_transform(CAS2);
72aa43c215SJeff Kirsher 	crb_addr_transform(CAS1);
73aa43c215SJeff Kirsher 	crb_addr_transform(CAS0);
74aa43c215SJeff Kirsher 	crb_addr_transform(CAM);
75aa43c215SJeff Kirsher 	crb_addr_transform(C2C1);
76aa43c215SJeff Kirsher 	crb_addr_transform(C2C0);
77aa43c215SJeff Kirsher 	crb_addr_transform(SMB);
78aa43c215SJeff Kirsher 	crb_addr_transform(OCM0);
79aa43c215SJeff Kirsher 	crb_addr_transform(I2C0);
80aa43c215SJeff Kirsher }
81aa43c215SJeff Kirsher 
qlcnic_release_rx_buffers(struct qlcnic_adapter * adapter)82aa43c215SJeff Kirsher void qlcnic_release_rx_buffers(struct qlcnic_adapter *adapter)
83aa43c215SJeff Kirsher {
84aa43c215SJeff Kirsher 	struct qlcnic_recv_context *recv_ctx;
85aa43c215SJeff Kirsher 	struct qlcnic_host_rds_ring *rds_ring;
86aa43c215SJeff Kirsher 	struct qlcnic_rx_buffer *rx_buf;
87aa43c215SJeff Kirsher 	int i, ring;
88aa43c215SJeff Kirsher 
89aa43c215SJeff Kirsher 	recv_ctx = adapter->recv_ctx;
90aa43c215SJeff Kirsher 	for (ring = 0; ring < adapter->max_rds_rings; ring++) {
91aa43c215SJeff Kirsher 		rds_ring = &recv_ctx->rds_rings[ring];
92aa43c215SJeff Kirsher 		for (i = 0; i < rds_ring->num_desc; ++i) {
93aa43c215SJeff Kirsher 			rx_buf = &(rds_ring->rx_buf_arr[i]);
94aa43c215SJeff Kirsher 			if (rx_buf->skb == NULL)
95aa43c215SJeff Kirsher 				continue;
96aa43c215SJeff Kirsher 
97*a14e3904SChristophe JAILLET 			dma_unmap_single(&adapter->pdev->dev, rx_buf->dma,
98*a14e3904SChristophe JAILLET 					 rds_ring->dma_size, DMA_FROM_DEVICE);
99aa43c215SJeff Kirsher 
100aa43c215SJeff Kirsher 			dev_kfree_skb_any(rx_buf->skb);
101aa43c215SJeff Kirsher 		}
102aa43c215SJeff Kirsher 	}
103aa43c215SJeff Kirsher }
104aa43c215SJeff Kirsher 
qlcnic_reset_rx_buffers_list(struct qlcnic_adapter * adapter)105aa43c215SJeff Kirsher void qlcnic_reset_rx_buffers_list(struct qlcnic_adapter *adapter)
106aa43c215SJeff Kirsher {
107aa43c215SJeff Kirsher 	struct qlcnic_recv_context *recv_ctx;
108aa43c215SJeff Kirsher 	struct qlcnic_host_rds_ring *rds_ring;
109aa43c215SJeff Kirsher 	struct qlcnic_rx_buffer *rx_buf;
110aa43c215SJeff Kirsher 	int i, ring;
111aa43c215SJeff Kirsher 
112aa43c215SJeff Kirsher 	recv_ctx = adapter->recv_ctx;
113aa43c215SJeff Kirsher 	for (ring = 0; ring < adapter->max_rds_rings; ring++) {
114aa43c215SJeff Kirsher 		rds_ring = &recv_ctx->rds_rings[ring];
115aa43c215SJeff Kirsher 
116aa43c215SJeff Kirsher 		INIT_LIST_HEAD(&rds_ring->free_list);
117aa43c215SJeff Kirsher 
118aa43c215SJeff Kirsher 		rx_buf = rds_ring->rx_buf_arr;
119aa43c215SJeff Kirsher 		for (i = 0; i < rds_ring->num_desc; i++) {
120aa43c215SJeff Kirsher 			list_add_tail(&rx_buf->list,
121aa43c215SJeff Kirsher 					&rds_ring->free_list);
122aa43c215SJeff Kirsher 			rx_buf++;
123aa43c215SJeff Kirsher 		}
124aa43c215SJeff Kirsher 	}
125aa43c215SJeff Kirsher }
126aa43c215SJeff Kirsher 
qlcnic_release_tx_buffers(struct qlcnic_adapter * adapter,struct qlcnic_host_tx_ring * tx_ring)127012ec812SHimanshu Madhani void qlcnic_release_tx_buffers(struct qlcnic_adapter *adapter,
128012ec812SHimanshu Madhani 			       struct qlcnic_host_tx_ring *tx_ring)
129aa43c215SJeff Kirsher {
130aa43c215SJeff Kirsher 	struct qlcnic_cmd_buffer *cmd_buf;
131aa43c215SJeff Kirsher 	struct qlcnic_skb_frag *buffrag;
132aa43c215SJeff Kirsher 	int i, j;
133aa43c215SJeff Kirsher 
134a02bdd42SShahed Shaikh 	spin_lock(&tx_ring->tx_clean_lock);
135a02bdd42SShahed Shaikh 
136aa43c215SJeff Kirsher 	cmd_buf = tx_ring->cmd_buf_arr;
137aa43c215SJeff Kirsher 	for (i = 0; i < tx_ring->num_desc; i++) {
138aa43c215SJeff Kirsher 		buffrag = cmd_buf->frag_array;
139aa43c215SJeff Kirsher 		if (buffrag->dma) {
140*a14e3904SChristophe JAILLET 			dma_unmap_single(&adapter->pdev->dev, buffrag->dma,
141*a14e3904SChristophe JAILLET 					 buffrag->length, DMA_TO_DEVICE);
142aa43c215SJeff Kirsher 			buffrag->dma = 0ULL;
143aa43c215SJeff Kirsher 		}
144b662eca0SJitendra Kalsaria 		for (j = 1; j < cmd_buf->frag_count; j++) {
145aa43c215SJeff Kirsher 			buffrag++;
146aa43c215SJeff Kirsher 			if (buffrag->dma) {
147*a14e3904SChristophe JAILLET 				dma_unmap_page(&adapter->pdev->dev,
148*a14e3904SChristophe JAILLET 					       buffrag->dma, buffrag->length,
149*a14e3904SChristophe JAILLET 					       DMA_TO_DEVICE);
150aa43c215SJeff Kirsher 				buffrag->dma = 0ULL;
151aa43c215SJeff Kirsher 			}
152aa43c215SJeff Kirsher 		}
153aa43c215SJeff Kirsher 		if (cmd_buf->skb) {
154aa43c215SJeff Kirsher 			dev_kfree_skb_any(cmd_buf->skb);
155aa43c215SJeff Kirsher 			cmd_buf->skb = NULL;
156aa43c215SJeff Kirsher 		}
157aa43c215SJeff Kirsher 		cmd_buf++;
158aa43c215SJeff Kirsher 	}
159a02bdd42SShahed Shaikh 
160a02bdd42SShahed Shaikh 	spin_unlock(&tx_ring->tx_clean_lock);
161aa43c215SJeff Kirsher }
162aa43c215SJeff Kirsher 
qlcnic_free_sw_resources(struct qlcnic_adapter * adapter)163aa43c215SJeff Kirsher void qlcnic_free_sw_resources(struct qlcnic_adapter *adapter)
164aa43c215SJeff Kirsher {
165aa43c215SJeff Kirsher 	struct qlcnic_recv_context *recv_ctx;
166aa43c215SJeff Kirsher 	struct qlcnic_host_rds_ring *rds_ring;
167aa43c215SJeff Kirsher 	int ring;
168aa43c215SJeff Kirsher 
169aa43c215SJeff Kirsher 	recv_ctx = adapter->recv_ctx;
170aa43c215SJeff Kirsher 
171aa43c215SJeff Kirsher 	if (recv_ctx->rds_rings == NULL)
1724be41e92SSony Chacko 		return;
173aa43c215SJeff Kirsher 
174aa43c215SJeff Kirsher 	for (ring = 0; ring < adapter->max_rds_rings; ring++) {
175aa43c215SJeff Kirsher 		rds_ring = &recv_ctx->rds_rings[ring];
176aa43c215SJeff Kirsher 		vfree(rds_ring->rx_buf_arr);
177aa43c215SJeff Kirsher 		rds_ring->rx_buf_arr = NULL;
178aa43c215SJeff Kirsher 	}
179aa43c215SJeff Kirsher 	kfree(recv_ctx->rds_rings);
180aa43c215SJeff Kirsher }
181aa43c215SJeff Kirsher 
qlcnic_alloc_sw_resources(struct qlcnic_adapter * adapter)182aa43c215SJeff Kirsher int qlcnic_alloc_sw_resources(struct qlcnic_adapter *adapter)
183aa43c215SJeff Kirsher {
184aa43c215SJeff Kirsher 	struct qlcnic_recv_context *recv_ctx;
185aa43c215SJeff Kirsher 	struct qlcnic_host_rds_ring *rds_ring;
186aa43c215SJeff Kirsher 	struct qlcnic_host_sds_ring *sds_ring;
187aa43c215SJeff Kirsher 	struct qlcnic_rx_buffer *rx_buf;
188b2adaca9SJoe Perches 	int ring, i;
189aa43c215SJeff Kirsher 
190aa43c215SJeff Kirsher 	recv_ctx = adapter->recv_ctx;
191aa43c215SJeff Kirsher 
192b2adaca9SJoe Perches 	rds_ring = kcalloc(adapter->max_rds_rings,
193b2adaca9SJoe Perches 			   sizeof(struct qlcnic_host_rds_ring), GFP_KERNEL);
194b2adaca9SJoe Perches 	if (rds_ring == NULL)
195aa43c215SJeff Kirsher 		goto err_out;
196b2adaca9SJoe Perches 
197aa43c215SJeff Kirsher 	recv_ctx->rds_rings = rds_ring;
198aa43c215SJeff Kirsher 
199aa43c215SJeff Kirsher 	for (ring = 0; ring < adapter->max_rds_rings; ring++) {
200aa43c215SJeff Kirsher 		rds_ring = &recv_ctx->rds_rings[ring];
201aa43c215SJeff Kirsher 		switch (ring) {
202aa43c215SJeff Kirsher 		case RCV_RING_NORMAL:
203aa43c215SJeff Kirsher 			rds_ring->num_desc = adapter->num_rxd;
204aa43c215SJeff Kirsher 			rds_ring->dma_size = QLCNIC_P3P_RX_BUF_MAX_LEN;
205aa43c215SJeff Kirsher 			rds_ring->skb_size = rds_ring->dma_size + NET_IP_ALIGN;
206aa43c215SJeff Kirsher 			break;
207aa43c215SJeff Kirsher 
208aa43c215SJeff Kirsher 		case RCV_RING_JUMBO:
209aa43c215SJeff Kirsher 			rds_ring->num_desc = adapter->num_jumbo_rxd;
210aa43c215SJeff Kirsher 			rds_ring->dma_size =
211aa43c215SJeff Kirsher 				QLCNIC_P3P_RX_JUMBO_BUF_MAX_LEN;
212aa43c215SJeff Kirsher 
21379788450SSony Chacko 			if (adapter->ahw->capabilities &
21479788450SSony Chacko 			    QLCNIC_FW_CAPABILITY_HW_LRO)
215aa43c215SJeff Kirsher 				rds_ring->dma_size += QLCNIC_LRO_BUFFER_EXTRA;
216aa43c215SJeff Kirsher 
217aa43c215SJeff Kirsher 			rds_ring->skb_size =
218aa43c215SJeff Kirsher 				rds_ring->dma_size + NET_IP_ALIGN;
219aa43c215SJeff Kirsher 			break;
220aa43c215SJeff Kirsher 		}
221aa43c215SJeff Kirsher 		rds_ring->rx_buf_arr = vzalloc(RCV_BUFF_RINGSIZE(rds_ring));
222b2adaca9SJoe Perches 		if (rds_ring->rx_buf_arr == NULL)
223aa43c215SJeff Kirsher 			goto err_out;
2244be41e92SSony Chacko 
225aa43c215SJeff Kirsher 		INIT_LIST_HEAD(&rds_ring->free_list);
226aa43c215SJeff Kirsher 		/*
227aa43c215SJeff Kirsher 		 * Now go through all of them, set reference handles
228aa43c215SJeff Kirsher 		 * and put them in the queues.
229aa43c215SJeff Kirsher 		 */
230aa43c215SJeff Kirsher 		rx_buf = rds_ring->rx_buf_arr;
231aa43c215SJeff Kirsher 		for (i = 0; i < rds_ring->num_desc; i++) {
232aa43c215SJeff Kirsher 			list_add_tail(&rx_buf->list,
233aa43c215SJeff Kirsher 					&rds_ring->free_list);
234aa43c215SJeff Kirsher 			rx_buf->ref_handle = i;
235aa43c215SJeff Kirsher 			rx_buf++;
236aa43c215SJeff Kirsher 		}
237aa43c215SJeff Kirsher 		spin_lock_init(&rds_ring->lock);
238aa43c215SJeff Kirsher 	}
239aa43c215SJeff Kirsher 
24034e8c406SHimanshu Madhani 	for (ring = 0; ring < adapter->drv_sds_rings; ring++) {
241aa43c215SJeff Kirsher 		sds_ring = &recv_ctx->sds_rings[ring];
242aa43c215SJeff Kirsher 		sds_ring->irq = adapter->msix_entries[ring].vector;
243aa43c215SJeff Kirsher 		sds_ring->adapter = adapter;
244aa43c215SJeff Kirsher 		sds_ring->num_desc = adapter->num_rxd;
245012ec812SHimanshu Madhani 		if (qlcnic_82xx_check(adapter)) {
246c2c5e3a0SHimanshu Madhani 			if (qlcnic_check_multi_tx(adapter) &&
247c2c5e3a0SHimanshu Madhani 			    !adapter->ahw->diag_test)
248012ec812SHimanshu Madhani 				sds_ring->tx_ring = &adapter->tx_ring[ring];
249012ec812SHimanshu Madhani 			else
250012ec812SHimanshu Madhani 				sds_ring->tx_ring = &adapter->tx_ring[0];
251012ec812SHimanshu Madhani 		}
252aa43c215SJeff Kirsher 		for (i = 0; i < NUM_RCV_DESC_RINGS; i++)
253aa43c215SJeff Kirsher 			INIT_LIST_HEAD(&sds_ring->free_list[i]);
254aa43c215SJeff Kirsher 	}
255aa43c215SJeff Kirsher 
256aa43c215SJeff Kirsher 	return 0;
257aa43c215SJeff Kirsher 
258aa43c215SJeff Kirsher err_out:
259aa43c215SJeff Kirsher 	qlcnic_free_sw_resources(adapter);
260aa43c215SJeff Kirsher 	return -ENOMEM;
261aa43c215SJeff Kirsher }
262aa43c215SJeff Kirsher 
263aa43c215SJeff Kirsher /*
264aa43c215SJeff Kirsher  * Utility to translate from internal Phantom CRB address
265aa43c215SJeff Kirsher  * to external PCI CRB address.
266aa43c215SJeff Kirsher  */
qlcnic_decode_crb_addr(u32 addr)267aa43c215SJeff Kirsher static u32 qlcnic_decode_crb_addr(u32 addr)
268aa43c215SJeff Kirsher {
269aa43c215SJeff Kirsher 	int i;
270aa43c215SJeff Kirsher 	u32 base_addr, offset, pci_base;
271aa43c215SJeff Kirsher 
272aa43c215SJeff Kirsher 	crb_addr_transform_setup();
273aa43c215SJeff Kirsher 
274aa43c215SJeff Kirsher 	pci_base = QLCNIC_ADDR_ERROR;
275aa43c215SJeff Kirsher 	base_addr = addr & 0xfff00000;
276aa43c215SJeff Kirsher 	offset = addr & 0x000fffff;
277aa43c215SJeff Kirsher 
278aa43c215SJeff Kirsher 	for (i = 0; i < QLCNIC_MAX_CRB_XFORM; i++) {
279aa43c215SJeff Kirsher 		if (crb_addr_xform[i] == base_addr) {
280aa43c215SJeff Kirsher 			pci_base = i << 20;
281aa43c215SJeff Kirsher 			break;
282aa43c215SJeff Kirsher 		}
283aa43c215SJeff Kirsher 	}
284aa43c215SJeff Kirsher 	if (pci_base == QLCNIC_ADDR_ERROR)
285aa43c215SJeff Kirsher 		return pci_base;
286aa43c215SJeff Kirsher 	else
287aa43c215SJeff Kirsher 		return pci_base + offset;
288aa43c215SJeff Kirsher }
289aa43c215SJeff Kirsher 
290aa43c215SJeff Kirsher #define QLCNIC_MAX_ROM_WAIT_USEC	100
291aa43c215SJeff Kirsher 
qlcnic_wait_rom_done(struct qlcnic_adapter * adapter)292aa43c215SJeff Kirsher static int qlcnic_wait_rom_done(struct qlcnic_adapter *adapter)
293aa43c215SJeff Kirsher {
294aa43c215SJeff Kirsher 	long timeout = 0;
295aa43c215SJeff Kirsher 	long done = 0;
2964bd8e738SHimanshu Madhani 	int err = 0;
297aa43c215SJeff Kirsher 
298aa43c215SJeff Kirsher 	cond_resched();
299aa43c215SJeff Kirsher 	while (done == 0) {
3004bd8e738SHimanshu Madhani 		done = QLCRD32(adapter, QLCNIC_ROMUSB_GLB_STATUS, &err);
301aa43c215SJeff Kirsher 		done &= 2;
302aa43c215SJeff Kirsher 		if (++timeout >= QLCNIC_MAX_ROM_WAIT_USEC) {
303aa43c215SJeff Kirsher 			dev_err(&adapter->pdev->dev,
304aa43c215SJeff Kirsher 				"Timeout reached  waiting for rom done");
305aa43c215SJeff Kirsher 			return -EIO;
306aa43c215SJeff Kirsher 		}
307aa43c215SJeff Kirsher 		udelay(1);
308aa43c215SJeff Kirsher 	}
309aa43c215SJeff Kirsher 	return 0;
310aa43c215SJeff Kirsher }
311aa43c215SJeff Kirsher 
do_rom_fast_read(struct qlcnic_adapter * adapter,u32 addr,u32 * valp)312aa43c215SJeff Kirsher static int do_rom_fast_read(struct qlcnic_adapter *adapter,
313aa43c215SJeff Kirsher 			    u32 addr, u32 *valp)
314aa43c215SJeff Kirsher {
3154bd8e738SHimanshu Madhani 	int err = 0;
3164bd8e738SHimanshu Madhani 
317aa43c215SJeff Kirsher 	QLCWR32(adapter, QLCNIC_ROMUSB_ROM_ADDRESS, addr);
318aa43c215SJeff Kirsher 	QLCWR32(adapter, QLCNIC_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
319aa43c215SJeff Kirsher 	QLCWR32(adapter, QLCNIC_ROMUSB_ROM_ABYTE_CNT, 3);
320aa43c215SJeff Kirsher 	QLCWR32(adapter, QLCNIC_ROMUSB_ROM_INSTR_OPCODE, 0xb);
321aa43c215SJeff Kirsher 	if (qlcnic_wait_rom_done(adapter)) {
322aa43c215SJeff Kirsher 		dev_err(&adapter->pdev->dev, "Error waiting for rom done\n");
323aa43c215SJeff Kirsher 		return -EIO;
324aa43c215SJeff Kirsher 	}
325aa43c215SJeff Kirsher 	/* reset abyte_cnt and dummy_byte_cnt */
326aa43c215SJeff Kirsher 	QLCWR32(adapter, QLCNIC_ROMUSB_ROM_ABYTE_CNT, 0);
327aa43c215SJeff Kirsher 	udelay(10);
328aa43c215SJeff Kirsher 	QLCWR32(adapter, QLCNIC_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
329aa43c215SJeff Kirsher 
3304bd8e738SHimanshu Madhani 	*valp = QLCRD32(adapter, QLCNIC_ROMUSB_ROM_RDATA, &err);
3314bd8e738SHimanshu Madhani 	if (err == -EIO)
3324bd8e738SHimanshu Madhani 		return err;
333aa43c215SJeff Kirsher 	return 0;
334aa43c215SJeff Kirsher }
335aa43c215SJeff Kirsher 
do_rom_fast_read_words(struct qlcnic_adapter * adapter,int addr,u8 * bytes,size_t size)336aa43c215SJeff Kirsher static int do_rom_fast_read_words(struct qlcnic_adapter *adapter, int addr,
337aa43c215SJeff Kirsher 				  u8 *bytes, size_t size)
338aa43c215SJeff Kirsher {
339aa43c215SJeff Kirsher 	int addridx;
340aa43c215SJeff Kirsher 	int ret = 0;
341aa43c215SJeff Kirsher 
342aa43c215SJeff Kirsher 	for (addridx = addr; addridx < (addr + size); addridx += 4) {
343aa43c215SJeff Kirsher 		int v;
344aa43c215SJeff Kirsher 		ret = do_rom_fast_read(adapter, addridx, &v);
345aa43c215SJeff Kirsher 		if (ret != 0)
346aa43c215SJeff Kirsher 			break;
347aa43c215SJeff Kirsher 		*(__le32 *)bytes = cpu_to_le32(v);
348aa43c215SJeff Kirsher 		bytes += 4;
349aa43c215SJeff Kirsher 	}
350aa43c215SJeff Kirsher 
351aa43c215SJeff Kirsher 	return ret;
352aa43c215SJeff Kirsher }
353aa43c215SJeff Kirsher 
354aa43c215SJeff Kirsher int
qlcnic_rom_fast_read_words(struct qlcnic_adapter * adapter,int addr,u8 * bytes,size_t size)355aa43c215SJeff Kirsher qlcnic_rom_fast_read_words(struct qlcnic_adapter *adapter, int addr,
356aa43c215SJeff Kirsher 				u8 *bytes, size_t size)
357aa43c215SJeff Kirsher {
358aa43c215SJeff Kirsher 	int ret;
359aa43c215SJeff Kirsher 
360aa43c215SJeff Kirsher 	ret = qlcnic_rom_lock(adapter);
361aa43c215SJeff Kirsher 	if (ret < 0)
362aa43c215SJeff Kirsher 		return ret;
363aa43c215SJeff Kirsher 
364aa43c215SJeff Kirsher 	ret = do_rom_fast_read_words(adapter, addr, bytes, size);
365aa43c215SJeff Kirsher 
366aa43c215SJeff Kirsher 	qlcnic_rom_unlock(adapter);
367aa43c215SJeff Kirsher 	return ret;
368aa43c215SJeff Kirsher }
369aa43c215SJeff Kirsher 
qlcnic_rom_fast_read(struct qlcnic_adapter * adapter,u32 addr,u32 * valp)370aa43c215SJeff Kirsher int qlcnic_rom_fast_read(struct qlcnic_adapter *adapter, u32 addr, u32 *valp)
371aa43c215SJeff Kirsher {
372aa43c215SJeff Kirsher 	int ret;
373aa43c215SJeff Kirsher 
374aa43c215SJeff Kirsher 	if (qlcnic_rom_lock(adapter) != 0)
375aa43c215SJeff Kirsher 		return -EIO;
376aa43c215SJeff Kirsher 
377aa43c215SJeff Kirsher 	ret = do_rom_fast_read(adapter, addr, valp);
378aa43c215SJeff Kirsher 	qlcnic_rom_unlock(adapter);
379aa43c215SJeff Kirsher 	return ret;
380aa43c215SJeff Kirsher }
381aa43c215SJeff Kirsher 
qlcnic_pinit_from_rom(struct qlcnic_adapter * adapter)382aa43c215SJeff Kirsher int qlcnic_pinit_from_rom(struct qlcnic_adapter *adapter)
383aa43c215SJeff Kirsher {
3844bd8e738SHimanshu Madhani 	int addr, err = 0;
385aa43c215SJeff Kirsher 	int i, n, init_delay;
386aa43c215SJeff Kirsher 	struct crb_addr_pair *buf;
387aa43c215SJeff Kirsher 	unsigned offset;
3884bd8e738SHimanshu Madhani 	u32 off, val;
389aa43c215SJeff Kirsher 	struct pci_dev *pdev = adapter->pdev;
390aa43c215SJeff Kirsher 
391a15ebd37SHimanshu Madhani 	QLC_SHARED_REG_WR32(adapter, QLCNIC_CMDPEG_STATE, 0);
392a15ebd37SHimanshu Madhani 	QLC_SHARED_REG_WR32(adapter, QLCNIC_RCVPEG_STATE, 0);
393aa43c215SJeff Kirsher 
39468233c58SSony Chacko 	/* Halt all the indiviual PEGs and other blocks */
39568233c58SSony Chacko 	/* disable all I2Q */
39668233c58SSony Chacko 	QLCWR32(adapter, QLCNIC_CRB_I2Q + 0x10, 0x0);
39768233c58SSony Chacko 	QLCWR32(adapter, QLCNIC_CRB_I2Q + 0x14, 0x0);
39868233c58SSony Chacko 	QLCWR32(adapter, QLCNIC_CRB_I2Q + 0x18, 0x0);
39968233c58SSony Chacko 	QLCWR32(adapter, QLCNIC_CRB_I2Q + 0x1c, 0x0);
40068233c58SSony Chacko 	QLCWR32(adapter, QLCNIC_CRB_I2Q + 0x20, 0x0);
40168233c58SSony Chacko 	QLCWR32(adapter, QLCNIC_CRB_I2Q + 0x24, 0x0);
40268233c58SSony Chacko 
40368233c58SSony Chacko 	/* disable all niu interrupts */
40468233c58SSony Chacko 	QLCWR32(adapter, QLCNIC_CRB_NIU + 0x40, 0xff);
40568233c58SSony Chacko 	/* disable xge rx/tx */
40668233c58SSony Chacko 	QLCWR32(adapter, QLCNIC_CRB_NIU + 0x70000, 0x00);
40768233c58SSony Chacko 	/* disable xg1 rx/tx */
40868233c58SSony Chacko 	QLCWR32(adapter, QLCNIC_CRB_NIU + 0x80000, 0x00);
40968233c58SSony Chacko 	/* disable sideband mac */
41068233c58SSony Chacko 	QLCWR32(adapter, QLCNIC_CRB_NIU + 0x90000, 0x00);
41168233c58SSony Chacko 	/* disable ap0 mac */
41268233c58SSony Chacko 	QLCWR32(adapter, QLCNIC_CRB_NIU + 0xa0000, 0x00);
41368233c58SSony Chacko 	/* disable ap1 mac */
41468233c58SSony Chacko 	QLCWR32(adapter, QLCNIC_CRB_NIU + 0xb0000, 0x00);
41568233c58SSony Chacko 
41668233c58SSony Chacko 	/* halt sre */
4174bd8e738SHimanshu Madhani 	val = QLCRD32(adapter, QLCNIC_CRB_SRE + 0x1000, &err);
4184bd8e738SHimanshu Madhani 	if (err == -EIO)
4194bd8e738SHimanshu Madhani 		return err;
42068233c58SSony Chacko 	QLCWR32(adapter, QLCNIC_CRB_SRE + 0x1000, val & (~(0x1)));
42168233c58SSony Chacko 
42268233c58SSony Chacko 	/* halt epg */
42368233c58SSony Chacko 	QLCWR32(adapter, QLCNIC_CRB_EPG + 0x1300, 0x1);
42468233c58SSony Chacko 
42568233c58SSony Chacko 	/* halt timers */
42668233c58SSony Chacko 	QLCWR32(adapter, QLCNIC_CRB_TIMER + 0x0, 0x0);
42768233c58SSony Chacko 	QLCWR32(adapter, QLCNIC_CRB_TIMER + 0x8, 0x0);
42868233c58SSony Chacko 	QLCWR32(adapter, QLCNIC_CRB_TIMER + 0x10, 0x0);
42968233c58SSony Chacko 	QLCWR32(adapter, QLCNIC_CRB_TIMER + 0x18, 0x0);
43068233c58SSony Chacko 	QLCWR32(adapter, QLCNIC_CRB_TIMER + 0x100, 0x0);
43168233c58SSony Chacko 	QLCWR32(adapter, QLCNIC_CRB_TIMER + 0x200, 0x0);
43268233c58SSony Chacko 	/* halt pegs */
43368233c58SSony Chacko 	QLCWR32(adapter, QLCNIC_CRB_PEG_NET_0 + 0x3c, 1);
43468233c58SSony Chacko 	QLCWR32(adapter, QLCNIC_CRB_PEG_NET_1 + 0x3c, 1);
43568233c58SSony Chacko 	QLCWR32(adapter, QLCNIC_CRB_PEG_NET_2 + 0x3c, 1);
43668233c58SSony Chacko 	QLCWR32(adapter, QLCNIC_CRB_PEG_NET_3 + 0x3c, 1);
43768233c58SSony Chacko 	QLCWR32(adapter, QLCNIC_CRB_PEG_NET_4 + 0x3c, 1);
43868233c58SSony Chacko 	msleep(20);
43968233c58SSony Chacko 
44068233c58SSony Chacko 	/* big hammer don't reset CAM block on reset */
44168233c58SSony Chacko 	QLCWR32(adapter, QLCNIC_ROMUSB_GLB_SW_RESET, 0xfeffffff);
442aa43c215SJeff Kirsher 
443aa43c215SJeff Kirsher 	/* Init HW CRB block */
444aa43c215SJeff Kirsher 	if (qlcnic_rom_fast_read(adapter, 0, &n) != 0 || (n != 0xcafecafe) ||
445aa43c215SJeff Kirsher 			qlcnic_rom_fast_read(adapter, 4, &n) != 0) {
446aa43c215SJeff Kirsher 		dev_err(&pdev->dev, "ERROR Reading crb_init area: val:%x\n", n);
447aa43c215SJeff Kirsher 		return -EIO;
448aa43c215SJeff Kirsher 	}
449aa43c215SJeff Kirsher 	offset = n & 0xffffU;
450aa43c215SJeff Kirsher 	n = (n >> 16) & 0xffffU;
451aa43c215SJeff Kirsher 
452aa43c215SJeff Kirsher 	if (n >= 1024) {
453aa43c215SJeff Kirsher 		dev_err(&pdev->dev, "QLOGIC card flash not initialized.\n");
454aa43c215SJeff Kirsher 		return -EIO;
455aa43c215SJeff Kirsher 	}
456aa43c215SJeff Kirsher 
457aa43c215SJeff Kirsher 	buf = kcalloc(n, sizeof(struct crb_addr_pair), GFP_KERNEL);
458b2adaca9SJoe Perches 	if (buf == NULL)
459aa43c215SJeff Kirsher 		return -ENOMEM;
460aa43c215SJeff Kirsher 
461aa43c215SJeff Kirsher 	for (i = 0; i < n; i++) {
462aa43c215SJeff Kirsher 		if (qlcnic_rom_fast_read(adapter, 8*i + 4*offset, &val) != 0 ||
463aa43c215SJeff Kirsher 		qlcnic_rom_fast_read(adapter, 8*i + 4*offset + 4, &addr) != 0) {
464aa43c215SJeff Kirsher 			kfree(buf);
465aa43c215SJeff Kirsher 			return -EIO;
466aa43c215SJeff Kirsher 		}
467aa43c215SJeff Kirsher 
468aa43c215SJeff Kirsher 		buf[i].addr = addr;
469aa43c215SJeff Kirsher 		buf[i].data = val;
470aa43c215SJeff Kirsher 	}
471aa43c215SJeff Kirsher 
472aa43c215SJeff Kirsher 	for (i = 0; i < n; i++) {
473aa43c215SJeff Kirsher 
474aa43c215SJeff Kirsher 		off = qlcnic_decode_crb_addr(buf[i].addr);
475aa43c215SJeff Kirsher 		if (off == QLCNIC_ADDR_ERROR) {
476aa43c215SJeff Kirsher 			dev_err(&pdev->dev, "CRB init value out of range %x\n",
477aa43c215SJeff Kirsher 					buf[i].addr);
478aa43c215SJeff Kirsher 			continue;
479aa43c215SJeff Kirsher 		}
480aa43c215SJeff Kirsher 		off += QLCNIC_PCI_CRBSPACE;
481aa43c215SJeff Kirsher 
482aa43c215SJeff Kirsher 		if (off & 1)
483aa43c215SJeff Kirsher 			continue;
484aa43c215SJeff Kirsher 
485aa43c215SJeff Kirsher 		/* skipping cold reboot MAGIC */
486aa43c215SJeff Kirsher 		if (off == QLCNIC_CAM_RAM(0x1fc))
487aa43c215SJeff Kirsher 			continue;
488aa43c215SJeff Kirsher 		if (off == (QLCNIC_CRB_I2C0 + 0x1c))
489aa43c215SJeff Kirsher 			continue;
490aa43c215SJeff Kirsher 		if (off == (ROMUSB_GLB + 0xbc)) /* do not reset PCI */
491aa43c215SJeff Kirsher 			continue;
492aa43c215SJeff Kirsher 		if (off == (ROMUSB_GLB + 0xa8))
493aa43c215SJeff Kirsher 			continue;
494aa43c215SJeff Kirsher 		if (off == (ROMUSB_GLB + 0xc8)) /* core clock */
495aa43c215SJeff Kirsher 			continue;
496aa43c215SJeff Kirsher 		if (off == (ROMUSB_GLB + 0x24)) /* MN clock */
497aa43c215SJeff Kirsher 			continue;
498aa43c215SJeff Kirsher 		if (off == (ROMUSB_GLB + 0x1c)) /* MS clock */
499aa43c215SJeff Kirsher 			continue;
500aa43c215SJeff Kirsher 		if ((off & 0x0ff00000) == QLCNIC_CRB_DDR_NET)
501aa43c215SJeff Kirsher 			continue;
502aa43c215SJeff Kirsher 		/* skip the function enable register */
503aa43c215SJeff Kirsher 		if (off == QLCNIC_PCIE_REG(PCIE_SETUP_FUNCTION))
504aa43c215SJeff Kirsher 			continue;
505aa43c215SJeff Kirsher 		if (off == QLCNIC_PCIE_REG(PCIE_SETUP_FUNCTION2))
506aa43c215SJeff Kirsher 			continue;
507aa43c215SJeff Kirsher 		if ((off & 0x0ff00000) == QLCNIC_CRB_SMB)
508aa43c215SJeff Kirsher 			continue;
509aa43c215SJeff Kirsher 
510aa43c215SJeff Kirsher 		init_delay = 1;
511aa43c215SJeff Kirsher 		/* After writing this register, HW needs time for CRB */
512aa43c215SJeff Kirsher 		/* to quiet down (else crb_window returns 0xffffffff) */
513aa43c215SJeff Kirsher 		if (off == QLCNIC_ROMUSB_GLB_SW_RESET)
514aa43c215SJeff Kirsher 			init_delay = 1000;
515aa43c215SJeff Kirsher 
516aa43c215SJeff Kirsher 		QLCWR32(adapter, off, buf[i].data);
517aa43c215SJeff Kirsher 
518aa43c215SJeff Kirsher 		msleep(init_delay);
519aa43c215SJeff Kirsher 	}
520aa43c215SJeff Kirsher 	kfree(buf);
521aa43c215SJeff Kirsher 
522aa43c215SJeff Kirsher 	/* Initialize protocol process engine */
523aa43c215SJeff Kirsher 	QLCWR32(adapter, QLCNIC_CRB_PEG_NET_D + 0xec, 0x1e);
524aa43c215SJeff Kirsher 	QLCWR32(adapter, QLCNIC_CRB_PEG_NET_D + 0x4c, 8);
525aa43c215SJeff Kirsher 	QLCWR32(adapter, QLCNIC_CRB_PEG_NET_I + 0x4c, 8);
526aa43c215SJeff Kirsher 	QLCWR32(adapter, QLCNIC_CRB_PEG_NET_0 + 0x8, 0);
527aa43c215SJeff Kirsher 	QLCWR32(adapter, QLCNIC_CRB_PEG_NET_0 + 0xc, 0);
528aa43c215SJeff Kirsher 	QLCWR32(adapter, QLCNIC_CRB_PEG_NET_1 + 0x8, 0);
529aa43c215SJeff Kirsher 	QLCWR32(adapter, QLCNIC_CRB_PEG_NET_1 + 0xc, 0);
530aa43c215SJeff Kirsher 	QLCWR32(adapter, QLCNIC_CRB_PEG_NET_2 + 0x8, 0);
531aa43c215SJeff Kirsher 	QLCWR32(adapter, QLCNIC_CRB_PEG_NET_2 + 0xc, 0);
532aa43c215SJeff Kirsher 	QLCWR32(adapter, QLCNIC_CRB_PEG_NET_3 + 0x8, 0);
533aa43c215SJeff Kirsher 	QLCWR32(adapter, QLCNIC_CRB_PEG_NET_3 + 0xc, 0);
534aa43c215SJeff Kirsher 	QLCWR32(adapter, QLCNIC_CRB_PEG_NET_4 + 0x8, 0);
535aa43c215SJeff Kirsher 	QLCWR32(adapter, QLCNIC_CRB_PEG_NET_4 + 0xc, 0);
536c1b2037fSJitendra Kalsaria 	usleep_range(1000, 1500);
53768233c58SSony Chacko 
538a15ebd37SHimanshu Madhani 	QLC_SHARED_REG_WR32(adapter, QLCNIC_PEG_HALT_STATUS1, 0);
539a15ebd37SHimanshu Madhani 	QLC_SHARED_REG_WR32(adapter, QLCNIC_PEG_HALT_STATUS2, 0);
54068233c58SSony Chacko 
541aa43c215SJeff Kirsher 	return 0;
542aa43c215SJeff Kirsher }
543aa43c215SJeff Kirsher 
qlcnic_cmd_peg_ready(struct qlcnic_adapter * adapter)544aa43c215SJeff Kirsher static int qlcnic_cmd_peg_ready(struct qlcnic_adapter *adapter)
545aa43c215SJeff Kirsher {
546aa43c215SJeff Kirsher 	u32 val;
547aa43c215SJeff Kirsher 	int retries = QLCNIC_CMDPEG_CHECK_RETRY_COUNT;
548aa43c215SJeff Kirsher 
549aa43c215SJeff Kirsher 	do {
550a15ebd37SHimanshu Madhani 		val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CMDPEG_STATE);
551aa43c215SJeff Kirsher 
552aa43c215SJeff Kirsher 		switch (val) {
553aa43c215SJeff Kirsher 		case PHAN_INITIALIZE_COMPLETE:
554aa43c215SJeff Kirsher 		case PHAN_INITIALIZE_ACK:
555aa43c215SJeff Kirsher 			return 0;
556aa43c215SJeff Kirsher 		case PHAN_INITIALIZE_FAILED:
557aa43c215SJeff Kirsher 			goto out_err;
558aa43c215SJeff Kirsher 		default:
559aa43c215SJeff Kirsher 			break;
560aa43c215SJeff Kirsher 		}
561aa43c215SJeff Kirsher 
562aa43c215SJeff Kirsher 		msleep(QLCNIC_CMDPEG_CHECK_DELAY);
563aa43c215SJeff Kirsher 
564aa43c215SJeff Kirsher 	} while (--retries);
565aa43c215SJeff Kirsher 
566a15ebd37SHimanshu Madhani 	QLC_SHARED_REG_WR32(adapter, QLCNIC_CMDPEG_STATE,
567a15ebd37SHimanshu Madhani 			    PHAN_INITIALIZE_FAILED);
568aa43c215SJeff Kirsher 
569aa43c215SJeff Kirsher out_err:
570aa43c215SJeff Kirsher 	dev_err(&adapter->pdev->dev, "Command Peg initialization not "
571aa43c215SJeff Kirsher 		      "complete, state: 0x%x.\n", val);
572aa43c215SJeff Kirsher 	return -EIO;
573aa43c215SJeff Kirsher }
574aa43c215SJeff Kirsher 
575aa43c215SJeff Kirsher static int
qlcnic_receive_peg_ready(struct qlcnic_adapter * adapter)576aa43c215SJeff Kirsher qlcnic_receive_peg_ready(struct qlcnic_adapter *adapter)
577aa43c215SJeff Kirsher {
578aa43c215SJeff Kirsher 	u32 val;
579aa43c215SJeff Kirsher 	int retries = QLCNIC_RCVPEG_CHECK_RETRY_COUNT;
580aa43c215SJeff Kirsher 
581aa43c215SJeff Kirsher 	do {
582a15ebd37SHimanshu Madhani 		val = QLC_SHARED_REG_RD32(adapter, QLCNIC_RCVPEG_STATE);
583aa43c215SJeff Kirsher 
584aa43c215SJeff Kirsher 		if (val == PHAN_PEG_RCV_INITIALIZED)
585aa43c215SJeff Kirsher 			return 0;
586aa43c215SJeff Kirsher 
587aa43c215SJeff Kirsher 		msleep(QLCNIC_RCVPEG_CHECK_DELAY);
588aa43c215SJeff Kirsher 
589aa43c215SJeff Kirsher 	} while (--retries);
590aa43c215SJeff Kirsher 
591f6849d01SColin Ian King 	dev_err(&adapter->pdev->dev, "Receive Peg initialization not complete, state: 0x%x.\n",
592f6849d01SColin Ian King 		val);
593aa43c215SJeff Kirsher 	return -EIO;
594aa43c215SJeff Kirsher }
595aa43c215SJeff Kirsher 
596aa43c215SJeff Kirsher int
qlcnic_check_fw_status(struct qlcnic_adapter * adapter)597aa43c215SJeff Kirsher qlcnic_check_fw_status(struct qlcnic_adapter *adapter)
598aa43c215SJeff Kirsher {
599aa43c215SJeff Kirsher 	int err;
600aa43c215SJeff Kirsher 
601aa43c215SJeff Kirsher 	err = qlcnic_cmd_peg_ready(adapter);
602aa43c215SJeff Kirsher 	if (err)
603aa43c215SJeff Kirsher 		return err;
604aa43c215SJeff Kirsher 
605aa43c215SJeff Kirsher 	err = qlcnic_receive_peg_ready(adapter);
606aa43c215SJeff Kirsher 	if (err)
607aa43c215SJeff Kirsher 		return err;
608aa43c215SJeff Kirsher 
609a15ebd37SHimanshu Madhani 	QLC_SHARED_REG_WR32(adapter, QLCNIC_CMDPEG_STATE, PHAN_INITIALIZE_ACK);
610aa43c215SJeff Kirsher 
611aa43c215SJeff Kirsher 	return err;
612aa43c215SJeff Kirsher }
613aa43c215SJeff Kirsher 
614aa43c215SJeff Kirsher int
qlcnic_setup_idc_param(struct qlcnic_adapter * adapter)615aa43c215SJeff Kirsher qlcnic_setup_idc_param(struct qlcnic_adapter *adapter) {
616aa43c215SJeff Kirsher 
617aa43c215SJeff Kirsher 	int timeo;
618aa43c215SJeff Kirsher 	u32 val;
619aa43c215SJeff Kirsher 
620a15ebd37SHimanshu Madhani 	val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_PARTITION_INFO);
621aa43c215SJeff Kirsher 	val = QLC_DEV_GET_DRV(val, adapter->portnum);
622aa43c215SJeff Kirsher 	if ((val & 0x3) != QLCNIC_TYPE_NIC) {
623aa43c215SJeff Kirsher 		dev_err(&adapter->pdev->dev,
624aa43c215SJeff Kirsher 			"Not an Ethernet NIC func=%u\n", val);
625aa43c215SJeff Kirsher 		return -EIO;
626aa43c215SJeff Kirsher 	}
62779788450SSony Chacko 	adapter->ahw->physical_port = (val >> 2);
628aa43c215SJeff Kirsher 	if (qlcnic_rom_fast_read(adapter, QLCNIC_ROM_DEV_INIT_TIMEOUT, &timeo))
629aa43c215SJeff Kirsher 		timeo = QLCNIC_INIT_TIMEOUT_SECS;
630aa43c215SJeff Kirsher 
631aa43c215SJeff Kirsher 	adapter->dev_init_timeo = timeo;
632aa43c215SJeff Kirsher 
633aa43c215SJeff Kirsher 	if (qlcnic_rom_fast_read(adapter, QLCNIC_ROM_DRV_RESET_TIMEOUT, &timeo))
634aa43c215SJeff Kirsher 		timeo = QLCNIC_RESET_TIMEOUT_SECS;
635aa43c215SJeff Kirsher 
636aa43c215SJeff Kirsher 	adapter->reset_ack_timeo = timeo;
637aa43c215SJeff Kirsher 
638aa43c215SJeff Kirsher 	return 0;
639aa43c215SJeff Kirsher }
640aa43c215SJeff Kirsher 
qlcnic_get_flt_entry(struct qlcnic_adapter * adapter,u8 region,struct qlcnic_flt_entry * region_entry)641aa43c215SJeff Kirsher static int qlcnic_get_flt_entry(struct qlcnic_adapter *adapter, u8 region,
642aa43c215SJeff Kirsher 				struct qlcnic_flt_entry *region_entry)
643aa43c215SJeff Kirsher {
644aa43c215SJeff Kirsher 	struct qlcnic_flt_header flt_hdr;
645aa43c215SJeff Kirsher 	struct qlcnic_flt_entry *flt_entry;
646aa43c215SJeff Kirsher 	int i = 0, ret;
647aa43c215SJeff Kirsher 	u32 entry_size;
648aa43c215SJeff Kirsher 
649aa43c215SJeff Kirsher 	memset(region_entry, 0, sizeof(struct qlcnic_flt_entry));
650aa43c215SJeff Kirsher 	ret = qlcnic_rom_fast_read_words(adapter, QLCNIC_FLT_LOCATION,
651aa43c215SJeff Kirsher 					 (u8 *)&flt_hdr,
652aa43c215SJeff Kirsher 					 sizeof(struct qlcnic_flt_header));
653aa43c215SJeff Kirsher 	if (ret) {
654aa43c215SJeff Kirsher 		dev_warn(&adapter->pdev->dev,
655aa43c215SJeff Kirsher 			 "error reading flash layout header\n");
656aa43c215SJeff Kirsher 		return -EIO;
657aa43c215SJeff Kirsher 	}
658aa43c215SJeff Kirsher 
659aa43c215SJeff Kirsher 	entry_size = flt_hdr.len - sizeof(struct qlcnic_flt_header);
660a15ebd37SHimanshu Madhani 	flt_entry = vzalloc(entry_size);
661b2adaca9SJoe Perches 	if (flt_entry == NULL)
662aa43c215SJeff Kirsher 		return -EIO;
663aa43c215SJeff Kirsher 
664aa43c215SJeff Kirsher 	ret = qlcnic_rom_fast_read_words(adapter, QLCNIC_FLT_LOCATION +
665aa43c215SJeff Kirsher 					 sizeof(struct qlcnic_flt_header),
666aa43c215SJeff Kirsher 					 (u8 *)flt_entry, entry_size);
667aa43c215SJeff Kirsher 	if (ret) {
668aa43c215SJeff Kirsher 		dev_warn(&adapter->pdev->dev,
669aa43c215SJeff Kirsher 			 "error reading flash layout entries\n");
670aa43c215SJeff Kirsher 		goto err_out;
671aa43c215SJeff Kirsher 	}
672aa43c215SJeff Kirsher 
673aa43c215SJeff Kirsher 	while (i < (entry_size/sizeof(struct qlcnic_flt_entry))) {
674aa43c215SJeff Kirsher 		if (flt_entry[i].region == region)
675aa43c215SJeff Kirsher 			break;
676aa43c215SJeff Kirsher 		i++;
677aa43c215SJeff Kirsher 	}
678aa43c215SJeff Kirsher 	if (i >= (entry_size/sizeof(struct qlcnic_flt_entry))) {
679aa43c215SJeff Kirsher 		dev_warn(&adapter->pdev->dev,
680aa43c215SJeff Kirsher 			 "region=%x not found in %d regions\n", region, i);
681aa43c215SJeff Kirsher 		ret = -EIO;
682aa43c215SJeff Kirsher 		goto err_out;
683aa43c215SJeff Kirsher 	}
684aa43c215SJeff Kirsher 	memcpy(region_entry, &flt_entry[i], sizeof(struct qlcnic_flt_entry));
685aa43c215SJeff Kirsher 
686aa43c215SJeff Kirsher err_out:
687aa43c215SJeff Kirsher 	vfree(flt_entry);
688aa43c215SJeff Kirsher 	return ret;
689aa43c215SJeff Kirsher }
690aa43c215SJeff Kirsher 
691aa43c215SJeff Kirsher int
qlcnic_check_flash_fw_ver(struct qlcnic_adapter * adapter)692aa43c215SJeff Kirsher qlcnic_check_flash_fw_ver(struct qlcnic_adapter *adapter)
693aa43c215SJeff Kirsher {
694aa43c215SJeff Kirsher 	struct qlcnic_flt_entry fw_entry;
695aa43c215SJeff Kirsher 	u32 ver = -1, min_ver;
696aa43c215SJeff Kirsher 	int ret;
697aa43c215SJeff Kirsher 
698a2050c7eSSritej Velaga 	if (adapter->ahw->revision_id == QLCNIC_P3P_C0)
699a2050c7eSSritej Velaga 		ret = qlcnic_get_flt_entry(adapter, QLCNIC_C0_FW_IMAGE_REGION,
700a2050c7eSSritej Velaga 						 &fw_entry);
701a2050c7eSSritej Velaga 	else
702a2050c7eSSritej Velaga 		ret = qlcnic_get_flt_entry(adapter, QLCNIC_B0_FW_IMAGE_REGION,
703a2050c7eSSritej Velaga 						 &fw_entry);
704a2050c7eSSritej Velaga 
705aa43c215SJeff Kirsher 	if (!ret)
706aa43c215SJeff Kirsher 		/* 0-4:-signature,  4-8:-fw version */
707aa43c215SJeff Kirsher 		qlcnic_rom_fast_read(adapter, fw_entry.start_addr + 4,
708aa43c215SJeff Kirsher 				     (int *)&ver);
709aa43c215SJeff Kirsher 	else
710aa43c215SJeff Kirsher 		qlcnic_rom_fast_read(adapter, QLCNIC_FW_VERSION_OFFSET,
711aa43c215SJeff Kirsher 				     (int *)&ver);
712aa43c215SJeff Kirsher 
713aa43c215SJeff Kirsher 	ver = QLCNIC_DECODE_VERSION(ver);
714aa43c215SJeff Kirsher 	min_ver = QLCNIC_MIN_FW_VERSION;
715aa43c215SJeff Kirsher 
716aa43c215SJeff Kirsher 	if (ver < min_ver) {
717aa43c215SJeff Kirsher 		dev_err(&adapter->pdev->dev,
718aa43c215SJeff Kirsher 			"firmware version %d.%d.%d unsupported."
719aa43c215SJeff Kirsher 			"Min supported version %d.%d.%d\n",
720aa43c215SJeff Kirsher 			_major(ver), _minor(ver), _build(ver),
721aa43c215SJeff Kirsher 			_major(min_ver), _minor(min_ver), _build(min_ver));
722aa43c215SJeff Kirsher 		return -EINVAL;
723aa43c215SJeff Kirsher 	}
724aa43c215SJeff Kirsher 
725aa43c215SJeff Kirsher 	return 0;
726aa43c215SJeff Kirsher }
727aa43c215SJeff Kirsher 
728aa43c215SJeff Kirsher static int
qlcnic_has_mn(struct qlcnic_adapter * adapter)729aa43c215SJeff Kirsher qlcnic_has_mn(struct qlcnic_adapter *adapter)
730aa43c215SJeff Kirsher {
7314bd8e738SHimanshu Madhani 	u32 capability = 0;
7324bd8e738SHimanshu Madhani 	int err = 0;
733aa43c215SJeff Kirsher 
7344bd8e738SHimanshu Madhani 	capability = QLCRD32(adapter, QLCNIC_PEG_TUNE_CAPABILITY, &err);
7354bd8e738SHimanshu Madhani 	if (err == -EIO)
7364bd8e738SHimanshu Madhani 		return err;
737aa43c215SJeff Kirsher 	if (capability & QLCNIC_PEG_TUNE_MN_PRESENT)
738aa43c215SJeff Kirsher 		return 1;
739aa43c215SJeff Kirsher 
740aa43c215SJeff Kirsher 	return 0;
741aa43c215SJeff Kirsher }
742aa43c215SJeff Kirsher 
743aa43c215SJeff Kirsher static
qlcnic_get_table_desc(const u8 * unirom,int section)744aa43c215SJeff Kirsher struct uni_table_desc *qlcnic_get_table_desc(const u8 *unirom, int section)
745aa43c215SJeff Kirsher {
74663507592SShahed Shaikh 	u32 i, entries;
747aa43c215SJeff Kirsher 	struct uni_table_desc *directory = (struct uni_table_desc *) &unirom[0];
74863507592SShahed Shaikh 	entries = le32_to_cpu(directory->num_entries);
749aa43c215SJeff Kirsher 
750aa43c215SJeff Kirsher 	for (i = 0; i < entries; i++) {
751aa43c215SJeff Kirsher 
75263507592SShahed Shaikh 		u32 offs = le32_to_cpu(directory->findex) +
75363507592SShahed Shaikh 			   i * le32_to_cpu(directory->entry_size);
75463507592SShahed Shaikh 		u32 tab_type = le32_to_cpu(*((__le32 *)&unirom[offs] + 8));
755aa43c215SJeff Kirsher 
756aa43c215SJeff Kirsher 		if (tab_type == section)
757aa43c215SJeff Kirsher 			return (struct uni_table_desc *) &unirom[offs];
758aa43c215SJeff Kirsher 	}
759aa43c215SJeff Kirsher 
760aa43c215SJeff Kirsher 	return NULL;
761aa43c215SJeff Kirsher }
762aa43c215SJeff Kirsher 
763aa43c215SJeff Kirsher #define FILEHEADER_SIZE (14 * 4)
764aa43c215SJeff Kirsher 
765aa43c215SJeff Kirsher static int
qlcnic_validate_header(struct qlcnic_adapter * adapter)766aa43c215SJeff Kirsher qlcnic_validate_header(struct qlcnic_adapter *adapter)
767aa43c215SJeff Kirsher {
768aa43c215SJeff Kirsher 	const u8 *unirom = adapter->fw->data;
769aa43c215SJeff Kirsher 	struct uni_table_desc *directory = (struct uni_table_desc *) &unirom[0];
77063507592SShahed Shaikh 	u32 entries, entry_size, tab_size, fw_file_size;
77163507592SShahed Shaikh 
77263507592SShahed Shaikh 	fw_file_size = adapter->fw->size;
773aa43c215SJeff Kirsher 
774aa43c215SJeff Kirsher 	if (fw_file_size < FILEHEADER_SIZE)
775aa43c215SJeff Kirsher 		return -EINVAL;
776aa43c215SJeff Kirsher 
77763507592SShahed Shaikh 	entries = le32_to_cpu(directory->num_entries);
77863507592SShahed Shaikh 	entry_size = le32_to_cpu(directory->entry_size);
77963507592SShahed Shaikh 	tab_size = le32_to_cpu(directory->findex) + (entries * entry_size);
780aa43c215SJeff Kirsher 
781aa43c215SJeff Kirsher 	if (fw_file_size < tab_size)
782aa43c215SJeff Kirsher 		return -EINVAL;
783aa43c215SJeff Kirsher 
784aa43c215SJeff Kirsher 	return 0;
785aa43c215SJeff Kirsher }
786aa43c215SJeff Kirsher 
787aa43c215SJeff Kirsher static int
qlcnic_validate_bootld(struct qlcnic_adapter * adapter)788aa43c215SJeff Kirsher qlcnic_validate_bootld(struct qlcnic_adapter *adapter)
789aa43c215SJeff Kirsher {
790aa43c215SJeff Kirsher 	struct uni_table_desc *tab_desc;
791aa43c215SJeff Kirsher 	struct uni_data_desc *descr;
79263507592SShahed Shaikh 	u32 offs, tab_size, data_size, idx;
793aa43c215SJeff Kirsher 	const u8 *unirom = adapter->fw->data;
79463507592SShahed Shaikh 	__le32 temp;
795aa43c215SJeff Kirsher 
79663507592SShahed Shaikh 	temp = *((__le32 *)&unirom[adapter->file_prd_off] +
79763507592SShahed Shaikh 		 QLCNIC_UNI_BOOTLD_IDX_OFF);
79863507592SShahed Shaikh 	idx = le32_to_cpu(temp);
799aa43c215SJeff Kirsher 	tab_desc = qlcnic_get_table_desc(unirom, QLCNIC_UNI_DIR_SECT_BOOTLD);
800aa43c215SJeff Kirsher 
801aa43c215SJeff Kirsher 	if (!tab_desc)
802aa43c215SJeff Kirsher 		return -EINVAL;
803aa43c215SJeff Kirsher 
80463507592SShahed Shaikh 	tab_size = le32_to_cpu(tab_desc->findex) +
80563507592SShahed Shaikh 		   le32_to_cpu(tab_desc->entry_size) * (idx + 1);
806aa43c215SJeff Kirsher 
807aa43c215SJeff Kirsher 	if (adapter->fw->size < tab_size)
808aa43c215SJeff Kirsher 		return -EINVAL;
809aa43c215SJeff Kirsher 
81063507592SShahed Shaikh 	offs = le32_to_cpu(tab_desc->findex) +
81163507592SShahed Shaikh 	       le32_to_cpu(tab_desc->entry_size) * idx;
812aa43c215SJeff Kirsher 	descr = (struct uni_data_desc *)&unirom[offs];
813aa43c215SJeff Kirsher 
81463507592SShahed Shaikh 	data_size = le32_to_cpu(descr->findex) + le32_to_cpu(descr->size);
815aa43c215SJeff Kirsher 
816aa43c215SJeff Kirsher 	if (adapter->fw->size < data_size)
817aa43c215SJeff Kirsher 		return -EINVAL;
818aa43c215SJeff Kirsher 
819aa43c215SJeff Kirsher 	return 0;
820aa43c215SJeff Kirsher }
821aa43c215SJeff Kirsher 
822aa43c215SJeff Kirsher static int
qlcnic_validate_fw(struct qlcnic_adapter * adapter)823aa43c215SJeff Kirsher qlcnic_validate_fw(struct qlcnic_adapter *adapter)
824aa43c215SJeff Kirsher {
825aa43c215SJeff Kirsher 	struct uni_table_desc *tab_desc;
826aa43c215SJeff Kirsher 	struct uni_data_desc *descr;
827aa43c215SJeff Kirsher 	const u8 *unirom = adapter->fw->data;
82863507592SShahed Shaikh 	u32 offs, tab_size, data_size, idx;
82963507592SShahed Shaikh 	__le32 temp;
830aa43c215SJeff Kirsher 
83163507592SShahed Shaikh 	temp = *((__le32 *)&unirom[adapter->file_prd_off] +
83263507592SShahed Shaikh 		 QLCNIC_UNI_FIRMWARE_IDX_OFF);
83363507592SShahed Shaikh 	idx = le32_to_cpu(temp);
834aa43c215SJeff Kirsher 	tab_desc = qlcnic_get_table_desc(unirom, QLCNIC_UNI_DIR_SECT_FW);
835aa43c215SJeff Kirsher 
836aa43c215SJeff Kirsher 	if (!tab_desc)
837aa43c215SJeff Kirsher 		return -EINVAL;
838aa43c215SJeff Kirsher 
83963507592SShahed Shaikh 	tab_size = le32_to_cpu(tab_desc->findex) +
84063507592SShahed Shaikh 		   le32_to_cpu(tab_desc->entry_size) * (idx + 1);
841aa43c215SJeff Kirsher 
842aa43c215SJeff Kirsher 	if (adapter->fw->size < tab_size)
843aa43c215SJeff Kirsher 		return -EINVAL;
844aa43c215SJeff Kirsher 
84563507592SShahed Shaikh 	offs = le32_to_cpu(tab_desc->findex) +
84663507592SShahed Shaikh 	       le32_to_cpu(tab_desc->entry_size) * idx;
847aa43c215SJeff Kirsher 	descr = (struct uni_data_desc *)&unirom[offs];
84863507592SShahed Shaikh 	data_size = le32_to_cpu(descr->findex) + le32_to_cpu(descr->size);
849aa43c215SJeff Kirsher 
850aa43c215SJeff Kirsher 	if (adapter->fw->size < data_size)
851aa43c215SJeff Kirsher 		return -EINVAL;
852aa43c215SJeff Kirsher 
853aa43c215SJeff Kirsher 	return 0;
854aa43c215SJeff Kirsher }
855aa43c215SJeff Kirsher 
856aa43c215SJeff Kirsher static int
qlcnic_validate_product_offs(struct qlcnic_adapter * adapter)857aa43c215SJeff Kirsher qlcnic_validate_product_offs(struct qlcnic_adapter *adapter)
858aa43c215SJeff Kirsher {
859aa43c215SJeff Kirsher 	struct uni_table_desc *ptab_descr;
860aa43c215SJeff Kirsher 	const u8 *unirom = adapter->fw->data;
861aa43c215SJeff Kirsher 	int mn_present = qlcnic_has_mn(adapter);
86263507592SShahed Shaikh 	u32 entries, entry_size, tab_size, i;
86363507592SShahed Shaikh 	__le32 temp;
864aa43c215SJeff Kirsher 
865aa43c215SJeff Kirsher 	ptab_descr = qlcnic_get_table_desc(unirom,
866aa43c215SJeff Kirsher 				QLCNIC_UNI_DIR_SECT_PRODUCT_TBL);
867aa43c215SJeff Kirsher 	if (!ptab_descr)
868aa43c215SJeff Kirsher 		return -EINVAL;
869aa43c215SJeff Kirsher 
87063507592SShahed Shaikh 	entries = le32_to_cpu(ptab_descr->num_entries);
87163507592SShahed Shaikh 	entry_size = le32_to_cpu(ptab_descr->entry_size);
87263507592SShahed Shaikh 	tab_size = le32_to_cpu(ptab_descr->findex) + (entries * entry_size);
873aa43c215SJeff Kirsher 
874aa43c215SJeff Kirsher 	if (adapter->fw->size < tab_size)
875aa43c215SJeff Kirsher 		return -EINVAL;
876aa43c215SJeff Kirsher 
877aa43c215SJeff Kirsher nomn:
878aa43c215SJeff Kirsher 	for (i = 0; i < entries; i++) {
879aa43c215SJeff Kirsher 
88063507592SShahed Shaikh 		u32 flags, file_chiprev, offs;
881aa43c215SJeff Kirsher 		u8 chiprev = adapter->ahw->revision_id;
882aa43c215SJeff Kirsher 		u32 flagbit;
883aa43c215SJeff Kirsher 
88463507592SShahed Shaikh 		offs = le32_to_cpu(ptab_descr->findex) +
88563507592SShahed Shaikh 		       i * le32_to_cpu(ptab_descr->entry_size);
88663507592SShahed Shaikh 		temp = *((__le32 *)&unirom[offs] + QLCNIC_UNI_FLAGS_OFF);
88763507592SShahed Shaikh 		flags = le32_to_cpu(temp);
88863507592SShahed Shaikh 		temp = *((__le32 *)&unirom[offs] + QLCNIC_UNI_CHIP_REV_OFF);
88963507592SShahed Shaikh 		file_chiprev = le32_to_cpu(temp);
890aa43c215SJeff Kirsher 
891aa43c215SJeff Kirsher 		flagbit = mn_present ? 1 : 2;
892aa43c215SJeff Kirsher 
893aa43c215SJeff Kirsher 		if ((chiprev == file_chiprev) &&
894aa43c215SJeff Kirsher 					((1ULL << flagbit) & flags)) {
895aa43c215SJeff Kirsher 			adapter->file_prd_off = offs;
896aa43c215SJeff Kirsher 			return 0;
897aa43c215SJeff Kirsher 		}
898aa43c215SJeff Kirsher 	}
899aa43c215SJeff Kirsher 	if (mn_present) {
900aa43c215SJeff Kirsher 		mn_present = 0;
901aa43c215SJeff Kirsher 		goto nomn;
902aa43c215SJeff Kirsher 	}
903aa43c215SJeff Kirsher 	return -EINVAL;
904aa43c215SJeff Kirsher }
905aa43c215SJeff Kirsher 
906aa43c215SJeff Kirsher static int
qlcnic_validate_unified_romimage(struct qlcnic_adapter * adapter)907aa43c215SJeff Kirsher qlcnic_validate_unified_romimage(struct qlcnic_adapter *adapter)
908aa43c215SJeff Kirsher {
909aa43c215SJeff Kirsher 	if (qlcnic_validate_header(adapter)) {
910aa43c215SJeff Kirsher 		dev_err(&adapter->pdev->dev,
911aa43c215SJeff Kirsher 				"unified image: header validation failed\n");
912aa43c215SJeff Kirsher 		return -EINVAL;
913aa43c215SJeff Kirsher 	}
914aa43c215SJeff Kirsher 
915aa43c215SJeff Kirsher 	if (qlcnic_validate_product_offs(adapter)) {
916aa43c215SJeff Kirsher 		dev_err(&adapter->pdev->dev,
917aa43c215SJeff Kirsher 				"unified image: product validation failed\n");
918aa43c215SJeff Kirsher 		return -EINVAL;
919aa43c215SJeff Kirsher 	}
920aa43c215SJeff Kirsher 
921aa43c215SJeff Kirsher 	if (qlcnic_validate_bootld(adapter)) {
922aa43c215SJeff Kirsher 		dev_err(&adapter->pdev->dev,
923aa43c215SJeff Kirsher 				"unified image: bootld validation failed\n");
924aa43c215SJeff Kirsher 		return -EINVAL;
925aa43c215SJeff Kirsher 	}
926aa43c215SJeff Kirsher 
927aa43c215SJeff Kirsher 	if (qlcnic_validate_fw(adapter)) {
928aa43c215SJeff Kirsher 		dev_err(&adapter->pdev->dev,
929aa43c215SJeff Kirsher 				"unified image: firmware validation failed\n");
930aa43c215SJeff Kirsher 		return -EINVAL;
931aa43c215SJeff Kirsher 	}
932aa43c215SJeff Kirsher 
933aa43c215SJeff Kirsher 	return 0;
934aa43c215SJeff Kirsher }
935aa43c215SJeff Kirsher 
936aa43c215SJeff Kirsher static
qlcnic_get_data_desc(struct qlcnic_adapter * adapter,u32 section,u32 idx_offset)937aa43c215SJeff Kirsher struct uni_data_desc *qlcnic_get_data_desc(struct qlcnic_adapter *adapter,
938aa43c215SJeff Kirsher 			u32 section, u32 idx_offset)
939aa43c215SJeff Kirsher {
940aa43c215SJeff Kirsher 	const u8 *unirom = adapter->fw->data;
941aa43c215SJeff Kirsher 	struct uni_table_desc *tab_desc;
94263507592SShahed Shaikh 	u32 offs, idx;
94363507592SShahed Shaikh 	__le32 temp;
94463507592SShahed Shaikh 
94563507592SShahed Shaikh 	temp = *((__le32 *)&unirom[adapter->file_prd_off] + idx_offset);
94663507592SShahed Shaikh 	idx = le32_to_cpu(temp);
947aa43c215SJeff Kirsher 
948aa43c215SJeff Kirsher 	tab_desc = qlcnic_get_table_desc(unirom, section);
949aa43c215SJeff Kirsher 
950aa43c215SJeff Kirsher 	if (tab_desc == NULL)
951aa43c215SJeff Kirsher 		return NULL;
952aa43c215SJeff Kirsher 
95363507592SShahed Shaikh 	offs = le32_to_cpu(tab_desc->findex) +
95463507592SShahed Shaikh 	       le32_to_cpu(tab_desc->entry_size) * idx;
955aa43c215SJeff Kirsher 
956aa43c215SJeff Kirsher 	return (struct uni_data_desc *)&unirom[offs];
957aa43c215SJeff Kirsher }
958aa43c215SJeff Kirsher 
959aa43c215SJeff Kirsher static u8 *
qlcnic_get_bootld_offs(struct qlcnic_adapter * adapter)960aa43c215SJeff Kirsher qlcnic_get_bootld_offs(struct qlcnic_adapter *adapter)
961aa43c215SJeff Kirsher {
962aa43c215SJeff Kirsher 	u32 offs = QLCNIC_BOOTLD_START;
96363507592SShahed Shaikh 	struct uni_data_desc *data_desc;
96463507592SShahed Shaikh 
96563507592SShahed Shaikh 	data_desc = qlcnic_get_data_desc(adapter, QLCNIC_UNI_DIR_SECT_BOOTLD,
96663507592SShahed Shaikh 					 QLCNIC_UNI_BOOTLD_IDX_OFF);
967aa43c215SJeff Kirsher 
96879788450SSony Chacko 	if (adapter->ahw->fw_type == QLCNIC_UNIFIED_ROMIMAGE)
96963507592SShahed Shaikh 		offs = le32_to_cpu(data_desc->findex);
970aa43c215SJeff Kirsher 
971aa43c215SJeff Kirsher 	return (u8 *)&adapter->fw->data[offs];
972aa43c215SJeff Kirsher }
973aa43c215SJeff Kirsher 
974aa43c215SJeff Kirsher static u8 *
qlcnic_get_fw_offs(struct qlcnic_adapter * adapter)975aa43c215SJeff Kirsher qlcnic_get_fw_offs(struct qlcnic_adapter *adapter)
976aa43c215SJeff Kirsher {
977aa43c215SJeff Kirsher 	u32 offs = QLCNIC_IMAGE_START;
97863507592SShahed Shaikh 	struct uni_data_desc *data_desc;
979aa43c215SJeff Kirsher 
98063507592SShahed Shaikh 	data_desc = qlcnic_get_data_desc(adapter, QLCNIC_UNI_DIR_SECT_FW,
98163507592SShahed Shaikh 					 QLCNIC_UNI_FIRMWARE_IDX_OFF);
98279788450SSony Chacko 	if (adapter->ahw->fw_type == QLCNIC_UNIFIED_ROMIMAGE)
98363507592SShahed Shaikh 		offs = le32_to_cpu(data_desc->findex);
984aa43c215SJeff Kirsher 
985aa43c215SJeff Kirsher 	return (u8 *)&adapter->fw->data[offs];
986aa43c215SJeff Kirsher }
987aa43c215SJeff Kirsher 
qlcnic_get_fw_size(struct qlcnic_adapter * adapter)98863507592SShahed Shaikh static u32 qlcnic_get_fw_size(struct qlcnic_adapter *adapter)
989aa43c215SJeff Kirsher {
99063507592SShahed Shaikh 	struct uni_data_desc *data_desc;
99163507592SShahed Shaikh 	const u8 *unirom = adapter->fw->data;
99263507592SShahed Shaikh 
99363507592SShahed Shaikh 	data_desc = qlcnic_get_data_desc(adapter, QLCNIC_UNI_DIR_SECT_FW,
99463507592SShahed Shaikh 					 QLCNIC_UNI_FIRMWARE_IDX_OFF);
99563507592SShahed Shaikh 
99679788450SSony Chacko 	if (adapter->ahw->fw_type == QLCNIC_UNIFIED_ROMIMAGE)
99763507592SShahed Shaikh 		return le32_to_cpu(data_desc->size);
998aa43c215SJeff Kirsher 	else
99963507592SShahed Shaikh 		return le32_to_cpu(*(__le32 *)&unirom[QLCNIC_FW_SIZE_OFFSET]);
1000aa43c215SJeff Kirsher }
1001aa43c215SJeff Kirsher 
qlcnic_get_fw_version(struct qlcnic_adapter * adapter)100263507592SShahed Shaikh static u32 qlcnic_get_fw_version(struct qlcnic_adapter *adapter)
1003aa43c215SJeff Kirsher {
1004aa43c215SJeff Kirsher 	struct uni_data_desc *fw_data_desc;
1005aa43c215SJeff Kirsher 	const struct firmware *fw = adapter->fw;
100663507592SShahed Shaikh 	u32 major, minor, sub;
100763507592SShahed Shaikh 	__le32 version_offset;
1008aa43c215SJeff Kirsher 	const u8 *ver_str;
1009aa43c215SJeff Kirsher 	int i, ret;
1010aa43c215SJeff Kirsher 
101179788450SSony Chacko 	if (adapter->ahw->fw_type != QLCNIC_UNIFIED_ROMIMAGE) {
101263507592SShahed Shaikh 		version_offset = *(__le32 *)&fw->data[QLCNIC_FW_VERSION_OFFSET];
101363507592SShahed Shaikh 		return le32_to_cpu(version_offset);
101463507592SShahed Shaikh 	}
1015aa43c215SJeff Kirsher 
1016aa43c215SJeff Kirsher 	fw_data_desc = qlcnic_get_data_desc(adapter, QLCNIC_UNI_DIR_SECT_FW,
1017aa43c215SJeff Kirsher 			QLCNIC_UNI_FIRMWARE_IDX_OFF);
101863507592SShahed Shaikh 	ver_str = fw->data + le32_to_cpu(fw_data_desc->findex) +
101963507592SShahed Shaikh 		  le32_to_cpu(fw_data_desc->size) - 17;
1020aa43c215SJeff Kirsher 
1021aa43c215SJeff Kirsher 	for (i = 0; i < 12; i++) {
1022aa43c215SJeff Kirsher 		if (!strncmp(&ver_str[i], "REV=", 4)) {
1023aa43c215SJeff Kirsher 			ret = sscanf(&ver_str[i+4], "%u.%u.%u ",
1024aa43c215SJeff Kirsher 					&major, &minor, &sub);
1025aa43c215SJeff Kirsher 			if (ret != 3)
1026aa43c215SJeff Kirsher 				return 0;
1027aa43c215SJeff Kirsher 			else
1028aa43c215SJeff Kirsher 				return major + (minor << 8) + (sub << 16);
1029aa43c215SJeff Kirsher 		}
1030aa43c215SJeff Kirsher 	}
1031aa43c215SJeff Kirsher 
1032aa43c215SJeff Kirsher 	return 0;
1033aa43c215SJeff Kirsher }
1034aa43c215SJeff Kirsher 
qlcnic_get_bios_version(struct qlcnic_adapter * adapter)103563507592SShahed Shaikh static u32 qlcnic_get_bios_version(struct qlcnic_adapter *adapter)
1036aa43c215SJeff Kirsher {
1037aa43c215SJeff Kirsher 	const struct firmware *fw = adapter->fw;
103863507592SShahed Shaikh 	u32 bios_ver, prd_off = adapter->file_prd_off;
103963507592SShahed Shaikh 	u8 *version_offset;
104063507592SShahed Shaikh 	__le32 temp;
1041aa43c215SJeff Kirsher 
104279788450SSony Chacko 	if (adapter->ahw->fw_type != QLCNIC_UNIFIED_ROMIMAGE) {
104363507592SShahed Shaikh 		version_offset = (u8 *)&fw->data[QLCNIC_BIOS_VERSION_OFFSET];
104463507592SShahed Shaikh 		return le32_to_cpu(*(__le32 *)version_offset);
104563507592SShahed Shaikh 	}
1046aa43c215SJeff Kirsher 
104763507592SShahed Shaikh 	temp = *((__le32 *)(&fw->data[prd_off]) + QLCNIC_UNI_BIOS_VERSION_OFF);
104863507592SShahed Shaikh 	bios_ver = le32_to_cpu(temp);
1049aa43c215SJeff Kirsher 
1050aa43c215SJeff Kirsher 	return (bios_ver << 16) + ((bios_ver >> 8) & 0xff00) + (bios_ver >> 24);
1051aa43c215SJeff Kirsher }
1052aa43c215SJeff Kirsher 
qlcnic_rom_lock_recovery(struct qlcnic_adapter * adapter)1053aa43c215SJeff Kirsher static void qlcnic_rom_lock_recovery(struct qlcnic_adapter *adapter)
1054aa43c215SJeff Kirsher {
1055aa43c215SJeff Kirsher 	if (qlcnic_pcie_sem_lock(adapter, 2, QLCNIC_ROM_LOCK_ID))
1056aa43c215SJeff Kirsher 		dev_info(&adapter->pdev->dev, "Resetting rom_lock\n");
1057aa43c215SJeff Kirsher 
1058aa43c215SJeff Kirsher 	qlcnic_pcie_sem_unlock(adapter, 2);
1059aa43c215SJeff Kirsher }
1060aa43c215SJeff Kirsher 
1061aa43c215SJeff Kirsher static int
qlcnic_check_fw_hearbeat(struct qlcnic_adapter * adapter)1062aa43c215SJeff Kirsher qlcnic_check_fw_hearbeat(struct qlcnic_adapter *adapter)
1063aa43c215SJeff Kirsher {
1064aa43c215SJeff Kirsher 	u32 heartbeat, ret = -EIO;
1065aa43c215SJeff Kirsher 	int retries = QLCNIC_HEARTBEAT_CHECK_RETRY_COUNT;
1066aa43c215SJeff Kirsher 
1067a15ebd37SHimanshu Madhani 	adapter->heartbeat = QLC_SHARED_REG_RD32(adapter,
1068a15ebd37SHimanshu Madhani 						 QLCNIC_PEG_ALIVE_COUNTER);
1069aa43c215SJeff Kirsher 
1070aa43c215SJeff Kirsher 	do {
1071aa43c215SJeff Kirsher 		msleep(QLCNIC_HEARTBEAT_PERIOD_MSECS);
1072a15ebd37SHimanshu Madhani 		heartbeat = QLC_SHARED_REG_RD32(adapter,
1073a15ebd37SHimanshu Madhani 						QLCNIC_PEG_ALIVE_COUNTER);
1074aa43c215SJeff Kirsher 		if (heartbeat != adapter->heartbeat) {
1075aa43c215SJeff Kirsher 			ret = QLCNIC_RCODE_SUCCESS;
1076aa43c215SJeff Kirsher 			break;
1077aa43c215SJeff Kirsher 		}
1078aa43c215SJeff Kirsher 	} while (--retries);
1079aa43c215SJeff Kirsher 
1080aa43c215SJeff Kirsher 	return ret;
1081aa43c215SJeff Kirsher }
1082aa43c215SJeff Kirsher 
1083aa43c215SJeff Kirsher int
qlcnic_need_fw_reset(struct qlcnic_adapter * adapter)1084aa43c215SJeff Kirsher qlcnic_need_fw_reset(struct qlcnic_adapter *adapter)
1085aa43c215SJeff Kirsher {
1086aa43c215SJeff Kirsher 	if ((adapter->flags & QLCNIC_FW_HANG) ||
1087aa43c215SJeff Kirsher 			qlcnic_check_fw_hearbeat(adapter)) {
1088aa43c215SJeff Kirsher 		qlcnic_rom_lock_recovery(adapter);
1089aa43c215SJeff Kirsher 		return 1;
1090aa43c215SJeff Kirsher 	}
1091aa43c215SJeff Kirsher 
1092aa43c215SJeff Kirsher 	if (adapter->need_fw_reset)
1093aa43c215SJeff Kirsher 		return 1;
1094aa43c215SJeff Kirsher 
1095aa43c215SJeff Kirsher 	if (adapter->fw)
1096aa43c215SJeff Kirsher 		return 1;
1097aa43c215SJeff Kirsher 
1098aa43c215SJeff Kirsher 	return 0;
1099aa43c215SJeff Kirsher }
1100aa43c215SJeff Kirsher 
1101aa43c215SJeff Kirsher static const char *fw_name[] = {
1102aa43c215SJeff Kirsher 	QLCNIC_UNIFIED_ROMIMAGE_NAME,
1103aa43c215SJeff Kirsher 	QLCNIC_FLASH_ROMIMAGE_NAME,
1104aa43c215SJeff Kirsher };
1105aa43c215SJeff Kirsher 
1106aa43c215SJeff Kirsher int
qlcnic_load_firmware(struct qlcnic_adapter * adapter)1107aa43c215SJeff Kirsher qlcnic_load_firmware(struct qlcnic_adapter *adapter)
1108aa43c215SJeff Kirsher {
110963507592SShahed Shaikh 	__le64 *ptr64;
1110aa43c215SJeff Kirsher 	u32 i, flashaddr, size;
1111aa43c215SJeff Kirsher 	const struct firmware *fw = adapter->fw;
1112aa43c215SJeff Kirsher 	struct pci_dev *pdev = adapter->pdev;
1113aa43c215SJeff Kirsher 
1114aa43c215SJeff Kirsher 	dev_info(&pdev->dev, "loading firmware from %s\n",
111579788450SSony Chacko 		 fw_name[adapter->ahw->fw_type]);
1116aa43c215SJeff Kirsher 
1117aa43c215SJeff Kirsher 	if (fw) {
111863507592SShahed Shaikh 		u64 data;
1119aa43c215SJeff Kirsher 
1120aa43c215SJeff Kirsher 		size = (QLCNIC_IMAGE_START - QLCNIC_BOOTLD_START) / 8;
1121aa43c215SJeff Kirsher 
112263507592SShahed Shaikh 		ptr64 = (__le64 *)qlcnic_get_bootld_offs(adapter);
1123aa43c215SJeff Kirsher 		flashaddr = QLCNIC_BOOTLD_START;
1124aa43c215SJeff Kirsher 
1125aa43c215SJeff Kirsher 		for (i = 0; i < size; i++) {
112663507592SShahed Shaikh 			data = le64_to_cpu(ptr64[i]);
1127aa43c215SJeff Kirsher 
1128aa43c215SJeff Kirsher 			if (qlcnic_pci_mem_write_2M(adapter, flashaddr, data))
1129aa43c215SJeff Kirsher 				return -EIO;
1130aa43c215SJeff Kirsher 
1131aa43c215SJeff Kirsher 			flashaddr += 8;
1132aa43c215SJeff Kirsher 		}
1133aa43c215SJeff Kirsher 
113463507592SShahed Shaikh 		size = qlcnic_get_fw_size(adapter) / 8;
1135aa43c215SJeff Kirsher 
113663507592SShahed Shaikh 		ptr64 = (__le64 *)qlcnic_get_fw_offs(adapter);
1137aa43c215SJeff Kirsher 		flashaddr = QLCNIC_IMAGE_START;
1138aa43c215SJeff Kirsher 
1139aa43c215SJeff Kirsher 		for (i = 0; i < size; i++) {
114063507592SShahed Shaikh 			data = le64_to_cpu(ptr64[i]);
1141aa43c215SJeff Kirsher 
1142aa43c215SJeff Kirsher 			if (qlcnic_pci_mem_write_2M(adapter,
1143aa43c215SJeff Kirsher 						flashaddr, data))
1144aa43c215SJeff Kirsher 				return -EIO;
1145aa43c215SJeff Kirsher 
1146aa43c215SJeff Kirsher 			flashaddr += 8;
1147aa43c215SJeff Kirsher 		}
1148aa43c215SJeff Kirsher 
114963507592SShahed Shaikh 		size = qlcnic_get_fw_size(adapter) % 8;
1150aa43c215SJeff Kirsher 		if (size) {
115163507592SShahed Shaikh 			data = le64_to_cpu(ptr64[i]);
1152aa43c215SJeff Kirsher 
1153aa43c215SJeff Kirsher 			if (qlcnic_pci_mem_write_2M(adapter,
1154aa43c215SJeff Kirsher 						flashaddr, data))
1155aa43c215SJeff Kirsher 				return -EIO;
1156aa43c215SJeff Kirsher 		}
1157aa43c215SJeff Kirsher 
1158aa43c215SJeff Kirsher 	} else {
1159aa43c215SJeff Kirsher 		u64 data;
1160aa43c215SJeff Kirsher 		u32 hi, lo;
1161aa43c215SJeff Kirsher 		int ret;
1162aa43c215SJeff Kirsher 		struct qlcnic_flt_entry bootld_entry;
1163aa43c215SJeff Kirsher 
1164aa43c215SJeff Kirsher 		ret = qlcnic_get_flt_entry(adapter, QLCNIC_BOOTLD_REGION,
1165aa43c215SJeff Kirsher 					&bootld_entry);
1166aa43c215SJeff Kirsher 		if (!ret) {
1167aa43c215SJeff Kirsher 			size = bootld_entry.size / 8;
1168aa43c215SJeff Kirsher 			flashaddr = bootld_entry.start_addr;
1169aa43c215SJeff Kirsher 		} else {
1170aa43c215SJeff Kirsher 			size = (QLCNIC_IMAGE_START - QLCNIC_BOOTLD_START) / 8;
1171aa43c215SJeff Kirsher 			flashaddr = QLCNIC_BOOTLD_START;
1172aa43c215SJeff Kirsher 			dev_info(&pdev->dev,
1173aa43c215SJeff Kirsher 				"using legacy method to get flash fw region");
1174aa43c215SJeff Kirsher 		}
1175aa43c215SJeff Kirsher 
1176aa43c215SJeff Kirsher 		for (i = 0; i < size; i++) {
1177aa43c215SJeff Kirsher 			if (qlcnic_rom_fast_read(adapter,
1178aa43c215SJeff Kirsher 					flashaddr, (int *)&lo) != 0)
1179aa43c215SJeff Kirsher 				return -EIO;
1180aa43c215SJeff Kirsher 			if (qlcnic_rom_fast_read(adapter,
1181aa43c215SJeff Kirsher 					flashaddr + 4, (int *)&hi) != 0)
1182aa43c215SJeff Kirsher 				return -EIO;
1183aa43c215SJeff Kirsher 
1184aa43c215SJeff Kirsher 			data = (((u64)hi << 32) | lo);
1185aa43c215SJeff Kirsher 
1186aa43c215SJeff Kirsher 			if (qlcnic_pci_mem_write_2M(adapter,
1187aa43c215SJeff Kirsher 						flashaddr, data))
1188aa43c215SJeff Kirsher 				return -EIO;
1189aa43c215SJeff Kirsher 
1190aa43c215SJeff Kirsher 			flashaddr += 8;
1191aa43c215SJeff Kirsher 		}
1192aa43c215SJeff Kirsher 	}
1193c1b2037fSJitendra Kalsaria 	usleep_range(1000, 1500);
1194aa43c215SJeff Kirsher 
1195aa43c215SJeff Kirsher 	QLCWR32(adapter, QLCNIC_CRB_PEG_NET_0 + 0x18, 0x1020);
1196aa43c215SJeff Kirsher 	QLCWR32(adapter, QLCNIC_ROMUSB_GLB_SW_RESET, 0x80001e);
1197aa43c215SJeff Kirsher 	return 0;
1198aa43c215SJeff Kirsher }
1199aa43c215SJeff Kirsher 
1200aa43c215SJeff Kirsher static int
qlcnic_validate_firmware(struct qlcnic_adapter * adapter)1201aa43c215SJeff Kirsher qlcnic_validate_firmware(struct qlcnic_adapter *adapter)
1202aa43c215SJeff Kirsher {
120363507592SShahed Shaikh 	u32 val;
1204aa43c215SJeff Kirsher 	u32 ver, bios, min_size;
1205aa43c215SJeff Kirsher 	struct pci_dev *pdev = adapter->pdev;
1206aa43c215SJeff Kirsher 	const struct firmware *fw = adapter->fw;
120779788450SSony Chacko 	u8 fw_type = adapter->ahw->fw_type;
1208aa43c215SJeff Kirsher 
1209aa43c215SJeff Kirsher 	if (fw_type == QLCNIC_UNIFIED_ROMIMAGE) {
1210aa43c215SJeff Kirsher 		if (qlcnic_validate_unified_romimage(adapter))
1211aa43c215SJeff Kirsher 			return -EINVAL;
1212aa43c215SJeff Kirsher 
1213aa43c215SJeff Kirsher 		min_size = QLCNIC_UNI_FW_MIN_SIZE;
1214aa43c215SJeff Kirsher 	} else {
121563507592SShahed Shaikh 		val = le32_to_cpu(*(__le32 *)&fw->data[QLCNIC_FW_MAGIC_OFFSET]);
121663507592SShahed Shaikh 		if (val != QLCNIC_BDINFO_MAGIC)
1217aa43c215SJeff Kirsher 			return -EINVAL;
1218aa43c215SJeff Kirsher 
1219aa43c215SJeff Kirsher 		min_size = QLCNIC_FW_MIN_SIZE;
1220aa43c215SJeff Kirsher 	}
1221aa43c215SJeff Kirsher 
1222aa43c215SJeff Kirsher 	if (fw->size < min_size)
1223aa43c215SJeff Kirsher 		return -EINVAL;
1224aa43c215SJeff Kirsher 
1225aa43c215SJeff Kirsher 	val = qlcnic_get_fw_version(adapter);
1226aa43c215SJeff Kirsher 	ver = QLCNIC_DECODE_VERSION(val);
1227aa43c215SJeff Kirsher 
1228aa43c215SJeff Kirsher 	if (ver < QLCNIC_MIN_FW_VERSION) {
1229aa43c215SJeff Kirsher 		dev_err(&pdev->dev,
1230aa43c215SJeff Kirsher 				"%s: firmware version %d.%d.%d unsupported\n",
1231aa43c215SJeff Kirsher 		fw_name[fw_type], _major(ver), _minor(ver), _build(ver));
1232aa43c215SJeff Kirsher 		return -EINVAL;
1233aa43c215SJeff Kirsher 	}
1234aa43c215SJeff Kirsher 
1235aa43c215SJeff Kirsher 	val = qlcnic_get_bios_version(adapter);
1236aa43c215SJeff Kirsher 	qlcnic_rom_fast_read(adapter, QLCNIC_BIOS_VERSION_OFFSET, (int *)&bios);
123763507592SShahed Shaikh 	if (val != bios) {
1238aa43c215SJeff Kirsher 		dev_err(&pdev->dev, "%s: firmware bios is incompatible\n",
1239aa43c215SJeff Kirsher 				fw_name[fw_type]);
1240aa43c215SJeff Kirsher 		return -EINVAL;
1241aa43c215SJeff Kirsher 	}
1242aa43c215SJeff Kirsher 
1243a15ebd37SHimanshu Madhani 	QLC_SHARED_REG_WR32(adapter, QLCNIC_FW_IMG_VALID, QLCNIC_BDINFO_MAGIC);
1244aa43c215SJeff Kirsher 	return 0;
1245aa43c215SJeff Kirsher }
1246aa43c215SJeff Kirsher 
1247aa43c215SJeff Kirsher static void
qlcnic_get_next_fwtype(struct qlcnic_adapter * adapter)1248aa43c215SJeff Kirsher qlcnic_get_next_fwtype(struct qlcnic_adapter *adapter)
1249aa43c215SJeff Kirsher {
1250aa43c215SJeff Kirsher 	u8 fw_type;
1251aa43c215SJeff Kirsher 
125279788450SSony Chacko 	switch (adapter->ahw->fw_type) {
1253aa43c215SJeff Kirsher 	case QLCNIC_UNKNOWN_ROMIMAGE:
1254aa43c215SJeff Kirsher 		fw_type = QLCNIC_UNIFIED_ROMIMAGE;
1255aa43c215SJeff Kirsher 		break;
1256aa43c215SJeff Kirsher 
1257aa43c215SJeff Kirsher 	case QLCNIC_UNIFIED_ROMIMAGE:
1258aa43c215SJeff Kirsher 	default:
1259aa43c215SJeff Kirsher 		fw_type = QLCNIC_FLASH_ROMIMAGE;
1260aa43c215SJeff Kirsher 		break;
1261aa43c215SJeff Kirsher 	}
1262aa43c215SJeff Kirsher 
126379788450SSony Chacko 	adapter->ahw->fw_type = fw_type;
1264aa43c215SJeff Kirsher }
1265aa43c215SJeff Kirsher 
1266aa43c215SJeff Kirsher 
1267aa43c215SJeff Kirsher 
qlcnic_request_firmware(struct qlcnic_adapter * adapter)1268aa43c215SJeff Kirsher void qlcnic_request_firmware(struct qlcnic_adapter *adapter)
1269aa43c215SJeff Kirsher {
1270aa43c215SJeff Kirsher 	struct pci_dev *pdev = adapter->pdev;
1271aa43c215SJeff Kirsher 	int rc;
1272aa43c215SJeff Kirsher 
127379788450SSony Chacko 	adapter->ahw->fw_type = QLCNIC_UNKNOWN_ROMIMAGE;
1274aa43c215SJeff Kirsher 
1275aa43c215SJeff Kirsher next:
1276aa43c215SJeff Kirsher 	qlcnic_get_next_fwtype(adapter);
1277aa43c215SJeff Kirsher 
127879788450SSony Chacko 	if (adapter->ahw->fw_type == QLCNIC_FLASH_ROMIMAGE) {
1279aa43c215SJeff Kirsher 		adapter->fw = NULL;
1280aa43c215SJeff Kirsher 	} else {
1281aa43c215SJeff Kirsher 		rc = request_firmware(&adapter->fw,
128279788450SSony Chacko 				      fw_name[adapter->ahw->fw_type],
128379788450SSony Chacko 				      &pdev->dev);
1284aa43c215SJeff Kirsher 		if (rc != 0)
1285aa43c215SJeff Kirsher 			goto next;
1286aa43c215SJeff Kirsher 
1287aa43c215SJeff Kirsher 		rc = qlcnic_validate_firmware(adapter);
1288aa43c215SJeff Kirsher 		if (rc != 0) {
1289aa43c215SJeff Kirsher 			release_firmware(adapter->fw);
1290c1b2037fSJitendra Kalsaria 			usleep_range(1000, 1500);
1291aa43c215SJeff Kirsher 			goto next;
1292aa43c215SJeff Kirsher 		}
1293aa43c215SJeff Kirsher 	}
1294aa43c215SJeff Kirsher }
1295aa43c215SJeff Kirsher 
1296aa43c215SJeff Kirsher 
1297aa43c215SJeff Kirsher void
qlcnic_release_firmware(struct qlcnic_adapter * adapter)1298aa43c215SJeff Kirsher qlcnic_release_firmware(struct qlcnic_adapter *adapter)
1299aa43c215SJeff Kirsher {
1300aa43c215SJeff Kirsher 	release_firmware(adapter->fw);
1301aa43c215SJeff Kirsher 	adapter->fw = NULL;
1302aa43c215SJeff Kirsher }
1303