2023-01-23 05:31:57

by Doug Brown

[permalink] [raw]
Subject: [PATCH v4 0/4] wifi: libertas: IE handling fixes

This series implements two fixes for the libertas driver that restore
compatibility with modern wpa_supplicant versions, and adds (or at least
improves) support for WPS in the process.

1) Better handling of the RSN/WPA IE in association requests:
The previous logic was always just grabbing the first one, and didn't
handle multiple IEs properly, which wpa_supplicant adds nowadays.

2) Support for IEs in scan requests:
Modern wpa_supplicant always adds an "extended capabilities" IE,
which violates max_scan_ie_len in this driver. Go ahead and allow
scan IEs, and handle WPS based on the info that Dan provided.

These changes have been tested on a Marvell PXA168-based device with a
Marvell 88W8686 Wi-Fi chipset. I've confirmed that with these changes
applied, modern wpa_supplicant versions connect properly and WPS also
works correctly (tested with "wpa_cli -i wlan0 wps_pbc any").

Changes since V3:
- Do more extensive code style fixes suggested by Ping-Ke Shih

Changes since V2:
- Add missing cpu_to_le16 as suggested by Simon Horman

Changes since V1 (which was a single patch linked here [1]):

- Switch to cfg80211_find_*_elem when looking for specific IEs,
resulting in cleaner/safer code.
- Use mrvl_ie_data struct for cleaner manipulation of TLV buffer, and
fix capitalization of the "data" member to avoid checkpatch warnings.
- Implement idea suggested by Dan to change max_scan_ie_len to be
nonzero and enable WPS support in probe requests while we're at it.
- Remove "Fixes:" tag; I'm not sure if it's still appropriate or not
with it depending on the capitalization fix.
- Clarify comments.

[1] https://lore.kernel.org/all/[email protected]/

Doug Brown (4):
wifi: libertas: fix code style in Marvell structs
wifi: libertas: only add RSN/WPA IE in lbs_add_wpa_tlv
wifi: libertas: add new TLV type for WPS enrollee IE
wifi: libertas: add support for WPS enrollee IE in probe requests

drivers/net/wireless/marvell/libertas/cfg.c | 76 +++++++++++++++----
drivers/net/wireless/marvell/libertas/types.h | 21 ++---
2 files changed, 74 insertions(+), 23 deletions(-)

--
2.34.1



2023-01-23 05:32:00

by Doug Brown

[permalink] [raw]
Subject: [PATCH v4 1/4] wifi: libertas: fix code style in Marvell structs

Several of the structs are using the deprecated convention of items[1]
for a dynamically sized trailing element. Convert these structs to the
modern C99 style of items[]. Also fix a couple of camel case struct
element names.

