Linux Audio

Check our new training course

Loading...
v4.17
  1// SPDX-License-Identifier: GPL-2.0
  2static 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
 87static 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
118static 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
149static 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
180struct prism2_download_aux_dump {
181	local_info_t *local;
182	u16 page[0x80];
183};
184
185static 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
194static 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
203static 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
211static 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
217static 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
224static 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
235static const struct file_operations prism2_download_aux_dump_proc_fops = {
236	.open		= prism2_download_aux_dump_proc_open,
237	.read		= seq_read,
238	.llseek		= seq_lseek,
239	.release	= seq_release_private,
240};
241
242
243static 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
291static 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
388static 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 "
411		       "write %02x %02x %02x %02x read %02x %02x %02x %02x\n",
412		       hcr, initseq[0], initseq[1], initseq[2], initseq[3],
413		       readbuf[0], readbuf[1], readbuf[2], readbuf[3]);
414		return 1;
415	}
416}
417
418
419static int prism2_get_ram_size(local_info_t *local)
420{
421	int ret;
422
423	/* Try to enable genesis mode; 0x1F for x8 SRAM or 0x0F for x16 SRAM */
424	if (prism2_enable_genesis(local, 0x1f) == 0)
425		ret = 8;
426	else if (prism2_enable_genesis(local, 0x0f) == 0)
427		ret = 16;
428	else
429		ret = -1;
430
431	/* Disable genesis mode */
432	local->func->genesis_reset(local, ret == 16 ? 0x07 : 0x17);
433
434	return ret;
435}
436
437
438static int prism2_download_genesis(local_info_t *local,
439				   struct prism2_download_data *param)
440{
441	struct net_device *dev = local->dev;
442	int ram16 = 0, i;
443	int ret = 0;
444
445	if (local->hw_downloading) {
446		printk(KERN_WARNING "%s: Already downloading - aborting new "
447		       "request\n", dev->name);
448		return -EBUSY;
449	}
450
451	if (!local->func->genesis_reset || !local->func->cor_sreset) {
452		printk(KERN_INFO "%s: Genesis mode downloading not supported "
453		       "with this hwmodel\n", dev->name);
454		return -EOPNOTSUPP;
455	}
456
457	local->hw_downloading = 1;
458
459	if (prism2_enable_aux_port(dev, 1)) {
460		printk(KERN_DEBUG "%s: failed to enable AUX port\n",
461		       dev->name);
462		ret = -EIO;
463		goto out;
464	}
465
466	if (local->sram_type == -1) {
467		/* 0x1F for x8 SRAM or 0x0F for x16 SRAM */
468		if (prism2_enable_genesis(local, 0x1f) == 0) {
469			ram16 = 0;
470			PDEBUG(DEBUG_EXTRA2, "%s: Genesis mode OK using x8 "
471			       "SRAM\n", dev->name);
472		} else if (prism2_enable_genesis(local, 0x0f) == 0) {
473			ram16 = 1;
474			PDEBUG(DEBUG_EXTRA2, "%s: Genesis mode OK using x16 "
475			       "SRAM\n", dev->name);
476		} else {
477			printk(KERN_DEBUG "%s: Could not initiate genesis "
478			       "mode\n", dev->name);
479			ret = -EIO;
480			goto out;
481		}
482	} else {
483		if (prism2_enable_genesis(local, local->sram_type == 8 ?
484					  0x1f : 0x0f)) {
485			printk(KERN_DEBUG "%s: Failed to set Genesis "
486			       "mode (sram_type=%d)\n", dev->name,
487			       local->sram_type);
488			ret = -EIO;
489			goto out;
490		}
491		ram16 = local->sram_type != 8;
492	}
493
494	for (i = 0; i < param->num_areas; i++) {
495		PDEBUG(DEBUG_EXTRA2, "%s: Writing %d bytes at 0x%08x\n",
496		       dev->name, param->data[i].len, param->data[i].addr);
497		if (hfa384x_to_aux(dev, param->data[i].addr,
498				   param->data[i].len, param->data[i].data)) {
499			printk(KERN_WARNING "%s: RAM download at 0x%08x "
500			       "(len=%d) failed\n", dev->name,
501			       param->data[i].addr, param->data[i].len);
502			ret = -EIO;
503			goto out;
504		}
505	}
506
507	PDEBUG(DEBUG_EXTRA2, "Disable genesis mode\n");
508	local->func->genesis_reset(local, ram16 ? 0x07 : 0x17);
509	if (prism2_enable_aux_port(dev, 0)) {
510		printk(KERN_DEBUG "%s: Failed to disable AUX port\n",
511		       dev->name);
512	}
513
514	mdelay(5);
515	local->hw_downloading = 0;
516
517	PDEBUG(DEBUG_EXTRA2, "Trying to initialize card\n");
518	/*
519	 * Make sure the INIT command does not generate a command completion
520	 * event by disabling interrupts.
521	 */
522	hfa384x_disable_interrupts(dev);
523	if (prism2_hw_init(dev, 1)) {
524		printk(KERN_DEBUG "%s: Initialization after genesis mode "
525		       "download failed\n", dev->name);
526		ret = -EIO;
527		goto out;
528	}
529
530	PDEBUG(DEBUG_EXTRA2, "Card initialized - running PRI only\n");
531	if (prism2_hw_init2(dev, 1)) {
532		printk(KERN_DEBUG "%s: Initialization(2) after genesis mode "
533		       "download failed\n", dev->name);
534		ret = -EIO;
535		goto out;
536	}
537
538 out:
539	local->hw_downloading = 0;
540	return ret;
541}
542
543
544#ifdef PRISM2_NON_VOLATILE_DOWNLOAD
545/* Note! Non-volatile downloading functionality has not yet been tested
546 * thoroughly and it may corrupt flash image and effectively kill the card that
547 * is being updated. You have been warned. */
548
549static inline int prism2_download_block(struct net_device *dev,
550					u32 addr, u8 *data,
551					u32 bufaddr, int rest_len)
552{
553	u16 param0, param1;
554	int block_len;
555
556	block_len = rest_len < 4096 ? rest_len : 4096;
557
558	param0 = addr & 0xffff;
559	param1 = addr >> 16;
560
561	HFA384X_OUTW(block_len, HFA384X_PARAM2_OFF);
562	HFA384X_OUTW(param1, HFA384X_PARAM1_OFF);
563
564	if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
565			     (HFA384X_PROGMODE_ENABLE_NON_VOLATILE << 8),
566			     param0)) {
567		printk(KERN_WARNING "%s: Flash download command execution "
568		       "failed\n", dev->name);
569		return -1;
570	}
571
572	if (hfa384x_to_aux(dev, bufaddr, block_len, data)) {
573		printk(KERN_WARNING "%s: flash download at 0x%08x "
574		       "(len=%d) failed\n", dev->name, addr, block_len);
575		return -1;
576	}
577
578	HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
579	HFA384X_OUTW(0, HFA384X_PARAM1_OFF);
580	if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
581			     (HFA384X_PROGMODE_PROGRAM_NON_VOLATILE << 8),
582			     0)) {
583		printk(KERN_WARNING "%s: Flash write command execution "
584		       "failed\n", dev->name);
585		return -1;
586	}
587
588	return block_len;
589}
590
591
592static int prism2_download_nonvolatile(local_info_t *local,
593				       struct prism2_download_data *dl)
594{
595	struct net_device *dev = local->dev;
596	int ret = 0, i;
597	struct {
598		__le16 page;
599		__le16 offset;
600		__le16 len;
601	} dlbuffer;
602	u32 bufaddr;
603
604	if (local->hw_downloading) {
605		printk(KERN_WARNING "%s: Already downloading - aborting new "
606		       "request\n", dev->name);
607		return -1;
608	}
609
610	ret = local->func->get_rid(dev, HFA384X_RID_DOWNLOADBUFFER,
611				   &dlbuffer, 6, 0);
612
613	if (ret < 0) {
614		printk(KERN_WARNING "%s: Could not read download buffer "
615		       "parameters\n", dev->name);
616		goto out;
617	}
618
619	printk(KERN_DEBUG "Download buffer: %d bytes at 0x%04x:0x%04x\n",
620	       le16_to_cpu(dlbuffer.len),
621	       le16_to_cpu(dlbuffer.page),
622	       le16_to_cpu(dlbuffer.offset));
623
624	bufaddr = (le16_to_cpu(dlbuffer.page) << 7) + le16_to_cpu(dlbuffer.offset);
625
626	local->hw_downloading = 1;
627
628	if (!local->pri_only) {
629		prism2_hw_shutdown(dev, 0);
630
631		if (prism2_hw_init(dev, 0)) {
632			printk(KERN_WARNING "%s: Could not initialize card for"
633			       " download\n", dev->name);
634			ret = -1;
635			goto out;
636		}
637	}
638
639	hfa384x_disable_interrupts(dev);
640
641	if (prism2_enable_aux_port(dev, 1)) {
642		printk(KERN_WARNING "%s: Could not enable AUX port\n",
643		       dev->name);
644		ret = -1;
645		goto out;
646	}
647
648	printk(KERN_DEBUG "%s: starting flash download\n", dev->name);
649	for (i = 0; i < dl->num_areas; i++) {
650		int rest_len = dl->data[i].len;
651		int data_off = 0;
652
653		while (rest_len > 0) {
654			int block_len;
655
656			block_len = prism2_download_block(
657				dev, dl->data[i].addr + data_off,
658				dl->data[i].data + data_off, bufaddr,
659				rest_len);
660
661			if (block_len < 0) {
662				ret = -1;
663				goto out;
664			}
665
666			rest_len -= block_len;
667			data_off += block_len;
668		}
669	}
670
671	HFA384X_OUTW(0, HFA384X_PARAM1_OFF);
672	HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
673	if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
674				(HFA384X_PROGMODE_DISABLE << 8), 0)) {
675		printk(KERN_WARNING "%s: Download command execution failed\n",
676		       dev->name);
677		ret = -1;
678		goto out;
679	}
680
681	if (prism2_enable_aux_port(dev, 0)) {
682		printk(KERN_DEBUG "%s: Disabling AUX port failed\n",
683		       dev->name);
684		/* continue anyway.. restart should have taken care of this */
685	}
686
687	mdelay(5);
688
689	local->func->hw_reset(dev);
690	local->hw_downloading = 0;
691	if (prism2_hw_config(dev, 2)) {
692		printk(KERN_WARNING "%s: Card configuration after flash "
693		       "download failed\n", dev->name);
694		ret = -1;
695	} else {
696		printk(KERN_INFO "%s: Card initialized successfully after "
697		       "flash download\n", dev->name);
698	}
699
700 out:
701	local->hw_downloading = 0;
702	return ret;
703}
704#endif /* PRISM2_NON_VOLATILE_DOWNLOAD */
705
706
707static void prism2_download_free_data(struct prism2_download_data *dl)
708{
709	int i;
710
711	if (dl == NULL)
712		return;
713
714	for (i = 0; i < dl->num_areas; i++)
715		kfree(dl->data[i].data);
716	kfree(dl);
717}
718
719
720static int prism2_download(local_info_t *local,
721			   struct prism2_download_param *param)
722{
723	int ret = 0;
724	int i;
725	u32 total_len = 0;
726	struct prism2_download_data *dl = NULL;
727
728	printk(KERN_DEBUG "prism2_download: dl_cmd=%d start_addr=0x%08x "
729	       "num_areas=%d\n",
730	       param->dl_cmd, param->start_addr, param->num_areas);
731
732	if (param->num_areas > 100) {
733		ret = -EINVAL;
734		goto out;
735	}
736
737	dl = kzalloc(sizeof(*dl) + param->num_areas *
738		     sizeof(struct prism2_download_data_area), GFP_KERNEL);
739	if (dl == NULL) {
740		ret = -ENOMEM;
741		goto out;
742	}
743	dl->dl_cmd = param->dl_cmd;
744	dl->start_addr = param->start_addr;
745	dl->num_areas = param->num_areas;
746	for (i = 0; i < param->num_areas; i++) {
747		PDEBUG(DEBUG_EXTRA2,
748		       "  area %d: addr=0x%08x len=%d ptr=0x%p\n",
749		       i, param->data[i].addr, param->data[i].len,
750		       param->data[i].ptr);
751
752		dl->data[i].addr = param->data[i].addr;
753		dl->data[i].len = param->data[i].len;
754
755		total_len += param->data[i].len;
756		if (param->data[i].len > PRISM2_MAX_DOWNLOAD_AREA_LEN ||
757		    total_len > PRISM2_MAX_DOWNLOAD_LEN) {
758			ret = -E2BIG;
759			goto out;
760		}
761
762		dl->data[i].data = kmalloc(dl->data[i].len, GFP_KERNEL);
763		if (dl->data[i].data == NULL) {
764			ret = -ENOMEM;
765			goto out;
766		}
767
768		if (copy_from_user(dl->data[i].data, param->data[i].ptr,
769				   param->data[i].len)) {
770			ret = -EFAULT;
771			goto out;
772		}
773	}
774
775	switch (param->dl_cmd) {
776	case PRISM2_DOWNLOAD_VOLATILE:
777	case PRISM2_DOWNLOAD_VOLATILE_PERSISTENT:
778		ret = prism2_download_volatile(local, dl);
779		break;
780	case PRISM2_DOWNLOAD_VOLATILE_GENESIS:
781	case PRISM2_DOWNLOAD_VOLATILE_GENESIS_PERSISTENT:
782		ret = prism2_download_genesis(local, dl);
783		break;
784	case PRISM2_DOWNLOAD_NON_VOLATILE:
785#ifdef PRISM2_NON_VOLATILE_DOWNLOAD
786		ret = prism2_download_nonvolatile(local, dl);
787#else /* PRISM2_NON_VOLATILE_DOWNLOAD */
788		printk(KERN_INFO "%s: non-volatile downloading not enabled\n",
789		       local->dev->name);
790		ret = -EOPNOTSUPP;
791#endif /* PRISM2_NON_VOLATILE_DOWNLOAD */
792		break;
793	default:
794		printk(KERN_DEBUG "%s: unsupported download command %d\n",
795		       local->dev->name, param->dl_cmd);
796		ret = -EINVAL;
797		break;
798	}
799
800 out:
801	if (ret == 0 && dl &&
802	    param->dl_cmd == PRISM2_DOWNLOAD_VOLATILE_GENESIS_PERSISTENT) {
803		prism2_download_free_data(local->dl_pri);
804		local->dl_pri = dl;
805	} else if (ret == 0 && dl &&
806		   param->dl_cmd == PRISM2_DOWNLOAD_VOLATILE_PERSISTENT) {
807		prism2_download_free_data(local->dl_sec);
808		local->dl_sec = dl;
809	} else
810		prism2_download_free_data(dl);
811
812	return ret;
813}
v5.4
  1// SPDX-License-Identifier: GPL-2.0
  2static 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
 87static 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
118static 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
149static 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
180struct prism2_download_aux_dump {
181	local_info_t *local;
182	u16 page[0x80];
183};
184
185static 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
194static 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
203static 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
211static 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
217static 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
224static 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
235static const struct file_operations prism2_download_aux_dump_proc_fops = {
236	.open		= prism2_download_aux_dump_proc_open,
237	.read		= seq_read,
238	.llseek		= seq_lseek,
239	.release	= seq_release_private,
240};
241
242
243static 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
291static 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
388static 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
417static 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
436static 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
547static 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
590static 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
705static 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
718static 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}