]> git.ipfire.org Git - thirdparty/hostap.git/blobdiff - src/drivers/driver_nl80211.c
HT: Remove SMPS in AP mode
[thirdparty/hostap.git] / src / drivers / driver_nl80211.c
index 0809e4d9a135ee1fbfaf07b51000636e6c077738..6c26e8ba893ae4bd621b1f1a3fddec78dee2bd9e 100644 (file)
@@ -165,7 +165,8 @@ wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv,
                                   const char *driver_params);
 static int nl80211_send_frame_cmd(struct i802_bss *bss,
                                  unsigned int freq, unsigned int wait,
-                                 const u8 *buf, size_t buf_len, u64 *cookie,
+                                 const u8 *buf, size_t buf_len,
+                                 int save_cookie,
                                  int no_cck, int no_ack, int offchanok,
                                  const u16 *csa_offs, size_t csa_offs_len);
 static int wpa_driver_nl80211_probe_req_report(struct i802_bss *bss,
@@ -2107,7 +2108,7 @@ static int nl80211_register_frame(struct i802_bss *bss,
        wpa_printf(MSG_DEBUG, "nl80211: Register frame type=0x%x (%s) nl_handle=%p match=%s",
                   type, fc2str(type), nl_handle, buf);
 
-       if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_REGISTER_ACTION)) ||
+       if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_REGISTER_FRAME)) ||
            nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE, type) ||
            nla_put(msg, NL80211_ATTR_FRAME_MATCH, match_len, match)) {
                nlmsg_free(msg);
@@ -3010,11 +3011,8 @@ static int nl80211_set_pmk(struct wpa_driver_nl80211_data *drv,
 }
 
 
-static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss,
-                                     enum wpa_alg alg, const u8 *addr,
-                                     int key_idx, int set_tx,
-                                     const u8 *seq, size_t seq_len,
-                                     const u8 *key, size_t key_len)
+static int wpa_driver_nl80211_set_key(struct i802_bss *bss,
+                                     struct wpa_driver_set_key_params *params)
 {
        struct wpa_driver_nl80211_data *drv = bss->drv;
        int ifindex;
@@ -3022,6 +3020,16 @@ static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss,
        struct nl_msg *key_msg;
        int ret;
        int tdls = 0;
+       const char *ifname = params->ifname;
+       enum wpa_alg alg = params->alg;
+       const u8 *addr = params->addr;
+       int key_idx = params->key_idx;
+       int set_tx = params->set_tx;
+       const u8 *seq = params->seq;
+       size_t seq_len = params->seq_len;
+       const u8 *key = params->key;
+       size_t key_len = params->key_len;
+       int vlan_id = params->vlan_id;
 
        /* Ignore for P2P Device */
        if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE)
@@ -3111,6 +3119,12 @@ static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss,
        nlmsg_free(key_msg);
        key_msg = NULL;
 
+       if (vlan_id && (drv->capa.flags & WPA_DRIVER_FLAGS_VLAN_OFFLOAD)) {
+               wpa_printf(MSG_DEBUG, "nl80211: VLAN ID %d", vlan_id);
+               if (nla_put_u16(msg, NL80211_ATTR_VLAN_ID, vlan_id))
+                       goto fail;
+       }
+
        ret = send_and_recv_msgs(drv, msg, NULL, key ? (void *) -1 : NULL);
        if ((ret == -ENOENT || ret == -ENOLINK) && alg == WPA_ALG_NONE)
                ret = 0;
@@ -3168,6 +3182,13 @@ static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss,
        nlmsg_free(key_msg);
        key_msg = NULL;
 
+       if (vlan_id && (drv->capa.flags & WPA_DRIVER_FLAGS_VLAN_OFFLOAD)) {
+               wpa_printf(MSG_DEBUG, "nl80211: set_key default - VLAN ID %d",
+                          vlan_id);
+               if (nla_put_u16(msg, NL80211_ATTR_VLAN_ID, vlan_id))
+                       goto fail;
+       }
+
        ret = send_and_recv_msgs(drv, msg, NULL, NULL);
        if (ret == -ENOENT)
                ret = 0;
