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