]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c
staging: brcm80211: remove duplicated #include
[mv-sheeva.git] / drivers / staging / brcm80211 / brcmfmac / wl_cfg80211.c
index eea647ce8a4e2241e017087feed3863f7450edd6..0d7aa4adbb77bad3d05cdb21aec65d501e1c77aa 100644 (file)
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <typedefs.h>
-#include <linuxver.h>
-#include <osl.h>
 #include <linux/kernel.h>
+#include <linux/if_arp.h>
+#include <osl.h>
 
 #include <bcmutils.h>
 #include <bcmendian.h>
 #include <proto/ethernet.h>
 
-#include <linux/if_arp.h>
 #include <asm/uaccess.h>
 
 #include <dngl_stats.h>
 #include <dhdioctl.h>
 #include <wlioctl.h>
 
-#include <proto/ethernet.h>
-#include <dngl_stats.h>
-#include <dhd.h>
-
-#include <linux/kernel.h>
 #include <linux/kthread.h>
 #include <linux/netdevice.h>
 #include <linux/sched.h>
@@ -54,8 +47,8 @@ static struct wl_dev *wl_cfg80211_dev;
 
 u32 wl_dbg_level = WL_DBG_ERR | WL_DBG_INFO;
 
-#define WL_4329_FW_FILE "brcm/bcm4329-fullmac-4-218-248-5.bin"
-#define WL_4329_NVRAM_FILE "brcm/bcm4329-fullmac-4-218-248-5.txt"
+#define WL_4329_FW_FILE "brcm/bcm4329-fullmac-4.bin"
+#define WL_4329_NVRAM_FILE "brcm/bcm4329-fullmac-4.txt"
 
 /*
 ** cfg80211_ops api/callback list
@@ -97,12 +90,12 @@ static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy,
                                            struct net_device *dev,
                                            u8 key_idx);
 static s32 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
-                                u8 key_idx, const u8 *mac_addr,
+                                u8 key_idx, bool pairwise, const u8 *mac_addr,
                                 struct key_params *params);
 static s32 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
-                                u8 key_idx, const u8 *mac_addr);
+                                u8 key_idx, bool pairwise, const u8 *mac_addr);
 static s32 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
-                                u8 key_idx, const u8 *mac_addr,
+                                u8 key_idx, bool pairwise, const u8 *mac_addr,
                                 void *cookie, void (*callback) (void *cookie,
                                                                 struct
                                                                 key_params *
@@ -333,6 +326,12 @@ static __used s32 wl_update_pmklist(struct net_device *dev,
 
 static void wl_set_mpc(struct net_device *ndev, int mpc);
 
+/*
+* debufs support
+*/
+static int wl_debugfs_add_netdev_params(struct wl_priv *wl);
+static void wl_debugfs_remove_netdev(struct wl_priv *wl);
+
 #define WL_PRIV_GET()                                                  \
        ({                                                              \
        struct wl_iface *ci;                                            \
@@ -701,7 +700,7 @@ wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid, u16 action)
 
        if (ssid && ssid->SSID_len)
                params_size += sizeof(struct wlc_ssid);
-       params = (struct wl_iscan_params *)kzalloc(params_size, GFP_KERNEL);
+       params = kzalloc(params_size, GFP_KERNEL);
        if (unlikely(!params))
                return -ENOMEM;
        memset(params, 0, params_size);
@@ -732,6 +731,7 @@ static s32 wl_do_iscan(struct wl_priv *wl)
        struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
        struct net_device *ndev = wl_to_ndev(wl);
        struct wlc_ssid ssid;
+       s32 passive_scan;
        s32 err = 0;
 
        /* Broadcast scan by default */
@@ -739,15 +739,12 @@ static s32 wl_do_iscan(struct wl_priv *wl)
 
        iscan->state = WL_ISCAN_STATE_SCANING;
 
-       if (wl->active_scan) {
-               s32 passive_scan = 0;
-               /* make it active scan */
-               err = wl_dev_ioctl(wl_to_ndev(wl), WLC_SET_PASSIVE_SCAN,
-                               &passive_scan, sizeof(passive_scan));
-               if (unlikely(err)) {
-                       WL_DBG(("error (%d)\n", err));
-                       return err;
-               }
+       passive_scan = wl->active_scan ? 0 : 1;
+       err = wl_dev_ioctl(wl_to_ndev(wl), WLC_SET_PASSIVE_SCAN,
+                       &passive_scan, sizeof(passive_scan));
+       if (unlikely(err)) {
+               WL_DBG(("error (%d)\n", err));
+               return err;
        }
        wl_set_mpc(ndev, 0);
        wl->iscan_kickstart = true;
@@ -766,6 +763,7 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
        struct wl_priv *wl = ndev_to_wl(ndev);
        struct cfg80211_ssid *ssids;
        struct wl_scan_req *sr = wl_to_sr(wl);
+       s32 passive_scan;
        bool iscan_req;
        bool spec_scan;
        s32 err = 0;
@@ -823,16 +821,12 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
                        WL_DBG(("Broadcast scan\n"));
                }
                WL_DBG(("sr->ssid.SSID_len (%d)\n", sr->ssid.SSID_len));
-               if (wl->active_scan) {
-                       s32 pssive_scan = 0;
-                       /* make it active scan */
-                       err = wl_dev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
-                                       &pssive_scan, sizeof(pssive_scan));
-                       if (unlikely(err)) {
-                               WL_ERR(("WLC_SET_PASSIVE_SCAN error (%d)\n",
-                                       err));
-                               goto scan_out;
-                       }
+               passive_scan = wl->active_scan ? 0 : 1;
+               err = wl_dev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
+                               &passive_scan, sizeof(passive_scan));
+               if (unlikely(err)) {
+                       WL_ERR(("WLC_SET_PASSIVE_SCAN error (%d)\n", err));
+                       goto scan_out;
                }
                wl_set_mpc(ndev, 0);
                err = wl_dev_ioctl(ndev, WLC_SCAN, &sr->ssid,
@@ -1616,7 +1610,7 @@ wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
 
 static s32
 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
-                   u8 key_idx, const u8 *mac_addr,
+                   u8 key_idx, bool pairwise, const u8 *mac_addr,
                    struct key_params *params)
 {
        struct wl_wsec_key key;
@@ -1701,7 +1695,7 @@ wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
 
 static s32
 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
-                   u8 key_idx, const u8 *mac_addr)
+                   u8 key_idx, bool pairwise, const u8 *mac_addr)
 {
        struct wl_wsec_key key;
        s32 err = 0;
@@ -1757,7 +1751,7 @@ wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
 
 static s32
 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
-                   u8 key_idx, const u8 *mac_addr, void *cookie,
+                   u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
                    void (*callback) (void *cookie, struct key_params * params))
 {
        struct key_params params;
@@ -2264,6 +2258,8 @@ static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
        struct ieee80211_supported_band *band;
        struct wl_cfg80211_bss_info *notif_bss_info;
        struct wl_scan_req *sr = wl_to_sr(wl);
+       struct beacon_proberesp *beacon_proberesp;
+       s32 mgmt_type;
        u32 signal;
        u32 freq;
        s32 err = 0;
@@ -2289,13 +2285,18 @@ static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
                band = wiphy->bands[IEEE80211_BAND_5GHZ];
        notif_bss_info->rssi = bi->RSSI;
        memcpy(mgmt->bssid, &bi->BSSID, ETHER_ADDR_LEN);
+       mgmt_type = wl->active_scan ?
+               IEEE80211_STYPE_PROBE_RESP : IEEE80211_STYPE_BEACON;
        if (!memcmp(bi->SSID, sr->ssid.SSID, bi->SSID_len)) {
                mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
-                                                 IEEE80211_STYPE_PROBE_RESP);
-       }
-       mgmt->u.probe_resp.timestamp = 0;
-       mgmt->u.probe_resp.beacon_int = cpu_to_le16(bi->beacon_period);
-       mgmt->u.probe_resp.capab_info = cpu_to_le16(bi->capability);
+                                                       mgmt_type);
+       }
+       beacon_proberesp = wl->active_scan ?
+               (struct beacon_proberesp *)&mgmt->u.probe_resp :
+               (struct beacon_proberesp *)&mgmt->u.beacon;
+       beacon_proberesp->timestamp = 0;
+       beacon_proberesp->beacon_int = cpu_to_le16(bi->beacon_period);
+       beacon_proberesp->capab_info = cpu_to_le16(bi->capability);
        wl_rst_ie(wl);
        /*
        * wl_add_ie is not necessary because it can only add duplicated
@@ -2307,18 +2308,18 @@ static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
        * bi->rateset.rates);
        */
        wl_mrg_ie(wl, ((u8 *) bi) + bi->ie_offset, bi->ie_length);
