uap_txrx.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532
  1. /*
  2. * Marvell Wireless LAN device driver: AP TX and RX data handling
  3. *
  4. * Copyright (C) 2012-2014, Marvell International Ltd.
  5. *
  6. * This software file (the "File") is distributed by Marvell International
  7. * Ltd. under the terms of the GNU General Public License Version 2, June 1991
  8. * (the "License"). You may use, redistribute and/or modify this File in
  9. * accordance with the terms and conditions of the License, a copy of which
  10. * is available by writing to the Free Software Foundation, Inc.,
  11. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
  12. * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
  13. *
  14. * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
  15. * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
  16. * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
  17. * this warranty disclaimer.
  18. */
  19. #include "decl.h"
  20. #include "ioctl.h"
  21. #include "main.h"
  22. #include "wmm.h"
  23. #include "11n_aggr.h"
  24. #include "11n_rxreorder.h"
  25. /* This function checks if particular RA list has packets more than low bridge
  26. * packet threshold and then deletes packet from this RA list.
  27. * Function deletes packets from such RA list and returns true. If no such list
  28. * is found, false is returned.
  29. */
  30. static bool
  31. mwifiex_uap_del_tx_pkts_in_ralist(struct mwifiex_private *priv,
  32. struct list_head *ra_list_head,
  33. int tid)
  34. {
  35. struct mwifiex_ra_list_tbl *ra_list;
  36. struct sk_buff *skb, *tmp;
  37. bool pkt_deleted = false;
  38. struct mwifiex_txinfo *tx_info;
  39. struct mwifiex_adapter *adapter = priv->adapter;
  40. list_for_each_entry(ra_list, ra_list_head, list) {
  41. if (skb_queue_empty(&ra_list->skb_head))
  42. continue;
  43. skb_queue_walk_safe(&ra_list->skb_head, skb, tmp) {
  44. tx_info = MWIFIEX_SKB_TXCB(skb);
  45. if (tx_info->flags & MWIFIEX_BUF_FLAG_BRIDGED_PKT) {
  46. __skb_unlink(skb, &ra_list->skb_head);
  47. mwifiex_write_data_complete(adapter, skb, 0,
  48. -1);
  49. if (ra_list->tx_paused)
  50. priv->wmm.pkts_paused[tid]--;
  51. else
  52. atomic_dec(&priv->wmm.tx_pkts_queued);
  53. pkt_deleted = true;
  54. }
  55. if ((atomic_read(&adapter->pending_bridged_pkts) <=
  56. MWIFIEX_BRIDGED_PKTS_THR_LOW))
  57. break;
  58. }
  59. }
  60. return pkt_deleted;
  61. }
  62. /* This function deletes packets from particular RA List. RA list index
  63. * from which packets are deleted is preserved so that packets from next RA
  64. * list are deleted upon subsequent call thus maintaining fairness.
  65. */
  66. static void mwifiex_uap_cleanup_tx_queues(struct mwifiex_private *priv)
  67. {
  68. unsigned long flags;
  69. struct list_head *ra_list;
  70. int i;
  71. spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags);
  72. for (i = 0; i < MAX_NUM_TID; i++, priv->del_list_idx++) {
  73. if (priv->del_list_idx == MAX_NUM_TID)
  74. priv->del_list_idx = 0;
  75. ra_list = &priv->wmm.tid_tbl_ptr[priv->del_list_idx].ra_list;
  76. if (mwifiex_uap_del_tx_pkts_in_ralist(priv, ra_list, i)) {
  77. priv->del_list_idx++;
  78. break;
  79. }
  80. }
  81. spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
  82. }
  83. static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv,
  84. struct sk_buff *skb)
  85. {
  86. struct mwifiex_adapter *adapter = priv->adapter;
  87. struct uap_rxpd *uap_rx_pd;
  88. struct rx_packet_hdr *rx_pkt_hdr;
  89. struct sk_buff *new_skb;
  90. struct mwifiex_txinfo *tx_info;
  91. int hdr_chop;
  92. struct ethhdr *p_ethhdr;
  93. struct mwifiex_sta_node *src_node;
  94. int index;
  95. uap_rx_pd = (struct uap_rxpd *)(skb->data);
  96. rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset);
  97. if ((atomic_read(&adapter->pending_bridged_pkts) >=
  98. MWIFIEX_BRIDGED_PKTS_THR_HIGH)) {
  99. mwifiex_dbg(priv->adapter, ERROR,
  100. "Tx: Bridge packet limit reached. Drop packet!\n");
  101. kfree_skb(skb);
  102. mwifiex_uap_cleanup_tx_queues(priv);
  103. return;
  104. }
  105. if ((!memcmp(&rx_pkt_hdr->rfc1042_hdr, bridge_tunnel_header,
  106. sizeof(bridge_tunnel_header))) ||
  107. (!memcmp(&rx_pkt_hdr->rfc1042_hdr, rfc1042_header,
  108. sizeof(rfc1042_header)) &&
  109. ntohs(rx_pkt_hdr->rfc1042_hdr.snap_type) != ETH_P_AARP &&
  110. ntohs(rx_pkt_hdr->rfc1042_hdr.snap_type) != ETH_P_IPX)) {
  111. /* Replace the 803 header and rfc1042 header (llc/snap) with
  112. * an Ethernet II header, keep the src/dst and snap_type
  113. * (ethertype).
  114. *
  115. * The firmware only passes up SNAP frames converting all RX
  116. * data from 802.11 to 802.2/LLC/SNAP frames.
  117. *
  118. * To create the Ethernet II, just move the src, dst address
  119. * right before the snap_type.
  120. */
  121. p_ethhdr = (struct ethhdr *)
  122. ((u8 *)(&rx_pkt_hdr->eth803_hdr)
  123. + sizeof(rx_pkt_hdr->eth803_hdr)
  124. + sizeof(rx_pkt_hdr->rfc1042_hdr)
  125. - sizeof(rx_pkt_hdr->eth803_hdr.h_dest)
  126. - sizeof(rx_pkt_hdr->eth803_hdr.h_source)
  127. - sizeof(rx_pkt_hdr->rfc1042_hdr.snap_type));
  128. memcpy(p_ethhdr->h_source, rx_pkt_hdr->eth803_hdr.h_source,
  129. sizeof(p_ethhdr->h_source));
  130. memcpy(p_ethhdr->h_dest, rx_pkt_hdr->eth803_hdr.h_dest,
  131. sizeof(p_ethhdr->h_dest));
  132. /* Chop off the rxpd + the excess memory from
  133. * 802.2/llc/snap header that was removed.
  134. */
  135. hdr_chop = (u8 *)p_ethhdr - (u8 *)uap_rx_pd;
  136. } else {
  137. /* Chop off the rxpd */
  138. hdr_chop = (u8 *)&rx_pkt_hdr->eth803_hdr - (u8 *)uap_rx_pd;
  139. }
  140. /* Chop off the leading header bytes so that it points
  141. * to the start of either the reconstructed EthII frame
  142. * or the 802.2/llc/snap frame.
  143. */
  144. skb_pull(skb, hdr_chop);
  145. if (skb_headroom(skb) < MWIFIEX_MIN_DATA_HEADER_LEN) {
  146. mwifiex_dbg(priv->adapter, ERROR,
  147. "data: Tx: insufficient skb headroom %d\n",
  148. skb_headroom(skb));
  149. /* Insufficient skb headroom - allocate a new skb */
  150. new_skb =
  151. skb_realloc_headroom(skb, MWIFIEX_MIN_DATA_HEADER_LEN);
  152. if (unlikely(!new_skb)) {
  153. mwifiex_dbg(priv->adapter, ERROR,
  154. "Tx: cannot allocate new_skb\n");
  155. kfree_skb(skb);
  156. priv->stats.tx_dropped++;
  157. return;
  158. }
  159. kfree_skb(skb);
  160. skb = new_skb;
  161. mwifiex_dbg(priv->adapter, INFO,
  162. "info: new skb headroom %d\n",
  163. skb_headroom(skb));
  164. }
  165. tx_info = MWIFIEX_SKB_TXCB(skb);
  166. memset(tx_info, 0, sizeof(*tx_info));
  167. tx_info->bss_num = priv->bss_num;
  168. tx_info->bss_type = priv->bss_type;
  169. tx_info->flags |= MWIFIEX_BUF_FLAG_BRIDGED_PKT;
  170. src_node = mwifiex_get_sta_entry(priv, rx_pkt_hdr->eth803_hdr.h_source);
  171. if (src_node) {
  172. src_node->stats.last_rx = jiffies;
  173. src_node->stats.rx_bytes += skb->len;
  174. src_node->stats.rx_packets++;
  175. src_node->stats.last_tx_rate = uap_rx_pd->rx_rate;
  176. src_node->stats.last_tx_htinfo = uap_rx_pd->ht_info;
  177. }
  178. if (is_unicast_ether_addr(rx_pkt_hdr->eth803_hdr.h_dest)) {
  179. /* Update bridge packet statistics as the
  180. * packet is not going to kernel/upper layer.
  181. */
  182. priv->stats.rx_bytes += skb->len;
  183. priv->stats.rx_packets++;
  184. /* Sending bridge packet to TX queue, so save the packet
  185. * length in TXCB to update statistics in TX complete.
  186. */
  187. tx_info->pkt_len = skb->len;
  188. }
  189. __net_timestamp(skb);
  190. index = mwifiex_1d_to_wmm_queue[skb->priority];
  191. atomic_inc(&priv->wmm_tx_pending[index]);
  192. mwifiex_wmm_add_buf_txqueue(priv, skb);
  193. atomic_inc(&adapter->tx_pending);
  194. atomic_inc(&adapter->pending_bridged_pkts);
  195. mwifiex_queue_main_work(priv->adapter);
  196. return;
  197. }
  198. /*
  199. * This function contains logic for AP packet forwarding.
  200. *
  201. * If a packet is multicast/broadcast, it is sent to kernel/upper layer
  202. * as well as queued back to AP TX queue so that it can be sent to other
  203. * associated stations.
  204. * If a packet is unicast and RA is present in associated station list,
  205. * it is again requeued into AP TX queue.
  206. * If a packet is unicast and RA is not in associated station list,
  207. * packet is forwarded to kernel to handle routing logic.
  208. */
  209. int mwifiex_handle_uap_rx_forward(struct mwifiex_private *priv,
  210. struct sk_buff *skb)
  211. {
  212. struct mwifiex_adapter *adapter = priv->adapter;
  213. struct uap_rxpd *uap_rx_pd;
  214. struct rx_packet_hdr *rx_pkt_hdr;
  215. u8 ra[ETH_ALEN];
  216. struct sk_buff *skb_uap;
  217. uap_rx_pd = (struct uap_rxpd *)(skb->data);
  218. rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset);
  219. /* don't do packet forwarding in disconnected state */
  220. if (!priv->media_connected) {
  221. mwifiex_dbg(adapter, ERROR,
  222. "drop packet in disconnected state.\n");
  223. dev_kfree_skb_any(skb);
  224. return 0;
  225. }
  226. memcpy(ra, rx_pkt_hdr->eth803_hdr.h_dest, ETH_ALEN);
  227. if (is_multicast_ether_addr(ra)) {
  228. skb_uap = skb_copy(skb, GFP_ATOMIC);
  229. mwifiex_uap_queue_bridged_pkt(priv, skb_uap);
  230. } else {
  231. if (mwifiex_get_sta_entry(priv, ra)) {
  232. /* Requeue Intra-BSS packet */
  233. mwifiex_uap_queue_bridged_pkt(priv, skb);
  234. return 0;
  235. }
  236. }
  237. /* Forward unicat/Inter-BSS packets to kernel. */
  238. return mwifiex_process_rx_packet(priv, skb);
  239. }
  240. int mwifiex_uap_recv_packet(struct mwifiex_private *priv,
  241. struct sk_buff *skb)
  242. {
  243. struct mwifiex_adapter *adapter = priv->adapter;
  244. struct mwifiex_sta_node *src_node;
  245. struct ethhdr *p_ethhdr;
  246. struct sk_buff *skb_uap;
  247. struct mwifiex_txinfo *tx_info;
  248. if (!skb)
  249. return -1;
  250. p_ethhdr = (void *)skb->data;
  251. src_node = mwifiex_get_sta_entry(priv, p_ethhdr->h_source);
  252. if (src_node) {
  253. src_node->stats.last_rx = jiffies;
  254. src_node->stats.rx_bytes += skb->len;
  255. src_node->stats.rx_packets++;
  256. }
  257. skb->dev = priv->netdev;
  258. skb->protocol = eth_type_trans(skb, priv->netdev);
  259. skb->ip_summed = CHECKSUM_NONE;
  260. /* This is required only in case of 11n and USB/PCIE as we alloc
  261. * a buffer of 4K only if its 11N (to be able to receive 4K
  262. * AMSDU packets). In case of SD we allocate buffers based
  263. * on the size of packet and hence this is not needed.
  264. *
  265. * Modifying the truesize here as our allocation for each
  266. * skb is 4K but we only receive 2K packets and this cause
  267. * the kernel to start dropping packets in case where
  268. * application has allocated buffer based on 2K size i.e.
  269. * if there a 64K packet received (in IP fragments and
  270. * application allocates 64K to receive this packet but
  271. * this packet would almost double up because we allocate
  272. * each 1.5K fragment in 4K and pass it up. As soon as the
  273. * 64K limit hits kernel will start to drop rest of the
  274. * fragments. Currently we fail the Filesndl-ht.scr script
  275. * for UDP, hence this fix
  276. */
  277. if ((adapter->iface_type == MWIFIEX_USB ||
  278. adapter->iface_type == MWIFIEX_PCIE) &&
  279. (skb->truesize > MWIFIEX_RX_DATA_BUF_SIZE))
  280. skb->truesize += (skb->len - MWIFIEX_RX_DATA_BUF_SIZE);
  281. if (is_multicast_ether_addr(p_ethhdr->h_dest) ||
  282. mwifiex_get_sta_entry(priv, p_ethhdr->h_dest)) {
  283. if (skb_headroom(skb) < MWIFIEX_MIN_DATA_HEADER_LEN)
  284. skb_uap =
  285. skb_realloc_headroom(skb, MWIFIEX_MIN_DATA_HEADER_LEN);
  286. else
  287. skb_uap = skb_copy(skb, GFP_ATOMIC);
  288. if (likely(skb_uap)) {
  289. tx_info = MWIFIEX_SKB_TXCB(skb_uap);
  290. memset(tx_info, 0, sizeof(*tx_info));
  291. tx_info->bss_num = priv->bss_num;
  292. tx_info->bss_type = priv->bss_type;
  293. tx_info->flags |= MWIFIEX_BUF_FLAG_BRIDGED_PKT;
  294. __net_timestamp(skb_uap);
  295. mwifiex_wmm_add_buf_txqueue(priv, skb_uap);
  296. atomic_inc(&adapter->tx_pending);
  297. atomic_inc(&adapter->pending_bridged_pkts);
  298. if ((atomic_read(&adapter->pending_bridged_pkts) >=
  299. MWIFIEX_BRIDGED_PKTS_THR_HIGH)) {
  300. mwifiex_dbg(adapter, ERROR,
  301. "Tx: Bridge packet limit reached. Drop packet!\n");
  302. mwifiex_uap_cleanup_tx_queues(priv);
  303. }
  304. } else {
  305. mwifiex_dbg(adapter, ERROR, "failed to allocate skb_uap");
  306. }
  307. mwifiex_queue_main_work(adapter);
  308. /* Don't forward Intra-BSS unicast packet to upper layer*/
  309. if (mwifiex_get_sta_entry(priv, p_ethhdr->h_dest))
  310. return 0;
  311. }
  312. /* Forward multicast/broadcast packet to upper layer*/
  313. if (in_interrupt())
  314. netif_rx(skb);
  315. else
  316. netif_rx_ni(skb);
  317. return 0;
  318. }
  319. /*
  320. * This function processes the packet received on AP interface.
  321. *
  322. * The function looks into the RxPD and performs sanity tests on the
  323. * received buffer to ensure its a valid packet before processing it
  324. * further. If the packet is determined to be aggregated, it is
  325. * de-aggregated accordingly. Then skb is passed to AP packet forwarding logic.
  326. *
  327. * The completion callback is called after processing is complete.
  328. */
  329. int mwifiex_process_uap_rx_packet(struct mwifiex_private *priv,
  330. struct sk_buff *skb)
  331. {
  332. struct mwifiex_adapter *adapter = priv->adapter;
  333. int ret;
  334. struct uap_rxpd *uap_rx_pd;
  335. struct rx_packet_hdr *rx_pkt_hdr;
  336. u16 rx_pkt_type;
  337. u8 ta[ETH_ALEN], pkt_type;
  338. unsigned long flags;
  339. struct mwifiex_sta_node *node;
  340. uap_rx_pd = (struct uap_rxpd *)(skb->data);
  341. rx_pkt_type = le16_to_cpu(uap_rx_pd->rx_pkt_type);
  342. rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset);
  343. ether_addr_copy(ta, rx_pkt_hdr->eth803_hdr.h_source);
  344. if ((le16_to_cpu(uap_rx_pd->rx_pkt_offset) +
  345. le16_to_cpu(uap_rx_pd->rx_pkt_length)) > (u16) skb->len) {
  346. mwifiex_dbg(adapter, ERROR,
  347. "wrong rx packet: len=%d, offset=%d, length=%d\n",
  348. skb->len, le16_to_cpu(uap_rx_pd->rx_pkt_offset),
  349. le16_to_cpu(uap_rx_pd->rx_pkt_length));
  350. priv->stats.rx_dropped++;
  351. node = mwifiex_get_sta_entry(priv, ta);
  352. if (node)
  353. node->stats.tx_failed++;
  354. dev_kfree_skb_any(skb);
  355. return 0;
  356. }
  357. if (rx_pkt_type == PKT_TYPE_MGMT) {
  358. ret = mwifiex_process_mgmt_packet(priv, skb);
  359. if (ret)
  360. mwifiex_dbg(adapter, DATA, "Rx of mgmt packet failed");
  361. dev_kfree_skb_any(skb);
  362. return ret;
  363. }
  364. if (rx_pkt_type != PKT_TYPE_BAR && uap_rx_pd->priority < MAX_NUM_TID) {
  365. spin_lock_irqsave(&priv->sta_list_spinlock, flags);
  366. node = mwifiex_get_sta_entry(priv, ta);
  367. if (node)
  368. node->rx_seq[uap_rx_pd->priority] =
  369. le16_to_cpu(uap_rx_pd->seq_num);
  370. spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
  371. }
  372. if (!priv->ap_11n_enabled ||
  373. (!mwifiex_11n_get_rx_reorder_tbl(priv, uap_rx_pd->priority, ta) &&
  374. (le16_to_cpu(uap_rx_pd->rx_pkt_type) != PKT_TYPE_AMSDU))) {
  375. ret = mwifiex_handle_uap_rx_forward(priv, skb);
  376. return ret;
  377. }
  378. /* Reorder and send to kernel */
  379. pkt_type = (u8)le16_to_cpu(uap_rx_pd->rx_pkt_type);
  380. ret = mwifiex_11n_rx_reorder_pkt(priv, le16_to_cpu(uap_rx_pd->seq_num),
  381. uap_rx_pd->priority, ta, pkt_type,
  382. skb);
  383. if (ret || (rx_pkt_type == PKT_TYPE_BAR))
  384. dev_kfree_skb_any(skb);
  385. if (ret)
  386. priv->stats.rx_dropped++;
  387. return ret;
  388. }
  389. /*
  390. * This function fills the TxPD for AP tx packets.
  391. *
  392. * The Tx buffer received by this function should already have the
  393. * header space allocated for TxPD.
  394. *
  395. * This function inserts the TxPD in between interface header and actual
  396. * data and adjusts the buffer pointers accordingly.
  397. *
  398. * The following TxPD fields are set by this function, as required -
  399. * - BSS number
  400. * - Tx packet length and offset
  401. * - Priority
  402. * - Packet delay
  403. * - Priority specific Tx control
  404. * - Flags
  405. */
  406. void *mwifiex_process_uap_txpd(struct mwifiex_private *priv,
  407. struct sk_buff *skb)
  408. {
  409. struct mwifiex_adapter *adapter = priv->adapter;
  410. struct uap_txpd *txpd;
  411. struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb);
  412. int pad;
  413. u16 pkt_type, pkt_offset;
  414. int hroom = (priv->adapter->iface_type == MWIFIEX_USB) ? 0 :
  415. INTF_HEADER_LEN;
  416. if (!skb->len) {
  417. mwifiex_dbg(adapter, ERROR,
  418. "Tx: bad packet length: %d\n", skb->len);
  419. tx_info->status_code = -1;
  420. return skb->data;
  421. }
  422. BUG_ON(skb_headroom(skb) < MWIFIEX_MIN_DATA_HEADER_LEN);
  423. pkt_type = mwifiex_is_skb_mgmt_frame(skb) ? PKT_TYPE_MGMT : 0;
  424. pad = ((void *)skb->data - (sizeof(*txpd) + hroom) - NULL) &
  425. (MWIFIEX_DMA_ALIGN_SZ - 1);
  426. skb_push(skb, sizeof(*txpd) + pad);
  427. txpd = (struct uap_txpd *)skb->data;
  428. memset(txpd, 0, sizeof(*txpd));
  429. txpd->bss_num = priv->bss_num;
  430. txpd->bss_type = priv->bss_type;
  431. txpd->tx_pkt_length = cpu_to_le16((u16)(skb->len - (sizeof(*txpd) +
  432. pad)));
  433. txpd->priority = (u8)skb->priority;
  434. txpd->pkt_delay_2ms = mwifiex_wmm_compute_drv_pkt_delay(priv, skb);
  435. if (tx_info->flags & MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS ||
  436. tx_info->flags & MWIFIEX_BUF_FLAG_ACTION_TX_STATUS) {
  437. txpd->tx_token_id = tx_info->ack_frame_id;
  438. txpd->flags |= MWIFIEX_TXPD_FLAGS_REQ_TX_STATUS;
  439. }
  440. if (txpd->priority < ARRAY_SIZE(priv->wmm.user_pri_pkt_tx_ctrl))
  441. /*
  442. * Set the priority specific tx_control field, setting of 0 will
  443. * cause the default value to be used later in this function.
  444. */
  445. txpd->tx_control =
  446. cpu_to_le32(priv->wmm.user_pri_pkt_tx_ctrl[txpd->priority]);
  447. /* Offset of actual data */
  448. pkt_offset = sizeof(*txpd) + pad;
  449. if (pkt_type == PKT_TYPE_MGMT) {
  450. /* Set the packet type and add header for management frame */
  451. txpd->tx_pkt_type = cpu_to_le16(pkt_type);
  452. pkt_offset += MWIFIEX_MGMT_FRAME_HEADER_SIZE;
  453. }
  454. txpd->tx_pkt_offset = cpu_to_le16(pkt_offset);
  455. /* make space for INTF_HEADER_LEN */
  456. skb_push(skb, hroom);
  457. if (!txpd->tx_control)
  458. /* TxCtrl set by user or default */
  459. txpd->tx_control = cpu_to_le32(priv->pkt_tx_ctrl);
  460. return skb->data;
  461. }