Signed-off-by: Doug Brown <[email protected]>
---
drivers/net/wireless/marvell/libertas/types.h | 20 +++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/marvell/libertas/types.h b/drivers/net/wireless/marvell/libertas/types.h
index cd4ceb6f885d..de60becaac12 100644
--- a/drivers/net/wireless/marvell/libertas/types.h
+++ b/drivers/net/wireless/marvell/libertas/types.h
@@ -105,23 +105,23 @@ struct mrvl_ie_header {

struct mrvl_ie_data {
struct mrvl_ie_header header;
- u8 Data[1];
+ u8 data[];
} __packed;

struct mrvl_ie_rates_param_set {
struct mrvl_ie_header header;
- u8 rates[1];
+ u8 rates[];
} __packed;

struct mrvl_ie_ssid_param_set {
struct mrvl_ie_header header;
- u8 ssid[1];
+ u8 ssid[];
} __packed;

struct mrvl_ie_wildcard_ssid_param_set {
struct mrvl_ie_header header;
- u8 MaxSsidlength;
- u8 ssid[1];
+ u8 maxssidlength;
+ u8 ssid[];
} __packed;

struct chanscanmode {
@@ -146,7 +146,7 @@ struct chanscanparamset {

struct mrvl_ie_chanlist_param_set {
struct mrvl_ie_header header;
- struct chanscanparamset chanscanparam[1];
+ struct chanscanparamset chanscanparam[];
} __packed;

struct mrvl_ie_cf_param_set {
@@ -164,12 +164,12 @@ struct mrvl_ie_ds_param_set {

struct mrvl_ie_rsn_param_set {
struct mrvl_ie_header header;
- u8 rsnie[1];
+ u8 rsnie[];
} __packed;

struct mrvl_ie_tsf_timestamp {
struct mrvl_ie_header header;
- __le64 tsftable[1];
+ __le64 tsftable[];
} __packed;

/* v9 and later firmware only */
@@ -220,7 +220,7 @@ struct led_pin {

struct mrvl_ie_ledgpio {
struct mrvl_ie_header header;
- struct led_pin ledpin[1];
+ struct led_pin ledpin[];
} __packed;

struct led_bhv {
@@ -233,7 +233,7 @@ struct led_bhv {

struct mrvl_ie_ledbhv {
struct mrvl_ie_header header;
- struct led_bhv ledbhv[1];
+ struct led_bhv ledbhv[];
} __packed;

/*
--
2.34.1


2023-01-23 05:32:01

by Doug Brown

[permalink] [raw]
Subject: [PATCH v4 2/4] wifi: libertas: only add RSN/WPA IE in lbs_add_wpa_tlv

The existing code only converts the first IE to a TLV, but it returns a
value that takes the length of all IEs into account. When there is more
than one IE (which happens with modern wpa_supplicant versions for
example), the returned length is too long and extra junk TLVs get sent
to the firmware, resulting in an association failure.

Fix this by finding the first RSN or WPA IE and only adding that. This
has the extra benefit of working properly if the RSN/WPA IE isn't the
first one in the IE buffer.

While we're at it, clean up the code to use the available structs like
the other lbs_add_* functions instead of directly manipulating the TLV
buffer.

Signed-off-by: Doug Brown <[email protected]>
---
drivers/net/wireless/marvell/libertas/cfg.c | 28 +++++++++++++--------
1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/marvell/libertas/cfg.c b/drivers/net/wireless/marvell/libertas/cfg.c
index 3e065cbb0af9..3f35dc7a1d7d 100644
--- a/drivers/net/wireless/marvell/libertas/cfg.c
+++ b/drivers/net/wireless/marvell/libertas/cfg.c
@@ -416,10 +416,20 @@ static int lbs_add_cf_param_tlv(u8 *tlv)

static int lbs_add_wpa_tlv(u8 *tlv, const u8 *ie, u8 ie_len)
{
- size_t tlv_len;
+ struct mrvl_ie_data *wpatlv = (struct mrvl_ie_data *)tlv;
+ const struct element *wpaie;
+
+ /* Find the first RSN or WPA IE to use */
+ wpaie = cfg80211_find_elem(WLAN_EID_RSN, ie, ie_len);
+ if (!wpaie)
+ wpaie = cfg80211_find_vendor_elem(WLAN_OUI_MICROSOFT,
+ WLAN_OUI_TYPE_MICROSOFT_WPA,
+ ie, ie_len);
+ if (!wpaie || wpaie->datalen > 128)
+ return 0;

/*
- * We need just convert an IE to an TLV. IEs use u8 for the header,
+ * Convert the found IE to a TLV. IEs use u8 for the header,
* u8 type
* u8 len
* u8[] data
@@ -428,14 +438,12 @@ static int lbs_add_wpa_tlv(u8 *tlv, const u8 *ie, u8 ie_len)
* __le16 len
* u8[] data
*/
- *tlv++ = *ie++;
- *tlv++ = 0;
- tlv_len = *tlv++ = *ie++;
- *tlv++ = 0;
- while (tlv_len--)
- *tlv++ = *ie++;
- /* the TLV is two bytes larger than the IE */
- return ie_len + 2;
+ wpatlv->header.type = cpu_to_le16(wpaie->id);
+ wpatlv->header.len = cpu_to_le16(wpaie->datalen);
+ memcpy(wpatlv->data, wpaie->data, wpaie->datalen);
+
+ /* Return the total number of bytes added to the TLV buffer */
+ return sizeof(struct mrvl_ie_header) + wpaie->datalen;
}

/*
--
2.34.1


2023-01-23 05:32:09

by Doug Brown

[permalink] [raw]
Subject: [PATCH v4 3/4] wifi: libertas: add new TLV type for WPS enrollee IE

Add a define for the TLV type that will be used to add WPS enrollee
information to probe requests.

Suggested-by: Dan Williams <[email protected]>
Signed-off-by: Doug Brown <[email protected]>
---
drivers/net/wireless/marvell/libertas/types.h | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/marvell/libertas/types.h b/drivers/net/wireless/marvell/libertas/types.h
index de60becaac12..bad38d312d0d 100644
--- a/drivers/net/wireless/marvell/libertas/types.h
+++ b/drivers/net/wireless/marvell/libertas/types.h
@@ -93,6 +93,7 @@ union ieee_phy_param_set {
#define TLV_TYPE_TSFTIMESTAMP (PROPRIETARY_TLV_BASE_ID + 19)
#define TLV_TYPE_RSSI_HIGH (PROPRIETARY_TLV_BASE_ID + 22)
#define TLV_TYPE_SNR_HIGH (PROPRIETARY_TLV_BASE_ID + 23)
+#define TLV_TYPE_WPS_ENROLLEE (PROPRIETARY_TLV_BASE_ID + 27)
#define TLV_TYPE_AUTH_TYPE (PROPRIETARY_TLV_BASE_ID + 31)
#define TLV_TYPE_MESH_ID (PROPRIETARY_TLV_BASE_ID + 37)
#define TLV_TYPE_OLD_MESH_ID (PROPRIETARY_TLV_BASE_ID + 291)
--
2.34.1


2023-01-23 05:32:10

by Doug Brown

[permalink] [raw]
Subject: [PATCH v4 4/4] wifi: libertas: add support for WPS enrollee IE in probe requests

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 <[email protected]>
Signed-off-by: Doug Brown <[email protected]>
Reviewed-by: Dan Williams <[email protected]>
---
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 =
--
2.34.1


2023-01-23 08:06:15

by Simon Horman

[permalink] [raw]
Subject: Re: [PATCH v4 0/4] wifi: libertas: IE handling fixes

On Sun, Jan 22, 2023 at 09:31:28PM -0800, Doug Brown wrote:
> This series implements two fixes for the libertas driver that restore
> compatibility with modern wpa_supplicant versions, and adds (or at least
> improves) support for WPS in the process.
>
> 1) Better handling of the RSN/WPA IE in association requests:
> The previous logic was always just grabbing the first one, and didn't
> handle multiple IEs properly, which wpa_supplicant adds nowadays.
>
> 2) Support for IEs in scan requests:
> Modern wpa_supplicant always adds an "extended capabilities" IE,
> which violates max_scan_ie_len in this driver. Go ahead and allow
> scan IEs, and handle WPS based on the info that Dan provided.
>
> These changes have been tested on a Marvell PXA168-based device with a
> Marvell 88W8686 Wi-Fi chipset. I've confirmed that with these changes
> applied, modern wpa_supplicant versions connect properly and WPS also
> works correctly (tested with "wpa_cli -i wlan0 wps_pbc any").

Thanks,

this looks good to me. So, FWIIW,

Reviewed-by: Simon Horman <[email protected]>

2023-01-24 18:25:53

by Dan Williams

[permalink] [raw]
Subject: Re: [PATCH v4 0/4] wifi: libertas: IE handling fixes

On Sun, 2023-01-22 at 21:31 -0800, Doug Brown wrote:
> This series implements two fixes for the libertas driver that restore
> compatibility with modern wpa_supplicant versions, and adds (or at
> least
> improves) support for WPS in the process.
>
> 1) Better handling of the RSN/WPA IE in association requests:
>    The previous logic was always just grabbing the first one, and
> didn't
>    handle multiple IEs properly, which wpa_supplicant adds nowadays.
>
> 2) Support for IEs in scan requests:
>    Modern wpa_supplicant always adds an "extended capabilities" IE,
>    which violates max_scan_ie_len in this driver. Go ahead and allow
>    scan IEs, and handle WPS based on the info that Dan provided.
>
> These changes have been tested on a Marvell PXA168-based device with
> a
> Marvell 88W8686 Wi-Fi chipset. I've confirmed that with these changes
> applied, modern wpa_supplicant versions connect properly and WPS also
> works correctly (tested with "wpa_cli -i wlan0 wps_pbc any").

Tested with a usb8388 (fw 9.34.3p23), x86, wpa_supplicant 2.10.
Scanning and connecting to a WPA2 AP works. Doesn't panic when I pull
the dongle out. Ship it!

Reviewed-by: Dan Williams <[email protected]>
Tested-by: Dan Williams <[email protected]>

Dan

>
> Changes since V3:
> - Do more extensive code style fixes suggested by Ping-Ke Shih
>
> Changes since V2:
> - Add missing cpu_to_le16 as suggested by Simon Horman
>
> Changes since V1 (which was a single patch linked here [1]):
>
> - Switch to cfg80211_find_*_elem when looking for specific IEs,
>   resulting in cleaner/safer code.
> - Use mrvl_ie_data struct for cleaner manipulation of TLV buffer, and
>   fix capitalization of the "data" member to avoid checkpatch
> warnings.
> - Implement idea suggested by Dan to change max_scan_ie_len to be
>   nonzero and enable WPS support in probe requests while we're at it.
> - Remove "Fixes:" tag; I'm not sure if it's still appropriate or not
>   with it depending on the capitalization fix.
> - Clarify comments.
>
> [1]
> https://lore.kernel.org/all/[email protected]/
>
> Doug Brown (4):
>   wifi: libertas: fix code style in Marvell structs
>   wifi: libertas: only add RSN/WPA IE in lbs_add_wpa_tlv
>   wifi: libertas: add new TLV type for WPS enrollee IE
>   wifi: libertas: add support for WPS enrollee IE in probe requests
>
>  drivers/net/wireless/marvell/libertas/cfg.c   | 76 +++++++++++++++--
> --
>  drivers/net/wireless/marvell/libertas/types.h | 21 ++---
>  2 files changed, 74 insertions(+), 23 deletions(-)
>


2023-02-13 15:14:48

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH v4 1/4] wifi: libertas: fix code style in Marvell structs

Doug Brown <[email protected]> wrote:

> Several of the structs are using the deprecated convention of items[1]
> for a dynamically sized trailing element. Convert these structs to the
> modern C99 style of items[]. Also fix a couple of camel case struct
> element names.
>
> Signed-off-by: Doug Brown <[email protected]>

4 patches applied to wireless-next.git, thanks.

53d3a735875e wifi: libertas: fix code style in Marvell structs
57db1ba35736 wifi: libertas: only add RSN/WPA IE in lbs_add_wpa_tlv
5fb2a7854a9e wifi: libertas: add new TLV type for WPS enrollee IE
e6a1c4b9884f wifi: libertas: add support for WPS enrollee IE in probe requests

--
https://patchwork.kernel.org/project/linux-wireless/patch/[email protected]/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches