[PATCH v3 4/4] wifi: libertas: add support for WPS enrollee IE in probe requests

Dan Williams dcbw at redhat.com
Tue Jan 17 11:05:58 PST 2023


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 at redhat.com>
> Signed-off-by: Doug Brown <doug at schmorgal.com>

Reviewed-by: Dan Williams <dcbw at redhat.com>

(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 =



More information about the libertas-dev mailing list