pcmcia.c 20 KB

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