staging: r8712u: Merging Realtek's latest (v2.6.6). Various fixes.
authorAli Bahar <ali@internetdog.org>
Sat, 3 Sep 2011 19:14:20 +0000 (03:14 +0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 7 Sep 2011 00:00:35 +0000 (17:00 -0700)
passive_mode added to private ioctls.
New private ioctls added for RSSI, link speed, mac address, scan type,
and DCE-D.
In r8711_wx_get_scan(), we now sleep only 100 times, instead of 1000.
In r8711_wx_set_essid(), added a check for Ad-Hoc state.
In r8711_wx_get_rate(), added a check for RTL8712_RF_2T2R RF type.
Added Set chplan.
In r871x_get_wireless_stats(), updated the mechanism for displaying
link quality.
Added SetDIG and SetRA commands.
r8712_joinbss_cmd() no longer checks for Ad-Hoc mode.

Signed-off-by: Ali Bahar <ali@internetDog.org>
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/staging/rtl8712/rtl871x_cmd.c
drivers/staging/rtl8712/rtl871x_cmd.h
drivers/staging/rtl8712/rtl871x_ioctl_linux.c
drivers/staging/rtl8712/rtl871x_mlme.h

index c416ee3..2d8f48c 100644 (file)
@@ -277,6 +277,28 @@ u8 r8712_setdatarate_cmd(struct _adapter *padapter, u8 *rateset)
        return _SUCCESS;
 }
 
