1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * NXP Wireless LAN device driver: generic TX/RX data handling 4 * 5 * Copyright 2011-2024 NXP 6 */ 7 8 #include "cfg.h" 9 #include "util.h" 10 #include "fw.h" 11 #include "main.h" 12 #include "wmm.h" 13 14 /* 15 * Parse the RxPD, select the target interface, and dispatch the packet for 16 * handling. 17 */ 18 int nxpwifi_handle_rx_packet(struct nxpwifi_adapter *adapter, 19 struct sk_buff *skb) 20 { 21 struct nxpwifi_private *priv = 22 nxpwifi_get_priv(adapter, NXPWIFI_BSS_ROLE_ANY); 23 struct rxpd *local_rx_pd; 24 struct nxpwifi_rxinfo *rx_info = NXPWIFI_SKB_RXCB(skb); 25 int ret; 26 27 local_rx_pd = (struct rxpd *)(skb->data); 28 /* Get the BSS number from rxpd, get corresponding priv */ 29 priv = nxpwifi_get_priv_by_id(adapter, local_rx_pd->bss_num & 30 BSS_NUM_MASK, local_rx_pd->bss_type); 31 if (!priv) 32 priv = nxpwifi_get_priv(adapter, NXPWIFI_BSS_ROLE_ANY); 33 34 if (!priv) { 35 nxpwifi_dbg(adapter, ERROR, 36 "data: priv not found. Drop RX packet\n"); 37 dev_kfree_skb_any(skb); 38 return -EINVAL; 39 } 40 41 nxpwifi_dbg_dump(adapter, DAT_D, "rx pkt:", skb->data, 42 min_t(size_t, skb->len, DEBUG_DUMP_DATA_MAX_LEN)); 43 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 48 if (priv->bss_role == NXPWIFI_BSS_ROLE_UAP) 49 ret = nxpwifi_process_uap_rx_packet(priv, skb); 50 else 51 ret = nxpwifi_process_sta_rx_packet(priv, skb); 52 53 return ret; 54 } 55 EXPORT_SYMBOL_GPL(nxpwifi_handle_rx_packet); 56 57 /* 58 * Add TxPD, validate, send the packet to firmware, then run completion 59 * callback. 60 */ 61 int nxpwifi_process_tx(struct nxpwifi_private *priv, struct sk_buff *skb, 62 struct nxpwifi_tx_param *tx_param) 63 { 64 int hroom, ret; 65 struct nxpwifi_adapter *adapter = priv->adapter; 66 struct txpd *local_tx_pd = NULL; 67 struct nxpwifi_sta_node *dest_node; 68 struct ethhdr *hdr = (void *)skb->data; 69 70 if (unlikely(!skb->len || 71 skb_headroom(skb) < NXPWIFI_MIN_DATA_HEADER_LEN)) { 72 ret = -EINVAL; 73 goto out; 74 } 75 76 hroom = adapter->intf_hdr_len; 77 78 if (priv->bss_role == NXPWIFI_BSS_ROLE_UAP) { 79 rcu_read_lock(); 80 dest_node = nxpwifi_get_sta_entry(priv, hdr->h_dest); 81 if (dest_node) { 82 dest_node->stats.tx_bytes += skb->len; 83 dest_node->stats.tx_packets++; 84 } 85 rcu_read_unlock(); 86 nxpwifi_process_uap_txpd(priv, skb); 87 } else { 88 nxpwifi_process_sta_txpd(priv, skb); 89 } 90 91 if ((adapter->data_sent || adapter->tx_lock_flag)) { 92 skb_queue_tail(&adapter->tx_data_q, skb); 93 atomic_inc(&adapter->tx_queued); 94 return 0; 95 } 96 97 if (GET_BSS_ROLE(priv) == NXPWIFI_BSS_ROLE_STA) 98 local_tx_pd = (struct txpd *)(skb->data + hroom); 99 ret = adapter->if_ops.host_to_card(adapter, 100 NXPWIFI_TYPE_DATA, 101 skb, tx_param); 102 nxpwifi_dbg_dump(adapter, DAT_D, "tx pkt:", skb->data, 103 min_t(size_t, skb->len, DEBUG_DUMP_DATA_MAX_LEN)); 104 105 out: 106 switch (ret) { 107 case -ENOSR: 108 nxpwifi_dbg(adapter, DATA, "data: -ENOSR is returned\n"); 109 break; 110 case -EBUSY: 111 if ((GET_BSS_ROLE(priv) == NXPWIFI_BSS_ROLE_STA) && 112 adapter->pps_uapsd_mode && adapter->tx_lock_flag) { 113 priv->adapter->tx_lock_flag = false; 114 if (local_tx_pd) 115 local_tx_pd->flags = 0; 116 } 117 nxpwifi_dbg(adapter, ERROR, "data: -EBUSY is returned\n"); 118 break; 119 case -EINPROGRESS: 120 break; 121 case -EINVAL: 122 nxpwifi_dbg(adapter, ERROR, 123 "malformed skb (length: %u, headroom: %u)\n", 124 skb->len, skb_headroom(skb)); 125 fallthrough; 126 case 0: 127 nxpwifi_write_data_complete(adapter, skb, 0, ret); 128 break; 129 default: 130 nxpwifi_dbg(adapter, ERROR, 131 "nxpwifi_write_data_async failed: 0x%X\n", 132 ret); 133 adapter->dbg.num_tx_host_to_card_failure++; 134 nxpwifi_write_data_complete(adapter, skb, 0, ret); 135 break; 136 } 137 138 return ret; 139 } 140 141 static int nxpwifi_host_to_card(struct nxpwifi_adapter *adapter, 142 struct sk_buff *skb, 143 struct nxpwifi_tx_param *tx_param) 144 { 145 struct txpd *local_tx_pd = NULL; 146 u8 *head_ptr = skb->data; 147 int ret = 0; 148 struct nxpwifi_private *priv; 149 struct nxpwifi_txinfo *tx_info; 150 151 tx_info = NXPWIFI_SKB_TXCB(skb); 152 priv = nxpwifi_get_priv_by_id(adapter, tx_info->bss_num, 153 tx_info->bss_type); 154 if (!priv) { 155 nxpwifi_dbg(adapter, ERROR, 156 "data: priv not found. Drop TX packet\n"); 157 adapter->dbg.num_tx_host_to_card_failure++; 158 nxpwifi_write_data_complete(adapter, skb, 0, 0); 159 return ret; 160 } 161 if (GET_BSS_ROLE(priv) == NXPWIFI_BSS_ROLE_STA) 162 local_tx_pd = (struct txpd *)(head_ptr + adapter->intf_hdr_len); 163 164 ret = adapter->if_ops.host_to_card(adapter, 165 NXPWIFI_TYPE_DATA, 166 skb, tx_param); 167 168 switch (ret) { 169 case -ENOSR: 170 nxpwifi_dbg(adapter, ERROR, "data: -ENOSR is returned\n"); 171 break; 172 case -EBUSY: 173 if ((GET_BSS_ROLE(priv) == NXPWIFI_BSS_ROLE_STA) && 174 adapter->pps_uapsd_mode && 175 adapter->tx_lock_flag) { 176 priv->adapter->tx_lock_flag = false; 177 if (local_tx_pd) 178 local_tx_pd->flags = 0; 179 } 180 skb_queue_head(&adapter->tx_data_q, skb); 181 if (tx_info->flags & NXPWIFI_BUF_FLAG_AGGR_PKT) 182 atomic_add(tx_info->aggr_num, &adapter->tx_queued); 183 else 184 atomic_inc(&adapter->tx_queued); 185 nxpwifi_dbg(adapter, ERROR, "data: -EBUSY is returned\n"); 186 break; 187 case -EINPROGRESS: 188 break; 189 case 0: 190 nxpwifi_write_data_complete(adapter, skb, 0, ret); 191 break; 192 default: 193 nxpwifi_dbg(adapter, ERROR, 194 "nxpwifi_write_data_async failed: 0x%X\n", ret); 195 adapter->dbg.num_tx_host_to_card_failure++; 196 nxpwifi_write_data_complete(adapter, skb, 0, ret); 197 break; 198 } 199 return ret; 200 } 201 202 static int 203 nxpwifi_dequeue_tx_queue(struct nxpwifi_adapter *adapter) 204 { 205 struct sk_buff *skb, *skb_next; 206 struct nxpwifi_txinfo *tx_info; 207 struct nxpwifi_tx_param tx_param; 208 209 skb = skb_dequeue(&adapter->tx_data_q); 210 if (!skb) 211 return -ENOMEM; 212 213 tx_info = NXPWIFI_SKB_TXCB(skb); 214 if (tx_info->flags & NXPWIFI_BUF_FLAG_AGGR_PKT) 215 atomic_sub(tx_info->aggr_num, &adapter->tx_queued); 216 else 217 atomic_dec(&adapter->tx_queued); 218 219 if (!skb_queue_empty(&adapter->tx_data_q)) 220 skb_next = skb_peek(&adapter->tx_data_q); 221 else 222 skb_next = NULL; 223 tx_param.next_pkt_len = ((skb_next) ? skb_next->len : 0); 224 if (!tx_param.next_pkt_len) { 225 if (!nxpwifi_wmm_lists_empty(adapter)) 226 tx_param.next_pkt_len = 1; 227 } 228 return nxpwifi_host_to_card(adapter, skb, &tx_param); 229 } 230 231 void 232 nxpwifi_process_tx_queue(struct nxpwifi_adapter *adapter) 233 { 234 do { 235 if (adapter->data_sent || adapter->tx_lock_flag) 236 break; 237 if (nxpwifi_dequeue_tx_queue(adapter)) 238 break; 239 } while (!skb_queue_empty(&adapter->tx_data_q)); 240 } 241 242 /* 243 * Packet send completion callback handler. 244 * 245 * It either frees the buffer directly or forwards it to another 246 * completion callback which checks conditions, updates statistics, 247 * wakes up stalled traffic queue if required, and then frees the buffer. 248 */ 249 int nxpwifi_write_data_complete(struct nxpwifi_adapter *adapter, 250 struct sk_buff *skb, int aggr, int status) 251 { 252 struct nxpwifi_private *priv; 253 struct nxpwifi_txinfo *tx_info; 254 struct netdev_queue *txq; 255 int index; 256 257 if (!skb) 258 return 0; 259 260 tx_info = NXPWIFI_SKB_TXCB(skb); 261 priv = nxpwifi_get_priv_by_id(adapter, tx_info->bss_num, 262 tx_info->bss_type); 263 if (!priv) 264 goto done; 265 266 nxpwifi_set_trans_start(priv->netdev); 267 268 if (tx_info->flags & NXPWIFI_BUF_FLAG_BRIDGED_PKT) 269 atomic_dec_return(&adapter->pending_bridged_pkts); 270 271 if (tx_info->flags & NXPWIFI_BUF_FLAG_AGGR_PKT) 272 goto done; 273 274 if (!status) { 275 priv->stats.tx_packets++; 276 priv->stats.tx_bytes += tx_info->pkt_len; 277 if (priv->tx_timeout_cnt) 278 priv->tx_timeout_cnt = 0; 279 } else { 280 priv->stats.tx_errors++; 281 } 282 283 if (aggr) 284 /* For skb_aggr, do not wake up tx queue */ 285 goto done; 286 287 atomic_dec(&adapter->tx_pending); 288 289 index = nxpwifi_1d_to_wmm_queue[skb->priority]; 290 if (atomic_dec_return(&priv->wmm_tx_pending[index]) < LOW_TX_PENDING) { 291 txq = netdev_get_tx_queue(priv->netdev, index); 292 if (netif_tx_queue_stopped(txq)) { 293 netif_tx_wake_queue(txq); 294 nxpwifi_dbg(adapter, DATA, "wake queue: %d\n", index); 295 } 296 } 297 done: 298 dev_kfree_skb_any(skb); 299 300 return 0; 301 } 302 EXPORT_SYMBOL_GPL(nxpwifi_write_data_complete); 303 304 void nxpwifi_parse_tx_status_event(struct nxpwifi_private *priv, 305 void *event_body) 306 { 307 struct tx_status_event *tx_status = (void *)priv->adapter->event_body; 308 struct sk_buff *ack_skb; 309 struct nxpwifi_txinfo *tx_info; 310 311 if (!tx_status->tx_token_id) 312 return; 313 314 spin_lock_bh(&priv->ack_status_lock); 315 ack_skb = xa_erase(&priv->ack_status_frames, tx_status->tx_token_id); 316 spin_unlock_bh(&priv->ack_status_lock); 317 318 if (ack_skb) { 319 tx_info = NXPWIFI_SKB_TXCB(ack_skb); 320 321 if (tx_info->flags & NXPWIFI_BUF_FLAG_EAPOL_TX_STATUS) { 322 /* consumes ack_skb */ 323 skb_complete_wifi_ack(ack_skb, !tx_status->status); 324 } else { 325 /* Remove broadcast address which was added by driver */ 326 memmove(ack_skb->data + 327 sizeof(struct ieee80211_hdr_3addr) + 328 NXPWIFI_MGMT_FRAME_HEADER_SIZE + sizeof(u16), 329 ack_skb->data + 330 sizeof(struct ieee80211_hdr_3addr) + 331 NXPWIFI_MGMT_FRAME_HEADER_SIZE + sizeof(u16) + 332 ETH_ALEN, ack_skb->len - 333 (sizeof(struct ieee80211_hdr_3addr) + 334 NXPWIFI_MGMT_FRAME_HEADER_SIZE + sizeof(u16) + 335 ETH_ALEN)); 336 ack_skb->len = ack_skb->len - ETH_ALEN; 337 /* 338 * Remove driver's proprietary header including 2 bytes 339 * of packet length and pass actual management frame buffer 340 * to cfg80211. 341 */ 342 cfg80211_mgmt_tx_status(&priv->wdev, tx_info->cookie, 343 ack_skb->data + 344 NXPWIFI_MGMT_FRAME_HEADER_SIZE + 345 sizeof(u16), ack_skb->len - 346 (NXPWIFI_MGMT_FRAME_HEADER_SIZE 347 + sizeof(u16)), 348 !tx_status->status, GFP_ATOMIC); 349 dev_kfree_skb_any(ack_skb); 350 } 351 } 352 } 353