905-wlcore-wl12xx-wl18xx-simplify-fw_status-handling.patch 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731
  1. Instead of splitting the fw_status into 2 and using some
  2. complex calculations, read the fw status and let each low-level
  3. driver (wl12xx/wl18xx) convert it into a common struct.
  4. This is required for the upcoming fw api changes, which
  5. break the current logic anyway.
  6. Signed-off-by: Eliad Peller <[email protected]>
  7. ---
  8. drivers/net/wireless/ti/wl12xx/main.c | 35 ++++++++++-
  9. drivers/net/wireless/ti/wl12xx/wl12xx.h | 50 ++++++++++++++++
  10. drivers/net/wireless/ti/wl18xx/main.c | 39 ++++++++++++-
  11. drivers/net/wireless/ti/wl18xx/tx.c | 4 +-
  12. drivers/net/wireless/ti/wl18xx/wl18xx.h | 53 +++++++++++++++++
  13. drivers/net/wireless/ti/wlcore/cmd.c | 11 +++-
  14. drivers/net/wireless/ti/wlcore/hw_ops.h | 9 +++
  15. drivers/net/wireless/ti/wlcore/main.c | 96 +++++++++++++++----------------
  16. drivers/net/wireless/ti/wlcore/rx.c | 2 +-
  17. drivers/net/wireless/ti/wlcore/rx.h | 2 +-
  18. drivers/net/wireless/ti/wlcore/wlcore.h | 7 ++-
  19. drivers/net/wireless/ti/wlcore/wlcore_i.h | 72 ++++++++++-------------
  20. 12 files changed, 277 insertions(+), 103 deletions(-)
  21. --- a/drivers/net/wireless/ti/wl12xx/main.c
  22. +++ b/drivers/net/wireless/ti/wl12xx/main.c
  23. @@ -1378,7 +1378,7 @@ static u32 wl12xx_get_rx_packet_len(stru
  24. static int wl12xx_tx_delayed_compl(struct wl1271 *wl)
  25. {
  26. - if (wl->fw_status_1->tx_results_counter ==
  27. + if (wl->fw_status->tx_results_counter ==
  28. (wl->tx_results_count & 0xff))
  29. return 0;
  30. @@ -1438,6 +1438,37 @@ out:
  31. return ret;
  32. }
  33. +static void wl12xx_convert_fw_status(struct wl1271 *wl, void *raw_fw_status,
  34. + struct wl_fw_status *fw_status)
  35. +{
  36. + struct wl12xx_fw_status *int_fw_status = raw_fw_status;
  37. +
  38. + fw_status->intr = le32_to_cpu(int_fw_status->intr);
  39. + fw_status->fw_rx_counter = int_fw_status->fw_rx_counter;
  40. + fw_status->drv_rx_counter = int_fw_status->drv_rx_counter;
  41. + fw_status->tx_results_counter = int_fw_status->tx_results_counter;
  42. + fw_status->rx_pkt_descs = int_fw_status->rx_pkt_descs;
  43. +
  44. + fw_status->fw_localtime = le32_to_cpu(int_fw_status->fw_localtime);
  45. + fw_status->link_ps_bitmap = le32_to_cpu(int_fw_status->link_ps_bitmap);
  46. + fw_status->link_fast_bitmap =
  47. + le32_to_cpu(int_fw_status->link_fast_bitmap);
  48. + fw_status->total_released_blks =
  49. + le32_to_cpu(int_fw_status->total_released_blks);
  50. + fw_status->tx_total = le32_to_cpu(int_fw_status->tx_total);
  51. +
  52. + fw_status->counters.tx_released_pkts =
  53. + int_fw_status->counters.tx_released_pkts;
  54. + fw_status->counters.tx_lnk_free_pkts =
  55. + int_fw_status->counters.tx_lnk_free_pkts;
  56. + fw_status->counters.tx_voice_released_blks =
  57. + int_fw_status->counters.tx_voice_released_blks;
  58. + fw_status->counters.tx_last_rate =
  59. + int_fw_status->counters.tx_last_rate;
  60. +
  61. + fw_status->log_start_addr = le32_to_cpu(int_fw_status->log_start_addr);
  62. +}
  63. +
  64. static u32 wl12xx_sta_get_ap_rate_mask(struct wl1271 *wl,
  65. struct wl12xx_vif *wlvif)
  66. {
  67. @@ -1677,6 +1708,7 @@ static struct wlcore_ops wl12xx_ops = {
  68. .tx_delayed_compl = wl12xx_tx_delayed_compl,
  69. .hw_init = wl12xx_hw_init,
  70. .init_vif = NULL,
  71. + .convert_fw_status = wl12xx_convert_fw_status,
  72. .sta_get_ap_rate_mask = wl12xx_sta_get_ap_rate_mask,
  73. .get_pg_ver = wl12xx_get_pg_ver,
  74. .get_mac = wl12xx_get_mac,
  75. @@ -1725,6 +1757,7 @@ static int wl12xx_setup(struct wl1271 *w
  76. wl->band_rate_to_idx = wl12xx_band_rate_to_idx;
  77. wl->hw_tx_rate_tbl_size = WL12XX_CONF_HW_RXTX_RATE_MAX;
  78. wl->hw_min_ht_rate = WL12XX_CONF_HW_RXTX_RATE_MCS0;
  79. + wl->fw_status_len = sizeof(struct wl12xx_fw_status);
  80. wl->fw_status_priv_len = 0;
  81. wl->stats.fw_stats_len = sizeof(struct wl12xx_acx_statistics);
  82. wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ, &wl12xx_ht_cap);
  83. --- a/drivers/net/wireless/ti/wl12xx/wl12xx.h
  84. +++ b/drivers/net/wireless/ti/wl12xx/wl12xx.h
  85. @@ -79,4 +79,54 @@ struct wl12xx_priv {
  86. struct wl127x_rx_mem_pool_addr *rx_mem_addr;
  87. };
  88. +struct wl12xx_fw_packet_counters {
  89. + /* Cumulative counter of released packets per AC */
  90. + u8 tx_released_pkts[NUM_TX_QUEUES];
  91. +
  92. + /* Cumulative counter of freed packets per HLID */
  93. + u8 tx_lnk_free_pkts[WL12XX_MAX_LINKS];
  94. +
  95. + /* Cumulative counter of released Voice memory blocks */
  96. + u8 tx_voice_released_blks;
  97. +
  98. + /* Tx rate of the last transmitted packet */
  99. + u8 tx_last_rate;
  100. +
  101. + u8 padding[2];
  102. +} __packed;
  103. +
  104. +/* FW status registers */
  105. +struct wl12xx_fw_status {
  106. + __le32 intr;
  107. + u8 fw_rx_counter;
  108. + u8 drv_rx_counter;
  109. + u8 reserved;
  110. + u8 tx_results_counter;
  111. + __le32 rx_pkt_descs[WL12XX_NUM_RX_DESCRIPTORS];
  112. +
  113. + __le32 fw_localtime;
  114. +
  115. + /*
  116. + * A bitmap (where each bit represents a single HLID)
  117. + * to indicate if the station is in PS mode.
  118. + */
  119. + __le32 link_ps_bitmap;
  120. +
  121. + /*
  122. + * A bitmap (where each bit represents a single HLID) to indicate
  123. + * if the station is in Fast mode
  124. + */
  125. + __le32 link_fast_bitmap;
  126. +
  127. + /* Cumulative counter of total released mem blocks since FW-reset */
  128. + __le32 total_released_blks;
  129. +
  130. + /* Size (in Memory Blocks) of TX pool */
  131. + __le32 tx_total;
  132. +
  133. + struct wl12xx_fw_packet_counters counters;
  134. +
  135. + __le32 log_start_addr;
  136. +} __packed;
  137. +
  138. #endif /* __WL12XX_PRIV_H__ */
  139. --- a/drivers/net/wireless/ti/wl18xx/main.c
  140. +++ b/drivers/net/wireless/ti/wl18xx/main.c
  141. @@ -1133,6 +1133,39 @@ static int wl18xx_hw_init(struct wl1271
  142. return ret;
  143. }
  144. +static void wl18xx_convert_fw_status(struct wl1271 *wl, void *raw_fw_status,
  145. + struct wl_fw_status *fw_status)
  146. +{
  147. + struct wl18xx_fw_status *int_fw_status = raw_fw_status;
  148. +
  149. + fw_status->intr = le32_to_cpu(int_fw_status->intr);
  150. + fw_status->fw_rx_counter = int_fw_status->fw_rx_counter;
  151. + fw_status->drv_rx_counter = int_fw_status->drv_rx_counter;
  152. + fw_status->tx_results_counter = int_fw_status->tx_results_counter;
  153. + fw_status->rx_pkt_descs = int_fw_status->rx_pkt_descs;
  154. +
  155. + fw_status->fw_localtime = le32_to_cpu(int_fw_status->fw_localtime);
  156. + fw_status->link_ps_bitmap = le32_to_cpu(int_fw_status->link_ps_bitmap);
  157. + fw_status->link_fast_bitmap =
  158. + le32_to_cpu(int_fw_status->link_fast_bitmap);
  159. + fw_status->total_released_blks =
  160. + le32_to_cpu(int_fw_status->total_released_blks);
  161. + fw_status->tx_total = le32_to_cpu(int_fw_status->tx_total);
  162. +
  163. + fw_status->counters.tx_released_pkts =
  164. + int_fw_status->counters.tx_released_pkts;
  165. + fw_status->counters.tx_lnk_free_pkts =
  166. + int_fw_status->counters.tx_lnk_free_pkts;
  167. + fw_status->counters.tx_voice_released_blks =
  168. + int_fw_status->counters.tx_voice_released_blks;
  169. + fw_status->counters.tx_last_rate =
  170. + int_fw_status->counters.tx_last_rate;
  171. +
  172. + fw_status->log_start_addr = le32_to_cpu(int_fw_status->log_start_addr);
  173. +
  174. + fw_status->priv = &int_fw_status->priv;
  175. +}
  176. +
  177. static void wl18xx_set_tx_desc_csum(struct wl1271 *wl,
  178. struct wl1271_tx_hw_descr *desc,
  179. struct sk_buff *skb)
  180. @@ -1572,7 +1605,7 @@ static bool wl18xx_lnk_high_prio(struct
  181. {
  182. u8 thold;
  183. struct wl18xx_fw_status_priv *status_priv =
  184. - (struct wl18xx_fw_status_priv *)wl->fw_status_2->priv;
  185. + (struct wl18xx_fw_status_priv *)wl->fw_status->priv;
  186. u32 suspend_bitmap = le32_to_cpu(status_priv->link_suspend_bitmap);
  187. /* suspended links are never high priority */
  188. @@ -1594,7 +1627,7 @@ static bool wl18xx_lnk_low_prio(struct w
  189. {
  190. u8 thold;
  191. struct wl18xx_fw_status_priv *status_priv =
  192. - (struct wl18xx_fw_status_priv *)wl->fw_status_2->priv;
  193. + (struct wl18xx_fw_status_priv *)wl->fw_status->priv;
  194. u32 suspend_bitmap = le32_to_cpu(status_priv->link_suspend_bitmap);
  195. if (test_bit(hlid, (unsigned long *)&suspend_bitmap))
  196. @@ -1632,6 +1665,7 @@ static struct wlcore_ops wl18xx_ops = {
  197. .tx_immediate_compl = wl18xx_tx_immediate_completion,
  198. .tx_delayed_compl = NULL,
  199. .hw_init = wl18xx_hw_init,
  200. + .convert_fw_status = wl18xx_convert_fw_status,
  201. .set_tx_desc_csum = wl18xx_set_tx_desc_csum,
  202. .get_pg_ver = wl18xx_get_pg_ver,
  203. .set_rx_csum = wl18xx_set_rx_csum,
  204. @@ -1726,6 +1760,7 @@ static int wl18xx_setup(struct wl1271 *w
  205. wl->band_rate_to_idx = wl18xx_band_rate_to_idx;
  206. wl->hw_tx_rate_tbl_size = WL18XX_CONF_HW_RXTX_RATE_MAX;
  207. wl->hw_min_ht_rate = WL18XX_CONF_HW_RXTX_RATE_MCS0;
  208. + wl->fw_status_len = sizeof(struct wl18xx_fw_status);
  209. wl->fw_status_priv_len = sizeof(struct wl18xx_fw_status_priv);
  210. wl->stats.fw_stats_len = sizeof(struct wl18xx_acx_statistics);
  211. wl->static_data_priv_len = sizeof(struct wl18xx_static_data_priv);
  212. --- a/drivers/net/wireless/ti/wl18xx/tx.c
  213. +++ b/drivers/net/wireless/ti/wl18xx/tx.c
  214. @@ -32,7 +32,7 @@ static
  215. void wl18xx_get_last_tx_rate(struct wl1271 *wl, struct ieee80211_vif *vif,
  216. struct ieee80211_tx_rate *rate)
  217. {
  218. - u8 fw_rate = wl->fw_status_2->counters.tx_last_rate;
  219. + u8 fw_rate = wl->fw_status->counters.tx_last_rate;
  220. if (fw_rate > CONF_HW_RATE_INDEX_MAX) {
  221. wl1271_error("last Tx rate invalid: %d", fw_rate);
  222. @@ -139,7 +139,7 @@ static void wl18xx_tx_complete_packet(st
  223. void wl18xx_tx_immediate_complete(struct wl1271 *wl)
  224. {
  225. struct wl18xx_fw_status_priv *status_priv =
  226. - (struct wl18xx_fw_status_priv *)wl->fw_status_2->priv;
  227. + (struct wl18xx_fw_status_priv *)wl->fw_status->priv;
  228. struct wl18xx_priv *priv = wl->priv;
  229. u8 i;
  230. --- a/drivers/net/wireless/ti/wl18xx/wl18xx.h
  231. +++ b/drivers/net/wireless/ti/wl18xx/wl18xx.h
  232. @@ -109,6 +109,59 @@ struct wl18xx_fw_status_priv {
  233. u8 padding[3];
  234. };
  235. +struct wl18xx_fw_packet_counters {
  236. + /* Cumulative counter of released packets per AC */
  237. + u8 tx_released_pkts[NUM_TX_QUEUES];
  238. +
  239. + /* Cumulative counter of freed packets per HLID */
  240. + u8 tx_lnk_free_pkts[WL12XX_MAX_LINKS];
  241. +
  242. + /* Cumulative counter of released Voice memory blocks */
  243. + u8 tx_voice_released_blks;
  244. +
  245. + /* Tx rate of the last transmitted packet */
  246. + u8 tx_last_rate;
  247. +
  248. + u8 padding[2];
  249. +} __packed;
  250. +
  251. +/* FW status registers */
  252. +struct wl18xx_fw_status {
  253. + __le32 intr;
  254. + u8 fw_rx_counter;
  255. + u8 drv_rx_counter;
  256. + u8 reserved;
  257. + u8 tx_results_counter;
  258. + __le32 rx_pkt_descs[WL18XX_NUM_RX_DESCRIPTORS];
  259. +
  260. + __le32 fw_localtime;
  261. +
  262. + /*
  263. + * A bitmap (where each bit represents a single HLID)
  264. + * to indicate if the station is in PS mode.
  265. + */
  266. + __le32 link_ps_bitmap;
  267. +
  268. + /*
  269. + * A bitmap (where each bit represents a single HLID) to indicate
  270. + * if the station is in Fast mode
  271. + */
  272. + __le32 link_fast_bitmap;
  273. +
  274. + /* Cumulative counter of total released mem blocks since FW-reset */
  275. + __le32 total_released_blks;
  276. +
  277. + /* Size (in Memory Blocks) of TX pool */
  278. + __le32 tx_total;
  279. +
  280. + struct wl18xx_fw_packet_counters counters;
  281. +
  282. + __le32 log_start_addr;
  283. +
  284. + /* Private status to be used by the lower drivers */
  285. + struct wl18xx_fw_status_priv priv;
  286. +} __packed;
  287. +
  288. #define WL18XX_PHY_VERSION_MAX_LEN 20
  289. struct wl18xx_static_data_priv {
  290. --- a/drivers/net/wireless/ti/wlcore/cmd.c
  291. +++ b/drivers/net/wireless/ti/wlcore/cmd.c
  292. @@ -324,9 +324,14 @@ int wl12xx_allocate_link(struct wl1271 *
  293. __set_bit(link, wlvif->links_map);
  294. spin_unlock_irqrestore(&wl->wl_lock, flags);
  295. - /* take the last "freed packets" value from the current FW status */
  296. - wl->links[link].prev_freed_pkts =
  297. - wl->fw_status_2->counters.tx_lnk_free_pkts[link];
  298. + /*
  299. + * take the last "freed packets" value from the current FW status.
  300. + * on recovery, we might not have fw_status yet, and
  301. + * tx_lnk_free_pkts will be NULL. check for it.
  302. + */
  303. + if (wl->fw_status->counters.tx_lnk_free_pkts)
  304. + wl->links[link].prev_freed_pkts =
  305. + wl->fw_status->counters.tx_lnk_free_pkts[link];
  306. wl->links[link].wlvif = wlvif;
  307. /*
  308. --- a/drivers/net/wireless/ti/wlcore/hw_ops.h
  309. +++ b/drivers/net/wireless/ti/wlcore/hw_ops.h
  310. @@ -106,6 +106,15 @@ wlcore_hw_init_vif(struct wl1271 *wl, st
  311. return 0;
  312. }
  313. +static inline void
  314. +wlcore_hw_convert_fw_status(struct wl1271 *wl, void *raw_fw_status,
  315. + struct wl_fw_status *fw_status)
  316. +{
  317. + BUG_ON(!wl->ops->convert_fw_status);
  318. +
  319. + wl->ops->convert_fw_status(wl, raw_fw_status, fw_status);
  320. +}
  321. +
  322. static inline u32
  323. wlcore_hw_sta_get_ap_rate_mask(struct wl1271 *wl, struct wl12xx_vif *wlvif)
  324. {
  325. --- a/drivers/net/wireless/ti/wlcore/main.c
  326. +++ b/drivers/net/wireless/ti/wlcore/main.c
  327. @@ -357,12 +357,12 @@ static void wl12xx_irq_ps_regulate_link(
  328. static void wl12xx_irq_update_links_status(struct wl1271 *wl,
  329. struct wl12xx_vif *wlvif,
  330. - struct wl_fw_status_2 *status)
  331. + struct wl_fw_status *status)
  332. {
  333. u32 cur_fw_ps_map;
  334. u8 hlid;
  335. - cur_fw_ps_map = le32_to_cpu(status->link_ps_bitmap);
  336. + cur_fw_ps_map = status->link_ps_bitmap;
  337. if (wl->ap_fw_ps_map != cur_fw_ps_map) {
  338. wl1271_debug(DEBUG_PSM,
  339. "link ps prev 0x%x cur 0x%x changed 0x%x",
  340. @@ -377,41 +377,38 @@ static void wl12xx_irq_update_links_stat
  341. wl->links[hlid].allocated_pkts);
  342. }
  343. -static int wlcore_fw_status(struct wl1271 *wl,
  344. - struct wl_fw_status_1 *status_1,
  345. - struct wl_fw_status_2 *status_2)
  346. +static int wlcore_fw_status(struct wl1271 *wl, struct wl_fw_status *status)
  347. {
  348. struct wl12xx_vif *wlvif;
  349. struct timespec ts;
  350. u32 old_tx_blk_count = wl->tx_blocks_available;
  351. int avail, freed_blocks;
  352. int i;
  353. - size_t status_len;
  354. int ret;
  355. struct wl1271_link *lnk;
  356. - status_len = WLCORE_FW_STATUS_1_LEN(wl->num_rx_desc) +
  357. - sizeof(*status_2) + wl->fw_status_priv_len;
  358. -
  359. - ret = wlcore_raw_read_data(wl, REG_RAW_FW_STATUS_ADDR, status_1,
  360. - status_len, false);
  361. + ret = wlcore_raw_read_data(wl, REG_RAW_FW_STATUS_ADDR,
  362. + wl->raw_fw_status,
  363. + wl->fw_status_len, false);
  364. if (ret < 0)
  365. return ret;
  366. + wlcore_hw_convert_fw_status(wl, wl->raw_fw_status, wl->fw_status);
  367. +
  368. wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, "
  369. "drv_rx_counter = %d, tx_results_counter = %d)",
  370. - status_1->intr,
  371. - status_1->fw_rx_counter,
  372. - status_1->drv_rx_counter,
  373. - status_1->tx_results_counter);
  374. + status->intr,
  375. + status->fw_rx_counter,
  376. + status->drv_rx_counter,
  377. + status->tx_results_counter);
  378. for (i = 0; i < NUM_TX_QUEUES; i++) {
  379. /* prevent wrap-around in freed-packets counter */
  380. wl->tx_allocated_pkts[i] -=
  381. - (status_2->counters.tx_released_pkts[i] -
  382. + (status->counters.tx_released_pkts[i] -
  383. wl->tx_pkts_freed[i]) & 0xff;
  384. - wl->tx_pkts_freed[i] = status_2->counters.tx_released_pkts[i];
  385. + wl->tx_pkts_freed[i] = status->counters.tx_released_pkts[i];
  386. }
  387. @@ -420,29 +417,28 @@ static int wlcore_fw_status(struct wl127
  388. lnk = &wl->links[i];
  389. /* prevent wrap-around in freed-packets counter */
  390. - diff = (status_2->counters.tx_lnk_free_pkts[i] -
  391. + diff = (status->counters.tx_lnk_free_pkts[i] -
  392. lnk->prev_freed_pkts) & 0xff;
  393. if (diff == 0)
  394. continue;
  395. lnk->allocated_pkts -= diff;
  396. - lnk->prev_freed_pkts = status_2->counters.tx_lnk_free_pkts[i];
  397. + lnk->prev_freed_pkts = status->counters.tx_lnk_free_pkts[i];
  398. /* accumulate the prev_freed_pkts counter */
  399. lnk->total_freed_pkts += diff;
  400. }
  401. /* prevent wrap-around in total blocks counter */
  402. - if (likely(wl->tx_blocks_freed <=
  403. - le32_to_cpu(status_2->total_released_blks)))
  404. - freed_blocks = le32_to_cpu(status_2->total_released_blks) -
  405. + if (likely(wl->tx_blocks_freed <= status->total_released_blks))
  406. + freed_blocks = status->total_released_blks -
  407. wl->tx_blocks_freed;
  408. else
  409. freed_blocks = 0x100000000LL - wl->tx_blocks_freed +
  410. - le32_to_cpu(status_2->total_released_blks);
  411. + status->total_released_blks;
  412. - wl->tx_blocks_freed = le32_to_cpu(status_2->total_released_blks);
  413. + wl->tx_blocks_freed = status->total_released_blks;
  414. wl->tx_allocated_blocks -= freed_blocks;
  415. @@ -458,7 +454,7 @@ static int wlcore_fw_status(struct wl127
  416. cancel_delayed_work(&wl->tx_watchdog_work);
  417. }
  418. - avail = le32_to_cpu(status_2->tx_total) - wl->tx_allocated_blocks;
  419. + avail = status->tx_total - wl->tx_allocated_blocks;
  420. /*
  421. * The FW might change the total number of TX memblocks before
  422. @@ -477,15 +473,15 @@ static int wlcore_fw_status(struct wl127
  423. /* for AP update num of allocated TX blocks per link and ps status */
  424. wl12xx_for_each_wlvif_ap(wl, wlvif) {
  425. - wl12xx_irq_update_links_status(wl, wlvif, status_2);
  426. + wl12xx_irq_update_links_status(wl, wlvif, status);
  427. }
  428. /* update the host-chipset time offset */
  429. getnstimeofday(&ts);
  430. wl->time_offset = (timespec_to_ns(&ts) >> 10) -
  431. - (s64)le32_to_cpu(status_2->fw_localtime);
  432. + (s64)(status->fw_localtime);
  433. - wl->fw_fast_lnk_map = le32_to_cpu(status_2->link_fast_bitmap);
  434. + wl->fw_fast_lnk_map = status->link_fast_bitmap;
  435. return 0;
  436. }
  437. @@ -549,13 +545,13 @@ static int wlcore_irq_locked(struct wl12
  438. clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags);
  439. smp_mb__after_clear_bit();
  440. - ret = wlcore_fw_status(wl, wl->fw_status_1, wl->fw_status_2);
  441. + ret = wlcore_fw_status(wl, wl->fw_status);
  442. if (ret < 0)
  443. goto out;
  444. wlcore_hw_tx_immediate_compl(wl);
  445. - intr = le32_to_cpu(wl->fw_status_1->intr);
  446. + intr = wl->fw_status->intr;
  447. intr &= WLCORE_ALL_INTR_MASK;
  448. if (!intr) {
  449. done = true;
  450. @@ -584,7 +580,7 @@ static int wlcore_irq_locked(struct wl12
  451. if (likely(intr & WL1271_ACX_INTR_DATA)) {
  452. wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA");
  453. - ret = wlcore_rx(wl, wl->fw_status_1);
  454. + ret = wlcore_rx(wl, wl->fw_status);
  455. if (ret < 0)
  456. goto out;
  457. @@ -843,11 +839,11 @@ static void wl12xx_read_fwlog_panic(stru
  458. wl12xx_cmd_stop_fwlog(wl);
  459. /* Read the first memory block address */
  460. - ret = wlcore_fw_status(wl, wl->fw_status_1, wl->fw_status_2);
  461. + ret = wlcore_fw_status(wl, wl->fw_status);
  462. if (ret < 0)
  463. goto out;
  464. - addr = le32_to_cpu(wl->fw_status_2->log_start_addr);
  465. + addr = wl->fw_status->log_start_addr;
  466. if (!addr)
  467. goto out;
  468. @@ -990,23 +986,23 @@ static int wlcore_fw_wakeup(struct wl127
  469. static int wl1271_setup(struct wl1271 *wl)
  470. {
  471. - wl->fw_status_1 = kzalloc(WLCORE_FW_STATUS_1_LEN(wl->num_rx_desc) +
  472. - sizeof(*wl->fw_status_2) +
  473. - wl->fw_status_priv_len, GFP_KERNEL);
  474. - if (!wl->fw_status_1)
  475. - return -ENOMEM;
  476. + wl->raw_fw_status = kzalloc(wl->fw_status_len, GFP_KERNEL);
  477. + if (!wl->raw_fw_status)
  478. + goto err;
  479. - wl->fw_status_2 = (struct wl_fw_status_2 *)
  480. - (((u8 *) wl->fw_status_1) +
  481. - WLCORE_FW_STATUS_1_LEN(wl->num_rx_desc));
  482. + wl->fw_status = kzalloc(sizeof(*wl->fw_status), GFP_KERNEL);
  483. + if (!wl->fw_status)
  484. + goto err;
  485. wl->tx_res_if = kzalloc(sizeof(*wl->tx_res_if), GFP_KERNEL);
  486. - if (!wl->tx_res_if) {
  487. - kfree(wl->fw_status_1);
  488. - return -ENOMEM;
  489. - }
  490. + if (!wl->tx_res_if)
  491. + goto err;
  492. return 0;
  493. +err:
  494. + kfree(wl->fw_status);
  495. + kfree(wl->raw_fw_status);
  496. + return -ENOMEM;
  497. }
  498. static int wl12xx_set_power_on(struct wl1271 *wl)
  499. @@ -1952,9 +1948,10 @@ static void wlcore_op_stop_locked(struct
  500. wl1271_debugfs_reset(wl);
  501. - kfree(wl->fw_status_1);
  502. - wl->fw_status_1 = NULL;
  503. - wl->fw_status_2 = NULL;
  504. + kfree(wl->raw_fw_status);
  505. + wl->raw_fw_status = NULL;
  506. + kfree(wl->fw_status);
  507. + wl->fw_status = NULL;
  508. kfree(wl->tx_res_if);
  509. wl->tx_res_if = NULL;
  510. kfree(wl->target_mem_map);
  511. @@ -6058,7 +6055,8 @@ int wlcore_free_hw(struct wl1271 *wl)
  512. kfree(wl->nvs);
  513. wl->nvs = NULL;
  514. - kfree(wl->fw_status_1);
  515. + kfree(wl->raw_fw_status);
  516. + kfree(wl->fw_status);
  517. kfree(wl->tx_res_if);
  518. destroy_workqueue(wl->freezable_wq);
  519. --- a/drivers/net/wireless/ti/wlcore/rx.c
  520. +++ b/drivers/net/wireless/ti/wlcore/rx.c
  521. @@ -203,7 +203,7 @@ static int wl1271_rx_handle_data(struct
  522. return is_data;
  523. }
  524. -int wlcore_rx(struct wl1271 *wl, struct wl_fw_status_1 *status)
  525. +int wlcore_rx(struct wl1271 *wl, struct wl_fw_status *status)
  526. {
  527. unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0};
  528. u32 buf_size;
  529. --- a/drivers/net/wireless/ti/wlcore/rx.h
  530. +++ b/drivers/net/wireless/ti/wlcore/rx.h
  531. @@ -142,7 +142,7 @@ struct wl1271_rx_descriptor {
  532. u8 reserved;
  533. } __packed;
  534. -int wlcore_rx(struct wl1271 *wl, struct wl_fw_status_1 *status);
  535. +int wlcore_rx(struct wl1271 *wl, struct wl_fw_status *status);
  536. u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band);
  537. int wl1271_rx_filter_enable(struct wl1271 *wl,
  538. int index, bool enable,
  539. --- a/drivers/net/wireless/ti/wlcore/wlcore.h
  540. +++ b/drivers/net/wireless/ti/wlcore/wlcore.h
  541. @@ -73,6 +73,8 @@ struct wlcore_ops {
  542. void (*tx_immediate_compl)(struct wl1271 *wl);
  543. int (*hw_init)(struct wl1271 *wl);
  544. int (*init_vif)(struct wl1271 *wl, struct wl12xx_vif *wlvif);
  545. + void (*convert_fw_status)(struct wl1271 *wl, void *raw_fw_status,
  546. + struct wl_fw_status *fw_status);
  547. u32 (*sta_get_ap_rate_mask)(struct wl1271 *wl,
  548. struct wl12xx_vif *wlvif);
  549. int (*get_pg_ver)(struct wl1271 *wl, s8 *ver);
  550. @@ -348,8 +350,8 @@ struct wl1271 {
  551. u32 buffer_cmd;
  552. u32 buffer_busyword[WL1271_BUSY_WORD_CNT];
  553. - struct wl_fw_status_1 *fw_status_1;
  554. - struct wl_fw_status_2 *fw_status_2;
  555. + void *raw_fw_status;
  556. + struct wl_fw_status *fw_status;
  557. struct wl1271_tx_hw_res_if *tx_res_if;
  558. /* Current chipset configuration */
  559. @@ -450,6 +452,7 @@ struct wl1271 {
  560. struct ieee80211_sta_ht_cap ht_cap[WLCORE_NUM_BANDS];
  561. /* size of the private FW status data */
  562. + size_t fw_status_len;
  563. size_t fw_status_priv_len;
  564. /* RX Data filter rule state - enabled/disabled */
  565. --- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
  566. +++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
  567. @@ -120,70 +120,58 @@ struct wl1271_chip {
  568. #define AP_MAX_STATIONS 8
  569. -struct wl_fw_packet_counters {
  570. - /* Cumulative counter of released packets per AC */
  571. - u8 tx_released_pkts[NUM_TX_QUEUES];
  572. -
  573. - /* Cumulative counter of freed packets per HLID */
  574. - u8 tx_lnk_free_pkts[WL12XX_MAX_LINKS];
  575. -
  576. - /* Cumulative counter of released Voice memory blocks */
  577. - u8 tx_voice_released_blks;
  578. -
  579. - /* Tx rate of the last transmitted packet */
  580. - u8 tx_last_rate;
  581. -
  582. - u8 padding[2];
  583. -} __packed;
  584. -
  585. -/* FW status registers */
  586. -struct wl_fw_status_1 {
  587. - __le32 intr;
  588. +struct wl_fw_status {
  589. + u32 intr;
  590. u8 fw_rx_counter;
  591. u8 drv_rx_counter;
  592. - u8 reserved;
  593. u8 tx_results_counter;
  594. - __le32 rx_pkt_descs[0];
  595. -} __packed;
  596. -
  597. -/*
  598. - * Each HW arch has a different number of Rx descriptors.
  599. - * The length of the status depends on it, since it holds an array
  600. - * of descriptors.
  601. - */
  602. -#define WLCORE_FW_STATUS_1_LEN(num_rx_desc) \
  603. - (sizeof(struct wl_fw_status_1) + \
  604. - (sizeof(((struct wl_fw_status_1 *)0)->rx_pkt_descs[0])) * \
  605. - num_rx_desc)
  606. + __le32 *rx_pkt_descs;
  607. -struct wl_fw_status_2 {
  608. - __le32 fw_localtime;
  609. + u32 fw_localtime;
  610. /*
  611. * A bitmap (where each bit represents a single HLID)
  612. * to indicate if the station is in PS mode.
  613. */
  614. - __le32 link_ps_bitmap;
  615. + u32 link_ps_bitmap;
  616. /*
  617. * A bitmap (where each bit represents a single HLID) to indicate
  618. * if the station is in Fast mode
  619. */
  620. - __le32 link_fast_bitmap;
  621. + u32 link_fast_bitmap;
  622. /* Cumulative counter of total released mem blocks since FW-reset */
  623. - __le32 total_released_blks;
  624. + u32 total_released_blks;
  625. /* Size (in Memory Blocks) of TX pool */
  626. - __le32 tx_total;
  627. + u32 tx_total;
  628. - struct wl_fw_packet_counters counters;
  629. + struct {
  630. + /*
  631. + * Cumulative counter of released packets per AC
  632. + * (length of the array is NUM_TX_QUEUES)
  633. + */
  634. + u8 *tx_released_pkts;
  635. +
  636. + /*
  637. + * Cumulative counter of freed packets per HLID
  638. + * (length of the array is WL12XX_MAX_LINKS)
  639. + */
  640. + u8 *tx_lnk_free_pkts;
  641. +
  642. + /* Cumulative counter of released Voice memory blocks */
  643. + u8 tx_voice_released_blks;
  644. +
  645. + /* Tx rate of the last transmitted packet */
  646. + u8 tx_last_rate;
  647. + } counters;
  648. - __le32 log_start_addr;
  649. + u32 log_start_addr;
  650. /* Private status to be used by the lower drivers */
  651. - u8 priv[0];
  652. -} __packed;
  653. + void *priv;
  654. +};
  655. #define WL1271_MAX_CHANNELS 64
  656. struct wl1271_scan {