staging: r8712u: Merging Realtek's latest (v2.6.6). Various fixes.

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>
This commit is contained in:
Ali Bahar 2011-09-04 03:14:20 +08:00 committed by Greg Kroah-Hartman
parent f15abb8b20
commit c6dc001f2a
4 changed files with 283 additions and 23 deletions

View 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;
}

View 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,

View 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
};

View 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_*/