]> rtime.felk.cvut.cz Git - hercules2020/nv-tegra/linux-4.4.git/commitdiff
net: wireless: bcmdhd: add nvidia fixes on latest driver from st8 branch
authorManikanta <mmaddireddy@nvidia.com>
Fri, 19 Sep 2014 10:41:17 +0000 (16:11 +0530)
committerDan Willemsen <dwillemsen@nvidia.com>
Wed, 18 Mar 2015 19:26:10 +0000 (12:26 -0700)
- reorder sdlock to avoid lockup
- add driver command MKEEP_ALIVE
- reduce tasklet priority
- update cfg layer with active channel list
- set p2p bw 20MHz if wlan0 is on 20MHz

bug 200037988

Change-Id: I96565fdd61309e5d4ea94d6a96b5a2c03a061d8d
Signed-off-by: Manikanta <mmaddireddy@nvidia.com>
Reviewed-on: http://git-master/r/553602
Reviewed-by: Mohan Thadikamalla <mohant@nvidia.com>
Reviewed-by: Bitan Biswas <bbiswas@nvidia.com>
drivers/net/wireless/bcmdhd/Makefile
drivers/net/wireless/bcmdhd/dhd_linux.c
drivers/net/wireless/bcmdhd/wl_android.c
drivers/net/wireless/bcmdhd/wl_cfg80211.c

index b230617fa6b798ba0aa65bf753c1d805505205c2..e6473d08a7672bc10e3a3bc471de61fcfbbb1139 100644 (file)
@@ -103,7 +103,7 @@ ifneq ($(CONFIG_BCM43241),)
   DHDCFLAGS += -DAMPDU_HOSTREORDER
   DHDCFLAGS += -DCUSTOM_AMPDU_BA_WSIZE=32
   DHDCFLAGS += -DPROP_TXSTATUS_VSDB
-  DHDCFLAGS += -DCUSTOM_DPC_PRIO_SETTING=99
+  DHDCFLAGS += -DCUSTOM_DPC_PRIO_SETTING=MAX_USER_RT_PRIO/2
   DHDCFLAGS += -DRXFRAME_THREAD
   DHDCFLAGS += -DDHDTCPACK_SUPPRESS
   DHDCFLAGS += -DCUSTOM_DPC_CPUCORE=0
index 033570190c24d72749d7a0283d699609ad2a89cb..31aab2442dd2a76da148207b6952fef47c2a7009 100644 (file)
@@ -2952,6 +2952,8 @@ exit:
 static int
 dhd_dpc_thread(void *data)
 {
+       unsigned long timeout;
+       unsigned int loopcnt;
        tsk_ctl_t *tsk = (tsk_ctl_t *)data;
        dhd_info_t *dhd = (dhd_info_t *)tsk->parent;
 
@@ -2986,7 +2988,17 @@ dhd_dpc_thread(void *data)
                        /* Call bus dpc unless it indicated down (then clean stop) */
                        if (dhd->pub.busstate != DHD_BUS_DOWN) {
                                dhd_os_wd_timer_extend(&dhd->pub, TRUE);
+                               timeout = jiffies + msecs_to_jiffies(100);
+                               loopcnt = 0;
                                while (dhd_bus_dpc(dhd->pub.bus)) {
+                                       ++loopcnt;
+                                       if (time_after(jiffies, timeout) &&
+                                               (loopcnt % 1000 == 0)) {
+                                               DHD_ERROR(("%s is consuming "
+                                                       "too much time. %uth "
+                                                       "iteration\b",
+                                                       __func__, loopcnt));
+                                       }
                                        /* process all data */
                                }
                                dhd_os_wd_timer_extend(&dhd->pub, FALSE);
@@ -4775,10 +4787,10 @@ dhd_bus_start(dhd_pub_t *dhdp)
                DHD_GENERAL_LOCK(&dhd->pub, flags);
                dhd->wd_timer_valid = FALSE;
                DHD_GENERAL_UNLOCK(&dhd->pub, flags);
+               dhd_os_sdunlock(dhdp);
                del_timer_sync(&dhd->timer);
 
                DHD_ERROR(("%s Host failed to register for OOB\n", __FUNCTION__));
-               dhd_os_sdunlock(dhdp);
                DHD_PERIM_UNLOCK(dhdp);
                DHD_OS_WD_WAKE_UNLOCK(&dhd->pub);
                return -ENODEV;
@@ -4810,9 +4822,9 @@ dhd_bus_start(dhd_pub_t *dhdp)
                DHD_GENERAL_LOCK(&dhd->pub, flags);
                dhd->wd_timer_valid = FALSE;
                DHD_GENERAL_UNLOCK(&dhd->pub, flags);
+               dhd_os_sdunlock(dhdp);
                del_timer_sync(&dhd->timer);
                DHD_ERROR(("%s failed bus is not ready\n", __FUNCTION__));
-               dhd_os_sdunlock(dhdp);
                DHD_PERIM_UNLOCK(dhdp);
                DHD_OS_WD_WAKE_UNLOCK(&dhd->pub);
                return -ENODEV;
index 15e6aa47e50bbdb881637fed1013297b6e661d8a..03e37f0bb2235559dcf18809aa84ace053e6b071 100644 (file)
@@ -96,6 +96,7 @@
 #endif /* WL_SUPPORT_AUTO_CHANNEL */
 
 #define CMD_KEEP_ALIVE         "KEEPALIVE"
+#define CMD_MKEEP_ALIVE                "MKEEP_ALIVE"
 
 #define CMD_SETMIRACAST        "SETMIRACAST"
 #define CMD_ASSOCRESPIE        "ASSOCRESPIE"
@@ -1639,6 +1640,10 @@ int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
                int skip = strlen(CMD_KEEP_ALIVE) + 1;
                bytes_written = wl_keep_alive_set(net, command + skip, priv_cmd.total_len - skip);
        }
+       else if (strnicmp(command, CMD_MKEEP_ALIVE, strlen(CMD_MKEEP_ALIVE)) == 0) {
+               int skip = strlen(CMD_MKEEP_ALIVE) + 1;
+               bytes_written = wl_keep_alive_set(net, command + skip, priv_cmd.total_len - skip);
+       }
        else if (strnicmp(command, CMD_SETMIRACAST, strlen(CMD_SETMIRACAST)) == 0)
                bytes_written = wldev_miracast_tuning(net, command, priv_cmd.total_len);
        else if (strnicmp(command, CMD_ASSOCRESPIE, strlen(CMD_ASSOCRESPIE)) == 0)
index e9cbbb62914c30c74d8fbe61eb2cec7c941453e6..5bd82aca7bd43e0af48258be3b6f3c22129b831f 100644 (file)
@@ -5844,14 +5844,11 @@ wl_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev,
        s32 _chan;
        chanspec_t chspec = 0;
        chanspec_t fw_chspec = 0;
-       u32 bw = WL_CHANSPEC_BW_20;
+       u32 bw = WL_CHANSPEC_BW_40;
+       u32 chanspec = 0;
+       struct net_info *iter, *next;
 
        s32 err = BCME_OK;
-       s32 bw_cap = 0;
-       struct {
-               u32 band;
-               u32 bw_cap;
-       } param = {0, 0};
        struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
 #ifdef CUSTOM_SET_CPUCORE
        dhd_pub_t *dhd =  (dhd_pub_t *)(cfg->pub);
@@ -5859,40 +5856,39 @@ wl_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev,
 
        if (!cfg)
                return ERR_PTR(-EINVAL);
-       dev = ndev_to_wlc_ndev(dev, wl);
+       dev = ndev_to_wlc_ndev(dev, cfg);
        _chan = ieee80211_frequency_to_channel(chan->center_freq);
        WL_ERR(("netdev_ifidx(%d), chan_type(%d) target channel(%d)\n",
                dev->ifindex, channel_type, _chan));
 
-
-       if (chan->band == IEEE80211_BAND_5GHZ) {
-               param.band = WLC_BAND_5G;
-               err = wldev_iovar_getbuf(dev, "bw_cap", &param, sizeof(param),
-                       cfg->ioctl_buf, WLC_IOCTL_SMLEN, &cfg->ioctl_buf_sync);
-               if (err) {
-                       if (err != BCME_UNSUPPORTED) {
-                               WL_ERR(("bw_cap failed, %d\n", err));
-                               return err;
-                       } else {
-                               err = wldev_iovar_getint(dev, "mimo_bw_cap", &bw_cap);
-                               if (err) {
-                                       WL_ERR(("error get mimo_bw_cap (%d)\n", err));
+       /* In 5GHz band If AP is connected in 20 MHz then follow AP's bw
+          else 40MHz by default. */
+       for_each_ndev(cfg, iter, next) {
+               /* In case interface name is not wlan0 put the right
+                  interface name. */
+               if(!strncmp(iter->ndev->name, "wlan0", strlen("wlan0"))) {
+                       if (wl_get_drv_status(cfg, CONNECTED, iter->ndev)) {
+                               if (chan->band == IEEE80211_BAND_5GHZ) {
+                                       if(wldev_iovar_getint(iter->ndev,
+                                               "chanspec", (s32 *)&chanspec) == BCME_OK) {
+                                               chanspec = wl_chspec_driver_to_host(chanspec);
+                                               /* bits 11,12 and 13 starting from 0 are bw
+                                                  bits. So, values formed with these bits
+                                                  are 0 ,1, 2, 3, 4, 5, 6 which are mapped
+                                                  to 5, 10, 20 ,40 ,80, 160, 80+80 MHz
+                                                  respectively. In below case, 0x1000 = 2
+                                                  which is for 20 MHz */
+                                               if((chanspec & 0x3800) == 0x1000)
+                                                       bw = WL_CHANSPEC_BW_20;
+                                       }
+                               } else {
+                                       /* In 2.4 GHz supported bw is 20 MHz */
+                                       bw = WL_CHANSPEC_BW_20;
                                }
-                               if (bw_cap != WLC_N_BW_20ALL)
-                                       bw = WL_CHANSPEC_BW_40;
                        }
-               } else {
-                       if (WL_BW_CAP_80MHZ(cfg->ioctl_buf[0]))
-                               bw = WL_CHANSPEC_BW_80;
-                       else if (WL_BW_CAP_40MHZ(cfg->ioctl_buf[0]))
-                               bw = WL_CHANSPEC_BW_40;
-                       else
-                               bw = WL_CHANSPEC_BW_20;
-
                }
+       }
 
-       } else if (chan->band == IEEE80211_BAND_2GHZ)
-               bw = WL_CHANSPEC_BW_20;
 set_channel:
        chspec = wf_channel2chspec(_chan, bw);
        if (wf_chspec_valid(chspec)) {
@@ -6694,7 +6690,7 @@ wl_cfg80211_del_station(
        if (!cfg)
                return ERR_PTR(-EINVAL);
 
-       dev = ndev_to_wlc_ndev(ndev, wl);
+       dev = ndev_to_wlc_ndev(ndev, cfg);
 
        if (p2p_is_on(cfg)) {
                /* Suspend P2P discovery search-listen to prevent it from changing the
@@ -8769,6 +8765,9 @@ wl_bss_connect_done(struct bcm_cfg80211 *cfg, struct net_device *ndev,
 #endif /* CUSTOM_SET_CPUCORE */
 
                }
+               /* Update the cfg layer with the lates active channels available */
+               wl_update_wiphybands(NULL, true);
+
                cfg80211_connect_result(ndev,
                        curbssid,
                        conn_info->req_ie,