Lines Matching +full:tlv +full:- +full:layout
1 // SPDX-License-Identifier: GPL-2.0
6 * Holger Schurig <hs4233@mail.mn-solutions.de>
109 int ret = -ENOTSUPP; in lbs_auth_to_authtype()
132 * the hight-bit set for basic rates
150 * TLV utility functions
159 * Add ssid TLV
165 static int lbs_add_ssid_tlv(u8 *tlv, const u8 *ssid, int ssid_len) in lbs_add_ssid_tlv() argument
167 struct mrvl_ie_ssid_param_set *ssid_tlv = (void *)tlv; in lbs_add_ssid_tlv()
170 * TLV-ID SSID 00 00 in lbs_add_ssid_tlv()
174 ssid_tlv->header.type = cpu_to_le16(TLV_TYPE_SSID); in lbs_add_ssid_tlv()
175 ssid_tlv->header.len = cpu_to_le16(ssid_len); in lbs_add_ssid_tlv()
176 memcpy(ssid_tlv->ssid, ssid, ssid_len); in lbs_add_ssid_tlv()
177 return sizeof(ssid_tlv->header) + ssid_len; in lbs_add_ssid_tlv()
182 * Add channel list TLV (section 8.4.2)
184 * Actual channel data comes from priv->wdev->wiphy->channels.
190 static int lbs_add_channel_list_tlv(struct lbs_private *priv, u8 *tlv, in lbs_add_channel_list_tlv() argument
194 (last_channel - priv->scan_channel); in lbs_add_channel_list_tlv()
196 struct mrvl_ie_header *header = (void *) tlv; in lbs_add_channel_list_tlv()
199 * TLV-ID CHANLIST 01 01 in lbs_add_channel_list_tlv()
211 header->type = cpu_to_le16(TLV_TYPE_CHANLIST); in lbs_add_channel_list_tlv()
212 header->len = cpu_to_le16(chanscanparamsize); in lbs_add_channel_list_tlv()
213 tlv += sizeof(struct mrvl_ie_header); in lbs_add_channel_list_tlv()
215 /* lbs_deb_scan("scan: channels %d to %d\n", priv->scan_channel, in lbs_add_channel_list_tlv()
217 memset(tlv, 0, chanscanparamsize); in lbs_add_channel_list_tlv()
219 while (priv->scan_channel < last_channel) { in lbs_add_channel_list_tlv()
220 struct chanscanparamset *param = (void *) tlv; in lbs_add_channel_list_tlv()
222 param->radiotype = CMD_SCAN_RADIO_TYPE_BG; in lbs_add_channel_list_tlv()
223 param->channumber = in lbs_add_channel_list_tlv()
224 priv->scan_req->channels[priv->scan_channel]->hw_value; in lbs_add_channel_list_tlv()
226 param->maxscantime = cpu_to_le16(LBS_DWELL_ACTIVE); in lbs_add_channel_list_tlv()
228 param->chanscanmode.passivescan = 1; in lbs_add_channel_list_tlv()
229 param->maxscantime = cpu_to_le16(LBS_DWELL_PASSIVE); in lbs_add_channel_list_tlv()
231 tlv += sizeof(struct chanscanparamset); in lbs_add_channel_list_tlv()
232 priv->scan_channel++; in lbs_add_channel_list_tlv()
239 * Add rates TLV
242 * rates the high bit is set. We add this TLV only because
250 /* Adds a TLV with all rates the hardware supports */
251 static int lbs_add_supported_rates_tlv(u8 *tlv) in lbs_add_supported_rates_tlv() argument
254 struct mrvl_ie_rates_param_set *rate_tlv = (void *)tlv; in lbs_add_supported_rates_tlv()
257 * TLV-ID RATES 01 00 in lbs_add_supported_rates_tlv()
261 rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES); in lbs_add_supported_rates_tlv()
262 tlv += sizeof(rate_tlv->header); in lbs_add_supported_rates_tlv()
263 i = lbs_add_rates(tlv); in lbs_add_supported_rates_tlv()
264 tlv += i; in lbs_add_supported_rates_tlv()
265 rate_tlv->header.len = cpu_to_le16(i); in lbs_add_supported_rates_tlv()
266 return sizeof(rate_tlv->header) + i; in lbs_add_supported_rates_tlv()
269 /* Add common rates from a TLV and return the new end of the TLV */
271 add_ie_rates(u8 *tlv, const u8 *ie, int *nrates) in add_ie_rates() argument
278 return tlv; in add_ie_rates()
289 *tlv++ = ie[ap]; in add_ie_rates()
294 return tlv; in add_ie_rates()
298 * Adds a TLV with all rates the hardware *and* BSS supports.
300 static int lbs_add_common_rates_tlv(u8 *tlv, struct cfg80211_bss *bss) in lbs_add_common_rates_tlv() argument
302 struct mrvl_ie_rates_param_set *rate_tlv = (void *)tlv; in lbs_add_common_rates_tlv()
315 rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES); in lbs_add_common_rates_tlv()
316 tlv += sizeof(rate_tlv->header); in lbs_add_common_rates_tlv()
320 tlv = add_ie_rates(tlv, rates_eid, &n); in lbs_add_common_rates_tlv()
324 tlv = add_ie_rates(tlv, ext_rates_eid, &n); in lbs_add_common_rates_tlv()
328 *tlv++ = 0x82; in lbs_add_common_rates_tlv()
329 *tlv++ = 0x84; in lbs_add_common_rates_tlv()
330 *tlv++ = 0x8b; in lbs_add_common_rates_tlv()
331 *tlv++ = 0x96; in lbs_add_common_rates_tlv()
336 rate_tlv->header.len = cpu_to_le16(n); in lbs_add_common_rates_tlv()
337 return sizeof(rate_tlv->header) + n; in lbs_add_common_rates_tlv()
342 * Add auth type TLV.
349 static int lbs_add_auth_type_tlv(u8 *tlv, enum nl80211_auth_type auth_type) in lbs_add_auth_type_tlv() argument
351 struct mrvl_ie_auth_type *auth = (void *) tlv; in lbs_add_auth_type_tlv()
358 auth->header.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE); in lbs_add_auth_type_tlv()
359 auth->header.len = cpu_to_le16(sizeof(*auth)-sizeof(auth->header)); in lbs_add_auth_type_tlv()
360 auth->auth = cpu_to_le16(lbs_auth_to_authtype(auth_type)); in lbs_add_auth_type_tlv()
366 * Add channel (phy ds) TLV
371 static int lbs_add_channel_tlv(u8 *tlv, u8 channel) in lbs_add_channel_tlv() argument
373 struct mrvl_ie_ds_param_set *ds = (void *) tlv; in lbs_add_channel_tlv()
380 ds->header.type = cpu_to_le16(TLV_TYPE_PHY_DS); in lbs_add_channel_tlv()
381 ds->header.len = cpu_to_le16(sizeof(*ds)-sizeof(ds->header)); in lbs_add_channel_tlv()
382 ds->channel = channel; in lbs_add_channel_tlv()
388 * Add (empty) CF param TLV of the form:
393 static int lbs_add_cf_param_tlv(u8 *tlv) in lbs_add_cf_param_tlv() argument
395 struct mrvl_ie_cf_param_set *cf = (void *)tlv; in lbs_add_cf_param_tlv()
405 cf->header.type = cpu_to_le16(TLV_TYPE_CF); in lbs_add_cf_param_tlv()
406 cf->header.len = cpu_to_le16(sizeof(*cf)-sizeof(cf->header)); in lbs_add_cf_param_tlv()
411 * Add WPA TLV
417 static int lbs_add_wpa_tlv(u8 *tlv, const u8 *ie, u8 ie_len) in lbs_add_wpa_tlv() argument
419 struct mrvl_ie_data *wpatlv = (struct mrvl_ie_data *)tlv; in lbs_add_wpa_tlv()
428 if (!wpaie || wpaie->datalen > 128) in lbs_add_wpa_tlv()
432 * Convert the found IE to a TLV. IEs use u8 for the header, in lbs_add_wpa_tlv()
441 wpatlv->header.type = cpu_to_le16(wpaie->id); in lbs_add_wpa_tlv()
442 wpatlv->header.len = cpu_to_le16(wpaie->datalen); in lbs_add_wpa_tlv()
443 memcpy(wpatlv->data, wpaie->data, wpaie->datalen); in lbs_add_wpa_tlv()
445 /* Return the total number of bytes added to the TLV buffer */ in lbs_add_wpa_tlv()
446 return sizeof(struct mrvl_ie_header) + wpaie->datalen; in lbs_add_wpa_tlv()
449 /* Add WPS enrollee TLV
455 static int lbs_add_wps_enrollee_tlv(u8 *tlv, const u8 *ie, size_t ie_len) in lbs_add_wps_enrollee_tlv() argument
457 struct mrvl_ie_data *wpstlv = (struct mrvl_ie_data *)tlv; in lbs_add_wps_enrollee_tlv()
467 /* Convert the WPS IE to a TLV. The IE looks like this: in lbs_add_wps_enrollee_tlv()
471 * but the TLV will look like this instead: in lbs_add_wps_enrollee_tlv()
476 wpstlv->header.type = cpu_to_le16(TLV_TYPE_WPS_ENROLLEE); in lbs_add_wps_enrollee_tlv()
477 wpstlv->header.len = cpu_to_le16(wpsie->datalen); in lbs_add_wps_enrollee_tlv()
478 memcpy(wpstlv->data, wpsie->data, wpsie->datalen); in lbs_add_wps_enrollee_tlv()
480 /* Return the total number of bytes added to the TLV buffer */ in lbs_add_wps_enrollee_tlv()
481 return sizeof(struct mrvl_ie_header) + wpsie->datalen; in lbs_add_wps_enrollee_tlv()
492 int ret = -ENOTSUPP; in lbs_cfg_set_monitor_channel()
497 ret = lbs_set_channel(priv, chandef->chan->hw_value); in lbs_cfg_set_monitor_channel()
508 int ret = -ENOTSUPP; in lbs_cfg_set_mesh_channel()
510 if (netdev != priv->mesh_dev) in lbs_cfg_set_mesh_channel()
513 ret = lbs_mesh_set_channel(priv, channel->hw_value); in lbs_cfg_set_mesh_channel()
526 * When scanning, the firmware doesn't send a nul packet with the power-safe
535 * When the firmware reports back a scan-result, it gives us an "u8 rssi",
540 ((-(int)rssi + 3)*100)
552 int ret = -EILSEQ; in lbs_ret_scan()
554 bsssize = get_unaligned_le16(&scanresp->bssdescriptsize); in lbs_ret_scan()
557 scanresp->nr_sets, bsssize, le16_to_cpu(resp->size)); in lbs_ret_scan()
559 if (scanresp->nr_sets == 0) { in lbs_ret_scan()
565 * The general layout of the scan response is described in chapter in lbs_ret_scan()
589 pos = scanresp->bssdesc_and_tlvbuffer; in lbs_ret_scan()
591 lbs_deb_hex(LBS_DEB_SCAN, "SCAN_RSP", scanresp->bssdesc_and_tlvbuffer, in lbs_ret_scan()
595 tsfsize = 4 + 8 * scanresp->nr_sets; in lbs_ret_scan()
598 /* Validity check: we expect a Marvell-Local TLV */ in lbs_ret_scan()
607 * Validity check: the TLV holds TSF values with 8 bytes each, so in lbs_ret_scan()
608 * the size in the TLV must match the nr_sets value in lbs_ret_scan()
612 if (i / 8 != scanresp->nr_sets) { in lbs_ret_scan()
614 "sets (expected %d got %d)\n", scanresp->nr_sets, in lbs_ret_scan()
619 for (i = 0; i < scanresp->nr_sets; i++) { in lbs_ret_scan()
627 int chan_no = -1; in lbs_ret_scan()
654 ielen = left = len - (6 + 1 + 8 + 2 + 2); in lbs_ret_scan()
659 left -= 2; in lbs_ret_scan()
671 left -= elen; in lbs_ret_scan()
676 if (chan_no != -1) { in lbs_ret_scan()
677 struct wiphy *wiphy = priv->wdev->wiphy; in lbs_ret_scan()
688 !(channel->flags & IEEE80211_CHAN_DISABLED)) { in lbs_ret_scan()
710 * Our scan command contains a TLV, consisting of a SSID TLV, a channel list
711 * TLV, a rates TLV, and an optional WPS IE. Determine the maximum size of them:
721 * Assumes priv->scan_req is initialized and valid
722 * Assumes priv->scan_channel is initialized
729 u8 *tlv; /* pointer into our current, growing TLV storage area */ in lbs_scan_worker() local
738 scan_cmd->bsstype = CMD_BSS_TYPE_ANY; in lbs_scan_worker()
741 running = !netif_queue_stopped(priv->dev); in lbs_scan_worker()
742 carrier = netif_carrier_ok(priv->dev); in lbs_scan_worker()
744 netif_stop_queue(priv->dev); in lbs_scan_worker()
746 netif_carrier_off(priv->dev); in lbs_scan_worker()
749 tlv = scan_cmd->tlvbuffer; in lbs_scan_worker()
751 /* add SSID TLV */ in lbs_scan_worker()
752 if (priv->scan_req->n_ssids && priv->scan_req->ssids[0].ssid_len > 0) in lbs_scan_worker()
753 tlv += lbs_add_ssid_tlv(tlv, in lbs_scan_worker()
754 priv->scan_req->ssids[0].ssid, in lbs_scan_worker()
755 priv->scan_req->ssids[0].ssid_len); in lbs_scan_worker()
758 last_channel = priv->scan_channel + LBS_SCAN_BEFORE_NAP; in lbs_scan_worker()
759 if (last_channel > priv->scan_req->n_channels) in lbs_scan_worker()
760 last_channel = priv->scan_req->n_channels; in lbs_scan_worker()
761 tlv += lbs_add_channel_list_tlv(priv, tlv, last_channel, in lbs_scan_worker()
762 priv->scan_req->n_ssids); in lbs_scan_worker()
764 /* add rates TLV */ in lbs_scan_worker()
765 tlv += lbs_add_supported_rates_tlv(tlv); in lbs_scan_worker()
767 /* add optional WPS enrollee TLV */ in lbs_scan_worker()
768 if (priv->scan_req->ie && priv->scan_req->ie_len) in lbs_scan_worker()
769 tlv += lbs_add_wps_enrollee_tlv(tlv, priv->scan_req->ie, in lbs_scan_worker()
770 priv->scan_req->ie_len); in lbs_scan_worker()
772 if (priv->scan_channel < priv->scan_req->n_channels) { in lbs_scan_worker()
773 cancel_delayed_work(&priv->scan_work); in lbs_scan_worker()
774 if (netif_running(priv->dev)) in lbs_scan_worker()
775 queue_delayed_work(priv->work_thread, &priv->scan_work, in lbs_scan_worker()
780 scan_cmd->hdr.size = cpu_to_le16(tlv - (u8 *)scan_cmd); in lbs_scan_worker()
783 lbs_deb_hex(LBS_DEB_SCAN, "SCAN_TLV", scan_cmd->tlvbuffer, in lbs_scan_worker()
784 tlv - scan_cmd->tlvbuffer); in lbs_scan_worker()
786 __lbs_cmd(priv, CMD_802_11_SCAN, &scan_cmd->hdr, in lbs_scan_worker()
787 le16_to_cpu(scan_cmd->hdr.size), in lbs_scan_worker()
790 if (priv->scan_channel >= priv->scan_req->n_channels) { in lbs_scan_worker()
792 cancel_delayed_work(&priv->scan_work); in lbs_scan_worker()
798 netif_carrier_on(priv->dev); in lbs_scan_worker()
799 if (running && !priv->tx_pending_len) in lbs_scan_worker()
800 netif_wake_queue(priv->dev); in lbs_scan_worker()
805 if (priv->scan_req == NULL) { in lbs_scan_worker()
807 wake_up_all(&priv->scan_q); in lbs_scan_worker()
815 request->n_ssids, request->n_channels, request->ie_len); in _internal_start_scan()
817 priv->scan_channel = 0; in _internal_start_scan()
818 priv->scan_req = request; in _internal_start_scan()
819 priv->internal_scan = internal; in _internal_start_scan()
821 queue_delayed_work(priv->work_thread, &priv->scan_work, in _internal_start_scan()
826 * Clean up priv->scan_req. Should be used to handle the allocation details.
830 WARN_ON(!priv->scan_req); in lbs_scan_done()
832 if (priv->internal_scan) { in lbs_scan_done()
833 kfree(priv->scan_req); in lbs_scan_done()
839 cfg80211_scan_done(priv->scan_req, &info); in lbs_scan_done()
842 priv->scan_req = NULL; in lbs_scan_done()
851 if (priv->scan_req || delayed_work_pending(&priv->scan_work)) { in lbs_cfg_scan()
853 ret = -EAGAIN; in lbs_cfg_scan()
859 if (priv->surpriseremoved) in lbs_cfg_scan()
860 ret = -EIO; in lbs_cfg_scan()
876 cfg80211_disconnected(priv->dev, 0, NULL, 0, locally_generated, in lbs_send_disconnect_notification()
882 cfg80211_michael_mic_failure(priv->dev, in lbs_send_mic_failureevent()
883 priv->assoc_bss, in lbs_send_mic_failureevent()
887 -1, in lbs_send_mic_failureevent()
910 cmd.keyindex = cpu_to_le16(priv->wep_tx_key); in lbs_remove_wep_keys()
946 if (priv->wep_key_len[0] || priv->wep_key_len[1] || in lbs_set_wep_keys()
947 priv->wep_key_len[2] || priv->wep_key_len[3]) { in lbs_set_wep_keys()
951 cmd.keyindex = cpu_to_le16(priv->wep_tx_key); in lbs_set_wep_keys()
955 switch (priv->wep_key_len[i]) { in lbs_set_wep_keys()
966 memcpy(cmd.keymaterial[i], priv->wep_key[i], in lbs_set_wep_keys()
967 priv->wep_key_len[i]); in lbs_set_wep_keys()
1038 * TLV type 00 01 key param in lbs_set_key_material()
1049 cmd.param.length = cpu_to_le16(sizeof(cmd.param) - 4); in lbs_set_key_material()
1085 if (sme->bssid) in lbs_set_authtype()
1086 memcpy(cmd.bssid, sme->bssid, ETH_ALEN); in lbs_set_authtype()
1088 ret = lbs_auth_to_authtype(sme->auth_type); in lbs_set_authtype()
1126 ret = -ENOMEM; in lbs_associate()
1129 pos = &cmd->iebuf[0]; in lbs_associate()
1143 cmd->hdr.command = cpu_to_le16(CMD_802_11_ASSOCIATE); in lbs_associate()
1146 memcpy(cmd->bssid, bss->bssid, ETH_ALEN); in lbs_associate()
1147 cmd->listeninterval = cpu_to_le16(MRVDRV_DEFAULT_LISTEN_INTERVAL); in lbs_associate()
1148 cmd->capability = cpu_to_le16(bss->capability); in lbs_associate()
1150 /* add SSID TLV */ in lbs_associate()
1159 /* add DS param TLV */ in lbs_associate()
1160 if (bss->channel) in lbs_associate()
1161 pos += lbs_add_channel_tlv(pos, bss->channel->hw_value); in lbs_associate()
1165 /* add (empty) CF param TLV */ in lbs_associate()
1168 /* add rates TLV */ in lbs_associate()
1171 lbs_deb_hex(LBS_DEB_ASSOC, "Common Rates", tmp, pos - tmp); in lbs_associate()
1173 /* add auth type TLV */ in lbs_associate()
1174 if (MRVL_FW_MAJOR_REV(priv->fwrelease) >= 9) in lbs_associate()
1175 pos += lbs_add_auth_type_tlv(pos, sme->auth_type); in lbs_associate()
1177 /* add WPA/WPA2 TLV */ in lbs_associate()
1178 if (sme->ie && sme->ie_len) in lbs_associate()
1179 pos += lbs_add_wpa_tlv(pos, sme->ie, sme->ie_len); in lbs_associate()
1181 len = sizeof(*cmd) + (u16)(pos - (u8 *) &cmd->iebuf); in lbs_associate()
1182 cmd->hdr.size = cpu_to_le16(len); in lbs_associate()
1185 le16_to_cpu(cmd->hdr.size)); in lbs_associate()
1188 memcpy(priv->assoc_bss, bss->bssid, ETH_ALEN); in lbs_associate()
1197 status = le16_to_cpu(resp->statuscode); in lbs_associate()
1200 * response to the following values returned in resp->statuscode: in lbs_associate()
1203 * 0 -> 0x0000 ASSOC_RESULT_SUCCESS in lbs_associate()
1204 * 13 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED in lbs_associate()
1205 * 14 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED in lbs_associate()
1206 * 15 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED in lbs_associate()
1207 * 16 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED in lbs_associate()
1208 * others -> 0x0003 ASSOC_RESULT_REFUSED in lbs_associate()
1211 * 0x0001 -> ASSOC_RESULT_INVALID_PARAMETERS (unused) in lbs_associate()
1212 * 0x0002 -> ASSOC_RESULT_TIMEOUT (internal timer expired waiting for in lbs_associate()
1215 if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8) { in lbs_associate()
1245 "aid 0x%04x\n", status, le16_to_cpu(resp->statuscode), in lbs_associate()
1246 le16_to_cpu(resp->capability), le16_to_cpu(resp->aid)); in lbs_associate()
1248 resp_ie_len = le16_to_cpu(resp->hdr.size) in lbs_associate()
1249 - sizeof(resp->hdr) in lbs_associate()
1250 - 6; in lbs_associate()
1251 cfg80211_connect_result(priv->dev, in lbs_associate()
1252 priv->assoc_bss, in lbs_associate()
1253 sme->ie, sme->ie_len, in lbs_associate()
1254 resp->iebuf, resp_ie_len, in lbs_associate()
1259 /* TODO: get rid of priv->connect_status */ in lbs_associate()
1260 priv->connect_status = LBS_CONNECTED; in lbs_associate()
1261 netif_carrier_on(priv->dev); in lbs_associate()
1262 if (!priv->tx_pending_len) in lbs_associate()
1263 netif_tx_wake_all_queues(priv->dev); in lbs_associate()
1285 creq->ssids = (void *)&creq->channels[n_channels]; in _new_connect_scan_req()
1286 creq->n_channels = n_channels; in _new_connect_scan_req()
1287 creq->n_ssids = 1; in _new_connect_scan_req()
1294 if (!wiphy->bands[band]) in _new_connect_scan_req()
1297 for (j = 0; j < wiphy->bands[band]->n_channels; j++) { in _new_connect_scan_req()
1299 if (wiphy->bands[band]->channels[j].flags & in _new_connect_scan_req()
1303 creq->channels[i] = &wiphy->bands[band]->channels[j]; in _new_connect_scan_req()
1308 /* Set real number of channels specified in creq->channels[] */ in _new_connect_scan_req()
1309 creq->n_channels = i; in _new_connect_scan_req()
1312 memcpy(creq->ssids[0].ssid, sme->ssid, sme->ssid_len); in _new_connect_scan_req()
1313 creq->ssids[0].ssid_len = sme->ssid_len; in _new_connect_scan_req()
1331 if (dev == priv->mesh_dev) in lbs_cfg_connect()
1332 return -EOPNOTSUPP; in lbs_cfg_connect()
1334 if (!sme->bssid) { in lbs_cfg_connect()
1342 wait_event_interruptible_timeout(priv->scan_q, in lbs_cfg_connect()
1343 (priv->scan_req == NULL), in lbs_cfg_connect()
1348 ret = -EINVAL; in lbs_cfg_connect()
1356 wait_event_interruptible_timeout(priv->scan_q, in lbs_cfg_connect()
1357 (priv->scan_req == NULL), in lbs_cfg_connect()
1363 bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid, in lbs_cfg_connect()
1364 sme->ssid, sme->ssid_len, IEEE80211_BSS_TYPE_ESS, in lbs_cfg_connect()
1368 sme->bssid); in lbs_cfg_connect()
1369 ret = -ENOENT; in lbs_cfg_connect()
1372 lbs_deb_assoc("trying %pM\n", bss->bssid); in lbs_cfg_connect()
1374 sme->crypto.cipher_group, in lbs_cfg_connect()
1375 sme->key_idx, sme->key_len); in lbs_cfg_connect()
1378 priv->wep_tx_key = 0; in lbs_cfg_connect()
1379 memset(priv->wep_key, 0, sizeof(priv->wep_key)); in lbs_cfg_connect()
1380 memset(priv->wep_key_len, 0, sizeof(priv->wep_key_len)); in lbs_cfg_connect()
1383 switch (sme->crypto.cipher_group) { in lbs_cfg_connect()
1386 /* Store provided WEP keys in priv-> */ in lbs_cfg_connect()
1387 priv->wep_tx_key = sme->key_idx; in lbs_cfg_connect()
1388 priv->wep_key_len[sme->key_idx] = sme->key_len; in lbs_cfg_connect()
1389 memcpy(priv->wep_key[sme->key_idx], sme->key, sme->key_len); in lbs_cfg_connect()
1392 priv->mac_control |= CMD_ACT_MAC_WEP_ENABLE; in lbs_cfg_connect()
1403 * Therefore: fall-through in lbs_cfg_connect()
1409 priv->mac_control &= ~CMD_ACT_MAC_WEP_ENABLE; in lbs_cfg_connect()
1422 lbs_enable_rsn(priv, sme->crypto.cipher_group != 0); in lbs_cfg_connect()
1426 sme->crypto.cipher_group); in lbs_cfg_connect()
1427 ret = -ENOTSUPP; in lbs_cfg_connect()
1432 if (ret == -ENOTSUPP) { in lbs_cfg_connect()
1433 wiphy_err(wiphy, "unsupported authtype 0x%x\n", sme->auth_type); in lbs_cfg_connect()
1456 memcpy(cmd.macaddr, &priv->assoc_bss, ETH_ALEN); in lbs_disconnect()
1463 cfg80211_disconnected(priv->dev, in lbs_disconnect()
1467 priv->connect_status = LBS_DISCONNECTED; in lbs_disconnect()
1477 if (dev == priv->mesh_dev) in lbs_cfg_disconnect()
1478 return -EOPNOTSUPP; in lbs_cfg_disconnect()
1481 priv->disassoc_reason = reason_code; in lbs_cfg_disconnect()
1493 if (netdev == priv->mesh_dev) in lbs_cfg_set_default_key()
1494 return -EOPNOTSUPP; in lbs_cfg_set_default_key()
1496 if (key_index != priv->wep_tx_key) { in lbs_cfg_set_default_key()
1498 priv->wep_tx_key = key_index; in lbs_cfg_set_default_key()
1515 if (netdev == priv->mesh_dev) in lbs_cfg_add_key()
1516 return -EOPNOTSUPP; in lbs_cfg_add_key()
1519 params->cipher, mac_addr); in lbs_cfg_add_key()
1521 idx, params->key_len); in lbs_cfg_add_key()
1522 if (params->key_len) in lbs_cfg_add_key()
1524 params->key, params->key_len); in lbs_cfg_add_key()
1526 lbs_deb_assoc("add_key: seq len %d\n", params->seq_len); in lbs_cfg_add_key()
1527 if (params->seq_len) in lbs_cfg_add_key()
1529 params->seq, params->seq_len); in lbs_cfg_add_key()
1531 switch (params->cipher) { in lbs_cfg_add_key()
1535 if ((priv->wep_key_len[idx] != params->key_len) || in lbs_cfg_add_key()
1536 memcmp(priv->wep_key[idx], in lbs_cfg_add_key()
1537 params->key, params->key_len) != 0) { in lbs_cfg_add_key()
1538 priv->wep_key_len[idx] = params->key_len; in lbs_cfg_add_key()
1539 memcpy(priv->wep_key[idx], in lbs_cfg_add_key()
1540 params->key, params->key_len); in lbs_cfg_add_key()
1549 key_type = (params->cipher == WLAN_CIPHER_SUITE_TKIP) in lbs_cfg_add_key()
1555 params->key, params->key_len); in lbs_cfg_add_key()
1558 wiphy_err(wiphy, "unhandled cipher 0x%x\n", params->cipher); in lbs_cfg_add_key()
1559 ret = -ENOTSUPP; in lbs_cfg_add_key()
1578 * I think can keep this a NO-OP, because: in lbs_cfg_del_key()
1580 * - we clear all keys whenever we do lbs_cfg_connect() anyway in lbs_cfg_del_key()
1581 * - neither "iw" nor "wpa_supplicant" won't call this during in lbs_cfg_del_key()
1583 * - TODO: but I have to check if this is still true when in lbs_cfg_del_key()
1584 * I set the AP to periodic re-keying in lbs_cfg_del_key()
1585 * - we've not kzallec() something when we've added a key at in lbs_cfg_del_key()
1592 if (key_index < 3 && priv->wep_key_len[key_index]) { in lbs_cfg_del_key()
1593 priv->wep_key_len[key_index] = 0; in lbs_cfg_del_key()
1614 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES) | in lbs_cfg_get_station()
1618 sinfo->tx_bytes = priv->dev->stats.tx_bytes; in lbs_cfg_get_station()
1619 sinfo->tx_packets = priv->dev->stats.tx_packets; in lbs_cfg_get_station()
1620 sinfo->rx_bytes = priv->dev->stats.rx_bytes; in lbs_cfg_get_station()
1621 sinfo->rx_packets = priv->dev->stats.rx_packets; in lbs_cfg_get_station()
1626 sinfo->signal = signal; in lbs_cfg_get_station()
1627 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL); in lbs_cfg_get_station()
1630 /* Convert priv->cur_rate from hw_value to NL80211 value */ in lbs_cfg_get_station()
1632 if (priv->cur_rate == lbs_rates[i].hw_value) { in lbs_cfg_get_station()
1633 sinfo->txrate.legacy = lbs_rates[i].bitrate; in lbs_cfg_get_station()
1634 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); in lbs_cfg_get_station()
1656 if (dev == priv->mesh_dev) in lbs_change_intf()
1657 return -EOPNOTSUPP; in lbs_change_intf()
1665 return -EOPNOTSUPP; in lbs_change_intf()
1668 if (priv->iface_running) in lbs_change_intf()
1672 priv->wdev->iftype = type; in lbs_change_intf()
1680 * IBSS (Ad-Hoc)
1684 * The firmware needs the following bits masked out of the beacon-derived
1710 *fake++ = params->ssid_len; in lbs_join_post()
1711 memcpy(fake, params->ssid, params->ssid_len); in lbs_join_post()
1712 fake += params->ssid_len; in lbs_join_post()
1723 *fake++ = params->chandef.chan->hw_value; in lbs_join_post()
1741 lbs_deb_hex(LBS_DEB_CFG80211, "IE", fake_ie, fake - fake_ie); in lbs_join_post()
1743 bss = cfg80211_inform_bss(priv->wdev->wiphy, in lbs_join_post()
1744 params->chandef.chan, in lbs_join_post()
1749 params->beacon_interval, in lbs_join_post()
1750 fake_ie, fake - fake_ie, in lbs_join_post()
1752 cfg80211_put_bss(priv->wdev->wiphy, bss); in lbs_join_post()
1754 cfg80211_ibss_joined(priv->dev, bssid, params->chandef.chan, in lbs_join_post()
1758 priv->connect_status = LBS_CONNECTED; in lbs_join_post()
1759 netif_carrier_on(priv->dev); in lbs_join_post()
1760 if (!priv->tx_pending_len) in lbs_join_post()
1761 netif_wake_queue(priv->dev); in lbs_join_post()
1814 memcpy(cmd.bss.bssid, bss->bssid, ETH_ALEN); in lbs_ibss_join_existing()
1815 memcpy(cmd.bss.ssid, params->ssid, params->ssid_len); in lbs_ibss_join_existing()
1817 cmd.bss.beaconperiod = cpu_to_le16(params->beacon_interval); in lbs_ibss_join_existing()
1820 cmd.bss.ds.channel = params->chandef.chan->hw_value; in lbs_ibss_join_existing()
1824 cmd.bss.capability = cpu_to_le16(bss->capability & CAPINFO_MASK); in lbs_ibss_join_existing()
1837 ret = -EINVAL; in lbs_ibss_join_existing()
1857 if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8) { in lbs_ibss_join_existing()
1874 lbs_join_post(priv, params, bss->bssid, bss->capability); in lbs_ibss_join_existing()
1926 memcpy(cmd.ssid, params->ssid, params->ssid_len); in lbs_ibss_start_new()
1928 cmd.beaconperiod = cpu_to_le16(params->beacon_interval); in lbs_ibss_start_new()
1934 cmd.ds.channel = params->chandef.chan->hw_value; in lbs_ibss_start_new()
1936 if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8) in lbs_ibss_start_new()
1958 lbs_join_post(priv, params, resp->bssid, capability); in lbs_ibss_start_new()
1972 if (dev == priv->mesh_dev) in lbs_join_ibss()
1973 return -EOPNOTSUPP; in lbs_join_ibss()
1975 if (!params->chandef.chan) { in lbs_join_ibss()
1976 ret = -ENOTSUPP; in lbs_join_ibss()
1980 ret = lbs_set_channel(priv, params->chandef.chan->hw_value); in lbs_join_ibss()
1986 bss = cfg80211_get_bss(wiphy, params->chandef.chan, params->bssid, in lbs_join_ibss()
1987 params->ssid, params->ssid_len, in lbs_join_ibss()
2008 if (dev == priv->mesh_dev) in lbs_leave_ibss()
2009 return -EOPNOTSUPP; in lbs_leave_ibss()
2028 if (!(priv->fwcapinfo & FW_CAPINFO_PS)) { in lbs_set_power_mgmt()
2032 return -EINVAL; in lbs_set_power_mgmt()
2039 if (priv->is_polling) { in lbs_set_power_mgmt()
2043 return -EINVAL; in lbs_set_power_mgmt()
2046 priv->psmode = LBS802_11POWERMODECAM; in lbs_set_power_mgmt()
2047 if (priv->psstate != PS_STATE_FULL_POWER) in lbs_set_power_mgmt()
2053 if (priv->psmode != LBS802_11POWERMODECAM) in lbs_set_power_mgmt()
2055 priv->psmode = LBS802_11POWERMODEMAX_PSP; in lbs_set_power_mgmt()
2056 if (priv->connect_status == LBS_CONNECTED) in lbs_set_power_mgmt()
2095 return ERR_PTR(-ENOMEM); in lbs_cfg_alloc()
2097 wdev->wiphy = wiphy_new(&lbs_cfg80211_ops, sizeof(struct lbs_private)); in lbs_cfg_alloc()
2098 if (!wdev->wiphy) { in lbs_cfg_alloc()
2100 ret = -ENOMEM; in lbs_cfg_alloc()
2131 if (regmap[i].code == priv->regioncode) { in lbs_cfg_set_regulatory_hint()
2132 regulatory_hint(priv->wdev->wiphy, regmap[i].cn); in lbs_cfg_set_regulatory_hint()
2142 memcpy(priv->country_code, request->alpha2, sizeof(request->alpha2)); in lbs_reg_notifier()
2154 struct wireless_dev *wdev = priv->wdev; in lbs_cfg_register()
2157 wdev->wiphy->max_scan_ssids = 1; in lbs_cfg_register()
2158 wdev->wiphy->max_scan_ie_len = 256; in lbs_cfg_register()
2159 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; in lbs_cfg_register()
2161 wdev->wiphy->interface_modes = in lbs_cfg_register()
2165 wdev->wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR); in lbs_cfg_register()
2167 wdev->wiphy->interface_modes |= BIT(NL80211_IFTYPE_MESH_POINT); in lbs_cfg_register()
2169 wdev->wiphy->bands[NL80211_BAND_2GHZ] = &lbs_band_2ghz; in lbs_cfg_register()
2172 * We could check priv->fwcapinfo && FW_CAPINFO_WPA, but I have in lbs_cfg_register()
2175 wdev->wiphy->cipher_suites = cipher_suites; in lbs_cfg_register()
2176 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); in lbs_cfg_register()
2177 wdev->wiphy->reg_notifier = lbs_reg_notifier; in lbs_cfg_register()
2179 ret = wiphy_register(wdev->wiphy); in lbs_cfg_register()
2183 priv->wiphy_registered = true; in lbs_cfg_register()
2185 ret = register_netdev(priv->dev); in lbs_cfg_register()
2189 INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker); in lbs_cfg_register()
2198 cancel_delayed_work_sync(&priv->scan_work); in lbs_scan_deinit()
2204 struct wireless_dev *wdev = priv->wdev; in lbs_cfg_free()
2209 if (priv->wiphy_registered) in lbs_cfg_free()
2210 wiphy_unregister(wdev->wiphy); in lbs_cfg_free()
2212 if (wdev->wiphy) in lbs_cfg_free()
2213 wiphy_free(wdev->wiphy); in lbs_cfg_free()