iwl-io.h 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2003 - 2011 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. * Intel Linux Wireless <ilw@linux.intel.com>
  25. * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  26. *
  27. *****************************************************************************/
  28. #ifndef __il_io_h__
  29. #define __il_io_h__
  30. #include <linux/io.h>
  31. #include "iwl-dev.h"
  32. #include "iwl-debug.h"
  33. static inline void _il_write8(struct il_priv *il, u32 ofs, u8 val)
  34. {
  35. iowrite8(val, il->hw_base + ofs);
  36. }
  37. #define il_write8(il, ofs, val) _il_write8(il, ofs, val)
  38. static inline void _il_write32(struct il_priv *il, u32 ofs, u32 val)
  39. {
  40. iowrite32(val, il->hw_base + ofs);
  41. }
  42. #define il_write32(il, ofs, val) _il_write32(il, ofs, val)
  43. static inline u32 _il_read32(struct il_priv *il, u32 ofs)
  44. {
  45. u32 val = ioread32(il->hw_base + ofs);
  46. return val;
  47. }
  48. #define il_read32(p, o) _il_read32(p, o)
  49. #define IL_POLL_INTERVAL 10 /* microseconds */
  50. static inline int
  51. _il_poll_bit(struct il_priv *il, u32 addr,
  52. u32 bits, u32 mask, int timeout)
  53. {
  54. int t = 0;
  55. do {
  56. if ((_il_read32(il, addr) & mask) == (bits & mask))
  57. return t;
  58. udelay(IL_POLL_INTERVAL);
  59. t += IL_POLL_INTERVAL;
  60. } while (t < timeout);
  61. return -ETIMEDOUT;
  62. }
  63. #define il_poll_bit(p, a, b, m, t) _il_poll_bit(p, a, b, m, t)
  64. static inline void _il_set_bit(struct il_priv *il, u32 reg, u32 mask)
  65. {
  66. _il_write32(il, reg, _il_read32(il, reg) | mask);
  67. }
  68. static inline void il_set_bit(struct il_priv *p, u32 r, u32 m)
  69. {
  70. unsigned long reg_flags;
  71. spin_lock_irqsave(&p->reg_lock, reg_flags);
  72. _il_set_bit(p, r, m);
  73. spin_unlock_irqrestore(&p->reg_lock, reg_flags);
  74. }
  75. static inline void
  76. _il_clear_bit(struct il_priv *il, u32 reg, u32 mask)
  77. {
  78. _il_write32(il, reg, _il_read32(il, reg) & ~mask);
  79. }
  80. static inline void il_clear_bit(struct il_priv *p, u32 r, u32 m)
  81. {
  82. unsigned long reg_flags;
  83. spin_lock_irqsave(&p->reg_lock, reg_flags);
  84. _il_clear_bit(p, r, m);
  85. spin_unlock_irqrestore(&p->reg_lock, reg_flags);
  86. }
  87. static inline int _il_grab_nic_access(struct il_priv *il)
  88. {
  89. int ret;
  90. u32 val;
  91. /* this bit wakes up the NIC */
  92. _il_set_bit(il, CSR_GP_CNTRL,
  93. CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
  94. /*
  95. * These bits say the device is running, and should keep running for
  96. * at least a short while (at least as long as MAC_ACCESS_REQ stays 1),
  97. * but they do not indicate that embedded SRAM is restored yet;
  98. * 3945 and 4965 have volatile SRAM, and must save/restore contents
  99. * to/from host DRAM when sleeping/waking for power-saving.
  100. * Each direction takes approximately 1/4 millisecond; with this
  101. * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a
  102. * series of register accesses are expected (e.g. reading Event Log),
  103. * to keep device from sleeping.
  104. *
  105. * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that
  106. * SRAM is okay/restored. We don't check that here because this call
  107. * is just for hardware register access; but GP1 MAC_SLEEP check is a
  108. * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log).
  109. *
  110. */
  111. ret = _il_poll_bit(il, CSR_GP_CNTRL,
  112. CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
  113. (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
  114. CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);
  115. if (ret < 0) {
  116. val = _il_read32(il, CSR_GP_CNTRL);
  117. IL_ERR(
  118. "MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val);
  119. _il_write32(il, CSR_RESET,
  120. CSR_RESET_REG_FLAG_FORCE_NMI);
  121. return -EIO;
  122. }
  123. return 0;
  124. }
  125. #define il_grab_nic_access(il) _il_grab_nic_access(il)
  126. static inline void _il_release_nic_access(struct il_priv *il)
  127. {
  128. _il_clear_bit(il, CSR_GP_CNTRL,
  129. CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
  130. }
  131. #define il_release_nic_access(il) _il_release_nic_access(il)
  132. static inline u32 _il_read_direct32(struct il_priv *il, u32 reg)
  133. {
  134. return _il_read32(il, reg);
  135. }
  136. static inline u32 il_read_direct32(struct il_priv *il, u32 reg)
  137. {
  138. u32 value;
  139. unsigned long reg_flags;
  140. spin_lock_irqsave(&il->reg_lock, reg_flags);
  141. il_grab_nic_access(il);
  142. value = _il_read_direct32(il, reg);
  143. il_release_nic_access(il);
  144. spin_unlock_irqrestore(&il->reg_lock, reg_flags);
  145. return value;
  146. }
  147. static inline void _il_write_direct32(struct il_priv *il,
  148. u32 reg, u32 value)
  149. {
  150. _il_write32(il, reg, value);
  151. }
  152. static inline void
  153. il_write_direct32(struct il_priv *il, u32 reg, u32 value)
  154. {
  155. unsigned long reg_flags;
  156. spin_lock_irqsave(&il->reg_lock, reg_flags);
  157. if (!il_grab_nic_access(il)) {
  158. _il_write_direct32(il, reg, value);
  159. il_release_nic_access(il);
  160. }
  161. spin_unlock_irqrestore(&il->reg_lock, reg_flags);
  162. }
  163. static inline void il_write_reg_buf(struct il_priv *il,
  164. u32 reg, u32 len, u32 *values)
  165. {
  166. u32 count = sizeof(u32);
  167. if ((il != NULL) && (values != NULL)) {
  168. for (; 0 < len; len -= count, reg += count, values++)
  169. il_write_direct32(il, reg, *values);
  170. }
  171. }
  172. static inline int _il_poll_direct_bit(struct il_priv *il, u32 addr,
  173. u32 mask, int timeout)
  174. {
  175. int t = 0;
  176. do {
  177. if ((il_read_direct32(il, addr) & mask) == mask)
  178. return t;
  179. udelay(IL_POLL_INTERVAL);
  180. t += IL_POLL_INTERVAL;
  181. } while (t < timeout);
  182. return -ETIMEDOUT;
  183. }
  184. #define il_poll_direct_bit _il_poll_direct_bit
  185. static inline u32 _il_read_prph(struct il_priv *il, u32 reg)
  186. {
  187. _il_write_direct32(il, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
  188. rmb();
  189. return _il_read_direct32(il, HBUS_TARG_PRPH_RDAT);
  190. }
  191. static inline u32 il_read_prph(struct il_priv *il, u32 reg)
  192. {
  193. unsigned long reg_flags;
  194. u32 val;
  195. spin_lock_irqsave(&il->reg_lock, reg_flags);
  196. il_grab_nic_access(il);
  197. val = _il_read_prph(il, reg);
  198. il_release_nic_access(il);
  199. spin_unlock_irqrestore(&il->reg_lock, reg_flags);
  200. return val;
  201. }
  202. static inline void _il_write_prph(struct il_priv *il,
  203. u32 addr, u32 val)
  204. {
  205. _il_write_direct32(il, HBUS_TARG_PRPH_WADDR,
  206. ((addr & 0x0000FFFF) | (3 << 24)));
  207. wmb();
  208. _il_write_direct32(il, HBUS_TARG_PRPH_WDAT, val);
  209. }
  210. static inline void
  211. il_write_prph(struct il_priv *il, u32 addr, u32 val)
  212. {
  213. unsigned long reg_flags;
  214. spin_lock_irqsave(&il->reg_lock, reg_flags);
  215. if (!il_grab_nic_access(il)) {
  216. _il_write_prph(il, addr, val);
  217. il_release_nic_access(il);
  218. }
  219. spin_unlock_irqrestore(&il->reg_lock, reg_flags);
  220. }
  221. #define _il_set_bits_prph(il, reg, mask) \
  222. _il_write_prph(il, reg, (_il_read_prph(il, reg) | mask))
  223. static inline void
  224. il_set_bits_prph(struct il_priv *il, u32 reg, u32 mask)
  225. {
  226. unsigned long reg_flags;
  227. spin_lock_irqsave(&il->reg_lock, reg_flags);
  228. il_grab_nic_access(il);
  229. _il_set_bits_prph(il, reg, mask);
  230. il_release_nic_access(il);
  231. spin_unlock_irqrestore(&il->reg_lock, reg_flags);
  232. }
  233. #define _il_set_bits_mask_prph(il, reg, bits, mask) \
  234. _il_write_prph(il, reg, \
  235. ((_il_read_prph(il, reg) & mask) | bits))
  236. static inline void il_set_bits_mask_prph(struct il_priv *il, u32 reg,
  237. u32 bits, u32 mask)
  238. {
  239. unsigned long reg_flags;
  240. spin_lock_irqsave(&il->reg_lock, reg_flags);
  241. il_grab_nic_access(il);
  242. _il_set_bits_mask_prph(il, reg, bits, mask);
  243. il_release_nic_access(il);
  244. spin_unlock_irqrestore(&il->reg_lock, reg_flags);
  245. }
  246. static inline void il_clear_bits_prph(struct il_priv
  247. *il, u32 reg, u32 mask)
  248. {
  249. unsigned long reg_flags;
  250. u32 val;
  251. spin_lock_irqsave(&il->reg_lock, reg_flags);
  252. il_grab_nic_access(il);
  253. val = _il_read_prph(il, reg);
  254. _il_write_prph(il, reg, (val & ~mask));
  255. il_release_nic_access(il);
  256. spin_unlock_irqrestore(&il->reg_lock, reg_flags);
  257. }
  258. static inline u32 il_read_targ_mem(struct il_priv *il, u32 addr)
  259. {
  260. unsigned long reg_flags;
  261. u32 value;
  262. spin_lock_irqsave(&il->reg_lock, reg_flags);
  263. il_grab_nic_access(il);
  264. _il_write_direct32(il, HBUS_TARG_MEM_RADDR, addr);
  265. rmb();
  266. value = _il_read_direct32(il, HBUS_TARG_MEM_RDAT);
  267. il_release_nic_access(il);
  268. spin_unlock_irqrestore(&il->reg_lock, reg_flags);
  269. return value;
  270. }
  271. static inline void
  272. il_write_targ_mem(struct il_priv *il, u32 addr, u32 val)
  273. {
  274. unsigned long reg_flags;
  275. spin_lock_irqsave(&il->reg_lock, reg_flags);
  276. if (!il_grab_nic_access(il)) {
  277. _il_write_direct32(il, HBUS_TARG_MEM_WADDR, addr);
  278. wmb();
  279. _il_write_direct32(il, HBUS_TARG_MEM_WDAT, val);
  280. il_release_nic_access(il);
  281. }
  282. spin_unlock_irqrestore(&il->reg_lock, reg_flags);
  283. }
  284. static inline void
  285. il_write_targ_mem_buf(struct il_priv *il, u32 addr,
  286. u32 len, u32 *values)
  287. {
  288. unsigned long reg_flags;
  289. spin_lock_irqsave(&il->reg_lock, reg_flags);
  290. if (!il_grab_nic_access(il)) {
  291. _il_write_direct32(il, HBUS_TARG_MEM_WADDR, addr);
  292. wmb();
  293. for (; 0 < len; len -= sizeof(u32), values++)
  294. _il_write_direct32(il,
  295. HBUS_TARG_MEM_WDAT, *values);
  296. il_release_nic_access(il);
  297. }
  298. spin_unlock_irqrestore(&il->reg_lock, reg_flags);
  299. }
  300. #endif