@@ -3457,6 +3478,7 @@ static int wpa_driver_nl80211_authenticate(
        enum nl80211_iftype nlmode;
        int count = 0;
        int is_retry;
+       struct wpa_driver_set_key_params p;
 
        nl80211_unmask_11b_rates(bss);
 
@@ -3485,14 +3507,17 @@ retry:
        if (!msg)
                goto fail;
 
+       os_memset(&p, 0, sizeof(p));
+       p.ifname = bss->ifname;
+       p.alg = WPA_ALG_WEP;
        for (i = 0; i < 4; i++) {
                if (!params->wep_key[i])
                        continue;
-               wpa_driver_nl80211_set_key(bss->ifname, bss, WPA_ALG_WEP,
-                                          NULL, i,
-                                          i == params->wep_tx_keyidx, NULL, 0,
-                                          params->wep_key[i],
-                                          params->wep_key_len[i]);
+               p.key_idx = i;
+               p.set_tx = i == params->wep_tx_keyidx;
+               p.key = params->wep_key[i];
+               p.key_len = params->wep_key_len[i];
+               wpa_driver_nl80211_set_key(bss, &p);
                if (params->wep_tx_keyidx != i)
                        continue;
                if (nl_add_key(msg, WPA_ALG_WEP, i, 1, NULL, 0,
@@ -3654,80 +3679,27 @@ int wpa_driver_nl80211_authenticate_retry(struct wpa_driver_nl80211_data *drv)
 }
 
 
-static int wpa_driver_nl80211_send_frame(struct i802_bss *bss,
-                                        const void *data, size_t len,
-                                        int encrypt, int noack,
-                                        unsigned int freq, int no_cck,
-                                        int offchanok, unsigned int wait_time,
-                                        const u16 *csa_offs,
-                                        size_t csa_offs_len)
-{
-       struct wpa_driver_nl80211_data *drv = bss->drv;
-       u64 cookie;
-       int res;
-
-       if (freq == 0 && drv->nlmode == NL80211_IFTYPE_ADHOC) {
-               freq = nl80211_get_assoc_freq(drv);
-               wpa_printf(MSG_DEBUG,
-                          "nl80211: send_frame - Use assoc_freq=%u for IBSS",
-                          freq);
-       }
-       if (freq == 0) {
-               wpa_printf(MSG_DEBUG, "nl80211: send_frame - Use bss->freq=%u",
-                          bss->freq);
-               freq = bss->freq;
-       }
-
-       if (drv->use_monitor) {
-               wpa_printf(MSG_DEBUG, "nl80211: send_frame(freq=%u bss->freq=%u) -> send_monitor",
-                          freq, bss->freq);
-               return nl80211_send_monitor(drv, data, len, encrypt, noack);
-       }
-
-       wpa_printf(MSG_DEBUG, "nl80211: send_frame -> send_frame_cmd");
-       res = nl80211_send_frame_cmd(bss, freq, wait_time, data, len,
-                                    &cookie, no_cck, noack, offchanok,
-                                    csa_offs, csa_offs_len);
-       if (res == 0 && !noack) {
-               const struct ieee80211_mgmt *mgmt;
-               u16 fc;
-
-               mgmt = (const struct ieee80211_mgmt *) data;
-               fc = le_to_host16(mgmt->frame_control);
-               if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
-                   WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACTION) {
-                       wpa_printf(MSG_MSGDUMP,
-                                  "nl80211: Update send_action_cookie from 0x%llx to 0x%llx",
-                                  (long long unsigned int)
-                                  drv->send_action_cookie,
-                                  (long long unsigned int) cookie);
-                       drv->send_action_cookie = cookie;
-               }
-       }
-
-       return res;
-}
-
-
 static int wpa_driver_nl80211_send_mlme(struct i802_bss *bss, const u8 *data,
                                        size_t data_len, int noack,
                                        unsigned int freq, int no_cck,
                                        int offchanok,
                                        unsigned int wait_time,
                                        const u16 *csa_offs,
-                                       size_t csa_offs_len)
+                                       size_t csa_offs_len, int no_encrypt)
 {
        struct wpa_driver_nl80211_data *drv = bss->drv;
        struct ieee80211_mgmt *mgmt;
-       int encrypt = 1;
+       int encrypt = !no_encrypt;
        u16 fc;
+       int use_cookie = 1;
+       int res;
 
        mgmt = (struct ieee80211_mgmt *) data;
        fc = le_to_host16(mgmt->frame_control);
        wpa_printf(MSG_DEBUG, "nl80211: send_mlme - da= " MACSTR
-                  " noack=%d freq=%u no_cck=%d offchanok=%d wait_time=%u fc=0x%x (%s) nlmode=%d",
+                  " noack=%d freq=%u no_cck=%d offchanok=%d wait_time=%u no_encrypt=%d fc=0x%x (%s) nlmode=%d",
                   MAC2STR(mgmt->da), noack, freq, no_cck, offchanok, wait_time,
-                  fc, fc2str(fc), drv->nlmode);
+                  no_encrypt, fc, fc2str(fc), drv->nlmode);
 
        if ((is_sta_interface(drv->nlmode) ||
             drv->nlmode == NL80211_IFTYPE_P2P_DEVICE) &&
@@ -3743,9 +3715,11 @@ static int wpa_driver_nl80211_send_mlme(struct i802_bss *bss, const u8 *data,
                                   drv->last_mgmt_freq);
                        freq = drv->last_mgmt_freq;
                }
-               return nl80211_send_frame_cmd(bss, freq, 0,
-                                             data, data_len, NULL, 1, noack,
-                                             1, csa_offs, csa_offs_len);
+               wait_time = 0;
+               use_cookie = 0;
+               no_cck = 1;
+               offchanok = 1;
+               goto send_frame_cmd;
        }
 
        if (drv->device_ap_sme && is_ap_interface(drv->nlmode)) {
@@ -3754,13 +3728,9 @@ static int wpa_driver_nl80211_send_mlme(struct i802_bss *bss, const u8 *data,
                                   bss->freq);
                        freq = bss->freq;
                }
