600-0003-rt2x00-rt2800-serialize-shared-memory-access.patch 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. From 250a1b520cd7fdc0df4fc3fedea9066913f49ecf Mon Sep 17 00:00:00 2001
  2. From: Gabor Juhos <juhosg@openwrt.org>
  3. Date: Sat, 17 Aug 2013 19:31:42 +0200
  4. Subject: [PATCH] rt2x00: rt2800: serialize shared memory access
  5. The shared memory of the rt2800 devices is accessible
  6. through the register offset range between 0x4000 and
  7. 0x8000. The size of this range is 16KB only and on
  8. devices which have more than 16KB of shared memory either
  9. the low or the high part of the memory is accessible at a
  10. time.
  11. Serialize all accesses to the shared memory by a mutex,
  12. in order to avoid concurrent use of that.
  13. Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
  14. ---
  15. Changes since v1: ---
  16. ---
  17. drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 55 +++++++++++++++++++++++++++++-
  18. drivers/net/wireless/ralink/rt2x00/rt2800lib.h | 32 +++++++++++++++++
  19. drivers/net/wireless/ralink/rt2x00/rt2800mmio.c | 26 ++++++++++++++
  20. drivers/net/wireless/ralink/rt2x00/rt2800mmio.h | 4 +++
  21. drivers/net/wireless/ralink/rt2x00/rt2800pci.c | 14 ++++++++
  22. drivers/net/wireless/ralink/rt2x00/rt2800soc.c | 3 ++
  23. drivers/net/wireless/ralink/rt2x00/rt2800usb.c | 31 +++++++++++++++++
  24. 7 files changed, 164 insertions(+), 1 deletion(-)
  25. --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
  26. +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
  27. @@ -451,11 +451,13 @@ void rt2800_mcu_request(struct rt2x00_de
  28. rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_CMD_TOKEN, token);
  29. rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_ARG0, arg0);
  30. rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_ARG1, arg1);
  31. + rt2800_shared_mem_lock(rt2x00dev);
  32. rt2800_register_write_lock(rt2x00dev, H2M_MAILBOX_CSR, reg);
  33. reg = 0;
  34. rt2x00_set_field32(&reg, HOST_CMD_CSR_HOST_COMMAND, command);
  35. rt2800_register_write_lock(rt2x00dev, HOST_CMD_CSR, reg);
  36. + rt2800_shared_mem_unlock(rt2x00dev);
  37. }
  38. mutex_unlock(&rt2x00dev->csr_mutex);
  39. @@ -674,7 +676,9 @@ int rt2800_load_firmware(struct rt2x00_d
  40. * Wait for device to stabilize.
  41. */
  42. for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
  43. + rt2800_shared_mem_lock(rt2x00dev);
  44. rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
  45. + rt2800_shared_mem_unlock(rt2x00dev);
  46. if (rt2x00_get_field32(reg, PBF_SYS_CTRL_READY))
  47. break;
  48. msleep(1);
  49. @@ -694,10 +698,16 @@ int rt2800_load_firmware(struct rt2x00_d
  50. /*
  51. * Initialize firmware.
  52. */
  53. + rt2800_shared_mem_lock(rt2x00dev);
  54. rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
  55. rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
  56. + rt2800_shared_mem_unlock(rt2x00dev);
  57. +
  58. if (rt2x00_is_usb(rt2x00dev)) {
  59. + rt2800_shared_mem_lock(rt2x00dev);
  60. rt2800_register_write(rt2x00dev, H2M_INT_SRC, 0);
  61. + rt2800_shared_mem_unlock(rt2x00dev);
  62. +
  63. rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0);
  64. }
  65. msleep(1);
  66. @@ -1035,8 +1045,10 @@ void rt2800_write_beacon(struct queue_en
  67. beacon_base = rt2800_hw_beacon_base(rt2x00dev, entry->entry_idx);
  68. + rt2800_shared_mem_lock(rt2x00dev);
  69. rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
  70. entry->skb->len + padding_len);
  71. + rt2800_shared_mem_unlock(rt2x00dev);
  72. __set_bit(ENTRY_BCN_ENABLED, &entry->flags);
  73. /*
  74. @@ -1066,6 +1078,8 @@ static inline void rt2800_clear_beacon_r
  75. beacon_base = rt2800_hw_beacon_base(rt2x00dev, index);
  76. + rt2800_shared_mem_lock(rt2x00dev);
  77. +
  78. /*
  79. * For the Beacon base registers we only need to clear
  80. * the whole TXWI which (when set to 0) will invalidate
  81. @@ -1073,6 +1087,8 @@ static inline void rt2800_clear_beacon_r
  82. */
  83. for (i = 0; i < txwi_desc_size; i += sizeof(__le32))
  84. rt2800_register_write(rt2x00dev, beacon_base + i, 0);
  85. +
  86. + rt2800_shared_mem_unlock(rt2x00dev);
  87. }
  88. void rt2800_clear_beacon(struct queue_entry *entry)
  89. @@ -1261,7 +1277,9 @@ static void rt2800_delete_wcid_attr(stru
  90. {
  91. u32 offset;
  92. offset = MAC_WCID_ATTR_ENTRY(wcid);
  93. + rt2800_shared_mem_lock(rt2x00dev);
  94. rt2800_register_write(rt2x00dev, offset, 0);
  95. + rt2800_shared_mem_unlock(rt2x00dev);
  96. }
  97. static void rt2800_config_wcid_attr_bssidx(struct rt2x00_dev *rt2x00dev,
  98. @@ -1274,11 +1292,13 @@ static void rt2800_config_wcid_attr_bssi
  99. * The BSS Idx numbers is split in a main value of 3 bits,
  100. * and a extended field for adding one additional bit to the value.
  101. */
  102. + rt2800_shared_mem_lock(rt2x00dev);
  103. rt2800_register_read(rt2x00dev, offset, &reg);
  104. rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_BSS_IDX, (bssidx & 0x7));
  105. rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_BSS_IDX_EXT,
  106. (bssidx & 0x8) >> 3);
  107. rt2800_register_write(rt2x00dev, offset, reg);
  108. + rt2800_shared_mem_unlock(rt2x00dev);
  109. }
  110. static void rt2800_config_wcid_attr_cipher(struct rt2x00_dev *rt2x00dev,
  111. @@ -1291,6 +1311,7 @@ static void rt2800_config_wcid_attr_ciph
  112. offset = MAC_WCID_ATTR_ENTRY(key->hw_key_idx);
  113. + rt2800_shared_mem_lock(rt2x00dev);
  114. if (crypto->cmd == SET_KEY) {
  115. rt2800_register_read(rt2x00dev, offset, &reg);
  116. rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_KEYTAB,
  117. @@ -1315,6 +1336,7 @@ static void rt2800_config_wcid_attr_ciph
  118. rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_RX_WIUDF, 0);
  119. rt2800_register_write(rt2x00dev, offset, reg);
  120. }
  121. + rt2800_shared_mem_unlock(rt2x00dev);
  122. offset = MAC_IVEIV_ENTRY(key->hw_key_idx);
  123. @@ -1324,8 +1346,11 @@ static void rt2800_config_wcid_attr_ciph
  124. (crypto->cipher == CIPHER_AES))
  125. iveiv_entry.iv[3] |= 0x20;
  126. iveiv_entry.iv[3] |= key->keyidx << 6;
  127. +
  128. + rt2800_shared_mem_lock(rt2x00dev);
  129. rt2800_register_multiwrite(rt2x00dev, offset,
  130. &iveiv_entry, sizeof(iveiv_entry));
  131. + rt2800_shared_mem_unlock(rt2x00dev);
  132. }
  133. int rt2800_config_shared_key(struct rt2x00_dev *rt2x00dev,
  134. @@ -1348,8 +1373,11 @@ int rt2800_config_shared_key(struct rt2x
  135. sizeof(key_entry.rx_mic));
  136. offset = SHARED_KEY_ENTRY(key->hw_key_idx);
  137. +
  138. + rt2800_shared_mem_lock(rt2x00dev);
  139. rt2800_register_multiwrite(rt2x00dev, offset,
  140. &key_entry, sizeof(key_entry));
  141. + rt2800_shared_mem_unlock(rt2x00dev);
  142. }
  143. /*
  144. @@ -1364,10 +1392,12 @@ int rt2800_config_shared_key(struct rt2x
  145. offset = SHARED_KEY_MODE_ENTRY(key->hw_key_idx / 8);
  146. + rt2800_shared_mem_lock(rt2x00dev);
  147. rt2800_register_read(rt2x00dev, offset, &reg);
  148. rt2x00_set_field32(&reg, field,
  149. (crypto->cmd == SET_KEY) * crypto->cipher);
  150. rt2800_register_write(rt2x00dev, offset, reg);
  151. + rt2800_shared_mem_unlock(rt2x00dev);
  152. /*
  153. * Update WCID information
  154. @@ -1405,8 +1435,11 @@ int rt2800_config_pairwise_key(struct rt
  155. sizeof(key_entry.rx_mic));
  156. offset = PAIRWISE_KEY_ENTRY(key->hw_key_idx);
  157. +
  158. + rt2800_shared_mem_lock(rt2x00dev);
  159. rt2800_register_multiwrite(rt2x00dev, offset,
  160. &key_entry, sizeof(key_entry));
  161. + rt2800_shared_mem_unlock(rt2x00dev);
  162. }
  163. /*
  164. @@ -4885,14 +4918,19 @@ static int rt2800_init_registers(struct
  165. /*
  166. * ASIC will keep garbage value after boot, clear encryption keys.
  167. */
  168. + rt2800_shared_mem_lock(rt2x00dev);
  169. for (i = 0; i < 4; i++)
  170. rt2800_register_write(rt2x00dev,
  171. SHARED_KEY_MODE_ENTRY(i), 0);
  172. + rt2800_shared_mem_unlock(rt2x00dev);
  173. for (i = 0; i < 256; i++) {
  174. rt2800_config_wcid(rt2x00dev, NULL, i);
  175. rt2800_delete_wcid_attr(rt2x00dev, i);
  176. +
  177. + rt2800_shared_mem_lock(rt2x00dev);
  178. rt2800_register_write(rt2x00dev, MAC_IVEIV_ENTRY(i), 0);
  179. + rt2800_shared_mem_unlock(rt2x00dev);
  180. }
  181. /*
  182. @@ -5018,8 +5056,10 @@ static int rt2800_wait_bbp_ready(struct
  183. * BBP was enabled after firmware was loaded,
  184. * but we need to reactivate it now.
  185. */
  186. + rt2800_shared_mem_lock(rt2x00dev);
  187. rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
  188. rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
  189. + rt2800_shared_mem_unlock(rt2x00dev);
  190. msleep(1);
  191. for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
  192. @@ -6715,11 +6755,19 @@ int rt2800_enable_radio(struct rt2x00_de
  193. /*
  194. * Send signal during boot time to initialize firmware.
  195. */
  196. + rt2800_shared_mem_lock(rt2x00dev);
  197. rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
  198. rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
  199. - if (rt2x00_is_usb(rt2x00dev))
  200. + rt2800_shared_mem_unlock(rt2x00dev);
  201. +
  202. + if (rt2x00_is_usb(rt2x00dev)) {
  203. + rt2800_shared_mem_lock(rt2x00dev);
  204. rt2800_register_write(rt2x00dev, H2M_INT_SRC, 0);
  205. + rt2800_shared_mem_unlock(rt2x00dev);
  206. + }
  207. +
  208. rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0);
  209. +
  210. msleep(1);
  211. /*
  212. @@ -7726,6 +7774,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r
  213. int retval;
  214. u32 reg;
  215. + rt2800_shared_mem_init_lock(rt2x00dev);
  216. +
  217. retval = rt2800_probe_rt(rt2x00dev);
  218. if (retval)
  219. return retval;
  220. @@ -7809,8 +7859,11 @@ void rt2800_get_key_seq(struct ieee80211
  221. return;
  222. offset = MAC_IVEIV_ENTRY(key->hw_key_idx);
  223. +
  224. + rt2800_shared_mem_lock(rt2x00dev);
  225. rt2800_register_multiread(rt2x00dev, offset,
  226. &iveiv_entry, sizeof(iveiv_entry));
  227. + rt2800_shared_mem_unlock(rt2x00dev);
  228. memcpy(&seq->tkip.iv16, &iveiv_entry.iv[0], 2);
  229. memcpy(&seq->tkip.iv32, &iveiv_entry.iv[4], 4);
  230. --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
  231. +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
  232. @@ -38,6 +38,11 @@ struct rt2800_drv_data {
  233. DECLARE_BITMAP(sta_ids, STA_IDS_SIZE);
  234. unsigned long rt2800_flags;
  235. +
  236. + union {
  237. + spinlock_t spin;
  238. + struct mutex mutex;
  239. + } shmem_lock;
  240. };
  241. struct rt2800_ops {
  242. @@ -68,6 +73,10 @@ struct rt2800_ops {
  243. const u8 *data, const size_t len);
  244. int (*drv_init_registers)(struct rt2x00_dev *rt2x00dev);
  245. __le32 *(*drv_get_txwi)(struct queue_entry *entry);
  246. +
  247. + void (*shmem_init_lock)(struct rt2x00_dev *rt2x00dev);
  248. + void (*shmem_lock)(struct rt2x00_dev *rt2x00dev);
  249. + void (*shmem_unlock)(struct rt2x00_dev *rt2x00dev);
  250. };
  251. static inline bool rt2800_has_high_shared_mem(struct rt2x00_dev *rt2x00dev)
  252. @@ -77,6 +86,29 @@ static inline bool rt2800_has_high_share
  253. return test_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);
  254. }
  255. +static inline void rt2800_shared_mem_init_lock(struct rt2x00_dev *rt2x00dev)
  256. +{
  257. + const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
  258. +
  259. + rt2800ops->shmem_init_lock(rt2x00dev);
  260. +}
  261. +
  262. +static inline void rt2800_shared_mem_lock(struct rt2x00_dev *rt2x00dev)
  263. +{
  264. + const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
  265. +
  266. + if (rt2800_has_high_shared_mem(rt2x00dev))
  267. + rt2800ops->shmem_lock(rt2x00dev);
  268. +}
  269. +
  270. +static inline void rt2800_shared_mem_unlock(struct rt2x00_dev *rt2x00dev)
  271. +{
  272. + const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
  273. +
  274. + if (rt2800_has_high_shared_mem(rt2x00dev))
  275. + rt2800ops->shmem_unlock(rt2x00dev);
  276. +}
  277. +
  278. static inline void rt2800_register_read(struct rt2x00_dev *rt2x00dev,
  279. const unsigned int offset,
  280. u32 *value)
  281. --- a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c
  282. +++ b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c
  283. @@ -820,8 +820,10 @@ int rt2800mmio_init_registers(struct rt2
  284. rt2x00_set_field32(&reg, WPDMA_RST_IDX_DRX_IDX0, 1);
  285. rt2x00mmio_register_write(rt2x00dev, WPDMA_RST_IDX, reg);
  286. + rt2800_shared_mem_lock(rt2x00dev);
  287. rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f);
  288. rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00);
  289. + rt2800_shared_mem_unlock(rt2x00dev);
  290. if (rt2x00_is_pcie(rt2x00dev) &&
  291. (rt2x00_rt(rt2x00dev, RT3090) ||
  292. @@ -865,6 +867,30 @@ int rt2800mmio_enable_radio(struct rt2x0
  293. }
  294. EXPORT_SYMBOL_GPL(rt2800mmio_enable_radio);
  295. +void rt2800mmio_shmem_init_lock(struct rt2x00_dev *rt2x00dev)
  296. +{
  297. + struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
  298. +
  299. + spin_lock_init(&drv_data->shmem_lock.spin);
  300. +}
  301. +EXPORT_SYMBOL_GPL(rt2800mmio_shmem_init_lock);
  302. +
  303. +void rt2800mmio_shmem_lock(struct rt2x00_dev *rt2x00dev)
  304. +{
  305. + struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
  306. +
  307. + spin_lock_bh(&drv_data->shmem_lock.spin);
  308. +}
  309. +EXPORT_SYMBOL_GPL(rt2800mmio_shmem_lock);
  310. +
  311. +void rt2800mmio_shmem_unlock(struct rt2x00_dev *rt2x00dev)
  312. +{
  313. + struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
  314. +
  315. + spin_unlock_bh(&drv_data->shmem_lock.spin);
  316. +}
  317. +EXPORT_SYMBOL_GPL(rt2800mmio_shmem_unlock);
  318. +
  319. MODULE_AUTHOR(DRV_PROJECT);
  320. MODULE_VERSION(DRV_VERSION);
  321. MODULE_DESCRIPTION("rt2800 MMIO library");
  322. --- a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.h
  323. +++ b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.h
  324. @@ -160,4 +160,8 @@ int rt2800mmio_init_registers(struct rt2
  325. /* Device state switch handlers. */
  326. int rt2800mmio_enable_radio(struct rt2x00_dev *rt2x00dev);
  327. +void rt2800mmio_shmem_init_lock(struct rt2x00_dev *rt2x00dev);
  328. +void rt2800mmio_shmem_lock(struct rt2x00_dev *rt2x00dev);
  329. +void rt2800mmio_shmem_unlock(struct rt2x00_dev *rt2x00dev);
  330. +
  331. #endif /* RT2800MMIO_H */
  332. --- a/drivers/net/wireless/ralink/rt2x00/rt2800pci.c
  333. +++ b/drivers/net/wireless/ralink/rt2x00/rt2800pci.c
  334. @@ -69,7 +69,9 @@ static void rt2800pci_mcu_status(struct
  335. return;
  336. for (i = 0; i < 200; i++) {
  337. + rt2800_shared_mem_lock(rt2x00dev);
  338. rt2x00mmio_register_read(rt2x00dev, H2M_MAILBOX_CID, &reg);
  339. + rt2800_shared_mem_unlock(rt2x00dev);
  340. if ((rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD0) == token) ||
  341. (rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD1) == token) ||
  342. @@ -83,8 +85,10 @@ static void rt2800pci_mcu_status(struct
  343. if (i == 200)
  344. rt2x00_err(rt2x00dev, "MCU request failed, no response from hardware\n");
  345. + rt2800_shared_mem_lock(rt2x00dev);
  346. rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
  347. rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
  348. + rt2800_shared_mem_unlock(rt2x00dev);
  349. }
  350. static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
  351. @@ -184,6 +188,8 @@ static int rt2800pci_write_firmware(stru
  352. */
  353. reg = 0;
  354. rt2x00_set_field32(&reg, PBF_SYS_CTRL_HOST_RAM_WRITE, 1);
  355. +
  356. + rt2800_shared_mem_lock(rt2x00dev);
  357. rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, reg);
  358. /*
  359. @@ -197,6 +203,7 @@ static int rt2800pci_write_firmware(stru
  360. rt2x00mmio_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
  361. rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
  362. + rt2800_shared_mem_unlock(rt2x00dev);
  363. return 0;
  364. }
  365. @@ -213,8 +220,10 @@ static int rt2800pci_enable_radio(struct
  366. return retval;
  367. /* After resume MCU_BOOT_SIGNAL will trash these. */
  368. + rt2800_shared_mem_lock(rt2x00dev);
  369. rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
  370. rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
  371. + rt2800_shared_mem_unlock(rt2x00dev);
  372. rt2800_mcu_request(rt2x00dev, MCU_SLEEP, TOKEN_RADIO_OFF, 0xff, 0x02);
  373. rt2800pci_mcu_status(rt2x00dev, TOKEN_RADIO_OFF);
  374. @@ -233,10 +242,12 @@ static int rt2800pci_set_state(struct rt
  375. 0, 0x02);
  376. rt2800pci_mcu_status(rt2x00dev, TOKEN_WAKEUP);
  377. } else if (state == STATE_SLEEP) {
  378. + rt2800_shared_mem_lock(rt2x00dev);
  379. rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_STATUS,
  380. 0xffffffff);
  381. rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID,
  382. 0xffffffff);
  383. + rt2800_shared_mem_unlock(rt2x00dev);
  384. rt2800_mcu_request(rt2x00dev, MCU_SLEEP, TOKEN_SLEEP,
  385. 0xff, 0x01);
  386. }
  387. @@ -337,6 +348,9 @@ static const struct rt2800_ops rt2800pci
  388. .drv_write_firmware = rt2800pci_write_firmware,
  389. .drv_init_registers = rt2800mmio_init_registers,
  390. .drv_get_txwi = rt2800mmio_get_txwi,
  391. + .shmem_init_lock = rt2800mmio_shmem_init_lock,
  392. + .shmem_lock = rt2800mmio_shmem_lock,
  393. + .shmem_unlock = rt2800mmio_shmem_unlock,
  394. };
  395. static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
  396. --- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
  397. +++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
  398. @@ -176,6 +176,9 @@ static const struct rt2800_ops rt2800soc
  399. .drv_write_firmware = rt2800soc_write_firmware,
  400. .drv_init_registers = rt2800mmio_init_registers,
  401. .drv_get_txwi = rt2800mmio_get_txwi,
  402. + .shmem_init_lock = rt2800mmio_shmem_init_lock,
  403. + .shmem_lock = rt2800mmio_shmem_lock,
  404. + .shmem_unlock = rt2800mmio_shmem_unlock,
  405. };
  406. static const struct rt2x00lib_ops rt2800soc_rt2x00_ops = {
  407. --- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
  408. +++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
  409. @@ -51,6 +51,27 @@ static bool rt2800usb_hwcrypt_disabled(s
  410. return modparam_nohwcrypt;
  411. }
  412. +static void rt2800usb_shmem_init_lock(struct rt2x00_dev *rt2x00dev)
  413. +{
  414. + struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
  415. +
  416. + mutex_init(&drv_data->shmem_lock.mutex);
  417. +}
  418. +
  419. +static void rt2800usb_shmem_lock(struct rt2x00_dev *rt2x00dev)
  420. +{
  421. + struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
  422. +
  423. + mutex_lock(&drv_data->shmem_lock.mutex);
  424. +}
  425. +
  426. +static void rt2800usb_shmem_unlock(struct rt2x00_dev *rt2x00dev)
  427. +{
  428. + struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
  429. +
  430. + mutex_unlock(&drv_data->shmem_lock.mutex);
  431. +}
  432. +
  433. /*
  434. * Queue handlers.
  435. */
  436. @@ -299,8 +320,10 @@ static int rt2800usb_write_firmware(stru
  437. data + offset, length);
  438. }
  439. + rt2800_shared_mem_lock(rt2x00dev);
  440. rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
  441. rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
  442. + rt2800_shared_mem_unlock(rt2x00dev);
  443. /*
  444. * Send firmware request to device to load firmware,
  445. @@ -315,7 +338,10 @@ static int rt2800usb_write_firmware(stru
  446. }
  447. msleep(10);
  448. +
  449. + rt2800_shared_mem_lock(rt2x00dev);
  450. rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
  451. + rt2800_shared_mem_unlock(rt2x00dev);
  452. return 0;
  453. }
  454. @@ -333,8 +359,10 @@ static int rt2800usb_init_registers(stru
  455. if (rt2800_wait_csr_ready(rt2x00dev))
  456. return -EBUSY;
  457. + rt2800_shared_mem_lock(rt2x00dev);
  458. rt2x00usb_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
  459. rt2x00usb_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000);
  460. + rt2800_shared_mem_unlock(rt2x00dev);
  461. reg = 0;
  462. rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_CSR, 1);
  463. @@ -863,6 +891,9 @@ static const struct rt2800_ops rt2800usb
  464. .drv_write_firmware = rt2800usb_write_firmware,
  465. .drv_init_registers = rt2800usb_init_registers,
  466. .drv_get_txwi = rt2800usb_get_txwi,
  467. + .shmem_init_lock = rt2800usb_shmem_init_lock,
  468. + .shmem_lock = rt2800usb_shmem_lock,
  469. + .shmem_unlock = rt2800usb_shmem_unlock,
  470. };
  471. static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {