]> rtime.felk.cvut.cz Git - hercules2020/nv-tegra/linux-4.4.git/commitdiff
bcmdhd: Define miracast modes 3 & 4
authorNarayan Reddy <narayanr@nvidia.com>
Tue, 14 Jan 2014 06:09:53 +0000 (11:39 +0530)
committerDan Willemsen <dwillemsen@nvidia.com>
Wed, 18 Mar 2015 19:25:57 +0000 (12:25 -0700)
Improve QoS for Grid2shield stream by
turning off AMPDU aggregation on 11n AP's
Mode 3 - disable AMPDU for all CS's
Mode 4 - re-enable AMPDU except CS 5 & 7
Driver command MAXLINKSPEED added to
distinguish 11n and non-11n AP's

Bug 1375583

Change-Id: I872ea99d7251845af716a6628eb52f7a7bdedfe2
Reviewed-on: http://git-master/r/355376
Reviewed-by: Narayan Reddy <narayanr@nvidia.com>
Tested-by: Narayan Reddy <narayanr@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Bitan Biswas <bbiswas@nvidia.com>
drivers/net/wireless/bcmdhd/dhd_linux.c
drivers/net/wireless/bcmdhd/wl_android.c
drivers/net/wireless/bcmdhd/wldev_common.c
drivers/net/wireless/bcmdhd/wldev_common.h

index 322f7074565e44796289cefc15dc1e7013519c6b..800c2f864686a96845097bc24f48c4b4e2fc7eac 100644 (file)
@@ -4512,6 +4512,22 @@ done:
        return ret;
 }
 
+void dhd_set_ampdu_rx_tid(struct net_device *dev, int ampdu_rx_tid)
+{
+       int i, ret = 0;
+       dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+       dhd_pub_t *pub = &dhd->pub;
+       char iovbuf[32];
+       for (i = 0; i < 8; i++) { /* One bit each for traffic class CS7 - CS0 */
+               struct ampdu_tid_control atc;
+               atc.tid = i;
+               atc.enable = (ampdu_rx_tid >> i) & 1;
+               bcm_mkiovar("ampdu_rx_tid", (char *)&atc, sizeof(atc), iovbuf,sizeof(iovbuf));
+               ret = dhd_wl_ioctl_cmd(pub, WLC_SET_VAR, iovbuf, sizeof(iovbuf),TRUE, 0);
+               if (ret < 0)
+                       DHD_ERROR(("%s failed %d\n", __func__, ret));
+       }
+}
 
 int
 dhd_iovar(dhd_pub_t *pub, int ifidx, char *name, char *cmd_buf, uint cmd_len, int set)
index f474398fc0b9727d1c5021a13863fbc6c6c894f8..5fc5575bc718871933d52961e761929f80750970 100644 (file)
@@ -99,6 +99,7 @@
 
 #define CMD_SETMIRACAST        "SETMIRACAST"
 #define CMD_ASSOCRESPIE        "ASSOCRESPIE"
+#define CMD_MAXLINKSPEED       "MAXLINKSPEED"
 #define CMD_RXRATESTATS        "RXRATESTATS"
 
 
@@ -1274,6 +1275,8 @@ int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
                bytes_written = wldev_miracast_tuning(net, command, priv_cmd.total_len);
        else if (strnicmp(command, CMD_ASSOCRESPIE, strlen(CMD_ASSOCRESPIE)) == 0)
                bytes_written = wldev_get_assoc_resp_ie(net, command, priv_cmd.total_len);
