spectrum_cs.c 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096
  1. /*
  2. * Driver for 802.11b cards using RAM-loadable Symbol firmware, such as
  3. * Symbol Wireless Networker LA4100, CompactFlash cards by Socket
  4. * Communications and Intel PRO/Wireless 2011B.
  5. *
  6. * The driver implements Symbol firmware download. The rest is handled
  7. * in hermes.c and orinoco.c.
  8. *
  9. * Utilities for downloading the Symbol firmware are available at
  10. * http://sourceforge.net/projects/orinoco/
  11. *
  12. * Copyright (C) 2002-2005 Pavel Roskin <proski@gnu.org>
  13. * Portions based on orinoco_cs.c:
  14. * Copyright (C) David Gibson, Linuxcare Australia
  15. * Portions based on Spectrum24tDnld.c from original spectrum24 driver:
  16. * Copyright (C) Symbol Technologies.
  17. *
  18. * See copyright notice in file orinoco.c.
  19. */
  20. #define DRIVER_NAME "spectrum_cs"
  21. #define PFX DRIVER_NAME ": "
  22. #include <linux/config.h>
  23. #include <linux/module.h>
  24. #include <linux/kernel.h>
  25. #include <linux/init.h>
  26. #include <linux/sched.h>
  27. #include <linux/ptrace.h>
  28. #include <linux/slab.h>
  29. #include <linux/string.h>
  30. #include <linux/ioport.h>
  31. #include <linux/netdevice.h>
  32. #include <linux/if_arp.h>
  33. #include <linux/etherdevice.h>
  34. #include <linux/wireless.h>
  35. #include <linux/firmware.h>
  36. #include <pcmcia/cs_types.h>
  37. #include <pcmcia/cs.h>
  38. #include <pcmcia/cistpl.h>
  39. #include <pcmcia/cisreg.h>
  40. #include <pcmcia/ds.h>
  41. #include <asm/uaccess.h>
  42. #include <asm/io.h>
  43. #include <asm/system.h>
  44. #include "orinoco.h"
  45. static unsigned char *primsym;
  46. static unsigned char *secsym;
  47. static const char primary_fw_name[] = "symbol_sp24t_prim_fw";
  48. static const char secondary_fw_name[] = "symbol_sp24t_sec_fw";
  49. /********************************************************************/
  50. /* Module stuff */
  51. /********************************************************************/
  52. MODULE_AUTHOR("Pavel Roskin <proski@gnu.org>");
  53. MODULE_DESCRIPTION("Driver for Symbol Spectrum24 Trilogy cards with firmware downloader");
  54. MODULE_LICENSE("Dual MPL/GPL");
  55. /* Module parameters */
  56. /* Some D-Link cards have buggy CIS. They do work at 5v properly, but
  57. * don't have any CIS entry for it. This workaround it... */
  58. static int ignore_cis_vcc; /* = 0 */
  59. module_param(ignore_cis_vcc, int, 0);
  60. MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket");
  61. /********************************************************************/
  62. /* Magic constants */
  63. /********************************************************************/
  64. /*
  65. * The dev_info variable is the "key" that is used to match up this
  66. * device driver with appropriate cards, through the card
  67. * configuration database.
  68. */
  69. static dev_info_t dev_info = DRIVER_NAME;
  70. /********************************************************************/
  71. /* Data structures */
  72. /********************************************************************/
  73. /* PCMCIA specific device information (goes in the card field of
  74. * struct orinoco_private */
  75. struct orinoco_pccard {
  76. dev_link_t link;
  77. dev_node_t node;
  78. };
  79. /*
  80. * A linked list of "instances" of the device. Each actual PCMCIA
  81. * card corresponds to one device instance, and is described by one
  82. * dev_link_t structure (defined in ds.h).
  83. */
  84. static dev_link_t *dev_list; /* = NULL */
  85. /********************************************************************/
  86. /* Function prototypes */
  87. /********************************************************************/
  88. /* device methods */
  89. static int spectrum_cs_hard_reset(struct orinoco_private *priv);
  90. /* PCMCIA gumpf */
  91. static void spectrum_cs_config(dev_link_t * link);
  92. static void spectrum_cs_release(dev_link_t * link);
  93. static int spectrum_cs_event(event_t event, int priority,
  94. event_callback_args_t * args);
  95. static dev_link_t *spectrum_cs_attach(void);
  96. static void spectrum_cs_detach(dev_link_t *);
  97. /********************************************************************/
  98. /* Firmware downloader */
  99. /********************************************************************/
  100. /* Position of PDA in the adapter memory */
  101. #define EEPROM_ADDR 0x3000
  102. #define EEPROM_LEN 0x200
  103. #define PDA_OFFSET 0x100
  104. #define PDA_ADDR (EEPROM_ADDR + PDA_OFFSET)
  105. #define PDA_WORDS ((EEPROM_LEN - PDA_OFFSET) / 2)
  106. /* Constants for the CISREG_CCSR register */
  107. #define HCR_RUN 0x07 /* run firmware after reset */
  108. #define HCR_IDLE 0x0E /* don't run firmware after reset */
  109. #define HCR_MEM16 0x10 /* memory width bit, should be preserved */
  110. /*
  111. * AUX port access. To unlock the AUX port write the access keys to the
  112. * PARAM0-2 registers, then write HERMES_AUX_ENABLE to the HERMES_CONTROL
  113. * register. Then read it and make sure it's HERMES_AUX_ENABLED.
  114. */
  115. #define HERMES_AUX_ENABLE 0x8000 /* Enable auxiliary port access */
  116. #define HERMES_AUX_DISABLE 0x4000 /* Disable to auxiliary port access */
  117. #define HERMES_AUX_ENABLED 0xC000 /* Auxiliary port is open */
  118. #define HERMES_AUX_PW0 0xFE01
  119. #define HERMES_AUX_PW1 0xDC23
  120. #define HERMES_AUX_PW2 0xBA45
  121. /* End markers */
  122. #define PDI_END 0x00000000 /* End of PDA */
  123. #define BLOCK_END 0xFFFFFFFF /* Last image block */
  124. #define TEXT_END 0x1A /* End of text header */
  125. /*
  126. * The following structures have little-endian fields denoted by
  127. * the leading underscore. Don't access them directly - use inline
  128. * functions defined below.
  129. */
  130. /*
  131. * The binary image to be downloaded consists of series of data blocks.
  132. * Each block has the following structure.
  133. */
  134. struct dblock {
  135. u32 _addr; /* adapter address where to write the block */
  136. u16 _len; /* length of the data only, in bytes */
  137. char data[0]; /* data to be written */
  138. } __attribute__ ((packed));
  139. /*
  140. * Plug Data References are located in in the image after the last data
  141. * block. They refer to areas in the adapter memory where the plug data
  142. * items with matching ID should be written.
  143. */
  144. struct pdr {
  145. u32 _id; /* record ID */
  146. u32 _addr; /* adapter address where to write the data */
  147. u32 _len; /* expected length of the data, in bytes */
  148. char next[0]; /* next PDR starts here */
  149. } __attribute__ ((packed));
  150. /*
  151. * Plug Data Items are located in the EEPROM read from the adapter by
  152. * primary firmware. They refer to the device-specific data that should
  153. * be plugged into the secondary firmware.
  154. */
  155. struct pdi {
  156. u16 _len; /* length of ID and data, in words */
  157. u16 _id; /* record ID */
  158. char data[0]; /* plug data */
  159. } __attribute__ ((packed));;
  160. /* Functions for access to little-endian data */
  161. static inline u32
  162. dblock_addr(const struct dblock *blk)
  163. {
  164. return le32_to_cpu(blk->_addr);
  165. }
  166. static inline u32
  167. dblock_len(const struct dblock *blk)
  168. {
  169. return le16_to_cpu(blk->_len);
  170. }
  171. static inline u32
  172. pdr_id(const struct pdr *pdr)
  173. {
  174. return le32_to_cpu(pdr->_id);
  175. }
  176. static inline u32
  177. pdr_addr(const struct pdr *pdr)
  178. {
  179. return le32_to_cpu(pdr->_addr);
  180. }
  181. static inline u32
  182. pdr_len(const struct pdr *pdr)
  183. {
  184. return le32_to_cpu(pdr->_len);
  185. }
  186. static inline u32
  187. pdi_id(const struct pdi *pdi)
  188. {
  189. return le16_to_cpu(pdi->_id);
  190. }
  191. /* Return length of the data only, in bytes */
  192. static inline u32
  193. pdi_len(const struct pdi *pdi)
  194. {
  195. return 2 * (le16_to_cpu(pdi->_len) - 1);
  196. }
  197. /* Set address of the auxiliary port */
  198. static inline void
  199. spectrum_aux_setaddr(hermes_t *hw, u32 addr)
  200. {
  201. hermes_write_reg(hw, HERMES_AUXPAGE, (u16) (addr >> 7));
  202. hermes_write_reg(hw, HERMES_AUXOFFSET, (u16) (addr & 0x7F));
  203. }
  204. /* Open access to the auxiliary port */
  205. static int
  206. spectrum_aux_open(hermes_t *hw)
  207. {
  208. int i;
  209. /* Already open? */
  210. if (hermes_read_reg(hw, HERMES_CONTROL) == HERMES_AUX_ENABLED)
  211. return 0;
  212. hermes_write_reg(hw, HERMES_PARAM0, HERMES_AUX_PW0);
  213. hermes_write_reg(hw, HERMES_PARAM1, HERMES_AUX_PW1);
  214. hermes_write_reg(hw, HERMES_PARAM2, HERMES_AUX_PW2);
  215. hermes_write_reg(hw, HERMES_CONTROL, HERMES_AUX_ENABLE);
  216. for (i = 0; i < 20; i++) {
  217. udelay(10);
  218. if (hermes_read_reg(hw, HERMES_CONTROL) ==
  219. HERMES_AUX_ENABLED)
  220. return 0;
  221. }
  222. return -EBUSY;
  223. }
  224. #define CS_CHECK(fn, ret) \
  225. do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
  226. /*
  227. * Reset the card using configuration registers COR and CCSR.
  228. * If IDLE is 1, stop the firmware, so that it can be safely rewritten.
  229. */
  230. static int
  231. spectrum_reset(dev_link_t *link, int idle)
  232. {
  233. int last_ret, last_fn;
  234. conf_reg_t reg;
  235. u_int save_cor;
  236. /* Doing it if hardware is gone is guaranteed crash */
  237. if (!(link->state & DEV_CONFIG))
  238. return -ENODEV;
  239. /* Save original COR value */
  240. reg.Function = 0;
  241. reg.Action = CS_READ;
  242. reg.Offset = CISREG_COR;
  243. CS_CHECK(AccessConfigurationRegister,
  244. pcmcia_access_configuration_register(link->handle, &reg));
  245. save_cor = reg.Value;
  246. /* Soft-Reset card */
  247. reg.Action = CS_WRITE;
  248. reg.Offset = CISREG_COR;
  249. reg.Value = (save_cor | COR_SOFT_RESET);
  250. CS_CHECK(AccessConfigurationRegister,
  251. pcmcia_access_configuration_register(link->handle, &reg));
  252. udelay(1000);
  253. /* Read CCSR */
  254. reg.Action = CS_READ;
  255. reg.Offset = CISREG_CCSR;
  256. CS_CHECK(AccessConfigurationRegister,
  257. pcmcia_access_configuration_register(link->handle, &reg));
  258. /*
  259. * Start or stop the firmware. Memory width bit should be
  260. * preserved from the value we've just read.
  261. */
  262. reg.Action = CS_WRITE;
  263. reg.Offset = CISREG_CCSR;
  264. reg.Value = (idle ? HCR_IDLE : HCR_RUN) | (reg.Value & HCR_MEM16);
  265. CS_CHECK(AccessConfigurationRegister,
  266. pcmcia_access_configuration_register(link->handle, &reg));
  267. udelay(1000);
  268. /* Restore original COR configuration index */
  269. reg.Action = CS_WRITE;
  270. reg.Offset = CISREG_COR;
  271. reg.Value = (save_cor & ~COR_SOFT_RESET);
  272. CS_CHECK(AccessConfigurationRegister,
  273. pcmcia_access_configuration_register(link->handle, &reg));
  274. udelay(1000);
  275. return 0;
  276. cs_failed:
  277. cs_error(link->handle, last_fn, last_ret);
  278. return -ENODEV;
  279. }
  280. /*
  281. * Scan PDR for the record with the specified RECORD_ID.
  282. * If it's not found, return NULL.
  283. */
  284. static struct pdr *
  285. spectrum_find_pdr(struct pdr *first_pdr, u32 record_id)
  286. {
  287. struct pdr *pdr = first_pdr;
  288. while (pdr_id(pdr) != PDI_END) {
  289. /*
  290. * PDR area is currently not terminated by PDI_END.
  291. * It's followed by CRC records, which have the type
  292. * field where PDR has length. The type can be 0 or 1.
  293. */
  294. if (pdr_len(pdr) < 2)
  295. return NULL;
  296. /* If the record ID matches, we are done */
  297. if (pdr_id(pdr) == record_id)
  298. return pdr;
  299. pdr = (struct pdr *) pdr->next;
  300. }
  301. return NULL;
  302. }
  303. /* Process one Plug Data Item - find corresponding PDR and plug it */
  304. static int
  305. spectrum_plug_pdi(hermes_t *hw, struct pdr *first_pdr, struct pdi *pdi)
  306. {
  307. struct pdr *pdr;
  308. /* Find the PDI corresponding to this PDR */
  309. pdr = spectrum_find_pdr(first_pdr, pdi_id(pdi));
  310. /* No match is found, safe to ignore */
  311. if (!pdr)
  312. return 0;
  313. /* Lengths of the data in PDI and PDR must match */
  314. if (pdi_len(pdi) != pdr_len(pdr))
  315. return -EINVAL;
  316. /* do the actual plugging */
  317. spectrum_aux_setaddr(hw, pdr_addr(pdr));
  318. hermes_write_words(hw, HERMES_AUXDATA, pdi->data,
  319. pdi_len(pdi) / 2);
  320. return 0;
  321. }
  322. /* Read PDA from the adapter */
  323. static int
  324. spectrum_read_pda(hermes_t *hw, u16 *pda, int pda_len)
  325. {
  326. int ret;
  327. int pda_size;
  328. /* Issue command to read EEPROM */
  329. ret = hermes_docmd_wait(hw, HERMES_CMD_READMIF, 0, NULL);
  330. if (ret)
  331. return ret;
  332. /* Open auxiliary port */
  333. ret = spectrum_aux_open(hw);
  334. if (ret)
  335. return ret;
  336. /* read PDA from EEPROM */
  337. spectrum_aux_setaddr(hw, PDA_ADDR);
  338. hermes_read_words(hw, HERMES_AUXDATA, pda, pda_len / 2);
  339. /* Check PDA length */
  340. pda_size = le16_to_cpu(pda[0]);
  341. if (pda_size > pda_len)
  342. return -EINVAL;
  343. return 0;
  344. }
  345. /* Parse PDA and write the records into the adapter */
  346. static int
  347. spectrum_apply_pda(hermes_t *hw, const struct dblock *first_block,
  348. u16 *pda)
  349. {
  350. int ret;
  351. struct pdi *pdi;
  352. struct pdr *first_pdr;
  353. const struct dblock *blk = first_block;
  354. /* Skip all blocks to locate Plug Data References */
  355. while (dblock_addr(blk) != BLOCK_END)
  356. blk = (struct dblock *) &blk->data[dblock_len(blk)];
  357. first_pdr = (struct pdr *) blk;
  358. /* Go through every PDI and plug them into the adapter */
  359. pdi = (struct pdi *) (pda + 2);
  360. while (pdi_id(pdi) != PDI_END) {
  361. ret = spectrum_plug_pdi(hw, first_pdr, pdi);
  362. if (ret)
  363. return ret;
  364. /* Increment to the next PDI */
  365. pdi = (struct pdi *) &pdi->data[pdi_len(pdi)];
  366. }
  367. return 0;
  368. }
  369. /* Load firmware blocks into the adapter */
  370. static int
  371. spectrum_load_blocks(hermes_t *hw, const struct dblock *first_block)
  372. {
  373. const struct dblock *blk;
  374. u32 blkaddr;
  375. u32 blklen;
  376. blk = first_block;
  377. blkaddr = dblock_addr(blk);
  378. blklen = dblock_len(blk);
  379. while (dblock_addr(blk) != BLOCK_END) {
  380. spectrum_aux_setaddr(hw, blkaddr);
  381. hermes_write_words(hw, HERMES_AUXDATA, blk->data,
  382. blklen / 2);
  383. blk = (struct dblock *) &blk->data[blklen];
  384. blkaddr = dblock_addr(blk);
  385. blklen = dblock_len(blk);
  386. }
  387. return 0;
  388. }
  389. /*
  390. * Process a firmware image - stop the card, load the firmware, reset
  391. * the card and make sure it responds. For the secondary firmware take
  392. * care of the PDA - read it and then write it on top of the firmware.
  393. */
  394. static int
  395. spectrum_dl_image(hermes_t *hw, dev_link_t *link,
  396. const unsigned char *image)
  397. {
  398. int ret;
  399. const unsigned char *ptr;
  400. const struct dblock *first_block;
  401. /* Plug Data Area (PDA) */
  402. u16 pda[PDA_WORDS];
  403. /* Binary block begins after the 0x1A marker */
  404. ptr = image;
  405. while (*ptr++ != TEXT_END);
  406. first_block = (const struct dblock *) ptr;
  407. /* Read the PDA */
  408. if (image != primsym) {
  409. ret = spectrum_read_pda(hw, pda, sizeof(pda));
  410. if (ret)
  411. return ret;
  412. }
  413. /* Stop the firmware, so that it can be safely rewritten */
  414. ret = spectrum_reset(link, 1);
  415. if (ret)
  416. return ret;
  417. /* Program the adapter with new firmware */
  418. ret = spectrum_load_blocks(hw, first_block);
  419. if (ret)
  420. return ret;
  421. /* Write the PDA to the adapter */
  422. if (image != primsym) {
  423. ret = spectrum_apply_pda(hw, first_block, pda);
  424. if (ret)
  425. return ret;
  426. }
  427. /* Run the firmware */
  428. ret = spectrum_reset(link, 0);
  429. if (ret)
  430. return ret;
  431. /* Reset hermes chip and make sure it responds */
  432. ret = hermes_init(hw);
  433. /* hermes_reset() should return 0 with the secondary firmware */
  434. if (image != primsym && ret != 0)
  435. return -ENODEV;
  436. /* And this should work with any firmware */
  437. if (!hermes_present(hw))
  438. return -ENODEV;
  439. return 0;
  440. }
  441. /*
  442. * Download the firmware into the card, this also does a PCMCIA soft
  443. * reset on the card, to make sure it's in a sane state.
  444. */
  445. static int
  446. spectrum_dl_firmware(hermes_t *hw, dev_link_t *link)
  447. {
  448. int ret;
  449. client_handle_t handle = link->handle;
  450. const struct firmware *fw_entry;
  451. if (request_firmware(&fw_entry, primary_fw_name,
  452. &handle_to_dev(handle)) == 0) {
  453. primsym = fw_entry->data;
  454. } else {
  455. printk(KERN_ERR PFX "Cannot find firmware: %s\n",
  456. primary_fw_name);
  457. return -ENOENT;
  458. }
  459. if (request_firmware(&fw_entry, secondary_fw_name,
  460. &handle_to_dev(handle)) == 0) {
  461. secsym = fw_entry->data;
  462. } else {
  463. printk(KERN_ERR PFX "Cannot find firmware: %s\n",
  464. secondary_fw_name);
  465. return -ENOENT;
  466. }
  467. /* Load primary firmware */
  468. ret = spectrum_dl_image(hw, link, primsym);
  469. if (ret) {
  470. printk(KERN_ERR PFX "Primary firmware download failed\n");
  471. return ret;
  472. }
  473. /* Load secondary firmware */
  474. ret = spectrum_dl_image(hw, link, secsym);
  475. if (ret) {
  476. printk(KERN_ERR PFX "Secondary firmware download failed\n");
  477. }
  478. return ret;
  479. }
  480. /********************************************************************/
  481. /* Device methods */
  482. /********************************************************************/
  483. static int
  484. spectrum_cs_hard_reset(struct orinoco_private *priv)
  485. {
  486. struct orinoco_pccard *card = priv->card;
  487. dev_link_t *link = &card->link;
  488. int err;
  489. if (!hermes_present(&priv->hw)) {
  490. /* The firmware needs to be reloaded */
  491. if (spectrum_dl_firmware(&priv->hw, &card->link) != 0) {
  492. printk(KERN_ERR PFX "Firmware download failed\n");
  493. err = -ENODEV;
  494. }
  495. } else {
  496. /* Soft reset using COR and HCR */
  497. spectrum_reset(link, 0);
  498. }
  499. return 0;
  500. }
  501. /********************************************************************/
  502. /* PCMCIA stuff */
  503. /********************************************************************/
  504. /*
  505. * This creates an "instance" of the driver, allocating local data
  506. * structures for one device. The device is registered with Card
  507. * Services.
  508. *
  509. * The dev_link structure is initialized, but we don't actually
  510. * configure the card at this point -- we wait until we receive a card
  511. * insertion event. */
  512. static dev_link_t *
  513. spectrum_cs_attach(void)
  514. {
  515. struct net_device *dev;
  516. struct orinoco_private *priv;
  517. struct orinoco_pccard *card;
  518. dev_link_t *link;
  519. client_reg_t client_reg;
  520. int ret;
  521. dev = alloc_orinocodev(sizeof(*card), spectrum_cs_hard_reset);
  522. if (! dev)
  523. return NULL;
  524. priv = netdev_priv(dev);
  525. card = priv->card;
  526. /* Link both structures together */
  527. link = &card->link;
  528. link->priv = dev;
  529. /* Interrupt setup */
  530. link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
  531. link->irq.IRQInfo1 = IRQ_LEVEL_ID;
  532. link->irq.Handler = orinoco_interrupt;
  533. link->irq.Instance = dev;
  534. /* General socket configuration defaults can go here. In this
  535. * client, we assume very little, and rely on the CIS for
  536. * almost everything. In most clients, many details (i.e.,
  537. * number, sizes, and attributes of IO windows) are fixed by
  538. * the nature of the device, and can be hard-wired here. */
  539. link->conf.Attributes = 0;
  540. link->conf.IntType = INT_MEMORY_AND_IO;
  541. /* Register with Card Services */
  542. /* FIXME: need a lock? */
  543. link->next = dev_list;
  544. dev_list = link;
  545. client_reg.dev_info = &dev_info;
  546. client_reg.Version = 0x0210; /* FIXME: what does this mean? */
  547. client_reg.event_callback_args.client_data = link;
  548. ret = pcmcia_register_client(&link->handle, &client_reg);
  549. if (ret != CS_SUCCESS) {
  550. cs_error(link->handle, RegisterClient, ret);
  551. spectrum_cs_detach(link);
  552. return NULL;
  553. }
  554. return link;
  555. } /* spectrum_cs_attach */
  556. /*
  557. * This deletes a driver "instance". The device is de-registered with
  558. * Card Services. If it has been released, all local data structures
  559. * are freed. Otherwise, the structures will be freed when the device
  560. * is released.
  561. */
  562. static void spectrum_cs_detach(dev_link_t *link)
  563. {
  564. dev_link_t **linkp;
  565. struct net_device *dev = link->priv;
  566. /* Locate device structure */
  567. for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
  568. if (*linkp == link)
  569. break;
  570. BUG_ON(*linkp == NULL);
  571. if (link->state & DEV_CONFIG)
  572. spectrum_cs_release(link);
  573. /* Break the link with Card Services */
  574. if (link->handle)
  575. pcmcia_deregister_client(link->handle);
  576. /* Unlink device structure, and free it */
  577. *linkp = link->next;
  578. DEBUG(0, PFX "detach: link=%p link->dev=%p\n", link, link->dev);
  579. if (link->dev) {
  580. DEBUG(0, PFX "About to unregister net device %p\n",
  581. dev);
  582. unregister_netdev(dev);
  583. }
  584. free_orinocodev(dev);
  585. } /* spectrum_cs_detach */
  586. /*
  587. * spectrum_cs_config() is scheduled to run after a CARD_INSERTION
  588. * event is received, to configure the PCMCIA socket, and to make the
  589. * device available to the system.
  590. */
  591. static void
  592. spectrum_cs_config(dev_link_t *link)
  593. {
  594. struct net_device *dev = link->priv;
  595. client_handle_t handle = link->handle;
  596. struct orinoco_private *priv = netdev_priv(dev);
  597. struct orinoco_pccard *card = priv->card;
  598. hermes_t *hw = &priv->hw;
  599. int last_fn, last_ret;
  600. u_char buf[64];
  601. config_info_t conf;
  602. cisinfo_t info;
  603. tuple_t tuple;
  604. cisparse_t parse;
  605. void __iomem *mem;
  606. CS_CHECK(ValidateCIS, pcmcia_validate_cis(handle, &info));
  607. /*
  608. * This reads the card's CONFIG tuple to find its
  609. * configuration registers.
  610. */
  611. tuple.DesiredTuple = CISTPL_CONFIG;
  612. tuple.Attributes = 0;
  613. tuple.TupleData = buf;
  614. tuple.TupleDataMax = sizeof(buf);
  615. tuple.TupleOffset = 0;
  616. CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
  617. CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
  618. CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
  619. link->conf.ConfigBase = parse.config.base;
  620. link->conf.Present = parse.config.rmask[0];
  621. /* Configure card */
  622. link->state |= DEV_CONFIG;
  623. /* Look up the current Vcc */
  624. CS_CHECK(GetConfigurationInfo,
  625. pcmcia_get_configuration_info(handle, &conf));
  626. link->conf.Vcc = conf.Vcc;
  627. /*
  628. * In this loop, we scan the CIS for configuration table
  629. * entries, each of which describes a valid card
  630. * configuration, including voltage, IO window, memory window,
  631. * and interrupt settings.
  632. *
  633. * We make no assumptions about the card to be configured: we
  634. * use just the information available in the CIS. In an ideal
  635. * world, this would work for any PCMCIA card, but it requires
  636. * a complete and accurate CIS. In practice, a driver usually
  637. * "knows" most of these things without consulting the CIS,
  638. * and most client drivers will only use the CIS to fill in
  639. * implementation-defined details.
  640. */
  641. tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
  642. CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
  643. while (1) {
  644. cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
  645. cistpl_cftable_entry_t dflt = { .index = 0 };
  646. if ( (pcmcia_get_tuple_data(handle, &tuple) != 0)
  647. || (pcmcia_parse_tuple(handle, &tuple, &parse) != 0))
  648. goto next_entry;
  649. if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
  650. dflt = *cfg;
  651. if (cfg->index == 0)
  652. goto next_entry;
  653. link->conf.ConfigIndex = cfg->index;
  654. /* Does this card need audio output? */
  655. if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
  656. link->conf.Attributes |= CONF_ENABLE_SPKR;
  657. link->conf.Status = CCSR_AUDIO_ENA;
  658. }
  659. /* Use power settings for Vcc and Vpp if present */
  660. /* Note that the CIS values need to be rescaled */
  661. if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
  662. if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
  663. DEBUG(2, "spectrum_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n", conf.Vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
  664. if (!ignore_cis_vcc)
  665. goto next_entry;
  666. }
  667. } else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
  668. if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) {
  669. DEBUG(2, "spectrum_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n", conf.Vcc, dflt.vcc.param[CISTPL_POWER_VNOM] / 10000);
  670. if(!ignore_cis_vcc)
  671. goto next_entry;
  672. }
  673. }
  674. if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
  675. link->conf.Vpp1 = link->conf.Vpp2 =
  676. cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
  677. else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
  678. link->conf.Vpp1 = link->conf.Vpp2 =
  679. dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
  680. /* Do we need to allocate an interrupt? */
  681. link->conf.Attributes |= CONF_ENABLE_IRQ;
  682. /* IO window settings */
  683. link->io.NumPorts1 = link->io.NumPorts2 = 0;
  684. if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
  685. cistpl_io_t *io =
  686. (cfg->io.nwin) ? &cfg->io : &dflt.io;
  687. link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
  688. if (!(io->flags & CISTPL_IO_8BIT))
  689. link->io.Attributes1 =
  690. IO_DATA_PATH_WIDTH_16;
  691. if (!(io->flags & CISTPL_IO_16BIT))
  692. link->io.Attributes1 =
  693. IO_DATA_PATH_WIDTH_8;
  694. link->io.IOAddrLines =
  695. io->flags & CISTPL_IO_LINES_MASK;
  696. link->io.BasePort1 = io->win[0].base;
  697. link->io.NumPorts1 = io->win[0].len;
  698. if (io->nwin > 1) {
  699. link->io.Attributes2 =
  700. link->io.Attributes1;
  701. link->io.BasePort2 = io->win[1].base;
  702. link->io.NumPorts2 = io->win[1].len;
  703. }
  704. /* This reserves IO space but doesn't actually enable it */
  705. if (pcmcia_request_io(link->handle, &link->io) != 0)
  706. goto next_entry;
  707. }
  708. /* If we got this far, we're cool! */
  709. break;
  710. next_entry:
  711. if (link->io.NumPorts1)
  712. pcmcia_release_io(link->handle, &link->io);
  713. last_ret = pcmcia_get_next_tuple(handle, &tuple);
  714. if (last_ret == CS_NO_MORE_ITEMS) {
  715. printk(KERN_ERR PFX "GetNextTuple(): No matching "
  716. "CIS configuration. Maybe you need the "
  717. "ignore_cis_vcc=1 parameter.\n");
  718. goto cs_failed;
  719. }
  720. }
  721. /*
  722. * Allocate an interrupt line. Note that this does not assign
  723. * a handler to the interrupt, unless the 'Handler' member of
  724. * the irq structure is initialized.
  725. */
  726. CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
  727. /* We initialize the hermes structure before completing PCMCIA
  728. * configuration just in case the interrupt handler gets
  729. * called. */
  730. mem = ioport_map(link->io.BasePort1, link->io.NumPorts1);
  731. if (!mem)
  732. goto cs_failed;
  733. hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
  734. /*
  735. * This actually configures the PCMCIA socket -- setting up
  736. * the I/O windows and the interrupt mapping, and putting the
  737. * card and host interface into "Memory and IO" mode.
  738. */
  739. CS_CHECK(RequestConfiguration,
  740. pcmcia_request_configuration(link->handle, &link->conf));
  741. /* Ok, we have the configuration, prepare to register the netdev */
  742. dev->base_addr = link->io.BasePort1;
  743. dev->irq = link->irq.AssignedIRQ;
  744. SET_MODULE_OWNER(dev);
  745. card->node.major = card->node.minor = 0;
  746. /* Reset card and download firmware */
  747. if (spectrum_cs_hard_reset(priv) != 0) {
  748. goto failed;
  749. }
  750. SET_NETDEV_DEV(dev, &handle_to_dev(handle));
  751. /* Tell the stack we exist */
  752. if (register_netdev(dev) != 0) {
  753. printk(KERN_ERR PFX "register_netdev() failed\n");
  754. goto failed;
  755. }
  756. /* At this point, the dev_node_t structure(s) needs to be
  757. * initialized and arranged in a linked list at link->dev. */
  758. strcpy(card->node.dev_name, dev->name);
  759. link->dev = &card->node; /* link->dev being non-NULL is also
  760. used to indicate that the
  761. net_device has been registered */
  762. link->state &= ~DEV_CONFIG_PENDING;
  763. /* Finally, report what we've done */
  764. printk(KERN_DEBUG "%s: index 0x%02x: Vcc %d.%d",
  765. dev->name, link->conf.ConfigIndex,
  766. link->conf.Vcc / 10, link->conf.Vcc % 10);
  767. if (link->conf.Vpp1)
  768. printk(", Vpp %d.%d", link->conf.Vpp1 / 10,
  769. link->conf.Vpp1 % 10);
  770. printk(", irq %d", link->irq.AssignedIRQ);
  771. if (link->io.NumPorts1)
  772. printk(", io 0x%04x-0x%04x", link->io.BasePort1,
  773. link->io.BasePort1 + link->io.NumPorts1 - 1);
  774. if (link->io.NumPorts2)
  775. printk(" & 0x%04x-0x%04x", link->io.BasePort2,
  776. link->io.BasePort2 + link->io.NumPorts2 - 1);
  777. printk("\n");
  778. return;
  779. cs_failed:
  780. cs_error(link->handle, last_fn, last_ret);
  781. failed:
  782. spectrum_cs_release(link);
  783. } /* spectrum_cs_config */
  784. /*
  785. * After a card is removed, spectrum_cs_release() will unregister the
  786. * device, and release the PCMCIA configuration. If the device is
  787. * still open, this will be postponed until it is closed.
  788. */
  789. static void
  790. spectrum_cs_release(dev_link_t *link)
  791. {
  792. struct net_device *dev = link->priv;
  793. struct orinoco_private *priv = netdev_priv(dev);
  794. unsigned long flags;
  795. /* We're committed to taking the device away now, so mark the
  796. * hardware as unavailable */
  797. spin_lock_irqsave(&priv->lock, flags);
  798. priv->hw_unavailable++;
  799. spin_unlock_irqrestore(&priv->lock, flags);
  800. /* Don't bother checking to see if these succeed or not */
  801. pcmcia_release_configuration(link->handle);
  802. if (link->io.NumPorts1)
  803. pcmcia_release_io(link->handle, &link->io);
  804. if (link->irq.AssignedIRQ)
  805. pcmcia_release_irq(link->handle, &link->irq);
  806. link->state &= ~DEV_CONFIG;
  807. if (priv->hw.iobase)
  808. ioport_unmap(priv->hw.iobase);
  809. } /* spectrum_cs_release */
  810. /*
  811. * The card status event handler. Mostly, this schedules other stuff
  812. * to run after an event is received.
  813. */
  814. static int
  815. spectrum_cs_event(event_t event, int priority,
  816. event_callback_args_t * args)
  817. {
  818. dev_link_t *link = args->client_data;
  819. struct net_device *dev = link->priv;
  820. struct orinoco_private *priv = netdev_priv(dev);
  821. int err = 0;
  822. unsigned long flags;
  823. switch (event) {
  824. case CS_EVENT_CARD_REMOVAL:
  825. link->state &= ~DEV_PRESENT;
  826. if (link->state & DEV_CONFIG) {
  827. unsigned long flags;
  828. spin_lock_irqsave(&priv->lock, flags);
  829. netif_device_detach(dev);
  830. priv->hw_unavailable++;
  831. spin_unlock_irqrestore(&priv->lock, flags);
  832. }
  833. break;
  834. case CS_EVENT_CARD_INSERTION:
  835. link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
  836. spectrum_cs_config(link);
  837. break;
  838. case CS_EVENT_PM_SUSPEND:
  839. link->state |= DEV_SUSPEND;
  840. /* Fall through... */
  841. case CS_EVENT_RESET_PHYSICAL:
  842. /* Mark the device as stopped, to block IO until later */
  843. if (link->state & DEV_CONFIG) {
  844. /* This is probably racy, but I can't think of
  845. a better way, short of rewriting the PCMCIA
  846. layer to not suck :-( */
  847. spin_lock_irqsave(&priv->lock, flags);
  848. err = __orinoco_down(dev);
  849. if (err)
  850. printk(KERN_WARNING "%s: %s: Error %d downing interface\n",
  851. dev->name,
  852. event == CS_EVENT_PM_SUSPEND ? "SUSPEND" : "RESET_PHYSICAL",
  853. err);
  854. netif_device_detach(dev);
  855. priv->hw_unavailable++;
  856. spin_unlock_irqrestore(&priv->lock, flags);
  857. pcmcia_release_configuration(link->handle);
  858. }
  859. break;
  860. case CS_EVENT_PM_RESUME:
  861. link->state &= ~DEV_SUSPEND;
  862. /* Fall through... */
  863. case CS_EVENT_CARD_RESET:
  864. if (link->state & DEV_CONFIG) {
  865. /* FIXME: should we double check that this is
  866. * the same card as we had before */
  867. pcmcia_request_configuration(link->handle, &link->conf);
  868. netif_device_attach(dev);
  869. priv->hw_unavailable--;
  870. schedule_work(&priv->reset_work);
  871. }
  872. break;
  873. }
  874. return err;
  875. } /* spectrum_cs_event */
  876. /********************************************************************/
  877. /* Module initialization */
  878. /********************************************************************/
  879. /* Can't be declared "const" or the whole __initdata section will
  880. * become const */
  881. static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
  882. " (Pavel Roskin <proski@gnu.org>,"
  883. " David Gibson <hermes@gibson.dropbear.id.au>, et al)";
  884. static struct pcmcia_device_id spectrum_cs_ids[] = {
  885. PCMCIA_DEVICE_MANF_CARD(0x026c, 0x0001), /* Symbol Spectrum24 LA4100 */
  886. PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0001), /* Socket Communications CF */
  887. PCMCIA_DEVICE_PROD_ID12("Intel", "PRO/Wireless LAN PC Card", 0x816cc815, 0x6fbf459a), /* 2011B, not 2011 */
  888. PCMCIA_DEVICE_NULL,
  889. };
  890. MODULE_DEVICE_TABLE(pcmcia, spectrum_cs_ids);
  891. static struct pcmcia_driver orinoco_driver = {
  892. .owner = THIS_MODULE,
  893. .drv = {
  894. .name = DRIVER_NAME,
  895. },
  896. .attach = spectrum_cs_attach,
  897. .event = spectrum_cs_event,
  898. .detach = spectrum_cs_detach,
  899. .id_table = spectrum_cs_ids,
  900. };
  901. static int __init
  902. init_spectrum_cs(void)
  903. {
  904. printk(KERN_DEBUG "%s\n", version);
  905. return pcmcia_register_driver(&orinoco_driver);
  906. }
  907. static void __exit
  908. exit_spectrum_cs(void)
  909. {
  910. pcmcia_unregister_driver(&orinoco_driver);
  911. BUG_ON(dev_list != NULL);
  912. }
  913. module_init(init_spectrum_cs);
  914. module_exit(exit_spectrum_cs);