iwl-4965-io.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved.
  4. *
  5. * Portions of this file are derived from the ipw3945 project.
  6. *
  7. * This program is free software; you can redistribute it and/or modify it
  8. * under the terms of version 2 of the GNU General Public License as
  9. * published by the Free Software Foundation.
  10. *
  11. * This program is distributed in the hope that it will be useful, but WITHOUT
  12. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  14. * more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along with
  17. * this program; if not, write to the Free Software Foundation, Inc.,
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
  19. *
  20. * The full GNU General Public License is included in this distribution in the
  21. * file called LICENSE.
  22. *
  23. * Contact Information:
  24. * James P. Ketrenos <ipw2100-admin@linux.intel.com>
  25. * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  26. *
  27. *****************************************************************************/
  28. #ifndef __iwl4965_io_h__
  29. #define __iwl4965_io_h__
  30. #include <linux/io.h>
  31. #include "iwl-4965-debug.h"
  32. /*
  33. * IO, register, and NIC memory access functions
  34. *
  35. * NOTE on naming convention and macro usage for these
  36. *
  37. * A single _ prefix before a an access function means that no state
  38. * check or debug information is printed when that function is called.
  39. *
  40. * A double __ prefix before an access function means that state is checked
  41. * and the current line number is printed in addition to any other debug output.
  42. *
  43. * The non-prefixed name is the #define that maps the caller into a
  44. * #define that provides the caller's __LINE__ to the double prefix version.
  45. *
  46. * If you wish to call the function without any debug or state checking,
  47. * you should use the single _ prefix version (as is used by dependent IO
  48. * routines, for example _iwl4965_read_direct32 calls the non-check version of
  49. * _iwl4965_read32.)
  50. *
  51. * These declarations are *extremely* useful in quickly isolating code deltas
  52. * which result in misconfiguring of the hardware I/O. In combination with
  53. * git-bisect and the IO debug level you can quickly determine the specific
  54. * commit which breaks the IO sequence to the hardware.
  55. *
  56. */
  57. #define _iwl4965_write32(iwl, ofs, val) writel((val), (iwl)->hw_base + (ofs))
  58. #ifdef CONFIG_IWL4965_DEBUG
  59. static inline void __iwl4965_write32(const char *f, u32 l, struct iwl4965_priv *iwl,
  60. u32 ofs, u32 val)
  61. {
  62. IWL_DEBUG_IO("write32(0x%08X, 0x%08X) - %s %d\n", ofs, val, f, l);
  63. _iwl4965_write32(iwl, ofs, val);
  64. }
  65. #define iwl4965_write32(iwl, ofs, val) \
  66. __iwl4965_write32(__FILE__, __LINE__, iwl, ofs, val)
  67. #else
  68. #define iwl4965_write32(iwl, ofs, val) _iwl4965_write32(iwl, ofs, val)
  69. #endif
  70. #define _iwl4965_read32(iwl, ofs) readl((iwl)->hw_base + (ofs))
  71. #ifdef CONFIG_IWL4965_DEBUG
  72. static inline u32 __iwl4965_read32(char *f, u32 l, struct iwl4965_priv *iwl, u32 ofs)
  73. {
  74. IWL_DEBUG_IO("read_direct32(0x%08X) - %s %d\n", ofs, f, l);
  75. return _iwl4965_read32(iwl, ofs);
  76. }
  77. #define iwl4965_read32(iwl, ofs) __iwl4965_read32(__FILE__, __LINE__, iwl, ofs)
  78. #else
  79. #define iwl4965_read32(p, o) _iwl4965_read32(p, o)
  80. #endif
  81. static inline int _iwl4965_poll_bit(struct iwl4965_priv *priv, u32 addr,
  82. u32 bits, u32 mask, int timeout)
  83. {
  84. int i = 0;
  85. do {
  86. if ((_iwl4965_read32(priv, addr) & mask) == (bits & mask))
  87. return i;
  88. mdelay(10);
  89. i += 10;
  90. } while (i < timeout);
  91. return -ETIMEDOUT;
  92. }
  93. #ifdef CONFIG_IWL4965_DEBUG
  94. static inline int __iwl4965_poll_bit(const char *f, u32 l,
  95. struct iwl4965_priv *priv, u32 addr,
  96. u32 bits, u32 mask, int timeout)
  97. {
  98. int ret = _iwl4965_poll_bit(priv, addr, bits, mask, timeout);
  99. if (unlikely(ret == -ETIMEDOUT))
  100. IWL_DEBUG_IO
  101. ("poll_bit(0x%08X, 0x%08X, 0x%08X) - timedout - %s %d\n",
  102. addr, bits, mask, f, l);
  103. else
  104. IWL_DEBUG_IO
  105. ("poll_bit(0x%08X, 0x%08X, 0x%08X) = 0x%08X - %s %d\n",
  106. addr, bits, mask, ret, f, l);
  107. return ret;
  108. }
  109. #define iwl4965_poll_bit(iwl, addr, bits, mask, timeout) \
  110. __iwl4965_poll_bit(__FILE__, __LINE__, iwl, addr, bits, mask, timeout)
  111. #else
  112. #define iwl4965_poll_bit(p, a, b, m, t) _iwl4965_poll_bit(p, a, b, m, t)
  113. #endif
  114. static inline void _iwl4965_set_bit(struct iwl4965_priv *priv, u32 reg, u32 mask)
  115. {
  116. _iwl4965_write32(priv, reg, _iwl4965_read32(priv, reg) | mask);
  117. }
  118. #ifdef CONFIG_IWL4965_DEBUG
  119. static inline void __iwl4965_set_bit(const char *f, u32 l,
  120. struct iwl4965_priv *priv, u32 reg, u32 mask)
  121. {
  122. u32 val = _iwl4965_read32(priv, reg) | mask;
  123. IWL_DEBUG_IO("set_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
  124. _iwl4965_write32(priv, reg, val);
  125. }
  126. #define iwl4965_set_bit(p, r, m) __iwl4965_set_bit(__FILE__, __LINE__, p, r, m)
  127. #else
  128. #define iwl4965_set_bit(p, r, m) _iwl4965_set_bit(p, r, m)
  129. #endif
  130. static inline void _iwl4965_clear_bit(struct iwl4965_priv *priv, u32 reg, u32 mask)
  131. {
  132. _iwl4965_write32(priv, reg, _iwl4965_read32(priv, reg) & ~mask);
  133. }
  134. #ifdef CONFIG_IWL4965_DEBUG
  135. static inline void __iwl4965_clear_bit(const char *f, u32 l,
  136. struct iwl4965_priv *priv, u32 reg, u32 mask)
  137. {
  138. u32 val = _iwl4965_read32(priv, reg) & ~mask;
  139. IWL_DEBUG_IO("clear_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
  140. _iwl4965_write32(priv, reg, val);
  141. }
  142. #define iwl4965_clear_bit(p, r, m) __iwl4965_clear_bit(__FILE__, __LINE__, p, r, m)
  143. #else
  144. #define iwl4965_clear_bit(p, r, m) _iwl4965_clear_bit(p, r, m)
  145. #endif
  146. static inline int _iwl4965_grab_nic_access(struct iwl4965_priv *priv)
  147. {
  148. int ret;
  149. u32 gp_ctl;
  150. #ifdef CONFIG_IWL4965_DEBUG
  151. if (atomic_read(&priv->restrict_refcnt))
  152. return 0;
  153. #endif
  154. if (test_bit(STATUS_RF_KILL_HW, &priv->status) ||
  155. test_bit(STATUS_RF_KILL_SW, &priv->status)) {
  156. IWL_WARNING("WARNING: Requesting MAC access during RFKILL "
  157. "wakes up NIC\n");
  158. /* 10 msec allows time for NIC to complete its data save */
  159. gp_ctl = _iwl4965_read32(priv, CSR_GP_CNTRL);
  160. if (gp_ctl & CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY) {
  161. IWL_DEBUG_RF_KILL("Wait for complete power-down, "
  162. "gpctl = 0x%08x\n", gp_ctl);
  163. mdelay(10);
  164. } else
  165. IWL_DEBUG_RF_KILL("power-down complete, "
  166. "gpctl = 0x%08x\n", gp_ctl);
  167. }
  168. /* this bit wakes up the NIC */
  169. _iwl4965_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
  170. ret = _iwl4965_poll_bit(priv, CSR_GP_CNTRL,
  171. CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
  172. (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
  173. CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 50);
  174. if (ret < 0) {
  175. IWL_ERROR("MAC is in deep sleep!\n");
  176. return -EIO;
  177. }
  178. #ifdef CONFIG_IWL4965_DEBUG
  179. atomic_inc(&priv->restrict_refcnt);
  180. #endif
  181. return 0;
  182. }
  183. #ifdef CONFIG_IWL4965_DEBUG
  184. static inline int __iwl4965_grab_nic_access(const char *f, u32 l,
  185. struct iwl4965_priv *priv)
  186. {
  187. if (atomic_read(&priv->restrict_refcnt))
  188. IWL_DEBUG_INFO("Grabbing access while already held at "
  189. "line %d.\n", l);
  190. IWL_DEBUG_IO("grabbing nic access - %s %d\n", f, l);
  191. return _iwl4965_grab_nic_access(priv);
  192. }
  193. #define iwl4965_grab_nic_access(priv) \
  194. __iwl4965_grab_nic_access(__FILE__, __LINE__, priv)
  195. #else
  196. #define iwl4965_grab_nic_access(priv) \
  197. _iwl4965_grab_nic_access(priv)
  198. #endif
  199. static inline void _iwl4965_release_nic_access(struct iwl4965_priv *priv)
  200. {
  201. #ifdef CONFIG_IWL4965_DEBUG
  202. if (atomic_dec_and_test(&priv->restrict_refcnt))
  203. #endif
  204. _iwl4965_clear_bit(priv, CSR_GP_CNTRL,
  205. CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
  206. }
  207. #ifdef CONFIG_IWL4965_DEBUG
  208. static inline void __iwl4965_release_nic_access(const char *f, u32 l,
  209. struct iwl4965_priv *priv)
  210. {
  211. if (atomic_read(&priv->restrict_refcnt) <= 0)
  212. IWL_ERROR("Release unheld nic access at line %d.\n", l);
  213. IWL_DEBUG_IO("releasing nic access - %s %d\n", f, l);
  214. _iwl4965_release_nic_access(priv);
  215. }
  216. #define iwl4965_release_nic_access(priv) \
  217. __iwl4965_release_nic_access(__FILE__, __LINE__, priv)
  218. #else
  219. #define iwl4965_release_nic_access(priv) \
  220. _iwl4965_release_nic_access(priv)
  221. #endif
  222. static inline u32 _iwl4965_read_direct32(struct iwl4965_priv *priv, u32 reg)
  223. {
  224. return _iwl4965_read32(priv, reg);
  225. }
  226. #ifdef CONFIG_IWL4965_DEBUG
  227. static inline u32 __iwl4965_read_direct32(const char *f, u32 l,
  228. struct iwl4965_priv *priv, u32 reg)
  229. {
  230. u32 value = _iwl4965_read_direct32(priv, reg);
  231. if (!atomic_read(&priv->restrict_refcnt))
  232. IWL_ERROR("Nic access not held from %s %d\n", f, l);
  233. IWL_DEBUG_IO("read_direct32(0x%4X) = 0x%08x - %s %d \n", reg, value,
  234. f, l);
  235. return value;
  236. }
  237. #define iwl4965_read_direct32(priv, reg) \
  238. __iwl4965_read_direct32(__FILE__, __LINE__, priv, reg)
  239. #else
  240. #define iwl4965_read_direct32 _iwl4965_read_direct32
  241. #endif
  242. static inline void _iwl4965_write_direct32(struct iwl4965_priv *priv,
  243. u32 reg, u32 value)
  244. {
  245. _iwl4965_write32(priv, reg, value);
  246. }
  247. #ifdef CONFIG_IWL4965_DEBUG
  248. static void __iwl4965_write_direct32(u32 line,
  249. struct iwl4965_priv *priv, u32 reg, u32 value)
  250. {
  251. if (!atomic_read(&priv->restrict_refcnt))
  252. IWL_ERROR("Nic access not held from line %d\n", line);
  253. _iwl4965_write_direct32(priv, reg, value);
  254. }
  255. #define iwl4965_write_direct32(priv, reg, value) \
  256. __iwl4965_write_direct32(__LINE__, priv, reg, value)
  257. #else
  258. #define iwl4965_write_direct32 _iwl4965_write_direct32
  259. #endif
  260. static inline void iwl4965_write_reg_buf(struct iwl4965_priv *priv,
  261. u32 reg, u32 len, u32 *values)
  262. {
  263. u32 count = sizeof(u32);
  264. if ((priv != NULL) && (values != NULL)) {
  265. for (; 0 < len; len -= count, reg += count, values++)
  266. _iwl4965_write_direct32(priv, reg, *values);
  267. }
  268. }
  269. static inline int _iwl4965_poll_direct_bit(struct iwl4965_priv *priv,
  270. u32 addr, u32 mask, int timeout)
  271. {
  272. int i = 0;
  273. do {
  274. if ((_iwl4965_read_direct32(priv, addr) & mask) == mask)
  275. return i;
  276. mdelay(10);
  277. i += 10;
  278. } while (i < timeout);
  279. return -ETIMEDOUT;
  280. }
  281. #ifdef CONFIG_IWL4965_DEBUG
  282. static inline int __iwl4965_poll_direct_bit(const char *f, u32 l,
  283. struct iwl4965_priv *priv,
  284. u32 addr, u32 mask, int timeout)
  285. {
  286. int ret = _iwl4965_poll_direct_bit(priv, addr, mask, timeout);
  287. if (unlikely(ret == -ETIMEDOUT))
  288. IWL_DEBUG_IO("poll_direct_bit(0x%08X, 0x%08X) - "
  289. "timedout - %s %d\n", addr, mask, f, l);
  290. else
  291. IWL_DEBUG_IO("poll_direct_bit(0x%08X, 0x%08X) = 0x%08X "
  292. "- %s %d\n", addr, mask, ret, f, l);
  293. return ret;
  294. }
  295. #define iwl4965_poll_direct_bit(iwl, addr, mask, timeout) \
  296. __iwl4965_poll_direct_bit(__FILE__, __LINE__, iwl, addr, mask, timeout)
  297. #else
  298. #define iwl4965_poll_direct_bit _iwl4965_poll_direct_bit
  299. #endif
  300. static inline u32 _iwl4965_read_prph(struct iwl4965_priv *priv, u32 reg)
  301. {
  302. _iwl4965_write_direct32(priv, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
  303. return _iwl4965_read_direct32(priv, HBUS_TARG_PRPH_RDAT);
  304. }
  305. #ifdef CONFIG_IWL4965_DEBUG
  306. static inline u32 __iwl4965_read_prph(u32 line, struct iwl4965_priv *priv, u32 reg)
  307. {
  308. if (!atomic_read(&priv->restrict_refcnt))
  309. IWL_ERROR("Nic access not held from line %d\n", line);
  310. return _iwl4965_read_prph(priv, reg);
  311. }
  312. #define iwl4965_read_prph(priv, reg) \
  313. __iwl4965_read_prph(__LINE__, priv, reg)
  314. #else
  315. #define iwl4965_read_prph _iwl4965_read_prph
  316. #endif
  317. static inline void _iwl4965_write_prph(struct iwl4965_priv *priv,
  318. u32 addr, u32 val)
  319. {
  320. _iwl4965_write_direct32(priv, HBUS_TARG_PRPH_WADDR,
  321. ((addr & 0x0000FFFF) | (3 << 24)));
  322. _iwl4965_write_direct32(priv, HBUS_TARG_PRPH_WDAT, val);
  323. }
  324. #ifdef CONFIG_IWL4965_DEBUG
  325. static inline void __iwl4965_write_prph(u32 line, struct iwl4965_priv *priv,
  326. u32 addr, u32 val)
  327. {
  328. if (!atomic_read(&priv->restrict_refcnt))
  329. IWL_ERROR("Nic access from line %d\n", line);
  330. _iwl4965_write_prph(priv, addr, val);
  331. }
  332. #define iwl4965_write_prph(priv, addr, val) \
  333. __iwl4965_write_prph(__LINE__, priv, addr, val);
  334. #else
  335. #define iwl4965_write_prph _iwl4965_write_prph
  336. #endif
  337. #define _iwl4965_set_bits_prph(priv, reg, mask) \
  338. _iwl4965_write_prph(priv, reg, (_iwl4965_read_prph(priv, reg) | mask))
  339. #ifdef CONFIG_IWL4965_DEBUG
  340. static inline void __iwl4965_set_bits_prph(u32 line, struct iwl4965_priv *priv,
  341. u32 reg, u32 mask)
  342. {
  343. if (!atomic_read(&priv->restrict_refcnt))
  344. IWL_ERROR("Nic access not held from line %d\n", line);
  345. _iwl4965_set_bits_prph(priv, reg, mask);
  346. }
  347. #define iwl4965_set_bits_prph(priv, reg, mask) \
  348. __iwl4965_set_bits_prph(__LINE__, priv, reg, mask)
  349. #else
  350. #define iwl4965_set_bits_prph _iwl4965_set_bits_prph
  351. #endif
  352. #define _iwl4965_set_bits_mask_prph(priv, reg, bits, mask) \
  353. _iwl4965_write_prph(priv, reg, ((_iwl4965_read_prph(priv, reg) & mask) | bits))
  354. #ifdef CONFIG_IWL4965_DEBUG
  355. static inline void __iwl4965_set_bits_mask_prph(u32 line,
  356. struct iwl4965_priv *priv, u32 reg, u32 bits, u32 mask)
  357. {
  358. if (!atomic_read(&priv->restrict_refcnt))
  359. IWL_ERROR("Nic access not held from line %d\n", line);
  360. _iwl4965_set_bits_mask_prph(priv, reg, bits, mask);
  361. }
  362. #define iwl4965_set_bits_mask_prph(priv, reg, bits, mask) \
  363. __iwl4965_set_bits_mask_prph(__LINE__, priv, reg, bits, mask)
  364. #else
  365. #define iwl4965_set_bits_mask_prph _iwl4965_set_bits_mask_prph
  366. #endif
  367. static inline void iwl4965_clear_bits_prph(struct iwl4965_priv
  368. *priv, u32 reg, u32 mask)
  369. {
  370. u32 val = _iwl4965_read_prph(priv, reg);
  371. _iwl4965_write_prph(priv, reg, (val & ~mask));
  372. }
  373. static inline u32 iwl4965_read_targ_mem(struct iwl4965_priv *priv, u32 addr)
  374. {
  375. iwl4965_write_direct32(priv, HBUS_TARG_MEM_RADDR, addr);
  376. return iwl4965_read_direct32(priv, HBUS_TARG_MEM_RDAT);
  377. }
  378. static inline void iwl4965_write_targ_mem(struct iwl4965_priv *priv, u32 addr, u32 val)
  379. {
  380. iwl4965_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
  381. iwl4965_write_direct32(priv, HBUS_TARG_MEM_WDAT, val);
  382. }
  383. static inline void iwl4965_write_targ_mem_buf(struct iwl4965_priv *priv, u32 addr,
  384. u32 len, u32 *values)
  385. {
  386. iwl4965_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
  387. for (; 0 < len; len -= sizeof(u32), values++)
  388. iwl4965_write_direct32(priv, HBUS_TARG_MEM_WDAT, *values);
  389. }
  390. #endif