-       wl_cp_ie(wl, mgmt->u.probe_resp.variable, WL_BSS_INFO_MAX -
+       wl_cp_ie(wl, beacon_proberesp->variable, WL_BSS_INFO_MAX -
                 offsetof(struct wl_cfg80211_bss_info, frame_buf));
        notif_bss_info->frame_len =
            offsetof(struct ieee80211_mgmt,
-                    u.probe_resp.variable) + wl_get_ielen(wl);
+                    u.beacon.variable) + wl_get_ielen(wl);
        freq = ieee80211_channel_to_frequency(notif_bss_info->channel);
        channel = ieee80211_get_channel(wiphy, freq);
 
        WL_DBG(("SSID : \"%s\", rssi %d, channel %d, capability : 0x04%x, bssid %pM\n",
                bi->SSID,
                notif_bss_info->rssi, notif_bss_info->channel,
-               mgmt->u.probe_resp.capab_info, &bi->BSSID));
+               mgmt->u.beacon.capab_info, &bi->BSSID));
 
        signal = notif_bss_info->rssi * 100;
        if (unlikely(!cfg80211_inform_bss_frame(wiphy, channel, mgmt,
@@ -2551,6 +2552,11 @@ static s32 wl_update_bss_info(struct wl_priv *wl)
        struct cfg80211_bss *bss;
        struct wl_bss_info *bi;
        struct wlc_ssid *ssid;
+       struct bcm_tlv *tim;
+       u16 beacon_interval;
+       u8 dtim_period;
+       size_t ie_len;
+       u8 *ie;
        s32 err = 0;
 
        if (wl_is_ibssmode(wl))
@@ -2580,11 +2586,38 @@ static s32 wl_update_bss_info(struct wl_priv *wl)
                err = wl_inform_single_bss(wl, bi);
                if (unlikely(err))
                        goto update_bss_info_out;
+
+               ie = ((u8 *)bi) + bi->ie_offset;
+               ie_len = bi->ie_length;
+               beacon_interval = cpu_to_le16(bi->beacon_period);
        } else {
                WL_DBG(("Found the AP in the list - BSSID %pM\n", bss->bssid));
+               ie = bss->information_elements;
+               ie_len = bss->len_information_elements;
+               beacon_interval = bss->beacon_interval;
                cfg80211_put_bss(bss);
        }
 
+       tim = bcm_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
+       if (tim) {
+               dtim_period = tim->data[1];
+       } else {
+               /*
+               * active scan was done so we could not get dtim
+               * information out of probe response.
+               * so we speficially query dtim information to dongle.
+               */
+               err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_DTIMPRD,
+                       &dtim_period, sizeof(dtim_period));
+               if (unlikely(err)) {
+                       WL_ERR(("WLC_GET_DTIMPRD error (%d)\n", err));
+                       goto update_bss_info_out;
+               }
+       }
+
+       wl_update_prof(wl, NULL, &beacon_interval, WL_PROF_BEACONINT);
+       wl_update_prof(wl, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
+
 update_bss_info_out:
        rtnl_unlock();
        return err;
@@ -2756,53 +2789,52 @@ static void wl_init_eloop_handler(struct wl_event_loop *el)
 
 static s32 wl_init_priv_mem(struct wl_priv *wl)
 {
-       wl->scan_results = (void *)kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
+       wl->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
        if (unlikely(!wl->scan_results)) {
                WL_ERR(("Scan results alloc failed\n"));
                goto init_priv_mem_out;
        }
-       wl->conf = (void *)kzalloc(sizeof(*wl->conf), GFP_KERNEL);
+       wl->conf = kzalloc(sizeof(*wl->conf), GFP_KERNEL);
        if (unlikely(!wl->conf)) {
                WL_ERR(("wl_conf alloc failed\n"));
                goto init_priv_mem_out;
        }
-       wl->profile = (void *)kzalloc(sizeof(*wl->profile), GFP_KERNEL);
+       wl->profile = kzalloc(sizeof(*wl->profile), GFP_KERNEL);
        if (unlikely(!wl->profile)) {
                WL_ERR(("wl_profile alloc failed\n"));
                goto init_priv_mem_out;
        }
-       wl->bss_info = (void *)kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
+       wl->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
        if (unlikely(!wl->bss_info)) {
                WL_ERR(("Bss information alloc failed\n"));
                goto init_priv_mem_out;
        }
-       wl->scan_req_int =
-           (void *)kzalloc(sizeof(*wl->scan_req_int), GFP_KERNEL);
+       wl->scan_req_int = kzalloc(sizeof(*wl->scan_req_int), GFP_KERNEL);
        if (unlikely(!wl->scan_req_int)) {
                WL_ERR(("Scan req alloc failed\n"));
                goto init_priv_mem_out;
        }
-       wl->ioctl_buf = (void *)kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL);
+       wl->ioctl_buf = kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL);
        if (unlikely(!wl->ioctl_buf)) {
                WL_ERR(("Ioctl buf alloc failed\n"));
                goto init_priv_mem_out;
        }
-       wl->extra_buf = (void *)kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
+       wl->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
        if (unlikely(!wl->extra_buf)) {
                WL_ERR(("Extra buf alloc failed\n"));
                goto init_priv_mem_out;
        }
-       wl->iscan = (void *)kzalloc(sizeof(*wl->iscan), GFP_KERNEL);
+       wl->iscan = kzalloc(sizeof(*wl->iscan), GFP_KERNEL);
        if (unlikely(!wl->iscan)) {
                WL_ERR(("Iscan buf alloc failed\n"));
                goto init_priv_mem_out;
        }
-       wl->fw = (void *)kzalloc(sizeof(*wl->fw), GFP_KERNEL);
+       wl->fw = kzalloc(sizeof(*wl->fw), GFP_KERNEL);
        if (unlikely(!wl->fw)) {
                WL_ERR(("fw object alloc failed\n"));
                goto init_priv_mem_out;
        }
-       wl->pmk_list = (void *)kzalloc(sizeof(*wl->pmk_list), GFP_KERNEL);
+       wl->pmk_list = kzalloc(sizeof(*wl->pmk_list), GFP_KERNEL);
        if (unlikely(!wl->pmk_list)) {
                WL_ERR(("pmk list alloc failed\n"));
                goto init_priv_mem_out;
@@ -3780,6 +3812,8 @@ static s32 __wl_cfg80211_up(struct wl_priv *wl)
 {
        s32 err = 0;
 
+       wl_debugfs_add_netdev_params(wl);
+
        err = wl_config_dongle(wl, false);
        if (unlikely(err))
                return err;
@@ -3817,6 +3851,8 @@ static s32 __wl_cfg80211_down(struct wl_priv *wl)
        clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
        clear_bit(WL_STATUS_CONNECTED, &wl->status);
 
+       wl_debugfs_remove_netdev(wl);
+
        return err;
 }
 
@@ -3898,7 +3934,13 @@ wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e, void *data,
                memcpy(&wl->profile->sec, data, sizeof(wl->profile->sec));
                break;
        case WL_PROF_ACT:
-               wl->profile->active = *(bool *) data;
+               wl->profile->active = *(bool *)data;
+               break;
+       case WL_PROF_BEACONINT:
+               wl->profile->beacon_interval = *(u16 *)data;
+               break;
+       case WL_PROF_DTIMPERIOD:
+               wl->profile->dtim_period = *(u8 *)data;
                break;
        default:
                WL_ERR(("unsupported item (%d)\n", item));
@@ -4146,3 +4188,36 @@ static void wl_set_mpc(struct net_device *ndev, int mpc)
        }
        WL_DBG(("MPC : %d\n", mpc));
 }
+
+static int wl_debugfs_add_netdev_params(struct wl_priv *wl)
+{
+       char buf[10+IFNAMSIZ];
+       struct dentry *fd;
+       s32 err = 0;
+
+       sprintf(buf, "netdev:%s", wl_to_ndev(wl)->name);
+       wl->debugfsdir = debugfs_create_dir(buf, wl_to_wiphy(wl)->debugfsdir);
+
+       fd = debugfs_create_u16("beacon_int", S_IRUGO, wl->debugfsdir,
+               (u16 *)&wl->profile->beacon_interval);
+       if (!fd) {
+               err = -ENOMEM;
+               goto err_out;
+       }
+
+       fd = debugfs_create_u8("dtim_period", S_IRUGO, wl->debugfsdir,
+               (u8 *)&wl->profile->dtim_period);
+       if (!fd) {
+               err = -ENOMEM;
+               goto err_out;
+       }
+
+err_out:
+       return err;
+}
+
+static void wl_debugfs_remove_netdev(struct wl_priv *wl)
+{
+       debugfs_remove_recursive(wl->debugfsdir);
+       wl->debugfsdir = NULL;
+}