txrx.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * NXP Wireless LAN device driver: generic TX/RX data handling
  4. *
  5. * Copyright 2011-2020 NXP
  6. */
  7. #include "decl.h"
  8. #include "ioctl.h"
  9. #include "util.h"
  10. #include "fw.h"
  11. #include "main.h"
  12. #include "wmm.h"
  13. /*
  14. * This function processes the received buffer.
  15. *
  16. * Main responsibility of this function is to parse the RxPD to
  17. * identify the correct interface this packet is headed for and
  18. * forwarding it to the associated handling function, where the
  19. * packet will be further processed and sent to kernel/upper layer
  20. * if required.
  21. */
  22. int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter,
  23. struct sk_buff *skb)
  24. {
  25. struct mwifiex_private *priv =
  26. mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
  27. struct rxpd *local_rx_pd;
  28. struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb);
  29. int ret;
  30. local_rx_pd = (struct rxpd *) (skb->data);
  31. /* Get the BSS number from rxpd, get corresponding priv */
  32. priv = mwifiex_get_priv_by_id(adapter, local_rx_pd->bss_num &
  33. BSS_NUM_MASK, local_rx_pd->bss_type);
  34. if (!priv)
  35. priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
  36. if (!priv) {
  37. mwifiex_dbg(adapter, ERROR,
  38. "data: priv not found. Drop RX packet\n");
  39. dev_kfree_skb_any(skb);
  40. return -1;
  41. }
  42. mwifiex_dbg_dump(adapter, DAT_D, "rx pkt:", skb->data,
  43. min_t(size_t, skb->len, DEBUG_DUMP_DATA_MAX_LEN));
  44. memset(rx_info, 0, sizeof(*rx_info));
  45. rx_info->bss_num = priv->bss_num;
  46. rx_info->bss_type = priv->bss_type;
  47. if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP)
  48. ret = mwifiex_process_uap_rx_packet(priv, skb);
  49. else
  50. ret = mwifiex_process_sta_rx_packet(priv, skb);
  51. return ret;
  52. }
  53. EXPORT_SYMBOL_GPL(mwifiex_handle_rx_packet);
  54. /*
  55. * This function sends a packet to device.
  56. *
  57. * It processes the packet to add the TxPD, checks condition and
  58. * sends the processed packet to firmware for transmission.
  59. *
  60. * On successful completion, the function calls the completion callback
  61. * and logs the time.
  62. */
  63. int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
  64. struct mwifiex_tx_param *tx_param)
  65. {
  66. int hroom, ret = -1;
  67. struct mwifiex_adapter *adapter = priv->adapter;
  68. u8 *head_ptr;
  69. struct txpd *local_tx_pd = NULL;
  70. struct mwifiex_sta_node *dest_node;
  71. struct ethhdr *hdr = (void *)skb->data;
  72. hroom = adapter->intf_hdr_len;
  73. if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) {
  74. dest_node = mwifiex_get_sta_entry(priv, hdr->h_dest);
  75. if (dest_node) {
  76. dest_node->stats.tx_bytes += skb->len;
  77. dest_node->stats.tx_packets++;
  78. }
  79. head_ptr = mwifiex_process_uap_txpd(priv, skb);
  80. } else {
  81. head_ptr = mwifiex_process_sta_txpd(priv, skb);
  82. }
  83. if ((adapter->data_sent || adapter->tx_lock_flag) && head_ptr) {
  84. skb_queue_tail(&adapter->tx_data_q, skb);
  85. atomic_inc(&adapter->tx_queued);
  86. return 0;
  87. }
  88. if (head_ptr) {
  89. if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA)
  90. local_tx_pd = (struct txpd *)(head_ptr + hroom);
  91. if (adapter->iface_type == MWIFIEX_USB) {
  92. ret = adapter->if_ops.host_to_card(adapter,
  93. priv->usb_port,
  94. skb, tx_param);
  95. } else {
  96. ret = adapter->if_ops.host_to_card(adapter,
  97. MWIFIEX_TYPE_DATA,
  98. skb, tx_param);
  99. }
  100. }
  101. mwifiex_dbg_dump(adapter, DAT_D, "tx pkt:", skb->data,
  102. min_t(size_t, skb->len, DEBUG_DUMP_DATA_MAX_LEN));
  103. switch (ret) {
  104. case -ENOSR:
  105. mwifiex_dbg(adapter, DATA, "data: -ENOSR is returned\n");
  106. break;
  107. case -EBUSY:
  108. if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
  109. (adapter->pps_uapsd_mode) && (adapter->tx_lock_flag)) {
  110. priv->adapter->tx_lock_flag = false;
  111. if (local_tx_pd)
  112. local_tx_pd->flags = 0;
  113. }
  114. mwifiex_dbg(adapter, ERROR, "data: -EBUSY is returned\n");
  115. break;
  116. case -1:
  117. mwifiex_dbg(adapter, ERROR,
  118. "mwifiex_write_data_async failed: 0x%X\n",
  119. ret);
  120. adapter->dbg.num_tx_host_to_card_failure++;
  121. mwifiex_write_data_complete(adapter, skb, 0, ret);
  122. break;
  123. case -EINPROGRESS:
  124. break;
  125. case 0:
  126. mwifiex_write_data_complete(adapter, skb, 0, ret);
  127. break;
  128. default:
  129. break;
  130. }
  131. return ret;
  132. }
  133. static int mwifiex_host_to_card(struct mwifiex_adapter *adapter,
  134. struct sk_buff *skb,
  135. struct mwifiex_tx_param *tx_param)
  136. {
  137. struct txpd *local_tx_pd = NULL;
  138. u8 *head_ptr = skb->data;
  139. int ret = 0;
  140. struct mwifiex_private *priv;
  141. struct mwifiex_txinfo *tx_info;
  142. tx_info = MWIFIEX_SKB_TXCB(skb);
  143. priv = mwifiex_get_priv_by_id(adapter, tx_info->bss_num,
  144. tx_info->bss_type);
  145. if (!priv) {
  146. mwifiex_dbg(adapter, ERROR,
  147. "data: priv not found. Drop TX packet\n");
  148. adapter->dbg.num_tx_host_to_card_failure++;
  149. mwifiex_write_data_complete(adapter, skb, 0, 0);
  150. return ret;
  151. }
  152. if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA)
  153. local_tx_pd = (struct txpd *)(head_ptr + adapter->intf_hdr_len);
  154. if (adapter->iface_type == MWIFIEX_USB) {
  155. ret = adapter->if_ops.host_to_card(adapter,
  156. priv->usb_port,
  157. skb, tx_param);
  158. } else {
  159. ret = adapter->if_ops.host_to_card(adapter,
  160. MWIFIEX_TYPE_DATA,
  161. skb, tx_param);
  162. }
  163. switch (ret) {
  164. case -ENOSR:
  165. mwifiex_dbg(adapter, ERROR, "data: -ENOSR is returned\n");
  166. break;
  167. case -EBUSY:
  168. if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
  169. (adapter->pps_uapsd_mode) &&
  170. (adapter->tx_lock_flag)) {
  171. priv->adapter->tx_lock_flag = false;
  172. if (local_tx_pd)
  173. local_tx_pd->flags = 0;
  174. }
  175. skb_queue_head(&adapter->tx_data_q, skb);
  176. if (tx_info->flags & MWIFIEX_BUF_FLAG_AGGR_PKT)
  177. atomic_add(tx_info->aggr_num, &adapter->tx_queued);
  178. else
  179. atomic_inc(&adapter->tx_queued);
  180. mwifiex_dbg(adapter, ERROR, "data: -EBUSY is returned\n");
  181. break;
  182. case -1:
  183. mwifiex_dbg(adapter, ERROR,
  184. "mwifiex_write_data_async failed: 0x%X\n", ret);
  185. adapter->dbg.num_tx_host_to_card_failure++;
  186. mwifiex_write_data_complete(adapter, skb, 0, ret);
  187. break;
  188. case -EINPROGRESS:
  189. break;
  190. case 0:
  191. mwifiex_write_data_complete(adapter, skb, 0, ret);
  192. break;
  193. default:
  194. break;
  195. }
  196. return ret;
  197. }
  198. static int
  199. mwifiex_dequeue_tx_queue(struct mwifiex_adapter *adapter)
  200. {
  201. struct sk_buff *skb, *skb_next;
  202. struct mwifiex_txinfo *tx_info;
  203. struct mwifiex_tx_param tx_param;
  204. skb = skb_dequeue(&adapter->tx_data_q);
  205. if (!skb)
  206. return -1;
  207. tx_info = MWIFIEX_SKB_TXCB(skb);
  208. if (tx_info->flags & MWIFIEX_BUF_FLAG_AGGR_PKT)
  209. atomic_sub(tx_info->aggr_num, &adapter->tx_queued);
  210. else
  211. atomic_dec(&adapter->tx_queued);
  212. if (!skb_queue_empty(&adapter->tx_data_q))
  213. skb_next = skb_peek(&adapter->tx_data_q);
  214. else
  215. skb_next = NULL;
  216. tx_param.next_pkt_len = ((skb_next) ? skb_next->len : 0);
  217. if (!tx_param.next_pkt_len) {
  218. if (!mwifiex_wmm_lists_empty(adapter))
  219. tx_param.next_pkt_len = 1;
  220. }
  221. return mwifiex_host_to_card(adapter, skb, &tx_param);
  222. }
  223. void
  224. mwifiex_process_tx_queue(struct mwifiex_adapter *adapter)
  225. {
  226. do {
  227. if (adapter->data_sent || adapter->tx_lock_flag)
  228. break;
  229. if (mwifiex_dequeue_tx_queue(adapter))
  230. break;
  231. } while (!skb_queue_empty(&adapter->tx_data_q));
  232. }
  233. /*
  234. * Packet send completion callback handler.
  235. *
  236. * It either frees the buffer directly or forwards it to another
  237. * completion callback which checks conditions, updates statistics,
  238. * wakes up stalled traffic queue if required, and then frees the buffer.
  239. */
  240. int mwifiex_write_data_complete(struct mwifiex_adapter *adapter,
  241. struct sk_buff *skb, int aggr, int status)
  242. {
  243. struct mwifiex_private *priv;
  244. struct mwifiex_txinfo *tx_info;
  245. struct netdev_queue *txq;
  246. int index;
  247. if (!skb)
  248. return 0;
  249. tx_info = MWIFIEX_SKB_TXCB(skb);
  250. priv = mwifiex_get_priv_by_id(adapter, tx_info->bss_num,
  251. tx_info->bss_type);
  252. if (!priv)
  253. goto done;
  254. mwifiex_set_trans_start(priv->netdev);
  255. if (tx_info->flags & MWIFIEX_BUF_FLAG_BRIDGED_PKT)
  256. atomic_dec_return(&adapter->pending_bridged_pkts);
  257. if (tx_info->flags & MWIFIEX_BUF_FLAG_AGGR_PKT)
  258. goto done;
  259. if (!status) {
  260. priv->stats.tx_packets++;
  261. priv->stats.tx_bytes += tx_info->pkt_len;
  262. if (priv->tx_timeout_cnt)
  263. priv->tx_timeout_cnt = 0;
  264. } else {
  265. priv->stats.tx_errors++;
  266. }
  267. if (aggr)
  268. /* For skb_aggr, do not wake up tx queue */
  269. goto done;
  270. atomic_dec(&adapter->tx_pending);
  271. index = mwifiex_1d_to_wmm_queue[skb->priority];
  272. if (atomic_dec_return(&priv->wmm_tx_pending[index]) < LOW_TX_PENDING) {
  273. txq = netdev_get_tx_queue(priv->netdev, index);
  274. if (netif_tx_queue_stopped(txq)) {
  275. netif_tx_wake_queue(txq);
  276. mwifiex_dbg(adapter, DATA, "wake queue: %d\n", index);
  277. }
  278. }
  279. done:
  280. dev_kfree_skb_any(skb);
  281. return 0;
  282. }
  283. EXPORT_SYMBOL_GPL(mwifiex_write_data_complete);
  284. void mwifiex_parse_tx_status_event(struct mwifiex_private *priv,
  285. void *event_body)
  286. {
  287. struct tx_status_event *tx_status = (void *)priv->adapter->event_body;
  288. struct sk_buff *ack_skb;
  289. struct mwifiex_txinfo *tx_info;
  290. if (!tx_status->tx_token_id)
  291. return;
  292. spin_lock_bh(&priv->ack_status_lock);
  293. ack_skb = idr_remove(&priv->ack_status_frames, tx_status->tx_token_id);
  294. spin_unlock_bh(&priv->ack_status_lock);
  295. if (ack_skb) {
  296. tx_info = MWIFIEX_SKB_TXCB(ack_skb);
  297. if (tx_info->flags & MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS) {
  298. /* consumes ack_skb */
  299. skb_complete_wifi_ack(ack_skb, !tx_status->status);
  300. } else {
  301. /* Remove broadcast address which was added by driver */
  302. memmove(ack_skb->data +
  303. sizeof(struct ieee80211_hdr_3addr) +
  304. MWIFIEX_MGMT_FRAME_HEADER_SIZE + sizeof(u16),
  305. ack_skb->data +
  306. sizeof(struct ieee80211_hdr_3addr) +
  307. MWIFIEX_MGMT_FRAME_HEADER_SIZE + sizeof(u16) +
  308. ETH_ALEN, ack_skb->len -
  309. (sizeof(struct ieee80211_hdr_3addr) +
  310. MWIFIEX_MGMT_FRAME_HEADER_SIZE + sizeof(u16) +
  311. ETH_ALEN));
  312. ack_skb->len = ack_skb->len - ETH_ALEN;
  313. /* Remove driver's proprietary header including 2 bytes
  314. * of packet length and pass actual management frame buffer
  315. * to cfg80211.
  316. */
  317. cfg80211_mgmt_tx_status(&priv->wdev, tx_info->cookie,
  318. ack_skb->data +
  319. MWIFIEX_MGMT_FRAME_HEADER_SIZE +
  320. sizeof(u16), ack_skb->len -
  321. (MWIFIEX_MGMT_FRAME_HEADER_SIZE
  322. + sizeof(u16)),
  323. !tx_status->status, GFP_ATOMIC);
  324. dev_kfree_skb_any(ack_skb);
  325. }
  326. }
  327. }