Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c6dc001f authored by Ali Bahar's avatar Ali Bahar Committed by Greg Kroah-Hartman
Browse files

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: default avatarAli Bahar <ali@internetDog.org>
Signed-off-by: default avatarLarry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent f15abb8b
Loading
Loading
Loading
Loading
+99 −12
Original line number Diff line number Diff line
@@ -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;
}
+45 −3
Original line number Diff line number Diff line
@@ -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,
+138 −6
Original line number Diff line number Diff line
@@ -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"
	}
};

@@ -2234,6 +2359,7 @@ static iw_handler r8711_private_handler[] = {
	r871x_get_ap_info, /*for MM DTV platform*/
	r871x_set_pid,
	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
};
+1 −2
Original line number Diff line number Diff line
@@ -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_*/