diff options
Diffstat (limited to 'drivers/net/wireless/libertas')
33 files changed, 3530 insertions, 5007 deletions
diff --git a/drivers/net/wireless/libertas/11d.c b/drivers/net/wireless/libertas/11d.c index e0ecc4d483b..4cf0ff7b833 100644 --- a/drivers/net/wireless/libertas/11d.c +++ b/drivers/net/wireless/libertas/11d.c @@ -95,7 +95,7 @@ static u8 wlan_get_chan_11d(u8 band, u8 firstchan, u8 nrchan, u8 * chan) for (i = 0; i < cfp_no; i++) { if ((cfp + i)->channel == firstchan) { - lbs_pr_debug(1, "firstchan found\n"); + lbs_deb_11d("firstchan found\n"); break; } } @@ -129,12 +129,12 @@ static u8 wlan_channel_known_11d(u8 chan, for (i = 0; i < nr_chan; i++) { if (chan == chanpwr[i].chan) { - lbs_pr_debug(1, "11D: Found Chan:%d\n", chan); + lbs_deb_11d("11D: Found Chan:%d\n", chan); return 1; } } - lbs_pr_debug(1, "11D: Not Find Chan:%d\n", chan); + lbs_deb_11d("11D: Not Find Chan:%d\n", chan); return 0; } @@ -174,7 +174,7 @@ static int generate_domain_info_11d(struct parsed_region_chan_11d memcpy(domaininfo->countrycode, parsed_region_chan->countrycode, COUNTRY_CODE_LEN); - lbs_pr_debug(1, "11D:nrchan=%d\n", nr_chan); + lbs_deb_11d("11D:nrchan=%d\n", nr_chan); lbs_dbg_hex("11D:parsed_region_chan:", (char *)parsed_region_chan, sizeof(struct parsed_region_chan_11d)); @@ -212,7 +212,7 @@ static int generate_domain_info_11d(struct parsed_region_chan_11d } domaininfo->nr_subband = nr_subband; - lbs_pr_debug(1, "nr_subband=%x\n", domaininfo->nr_subband); + lbs_deb_11d("nr_subband=%x\n", domaininfo->nr_subband); lbs_dbg_hex("11D:domaininfo:", (char *)domaininfo, COUNTRY_CODE_LEN + 1 + sizeof(struct ieeetypes_subbandset) * nr_subband); @@ -233,13 +233,13 @@ static void wlan_generate_parsed_region_chan_11d(struct region_channel * region_ struct chan_freq_power *cfp; if (region_chan == NULL) { - lbs_pr_debug(1, "11D: region_chan is NULL\n"); + lbs_deb_11d("11D: region_chan is NULL\n"); return; } cfp = region_chan->CFP; if (cfp == NULL) { - lbs_pr_debug(1, "11D: cfp equal NULL \n"); + lbs_deb_11d("11D: cfp equal NULL \n"); return; } @@ -248,19 +248,19 @@ static void wlan_generate_parsed_region_chan_11d(struct region_channel * region_ memcpy(parsed_region_chan->countrycode, wlan_code_2_region(region_chan->region), COUNTRY_CODE_LEN); - lbs_pr_debug(1, "11D: region[0x%x] band[%d]\n", parsed_region_chan->region, + lbs_deb_11d("11D: region[0x%x] band[%d]\n", parsed_region_chan->region, parsed_region_chan->band); for (i = 0; i < region_chan->nrcfp; i++, cfp++) { parsed_region_chan->chanpwr[i].chan = cfp->channel; parsed_region_chan->chanpwr[i].pwr = cfp->maxtxpower; - lbs_pr_debug(1, "11D: Chan[%d] Pwr[%d]\n", + lbs_deb_11d("11D: Chan[%d] Pwr[%d]\n", parsed_region_chan->chanpwr[i].chan, parsed_region_chan->chanpwr[i].pwr); } parsed_region_chan->nr_chan = region_chan->nrcfp; - lbs_pr_debug(1, "11D: nrchan[%d]\n", parsed_region_chan->nr_chan); + lbs_deb_11d("11D: nrchan[%d]\n", parsed_region_chan->nr_chan); return; } @@ -277,8 +277,9 @@ static u8 wlan_region_chan_supported_11d(u8 region, u8 band, u8 chan) struct chan_freq_power *cfp; int cfp_no; u8 idx; + int ret = 0; - ENTER(); + lbs_deb_enter(LBS_DEB_11D); cfp = libertas_get_region_cfp_table(region, band, &cfp_no); if (cfp == NULL) @@ -288,16 +289,19 @@ static u8 wlan_region_chan_supported_11d(u8 region, u8 band, u8 chan) if (chan == (cfp + idx)->channel) { /* If Mrvl Chip Supported? */ if ((cfp + idx)->unsupported) { - return 0; + ret = 0; } else { - return 1; + ret = 1; } + goto done; } } /*chan is not in the region table */ - LEAVE(); - return 0; + +done: + lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret); + return ret; } /** @@ -321,7 +325,7 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset* u8 j, i; - ENTER(); + lbs_deb_enter(LBS_DEB_11D); /*validation Rules: 1. valid region Code @@ -337,15 +341,14 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset* if ((*(countryinfo->countrycode)) == 0 || (countryinfo->len <= COUNTRY_CODE_LEN)) { /* No region Info or Wrong region info: treat as No 11D info */ - LEAVE(); - return 0; + goto done; } /*Step1: check region_code */ parsed_region_chan->region = region = wlan_region_2_code(countryinfo->countrycode); - lbs_pr_debug(1, "regioncode=%x\n", (u8) parsed_region_chan->region); + lbs_deb_11d("regioncode=%x\n", (u8) parsed_region_chan->region); lbs_dbg_hex("CountryCode:", (char *)countryinfo->countrycode, COUNTRY_CODE_LEN); @@ -361,7 +364,7 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset* if (countryinfo->subband[j].firstchan <= lastchan) { /*Step2&3. Check First Chan Num increment and no overlap */ - lbs_pr_debug(1, "11D: Chan[%d>%d] Overlap\n", + lbs_deb_11d("11D: Chan[%d>%d] Overlap\n", countryinfo->subband[j].firstchan, lastchan); continue; } @@ -374,7 +377,7 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset* if (!wlan_get_chan_11d(band, firstchan, i, &curchan)) { /* Chan is not found in UN table */ - lbs_pr_debug(1, "chan is not supported: %d \n", i); + lbs_deb_11d("chan is not supported: %d \n", i); break; } @@ -389,7 +392,7 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset* idx++; } else { /*not supported and ignore the chan */ - lbs_pr_debug(1, + lbs_deb_11d( "11D:i[%d] chan[%d] unsupported in region[%x] band[%d]\n", i, curchan, region, band); } @@ -401,11 +404,12 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset* parsed_region_chan->nr_chan = idx; - lbs_pr_debug(1, "nrchan=%x\n", parsed_region_chan->nr_chan); + lbs_deb_11d("nrchan=%x\n", parsed_region_chan->nr_chan); lbs_dbg_hex("11D:parsed_region_chan:", (u8 *) parsed_region_chan, 2 + COUNTRY_CODE_LEN + sizeof(struct parsed_region_chan_11d) * idx); - LEAVE(); +done: + lbs_deb_enter(LBS_DEB_11D); return 0; } @@ -420,16 +424,16 @@ u8 libertas_get_scan_type_11d(u8 chan, { u8 scan_type = cmd_scan_type_passive; - ENTER(); + lbs_deb_enter(LBS_DEB_11D); if (wlan_channel_known_11d(chan, parsed_region_chan)) { - lbs_pr_debug(1, "11D: Found and do Active Scan\n"); + lbs_deb_11d("11D: Found and do Active Scan\n"); scan_type = cmd_scan_type_active; } else { - lbs_pr_debug(1, "11D: Not Find and do Passive Scan\n"); + lbs_deb_11d("11D: Not Find and do Passive Scan\n"); } - LEAVE(); + lbs_deb_leave_args(LBS_DEB_11D, "ret scan_type %d", scan_type); return scan_type; } @@ -456,7 +460,7 @@ static int wlan_enable_11d(wlan_private * priv, u8 flag) OID_802_11D_ENABLE, &priv->adapter->enable11d); if (ret) - lbs_pr_debug(1, "11D: Fail to enable 11D \n"); + lbs_deb_11d("11D: Fail to enable 11D \n"); return 0; } @@ -471,7 +475,7 @@ static int set_domain_info_11d(wlan_private * priv) int ret; if (!priv->adapter->enable11d) { - lbs_pr_debug(1, "11D: dnld domain Info with 11d disabled\n"); + lbs_deb_11d("11D: dnld domain Info with 11d disabled\n"); return 0; } @@ -479,7 +483,7 @@ static int set_domain_info_11d(wlan_private * priv) cmd_act_set, cmd_option_waitforrsp, 0, NULL); if (ret) - lbs_pr_debug(1, "11D: Fail to dnld domain Info\n"); + lbs_deb_11d("11D: Fail to dnld domain Info\n"); return ret; } @@ -501,7 +505,7 @@ int libertas_set_universaltable(wlan_private * priv, u8 band) adapter->universal_channel[i].nrcfp = sizeof(channel_freq_power_UN_BG) / size; - lbs_pr_debug(1, "11D: BG-band nrcfp=%d\n", + lbs_deb_11d("11D: BG-band nrcfp=%d\n", adapter->universal_channel[i].nrcfp); adapter->universal_channel[i].CFP = channel_freq_power_UN_BG; @@ -531,9 +535,9 @@ int libertas_cmd_802_11d_domain_info(wlan_private * priv, wlan_adapter *adapter = priv->adapter; u8 nr_subband = adapter->domainreg.nr_subband; - ENTER(); + lbs_deb_enter(LBS_DEB_11D); - lbs_pr_debug(1, "nr_subband=%x\n", nr_subband); + lbs_deb_11d("nr_subband=%x\n", nr_subband); cmd->command = cpu_to_le16(cmdno); pdomaininfo->action = cpu_to_le16(cmdoption); @@ -542,8 +546,7 @@ int libertas_cmd_802_11d_domain_info(wlan_private * priv, cpu_to_le16(sizeof(pdomaininfo->action) + S_DS_GEN); lbs_dbg_hex("11D: 802_11D_DOMAIN_INFO:", (u8 *) cmd, (int)(cmd->size)); - LEAVE(); - return 0; + goto done; } domain->header.type = cpu_to_le16(TLV_TYPE_DOMAIN); @@ -567,10 +570,10 @@ int libertas_cmd_802_11d_domain_info(wlan_private * priv, cpu_to_le16(sizeof(pdomaininfo->action) + S_DS_GEN); } - lbs_dbg_hex("11D:802_11D_DOMAIN_INFO:", (u8 *) cmd, (int)(cmd->size)); - - LEAVE(); + lbs_dbg_hex("11D:802_11D_DOMAIN_INFO:", (u8 *) cmd, le16_to_cpu(cmd->size)); +done: + lbs_deb_enter(LBS_DEB_11D); return 0; } @@ -585,17 +588,17 @@ int libertas_cmd_enable_11d(wlan_private * priv, struct iwreq *wrq) int data = 0; int *val; - ENTER(); + lbs_deb_enter(LBS_DEB_11D); data = SUBCMD_DATA(wrq); - lbs_pr_debug(1, "enable 11D: %s\n", + lbs_deb_11d("enable 11D: %s\n", (data == 1) ? "enable" : "Disable"); wlan_enable_11d(priv, data); val = (int *)wrq->u.name; *val = priv->adapter->enable11d; - LEAVE(); + lbs_deb_enter(LBS_DEB_11D); return 0; } @@ -608,25 +611,24 @@ int libertas_cmd_enable_11d(wlan_private * priv, struct iwreq *wrq) int libertas_ret_802_11d_domain_info(wlan_private * priv, struct cmd_ds_command *resp) { - struct cmd_ds_802_11d_domain_info - *domaininfo = &resp->params.domaininforesp; + struct cmd_ds_802_11d_domain_info *domaininfo = &resp->params.domaininforesp; struct mrvlietypes_domainparamset *domain = &domaininfo->domain; u16 action = le16_to_cpu(domaininfo->action); s16 ret = 0; u8 nr_subband = 0; - ENTER(); + lbs_deb_enter(LBS_DEB_11D); lbs_dbg_hex("11D DOMAIN Info Rsp Data:", (u8 *) resp, (int)le16_to_cpu(resp->size)); - nr_subband = (domain->header.len - 3) / sizeof(struct ieeetypes_subbandset); - /* countrycode 3 bytes */ + nr_subband = (le16_to_cpu(domain->header.len) - COUNTRY_CODE_LEN) / + sizeof(struct ieeetypes_subbandset); - lbs_pr_debug(1, "11D Domain Info Resp: nr_subband=%d\n", nr_subband); + lbs_deb_11d("11D Domain Info Resp: nr_subband=%d\n", nr_subband); if (nr_subband > MRVDRV_MAX_SUBBAND_802_11D) { - lbs_pr_debug(1, "Invalid Numrer of Subband returned!!\n"); + lbs_deb_11d("Invalid Numrer of Subband returned!!\n"); return -1; } @@ -637,12 +639,12 @@ int libertas_ret_802_11d_domain_info(wlan_private * priv, case cmd_act_get: break; default: - lbs_pr_debug(1, "Invalid action:%d\n", domaininfo->action); + lbs_deb_11d("Invalid action:%d\n", domaininfo->action); ret = -1; break; } - LEAVE(); + lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret); return ret; } @@ -651,23 +653,22 @@ int libertas_ret_802_11d_domain_info(wlan_private * priv, * @param priv pointer to wlan_private * @return 0; -1 */ -int libertas_parse_dnld_countryinfo_11d(wlan_private * priv) +int libertas_parse_dnld_countryinfo_11d(wlan_private * priv, + struct bss_descriptor * bss) { int ret; wlan_adapter *adapter = priv->adapter; - ENTER(); + lbs_deb_enter(LBS_DEB_11D); if (priv->adapter->enable11d) { memset(&adapter->parsed_region_chan, 0, sizeof(struct parsed_region_chan_11d)); - ret = parse_domain_info_11d(&adapter->pattemptedbssdesc-> - countryinfo, 0, + ret = parse_domain_info_11d(&bss->countryinfo, 0, &adapter->parsed_region_chan); if (ret == -1) { - lbs_pr_debug(1, "11D: Err Parse domain_info from AP..\n"); - LEAVE(); - return ret; + lbs_deb_11d("11D: Err Parse domain_info from AP..\n"); + goto done; } memset(&adapter->domainreg, 0, @@ -678,13 +679,15 @@ int libertas_parse_dnld_countryinfo_11d(wlan_private * priv) ret = set_domain_info_11d(priv); if (ret) { - lbs_pr_debug(1, "11D: Err set domainInfo to FW\n"); - LEAVE(); - return ret; + lbs_deb_11d("11D: Err set domainInfo to FW\n"); + goto done; } } - LEAVE(); - return 0; + ret = 0; + +done: + lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret); + return ret; } /** @@ -699,8 +702,8 @@ int libertas_create_dnld_countryinfo_11d(wlan_private * priv) struct region_channel *region_chan; u8 j; - ENTER(); - lbs_pr_debug(1, "11D:curbssparams.band[%d]\n", adapter->curbssparams.band); + lbs_deb_enter(LBS_DEB_11D); + lbs_deb_11d("11D:curbssparams.band[%d]\n", adapter->curbssparams.band); if (priv->adapter->enable11d) { /* update parsed_region_chan_11; dnld domaininf to FW */ @@ -709,7 +712,7 @@ int libertas_create_dnld_countryinfo_11d(wlan_private * priv) sizeof(adapter->region_channel[0]); j++) { region_chan = &adapter->region_channel[j]; - lbs_pr_debug(1, "11D:[%d] region_chan->band[%d]\n", j, + lbs_deb_11d("11D:[%d] region_chan->band[%d]\n", j, region_chan->band); if (!region_chan || !region_chan->valid @@ -722,10 +725,10 @@ int libertas_create_dnld_countryinfo_11d(wlan_private * priv) if (j >= sizeof(adapter->region_channel) / sizeof(adapter->region_channel[0])) { - lbs_pr_debug(1, "11D:region_chan not found. band[%d]\n", + lbs_deb_11d("11D:region_chan not found. band[%d]\n", adapter->curbssparams.band); - LEAVE(); - return -1; + ret = -1; + goto done; } memset(&adapter->parsed_region_chan, 0, @@ -742,13 +745,14 @@ int libertas_create_dnld_countryinfo_11d(wlan_private * priv) ret = set_domain_info_11d(priv); if (ret) { - lbs_pr_debug(1, "11D: Err set domainInfo to FW\n"); - LEAVE(); - return ret; + lbs_deb_11d("11D: Err set domainInfo to FW\n"); + goto done; } } + ret = 0; - LEAVE(); - return 0; +done: + lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret); + return ret; } diff --git a/drivers/net/wireless/libertas/11d.h b/drivers/net/wireless/libertas/11d.h index db2ebea9f23..73e42e71291 100644 --- a/drivers/net/wireless/libertas/11d.h +++ b/drivers/net/wireless/libertas/11d.h @@ -47,7 +47,7 @@ struct mrvlietypes_domainparamset { } __attribute__ ((packed)); struct cmd_ds_802_11d_domain_info { - u16 action; + __le16 action; struct mrvlietypes_domainparamset domain; } __attribute__ ((packed)); @@ -98,7 +98,9 @@ int libertas_cmd_enable_11d(wlan_private * priv, struct iwreq *wrq); int libertas_ret_802_11d_domain_info(wlan_private * priv, struct cmd_ds_command *resp); -int libertas_parse_dnld_countryinfo_11d(wlan_private * priv); +struct bss_descriptor; +int libertas_parse_dnld_countryinfo_11d(wlan_private * priv, + struct bss_descriptor * bss); int libertas_create_dnld_countryinfo_11d(wlan_private * priv); diff --git a/drivers/net/wireless/libertas/Makefile b/drivers/net/wireless/libertas/Makefile index 56a8ea1fbf0..32ed4136b0d 100644 --- a/drivers/net/wireless/libertas/Makefile +++ b/drivers/net/wireless/libertas/Makefile @@ -1,12 +1,12 @@ -usb8xxx-objs := main.o fw.o wext.o \ +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 usb8xxx-objs += if_usb.o +obj-$(CONFIG_LIBERTAS) += libertas.o obj-$(CONFIG_LIBERTAS_USB) += usb8xxx.o - diff --git a/drivers/net/wireless/libertas/README b/drivers/net/wireless/libertas/README index 378577200b5..0b133ce6380 100644 --- a/drivers/net/wireless/libertas/README +++ b/drivers/net/wireless/libertas/README @@ -1,7 +1,7 @@ ================================================================================ README for USB8388 - (c) Copyright © 2003-2006, Marvell International Ltd. + (c) Copyright © 2003-2006, Marvell International Ltd. All Rights Reserved This software file (the "File") is distributed by Marvell International @@ -28,293 +28,6 @@ DRIVER LOADING insmod usb8388.ko [fw_name=usb8388.bin] -===================== -IWPRIV COMMAND -===================== - -NAME - This manual describes the usage of private commands used in Marvell WLAN - Linux Driver. All the commands available in Wlanconfig will not be available - in the iwpriv. - -SYNOPSIS - iwpriv <ethX> <command> [sub-command] ... - - iwpriv ethX setregioncode <n> - iwpriv ethX getregioncode - -Version 5 Command: - iwpriv ethX ledgpio <n> - -BT Commands: - The blinding table (BT) contains a list of mac addresses that should be - ignored by the firmware. It is primarily used for debugging and - testing networks. It can be edited and inspected with the following - commands: - - iwpriv ethX bt_reset - iwpriv ethX bt_add <mac_address> - iwpriv ethX bt_del <mac_address> - iwpriv ethX bt_list <id> - -FWT Commands: - The forwarding table (FWT) is a feature used to manage mesh network - routing in the firmware. The FWT is essentially a routing table that - associates a destination mac address (da) with a next hop receiver - address (ra). The FWT can be inspected and edited with the following - iwpriv commands, which are described in greater detail below. - Eventually, the table will be automatically maintained by a custom - routing protocol. - - NOTE: FWT commands replace the previous DFT commands. What were the DFT - commands?, you might ask. They were an earlier API to the firmware that - implemented a simple MAC-layer forwarding mechanism. In the unlikely - event that you were using these commands, you must migrate to the new - FWT commands which can be used to achieve the same functionality. - - iwpriv ethX fwt_add [parameters] - iwpriv ethX fwt_del [parameters] - iwpriv ethX fwt_lookup [parameters] - iwpriv ethX fwt_list [parameters] - iwpriv ethX fwt_list_route [parameters] - iwpriv ethX fwt_list_neigh [parameters] - iwpriv ethX fwt_reset [parameters] - iwpriv ethX fwt_cleanup - iwpriv ethX fwt_time - -MESH Commands: - - The MESH commands are used to configure various features of the mesh - routing protocol. The following commands are supported: - - iwpriv ethX mesh_get_ttl - iwpriv ethX mesh_set_ttl ttl - -DESCRIPTION - Those commands are used to send additional commands to the Marvell WLAN - card via the Linux device driver. - - The ethX parameter specifies the network device that is to be used to - perform this command on. it could be eth0, eth1 etc. - -setregioncode - This command is used to set the region code in the station. - where value is 'region code' for various regions like - USA FCC, Canada IC, Spain, France, Europe ETSI, Japan ... - - Usage: - iwpriv ethX setregioncode 0x10: set region code to USA (0x10). - -getregioncode - This command is used to get the region code information set in the - station. - -ledgpio - This command is used to set/get LEDs. - - iwpriv ethX ledgpio <LEDs> - will set the corresponding LED for the GPIO Line. - - iwpriv ethX ledgpio - will give u which LEDs are Enabled. - - Usage: - iwpriv eth1 ledgpio 1 0 2 1 3 4 - will enable - LED 1 -> GPIO 0 - LED 2 -> GPIO 1 - LED 3 -> GPIO 4 - - iwpriv eth1 ledgpio - shows LED information in the format as mentioned above. - - Note: LED0 is invalid - Note: Maximum Number of LEDs are 16. - -fwt_add - This command is used to insert an entry into the FWT table. The list of - parameters must follow the following structure: - - iwpriv ethX fwt_add da ra [metric dir ssn dsn hopcount ttl expiration sleepmode snr] - - The parameters between brackets are optional, but they must appear in - the order specified. For example, if you want to specify the metric, - you must also specify the dir, ssn, and dsn but you need not specify the - hopcount, expiration, sleepmode, or snr. Any unspecified parameters - will be assigned the defaults specified below. - - The different parameters are:- - da -- DA MAC address in the form 00:11:22:33:44:55 - ra -- RA MAC address in the form 00:11:22:33:44:55 - metric -- route metric (cost: smaller-metric routes are - preferred, default is 0) - dir -- direction (1 for direct, 0 for reverse, - default is 1) - ssn -- Source Sequence Number (time at the RA for - reverse routes. Default is 0) - dsn -- Destination Sequence Number (time at the DA - for direct routes. Default is 0) - hopcount -- hop count (currently unused, default is 0) - ttl -- TTL (Only used in reverse entries) - expiration -- entry expiration (in ticks, where a tick is - 1024us, or ~ 1ms. Use 0 for an indefinite - entry, default is 0) - sleepmode -- RA's sleep mode (currently unused, default is - 0) - snr -- SNR in the link to RA (currently unused, - default is 0) - - The command does not return anything. - -fwt_del - This command is used to remove an entry to the FWT table. The list of - parameters must follow the following structure: - - iwpriv ethX fwt_del da ra [dir] - - where the different parameters are:- - da -- DA MAC address (in the form "00:11:22:33:44:55") - ra -- RA MAC address (in the form "00:11:22:33:44:55") - dir -- direction (1 for direct, 0 for reverse, - default is 1) - - The command does not return anything. - -fwt_lookup - This command is used to get the best route in the FWT table to a given - host. The only parameter is the MAC address of the host that is being - looked for. - - iwpriv ethX fwt_lookup da - - where:- - da -- DA MAC address (in the form "00:11:22:33:44:55") - - The command returns an output string identical to the one returned by - fwt_list described below. - - -fwt_list - This command is used to list a route from the FWT table. The only - parameter is the index into the table. If you want to list all the - routes in a table, start with index=0, and keep listing until you get a - "(null)" string. Note that the indicies may change as the fwt is - updated. It is expected that most users will not use fwt_list directly, - but that a utility similar to the traditional route command will be used - to invoke fwt_list over and over. - - iwpriv ethX fwt_list index - - The output is a string of the following form: - - da ra metric dir ssn dsn hopcount ttl expiration sleepmode snr - - where the different fields are:- - da -- DA MAC address (in the form "00:11:22:33:44:55") - ra -- RA MAC address (in the form "00:11:22:33:44:55") - metric -- route metric (cost: smaller-metric routes are preferred) - dir -- direction (1 for direct, 0 for reverse) - ssn -- Source Sequence Number (time at the RA for reverse routes) - dsn -- Destination Sequence Number (time at the DA for direct routes) - hopcount -- hop count (currently unused) - ttl -- TTL (only used in reverse entries) - expiration -- entry expiration (in ticks, where a tick is 1024us, or ~ 1ms. Use 0 for an indefinite entry) - sleepmode -- RA's sleep mode (currently unused) - snr -- SNR in the link to RA (currently unused) - -fwt_list_route - This command is used to list a route from the FWT table. The only - parameter is the route ID. If you want to list all the routes in a - table, start with rid=0, and keep incrementing rid until you get a - "(null)" string. This function is similar to fwt_list. The only - difference is the output format. Also note that this command is meant - for debugging. It is expected that users will use fwt_lookup and - fwt_list. One important reason for this is that the route id may change - as the route table is altered. - - iwpriv ethX fwt_list_route rid - - The output is a string of the following form: - - da metric dir nid ssn dsn hopcount ttl expiration - - where the different fields are:- - da -- DA MAC address (in the form "00:11:22:33:44:55") - metric -- route metric (cost: smaller-metric routes are preferred) - dir -- direction (1 for direct, 0 for reverse) - nid -- Next-hop (neighbor) host ID (nid) - ssn -- Source Sequence Number (time at the RA for reverse routes) - dsn -- Destination Sequence Number (time at the DA for direct routes) - hopcount -- hop count (currently unused) - ttl -- TTL count (only used in reverse entries) - expiration -- entry expiration (in ticks, where a tick is 1024us, or ~ 1ms. Use 0 for an indefinite entry) - -fwt_list_neigh - This command is used to list a neighbor from the FWT table. The only - parameter is the neighbor ID. If you want to list all the neighbors in a - table, start with nid=0, and keep incrementing nid until you get a - "(null)" string. Note that the nid from a fwt_list_route command can be - used as an input to this command. Also note that this command is meant - mostly for debugging. It is expected that users will use fwt_lookup. - One important reason for this is that the neighbor id may change as the - neighbor table is altered. - - iwpriv ethX fwt_list_neigh nid - - The output is a string of the following form: - - ra sleepmode snr references - - where the different fields are:- - ra -- RA MAC address (in the form "00:11:22:33:44:55") - sleepmode -- RA's sleep mode (currently unused) - snr -- SNR in the link to RA (currently unused) - references -- RA's reference counter - -fwt_reset - This command is used to reset the FWT table, getting rid of all the - entries. There are no input parameters. - - iwpriv ethX fwt_reset - - The command does not return anything. - -fwt_cleanup - This command is used to perform user-based garbage recollection. The - FWT table is checked, and all the entries that are expired or invalid - are cleaned. Note that this is exported to the driver for debugging - purposes, as garbage collection is also fired by the firmware when in - space problems. There are no input parameters. - - iwpriv ethX fwt_cleanup - - The command does returns the number of invalid/expired routes deleted. - -fwt_time - This command returns a card's internal time representation. It is this - time that is used to represent the expiration times of FWT entries. The - number is not consistent from card to card; it is simply a timer count. - The fwt_time command is used to inspect the timer so that expiration - times reported by fwt_list can be properly interpreted. - - iwpriv ethX fwt_time - -mesh_get_ttl - - The mesh ttl is the number of hops a mesh packet can traverse before it - is dropped. This parameter is used to prevent infinite loops in the - mesh network. The value returned by this function is the ttl assigned - to all mesh packets. Currently there is no way to control the ttl on a - per packet or per socket basis. - - iwpriv ethX mesh_get_ttl - -mesh_set_ttl ttl - - Set the ttl. The argument must be between 0 and 255. - - iwpriv ethX mesh_set_ttl <ttl> - ========================= ETHTOOL ========================= diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c index c260bd1b3d4..afd5617dd92 100644 --- a/drivers/net/wireless/libertas/assoc.c +++ b/drivers/net/wireless/libertas/assoc.c @@ -2,6 +2,7 @@ #include <linux/bitops.h> #include <net/ieee80211.h> +#include <linux/etherdevice.h> #include "assoc.h" #include "join.h" @@ -13,59 +14,88 @@ static const u8 bssid_any[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; static const u8 bssid_off[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static void print_assoc_req(const char * extra, struct assoc_request * assoc_req) +{ + lbs_deb_assoc( + "#### Association Request: %s\n" + " flags: 0x%08lX\n" + " SSID: '%s'\n" + " channel: %d\n" + " band: %d\n" + " mode: %d\n" + " BSSID: " MAC_FMT "\n" + " Encryption:%s%s%s\n" + " auth: %d\n", + extra, assoc_req->flags, + escape_essid(assoc_req->ssid, assoc_req->ssid_len), + assoc_req->channel, assoc_req->band, assoc_req->mode, + MAC_ARG(assoc_req->bssid), + assoc_req->secinfo.WPAenabled ? " WPA" : "", + assoc_req->secinfo.WPA2enabled ? " WPA2" : "", + assoc_req->secinfo.wep_enabled ? " WEP" : "", + assoc_req->secinfo.auth_mode); +} + + static int assoc_helper_essid(wlan_private *priv, struct assoc_request * assoc_req) { wlan_adapter *adapter = priv->adapter; int ret = 0; - int i; + struct bss_descriptor * bss; + int channel = -1; + + lbs_deb_enter(LBS_DEB_ASSOC); - ENTER(); + /* FIXME: take channel into account when picking SSIDs if a channel + * is set. + */ + + if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) + channel = assoc_req->channel; - lbs_pr_debug(1, "New SSID requested: %s\n", assoc_req->ssid.ssid); + lbs_deb_assoc("New SSID requested: '%s'\n", + escape_essid(assoc_req->ssid, assoc_req->ssid_len)); if (assoc_req->mode == IW_MODE_INFRA) { if (adapter->prescan) { - libertas_send_specific_SSID_scan(priv, &assoc_req->ssid, 1); + libertas_send_specific_ssid_scan(priv, assoc_req->ssid, + assoc_req->ssid_len, 0); } - i = libertas_find_SSID_in_list(adapter, &assoc_req->ssid, - NULL, IW_MODE_INFRA); - if (i >= 0) { - lbs_pr_debug(1, - "SSID found in scan list ... associating...\n"); - - ret = wlan_associate(priv, &adapter->scantable[i]); - if (ret == 0) { - memcpy(&assoc_req->bssid, - &adapter->scantable[i].macaddress, - ETH_ALEN); - } + bss = libertas_find_ssid_in_list(adapter, assoc_req->ssid, + assoc_req->ssid_len, NULL, IW_MODE_INFRA, channel); + if (bss != NULL) { + lbs_deb_assoc("SSID found in scan list, associating\n"); + memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor)); + ret = wlan_associate(priv, assoc_req); } else { - lbs_pr_debug(1, "SSID '%s' not found; cannot associate\n", - assoc_req->ssid.ssid); + lbs_deb_assoc("SSID not found; cannot associate\n"); } } else if (assoc_req->mode == IW_MODE_ADHOC) { /* Scan for the network, do not save previous results. Stale * scan data will cause us to join a non-existant adhoc network */ - libertas_send_specific_SSID_scan(priv, &assoc_req->ssid, 0); + libertas_send_specific_ssid_scan(priv, assoc_req->ssid, + assoc_req->ssid_len, 1); /* Search for the requested SSID in the scan table */ - i = libertas_find_SSID_in_list(adapter, &assoc_req->ssid, NULL, - IW_MODE_ADHOC); - if (i >= 0) { - lbs_pr_debug(1, "SSID found at %d in List, so join\n", ret); - libertas_join_adhoc_network(priv, &adapter->scantable[i]); + bss = libertas_find_ssid_in_list(adapter, assoc_req->ssid, + assoc_req->ssid_len, NULL, IW_MODE_ADHOC, channel); + if (bss != NULL) { + lbs_deb_assoc("SSID found, will join\n"); + memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor)); + libertas_join_adhoc_network(priv, assoc_req); } else { /* else send START command */ - lbs_pr_debug(1, "SSID not found in list, so creating adhoc" - " with SSID '%s'\n", assoc_req->ssid.ssid); - libertas_start_adhoc_network(priv, &assoc_req->ssid); + lbs_deb_assoc("SSID not found, creating adhoc network\n"); + memcpy(&assoc_req->bss.ssid, &assoc_req->ssid, + IW_ESSID_MAX_SIZE); + assoc_req->bss.ssid_len = assoc_req->ssid_len; + libertas_start_adhoc_network(priv, assoc_req); } - memcpy(&assoc_req->bssid, &adapter->current_addr, ETH_ALEN); } - LEAVE(); + lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); return ret; } @@ -74,33 +104,31 @@ static int assoc_helper_bssid(wlan_private *priv, struct assoc_request * assoc_req) { wlan_adapter *adapter = priv->adapter; - int i, ret = 0; - - ENTER(); + int ret = 0; + struct bss_descriptor * bss; - lbs_pr_debug(1, "ASSOC: WAP: BSSID = " MAC_FMT "\n", + lbs_deb_enter_args(LBS_DEB_ASSOC, "BSSID " MAC_FMT, MAC_ARG(assoc_req->bssid)); /* Search for index position in list for requested MAC */ - i = libertas_find_BSSID_in_list(adapter, assoc_req->bssid, + bss = libertas_find_bssid_in_list(adapter, assoc_req->bssid, assoc_req->mode); - if (i < 0) { - lbs_pr_debug(1, "ASSOC: WAP: BSSID " MAC_FMT " not found, " + if (bss == NULL) { + lbs_deb_assoc("ASSOC: WAP: BSSID " MAC_FMT " not found, " "cannot associate.\n", MAC_ARG(assoc_req->bssid)); goto out; } + memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor)); if (assoc_req->mode == IW_MODE_INFRA) { - ret = wlan_associate(priv, &adapter->scantable[i]); - lbs_pr_debug(1, "ASSOC: return from wlan_associate(bssd) was %d\n", ret); + ret = wlan_associate(priv, assoc_req); + lbs_deb_assoc("ASSOC: wlan_associate(bssid) returned %d\n", ret); } else if (assoc_req->mode == IW_MODE_ADHOC) { - libertas_join_adhoc_network(priv, &adapter->scantable[i]); + libertas_join_adhoc_network(priv, assoc_req); } - memcpy(&assoc_req->ssid, &adapter->scantable[i].ssid, - sizeof(struct WLAN_802_11_SSID)); out: - LEAVE(); + lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); return ret; } @@ -113,12 +141,12 @@ static int assoc_helper_associate(wlan_private *priv, /* If we're given and 'any' BSSID, try associating based on SSID */ if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { - if (memcmp(bssid_any, assoc_req->bssid, ETH_ALEN) - && memcmp(bssid_off, assoc_req->bssid, ETH_ALEN)) { + if (compare_ether_addr(bssid_any, assoc_req->bssid) + && compare_ether_addr(bssid_off, assoc_req->bssid)) { ret = assoc_helper_bssid(priv, assoc_req); done = 1; if (ret) { - lbs_pr_debug(1, "ASSOC: bssid: ret = %d\n", ret); + lbs_deb_assoc("ASSOC: bssid: ret = %d\n", ret); } } } @@ -126,7 +154,7 @@ static int assoc_helper_associate(wlan_private *priv, if (!done && test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { ret = assoc_helper_essid(priv, assoc_req); if (ret) { - lbs_pr_debug(1, "ASSOC: bssid: ret = %d\n", ret); + lbs_deb_assoc("ASSOC: bssid: ret = %d\n", ret); } } @@ -140,12 +168,10 @@ static int assoc_helper_mode(wlan_private *priv, wlan_adapter *adapter = priv->adapter; int ret = 0; - ENTER(); + lbs_deb_enter(LBS_DEB_ASSOC); - if (assoc_req->mode == adapter->mode) { - LEAVE(); - return 0; - } + if (assoc_req->mode == adapter->mode) + goto done; if (assoc_req->mode == IW_MODE_INFRA) { if (adapter->psstate != PS_STATE_FULL_POWER) @@ -158,9 +184,81 @@ static int assoc_helper_mode(wlan_private *priv, cmd_802_11_snmp_mib, 0, cmd_option_waitforrsp, OID_802_11_INFRASTRUCTURE_MODE, - (void *) (size_t) assoc_req->mode); + /* Shoot me now */ (void *) (size_t) assoc_req->mode); - LEAVE(); +done: + lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); + return ret; +} + + +static int update_channel(wlan_private * priv) +{ + /* the channel in f/w could be out of sync, get the current channel */ + return libertas_prepare_and_send_command(priv, cmd_802_11_rf_channel, + cmd_opt_802_11_rf_channel_get, + cmd_option_waitforrsp, 0, NULL); +} + +void libertas_sync_channel(struct work_struct *work) +{ + wlan_private *priv = container_of(work, wlan_private, sync_channel); + + if (update_channel(priv) != 0) + lbs_pr_info("Channel synchronization failed."); +} + +static int assoc_helper_channel(wlan_private *priv, + struct assoc_request * assoc_req) +{ + wlan_adapter *adapter = priv->adapter; + int ret = 0; + + lbs_deb_enter(LBS_DEB_ASSOC); + + ret = update_channel(priv); + if (ret < 0) { + lbs_deb_assoc("ASSOC: channel: error getting channel."); + } + + if (assoc_req->channel == adapter->curbssparams.channel) + goto done; + + lbs_deb_assoc("ASSOC: channel: %d -> %d\n", + adapter->curbssparams.channel, assoc_req->channel); + + ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_channel, + cmd_opt_802_11_rf_channel_set, + cmd_option_waitforrsp, 0, &assoc_req->channel); + if (ret < 0) { + lbs_deb_assoc("ASSOC: channel: error setting channel."); + } + + ret = update_channel(priv); + if (ret < 0) { + lbs_deb_assoc("ASSOC: channel: error getting channel."); + } + + if (assoc_req->channel != adapter->curbssparams.channel) { + lbs_deb_assoc("ASSOC: channel: failed to update channel to %d", + assoc_req->channel); + goto done; + } + + if ( assoc_req->secinfo.wep_enabled + && (assoc_req->wep_keys[0].len + || assoc_req->wep_keys[1].len + || assoc_req->wep_keys[2].len + || assoc_req->wep_keys[3].len)) { + /* Make sure WEP keys are re-sent to firmware */ + set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags); + } + + /* Must restart/rejoin adhoc networks after channel change */ + set_bit(ASSOC_FLAG_SSID, &assoc_req->flags); + +done: + lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); return ret; } @@ -172,7 +270,7 @@ static int assoc_helper_wep_keys(wlan_private *priv, int i; int ret = 0; - ENTER(); + lbs_deb_enter(LBS_DEB_ASSOC); /* Set or remove WEP keys */ if ( assoc_req->wep_keys[0].len @@ -216,7 +314,7 @@ static int assoc_helper_wep_keys(wlan_private *priv, mutex_unlock(&adapter->lock); out: - LEAVE(); + lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); return ret; } @@ -225,15 +323,49 @@ static int assoc_helper_secinfo(wlan_private *priv, { wlan_adapter *adapter = priv->adapter; int ret = 0; + u32 do_wpa; + u32 rsn = 0; - ENTER(); + lbs_deb_enter(LBS_DEB_ASSOC); memcpy(&adapter->secinfo, &assoc_req->secinfo, sizeof(struct wlan_802_11_security)); ret = libertas_set_mac_packet_filter(priv); + if (ret) + goto out; + + /* If RSN is already enabled, don't try to enable it again, since + * ENABLE_RSN resets internal state machines and will clobber the + * 4-way WPA handshake. + */ - LEAVE(); + /* Get RSN enabled/disabled */ + ret = libertas_prepare_and_send_command(priv, + cmd_802_11_enable_rsn, + cmd_act_set, + cmd_option_waitforrsp, + 0, &rsn); + if (ret) { + lbs_deb_assoc("Failed to get RSN status: %d", ret); + goto out; + } + + /* Don't re-enable RSN if it's already enabled */ + do_wpa = (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled); + if (do_wpa == rsn) + goto out; + + /* Set RSN enabled/disabled */ + rsn = do_wpa; + ret = libertas_prepare_and_send_command(priv, + cmd_802_11_enable_rsn, + cmd_act_set, + cmd_option_waitforrsp, + 0, &rsn); + +out: + lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); return ret; } @@ -243,16 +375,7 @@ static int assoc_helper_wpa_keys(wlan_private *priv, { int ret = 0; - ENTER(); - - /* enable/Disable RSN */ - ret = libertas_prepare_and_send_command(priv, - cmd_802_11_enable_rsn, - cmd_act_set, - cmd_option_waitforrsp, - 0, assoc_req); - if (ret) - goto out; + lbs_deb_enter(LBS_DEB_ASSOC); ret = libertas_prepare_and_send_command(priv, cmd_802_11_key_material, @@ -260,8 +383,7 @@ static int assoc_helper_wpa_keys(wlan_private *priv, cmd_option_waitforrsp, 0, assoc_req); -out: - LEAVE(); + lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); return ret; } @@ -272,7 +394,7 @@ static int assoc_helper_wpa_ie(wlan_private *priv, wlan_adapter *adapter = priv->adapter; int ret = 0; - ENTER(); + lbs_deb_enter(LBS_DEB_ASSOC); if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) { memcpy(&adapter->wpa_ie, &assoc_req->wpa_ie, assoc_req->wpa_ie_len); @@ -282,7 +404,7 @@ static int assoc_helper_wpa_ie(wlan_private *priv, adapter->wpa_ie_len = 0; } - LEAVE(); + lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); return ret; } @@ -294,25 +416,30 @@ static int should_deauth_infrastructure(wlan_adapter *adapter, return 0; if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { - lbs_pr_debug(1, "Deauthenticating due to new SSID in " + lbs_deb_assoc("Deauthenticating due to new SSID in " " configuration request.\n"); return 1; } if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) { if (adapter->secinfo.auth_mode != assoc_req->secinfo.auth_mode) { - lbs_pr_debug(1, "Deauthenticating due to updated security " + lbs_deb_assoc("Deauthenticating due to updated security " "info in configuration request.\n"); return 1; } } if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { - lbs_pr_debug(1, "Deauthenticating due to new BSSID in " + lbs_deb_assoc("Deauthenticating due to new BSSID in " " configuration request.\n"); return 1; } + if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) { + lbs_deb_assoc("Deauthenticating due to channel switch.\n"); + return 1; + } + /* FIXME: deal with 'auto' mode somehow */ if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) { if (assoc_req->mode != IW_MODE_INFRA) @@ -329,10 +456,9 @@ static int should_stop_adhoc(wlan_adapter *adapter, if (adapter->connect_status != libertas_connected) return 0; - if (adapter->curbssparams.ssid.ssidlength != assoc_req->ssid.ssidlength) - return 1; - if (memcmp(adapter->curbssparams.ssid.ssid, assoc_req->ssid.ssid, - adapter->curbssparams.ssid.ssidlength)) + if (libertas_ssid_cmp(adapter->curbssparams.ssid, + adapter->curbssparams.ssid_len, + assoc_req->ssid, assoc_req->ssid_len) != 0) return 1; /* FIXME: deal with 'auto' mode somehow */ @@ -341,11 +467,16 @@ static int should_stop_adhoc(wlan_adapter *adapter, return 1; } + if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) { + if (assoc_req->channel != adapter->curbssparams.channel) + return 1; + } + return 0; } -void wlan_association_worker(struct work_struct *work) +void libertas_association_worker(struct work_struct *work) { wlan_private *priv = container_of(work, wlan_private, assoc_work.work); wlan_adapter *adapter = priv->adapter; @@ -353,40 +484,38 @@ void wlan_association_worker(struct work_struct *work) int ret = 0; int find_any_ssid = 0; - ENTER(); + lbs_deb_enter(LBS_DEB_ASSOC); mutex_lock(&adapter->lock); - assoc_req = adapter->assoc_req; - adapter->assoc_req = NULL; + assoc_req = adapter->pending_assoc_req; + adapter->pending_assoc_req = NULL; + adapter->in_progress_assoc_req = assoc_req; mutex_unlock(&adapter->lock); - if (!assoc_req) { - LEAVE(); - return; - } + if (!assoc_req) + goto done; - lbs_pr_debug(1, "ASSOC: starting new association request: flags = 0x%lX\n", - assoc_req->flags); + print_assoc_req(__func__, assoc_req); /* If 'any' SSID was specified, find an SSID to associate with */ if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags) - && !assoc_req->ssid.ssidlength) + && !assoc_req->ssid_len) find_any_ssid = 1; /* But don't use 'any' SSID if there's a valid locked BSSID to use */ if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { - if (memcmp(&assoc_req->bssid, bssid_any, ETH_ALEN) - && memcmp(&assoc_req->bssid, bssid_off, ETH_ALEN)) + if (compare_ether_addr(assoc_req->bssid, bssid_any) + && compare_ether_addr(assoc_req->bssid, bssid_off)) find_any_ssid = 0; } if (find_any_ssid) { u8 new_mode; - ret = libertas_find_best_network_SSID(priv, &assoc_req->ssid, - assoc_req->mode, &new_mode); + ret = libertas_find_best_network_ssid(priv, assoc_req->ssid, + &assoc_req->ssid_len, assoc_req->mode, &new_mode); if (ret) { - lbs_pr_debug(1, "Could not find best network\n"); + lbs_deb_assoc("Could not find best network\n"); ret = -ENETUNREACH; goto out; } @@ -406,7 +535,7 @@ void wlan_association_worker(struct work_struct *work) if (should_deauth_infrastructure(adapter, assoc_req)) { ret = libertas_send_deauthentication(priv); if (ret) { - lbs_pr_debug(1, "Deauthentication due to new " + lbs_deb_assoc("Deauthentication due to new " "configuration request failed: %d\n", ret); } @@ -415,7 +544,7 @@ void wlan_association_worker(struct work_struct *work) if (should_stop_adhoc(adapter, assoc_req)) { ret = libertas_stop_adhoc_network(priv); if (ret) { - lbs_pr_debug(1, "Teardown of AdHoc network due to " + lbs_deb_assoc("Teardown of AdHoc network due to " "new configuration request failed: %d\n", ret); } @@ -427,7 +556,16 @@ void wlan_association_worker(struct work_struct *work) if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) { ret = assoc_helper_mode(priv, assoc_req); if (ret) { -lbs_pr_debug(1, "ASSOC(:%d) mode: ret = %d\n", __LINE__, ret); +lbs_deb_assoc("ASSOC(:%d) mode: ret = %d\n", __LINE__, ret); + goto out; + } + } + + if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) { + ret = assoc_helper_channel(priv, assoc_req); + if (ret) { + lbs_deb_assoc("ASSOC(:%d) channel: ret = %d\n", + __LINE__, ret); goto out; } } @@ -436,7 +574,7 @@ lbs_pr_debug(1, "ASSOC(:%d) mode: ret = %d\n", __LINE__, ret); || test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) { ret = assoc_helper_wep_keys(priv, assoc_req); if (ret) { -lbs_pr_debug(1, "ASSOC(:%d) wep_keys: ret = %d\n", __LINE__, ret); +lbs_deb_assoc("ASSOC(:%d) wep_keys: ret = %d\n", __LINE__, ret); goto out; } } @@ -444,7 +582,7 @@ lbs_pr_debug(1, "ASSOC(:%d) wep_keys: ret = %d\n", __LINE__, ret); if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) { ret = assoc_helper_secinfo(priv, assoc_req); if (ret) { -lbs_pr_debug(1, "ASSOC(:%d) secinfo: ret = %d\n", __LINE__, ret); +lbs_deb_assoc("ASSOC(:%d) secinfo: ret = %d\n", __LINE__, ret); goto out; } } @@ -452,7 +590,7 @@ lbs_pr_debug(1, "ASSOC(:%d) secinfo: ret = %d\n", __LINE__, ret); if (test_bit(ASSOC_FLAG_WPA_IE, &assoc_req->flags)) { ret = assoc_helper_wpa_ie(priv, assoc_req); if (ret) { -lbs_pr_debug(1, "ASSOC(:%d) wpa_ie: ret = %d\n", __LINE__, ret); +lbs_deb_assoc("ASSOC(:%d) wpa_ie: ret = %d\n", __LINE__, ret); goto out; } } @@ -461,7 +599,7 @@ lbs_pr_debug(1, "ASSOC(:%d) wpa_ie: ret = %d\n", __LINE__, ret); || test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) { ret = assoc_helper_wpa_keys(priv, assoc_req); if (ret) { -lbs_pr_debug(1, "ASSOC(:%d) wpa_keys: ret = %d\n", __LINE__, ret); +lbs_deb_assoc("ASSOC(:%d) wpa_keys: ret = %d\n", __LINE__, ret); goto out; } } @@ -475,21 +613,23 @@ lbs_pr_debug(1, "ASSOC(:%d) wpa_keys: ret = %d\n", __LINE__, ret); ret = assoc_helper_associate(priv, assoc_req); if (ret) { - lbs_pr_debug(1, "ASSOC: association attempt unsuccessful: %d\n", + lbs_deb_assoc("ASSOC: association attempt unsuccessful: %d\n", ret); success = 0; } if (adapter->connect_status != libertas_connected) { - lbs_pr_debug(1, "ASSOC: assoication attempt unsuccessful, " + lbs_deb_assoc("ASSOC: assoication attempt unsuccessful, " "not connected.\n"); success = 0; } if (success) { - lbs_pr_debug(1, "ASSOC: association attempt successful. " + lbs_deb_assoc("ASSOC: association attempt successful. " "Associated to '%s' (" MAC_FMT ")\n", - assoc_req->ssid.ssid, MAC_ARG(assoc_req->bssid)); + escape_essid(adapter->curbssparams.ssid, + adapter->curbssparams.ssid_len), + MAC_ARG(adapter->curbssparams.bssid)); libertas_prepare_and_send_command(priv, cmd_802_11_rssi, 0, cmd_option_waitforrsp, 0, NULL); @@ -498,18 +638,23 @@ lbs_pr_debug(1, "ASSOC(:%d) wpa_keys: ret = %d\n", __LINE__, ret); cmd_802_11_get_log, 0, cmd_option_waitforrsp, 0, NULL); } else { - ret = -1; } } out: if (ret) { - lbs_pr_debug(1, "ASSOC: reconfiguration attempt unsuccessful: %d\n", + lbs_deb_assoc("ASSOC: reconfiguration attempt unsuccessful: %d\n", ret); } + + mutex_lock(&adapter->lock); + adapter->in_progress_assoc_req = NULL; + mutex_unlock(&adapter->lock); kfree(assoc_req); - LEAVE(); + +done: + lbs_deb_leave(LBS_DEB_ASSOC); } @@ -520,9 +665,10 @@ struct assoc_request * wlan_get_association_request(wlan_adapter *adapter) { struct assoc_request * assoc_req; - if (!adapter->assoc_req) { - adapter->assoc_req = kzalloc(sizeof(struct assoc_request), GFP_KERNEL); - if (!adapter->assoc_req) { + if (!adapter->pending_assoc_req) { + adapter->pending_assoc_req = kzalloc(sizeof(struct assoc_request), + GFP_KERNEL); + if (!adapter->pending_assoc_req) { lbs_pr_info("Not enough memory to allocate association" " request!\n"); return NULL; @@ -532,15 +678,19 @@ struct assoc_request * wlan_get_association_request(wlan_adapter *adapter) /* Copy current configuration attributes to the association request, * but don't overwrite any that are already set. */ - assoc_req = adapter->assoc_req; + assoc_req = adapter->pending_assoc_req; if (!test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { - memcpy(&assoc_req->ssid, adapter->curbssparams.ssid.ssid, - adapter->curbssparams.ssid.ssidlength); + memcpy(&assoc_req->ssid, &adapter->curbssparams.ssid, + IW_ESSID_MAX_SIZE); + assoc_req->ssid_len = adapter->curbssparams.ssid_len; } if (!test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) assoc_req->channel = adapter->curbssparams.channel; + if (!test_bit(ASSOC_FLAG_BAND, &assoc_req->flags)) + assoc_req->band = adapter->curbssparams.band; + if (!test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) assoc_req->mode = adapter->mode; @@ -581,7 +731,7 @@ struct assoc_request * wlan_get_association_request(wlan_adapter *adapter) assoc_req->wpa_ie_len = adapter->wpa_ie_len; } + print_assoc_req(__func__, assoc_req); + return assoc_req; } - - diff --git a/drivers/net/wireless/libertas/assoc.h b/drivers/net/wireless/libertas/assoc.h index 2ffd82d99b3..5e9c31f0932 100644 --- a/drivers/net/wireless/libertas/assoc.h +++ b/drivers/net/wireless/libertas/assoc.h @@ -5,10 +5,12 @@ #include "dev.h" -void wlan_association_worker(struct work_struct *work); +void libertas_association_worker(struct work_struct *work); struct assoc_request * wlan_get_association_request(wlan_adapter *adapter); +void libertas_sync_channel(struct work_struct *work); + #define ASSOC_DELAY (HZ / 2) static inline void wlan_postpone_association_work(wlan_private *priv) { @@ -21,9 +23,9 @@ static inline void wlan_postpone_association_work(wlan_private *priv) static inline void wlan_cancel_association_work(wlan_private *priv) { cancel_delayed_work(&priv->assoc_work); - if (priv->adapter->assoc_req) { - kfree(priv->adapter->assoc_req); - priv->adapter->assoc_req = NULL; + if (priv->adapter->pending_assoc_req) { + kfree(priv->adapter->pending_assoc_req); + priv->adapter->pending_assoc_req = NULL; } } diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index de9cb46a70f..13f6528abb0 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c @@ -6,7 +6,6 @@ #include <net/iw_handler.h> #include "host.h" #include "hostcmd.h" -#include "sbi.h" #include "decl.h" #include "defs.h" #include "dev.h" @@ -26,13 +25,11 @@ static u16 commands_allowed_in_ps[] = { * @param command the command ID * @return TRUE or FALSE */ -static u8 is_command_allowed_in_ps(u16 command) +static u8 is_command_allowed_in_ps(__le16 command) { - int count = sizeof(commands_allowed_in_ps) - / sizeof(commands_allowed_in_ps[0]); int i; - for (i = 0; i < count; i++) { + for (i = 0; i < ARRAY_SIZE(commands_allowed_in_ps); i++) { if (command == cpu_to_le16(commands_allowed_in_ps[i])) return 1; } @@ -44,14 +41,13 @@ static int wlan_cmd_hw_spec(wlan_private * priv, struct cmd_ds_command *cmd) { struct cmd_ds_get_hw_spec *hwspec = &cmd->params.hwspec; - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); cmd->command = cpu_to_le16(cmd_get_hw_spec); - cmd->size = - cpu_to_le16(sizeof(struct cmd_ds_get_hw_spec) + S_DS_GEN); + cmd->size = cpu_to_le16(sizeof(struct cmd_ds_get_hw_spec) + S_DS_GEN); memcpy(hwspec->permanentaddr, priv->adapter->current_addr, ETH_ALEN); - LEAVE(); + lbs_deb_leave(LBS_DEB_CMD); return 0; } @@ -60,21 +56,19 @@ static int wlan_cmd_802_11_ps_mode(wlan_private * priv, u16 cmd_action) { struct cmd_ds_802_11_ps_mode *psm = &cmd->params.psmode; - u16 action = cmd_action; wlan_adapter *adapter = priv->adapter; - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); cmd->command = cpu_to_le16(cmd_802_11_ps_mode); - cmd->size = - cpu_to_le16(sizeof(struct cmd_ds_802_11_ps_mode) + - S_DS_GEN); + cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_ps_mode) + + S_DS_GEN); psm->action = cpu_to_le16(cmd_action); psm->multipledtim = 0; - switch (action) { + switch (cmd_action) { case cmd_subcmd_enter_ps: - lbs_pr_debug(1, "PS command:" "SubCode- Enter PS\n"); - lbs_pr_debug(1, "locallisteninterval = %d\n", + lbs_deb_cmd("PS command:" "SubCode- Enter PS\n"); + lbs_deb_cmd("locallisteninterval = %d\n", adapter->locallisteninterval); psm->locallisteninterval = @@ -86,18 +80,18 @@ static int wlan_cmd_802_11_ps_mode(wlan_private * priv, break; case cmd_subcmd_exit_ps: - lbs_pr_debug(1, "PS command:" "SubCode- Exit PS\n"); + lbs_deb_cmd("PS command:" "SubCode- Exit PS\n"); break; case cmd_subcmd_sleep_confirmed: - lbs_pr_debug(1, "PS command: SubCode- sleep confirm\n"); + lbs_deb_cmd("PS command: SubCode- sleep confirm\n"); break; default: break; } - LEAVE(); + lbs_deb_leave(LBS_DEB_CMD); return 0; } @@ -115,8 +109,7 @@ static int wlan_cmd_802_11_inactivity_timeout(wlan_private * priv, cmd->params.inactivity_timeout.action = cpu_to_le16(cmd_action); if (cmd_action) - cmd->params.inactivity_timeout.timeout = - cpu_to_le16(*timeout); + cmd->params.inactivity_timeout.timeout = cpu_to_le16(*timeout); else cmd->params.inactivity_timeout.timeout = 0; @@ -130,11 +123,10 @@ static int wlan_cmd_802_11_sleep_params(wlan_private * priv, wlan_adapter *adapter = priv->adapter; struct cmd_ds_802_11_sleep_params *sp = &cmd->params.sleep_params; - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); - cmd->size = - cpu_to_le16((sizeof(struct cmd_ds_802_11_sleep_params)) + - S_DS_GEN); + cmd->size = cpu_to_le16((sizeof(struct cmd_ds_802_11_sleep_params)) + + S_DS_GEN); cmd->command = cpu_to_le16(cmd_802_11_sleep_params); if (cmd_action == cmd_act_get) { @@ -151,7 +143,7 @@ static int wlan_cmd_802_11_sleep_params(wlan_private * priv, sp->reserved = cpu_to_le16(adapter->sp.sp_reserved); } - LEAVE(); + lbs_deb_leave(LBS_DEB_CMD); return 0; } @@ -165,17 +157,16 @@ static int wlan_cmd_802_11_set_wep(wlan_private * priv, int ret = 0; struct assoc_request * assoc_req = pdata_buf; - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); cmd->command = cpu_to_le16(cmd_802_11_set_wep); - cmd->size = cpu_to_le16((sizeof(struct cmd_ds_802_11_set_wep)) - + S_DS_GEN); + cmd->size = cpu_to_le16(sizeof(*wep) + S_DS_GEN); if (cmd_act == cmd_act_add) { int i; if (!assoc_req) { - lbs_pr_debug(1, "Invalid association request!"); + lbs_deb_cmd("Invalid association request!"); ret = -1; goto done; } @@ -183,11 +174,10 @@ static int wlan_cmd_802_11_set_wep(wlan_private * priv, wep->action = cpu_to_le16(cmd_act_add); /* default tx key index */ - wep->keyindex = cpu_to_le16((u16) - (assoc_req->wep_tx_keyidx & - (u32)cmd_WEP_KEY_INDEX_MASK)); + wep->keyindex = cpu_to_le16((u16)(assoc_req->wep_tx_keyidx & + (u32)cmd_WEP_KEY_INDEX_MASK)); - lbs_pr_debug(1, "Tx key Index: %u\n", wep->keyindex); + lbs_deb_cmd("Tx key Index: %u\n", le16_to_cpu(wep->keyindex)); /* Copy key types and material to host command structure */ for (i = 0; i < 4; i++) { @@ -195,19 +185,21 @@ static int wlan_cmd_802_11_set_wep(wlan_private * priv, switch (pkey->len) { case KEY_LEN_WEP_40: - wep->keytype[i] = cmd_type_wep_40_bit; + wep->keytype[i] = + cpu_to_le16(cmd_type_wep_40_bit); memmove(&wep->keymaterial[i], pkey->key, pkey->len); break; case KEY_LEN_WEP_104: - wep->keytype[i] = cmd_type_wep_104_bit; + wep->keytype[i] = + cpu_to_le16(cmd_type_wep_104_bit); memmove(&wep->keymaterial[i], pkey->key, pkey->len); break; case 0: break; default: - lbs_pr_debug(1, "Invalid WEP key %d length of %d\n", + lbs_deb_cmd("Invalid WEP key %d length of %d\n", i, pkey->len); ret = -1; goto done; @@ -219,36 +211,39 @@ static int wlan_cmd_802_11_set_wep(wlan_private * priv, wep->action = cpu_to_le16(cmd_act_remove); /* default tx key index */ - wep->keyindex = cpu_to_le16((u16) - (adapter->wep_tx_keyidx & - (u32)cmd_WEP_KEY_INDEX_MASK)); + wep->keyindex = cpu_to_le16((u16)(adapter->wep_tx_keyidx & + (u32)cmd_WEP_KEY_INDEX_MASK)); } ret = 0; done: - LEAVE(); + lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); return ret; } static int wlan_cmd_802_11_enable_rsn(wlan_private * priv, struct cmd_ds_command *cmd, - u16 cmd_action) + u16 cmd_action, + void * pdata_buf) { struct cmd_ds_802_11_enable_rsn *penableRSN = &cmd->params.enbrsn; - wlan_adapter *adapter = priv->adapter; + u32 * enable = pdata_buf; + + lbs_deb_enter(LBS_DEB_CMD); cmd->command = cpu_to_le16(cmd_802_11_enable_rsn); - cmd->size = - cpu_to_le16(sizeof(struct cmd_ds_802_11_enable_rsn) + - S_DS_GEN); + cmd->size = cpu_to_le16(sizeof(*penableRSN) + S_DS_GEN); penableRSN->action = cpu_to_le16(cmd_action); - if (adapter->secinfo.WPAenabled || adapter->secinfo.WPA2enabled) { - penableRSN->enable = cpu_to_le16(cmd_enable_rsn); - } else { - penableRSN->enable = cpu_to_le16(cmd_disable_rsn); + + if (cmd_action == cmd_act_set) { + if (*enable) + penableRSN->enable = cpu_to_le16(cmd_enable_rsn); + else + penableRSN->enable = cpu_to_le16(cmd_enable_rsn); } + lbs_deb_leave(LBS_DEB_CMD); return 0; } @@ -259,14 +254,12 @@ static void set_one_wpa_key(struct MrvlIEtype_keyParamSet * pkeyparamset, pkeyparamset->keytypeid = cpu_to_le16(pkey->type); if (pkey->flags & KEY_INFO_WPA_ENABLED) { - pkeyparamset->keyinfo = cpu_to_le16(KEY_INFO_WPA_ENABLED); - } else { - pkeyparamset->keyinfo = cpu_to_le16(!KEY_INFO_WPA_ENABLED); + pkeyparamset->keyinfo |= cpu_to_le16(KEY_INFO_WPA_ENABLED); } - if (pkey->flags & KEY_INFO_WPA_UNICAST) { pkeyparamset->keyinfo |= cpu_to_le16(KEY_INFO_WPA_UNICAST); - } else if (pkey->flags & KEY_INFO_WPA_MCAST) { + } + if (pkey->flags & KEY_INFO_WPA_MCAST) { pkeyparamset->keyinfo |= cpu_to_le16(KEY_INFO_WPA_MCAST); } @@ -284,46 +277,45 @@ static int wlan_cmd_802_11_key_material(wlan_private * priv, u16 cmd_action, u32 cmd_oid, void *pdata_buf) { - wlan_adapter *adapter = priv->adapter; struct cmd_ds_802_11_key_material *pkeymaterial = &cmd->params.keymaterial; + struct assoc_request * assoc_req = pdata_buf; int ret = 0; int index = 0; - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); cmd->command = cpu_to_le16(cmd_802_11_key_material); pkeymaterial->action = cpu_to_le16(cmd_action); if (cmd_action == cmd_act_get) { - cmd->size = cpu_to_le16( S_DS_GEN - + sizeof (pkeymaterial->action)); + cmd->size = cpu_to_le16(S_DS_GEN + sizeof (pkeymaterial->action)); ret = 0; goto done; } memset(&pkeymaterial->keyParamSet, 0, sizeof(pkeymaterial->keyParamSet)); - if (adapter->wpa_unicast_key.len) { + if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) { set_one_wpa_key(&pkeymaterial->keyParamSet[index], - &adapter->wpa_unicast_key); + &assoc_req->wpa_unicast_key); index++; } - if (adapter->wpa_mcast_key.len) { + if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) { set_one_wpa_key(&pkeymaterial->keyParamSet[index], - &adapter->wpa_mcast_key); + &assoc_req->wpa_mcast_key); index++; } cmd->size = cpu_to_le16( S_DS_GEN - + sizeof (pkeymaterial->action) - + index * sizeof(struct MrvlIEtype_keyParamSet)); + + sizeof (pkeymaterial->action) + + (index * sizeof(struct MrvlIEtype_keyParamSet))); ret = 0; done: - LEAVE(); + lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); return ret; } @@ -354,8 +346,7 @@ static int wlan_cmd_802_11_get_stat(wlan_private * priv, { cmd->command = cpu_to_le16(cmd_802_11_get_stat); cmd->size = - cpu_to_le16(sizeof(struct cmd_ds_802_11_get_stat) + - S_DS_GEN); + cpu_to_le16(sizeof(struct cmd_ds_802_11_get_stat) + S_DS_GEN); return 0; } @@ -369,14 +360,12 @@ static int wlan_cmd_802_11_snmp_mib(wlan_private * priv, wlan_adapter *adapter = priv->adapter; u8 ucTemp; - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); - lbs_pr_debug(1, "SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid); + lbs_deb_cmd("SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid); cmd->command = cpu_to_le16(cmd_802_11_snmp_mib); - cmd->size = - cpu_to_le16(sizeof(struct cmd_ds_802_11_snmp_mib) + - S_DS_GEN); + cmd->size = cpu_to_le16(sizeof(*pSNMPMIB) + S_DS_GEN); switch (cmd_oid) { case OID_802_11_INFRASTRUCTURE_MODE: @@ -407,7 +396,7 @@ static int wlan_cmd_802_11_snmp_mib(wlan_private * priv, pSNMPMIB->querytype = cmd_act_set; pSNMPMIB->bufsize = sizeof(u16); ulTemp = *(u32 *)pdata_buf; - *((unsigned short *)(pSNMPMIB->value)) = + *((__le16 *)(pSNMPMIB->value)) = cpu_to_le16((u16) ulTemp); } break; @@ -420,15 +409,12 @@ static int wlan_cmd_802_11_snmp_mib(wlan_private * priv, pSNMPMIB->oid = cpu_to_le16((u16) fragthresh_i); if (cmd_action == cmd_act_get) { - pSNMPMIB->querytype = - cpu_to_le16(cmd_act_get); + pSNMPMIB->querytype = cpu_to_le16(cmd_act_get); } else if (cmd_action == cmd_act_set) { - pSNMPMIB->querytype = - cpu_to_le16(cmd_act_set); - pSNMPMIB->bufsize = - cpu_to_le16(sizeof(u16)); + pSNMPMIB->querytype = cpu_to_le16(cmd_act_set); + pSNMPMIB->bufsize = cpu_to_le16(sizeof(u16)); ulTemp = *((u32 *) pdata_buf); - *((unsigned short *)(pSNMPMIB->value)) = + *((__le16 *)(pSNMPMIB->value)) = cpu_to_le16((u16) ulTemp); } @@ -443,16 +429,12 @@ static int wlan_cmd_802_11_snmp_mib(wlan_private * priv, pSNMPMIB->oid = le16_to_cpu((u16) rtsthresh_i); if (cmd_action == cmd_act_get) { - pSNMPMIB->querytype = - cpu_to_le16(cmd_act_get); + pSNMPMIB->querytype = cpu_to_le16(cmd_act_get); } else if (cmd_action == cmd_act_set) { - pSNMPMIB->querytype = - cpu_to_le16(cmd_act_set); - pSNMPMIB->bufsize = - cpu_to_le16(sizeof(u16)); - ulTemp = *((u32 *) - pdata_buf); - *(unsigned short *)(pSNMPMIB->value) = + pSNMPMIB->querytype = cpu_to_le16(cmd_act_set); + pSNMPMIB->bufsize = cpu_to_le16(sizeof(u16)); + ulTemp = *((u32 *)pdata_buf); + *(__le16 *)(pSNMPMIB->value) = cpu_to_le16((u16) ulTemp); } @@ -462,13 +444,11 @@ static int wlan_cmd_802_11_snmp_mib(wlan_private * priv, pSNMPMIB->oid = cpu_to_le16((u16) short_retrylim_i); if (cmd_action == cmd_act_get) { - pSNMPMIB->querytype = - cpu_to_le16(cmd_act_get); + pSNMPMIB->querytype = cpu_to_le16(cmd_act_get); } else if (cmd_action == cmd_act_set) { - pSNMPMIB->querytype = - cpu_to_le16(cmd_act_set); + pSNMPMIB->querytype = cpu_to_le16(cmd_act_set); pSNMPMIB->bufsize = cpu_to_le16(sizeof(u16)); - *((unsigned short *)(pSNMPMIB->value)) = + *((__le16 *)(pSNMPMIB->value)) = cpu_to_le16((u16) adapter->txretrycount); } @@ -477,16 +457,18 @@ static int wlan_cmd_802_11_snmp_mib(wlan_private * priv, break; } - lbs_pr_debug(1, + lbs_deb_cmd( "SNMP_CMD: command=0x%x, size=0x%x, seqnum=0x%x, result=0x%x\n", - cmd->command, cmd->size, cmd->seqnum, cmd->result); + le16_to_cpu(cmd->command), le16_to_cpu(cmd->size), + le16_to_cpu(cmd->seqnum), le16_to_cpu(cmd->result)); - lbs_pr_debug(1, + lbs_deb_cmd( "SNMP_CMD: action=0x%x, oid=0x%x, oidsize=0x%x, value=0x%x\n", - pSNMPMIB->querytype, pSNMPMIB->oid, pSNMPMIB->bufsize, - *(u16 *) pSNMPMIB->value); + le16_to_cpu(pSNMPMIB->querytype), le16_to_cpu(pSNMPMIB->oid), + le16_to_cpu(pSNMPMIB->bufsize), + le16_to_cpu(*(__le16 *) pSNMPMIB->value)); - LEAVE(); + lbs_deb_leave(LBS_DEB_CMD); return 0; } @@ -495,10 +477,9 @@ static int wlan_cmd_802_11_radio_control(wlan_private * priv, int cmd_action) { wlan_adapter *adapter = priv->adapter; - struct cmd_ds_802_11_radio_control *pradiocontrol = - &cmd->params.radio; + struct cmd_ds_802_11_radio_control *pradiocontrol = &cmd->params.radio; - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); cmd->size = cpu_to_le16((sizeof(struct cmd_ds_802_11_radio_control)) + @@ -527,7 +508,7 @@ static int wlan_cmd_802_11_radio_control(wlan_private * priv, else pradiocontrol->control &= cpu_to_le16(~TURN_ON_RF); - LEAVE(); + lbs_deb_leave(LBS_DEB_CMD); return 0; } @@ -538,16 +519,16 @@ static int wlan_cmd_802_11_rf_tx_power(wlan_private * priv, struct cmd_ds_802_11_rf_tx_power *prtp = &cmd->params.txp; - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); cmd->size = - cpu_to_le16((sizeof(struct cmd_ds_802_11_rf_tx_power)) + - S_DS_GEN); + cpu_to_le16((sizeof(struct cmd_ds_802_11_rf_tx_power)) + S_DS_GEN); cmd->command = cpu_to_le16(cmd_802_11_rf_tx_power); - prtp->action = cmd_action; + prtp->action = cpu_to_le16(cmd_action); - lbs_pr_debug(1, "RF_TX_POWER_CMD: size:%d cmd:0x%x Act:%d\n", cmd->size, - cmd->command, prtp->action); + lbs_deb_cmd("RF_TX_POWER_CMD: size:%d cmd:0x%x Act:%d\n", + le16_to_cpu(cmd->size), le16_to_cpu(cmd->command), + le16_to_cpu(prtp->action)); switch (cmd_action) { case cmd_act_tx_power_opt_get: @@ -557,14 +538,12 @@ static int wlan_cmd_802_11_rf_tx_power(wlan_private * priv, case cmd_act_tx_power_opt_set_high: prtp->action = cpu_to_le16(cmd_act_set); - prtp->currentlevel = - cpu_to_le16(cmd_act_tx_power_index_high); + prtp->currentlevel = cpu_to_le16(cmd_act_tx_power_index_high); break; case cmd_act_tx_power_opt_set_mid: prtp->action = cpu_to_le16(cmd_act_set); - prtp->currentlevel = - cpu_to_le16(cmd_act_tx_power_index_mid); + prtp->currentlevel = cpu_to_le16(cmd_act_tx_power_index_mid); break; case cmd_act_tx_power_opt_set_low: @@ -572,7 +551,8 @@ static int wlan_cmd_802_11_rf_tx_power(wlan_private * priv, prtp->currentlevel = cpu_to_le16(*((u16 *) pdata_buf)); break; } - LEAVE(); + + lbs_deb_leave(LBS_DEB_CMD); return 0; } @@ -583,15 +563,12 @@ static int wlan_cmd_802_11_rf_antenna(wlan_private * priv, struct cmd_ds_802_11_rf_antenna *rant = &cmd->params.rant; cmd->command = cpu_to_le16(cmd_802_11_rf_antenna); - cmd->size = - cpu_to_le16(sizeof(struct cmd_ds_802_11_rf_antenna) + - S_DS_GEN); + cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_rf_antenna) + + S_DS_GEN); rant->action = cpu_to_le16(cmd_action); - if ((cmd_action == cmd_act_set_rx) || - (cmd_action == cmd_act_set_tx)) { - rant->antennamode = - cpu_to_le16((u16) (*(u32 *) pdata_buf)); + if ((cmd_action == cmd_act_set_rx) || (cmd_action == cmd_act_set_tx)) { + rant->antennamode = cpu_to_le16((u16) (*(u32 *) pdata_buf)); } return 0; @@ -610,13 +587,13 @@ static int wlan_cmd_802_11_rate_adapt_rateset(wlan_private * priv, + S_DS_GEN); cmd->command = cpu_to_le16(cmd_802_11_rate_adapt_rateset); - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); - rateadapt->action = cmd_action; - rateadapt->enablehwauto = adapter->enablehwauto; - rateadapt->bitmap = adapter->ratebitmap; + rateadapt->action = cpu_to_le16(cmd_action); + rateadapt->enablehwauto = cpu_to_le16(adapter->enablehwauto); + rateadapt->bitmap = cpu_to_le16(adapter->ratebitmap); - LEAVE(); + lbs_deb_leave(LBS_DEB_CMD); return 0; } @@ -626,12 +603,10 @@ static int wlan_cmd_802_11_data_rate(wlan_private * priv, { struct cmd_ds_802_11_data_rate *pdatarate = &cmd->params.drate; wlan_adapter *adapter = priv->adapter; - u16 action = cmd_action; - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); - cmd->size = - cpu_to_le16(sizeof(struct cmd_ds_802_11_data_rate) + + cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_data_rate) + S_DS_GEN); cmd->command = cpu_to_le16(cmd_802_11_data_rate); @@ -640,15 +615,15 @@ static int wlan_cmd_802_11_data_rate(wlan_private * priv, pdatarate->action = cpu_to_le16(cmd_action); - if (action == cmd_act_set_tx_fix_rate) { + if (cmd_action == cmd_act_set_tx_fix_rate) { pdatarate->datarate[0] = libertas_data_rate_to_index(adapter->datarate); - lbs_pr_debug(1, "Setting FW for fixed rate 0x%02X\n", + lbs_deb_cmd("Setting FW for fixed rate 0x%02X\n", adapter->datarate); - } else if (action == cmd_act_set_tx_auto) { - lbs_pr_debug(1, "Setting FW for AUTO rate\n"); + } else if (cmd_action == cmd_act_set_tx_auto) { + lbs_deb_cmd("Setting FW for AUTO rate\n"); } - LEAVE(); + lbs_deb_leave(LBS_DEB_CMD); return 0; } @@ -659,8 +634,7 @@ static int wlan_cmd_mac_multicast_adr(wlan_private * priv, struct cmd_ds_mac_multicast_adr *pMCastAdr = &cmd->params.madr; wlan_adapter *adapter = priv->adapter; - cmd->size = - cpu_to_le16(sizeof(struct cmd_ds_mac_multicast_adr) + + cmd->size = cpu_to_le16(sizeof(struct cmd_ds_mac_multicast_adr) + S_DS_GEN); cmd->command = cpu_to_le16(cmd_mac_multicast_adr); @@ -680,8 +654,8 @@ static int wlan_cmd_802_11_rf_channel(wlan_private * priv, struct cmd_ds_802_11_rf_channel *rfchan = &cmd->params.rfchannel; cmd->command = cpu_to_le16(cmd_802_11_rf_channel); - cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_rf_channel) - + S_DS_GEN); + cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_rf_channel) + + S_DS_GEN); if (option == cmd_opt_802_11_rf_channel_set) { rfchan->currentchannel = cpu_to_le16(*((u16 *) pdata_buf)); @@ -698,9 +672,8 @@ static int wlan_cmd_802_11_rssi(wlan_private * priv, wlan_adapter *adapter = priv->adapter; cmd->command = cpu_to_le16(cmd_802_11_rssi); - cmd->size = - cpu_to_le16(sizeof(struct cmd_ds_802_11_rssi) + S_DS_GEN); - cmd->params.rssi.N = priv->adapter->bcn_avg_factor; + cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_rssi) + S_DS_GEN); + cmd->params.rssi.N = cpu_to_le16(priv->adapter->bcn_avg_factor); /* reset Beacon SNR/NF/RSSI values */ adapter->SNR[TYPE_BEACON][TYPE_NOAVG] = 0; @@ -719,7 +692,7 @@ static int wlan_cmd_reg_access(wlan_private * priv, { struct wlan_offset_value *offval; - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); offval = (struct wlan_offset_value *)pdata_buf; @@ -729,9 +702,8 @@ static int wlan_cmd_reg_access(wlan_private * priv, struct cmd_ds_mac_reg_access *macreg; cmdptr->size = - cpu_to_le16(sizeof - (struct cmd_ds_mac_reg_access) - + S_DS_GEN); + cpu_to_le16(sizeof (struct cmd_ds_mac_reg_access) + + S_DS_GEN); macreg = (struct cmd_ds_mac_reg_access *)&cmdptr->params. macreg; @@ -785,7 +757,7 @@ static int wlan_cmd_reg_access(wlan_private * priv, break; } - LEAVE(); + lbs_deb_leave(LBS_DEB_CMD); return 0; } @@ -796,8 +768,7 @@ static int wlan_cmd_802_11_mac_address(wlan_private * priv, wlan_adapter *adapter = priv->adapter; cmd->command = cpu_to_le16(cmd_802_11_mac_address); - cmd->size = - cpu_to_le16(sizeof(struct cmd_ds_802_11_mac_address) + + cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_mac_address) + S_DS_GEN); cmd->result = 0; @@ -818,12 +789,11 @@ static int wlan_cmd_802_11_eeprom_access(wlan_private * priv, { struct wlan_ioctl_regrdwr *ea = pdata_buf; - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); cmd->command = cpu_to_le16(cmd_802_11_eeprom_access); - cmd->size = - cpu_to_le16(sizeof(struct cmd_ds_802_11_eeprom_access) + - S_DS_GEN); + cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_eeprom_access) + + S_DS_GEN); cmd->result = 0; cmd->params.rdeeprom.action = cpu_to_le16(ea->action); @@ -839,11 +809,10 @@ static int wlan_cmd_bt_access(wlan_private * priv, u16 cmd_action, void *pdata_buf) { struct cmd_ds_bt_access *bt_access = &cmd->params.bt; - lbs_pr_debug(1, "BT CMD(%d)\n", cmd_action); + lbs_deb_cmd("BT CMD(%d)\n", cmd_action); cmd->command = cpu_to_le16(cmd_bt_access); - cmd->size = cpu_to_le16(sizeof(struct cmd_ds_bt_access) - + S_DS_GEN); + cmd->size = cpu_to_le16(sizeof(struct cmd_ds_bt_access) + S_DS_GEN); cmd->result = 0; bt_access->action = cpu_to_le16(cmd_action); @@ -861,6 +830,11 @@ static int wlan_cmd_bt_access(wlan_private * priv, break; case cmd_act_bt_access_reset: break; + case cmd_act_bt_access_set_invert: + bt_access->id = cpu_to_le32(*(u32 *) pdata_buf); + break; + case cmd_act_bt_access_get_invert: + break; default: break; } @@ -872,11 +846,10 @@ static int wlan_cmd_fwt_access(wlan_private * priv, u16 cmd_action, void *pdata_buf) { struct cmd_ds_fwt_access *fwt_access = &cmd->params.fwt; - lbs_pr_debug(1, "FWT CMD(%d)\n", cmd_action); + lbs_deb_cmd("FWT CMD(%d)\n", cmd_action); cmd->command = cpu_to_le16(cmd_fwt_access); - cmd->size = cpu_to_le16(sizeof(struct cmd_ds_fwt_access) - + S_DS_GEN); + cmd->size = cpu_to_le16(sizeof(struct cmd_ds_fwt_access) + S_DS_GEN); cmd->result = 0; if (pdata_buf) @@ -894,11 +867,10 @@ static int wlan_cmd_mesh_access(wlan_private * priv, u16 cmd_action, void *pdata_buf) { struct cmd_ds_mesh_access *mesh_access = &cmd->params.mesh; - lbs_pr_debug(1, "FWT CMD(%d)\n", cmd_action); + lbs_deb_cmd("FWT CMD(%d)\n", cmd_action); cmd->command = cpu_to_le16(cmd_mesh_access); - cmd->size = cpu_to_le16(sizeof(struct cmd_ds_mesh_access) - + S_DS_GEN); + cmd->size = cpu_to_le16(sizeof(struct cmd_ds_mesh_access) + S_DS_GEN); cmd->result = 0; if (pdata_buf) @@ -916,23 +888,23 @@ void libertas_queue_cmd(wlan_adapter * adapter, struct cmd_ctrl_node *cmdnode, u unsigned long flags; struct cmd_ds_command *cmdptr; - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); if (!cmdnode) { - lbs_pr_debug(1, "QUEUE_CMD: cmdnode is NULL\n"); + lbs_deb_cmd("QUEUE_CMD: cmdnode is NULL\n"); goto done; } cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr; if (!cmdptr) { - lbs_pr_debug(1, "QUEUE_CMD: cmdptr is NULL\n"); + lbs_deb_cmd("QUEUE_CMD: cmdptr is NULL\n"); goto done; } /* Exit_PS command needs to be queued in the header always. */ if (cmdptr->command == cmd_802_11_ps_mode) { struct cmd_ds_802_11_ps_mode *psm = &cmdptr->params.psmode; - if (psm->action == cmd_subcmd_exit_ps) { + if (psm->action == cpu_to_le16(cmd_subcmd_exit_ps)) { if (adapter->psstate != PS_STATE_FULL_POWER) addtail = 0; } @@ -948,13 +920,12 @@ void libertas_queue_cmd(wlan_adapter * adapter, struct cmd_ctrl_node *cmdnode, u spin_unlock_irqrestore(&adapter->driver_lock, flags); - lbs_pr_debug(1, "QUEUE_CMD: Inserted node=%p, cmd=0x%x in cmdpendingq\n", + lbs_deb_cmd("QUEUE_CMD: Inserted node=%p, cmd=0x%x in cmdpendingq\n", cmdnode, - ((struct cmd_ds_gen*)cmdnode->bufvirtualaddr)->command); + le16_to_cpu(((struct cmd_ds_gen*)cmdnode->bufvirtualaddr)->command)); done: - LEAVE(); - return; + lbs_deb_leave(LBS_DEB_CMD); } /* @@ -974,10 +945,10 @@ static int DownloadcommandToStation(wlan_private * priv, u16 cmdsize; u16 command; - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); if (!adapter || !cmdnode) { - lbs_pr_debug(1, "DNLD_CMD: adapter = %p, cmdnode = %p\n", + lbs_deb_cmd("DNLD_CMD: adapter = %p, cmdnode = %p\n", adapter, cmdnode); if (cmdnode) { spin_lock_irqsave(&adapter->driver_lock, flags); @@ -993,7 +964,7 @@ static int DownloadcommandToStation(wlan_private * priv, spin_lock_irqsave(&adapter->driver_lock, flags); if (!cmdptr || !cmdptr->size) { - lbs_pr_debug(1, "DNLD_CMD: cmdptr is Null or cmd size is Zero, " + lbs_deb_cmd("DNLD_CMD: cmdptr is Null or cmd size is Zero, " "Not sending\n"); __libertas_cleanup_and_insert_cmd(priv, cmdnode); spin_unlock_irqrestore(&adapter->driver_lock, flags); @@ -1004,8 +975,8 @@ static int DownloadcommandToStation(wlan_private * priv, adapter->cur_cmd = cmdnode; adapter->cur_cmd_retcode = 0; spin_unlock_irqrestore(&adapter->driver_lock, flags); - lbs_pr_debug(1, "DNLD_CMD:: Before download, size of cmd = %d\n", - cmdptr->size); + lbs_deb_cmd("DNLD_CMD:: Before download, size of cmd = %d\n", + le16_to_cpu(cmdptr->size)); cmdsize = cmdptr->size; @@ -1014,10 +985,10 @@ static int DownloadcommandToStation(wlan_private * priv, cmdnode->cmdwaitqwoken = 0; cmdsize = cpu_to_le16(cmdsize); - ret = libertas_sbi_host_to_card(priv, MVMS_CMD, (u8 *) cmdptr, cmdsize); + ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmdptr, cmdsize); if (ret != 0) { - lbs_pr_debug(1, "DNLD_CMD: Host to Card failed\n"); + lbs_deb_cmd("DNLD_CMD: Host to Card failed\n"); spin_lock_irqsave(&adapter->driver_lock, flags); __libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd); adapter->cur_cmd = NULL; @@ -1026,12 +997,11 @@ static int DownloadcommandToStation(wlan_private * priv, goto done; } - lbs_pr_debug(1, "DNLD_CMD: Sent command 0x%x @ %lu\n", command, jiffies); + lbs_deb_cmd("DNLD_CMD: Sent command 0x%x @ %lu\n", command, jiffies); lbs_dbg_hex("DNLD_CMD: command", cmdnode->bufvirtualaddr, cmdsize); /* Setup the timer after transmit command */ - if (command == cmd_802_11_scan - || command == cmd_802_11_authenticate + if (command == cmd_802_11_scan || command == cmd_802_11_authenticate || command == cmd_802_11_associate) mod_timer(&adapter->command_timer, jiffies + (10*HZ)); else @@ -1039,8 +1009,8 @@ static int DownloadcommandToStation(wlan_private * priv, ret = 0; - done: - LEAVE(); +done: + lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); return ret; } @@ -1049,17 +1019,16 @@ static int wlan_cmd_mac_control(wlan_private * priv, { struct cmd_ds_mac_control *mac = &cmd->params.macctrl; - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); cmd->command = cpu_to_le16(cmd_mac_control); - cmd->size = - cpu_to_le16(sizeof(struct cmd_ds_mac_control) + S_DS_GEN); + cmd->size = cpu_to_le16(sizeof(struct cmd_ds_mac_control) + S_DS_GEN); mac->action = cpu_to_le16(priv->adapter->currentpacketfilter); - lbs_pr_debug(1, "wlan_cmd_mac_control(): action=0x%X size=%d\n", - mac->action, cmd->size); + lbs_deb_cmd("wlan_cmd_mac_control(): action=0x%X size=%d\n", + le16_to_cpu(mac->action), le16_to_cpu(cmd->size)); - LEAVE(); + lbs_deb_leave(LBS_DEB_CMD); return 0; } @@ -1093,17 +1062,17 @@ int libertas_set_radio_control(wlan_private * priv) { int ret = 0; - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); ret = libertas_prepare_and_send_command(priv, cmd_802_11_radio_control, cmd_act_set, cmd_option_waitforrsp, 0, NULL); - lbs_pr_debug(1, "RADIO_SET: on or off: 0x%X, preamble = 0x%X\n", + lbs_deb_cmd("RADIO_SET: on or off: 0x%X, preamble = 0x%X\n", priv->adapter->radioon, priv->adapter->preamble); - LEAVE(); + lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); return ret; } @@ -1111,16 +1080,16 @@ int libertas_set_mac_packet_filter(wlan_private * priv) { int ret = 0; - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); - lbs_pr_debug(1, "libertas_set_mac_packet_filter value = %x\n", + lbs_deb_cmd("libertas_set_mac_packet_filter value = %x\n", priv->adapter->currentpacketfilter); /* Send MAC control command to station */ ret = libertas_prepare_and_send_command(priv, cmd_mac_control, 0, 0, 0, NULL); - LEAVE(); + lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); return ret; } @@ -1146,16 +1115,16 @@ int libertas_prepare_and_send_command(wlan_private * priv, struct cmd_ds_command *cmdptr; unsigned long flags; - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); if (!adapter) { - lbs_pr_debug(1, "PREP_CMD: adapter is Null\n"); + lbs_deb_cmd("PREP_CMD: adapter is Null\n"); ret = -1; goto done; } if (adapter->surpriseremoved) { - lbs_pr_debug(1, "PREP_CMD: Card is Removed\n"); + lbs_deb_cmd("PREP_CMD: Card is Removed\n"); ret = -1; goto done; } @@ -1163,7 +1132,7 @@ int libertas_prepare_and_send_command(wlan_private * priv, cmdnode = libertas_get_free_cmd_ctrl_node(priv); if (cmdnode == NULL) { - lbs_pr_debug(1, "PREP_CMD: No free cmdnode\n"); + lbs_deb_cmd("PREP_CMD: No free cmdnode\n"); /* Wake up main thread to execute next command */ wake_up_interruptible(&priv->mainthread.waitq); @@ -1175,11 +1144,11 @@ int libertas_prepare_and_send_command(wlan_private * priv, cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr; - lbs_pr_debug(1, "PREP_CMD: Val of cmd ptr=%p, command=0x%X\n", + lbs_deb_cmd("PREP_CMD: Val of cmd ptr=%p, command=0x%X\n", cmdptr, cmd_no); if (!cmdptr) { - lbs_pr_debug(1, "PREP_CMD: bufvirtualaddr of cmdnode is NULL\n"); + lbs_deb_cmd("PREP_CMD: bufvirtualaddr of cmdnode is NULL\n"); libertas_cleanup_and_insert_cmd(priv, cmdnode); ret = -1; goto done; @@ -1189,7 +1158,7 @@ int libertas_prepare_and_send_command(wlan_private * priv, adapter->seqnum++; cmdptr->seqnum = cpu_to_le16(adapter->seqnum); - cmdptr->command = cmd_no; + cmdptr->command = cpu_to_le16(cmd_no); cmdptr->result = 0; switch (cmd_no) { @@ -1298,13 +1267,13 @@ int libertas_prepare_and_send_command(wlan_private * priv, break; case cmd_802_11_enable_rsn: - ret = wlan_cmd_802_11_enable_rsn(priv, cmdptr, cmd_action); + ret = wlan_cmd_802_11_enable_rsn(priv, cmdptr, cmd_action, + pdata_buf); break; case cmd_802_11_key_material: - ret = wlan_cmd_802_11_key_material(priv, cmdptr, - cmd_action, cmd_oid, - pdata_buf); + ret = wlan_cmd_802_11_key_material(priv, cmdptr, cmd_action, + cmd_oid, pdata_buf); break; case cmd_802_11_pairwise_tsc: @@ -1325,9 +1294,8 @@ int libertas_prepare_and_send_command(wlan_private * priv, case cmd_802_11_get_afc: cmdptr->command = cpu_to_le16(cmd_no); - cmdptr->size = - cpu_to_le16(sizeof(struct cmd_ds_802_11_afc) + - S_DS_GEN); + cmdptr->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_afc) + + S_DS_GEN); memmove(&cmdptr->params.afc, pdata_buf, sizeof(struct cmd_ds_802_11_afc)); @@ -1406,29 +1374,26 @@ int libertas_prepare_and_send_command(wlan_private * priv, case cmd_get_tsf: cmdptr->command = cpu_to_le16(cmd_get_tsf); - cmdptr->size = - cpu_to_le16(sizeof(struct cmd_ds_get_tsf) - + S_DS_GEN); + cmdptr->size = cpu_to_le16(sizeof(struct cmd_ds_get_tsf) + + S_DS_GEN); ret = 0; break; case cmd_802_11_tx_rate_query: - cmdptr->command = - cpu_to_le16(cmd_802_11_tx_rate_query); - cmdptr->size = - cpu_to_le16(sizeof(struct cmd_tx_rate_query) + - S_DS_GEN); + cmdptr->command = cpu_to_le16(cmd_802_11_tx_rate_query); + cmdptr->size = cpu_to_le16(sizeof(struct cmd_tx_rate_query) + + S_DS_GEN); adapter->txrate = 0; ret = 0; break; default: - lbs_pr_debug(1, "PREP_CMD: unknown command- %#x\n", cmd_no); + lbs_deb_cmd("PREP_CMD: unknown command- %#x\n", cmd_no); ret = -1; break; } /* return error, since the command preparation failed */ if (ret != 0) { - lbs_pr_debug(1, "PREP_CMD: command preparation failed\n"); + lbs_deb_cmd("PREP_CMD: command preparation failed\n"); libertas_cleanup_and_insert_cmd(priv, cmdnode); ret = -1; goto done; @@ -1441,7 +1406,7 @@ int libertas_prepare_and_send_command(wlan_private * priv, wake_up_interruptible(&priv->mainthread.waitq); if (wait_option & cmd_option_waitforrsp) { - lbs_pr_debug(1, "PREP_CMD: Wait for CMD response\n"); + lbs_deb_cmd("PREP_CMD: Wait for CMD response\n"); might_sleep(); wait_event_interruptible(cmdnode->cmdwait_q, cmdnode->cmdwaitqwoken); @@ -1449,7 +1414,7 @@ int libertas_prepare_and_send_command(wlan_private * priv, spin_lock_irqsave(&adapter->driver_lock, flags); if (adapter->cur_cmd_retcode) { - lbs_pr_debug(1, "PREP_CMD: command failed with return code=%d\n", + lbs_deb_cmd("PREP_CMD: command failed with return code=%d\n", adapter->cur_cmd_retcode); adapter->cur_cmd_retcode = 0; ret = -1; @@ -1457,9 +1422,10 @@ int libertas_prepare_and_send_command(wlan_private * priv, spin_unlock_irqrestore(&adapter->driver_lock, flags); done: - LEAVE(); + lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); return ret; } +EXPORT_SYMBOL_GPL(libertas_prepare_and_send_command); /** * @brief This function allocates the command buffer and link @@ -1477,33 +1443,29 @@ int libertas_allocate_cmd_buffer(wlan_private * priv) u8 *ptempvirtualaddr; wlan_adapter *adapter = priv->adapter; - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); /* Allocate and initialize cmdCtrlNode */ ulbufsize = sizeof(struct cmd_ctrl_node) * MRVDRV_NUM_OF_CMD_BUFFER; - if (!(tempcmd_array = kmalloc(ulbufsize, GFP_KERNEL))) { - lbs_pr_debug(1, + if (!(tempcmd_array = kzalloc(ulbufsize, GFP_KERNEL))) { + lbs_deb_cmd( "ALLOC_CMD_BUF: failed to allocate tempcmd_array\n"); ret = -1; goto done; } - adapter->cmd_array = tempcmd_array; - memset(adapter->cmd_array, 0, ulbufsize); /* Allocate and initialize command buffers */ ulbufsize = MRVDRV_SIZE_OF_CMD_BUFFER; for (i = 0; i < MRVDRV_NUM_OF_CMD_BUFFER; i++) { - if (!(ptempvirtualaddr = kmalloc(ulbufsize, GFP_KERNEL))) { - lbs_pr_debug(1, + if (!(ptempvirtualaddr = kzalloc(ulbufsize, GFP_KERNEL))) { + lbs_deb_cmd( "ALLOC_CMD_BUF: ptempvirtualaddr: out of memory\n"); ret = -1; goto done; } - memset(ptempvirtualaddr, 0, ulbufsize); - /* Update command buffer virtual */ tempcmd_array[i].bufvirtualaddr = ptempvirtualaddr; } @@ -1514,8 +1476,9 @@ int libertas_allocate_cmd_buffer(wlan_private * priv) } ret = 0; - done: - LEAVE(); + +done: + lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); return ret; } @@ -1527,16 +1490,16 @@ int libertas_allocate_cmd_buffer(wlan_private * priv) */ int libertas_free_cmd_buffer(wlan_private * priv) { - u32 ulbufsize; + u32 ulbufsize; /* Someone needs to die for this. Slowly and painfully */ unsigned int i; struct cmd_ctrl_node *tempcmd_array; wlan_adapter *adapter = priv->adapter; - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); /* need to check if cmd array is allocated or not */ if (adapter->cmd_array == NULL) { - lbs_pr_debug(1, "FREE_CMD_BUF: cmd_array is Null\n"); + lbs_deb_cmd("FREE_CMD_BUF: cmd_array is Null\n"); goto done; } @@ -1546,7 +1509,7 @@ int libertas_free_cmd_buffer(wlan_private * priv) ulbufsize = MRVDRV_SIZE_OF_CMD_BUFFER; for (i = 0; i < MRVDRV_NUM_OF_CMD_BUFFER; i++) { if (tempcmd_array[i].bufvirtualaddr) { - lbs_pr_debug(1, "Free all the array\n"); + lbs_deb_cmd("Free all the array\n"); kfree(tempcmd_array[i].bufvirtualaddr); tempcmd_array[i].bufvirtualaddr = NULL; } @@ -1554,13 +1517,13 @@ int libertas_free_cmd_buffer(wlan_private * priv) /* Release cmd_ctrl_node */ if (adapter->cmd_array) { - lbs_pr_debug(1, "Free cmd_array\n"); + lbs_deb_cmd("Free cmd_array\n"); kfree(adapter->cmd_array); adapter->cmd_array = NULL; } done: - LEAVE(); + lbs_deb_leave(LBS_DEB_CMD); return 0; } @@ -1586,16 +1549,18 @@ struct cmd_ctrl_node *libertas_get_free_cmd_ctrl_node(wlan_private * priv) tempnode = (struct cmd_ctrl_node *)adapter->cmdfreeq.next; list_del((struct list_head *)tempnode); } else { - lbs_pr_debug(1, "GET_CMD_NODE: cmd_ctrl_node is not available\n"); + lbs_deb_cmd("GET_CMD_NODE: cmd_ctrl_node is not available\n"); tempnode = NULL; } spin_unlock_irqrestore(&adapter->driver_lock, flags); if (tempnode) { + /* lbs_pr_debug(3, "GET_CMD_NODE: cmdCtrlNode available\n"); lbs_pr_debug(3, "GET_CMD_NODE: cmdCtrlNode Address = %p\n", tempnode); + */ cleanup_cmdnode(tempnode); } @@ -1638,7 +1603,7 @@ void libertas_set_cmd_ctrl_node(wlan_private * priv, struct cmd_ctrl_node *ptempnode, u32 cmd_oid, u16 wait_option, void *pdata_buf) { - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); if (!ptempnode) return; @@ -1647,7 +1612,7 @@ void libertas_set_cmd_ctrl_node(wlan_private * priv, ptempnode->wait_option = wait_option; ptempnode->pdata_buf = pdata_buf; - LEAVE(); + lbs_deb_leave(LBS_DEB_CMD); } /** @@ -1666,7 +1631,7 @@ int libertas_execute_next_command(wlan_private * priv) unsigned long flags; int ret = 0; - lbs_pr_debug(1, "libertas_execute_next_command\n"); + lbs_deb_enter(LBS_DEB_CMD); spin_lock_irqsave(&adapter->driver_lock, flags); @@ -1685,23 +1650,24 @@ int libertas_execute_next_command(wlan_private * priv) spin_unlock_irqrestore(&adapter->driver_lock, flags); if (cmdnode) { - lbs_pr_debug(1, + lbs_deb_cmd( "EXEC_NEXT_CMD: Got next command from cmdpendingq\n"); cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr; if (is_command_allowed_in_ps(cmdptr->command)) { - if ((adapter->psstate == PS_STATE_SLEEP) - || (adapter->psstate == PS_STATE_PRE_SLEEP) - ) { - lbs_pr_debug(1, + if ((adapter->psstate == PS_STATE_SLEEP) || + (adapter->psstate == PS_STATE_PRE_SLEEP)) { + lbs_deb_cmd( "EXEC_NEXT_CMD: Cannot send cmd 0x%x in psstate %d\n", - cmdptr->command, adapter->psstate); + le16_to_cpu(cmdptr->command), + adapter->psstate); ret = -1; goto done; } - lbs_pr_debug(1, "EXEC_NEXT_CMD: OK to send command " + lbs_deb_cmd("EXEC_NEXT_CMD: OK to send command " "0x%x in psstate %d\n", - cmdptr->command, adapter->psstate); + le16_to_cpu(cmdptr->command), + adapter->psstate); } else if (adapter->psstate != PS_STATE_FULL_POWER) { /* * 1. Non-PS command: @@ -1737,12 +1703,12 @@ int libertas_execute_next_command(wlan_private * priv) struct cmd_ds_802_11_ps_mode *psm = &cmdptr->params.psmode; - lbs_pr_debug(1, + lbs_deb_cmd( "EXEC_NEXT_CMD: PS cmd- action=0x%x\n", psm->action); if (psm->action != cpu_to_le16(cmd_subcmd_exit_ps)) { - lbs_pr_debug(1, + lbs_deb_cmd( "EXEC_NEXT_CMD: Ignore Enter PS cmd\n"); list_del((struct list_head *)cmdnode); libertas_cleanup_and_insert_cmd(priv, cmdnode); @@ -1751,10 +1717,9 @@ int libertas_execute_next_command(wlan_private * priv) goto done; } - if ((adapter->psstate == PS_STATE_SLEEP) - || (adapter->psstate == PS_STATE_PRE_SLEEP) - ) { - lbs_pr_debug(1, + if ((adapter->psstate == PS_STATE_SLEEP) || + (adapter->psstate == PS_STATE_PRE_SLEEP)) { + lbs_deb_cmd( "EXEC_NEXT_CMD: Ignore ExitPS cmd in sleep\n"); list_del((struct list_head *)cmdnode); libertas_cleanup_and_insert_cmd(priv, cmdnode); @@ -1764,13 +1729,13 @@ int libertas_execute_next_command(wlan_private * priv) goto done; } - lbs_pr_debug(1, + lbs_deb_cmd( "EXEC_NEXT_CMD: Sending Exit_PS down...\n"); } } list_del((struct list_head *)cmdnode); - lbs_pr_debug(1, "EXEC_NEXT_CMD: Sending 0x%04X command\n", - cmdptr->command); + lbs_deb_cmd("EXEC_NEXT_CMD: Sending 0x%04X command\n", + le16_to_cpu(cmdptr->command)); DownloadcommandToStation(priv, cmdnode); } else { /* @@ -1780,18 +1745,18 @@ int libertas_execute_next_command(wlan_private * priv) if ((adapter->psmode != wlan802_11powermodecam) && (adapter->psstate == PS_STATE_FULL_POWER) && (adapter->connect_status == libertas_connected)) { - if (adapter->secinfo.WPAenabled - || adapter->secinfo.WPA2enabled) { + if (adapter->secinfo.WPAenabled || + adapter->secinfo.WPA2enabled) { /* check for valid WPA group keys */ - if (adapter->wpa_mcast_key.len - || adapter->wpa_unicast_key.len) { - lbs_pr_debug(1, + if (adapter->wpa_mcast_key.len || + adapter->wpa_unicast_key.len) { + lbs_deb_cmd( "EXEC_NEXT_CMD: WPA enabled and GTK_SET" " go back to PS_SLEEP"); libertas_ps_sleep(priv, 0); } } else { - lbs_pr_debug(1, + lbs_deb_cmd( "EXEC_NEXT_CMD: command PendQ is empty," " go back to PS_SLEEP"); libertas_ps_sleep(priv, 0); @@ -1801,6 +1766,7 @@ int libertas_execute_next_command(wlan_private * priv) ret = 0; done: + lbs_deb_leave(LBS_DEB_CMD); return ret; } @@ -1809,7 +1775,7 @@ void libertas_send_iwevcustom_event(wlan_private * priv, s8 * str) union iwreq_data iwrq; u8 buf[50]; - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); memset(&iwrq, 0, sizeof(union iwreq_data)); memset(buf, 0, sizeof(buf)); @@ -1819,15 +1785,13 @@ void libertas_send_iwevcustom_event(wlan_private * priv, s8 * str) iwrq.data.length = strlen(buf) + 1 + IW_EV_LCP_LEN; /* Send Event to upper layer */ - lbs_pr_debug(1, "Event Indication string = %s\n", - (char *)buf); - lbs_pr_debug(1, "Event Indication String length = %d\n", iwrq.data.length); + lbs_deb_cmd("Event Indication string = %s\n", (char *)buf); + lbs_deb_cmd("Event Indication String length = %d\n", iwrq.data.length); - lbs_pr_debug(1, "Sending wireless event IWEVCUSTOM for %s\n", str); - wireless_send_event(priv->wlan_dev.netdev, IWEVCUSTOM, &iwrq, buf); + lbs_deb_cmd("Sending wireless event IWEVCUSTOM for %s\n", str); + wireless_send_event(priv->dev, IWEVCUSTOM, &iwrq, buf); - LEAVE(); - return; + lbs_deb_leave(LBS_DEB_CMD); } static int sendconfirmsleep(wlan_private * priv, u8 * cmdptr, u16 size) @@ -1836,19 +1800,19 @@ static int sendconfirmsleep(wlan_private * priv, u8 * cmdptr, u16 size) wlan_adapter *adapter = priv->adapter; int ret = 0; - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); - lbs_pr_debug(1, "SEND_SLEEPC_CMD: Before download, size of cmd = %d\n", + lbs_deb_cmd("SEND_SLEEPC_CMD: Before download, size of cmd = %d\n", size); lbs_dbg_hex("SEND_SLEEPC_CMD: Sleep confirm command", cmdptr, size); - ret = libertas_sbi_host_to_card(priv, MVMS_CMD, cmdptr, size); - priv->wlan_dev.dnld_sent = DNLD_RES_RECEIVED; + ret = priv->hw_host_to_card(priv, MVMS_CMD, cmdptr, size); + priv->dnld_sent = DNLD_RES_RECEIVED; spin_lock_irqsave(&adapter->driver_lock, flags); if (adapter->intcounter || adapter->currenttxskb) - lbs_pr_debug(1, "SEND_SLEEPC_CMD: intcounter=%d currenttxskb=%p\n", + lbs_deb_cmd("SEND_SLEEPC_CMD: intcounter=%d currenttxskb=%p\n", adapter->intcounter, adapter->currenttxskb); spin_unlock_irqrestore(&adapter->driver_lock, flags); @@ -1860,23 +1824,22 @@ static int sendconfirmsleep(wlan_private * priv, u8 * cmdptr, u16 size) if (!adapter->intcounter) { adapter->psstate = PS_STATE_SLEEP; } else { - lbs_pr_debug(1, "SEND_SLEEPC_CMD: After sent,IntC=%d\n", + lbs_deb_cmd("SEND_SLEEPC_CMD: After sent,IntC=%d\n", adapter->intcounter); } spin_unlock_irqrestore(&adapter->driver_lock, flags); - lbs_pr_debug(1, "SEND_SLEEPC_CMD: Sent Confirm Sleep command\n"); - lbs_pr_debug(1, "+"); + lbs_deb_cmd("SEND_SLEEPC_CMD: Sent Confirm Sleep command\n"); + lbs_deb_cmd("+"); } - LEAVE(); + lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); return ret; } void libertas_ps_sleep(wlan_private * priv, int wait_option) { - - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); /* * PS is currently supported only in Infrastructure mode @@ -1886,8 +1849,7 @@ void libertas_ps_sleep(wlan_private * priv, int wait_option) libertas_prepare_and_send_command(priv, cmd_802_11_ps_mode, cmd_subcmd_enter_ps, wait_option, 0, NULL); - LEAVE(); - return; + lbs_deb_leave(LBS_DEB_CMD); } /** @@ -1899,20 +1861,19 @@ void libertas_ps_sleep(wlan_private * priv, int wait_option) */ void libertas_ps_wakeup(wlan_private * priv, int wait_option) { - enum WLAN_802_11_POWER_MODE Localpsmode; + __le32 Localpsmode; - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); - Localpsmode = wlan802_11powermodecam; + Localpsmode = cpu_to_le32(wlan802_11powermodecam); - lbs_pr_debug(1, "Exit_PS: Localpsmode = %d\n", Localpsmode); + lbs_deb_cmd("Exit_PS: Localpsmode = %d\n", wlan802_11powermodecam); libertas_prepare_and_send_command(priv, cmd_802_11_ps_mode, cmd_subcmd_exit_ps, wait_option, 0, &Localpsmode); - LEAVE(); - return; + lbs_deb_leave(LBS_DEB_CMD); } /** @@ -1929,31 +1890,31 @@ void libertas_ps_confirm_sleep(wlan_private * priv, u16 psmode) wlan_adapter *adapter = priv->adapter; u8 allowed = 1; - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); - if (priv->wlan_dev.dnld_sent) { + if (priv->dnld_sent) { allowed = 0; - lbs_pr_debug(1, "D"); + lbs_deb_cmd("D"); } spin_lock_irqsave(&adapter->driver_lock, flags); if (adapter->cur_cmd) { allowed = 0; - lbs_pr_debug(1, "C"); + lbs_deb_cmd("C"); } if (adapter->intcounter > 0) { allowed = 0; - lbs_pr_debug(1, "I%d", adapter->intcounter); + lbs_deb_cmd("I%d", adapter->intcounter); } spin_unlock_irqrestore(&adapter->driver_lock, flags); if (allowed) { - lbs_pr_debug(1, "Sending libertas_ps_confirm_sleep\n"); + lbs_deb_cmd("Sending libertas_ps_confirm_sleep\n"); sendconfirmsleep(priv, (u8 *) & adapter->libertas_ps_confirm_sleep, sizeof(struct PS_CMD_ConfirmSleep)); } else { - lbs_pr_debug(1, "Sleep Confirm has been delayed\n"); + lbs_deb_cmd("Sleep Confirm has been delayed\n"); } - LEAVE(); + lbs_deb_leave(LBS_DEB_CMD); } diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index c86454034b5..6ac0d4752fa 100644 --- a/drivers/net/wireless/libertas/cmdresp.c +++ b/drivers/net/wireless/libertas/cmdresp.c @@ -9,7 +9,6 @@ #include <net/iw_handler.h> #include "host.h" -#include "sbi.h" #include "decl.h" #include "defs.h" #include "dev.h" @@ -32,7 +31,7 @@ void libertas_mac_event_disconnected(wlan_private * priv) if (adapter->connect_status != libertas_connected) return; - lbs_pr_debug(1, "Handles disconnect event.\n"); + lbs_deb_cmd("Handles disconnect event.\n"); memset(wrqu.ap_addr.sa_data, 0x00, ETH_ALEN); wrqu.ap_addr.sa_family = ARPHRD_ETHER; @@ -43,15 +42,15 @@ void libertas_mac_event_disconnected(wlan_private * priv) */ msleep_interruptible(1000); - wireless_send_event(priv->wlan_dev.netdev, SIOCGIWAP, &wrqu, NULL); + wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL); /* Free Tx and Rx packets */ kfree_skb(priv->adapter->currenttxskb); priv->adapter->currenttxskb = NULL; /* report disconnect to upper layer */ - netif_stop_queue(priv->wlan_dev.netdev); - netif_carrier_off(priv->wlan_dev.netdev); + netif_stop_queue(priv->dev); + netif_carrier_off(priv->dev); /* reset SNR/NF/RSSI values */ memset(adapter->SNR, 0x00, sizeof(adapter->SNR)); @@ -62,35 +61,32 @@ void libertas_mac_event_disconnected(wlan_private * priv) adapter->nextSNRNF = 0; adapter->numSNRNF = 0; adapter->rxpd_rate = 0; - lbs_pr_debug(1, "Current SSID=%s, ssid length=%u\n", - adapter->curbssparams.ssid.ssid, - adapter->curbssparams.ssid.ssidlength); - lbs_pr_debug(1, "Previous SSID=%s, ssid length=%u\n", - adapter->previousssid.ssid, adapter->previousssid.ssidlength); - - /* reset internal flags */ - adapter->secinfo.WPAenabled = 0; - adapter->secinfo.WPA2enabled = 0; - adapter->wpa_ie_len = 0; + lbs_deb_cmd("Current SSID='%s', ssid length=%u\n", + escape_essid(adapter->curbssparams.ssid, + adapter->curbssparams.ssid_len), + adapter->curbssparams.ssid_len); + lbs_deb_cmd("Previous SSID='%s', ssid length=%u\n", + escape_essid(adapter->prev_ssid, adapter->prev_ssid_len), + adapter->prev_ssid_len); adapter->connect_status = libertas_disconnected; - /* - * memorize the previous SSID and BSSID - * it could be used for re-assoc - */ - memcpy(&adapter->previousssid, - &adapter->curbssparams.ssid, sizeof(struct WLAN_802_11_SSID)); - memcpy(adapter->previousbssid, - adapter->curbssparams.bssid, ETH_ALEN); + /* Save previous SSID and BSSID for possible reassociation */ + memcpy(&adapter->prev_ssid, &adapter->curbssparams.ssid, + IW_ESSID_MAX_SIZE); + adapter->prev_ssid_len = adapter->curbssparams.ssid_len; + memcpy(adapter->prev_bssid, adapter->curbssparams.bssid, ETH_ALEN); - /* need to erase the current SSID and BSSID info */ - adapter->pattemptedbssdesc = NULL; - memset(&adapter->curbssparams, 0, sizeof(adapter->curbssparams)); + /* Clear out associated SSID and BSSID since connection is + * no longer valid. + */ + memset(&adapter->curbssparams.bssid, 0, ETH_ALEN); + memset(&adapter->curbssparams.ssid, 0, IW_ESSID_MAX_SIZE); + adapter->curbssparams.ssid_len = 0; if (adapter->psstate != PS_STATE_FULL_POWER) { /* make firmware to exit PS mode */ - lbs_pr_debug(1, "Disconnected, so exit PS mode.\n"); + lbs_deb_cmd("Disconnected, so exit PS mode.\n"); libertas_ps_wakeup(priv, 0); } } @@ -122,55 +118,45 @@ static void handle_mic_failureevent(wlan_private * priv, u32 event) static int wlan_ret_reg_access(wlan_private * priv, u16 type, struct cmd_ds_command *resp) { + int ret = 0; wlan_adapter *adapter = priv->adapter; - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); switch (type) { case cmd_ret_mac_reg_access: { - struct cmd_ds_mac_reg_access *reg; + struct cmd_ds_mac_reg_access *reg = &resp->params.macreg; - reg = - (struct cmd_ds_mac_reg_access *)&resp->params. - macreg; - - adapter->offsetvalue.offset = reg->offset; - adapter->offsetvalue.value = reg->value; + adapter->offsetvalue.offset = (u32)le16_to_cpu(reg->offset); + adapter->offsetvalue.value = le32_to_cpu(reg->value); break; } case cmd_ret_bbp_reg_access: { - struct cmd_ds_bbp_reg_access *reg; - reg = - (struct cmd_ds_bbp_reg_access *)&resp->params. - bbpreg; + struct cmd_ds_bbp_reg_access *reg = &resp->params.bbpreg; - adapter->offsetvalue.offset = reg->offset; + adapter->offsetvalue.offset = (u32)le16_to_cpu(reg->offset); adapter->offsetvalue.value = reg->value; break; } case cmd_ret_rf_reg_access: { - struct cmd_ds_rf_reg_access *reg; - reg = - (struct cmd_ds_rf_reg_access *)&resp->params. - rfreg; + struct cmd_ds_rf_reg_access *reg = &resp->params.rfreg; - adapter->offsetvalue.offset = reg->offset; + adapter->offsetvalue.offset = (u32)le16_to_cpu(reg->offset); adapter->offsetvalue.value = reg->value; break; } default: - LEAVE(); - return -1; + ret = -1; } - LEAVE(); - return 0; + lbs_deb_enter_args(LBS_DEB_CMD, "ret %d", ret); + return ret; } static int wlan_ret_get_hw_spec(wlan_private * priv, @@ -181,19 +167,20 @@ static int wlan_ret_get_hw_spec(wlan_private * priv, wlan_adapter *adapter = priv->adapter; int ret = 0; - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); adapter->fwcapinfo = le32_to_cpu(hwspec->fwcapinfo); - adapter->fwreleasenumber = hwspec->fwreleasenumber; + memcpy(adapter->fwreleasenumber, hwspec->fwreleasenumber, 4); - lbs_pr_debug(1, "GET_HW_SPEC: FWReleaseVersion- 0x%X\n", - adapter->fwreleasenumber); - lbs_pr_debug(1, "GET_HW_SPEC: Permanent addr- %2x:%2x:%2x:%2x:%2x:%2x\n", + lbs_deb_cmd("GET_HW_SPEC: FWReleaseVersion- %u.%u.%u.p%u\n", + adapter->fwreleasenumber[2], adapter->fwreleasenumber[1], + adapter->fwreleasenumber[0], adapter->fwreleasenumber[3]); + lbs_deb_cmd("GET_HW_SPEC: Permanent addr- %2x:%2x:%2x:%2x:%2x:%2x\n", hwspec->permanentaddr[0], hwspec->permanentaddr[1], hwspec->permanentaddr[2], hwspec->permanentaddr[3], hwspec->permanentaddr[4], hwspec->permanentaddr[5]); - lbs_pr_debug(1, "GET_HW_SPEC: hwifversion=0x%X version=0x%X\n", + lbs_deb_cmd("GET_HW_SPEC: hwifversion=0x%X version=0x%X\n", hwspec->hwifversion, hwspec->version); adapter->regioncode = le16_to_cpu(hwspec->regioncode); @@ -210,17 +197,15 @@ static int wlan_ret_get_hw_spec(wlan_private * priv, if (i >= MRVDRV_MAX_REGION_CODE) { adapter->regioncode = 0x10; adapter->regiontableindex = 0; - lbs_pr_info( - "unidentified region code, use the default (USA)\n"); + lbs_pr_info("unidentified region code; using the default (USA)\n"); } - if (adapter->current_addr[0] == 0xff) { - memmove(adapter->current_addr, hwspec->permanentaddr, - ETH_ALEN); - } + if (adapter->current_addr[0] == 0xff) + memmove(adapter->current_addr, hwspec->permanentaddr, ETH_ALEN); - memcpy(priv->wlan_dev.netdev->dev_addr, adapter->current_addr, ETH_ALEN); - memcpy(priv->mesh_dev->dev_addr, adapter->current_addr, ETH_ALEN); + memcpy(priv->dev->dev_addr, adapter->current_addr, ETH_ALEN); + if (priv->mesh_dev) + memcpy(priv->mesh_dev->dev_addr, adapter->current_addr, ETH_ALEN); if (libertas_set_regiontable(priv, adapter->regioncode, 0)) { ret = -1; @@ -232,8 +217,8 @@ static int wlan_ret_get_hw_spec(wlan_private * priv, goto done; } - done: - LEAVE(); +done: + lbs_deb_enter_args(LBS_DEB_CMD, "ret %d", ret); return ret; } @@ -243,19 +228,21 @@ static int wlan_ret_802_11_sleep_params(wlan_private * priv, struct cmd_ds_802_11_sleep_params *sp = &resp->params.sleep_params; wlan_adapter *adapter = priv->adapter; - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); + + lbs_deb_cmd("error=%x offset=%x stabletime=%x calcontrol=%x\n" + " extsleepclk=%x\n", le16_to_cpu(sp->error), + le16_to_cpu(sp->offset), le16_to_cpu(sp->stabletime), + sp->calcontrol, sp->externalsleepclk); - lbs_pr_debug(1, "error=%x offset=%x stabletime=%x calcontrol=%x\n" - " extsleepclk=%x\n", sp->error, sp->offset, - sp->stabletime, sp->calcontrol, sp->externalsleepclk); adapter->sp.sp_error = le16_to_cpu(sp->error); adapter->sp.sp_offset = le16_to_cpu(sp->offset); adapter->sp.sp_stabletime = le16_to_cpu(sp->stabletime); - adapter->sp.sp_calcontrol = le16_to_cpu(sp->calcontrol); - adapter->sp.sp_extsleepclk = le16_to_cpu(sp->externalsleepclk); + adapter->sp.sp_calcontrol = sp->calcontrol; + adapter->sp.sp_extsleepclk = sp->externalsleepclk; adapter->sp.sp_reserved = le16_to_cpu(sp->reserved); - LEAVE(); + lbs_deb_enter(LBS_DEB_CMD); return 0; } @@ -281,42 +268,38 @@ static int wlan_ret_802_11_snmp_mib(wlan_private * priv, u16 oid = le16_to_cpu(smib->oid); u16 querytype = le16_to_cpu(smib->querytype); - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); - lbs_pr_debug(1, "SNMP_RESP: value of the oid = %x, querytype=%x\n", oid, + lbs_deb_cmd("SNMP_RESP: value of the oid = %x, querytype=%x\n", oid, querytype); - lbs_pr_debug(1, "SNMP_RESP: Buf size = %x\n", - le16_to_cpu(smib->bufsize)); + lbs_deb_cmd("SNMP_RESP: Buf size = %x\n", le16_to_cpu(smib->bufsize)); if (querytype == cmd_act_get) { switch (oid) { case fragthresh_i: priv->adapter->fragthsd = - le16_to_cpu(* - ((unsigned short *)(smib->value))); - lbs_pr_debug(1, "SNMP_RESP: fragthsd =%u\n", - priv->adapter->fragthsd); + le16_to_cpu(*((__le16 *)(smib->value))); + lbs_deb_cmd("SNMP_RESP: fragthsd =%u\n", + priv->adapter->fragthsd); break; case rtsthresh_i: priv->adapter->rtsthsd = - le16_to_cpu(* - ((unsigned short *)(smib->value))); - lbs_pr_debug(1, "SNMP_RESP: rtsthsd =%u\n", - priv->adapter->rtsthsd); + le16_to_cpu(*((__le16 *)(smib->value))); + lbs_deb_cmd("SNMP_RESP: rtsthsd =%u\n", + priv->adapter->rtsthsd); break; case short_retrylim_i: priv->adapter->txretrycount = - le16_to_cpu(* - ((unsigned short *)(smib->value))); - lbs_pr_debug(1, "SNMP_RESP: txretrycount =%u\n", - priv->adapter->rtsthsd); + le16_to_cpu(*((__le16 *)(smib->value))); + lbs_deb_cmd("SNMP_RESP: txretrycount =%u\n", + priv->adapter->rtsthsd); break; default: break; } } - LEAVE(); + lbs_deb_enter(LBS_DEB_CMD); return 0; } @@ -328,7 +311,7 @@ static int wlan_ret_802_11_key_material(wlan_private * priv, wlan_adapter *adapter = priv->adapter; u16 action = le16_to_cpu(pkeymaterial->action); - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); /* Copy the returned key to driver private data */ if (action == cmd_act_get) { @@ -371,7 +354,7 @@ static int wlan_ret_802_11_key_material(wlan_private * priv, } } - LEAVE(); + lbs_deb_enter(LBS_DEB_CMD); return 0; } @@ -381,11 +364,11 @@ static int wlan_ret_802_11_mac_address(wlan_private * priv, struct cmd_ds_802_11_mac_address *macadd = &resp->params.macadd; wlan_adapter *adapter = priv->adapter; - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); memcpy(adapter->current_addr, macadd->macadd, ETH_ALEN); - LEAVE(); + lbs_deb_enter(LBS_DEB_CMD); return 0; } @@ -395,13 +378,13 @@ static int wlan_ret_802_11_rf_tx_power(wlan_private * priv, struct cmd_ds_802_11_rf_tx_power *rtp = &resp->params.txp; wlan_adapter *adapter = priv->adapter; - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); adapter->txpowerlevel = le16_to_cpu(rtp->currentlevel); - lbs_pr_debug(1, "Current TxPower Level = %d\n", adapter->txpowerlevel); + lbs_deb_cmd("Current TxPower Level = %d\n", adapter->txpowerlevel); - LEAVE(); + lbs_deb_enter(LBS_DEB_CMD); return 0; } @@ -413,14 +396,12 @@ static int wlan_ret_802_11_rf_antenna(wlan_private * priv, u16 action = le16_to_cpu(pAntenna->action); if (action == cmd_act_get_rx) - adapter->rxantennamode = - le16_to_cpu(pAntenna->antennamode); + adapter->rxantennamode = le16_to_cpu(pAntenna->antennamode); if (action == cmd_act_get_tx) - adapter->txantennamode = - le16_to_cpu(pAntenna->antennamode); + adapter->txantennamode = le16_to_cpu(pAntenna->antennamode); - lbs_pr_debug(1, "RF_ANT_RESP: action = 0x%x, mode = 0x%04x\n", + lbs_deb_cmd("RF_ANT_RESP: action = 0x%x, mode = 0x%04x\n", action, le16_to_cpu(pAntenna->antennamode)); return 0; @@ -429,19 +410,17 @@ static int wlan_ret_802_11_rf_antenna(wlan_private * priv, static int wlan_ret_802_11_rate_adapt_rateset(wlan_private * priv, struct cmd_ds_command *resp) { - struct cmd_ds_802_11_rate_adapt_rateset *rates = - &resp->params.rateset; + struct cmd_ds_802_11_rate_adapt_rateset *rates = &resp->params.rateset; wlan_adapter *adapter = priv->adapter; - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); if (rates->action == cmd_act_get) { - adapter->enablehwauto = rates->enablehwauto; - adapter->ratebitmap = rates->bitmap; + adapter->enablehwauto = le16_to_cpu(rates->enablehwauto); + adapter->ratebitmap = le16_to_cpu(rates->bitmap); } - LEAVE(); - + lbs_deb_enter(LBS_DEB_CMD); return 0; } @@ -452,43 +431,42 @@ static int wlan_ret_802_11_data_rate(wlan_private * priv, wlan_adapter *adapter = priv->adapter; u8 dot11datarate; - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); lbs_dbg_hex("DATA_RATE_RESP: data_rate- ", (u8 *) pdatarate, sizeof(struct cmd_ds_802_11_data_rate)); dot11datarate = pdatarate->datarate[0]; - if (pdatarate->action == cmd_act_get_tx_rate) { + if (pdatarate->action == cpu_to_le16(cmd_act_get_tx_rate)) { memcpy(adapter->libertas_supported_rates, pdatarate->datarate, sizeof(adapter->libertas_supported_rates)); } adapter->datarate = libertas_index_to_data_rate(dot11datarate); - LEAVE(); + lbs_deb_enter(LBS_DEB_CMD); return 0; } static int wlan_ret_802_11_rf_channel(wlan_private * priv, struct cmd_ds_command *resp) { - struct cmd_ds_802_11_rf_channel *rfchannel = - &resp->params.rfchannel; + struct cmd_ds_802_11_rf_channel *rfchannel = &resp->params.rfchannel; wlan_adapter *adapter = priv->adapter; u16 action = le16_to_cpu(rfchannel->action); u16 newchannel = le16_to_cpu(rfchannel->currentchannel); - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); if (action == cmd_opt_802_11_rf_channel_get && adapter->curbssparams.channel != newchannel) { - lbs_pr_debug(1, "channel Switch: %d to %d\n", + lbs_deb_cmd("channel Switch: %d to %d\n", adapter->curbssparams.channel, newchannel); /* Update the channel again */ adapter->curbssparams.channel = newchannel; } - LEAVE(); + lbs_deb_enter(LBS_DEB_CMD); return 0; } @@ -500,12 +478,10 @@ static int wlan_ret_802_11_rssi(wlan_private * priv, /* store the non average value */ adapter->SNR[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->SNR); - adapter->NF[TYPE_BEACON][TYPE_NOAVG] = - le16_to_cpu(rssirsp->noisefloor); + adapter->NF[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->noisefloor); adapter->SNR[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgSNR); - adapter->NF[TYPE_BEACON][TYPE_AVG] = - le16_to_cpu(rssirsp->avgnoisefloor); + adapter->NF[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgnoisefloor); adapter->RSSI[TYPE_BEACON][TYPE_NOAVG] = CAL_RSSI(adapter->SNR[TYPE_BEACON][TYPE_NOAVG], @@ -515,7 +491,7 @@ static int wlan_ret_802_11_rssi(wlan_private * priv, CAL_RSSI(adapter->SNR[TYPE_BEACON][TYPE_AVG] / AVG_SCALE, adapter->NF[TYPE_BEACON][TYPE_AVG] / AVG_SCALE); - lbs_pr_debug(1, "Beacon RSSI value = 0x%x\n", + lbs_deb_cmd("Beacon RSSI value = 0x%x\n", adapter->RSSI[TYPE_BEACON][TYPE_AVG]); return 0; @@ -528,11 +504,11 @@ static int wlan_ret_802_11_eeprom_access(wlan_private * priv, struct wlan_ioctl_regrdwr *pbuf; pbuf = (struct wlan_ioctl_regrdwr *) adapter->prdeeprom; - lbs_pr_debug(1, "eeprom read len=%x\n", + lbs_deb_cmd("eeprom read len=%x\n", le16_to_cpu(resp->params.rdeeprom.bytecount)); if (pbuf->NOB < le16_to_cpu(resp->params.rdeeprom.bytecount)) { pbuf->NOB = 0; - lbs_pr_debug(1, "eeprom read return length is too big\n"); + lbs_deb_cmd("eeprom read return length is too big\n"); return -1; } pbuf->NOB = le16_to_cpu(resp->params.rdeeprom.bytecount); @@ -549,17 +525,33 @@ static int wlan_ret_802_11_eeprom_access(wlan_private * priv, static int wlan_ret_get_log(wlan_private * priv, struct cmd_ds_command *resp) { - struct cmd_ds_802_11_get_log *logmessage = - (struct cmd_ds_802_11_get_log *)&resp->params.glog; + struct cmd_ds_802_11_get_log *logmessage = &resp->params.glog; wlan_adapter *adapter = priv->adapter; - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); - /* TODO Convert it to Big Endian before copy */ - memcpy(&adapter->logmsg, logmessage, - sizeof(struct cmd_ds_802_11_get_log)); + /* Stored little-endian */ + memcpy(&adapter->logmsg, logmessage, sizeof(struct cmd_ds_802_11_get_log)); - LEAVE(); + lbs_deb_enter(LBS_DEB_CMD); + return 0; +} + +static int libertas_ret_802_11_enable_rsn(wlan_private * priv, + struct cmd_ds_command *resp) +{ + struct cmd_ds_802_11_enable_rsn *enable_rsn = &resp->params.enbrsn; + wlan_adapter *adapter = priv->adapter; + u32 * pdata_buf = adapter->cur_cmd->pdata_buf; + + lbs_deb_enter(LBS_DEB_CMD); + + if (enable_rsn->action == cpu_to_le16(cmd_act_get)) { + if (pdata_buf) + *pdata_buf = (u32) le16_to_cpu(enable_rsn->enable); + } + + lbs_deb_enter(LBS_DEB_CMD); return 0; } @@ -620,8 +612,7 @@ static inline int handle_cmd_response(u16 respcmd, case cmd_ret_802_11_set_afc: case cmd_ret_802_11_get_afc: spin_lock_irqsave(&adapter->driver_lock, flags); - memmove(adapter->cur_cmd->pdata_buf, - &resp->params.afc, + memmove(adapter->cur_cmd->pdata_buf, &resp->params.afc, sizeof(struct cmd_ds_802_11_afc)); spin_unlock_irqrestore(&adapter->driver_lock, flags); @@ -637,7 +628,10 @@ static inline int handle_cmd_response(u16 respcmd, case cmd_ret_802_11_authenticate: case cmd_ret_802_11_radio_control: case cmd_ret_802_11_beacon_stop: + break; + case cmd_ret_802_11_enable_rsn: + ret = libertas_ret_802_11_enable_rsn(priv, resp); break; case cmd_ret_802_11_data_rate: @@ -663,7 +657,7 @@ static inline int handle_cmd_response(u16 respcmd, break; case cmd_ret_802_11_key_material: - lbs_pr_debug(1, "CMD_RESP: KEY_MATERIAL command response\n"); + lbs_deb_cmd("CMD_RESP: KEY_MATERIAL command response\n"); ret = wlan_ret_802_11_key_material(priv, resp); break; @@ -687,22 +681,19 @@ static inline int handle_cmd_response(u16 respcmd, case cmd_ret_802_11_tpc_cfg: spin_lock_irqsave(&adapter->driver_lock, flags); - memmove(adapter->cur_cmd->pdata_buf, - &resp->params.tpccfg, + memmove(adapter->cur_cmd->pdata_buf, &resp->params.tpccfg, sizeof(struct cmd_ds_802_11_tpc_cfg)); spin_unlock_irqrestore(&adapter->driver_lock, flags); break; case cmd_ret_802_11_led_gpio_ctrl: spin_lock_irqsave(&adapter->driver_lock, flags); - memmove(adapter->cur_cmd->pdata_buf, - &resp->params.ledgpio, + memmove(adapter->cur_cmd->pdata_buf, &resp->params.ledgpio, sizeof(struct cmd_ds_802_11_led_ctrl)); spin_unlock_irqrestore(&adapter->driver_lock, flags); break; case cmd_ret_802_11_pwr_cfg: spin_lock_irqsave(&adapter->driver_lock, flags); - memmove(adapter->cur_cmd->pdata_buf, - &resp->params.pwrcfg, + memmove(adapter->cur_cmd->pdata_buf, &resp->params.pwrcfg, sizeof(struct cmd_ds_802_11_pwr_cfg)); spin_unlock_irqrestore(&adapter->driver_lock, flags); @@ -724,23 +715,21 @@ static inline int handle_cmd_response(u16 respcmd, case cmd_ret_fwt_access: spin_lock_irqsave(&adapter->driver_lock, flags); if (adapter->cur_cmd->pdata_buf) - memcpy(adapter->cur_cmd->pdata_buf, - &resp->params.fwt, - sizeof(resp->params.fwt)); + memcpy(adapter->cur_cmd->pdata_buf, &resp->params.fwt, + sizeof(resp->params.fwt)); spin_unlock_irqrestore(&adapter->driver_lock, flags); break; case cmd_ret_mesh_access: if (adapter->cur_cmd->pdata_buf) - memcpy(adapter->cur_cmd->pdata_buf, - &resp->params.mesh, + memcpy(adapter->cur_cmd->pdata_buf, &resp->params.mesh, sizeof(resp->params.mesh)); break; case cmd_rte_802_11_tx_rate_query: priv->adapter->txrate = resp->params.txrate.txrate; break; default: - lbs_pr_debug(1, "CMD_RESP: Unknown command response %#x\n", - resp->command); + lbs_deb_cmd("CMD_RESP: Unknown command response %#x\n", + resp->command); break; } return ret; @@ -755,9 +744,9 @@ int libertas_process_rx_command(wlan_private * priv) ulong flags; u16 result; - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); - lbs_pr_debug(1, "CMD_RESP: @ %lu\n", jiffies); + lbs_deb_cmd("CMD_RESP: @ %lu\n", jiffies); /* Now we got response from FW, cancel the command timer */ del_timer(&adapter->command_timer); @@ -766,7 +755,7 @@ int libertas_process_rx_command(wlan_private * priv) spin_lock_irqsave(&adapter->driver_lock, flags); if (!adapter->cur_cmd) { - lbs_pr_debug(1, "CMD_RESP: NULL cur_cmd=%p\n", adapter->cur_cmd); + lbs_deb_cmd("CMD_RESP: NULL cur_cmd=%p\n", adapter->cur_cmd); ret = -1; spin_unlock_irqrestore(&adapter->driver_lock, flags); goto done; @@ -774,17 +763,17 @@ int libertas_process_rx_command(wlan_private * priv) resp = (struct cmd_ds_command *)(adapter->cur_cmd->bufvirtualaddr); lbs_dbg_hex("CMD_RESP:", adapter->cur_cmd->bufvirtualaddr, - priv->wlan_dev.upld_len); + priv->upld_len); respcmd = le16_to_cpu(resp->command); result = le16_to_cpu(resp->result); - lbs_pr_debug(1, "CMD_RESP: %x result: %d length: %d\n", respcmd, - result, priv->wlan_dev.upld_len); + lbs_deb_cmd("CMD_RESP: %x result: %d length: %d\n", respcmd, + result, priv->upld_len); if (!(respcmd & 0x8000)) { - lbs_pr_debug(1, "Invalid response to command!"); + lbs_deb_cmd("Invalid response to command!"); adapter->cur_cmd_retcode = -1; __libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd); adapter->nr_cmd_pending--; @@ -795,56 +784,52 @@ int libertas_process_rx_command(wlan_private * priv) } /* Store the response code to cur_cmd_retcode. */ - adapter->cur_cmd_retcode = le16_to_cpu(resp->result); + adapter->cur_cmd_retcode = result;; if (respcmd == cmd_ret_802_11_ps_mode) { - struct cmd_ds_802_11_ps_mode *psmode; + struct cmd_ds_802_11_ps_mode *psmode = &resp->params.psmode; + u16 action = le16_to_cpu(psmode->action); - psmode = &resp->params.psmode; - lbs_pr_debug(1, + lbs_deb_cmd( "CMD_RESP: PS_MODE cmd reply result=%#x action=0x%X\n", - resp->result, psmode->action); - psmode->action = cpu_to_le16(psmode->action); + result, action); if (result) { - lbs_pr_debug(1, "CMD_RESP: PS command failed- %#x \n", - resp->result); - if (adapter->mode == IW_MODE_ADHOC) { - /* - * We should not re-try enter-ps command in - * ad-hoc mode. It takes place in - * libertas_execute_next_command(). - */ - if (psmode->action == cmd_subcmd_enter_ps) - adapter->psmode = - wlan802_11powermodecam; - } - } else if (psmode->action == cmd_subcmd_enter_ps) { + lbs_deb_cmd("CMD_RESP: PS command failed- %#x \n", + result); + /* + * We should not re-try enter-ps command in + * ad-hoc mode. It takes place in + * libertas_execute_next_command(). + */ + if (adapter->mode == IW_MODE_ADHOC && + action == cmd_subcmd_enter_ps) + adapter->psmode = wlan802_11powermodecam; + } else if (action == cmd_subcmd_enter_ps) { adapter->needtowakeup = 0; adapter->psstate = PS_STATE_AWAKE; - lbs_pr_debug(1, "CMD_RESP: Enter_PS command response\n"); + lbs_deb_cmd("CMD_RESP: Enter_PS command response\n"); if (adapter->connect_status != libertas_connected) { /* * When Deauth Event received before Enter_PS command * response, We need to wake up the firmware. */ - lbs_pr_debug(1, + lbs_deb_cmd( "Disconnected, Going to invoke libertas_ps_wakeup\n"); - mutex_unlock(&adapter->lock); spin_unlock_irqrestore(&adapter->driver_lock, flags); + mutex_unlock(&adapter->lock); libertas_ps_wakeup(priv, 0); mutex_lock(&adapter->lock); spin_lock_irqsave(&adapter->driver_lock, flags); } - } else if (psmode->action == cmd_subcmd_exit_ps) { + } else if (action == cmd_subcmd_exit_ps) { adapter->needtowakeup = 0; adapter->psstate = PS_STATE_FULL_POWER; - lbs_pr_debug(1, "CMD_RESP: Exit_PS command response\n"); + lbs_deb_cmd("CMD_RESP: Exit_PS command response\n"); } else { - lbs_pr_debug(1, "CMD_RESP: PS- action=0x%X\n", - psmode->action); + lbs_deb_cmd("CMD_RESP: PS- action=0x%X\n", action); } __libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd); @@ -865,15 +850,15 @@ int libertas_process_rx_command(wlan_private * priv) /* If the command is not successful, cleanup and return failure */ if ((result != 0 || !(respcmd & 0x8000))) { - lbs_pr_debug(1, "CMD_RESP: command reply %#x result=%#x\n", - resp->command, resp->result); + lbs_deb_cmd("CMD_RESP: command reply %#x result=%#x\n", + respcmd, result); /* * Handling errors here */ switch (respcmd) { case cmd_ret_hw_spec_info: case cmd_ret_802_11_reset: - lbs_pr_debug(1, "CMD_RESP: Reset command failed\n"); + lbs_deb_cmd("CMD_RESP: Reset command failed\n"); break; } @@ -903,7 +888,7 @@ int libertas_process_rx_command(wlan_private * priv) done: mutex_unlock(&adapter->lock); - LEAVE(); + lbs_deb_enter_args(LBS_DEB_CMD, "ret %d", ret); return ret; } @@ -917,37 +902,37 @@ int libertas_process_event(wlan_private * priv) eventcause = adapter->eventcause; spin_unlock_irq(&adapter->driver_lock); - ENTER(); + lbs_deb_enter(LBS_DEB_CMD); - lbs_pr_debug(1, "EVENT Cause %x\n", eventcause); + lbs_deb_cmd("EVENT Cause %x\n", eventcause); switch (eventcause >> SBI_EVENT_CAUSE_SHIFT) { case MACREG_INT_CODE_LINK_SENSED: - lbs_pr_debug(1, "EVENT: MACREG_INT_CODE_LINK_SENSED\n"); + lbs_deb_cmd("EVENT: MACREG_INT_CODE_LINK_SENSED\n"); break; case MACREG_INT_CODE_DEAUTHENTICATED: - lbs_pr_debug(1, "EVENT: Deauthenticated\n"); + lbs_deb_cmd("EVENT: Deauthenticated\n"); libertas_mac_event_disconnected(priv); break; case MACREG_INT_CODE_DISASSOCIATED: - lbs_pr_debug(1, "EVENT: Disassociated\n"); + lbs_deb_cmd("EVENT: Disassociated\n"); libertas_mac_event_disconnected(priv); break; case MACREG_INT_CODE_LINK_LOSE_NO_SCAN: - lbs_pr_debug(1, "EVENT: Link lost\n"); + lbs_deb_cmd("EVENT: Link lost\n"); libertas_mac_event_disconnected(priv); break; case MACREG_INT_CODE_PS_SLEEP: - lbs_pr_debug(1, "EVENT: SLEEP\n"); - lbs_pr_debug(1, "_"); + lbs_deb_cmd("EVENT: SLEEP\n"); + lbs_deb_cmd("_"); /* handle unexpected PS SLEEP event */ if (adapter->psstate == PS_STATE_FULL_POWER) { - lbs_pr_debug(1, + lbs_deb_cmd( "EVENT: In FULL POWER mode - ignore PS SLEEP\n"); break; } @@ -958,12 +943,12 @@ int libertas_process_event(wlan_private * priv) break; case MACREG_INT_CODE_PS_AWAKE: - lbs_pr_debug(1, "EVENT: AWAKE \n"); - lbs_pr_debug(1, "|"); + lbs_deb_cmd("EVENT: AWAKE \n"); + lbs_deb_cmd("|"); /* handle unexpected PS AWAKE event */ if (adapter->psstate == PS_STATE_FULL_POWER) { - lbs_pr_debug(1, + lbs_deb_cmd( "EVENT: In FULL POWER mode - ignore PS AWAKE\n"); break; } @@ -977,18 +962,18 @@ int libertas_process_event(wlan_private * priv) * adapter->needtowakeup will be set to FALSE * in libertas_ps_wakeup() */ - lbs_pr_debug(1, "Waking up...\n"); + lbs_deb_cmd("Waking up...\n"); libertas_ps_wakeup(priv, 0); } break; case MACREG_INT_CODE_MIC_ERR_UNICAST: - lbs_pr_debug(1, "EVENT: UNICAST MIC ERROR\n"); + lbs_deb_cmd("EVENT: UNICAST MIC ERROR\n"); handle_mic_failureevent(priv, MACREG_INT_CODE_MIC_ERR_UNICAST); break; case MACREG_INT_CODE_MIC_ERR_MULTICAST: - lbs_pr_debug(1, "EVENT: MULTICAST MIC ERROR\n"); + lbs_deb_cmd("EVENT: MULTICAST MIC ERROR\n"); handle_mic_failureevent(priv, MACREG_INT_CODE_MIC_ERR_MULTICAST); break; case MACREG_INT_CODE_MIB_CHANGED: @@ -996,7 +981,7 @@ int libertas_process_event(wlan_private * priv) break; case MACREG_INT_CODE_ADHOC_BCN_LOST: - lbs_pr_debug(1, "EVENT: HWAC - ADHOC BCN LOST\n"); + lbs_deb_cmd("EVENT: HWAC - ADHOC BCN LOST\n"); break; case MACREG_INT_CODE_RSSI_LOW: @@ -1015,6 +1000,17 @@ int libertas_process_event(wlan_private * priv) lbs_pr_alert( "EVENT: SNR_HIGH\n"); break; + case MACREG_INT_CODE_MESH_AUTO_STARTED: + lbs_pr_alert( "EVENT: MESH_AUTO_STARTED\n"); + adapter->connect_status = libertas_connected ; + if (priv->mesh_open == 1) { + netif_wake_queue(priv->mesh_dev) ; + netif_carrier_on(priv->mesh_dev) ; + } + adapter->mode = IW_MODE_ADHOC ; + schedule_work(&priv->sync_channel); + break; + default: lbs_pr_alert( "EVENT: unknown event id: %#x\n", eventcause >> SBI_EVENT_CAUSE_SHIFT); @@ -1024,6 +1020,7 @@ int libertas_process_event(wlan_private * priv) spin_lock_irq(&adapter->driver_lock); adapter->eventcause = 0; spin_unlock_irq(&adapter->driver_lock); - LEAVE(); + + lbs_deb_enter_args(LBS_DEB_CMD, "ret %d", ret); return ret; } diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c index 7d7bc5e86a5..715cbdaa1d4 100644 --- a/drivers/net/wireless/libertas/debugfs.c +++ b/drivers/net/wireless/libertas/debugfs.c @@ -4,6 +4,7 @@ #include <linux/delay.h> #include <linux/mm.h> #include <net/iw_handler.h> + #include "dev.h" #include "decl.h" #include "host.h" @@ -15,7 +16,9 @@ static char *szStates[] = { "Disconnected" }; -void libertas_debug_init(wlan_private * priv, struct net_device *dev); +#ifdef PROC_DEBUG +static void libertas_debug_init(wlan_private * priv, struct net_device *dev); +#endif static int open_file_generic(struct inode *inode, struct file *file) { @@ -60,43 +63,33 @@ static ssize_t libertas_getscantable(struct file *file, char __user *userbuf, int numscansdone = 0, res; unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf = (char *)addr; + struct bss_descriptor * iter_bss; pos += snprintf(buf+pos, len-pos, - "---------------------------------------"); - pos += snprintf(buf+pos, len-pos, - "---------------------------------------\n"); - pos += snprintf(buf+pos, len-pos, "# | ch | ss | bssid | cap | TSF | Qual | SSID \n"); - pos += snprintf(buf+pos, len-pos, - "---------------------------------------"); - pos += snprintf(buf+pos, len-pos, - "---------------------------------------\n"); - while (numscansdone < priv->adapter->numinscantable) { - struct bss_descriptor *pbssinfo; + mutex_lock(&priv->adapter->lock); + list_for_each_entry (iter_bss, &priv->adapter->network_list, list) { u16 cap; - pbssinfo = &priv->adapter->scantable[numscansdone]; - memcpy(&cap, &pbssinfo->cap, sizeof(cap)); + memcpy(&cap, &iter_bss->cap, sizeof(cap)); pos += snprintf(buf+pos, len-pos, - "%02u| %03d | %03ld | %02x:%02x:%02x:%02x:%02x:%02x |", - numscansdone, pbssinfo->channel, pbssinfo->rssi, - pbssinfo->macaddress[0], pbssinfo->macaddress[1], - pbssinfo->macaddress[2], pbssinfo->macaddress[3], - pbssinfo->macaddress[4], pbssinfo->macaddress[5]); + "%02u| %03d | %03ld | " MAC_FMT " |", + numscansdone, iter_bss->channel, iter_bss->rssi, + MAC_ARG(iter_bss->bssid)); pos += snprintf(buf+pos, len-pos, " %04x-", cap); pos += snprintf(buf+pos, len-pos, "%c%c%c |", - pbssinfo->cap.ibss ? 'A' : 'I', - pbssinfo->cap.privacy ? 'P' : ' ', - pbssinfo->cap.spectrummgmt ? 'S' : ' '); - pos += snprintf(buf+pos, len-pos, " %08llx |", pbssinfo->networktsf); - pos += snprintf(buf+pos, len-pos, " %d |", - SCAN_RSSI(priv->adapter->scantable[numscansdone].rssi)); - - pos += snprintf(buf+pos, len-pos, " %s\n", pbssinfo->ssid.ssid); + iter_bss->cap.ibss ? 'A' : 'I', + iter_bss->cap.privacy ? 'P' : ' ', + iter_bss->cap.spectrummgmt ? 'S' : ' '); + pos += snprintf(buf+pos, len-pos, " %08llx |", iter_bss->networktsf); + pos += snprintf(buf+pos, len-pos, " %d |", SCAN_RSSI(iter_bss->rssi)); + pos += snprintf(buf+pos, len-pos, " %s\n", + escape_essid(iter_bss->ssid, iter_bss->ssid_len)); numscansdone++; } + mutex_unlock(&priv->adapter->lock); res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); @@ -111,7 +104,6 @@ static ssize_t libertas_sleepparams_write(struct file *file, wlan_private *priv = file->private_data; ssize_t buf_size, res; int p1, p2, p3, p4, p5, p6; - struct sleep_params sp; unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf = (char *)addr; @@ -125,14 +117,12 @@ static ssize_t libertas_sleepparams_write(struct file *file, res = -EFAULT; goto out_unlock; } - sp.sp_error = p1; - sp.sp_offset = p2; - sp.sp_stabletime = p3; - sp.sp_calcontrol = p4; - sp.sp_extsleepclk = p5; - sp.sp_reserved = p6; - - memcpy(&priv->adapter->sp, &sp, sizeof(struct sleep_params)); + priv->adapter->sp.sp_error = p1; + priv->adapter->sp.sp_offset = p2; + priv->adapter->sp.sp_stabletime = p3; + priv->adapter->sp.sp_calcontrol = p4; + priv->adapter->sp.sp_extsleepclk = p5; + priv->adapter->sp.sp_reserved = p6; res = libertas_prepare_and_send_command(priv, cmd_802_11_sleep_params, @@ -185,7 +175,6 @@ static ssize_t libertas_extscan(struct file *file, const char __user *userbuf, { wlan_private *priv = file->private_data; ssize_t res, buf_size; - struct WLAN_802_11_SSID extscan_ssid; union iwreq_data wrqu; unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf = (char *)addr; @@ -196,13 +185,10 @@ static ssize_t libertas_extscan(struct file *file, const char __user *userbuf, goto out_unlock; } - memcpy(&extscan_ssid.ssid, buf, strlen(buf)-1); - extscan_ssid.ssidlength = strlen(buf)-1; - - libertas_send_specific_SSID_scan(priv, &extscan_ssid, 1); + libertas_send_specific_ssid_scan(priv, buf, strlen(buf)-1, 0); memset(&wrqu, 0, sizeof(union iwreq_data)); - wireless_send_event(priv->wlan_dev.netdev, SIOCGIWSCAN, &wrqu, NULL); + wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL); out_unlock: free_page(addr); @@ -251,16 +237,13 @@ static void libertas_parse_bssid(char *buf, size_t count, { char *hold; unsigned int mac[ETH_ALEN]; - int i; hold = strstr(buf, "bssid="); if (!hold) return; hold += 6; - sscanf(hold, "%2x:%2x:%2x:%2x:%2x:%2x", mac, mac+1, mac+2, mac+3, - mac+4, mac+5); - for(i=0;i<ETH_ALEN;i++) - scan_cfg->specificBSSID[i] = mac[i]; + sscanf(hold, MAC_FMT, mac, mac+1, mac+2, mac+3, mac+4, mac+5); + memcpy(scan_cfg->bssid, mac, ETH_ALEN); } static void libertas_parse_ssid(char *buf, size_t count, @@ -278,28 +261,26 @@ static void libertas_parse_ssid(char *buf, size_t count, end = buf + count - 1; size = min((size_t)IW_ESSID_MAX_SIZE, (size_t) (end - hold)); - strncpy(scan_cfg->specificSSID, hold, size); + strncpy(scan_cfg->ssid, hold, size); return; } -static void libertas_parse_keep(char *buf, size_t count, - struct wlan_ioctl_user_scan_cfg *scan_cfg) +static int libertas_parse_clear(char *buf, size_t count, const char *tag) { char *hold; int val; - hold = strstr(buf, "keep="); + hold = strstr(buf, tag); if (!hold) - return; - hold += 5; + return 0; + hold += strlen(tag); sscanf(hold, "%d", &val); if (val != 0) val = 1; - scan_cfg->keeppreviousscan = val; - return; + return val; } static int libertas_parse_dur(char *buf, size_t count, @@ -382,17 +363,18 @@ static ssize_t libertas_setuserscan(struct file *file, dur = libertas_parse_dur(buf, count, scan_cfg); libertas_parse_chan(buf, count, scan_cfg, dur); libertas_parse_bssid(buf, count, scan_cfg); + scan_cfg->clear_bssid = libertas_parse_clear(buf, count, "clear_bssid="); libertas_parse_ssid(buf, count, scan_cfg); - libertas_parse_keep(buf, count, scan_cfg); + scan_cfg->clear_ssid = libertas_parse_clear(buf, count, "clear_ssid="); libertas_parse_probes(buf, count, scan_cfg); libertas_parse_type(buf, count, scan_cfg); - wlan_scan_networks(priv, scan_cfg); + wlan_scan_networks(priv, scan_cfg, 1); wait_event_interruptible(priv->adapter->cmd_pending, !priv->adapter->nr_cmd_pending); memset(&wrqu, 0x00, sizeof(union iwreq_data)); - wireless_send_event(priv->wlan_dev.netdev, SIOCGIWSCAN, &wrqu, NULL); + wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL); out_unlock: free_page(addr); @@ -407,11 +389,11 @@ static int libertas_event_initcmd(wlan_private *priv, void **response_buf, u16 wait_option = cmd_option_waitforrsp; if (!(*cmdnode = libertas_get_free_cmd_ctrl_node(priv))) { - lbs_pr_debug(1, "failed libertas_get_free_cmd_ctrl_node\n"); + lbs_deb_debugfs("failed libertas_get_free_cmd_ctrl_node\n"); return -ENOMEM; } if (!(*response_buf = kmalloc(3000, GFP_KERNEL))) { - lbs_pr_debug(1, "failed to allocate response buffer!\n"); + lbs_deb_debugfs("failed to allocate response buffer!\n"); return -ENOMEM; } libertas_set_cmd_ctrl_node(priv, *cmdnode, 0, wait_option, NULL); @@ -420,8 +402,8 @@ static int libertas_event_initcmd(wlan_private *priv, void **response_buf, (*cmdnode)->cmdflags |= CMD_F_HOSTCMD; (*cmdnode)->cmdwaitqwoken = 0; *cmd = (struct cmd_ds_command *)(*cmdnode)->bufvirtualaddr; - (*cmd)->command = cmd_802_11_subscribe_event; - (*cmd)->seqnum = ++priv->adapter->seqnum; + (*cmd)->command = cpu_to_le16(cmd_802_11_subscribe_event); + (*cmd)->seqnum = cpu_to_le16(++priv->adapter->seqnum); (*cmd)->result = 0; return 0; } @@ -447,26 +429,25 @@ static ssize_t libertas_lowrssi_read(struct file *file, char __user *userbuf, } event = &pcmdptr->params.subscribe_event; - event->action = cmd_act_get; - pcmdptr->size = - cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN); + event->action = cpu_to_le16(cmd_act_get); + pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN); libertas_queue_cmd(adapter, pcmdnode, 1); wake_up_interruptible(&priv->mainthread.waitq); /* Sleep until response is generated by FW */ wait_event_interruptible(pcmdnode->cmdwait_q, - pcmdnode->cmdwaitqwoken); + pcmdnode->cmdwaitqwoken); pcmdptr = response_buf; if (pcmdptr->result) { - lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__, - pcmdptr->result); + lbs_pr_err("%s: fail, result=%d\n", __func__, + le16_to_cpu(pcmdptr->result)); kfree(response_buf); free_page(addr); return 0; } - if (pcmdptr->command != cmd_ret_802_11_subscribe_event) { + if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) { lbs_pr_err("command response incorrect!\n"); kfree(response_buf); free_page(addr); @@ -474,17 +455,17 @@ static ssize_t libertas_lowrssi_read(struct file *file, char __user *userbuf, } cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event); - event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN); - while (cmd_len < pcmdptr->size) { - struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len); - switch(header->type) { + event = (void *)(response_buf + S_DS_GEN); + while (cmd_len < le16_to_cpu(pcmdptr->size)) { + struct mrvlietypesheader *header = (void *)(response_buf + cmd_len); + switch (header->type) { struct mrvlietypes_rssithreshold *Lowrssi; - case TLV_TYPE_RSSI_LOW: - Lowrssi = (struct mrvlietypes_rssithreshold *)(response_buf + cmd_len); - pos += snprintf(buf+pos, len-pos, "%d %d %d\n", - Lowrssi->rssivalue, - Lowrssi->rssifreq, - (event->events & 0x0001)?1:0); + case __constant_cpu_to_le16(TLV_TYPE_RSSI_LOW): + Lowrssi = (void *)(response_buf + cmd_len); + pos += snprintf(buf+pos, len-pos, "%d %d %d\n", + Lowrssi->rssivalue, + Lowrssi->rssifreq, + (event->events & cpu_to_le16(0x0001))?1:0); default: cmd_len += sizeof(struct mrvlietypes_snrthreshold); break; @@ -512,21 +493,20 @@ static u16 libertas_get_events_bitmap(wlan_private *priv) return res; event = &pcmdptr->params.subscribe_event; - event->action = cmd_act_get; - pcmdptr->size = - cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN); + event->action = cpu_to_le16(cmd_act_get); + pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN); libertas_queue_cmd(adapter, pcmdnode, 1); wake_up_interruptible(&priv->mainthread.waitq); /* Sleep until response is generated by FW */ wait_event_interruptible(pcmdnode->cmdwait_q, - pcmdnode->cmdwaitqwoken); + pcmdnode->cmdwaitqwoken); pcmdptr = response_buf; if (pcmdptr->result) { - lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__, - pcmdptr->result); + lbs_pr_err("%s: fail, result=%d\n", __func__, + le16_to_cpu(pcmdptr->result)); kfree(response_buf); return 0; } @@ -538,7 +518,7 @@ static u16 libertas_get_events_bitmap(wlan_private *priv) } event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN); - event_bitmap = event->events; + event_bitmap = le16_to_cpu(event->events); kfree(response_buf); return event_bitmap; } @@ -579,7 +559,7 @@ static ssize_t libertas_lowrssi_write(struct file *file, goto out_unlock; event = &pcmdptr->params.subscribe_event; - event->action = cmd_act_set; + event->action = cpu_to_le16(cmd_act_set); pcmdptr->size = cpu_to_le16(S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event) + sizeof(struct mrvlietypes_rssithreshold)); @@ -588,30 +568,30 @@ static ssize_t libertas_lowrssi_write(struct file *file, ptr = (u8*) pcmdptr+cmd_len; rssi_threshold = (struct mrvlietypes_rssithreshold *)(ptr); rssi_threshold->header.type = cpu_to_le16(0x0104); - rssi_threshold->header.len = 2; - rssi_threshold->rssivalue = cpu_to_le16(value); - rssi_threshold->rssifreq = cpu_to_le16(freq); + rssi_threshold->header.len = cpu_to_le16(2); + rssi_threshold->rssivalue = value; + rssi_threshold->rssifreq = freq; event_bitmap |= subscribed ? 0x0001 : 0x0; - event->events = event_bitmap; + event->events = cpu_to_le16(event_bitmap); libertas_queue_cmd(adapter, pcmdnode, 1); wake_up_interruptible(&priv->mainthread.waitq); /* Sleep until response is generated by FW */ wait_event_interruptible(pcmdnode->cmdwait_q, - pcmdnode->cmdwaitqwoken); + pcmdnode->cmdwaitqwoken); pcmdptr = response_buf; if (pcmdptr->result) { - lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__, - pcmdptr->result); + lbs_pr_err("%s: fail, result=%d\n", __func__, + le16_to_cpu(pcmdptr->result)); kfree(response_buf); free_page(addr); return 0; } - if (pcmdptr->command != cmd_ret_802_11_subscribe_event) { + if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) { lbs_pr_err("command response incorrect!\n"); kfree(response_buf); free_page(addr); @@ -645,27 +625,26 @@ static ssize_t libertas_lowsnr_read(struct file *file, char __user *userbuf, } event = &pcmdptr->params.subscribe_event; - event->action = cmd_act_get; - pcmdptr->size = - cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN); + event->action = cpu_to_le16(cmd_act_get); + pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN); libertas_queue_cmd(adapter, pcmdnode, 1); wake_up_interruptible(&priv->mainthread.waitq); /* Sleep until response is generated by FW */ wait_event_interruptible(pcmdnode->cmdwait_q, - pcmdnode->cmdwaitqwoken); + pcmdnode->cmdwaitqwoken); pcmdptr = response_buf; if (pcmdptr->result) { - lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__, - pcmdptr->result); + lbs_pr_err("%s: fail, result=%d\n", __func__, + le16_to_cpu(pcmdptr->result)); kfree(response_buf); free_page(addr); return 0; } - if (pcmdptr->command != cmd_ret_802_11_subscribe_event) { + if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) { lbs_pr_err("command response incorrect!\n"); kfree(response_buf); free_page(addr); @@ -673,17 +652,17 @@ static ssize_t libertas_lowsnr_read(struct file *file, char __user *userbuf, } cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event); - event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN); - while (cmd_len < pcmdptr->size) { - struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len); - switch(header->type) { + event = (void *)(response_buf + S_DS_GEN); + while (cmd_len < le16_to_cpu(pcmdptr->size)) { + struct mrvlietypesheader *header = (void *)(response_buf + cmd_len); + switch (header->type) { struct mrvlietypes_snrthreshold *LowSnr; - case TLV_TYPE_SNR_LOW: - LowSnr = (struct mrvlietypes_snrthreshold *)(response_buf + cmd_len); - pos += snprintf(buf+pos, len-pos, "%d %d %d\n", - LowSnr->snrvalue, - LowSnr->snrfreq, - (event->events & 0x0002)?1:0); + case __constant_cpu_to_le16(TLV_TYPE_SNR_LOW): + LowSnr = (void *)(response_buf + cmd_len); + pos += snprintf(buf+pos, len-pos, "%d %d %d\n", + LowSnr->snrvalue, + LowSnr->snrfreq, + (event->events & cpu_to_le16(0x0002))?1:0); default: cmd_len += sizeof(struct mrvlietypes_snrthreshold); break; @@ -733,7 +712,7 @@ static ssize_t libertas_lowsnr_write(struct file *file, goto out_unlock; event = &pcmdptr->params.subscribe_event; - event->action = cmd_act_set; + event->action = cpu_to_le16(cmd_act_set); pcmdptr->size = cpu_to_le16(S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event) + sizeof(struct mrvlietypes_snrthreshold)); @@ -741,30 +720,30 @@ static ssize_t libertas_lowsnr_write(struct file *file, ptr = (u8*) pcmdptr+cmd_len; snr_threshold = (struct mrvlietypes_snrthreshold *)(ptr); snr_threshold->header.type = cpu_to_le16(TLV_TYPE_SNR_LOW); - snr_threshold->header.len = 2; - snr_threshold->snrvalue = cpu_to_le16(value); - snr_threshold->snrfreq = cpu_to_le16(freq); + snr_threshold->header.len = cpu_to_le16(2); + snr_threshold->snrvalue = value; + snr_threshold->snrfreq = freq; event_bitmap |= subscribed ? 0x0002 : 0x0; - event->events = event_bitmap; + event->events = cpu_to_le16(event_bitmap); libertas_queue_cmd(adapter, pcmdnode, 1); wake_up_interruptible(&priv->mainthread.waitq); /* Sleep until response is generated by FW */ wait_event_interruptible(pcmdnode->cmdwait_q, - pcmdnode->cmdwaitqwoken); + pcmdnode->cmdwaitqwoken); pcmdptr = response_buf; if (pcmdptr->result) { - lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__, - pcmdptr->result); + lbs_pr_err("%s: fail, result=%d\n", __func__, + le16_to_cpu(pcmdptr->result)); kfree(response_buf); free_page(addr); return 0; } - if (pcmdptr->command != cmd_ret_802_11_subscribe_event) { + if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) { lbs_pr_err("command response incorrect!\n"); kfree(response_buf); free_page(addr); @@ -799,27 +778,26 @@ static ssize_t libertas_failcount_read(struct file *file, char __user *userbuf, } event = &pcmdptr->params.subscribe_event; - event->action = cmd_act_get; - pcmdptr->size = - cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN); + event->action = cpu_to_le16(cmd_act_get); + pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN); libertas_queue_cmd(adapter, pcmdnode, 1); wake_up_interruptible(&priv->mainthread.waitq); /* Sleep until response is generated by FW */ wait_event_interruptible(pcmdnode->cmdwait_q, - pcmdnode->cmdwaitqwoken); + pcmdnode->cmdwaitqwoken); pcmdptr = response_buf; if (pcmdptr->result) { - lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__, - pcmdptr->result); + lbs_pr_err("%s: fail, result=%d\n", __func__, + le16_to_cpu(pcmdptr->result)); kfree(response_buf); free_page(addr); return 0; } - if (pcmdptr->command != cmd_ret_802_11_subscribe_event) { + if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) { lbs_pr_err("command response incorrect!\n"); kfree(response_buf); free_page(addr); @@ -827,17 +805,17 @@ static ssize_t libertas_failcount_read(struct file *file, char __user *userbuf, } cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event); - event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN); - while (cmd_len < pcmdptr->size) { - struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len); - switch(header->type) { + event = (void *)(response_buf + S_DS_GEN); + while (cmd_len < le16_to_cpu(pcmdptr->size)) { + struct mrvlietypesheader *header = (void *)(response_buf + cmd_len); + switch (header->type) { struct mrvlietypes_failurecount *failcount; - case TLV_TYPE_FAILCOUNT: - failcount = (struct mrvlietypes_failurecount *)(response_buf + cmd_len); - pos += snprintf(buf+pos, len-pos, "%d %d %d\n", - failcount->failvalue, - failcount->Failfreq, - (event->events & 0x0004)?1:0); + case __constant_cpu_to_le16(TLV_TYPE_FAILCOUNT): + failcount = (void *)(response_buf + cmd_len); + pos += snprintf(buf+pos, len-pos, "%d %d %d\n", + failcount->failvalue, + failcount->Failfreq, + (event->events & cpu_to_le16(0x0004))?1:0); default: cmd_len += sizeof(struct mrvlietypes_failurecount); break; @@ -886,7 +864,7 @@ static ssize_t libertas_failcount_write(struct file *file, goto out_unlock; event = &pcmdptr->params.subscribe_event; - event->action = cmd_act_set; + event->action = cpu_to_le16(cmd_act_set); pcmdptr->size = cpu_to_le16(S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event) + sizeof(struct mrvlietypes_failurecount)); @@ -894,30 +872,30 @@ static ssize_t libertas_failcount_write(struct file *file, ptr = (u8*) pcmdptr+cmd_len; failcount = (struct mrvlietypes_failurecount *)(ptr); failcount->header.type = cpu_to_le16(TLV_TYPE_FAILCOUNT); - failcount->header.len = 2; - failcount->failvalue = cpu_to_le16(value); - failcount->Failfreq = cpu_to_le16(freq); + failcount->header.len = cpu_to_le16(2); + failcount->failvalue = value; + failcount->Failfreq = freq; event_bitmap |= subscribed ? 0x0004 : 0x0; - event->events = event_bitmap; + event->events = cpu_to_le16(event_bitmap); libertas_queue_cmd(adapter, pcmdnode, 1); wake_up_interruptible(&priv->mainthread.waitq); /* Sleep until response is generated by FW */ wait_event_interruptible(pcmdnode->cmdwait_q, - pcmdnode->cmdwaitqwoken); + pcmdnode->cmdwaitqwoken); pcmdptr = (struct cmd_ds_command *)response_buf; if (pcmdptr->result) { - lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__, - pcmdptr->result); + lbs_pr_err("%s: fail, result=%d\n", __func__, + le16_to_cpu(pcmdptr->result)); kfree(response_buf); free_page(addr); return 0; } - if (pcmdptr->command != cmd_ret_802_11_subscribe_event) { + if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) { lbs_pr_err("command response incorrect!\n"); kfree(response_buf); free_page(addr); @@ -951,27 +929,26 @@ static ssize_t libertas_bcnmiss_read(struct file *file, char __user *userbuf, } event = &pcmdptr->params.subscribe_event; - event->action = cmd_act_get; - pcmdptr->size = - cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN); + event->action = cpu_to_le16(cmd_act_get); + pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN); libertas_queue_cmd(adapter, pcmdnode, 1); wake_up_interruptible(&priv->mainthread.waitq); /* Sleep until response is generated by FW */ wait_event_interruptible(pcmdnode->cmdwait_q, - pcmdnode->cmdwaitqwoken); + pcmdnode->cmdwaitqwoken); pcmdptr = response_buf; if (pcmdptr->result) { - lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__, - pcmdptr->result); + lbs_pr_err("%s: fail, result=%d\n", __func__, + le16_to_cpu(pcmdptr->result)); free_page(addr); kfree(response_buf); return 0; } - if (pcmdptr->command != cmd_ret_802_11_subscribe_event) { + if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) { lbs_pr_err("command response incorrect!\n"); free_page(addr); kfree(response_buf); @@ -979,16 +956,16 @@ static ssize_t libertas_bcnmiss_read(struct file *file, char __user *userbuf, } cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event); - event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN); - while (cmd_len < pcmdptr->size) { - struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len); - switch(header->type) { + event = (void *)(response_buf + S_DS_GEN); + while (cmd_len < le16_to_cpu(pcmdptr->size)) { + struct mrvlietypesheader *header = (void *)(response_buf + cmd_len); + switch (header->type) { struct mrvlietypes_beaconsmissed *bcnmiss; - case TLV_TYPE_BCNMISS: - bcnmiss = (struct mrvlietypes_beaconsmissed *)(response_buf + cmd_len); - pos += snprintf(buf+pos, len-pos, "%d N/A %d\n", - bcnmiss->beaconmissed, - (event->events & 0x0008)?1:0); + case __constant_cpu_to_le16(TLV_TYPE_BCNMISS): + bcnmiss = (void *)(response_buf + cmd_len); + pos += snprintf(buf+pos, len-pos, "%d N/A %d\n", + bcnmiss->beaconmissed, + (event->events & cpu_to_le16(0x0008))?1:0); default: cmd_len += sizeof(struct mrvlietypes_beaconsmissed); break; @@ -1038,7 +1015,7 @@ static ssize_t libertas_bcnmiss_write(struct file *file, goto out_unlock; event = &pcmdptr->params.subscribe_event; - event->action = cmd_act_set; + event->action = cpu_to_le16(cmd_act_set); pcmdptr->size = cpu_to_le16(S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event) + sizeof(struct mrvlietypes_beaconsmissed)); @@ -1046,29 +1023,29 @@ static ssize_t libertas_bcnmiss_write(struct file *file, ptr = (u8*) pcmdptr+cmd_len; bcnmiss = (struct mrvlietypes_beaconsmissed *)(ptr); bcnmiss->header.type = cpu_to_le16(TLV_TYPE_BCNMISS); - bcnmiss->header.len = 2; - bcnmiss->beaconmissed = cpu_to_le16(value); + bcnmiss->header.len = cpu_to_le16(2); + bcnmiss->beaconmissed = value; event_bitmap |= subscribed ? 0x0008 : 0x0; - event->events = event_bitmap; + event->events = cpu_to_le16(event_bitmap); libertas_queue_cmd(adapter, pcmdnode, 1); wake_up_interruptible(&priv->mainthread.waitq); /* Sleep until response is generated by FW */ wait_event_interruptible(pcmdnode->cmdwait_q, - pcmdnode->cmdwaitqwoken); + pcmdnode->cmdwaitqwoken); pcmdptr = response_buf; if (pcmdptr->result) { - lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__, - pcmdptr->result); + lbs_pr_err("%s: fail, result=%d\n", __func__, + le16_to_cpu(pcmdptr->result)); kfree(response_buf); free_page(addr); return 0; } - if (pcmdptr->command != cmd_ret_802_11_subscribe_event) { + if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) { lbs_pr_err("command response incorrect!\n"); free_page(addr); kfree(response_buf); @@ -1102,27 +1079,26 @@ static ssize_t libertas_highrssi_read(struct file *file, char __user *userbuf, } event = &pcmdptr->params.subscribe_event; - event->action = cmd_act_get; - pcmdptr->size = - cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN); + event->action = cpu_to_le16(cmd_act_get); + pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN); libertas_queue_cmd(adapter, pcmdnode, 1); wake_up_interruptible(&priv->mainthread.waitq); /* Sleep until response is generated by FW */ wait_event_interruptible(pcmdnode->cmdwait_q, - pcmdnode->cmdwaitqwoken); + pcmdnode->cmdwaitqwoken); pcmdptr = response_buf; if (pcmdptr->result) { - lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__, - pcmdptr->result); + lbs_pr_err("%s: fail, result=%d\n", __func__, + le16_to_cpu(pcmdptr->result)); kfree(response_buf); free_page(addr); return 0; } - if (pcmdptr->command != cmd_ret_802_11_subscribe_event) { + if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) { lbs_pr_err("command response incorrect!\n"); kfree(response_buf); free_page(addr); @@ -1130,17 +1106,17 @@ static ssize_t libertas_highrssi_read(struct file *file, char __user *userbuf, } cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event); - event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN); - while (cmd_len < pcmdptr->size) { - struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len); - switch(header->type) { + event = (void *)(response_buf + S_DS_GEN); + while (cmd_len < le16_to_cpu(pcmdptr->size)) { + struct mrvlietypesheader *header = (void *)(response_buf + cmd_len); + switch (header->type) { struct mrvlietypes_rssithreshold *Highrssi; - case TLV_TYPE_RSSI_HIGH: - Highrssi = (struct mrvlietypes_rssithreshold *)(response_buf + cmd_len); - pos += snprintf(buf+pos, len-pos, "%d %d %d\n", - Highrssi->rssivalue, - Highrssi->rssifreq, - (event->events & 0x0010)?1:0); + case __constant_cpu_to_le16(TLV_TYPE_RSSI_HIGH): + Highrssi = (void *)(response_buf + cmd_len); + pos += snprintf(buf+pos, len-pos, "%d %d %d\n", + Highrssi->rssivalue, + Highrssi->rssifreq, + (event->events & cpu_to_le16(0x0010))?1:0); default: cmd_len += sizeof(struct mrvlietypes_snrthreshold); break; @@ -1190,7 +1166,7 @@ static ssize_t libertas_highrssi_write(struct file *file, goto out_unlock; event = &pcmdptr->params.subscribe_event; - event->action = cmd_act_set; + event->action = cpu_to_le16(cmd_act_set); pcmdptr->size = cpu_to_le16(S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event) + sizeof(struct mrvlietypes_rssithreshold)); @@ -1198,29 +1174,29 @@ static ssize_t libertas_highrssi_write(struct file *file, ptr = (u8*) pcmdptr+cmd_len; rssi_threshold = (struct mrvlietypes_rssithreshold *)(ptr); rssi_threshold->header.type = cpu_to_le16(TLV_TYPE_RSSI_HIGH); - rssi_threshold->header.len = 2; - rssi_threshold->rssivalue = cpu_to_le16(value); - rssi_threshold->rssifreq = cpu_to_le16(freq); + rssi_threshold->header.len = cpu_to_le16(2); + rssi_threshold->rssivalue = value; + rssi_threshold->rssifreq = freq; event_bitmap |= subscribed ? 0x0010 : 0x0; - event->events = event_bitmap; + event->events = cpu_to_le16(event_bitmap); libertas_queue_cmd(adapter, pcmdnode, 1); wake_up_interruptible(&priv->mainthread.waitq); /* Sleep until response is generated by FW */ wait_event_interruptible(pcmdnode->cmdwait_q, - pcmdnode->cmdwaitqwoken); + pcmdnode->cmdwaitqwoken); pcmdptr = response_buf; if (pcmdptr->result) { - lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__, - pcmdptr->result); + lbs_pr_err("%s: fail, result=%d\n", __func__, + le16_to_cpu(pcmdptr->result)); kfree(response_buf); return 0; } - if (pcmdptr->command != cmd_ret_802_11_subscribe_event) { + if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) { lbs_pr_err("command response incorrect!\n"); kfree(response_buf); return 0; @@ -1253,27 +1229,26 @@ static ssize_t libertas_highsnr_read(struct file *file, char __user *userbuf, } event = &pcmdptr->params.subscribe_event; - event->action = cmd_act_get; - pcmdptr->size = - cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN); + event->action = cpu_to_le16(cmd_act_get); + pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN); libertas_queue_cmd(adapter, pcmdnode, 1); wake_up_interruptible(&priv->mainthread.waitq); /* Sleep until response is generated by FW */ wait_event_interruptible(pcmdnode->cmdwait_q, - pcmdnode->cmdwaitqwoken); + pcmdnode->cmdwaitqwoken); pcmdptr = response_buf; if (pcmdptr->result) { - lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__, - pcmdptr->result); + lbs_pr_err("%s: fail, result=%d\n", __func__, + le16_to_cpu(pcmdptr->result)); kfree(response_buf); free_page(addr); return 0; } - if (pcmdptr->command != cmd_ret_802_11_subscribe_event) { + if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) { lbs_pr_err("command response incorrect!\n"); kfree(response_buf); free_page(addr); @@ -1281,17 +1256,17 @@ static ssize_t libertas_highsnr_read(struct file *file, char __user *userbuf, } cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event); - event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN); - while (cmd_len < pcmdptr->size) { - struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len); - switch(header->type) { + event = (void *)(response_buf + S_DS_GEN); + while (cmd_len < le16_to_cpu(pcmdptr->size)) { + struct mrvlietypesheader *header = (void *)(response_buf + cmd_len); + switch (header->type) { struct mrvlietypes_snrthreshold *HighSnr; - case TLV_TYPE_SNR_HIGH: - HighSnr = (struct mrvlietypes_snrthreshold *)(response_buf + cmd_len); - pos += snprintf(buf+pos, len-pos, "%d %d %d\n", - HighSnr->snrvalue, - HighSnr->snrfreq, - (event->events & 0x0020)?1:0); + case __constant_cpu_to_le16(TLV_TYPE_SNR_HIGH): + HighSnr = (void *)(response_buf + cmd_len); + pos += snprintf(buf+pos, len-pos, "%d %d %d\n", + HighSnr->snrvalue, + HighSnr->snrfreq, + (event->events & cpu_to_le16(0x0020))?1:0); default: cmd_len += sizeof(struct mrvlietypes_snrthreshold); break; @@ -1341,7 +1316,7 @@ static ssize_t libertas_highsnr_write(struct file *file, goto out_unlock; event = &pcmdptr->params.subscribe_event; - event->action = cmd_act_set; + event->action = cpu_to_le16(cmd_act_set); pcmdptr->size = cpu_to_le16(S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event) + sizeof(struct mrvlietypes_snrthreshold)); @@ -1349,30 +1324,30 @@ static ssize_t libertas_highsnr_write(struct file *file, ptr = (u8*) pcmdptr+cmd_len; snr_threshold = (struct mrvlietypes_snrthreshold *)(ptr); snr_threshold->header.type = cpu_to_le16(TLV_TYPE_SNR_HIGH); - snr_threshold->header.len = 2; - snr_threshold->snrvalue = cpu_to_le16(value); - snr_threshold->snrfreq = cpu_to_le16(freq); + snr_threshold->header.len = cpu_to_le16(2); + snr_threshold->snrvalue = value; + snr_threshold->snrfreq = freq; event_bitmap |= subscribed ? 0x0020 : 0x0; - event->events = event_bitmap; + event->events = cpu_to_le16(event_bitmap); libertas_queue_cmd(adapter, pcmdnode, 1); wake_up_interruptible(&priv->mainthread.waitq); /* Sleep until response is generated by FW */ wait_event_interruptible(pcmdnode->cmdwait_q, - pcmdnode->cmdwaitqwoken); + pcmdnode->cmdwaitqwoken); pcmdptr = response_buf; if (pcmdptr->result) { - lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__, - pcmdptr->result); + lbs_pr_err("%s: fail, result=%d\n", __func__, + le16_to_cpu(pcmdptr->result)); kfree(response_buf); free_page(addr); return 0; } - if (pcmdptr->command != cmd_ret_802_11_subscribe_event) { + if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) { lbs_pr_err("command response incorrect!\n"); kfree(response_buf); free_page(addr); @@ -1760,7 +1735,7 @@ void libertas_debugfs_remove_one(wlan_private *priv) debugfs_remove(priv->regs_dir); - for(i=0; i<ARRAY_SIZE(debugfs_files); i++) + for(i=0; i<ARRAY_SIZE(debugfs_events_files); i++) debugfs_remove(priv->debugfs_events_files[i]); debugfs_remove(priv->events_dir); @@ -1769,13 +1744,19 @@ void libertas_debugfs_remove_one(wlan_private *priv) #endif for(i=0; i<ARRAY_SIZE(debugfs_files); i++) debugfs_remove(priv->debugfs_files[i]); + debugfs_remove(priv->debugfs_dir); } + + /* debug entry */ +#ifdef PROC_DEBUG + #define item_size(n) (FIELD_SIZEOF(wlan_adapter, n)) #define item_addr(n) (offsetof(wlan_adapter, n)) + struct debug_data { char name[32]; u32 size; @@ -1863,7 +1844,7 @@ static ssize_t wlan_debugfs_write(struct file *f, const char __user *buf, return 0; if (copy_from_user(pdata, buf, cnt)) { - lbs_pr_debug(1, "Copy from user failed\n"); + lbs_deb_debugfs("Copy from user failed\n"); kfree(pdata); return 0; } @@ -1913,7 +1894,7 @@ static struct file_operations libertas_debug_fops = { * @param dev pointer net_device * @return N/A */ -void libertas_debug_init(wlan_private * priv, struct net_device *dev) +static void libertas_debug_init(wlan_private * priv, struct net_device *dev) { int i; @@ -1927,4 +1908,5 @@ void libertas_debug_init(wlan_private * priv, struct net_device *dev) priv->debugfs_dir, &items[0], &libertas_debug_fops); } +#endif diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h index dfe27642322..40f56bb1eac 100644 --- a/drivers/net/wireless/libertas/decl.h +++ b/drivers/net/wireless/libertas/decl.h @@ -6,6 +6,8 @@ #ifndef _WLAN_DECL_H_ #define _WLAN_DECL_H_ +#include <linux/device.h> + #include "defs.h" /** Function Prototype Declaration */ @@ -66,18 +68,24 @@ void libertas_ps_wakeup(wlan_private * priv, int wait_option); void libertas_tx_runqueue(wlan_private *priv); -extern struct chan_freq_power *libertas_find_cfp_by_band_and_channel( +struct chan_freq_power *libertas_find_cfp_by_band_and_channel( wlan_adapter * adapter, u8 band, u16 channel); -extern void libertas_mac_event_disconnected(wlan_private * priv); +void libertas_mac_event_disconnected(wlan_private * priv); void libertas_send_iwevcustom_event(wlan_private * priv, s8 * str); -int reset_device(wlan_private *priv); +/* fw.c */ +int libertas_init_fw(wlan_private * priv, char *fw_name); + /* main.c */ -extern struct chan_freq_power *libertas_get_region_cfp_table(u8 region, u8 band, +struct chan_freq_power *libertas_get_region_cfp_table(u8 region, u8 band, int *cfp_no); -wlan_private *wlan_add_card(void *card); -int wlan_remove_card(void *card); +wlan_private *libertas_add_card(void *card, struct device *dmdev); +int libertas_activate_card(wlan_private *priv, char *fw_name); +int libertas_remove_card(wlan_private *priv); +int libertas_add_mesh(wlan_private *priv, struct device *dev); +void libertas_remove_mesh(wlan_private *priv); + #endif /* _WLAN_DECL_H_ */ diff --git a/drivers/net/wireless/libertas/defs.h b/drivers/net/wireless/libertas/defs.h index 80dd9ea19c8..4dd43e59bda 100644 --- a/drivers/net/wireless/libertas/defs.h +++ b/drivers/net/wireless/libertas/defs.h @@ -7,14 +7,79 @@ #include <linux/spinlock.h> -extern unsigned int libertas_debug; - #ifdef CONFIG_LIBERTAS_DEBUG #define DEBUG #define PROC_DEBUG #endif -#define DRV_NAME "usb8xxx" +#ifndef DRV_NAME +#define DRV_NAME "libertas" +#endif + + +#define LBS_DEB_ENTER 0x00000001 +#define LBS_DEB_LEAVE 0x00000002 +#define LBS_DEB_MAIN 0x00000004 +#define LBS_DEB_NET 0x00000008 +#define LBS_DEB_MESH 0x00000010 +#define LBS_DEB_WEXT 0x00000020 +#define LBS_DEB_IOCTL 0x00000040 +#define LBS_DEB_SCAN 0x00000080 +#define LBS_DEB_ASSOC 0x00000100 +#define LBS_DEB_JOIN 0x00000200 +#define LBS_DEB_11D 0x00000400 +#define LBS_DEB_DEBUGFS 0x00000800 +#define LBS_DEB_ETHTOOL 0x00001000 +#define LBS_DEB_HOST 0x00002000 +#define LBS_DEB_CMD 0x00004000 +#define LBS_DEB_RX 0x00008000 +#define LBS_DEB_TX 0x00010000 +#define LBS_DEB_USB 0x00020000 +#define LBS_DEB_CS 0x00040000 +#define LBS_DEB_FW 0x00080000 +#define LBS_DEB_THREAD 0x00100000 +#define LBS_DEB_HEX 0x00200000 + +extern unsigned int libertas_debug; + +#ifdef DEBUG +#define LBS_DEB_LL(grp, fmt, args...) \ +do { if ((libertas_debug & (grp)) == (grp)) \ + printk(KERN_DEBUG DRV_NAME "%s: " fmt, \ + in_interrupt() ? " (INT)" : "", ## args); } while (0) +#else +#define LBS_DEB_LL(grp, fmt, args...) do {} while (0) +#endif + +#define lbs_deb_enter(grp) \ + LBS_DEB_LL(grp | LBS_DEB_ENTER, "%s():%d enter\n", __FUNCTION__, __LINE__); +#define lbs_deb_enter_args(grp, fmt, args...) \ + LBS_DEB_LL(grp | LBS_DEB_ENTER, "%s(" fmt "):%d\n", __FUNCTION__, ## args, __LINE__); +#define lbs_deb_leave(grp) \ + LBS_DEB_LL(grp | LBS_DEB_LEAVE, "%s():%d leave\n", __FUNCTION__, __LINE__); +#define lbs_deb_leave_args(grp, fmt, args...) \ + LBS_DEB_LL(grp | LBS_DEB_LEAVE, "%s():%d leave, " fmt "\n", \ + __FUNCTION__, __LINE__, ##args); +#define lbs_deb_main(fmt, args...) LBS_DEB_LL(LBS_DEB_MAIN, fmt, ##args) +#define lbs_deb_net(fmt, args...) LBS_DEB_LL(LBS_DEB_NET, fmt, ##args) +#define lbs_deb_mesh(fmt, args...) LBS_DEB_LL(LBS_DEB_MESH, fmt, ##args) +#define lbs_deb_wext(fmt, args...) LBS_DEB_LL(LBS_DEB_WEXT, fmt, ##args) +#define lbs_deb_ioctl(fmt, args...) LBS_DEB_LL(LBS_DEB_IOCTL, fmt, ##args) +#define lbs_deb_scan(fmt, args...) LBS_DEB_LL(LBS_DEB_SCAN, fmt, ##args) +#define lbs_deb_assoc(fmt, args...) LBS_DEB_LL(LBS_DEB_ASSOC, fmt, ##args) +#define lbs_deb_join(fmt, args...) LBS_DEB_LL(LBS_DEB_JOIN, fmt, ##args) +#define lbs_deb_11d(fmt, args...) LBS_DEB_LL(LBS_DEB_11D, fmt, ##args) +#define lbs_deb_debugfs(fmt, args...) LBS_DEB_LL(LBS_DEB_DEBUGFS, fmt, ##args) +#define lbs_deb_ethtool(fmt, args...) LBS_DEB_LL(LBS_DEB_ETHTOOL, fmt, ##args) +#define lbs_deb_host(fmt, args...) LBS_DEB_LL(LBS_DEB_HOST, fmt, ##args) +#define lbs_deb_cmd(fmt, args...) LBS_DEB_LL(LBS_DEB_CMD, fmt, ##args) +#define lbs_deb_rx(fmt, args...) LBS_DEB_LL(LBS_DEB_RX, fmt, ##args) +#define lbs_deb_tx(fmt, args...) LBS_DEB_LL(LBS_DEB_TX, fmt, ##args) +#define lbs_deb_fw(fmt, args...) LBS_DEB_LL(LBS_DEB_FW, fmt, ##args) +#define lbs_deb_usb(fmt, args...) LBS_DEB_LL(LBS_DEB_USB, fmt, ##args) +#define lbs_deb_usbd(dev, fmt, args...) LBS_DEB_LL(LBS_DEB_USB, "%s:" fmt, (dev)->bus_id, ##args) +#define lbs_deb_cs(fmt, args...) LBS_DEB_LL(LBS_DEB_CS, fmt, ##args) +#define lbs_deb_thread(fmt, args...) LBS_DEB_LL(LBS_DEB_THREAD, fmt, ##args) #define lbs_pr_info(format, args...) \ printk(KERN_INFO DRV_NAME": " format, ## args) @@ -24,37 +89,25 @@ extern unsigned int libertas_debug; printk(KERN_ALERT DRV_NAME": " format, ## args) #ifdef DEBUG -#define lbs_pr_debug(level, format, args...) \ - do { if (libertas_debug >= level) \ - printk(KERN_INFO DRV_NAME": " format, ##args); } while (0) -#define lbs_dev_dbg(level, device, format, args...) \ - lbs_pr_debug(level, "%s: " format, \ - (device)->bus_id , ## args) - static inline void lbs_dbg_hex(char *prompt, u8 * buf, int len) { int i = 0; - if (!libertas_debug) + if (!(libertas_debug & LBS_DEB_HEX)) return; printk(KERN_DEBUG "%s: ", prompt); for (i = 1; i <= len; i++) { - printk(KERN_DEBUG "%02x ", (u8) * buf); + printk("%02x ", (u8) * buf); buf++; } printk("\n"); } #else -#define lbs_pr_debug(level, format, args...) do {} while (0) -#define lbs_dev_dbg(level, device, format, args...) do {} while (0) #define lbs_dbg_hex(x,y,z) do {} while (0) #endif -#define ENTER() lbs_pr_debug(1, "Enter: %s, %s:%i\n", \ - __FUNCTION__, __FILE__, __LINE__) -#define LEAVE() lbs_pr_debug(1, "Leave: %s, %s:%i\n", \ - __FUNCTION__, __FILE__, __LINE__) + /** Buffer Constants */ @@ -74,7 +127,6 @@ static inline void lbs_dbg_hex(char *prompt, u8 * buf, int len) #define MRVDRV_NUM_OF_CMD_BUFFER 10 #define MRVDRV_SIZE_OF_CMD_BUFFER (2 * 1024) #define MRVDRV_MAX_CHANNEL_SIZE 14 -#define MRVDRV_MAX_BSSID_LIST 64 #define MRVDRV_ASSOCIATION_TIME_OUT 255 #define MRVDRV_SNAP_HEADER_LEN 8 @@ -104,6 +156,13 @@ static inline void lbs_dbg_hex(char *prompt, u8 * buf, int len) #define MRVDRV_MAX_BEACON_INTERVAL 1000 #define MRVDRV_BEACON_INTERVAL 100 +/** INT status Bit Definition*/ +#define his_cmddnldrdy 0x01 +#define his_cardevent 0x02 +#define his_cmdupldrdy 0x04 + +#define SBI_EVENT_CAUSE_SHIFT 3 + /** TxPD status */ /* Station firmware use TxPD status field to report final Tx transmit @@ -205,8 +264,6 @@ typedef struct _wlan_adapter wlan_adapter; extern const char libertas_driver_version[]; extern u16 libertas_region_code_to_index[MRVDRV_MAX_REGION_CODE]; -extern u8 libertas_wlan_data_rates[WLAN_SUPPORTED_RATES]; - extern u8 libertas_supported_rates[G_SUPPORTED_RATES]; extern u8 libertas_adhoc_rates_g[G_SUPPORTED_RATES]; @@ -316,6 +373,8 @@ enum SNMP_MIB_VALUE_e { /* Default values for fwt commands. */ #define FWT_DEFAULT_METRIC 0 #define FWT_DEFAULT_DIR 1 +/* Default Rate, 11Mbps */ +#define FWT_DEFAULT_RATE 3 #define FWT_DEFAULT_SSN 0xffffffff #define FWT_DEFAULT_DSN 0 #define FWT_DEFAULT_HOPCOUNT 0 diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h index e8b9020f9bd..785192b884b 100644 --- a/drivers/net/wireless/libertas/dev.h +++ b/drivers/net/wireless/libertas/dev.h @@ -63,11 +63,11 @@ struct wlan_802_11_security { /** Current Basic Service Set State Structure */ struct current_bss_params { - struct bss_descriptor bssdescriptor; /** bssid */ u8 bssid[ETH_ALEN]; /** ssid */ - struct WLAN_802_11_SSID ssid; + u8 ssid[IW_ESSID_MAX_SIZE + 1]; + u8 ssid_len; /** band */ u8 band; @@ -89,31 +89,6 @@ struct sleep_params { u16 sp_reserved; }; -/** Data structure for the Marvell WLAN device */ -typedef struct _wlan_dev { - /** device name */ - char name[DEV_NAME_LEN]; - /** card pointer */ - void *card; - /** IO port */ - u32 ioport; - /** Upload received */ - u32 upld_rcv; - /** Upload type */ - u32 upld_typ; - /** Upload length */ - u32 upld_len; - /** netdev pointer */ - struct net_device *netdev; - /* Upload buffer */ - u8 upld_buf[WLAN_UPLD_SIZE]; - /* Download sent: - bit0 1/0=data_sent/data_tx_done, - bit1 1/0=cmd_sent/cmd_tx_done, - all other bits reserved 0 */ - u8 dnld_sent; -} wlan_dev_t, *pwlan_dev_t; - /* Mesh statistics */ struct wlan_mesh_stats { u32 fwd_bcast_cnt; /* Fwd: Broadcast counter */ @@ -123,6 +98,7 @@ struct wlan_mesh_stats { u32 fwd_drop_noroute; /* Fwd: No route to Destination */ u32 fwd_drop_nobuf; /* Fwd: Run out of internal buffers */ u32 drop_blind; /* Rx: Dropped by blinding table */ + u32 tx_failed_cnt; /* Tx: Failed transmissions */ }; /** Private structure for the MV device */ @@ -131,8 +107,11 @@ struct _wlan_private { int mesh_open; int infra_open; + char name[DEV_NAME_LEN]; + + void *card; wlan_adapter *adapter; - wlan_dev_t wlan_dev; + struct net_device *dev; struct net_device_stats stats; struct net_device *mesh_dev ; /* Virtual device */ @@ -153,6 +132,16 @@ struct _wlan_private { u32 bbp_offset; u32 rf_offset; + /** Upload length */ + u32 upld_len; + /* Upload buffer */ + u8 upld_buf[WLAN_UPLD_SIZE]; + /* Download sent: + bit0 1/0=data_sent/data_tx_done, + bit1 1/0=cmd_sent/cmd_tx_done, + all other bits reserved 0 */ + u8 dnld_sent; + const struct firmware *firmware; struct device *hotplug_device; @@ -161,6 +150,15 @@ struct _wlan_private { struct delayed_work assoc_work; struct workqueue_struct *assoc_thread; + struct work_struct sync_channel; + + /** Hardware access */ + int (*hw_register_dev) (wlan_private * priv); + int (*hw_unregister_dev) (wlan_private *); + int (*hw_prog_firmware) (wlan_private *); + int (*hw_host_to_card) (wlan_private * priv, u8 type, u8 * payload, u16 nb); + int (*hw_get_int_status) (wlan_private * priv, u8 *); + int (*hw_read_event_cause) (wlan_private *); }; /** Association request @@ -171,18 +169,21 @@ struct _wlan_private { struct assoc_request { #define ASSOC_FLAG_SSID 1 #define ASSOC_FLAG_CHANNEL 2 -#define ASSOC_FLAG_MODE 3 -#define ASSOC_FLAG_BSSID 4 -#define ASSOC_FLAG_WEP_KEYS 5 -#define ASSOC_FLAG_WEP_TX_KEYIDX 6 -#define ASSOC_FLAG_WPA_MCAST_KEY 7 -#define ASSOC_FLAG_WPA_UCAST_KEY 8 -#define ASSOC_FLAG_SECINFO 9 -#define ASSOC_FLAG_WPA_IE 10 +#define ASSOC_FLAG_BAND 3 +#define ASSOC_FLAG_MODE 4 +#define ASSOC_FLAG_BSSID 5 +#define ASSOC_FLAG_WEP_KEYS 6 +#define ASSOC_FLAG_WEP_TX_KEYIDX 7 +#define ASSOC_FLAG_WPA_MCAST_KEY 8 +#define ASSOC_FLAG_WPA_UCAST_KEY 9 +#define ASSOC_FLAG_SECINFO 10 +#define ASSOC_FLAG_WPA_IE 11 unsigned long flags; - struct WLAN_802_11_SSID ssid; + u8 ssid[IW_ESSID_MAX_SIZE + 1]; + u8 ssid_len; u8 channel; + u8 band; u8 mode; u8 bssid[ETH_ALEN]; @@ -199,12 +200,15 @@ struct assoc_request { /** WPA Information Elements*/ u8 wpa_ie[MAX_WPA_IE_LEN]; u8 wpa_ie_len; + + /* BSS to associate with for infrastructure of Ad-Hoc join */ + struct bss_descriptor bss; }; /** Wlan adapter data structure*/ struct _wlan_adapter { /** STATUS variables */ - u32 fwreleasenumber; + u8 fwreleasenumber[4]; u32 fwcapinfo; /* protected with big lock */ @@ -255,13 +259,14 @@ struct _wlan_adapter { /* IW_MODE_* */ u8 mode; - struct bss_descriptor *pattemptedbssdesc; - - struct WLAN_802_11_SSID previousssid; - u8 previousbssid[ETH_ALEN]; + u8 prev_ssid[IW_ESSID_MAX_SIZE + 1]; + u8 prev_ssid_len; + u8 prev_bssid[ETH_ALEN]; - struct bss_descriptor *scantable; - u32 numinscantable; + /* Scan results list */ + struct list_head network_list; + struct list_head network_free_list; + struct bss_descriptor *networks; u8 scantype; u32 scanmode; @@ -288,7 +293,6 @@ struct _wlan_adapter { u32 txantenna; u32 rxantenna; - u8 adhocchannel; u32 fragthsd; u32 rtsthsd; @@ -324,7 +328,8 @@ struct _wlan_adapter { u16 locallisteninterval; u16 nullpktinterval; - struct assoc_request * assoc_req; + struct assoc_request * pending_assoc_req; + struct assoc_request * in_progress_assoc_req; /** Encryption parameter */ struct wlan_802_11_security secinfo; @@ -396,6 +401,8 @@ struct _wlan_adapter { u32 radiomode; u32 debugmode; u8 fw_ready; + + u8 last_scanned_channel; }; #endif /* _WLAN_DEV_H_ */ diff --git a/drivers/net/wireless/libertas/ethtool.c b/drivers/net/wireless/libertas/ethtool.c index 0064de54296..96f1974685d 100644 --- a/drivers/net/wireless/libertas/ethtool.c +++ b/drivers/net/wireless/libertas/ethtool.c @@ -1,10 +1,8 @@ - #include <linux/netdevice.h> #include <linux/ethtool.h> #include <linux/delay.h> #include "host.h" -#include "sbi.h" #include "decl.h" #include "defs.h" #include "dev.h" @@ -17,7 +15,8 @@ static const char * mesh_stat_strings[]= { "drop_no_buffers", "fwded_unicast_cnt", "fwded_bcast_cnt", - "drop_blind_table" + "drop_blind_table", + "tx_failed_cnt" }; static void libertas_ethtool_get_drvinfo(struct net_device *dev, @@ -69,7 +68,7 @@ static int libertas_ethtool_get_eeprom(struct net_device *dev, /* +14 is for action, offset, and NOB in * response */ - lbs_pr_debug(1, "action:%d offset: %x NOB: %02x\n", + lbs_deb_ethtool("action:%d offset: %x NOB: %02x\n", regctrl.action, regctrl.offset, regctrl.NOB); ret = libertas_prepare_and_send_command(priv, @@ -81,8 +80,7 @@ static int libertas_ethtool_get_eeprom(struct net_device *dev, if (ret) { if (adapter->prdeeprom) kfree(adapter->prdeeprom); - LEAVE(); - return ret; + goto done; } mdelay(10); @@ -101,7 +99,11 @@ static int libertas_ethtool_get_eeprom(struct net_device *dev, kfree(adapter->prdeeprom); // mutex_unlock(&priv->mutex); - return 0; + ret = 0; + +done: + lbs_deb_enter_args(LBS_DEB_ETHTOOL, "ret %d", ret); + return ret; } static void libertas_ethtool_get_stats(struct net_device * dev, @@ -109,7 +111,7 @@ static void libertas_ethtool_get_stats(struct net_device * dev, { wlan_private *priv = dev->priv; - ENTER(); + lbs_deb_enter(LBS_DEB_ETHTOOL); stats->cmd = ETHTOOL_GSTATS; BUG_ON(stats->n_stats != MESH_STATS_NUM); @@ -121,8 +123,9 @@ static void libertas_ethtool_get_stats(struct net_device * dev, data[4] = priv->mstats.fwd_unicast_cnt; data[5] = priv->mstats.fwd_bcast_cnt; data[6] = priv->mstats.drop_blind; + data[7] = priv->mstats.tx_failed_cnt; - LEAVE(); + lbs_deb_enter(LBS_DEB_ETHTOOL); } static int libertas_ethtool_get_stats_count(struct net_device * dev) @@ -131,27 +134,32 @@ static int libertas_ethtool_get_stats_count(struct net_device * dev) wlan_private *priv = dev->priv; struct cmd_ds_mesh_access mesh_access; - ENTER(); + lbs_deb_enter(LBS_DEB_ETHTOOL); + /* Get Mesh Statistics */ ret = libertas_prepare_and_send_command(priv, cmd_mesh_access, cmd_act_mesh_get_stats, cmd_option_waitforrsp, 0, &mesh_access); if (ret) { - LEAVE(); - return 0; + ret = 0; + goto done; } - priv->mstats.fwd_drop_rbt = mesh_access.data[0]; - priv->mstats.fwd_drop_ttl = mesh_access.data[1]; - priv->mstats.fwd_drop_noroute = mesh_access.data[2]; - priv->mstats.fwd_drop_nobuf = mesh_access.data[3]; - priv->mstats.fwd_unicast_cnt = mesh_access.data[4]; - priv->mstats.fwd_bcast_cnt = mesh_access.data[5]; - priv->mstats.drop_blind = mesh_access.data[6]; + priv->mstats.fwd_drop_rbt = le32_to_cpu(mesh_access.data[0]); + priv->mstats.fwd_drop_ttl = le32_to_cpu(mesh_access.data[1]); + priv->mstats.fwd_drop_noroute = le32_to_cpu(mesh_access.data[2]); + priv->mstats.fwd_drop_nobuf = le32_to_cpu(mesh_access.data[3]); + priv->mstats.fwd_unicast_cnt = le32_to_cpu(mesh_access.data[4]); + priv->mstats.fwd_bcast_cnt = le32_to_cpu(mesh_access.data[5]); + priv->mstats.drop_blind = le32_to_cpu(mesh_access.data[6]); + priv->mstats.tx_failed_cnt = le32_to_cpu(mesh_access.data[7]); - LEAVE(); - return MESH_STATS_NUM; + ret = MESH_STATS_NUM; + +done: + lbs_deb_enter_args(LBS_DEB_ETHTOOL, "ret %d", ret); + return ret; } static void libertas_ethtool_get_strings (struct net_device * dev, @@ -160,7 +168,8 @@ static void libertas_ethtool_get_strings (struct net_device * dev, { int i; - ENTER(); + lbs_deb_enter(LBS_DEB_ETHTOOL); + switch (stringset) { case ETH_SS_STATS: for (i=0; i < MESH_STATS_NUM; i++) { @@ -170,7 +179,7 @@ static void libertas_ethtool_get_strings (struct net_device * dev, } break; } - LEAVE(); + lbs_deb_enter(LBS_DEB_ETHTOOL); } struct ethtool_ops libertas_ethtool_ops = { diff --git a/drivers/net/wireless/libertas/fw.c b/drivers/net/wireless/libertas/fw.c index 5c63c9b1659..2dc84ff7a54 100644 --- a/drivers/net/wireless/libertas/fw.c +++ b/drivers/net/wireless/libertas/fw.c @@ -1,28 +1,15 @@ /** * This file contains the initialization for FW and HW */ -#include <linux/module.h> -#include <linux/moduleparam.h> - -#include <linux/vmalloc.h> #include <linux/firmware.h> -#include <linux/version.h> #include "host.h" -#include "sbi.h" #include "defs.h" #include "decl.h" #include "dev.h" -#include "fw.h" #include "wext.h" #include "if_usb.h" -char *libertas_fw_name = NULL; -module_param_named(fw_name, libertas_fw_name, charp, 0644); - -unsigned int libertas_debug = 0; -module_param(libertas_debug, int, 0); - /** * @brief This function checks the validity of Boot2/FW image. * @@ -32,7 +19,7 @@ module_param(libertas_debug, int, 0); */ static int check_fwfile_format(u8 *data, u32 totlen) { - u8 bincmd, exit; + u32 bincmd, exit; u32 blksize, offset, len; int ret; @@ -40,8 +27,10 @@ static int check_fwfile_format(u8 *data, u32 totlen) exit = len = 0; do { - bincmd = *data; - blksize = *(u32*)(data + offsetof(struct fwheader, datalength)); + struct fwheader *fwh = (void *)data; + + bincmd = le32_to_cpu(fwh->dnldcmd); + blksize = le32_to_cpu(fwh->datalength); switch (bincmd) { case FW_HAS_DATA_TO_RECV: offset = sizeof(struct fwheader) + blksize; @@ -61,9 +50,9 @@ static int check_fwfile_format(u8 *data, u32 totlen) } while (!exit); if (ret) - lbs_pr_err("bin file format check FAIL...\n"); + lbs_pr_err("firmware file format check FAIL\n"); else - lbs_pr_debug(1, "bin file format check PASS...\n"); + lbs_deb_fw("firmware file format check PASS\n"); return ret; } @@ -76,32 +65,31 @@ static int check_fwfile_format(u8 *data, u32 totlen) * @param priv A pointer to wlan_private structure * @return 0 or -1 */ -static int wlan_setup_station_hw(wlan_private * priv) +static int wlan_setup_station_hw(wlan_private * priv, char *fw_name) { int ret = -1; wlan_adapter *adapter = priv->adapter; - ENTER(); + lbs_deb_enter(LBS_DEB_FW); - if ((ret = request_firmware(&priv->firmware, libertas_fw_name, + if ((ret = request_firmware(&priv->firmware, fw_name, priv->hotplug_device)) < 0) { - lbs_pr_err("request_firmware() failed, error code = %#x\n", - ret); - lbs_pr_err("%s not found in /lib/firmware\n", libertas_fw_name); + lbs_pr_err("request_firmware() failed with %#x\n", ret); + lbs_pr_err("firmware %s not found\n", fw_name); goto done; } - if(check_fwfile_format(priv->firmware->data, priv->firmware->size)) { + if (check_fwfile_format(priv->firmware->data, priv->firmware->size)) { release_firmware(priv->firmware); goto done; } - ret = libertas_sbi_prog_firmware(priv); + ret = priv->hw_prog_firmware(priv); release_firmware(priv->firmware); if (ret) { - lbs_pr_debug(1, "Bootloader in invalid state!\n"); + lbs_deb_fw("bootloader in invalid state\n"); ret = -1; goto done; } @@ -133,28 +121,24 @@ static int wlan_setup_station_hw(wlan_private * priv) ret = 0; done: - LEAVE(); - - return (ret); + lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret); + return ret; } static int wlan_allocate_adapter(wlan_private * priv) { - u32 ulbufsize; + size_t bufsize; wlan_adapter *adapter = priv->adapter; - struct bss_descriptor *ptempscantable; - /* Allocate buffer to store the BSSID list */ - ulbufsize = sizeof(struct bss_descriptor) * MRVDRV_MAX_BSSID_LIST; - if (!(ptempscantable = kmalloc(ulbufsize, GFP_KERNEL))) { + bufsize = MAX_NETWORK_COUNT * sizeof(struct bss_descriptor); + adapter->networks = kzalloc(bufsize, GFP_KERNEL); + if (!adapter->networks) { + lbs_pr_err("Out of memory allocating beacons\n"); libertas_free_adapter(priv); - return -1; + return -ENOMEM; } - adapter->scantable = ptempscantable; - memset(adapter->scantable, 0, ulbufsize); - /* Allocate the command buffers */ libertas_allocate_cmd_buffer(priv); @@ -202,15 +186,23 @@ static void wlan_init_adapter(wlan_private * priv) adapter->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; adapter->mode = IW_MODE_INFRA; - adapter->assoc_req = NULL; + adapter->pending_assoc_req = NULL; + adapter->in_progress_assoc_req = NULL; + + /* Initialize scan result lists */ + INIT_LIST_HEAD(&adapter->network_free_list); + INIT_LIST_HEAD(&adapter->network_list); + for (i = 0; i < MAX_NETWORK_COUNT; i++) { + list_add_tail(&adapter->networks[i].list, + &adapter->network_free_list); + } - adapter->numinscantable = 0; - adapter->pattemptedbssdesc = NULL; mutex_init(&adapter->lock); adapter->prescan = 1; memset(&adapter->curbssparams, 0, sizeof(adapter->curbssparams)); + adapter->curbssparams.channel = DEFAULT_AD_HOC_CHANNEL; /* PnP and power profile */ adapter->surpriseremoved = 0; @@ -230,8 +222,6 @@ static void wlan_init_adapter(wlan_private * priv) memset(&adapter->capinfo, 0, sizeof(adapter->capinfo)); adapter->capinfo.shortpreamble = SHORT_PREAMBLE_ALLOWED; - adapter->adhocchannel = DEFAULT_AD_HOC_CHANNEL; - adapter->psmode = wlan802_11powermodecam; adapter->multipledtim = MRVDRV_DEFAULT_MULTIPLE_DTIM; @@ -259,12 +249,12 @@ static void wlan_init_adapter(wlan_private * priv) static void command_timer_fn(unsigned long data); -int libertas_init_fw(wlan_private * priv) +int libertas_init_fw(wlan_private * priv, char *fw_name) { int ret = -1; wlan_adapter *adapter = priv->adapter; - ENTER(); + lbs_deb_enter(LBS_DEB_FW); /* Allocate adapter structure */ if ((ret = wlan_allocate_adapter(priv)) != 0) @@ -278,7 +268,7 @@ int libertas_init_fw(wlan_private * priv) (unsigned long)priv); /* download fimrware etc. */ - if ((ret = wlan_setup_station_hw(priv)) != 0) { + if ((ret = wlan_setup_station_hw(priv, fw_name)) != 0) { del_timer_sync(&adapter->command_timer); goto done; } @@ -288,7 +278,7 @@ int libertas_init_fw(wlan_private * priv) ret = 0; done: - LEAVE(); + lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret); return ret; } @@ -297,25 +287,22 @@ void libertas_free_adapter(wlan_private * priv) wlan_adapter *adapter = priv->adapter; if (!adapter) { - lbs_pr_debug(1, "Why double free adapter?:)\n"); + lbs_deb_fw("why double free adapter?\n"); return; } - lbs_pr_debug(1, "Free command buffer\n"); + lbs_deb_fw("free command buffer\n"); libertas_free_cmd_buffer(priv); - lbs_pr_debug(1, "Free commandTimer\n"); + lbs_deb_fw("free command_timer\n"); del_timer(&adapter->command_timer); - lbs_pr_debug(1, "Free scantable\n"); - if (adapter->scantable) { - kfree(adapter->scantable); - adapter->scantable = NULL; - } - - lbs_pr_debug(1, "Free adapter\n"); + lbs_deb_fw("free scan results table\n"); + kfree(adapter->networks); + adapter->networks = NULL; /* Free the adapter object itself */ + lbs_deb_fw("free adapter\n"); kfree(adapter); priv->adapter = NULL; } @@ -334,17 +321,17 @@ static void command_timer_fn(unsigned long data) ptempnode = adapter->cur_cmd; if (ptempnode == NULL) { - lbs_pr_debug(1, "PTempnode Empty\n"); + lbs_deb_fw("ptempnode empty\n"); return; } cmd = (struct cmd_ds_command *)ptempnode->bufvirtualaddr; if (!cmd) { - lbs_pr_debug(1, "cmd is NULL\n"); + lbs_deb_fw("cmd is NULL\n"); return; } - lbs_pr_info("command_timer_fn fired (%x)\n", cmd->command); + lbs_deb_fw("command_timer_fn fired, cmd %x\n", cmd->command); if (!adapter->fw_ready) return; @@ -353,7 +340,7 @@ static void command_timer_fn(unsigned long data) adapter->cur_cmd = NULL; spin_unlock_irqrestore(&adapter->driver_lock, flags); - lbs_pr_debug(1, "Re-sending same command as it timeout...!\n"); + lbs_deb_fw("re-sending same command because of timeout\n"); libertas_queue_cmd(adapter, ptempnode, 0); wake_up_interruptible(&priv->mainthread.waitq); diff --git a/drivers/net/wireless/libertas/fw.h b/drivers/net/wireless/libertas/fw.h deleted file mode 100644 index 1f9ae267a9e..00000000000 --- a/drivers/net/wireless/libertas/fw.h +++ /dev/null @@ -1,13 +0,0 @@ -/** - * This header file contains FW interface related definitions. - */ -#ifndef _WLAN_FW_H_ -#define _WLAN_FW_H_ - -#ifndef DEV_NAME_LEN -#define DEV_NAME_LEN 32 -#endif - -int libertas_init_fw(wlan_private * priv); - -#endif /* _WLAN_FW_H_ */ diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h index c0faaecaf5b..7509cc10af3 100644 --- a/drivers/net/wireless/libertas/host.h +++ b/drivers/net/wireless/libertas/host.h @@ -99,11 +99,11 @@ #define cmd_bt_access 0x0087 #define cmd_ret_bt_access 0x8087 -#define cmd_fwt_access 0x0088 -#define cmd_ret_fwt_access 0x8088 +#define cmd_fwt_access 0x0095 +#define cmd_ret_fwt_access 0x8095 -#define cmd_mesh_access 0x0090 -#define cmd_ret_mesh_access 0x8090 +#define cmd_mesh_access 0x009b +#define cmd_ret_mesh_access 0x809b /* For the IEEE Power Save */ #define cmd_subcmd_enter_ps 0x0030 @@ -287,7 +287,9 @@ enum cmd_bt_access_opts { cmd_act_bt_access_add = 5, cmd_act_bt_access_del, cmd_act_bt_access_list, - cmd_act_bt_access_reset + cmd_act_bt_access_reset, + cmd_act_bt_access_set_invert, + cmd_act_bt_access_get_invert }; /* Define action or option for cmd_fwt_access */ @@ -308,8 +310,8 @@ enum cmd_mesh_access_opts { cmd_act_mesh_get_ttl = 1, cmd_act_mesh_set_ttl, cmd_act_mesh_get_stats, - cmd_act_mesh_get_mpp, - cmd_act_mesh_set_mpp, + cmd_act_mesh_get_anycast, + cmd_act_mesh_set_anycast, }; /** Card Event definition */ @@ -334,5 +336,6 @@ enum cmd_mesh_access_opts { #define MACREG_INT_CODE_MAX_FAIL 0x0000001b #define MACREG_INT_CODE_RSSI_HIGH 0x0000001c #define MACREG_INT_CODE_SNR_HIGH 0x0000001d +#define MACREG_INT_CODE_MESH_AUTO_STARTED 0x00000023 #endif /* _HOST_H_ */ diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h index f239e5d2435..09b898f6719 100644 --- a/drivers/net/wireless/libertas/hostcmd.h +++ b/drivers/net/wireless/libertas/hostcmd.h @@ -14,12 +14,12 @@ /* TxPD descriptor */ struct txpd { /* Current Tx packet status */ - u32 tx_status; + __le32 tx_status; /* Tx control */ - u32 tx_control; - u32 tx_packet_location; + __le32 tx_control; + __le32 tx_packet_location; /* Tx packet length */ - u16 tx_packet_length; + __le16 tx_packet_length; /* First 2 byte of destination MAC address */ u8 tx_dest_addr_high[2]; /* Last 4 byte of destination MAC address */ @@ -37,7 +37,7 @@ struct txpd { /* RxPD Descriptor */ struct rxpd { /* Current Rx packet status */ - u16 status; + __le16 status; /* SNR */ u8 snr; @@ -46,7 +46,7 @@ struct rxpd { u8 rx_control; /* Pkt length */ - u16 pkt_len; + __le16 pkt_len; /* Noise Floor */ u8 nf; @@ -55,10 +55,10 @@ struct rxpd { u8 rx_rate; /* Pkt addr */ - u32 pkt_ptr; + __le32 pkt_ptr; /* Next Rx RxPD addr */ - u32 next_rxpd_ptr; + __le32 next_rxpd_ptr; /* Pkt Priority */ u8 priority; @@ -89,30 +89,17 @@ struct cmd_ctrl_node { * is determined from the keylength field. */ struct WLAN_802_11_KEY { - u32 len; - u32 flags; /* KEY_INFO_* from wlan_defs.h */ + __le32 len; + __le32 flags; /* KEY_INFO_* from wlan_defs.h */ u8 key[MRVL_MAX_KEY_WPA_KEY_LENGTH]; - u16 type; /* KEY_TYPE_* from wlan_defs.h */ + __le16 type; /* KEY_TYPE_* from wlan_defs.h */ }; struct IE_WPA { u8 elementid; u8 len; u8 oui[4]; - u16 version; -}; - -struct WLAN_802_11_SSID { - /* SSID length */ - u32 ssidlength; - - /* SSID information field */ - u8 ssid[IW_ESSID_MAX_SIZE]; -}; - -struct WPA_SUPPLICANT { - u8 wpa_ie[256]; - u8 wpa_ie_len; + __le16 version; }; /* wlan_offset_value */ @@ -122,9 +109,9 @@ struct wlan_offset_value { }; struct WLAN_802_11_FIXED_IEs { - u8 timestamp[8]; - u16 beaconinterval; - u16 capabilities; + __le64 timestamp; + __le16 beaconinterval; + u16 capabilities; /* Actually struct ieeetypes_capinfo */ }; struct WLAN_802_11_VARIABLE_IEs { @@ -136,10 +123,10 @@ struct WLAN_802_11_VARIABLE_IEs { /* Define general data structure */ /* cmd_DS_GEN */ struct cmd_ds_gen { - u16 command; - u16 size; - u16 seqnum; - u16 result; + __le16 command; + __le16 size; + __le16 seqnum; + __le16 result; }; #define S_DS_GEN sizeof(struct cmd_ds_gen) @@ -149,44 +136,44 @@ struct cmd_ds_gen { */ struct cmd_ds_get_hw_spec { /* HW Interface version number */ - u16 hwifversion; + __le16 hwifversion; /* HW version number */ - u16 version; + __le16 version; /* Max number of TxPD FW can handle */ - u16 nr_txpd; + __le16 nr_txpd; /* Max no of Multicast address */ - u16 nr_mcast_adr; + __le16 nr_mcast_adr; /* MAC address */ u8 permanentaddr[6]; /* region Code */ - u16 regioncode; + __le16 regioncode; /* Number of antenna used */ - u16 nr_antenna; + __le16 nr_antenna; - /* FW release number, example 0x1234=1.2.3.4 */ - u32 fwreleasenumber; + /* FW release number, example 1,2,3,4 = 3.2.1p4 */ + u8 fwreleasenumber[4]; /* Base Address of TxPD queue */ - u32 wcb_base; + __le32 wcb_base; /* Read Pointer of RxPd queue */ - u32 rxpd_rdptr; + __le32 rxpd_rdptr; /* Write Pointer of RxPd queue */ - u32 rxpd_wrptr; + __le32 rxpd_wrptr; /*FW/HW capability */ - u32 fwcapinfo; + __le32 fwcapinfo; } __attribute__ ((packed)); struct cmd_ds_802_11_reset { - u16 action; + __le16 action; }; struct cmd_ds_802_11_subscribe_event { - u16 action; - u16 events; + __le16 action; + __le16 events; }; /* @@ -205,35 +192,35 @@ struct cmd_ds_802_11_scan { }; struct cmd_ds_802_11_scan_rsp { - u16 bssdescriptsize; + __le16 bssdescriptsize; u8 nr_sets; u8 bssdesc_and_tlvbuffer[1]; }; struct cmd_ds_802_11_get_log { - u32 mcasttxframe; - u32 failed; - u32 retry; - u32 multiretry; - u32 framedup; - u32 rtssuccess; - u32 rtsfailure; - u32 ackfailure; - u32 rxfrag; - u32 mcastrxframe; - u32 fcserror; - u32 txframe; - u32 wepundecryptable; + __le32 mcasttxframe; + __le32 failed; + __le32 retry; + __le32 multiretry; + __le32 framedup; + __le32 rtssuccess; + __le32 rtsfailure; + __le32 ackfailure; + __le32 rxfrag; + __le32 mcastrxframe; + __le32 fcserror; + __le32 txframe; + __le32 wepundecryptable; }; struct cmd_ds_mac_control { - u16 action; - u16 reserved; + __le16 action; + __le16 reserved; }; struct cmd_ds_mac_multicast_adr { - u16 action; - u16 nr_of_adrs; + __le16 action; + __le16 nr_of_adrs; u8 maclist[ETH_ALEN * MRVDRV_MAX_MULTICAST_LIST_SIZE]; }; @@ -245,14 +232,14 @@ struct cmd_ds_802_11_authenticate { struct cmd_ds_802_11_deauthenticate { u8 macaddr[6]; - u16 reasoncode; + __le16 reasoncode; }; struct cmd_ds_802_11_associate { u8 peerstaaddr[6]; struct ieeetypes_capinfo capinfo; - u16 listeninterval; - u16 bcnperiod; + __le16 listeninterval; + __le16 bcnperiod; u8 dtimperiod; #if 0 @@ -265,7 +252,7 @@ struct cmd_ds_802_11_associate { struct cmd_ds_802_11_disassociate { u8 destmacaddr[6]; - u16 reasoncode; + __le16 reasoncode; }; struct cmd_ds_802_11_associate_rsp { @@ -279,10 +266,10 @@ struct cmd_ds_802_11_ad_hoc_result { struct cmd_ds_802_11_set_wep { /* ACT_ADD, ACT_REMOVE or ACT_ENABLE */ - u16 action; + __le16 action; /* key Index selected for Tx */ - u16 keyindex; + __le16 keyindex; /* 40, 128bit or TXWEP */ u8 keytype[4]; @@ -290,96 +277,96 @@ struct cmd_ds_802_11_set_wep { }; struct cmd_ds_802_3_get_stat { - u32 xmitok; - u32 rcvok; - u32 xmiterror; - u32 rcverror; - u32 rcvnobuffer; - u32 rcvcrcerror; + __le32 xmitok; + __le32 rcvok; + __le32 xmiterror; + __le32 rcverror; + __le32 rcvnobuffer; + __le32 rcvcrcerror; }; struct cmd_ds_802_11_get_stat { - u32 txfragmentcnt; - u32 mcasttxframecnt; - u32 failedcnt; - u32 retrycnt; - u32 Multipleretrycnt; - u32 rtssuccesscnt; - u32 rtsfailurecnt; - u32 ackfailurecnt; - u32 frameduplicatecnt; - u32 rxfragmentcnt; - u32 mcastrxframecnt; - u32 fcserrorcnt; - u32 bcasttxframecnt; - u32 bcastrxframecnt; - u32 txbeacon; - u32 rxbeacon; - u32 wepundecryptable; + __le32 txfragmentcnt; + __le32 mcasttxframecnt; + __le32 failedcnt; + __le32 retrycnt; + __le32 Multipleretrycnt; + __le32 rtssuccesscnt; + __le32 rtsfailurecnt; + __le32 ackfailurecnt; + __le32 frameduplicatecnt; + __le32 rxfragmentcnt; + __le32 mcastrxframecnt; + __le32 fcserrorcnt; + __le32 bcasttxframecnt; + __le32 bcastrxframecnt; + __le32 txbeacon; + __le32 rxbeacon; + __le32 wepundecryptable; }; struct cmd_ds_802_11_snmp_mib { - u16 querytype; - u16 oid; - u16 bufsize; + __le16 querytype; + __le16 oid; + __le16 bufsize; u8 value[128]; }; struct cmd_ds_mac_reg_map { - u16 buffersize; + __le16 buffersize; u8 regmap[128]; - u16 reserved; + __le16 reserved; }; struct cmd_ds_bbp_reg_map { - u16 buffersize; + __le16 buffersize; u8 regmap[128]; - u16 reserved; + __le16 reserved; }; struct cmd_ds_rf_reg_map { - u16 buffersize; + __le16 buffersize; u8 regmap[64]; - u16 reserved; + __le16 reserved; }; struct cmd_ds_mac_reg_access { - u16 action; - u16 offset; - u32 value; + __le16 action; + __le16 offset; + __le32 value; }; struct cmd_ds_bbp_reg_access { - u16 action; - u16 offset; + __le16 action; + __le16 offset; u8 value; u8 reserved[3]; }; struct cmd_ds_rf_reg_access { - u16 action; - u16 offset; + __le16 action; + __le16 offset; u8 value; u8 reserved[3]; }; struct cmd_ds_802_11_radio_control { - u16 action; - u16 control; + __le16 action; + __le16 control; }; struct cmd_ds_802_11_sleep_params { /* ACT_GET/ACT_SET */ - u16 action; + __le16 action; /* Sleep clock error in ppm */ - u16 error; + __le16 error; /* Wakeup offset in usec */ - u16 offset; + __le16 offset; /* Clock stabilization time in usec */ - u16 stabletime; + __le16 stabletime; /* control periodic calibration */ u8 calcontrol; @@ -388,100 +375,100 @@ struct cmd_ds_802_11_sleep_params { u8 externalsleepclk; /* reserved field, should be set to zero */ - u16 reserved; + __le16 reserved; }; struct cmd_ds_802_11_inactivity_timeout { /* ACT_GET/ACT_SET */ - u16 action; + __le16 action; /* Inactivity timeout in msec */ - u16 timeout; + __le16 timeout; }; struct cmd_ds_802_11_rf_channel { - u16 action; - u16 currentchannel; - u16 rftype; - u16 reserved; + __le16 action; + __le16 currentchannel; + __le16 rftype; + __le16 reserved; u8 channellist[32]; }; struct cmd_ds_802_11_rssi { /* weighting factor */ - u16 N; + __le16 N; - u16 reserved_0; - u16 reserved_1; - u16 reserved_2; + __le16 reserved_0; + __le16 reserved_1; + __le16 reserved_2; }; struct cmd_ds_802_11_rssi_rsp { - u16 SNR; - u16 noisefloor; - u16 avgSNR; - u16 avgnoisefloor; + __le16 SNR; + __le16 noisefloor; + __le16 avgSNR; + __le16 avgnoisefloor; }; struct cmd_ds_802_11_mac_address { - u16 action; + __le16 action; u8 macadd[ETH_ALEN]; }; struct cmd_ds_802_11_rf_tx_power { - u16 action; - u16 currentlevel; + __le16 action; + __le16 currentlevel; }; struct cmd_ds_802_11_rf_antenna { - u16 action; + __le16 action; /* Number of antennas or 0xffff(diversity) */ - u16 antennamode; + __le16 antennamode; }; struct cmd_ds_802_11_ps_mode { - u16 action; - u16 nullpktinterval; - u16 multipledtim; - u16 reserved; - u16 locallisteninterval; + __le16 action; + __le16 nullpktinterval; + __le16 multipledtim; + __le16 reserved; + __le16 locallisteninterval; }; struct PS_CMD_ConfirmSleep { - u16 command; - u16 size; - u16 seqnum; - u16 result; + __le16 command; + __le16 size; + __le16 seqnum; + __le16 result; - u16 action; - u16 reserved1; - u16 multipledtim; - u16 reserved; - u16 locallisteninterval; + __le16 action; + __le16 reserved1; + __le16 multipledtim; + __le16 reserved; + __le16 locallisteninterval; }; struct cmd_ds_802_11_data_rate { - u16 action; - u16 reserverd; + __le16 action; + __le16 reserverd; u8 datarate[G_SUPPORTED_RATES]; }; struct cmd_ds_802_11_rate_adapt_rateset { - u16 action; - u16 enablehwauto; - u16 bitmap; + __le16 action; + __le16 enablehwauto; + __le16 bitmap; }; struct cmd_ds_802_11_ad_hoc_start { u8 SSID[IW_ESSID_MAX_SIZE]; u8 bsstype; - u16 beaconperiod; + __le16 beaconperiod; u8 dtimperiod; union IEEEtypes_ssparamset ssparamset; union ieeetypes_phyparamset phyparamset; - u16 probedelay; + __le16 probedelay; struct ieeetypes_capinfo cap; u8 datarate[G_SUPPORTED_RATES]; u8 tlv_memory_size_pad[100]; @@ -491,10 +478,10 @@ struct adhoc_bssdesc { u8 BSSID[6]; u8 SSID[32]; u8 bsstype; - u16 beaconperiod; + __le16 beaconperiod; u8 dtimperiod; - u8 timestamp[8]; - u8 localtime[8]; + __le64 timestamp; + __le64 localtime; union ieeetypes_phyparamset phyparamset; union IEEEtypes_ssparamset ssparamset; struct ieeetypes_capinfo cap; @@ -508,52 +495,52 @@ struct adhoc_bssdesc { struct cmd_ds_802_11_ad_hoc_join { struct adhoc_bssdesc bssdescriptor; - u16 failtimeout; - u16 probedelay; + __le16 failtimeout; + __le16 probedelay; } __attribute__ ((packed)); struct cmd_ds_802_11_enable_rsn { - u16 action; - u16 enable; -}; + __le16 action; + __le16 enable; +} __attribute__ ((packed)); struct MrvlIEtype_keyParamSet { /* type ID */ - u16 type; + __le16 type; /* length of Payload */ - u16 length; + __le16 length; /* type of key: WEP=0, TKIP=1, AES=2 */ - u16 keytypeid; + __le16 keytypeid; /* key control Info specific to a keytypeid */ - u16 keyinfo; + __le16 keyinfo; /* length of key */ - u16 keylen; + __le16 keylen; /* key material of size keylen */ u8 key[32]; }; struct cmd_ds_802_11_key_material { - u16 action; + __le16 action; struct MrvlIEtype_keyParamSet keyParamSet[2]; } __attribute__ ((packed)); struct cmd_ds_802_11_eeprom_access { - u16 action; + __le16 action; /* multiple 4 */ - u16 offset; - u16 bytecount; + __le16 offset; + __le16 bytecount; u8 value; } __attribute__ ((packed)); struct cmd_ds_802_11_tpc_cfg { - u16 action; + __le16 action; u8 enable; s8 P0; s8 P1; @@ -562,13 +549,13 @@ struct cmd_ds_802_11_tpc_cfg { } __attribute__ ((packed)); struct cmd_ds_802_11_led_ctrl { - u16 action; - u16 numled; + __le16 action; + __le16 numled; u8 data[256]; } __attribute__ ((packed)); struct cmd_ds_802_11_pwr_cfg { - u16 action; + __le16 action; u8 enable; s8 PA_P0; s8 PA_P1; @@ -576,21 +563,21 @@ struct cmd_ds_802_11_pwr_cfg { } __attribute__ ((packed)); struct cmd_ds_802_11_afc { - u16 afc_auto; + __le16 afc_auto; union { struct { - u16 threshold; - u16 period; + __le16 threshold; + __le16 period; }; struct { - s16 timing_offset; - s16 carrier_offset; + __le16 timing_offset; /* signed */ + __le16 carrier_offset; /* signed */ }; }; } __attribute__ ((packed)); struct cmd_tx_rate_query { - u16 txrate; + __le16 txrate; } __attribute__ ((packed)); struct cmd_ds_get_tsf { @@ -598,41 +585,46 @@ struct cmd_ds_get_tsf { } __attribute__ ((packed)); struct cmd_ds_bt_access { - u16 action; - u32 id; + __le16 action; + __le32 id; u8 addr1[ETH_ALEN]; u8 addr2[ETH_ALEN]; } __attribute__ ((packed)); struct cmd_ds_fwt_access { - u16 action; - u32 id; + __le16 action; + __le32 id; + u8 valid; u8 da[ETH_ALEN]; u8 dir; u8 ra[ETH_ALEN]; - u32 ssn; - u32 dsn; - u32 metric; + __le32 ssn; + __le32 dsn; + __le32 metric; + u8 rate; u8 hopcount; u8 ttl; - u32 expiration; + __le32 expiration; u8 sleepmode; - u32 snr; - u32 references; + __le32 snr; + __le32 references; + u8 prec[ETH_ALEN]; } __attribute__ ((packed)); -#define MESH_STATS_NUM 7 struct cmd_ds_mesh_access { - u16 action; - u32 data[MESH_STATS_NUM + 1]; /* last position reserved */ + __le16 action; + __le32 data[32]; /* last position reserved */ } __attribute__ ((packed)); +/* Number of stats counters returned by the firmware */ +#define MESH_STATS_NUM 8 + struct cmd_ds_command { /* command header */ - u16 command; - u16 size; - u16 seqnum; - u16 result; + __le16 command; + __le16 size; + __le16 seqnum; + __le16 result; /* command Body */ union { diff --git a/drivers/net/wireless/libertas/if_bootcmd.c b/drivers/net/wireless/libertas/if_bootcmd.c index 567000c3e87..8bca306ffad 100644 --- a/drivers/net/wireless/libertas/if_bootcmd.c +++ b/drivers/net/wireless/libertas/if_bootcmd.c @@ -8,6 +8,8 @@ #include <linux/netdevice.h> #include <linux/usb.h> +#define DRV_NAME "usb8xxx" + #include "defs.h" #include "dev.h" #include "if_usb.h" @@ -20,12 +22,12 @@ */ int if_usb_issue_boot_command(wlan_private *priv, int ivalue) { - struct usb_card_rec *cardp = priv->wlan_dev.card; + struct usb_card_rec *cardp = priv->card; struct bootcmdstr sbootcmd; int i; /* Prepare command */ - sbootcmd.u32magicnumber = BOOT_CMD_MAGIC_NUMBER; + sbootcmd.u32magicnumber = cpu_to_le32(BOOT_CMD_MAGIC_NUMBER); sbootcmd.u8cmd_tag = ivalue; for (i=0; i<11; i++) sbootcmd.au8dumy[i]=0x00; diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c index ae6f72a6cdf..998317571ec 100644 --- a/drivers/net/wireless/libertas/if_usb.c +++ b/drivers/net/wireless/libertas/if_usb.c @@ -2,12 +2,15 @@ * This file contains functions used in USB interface module. */ #include <linux/delay.h> +#include <linux/moduleparam.h> #include <linux/firmware.h> #include <linux/netdevice.h> +#include <linux/list.h> #include <linux/usb.h> +#define DRV_NAME "usb8xxx" + #include "host.h" -#include "sbi.h" #include "decl.h" #include "defs.h" #include "dev.h" @@ -16,15 +19,24 @@ #define MESSAGE_HEADER_LEN 4 static const char usbdriver_name[] = "usb8xxx"; +static u8 *default_fw_name = "usb8388.bin"; + +char *libertas_fw_name = NULL; +module_param_named(fw_name, libertas_fw_name, charp, 0644); + +/* + * We need to send a RESET command to all USB devices before + * we tear down the USB connection. Otherwise we would not + * be able to re-init device the device if the module gets + * loaded again. This is a list of all initialized USB devices, + * for the reset code see if_usb_reset_device() +*/ +static LIST_HEAD(usb_devices); static struct usb_device_id if_usb_table[] = { /* Enter the device signature inside */ - { - USB_DEVICE(USB8388_VID_1, USB8388_PID_1), - }, - { - USB_DEVICE(USB8388_VID_2, USB8388_PID_2), - }, + { USB_DEVICE(0x1286, 0x2001) }, + { USB_DEVICE(0x05a3, 0x8388) }, {} /* Terminating entry */ }; @@ -32,6 +44,13 @@ MODULE_DEVICE_TABLE(usb, if_usb_table); static void if_usb_receive(struct urb *urb); static void if_usb_receive_fwload(struct urb *urb); +static int if_usb_reset_device(wlan_private *priv); +static int if_usb_register_dev(wlan_private * priv); +static int if_usb_unregister_dev(wlan_private *); +static int if_usb_prog_firmware(wlan_private *); +static int if_usb_host_to_card(wlan_private * priv, u8 type, u8 * payload, u16 nb); +static int if_usb_get_int_status(wlan_private * priv, u8 *); +static int if_usb_read_event_cause(wlan_private *); /** * @brief call back function to handle the status of the URB @@ -42,23 +61,27 @@ static void if_usb_write_bulk_callback(struct urb *urb) { wlan_private *priv = (wlan_private *) (urb->context); wlan_adapter *adapter = priv->adapter; - struct net_device *dev = priv->wlan_dev.netdev; + struct net_device *dev = priv->dev; /* handle the transmission complete validations */ if (urb->status != 0) { /* print the failure status number for debug */ - lbs_pr_info("URB in failure status\n"); + lbs_pr_info("URB in failure status: %d\n", urb->status); } else { - lbs_dev_dbg(2, &urb->dev->dev, "URB status is successfull\n"); - lbs_dev_dbg(2, &urb->dev->dev, "Actual length transmitted %d\n", + /* + lbs_deb_usbd(&urb->dev->dev, "URB status is successfull\n"); + lbs_deb_usbd(&urb->dev->dev, "Actual length transmitted %d\n", urb->actual_length); - priv->wlan_dev.dnld_sent = DNLD_RES_RECEIVED; + */ + priv->dnld_sent = DNLD_RES_RECEIVED; /* Wake main thread if commands are pending */ if (!adapter->cur_cmd) wake_up_interruptible(&priv->mainthread.waitq); - if ((adapter->connect_status == libertas_connected)) + if ((adapter->connect_status == libertas_connected)) { netif_wake_queue(dev); + netif_wake_queue(priv->mesh_dev); + } } return; @@ -71,7 +94,7 @@ static void if_usb_write_bulk_callback(struct urb *urb) */ void if_usb_free(struct usb_card_rec *cardp) { - ENTER(); + lbs_deb_enter(LBS_DEB_USB); /* Unlink tx & rx urb */ usb_kill_urb(cardp->tx_urb); @@ -86,8 +109,7 @@ void if_usb_free(struct usb_card_rec *cardp) kfree(cardp->bulk_out_buffer); cardp->bulk_out_buffer = NULL; - LEAVE(); - return; + lbs_deb_leave(LBS_DEB_USB); } /** @@ -102,27 +124,27 @@ static int if_usb_probe(struct usb_interface *intf, struct usb_device *udev; struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; - wlan_private *pwlanpriv; - struct usb_card_rec *usb_cardp; + wlan_private *priv; + struct usb_card_rec *cardp; int i; udev = interface_to_usbdev(intf); - usb_cardp = kzalloc(sizeof(struct usb_card_rec), GFP_KERNEL); - if (!usb_cardp) { + cardp = kzalloc(sizeof(struct usb_card_rec), GFP_KERNEL); + if (!cardp) { lbs_pr_err("Out of memory allocating private data.\n"); goto error; } - usb_cardp->udev = udev; + cardp->udev = udev; iface_desc = intf->cur_altsetting; - lbs_dev_dbg(1, &udev->dev, "bcdUSB = 0x%X bDeviceClass = 0x%X" + lbs_deb_usbd(&udev->dev, "bcdUSB = 0x%X bDeviceClass = 0x%X" " bDeviceSubClass = 0x%X, bDeviceProtocol = 0x%X\n", - udev->descriptor.bcdUSB, - udev->descriptor.bDeviceClass, - udev->descriptor.bDeviceSubClass, - udev->descriptor.bDeviceProtocol); + le16_to_cpu(udev->descriptor.bcdUSB), + udev->descriptor.bDeviceClass, + udev->descriptor.bDeviceSubClass, + udev->descriptor.bDeviceProtocol); for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { endpoint = &iface_desc->endpoint[i].desc; @@ -130,23 +152,21 @@ static int if_usb_probe(struct usb_interface *intf, && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)) { /* we found a bulk in endpoint */ - lbs_dev_dbg(1, &udev->dev, "Bulk in size is %d\n", - endpoint->wMaxPacketSize); - if (! - (usb_cardp->rx_urb = - usb_alloc_urb(0, GFP_KERNEL))) { - lbs_dev_dbg(1, &udev->dev, + lbs_deb_usbd(&udev->dev, "Bulk in size is %d\n", + le16_to_cpu(endpoint->wMaxPacketSize)); + if (!(cardp->rx_urb = usb_alloc_urb(0, GFP_KERNEL))) { + lbs_deb_usbd(&udev->dev, "Rx URB allocation failed\n"); goto dealloc; } - usb_cardp->rx_urb_recall = 0; + cardp->rx_urb_recall = 0; - usb_cardp->bulk_in_size = - endpoint->wMaxPacketSize; - usb_cardp->bulk_in_endpointAddr = + cardp->bulk_in_size = + le16_to_cpu(endpoint->wMaxPacketSize); + cardp->bulk_in_endpointAddr = (endpoint-> bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); - lbs_dev_dbg(1, &udev->dev, "in_endpoint = %d\n", + lbs_deb_usbd(&udev->dev, "in_endpoint = %d\n", endpoint->bEndpointAddress); } @@ -156,55 +176,63 @@ static int if_usb_probe(struct usb_interface *intf, && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)) { /* We found bulk out endpoint */ - if (! - (usb_cardp->tx_urb = - usb_alloc_urb(0, GFP_KERNEL))) { - lbs_dev_dbg(1,&udev->dev, + if (!(cardp->tx_urb = usb_alloc_urb(0, GFP_KERNEL))) { + lbs_deb_usbd(&udev->dev, "Tx URB allocation failed\n"); goto dealloc; } - usb_cardp->bulk_out_size = - endpoint->wMaxPacketSize; - lbs_dev_dbg(1, &udev->dev, - "Bulk out size is %d\n", - endpoint->wMaxPacketSize); - usb_cardp->bulk_out_endpointAddr = + cardp->bulk_out_size = + le16_to_cpu(endpoint->wMaxPacketSize); + lbs_deb_usbd(&udev->dev, + "Bulk out size is %d\n", + le16_to_cpu(endpoint->wMaxPacketSize)); + cardp->bulk_out_endpointAddr = endpoint->bEndpointAddress; - lbs_dev_dbg(1, &udev->dev, "out_endpoint = %d\n", + lbs_deb_usbd(&udev->dev, "out_endpoint = %d\n", endpoint->bEndpointAddress); - usb_cardp->bulk_out_buffer = + cardp->bulk_out_buffer = kmalloc(MRVDRV_ETH_TX_PACKET_BUFFER_SIZE, GFP_KERNEL); - if (!usb_cardp->bulk_out_buffer) { - lbs_dev_dbg(1, &udev->dev, + if (!cardp->bulk_out_buffer) { + lbs_deb_usbd(&udev->dev, "Could not allocate buffer\n"); goto dealloc; } } } - - /* At this point wlan_add_card() will be called. Don't worry - * about keeping pwlanpriv around since it will be set on our - * usb device data in -> add() -> libertas_sbi_register_dev(). - */ - if (!(pwlanpriv = wlan_add_card(usb_cardp))) + if (!(priv = libertas_add_card(cardp, &udev->dev))) goto dealloc; + if (libertas_add_mesh(priv, &udev->dev)) + goto err_add_mesh; + + priv->hw_register_dev = if_usb_register_dev; + priv->hw_unregister_dev = if_usb_unregister_dev; + priv->hw_prog_firmware = if_usb_prog_firmware; + priv->hw_host_to_card = if_usb_host_to_card; + priv->hw_get_int_status = if_usb_get_int_status; + priv->hw_read_event_cause = if_usb_read_event_cause; + + if (libertas_activate_card(priv, libertas_fw_name)) + goto err_activate_card; + + list_add_tail(&cardp->list, &usb_devices); + usb_get_dev(udev); - usb_set_intfdata(intf, usb_cardp); + usb_set_intfdata(intf, cardp); - /* - * return card structure, which can be got back in the - * diconnect function as the ptr - * argument. - */ return 0; +err_activate_card: + libertas_remove_mesh(priv); +err_add_mesh: + free_netdev(priv->dev); + kfree(priv->adapter); dealloc: - if_usb_free(usb_cardp); + if_usb_free(cardp); error: return -ENOMEM; @@ -212,8 +240,7 @@ error: /** * @brief free resource and cleanup - * @param udev pointer to usb_device - * @param ptr pointer to usb_cardp + * @param intf USB interface structure * @return N/A */ static void if_usb_disconnect(struct usb_interface *intf) @@ -229,9 +256,12 @@ static void if_usb_disconnect(struct usb_interface *intf) */ adapter->surpriseremoved = 1; + list_del(&cardp->list); + /* card is removed and we can call wlan_remove_card */ - lbs_dev_dbg(1, &cardp->udev->dev, "call remove card\n"); - wlan_remove_card(cardp); + lbs_deb_usbd(&cardp->udev->dev, "call remove card\n"); + libertas_remove_mesh(priv); + libertas_remove_card(priv); /* Unlink and free urb */ if_usb_free(cardp); @@ -249,7 +279,7 @@ static void if_usb_disconnect(struct usb_interface *intf) */ static int if_prog_firmware(wlan_private * priv) { - struct usb_card_rec *cardp = priv->wlan_dev.card; + struct usb_card_rec *cardp = priv->card; struct FWData *fwdata; struct fwheader *fwheader; u8 *firmware = priv->firmware->data; @@ -266,8 +296,10 @@ static int if_prog_firmware(wlan_private * priv) cardp->fwseqnum = cardp->lastseqnum - 1; } - lbs_dev_dbg(2, &cardp->udev->dev, "totalbytes = %d\n", + /* + lbs_deb_usbd(&cardp->udev->dev, "totalbytes = %d\n", cardp->totalbytes); + */ memcpy(fwheader, &firmware[cardp->totalbytes], sizeof(struct fwheader)); @@ -275,40 +307,48 @@ static int if_prog_firmware(wlan_private * priv) cardp->fwlastblksent = cardp->totalbytes; cardp->totalbytes += sizeof(struct fwheader); - lbs_dev_dbg(2, &cardp->udev->dev,"Copy Data\n"); + /* lbs_deb_usbd(&cardp->udev->dev,"Copy Data\n"); */ memcpy(fwdata->data, &firmware[cardp->totalbytes], - fwdata->fwheader.datalength); + le32_to_cpu(fwdata->fwheader.datalength)); - lbs_dev_dbg(2, &cardp->udev->dev, - "Data length = %d\n", fwdata->fwheader.datalength); + /* + lbs_deb_usbd(&cardp->udev->dev, + "Data length = %d\n", le32_to_cpu(fwdata->fwheader.datalength)); + */ cardp->fwseqnum = cardp->fwseqnum + 1; - fwdata->seqnum = cardp->fwseqnum; - cardp->lastseqnum = fwdata->seqnum; - cardp->totalbytes += fwdata->fwheader.datalength; + fwdata->seqnum = cpu_to_le32(cardp->fwseqnum); + cardp->lastseqnum = cardp->fwseqnum; + cardp->totalbytes += le32_to_cpu(fwdata->fwheader.datalength); - if (fwheader->dnldcmd == FW_HAS_DATA_TO_RECV) { - lbs_dev_dbg(2, &cardp->udev->dev, "There is data to follow\n"); - lbs_dev_dbg(2, &cardp->udev->dev, + if (fwheader->dnldcmd == cpu_to_le32(FW_HAS_DATA_TO_RECV)) { + /* + lbs_deb_usbd(&cardp->udev->dev, "There are data to follow\n"); + lbs_deb_usbd(&cardp->udev->dev, "seqnum = %d totalbytes = %d\n", cardp->fwseqnum, cardp->totalbytes); + */ memcpy(cardp->bulk_out_buffer, fwheader, FW_DATA_XMIT_SIZE); usb_tx_block(priv, cardp->bulk_out_buffer, FW_DATA_XMIT_SIZE); - } else if (fwdata->fwheader.dnldcmd == FW_HAS_LAST_BLOCK) { - lbs_dev_dbg(2, &cardp->udev->dev, + } else if (fwdata->fwheader.dnldcmd == cpu_to_le32(FW_HAS_LAST_BLOCK)) { + /* + lbs_deb_usbd(&cardp->udev->dev, "Host has finished FW downloading\n"); - lbs_dev_dbg(2, &cardp->udev->dev, + lbs_deb_usbd(&cardp->udev->dev, "Donwloading FW JUMP BLOCK\n"); + */ memcpy(cardp->bulk_out_buffer, fwheader, FW_DATA_XMIT_SIZE); usb_tx_block(priv, cardp->bulk_out_buffer, FW_DATA_XMIT_SIZE); cardp->fwfinalblk = 1; } - lbs_dev_dbg(2, &cardp->udev->dev, + /* + lbs_deb_usbd(&cardp->udev->dev, "The firmware download is done size is %d\n", cardp->totalbytes); + */ kfree(fwdata); @@ -318,14 +358,19 @@ static int if_prog_firmware(wlan_private * priv) static int libertas_do_reset(wlan_private *priv) { int ret; - struct usb_card_rec *cardp = priv->wlan_dev.card; + struct usb_card_rec *cardp = priv->card; + + lbs_deb_enter(LBS_DEB_USB); ret = usb_reset_device(cardp->udev); if (!ret) { msleep(10); - reset_device(priv); + if_usb_reset_device(priv); msleep(10); } + + lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret); + return ret; } @@ -339,12 +384,12 @@ static int libertas_do_reset(wlan_private *priv) int usb_tx_block(wlan_private * priv, u8 * payload, u16 nb) { /* pointer to card structure */ - struct usb_card_rec *cardp = priv->wlan_dev.card; + struct usb_card_rec *cardp = priv->card; int ret = -1; /* check if device is removed */ if (priv->adapter->surpriseremoved) { - lbs_dev_dbg(1, &cardp->udev->dev, "Device removed\n"); + lbs_deb_usbd(&cardp->udev->dev, "Device removed\n"); goto tx_ret; } @@ -357,10 +402,10 @@ int usb_tx_block(wlan_private * priv, u8 * payload, u16 nb) if ((ret = usb_submit_urb(cardp->tx_urb, GFP_ATOMIC))) { /* transfer failed */ - lbs_dev_dbg(1, &cardp->udev->dev, "usb_submit_urb failed\n"); + lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb failed\n"); ret = -1; } else { - lbs_dev_dbg(2, &cardp->udev->dev, "usb_submit_urb success\n"); + /* lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb success\n"); */ ret = 0; } @@ -372,7 +417,7 @@ static int __if_usb_submit_rx_urb(wlan_private * priv, void (*callbackfn) (struct urb *urb)) { - struct usb_card_rec *cardp = priv->wlan_dev.card; + struct usb_card_rec *cardp = priv->card; struct sk_buff *skb; struct read_cb_info *rinfo = &cardp->rinfo; int ret = -1; @@ -394,13 +439,13 @@ static int __if_usb_submit_rx_urb(wlan_private * priv, cardp->rx_urb->transfer_flags |= URB_ZERO_PACKET; - lbs_dev_dbg(2, &cardp->udev->dev, "Pointer for rx_urb %p\n", cardp->rx_urb); + /* lbs_deb_usbd(&cardp->udev->dev, "Pointer for rx_urb %p\n", cardp->rx_urb); */ if ((ret = usb_submit_urb(cardp->rx_urb, GFP_ATOMIC))) { /* handle failure conditions */ - lbs_dev_dbg(1, &cardp->udev->dev, "Submit Rx URB failed\n"); + lbs_deb_usbd(&cardp->udev->dev, "Submit Rx URB failed\n"); ret = -1; } else { - lbs_dev_dbg(2, &cardp->udev->dev, "Submit Rx URB success\n"); + /* lbs_deb_usbd(&cardp->udev->dev, "Submit Rx URB success\n"); */ ret = 0; } @@ -423,12 +468,12 @@ static void if_usb_receive_fwload(struct urb *urb) struct read_cb_info *rinfo = (struct read_cb_info *)urb->context; wlan_private *priv = rinfo->priv; struct sk_buff *skb = rinfo->skb; - struct usb_card_rec *cardp = (struct usb_card_rec *)priv->wlan_dev.card; + struct usb_card_rec *cardp = (struct usb_card_rec *)priv->card; struct fwsyncheader *syncfwheader; struct bootcmdrespStr bootcmdresp; if (urb->status) { - lbs_dev_dbg(1, &cardp->udev->dev, + lbs_deb_usbd(&cardp->udev->dev, "URB status is failed during fw load\n"); kfree_skb(skb); return; @@ -437,18 +482,18 @@ static void if_usb_receive_fwload(struct urb *urb) if (cardp->bootcmdresp == 0) { memcpy (&bootcmdresp, skb->data + IPFIELD_ALIGN_OFFSET, sizeof(bootcmdresp)); - if (cardp->udev->descriptor.bcdDevice < 0x3106) { + if (le16_to_cpu(cardp->udev->descriptor.bcdDevice) < 0x3106) { kfree_skb(skb); if_usb_submit_rx_urb_fwload(priv); cardp->bootcmdresp = 1; - lbs_dev_dbg(1, &cardp->udev->dev, + lbs_deb_usbd(&cardp->udev->dev, "Received valid boot command response\n"); return; } - if (bootcmdresp.u32magicnumber != BOOT_CMD_MAGIC_NUMBER) { + if (bootcmdresp.u32magicnumber != cpu_to_le32(BOOT_CMD_MAGIC_NUMBER)) { lbs_pr_info( "boot cmd response wrong magic number (0x%x)\n", - bootcmdresp.u32magicnumber); + le32_to_cpu(bootcmdresp.u32magicnumber)); } else if (bootcmdresp.u8cmd_tag != BOOT_CMD_FW_BY_USB) { lbs_pr_info( "boot cmd response cmd_tag error (%d)\n", @@ -459,7 +504,7 @@ static void if_usb_receive_fwload(struct urb *urb) bootcmdresp.u8result); } else { cardp->bootcmdresp = 1; - lbs_dev_dbg(1, &cardp->udev->dev, + lbs_deb_usbd(&cardp->udev->dev, "Received valid boot command response\n"); } kfree_skb(skb); @@ -469,7 +514,7 @@ static void if_usb_receive_fwload(struct urb *urb) syncfwheader = kmalloc(sizeof(struct fwsyncheader), GFP_ATOMIC); if (!syncfwheader) { - lbs_dev_dbg(1, &cardp->udev->dev, "Failure to allocate syncfwheader\n"); + lbs_deb_usbd(&cardp->udev->dev, "Failure to allocate syncfwheader\n"); kfree_skb(skb); return; } @@ -478,14 +523,16 @@ static void if_usb_receive_fwload(struct urb *urb) sizeof(struct fwsyncheader)); if (!syncfwheader->cmd) { - lbs_dev_dbg(2, &cardp->udev->dev, + /* + lbs_deb_usbd(&cardp->udev->dev, "FW received Blk with correct CRC\n"); - lbs_dev_dbg(2, &cardp->udev->dev, + lbs_deb_usbd(&cardp->udev->dev, "FW received Blk seqnum = %d\n", syncfwheader->seqnum); + */ cardp->CRC_OK = 1; } else { - lbs_dev_dbg(1, &cardp->udev->dev, + lbs_deb_usbd(&cardp->udev->dev, "FW received Blk with CRC error\n"); cardp->CRC_OK = 0; } @@ -515,7 +562,7 @@ static inline void process_cmdtypedata(int recvlength, struct sk_buff *skb, { if (recvlength > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE + MESSAGE_HEADER_LEN || recvlength < MRVDRV_MIN_PKT_LEN) { - lbs_dev_dbg(1, &cardp->udev->dev, + lbs_deb_usbd(&cardp->udev->dev, "Packet length is Invalid\n"); kfree_skb(skb); return; @@ -525,7 +572,7 @@ static inline void process_cmdtypedata(int recvlength, struct sk_buff *skb, skb_put(skb, recvlength); skb_pull(skb, MESSAGE_HEADER_LEN); libertas_process_rxed_packet(priv, skb); - priv->wlan_dev.upld_len = (recvlength - MESSAGE_HEADER_LEN); + priv->upld_len = (recvlength - MESSAGE_HEADER_LEN); } static inline void process_cmdrequest(int recvlength, u8 *recvbuff, @@ -535,7 +582,7 @@ static inline void process_cmdrequest(int recvlength, u8 *recvbuff, { u8 *cmdbuf; if (recvlength > MRVDRV_SIZE_OF_CMD_BUFFER) { - lbs_dev_dbg(1, &cardp->udev->dev, + lbs_deb_usbd(&cardp->udev->dev, "The receive buffer is too large\n"); kfree_skb(skb); return; @@ -548,21 +595,21 @@ static inline void process_cmdrequest(int recvlength, u8 *recvbuff, /* take care of cur_cmd = NULL case by reading the * data to clear the interrupt */ if (!priv->adapter->cur_cmd) { - cmdbuf = priv->wlan_dev.upld_buf; + cmdbuf = priv->upld_buf; priv->adapter->hisregcpy &= ~his_cmdupldrdy; } else cmdbuf = priv->adapter->cur_cmd->bufvirtualaddr; cardp->usb_int_cause |= his_cmdupldrdy; - priv->wlan_dev.upld_len = (recvlength - MESSAGE_HEADER_LEN); + priv->upld_len = (recvlength - MESSAGE_HEADER_LEN); memcpy(cmdbuf, recvbuff + MESSAGE_HEADER_LEN, - priv->wlan_dev.upld_len); + priv->upld_len); kfree_skb(skb); - libertas_interrupt(priv->wlan_dev.netdev); + libertas_interrupt(priv->dev); spin_unlock(&priv->adapter->driver_lock); - lbs_dev_dbg(1, &cardp->udev->dev, + lbs_deb_usbd(&cardp->udev->dev, "Wake up main thread to handle cmd response\n"); return; @@ -580,17 +627,17 @@ static void if_usb_receive(struct urb *urb) struct read_cb_info *rinfo = (struct read_cb_info *)urb->context; wlan_private *priv = rinfo->priv; struct sk_buff *skb = rinfo->skb; - struct usb_card_rec *cardp = (struct usb_card_rec *)priv->wlan_dev.card; + struct usb_card_rec *cardp = (struct usb_card_rec *)priv->card; int recvlength = urb->actual_length; u8 *recvbuff = NULL; u32 recvtype; - ENTER(); + lbs_deb_enter(LBS_DEB_USB); if (recvlength) { if (urb->status) { - lbs_dev_dbg(1, &cardp->udev->dev, + lbs_deb_usbd(&cardp->udev->dev, "URB status is failed\n"); kfree_skb(skb); goto setup_for_next; @@ -598,12 +645,12 @@ static void if_usb_receive(struct urb *urb) recvbuff = skb->data + IPFIELD_ALIGN_OFFSET; memcpy(&recvtype, recvbuff, sizeof(u32)); - lbs_dev_dbg(1, &cardp->udev->dev, + lbs_deb_usbd(&cardp->udev->dev, "Recv length = 0x%x\n", recvlength); - lbs_dev_dbg(1, &cardp->udev->dev, + lbs_deb_usbd(&cardp->udev->dev, "Receive type = 0x%X\n", recvtype); recvtype = le32_to_cpu(recvtype); - lbs_dev_dbg(1, &cardp->udev->dev, + lbs_deb_usbd(&cardp->udev->dev, "Receive type after = 0x%X\n", recvtype); } else if (urb->status) goto rx_exit; @@ -621,18 +668,18 @@ static void if_usb_receive(struct urb *urb) case CMD_TYPE_INDICATION: /* Event cause handling */ spin_lock(&priv->adapter->driver_lock); - cardp->usb_event_cause = *(u32 *) (recvbuff + MESSAGE_HEADER_LEN); - lbs_dev_dbg(1, &cardp->udev->dev,"**EVENT** 0x%X\n", + cardp->usb_event_cause = le32_to_cpu(*(__le32 *) (recvbuff + MESSAGE_HEADER_LEN)); + lbs_deb_usbd(&cardp->udev->dev,"**EVENT** 0x%X\n", cardp->usb_event_cause); if (cardp->usb_event_cause & 0xffff0000) { libertas_send_tx_feedback(priv); spin_unlock(&priv->adapter->driver_lock); break; } - cardp->usb_event_cause = le32_to_cpu(cardp->usb_event_cause) << 3; + cardp->usb_event_cause <<= 3; cardp->usb_int_cause |= his_cardevent; kfree_skb(skb); - libertas_interrupt(priv->wlan_dev.netdev); + libertas_interrupt(priv->dev); spin_unlock(&priv->adapter->driver_lock); goto rx_exit; default: @@ -643,8 +690,7 @@ static void if_usb_receive(struct urb *urb) setup_for_next: if_usb_submit_rx_urb(priv); rx_exit: - LEAVE(); - return; + lbs_deb_leave(LBS_DEB_USB); } /** @@ -655,24 +701,24 @@ rx_exit: * @param len number of bytes * @return 0 or -1 */ -int libertas_sbi_host_to_card(wlan_private * priv, u8 type, u8 * payload, u16 nb) +static int if_usb_host_to_card(wlan_private * priv, u8 type, u8 * payload, u16 nb) { int ret = -1; u32 tmp; - struct usb_card_rec *cardp = (struct usb_card_rec *)priv->wlan_dev.card; + struct usb_card_rec *cardp = (struct usb_card_rec *)priv->card; - lbs_dev_dbg(1, &cardp->udev->dev,"*** type = %u\n", type); - lbs_dev_dbg(1, &cardp->udev->dev,"size after = %d\n", nb); + lbs_deb_usbd(&cardp->udev->dev,"*** type = %u\n", type); + lbs_deb_usbd(&cardp->udev->dev,"size after = %d\n", nb); if (type == MVMS_CMD) { tmp = cpu_to_le32(CMD_TYPE_REQUEST); - priv->wlan_dev.dnld_sent = DNLD_CMD_SENT; + priv->dnld_sent = DNLD_CMD_SENT; memcpy(cardp->bulk_out_buffer, (u8 *) & tmp, MESSAGE_HEADER_LEN); } else { tmp = cpu_to_le32(CMD_TYPE_DATA); - priv->wlan_dev.dnld_sent = DNLD_DATA_SENT; + priv->dnld_sent = DNLD_DATA_SENT; memcpy(cardp->bulk_out_buffer, (u8 *) & tmp, MESSAGE_HEADER_LEN); } @@ -686,39 +732,41 @@ int libertas_sbi_host_to_card(wlan_private * priv, u8 type, u8 * payload, u16 nb } /* called with adapter->driver_lock held */ -int libertas_sbi_get_int_status(wlan_private * priv, u8 * ireg) +static int if_usb_get_int_status(wlan_private * priv, u8 * ireg) { - struct usb_card_rec *cardp = priv->wlan_dev.card; + struct usb_card_rec *cardp = priv->card; *ireg = cardp->usb_int_cause; cardp->usb_int_cause = 0; - lbs_dev_dbg(1, &cardp->udev->dev,"Int cause is 0x%X\n", *ireg); + lbs_deb_usbd(&cardp->udev->dev,"Int cause is 0x%X\n", *ireg); return 0; } -int libertas_sbi_read_event_cause(wlan_private * priv) +static int if_usb_read_event_cause(wlan_private * priv) { - struct usb_card_rec *cardp = priv->wlan_dev.card; + struct usb_card_rec *cardp = priv->card; priv->adapter->eventcause = cardp->usb_event_cause; /* Re-submit rx urb here to avoid event lost issue */ if_usb_submit_rx_urb(priv); return 0; } -int reset_device(wlan_private *priv) +static int if_usb_reset_device(wlan_private *priv) { int ret; + lbs_deb_enter(LBS_DEB_USB); ret = libertas_prepare_and_send_command(priv, cmd_802_11_reset, cmd_act_halt, 0, 0, NULL); msleep_interruptible(10); + lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret); return ret; } -int libertas_sbi_unregister_dev(wlan_private * priv) +static int if_usb_unregister_dev(wlan_private * priv) { int ret = 0; @@ -727,7 +775,7 @@ int libertas_sbi_unregister_dev(wlan_private * priv) * again. */ if (priv) - reset_device(priv); + if_usb_reset_device(priv); return ret; } @@ -738,42 +786,41 @@ int libertas_sbi_unregister_dev(wlan_private * priv) * @param priv pointer to wlan_private * @return 0 or -1 */ -int libertas_sbi_register_dev(wlan_private * priv) +static int if_usb_register_dev(wlan_private * priv) { + struct usb_card_rec *cardp = (struct usb_card_rec *)priv->card; - struct usb_card_rec *cardp = (struct usb_card_rec *)priv->wlan_dev.card; - ENTER(); + lbs_deb_enter(LBS_DEB_USB); cardp->priv = priv; - cardp->eth_dev = priv->wlan_dev.netdev; + cardp->eth_dev = priv->dev; priv->hotplug_device = &(cardp->udev->dev); - SET_NETDEV_DEV(cardp->eth_dev, &(cardp->udev->dev)); - - lbs_dev_dbg(1, &cardp->udev->dev, "udev pointer is at %p\n", + lbs_deb_usbd(&cardp->udev->dev, "udev pointer is at %p\n", cardp->udev); - LEAVE(); + lbs_deb_leave(LBS_DEB_USB); return 0; } -int libertas_sbi_prog_firmware(wlan_private * priv) +static int if_usb_prog_firmware(wlan_private * priv) { - struct usb_card_rec *cardp = priv->wlan_dev.card; + struct usb_card_rec *cardp = priv->card; int i = 0; static int reset_count = 10; + int ret = 0; - ENTER(); + lbs_deb_enter(LBS_DEB_USB); cardp->rinfo.priv = priv; restart: if (if_usb_submit_rx_urb_fwload(priv) < 0) { - lbs_dev_dbg(1, &cardp->udev->dev, "URB submission is failed\n"); - LEAVE(); - return -1; + lbs_deb_usbd(&cardp->udev->dev, "URB submission is failed\n"); + ret = -1; + goto done; } cardp->bootcmdresp = 0; @@ -811,7 +858,7 @@ restart: if_prog_firmware(priv); do { - lbs_dev_dbg(1, &cardp->udev->dev,"Wlan sched timeout\n"); + lbs_deb_usbd(&cardp->udev->dev,"Wlan sched timeout\n"); i++; msleep_interruptible(100); if (priv->adapter->surpriseremoved || i >= 20) @@ -826,8 +873,8 @@ restart: } lbs_pr_info("FW download failure, time = %d ms\n", i * 100); - LEAVE(); - return -1; + ret = -1; + goto done; } if_usb_submit_rx_urb(priv); @@ -837,32 +884,10 @@ restart: priv->adapter->fw_ready = 1; - LEAVE(); - return 0; -} - -/** - * @brief Given a usb_card_rec return its wlan_private - * @param card pointer to a usb_card_rec - * @return pointer to wlan_private - */ -wlan_private *libertas_sbi_get_priv(void *card) -{ - struct usb_card_rec *cardp = card; - return cardp->priv; -} - -#ifdef ENABLE_PM -int libertas_sbi_suspend(wlan_private * priv) -{ - return 0; -} - -int libertas_sbi_resume(wlan_private * priv) -{ - return 0; +done: + lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret); + return ret; } -#endif #ifdef CONFIG_PM static int if_usb_suspend(struct usb_interface *intf, pm_message_t message) @@ -870,12 +895,13 @@ static int if_usb_suspend(struct usb_interface *intf, pm_message_t message) struct usb_card_rec *cardp = usb_get_intfdata(intf); wlan_private *priv = cardp->priv; - ENTER(); + lbs_deb_enter(LBS_DEB_USB); if (priv->adapter->psstate != PS_STATE_FULL_POWER) return -1; netif_device_detach(cardp->eth_dev); + netif_device_detach(priv->mesh_dev); /* Unlink tx & rx urb */ usb_kill_urb(cardp->tx_urb); @@ -883,23 +909,25 @@ static int if_usb_suspend(struct usb_interface *intf, pm_message_t message) cardp->rx_urb_recall = 1; - LEAVE(); + lbs_deb_leave(LBS_DEB_USB); return 0; } static int if_usb_resume(struct usb_interface *intf) { struct usb_card_rec *cardp = usb_get_intfdata(intf); + wlan_private *priv = cardp->priv; - ENTER(); + lbs_deb_enter(LBS_DEB_USB); cardp->rx_urb_recall = 0; if_usb_submit_rx_urb(cardp->priv); netif_device_attach(cardp->eth_dev); + netif_device_attach(priv->mesh_dev); - LEAVE(); + lbs_deb_leave(LBS_DEB_USB); return 0; } #else @@ -920,32 +948,40 @@ static struct usb_driver if_usb_driver = { .resume = if_usb_resume, }; -/** - * @brief This function registers driver. - * @param add pointer to add_card callback function - * @param remove pointer to remove card callback function - * @param arg pointer to call back function parameter - * @return dummy success variable - */ -int libertas_sbi_register(void) +static int if_usb_init_module(void) { - /* - * API registers the Marvell USB driver - * to the USB system - */ - usb_register(&if_usb_driver); + int ret = 0; - /* Return success to wlan layer */ - return 0; + lbs_deb_enter(LBS_DEB_MAIN); + + if (libertas_fw_name == NULL) { + libertas_fw_name = default_fw_name; + } + + ret = usb_register(&if_usb_driver); + + lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret); + return ret; } -/** - * @brief This function removes usb driver. - * @return N/A - */ -void libertas_sbi_unregister(void) +static void if_usb_exit_module(void) { + struct usb_card_rec *cardp, *cardp_temp; + + lbs_deb_enter(LBS_DEB_MAIN); + + list_for_each_entry_safe(cardp, cardp_temp, &usb_devices, list) + if_usb_reset_device((wlan_private *) cardp->priv); + /* API unregisters the driver from USB subsystem */ usb_deregister(&if_usb_driver); - return; + + lbs_deb_leave(LBS_DEB_MAIN); } + +module_init(if_usb_init_module); +module_exit(if_usb_exit_module); + +MODULE_DESCRIPTION("8388 USB WLAN Driver"); +MODULE_AUTHOR("Marvell International Ltd."); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/wireless/libertas/if_usb.h b/drivers/net/wireless/libertas/if_usb.h index 170dfe6809f..156bb485e1a 100644 --- a/drivers/net/wireless/libertas/if_usb.h +++ b/drivers/net/wireless/libertas/if_usb.h @@ -1,3 +1,8 @@ +#ifndef _LIBERTAS_IF_USB_H +#define _LIBERTAS_IF_USB_H + +#include <linux/list.h> + /** * This file contains definition for USB interface. */ @@ -7,11 +12,6 @@ #define IPFIELD_ALIGN_OFFSET 2 -#define USB8388_VID_1 0x1286 -#define USB8388_PID_1 0x2001 -#define USB8388_VID_2 0x05a3 -#define USB8388_PID_2 0x8388 - #define BOOT_CMD_FW_BY_USB 0x01 #define BOOT_CMD_FW_IN_EEPROM 0x02 #define BOOT_CMD_UPDATE_BOOT2 0x03 @@ -20,7 +20,7 @@ struct bootcmdstr { - u32 u32magicnumber; + __le32 u32magicnumber; u8 u8cmd_tag; u8 au8dumy[11]; }; @@ -30,7 +30,7 @@ struct bootcmdstr struct bootcmdrespStr { - u32 u32magicnumber; + __le32 u32magicnumber; u8 u8cmd_tag; u8 u8result; u8 au8dumy[2]; @@ -44,6 +44,7 @@ struct read_cb_info { /** USB card description structure*/ struct usb_card_rec { + struct list_head list; struct net_device *eth_dev; struct usb_device *udev; struct urb *rx_urb, *tx_urb; @@ -75,33 +76,34 @@ struct usb_card_rec { /** fwheader */ struct fwheader { - u32 dnldcmd; - u32 baseaddr; - u32 datalength; - u32 CRC; + __le32 dnldcmd; + __le32 baseaddr; + __le32 datalength; + __le32 CRC; }; #define FW_MAX_DATA_BLK_SIZE 600 /** FWData */ struct FWData { struct fwheader fwheader; - u32 seqnum; + __le32 seqnum; u8 data[FW_MAX_DATA_BLK_SIZE]; }; /** fwsyncheader */ struct fwsyncheader { - u32 cmd; - u32 seqnum; + __le32 cmd; + __le32 seqnum; }; #define FW_HAS_DATA_TO_RECV 0x00000001 #define FW_HAS_LAST_BLOCK 0x00000004 #define FW_DATA_XMIT_SIZE \ - sizeof(struct fwheader) + fwdata->fwheader.datalength + sizeof(u32) + sizeof(struct fwheader) + le32_to_cpu(fwdata->fwheader.datalength) + sizeof(u32) int usb_tx_block(wlan_private *priv, u8 *payload, u16 nb); void if_usb_free(struct usb_card_rec *cardp); int if_usb_issue_boot_command(wlan_private *priv, int ivalue); +#endif diff --git a/drivers/net/wireless/libertas/ioctl.c b/drivers/net/wireless/libertas/ioctl.c deleted file mode 100644 index a8f76c35899..00000000000 --- a/drivers/net/wireless/libertas/ioctl.c +++ /dev/null @@ -1,991 +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; - - 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_pr_debug(1, "region Code not identified\n"); - LEAVE(); - return -1; - } - - if (libertas_set_regiontable(priv, priv->adapter->regioncode, 0)) { - LEAVE(); - return -EINVAL; - } - - return 0; -} - -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]; - - ENTER(); - 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_pr_debug(1, "BT: adding %s\n", ethaddrs_str); - LEAVE(); - return (libertas_prepare_and_send_command(priv, cmd_bt_access, - cmd_act_bt_access_add, - cmd_option_waitforrsp, 0, ethaddr)); -} - -/** - * @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; - - ENTER(); - 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_pr_debug(1, "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)); - LEAVE(); - 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) -{ - ENTER(); - - 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)); - - LEAVE(); - 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 { - int id; - char addr1addr2[2 * ETH_ALEN]; - } param; - static char outstr[64]; - char *pbuf = outstr; - int ret; - - ENTER(); - - if (copy_from_user(outstr, wrq->u.data.pointer, sizeof(outstr))) { - lbs_pr_debug(1, "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, "ignoring traffic from "); - 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_pr_debug(1, "BT_LIST: Copy to user failed!\n"); - return -EFAULT; - } - - LEAVE(); - 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; - - ENTER(); - 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 = 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.ssn = - cpu_to_le32(simple_strtoul(ptr, &ptr, 10)); - else - fwt_access.ssn = FWT_DEFAULT_SSN; - - if ((ptr = next_param(ptr))) - fwt_access.dsn = - cpu_to_le32(simple_strtoul(ptr, &ptr, 10)); - else - fwt_access.dsn = 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 = 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 = 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_pr_debug(1, "FWT_ADD: adding (da:%s,%i,ra:%s)\n", ethaddr1_str, - fwt_access.dir, ethaddr2_str); - lbs_pr_debug(1, "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 - - LEAVE(); - return (libertas_prepare_and_send_command(priv, cmd_fwt_access, - cmd_act_fwt_access_add, - cmd_option_waitforrsp, 0, - (void *)&fwt_access)); -} - -/** - * @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; - - ENTER(); - 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_pr_debug(1, "FWT_DEL: line is %s\n", in_str); - eth_addr2str(fwt_access.da, ethaddr1_str); - eth_addr2str(fwt_access.ra, ethaddr2_str); - lbs_pr_debug(1, "FWT_DEL: removing (da:%s,ra:%s,dir:%d)\n", ethaddr1_str, - ethaddr2_str, fwt_access.dir); - } -#endif - - LEAVE(); - return (libertas_prepare_and_send_command(priv, - cmd_fwt_access, - cmd_act_fwt_access_del, - cmd_option_waitforrsp, 0, - (void *)&fwt_access)); -} - - -/** - * @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", le32_to_cpu(fwt_access.metric)); - buf += sprintf(buf, " %u", fwt_access.dir); - 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)); -} - -/** - * @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; - - ENTER(); - 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_pr_debug(1, "FWT_LOOKUP: line is %s\n", in_str); - eth_addr2str(fwt_access.da, ethaddr1_str); - lbs_pr_debug(1, "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_pr_debug(1, "FWT_LOOKUP: Copy to user failed!\n"); - return -EFAULT; - } - - LEAVE(); - 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_pr_debug(1, "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; - - ENTER(); - 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_pr_debug(1, "FWT_LIST: line is %s\n", in_str); - lbs_pr_debug(1, "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_pr_debug(1, "FWT_LIST: Copy to user failed!\n"); - return -EFAULT; - } - - LEAVE(); - return 0; -} - -/** - * @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; - - ENTER(); - 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_pr_debug(1, "FWT_LIST_ROUTE: line is %s\n", in_str); - lbs_pr_debug(1, "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) { - pbuf += sprintf(pbuf, " "); - pbuf += eth_addr2str(fwt_access.da, pbuf); - pbuf += sprintf(pbuf, " %u", le32_to_cpu(fwt_access.metric)); - pbuf += sprintf(pbuf, " %u", fwt_access.dir); - /* note that the firmware returns the nid in the id field */ - pbuf += sprintf(pbuf, " %u", le32_to_cpu(fwt_access.id)); - pbuf += sprintf(pbuf, " %u", le32_to_cpu(fwt_access.ssn)); - pbuf += sprintf(pbuf, " %u", le32_to_cpu(fwt_access.dsn)); - pbuf += sprintf(pbuf, " hop %u", fwt_access.hopcount); - pbuf += sprintf(pbuf, " ttl %u", fwt_access.ttl); - pbuf += sprintf(pbuf, " %u", le32_to_cpu(fwt_access.expiration)); - } 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_pr_debug(1, "FWT_LIST_ROUTE: Copy to user failed!\n"); - return -EFAULT; - } - - LEAVE(); - 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; - - ENTER(); - 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_pr_debug(1, "FWT_LIST_NEIGHBOR: line is %s\n", in_str); - lbs_pr_debug(1, "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_pr_debug(1, "FWT_LIST_NEIGHBOR: Copy to user failed!\n"); - return -EFAULT; - } - - LEAVE(); - 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; - - ENTER(); - - lbs_pr_debug(1, "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; - - LEAVE(); - 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; - - ENTER(); - - lbs_pr_debug(1, "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; - - LEAVE(); - 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; - - ENTER(); - - 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; - - LEAVE(); - 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; - - ENTER(); - - if( (ttl > 0xff) || (ttl < 0) ) - return -EINVAL; - - memset(&mesh_access, 0, sizeof(mesh_access)); - mesh_access.data[0] = 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; - - LEAVE(); - 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; - - ENTER(); - - lbs_pr_debug(1, "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; - - 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; - - 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_pr_debug(1, - "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_pr_debug(1, "Copy to user failed\n"); - return -EFAULT; - } - - wrq->u.data.length = gpio->header.len; - } - break; - } - break; - - default: - ret = -EINVAL; - break; - } - LEAVE(); - return ret; -} - - diff --git a/drivers/net/wireless/libertas/join.c b/drivers/net/wireless/libertas/join.c index d4926b83e14..78ac3064a0b 100644 --- a/drivers/net/wireless/libertas/join.c +++ b/drivers/net/wireless/libertas/join.c @@ -7,6 +7,7 @@ #include <linux/netdevice.h> #include <linux/if_arp.h> #include <linux/wireless.h> +#include <linux/etherdevice.h> #include <net/iw_handler.h> @@ -14,6 +15,7 @@ #include "decl.h" #include "join.h" #include "dev.h" +#include "assoc.h" #define AD_HOC_CAP_PRIVACY_ON 1 @@ -60,7 +62,7 @@ static int get_common_rates(wlan_adapter * adapter, u8 * rate1, lbs_dbg_hex("rate1 (AP) rates:", tmp, sizeof(tmp)); lbs_dbg_hex("rate2 (Card) rates:", rate2, rate2_size); lbs_dbg_hex("Common rates:", ptr, rate1_size); - lbs_pr_debug(1, "Tx datarate is set to 0x%X\n", adapter->datarate); + lbs_deb_join("Tx datarate is set to 0x%X\n", adapter->datarate); if (!adapter->is_datarate_auto) { while (*ptr) { @@ -104,24 +106,22 @@ int libertas_send_deauth(wlan_private * priv) * * @return 0-success, otherwise fail */ -int wlan_associate(wlan_private * priv, struct bss_descriptor * pbssdesc) +int wlan_associate(wlan_private * priv, struct assoc_request * assoc_req) { wlan_adapter *adapter = priv->adapter; int ret; - ENTER(); + lbs_deb_enter(LBS_DEB_JOIN); ret = libertas_prepare_and_send_command(priv, cmd_802_11_authenticate, 0, cmd_option_waitforrsp, - 0, pbssdesc->macaddress); + 0, assoc_req->bss.bssid); - if (ret) { - LEAVE(); - return ret; - } + if (ret) + goto done; /* set preamble to firmware */ - if (adapter->capinfo.shortpreamble && pbssdesc->cap.shortpreamble) + if (adapter->capinfo.shortpreamble && assoc_req->bss.cap.shortpreamble) adapter->preamble = cmd_type_short_preamble; else adapter->preamble = cmd_type_long_preamble; @@ -129,9 +129,10 @@ int wlan_associate(wlan_private * priv, struct bss_descriptor * pbssdesc) libertas_set_radio_control(priv); ret = libertas_prepare_and_send_command(priv, cmd_802_11_associate, - 0, cmd_option_waitforrsp, 0, pbssdesc); + 0, cmd_option_waitforrsp, 0, assoc_req); - LEAVE(); +done: + lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret); return ret; } @@ -142,7 +143,7 @@ int wlan_associate(wlan_private * priv, struct bss_descriptor * pbssdesc) * @param adhocssid The ssid of the Adhoc Network * @return 0--success, -1--fail */ -int libertas_start_adhoc_network(wlan_private * priv, struct WLAN_802_11_SSID *adhocssid) +int libertas_start_adhoc_network(wlan_private * priv, struct assoc_request * assoc_req) { wlan_adapter *adapter = priv->adapter; int ret = 0; @@ -150,22 +151,20 @@ int libertas_start_adhoc_network(wlan_private * priv, struct WLAN_802_11_SSID *a adapter->adhoccreate = 1; if (!adapter->capinfo.shortpreamble) { - lbs_pr_debug(1, "AdhocStart: Long preamble\n"); + lbs_deb_join("AdhocStart: Long preamble\n"); adapter->preamble = cmd_type_long_preamble; } else { - lbs_pr_debug(1, "AdhocStart: Short preamble\n"); + lbs_deb_join("AdhocStart: Short preamble\n"); adapter->preamble = cmd_type_short_preamble; } libertas_set_radio_control(priv); - lbs_pr_debug(1, "Adhoc channel = %d\n", adapter->adhocchannel); - lbs_pr_debug(1, "curbssparams.channel = %d\n", - adapter->curbssparams.channel); - lbs_pr_debug(1, "curbssparams.band = %d\n", adapter->curbssparams.band); + lbs_deb_join("AdhocStart: channel = %d\n", assoc_req->channel); + lbs_deb_join("AdhocStart: band = %d\n", assoc_req->band); ret = libertas_prepare_and_send_command(priv, cmd_802_11_ad_hoc_start, - 0, cmd_option_waitforrsp, 0, adhocssid); + 0, cmd_option_waitforrsp, 0, assoc_req); return ret; } @@ -179,52 +178,53 @@ int libertas_start_adhoc_network(wlan_private * priv, struct WLAN_802_11_SSID *a * * @return 0--success, -1--fail */ -int libertas_join_adhoc_network(wlan_private * priv, struct bss_descriptor * pbssdesc) +int libertas_join_adhoc_network(wlan_private * priv, struct assoc_request * assoc_req) { wlan_adapter *adapter = priv->adapter; + struct bss_descriptor * bss = &assoc_req->bss; int ret = 0; - lbs_pr_debug(1, "libertas_join_adhoc_network: CurBss.ssid =%s\n", - adapter->curbssparams.ssid.ssid); - lbs_pr_debug(1, "libertas_join_adhoc_network: CurBss.ssid_len =%u\n", - adapter->curbssparams.ssid.ssidlength); - lbs_pr_debug(1, "libertas_join_adhoc_network: ssid =%s\n", pbssdesc->ssid.ssid); - lbs_pr_debug(1, "libertas_join_adhoc_network: ssid len =%u\n", - pbssdesc->ssid.ssidlength); + lbs_deb_join("%s: Current SSID '%s', ssid length %u\n", + __func__, + escape_essid(adapter->curbssparams.ssid, + adapter->curbssparams.ssid_len), + adapter->curbssparams.ssid_len); + lbs_deb_join("%s: requested ssid '%s', ssid length %u\n", + __func__, escape_essid(bss->ssid, bss->ssid_len), + bss->ssid_len); /* check if the requested SSID is already joined */ - if (adapter->curbssparams.ssid.ssidlength - && !libertas_SSID_cmp(&pbssdesc->ssid, &adapter->curbssparams.ssid) + if (adapter->curbssparams.ssid_len + && !libertas_ssid_cmp(adapter->curbssparams.ssid, + adapter->curbssparams.ssid_len, + bss->ssid, bss->ssid_len) && (adapter->mode == IW_MODE_ADHOC)) { - - lbs_pr_debug(1, + lbs_deb_join( "ADHOC_J_CMD: New ad-hoc SSID is the same as current, " "not attempting to re-join"); - return -1; } /*Use shortpreamble only when both creator and card supports short preamble */ - if (!pbssdesc->cap.shortpreamble || !adapter->capinfo.shortpreamble) { - lbs_pr_debug(1, "AdhocJoin: Long preamble\n"); + if (!bss->cap.shortpreamble || !adapter->capinfo.shortpreamble) { + lbs_deb_join("AdhocJoin: Long preamble\n"); adapter->preamble = cmd_type_long_preamble; } else { - lbs_pr_debug(1, "AdhocJoin: Short preamble\n"); + lbs_deb_join("AdhocJoin: Short preamble\n"); adapter->preamble = cmd_type_short_preamble; } libertas_set_radio_control(priv); - lbs_pr_debug(1, "curbssparams.channel = %d\n", - adapter->curbssparams.channel); - lbs_pr_debug(1, "curbssparams.band = %c\n", adapter->curbssparams.band); + lbs_deb_join("AdhocJoin: channel = %d\n", assoc_req->channel); + lbs_deb_join("AdhocJoin: band = %c\n", assoc_req->band); adapter->adhoccreate = 0; ret = libertas_prepare_and_send_command(priv, cmd_802_11_ad_hoc_join, 0, cmd_option_waitforrsp, - OID_802_11_SSID, pbssdesc); + OID_802_11_SSID, assoc_req); return ret; } @@ -265,6 +265,8 @@ int libertas_cmd_80211_authenticate(wlan_private * priv, int ret = -1; u8 *bssid = pdata_buf; + lbs_deb_enter(LBS_DEB_JOIN); + cmd->command = cpu_to_le16(cmd_802_11_authenticate); cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_authenticate) + S_DS_GEN); @@ -281,18 +283,19 @@ int libertas_cmd_80211_authenticate(wlan_private * priv, pauthenticate->authtype = 0x80; break; default: - lbs_pr_debug(1, "AUTH_CMD: invalid auth alg 0x%X\n", + lbs_deb_join("AUTH_CMD: invalid auth alg 0x%X\n", adapter->secinfo.auth_mode); goto out; } memcpy(pauthenticate->macaddr, bssid, ETH_ALEN); - lbs_pr_debug(1, "AUTH_CMD: Bssid is : %x:%x:%x:%x:%x:%x\n", - bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]); + lbs_deb_join("AUTH_CMD: BSSID is : " MAC_FMT " auth=0x%X\n", + MAC_ARG(bssid), pauthenticate->authtype); ret = 0; out: + lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret); return ret; } @@ -302,22 +305,20 @@ int libertas_cmd_80211_deauthenticate(wlan_private * priv, wlan_adapter *adapter = priv->adapter; struct cmd_ds_802_11_deauthenticate *dauth = &cmd->params.deauth; - ENTER(); + lbs_deb_enter(LBS_DEB_JOIN); cmd->command = cpu_to_le16(cmd_802_11_deauthenticate); - cmd->size = - cpu_to_le16(sizeof(struct cmd_ds_802_11_deauthenticate) + + cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_deauthenticate) + S_DS_GEN); /* set AP MAC address */ - memmove(dauth->macaddr, adapter->curbssparams.bssid, - ETH_ALEN); + memmove(dauth->macaddr, adapter->curbssparams.bssid, ETH_ALEN); /* Reason code 3 = Station is leaving */ #define REASON_CODE_STA_LEAVING 3 dauth->reasoncode = cpu_to_le16(REASON_CODE_STA_LEAVING); - LEAVE(); + lbs_deb_leave(LBS_DEB_JOIN); return 0; } @@ -327,20 +328,20 @@ int libertas_cmd_80211_associate(wlan_private * priv, wlan_adapter *adapter = priv->adapter; struct cmd_ds_802_11_associate *passo = &cmd->params.associate; int ret = 0; - struct bss_descriptor *pbssdesc; + struct assoc_request * assoc_req = pdata_buf; + struct bss_descriptor * bss = &assoc_req->bss; u8 *card_rates; u8 *pos; int card_rates_size; - u16 tmpcap; + u16 tmpcap, tmplen; struct mrvlietypes_ssidparamset *ssid; struct mrvlietypes_phyparamset *phy; struct mrvlietypes_ssparamset *ss; struct mrvlietypes_ratesparamset *rates; struct mrvlietypes_rsnparamset *rsn; - ENTER(); + lbs_deb_enter(LBS_DEB_JOIN); - pbssdesc = pdata_buf; pos = (u8 *) passo; if (!adapter) { @@ -350,15 +351,11 @@ int libertas_cmd_80211_associate(wlan_private * priv, cmd->command = cpu_to_le16(cmd_802_11_associate); - /* Save so we know which BSS Desc to use in the response handler */ - adapter->pattemptedbssdesc = pbssdesc; - - memcpy(passo->peerstaaddr, - pbssdesc->macaddress, sizeof(passo->peerstaaddr)); + memcpy(passo->peerstaaddr, bss->bssid, sizeof(passo->peerstaaddr)); pos += sizeof(passo->peerstaaddr); /* set the listen interval */ - passo->listeninterval = adapter->listeninterval; + passo->listeninterval = cpu_to_le16(adapter->listeninterval); pos += sizeof(passo->capinfo); pos += sizeof(passo->listeninterval); @@ -367,30 +364,30 @@ int libertas_cmd_80211_associate(wlan_private * priv, ssid = (struct mrvlietypes_ssidparamset *) pos; ssid->header.type = cpu_to_le16(TLV_TYPE_SSID); - ssid->header.len = pbssdesc->ssid.ssidlength; - memcpy(ssid->ssid, pbssdesc->ssid.ssid, ssid->header.len); - pos += sizeof(ssid->header) + ssid->header.len; - ssid->header.len = cpu_to_le16(ssid->header.len); + tmplen = bss->ssid_len; + ssid->header.len = cpu_to_le16(tmplen); + memcpy(ssid->ssid, bss->ssid, tmplen); + pos += sizeof(ssid->header) + tmplen; phy = (struct mrvlietypes_phyparamset *) pos; phy->header.type = cpu_to_le16(TLV_TYPE_PHY_DS); - phy->header.len = sizeof(phy->fh_ds.dsparamset); + tmplen = sizeof(phy->fh_ds.dsparamset); + phy->header.len = cpu_to_le16(tmplen); memcpy(&phy->fh_ds.dsparamset, - &pbssdesc->phyparamset.dsparamset.currentchan, - sizeof(phy->fh_ds.dsparamset)); - pos += sizeof(phy->header) + phy->header.len; - phy->header.len = cpu_to_le16(phy->header.len); + &bss->phyparamset.dsparamset.currentchan, + tmplen); + pos += sizeof(phy->header) + tmplen; ss = (struct mrvlietypes_ssparamset *) pos; ss->header.type = cpu_to_le16(TLV_TYPE_CF); - ss->header.len = sizeof(ss->cf_ibss.cfparamset); - pos += sizeof(ss->header) + ss->header.len; - ss->header.len = cpu_to_le16(ss->header.len); + tmplen = sizeof(ss->cf_ibss.cfparamset); + ss->header.len = cpu_to_le16(tmplen); + pos += sizeof(ss->header) + tmplen; rates = (struct mrvlietypes_ratesparamset *) pos; rates->header.type = cpu_to_le16(TLV_TYPE_RATES); - memcpy(&rates->rates, &pbssdesc->libertas_supported_rates, WLAN_SUPPORTED_RATES); + memcpy(&rates->rates, &bss->libertas_supported_rates, WLAN_SUPPORTED_RATES); card_rates = libertas_supported_rates; card_rates_size = sizeof(libertas_supported_rates); @@ -401,41 +398,42 @@ int libertas_cmd_80211_associate(wlan_private * priv, goto done; } - rates->header.len = min_t(size_t, strlen(rates->rates), WLAN_SUPPORTED_RATES); - adapter->curbssparams.numofrates = rates->header.len; + tmplen = min_t(size_t, strlen(rates->rates), WLAN_SUPPORTED_RATES); + adapter->curbssparams.numofrates = tmplen; - pos += sizeof(rates->header) + rates->header.len; - rates->header.len = cpu_to_le16(rates->header.len); + pos += sizeof(rates->header) + tmplen; + rates->header.len = cpu_to_le16(tmplen); - if (adapter->secinfo.WPAenabled || adapter->secinfo.WPA2enabled) { + if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) { rsn = (struct mrvlietypes_rsnparamset *) pos; - rsn->header.type = (u16) adapter->wpa_ie[0]; /* WPA_IE or WPA2_IE */ - rsn->header.type = cpu_to_le16(rsn->header.type); - rsn->header.len = (u16) adapter->wpa_ie[1]; - memcpy(rsn->rsnie, &adapter->wpa_ie[2], rsn->header.len); + /* WPA_IE or WPA2_IE */ + rsn->header.type = cpu_to_le16((u16) assoc_req->wpa_ie[0]); + tmplen = (u16) assoc_req->wpa_ie[1]; + rsn->header.len = cpu_to_le16(tmplen); + memcpy(rsn->rsnie, &assoc_req->wpa_ie[2], tmplen); lbs_dbg_hex("ASSOC_CMD: RSN IE", (u8 *) rsn, - sizeof(rsn->header) + rsn->header.len); - pos += sizeof(rsn->header) + rsn->header.len; - rsn->header.len = cpu_to_le16(rsn->header.len); + sizeof(rsn->header) + tmplen); + pos += sizeof(rsn->header) + tmplen; } /* update curbssparams */ - adapter->curbssparams.channel = - (pbssdesc->phyparamset.dsparamset.currentchan); + adapter->curbssparams.channel = bss->phyparamset.dsparamset.currentchan; /* Copy the infra. association rates into Current BSS state structure */ memcpy(&adapter->curbssparams.datarates, &rates->rates, - min_t(size_t, sizeof(adapter->curbssparams.datarates), rates->header.len)); + min_t(size_t, sizeof(adapter->curbssparams.datarates), + cpu_to_le16(rates->header.len))); - lbs_pr_debug(1, "ASSOC_CMD: rates->header.len = %d\n", rates->header.len); + lbs_deb_join("ASSOC_CMD: rates->header.len = %d\n", + cpu_to_le16(rates->header.len)); /* set IBSS field */ - if (pbssdesc->mode == IW_MODE_INFRA) { + if (bss->mode == IW_MODE_INFRA) { #define CAPINFO_ESS_MODE 1 passo->capinfo.ess = CAPINFO_ESS_MODE; } - if (libertas_parse_dnld_countryinfo_11d(priv)) { + if (libertas_parse_dnld_countryinfo_11d(priv, bss)) { ret = -1; goto done; } @@ -443,31 +441,28 @@ int libertas_cmd_80211_associate(wlan_private * priv, cmd->size = cpu_to_le16((u16) (pos - (u8 *) passo) + S_DS_GEN); /* set the capability info at last */ - memcpy(&tmpcap, &pbssdesc->cap, sizeof(passo->capinfo)); + memcpy(&tmpcap, &bss->cap, sizeof(passo->capinfo)); tmpcap &= CAPINFO_MASK; - lbs_pr_debug(1, "ASSOC_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n", - tmpcap, CAPINFO_MASK); - tmpcap = cpu_to_le16(tmpcap); + lbs_deb_join("ASSOC_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n", + tmpcap, CAPINFO_MASK); memcpy(&passo->capinfo, &tmpcap, sizeof(passo->capinfo)); - done: - LEAVE(); +done: + lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret); return ret; } int libertas_cmd_80211_ad_hoc_start(wlan_private * priv, - struct cmd_ds_command *cmd, void *pssid) + struct cmd_ds_command *cmd, void *pdata_buf) { wlan_adapter *adapter = priv->adapter; struct cmd_ds_802_11_ad_hoc_start *adhs = &cmd->params.ads; int ret = 0; int cmdappendsize = 0; int i; - u16 tmpcap; - struct bss_descriptor *pbssdesc; - struct WLAN_802_11_SSID *ssid = pssid; + struct assoc_request * assoc_req = pdata_buf; - ENTER(); + lbs_deb_enter(LBS_DEB_JOIN); if (!adapter) { ret = -1; @@ -476,9 +471,6 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv, cmd->command = cpu_to_le16(cmd_802_11_ad_hoc_start); - pbssdesc = &adapter->curbssparams.bssdescriptor; - adapter->pattemptedbssdesc = pbssdesc; - /* * Fill in the parameters for 2 data structures: * 1. cmd_ds_802_11_ad_hoc_start command @@ -492,20 +484,16 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv, */ memset(adhs->SSID, 0, IW_ESSID_MAX_SIZE); + memcpy(adhs->SSID, assoc_req->ssid, assoc_req->ssid_len); - memcpy(adhs->SSID, ssid->ssid, ssid->ssidlength); - - lbs_pr_debug(1, "ADHOC_S_CMD: SSID = %s\n", adhs->SSID); - - memset(pbssdesc->ssid.ssid, 0, IW_ESSID_MAX_SIZE); - memcpy(pbssdesc->ssid.ssid, ssid->ssid, ssid->ssidlength); - - pbssdesc->ssid.ssidlength = ssid->ssidlength; + lbs_deb_join("ADHOC_S_CMD: SSID '%s', ssid length %u\n", + escape_essid(assoc_req->ssid, assoc_req->ssid_len), + assoc_req->ssid_len); /* set the BSS type */ adhs->bsstype = cmd_bss_type_ibss; - pbssdesc->mode = IW_MODE_ADHOC; - adhs->beaconperiod = adapter->beaconperiod; + adapter->mode = IW_MODE_ADHOC; + adhs->beaconperiod = cpu_to_le16(adapter->beaconperiod); /* set Physical param set */ #define DS_PARA_IE_ID 3 @@ -514,18 +502,12 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv, adhs->phyparamset.dsparamset.elementid = DS_PARA_IE_ID; adhs->phyparamset.dsparamset.len = DS_PARA_IE_LEN; - WARN_ON(!adapter->adhocchannel); + WARN_ON(!assoc_req->channel); - lbs_pr_debug(1, "ADHOC_S_CMD: Creating ADHOC on channel %d\n", - adapter->adhocchannel); + lbs_deb_join("ADHOC_S_CMD: Creating ADHOC on channel %d\n", + assoc_req->channel); - adapter->curbssparams.channel = adapter->adhocchannel; - - pbssdesc->channel = adapter->adhocchannel; - adhs->phyparamset.dsparamset.currentchan = adapter->adhocchannel; - - memcpy(&pbssdesc->phyparamset, - &adhs->phyparamset, sizeof(union ieeetypes_phyparamset)); + adhs->phyparamset.dsparamset.currentchan = assoc_req->channel; /* set IBSS param set */ #define IBSS_PARA_IE_ID 6 @@ -533,26 +515,21 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv, adhs->ssparamset.ibssparamset.elementid = IBSS_PARA_IE_ID; adhs->ssparamset.ibssparamset.len = IBSS_PARA_IE_LEN; - adhs->ssparamset.ibssparamset.atimwindow = adapter->atimwindow; - memcpy(&pbssdesc->ssparamset, - &adhs->ssparamset, sizeof(union IEEEtypes_ssparamset)); + adhs->ssparamset.ibssparamset.atimwindow = cpu_to_le16(adapter->atimwindow); /* set capability info */ adhs->cap.ess = 0; adhs->cap.ibss = 1; - pbssdesc->cap.ibss = 1; /* probedelay */ adhs->probedelay = cpu_to_le16(cmd_scan_probe_delay_time); /* set up privacy in adapter->scantable[i] */ - if (adapter->secinfo.wep_enabled) { - lbs_pr_debug(1, "ADHOC_S_CMD: WEP enabled, setting privacy on\n"); - pbssdesc->privacy = wlan802_11privfilter8021xWEP; + if (assoc_req->secinfo.wep_enabled) { + lbs_deb_join("ADHOC_S_CMD: WEP enabled, setting privacy on\n"); adhs->cap.privacy = AD_HOC_CAP_PRIVACY_ON; } else { - lbs_pr_debug(1, "ADHOC_S_CMD: WEP disabled, setting privacy off\n"); - pbssdesc->privacy = wlan802_11privfilteracceptall; + lbs_deb_join("ADHOC_S_CMD: WEP disabled, setting privacy off\n"); } memset(adhs->datarate, 0, sizeof(adhs->datarate)); @@ -574,29 +551,24 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv, memcpy(&adapter->curbssparams.datarates, &adhs->datarate, adapter->curbssparams.numofrates); - lbs_pr_debug(1, "ADHOC_S_CMD: rates=%02x %02x %02x %02x \n", + lbs_deb_join("ADHOC_S_CMD: rates=%02x %02x %02x %02x \n", adhs->datarate[0], adhs->datarate[1], adhs->datarate[2], adhs->datarate[3]); - lbs_pr_debug(1, "ADHOC_S_CMD: AD HOC Start command is ready\n"); + lbs_deb_join("ADHOC_S_CMD: AD HOC Start command is ready\n"); if (libertas_create_dnld_countryinfo_11d(priv)) { - lbs_pr_debug(1, "ADHOC_S_CMD: dnld_countryinfo_11d failed\n"); + lbs_deb_join("ADHOC_S_CMD: dnld_countryinfo_11d failed\n"); ret = -1; goto done; } - cmd->size = - cpu_to_le16(sizeof(struct cmd_ds_802_11_ad_hoc_start) - + S_DS_GEN + cmdappendsize); - - memcpy(&tmpcap, &adhs->cap, sizeof(u16)); - tmpcap = cpu_to_le16(tmpcap); - memcpy(&adhs->cap, &tmpcap, sizeof(u16)); + cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_ad_hoc_start) + + S_DS_GEN + cmdappendsize); ret = 0; done: - LEAVE(); + lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret); return ret; } @@ -614,7 +586,8 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv, { wlan_adapter *adapter = priv->adapter; struct cmd_ds_802_11_ad_hoc_join *padhocjoin = &cmd->params.adj; - struct bss_descriptor *pbssdesc = pdata_buf; + struct assoc_request * assoc_req = pdata_buf; + struct bss_descriptor *bss = &assoc_req->bss; int cmdappendsize = 0; int ret = 0; u8 *card_rates; @@ -622,70 +595,59 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv, u16 tmpcap; int i; - ENTER(); - - adapter->pattemptedbssdesc = pbssdesc; + lbs_deb_enter(LBS_DEB_JOIN); cmd->command = cpu_to_le16(cmd_802_11_ad_hoc_join); padhocjoin->bssdescriptor.bsstype = cmd_bss_type_ibss; - padhocjoin->bssdescriptor.beaconperiod = pbssdesc->beaconperiod; - - memcpy(&padhocjoin->bssdescriptor.BSSID, - &pbssdesc->macaddress, ETH_ALEN); + padhocjoin->bssdescriptor.beaconperiod = cpu_to_le16(bss->beaconperiod); - memcpy(&padhocjoin->bssdescriptor.SSID, - &pbssdesc->ssid.ssid, pbssdesc->ssid.ssidlength); + memcpy(&padhocjoin->bssdescriptor.BSSID, &bss->bssid, ETH_ALEN); + memcpy(&padhocjoin->bssdescriptor.SSID, &bss->ssid, bss->ssid_len); memcpy(&padhocjoin->bssdescriptor.phyparamset, - &pbssdesc->phyparamset, sizeof(union ieeetypes_phyparamset)); + &bss->phyparamset, sizeof(union ieeetypes_phyparamset)); memcpy(&padhocjoin->bssdescriptor.ssparamset, - &pbssdesc->ssparamset, sizeof(union IEEEtypes_ssparamset)); + &bss->ssparamset, sizeof(union IEEEtypes_ssparamset)); - memcpy(&tmpcap, &pbssdesc->cap, sizeof(struct ieeetypes_capinfo)); + memcpy(&tmpcap, &bss->cap, sizeof(struct ieeetypes_capinfo)); tmpcap &= CAPINFO_MASK; - lbs_pr_debug(1, "ADHOC_J_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n", + lbs_deb_join("ADHOC_J_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n", tmpcap, CAPINFO_MASK); memcpy(&padhocjoin->bssdescriptor.cap, &tmpcap, sizeof(struct ieeetypes_capinfo)); /* information on BSSID descriptor passed to FW */ - lbs_pr_debug(1, - "ADHOC_J_CMD: BSSID = %2x-%2x-%2x-%2x-%2x-%2x, SSID = %s\n", - padhocjoin->bssdescriptor.BSSID[0], - padhocjoin->bssdescriptor.BSSID[1], - padhocjoin->bssdescriptor.BSSID[2], - padhocjoin->bssdescriptor.BSSID[3], - padhocjoin->bssdescriptor.BSSID[4], - padhocjoin->bssdescriptor.BSSID[5], + lbs_deb_join( + "ADHOC_J_CMD: BSSID = " MAC_FMT ", SSID = '%s'\n", + MAC_ARG(padhocjoin->bssdescriptor.BSSID), padhocjoin->bssdescriptor.SSID); /* failtimeout */ padhocjoin->failtimeout = cpu_to_le16(MRVDRV_ASSOCIATION_TIME_OUT); /* probedelay */ - padhocjoin->probedelay = - cpu_to_le16(cmd_scan_probe_delay_time); + padhocjoin->probedelay = cpu_to_le16(cmd_scan_probe_delay_time); /* Copy Data rates from the rates recorded in scan response */ memset(padhocjoin->bssdescriptor.datarates, 0, sizeof(padhocjoin->bssdescriptor.datarates)); - memcpy(padhocjoin->bssdescriptor.datarates, pbssdesc->datarates, + memcpy(padhocjoin->bssdescriptor.datarates, bss->datarates, min(sizeof(padhocjoin->bssdescriptor.datarates), - sizeof(pbssdesc->datarates))); + sizeof(bss->datarates))); card_rates = libertas_supported_rates; card_rates_size = sizeof(libertas_supported_rates); - adapter->curbssparams.channel = pbssdesc->channel; + adapter->curbssparams.channel = bss->channel; if (get_common_rates(adapter, padhocjoin->bssdescriptor.datarates, sizeof(padhocjoin->bssdescriptor.datarates), card_rates, card_rates_size)) { - lbs_pr_debug(1, "ADHOC_J_CMD: get_common_rates returns error.\n"); + lbs_deb_join("ADHOC_J_CMD: get_common_rates returns error.\n"); ret = -1; goto done; } @@ -704,17 +666,17 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv, adapter->curbssparams.numofrates); padhocjoin->bssdescriptor.ssparamset.ibssparamset.atimwindow = - cpu_to_le16(pbssdesc->atimwindow); + cpu_to_le16(bss->atimwindow); - if (adapter->secinfo.wep_enabled) { + if (assoc_req->secinfo.wep_enabled) { padhocjoin->bssdescriptor.cap.privacy = AD_HOC_CAP_PRIVACY_ON; } if (adapter->psmode == wlan802_11powermodemax_psp) { /* wake up first */ - enum WLAN_802_11_POWER_MODE Localpsmode; + __le32 Localpsmode; - Localpsmode = wlan802_11powermodecam; + Localpsmode = cpu_to_le32(wlan802_11powermodecam); ret = libertas_prepare_and_send_command(priv, cmd_802_11_ps_mode, cmd_act_set, @@ -726,24 +688,16 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv, } } - if (libertas_parse_dnld_countryinfo_11d(priv)) { + if (libertas_parse_dnld_countryinfo_11d(priv, bss)) { ret = -1; goto done; } - cmd->size = - cpu_to_le16(sizeof(struct cmd_ds_802_11_ad_hoc_join) - + S_DS_GEN + cmdappendsize); - - memcpy(&tmpcap, &padhocjoin->bssdescriptor.cap, - sizeof(struct ieeetypes_capinfo)); - tmpcap = cpu_to_le16(tmpcap); - - memcpy(&padhocjoin->bssdescriptor.cap, - &tmpcap, sizeof(struct ieeetypes_capinfo)); + cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_ad_hoc_join) + + S_DS_GEN + cmdappendsize); - done: - LEAVE(); +done: + lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret); return ret; } @@ -754,19 +708,24 @@ int libertas_ret_80211_associate(wlan_private * priv, int ret = 0; union iwreq_data wrqu; struct ieeetypes_assocrsp *passocrsp; - struct bss_descriptor *pbssdesc; + struct bss_descriptor * bss; - ENTER(); + lbs_deb_enter(LBS_DEB_JOIN); - passocrsp = (struct ieeetypes_assocrsp *) & resp->params; + if (!adapter->in_progress_assoc_req) { + lbs_deb_join("ASSOC_RESP: no in-progress association request\n"); + ret = -1; + goto done; + } + bss = &adapter->in_progress_assoc_req->bss; - if (passocrsp->statuscode) { + passocrsp = (struct ieeetypes_assocrsp *) & resp->params; + if (le16_to_cpu(passocrsp->statuscode)) { libertas_mac_event_disconnected(priv); - lbs_pr_debug(1, - "ASSOC_RESP: Association failed, status code = %d\n", - passocrsp->statuscode); + lbs_deb_join("ASSOC_RESP: Association failed, status code = %d\n", + le16_to_cpu(passocrsp->statuscode)); ret = -1; goto done; @@ -778,24 +737,15 @@ int libertas_ret_80211_associate(wlan_private * priv, /* Send a Media Connected event, according to the Spec */ adapter->connect_status = libertas_connected; - /* Set the attempted BSSID Index to current */ - pbssdesc = adapter->pattemptedbssdesc; - - lbs_pr_debug(1, "ASSOC_RESP: %s\n", pbssdesc->ssid.ssid); + lbs_deb_join("ASSOC_RESP: assocated to '%s'\n", + escape_essid(bss->ssid, bss->ssid_len)); - /* Set the new SSID to current SSID */ - memcpy(&adapter->curbssparams.ssid, - &pbssdesc->ssid, sizeof(struct WLAN_802_11_SSID)); - - /* Set the new BSSID (AP's MAC address) to current BSSID */ - memcpy(adapter->curbssparams.bssid, - pbssdesc->macaddress, ETH_ALEN); - - /* Make a copy of current BSSID descriptor */ - memcpy(&adapter->curbssparams.bssdescriptor, - pbssdesc, sizeof(struct bss_descriptor)); + /* Update current SSID and BSSID */ + memcpy(&adapter->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE); + adapter->curbssparams.ssid_len = bss->ssid_len; + memcpy(adapter->curbssparams.bssid, bss->bssid, ETH_ALEN); - lbs_pr_debug(1, "ASSOC_RESP: currentpacketfilter is %x\n", + lbs_deb_join("ASSOC_RESP: currentpacketfilter is %x\n", adapter->currentpacketfilter); adapter->SNR[TYPE_RXPD][TYPE_AVG] = 0; @@ -806,28 +756,31 @@ int libertas_ret_80211_associate(wlan_private * priv, adapter->nextSNRNF = 0; adapter->numSNRNF = 0; - netif_carrier_on(priv->wlan_dev.netdev); - netif_wake_queue(priv->wlan_dev.netdev); + netif_carrier_on(priv->dev); + netif_wake_queue(priv->dev); - lbs_pr_debug(1, "ASSOC_RESP: Associated \n"); + netif_carrier_on(priv->mesh_dev); + netif_wake_queue(priv->mesh_dev); + + lbs_deb_join("ASSOC_RESP: Associated \n"); memcpy(wrqu.ap_addr.sa_data, adapter->curbssparams.bssid, ETH_ALEN); wrqu.ap_addr.sa_family = ARPHRD_ETHER; - wireless_send_event(priv->wlan_dev.netdev, SIOCGIWAP, &wrqu, NULL); + wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL); - done: - LEAVE(); +done: + lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret); return ret; } int libertas_ret_80211_disassociate(wlan_private * priv, struct cmd_ds_command *resp) { - ENTER(); + lbs_deb_enter(LBS_DEB_JOIN); libertas_mac_event_disconnected(priv); - LEAVE(); + lbs_deb_leave(LBS_DEB_JOIN); return 0; } @@ -840,90 +793,85 @@ int libertas_ret_80211_ad_hoc_start(wlan_private * priv, u16 result = le16_to_cpu(resp->result); struct cmd_ds_802_11_ad_hoc_result *padhocresult; union iwreq_data wrqu; - struct bss_descriptor *pbssdesc; + struct bss_descriptor *bss; - ENTER(); + lbs_deb_enter(LBS_DEB_JOIN); padhocresult = &resp->params.result; - lbs_pr_debug(1, "ADHOC_S_RESP: size = %d\n", le16_to_cpu(resp->size)); - lbs_pr_debug(1, "ADHOC_S_RESP: command = %x\n", command); - lbs_pr_debug(1, "ADHOC_S_RESP: result = %x\n", result); + lbs_deb_join("ADHOC_RESP: size = %d\n", le16_to_cpu(resp->size)); + lbs_deb_join("ADHOC_RESP: command = %x\n", command); + lbs_deb_join("ADHOC_RESP: result = %x\n", result); - pbssdesc = adapter->pattemptedbssdesc; + if (!adapter->in_progress_assoc_req) { + lbs_deb_join("ADHOC_RESP: no in-progress association request\n"); + ret = -1; + goto done; + } + bss = &adapter->in_progress_assoc_req->bss; /* * Join result code 0 --> SUCCESS */ if (result) { - lbs_pr_debug(1, "ADHOC_RESP failed\n"); + lbs_deb_join("ADHOC_RESP: failed\n"); if (adapter->connect_status == libertas_connected) { libertas_mac_event_disconnected(priv); } - - memset(&adapter->curbssparams.bssdescriptor, - 0x00, sizeof(adapter->curbssparams.bssdescriptor)); - - LEAVE(); - return -1; + ret = -1; + goto done; } /* * Now the join cmd should be successful * If BSSID has changed use SSID to compare instead of BSSID */ - lbs_pr_debug(1, "ADHOC_J_RESP %s\n", pbssdesc->ssid.ssid); + lbs_deb_join("ADHOC_RESP: associated to '%s'\n", + escape_essid(bss->ssid, bss->ssid_len)); /* Send a Media Connected event, according to the Spec */ adapter->connect_status = libertas_connected; if (command == cmd_ret_802_11_ad_hoc_start) { /* Update the created network descriptor with the new BSSID */ - memcpy(pbssdesc->macaddress, - padhocresult->BSSID, ETH_ALEN); - } else { - - /* Make a copy of current BSSID descriptor, only needed for join since - * the current descriptor is already being used for adhoc start - */ - memmove(&adapter->curbssparams.bssdescriptor, - pbssdesc, sizeof(struct bss_descriptor)); + memcpy(bss->bssid, padhocresult->BSSID, ETH_ALEN); } /* Set the BSSID from the joined/started descriptor */ - memcpy(&adapter->curbssparams.bssid, - pbssdesc->macaddress, ETH_ALEN); + memcpy(&adapter->curbssparams.bssid, bss->bssid, ETH_ALEN); /* Set the new SSID to current SSID */ - memcpy(&adapter->curbssparams.ssid, - &pbssdesc->ssid, sizeof(struct WLAN_802_11_SSID)); + memcpy(&adapter->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE); + adapter->curbssparams.ssid_len = bss->ssid_len; - netif_carrier_on(priv->wlan_dev.netdev); - netif_wake_queue(priv->wlan_dev.netdev); + netif_carrier_on(priv->dev); + netif_wake_queue(priv->dev); + + netif_carrier_on(priv->mesh_dev); + netif_wake_queue(priv->mesh_dev); memset(&wrqu, 0, sizeof(wrqu)); memcpy(wrqu.ap_addr.sa_data, adapter->curbssparams.bssid, ETH_ALEN); wrqu.ap_addr.sa_family = ARPHRD_ETHER; - wireless_send_event(priv->wlan_dev.netdev, SIOCGIWAP, &wrqu, NULL); + wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL); - lbs_pr_debug(1, "ADHOC_RESP: - Joined/Started Ad Hoc\n"); - lbs_pr_debug(1, "ADHOC_RESP: channel = %d\n", adapter->adhocchannel); - lbs_pr_debug(1, "ADHOC_RESP: BSSID = %02x:%02x:%02x:%02x:%02x:%02x\n", - padhocresult->BSSID[0], padhocresult->BSSID[1], - padhocresult->BSSID[2], padhocresult->BSSID[3], - padhocresult->BSSID[4], padhocresult->BSSID[5]); + lbs_deb_join("ADHOC_RESP: - Joined/Started Ad Hoc\n"); + lbs_deb_join("ADHOC_RESP: channel = %d\n", adapter->curbssparams.channel); + lbs_deb_join("ADHOC_RESP: BSSID = " MAC_FMT "\n", + MAC_ARG(padhocresult->BSSID)); - LEAVE(); +done: + lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret); return ret; } int libertas_ret_80211_ad_hoc_stop(wlan_private * priv, struct cmd_ds_command *resp) { - ENTER(); + lbs_deb_enter(LBS_DEB_JOIN); libertas_mac_event_disconnected(priv); - LEAVE(); + lbs_deb_leave(LBS_DEB_JOIN); return 0; } diff --git a/drivers/net/wireless/libertas/join.h b/drivers/net/wireless/libertas/join.h index 115f5a8ba34..d522630ff8c 100644 --- a/drivers/net/wireless/libertas/join.h +++ b/drivers/net/wireless/libertas/join.h @@ -9,6 +9,7 @@ #define _WLAN_JOIN_H #include "defs.h" +#include "dev.h" struct cmd_ds_command; extern int libertas_cmd_80211_authenticate(wlan_private * priv, @@ -21,7 +22,7 @@ extern int libertas_cmd_80211_ad_hoc_stop(wlan_private * priv, struct cmd_ds_command *cmd); extern int libertas_cmd_80211_ad_hoc_start(wlan_private * priv, struct cmd_ds_command *cmd, - void *pssid); + void *pdata_buf); extern int libertas_cmd_80211_deauthenticate(wlan_private * priv, struct cmd_ds_command *cmd); extern int libertas_cmd_80211_associate(wlan_private * priv, @@ -39,12 +40,10 @@ extern int libertas_ret_80211_associate(wlan_private * priv, extern int libertas_reassociation_thread(void *data); -struct WLAN_802_11_SSID; -struct bss_descriptor; - extern int libertas_start_adhoc_network(wlan_private * priv, - struct WLAN_802_11_SSID *adhocssid); -extern int libertas_join_adhoc_network(wlan_private * priv, struct bss_descriptor *pbssdesc); + struct assoc_request * assoc_req); +extern int libertas_join_adhoc_network(wlan_private * priv, + struct assoc_request * assoc_req); extern int libertas_stop_adhoc_network(wlan_private * priv); extern int libertas_send_deauthentication(wlan_private * priv); @@ -52,6 +51,6 @@ extern int libertas_send_deauth(wlan_private * priv); extern int libertas_do_adhocstop_ioctl(wlan_private * priv); -int wlan_associate(wlan_private * priv, struct bss_descriptor * pbssdesc); +int wlan_associate(wlan_private * priv, struct assoc_request * assoc_req); #endif diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index b9b25ce6591..4a59306a3f0 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -4,6 +4,7 @@ * thread etc.. */ +#include <linux/moduleparam.h> #include <linux/delay.h> #include <linux/freezer.h> #include <linux/etherdevice.h> @@ -11,26 +12,28 @@ #include <linux/if_arp.h> #include <net/iw_handler.h> +#include <net/ieee80211.h> #include "host.h" -#include "sbi.h" #include "decl.h" #include "dev.h" -#include "fw.h" #include "wext.h" #include "debugfs.h" #include "assoc.h" -#define DRIVER_RELEASE_VERSION "320.p0" +#define DRIVER_RELEASE_VERSION "322.p0" const char libertas_driver_version[] = "COMM-USB8388-" DRIVER_RELEASE_VERSION #ifdef DEBUG "-dbg" #endif ""; -#ifdef ENABLE_PM -static struct pm_dev *wlan_pm_dev = NULL; -#endif + +/* Module parameters */ +unsigned int libertas_debug = 0; +module_param(libertas_debug, int, 0644); +EXPORT_SYMBOL_GPL(libertas_debug); + #define WLAN_TX_PWR_DEFAULT 20 /*100mW */ #define WLAN_TX_PWR_US_DEFAULT 20 /*100mW */ @@ -146,14 +149,6 @@ static struct region_cfp_table region_cfp_table[] = { }; /** - * the rates supported by the card - */ -u8 libertas_wlan_data_rates[WLAN_SUPPORTED_RATES] = - { 0x02, 0x04, 0x0B, 0x16, 0x00, 0x0C, 0x12, - 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x00 -}; - -/** * the rates supported */ u8 libertas_supported_rates[G_SUPPORTED_RATES] = @@ -173,66 +168,57 @@ u8 libertas_adhoc_rates_g[G_SUPPORTED_RATES] = u8 libertas_adhoc_rates_b[4] = { 0x82, 0x84, 0x8b, 0x96 }; /** - * the global variable of a pointer to wlan_private - * structure variable - */ -static wlan_private *wlanpriv = NULL; - -#define MAX_DEVS 5 -static struct net_device *libertas_devs[MAX_DEVS]; -static int libertas_found = 0; - -/** * the table to keep region code */ u16 libertas_region_code_to_index[MRVDRV_MAX_REGION_CODE] = { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40 }; -static u8 *default_fw_name = "usb8388.bin"; - /** * Attributes exported through sysfs */ /** - * @brief Get function for sysfs attribute libertas_mpp + * @brief Get function for sysfs attribute anycast_mask */ -static ssize_t libertas_mpp_get(struct device * dev, - struct device_attribute *attr, char * buf) { +static ssize_t libertas_anycast_get(struct device * dev, + struct device_attribute *attr, char * buf) +{ struct cmd_ds_mesh_access mesh_access; memset(&mesh_access, 0, sizeof(mesh_access)); libertas_prepare_and_send_command(to_net_dev(dev)->priv, cmd_mesh_access, - cmd_act_mesh_get_mpp, + cmd_act_mesh_get_anycast, cmd_option_waitforrsp, 0, (void *)&mesh_access); - return snprintf(buf, 3, "%d\n", mesh_access.data[0]); + return snprintf(buf, 12, "0x%X\n", le32_to_cpu(mesh_access.data[0])); } /** - * @brief Set function for sysfs attribute libertas_mpp + * @brief Set function for sysfs attribute anycast_mask */ -static ssize_t libertas_mpp_set(struct device * dev, - struct device_attribute *attr, const char * buf, size_t count) { +static ssize_t libertas_anycast_set(struct device * dev, + struct device_attribute *attr, const char * buf, size_t count) +{ struct cmd_ds_mesh_access mesh_access; - + uint32_t datum; memset(&mesh_access, 0, sizeof(mesh_access)); - sscanf(buf, "%d", &(mesh_access.data[0])); + sscanf(buf, "%x", &datum); + mesh_access.data[0] = cpu_to_le32(datum); + libertas_prepare_and_send_command((to_net_dev(dev))->priv, cmd_mesh_access, - cmd_act_mesh_set_mpp, + cmd_act_mesh_set_anycast, cmd_option_waitforrsp, 0, (void *)&mesh_access); return strlen(buf); } /** - * libertas_mpp attribute to be exported per mshX interface - * through sysfs (/sys/class/net/mshX/libertas-mpp) + * anycast_mask attribute to be exported per mshX interface + * through sysfs (/sys/class/net/mshX/anycast_mask) */ -static DEVICE_ATTR(libertas_mpp, 0644, libertas_mpp_get, - libertas_mpp_set ); +static DEVICE_ATTR(anycast_mask, 0644, libertas_anycast_get, libertas_anycast_set); /** * @brief Check if the device can be open and wait if necessary. @@ -245,7 +231,8 @@ static DEVICE_ATTR(libertas_mpp, 0644, libertas_mpp_get, * function to work around the issue. * */ -static int pre_open_check(struct net_device *dev) { +static int pre_open_check(struct net_device *dev) +{ wlan_private *priv = (wlan_private *) dev->priv; wlan_adapter *adapter = priv->adapter; int i = 0; @@ -255,8 +242,7 @@ static int pre_open_check(struct net_device *dev) { msleep_interruptible(100); } if (!adapter->fw_ready) { - lbs_pr_info("FW not ready, pre_open_check() return failure\n"); - LEAVE(); + lbs_pr_err("firmware not ready\n"); return -1; } @@ -274,17 +260,19 @@ static int wlan_dev_open(struct net_device *dev) wlan_private *priv = (wlan_private *) dev->priv; wlan_adapter *adapter = priv->adapter; - ENTER(); - + lbs_deb_enter(LBS_DEB_NET); priv->open = 1; if (adapter->connect_status == libertas_connected) { - netif_carrier_on(priv->wlan_dev.netdev); - } else - netif_carrier_off(priv->wlan_dev.netdev); + netif_carrier_on(priv->dev); + netif_carrier_on(priv->mesh_dev); + } else { + netif_carrier_off(priv->dev); + netif_carrier_off(priv->mesh_dev); + } - LEAVE(); + lbs_deb_leave(LBS_DEB_NET); return 0; } /** @@ -297,12 +285,12 @@ static int mesh_open(struct net_device *dev) { wlan_private *priv = (wlan_private *) dev->priv ; - if(pre_open_check(dev) == -1) + if (pre_open_check(dev) == -1) return -1; priv->mesh_open = 1 ; - netif_start_queue(priv->mesh_dev); + netif_wake_queue(priv->mesh_dev); if (priv->infra_open == 0) - return wlan_dev_open(priv->wlan_dev.netdev) ; + return wlan_dev_open(priv->dev) ; return 0; } @@ -319,9 +307,9 @@ static int wlan_open(struct net_device *dev) if(pre_open_check(dev) == -1) return -1; priv->infra_open = 1 ; - netif_wake_queue(priv->wlan_dev.netdev); + netif_wake_queue(priv->dev); if (priv->open == 0) - return wlan_dev_open(priv->wlan_dev.netdev) ; + return wlan_dev_open(priv->dev) ; return 0; } @@ -329,12 +317,12 @@ static int wlan_dev_close(struct net_device *dev) { wlan_private *priv = dev->priv; - ENTER(); + lbs_deb_enter(LBS_DEB_NET); - netif_carrier_off(priv->wlan_dev.netdev); + netif_carrier_off(priv->dev); priv->open = 0; - LEAVE(); + lbs_deb_leave(LBS_DEB_NET); return 0; } @@ -351,7 +339,7 @@ static int mesh_close(struct net_device *dev) priv->mesh_open = 0; netif_stop_queue(priv->mesh_dev); if (priv->infra_open == 0) - return wlan_dev_close( ((wlan_private *) dev->priv)->wlan_dev.netdev) ; + return wlan_dev_close(dev); else return 0; } @@ -362,147 +350,38 @@ static int mesh_close(struct net_device *dev) * @param dev A pointer to net_device structure * @return 0 */ -static int wlan_close(struct net_device *dev) { +static int wlan_close(struct net_device *dev) +{ wlan_private *priv = (wlan_private *) dev->priv; - netif_stop_queue(priv->wlan_dev.netdev); + netif_stop_queue(dev); priv->infra_open = 0; if (priv->mesh_open == 0) - return wlan_dev_close( ((wlan_private *) dev->priv)->wlan_dev.netdev) ; + return wlan_dev_close(dev); else return 0; } -#ifdef ENABLE_PM - -/** - * @brief This function is a callback function. it is called by - * kernel to enter or exit power saving mode. - * - * @param pmdev A pointer to pm_dev - * @param pmreq pm_request_t - * @param pmdata A pointer to pmdata - * @return 0 or -1 - */ -static int wlan_pm_callback(struct pm_dev *pmdev, pm_request_t pmreq, - void *pmdata) -{ - wlan_private *priv = wlanpriv; - wlan_adapter *adapter = priv->adapter; - struct net_device *dev = priv->wlan_dev.netdev; - - lbs_pr_debug(1, "WPRM_PM_CALLBACK: pmreq = %d.\n", pmreq); - - switch (pmreq) { - case PM_SUSPEND: - lbs_pr_debug(1, "WPRM_PM_CALLBACK: enter PM_SUSPEND.\n"); - - /* in associated mode */ - if (adapter->connect_status == libertas_connected) { - if ((adapter->psstate != PS_STATE_SLEEP) - ) { - lbs_pr_debug(1, - "wlan_pm_callback: can't enter sleep mode\n"); - return -1; - } else { - - /* - * Detach the network interface - * if the network is running - */ - if (netif_running(dev)) { - netif_device_detach(dev); - lbs_pr_debug(1, - "netif_device_detach().\n"); - } - libertas_sbi_suspend(priv); - } - break; - } - - /* in non associated mode */ - - /* - * Detach the network interface - * if the network is running - */ - if (netif_running(dev)) - netif_device_detach(dev); - - /* - * Storing and restoring of the regs be taken care - * at the driver rest will be done at wlan driver - * this makes driver independent of the card - */ - - libertas_sbi_suspend(priv); - - break; - - case PM_RESUME: - /* in associated mode */ - if (adapter->connect_status == libertas_connected) { - { - /* - * Bring the inteface up first - * This case should not happen still ... - */ - libertas_sbi_resume(priv); - - /* - * Attach the network interface - * if the network is running - */ - if (netif_running(dev)) { - netif_device_attach(dev); - lbs_pr_debug(1, - "after netif_device_attach().\n"); - } - lbs_pr_debug(1, - "After netif attach, in associated mode.\n"); - } - break; - } - - /* in non associated mode */ - - /* - * Bring the inteface up first - * This case should not happen still ... - */ - - libertas_sbi_resume(priv); - - if (netif_running(dev)) - netif_device_attach(dev); - - lbs_pr_debug(1, "after netif attach, in NON associated mode.\n"); - break; - } - - return 0; -} -#endif /* ENABLE_PM */ - static int wlan_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) { int ret = 0; wlan_private *priv = dev->priv; - ENTER(); + lbs_deb_enter(LBS_DEB_NET); - if (priv->wlan_dev.dnld_sent || priv->adapter->TxLockFlag) { + if (priv->dnld_sent || priv->adapter->TxLockFlag) { priv->stats.tx_dropped++; goto done; } - netif_stop_queue(priv->wlan_dev.netdev); + netif_stop_queue(priv->dev); + netif_stop_queue(priv->mesh_dev); if (libertas_process_tx(priv, skb) == 0) dev->trans_start = jiffies; done: - LEAVE(); + lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret); return ret; } @@ -513,33 +392,43 @@ done: static int mesh_pre_start_xmit(struct sk_buff *skb, struct net_device *dev) { wlan_private *priv = dev->priv; - ENTER(); + int ret; + + lbs_deb_enter(LBS_DEB_MESH); + SET_MESH_FRAME(skb); - LEAVE(); - return wlan_hard_start_xmit(skb, priv->wlan_dev.netdev); + ret = wlan_hard_start_xmit(skb, priv->dev); + lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret); + return ret; } /** * @brief Mark non-mesh packets and handover them to wlan_hard_start_xmit * */ -static int wlan_pre_start_xmit(struct sk_buff *skb, struct net_device *dev) { - ENTER(); +static int wlan_pre_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + int ret; + + lbs_deb_enter(LBS_DEB_NET); + UNSET_MESH_FRAME(skb); - LEAVE(); - return wlan_hard_start_xmit(skb, dev); + + ret = wlan_hard_start_xmit(skb, dev); + lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret); + return ret; } static void wlan_tx_timeout(struct net_device *dev) { wlan_private *priv = (wlan_private *) dev->priv; - ENTER(); + lbs_deb_enter(LBS_DEB_TX); - lbs_pr_err("tx watch dog timeout!\n"); + lbs_pr_err("tx watch dog timeout\n"); - priv->wlan_dev.dnld_sent = DNLD_RES_RECEIVED; + priv->dnld_sent = DNLD_RES_RECEIVED; dev->trans_start = jiffies; if (priv->adapter->currenttxskb) { @@ -550,10 +439,12 @@ static void wlan_tx_timeout(struct net_device *dev) libertas_send_tx_feedback(priv); } else wake_up_interruptible(&priv->mainthread.waitq); - } else if (priv->adapter->connect_status == libertas_connected) - netif_wake_queue(priv->wlan_dev.netdev); + } else if (priv->adapter->connect_status == libertas_connected) { + netif_wake_queue(priv->dev); + netif_wake_queue(priv->mesh_dev); + } - LEAVE(); + lbs_deb_leave(LBS_DEB_TX); } /** @@ -576,7 +467,10 @@ static int wlan_set_mac_address(struct net_device *dev, void *addr) wlan_adapter *adapter = priv->adapter; struct sockaddr *phwaddr = addr; - ENTER(); + lbs_deb_enter(LBS_DEB_NET); + + /* In case it was called from the mesh device */ + dev = priv->dev ; memset(adapter->current_addr, 0, ETH_ALEN); @@ -591,17 +485,18 @@ static int wlan_set_mac_address(struct net_device *dev, void *addr) cmd_option_waitforrsp, 0, NULL); if (ret) { - lbs_pr_debug(1, "set mac address failed.\n"); + lbs_deb_net("set MAC address failed\n"); ret = -1; goto done; } lbs_dbg_hex("adapter->macaddr:", adapter->current_addr, ETH_ALEN); memcpy(dev->dev_addr, adapter->current_addr, ETH_ALEN); - memcpy(((wlan_private *) dev->priv)->mesh_dev->dev_addr, adapter->current_addr, ETH_ALEN); + if (priv->mesh_dev) + memcpy(priv->mesh_dev->dev_addr, adapter->current_addr, ETH_ALEN); done: - LEAVE(); + lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret); return ret; } @@ -626,12 +521,12 @@ static void wlan_set_multicast_list(struct net_device *dev) wlan_adapter *adapter = priv->adapter; int oldpacketfilter; - ENTER(); + lbs_deb_enter(LBS_DEB_NET); oldpacketfilter = adapter->currentpacketfilter; if (dev->flags & IFF_PROMISC) { - lbs_pr_debug(1, "enable Promiscuous mode\n"); + lbs_deb_net("enable promiscuous mode\n"); adapter->currentpacketfilter |= cmd_act_mac_promiscuous_enable; adapter->currentpacketfilter &= @@ -644,7 +539,7 @@ static void wlan_set_multicast_list(struct net_device *dev) if (dev->flags & IFF_ALLMULTI || dev->mc_count > MRVDRV_MAX_MULTICAST_LIST_SIZE) { - lbs_pr_debug(1, "Enabling All Multicast!\n"); + lbs_deb_net( "enabling all multicast\n"); adapter->currentpacketfilter |= cmd_act_mac_all_multicast_enable; adapter->currentpacketfilter &= @@ -654,8 +549,8 @@ static void wlan_set_multicast_list(struct net_device *dev) ~cmd_act_mac_all_multicast_enable; if (!dev->mc_count) { - lbs_pr_debug(1, "No multicast addresses - " - "disabling multicast!\n"); + lbs_deb_net("no multicast addresses, " + "disabling multicast\n"); adapter->currentpacketfilter &= ~cmd_act_mac_multicast_enable; } else { @@ -667,12 +562,12 @@ static void wlan_set_multicast_list(struct net_device *dev) adapter->nr_of_multicastmacaddr = wlan_copy_multicast_address(adapter, dev); - lbs_pr_debug(1, "Multicast addresses: %d\n", + lbs_deb_net("multicast addresses: %d\n", dev->mc_count); for (i = 0; i < dev->mc_count; i++) { - lbs_pr_debug(1, "Multicast address %d:" - "%x %x %x %x %x %x\n", i, + lbs_deb_net("Multicast address %d:" + MAC_FMT "\n", i, adapter->multicastlist[i][0], adapter->multicastlist[i][1], adapter->multicastlist[i][2], @@ -680,7 +575,7 @@ static void wlan_set_multicast_list(struct net_device *dev) adapter->multicastlist[i][4], adapter->multicastlist[i][5]); } - /* set multicast addresses to firmware */ + /* send multicast addresses to firmware */ libertas_prepare_and_send_command(priv, cmd_mac_multicast_adr, cmd_act_set, 0, 0, @@ -693,13 +588,13 @@ static void wlan_set_multicast_list(struct net_device *dev) libertas_set_mac_packet_filter(priv); } - LEAVE(); + lbs_deb_leave(LBS_DEB_NET); } /** - * @brief This function hanldes the major job in WLAN driver. - * it handles the event generated by firmware, rx data received - * from firmware and tx data sent from kernel. + * @brief This function handles the major jobs in the WLAN driver. + * It handles all events generated by firmware, RX data received + * from firmware and TX data sent from kernel. * * @param data A pointer to wlan_thread structure * @return 0 @@ -712,26 +607,26 @@ static int wlan_service_main_thread(void *data) wait_queue_t wait; u8 ireg = 0; - ENTER(); + lbs_deb_enter(LBS_DEB_THREAD); wlan_activate_thread(thread); init_waitqueue_entry(&wait, current); for (;;) { - lbs_pr_debug(1, "main-thread 111: intcounter=%d " + lbs_deb_thread( "main-thread 111: intcounter=%d " "currenttxskb=%p dnld_sent=%d\n", adapter->intcounter, - adapter->currenttxskb, priv->wlan_dev.dnld_sent); + adapter->currenttxskb, priv->dnld_sent); add_wait_queue(&thread->waitq, &wait); set_current_state(TASK_INTERRUPTIBLE); spin_lock_irq(&adapter->driver_lock); if ((adapter->psstate == PS_STATE_SLEEP) || (!adapter->intcounter - && (priv->wlan_dev.dnld_sent || adapter->cur_cmd || + && (priv->dnld_sent || adapter->cur_cmd || list_empty(&adapter->cmdpendingq)))) { - lbs_pr_debug(1, + lbs_deb_thread( "main-thread sleeping... Conn=%d IntC=%d PS_mode=%d PS_State=%d\n", adapter->connect_status, adapter->intcounter, adapter->psmode, adapter->psstate); @@ -741,23 +636,23 @@ static int wlan_service_main_thread(void *data) spin_unlock_irq(&adapter->driver_lock); - lbs_pr_debug(1, + lbs_deb_thread( "main-thread 222 (waking up): intcounter=%d currenttxskb=%p " "dnld_sent=%d\n", adapter->intcounter, - adapter->currenttxskb, priv->wlan_dev.dnld_sent); + adapter->currenttxskb, priv->dnld_sent); set_current_state(TASK_RUNNING); remove_wait_queue(&thread->waitq, &wait); try_to_freeze(); - lbs_pr_debug(1, "main-thread 333: intcounter=%d currenttxskb=%p " + lbs_deb_thread("main-thread 333: intcounter=%d currenttxskb=%p " "dnld_sent=%d\n", adapter->intcounter, - adapter->currenttxskb, priv->wlan_dev.dnld_sent); + adapter->currenttxskb, priv->dnld_sent); if (kthread_should_stop() || adapter->surpriseremoved) { - lbs_pr_debug(1, + lbs_deb_thread( "main-thread: break from main thread: surpriseremoved=0x%x\n", adapter->surpriseremoved); break; @@ -768,10 +663,10 @@ static int wlan_service_main_thread(void *data) if (adapter->intcounter) { u8 int_status; adapter->intcounter = 0; - int_status = libertas_sbi_get_int_status(priv, &ireg); + int_status = priv->hw_get_int_status(priv, &ireg); if (int_status) { - lbs_pr_debug(1, + lbs_deb_thread( "main-thread: reading HOST_INT_STATUS_REG failed\n"); spin_unlock_irq(&adapter->driver_lock); continue; @@ -779,14 +674,14 @@ static int wlan_service_main_thread(void *data) adapter->hisregcpy |= ireg; } - lbs_pr_debug(1, "main-thread 444: intcounter=%d currenttxskb=%p " + lbs_deb_thread("main-thread 444: intcounter=%d currenttxskb=%p " "dnld_sent=%d\n", adapter->intcounter, - adapter->currenttxskb, priv->wlan_dev.dnld_sent); + adapter->currenttxskb, priv->dnld_sent); /* command response? */ if (adapter->hisregcpy & his_cmdupldrdy) { - lbs_pr_debug(1, "main-thread: cmd response ready.\n"); + lbs_deb_thread("main-thread: cmd response ready\n"); adapter->hisregcpy &= ~his_cmdupldrdy; spin_unlock_irq(&adapter->driver_lock); @@ -796,13 +691,13 @@ static int wlan_service_main_thread(void *data) /* Any Card Event */ if (adapter->hisregcpy & his_cardevent) { - lbs_pr_debug(1, "main-thread: Card Event Activity.\n"); + lbs_deb_thread("main-thread: Card Event Activity\n"); adapter->hisregcpy &= ~his_cardevent; - if (libertas_sbi_read_event_cause(priv)) { + if (priv->hw_read_event_cause(priv)) { lbs_pr_alert( - "main-thread: libertas_sbi_read_event_cause failed.\n"); + "main-thread: hw_read_event_cause failed\n"); spin_unlock_irq(&adapter->driver_lock); continue; } @@ -813,15 +708,15 @@ static int wlan_service_main_thread(void *data) /* Check if we need to confirm Sleep Request received previously */ if (adapter->psstate == PS_STATE_PRE_SLEEP) { - if (!priv->wlan_dev.dnld_sent && !adapter->cur_cmd) { + if (!priv->dnld_sent && !adapter->cur_cmd) { if (adapter->connect_status == libertas_connected) { - lbs_pr_debug(1, + lbs_deb_thread( "main_thread: PRE_SLEEP--intcounter=%d currenttxskb=%p " "dnld_sent=%d cur_cmd=%p, confirm now\n", adapter->intcounter, adapter->currenttxskb, - priv->wlan_dev.dnld_sent, + priv->dnld_sent, adapter->cur_cmd); libertas_ps_confirm_sleep(priv, @@ -847,7 +742,7 @@ static int wlan_service_main_thread(void *data) continue; /* Execute the next command */ - if (!priv->wlan_dev.dnld_sent && !priv->adapter->cur_cmd) + if (!priv->dnld_sent && !priv->adapter->cur_cmd) libertas_execute_next_command(priv); /* Wake-up command waiters which can't sleep in @@ -864,7 +759,7 @@ static int wlan_service_main_thread(void *data) wake_up_all(&adapter->cmd_pending); wlan_deactivate_thread(thread); - LEAVE(); + lbs_deb_leave(LBS_DEB_THREAD); return 0; } @@ -875,166 +770,203 @@ static int wlan_service_main_thread(void *data) * @param card A pointer to card * @return A pointer to wlan_private structure */ -wlan_private *wlan_add_card(void *card) +wlan_private *libertas_add_card(void *card, struct device *dmdev) { struct net_device *dev = NULL; - struct net_device *mesh_dev = NULL; wlan_private *priv = NULL; - ENTER(); + lbs_deb_enter(LBS_DEB_NET); /* Allocate an Ethernet device and register it */ if (!(dev = alloc_etherdev(sizeof(wlan_private)))) { - lbs_pr_alert( "Init ethernet device failed!\n"); + lbs_pr_err("init ethX device failed\n"); return NULL; } - priv = dev->priv; /* allocate buffer for wlan_adapter */ - if (!(priv->adapter = kmalloc(sizeof(wlan_adapter), GFP_KERNEL))) { - lbs_pr_alert( "Allocate buffer for wlan_adapter failed!\n"); - goto err_kmalloc; - } - - /* Allocate a virtual mesh device */ - if (!(mesh_dev = alloc_netdev(0, "msh%d", ether_setup))) { - lbs_pr_debug(1, "Init ethernet device failed!\n"); - return NULL; + if (!(priv->adapter = kzalloc(sizeof(wlan_adapter), GFP_KERNEL))) { + lbs_pr_err("allocate buffer for wlan_adapter failed\n"); + goto err_kzalloc; } - /* Both intervaces share the priv structure */ - mesh_dev->priv = priv; - - /* init wlan_adapter */ - memset(priv->adapter, 0, sizeof(wlan_adapter)); - - priv->wlan_dev.netdev = dev; - priv->wlan_dev.card = card; + priv->dev = dev; + priv->card = card; priv->mesh_open = 0; priv->infra_open = 0; - priv->mesh_dev = mesh_dev; - wlanpriv = priv; SET_MODULE_OWNER(dev); - SET_MODULE_OWNER(mesh_dev); /* Setup the OS Interface to our functions */ 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; - 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; - memcpy(mesh_dev->dev_addr, wlanpriv->wlan_dev.netdev->dev_addr, - sizeof(wlanpriv->wlan_dev.netdev->dev_addr)); - -#define WLAN_WATCHDOG_TIMEOUT (5 * HZ) - dev->tx_timeout = wlan_tx_timeout; dev->get_stats = wlan_get_stats; - dev->watchdog_timeo = WLAN_WATCHDOG_TIMEOUT; + dev->watchdog_timeo = 5 * HZ; dev->ethtool_ops = &libertas_ethtool_ops; - mesh_dev->get_stats = wlan_get_stats; - mesh_dev->ethtool_ops = &libertas_ethtool_ops; - #ifdef WIRELESS_EXT dev->wireless_handlers = (struct iw_handler_def *)&libertas_handler_def; - mesh_dev->wireless_handlers = (struct iw_handler_def *)&libertas_handler_def; #endif #define NETIF_F_DYNALLOC 16 dev->features |= NETIF_F_DYNALLOC; dev->flags |= IFF_BROADCAST | IFF_MULTICAST; dev->set_multicast_list = wlan_set_multicast_list; + SET_NETDEV_DEV(dev, dmdev); + INIT_LIST_HEAD(&priv->adapter->cmdfreeq); INIT_LIST_HEAD(&priv->adapter->cmdpendingq); spin_lock_init(&priv->adapter->driver_lock); init_waitqueue_head(&priv->adapter->cmd_pending); priv->adapter->nr_cmd_pending = 0; + goto done; + +err_kzalloc: + free_netdev(dev); + priv = NULL; +done: + lbs_deb_leave_args(LBS_DEB_NET, "priv %p", priv); + return priv; +} +EXPORT_SYMBOL_GPL(libertas_add_card); - lbs_pr_debug(1, "Starting kthread...\n"); +int libertas_activate_card(wlan_private *priv, char *fw_name) +{ + struct net_device *dev = priv->dev; + int ret = -1; + + lbs_deb_enter(LBS_DEB_MAIN); + + lbs_deb_thread("Starting kthread...\n"); priv->mainthread.priv = priv; wlan_create_thread(wlan_service_main_thread, &priv->mainthread, "wlan_main_service"); priv->assoc_thread = create_singlethread_workqueue("libertas_assoc"); - INIT_DELAYED_WORK(&priv->assoc_work, wlan_association_worker); + INIT_DELAYED_WORK(&priv->assoc_work, libertas_association_worker); + INIT_WORK(&priv->sync_channel, libertas_sync_channel); /* * Register the device. Fillup the private data structure with * relevant information from the card and request for the required * IRQ. */ - if (libertas_sbi_register_dev(priv) < 0) { - lbs_pr_info("failed to register wlan device!\n"); + if (priv->hw_register_dev(priv) < 0) { + lbs_pr_err("failed to register WLAN device\n"); goto err_registerdev; } /* init FW and HW */ - if (libertas_init_fw(priv)) { - lbs_pr_debug(1, "Firmware Init failed\n"); + if (fw_name && libertas_init_fw(priv, fw_name)) { + lbs_pr_err("firmware init failed\n"); goto err_registerdev; } if (register_netdev(dev)) { - lbs_pr_err("Cannot register network device!\n"); - goto err_init_fw; - } - - /* Register virtual mesh interface */ - if (register_netdev(mesh_dev)) { - lbs_pr_info("Cannot register mesh virtual interface!\n"); + lbs_pr_err("cannot register ethX device\n"); goto err_init_fw; } - lbs_pr_info("%s: Marvell Wlan 802.11 adapter ", dev->name); + lbs_pr_info("%s: Marvell WLAN 802.11 adapter\n", dev->name); libertas_debugfs_init_one(priv, dev); - if (libertas_found == MAX_DEVS) - goto err_init_fw; - libertas_devs[libertas_found] = dev; - libertas_found++; -#ifdef ENABLE_PM - if (!(wlan_pm_dev = pm_register(PM_UNKNOWN_DEV, 0, wlan_pm_callback))) - lbs_pr_alert( "failed to register PM callback\n"); -#endif - if (device_create_file(&(mesh_dev->dev), &dev_attr_libertas_mpp)) - goto err_create_file; + ret = 0; + goto done; - LEAVE(); - return priv; - -err_create_file: - device_remove_file(&(mesh_dev->dev), &dev_attr_libertas_mpp); err_init_fw: - libertas_sbi_unregister_dev(priv); + priv->hw_unregister_dev(priv); err_registerdev: destroy_workqueue(priv->assoc_thread); /* Stop the thread servicing the interrupts */ wake_up_interruptible(&priv->mainthread.waitq); wlan_terminate_thread(&priv->mainthread); - kfree(priv->adapter); -err_kmalloc: - free_netdev(dev); +done: + lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret); + return ret; +} +EXPORT_SYMBOL_GPL(libertas_activate_card); + + +/** + * @brief This function adds mshX interface + * + * @param priv A pointer to the wlan_private structure + * @return 0 if successful, -X otherwise + */ +int libertas_add_mesh(wlan_private *priv, struct device *dev) +{ + struct net_device *mesh_dev = NULL; + int ret = 0; + + lbs_deb_enter(LBS_DEB_MESH); + + /* Allocate a virtual mesh device */ + if (!(mesh_dev = alloc_netdev(0, "msh%d", ether_setup))) { + lbs_deb_mesh("init mshX device failed\n"); + ret = -ENOMEM; + goto done; + } + mesh_dev->priv = priv; + priv->mesh_dev = mesh_dev; + + SET_MODULE_OWNER(mesh_dev); + + mesh_dev->open = mesh_open; + mesh_dev->hard_start_xmit = mesh_pre_start_xmit; + mesh_dev->stop = mesh_close; + mesh_dev->get_stats = wlan_get_stats; + mesh_dev->set_mac_address = wlan_set_mac_address; + mesh_dev->ethtool_ops = &libertas_ethtool_ops; + memcpy(mesh_dev->dev_addr, priv->dev->dev_addr, + sizeof(priv->dev->dev_addr)); + + SET_NETDEV_DEV(priv->mesh_dev, dev); + +#ifdef WIRELESS_EXT + mesh_dev->wireless_handlers = (struct iw_handler_def *)&mesh_handler_def; +#endif +#define NETIF_F_DYNALLOC 16 + + /* Register virtual mesh interface */ + ret = register_netdev(mesh_dev); + if (ret) { + lbs_pr_err("cannot register mshX virtual interface\n"); + goto err_free; + } + + ret = device_create_file(&(mesh_dev->dev), &dev_attr_anycast_mask); + if (ret) + goto err_unregister; + + /* Everything successful */ + ret = 0; + goto done; + + +err_unregister: + unregister_netdev(mesh_dev); + +err_free: free_netdev(mesh_dev); - wlanpriv = NULL; - LEAVE(); - return NULL; +done: + lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret); + return ret; } +EXPORT_SYMBOL_GPL(libertas_add_mesh); static void wake_pending_cmdnodes(wlan_private *priv) { struct cmd_ctrl_node *cmdnode; unsigned long flags; + lbs_deb_enter(LBS_DEB_CMD); + spin_lock_irqsave(&priv->adapter->driver_lock, flags); list_for_each_entry(cmdnode, &priv->adapter->cmdpendingq, list) { cmdnode->cmdwaitqwoken = 1; @@ -1044,40 +976,29 @@ static void wake_pending_cmdnodes(wlan_private *priv) } -int wlan_remove_card(void *card) +int libertas_remove_card(wlan_private *priv) { - wlan_private *priv = libertas_sbi_get_priv(card); wlan_adapter *adapter; struct net_device *dev; - struct net_device *mesh_dev; union iwreq_data wrqu; - int i; - ENTER(); + lbs_deb_enter(LBS_DEB_NET); - if (!priv) { - LEAVE(); - return 0; - } + if (!priv) + goto out; adapter = priv->adapter; - if (!adapter) { - LEAVE(); - return 0; - } + if (!adapter) + goto out; - dev = priv->wlan_dev.netdev; - mesh_dev = priv->mesh_dev; + dev = priv->dev; - netif_stop_queue(mesh_dev); - netif_stop_queue(priv->wlan_dev.netdev); - netif_carrier_off(priv->wlan_dev.netdev); + netif_stop_queue(priv->dev); + netif_carrier_off(priv->dev); wake_pending_cmdnodes(priv); - device_remove_file(&(mesh_dev->dev), &dev_attr_libertas_mpp); - unregister_netdev(mesh_dev); unregister_netdev(dev); cancel_delayed_work(&priv->assoc_work); @@ -1090,11 +1011,7 @@ int wlan_remove_card(void *card) memset(wrqu.ap_addr.sa_data, 0xaa, ETH_ALEN); wrqu.ap_addr.sa_family = ARPHRD_ETHER; - wireless_send_event(priv->wlan_dev.netdev, SIOCGIWAP, &wrqu, NULL); - -#ifdef ENABLE_PM - pm_unregister(wlan_pm_dev); -#endif + wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL); adapter->surpriseremoved = 1; @@ -1103,28 +1020,45 @@ int wlan_remove_card(void *card) libertas_debugfs_remove_one(priv); - lbs_pr_debug(1, "Free adapter\n"); + lbs_deb_net("free adapter\n"); libertas_free_adapter(priv); - for (i = 0; i<libertas_found; i++) { - if (libertas_devs[i]==priv->wlan_dev.netdev) { - libertas_devs[i] = libertas_devs[--libertas_found]; - libertas_devs[libertas_found] = NULL ; - break ; - } - } + lbs_deb_net("unregister finish\n"); + + priv->dev = NULL; + free_netdev(dev); + +out: + lbs_deb_leave(LBS_DEB_NET); + return 0; +} +EXPORT_SYMBOL_GPL(libertas_remove_card); + + +void libertas_remove_mesh(wlan_private *priv) +{ + struct net_device *mesh_dev; + + lbs_deb_enter(LBS_DEB_NET); + + if (!priv) + goto out; + + mesh_dev = priv->mesh_dev; + + netif_stop_queue(mesh_dev); + netif_carrier_off(priv->mesh_dev); - lbs_pr_debug(1, "Unregister finish\n"); + device_remove_file(&(mesh_dev->dev), &dev_attr_anycast_mask); + unregister_netdev(mesh_dev); - priv->wlan_dev.netdev = NULL; priv->mesh_dev = NULL ; free_netdev(mesh_dev); - free_netdev(dev); - wlanpriv = NULL; - LEAVE(); - return 0; +out: + lbs_deb_leave(LBS_DEB_NET); } +EXPORT_SYMBOL_GPL(libertas_remove_mesh); /** * @brief This function finds the CFP in @@ -1139,33 +1073,34 @@ struct chan_freq_power *libertas_get_region_cfp_table(u8 region, u8 band, int *c { int i, end; - ENTER(); + lbs_deb_enter(LBS_DEB_MAIN); end = sizeof(region_cfp_table)/sizeof(struct region_cfp_table); for (i = 0; i < end ; i++) { - lbs_pr_debug(1, "region_cfp_table[i].region=%d\n", + lbs_deb_main("region_cfp_table[i].region=%d\n", region_cfp_table[i].region); if (region_cfp_table[i].region == region) { *cfp_no = region_cfp_table[i].cfp_no_BG; - LEAVE(); + lbs_deb_leave(LBS_DEB_MAIN); return region_cfp_table[i].cfp_BG; } } - LEAVE(); + lbs_deb_leave_args(LBS_DEB_MAIN, "ret NULL"); return NULL; } int libertas_set_regiontable(wlan_private * priv, u8 region, u8 band) { wlan_adapter *adapter = priv->adapter; + int ret = 0; int i = 0; struct chan_freq_power *cfp; int cfp_no; - ENTER(); + lbs_deb_enter(LBS_DEB_MAIN); memset(adapter->region_channel, 0, sizeof(adapter->region_channel)); @@ -1175,17 +1110,19 @@ int libertas_set_regiontable(wlan_private * priv, u8 region, u8 band) adapter->region_channel[i].nrcfp = cfp_no; adapter->region_channel[i].CFP = cfp; } else { - lbs_pr_debug(1, "wrong region code %#x in band B-G\n", + lbs_deb_main("wrong region code %#x in band B/G\n", region); - return -1; + ret = -1; + goto out; } adapter->region_channel[i].valid = 1; adapter->region_channel[i].region = region; adapter->region_channel[i].band = band; i++; } - LEAVE(); - return 0; +out: + lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret); + return ret; } /** @@ -1200,9 +1137,9 @@ void libertas_interrupt(struct net_device *dev) { wlan_private *priv = dev->priv; - ENTER(); + lbs_deb_enter(LBS_DEB_THREAD); - lbs_pr_debug(1, "libertas_interrupt: intcounter=%d\n", + lbs_deb_thread("libertas_interrupt: intcounter=%d\n", priv->adapter->intcounter); priv->adapter->intcounter++; @@ -1210,56 +1147,35 @@ void libertas_interrupt(struct net_device *dev) if (priv->adapter->psstate == PS_STATE_SLEEP) { priv->adapter->psstate = PS_STATE_AWAKE; netif_wake_queue(dev); + netif_wake_queue(priv->mesh_dev); } wake_up_interruptible(&priv->mainthread.waitq); - LEAVE(); + lbs_deb_leave(LBS_DEB_THREAD); } +EXPORT_SYMBOL_GPL(libertas_interrupt); -static int wlan_init_module(void) +static int libertas_init_module(void) { - int ret = 0; - - ENTER(); - - if (libertas_fw_name == NULL) { - libertas_fw_name = default_fw_name; - } - + lbs_deb_enter(LBS_DEB_MAIN); libertas_debugfs_init(); - - if (libertas_sbi_register()) { - ret = -1; - libertas_debugfs_remove(); - goto done; - } - -done: - LEAVE(); - return ret; + lbs_deb_leave(LBS_DEB_MAIN); + return 0; } -static void wlan_cleanup_module(void) +static void libertas_exit_module(void) { - int i; - - ENTER(); - - for (i = 0; i<libertas_found; i++) { - wlan_private *priv = libertas_devs[i]->priv; - reset_device(priv); - } + lbs_deb_enter(LBS_DEB_MAIN); - libertas_sbi_unregister(); libertas_debugfs_remove(); - LEAVE(); + lbs_deb_leave(LBS_DEB_MAIN); } -module_init(wlan_init_module); -module_exit(wlan_cleanup_module); +module_init(libertas_init_module); +module_exit(libertas_exit_module); -MODULE_DESCRIPTION("M-WLAN Driver"); +MODULE_DESCRIPTION("Libertas WLAN Driver Library"); MODULE_AUTHOR("Marvell International Ltd."); MODULE_LICENSE("GPL"); diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c index 96619a32951..88d9d2d787d 100644 --- a/drivers/net/wireless/libertas/rx.c +++ b/drivers/net/wireless/libertas/rx.c @@ -106,10 +106,10 @@ static void wlan_compute_rssi(wlan_private * priv, struct rxpd *p_rx_pd) { wlan_adapter *adapter = priv->adapter; - ENTER(); + lbs_deb_enter(LBS_DEB_RX); - lbs_pr_debug(1, "rxpd: SNR = %d, NF = %d\n", p_rx_pd->snr, p_rx_pd->nf); - lbs_pr_debug(1, "Before computing SNR: SNR- avg = %d, NF-avg = %d\n", + lbs_deb_rx("rxpd: SNR %d, NF %d\n", p_rx_pd->snr, p_rx_pd->nf); + lbs_deb_rx("before computing SNR: SNR-avg = %d, NF-avg = %d\n", adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE, adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE); @@ -121,7 +121,7 @@ static void wlan_compute_rssi(wlan_private * priv, struct rxpd *p_rx_pd) adapter->SNR[TYPE_RXPD][TYPE_AVG] = wlan_getavgsnr(priv) * AVG_SCALE; adapter->NF[TYPE_RXPD][TYPE_AVG] = wlan_getavgnf(priv) * AVG_SCALE; - lbs_pr_debug(1, "After computing SNR: SNR-avg = %d, NF-avg = %d\n", + lbs_deb_rx("after computing SNR: SNR-avg = %d, NF-avg = %d\n", adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE, adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE); @@ -133,18 +133,17 @@ static void wlan_compute_rssi(wlan_private * priv, struct rxpd *p_rx_pd) CAL_RSSI(adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE, adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE); - LEAVE(); + lbs_deb_leave(LBS_DEB_RX); } void libertas_upload_rx_packet(wlan_private * priv, struct sk_buff *skb) { - lbs_pr_debug(1, "skb->data=%p\n", skb->data); + lbs_deb_rx("skb->data %p\n", skb->data); - if(IS_MESH_FRAME(skb)) - skb->dev = priv->mesh_dev; + if (priv->mesh_dev && IS_MESH_FRAME(skb)) + skb->protocol = eth_type_trans(skb, priv->mesh_dev); else - skb->dev = priv->wlan_dev.netdev; - skb->protocol = eth_type_trans(skb, priv->wlan_dev.netdev); + skb->protocol = eth_type_trans(skb, priv->dev); skb->ip_summed = CHECKSUM_UNNECESSARY; netif_rx(skb); @@ -171,7 +170,7 @@ int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *skb) const u8 rfc1042_eth_hdr[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; - ENTER(); + lbs_deb_enter(LBS_DEB_RX); if (priv->adapter->debugmode & MRVDRV_DEBUG_RX_PATH) lbs_dbg_hex("RX packet: ", skb->data, @@ -191,7 +190,7 @@ int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *skb) min_t(unsigned int, skb->len, 100)); if (skb->len < (ETH_HLEN + 8 + sizeof(struct rxpd))) { - lbs_pr_debug(1, "RX error: FRAME RECEIVED WITH BAD LENGTH\n"); + lbs_deb_rx("rx err: frame received with bad length\n"); priv->stats.rx_length_errors++; ret = 0; goto done; @@ -200,15 +199,15 @@ int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *skb) /* * Check rxpd status and update 802.3 stat, */ - if (!(p_rx_pd->status & MRVDRV_RXPD_STATUS_OK)) { - lbs_pr_debug(1, "RX error: frame received with bad status\n"); - lbs_pr_alert("rxpd Not OK\n"); + if (!(p_rx_pd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK))) { + lbs_deb_rx("rx err: frame received with bad status\n"); + lbs_pr_alert("rxpd not ok\n"); priv->stats.rx_errors++; ret = 0; goto done; } - lbs_pr_debug(1, "RX Data: skb->len - sizeof(RxPd) = %d - %zd = %zd\n", + lbs_deb_rx("rx data: skb->len-sizeof(RxPd) = %d-%zd = %zd\n", skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd)); lbs_dbg_hex("RX Data: Dest", p_rx_pkt->eth803_hdr.dest_addr, @@ -266,7 +265,7 @@ int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *skb) wlan_compute_rssi(priv, p_rx_pd); - lbs_pr_debug(1, "RX Data: size of actual packet = %d\n", skb->len); + lbs_deb_rx("rx data: size of actual packet %d\n", skb->len); priv->stats.rx_bytes += skb->len; priv->stats.rx_packets++; @@ -274,10 +273,10 @@ int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *skb) ret = 0; done: - LEAVE(); - + lbs_deb_leave_args(LBS_DEB_RX, "ret %d", ret); return ret; } +EXPORT_SYMBOL_GPL(libertas_process_rxed_packet); /** * @brief This function converts Tx/Rx rates from the Marvell WLAN format @@ -314,7 +313,7 @@ static u8 convert_mv_rate_to_radiotap(u8 rate) case 11: /* 54 Mbps */ return 108; } - lbs_pr_alert( "Invalid Marvell WLAN rate (%i)\n", rate); + lbs_pr_alert("Invalid Marvell WLAN rate %i\n", rate); return 0; } @@ -336,7 +335,7 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb) struct rx_radiotap_hdr radiotap_hdr; struct rx_radiotap_hdr *pradiotap_hdr; - ENTER(); + lbs_deb_enter(LBS_DEB_RX); p_rx_pkt = (struct rx80211packethdr *) skb->data; prxpd = &p_rx_pkt->rx_pd; @@ -344,7 +343,7 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb) // lbs_dbg_hex("RX Data: Before chop rxpd", skb->data, min(skb->len, 100)); if (skb->len < (ETH_HLEN + 8 + sizeof(struct rxpd))) { - lbs_pr_debug(1, "RX error: FRAME RECEIVED WITH BAD LENGTH\n"); + lbs_deb_rx("rx err: frame received wit bad length\n"); priv->stats.rx_length_errors++; ret = 0; goto done; @@ -353,12 +352,12 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb) /* * Check rxpd status and update 802.3 stat, */ - if (!(prxpd->status & MRVDRV_RXPD_STATUS_OK)) { - //lbs_pr_debug(1, "RX error: frame received with bad status\n"); + if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK))) { + //lbs_deb_rx("rx err: frame received with bad status\n"); priv->stats.rx_errors++; } - lbs_pr_debug(1, "RX Data: skb->len - sizeof(RxPd) = %d - %zd = %zd\n", + lbs_deb_rx("rx data: skb->len-sizeof(RxPd) = %d-%zd = %zd\n", skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd)); /* create the exported radio header */ @@ -386,7 +385,7 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb) /* XXX must check no carryout */ radiotap_hdr.antsignal = prxpd->snr + prxpd->nf; radiotap_hdr.rx_flags = 0; - if (!(prxpd->status & MRVDRV_RXPD_STATUS_OK)) + if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK))) radiotap_hdr.rx_flags |= IEEE80211_RADIOTAP_F_RX_BADFCS; //memset(radiotap_hdr.pad, 0x11, IEEE80211_RADIOTAP_HDRLEN - 18); @@ -399,7 +398,7 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb) if ((skb_headroom(skb) < sizeof(struct rx_radiotap_hdr)) && pskb_expand_head(skb, sizeof(struct rx_radiotap_hdr), 0, GFP_ATOMIC)) { - lbs_pr_alert( "%s: couldn't pskb_expand_head\n", + lbs_pr_alert("%s: couldn't pskb_expand_head\n", __func__); } @@ -414,7 +413,7 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb) default: /* unknown header */ - lbs_pr_alert( "Unknown radiomode (%i)\n", + lbs_pr_alert("Unknown radiomode %i\n", priv->adapter->radiomode); /* don't export any header */ /* chop the rxpd */ @@ -431,15 +430,16 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb) wlan_compute_rssi(priv, prxpd); - lbs_pr_debug(1, "RX Data: size of actual packet = %d\n", skb->len); + lbs_deb_rx("rx data: size of actual packet %d\n", skb->len); priv->stats.rx_bytes += skb->len; priv->stats.rx_packets++; libertas_upload_rx_packet(priv, skb); ret = 0; -done: - LEAVE(); - return (ret); +done: + skb->protocol = __constant_htons(0x0019); /* ETH_P_80211_RAW */ + lbs_deb_leave_args(LBS_DEB_RX, "ret %d", ret); + return ret; } diff --git a/drivers/net/wireless/libertas/sbi.h b/drivers/net/wireless/libertas/sbi.h deleted file mode 100644 index 59d3a59ccef..00000000000 --- a/drivers/net/wireless/libertas/sbi.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - * This file contains IF layer definitions. - */ - -#ifndef _SBI_H_ -#define _SBI_H_ - -#include <linux/interrupt.h> - -#include "defs.h" - -/** INT status Bit Definition*/ -#define his_cmddnldrdy 0x01 -#define his_cardevent 0x02 -#define his_cmdupldrdy 0x04 - -#ifndef DEV_NAME_LEN -#define DEV_NAME_LEN 32 -#endif - -#define SBI_EVENT_CAUSE_SHIFT 3 - -/* Probe and Check if the card is present*/ -int libertas_sbi_register_dev(wlan_private * priv); -int libertas_sbi_unregister_dev(wlan_private *); -int libertas_sbi_get_int_status(wlan_private * priv, u8 *); -int libertas_sbi_register(void); -void libertas_sbi_unregister(void); -int libertas_sbi_prog_firmware(wlan_private *); - -int libertas_sbi_read_event_cause(wlan_private *); -int libertas_sbi_host_to_card(wlan_private * priv, u8 type, u8 * payload, u16 nb); -wlan_private *libertas_sbi_get_priv(void *card); - -#ifdef ENABLE_PM -int libertas_sbi_suspend(wlan_private *); -int libertas_sbi_resume(wlan_private *); -#endif - -#endif /* _SBI_H */ diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c index 3c0b1a2a172..c3043dcb541 100644 --- a/drivers/net/wireless/libertas/scan.c +++ b/drivers/net/wireless/libertas/scan.c @@ -8,6 +8,7 @@ #include <linux/if.h> #include <linux/netdevice.h> #include <linux/wireless.h> +#include <linux/etherdevice.h> #include <net/ieee80211.h> #include <net/iw_handler.h> @@ -58,12 +59,82 @@ //! Scan time specified in the channel TLV for each channel for active scans #define MRVDRV_ACTIVE_SCAN_CHAN_TIME 100 -//! Macro to enable/disable SSID checking before storing a scan table -#ifdef DISCARD_BAD_SSID -#define CHECK_SSID_IS_VALID(x) ssid_valid(&bssidEntry.ssid) -#else -#define CHECK_SSID_IS_VALID(x) 1 -#endif +static const u8 zeromac[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static const u8 bcastmac[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + +static inline void clear_bss_descriptor (struct bss_descriptor * bss) +{ + /* Don't blow away ->list, just BSS data */ + memset(bss, 0, offsetof(struct bss_descriptor, list)); +} + +static inline int match_bss_no_security(struct wlan_802_11_security * secinfo, + struct bss_descriptor * match_bss) +{ + if ( !secinfo->wep_enabled + && !secinfo->WPAenabled + && !secinfo->WPA2enabled + && match_bss->wpa_ie[0] != WPA_IE + && match_bss->rsn_ie[0] != WPA2_IE + && !match_bss->privacy) { + return 1; + } + return 0; +} + +static inline int match_bss_static_wep(struct wlan_802_11_security * secinfo, + struct bss_descriptor * match_bss) +{ + if ( secinfo->wep_enabled + && !secinfo->WPAenabled + && !secinfo->WPA2enabled + && match_bss->privacy) { + return 1; + } + return 0; +} + +static inline int match_bss_wpa(struct wlan_802_11_security * secinfo, + struct bss_descriptor * match_bss) +{ + if ( !secinfo->wep_enabled + && secinfo->WPAenabled + && (match_bss->wpa_ie[0] == WPA_IE) + /* privacy bit may NOT be set in some APs like LinkSys WRT54G + && bss->privacy */ + ) { + return 1; + } + return 0; +} + +static inline int match_bss_wpa2(struct wlan_802_11_security * secinfo, + struct bss_descriptor * match_bss) +{ + if ( !secinfo->wep_enabled + && secinfo->WPA2enabled + && (match_bss->rsn_ie[0] == WPA2_IE) + /* privacy bit may NOT be set in some APs like LinkSys WRT54G + && bss->privacy */ + ) { + return 1; + } + return 0; +} + +static inline int match_bss_dynamic_wep(struct wlan_802_11_security * secinfo, + struct bss_descriptor * match_bss) +{ + if ( !secinfo->wep_enabled + && !secinfo->WPAenabled + && !secinfo->WPA2enabled + && (match_bss->wpa_ie[0] != WPA_IE) + && (match_bss->rsn_ie[0] != WPA2_IE) + && match_bss->privacy) { + return 1; + } + return 0; +} /** * @brief Check if a scanned network compatible with the driver settings @@ -84,180 +155,63 @@ * * @return Index in scantable, or error code if negative */ -static int is_network_compatible(wlan_adapter * adapter, int index, u8 mode) +static int is_network_compatible(wlan_adapter * adapter, + struct bss_descriptor * bss, u8 mode) { - ENTER(); - - if (adapter->scantable[index].mode == mode) { - if ( !adapter->secinfo.wep_enabled - && !adapter->secinfo.WPAenabled - && !adapter->secinfo.WPA2enabled - && adapter->scantable[index].wpa_ie[0] != WPA_IE - && adapter->scantable[index].rsn_ie[0] != WPA2_IE - && !adapter->scantable[index].privacy) { - /* no security */ - LEAVE(); - return index; - } else if ( adapter->secinfo.wep_enabled - && !adapter->secinfo.WPAenabled - && !adapter->secinfo.WPA2enabled - && adapter->scantable[index].privacy) { - /* static WEP enabled */ - LEAVE(); - return index; - } else if ( !adapter->secinfo.wep_enabled - && adapter->secinfo.WPAenabled - && !adapter->secinfo.WPA2enabled - && (adapter->scantable[index].wpa_ie[0] == WPA_IE) - /* privacy bit may NOT be set in some APs like LinkSys WRT54G - && adapter->scantable[index].privacy */ - ) { - /* WPA enabled */ - lbs_pr_debug(1, - "is_network_compatible() WPA: index=%d wpa_ie=%#x " - "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s " - "privacy=%#x\n", index, - adapter->scantable[index].wpa_ie[0], - adapter->scantable[index].rsn_ie[0], - adapter->secinfo.wep_enabled ? "e" : "d", - adapter->secinfo.WPAenabled ? "e" : "d", - adapter->secinfo.WPA2enabled ? "e" : "d", - adapter->scantable[index].privacy); - LEAVE(); - return index; - } else if ( !adapter->secinfo.wep_enabled - && !adapter->secinfo.WPAenabled - && adapter->secinfo.WPA2enabled - && (adapter->scantable[index].rsn_ie[0] == WPA2_IE) - /* privacy bit may NOT be set in some APs like LinkSys WRT54G - && adapter->scantable[index].privacy */ - ) { - /* WPA2 enabled */ - lbs_pr_debug(1, - "is_network_compatible() WPA2: index=%d wpa_ie=%#x " - "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s " - "privacy=%#x\n", index, - adapter->scantable[index].wpa_ie[0], - adapter->scantable[index].rsn_ie[0], - adapter->secinfo.wep_enabled ? "e" : "d", - adapter->secinfo.WPAenabled ? "e" : "d", - adapter->secinfo.WPA2enabled ? "e" : "d", - adapter->scantable[index].privacy); - LEAVE(); - return index; - } else if ( !adapter->secinfo.wep_enabled - && !adapter->secinfo.WPAenabled - && !adapter->secinfo.WPA2enabled - && (adapter->scantable[index].wpa_ie[0] != WPA_IE) - && (adapter->scantable[index].rsn_ie[0] != WPA2_IE) - && adapter->scantable[index].privacy) { - /* dynamic WEP enabled */ - lbs_pr_debug(1, - "is_network_compatible() dynamic WEP: index=%d " - "wpa_ie=%#x wpa2_ie=%#x privacy=%#x\n", - index, - adapter->scantable[index].wpa_ie[0], - adapter->scantable[index].rsn_ie[0], - adapter->scantable[index].privacy); - LEAVE(); - return index; - } - - /* security doesn't match */ - lbs_pr_debug(1, - "is_network_compatible() FAILED: index=%d wpa_ie=%#x " - "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s privacy=%#x\n", - index, - adapter->scantable[index].wpa_ie[0], - adapter->scantable[index].rsn_ie[0], + int matched = 0; + + lbs_deb_enter(LBS_DEB_ASSOC); + + if (bss->mode != mode) + goto done; + + if ((matched = match_bss_no_security(&adapter->secinfo, bss))) { + goto done; + } else if ((matched = match_bss_static_wep(&adapter->secinfo, bss))) { + goto done; + } else if ((matched = match_bss_wpa(&adapter->secinfo, bss))) { + lbs_deb_scan( + "is_network_compatible() WPA: wpa_ie=%#x " + "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s " + "privacy=%#x\n", bss->wpa_ie[0], bss->rsn_ie[0], adapter->secinfo.wep_enabled ? "e" : "d", adapter->secinfo.WPAenabled ? "e" : "d", adapter->secinfo.WPA2enabled ? "e" : "d", - adapter->scantable[index].privacy); - LEAVE(); - return -ECONNREFUSED; - } - - /* mode doesn't match */ - LEAVE(); - return -ENETUNREACH; -} - -/** - * @brief This function validates a SSID as being able to be printed - * - * @param pssid SSID structure to validate - * - * @return TRUE or FALSE - */ -static u8 ssid_valid(struct WLAN_802_11_SSID *pssid) -{ - int ssididx; - - for (ssididx = 0; ssididx < pssid->ssidlength; ssididx++) { - if (!isprint(pssid->ssid[ssididx])) { - return 0; - } - } - - return 1; -} - -/** - * @brief Post process the scan table after a new scan command has completed - * - * Inspect each entry of the scan table and try to find an entry that - * matches our current associated/joined network from the scan. If - * one is found, update the stored copy of the bssdescriptor for our - * current network. - * - * Debug dump the current scan table contents if compiled accordingly. - * - * @param priv A pointer to wlan_private structure - * - * @return void - */ -static void wlan_scan_process_results(wlan_private * priv) -{ - wlan_adapter *adapter = priv->adapter; - int foundcurrent; - int i; - - foundcurrent = 0; - - if (adapter->connect_status == libertas_connected) { - /* try to find the current BSSID in the new scan list */ - for (i = 0; i < adapter->numinscantable; i++) { - if (!libertas_SSID_cmp(&adapter->scantable[i].ssid, - &adapter->curbssparams.ssid) && - !memcmp(adapter->curbssparams.bssid, - adapter->scantable[i].macaddress, - ETH_ALEN)) { - foundcurrent = 1; - } - } - - if (foundcurrent) { - /* Make a copy of current BSSID descriptor */ - memcpy(&adapter->curbssparams.bssdescriptor, - &adapter->scantable[i], - sizeof(adapter->curbssparams.bssdescriptor)); - } + bss->privacy); + goto done; + } else if ((matched = match_bss_wpa2(&adapter->secinfo, bss))) { + lbs_deb_scan( + "is_network_compatible() WPA2: wpa_ie=%#x " + "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s " + "privacy=%#x\n", bss->wpa_ie[0], bss->rsn_ie[0], + adapter->secinfo.wep_enabled ? "e" : "d", + adapter->secinfo.WPAenabled ? "e" : "d", + adapter->secinfo.WPA2enabled ? "e" : "d", + bss->privacy); + goto done; + } else if ((matched = match_bss_dynamic_wep(&adapter->secinfo, bss))) { + lbs_deb_scan( + "is_network_compatible() dynamic WEP: " + "wpa_ie=%#x wpa2_ie=%#x privacy=%#x\n", + bss->wpa_ie[0], + bss->rsn_ie[0], + bss->privacy); + goto done; } - for (i = 0; i < adapter->numinscantable; i++) { - lbs_pr_debug(1, "Scan:(%02d) %02x:%02x:%02x:%02x:%02x:%02x, " - "RSSI[%03d], SSID[%s]\n", - i, - adapter->scantable[i].macaddress[0], - adapter->scantable[i].macaddress[1], - adapter->scantable[i].macaddress[2], - adapter->scantable[i].macaddress[3], - adapter->scantable[i].macaddress[4], - adapter->scantable[i].macaddress[5], - (s32) adapter->scantable[i].rssi, - adapter->scantable[i].ssid.ssid); - } + /* bss security settings don't match those configured on card */ + lbs_deb_scan( + "is_network_compatible() FAILED: wpa_ie=%#x " + "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s privacy=%#x\n", + bss->wpa_ie[0], bss->rsn_ie[0], + adapter->secinfo.wep_enabled ? "e" : "d", + adapter->secinfo.WPAenabled ? "e" : "d", + adapter->secinfo.WPA2enabled ? "e" : "d", + bss->privacy); + +done: + lbs_deb_leave(LBS_DEB_SCAN); + return matched; } /** @@ -338,14 +292,12 @@ static void wlan_scan_create_channel_list(wlan_private * priv, if (scantype == cmd_scan_type_passive) { scanchanlist[chanidx].maxscantime = - cpu_to_le16 - (MRVDRV_PASSIVE_SCAN_CHAN_TIME); + cpu_to_le16(MRVDRV_PASSIVE_SCAN_CHAN_TIME); scanchanlist[chanidx].chanscanmode.passivescan = 1; } else { scanchanlist[chanidx].maxscantime = - cpu_to_le16 - (MRVDRV_ACTIVE_SCAN_CHAN_TIME); + cpu_to_le16(MRVDRV_ACTIVE_SCAN_CHAN_TIME); scanchanlist[chanidx].chanscanmode.passivescan = 0; } @@ -408,13 +360,11 @@ wlan_scan_setup_scan_config(wlan_private * priv, u8 * pscancurrentonly) { wlan_adapter *adapter = priv->adapter; - const u8 zeromac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; struct mrvlietypes_numprobes *pnumprobestlv; struct mrvlietypes_ssidparamset *pssidtlv; struct wlan_scan_cmd_config * pscancfgout = NULL; u8 *ptlvpos; u16 numprobes; - u16 ssidlen; int chanidx; int scantype; int scandur; @@ -471,21 +421,18 @@ wlan_scan_setup_scan_config(wlan_private * priv, * Set the BSSID filter to the incoming configuration, * if non-zero. If not set, it will remain disabled (all zeros). */ - memcpy(pscancfgout->specificBSSID, - puserscanin->specificBSSID, - sizeof(pscancfgout->specificBSSID)); - - ssidlen = strlen(puserscanin->specificSSID); + memcpy(pscancfgout->bssid, puserscanin->bssid, + sizeof(pscancfgout->bssid)); - if (ssidlen) { + if (puserscanin->ssid_len) { pssidtlv = (struct mrvlietypes_ssidparamset *) pscancfgout-> tlvbuffer; pssidtlv->header.type = cpu_to_le16(TLV_TYPE_SSID); - pssidtlv->header.len = cpu_to_le16(ssidlen); - memcpy(pssidtlv->ssid, puserscanin->specificSSID, - ssidlen); - ptlvpos += sizeof(pssidtlv->header) + ssidlen; + pssidtlv->header.len = cpu_to_le16(puserscanin->ssid_len); + memcpy(pssidtlv->ssid, puserscanin->ssid, + puserscanin->ssid_len); + ptlvpos += sizeof(pssidtlv->header) + puserscanin->ssid_len; } /* @@ -494,8 +441,8 @@ wlan_scan_setup_scan_config(wlan_private * priv, * scan results. That is not an issue with an SSID or BSSID * filter applied to the scan results in the firmware. */ - if (ssidlen || (memcmp(pscancfgout->specificBSSID, - &zeromac, sizeof(zeromac)) != 0)) { + if ( puserscanin->ssid_len + || (compare_ether_addr(pscancfgout->bssid, &zeromac[0]) != 0)) { *pmaxchanperscan = MRVDRV_MAX_CHANNELS_PER_SCAN; *pfilteredscan = 1; } @@ -507,16 +454,11 @@ wlan_scan_setup_scan_config(wlan_private * priv, /* If the input config or adapter has the number of Probes set, add tlv */ if (numprobes) { pnumprobestlv = (struct mrvlietypes_numprobes *) ptlvpos; - pnumprobestlv->header.type = - cpu_to_le16(TLV_TYPE_NUMPROBES); - pnumprobestlv->header.len = sizeof(pnumprobestlv->numprobes); + pnumprobestlv->header.type = cpu_to_le16(TLV_TYPE_NUMPROBES); + pnumprobestlv->header.len = cpu_to_le16(2); pnumprobestlv->numprobes = cpu_to_le16(numprobes); - ptlvpos += - sizeof(pnumprobestlv->header) + pnumprobestlv->header.len; - - pnumprobestlv->header.len = - cpu_to_le16(pnumprobestlv->header.len); + ptlvpos += sizeof(*pnumprobestlv); } /* @@ -529,7 +471,7 @@ wlan_scan_setup_scan_config(wlan_private * priv, if (puserscanin && puserscanin->chanlist[0].channumber) { - lbs_pr_debug(1, "Scan: Using supplied channel list\n"); + lbs_deb_scan("Scan: Using supplied channel list\n"); for (chanidx = 0; chanidx < WLAN_IOCTL_USER_SCAN_CHAN_MAX @@ -573,11 +515,11 @@ wlan_scan_setup_scan_config(wlan_private * priv, == priv->adapter->curbssparams.channel)) { *pscancurrentonly = 1; - lbs_pr_debug(1, "Scan: Scanning current channel only"); + lbs_deb_scan("Scan: Scanning current channel only"); } } else { - lbs_pr_debug(1, "Scan: Creating full region channel list\n"); + lbs_deb_scan("Scan: Creating full region channel list\n"); wlan_scan_create_channel_list(priv, pscanchanlist, *pfilteredscan); } @@ -613,7 +555,9 @@ static int wlan_scan_channel_list(wlan_private * priv, u8 filteredscan, struct wlan_scan_cmd_config * pscancfgout, struct mrvlietypes_chanlistparamset * pchantlvout, - struct chanscanparamset * pscanchanlist) + struct chanscanparamset * pscanchanlist, + const struct wlan_ioctl_user_scan_cfg * puserscanin, + int full_scan) { struct chanscanparamset *ptmpchan; struct chanscanparamset *pstartchan; @@ -621,11 +565,13 @@ static int wlan_scan_channel_list(wlan_private * priv, int doneearly; int tlvidx; int ret = 0; + int scanned = 0; + union iwreq_data wrqu; - ENTER(); + lbs_deb_enter(LBS_DEB_ASSOC); if (pscancfgout == 0 || pchantlvout == 0 || pscanchanlist == 0) { - lbs_pr_debug(1, "Scan: Null detect: %p, %p, %p\n", + lbs_deb_scan("Scan: Null detect: %p, %p, %p\n", pscancfgout, pchantlvout, pscanchanlist); return -1; } @@ -635,6 +581,9 @@ static int wlan_scan_channel_list(wlan_private * priv, /* Set the temp channel struct pointer to the start of the desired list */ ptmpchan = pscanchanlist; + if (priv->adapter->last_scanned_channel && !puserscanin) + ptmpchan += priv->adapter->last_scanned_channel; + /* Loop through the desired channel list, sending a new firmware scan * commands for each maxchanperscan channels (or for 1,6,11 individually * if configured accordingly) @@ -654,9 +603,9 @@ static int wlan_scan_channel_list(wlan_private * priv, * - doneearly is set (controlling individual scanning of 1,6,11) */ while (tlvidx < maxchanperscan && ptmpchan->channumber - && !doneearly) { + && !doneearly && scanned < 2) { - lbs_pr_debug(1, + lbs_deb_scan( "Scan: Chan(%3d), Radio(%d), mode(%d,%d), Dur(%d)\n", ptmpchan->channumber, ptmpchan->radiotype, ptmpchan->chanscanmode.passivescan, @@ -668,8 +617,11 @@ static int wlan_scan_channel_list(wlan_private * priv, ptmpchan, sizeof(pchantlvout->chanscanparam)); /* Increment the TLV header length by the size appended */ - pchantlvout->header.len += - sizeof(pchantlvout->chanscanparam); + /* Ew, it would be _so_ nice if we could just declare the + variable little-endian and let GCC handle it for us */ + pchantlvout->header.len = + cpu_to_le16(le16_to_cpu(pchantlvout->header.len) + + sizeof(pchantlvout->chanscanparam)); /* * The tlv buffer length is set to the number of bytes of the @@ -683,7 +635,7 @@ static int wlan_scan_channel_list(wlan_private * priv, /* Add the size of the channel tlv header and the data length */ pscancfgout->tlvbufferlen += (sizeof(pchantlvout->header) - + pchantlvout->header.len); + + le16_to_cpu(pchantlvout->header.len)); /* Increment the index to the channel tlv we are constructing */ tlvidx++; @@ -701,6 +653,7 @@ static int wlan_scan_channel_list(wlan_private * priv, /* Increment the tmp pointer to the next channel to be scanned */ ptmpchan++; + scanned++; /* Stop the loop if the *next* channel is in the 1,6,11 set. * This will cause it to be the only channel scanned on the next @@ -716,12 +669,71 @@ static int wlan_scan_channel_list(wlan_private * priv, /* Send the scan command to the firmware with the specified cfg */ ret = libertas_prepare_and_send_command(priv, cmd_802_11_scan, 0, 0, 0, pscancfgout); + if (scanned >= 2 && !full_scan) { + ret = 0; + goto done; + } + scanned = 0; } - LEAVE(); +done: + priv->adapter->last_scanned_channel = ptmpchan->channumber; + + /* Tell userspace the scan table has been updated */ + memset(&wrqu, 0, sizeof(union iwreq_data)); + wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL); + + lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret); return ret; } +static void +clear_selected_scan_list_entries(wlan_adapter * adapter, + const struct wlan_ioctl_user_scan_cfg * scan_cfg) +{ + struct bss_descriptor * bss; + struct bss_descriptor * safe; + u32 clear_ssid_flag = 0, clear_bssid_flag = 0; + + if (!scan_cfg) + return; + + if (scan_cfg->clear_ssid && scan_cfg->ssid_len) + clear_ssid_flag = 1; + + if (scan_cfg->clear_bssid + && (compare_ether_addr(scan_cfg->bssid, &zeromac[0]) != 0) + && (compare_ether_addr(scan_cfg->bssid, &bcastmac[0]) != 0)) { + clear_bssid_flag = 1; + } + + if (!clear_ssid_flag && !clear_bssid_flag) + return; + + mutex_lock(&adapter->lock); + list_for_each_entry_safe (bss, safe, &adapter->network_list, list) { + u32 clear = 0; + + /* Check for an SSID match */ + if ( clear_ssid_flag + && (bss->ssid_len == scan_cfg->ssid_len) + && !memcmp(bss->ssid, scan_cfg->ssid, bss->ssid_len)) + clear = 1; + + /* Check for a BSSID match */ + if ( clear_bssid_flag + && !compare_ether_addr(bss->bssid, scan_cfg->bssid)) + clear = 1; + + if (clear) { + list_move_tail (&bss->list, &adapter->network_free_list); + clear_bss_descriptor(bss); + } + } + mutex_unlock(&adapter->lock); +} + + /** * @brief Internal function used to start a scan based on an input config * @@ -736,19 +748,23 @@ static int wlan_scan_channel_list(wlan_private * priv, * @return 0 or < 0 if error */ int wlan_scan_networks(wlan_private * priv, - const struct wlan_ioctl_user_scan_cfg * puserscanin) + const struct wlan_ioctl_user_scan_cfg * puserscanin, + int full_scan) { - wlan_adapter *adapter = priv->adapter; + wlan_adapter * adapter = priv->adapter; struct mrvlietypes_chanlistparamset *pchantlvout; struct chanscanparamset * scan_chan_list = NULL; struct wlan_scan_cmd_config * scan_cfg = NULL; - u8 keeppreviousscan; u8 filteredscan; u8 scancurrentchanonly; int maxchanperscan; int ret; +#ifdef CONFIG_LIBERTAS_DEBUG + struct bss_descriptor * iter_bss; + int i = 0; +#endif - ENTER(); + lbs_deb_enter(LBS_DEB_ASSOC); scan_chan_list = kzalloc(sizeof(struct chanscanparamset) * WLAN_IOCTL_USER_SCAN_CHAN_MAX, GFP_KERNEL); @@ -769,22 +785,14 @@ int wlan_scan_networks(wlan_private * priv, goto out; } - keeppreviousscan = 0; - - if (puserscanin) { - keeppreviousscan = puserscanin->keeppreviousscan; - } - - if (!keeppreviousscan) { - memset(adapter->scantable, 0x00, - sizeof(struct bss_descriptor) * MRVDRV_MAX_BSSID_LIST); - adapter->numinscantable = 0; - } + clear_selected_scan_list_entries(adapter, puserscanin); /* Keep the data path active if we are only scanning our current channel */ if (!scancurrentchanonly) { - netif_stop_queue(priv->wlan_dev.netdev); - netif_carrier_off(priv->wlan_dev.netdev); + netif_stop_queue(priv->dev); + netif_carrier_off(priv->dev); + netif_stop_queue(priv->mesh_dev); + netif_carrier_off(priv->mesh_dev); } ret = wlan_scan_channel_list(priv, @@ -792,17 +800,26 @@ int wlan_scan_networks(wlan_private * priv, filteredscan, scan_cfg, pchantlvout, - scan_chan_list); - - /* Process the resulting scan table: - * - Remove any bad ssids - * - Update our current BSS information from scan data - */ - wlan_scan_process_results(priv); + scan_chan_list, + puserscanin, + full_scan); + +#ifdef CONFIG_LIBERTAS_DEBUG + /* Dump the scan table */ + mutex_lock(&adapter->lock); + list_for_each_entry (iter_bss, &adapter->network_list, list) { + lbs_deb_scan("Scan:(%02d) " MAC_FMT ", RSSI[%03d], SSID[%s]\n", + i++, MAC_ARG(iter_bss->bssid), (s32) iter_bss->rssi, + escape_essid(iter_bss->ssid, iter_bss->ssid_len)); + } + mutex_unlock(&adapter->lock); +#endif if (priv->adapter->connect_status == libertas_connected) { - netif_carrier_on(priv->wlan_dev.netdev); - netif_wake_queue(priv->wlan_dev.netdev); + netif_carrier_on(priv->dev); + netif_wake_queue(priv->dev); + netif_carrier_on(priv->mesh_dev); + netif_wake_queue(priv->mesh_dev); } out: @@ -812,7 +829,7 @@ out: if (scan_chan_list) kfree(scan_chan_list); - LEAVE(); + lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret); return ret; } @@ -843,7 +860,7 @@ void wlan_ret_802_11_scan_get_tlv_ptrs(struct mrvlietypes_data * ptlv, tlvbufleft = tlvbufsize; *ptsftlv = NULL; - lbs_pr_debug(1, "SCAN_RESP: tlvbufsize = %d\n", tlvbufsize); + lbs_deb_scan("SCAN_RESP: tlvbufsize = %d\n", tlvbufsize); lbs_dbg_hex("SCAN_RESP: TLV Buf", (u8 *) ptlv, tlvbufsize); while (tlvbufleft >= sizeof(struct mrvlietypesheader)) { @@ -856,7 +873,7 @@ void wlan_ret_802_11_scan_get_tlv_ptrs(struct mrvlietypes_data * ptlv, break; default: - lbs_pr_debug(1, "SCAN_RESP: Unhandled TLV = %d\n", + lbs_deb_scan("SCAN_RESP: Unhandled TLV = %d\n", tlvtype); /* Give up, this seems corrupted */ return; @@ -875,12 +892,12 @@ void wlan_ret_802_11_scan_get_tlv_ptrs(struct mrvlietypes_data * ptlv, * response or beacon from the scan command. Record information as needed * in the scan table struct bss_descriptor for that entry. * - * @param pBSSIDEntry Output parameter: Pointer to the BSS Entry + * @param bss Output parameter: Pointer to the BSS Entry * * @return 0 or -1 */ -static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry, - u8 ** pbeaconinfo, int *bytesleft) +static int libertas_process_bss(struct bss_descriptor * bss, + u8 ** pbeaconinfo, int *bytesleft) { enum ieeetypes_elementid elemID; struct ieeetypes_fhparamset *pFH; @@ -897,13 +914,14 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry, u16 beaconsize; u8 founddatarateie; int bytesleftforcurrentbeacon; + int ret; struct IE_WPA *pIe; const u8 oui01[4] = { 0x00, 0x50, 0xf2, 0x01 }; struct ieeetypes_countryinfoset *pcountryinfo; - ENTER(); + lbs_deb_enter(LBS_DEB_ASSOC); founddatarateie = 0; ratesize = 0; @@ -911,8 +929,7 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry, if (*bytesleft >= sizeof(beaconsize)) { /* Extract & convert beacon size from the command buffer */ - memcpy(&beaconsize, *pbeaconinfo, sizeof(beaconsize)); - beaconsize = le16_to_cpu(beaconsize); + beaconsize = le16_to_cpup((void *)*pbeaconinfo); *bytesleft -= sizeof(beaconsize); *pbeaconinfo += sizeof(beaconsize); } @@ -934,17 +951,14 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry, bytesleftforcurrentbeacon = beaconsize; - memcpy(pBSSEntry->macaddress, pcurrentptr, ETH_ALEN); - lbs_pr_debug(1, "InterpretIE: AP MAC Addr-%x:%x:%x:%x:%x:%x\n", - pBSSEntry->macaddress[0], pBSSEntry->macaddress[1], - pBSSEntry->macaddress[2], pBSSEntry->macaddress[3], - pBSSEntry->macaddress[4], pBSSEntry->macaddress[5]); + memcpy(bss->bssid, pcurrentptr, ETH_ALEN); + lbs_deb_scan("process_bss: AP BSSID " MAC_FMT "\n", MAC_ARG(bss->bssid)); pcurrentptr += ETH_ALEN; bytesleftforcurrentbeacon -= ETH_ALEN; if (bytesleftforcurrentbeacon < 12) { - lbs_pr_debug(1, "InterpretIE: Not enough bytes left\n"); + lbs_deb_scan("process_bss: Not enough bytes left\n"); return -1; } @@ -954,51 +968,48 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry, */ /* RSSI is 1 byte long */ - pBSSEntry->rssi = le32_to_cpu((long)(*pcurrentptr)); - lbs_pr_debug(1, "InterpretIE: RSSI=%02X\n", *pcurrentptr); + bss->rssi = *pcurrentptr; + lbs_deb_scan("process_bss: RSSI=%02X\n", *pcurrentptr); pcurrentptr += 1; bytesleftforcurrentbeacon -= 1; /* time stamp is 8 bytes long */ - memcpy(fixedie.timestamp, pcurrentptr, 8); - memcpy(pBSSEntry->timestamp, pcurrentptr, 8); + fixedie.timestamp = bss->timestamp = le64_to_cpup((void *)pcurrentptr); pcurrentptr += 8; bytesleftforcurrentbeacon -= 8; /* beacon interval is 2 bytes long */ - memcpy(&fixedie.beaconinterval, pcurrentptr, 2); - pBSSEntry->beaconperiod = le16_to_cpu(fixedie.beaconinterval); + fixedie.beaconinterval = bss->beaconperiod = le16_to_cpup((void *)pcurrentptr); pcurrentptr += 2; bytesleftforcurrentbeacon -= 2; /* capability information is 2 bytes long */ - memcpy(&fixedie.capabilities, pcurrentptr, 2); - lbs_pr_debug(1, "InterpretIE: fixedie.capabilities=0x%X\n", + memcpy(&fixedie.capabilities, pcurrentptr, 2); + lbs_deb_scan("process_bss: fixedie.capabilities=0x%X\n", fixedie.capabilities); - fixedie.capabilities = le16_to_cpu(fixedie.capabilities); pcap = (struct ieeetypes_capinfo *) & fixedie.capabilities; - memcpy(&pBSSEntry->cap, pcap, sizeof(struct ieeetypes_capinfo)); + memcpy(&bss->cap, pcap, sizeof(struct ieeetypes_capinfo)); pcurrentptr += 2; bytesleftforcurrentbeacon -= 2; /* rest of the current buffer are IE's */ - lbs_pr_debug(1, "InterpretIE: IElength for this AP = %d\n", + lbs_deb_scan("process_bss: IE length for this AP = %d\n", bytesleftforcurrentbeacon); - lbs_dbg_hex("InterpretIE: IE info", (u8 *) pcurrentptr, + lbs_dbg_hex("process_bss: IE info", (u8 *) pcurrentptr, bytesleftforcurrentbeacon); if (pcap->privacy) { - lbs_pr_debug(1, "InterpretIE: AP WEP enabled\n"); - pBSSEntry->privacy = wlan802_11privfilter8021xWEP; + lbs_deb_scan("process_bss: AP WEP enabled\n"); + bss->privacy = wlan802_11privfilter8021xWEP; } else { - pBSSEntry->privacy = wlan802_11privfilteracceptall; + bss->privacy = wlan802_11privfilteracceptall; } if (pcap->ibss == 1) { - pBSSEntry->mode = IW_MODE_ADHOC; + bss->mode = IW_MODE_ADHOC; } else { - pBSSEntry->mode = IW_MODE_INFRA; + bss->mode = IW_MODE_INFRA; } /* process variable IE */ @@ -1007,94 +1018,83 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry, elemlen = *((u8 *) pcurrentptr + 1); if (bytesleftforcurrentbeacon < elemlen) { - lbs_pr_debug(1, "InterpretIE: error in processing IE, " + lbs_deb_scan("process_bss: error in processing IE, " "bytes left < IE length\n"); bytesleftforcurrentbeacon = 0; continue; } switch (elemID) { - case SSID: - pBSSEntry->ssid.ssidlength = elemlen; - memcpy(pBSSEntry->ssid.ssid, (pcurrentptr + 2), - elemlen); - lbs_pr_debug(1, "ssid: %32s", pBSSEntry->ssid.ssid); + bss->ssid_len = elemlen; + memcpy(bss->ssid, (pcurrentptr + 2), elemlen); + lbs_deb_scan("ssid '%s', ssid length %u\n", + escape_essid(bss->ssid, bss->ssid_len), + bss->ssid_len); break; case SUPPORTED_RATES: - memcpy(pBSSEntry->datarates, (pcurrentptr + 2), - elemlen); - memmove(pBSSEntry->libertas_supported_rates, (pcurrentptr + 2), + memcpy(bss->datarates, (pcurrentptr + 2), elemlen); + memmove(bss->libertas_supported_rates, (pcurrentptr + 2), elemlen); ratesize = elemlen; founddatarateie = 1; break; case EXTRA_IE: - lbs_pr_debug(1, "InterpretIE: EXTRA_IE Found!\n"); - pBSSEntry->extra_ie = 1; + lbs_deb_scan("process_bss: EXTRA_IE Found!\n"); break; case FH_PARAM_SET: pFH = (struct ieeetypes_fhparamset *) pcurrentptr; - memmove(&pBSSEntry->phyparamset.fhparamset, pFH, + memmove(&bss->phyparamset.fhparamset, pFH, sizeof(struct ieeetypes_fhparamset)); - pBSSEntry->phyparamset.fhparamset.dwelltime - = - le16_to_cpu(pBSSEntry->phyparamset.fhparamset. - dwelltime); +#if 0 /* I think we can store these LE */ + bss->phyparamset.fhparamset.dwelltime + = le16_to_cpu(bss->phyparamset.fhparamset.dwelltime); +#endif break; case DS_PARAM_SET: pDS = (struct ieeetypes_dsparamset *) pcurrentptr; - - pBSSEntry->channel = pDS->currentchan; - - memcpy(&pBSSEntry->phyparamset.dsparamset, pDS, + bss->channel = pDS->currentchan; + memcpy(&bss->phyparamset.dsparamset, pDS, sizeof(struct ieeetypes_dsparamset)); break; case CF_PARAM_SET: pCF = (struct ieeetypes_cfparamset *) pcurrentptr; - - memcpy(&pBSSEntry->ssparamset.cfparamset, pCF, + memcpy(&bss->ssparamset.cfparamset, pCF, sizeof(struct ieeetypes_cfparamset)); break; case IBSS_PARAM_SET: pibss = (struct ieeetypes_ibssparamset *) pcurrentptr; - pBSSEntry->atimwindow = - le32_to_cpu(pibss->atimwindow); - - memmove(&pBSSEntry->ssparamset.ibssparamset, pibss, + bss->atimwindow = le32_to_cpu(pibss->atimwindow); + memmove(&bss->ssparamset.ibssparamset, pibss, sizeof(struct ieeetypes_ibssparamset)); - - pBSSEntry->ssparamset.ibssparamset.atimwindow - = - le16_to_cpu(pBSSEntry->ssparamset.ibssparamset. - atimwindow); +#if 0 + bss->ssparamset.ibssparamset.atimwindow + = le16_to_cpu(bss->ssparamset.ibssparamset.atimwindow); +#endif break; /* Handle Country Info IE */ case COUNTRY_INFO: - pcountryinfo = - (struct ieeetypes_countryinfoset *) pcurrentptr; - - if (pcountryinfo->len < - sizeof(pcountryinfo->countrycode) + pcountryinfo = (struct ieeetypes_countryinfoset *) pcurrentptr; + if (pcountryinfo->len < sizeof(pcountryinfo->countrycode) || pcountryinfo->len > 254) { - lbs_pr_debug(1, "InterpretIE: 11D- Err " + lbs_deb_scan("process_bss: 11D- Err " "CountryInfo len =%d min=%zd max=254\n", pcountryinfo->len, sizeof(pcountryinfo->countrycode)); - LEAVE(); - return -1; + ret = -1; + goto done; } - memcpy(&pBSSEntry->countryinfo, + memcpy(&bss->countryinfo, pcountryinfo, pcountryinfo->len + 2); - lbs_dbg_hex("InterpretIE: 11D- CountryInfo:", + lbs_dbg_hex("process_bss: 11D- CountryInfo:", (u8 *) pcountryinfo, (u32) (pcountryinfo->len + 2)); break; @@ -1114,12 +1114,10 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry, bytestocopy = elemlen; } - pRate = (u8 *) pBSSEntry->datarates; + pRate = (u8 *) bss->datarates; pRate += ratesize; memmove(pRate, (pcurrentptr + 2), bytestocopy); - - pRate = (u8 *) pBSSEntry->libertas_supported_rates; - + pRate = (u8 *) bss->libertas_supported_rates; pRate += ratesize; memmove(pRate, (pcurrentptr + 2), bytestocopy); } @@ -1132,24 +1130,17 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry, if (memcmp(pIe->oui, oui01, sizeof(oui01))) break; - pBSSEntry->wpa_ie_len = min_t(size_t, - elemlen + IE_ID_LEN_FIELDS_BYTES, - sizeof(pBSSEntry->wpa_ie)); - memcpy(pBSSEntry->wpa_ie, pcurrentptr, - pBSSEntry->wpa_ie_len); - lbs_dbg_hex("InterpretIE: Resp WPA_IE", - pBSSEntry->wpa_ie, elemlen); + bss->wpa_ie_len = min(elemlen + IE_ID_LEN_FIELDS_BYTES, + MAX_WPA_IE_LEN); + memcpy(bss->wpa_ie, pcurrentptr, bss->wpa_ie_len); + lbs_dbg_hex("process_bss: WPA IE", bss->wpa_ie, elemlen); break; case WPA2_IE: pIe = (struct IE_WPA *)pcurrentptr; - - pBSSEntry->rsn_ie_len = min_t(size_t, - elemlen + IE_ID_LEN_FIELDS_BYTES, - sizeof(pBSSEntry->rsn_ie)); - memcpy(pBSSEntry->rsn_ie, pcurrentptr, - pBSSEntry->rsn_ie_len); - lbs_dbg_hex("InterpretIE: Resp WPA2_IE", - pBSSEntry->rsn_ie, elemlen); + bss->rsn_ie_len = min(elemlen + IE_ID_LEN_FIELDS_BYTES, + MAX_WPA_IE_LEN); + memcpy(bss->rsn_ie, pcurrentptr, bss->rsn_ie_len); + lbs_dbg_hex("process_bss: RSN_IE", bss->rsn_ie, elemlen); break; case TIM: break; @@ -1165,7 +1156,14 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry, } /* while (bytesleftforcurrentbeacon > 2) */ - return 0; + /* Timestamp */ + bss->last_scanned = jiffies; + + ret = 0; + +done: + lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret); + return ret; } /** @@ -1176,15 +1174,12 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry, * * @return 0--ssid is same, otherwise is different */ -int libertas_SSID_cmp(struct WLAN_802_11_SSID *ssid1, struct WLAN_802_11_SSID *ssid2) +int libertas_ssid_cmp(u8 *ssid1, u8 ssid1_len, u8 *ssid2, u8 ssid2_len) { - if (!ssid1 || !ssid2) - return -1; - - if (ssid1->ssidlength != ssid2->ssidlength) + if (ssid1_len != ssid2_len) return -1; - return memcmp(ssid1->ssid, ssid2->ssid, ssid1->ssidlength); + return memcmp(ssid1, ssid2, ssid1_len); } /** @@ -1196,38 +1191,41 @@ int libertas_SSID_cmp(struct WLAN_802_11_SSID *ssid1, struct WLAN_802_11_SSID *s * * @return index in BSSID list, or error return code (< 0) */ -int libertas_find_BSSID_in_list(wlan_adapter * adapter, u8 * bssid, u8 mode) +struct bss_descriptor * libertas_find_bssid_in_list(wlan_adapter * adapter, + u8 * bssid, u8 mode) { - int ret = -ENETUNREACH; - int i; + struct bss_descriptor * iter_bss; + struct bss_descriptor * found_bss = NULL; if (!bssid) - return -EFAULT; + return NULL; - lbs_pr_debug(1, "FindBSSID: Num of BSSIDs = %d\n", - adapter->numinscantable); + lbs_dbg_hex("libertas_find_BSSID_in_list: looking for ", + bssid, ETH_ALEN); - /* Look through the scan table for a compatible match. The ret return - * variable will be equal to the index in the scan table (greater - * than zero) if the network is compatible. The loop will continue - * past a matched bssid that is not compatible in case there is an - * AP with multiple SSIDs assigned to the same BSSID + /* Look through the scan table for a compatible match. The loop will + * continue past a matched bssid that is not compatible in case there + * is an AP with multiple SSIDs assigned to the same BSSID */ - for (i = 0; ret < 0 && i < adapter->numinscantable; i++) { - if (!memcmp(adapter->scantable[i].macaddress, bssid, ETH_ALEN)) { - switch (mode) { - case IW_MODE_INFRA: - case IW_MODE_ADHOC: - ret = is_network_compatible(adapter, i, mode); - break; - default: - ret = i; + mutex_lock(&adapter->lock); + list_for_each_entry (iter_bss, &adapter->network_list, list) { + if (compare_ether_addr(iter_bss->bssid, bssid)) + continue; /* bssid doesn't match */ + switch (mode) { + case IW_MODE_INFRA: + case IW_MODE_ADHOC: + if (!is_network_compatible(adapter, iter_bss, mode)) break; - } + found_bss = iter_bss; + break; + default: + found_bss = iter_bss; + break; } } + mutex_unlock(&adapter->lock); - return ret; + return found_bss; } /** @@ -1240,61 +1238,60 @@ int libertas_find_BSSID_in_list(wlan_adapter * adapter, u8 * bssid, u8 mode) * * @return index in BSSID list */ -int libertas_find_SSID_in_list(wlan_adapter * adapter, - struct WLAN_802_11_SSID *ssid, u8 * bssid, u8 mode) +struct bss_descriptor * libertas_find_ssid_in_list(wlan_adapter * adapter, + u8 *ssid, u8 ssid_len, u8 * bssid, u8 mode, + int channel) { - int net = -ENETUNREACH; u8 bestrssi = 0; - int i; - int j; + struct bss_descriptor * iter_bss = NULL; + struct bss_descriptor * found_bss = NULL; + struct bss_descriptor * tmp_oldest = NULL; - lbs_pr_debug(1, "Num of Entries in Table = %d\n", adapter->numinscantable); - - for (i = 0; i < adapter->numinscantable; i++) { - if (!libertas_SSID_cmp(&adapter->scantable[i].ssid, ssid) && - (!bssid || - !memcmp(adapter->scantable[i]. - macaddress, bssid, ETH_ALEN))) { - switch (mode) { - case IW_MODE_INFRA: - case IW_MODE_ADHOC: - j = is_network_compatible(adapter, i, mode); - - if (j >= 0) { - if (bssid) { - return i; - } - - if (SCAN_RSSI - (adapter->scantable[i].rssi) - > bestrssi) { - bestrssi = - SCAN_RSSI(adapter-> - scantable[i]. - rssi); - net = i; - } - } else { - if (net == -ENETUNREACH) { - net = j; - } - } - break; - case IW_MODE_AUTO: - default: - if (SCAN_RSSI(adapter->scantable[i].rssi) - > bestrssi) { - bestrssi = - SCAN_RSSI(adapter->scantable[i]. - rssi); - net = i; - } + mutex_lock(&adapter->lock); + + list_for_each_entry (iter_bss, &adapter->network_list, list) { + if ( !tmp_oldest + || (iter_bss->last_scanned < tmp_oldest->last_scanned)) + tmp_oldest = iter_bss; + + if (libertas_ssid_cmp(iter_bss->ssid, iter_bss->ssid_len, + ssid, ssid_len) != 0) + continue; /* ssid doesn't match */ + if (bssid && compare_ether_addr(iter_bss->bssid, bssid) != 0) + continue; /* bssid doesn't match */ + if ((channel > 0) && (iter_bss->channel != channel)) + continue; /* channel doesn't match */ + + switch (mode) { + case IW_MODE_INFRA: + case IW_MODE_ADHOC: + if (!is_network_compatible(adapter, iter_bss, mode)) break; + + if (bssid) { + /* Found requested BSSID */ + found_bss = iter_bss; + goto out; + } + + if (SCAN_RSSI(iter_bss->rssi) > bestrssi) { + bestrssi = SCAN_RSSI(iter_bss->rssi); + found_bss = iter_bss; } + break; + case IW_MODE_AUTO: + default: + if (SCAN_RSSI(iter_bss->rssi) > bestrssi) { + bestrssi = SCAN_RSSI(iter_bss->rssi); + found_bss = iter_bss; + } + break; } } - return net; +out: + mutex_unlock(&adapter->lock); + return found_bss; } /** @@ -1307,43 +1304,38 @@ int libertas_find_SSID_in_list(wlan_adapter * adapter, * * @return index in BSSID list */ -int libertas_find_best_SSID_in_list(wlan_adapter * adapter, u8 mode) +struct bss_descriptor * libertas_find_best_ssid_in_list(wlan_adapter * adapter, + u8 mode) { - int bestnet = -ENETUNREACH; u8 bestrssi = 0; - int i; - - ENTER(); + struct bss_descriptor * iter_bss; + struct bss_descriptor * best_bss = NULL; - lbs_pr_debug(1, "Num of BSSIDs = %d\n", adapter->numinscantable); + mutex_lock(&adapter->lock); - for (i = 0; i < adapter->numinscantable; i++) { + list_for_each_entry (iter_bss, &adapter->network_list, list) { switch (mode) { case IW_MODE_INFRA: case IW_MODE_ADHOC: - if (is_network_compatible(adapter, i, mode) >= 0) { - if (SCAN_RSSI(adapter->scantable[i].rssi) > - bestrssi) { - bestrssi = - SCAN_RSSI(adapter->scantable[i]. - rssi); - bestnet = i; - } - } + if (!is_network_compatible(adapter, iter_bss, mode)) + break; + if (SCAN_RSSI(iter_bss->rssi) <= bestrssi) + break; + bestrssi = SCAN_RSSI(iter_bss->rssi); + best_bss = iter_bss; break; case IW_MODE_AUTO: default: - if (SCAN_RSSI(adapter->scantable[i].rssi) > bestrssi) { - bestrssi = - SCAN_RSSI(adapter->scantable[i].rssi); - bestnet = i; - } + if (SCAN_RSSI(iter_bss->rssi) <= bestrssi) + break; + bestrssi = SCAN_RSSI(iter_bss->rssi); + best_bss = iter_bss; break; } } - LEAVE(); - return bestnet; + mutex_unlock(&adapter->lock); + return best_bss; } /** @@ -1354,41 +1346,30 @@ int libertas_find_best_SSID_in_list(wlan_adapter * adapter, u8 mode) * * @return 0--success, otherwise--fail */ -int libertas_find_best_network_SSID(wlan_private * priv, - struct WLAN_802_11_SSID *pSSID, - u8 preferred_mode, u8 *out_mode) +int libertas_find_best_network_ssid(wlan_private * priv, + u8 *out_ssid, u8 *out_ssid_len, u8 preferred_mode, u8 *out_mode) { wlan_adapter *adapter = priv->adapter; - int ret = 0; - struct bss_descriptor *preqbssid; - int i; + int ret = -1; + struct bss_descriptor * found; - ENTER(); + lbs_deb_enter(LBS_DEB_ASSOC); - memset(pSSID, 0, sizeof(struct WLAN_802_11_SSID)); - - wlan_scan_networks(priv, NULL); + wlan_scan_networks(priv, NULL, 1); if (adapter->surpriseremoved) return -1; - wait_event_interruptible(adapter->cmd_pending, !adapter->nr_cmd_pending); - i = libertas_find_best_SSID_in_list(adapter, preferred_mode); - if (i < 0) { - ret = -1; - goto out; - } - - preqbssid = &adapter->scantable[i]; - memcpy(pSSID, &preqbssid->ssid, - sizeof(struct WLAN_802_11_SSID)); - *out_mode = preqbssid->mode; + wait_event_interruptible(adapter->cmd_pending, !adapter->nr_cmd_pending); - if (!pSSID->ssidlength) { - ret = -1; + found = libertas_find_best_ssid_in_list(adapter, preferred_mode); + if (found && (found->ssid_len > 0)) { + memcpy(out_ssid, &found->ssid, IW_ESSID_MAX_SIZE); + *out_ssid_len = found->ssid_len; + *out_mode = found->mode; + ret = 0; } -out: - LEAVE(); + lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret); return ret; } @@ -1407,20 +1388,15 @@ int libertas_set_scan(struct net_device *dev, struct iw_request_info *info, { wlan_private *priv = dev->priv; wlan_adapter *adapter = priv->adapter; - union iwreq_data wrqu; - ENTER(); + lbs_deb_enter(LBS_DEB_SCAN); - if (!wlan_scan_networks(priv, NULL)) { - memset(&wrqu, 0, sizeof(union iwreq_data)); - wireless_send_event(priv->wlan_dev.netdev, SIOCGIWSCAN, &wrqu, - NULL); - } + wlan_scan_networks(priv, NULL, 0); if (adapter->surpriseremoved) return -1; - LEAVE(); + lbs_deb_leave(LBS_DEB_SCAN); return 0; } @@ -1433,32 +1409,31 @@ int libertas_set_scan(struct net_device *dev, struct iw_request_info *info, * * @return 0-success, otherwise fail */ -int libertas_send_specific_SSID_scan(wlan_private * priv, - struct WLAN_802_11_SSID *prequestedssid, - u8 keeppreviousscan) +int libertas_send_specific_ssid_scan(wlan_private * priv, + u8 *ssid, u8 ssid_len, u8 clear_ssid) { wlan_adapter *adapter = priv->adapter; struct wlan_ioctl_user_scan_cfg scancfg; + int ret = 0; - ENTER(); + lbs_deb_enter(LBS_DEB_ASSOC); - if (prequestedssid == NULL) { - return -1; - } + if (!ssid_len) + goto out; memset(&scancfg, 0x00, sizeof(scancfg)); + memcpy(scancfg.ssid, ssid, ssid_len); + scancfg.ssid_len = ssid_len; + scancfg.clear_ssid = clear_ssid; - memcpy(scancfg.specificSSID, prequestedssid->ssid, - prequestedssid->ssidlength); - scancfg.keeppreviousscan = keeppreviousscan; - - wlan_scan_networks(priv, &scancfg); + wlan_scan_networks(priv, &scancfg, 1); if (adapter->surpriseremoved) return -1; wait_event_interruptible(adapter->cmd_pending, !adapter->nr_cmd_pending); - LEAVE(); - return 0; +out: + lbs_deb_leave(LBS_DEB_ASSOC); + return ret; } /** @@ -1470,304 +1445,235 @@ int libertas_send_specific_SSID_scan(wlan_private * priv, * * @return 0-success, otherwise fail */ -int libertas_send_specific_BSSID_scan(wlan_private * priv, u8 * bssid, u8 keeppreviousscan) +int libertas_send_specific_bssid_scan(wlan_private * priv, u8 * bssid, u8 clear_bssid) { struct wlan_ioctl_user_scan_cfg scancfg; - ENTER(); + lbs_deb_enter(LBS_DEB_ASSOC); - if (bssid == NULL) { - return -1; - } + if (bssid == NULL) + goto out; memset(&scancfg, 0x00, sizeof(scancfg)); - memcpy(scancfg.specificBSSID, bssid, sizeof(scancfg.specificBSSID)); - scancfg.keeppreviousscan = keeppreviousscan; + memcpy(scancfg.bssid, bssid, ETH_ALEN); + scancfg.clear_bssid = clear_bssid; - wlan_scan_networks(priv, &scancfg); + wlan_scan_networks(priv, &scancfg, 1); if (priv->adapter->surpriseremoved) return -1; wait_event_interruptible(priv->adapter->cmd_pending, !priv->adapter->nr_cmd_pending); - LEAVE(); +out: + lbs_deb_leave(LBS_DEB_ASSOC); return 0; } -/** - * @brief Retrieve the scan table entries via wireless tools IOCTL call - * - * @param dev A pointer to net_device structure - * @param info A pointer to iw_request_info structure - * @param dwrq A pointer to iw_point structure - * @param extra A pointer to extra data buf - * - * @return 0 --success, otherwise fail - */ -int libertas_get_scan(struct net_device *dev, struct iw_request_info *info, - struct iw_point *dwrq, char *extra) +static inline char *libertas_translate_scan(wlan_private *priv, + char *start, char *stop, + struct bss_descriptor *bss) { - wlan_private *priv = dev->priv; wlan_adapter *adapter = priv->adapter; - int ret = 0; - char *current_ev = extra; - char *end_buf = extra + IW_SCAN_MAX_DATA; struct chan_freq_power *cfp; - struct bss_descriptor *pscantable; char *current_val; /* For rates */ struct iw_event iwe; /* Temporary buffer */ - int i; int j; - int rate; #define PERFECT_RSSI ((u8)50) #define WORST_RSSI ((u8)0) #define RSSI_DIFF ((u8)(PERFECT_RSSI - WORST_RSSI)) u8 rssi; - u8 buf[16 + 256 * 2]; - u8 *ptr; - - ENTER(); - - /* - * if there's either commands in the queue or one being - * processed return -EAGAIN for iwlist to retry later. - */ - if (adapter->nr_cmd_pending) - return -EAGAIN; - - if (adapter->connect_status == libertas_connected) - lbs_pr_debug(1, "Current ssid: %32s\n", - adapter->curbssparams.ssid.ssid); + cfp = libertas_find_cfp_by_band_and_channel(adapter, 0, bss->channel); + if (!cfp) { + lbs_deb_scan("Invalid channel number %d\n", bss->channel); + return NULL; + } - lbs_pr_debug(1, "Scan: Get: numinscantable = %d\n", - adapter->numinscantable); + /* First entry *MUST* be the AP BSSID */ + iwe.cmd = SIOCGIWAP; + iwe.u.ap_addr.sa_family = ARPHRD_ETHER; + memcpy(iwe.u.ap_addr.sa_data, &bss->bssid, ETH_ALEN); + start = iwe_stream_add_event(start, stop, &iwe, IW_EV_ADDR_LEN); + + /* SSID */ + iwe.cmd = SIOCGIWESSID; + iwe.u.data.flags = 1; + iwe.u.data.length = min((u32) bss->ssid_len, (u32) IW_ESSID_MAX_SIZE); + start = iwe_stream_add_point(start, stop, &iwe, bss->ssid); + + /* Mode */ + iwe.cmd = SIOCGIWMODE; + iwe.u.mode = bss->mode; + start = iwe_stream_add_event(start, stop, &iwe, IW_EV_UINT_LEN); + + /* Frequency */ + iwe.cmd = SIOCGIWFREQ; + iwe.u.freq.m = (long)cfp->freq * 100000; + iwe.u.freq.e = 1; + start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN); + + /* Add quality statistics */ + iwe.cmd = IWEVQUAL; + iwe.u.qual.updated = IW_QUAL_ALL_UPDATED; + iwe.u.qual.level = SCAN_RSSI(bss->rssi); + + rssi = iwe.u.qual.level - MRVDRV_NF_DEFAULT_SCAN_VALUE; + iwe.u.qual.qual = + (100 * RSSI_DIFF * RSSI_DIFF - (PERFECT_RSSI - rssi) * + (15 * (RSSI_DIFF) + 62 * (PERFECT_RSSI - rssi))) / + (RSSI_DIFF * RSSI_DIFF); + if (iwe.u.qual.qual > 100) + iwe.u.qual.qual = 100; + + if (adapter->NF[TYPE_BEACON][TYPE_NOAVG] == 0) { + iwe.u.qual.noise = MRVDRV_NF_DEFAULT_SCAN_VALUE; + } else { + iwe.u.qual.noise = + CAL_NF(adapter->NF[TYPE_BEACON][TYPE_NOAVG]); + } - /* The old API using SIOCGIWAPLIST had a hard limit of IW_MAX_AP. - * The new API using SIOCGIWSCAN is only limited by buffer size - * WE-14 -> WE-16 the buffer is limited to IW_SCAN_MAX_DATA bytes - * which is 4096. + /* Locally created ad-hoc BSSs won't have beacons if this is the + * only station in the adhoc network; so get signal strength + * from receive statistics. */ - for (i = 0; i < adapter->numinscantable; i++) { - if ((current_ev + MAX_SCAN_CELL_SIZE) >= end_buf) { - lbs_pr_debug(1, "i=%d break out: current_ev=%p end_buf=%p " - "MAX_SCAN_CELL_SIZE=%zd\n", - i, current_ev, end_buf, MAX_SCAN_CELL_SIZE); - break; - } - - pscantable = &adapter->scantable[i]; - - lbs_pr_debug(1, "i=%d ssid: %32s\n", i, pscantable->ssid.ssid); - - cfp = - libertas_find_cfp_by_band_and_channel(adapter, 0, - pscantable->channel); - if (!cfp) { - lbs_pr_debug(1, "Invalid channel number %d\n", - pscantable->channel); - continue; - } - - if (!ssid_valid(&adapter->scantable[i].ssid)) { - continue; - } - - /* First entry *MUST* be the AP MAC address */ - iwe.cmd = SIOCGIWAP; - iwe.u.ap_addr.sa_family = ARPHRD_ETHER; - memcpy(iwe.u.ap_addr.sa_data, - &adapter->scantable[i].macaddress, ETH_ALEN); - - iwe.len = IW_EV_ADDR_LEN; - current_ev = - iwe_stream_add_event(current_ev, end_buf, &iwe, iwe.len); - - //Add the ESSID - iwe.u.data.length = adapter->scantable[i].ssid.ssidlength; - - if (iwe.u.data.length > 32) { - iwe.u.data.length = 32; - } - - iwe.cmd = SIOCGIWESSID; - iwe.u.data.flags = 1; - iwe.len = IW_EV_POINT_LEN + iwe.u.data.length; - current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, - adapter->scantable[i].ssid. - ssid); - - //Add mode - iwe.cmd = SIOCGIWMODE; - iwe.u.mode = adapter->scantable[i].mode; - iwe.len = IW_EV_UINT_LEN; - current_ev = - iwe_stream_add_event(current_ev, end_buf, &iwe, iwe.len); - - //frequency - iwe.cmd = SIOCGIWFREQ; - iwe.u.freq.m = (long)cfp->freq * 100000; - iwe.u.freq.e = 1; - iwe.len = IW_EV_FREQ_LEN; - current_ev = - iwe_stream_add_event(current_ev, end_buf, &iwe, iwe.len); - - /* Add quality statistics */ - iwe.cmd = IWEVQUAL; - iwe.u.qual.updated = IW_QUAL_ALL_UPDATED; - iwe.u.qual.level = SCAN_RSSI(adapter->scantable[i].rssi); - - rssi = iwe.u.qual.level - MRVDRV_NF_DEFAULT_SCAN_VALUE; - iwe.u.qual.qual = - (100 * RSSI_DIFF * RSSI_DIFF - (PERFECT_RSSI - rssi) * - (15 * (RSSI_DIFF) + 62 * (PERFECT_RSSI - rssi))) / - (RSSI_DIFF * RSSI_DIFF); - if (iwe.u.qual.qual > 100) - iwe.u.qual.qual = 100; - else if (iwe.u.qual.qual < 1) - iwe.u.qual.qual = 0; - - if (adapter->NF[TYPE_BEACON][TYPE_NOAVG] == 0) { - iwe.u.qual.noise = MRVDRV_NF_DEFAULT_SCAN_VALUE; - } else { - iwe.u.qual.noise = - CAL_NF(adapter->NF[TYPE_BEACON][TYPE_NOAVG]); - } - if ((adapter->mode == IW_MODE_ADHOC) && - !libertas_SSID_cmp(&adapter->curbssparams.ssid, - &adapter->scantable[i].ssid) - && adapter->adhoccreate) { - ret = libertas_prepare_and_send_command(priv, - cmd_802_11_rssi, - 0, - cmd_option_waitforrsp, - 0, NULL); - - if (!ret) { - iwe.u.qual.level = - CAL_RSSI(adapter->SNR[TYPE_RXPD][TYPE_AVG] / - AVG_SCALE, - adapter->NF[TYPE_RXPD][TYPE_AVG] / - AVG_SCALE); - } - } - iwe.len = IW_EV_QUAL_LEN; - current_ev = - iwe_stream_add_event(current_ev, end_buf, &iwe, iwe.len); - - /* Add encryption capability */ - iwe.cmd = SIOCGIWENCODE; - if (adapter->scantable[i].privacy) { - iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; - } else { - iwe.u.data.flags = IW_ENCODE_DISABLED; - } - iwe.u.data.length = 0; - iwe.len = IW_EV_POINT_LEN + iwe.u.data.length; - current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, - adapter->scantable->ssid. - ssid); + if ((adapter->mode == IW_MODE_ADHOC) + && adapter->adhoccreate + && !libertas_ssid_cmp(adapter->curbssparams.ssid, + adapter->curbssparams.ssid_len, + bss->ssid, bss->ssid_len)) { + int snr, nf; + snr = adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE; + nf = adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE; + iwe.u.qual.level = CAL_RSSI(snr, nf); + } + start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN); - current_val = current_ev + IW_EV_LCP_LEN; + /* Add encryption capability */ + iwe.cmd = SIOCGIWENCODE; + if (bss->privacy) { + iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; + } else { + iwe.u.data.flags = IW_ENCODE_DISABLED; + } + iwe.u.data.length = 0; + start = iwe_stream_add_point(start, stop, &iwe, bss->ssid); - iwe.cmd = SIOCGIWRATE; + current_val = start + IW_EV_LCP_LEN; - iwe.u.bitrate.fixed = 0; - iwe.u.bitrate.disabled = 0; - iwe.u.bitrate.value = 0; + iwe.cmd = SIOCGIWRATE; + iwe.u.bitrate.fixed = 0; + iwe.u.bitrate.disabled = 0; + iwe.u.bitrate.value = 0; + for (j = 0; j < sizeof(bss->libertas_supported_rates); j++) { + u8 rate = bss->libertas_supported_rates[j]; + if (rate == 0) + break; /* no more rates */ /* Bit rate given in 500 kb/s units (+ 0x80) */ - for (j = 0; j < sizeof(adapter->scantable[i].libertas_supported_rates); - j++) { - if (adapter->scantable[i].libertas_supported_rates[j] == 0) { - break; - } - rate = - (adapter->scantable[i].libertas_supported_rates[j] & 0x7F) * - 500000; - if (rate > iwe.u.bitrate.value) { - iwe.u.bitrate.value = rate; - } - - iwe.u.bitrate.value = - (adapter->scantable[i].libertas_supported_rates[j] - & 0x7f) * 500000; - iwe.len = IW_EV_PARAM_LEN; - current_ev = - iwe_stream_add_value(current_ev, current_val, - end_buf, &iwe, iwe.len); + iwe.u.bitrate.value = (rate & 0x7f) * 500000; + current_val = iwe_stream_add_value(start, current_val, + stop, &iwe, IW_EV_PARAM_LEN); + } + if ((bss->mode == IW_MODE_ADHOC) + && !libertas_ssid_cmp(adapter->curbssparams.ssid, + adapter->curbssparams.ssid_len, + bss->ssid, bss->ssid_len) + && adapter->adhoccreate) { + iwe.u.bitrate.value = 22 * 500000; + current_val = iwe_stream_add_value(start, current_val, + stop, &iwe, IW_EV_PARAM_LEN); + } + /* Check if we added any event */ + if((current_val - start) > IW_EV_LCP_LEN) + start = current_val; + + memset(&iwe, 0, sizeof(iwe)); + if (bss->wpa_ie_len) { + char buf[MAX_WPA_IE_LEN]; + memcpy(buf, bss->wpa_ie, bss->wpa_ie_len); + iwe.cmd = IWEVGENIE; + iwe.u.data.length = bss->wpa_ie_len; + start = iwe_stream_add_point(start, stop, &iwe, buf); + } - } - if ((adapter->scantable[i].mode == IW_MODE_ADHOC) - && !libertas_SSID_cmp(&adapter->curbssparams.ssid, - &adapter->scantable[i].ssid) - && adapter->adhoccreate) { - iwe.u.bitrate.value = 22 * 500000; - } - iwe.len = IW_EV_PARAM_LEN; - current_ev = - iwe_stream_add_value(current_ev, current_val, end_buf, &iwe, - iwe.len); - - /* Add new value to event */ - current_val = current_ev + IW_EV_LCP_LEN; - - if (adapter->scantable[i].rsn_ie[0] == WPA2_IE) { - memset(&iwe, 0, sizeof(iwe)); - memset(buf, 0, sizeof(buf)); - memcpy(buf, adapter->scantable[i].rsn_ie, - adapter->scantable[i].rsn_ie_len); - iwe.cmd = IWEVGENIE; - iwe.u.data.length = adapter->scantable[i].rsn_ie_len; - iwe.len = IW_EV_POINT_LEN + iwe.u.data.length; - current_ev = iwe_stream_add_point(current_ev, end_buf, - &iwe, buf); - } - if (adapter->scantable[i].wpa_ie[0] == WPA_IE) { - memset(&iwe, 0, sizeof(iwe)); - memset(buf, 0, sizeof(buf)); - memcpy(buf, adapter->scantable[i].wpa_ie, - adapter->scantable[i].wpa_ie_len); - iwe.cmd = IWEVGENIE; - iwe.u.data.length = adapter->scantable[i].wpa_ie_len; - iwe.len = IW_EV_POINT_LEN + iwe.u.data.length; - current_ev = iwe_stream_add_point(current_ev, end_buf, - &iwe, buf); - } + memset(&iwe, 0, sizeof(iwe)); + if (bss->rsn_ie_len) { + char buf[MAX_WPA_IE_LEN]; + memcpy(buf, bss->rsn_ie, bss->rsn_ie_len); + iwe.cmd = IWEVGENIE; + iwe.u.data.length = bss->rsn_ie_len; + start = iwe_stream_add_point(start, stop, &iwe, buf); + } + return start; +} - if (adapter->scantable[i].extra_ie != 0) { - memset(&iwe, 0, sizeof(iwe)); - memset(buf, 0, sizeof(buf)); - ptr = buf; - ptr += sprintf(ptr, "extra_ie"); - iwe.u.data.length = strlen(buf); +/** + * @brief Retrieve the scan table entries via wireless tools IOCTL call + * + * @param dev A pointer to net_device structure + * @param info A pointer to iw_request_info structure + * @param dwrq A pointer to iw_point structure + * @param extra A pointer to extra data buf + * + * @return 0 --success, otherwise fail + */ +int libertas_get_scan(struct net_device *dev, struct iw_request_info *info, + struct iw_point *dwrq, char *extra) +{ +#define SCAN_ITEM_SIZE 128 + wlan_private *priv = dev->priv; + wlan_adapter *adapter = priv->adapter; + int err = 0; + char *ev = extra; + char *stop = ev + dwrq->length; + struct bss_descriptor * iter_bss; + struct bss_descriptor * safe; + + lbs_deb_enter(LBS_DEB_ASSOC); + + /* If we've got an uncompleted scan, schedule the next part */ + if (!adapter->nr_cmd_pending && adapter->last_scanned_channel) + wlan_scan_networks(priv, NULL, 0); + + /* Update RSSI if current BSS is a locally created ad-hoc BSS */ + if ((adapter->mode == IW_MODE_ADHOC) && adapter->adhoccreate) { + libertas_prepare_and_send_command(priv, cmd_802_11_rssi, 0, + cmd_option_waitforrsp, 0, NULL); + } - lbs_pr_debug(1, "iwe.u.data.length %d\n", - iwe.u.data.length); - lbs_pr_debug(1, "BUF: %s \n", buf); + mutex_lock(&adapter->lock); + list_for_each_entry_safe (iter_bss, safe, &adapter->network_list, list) { + char * next_ev; + unsigned long stale_time; - iwe.cmd = IWEVCUSTOM; - iwe.len = IW_EV_POINT_LEN + iwe.u.data.length; - current_ev = - iwe_stream_add_point(current_ev, end_buf, &iwe, - buf); + if (stop - ev < SCAN_ITEM_SIZE) { + err = -E2BIG; + break; } - current_val = current_ev + IW_EV_LCP_LEN; + /* Prune old an old scan result */ + stale_time = iter_bss->last_scanned + DEFAULT_MAX_SCAN_AGE; + if (time_after(jiffies, stale_time)) { + list_move_tail (&iter_bss->list, + &adapter->network_free_list); + clear_bss_descriptor(iter_bss); + continue; + } - /* - * Check if we added any event - */ - if ((current_val - current_ev) > IW_EV_LCP_LEN) - current_ev = current_val; + /* Translate to WE format this entry */ + next_ev = libertas_translate_scan(priv, ev, stop, iter_bss); + if (next_ev == NULL) + continue; + ev = next_ev; } + mutex_unlock(&adapter->lock); - dwrq->length = (current_ev - extra); + dwrq->length = (ev - extra); dwrq->flags = 0; - LEAVE(); - return 0; + lbs_deb_leave(LBS_DEB_ASSOC); + return err; } /** @@ -1796,13 +1702,13 @@ int libertas_cmd_80211_scan(wlan_private * priv, struct cmd_ds_802_11_scan *pscan = &cmd->params.scan; struct wlan_scan_cmd_config *pscancfg; - ENTER(); + lbs_deb_enter(LBS_DEB_ASSOC); pscancfg = pdata_buf; /* Set fixed field variables in scan command */ pscan->bsstype = pscancfg->bsstype; - memcpy(pscan->BSSID, pscancfg->specificBSSID, sizeof(pscan->BSSID)); + memcpy(pscan->BSSID, pscancfg->bssid, sizeof(pscan->BSSID)); memcpy(pscan->tlvbuffer, pscancfg->tlvbuffer, pscancfg->tlvbufferlen); cmd->command = cpu_to_le16(cmd_802_11_scan); @@ -1812,12 +1718,26 @@ int libertas_cmd_80211_scan(wlan_private * priv, + sizeof(pscan->BSSID) + pscancfg->tlvbufferlen + S_DS_GEN); - lbs_pr_debug(1, "SCAN_CMD: command=%x, size=%x, seqnum=%x\n", - cmd->command, cmd->size, cmd->seqnum); - LEAVE(); + lbs_deb_scan("SCAN_CMD: command=%x, size=%x, seqnum=%x\n", + le16_to_cpu(cmd->command), le16_to_cpu(cmd->size), + le16_to_cpu(cmd->seqnum)); + + lbs_deb_leave(LBS_DEB_ASSOC); return 0; } +static inline int is_same_network(struct bss_descriptor *src, + struct bss_descriptor *dst) +{ + /* A network is only a duplicate if the channel, BSSID, and ESSID + * all match. We treat all <hidden> with the same BSSID and channel + * as one network */ + return ((src->ssid_len == dst->ssid_len) && + (src->channel == dst->channel) && + !compare_ether_addr(src->bssid, dst->bssid) && + !memcmp(src->ssid, dst->ssid, src->ssid_len)); +} + /** * @brief This function handles the command response of scan * @@ -1846,38 +1766,45 @@ int libertas_ret_80211_scan(wlan_private * priv, struct cmd_ds_command *resp) { wlan_adapter *adapter = priv->adapter; struct cmd_ds_802_11_scan_rsp *pscan; - struct bss_descriptor newbssentry; struct mrvlietypes_data *ptlv; struct mrvlietypes_tsftimestamp *ptsftlv; + struct bss_descriptor * iter_bss; + struct bss_descriptor * safe; u8 *pbssinfo; u16 scanrespsize; int bytesleft; - int numintable; - int bssIdx; int idx; int tlvbufsize; - u64 tsfval; + int ret; - ENTER(); + lbs_deb_enter(LBS_DEB_ASSOC); + + /* Prune old entries from scan table */ + list_for_each_entry_safe (iter_bss, safe, &adapter->network_list, list) { + unsigned long stale_time = iter_bss->last_scanned + DEFAULT_MAX_SCAN_AGE; + if (time_before(jiffies, stale_time)) + continue; + list_move_tail (&iter_bss->list, &adapter->network_free_list); + clear_bss_descriptor(iter_bss); + } pscan = &resp->params.scanresp; - if (pscan->nr_sets > MRVDRV_MAX_BSSID_LIST) { - lbs_pr_debug(1, - "SCAN_RESP: Invalid number of AP returned (%d)!!\n", - pscan->nr_sets); - LEAVE(); - return -1; + if (pscan->nr_sets > MAX_NETWORK_COUNT) { + lbs_deb_scan( + "SCAN_RESP: too many scan results (%d, max %d)!!\n", + pscan->nr_sets, MAX_NETWORK_COUNT); + ret = -1; + goto done; } bytesleft = le16_to_cpu(pscan->bssdescriptsize); - lbs_pr_debug(1, "SCAN_RESP: bssdescriptsize %d\n", bytesleft); + lbs_deb_scan("SCAN_RESP: bssdescriptsize %d\n", bytesleft); scanrespsize = le16_to_cpu(resp->size); - lbs_pr_debug(1, "SCAN_RESP: returned %d AP before parsing\n", + lbs_deb_scan("SCAN_RESP: returned %d AP before parsing\n", pscan->nr_sets); - numintable = adapter->numinscantable; pbssinfo = pscan->bssdesc_and_tlvbuffer; /* The size of the TLV buffer is equal to the entire command response @@ -1901,105 +1828,68 @@ int libertas_ret_80211_scan(wlan_private * priv, struct cmd_ds_command *resp) * or as an addition at the end of the table */ for (idx = 0; idx < pscan->nr_sets && bytesleft; idx++) { - /* Zero out the newbssentry we are about to store info in */ - memset(&newbssentry, 0x00, sizeof(newbssentry)); + struct bss_descriptor new; + struct bss_descriptor * found = NULL; + struct bss_descriptor * oldest = NULL; /* Process the data fields and IEs returned for this BSS */ - if ((InterpretBSSDescriptionWithIE(&newbssentry, - &pbssinfo, - &bytesleft) == - 0) - && CHECK_SSID_IS_VALID(&newbssentry.ssid)) { - - lbs_pr_debug(1, - "SCAN_RESP: BSSID = %02x:%02x:%02x:%02x:%02x:%02x\n", - newbssentry.macaddress[0], - newbssentry.macaddress[1], - newbssentry.macaddress[2], - newbssentry.macaddress[3], - newbssentry.macaddress[4], - newbssentry.macaddress[5]); - - /* - * Search the scan table for the same bssid - */ - for (bssIdx = 0; bssIdx < numintable; bssIdx++) { - if (memcmp(newbssentry.macaddress, - adapter->scantable[bssIdx]. - macaddress, - sizeof(newbssentry.macaddress)) == - 0) { - /* - * If the SSID matches as well, it is a duplicate of - * this entry. Keep the bssIdx set to this - * entry so we replace the old contents in the table - */ - if ((newbssentry.ssid.ssidlength == - adapter->scantable[bssIdx].ssid. - ssidlength) - && - (memcmp - (newbssentry.ssid.ssid, - adapter->scantable[bssIdx].ssid. - ssid, - newbssentry.ssid.ssidlength) == - 0)) { - lbs_pr_debug(1, - "SCAN_RESP: Duplicate of index: %d\n", - bssIdx); - break; - } - } - } - /* - * If the bssIdx is equal to the number of entries in the table, - * the new entry was not a duplicate; append it to the scan - * table - */ - if (bssIdx == numintable) { - /* Range check the bssIdx, keep it limited to the last entry */ - if (bssIdx == MRVDRV_MAX_BSSID_LIST) { - bssIdx--; - } else { - numintable++; - } - } - - /* - * If the TSF TLV was appended to the scan results, save the - * this entries TSF value in the networktsf field. The - * networktsf is the firmware's TSF value at the time the - * beacon or probe response was received. - */ - if (ptsftlv) { - memcpy(&tsfval, &ptsftlv->tsftable[idx], - sizeof(tsfval)); - tsfval = le64_to_cpu(tsfval); + memset(&new, 0, sizeof (struct bss_descriptor)); + if (libertas_process_bss(&new, &pbssinfo, &bytesleft) != 0) { + /* error parsing the scan response, skipped */ + lbs_deb_scan("SCAN_RESP: process_bss returned ERROR\n"); + continue; + } - memcpy(&newbssentry.networktsf, - &tsfval, sizeof(newbssentry.networktsf)); + /* Try to find this bss in the scan table */ + list_for_each_entry (iter_bss, &adapter->network_list, list) { + if (is_same_network(iter_bss, &new)) { + found = iter_bss; + break; } - /* Copy the locally created newbssentry to the scan table */ - memcpy(&adapter->scantable[bssIdx], - &newbssentry, - sizeof(adapter->scantable[bssIdx])); + if ((oldest == NULL) || + (iter_bss->last_scanned < oldest->last_scanned)) + oldest = iter_bss; + } + if (found) { + /* found, clear it */ + clear_bss_descriptor(found); + } else if (!list_empty(&adapter->network_free_list)) { + /* Pull one from the free list */ + found = list_entry(adapter->network_free_list.next, + struct bss_descriptor, list); + list_move_tail(&found->list, &adapter->network_list); + } else if (oldest) { + /* If there are no more slots, expire the oldest */ + found = oldest; + clear_bss_descriptor(found); + list_move_tail(&found->list, &adapter->network_list); } else { + continue; + } + + lbs_deb_scan("SCAN_RESP: BSSID = " MAC_FMT "\n", + new.bssid[0], new.bssid[1], new.bssid[2], + new.bssid[3], new.bssid[4], new.bssid[5]); - /* error parsing/interpreting the scan response, skipped */ - lbs_pr_debug(1, "SCAN_RESP: " - "InterpretBSSDescriptionWithIE returned ERROR\n"); + /* + * If the TSF TLV was appended to the scan results, save the + * this entries TSF value in the networktsf field. The + * networktsf is the firmware's TSF value at the time the + * beacon or probe response was received. + */ + if (ptsftlv) { + new.networktsf = le64_to_cpup(&ptsftlv->tsftable[idx]); } - } - lbs_pr_debug(1, "SCAN_RESP: Scanned %2d APs, %d valid, %d total\n", - pscan->nr_sets, numintable - adapter->numinscantable, - numintable); + /* Copy the locally created newbssentry to the scan table */ + memcpy(found, &new, offsetof(struct bss_descriptor, list)); + } - /* Update the total number of BSSIDs in the scan table */ - adapter->numinscantable = numintable; + ret = 0; - LEAVE(); - return 0; +done: + lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret); + return ret; } diff --git a/drivers/net/wireless/libertas/scan.h b/drivers/net/wireless/libertas/scan.h index 405f4f0fe57..bd019e5ff1e 100644 --- a/drivers/net/wireless/libertas/scan.h +++ b/drivers/net/wireless/libertas/scan.h @@ -51,7 +51,7 @@ struct wlan_scan_cmd_config { /** * @brief Specific BSSID used to filter scan results in the firmware */ - u8 specificBSSID[ETH_ALEN]; + u8 bssid[ETH_ALEN]; /** * @brief length of TLVs sent in command starting at tlvBuffer @@ -91,15 +91,6 @@ struct wlan_ioctl_user_scan_chan { * @sa libertas_set_user_scan_ioctl */ struct wlan_ioctl_user_scan_cfg { - - /** - * @brief Flag set to keep the previous scan table intact - * - * If set, the scan results will accumulate, replacing any previous - * matched entries for a BSS with the new scan data - */ - u8 keeppreviousscan; //!< Do not erase the existing scan results - /** * @brief BSS type to be sent in the firmware command * @@ -117,15 +108,22 @@ struct wlan_ioctl_user_scan_cfg { */ u8 numprobes; - /** - * @brief BSSID filter sent in the firmware command to limit the results - */ - u8 specificBSSID[ETH_ALEN]; + /** + * @brief BSSID filter sent in the firmware command to limit the results + */ + u8 bssid[ETH_ALEN]; - /** - * @brief SSID filter sent in the firmware command to limit the results - */ - char specificSSID[IW_ESSID_MAX_SIZE + 1]; + /* Clear existing scan results matching this BSSID */ + u8 clear_bssid; + + /** + * @brief SSID filter sent in the firmware command to limit the results + */ + char ssid[IW_ESSID_MAX_SIZE]; + u8 ssid_len; + + /* Clear existing scan results matching this SSID */ + u8 clear_ssid; /** * @brief Variable number (fixed maximum) of channels to scan up @@ -137,9 +135,10 @@ struct wlan_ioctl_user_scan_cfg { * @brief Structure used to store information for each beacon/probe response */ struct bss_descriptor { - u8 macaddress[ETH_ALEN]; + u8 bssid[ETH_ALEN]; - struct WLAN_802_11_SSID ssid; + u8 ssid[IW_ESSID_MAX_SIZE + 1]; + u8 ssid_len; /* WEP encryption requirement */ u32 privacy; @@ -156,15 +155,15 @@ struct bss_descriptor { u8 mode; u8 libertas_supported_rates[WLAN_SUPPORTED_RATES]; - int extra_ie; + __le64 timestamp; //!< TSF value included in the beacon/probe response + unsigned long last_scanned; - u8 timestamp[8]; //!< TSF value included in the beacon/probe response union ieeetypes_phyparamset phyparamset; union IEEEtypes_ssparamset ssparamset; struct ieeetypes_capinfo cap; u8 datarates[WLAN_SUPPORTED_RATES]; - __le64 networktsf; //!< TSF timestamp from the current firmware TSF + u64 networktsf; //!< TSF timestamp from the current firmware TSF struct ieeetypes_countryinfofullset countryinfo; @@ -172,24 +171,29 @@ struct bss_descriptor { size_t wpa_ie_len; u8 rsn_ie[MAX_WPA_IE_LEN]; size_t rsn_ie_len; + + struct list_head list; }; -extern int libertas_SSID_cmp(struct WLAN_802_11_SSID *ssid1, - struct WLAN_802_11_SSID *ssid2); -extern int libertas_find_SSID_in_list(wlan_adapter * adapter, struct WLAN_802_11_SSID *ssid, - u8 * bssid, u8 mode); -int libertas_find_best_SSID_in_list(wlan_adapter * adapter, u8 mode); -extern int libertas_find_BSSID_in_list(wlan_adapter * adapter, u8 * bssid, u8 mode); +extern int libertas_ssid_cmp(u8 *ssid1, u8 ssid1_len, u8 *ssid2, u8 ssid2_len); + +struct bss_descriptor * libertas_find_ssid_in_list(wlan_adapter * adapter, + u8 *ssid, u8 ssid_len, u8 * bssid, u8 mode, + int channel); + +struct bss_descriptor * libertas_find_best_ssid_in_list(wlan_adapter * adapter, + u8 mode); + +extern struct bss_descriptor * libertas_find_bssid_in_list(wlan_adapter * adapter, + u8 * bssid, u8 mode); -int libertas_find_best_network_SSID(wlan_private * priv, - struct WLAN_802_11_SSID *pSSID, - u8 preferred_mode, u8 *out_mode); +int libertas_find_best_network_ssid(wlan_private * priv, u8 *out_ssid, + u8 *out_ssid_len, u8 preferred_mode, u8 *out_mode); -extern int libertas_send_specific_SSID_scan(wlan_private * priv, - struct WLAN_802_11_SSID *prequestedssid, - u8 keeppreviousscan); -extern int libertas_send_specific_BSSID_scan(wlan_private * priv, - u8 * bssid, u8 keeppreviousscan); +extern int libertas_send_specific_ssid_scan(wlan_private * priv, u8 *ssid, + u8 ssid_len, u8 clear_ssid); +extern int libertas_send_specific_bssid_scan(wlan_private * priv, + u8 * bssid, u8 clear_bssid); extern int libertas_cmd_80211_scan(wlan_private * priv, struct cmd_ds_command *cmd, @@ -199,7 +203,8 @@ extern int libertas_ret_80211_scan(wlan_private * priv, struct cmd_ds_command *resp); int wlan_scan_networks(wlan_private * priv, - const struct wlan_ioctl_user_scan_cfg * puserscanin); + const struct wlan_ioctl_user_scan_cfg * puserscanin, + int full_scan); struct ifreq; diff --git a/drivers/net/wireless/libertas/thread.h b/drivers/net/wireless/libertas/thread.h index 207b8a6cc33..b1f34d92ff3 100644 --- a/drivers/net/wireless/libertas/thread.h +++ b/drivers/net/wireless/libertas/thread.h @@ -21,11 +21,11 @@ static inline void wlan_activate_thread(struct wlan_thread * thr) static inline void wlan_deactivate_thread(struct wlan_thread * thr) { - ENTER(); + lbs_deb_enter(LBS_DEB_THREAD); thr->pid = 0; - LEAVE(); + lbs_deb_leave(LBS_DEB_THREAD); } static inline void wlan_create_thread(int (*wlanfunc) (void *), @@ -36,7 +36,7 @@ static inline void wlan_create_thread(int (*wlanfunc) (void *), static inline int wlan_terminate_thread(struct wlan_thread * thr) { - ENTER(); + lbs_deb_enter(LBS_DEB_THREAD); /* Check if the thread is active or not */ if (!thr->pid) { @@ -45,7 +45,7 @@ static inline int wlan_terminate_thread(struct wlan_thread * thr) } kthread_stop(thr->task); - LEAVE(); + lbs_deb_leave(LBS_DEB_THREAD); return 0; } diff --git a/drivers/net/wireless/libertas/tx.c b/drivers/net/wireless/libertas/tx.c index d4b13478c9a..17c437635a0 100644 --- a/drivers/net/wireless/libertas/tx.c +++ b/drivers/net/wireless/libertas/tx.c @@ -5,7 +5,6 @@ #include "hostcmd.h" #include "radiotap.h" -#include "sbi.h" #include "decl.h" #include "defs.h" #include "dev.h" @@ -68,7 +67,7 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb) u32 new_rate; u8 *ptr = priv->adapter->tmptxbuf; - ENTER(); + lbs_deb_enter(LBS_DEB_TX); if (priv->adapter->surpriseremoved) return -1; @@ -78,7 +77,7 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb) min_t(unsigned int, skb->len, 100)); if (!skb->len || (skb->len > MRVDRV_ETH_TX_PACKET_BUFFER_SIZE)) { - lbs_pr_debug(1, "Tx error: Bad skb length %d : %zd\n", + lbs_deb_tx("tx err: skb length %d 0 or > %zd\n", skb->len, MRVDRV_ETH_TX_PACKET_BUFFER_SIZE); ret = -1; goto done; @@ -86,13 +85,13 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb) memset(plocaltxpd, 0, sizeof(struct txpd)); - plocaltxpd->tx_packet_length = skb->len; + plocaltxpd->tx_packet_length = cpu_to_le16(skb->len); /* offset of actual data */ - plocaltxpd->tx_packet_location = sizeof(struct txpd); + plocaltxpd->tx_packet_location = cpu_to_le32(sizeof(struct txpd)); /* TxCtrl set by user or default */ - plocaltxpd->tx_control = adapter->pkttxctrl; + plocaltxpd->tx_control = cpu_to_le32(adapter->pkttxctrl); p802x_hdr = skb->data; if (priv->adapter->radiomode == WLAN_RADIOMODE_RADIOTAP) { @@ -103,15 +102,16 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb) /* set txpd fields from the radiotap header */ new_rate = convert_radiotap_rate_to_mv(pradiotap_hdr->rate); if (new_rate != 0) { - /* erase tx_control[4:0] */ - plocaltxpd->tx_control &= ~0x1f; - /* write new tx_control[4:0] */ - plocaltxpd->tx_control |= new_rate; + /* use new tx_control[4:0] */ + new_rate |= (adapter->pkttxctrl & ~0x1f); + plocaltxpd->tx_control = cpu_to_le32(new_rate); } /* skip the radiotap header */ p802x_hdr += sizeof(struct tx_radiotap_hdr); - plocaltxpd->tx_packet_length -= sizeof(struct tx_radiotap_hdr); + plocaltxpd->tx_packet_length = + cpu_to_le16(le16_to_cpu(plocaltxpd->tx_packet_length) + - sizeof(struct tx_radiotap_hdr)); } /* copy destination address from 802.3 or 802.11 header */ @@ -123,28 +123,28 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb) lbs_dbg_hex("txpd", (u8 *) plocaltxpd, sizeof(struct txpd)); if (IS_MESH_FRAME(skb)) { - plocaltxpd->tx_control |= TxPD_MESH_FRAME; + plocaltxpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME); } memcpy(ptr, plocaltxpd, sizeof(struct txpd)); ptr += sizeof(struct txpd); - lbs_dbg_hex("Tx Data", (u8 *) p802x_hdr, plocaltxpd->tx_packet_length); - memcpy(ptr, p802x_hdr, plocaltxpd->tx_packet_length); - ret = libertas_sbi_host_to_card(priv, MVMS_DAT, - priv->adapter->tmptxbuf, - plocaltxpd->tx_packet_length + - sizeof(struct txpd)); + lbs_dbg_hex("Tx Data", (u8 *) p802x_hdr, le16_to_cpu(plocaltxpd->tx_packet_length)); + memcpy(ptr, p802x_hdr, le16_to_cpu(plocaltxpd->tx_packet_length)); + ret = priv->hw_host_to_card(priv, MVMS_DAT, + priv->adapter->tmptxbuf, + le16_to_cpu(plocaltxpd->tx_packet_length) + + sizeof(struct txpd)); if (ret) { - lbs_pr_debug(1, "Tx error: libertas_sbi_host_to_card failed: 0x%X\n", ret); + lbs_deb_tx("tx err: hw_host_to_card returned 0x%X\n", ret); goto done; } - lbs_pr_debug(1, "SendSinglePacket succeeds\n"); + lbs_deb_tx("SendSinglePacket succeeds\n"); - done: +done: if (!ret) { priv->stats.tx_packets++; priv->stats.tx_bytes += skb->len; @@ -158,7 +158,8 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb) received from FW */ skb_orphan(skb); /* stop processing outgoing pkts */ - netif_stop_queue(priv->wlan_dev.netdev); + netif_stop_queue(priv->dev); + netif_stop_queue(priv->mesh_dev); /* freeze any packets already in our queues */ priv->adapter->TxLockFlag = 1; } else { @@ -166,7 +167,7 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb) priv->adapter->currenttxskb = NULL; } - LEAVE(); + lbs_deb_leave_args(LBS_DEB_TX, "ret %d", ret); return ret; } @@ -195,10 +196,13 @@ static void wlan_tx_queue(wlan_private *priv, struct sk_buff *skb) WARN_ON(priv->adapter->tx_queue_idx >= NR_TX_QUEUE); adapter->tx_queue_ps[adapter->tx_queue_idx++] = skb; - if (adapter->tx_queue_idx == NR_TX_QUEUE) - netif_stop_queue(priv->wlan_dev.netdev); - else - netif_start_queue(priv->wlan_dev.netdev); + if (adapter->tx_queue_idx == NR_TX_QUEUE) { + netif_stop_queue(priv->dev); + netif_stop_queue(priv->mesh_dev); + } else { + netif_start_queue(priv->dev); + netif_start_queue(priv->mesh_dev); + } spin_unlock(&adapter->txqueue_lock); } @@ -214,13 +218,12 @@ int libertas_process_tx(wlan_private * priv, struct sk_buff *skb) { int ret = -1; - ENTER(); - + lbs_deb_enter(LBS_DEB_TX); lbs_dbg_hex("TX Data", skb->data, min_t(unsigned int, skb->len, 100)); - if (priv->wlan_dev.dnld_sent) { + if (priv->dnld_sent) { lbs_pr_alert( "TX error: dnld_sent = %d, not sending\n", - priv->wlan_dev.dnld_sent); + priv->dnld_sent); goto done; } @@ -234,7 +237,7 @@ int libertas_process_tx(wlan_private * priv, struct sk_buff *skb) ret = SendSinglePacket(priv, skb); done: - LEAVE(); + lbs_deb_leave_args(LBS_DEB_TX, "ret %d", ret); return ret; } @@ -280,6 +283,9 @@ void libertas_send_tx_feedback(wlan_private * priv) libertas_upload_rx_packet(priv, adapter->currenttxskb); adapter->currenttxskb = NULL; priv->adapter->TxLockFlag = 0; - if (priv->adapter->connect_status == libertas_connected) - netif_wake_queue(priv->wlan_dev.netdev); + if (priv->adapter->connect_status == libertas_connected) { + netif_wake_queue(priv->dev); + netif_wake_queue(priv->mesh_dev); + } } +EXPORT_SYMBOL_GPL(libertas_send_tx_feedback); diff --git a/drivers/net/wireless/libertas/types.h b/drivers/net/wireless/libertas/types.h index 09d62f8b1a1..028e2f3b53d 100644 --- a/drivers/net/wireless/libertas/types.h +++ b/drivers/net/wireless/libertas/types.h @@ -5,6 +5,7 @@ #define _WLAN_TYPES_ #include <linux/if_ether.h> +#include <asm/byteorder.h> /** IEEE type definitions */ enum ieeetypes_elementid { @@ -29,9 +30,30 @@ enum ieeetypes_elementid { EXTRA_IE = 133, } __attribute__ ((packed)); +#ifdef __BIG_ENDIAN #define CAPINFO_MASK (~(0xda00)) +#else +#define CAPINFO_MASK (~(0x00da)) +#endif struct ieeetypes_capinfo { +#ifdef __BIG_ENDIAN_BITFIELD + u8 chanagility:1; + u8 pbcc:1; + u8 shortpreamble:1; + u8 privacy:1; + u8 cfpollrqst:1; + u8 cfpollable:1; + u8 ibss:1; + u8 ess:1; + u8 rsrvd1:2; + u8 dsssofdm:1; + u8 rsvrd2:1; + u8 apsd:1; + u8 shortslottime:1; + u8 rsrvd3:1; + u8 spectrummgmt:1; +#else u8 ess:1; u8 ibss:1; u8 cfpollable:1; @@ -47,6 +69,7 @@ struct ieeetypes_capinfo { u8 rsvrd2:1; u8 dsssofdm:1; u8 rsrvd1:2; +#endif } __attribute__ ((packed)); struct ieeetypes_cfparamset { @@ -54,15 +77,15 @@ struct ieeetypes_cfparamset { u8 len; u8 cfpcnt; u8 cfpperiod; - u16 cfpmaxduration; - u16 cfpdurationremaining; + __le16 cfpmaxduration; + __le16 cfpdurationremaining; } __attribute__ ((packed)); struct ieeetypes_ibssparamset { u8 elementid; u8 len; - u16 atimwindow; + __le16 atimwindow; } __attribute__ ((packed)); union IEEEtypes_ssparamset { @@ -73,7 +96,7 @@ union IEEEtypes_ssparamset { struct ieeetypes_fhparamset { u8 elementid; u8 len; - u16 dwelltime; + __le16 dwelltime; u8 hopset; u8 hoppattern; u8 hopindex; @@ -92,8 +115,8 @@ union ieeetypes_phyparamset { struct ieeetypes_assocrsp { struct ieeetypes_capinfo capability; - u16 statuscode; - u16 aid; + __le16 statuscode; + __le16 aid; u8 iebuffer[1]; } __attribute__ ((packed)); @@ -138,8 +161,8 @@ struct ieeetypes_assocrsp { /** TLV related data structures*/ struct mrvlietypesheader { - u16 type; - u16 len; + __le16 type; + __le16 len; } __attribute__ ((packed)); struct mrvlietypes_data { @@ -164,17 +187,23 @@ struct mrvlietypes_wildcardssidparamset { } __attribute__ ((packed)); struct chanscanmode { +#ifdef __BIG_ENDIAN_BITFIELD + u8 reserved_2_7:6; + u8 disablechanfilt:1; + u8 passivescan:1; +#else u8 passivescan:1; u8 disablechanfilt:1; u8 reserved_2_7:6; +#endif } __attribute__ ((packed)); struct chanscanparamset { u8 radiotype; u8 channumber; struct chanscanmode chanscanmode; - u16 minscantime; - u16 maxscantime; + __le16 minscantime; + __le16 maxscantime; } __attribute__ ((packed)); struct mrvlietypes_chanlistparamset { @@ -185,12 +214,12 @@ struct mrvlietypes_chanlistparamset { struct cfparamset { u8 cfpcnt; u8 cfpperiod; - u16 cfpmaxduration; - u16 cfpdurationremaining; + __le16 cfpmaxduration; + __le16 cfpdurationremaining; } __attribute__ ((packed)); struct ibssparamset { - u16 atimwindow; + __le16 atimwindow; } __attribute__ ((packed)); struct mrvlietypes_ssparamset { @@ -202,7 +231,7 @@ struct mrvlietypes_ssparamset { } __attribute__ ((packed)); struct fhparamset { - u16 dwelltime; + __le16 dwelltime; u8 hopset; u8 hoppattern; u8 hopindex; @@ -263,17 +292,17 @@ struct mrvlietypes_beaconsmissed { struct mrvlietypes_numprobes { struct mrvlietypesheader header; - u16 numprobes; + __le16 numprobes; } __attribute__ ((packed)); struct mrvlietypes_bcastprobe { struct mrvlietypesheader header; - u16 bcastprobe; + __le16 bcastprobe; } __attribute__ ((packed)); struct mrvlietypes_numssidprobe { struct mrvlietypesheader header; - u16 numssidprobe; + __le16 numssidprobe; } __attribute__ ((packed)); struct led_pin { diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c index 69f52b6e59c..f42b796b5e4 100644 --- a/drivers/net/wireless/libertas/wext.c +++ b/drivers/net/wireless/libertas/wext.c @@ -22,6 +22,14 @@ /** + * the rates supported by the card + */ +static u8 libertas_wlan_data_rates[WLAN_SUPPORTED_RATES] = + { 0x02, 0x04, 0x0B, 0x16, 0x00, 0x0C, 0x12, + 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x00 +}; + +/** * @brief Convert mw value to dbm value * * @param mw the value of mw @@ -102,8 +110,8 @@ struct chan_freq_power *libertas_find_cfp_by_band_and_channel(wlan_adapter * ada } if (!cfp && channel) - lbs_pr_debug(1, "libertas_find_cfp_by_band_and_channel(): cannot find " - "cfp by band %d & channel %d\n", band, channel); + lbs_deb_wext("libertas_find_cfp_by_band_and_channel: can't find " + "cfp by band %d / channel %d\n", band, channel); return cfp; } @@ -143,113 +151,12 @@ static struct chan_freq_power *find_cfp_by_band_and_freq(wlan_adapter * adapter, } if (!cfp && freq) - lbs_pr_debug(1, "find_cfp_by_band_and_freql(): cannot find cfp by " - "band %d & freq %d\n", band, freq); + lbs_deb_wext("find_cfp_by_band_and_freql: can't find cfp by " + "band %d / freq %d\n", band, freq); return cfp; } -static int updatecurrentchannel(wlan_private * priv) -{ - int ret; - - /* - ** the channel in f/w could be out of sync, get the current channel - */ - ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_channel, - cmd_opt_802_11_rf_channel_get, - cmd_option_waitforrsp, 0, NULL); - - lbs_pr_debug(1, "Current channel = %d\n", - priv->adapter->curbssparams.channel); - - return ret; -} - -static int setcurrentchannel(wlan_private * priv, int channel) -{ - lbs_pr_debug(1, "Set channel = %d\n", channel); - - /* - ** Current channel is not set to adhocchannel requested, set channel - */ - return (libertas_prepare_and_send_command(priv, cmd_802_11_rf_channel, - cmd_opt_802_11_rf_channel_set, - cmd_option_waitforrsp, 0, &channel)); -} - -static int changeadhocchannel(wlan_private * priv, int channel) -{ - int ret = 0; - wlan_adapter *adapter = priv->adapter; - - adapter->adhocchannel = channel; - - updatecurrentchannel(priv); - - if (adapter->curbssparams.channel == adapter->adhocchannel) { - /* adhocchannel is set to the current channel already */ - LEAVE(); - return 0; - } - - lbs_pr_debug(1, "Updating channel from %d to %d\n", - adapter->curbssparams.channel, adapter->adhocchannel); - - setcurrentchannel(priv, adapter->adhocchannel); - - updatecurrentchannel(priv); - - if (adapter->curbssparams.channel != adapter->adhocchannel) { - lbs_pr_debug(1, "failed to updated channel to %d, channel = %d\n", - adapter->adhocchannel, adapter->curbssparams.channel); - LEAVE(); - return -1; - } - - if (adapter->connect_status == libertas_connected) { - int i; - struct WLAN_802_11_SSID curadhocssid; - - lbs_pr_debug(1, "channel Changed while in an IBSS\n"); - - /* Copy the current ssid */ - memcpy(&curadhocssid, &adapter->curbssparams.ssid, - sizeof(struct WLAN_802_11_SSID)); - - /* Exit Adhoc mode */ - lbs_pr_debug(1, "In changeadhocchannel(): Sending Adhoc Stop\n"); - ret = libertas_stop_adhoc_network(priv); - - if (ret) { - LEAVE(); - return ret; - } - /* Scan for the network, do not save previous results. Stale - * scan data will cause us to join a non-existant adhoc network - */ - libertas_send_specific_SSID_scan(priv, &curadhocssid, 0); - - // find out the BSSID that matches the current SSID - i = libertas_find_SSID_in_list(adapter, &curadhocssid, NULL, - IW_MODE_ADHOC); - - if (i >= 0) { - lbs_pr_debug(1, "SSID found at %d in List," - "so join\n", i); - libertas_join_adhoc_network(priv, &adapter->scantable[i]); - } else { - // else send START command - lbs_pr_debug(1, "SSID not found in list, " - "so creating adhoc with ssid = %s\n", - curadhocssid.ssid); - libertas_start_adhoc_network(priv, &curadhocssid); - } // end of else (START command) - } - - LEAVE(); - return 0; -} /** * @brief Set Radio On/OFF @@ -263,10 +170,10 @@ int wlan_radio_ioctl(wlan_private * priv, u8 option) int ret = 0; wlan_adapter *adapter = priv->adapter; - ENTER(); + lbs_deb_enter(LBS_DEB_WEXT); if (adapter->radioon != option) { - lbs_pr_debug(1, "Switching %s the Radio\n", option ? "On" : "Off"); + lbs_deb_wext("switching radio %s\n", option ? "on" : "off"); adapter->radioon = option; ret = libertas_prepare_and_send_command(priv, @@ -275,7 +182,7 @@ int wlan_radio_ioctl(wlan_private * priv, u8 option) cmd_option_waitforrsp, 0, NULL); } - LEAVE(); + lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); return ret; } @@ -312,15 +219,15 @@ static int get_active_data_rates(wlan_adapter * adapter, { int k = 0; - ENTER(); + lbs_deb_enter(LBS_DEB_WEXT); if (adapter->connect_status != libertas_connected) { if (adapter->mode == IW_MODE_INFRA) { - lbs_pr_debug(1, "Infra\n"); + lbs_deb_wext("infra\n"); k = copyrates(rates, k, libertas_supported_rates, sizeof(libertas_supported_rates)); } else { - lbs_pr_debug(1, "Adhoc G\n"); + lbs_deb_wext("Adhoc G\n"); k = copyrates(rates, k, libertas_adhoc_rates_g, sizeof(libertas_adhoc_rates_g)); } @@ -329,8 +236,7 @@ static int get_active_data_rates(wlan_adapter * adapter, adapter->curbssparams.numofrates); } - LEAVE(); - + lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", k); return k; } @@ -342,7 +248,7 @@ static int wlan_get_name(struct net_device *dev, struct iw_request_info *info, char mrvl[6] = { "MRVL-" }; int cnt; - ENTER(); + lbs_deb_enter(LBS_DEB_WEXT); strcpy(cwrq, mrvl); @@ -360,8 +266,7 @@ static int wlan_get_name(struct net_device *dev, struct iw_request_info *info, } *cwrq = '\0'; - LEAVE(); - + lbs_deb_leave(LBS_DEB_WEXT); return 0; } @@ -372,14 +277,14 @@ static int wlan_get_freq(struct net_device *dev, struct iw_request_info *info, wlan_adapter *adapter = priv->adapter; struct chan_freq_power *cfp; - ENTER(); + lbs_deb_enter(LBS_DEB_WEXT); cfp = libertas_find_cfp_by_band_and_channel(adapter, 0, adapter->curbssparams.channel); if (!cfp) { if (adapter->curbssparams.channel) - lbs_pr_debug(1, "Invalid channel=%d\n", + lbs_deb_wext("invalid channel %d\n", adapter->curbssparams.channel); return -EINVAL; } @@ -387,9 +292,8 @@ static int wlan_get_freq(struct net_device *dev, struct iw_request_info *info, fwrq->m = (long)cfp->freq * 100000; fwrq->e = 1; - lbs_pr_debug(1, "freq=%u\n", fwrq->m); - - LEAVE(); + lbs_deb_wext("freq %u\n", fwrq->m); + lbs_deb_leave(LBS_DEB_WEXT); return 0; } @@ -399,7 +303,7 @@ static int wlan_get_wap(struct net_device *dev, struct iw_request_info *info, wlan_private *priv = dev->priv; wlan_adapter *adapter = priv->adapter; - ENTER(); + lbs_deb_enter(LBS_DEB_WEXT); if (adapter->connect_status == libertas_connected) { memcpy(awrq->sa_data, adapter->curbssparams.bssid, ETH_ALEN); @@ -408,7 +312,7 @@ static int wlan_get_wap(struct net_device *dev, struct iw_request_info *info, } awrq->sa_family = ARPHRD_ETHER; - LEAVE(); + lbs_deb_leave(LBS_DEB_WEXT); return 0; } @@ -418,7 +322,7 @@ static int wlan_set_nick(struct net_device *dev, struct iw_request_info *info, wlan_private *priv = dev->priv; wlan_adapter *adapter = priv->adapter; - ENTER(); + lbs_deb_enter(LBS_DEB_WEXT); /* * Check the size of the string @@ -433,7 +337,7 @@ static int wlan_set_nick(struct net_device *dev, struct iw_request_info *info, memcpy(adapter->nodename, extra, dwrq->length); mutex_unlock(&adapter->lock); - LEAVE(); + lbs_deb_leave(LBS_DEB_WEXT); return 0; } @@ -443,7 +347,7 @@ static int wlan_get_nick(struct net_device *dev, struct iw_request_info *info, wlan_private *priv = dev->priv; wlan_adapter *adapter = priv->adapter; - ENTER(); + lbs_deb_enter(LBS_DEB_WEXT); /* * Get the Nick Name saved @@ -464,19 +368,43 @@ static int wlan_get_nick(struct net_device *dev, struct iw_request_info *info, */ dwrq->length = strlen(extra) + 1; - LEAVE(); + lbs_deb_leave(LBS_DEB_WEXT); return 0; } +static int mesh_get_nick(struct net_device *dev, struct iw_request_info *info, + struct iw_point *dwrq, char *extra) +{ + wlan_private *priv = dev->priv; + wlan_adapter *adapter = priv->adapter; + + lbs_deb_enter(LBS_DEB_WEXT); + + /* Use nickname to indicate that mesh is on */ + + if (adapter->connect_status == libertas_connected) { + strncpy(extra, "Mesh", 12); + extra[12] = '\0'; + dwrq->length = strlen(extra) + 1; + } + + else { + extra[0] = '\0'; + dwrq->length = 1 ; + } + + lbs_deb_leave(LBS_DEB_WEXT); + return 0; +} static int wlan_set_rts(struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra) { int ret = 0; wlan_private *priv = dev->priv; wlan_adapter *adapter = priv->adapter; - int rthr = vwrq->value; + u32 rthr = vwrq->value; - ENTER(); + lbs_deb_enter(LBS_DEB_WEXT); if (vwrq->disabled) { adapter->rtsthsd = rthr = MRVDRV_RTS_MAX_VALUE; @@ -490,7 +418,7 @@ static int wlan_set_rts(struct net_device *dev, struct iw_request_info *info, cmd_act_set, cmd_option_waitforrsp, OID_802_11_RTS_THRESHOLD, &rthr); - LEAVE(); + lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); return ret; } @@ -501,35 +429,34 @@ static int wlan_get_rts(struct net_device *dev, struct iw_request_info *info, wlan_private *priv = dev->priv; wlan_adapter *adapter = priv->adapter; - ENTER(); + lbs_deb_enter(LBS_DEB_WEXT); adapter->rtsthsd = 0; ret = libertas_prepare_and_send_command(priv, cmd_802_11_snmp_mib, cmd_act_get, cmd_option_waitforrsp, OID_802_11_RTS_THRESHOLD, NULL); - if (ret) { - LEAVE(); - return ret; - } + if (ret) + goto out; vwrq->value = adapter->rtsthsd; vwrq->disabled = ((vwrq->value < MRVDRV_RTS_MIN_VALUE) || (vwrq->value > MRVDRV_RTS_MAX_VALUE)); vwrq->fixed = 1; - LEAVE(); - return 0; +out: + lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); + return ret; } static int wlan_set_frag(struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra) { int ret = 0; - int fthr = vwrq->value; + u32 fthr = vwrq->value; wlan_private *priv = dev->priv; wlan_adapter *adapter = priv->adapter; - ENTER(); + lbs_deb_enter(LBS_DEB_WEXT); if (vwrq->disabled) { adapter->fragthsd = fthr = MRVDRV_FRAG_MAX_VALUE; @@ -543,7 +470,8 @@ static int wlan_set_frag(struct net_device *dev, struct iw_request_info *info, ret = libertas_prepare_and_send_command(priv, cmd_802_11_snmp_mib, cmd_act_set, cmd_option_waitforrsp, OID_802_11_FRAGMENTATION_THRESHOLD, &fthr); - LEAVE(); + + lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); return ret; } @@ -554,24 +482,23 @@ static int wlan_get_frag(struct net_device *dev, struct iw_request_info *info, wlan_private *priv = dev->priv; wlan_adapter *adapter = priv->adapter; - ENTER(); + lbs_deb_enter(LBS_DEB_WEXT); adapter->fragthsd = 0; ret = libertas_prepare_and_send_command(priv, cmd_802_11_snmp_mib, cmd_act_get, cmd_option_waitforrsp, OID_802_11_FRAGMENTATION_THRESHOLD, NULL); - if (ret) { - LEAVE(); - return ret; - } + if (ret) + goto out; vwrq->value = adapter->fragthsd; vwrq->disabled = ((vwrq->value < MRVDRV_FRAG_MIN_VALUE) || (vwrq->value > MRVDRV_FRAG_MAX_VALUE)); vwrq->fixed = 1; - LEAVE(); +out: + lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); return ret; } @@ -581,11 +508,23 @@ static int wlan_get_mode(struct net_device *dev, wlan_private *priv = dev->priv; wlan_adapter *adapter = priv->adapter; - ENTER(); + lbs_deb_enter(LBS_DEB_WEXT); *uwrq = adapter->mode; - LEAVE(); + lbs_deb_leave(LBS_DEB_WEXT); + return 0; +} + +static int mesh_wlan_get_mode(struct net_device *dev, + struct iw_request_info *info, u32 * uwrq, + char *extra) +{ + lbs_deb_enter(LBS_DEB_WEXT); + + *uwrq = IW_MODE_REPEAT ; + + lbs_deb_leave(LBS_DEB_WEXT); return 0; } @@ -597,19 +536,17 @@ static int wlan_get_txpow(struct net_device *dev, wlan_private *priv = dev->priv; wlan_adapter *adapter = priv->adapter; - ENTER(); + lbs_deb_enter(LBS_DEB_WEXT); ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_tx_power, cmd_act_tx_power_opt_get, cmd_option_waitforrsp, 0, NULL); - if (ret) { - LEAVE(); - return ret; - } + if (ret) + goto out; - lbs_pr_debug(1, "TXPOWER GET %d dbm.\n", adapter->txpowerlevel); + lbs_deb_wext("tx power level %d dbm\n", adapter->txpowerlevel); vwrq->value = adapter->txpowerlevel; vwrq->fixed = 1; if (adapter->radioon) { @@ -619,8 +556,9 @@ static int wlan_get_txpow(struct net_device *dev, vwrq->disabled = 1; } - LEAVE(); - return 0; +out: + lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); + return ret; } static int wlan_set_retry(struct net_device *dev, struct iw_request_info *info, @@ -630,7 +568,7 @@ static int wlan_set_retry(struct net_device *dev, struct iw_request_info *info, wlan_private *priv = dev->priv; wlan_adapter *adapter = priv->adapter; - ENTER(); + lbs_deb_enter(LBS_DEB_WEXT); if (vwrq->flags == IW_RETRY_LIMIT) { /* The MAC has a 4-bit Total_Tx_Count register @@ -648,16 +586,15 @@ static int wlan_set_retry(struct net_device *dev, struct iw_request_info *info, cmd_option_waitforrsp, OID_802_11_TX_RETRYCOUNT, NULL); - if (ret) { - LEAVE(); - return ret; - } + if (ret) + goto out; } else { return -EOPNOTSUPP; } - LEAVE(); - return 0; +out: + lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); + return ret; } static int wlan_get_retry(struct net_device *dev, struct iw_request_info *info, @@ -667,16 +604,16 @@ static int wlan_get_retry(struct net_device *dev, struct iw_request_info *info, wlan_adapter *adapter = priv->adapter; int ret = 0; - ENTER(); + lbs_deb_enter(LBS_DEB_WEXT); + adapter->txretrycount = 0; ret = libertas_prepare_and_send_command(priv, cmd_802_11_snmp_mib, cmd_act_get, cmd_option_waitforrsp, OID_802_11_TX_RETRYCOUNT, NULL); - if (ret) { - LEAVE(); - return ret; - } + if (ret) + goto out; + vwrq->disabled = 0; if (!vwrq->flags) { vwrq->flags = IW_RETRY_LIMIT; @@ -684,8 +621,9 @@ static int wlan_get_retry(struct net_device *dev, struct iw_request_info *info, vwrq->value = adapter->txretrycount - 1; } - LEAVE(); - return 0; +out: + lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); + return ret; } static inline void sort_channels(struct iw_freq *freq, int num) @@ -739,7 +677,7 @@ static int wlan_get_range(struct net_device *dev, struct iw_request_info *info, u8 flag = 0; - ENTER(); + lbs_deb_enter(LBS_DEB_WEXT); dwrq->length = sizeof(struct iw_range); memset(range, 0, sizeof(struct iw_range)); @@ -755,7 +693,7 @@ static int wlan_get_range(struct net_device *dev, struct iw_request_info *info, range->bitrate[i] = (rates[i] & 0x7f) * 500000; } range->num_bitrates = i; - lbs_pr_debug(1, "IW_MAX_BITRATES=%d num_bitrates=%d\n", IW_MAX_BITRATES, + lbs_deb_wext("IW_MAX_BITRATES %d, num_bitrates %d\n", IW_MAX_BITRATES, range->num_bitrates); range->num_frequency = 0; @@ -768,18 +706,17 @@ static int wlan_get_range(struct net_device *dev, struct iw_request_info *info, &adapter->parsed_region_chan; if (parsed_region_chan == NULL) { - lbs_pr_debug(1, "11D:parsed_region_chan is NULL\n"); - LEAVE(); - return 0; + lbs_deb_wext("11d: parsed_region_chan is NULL\n"); + goto out; } band = parsed_region_chan->band; - lbs_pr_debug(1, "band=%d NoOfChan=%d\n", band, + lbs_deb_wext("band %d, nr_char %d\n", band, parsed_region_chan->nr_chan); for (i = 0; (range->num_frequency < IW_MAX_FREQUENCIES) && (i < parsed_region_chan->nr_chan); i++) { chan_no = parsed_region_chan->chanpwr[i].chan; - lbs_pr_debug(1, "chan_no=%d\n", chan_no); + lbs_deb_wext("chan_no %d\n", chan_no); range->freq[range->num_frequency].i = (long)chan_no; range->freq[range->num_frequency].m = (long)libertas_chan_2_freq(chan_no, band) * 100000; @@ -808,7 +745,7 @@ static int wlan_get_range(struct net_device *dev, struct iw_request_info *info, } } - lbs_pr_debug(1, "IW_MAX_FREQUENCIES=%d num_frequency=%d\n", + lbs_deb_wext("IW_MAX_FREQUENCIES %d, num_frequency %d\n", IW_MAX_FREQUENCIES, range->num_frequency); range->num_channels = range->num_frequency; @@ -903,7 +840,8 @@ static int wlan_get_range(struct net_device *dev, struct iw_request_info *info, | IW_ENC_CAPA_CIPHER_CCMP; } - LEAVE(); +out: + lbs_deb_leave(LBS_DEB_WEXT); return 0; } @@ -913,7 +851,7 @@ static int wlan_set_power(struct net_device *dev, struct iw_request_info *info, wlan_private *priv = dev->priv; wlan_adapter *adapter = priv->adapter; - ENTER(); + lbs_deb_enter(LBS_DEB_WEXT); /* PS is currently supported only in Infrastructure mode * Remove this check if it is to be supported in IBSS mode also @@ -929,11 +867,11 @@ static int wlan_set_power(struct net_device *dev, struct iw_request_info *info, } if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { - lbs_pr_debug(1, - "Setting power timeout command is not supported\n"); + lbs_deb_wext( + "setting power timeout is not supported\n"); return -EINVAL; } else if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) { - lbs_pr_debug(1, "Setting power period command is not supported\n"); + lbs_deb_wext("setting power period not supported\n"); return -EINVAL; } @@ -947,7 +885,7 @@ static int wlan_set_power(struct net_device *dev, struct iw_request_info *info, libertas_ps_sleep(priv, cmd_option_waitforrsp); } - LEAVE(); + lbs_deb_leave(LBS_DEB_WEXT); return 0; } @@ -958,154 +896,23 @@ static int wlan_get_power(struct net_device *dev, struct iw_request_info *info, wlan_adapter *adapter = priv->adapter; int mode; - ENTER(); + lbs_deb_enter(LBS_DEB_WEXT); mode = adapter->psmode; if ((vwrq->disabled = (mode == wlan802_11powermodecam)) - || adapter->connect_status == libertas_disconnected) { - LEAVE(); - return 0; + || adapter->connect_status == libertas_disconnected) + { + goto out; } vwrq->value = 0; - LEAVE(); +out: + lbs_deb_leave(LBS_DEB_WEXT); 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"}, - /* 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 { @@ -1125,7 +932,7 @@ static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev) u8 rssi; u32 tx_retries; - ENTER(); + lbs_deb_enter(LBS_DEB_WEXT); priv->wstats.status = adapter->mode; @@ -1145,8 +952,8 @@ static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev) CAL_NF(adapter->NF[TYPE_BEACON][TYPE_NOAVG]); } - lbs_pr_debug(1, "Signal Level = %#x\n", priv->wstats.qual.level); - lbs_pr_debug(1, "Noise = %#x\n", priv->wstats.qual.noise); + lbs_deb_wext("signal level %#x\n", priv->wstats.qual.level); + lbs_deb_wext("noise %#x\n", priv->wstats.qual.noise); rssi = priv->wstats.qual.level - priv->wstats.qual.noise; if (rssi < 15) @@ -1166,7 +973,7 @@ static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev) /* Quality by TX errors */ priv->wstats.discard.retries = priv->stats.tx_errors; - tx_retries = adapter->logmsg.retry; + tx_retries = le16_to_cpu(adapter->logmsg.retry); if (tx_retries > 75) tx_qual = (90 - tx_retries) * POOR / 15; @@ -1182,10 +989,10 @@ static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev) (PERFECT - VERY_GOOD) / 50 + VERY_GOOD; quality = min(quality, tx_qual); - priv->wstats.discard.code = adapter->logmsg.wepundecryptable; - priv->wstats.discard.fragment = adapter->logmsg.fcserror; + priv->wstats.discard.code = le16_to_cpu(adapter->logmsg.wepundecryptable); + priv->wstats.discard.fragment = le16_to_cpu(adapter->logmsg.rxfrag); priv->wstats.discard.retries = tx_retries; - priv->wstats.discard.misc = adapter->logmsg.ackfailure; + priv->wstats.discard.misc = le16_to_cpu(adapter->logmsg.ackfailure); /* Calculate quality */ priv->wstats.qual.qual = max(quality, (u32)100); @@ -1209,7 +1016,7 @@ out: IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID; } - LEAVE (); + lbs_deb_leave(LBS_DEB_WEXT); return &priv->wstats; @@ -1218,81 +1025,59 @@ out: static int wlan_set_freq(struct net_device *dev, struct iw_request_info *info, struct iw_freq *fwrq, char *extra) { - int ret = 0; + int ret = -EINVAL; wlan_private *priv = dev->priv; wlan_adapter *adapter = priv->adapter; - int rc = -EINPROGRESS; /* Call commit handler */ struct chan_freq_power *cfp; + struct assoc_request * assoc_req; - ENTER(); + lbs_deb_enter(LBS_DEB_WEXT); - /* - * If setting by frequency, convert to a channel - */ - if (fwrq->e == 1) { + mutex_lock(&adapter->lock); + assoc_req = wlan_get_association_request(adapter); + if (!assoc_req) { + ret = -ENOMEM; + goto out; + } + /* If setting by frequency, convert to a channel */ + if (fwrq->e == 1) { long f = fwrq->m / 100000; - int c = 0; cfp = find_cfp_by_band_and_freq(adapter, 0, f); if (!cfp) { - lbs_pr_debug(1, "Invalid freq=%ld\n", f); - return -EINVAL; + lbs_deb_wext("invalid freq %ld\n", f); + goto out; } - c = (int)cfp->channel; - - if (c < 0) - return -EINVAL; - fwrq->e = 0; - fwrq->m = c; + fwrq->m = (int) cfp->channel; } - /* - * Setting by channel number - */ + /* Setting by channel number */ if (fwrq->m > 1000 || fwrq->e > 0) { - rc = -EOPNOTSUPP; - } else { - int channel = fwrq->m; + goto out; + } - cfp = libertas_find_cfp_by_band_and_channel(adapter, 0, channel); - if (!cfp) { - rc = -EINVAL; - } else { - if (adapter->mode == IW_MODE_ADHOC) { - rc = changeadhocchannel(priv, channel); - /* If station is WEP enabled, send the - * command to set WEP in firmware - */ - if (adapter->secinfo.wep_enabled) { - lbs_pr_debug(1, "set_freq: WEP enabled\n"); - ret = libertas_prepare_and_send_command(priv, - cmd_802_11_set_wep, - cmd_act_add, - cmd_option_waitforrsp, - 0, - NULL); - - if (ret) { - LEAVE(); - return ret; - } - - adapter->currentpacketfilter |= - cmd_act_mac_wep_enable; - - libertas_set_mac_packet_filter(priv); - } - } else { - rc = -EOPNOTSUPP; - } - } + cfp = libertas_find_cfp_by_band_and_channel(adapter, 0, fwrq->m); + if (!cfp) { + goto out; } - LEAVE(); - return rc; + assoc_req->channel = fwrq->m; + ret = 0; + +out: + if (ret == 0) { + set_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags); + wlan_postpone_association_work(priv); + } else { + wlan_cancel_association_work(priv); + } + mutex_unlock(&adapter->lock); + + lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); + return ret; } /** @@ -1338,9 +1123,9 @@ static int wlan_set_rate(struct net_device *dev, struct iw_request_info *info, u8 rates[WLAN_SUPPORTED_RATES]; u8 *rate; - ENTER(); + lbs_deb_enter(LBS_DEB_WEXT); - lbs_pr_debug(1, "Vwrq->value = %d\n", vwrq->value); + lbs_deb_wext("vwrq->value %d\n", vwrq->value); if (vwrq->value == -1) { action = cmd_act_set_tx_auto; // Auto @@ -1357,15 +1142,15 @@ static int wlan_set_rate(struct net_device *dev, struct iw_request_info *info, get_active_data_rates(adapter, rates); rate = rates; while (*rate) { - lbs_pr_debug(1, "Rate=0x%X Wanted=0x%X\n", *rate, + lbs_deb_wext("rate=0x%X, wanted data_rate 0x%X\n", *rate, data_rate); if ((*rate & 0x7f) == (data_rate & 0x7f)) break; rate++; } if (!*rate) { - lbs_pr_alert( "The fixed data rate 0x%X is out " - "of range.\n", data_rate); + lbs_pr_alert("fixed data rate 0x%X out " + "of range\n", data_rate); return -EINVAL; } @@ -1377,7 +1162,7 @@ static int wlan_set_rate(struct net_device *dev, struct iw_request_info *info, ret = libertas_prepare_and_send_command(priv, cmd_802_11_data_rate, action, cmd_option_waitforrsp, 0, NULL); - LEAVE(); + lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); return ret; } @@ -1387,7 +1172,7 @@ static int wlan_get_rate(struct net_device *dev, struct iw_request_info *info, wlan_private *priv = dev->priv; wlan_adapter *adapter = priv->adapter; - ENTER(); + lbs_deb_enter(LBS_DEB_WEXT); if (adapter->is_datarate_auto) { vwrq->fixed = 0; @@ -1397,7 +1182,7 @@ static int wlan_get_rate(struct net_device *dev, struct iw_request_info *info, vwrq->value = adapter->datarate * 500000; - LEAVE(); + lbs_deb_leave(LBS_DEB_WEXT); return 0; } @@ -1409,12 +1194,12 @@ static int wlan_set_mode(struct net_device *dev, wlan_adapter *adapter = priv->adapter; struct assoc_request * assoc_req; - ENTER(); + lbs_deb_enter(LBS_DEB_WEXT); if ( (*uwrq != IW_MODE_ADHOC) && (*uwrq != IW_MODE_INFRA) && (*uwrq != IW_MODE_AUTO)) { - lbs_pr_debug(1, "Invalid mode: 0x%x\n", *uwrq); + lbs_deb_wext("Invalid mode: 0x%x\n", *uwrq); ret = -EINVAL; goto out; } @@ -1428,12 +1213,12 @@ static int wlan_set_mode(struct net_device *dev, assoc_req->mode = *uwrq; set_bit(ASSOC_FLAG_MODE, &assoc_req->flags); wlan_postpone_association_work(priv); - lbs_pr_debug(1, "Switching to mode: 0x%x\n", *uwrq); + lbs_deb_wext("Switching to mode: 0x%x\n", *uwrq); } mutex_unlock(&adapter->lock); out: - LEAVE(); + lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); return ret; } @@ -1455,9 +1240,9 @@ static int wlan_get_encode(struct net_device *dev, wlan_adapter *adapter = priv->adapter; int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; - ENTER(); + lbs_deb_enter(LBS_DEB_WEXT); - lbs_pr_debug(1, "flags=0x%x index=%d length=%d wep_tx_keyidx=%d\n", + lbs_deb_wext("flags 0x%x, index %d, length %d, wep_tx_keyidx %d\n", dwrq->flags, index, dwrq->length, adapter->wep_tx_keyidx); dwrq->flags = 0; @@ -1513,13 +1298,13 @@ static int wlan_get_encode(struct net_device *dev, dwrq->flags |= IW_ENCODE_NOKEY; - lbs_pr_debug(1, "key:%02x:%02x:%02x:%02x:%02x:%02x keylen=%d\n", + lbs_deb_wext("key: " MAC_FMT ", keylen %d\n", extra[0], extra[1], extra[2], extra[3], extra[4], extra[5], dwrq->length); - lbs_pr_debug(1, "Return flags=0x%x\n", dwrq->flags); + lbs_deb_wext("return flags 0x%x\n", dwrq->flags); - LEAVE(); + lbs_deb_leave(LBS_DEB_WEXT); return 0; } @@ -1539,20 +1324,21 @@ static int wlan_set_wep_key(struct assoc_request *assoc_req, u16 index, int set_tx_key) { + int ret = 0; struct WLAN_802_11_KEY *pkey; - ENTER(); + lbs_deb_enter(LBS_DEB_WEXT); /* Paranoid validation of key index */ if (index > 3) { - LEAVE(); - return -EINVAL; + ret = -EINVAL; + goto out; } /* validate max key length */ if (key_length > KEY_LEN_WEP_104) { - LEAVE(); - return -EINVAL; + ret = -EINVAL; + goto out; } pkey = &assoc_req->wep_keys[index]; @@ -1570,17 +1356,18 @@ static int wlan_set_wep_key(struct assoc_request *assoc_req, if (set_tx_key) { /* Ensure the chosen key is valid */ if (!pkey->len) { - lbs_pr_debug(1, "key not set, so cannot enable it\n"); - LEAVE(); - return -EINVAL; + lbs_deb_wext("key not set, so cannot enable it\n"); + ret = -EINVAL; + goto out; } assoc_req->wep_tx_keyidx = index; } assoc_req->secinfo.wep_enabled = 1; - LEAVE(); - return 0; +out: + lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); + return ret; } static int validate_key_index(u16 def_index, u16 raw_index, @@ -1605,6 +1392,8 @@ static void disable_wep(struct assoc_request *assoc_req) { int i; + lbs_deb_enter(LBS_DEB_WEXT); + /* Set Open System auth mode */ assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; @@ -1615,6 +1404,27 @@ static void disable_wep(struct assoc_request *assoc_req) set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags); set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags); + + lbs_deb_leave(LBS_DEB_WEXT); +} + +static void disable_wpa(struct assoc_request *assoc_req) +{ + lbs_deb_enter(LBS_DEB_WEXT); + + memset(&assoc_req->wpa_mcast_key, 0, sizeof (struct WLAN_802_11_KEY)); + assoc_req->wpa_mcast_key.flags = KEY_INFO_WPA_MCAST; + set_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags); + + memset(&assoc_req->wpa_unicast_key, 0, sizeof (struct WLAN_802_11_KEY)); + assoc_req->wpa_unicast_key.flags = KEY_INFO_WPA_UNICAST; + set_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags); + + assoc_req->secinfo.WPAenabled = 0; + assoc_req->secinfo.WPA2enabled = 0; + set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags); + + lbs_deb_leave(LBS_DEB_WEXT); } /** @@ -1636,7 +1446,7 @@ static int wlan_set_encode(struct net_device *dev, struct assoc_request * assoc_req; u16 is_default = 0, index = 0, set_tx_key = 0; - ENTER(); + lbs_deb_enter(LBS_DEB_WEXT); mutex_lock(&adapter->lock); assoc_req = wlan_get_association_request(adapter); @@ -1647,6 +1457,7 @@ static int wlan_set_encode(struct net_device *dev, if (dwrq->flags & IW_ENCODE_DISABLED) { disable_wep (assoc_req); + disable_wpa (assoc_req); goto out; } @@ -1688,7 +1499,7 @@ out: } mutex_unlock(&adapter->lock); - LEAVE(); + lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); return ret; } @@ -1712,7 +1523,7 @@ static int wlan_get_encodeext(struct net_device *dev, struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; int index, max_key_len; - ENTER(); + lbs_deb_enter(LBS_DEB_WEXT); max_key_len = dwrq->length - sizeof(*ext); if (max_key_len < 0) @@ -1748,6 +1559,7 @@ static int wlan_get_encodeext(struct net_device *dev, if ( adapter->secinfo.wep_enabled && !adapter->secinfo.WPAenabled && !adapter->secinfo.WPA2enabled) { + /* WEP */ ext->alg = IW_ENCODE_ALG_WEP; ext->key_len = adapter->wep_keys[index].len; key = &adapter->wep_keys[index].key[0]; @@ -1755,8 +1567,27 @@ static int wlan_get_encodeext(struct net_device *dev, && (adapter->secinfo.WPAenabled || adapter->secinfo.WPA2enabled)) { /* WPA */ - ext->alg = IW_ENCODE_ALG_TKIP; - ext->key_len = 0; + struct WLAN_802_11_KEY * pkey = NULL; + + if ( adapter->wpa_mcast_key.len + && (adapter->wpa_mcast_key.flags & KEY_INFO_WPA_ENABLED)) + pkey = &adapter->wpa_mcast_key; + else if ( adapter->wpa_unicast_key.len + && (adapter->wpa_unicast_key.flags & KEY_INFO_WPA_ENABLED)) + pkey = &adapter->wpa_unicast_key; + + if (pkey) { + if (pkey->type == KEY_TYPE_ID_AES) { + ext->alg = IW_ENCODE_ALG_CCMP; + } else { + ext->alg = IW_ENCODE_ALG_TKIP; + } + ext->key_len = pkey->len; + key = &pkey->key[0]; + } else { + ext->alg = IW_ENCODE_ALG_TKIP; + ext->key_len = 0; + } } else { goto out; } @@ -1775,7 +1606,7 @@ static int wlan_get_encodeext(struct net_device *dev, ret = 0; out: - LEAVE(); + lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); return ret; } @@ -1800,7 +1631,7 @@ static int wlan_set_encodeext(struct net_device *dev, int alg = ext->alg; struct assoc_request * assoc_req; - ENTER(); + lbs_deb_enter(LBS_DEB_WEXT); mutex_lock(&adapter->lock); assoc_req = wlan_get_association_request(adapter); @@ -1811,6 +1642,7 @@ static int wlan_set_encodeext(struct net_device *dev, if ((alg == IW_ENCODE_ALG_NONE) || (dwrq->flags & IW_ENCODE_DISABLED)) { disable_wep (assoc_req); + disable_wpa (assoc_req); } else if (alg == IW_ENCODE_ALG_WEP) { u16 is_default = 0, index, set_tx_key = 0; @@ -1846,7 +1678,6 @@ static int wlan_set_encodeext(struct net_device *dev, set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags); if (set_tx_key) set_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags); - } else if ((alg == IW_ENCODE_ALG_TKIP) || (alg == IW_ENCODE_ALG_CCMP)) { struct WLAN_802_11_KEY * pkey; @@ -1855,36 +1686,43 @@ static int wlan_set_encodeext(struct net_device *dev, && (ext->key_len != KEY_LEN_WPA_TKIP)) || ((alg == IW_ENCODE_ALG_CCMP) && (ext->key_len != KEY_LEN_WPA_AES))) { - lbs_pr_debug(1, "Invalid size %d for key of alg" - "type %d.\n", + lbs_deb_wext("invalid size %d for key of alg" + "type %d\n", ext->key_len, alg); ret = -EINVAL; goto out; } - if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) + if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { pkey = &assoc_req->wpa_mcast_key; - else + set_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags); + } else { pkey = &assoc_req->wpa_unicast_key; + set_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags); + } memset(pkey, 0, sizeof (struct WLAN_802_11_KEY)); memcpy(pkey->key, ext->key, ext->key_len); pkey->len = ext->key_len; - pkey->flags = KEY_INFO_WPA_ENABLED; + if (pkey->len) + pkey->flags |= KEY_INFO_WPA_ENABLED; + /* Do this after zeroing key structure */ if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { pkey->flags |= KEY_INFO_WPA_MCAST; - set_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags); } else { pkey->flags |= KEY_INFO_WPA_UNICAST; - set_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags); } - if (alg == IW_ENCODE_ALG_TKIP) + if (alg == IW_ENCODE_ALG_TKIP) { pkey->type = KEY_TYPE_ID_TKIP; - else if (alg == IW_ENCODE_ALG_CCMP) + } else if (alg == IW_ENCODE_ALG_CCMP) { pkey->type = KEY_TYPE_ID_AES; + } else { + ret = -EINVAL; + goto out; + } /* If WPA isn't enabled yet, do that now */ if ( assoc_req->secinfo.WPAenabled == 0 @@ -1905,7 +1743,7 @@ out: } mutex_unlock(&adapter->lock); - LEAVE(); + lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); return ret; } @@ -1920,7 +1758,7 @@ static int wlan_set_genie(struct net_device *dev, int ret = 0; struct assoc_request * assoc_req; - ENTER(); + lbs_deb_enter(LBS_DEB_WEXT); mutex_lock(&adapter->lock); assoc_req = wlan_get_association_request(adapter); @@ -1952,7 +1790,7 @@ out: } mutex_unlock(&adapter->lock); - LEAVE(); + lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); return ret; } @@ -1961,27 +1799,28 @@ static int wlan_get_genie(struct net_device *dev, struct iw_point *dwrq, char *extra) { + int ret = 0; wlan_private *priv = dev->priv; wlan_adapter *adapter = priv->adapter; - ENTER(); + lbs_deb_enter(LBS_DEB_WEXT); if (adapter->wpa_ie_len == 0) { dwrq->length = 0; - LEAVE(); - return 0; + goto out; } if (dwrq->length < adapter->wpa_ie_len) { - LEAVE(); - return -E2BIG; + ret = -E2BIG; + goto out; } dwrq->length = adapter->wpa_ie_len; memcpy(extra, &adapter->wpa_ie[0], adapter->wpa_ie_len); - LEAVE(); - return 0; +out: + lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); + return ret; } @@ -1996,7 +1835,7 @@ static int wlan_set_auth(struct net_device *dev, int ret = 0; int updated = 0; - ENTER(); + lbs_deb_enter(LBS_DEB_WEXT); mutex_lock(&adapter->lock); assoc_req = wlan_get_association_request(adapter); @@ -2010,6 +1849,7 @@ static int wlan_set_auth(struct net_device *dev, case IW_AUTH_CIPHER_PAIRWISE: case IW_AUTH_CIPHER_GROUP: case IW_AUTH_KEY_MGMT: + case IW_AUTH_DROP_UNENCRYPTED: /* * libertas does not use these parameters */ @@ -2019,6 +1859,7 @@ static int wlan_set_auth(struct net_device *dev, if (dwrq->value & IW_AUTH_WPA_VERSION_DISABLED) { assoc_req->secinfo.WPAenabled = 0; assoc_req->secinfo.WPA2enabled = 0; + disable_wpa (assoc_req); } if (dwrq->value & IW_AUTH_WPA_VERSION_WPA) { assoc_req->secinfo.WPAenabled = 1; @@ -2033,17 +1874,6 @@ static int wlan_set_auth(struct net_device *dev, updated = 1; break; - case IW_AUTH_DROP_UNENCRYPTED: - if (dwrq->value) { - adapter->currentpacketfilter |= - cmd_act_mac_strict_protection_enable; - } else { - adapter->currentpacketfilter &= - ~cmd_act_mac_strict_protection_enable; - } - updated = 1; - break; - case IW_AUTH_80211_AUTH_ALG: if (dwrq->value & IW_AUTH_ALG_SHARED_KEY) { assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY; @@ -2069,6 +1899,7 @@ static int wlan_set_auth(struct net_device *dev, } else { assoc_req->secinfo.WPAenabled = 0; assoc_req->secinfo.WPA2enabled = 0; + disable_wpa (assoc_req); } updated = 1; break; @@ -2088,7 +1919,7 @@ out: } mutex_unlock(&adapter->lock); - LEAVE(); + lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); return ret; } @@ -2097,10 +1928,11 @@ static int wlan_get_auth(struct net_device *dev, struct iw_param *dwrq, char *extra) { + int ret = 0; wlan_private *priv = dev->priv; wlan_adapter *adapter = priv->adapter; - ENTER(); + lbs_deb_enter(LBS_DEB_WEXT); switch (dwrq->flags & IW_AUTH_INDEX) { case IW_AUTH_WPA_VERSION: @@ -2113,13 +1945,6 @@ static int wlan_get_auth(struct net_device *dev, dwrq->value |= IW_AUTH_WPA_VERSION_DISABLED; break; - case IW_AUTH_DROP_UNENCRYPTED: - dwrq->value = 0; - if (adapter->currentpacketfilter & - cmd_act_mac_strict_protection_enable) - dwrq->value = 1; - break; - case IW_AUTH_80211_AUTH_ALG: dwrq->value = adapter->secinfo.auth_mode; break; @@ -2130,12 +1955,11 @@ static int wlan_get_auth(struct net_device *dev, break; default: - LEAVE(); - return -EOPNOTSUPP; + ret = -EOPNOTSUPP; } - LEAVE(); - return 0; + lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); + return ret; } @@ -2148,7 +1972,7 @@ static int wlan_set_txpow(struct net_device *dev, struct iw_request_info *info, u16 dbm; - ENTER(); + lbs_deb_enter(LBS_DEB_WEXT); if (vwrq->disabled) { wlan_radio_ioctl(priv, RADIO_OFF); @@ -2169,14 +1993,14 @@ static int wlan_set_txpow(struct net_device *dev, struct iw_request_info *info, if (vwrq->fixed == 0) dbm = 0xffff; - lbs_pr_debug(1, "<1>TXPOWER SET %d dbm.\n", dbm); + lbs_deb_wext("txpower set %d dbm\n", dbm); ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_tx_power, cmd_act_tx_power_opt_set_low, cmd_option_waitforrsp, 0, (void *)&dbm); - LEAVE(); + lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); return ret; } @@ -2186,7 +2010,8 @@ static int wlan_get_essid(struct net_device *dev, struct iw_request_info *info, wlan_private *priv = dev->priv; wlan_adapter *adapter = priv->adapter; - ENTER(); + lbs_deb_enter(LBS_DEB_WEXT); + /* * Note : if dwrq->flags != 0, we should get the relevant SSID from * the SSID list... @@ -2196,12 +2021,12 @@ static int wlan_get_essid(struct net_device *dev, struct iw_request_info *info, * Get the current SSID */ if (adapter->connect_status == libertas_connected) { - memcpy(extra, adapter->curbssparams.ssid.ssid, - adapter->curbssparams.ssid.ssidlength); - extra[adapter->curbssparams.ssid.ssidlength] = '\0'; + memcpy(extra, adapter->curbssparams.ssid, + adapter->curbssparams.ssid_len); + extra[adapter->curbssparams.ssid_len] = '\0'; } else { memset(extra, 0, 32); - extra[adapter->curbssparams.ssid.ssidlength] = '\0'; + extra[adapter->curbssparams.ssid_len] = '\0'; } /* * If none, we may want to get the one that was set @@ -2209,14 +2034,14 @@ static int wlan_get_essid(struct net_device *dev, struct iw_request_info *info, /* To make the driver backward compatible with WPA supplicant v0.2.4 */ if (dwrq->length == 32) /* check with WPA supplicant buffer size */ - dwrq->length = min_t(size_t, adapter->curbssparams.ssid.ssidlength, + dwrq->length = min_t(size_t, adapter->curbssparams.ssid_len, IW_ESSID_MAX_SIZE); else - dwrq->length = adapter->curbssparams.ssid.ssidlength + 1; + dwrq->length = adapter->curbssparams.ssid_len + 1; dwrq->flags = 1; /* active */ - LEAVE(); + lbs_deb_leave(LBS_DEB_WEXT); return 0; } @@ -2226,38 +2051,43 @@ static int wlan_set_essid(struct net_device *dev, struct iw_request_info *info, wlan_private *priv = dev->priv; wlan_adapter *adapter = priv->adapter; int ret = 0; - struct WLAN_802_11_SSID ssid; + u8 ssid[IW_ESSID_MAX_SIZE]; + u8 ssid_len = 0; struct assoc_request * assoc_req; - int ssid_len = dwrq->length; + int in_ssid_len = dwrq->length; - ENTER(); + lbs_deb_enter(LBS_DEB_WEXT); /* * WE-20 and earlier NULL pad the end of the SSID and increment * SSID length so it can be used like a string. WE-21 and later don't, * but some userspace tools aren't able to cope with the change. */ - if ((ssid_len > 0) && (extra[ssid_len - 1] == '\0')) - ssid_len--; + if ((in_ssid_len > 0) && (extra[in_ssid_len - 1] == '\0')) + in_ssid_len--; /* Check the size of the string */ - if (ssid_len > IW_ESSID_MAX_SIZE) { + if (in_ssid_len > IW_ESSID_MAX_SIZE) { ret = -E2BIG; goto out; } - memset(&ssid, 0, sizeof(struct WLAN_802_11_SSID)); + memset(&ssid, 0, sizeof(ssid)); - if (!dwrq->flags || !ssid_len) { + if (!dwrq->flags || !in_ssid_len) { /* "any" SSID requested; leave SSID blank */ } else { /* Specific SSID requested */ - memcpy(&ssid.ssid, extra, ssid_len); - ssid.ssidlength = ssid_len; + memcpy(&ssid, extra, in_ssid_len); + ssid_len = in_ssid_len; } - lbs_pr_debug(1, "Requested new SSID = %s\n", - (ssid.ssidlength > 0) ? (char *)ssid.ssid : "any"); + if (!ssid_len) { + lbs_deb_wext("requested any SSID\n"); + } else { + lbs_deb_wext("requested SSID '%s'\n", + escape_essid(ssid, ssid_len)); + } out: mutex_lock(&adapter->lock); @@ -2268,7 +2098,8 @@ out: ret = -ENOMEM; } else { /* Copy the SSID to the association request */ - memcpy(&assoc_req->ssid, &ssid, sizeof(struct WLAN_802_11_SSID)); + memcpy(&assoc_req->ssid, &ssid, IW_ESSID_MAX_SIZE); + assoc_req->ssid_len = ssid_len; set_bit(ASSOC_FLAG_SSID, &assoc_req->flags); wlan_postpone_association_work(priv); } @@ -2281,7 +2112,7 @@ out: mutex_unlock(&adapter->lock); - LEAVE(); + lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); return ret; } @@ -2302,12 +2133,12 @@ static int wlan_set_wap(struct net_device *dev, struct iw_request_info *info, struct assoc_request * assoc_req; int ret = 0; - ENTER(); + lbs_deb_enter(LBS_DEB_WEXT); if (awrq->sa_family != ARPHRD_ETHER) return -EINVAL; - lbs_pr_debug(1, "ASSOC: WAP: sa_data: " MAC_FMT "\n", MAC_ARG(awrq->sa_data)); + lbs_deb_wext("ASSOC: WAP: sa_data " MAC_FMT "\n", MAC_ARG(awrq->sa_data)); mutex_lock(&adapter->lock); @@ -2330,22 +2161,23 @@ static int wlan_set_wap(struct net_device *dev, struct iw_request_info *info, void libertas_get_fwversion(wlan_adapter * adapter, char *fwversion, int maxlen) { - union { - u32 l; - u8 c[4]; - } ver; char fwver[32]; mutex_lock(&adapter->lock); - ver.l = adapter->fwreleasenumber; - mutex_unlock(&adapter->lock); - if (ver.c[3] == 0) - sprintf(fwver, "%u.%u.%u", ver.c[2], ver.c[1], ver.c[0]); + if (adapter->fwreleasenumber[3] == 0) + sprintf(fwver, "%u.%u.%u", + adapter->fwreleasenumber[2], + adapter->fwreleasenumber[1], + adapter->fwreleasenumber[0]); else sprintf(fwver, "%u.%u.%u.p%u", - ver.c[2], ver.c[1], ver.c[0], ver.c[3]); + adapter->fwreleasenumber[2], + adapter->fwreleasenumber[1], + adapter->fwreleasenumber[0], + adapter->fwreleasenumber[3]); + mutex_unlock(&adapter->lock); snprintf(fwversion, maxlen, fwver); } @@ -2411,13 +2243,71 @@ static const iw_handler wlan_handler[] = { (iw_handler) NULL, /* SIOCSIWPMKSA */ }; +static const iw_handler mesh_wlan_handler[] = { + (iw_handler) NULL, /* SIOCSIWCOMMIT */ + (iw_handler) wlan_get_name, /* SIOCGIWNAME */ + (iw_handler) NULL, /* SIOCSIWNWID */ + (iw_handler) NULL, /* SIOCGIWNWID */ + (iw_handler) wlan_set_freq, /* SIOCSIWFREQ */ + (iw_handler) wlan_get_freq, /* SIOCGIWFREQ */ + (iw_handler) NULL, /* SIOCSIWMODE */ + (iw_handler) mesh_wlan_get_mode, /* SIOCGIWMODE */ + (iw_handler) NULL, /* SIOCSIWSENS */ + (iw_handler) NULL, /* SIOCGIWSENS */ + (iw_handler) NULL, /* SIOCSIWRANGE */ + (iw_handler) wlan_get_range, /* SIOCGIWRANGE */ + (iw_handler) NULL, /* SIOCSIWPRIV */ + (iw_handler) NULL, /* SIOCGIWPRIV */ + (iw_handler) NULL, /* SIOCSIWSTATS */ + (iw_handler) NULL, /* SIOCGIWSTATS */ + iw_handler_set_spy, /* SIOCSIWSPY */ + iw_handler_get_spy, /* SIOCGIWSPY */ + iw_handler_set_thrspy, /* SIOCSIWTHRSPY */ + iw_handler_get_thrspy, /* SIOCGIWTHRSPY */ + (iw_handler) NULL, /* SIOCSIWAP */ + (iw_handler) NULL, /* SIOCGIWAP */ + (iw_handler) NULL, /* SIOCSIWMLME */ + (iw_handler) NULL, /* SIOCGIWAPLIST - deprecated */ + (iw_handler) libertas_set_scan, /* SIOCSIWSCAN */ + (iw_handler) libertas_get_scan, /* SIOCGIWSCAN */ + (iw_handler) NULL, /* SIOCSIWESSID */ + (iw_handler) NULL, /* SIOCGIWESSID */ + (iw_handler) NULL, /* SIOCSIWNICKN */ + (iw_handler) mesh_get_nick, /* SIOCGIWNICKN */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) wlan_set_rate, /* SIOCSIWRATE */ + (iw_handler) wlan_get_rate, /* SIOCGIWRATE */ + (iw_handler) wlan_set_rts, /* SIOCSIWRTS */ + (iw_handler) wlan_get_rts, /* SIOCGIWRTS */ + (iw_handler) wlan_set_frag, /* SIOCSIWFRAG */ + (iw_handler) wlan_get_frag, /* SIOCGIWFRAG */ + (iw_handler) wlan_set_txpow, /* SIOCSIWTXPOW */ + (iw_handler) wlan_get_txpow, /* SIOCGIWTXPOW */ + (iw_handler) wlan_set_retry, /* SIOCSIWRETRY */ + (iw_handler) wlan_get_retry, /* SIOCGIWRETRY */ + (iw_handler) wlan_set_encode, /* SIOCSIWENCODE */ + (iw_handler) wlan_get_encode, /* SIOCGIWENCODE */ + (iw_handler) wlan_set_power, /* SIOCSIWPOWER */ + (iw_handler) wlan_get_power, /* SIOCGIWPOWER */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) wlan_set_genie, /* SIOCSIWGENIE */ + (iw_handler) wlan_get_genie, /* SIOCGIWGENIE */ + (iw_handler) wlan_set_auth, /* SIOCSIWAUTH */ + (iw_handler) wlan_get_auth, /* SIOCGIWAUTH */ + (iw_handler) wlan_set_encodeext,/* SIOCSIWENCODEEXT */ + (iw_handler) wlan_get_encodeext,/* SIOCGIWENCODEEXT */ + (iw_handler) NULL, /* SIOCSIWPMKSA */ +}; 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), + .standard = (iw_handler *) mesh_wlan_handler, .get_wireless_stats = wlan_get_wireless_stats, }; diff --git a/drivers/net/wireless/libertas/wext.h b/drivers/net/wireless/libertas/wext.h index 15cfaaf0797..3d5196c9553 100644 --- a/drivers/net/wireless/libertas/wext.h +++ b/drivers/net/wireless/libertas/wext.h @@ -7,43 +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_SETONEINT_GETNONE (WLANIOCTL + 24) -#define WLANSETREGION 8 -#define WLAN_SUBCMD_MESH_SET_TTL 18 - -#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 */ @@ -55,8 +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; -int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int i); +extern struct iw_handler_def mesh_handler_def; int wlan_radio_ioctl(wlan_private * priv, u8 option); #endif /* _WLAN_WEXT_H_ */ |