aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIgor Mitsyanko <igor.mitsyanko.os@quantenna.com>2017-10-30 21:04:50 -0400
committerKalle Valo <kvalo@codeaurora.org>2017-11-09 21:30:56 -0500
commit18b7470f92dfbea3e5ef82cab70edfc559d46735 (patch)
treecae86e88506436ab01e368b8bbb06a19f68967f4
parentd1398b5b34cca945cadf75f29833785cf6a675b1 (diff)
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: Igor Mitsyanko <igor.mitsyanko.os@quantenna.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-rw-r--r--drivers/net/wireless/quantenna/qtnfmac/commands.c25
-rw-r--r--drivers/net/wireless/quantenna/qtnfmac/event.c58
-rw-r--r--drivers/net/wireless/quantenna/qtnfmac/qlink.h27
3 files changed, 80 insertions, 30 deletions
diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.c b/drivers/net/wireless/quantenna/qtnfmac/commands.c
index 503187a371ae..8d3cdba99390 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/commands.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/commands.c
@@ -147,6 +147,21 @@ static struct sk_buff *qtnf_cmd_alloc_new_cmdskb(u8 macid, u8 vifid, u16 cmd_no,
147 return cmd_skb; 147 return cmd_skb;
148} 148}
149 149
150static void qtnf_cmd_tlv_ie_set_add(struct sk_buff *cmd_skb, u8 frame_type,
151 const u8 *buf, size_t len)
152{
153 struct qlink_tlv_ie_set *tlv;
154
155 tlv = (struct qlink_tlv_ie_set *)skb_put(cmd_skb, sizeof(*tlv) + len);
156 tlv->hdr.type = cpu_to_le16(QTN_TLV_ID_IE_SET);
157 tlv->hdr.len = cpu_to_le16(len + sizeof(*tlv) - sizeof(tlv->hdr));
158 tlv->type = frame_type;
159 tlv->flags = 0;
160
161 if (len && buf)
162 memcpy(tlv->ie_data, buf, len);
163}
164
150int qtnf_cmd_send_start_ap(struct qtnf_vif *vif) 165int qtnf_cmd_send_start_ap(struct qtnf_vif *vif)
151{ 166{
152 struct sk_buff *cmd_skb; 167 struct sk_buff *cmd_skb;
@@ -2028,9 +2043,8 @@ int qtnf_cmd_send_scan(struct qtnf_wmac *mac)
2028 } 2043 }
2029 2044
2030 if (scan_req->ie_len != 0) 2045 if (scan_req->ie_len != 0)
2031 qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_IE_SET, 2046 qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_PROBE_REQ,
2032 scan_req->ie, 2047 scan_req->ie, scan_req->ie_len);
2033 scan_req->ie_len);
2034 2048
2035 if (scan_req->n_channels) { 2049 if (scan_req->n_channels) {
2036 n_channels = scan_req->n_channels; 2050 n_channels = scan_req->n_channels;
@@ -2154,9 +2168,8 @@ int qtnf_cmd_send_connect(struct qtnf_vif *vif,
2154 sme->ssid_len); 2168 sme->ssid_len);
2155 2169
2156 if (sme->ie_len != 0) 2170 if (sme->ie_len != 0)
2157 qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_IE_SET, 2171 qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_ASSOC_REQ,
2158 sme->ie, 2172 sme->ie, sme->ie_len);
2159 sme->ie_len);
2160 2173
2161 qtnf_bus_lock(vif->mac->bus); 2174 qtnf_bus_lock(vif->mac->bus);
2162 2175
diff --git a/drivers/net/wireless/quantenna/qtnfmac/event.c b/drivers/net/wireless/quantenna/qtnfmac/event.c
index 4b29f9fb9c3c..b67a082eed69 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/event.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/event.c
@@ -65,34 +65,39 @@ qtnf_event_handle_sta_assoc(struct qtnf_wmac *mac, struct qtnf_vif *vif,
65 sinfo.assoc_req_ies_len = 0; 65 sinfo.assoc_req_ies_len = 0;
66 66
67 payload_len = len - sizeof(*sta_assoc); 67 payload_len = len - sizeof(*sta_assoc);
68 tlv = (struct qlink_tlv_hdr *)sta_assoc->ies; 68 tlv = (const struct qlink_tlv_hdr *)sta_assoc->ies;
69 69
70 while (payload_len >= sizeof(struct qlink_tlv_hdr)) { 70 while (payload_len >= sizeof(*tlv)) {
71 tlv_type = le16_to_cpu(tlv->type); 71 tlv_type = le16_to_cpu(tlv->type);
72 tlv_value_len = le16_to_cpu(tlv->len); 72 tlv_value_len = le16_to_cpu(tlv->len);
73 tlv_full_len = tlv_value_len + sizeof(struct qlink_tlv_hdr); 73 tlv_full_len = tlv_value_len + sizeof(struct qlink_tlv_hdr);
74 74
75 if (tlv_full_len > payload_len) { 75 if (tlv_full_len > payload_len)
76 pr_warn("VIF%u.%u: malformed TLV 0x%.2X; LEN: %u\n",
77 mac->macid, vif->vifid, tlv_type,
78 tlv_value_len);
79 return -EINVAL; 76 return -EINVAL;
80 }
81 77
82 if (tlv_type == QTN_TLV_ID_IE_SET) { 78 if (tlv_type == QTN_TLV_ID_IE_SET) {
83 sinfo.assoc_req_ies = tlv->val; 79 const struct qlink_tlv_ie_set *ie_set;
84 sinfo.assoc_req_ies_len = tlv_value_len; 80 unsigned int ie_len;
81
82 if (payload_len < sizeof(*ie_set))
83 return -EINVAL;
84
85 ie_set = (const struct qlink_tlv_ie_set *)tlv;
86 ie_len = tlv_value_len -
87 (sizeof(*ie_set) - sizeof(ie_set->hdr));
88
89 if (ie_set->type == QLINK_IE_SET_ASSOC_REQ && ie_len) {
90 sinfo.assoc_req_ies = ie_set->ie_data;
91 sinfo.assoc_req_ies_len = ie_len;
92 }
85 } 93 }
86 94
87 payload_len -= tlv_full_len; 95 payload_len -= tlv_full_len;
88 tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_value_len); 96 tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_value_len);
89 } 97 }
90 98
91 if (payload_len) { 99 if (payload_len)
92 pr_warn("VIF%u.%u: malformed TLV buf; bytes left: %zu\n",
93 mac->macid, vif->vifid, payload_len);
94 return -EINVAL; 100 return -EINVAL;
95 }
96 101
97 cfg80211_new_sta(vif->netdev, sta_assoc->sta_addr, &sinfo, 102 cfg80211_new_sta(vif->netdev, sta_assoc->sta_addr, &sinfo,
98 GFP_KERNEL); 103 GFP_KERNEL);
@@ -289,27 +294,32 @@ qtnf_event_handle_scan_results(struct qtnf_vif *vif,
289 tlv_value_len = le16_to_cpu(tlv->len); 294 tlv_value_len = le16_to_cpu(tlv->len);
290 tlv_full_len = tlv_value_len + sizeof(struct qlink_tlv_hdr); 295 tlv_full_len = tlv_value_len + sizeof(struct qlink_tlv_hdr);
291 296
292 if (tlv_full_len > payload_len) { 297 if (tlv_full_len > payload_len)
293 pr_warn("VIF%u.%u: malformed TLV 0x%.2X; LEN: %u\n",
294 vif->mac->macid, vif->vifid, tlv_type,
295 tlv_value_len);
296 return -EINVAL; 298 return -EINVAL;
297 }
298 299
299 if (tlv_type == QTN_TLV_ID_IE_SET) { 300 if (tlv_type == QTN_TLV_ID_IE_SET) {
300 ies = tlv->val; 301 const struct qlink_tlv_ie_set *ie_set;
301 ies_len = tlv_value_len; 302 unsigned int ie_len;
303
304 if (payload_len < sizeof(*ie_set))
305 return -EINVAL;
306
307 ie_set = (const struct qlink_tlv_ie_set *)tlv;
308 ie_len = tlv_value_len -
309 (sizeof(*ie_set) - sizeof(ie_set->hdr));
310
311 if (ie_len) {
312 ies = ie_set->ie_data;
313 ies_len = ie_len;
314 }
302 } 315 }
303 316
304 payload_len -= tlv_full_len; 317 payload_len -= tlv_full_len;
305 tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_value_len); 318 tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_value_len);
306 } 319 }
307 320
308 if (payload_len) { 321 if (payload_len)
309 pr_warn("VIF%u.%u: malformed TLV buf; bytes left: %zu\n",
310 vif->mac->macid, vif->vifid, payload_len);
311 return -EINVAL; 322 return -EINVAL;
312 }
313 323
314 bss = cfg80211_inform_bss(wiphy, channel, frame_type, 324 bss = cfg80211_inform_bss(wiphy, channel, frame_type,
315 sr->bssid, get_unaligned_le64(&sr->tsf), 325 sr->bssid, get_unaligned_le64(&sr->tsf),
diff --git a/drivers/net/wireless/quantenna/qtnfmac/qlink.h b/drivers/net/wireless/quantenna/qtnfmac/qlink.h
index c558d819a966..f491942eb6d0 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/qlink.h
+++ b/drivers/net/wireless/quantenna/qtnfmac/qlink.h
@@ -1147,6 +1147,33 @@ struct qlink_tlv_chandef {
1147 struct qlink_chandef chan; 1147 struct qlink_chandef chan;
1148} __packed; 1148} __packed;
1149 1149
1150enum qlink_ie_set_type {
1151 QLINK_IE_SET_UNKNOWN,
1152 QLINK_IE_SET_ASSOC_REQ,
1153 QLINK_IE_SET_ASSOC_RESP,
1154 QLINK_IE_SET_PROBE_REQ,
1155 QLINK_IE_SET_SCAN,
1156 QLINK_IE_SET_BEACON_HEAD,
1157 QLINK_IE_SET_BEACON_TAIL,
1158 QLINK_IE_SET_BEACON_IES,
1159 QLINK_IE_SET_PROBE_RESP,
1160 QLINK_IE_SET_PROBE_RESP_IES,
1161};
1162
1163/**
1164 * struct qlink_tlv_ie_set - data for QTN_TLV_ID_IE_SET
1165 *
1166 * @type: type of MGMT frame IEs belong to, one of &enum qlink_ie_set_type.
1167 * @flags: for future use.
1168 * @ie_data: IEs data.
1169 */
1170struct qlink_tlv_ie_set {
1171 struct qlink_tlv_hdr hdr;
1172 u8 type;
1173 u8 flags;
1174 u8 ie_data[0];
1175} __packed;
1176
1150struct qlink_chan_stats { 1177struct qlink_chan_stats {
1151 __le32 chan_num; 1178 __le32 chan_num;
1152 __le32 cca_tx; 1179 __le32 cca_tx;