* Re: libertas (private) ioctls vs. nl80211 [not found] <1181757483.29767.99.camel@johannes.berg> @ 2007-06-14 17:09 ` Christoph Hellwig 2007-06-14 17:38 ` Andrew Morton 2007-06-14 20:03 ` Holger Schurig 0 siblings, 2 replies; 17+ messages in thread From: Christoph Hellwig @ 2007-06-14 17:09 UTC (permalink / raw) To: Johannes Berg Cc: linux-wireless, Dan Williams, Holger Schurig, akpm, linux-kernel Independent of any nl80211 status the private libertas ioctls have to go. Not only don't we want private ioctls for mesh networking but rather have it as driver-independent interface, but the actual libertas interface is the worst possible choice. It uses the absolutely broken iwpriv interface instead of plain ioctls, and has a cmpletely confusing forest of sub ioctls. I strongly recommend ripping out all the ioctls for 2.6.22 and waiting for a proper interface to appear. The olpc people can patch the ioctls back in for their use, but we should not put in interface like this into the upstream kernel. All NIC vendors get pushed back badly when they try to put in less crappy ioctls, there is no reason to make a exception for libtertas just because it's used by a project that some of the involved maintainers like a lot. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: libertas (private) ioctls vs. nl80211 2007-06-14 17:09 ` libertas (private) ioctls vs. nl80211 Christoph Hellwig @ 2007-06-14 17:38 ` Andrew Morton 2007-06-14 18:13 ` Christoph Hellwig 2007-06-14 20:03 ` Holger Schurig 1 sibling, 1 reply; 17+ messages in thread From: Andrew Morton @ 2007-06-14 17:38 UTC (permalink / raw) To: Christoph Hellwig Cc: johannes, linux-wireless, dcbw, hs4233, linux-kernel, Linus Torvalds > On Thu, 14 Jun 2007 18:09:01 +0100 Christoph Hellwig <hch@infradead.org> wrote: > Independent of any nl80211 status the private libertas ioctls have to > go. Not only don't we want private ioctls for mesh networking but rather > have it as driver-independent interface, but the actual libertas interface > is the worst possible choice. It uses the absolutely broken iwpriv interface > instead of plain ioctls, and has a cmpletely confusing forest of sub ioctls. > > I strongly recommend ripping out all the ioctls for 2.6.22 and waiting for > a proper interface to appear. If we're going to change the interface in the future (and it sounds like we should) then yes, we should strenuously avoid releasing the current interface in 2.6.22. > The olpc people can patch the ioctls back > in for their use, but we should not put in interface like this into the > upstream kernel. All NIC vendors get pushed back badly when they try > to put in less crappy ioctls, there is no reason to make a exception for > libtertas just because it's used by a project that some of the involved > maintainers like a lot. I suspect that the probability of your proposal succeeding would be increased if you could prepare a patch... ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: libertas (private) ioctls vs. nl80211 2007-06-14 17:38 ` Andrew Morton @ 2007-06-14 18:13 ` Christoph Hellwig 2007-06-14 18:23 ` Linus Torvalds 2007-06-18 17:38 ` Dan Williams 0 siblings, 2 replies; 17+ messages in thread From: Christoph Hellwig @ 2007-06-14 18:13 UTC (permalink / raw) To: Andrew Morton Cc: Christoph Hellwig, johannes, linux-wireless, dcbw, hs4233, linux-kernel, Linus Torvalds > I suspect that the probability of your proposal succeeding would be increased > if you could prepare a patch... Here we go: Index: linux-2.6/drivers/net/wireless/libertas/Makefile =================================================================== --- linux-2.6.orig/drivers/net/wireless/libertas/Makefile 2007-06-14 18:53:57.000000000 +0200 +++ linux-2.6/drivers/net/wireless/libertas/Makefile 2007-06-14 18:54:01.000000000 +0200 @@ -2,7 +2,7 @@ libertas-objs := main.o fw.o wext.o \ rx.o tx.o cmd.o \ cmdresp.o scan.o \ join.o 11d.o \ - ioctl.o debugfs.o \ + debugfs.o \ ethtool.o assoc.o usb8xxx-objs += if_bootcmd.o Index: linux-2.6/drivers/net/wireless/libertas/ioctl.c =================================================================== --- linux-2.6.orig/drivers/net/wireless/libertas/ioctl.c 2007-06-14 18:48:47.000000000 +0200 +++ /dev/null 1970-01-01 00:00:00.000000000 +0000 @@ -1,1081 +0,0 @@ -/** - * This file contains ioctl functions - */ - -#include <linux/ctype.h> -#include <linux/delay.h> -#include <linux/if.h> -#include <linux/if_arp.h> -#include <linux/wireless.h> - -#include <net/iw_handler.h> -#include <net/ieee80211.h> - -#include "host.h" -#include "radiotap.h" -#include "decl.h" -#include "defs.h" -#include "dev.h" -#include "join.h" -#include "wext.h" - -#define MAX_SCAN_CELL_SIZE (IW_EV_ADDR_LEN + \ - IW_ESSID_MAX_SIZE + \ - IW_EV_UINT_LEN + IW_EV_FREQ_LEN + \ - IW_EV_QUAL_LEN + IW_ESSID_MAX_SIZE + \ - IW_EV_PARAM_LEN + 40) /* 40 for WPAIE */ - -#define WAIT_FOR_SCAN_RRESULT_MAX_TIME (10 * HZ) - -static int wlan_set_region(wlan_private * priv, u16 region_code) -{ - int i; - int ret = 0; - - for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) { - // use the region code to search for the index - if (region_code == libertas_region_code_to_index[i]) { - priv->adapter->regiontableindex = (u16) i; - priv->adapter->regioncode = region_code; - break; - } - } - - // if it's unidentified region code - if (i >= MRVDRV_MAX_REGION_CODE) { - lbs_deb_ioctl("region Code not identified\n"); - ret = -1; - goto done; - } - - if (libertas_set_regiontable(priv, priv->adapter->regioncode, 0)) { - ret = -EINVAL; - } - -done: - lbs_deb_leave_args(LBS_DEB_IOCTL, "ret %d", ret); - return ret; -} - -static inline int hex2int(char c) -{ - if (c >= '0' && c <= '9') - return (c - '0'); - if (c >= 'a' && c <= 'f') - return (c - 'a' + 10); - if (c >= 'A' && c <= 'F') - return (c - 'A' + 10); - return -1; -} - -/* Convert a string representation of a MAC address ("xx:xx:xx:xx:xx:xx") - into binary format (6 bytes). - - This function expects that each byte is represented with 2 characters - (e.g., 11:2:11:11:11:11 is invalid) - - */ -static char *eth_str2addr(char *ethstr, u8 * addr) -{ - int i, val, val2; - char *pos = ethstr; - - /* get rid of initial blanks */ - while (*pos == ' ' || *pos == '\t') - ++pos; - - for (i = 0; i < 6; i++) { - val = hex2int(*pos++); - if (val < 0) - return NULL; - val2 = hex2int(*pos++); - if (val2 < 0) - return NULL; - addr[i] = (val * 16 + val2) & 0xff; - - if (i < 5 && *pos++ != ':') - return NULL; - } - return pos; -} - -/* this writes xx:xx:xx:xx:xx:xx into ethstr - (ethstr must have space for 18 chars) */ -static int eth_addr2str(u8 * addr, char *ethstr) -{ - int i; - char *pos = ethstr; - - for (i = 0; i < 6; i++) { - sprintf(pos, "%02x", addr[i] & 0xff); - pos += 2; - if (i < 5) - *pos++ = ':'; - } - return 17; -} - -/** - * @brief Add an entry to the BT table - * @param priv A pointer to wlan_private structure - * @param req A pointer to ifreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_bt_add_ioctl(wlan_private * priv, struct ifreq *req) -{ - struct iwreq *wrq = (struct iwreq *)req; - char ethaddrs_str[18]; - char *pos; - u8 ethaddr[ETH_ALEN]; - int ret; - - lbs_deb_enter(LBS_DEB_IOCTL); - - if (copy_from_user(ethaddrs_str, wrq->u.data.pointer, - sizeof(ethaddrs_str))) - return -EFAULT; - - if ((pos = eth_str2addr(ethaddrs_str, ethaddr)) == NULL) { - lbs_pr_info("BT_ADD: Invalid MAC address\n"); - return -EINVAL; - } - - lbs_deb_ioctl("BT: adding %s\n", ethaddrs_str); - ret = libertas_prepare_and_send_command(priv, cmd_bt_access, - cmd_act_bt_access_add, - cmd_option_waitforrsp, 0, ethaddr); - lbs_deb_leave_args(LBS_DEB_IOCTL, "ret %d", ret); - return ret; -} - -/** - * @brief Delete an entry from the BT table - * @param priv A pointer to wlan_private structure - * @param req A pointer to ifreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_bt_del_ioctl(wlan_private * priv, struct ifreq *req) -{ - struct iwreq *wrq = (struct iwreq *)req; - char ethaddrs_str[18]; - u8 ethaddr[ETH_ALEN]; - char *pos; - - lbs_deb_enter(LBS_DEB_IOCTL); - - if (copy_from_user(ethaddrs_str, wrq->u.data.pointer, - sizeof(ethaddrs_str))) - return -EFAULT; - - if ((pos = eth_str2addr(ethaddrs_str, ethaddr)) == NULL) { - lbs_pr_info("Invalid MAC address\n"); - return -EINVAL; - } - - lbs_deb_ioctl("BT: deleting %s\n", ethaddrs_str); - - return (libertas_prepare_and_send_command(priv, - cmd_bt_access, - cmd_act_bt_access_del, - cmd_option_waitforrsp, 0, ethaddr)); - - lbs_deb_leave(LBS_DEB_IOCTL); - return 0; -} - -/** - * @brief Reset all entries from the BT table - * @param priv A pointer to wlan_private structure - * @return 0 --success, otherwise fail - */ -static int wlan_bt_reset_ioctl(wlan_private * priv) -{ - lbs_deb_enter(LBS_DEB_IOCTL); - - lbs_pr_alert( "BT: resetting\n"); - - return (libertas_prepare_and_send_command(priv, - cmd_bt_access, - cmd_act_bt_access_reset, - cmd_option_waitforrsp, 0, NULL)); - - lbs_deb_leave(LBS_DEB_IOCTL); - return 0; -} - -/** - * @brief List an entry from the BT table - * @param priv A pointer to wlan_private structure - * @param req A pointer to ifreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_bt_list_ioctl(wlan_private * priv, struct ifreq *req) -{ - int pos; - char *addr1; - struct iwreq *wrq = (struct iwreq *)req; - /* used to pass id and store the bt entry returned by the FW */ - union { - u32 id; - char addr1addr2[2 * ETH_ALEN]; - } param; - static char outstr[64]; - char *pbuf = outstr; - int ret; - - lbs_deb_enter(LBS_DEB_IOCTL); - - if (copy_from_user(outstr, wrq->u.data.pointer, sizeof(outstr))) { - lbs_deb_ioctl("Copy from user failed\n"); - return -1; - } - param.id = simple_strtoul(outstr, NULL, 10); - pos = sprintf(pbuf, "%d: ", param.id); - pbuf += pos; - - ret = libertas_prepare_and_send_command(priv, cmd_bt_access, - cmd_act_bt_access_list, - cmd_option_waitforrsp, 0, - (char *)¶m); - - if (ret == 0) { - addr1 = param.addr1addr2; - - pos = sprintf(pbuf, "BT includes node "); - pbuf += pos; - pos = eth_addr2str(addr1, pbuf); - pbuf += pos; - } else { - sprintf(pbuf, "(null)"); - pbuf += pos; - } - - wrq->u.data.length = strlen(outstr); - if (copy_to_user(wrq->u.data.pointer, (char *)outstr, - wrq->u.data.length)) { - lbs_deb_ioctl("BT_LIST: Copy to user failed!\n"); - return -EFAULT; - } - - lbs_deb_leave(LBS_DEB_IOCTL); - return 0 ; -} - -/** - * @brief Sets inverted state of blacklist (non-zero if inverted) - * @param priv A pointer to wlan_private structure - * @param req A pointer to ifreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_bt_set_invert_ioctl(wlan_private * priv, struct ifreq *req) -{ - int ret; - struct iwreq *wrq = (struct iwreq *)req; - union { - u32 id; - char addr1addr2[2 * ETH_ALEN]; - } param; - - lbs_deb_enter(LBS_DEB_IOCTL); - - param.id = SUBCMD_DATA(wrq) ; - ret = libertas_prepare_and_send_command(priv, cmd_bt_access, - cmd_act_bt_access_set_invert, - cmd_option_waitforrsp, 0, - (char *)¶m); - if (ret != 0) - return -EFAULT; - lbs_deb_leave(LBS_DEB_IOCTL); - return 0; -} - -/** - * @brief Gets inverted state of blacklist (non-zero if inverted) - * @param priv A pointer to wlan_private structure - * @param req A pointer to ifreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_bt_get_invert_ioctl(wlan_private * priv, struct ifreq *req) -{ - struct iwreq *wrq = (struct iwreq *)req; - int ret; - union { - u32 id; - char addr1addr2[2 * ETH_ALEN]; - } param; - - lbs_deb_enter(LBS_DEB_IOCTL); - - ret = libertas_prepare_and_send_command(priv, cmd_bt_access, - cmd_act_bt_access_get_invert, - cmd_option_waitforrsp, 0, - (char *)¶m); - - if (ret == 0) - wrq->u.param.value = le32_to_cpu(param.id); - else - return -EFAULT; - - lbs_deb_leave(LBS_DEB_IOCTL); - return 0; -} - -/** - * @brief Find the next parameter in an input string - * @param ptr A pointer to the input parameter string - * @return A pointer to the next parameter, or 0 if no parameters left. - */ -static char * next_param(char * ptr) -{ - if (!ptr) return NULL; - while (*ptr == ' ' || *ptr == '\t') ++ptr; - return (*ptr == '\0') ? NULL : ptr; -} - -/** - * @brief Add an entry to the FWT table - * @param priv A pointer to wlan_private structure - * @param req A pointer to ifreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_fwt_add_ioctl(wlan_private * priv, struct ifreq *req) -{ - struct iwreq *wrq = (struct iwreq *)req; - char in_str[128]; - static struct cmd_ds_fwt_access fwt_access; - char *ptr; - int ret; - - lbs_deb_enter(LBS_DEB_IOCTL); - - if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str))) - return -EFAULT; - - if ((ptr = eth_str2addr(in_str, fwt_access.da)) == NULL) { - lbs_pr_alert( "FWT_ADD: Invalid MAC address 1\n"); - return -EINVAL; - } - - if ((ptr = eth_str2addr(ptr, fwt_access.ra)) == NULL) { - lbs_pr_alert( "FWT_ADD: Invalid MAC address 2\n"); - return -EINVAL; - } - - if ((ptr = next_param(ptr))) - fwt_access.metric = - cpu_to_le32(simple_strtoul(ptr, &ptr, 10)); - else - fwt_access.metric = cpu_to_le32(FWT_DEFAULT_METRIC); - - if ((ptr = next_param(ptr))) - fwt_access.dir = (u8)simple_strtoul(ptr, &ptr, 10); - else - fwt_access.dir = FWT_DEFAULT_DIR; - - if ((ptr = next_param(ptr))) - fwt_access.rate = (u8) simple_strtoul(ptr, &ptr, 10); - else - fwt_access.rate = FWT_DEFAULT_RATE; - - if ((ptr = next_param(ptr))) - fwt_access.ssn = - cpu_to_le32(simple_strtoul(ptr, &ptr, 10)); - else - fwt_access.ssn = cpu_to_le32(FWT_DEFAULT_SSN); - - if ((ptr = next_param(ptr))) - fwt_access.dsn = - cpu_to_le32(simple_strtoul(ptr, &ptr, 10)); - else - fwt_access.dsn = cpu_to_le32(FWT_DEFAULT_DSN); - - if ((ptr = next_param(ptr))) - fwt_access.hopcount = simple_strtoul(ptr, &ptr, 10); - else - fwt_access.hopcount = FWT_DEFAULT_HOPCOUNT; - - if ((ptr = next_param(ptr))) - fwt_access.ttl = simple_strtoul(ptr, &ptr, 10); - else - fwt_access.ttl = FWT_DEFAULT_TTL; - - if ((ptr = next_param(ptr))) - fwt_access.expiration = - cpu_to_le32(simple_strtoul(ptr, &ptr, 10)); - else - fwt_access.expiration = cpu_to_le32(FWT_DEFAULT_EXPIRATION); - - if ((ptr = next_param(ptr))) - fwt_access.sleepmode = (u8)simple_strtoul(ptr, &ptr, 10); - else - fwt_access.sleepmode = FWT_DEFAULT_SLEEPMODE; - - if ((ptr = next_param(ptr))) - fwt_access.snr = - cpu_to_le32(simple_strtoul(ptr, &ptr, 10)); - else - fwt_access.snr = cpu_to_le32(FWT_DEFAULT_SNR); - -#ifdef DEBUG - { - char ethaddr1_str[18], ethaddr2_str[18]; - eth_addr2str(fwt_access.da, ethaddr1_str); - eth_addr2str(fwt_access.ra, ethaddr2_str); - lbs_deb_ioctl("FWT_ADD: adding (da:%s,%i,ra:%s)\n", ethaddr1_str, - fwt_access.dir, ethaddr2_str); - lbs_deb_ioctl("FWT_ADD: ssn:%u dsn:%u met:%u hop:%u ttl:%u exp:%u slp:%u snr:%u\n", - fwt_access.ssn, fwt_access.dsn, fwt_access.metric, - fwt_access.hopcount, fwt_access.ttl, fwt_access.expiration, - fwt_access.sleepmode, fwt_access.snr); - } -#endif - - ret = libertas_prepare_and_send_command(priv, cmd_fwt_access, - cmd_act_fwt_access_add, - cmd_option_waitforrsp, 0, - (void *)&fwt_access); - - lbs_deb_leave_args(LBS_DEB_IOCTL, "ret %d", ret); - return ret; -} - -/** - * @brief Delete an entry from the FWT table - * @param priv A pointer to wlan_private structure - * @param req A pointer to ifreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_fwt_del_ioctl(wlan_private * priv, struct ifreq *req) -{ - struct iwreq *wrq = (struct iwreq *)req; - char in_str[64]; - static struct cmd_ds_fwt_access fwt_access; - char *ptr; - int ret; - - lbs_deb_enter(LBS_DEB_IOCTL); - - if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str))) - return -EFAULT; - - if ((ptr = eth_str2addr(in_str, fwt_access.da)) == NULL) { - lbs_pr_alert( "FWT_DEL: Invalid MAC address 1\n"); - return -EINVAL; - } - - if ((ptr = eth_str2addr(ptr, fwt_access.ra)) == NULL) { - lbs_pr_alert( "FWT_DEL: Invalid MAC address 2\n"); - return -EINVAL; - } - - if ((ptr = next_param(ptr))) - fwt_access.dir = (u8)simple_strtoul(ptr, &ptr, 10); - else - fwt_access.dir = FWT_DEFAULT_DIR; - -#ifdef DEBUG - { - char ethaddr1_str[18], ethaddr2_str[18]; - lbs_deb_ioctl("FWT_DEL: line is %s\n", in_str); - eth_addr2str(fwt_access.da, ethaddr1_str); - eth_addr2str(fwt_access.ra, ethaddr2_str); - lbs_deb_ioctl("FWT_DEL: removing (da:%s,ra:%s,dir:%d)\n", ethaddr1_str, - ethaddr2_str, fwt_access.dir); - } -#endif - - ret = libertas_prepare_and_send_command(priv, - cmd_fwt_access, - cmd_act_fwt_access_del, - cmd_option_waitforrsp, 0, - (void *)&fwt_access); - lbs_deb_leave_args(LBS_DEB_IOCTL, "ret %d", ret); - return ret; -} - - -/** - * @brief Print route parameters - * @param fwt_access struct cmd_ds_fwt_access with route info - * @param buf destination buffer for route info - */ -static void print_route(struct cmd_ds_fwt_access fwt_access, char *buf) -{ - buf += sprintf(buf, " "); - buf += eth_addr2str(fwt_access.da, buf); - buf += sprintf(buf, " "); - buf += eth_addr2str(fwt_access.ra, buf); - buf += sprintf(buf, " %u", fwt_access.valid); - buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.metric)); - buf += sprintf(buf, " %u", fwt_access.dir); - buf += sprintf(buf, " %u", fwt_access.rate); - buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.ssn)); - buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.dsn)); - buf += sprintf(buf, " %u", fwt_access.hopcount); - buf += sprintf(buf, " %u", fwt_access.ttl); - buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.expiration)); - buf += sprintf(buf, " %u", fwt_access.sleepmode); - buf += sprintf(buf, " %u ", le32_to_cpu(fwt_access.snr)); - buf += eth_addr2str(fwt_access.prec, buf); -} - -/** - * @brief Lookup an entry in the FWT table - * @param priv A pointer to wlan_private structure - * @param req A pointer to ifreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_fwt_lookup_ioctl(wlan_private * priv, struct ifreq *req) -{ - struct iwreq *wrq = (struct iwreq *)req; - char in_str[64]; - char *ptr; - static struct cmd_ds_fwt_access fwt_access; - static char out_str[128]; - int ret; - - lbs_deb_enter(LBS_DEB_IOCTL); - - if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str))) - return -EFAULT; - - if ((ptr = eth_str2addr(in_str, fwt_access.da)) == NULL) { - lbs_pr_alert( "FWT_LOOKUP: Invalid MAC address\n"); - return -EINVAL; - } - -#ifdef DEBUG - { - char ethaddr1_str[18]; - lbs_deb_ioctl("FWT_LOOKUP: line is %s\n", in_str); - eth_addr2str(fwt_access.da, ethaddr1_str); - lbs_deb_ioctl("FWT_LOOKUP: looking for (da:%s)\n", ethaddr1_str); - } -#endif - - ret = libertas_prepare_and_send_command(priv, - cmd_fwt_access, - cmd_act_fwt_access_lookup, - cmd_option_waitforrsp, 0, - (void *)&fwt_access); - - if (ret == 0) - print_route(fwt_access, out_str); - else - sprintf(out_str, "(null)"); - - wrq->u.data.length = strlen(out_str); - if (copy_to_user(wrq->u.data.pointer, (char *)out_str, - wrq->u.data.length)) { - lbs_deb_ioctl("FWT_LOOKUP: Copy to user failed!\n"); - return -EFAULT; - } - - lbs_deb_leave(LBS_DEB_IOCTL); - return 0; -} - -/** - * @brief Reset all entries from the FWT table - * @param priv A pointer to wlan_private structure - * @return 0 --success, otherwise fail - */ -static int wlan_fwt_reset_ioctl(wlan_private * priv) -{ - lbs_deb_ioctl("FWT: resetting\n"); - - return (libertas_prepare_and_send_command(priv, - cmd_fwt_access, - cmd_act_fwt_access_reset, - cmd_option_waitforrsp, 0, NULL)); -} - -/** - * @brief List an entry from the FWT table - * @param priv A pointer to wlan_private structure - * @param req A pointer to ifreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_fwt_list_ioctl(wlan_private * priv, struct ifreq *req) -{ - struct iwreq *wrq = (struct iwreq *)req; - char in_str[8]; - static struct cmd_ds_fwt_access fwt_access; - char *ptr = in_str; - static char out_str[128]; - char *pbuf = out_str; - int ret = 0; - - lbs_deb_enter(LBS_DEB_IOCTL); - - if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str))) { - ret = -EFAULT; - goto out; - } - - fwt_access.id = cpu_to_le32(simple_strtoul(ptr, &ptr, 10)); - -#ifdef DEBUG - { - lbs_deb_ioctl("FWT_LIST: line is %s\n", in_str); - lbs_deb_ioctl("FWT_LIST: listing id:%i\n", le32_to_cpu(fwt_access.id)); - } -#endif - - ret = libertas_prepare_and_send_command(priv, cmd_fwt_access, - cmd_act_fwt_access_list, - cmd_option_waitforrsp, 0, (void *)&fwt_access); - - if (ret == 0) - print_route(fwt_access, pbuf); - else - pbuf += sprintf(pbuf, " (null)"); - - wrq->u.data.length = strlen(out_str); - if (copy_to_user(wrq->u.data.pointer, (char *)out_str, - wrq->u.data.length)) { - lbs_deb_ioctl("FWT_LIST: Copy to user failed!\n"); - ret = -EFAULT; - goto out; - } - - ret = 0; - -out: - lbs_deb_leave(LBS_DEB_IOCTL); - return ret; -} - -/** - * @brief List an entry from the FRT table - * @param priv A pointer to wlan_private structure - * @param req A pointer to ifreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_fwt_list_route_ioctl(wlan_private * priv, struct ifreq *req) -{ - struct iwreq *wrq = (struct iwreq *)req; - char in_str[64]; - static struct cmd_ds_fwt_access fwt_access; - char *ptr = in_str; - static char out_str[128]; - char *pbuf = out_str; - int ret; - - lbs_deb_enter(LBS_DEB_IOCTL); - - if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str))) - return -EFAULT; - - fwt_access.id = cpu_to_le32(simple_strtoul(ptr, &ptr, 10)); - -#ifdef DEBUG - { - lbs_deb_ioctl("FWT_LIST_ROUTE: line is %s\n", in_str); - lbs_deb_ioctl("FWT_LIST_ROUTE: listing id:%i\n", le32_to_cpu(fwt_access.id)); - } -#endif - - ret = libertas_prepare_and_send_command(priv, cmd_fwt_access, - cmd_act_fwt_access_list_route, - cmd_option_waitforrsp, 0, (void *)&fwt_access); - - if (ret == 0) { - print_route(fwt_access, pbuf); - } else - pbuf += sprintf(pbuf, " (null)"); - - wrq->u.data.length = strlen(out_str); - if (copy_to_user(wrq->u.data.pointer, (char *)out_str, - wrq->u.data.length)) { - lbs_deb_ioctl("FWT_LIST_ROUTE: Copy to user failed!\n"); - return -EFAULT; - } - - lbs_deb_leave(LBS_DEB_IOCTL); - return 0; -} - -/** - * @brief List an entry from the FNT table - * @param priv A pointer to wlan_private structure - * @param req A pointer to ifreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_fwt_list_neighbor_ioctl(wlan_private * priv, struct ifreq *req) -{ - struct iwreq *wrq = (struct iwreq *)req; - char in_str[8]; - static struct cmd_ds_fwt_access fwt_access; - char *ptr = in_str; - static char out_str[128]; - char *pbuf = out_str; - int ret; - - lbs_deb_enter(LBS_DEB_IOCTL); - - if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str))) - return -EFAULT; - - memset(&fwt_access, 0, sizeof(fwt_access)); - fwt_access.id = cpu_to_le32(simple_strtoul(ptr, &ptr, 10)); - -#ifdef DEBUG - { - lbs_deb_ioctl("FWT_LIST_NEIGHBOR: line is %s\n", in_str); - lbs_deb_ioctl("FWT_LIST_NEIGHBOR: listing id:%i\n", le32_to_cpu(fwt_access.id)); - } -#endif - - ret = libertas_prepare_and_send_command(priv, cmd_fwt_access, - cmd_act_fwt_access_list_neighbor, - cmd_option_waitforrsp, 0, - (void *)&fwt_access); - - if (ret == 0) { - pbuf += sprintf(pbuf, " ra "); - pbuf += eth_addr2str(fwt_access.ra, pbuf); - pbuf += sprintf(pbuf, " slp %u", fwt_access.sleepmode); - pbuf += sprintf(pbuf, " snr %u", le32_to_cpu(fwt_access.snr)); - pbuf += sprintf(pbuf, " ref %u", le32_to_cpu(fwt_access.references)); - } else - pbuf += sprintf(pbuf, " (null)"); - - wrq->u.data.length = strlen(out_str); - if (copy_to_user(wrq->u.data.pointer, (char *)out_str, - wrq->u.data.length)) { - lbs_deb_ioctl("FWT_LIST_NEIGHBOR: Copy to user failed!\n"); - return -EFAULT; - } - - lbs_deb_leave(LBS_DEB_IOCTL); - return 0; -} - -/** - * @brief Cleans up the route (FRT) and neighbor (FNT) tables - * (Garbage Collection) - * @param priv A pointer to wlan_private structure - * @param req A pointer to ifreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_fwt_cleanup_ioctl(wlan_private * priv, struct ifreq *req) -{ - struct iwreq *wrq = (struct iwreq *)req; - static struct cmd_ds_fwt_access fwt_access; - int ret; - - lbs_deb_enter(LBS_DEB_IOCTL); - - lbs_deb_ioctl("FWT: cleaning up\n"); - - memset(&fwt_access, 0, sizeof(fwt_access)); - - ret = libertas_prepare_and_send_command(priv, cmd_fwt_access, - cmd_act_fwt_access_cleanup, - cmd_option_waitforrsp, 0, - (void *)&fwt_access); - - if (ret == 0) - wrq->u.param.value = le32_to_cpu(fwt_access.references); - else - return -EFAULT; - - lbs_deb_leave(LBS_DEB_IOCTL); - return 0; -} - -/** - * @brief Gets firmware internal time (debug purposes) - * @param priv A pointer to wlan_private structure - * @param req A pointer to ifreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_fwt_time_ioctl(wlan_private * priv, struct ifreq *req) -{ - struct iwreq *wrq = (struct iwreq *)req; - static struct cmd_ds_fwt_access fwt_access; - int ret; - - lbs_deb_enter(LBS_DEB_IOCTL); - - lbs_deb_ioctl("FWT: getting time\n"); - - memset(&fwt_access, 0, sizeof(fwt_access)); - - ret = libertas_prepare_and_send_command(priv, cmd_fwt_access, - cmd_act_fwt_access_time, - cmd_option_waitforrsp, 0, - (void *)&fwt_access); - - if (ret == 0) - wrq->u.param.value = le32_to_cpu(fwt_access.references); - else - return -EFAULT; - - lbs_deb_leave(LBS_DEB_IOCTL); - return 0; -} - -/** - * @brief Gets mesh ttl from firmware - * @param priv A pointer to wlan_private structure - * @param req A pointer to ifreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_mesh_get_ttl_ioctl(wlan_private * priv, struct ifreq *req) -{ - struct iwreq *wrq = (struct iwreq *)req; - struct cmd_ds_mesh_access mesh_access; - int ret; - - lbs_deb_enter(LBS_DEB_IOCTL); - - memset(&mesh_access, 0, sizeof(mesh_access)); - - ret = libertas_prepare_and_send_command(priv, cmd_mesh_access, - cmd_act_mesh_get_ttl, - cmd_option_waitforrsp, 0, - (void *)&mesh_access); - - if (ret == 0) - wrq->u.param.value = le32_to_cpu(mesh_access.data[0]); - else - return -EFAULT; - - lbs_deb_leave(LBS_DEB_IOCTL); - return 0; -} - -/** - * @brief Gets mesh ttl from firmware - * @param priv A pointer to wlan_private structure - * @param ttl New ttl value - * @return 0 --success, otherwise fail - */ -static int wlan_mesh_set_ttl_ioctl(wlan_private * priv, int ttl) -{ - struct cmd_ds_mesh_access mesh_access; - int ret; - - lbs_deb_enter(LBS_DEB_IOCTL); - - if( (ttl > 0xff) || (ttl < 0) ) - return -EINVAL; - - memset(&mesh_access, 0, sizeof(mesh_access)); - mesh_access.data[0] = cpu_to_le32(ttl); - - ret = libertas_prepare_and_send_command(priv, cmd_mesh_access, - cmd_act_mesh_set_ttl, - cmd_option_waitforrsp, 0, - (void *)&mesh_access); - - if (ret != 0) - ret = -EFAULT; - - lbs_deb_leave(LBS_DEB_IOCTL); - return ret; -} - -/** - * @brief ioctl function - entry point - * - * @param dev A pointer to net_device structure - * @param req A pointer to ifreq structure - * @param cmd command - * @return 0--success, otherwise fail - */ -int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd) -{ - int subcmd = 0; - int idata = 0; - int *pdata; - int ret = 0; - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; - struct iwreq *wrq = (struct iwreq *)req; - - lbs_deb_enter(LBS_DEB_IOCTL); - - lbs_deb_ioctl("libertas_do_ioctl: ioctl cmd = 0x%x\n", cmd); - switch (cmd) { - case WLAN_SETNONE_GETNONE: /* set WPA mode on/off ioctl #20 */ - switch (wrq->u.data.flags) { - case WLAN_SUBCMD_BT_RESET: /* bt_reset */ - wlan_bt_reset_ioctl(priv); - break; - case WLAN_SUBCMD_FWT_RESET: /* fwt_reset */ - wlan_fwt_reset_ioctl(priv); - break; - } /* End of switch */ - break; - - case WLAN_SETONEINT_GETNONE: - /* The first 4 bytes of req->ifr_data is sub-ioctl number - * after 4 bytes sits the payload. - */ - subcmd = wrq->u.data.flags; - if (!subcmd) - subcmd = (int)wrq->u.param.value; - - switch (subcmd) { - case WLANSETREGION: - idata = SUBCMD_DATA(wrq); - ret = wlan_set_region(priv, (u16) idata); - break; - case WLAN_SUBCMD_MESH_SET_TTL: - idata = SUBCMD_DATA(wrq); - ret = wlan_mesh_set_ttl_ioctl(priv, idata); - break; - - case WLAN_SUBCMD_BT_SET_INVERT: - ret = wlan_bt_set_invert_ioctl(priv, req); - break ; - - default: - ret = -EOPNOTSUPP; - break; - } - - break; - - case WLAN_SET128CHAR_GET128CHAR: - switch ((int)wrq->u.data.flags) { - case WLAN_SUBCMD_BT_ADD: - ret = wlan_bt_add_ioctl(priv, req); - break; - case WLAN_SUBCMD_BT_DEL: - ret = wlan_bt_del_ioctl(priv, req); - break; - case WLAN_SUBCMD_BT_LIST: - ret = wlan_bt_list_ioctl(priv, req); - break; - case WLAN_SUBCMD_FWT_ADD: - ret = wlan_fwt_add_ioctl(priv, req); - break; - case WLAN_SUBCMD_FWT_DEL: - ret = wlan_fwt_del_ioctl(priv, req); - break; - case WLAN_SUBCMD_FWT_LOOKUP: - ret = wlan_fwt_lookup_ioctl(priv, req); - break; - case WLAN_SUBCMD_FWT_LIST_NEIGHBOR: - ret = wlan_fwt_list_neighbor_ioctl(priv, req); - break; - case WLAN_SUBCMD_FWT_LIST: - ret = wlan_fwt_list_ioctl(priv, req); - break; - case WLAN_SUBCMD_FWT_LIST_ROUTE: - ret = wlan_fwt_list_route_ioctl(priv, req); - break; - } - break; - - case WLAN_SETNONE_GETONEINT: - switch (wrq->u.param.value) { - case WLANGETREGION: - pdata = (int *)wrq->u.name; - *pdata = (int)adapter->regioncode; - break; - case WLAN_SUBCMD_FWT_CLEANUP: /* fwt_cleanup */ - ret = wlan_fwt_cleanup_ioctl(priv, req); - break; - - case WLAN_SUBCMD_FWT_TIME: /* fwt_time */ - ret = wlan_fwt_time_ioctl(priv, req); - break; - - case WLAN_SUBCMD_MESH_GET_TTL: - ret = wlan_mesh_get_ttl_ioctl(priv, req); - break; - - case WLAN_SUBCMD_BT_GET_INVERT: - ret = wlan_bt_get_invert_ioctl(priv, req); - break ; - - default: - ret = -EOPNOTSUPP; - - } - - break; - - case WLAN_SET_GET_SIXTEEN_INT: - switch ((int)wrq->u.data.flags) { - case WLAN_LED_GPIO_CTRL: - { - int i; - int data[16]; - - struct cmd_ds_802_11_led_ctrl ctrl; - struct mrvlietypes_ledgpio *gpio = - (struct mrvlietypes_ledgpio *) ctrl.data; - - memset(&ctrl, 0, sizeof(ctrl)); - if (wrq->u.data.length > MAX_LEDS * 2) - return -ENOTSUPP; - if ((wrq->u.data.length % 2) != 0) - return -ENOTSUPP; - if (wrq->u.data.length == 0) { - ctrl.action = - cpu_to_le16 - (cmd_act_get); - } else { - if (copy_from_user - (data, wrq->u.data.pointer, - sizeof(int) * - wrq->u.data.length)) { - lbs_deb_ioctl( - "Copy from user failed\n"); - return -EFAULT; - } - - ctrl.action = - cpu_to_le16 - (cmd_act_set); - ctrl.numled = cpu_to_le16(0); - gpio->header.type = - cpu_to_le16(TLV_TYPE_LED_GPIO); - gpio->header.len = wrq->u.data.length; - for (i = 0; i < wrq->u.data.length; - i += 2) { - gpio->ledpin[i / 2].led = - data[i]; - gpio->ledpin[i / 2].pin = - data[i + 1]; - } - } - ret = - libertas_prepare_and_send_command(priv, - cmd_802_11_led_gpio_ctrl, - 0, - cmd_option_waitforrsp, - 0, (void *)&ctrl); - for (i = 0; i < gpio->header.len; i += 2) { - data[i] = gpio->ledpin[i / 2].led; - data[i + 1] = gpio->ledpin[i / 2].pin; - } - if (copy_to_user(wrq->u.data.pointer, data, - sizeof(int) * - gpio->header.len)) { - lbs_deb_ioctl("Copy to user failed\n"); - return -EFAULT; - } - - wrq->u.data.length = gpio->header.len; - } - break; - } - break; - - default: - ret = -EINVAL; - break; - } - - lbs_deb_leave_args(LBS_DEB_IOCTL, "ret %d", ret); - return ret; -} - - Index: linux-2.6/drivers/net/wireless/libertas/main.c =================================================================== --- linux-2.6.orig/drivers/net/wireless/libertas/main.c 2007-06-14 18:49:15.000000000 +0200 +++ linux-2.6/drivers/net/wireless/libertas/main.c 2007-06-14 18:49:19.000000000 +0200 @@ -799,7 +799,6 @@ wlan_private *libertas_add_card(void *ca dev->open = wlan_open; dev->hard_start_xmit = wlan_pre_start_xmit; dev->stop = wlan_close; - dev->do_ioctl = libertas_do_ioctl; dev->set_mac_address = wlan_set_mac_address; dev->tx_timeout = wlan_tx_timeout; dev->get_stats = wlan_get_stats; @@ -918,7 +917,6 @@ int libertas_add_mesh(wlan_private *priv mesh_dev->open = mesh_open; mesh_dev->hard_start_xmit = mesh_pre_start_xmit; mesh_dev->stop = mesh_close; - mesh_dev->do_ioctl = libertas_do_ioctl; mesh_dev->get_stats = wlan_get_stats; mesh_dev->set_mac_address = wlan_set_mac_address; mesh_dev->ethtool_ops = &libertas_ethtool_ops; Index: linux-2.6/drivers/net/wireless/libertas/wext.h =================================================================== --- linux-2.6.orig/drivers/net/wireless/libertas/wext.h 2007-06-14 18:49:33.000000000 +0200 +++ linux-2.6/drivers/net/wireless/libertas/wext.h 2007-06-14 19:10:31.000000000 +0200 @@ -7,45 +7,6 @@ #define SUBCMD_OFFSET 4 #define SUBCMD_DATA(x) *((int *)(x->u.name + SUBCMD_OFFSET)) -/** PRIVATE CMD ID */ -#define WLANIOCTL SIOCIWFIRSTPRIV - -#define WLAN_SETNONE_GETNONE (WLANIOCTL + 8) -#define WLAN_SUBCMD_BT_RESET 13 -#define WLAN_SUBCMD_FWT_RESET 14 - -#define WLAN_SETNONE_GETONEINT (WLANIOCTL + 15) -#define WLANGETREGION 1 - -#define WLAN_SUBCMD_FWT_CLEANUP 15 -#define WLAN_SUBCMD_FWT_TIME 16 -#define WLAN_SUBCMD_MESH_GET_TTL 17 -#define WLAN_SUBCMD_BT_GET_INVERT 18 - -#define WLAN_SETONEINT_GETNONE (WLANIOCTL + 24) -#define WLANSETREGION 8 -#define WLAN_SUBCMD_MESH_SET_TTL 18 -#define WLAN_SUBCMD_BT_SET_INVERT 19 - -#define WLAN_SET128CHAR_GET128CHAR (WLANIOCTL + 25) -#define WLAN_SUBCMD_BT_ADD 18 -#define WLAN_SUBCMD_BT_DEL 19 -#define WLAN_SUBCMD_BT_LIST 20 -#define WLAN_SUBCMD_FWT_ADD 21 -#define WLAN_SUBCMD_FWT_DEL 22 -#define WLAN_SUBCMD_FWT_LOOKUP 23 -#define WLAN_SUBCMD_FWT_LIST_NEIGHBOR 24 -#define WLAN_SUBCMD_FWT_LIST 25 -#define WLAN_SUBCMD_FWT_LIST_ROUTE 26 - -#define WLAN_SET_GET_SIXTEEN_INT (WLANIOCTL + 29) -#define WLAN_LED_GPIO_CTRL 5 - -#define WLAN_LINKMODE_802_3 0 -#define WLAN_LINKMODE_802_11 2 -#define WLAN_RADIOMODE_NONE 0 -#define WLAN_RADIOMODE_RADIOTAP 2 - /** wlan_ioctl_regrdwr */ struct wlan_ioctl_regrdwr { /** Which register to access */ @@ -57,9 +18,13 @@ struct wlan_ioctl_regrdwr { u32 value; }; +#define WLAN_LINKMODE_802_3 0 +#define WLAN_LINKMODE_802_11 2 +#define WLAN_RADIOMODE_NONE 0 +#define WLAN_RADIOMODE_RADIOTAP 2 + extern struct iw_handler_def libertas_handler_def; extern struct iw_handler_def mesh_handler_def; -int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int i); int wlan_radio_ioctl(wlan_private * priv, u8 option); #endif /* _WLAN_WEXT_H_ */ Index: linux-2.6/drivers/net/wireless/libertas/wext.c =================================================================== --- linux-2.6.orig/drivers/net/wireless/libertas/wext.c 2007-06-14 18:49:28.000000000 +0200 +++ linux-2.6/drivers/net/wireless/libertas/wext.c 2007-06-14 19:08:42.000000000 +0200 @@ -913,148 +913,6 @@ out: return 0; } -/* - * iwpriv settable callbacks - */ - -static const iw_handler wlan_private_handler[] = { - NULL, /* SIOCIWFIRSTPRIV */ -}; - -static const struct iw_priv_args wlan_private_args[] = { - /* - * { cmd, set_args, get_args, name } - */ - /* Using iwpriv sub-command feature */ - { - WLAN_SETONEINT_GETNONE, /* IOCTL: 24 */ - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - IW_PRIV_TYPE_NONE, - ""}, - { - WLANSETREGION, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - IW_PRIV_TYPE_NONE, - "setregioncode"}, - { - WLAN_SUBCMD_MESH_SET_TTL, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - IW_PRIV_TYPE_NONE, - "mesh_set_ttl"}, - { - WLAN_SETNONE_GETONEINT, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - ""}, - { - WLANGETREGION, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - "getregioncode"}, - { - WLAN_SUBCMD_FWT_CLEANUP, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - "fwt_cleanup"}, - { - WLAN_SUBCMD_FWT_TIME, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - "fwt_time"}, - { - WLAN_SUBCMD_MESH_GET_TTL, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - "mesh_get_ttl"}, - { - WLAN_SETNONE_GETNONE, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_NONE, - ""}, - { - WLAN_SUBCMD_FWT_RESET, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_NONE, - "fwt_reset"}, - { - WLAN_SUBCMD_BT_RESET, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_NONE, - "bt_reset"}, - { - WLAN_SET128CHAR_GET128CHAR, - IW_PRIV_TYPE_CHAR | 128, - IW_PRIV_TYPE_CHAR | 128, - ""}, - /* BT Management */ - { - WLAN_SUBCMD_BT_ADD, - IW_PRIV_TYPE_CHAR | 128, - IW_PRIV_TYPE_CHAR | 128, - "bt_add"}, - { - WLAN_SUBCMD_BT_DEL, - IW_PRIV_TYPE_CHAR | 128, - IW_PRIV_TYPE_CHAR | 128, - "bt_del"}, - { - WLAN_SUBCMD_BT_LIST, - IW_PRIV_TYPE_CHAR | 128, - IW_PRIV_TYPE_CHAR | 128, - "bt_list"}, - { - WLAN_SUBCMD_BT_SET_INVERT, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - IW_PRIV_TYPE_NONE, - "bt_set_invert"}, - { - WLAN_SUBCMD_BT_GET_INVERT, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - "bt_get_invert"}, - /* FWT Management */ - { - WLAN_SUBCMD_FWT_ADD, - IW_PRIV_TYPE_CHAR | 128, - IW_PRIV_TYPE_CHAR | 128, - "fwt_add"}, - { - WLAN_SUBCMD_FWT_DEL, - IW_PRIV_TYPE_CHAR | 128, - IW_PRIV_TYPE_CHAR | 128, - "fwt_del"}, - { - WLAN_SUBCMD_FWT_LOOKUP, - IW_PRIV_TYPE_CHAR | 128, - IW_PRIV_TYPE_CHAR | 128, - "fwt_lookup"}, - { - WLAN_SUBCMD_FWT_LIST_NEIGHBOR, - IW_PRIV_TYPE_CHAR | 128, - IW_PRIV_TYPE_CHAR | 128, - "fwt_list_neigh"}, - { - WLAN_SUBCMD_FWT_LIST, - IW_PRIV_TYPE_CHAR | 128, - IW_PRIV_TYPE_CHAR | 128, - "fwt_list"}, - { - WLAN_SUBCMD_FWT_LIST_ROUTE, - IW_PRIV_TYPE_CHAR | 128, - IW_PRIV_TYPE_CHAR | 128, - "fwt_list_route"}, - { - WLAN_SET_GET_SIXTEEN_INT, - IW_PRIV_TYPE_INT | 16, - IW_PRIV_TYPE_INT | 16, - ""}, - { - WLAN_LED_GPIO_CTRL, - IW_PRIV_TYPE_INT | 16, - IW_PRIV_TYPE_INT | 16, - "ledgpio"}, -}; - static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev) { enum { @@ -2444,22 +2302,12 @@ static const iw_handler mesh_wlan_handle }; struct iw_handler_def libertas_handler_def = { .num_standard = sizeof(wlan_handler) / sizeof(iw_handler), - .num_private = sizeof(wlan_private_handler) / sizeof(iw_handler), - .num_private_args = sizeof(wlan_private_args) / - sizeof(struct iw_priv_args), .standard = (iw_handler *) wlan_handler, - .private = (iw_handler *) wlan_private_handler, - .private_args = (struct iw_priv_args *)wlan_private_args, .get_wireless_stats = wlan_get_wireless_stats, }; struct iw_handler_def mesh_handler_def = { .num_standard = sizeof(mesh_wlan_handler) / sizeof(iw_handler), - .num_private = sizeof(wlan_private_handler) / sizeof(iw_handler), - .num_private_args = sizeof(wlan_private_args) / - sizeof(struct iw_priv_args), .standard = (iw_handler *) mesh_wlan_handler, - .private = (iw_handler *) wlan_private_handler, - .private_args = (struct iw_priv_args *)wlan_private_args, .get_wireless_stats = wlan_get_wireless_stats, }; ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: libertas (private) ioctls vs. nl80211 2007-06-14 18:13 ` Christoph Hellwig @ 2007-06-14 18:23 ` Linus Torvalds 2007-06-14 18:48 ` Jeff Garzik 2007-06-14 19:09 ` John W. Linville 2007-06-18 17:38 ` Dan Williams 1 sibling, 2 replies; 17+ messages in thread From: Linus Torvalds @ 2007-06-14 18:23 UTC (permalink / raw) To: Christoph Hellwig Cc: Andrew Morton, johannes, linux-wireless, dcbw, hs4233, linux-kernel On Thu, 14 Jun 2007, Christoph Hellwig wrote: > > > I suspect that the probability of your proposal succeeding would be increased > > if you could prepare a patch... > > Here we go: I don't mind ripping them out, but it makes sense only if people are actually signed up to implementing this on a higher layer. As such, I'd need to get a sign-off from somebody actually involved in wireless mesh stuff etc. Please? I do agree that the private iwpriv interface seems to be totally the wrong thing to do, but I want to see this as a first step towards a better situation, rather than just a "remove code that is ugly" issue! Comments? Linus ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: libertas (private) ioctls vs. nl80211 2007-06-14 18:23 ` Linus Torvalds @ 2007-06-14 18:48 ` Jeff Garzik 2007-06-14 22:22 ` Dan Williams 2007-06-14 19:09 ` John W. Linville 1 sibling, 1 reply; 17+ messages in thread From: Jeff Garzik @ 2007-06-14 18:48 UTC (permalink / raw) To: Linus Torvalds Cc: Christoph Hellwig, Andrew Morton, johannes, linux-wireless, dcbw, hs4233, linux-kernel Linus Torvalds wrote: > > On Thu, 14 Jun 2007, Christoph Hellwig wrote: >>> I suspect that the probability of your proposal succeeding would be increased >>> if you could prepare a patch... >> Here we go: > > I don't mind ripping them out, but it makes sense only if people are > actually signed up to implementing this on a higher layer. As such, I'd > need to get a sign-off from somebody actually involved in wireless mesh > stuff etc. Correct me if I'm wrong, linux-wireless, but AFAIK there has never been a single post or line of code written for a generic wireless _mesh_ interface. My general sentiment is -- remove the pointless and iw-duplicated ioctls, but leave the mesh ones that won't see generic counterparts for years. Jeff ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: libertas (private) ioctls vs. nl80211 2007-06-14 18:48 ` Jeff Garzik @ 2007-06-14 22:22 ` Dan Williams 2007-06-14 22:31 ` Christoph Hellwig 0 siblings, 1 reply; 17+ messages in thread From: Dan Williams @ 2007-06-14 22:22 UTC (permalink / raw) To: Jeff Garzik Cc: Linus Torvalds, Christoph Hellwig, Andrew Morton, johannes, linux-wireless, hs4233, linux-kernel On Thu, 2007-06-14 at 14:48 -0400, Jeff Garzik wrote: > Linus Torvalds wrote: > > > > On Thu, 14 Jun 2007, Christoph Hellwig wrote: > >>> I suspect that the probability of your proposal succeeding would be increased > >>> if you could prepare a patch... > >> Here we go: > > > > I don't mind ripping them out, but it makes sense only if people are > > actually signed up to implementing this on a higher layer. As such, I'd > > need to get a sign-off from somebody actually involved in wireless mesh > > stuff etc. > > Correct me if I'm wrong, linux-wireless, but AFAIK there has never been > a single post or line of code written for a generic wireless _mesh_ > interface. > > My general sentiment is -- remove the pointless and iw-duplicated > ioctls, but leave the mesh ones that won't see generic counterparts for > years. And that's what I did in the last pull you got from John; all pointless and duplicated ioctls were removed. The only ones left are mesh tweakables, an LED GPIO control ioctl, and a regulatory region/domain thing. I agree the interface is somewhat ugly (like the char-128/char-128 ones that return information from the mesh forwarding table), and I also agree that we need to move to using netlink for this sort of stuff in the future. There are _no_ ioctls that duplicate WEXT functionality. Dan ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: libertas (private) ioctls vs. nl80211 2007-06-14 22:22 ` Dan Williams @ 2007-06-14 22:31 ` Christoph Hellwig 2007-06-14 22:55 ` Dan Williams 0 siblings, 1 reply; 17+ messages in thread From: Christoph Hellwig @ 2007-06-14 22:31 UTC (permalink / raw) To: Dan Williams Cc: Jeff Garzik, Linus Torvalds, Christoph Hellwig, Andrew Morton, johannes, linux-wireless, hs4233, linux-kernel On Thu, Jun 14, 2007 at 06:22:35PM -0400, Dan Williams wrote: > And that's what I did in the last pull you got from John; all pointless > and duplicated ioctls were removed. The only ones left are mesh > tweakables, an LED GPIO control ioctl, and a regulatory region/domain > thing. I agree the interface is somewhat ugly (like the > char-128/char-128 ones that return information from the mesh forwarding > table), and I also agree that we need to move to using netlink for this > sort of stuff in the future. There are _no_ ioctls that duplicate WEXT > functionality. The problem is not any kind of duplication. The problem is that the interface is plain and simply bad. If anyone else would come in with an ioctl interface using pointer indirections and subfunctions which is horribly complex and not 32on64 clean they would get beaten up. So even if the interface is not going to be generic it needs to be done properly and document. And once it's documented you've actually layed down the first building block have it generic. If no other driver actually implements the same kind of non-standardized mesh interface it'll stay that way, if other pop up they can implement the same interface and eventually we'll grow a generic layer helping out with it. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: libertas (private) ioctls vs. nl80211 2007-06-14 22:31 ` Christoph Hellwig @ 2007-06-14 22:55 ` Dan Williams 0 siblings, 0 replies; 17+ messages in thread From: Dan Williams @ 2007-06-14 22:55 UTC (permalink / raw) To: Christoph Hellwig Cc: Jeff Garzik, Linus Torvalds, Andrew Morton, johannes, linux-wireless, hs4233, linux-kernel On Thu, 2007-06-14 at 23:31 +0100, Christoph Hellwig wrote: > On Thu, Jun 14, 2007 at 06:22:35PM -0400, Dan Williams wrote: > > And that's what I did in the last pull you got from John; all pointless > > and duplicated ioctls were removed. The only ones left are mesh > > tweakables, an LED GPIO control ioctl, and a regulatory region/domain > > thing. I agree the interface is somewhat ugly (like the > > char-128/char-128 ones that return information from the mesh forwarding > > table), and I also agree that we need to move to using netlink for this > > sort of stuff in the future. There are _no_ ioctls that duplicate WEXT > > functionality. > > The problem is not any kind of duplication. The problem is that the > interface is plain and simply bad. If anyone else would come in with > an ioctl interface using pointer indirections and subfunctions which > is horribly complex and not 32on64 clean they would get beaten up. I agree that it's suboptimal; I tried to clean it up and bashed my head against the current iwpriv system for about 2 days before concluding that the iwpriv stuff is just too insane to actually use. We both want a well-defined, clean, generic 802.11s-type interface, make no mistake. Unfortunately, we don't have any framework which that interface could use (ie, nl80211 or cfg80211). That's unlikely to land until 2.6.23 or even later. And the regulatory stuff is still probably 6 months away from agreement. So if everybody is objecting to _any_ new private ioctls, even if they don't duplicate WEXT functionality, whatever; rip them out and we'll maintain them out-of-kernel or something until there's a nicer framework to piggy-back the mesh tune-ables on. Dan > So even if the interface is not going to be generic it needs to be > done properly and document. And once it's documented you've actually > layed down the first building block have it generic. If no other > driver actually implements the same kind of non-standardized mesh > interface it'll stay that way, if other pop up they can implement > the same interface and eventually we'll grow a generic layer helping > out with it. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: libertas (private) ioctls vs. nl80211 2007-06-14 18:23 ` Linus Torvalds 2007-06-14 18:48 ` Jeff Garzik @ 2007-06-14 19:09 ` John W. Linville 2007-06-14 19:56 ` Andrew Morton 1 sibling, 1 reply; 17+ messages in thread From: John W. Linville @ 2007-06-14 19:09 UTC (permalink / raw) To: Linus Torvalds Cc: Christoph Hellwig, Andrew Morton, johannes, linux-wireless, dcbw, hs4233, linux-kernel, marcelo On Thu, Jun 14, 2007 at 11:23:11AM -0700, Linus Torvalds wrote: > > > On Thu, 14 Jun 2007, Christoph Hellwig wrote: > > > > > I suspect that the probability of your proposal succeeding would be increased > > > if you could prepare a patch... > > > > Here we go: FWIW, I do appreciate the patch rather than just mere complaining... :-) > I don't mind ripping them out, but it makes sense only if people are > actually signed up to implementing this on a higher layer. As such, I'd > need to get a sign-off from somebody actually involved in wireless mesh > stuff etc. I'm not aware of any project working on wireless mesh in mac80211 at the moment, serious or otherwise. I think one would be worthwhile, but I don't know of anyone working on it. > Please? I do agree that the private iwpriv interface seems to be totally > the wrong thing to do, but I want to see this as a first step towards a > better situation, rather than just a "remove code that is ugly" issue! Private wireless extensions are ugly, even uglier in some ways than normal private ioctls. However, they have been used in the past for just this sort of thing (i.e. something a given driver can do but is not generically available). We don't have either generic functionality for mesh in mac80211 or even other drivers doing mesh on their own, so there is nothing to validate a generic configuration option. Further, while the beginnings of nl80211 are available it will still be some non-zero time before it is even mature enough to replace truly generic configuration facilities in the wireless extensions. > Comments? Aside from simply carrying an out-of-stream patch, the OLPC and libertas driver people would have only the alternative of hacking-up a debugfs configuration regime. Is it worthwhile to obligate them to either alternative? What is to be gained? It does not make sense to me to rip this out purely for aesthetic reasons. John -- John W. Linville linville@tuxdriver.com ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: libertas (private) ioctls vs. nl80211 2007-06-14 19:09 ` John W. Linville @ 2007-06-14 19:56 ` Andrew Morton 2007-06-14 20:08 ` John W. Linville 0 siblings, 1 reply; 17+ messages in thread From: Andrew Morton @ 2007-06-14 19:56 UTC (permalink / raw) To: John W. Linville Cc: Linus Torvalds, Christoph Hellwig, johannes, linux-wireless, dcbw, hs4233, linux-kernel, marcelo On Thu, 14 Jun 2007 15:09:36 -0400 "John W. Linville" <linville@tuxdriver.com> wrote: > It does not make sense to me to rip this out purely for aesthetic > reasons. Aesthetics are good, but that's not the main issue. What is most worrying is that there appears to be a risk that these newly-added interfaces will later become obsoleted by another interface. This means that we'll need to maintain, test and support _both_ interfaces for a very long time. This is the sort of foot-shooting we should avoid. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: libertas (private) ioctls vs. nl80211 2007-06-14 19:56 ` Andrew Morton @ 2007-06-14 20:08 ` John W. Linville 2007-06-17 4:46 ` Matt Mackall 0 siblings, 1 reply; 17+ messages in thread From: John W. Linville @ 2007-06-14 20:08 UTC (permalink / raw) To: Andrew Morton Cc: Linus Torvalds, Christoph Hellwig, johannes, linux-wireless, dcbw, hs4233, linux-kernel, marcelo On Thu, Jun 14, 2007 at 12:56:18PM -0700, Andrew Morton wrote: > On Thu, 14 Jun 2007 15:09:36 -0400 > "John W. Linville" <linville@tuxdriver.com> wrote: > > > It does not make sense to me to rip this out purely for aesthetic > > reasons. > > Aesthetics are good, but that's not the main issue. > > What is most worrying is that there appears to be a risk that these > newly-added interfaces will later become obsoleted by another interface. > This means that we'll need to maintain, test and support _both_ interfaces > for a very long time. This is the sort of foot-shooting we should avoid. True enough. However, I hope you will agree that we should not confuse foresight with speculation. At present there is no sign on the horizon of either any mac80211 mesh code or any other full-MAC wireless driver supporting mesh. Without either of those, it would seem imprudent to rush toward a gneric configuration interface even if nl80211 was prepared to sprout one. John P.S. If someone wants to announce either mesh support for mac80211 or a driver for a new full-MAC device supporting mesh, I'm prepared to be wrong! :-) -- John W. Linville linville@tuxdriver.com ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: libertas (private) ioctls vs. nl80211 2007-06-14 20:08 ` John W. Linville @ 2007-06-17 4:46 ` Matt Mackall 0 siblings, 0 replies; 17+ messages in thread From: Matt Mackall @ 2007-06-17 4:46 UTC (permalink / raw) To: John W. Linville Cc: Andrew Morton, Linus Torvalds, Christoph Hellwig, johannes, linux-wireless, dcbw, hs4233, linux-kernel, marcelo On Thu, Jun 14, 2007 at 04:08:44PM -0400, John W. Linville wrote: > On Thu, Jun 14, 2007 at 12:56:18PM -0700, Andrew Morton wrote: > > On Thu, 14 Jun 2007 15:09:36 -0400 > > "John W. Linville" <linville@tuxdriver.com> wrote: > > > > > It does not make sense to me to rip this out purely for aesthetic > > > reasons. > > > > Aesthetics are good, but that's not the main issue. > > > > What is most worrying is that there appears to be a risk that these > > newly-added interfaces will later become obsoleted by another interface. > > This means that we'll need to maintain, test and support _both_ interfaces > > for a very long time. This is the sort of foot-shooting we should avoid. > > True enough. However, I hope you will agree that we should not > confuse foresight with speculation. > > At present there is no sign on the horizon of either any mac80211 > mesh code or any other full-MAC wireless driver supporting mesh. > Without either of those, it would seem imprudent to rush toward > a gneric configuration interface even if nl80211 was prepared to > sprout one. Making it generic may be premature optimization. But at the very least, we should deal with the three other problems Christoph has pointed out: subfunctions, pointer indirections, and 32on64 cleanliness. That last one may come back to bite you in a couple years' time, if not other people. It's a major pain in the ass. -- Mathematics is the supreme nostalgia of our time. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: libertas (private) ioctls vs. nl80211 2007-06-14 18:13 ` Christoph Hellwig 2007-06-14 18:23 ` Linus Torvalds @ 2007-06-18 17:38 ` Dan Williams 2007-06-18 18:44 ` Christoph Hellwig 1 sibling, 1 reply; 17+ messages in thread From: Dan Williams @ 2007-06-18 17:38 UTC (permalink / raw) To: Christoph Hellwig Cc: Andrew Morton, johannes, linux-wireless, hs4233, linux-kernel, Linus Torvalds On Thu, 2007-06-14 at 19:13 +0100, Christoph Hellwig wrote: > > I suspect that the probability of your proposal succeeding would be increased > > if you could prepare a patch... Applied to upstream-fixes branch of libertas-2.6 which is destined for 2.6.22; I hope you don't mind that I just added the Signed-off-by for you. Dan > Here we go: > > Index: linux-2.6/drivers/net/wireless/libertas/Makefile > =================================================================== > --- linux-2.6.orig/drivers/net/wireless/libertas/Makefile 2007-06-14 18:53:57.000000000 +0200 > +++ linux-2.6/drivers/net/wireless/libertas/Makefile 2007-06-14 18:54:01.000000000 +0200 > @@ -2,7 +2,7 @@ libertas-objs := main.o fw.o wext.o \ > rx.o tx.o cmd.o \ > cmdresp.o scan.o \ > join.o 11d.o \ > - ioctl.o debugfs.o \ > + debugfs.o \ > ethtool.o assoc.o > > usb8xxx-objs += if_bootcmd.o > Index: linux-2.6/drivers/net/wireless/libertas/ioctl.c > =================================================================== > --- linux-2.6.orig/drivers/net/wireless/libertas/ioctl.c 2007-06-14 18:48:47.000000000 +0200 > +++ /dev/null 1970-01-01 00:00:00.000000000 +0000 > @@ -1,1081 +0,0 @@ > -/** > - * This file contains ioctl functions > - */ > - > -#include <linux/ctype.h> > -#include <linux/delay.h> > -#include <linux/if.h> > -#include <linux/if_arp.h> > -#include <linux/wireless.h> > - > -#include <net/iw_handler.h> > -#include <net/ieee80211.h> > - > -#include "host.h" > -#include "radiotap.h" > -#include "decl.h" > -#include "defs.h" > -#include "dev.h" > -#include "join.h" > -#include "wext.h" > - > -#define MAX_SCAN_CELL_SIZE (IW_EV_ADDR_LEN + \ > - IW_ESSID_MAX_SIZE + \ > - IW_EV_UINT_LEN + IW_EV_FREQ_LEN + \ > - IW_EV_QUAL_LEN + IW_ESSID_MAX_SIZE + \ > - IW_EV_PARAM_LEN + 40) /* 40 for WPAIE */ > - > -#define WAIT_FOR_SCAN_RRESULT_MAX_TIME (10 * HZ) > - > -static int wlan_set_region(wlan_private * priv, u16 region_code) > -{ > - int i; > - int ret = 0; > - > - for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) { > - // use the region code to search for the index > - if (region_code == libertas_region_code_to_index[i]) { > - priv->adapter->regiontableindex = (u16) i; > - priv->adapter->regioncode = region_code; > - break; > - } > - } > - > - // if it's unidentified region code > - if (i >= MRVDRV_MAX_REGION_CODE) { > - lbs_deb_ioctl("region Code not identified\n"); > - ret = -1; > - goto done; > - } > - > - if (libertas_set_regiontable(priv, priv->adapter->regioncode, 0)) { > - ret = -EINVAL; > - } > - > -done: > - lbs_deb_leave_args(LBS_DEB_IOCTL, "ret %d", ret); > - return ret; > -} > - > -static inline int hex2int(char c) > -{ > - if (c >= '0' && c <= '9') > - return (c - '0'); > - if (c >= 'a' && c <= 'f') > - return (c - 'a' + 10); > - if (c >= 'A' && c <= 'F') > - return (c - 'A' + 10); > - return -1; > -} > - > -/* Convert a string representation of a MAC address ("xx:xx:xx:xx:xx:xx") > - into binary format (6 bytes). > - > - This function expects that each byte is represented with 2 characters > - (e.g., 11:2:11:11:11:11 is invalid) > - > - */ > -static char *eth_str2addr(char *ethstr, u8 * addr) > -{ > - int i, val, val2; > - char *pos = ethstr; > - > - /* get rid of initial blanks */ > - while (*pos == ' ' || *pos == '\t') > - ++pos; > - > - for (i = 0; i < 6; i++) { > - val = hex2int(*pos++); > - if (val < 0) > - return NULL; > - val2 = hex2int(*pos++); > - if (val2 < 0) > - return NULL; > - addr[i] = (val * 16 + val2) & 0xff; > - > - if (i < 5 && *pos++ != ':') > - return NULL; > - } > - return pos; > -} > - > -/* this writes xx:xx:xx:xx:xx:xx into ethstr > - (ethstr must have space for 18 chars) */ > -static int eth_addr2str(u8 * addr, char *ethstr) > -{ > - int i; > - char *pos = ethstr; > - > - for (i = 0; i < 6; i++) { > - sprintf(pos, "%02x", addr[i] & 0xff); > - pos += 2; > - if (i < 5) > - *pos++ = ':'; > - } > - return 17; > -} > - > -/** > - * @brief Add an entry to the BT table > - * @param priv A pointer to wlan_private structure > - * @param req A pointer to ifreq structure > - * @return 0 --success, otherwise fail > - */ > -static int wlan_bt_add_ioctl(wlan_private * priv, struct ifreq *req) > -{ > - struct iwreq *wrq = (struct iwreq *)req; > - char ethaddrs_str[18]; > - char *pos; > - u8 ethaddr[ETH_ALEN]; > - int ret; > - > - lbs_deb_enter(LBS_DEB_IOCTL); > - > - if (copy_from_user(ethaddrs_str, wrq->u.data.pointer, > - sizeof(ethaddrs_str))) > - return -EFAULT; > - > - if ((pos = eth_str2addr(ethaddrs_str, ethaddr)) == NULL) { > - lbs_pr_info("BT_ADD: Invalid MAC address\n"); > - return -EINVAL; > - } > - > - lbs_deb_ioctl("BT: adding %s\n", ethaddrs_str); > - ret = libertas_prepare_and_send_command(priv, cmd_bt_access, > - cmd_act_bt_access_add, > - cmd_option_waitforrsp, 0, ethaddr); > - lbs_deb_leave_args(LBS_DEB_IOCTL, "ret %d", ret); > - return ret; > -} > - > -/** > - * @brief Delete an entry from the BT table > - * @param priv A pointer to wlan_private structure > - * @param req A pointer to ifreq structure > - * @return 0 --success, otherwise fail > - */ > -static int wlan_bt_del_ioctl(wlan_private * priv, struct ifreq *req) > -{ > - struct iwreq *wrq = (struct iwreq *)req; > - char ethaddrs_str[18]; > - u8 ethaddr[ETH_ALEN]; > - char *pos; > - > - lbs_deb_enter(LBS_DEB_IOCTL); > - > - if (copy_from_user(ethaddrs_str, wrq->u.data.pointer, > - sizeof(ethaddrs_str))) > - return -EFAULT; > - > - if ((pos = eth_str2addr(ethaddrs_str, ethaddr)) == NULL) { > - lbs_pr_info("Invalid MAC address\n"); > - return -EINVAL; > - } > - > - lbs_deb_ioctl("BT: deleting %s\n", ethaddrs_str); > - > - return (libertas_prepare_and_send_command(priv, > - cmd_bt_access, > - cmd_act_bt_access_del, > - cmd_option_waitforrsp, 0, ethaddr)); > - > - lbs_deb_leave(LBS_DEB_IOCTL); > - return 0; > -} > - > -/** > - * @brief Reset all entries from the BT table > - * @param priv A pointer to wlan_private structure > - * @return 0 --success, otherwise fail > - */ > -static int wlan_bt_reset_ioctl(wlan_private * priv) > -{ > - lbs_deb_enter(LBS_DEB_IOCTL); > - > - lbs_pr_alert( "BT: resetting\n"); > - > - return (libertas_prepare_and_send_command(priv, > - cmd_bt_access, > - cmd_act_bt_access_reset, > - cmd_option_waitforrsp, 0, NULL)); > - > - lbs_deb_leave(LBS_DEB_IOCTL); > - return 0; > -} > - > -/** > - * @brief List an entry from the BT table > - * @param priv A pointer to wlan_private structure > - * @param req A pointer to ifreq structure > - * @return 0 --success, otherwise fail > - */ > -static int wlan_bt_list_ioctl(wlan_private * priv, struct ifreq *req) > -{ > - int pos; > - char *addr1; > - struct iwreq *wrq = (struct iwreq *)req; > - /* used to pass id and store the bt entry returned by the FW */ > - union { > - u32 id; > - char addr1addr2[2 * ETH_ALEN]; > - } param; > - static char outstr[64]; > - char *pbuf = outstr; > - int ret; > - > - lbs_deb_enter(LBS_DEB_IOCTL); > - > - if (copy_from_user(outstr, wrq->u.data.pointer, sizeof(outstr))) { > - lbs_deb_ioctl("Copy from user failed\n"); > - return -1; > - } > - param.id = simple_strtoul(outstr, NULL, 10); > - pos = sprintf(pbuf, "%d: ", param.id); > - pbuf += pos; > - > - ret = libertas_prepare_and_send_command(priv, cmd_bt_access, > - cmd_act_bt_access_list, > - cmd_option_waitforrsp, 0, > - (char *)¶m); > - > - if (ret == 0) { > - addr1 = param.addr1addr2; > - > - pos = sprintf(pbuf, "BT includes node "); > - pbuf += pos; > - pos = eth_addr2str(addr1, pbuf); > - pbuf += pos; > - } else { > - sprintf(pbuf, "(null)"); > - pbuf += pos; > - } > - > - wrq->u.data.length = strlen(outstr); > - if (copy_to_user(wrq->u.data.pointer, (char *)outstr, > - wrq->u.data.length)) { > - lbs_deb_ioctl("BT_LIST: Copy to user failed!\n"); > - return -EFAULT; > - } > - > - lbs_deb_leave(LBS_DEB_IOCTL); > - return 0 ; > -} > - > -/** > - * @brief Sets inverted state of blacklist (non-zero if inverted) > - * @param priv A pointer to wlan_private structure > - * @param req A pointer to ifreq structure > - * @return 0 --success, otherwise fail > - */ > -static int wlan_bt_set_invert_ioctl(wlan_private * priv, struct ifreq *req) > -{ > - int ret; > - struct iwreq *wrq = (struct iwreq *)req; > - union { > - u32 id; > - char addr1addr2[2 * ETH_ALEN]; > - } param; > - > - lbs_deb_enter(LBS_DEB_IOCTL); > - > - param.id = SUBCMD_DATA(wrq) ; > - ret = libertas_prepare_and_send_command(priv, cmd_bt_access, > - cmd_act_bt_access_set_invert, > - cmd_option_waitforrsp, 0, > - (char *)¶m); > - if (ret != 0) > - return -EFAULT; > - lbs_deb_leave(LBS_DEB_IOCTL); > - return 0; > -} > - > -/** > - * @brief Gets inverted state of blacklist (non-zero if inverted) > - * @param priv A pointer to wlan_private structure > - * @param req A pointer to ifreq structure > - * @return 0 --success, otherwise fail > - */ > -static int wlan_bt_get_invert_ioctl(wlan_private * priv, struct ifreq *req) > -{ > - struct iwreq *wrq = (struct iwreq *)req; > - int ret; > - union { > - u32 id; > - char addr1addr2[2 * ETH_ALEN]; > - } param; > - > - lbs_deb_enter(LBS_DEB_IOCTL); > - > - ret = libertas_prepare_and_send_command(priv, cmd_bt_access, > - cmd_act_bt_access_get_invert, > - cmd_option_waitforrsp, 0, > - (char *)¶m); > - > - if (ret == 0) > - wrq->u.param.value = le32_to_cpu(param.id); > - else > - return -EFAULT; > - > - lbs_deb_leave(LBS_DEB_IOCTL); > - return 0; > -} > - > -/** > - * @brief Find the next parameter in an input string > - * @param ptr A pointer to the input parameter string > - * @return A pointer to the next parameter, or 0 if no parameters left. > - */ > -static char * next_param(char * ptr) > -{ > - if (!ptr) return NULL; > - while (*ptr == ' ' || *ptr == '\t') ++ptr; > - return (*ptr == '\0') ? NULL : ptr; > -} > - > -/** > - * @brief Add an entry to the FWT table > - * @param priv A pointer to wlan_private structure > - * @param req A pointer to ifreq structure > - * @return 0 --success, otherwise fail > - */ > -static int wlan_fwt_add_ioctl(wlan_private * priv, struct ifreq *req) > -{ > - struct iwreq *wrq = (struct iwreq *)req; > - char in_str[128]; > - static struct cmd_ds_fwt_access fwt_access; > - char *ptr; > - int ret; > - > - lbs_deb_enter(LBS_DEB_IOCTL); > - > - if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str))) > - return -EFAULT; > - > - if ((ptr = eth_str2addr(in_str, fwt_access.da)) == NULL) { > - lbs_pr_alert( "FWT_ADD: Invalid MAC address 1\n"); > - return -EINVAL; > - } > - > - if ((ptr = eth_str2addr(ptr, fwt_access.ra)) == NULL) { > - lbs_pr_alert( "FWT_ADD: Invalid MAC address 2\n"); > - return -EINVAL; > - } > - > - if ((ptr = next_param(ptr))) > - fwt_access.metric = > - cpu_to_le32(simple_strtoul(ptr, &ptr, 10)); > - else > - fwt_access.metric = cpu_to_le32(FWT_DEFAULT_METRIC); > - > - if ((ptr = next_param(ptr))) > - fwt_access.dir = (u8)simple_strtoul(ptr, &ptr, 10); > - else > - fwt_access.dir = FWT_DEFAULT_DIR; > - > - if ((ptr = next_param(ptr))) > - fwt_access.rate = (u8) simple_strtoul(ptr, &ptr, 10); > - else > - fwt_access.rate = FWT_DEFAULT_RATE; > - > - if ((ptr = next_param(ptr))) > - fwt_access.ssn = > - cpu_to_le32(simple_strtoul(ptr, &ptr, 10)); > - else > - fwt_access.ssn = cpu_to_le32(FWT_DEFAULT_SSN); > - > - if ((ptr = next_param(ptr))) > - fwt_access.dsn = > - cpu_to_le32(simple_strtoul(ptr, &ptr, 10)); > - else > - fwt_access.dsn = cpu_to_le32(FWT_DEFAULT_DSN); > - > - if ((ptr = next_param(ptr))) > - fwt_access.hopcount = simple_strtoul(ptr, &ptr, 10); > - else > - fwt_access.hopcount = FWT_DEFAULT_HOPCOUNT; > - > - if ((ptr = next_param(ptr))) > - fwt_access.ttl = simple_strtoul(ptr, &ptr, 10); > - else > - fwt_access.ttl = FWT_DEFAULT_TTL; > - > - if ((ptr = next_param(ptr))) > - fwt_access.expiration = > - cpu_to_le32(simple_strtoul(ptr, &ptr, 10)); > - else > - fwt_access.expiration = cpu_to_le32(FWT_DEFAULT_EXPIRATION); > - > - if ((ptr = next_param(ptr))) > - fwt_access.sleepmode = (u8)simple_strtoul(ptr, &ptr, 10); > - else > - fwt_access.sleepmode = FWT_DEFAULT_SLEEPMODE; > - > - if ((ptr = next_param(ptr))) > - fwt_access.snr = > - cpu_to_le32(simple_strtoul(ptr, &ptr, 10)); > - else > - fwt_access.snr = cpu_to_le32(FWT_DEFAULT_SNR); > - > -#ifdef DEBUG > - { > - char ethaddr1_str[18], ethaddr2_str[18]; > - eth_addr2str(fwt_access.da, ethaddr1_str); > - eth_addr2str(fwt_access.ra, ethaddr2_str); > - lbs_deb_ioctl("FWT_ADD: adding (da:%s,%i,ra:%s)\n", ethaddr1_str, > - fwt_access.dir, ethaddr2_str); > - lbs_deb_ioctl("FWT_ADD: ssn:%u dsn:%u met:%u hop:%u ttl:%u exp:%u slp:%u snr:%u\n", > - fwt_access.ssn, fwt_access.dsn, fwt_access.metric, > - fwt_access.hopcount, fwt_access.ttl, fwt_access.expiration, > - fwt_access.sleepmode, fwt_access.snr); > - } > -#endif > - > - ret = libertas_prepare_and_send_command(priv, cmd_fwt_access, > - cmd_act_fwt_access_add, > - cmd_option_waitforrsp, 0, > - (void *)&fwt_access); > - > - lbs_deb_leave_args(LBS_DEB_IOCTL, "ret %d", ret); > - return ret; > -} > - > -/** > - * @brief Delete an entry from the FWT table > - * @param priv A pointer to wlan_private structure > - * @param req A pointer to ifreq structure > - * @return 0 --success, otherwise fail > - */ > -static int wlan_fwt_del_ioctl(wlan_private * priv, struct ifreq *req) > -{ > - struct iwreq *wrq = (struct iwreq *)req; > - char in_str[64]; > - static struct cmd_ds_fwt_access fwt_access; > - char *ptr; > - int ret; > - > - lbs_deb_enter(LBS_DEB_IOCTL); > - > - if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str))) > - return -EFAULT; > - > - if ((ptr = eth_str2addr(in_str, fwt_access.da)) == NULL) { > - lbs_pr_alert( "FWT_DEL: Invalid MAC address 1\n"); > - return -EINVAL; > - } > - > - if ((ptr = eth_str2addr(ptr, fwt_access.ra)) == NULL) { > - lbs_pr_alert( "FWT_DEL: Invalid MAC address 2\n"); > - return -EINVAL; > - } > - > - if ((ptr = next_param(ptr))) > - fwt_access.dir = (u8)simple_strtoul(ptr, &ptr, 10); > - else > - fwt_access.dir = FWT_DEFAULT_DIR; > - > -#ifdef DEBUG > - { > - char ethaddr1_str[18], ethaddr2_str[18]; > - lbs_deb_ioctl("FWT_DEL: line is %s\n", in_str); > - eth_addr2str(fwt_access.da, ethaddr1_str); > - eth_addr2str(fwt_access.ra, ethaddr2_str); > - lbs_deb_ioctl("FWT_DEL: removing (da:%s,ra:%s,dir:%d)\n", ethaddr1_str, > - ethaddr2_str, fwt_access.dir); > - } > -#endif > - > - ret = libertas_prepare_and_send_command(priv, > - cmd_fwt_access, > - cmd_act_fwt_access_del, > - cmd_option_waitforrsp, 0, > - (void *)&fwt_access); > - lbs_deb_leave_args(LBS_DEB_IOCTL, "ret %d", ret); > - return ret; > -} > - > - > -/** > - * @brief Print route parameters > - * @param fwt_access struct cmd_ds_fwt_access with route info > - * @param buf destination buffer for route info > - */ > -static void print_route(struct cmd_ds_fwt_access fwt_access, char *buf) > -{ > - buf += sprintf(buf, " "); > - buf += eth_addr2str(fwt_access.da, buf); > - buf += sprintf(buf, " "); > - buf += eth_addr2str(fwt_access.ra, buf); > - buf += sprintf(buf, " %u", fwt_access.valid); > - buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.metric)); > - buf += sprintf(buf, " %u", fwt_access.dir); > - buf += sprintf(buf, " %u", fwt_access.rate); > - buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.ssn)); > - buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.dsn)); > - buf += sprintf(buf, " %u", fwt_access.hopcount); > - buf += sprintf(buf, " %u", fwt_access.ttl); > - buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.expiration)); > - buf += sprintf(buf, " %u", fwt_access.sleepmode); > - buf += sprintf(buf, " %u ", le32_to_cpu(fwt_access.snr)); > - buf += eth_addr2str(fwt_access.prec, buf); > -} > - > -/** > - * @brief Lookup an entry in the FWT table > - * @param priv A pointer to wlan_private structure > - * @param req A pointer to ifreq structure > - * @return 0 --success, otherwise fail > - */ > -static int wlan_fwt_lookup_ioctl(wlan_private * priv, struct ifreq *req) > -{ > - struct iwreq *wrq = (struct iwreq *)req; > - char in_str[64]; > - char *ptr; > - static struct cmd_ds_fwt_access fwt_access; > - static char out_str[128]; > - int ret; > - > - lbs_deb_enter(LBS_DEB_IOCTL); > - > - if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str))) > - return -EFAULT; > - > - if ((ptr = eth_str2addr(in_str, fwt_access.da)) == NULL) { > - lbs_pr_alert( "FWT_LOOKUP: Invalid MAC address\n"); > - return -EINVAL; > - } > - > -#ifdef DEBUG > - { > - char ethaddr1_str[18]; > - lbs_deb_ioctl("FWT_LOOKUP: line is %s\n", in_str); > - eth_addr2str(fwt_access.da, ethaddr1_str); > - lbs_deb_ioctl("FWT_LOOKUP: looking for (da:%s)\n", ethaddr1_str); > - } > -#endif > - > - ret = libertas_prepare_and_send_command(priv, > - cmd_fwt_access, > - cmd_act_fwt_access_lookup, > - cmd_option_waitforrsp, 0, > - (void *)&fwt_access); > - > - if (ret == 0) > - print_route(fwt_access, out_str); > - else > - sprintf(out_str, "(null)"); > - > - wrq->u.data.length = strlen(out_str); > - if (copy_to_user(wrq->u.data.pointer, (char *)out_str, > - wrq->u.data.length)) { > - lbs_deb_ioctl("FWT_LOOKUP: Copy to user failed!\n"); > - return -EFAULT; > - } > - > - lbs_deb_leave(LBS_DEB_IOCTL); > - return 0; > -} > - > -/** > - * @brief Reset all entries from the FWT table > - * @param priv A pointer to wlan_private structure > - * @return 0 --success, otherwise fail > - */ > -static int wlan_fwt_reset_ioctl(wlan_private * priv) > -{ > - lbs_deb_ioctl("FWT: resetting\n"); > - > - return (libertas_prepare_and_send_command(priv, > - cmd_fwt_access, > - cmd_act_fwt_access_reset, > - cmd_option_waitforrsp, 0, NULL)); > -} > - > -/** > - * @brief List an entry from the FWT table > - * @param priv A pointer to wlan_private structure > - * @param req A pointer to ifreq structure > - * @return 0 --success, otherwise fail > - */ > -static int wlan_fwt_list_ioctl(wlan_private * priv, struct ifreq *req) > -{ > - struct iwreq *wrq = (struct iwreq *)req; > - char in_str[8]; > - static struct cmd_ds_fwt_access fwt_access; > - char *ptr = in_str; > - static char out_str[128]; > - char *pbuf = out_str; > - int ret = 0; > - > - lbs_deb_enter(LBS_DEB_IOCTL); > - > - if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str))) { > - ret = -EFAULT; > - goto out; > - } > - > - fwt_access.id = cpu_to_le32(simple_strtoul(ptr, &ptr, 10)); > - > -#ifdef DEBUG > - { > - lbs_deb_ioctl("FWT_LIST: line is %s\n", in_str); > - lbs_deb_ioctl("FWT_LIST: listing id:%i\n", le32_to_cpu(fwt_access.id)); > - } > -#endif > - > - ret = libertas_prepare_and_send_command(priv, cmd_fwt_access, > - cmd_act_fwt_access_list, > - cmd_option_waitforrsp, 0, (void *)&fwt_access); > - > - if (ret == 0) > - print_route(fwt_access, pbuf); > - else > - pbuf += sprintf(pbuf, " (null)"); > - > - wrq->u.data.length = strlen(out_str); > - if (copy_to_user(wrq->u.data.pointer, (char *)out_str, > - wrq->u.data.length)) { > - lbs_deb_ioctl("FWT_LIST: Copy to user failed!\n"); > - ret = -EFAULT; > - goto out; > - } > - > - ret = 0; > - > -out: > - lbs_deb_leave(LBS_DEB_IOCTL); > - return ret; > -} > - > -/** > - * @brief List an entry from the FRT table > - * @param priv A pointer to wlan_private structure > - * @param req A pointer to ifreq structure > - * @return 0 --success, otherwise fail > - */ > -static int wlan_fwt_list_route_ioctl(wlan_private * priv, struct ifreq *req) > -{ > - struct iwreq *wrq = (struct iwreq *)req; > - char in_str[64]; > - static struct cmd_ds_fwt_access fwt_access; > - char *ptr = in_str; > - static char out_str[128]; > - char *pbuf = out_str; > - int ret; > - > - lbs_deb_enter(LBS_DEB_IOCTL); > - > - if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str))) > - return -EFAULT; > - > - fwt_access.id = cpu_to_le32(simple_strtoul(ptr, &ptr, 10)); > - > -#ifdef DEBUG > - { > - lbs_deb_ioctl("FWT_LIST_ROUTE: line is %s\n", in_str); > - lbs_deb_ioctl("FWT_LIST_ROUTE: listing id:%i\n", le32_to_cpu(fwt_access.id)); > - } > -#endif > - > - ret = libertas_prepare_and_send_command(priv, cmd_fwt_access, > - cmd_act_fwt_access_list_route, > - cmd_option_waitforrsp, 0, (void *)&fwt_access); > - > - if (ret == 0) { > - print_route(fwt_access, pbuf); > - } else > - pbuf += sprintf(pbuf, " (null)"); > - > - wrq->u.data.length = strlen(out_str); > - if (copy_to_user(wrq->u.data.pointer, (char *)out_str, > - wrq->u.data.length)) { > - lbs_deb_ioctl("FWT_LIST_ROUTE: Copy to user failed!\n"); > - return -EFAULT; > - } > - > - lbs_deb_leave(LBS_DEB_IOCTL); > - return 0; > -} > - > -/** > - * @brief List an entry from the FNT table > - * @param priv A pointer to wlan_private structure > - * @param req A pointer to ifreq structure > - * @return 0 --success, otherwise fail > - */ > -static int wlan_fwt_list_neighbor_ioctl(wlan_private * priv, struct ifreq *req) > -{ > - struct iwreq *wrq = (struct iwreq *)req; > - char in_str[8]; > - static struct cmd_ds_fwt_access fwt_access; > - char *ptr = in_str; > - static char out_str[128]; > - char *pbuf = out_str; > - int ret; > - > - lbs_deb_enter(LBS_DEB_IOCTL); > - > - if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str))) > - return -EFAULT; > - > - memset(&fwt_access, 0, sizeof(fwt_access)); > - fwt_access.id = cpu_to_le32(simple_strtoul(ptr, &ptr, 10)); > - > -#ifdef DEBUG > - { > - lbs_deb_ioctl("FWT_LIST_NEIGHBOR: line is %s\n", in_str); > - lbs_deb_ioctl("FWT_LIST_NEIGHBOR: listing id:%i\n", le32_to_cpu(fwt_access.id)); > - } > -#endif > - > - ret = libertas_prepare_and_send_command(priv, cmd_fwt_access, > - cmd_act_fwt_access_list_neighbor, > - cmd_option_waitforrsp, 0, > - (void *)&fwt_access); > - > - if (ret == 0) { > - pbuf += sprintf(pbuf, " ra "); > - pbuf += eth_addr2str(fwt_access.ra, pbuf); > - pbuf += sprintf(pbuf, " slp %u", fwt_access.sleepmode); > - pbuf += sprintf(pbuf, " snr %u", le32_to_cpu(fwt_access.snr)); > - pbuf += sprintf(pbuf, " ref %u", le32_to_cpu(fwt_access.references)); > - } else > - pbuf += sprintf(pbuf, " (null)"); > - > - wrq->u.data.length = strlen(out_str); > - if (copy_to_user(wrq->u.data.pointer, (char *)out_str, > - wrq->u.data.length)) { > - lbs_deb_ioctl("FWT_LIST_NEIGHBOR: Copy to user failed!\n"); > - return -EFAULT; > - } > - > - lbs_deb_leave(LBS_DEB_IOCTL); > - return 0; > -} > - > -/** > - * @brief Cleans up the route (FRT) and neighbor (FNT) tables > - * (Garbage Collection) > - * @param priv A pointer to wlan_private structure > - * @param req A pointer to ifreq structure > - * @return 0 --success, otherwise fail > - */ > -static int wlan_fwt_cleanup_ioctl(wlan_private * priv, struct ifreq *req) > -{ > - struct iwreq *wrq = (struct iwreq *)req; > - static struct cmd_ds_fwt_access fwt_access; > - int ret; > - > - lbs_deb_enter(LBS_DEB_IOCTL); > - > - lbs_deb_ioctl("FWT: cleaning up\n"); > - > - memset(&fwt_access, 0, sizeof(fwt_access)); > - > - ret = libertas_prepare_and_send_command(priv, cmd_fwt_access, > - cmd_act_fwt_access_cleanup, > - cmd_option_waitforrsp, 0, > - (void *)&fwt_access); > - > - if (ret == 0) > - wrq->u.param.value = le32_to_cpu(fwt_access.references); > - else > - return -EFAULT; > - > - lbs_deb_leave(LBS_DEB_IOCTL); > - return 0; > -} > - > -/** > - * @brief Gets firmware internal time (debug purposes) > - * @param priv A pointer to wlan_private structure > - * @param req A pointer to ifreq structure > - * @return 0 --success, otherwise fail > - */ > -static int wlan_fwt_time_ioctl(wlan_private * priv, struct ifreq *req) > -{ > - struct iwreq *wrq = (struct iwreq *)req; > - static struct cmd_ds_fwt_access fwt_access; > - int ret; > - > - lbs_deb_enter(LBS_DEB_IOCTL); > - > - lbs_deb_ioctl("FWT: getting time\n"); > - > - memset(&fwt_access, 0, sizeof(fwt_access)); > - > - ret = libertas_prepare_and_send_command(priv, cmd_fwt_access, > - cmd_act_fwt_access_time, > - cmd_option_waitforrsp, 0, > - (void *)&fwt_access); > - > - if (ret == 0) > - wrq->u.param.value = le32_to_cpu(fwt_access.references); > - else > - return -EFAULT; > - > - lbs_deb_leave(LBS_DEB_IOCTL); > - return 0; > -} > - > -/** > - * @brief Gets mesh ttl from firmware > - * @param priv A pointer to wlan_private structure > - * @param req A pointer to ifreq structure > - * @return 0 --success, otherwise fail > - */ > -static int wlan_mesh_get_ttl_ioctl(wlan_private * priv, struct ifreq *req) > -{ > - struct iwreq *wrq = (struct iwreq *)req; > - struct cmd_ds_mesh_access mesh_access; > - int ret; > - > - lbs_deb_enter(LBS_DEB_IOCTL); > - > - memset(&mesh_access, 0, sizeof(mesh_access)); > - > - ret = libertas_prepare_and_send_command(priv, cmd_mesh_access, > - cmd_act_mesh_get_ttl, > - cmd_option_waitforrsp, 0, > - (void *)&mesh_access); > - > - if (ret == 0) > - wrq->u.param.value = le32_to_cpu(mesh_access.data[0]); > - else > - return -EFAULT; > - > - lbs_deb_leave(LBS_DEB_IOCTL); > - return 0; > -} > - > -/** > - * @brief Gets mesh ttl from firmware > - * @param priv A pointer to wlan_private structure > - * @param ttl New ttl value > - * @return 0 --success, otherwise fail > - */ > -static int wlan_mesh_set_ttl_ioctl(wlan_private * priv, int ttl) > -{ > - struct cmd_ds_mesh_access mesh_access; > - int ret; > - > - lbs_deb_enter(LBS_DEB_IOCTL); > - > - if( (ttl > 0xff) || (ttl < 0) ) > - return -EINVAL; > - > - memset(&mesh_access, 0, sizeof(mesh_access)); > - mesh_access.data[0] = cpu_to_le32(ttl); > - > - ret = libertas_prepare_and_send_command(priv, cmd_mesh_access, > - cmd_act_mesh_set_ttl, > - cmd_option_waitforrsp, 0, > - (void *)&mesh_access); > - > - if (ret != 0) > - ret = -EFAULT; > - > - lbs_deb_leave(LBS_DEB_IOCTL); > - return ret; > -} > - > -/** > - * @brief ioctl function - entry point > - * > - * @param dev A pointer to net_device structure > - * @param req A pointer to ifreq structure > - * @param cmd command > - * @return 0--success, otherwise fail > - */ > -int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd) > -{ > - int subcmd = 0; > - int idata = 0; > - int *pdata; > - int ret = 0; > - wlan_private *priv = dev->priv; > - wlan_adapter *adapter = priv->adapter; > - struct iwreq *wrq = (struct iwreq *)req; > - > - lbs_deb_enter(LBS_DEB_IOCTL); > - > - lbs_deb_ioctl("libertas_do_ioctl: ioctl cmd = 0x%x\n", cmd); > - switch (cmd) { > - case WLAN_SETNONE_GETNONE: /* set WPA mode on/off ioctl #20 */ > - switch (wrq->u.data.flags) { > - case WLAN_SUBCMD_BT_RESET: /* bt_reset */ > - wlan_bt_reset_ioctl(priv); > - break; > - case WLAN_SUBCMD_FWT_RESET: /* fwt_reset */ > - wlan_fwt_reset_ioctl(priv); > - break; > - } /* End of switch */ > - break; > - > - case WLAN_SETONEINT_GETNONE: > - /* The first 4 bytes of req->ifr_data is sub-ioctl number > - * after 4 bytes sits the payload. > - */ > - subcmd = wrq->u.data.flags; > - if (!subcmd) > - subcmd = (int)wrq->u.param.value; > - > - switch (subcmd) { > - case WLANSETREGION: > - idata = SUBCMD_DATA(wrq); > - ret = wlan_set_region(priv, (u16) idata); > - break; > - case WLAN_SUBCMD_MESH_SET_TTL: > - idata = SUBCMD_DATA(wrq); > - ret = wlan_mesh_set_ttl_ioctl(priv, idata); > - break; > - > - case WLAN_SUBCMD_BT_SET_INVERT: > - ret = wlan_bt_set_invert_ioctl(priv, req); > - break ; > - > - default: > - ret = -EOPNOTSUPP; > - break; > - } > - > - break; > - > - case WLAN_SET128CHAR_GET128CHAR: > - switch ((int)wrq->u.data.flags) { > - case WLAN_SUBCMD_BT_ADD: > - ret = wlan_bt_add_ioctl(priv, req); > - break; > - case WLAN_SUBCMD_BT_DEL: > - ret = wlan_bt_del_ioctl(priv, req); > - break; > - case WLAN_SUBCMD_BT_LIST: > - ret = wlan_bt_list_ioctl(priv, req); > - break; > - case WLAN_SUBCMD_FWT_ADD: > - ret = wlan_fwt_add_ioctl(priv, req); > - break; > - case WLAN_SUBCMD_FWT_DEL: > - ret = wlan_fwt_del_ioctl(priv, req); > - break; > - case WLAN_SUBCMD_FWT_LOOKUP: > - ret = wlan_fwt_lookup_ioctl(priv, req); > - break; > - case WLAN_SUBCMD_FWT_LIST_NEIGHBOR: > - ret = wlan_fwt_list_neighbor_ioctl(priv, req); > - break; > - case WLAN_SUBCMD_FWT_LIST: > - ret = wlan_fwt_list_ioctl(priv, req); > - break; > - case WLAN_SUBCMD_FWT_LIST_ROUTE: > - ret = wlan_fwt_list_route_ioctl(priv, req); > - break; > - } > - break; > - > - case WLAN_SETNONE_GETONEINT: > - switch (wrq->u.param.value) { > - case WLANGETREGION: > - pdata = (int *)wrq->u.name; > - *pdata = (int)adapter->regioncode; > - break; > - case WLAN_SUBCMD_FWT_CLEANUP: /* fwt_cleanup */ > - ret = wlan_fwt_cleanup_ioctl(priv, req); > - break; > - > - case WLAN_SUBCMD_FWT_TIME: /* fwt_time */ > - ret = wlan_fwt_time_ioctl(priv, req); > - break; > - > - case WLAN_SUBCMD_MESH_GET_TTL: > - ret = wlan_mesh_get_ttl_ioctl(priv, req); > - break; > - > - case WLAN_SUBCMD_BT_GET_INVERT: > - ret = wlan_bt_get_invert_ioctl(priv, req); > - break ; > - > - default: > - ret = -EOPNOTSUPP; > - > - } > - > - break; > - > - case WLAN_SET_GET_SIXTEEN_INT: > - switch ((int)wrq->u.data.flags) { > - case WLAN_LED_GPIO_CTRL: > - { > - int i; > - int data[16]; > - > - struct cmd_ds_802_11_led_ctrl ctrl; > - struct mrvlietypes_ledgpio *gpio = > - (struct mrvlietypes_ledgpio *) ctrl.data; > - > - memset(&ctrl, 0, sizeof(ctrl)); > - if (wrq->u.data.length > MAX_LEDS * 2) > - return -ENOTSUPP; > - if ((wrq->u.data.length % 2) != 0) > - return -ENOTSUPP; > - if (wrq->u.data.length == 0) { > - ctrl.action = > - cpu_to_le16 > - (cmd_act_get); > - } else { > - if (copy_from_user > - (data, wrq->u.data.pointer, > - sizeof(int) * > - wrq->u.data.length)) { > - lbs_deb_ioctl( > - "Copy from user failed\n"); > - return -EFAULT; > - } > - > - ctrl.action = > - cpu_to_le16 > - (cmd_act_set); > - ctrl.numled = cpu_to_le16(0); > - gpio->header.type = > - cpu_to_le16(TLV_TYPE_LED_GPIO); > - gpio->header.len = wrq->u.data.length; > - for (i = 0; i < wrq->u.data.length; > - i += 2) { > - gpio->ledpin[i / 2].led = > - data[i]; > - gpio->ledpin[i / 2].pin = > - data[i + 1]; > - } > - } > - ret = > - libertas_prepare_and_send_command(priv, > - cmd_802_11_led_gpio_ctrl, > - 0, > - cmd_option_waitforrsp, > - 0, (void *)&ctrl); > - for (i = 0; i < gpio->header.len; i += 2) { > - data[i] = gpio->ledpin[i / 2].led; > - data[i + 1] = gpio->ledpin[i / 2].pin; > - } > - if (copy_to_user(wrq->u.data.pointer, data, > - sizeof(int) * > - gpio->header.len)) { > - lbs_deb_ioctl("Copy to user failed\n"); > - return -EFAULT; > - } > - > - wrq->u.data.length = gpio->header.len; > - } > - break; > - } > - break; > - > - default: > - ret = -EINVAL; > - break; > - } > - > - lbs_deb_leave_args(LBS_DEB_IOCTL, "ret %d", ret); > - return ret; > -} > - > - > Index: linux-2.6/drivers/net/wireless/libertas/main.c > =================================================================== > --- linux-2.6.orig/drivers/net/wireless/libertas/main.c 2007-06-14 18:49:15.000000000 +0200 > +++ linux-2.6/drivers/net/wireless/libertas/main.c 2007-06-14 18:49:19.000000000 +0200 > @@ -799,7 +799,6 @@ wlan_private *libertas_add_card(void *ca > dev->open = wlan_open; > dev->hard_start_xmit = wlan_pre_start_xmit; > dev->stop = wlan_close; > - dev->do_ioctl = libertas_do_ioctl; > dev->set_mac_address = wlan_set_mac_address; > dev->tx_timeout = wlan_tx_timeout; > dev->get_stats = wlan_get_stats; > @@ -918,7 +917,6 @@ int libertas_add_mesh(wlan_private *priv > mesh_dev->open = mesh_open; > mesh_dev->hard_start_xmit = mesh_pre_start_xmit; > mesh_dev->stop = mesh_close; > - mesh_dev->do_ioctl = libertas_do_ioctl; > mesh_dev->get_stats = wlan_get_stats; > mesh_dev->set_mac_address = wlan_set_mac_address; > mesh_dev->ethtool_ops = &libertas_ethtool_ops; > Index: linux-2.6/drivers/net/wireless/libertas/wext.h > =================================================================== > --- linux-2.6.orig/drivers/net/wireless/libertas/wext.h 2007-06-14 18:49:33.000000000 +0200 > +++ linux-2.6/drivers/net/wireless/libertas/wext.h 2007-06-14 19:10:31.000000000 +0200 > @@ -7,45 +7,6 @@ > #define SUBCMD_OFFSET 4 > #define SUBCMD_DATA(x) *((int *)(x->u.name + SUBCMD_OFFSET)) > > -/** PRIVATE CMD ID */ > -#define WLANIOCTL SIOCIWFIRSTPRIV > - > -#define WLAN_SETNONE_GETNONE (WLANIOCTL + 8) > -#define WLAN_SUBCMD_BT_RESET 13 > -#define WLAN_SUBCMD_FWT_RESET 14 > - > -#define WLAN_SETNONE_GETONEINT (WLANIOCTL + 15) > -#define WLANGETREGION 1 > - > -#define WLAN_SUBCMD_FWT_CLEANUP 15 > -#define WLAN_SUBCMD_FWT_TIME 16 > -#define WLAN_SUBCMD_MESH_GET_TTL 17 > -#define WLAN_SUBCMD_BT_GET_INVERT 18 > - > -#define WLAN_SETONEINT_GETNONE (WLANIOCTL + 24) > -#define WLANSETREGION 8 > -#define WLAN_SUBCMD_MESH_SET_TTL 18 > -#define WLAN_SUBCMD_BT_SET_INVERT 19 > - > -#define WLAN_SET128CHAR_GET128CHAR (WLANIOCTL + 25) > -#define WLAN_SUBCMD_BT_ADD 18 > -#define WLAN_SUBCMD_BT_DEL 19 > -#define WLAN_SUBCMD_BT_LIST 20 > -#define WLAN_SUBCMD_FWT_ADD 21 > -#define WLAN_SUBCMD_FWT_DEL 22 > -#define WLAN_SUBCMD_FWT_LOOKUP 23 > -#define WLAN_SUBCMD_FWT_LIST_NEIGHBOR 24 > -#define WLAN_SUBCMD_FWT_LIST 25 > -#define WLAN_SUBCMD_FWT_LIST_ROUTE 26 > - > -#define WLAN_SET_GET_SIXTEEN_INT (WLANIOCTL + 29) > -#define WLAN_LED_GPIO_CTRL 5 > - > -#define WLAN_LINKMODE_802_3 0 > -#define WLAN_LINKMODE_802_11 2 > -#define WLAN_RADIOMODE_NONE 0 > -#define WLAN_RADIOMODE_RADIOTAP 2 > - > /** wlan_ioctl_regrdwr */ > struct wlan_ioctl_regrdwr { > /** Which register to access */ > @@ -57,9 +18,13 @@ struct wlan_ioctl_regrdwr { > u32 value; > }; > > +#define WLAN_LINKMODE_802_3 0 > +#define WLAN_LINKMODE_802_11 2 > +#define WLAN_RADIOMODE_NONE 0 > +#define WLAN_RADIOMODE_RADIOTAP 2 > + > extern struct iw_handler_def libertas_handler_def; > extern struct iw_handler_def mesh_handler_def; > -int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int i); > int wlan_radio_ioctl(wlan_private * priv, u8 option); > > #endif /* _WLAN_WEXT_H_ */ > Index: linux-2.6/drivers/net/wireless/libertas/wext.c > =================================================================== > --- linux-2.6.orig/drivers/net/wireless/libertas/wext.c 2007-06-14 18:49:28.000000000 +0200 > +++ linux-2.6/drivers/net/wireless/libertas/wext.c 2007-06-14 19:08:42.000000000 +0200 > @@ -913,148 +913,6 @@ out: > return 0; > } > > -/* > - * iwpriv settable callbacks > - */ > - > -static const iw_handler wlan_private_handler[] = { > - NULL, /* SIOCIWFIRSTPRIV */ > -}; > - > -static const struct iw_priv_args wlan_private_args[] = { > - /* > - * { cmd, set_args, get_args, name } > - */ > - /* Using iwpriv sub-command feature */ > - { > - WLAN_SETONEINT_GETNONE, /* IOCTL: 24 */ > - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, > - IW_PRIV_TYPE_NONE, > - ""}, > - { > - WLANSETREGION, > - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, > - IW_PRIV_TYPE_NONE, > - "setregioncode"}, > - { > - WLAN_SUBCMD_MESH_SET_TTL, > - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, > - IW_PRIV_TYPE_NONE, > - "mesh_set_ttl"}, > - { > - WLAN_SETNONE_GETONEINT, > - IW_PRIV_TYPE_NONE, > - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, > - ""}, > - { > - WLANGETREGION, > - IW_PRIV_TYPE_NONE, > - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, > - "getregioncode"}, > - { > - WLAN_SUBCMD_FWT_CLEANUP, > - IW_PRIV_TYPE_NONE, > - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, > - "fwt_cleanup"}, > - { > - WLAN_SUBCMD_FWT_TIME, > - IW_PRIV_TYPE_NONE, > - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, > - "fwt_time"}, > - { > - WLAN_SUBCMD_MESH_GET_TTL, > - IW_PRIV_TYPE_NONE, > - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, > - "mesh_get_ttl"}, > - { > - WLAN_SETNONE_GETNONE, > - IW_PRIV_TYPE_NONE, > - IW_PRIV_TYPE_NONE, > - ""}, > - { > - WLAN_SUBCMD_FWT_RESET, > - IW_PRIV_TYPE_NONE, > - IW_PRIV_TYPE_NONE, > - "fwt_reset"}, > - { > - WLAN_SUBCMD_BT_RESET, > - IW_PRIV_TYPE_NONE, > - IW_PRIV_TYPE_NONE, > - "bt_reset"}, > - { > - WLAN_SET128CHAR_GET128CHAR, > - IW_PRIV_TYPE_CHAR | 128, > - IW_PRIV_TYPE_CHAR | 128, > - ""}, > - /* BT Management */ > - { > - WLAN_SUBCMD_BT_ADD, > - IW_PRIV_TYPE_CHAR | 128, > - IW_PRIV_TYPE_CHAR | 128, > - "bt_add"}, > - { > - WLAN_SUBCMD_BT_DEL, > - IW_PRIV_TYPE_CHAR | 128, > - IW_PRIV_TYPE_CHAR | 128, > - "bt_del"}, > - { > - WLAN_SUBCMD_BT_LIST, > - IW_PRIV_TYPE_CHAR | 128, > - IW_PRIV_TYPE_CHAR | 128, > - "bt_list"}, > - { > - WLAN_SUBCMD_BT_SET_INVERT, > - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, > - IW_PRIV_TYPE_NONE, > - "bt_set_invert"}, > - { > - WLAN_SUBCMD_BT_GET_INVERT, > - IW_PRIV_TYPE_NONE, > - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, > - "bt_get_invert"}, > - /* FWT Management */ > - { > - WLAN_SUBCMD_FWT_ADD, > - IW_PRIV_TYPE_CHAR | 128, > - IW_PRIV_TYPE_CHAR | 128, > - "fwt_add"}, > - { > - WLAN_SUBCMD_FWT_DEL, > - IW_PRIV_TYPE_CHAR | 128, > - IW_PRIV_TYPE_CHAR | 128, > - "fwt_del"}, > - { > - WLAN_SUBCMD_FWT_LOOKUP, > - IW_PRIV_TYPE_CHAR | 128, > - IW_PRIV_TYPE_CHAR | 128, > - "fwt_lookup"}, > - { > - WLAN_SUBCMD_FWT_LIST_NEIGHBOR, > - IW_PRIV_TYPE_CHAR | 128, > - IW_PRIV_TYPE_CHAR | 128, > - "fwt_list_neigh"}, > - { > - WLAN_SUBCMD_FWT_LIST, > - IW_PRIV_TYPE_CHAR | 128, > - IW_PRIV_TYPE_CHAR | 128, > - "fwt_list"}, > - { > - WLAN_SUBCMD_FWT_LIST_ROUTE, > - IW_PRIV_TYPE_CHAR | 128, > - IW_PRIV_TYPE_CHAR | 128, > - "fwt_list_route"}, > - { > - WLAN_SET_GET_SIXTEEN_INT, > - IW_PRIV_TYPE_INT | 16, > - IW_PRIV_TYPE_INT | 16, > - ""}, > - { > - WLAN_LED_GPIO_CTRL, > - IW_PRIV_TYPE_INT | 16, > - IW_PRIV_TYPE_INT | 16, > - "ledgpio"}, > -}; > - > static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev) > { > enum { > @@ -2444,22 +2302,12 @@ static const iw_handler mesh_wlan_handle > }; > struct iw_handler_def libertas_handler_def = { > .num_standard = sizeof(wlan_handler) / sizeof(iw_handler), > - .num_private = sizeof(wlan_private_handler) / sizeof(iw_handler), > - .num_private_args = sizeof(wlan_private_args) / > - sizeof(struct iw_priv_args), > .standard = (iw_handler *) wlan_handler, > - .private = (iw_handler *) wlan_private_handler, > - .private_args = (struct iw_priv_args *)wlan_private_args, > .get_wireless_stats = wlan_get_wireless_stats, > }; > > struct iw_handler_def mesh_handler_def = { > .num_standard = sizeof(mesh_wlan_handler) / sizeof(iw_handler), > - .num_private = sizeof(wlan_private_handler) / sizeof(iw_handler), > - .num_private_args = sizeof(wlan_private_args) / > - sizeof(struct iw_priv_args), > .standard = (iw_handler *) mesh_wlan_handler, > - .private = (iw_handler *) wlan_private_handler, > - .private_args = (struct iw_priv_args *)wlan_private_args, > .get_wireless_stats = wlan_get_wireless_stats, > }; ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: libertas (private) ioctls vs. nl80211 2007-06-18 17:38 ` Dan Williams @ 2007-06-18 18:44 ` Christoph Hellwig 2007-06-18 18:57 ` Sam Ravnborg 0 siblings, 1 reply; 17+ messages in thread From: Christoph Hellwig @ 2007-06-18 18:44 UTC (permalink / raw) To: Dan Williams Cc: Christoph Hellwig, Andrew Morton, johannes, linux-wireless, hs4233, linux-kernel, Linus Torvalds On Mon, Jun 18, 2007 at 01:38:47PM -0400, Dan Williams wrote: > On Thu, 2007-06-14 at 19:13 +0100, Christoph Hellwig wrote: > > > I suspect that the probability of your proposal succeeding would be increased > > > if you could prepare a patch... > > Applied to upstream-fixes branch of libertas-2.6 which is destined for > 2.6.22; I hope you don't mind that I just added the Signed-off-by for > you. Adding a signed off line for a patch that purely removes codes seems rather pointless to me, but feel free to add it if you care. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: libertas (private) ioctls vs. nl80211 2007-06-18 18:44 ` Christoph Hellwig @ 2007-06-18 18:57 ` Sam Ravnborg 0 siblings, 0 replies; 17+ messages in thread From: Sam Ravnborg @ 2007-06-18 18:57 UTC (permalink / raw) To: Christoph Hellwig, Dan Williams, Andrew Morton, johannes, linux-wireless, hs4233, linux-kernel, Linus Torvalds On Mon, Jun 18, 2007 at 07:44:36PM +0100, Christoph Hellwig wrote: > On Mon, Jun 18, 2007 at 01:38:47PM -0400, Dan Williams wrote: > > On Thu, 2007-06-14 at 19:13 +0100, Christoph Hellwig wrote: > > > > I suspect that the probability of your proposal succeeding would be increased > > > > if you could prepare a patch... > > > > Applied to upstream-fixes branch of libertas-2.6 which is destined for > > 2.6.22; I hope you don't mind that I just added the Signed-off-by for > > you. > > Adding a signed off line for a patch that purely removes codes seems > rather pointless to me, but feel free to add it if you care. THe Signed-off-by: document the path a given patch have taken on its way to the final acceptance and does not have any significance whatsoever about the content of the patch. Anyone on the Signed-of-by route may change the patch (and I often do so) without further notice. So judging if a Signed-off-by: should be added or not based on patch content is wrong. It is a patch anyway. That said the legal(in a loose definition of legal) rationale may be of much less significance when trivially removing some code. But we use the same mechanish even to cover spelling corrections. Sam ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: libertas (private) ioctls vs. nl80211 2007-06-14 17:09 ` libertas (private) ioctls vs. nl80211 Christoph Hellwig 2007-06-14 17:38 ` Andrew Morton @ 2007-06-14 20:03 ` Holger Schurig 2007-06-14 22:48 ` Dan Williams 1 sibling, 1 reply; 17+ messages in thread From: Holger Schurig @ 2007-06-14 20:03 UTC (permalink / raw) To: Christoph Hellwig, Johannes Berg, linux-wireless, Dan Williams, akpm, linux-kernel > Independent of any nl80211 status the private libertas ioctls have to > go. Not only don't we want private ioctls for mesh networking but > rather have it as driver-independent interface, but the actual > libertas interface is the worst possible choice. I have been told that the Libertas mesh functionality is not 802.11s, Marvell brew their own beer (because it predates 802.11s, I guess). However, for the kernel I'd see more an interface that supports 802.11s --- or is flexible to support both this and the libertas one. I also have two related observations: If I'm correctt, the only non-mesh ioctl in ioctl.c is the led_gpio ioctl. Theoretically one can abstract this, many WLAN chips have GPIOs. But mostly there is no documentation available about how those GPIOs are used, where they are soldered to etc. To blindly allow changing arbitrary GPIOs migth even be harmful to the hardware. That said: with the USB 8388 dongle that I have, the LED GPIO iwpriv call didn't do anything. Not sure if it works on OLPC ... but I doubt that one can see the LEDs there ... Another thing: I'm working on a CF 8385 based driver. Here I have a firmware that does not (as far as I know this undocumented pile of bytes) have any mesh functionality at all. So I need a way from if_cs.c to disable all those iwpriv ioctls. Haven't thought about this issue yet, other things are more pressing right now. However, I already don't create the mshX interface. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: libertas (private) ioctls vs. nl80211 2007-06-14 20:03 ` Holger Schurig @ 2007-06-14 22:48 ` Dan Williams 0 siblings, 0 replies; 17+ messages in thread From: Dan Williams @ 2007-06-14 22:48 UTC (permalink / raw) To: Holger Schurig Cc: Christoph Hellwig, Johannes Berg, linux-wireless, akpm, linux-kernel On Thu, 2007-06-14 at 22:03 +0200, Holger Schurig wrote: > > Independent of any nl80211 status the private libertas ioctls have to > > go. Not only don't we want private ioctls for mesh networking but > > rather have it as driver-independent interface, but the actual > > libertas interface is the worst possible choice. > > I have been told that the Libertas mesh functionality is not 802.11s, Technically this is correct. A bit more back-story though. 802.11s is still in draft form. It'll be there for a while yet. Stuff like authentication and encryption are in heavy flux. Previously, the mesh stuff was using the 4th value in the 802.11 frame type. But it turns out that a lot of fullmac parts can't handle that because they drop those frames in silicon. So the standard is moving towards using WDS frames without changing the frame type, which is what the Marvell implementation is _already_ using. I repeat, the standard is moving towards the Marvell mesh implementation. Furthermore, the CozyBit guys who wrote the Marvell mesh implementation are heavily involved in the 802.11s standards groups anyway. > Marvell brew their own beer (because it predates 802.11s, I guess). > However, for the kernel I'd see more an interface that supports > 802.11s --- or is flexible to support both this and the libertas one. Definitely; > I also have two related observations: > > If I'm correctt, the only non-mesh ioctl in ioctl.c is the led_gpio > ioctl. Theoretically one can abstract this, many WLAN chips have GPIOs. Plus the set_region call that can be replaced by whatever the regulatory stuff comes up with. > But mostly there is no documentation available about how those GPIOs > are used, where they are soldered to etc. To blindly allow changing > arbitrary GPIOs migth even be harmful to the hardware. > > That said: with the USB 8388 dongle that I have, the LED GPIO iwpriv > call didn't do anything. Not sure if it works on OLPC ... but I doubt > that one can see the LEDs there ... I think it's all dependent on the firmware; do you know what version of the CF firmware you have? The ledgpio function is apparently from an older version of the firmware but is still in our 8388 5.x branch. There's apparently a new command for this sort of thing. > Another thing: I'm working on a CF 8385 based driver. Here I have a > firmware that does not (as far as I know this undocumented pile of > bytes) have any mesh functionality at all. So I need a way from if_cs.c > to disable all those iwpriv ioctls. Haven't thought about this issue > yet, other things are more pressing right now. However, I already don't > create the mshX interface. Well, can't the ioctl stuff just return -EOPNOTSUPP or something if mesh isn't available? Dan ^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2007-06-18 18:56 UTC | newest] Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- [not found] <1181757483.29767.99.camel@johannes.berg> 2007-06-14 17:09 ` libertas (private) ioctls vs. nl80211 Christoph Hellwig 2007-06-14 17:38 ` Andrew Morton 2007-06-14 18:13 ` Christoph Hellwig 2007-06-14 18:23 ` Linus Torvalds 2007-06-14 18:48 ` Jeff Garzik 2007-06-14 22:22 ` Dan Williams 2007-06-14 22:31 ` Christoph Hellwig 2007-06-14 22:55 ` Dan Williams 2007-06-14 19:09 ` John W. Linville 2007-06-14 19:56 ` Andrew Morton 2007-06-14 20:08 ` John W. Linville 2007-06-17 4:46 ` Matt Mackall 2007-06-18 17:38 ` Dan Williams 2007-06-18 18:44 ` Christoph Hellwig 2007-06-18 18:57 ` Sam Ravnborg 2007-06-14 20:03 ` Holger Schurig 2007-06-14 22:48 ` Dan Williams
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).