+       else if (strnicmp(command, CMD_MAXLINKSPEED, strlen(CMD_MAXLINKSPEED))== 0)
+               bytes_written = wldev_get_max_linkspeed(net, command, priv_cmd.total_len);
        else if (strnicmp(command, CMD_RXRATESTATS, strlen(CMD_RXRATESTATS)) == 0)
                bytes_written = wldev_get_rx_rate_stats(net, command, priv_cmd.total_len);
        else if (strnicmp(command, CMD_SETIBSSBEACONOUIDATA,
index 90d7e8f0a237379619646483a5f09ff837ef0b42..92464b00bce61de508eef42b9ed78af04ba7133c 100644 (file)
@@ -392,6 +392,7 @@ int wldev_miracast_tuning(
        int mode = 0;
        int ampdu_mpdu;
        int roam_off;
+       int ampdu_rx_tid = -1;
 #ifdef VSDB_BW_ALLOCATE_ENABLE
        int mchan_algo;
        int mchan_bw;
@@ -402,6 +403,8 @@ int wldev_miracast_tuning(
                return -1;
        }
 
+set_mode:
+
        WLDEV_ERROR(("mode: %d\n", mode));
 
        if (mode == 0) {
@@ -438,6 +441,14 @@ int wldev_miracast_tuning(
                mchan_algo = 0; /* Default */
                mchan_bw = 50;  /* 50:50 */
 #endif /* VSDB_BW_ALLOCATE_ENABLE */
+       } else if (mode == 3) {
+               ampdu_rx_tid = 0;
+               mode = 2;
+               goto set_mode;
+       } else if (mode == 4) {
+               ampdu_rx_tid = 0x5f;
+               mode = 0;
+               goto set_mode;
        }
        else {
                WLDEV_ERROR(("Unknown mode: %d\n", mode));
@@ -477,6 +488,9 @@ int wldev_miracast_tuning(
        }
 #endif /* VSDB_BW_ALLOCATE_ENABLE */
 
+       if (ampdu_rx_tid != -1)
+               dhd_set_ampdu_rx_tid(dev, ampdu_rx_tid);
+
        return error;
 }
 
@@ -552,6 +566,115 @@ done:
        return bytes_written;
 }
 
+int wldev_get_max_linkspeed(
+       struct net_device *dev, char *command, int total_len)
+{
+       wl_assoc_info_t *assoc_info;
+       char smbuf[WLC_IOCTL_SMLEN];
+       char bssid[6], null_bssid[6];
+       int resp_ies_len = 0;
+       int bytes_written = 0;
+       int error, i;
+
+       bzero(bssid, 6);
+       bzero(null_bssid, 6);
+
+       /* Check Association */
+       error = wldev_ioctl(dev, WLC_GET_BSSID, &bssid, sizeof(bssid), 0);
+       if (error == BCME_NOTASSOCIATED) {
+               /* Not associated */
+               bytes_written += snprintf(&command[bytes_written],
+                                       total_len, "-1");
+               goto done;
+       } else if (error < 0) {
+               WLDEV_ERROR(("WLC_GET_BSSID failed = %d\n", error));
+               return -1;
+       } else if (memcmp(bssid, null_bssid, ETHER_ADDR_LEN) == 0) {
+               /*  Zero BSSID: Not associated */
+               bytes_written += snprintf(&command[bytes_written],
+                                       total_len, "-1");
+               goto done;
+       }
+       /* Get assoc_info */
+       bzero(smbuf, sizeof(smbuf));
+       error = wldev_iovar_getbuf(dev, "assoc_info", NULL, 0, smbuf,
+                               sizeof(smbuf), NULL);
+       if (error < 0) {
+               WLDEV_ERROR(("get assoc_info failed = %d\n", error));
+               return -1;
+       }
+
+       assoc_info = (wl_assoc_info_t *)smbuf;
+       resp_ies_len = dtoh32(assoc_info->resp_len) -
+                               sizeof(struct dot11_assoc_resp);
+
+       /* Retrieve assoc resp IEs */
+       if (resp_ies_len) {
+               error = wldev_iovar_getbuf(dev, "assoc_resp_ies", NULL, 0,
+                                       smbuf, sizeof(smbuf), NULL);
+               if (error < 0) {
+                       WLDEV_ERROR(("get assoc_resp_ies failed = %d\n",
+                               error));
+                       return -1;
+               }
+
+               {
+                       int maxRate = 0;
+                       struct dot11IE {
+                               unsigned char ie;
+                               unsigned char len;
+                               unsigned char data[0];
+                       } *dot11IE = (struct dot11IE *)smbuf;
+                       int remaining = resp_ies_len;
+
+                       while (1) {
+                               if (remaining < 2)
+                                       break;
+                               if (remaining < dot11IE->len + 2)
+                                       break;
+                               switch (dot11IE->ie) {
+                               case 0x01: /* supported rates */
+                               case 0x32: /* extended supported rates */
+                                       for (i = 0; i < dot11IE->len; i++) {
+                                               int rate = ((dot11IE->data[i] &
+                                                               0x7f) / 2);
+                                               if (rate > maxRate)
+                                                       maxRate = rate;
+                                       }
+                                       break;
+                               case 0x2d: /* HT capabilities */
+                               case 0x3d: /* HT operation */
+                                       /* 11n supported */
+                                       maxRate = 150; /* Just return an 11n
+                                       rate for now. Could implement detailed
+                                       parser later. */
+                                       break;
+                               default:
+                                       break;
+                               }
+
+                               /* next IE */
+                               dot11IE = (struct dot11IE *)
+                               ((unsigned char *)dot11IE + dot11IE->len + 2);
+                               remaining -= (dot11IE->len + 2);
+                       }
+                       bytes_written += snprintf(&command[bytes_written],
+                                               total_len, "MaxLinkSpeed %d",
+                                               maxRate);
+                       goto done;
+                       }
+       } else {
+               WLDEV_ERROR(("Zero Length assoc resp ies = %d\n",
+                       resp_ies_len));
+               return -1;
+       }
+
+done:
+
+       return bytes_written;
+
+}
+
 int wldev_get_rx_rate_stats(
        struct net_device *dev, char *command, int total_len)
 {
index daa089f7e0dd4c8547d1ebff4a6e844472d15229..ba82974fddaf4992d793540613a0f453f24ccaf9 100644 (file)
@@ -112,5 +112,7 @@ int wldev_set_band(struct net_device *dev, uint band);
 int wldev_miracast_tuning(struct net_device *dev, char *command, int total_len);
 int wldev_get_assoc_resp_ie(struct net_device *dev, char *command, int total_len);
 int wldev_get_rx_rate_stats(struct net_device *dev, char *command, int total_len);
+int wldev_get_max_linkspeed(struct net_device *dev, char *command, int total_len);
+extern void dhd_set_ampdu_rx_tid(struct net_device *dev, int ampdu_rx_tid);
 
 #endif /* __WLDEV_COMMON_H__ */