pcmcia.c 20 KB

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