]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/net/wireless/ath/wil6210/cfg80211.c
cfg80211: Convert del_station() callback to use a param struct
[karo-tx-linux.git] / drivers / net / wireless / ath / wil6210 / cfg80211.c
index c8c9852c81a74f56f11419161a05ddf1e1b1d214..8fdfa3222a6e72e1f77aabf2b6ee7a8e4311eed9 100644 (file)
@@ -309,9 +309,23 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
                             request->channels[i]->center_freq);
        }
 
+       if (request->ie_len)
+               print_hex_dump_bytes("Scan IE ", DUMP_PREFIX_OFFSET,
+                                    request->ie, request->ie_len);
+       else
+               wil_dbg_misc(wil, "Scan has no IE's\n");
+
+       rc = wmi_set_ie(wil, WMI_FRAME_PROBE_REQ, request->ie_len,
+                       request->ie);
+       if (rc) {
+               wil_err(wil, "Aborting scan, set_ie failed: %d\n", rc);
+               goto out;
+       }
+
        rc = wmi_send(wil, WMI_START_SCAN_CMDID, &cmd, sizeof(cmd.cmd) +
                        cmd.cmd.num_channels * sizeof(cmd.cmd.channel_list[0]));
 
+out:
        if (rc) {
                del_timer_sync(&wil->scan_timer);
                wil->scan_request = NULL;
@@ -379,22 +393,22 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
                                sme->ie_len);
                        goto out;
                }
-               /*
-                * For secure assoc, send:
-                * (1) WMI_DELETE_CIPHER_KEY_CMD
-                * (2) WMI_SET_APPIE_CMD
-                */
+               /* For secure assoc, send WMI_DELETE_CIPHER_KEY_CMD */
                rc = wmi_del_cipher_key(wil, 0, bss->bssid);
                if (rc) {
                        wil_err(wil, "WMI_DELETE_CIPHER_KEY_CMD failed\n");
                        goto out;
                }
-               /* WMI_SET_APPIE_CMD */
-               rc = wmi_set_ie(wil, WMI_FRAME_ASSOC_REQ, sme->ie_len, sme->ie);
-               if (rc) {
-                       wil_err(wil, "WMI_SET_APPIE_CMD failed\n");
-                       goto out;
-               }
+       }
+
+       /* WMI_SET_APPIE_CMD. ie may contain rsn info as well as other info
+        * elements. Send it also in case it's empty, to erase previously set
+        * ies in FW.
+        */
+       rc = wmi_set_ie(wil, WMI_FRAME_ASSOC_REQ, sme->ie_len, sme->ie);
+       if (rc) {
+               wil_err(wil, "WMI_SET_APPIE_CMD failed\n");
+               goto out;
        }
 
        /* WMI_CONNECT_CMD */
@@ -640,6 +654,45 @@ static int wil_fix_bcon(struct wil6210_priv *wil,
        return rc;
 }
 
+static int wil_cfg80211_change_beacon(struct wiphy *wiphy,
+                                     struct net_device *ndev,
+                                     struct cfg80211_beacon_data *bcon)
+{
+       struct wil6210_priv *wil = wiphy_to_wil(wiphy);
+       int rc;
+
+       wil_dbg_misc(wil, "%s()\n", __func__);
+
+       if (wil_fix_bcon(wil, bcon)) {
+               wil_dbg_misc(wil, "Fixed bcon\n");
+               wil_print_bcon_data(bcon);
+       }
+
+       /* FW do not form regular beacon, so bcon IE's are not set
+        * For the DMG bcon, when it will be supported, bcon IE's will
+        * be reused; add something like:
+        * wmi_set_ie(wil, WMI_FRAME_BEACON, bcon->beacon_ies_len,
+        * bcon->beacon_ies);
+        */
+       rc = wmi_set_ie(wil, WMI_FRAME_PROBE_RESP,
+                       bcon->proberesp_ies_len,
+                       bcon->proberesp_ies);
+       if (rc) {
+               wil_err(wil, "set_ie(PROBE_RESP) failed\n");
+               return rc;
+       }
+
+       rc = wmi_set_ie(wil, WMI_FRAME_ASSOC_RESP,
+                       bcon->assocresp_ies_len,
+                       bcon->assocresp_ies);
+       if (rc) {
+               wil_err(wil, "set_ie(ASSOC_RESP) failed\n");
+               return rc;
+       }
+
+       return 0;
+}
+
 static int wil_cfg80211_start_ap(struct wiphy *wiphy,
                                 struct net_device *ndev,
                                 struct cfg80211_ap_settings *info)
@@ -675,14 +728,12 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
                wil_print_bcon_data(bcon);
        }
 
-       mutex_lock(&wil->mutex);
+       wil_set_recovery_state(wil, fw_recovery_idle);
 
-       rc = wil_reset(wil);
-       if (rc)
-               goto out;
+       mutex_lock(&wil->mutex);
 
-       /* Rx VRING. */
-       rc = wil_rx_init(wil);
+       __wil_down(wil);
+       rc = __wil_up(wil);
        if (rc)
                goto out;
 
@@ -690,9 +741,6 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
        if (rc)
                goto out;
 
-       /* MAC address - pre-requisite for other commands */
-       wmi_set_mac_address(wil, ndev->dev_addr);
-
        /* IE's */
        /* bcon 'head IE's are not relevant for 60g band */
        /*
@@ -724,26 +772,33 @@ out:
 static int wil_cfg80211_stop_ap(struct wiphy *wiphy,
                                struct net_device *ndev)
 {
-       int rc = 0;
+       int rc, rc1;
        struct wil6210_priv *wil = wiphy_to_wil(wiphy);
 
        wil_dbg_misc(wil, "%s()\n", __func__);
 
+       wil_set_recovery_state(wil, fw_recovery_idle);
+
        mutex_lock(&wil->mutex);
 
        rc = wmi_pcp_stop(wil);
 
+       __wil_down(wil);
+       rc1 = __wil_up(wil);
+
        mutex_unlock(&wil->mutex);
-       return rc;
+
+       return min(rc, rc1);
 }
 
 static int wil_cfg80211_del_station(struct wiphy *wiphy,
-                                   struct net_device *dev, const u8 *mac)
+                                   struct net_device *dev,
+                                   struct station_del_parameters *params)
 {
        struct wil6210_priv *wil = wiphy_to_wil(wiphy);
 
        mutex_lock(&wil->mutex);
-       wil6210_disconnect(wil, mac);
+       wil6210_disconnect(wil, params->mac);
        mutex_unlock(&wil->mutex);
 
        return 0;
@@ -764,6 +819,7 @@ static struct cfg80211_ops wil_cfg80211_ops = {
        .del_key = wil_cfg80211_del_key,
        .set_default_key = wil_cfg80211_set_default_key,
        /* AP mode */
+       .change_beacon = wil_cfg80211_change_beacon,
        .start_ap = wil_cfg80211_start_ap,
        .stop_ap = wil_cfg80211_stop_ap,
        .del_station = wil_cfg80211_del_station,
@@ -773,6 +829,7 @@ static void wil_wiphy_init(struct wiphy *wiphy)
 {
        /* TODO: set real value */
        wiphy->max_scan_ssids = 10;
+       wiphy->max_scan_ie_len = WMI_MAX_IE_LEN;
        wiphy->max_num_pmkids = 0 /* TODO: */;
        wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
                                 BIT(NL80211_IFTYPE_AP) |