hermes.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779
  1. /* hermes.c
  2. *
  3. * Driver core for the "Hermes" wireless MAC controller, as used in
  4. * the Lucent Orinoco and Cabletron RoamAbout cards. It should also
  5. * work on the hfa3841 and hfa3842 MAC controller chips used in the
  6. * Prism II chipsets.
  7. *
  8. * This is not a complete driver, just low-level access routines for
  9. * the MAC controller itself.
  10. *
  11. * Based on the prism2 driver from Absolute Value Systems' linux-wlan
  12. * project, the Linux wvlan_cs driver, Lucent's HCF-Light
  13. * (wvlan_hcf.c) library, and the NetBSD wireless driver (in no
  14. * particular order).
  15. *
  16. * Copyright (C) 2000, David Gibson, Linuxcare Australia.
  17. * (C) Copyright David Gibson, IBM Corp. 2001-2003.
  18. *
  19. * The contents of this file are subject to the Mozilla Public License
  20. * Version 1.1 (the "License"); you may not use this file except in
  21. * compliance with the License. You may obtain a copy of the License
  22. * at http://www.mozilla.org/MPL/
  23. *
  24. * Software distributed under the License is distributed on an "AS IS"
  25. * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
  26. * the License for the specific language governing rights and
  27. * limitations under the License.
  28. *
  29. * Alternatively, the contents of this file may be used under the
  30. * terms of the GNU General Public License version 2 (the "GPL"), in
  31. * which case the provisions of the GPL are applicable instead of the
  32. * above. If you wish to allow the use of your version of this file
  33. * only under the terms of the GPL and not to allow others to use your
  34. * version of this file under the MPL, indicate your decision by
  35. * deleting the provisions above and replace them with the notice and
  36. * other provisions required by the GPL. If you do not delete the
  37. * provisions above, a recipient may use your version of this file
  38. * under either the MPL or the GPL.
  39. */
  40. #include <linux/module.h>
  41. #include <linux/kernel.h>
  42. #include <linux/init.h>
  43. #include <linux/delay.h>
  44. #include "hermes.h"
  45. /* These are maximum timeouts. Most often, card wil react much faster */
  46. #define CMD_BUSY_TIMEOUT (100) /* In iterations of ~1us */
  47. #define CMD_INIT_TIMEOUT (50000) /* in iterations of ~10us */
  48. #define CMD_COMPL_TIMEOUT (20000) /* in iterations of ~10us */
  49. #define ALLOC_COMPL_TIMEOUT (1000) /* in iterations of ~10us */
  50. /*
  51. * AUX port access. To unlock the AUX port write the access keys to the
  52. * PARAM0-2 registers, then write HERMES_AUX_ENABLE to the HERMES_CONTROL
  53. * register. Then read it and make sure it's HERMES_AUX_ENABLED.
  54. */
  55. #define HERMES_AUX_ENABLE 0x8000 /* Enable auxiliary port access */
  56. #define HERMES_AUX_DISABLE 0x4000 /* Disable to auxiliary port access */
  57. #define HERMES_AUX_ENABLED 0xC000 /* Auxiliary port is open */
  58. #define HERMES_AUX_DISABLED 0x0000 /* Auxiliary port is closed */
  59. #define HERMES_AUX_PW0 0xFE01
  60. #define HERMES_AUX_PW1 0xDC23
  61. #define HERMES_AUX_PW2 0xBA45
  62. /* HERMES_CMD_DOWNLD */
  63. #define HERMES_PROGRAM_DISABLE (0x0000 | HERMES_CMD_DOWNLD)
  64. #define HERMES_PROGRAM_ENABLE_VOLATILE (0x0100 | HERMES_CMD_DOWNLD)
  65. #define HERMES_PROGRAM_ENABLE_NON_VOLATILE (0x0200 | HERMES_CMD_DOWNLD)
  66. #define HERMES_PROGRAM_NON_VOLATILE (0x0300 | HERMES_CMD_DOWNLD)
  67. /*
  68. * Debugging helpers
  69. */
  70. #define DMSG(stuff...) do {printk(KERN_DEBUG "hermes @ %p: " , hw->iobase); \
  71. printk(stuff); } while (0)
  72. #undef HERMES_DEBUG
  73. #ifdef HERMES_DEBUG
  74. #include <stdarg.h>
  75. #define DEBUG(lvl, stuff...) if ((lvl) <= HERMES_DEBUG) DMSG(stuff)
  76. #else /* ! HERMES_DEBUG */
  77. #define DEBUG(lvl, stuff...) do { } while (0)
  78. #endif /* ! HERMES_DEBUG */
  79. static const struct hermes_ops hermes_ops_local;
  80. /*
  81. * Internal functions
  82. */
  83. /* Issue a command to the chip. Waiting for it to complete is the caller's
  84. problem.
  85. Returns -EBUSY if the command register is busy, 0 on success.
  86. Callable from any context.
  87. */
  88. static int hermes_issue_cmd(struct hermes *hw, u16 cmd, u16 param0,
  89. u16 param1, u16 param2)
  90. {
  91. int k = CMD_BUSY_TIMEOUT;
  92. u16 reg;
  93. /* First wait for the command register to unbusy */
  94. reg = hermes_read_regn(hw, CMD);
  95. while ((reg & HERMES_CMD_BUSY) && k) {
  96. k--;
  97. udelay(1);
  98. reg = hermes_read_regn(hw, CMD);
  99. }
  100. if (reg & HERMES_CMD_BUSY)
  101. return -EBUSY;
  102. hermes_write_regn(hw, PARAM2, param2);
  103. hermes_write_regn(hw, PARAM1, param1);
  104. hermes_write_regn(hw, PARAM0, param0);
  105. hermes_write_regn(hw, CMD, cmd);
  106. return 0;
  107. }
  108. /*
  109. * Function definitions
  110. */
  111. /* For doing cmds that wipe the magic constant in SWSUPPORT0 */
  112. static int hermes_doicmd_wait(struct hermes *hw, u16 cmd,
  113. u16 parm0, u16 parm1, u16 parm2,
  114. struct hermes_response *resp)
  115. {
  116. int err = 0;
  117. int k;
  118. u16 status, reg;
  119. err = hermes_issue_cmd(hw, cmd, parm0, parm1, parm2);
  120. if (err)
  121. return err;
  122. reg = hermes_read_regn(hw, EVSTAT);
  123. k = CMD_INIT_TIMEOUT;
  124. while ((!(reg & HERMES_EV_CMD)) && k) {
  125. k--;
  126. udelay(10);
  127. reg = hermes_read_regn(hw, EVSTAT);
  128. }
  129. hermes_write_regn(hw, SWSUPPORT0, HERMES_MAGIC);
  130. if (!hermes_present(hw)) {
  131. DEBUG(0, "hermes @ 0x%x: Card removed during reset.\n",
  132. hw->iobase);
  133. err = -ENODEV;
  134. goto out;
  135. }
  136. if (!(reg & HERMES_EV_CMD)) {
  137. printk(KERN_ERR "hermes @ %p: "
  138. "Timeout waiting for card to reset (reg=0x%04x)!\n",
  139. hw->iobase, reg);
  140. err = -ETIMEDOUT;
  141. goto out;
  142. }
  143. status = hermes_read_regn(hw, STATUS);
  144. if (resp) {
  145. resp->status = status;
  146. resp->resp0 = hermes_read_regn(hw, RESP0);
  147. resp->resp1 = hermes_read_regn(hw, RESP1);
  148. resp->resp2 = hermes_read_regn(hw, RESP2);
  149. }
  150. hermes_write_regn(hw, EVACK, HERMES_EV_CMD);
  151. if (status & HERMES_STATUS_RESULT)
  152. err = -EIO;
  153. out:
  154. return err;
  155. }
  156. void hermes_struct_init(struct hermes *hw, void __iomem *address,
  157. int reg_spacing)
  158. {
  159. hw->iobase = address;
  160. hw->reg_spacing = reg_spacing;
  161. hw->inten = 0x0;
  162. hw->eeprom_pda = false;
  163. hw->ops = &hermes_ops_local;
  164. }
  165. EXPORT_SYMBOL(hermes_struct_init);
  166. static int hermes_init(struct hermes *hw)
  167. {
  168. u16 reg;
  169. int err = 0;
  170. int k;
  171. /* We don't want to be interrupted while resetting the chipset */
  172. hw->inten = 0x0;
  173. hermes_write_regn(hw, INTEN, 0);
  174. hermes_write_regn(hw, EVACK, 0xffff);
  175. /* Normally it's a "can't happen" for the command register to
  176. be busy when we go to issue a command because we are
  177. serializing all commands. However we want to have some
  178. chance of resetting the card even if it gets into a stupid
  179. state, so we actually wait to see if the command register
  180. will unbusy itself here. */
  181. k = CMD_BUSY_TIMEOUT;
  182. reg = hermes_read_regn(hw, CMD);
  183. while (k && (reg & HERMES_CMD_BUSY)) {
  184. if (reg == 0xffff) /* Special case - the card has probably been
  185. removed, so don't wait for the timeout */
  186. return -ENODEV;
  187. k--;
  188. udelay(1);
  189. reg = hermes_read_regn(hw, CMD);
  190. }
  191. /* No need to explicitly handle the timeout - if we've timed
  192. out hermes_issue_cmd() will probably return -EBUSY below */
  193. /* According to the documentation, EVSTAT may contain
  194. obsolete event occurrence information. We have to acknowledge
  195. it by writing EVACK. */
  196. reg = hermes_read_regn(hw, EVSTAT);
  197. hermes_write_regn(hw, EVACK, reg);
  198. /* We don't use hermes_docmd_wait here, because the reset wipes
  199. the magic constant in SWSUPPORT0 away, and it gets confused */
  200. err = hermes_doicmd_wait(hw, HERMES_CMD_INIT, 0, 0, 0, NULL);
  201. return err;
  202. }
  203. /* Issue a command to the chip, and (busy!) wait for it to
  204. * complete.
  205. *
  206. * Returns:
  207. * < 0 on internal error
  208. * 0 on success
  209. * > 0 on error returned by the firmware
  210. *
  211. * Callable from any context, but locking is your problem. */
  212. static int hermes_docmd_wait(struct hermes *hw, u16 cmd, u16 parm0,
  213. struct hermes_response *resp)
  214. {
  215. int err;
  216. int k;
  217. u16 reg;
  218. u16 status;
  219. err = hermes_issue_cmd(hw, cmd, parm0, 0, 0);
  220. if (err) {
  221. if (!hermes_present(hw)) {
  222. if (net_ratelimit())
  223. printk(KERN_WARNING "hermes @ %p: "
  224. "Card removed while issuing command "
  225. "0x%04x.\n", hw->iobase, cmd);
  226. err = -ENODEV;
  227. } else
  228. if (net_ratelimit())
  229. printk(KERN_ERR "hermes @ %p: "
  230. "Error %d issuing command 0x%04x.\n",
  231. hw->iobase, err, cmd);
  232. goto out;
  233. }
  234. reg = hermes_read_regn(hw, EVSTAT);
  235. k = CMD_COMPL_TIMEOUT;
  236. while ((!(reg & HERMES_EV_CMD)) && k) {
  237. k--;
  238. udelay(10);
  239. reg = hermes_read_regn(hw, EVSTAT);
  240. }
  241. if (!hermes_present(hw)) {
  242. printk(KERN_WARNING "hermes @ %p: Card removed "
  243. "while waiting for command 0x%04x completion.\n",
  244. hw->iobase, cmd);
  245. err = -ENODEV;
  246. goto out;
  247. }
  248. if (!(reg & HERMES_EV_CMD)) {
  249. printk(KERN_ERR "hermes @ %p: Timeout waiting for "
  250. "command 0x%04x completion.\n", hw->iobase, cmd);
  251. err = -ETIMEDOUT;
  252. goto out;
  253. }
  254. status = hermes_read_regn(hw, STATUS);
  255. if (resp) {
  256. resp->status = status;
  257. resp->resp0 = hermes_read_regn(hw, RESP0);
  258. resp->resp1 = hermes_read_regn(hw, RESP1);
  259. resp->resp2 = hermes_read_regn(hw, RESP2);
  260. }
  261. hermes_write_regn(hw, EVACK, HERMES_EV_CMD);
  262. if (status & HERMES_STATUS_RESULT)
  263. err = -EIO;
  264. out:
  265. return err;
  266. }
  267. static int hermes_allocate(struct hermes *hw, u16 size, u16 *fid)
  268. {
  269. int err = 0;
  270. int k;
  271. u16 reg;
  272. if ((size < HERMES_ALLOC_LEN_MIN) || (size > HERMES_ALLOC_LEN_MAX))
  273. return -EINVAL;
  274. err = hermes_docmd_wait(hw, HERMES_CMD_ALLOC, size, NULL);
  275. if (err)
  276. return err;
  277. reg = hermes_read_regn(hw, EVSTAT);
  278. k = ALLOC_COMPL_TIMEOUT;
  279. while ((!(reg & HERMES_EV_ALLOC)) && k) {
  280. k--;
  281. udelay(10);
  282. reg = hermes_read_regn(hw, EVSTAT);
  283. }
  284. if (!hermes_present(hw)) {
  285. printk(KERN_WARNING "hermes @ %p: "
  286. "Card removed waiting for frame allocation.\n",
  287. hw->iobase);
  288. return -ENODEV;
  289. }
  290. if (!(reg & HERMES_EV_ALLOC)) {
  291. printk(KERN_ERR "hermes @ %p: "
  292. "Timeout waiting for frame allocation\n",
  293. hw->iobase);
  294. return -ETIMEDOUT;
  295. }
  296. *fid = hermes_read_regn(hw, ALLOCFID);
  297. hermes_write_regn(hw, EVACK, HERMES_EV_ALLOC);
  298. return 0;
  299. }
  300. /* Set up a BAP to read a particular chunk of data from card's internal buffer.
  301. *
  302. * Returns:
  303. * < 0 on internal failure (errno)
  304. * 0 on success
  305. * > 0 on error
  306. * from firmware
  307. *
  308. * Callable from any context */
  309. static int hermes_bap_seek(struct hermes *hw, int bap, u16 id, u16 offset)
  310. {
  311. int sreg = bap ? HERMES_SELECT1 : HERMES_SELECT0;
  312. int oreg = bap ? HERMES_OFFSET1 : HERMES_OFFSET0;
  313. int k;
  314. u16 reg;
  315. /* Paranoia.. */
  316. if ((offset > HERMES_BAP_OFFSET_MAX) || (offset % 2))
  317. return -EINVAL;
  318. k = HERMES_BAP_BUSY_TIMEOUT;
  319. reg = hermes_read_reg(hw, oreg);
  320. while ((reg & HERMES_OFFSET_BUSY) && k) {
  321. k--;
  322. udelay(1);
  323. reg = hermes_read_reg(hw, oreg);
  324. }
  325. if (reg & HERMES_OFFSET_BUSY)
  326. return -ETIMEDOUT;
  327. /* Now we actually set up the transfer */
  328. hermes_write_reg(hw, sreg, id);
  329. hermes_write_reg(hw, oreg, offset);
  330. /* Wait for the BAP to be ready */
  331. k = HERMES_BAP_BUSY_TIMEOUT;
  332. reg = hermes_read_reg(hw, oreg);
  333. while ((reg & (HERMES_OFFSET_BUSY | HERMES_OFFSET_ERR)) && k) {
  334. k--;
  335. udelay(1);
  336. reg = hermes_read_reg(hw, oreg);
  337. }
  338. if (reg != offset) {
  339. printk(KERN_ERR "hermes @ %p: BAP%d offset %s: "
  340. "reg=0x%x id=0x%x offset=0x%x\n", hw->iobase, bap,
  341. (reg & HERMES_OFFSET_BUSY) ? "timeout" : "error",
  342. reg, id, offset);
  343. if (reg & HERMES_OFFSET_BUSY)
  344. return -ETIMEDOUT;
  345. return -EIO; /* error or wrong offset */
  346. }
  347. return 0;
  348. }
  349. /* Read a block of data from the chip's buffer, via the
  350. * BAP. Synchronization/serialization is the caller's problem. len
  351. * must be even.
  352. *
  353. * Returns:
  354. * < 0 on internal failure (errno)
  355. * 0 on success
  356. * > 0 on error from firmware
  357. */
  358. static int hermes_bap_pread(struct hermes *hw, int bap, void *buf, int len,
  359. u16 id, u16 offset)
  360. {
  361. int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
  362. int err = 0;
  363. if ((len < 0) || (len % 2))
  364. return -EINVAL;
  365. err = hermes_bap_seek(hw, bap, id, offset);
  366. if (err)
  367. goto out;
  368. /* Actually do the transfer */
  369. hermes_read_words(hw, dreg, buf, len / 2);
  370. out:
  371. return err;
  372. }
  373. /* Write a block of data to the chip's buffer, via the
  374. * BAP. Synchronization/serialization is the caller's problem.
  375. *
  376. * Returns:
  377. * < 0 on internal failure (errno)
  378. * 0 on success
  379. * > 0 on error from firmware
  380. */
  381. static int hermes_bap_pwrite(struct hermes *hw, int bap, const void *buf,
  382. int len, u16 id, u16 offset)
  383. {
  384. int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
  385. int err = 0;
  386. if (len < 0)
  387. return -EINVAL;
  388. err = hermes_bap_seek(hw, bap, id, offset);
  389. if (err)
  390. goto out;
  391. /* Actually do the transfer */
  392. hermes_write_bytes(hw, dreg, buf, len);
  393. out:
  394. return err;
  395. }
  396. /* Read a Length-Type-Value record from the card.
  397. *
  398. * If length is NULL, we ignore the length read from the card, and
  399. * read the entire buffer regardless. This is useful because some of
  400. * the configuration records appear to have incorrect lengths in
  401. * practice.
  402. *
  403. * Callable from user or bh context. */
  404. static int hermes_read_ltv(struct hermes *hw, int bap, u16 rid,
  405. unsigned bufsize, u16 *length, void *buf)
  406. {
  407. int err = 0;
  408. int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
  409. u16 rlength, rtype;
  410. unsigned nwords;
  411. if (bufsize % 2)
  412. return -EINVAL;
  413. err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS, rid, NULL);
  414. if (err)
  415. return err;
  416. err = hermes_bap_seek(hw, bap, rid, 0);
  417. if (err)
  418. return err;
  419. rlength = hermes_read_reg(hw, dreg);
  420. if (!rlength)
  421. return -ENODATA;
  422. rtype = hermes_read_reg(hw, dreg);
  423. if (length)
  424. *length = rlength;
  425. if (rtype != rid)
  426. printk(KERN_WARNING "hermes @ %p: %s(): "
  427. "rid (0x%04x) does not match type (0x%04x)\n",
  428. hw->iobase, __func__, rid, rtype);
  429. if (HERMES_RECLEN_TO_BYTES(rlength) > bufsize)
  430. printk(KERN_WARNING "hermes @ %p: "
  431. "Truncating LTV record from %d to %d bytes. "
  432. "(rid=0x%04x, len=0x%04x)\n", hw->iobase,
  433. HERMES_RECLEN_TO_BYTES(rlength), bufsize, rid, rlength);
  434. nwords = min((unsigned)rlength - 1, bufsize / 2);
  435. hermes_read_words(hw, dreg, buf, nwords);
  436. return 0;
  437. }
  438. static int hermes_write_ltv(struct hermes *hw, int bap, u16 rid,
  439. u16 length, const void *value)
  440. {
  441. int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
  442. int err = 0;
  443. unsigned count;
  444. if (length == 0)
  445. return -EINVAL;
  446. err = hermes_bap_seek(hw, bap, rid, 0);
  447. if (err)
  448. return err;
  449. hermes_write_reg(hw, dreg, length);
  450. hermes_write_reg(hw, dreg, rid);
  451. count = length - 1;
  452. hermes_write_bytes(hw, dreg, value, count << 1);
  453. err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS | HERMES_CMD_WRITE,
  454. rid, NULL);
  455. return err;
  456. }
  457. /*** Hermes AUX control ***/
  458. static inline void
  459. hermes_aux_setaddr(struct hermes *hw, u32 addr)
  460. {
  461. hermes_write_reg(hw, HERMES_AUXPAGE, (u16) (addr >> 7));
  462. hermes_write_reg(hw, HERMES_AUXOFFSET, (u16) (addr & 0x7F));
  463. }
  464. static inline int
  465. hermes_aux_control(struct hermes *hw, int enabled)
  466. {
  467. int desired_state = enabled ? HERMES_AUX_ENABLED : HERMES_AUX_DISABLED;
  468. int action = enabled ? HERMES_AUX_ENABLE : HERMES_AUX_DISABLE;
  469. int i;
  470. /* Already open? */
  471. if (hermes_read_reg(hw, HERMES_CONTROL) == desired_state)
  472. return 0;
  473. hermes_write_reg(hw, HERMES_PARAM0, HERMES_AUX_PW0);
  474. hermes_write_reg(hw, HERMES_PARAM1, HERMES_AUX_PW1);
  475. hermes_write_reg(hw, HERMES_PARAM2, HERMES_AUX_PW2);
  476. hermes_write_reg(hw, HERMES_CONTROL, action);
  477. for (i = 0; i < 20; i++) {
  478. udelay(10);
  479. if (hermes_read_reg(hw, HERMES_CONTROL) ==
  480. desired_state)
  481. return 0;
  482. }
  483. return -EBUSY;
  484. }
  485. /*** Hermes programming ***/
  486. /* About to start programming data (Hermes I)
  487. * offset is the entry point
  488. *
  489. * Spectrum_cs' Symbol fw does not require this
  490. * wl_lkm Agere fw does
  491. * Don't know about intersil
  492. */
  493. static int hermesi_program_init(struct hermes *hw, u32 offset)
  494. {
  495. int err;
  496. /* Disable interrupts?*/
  497. /*hw->inten = 0x0;*/
  498. /*hermes_write_regn(hw, INTEN, 0);*/
  499. /*hermes_set_irqmask(hw, 0);*/
  500. /* Acknowledge any outstanding command */
  501. hermes_write_regn(hw, EVACK, 0xFFFF);
  502. /* Using init_cmd_wait rather than cmd_wait */
  503. err = hw->ops->init_cmd_wait(hw,
  504. 0x0100 | HERMES_CMD_INIT,
  505. 0, 0, 0, NULL);
  506. if (err)
  507. return err;
  508. err = hw->ops->init_cmd_wait(hw,
  509. 0x0000 | HERMES_CMD_INIT,
  510. 0, 0, 0, NULL);
  511. if (err)
  512. return err;
  513. err = hermes_aux_control(hw, 1);
  514. pr_debug("AUX enable returned %d\n", err);
  515. if (err)
  516. return err;
  517. pr_debug("Enabling volatile, EP 0x%08x\n", offset);
  518. err = hw->ops->init_cmd_wait(hw,
  519. HERMES_PROGRAM_ENABLE_VOLATILE,
  520. offset & 0xFFFFu,
  521. offset >> 16,
  522. 0,
  523. NULL);
  524. pr_debug("PROGRAM_ENABLE returned %d\n", err);
  525. return err;
  526. }
  527. /* Done programming data (Hermes I)
  528. *
  529. * Spectrum_cs' Symbol fw does not require this
  530. * wl_lkm Agere fw does
  531. * Don't know about intersil
  532. */
  533. static int hermesi_program_end(struct hermes *hw)
  534. {
  535. struct hermes_response resp;
  536. int rc = 0;
  537. int err;
  538. rc = hw->ops->cmd_wait(hw, HERMES_PROGRAM_DISABLE, 0, &resp);
  539. pr_debug("PROGRAM_DISABLE returned %d, "
  540. "r0 0x%04x, r1 0x%04x, r2 0x%04x\n",
  541. rc, resp.resp0, resp.resp1, resp.resp2);
  542. if ((rc == 0) &&
  543. ((resp.status & HERMES_STATUS_CMDCODE) != HERMES_CMD_DOWNLD))
  544. rc = -EIO;
  545. err = hermes_aux_control(hw, 0);
  546. pr_debug("AUX disable returned %d\n", err);
  547. /* Acknowledge any outstanding command */
  548. hermes_write_regn(hw, EVACK, 0xFFFF);
  549. /* Reinitialise, ignoring return */
  550. (void) hw->ops->init_cmd_wait(hw, 0x0000 | HERMES_CMD_INIT,
  551. 0, 0, 0, NULL);
  552. return rc ? rc : err;
  553. }
  554. static int hermes_program_bytes(struct hermes *hw, const char *data,
  555. u32 addr, u32 len)
  556. {
  557. /* wl lkm splits the programming into chunks of 2000 bytes.
  558. * This restriction appears to come from USB. The PCMCIA
  559. * adapters can program the whole lot in one go */
  560. hermes_aux_setaddr(hw, addr);
  561. hermes_write_bytes(hw, HERMES_AUXDATA, data, len);
  562. return 0;
  563. }
  564. /* Read PDA from the adapter */
  565. static int hermes_read_pda(struct hermes *hw, __le16 *pda, u32 pda_addr,
  566. u16 pda_len)
  567. {
  568. int ret;
  569. u16 pda_size;
  570. u16 data_len = pda_len;
  571. __le16 *data = pda;
  572. if (hw->eeprom_pda) {
  573. /* PDA of spectrum symbol is in eeprom */
  574. /* Issue command to read EEPROM */
  575. ret = hw->ops->cmd_wait(hw, HERMES_CMD_READMIF, 0, NULL);
  576. if (ret)
  577. return ret;
  578. } else {
  579. /* wl_lkm does not include PDA size in the PDA area.
  580. * We will pad the information into pda, so other routines
  581. * don't have to be modified */
  582. pda[0] = cpu_to_le16(pda_len - 2);
  583. /* Includes CFG_PROD_DATA but not itself */
  584. pda[1] = cpu_to_le16(0x0800); /* CFG_PROD_DATA */
  585. data_len = pda_len - 4;
  586. data = pda + 2;
  587. }
  588. /* Open auxiliary port */
  589. ret = hermes_aux_control(hw, 1);
  590. pr_debug("AUX enable returned %d\n", ret);
  591. if (ret)
  592. return ret;
  593. /* Read PDA */
  594. hermes_aux_setaddr(hw, pda_addr);
  595. hermes_read_words(hw, HERMES_AUXDATA, data, data_len / 2);
  596. /* Close aux port */
  597. ret = hermes_aux_control(hw, 0);
  598. pr_debug("AUX disable returned %d\n", ret);
  599. /* Check PDA length */
  600. pda_size = le16_to_cpu(pda[0]);
  601. pr_debug("Actual PDA length %d, Max allowed %d\n",
  602. pda_size, pda_len);
  603. if (pda_size > pda_len)
  604. return -EINVAL;
  605. return 0;
  606. }
  607. static void hermes_lock_irqsave(spinlock_t *lock,
  608. unsigned long *flags) __acquires(lock)
  609. {
  610. spin_lock_irqsave(lock, *flags);
  611. }
  612. static void hermes_unlock_irqrestore(spinlock_t *lock,
  613. unsigned long *flags) __releases(lock)
  614. {
  615. spin_unlock_irqrestore(lock, *flags);
  616. }
  617. static void hermes_lock_irq(spinlock_t *lock) __acquires(lock)
  618. {
  619. spin_lock_irq(lock);
  620. }
  621. static void hermes_unlock_irq(spinlock_t *lock) __releases(lock)
  622. {
  623. spin_unlock_irq(lock);
  624. }
  625. /* Hermes operations for local buses */
  626. static const struct hermes_ops hermes_ops_local = {
  627. .init = hermes_init,
  628. .cmd_wait = hermes_docmd_wait,
  629. .init_cmd_wait = hermes_doicmd_wait,
  630. .allocate = hermes_allocate,
  631. .read_ltv = hermes_read_ltv,
  632. .write_ltv = hermes_write_ltv,
  633. .bap_pread = hermes_bap_pread,
  634. .bap_pwrite = hermes_bap_pwrite,
  635. .read_pda = hermes_read_pda,
  636. .program_init = hermesi_program_init,
  637. .program_end = hermesi_program_end,
  638. .program = hermes_program_bytes,
  639. .lock_irqsave = hermes_lock_irqsave,
  640. .unlock_irqrestore = hermes_unlock_irqrestore,
  641. .lock_irq = hermes_lock_irq,
  642. .unlock_irq = hermes_unlock_irq,
  643. };