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

Commit 18b7470f authored by Igor Mitsyanko's avatar Igor Mitsyanko Committed by Kalle Valo
Browse files

qtnfmac: extend "IE set" TLV to include frame type info



Specifying frame type for "IE set" TLV will allow to use several
TLVs in a single message.
Modify users accordingly.

Signed-off-by: default avatarIgor Mitsyanko <igor.mitsyanko.os@quantenna.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent d1398b5b
Loading
Loading
Loading
Loading
+19 −6
Original line number Diff line number Diff line
@@ -147,6 +147,21 @@ static struct sk_buff *qtnf_cmd_alloc_new_cmdskb(u8 macid, u8 vifid, u16 cmd_no,
	return cmd_skb;
}

static void qtnf_cmd_tlv_ie_set_add(struct sk_buff *cmd_skb, u8 frame_type,
				    const u8 *buf, size_t len)
{
	struct qlink_tlv_ie_set *tlv;

	tlv = (struct qlink_tlv_ie_set *)skb_put(cmd_skb, sizeof(*tlv) + len);
	tlv->hdr.type = cpu_to_le16(QTN_TLV_ID_IE_SET);
	tlv->hdr.len = cpu_to_le16(len + sizeof(*tlv) - sizeof(tlv->hdr));
	tlv->type = frame_type;
	tlv->flags = 0;

	if (len && buf)
		memcpy(tlv->ie_data, buf, len);
}

int qtnf_cmd_send_start_ap(struct qtnf_vif *vif)
{
	struct sk_buff *cmd_skb;
@@ -2028,9 +2043,8 @@ int qtnf_cmd_send_scan(struct qtnf_wmac *mac)
	}

	if (scan_req->ie_len != 0)
		qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_IE_SET,
					 scan_req->ie,
					 scan_req->ie_len);
		qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_PROBE_REQ,
					scan_req->ie, scan_req->ie_len);

	if (scan_req->n_channels) {
		n_channels = scan_req->n_channels;
@@ -2154,9 +2168,8 @@ int qtnf_cmd_send_connect(struct qtnf_vif *vif,
				 sme->ssid_len);

	if (sme->ie_len != 0)
		qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_IE_SET,
					 sme->ie,
					 sme->ie_len);
		qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_ASSOC_REQ,
					sme->ie, sme->ie_len);

	qtnf_bus_lock(vif->mac->bus);

+34 −24
Original line number Diff line number Diff line
@@ -65,34 +65,39 @@ qtnf_event_handle_sta_assoc(struct qtnf_wmac *mac, struct qtnf_vif *vif,
	sinfo.assoc_req_ies_len = 0;

	payload_len = len - sizeof(*sta_assoc);
	tlv = (struct qlink_tlv_hdr *)sta_assoc->ies;
	tlv = (const struct qlink_tlv_hdr *)sta_assoc->ies;

	while (payload_len >= sizeof(struct qlink_tlv_hdr)) {
	while (payload_len >= sizeof(*tlv)) {
		tlv_type = le16_to_cpu(tlv->type);
		tlv_value_len = le16_to_cpu(tlv->len);
		tlv_full_len = tlv_value_len + sizeof(struct qlink_tlv_hdr);

		if (tlv_full_len > payload_len) {
			pr_warn("VIF%u.%u: malformed TLV 0x%.2X; LEN: %u\n",
				mac->macid, vif->vifid, tlv_type,
				tlv_value_len);
		if (tlv_full_len > payload_len)
			return -EINVAL;
		}

		if (tlv_type == QTN_TLV_ID_IE_SET) {
			sinfo.assoc_req_ies = tlv->val;
			sinfo.assoc_req_ies_len = tlv_value_len;
			const struct qlink_tlv_ie_set *ie_set;
			unsigned int ie_len;

			if (payload_len < sizeof(*ie_set))
				return -EINVAL;

			ie_set = (const struct qlink_tlv_ie_set *)tlv;
			ie_len = tlv_value_len -
				(sizeof(*ie_set) - sizeof(ie_set->hdr));

			if (ie_set->type == QLINK_IE_SET_ASSOC_REQ && ie_len) {
				sinfo.assoc_req_ies = ie_set->ie_data;
				sinfo.assoc_req_ies_len = ie_len;
			}
		}

		payload_len -= tlv_full_len;
		tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_value_len);
	}

	if (payload_len) {
		pr_warn("VIF%u.%u: malformed TLV buf; bytes left: %zu\n",
			mac->macid, vif->vifid, payload_len);
	if (payload_len)
		return -EINVAL;
	}

	cfg80211_new_sta(vif->netdev, sta_assoc->sta_addr, &sinfo,
			 GFP_KERNEL);
@@ -289,27 +294,32 @@ qtnf_event_handle_scan_results(struct qtnf_vif *vif,
		tlv_value_len = le16_to_cpu(tlv->len);
		tlv_full_len = tlv_value_len + sizeof(struct qlink_tlv_hdr);

		if (tlv_full_len > payload_len) {
			pr_warn("VIF%u.%u: malformed TLV 0x%.2X; LEN: %u\n",
				vif->mac->macid, vif->vifid, tlv_type,
				tlv_value_len);
		if (tlv_full_len > payload_len)
			return -EINVAL;
		}

		if (tlv_type == QTN_TLV_ID_IE_SET) {
			ies = tlv->val;
			ies_len = tlv_value_len;
			const struct qlink_tlv_ie_set *ie_set;
			unsigned int ie_len;

			if (payload_len < sizeof(*ie_set))
				return -EINVAL;

			ie_set = (const struct qlink_tlv_ie_set *)tlv;
			ie_len = tlv_value_len -
				(sizeof(*ie_set) - sizeof(ie_set->hdr));

			if (ie_len) {
				ies = ie_set->ie_data;
				ies_len = ie_len;
			}
		}

		payload_len -= tlv_full_len;
		tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_value_len);
	}

	if (payload_len) {
		pr_warn("VIF%u.%u: malformed TLV buf; bytes left: %zu\n",
			vif->mac->macid, vif->vifid, payload_len);
	if (payload_len)
		return -EINVAL;
	}

	bss = cfg80211_inform_bss(wiphy, channel, frame_type,
				  sr->bssid, get_unaligned_le64(&sr->tsf),
+27 −0
Original line number Diff line number Diff line
@@ -1147,6 +1147,33 @@ struct qlink_tlv_chandef {
	struct qlink_chandef chan;
} __packed;

enum qlink_ie_set_type {
	QLINK_IE_SET_UNKNOWN,
	QLINK_IE_SET_ASSOC_REQ,
	QLINK_IE_SET_ASSOC_RESP,
	QLINK_IE_SET_PROBE_REQ,
	QLINK_IE_SET_SCAN,
	QLINK_IE_SET_BEACON_HEAD,
	QLINK_IE_SET_BEACON_TAIL,
	QLINK_IE_SET_BEACON_IES,
	QLINK_IE_SET_PROBE_RESP,
	QLINK_IE_SET_PROBE_RESP_IES,
};

/**
 * struct qlink_tlv_ie_set - data for QTN_TLV_ID_IE_SET
 *
 * @type: type of MGMT frame IEs belong to, one of &enum qlink_ie_set_type.
 * @flags: for future use.
 * @ie_data: IEs data.
 */
struct qlink_tlv_ie_set {
	struct qlink_tlv_hdr hdr;
	u8 type;
	u8 flags;
	u8 ie_data[0];
} __packed;

struct qlink_chan_stats {
	__le32 chan_num;
	__le32 cca_tx;