+u8 r8712_set_chplan_cmd(struct _adapter *padapter, int chplan)
+{
+       struct cmd_obj *ph2c;
+       struct SetChannelPlan_param *psetchplanpara;
+       struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
+
+       ph2c = (struct cmd_obj *)_malloc(sizeof(struct cmd_obj));
+       if (ph2c == NULL)
+               return _FAIL;
+       psetchplanpara = (struct SetChannelPlan_param *)
+               _malloc(sizeof(struct SetChannelPlan_param));
+       if (psetchplanpara == NULL) {
+               kfree((u8 *) ph2c);
+               return _FAIL;
+       }
+       init_h2fwcmd_w_parm_no_rsp(ph2c, psetchplanpara,
+                               GEN_CMD_CODE(_SetChannelPlan));
+       psetchplanpara->ChannelPlan = chplan;
+       r8712_enqueue_cmd(pcmdpriv, ph2c);
+       return _SUCCESS;
+}
+
 u8 r8712_setbasicrate_cmd(struct _adapter *padapter, u8 *rateset)
 {
        struct cmd_obj *ph2c;
@@ -303,20 +325,62 @@ u8 r8712_setbasicrate_cmd(struct _adapter *padapter, u8 *rateset)
 u8 r8712_setptm_cmd(struct _adapter *padapter, u8 type)
 {
        struct cmd_obj          *ph2c;
-       struct PT_param         *pptparm;
+       struct writePTM_parm    *pwriteptmparm;
        struct cmd_priv         *pcmdpriv = &padapter->cmdpriv;
 
        ph2c = (struct cmd_obj *)_malloc(sizeof(struct cmd_obj));
        if (ph2c == NULL)
                return _FAIL;
-       pptparm = (struct PT_param *)_malloc(sizeof(struct PT_param));
-       if (pptparm == NULL) {
+       pwriteptmparm = (struct writePTM_parm *)
+               _malloc(sizeof(struct writePTM_parm));
+       if (pwriteptmparm == NULL) {
                kfree((u8 *) ph2c);
                return _FAIL;
        }
-       init_h2fwcmd_w_parm_no_rsp(ph2c, pptparm,
-                                  GEN_CMD_CODE(_SetPowerTracking));
-       pptparm->PT_En = type;
+       init_h2fwcmd_w_parm_no_rsp(ph2c, pwriteptmparm, GEN_CMD_CODE(_SetPT));
+       pwriteptmparm->type = type;
+       r8712_enqueue_cmd(pcmdpriv, ph2c);
+       return _SUCCESS;
+}
+
+u8 r8712_setfwdig_cmd(struct _adapter *padapter, u8 type)
+{
+       struct cmd_obj *ph2c;
+       struct writePTM_parm *pwriteptmparm;
+       struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
+
+       ph2c = (struct cmd_obj *)_malloc(sizeof(struct cmd_obj));
+       if (ph2c == NULL)
+               return _FAIL;
+       pwriteptmparm = (struct writePTM_parm *)
+               _malloc(sizeof(struct setdig_parm));
+       if (pwriteptmparm == NULL) {
+               kfree((u8 *) ph2c);
+               return _FAIL;
+       }
+       init_h2fwcmd_w_parm_no_rsp(ph2c, pwriteptmparm, GEN_CMD_CODE(_SetDIG));
+       pwriteptmparm->type = type;
+       r8712_enqueue_cmd(pcmdpriv, ph2c);
+       return _SUCCESS;
+}
+
+u8 r8712_setfwra_cmd(struct _adapter *padapter, u8 type)
+{
+       struct cmd_obj *ph2c;
+       struct writePTM_parm *pwriteptmparm;
+       struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
+
+       ph2c = (struct cmd_obj *)_malloc(sizeof(struct cmd_obj));
+       if (ph2c == NULL)
+               return _FAIL;
+       pwriteptmparm = (struct writePTM_parm *)
+               _malloc(sizeof(struct setra_parm));
+       if (pwriteptmparm == NULL) {
+               kfree((u8 *) ph2c);
+               return _FAIL;
+       }
+       init_h2fwcmd_w_parm_no_rsp(ph2c, pwriteptmparm, GEN_CMD_CODE(_SetRA));
+       pwriteptmparm->type = type;
        r8712_enqueue_cmd(pcmdpriv, ph2c);
        return _SUCCESS;
 }
@@ -512,12 +576,6 @@ u8 r8712_joinbss_cmd(struct _adapter  *padapter, struct wlan_network *pnetwork)
                                                &psecnetwork->IEs[0],
                                                pnetwork->network.IELength,
                                                &psecnetwork->IELength);
-                       if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE))
-                               r8712_add_ht_addt_info(padapter,
-                                               &pnetwork->network.IEs[0],
-                                               &psecnetwork->IEs[0],
-                                               pnetwork->network.IELength,
-                                               &psecnetwork->IELength);
                }
        }
        psecuritypriv->supplicant_ie[0] = (u8)psecnetwork->IELength;
@@ -950,3 +1008,32 @@ void r8712_setassocsta_cmdrsp_callback(struct _adapter *padapter,
        spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
        r8712_free_cmd_obj(pcmd);
 }
+
+u8 r8712_disconnectCtrlEx_cmd(struct _adapter *adapter, u32 enableDrvCtrl,
+                       u32 tryPktCnt, u32 tryPktInterval, u32 firstStageTO)
+{
+       struct cmd_obj *ph2c;
+       struct DisconnectCtrlEx_param *param;
+       struct cmd_priv *pcmdpriv = &adapter->cmdpriv;
+
+       ph2c = (struct cmd_obj *)_malloc(sizeof(struct cmd_obj));
+       if (ph2c == NULL)
+               return _FAIL;
+       param = (struct DisconnectCtrlEx_param *)
+               _malloc(sizeof(struct DisconnectCtrlEx_param));
+       if (param == NULL) {
+               kfree((unsigned char *) ph2c);
+               return _FAIL;
+       }
+       memset(param, 0, sizeof(struct DisconnectCtrlEx_param));
+
+       param->EnableDrvCtrl = (unsigned char)enableDrvCtrl;
+       param->TryPktCnt = (unsigned char)tryPktCnt;
+       param->TryPktInterval = (unsigned char)tryPktInterval;
+       param->FirstStageTO = (unsigned int)firstStageTO;
+
+       init_h2fwcmd_w_parm_no_rsp(ph2c, param,
+                               GEN_CMD_CODE(_DisconnectCtrlEx));
+       r8712_enqueue_cmd(pcmdpriv, ph2c);
+       return _SUCCESS;
+}
index 2aab78a..757ebf7 100644 (file)
@@ -320,6 +320,35 @@ struct setdatarate_parm {
        u8      datarates[NumRates];
 };
 