-               return nl80211_send_frame_cmd(bss, freq,
-                                             (int) freq == bss->freq ? 0 :
-                                             wait_time,
-                                             data, data_len,
-                                             &drv->send_action_cookie,
-                                             no_cck, noack, offchanok,
-                                             csa_offs, csa_offs_len);
+               if ((int) freq == bss->freq)
+                       wait_time = 0;
+               goto send_frame_cmd;
        }
 
        if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
@@ -3777,11 +3747,60 @@ static int wpa_driver_nl80211_send_mlme(struct i802_bss *bss, const u8 *data,
                        encrypt = 0;
        }
 
-       wpa_printf(MSG_DEBUG, "nl80211: send_mlme -> send_frame");
-       return wpa_driver_nl80211_send_frame(bss, data, data_len, encrypt,
-                                            noack, freq, no_cck, offchanok,
-                                            wait_time, csa_offs,
-                                            csa_offs_len);
+       if (freq == 0 && drv->nlmode == NL80211_IFTYPE_STATION &&
+           (drv->capa.flags & WPA_DRIVER_FLAGS_SAE) &&
+           !(drv->capa.flags & WPA_DRIVER_FLAGS_SME) &&
+           WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
+           WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_AUTH) {
+               freq = nl80211_get_assoc_freq(drv);
+               wpa_printf(MSG_DEBUG,
+                          "nl80211: send_mlme - Use assoc_freq=%u for external auth",
+                          freq);
+       }
+
+       if (freq == 0 && drv->nlmode == NL80211_IFTYPE_ADHOC) {
+               freq = nl80211_get_assoc_freq(drv);
+               wpa_printf(MSG_DEBUG,
+                          "nl80211: send_mlme - Use assoc_freq=%u for IBSS",
+                          freq);
+       }
+       if (freq == 0) {
+               wpa_printf(MSG_DEBUG, "nl80211: send_mlme - Use bss->freq=%u",
+                          bss->freq);
+               freq = bss->freq;
+       }
+
+       if (drv->use_monitor) {
+               wpa_printf(MSG_DEBUG,
+                          "nl80211: send_frame(freq=%u bss->freq=%u) -> send_monitor",
+                          freq, bss->freq);
+               return nl80211_send_monitor(drv, data, data_len, encrypt,
+                                           noack);
+       }
+
+       if (noack || WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT ||
+           WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_ACTION)
+               use_cookie = 0;
+send_frame_cmd:
+#ifdef CONFIG_TESTING_OPTIONS
+       if (no_encrypt && !encrypt && !drv->use_monitor) {
+               wpa_printf(MSG_DEBUG,
+                          "nl80211: Request to send an unencrypted frame - use a monitor interface for this");
+               if (nl80211_create_monitor_interface(drv) < 0)
+                       return -1;
+               res = nl80211_send_monitor(drv, data, data_len, encrypt,
+                                          noack);
+               nl80211_remove_monitor_interface(drv);
+               return res;
+       }
+#endif /* CONFIG_TESTING_OPTIONS */
+
+       wpa_printf(MSG_DEBUG, "nl80211: send_mlme -> send_frame_cmd");
+       res = nl80211_send_frame_cmd(bss, freq, wait_time, data, data_len,
+                                    use_cookie, no_cck, noack, offchanok,
+                                    csa_offs, csa_offs_len);
+
+       return res;
 }
 
 
