pcmcia.c revision 4c89e88bfde6a3c179790e21004f24e09a058290
1/*
2 * Sonics Silicon Backplane
3 * PCMCIA-Hostbus related functions
4 *
5 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
6 * Copyright 2007-2008 Michael Buesch <mb@bu3sch.de>
7 *
8 * Licensed under the GNU/GPL. See COPYING for details.
9 */
10
11#include <linux/ssb/ssb.h>
12#include <linux/delay.h>
13#include <linux/io.h>
14#include <linux/etherdevice.h>
15
16#include <pcmcia/cs_types.h>
17#include <pcmcia/cs.h>
18#include <pcmcia/cistpl.h>
19#include <pcmcia/ciscode.h>
20#include <pcmcia/ds.h>
21#include <pcmcia/cisreg.h>
22
23#include "ssb_private.h"
24
25
26/* Define the following to 1 to enable a printk on each coreswitch. */
27#define SSB_VERBOSE_PCMCIACORESWITCH_DEBUG		0
28
29
30/* PCMCIA configuration registers */
31#define SSB_PCMCIA_ADDRESS0		0x2E
32#define SSB_PCMCIA_ADDRESS1		0x30
33#define SSB_PCMCIA_ADDRESS2		0x32
34#define SSB_PCMCIA_MEMSEG		0x34
35#define SSB_PCMCIA_SPROMCTL		0x36
36#define  SSB_PCMCIA_SPROMCTL_IDLE	0
37#define  SSB_PCMCIA_SPROMCTL_WRITE	1
38#define  SSB_PCMCIA_SPROMCTL_READ	2
39#define  SSB_PCMCIA_SPROMCTL_WRITEEN	4
40#define  SSB_PCMCIA_SPROMCTL_WRITEDIS	7
41#define  SSB_PCMCIA_SPROMCTL_DONE	8
42#define SSB_PCMCIA_SPROM_DATALO		0x38
43#define SSB_PCMCIA_SPROM_DATAHI		0x3A
44#define SSB_PCMCIA_SPROM_ADDRLO		0x3C
45#define SSB_PCMCIA_SPROM_ADDRHI		0x3E
46
47/* Hardware invariants CIS tuples */
48#define SSB_PCMCIA_CIS			0x80
49#define  SSB_PCMCIA_CIS_ID		0x01
50#define  SSB_PCMCIA_CIS_BOARDREV	0x02
51#define  SSB_PCMCIA_CIS_PA		0x03
52#define   SSB_PCMCIA_CIS_PA_PA0B0_LO	0
53#define   SSB_PCMCIA_CIS_PA_PA0B0_HI	1
54#define   SSB_PCMCIA_CIS_PA_PA0B1_LO	2
55#define   SSB_PCMCIA_CIS_PA_PA0B1_HI	3
56#define   SSB_PCMCIA_CIS_PA_PA0B2_LO	4
57#define   SSB_PCMCIA_CIS_PA_PA0B2_HI	5
58#define   SSB_PCMCIA_CIS_PA_ITSSI	6
59#define   SSB_PCMCIA_CIS_PA_MAXPOW	7
60#define  SSB_PCMCIA_CIS_OEMNAME		0x04
61#define  SSB_PCMCIA_CIS_CCODE		0x05
62#define  SSB_PCMCIA_CIS_ANTENNA		0x06
63#define  SSB_PCMCIA_CIS_ANTGAIN		0x07
64#define  SSB_PCMCIA_CIS_BFLAGS		0x08
65#define  SSB_PCMCIA_CIS_LEDS		0x09
66
67/* PCMCIA SPROM size. */
68#define SSB_PCMCIA_SPROM_SIZE		256
69#define SSB_PCMCIA_SPROM_SIZE_BYTES	(SSB_PCMCIA_SPROM_SIZE * sizeof(u16))
70
71
72/* Write to a PCMCIA configuration register. */
73static int ssb_pcmcia_cfg_write(struct ssb_bus *bus, u8 offset, u8 value)
74{
75	conf_reg_t reg;
76	int res;
77
78	memset(&reg, 0, sizeof(reg));
79	reg.Offset = offset;
80	reg.Action = CS_WRITE;
81	reg.Value = value;
82	res = pcmcia_access_configuration_register(bus->host_pcmcia, &reg);
83	if (unlikely(res != 0))
84		return -EBUSY;
85
86	return 0;
87}
88
89/* Read from a PCMCIA configuration register. */
90static int ssb_pcmcia_cfg_read(struct ssb_bus *bus, u8 offset, u8 *value)
91{
92	conf_reg_t reg;
93	int res;
94
95	memset(&reg, 0, sizeof(reg));
96	reg.Offset = offset;
97	reg.Action = CS_READ;
98	res = pcmcia_access_configuration_register(bus->host_pcmcia, &reg);
99	if (unlikely(res != 0))
100		return -EBUSY;
101	*value = reg.Value;
102
103	return 0;
104}
105
106int ssb_pcmcia_switch_coreidx(struct ssb_bus *bus,
107			      u8 coreidx)
108{
109	int err;
110	int attempts = 0;
111	u32 cur_core;
112	u32 addr;
113	u32 read_addr;
114	u8 val;
115
116	addr = (coreidx * SSB_CORE_SIZE) + SSB_ENUM_BASE;
117	while (1) {
118		err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_ADDRESS0,
119					   (addr & 0x0000F000) >> 12);
120		if (err)
121			goto error;
122		err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_ADDRESS1,
123					   (addr & 0x00FF0000) >> 16);
124		if (err)
125			goto error;
126		err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_ADDRESS2,
127					   (addr & 0xFF000000) >> 24);
128		if (err)
129			goto error;
130
131		read_addr = 0;
132
133		err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_ADDRESS0, &val);
134		if (err)
135			goto error;
136		read_addr |= ((u32)(val & 0x0F)) << 12;
137		err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_ADDRESS1, &val);
138		if (err)
139			goto error;
140		read_addr |= ((u32)val) << 16;
141		err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_ADDRESS2, &val);
142		if (err)
143			goto error;
144		read_addr |= ((u32)val) << 24;
145
146		cur_core = (read_addr - SSB_ENUM_BASE) / SSB_CORE_SIZE;
147		if (cur_core == coreidx)
148			break;
149
150		err = -ETIMEDOUT;
151		if (attempts++ > SSB_BAR0_MAX_RETRIES)
152			goto error;
153		udelay(10);
154	}
155
156	return 0;
157error:
158	ssb_printk(KERN_ERR PFX "Failed to switch to core %u\n", coreidx);
159	return err;
160}
161
162int ssb_pcmcia_switch_core(struct ssb_bus *bus,
163			   struct ssb_device *dev)
164{
165	int err;
166
167#if SSB_VERBOSE_PCMCIACORESWITCH_DEBUG
168	ssb_printk(KERN_INFO PFX
169		   "Switching to %s core, index %d\n",
170		   ssb_core_name(dev->id.coreid),
171		   dev->core_index);
172#endif
173
174	err = ssb_pcmcia_switch_coreidx(bus, dev->core_index);
175	if (!err)
176		bus->mapped_device = dev;
177
178	return err;
179}
180
181int ssb_pcmcia_switch_segment(struct ssb_bus *bus, u8 seg)
182{
183	int attempts = 0;
184	int err;
185	u8 val;
186
187	SSB_WARN_ON((seg != 0) && (seg != 1));
188	while (1) {
189		err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_MEMSEG, seg);
190		if (err)
191			goto error;
192		err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_MEMSEG, &val);
193		if (err)
194			goto error;
195		if (val == seg)
196			break;
197
198		err = -ETIMEDOUT;
199		if (unlikely(attempts++ > SSB_BAR0_MAX_RETRIES))
200			goto error;
201		udelay(10);
202	}
203	bus->mapped_pcmcia_seg = seg;
204
205	return 0;
206error:
207	ssb_printk(KERN_ERR PFX "Failed to switch pcmcia segment\n");
208	return err;
209}
210
211static int select_core_and_segment(struct ssb_device *dev,
212				   u16 *offset)
213{
214	struct ssb_bus *bus = dev->bus;
215	int err;
216	u8 need_segment;
217
218	if (*offset >= 0x800) {
219		*offset -= 0x800;
220		need_segment = 1;
221	} else
222		need_segment = 0;
223
224	if (unlikely(dev != bus->mapped_device)) {
225		err = ssb_pcmcia_switch_core(bus, dev);
226		if (unlikely(err))
227			return err;
228	}
229	if (unlikely(need_segment != bus->mapped_pcmcia_seg)) {
230		err = ssb_pcmcia_switch_segment(bus, need_segment);
231		if (unlikely(err))
232			return err;
233	}
234
235	return 0;
236}
237
238static u8 ssb_pcmcia_read8(struct ssb_device *dev, u16 offset)
239{
240	struct ssb_bus *bus = dev->bus;
241	unsigned long flags;
242	int err;
243	u8 value = 0xFF;
244
245	spin_lock_irqsave(&bus->bar_lock, flags);
246	err = select_core_and_segment(dev, &offset);
247	if (likely(!err))
248		value = readb(bus->mmio + offset);
249	spin_unlock_irqrestore(&bus->bar_lock, flags);
250
251	return value;
252}
253
254static u16 ssb_pcmcia_read16(struct ssb_device *dev, u16 offset)
255{
256	struct ssb_bus *bus = dev->bus;
257	unsigned long flags;
258	int err;
259	u16 value = 0xFFFF;
260
261	spin_lock_irqsave(&bus->bar_lock, flags);
262	err = select_core_and_segment(dev, &offset);
263	if (likely(!err))
264		value = readw(bus->mmio + offset);
265	spin_unlock_irqrestore(&bus->bar_lock, flags);
266
267	return value;
268}
269
270static u32 ssb_pcmcia_read32(struct ssb_device *dev, u16 offset)
271{
272	struct ssb_bus *bus = dev->bus;
273	unsigned long flags;
274	int err;
275	u32 lo = 0xFFFFFFFF, hi = 0xFFFFFFFF;
276
277	spin_lock_irqsave(&bus->bar_lock, flags);
278	err = select_core_and_segment(dev, &offset);
279	if (likely(!err)) {
280		lo = readw(bus->mmio + offset);
281		hi = readw(bus->mmio + offset + 2);
282	}
283	spin_unlock_irqrestore(&bus->bar_lock, flags);
284
285	return (lo | (hi << 16));
286}
287
288#ifdef CONFIG_SSB_BLOCKIO
289static void ssb_pcmcia_block_read(struct ssb_device *dev, void *buffer,
290				  size_t count, u16 offset, u8 reg_width)
291{
292	struct ssb_bus *bus = dev->bus;
293	unsigned long flags;
294	void __iomem *addr = bus->mmio + offset;
295	int err;
296
297	spin_lock_irqsave(&bus->bar_lock, flags);
298	err = select_core_and_segment(dev, &offset);
299	if (unlikely(err)) {
300		memset(buffer, 0xFF, count);
301		goto unlock;
302	}
303	switch (reg_width) {
304	case sizeof(u8): {
305		u8 *buf = buffer;
306
307		while (count) {
308			*buf = __raw_readb(addr);
309			buf++;
310			count--;
311		}
312		break;
313	}
314	case sizeof(u16): {
315		__le16 *buf = buffer;
316
317		SSB_WARN_ON(count & 1);
318		while (count) {
319			*buf = (__force __le16)__raw_readw(addr);
320			buf++;
321			count -= 2;
322		}
323		break;
324	}
325	case sizeof(u32): {
326		__le16 *buf = buffer;
327
328		SSB_WARN_ON(count & 3);
329		while (count) {
330			*buf = (__force __le16)__raw_readw(addr);
331			buf++;
332			*buf = (__force __le16)__raw_readw(addr + 2);
333			buf++;
334			count -= 4;
335		}
336		break;
337	}
338	default:
339		SSB_WARN_ON(1);
340	}
341unlock:
342	spin_unlock_irqrestore(&bus->bar_lock, flags);
343}
344#endif /* CONFIG_SSB_BLOCKIO */
345
346static void ssb_pcmcia_write8(struct ssb_device *dev, u16 offset, u8 value)
347{
348	struct ssb_bus *bus = dev->bus;
349	unsigned long flags;
350	int err;
351
352	spin_lock_irqsave(&bus->bar_lock, flags);
353	err = select_core_and_segment(dev, &offset);
354	if (likely(!err))
355		writeb(value, bus->mmio + offset);
356	mmiowb();
357	spin_unlock_irqrestore(&bus->bar_lock, flags);
358}
359
360static void ssb_pcmcia_write16(struct ssb_device *dev, u16 offset, u16 value)
361{
362	struct ssb_bus *bus = dev->bus;
363	unsigned long flags;
364	int err;
365
366	spin_lock_irqsave(&bus->bar_lock, flags);
367	err = select_core_and_segment(dev, &offset);
368	if (likely(!err))
369		writew(value, bus->mmio + offset);
370	mmiowb();
371	spin_unlock_irqrestore(&bus->bar_lock, flags);
372}
373
374static void ssb_pcmcia_write32(struct ssb_device *dev, u16 offset, u32 value)
375{
376	struct ssb_bus *bus = dev->bus;
377	unsigned long flags;
378	int err;
379
380	spin_lock_irqsave(&bus->bar_lock, flags);
381	err = select_core_and_segment(dev, &offset);
382	if (likely(!err)) {
383		writew((value & 0x0000FFFF), bus->mmio + offset);
384		writew(((value & 0xFFFF0000) >> 16), bus->mmio + offset + 2);
385	}
386	mmiowb();
387	spin_unlock_irqrestore(&bus->bar_lock, flags);
388}
389
390#ifdef CONFIG_SSB_BLOCKIO
391static void ssb_pcmcia_block_write(struct ssb_device *dev, const void *buffer,
392				   size_t count, u16 offset, u8 reg_width)
393{
394	struct ssb_bus *bus = dev->bus;
395	unsigned long flags;
396	void __iomem *addr = bus->mmio + offset;
397	int err;
398
399	spin_lock_irqsave(&bus->bar_lock, flags);
400	err = select_core_and_segment(dev, &offset);
401	if (unlikely(err))
402		goto unlock;
403	switch (reg_width) {
404	case sizeof(u8): {
405		const u8 *buf = buffer;
406
407		while (count) {
408			__raw_writeb(*buf, addr);
409			buf++;
410			count--;
411		}
412		break;
413	}
414	case sizeof(u16): {
415		const __le16 *buf = buffer;
416
417		SSB_WARN_ON(count & 1);
418		while (count) {
419			__raw_writew((__force u16)(*buf), addr);
420			buf++;
421			count -= 2;
422		}
423		break;
424	}
425	case sizeof(u32): {
426		const __le16 *buf = buffer;
427
428		SSB_WARN_ON(count & 3);
429		while (count) {
430			__raw_writew((__force u16)(*buf), addr);
431			buf++;
432			__raw_writew((__force u16)(*buf), addr + 2);
433			buf++;
434			count -= 4;
435		}
436		break;
437	}
438	default:
439		SSB_WARN_ON(1);
440	}
441unlock:
442	mmiowb();
443	spin_unlock_irqrestore(&bus->bar_lock, flags);
444}
445#endif /* CONFIG_SSB_BLOCKIO */
446
447/* Not "static", as it's used in main.c */
448const struct ssb_bus_ops ssb_pcmcia_ops = {
449	.read8		= ssb_pcmcia_read8,
450	.read16		= ssb_pcmcia_read16,
451	.read32		= ssb_pcmcia_read32,
452	.write8		= ssb_pcmcia_write8,
453	.write16	= ssb_pcmcia_write16,
454	.write32	= ssb_pcmcia_write32,
455#ifdef CONFIG_SSB_BLOCKIO
456	.block_read	= ssb_pcmcia_block_read,
457	.block_write	= ssb_pcmcia_block_write,
458#endif
459};
460
461static int ssb_pcmcia_sprom_command(struct ssb_bus *bus, u8 command)
462{
463	unsigned int i;
464	int err;
465	u8 value;
466
467	err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROMCTL, command);
468	if (err)
469		return err;
470	for (i = 0; i < 1000; i++) {
471		err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_SPROMCTL, &value);
472		if (err)
473			return err;
474		if (value & SSB_PCMCIA_SPROMCTL_DONE)
475			return 0;
476		udelay(10);
477	}
478
479	return -ETIMEDOUT;
480}
481
482/* offset is the 16bit word offset */
483static int ssb_pcmcia_sprom_read(struct ssb_bus *bus, u16 offset, u16 *value)
484{
485	int err;
486	u8 lo, hi;
487
488	offset *= 2; /* Make byte offset */
489
490	err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_ADDRLO,
491				   (offset & 0x00FF));
492	if (err)
493		return err;
494	err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_ADDRHI,
495				   (offset & 0xFF00) >> 8);
496	if (err)
497		return err;
498	err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_READ);
499	if (err)
500		return err;
501	err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_SPROM_DATALO, &lo);
502	if (err)
503		return err;
504	err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_SPROM_DATAHI, &hi);
505	if (err)
506		return err;
507	*value = (lo | (((u16)hi) << 8));
508
509	return 0;
510}
511
512/* offset is the 16bit word offset */
513static int ssb_pcmcia_sprom_write(struct ssb_bus *bus, u16 offset, u16 value)
514{
515	int err;
516
517	offset *= 2; /* Make byte offset */
518
519	err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_ADDRLO,
520				   (offset & 0x00FF));
521	if (err)
522		return err;
523	err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_ADDRHI,
524				   (offset & 0xFF00) >> 8);
525	if (err)
526		return err;
527	err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_DATALO,
528				   (value & 0x00FF));
529	if (err)
530		return err;
531	err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_DATAHI,
532				   (value & 0xFF00) >> 8);
533	if (err)
534		return err;
535	err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITE);
536	if (err)
537		return err;
538	msleep(20);
539
540	return 0;
541}
542
543/* Read the SPROM image. bufsize is in 16bit words. */
544static int ssb_pcmcia_sprom_read_all(struct ssb_bus *bus, u16 *sprom)
545{
546	int err, i;
547
548	for (i = 0; i < SSB_PCMCIA_SPROM_SIZE; i++) {
549		err = ssb_pcmcia_sprom_read(bus, i, &sprom[i]);
550		if (err)
551			return err;
552	}
553
554	return 0;
555}
556
557/* Write the SPROM image. size is in 16bit words. */
558static int ssb_pcmcia_sprom_write_all(struct ssb_bus *bus, const u16 *sprom)
559{
560	int i, err;
561	bool failed = 0;
562	size_t size = SSB_PCMCIA_SPROM_SIZE;
563
564	ssb_printk(KERN_NOTICE PFX
565		   "Writing SPROM. Do NOT turn off the power! "
566		   "Please stand by...\n");
567	err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITEEN);
568	if (err) {
569		ssb_printk(KERN_NOTICE PFX
570			   "Could not enable SPROM write access.\n");
571		return -EBUSY;
572	}
573	ssb_printk(KERN_NOTICE PFX "[ 0%%");
574	msleep(500);
575	for (i = 0; i < size; i++) {
576		if (i == size / 4)
577			ssb_printk("25%%");
578		else if (i == size / 2)
579			ssb_printk("50%%");
580		else if (i == (size * 3) / 4)
581			ssb_printk("75%%");
582		else if (i % 2)
583			ssb_printk(".");
584		err = ssb_pcmcia_sprom_write(bus, i, sprom[i]);
585		if (err) {
586			ssb_printk("\n" KERN_NOTICE PFX
587				   "Failed to write to SPROM.\n");
588			failed = 1;
589			break;
590		}
591	}
592	err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITEDIS);
593	if (err) {
594		ssb_printk("\n" KERN_NOTICE PFX
595			   "Could not disable SPROM write access.\n");
596		failed = 1;
597	}
598	msleep(500);
599	if (!failed) {
600		ssb_printk("100%% ]\n");
601		ssb_printk(KERN_NOTICE PFX "SPROM written.\n");
602	}
603
604	return failed ? -EBUSY : 0;
605}
606
607static int ssb_pcmcia_sprom_check_crc(const u16 *sprom, size_t size)
608{
609	//TODO
610	return 0;
611}
612
613#define GOTO_ERROR_ON(condition, description) do {	\
614	if (unlikely(condition)) {			\
615		error_description = description;	\
616		goto error;				\
617	}						\
618  } while (0)
619
620int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
621			      struct ssb_init_invariants *iv)
622{
623	tuple_t tuple;
624	int res;
625	unsigned char buf[32];
626	struct ssb_sprom *sprom = &iv->sprom;
627	struct ssb_boardinfo *bi = &iv->boardinfo;
628	const char *error_description;
629
630	memset(sprom, 0xFF, sizeof(*sprom));
631	sprom->revision = 1;
632	sprom->boardflags_lo = 0;
633	sprom->boardflags_hi = 0;
634
635	/* First fetch the MAC address. */
636	memset(&tuple, 0, sizeof(tuple));
637	tuple.DesiredTuple = CISTPL_FUNCE;
638	tuple.TupleData = buf;
639	tuple.TupleDataMax = sizeof(buf);
640	res = pcmcia_get_first_tuple(bus->host_pcmcia, &tuple);
641	GOTO_ERROR_ON(res != 0, "MAC first tpl");
642	res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
643	GOTO_ERROR_ON(res != 0, "MAC first tpl data");
644	while (1) {
645		GOTO_ERROR_ON(tuple.TupleDataLen < 1, "MAC tpl < 1");
646		if (tuple.TupleData[0] == CISTPL_FUNCE_LAN_NODE_ID)
647			break;
648		res = pcmcia_get_next_tuple(bus->host_pcmcia, &tuple);
649		GOTO_ERROR_ON(res != 0, "MAC next tpl");
650		res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
651		GOTO_ERROR_ON(res != 0, "MAC next tpl data");
652	}
653	GOTO_ERROR_ON(tuple.TupleDataLen != ETH_ALEN + 2, "MAC tpl size");
654	memcpy(sprom->il0mac, &tuple.TupleData[2], ETH_ALEN);
655
656	/* Fetch the vendor specific tuples. */
657	memset(&tuple, 0, sizeof(tuple));
658	tuple.DesiredTuple = SSB_PCMCIA_CIS;
659	tuple.TupleData = buf;
660	tuple.TupleDataMax = sizeof(buf);
661	res = pcmcia_get_first_tuple(bus->host_pcmcia, &tuple);
662	GOTO_ERROR_ON(res != 0, "VEN first tpl");
663	res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
664	GOTO_ERROR_ON(res != 0, "VEN first tpl data");
665	while (1) {
666		GOTO_ERROR_ON(tuple.TupleDataLen < 1, "VEN tpl < 1");
667		switch (tuple.TupleData[0]) {
668		case SSB_PCMCIA_CIS_ID:
669			GOTO_ERROR_ON((tuple.TupleDataLen != 5) &&
670				      (tuple.TupleDataLen != 7),
671				      "id tpl size");
672			bi->vendor = tuple.TupleData[1] |
673			       ((u16)tuple.TupleData[2] << 8);
674			break;
675		case SSB_PCMCIA_CIS_BOARDREV:
676			GOTO_ERROR_ON(tuple.TupleDataLen != 2,
677				      "boardrev tpl size");
678			sprom->board_rev = tuple.TupleData[1];
679			break;
680		case SSB_PCMCIA_CIS_PA:
681			GOTO_ERROR_ON(tuple.TupleDataLen != 9,
682				      "pa tpl size");
683			sprom->pa0b0 = tuple.TupleData[1] |
684				 ((u16)tuple.TupleData[2] << 8);
685			sprom->pa0b1 = tuple.TupleData[3] |
686				 ((u16)tuple.TupleData[4] << 8);
687			sprom->pa0b2 = tuple.TupleData[5] |
688				 ((u16)tuple.TupleData[6] << 8);
689			sprom->itssi_a = tuple.TupleData[7];
690			sprom->itssi_bg = tuple.TupleData[7];
691			sprom->maxpwr_a = tuple.TupleData[8];
692			sprom->maxpwr_bg = tuple.TupleData[8];
693			break;
694		case SSB_PCMCIA_CIS_OEMNAME:
695			/* We ignore this. */
696			break;
697		case SSB_PCMCIA_CIS_CCODE:
698			GOTO_ERROR_ON(tuple.TupleDataLen != 2,
699				      "ccode tpl size");
700			sprom->country_code = tuple.TupleData[1];
701			break;
702		case SSB_PCMCIA_CIS_ANTENNA:
703			GOTO_ERROR_ON(tuple.TupleDataLen != 2,
704				      "ant tpl size");
705			sprom->ant_available_a = tuple.TupleData[1];
706			sprom->ant_available_bg = tuple.TupleData[1];
707			break;
708		case SSB_PCMCIA_CIS_ANTGAIN:
709			GOTO_ERROR_ON(tuple.TupleDataLen != 2,
710				      "antg tpl size");
711			sprom->antenna_gain.ghz24.a0 = tuple.TupleData[1];
712			sprom->antenna_gain.ghz24.a1 = tuple.TupleData[1];
713			sprom->antenna_gain.ghz24.a2 = tuple.TupleData[1];
714			sprom->antenna_gain.ghz24.a3 = tuple.TupleData[1];
715			sprom->antenna_gain.ghz5.a0 = tuple.TupleData[1];
716			sprom->antenna_gain.ghz5.a1 = tuple.TupleData[1];
717			sprom->antenna_gain.ghz5.a2 = tuple.TupleData[1];
718			sprom->antenna_gain.ghz5.a3 = tuple.TupleData[1];
719			break;
720		case SSB_PCMCIA_CIS_BFLAGS:
721			GOTO_ERROR_ON(tuple.TupleDataLen != 3,
722				      "bfl tpl size");
723			sprom->boardflags_lo = tuple.TupleData[1] |
724					 ((u16)tuple.TupleData[2] << 8);
725			break;
726		case SSB_PCMCIA_CIS_LEDS:
727			GOTO_ERROR_ON(tuple.TupleDataLen != 5,
728				      "leds tpl size");
729			sprom->gpio0 = tuple.TupleData[1];
730			sprom->gpio1 = tuple.TupleData[2];
731			sprom->gpio2 = tuple.TupleData[3];
732			sprom->gpio3 = tuple.TupleData[4];
733			break;
734		}
735		res = pcmcia_get_next_tuple(bus->host_pcmcia, &tuple);
736		if (res == CS_NO_MORE_ITEMS)
737			break;
738		GOTO_ERROR_ON(res != 0, "VEN next tpl");
739		res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
740		GOTO_ERROR_ON(res != 0, "VEN next tpl data");
741	}
742
743	return 0;
744error:
745	ssb_printk(KERN_ERR PFX
746		   "PCMCIA: Failed to fetch device invariants: %s\n",
747		   error_description);
748	return -ENODEV;
749}
750
751static ssize_t ssb_pcmcia_attr_sprom_show(struct device *pcmciadev,
752					  struct device_attribute *attr,
753					  char *buf)
754{
755	struct pcmcia_device *pdev =
756		container_of(pcmciadev, struct pcmcia_device, dev);
757	struct ssb_bus *bus;
758
759	bus = ssb_pcmcia_dev_to_bus(pdev);
760	if (!bus)
761		return -ENODEV;
762
763	return ssb_attr_sprom_show(bus, buf,
764				   ssb_pcmcia_sprom_read_all);
765}
766
767static ssize_t ssb_pcmcia_attr_sprom_store(struct device *pcmciadev,
768					   struct device_attribute *attr,
769					   const char *buf, size_t count)
770{
771	struct pcmcia_device *pdev =
772		container_of(pcmciadev, struct pcmcia_device, dev);
773	struct ssb_bus *bus;
774
775	bus = ssb_pcmcia_dev_to_bus(pdev);
776	if (!bus)
777		return -ENODEV;
778
779	return ssb_attr_sprom_store(bus, buf, count,
780				    ssb_pcmcia_sprom_check_crc,
781				    ssb_pcmcia_sprom_write_all);
782}
783
784static DEVICE_ATTR(ssb_sprom, 0600,
785		   ssb_pcmcia_attr_sprom_show,
786		   ssb_pcmcia_attr_sprom_store);
787
788static int ssb_pcmcia_cor_setup(struct ssb_bus *bus, u8 cor)
789{
790	u8 val;
791	int err;
792
793	err = ssb_pcmcia_cfg_read(bus, cor, &val);
794	if (err)
795		return err;
796	val &= ~COR_SOFT_RESET;
797	val |= COR_FUNC_ENA | COR_IREQ_ENA | COR_LEVEL_REQ;
798	err = ssb_pcmcia_cfg_write(bus, cor, val);
799	if (err)
800		return err;
801	msleep(40);
802
803	return 0;
804}
805
806/* Initialize the PCMCIA hardware. This is called on Init and Resume. */
807int ssb_pcmcia_hardware_setup(struct ssb_bus *bus)
808{
809	int err;
810
811	if (bus->bustype != SSB_BUSTYPE_PCMCIA)
812		return 0;
813
814	/* Switch segment to a known state and sync
815	 * bus->mapped_pcmcia_seg with hardware state. */
816	ssb_pcmcia_switch_segment(bus, 0);
817	/* Init the COR register. */
818	err = ssb_pcmcia_cor_setup(bus, CISREG_COR);
819	if (err)
820		return err;
821	/* Some cards also need this register to get poked. */
822	err = ssb_pcmcia_cor_setup(bus, CISREG_COR + 0x80);
823	if (err)
824		return err;
825
826	return 0;
827}
828
829void ssb_pcmcia_exit(struct ssb_bus *bus)
830{
831	if (bus->bustype != SSB_BUSTYPE_PCMCIA)
832		return;
833
834	device_remove_file(&bus->host_pcmcia->dev, &dev_attr_ssb_sprom);
835}
836
837int ssb_pcmcia_init(struct ssb_bus *bus)
838{
839	int err;
840
841	if (bus->bustype != SSB_BUSTYPE_PCMCIA)
842		return 0;
843
844	err = ssb_pcmcia_hardware_setup(bus);
845	if (err)
846		goto error;
847
848	bus->sprom_size = SSB_PCMCIA_SPROM_SIZE;
849	mutex_init(&bus->sprom_mutex);
850	err = device_create_file(&bus->host_pcmcia->dev, &dev_attr_ssb_sprom);
851	if (err)
852		goto error;
853
854	return 0;
855error:
856	ssb_printk(KERN_ERR PFX "Failed to initialize PCMCIA host device\n");
857	return err;
858}
859