reset.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925
  1. /*
  2. * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
  3. * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
  4. * Copyright (c) 2007-2008 Luis Rodriguez <mcgrof@winlab.rutgers.edu>
  5. * Copyright (c) 2007-2008 Pavel Roskin <proski@gnu.org>
  6. * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
  7. *
  8. * Permission to use, copy, modify, and distribute this software for any
  9. * purpose with or without fee is hereby granted, provided that the above
  10. * copyright notice and this permission notice appear in all copies.
  11. *
  12. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  13. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  14. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  15. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  16. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  17. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  18. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  19. *
  20. */
  21. #define _ATH5K_RESET
  22. /*****************************\
  23. Reset functions and helpers
  24. \*****************************/
  25. #include <linux/pci.h>
  26. #include "ath5k.h"
  27. #include "reg.h"
  28. #include "base.h"
  29. #include "debug.h"
  30. /**
  31. * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212
  32. *
  33. * @ah: the &struct ath5k_hw
  34. * @channel: the currently set channel upon reset
  35. *
  36. * Write the OFDM timings for the AR5212 upon reset. This is a helper for
  37. * ath5k_hw_reset(). This seems to tune the PLL a specified frequency
  38. * depending on the bandwidth of the channel.
  39. *
  40. */
  41. static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
  42. struct ieee80211_channel *channel)
  43. {
  44. /* Get exponent and mantissa and set it */
  45. u32 coef_scaled, coef_exp, coef_man,
  46. ds_coef_exp, ds_coef_man, clock;
  47. if (!(ah->ah_version == AR5K_AR5212) ||
  48. !(channel->hw_value & CHANNEL_OFDM))
  49. BUG();
  50. /* Seems there are two PLLs, one for baseband sampling and one
  51. * for tuning. Tuning basebands are 40 MHz or 80MHz when in
  52. * turbo. */
  53. clock = channel->hw_value & CHANNEL_TURBO ? 80 : 40;
  54. coef_scaled = ((5 * (clock << 24)) / 2) /
  55. channel->center_freq;
  56. for (coef_exp = 31; coef_exp > 0; coef_exp--)
  57. if ((coef_scaled >> coef_exp) & 0x1)
  58. break;
  59. if (!coef_exp)
  60. return -EINVAL;
  61. coef_exp = 14 - (coef_exp - 24);
  62. coef_man = coef_scaled +
  63. (1 << (24 - coef_exp - 1));
  64. ds_coef_man = coef_man >> (24 - coef_exp);
  65. ds_coef_exp = coef_exp - 16;
  66. AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
  67. AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man);
  68. AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
  69. AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp);
  70. return 0;
  71. }
  72. /*
  73. * index into rates for control rates, we can set it up like this because
  74. * this is only used for AR5212 and we know it supports G mode
  75. */
  76. static int control_rates[] =
  77. { 0, 1, 1, 1, 4, 4, 6, 6, 8, 8, 8, 8 };
  78. /**
  79. * ath5k_hw_write_rate_duration - set rate duration during hw resets
  80. *
  81. * @ah: the &struct ath5k_hw
  82. * @mode: one of enum ath5k_driver_mode
  83. *
  84. * Write the rate duration table upon hw reset. This is a helper for
  85. * ath5k_hw_reset(). It seems all this is doing is setting an ACK timeout for
  86. * the hardware for the current mode for each rate. The rates which are capable
  87. * of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have another
  88. * register for the short preamble ACK timeout calculation.
  89. */
  90. static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah,
  91. unsigned int mode)
  92. {
  93. struct ath5k_softc *sc = ah->ah_sc;
  94. struct ieee80211_rate *rate;
  95. unsigned int i;
  96. /* Write rate duration table */
  97. for (i = 0; i < sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates; i++) {
  98. u32 reg;
  99. u16 tx_time;
  100. rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[control_rates[i]];
  101. /* Set ACK timeout */
  102. reg = AR5K_RATE_DUR(rate->hw_value);
  103. /* An ACK frame consists of 10 bytes. If you add the FCS,
  104. * which ieee80211_generic_frame_duration() adds,
  105. * its 14 bytes. Note we use the control rate and not the
  106. * actual rate for this rate. See mac80211 tx.c
  107. * ieee80211_duration() for a brief description of
  108. * what rate we should choose to TX ACKs. */
  109. tx_time = le16_to_cpu(ieee80211_generic_frame_duration(sc->hw,
  110. sc->vif, 10, rate));
  111. ath5k_hw_reg_write(ah, tx_time, reg);
  112. if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE))
  113. continue;
  114. /*
  115. * We're not distinguishing short preamble here,
  116. * This is true, all we'll get is a longer value here
  117. * which is not necessarilly bad. We could use
  118. * export ieee80211_frame_duration() but that needs to be
  119. * fixed first to be properly used by mac802111 drivers:
  120. *
  121. * - remove erp stuff and let the routine figure ofdm
  122. * erp rates
  123. * - remove passing argument ieee80211_local as
  124. * drivers don't have access to it
  125. * - move drivers using ieee80211_generic_frame_duration()
  126. * to this
  127. */
  128. ath5k_hw_reg_write(ah, tx_time,
  129. reg + (AR5K_SET_SHORT_PREAMBLE << 2));
  130. }
  131. }
  132. /*
  133. * Reset chipset
  134. */
  135. static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val)
  136. {
  137. int ret;
  138. u32 mask = val ? val : ~0U;
  139. ATH5K_TRACE(ah->ah_sc);
  140. /* Read-and-clear RX Descriptor Pointer*/
  141. ath5k_hw_reg_read(ah, AR5K_RXDP);
  142. /*
  143. * Reset the device and wait until success
  144. */
  145. ath5k_hw_reg_write(ah, val, AR5K_RESET_CTL);
  146. /* Wait at least 128 PCI clocks */
  147. udelay(15);
  148. if (ah->ah_version == AR5K_AR5210) {
  149. val &= AR5K_RESET_CTL_CHIP;
  150. mask &= AR5K_RESET_CTL_CHIP;
  151. } else {
  152. val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
  153. mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
  154. }
  155. ret = ath5k_hw_register_timeout(ah, AR5K_RESET_CTL, mask, val, false);
  156. /*
  157. * Reset configuration register (for hw byte-swap). Note that this
  158. * is only set for big endian. We do the necessary magic in
  159. * AR5K_INIT_CFG.
  160. */
  161. if ((val & AR5K_RESET_CTL_PCU) == 0)
  162. ath5k_hw_reg_write(ah, AR5K_INIT_CFG, AR5K_CFG);
  163. return ret;
  164. }
  165. /*
  166. * Sleep control
  167. */
  168. int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
  169. bool set_chip, u16 sleep_duration)
  170. {
  171. unsigned int i;
  172. u32 staid, data;
  173. ATH5K_TRACE(ah->ah_sc);
  174. staid = ath5k_hw_reg_read(ah, AR5K_STA_ID1);
  175. switch (mode) {
  176. case AR5K_PM_AUTO:
  177. staid &= ~AR5K_STA_ID1_DEFAULT_ANTENNA;
  178. /* fallthrough */
  179. case AR5K_PM_NETWORK_SLEEP:
  180. if (set_chip)
  181. ath5k_hw_reg_write(ah,
  182. AR5K_SLEEP_CTL_SLE_ALLOW |
  183. sleep_duration,
  184. AR5K_SLEEP_CTL);
  185. staid |= AR5K_STA_ID1_PWR_SV;
  186. break;
  187. case AR5K_PM_FULL_SLEEP:
  188. if (set_chip)
  189. ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_SLP,
  190. AR5K_SLEEP_CTL);
  191. staid |= AR5K_STA_ID1_PWR_SV;
  192. break;
  193. case AR5K_PM_AWAKE:
  194. staid &= ~AR5K_STA_ID1_PWR_SV;
  195. if (!set_chip)
  196. goto commit;
  197. /* Preserve sleep duration */
  198. data = ath5k_hw_reg_read(ah, AR5K_SLEEP_CTL);
  199. if (data & 0xffc00000)
  200. data = 0;
  201. else
  202. data = data & 0xfffcffff;
  203. ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL);
  204. udelay(15);
  205. for (i = 50; i > 0; i--) {
  206. /* Check if the chip did wake up */
  207. if ((ath5k_hw_reg_read(ah, AR5K_PCICFG) &
  208. AR5K_PCICFG_SPWR_DN) == 0)
  209. break;
  210. /* Wait a bit and retry */
  211. udelay(200);
  212. ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL);
  213. }
  214. /* Fail if the chip didn't wake up */
  215. if (i <= 0)
  216. return -EIO;
  217. break;
  218. default:
  219. return -EINVAL;
  220. }
  221. commit:
  222. ah->ah_power_mode = mode;
  223. ath5k_hw_reg_write(ah, staid, AR5K_STA_ID1);
  224. return 0;
  225. }
  226. /*
  227. * Bring up MAC + PHY Chips
  228. */
  229. int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
  230. {
  231. struct pci_dev *pdev = ah->ah_sc->pdev;
  232. u32 turbo, mode, clock, bus_flags;
  233. int ret;
  234. turbo = 0;
  235. mode = 0;
  236. clock = 0;
  237. ATH5K_TRACE(ah->ah_sc);
  238. /* Wakeup the device */
  239. ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
  240. if (ret) {
  241. ATH5K_ERR(ah->ah_sc, "failed to wakeup the MAC Chip\n");
  242. return ret;
  243. }
  244. if (ah->ah_version != AR5K_AR5210) {
  245. /*
  246. * Get channel mode flags
  247. */
  248. if (ah->ah_radio >= AR5K_RF5112) {
  249. mode = AR5K_PHY_MODE_RAD_RF5112;
  250. clock = AR5K_PHY_PLL_RF5112;
  251. } else {
  252. mode = AR5K_PHY_MODE_RAD_RF5111; /*Zero*/
  253. clock = AR5K_PHY_PLL_RF5111; /*Zero*/
  254. }
  255. if (flags & CHANNEL_2GHZ) {
  256. mode |= AR5K_PHY_MODE_FREQ_2GHZ;
  257. clock |= AR5K_PHY_PLL_44MHZ;
  258. if (flags & CHANNEL_CCK) {
  259. mode |= AR5K_PHY_MODE_MOD_CCK;
  260. } else if (flags & CHANNEL_OFDM) {
  261. /* XXX Dynamic OFDM/CCK is not supported by the
  262. * AR5211 so we set MOD_OFDM for plain g (no
  263. * CCK headers) operation. We need to test
  264. * this, 5211 might support ofdm-only g after
  265. * all, there are also initial register values
  266. * in the code for g mode (see initvals.c). */
  267. if (ah->ah_version == AR5K_AR5211)
  268. mode |= AR5K_PHY_MODE_MOD_OFDM;
  269. else
  270. mode |= AR5K_PHY_MODE_MOD_DYN;
  271. } else {
  272. ATH5K_ERR(ah->ah_sc,
  273. "invalid radio modulation mode\n");
  274. return -EINVAL;
  275. }
  276. } else if (flags & CHANNEL_5GHZ) {
  277. mode |= AR5K_PHY_MODE_FREQ_5GHZ;
  278. clock |= AR5K_PHY_PLL_40MHZ;
  279. if (flags & CHANNEL_OFDM)
  280. mode |= AR5K_PHY_MODE_MOD_OFDM;
  281. else {
  282. ATH5K_ERR(ah->ah_sc,
  283. "invalid radio modulation mode\n");
  284. return -EINVAL;
  285. }
  286. } else {
  287. ATH5K_ERR(ah->ah_sc, "invalid radio frequency mode\n");
  288. return -EINVAL;
  289. }
  290. if (flags & CHANNEL_TURBO)
  291. turbo = AR5K_PHY_TURBO_MODE | AR5K_PHY_TURBO_SHORT;
  292. } else { /* Reset the device */
  293. /* ...enable Atheros turbo mode if requested */
  294. if (flags & CHANNEL_TURBO)
  295. ath5k_hw_reg_write(ah, AR5K_PHY_TURBO_MODE,
  296. AR5K_PHY_TURBO);
  297. }
  298. /* reseting PCI on PCI-E cards results card to hang
  299. * and always return 0xffff... so we ingore that flag
  300. * for PCI-E cards */
  301. bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
  302. /* Reset chipset */
  303. ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
  304. AR5K_RESET_CTL_BASEBAND | bus_flags);
  305. if (ret) {
  306. ATH5K_ERR(ah->ah_sc, "failed to reset the MAC Chip\n");
  307. return -EIO;
  308. }
  309. if (ah->ah_version == AR5K_AR5210)
  310. udelay(2300);
  311. /* ...wakeup again!*/
  312. ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
  313. if (ret) {
  314. ATH5K_ERR(ah->ah_sc, "failed to resume the MAC Chip\n");
  315. return ret;
  316. }
  317. /* ...final warm reset */
  318. if (ath5k_hw_nic_reset(ah, 0)) {
  319. ATH5K_ERR(ah->ah_sc, "failed to warm reset the MAC Chip\n");
  320. return -EIO;
  321. }
  322. if (ah->ah_version != AR5K_AR5210) {
  323. /* ...set the PHY operating mode */
  324. ath5k_hw_reg_write(ah, clock, AR5K_PHY_PLL);
  325. udelay(300);
  326. ath5k_hw_reg_write(ah, mode, AR5K_PHY_MODE);
  327. ath5k_hw_reg_write(ah, turbo, AR5K_PHY_TURBO);
  328. }
  329. return 0;
  330. }
  331. /*
  332. * Main reset function
  333. */
  334. int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
  335. struct ieee80211_channel *channel, bool change_channel)
  336. {
  337. struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
  338. struct pci_dev *pdev = ah->ah_sc->pdev;
  339. u32 data, s_seq, s_ant, s_led[3], dma_size;
  340. unsigned int i, mode, freq, ee_mode, ant[2];
  341. int ret;
  342. ATH5K_TRACE(ah->ah_sc);
  343. s_seq = 0;
  344. s_ant = 0;
  345. ee_mode = 0;
  346. freq = 0;
  347. mode = 0;
  348. /*
  349. * Save some registers before a reset
  350. */
  351. /*DCU/Antenna selection not available on 5210*/
  352. if (ah->ah_version != AR5K_AR5210) {
  353. if (change_channel) {
  354. /* Seq number for queue 0 -do this for all queues ? */
  355. s_seq = ath5k_hw_reg_read(ah,
  356. AR5K_QUEUE_DFS_SEQNUM(0));
  357. /*Default antenna*/
  358. s_ant = ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA);
  359. }
  360. }
  361. /*GPIOs*/
  362. s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) & AR5K_PCICFG_LEDSTATE;
  363. s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR);
  364. s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO);
  365. if (change_channel && ah->ah_rf_banks != NULL)
  366. ath5k_hw_get_rf_gain(ah);
  367. /*Wakeup the device*/
  368. ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false);
  369. if (ret)
  370. return ret;
  371. /*
  372. * Initialize operating mode
  373. */
  374. ah->ah_op_mode = op_mode;
  375. /*
  376. * 5111/5112 Settings
  377. * 5210 only comes with RF5110
  378. */
  379. if (ah->ah_version != AR5K_AR5210) {
  380. if (ah->ah_radio != AR5K_RF5111 &&
  381. ah->ah_radio != AR5K_RF5112 &&
  382. ah->ah_radio != AR5K_RF5413 &&
  383. ah->ah_radio != AR5K_RF2413 &&
  384. ah->ah_radio != AR5K_RF2425) {
  385. ATH5K_ERR(ah->ah_sc,
  386. "invalid phy radio: %u\n", ah->ah_radio);
  387. return -EINVAL;
  388. }
  389. switch (channel->hw_value & CHANNEL_MODES) {
  390. case CHANNEL_A:
  391. mode = AR5K_MODE_11A;
  392. freq = AR5K_INI_RFGAIN_5GHZ;
  393. ee_mode = AR5K_EEPROM_MODE_11A;
  394. break;
  395. case CHANNEL_G:
  396. mode = AR5K_MODE_11G;
  397. freq = AR5K_INI_RFGAIN_2GHZ;
  398. ee_mode = AR5K_EEPROM_MODE_11G;
  399. break;
  400. case CHANNEL_B:
  401. mode = AR5K_MODE_11B;
  402. freq = AR5K_INI_RFGAIN_2GHZ;
  403. ee_mode = AR5K_EEPROM_MODE_11B;
  404. break;
  405. case CHANNEL_T:
  406. mode = AR5K_MODE_11A_TURBO;
  407. freq = AR5K_INI_RFGAIN_5GHZ;
  408. ee_mode = AR5K_EEPROM_MODE_11A;
  409. break;
  410. /*Is this ok on 5211 too ?*/
  411. case CHANNEL_TG:
  412. mode = AR5K_MODE_11G_TURBO;
  413. freq = AR5K_INI_RFGAIN_2GHZ;
  414. ee_mode = AR5K_EEPROM_MODE_11G;
  415. break;
  416. case CHANNEL_XR:
  417. if (ah->ah_version == AR5K_AR5211) {
  418. ATH5K_ERR(ah->ah_sc,
  419. "XR mode not available on 5211");
  420. return -EINVAL;
  421. }
  422. mode = AR5K_MODE_XR;
  423. freq = AR5K_INI_RFGAIN_5GHZ;
  424. ee_mode = AR5K_EEPROM_MODE_11A;
  425. break;
  426. default:
  427. ATH5K_ERR(ah->ah_sc,
  428. "invalid channel: %d\n", channel->center_freq);
  429. return -EINVAL;
  430. }
  431. /* PHY access enable */
  432. ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
  433. }
  434. ret = ath5k_hw_write_initvals(ah, mode, change_channel);
  435. if (ret)
  436. return ret;
  437. /*
  438. * 5211/5212 Specific
  439. */
  440. if (ah->ah_version != AR5K_AR5210) {
  441. /*
  442. * Write initial RF gain settings
  443. * This should work for both 5111/5112
  444. */
  445. ret = ath5k_hw_rfgain(ah, freq);
  446. if (ret)
  447. return ret;
  448. mdelay(1);
  449. /*
  450. * Write some more initial register settings
  451. */
  452. if (ah->ah_version == AR5K_AR5212) {
  453. ath5k_hw_reg_write(ah, 0x0002a002, 0x982c);
  454. if (channel->hw_value == CHANNEL_G)
  455. if (ah->ah_mac_srev < AR5K_SREV_VER_AR2413)
  456. ath5k_hw_reg_write(ah, 0x00f80d80,
  457. 0x994c);
  458. else if (ah->ah_mac_srev < AR5K_SREV_VER_AR2424)
  459. ath5k_hw_reg_write(ah, 0x00380140,
  460. 0x994c);
  461. else if (ah->ah_mac_srev < AR5K_SREV_VER_AR2425)
  462. ath5k_hw_reg_write(ah, 0x00fc0ec0,
  463. 0x994c);
  464. else /* 2425 */
  465. ath5k_hw_reg_write(ah, 0x00fc0fc0,
  466. 0x994c);
  467. else
  468. ath5k_hw_reg_write(ah, 0x00000000, 0x994c);
  469. /* Some bits are disabled here, we know nothing about
  470. * register 0xa228 yet, most of the times this ends up
  471. * with a value 0x9b5 -haven't seen any dump with
  472. * a different value- */
  473. /* Got this from decompiling binary HAL */
  474. data = ath5k_hw_reg_read(ah, 0xa228);
  475. data &= 0xfffffdff;
  476. ath5k_hw_reg_write(ah, data, 0xa228);
  477. data = ath5k_hw_reg_read(ah, 0xa228);
  478. data &= 0xfffe03ff;
  479. ath5k_hw_reg_write(ah, data, 0xa228);
  480. data = 0;
  481. /* Just write 0x9b5 ? */
  482. /* ath5k_hw_reg_write(ah, 0x000009b5, 0xa228); */
  483. ath5k_hw_reg_write(ah, 0x0000000f, AR5K_SEQ_MASK);
  484. ath5k_hw_reg_write(ah, 0x00000000, 0xa254);
  485. ath5k_hw_reg_write(ah, 0x0000000e, AR5K_PHY_SCAL);
  486. }
  487. /* Fix for first revision of the RF5112 RF chipset */
  488. if (ah->ah_radio >= AR5K_RF5112 &&
  489. ah->ah_radio_5ghz_revision <
  490. AR5K_SREV_RAD_5112A) {
  491. ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD,
  492. AR5K_PHY_CCKTXCTL);
  493. if (channel->hw_value & CHANNEL_5GHZ)
  494. data = 0xffb81020;
  495. else
  496. data = 0xffb80d20;
  497. ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL);
  498. data = 0;
  499. }
  500. /*
  501. * Set TX power (FIXME)
  502. */
  503. ret = ath5k_hw_txpower(ah, channel, AR5K_TUNE_DEFAULT_TXPOWER);
  504. if (ret)
  505. return ret;
  506. /* Write rate duration table only on AR5212 and if
  507. * virtual interface has already been brought up
  508. * XXX: rethink this after new mode changes to
  509. * mac80211 are integrated */
  510. if (ah->ah_version == AR5K_AR5212 &&
  511. ah->ah_sc->vif != NULL)
  512. ath5k_hw_write_rate_duration(ah, mode);
  513. /*
  514. * Write RF registers
  515. */
  516. ret = ath5k_hw_rfregs(ah, channel, mode);
  517. if (ret)
  518. return ret;
  519. /*
  520. * Configure additional registers
  521. */
  522. /* Write OFDM timings on 5212*/
  523. if (ah->ah_version == AR5K_AR5212 &&
  524. channel->hw_value & CHANNEL_OFDM) {
  525. ret = ath5k_hw_write_ofdm_timings(ah, channel);
  526. if (ret)
  527. return ret;
  528. }
  529. /*Enable/disable 802.11b mode on 5111
  530. (enable 2111 frequency converter + CCK)*/
  531. if (ah->ah_radio == AR5K_RF5111) {
  532. if (mode == AR5K_MODE_11B)
  533. AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG,
  534. AR5K_TXCFG_B_MODE);
  535. else
  536. AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,
  537. AR5K_TXCFG_B_MODE);
  538. }
  539. /*
  540. * Set channel and calibrate the PHY
  541. */
  542. ret = ath5k_hw_channel(ah, channel);
  543. if (ret)
  544. return ret;
  545. /* Set antenna mode */
  546. AR5K_REG_MASKED_BITS(ah, AR5K_PHY_ANT_CTL,
  547. ah->ah_antenna[ee_mode][0], 0xfffffc06);
  548. /*
  549. * In case a fixed antenna was set as default
  550. * write the same settings on both AR5K_PHY_ANT_SWITCH_TABLE
  551. * registers.
  552. */
  553. if (s_ant != 0) {
  554. if (s_ant == AR5K_ANT_FIXED_A) /* 1 - Main */
  555. ant[0] = ant[1] = AR5K_ANT_FIXED_A;
  556. else /* 2 - Aux */
  557. ant[0] = ant[1] = AR5K_ANT_FIXED_B;
  558. } else {
  559. ant[0] = AR5K_ANT_FIXED_A;
  560. ant[1] = AR5K_ANT_FIXED_B;
  561. }
  562. ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[0]],
  563. AR5K_PHY_ANT_SWITCH_TABLE_0);
  564. ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[1]],
  565. AR5K_PHY_ANT_SWITCH_TABLE_1);
  566. /* Commit values from EEPROM */
  567. if (ah->ah_radio == AR5K_RF5111)
  568. AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL,
  569. AR5K_PHY_FRAME_CTL_TX_CLIP, ee->ee_tx_clip);
  570. ath5k_hw_reg_write(ah,
  571. AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]),
  572. AR5K_PHY_NFTHRES);
  573. AR5K_REG_MASKED_BITS(ah, AR5K_PHY_SETTLING,
  574. (ee->ee_switch_settling[ee_mode] << 7) & 0x3f80,
  575. 0xffffc07f);
  576. AR5K_REG_MASKED_BITS(ah, AR5K_PHY_GAIN,
  577. (ee->ee_ant_tx_rx[ee_mode] << 12) & 0x3f000,
  578. 0xfffc0fff);
  579. AR5K_REG_MASKED_BITS(ah, AR5K_PHY_DESIRED_SIZE,
  580. (ee->ee_adc_desired_size[ee_mode] & 0x00ff) |
  581. ((ee->ee_pga_desired_size[ee_mode] << 8) & 0xff00),
  582. 0xffff0000);
  583. ath5k_hw_reg_write(ah,
  584. (ee->ee_tx_end2xpa_disable[ee_mode] << 24) |
  585. (ee->ee_tx_end2xpa_disable[ee_mode] << 16) |
  586. (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) |
  587. (ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY_RF_CTL4);
  588. AR5K_REG_MASKED_BITS(ah, AR5K_PHY_RF_CTL3,
  589. ee->ee_tx_end2xlna_enable[ee_mode] << 8, 0xffff00ff);
  590. AR5K_REG_MASKED_BITS(ah, AR5K_PHY_NF,
  591. (ee->ee_thr_62[ee_mode] << 12) & 0x7f000, 0xfff80fff);
  592. AR5K_REG_MASKED_BITS(ah, AR5K_PHY_OFDM_SELFCORR, 4, 0xffffff01);
  593. AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
  594. AR5K_PHY_IQ_CORR_ENABLE |
  595. (ee->ee_i_cal[ee_mode] << AR5K_PHY_IQ_CORR_Q_I_COFF_S) |
  596. ee->ee_q_cal[ee_mode]);
  597. if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
  598. AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ,
  599. AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX,
  600. ee->ee_margin_tx_rx[ee_mode]);
  601. } else {
  602. mdelay(1);
  603. /* Disable phy and wait */
  604. ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
  605. mdelay(1);
  606. }
  607. /*
  608. * Restore saved values
  609. */
  610. /*DCU/Antenna selection not available on 5210*/
  611. if (ah->ah_version != AR5K_AR5210) {
  612. ath5k_hw_reg_write(ah, s_seq, AR5K_QUEUE_DFS_SEQNUM(0));
  613. ath5k_hw_reg_write(ah, s_ant, AR5K_DEFAULT_ANTENNA);
  614. }
  615. AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, s_led[0]);
  616. ath5k_hw_reg_write(ah, s_led[1], AR5K_GPIOCR);
  617. ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO);
  618. /*
  619. * Misc
  620. */
  621. /* XXX: add ah->aid once mac80211 gives this to us */
  622. ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
  623. ath5k_hw_set_opmode(ah);
  624. /*PISR/SISR Not available on 5210*/
  625. if (ah->ah_version != AR5K_AR5210) {
  626. ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR);
  627. /* If we later allow tuning for this, store into sc structure */
  628. data = AR5K_TUNE_RSSI_THRES |
  629. AR5K_TUNE_BMISS_THRES << AR5K_RSSI_THR_BMISS_S;
  630. ath5k_hw_reg_write(ah, data, AR5K_RSSI_THR);
  631. }
  632. /*
  633. * Set Rx/Tx DMA Configuration
  634. *
  635. * Set maximum DMA size (512) except for PCI-E cards since
  636. * it causes rx overruns and tx errors (tested on 5424 but since
  637. * rx overruns also occur on 5416/5418 with madwifi we set 128
  638. * for all PCI-E cards to be safe).
  639. *
  640. * In dumps this is 128 for allchips.
  641. *
  642. * XXX: need to check 5210 for this
  643. * TODO: Check out tx triger level, it's always 64 on dumps but I
  644. * guess we can tweak it and see how it goes ;-)
  645. */
  646. dma_size = (pdev->is_pcie) ? AR5K_DMASIZE_128B : AR5K_DMASIZE_512B;
  647. if (ah->ah_version != AR5K_AR5210) {
  648. AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
  649. AR5K_TXCFG_SDMAMR, dma_size);
  650. AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
  651. AR5K_RXCFG_SDMAMW, dma_size);
  652. }
  653. /*
  654. * Enable the PHY and wait until completion
  655. */
  656. ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
  657. /*
  658. * On 5211+ read activation -> rx delay
  659. * and use it.
  660. */
  661. if (ah->ah_version != AR5K_AR5210) {
  662. data = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
  663. AR5K_PHY_RX_DELAY_M;
  664. data = (channel->hw_value & CHANNEL_CCK) ?
  665. ((data << 2) / 22) : (data / 10);
  666. udelay(100 + (2 * data));
  667. data = 0;
  668. } else {
  669. mdelay(1);
  670. }
  671. /*
  672. * Perform ADC test (?)
  673. */
  674. data = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);
  675. ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1);
  676. for (i = 0; i <= 20; i++) {
  677. if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10))
  678. break;
  679. udelay(200);
  680. }
  681. ath5k_hw_reg_write(ah, data, AR5K_PHY_TST1);
  682. data = 0;
  683. /*
  684. * Start automatic gain calibration
  685. *
  686. * During AGC calibration RX path is re-routed to
  687. * a signal detector so we don't receive anything.
  688. *
  689. * This method is used to calibrate some static offsets
  690. * used together with on-the fly I/Q calibration (the
  691. * one performed via ath5k_hw_phy_calibrate), that doesn't
  692. * interrupt rx path.
  693. *
  694. * If we are in a noisy environment AGC calibration may time
  695. * out.
  696. */
  697. AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
  698. AR5K_PHY_AGCCTL_CAL);
  699. /* At the same time start I/Q calibration for QAM constellation
  700. * -no need for CCK- */
  701. ah->ah_calibration = false;
  702. if (!(mode == AR5K_MODE_11B)) {
  703. ah->ah_calibration = true;
  704. AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
  705. AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
  706. AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
  707. AR5K_PHY_IQ_RUN);
  708. }
  709. /* Wait for gain calibration to finish (we check for I/Q calibration
  710. * during ath5k_phy_calibrate) */
  711. if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
  712. AR5K_PHY_AGCCTL_CAL, 0, false)) {
  713. ATH5K_ERR(ah->ah_sc, "gain calibration timeout (%uMHz)\n",
  714. channel->center_freq);
  715. return -EAGAIN;
  716. }
  717. /*
  718. * Start noise floor calibration
  719. *
  720. * If we run NF calibration before AGC, it always times out.
  721. * Binary HAL starts NF and AGC calibration at the same time
  722. * and only waits for AGC to finish. I believe that's wrong because
  723. * during NF calibration, rx path is also routed to a detector, so if
  724. * it doesn't finish we won't have RX.
  725. *
  726. * XXX: Find an interval that's OK for all cards...
  727. */
  728. ret = ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
  729. if (ret)
  730. return ret;
  731. /*
  732. * Reset queues and start beacon timers at the end of the reset routine
  733. */
  734. for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) {
  735. /*No QCU on 5210*/
  736. if (ah->ah_version != AR5K_AR5210)
  737. AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(i), i);
  738. ret = ath5k_hw_reset_tx_queue(ah, i);
  739. if (ret) {
  740. ATH5K_ERR(ah->ah_sc,
  741. "failed to reset TX queue #%d\n", i);
  742. return ret;
  743. }
  744. }
  745. /* Pre-enable interrupts on 5211/5212*/
  746. if (ah->ah_version != AR5K_AR5210)
  747. ath5k_hw_set_imr(ah, AR5K_INT_RX | AR5K_INT_TX |
  748. AR5K_INT_FATAL);
  749. /*
  750. * Set RF kill flags if supported by the device (read from the EEPROM)
  751. * Disable gpio_intr for now since it results system hang.
  752. * TODO: Handle this in ath5k_intr
  753. */
  754. #if 0
  755. if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) {
  756. ath5k_hw_set_gpio_input(ah, 0);
  757. ah->ah_gpio[0] = ath5k_hw_get_gpio(ah, 0);
  758. if (ah->ah_gpio[0] == 0)
  759. ath5k_hw_set_gpio_intr(ah, 0, 1);
  760. else
  761. ath5k_hw_set_gpio_intr(ah, 0, 0);
  762. }
  763. #endif
  764. /*
  765. * Set the 32MHz reference clock on 5212 phy clock sleep register
  766. *
  767. * TODO: Find out how to switch to external 32Khz clock to save power
  768. */
  769. if (ah->ah_version == AR5K_AR5212) {
  770. ath5k_hw_reg_write(ah, AR5K_PHY_SCR_32MHZ, AR5K_PHY_SCR);
  771. ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT);
  772. ath5k_hw_reg_write(ah, AR5K_PHY_SCAL_32MHZ, AR5K_PHY_SCAL);
  773. ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK);
  774. ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY);
  775. ath5k_hw_reg_write(ah, ah->ah_phy_spending, AR5K_PHY_SPENDING);
  776. data = ath5k_hw_reg_read(ah, AR5K_USEC_5211) & 0xffffc07f ;
  777. data |= (ah->ah_phy_spending == AR5K_PHY_SPENDING_18) ?
  778. 0x00000f80 : 0x00001380 ;
  779. ath5k_hw_reg_write(ah, data, AR5K_USEC_5211);
  780. data = 0;
  781. }
  782. if (ah->ah_version == AR5K_AR5212) {
  783. ath5k_hw_reg_write(ah, 0x000100aa, 0x8118);
  784. ath5k_hw_reg_write(ah, 0x00003210, 0x811c);
  785. ath5k_hw_reg_write(ah, 0x00000052, 0x8108);
  786. if (ah->ah_mac_srev >= AR5K_SREV_VER_AR2413)
  787. ath5k_hw_reg_write(ah, 0x00000004, 0x8120);
  788. }
  789. /*
  790. * Disable beacons and reset the register
  791. */
  792. AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE |
  793. AR5K_BEACON_RESET_TSF);
  794. return 0;
  795. }
  796. #undef _ATH5K_RESET