@@ -4083,7 +4102,6 @@ static int wpa_driver_nl80211_set_ap(void *priv,
        int ret = -ENOBUFS;
        int beacon_set;
        int num_suites;
-       int smps_mode;
        u32 suites[10], suite;
        u32 ver;
 #ifdef CONFIG_MESH
@@ -4216,27 +4234,6 @@ static int wpa_driver_nl80211_set_ap(void *priv,
            nla_put_u32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP, suite))
                goto fail;
 
-       if (params->ht_opmode != -1) {
-               switch (params->smps_mode) {
-               case HT_CAP_INFO_SMPS_DYNAMIC:
-                       wpa_printf(MSG_DEBUG, "nl80211: SMPS mode - dynamic");
-                       smps_mode = NL80211_SMPS_DYNAMIC;
-                       break;
-               case HT_CAP_INFO_SMPS_STATIC:
-                       wpa_printf(MSG_DEBUG, "nl80211: SMPS mode - static");
-                       smps_mode = NL80211_SMPS_STATIC;
-                       break;
-               default:
-                       /* invalid - fallback to smps off */
-               case HT_CAP_INFO_SMPS_DISABLED:
-                       wpa_printf(MSG_DEBUG, "nl80211: SMPS mode - off");
-                       smps_mode = NL80211_SMPS_OFF;
-                       break;
-               }
-               if (nla_put_u8(msg, NL80211_ATTR_SMPS_MODE, smps_mode))
-                       goto fail;
-       }
-
        if (params->beacon_ies) {
                wpa_hexdump_buf(MSG_DEBUG, "nl80211: beacon_ies",
                                params->beacon_ies);
@@ -4329,6 +4326,13 @@ static int wpa_driver_nl80211_set_ap(void *priv,
 
                nla_nest_end(msg, spr);
        }
+
+       if (params->twt_responder) {
+               wpa_printf(MSG_DEBUG, "nl80211: twt_responder=%d",
+                          params->twt_responder);
+               if (nla_put_flag(msg, NL80211_ATTR_TWT_RESPONDER))
+                       goto fail;
+       }
 #endif /* CONFIG_IEEE80211AX */
 
        ret = send_and_recv_msgs(drv, msg, NULL, NULL);
@@ -5108,6 +5112,40 @@ static void nl80211_teardown_ap(struct i802_bss *bss)
 }
 
 
