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