29 #define _RTL871X_IOCTL_LINUX_C_
30 #define _RTL871X_MP_IOCTL_C_
42 #include <linux/wireless.h>
43 #include <linux/module.h>
44 #include <linux/kernel.h>
49 #include <linux/if_arp.h>
51 #define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV + 0x1E)
53 #define SCAN_ITEM_SIZE 768
54 #define MAX_CUSTOM_LEN 64
59 6000000, 9000000, 12000000, 18000000,
60 24000000, 36000000, 48000000, 54000000};
63 2412, 2417, 2422, 2427,
64 2432, 2437, 2442, 2447,
65 2452, 2457, 2462, 2467,
69 static const char *
const iw_operation_mode[] = {
70 "Auto",
"Ad-Hoc",
"Managed",
"Master",
"Repeater",
"Secondary",
80 static int hwaddr_aton_i(
const char *txt,
u8 *
addr)
84 for (i = 0; i < 6; i++) {
93 *addr++ = (a << 4) | b;
94 if (i < 5 && *txt++ !=
':')
120 static inline void handle_pairwise_key(
struct sta_info *psta,
138 static inline void handle_group_key(
struct ieee_param *param,
141 if (0 < param->
u.
crypt.idx &&
146 > 16 ? 16 : param->
u.
crypt.key_len));
148 u.crypt.idx-1].skey, &(param->
u.
crypt.key[16]), 8);
150 u.crypt.idx-1].skey, &(param->
u.
crypt.key[24]), 8);
156 pwrctrlpriv.pwr_mode)
157 _set_timer(&(padapter->
mlmepriv.dhcp_timer),
163 static inline char *translate_scan(
struct _adapter *padapter,
172 u32 i = 0, ht_ielen = 0;
173 u16 cap, ht_cap =
false, mcs_rate;
174 u8 rssi, bw_40MHz = 0, short_GI = 0;
176 if ((pnetwork->
network.Configuration.DSConfig < 1) ||
177 (pnetwork->
network.Configuration.DSConfig > 14)) {
178 if (pnetwork->
network.Configuration.DSConfig < 1)
179 pnetwork->
network.Configuration.DSConfig = 1;
181 pnetwork->
network.Configuration.DSConfig = 14;
187 start = iwe_stream_add_event(info, start, stop, &iwe,
IW_EV_ADDR_LEN);
190 iwe.u.data.flags = 1;
193 start = iwe_stream_add_point(info, start, stop, &iwe,
197 &ht_ielen, pnetwork->
network.IELength - 12);
198 if (p && ht_ielen > 0) {
210 SupportedRates)) ==
true) {
216 SupportedRates)) ==
true) {
227 start = iwe_stream_add_event(info, start, stop, &iwe,
IW_EV_CHAR_LEN);
238 start = iwe_stream_add_event(info, start, stop, &iwe,
245 u8 dsconfig = pnetwork->
network.Configuration.DSConfig;
246 if (dsconfig >= 1 && dsconfig <=
sizeof(
249 pnetwork->
network.Configuration.
250 DSConfig - 1] * 100000);
254 iwe.u.freq.e = (
s16)1;
255 iwe.u.freq.i = (
u8)pnetwork->
network.Configuration.DSConfig;
256 start = iwe_stream_add_event(info, start, stop, &iwe,
265 iwe.u.data.length = (
u16)0;
266 start = iwe_stream_add_point(info, start, stop, &iwe,
269 current_val = start + iwe_stream_lcp_len(info);
271 iwe.u.bitrate.fixed = 0;
272 iwe.u.bitrate.disabled = 0;
273 iwe.u.bitrate.value = 0;
275 while (pnetwork->
network.SupportedRates[i] != 0) {
277 iwe.u.bitrate.value = (pnetwork->
network.SupportedRates[i++] &
279 current_val = iwe_stream_add_value(info, start, current_val,
283 if ((current_val - start) > iwe_stream_lcp_len(info))
288 u8 wpa_ie[255], rsn_ie[255];
289 u16 wpa_len = 0, rsn_len = 0;
294 IELength, rsn_ie, &rsn_len,
299 for (i = 0; i < wpa_len; i++) {
305 memset(&iwe, 0,
sizeof(iwe));
308 start = iwe_stream_add_point(info, start, stop,
310 memset(&iwe, 0,
sizeof(iwe));
312 iwe.u.data.length = (
u16)wpa_len;
313 start = iwe_stream_add_point(info, start, stop,
319 for (i = 0; i < rsn_len; i++) {
325 memset(&iwe, 0,
sizeof(iwe));
327 iwe.u.data.length =
strlen(buf);
328 start = iwe_stream_add_point(info, start, stop,
330 memset(&iwe, 0,
sizeof(iwe));
332 iwe.u.data.length = rsn_len;
333 start = iwe_stream_add_point(info, start, stop, &iwe,
344 wps_ie, &wps_ielen) ==
true) {
347 iwe.u.data.length = (
u16)wps_ielen;
348 start = iwe_stream_add_point(info, start, stop,
359 iwe.u.qual.level = rssi;
361 iwe.u.qual.noise = 0;
362 start = iwe_stream_add_event(info, start, stop, &iwe,
IW_EV_QUAL_LEN);
378 }
else if (value & AUTH_ALG_SHARED_KEY) {
399 u32 wep_key_idx, wep_key_len = 0;
410 if (is_broadcast_ether_addr(param->
sta_addr)) {
424 wep_key_idx = param->
u.
crypt.idx;
425 wep_key_len = param->
u.
crypt.key_len;
428 if (wep_key_len > 0) {
429 wep_key_len = wep_key_len <= 5 ? 5 : 13;
438 pwep->
Length = wep_key_len +
441 if (wep_key_len == 13) {
452 if (param->
u.
crypt.set_tx) {
481 get_bssid(pmlmepriv));
489 securitypriv.PrivacyAlgrthm;
490 if (param->
u.
crypt.set_tx == 1)
491 handle_pairwise_key(psta, param,
494 handle_group_key(param, padapter);
514 static int r871x_set_wpa_ie(
struct _adapter *padapter,
char *pie,
515 unsigned short ielen)
518 int group_cipher = 0, pairwise_cipher = 0;
524 buf = _malloc(ielen);
543 Ndis802_11AuthModeWPA2PSK;
545 switch (group_cipher) {
573 switch (pairwise_cipher) {
604 u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
606 while (cnt < ielen) {
610 (!
memcmp(&buf[cnt+2], wps_oui, 4))) {
624 " wps_phase==true\n");
628 cnt += buf[cnt + 1] + 2;
637 static int r8711_wx_get_name(
struct net_device *dev,
653 &ht_ielen, pcur_bss->
IELength - 12);
654 if (p && ht_ielen > 0)
684 static const long frequency_list[] = {
685 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462,
686 2467, 2472, 2484, 4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980,
687 5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210,
688 5220, 5230, 5240, 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560,
689 5580, 5600, 5620, 5640, 5660, 5680, 5700, 5745, 5765, 5785, 5805,
693 static int r8711_wx_set_freq(
struct net_device *dev,
702 if ((fwrq->
e == 1) &&
703 (fwrq->
m >= (
int) 2.412e8) &&
704 (fwrq->
m <= (
int) 2.487e8)) {
705 int f = fwrq->
m / 100000;
707 while ((c < 14) && (f != frequency_list[
c]))
713 if ((fwrq->
m > 14) || (fwrq->
e > 0))
717 if ((channel < 1) || (channel > 14))
727 static int r8711_wx_get_freq(
struct net_device *dev,
735 if (check_fwstate(pmlmepriv,
_FW_LINKED) ==
true) {
746 static int r8711_wx_set_mode(
struct net_device *dev,
753 switch (wrqu->
mode) {
786 else if (check_fwstate(pmlmepriv,
796 static int r871x_wx_set_pmkid(
struct net_device *dev,
805 u8 j, blInserted =
false;
806 int intReturn =
false;
833 " BSSID exists in the PMKList.\n");
845 " new entry index = %d for this PMKID.\n",
848 PMKIDIndex].Bssid, strIssueBssid,
ETH_ALEN);
854 if (psecuritypriv->
PMKIDIndex == NUM_PMKID_CACHE)
880 "unknown Command\n");
887 static int r8711_wx_get_sens(
struct net_device *dev,
891 wrqu->
sens.value = 0;
892 wrqu->
sens.fixed = 0;
893 wrqu->
sens.disabled = 1;
897 static int r8711_wx_get_range(
struct net_device *dev,
905 wrqu->
data.length =
sizeof(*range);
906 memset(range, 0,
sizeof(*range));
937 for (i = 0, val = 0; i < 14; i++) {
954 static int r8711_wx_get_rate(
struct net_device *dev,
958 static int r871x_wx_set_priv(
struct net_device *dev,
963 int ret = 0,
len = 0;
965 struct _adapter *padapter = netdev_priv(dev);
984 if (check_fwstate(pmlmepriv,
_FW_LINKED) ==
true) {
986 pcur_network->
network.Ssid.Ssid,
988 ((padapter->
recvpriv.fw_rssi)>>1)-95
994 }
else if (0 ==
strcasecmp(ext,
"LINKSPEED")) {
1001 ret_inner = r8711_wx_get_rate(dev, info, &wrqd, extra);
1005 mbps = wrqd.bitrate.value / 1000000;
1006 sprintf(ext,
"LINKSPEED %d", mbps);
1007 }
else if (0 ==
strcasecmp(ext,
"MACADDR")) {
1011 "MACADDR = %02x.%02x.%02x.%02x.%02x.%02x",
1015 }
else if (0 ==
strcasecmp(ext,
"SCAN-ACTIVE")) {
1021 }
else if (0 ==
strcasecmp(ext,
"SCAN-PASSIVE")) {
1027 }
else if (0 ==
strncmp(ext,
"DCE-E", 5)) {
1037 }
else if (0 ==
strncmp(ext,
"DCE-D", 5)) {
1074 static int r8711_wx_set_wap(
struct net_device *dev,
1098 phead = get_list_head(queue);
1101 if (end_of_queue_search(phead, pmlmepriv->
pscanned) ==
true)
1106 dst_bssid = pnetwork->
network.MacAddress;
1109 pnetwork->
network.InfrastructureMode);
1113 spin_unlock_irqrestore(&queue->
lock, irqL);
1125 static int r8711_wx_get_wap(
struct net_device *dev,
1142 static int r871x_wx_set_mlme(
struct net_device *dev,
1154 switch (mlme->
cmd) {
1177 static int r8711_wx_set_scan(
struct net_device *dev,
1190 if (padapter->
bup ==
false)
1207 ssid.SsidLength = len;
1216 spin_unlock_irqrestore(&pmlmepriv->
lock, irqL);
1220 if (status ==
false)
1225 static int r8711_wx_get_scan(
struct net_device *dev,
1236 char *stop = ev + wrqu->
data.length;
1237 u32 ret = 0, cnt = 0;
1248 phead = get_list_head(queue);
1251 if (end_of_queue_search(phead, plist) ==
true)
1258 ev = translate_scan(padapter, a, pnetwork, ev, stop);
1261 spin_unlock_irqrestore(&queue->
lock, irqL);
1263 wrqu->
data.flags = 0;
1279 static int r8711_wx_set_essid(
struct net_device *dev,
1289 u8 *dst_ssid, *src_ssid;
1300 if (wrqu->
essid.flags && wrqu->
essid.length) {
1304 ndis_ssid.SsidLength = len;
1305 memcpy(ndis_ssid.Ssid, extra, len);
1306 src_ssid = ndis_ssid.Ssid;
1307 phead = get_list_head(queue);
1310 if (end_of_queue_search(phead, pmlmepriv->
pscanned))
1315 dst_ssid = pnetwork->
network.Ssid.Ssid;
1316 if ((!
memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength))
1317 && (pnetwork->
network.Ssid.SsidLength ==
1318 ndis_ssid.SsidLength)) {
1319 if (check_fwstate(pmlmepriv,
1325 cur_network.network.
1332 pnetwork->
network.InfrastructureMode);
1342 static int r8711_wx_get_essid(
struct net_device *dev,
1352 len = pcur_bss->
Ssid.SsidLength;
1353 wrqu->
essid.length = len;
1355 wrqu->
essid.flags = 1;
1362 static int r8711_wx_set_rate(
struct net_device *dev,
1371 u8 mpdatarate[
NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
1374 if (target_rate == -1) {
1378 target_rate = target_rate / 100000;
1379 switch (target_rate) {
1422 if (ratevalue == mpdatarate[i]) {
1423 datarates[
i] = mpdatarate[
i];
1427 datarates[
i] = 0xff;
1434 static int r8711_wx_get_rate(
struct net_device *dev,
1445 u16 rate, max_rate = 0, ht_cap =
false;
1447 u8 bw_40MHz = 0, short_GI = 0;
1455 if (p && ht_ielen > 0) {
1468 if (rate > max_rate)
1471 wrqu->
bitrate.value = rate*500000;
1474 if (ht_cap ==
true) {
1475 if (mcs_rate & 0x8000
1478 max_rate = (bw_40MHz) ? ((short_GI) ? 300 :
1479 270) : ((short_GI) ? 144 : 130);
1480 else if (mcs_rate & 0x0080)
1481 max_rate = (bw_40MHz) ? ((short_GI) ? 150 :
1482 135) : ((short_GI) ? 72 : 65);
1484 max_rate = (bw_40MHz) ? ((short_GI) ? 150 :
1485 135) : ((short_GI) ? 72 : 65);
1487 wrqu->
bitrate.value = max_rate * 500000;
1489 wrqu->
bitrate.value = max_rate * 500000;
1496 static int r8711_wx_get_rts(
struct net_device *dev,
1503 wrqu->
rts.fixed = 0;
1507 static int r8711_wx_set_frag(
struct net_device *dev,
1513 if (wrqu->
frag.disabled)
1524 static int r8711_wx_get_frag(
struct net_device *dev,
1531 wrqu->
frag.fixed = 0;
1535 static int r8711_wx_get_retry(
struct net_device *dev,
1539 wrqu->
retry.value = 7;
1540 wrqu->
retry.fixed = 0;
1541 wrqu->
retry.disabled = 1;
1545 static int r8711_wx_set_enc(
struct net_device *dev,
1550 u32 keyindex_provided;
1560 "EncryptionDisabled\n");
1574 keyindex_provided = 1;
1576 keyindex_provided = 0;
1582 "IW_ENCODE_OPEN\n");
1592 "IW_ENCODE_RESTRICTED\n");
1611 wep.KeyLength = erq->
length <= 5 ? 5 : 13;
1612 wep.Length = wep.KeyLength +
1616 if (keyindex_provided == 1) {
1636 wep.KeyIndex |= 0x80000000;
1637 memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
1643 static int r8711_wx_get_enc(
struct net_device *dev,
1652 if (check_fwstate(pmlmepriv,
_FW_LINKED) ==
false) {
1667 erq->
flags = key + 1;
1706 static int r8711_wx_get_power(
struct net_device *dev,
1710 wrqu->
power.value = 0;
1711 wrqu->
power.fixed = 0;
1712 wrqu->
power.disabled = 1;
1716 static int r871x_wx_set_gen_ie(
struct net_device *dev,
1722 return r871x_set_wpa_ie(padapter, extra, wrqu->
data.length);
1725 static int r871x_wx_set_auth(
struct net_device *dev,
1736 paramval = param->
value;
1793 ret = wpa_set_auth_algs(dev, (
u32)paramval);
1808 static int r871x_wx_set_enc_ext(
struct net_device *dev,
1820 param = (
struct ieee_param *)_malloc(param_len);
1823 memset(param, 0, param_len);
1826 switch (pext->
alg) {
1844 param->u.crypt.set_tx = 0;
1846 param->u.crypt.set_tx = 1;
1847 param->u.crypt.idx = (pencoding->
flags & 0x00FF) - 1;
1851 param->u.crypt.key_len = pext->
key_len;
1854 ret = wpa_set_encryption(dev, param, param_len);
1859 static int r871x_wx_get_nick(
struct net_device *dev,
1864 wrqu->
data.length = 8;
1865 wrqu->
data.flags = 1;
1866 memcpy(extra,
"rtl_wifi", 8);
1871 static int r8711_wx_read32(
struct net_device *dev,
1882 wrqu->
data.length = (data32 & 0xffff0000) >> 16;
1883 wrqu->
data.flags = data32 & 0xffff;
1888 static int r8711_wx_write32(
struct net_device *dev,
1909 static int r8711_drvext_hdl(
struct net_device *dev,
1916 static int r871x_mp_ioctl_hdl(
struct net_device *dev,
1925 unsigned long BytesRead, BytesWritten, BytesNeeded;
1933 goto _r871x_mp_ioctl_hdl_exit;
1935 bset = (
u8)(p->
flags & 0xFFFF);
1938 pparmbuf = (
u8 *)_malloc(len);
1939 if (pparmbuf ==
NULL) {
1941 goto _r871x_mp_ioctl_hdl_exit;
1945 goto _r871x_mp_ioctl_hdl_exit;
1950 goto _r871x_mp_ioctl_hdl_exit;
1956 goto _r871x_mp_ioctl_hdl_exit;
1959 status = phandler->
handler(&oid_par);
1961 oid_par.adapter_context = padapter;
1962 oid_par.oid = phandler->
oid;
1963 oid_par.information_buf = poidparam->
data;
1964 oid_par.information_buf_len = poidparam->
len;
1969 oid_par.bytes_rw = &BytesRead;
1970 oid_par.bytes_needed = &BytesNeeded;
1971 oid_par.type_of_oid =
SET_OID;
1973 oid_par.bytes_rw = &BytesWritten;
1974 oid_par.bytes_needed = &BytesNeeded;
1977 status = phandler->
handler(&oid_par);
1981 " subcode=%d, oid=%d, handler=%p\n",
1984 goto _r871x_mp_ioctl_hdl_exit;
1992 goto _r871x_mp_ioctl_hdl_exit;
1994 _r871x_mp_ioctl_hdl_exit:
1999 static int r871x_get_ap_info(
struct net_device *dev,
2008 u32 cnt = 0, wpa_ielen;
2011 unsigned char *pbuf;
2024 if (pdata->
length >= 32) {
2030 phead = get_list_head(queue);
2033 if (end_of_queue_search(phead, plist) ==
true)
2036 if (hwaddr_aton_i(data, bssid)) {
2047 &wpa_ielen, pnetwork->
network.IELength-12);
2048 if (pbuf && (wpa_ielen > 0)) {
2053 &wpa_ielen, pnetwork->
network.IELength-12);
2054 if (pbuf && (wpa_ielen > 0)) {
2061 spin_unlock_irqrestore(&(pmlmepriv->
scanned_queue.lock), irqL);
2062 if (pdata->
length >= 34) {
2070 static int r871x_set_pid(
struct net_device *dev,
2084 static int r871x_set_chplan(
struct net_device *dev,
2097 ch_plan = (
int)*extra;
2105 static int r871x_wps_start(
struct net_device *dev,
2111 u32 u32wps_start = 0;
2117 if (u32wps_start == 0)
2118 u32wps_start = *
extra;
2119 if (u32wps_start == 1)
2120 padapter->
ledpriv.LedControlHandler(padapter,
2122 else if (u32wps_start == 2)
2123 padapter->
ledpriv.LedControlHandler(padapter,
2125 else if (u32wps_start == 3)
2126 padapter->
ledpriv.LedControlHandler(padapter,
2138 switch ((value)&0xff) {
2147 Ndis802_11AuthModeWPA2PSK;
2171 return wpa_set_auth_algs(dev, value);
2218 switch (param->
cmd) {
2220 ret = wpa_set_param(dev, param->
u.
wpa_param.name,
2224 ret = r871x_set_wpa_ie(padapter, (
char *)param->
u.
wpa_ie.data,
2228 ret = wpa_set_encryption(dev, param, p->
length);
2231 ret = wpa_mlme(dev, param->
u.
mlme.command,
2232 param->
u.
mlme.reason_code);
2251 return wpa_supplicant_ioctl(dev, &wrq->
u.
data);
2308 r871x_wx_set_gen_ie,
2312 r871x_wx_set_enc_ext,
2318 static const struct iw_priv_args r8711_private_args[] = {
2351 static iw_handler r8711_private_handler[] = {
2371 piwstats->
qual.qual = 0;
2372 piwstats->
qual.level = 0;
2373 piwstats->
qual.noise = 0;
2376 tmp_level = padapter->
recvpriv.fw_rssi;
2377 tmp_qual = padapter->
recvpriv.signal;
2378 tmp_noise = padapter->
recvpriv.noise;
2379 piwstats->
qual.level = tmp_level;
2380 piwstats->
qual.qual = tmp_qual;
2381 piwstats->
qual.noise = tmp_noise;
2388 .standard = r8711_handlers,
2390 .private = r8711_private_handler,
2391 .private_args = (
struct iw_priv_args *)r8711_private_args,
2392 .num_private =
ARRAY_SIZE(r8711_private_handler),
2393 .num_private_args =
sizeof(r8711_private_args) /
2395 .get_wireless_stats = r871x_get_wireless_stats