+static int nl80211_tx_control_port(void *priv, const u8 *dest,
+                                  u16 proto, const u8 *buf, size_t len,
+                                  int no_encrypt)
+{
+       struct i802_bss *bss = priv;
+       struct nl_msg *msg;
+       int ret;
+
+       wpa_printf(MSG_DEBUG,
+                  "nl80211: Send over control port dest=" MACSTR
+                  " proto=0x%04x len=%u no_encrypt=%d",
+                  MAC2STR(dest), proto, (unsigned int) len, no_encrypt);
+
+       msg = nl80211_bss_msg(bss, 0, NL80211_CMD_CONTROL_PORT_FRAME);
+       if (!msg ||
+           nla_put_u16(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE, proto) ||
+           nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, dest) ||
+           nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
+           (no_encrypt &&
+            nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT))) {
+               nlmsg_free(msg);
+               return -ENOBUFS;
+       }
+
+       ret = send_and_recv_msgs(bss->drv, msg, NULL, NULL);
+       if (ret)
+               wpa_printf(MSG_DEBUG,
+                          "nl80211: tx_control_port failed: ret=%d (%s)",
+                          ret, strerror(ret));
+
+       return ret;
+}
+
+
 static int nl80211_send_eapol_data(struct i802_bss *bss,
                                   const u8 *addr, const u8 *data,
                                   size_t data_len)
@@ -5150,6 +5188,10 @@ static int wpa_driver_nl80211_hapd_send_eapol(
        int res;
        int qos = flags & WPA_STA_WMM;
 
+       if (drv->capa.flags & WPA_DRIVER_FLAGS_CONTROL_PORT)
+               return nl80211_tx_control_port(bss, addr, ETH_P_EAPOL,
+                                              data, data_len, !encrypt);
+
        if (drv->device_ap_sme || !drv->use_monitor)
                return nl80211_send_eapol_data(bss, addr, data, data_len);
 
@@ -6652,6 +6694,8 @@ static int i802_set_sta_vlan(struct i802_bss *bss, const u8 *addr,
                   MAC2STR(addr), ifname, if_nametoindex(ifname), vlan_id);
        if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_STATION)) ||
            nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
+           ((drv->capa.flags & WPA_DRIVER_FLAGS_VLAN_OFFLOAD) &&
+            nla_put_u16(msg, NL80211_ATTR_VLAN_ID, vlan_id)) ||
            nla_put_u32(msg, NL80211_ATTR_STA_VLAN, if_nametoindex(ifname))) {
                nlmsg_free(msg);
                return -ENOBUFS;
@@ -6724,7 +6768,7 @@ static int i802_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
        return wpa_driver_nl80211_send_mlme(bss, (u8 *) &mgmt,
                                            IEEE80211_HDRLEN +
                                            sizeof(mgmt.u.deauth), 0, 0, 0, 0,
-                                           0, NULL, 0);
+                                           0, NULL, 0, 0);
 }
 
 
@@ -6751,7 +6795,7 @@ static int i802_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr,
        return wpa_driver_nl80211_send_mlme(bss, (u8 *) &mgmt,
                                            IEEE80211_HDRLEN +
                                            sizeof(mgmt.u.disassoc), 0, 0, 0, 0,
-                                           0, NULL, 0);
+                                           0, NULL, 0, 0);
 }
 
 
