]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
cfg80211: Convert del_station() callback to use a param struct
[karo-tx-linux.git] / drivers / net / wireless / brcm80211 / brcmfmac / wl_cfg80211.c
index 1db11b00001c8cbf399597ad5db91ddd685a61c1..1a2e062d3bfd8976d8b6f217e34005dd083d4393 100644 (file)
@@ -37,6 +37,7 @@
 #include "fwil.h"
 #include "proto.h"
 #include "vendor.h"
+#include "dhd_bus.h"
 
 #define BRCMF_SCAN_IE_LEN_MAX          2048
 #define BRCMF_PNO_VERSION              2
@@ -2429,7 +2430,7 @@ static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
        s32 err = 0;
        int i;
 
-       bss_list = cfg->bss_list;
+       bss_list = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
        if (bss_list->count != 0 &&
            bss_list->version != BRCMF_BSS_INFO_VERSION) {
                brcmf_err("Version %d != WL_BSS_INFO_VERSION\n",
@@ -2605,6 +2606,7 @@ static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
                        container_of(work, struct brcmf_cfg80211_info,
                                     escan_timeout_work);
 
+       brcmf_inform_bss(cfg);
        brcmf_notify_escan_complete(cfg, cfg->escan_info.ifp, true, true);
 }
 
@@ -2743,12 +2745,9 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
                if (brcmf_p2p_scan_finding_common_channel(cfg, NULL))
                        goto exit;
                if (cfg->scan_request) {
-                       cfg->bss_list = (struct brcmf_scan_results *)
-                               cfg->escan_info.escan_buf;
                        brcmf_inform_bss(cfg);
                        aborted = status != BRCMF_E_STATUS_SUCCESS;
-                       brcmf_notify_escan_complete(cfg, ifp, aborted,
-                                                   false);
+                       brcmf_notify_escan_complete(cfg, ifp, aborted, false);
                } else
                        brcmf_dbg(SCAN, "Ignored scan complete result 0x%x\n",
                                  status);
@@ -2782,50 +2781,91 @@ static __always_inline void brcmf_delay(u32 ms)
 
 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
 {
+       struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
+       struct net_device *ndev = cfg_to_ndev(cfg);
+       struct brcmf_if *ifp = netdev_priv(ndev);
+
        brcmf_dbg(TRACE, "Enter\n");
 
+       if (cfg->wowl_enabled) {
+               brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM,
+                                     cfg->pre_wowl_pmmode);
+               brcmf_fil_iovar_data_set(ifp, "wowl_pattern", "clr", 4);
+               brcmf_fil_iovar_int_set(ifp, "wowl_clear", 0);
+               cfg->wowl_enabled = false;
+       }
        return 0;
 }
 
+static void brcmf_configure_wowl(struct brcmf_cfg80211_info *cfg,
+                                struct brcmf_if *ifp,
+                                struct cfg80211_wowlan *wowl)
+{
+       u32 wowl_config;
+
+       brcmf_dbg(TRACE, "Suspend, wowl config.\n");
+
+       brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_PM, &cfg->pre_wowl_pmmode);
+       brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, PM_MAX);
+
+       wowl_config = 0;
+       if (wowl->disconnect)
+               wowl_config |= WL_WOWL_DIS | WL_WOWL_BCN | WL_WOWL_RETR;
+               /* Note: if "wowl" target and not "wowlpf" then wowl_bcn_loss
+                * should be configured. This paramater is not supported by
+                * wowlpf.
+                */
+       if (wowl->magic_pkt)
+               wowl_config |= WL_WOWL_MAGIC;
+       brcmf_fil_iovar_int_set(ifp, "wowl", wowl_config);
+       brcmf_fil_iovar_int_set(ifp, "wowl_activate", 1);
+       brcmf_bus_wowl_config(cfg->pub->bus_if, true);
+       cfg->wowl_enabled = true;
+}
+
 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
