.. | .. |
---|
| 1 | +// SPDX-License-Identifier: ISC |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (c) 2012-2017 Qualcomm Atheros, Inc. |
---|
3 | | - * Copyright (c) 2018, The Linux Foundation. All rights reserved. |
---|
4 | | - * |
---|
5 | | - * Permission to use, copy, modify, and/or distribute this software for any |
---|
6 | | - * purpose with or without fee is hereby granted, provided that the above |
---|
7 | | - * copyright notice and this permission notice appear in all copies. |
---|
8 | | - * |
---|
9 | | - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
---|
10 | | - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
---|
11 | | - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
---|
12 | | - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
---|
13 | | - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
---|
14 | | - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
---|
15 | | - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
---|
| 4 | + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. |
---|
16 | 5 | */ |
---|
17 | 6 | |
---|
18 | 7 | #include <linux/etherdevice.h> |
---|
.. | .. |
---|
21 | 10 | #include <linux/moduleparam.h> |
---|
22 | 11 | #include <linux/ip.h> |
---|
23 | 12 | #include <linux/ipv6.h> |
---|
| 13 | +#include <linux/if_vlan.h> |
---|
24 | 14 | #include <net/ipv6.h> |
---|
25 | 15 | #include <linux/prefetch.h> |
---|
26 | 16 | |
---|
.. | .. |
---|
30 | 20 | #include "trace.h" |
---|
31 | 21 | #include "txrx_edma.h" |
---|
32 | 22 | |
---|
33 | | -static bool rtap_include_phy_info; |
---|
34 | | -module_param(rtap_include_phy_info, bool, 0444); |
---|
35 | | -MODULE_PARM_DESC(rtap_include_phy_info, |
---|
36 | | - " Include PHY info in the radiotap header, default - no"); |
---|
37 | | - |
---|
38 | 23 | bool rx_align_2; |
---|
39 | 24 | module_param(rx_align_2, bool, 0444); |
---|
40 | 25 | MODULE_PARM_DESC(rx_align_2, " align Rx buffers on 4*n+2, default - no"); |
---|
.. | .. |
---|
42 | 27 | bool rx_large_buf; |
---|
43 | 28 | module_param(rx_large_buf, bool, 0444); |
---|
44 | 29 | MODULE_PARM_DESC(rx_large_buf, " allocate 8KB RX buffers, default - no"); |
---|
| 30 | + |
---|
| 31 | +/* Drop Tx packets in case Tx ring is full */ |
---|
| 32 | +bool drop_if_ring_full; |
---|
45 | 33 | |
---|
46 | 34 | static inline uint wil_rx_snaplen(void) |
---|
47 | 35 | { |
---|
.. | .. |
---|
261 | 249 | vring->ctx = NULL; |
---|
262 | 250 | } |
---|
263 | 251 | |
---|
264 | | -/** |
---|
265 | | - * Allocate one skb for Rx VRING |
---|
| 252 | +/* Allocate one skb for Rx VRING |
---|
266 | 253 | * |
---|
267 | 254 | * Safe to call from IRQ |
---|
268 | 255 | */ |
---|
.. | .. |
---|
307 | 294 | return 0; |
---|
308 | 295 | } |
---|
309 | 296 | |
---|
310 | | -/** |
---|
311 | | - * Adds radiotap header |
---|
| 297 | +/* Adds radiotap header |
---|
312 | 298 | * |
---|
313 | 299 | * Any error indicated as "Bad FCS" |
---|
314 | 300 | * |
---|
.. | .. |
---|
332 | 318 | u8 mcs_flags; |
---|
333 | 319 | u8 mcs_index; |
---|
334 | 320 | } __packed; |
---|
335 | | - struct wil6210_rtap_vendor { |
---|
336 | | - struct wil6210_rtap rtap; |
---|
337 | | - /* vendor */ |
---|
338 | | - u8 vendor_oui[3] __aligned(2); |
---|
339 | | - u8 vendor_ns; |
---|
340 | | - __le16 vendor_skip; |
---|
341 | | - u8 vendor_data[0]; |
---|
342 | | - } __packed; |
---|
343 | 321 | struct vring_rx_desc *d = wil_skb_rxdesc(skb); |
---|
344 | | - struct wil6210_rtap_vendor *rtap_vendor; |
---|
| 322 | + struct wil6210_rtap *rtap; |
---|
345 | 323 | int rtap_len = sizeof(struct wil6210_rtap); |
---|
346 | | - int phy_length = 0; /* phy info header size, bytes */ |
---|
347 | | - static char phy_data[128]; |
---|
348 | 324 | struct ieee80211_channel *ch = wil->monitor_chandef.chan; |
---|
349 | | - |
---|
350 | | - if (rtap_include_phy_info) { |
---|
351 | | - rtap_len = sizeof(*rtap_vendor) + sizeof(*d); |
---|
352 | | - /* calculate additional length */ |
---|
353 | | - if (d->dma.status & RX_DMA_STATUS_PHY_INFO) { |
---|
354 | | - /** |
---|
355 | | - * PHY info starts from 8-byte boundary |
---|
356 | | - * there are 8-byte lines, last line may be partially |
---|
357 | | - * written (HW bug), thus FW configures for last line |
---|
358 | | - * to be excessive. Driver skips this last line. |
---|
359 | | - */ |
---|
360 | | - int len = min_t(int, 8 + sizeof(phy_data), |
---|
361 | | - wil_rxdesc_phy_length(d)); |
---|
362 | | - |
---|
363 | | - if (len > 8) { |
---|
364 | | - void *p = skb_tail_pointer(skb); |
---|
365 | | - void *pa = PTR_ALIGN(p, 8); |
---|
366 | | - |
---|
367 | | - if (skb_tailroom(skb) >= len + (pa - p)) { |
---|
368 | | - phy_length = len - 8; |
---|
369 | | - memcpy(phy_data, pa, phy_length); |
---|
370 | | - } |
---|
371 | | - } |
---|
372 | | - } |
---|
373 | | - rtap_len += phy_length; |
---|
374 | | - } |
---|
375 | 325 | |
---|
376 | 326 | if (skb_headroom(skb) < rtap_len && |
---|
377 | 327 | pskb_expand_head(skb, rtap_len, 0, GFP_ATOMIC)) { |
---|
.. | .. |
---|
379 | 329 | return; |
---|
380 | 330 | } |
---|
381 | 331 | |
---|
382 | | - rtap_vendor = skb_push(skb, rtap_len); |
---|
383 | | - memset(rtap_vendor, 0, rtap_len); |
---|
| 332 | + rtap = skb_push(skb, rtap_len); |
---|
| 333 | + memset(rtap, 0, rtap_len); |
---|
384 | 334 | |
---|
385 | | - rtap_vendor->rtap.rthdr.it_version = PKTHDR_RADIOTAP_VERSION; |
---|
386 | | - rtap_vendor->rtap.rthdr.it_len = cpu_to_le16(rtap_len); |
---|
387 | | - rtap_vendor->rtap.rthdr.it_present = cpu_to_le32( |
---|
388 | | - (1 << IEEE80211_RADIOTAP_FLAGS) | |
---|
| 335 | + rtap->rthdr.it_version = PKTHDR_RADIOTAP_VERSION; |
---|
| 336 | + rtap->rthdr.it_len = cpu_to_le16(rtap_len); |
---|
| 337 | + rtap->rthdr.it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | |
---|
389 | 338 | (1 << IEEE80211_RADIOTAP_CHANNEL) | |
---|
390 | 339 | (1 << IEEE80211_RADIOTAP_MCS)); |
---|
391 | 340 | if (d->dma.status & RX_DMA_STATUS_ERROR) |
---|
392 | | - rtap_vendor->rtap.flags |= IEEE80211_RADIOTAP_F_BADFCS; |
---|
| 341 | + rtap->flags |= IEEE80211_RADIOTAP_F_BADFCS; |
---|
393 | 342 | |
---|
394 | | - rtap_vendor->rtap.chnl_freq = cpu_to_le16(ch ? ch->center_freq : 58320); |
---|
395 | | - rtap_vendor->rtap.chnl_flags = cpu_to_le16(0); |
---|
| 343 | + rtap->chnl_freq = cpu_to_le16(ch ? ch->center_freq : 58320); |
---|
| 344 | + rtap->chnl_flags = cpu_to_le16(0); |
---|
396 | 345 | |
---|
397 | | - rtap_vendor->rtap.mcs_present = IEEE80211_RADIOTAP_MCS_HAVE_MCS; |
---|
398 | | - rtap_vendor->rtap.mcs_flags = 0; |
---|
399 | | - rtap_vendor->rtap.mcs_index = wil_rxdesc_mcs(d); |
---|
400 | | - |
---|
401 | | - if (rtap_include_phy_info) { |
---|
402 | | - rtap_vendor->rtap.rthdr.it_present |= cpu_to_le32(1 << |
---|
403 | | - IEEE80211_RADIOTAP_VENDOR_NAMESPACE); |
---|
404 | | - /* OUI for Wilocity 04:ce:14 */ |
---|
405 | | - rtap_vendor->vendor_oui[0] = 0x04; |
---|
406 | | - rtap_vendor->vendor_oui[1] = 0xce; |
---|
407 | | - rtap_vendor->vendor_oui[2] = 0x14; |
---|
408 | | - rtap_vendor->vendor_ns = 1; |
---|
409 | | - /* Rx descriptor + PHY data */ |
---|
410 | | - rtap_vendor->vendor_skip = cpu_to_le16(sizeof(*d) + |
---|
411 | | - phy_length); |
---|
412 | | - memcpy(rtap_vendor->vendor_data, (void *)d, sizeof(*d)); |
---|
413 | | - memcpy(rtap_vendor->vendor_data + sizeof(*d), phy_data, |
---|
414 | | - phy_length); |
---|
415 | | - } |
---|
| 346 | + rtap->mcs_present = IEEE80211_RADIOTAP_MCS_HAVE_MCS; |
---|
| 347 | + rtap->mcs_flags = 0; |
---|
| 348 | + rtap->mcs_index = wil_rxdesc_mcs(d); |
---|
416 | 349 | } |
---|
417 | 350 | |
---|
418 | 351 | static bool wil_is_rx_idle(struct wil6210_priv *wil) |
---|
.. | .. |
---|
427 | 360 | return true; |
---|
428 | 361 | } |
---|
429 | 362 | |
---|
430 | | -/** |
---|
431 | | - * reap 1 frame from @swhead |
---|
| 363 | +static int wil_rx_get_cid_by_skb(struct wil6210_priv *wil, struct sk_buff *skb) |
---|
| 364 | +{ |
---|
| 365 | + struct vring_rx_desc *d = wil_skb_rxdesc(skb); |
---|
| 366 | + int mid = wil_rxdesc_mid(d); |
---|
| 367 | + struct wil6210_vif *vif = wil->vifs[mid]; |
---|
| 368 | + /* cid from DMA descriptor is limited to 3 bits. |
---|
| 369 | + * In case of cid>=8, the value would be cid modulo 8 and we need to |
---|
| 370 | + * find real cid by locating the transmitter (ta) inside sta array |
---|
| 371 | + */ |
---|
| 372 | + int cid = wil_rxdesc_cid(d); |
---|
| 373 | + unsigned int snaplen = wil_rx_snaplen(); |
---|
| 374 | + struct ieee80211_hdr_3addr *hdr; |
---|
| 375 | + int i; |
---|
| 376 | + unsigned char *ta; |
---|
| 377 | + u8 ftype; |
---|
| 378 | + |
---|
| 379 | + /* in monitor mode there are no connections */ |
---|
| 380 | + if (vif->wdev.iftype == NL80211_IFTYPE_MONITOR) |
---|
| 381 | + return cid; |
---|
| 382 | + |
---|
| 383 | + ftype = wil_rxdesc_ftype(d) << 2; |
---|
| 384 | + if (likely(ftype == IEEE80211_FTYPE_DATA)) { |
---|
| 385 | + if (unlikely(skb->len < ETH_HLEN + snaplen)) { |
---|
| 386 | + wil_err_ratelimited(wil, |
---|
| 387 | + "Short data frame, len = %d\n", |
---|
| 388 | + skb->len); |
---|
| 389 | + return -ENOENT; |
---|
| 390 | + } |
---|
| 391 | + ta = wil_skb_get_sa(skb); |
---|
| 392 | + } else { |
---|
| 393 | + if (unlikely(skb->len < sizeof(struct ieee80211_hdr_3addr))) { |
---|
| 394 | + wil_err_ratelimited(wil, "Short frame, len = %d\n", |
---|
| 395 | + skb->len); |
---|
| 396 | + return -ENOENT; |
---|
| 397 | + } |
---|
| 398 | + hdr = (void *)skb->data; |
---|
| 399 | + ta = hdr->addr2; |
---|
| 400 | + } |
---|
| 401 | + |
---|
| 402 | + if (wil->max_assoc_sta <= WIL6210_RX_DESC_MAX_CID) |
---|
| 403 | + return cid; |
---|
| 404 | + |
---|
| 405 | + /* assuming no concurrency between AP interfaces and STA interfaces. |
---|
| 406 | + * multista is used only in P2P_GO or AP mode. In other modes return |
---|
| 407 | + * cid from the rx descriptor |
---|
| 408 | + */ |
---|
| 409 | + if (vif->wdev.iftype != NL80211_IFTYPE_P2P_GO && |
---|
| 410 | + vif->wdev.iftype != NL80211_IFTYPE_AP) |
---|
| 411 | + return cid; |
---|
| 412 | + |
---|
| 413 | + /* For Rx packets cid from rx descriptor is limited to 3 bits (0..7), |
---|
| 414 | + * to find the real cid, compare transmitter address with the stored |
---|
| 415 | + * stations mac address in the driver sta array |
---|
| 416 | + */ |
---|
| 417 | + for (i = cid; i < wil->max_assoc_sta; i += WIL6210_RX_DESC_MAX_CID) { |
---|
| 418 | + if (wil->sta[i].status != wil_sta_unused && |
---|
| 419 | + ether_addr_equal(wil->sta[i].addr, ta)) { |
---|
| 420 | + cid = i; |
---|
| 421 | + break; |
---|
| 422 | + } |
---|
| 423 | + } |
---|
| 424 | + if (i >= wil->max_assoc_sta) { |
---|
| 425 | + wil_err_ratelimited(wil, "Could not find cid for frame with transmit addr = %pM, iftype = %d, frametype = %d, len = %d\n", |
---|
| 426 | + ta, vif->wdev.iftype, ftype, skb->len); |
---|
| 427 | + cid = -ENOENT; |
---|
| 428 | + } |
---|
| 429 | + |
---|
| 430 | + return cid; |
---|
| 431 | +} |
---|
| 432 | + |
---|
| 433 | +/* reap 1 frame from @swhead |
---|
432 | 434 | * |
---|
433 | 435 | * Rx descriptor copied to skb->cb |
---|
434 | 436 | * |
---|
.. | .. |
---|
452 | 454 | int i; |
---|
453 | 455 | struct wil_net_stats *stats; |
---|
454 | 456 | |
---|
455 | | - BUILD_BUG_ON(sizeof(struct vring_rx_desc) > sizeof(skb->cb)); |
---|
| 457 | + BUILD_BUG_ON(sizeof(struct skb_rx_info) > sizeof(skb->cb)); |
---|
456 | 458 | |
---|
457 | 459 | again: |
---|
458 | 460 | if (unlikely(wil_ring_is_empty(vring))) |
---|
.. | .. |
---|
484 | 486 | wil_hex_dump_txrx("RxD ", DUMP_PREFIX_NONE, 32, 4, |
---|
485 | 487 | (const void *)d, sizeof(*d), false); |
---|
486 | 488 | |
---|
487 | | - cid = wil_rxdesc_cid(d); |
---|
488 | 489 | mid = wil_rxdesc_mid(d); |
---|
489 | 490 | vif = wil->vifs[mid]; |
---|
490 | 491 | |
---|
.. | .. |
---|
495 | 496 | goto again; |
---|
496 | 497 | } |
---|
497 | 498 | ndev = vif_to_ndev(vif); |
---|
498 | | - stats = &wil->sta[cid].stats; |
---|
499 | | - |
---|
500 | 499 | if (unlikely(dmalen > sz)) { |
---|
501 | | - wil_err(wil, "Rx size too large: %d bytes!\n", dmalen); |
---|
502 | | - stats->rx_large_frame++; |
---|
| 500 | + wil_err_ratelimited(wil, "Rx size too large: %d bytes!\n", |
---|
| 501 | + dmalen); |
---|
503 | 502 | kfree_skb(skb); |
---|
504 | 503 | goto again; |
---|
505 | 504 | } |
---|
.. | .. |
---|
509 | 508 | |
---|
510 | 509 | wil_hex_dump_txrx("Rx ", DUMP_PREFIX_OFFSET, 16, 1, |
---|
511 | 510 | skb->data, skb_headlen(skb), false); |
---|
| 511 | + |
---|
| 512 | + cid = wil_rx_get_cid_by_skb(wil, skb); |
---|
| 513 | + if (cid == -ENOENT) { |
---|
| 514 | + kfree_skb(skb); |
---|
| 515 | + goto again; |
---|
| 516 | + } |
---|
| 517 | + wil_skb_set_cid(skb, (u8)cid); |
---|
| 518 | + stats = &wil->sta[cid].stats; |
---|
512 | 519 | |
---|
513 | 520 | stats->last_mcs_rx = wil_rxdesc_mcs(d); |
---|
514 | 521 | if (stats->last_mcs_rx < ARRAY_SIZE(stats->rx_per_mcs)) |
---|
.. | .. |
---|
556 | 563 | goto again; |
---|
557 | 564 | } |
---|
558 | 565 | |
---|
559 | | - if (unlikely(skb->len < ETH_HLEN + snaplen)) { |
---|
560 | | - wil_err(wil, "Short frame, len = %d\n", skb->len); |
---|
561 | | - stats->rx_short_frame++; |
---|
562 | | - kfree_skb(skb); |
---|
563 | | - goto again; |
---|
564 | | - } |
---|
565 | | - |
---|
566 | 566 | /* L4 IDENT is on when HW calculated checksum, check status |
---|
567 | 567 | * and in case of error drop the packet |
---|
568 | 568 | * higher stack layers will handle retransmission (if required) |
---|
.. | .. |
---|
594 | 594 | return skb; |
---|
595 | 595 | } |
---|
596 | 596 | |
---|
597 | | -/** |
---|
598 | | - * allocate and fill up to @count buffers in rx ring |
---|
| 597 | +/* allocate and fill up to @count buffers in rx ring |
---|
599 | 598 | * buffers posted at @swtail |
---|
600 | 599 | * Note: we have a single RX queue for servicing all VIFs, but we |
---|
601 | 600 | * allocate skbs with headroom according to main interface only. This |
---|
.. | .. |
---|
659 | 658 | static int wil_rx_crypto_check(struct wil6210_priv *wil, struct sk_buff *skb) |
---|
660 | 659 | { |
---|
661 | 660 | struct vring_rx_desc *d = wil_skb_rxdesc(skb); |
---|
662 | | - int cid = wil_rxdesc_cid(d); |
---|
| 661 | + int cid = wil_skb_get_cid(skb); |
---|
663 | 662 | int tid = wil_rxdesc_tid(d); |
---|
664 | 663 | int key_id = wil_rxdesc_key_id(d); |
---|
665 | 664 | int mc = wil_rxdesc_mcast(d); |
---|
.. | .. |
---|
667 | 666 | struct wil_tid_crypto_rx *c = mc ? &s->group_crypto_rx : |
---|
668 | 667 | &s->tid_crypto_rx[tid]; |
---|
669 | 668 | struct wil_tid_crypto_rx_single *cc = &c->key_id[key_id]; |
---|
670 | | - const u8 *pn = (u8 *)&d->mac.pn_15_0; |
---|
| 669 | + const u8 *pn = (u8 *)&d->mac.pn; |
---|
671 | 670 | |
---|
672 | 671 | if (!cc->key_set) { |
---|
673 | 672 | wil_err_ratelimited(wil, |
---|
.. | .. |
---|
707 | 706 | { |
---|
708 | 707 | struct vring_rx_desc *d = wil_skb_rxdesc(skb); |
---|
709 | 708 | |
---|
710 | | - *cid = wil_rxdesc_cid(d); /* always 0..7, no need to check */ |
---|
| 709 | + *cid = wil_skb_get_cid(skb); |
---|
711 | 710 | *security = wil_rxdesc_security(d); |
---|
| 711 | +} |
---|
| 712 | + |
---|
| 713 | +/* |
---|
| 714 | + * Check if skb is ptk eapol key message |
---|
| 715 | + * |
---|
| 716 | + * returns a pointer to the start of the eapol key structure, NULL |
---|
| 717 | + * if frame is not PTK eapol key |
---|
| 718 | + */ |
---|
| 719 | +static struct wil_eapol_key *wil_is_ptk_eapol_key(struct wil6210_priv *wil, |
---|
| 720 | + struct sk_buff *skb) |
---|
| 721 | +{ |
---|
| 722 | + u8 *buf; |
---|
| 723 | + const struct wil_1x_hdr *hdr; |
---|
| 724 | + struct wil_eapol_key *key; |
---|
| 725 | + u16 key_info; |
---|
| 726 | + int len = skb->len; |
---|
| 727 | + |
---|
| 728 | + if (!skb_mac_header_was_set(skb)) { |
---|
| 729 | + wil_err(wil, "mac header was not set\n"); |
---|
| 730 | + return NULL; |
---|
| 731 | + } |
---|
| 732 | + |
---|
| 733 | + len -= skb_mac_offset(skb); |
---|
| 734 | + |
---|
| 735 | + if (len < sizeof(struct ethhdr) + sizeof(struct wil_1x_hdr) + |
---|
| 736 | + sizeof(struct wil_eapol_key)) |
---|
| 737 | + return NULL; |
---|
| 738 | + |
---|
| 739 | + buf = skb_mac_header(skb) + sizeof(struct ethhdr); |
---|
| 740 | + |
---|
| 741 | + hdr = (const struct wil_1x_hdr *)buf; |
---|
| 742 | + if (hdr->type != WIL_1X_TYPE_EAPOL_KEY) |
---|
| 743 | + return NULL; |
---|
| 744 | + |
---|
| 745 | + key = (struct wil_eapol_key *)(buf + sizeof(struct wil_1x_hdr)); |
---|
| 746 | + if (key->type != WIL_EAPOL_KEY_TYPE_WPA && |
---|
| 747 | + key->type != WIL_EAPOL_KEY_TYPE_RSN) |
---|
| 748 | + return NULL; |
---|
| 749 | + |
---|
| 750 | + key_info = be16_to_cpu(key->key_info); |
---|
| 751 | + if (!(key_info & WIL_KEY_INFO_KEY_TYPE)) /* check if pairwise */ |
---|
| 752 | + return NULL; |
---|
| 753 | + |
---|
| 754 | + return key; |
---|
| 755 | +} |
---|
| 756 | + |
---|
| 757 | +static bool wil_skb_is_eap_3(struct wil6210_priv *wil, struct sk_buff *skb) |
---|
| 758 | +{ |
---|
| 759 | + struct wil_eapol_key *key; |
---|
| 760 | + u16 key_info; |
---|
| 761 | + |
---|
| 762 | + key = wil_is_ptk_eapol_key(wil, skb); |
---|
| 763 | + if (!key) |
---|
| 764 | + return false; |
---|
| 765 | + |
---|
| 766 | + key_info = be16_to_cpu(key->key_info); |
---|
| 767 | + if (key_info & (WIL_KEY_INFO_MIC | |
---|
| 768 | + WIL_KEY_INFO_ENCR_KEY_DATA)) { |
---|
| 769 | + /* 3/4 of 4-Way Handshake */ |
---|
| 770 | + wil_dbg_misc(wil, "EAPOL key message 3\n"); |
---|
| 771 | + return true; |
---|
| 772 | + } |
---|
| 773 | + /* 1/4 of 4-Way Handshake */ |
---|
| 774 | + wil_dbg_misc(wil, "EAPOL key message 1\n"); |
---|
| 775 | + |
---|
| 776 | + return false; |
---|
| 777 | +} |
---|
| 778 | + |
---|
| 779 | +static bool wil_skb_is_eap_4(struct wil6210_priv *wil, struct sk_buff *skb) |
---|
| 780 | +{ |
---|
| 781 | + struct wil_eapol_key *key; |
---|
| 782 | + u32 *nonce, i; |
---|
| 783 | + |
---|
| 784 | + key = wil_is_ptk_eapol_key(wil, skb); |
---|
| 785 | + if (!key) |
---|
| 786 | + return false; |
---|
| 787 | + |
---|
| 788 | + nonce = (u32 *)key->key_nonce; |
---|
| 789 | + for (i = 0; i < WIL_EAP_NONCE_LEN / sizeof(u32); i++, nonce++) { |
---|
| 790 | + if (*nonce != 0) { |
---|
| 791 | + /* message 2/4 */ |
---|
| 792 | + wil_dbg_misc(wil, "EAPOL key message 2\n"); |
---|
| 793 | + return false; |
---|
| 794 | + } |
---|
| 795 | + } |
---|
| 796 | + wil_dbg_misc(wil, "EAPOL key message 4\n"); |
---|
| 797 | + |
---|
| 798 | + return true; |
---|
| 799 | +} |
---|
| 800 | + |
---|
| 801 | +void wil_enable_tx_key_worker(struct work_struct *work) |
---|
| 802 | +{ |
---|
| 803 | + struct wil6210_vif *vif = container_of(work, |
---|
| 804 | + struct wil6210_vif, enable_tx_key_worker); |
---|
| 805 | + struct wil6210_priv *wil = vif_to_wil(vif); |
---|
| 806 | + int rc, cid; |
---|
| 807 | + |
---|
| 808 | + rtnl_lock(); |
---|
| 809 | + if (vif->ptk_rekey_state != WIL_REKEY_WAIT_M4_SENT) { |
---|
| 810 | + wil_dbg_misc(wil, "Invalid rekey state = %d\n", |
---|
| 811 | + vif->ptk_rekey_state); |
---|
| 812 | + rtnl_unlock(); |
---|
| 813 | + return; |
---|
| 814 | + } |
---|
| 815 | + |
---|
| 816 | + cid = wil_find_cid_by_idx(wil, vif->mid, 0); |
---|
| 817 | + if (!wil_cid_valid(wil, cid)) { |
---|
| 818 | + wil_err(wil, "Invalid cid = %d\n", cid); |
---|
| 819 | + rtnl_unlock(); |
---|
| 820 | + return; |
---|
| 821 | + } |
---|
| 822 | + |
---|
| 823 | + wil_dbg_misc(wil, "Apply PTK key after eapol was sent out\n"); |
---|
| 824 | + rc = wmi_add_cipher_key(vif, 0, wil->sta[cid].addr, 0, NULL, |
---|
| 825 | + WMI_KEY_USE_APPLY_PTK); |
---|
| 826 | + |
---|
| 827 | + vif->ptk_rekey_state = WIL_REKEY_IDLE; |
---|
| 828 | + rtnl_unlock(); |
---|
| 829 | + |
---|
| 830 | + if (rc) |
---|
| 831 | + wil_err(wil, "Apply PTK key failed %d\n", rc); |
---|
| 832 | +} |
---|
| 833 | + |
---|
| 834 | +void wil_tx_complete_handle_eapol(struct wil6210_vif *vif, struct sk_buff *skb) |
---|
| 835 | +{ |
---|
| 836 | + struct wil6210_priv *wil = vif_to_wil(vif); |
---|
| 837 | + struct wireless_dev *wdev = vif_to_wdev(vif); |
---|
| 838 | + bool q = false; |
---|
| 839 | + |
---|
| 840 | + if (wdev->iftype != NL80211_IFTYPE_STATION || |
---|
| 841 | + !test_bit(WMI_FW_CAPABILITY_SPLIT_REKEY, wil->fw_capabilities)) |
---|
| 842 | + return; |
---|
| 843 | + |
---|
| 844 | + /* check if skb is an EAP message 4/4 */ |
---|
| 845 | + if (!wil_skb_is_eap_4(wil, skb)) |
---|
| 846 | + return; |
---|
| 847 | + |
---|
| 848 | + spin_lock_bh(&wil->eap_lock); |
---|
| 849 | + switch (vif->ptk_rekey_state) { |
---|
| 850 | + case WIL_REKEY_IDLE: |
---|
| 851 | + /* ignore idle state, can happen due to M4 retransmission */ |
---|
| 852 | + break; |
---|
| 853 | + case WIL_REKEY_M3_RECEIVED: |
---|
| 854 | + vif->ptk_rekey_state = WIL_REKEY_IDLE; |
---|
| 855 | + break; |
---|
| 856 | + case WIL_REKEY_WAIT_M4_SENT: |
---|
| 857 | + q = true; |
---|
| 858 | + break; |
---|
| 859 | + default: |
---|
| 860 | + wil_err(wil, "Unknown rekey state = %d", |
---|
| 861 | + vif->ptk_rekey_state); |
---|
| 862 | + } |
---|
| 863 | + spin_unlock_bh(&wil->eap_lock); |
---|
| 864 | + |
---|
| 865 | + if (q) { |
---|
| 866 | + q = queue_work(wil->wmi_wq, &vif->enable_tx_key_worker); |
---|
| 867 | + wil_dbg_misc(wil, "queue_work of enable_tx_key_worker -> %d\n", |
---|
| 868 | + q); |
---|
| 869 | + } |
---|
| 870 | +} |
---|
| 871 | + |
---|
| 872 | +static void wil_rx_handle_eapol(struct wil6210_vif *vif, struct sk_buff *skb) |
---|
| 873 | +{ |
---|
| 874 | + struct wil6210_priv *wil = vif_to_wil(vif); |
---|
| 875 | + struct wireless_dev *wdev = vif_to_wdev(vif); |
---|
| 876 | + |
---|
| 877 | + if (wdev->iftype != NL80211_IFTYPE_STATION || |
---|
| 878 | + !test_bit(WMI_FW_CAPABILITY_SPLIT_REKEY, wil->fw_capabilities)) |
---|
| 879 | + return; |
---|
| 880 | + |
---|
| 881 | + /* check if skb is a EAP message 3/4 */ |
---|
| 882 | + if (!wil_skb_is_eap_3(wil, skb)) |
---|
| 883 | + return; |
---|
| 884 | + |
---|
| 885 | + if (vif->ptk_rekey_state == WIL_REKEY_IDLE) |
---|
| 886 | + vif->ptk_rekey_state = WIL_REKEY_M3_RECEIVED; |
---|
712 | 887 | } |
---|
713 | 888 | |
---|
714 | 889 | /* |
---|
715 | 890 | * Pass Rx packet to the netif. Update statistics. |
---|
716 | 891 | * Called in softirq context (NAPI poll). |
---|
717 | 892 | */ |
---|
718 | | -void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev) |
---|
| 893 | +void wil_netif_rx(struct sk_buff *skb, struct net_device *ndev, int cid, |
---|
| 894 | + struct wil_net_stats *stats, bool gro) |
---|
719 | 895 | { |
---|
720 | | - gro_result_t rc = GRO_NORMAL; |
---|
721 | 896 | struct wil6210_vif *vif = ndev_to_vif(ndev); |
---|
722 | 897 | struct wil6210_priv *wil = ndev_to_wil(ndev); |
---|
723 | 898 | struct wireless_dev *wdev = vif_to_wdev(vif); |
---|
724 | 899 | unsigned int len = skb->len; |
---|
725 | | - int cid; |
---|
726 | | - int security; |
---|
727 | | - struct ethhdr *eth = (void *)skb->data; |
---|
| 900 | + u8 *sa, *da = wil_skb_get_da(skb); |
---|
728 | 901 | /* here looking for DA, not A1, thus Rxdesc's 'mcast' indication |
---|
729 | 902 | * is not suitable, need to look at data |
---|
730 | 903 | */ |
---|
731 | | - int mcast = is_multicast_ether_addr(eth->h_dest); |
---|
732 | | - struct wil_net_stats *stats; |
---|
| 904 | + int mcast = is_multicast_ether_addr(da); |
---|
733 | 905 | struct sk_buff *xmit_skb = NULL; |
---|
734 | | - static const char * const gro_res_str[] = { |
---|
735 | | - [GRO_MERGED] = "GRO_MERGED", |
---|
736 | | - [GRO_MERGED_FREE] = "GRO_MERGED_FREE", |
---|
737 | | - [GRO_HELD] = "GRO_HELD", |
---|
738 | | - [GRO_NORMAL] = "GRO_NORMAL", |
---|
739 | | - [GRO_DROP] = "GRO_DROP", |
---|
740 | | - [GRO_CONSUMED] = "GRO_CONSUMED", |
---|
741 | | - }; |
---|
742 | | - |
---|
743 | | - wil->txrx_ops.get_netif_rx_params(skb, &cid, &security); |
---|
744 | | - |
---|
745 | | - stats = &wil->sta[cid].stats; |
---|
746 | | - |
---|
747 | | - if (ndev->features & NETIF_F_RXHASH) |
---|
748 | | - /* fake L4 to ensure it won't be re-calculated later |
---|
749 | | - * set hash to any non-zero value to activate rps |
---|
750 | | - * mechanism, core will be chosen according |
---|
751 | | - * to user-level rps configuration. |
---|
752 | | - */ |
---|
753 | | - skb_set_hash(skb, 1, PKT_HASH_TYPE_L4); |
---|
754 | | - |
---|
755 | | - skb_orphan(skb); |
---|
756 | | - |
---|
757 | | - if (security && (wil->txrx_ops.rx_crypto_check(wil, skb) != 0)) { |
---|
758 | | - rc = GRO_DROP; |
---|
759 | | - dev_kfree_skb(skb); |
---|
760 | | - stats->rx_replay++; |
---|
761 | | - goto stats; |
---|
762 | | - } |
---|
763 | | - |
---|
764 | | - /* check errors reported by HW and update statistics */ |
---|
765 | | - if (unlikely(wil->txrx_ops.rx_error_check(wil, skb, stats))) { |
---|
766 | | - dev_kfree_skb(skb); |
---|
767 | | - return; |
---|
768 | | - } |
---|
769 | 906 | |
---|
770 | 907 | if (wdev->iftype == NL80211_IFTYPE_STATION) { |
---|
771 | | - if (mcast && ether_addr_equal(eth->h_source, ndev->dev_addr)) { |
---|
| 908 | + sa = wil_skb_get_sa(skb); |
---|
| 909 | + if (mcast && ether_addr_equal(sa, ndev->dev_addr)) { |
---|
772 | 910 | /* mcast packet looped back to us */ |
---|
773 | | - rc = GRO_DROP; |
---|
774 | 911 | dev_kfree_skb(skb); |
---|
775 | | - goto stats; |
---|
| 912 | + ndev->stats.rx_dropped++; |
---|
| 913 | + stats->rx_dropped++; |
---|
| 914 | + wil_dbg_txrx(wil, "Rx drop %d bytes\n", len); |
---|
| 915 | + return; |
---|
776 | 916 | } |
---|
777 | 917 | } else if (wdev->iftype == NL80211_IFTYPE_AP && !vif->ap_isolate) { |
---|
778 | 918 | if (mcast) { |
---|
.. | .. |
---|
781 | 921 | */ |
---|
782 | 922 | xmit_skb = skb_copy(skb, GFP_ATOMIC); |
---|
783 | 923 | } else { |
---|
784 | | - int xmit_cid = wil_find_cid(wil, vif->mid, |
---|
785 | | - eth->h_dest); |
---|
| 924 | + int xmit_cid = wil_find_cid(wil, vif->mid, da); |
---|
786 | 925 | |
---|
787 | 926 | if (xmit_cid >= 0) { |
---|
788 | 927 | /* The destination station is associated to |
---|
.. | .. |
---|
812 | 951 | if (skb) { /* deliver to local stack */ |
---|
813 | 952 | skb->protocol = eth_type_trans(skb, ndev); |
---|
814 | 953 | skb->dev = ndev; |
---|
815 | | - rc = napi_gro_receive(&wil->napi_rx, skb); |
---|
816 | | - wil_dbg_txrx(wil, "Rx complete %d bytes => %s\n", |
---|
817 | | - len, gro_res_str[rc]); |
---|
| 954 | + |
---|
| 955 | + if (skb->protocol == cpu_to_be16(ETH_P_PAE)) |
---|
| 956 | + wil_rx_handle_eapol(vif, skb); |
---|
| 957 | + |
---|
| 958 | + if (gro) |
---|
| 959 | + napi_gro_receive(&wil->napi_rx, skb); |
---|
| 960 | + else |
---|
| 961 | + netif_rx_ni(skb); |
---|
818 | 962 | } |
---|
819 | | -stats: |
---|
820 | | - /* statistics. rc set to GRO_NORMAL for AP bridging */ |
---|
821 | | - if (unlikely(rc == GRO_DROP)) { |
---|
822 | | - ndev->stats.rx_dropped++; |
---|
823 | | - stats->rx_dropped++; |
---|
824 | | - wil_dbg_txrx(wil, "Rx drop %d bytes\n", len); |
---|
825 | | - } else { |
---|
826 | | - ndev->stats.rx_packets++; |
---|
827 | | - stats->rx_packets++; |
---|
828 | | - ndev->stats.rx_bytes += len; |
---|
829 | | - stats->rx_bytes += len; |
---|
830 | | - if (mcast) |
---|
831 | | - ndev->stats.multicast++; |
---|
832 | | - } |
---|
| 963 | + ndev->stats.rx_packets++; |
---|
| 964 | + stats->rx_packets++; |
---|
| 965 | + ndev->stats.rx_bytes += len; |
---|
| 966 | + stats->rx_bytes += len; |
---|
| 967 | + if (mcast) |
---|
| 968 | + ndev->stats.multicast++; |
---|
833 | 969 | } |
---|
834 | 970 | |
---|
835 | | -/** |
---|
836 | | - * Proceed all completed skb's from Rx VRING |
---|
| 971 | +void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev) |
---|
| 972 | +{ |
---|
| 973 | + int cid, security; |
---|
| 974 | + struct wil6210_priv *wil = ndev_to_wil(ndev); |
---|
| 975 | + struct wil_net_stats *stats; |
---|
| 976 | + |
---|
| 977 | + wil->txrx_ops.get_netif_rx_params(skb, &cid, &security); |
---|
| 978 | + |
---|
| 979 | + stats = &wil->sta[cid].stats; |
---|
| 980 | + |
---|
| 981 | + skb_orphan(skb); |
---|
| 982 | + |
---|
| 983 | + if (security && (wil->txrx_ops.rx_crypto_check(wil, skb) != 0)) { |
---|
| 984 | + wil_dbg_txrx(wil, "Rx drop %d bytes\n", skb->len); |
---|
| 985 | + dev_kfree_skb(skb); |
---|
| 986 | + ndev->stats.rx_dropped++; |
---|
| 987 | + stats->rx_replay++; |
---|
| 988 | + stats->rx_dropped++; |
---|
| 989 | + return; |
---|
| 990 | + } |
---|
| 991 | + |
---|
| 992 | + /* check errors reported by HW and update statistics */ |
---|
| 993 | + if (unlikely(wil->txrx_ops.rx_error_check(wil, skb, stats))) { |
---|
| 994 | + dev_kfree_skb(skb); |
---|
| 995 | + return; |
---|
| 996 | + } |
---|
| 997 | + |
---|
| 998 | + wil_netif_rx(skb, ndev, cid, stats, true); |
---|
| 999 | +} |
---|
| 1000 | + |
---|
| 1001 | +/* Proceed all completed skb's from Rx VRING |
---|
837 | 1002 | * |
---|
838 | 1003 | * Safe to call from NAPI poll, i.e. softirq with interrupts enabled |
---|
839 | 1004 | */ |
---|
.. | .. |
---|
953 | 1118 | void wil_tx_data_init(struct wil_ring_tx_data *txdata) |
---|
954 | 1119 | { |
---|
955 | 1120 | spin_lock_bh(&txdata->lock); |
---|
956 | | - txdata->dot1x_open = 0; |
---|
| 1121 | + txdata->dot1x_open = false; |
---|
957 | 1122 | txdata->enabled = 0; |
---|
958 | 1123 | txdata->idle = 0; |
---|
959 | 1124 | txdata->last_idle = 0; |
---|
.. | .. |
---|
980 | 1145 | .ring_size = cpu_to_le16(size), |
---|
981 | 1146 | }, |
---|
982 | 1147 | .ringid = id, |
---|
983 | | - .cidxtid = mk_cidxtid(cid, tid), |
---|
984 | 1148 | .encap_trans_type = WMI_VRING_ENC_TYPE_802_3, |
---|
985 | 1149 | .mac_ctrl = 0, |
---|
986 | 1150 | .to_resolution = 0, |
---|
.. | .. |
---|
999 | 1163 | }; |
---|
1000 | 1164 | struct wil_ring *vring = &wil->ring_tx[id]; |
---|
1001 | 1165 | struct wil_ring_tx_data *txdata = &wil->ring_tx_data[id]; |
---|
| 1166 | + |
---|
| 1167 | + if (cid >= WIL6210_RX_DESC_MAX_CID) { |
---|
| 1168 | + cmd.vring_cfg.cidxtid = CIDXTID_EXTENDED_CID_TID; |
---|
| 1169 | + cmd.vring_cfg.cid = cid; |
---|
| 1170 | + cmd.vring_cfg.tid = tid; |
---|
| 1171 | + } else { |
---|
| 1172 | + cmd.vring_cfg.cidxtid = mk_cidxtid(cid, tid); |
---|
| 1173 | + } |
---|
1002 | 1174 | |
---|
1003 | 1175 | wil_dbg_misc(wil, "vring_init_tx: max_mpdu_size %d\n", |
---|
1004 | 1176 | cmd.vring_cfg.tx_sw_ring.max_mpdu_size); |
---|
.. | .. |
---|
1025 | 1197 | if (!vif->privacy) |
---|
1026 | 1198 | txdata->dot1x_open = true; |
---|
1027 | 1199 | rc = wmi_call(wil, WMI_VRING_CFG_CMDID, vif->mid, &cmd, sizeof(cmd), |
---|
1028 | | - WMI_VRING_CFG_DONE_EVENTID, &reply, sizeof(reply), 100); |
---|
| 1200 | + WMI_VRING_CFG_DONE_EVENTID, &reply, sizeof(reply), |
---|
| 1201 | + WIL_WMI_CALL_GENERAL_TO_MS); |
---|
1029 | 1202 | if (rc) |
---|
1030 | 1203 | goto out_free; |
---|
1031 | 1204 | |
---|
.. | .. |
---|
1052 | 1225 | txdata->enabled = 0; |
---|
1053 | 1226 | spin_unlock_bh(&txdata->lock); |
---|
1054 | 1227 | wil_vring_free(wil, vring); |
---|
1055 | | - wil->ring2cid_tid[id][0] = WIL6210_MAX_CID; |
---|
| 1228 | + wil->ring2cid_tid[id][0] = wil->max_assoc_sta; |
---|
1056 | 1229 | wil->ring2cid_tid[id][1] = 0; |
---|
1057 | 1230 | |
---|
1058 | 1231 | out: |
---|
1059 | 1232 | |
---|
| 1233 | + return rc; |
---|
| 1234 | +} |
---|
| 1235 | + |
---|
| 1236 | +static int wil_tx_vring_modify(struct wil6210_vif *vif, int ring_id, int cid, |
---|
| 1237 | + int tid) |
---|
| 1238 | +{ |
---|
| 1239 | + struct wil6210_priv *wil = vif_to_wil(vif); |
---|
| 1240 | + int rc; |
---|
| 1241 | + struct wmi_vring_cfg_cmd cmd = { |
---|
| 1242 | + .action = cpu_to_le32(WMI_VRING_CMD_MODIFY), |
---|
| 1243 | + .vring_cfg = { |
---|
| 1244 | + .tx_sw_ring = { |
---|
| 1245 | + .max_mpdu_size = |
---|
| 1246 | + cpu_to_le16(wil_mtu2macbuf(mtu_max)), |
---|
| 1247 | + .ring_size = 0, |
---|
| 1248 | + }, |
---|
| 1249 | + .ringid = ring_id, |
---|
| 1250 | + .cidxtid = mk_cidxtid(cid, tid), |
---|
| 1251 | + .encap_trans_type = WMI_VRING_ENC_TYPE_802_3, |
---|
| 1252 | + .mac_ctrl = 0, |
---|
| 1253 | + .to_resolution = 0, |
---|
| 1254 | + .agg_max_wsize = 0, |
---|
| 1255 | + .schd_params = { |
---|
| 1256 | + .priority = cpu_to_le16(0), |
---|
| 1257 | + .timeslot_us = cpu_to_le16(0xfff), |
---|
| 1258 | + }, |
---|
| 1259 | + }, |
---|
| 1260 | + }; |
---|
| 1261 | + struct { |
---|
| 1262 | + struct wmi_cmd_hdr wmi; |
---|
| 1263 | + struct wmi_vring_cfg_done_event cmd; |
---|
| 1264 | + } __packed reply = { |
---|
| 1265 | + .cmd = {.status = WMI_FW_STATUS_FAILURE}, |
---|
| 1266 | + }; |
---|
| 1267 | + struct wil_ring *vring = &wil->ring_tx[ring_id]; |
---|
| 1268 | + struct wil_ring_tx_data *txdata = &wil->ring_tx_data[ring_id]; |
---|
| 1269 | + |
---|
| 1270 | + wil_dbg_misc(wil, "vring_modify: ring %d cid %d tid %d\n", ring_id, |
---|
| 1271 | + cid, tid); |
---|
| 1272 | + lockdep_assert_held(&wil->mutex); |
---|
| 1273 | + |
---|
| 1274 | + if (!vring->va) { |
---|
| 1275 | + wil_err(wil, "Tx ring [%d] not allocated\n", ring_id); |
---|
| 1276 | + return -EINVAL; |
---|
| 1277 | + } |
---|
| 1278 | + |
---|
| 1279 | + if (wil->ring2cid_tid[ring_id][0] != cid || |
---|
| 1280 | + wil->ring2cid_tid[ring_id][1] != tid) { |
---|
| 1281 | + wil_err(wil, "ring info does not match cid=%u tid=%u\n", |
---|
| 1282 | + wil->ring2cid_tid[ring_id][0], |
---|
| 1283 | + wil->ring2cid_tid[ring_id][1]); |
---|
| 1284 | + } |
---|
| 1285 | + |
---|
| 1286 | + cmd.vring_cfg.tx_sw_ring.ring_mem_base = cpu_to_le64(vring->pa); |
---|
| 1287 | + |
---|
| 1288 | + rc = wmi_call(wil, WMI_VRING_CFG_CMDID, vif->mid, &cmd, sizeof(cmd), |
---|
| 1289 | + WMI_VRING_CFG_DONE_EVENTID, &reply, sizeof(reply), |
---|
| 1290 | + WIL_WMI_CALL_GENERAL_TO_MS); |
---|
| 1291 | + if (rc) |
---|
| 1292 | + goto fail; |
---|
| 1293 | + |
---|
| 1294 | + if (reply.cmd.status != WMI_FW_STATUS_SUCCESS) { |
---|
| 1295 | + wil_err(wil, "Tx modify failed, status 0x%02x\n", |
---|
| 1296 | + reply.cmd.status); |
---|
| 1297 | + rc = -EINVAL; |
---|
| 1298 | + goto fail; |
---|
| 1299 | + } |
---|
| 1300 | + |
---|
| 1301 | + /* set BA aggregation window size to 0 to force a new BA with the |
---|
| 1302 | + * new AP |
---|
| 1303 | + */ |
---|
| 1304 | + txdata->agg_wsize = 0; |
---|
| 1305 | + if (txdata->dot1x_open && agg_wsize >= 0) |
---|
| 1306 | + wil_addba_tx_request(wil, ring_id, agg_wsize); |
---|
| 1307 | + |
---|
| 1308 | + return 0; |
---|
| 1309 | +fail: |
---|
| 1310 | + spin_lock_bh(&txdata->lock); |
---|
| 1311 | + txdata->dot1x_open = false; |
---|
| 1312 | + txdata->enabled = 0; |
---|
| 1313 | + spin_unlock_bh(&txdata->lock); |
---|
| 1314 | + wil->ring2cid_tid[ring_id][0] = wil->max_assoc_sta; |
---|
| 1315 | + wil->ring2cid_tid[ring_id][1] = 0; |
---|
1060 | 1316 | return rc; |
---|
1061 | 1317 | } |
---|
1062 | 1318 | |
---|
.. | .. |
---|
1102 | 1358 | if (rc) |
---|
1103 | 1359 | goto out; |
---|
1104 | 1360 | |
---|
1105 | | - wil->ring2cid_tid[id][0] = WIL6210_MAX_CID; /* CID */ |
---|
| 1361 | + wil->ring2cid_tid[id][0] = wil->max_assoc_sta; /* CID */ |
---|
1106 | 1362 | wil->ring2cid_tid[id][1] = 0; /* TID */ |
---|
1107 | 1363 | |
---|
1108 | 1364 | cmd.vring_cfg.tx_sw_ring.ring_mem_base = cpu_to_le64(vring->pa); |
---|
.. | .. |
---|
1111 | 1367 | txdata->dot1x_open = true; |
---|
1112 | 1368 | rc = wmi_call(wil, WMI_BCAST_VRING_CFG_CMDID, vif->mid, |
---|
1113 | 1369 | &cmd, sizeof(cmd), |
---|
1114 | | - WMI_VRING_CFG_DONE_EVENTID, &reply, sizeof(reply), 100); |
---|
| 1370 | + WMI_VRING_CFG_DONE_EVENTID, &reply, sizeof(reply), |
---|
| 1371 | + WIL_WMI_CALL_GENERAL_TO_MS); |
---|
1115 | 1372 | if (rc) |
---|
1116 | 1373 | goto out_free; |
---|
1117 | 1374 | |
---|
.. | .. |
---|
1144 | 1401 | struct wil6210_vif *vif, |
---|
1145 | 1402 | struct sk_buff *skb) |
---|
1146 | 1403 | { |
---|
1147 | | - int i; |
---|
1148 | | - struct ethhdr *eth = (void *)skb->data; |
---|
1149 | | - int cid = wil_find_cid(wil, vif->mid, eth->h_dest); |
---|
| 1404 | + int i, cid; |
---|
| 1405 | + const u8 *da = wil_skb_get_da(skb); |
---|
1150 | 1406 | int min_ring_id = wil_get_min_tx_ring_id(wil); |
---|
1151 | 1407 | |
---|
1152 | | - if (cid < 0) |
---|
| 1408 | + cid = wil_find_cid(wil, vif->mid, da); |
---|
| 1409 | + |
---|
| 1410 | + if (cid < 0 || cid >= wil->max_assoc_sta) |
---|
1153 | 1411 | return NULL; |
---|
1154 | 1412 | |
---|
1155 | 1413 | /* TODO: fix for multiple TID */ |
---|
.. | .. |
---|
1162 | 1420 | struct wil_ring_tx_data *txdata = &wil->ring_tx_data[i]; |
---|
1163 | 1421 | |
---|
1164 | 1422 | wil_dbg_txrx(wil, "find_tx_ucast: (%pM) -> [%d]\n", |
---|
1165 | | - eth->h_dest, i); |
---|
| 1423 | + da, i); |
---|
1166 | 1424 | if (v->va && txdata->enabled) { |
---|
1167 | 1425 | return v; |
---|
1168 | 1426 | } else { |
---|
.. | .. |
---|
1201 | 1459 | continue; |
---|
1202 | 1460 | |
---|
1203 | 1461 | cid = wil->ring2cid_tid[i][0]; |
---|
1204 | | - if (cid >= WIL6210_MAX_CID) /* skip BCAST */ |
---|
| 1462 | + if (cid >= wil->max_assoc_sta) /* skip BCAST */ |
---|
1205 | 1463 | continue; |
---|
1206 | 1464 | |
---|
1207 | 1465 | if (!wil->ring_tx_data[i].dot1x_open && |
---|
.. | .. |
---|
1250 | 1508 | return v; |
---|
1251 | 1509 | } |
---|
1252 | 1510 | |
---|
| 1511 | +/* apply multicast to unicast only for ARP and IP packets |
---|
| 1512 | + * (see NL80211_CMD_SET_MULTICAST_TO_UNICAST for more info) |
---|
| 1513 | + */ |
---|
| 1514 | +static bool wil_check_multicast_to_unicast(struct wil6210_priv *wil, |
---|
| 1515 | + struct sk_buff *skb) |
---|
| 1516 | +{ |
---|
| 1517 | + const struct ethhdr *eth = (void *)skb->data; |
---|
| 1518 | + const struct vlan_ethhdr *ethvlan = (void *)skb->data; |
---|
| 1519 | + __be16 ethertype; |
---|
| 1520 | + |
---|
| 1521 | + if (!wil->multicast_to_unicast) |
---|
| 1522 | + return false; |
---|
| 1523 | + |
---|
| 1524 | + /* multicast to unicast conversion only for some payload */ |
---|
| 1525 | + ethertype = eth->h_proto; |
---|
| 1526 | + if (ethertype == htons(ETH_P_8021Q) && skb->len >= VLAN_ETH_HLEN) |
---|
| 1527 | + ethertype = ethvlan->h_vlan_encapsulated_proto; |
---|
| 1528 | + switch (ethertype) { |
---|
| 1529 | + case htons(ETH_P_ARP): |
---|
| 1530 | + case htons(ETH_P_IP): |
---|
| 1531 | + case htons(ETH_P_IPV6): |
---|
| 1532 | + break; |
---|
| 1533 | + default: |
---|
| 1534 | + return false; |
---|
| 1535 | + } |
---|
| 1536 | + |
---|
| 1537 | + return true; |
---|
| 1538 | +} |
---|
| 1539 | + |
---|
1253 | 1540 | static void wil_set_da_for_vring(struct wil6210_priv *wil, |
---|
1254 | 1541 | struct sk_buff *skb, int vring_index) |
---|
1255 | 1542 | { |
---|
1256 | | - struct ethhdr *eth = (void *)skb->data; |
---|
| 1543 | + u8 *da = wil_skb_get_da(skb); |
---|
1257 | 1544 | int cid = wil->ring2cid_tid[vring_index][0]; |
---|
1258 | 1545 | |
---|
1259 | | - ether_addr_copy(eth->h_dest, wil->sta[cid].addr); |
---|
| 1546 | + ether_addr_copy(da, wil->sta[cid].addr); |
---|
1260 | 1547 | } |
---|
1261 | 1548 | |
---|
1262 | 1549 | static struct wil_ring *wil_find_tx_bcast_2(struct wil6210_priv *wil, |
---|
.. | .. |
---|
1267 | 1554 | struct sk_buff *skb2; |
---|
1268 | 1555 | int i; |
---|
1269 | 1556 | u8 cid; |
---|
1270 | | - struct ethhdr *eth = (void *)skb->data; |
---|
1271 | | - char *src = eth->h_source; |
---|
| 1557 | + const u8 *src = wil_skb_get_sa(skb); |
---|
1272 | 1558 | struct wil_ring_tx_data *txdata, *txdata2; |
---|
1273 | 1559 | int min_ring_id = wil_get_min_tx_ring_id(wil); |
---|
1274 | 1560 | |
---|
.. | .. |
---|
1280 | 1566 | continue; |
---|
1281 | 1567 | |
---|
1282 | 1568 | cid = wil->ring2cid_tid[i][0]; |
---|
1283 | | - if (cid >= WIL6210_MAX_CID) /* skip BCAST */ |
---|
| 1569 | + if (cid >= wil->max_assoc_sta) /* skip BCAST */ |
---|
1284 | 1570 | continue; |
---|
1285 | 1571 | if (!wil->ring_tx_data[i].dot1x_open && |
---|
1286 | 1572 | skb->protocol != cpu_to_be16(ETH_P_PAE)) |
---|
.. | .. |
---|
1308 | 1594 | if (!v2->va || txdata2->mid != vif->mid) |
---|
1309 | 1595 | continue; |
---|
1310 | 1596 | cid = wil->ring2cid_tid[i][0]; |
---|
1311 | | - if (cid >= WIL6210_MAX_CID) /* skip BCAST */ |
---|
| 1597 | + if (cid >= wil->max_assoc_sta) /* skip BCAST */ |
---|
1312 | 1598 | continue; |
---|
1313 | 1599 | if (!wil->ring_tx_data[i].dot1x_open && |
---|
1314 | 1600 | skb->protocol != cpu_to_be16(ETH_P_PAE)) |
---|
.. | .. |
---|
1338 | 1624 | d->mac.d[2] |= (nr_frags << MAC_CFG_DESC_TX_2_NUM_OF_DESCRIPTORS_POS); |
---|
1339 | 1625 | } |
---|
1340 | 1626 | |
---|
1341 | | -/** |
---|
1342 | | - * Sets the descriptor @d up for csum and/or TSO offloading. The corresponding |
---|
| 1627 | +/* Sets the descriptor @d up for csum and/or TSO offloading. The corresponding |
---|
1343 | 1628 | * @skb is used to obtain the protocol and headers length. |
---|
1344 | 1629 | * @tso_desc_type is a descriptor type for TSO: 0 - a header, 1 - first data, |
---|
1345 | 1630 | * 2 - middle, 3 - last descriptor. |
---|
.. | .. |
---|
1369 | 1654 | d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_PSEUDO_HEADER_CALC_EN_POS); |
---|
1370 | 1655 | } |
---|
1371 | 1656 | |
---|
1372 | | -/** |
---|
1373 | | - * Sets the descriptor @d up for csum. The corresponding |
---|
| 1657 | +/* Sets the descriptor @d up for csum. The corresponding |
---|
1374 | 1658 | * @skb is used to obtain the protocol and headers length. |
---|
1375 | 1659 | * Returns the protocol: 0 - not TCP, 1 - TCPv4, 2 - TCPv6. |
---|
1376 | 1660 | * Note, if d==NULL, the function only returns the protocol result. |
---|
.. | .. |
---|
1560 | 1844 | len); |
---|
1561 | 1845 | } else { |
---|
1562 | 1846 | frag = &skb_shinfo(skb)->frags[f]; |
---|
1563 | | - len = frag->size; |
---|
| 1847 | + len = skb_frag_size(frag); |
---|
1564 | 1848 | wil_dbg_txrx(wil, "TSO: frag[%d]: len %u\n", f, len); |
---|
1565 | 1849 | } |
---|
1566 | 1850 | |
---|
.. | .. |
---|
1581 | 1865 | |
---|
1582 | 1866 | if (!headlen) { |
---|
1583 | 1867 | pa = skb_frag_dma_map(dev, frag, |
---|
1584 | | - frag->size - len, lenmss, |
---|
1585 | | - DMA_TO_DEVICE); |
---|
| 1868 | + skb_frag_size(frag) - len, |
---|
| 1869 | + lenmss, DMA_TO_DEVICE); |
---|
1586 | 1870 | vring->ctx[i].mapped_as = wil_mapped_as_page; |
---|
1587 | 1871 | } else { |
---|
1588 | 1872 | pa = dma_map_single(dev, |
---|
.. | .. |
---|
1666 | 1950 | *_desc = *d; |
---|
1667 | 1951 | } |
---|
1668 | 1952 | } |
---|
| 1953 | + |
---|
| 1954 | + if (!_desc) |
---|
| 1955 | + goto mem_error; |
---|
1669 | 1956 | |
---|
1670 | 1957 | /* first descriptor may also be the last. |
---|
1671 | 1958 | * in this case d pointer is invalid |
---|
.. | .. |
---|
1800 | 2087 | |
---|
1801 | 2088 | /* middle segments */ |
---|
1802 | 2089 | for (; f < nr_frags; f++) { |
---|
1803 | | - const struct skb_frag_struct *frag = |
---|
1804 | | - &skb_shinfo(skb)->frags[f]; |
---|
| 2090 | + const skb_frag_t *frag = &skb_shinfo(skb)->frags[f]; |
---|
1805 | 2091 | int len = skb_frag_size(frag); |
---|
1806 | 2092 | |
---|
1807 | 2093 | *_d = *d; |
---|
.. | .. |
---|
1923 | 2209 | return rc; |
---|
1924 | 2210 | } |
---|
1925 | 2211 | |
---|
1926 | | -/** |
---|
1927 | | - * Check status of tx vrings and stop/wake net queues if needed |
---|
| 2212 | +/* Check status of tx vrings and stop/wake net queues if needed |
---|
1928 | 2213 | * It will start/stop net queues of a specific VIF net_device. |
---|
1929 | 2214 | * |
---|
1930 | 2215 | * This function does one of two checks: |
---|
.. | .. |
---|
1958 | 2243 | else |
---|
1959 | 2244 | wil_dbg_txrx(wil, "check_stop=%d, mid=%d, stopped=%d", |
---|
1960 | 2245 | check_stop, vif->mid, vif->net_queue_stopped); |
---|
| 2246 | + |
---|
| 2247 | + if (ring && drop_if_ring_full) |
---|
| 2248 | + /* no need to stop/wake net queues */ |
---|
| 2249 | + return; |
---|
1961 | 2250 | |
---|
1962 | 2251 | if (check_stop == vif->net_queue_stopped) |
---|
1963 | 2252 | /* net queues already in desired state */ |
---|
.. | .. |
---|
2022 | 2311 | { |
---|
2023 | 2312 | struct wil6210_vif *vif = ndev_to_vif(ndev); |
---|
2024 | 2313 | struct wil6210_priv *wil = vif_to_wil(vif); |
---|
2025 | | - struct ethhdr *eth = (void *)skb->data; |
---|
2026 | | - bool bcast = is_multicast_ether_addr(eth->h_dest); |
---|
| 2314 | + const u8 *da = wil_skb_get_da(skb); |
---|
| 2315 | + bool bcast = is_multicast_ether_addr(da); |
---|
2027 | 2316 | struct wil_ring *ring; |
---|
2028 | 2317 | static bool pr_once_fw; |
---|
2029 | 2318 | int rc; |
---|
.. | .. |
---|
2052 | 2341 | /* in STA mode (ESS), all to same VRING (to AP) */ |
---|
2053 | 2342 | ring = wil_find_tx_ring_sta(wil, vif, skb); |
---|
2054 | 2343 | } else if (bcast) { |
---|
2055 | | - if (vif->pbss) |
---|
| 2344 | + if (vif->pbss || wil_check_multicast_to_unicast(wil, skb)) |
---|
2056 | 2345 | /* in pbss, no bcast VRING - duplicate skb in |
---|
2057 | 2346 | * all stations VRINGs |
---|
2058 | 2347 | */ |
---|
.. | .. |
---|
2070 | 2359 | ring = wil_find_tx_ucast(wil, vif, skb); |
---|
2071 | 2360 | } |
---|
2072 | 2361 | if (unlikely(!ring)) { |
---|
2073 | | - wil_dbg_txrx(wil, "No Tx RING found for %pM\n", eth->h_dest); |
---|
| 2362 | + wil_dbg_txrx(wil, "No Tx RING found for %pM\n", da); |
---|
2074 | 2363 | goto drop; |
---|
2075 | 2364 | } |
---|
2076 | 2365 | /* set up vring entry */ |
---|
.. | .. |
---|
2084 | 2373 | dev_kfree_skb_any(skb); |
---|
2085 | 2374 | return NETDEV_TX_OK; |
---|
2086 | 2375 | case -ENOMEM: |
---|
| 2376 | + if (drop_if_ring_full) |
---|
| 2377 | + goto drop; |
---|
2087 | 2378 | return NETDEV_TX_BUSY; |
---|
2088 | 2379 | default: |
---|
2089 | 2380 | break; /* goto drop; */ |
---|
.. | .. |
---|
2120 | 2411 | sta->stats.tx_latency_max_us = skb_time_us; |
---|
2121 | 2412 | } |
---|
2122 | 2413 | |
---|
2123 | | -/** |
---|
2124 | | - * Clean up transmitted skb's from the Tx VRING |
---|
| 2414 | +/* Clean up transmitted skb's from the Tx VRING |
---|
2125 | 2415 | * |
---|
2126 | 2416 | * Return number of descriptors cleared |
---|
2127 | 2417 | * |
---|
.. | .. |
---|
2155 | 2445 | |
---|
2156 | 2446 | used_before_complete = wil_ring_used_tx(vring); |
---|
2157 | 2447 | |
---|
2158 | | - if (cid < WIL6210_MAX_CID) |
---|
| 2448 | + if (cid < wil->max_assoc_sta) |
---|
2159 | 2449 | stats = &wil->sta[cid].stats; |
---|
2160 | 2450 | |
---|
2161 | 2451 | while (!wil_ring_is_empty(vring)) { |
---|
2162 | 2452 | int new_swtail; |
---|
2163 | 2453 | struct wil_ctx *ctx = &vring->ctx[vring->swtail]; |
---|
2164 | | - /** |
---|
2165 | | - * For the fragmented skb, HW will set DU bit only for the |
---|
| 2454 | + /* For the fragmented skb, HW will set DU bit only for the |
---|
2166 | 2455 | * last fragment. look for it. |
---|
2167 | 2456 | * In TSO the first DU will include hdr desc |
---|
2168 | 2457 | */ |
---|
.. | .. |
---|
2215 | 2504 | if (stats) |
---|
2216 | 2505 | stats->tx_errors++; |
---|
2217 | 2506 | } |
---|
| 2507 | + |
---|
| 2508 | + if (skb->protocol == cpu_to_be16(ETH_P_PAE)) |
---|
| 2509 | + wil_tx_complete_handle_eapol(vif, skb); |
---|
| 2510 | + |
---|
2218 | 2511 | wil_consume_skb(skb, d->dma.error == 0); |
---|
2219 | 2512 | } |
---|
2220 | 2513 | memset(ctx, 0, sizeof(*ctx)); |
---|
.. | .. |
---|
2264 | 2557 | struct vring_rx_desc *d = wil_skb_rxdesc(skb); |
---|
2265 | 2558 | |
---|
2266 | 2559 | *tid = wil_rxdesc_tid(d); |
---|
2267 | | - *cid = wil_rxdesc_cid(d); |
---|
| 2560 | + *cid = wil_skb_get_cid(skb); |
---|
2268 | 2561 | *mid = wil_rxdesc_mid(d); |
---|
2269 | 2562 | *seq = wil_rxdesc_seq(d); |
---|
2270 | 2563 | *mcast = wil_rxdesc_mcast(d); |
---|
.. | .. |
---|
2284 | 2577 | wil->txrx_ops.ring_init_bcast = wil_vring_init_bcast; |
---|
2285 | 2578 | wil->txrx_ops.tx_init = wil_tx_init; |
---|
2286 | 2579 | wil->txrx_ops.tx_fini = wil_tx_fini; |
---|
| 2580 | + wil->txrx_ops.tx_ring_modify = wil_tx_vring_modify; |
---|
2287 | 2581 | /* RX ops */ |
---|
2288 | 2582 | wil->txrx_ops.rx_init = wil_rx_init; |
---|
2289 | 2583 | wil->txrx_ops.wmi_addba_rx_resp = wmi_addba_rx_resp; |
---|