@@ -7469,7 +7513,7 @@ static int cookie_handler(struct nl_msg *msg, void *arg)
 static int nl80211_send_frame_cmd(struct i802_bss *bss,
                                  unsigned int freq, unsigned int wait,
                                  const u8 *buf, size_t buf_len,
-                                 u64 *cookie_out, int no_cck, int no_ack,
+                                 int save_cookie, int no_cck, int no_ack,
                                  int offchanok, const u16 *csa_offs,
                                  size_t csa_offs_len)
 {
@@ -7508,22 +7552,22 @@ static int nl80211_send_frame_cmd(struct i802_bss *bss,
                           "cookie 0x%llx", no_ack ? " (no ACK)" : "",
                           (long long unsigned int) cookie);
 
-               if (cookie_out)
-                       *cookie_out = no_ack ? (u64) -1 : cookie;
+               if (save_cookie)
+                       drv->send_frame_cookie = no_ack ? (u64) -1 : cookie;
 
-               if (drv->num_send_action_cookies == MAX_SEND_ACTION_COOKIES) {
+               if (drv->num_send_frame_cookies == MAX_SEND_FRAME_COOKIES) {
                        wpa_printf(MSG_DEBUG,
-                                  "nl80211: Drop oldest pending send action cookie 0x%llx",
+                                  "nl80211: Drop oldest pending send frame cookie 0x%llx",
                                   (long long unsigned int)
-                                  drv->send_action_cookies[0]);
-                       os_memmove(&drv->send_action_cookies[0],
-                                  &drv->send_action_cookies[1],
-                                  (MAX_SEND_ACTION_COOKIES - 1) *
+                                  drv->send_frame_cookies[0]);
+                       os_memmove(&drv->send_frame_cookies[0],
+                                  &drv->send_frame_cookies[1],
+                                  (MAX_SEND_FRAME_COOKIES - 1) *
                                   sizeof(u64));
-                       drv->num_send_action_cookies--;
+                       drv->num_send_frame_cookies--;
                }
-               drv->send_action_cookies[drv->num_send_action_cookies] = cookie;
-               drv->num_send_action_cookies++;
+               drv->send_frame_cookies[drv->num_send_frame_cookies] = cookie;
+               drv->num_send_frame_cookies++;
        }
 
 fail:
@@ -7544,10 +7588,14 @@ static int wpa_driver_nl80211_send_action(struct i802_bss *bss,
        int ret = -1;
        u8 *buf;
        struct ieee80211_hdr *hdr;
+       int offchanok = 1;
+
+       if (is_ap_interface(drv->nlmode) && (int) freq == bss->freq)
+               offchanok = 0;
 
        wpa_printf(MSG_DEBUG, "nl80211: Send Action frame (ifindex=%d, "
-                  "freq=%u MHz wait=%d ms no_cck=%d)",
-                  drv->ifindex, freq, wait_time, no_cck);
+                  "freq=%u MHz wait=%d ms no_cck=%d offchanok=%d)",
+                  drv->ifindex, freq, wait_time, no_cck, offchanok);
 
        buf = os_zalloc(24 + data_len);
        if (buf == NULL)
@@ -7573,13 +7621,12 @@ static int wpa_driver_nl80211_send_action(struct i802_bss *bss,
             (int) freq == bss->freq || drv->device_ap_sme ||
             !drv->use_monitor))
                ret = wpa_driver_nl80211_send_mlme(bss, buf, 24 + data_len,
-                                                  0, freq, no_cck, 1,
-                                                  wait_time, NULL, 0);
+                                                  0, freq, no_cck, offchanok,
+                                                  wait_time, NULL, 0, 0);
        else
                ret = nl80211_send_frame_cmd(bss, freq, wait_time, buf,
                                             24 + data_len,
-                                            &drv->send_action_cookie,
-                                            no_cck, 0, 1, NULL, 0);
+                                            1, no_cck, 0, offchanok, NULL, 0);
 
        os_free(buf);
        return ret;
@@ -7615,19 +7662,19 @@ static void wpa_driver_nl80211_send_action_cancel_wait(void *priv)
        u64 cookie;
 
        /* Cancel the last pending TX cookie */
-       nl80211_frame_wait_cancel(bss, drv->send_action_cookie);
+       nl80211_frame_wait_cancel(bss, drv->send_frame_cookie);
 
        /*
         * Cancel the other pending TX cookies, if any. This is needed since
         * the driver may keep a list of all pending offchannel TX operations
         * and free up the radio only once they have expired or cancelled.
         */