+enum _RT_CHANNEL_DOMAIN {
+       RT_CHANNEL_DOMAIN_FCC = 0,
+       RT_CHANNEL_DOMAIN_IC = 1,
+       RT_CHANNEL_DOMAIN_ETSI = 2,
+       RT_CHANNEL_DOMAIN_SPAIN = 3,
+       RT_CHANNEL_DOMAIN_FRANCE = 4,
+       RT_CHANNEL_DOMAIN_MKK = 5,
+       RT_CHANNEL_DOMAIN_MKK1 = 6,
+       RT_CHANNEL_DOMAIN_ISRAEL = 7,
+       RT_CHANNEL_DOMAIN_TELEC = 8,
+
+       /* Be compatible with old channel plan. No good! */
+       RT_CHANNEL_DOMAIN_MIC = 9,
+       RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN = 10,
+       RT_CHANNEL_DOMAIN_WORLD_WIDE_13 = 11,
+       RT_CHANNEL_DOMAIN_TELEC_NETGEAR = 12,
+
+       RT_CHANNEL_DOMAIN_NCC = 13,
+       RT_CHANNEL_DOMAIN_5G = 14,
+       RT_CHANNEL_DOMAIN_5G_40M = 15,
+ /*===== Add new channel plan above this line===============*/
+       RT_CHANNEL_DOMAIN_MAX,
+};
+
+
+struct SetChannelPlan_param {
+       enum _RT_CHANNEL_DOMAIN ChannelPlan;
+};
+
 /*
 Caller Mode: Any
 
@@ -392,6 +421,10 @@ struct writeBB_parm {
        u8      value;
 };
 
+struct writePTM_parm {
+       u8      type;
+};
+
 struct readRF_parm {
        u8      offset;
 };
@@ -671,9 +704,14 @@ struct SetChannel_parm {
        u32 curr_ch;
 };
 
-/*H2C Handler index: 56 */
-struct PT_param {
-       u8 PT_En;
+/*H2C Handler index: 61 */
+struct DisconnectCtrlEx_param {
+       /* MAXTIME = (2 * FirstStageTO) + (TryPktCnt * TryPktInterval) */
+       unsigned char EnableDrvCtrl;
+       unsigned char TryPktCnt;
+       unsigned char TryPktInterval; /* Unit: ms */
+       unsigned char rsvd;
+       unsigned int  FirstStageTO; /* Unit: ms */
 };
 
 #define GEN_CMD_CODE(cmd)      cmd ## _CMD_
@@ -709,13 +747,17 @@ u8 r8712_disassoc_cmd(struct _adapter *padapter);
 u8 r8712_setopmode_cmd(struct _adapter *padapter,
                 enum NDIS_802_11_NETWORK_INFRASTRUCTURE networktype);
 u8 r8712_setdatarate_cmd(struct _adapter *padapter, u8 *rateset);
+u8 r8712_set_chplan_cmd(struct _adapter  *padapter, int chplan);
 u8 r8712_setbasicrate_cmd(struct _adapter *padapter, u8 *rateset);
 u8 r8712_getrfreg_cmd(struct _adapter *padapter, u8 offset, u8 * pval);
 u8 r8712_setrfintfs_cmd(struct _adapter *padapter, u8 mode);
 u8 r8712_setrfreg_cmd(struct _adapter  *padapter, u8 offset, u32 val);
 u8 r8712_setrttbl_cmd(struct _adapter  *padapter,
                      struct setratable_parm *prate_table);
+u8 r8712_gettssi_cmd(struct _adapter  *padapter, u8 offset, u8 *pval);
 u8 r8712_setptm_cmd(struct _adapter *padapter, u8 type);
+u8 r8712_setfwdig_cmd(struct _adapter *padapter, u8 type);
+u8 r8712_setfwra_cmd(struct _adapter *padapter, u8 type);
 u8 r8712_addbareq_cmd(struct _adapter *padapter, u8 tid);
 u8 r8712_wdg_wk_cmd(struct _adapter *padapter);
 void r8712_survey_cmd_callback(struct _adapter  *padapter,
index 4522553..6b15ab8 100644 (file)
@@ -49,7 +49,7 @@
 #include <net/iw_handler.h>
 #include <linux/if_arp.h>
 
-#define RTL_IOCTL_WPA_SUPPLICANT       (SIOCIWFIRSTPRIV + 30)
+#define RTL_IOCTL_WPA_SUPPLICANT       (SIOCIWFIRSTPRIV + 0x1E)
 
 #define SCAN_ITEM_SIZE 768
 #define MAX_CUSTOM_LEN 64
@@ -953,6 +953,10 @@ static int r8711_wx_get_range(struct net_device *dev,
        return 0;
 }
 
+static int r8711_wx_get_rate(struct net_device *dev,
+                            struct iw_request_info *info,
+                            union iwreq_data *wrqu, char *extra);
+
 static int r871x_wx_set_priv(struct net_device *dev,
                                struct iw_request_info *info,
                                union iwreq_data *awrq,
@@ -960,6 +964,7 @@ static int r871x_wx_set_priv(struct net_device *dev,
 {
        int ret = 0, len = 0;
        char *ext;
+       struct _adapter *padapter = netdev_priv(dev);
        struct iw_point *dwrq = (struct iw_point *)awrq;
 
        len = dwrq->length;
@@ -970,6 +975,87 @@ static int r871x_wx_set_priv(struct net_device *dev,
                kfree(ext);
                return -EFAULT;
        }
+
+       if (0 == strcasecmp(ext, "RSSI")) {
+               /*Return received signal strength indicator in -db for */
+               /* current AP */
+               /*<ssid> Rssi xx */
+               struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+               struct wlan_network *pcur_network = &pmlmepriv->cur_network;
+               /*static u8 xxxx; */
+               if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
+                       sprintf(ext, "%s rssi %d",
+                               pcur_network->network.Ssid.Ssid,
+                               /*(xxxx=xxxx+10) */
+                               ((padapter->recvpriv.fw_rssi)>>1)-95
+                               /*pcur_network->network.Rssi */
+                               );
+               } else {
+                       sprintf(ext, "OK");
+               }
+       } else if (0 == strcasecmp(ext, "LINKSPEED")) {
+               /*Return link speed in MBPS */
+               /*LinkSpeed xx */
+               union iwreq_data wrqd;
+               int ret_inner;
+               int mbps;
+
+               ret_inner = r8711_wx_get_rate(dev, info, &wrqd, extra);
+               if (0 != ret_inner)
+                       mbps = 0;
+               else
+                       mbps = wrqd.bitrate.value / 1000000;
+               sprintf(ext, "LINKSPEED %d", mbps);
+       } else if (0 == strcasecmp(ext, "MACADDR")) {
+               /*Return mac address of the station */
+               /*Macaddr = xx.xx.xx.xx.xx.xx */
+               sprintf(ext,
+                       "MACADDR = %02x.%02x.%02x.%02x.%02x.%02x",
+                       *(dev->dev_addr), *(dev->dev_addr+1),
+                       *(dev->dev_addr+2), *(dev->dev_addr+3),
+                       *(dev->dev_addr+4), *(dev->dev_addr+5));
+       } else if (0 == strcasecmp(ext, "SCAN-ACTIVE")) {
+               /*Set scan type to active */
+               /*OK if successful */
+               struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+               pmlmepriv->passive_mode = 1;
+               sprintf(ext, "OK");
+       } else if (0 == strcasecmp(ext, "SCAN-PASSIVE")) {
+               /*Set scan type to passive */
+               /*OK if successful */
+               struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+               pmlmepriv->passive_mode = 0;
+               sprintf(ext, "OK");
+       } else if (0 == strncmp(ext, "DCE-E", 5)) {
+               /*Set scan type to passive */
+               /*OK if successful */
+               r8712_disconnectCtrlEx_cmd(padapter
+                       , 1 /*u32 enableDrvCtrl */
+                       , 5 /*u32 tryPktCnt */
+                       , 100 /*u32 tryPktInterval */
+                       , 5000 /*u32 firstStageTO */
+               );
+               sprintf(ext, "OK");
+       } else if (0 == strncmp(ext, "DCE-D", 5)) {
+               /*Set scan type to passive */
+               /*OK if successfu */
+               r8712_disconnectCtrlEx_cmd(padapter
+                       , 0 /*u32 enableDrvCtrl */
+                       , 5 /*u32 tryPktCnt */
+                       , 100 /*u32 tryPktInterval */
+                       , 5000 /*u32 firstStageTO */
+               );
+               sprintf(ext, "OK");
+       } else {
+               printk(KERN_INFO "r8712u: r871x_wx_set_priv: unknown Command"
+                      " %s.\n", ext);
+               goto FREE_EXT;
+       }
+       if (copy_to_user(dwrq->pointer, ext,
+                               min(dwrq->length, (__u16)(strlen(ext)+1))))
+               ret = -EFAULT;
+
+FREE_EXT:
        kfree(ext);
        return ret;
 }
@@ -1158,7 +1244,7 @@ static int r8711_wx_get_scan(struct net_device *dev,
        while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) {
                msleep(30);
                cnt++;
-               if (cnt > 1000)
+               if (cnt > 100)
                        break;
        }
        spin_lock_irqsave(&queue->lock, irqL);
@@ -1233,6 +1319,17 @@ static int r8711_wx_set_essid(struct net_device *dev,
                        if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength))
                            && (pnetwork->network.Ssid.SsidLength ==
                             ndis_ssid.SsidLength)) {
+                               if (check_fwstate(pmlmepriv,
+                                                       WIFI_ADHOC_STATE)) {
+                                       if (pnetwork->network.
+                                               InfrastructureMode
+                                               !=
+                                               padapter->mlmepriv.
+                                               cur_network.network.
+                                               InfrastructureMode)
+                                               continue;
+                               }
+
                                if (!r8712_set_802_11_infrastructure_mode(
                                     padapter,
                                     pnetwork->network.InfrastructureMode))
@@ -1345,6 +1442,7 @@ static int r8711_wx_get_rate(struct net_device *dev,
        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
        struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
        struct ieee80211_ht_cap *pht_capie;
+       unsigned char rf_type = padapter->registrypriv.rf_config;
        int i;
        u8 *p;
        u16 rate, max_rate = 0, ht_cap = false;
@@ -1377,7 +1475,9 @@ static int r8711_wx_get_rate(struct net_device *dev,
                        i++;
                }
                if (ht_cap == true) {
-                       if (mcs_rate & 0x8000) /* MCS15 */
+                       if (mcs_rate & 0x8000 /* MCS15 */
+                               &&
+                               RTL8712_RF_2T2R == rf_type)
                                max_rate = (bw_40MHz) ? ((short_GI) ? 300 :
                                            270) : ((short_GI) ? 144 : 130);
                        else if (mcs_rate & 0x0080) /* MCS7 */
@@ -1984,6 +2084,27 @@ static int r871x_set_pid(struct net_device *dev,
        return 0;
 }
 
+static int r871x_set_chplan(struct net_device *dev,
+                               struct iw_request_info *info,
+                               union iwreq_data *wrqu, char *extra)
+{
+       int ret = 0;
+       struct _adapter *padapter = (struct _adapter *) netdev_priv(dev);
+       struct iw_point *pdata = &wrqu->data;
+       int ch_plan = -1;
+
+       if ((padapter->bDriverStopped) || (pdata == NULL)) {
+               ret = -EINVAL;
+               goto exit;
+       }
+       ch_plan = (int)*extra;
+       r8712_set_chplan_cmd(padapter, ch_plan);
+
+exit:
+
+       return ret;
+}
+
 static int r871x_wps_start(struct net_device *dev,
                           struct iw_request_info *info,
                           union iwreq_data *wrqu, char *extra)
@@ -2223,6 +2344,10 @@ static const struct iw_priv_args r8711_private_args[] = {
        {
                SIOCIWFIRSTPRIV + 0x6,
                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start"
+       },
+       {
+               SIOCIWFIRSTPRIV + 0x7,
+               IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "chplan"
        }
 };
 
@@ -2233,7 +2358,8 @@ static iw_handler r8711_private_handler[] = {
        r871x_mp_ioctl_hdl,
        r871x_get_ap_info, /*for MM DTV platform*/
        r871x_set_pid,
-        r871x_wps_start,
+       r871x_wps_start,
+       r871x_set_chplan
 };
 
 static struct iw_statistics *r871x_get_wireless_stats(struct net_device *dev)
@@ -2254,7 +2380,13 @@ static struct iw_statistics *r871x_get_wireless_stats(struct net_device *dev)
                tmp_qual = padapter->recvpriv.signal;
                tmp_noise = padapter->recvpriv.noise;
                piwstats->qual.level = tmp_level;
-               piwstats->qual.qual = tmp_qual;
+               /*piwstats->qual.qual = tmp_qual;
+                * The NetworkManager of Fedora 10, 13 will use the link
+                * quality for its display.
+                * So, use the fw_rssi on link quality variable because
+                * fw_rssi will be updated per 2 seconds.
+                */
+               piwstats->qual.qual = tmp_level;
                piwstats->qual.noise = tmp_noise;
        }
        piwstats->qual.updated = IW_QUAL_ALL_UPDATED;
@@ -2269,5 +2401,5 @@ struct iw_handler_def r871x_handlers_def = {
        .num_private = sizeof(r8711_private_handler) / sizeof(iw_handler),
        .num_private_args = sizeof(r8711_private_args) /
                            sizeof(struct iw_priv_args),
-       .get_wireless_stats = r871x_get_wireless_stats,
+       .get_wireless_stats = r871x_get_wireless_stats
 };
index b8810a9..71ca013 100644 (file)
@@ -95,6 +95,7 @@ struct mlme_priv {
        struct  __queue scanned_queue;
        u8 *free_bss_buf;
        unsigned long num_of_scanned;
+       u8 passive_mode; /*add for Android's SCAN-ACTIVE/SCAN-PASSIVE */
        struct ndis_802_11_ssid assoc_ssid;
        u8 assoc_bssid[6];
        struct wlan_network cur_network;
@@ -226,8 +227,6 @@ void r8712_joinbss_reset(struct _adapter *padapter);
 unsigned int r8712_restructure_ht_ie(struct _adapter *padapter, u8 *in_ie,
                                     u8 *out_ie, uint in_len, uint *pout_len);
 void r8712_issue_addbareq_cmd(struct _adapter *padapter, int priority);
-unsigned int r8712_add_ht_addt_info(struct _adapter *padapter, u8 *in_ie,
-                                   u8 *out_ie, uint in_len, uint *pout_len);
 int r8712_is_same_ibss(struct _adapter *adapter, struct wlan_network *pnetwork);
 
 #endif /*__RTL871X_MLME_H_*/