Disbale / clean iw priv

This commit is contained in:
kimocoder 2019-08-16 18:38:23 +02:00
parent 341f3e9c80
commit 3a405781ba

View File

@ -11488,271 +11488,6 @@ static iw_handler rtw_handlers[] = {
NULL, /*---hole---*/
};
static const struct iw_priv_args rtw_private_args[] = {
{
SIOCIWFIRSTPRIV + 0x0,
IW_PRIV_TYPE_CHAR | 0x7FF, 0, "write"
},
{
SIOCIWFIRSTPRIV + 0x1,
IW_PRIV_TYPE_CHAR | 0x7FF,
IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "read"
},
{
SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext"
},
{
SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl"
},
{
SIOCIWFIRSTPRIV + 0x4,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
},
{
SIOCIWFIRSTPRIV + 0x5,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setpid"
},
{
SIOCIWFIRSTPRIV + 0x6,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start"
},
/* for PLATFORM_MT53XX */
{
SIOCIWFIRSTPRIV + 0x7,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "get_sensitivity"
},
{
SIOCIWFIRSTPRIV + 0x8,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_prob_req_ie"
},
{
SIOCIWFIRSTPRIV + 0x9,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_assoc_req_ie"
},
/* for RTK_DMP_PLATFORM */
{
SIOCIWFIRSTPRIV + 0xA,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "channel_plan"
},
{
SIOCIWFIRSTPRIV + 0xB,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "dbg"
},
{
SIOCIWFIRSTPRIV + 0xC,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "rfw"
},
{
SIOCIWFIRSTPRIV + 0xD,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "rfr"
},
#if 0
{
SIOCIWFIRSTPRIV + 0xE, 0, 0, "wowlan_ctrl"
},
#endif
{
SIOCIWFIRSTPRIV + 0x10,
IW_PRIV_TYPE_CHAR | 1024, 0, "p2p_set"
},
{
SIOCIWFIRSTPRIV + 0x11,
IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , "p2p_get"
},
{
SIOCIWFIRSTPRIV + 0x12, 0, 0, "NULL"
},
{
SIOCIWFIRSTPRIV + 0x13,
IW_PRIV_TYPE_CHAR | 64, IW_PRIV_TYPE_CHAR | 64 , "p2p_get2"
},
{
SIOCIWFIRSTPRIV + 0x14,
IW_PRIV_TYPE_CHAR | 64, 0, "tdls"
},
{
SIOCIWFIRSTPRIV + 0x15,
IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024 , "tdls_get"
},
{
SIOCIWFIRSTPRIV + 0x16,
IW_PRIV_TYPE_CHAR | 64, 0, "pm_set"
},
#ifdef CONFIG_RTW_80211K
{
SIOCIWFIRSTPRIV + 0x17,
IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024 , "rrm"
},
#endif
{SIOCIWFIRSTPRIV + 0x18, IW_PRIV_TYPE_CHAR | IFNAMSIZ , 0 , "rereg_nd_name"},
#ifdef CONFIG_MP_INCLUDED
{SIOCIWFIRSTPRIV + 0x1A, IW_PRIV_TYPE_CHAR | 1024, 0, "NULL"},
{SIOCIWFIRSTPRIV + 0x1B, IW_PRIV_TYPE_CHAR | 128, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "NULL"},
#else
{SIOCIWFIRSTPRIV + 0x1A, IW_PRIV_TYPE_CHAR | 1024, 0, "NULL"},
{SIOCIWFIRSTPRIV + 0x1B, IW_PRIV_TYPE_CHAR | 128, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get"},
#endif
{
SIOCIWFIRSTPRIV + 0x1D,
IW_PRIV_TYPE_CHAR | 40, IW_PRIV_TYPE_CHAR | 0x7FF, "test"
},
#ifdef CONFIG_INTEL_WIDI
{
SIOCIWFIRSTPRIV + 0x1E,
IW_PRIV_TYPE_CHAR | 1024, 0, "widi_set"
},
{
SIOCIWFIRSTPRIV + 0x1F,
IW_PRIV_TYPE_CHAR | 128, 0, "widi_prob_req"
},
#endif /* CONFIG_INTEL_WIDI */
{ SIOCIWFIRSTPRIV + 0x0E, IW_PRIV_TYPE_CHAR | 1024, 0 , ""}, /* set */
{ SIOCIWFIRSTPRIV + 0x0F, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , ""},/* get
* --- sub-ioctls definitions --- */
#ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
{ VENDOR_IE_SET, IW_PRIV_TYPE_CHAR | 1024 , 0 , "vendor_ie_set" },
{ VENDOR_IE_GET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "vendor_ie_get" },
#endif
#if defined(CONFIG_RTL8723B)
{ MP_SetBT, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_setbt" },
{ MP_DISABLE_BT_COEXIST, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_disa_btcoex"},
#endif
#ifdef CONFIG_WOWLAN
{ MP_WOW_ENABLE , IW_PRIV_TYPE_CHAR | 1024, 0, "wow_mode" },
{ MP_WOW_SET_PATTERN , IW_PRIV_TYPE_CHAR | 1024, 0, "wow_set_pattern" },
#endif
#ifdef CONFIG_AP_WOWLAN
{ MP_AP_WOW_ENABLE , IW_PRIV_TYPE_CHAR | 1024, 0, "ap_wow_mode" }, /* set */
#endif
#ifdef CONFIG_SDIO_INDIRECT_ACCESS
{ MP_SD_IREAD, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "sd_iread" },
{ MP_SD_IWRITE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "sd_iwrite" },
#endif
};
static const struct iw_priv_args rtw_mp_private_args[] = {
/* --- sub-ioctls definitions --- */
#ifdef CONFIG_MP_INCLUDED
{ MP_START , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_start" },
{ MP_PHYPARA, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_phypara" },
{ MP_STOP , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_stop" },
{ MP_CHANNEL , IW_PRIV_TYPE_CHAR | 1024 , IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_channel" },
{ MP_CHL_OFFSET , IW_PRIV_TYPE_CHAR | 1024 , IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ch_offset" },
{ MP_BANDWIDTH , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_bandwidth"},
{ MP_RATE , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate" },
{ MP_RESET_STATS , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_reset_stats"},
{ MP_QUERY , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , "mp_query"},
{ READ_REG , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_reg" },
{ MP_RATE , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate" },
{ READ_RF , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_rf" },
{ MP_PSD , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_psd"},
{ MP_DUMP, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_dump" },
{ MP_TXPOWER , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_txpower"},
{ MP_ANT_TX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_tx"},
{ MP_ANT_RX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_rx"},
{ WRITE_REG , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "write_reg" },
{ WRITE_RF , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "write_rf" },
{ MP_CTX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ctx"},
{ MP_ARX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_arx"},
{ MP_THER , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ther"},
{ EFUSE_SET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_set" },
{ EFUSE_GET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get" },
{ MP_PWRTRK , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_pwrtrk"},
{ MP_QueryDrvStats, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_drvquery" },
{ MP_IOCTL, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_ioctl"},
{ MP_SetRFPathSwh, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_setrfpath" },
{ MP_PwrCtlDM, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_pwrctldm" },
{ MP_GET_TXPOWER_INX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_get_txpower" },
{ MP_GETVER, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_priv_ver" },
{ MP_MON, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_mon" },
{ EFUSE_MASK, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_mask" },
{ EFUSE_FILE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_file" },
{ MP_TX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_tx" },
{ MP_RX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rx" },
{ MP_HW_TX_MODE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_hxtx" },
{ MP_PWRLMT, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_pwrlmt" },
{ MP_PWRBYRATE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_pwrbyrate" },
{ CTA_TEST, IW_PRIV_TYPE_CHAR | 1024, 0, "cta_test"},
{ MP_IQK, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_iqk"},
{ MP_LCK, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_lck"},
{ BT_EFUSE_FILE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "bt_efuse_file" },
{ MP_SWRFPath, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_swrfpath" },
#ifdef CONFIG_RTW_CUSTOMER_STR
{ MP_CUSTOMER_STR, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "customer_str" },
#endif
#endif /* CONFIG_MP_INCLUDED */
};
static iw_handler rtw_private_handler[] = {
rtw_wx_write32, /* 0x00 */
rtw_wx_read32, /* 0x01 */
NULL, /* 0x02 */
#ifdef MP_IOCTL_HDL
rtw_mp_ioctl_hdl, /* 0x03 */
#else
rtw_wx_priv_null,
#endif
/* for MM DTV platform */
rtw_get_ap_info, /* 0x04 */
rtw_set_pid, /* 0x05 */
rtw_wps_start, /* 0x06 */
/* for PLATFORM_MT53XX */
rtw_wx_get_sensitivity, /* 0x07 */
rtw_wx_set_mtk_wps_probe_ie, /* 0x08 */
rtw_wx_set_mtk_wps_ie, /* 0x09 */
/* for RTK_DMP_PLATFORM
* Set Channel depend on the country code */
rtw_wx_set_channel_plan, /* 0x0A */
rtw_dbg_port, /* 0x0B */
rtw_wx_write_rf, /* 0x0C */
rtw_wx_read_rf, /* 0x0D */
//rtw_priv_set, /*0x0E*/
//rtw_priv_get, /*0x0F*/
rtw_p2p_set, /* 0x10 */
rtw_p2p_get, /* 0x11 */
NULL, /* 0x12 */
rtw_p2p_get2, /* 0x13 */
rtw_tdls, /* 0x14 */
rtw_tdls_get, /* 0x15 */
rtw_pm_set, /* 0x16 */
#ifdef CONFIG_RTW_80211K
rtw_wx_priv_rrm, /* 0x17 */
#else
rtw_wx_priv_null, /* 0x17 */
#endif
rtw_rereg_nd_name, /* 0x18 */
rtw_wx_priv_null, /* 0x19 */
#ifdef CONFIG_MP_INCLUDED
rtw_wx_priv_null, /* 0x1A */
rtw_wx_priv_null, /* 0x1B */
#else
rtw_wx_priv_null, /* 0x1A */
rtw_mp_efuse_get, /* 0x1B */
#endif
NULL, /* 0x1C is reserved for hostapd */
rtw_test, /* 0x1D */
#ifdef CONFIG_INTEL_WIDI
rtw_widi_set, /* 0x1E */
rtw_widi_set_probe_request, /* 0x1F */
#endif /* CONFIG_INTEL_WIDI */
};
#if WIRELESS_EXT >= 17
static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev)
{
@ -11813,439 +11548,12 @@ static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev)
struct iw_handler_def rtw_handlers_def = {
.standard = rtw_handlers,
.num_standard = sizeof(rtw_handlers) / sizeof(iw_handler),
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33)) || defined(CONFIG_WEXT_PRIV)
.private = rtw_private_handler,
.private_args = (struct iw_priv_args *)rtw_private_args,
.num_private = sizeof(rtw_private_handler) / sizeof(iw_handler),
.num_private_args = sizeof(rtw_private_args) / sizeof(struct iw_priv_args),
#endif
#if WIRELESS_EXT >= 17
.get_wireless_stats = rtw_get_wireless_stats,
#endif
};
#endif
/* copy from net/wireless/wext.c start
* ----------------------------------------------------------------
*
* Calculate size of private arguments
*/
static const char iw_priv_type_size[] = {
0, /* IW_PRIV_TYPE_NONE */
1, /* IW_PRIV_TYPE_BYTE */
1, /* IW_PRIV_TYPE_CHAR */
0, /* Not defined */
sizeof(__u32), /* IW_PRIV_TYPE_INT */
sizeof(struct iw_freq), /* IW_PRIV_TYPE_FLOAT */
sizeof(struct sockaddr), /* IW_PRIV_TYPE_ADDR */
0, /* Not defined */
};
static int get_priv_size(__u16 args)
{
int num = args & IW_PRIV_SIZE_MASK;
int type = (args & IW_PRIV_TYPE_MASK) >> 12;
return num * iw_priv_type_size[type];
}
/* copy from net/wireless/wext.c end */
static int _rtw_ioctl_wext_private(struct net_device *dev, union iwreq_data *wrq_data)
{
int err = 0;
u8 *input = NULL;
u32 input_len = 0;
const char delim[] = " ";
u8 *output = NULL;
u32 output_len = 0;
u32 count = 0;
u8 *buffer = NULL;
u32 buffer_len = 0;
char *ptr = NULL;
u8 cmdname[17] = {0}; /* IFNAMSIZ+1 */
u32 cmdlen;
s32 len;
u8 *extra = NULL;
u32 extra_size = 0;
s32 k;
const iw_handler *priv; /* Private ioctl */
const struct iw_priv_args *priv_args; /* Private ioctl description */
const struct iw_priv_args *mp_priv_args; /*MP Private ioctl description */
const struct iw_priv_args *sel_priv_args; /*Selected Private ioctl description */
u32 num_priv; /* Number of ioctl */
u32 num_priv_args; /* Number of descriptions */
u32 num_mp_priv_args; /*Number of MP descriptions */
u32 num_sel_priv_args; /*Number of Selected descriptions */
iw_handler handler;
int temp;
int subcmd = 0; /* sub-ioctl index */
int offset = 0; /* Space for sub-ioctl index */
union iwreq_data wdata;
_rtw_memcpy(&wdata, wrq_data, sizeof(wdata));
input_len = wdata.data.length;
if (!input_len)
return -EINVAL;
input = rtw_zmalloc(input_len);
if (NULL == input)
return -ENOMEM;
if (copy_from_user(input, wdata.data.pointer, input_len)) {
err = -EFAULT;
goto exit;
}
input[input_len - 1] = '\0';
ptr = input;
len = input_len;
if (ptr == NULL) {
err = -EOPNOTSUPP;
goto exit;
}
sscanf(ptr, "%16s", cmdname);
cmdlen = strlen(cmdname);
RTW_INFO("%s: cmd=%s\n", __func__, cmdname);
/* skip command string */
if (cmdlen > 0)
cmdlen += 1; /* skip one space */
ptr += cmdlen;
len -= cmdlen;
RTW_INFO("%s: parameters=%s\n", __func__, ptr);
priv = rtw_private_handler;
priv_args = rtw_private_args;
mp_priv_args = rtw_mp_private_args;
num_priv = sizeof(rtw_private_handler) / sizeof(iw_handler);
num_priv_args = sizeof(rtw_private_args) / sizeof(struct iw_priv_args);
num_mp_priv_args = sizeof(rtw_mp_private_args) / sizeof(struct iw_priv_args);
if (num_priv_args == 0) {
err = -EOPNOTSUPP;
goto exit;
}
/* Search the correct ioctl */
k = -1;
sel_priv_args = priv_args;
num_sel_priv_args = num_priv_args;
while
((++k < num_sel_priv_args) && strcmp(sel_priv_args[k].name, cmdname))
;
/* If not found... */
if (k == num_sel_priv_args) {
k = -1;
sel_priv_args = mp_priv_args;
num_sel_priv_args = num_mp_priv_args;
while
((++k < num_sel_priv_args) && strcmp(sel_priv_args[k].name, cmdname))
;
if (k == num_sel_priv_args) {
err = -EOPNOTSUPP;
goto exit;
}
}
/* Watch out for sub-ioctls ! */
if (sel_priv_args[k].cmd < SIOCDEVPRIVATE) {
int j = -1;
/* Find the matching *real* ioctl */
while ((++j < num_priv_args) && ((priv_args[j].name[0] != '\0') ||
(priv_args[j].set_args != sel_priv_args[k].set_args) ||
(priv_args[j].get_args != sel_priv_args[k].get_args)))
;
/* If not found... */
if (j == num_priv_args) {
err = -EINVAL;
goto exit;
}
/* Save sub-ioctl number */
subcmd = sel_priv_args[k].cmd;
/* Reserve one int (simplify alignment issues) */
offset = sizeof(__u32);
/* Use real ioctl definition from now on */
k = j;
}
buffer = rtw_zmalloc(4096);
if (NULL == buffer) {
err = -ENOMEM;
goto exit;
}
if (k >= num_priv_args) {
err = -EINVAL;
goto exit;
}
/* If we have to set some data */
if ((priv_args[k].set_args & IW_PRIV_TYPE_MASK) &&
(priv_args[k].set_args & IW_PRIV_SIZE_MASK)) {
u8 *str;
switch (priv_args[k].set_args & IW_PRIV_TYPE_MASK) {
case IW_PRIV_TYPE_BYTE:
/* Fetch args */
count = 0;
do {
str = strsep(&ptr, delim);
if (NULL == str)
break;
sscanf(str, "%i", &temp);
buffer[count++] = (u8)temp;
} while (1);
buffer_len = count;
/* Number of args to fetch */
wdata.data.length = count;
if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
break;
case IW_PRIV_TYPE_INT:
/* Fetch args */
count = 0;
do {
str = strsep(&ptr, delim);
if (NULL == str)
break;
sscanf(str, "%i", &temp);
((s32 *)buffer)[count++] = (s32)temp;
} while (1);
buffer_len = count * sizeof(s32);
/* Number of args to fetch */
wdata.data.length = count;
if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
break;
case IW_PRIV_TYPE_CHAR:
if (len > 0) {
/* Size of the string to fetch */
wdata.data.length = len;
if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
/* Fetch string */
_rtw_memcpy(buffer, ptr, wdata.data.length);
} else {
wdata.data.length = 1;
buffer[0] = '\0';
}
buffer_len = wdata.data.length;
break;
default:
RTW_INFO("%s: Not yet implemented...\n", __func__);
err = -1;
goto exit;
}
if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
(wdata.data.length != (priv_args[k].set_args & IW_PRIV_SIZE_MASK))) {
RTW_INFO("%s: The command %s needs exactly %d argument(s)...\n",
__func__, cmdname, priv_args[k].set_args & IW_PRIV_SIZE_MASK);
err = -EINVAL;
goto exit;
}
} /* if args to set */
else
wdata.data.length = 0L;
/* Those two tests are important. They define how the driver
* will have to handle the data */
if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
((get_priv_size(priv_args[k].set_args) + offset) <= IFNAMSIZ)) {
/* First case : all SET args fit within wrq */
if (offset)
wdata.mode = subcmd;
_rtw_memcpy(wdata.name + offset, buffer, IFNAMSIZ - offset);
} else {
if ((priv_args[k].set_args == 0) &&
(priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
(get_priv_size(priv_args[k].get_args) <= IFNAMSIZ)) {
/* Second case : no SET args, GET args fit within wrq */
if (offset)
wdata.mode = subcmd;
} else {
/* Third case : args won't fit in wrq, or variable number of args */
if (copy_to_user(wdata.data.pointer, buffer, buffer_len)) {
err = -EFAULT;
goto exit;
}
wdata.data.flags = subcmd;
}
}
rtw_mfree(input, input_len);
input = NULL;
extra_size = 0;
if (IW_IS_SET(priv_args[k].cmd)) {
/* Size of set arguments */
extra_size = get_priv_size(priv_args[k].set_args);
/* Does it fits in iwr ? */
if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
((extra_size + offset) <= IFNAMSIZ))
extra_size = 0;
} else {
/* Size of get arguments */
extra_size = get_priv_size(priv_args[k].get_args);
/* Does it fits in iwr ? */
if ((priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
(extra_size <= IFNAMSIZ))
extra_size = 0;
}
if (extra_size == 0) {
extra = (u8 *)&wdata;
rtw_mfree(buffer, 4096);
buffer = NULL;
} else
extra = buffer;
handler = priv[priv_args[k].cmd - SIOCIWFIRSTPRIV];
err = handler(dev, NULL, &wdata, extra);
/* If we have to get some data */
if ((priv_args[k].get_args & IW_PRIV_TYPE_MASK) &&
(priv_args[k].get_args & IW_PRIV_SIZE_MASK)) {
int j;
int n = 0; /* number of args */
u8 str[20] = {0};
/* Check where is the returned data */
if ((priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
(get_priv_size(priv_args[k].get_args) <= IFNAMSIZ))
n = priv_args[k].get_args & IW_PRIV_SIZE_MASK;
else
n = wdata.data.length;
output = rtw_zmalloc(4096);
if (NULL == output) {
err = -ENOMEM;
goto exit;
}
switch (priv_args[k].get_args & IW_PRIV_TYPE_MASK) {
case IW_PRIV_TYPE_BYTE:
/* Display args */
for (j = 0; j < n; j++) {
sprintf(str, "%d ", extra[j]);
len = strlen(str);
output_len = strlen(output);
if ((output_len + len + 1) > 4096) {
err = -E2BIG;
goto exit;
}
_rtw_memcpy(output + output_len, str, len);
}
break;
case IW_PRIV_TYPE_INT:
/* Display args */
for (j = 0; j < n; j++) {
sprintf(str, "%d ", ((__s32 *)extra)[j]);
len = strlen(str);
output_len = strlen(output);
if ((output_len + len + 1) > 4096) {
err = -E2BIG;
goto exit;
}
_rtw_memcpy(output + output_len, str, len);
}
break;
case IW_PRIV_TYPE_CHAR:
/* Display args */
_rtw_memcpy(output, extra, n);
break;
default:
RTW_INFO("%s: Not yet implemented...\n", __func__);
err = -1;
goto exit;
}
output_len = strlen(output) + 1;
wrq_data->data.length = output_len;
if (copy_to_user(wrq_data->data.pointer, output, output_len)) {
err = -EFAULT;
goto exit;
}
} /* if args to set */
else
wrq_data->data.length = 0;
exit:
if (input)
rtw_mfree(input, input_len);
if (buffer)
rtw_mfree(buffer, 4096);
if (output)
rtw_mfree(output, 4096);
return err;
}
#ifdef CONFIG_COMPAT
static int rtw_ioctl_compat_wext_private(struct net_device *dev, struct ifreq *rq)
{
struct compat_iw_point iwp_compat;
union iwreq_data wrq_data;
int err = 0;
RTW_INFO("%s:...\n", __func__);
if (copy_from_user(&iwp_compat, rq->ifr_ifru.ifru_data, sizeof(struct compat_iw_point)))
return -EFAULT;
wrq_data.data.pointer = compat_ptr(iwp_compat.pointer);
wrq_data.data.length = iwp_compat.length;
wrq_data.data.flags = iwp_compat.flags;
err = _rtw_ioctl_wext_private(dev, &wrq_data);
iwp_compat.pointer = ptr_to_compat(wrq_data.data.pointer);
iwp_compat.length = wrq_data.data.length;
iwp_compat.flags = wrq_data.data.flags;
if (copy_to_user(rq->ifr_ifru.ifru_data, &iwp_compat, sizeof(struct compat_iw_point)))
return -EFAULT;
return err;
}
#endif /* CONFIG_COMPAT */
static int rtw_ioctl_standard_wext_private(struct net_device *dev, struct ifreq *rq)
{
struct iw_point *iwp;
union iwreq_data wrq_data;
int err = 0;
iwp = &wrq_data.data;
RTW_INFO("%s:...\n", __func__);
if (copy_from_user(iwp, rq->ifr_ifru.ifru_data, sizeof(struct iw_point)))
return -EFAULT;
err = _rtw_ioctl_wext_private(dev, &wrq_data);
if (copy_to_user(rq->ifr_ifru.ifru_data, iwp, sizeof(struct iw_point)))
return -EFAULT;
return err;
}
int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
struct iwreq *wrq = (struct iwreq *)rq;