1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * NXP Wireless LAN device driver: AP TX and RX data handling
4 *
5 * Copyright 2011-2024 NXP
6 */
7
8 #include "cfg.h"
9 #include "main.h"
10 #include "wmm.h"
11 #include "11n_aggr.h"
12 #include "11n_rxreorder.h"
13
14 /*
15 * Drop bridged pkts from RA list until pending <= low threshold; return true if
16 * any.
17 */
18 static bool
nxpwifi_uap_del_tx_pkts_in_ralist(struct nxpwifi_private * priv,struct list_head * ra_list_head,int tid)19 nxpwifi_uap_del_tx_pkts_in_ralist(struct nxpwifi_private *priv,
20 struct list_head *ra_list_head,
21 int tid)
22 {
23 struct nxpwifi_ra_list_tbl *ra_list;
24 struct sk_buff *skb, *tmp;
25 bool pkt_deleted = false;
26 struct nxpwifi_txinfo *tx_info;
27 struct nxpwifi_adapter *adapter = priv->adapter;
28
29 list_for_each_entry(ra_list, ra_list_head, list) {
30 if (skb_queue_empty(&ra_list->skb_head))
31 continue;
32
33 skb_queue_walk_safe(&ra_list->skb_head, skb, tmp) {
34 tx_info = NXPWIFI_SKB_TXCB(skb);
35 if (tx_info->flags & NXPWIFI_BUF_FLAG_BRIDGED_PKT) {
36 __skb_unlink(skb, &ra_list->skb_head);
37 nxpwifi_write_data_complete(adapter, skb, 0,
38 -1);
39 if (ra_list->tx_paused)
40 priv->wmm.pkts_paused[tid]--;
41 else
42 atomic_dec(&priv->wmm.tx_pkts_queued);
43 pkt_deleted = true;
44 }
45 if ((atomic_read(&adapter->pending_bridged_pkts) <=
46 NXPWIFI_BRIDGED_PKTS_THR_LOW))
47 break;
48 }
49 }
50
51 return pkt_deleted;
52 }
53
54 /* Delete bridged pkts from one RA list; rotate index to keep fairness. */
nxpwifi_uap_cleanup_tx_queues(struct nxpwifi_private * priv)55 static void nxpwifi_uap_cleanup_tx_queues(struct nxpwifi_private *priv)
56 {
57 struct list_head *ra_list;
58 int i;
59
60 spin_lock_bh(&priv->wmm.ra_list_spinlock);
61
62 for (i = 0; i < MAX_NUM_TID; i++, priv->del_list_idx++) {
63 if (priv->del_list_idx == MAX_NUM_TID)
64 priv->del_list_idx = 0;
65 ra_list = &priv->wmm.tid_tbl_ptr[priv->del_list_idx].ra_list;
66 if (nxpwifi_uap_del_tx_pkts_in_ralist(priv, ra_list, i)) {
67 priv->del_list_idx++;
68 break;
69 }
70 }
71
72 spin_unlock_bh(&priv->wmm.ra_list_spinlock);
73 }
74
75 static void
nxpwifi_uap_queue_bridged_pkt(struct nxpwifi_private * priv,struct sk_buff * skb)76 nxpwifi_uap_queue_bridged_pkt(struct nxpwifi_private *priv,
77 struct sk_buff *skb)
78 {
79 struct nxpwifi_adapter *adapter = priv->adapter;
80 struct uap_rxpd *uap_rx_pd;
81 struct rx_packet_hdr *rx_pkt_hdr;
82 struct sk_buff *new_skb;
83 struct nxpwifi_txinfo *tx_info;
84 int hdr_chop;
85 struct ethhdr *p_ethhdr;
86 struct nxpwifi_sta_node *src_node;
87 int index;
88
89 uap_rx_pd = (struct uap_rxpd *)(skb->data);
90 rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset);
91
92 if ((atomic_read(&adapter->pending_bridged_pkts) >=
93 NXPWIFI_BRIDGED_PKTS_THR_HIGH)) {
94 nxpwifi_dbg(adapter, ERROR,
95 "Tx: Bridge packet limit reached. Drop packet!\n");
96 kfree_skb(skb);
97 nxpwifi_uap_cleanup_tx_queues(priv);
98 return;
99 }
100
101 if (sizeof(*rx_pkt_hdr) +
102 le16_to_cpu(uap_rx_pd->rx_pkt_offset) > skb->len) {
103 priv->stats.rx_dropped++;
104 dev_kfree_skb_any(skb);
105 return;
106 }
107
108 if ((!memcmp(&rx_pkt_hdr->rfc1042_hdr, bridge_tunnel_header,
109 sizeof(bridge_tunnel_header))) ||
110 (!memcmp(&rx_pkt_hdr->rfc1042_hdr, rfc1042_header,
111 sizeof(rfc1042_header)) &&
112 rx_pkt_hdr->rfc1042_hdr.snap_type != htons(ETH_P_AARP) &&
113 rx_pkt_hdr->rfc1042_hdr.snap_type != htons(ETH_P_IPX))) {
114 /*
115 * Replace the 803 header and rfc1042 header (llc/snap) with
116 * an Ethernet II header, keep the src/dst and snap_type
117 * (ethertype).
118 *
119 * The firmware only passes up SNAP frames converting all RX
120 * data from 802.11 to 802.2/LLC/SNAP frames.
121 *
122 * To create the Ethernet II, just move the src, dst address
123 * right before the snap_type.
124 */
125 p_ethhdr = (struct ethhdr *)
126 ((u8 *)(&rx_pkt_hdr->eth803_hdr)
127 + sizeof(rx_pkt_hdr->eth803_hdr)
128 + sizeof(rx_pkt_hdr->rfc1042_hdr)
129 - sizeof(rx_pkt_hdr->eth803_hdr.h_dest)
130 - sizeof(rx_pkt_hdr->eth803_hdr.h_source)
131 - sizeof(rx_pkt_hdr->rfc1042_hdr.snap_type));
132 memcpy(p_ethhdr->h_source, rx_pkt_hdr->eth803_hdr.h_source,
133 sizeof(p_ethhdr->h_source));
134 memcpy(p_ethhdr->h_dest, rx_pkt_hdr->eth803_hdr.h_dest,
135 sizeof(p_ethhdr->h_dest));
136 /*
137 * Chop off the rxpd + the excess memory from
138 * 802.2/llc/snap header that was removed.
139 */
140 hdr_chop = (u8 *)p_ethhdr - (u8 *)uap_rx_pd;
141 } else {
142 /* Chop off the rxpd */
143 hdr_chop = (u8 *)&rx_pkt_hdr->eth803_hdr - (u8 *)uap_rx_pd;
144 }
145
146 /*
147 * Chop off the leading header bytes so that it points
148 * to the start of either the reconstructed EthII frame
149 * or the 802.2/llc/snap frame.
150 */
151 skb_pull(skb, hdr_chop);
152
153 if (skb_headroom(skb) < NXPWIFI_MIN_DATA_HEADER_LEN) {
154 nxpwifi_dbg(adapter, ERROR,
155 "data: Tx: insufficient skb headroom %d\n",
156 skb_headroom(skb));
157 /* Insufficient skb headroom - allocate a new skb */
158 new_skb =
159 skb_realloc_headroom(skb, NXPWIFI_MIN_DATA_HEADER_LEN);
160 if (unlikely(!new_skb)) {
161 nxpwifi_dbg(adapter, ERROR,
162 "Tx: cannot allocate new_skb\n");
163 kfree_skb(skb);
164 priv->stats.tx_dropped++;
165 return;
166 }
167
168 kfree_skb(skb);
169 skb = new_skb;
170 nxpwifi_dbg(adapter, INFO,
171 "info: new skb headroom %d\n",
172 skb_headroom(skb));
173 }
174
175 tx_info = NXPWIFI_SKB_TXCB(skb);
176 memset(tx_info, 0, sizeof(*tx_info));
177 tx_info->bss_num = priv->bss_num;
178 tx_info->bss_type = priv->bss_type;
179 tx_info->flags |= NXPWIFI_BUF_FLAG_BRIDGED_PKT;
180
181 rcu_read_lock();
182 src_node = nxpwifi_get_sta_entry(priv, rx_pkt_hdr->eth803_hdr.h_source);
183 if (src_node) {
184 src_node->stats.last_rx = jiffies;
185 src_node->stats.rx_bytes += skb->len;
186 src_node->stats.rx_packets++;
187 src_node->stats.last_tx_rate = uap_rx_pd->rx_rate;
188 src_node->stats.last_tx_htinfo = uap_rx_pd->ht_info;
189 }
190 rcu_read_unlock();
191
192 if (is_unicast_ether_addr(rx_pkt_hdr->eth803_hdr.h_dest)) {
193 /*
194 * Update bridge packet statistics as the
195 * packet is not going to kernel/upper layer.
196 */
197 priv->stats.rx_bytes += skb->len;
198 priv->stats.rx_packets++;
199
200 /*
201 * Sending bridge packet to TX queue, so save the packet
202 * length in TXCB to update statistics in TX complete.
203 */
204 tx_info->pkt_len = skb->len;
205 }
206
207 __net_timestamp(skb);
208
209 index = nxpwifi_1d_to_wmm_queue[skb->priority];
210 atomic_inc(&priv->wmm_tx_pending[index]);
211 nxpwifi_wmm_add_buf_txqueue(priv, skb);
212 atomic_inc(&adapter->tx_pending);
213 atomic_inc(&adapter->pending_bridged_pkts);
214
215 nxpwifi_queue_work(adapter, &adapter->main_work);
216 }
217
218 /* AP fwd: mcast/bcast -> up + bridge; unicast -> bridge if RA assoc, else up. */
nxpwifi_handle_uap_rx_forward(struct nxpwifi_private * priv,struct sk_buff * skb)219 int nxpwifi_handle_uap_rx_forward(struct nxpwifi_private *priv,
220 struct sk_buff *skb)
221 {
222 struct nxpwifi_adapter *adapter = priv->adapter;
223 struct uap_rxpd *uap_rx_pd;
224 struct rx_packet_hdr *rx_pkt_hdr;
225 u8 ra[ETH_ALEN];
226 struct sk_buff *skb_uap;
227 struct nxpwifi_sta_node *node;
228
229 uap_rx_pd = (struct uap_rxpd *)(skb->data);
230 rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset);
231
232 /* don't do packet forwarding in disconnected state */
233 if (!priv->media_connected) {
234 nxpwifi_dbg(adapter, ERROR,
235 "drop packet in disconnected state.\n");
236 dev_kfree_skb_any(skb);
237 return 0;
238 }
239
240 memcpy(ra, rx_pkt_hdr->eth803_hdr.h_dest, ETH_ALEN);
241
242 if (is_multicast_ether_addr(ra)) {
243 skb_uap = skb_copy(skb, GFP_ATOMIC);
244 if (likely(skb_uap)) {
245 nxpwifi_uap_queue_bridged_pkt(priv, skb_uap);
246 } else {
247 nxpwifi_dbg(adapter, ERROR,
248 "failed to copy skb for uAP\n");
249 priv->stats.rx_dropped++;
250 dev_kfree_skb_any(skb);
251 return -ENOMEM;
252 }
253 } else {
254 node = nxpwifi_get_sta_entry_rcu(priv, ra);
255 if (node) {
256 /* Requeue Intra-BSS packet */
257 nxpwifi_uap_queue_bridged_pkt(priv, skb);
258 return 0;
259 }
260 }
261
262 /* Forward unicat/Inter-BSS packets to kernel. */
263 return nxpwifi_process_rx_packet(priv, skb);
264 }
265
nxpwifi_uap_recv_packet(struct nxpwifi_private * priv,struct sk_buff * skb)266 int nxpwifi_uap_recv_packet(struct nxpwifi_private *priv,
267 struct sk_buff *skb)
268 {
269 struct nxpwifi_adapter *adapter = priv->adapter;
270 struct nxpwifi_sta_node *src_node, *dst_node;
271 struct ethhdr *p_ethhdr;
272 struct sk_buff *skb_uap;
273 struct nxpwifi_txinfo *tx_info;
274
275 if (!skb)
276 return -ENOMEM;
277
278 p_ethhdr = (void *)skb->data;
279 rcu_read_lock();
280 src_node = nxpwifi_get_sta_entry(priv, p_ethhdr->h_source);
281 if (src_node) {
282 src_node->stats.last_rx = jiffies;
283 src_node->stats.rx_bytes += skb->len;
284 src_node->stats.rx_packets++;
285 }
286 dst_node = nxpwifi_get_sta_entry(priv, p_ethhdr->h_dest);
287 rcu_read_unlock();
288
289 if (is_multicast_ether_addr(p_ethhdr->h_dest) || dst_node) {
290 if (skb_headroom(skb) < NXPWIFI_MIN_DATA_HEADER_LEN)
291 skb_uap =
292 skb_realloc_headroom(skb, NXPWIFI_MIN_DATA_HEADER_LEN);
293 else
294 skb_uap = skb_copy(skb, GFP_ATOMIC);
295
296 if (likely(skb_uap)) {
297 tx_info = NXPWIFI_SKB_TXCB(skb_uap);
298 memset(tx_info, 0, sizeof(*tx_info));
299 tx_info->bss_num = priv->bss_num;
300 tx_info->bss_type = priv->bss_type;
301 tx_info->flags |= NXPWIFI_BUF_FLAG_BRIDGED_PKT;
302 __net_timestamp(skb_uap);
303 nxpwifi_wmm_add_buf_txqueue(priv, skb_uap);
304 atomic_inc(&adapter->tx_pending);
305 atomic_inc(&adapter->pending_bridged_pkts);
306 if ((atomic_read(&adapter->pending_bridged_pkts) >=
307 NXPWIFI_BRIDGED_PKTS_THR_HIGH)) {
308 nxpwifi_dbg(adapter, ERROR,
309 "Tx: Bridge packet limit reached. Drop packet!\n");
310 nxpwifi_uap_cleanup_tx_queues(priv);
311 }
312
313 } else {
314 nxpwifi_dbg(adapter, ERROR, "failed to allocate skb_uap");
315 }
316
317 nxpwifi_queue_work(adapter, &adapter->main_work);
318 /* Don't forward Intra-BSS unicast packet to upper layer*/
319
320 if (dst_node)
321 return 0;
322 }
323
324 skb->dev = priv->netdev;
325 skb->protocol = eth_type_trans(skb, priv->netdev);
326 skb->ip_summed = CHECKSUM_NONE;
327
328 /* Forward multicast/broadcast packet to upper layer*/
329 netif_rx(skb);
330 return 0;
331 }
332
333 /* Process AP RX: check RxPD/len, handle mgmt or 11n reorder/AMSDU, then forward. */
nxpwifi_process_uap_rx_packet(struct nxpwifi_private * priv,struct sk_buff * skb)334 int nxpwifi_process_uap_rx_packet(struct nxpwifi_private *priv,
335 struct sk_buff *skb)
336 {
337 struct nxpwifi_adapter *adapter = priv->adapter;
338 int ret;
339 struct uap_rxpd *uap_rx_pd;
340 struct rx_packet_hdr *rx_pkt_hdr;
341 u16 rx_pkt_type;
342 u8 ta[ETH_ALEN], pkt_type;
343 struct nxpwifi_sta_node *node;
344
345 uap_rx_pd = (struct uap_rxpd *)(skb->data);
346 rx_pkt_type = le16_to_cpu(uap_rx_pd->rx_pkt_type);
347 rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset);
348
349 if (le16_to_cpu(uap_rx_pd->rx_pkt_offset) +
350 sizeof(rx_pkt_hdr->eth803_hdr) > skb->len) {
351 nxpwifi_dbg(adapter, ERROR,
352 "wrong rx packet for struct ethhdr: len=%d, offset=%d\n",
353 skb->len, le16_to_cpu(uap_rx_pd->rx_pkt_offset));
354 priv->stats.rx_dropped++;
355 dev_kfree_skb_any(skb);
356 return 0;
357 }
358
359 ether_addr_copy(ta, rx_pkt_hdr->eth803_hdr.h_source);
360
361 if ((le16_to_cpu(uap_rx_pd->rx_pkt_offset) +
362 le16_to_cpu(uap_rx_pd->rx_pkt_length)) > (u16)skb->len) {
363 nxpwifi_dbg(adapter, ERROR,
364 "wrong rx packet: len=%d, offset=%d, length=%d\n",
365 skb->len, le16_to_cpu(uap_rx_pd->rx_pkt_offset),
366 le16_to_cpu(uap_rx_pd->rx_pkt_length));
367 priv->stats.rx_dropped++;
368 rcu_read_lock();
369 node = nxpwifi_get_sta_entry(priv, ta);
370 if (node)
371 node->stats.tx_failed++;
372 rcu_read_unlock();
373
374 dev_kfree_skb_any(skb);
375 return 0;
376 }
377
378 if (rx_pkt_type == PKT_TYPE_MGMT) {
379 ret = nxpwifi_process_mgmt_packet(priv, skb);
380 if (ret && (ret != -EINPROGRESS))
381 nxpwifi_dbg(adapter, DATA, "Rx of mgmt packet failed");
382 if (ret != -EINPROGRESS)
383 dev_kfree_skb_any(skb);
384 return ret;
385 }
386
387 if (rx_pkt_type != PKT_TYPE_BAR && uap_rx_pd->priority < MAX_NUM_TID) {
388 rcu_read_lock();
389 node = nxpwifi_get_sta_entry(priv, ta);
390 if (node)
391 node->rx_seq[uap_rx_pd->priority] =
392 le16_to_cpu(uap_rx_pd->seq_num);
393 rcu_read_unlock();
394 }
395
396 if (!priv->ap_11n_enabled ||
397 (!nxpwifi_11n_get_rx_reorder_tbl(priv, uap_rx_pd->priority, ta) &&
398 (le16_to_cpu(uap_rx_pd->rx_pkt_type) != PKT_TYPE_AMSDU))) {
399 ret = nxpwifi_handle_uap_rx_forward(priv, skb);
400 return ret;
401 }
402
403 /* Reorder and send to kernel */
404 pkt_type = (u8)le16_to_cpu(uap_rx_pd->rx_pkt_type);
405 ret = nxpwifi_11n_rx_reorder_pkt(priv, le16_to_cpu(uap_rx_pd->seq_num),
406 uap_rx_pd->priority, ta, pkt_type, skb);
407
408 if (ret || rx_pkt_type == PKT_TYPE_BAR)
409 dev_kfree_skb_any(skb);
410
411 if (ret)
412 priv->stats.rx_dropped++;
413
414 return ret;
415 }
416
417 /*
418 * Build TxPD for AP TX: push aligned TxPD; set bss, len/off, prio, delay, txctl,
419 * flags.
420 */
nxpwifi_process_uap_txpd(struct nxpwifi_private * priv,struct sk_buff * skb)421 void nxpwifi_process_uap_txpd(struct nxpwifi_private *priv,
422 struct sk_buff *skb)
423 {
424 struct nxpwifi_adapter *adapter = priv->adapter;
425 struct uap_txpd *txpd;
426 struct nxpwifi_txinfo *tx_info = NXPWIFI_SKB_TXCB(skb);
427 int pad;
428 u16 pkt_type, pkt_offset;
429 int hroom = adapter->intf_hdr_len;
430
431 pkt_type = nxpwifi_is_skb_mgmt_frame(skb) ? PKT_TYPE_MGMT : 0;
432
433 pad = ((uintptr_t)skb->data - (sizeof(*txpd) + hroom)) &
434 (NXPWIFI_DMA_ALIGN_SZ - 1);
435
436 skb_push(skb, sizeof(*txpd) + pad);
437
438 txpd = (struct uap_txpd *)skb->data;
439 memset(txpd, 0, sizeof(*txpd));
440 txpd->bss_num = priv->bss_num;
441 txpd->bss_type = priv->bss_type;
442 txpd->tx_pkt_length = cpu_to_le16((u16)(skb->len - (sizeof(*txpd) +
443 pad)));
444 txpd->priority = (u8)skb->priority;
445
446 txpd->pkt_delay_2ms = nxpwifi_wmm_compute_drv_pkt_delay(priv, skb);
447
448 if (tx_info->flags & NXPWIFI_BUF_FLAG_EAPOL_TX_STATUS ||
449 tx_info->flags & NXPWIFI_BUF_FLAG_ACTION_TX_STATUS) {
450 txpd->tx_token_id = tx_info->ack_frame_id;
451 txpd->flags |= NXPWIFI_TXPD_FLAGS_REQ_TX_STATUS;
452 }
453
454 if (txpd->priority < ARRAY_SIZE(priv->wmm.user_pri_pkt_tx_ctrl))
455 /*
456 * Set the priority specific tx_control field, setting of 0 will
457 * cause the default value to be used later in this function.
458 */
459 txpd->tx_control =
460 cpu_to_le32(priv->wmm.user_pri_pkt_tx_ctrl[txpd->priority]);
461
462 /* Offset of actual data */
463 pkt_offset = sizeof(*txpd) + pad;
464 if (pkt_type == PKT_TYPE_MGMT) {
465 /* Set the packet type and add header for management frame */
466 txpd->tx_pkt_type = cpu_to_le16(pkt_type);
467 pkt_offset += NXPWIFI_MGMT_FRAME_HEADER_SIZE;
468 }
469
470 txpd->tx_pkt_offset = cpu_to_le16(pkt_offset);
471
472 /* make space for adapter->intf_hdr_len */
473 skb_push(skb, hroom);
474
475 if (!txpd->tx_control)
476 /* TxCtrl set by user or default */
477 txpd->tx_control = cpu_to_le32(priv->pkt_tx_ctrl);
478 }
479