-                                 struct cfg80211_wowlan *wow)
+                                 struct cfg80211_wowlan *wowl)
 {
        struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
        struct net_device *ndev = cfg_to_ndev(cfg);
+       struct brcmf_if *ifp = netdev_priv(ndev);
        struct brcmf_cfg80211_vif *vif;
 
        brcmf_dbg(TRACE, "Enter\n");
 
-       /*
-        * if the primary net_device is not READY there is nothing
+       /* if the primary net_device is not READY there is nothing
         * we can do but pray resume goes smoothly.
         */
-       vif = ((struct brcmf_if *)netdev_priv(ndev))->vif;
-       if (!check_vif_up(vif))
+       if (!check_vif_up(ifp->vif))
                goto exit;
 
-       list_for_each_entry(vif, &cfg->vif_list, list) {
-               if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state))
-                       continue;
-               /*
-                * While going to suspend if associated with AP disassociate
-                * from AP to save power while system is in suspended state
-                */
-               brcmf_link_down(vif);
-
-               /* Make sure WPA_Supplicant receives all the event
-                * generated due to DISASSOC call to the fw to keep
-                * the state fw and WPA_Supplicant state consistent
-                */
-               brcmf_delay(500);
-       }
-
        /* end any scanning */
        if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
                brcmf_abort_scanning(cfg);
 
-       /* Turn off watchdog timer */
-       brcmf_set_mpc(netdev_priv(ndev), 1);
+       if (wowl == NULL) {
+               brcmf_bus_wowl_config(cfg->pub->bus_if, false);
+               list_for_each_entry(vif, &cfg->vif_list, list) {
+                       if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state))
+                               continue;
+                       /* While going to suspend if associated with AP
+                        * disassociate from AP to save power while system is
+                        * in suspended state
+                        */
+                       brcmf_link_down(vif);
+                       /* Make sure WPA_Supplicant receives all the event
+                        * generated due to DISASSOC call to the fw to keep
+                        * the state fw and WPA_Supplicant state consistent
+                        */
+                       brcmf_delay(500);
+               }
+               /* Configure MPC */
+               brcmf_set_mpc(ifp, 1);
+
+       } else {
+               /* Configure WOWL paramaters */
+               brcmf_configure_wowl(cfg, ifp, wowl);
+       }
 
 exit:
        brcmf_dbg(TRACE, "Exit\n");
@@ -3958,24 +3998,24 @@ brcmf_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
 
 static int
 brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
-                          const u8 *mac)
+                          struct station_del_parameters *params)
 {
        struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
        struct brcmf_scb_val_le scbval;
        struct brcmf_if *ifp = netdev_priv(ndev);
        s32 err;
 
-       if (!mac)
+       if (!params->mac)
                return -EFAULT;
 
-       brcmf_dbg(TRACE, "Enter %pM\n", mac);
+       brcmf_dbg(TRACE, "Enter %pM\n", params->mac);
 
        if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
                ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
        if (!check_vif_up(ifp->vif))
                return -EIO;
 
-       memcpy(&scbval.ea, mac, ETH_ALEN);
+       memcpy(&scbval.ea, params->mac, ETH_ALEN);
        scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING);
        err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
                                     &scbval, sizeof(scbval));
@@ -5400,6 +5440,21 @@ static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
        wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
 }
 
+
+#ifdef CONFIG_PM
+static const struct wiphy_wowlan_support brcmf_wowlan_support = {
+       .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
+};
+#endif
+
+static void brcmf_wiphy_wowl_params(struct wiphy *wiphy)
+{
+#ifdef CONFIG_PM
+       /* wowl settings */
+       wiphy->wowlan = &brcmf_wowlan_support;
+#endif
+}
+
 static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
 {
        struct ieee80211_iface_combination ifc_combo;
@@ -5437,6 +5492,9 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
        wiphy->vendor_commands = brcmf_vendor_cmds;
        wiphy->n_vendor_commands = BRCMF_VNDR_CMDS_LAST - 1;
 
+       if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL))
+               brcmf_wiphy_wowl_params(wiphy);
+
        return brcmf_setup_wiphybands(wiphy);
 }