From nobody Mon Apr 18 09:33:50 2022 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id D587211E3B7C; Mon, 18 Apr 2022 09:33:51 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4KhhZl16F3z3Ccv; Mon, 18 Apr 2022 09:33:51 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1650274431; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=L8dxFoIjvORct/f8Y1Fn2WhPkBfebdQJ7LAVPMzG0rM=; b=tqf1msZ/sv033jVg0Nd+OMFa+KZMDRvPwKub1cmidKbvRwGts4k4D6kmHSTaTXBxCWOXkN 891dgjyxWnzgZPtIsIc6IxzCVkrYFDavkgbecR8U2kDKXFxVp0EMvc8ODNpoa599Swavk4 5yWtRcRuLhnIk5eMwx6qOKczZs616bFhTA80tAqQqTB4OJRCt8ebvLYlYjplhbS2E09e7K IleS93Y1vzbjjClbcABKJocrO+nkvmdcGY7LzWiervlSK85U3lx6DK+K0LJCRlEBm1WCjC QxQBuupn7+o0DUVPcQcvxUZhb19ah87FdqTmCPtll2nyyZyuuYWA3XqtVNBbfw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id CB9CF1061A; Mon, 18 Apr 2022 09:33:50 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 23I9XoVn018510; Mon, 18 Apr 2022 09:33:50 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 23I9XoCF018509; Mon, 18 Apr 2022 09:33:50 GMT (envelope-from git) Date: Mon, 18 Apr 2022 09:33:50 GMT Message-Id: <202204180933.23I9XoCF018509@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: "Bjoern A. Zeeb" Subject: git: 3c1373110f80 - stable/13 - LinuxKPI: 802.11: improve hw_scan List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-branches@freebsd.org X-BeenThere: dev-commits-src-branches@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: bz X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: 3c1373110f80d14f519abf4babb011379fe1008e Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1650274431; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=L8dxFoIjvORct/f8Y1Fn2WhPkBfebdQJ7LAVPMzG0rM=; b=YPe8z5kDETJ0xVejW43JH1+A1K2h9SF6sHDbH0Z+wA2GfCpxFPxym7rmu4aQr0aKONIDYL pLqyWKPCe8tqdyMdmNJtwT7svvEYt43wuayOpqtyIpYpw4ItuudCDsKrtqLsHPye+lXoH9 xe0xe0A1HoHWIznnTkTYR0lC4dwwgjSG1m0nuKcr59KJKoe2auBSbxD7GTV6XiEQeqLM5I GONAD0+iqfED1cwNQdY7effRIcIsZrAEEkwiM+p/ne4Rgn0+ZGHG4rQ5wH/kdvLF8iLTrV pp+Xb6xv+jSrlHxwpmES09gn5AfkN4wd3u7bDSQLkcm1dG7fcMBWkNpq/k7TQg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1650274431; a=rsa-sha256; cv=none; b=d16lultMTAZ2MpYtPWUGOQWhRGGL3sO6b7hnrRj3jG/afPPJqpUta9ZaZDhsCxuiUiBmve zKYofr/fRO4FhAGur1rEujCytXkCZzqyrU03+l59CixFR2j7COVQBWSD2K7tFR4iTR9bAy 3y1cjy4USUsOvuhZcnN1r22lPFgVJXouSjNuXb9/pfpChQb8XIgwDRJD7ZI10yoAaCSpS/ QgWRJeikXw7q/eXZCu4OXQ4lHQ/KsM1IH8/6mOaACm3cxXZb40BNvUdnNBVjGBD/0XAr9Q /0/VxudjWvvEAVaqs+oS+OgFpEUF4GKna9JWhpLXz6aBkOxAFeDkB+EvN5c1ig== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch stable/13 has been updated by bz: URL: https://cgit.FreeBSD.org/src/commit/?id=3c1373110f80d14f519abf4babb011379fe1008e commit 3c1373110f80d14f519abf4babb011379fe1008e Author: Bjoern A. Zeeb AuthorDate: 2022-04-15 14:55:40 +0000 Commit: Bjoern A. Zeeb CommitDate: 2022-04-18 09:32:58 +0000 LinuxKPI: 802.11: improve hw_scan Initially we were using the IEs from ieee80211_probereq_ie() of net80211 and put them into the common_ies field. Start by manually building the per-band and common IE parts as drivers put them back together. This also involves allocating the req.ie as one buffer for all IEs over all bands and setting req.ie_len correctly based on how many bytes we put in. Manually building per-band scan IEs we still use the net80211 routines to add IEs to the buffer (mostly). This is needed by Realtek drivers but will equally used by others. Realtek would simply panic due to skbs being allocated with the wrong length. Longer-term this will help us, e.g., when not supporting VHT on 2Ghz and we would have to do this anyway. Sponsored by: The FreeBSD Foundation (cherry picked from commit d9945d7821b9baf724a704d37d33b9adcad70030) --- sys/compat/linuxkpi/common/src/linux_80211.c | 174 ++++++++++++++++++++++----- sys/compat/linuxkpi/common/src/linux_80211.h | 5 + 2 files changed, 149 insertions(+), 30 deletions(-) diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c b/sys/compat/linuxkpi/common/src/linux_80211.c index d4fe1a182d6e..227016b77d82 100644 --- a/sys/compat/linuxkpi/common/src/linux_80211.c +++ b/sys/compat/linuxkpi/common/src/linux_80211.c @@ -2424,15 +2424,72 @@ linuxkpi_ieee80211_ie_advance(size_t *xp, const u8 *ies, size_t ies_len) return (true); } -static int -lkpi_ieee80211_probereq_ie_alloc(struct ieee80211vap *vap, - struct ieee80211com *ic, struct ieee80211_scan_ies *scan_ies, - const uint8_t *ssid, size_t ssidlen) +static uint8_t * +lkpi_scan_ies_add(uint8_t *p, struct ieee80211_scan_ies *scan_ies, + uint32_t band_mask, struct ieee80211vap *vap, struct ieee80211_hw *hw) { + struct ieee80211_supported_band *supband; + struct linuxkpi_ieee80211_channel *channels; + const struct ieee80211_channel *chan; + const struct ieee80211_rateset *rs; + uint8_t *pb; + int band, i; + + for (band = 0; band < NUM_NL80211_BANDS; band++) { + if ((band_mask & (1 << band)) == 0) + continue; + + supband = hw->wiphy->bands[band]; + /* + * This should not happen; + * band_mask is a bitmask of valid bands to scan on. + */ + if (supband == NULL || supband->n_channels == 0) + continue; + + /* Find a first channel to get the mode and rates from. */ + channels = supband->channels; + chan = NULL; + for (i = 0; i < supband->n_channels; i++) { + + if (channels[i].flags & IEEE80211_CHAN_DISABLED) + continue; + + chan = ieee80211_find_channel(vap->iv_ic, + channels[i].center_freq, 0); + if (chan != NULL) + break; + } + + /* This really should not happen. */ + if (chan == NULL) + continue; + + pb = p; + rs = ieee80211_get_suprates(vap->iv_ic, chan); /* calls chan2mode */ + p = ieee80211_add_rates(p, rs); + p = ieee80211_add_xrates(p, rs); + + scan_ies->ies[band] = pb; + scan_ies->len[band] = p - pb; + } + + /* Add common_ies */ + pb = p; + if ((vap->iv_flags & IEEE80211_F_WPA1) != 0 && + vap->iv_wpa_ie != NULL) { + memcpy(p, vap->iv_wpa_ie, 2 + vap->iv_wpa_ie[1]); + p += 2 + vap->iv_wpa_ie[1]; + } + if (vap->iv_appie_probereq != NULL) { + memcpy(p, vap->iv_appie_probereq->ie_data, + vap->iv_appie_probereq->ie_len); + p += vap->iv_appie_probereq->ie_len; + } + scan_ies->common_ies = pb; + scan_ies->common_ie_len = p - pb; - return (ieee80211_probereq_ie(vap, ic, - &scan_ies->common_ies, &scan_ies->common_ie_len, - ssid, ssidlen, true)); + return (p); } static void @@ -2482,26 +2539,50 @@ sw_scan: struct cfg80211_ssid *ssids; struct cfg80211_scan_6ghz_params *s6gp; size_t chan_len, nchan, ssids_len, s6ghzlen; - int i; + int band, i, ssid_count, common_ie_len; + uint32_t band_mask; + uint8_t *ie, *ieend; + + if (!ieee80211_hw_check(hw, SINGLE_SCAN_ON_ALL_BANDS)) { + IMPROVE("individual band scans not yet supported"); + /* In theory net80211 would have to drive this. */ + return; + } - ssids_len = ss->ss_nssid * sizeof(*ssids);; + ssid_count = min(ss->ss_nssid, hw->wiphy->max_scan_ssids); + ssids_len = ssid_count * sizeof(*ssids); s6ghzlen = 0 * (sizeof(*s6gp)); /* XXX-BZ */ + band_mask = 0; nchan = 0; - for (i = ss->ss_next; i < ss->ss_last; i++) + for (i = ss->ss_next; i < ss->ss_last; i++) { nchan++; + band = lkpi_net80211_chan_to_nl80211_band( + ss->ss_chans[ss->ss_next + i]); + band_mask |= (1 << band); + } chan_len = nchan * (sizeof(lc) + sizeof(*lc)); + common_ie_len = 0; + if ((vap->iv_flags & IEEE80211_F_WPA1) != 0 && + vap->iv_wpa_ie != NULL) + common_ie_len += vap->iv_wpa_ie[1]; + if (vap->iv_appie_probereq != NULL) + common_ie_len += vap->iv_appie_probereq->ie_len; + + /* We would love to check this at an earlier stage... */ + if (common_ie_len > hw->wiphy->max_scan_ie_len) { + ic_printf(ic, "WARNING: %s: common_ie_len %d > " + "wiphy->max_scan_ie_len %d\n", __func__, + common_ie_len, hw->wiphy->max_scan_ie_len); + } + KASSERT(lhw->hw_req == NULL, ("%s: ic %p lhw %p hw_req %p " "!= NULL\n", __func__, ic, lhw, lhw->hw_req)); - lhw->hw_req = hw_req = malloc(sizeof(*hw_req) + ssids_len + - s6ghzlen + chan_len, M_LKPI80211, M_WAITOK | M_ZERO); - error = lkpi_ieee80211_probereq_ie_alloc(vap, ic, - &hw_req->ies, NULL, -1); - if (error != 0) - ic_printf(ic, "ERROR: %s: probereq_ie returned %d\n", - __func__, error); + lhw->hw_req = hw_req = malloc(sizeof(*hw_req) + ssids_len + + s6ghzlen + chan_len + lhw->supbands * lhw->scan_ie_len + + common_ie_len, M_LKPI80211, M_WAITOK | M_ZERO); hw_req->req.flags = 0; /* XXX ??? */ /* hw_req->req.wdev */ @@ -2517,14 +2598,6 @@ sw_scan: memcpy(hw_req->req.mac_addr, xxx, IEEE80211_ADDR_LEN); memset(hw_req->req.mac_addr_mask, 0xxx, IEEE80211_ADDR_LEN); #endif -#if 0 - hw_req->req.ie_len = ; - hw_req->req.ie = ; -#endif -#if 0 - hw->wiphy->max_scan_ie_len - hw->wiphy->max_scan_ssids -#endif hw_req->req.n_channels = nchan; cpp = (struct linuxkpi_ieee80211_channel **)(hw_req + 1); @@ -2545,11 +2618,11 @@ sw_scan: lc++; } - hw_req->req.n_ssids = ss->ss_nssid; + hw_req->req.n_ssids = ssid_count; if (hw_req->req.n_ssids > 0) { ssids = (struct cfg80211_ssid *)lc; hw_req->req.ssids = ssids; - for (i = 0; i < ss->ss_nssid; i++) { + for (i = 0; i < ssid_count; i++) { ssids->ssid_len = ss->ss_ssid[i].len; memcpy(ssids->ssid, ss->ss_ssid[i].ssid, ss->ss_ssid[i].len); @@ -2566,15 +2639,21 @@ sw_scan: hw_req->req.scan_6ghz = false; /* Weird boolean; not what you think. */ /* s6gp->... */ + ie = ieend = (uint8_t *)s6gp; + /* Copy per-band IEs, copy common IEs */ + ieend = lkpi_scan_ies_add(ie, &hw_req->ies, band_mask, vap, hw); + hw_req->req.ie = ie; + hw_req->req.ie_len = ieend - ie; + lvif = VAP_TO_LVIF(vap); vif = LVIF_TO_VIF(lvif); error = lkpi_80211_mo_hw_scan(hw, vif, hw_req); if (error != 0) { - free(hw_req->ies.common_ies, M_80211_VAP); + ieee80211_cancel_scan(vap); + free(hw_req, M_LKPI80211); lhw->hw_req = NULL; - ieee80211_cancel_scan(vap); /* * XXX-SIGH magic number. * rtw88 has a magic "return 1" if offloading scan is @@ -3434,7 +3513,10 @@ linuxkpi_ieee80211_ifattach(struct ieee80211_hw *hw) /* * Assign the first possible channel for now; seems Realtek drivers * expect one. + * Also remember the amount of bands we support and the most rates + * in any band so we can scale [(ext) sup rates] IE(s) accordingly. */ + lhw->supbands = lhw->max_rates = 0; for (band = 0; band < NUM_NL80211_BANDS && hw->conf.chandef.chan == NULL; band++) { struct ieee80211_supported_band *supband; @@ -3444,6 +3526,9 @@ linuxkpi_ieee80211_ifattach(struct ieee80211_hw *hw) if (supband == NULL || supband->n_channels == 0) continue; + lhw->supbands++; + lhw->max_rates = max(lhw->max_rates, supband->n_bitrates); + channels = supband->channels; for (i = 0; i < supband->n_channels; i++) { @@ -3456,6 +3541,36 @@ linuxkpi_ieee80211_ifattach(struct ieee80211_hw *hw) } } + IMPROVE("see net80211::ieee80211_chan_init vs. wiphy->bands[].bitrates possibly in lkpi_ic_getradiocaps?"); + + /* Make sure we do not support more than net80211 is willing to take. */ + if (lhw->max_rates > IEEE80211_RATE_MAXSIZE) { + ic_printf(ic, "%s: limiting max_rates %d to %d!\n", __func__, + lhw->max_rates, IEEE80211_RATE_MAXSIZE); + lhw->max_rates = IEEE80211_RATE_MAXSIZE; + } + + /* + * The maximum supported bitrates on any band + size for + * DSSS Parameter Set give our per-band IE size. + * XXX-BZ FIXME add HT VHT ... later + * SSID is the responsibility of the driver and goes on the side. + * The user specified bits coming from the vap go into the + * "common ies" fields. + */ + lhw->scan_ie_len = 2 + IEEE80211_RATE_SIZE; + if (lhw->max_rates > IEEE80211_RATE_SIZE) + lhw->scan_ie_len += 2 + (lhw->max_rates - IEEE80211_RATE_SIZE); + /* + * net80211 does not seem to support the DSSS Parameter Set but some of + * the drivers insert it so calculate the extra fixed space in. + */ + lhw->scan_ie_len += 2 + 1; + + /* Reduce the max_scan_ie_len "left" by the amount we consume already. */ + if (hw->wiphy->max_scan_ie_len > 0) + hw->wiphy->max_scan_ie_len -= lhw->scan_ie_len; + if (bootverbose) ieee80211_announce(ic); @@ -3623,7 +3738,6 @@ linuxkpi_ieee80211_scan_completed(struct ieee80211_hw *hw, ieee80211_scan_done(ss->ss_vap); LKPI_80211_LHW_LOCK(lhw); - free(lhw->hw_req->ies.common_ies, M_80211_VAP); free(lhw->hw_req, M_LKPI80211); lhw->hw_req = NULL; lhw->scan_flags &= ~LKPI_SCAN_RUNNING; diff --git a/sys/compat/linuxkpi/common/src/linux_80211.h b/sys/compat/linuxkpi/common/src/linux_80211.h index bdcdb3fbf455..f7ade2d5e2f9 100644 --- a/sys/compat/linuxkpi/common/src/linux_80211.h +++ b/sys/compat/linuxkpi/common/src/linux_80211.h @@ -155,6 +155,11 @@ struct lkpi_hw { /* name it mac80211_sc? */ uint32_t sc_flags; #define LKPI_SCAN_RUNNING 0x00000001 uint32_t scan_flags; + + int supbands; /* Number of supported bands. */ + int max_rates; /* Maximum number of bitrates supported in any channel. */ + int scan_ie_len; /* Length of common per-band scan IEs. */ + bool update_mc; /* Must be last! */