aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/quantenna/qtnfmac/commands.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/quantenna/qtnfmac/commands.c')
-rw-r--r--drivers/net/wireless/quantenna/qtnfmac/commands.c276
1 files changed, 190 insertions, 86 deletions
diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.c b/drivers/net/wireless/quantenna/qtnfmac/commands.c
index b81f81bd1411..8bc8dd637315 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/commands.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/commands.c
@@ -147,56 +147,66 @@ 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
150int qtnf_cmd_send_start_ap(struct qtnf_vif *vif) 150static void qtnf_cmd_tlv_ie_set_add(struct sk_buff *cmd_skb, u8 frame_type,
151 const u8 *buf, size_t len)
151{ 152{
152 struct sk_buff *cmd_skb; 153 struct qlink_tlv_ie_set *tlv;
153 u16 res_code = QLINK_CMD_RESULT_OK;
154 int ret;
155 154
156 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 155 tlv = (struct qlink_tlv_ie_set *)skb_put(cmd_skb, sizeof(*tlv) + len);
157 QLINK_CMD_START_AP, 156 tlv->hdr.type = cpu_to_le16(QTN_TLV_ID_IE_SET);
158 sizeof(struct qlink_cmd)); 157 tlv->hdr.len = cpu_to_le16(len + sizeof(*tlv) - sizeof(tlv->hdr));
159 if (unlikely(!cmd_skb)) 158 tlv->type = frame_type;
160 return -ENOMEM; 159 tlv->flags = 0;
161 160
162 qtnf_bus_lock(vif->mac->bus); 161 if (len && buf)
162 memcpy(tlv->ie_data, buf, len);
163}
163 164
164 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 165static bool qtnf_cmd_start_ap_can_fit(const struct qtnf_vif *vif,
166 const struct cfg80211_ap_settings *s)
167{
168 unsigned int len = sizeof(struct qlink_cmd_start_ap);
165 169
166 if (unlikely(ret)) 170 len += s->ssid_len;
167 goto out; 171 len += s->beacon.head_len;
172 len += s->beacon.tail_len;
173 len += s->beacon.beacon_ies_len;
174 len += s->beacon.proberesp_ies_len;
175 len += s->beacon.assocresp_ies_len;
176 len += s->beacon.probe_resp_len;
168 177
169 if (unlikely(res_code != QLINK_CMD_RESULT_OK)) { 178 if (cfg80211_chandef_valid(&s->chandef))
170 pr_err("VIF%u.%u: CMD failed: %u\n", vif->mac->macid, 179 len += sizeof(struct qlink_tlv_chandef);
171 vif->vifid, res_code);
172 ret = -EFAULT;
173 goto out;
174 }
175 180
176 netif_carrier_on(vif->netdev); 181 if (len > (sizeof(struct qlink_cmd) + QTNF_MAX_CMD_BUF_SIZE)) {
182 pr_err("VIF%u.%u: can not fit AP settings: %u\n",
183 vif->mac->macid, vif->vifid, len);
184 return false;
185 }
177 186
178out: 187 return true;
179 qtnf_bus_unlock(vif->mac->bus);
180 return ret;
181} 188}
182 189
183int qtnf_cmd_send_config_ap(struct qtnf_vif *vif, 190int qtnf_cmd_send_start_ap(struct qtnf_vif *vif,
184 const struct cfg80211_ap_settings *s) 191 const struct cfg80211_ap_settings *s)
185{ 192{
186 struct sk_buff *cmd_skb; 193 struct sk_buff *cmd_skb;
187 struct qlink_cmd_config_ap *cmd; 194 struct qlink_cmd_start_ap *cmd;
188 struct qlink_auth_encr *aen; 195 struct qlink_auth_encr *aen;
189 u16 res_code = QLINK_CMD_RESULT_OK; 196 u16 res_code = QLINK_CMD_RESULT_OK;
190 int ret; 197 int ret;
191 int i; 198 int i;
192 199
200 if (!qtnf_cmd_start_ap_can_fit(vif, s))
201 return -E2BIG;
202
193 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 203 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
194 QLINK_CMD_CONFIG_AP, 204 QLINK_CMD_START_AP,
195 sizeof(*cmd)); 205 sizeof(*cmd));
196 if (unlikely(!cmd_skb)) 206 if (unlikely(!cmd_skb))
197 return -ENOMEM; 207 return -ENOMEM;
198 208
199 cmd = (struct qlink_cmd_config_ap *)cmd_skb->data; 209 cmd = (struct qlink_cmd_start_ap *)cmd_skb->data;
200 cmd->dtim_period = s->dtim_period; 210 cmd->dtim_period = s->dtim_period;
201 cmd->beacon_interval = cpu_to_le16(s->beacon_interval); 211 cmd->beacon_interval = cpu_to_le16(s->beacon_interval);
202 cmd->hidden_ssid = qlink_hidden_ssid_nl2q(s->hidden_ssid); 212 cmd->hidden_ssid = qlink_hidden_ssid_nl2q(s->hidden_ssid);
@@ -211,7 +221,6 @@ int qtnf_cmd_send_config_ap(struct qtnf_vif *vif,
211 aen = &cmd->aen; 221 aen = &cmd->aen;
212 aen->auth_type = s->auth_type; 222 aen->auth_type = s->auth_type;
213 aen->privacy = !!s->privacy; 223 aen->privacy = !!s->privacy;
214 aen->mfp = 0;
215 aen->wpa_versions = cpu_to_le32(s->crypto.wpa_versions); 224 aen->wpa_versions = cpu_to_le32(s->crypto.wpa_versions);
216 aen->cipher_group = cpu_to_le32(s->crypto.cipher_group); 225 aen->cipher_group = cpu_to_le32(s->crypto.cipher_group);
217 aen->n_ciphers_pairwise = cpu_to_le32(s->crypto.n_ciphers_pairwise); 226 aen->n_ciphers_pairwise = cpu_to_le32(s->crypto.n_ciphers_pairwise);
@@ -241,6 +250,39 @@ int qtnf_cmd_send_config_ap(struct qtnf_vif *vif,
241 qlink_chandef_cfg2q(&s->chandef, &chtlv->chan); 250 qlink_chandef_cfg2q(&s->chandef, &chtlv->chan);
242 } 251 }
243 252
253 qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_BEACON_HEAD,
254 s->beacon.head, s->beacon.head_len);
255 qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_BEACON_TAIL,
256 s->beacon.tail, s->beacon.tail_len);
257 qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_BEACON_IES,
258 s->beacon.beacon_ies, s->beacon.beacon_ies_len);
259 qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_PROBE_RESP,
260 s->beacon.probe_resp, s->beacon.probe_resp_len);
261 qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_PROBE_RESP_IES,
262 s->beacon.proberesp_ies,
263 s->beacon.proberesp_ies_len);
264 qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_ASSOC_RESP,
265 s->beacon.assocresp_ies,
266 s->beacon.assocresp_ies_len);
267
268 if (s->ht_cap) {
269 struct qlink_tlv_hdr *tlv = (struct qlink_tlv_hdr *)
270 skb_put(cmd_skb, sizeof(*tlv) + sizeof(*s->ht_cap));
271
272 tlv->type = cpu_to_le16(WLAN_EID_HT_CAPABILITY);
273 tlv->len = cpu_to_le16(sizeof(*s->ht_cap));
274 memcpy(tlv->val, s->ht_cap, sizeof(*s->ht_cap));
275 }
276
277 if (s->vht_cap) {
278 struct qlink_tlv_hdr *tlv = (struct qlink_tlv_hdr *)
279 skb_put(cmd_skb, sizeof(*tlv) + sizeof(*s->vht_cap));
280
281 tlv->type = cpu_to_le16(WLAN_EID_VHT_CAPABILITY);
282 tlv->len = cpu_to_le16(sizeof(*s->vht_cap));
283 memcpy(tlv->val, s->vht_cap, sizeof(*s->vht_cap));
284 }
285
244 qtnf_bus_lock(vif->mac->bus); 286 qtnf_bus_lock(vif->mac->bus);
245 287
246 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 288 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code);
@@ -255,6 +297,8 @@ int qtnf_cmd_send_config_ap(struct qtnf_vif *vif,
255 goto out; 297 goto out;
256 } 298 }
257 299
300 netif_carrier_on(vif->netdev);
301
258out: 302out:
259 qtnf_bus_unlock(vif->mac->bus); 303 qtnf_bus_unlock(vif->mac->bus);
260 return ret; 304 return ret;
@@ -380,11 +424,10 @@ int qtnf_cmd_send_mgmt_set_appie(struct qtnf_vif *vif, u8 frame_type,
380 const u8 *buf, size_t len) 424 const u8 *buf, size_t len)
381{ 425{
382 struct sk_buff *cmd_skb; 426 struct sk_buff *cmd_skb;
383 struct qlink_cmd_mgmt_append_ie *cmd;
384 u16 res_code = QLINK_CMD_RESULT_OK; 427 u16 res_code = QLINK_CMD_RESULT_OK;
385 int ret; 428 int ret;
386 429
387 if (sizeof(*cmd) + len > QTNF_MAX_CMD_BUF_SIZE) { 430 if (len > QTNF_MAX_CMD_BUF_SIZE) {
388 pr_warn("VIF%u.%u: %u frame is too big: %zu\n", vif->mac->macid, 431 pr_warn("VIF%u.%u: %u frame is too big: %zu\n", vif->mac->macid,
389 vif->vifid, frame_type, len); 432 vif->vifid, frame_type, len);
390 return -E2BIG; 433 return -E2BIG;
@@ -392,21 +435,13 @@ int qtnf_cmd_send_mgmt_set_appie(struct qtnf_vif *vif, u8 frame_type,
392 435
393 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid, 436 cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
394 QLINK_CMD_MGMT_SET_APPIE, 437 QLINK_CMD_MGMT_SET_APPIE,
395 sizeof(*cmd)); 438 sizeof(struct qlink_cmd));
396 if (unlikely(!cmd_skb)) 439 if (unlikely(!cmd_skb))
397 return -ENOMEM; 440 return -ENOMEM;
398 441
399 qtnf_bus_lock(vif->mac->bus); 442 qtnf_cmd_tlv_ie_set_add(cmd_skb, frame_type, buf, len);
400
401 cmd = (struct qlink_cmd_mgmt_append_ie *)cmd_skb->data;
402 cmd->type = frame_type;
403 cmd->flags = 0;
404 443
405 /* If len == 0 then IE buf for specified frame type 444 qtnf_bus_lock(vif->mac->bus);
406 * should be cleared on EP.
407 */
408 if (len && buf)
409 qtnf_cmd_skb_put_buffer(cmd_skb, buf, len);
410 445
411 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code); 446 ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code);
412 447
@@ -1090,7 +1125,6 @@ qtnf_cmd_resp_proc_mac_info(struct qtnf_wmac *mac,
1090 mac_info = &mac->macinfo; 1125 mac_info = &mac->macinfo;
1091 1126
1092 mac_info->bands_cap = resp_info->bands_cap; 1127 mac_info->bands_cap = resp_info->bands_cap;
1093 mac_info->phymode_cap = resp_info->phymode_cap;
1094 memcpy(&mac_info->dev_mac, &resp_info->dev_mac, 1128 memcpy(&mac_info->dev_mac, &resp_info->dev_mac,
1095 sizeof(mac_info->dev_mac)); 1129 sizeof(mac_info->dev_mac));
1096 1130
@@ -1110,24 +1144,56 @@ qtnf_cmd_resp_proc_mac_info(struct qtnf_wmac *mac,
1110 qlink_chan_width_mask_to_nl(le16_to_cpu( 1144 qlink_chan_width_mask_to_nl(le16_to_cpu(
1111 resp_info->radar_detect_widths)); 1145 resp_info->radar_detect_widths));
1112 1146
1113 memcpy(&mac_info->ht_cap, &resp_info->ht_cap, sizeof(mac_info->ht_cap)); 1147 memcpy(&mac_info->ht_cap_mod_mask, &resp_info->ht_cap_mod_mask,
1114 memcpy(&mac_info->vht_cap, &resp_info->vht_cap, 1148 sizeof(mac_info->ht_cap_mod_mask));
1115 sizeof(mac_info->vht_cap)); 1149 memcpy(&mac_info->vht_cap_mod_mask, &resp_info->vht_cap_mod_mask,
1150 sizeof(mac_info->vht_cap_mod_mask));
1151}
1152
1153static void qtnf_cmd_resp_band_fill_htcap(const u8 *info,
1154 struct ieee80211_sta_ht_cap *bcap)
1155{
1156 const struct ieee80211_ht_cap *ht_cap =
1157 (const struct ieee80211_ht_cap *)info;
1158
1159 bcap->ht_supported = true;
1160 bcap->cap = le16_to_cpu(ht_cap->cap_info);
1161 bcap->ampdu_factor =
1162 ht_cap->ampdu_params_info & IEEE80211_HT_AMPDU_PARM_FACTOR;
1163 bcap->ampdu_density =
1164 (ht_cap->ampdu_params_info & IEEE80211_HT_AMPDU_PARM_DENSITY) >>
1165 IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT;
1166 memcpy(&bcap->mcs, &ht_cap->mcs, sizeof(bcap->mcs));
1167}
1168
1169static void qtnf_cmd_resp_band_fill_vhtcap(const u8 *info,
1170 struct ieee80211_sta_vht_cap *bcap)
1171{
1172 const struct ieee80211_vht_cap *vht_cap =
1173 (const struct ieee80211_vht_cap *)info;
1174
1175 bcap->vht_supported = true;
1176 bcap->cap = le32_to_cpu(vht_cap->vht_cap_info);
1177 memcpy(&bcap->vht_mcs, &vht_cap->supp_mcs, sizeof(bcap->vht_mcs));
1116} 1178}
1117 1179
1118static int 1180static int
1119qtnf_cmd_resp_fill_channels_info(struct ieee80211_supported_band *band, 1181qtnf_cmd_resp_fill_band_info(struct ieee80211_supported_band *band,
1120 struct qlink_resp_get_chan_info *resp, 1182 struct qlink_resp_band_info_get *resp,
1121 size_t payload_len) 1183 size_t payload_len)
1122{ 1184{
1123 u16 tlv_type; 1185 u16 tlv_type;
1124 size_t tlv_len; 1186 size_t tlv_len;
1187 size_t tlv_dlen;
1125 const struct qlink_tlv_hdr *tlv; 1188 const struct qlink_tlv_hdr *tlv;
1126 const struct qlink_tlv_channel *qchan; 1189 const struct qlink_tlv_channel *qchan;
1127 struct ieee80211_channel *chan; 1190 struct ieee80211_channel *chan;
1128 unsigned int chidx = 0; 1191 unsigned int chidx = 0;
1129 u32 qflags; 1192 u32 qflags;
1130 1193
1194 memset(&band->ht_cap, 0, sizeof(band->ht_cap));
1195 memset(&band->vht_cap, 0, sizeof(band->vht_cap));
1196
1131 if (band->channels) { 1197 if (band->channels) {
1132 if (band->n_channels == resp->num_chans) { 1198 if (band->n_channels == resp->num_chans) {
1133 memset(band->channels, 0, 1199 memset(band->channels, 0,
@@ -1155,7 +1221,8 @@ qtnf_cmd_resp_fill_channels_info(struct ieee80211_supported_band *band,
1155 1221
1156 while (payload_len >= sizeof(*tlv)) { 1222 while (payload_len >= sizeof(*tlv)) {
1157 tlv_type = le16_to_cpu(tlv->type); 1223 tlv_type = le16_to_cpu(tlv->type);
1158 tlv_len = le16_to_cpu(tlv->len) + sizeof(*tlv); 1224 tlv_dlen = le16_to_cpu(tlv->len);
1225 tlv_len = tlv_dlen + sizeof(*tlv);
1159 1226
1160 if (tlv_len > payload_len) { 1227 if (tlv_len > payload_len) {
1161 pr_warn("malformed TLV 0x%.2X; LEN: %zu\n", 1228 pr_warn("malformed TLV 0x%.2X; LEN: %zu\n",
@@ -1241,13 +1308,32 @@ qtnf_cmd_resp_fill_channels_info(struct ieee80211_supported_band *band,
1241 chan->hw_value, chan->flags, chan->max_power, 1308 chan->hw_value, chan->flags, chan->max_power,
1242 chan->max_reg_power); 1309 chan->max_reg_power);
1243 break; 1310 break;
1311 case WLAN_EID_HT_CAPABILITY:
1312 if (unlikely(tlv_dlen !=
1313 sizeof(struct ieee80211_ht_cap))) {
1314 pr_err("bad HTCAP TLV len %zu\n", tlv_dlen);
1315 goto error_ret;
1316 }
1317
1318 qtnf_cmd_resp_band_fill_htcap(tlv->val, &band->ht_cap);
1319 break;
1320 case WLAN_EID_VHT_CAPABILITY:
1321 if (unlikely(tlv_dlen !=
1322 sizeof(struct ieee80211_vht_cap))) {
1323 pr_err("bad VHTCAP TLV len %zu\n", tlv_dlen);
1324 goto error_ret;
1325 }
1326
1327 qtnf_cmd_resp_band_fill_vhtcap(tlv->val,
1328 &band->vht_cap);
1329 break;
1244 default: 1330 default:
1245 pr_warn("unknown TLV type: %#x\n", tlv_type); 1331 pr_warn("unknown TLV type: %#x\n", tlv_type);
1246 break; 1332 break;
1247 } 1333 }
1248 1334
1249 payload_len -= tlv_len; 1335 payload_len -= tlv_len;
1250 tlv = (struct qlink_tlv_hdr *)((u8 *)tlv + tlv_len); 1336 tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_dlen);
1251 } 1337 }
1252 1338
1253 if (payload_len) { 1339 if (payload_len) {
@@ -1469,13 +1555,13 @@ out:
1469 return ret; 1555 return ret;
1470} 1556}
1471 1557
1472int qtnf_cmd_get_mac_chan_info(struct qtnf_wmac *mac, 1558int qtnf_cmd_band_info_get(struct qtnf_wmac *mac,
1473 struct ieee80211_supported_band *band) 1559 struct ieee80211_supported_band *band)
1474{ 1560{
1475 struct sk_buff *cmd_skb, *resp_skb = NULL; 1561 struct sk_buff *cmd_skb, *resp_skb = NULL;
1476 size_t info_len; 1562 size_t info_len;
1477 struct qlink_cmd_chans_info_get *cmd; 1563 struct qlink_cmd_band_info_get *cmd;
1478 struct qlink_resp_get_chan_info *resp; 1564 struct qlink_resp_band_info_get *resp;
1479 u16 res_code = QLINK_CMD_RESULT_OK; 1565 u16 res_code = QLINK_CMD_RESULT_OK;
1480 int ret = 0; 1566 int ret = 0;
1481 u8 qband; 1567 u8 qband;
@@ -1495,12 +1581,12 @@ int qtnf_cmd_get_mac_chan_info(struct qtnf_wmac *mac,
1495 } 1581 }
1496 1582
1497 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, 0, 1583 cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, 0,
1498 QLINK_CMD_CHANS_INFO_GET, 1584 QLINK_CMD_BAND_INFO_GET,
1499 sizeof(*cmd)); 1585 sizeof(*cmd));
1500 if (!cmd_skb) 1586 if (!cmd_skb)
1501 return -ENOMEM; 1587 return -ENOMEM;
1502 1588
1503 cmd = (struct qlink_cmd_chans_info_get *)cmd_skb->data; 1589 cmd = (struct qlink_cmd_band_info_get *)cmd_skb->data;
1504 cmd->band = qband; 1590 cmd->band = qband;
1505 1591
1506 qtnf_bus_lock(mac->bus); 1592 qtnf_bus_lock(mac->bus);
@@ -1517,7 +1603,7 @@ int qtnf_cmd_get_mac_chan_info(struct qtnf_wmac *mac,
1517 goto out; 1603 goto out;
1518 } 1604 }
1519 1605
1520 resp = (struct qlink_resp_get_chan_info *)resp_skb->data; 1606 resp = (struct qlink_resp_band_info_get *)resp_skb->data;
1521 if (resp->band != qband) { 1607 if (resp->band != qband) {
1522 pr_err("MAC%u: reply band %u != cmd band %u\n", mac->macid, 1608 pr_err("MAC%u: reply band %u != cmd band %u\n", mac->macid,
1523 resp->band, qband); 1609 resp->band, qband);
@@ -1525,7 +1611,7 @@ int qtnf_cmd_get_mac_chan_info(struct qtnf_wmac *mac,
1525 goto out; 1611 goto out;
1526 } 1612 }
1527 1613
1528 ret = qtnf_cmd_resp_fill_channels_info(band, resp, info_len); 1614 ret = qtnf_cmd_resp_fill_band_info(band, resp, info_len);
1529 1615
1530out: 1616out:
1531 qtnf_bus_unlock(mac->bus); 1617 qtnf_bus_unlock(mac->bus);
@@ -1942,17 +2028,36 @@ out:
1942 return ret; 2028 return ret;
1943} 2029}
1944 2030
2031static void qtnf_cmd_channel_tlv_add(struct sk_buff *cmd_skb,
2032 const struct ieee80211_channel *sc)
2033{
2034 struct qlink_tlv_channel *qchan;
2035 u32 flags = 0;
2036
2037 qchan = skb_put_zero(cmd_skb, sizeof(*qchan));
2038 qchan->hdr.type = cpu_to_le16(QTN_TLV_ID_CHANNEL);
2039 qchan->hdr.len = cpu_to_le16(sizeof(*qchan) - sizeof(qchan->hdr));
2040 qchan->center_freq = cpu_to_le16(sc->center_freq);
2041 qchan->hw_value = cpu_to_le16(sc->hw_value);
2042
2043 if (sc->flags & IEEE80211_CHAN_NO_IR)
2044 flags |= QLINK_CHAN_NO_IR;
2045
2046 if (sc->flags & IEEE80211_CHAN_RADAR)
2047 flags |= QLINK_CHAN_RADAR;
2048
2049 qchan->flags = cpu_to_le32(flags);
2050}
2051
1945int qtnf_cmd_send_scan(struct qtnf_wmac *mac) 2052int qtnf_cmd_send_scan(struct qtnf_wmac *mac)
1946{ 2053{
1947 struct sk_buff *cmd_skb; 2054 struct sk_buff *cmd_skb;
1948 u16 res_code = QLINK_CMD_RESULT_OK; 2055 u16 res_code = QLINK_CMD_RESULT_OK;
1949 struct ieee80211_channel *sc; 2056 struct ieee80211_channel *sc;
1950 struct cfg80211_scan_request *scan_req = mac->scan_req; 2057 struct cfg80211_scan_request *scan_req = mac->scan_req;
1951 struct qlink_tlv_channel *qchan;
1952 int n_channels; 2058 int n_channels;
1953 int count = 0; 2059 int count = 0;
1954 int ret; 2060 int ret;
1955 u32 flags;
1956 2061
1957 if (scan_req->n_ssids > QTNF_MAX_SSID_LIST_LENGTH) { 2062 if (scan_req->n_ssids > QTNF_MAX_SSID_LIST_LENGTH) {
1958 pr_err("MAC%u: too many SSIDs in scan request\n", mac->macid); 2063 pr_err("MAC%u: too many SSIDs in scan request\n", mac->macid);
@@ -1977,9 +2082,8 @@ int qtnf_cmd_send_scan(struct qtnf_wmac *mac)
1977 } 2082 }
1978 2083
1979 if (scan_req->ie_len != 0) 2084 if (scan_req->ie_len != 0)
1980 qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_IE_SET, 2085 qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_PROBE_REQ,
1981 scan_req->ie, 2086 scan_req->ie, scan_req->ie_len);
1982 scan_req->ie_len);
1983 2087
1984 if (scan_req->n_channels) { 2088 if (scan_req->n_channels) {
1985 n_channels = scan_req->n_channels; 2089 n_channels = scan_req->n_channels;
@@ -1995,22 +2099,8 @@ int qtnf_cmd_send_scan(struct qtnf_wmac *mac)
1995 pr_debug("MAC%u: scan chan=%d, freq=%d, flags=%#x\n", 2099 pr_debug("MAC%u: scan chan=%d, freq=%d, flags=%#x\n",
1996 mac->macid, sc->hw_value, sc->center_freq, 2100 mac->macid, sc->hw_value, sc->center_freq,
1997 sc->flags); 2101 sc->flags);
1998 qchan = skb_put_zero(cmd_skb, sizeof(*qchan));
1999 flags = 0;
2000
2001 qchan->hdr.type = cpu_to_le16(QTN_TLV_ID_CHANNEL);
2002 qchan->hdr.len = cpu_to_le16(sizeof(*qchan) -
2003 sizeof(struct qlink_tlv_hdr));
2004 qchan->center_freq = cpu_to_le16(sc->center_freq);
2005 qchan->hw_value = cpu_to_le16(sc->hw_value);
2006
2007 if (sc->flags & IEEE80211_CHAN_NO_IR)
2008 flags |= QLINK_CHAN_NO_IR;
2009
2010 if (sc->flags & IEEE80211_CHAN_RADAR)
2011 flags |= QLINK_CHAN_RADAR;
2012 2102
2013 qchan->flags = cpu_to_le32(flags); 2103 qtnf_cmd_channel_tlv_add(cmd_skb, sc);
2014 n_channels--; 2104 n_channels--;
2015 count++; 2105 count++;
2016 } 2106 }
@@ -2054,10 +2144,15 @@ int qtnf_cmd_send_connect(struct qtnf_vif *vif,
2054 2144
2055 ether_addr_copy(cmd->bssid, vif->bssid); 2145 ether_addr_copy(cmd->bssid, vif->bssid);
2056 2146
2057 if (sme->channel) 2147 if (sme->bssid_hint)
2058 cmd->channel = cpu_to_le16(sme->channel->hw_value); 2148 ether_addr_copy(cmd->bssid_hint, sme->bssid_hint);
2149 else
2150 eth_zero_addr(cmd->bssid_hint);
2151
2152 if (sme->prev_bssid)
2153 ether_addr_copy(cmd->prev_bssid, sme->prev_bssid);
2059 else 2154 else
2060 cmd->channel = 0; 2155 eth_zero_addr(cmd->prev_bssid);
2061 2156
2062 if ((sme->bg_scan_period > 0) && 2157 if ((sme->bg_scan_period > 0) &&
2063 (sme->bg_scan_period <= QTNF_MAX_BG_SCAN_PERIOD)) 2158 (sme->bg_scan_period <= QTNF_MAX_BG_SCAN_PERIOD))
@@ -2075,11 +2170,18 @@ int qtnf_cmd_send_connect(struct qtnf_vif *vif,
2075 connect_flags |= QLINK_STA_CONNECT_USE_RRM; 2170 connect_flags |= QLINK_STA_CONNECT_USE_RRM;
2076 2171
2077 cmd->flags = cpu_to_le32(connect_flags); 2172 cmd->flags = cpu_to_le32(connect_flags);
2173 memcpy(&cmd->ht_capa, &sme->ht_capa, sizeof(cmd->ht_capa));
2174 memcpy(&cmd->ht_capa_mask, &sme->ht_capa_mask,
2175 sizeof(cmd->ht_capa_mask));
2176 memcpy(&cmd->vht_capa, &sme->vht_capa, sizeof(cmd->vht_capa));
2177 memcpy(&cmd->vht_capa_mask, &sme->vht_capa_mask,
2178 sizeof(cmd->vht_capa_mask));
2179 cmd->pbss = sme->pbss;
2078 2180
2079 aen = &cmd->aen; 2181 aen = &cmd->aen;
2080 aen->auth_type = sme->auth_type; 2182 aen->auth_type = sme->auth_type;
2081 aen->privacy = !!sme->privacy; 2183 aen->privacy = !!sme->privacy;
2082 aen->mfp = sme->mfp; 2184 cmd->mfp = sme->mfp;
2083 aen->wpa_versions = cpu_to_le32(sme->crypto.wpa_versions); 2185 aen->wpa_versions = cpu_to_le32(sme->crypto.wpa_versions);
2084 aen->cipher_group = cpu_to_le32(sme->crypto.cipher_group); 2186 aen->cipher_group = cpu_to_le32(sme->crypto.cipher_group);
2085 aen->n_ciphers_pairwise = cpu_to_le32(sme->crypto.n_ciphers_pairwise); 2187 aen->n_ciphers_pairwise = cpu_to_le32(sme->crypto.n_ciphers_pairwise);
@@ -2103,9 +2205,11 @@ int qtnf_cmd_send_connect(struct qtnf_vif *vif,
2103 sme->ssid_len); 2205 sme->ssid_len);
2104 2206
2105 if (sme->ie_len != 0) 2207 if (sme->ie_len != 0)
2106 qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_IE_SET, 2208 qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_ASSOC_REQ,
2107 sme->ie, 2209 sme->ie, sme->ie_len);
2108 sme->ie_len); 2210
2211 if (sme->channel)
2212 qtnf_cmd_channel_tlv_add(cmd_skb, sme->channel);
2109 2213
2110 qtnf_bus_lock(vif->mac->bus); 2214 qtnf_bus_lock(vif->mac->bus);
2111 2215