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