Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 41c8fa0c authored by Sergey Matyukevich's avatar Sergey Matyukevich Committed by Kalle Valo
Browse files

qtnfmac: fix handling of iftype mask reported by firmware



Firmware sends supported interface type rather than mask. As a result,
types field of ieee80211_iface_limit structure may end up having
multiple iftype bits set. This leads to WARN_ON from
wiphy_verify_combinations.

Signed-off-by: default avatarIgor Mitsyanko <igor.mitsyanko.os@quantenna.com>
Signed-off-by: default avatarSergey Matyukevich <sergey.matyukevich.os@quantenna.com>
Signed-off-by: default avatarAvinash Patil <avinashp@quantenna.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent c7ead2ab
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -989,7 +989,7 @@ static int qtnf_parse_variable_mac_info(struct qtnf_wmac *mac,
	struct ieee80211_iface_limit *limits = NULL;
	const struct qlink_iface_limit *limit_record;
	size_t record_count = 0, rec = 0;
	u16 tlv_type, tlv_value_len, mask;
	u16 tlv_type, tlv_value_len;
	struct qlink_iface_comb_num *comb;
	size_t tlv_full_len;
	const struct qlink_tlv_hdr *tlv;
@@ -1042,9 +1042,10 @@ static int qtnf_parse_variable_mac_info(struct qtnf_wmac *mac,

			limit_record = (void *)tlv->val;
			limits[rec].max = le16_to_cpu(limit_record->max_num);
			mask = le16_to_cpu(limit_record->type_mask);
			limits[rec].types = qlink_iface_type_mask_to_nl(mask);
			/* only AP and STA modes are supported */
			limits[rec].types = qlink_iface_type_to_nl_mask(
				le16_to_cpu(limit_record->type));

			/* supported modes: STA, AP */
			limits[rec].types &= BIT(NL80211_IFTYPE_AP) |
					     BIT(NL80211_IFTYPE_STATION);

+1 −1
Original line number Diff line number Diff line
@@ -873,7 +873,7 @@ struct qlink_tlv_hdr {

struct qlink_iface_limit {
	__le16 max_num;
	__le16 type_mask;
	__le16 type;
} __packed;

struct qlink_iface_comb_num {
+13 −10
Original line number Diff line number Diff line
@@ -17,24 +17,27 @@

#include "qlink_util.h"

u16 qlink_iface_type_mask_to_nl(u16 qlink_mask)
u16 qlink_iface_type_to_nl_mask(u16 qlink_type)
{
	u16 result = 0;

	if (qlink_mask & QLINK_IFTYPE_AP)
	switch (qlink_type) {
	case QLINK_IFTYPE_AP:
		result |= BIT(NL80211_IFTYPE_AP);

	if (qlink_mask & QLINK_IFTYPE_STATION)
		break;
	case QLINK_IFTYPE_STATION:
		result |= BIT(NL80211_IFTYPE_STATION);

	if (qlink_mask & QLINK_IFTYPE_ADHOC)
		break;
	case QLINK_IFTYPE_ADHOC:
		result |= BIT(NL80211_IFTYPE_ADHOC);

	if (qlink_mask & QLINK_IFTYPE_MONITOR)
		break;
	case QLINK_IFTYPE_MONITOR:
		result |= BIT(NL80211_IFTYPE_MONITOR);

	if (qlink_mask & QLINK_IFTYPE_WDS)
		break;
	case QLINK_IFTYPE_WDS:
		result |= BIT(NL80211_IFTYPE_WDS);
		break;
	}

	return result;
}
+1 −1
Original line number Diff line number Diff line
@@ -68,7 +68,7 @@ static inline void qtnf_cmd_skb_put_tlv_u16(struct sk_buff *skb,
	memcpy(hdr->val, &tmp, sizeof(tmp));
}

u16 qlink_iface_type_mask_to_nl(u16 qlink_mask);
u16 qlink_iface_type_to_nl_mask(u16 qlink_type);
u8 qlink_chan_width_mask_to_nl(u16 qlink_mask);

#endif /* _QTN_FMAC_QLINK_UTIL_H_ */