net: wireless: bcmdhd: Fix get_noa() and set_noa() commands
Dmitry Shmidt [Wed, 28 Sep 2011 20:15:54 +0000 (13:15 -0700)]
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>

drivers/net/wireless/bcmdhd/wl_cfgp2p.c

index 2a5fdd1..356bb38 100644 (file)
@@ -1334,13 +1334,13 @@ s32 wl_cfgp2p_set_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf
 
                /* supplicant gives interval as start */
                if (start != -1)
-                       wl->p2p->noa.desc[0].interval = start * 1000;
+                       wl->p2p->noa.desc[0].interval = start;
 
                if (duration != -1)
-                       wl->p2p->noa.desc[0].duration = duration * 1000;
+                       wl->p2p->noa.desc[0].duration = duration;
 
                if (wl->p2p->noa.desc[0].count != 255) {
-                       wl->p2p->noa.desc[0].start = 200 * 1000;
+                       wl->p2p->noa.desc[0].start = 200;
                        dongle_noa.type = WL_P2P_SCHED_TYPE_REQ_ABS;
                        dongle_noa.action = WL_P2P_SCHED_ACTION_GOOFF;
                        dongle_noa.option = WL_P2P_SCHED_OPTION_TSFOFS;
@@ -1349,11 +1349,10 @@ s32 wl_cfgp2p_set_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf
                        /* Continuous NoA interval. */
                        dongle_noa.action = WL_P2P_SCHED_ACTION_NONE;
                        dongle_noa.type = WL_P2P_SCHED_TYPE_ABS;
-                       if ((wl->p2p->noa.desc[0].interval == 102000) ||
-                               (wl->p2p->noa.desc[0].interval == 100000)) {
+                       if ((wl->p2p->noa.desc[0].interval == 102) ||
+                               (wl->p2p->noa.desc[0].interval == 100)) {
                                wl->p2p->noa.desc[0].start = 100 -
-                                       (wl->p2p->noa.desc[0].duration / 1000);
-                               wl->p2p->noa.desc[0].duration /= 1000;
+                                       wl->p2p->noa.desc[0].duration;
                                dongle_noa.option = WL_P2P_SCHED_OPTION_BCNPCT;
                        }
                        else {
@@ -1361,11 +1360,16 @@ s32 wl_cfgp2p_set_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf
                        }
                }
                /* Put the noa descriptor in dongle format for dongle */
-
                dongle_noa.desc[0].count = htod32(wl->p2p->noa.desc[0].count);
-               dongle_noa.desc[0].start = htod32(wl->p2p->noa.desc[0].start);
-               dongle_noa.desc[0].interval = htod32(wl->p2p->noa.desc[0].interval);
-               dongle_noa.desc[0].duration = htod32(wl->p2p->noa.desc[0].duration);
+               if (dongle_noa.option == WL_P2P_SCHED_OPTION_BCNPCT) {
+                       dongle_noa.desc[0].start = htod32(wl->p2p->noa.desc[0].start);
+                       dongle_noa.desc[0].duration = htod32(wl->p2p->noa.desc[0].duration);
+               }
+               else {
+                       dongle_noa.desc[0].start = htod32(wl->p2p->noa.desc[0].start*1000);
+                       dongle_noa.desc[0].duration = htod32(wl->p2p->noa.desc[0].duration*1000);
+               }
+               dongle_noa.desc[0].interval = htod32(wl->p2p->noa.desc[0].interval*1000);
 
                ret = wldev_iovar_setbuf(wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION),
                        "p2p_noa", &dongle_noa, sizeof(dongle_noa), ioctlbuf, sizeof(ioctlbuf));
@@ -1380,45 +1384,58 @@ s32 wl_cfgp2p_set_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf
        return ret;
 }
 
