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