-       for (i = drv->num_send_action_cookies; i > 0; i--) {
-               cookie = drv->send_action_cookies[i - 1];
-               if (cookie != drv->send_action_cookie)
+       for (i = drv->num_send_frame_cookies; i > 0; i--) {
+               cookie = drv->send_frame_cookies[i - 1];
+               if (cookie != drv->send_frame_cookie)
                        nl80211_frame_wait_cancel(bss, cookie);
        }
-       drv->num_send_action_cookies = 0;
+       drv->num_send_frame_cookies = 0;
 }
 
 
@@ -7947,15 +7994,6 @@ static int nl80211_signal_poll(void *priv, struct wpa_signal_info *si)
 }
 
 
-static int nl80211_send_frame(void *priv, const u8 *data, size_t data_len,
-                             int encrypt)
-{
-       struct i802_bss *bss = priv;
-       return wpa_driver_nl80211_send_frame(bss, data, data_len, encrypt, 0,
-                                            0, 0, 0, 0, NULL, 0);
-}
-
-
 static int nl80211_set_param(void *priv, const char *param)
 {
        struct i802_bss *bss = priv;
@@ -7990,6 +8028,9 @@ static int nl80211_set_param(void *priv, const char *param)
                drv->test_use_roc_tx = 1;
        }
 
+       if (os_strstr(param, "control_port=0"))
+               drv->capa.flags &= ~WPA_DRIVER_FLAGS_CONTROL_PORT;
+
        return 0;
 }
 
@@ -8410,7 +8451,7 @@ static void nl80211_send_null_frame(struct i802_bss *bss, const u8 *own_addr,
        os_memcpy(nulldata.hdr.IEEE80211_SA_FROMDS, own_addr, ETH_ALEN);
 
        if (wpa_driver_nl80211_send_mlme(bss, (u8 *) &nulldata, size, 0, 0, 0,
-                                        0, 0, NULL, 0) < 0)
+                                        0, 0, NULL, 0, 0) < 0)
                wpa_printf(MSG_DEBUG, "nl80211_send_null_frame: Failed to "
                           "send poll frame");
 }
@@ -8684,15 +8725,12 @@ nl80211_tdls_disable_channel_switch(void *priv, const u8 *addr)
 #endif /* CONFIG TDLS */
 
 
-static int driver_nl80211_set_key(const char *ifname, void *priv,
-                                 enum wpa_alg alg, const u8 *addr,
-                                 int key_idx, int set_tx,
-                                 const u8 *seq, size_t seq_len,
-                                 const u8 *key, size_t key_len)
+static int driver_nl80211_set_key(void *priv,
+                                 struct wpa_driver_set_key_params *params)
 {
        struct i802_bss *bss = priv;
-       return wpa_driver_nl80211_set_key(ifname, bss, alg, addr, key_idx,
-                                         set_tx, seq, seq_len, key, key_len);
+
+       return wpa_driver_nl80211_set_key(bss, params);
 }
 
 
@@ -8757,7 +8795,7 @@ static int driver_nl80211_send_mlme(void *priv, const u8 *data,
        struct i802_bss *bss = priv;
        return wpa_driver_nl80211_send_mlme(bss, data, data_len, noack,
                                            freq, 0, 0, 0, csa_offs,
-                                           csa_offs_len);
+                                           csa_offs_len, no_encrypt);
 }
 
 
@@ -11254,6 +11292,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
        .get_hw_feature_data = nl80211_get_hw_feature_data,
        .sta_add = wpa_driver_nl80211_sta_add,
        .sta_remove = driver_nl80211_sta_remove,
+       .tx_control_port = nl80211_tx_control_port,
        .hapd_send_eapol = wpa_driver_nl80211_hapd_send_eapol,
        .sta_set_flags = wpa_driver_nl80211_sta_set_flags,
        .sta_set_airtime_weight = driver_nl80211_sta_set_airtime_weight,
@@ -11284,7 +11323,6 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
        .signal_monitor = nl80211_signal_monitor,
        .signal_poll = nl80211_signal_poll,
        .channel_info = nl80211_channel_info,
-       .send_frame = nl80211_send_frame,
        .set_param = nl80211_set_param,
        .get_radio_name = nl80211_get_radio_name,
        .add_pmkid = nl80211_add_pmkid,