-s32 wl_cfgp2p_get_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf, int len)
+s32 wl_cfgp2p_get_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf, int buf_len)
 {
-       wifi_p2p_noa_desc_t* noa_desc;
+       wifi_p2p_noa_desc_t *noa_desc;
+       int len = 0, i;
+       char _buf[200];
+
        CFGP2P_DBG((" Enter\n"));
+       buf[0] = '\0';
        if (wl->p2p && wl->p2p->vif_created) {
-               if (wl->p2p->noa.desc[0].count) {
-#define P2P_ATTR_NOTICE_OF_ABSENCE_LEN 2
-                       buf[0] = 0; /* noa index */
-                       buf[1] = (wl->p2p->ops.ops ? 0x80: 0) |
+               if (wl->p2p->noa.desc[0].count || wl->p2p->ops.ops) {
+                       _buf[0] = 1; /* noa index */
+                       _buf[1] = (wl->p2p->ops.ops ? 0x80: 0) |
                                (wl->p2p->ops.ctw & 0x7f); /* ops + ctw */
-                       noa_desc = (wifi_p2p_noa_desc_t*)&buf[P2P_ATTR_NOTICE_OF_ABSENCE_LEN];
-                       noa_desc->cnt_type = wl->p2p->noa.desc[0].count;
-                       noa_desc->duration = wl->p2p->noa.desc[0].duration;
-                       noa_desc->interval = wl->p2p->noa.desc[0].interval;
-                       noa_desc->start = wl->p2p->noa.desc[0].start;
-                       /* wl_android.c is adding 1 to ret value for all returned bufs */
-                       return sizeof(wifi_p2p_noa_desc_t) +
-                               P2P_ATTR_NOTICE_OF_ABSENCE_LEN - 1;
-               }
-               else {
-                       /* NOA parameters are not set */
-                       return 0;
+                       len += 2;
+                       if (wl->p2p->noa.desc[0].count) {
+                               noa_desc = (wifi_p2p_noa_desc_t*)&_buf[len];
+                               noa_desc->cnt_type = wl->p2p->noa.desc[0].count;
+                               noa_desc->duration = wl->p2p->noa.desc[0].duration;
+                               noa_desc->interval = wl->p2p->noa.desc[0].interval;
+                               noa_desc->start = wl->p2p->noa.desc[0].start;
+                               len += sizeof(wifi_p2p_noa_desc_t);
+                       }
+                       if (buf_len <= len * 2) {
+                               CFGP2P_ERR(("ERROR: buf_len %d in not enough for"
+                                       "returning noa in string format\n", buf_len));
+                               return -1;
+                       }
+                       /* We have to convert the buffer data into ASCII strings */
+                       for (i = 0; i < len; i++) {
+                               sprintf(buf, "%02x", _buf[i]);
+                               buf += 2;
+                       }
+                       buf[i*2] = '\0';
                }
        }
        else {
-               CFGP2P_ERR(("ERROR: set_noa in non-p2p mode\n"));
+               CFGP2P_ERR(("ERROR: get_noa in non-p2p mode\n"));
                return -1;
        }
+       return len * 2;
 }
 
 s32 wl_cfgp2p_set_p2p_ps(struct wl_priv *wl, struct net_device *ndev, char* buf, int len)
 {
-       int ps, ctw, legacy_ps;
+       int ps, ctw;
        int ret = -1;
+       s32 legacy_ps;
 
        CFGP2P_DBG((" Enter\n"));
        if (wl->p2p && wl->p2p->vif_created) {
                sscanf(buf, "%d %d %d", &legacy_ps, &ps, &ctw);
-               CFGP2P_DBG((" Enter ps %d ctw %d\n", ps, ctw));
+               CFGP2P_DBG((" Enter legacy_ps %d ps %d ctw %d\n", legacy_ps, ps, ctw));
                if (ctw != -1) {
                        wl->p2p->ops.ctw = ctw;
                        ret = 0;
@@ -1443,7 +1460,7 @@ s32 wl_cfgp2p_set_p2p_ps(struct wl_priv *wl, struct net_device *ndev, char* buf,
                }
        }
        else {
-               CFGP2P_ERR(("ERROR: set_noa in non-p2p mode\n"));
+               CFGP2P_ERR(("ERROR: set_p2p_ps in non-p2p mode\n"));
                ret = -1;
        }
        return ret;