From nobody Fri Apr 15 15:56:55 2022 X-Original-To: dev-commits-src-all@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 A8D287CD9A1; Fri, 15 Apr 2022 15:56:57 +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 4Kg1D8549Sz3FtV; Fri, 15 Apr 2022 15:56:56 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1650038217; 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=cqLyOSbgBrLZyPS66OPrYA/EsAzU0jxoF2d80rMLH64=; b=I1mnr3UhPdcyLrmEIvuoSgRzazgaFCz2zMhNw8Z7Ufsz+W6wHFMA4uFNVKz7xCZwHTXWyR FBrkBsC2rip54zLs/j+2zqoThC4fmEvazPzvxXmhm/pcsXFqj5UvYty4FuNnxIqDZ26nH0 t2OSwfKG5MovkvkQN81Vct1uxjWXxzHbonrygNpfiCCGImw5XWTPhJhyjSwgHx2dKR5wKZ OXpU9Qrkc8ZNSQTcSSxbO3TaSx11AxFllpfb+KqTjorHGjtPPH7uNrzIrqihskUKWD7bN8 AqGCLyAcFpd0o1n4h+31PHToF5nyQLeoHrPalISu7IEjGwpI+HH9Yp0pRXHzSQ== 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 6E27918035; Fri, 15 Apr 2022 15:56:55 +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 23FFut3D084413; Fri, 15 Apr 2022 15:56:55 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 23FFutgV084412; Fri, 15 Apr 2022 15:56:55 GMT (envelope-from git) Date: Fri, 15 Apr 2022 15:56:55 GMT Message-Id: <202204151556.23FFutgV084412@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: "Bjoern A. Zeeb" Subject: git: d9945d7821b9 - main - LinuxKPI: 802.11: improve hw_scan List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@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/main X-Git-Reftype: branch X-Git-Commit: d9945d7821b9baf724a704d37d33b9adcad70030 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1650038217; 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=cqLyOSbgBrLZyPS66OPrYA/EsAzU0jxoF2d80rMLH64=; b=u3MYxfWoACNBJ3pQ8RERzh06gZtTE9TwJfXombTRnEdCY68Hsjk8z4yjbDh2GacEYt8wVn UhzS65G4B/5dEVsADU4MkUfUG0/U1vCOZxgIfAXbNo3x4lVY2/ntVkmtAPyTyYkCyx8Y0R mHAUXXgS5OVoabhViUZ2ZXxhZNKweyFpJWBTDl0Pp40yNQy/v22/b3wOTcWszEHi7CVG9v /1KnwYwHEuFT+VOQudA8u79T8w1JBjf6XQ6eoMG5tTztggEJhEsUEcCYDYh9yZB4WfvpAq Le59uyaTB35Anpn6Y76XUUfn1zTYvYWgvZMAVcTWIG/F/rdobA9yVzmq7xirfQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1650038217; a=rsa-sha256; cv=none; b=flgK6Jz/5riGBXEbKRdIp8o5ixOqZwN/7ks5Dz0m+j+9PdrcOLCXLDAs+QVbYPRkC+gvTt tYhByE/cKj+OFMV85W1K6ImGalwp+3cOkob4/XMNkQayReEMGGw5WxhEe+0tlCE7lyNY6e uUjwh5aEdNiuFnSmrhy237643XAQXv6JWJmAAvBKfEAJMlXb6MPooD0PaugUafuLuwojf9 s9oGO+dHr4guZT7JFE2goOk64orpoaoqfx2Qd+uGu6Q4O8zWFXXykRBgruBp00lme2Q2wp xj/DrMES5IrlCoyjlSBWuFfUEiSVG2k1vRPZhkqNWzjVDtYKe6Yb17dXavK9PA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by bz: URL: https://cgit.FreeBSD.org/src/commit/?id=d9945d7821b9baf724a704d37d33b9adcad70030 commit d9945d7821b9baf724a704d37d33b9adcad70030 Author: Bjoern A. Zeeb AuthorDate: 2022-04-15 14:55:40 +0000 Commit: Bjoern A. Zeeb CommitDate: 2022-04-15 15:54:03 +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 MFC after: 3 days --- 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 286c40d7de4f..b80d8b62087b 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! */