prism2_enable_aux_port(struct net_device * dev,int enable)1 static int prism2_enable_aux_port(struct net_device *dev, int enable)
2 {
3 	u16 val, reg;
4 	int i, tries;
5 	unsigned long flags;
6 	struct hostap_interface *iface;
7 	local_info_t *local;
8 
9 	iface = netdev_priv(dev);
10 	local = iface->local;
11 
12 	if (local->no_pri) {
13 		if (enable) {
14 			PDEBUG(DEBUG_EXTRA2, "%s: no PRI f/w - assuming Aux "
15 			       "port is already enabled\n", dev->name);
16 		}
17 		return 0;
18 	}
19 
20 	spin_lock_irqsave(&local->cmdlock, flags);
21 
22 	/* wait until busy bit is clear */
23 	tries = HFA384X_CMD_BUSY_TIMEOUT;
24 	while (HFA384X_INW(HFA384X_CMD_OFF) & HFA384X_CMD_BUSY && tries > 0) {
25 		tries--;
26 		udelay(1);
27 	}
28 	if (tries == 0) {
29 		reg = HFA384X_INW(HFA384X_CMD_OFF);
30 		spin_unlock_irqrestore(&local->cmdlock, flags);
31 		printk("%s: prism2_enable_aux_port - timeout - reg=0x%04x\n",
32 		       dev->name, reg);
33 		return -ETIMEDOUT;
34 	}
35 
36 	val = HFA384X_INW(HFA384X_CONTROL_OFF);
37 
38 	if (enable) {
39 		HFA384X_OUTW(HFA384X_AUX_MAGIC0, HFA384X_PARAM0_OFF);
40 		HFA384X_OUTW(HFA384X_AUX_MAGIC1, HFA384X_PARAM1_OFF);
41 		HFA384X_OUTW(HFA384X_AUX_MAGIC2, HFA384X_PARAM2_OFF);
42 
43 		if ((val & HFA384X_AUX_PORT_MASK) != HFA384X_AUX_PORT_DISABLED)
44 			printk("prism2_enable_aux_port: was not disabled!?\n");
45 		val &= ~HFA384X_AUX_PORT_MASK;
46 		val |= HFA384X_AUX_PORT_ENABLE;
47 	} else {
48 		HFA384X_OUTW(0, HFA384X_PARAM0_OFF);
49 		HFA384X_OUTW(0, HFA384X_PARAM1_OFF);
50 		HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
51 
52 		if ((val & HFA384X_AUX_PORT_MASK) != HFA384X_AUX_PORT_ENABLED)
53 			printk("prism2_enable_aux_port: was not enabled!?\n");
54 		val &= ~HFA384X_AUX_PORT_MASK;
55 		val |= HFA384X_AUX_PORT_DISABLE;
56 	}
57 	HFA384X_OUTW(val, HFA384X_CONTROL_OFF);
58 
59 	udelay(5);
60 
61 	i = 10000;
62 	while (i > 0) {
63 		val = HFA384X_INW(HFA384X_CONTROL_OFF);
64 		val &= HFA384X_AUX_PORT_MASK;
65 
66 		if ((enable && val == HFA384X_AUX_PORT_ENABLED) ||
67 		    (!enable && val == HFA384X_AUX_PORT_DISABLED))
68 			break;
69 
70 		udelay(10);
71 		i--;
72 	}
73 
74 	spin_unlock_irqrestore(&local->cmdlock, flags);
75 
76 	if (i == 0) {
77 		printk("prism2_enable_aux_port(%d) timed out\n",
78 		       enable);
79 		return -ETIMEDOUT;
80 	}
81 
82 	return 0;
83 }
84 
85 
hfa384x_from_aux(struct net_device * dev,unsigned int addr,int len,void * buf)86 static int hfa384x_from_aux(struct net_device *dev, unsigned int addr, int len,
87 			    void *buf)
88 {
89 	u16 page, offset;
90 	if (addr & 1 || len & 1)
91 		return -1;
92 
93 	page = addr >> 7;
94 	offset = addr & 0x7f;
95 
96 	HFA384X_OUTW(page, HFA384X_AUXPAGE_OFF);
97 	HFA384X_OUTW(offset, HFA384X_AUXOFFSET_OFF);
98 
99 	udelay(5);
100 
101 #ifdef PRISM2_PCI
102 	{
103 		__le16 *pos = (__le16 *) buf;
104 		while (len > 0) {
105 			*pos++ = HFA384X_INW_DATA(HFA384X_AUXDATA_OFF);
106 			len -= 2;
107 		}
108 	}
109 #else /* PRISM2_PCI */
110 	HFA384X_INSW(HFA384X_AUXDATA_OFF, buf, len / 2);
111 #endif /* PRISM2_PCI */
112 
113 	return 0;
114 }
115 
116 
hfa384x_to_aux(struct net_device * dev,unsigned int addr,int len,void * buf)117 static int hfa384x_to_aux(struct net_device *dev, unsigned int addr, int len,
118 			  void *buf)
119 {
120 	u16 page, offset;
121 	if (addr & 1 || len & 1)
122 		return -1;
123 
124 	page = addr >> 7;
125 	offset = addr & 0x7f;
126 
127 	HFA384X_OUTW(page, HFA384X_AUXPAGE_OFF);
128 	HFA384X_OUTW(offset, HFA384X_AUXOFFSET_OFF);
129 
130 	udelay(5);
131 
132 #ifdef PRISM2_PCI
133 	{
134 		__le16 *pos = (__le16 *) buf;
135 		while (len > 0) {
136 			HFA384X_OUTW_DATA(*pos++, HFA384X_AUXDATA_OFF);
137 			len -= 2;
138 		}
139 	}
140 #else /* PRISM2_PCI */
141 	HFA384X_OUTSW(HFA384X_AUXDATA_OFF, buf, len / 2);
142 #endif /* PRISM2_PCI */
143 
144 	return 0;
145 }
146 
147 
prism2_pda_ok(u8 * buf)148 static int prism2_pda_ok(u8 *buf)
149 {
150 	__le16 *pda = (__le16 *) buf;
151 	int pos;
152 	u16 len, pdr;
153 
154 	if (buf[0] == 0xff && buf[1] == 0x00 && buf[2] == 0xff &&
155 	    buf[3] == 0x00)
156 		return 0;
157 
158 	pos = 0;
159 	while (pos + 1 < PRISM2_PDA_SIZE / 2) {
160 		len = le16_to_cpu(pda[pos]);
161 		pdr = le16_to_cpu(pda[pos + 1]);
162 		if (len == 0 || pos + len > PRISM2_PDA_SIZE / 2)
163 			return 0;
164 
165 		if (pdr == 0x0000 && len == 2) {
166 			/* PDA end found */
167 			return 1;
168 		}
169 
170 		pos += len + 1;
171 	}
172 
173 	return 0;
174 }
175 
176 
prism2_download_aux_dump(struct net_device * dev,unsigned int addr,int len,u8 * buf)177 static int prism2_download_aux_dump(struct net_device *dev,
178 				     unsigned int addr, int len, u8 *buf)
179 {
180 	int res;
181 
182 	prism2_enable_aux_port(dev, 1);
183 	res = hfa384x_from_aux(dev, addr, len, buf);
184 	prism2_enable_aux_port(dev, 0);
185 	if (res)
186 		return -1;
187 
188 	return 0;
189 }
190 
191 
prism2_read_pda(struct net_device * dev)192 static u8 * prism2_read_pda(struct net_device *dev)
193 {
194 	u8 *buf;
195 	int res, i, found = 0;
196 #define NUM_PDA_ADDRS 4
197 	unsigned int pda_addr[NUM_PDA_ADDRS] = {
198 		0x7f0000 /* others than HFA3841 */,
199 		0x3f0000 /* HFA3841 */,
200 		0x390000 /* apparently used in older cards */,
201 		0x7f0002 /* Intel PRO/Wireless 2011B (PCI) */,
202 	};
203 
204 	buf = kmalloc(PRISM2_PDA_SIZE, GFP_KERNEL);
205 	if (buf == NULL)
206 		return NULL;
207 
208 	/* Note: wlan card should be in initial state (just after init cmd)
209 	 * and no other operations should be performed concurrently. */
210 
211 	prism2_enable_aux_port(dev, 1);
212 
213 	for (i = 0; i < NUM_PDA_ADDRS; i++) {
214 		PDEBUG(DEBUG_EXTRA2, "%s: trying to read PDA from 0x%08x",
215 		       dev->name, pda_addr[i]);
216 		res = hfa384x_from_aux(dev, pda_addr[i], PRISM2_PDA_SIZE, buf);
217 		if (res)
218 			continue;
219 		if (res == 0 && prism2_pda_ok(buf)) {
220 			PDEBUG2(DEBUG_EXTRA2, ": OK\n");
221 			found = 1;
222 			break;
223 		} else {
224 			PDEBUG2(DEBUG_EXTRA2, ": failed\n");
225 		}
226 	}
227 
228 	prism2_enable_aux_port(dev, 0);
229 
230 	if (!found) {
231 		printk(KERN_DEBUG "%s: valid PDA not found\n", dev->name);
232 		kfree(buf);
233 		buf = NULL;
234 	}
235 
236 	return buf;
237 }
238 
239 
prism2_download_volatile(local_info_t * local,struct prism2_download_data * param)240 static int prism2_download_volatile(local_info_t *local,
241 				    struct prism2_download_data *param)
242 {
243 	struct net_device *dev = local->dev;
244 	int ret = 0, i;
245 	u16 param0, param1;
246 
247 	if (local->hw_downloading) {
248 		printk(KERN_WARNING "%s: Already downloading - aborting new "
249 		       "request\n", dev->name);
250 		return -1;
251 	}
252 
253 	local->hw_downloading = 1;
254 	if (local->pri_only) {
255 		hfa384x_disable_interrupts(dev);
256 	} else {
257 		prism2_hw_shutdown(dev, 0);
258 
259 		if (prism2_hw_init(dev, 0)) {
260 			printk(KERN_WARNING "%s: Could not initialize card for"
261 			       " download\n", dev->name);
262 			ret = -1;
263 			goto out;
264 		}
265 	}
266 
267 	if (prism2_enable_aux_port(dev, 1)) {
268 		printk(KERN_WARNING "%s: Could not enable AUX port\n",
269 		       dev->name);
270 		ret = -1;
271 		goto out;
272 	}
273 
274 	param0 = param->start_addr & 0xffff;
275 	param1 = param->start_addr >> 16;
276 
277 	HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
278 	HFA384X_OUTW(param1, HFA384X_PARAM1_OFF);
279 	if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
280 			     (HFA384X_PROGMODE_ENABLE_VOLATILE << 8),
281 			     param0)) {
282 		printk(KERN_WARNING "%s: Download command execution failed\n",
283 		       dev->name);
284 		ret = -1;
285 		goto out;
286 	}
287 
288 	for (i = 0; i < param->num_areas; i++) {
289 		PDEBUG(DEBUG_EXTRA2, "%s: Writing %d bytes at 0x%08x\n",
290 		       dev->name, param->data[i].len, param->data[i].addr);
291 		if (hfa384x_to_aux(dev, param->data[i].addr,
292 				   param->data[i].len, param->data[i].data)) {
293 			printk(KERN_WARNING "%s: RAM download at 0x%08x "
294 			       "(len=%d) failed\n", dev->name,
295 			       param->data[i].addr, param->data[i].len);
296 			ret = -1;
297 			goto out;
298 		}
299 	}
300 
301 	HFA384X_OUTW(param1, HFA384X_PARAM1_OFF);
302 	HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
303 	if (hfa384x_cmd_no_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
304 				(HFA384X_PROGMODE_DISABLE << 8), param0)) {
305 		printk(KERN_WARNING "%s: Download command execution failed\n",
306 		       dev->name);
307 		ret = -1;
308 		goto out;
309 	}
310 	/* ProgMode disable causes the hardware to restart itself from the
311 	 * given starting address. Give hw some time and ACK command just in
312 	 * case restart did not happen. */
313 	mdelay(5);
314 	HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_EVACK_OFF);
315 
316 	if (prism2_enable_aux_port(dev, 0)) {
317 		printk(KERN_DEBUG "%s: Disabling AUX port failed\n",
318 		       dev->name);
319 		/* continue anyway.. restart should have taken care of this */
320 	}
321 
322 	mdelay(5);
323 	local->hw_downloading = 0;
324 	if (prism2_hw_config(dev, 2)) {
325 		printk(KERN_WARNING "%s: Card configuration after RAM "
326 		       "download failed\n", dev->name);
327 		ret = -1;
328 		goto out;
329 	}
330 
331  out:
332 	local->hw_downloading = 0;
333 	return ret;
334 }
335 
336 
prism2_enable_genesis(local_info_t * local,int hcr)337 static int prism2_enable_genesis(local_info_t *local, int hcr)
338 {
339 	struct net_device *dev = local->dev;
340 	u8 initseq[4] = { 0x00, 0xe1, 0xa1, 0xff };
341 	u8 readbuf[4];
342 
343 	printk(KERN_DEBUG "%s: test Genesis mode with HCR 0x%02x\n",
344 	       dev->name, hcr);
345 	local->func->cor_sreset(local);
346 	hfa384x_to_aux(dev, 0x7e0038, sizeof(initseq), initseq);
347 	local->func->genesis_reset(local, hcr);
348 
349 	/* Readback test */
350 	hfa384x_from_aux(dev, 0x7e0038, sizeof(readbuf), readbuf);
351 	hfa384x_to_aux(dev, 0x7e0038, sizeof(initseq), initseq);
352 	hfa384x_from_aux(dev, 0x7e0038, sizeof(readbuf), readbuf);
353 
354 	if (memcmp(initseq, readbuf, sizeof(initseq)) == 0) {
355 		printk(KERN_DEBUG "Readback test succeeded, HCR 0x%02x\n",
356 		       hcr);
357 		return 0;
358 	} else {
359 		printk(KERN_DEBUG "Readback test failed, HCR 0x%02x "
360 		       "write %02x %02x %02x %02x read %02x %02x %02x %02x\n",
361 		       hcr, initseq[0], initseq[1], initseq[2], initseq[3],
362 		       readbuf[0], readbuf[1], readbuf[2], readbuf[3]);
363 		return 1;
364 	}
365 }
366 
367 
prism2_get_ram_size(local_info_t * local)368 static int prism2_get_ram_size(local_info_t *local)
369 {
370 	int ret;
371 
372 	/* Try to enable genesis mode; 0x1F for x8 SRAM or 0x0F for x16 SRAM */
373 	if (prism2_enable_genesis(local, 0x1f) == 0)
374 		ret = 8;
375 	else if (prism2_enable_genesis(local, 0x0f) == 0)
376 		ret = 16;
377 	else
378 		ret = -1;
379 
380 	/* Disable genesis mode */
381 	local->func->genesis_reset(local, ret == 16 ? 0x07 : 0x17);
382 
383 	return ret;
384 }
385 
386 
prism2_download_genesis(local_info_t * local,struct prism2_download_data * param)387 static int prism2_download_genesis(local_info_t *local,
388 				   struct prism2_download_data *param)
389 {
390 	struct net_device *dev = local->dev;
391 	int ram16 = 0, i;
392 	int ret = 0;
393 
394 	if (local->hw_downloading) {
395 		printk(KERN_WARNING "%s: Already downloading - aborting new "
396 		       "request\n", dev->name);
397 		return -EBUSY;
398 	}
399 
400 	if (!local->func->genesis_reset || !local->func->cor_sreset) {
401 		printk(KERN_INFO "%s: Genesis mode downloading not supported "
402 		       "with this hwmodel\n", dev->name);
403 		return -EOPNOTSUPP;
404 	}
405 
406 	local->hw_downloading = 1;
407 
408 	if (prism2_enable_aux_port(dev, 1)) {
409 		printk(KERN_DEBUG "%s: failed to enable AUX port\n",
410 		       dev->name);
411 		ret = -EIO;
412 		goto out;
413 	}
414 
415 	if (local->sram_type == -1) {
416 		/* 0x1F for x8 SRAM or 0x0F for x16 SRAM */
417 		if (prism2_enable_genesis(local, 0x1f) == 0) {
418 			ram16 = 0;
419 			PDEBUG(DEBUG_EXTRA2, "%s: Genesis mode OK using x8 "
420 			       "SRAM\n", dev->name);
421 		} else if (prism2_enable_genesis(local, 0x0f) == 0) {
422 			ram16 = 1;
423 			PDEBUG(DEBUG_EXTRA2, "%s: Genesis mode OK using x16 "
424 			       "SRAM\n", dev->name);
425 		} else {
426 			printk(KERN_DEBUG "%s: Could not initiate genesis "
427 			       "mode\n", dev->name);
428 			ret = -EIO;
429 			goto out;
430 		}
431 	} else {
432 		if (prism2_enable_genesis(local, local->sram_type == 8 ?
433 					  0x1f : 0x0f)) {
434 			printk(KERN_DEBUG "%s: Failed to set Genesis "
435 			       "mode (sram_type=%d)\n", dev->name,
436 			       local->sram_type);
437 			ret = -EIO;
438 			goto out;
439 		}
440 		ram16 = local->sram_type != 8;
441 	}
442 
443 	for (i = 0; i < param->num_areas; i++) {
444 		PDEBUG(DEBUG_EXTRA2, "%s: Writing %d bytes at 0x%08x\n",
445 		       dev->name, param->data[i].len, param->data[i].addr);
446 		if (hfa384x_to_aux(dev, param->data[i].addr,
447 				   param->data[i].len, param->data[i].data)) {
448 			printk(KERN_WARNING "%s: RAM download at 0x%08x "
449 			       "(len=%d) failed\n", dev->name,
450 			       param->data[i].addr, param->data[i].len);
451 			ret = -EIO;
452 			goto out;
453 		}
454 	}
455 
456 	PDEBUG(DEBUG_EXTRA2, "Disable genesis mode\n");
457 	local->func->genesis_reset(local, ram16 ? 0x07 : 0x17);
458 	if (prism2_enable_aux_port(dev, 0)) {
459 		printk(KERN_DEBUG "%s: Failed to disable AUX port\n",
460 		       dev->name);
461 	}
462 
463 	mdelay(5);
464 	local->hw_downloading = 0;
465 
466 	PDEBUG(DEBUG_EXTRA2, "Trying to initialize card\n");
467 	/*
468 	 * Make sure the INIT command does not generate a command completion
469 	 * event by disabling interrupts.
470 	 */
471 	hfa384x_disable_interrupts(dev);
472 	if (prism2_hw_init(dev, 1)) {
473 		printk(KERN_DEBUG "%s: Initialization after genesis mode "
474 		       "download failed\n", dev->name);
475 		ret = -EIO;
476 		goto out;
477 	}
478 
479 	PDEBUG(DEBUG_EXTRA2, "Card initialized - running PRI only\n");
480 	if (prism2_hw_init2(dev, 1)) {
481 		printk(KERN_DEBUG "%s: Initialization(2) after genesis mode "
482 		       "download failed\n", dev->name);
483 		ret = -EIO;
484 		goto out;
485 	}
486 
487  out:
488 	local->hw_downloading = 0;
489 	return ret;
490 }
491 
492 
493 #ifdef PRISM2_NON_VOLATILE_DOWNLOAD
494 /* Note! Non-volatile downloading functionality has not yet been tested
495  * thoroughly and it may corrupt flash image and effectively kill the card that
496  * is being updated. You have been warned. */
497 
prism2_download_block(struct net_device * dev,u32 addr,u8 * data,u32 bufaddr,int rest_len)498 static inline int prism2_download_block(struct net_device *dev,
499 					u32 addr, u8 *data,
500 					u32 bufaddr, int rest_len)
501 {
502 	u16 param0, param1;
503 	int block_len;
504 
505 	block_len = rest_len < 4096 ? rest_len : 4096;
506 
507 	param0 = addr & 0xffff;
508 	param1 = addr >> 16;
509 
510 	HFA384X_OUTW(block_len, HFA384X_PARAM2_OFF);
511 	HFA384X_OUTW(param1, HFA384X_PARAM1_OFF);
512 
513 	if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
514 			     (HFA384X_PROGMODE_ENABLE_NON_VOLATILE << 8),
515 			     param0)) {
516 		printk(KERN_WARNING "%s: Flash download command execution "
517 		       "failed\n", dev->name);
518 		return -1;
519 	}
520 
521 	if (hfa384x_to_aux(dev, bufaddr, block_len, data)) {
522 		printk(KERN_WARNING "%s: flash download at 0x%08x "
523 		       "(len=%d) failed\n", dev->name, addr, block_len);
524 		return -1;
525 	}
526 
527 	HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
528 	HFA384X_OUTW(0, HFA384X_PARAM1_OFF);
529 	if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
530 			     (HFA384X_PROGMODE_PROGRAM_NON_VOLATILE << 8),
531 			     0)) {
532 		printk(KERN_WARNING "%s: Flash write command execution "
533 		       "failed\n", dev->name);
534 		return -1;
535 	}
536 
537 	return block_len;
538 }
539 
540 
prism2_download_nonvolatile(local_info_t * local,struct prism2_download_data * dl)541 static int prism2_download_nonvolatile(local_info_t *local,
542 				       struct prism2_download_data *dl)
543 {
544 	struct net_device *dev = local->dev;
545 	int ret = 0, i;
546 	struct {
547 		__le16 page;
548 		__le16 offset;
549 		__le16 len;
550 	} dlbuffer;
551 	u32 bufaddr;
552 
553 	if (local->hw_downloading) {
554 		printk(KERN_WARNING "%s: Already downloading - aborting new "
555 		       "request\n", dev->name);
556 		return -1;
557 	}
558 
559 	ret = local->func->get_rid(dev, HFA384X_RID_DOWNLOADBUFFER,
560 				   &dlbuffer, 6, 0);
561 
562 	if (ret < 0) {
563 		printk(KERN_WARNING "%s: Could not read download buffer "
564 		       "parameters\n", dev->name);
565 		goto out;
566 	}
567 
568 	printk(KERN_DEBUG "Download buffer: %d bytes at 0x%04x:0x%04x\n",
569 	       le16_to_cpu(dlbuffer.len),
570 	       le16_to_cpu(dlbuffer.page),
571 	       le16_to_cpu(dlbuffer.offset));
572 
573 	bufaddr = (le16_to_cpu(dlbuffer.page) << 7) + le16_to_cpu(dlbuffer.offset);
574 
575 	local->hw_downloading = 1;
576 
577 	if (!local->pri_only) {
578 		prism2_hw_shutdown(dev, 0);
579 
580 		if (prism2_hw_init(dev, 0)) {
581 			printk(KERN_WARNING "%s: Could not initialize card for"
582 			       " download\n", dev->name);
583 			ret = -1;
584 			goto out;
585 		}
586 	}
587 
588 	hfa384x_disable_interrupts(dev);
589 
590 	if (prism2_enable_aux_port(dev, 1)) {
591 		printk(KERN_WARNING "%s: Could not enable AUX port\n",
592 		       dev->name);
593 		ret = -1;
594 		goto out;
595 	}
596 
597 	printk(KERN_DEBUG "%s: starting flash download\n", dev->name);
598 	for (i = 0; i < dl->num_areas; i++) {
599 		int rest_len = dl->data[i].len;
600 		int data_off = 0;
601 
602 		while (rest_len > 0) {
603 			int block_len;
604 
605 			block_len = prism2_download_block(
606 				dev, dl->data[i].addr + data_off,
607 				dl->data[i].data + data_off, bufaddr,
608 				rest_len);
609 
610 			if (block_len < 0) {
611 				ret = -1;
612 				goto out;
613 			}
614 
615 			rest_len -= block_len;
616 			data_off += block_len;
617 		}
618 	}
619 
620 	HFA384X_OUTW(0, HFA384X_PARAM1_OFF);
621 	HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
622 	if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
623 				(HFA384X_PROGMODE_DISABLE << 8), 0)) {
624 		printk(KERN_WARNING "%s: Download command execution failed\n",
625 		       dev->name);
626 		ret = -1;
627 		goto out;
628 	}
629 
630 	if (prism2_enable_aux_port(dev, 0)) {
631 		printk(KERN_DEBUG "%s: Disabling AUX port failed\n",
632 		       dev->name);
633 		/* continue anyway.. restart should have taken care of this */
634 	}
635 
636 	mdelay(5);
637 
638 	local->func->hw_reset(dev);
639 	local->hw_downloading = 0;
640 	if (prism2_hw_config(dev, 2)) {
641 		printk(KERN_WARNING "%s: Card configuration after flash "
642 		       "download failed\n", dev->name);
643 		ret = -1;
644 	} else {
645 		printk(KERN_INFO "%s: Card initialized successfully after "
646 		       "flash download\n", dev->name);
647 	}
648 
649  out:
650 	local->hw_downloading = 0;
651 	return ret;
652 }
653 #endif /* PRISM2_NON_VOLATILE_DOWNLOAD */
654 
655 
prism2_download_free_data(struct prism2_download_data * dl)656 static void prism2_download_free_data(struct prism2_download_data *dl)
657 {
658 	int i;
659 
660 	if (dl == NULL)
661 		return;
662 
663 	for (i = 0; i < dl->num_areas; i++)
664 		kfree(dl->data[i].data);
665 	kfree(dl);
666 }
667 
668 
prism2_download(local_info_t * local,struct prism2_download_param * param)669 static int prism2_download(local_info_t *local,
670 			   struct prism2_download_param *param)
671 {
672 	int ret = 0;
673 	int i;
674 	u32 total_len = 0;
675 	struct prism2_download_data *dl = NULL;
676 
677 	printk(KERN_DEBUG "prism2_download: dl_cmd=%d start_addr=0x%08x "
678 	       "num_areas=%d\n",
679 	       param->dl_cmd, param->start_addr, param->num_areas);
680 
681 	if (param->num_areas > 100) {
682 		ret = -EINVAL;
683 		goto out;
684 	}
685 
686 	dl = kzalloc(sizeof(*dl) + param->num_areas *
687 		     sizeof(struct prism2_download_data_area), GFP_KERNEL);
688 	if (dl == NULL) {
689 		ret = -ENOMEM;
690 		goto out;
691 	}
692 	dl->dl_cmd = param->dl_cmd;
693 	dl->start_addr = param->start_addr;
694 	dl->num_areas = param->num_areas;
695 	for (i = 0; i < param->num_areas; i++) {
696 		PDEBUG(DEBUG_EXTRA2,
697 		       "  area %d: addr=0x%08x len=%d ptr=0x%p\n",
698 		       i, param->data[i].addr, param->data[i].len,
699 		       param->data[i].ptr);
700 
701 		dl->data[i].addr = param->data[i].addr;
702 		dl->data[i].len = param->data[i].len;
703 
704 		total_len += param->data[i].len;
705 		if (param->data[i].len > PRISM2_MAX_DOWNLOAD_AREA_LEN ||
706 		    total_len > PRISM2_MAX_DOWNLOAD_LEN) {
707 			ret = -E2BIG;
708 			goto out;
709 		}
710 
711 		dl->data[i].data = kmalloc(dl->data[i].len, GFP_KERNEL);
712 		if (dl->data[i].data == NULL) {
713 			ret = -ENOMEM;
714 			goto out;
715 		}
716 
717 		if (copy_from_user(dl->data[i].data, param->data[i].ptr,
718 				   param->data[i].len)) {
719 			ret = -EFAULT;
720 			goto out;
721 		}
722 	}
723 
724 	switch (param->dl_cmd) {
725 	case PRISM2_DOWNLOAD_VOLATILE:
726 	case PRISM2_DOWNLOAD_VOLATILE_PERSISTENT:
727 		ret = prism2_download_volatile(local, dl);
728 		break;
729 	case PRISM2_DOWNLOAD_VOLATILE_GENESIS:
730 	case PRISM2_DOWNLOAD_VOLATILE_GENESIS_PERSISTENT:
731 		ret = prism2_download_genesis(local, dl);
732 		break;
733 	case PRISM2_DOWNLOAD_NON_VOLATILE:
734 #ifdef PRISM2_NON_VOLATILE_DOWNLOAD
735 		ret = prism2_download_nonvolatile(local, dl);
736 #else /* PRISM2_NON_VOLATILE_DOWNLOAD */
737 		printk(KERN_INFO "%s: non-volatile downloading not enabled\n",
738 		       local->dev->name);
739 		ret = -EOPNOTSUPP;
740 #endif /* PRISM2_NON_VOLATILE_DOWNLOAD */
741 		break;
742 	default:
743 		printk(KERN_DEBUG "%s: unsupported download command %d\n",
744 		       local->dev->name, param->dl_cmd);
745 		ret = -EINVAL;
746 		break;
747 	}
748 
749  out:
750 	if (ret == 0 && dl &&
751 	    param->dl_cmd == PRISM2_DOWNLOAD_VOLATILE_GENESIS_PERSISTENT) {
752 		prism2_download_free_data(local->dl_pri);
753 		local->dl_pri = dl;
754 	} else if (ret == 0 && dl &&
755 		   param->dl_cmd == PRISM2_DOWNLOAD_VOLATILE_PERSISTENT) {
756 		prism2_download_free_data(local->dl_sec);
757 		local->dl_sec = dl;
758 	} else
759 		prism2_download_free_data(dl);
760 
761 	return ret;
762 }
763