On Mon, 2023-01-16 at 12:21 -0800, Doug Brown wrote: > Add compatibility with WPS by passing on WPS enrollee information in > probe requests. Ignore other IEs supplied in the scan request. This > also > has the added benefit of restoring compatibility with newer > wpa_supplicant versions that always add scan IEs. Previously, with > max_scan_ie_len set to 0, scans would always fail. > > Suggested-by: Dan Williams <dcbw@xxxxxxxxxx> > Signed-off-by: Doug Brown <doug@xxxxxxxxxxxxx> Reviewed-by: Dan Williams <dcbw@xxxxxxxxxx> (don't know if I can/should ack anything anymore, given I haven't touched the driver in like 4 years...) > --- > drivers/net/wireless/marvell/libertas/cfg.c | 48 > +++++++++++++++++++-- > 1 file changed, 45 insertions(+), 3 deletions(-) > > diff --git a/drivers/net/wireless/marvell/libertas/cfg.c > b/drivers/net/wireless/marvell/libertas/cfg.c > index 3f35dc7a1d7d..b700c213d10c 100644 > --- a/drivers/net/wireless/marvell/libertas/cfg.c > +++ b/drivers/net/wireless/marvell/libertas/cfg.c > @@ -446,6 +446,41 @@ static int lbs_add_wpa_tlv(u8 *tlv, const u8 > *ie, u8 ie_len) > return sizeof(struct mrvl_ie_header) + wpaie->datalen; > } > > +/* Add WPS enrollee TLV > + */ > +#define LBS_MAX_WPS_ENROLLEE_TLV_SIZE \ > + (sizeof(struct mrvl_ie_header) \ > + + 256) > + > +static int lbs_add_wps_enrollee_tlv(u8 *tlv, const u8 *ie, size_t > ie_len) > +{ > + struct mrvl_ie_data *wpstlv = (struct mrvl_ie_data *)tlv; > + const struct element *wpsie; > + > + /* Look for a WPS IE and add it to the probe request */ > + wpsie = cfg80211_find_vendor_elem(WLAN_OUI_MICROSOFT, > + > WLAN_OUI_TYPE_MICROSOFT_WPS, > + ie, ie_len); > + if (!wpsie) > + return 0; > + > + /* Convert the WPS IE to a TLV. The IE looks like this: > + * u8 type (WLAN_EID_VENDOR_SPECIFIC) > + * u8 len > + * u8[] data > + * but the TLV will look like this instead: > + * __le16 type (TLV_TYPE_WPS_ENROLLEE) > + * __le16 len > + * u8[] data > + */ > + wpstlv->header.type = cpu_to_le16(TLV_TYPE_WPS_ENROLLEE); > + wpstlv->header.len = cpu_to_le16(wpsie->datalen); > + memcpy(wpstlv->data, wpsie->data, wpsie->datalen); > + > + /* Return the total number of bytes added to the TLV buffer > */ > + return sizeof(struct mrvl_ie_header) + wpsie->datalen; > +} > + > /* > * Set Channel > */ > @@ -672,14 +707,15 @@ static int lbs_ret_scan(struct lbs_private > *priv, unsigned long dummy, > > > /* > - * Our scan command contains a TLV, consting of a SSID TLV, a > channel list > - * TLV and a rates TLV. Determine the maximum size of them: > + * Our scan command contains a TLV, consisting of a SSID TLV, a > channel list > + * TLV, a rates TLV, and an optional WPS IE. Determine the maximum > size of them: > */ > #define LBS_SCAN_MAX_CMD_SIZE \ > (sizeof(struct cmd_ds_802_11_scan) \ > + LBS_MAX_SSID_TLV_SIZE \ > + LBS_MAX_CHANNEL_LIST_TLV_SIZE \ > - + LBS_MAX_RATES_TLV_SIZE) > + + LBS_MAX_RATES_TLV_SIZE \ > + + LBS_MAX_WPS_ENROLLEE_TLV_SIZE) > > /* > * Assumes priv->scan_req is initialized and valid > @@ -728,6 +764,11 @@ static void lbs_scan_worker(struct work_struct > *work) > /* add rates TLV */ > tlv += lbs_add_supported_rates_tlv(tlv); > > + /* add optional WPS enrollee TLV */ > + if (priv->scan_req->ie && priv->scan_req->ie_len) > + tlv += lbs_add_wps_enrollee_tlv(tlv, priv->scan_req- > >ie, > + priv->scan_req- > >ie_len); > + > if (priv->scan_channel < priv->scan_req->n_channels) { > cancel_delayed_work(&priv->scan_work); > if (netif_running(priv->dev)) > @@ -2114,6 +2155,7 @@ int lbs_cfg_register(struct lbs_private *priv) > int ret; > > wdev->wiphy->max_scan_ssids = 1; > + wdev->wiphy->max_scan_ie_len = 256; > wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; > > wdev->wiphy->interface_modes =