aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/wil6210/cfg80211.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/wil6210/cfg80211.c')
-rw-r--r--drivers/net/wireless/ath/wil6210/cfg80211.c458
1 files changed, 347 insertions, 111 deletions
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index cdbb393863f3..d18e81fae5f1 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -48,9 +48,29 @@ static struct ieee80211_channel wil_60ghz_channels[] = {
48 CHAN60G(1, 0), 48 CHAN60G(1, 0),
49 CHAN60G(2, 0), 49 CHAN60G(2, 0),
50 CHAN60G(3, 0), 50 CHAN60G(3, 0),
51/* channel 4 not supported yet */ 51 CHAN60G(4, 0),
52}; 52};
53 53
54static int wil_num_supported_channels(struct wil6210_priv *wil)
55{
56 int num_channels = ARRAY_SIZE(wil_60ghz_channels);
57
58 if (!test_bit(WMI_FW_CAPABILITY_CHANNEL_4, wil->fw_capabilities))
59 num_channels--;
60
61 return num_channels;
62}
63
64void update_supported_bands(struct wil6210_priv *wil)
65{
66 struct wiphy *wiphy = wil_to_wiphy(wil);
67
68 wil_dbg_misc(wil, "update supported bands");
69
70 wiphy->bands[NL80211_BAND_60GHZ]->n_channels =
71 wil_num_supported_channels(wil);
72}
73
54/* Vendor id to be used in vendor specific command and events 74/* Vendor id to be used in vendor specific command and events
55 * to user space. 75 * to user space.
56 * NOTE: The authoritative place for definition of QCA_NL80211_VENDOR_ID, 76 * NOTE: The authoritative place for definition of QCA_NL80211_VENDOR_ID,
@@ -199,7 +219,9 @@ wil_mgmt_stypes[NUM_NL80211_IFTYPES] = {
199 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) | 219 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
200 BIT(IEEE80211_STYPE_PROBE_RESP >> 4) | 220 BIT(IEEE80211_STYPE_PROBE_RESP >> 4) |
201 BIT(IEEE80211_STYPE_ASSOC_RESP >> 4) | 221 BIT(IEEE80211_STYPE_ASSOC_RESP >> 4) |
202 BIT(IEEE80211_STYPE_DISASSOC >> 4), 222 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
223 BIT(IEEE80211_STYPE_AUTH >> 4) |
224 BIT(IEEE80211_STYPE_REASSOC_RESP >> 4),
203 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | 225 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
204 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | 226 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
205 BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | 227 BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
@@ -276,6 +298,8 @@ int wil_cid_fill_sinfo(struct wil6210_vif *vif, int cid,
276 struct wil_net_stats *stats = &wil->sta[cid].stats; 298 struct wil_net_stats *stats = &wil->sta[cid].stats;
277 int rc; 299 int rc;
278 300
301 memset(&reply, 0, sizeof(reply));
302
279 rc = wmi_call(wil, WMI_NOTIFY_REQ_CMDID, vif->mid, &cmd, sizeof(cmd), 303 rc = wmi_call(wil, WMI_NOTIFY_REQ_CMDID, vif->mid, &cmd, sizeof(cmd),
280 WMI_NOTIFY_REQ_DONE_EVENTID, &reply, sizeof(reply), 20); 304 WMI_NOTIFY_REQ_DONE_EVENTID, &reply, sizeof(reply), 20);
281 if (rc) 305 if (rc)
@@ -300,14 +324,14 @@ int wil_cid_fill_sinfo(struct wil6210_vif *vif, int cid,
300 324
301 sinfo->generation = wil->sinfo_gen; 325 sinfo->generation = wil->sinfo_gen;
302 326
303 sinfo->filled = BIT(NL80211_STA_INFO_RX_BYTES) | 327 sinfo->filled = BIT_ULL(NL80211_STA_INFO_RX_BYTES) |
304 BIT(NL80211_STA_INFO_TX_BYTES) | 328 BIT_ULL(NL80211_STA_INFO_TX_BYTES) |
305 BIT(NL80211_STA_INFO_RX_PACKETS) | 329 BIT_ULL(NL80211_STA_INFO_RX_PACKETS) |
306 BIT(NL80211_STA_INFO_TX_PACKETS) | 330 BIT_ULL(NL80211_STA_INFO_TX_PACKETS) |
307 BIT(NL80211_STA_INFO_RX_BITRATE) | 331 BIT_ULL(NL80211_STA_INFO_RX_BITRATE) |
308 BIT(NL80211_STA_INFO_TX_BITRATE) | 332 BIT_ULL(NL80211_STA_INFO_TX_BITRATE) |
309 BIT(NL80211_STA_INFO_RX_DROP_MISC) | 333 BIT_ULL(NL80211_STA_INFO_RX_DROP_MISC) |
310 BIT(NL80211_STA_INFO_TX_FAILED); 334 BIT_ULL(NL80211_STA_INFO_TX_FAILED);
311 335
312 sinfo->txrate.flags = RATE_INFO_FLAGS_60G; 336 sinfo->txrate.flags = RATE_INFO_FLAGS_60G;
313 sinfo->txrate.mcs = le16_to_cpu(reply.evt.bf_mcs); 337 sinfo->txrate.mcs = le16_to_cpu(reply.evt.bf_mcs);
@@ -320,7 +344,7 @@ int wil_cid_fill_sinfo(struct wil6210_vif *vif, int cid,
320 sinfo->tx_failed = stats->tx_errors; 344 sinfo->tx_failed = stats->tx_errors;
321 345
322 if (test_bit(wil_vif_fwconnected, vif->status)) { 346 if (test_bit(wil_vif_fwconnected, vif->status)) {
323 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL); 347 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
324 if (test_bit(WMI_FW_CAPABILITY_RSSI_REPORTING, 348 if (test_bit(WMI_FW_CAPABILITY_RSSI_REPORTING,
325 wil->fw_capabilities)) 349 wil->fw_capabilities))
326 sinfo->signal = reply.evt.rssi; 350 sinfo->signal = reply.evt.rssi;
@@ -687,11 +711,12 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
687 711
688 wil_dbg_misc(wil, "scan: wdev=0x%p iftype=%d\n", wdev, wdev->iftype); 712 wil_dbg_misc(wil, "scan: wdev=0x%p iftype=%d\n", wdev, wdev->iftype);
689 713
690 /* check we are client side */ 714 /* scan is supported on client interfaces and on AP interface */
691 switch (wdev->iftype) { 715 switch (wdev->iftype) {
692 case NL80211_IFTYPE_STATION: 716 case NL80211_IFTYPE_STATION:
693 case NL80211_IFTYPE_P2P_CLIENT: 717 case NL80211_IFTYPE_P2P_CLIENT:
694 case NL80211_IFTYPE_P2P_DEVICE: 718 case NL80211_IFTYPE_P2P_DEVICE:
719 case NL80211_IFTYPE_AP:
695 break; 720 break;
696 default: 721 default:
697 return -EOPNOTSUPP; 722 return -EOPNOTSUPP;
@@ -868,6 +893,26 @@ static void wil_print_crypto(struct wil6210_priv *wil,
868 c->control_port_no_encrypt); 893 c->control_port_no_encrypt);
869} 894}
870 895
896static const char *
897wil_get_auth_type_name(enum nl80211_auth_type auth_type)
898{
899 switch (auth_type) {
900 case NL80211_AUTHTYPE_OPEN_SYSTEM:
901 return "OPEN_SYSTEM";
902 case NL80211_AUTHTYPE_SHARED_KEY:
903 return "SHARED_KEY";
904 case NL80211_AUTHTYPE_FT:
905 return "FT";
906 case NL80211_AUTHTYPE_NETWORK_EAP:
907 return "NETWORK_EAP";
908 case NL80211_AUTHTYPE_SAE:
909 return "SAE";
910 case NL80211_AUTHTYPE_AUTOMATIC:
911 return "AUTOMATIC";
912 default:
913 return "unknown";
914 }
915}
871static void wil_print_connect_params(struct wil6210_priv *wil, 916static void wil_print_connect_params(struct wil6210_priv *wil,
872 struct cfg80211_connect_params *sme) 917 struct cfg80211_connect_params *sme)
873{ 918{
@@ -881,11 +926,73 @@ static void wil_print_connect_params(struct wil6210_priv *wil,
881 if (sme->ssid) 926 if (sme->ssid)
882 print_hex_dump(KERN_INFO, " SSID: ", DUMP_PREFIX_OFFSET, 927 print_hex_dump(KERN_INFO, " SSID: ", DUMP_PREFIX_OFFSET,
883 16, 1, sme->ssid, sme->ssid_len, true); 928 16, 1, sme->ssid, sme->ssid_len, true);
929 if (sme->prev_bssid)
930 wil_info(wil, " Previous BSSID=%pM\n", sme->prev_bssid);
931 wil_info(wil, " Auth Type: %s\n",
932 wil_get_auth_type_name(sme->auth_type));
884 wil_info(wil, " Privacy: %s\n", sme->privacy ? "secure" : "open"); 933 wil_info(wil, " Privacy: %s\n", sme->privacy ? "secure" : "open");
885 wil_info(wil, " PBSS: %d\n", sme->pbss); 934 wil_info(wil, " PBSS: %d\n", sme->pbss);
886 wil_print_crypto(wil, &sme->crypto); 935 wil_print_crypto(wil, &sme->crypto);
887} 936}
888 937
938static int wil_ft_connect(struct wiphy *wiphy,
939 struct net_device *ndev,
940 struct cfg80211_connect_params *sme)
941{
942 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
943 struct wil6210_vif *vif = ndev_to_vif(ndev);
944 struct wmi_ft_auth_cmd auth_cmd;
945 int rc;
946
947 if (!test_bit(WMI_FW_CAPABILITY_FT_ROAMING, wil->fw_capabilities)) {
948 wil_err(wil, "FT: FW does not support FT roaming\n");
949 return -EOPNOTSUPP;
950 }
951
952 if (!sme->prev_bssid) {
953 wil_err(wil, "FT: prev_bssid was not set\n");
954 return -EINVAL;
955 }
956
957 if (ether_addr_equal(sme->prev_bssid, sme->bssid)) {
958 wil_err(wil, "FT: can not roam to same AP\n");
959 return -EINVAL;
960 }
961
962 if (!test_bit(wil_vif_fwconnected, vif->status)) {
963 wil_err(wil, "FT: roam while not connected\n");
964 return -EINVAL;
965 }
966
967 if (vif->privacy != sme->privacy) {
968 wil_err(wil, "FT: privacy mismatch, current (%d) roam (%d)\n",
969 vif->privacy, sme->privacy);
970 return -EINVAL;
971 }
972
973 if (sme->pbss) {
974 wil_err(wil, "FT: roam is not valid for PBSS\n");
975 return -EINVAL;
976 }
977
978 memset(&auth_cmd, 0, sizeof(auth_cmd));
979 auth_cmd.channel = sme->channel->hw_value - 1;
980 ether_addr_copy(auth_cmd.bssid, sme->bssid);
981
982 wil_info(wil, "FT: roaming\n");
983
984 set_bit(wil_vif_ft_roam, vif->status);
985 rc = wmi_send(wil, WMI_FT_AUTH_CMDID, vif->mid,
986 &auth_cmd, sizeof(auth_cmd));
987 if (rc == 0)
988 mod_timer(&vif->connect_timer,
989 jiffies + msecs_to_jiffies(5000));
990 else
991 clear_bit(wil_vif_ft_roam, vif->status);
992
993 return rc;
994}
995
889static int wil_cfg80211_connect(struct wiphy *wiphy, 996static int wil_cfg80211_connect(struct wiphy *wiphy,
890 struct net_device *ndev, 997 struct net_device *ndev,
891 struct cfg80211_connect_params *sme) 998 struct cfg80211_connect_params *sme)
@@ -898,14 +1005,23 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
898 const u8 *rsn_eid; 1005 const u8 *rsn_eid;
899 int ch; 1006 int ch;
900 int rc = 0; 1007 int rc = 0;
1008 bool is_ft_roam = false;
1009 u8 network_type;
901 enum ieee80211_bss_type bss_type = IEEE80211_BSS_TYPE_ESS; 1010 enum ieee80211_bss_type bss_type = IEEE80211_BSS_TYPE_ESS;
902 1011
903 wil_dbg_misc(wil, "connect, mid=%d\n", vif->mid); 1012 wil_dbg_misc(wil, "connect, mid=%d\n", vif->mid);
904 wil_print_connect_params(wil, sme); 1013 wil_print_connect_params(wil, sme);
905 1014
906 if (test_bit(wil_vif_fwconnecting, vif->status) || 1015 if (sme->auth_type == NL80211_AUTHTYPE_FT)
1016 is_ft_roam = true;
1017 if (sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC &&
907 test_bit(wil_vif_fwconnected, vif->status)) 1018 test_bit(wil_vif_fwconnected, vif->status))
908 return -EALREADY; 1019 is_ft_roam = true;
1020
1021 if (!is_ft_roam)
1022 if (test_bit(wil_vif_fwconnecting, vif->status) ||
1023 test_bit(wil_vif_fwconnected, vif->status))
1024 return -EALREADY;
909 1025
910 if (sme->ie_len > WMI_MAX_IE_LEN) { 1026 if (sme->ie_len > WMI_MAX_IE_LEN) {
911 wil_err(wil, "IE too large (%td bytes)\n", sme->ie_len); 1027 wil_err(wil, "IE too large (%td bytes)\n", sme->ie_len);
@@ -915,8 +1031,13 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
915 rsn_eid = sme->ie ? 1031 rsn_eid = sme->ie ?
916 cfg80211_find_ie(WLAN_EID_RSN, sme->ie, sme->ie_len) : 1032 cfg80211_find_ie(WLAN_EID_RSN, sme->ie, sme->ie_len) :
917 NULL; 1033 NULL;
918 if (sme->privacy && !rsn_eid) 1034 if (sme->privacy && !rsn_eid) {
919 wil_info(wil, "WSC connection\n"); 1035 wil_info(wil, "WSC connection\n");
1036 if (is_ft_roam) {
1037 wil_err(wil, "No WSC with FT roam\n");
1038 return -EINVAL;
1039 }
1040 }
920 1041
921 if (sme->pbss) 1042 if (sme->pbss)
922 bss_type = IEEE80211_BSS_TYPE_PBSS; 1043 bss_type = IEEE80211_BSS_TYPE_PBSS;
@@ -938,6 +1059,45 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
938 vif->privacy = sme->privacy; 1059 vif->privacy = sme->privacy;
939 vif->pbss = sme->pbss; 1060 vif->pbss = sme->pbss;
940 1061
1062 rc = wmi_set_ie(vif, WMI_FRAME_ASSOC_REQ, sme->ie_len, sme->ie);
1063 if (rc)
1064 goto out;
1065
1066 switch (bss->capability & WLAN_CAPABILITY_DMG_TYPE_MASK) {
1067 case WLAN_CAPABILITY_DMG_TYPE_AP:
1068 network_type = WMI_NETTYPE_INFRA;
1069 break;
1070 case WLAN_CAPABILITY_DMG_TYPE_PBSS:
1071 network_type = WMI_NETTYPE_P2P;
1072 break;
1073 default:
1074 wil_err(wil, "Unsupported BSS type, capability= 0x%04x\n",
1075 bss->capability);
1076 rc = -EINVAL;
1077 goto out;
1078 }
1079
1080 ch = bss->channel->hw_value;
1081 if (ch == 0) {
1082 wil_err(wil, "BSS at unknown frequency %dMhz\n",
1083 bss->channel->center_freq);
1084 rc = -EOPNOTSUPP;
1085 goto out;
1086 }
1087
1088 if (is_ft_roam) {
1089 if (network_type != WMI_NETTYPE_INFRA) {
1090 wil_err(wil, "FT: Unsupported BSS type, capability= 0x%04x\n",
1091 bss->capability);
1092 rc = -EINVAL;
1093 goto out;
1094 }
1095 rc = wil_ft_connect(wiphy, ndev, sme);
1096 if (rc == 0)
1097 vif->bss = bss;
1098 goto out;
1099 }
1100
941 if (vif->privacy) { 1101 if (vif->privacy) {
942 /* For secure assoc, remove old keys */ 1102 /* For secure assoc, remove old keys */
943 rc = wmi_del_cipher_key(vif, 0, bss->bssid, 1103 rc = wmi_del_cipher_key(vif, 0, bss->bssid,
@@ -954,28 +1114,9 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
954 } 1114 }
955 } 1115 }
956 1116
957 /* WMI_SET_APPIE_CMD. ie may contain rsn info as well as other info
958 * elements. Send it also in case it's empty, to erase previously set
959 * ies in FW.
960 */
961 rc = wmi_set_ie(vif, WMI_FRAME_ASSOC_REQ, sme->ie_len, sme->ie);
962 if (rc)
963 goto out;
964
965 /* WMI_CONNECT_CMD */ 1117 /* WMI_CONNECT_CMD */
966 memset(&conn, 0, sizeof(conn)); 1118 memset(&conn, 0, sizeof(conn));
967 switch (bss->capability & WLAN_CAPABILITY_DMG_TYPE_MASK) { 1119 conn.network_type = network_type;
968 case WLAN_CAPABILITY_DMG_TYPE_AP:
969 conn.network_type = WMI_NETTYPE_INFRA;
970 break;
971 case WLAN_CAPABILITY_DMG_TYPE_PBSS:
972 conn.network_type = WMI_NETTYPE_P2P;
973 break;
974 default:
975 wil_err(wil, "Unsupported BSS type, capability= 0x%04x\n",
976 bss->capability);
977 goto out;
978 }
979 if (vif->privacy) { 1120 if (vif->privacy) {
980 if (rsn_eid) { /* regular secure connection */ 1121 if (rsn_eid) { /* regular secure connection */
981 conn.dot11_auth_mode = WMI_AUTH11_SHARED; 1122 conn.dot11_auth_mode = WMI_AUTH11_SHARED;
@@ -995,14 +1136,6 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
995 1136
996 conn.ssid_len = min_t(u8, ssid_eid[1], 32); 1137 conn.ssid_len = min_t(u8, ssid_eid[1], 32);
997 memcpy(conn.ssid, ssid_eid+2, conn.ssid_len); 1138 memcpy(conn.ssid, ssid_eid+2, conn.ssid_len);
998
999 ch = bss->channel->hw_value;
1000 if (ch == 0) {
1001 wil_err(wil, "BSS at unknown frequency %dMhz\n",
1002 bss->channel->center_freq);
1003 rc = -EOPNOTSUPP;
1004 goto out;
1005 }
1006 conn.channel = ch - 1; 1139 conn.channel = ch - 1;
1007 1140
1008 ether_addr_copy(conn.bssid, bss->bssid); 1141 ether_addr_copy(conn.bssid, bss->bssid);
@@ -1081,55 +1214,57 @@ int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
1081 u64 *cookie) 1214 u64 *cookie)
1082{ 1215{
1083 const u8 *buf = params->buf; 1216 const u8 *buf = params->buf;
1084 size_t len = params->len, total; 1217 size_t len = params->len;
1085 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 1218 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1086 struct wil6210_vif *vif = wdev_to_vif(wil, wdev); 1219 struct wil6210_vif *vif = wdev_to_vif(wil, wdev);
1087 int rc; 1220 int rc;
1088 bool tx_status = false; 1221 bool tx_status;
1089 struct ieee80211_mgmt *mgmt_frame = (void *)buf;
1090 struct wmi_sw_tx_req_cmd *cmd;
1091 struct {
1092 struct wmi_cmd_hdr wmi;
1093 struct wmi_sw_tx_complete_event evt;
1094 } __packed evt;
1095
1096 /* Note, currently we do not support the "wait" parameter, user-space
1097 * must call remain_on_channel before mgmt_tx or listen on a channel
1098 * another way (AP/PCP or connected station)
1099 * in addition we need to check if specified "chan" argument is
1100 * different from currently "listened" channel and fail if it is.
1101 */
1102 1222
1103 wil_dbg_misc(wil, "mgmt_tx mid %d\n", vif->mid); 1223 wil_dbg_misc(wil, "mgmt_tx: channel %d offchan %d, wait %d\n",
1104 wil_hex_dump_misc("mgmt tx frame ", DUMP_PREFIX_OFFSET, 16, 1, buf, 1224 params->chan ? params->chan->hw_value : -1,
1105 len, true); 1225 params->offchan,
1226 params->wait);
1106 1227
1107 if (len < sizeof(struct ieee80211_hdr_3addr)) 1228 /* Note, currently we support the "wait" parameter only on AP mode.
1108 return -EINVAL; 1229 * In other modes, user-space must call remain_on_channel before
1230 * mgmt_tx or listen on a channel other than active one.
1231 */
1109 1232
1110 total = sizeof(*cmd) + len; 1233 if (params->chan && params->chan->hw_value == 0) {
1111 if (total < len) 1234 wil_err(wil, "invalid channel\n");
1112 return -EINVAL; 1235 return -EINVAL;
1236 }
1113 1237
1114 cmd = kmalloc(total, GFP_KERNEL); 1238 if (wdev->iftype != NL80211_IFTYPE_AP) {
1115 if (!cmd) { 1239 wil_dbg_misc(wil,
1116 rc = -ENOMEM; 1240 "send WMI_SW_TX_REQ_CMDID on non-AP interfaces\n");
1241 rc = wmi_mgmt_tx(vif, buf, len);
1117 goto out; 1242 goto out;
1118 } 1243 }
1119 1244
1120 memcpy(cmd->dst_mac, mgmt_frame->da, WMI_MAC_LEN); 1245 if (!params->chan || params->chan->hw_value == vif->channel) {
1121 cmd->len = cpu_to_le16(len); 1246 wil_dbg_misc(wil,
1122 memcpy(cmd->payload, buf, len); 1247 "send WMI_SW_TX_REQ_CMDID for on-channel\n");
1248 rc = wmi_mgmt_tx(vif, buf, len);
1249 goto out;
1250 }
1123 1251
1124 rc = wmi_call(wil, WMI_SW_TX_REQ_CMDID, vif->mid, cmd, total, 1252 if (params->offchan == 0) {
1125 WMI_SW_TX_COMPLETE_EVENTID, &evt, sizeof(evt), 2000); 1253 wil_err(wil,
1126 if (rc == 0) 1254 "invalid channel params: current %d requested %d, off-channel not allowed\n",
1127 tx_status = !evt.evt.status; 1255 vif->channel, params->chan->hw_value);
1256 return -EBUSY;
1257 }
1128 1258
1129 kfree(cmd); 1259 /* use the wmi_mgmt_tx_ext only on AP mode and off-channel */
1130 out: 1260 rc = wmi_mgmt_tx_ext(vif, buf, len, params->chan->hw_value,
1261 params->wait);
1262
1263out:
1264 tx_status = (rc == 0);
1131 cfg80211_mgmt_tx_status(wdev, cookie ? *cookie : 0, buf, len, 1265 cfg80211_mgmt_tx_status(wdev, cookie ? *cookie : 0, buf, len,
1132 tx_status, GFP_KERNEL); 1266 tx_status, GFP_KERNEL);
1267
1133 return rc; 1268 return rc;
1134} 1269}
1135 1270
@@ -1196,9 +1331,9 @@ wil_find_sta_by_key_usage(struct wil6210_priv *wil, u8 mid,
1196 return &wil->sta[cid]; 1331 return &wil->sta[cid];
1197} 1332}
1198 1333
1199static void wil_set_crypto_rx(u8 key_index, enum wmi_key_usage key_usage, 1334void wil_set_crypto_rx(u8 key_index, enum wmi_key_usage key_usage,
1200 struct wil_sta_info *cs, 1335 struct wil_sta_info *cs,
1201 struct key_params *params) 1336 struct key_params *params)
1202{ 1337{
1203 struct wil_tid_crypto_rx_single *cc; 1338 struct wil_tid_crypto_rx_single *cc;
1204 int tid; 1339 int tid;
@@ -1281,13 +1416,19 @@ static int wil_cfg80211_add_key(struct wiphy *wiphy,
1281 params->seq_len, params->seq); 1416 params->seq_len, params->seq);
1282 1417
1283 if (IS_ERR(cs)) { 1418 if (IS_ERR(cs)) {
1284 wil_err(wil, "Not connected, %pM %s[%d] PN %*phN\n", 1419 /* in FT, sta info may not be available as add_key may be
1285 mac_addr, key_usage_str[key_usage], key_index, 1420 * sent by host before FW sends WMI_CONNECT_EVENT
1286 params->seq_len, params->seq); 1421 */
1287 return -EINVAL; 1422 if (!test_bit(wil_vif_ft_roam, vif->status)) {
1423 wil_err(wil, "Not connected, %pM %s[%d] PN %*phN\n",
1424 mac_addr, key_usage_str[key_usage], key_index,
1425 params->seq_len, params->seq);
1426 return -EINVAL;
1427 }
1288 } 1428 }
1289 1429
1290 wil_del_rx_key(key_index, key_usage, cs); 1430 if (!IS_ERR(cs))
1431 wil_del_rx_key(key_index, key_usage, cs);
1291 1432
1292 if (params->seq && params->seq_len != IEEE80211_GCMP_PN_LEN) { 1433 if (params->seq && params->seq_len != IEEE80211_GCMP_PN_LEN) {
1293 wil_err(wil, 1434 wil_err(wil,
@@ -1300,7 +1441,10 @@ static int wil_cfg80211_add_key(struct wiphy *wiphy,
1300 1441
1301 rc = wmi_add_cipher_key(vif, key_index, mac_addr, params->key_len, 1442 rc = wmi_add_cipher_key(vif, key_index, mac_addr, params->key_len,
1302 params->key, key_usage); 1443 params->key, key_usage);
1303 if (!rc) 1444 if (!rc && !IS_ERR(cs))
1445 /* in FT set crypto will take place upon receiving
1446 * WMI_RING_EN_EVENTID event
1447 */
1304 wil_set_crypto_rx(key_index, key_usage, cs, params); 1448 wil_set_crypto_rx(key_index, key_usage, cs, params);
1305 1449
1306 return rc; 1450 return rc;
@@ -1463,21 +1607,36 @@ static void wil_print_bcon_data(struct cfg80211_beacon_data *b)
1463} 1607}
1464 1608
1465/* internal functions for device reset and starting AP */ 1609/* internal functions for device reset and starting AP */
1466static int _wil_cfg80211_set_ies(struct wil6210_vif *vif, 1610static u8 *
1467 struct cfg80211_beacon_data *bcon) 1611_wil_cfg80211_get_proberesp_ies(const u8 *proberesp, u16 proberesp_len,
1612 u16 *ies_len)
1468{ 1613{
1469 int rc; 1614 u8 *ies = NULL;
1470 u16 len = 0, proberesp_len = 0;
1471 u8 *ies = NULL, *proberesp = NULL;
1472 1615
1473 if (bcon->probe_resp) { 1616 if (proberesp) {
1474 struct ieee80211_mgmt *f = 1617 struct ieee80211_mgmt *f =
1475 (struct ieee80211_mgmt *)bcon->probe_resp; 1618 (struct ieee80211_mgmt *)proberesp;
1476 size_t hlen = offsetof(struct ieee80211_mgmt, 1619 size_t hlen = offsetof(struct ieee80211_mgmt,
1477 u.probe_resp.variable); 1620 u.probe_resp.variable);
1478 proberesp = f->u.probe_resp.variable; 1621
1479 proberesp_len = bcon->probe_resp_len - hlen; 1622 ies = f->u.probe_resp.variable;
1623 if (ies_len)
1624 *ies_len = proberesp_len - hlen;
1480 } 1625 }
1626
1627 return ies;
1628}
1629
1630static int _wil_cfg80211_set_ies(struct wil6210_vif *vif,
1631 struct cfg80211_beacon_data *bcon)
1632{
1633 int rc;
1634 u16 len = 0, proberesp_len = 0;
1635 u8 *ies = NULL, *proberesp;
1636
1637 proberesp = _wil_cfg80211_get_proberesp_ies(bcon->probe_resp,
1638 bcon->probe_resp_len,
1639 &proberesp_len);
1481 rc = _wil_cfg80211_merge_extra_ies(proberesp, 1640 rc = _wil_cfg80211_merge_extra_ies(proberesp,
1482 proberesp_len, 1641 proberesp_len,
1483 bcon->proberesp_ies, 1642 bcon->proberesp_ies,
@@ -1521,6 +1680,9 @@ static int _wil_cfg80211_start_ap(struct wiphy *wiphy,
1521 struct wireless_dev *wdev = ndev->ieee80211_ptr; 1680 struct wireless_dev *wdev = ndev->ieee80211_ptr;
1522 u8 wmi_nettype = wil_iftype_nl2wmi(wdev->iftype); 1681 u8 wmi_nettype = wil_iftype_nl2wmi(wdev->iftype);
1523 u8 is_go = (wdev->iftype == NL80211_IFTYPE_P2P_GO); 1682 u8 is_go = (wdev->iftype == NL80211_IFTYPE_P2P_GO);
1683 u16 proberesp_len = 0;
1684 u8 *proberesp;
1685 bool ft = false;
1524 1686
1525 if (pbss) 1687 if (pbss)
1526 wmi_nettype = WMI_NETTYPE_P2P; 1688 wmi_nettype = WMI_NETTYPE_P2P;
@@ -1533,6 +1695,25 @@ static int _wil_cfg80211_start_ap(struct wiphy *wiphy,
1533 1695
1534 wil_set_recovery_state(wil, fw_recovery_idle); 1696 wil_set_recovery_state(wil, fw_recovery_idle);
1535 1697
1698 proberesp = _wil_cfg80211_get_proberesp_ies(bcon->probe_resp,
1699 bcon->probe_resp_len,
1700 &proberesp_len);
1701 /* check that the probe response IEs has a MDE */
1702 if ((proberesp && proberesp_len > 0 &&
1703 cfg80211_find_ie(WLAN_EID_MOBILITY_DOMAIN,
1704 proberesp,
1705 proberesp_len)))
1706 ft = true;
1707
1708 if (ft) {
1709 if (!test_bit(WMI_FW_CAPABILITY_FT_ROAMING,
1710 wil->fw_capabilities)) {
1711 wil_err(wil, "FW does not support FT roaming\n");
1712 return -ENOTSUPP;
1713 }
1714 set_bit(wil_vif_ft_roam, vif->status);
1715 }
1716
1536 mutex_lock(&wil->mutex); 1717 mutex_lock(&wil->mutex);
1537 1718
1538 if (!wil_has_other_active_ifaces(wil, ndev, true, false)) { 1719 if (!wil_has_other_active_ifaces(wil, ndev, true, false)) {
@@ -1694,6 +1875,7 @@ static int wil_cfg80211_stop_ap(struct wiphy *wiphy,
1694 mutex_lock(&wil->mutex); 1875 mutex_lock(&wil->mutex);
1695 1876
1696 wmi_pcp_stop(vif); 1877 wmi_pcp_stop(vif);
1878 clear_bit(wil_vif_ft_roam, vif->status);
1697 1879
1698 if (last) 1880 if (last)
1699 __wil_down(wil); 1881 __wil_down(wil);
@@ -1713,8 +1895,9 @@ static int wil_cfg80211_add_station(struct wiphy *wiphy,
1713 struct wil6210_vif *vif = ndev_to_vif(dev); 1895 struct wil6210_vif *vif = ndev_to_vif(dev);
1714 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 1896 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1715 1897
1716 wil_dbg_misc(wil, "add station %pM aid %d mid %d\n", 1898 wil_dbg_misc(wil, "add station %pM aid %d mid %d mask 0x%x set 0x%x\n",
1717 mac, params->aid, vif->mid); 1899 mac, params->aid, vif->mid,
1900 params->sta_flags_mask, params->sta_flags_set);
1718 1901
1719 if (!disable_ap_sme) { 1902 if (!disable_ap_sme) {
1720 wil_err(wil, "not supported with AP SME enabled\n"); 1903 wil_err(wil, "not supported with AP SME enabled\n");
@@ -1755,7 +1938,7 @@ static int wil_cfg80211_change_station(struct wiphy *wiphy,
1755 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 1938 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1756 int authorize; 1939 int authorize;
1757 int cid, i; 1940 int cid, i;
1758 struct vring_tx_data *txdata = NULL; 1941 struct wil_ring_tx_data *txdata = NULL;
1759 1942
1760 wil_dbg_misc(wil, "change station %pM mask 0x%x set 0x%x mid %d\n", 1943 wil_dbg_misc(wil, "change station %pM mask 0x%x set 0x%x mid %d\n",
1761 mac, params->sta_flags_mask, params->sta_flags_set, 1944 mac, params->sta_flags_mask, params->sta_flags_set,
@@ -1775,20 +1958,20 @@ static int wil_cfg80211_change_station(struct wiphy *wiphy,
1775 return -ENOLINK; 1958 return -ENOLINK;
1776 } 1959 }
1777 1960
1778 for (i = 0; i < ARRAY_SIZE(wil->vring2cid_tid); i++) 1961 for (i = 0; i < ARRAY_SIZE(wil->ring2cid_tid); i++)
1779 if (wil->vring2cid_tid[i][0] == cid) { 1962 if (wil->ring2cid_tid[i][0] == cid) {
1780 txdata = &wil->vring_tx_data[i]; 1963 txdata = &wil->ring_tx_data[i];
1781 break; 1964 break;
1782 } 1965 }
1783 1966
1784 if (!txdata) { 1967 if (!txdata) {
1785 wil_err(wil, "vring data not found\n"); 1968 wil_err(wil, "ring data not found\n");
1786 return -ENOLINK; 1969 return -ENOLINK;
1787 } 1970 }
1788 1971
1789 authorize = params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED); 1972 authorize = params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED);
1790 txdata->dot1x_open = authorize ? 1 : 0; 1973 txdata->dot1x_open = authorize ? 1 : 0;
1791 wil_dbg_misc(wil, "cid %d vring %d authorize %d\n", cid, i, 1974 wil_dbg_misc(wil, "cid %d ring %d authorize %d\n", cid, i,
1792 txdata->dot1x_open); 1975 txdata->dot1x_open);
1793 1976
1794 return 0; 1977 return 0;
@@ -2035,6 +2218,54 @@ wil_cfg80211_sched_scan_stop(struct wiphy *wiphy, struct net_device *dev,
2035 return 0; 2218 return 0;
2036} 2219}
2037 2220
2221static int
2222wil_cfg80211_update_ft_ies(struct wiphy *wiphy, struct net_device *dev,
2223 struct cfg80211_update_ft_ies_params *ftie)
2224{
2225 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
2226 struct wil6210_vif *vif = ndev_to_vif(dev);
2227 struct cfg80211_bss *bss;
2228 struct wmi_ft_reassoc_cmd reassoc;
2229 int rc = 0;
2230
2231 wil_dbg_misc(wil, "update ft ies, mid=%d\n", vif->mid);
2232 wil_hex_dump_misc("FT IE ", DUMP_PREFIX_OFFSET, 16, 1,
2233 ftie->ie, ftie->ie_len, true);
2234
2235 if (!test_bit(WMI_FW_CAPABILITY_FT_ROAMING, wil->fw_capabilities)) {
2236 wil_err(wil, "FW does not support FT roaming\n");
2237 return -EOPNOTSUPP;
2238 }
2239
2240 rc = wmi_update_ft_ies(vif, ftie->ie_len, ftie->ie);
2241 if (rc)
2242 return rc;
2243
2244 if (!test_bit(wil_vif_ft_roam, vif->status))
2245 /* vif is not roaming */
2246 return 0;
2247
2248 /* wil_vif_ft_roam is set. wil_cfg80211_update_ft_ies is used as
2249 * a trigger for reassoc
2250 */
2251
2252 bss = vif->bss;
2253 if (!bss) {
2254 wil_err(wil, "FT: bss is NULL\n");
2255 return -EINVAL;
2256 }
2257
2258 memset(&reassoc, 0, sizeof(reassoc));
2259 ether_addr_copy(reassoc.bssid, bss->bssid);
2260
2261 rc = wmi_send(wil, WMI_FT_REASSOC_CMDID, vif->mid,
2262 &reassoc, sizeof(reassoc));
2263 if (rc)
2264 wil_err(wil, "FT: reassoc failed (%d)\n", rc);
2265
2266 return rc;
2267}
2268
2038static const struct cfg80211_ops wil_cfg80211_ops = { 2269static const struct cfg80211_ops wil_cfg80211_ops = {
2039 .add_virtual_intf = wil_cfg80211_add_iface, 2270 .add_virtual_intf = wil_cfg80211_add_iface,
2040 .del_virtual_intf = wil_cfg80211_del_iface, 2271 .del_virtual_intf = wil_cfg80211_del_iface,
@@ -2070,6 +2301,7 @@ static const struct cfg80211_ops wil_cfg80211_ops = {
2070 .resume = wil_cfg80211_resume, 2301 .resume = wil_cfg80211_resume,
2071 .sched_scan_start = wil_cfg80211_sched_scan_start, 2302 .sched_scan_start = wil_cfg80211_sched_scan_start,
2072 .sched_scan_stop = wil_cfg80211_sched_scan_stop, 2303 .sched_scan_stop = wil_cfg80211_sched_scan_stop,
2304 .update_ft_ies = wil_cfg80211_update_ft_ies,
2073}; 2305};
2074 2306
2075static void wil_wiphy_init(struct wiphy *wiphy) 2307static void wil_wiphy_init(struct wiphy *wiphy)
@@ -2277,7 +2509,9 @@ static int wil_rf_sector_get_cfg(struct wiphy *wiphy,
2277 struct { 2509 struct {
2278 struct wmi_cmd_hdr wmi; 2510 struct wmi_cmd_hdr wmi;
2279 struct wmi_get_rf_sector_params_done_event evt; 2511 struct wmi_get_rf_sector_params_done_event evt;
2280 } __packed reply; 2512 } __packed reply = {
2513 .evt = {.status = WMI_RF_SECTOR_STATUS_NOT_SUPPORTED_ERROR},
2514 };
2281 struct sk_buff *msg; 2515 struct sk_buff *msg;
2282 struct nlattr *nl_cfgs, *nl_cfg; 2516 struct nlattr *nl_cfgs, *nl_cfg;
2283 u32 i; 2517 u32 i;
@@ -2323,7 +2557,6 @@ static int wil_rf_sector_get_cfg(struct wiphy *wiphy,
2323 cmd.sector_idx = cpu_to_le16(sector_index); 2557 cmd.sector_idx = cpu_to_le16(sector_index);
2324 cmd.sector_type = sector_type; 2558 cmd.sector_type = sector_type;
2325 cmd.rf_modules_vec = rf_modules_vec & 0xFF; 2559 cmd.rf_modules_vec = rf_modules_vec & 0xFF;
2326 memset(&reply, 0, sizeof(reply));
2327 rc = wmi_call(wil, WMI_GET_RF_SECTOR_PARAMS_CMDID, vif->mid, 2560 rc = wmi_call(wil, WMI_GET_RF_SECTOR_PARAMS_CMDID, vif->mid,
2328 &cmd, sizeof(cmd), WMI_GET_RF_SECTOR_PARAMS_DONE_EVENTID, 2561 &cmd, sizeof(cmd), WMI_GET_RF_SECTOR_PARAMS_DONE_EVENTID,
2329 &reply, sizeof(reply), 2562 &reply, sizeof(reply),
@@ -2398,7 +2631,9 @@ static int wil_rf_sector_set_cfg(struct wiphy *wiphy,
2398 struct { 2631 struct {
2399 struct wmi_cmd_hdr wmi; 2632 struct wmi_cmd_hdr wmi;
2400 struct wmi_set_rf_sector_params_done_event evt; 2633 struct wmi_set_rf_sector_params_done_event evt;
2401 } __packed reply; 2634 } __packed reply = {
2635 .evt = {.status = WMI_RF_SECTOR_STATUS_NOT_SUPPORTED_ERROR},
2636 };
2402 struct nlattr *nl_cfg; 2637 struct nlattr *nl_cfg;
2403 struct wmi_rf_sector_info *si; 2638 struct wmi_rf_sector_info *si;
2404 2639
@@ -2481,7 +2716,6 @@ static int wil_rf_sector_set_cfg(struct wiphy *wiphy,
2481 } 2716 }
2482 2717
2483 cmd.rf_modules_vec = rf_modules_vec & 0xFF; 2718 cmd.rf_modules_vec = rf_modules_vec & 0xFF;
2484 memset(&reply, 0, sizeof(reply));
2485 rc = wmi_call(wil, WMI_SET_RF_SECTOR_PARAMS_CMDID, vif->mid, 2719 rc = wmi_call(wil, WMI_SET_RF_SECTOR_PARAMS_CMDID, vif->mid,
2486 &cmd, sizeof(cmd), WMI_SET_RF_SECTOR_PARAMS_DONE_EVENTID, 2720 &cmd, sizeof(cmd), WMI_SET_RF_SECTOR_PARAMS_DONE_EVENTID,
2487 &reply, sizeof(reply), 2721 &reply, sizeof(reply),
@@ -2505,7 +2739,9 @@ static int wil_rf_sector_get_selected(struct wiphy *wiphy,
2505 struct { 2739 struct {
2506 struct wmi_cmd_hdr wmi; 2740 struct wmi_cmd_hdr wmi;
2507 struct wmi_get_selected_rf_sector_index_done_event evt; 2741 struct wmi_get_selected_rf_sector_index_done_event evt;
2508 } __packed reply; 2742 } __packed reply = {
2743 .evt = {.status = WMI_RF_SECTOR_STATUS_NOT_SUPPORTED_ERROR},
2744 };
2509 struct sk_buff *msg; 2745 struct sk_buff *msg;
2510 2746
2511 if (!test_bit(WMI_FW_CAPABILITY_RF_SECTORS, wil->fw_capabilities)) 2747 if (!test_bit(WMI_FW_CAPABILITY_RF_SECTORS, wil->fw_capabilities))
@@ -2545,7 +2781,6 @@ static int wil_rf_sector_get_selected(struct wiphy *wiphy,
2545 memset(&cmd, 0, sizeof(cmd)); 2781 memset(&cmd, 0, sizeof(cmd));
2546 cmd.cid = (u8)cid; 2782 cmd.cid = (u8)cid;
2547 cmd.sector_type = sector_type; 2783 cmd.sector_type = sector_type;
2548 memset(&reply, 0, sizeof(reply));
2549 rc = wmi_call(wil, WMI_GET_SELECTED_RF_SECTOR_INDEX_CMDID, vif->mid, 2784 rc = wmi_call(wil, WMI_GET_SELECTED_RF_SECTOR_INDEX_CMDID, vif->mid,
2550 &cmd, sizeof(cmd), 2785 &cmd, sizeof(cmd),
2551 WMI_GET_SELECTED_RF_SECTOR_INDEX_DONE_EVENTID, 2786 WMI_GET_SELECTED_RF_SECTOR_INDEX_DONE_EVENTID,
@@ -2586,14 +2821,15 @@ static int wil_rf_sector_wmi_set_selected(struct wil6210_priv *wil,
2586 struct { 2821 struct {
2587 struct wmi_cmd_hdr wmi; 2822 struct wmi_cmd_hdr wmi;
2588 struct wmi_set_selected_rf_sector_index_done_event evt; 2823 struct wmi_set_selected_rf_sector_index_done_event evt;
2589 } __packed reply; 2824 } __packed reply = {
2825 .evt = {.status = WMI_RF_SECTOR_STATUS_NOT_SUPPORTED_ERROR},
2826 };
2590 int rc; 2827 int rc;
2591 2828
2592 memset(&cmd, 0, sizeof(cmd)); 2829 memset(&cmd, 0, sizeof(cmd));
2593 cmd.sector_idx = cpu_to_le16(sector_index); 2830 cmd.sector_idx = cpu_to_le16(sector_index);
2594 cmd.sector_type = sector_type; 2831 cmd.sector_type = sector_type;
2595 cmd.cid = (u8)cid; 2832 cmd.cid = (u8)cid;
2596 memset(&reply, 0, sizeof(reply));
2597 rc = wmi_call(wil, WMI_SET_SELECTED_RF_SECTOR_INDEX_CMDID, mid, 2833 rc = wmi_call(wil, WMI_SET_SELECTED_RF_SECTOR_INDEX_CMDID, mid,
2598 &cmd, sizeof(cmd), 2834 &cmd, sizeof(cmd),
2599 WMI_SET_SELECTED_RF_SECTOR_INDEX_DONE_EVENTID, 2835 WMI_SET_SELECTED_RF_SECTOR_INDEX_DONE_EVENTID,