spectrum_cs.c 31 KB

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