diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-11 19:40:14 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-11 19:40:14 -0700 |
commit | 038a5008b2f395c85e6e71d6ddf3c684e7c405b0 (patch) | |
tree | 4735eab577e97e5a22c3141e3f60071c8065585e /drivers/net/wireless/libertas | |
parent | dd6d1844af33acb4edd0a40b1770d091a22c94be (diff) | |
parent | 266918303226cceac7eca38ced30f15f277bd89c (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (867 commits)
[SKY2]: status polling loop (post merge)
[NET]: Fix NAPI completion handling in some drivers.
[TCP]: Limit processing lost_retrans loop to work-to-do cases
[TCP]: Fix lost_retrans loop vs fastpath problems
[TCP]: No need to re-count fackets_out/sacked_out at RTO
[TCP]: Extract tcp_match_queue_to_sack from sacktag code
[TCP]: Kill almost unused variable pcount from sacktag
[TCP]: Fix mark_head_lost to ignore R-bit when trying to mark L
[TCP]: Add bytes_acked (ABC) clearing to FRTO too
[IPv6]: Update setsockopt(IPV6_MULTICAST_IF) to support RFC 3493, try2
[NETFILTER]: x_tables: add missing ip6t_modulename aliases
[NETFILTER]: nf_conntrack_tcp: fix connection reopening
[QETH]: fix qeth_main.c
[NETLINK]: fib_frontend build fixes
[IPv6]: Export userland ND options through netlink (RDNSS support)
[9P]: build fix with !CONFIG_SYSCTL
[NET]: Fix dev_put() and dev_hold() comments
[NET]: make netlink user -> kernel interface synchronious
[NET]: unify netlink kernel socket recognition
[NET]: cleanup 3rd argument in netlink_sendskb
...
Fix up conflicts manually in Documentation/feature-removal-schedule.txt
and my new least favourite crap, the "mod_devicetable" support in the
files include/linux/mod_devicetable.h and scripts/mod/file2alias.c.
(The latter files seem to be explicitly _designed_ to get conflicts when
different subsystems work with them - that have an absolutely horrid
lack of subsystem separation!)
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/net/wireless/libertas')
30 files changed, 3796 insertions, 3175 deletions
diff --git a/drivers/net/wireless/libertas/11d.c b/drivers/net/wireless/libertas/11d.c index 4cf0ff7b833..9cf0211de67 100644 --- a/drivers/net/wireless/libertas/11d.c +++ b/drivers/net/wireless/libertas/11d.c @@ -124,17 +124,17 @@ static u8 wlan_channel_known_11d(u8 chan, u8 nr_chan = parsed_region_chan->nr_chan; u8 i = 0; - lbs_dbg_hex("11D:parsed_region_chan:", (char *)chanpwr, + lbs_deb_hex(LBS_DEB_11D, "parsed_region_chan", (char *)chanpwr, sizeof(struct chan_power_11d) * nr_chan); for (i = 0; i < nr_chan; i++) { if (chan == chanpwr[i].chan) { - lbs_deb_11d("11D: Found Chan:%d\n", chan); + lbs_deb_11d("found chan %d\n", chan); return 1; } } - lbs_deb_11d("11D: Not Find Chan:%d\n", chan); + lbs_deb_11d("chan %d not found\n", chan); return 0; } @@ -174,8 +174,8 @@ static int generate_domain_info_11d(struct parsed_region_chan_11d memcpy(domaininfo->countrycode, parsed_region_chan->countrycode, COUNTRY_CODE_LEN); - lbs_deb_11d("11D:nrchan=%d\n", nr_chan); - lbs_dbg_hex("11D:parsed_region_chan:", (char *)parsed_region_chan, + lbs_deb_11d("nrchan %d\n", nr_chan); + lbs_deb_hex(LBS_DEB_11D, "parsed_region_chan", (char *)parsed_region_chan, sizeof(struct parsed_region_chan_11d)); for (i = 0; i < nr_chan; i++) { @@ -213,7 +213,7 @@ static int generate_domain_info_11d(struct parsed_region_chan_11d domaininfo->nr_subband = nr_subband; lbs_deb_11d("nr_subband=%x\n", domaininfo->nr_subband); - lbs_dbg_hex("11D:domaininfo:", (char *)domaininfo, + lbs_deb_hex(LBS_DEB_11D, "domaininfo", (char *)domaininfo, COUNTRY_CODE_LEN + 1 + sizeof(struct ieeetypes_subbandset) * nr_subband); return 0; @@ -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_deb_11d("11D: region_chan is NULL\n"); + lbs_deb_11d("region_chan is NULL\n"); return; } cfp = region_chan->CFP; if (cfp == NULL) { - lbs_deb_11d("11D: cfp equal NULL \n"); + lbs_deb_11d("cfp is 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_deb_11d("11D: region[0x%x] band[%d]\n", parsed_region_chan->region, + lbs_deb_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_deb_11d("11D: Chan[%d] Pwr[%d]\n", + lbs_deb_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_deb_11d("11D: nrchan[%d]\n", parsed_region_chan->nr_chan); + lbs_deb_11d("nrchan %d\n", parsed_region_chan->nr_chan); return; } @@ -336,7 +336,7 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset* 6. Others */ - lbs_dbg_hex("CountryInfo:", (u8 *) countryinfo, 30); + lbs_deb_hex(LBS_DEB_11D, "countryinfo", (u8 *) countryinfo, 30); if ((*(countryinfo->countrycode)) == 0 || (countryinfo->len <= COUNTRY_CODE_LEN)) { @@ -349,7 +349,7 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset* wlan_region_2_code(countryinfo->countrycode); lbs_deb_11d("regioncode=%x\n", (u8) parsed_region_chan->region); - lbs_dbg_hex("CountryCode:", (char *)countryinfo->countrycode, + lbs_deb_hex(LBS_DEB_11D, "countrycode", (char *)countryinfo->countrycode, COUNTRY_CODE_LEN); parsed_region_chan->band = band; @@ -364,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_deb_11d("11D: Chan[%d>%d] Overlap\n", + lbs_deb_11d("chan %d>%d, overlap\n", countryinfo->subband[j].firstchan, lastchan); continue; } @@ -393,7 +393,7 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset* } else { /*not supported and ignore the chan */ lbs_deb_11d( - "11D:i[%d] chan[%d] unsupported in region[%x] band[%d]\n", + "i %d, chan %d unsupported in region %x, band %d\n", i, curchan, region, band); } } @@ -405,7 +405,7 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset* parsed_region_chan->nr_chan = idx; lbs_deb_11d("nrchan=%x\n", parsed_region_chan->nr_chan); - lbs_dbg_hex("11D:parsed_region_chan:", (u8 *) parsed_region_chan, + lbs_deb_hex(LBS_DEB_11D, "parsed_region_chan", (u8 *) parsed_region_chan, 2 + COUNTRY_CODE_LEN + sizeof(struct parsed_region_chan_11d) * idx); done: @@ -422,15 +422,15 @@ done: u8 libertas_get_scan_type_11d(u8 chan, struct parsed_region_chan_11d * parsed_region_chan) { - u8 scan_type = cmd_scan_type_passive; + u8 scan_type = CMD_SCAN_TYPE_PASSIVE; lbs_deb_enter(LBS_DEB_11D); if (wlan_channel_known_11d(chan, parsed_region_chan)) { - lbs_deb_11d("11D: Found and do Active Scan\n"); - scan_type = cmd_scan_type_active; + lbs_deb_11d("found, do active scan\n"); + scan_type = CMD_SCAN_TYPE_ACTIVE; } else { - lbs_deb_11d("11D: Not Find and do Passive Scan\n"); + lbs_deb_11d("not found, do passive scan\n"); } lbs_deb_leave_args(LBS_DEB_11D, "ret scan_type %d", scan_type); @@ -446,25 +446,6 @@ void libertas_init_11d(wlan_private * priv) return; } -static int wlan_enable_11d(wlan_private * priv, u8 flag) -{ - int ret; - - priv->adapter->enable11d = flag; - - /* send cmd to FW to enable/disable 11D function in FW */ - ret = libertas_prepare_and_send_command(priv, - cmd_802_11_snmp_mib, - cmd_act_set, - cmd_option_waitforrsp, - OID_802_11D_ENABLE, - &priv->adapter->enable11d); - if (ret) - lbs_deb_11d("11D: Fail to enable 11D \n"); - - return 0; -} - /** * @brief This function sets DOMAIN INFO to FW * @param priv pointer to wlan_private @@ -475,15 +456,15 @@ static int set_domain_info_11d(wlan_private * priv) int ret; if (!priv->adapter->enable11d) { - lbs_deb_11d("11D: dnld domain Info with 11d disabled\n"); + lbs_deb_11d("dnld domain Info with 11d disabled\n"); return 0; } - ret = libertas_prepare_and_send_command(priv, cmd_802_11d_domain_info, - cmd_act_set, - cmd_option_waitforrsp, 0, NULL); + ret = libertas_prepare_and_send_command(priv, CMD_802_11D_DOMAIN_INFO, + CMD_ACT_SET, + CMD_OPTION_WAITFORRSP, 0, NULL); if (ret) - lbs_deb_11d("11D: Fail to dnld domain Info\n"); + lbs_deb_11d("fail to dnld domain info\n"); return ret; } @@ -505,7 +486,7 @@ int libertas_set_universaltable(wlan_private * priv, u8 band) adapter->universal_channel[i].nrcfp = sizeof(channel_freq_power_UN_BG) / size; - lbs_deb_11d("11D: BG-band nrcfp=%d\n", + lbs_deb_11d("BG-band nrcfp %d\n", adapter->universal_channel[i].nrcfp); adapter->universal_channel[i].CFP = channel_freq_power_UN_BG; @@ -541,10 +522,10 @@ int libertas_cmd_802_11d_domain_info(wlan_private * priv, cmd->command = cpu_to_le16(cmdno); pdomaininfo->action = cpu_to_le16(cmdoption); - if (cmdoption == cmd_act_get) { + if (cmdoption == CMD_ACT_GET) { cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) + S_DS_GEN); - lbs_dbg_hex("11D: 802_11D_DOMAIN_INFO:", (u8 *) cmd, + lbs_deb_hex(LBS_DEB_11D, "802_11D_DOMAIN_INFO", (u8 *) cmd, (int)(cmd->size)); goto done; } @@ -562,7 +543,7 @@ int libertas_cmd_802_11d_domain_info(wlan_private * priv, nr_subband * sizeof(struct ieeetypes_subbandset)); cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) + - domain->header.len + + le16_to_cpu(domain->header.len) + sizeof(struct mrvlietypesheader) + S_DS_GEN); } else { @@ -570,7 +551,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, le16_to_cpu(cmd->size)); + lbs_deb_hex(LBS_DEB_11D, "802_11D_DOMAIN_INFO", (u8 *) cmd, le16_to_cpu(cmd->size)); done: lbs_deb_enter(LBS_DEB_11D); @@ -578,31 +559,6 @@ done: } /** - * @brief This function implements private cmd: enable/disable 11D - * @param priv pointer to wlan_private - * @param wrq pointer to user data - * @return 0 or -1 - */ -int libertas_cmd_enable_11d(wlan_private * priv, struct iwreq *wrq) -{ - int data = 0; - int *val; - - lbs_deb_enter(LBS_DEB_11D); - data = SUBCMD_DATA(wrq); - - 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; - - lbs_deb_enter(LBS_DEB_11D); - return 0; -} - -/** * @brief This function parses countryinfo from AP and download country info to FW * @param priv pointer to wlan_private * @param resp pointer to command response buffer @@ -619,13 +575,13 @@ int libertas_ret_802_11d_domain_info(wlan_private * priv, lbs_deb_enter(LBS_DEB_11D); - lbs_dbg_hex("11D DOMAIN Info Rsp Data:", (u8 *) resp, + lbs_deb_hex(LBS_DEB_11D, "domain info resp", (u8 *) resp, (int)le16_to_cpu(resp->size)); nr_subband = (le16_to_cpu(domain->header.len) - COUNTRY_CODE_LEN) / sizeof(struct ieeetypes_subbandset); - lbs_deb_11d("11D Domain Info Resp: nr_subband=%d\n", nr_subband); + lbs_deb_11d("domain info resp: nr_subband %d\n", nr_subband); if (nr_subband > MRVDRV_MAX_SUBBAND_802_11D) { lbs_deb_11d("Invalid Numrer of Subband returned!!\n"); @@ -633,10 +589,10 @@ int libertas_ret_802_11d_domain_info(wlan_private * priv, } switch (action) { - case cmd_act_set: /*Proc Set action */ + case CMD_ACT_SET: /*Proc Set action */ break; - case cmd_act_get: + case CMD_ACT_GET: break; default: lbs_deb_11d("Invalid action:%d\n", domaininfo->action); @@ -667,7 +623,7 @@ int libertas_parse_dnld_countryinfo_11d(wlan_private * priv, &adapter->parsed_region_chan); if (ret == -1) { - lbs_deb_11d("11D: Err Parse domain_info from AP..\n"); + lbs_deb_11d("error parsing domain_info from AP\n"); goto done; } @@ -679,7 +635,7 @@ int libertas_parse_dnld_countryinfo_11d(wlan_private * priv, ret = set_domain_info_11d(priv); if (ret) { - lbs_deb_11d("11D: Err set domainInfo to FW\n"); + lbs_deb_11d("error setting domain info\n"); goto done; } } @@ -703,7 +659,7 @@ int libertas_create_dnld_countryinfo_11d(wlan_private * priv) u8 j; lbs_deb_enter(LBS_DEB_11D); - lbs_deb_11d("11D:curbssparams.band[%d]\n", adapter->curbssparams.band); + lbs_deb_11d("curbssparams.band %d\n", adapter->curbssparams.band); if (priv->adapter->enable11d) { /* update parsed_region_chan_11; dnld domaininf to FW */ @@ -712,7 +668,7 @@ int libertas_create_dnld_countryinfo_11d(wlan_private * priv) sizeof(adapter->region_channel[0]); j++) { region_chan = &adapter->region_channel[j]; - lbs_deb_11d("11D:[%d] region_chan->band[%d]\n", j, + lbs_deb_11d("%d region_chan->band %d\n", j, region_chan->band); if (!region_chan || !region_chan->valid @@ -725,7 +681,7 @@ int libertas_create_dnld_countryinfo_11d(wlan_private * priv) if (j >= sizeof(adapter->region_channel) / sizeof(adapter->region_channel[0])) { - lbs_deb_11d("11D:region_chan not found. band[%d]\n", + lbs_deb_11d("region_chan not found, band %d\n", adapter->curbssparams.band); ret = -1; goto done; @@ -745,7 +701,7 @@ int libertas_create_dnld_countryinfo_11d(wlan_private * priv) ret = set_domain_info_11d(priv); if (ret) { - lbs_deb_11d("11D: Err set domainInfo to FW\n"); + lbs_deb_11d("error setting domain info\n"); goto done; } diff --git a/drivers/net/wireless/libertas/11d.h b/drivers/net/wireless/libertas/11d.h index 73e42e71291..3a6d1f8db78 100644 --- a/drivers/net/wireless/libertas/11d.h +++ b/drivers/net/wireless/libertas/11d.h @@ -83,8 +83,6 @@ u8 libertas_get_scan_type_11d(u8 chan, u32 libertas_chan_2_freq(u8 chan, u8 band); -enum state_11d libertas_get_state_11d(wlan_private * priv); - void libertas_init_11d(wlan_private * priv); int libertas_set_universaltable(wlan_private * priv, u8 band); @@ -93,8 +91,6 @@ int libertas_cmd_802_11d_domain_info(wlan_private * priv, struct cmd_ds_command *cmd, u16 cmdno, u16 cmdOption); -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); diff --git a/drivers/net/wireless/libertas/Makefile b/drivers/net/wireless/libertas/Makefile index 32ed4136b0d..c469d569f09 100644 --- a/drivers/net/wireless/libertas/Makefile +++ b/drivers/net/wireless/libertas/Makefile @@ -1,12 +1,13 @@ -libertas-objs := main.o fw.o wext.o \ +libertas-objs := main.o wext.o \ rx.o tx.o cmd.o \ cmdresp.o scan.o \ join.o 11d.o \ debugfs.o \ ethtool.o assoc.o -usb8xxx-objs += if_bootcmd.o usb8xxx-objs += if_usb.o +libertas_cs-objs += if_cs.o obj-$(CONFIG_LIBERTAS) += libertas.o obj-$(CONFIG_LIBERTAS_USB) += usb8xxx.o +obj-$(CONFIG_LIBERTAS_CS) += libertas_cs.o diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c index afd5617dd92..b61b176e9d0 100644 --- a/drivers/net/wireless/libertas/assoc.c +++ b/drivers/net/wireless/libertas/assoc.c @@ -16,6 +16,7 @@ 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) { + DECLARE_MAC_BUF(mac); lbs_deb_assoc( "#### Association Request: %s\n" " flags: 0x%08lX\n" @@ -23,13 +24,13 @@ static void print_assoc_req(const char * extra, struct assoc_request * assoc_req " channel: %d\n" " band: %d\n" " mode: %d\n" - " BSSID: " MAC_FMT "\n" + " BSSID: %s\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), + print_mac(mac, assoc_req->bssid), assoc_req->secinfo.WPAenabled ? " WPA" : "", assoc_req->secinfo.WPA2enabled ? " WPA2" : "", assoc_req->secinfo.wep_enabled ? " WEP" : "", @@ -57,10 +58,8 @@ static int assoc_helper_essid(wlan_private *priv, 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, - assoc_req->ssid_len, 0); - } + libertas_send_specific_ssid_scan(priv, assoc_req->ssid, + assoc_req->ssid_len, 0); bss = libertas_find_ssid_in_list(adapter, assoc_req->ssid, assoc_req->ssid_len, NULL, IW_MODE_INFRA, channel); @@ -106,16 +105,17 @@ static int assoc_helper_bssid(wlan_private *priv, wlan_adapter *adapter = priv->adapter; int ret = 0; struct bss_descriptor * bss; + DECLARE_MAC_BUF(mac); - lbs_deb_enter_args(LBS_DEB_ASSOC, "BSSID " MAC_FMT, - MAC_ARG(assoc_req->bssid)); + lbs_deb_enter_args(LBS_DEB_ASSOC, "BSSID %s", + print_mac(mac, assoc_req->bssid)); /* Search for index position in list for requested MAC */ bss = libertas_find_bssid_in_list(adapter, assoc_req->bssid, assoc_req->mode); if (bss == NULL) { - lbs_deb_assoc("ASSOC: WAP: BSSID " MAC_FMT " not found, " - "cannot associate.\n", MAC_ARG(assoc_req->bssid)); + lbs_deb_assoc("ASSOC: WAP: BSSID %s not found, " + "cannot associate.\n", print_mac(mac, assoc_req->bssid)); goto out; } @@ -175,14 +175,14 @@ static int assoc_helper_mode(wlan_private *priv, if (assoc_req->mode == IW_MODE_INFRA) { if (adapter->psstate != PS_STATE_FULL_POWER) - libertas_ps_wakeup(priv, cmd_option_waitforrsp); - adapter->psmode = wlan802_11powermodecam; + libertas_ps_wakeup(priv, CMD_OPTION_WAITFORRSP); + adapter->psmode = WLAN802_11POWERMODECAM; } adapter->mode = assoc_req->mode; ret = libertas_prepare_and_send_command(priv, - cmd_802_11_snmp_mib, - 0, cmd_option_waitforrsp, + CMD_802_11_SNMP_MIB, + 0, CMD_OPTION_WAITFORRSP, OID_802_11_INFRASTRUCTURE_MODE, /* Shoot me now */ (void *) (size_t) assoc_req->mode); @@ -195,9 +195,9 @@ done: 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); + 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) @@ -227,9 +227,9 @@ static int assoc_helper_channel(wlan_private *priv, 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); + 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."); } @@ -278,15 +278,15 @@ static int assoc_helper_wep_keys(wlan_private *priv, || assoc_req->wep_keys[2].len || assoc_req->wep_keys[3].len) { ret = libertas_prepare_and_send_command(priv, - cmd_802_11_set_wep, - cmd_act_add, - cmd_option_waitforrsp, + CMD_802_11_SET_WEP, + CMD_ACT_ADD, + CMD_OPTION_WAITFORRSP, 0, assoc_req); } else { ret = libertas_prepare_and_send_command(priv, - cmd_802_11_set_wep, - cmd_act_remove, - cmd_option_waitforrsp, + CMD_802_11_SET_WEP, + CMD_ACT_REMOVE, + CMD_OPTION_WAITFORRSP, 0, NULL); } @@ -295,9 +295,9 @@ static int assoc_helper_wep_keys(wlan_private *priv, /* enable/disable the MAC's WEP packet filter */ if (assoc_req->secinfo.wep_enabled) - adapter->currentpacketfilter |= cmd_act_mac_wep_enable; + adapter->currentpacketfilter |= CMD_ACT_MAC_WEP_ENABLE; else - adapter->currentpacketfilter &= ~cmd_act_mac_wep_enable; + adapter->currentpacketfilter &= ~CMD_ACT_MAC_WEP_ENABLE; ret = libertas_set_mac_packet_filter(priv); if (ret) goto out; @@ -307,7 +307,7 @@ static int assoc_helper_wep_keys(wlan_private *priv, /* Copy WEP keys into adapter wep key fields */ for (i = 0; i < 4; i++) { memcpy(&adapter->wep_keys[i], &assoc_req->wep_keys[i], - sizeof(struct WLAN_802_11_KEY)); + sizeof(struct enc_key)); } adapter->wep_tx_keyidx = assoc_req->wep_tx_keyidx; @@ -342,9 +342,9 @@ static int assoc_helper_secinfo(wlan_private *priv, /* Get RSN enabled/disabled */ ret = libertas_prepare_and_send_command(priv, - cmd_802_11_enable_rsn, - cmd_act_set, - cmd_option_waitforrsp, + CMD_802_11_ENABLE_RSN, + CMD_ACT_GET, + CMD_OPTION_WAITFORRSP, 0, &rsn); if (ret) { lbs_deb_assoc("Failed to get RSN status: %d", ret); @@ -359,9 +359,9 @@ static int assoc_helper_secinfo(wlan_private *priv, /* 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, + CMD_802_11_ENABLE_RSN, + CMD_ACT_SET, + CMD_OPTION_WAITFORRSP, 0, &rsn); out: @@ -374,15 +374,40 @@ static int assoc_helper_wpa_keys(wlan_private *priv, struct assoc_request * assoc_req) { int ret = 0; + unsigned int flags = assoc_req->flags; lbs_deb_enter(LBS_DEB_ASSOC); - ret = libertas_prepare_and_send_command(priv, - cmd_802_11_key_material, - cmd_act_set, - cmd_option_waitforrsp, - 0, assoc_req); + /* Work around older firmware bug where WPA unicast and multicast + * keys must be set independently. Seen in SDIO parts with firmware + * version 5.0.11p0. + */ + + if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) { + clear_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags); + ret = libertas_prepare_and_send_command(priv, + CMD_802_11_KEY_MATERIAL, + CMD_ACT_SET, + CMD_OPTION_WAITFORRSP, + 0, assoc_req); + assoc_req->flags = flags; + } + + if (ret) + goto out; + if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) { + clear_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags); + + ret = libertas_prepare_and_send_command(priv, + CMD_802_11_KEY_MATERIAL, + CMD_ACT_SET, + CMD_OPTION_WAITFORRSP, + 0, assoc_req); + assoc_req->flags = flags; + } + +out: lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); return ret; } @@ -412,7 +437,7 @@ static int assoc_helper_wpa_ie(wlan_private *priv, static int should_deauth_infrastructure(wlan_adapter *adapter, struct assoc_request * assoc_req) { - if (adapter->connect_status != libertas_connected) + if (adapter->connect_status != LIBERTAS_CONNECTED) return 0; if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { @@ -453,7 +478,7 @@ static int should_deauth_infrastructure(wlan_adapter *adapter, static int should_stop_adhoc(wlan_adapter *adapter, struct assoc_request * assoc_req) { - if (adapter->connect_status != libertas_connected) + if (adapter->connect_status != LIBERTAS_CONNECTED) return 0; if (libertas_ssid_cmp(adapter->curbssparams.ssid, @@ -483,6 +508,7 @@ void libertas_association_worker(struct work_struct *work) struct assoc_request * assoc_req = NULL; int ret = 0; int find_any_ssid = 0; + DECLARE_MAC_BUF(mac); lbs_deb_enter(LBS_DEB_ASSOC); @@ -556,7 +582,8 @@ void libertas_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_deb_assoc("ASSOC(:%d) mode: ret = %d\n", __LINE__, ret); + lbs_deb_assoc("ASSOC(:%d) mode: ret = %d\n", + __LINE__, ret); goto out; } } @@ -574,7 +601,8 @@ lbs_deb_assoc("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_deb_assoc("ASSOC(:%d) wep_keys: ret = %d\n", __LINE__, ret); + lbs_deb_assoc("ASSOC(:%d) wep_keys: ret = %d\n", + __LINE__, ret); goto out; } } @@ -582,7 +610,8 @@ lbs_deb_assoc("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_deb_assoc("ASSOC(:%d) secinfo: ret = %d\n", __LINE__, ret); + lbs_deb_assoc("ASSOC(:%d) secinfo: ret = %d\n", + __LINE__, ret); goto out; } } @@ -590,7 +619,8 @@ lbs_deb_assoc("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_deb_assoc("ASSOC(:%d) wpa_ie: ret = %d\n", __LINE__, ret); + lbs_deb_assoc("ASSOC(:%d) wpa_ie: ret = %d\n", + __LINE__, ret); goto out; } } @@ -599,7 +629,8 @@ lbs_deb_assoc("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_deb_assoc("ASSOC(:%d) wpa_keys: ret = %d\n", __LINE__, ret); + lbs_deb_assoc("ASSOC(:%d) wpa_keys: ret = %d\n", + __LINE__, ret); goto out; } } @@ -618,25 +649,25 @@ lbs_deb_assoc("ASSOC(:%d) wpa_keys: ret = %d\n", __LINE__, ret); success = 0; } - if (adapter->connect_status != libertas_connected) { - lbs_deb_assoc("ASSOC: assoication attempt unsuccessful, " + if (adapter->connect_status != LIBERTAS_CONNECTED) { + lbs_deb_assoc("ASSOC: association attempt unsuccessful, " "not connected.\n"); success = 0; } if (success) { lbs_deb_assoc("ASSOC: association attempt successful. " - "Associated to '%s' (" MAC_FMT ")\n", + "Associated to '%s' (%s)\n", escape_essid(adapter->curbssparams.ssid, adapter->curbssparams.ssid_len), - MAC_ARG(adapter->curbssparams.bssid)); + print_mac(mac, adapter->curbssparams.bssid)); libertas_prepare_and_send_command(priv, - cmd_802_11_rssi, - 0, cmd_option_waitforrsp, 0, NULL); + CMD_802_11_RSSI, + 0, CMD_OPTION_WAITFORRSP, 0, NULL); libertas_prepare_and_send_command(priv, - cmd_802_11_get_log, - 0, cmd_option_waitforrsp, 0, NULL); + CMD_802_11_GET_LOG, + 0, CMD_OPTION_WAITFORRSP, 0, NULL); } else { ret = -1; } @@ -703,7 +734,7 @@ struct assoc_request * wlan_get_association_request(wlan_adapter *adapter) int i; for (i = 0; i < 4; i++) { memcpy(&assoc_req->wep_keys[i], &adapter->wep_keys[i], - sizeof(struct WLAN_802_11_KEY)); + sizeof(struct enc_key)); } } @@ -712,12 +743,12 @@ struct assoc_request * wlan_get_association_request(wlan_adapter *adapter) if (!test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) { memcpy(&assoc_req->wpa_mcast_key, &adapter->wpa_mcast_key, - sizeof(struct WLAN_802_11_KEY)); + sizeof(struct enc_key)); } if (!test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) { memcpy(&assoc_req->wpa_unicast_key, &adapter->wpa_unicast_key, - sizeof(struct WLAN_802_11_KEY)); + sizeof(struct enc_key)); } if (!test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) { diff --git a/drivers/net/wireless/libertas/assoc.h b/drivers/net/wireless/libertas/assoc.h index 5e9c31f0932..e09b7490abb 100644 --- a/drivers/net/wireless/libertas/assoc.h +++ b/drivers/net/wireless/libertas/assoc.h @@ -17,7 +17,7 @@ static inline void wlan_postpone_association_work(wlan_private *priv) if (priv->adapter->surpriseremoved) return; cancel_delayed_work(&priv->assoc_work); - queue_delayed_work(priv->assoc_thread, &priv->assoc_work, ASSOC_DELAY); + queue_delayed_work(priv->work_thread, &priv->assoc_work, ASSOC_DELAY); } static inline void wlan_cancel_association_work(wlan_private *priv) diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 4a8f5dc7023..1cbbd96fdbd 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c @@ -15,7 +15,7 @@ static void cleanup_cmdnode(struct cmd_ctrl_node *ptempnode); static u16 commands_allowed_in_ps[] = { - cmd_802_11_rssi, + CMD_802_11_RSSI, }; /** @@ -43,7 +43,7 @@ static int wlan_cmd_hw_spec(wlan_private * priv, struct cmd_ds_command *cmd) lbs_deb_enter(LBS_DEB_CMD); - cmd->command = cpu_to_le16(cmd_get_hw_spec); + cmd->command = cpu_to_le16(CMD_GET_HW_SPEC); cmd->size = cpu_to_le16(sizeof(struct cmd_ds_get_hw_spec) + S_DS_GEN); memcpy(hwspec->permanentaddr, priv->adapter->current_addr, ETH_ALEN); @@ -56,34 +56,29 @@ 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; - wlan_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_CMD); - cmd->command = cpu_to_le16(cmd_802_11_ps_mode); + 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); psm->action = cpu_to_le16(cmd_action); psm->multipledtim = 0; switch (cmd_action) { - case cmd_subcmd_enter_ps: + case CMD_SUBCMD_ENTER_PS: lbs_deb_cmd("PS command:" "SubCode- Enter PS\n"); - lbs_deb_cmd("locallisteninterval = %d\n", - adapter->locallisteninterval); - psm->locallisteninterval = - cpu_to_le16(adapter->locallisteninterval); - psm->nullpktinterval = - cpu_to_le16(adapter->nullpktinterval); + psm->locallisteninterval = 0; + psm->nullpktinterval = 0; psm->multipledtim = - cpu_to_le16(priv->adapter->multipledtim); + cpu_to_le16(MRVDRV_DEFAULT_MULTIPLE_DTIM); break; - case cmd_subcmd_exit_ps: + case CMD_SUBCMD_EXIT_PS: lbs_deb_cmd("PS command:" "SubCode- Exit PS\n"); break; - case cmd_subcmd_sleep_confirmed: + case CMD_SUBCMD_SLEEP_CONFIRMED: lbs_deb_cmd("PS command: SubCode- sleep confirm\n"); break; @@ -101,7 +96,9 @@ static int wlan_cmd_802_11_inactivity_timeout(wlan_private * priv, { u16 *timeout = pdata_buf; - cmd->command = cpu_to_le16(cmd_802_11_inactivity_timeout); + lbs_deb_enter(LBS_DEB_CMD); + + cmd->command = cpu_to_le16(CMD_802_11_INACTIVITY_TIMEOUT); cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_inactivity_timeout) + S_DS_GEN); @@ -113,6 +110,7 @@ static int wlan_cmd_802_11_inactivity_timeout(wlan_private * priv, else cmd->params.inactivity_timeout.timeout = 0; + lbs_deb_leave(LBS_DEB_CMD); return 0; } @@ -127,13 +125,13 @@ static int wlan_cmd_802_11_sleep_params(wlan_private * priv, 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); + cmd->command = cpu_to_le16(CMD_802_11_SLEEP_PARAMS); - if (cmd_action == cmd_act_get) { + if (cmd_action == CMD_ACT_GET) { memset(&adapter->sp, 0, sizeof(struct sleep_params)); memset(sp, 0, sizeof(struct cmd_ds_802_11_sleep_params)); sp->action = cpu_to_le16(cmd_action); - } else if (cmd_action == cmd_act_set) { + } else if (cmd_action == CMD_ACT_SET) { sp->action = cpu_to_le16(cmd_action); sp->error = cpu_to_le16(adapter->sp.sp_error); sp->offset = cpu_to_le16(adapter->sp.sp_offset); @@ -159,10 +157,10 @@ static int wlan_cmd_802_11_set_wep(wlan_private * priv, lbs_deb_enter(LBS_DEB_CMD); - cmd->command = cpu_to_le16(cmd_802_11_set_wep); + cmd->command = cpu_to_le16(CMD_802_11_SET_WEP); cmd->size = cpu_to_le16(sizeof(*wep) + S_DS_GEN); - if (cmd_act == cmd_act_add) { + if (cmd_act == CMD_ACT_ADD) { int i; if (!assoc_req) { @@ -171,48 +169,47 @@ static int wlan_cmd_802_11_set_wep(wlan_private * priv, goto done; } - wep->action = cpu_to_le16(cmd_act_add); + 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)); - - lbs_deb_cmd("Tx key Index: %u\n", le16_to_cpu(wep->keyindex)); + (u32)CMD_WEP_KEY_INDEX_MASK)); /* Copy key types and material to host command structure */ for (i = 0; i < 4; i++) { - struct WLAN_802_11_KEY * pkey = &assoc_req->wep_keys[i]; + struct enc_key * pkey = &assoc_req->wep_keys[i]; switch (pkey->len) { case KEY_LEN_WEP_40: - wep->keytype[i] = - cpu_to_le16(cmd_type_wep_40_bit); + wep->keytype[i] = CMD_TYPE_WEP_40_BIT; memmove(&wep->keymaterial[i], pkey->key, pkey->len); + lbs_deb_cmd("SET_WEP: add key %d (40 bit)\n", i); break; case KEY_LEN_WEP_104: - wep->keytype[i] = - cpu_to_le16(cmd_type_wep_104_bit); + wep->keytype[i] = CMD_TYPE_WEP_104_BIT; memmove(&wep->keymaterial[i], pkey->key, pkey->len); + lbs_deb_cmd("SET_WEP: add key %d (104 bit)\n", i); break; case 0: break; default: - lbs_deb_cmd("Invalid WEP key %d length of %d\n", + lbs_deb_cmd("SET_WEP: invalid key %d, length %d\n", i, pkey->len); ret = -1; goto done; break; } } - } else if (cmd_act == cmd_act_remove) { + } else if (cmd_act == CMD_ACT_REMOVE) { /* ACT_REMOVE clears _all_ WEP keys */ - wep->action = cpu_to_le16(cmd_act_remove); + 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)); + (u32)CMD_WEP_KEY_INDEX_MASK)); + lbs_deb_cmd("SET_WEP: remove key %d\n", adapter->wep_tx_keyidx); } ret = 0; @@ -232,15 +229,16 @@ static int wlan_cmd_802_11_enable_rsn(wlan_private * priv, lbs_deb_enter(LBS_DEB_CMD); - cmd->command = cpu_to_le16(cmd_802_11_enable_rsn); + cmd->command = cpu_to_le16(CMD_802_11_ENABLE_RSN); cmd->size = cpu_to_le16(sizeof(*penableRSN) + S_DS_GEN); penableRSN->action = cpu_to_le16(cmd_action); - if (cmd_action == cmd_act_set) { + if (cmd_action == CMD_ACT_SET) { if (*enable) - penableRSN->enable = cpu_to_le16(cmd_enable_rsn); + penableRSN->enable = cpu_to_le16(CMD_ENABLE_RSN); else - penableRSN->enable = cpu_to_le16(cmd_disable_rsn); + penableRSN->enable = cpu_to_le16(CMD_DISABLE_RSN); + lbs_deb_cmd("ENABLE_RSN: %d\n", *enable); } lbs_deb_leave(LBS_DEB_CMD); @@ -249,9 +247,9 @@ static int wlan_cmd_802_11_enable_rsn(wlan_private * priv, static void set_one_wpa_key(struct MrvlIEtype_keyParamSet * pkeyparamset, - struct WLAN_802_11_KEY * pkey) + struct enc_key * pkey) { - pkeyparamset->keytypeid = cpu_to_le16(pkey->type); + lbs_deb_enter(LBS_DEB_CMD); if (pkey->flags & KEY_INFO_WPA_ENABLED) { pkeyparamset->keyinfo |= cpu_to_le16(KEY_INFO_WPA_ENABLED); @@ -264,12 +262,14 @@ static void set_one_wpa_key(struct MrvlIEtype_keyParamSet * pkeyparamset, } pkeyparamset->type = cpu_to_le16(TLV_TYPE_KEY_MATERIAL); + pkeyparamset->keytypeid = cpu_to_le16(pkey->type); pkeyparamset->keylen = cpu_to_le16(pkey->len); memcpy(pkeyparamset->key, pkey->key, pkey->len); pkeyparamset->length = cpu_to_le16( sizeof(pkeyparamset->keytypeid) + sizeof(pkeyparamset->keyinfo) + sizeof(pkeyparamset->keylen) + sizeof(pkeyparamset->key)); + lbs_deb_leave(LBS_DEB_CMD); } static int wlan_cmd_802_11_key_material(wlan_private * priv, @@ -285,10 +285,10 @@ static int wlan_cmd_802_11_key_material(wlan_private * priv, lbs_deb_enter(LBS_DEB_CMD); - cmd->command = cpu_to_le16(cmd_802_11_key_material); + cmd->command = cpu_to_le16(CMD_802_11_KEY_MATERIAL); pkeymaterial->action = cpu_to_le16(cmd_action); - if (cmd_action == cmd_act_get) { + if (cmd_action == CMD_ACT_GET) { cmd->size = cpu_to_le16(S_DS_GEN + sizeof (pkeymaterial->action)); ret = 0; goto done; @@ -324,30 +324,37 @@ static int wlan_cmd_802_11_reset(wlan_private * priv, { struct cmd_ds_802_11_reset *reset = &cmd->params.reset; - cmd->command = cpu_to_le16(cmd_802_11_reset); + lbs_deb_enter(LBS_DEB_CMD); + + cmd->command = cpu_to_le16(CMD_802_11_RESET); cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_reset) + S_DS_GEN); reset->action = cpu_to_le16(cmd_action); + lbs_deb_leave(LBS_DEB_CMD); return 0; } static int wlan_cmd_802_11_get_log(wlan_private * priv, struct cmd_ds_command *cmd) { - cmd->command = cpu_to_le16(cmd_802_11_get_log); + lbs_deb_enter(LBS_DEB_CMD); + cmd->command = cpu_to_le16(CMD_802_11_GET_LOG); cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_get_log) + S_DS_GEN); + lbs_deb_leave(LBS_DEB_CMD); return 0; } static int wlan_cmd_802_11_get_stat(wlan_private * priv, struct cmd_ds_command *cmd) { - cmd->command = cpu_to_le16(cmd_802_11_get_stat); + lbs_deb_enter(LBS_DEB_CMD); + 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); + lbs_deb_leave(LBS_DEB_CMD); return 0; } @@ -364,15 +371,15 @@ static int wlan_cmd_802_11_snmp_mib(wlan_private * priv, lbs_deb_cmd("SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid); - cmd->command = cpu_to_le16(cmd_802_11_snmp_mib); + cmd->command = cpu_to_le16(CMD_802_11_SNMP_MIB); cmd->size = cpu_to_le16(sizeof(*pSNMPMIB) + S_DS_GEN); switch (cmd_oid) { case OID_802_11_INFRASTRUCTURE_MODE: { u8 mode = (u8) (size_t) pdata_buf; - pSNMPMIB->querytype = cpu_to_le16(cmd_act_set); - pSNMPMIB->oid = cpu_to_le16((u16) desired_bsstype_i); + pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_SET); + pSNMPMIB->oid = cpu_to_le16((u16) DESIRED_BSSTYPE_I); pSNMPMIB->bufsize = sizeof(u8); if (mode == IW_MODE_ADHOC) { ucTemp = SNMP_MIB_VALUE_ADHOC; @@ -390,10 +397,10 @@ static int wlan_cmd_802_11_snmp_mib(wlan_private * priv, { u32 ulTemp; - pSNMPMIB->oid = cpu_to_le16((u16) dot11d_i); + pSNMPMIB->oid = cpu_to_le16((u16) DOT11D_I); - if (cmd_action == cmd_act_set) { - pSNMPMIB->querytype = cmd_act_set; + if (cmd_action == CMD_ACT_SET) { + pSNMPMIB->querytype = CMD_ACT_SET; pSNMPMIB->bufsize = sizeof(u16); ulTemp = *(u32 *)pdata_buf; *((__le16 *)(pSNMPMIB->value)) = @@ -406,12 +413,12 @@ static int wlan_cmd_802_11_snmp_mib(wlan_private * priv, { u32 ulTemp; - pSNMPMIB->oid = cpu_to_le16((u16) fragthresh_i); + pSNMPMIB->oid = cpu_to_le16((u16) FRAGTHRESH_I); - if (cmd_action == 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); + if (cmd_action == 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); *((__le16 *)(pSNMPMIB->value)) = @@ -426,12 +433,12 @@ static int wlan_cmd_802_11_snmp_mib(wlan_private * priv, { u32 ulTemp; - pSNMPMIB->oid = le16_to_cpu((u16) rtsthresh_i); + pSNMPMIB->oid = le16_to_cpu((u16) RTSTHRESH_I); - if (cmd_action == 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); + if (cmd_action == 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); *(__le16 *)(pSNMPMIB->value) = @@ -441,12 +448,12 @@ static int wlan_cmd_802_11_snmp_mib(wlan_private * priv, break; } case OID_802_11_TX_RETRYCOUNT: - pSNMPMIB->oid = cpu_to_le16((u16) short_retrylim_i); + pSNMPMIB->oid = cpu_to_le16((u16) SHORT_RETRYLIM_I); - if (cmd_action == 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); + if (cmd_action == 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)); *((__le16 *)(pSNMPMIB->value)) = cpu_to_le16((u16) adapter->txretrycount); @@ -463,7 +470,7 @@ static int wlan_cmd_802_11_snmp_mib(wlan_private * priv, le16_to_cpu(cmd->seqnum), le16_to_cpu(cmd->result)); lbs_deb_cmd( - "SNMP_CMD: action=0x%x, oid=0x%x, oidsize=0x%x, value=0x%x\n", + "SNMP_CMD: action 0x%x, oid 0x%x, oidsize 0x%x, value 0x%x\n", le16_to_cpu(pSNMPMIB->querytype), le16_to_cpu(pSNMPMIB->oid), le16_to_cpu(pSNMPMIB->bufsize), le16_to_cpu(*(__le16 *) pSNMPMIB->value)); @@ -484,20 +491,20 @@ static int wlan_cmd_802_11_radio_control(wlan_private * priv, cmd->size = cpu_to_le16((sizeof(struct cmd_ds_802_11_radio_control)) + S_DS_GEN); - cmd->command = cpu_to_le16(cmd_802_11_radio_control); + cmd->command = cpu_to_le16(CMD_802_11_RADIO_CONTROL); pradiocontrol->action = cpu_to_le16(cmd_action); switch (adapter->preamble) { - case cmd_type_short_preamble: + case CMD_TYPE_SHORT_PREAMBLE: pradiocontrol->control = cpu_to_le16(SET_SHORT_PREAMBLE); break; - case cmd_type_long_preamble: + case CMD_TYPE_LONG_PREAMBLE: pradiocontrol->control = cpu_to_le16(SET_LONG_PREAMBLE); break; - case cmd_type_auto_preamble: + case CMD_TYPE_AUTO_PREAMBLE: default: pradiocontrol->control = cpu_to_le16(SET_AUTO_PREAMBLE); break; @@ -523,7 +530,7 @@ static int wlan_cmd_802_11_rf_tx_power(wlan_private * priv, cmd->size = 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); + cmd->command = cpu_to_le16(CMD_802_11_RF_TX_POWER); prtp->action = cpu_to_le16(cmd_action); lbs_deb_cmd("RF_TX_POWER_CMD: size:%d cmd:0x%x Act:%d\n", @@ -531,23 +538,23 @@ static int wlan_cmd_802_11_rf_tx_power(wlan_private * priv, le16_to_cpu(prtp->action)); switch (cmd_action) { - case cmd_act_tx_power_opt_get: - prtp->action = cpu_to_le16(cmd_act_get); + case CMD_ACT_TX_POWER_OPT_GET: + prtp->action = cpu_to_le16(CMD_ACT_GET); prtp->currentlevel = 0; break; - 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); + 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); 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); + 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); break; - case cmd_act_tx_power_opt_set_low: - prtp->action = cpu_to_le16(cmd_act_set); + case CMD_ACT_TX_POWER_OPT_SET_LOW: + prtp->action = cpu_to_le16(CMD_ACT_SET); prtp->currentlevel = cpu_to_le16(*((u16 *) pdata_buf)); break; } @@ -556,19 +563,21 @@ static int wlan_cmd_802_11_rf_tx_power(wlan_private * priv, return 0; } -static int wlan_cmd_802_11_rf_antenna(wlan_private * priv, +static int wlan_cmd_802_11_monitor_mode(wlan_private * priv, struct cmd_ds_command *cmd, u16 cmd_action, void *pdata_buf) { - struct cmd_ds_802_11_rf_antenna *rant = &cmd->params.rant; + struct cmd_ds_802_11_monitor_mode *monitor = &cmd->params.monitor; - 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->command = cpu_to_le16(CMD_802_11_MONITOR_MODE); + cmd->size = + cpu_to_le16(sizeof(struct cmd_ds_802_11_monitor_mode) + + 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)); + monitor->action = cpu_to_le16(cmd_action); + if (cmd_action == CMD_ACT_SET) { + monitor->mode = + cpu_to_le16((u16) (*(u32 *) pdata_buf)); } return 0; @@ -582,12 +591,11 @@ static int wlan_cmd_802_11_rate_adapt_rateset(wlan_private * priv, *rateadapt = &cmd->params.rateset; wlan_adapter *adapter = priv->adapter; + lbs_deb_enter(LBS_DEB_CMD); cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_rate_adapt_rateset) + S_DS_GEN); - cmd->command = cpu_to_le16(cmd_802_11_rate_adapt_rateset); - - lbs_deb_enter(LBS_DEB_CMD); + cmd->command = cpu_to_le16(CMD_802_11_RATE_ADAPT_RATESET); rateadapt->action = cpu_to_le16(cmd_action); rateadapt->enablehwauto = cpu_to_le16(adapter->enablehwauto); @@ -608,19 +616,16 @@ static int wlan_cmd_802_11_data_rate(wlan_private * priv, 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); - + cmd->command = cpu_to_le16(CMD_802_11_DATA_RATE); memset(pdatarate, 0, sizeof(struct cmd_ds_802_11_data_rate)); - pdatarate->action = cpu_to_le16(cmd_action); - if (cmd_action == cmd_act_set_tx_fix_rate) { - pdatarate->datarate[0] = libertas_data_rate_to_index(adapter->datarate); - lbs_deb_cmd("Setting FW for fixed rate 0x%02X\n", - adapter->datarate); - } else if (cmd_action == cmd_act_set_tx_auto) { - lbs_deb_cmd("Setting FW for AUTO rate\n"); + if (cmd_action == CMD_ACT_SET_TX_FIX_RATE) { + pdatarate->rates[0] = libertas_data_rate_to_fw_index(adapter->cur_rate); + lbs_deb_cmd("DATA_RATE: set fixed 0x%02X\n", + adapter->cur_rate); + } else if (cmd_action == CMD_ACT_SET_TX_AUTO) { + lbs_deb_cmd("DATA_RATE: setting auto\n"); } lbs_deb_leave(LBS_DEB_CMD); @@ -634,16 +639,19 @@ 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; + lbs_deb_enter(LBS_DEB_CMD); cmd->size = cpu_to_le16(sizeof(struct cmd_ds_mac_multicast_adr) + S_DS_GEN); - cmd->command = cpu_to_le16(cmd_mac_multicast_adr); + cmd->command = cpu_to_le16(CMD_MAC_MULTICAST_ADR); + lbs_deb_cmd("MULTICAST_ADR: setting %d addresses\n", pMCastAdr->nr_of_adrs); pMCastAdr->action = cpu_to_le16(cmd_action); pMCastAdr->nr_of_adrs = cpu_to_le16((u16) adapter->nr_of_multicastmacaddr); memcpy(pMCastAdr->maclist, adapter->multicastlist, adapter->nr_of_multicastmacaddr * ETH_ALEN); + lbs_deb_leave(LBS_DEB_CMD); return 0; } @@ -653,16 +661,18 @@ 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); + lbs_deb_enter(LBS_DEB_CMD); + 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); - if (option == cmd_opt_802_11_rf_channel_set) { + if (option == CMD_OPT_802_11_RF_CHANNEL_SET) { rfchan->currentchannel = cpu_to_le16(*((u16 *) pdata_buf)); } rfchan->action = cpu_to_le16(option); + lbs_deb_leave(LBS_DEB_CMD); return 0; } @@ -671,9 +681,10 @@ static int wlan_cmd_802_11_rssi(wlan_private * priv, { wlan_adapter *adapter = priv->adapter; - cmd->command = cpu_to_le16(cmd_802_11_rssi); + lbs_deb_enter(LBS_DEB_CMD); + 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 = cpu_to_le16(priv->adapter->bcn_avg_factor); + cmd->params.rssi.N = cpu_to_le16(DEFAULT_BCN_AVG_FACTOR); /* reset Beacon SNR/NF/RSSI values */ adapter->SNR[TYPE_BEACON][TYPE_NOAVG] = 0; @@ -683,6 +694,7 @@ static int wlan_cmd_802_11_rssi(wlan_private * priv, adapter->RSSI[TYPE_BEACON][TYPE_NOAVG] = 0; adapter->RSSI[TYPE_BEACON][TYPE_AVG] = 0; + lbs_deb_leave(LBS_DEB_CMD); return 0; } @@ -697,7 +709,7 @@ static int wlan_cmd_reg_access(wlan_private * priv, offval = (struct wlan_offset_value *)pdata_buf; switch (cmdptr->command) { - case cmd_mac_reg_access: + case CMD_MAC_REG_ACCESS: { struct cmd_ds_mac_reg_access *macreg; @@ -715,7 +727,7 @@ static int wlan_cmd_reg_access(wlan_private * priv, break; } - case cmd_bbp_reg_access: + case CMD_BBP_REG_ACCESS: { struct cmd_ds_bbp_reg_access *bbpreg; @@ -734,7 +746,7 @@ static int wlan_cmd_reg_access(wlan_private * priv, break; } - case cmd_rf_reg_access: + case CMD_RF_REG_ACCESS: { struct cmd_ds_rf_reg_access *rfreg; @@ -767,19 +779,21 @@ 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); + lbs_deb_enter(LBS_DEB_CMD); + cmd->command = cpu_to_le16(CMD_802_11_MAC_ADDRESS); cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_mac_address) + S_DS_GEN); cmd->result = 0; cmd->params.macadd.action = cpu_to_le16(cmd_action); - if (cmd_action == cmd_act_set) { + if (cmd_action == CMD_ACT_SET) { memcpy(cmd->params.macadd.macadd, adapter->current_addr, ETH_ALEN); - lbs_dbg_hex("SET_CMD: MAC ADDRESS-", adapter->current_addr, 6); + lbs_deb_hex(LBS_DEB_CMD, "SET_CMD: MAC addr", adapter->current_addr, 6); } + lbs_deb_leave(LBS_DEB_CMD); return 0; } @@ -791,7 +805,7 @@ static int wlan_cmd_802_11_eeprom_access(wlan_private * priv, lbs_deb_enter(LBS_DEB_CMD); - cmd->command = cpu_to_le16(cmd_802_11_eeprom_access); + 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->result = 0; @@ -801,6 +815,7 @@ static int wlan_cmd_802_11_eeprom_access(wlan_private * priv, cmd->params.rdeeprom.bytecount = cpu_to_le16(ea->NOB); cmd->params.rdeeprom.value = 0; + lbs_deb_leave(LBS_DEB_CMD); return 0; } @@ -809,35 +824,36 @@ 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_deb_cmd("BT CMD(%d)\n", cmd_action); + lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action); - cmd->command = cpu_to_le16(cmd_bt_access); + cmd->command = cpu_to_le16(CMD_BT_ACCESS); 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); switch (cmd_action) { - case cmd_act_bt_access_add: + case CMD_ACT_BT_ACCESS_ADD: memcpy(bt_access->addr1, pdata_buf, 2 * ETH_ALEN); - lbs_dbg_hex("BT_ADD: blinded mac address-", bt_access->addr1, 6); + lbs_deb_hex(LBS_DEB_MESH, "BT_ADD: blinded MAC addr", bt_access->addr1, 6); break; - case cmd_act_bt_access_del: + case CMD_ACT_BT_ACCESS_DEL: memcpy(bt_access->addr1, pdata_buf, 1 * ETH_ALEN); - lbs_dbg_hex("BT_DEL: blinded mac address-", bt_access->addr1, 6); + lbs_deb_hex(LBS_DEB_MESH, "BT_DEL: blinded MAC addr", bt_access->addr1, 6); break; - case cmd_act_bt_access_list: + case CMD_ACT_BT_ACCESS_LIST: bt_access->id = cpu_to_le32(*(u32 *) pdata_buf); break; - case cmd_act_bt_access_reset: + case CMD_ACT_BT_ACCESS_RESET: break; - case cmd_act_bt_access_set_invert: + case CMD_ACT_BT_ACCESS_SET_INVERT: bt_access->id = cpu_to_le32(*(u32 *) pdata_buf); break; - case cmd_act_bt_access_get_invert: + case CMD_ACT_BT_ACCESS_GET_INVERT: break; default: break; } + lbs_deb_leave(LBS_DEB_CMD); return 0; } @@ -846,9 +862,9 @@ 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_deb_cmd("FWT CMD(%d)\n", cmd_action); + lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action); - cmd->command = cpu_to_le16(cmd_fwt_access); + cmd->command = cpu_to_le16(CMD_FWT_ACCESS); cmd->size = cpu_to_le16(sizeof(struct cmd_ds_fwt_access) + S_DS_GEN); cmd->result = 0; @@ -859,6 +875,7 @@ static int wlan_cmd_fwt_access(wlan_private * priv, fwt_access->action = cpu_to_le16(cmd_action); + lbs_deb_leave(LBS_DEB_CMD); return 0; } @@ -867,9 +884,9 @@ 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_deb_cmd("FWT CMD(%d)\n", cmd_action); + lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action); - cmd->command = cpu_to_le16(cmd_mesh_access); + cmd->command = cpu_to_le16(CMD_MESH_ACCESS); cmd->size = cpu_to_le16(sizeof(struct cmd_ds_mesh_access) + S_DS_GEN); cmd->result = 0; @@ -880,6 +897,18 @@ static int wlan_cmd_mesh_access(wlan_private * priv, mesh_access->action = cpu_to_le16(cmd_action); + lbs_deb_leave(LBS_DEB_CMD); + return 0; +} + +static int wlan_cmd_set_boot2_ver(wlan_private * priv, + struct cmd_ds_command *cmd, + u16 cmd_action, void *pdata_buf) +{ + struct cmd_ds_set_boot2_ver *boot2_ver = &cmd->params.boot2_ver; + cmd->command = cpu_to_le16(CMD_SET_BOOT2_VER); + cmd->size = cpu_to_le16(sizeof(struct cmd_ds_set_boot2_ver) + S_DS_GEN); + boot2_ver->version = priv->boot2_version; return 0; } @@ -888,23 +917,23 @@ void libertas_queue_cmd(wlan_adapter * adapter, struct cmd_ctrl_node *cmdnode, u unsigned long flags; struct cmd_ds_command *cmdptr; - lbs_deb_enter(LBS_DEB_CMD); + lbs_deb_enter(LBS_DEB_HOST); if (!cmdnode) { - lbs_deb_cmd("QUEUE_CMD: cmdnode is NULL\n"); + lbs_deb_host("QUEUE_CMD: cmdnode is NULL\n"); goto done; } cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr; if (!cmdptr) { - lbs_deb_cmd("QUEUE_CMD: cmdptr is NULL\n"); + lbs_deb_host("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) { + if (cmdptr->command == CMD_802_11_PS_MODE) { struct cmd_ds_802_11_ps_mode *psm = &cmdptr->params.psmode; - if (psm->action == cpu_to_le16(cmd_subcmd_exit_ps)) { + if (psm->action == cpu_to_le16(CMD_SUBCMD_EXIT_PS)) { if (adapter->psstate != PS_STATE_FULL_POWER) addtail = 0; } @@ -920,17 +949,16 @@ void libertas_queue_cmd(wlan_adapter * adapter, struct cmd_ctrl_node *cmdnode, u spin_unlock_irqrestore(&adapter->driver_lock, flags); - lbs_deb_cmd("QUEUE_CMD: Inserted node=%p, cmd=0x%x in cmdpendingq\n", - cmdnode, + lbs_deb_host("QUEUE_CMD: inserted command 0x%04x into cmdpendingq\n", le16_to_cpu(((struct cmd_ds_gen*)cmdnode->bufvirtualaddr)->command)); done: - lbs_deb_leave(LBS_DEB_CMD); + lbs_deb_leave(LBS_DEB_HOST); } /* * TODO: Fix the issue when DownloadcommandToStation is being called the - * second time when the command timesout. All the cmdptr->xxx are in little + * second time when the command times out. All the cmdptr->xxx are in little * endian and therefore all the comparissions will fail. * For now - we are not performing the endian conversion the second time - but * for PS and DEEP_SLEEP we need to worry @@ -941,68 +969,59 @@ static int DownloadcommandToStation(wlan_private * priv, unsigned long flags; struct cmd_ds_command *cmdptr; wlan_adapter *adapter = priv->adapter; - int ret = 0; + int ret = -1; u16 cmdsize; u16 command; - lbs_deb_enter(LBS_DEB_CMD); + lbs_deb_enter(LBS_DEB_HOST); if (!adapter || !cmdnode) { - lbs_deb_cmd("DNLD_CMD: adapter = %p, cmdnode = %p\n", - adapter, cmdnode); - if (cmdnode) { - spin_lock_irqsave(&adapter->driver_lock, flags); - __libertas_cleanup_and_insert_cmd(priv, cmdnode); - spin_unlock_irqrestore(&adapter->driver_lock, flags); - } - ret = -1; + lbs_deb_host("DNLD_CMD: adapter or cmdmode is NULL\n"); goto done; } cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr; - spin_lock_irqsave(&adapter->driver_lock, flags); if (!cmdptr || !cmdptr->size) { - lbs_deb_cmd("DNLD_CMD: cmdptr is Null or cmd size is Zero, " - "Not sending\n"); + lbs_deb_host("DNLD_CMD: cmdptr is NULL or zero\n"); __libertas_cleanup_and_insert_cmd(priv, cmdnode); spin_unlock_irqrestore(&adapter->driver_lock, flags); - ret = -1; goto done; } adapter->cur_cmd = cmdnode; adapter->cur_cmd_retcode = 0; spin_unlock_irqrestore(&adapter->driver_lock, flags); - lbs_deb_cmd("DNLD_CMD:: Before download, size of cmd = %d\n", - le16_to_cpu(cmdptr->size)); cmdsize = cmdptr->size; - command = cpu_to_le16(cmdptr->command); + lbs_deb_host("DNLD_CMD: command 0x%04x, size %d, jiffies %lu\n", + command, le16_to_cpu(cmdptr->size), jiffies); + lbs_deb_hex(LBS_DEB_HOST, "DNLD_CMD", cmdnode->bufvirtualaddr, cmdsize); + cmdnode->cmdwaitqwoken = 0; cmdsize = cpu_to_le16(cmdsize); ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmdptr, cmdsize); if (ret != 0) { - lbs_deb_cmd("DNLD_CMD: Host to Card failed\n"); + lbs_deb_host("DNLD_CMD: hw_host_to_card failed\n"); spin_lock_irqsave(&adapter->driver_lock, flags); + adapter->cur_cmd_retcode = ret; __libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd); + adapter->nr_cmd_pending--; adapter->cur_cmd = NULL; spin_unlock_irqrestore(&adapter->driver_lock, flags); - ret = -1; goto done; } - lbs_deb_cmd("DNLD_CMD: Sent command 0x%x @ %lu\n", command, jiffies); - lbs_dbg_hex("DNLD_CMD: command", cmdnode->bufvirtualaddr, cmdsize); + lbs_deb_cmd("DNLD_CMD: sent command 0x%04x, jiffies %lu\n", command, jiffies); /* Setup the timer after transmit command */ - if (command == cmd_802_11_scan || command == cmd_802_11_authenticate - || command == cmd_802_11_associate) + 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 mod_timer(&adapter->command_timer, jiffies + (5*HZ)); @@ -1010,7 +1029,7 @@ static int DownloadcommandToStation(wlan_private * priv, ret = 0; done: - lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); + lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret); return ret; } @@ -1021,11 +1040,11 @@ static int wlan_cmd_mac_control(wlan_private * priv, lbs_deb_enter(LBS_DEB_CMD); - cmd->command = cpu_to_le16(cmd_mac_control); + cmd->command = cpu_to_le16(CMD_MAC_CONTROL); cmd->size = cpu_to_le16(sizeof(struct cmd_ds_mac_control) + S_DS_GEN); mac->action = cpu_to_le16(priv->adapter->currentpacketfilter); - lbs_deb_cmd("wlan_cmd_mac_control(): action=0x%X size=%d\n", + lbs_deb_cmd("MAC_CONTROL: action 0x%x, size %d\n", le16_to_cpu(mac->action), le16_to_cpu(cmd->size)); lbs_deb_leave(LBS_DEB_CMD); @@ -1041,15 +1060,13 @@ void __libertas_cleanup_and_insert_cmd(wlan_private * priv, struct cmd_ctrl_node wlan_adapter *adapter = priv->adapter; if (!ptempcmd) - goto done; + return; cleanup_cmdnode(ptempcmd); list_add_tail((struct list_head *)ptempcmd, &adapter->cmdfreeq); -done: - return; } -void libertas_cleanup_and_insert_cmd(wlan_private * priv, struct cmd_ctrl_node *ptempcmd) +static void libertas_cleanup_and_insert_cmd(wlan_private * priv, struct cmd_ctrl_node *ptempcmd) { unsigned long flags; @@ -1065,11 +1082,11 @@ int libertas_set_radio_control(wlan_private * priv) 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); + CMD_802_11_RADIO_CONTROL, + CMD_ACT_SET, + CMD_OPTION_WAITFORRSP, 0, NULL); - lbs_deb_cmd("RADIO_SET: on or off: 0x%X, preamble = 0x%X\n", + lbs_deb_cmd("RADIO_SET: radio %d, preamble %d\n", priv->adapter->radioon, priv->adapter->preamble); lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); @@ -1082,12 +1099,9 @@ int libertas_set_mac_packet_filter(wlan_private * priv) lbs_deb_enter(LBS_DEB_CMD); - 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); + CMD_MAC_CONTROL, 0, 0, 0, NULL); lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); return ret; @@ -1115,16 +1129,16 @@ int libertas_prepare_and_send_command(wlan_private * priv, struct cmd_ds_command *cmdptr; unsigned long flags; - lbs_deb_enter(LBS_DEB_CMD); + lbs_deb_enter(LBS_DEB_HOST); if (!adapter) { - lbs_deb_cmd("PREP_CMD: adapter is Null\n"); + lbs_deb_host("PREP_CMD: adapter is NULL\n"); ret = -1; goto done; } if (adapter->surpriseremoved) { - lbs_deb_cmd("PREP_CMD: Card is Removed\n"); + lbs_deb_host("PREP_CMD: card removed\n"); ret = -1; goto done; } @@ -1132,10 +1146,10 @@ int libertas_prepare_and_send_command(wlan_private * priv, cmdnode = libertas_get_free_cmd_ctrl_node(priv); if (cmdnode == NULL) { - lbs_deb_cmd("PREP_CMD: No free cmdnode\n"); + lbs_deb_host("PREP_CMD: cmdnode is NULL\n"); /* Wake up main thread to execute next command */ - wake_up_interruptible(&priv->mainthread.waitq); + wake_up_interruptible(&priv->waitq); ret = -1; goto done; } @@ -1144,11 +1158,10 @@ int libertas_prepare_and_send_command(wlan_private * priv, cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr; - lbs_deb_cmd("PREP_CMD: Val of cmd ptr=%p, command=0x%X\n", - cmdptr, cmd_no); + lbs_deb_host("PREP_CMD: command 0x%04x\n", cmd_no); if (!cmdptr) { - lbs_deb_cmd("PREP_CMD: bufvirtualaddr of cmdnode is NULL\n"); + lbs_deb_host("PREP_CMD: cmdptr is NULL\n"); libertas_cleanup_and_insert_cmd(priv, cmdnode); ret = -1; goto done; @@ -1162,136 +1175,136 @@ int libertas_prepare_and_send_command(wlan_private * priv, cmdptr->result = 0; switch (cmd_no) { - case cmd_get_hw_spec: + case CMD_GET_HW_SPEC: ret = wlan_cmd_hw_spec(priv, cmdptr); break; - case cmd_802_11_ps_mode: + case CMD_802_11_PS_MODE: ret = wlan_cmd_802_11_ps_mode(priv, cmdptr, cmd_action); break; - case cmd_802_11_scan: + case CMD_802_11_SCAN: ret = libertas_cmd_80211_scan(priv, cmdptr, pdata_buf); break; - case cmd_mac_control: + case CMD_MAC_CONTROL: ret = wlan_cmd_mac_control(priv, cmdptr); break; - case cmd_802_11_associate: - case cmd_802_11_reassociate: + case CMD_802_11_ASSOCIATE: + case CMD_802_11_REASSOCIATE: ret = libertas_cmd_80211_associate(priv, cmdptr, pdata_buf); break; - case cmd_802_11_deauthenticate: + case CMD_802_11_DEAUTHENTICATE: ret = libertas_cmd_80211_deauthenticate(priv, cmdptr); break; - case cmd_802_11_set_wep: + case CMD_802_11_SET_WEP: ret = wlan_cmd_802_11_set_wep(priv, cmdptr, cmd_action, pdata_buf); break; - case cmd_802_11_ad_hoc_start: + case CMD_802_11_AD_HOC_START: ret = libertas_cmd_80211_ad_hoc_start(priv, cmdptr, pdata_buf); break; - case cmd_code_dnld: + case CMD_CODE_DNLD: break; - case cmd_802_11_reset: + case CMD_802_11_RESET: ret = wlan_cmd_802_11_reset(priv, cmdptr, cmd_action); break; - case cmd_802_11_get_log: + case CMD_802_11_GET_LOG: ret = wlan_cmd_802_11_get_log(priv, cmdptr); break; - case cmd_802_11_authenticate: + case CMD_802_11_AUTHENTICATE: ret = libertas_cmd_80211_authenticate(priv, cmdptr, pdata_buf); break; - case cmd_802_11_get_stat: + case CMD_802_11_GET_STAT: ret = wlan_cmd_802_11_get_stat(priv, cmdptr); break; - case cmd_802_11_snmp_mib: + case CMD_802_11_SNMP_MIB: ret = wlan_cmd_802_11_snmp_mib(priv, cmdptr, cmd_action, cmd_oid, pdata_buf); break; - case cmd_mac_reg_access: - case cmd_bbp_reg_access: - case cmd_rf_reg_access: + case CMD_MAC_REG_ACCESS: + case CMD_BBP_REG_ACCESS: + case CMD_RF_REG_ACCESS: ret = wlan_cmd_reg_access(priv, cmdptr, cmd_action, pdata_buf); break; - case cmd_802_11_rf_channel: + case CMD_802_11_RF_CHANNEL: ret = wlan_cmd_802_11_rf_channel(priv, cmdptr, cmd_action, pdata_buf); break; - case cmd_802_11_rf_tx_power: + case CMD_802_11_RF_TX_POWER: ret = wlan_cmd_802_11_rf_tx_power(priv, cmdptr, cmd_action, pdata_buf); break; - case cmd_802_11_radio_control: + case CMD_802_11_RADIO_CONTROL: ret = wlan_cmd_802_11_radio_control(priv, cmdptr, cmd_action); break; - case cmd_802_11_rf_antenna: - ret = wlan_cmd_802_11_rf_antenna(priv, cmdptr, - cmd_action, pdata_buf); - break; - - case cmd_802_11_data_rate: + case CMD_802_11_DATA_RATE: ret = wlan_cmd_802_11_data_rate(priv, cmdptr, cmd_action); break; - case cmd_802_11_rate_adapt_rateset: + case CMD_802_11_RATE_ADAPT_RATESET: ret = wlan_cmd_802_11_rate_adapt_rateset(priv, cmdptr, cmd_action); break; - case cmd_mac_multicast_adr: + case CMD_MAC_MULTICAST_ADR: ret = wlan_cmd_mac_multicast_adr(priv, cmdptr, cmd_action); break; - case cmd_802_11_ad_hoc_join: + case CMD_802_11_MONITOR_MODE: + ret = wlan_cmd_802_11_monitor_mode(priv, cmdptr, + cmd_action, pdata_buf); + break; + + case CMD_802_11_AD_HOC_JOIN: ret = libertas_cmd_80211_ad_hoc_join(priv, cmdptr, pdata_buf); break; - case cmd_802_11_rssi: + case CMD_802_11_RSSI: ret = wlan_cmd_802_11_rssi(priv, cmdptr); break; - case cmd_802_11_ad_hoc_stop: + case CMD_802_11_AD_HOC_STOP: ret = libertas_cmd_80211_ad_hoc_stop(priv, cmdptr); break; - case cmd_802_11_enable_rsn: + case CMD_802_11_ENABLE_RSN: ret = wlan_cmd_802_11_enable_rsn(priv, cmdptr, cmd_action, pdata_buf); break; - case cmd_802_11_key_material: + case CMD_802_11_KEY_MATERIAL: ret = wlan_cmd_802_11_key_material(priv, cmdptr, cmd_action, cmd_oid, pdata_buf); break; - case cmd_802_11_pairwise_tsc: + case CMD_802_11_PAIRWISE_TSC: break; - case cmd_802_11_group_tsc: + case CMD_802_11_GROUP_TSC: break; - case cmd_802_11_mac_address: + case CMD_802_11_MAC_ADDRESS: ret = wlan_cmd_802_11_mac_address(priv, cmdptr, cmd_action); break; - case cmd_802_11_eeprom_access: + case CMD_802_11_EEPROM_ACCESS: ret = wlan_cmd_802_11_eeprom_access(priv, cmdptr, cmd_action, pdata_buf); break; - case cmd_802_11_set_afc: - case cmd_802_11_get_afc: + case CMD_802_11_SET_AFC: + 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) + @@ -1303,22 +1316,22 @@ int libertas_prepare_and_send_command(wlan_private * priv, ret = 0; goto done; - case cmd_802_11d_domain_info: + case CMD_802_11D_DOMAIN_INFO: ret = libertas_cmd_802_11d_domain_info(priv, cmdptr, cmd_no, cmd_action); break; - case cmd_802_11_sleep_params: + case CMD_802_11_SLEEP_PARAMS: ret = wlan_cmd_802_11_sleep_params(priv, cmdptr, cmd_action); break; - case cmd_802_11_inactivity_timeout: + case CMD_802_11_INACTIVITY_TIMEOUT: ret = wlan_cmd_802_11_inactivity_timeout(priv, cmdptr, cmd_action, pdata_buf); libertas_set_cmd_ctrl_node(priv, cmdnode, 0, 0, pdata_buf); break; - case cmd_802_11_tpc_cfg: - cmdptr->command = cpu_to_le16(cmd_802_11_tpc_cfg); + case CMD_802_11_TPC_CFG: + cmdptr->command = cpu_to_le16(CMD_802_11_TPC_CFG); cmdptr->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_tpc_cfg) + S_DS_GEN); @@ -1328,7 +1341,7 @@ int libertas_prepare_and_send_command(wlan_private * priv, ret = 0; break; - case cmd_802_11_led_gpio_ctrl: + case CMD_802_11_LED_GPIO_CTRL: { struct mrvlietypes_ledgpio *gpio = (struct mrvlietypes_ledgpio*) @@ -1339,7 +1352,7 @@ int libertas_prepare_and_send_command(wlan_private * priv, sizeof(struct cmd_ds_802_11_led_ctrl)); cmdptr->command = - cpu_to_le16(cmd_802_11_led_gpio_ctrl); + cpu_to_le16(CMD_802_11_LED_GPIO_CTRL); #define ACTION_NUMLED_TLVTYPE_LEN_FIELDS_LEN 8 cmdptr->size = @@ -1350,8 +1363,8 @@ int libertas_prepare_and_send_command(wlan_private * priv, ret = 0; break; } - case cmd_802_11_pwr_cfg: - cmdptr->command = cpu_to_le16(cmd_802_11_pwr_cfg); + case CMD_802_11_PWR_CFG: + cmdptr->command = cpu_to_le16(CMD_802_11_PWR_CFG); cmdptr->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_pwr_cfg) + S_DS_GEN); @@ -1360,40 +1373,37 @@ int libertas_prepare_and_send_command(wlan_private * priv, ret = 0; break; - case cmd_bt_access: + case CMD_BT_ACCESS: ret = wlan_cmd_bt_access(priv, cmdptr, cmd_action, pdata_buf); break; - case cmd_fwt_access: + case CMD_FWT_ACCESS: ret = wlan_cmd_fwt_access(priv, cmdptr, cmd_action, pdata_buf); break; - case cmd_mesh_access: + case CMD_MESH_ACCESS: ret = wlan_cmd_mesh_access(priv, cmdptr, cmd_action, pdata_buf); break; - 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); - ret = 0; + case CMD_SET_BOOT2_VER: + ret = wlan_cmd_set_boot2_ver(priv, cmdptr, cmd_action, pdata_buf); 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) + + + 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); - adapter->txrate = 0; ret = 0; break; default: - lbs_deb_cmd("PREP_CMD: unknown command- %#x\n", cmd_no); + lbs_deb_host("PREP_CMD: unknown command 0x%04x\n", cmd_no); ret = -1; break; } /* return error, since the command preparation failed */ if (ret != 0) { - lbs_deb_cmd("PREP_CMD: command preparation failed\n"); + lbs_deb_host("PREP_CMD: command preparation failed\n"); libertas_cleanup_and_insert_cmd(priv, cmdnode); ret = -1; goto done; @@ -1403,10 +1413,10 @@ int libertas_prepare_and_send_command(wlan_private * priv, libertas_queue_cmd(adapter, cmdnode, 1); adapter->nr_cmd_pending++; - wake_up_interruptible(&priv->mainthread.waitq); + wake_up_interruptible(&priv->waitq); - if (wait_option & cmd_option_waitforrsp) { - lbs_deb_cmd("PREP_CMD: Wait for CMD response\n"); + if (wait_option & CMD_OPTION_WAITFORRSP) { + lbs_deb_host("PREP_CMD: wait for response\n"); might_sleep(); wait_event_interruptible(cmdnode->cmdwait_q, cmdnode->cmdwaitqwoken); @@ -1414,7 +1424,7 @@ int libertas_prepare_and_send_command(wlan_private * priv, spin_lock_irqsave(&adapter->driver_lock, flags); if (adapter->cur_cmd_retcode) { - lbs_deb_cmd("PREP_CMD: command failed with return code=%d\n", + lbs_deb_host("PREP_CMD: command failed with return code %d\n", adapter->cur_cmd_retcode); adapter->cur_cmd_retcode = 0; ret = -1; @@ -1422,7 +1432,7 @@ int libertas_prepare_and_send_command(wlan_private * priv, spin_unlock_irqrestore(&adapter->driver_lock, flags); done: - lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); + lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret); return ret; } EXPORT_SYMBOL_GPL(libertas_prepare_and_send_command); @@ -1443,14 +1453,13 @@ int libertas_allocate_cmd_buffer(wlan_private * priv) u8 *ptempvirtualaddr; wlan_adapter *adapter = priv->adapter; - lbs_deb_enter(LBS_DEB_CMD); + lbs_deb_enter(LBS_DEB_HOST); /* Allocate and initialize cmdCtrlNode */ ulbufsize = sizeof(struct cmd_ctrl_node) * MRVDRV_NUM_OF_CMD_BUFFER; if (!(tempcmd_array = kzalloc(ulbufsize, GFP_KERNEL))) { - lbs_deb_cmd( - "ALLOC_CMD_BUF: failed to allocate tempcmd_array\n"); + lbs_deb_host("ALLOC_CMD_BUF: tempcmd_array is NULL\n"); ret = -1; goto done; } @@ -1460,8 +1469,7 @@ int libertas_allocate_cmd_buffer(wlan_private * priv) ulbufsize = MRVDRV_SIZE_OF_CMD_BUFFER; for (i = 0; i < MRVDRV_NUM_OF_CMD_BUFFER; i++) { if (!(ptempvirtualaddr = kzalloc(ulbufsize, GFP_KERNEL))) { - lbs_deb_cmd( - "ALLOC_CMD_BUF: ptempvirtualaddr: out of memory\n"); + lbs_deb_host("ALLOC_CMD_BUF: ptempvirtualaddr is NULL\n"); ret = -1; goto done; } @@ -1478,7 +1486,7 @@ int libertas_allocate_cmd_buffer(wlan_private * priv) ret = 0; done: - lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); + lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret); return ret; } @@ -1495,11 +1503,11 @@ int libertas_free_cmd_buffer(wlan_private * priv) struct cmd_ctrl_node *tempcmd_array; wlan_adapter *adapter = priv->adapter; - lbs_deb_enter(LBS_DEB_CMD); + lbs_deb_enter(LBS_DEB_HOST); /* need to check if cmd array is allocated or not */ if (adapter->cmd_array == NULL) { - lbs_deb_cmd("FREE_CMD_BUF: cmd_array is Null\n"); + lbs_deb_host("FREE_CMD_BUF: cmd_array is NULL\n"); goto done; } @@ -1509,7 +1517,6 @@ 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_deb_cmd("Free all the array\n"); kfree(tempcmd_array[i].bufvirtualaddr); tempcmd_array[i].bufvirtualaddr = NULL; } @@ -1517,13 +1524,12 @@ int libertas_free_cmd_buffer(wlan_private * priv) /* Release cmd_ctrl_node */ if (adapter->cmd_array) { - lbs_deb_cmd("Free cmd_array\n"); kfree(adapter->cmd_array); adapter->cmd_array = NULL; } done: - lbs_deb_leave(LBS_DEB_CMD); + lbs_deb_leave(LBS_DEB_HOST); return 0; } @@ -1540,6 +1546,8 @@ struct cmd_ctrl_node *libertas_get_free_cmd_ctrl_node(wlan_private * priv) wlan_adapter *adapter = priv->adapter; unsigned long flags; + lbs_deb_enter(LBS_DEB_HOST); + if (!adapter) return NULL; @@ -1549,21 +1557,16 @@ 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_deb_cmd("GET_CMD_NODE: cmd_ctrl_node is not available\n"); + lbs_deb_host("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); - */ + if (tempnode) cleanup_cmdnode(tempnode); - } + lbs_deb_leave(LBS_DEB_HOST); return tempnode; } @@ -1575,6 +1578,8 @@ struct cmd_ctrl_node *libertas_get_free_cmd_ctrl_node(wlan_private * priv) */ static void cleanup_cmdnode(struct cmd_ctrl_node *ptempnode) { + lbs_deb_enter(LBS_DEB_HOST); + if (!ptempnode) return; ptempnode->cmdwaitqwoken = 1; @@ -1586,7 +1591,8 @@ static void cleanup_cmdnode(struct cmd_ctrl_node *ptempnode) if (ptempnode->bufvirtualaddr != NULL) memset(ptempnode->bufvirtualaddr, 0, MRVDRV_SIZE_OF_CMD_BUFFER); - return; + + lbs_deb_leave(LBS_DEB_HOST); } /** @@ -1603,7 +1609,7 @@ void libertas_set_cmd_ctrl_node(wlan_private * priv, struct cmd_ctrl_node *ptempnode, u32 cmd_oid, u16 wait_option, void *pdata_buf) { - lbs_deb_enter(LBS_DEB_CMD); + lbs_deb_enter(LBS_DEB_HOST); if (!ptempnode) return; @@ -1612,7 +1618,7 @@ void libertas_set_cmd_ctrl_node(wlan_private * priv, ptempnode->wait_option = wait_option; ptempnode->pdata_buf = pdata_buf; - lbs_deb_leave(LBS_DEB_CMD); + lbs_deb_leave(LBS_DEB_HOST); } /** @@ -1631,12 +1637,15 @@ int libertas_execute_next_command(wlan_private * priv) unsigned long flags; int ret = 0; - lbs_deb_enter(LBS_DEB_CMD); + // Debug group is LBS_DEB_THREAD and not LBS_DEB_HOST, because the + // only caller to us is libertas_thread() and we get even when a + // data packet is received + lbs_deb_enter(LBS_DEB_THREAD); spin_lock_irqsave(&adapter->driver_lock, flags); if (adapter->cur_cmd) { - lbs_pr_alert( "EXEC_NEXT_CMD: there is command in processing!\n"); + lbs_pr_alert( "EXEC_NEXT_CMD: already processing command!\n"); spin_unlock_irqrestore(&adapter->driver_lock, flags); ret = -1; goto done; @@ -1650,22 +1659,20 @@ int libertas_execute_next_command(wlan_private * priv) spin_unlock_irqrestore(&adapter->driver_lock, flags); if (cmdnode) { - 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_deb_cmd( - "EXEC_NEXT_CMD: Cannot send cmd 0x%x in psstate %d\n", + lbs_deb_host( + "EXEC_NEXT_CMD: cannot send cmd 0x%04x in psstate %d\n", le16_to_cpu(cmdptr->command), adapter->psstate); ret = -1; goto done; } - lbs_deb_cmd("EXEC_NEXT_CMD: OK to send command " - "0x%x in psstate %d\n", + lbs_deb_host("EXEC_NEXT_CMD: OK to send command " + "0x%04x in psstate %d\n", le16_to_cpu(cmdptr->command), adapter->psstate); } else if (adapter->psstate != PS_STATE_FULL_POWER) { @@ -1681,7 +1688,7 @@ int libertas_execute_next_command(wlan_private * priv) * immediately. */ if (cmdptr->command != - cpu_to_le16(cmd_802_11_ps_mode)) { + cpu_to_le16(CMD_802_11_PS_MODE)) { /* Prepare to send Exit PS, * this non PS command will be sent later */ if ((adapter->psstate == PS_STATE_SLEEP) @@ -1703,13 +1710,13 @@ int libertas_execute_next_command(wlan_private * priv) struct cmd_ds_802_11_ps_mode *psm = &cmdptr->params.psmode; - lbs_deb_cmd( - "EXEC_NEXT_CMD: PS cmd- action=0x%x\n", + lbs_deb_host( + "EXEC_NEXT_CMD: PS cmd, action 0x%02x\n", psm->action); if (psm->action != - cpu_to_le16(cmd_subcmd_exit_ps)) { - lbs_deb_cmd( - "EXEC_NEXT_CMD: Ignore Enter PS cmd\n"); + cpu_to_le16(CMD_SUBCMD_EXIT_PS)) { + lbs_deb_host( + "EXEC_NEXT_CMD: ignore ENTER_PS cmd\n"); list_del((struct list_head *)cmdnode); libertas_cleanup_and_insert_cmd(priv, cmdnode); @@ -1719,8 +1726,8 @@ int libertas_execute_next_command(wlan_private * priv) if ((adapter->psstate == PS_STATE_SLEEP) || (adapter->psstate == PS_STATE_PRE_SLEEP)) { - lbs_deb_cmd( - "EXEC_NEXT_CMD: Ignore ExitPS cmd in sleep\n"); + lbs_deb_host( + "EXEC_NEXT_CMD: ignore EXIT_PS cmd in sleep\n"); list_del((struct list_head *)cmdnode); libertas_cleanup_and_insert_cmd(priv, cmdnode); adapter->needtowakeup = 1; @@ -1729,12 +1736,12 @@ int libertas_execute_next_command(wlan_private * priv) goto done; } - lbs_deb_cmd( - "EXEC_NEXT_CMD: Sending Exit_PS down...\n"); + lbs_deb_host( + "EXEC_NEXT_CMD: sending EXIT_PS\n"); } } list_del((struct list_head *)cmdnode); - lbs_deb_cmd("EXEC_NEXT_CMD: Sending 0x%04X command\n", + lbs_deb_host("EXEC_NEXT_CMD: sending command 0x%04x\n", le16_to_cpu(cmdptr->command)); DownloadcommandToStation(priv, cmdnode); } else { @@ -1742,23 +1749,23 @@ int libertas_execute_next_command(wlan_private * priv) * check if in power save mode, if yes, put the device back * to PS mode */ - if ((adapter->psmode != wlan802_11powermodecam) && + if ((adapter->psmode != WLAN802_11POWERMODECAM) && (adapter->psstate == PS_STATE_FULL_POWER) && - (adapter->connect_status == libertas_connected)) { + (adapter->connect_status == LIBERTAS_CONNECTED)) { 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_deb_cmd( + lbs_deb_host( "EXEC_NEXT_CMD: WPA enabled and GTK_SET" " go back to PS_SLEEP"); libertas_ps_sleep(priv, 0); } } else { - lbs_deb_cmd( - "EXEC_NEXT_CMD: command PendQ is empty," - " go back to PS_SLEEP"); + lbs_deb_host( + "EXEC_NEXT_CMD: cmdpendingq empty, " + "go back to PS_SLEEP"); libertas_ps_sleep(priv, 0); } } @@ -1766,7 +1773,7 @@ int libertas_execute_next_command(wlan_private * priv) ret = 0; done: - lbs_deb_leave(LBS_DEB_CMD); + lbs_deb_leave(LBS_DEB_THREAD); return ret; } @@ -1775,7 +1782,7 @@ void libertas_send_iwevcustom_event(wlan_private * priv, s8 * str) union iwreq_data iwrq; u8 buf[50]; - lbs_deb_enter(LBS_DEB_CMD); + lbs_deb_enter(LBS_DEB_WEXT); memset(&iwrq, 0, sizeof(union iwreq_data)); memset(buf, 0, sizeof(buf)); @@ -1785,13 +1792,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_deb_cmd("Event Indication string = %s\n", (char *)buf); - lbs_deb_cmd("Event Indication String length = %d\n", iwrq.data.length); + lbs_deb_wext("event indication string %s\n", (char *)buf); + lbs_deb_wext("event indication length %d\n", iwrq.data.length); + lbs_deb_wext("sending wireless event IWEVCUSTOM for %s\n", str); - lbs_deb_cmd("Sending wireless event IWEVCUSTOM for %s\n", str); wireless_send_event(priv->dev, IWEVCUSTOM, &iwrq, buf); - lbs_deb_leave(LBS_DEB_CMD); + lbs_deb_leave(LBS_DEB_WEXT); } static int sendconfirmsleep(wlan_private * priv, u8 * cmdptr, u16 size) @@ -1800,19 +1807,19 @@ static int sendconfirmsleep(wlan_private * priv, u8 * cmdptr, u16 size) wlan_adapter *adapter = priv->adapter; int ret = 0; - lbs_deb_enter(LBS_DEB_CMD); + lbs_deb_enter(LBS_DEB_HOST); - lbs_deb_cmd("SEND_SLEEPC_CMD: Before download, size of cmd = %d\n", + lbs_deb_host("SEND_SLEEPC_CMD: before download, cmd size %d\n", size); - lbs_dbg_hex("SEND_SLEEPC_CMD: Sleep confirm command", cmdptr, size); + lbs_deb_hex(LBS_DEB_HOST, "sleep confirm command", cmdptr, size); 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_deb_cmd("SEND_SLEEPC_CMD: intcounter=%d currenttxskb=%p\n", + lbs_deb_host("SEND_SLEEPC_CMD: intcounter %d, currenttxskb %p\n", adapter->intcounter, adapter->currenttxskb); spin_unlock_irqrestore(&adapter->driver_lock, flags); @@ -1824,36 +1831,35 @@ static int sendconfirmsleep(wlan_private * priv, u8 * cmdptr, u16 size) if (!adapter->intcounter) { adapter->psstate = PS_STATE_SLEEP; } else { - lbs_deb_cmd("SEND_SLEEPC_CMD: After sent,IntC=%d\n", + lbs_deb_host("SEND_SLEEPC_CMD: after sent, intcounter %d\n", adapter->intcounter); } spin_unlock_irqrestore(&adapter->driver_lock, flags); - lbs_deb_cmd("SEND_SLEEPC_CMD: Sent Confirm Sleep command\n"); - lbs_deb_cmd("+"); + lbs_deb_host("SEND_SLEEPC_CMD: sent confirm sleep\n"); } - lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); + lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret); return ret; } void libertas_ps_sleep(wlan_private * priv, int wait_option) { - lbs_deb_enter(LBS_DEB_CMD); + lbs_deb_enter(LBS_DEB_HOST); /* * PS is currently supported only in Infrastructure mode * Remove this check if it is to be supported in IBSS mode also */ - libertas_prepare_and_send_command(priv, cmd_802_11_ps_mode, - cmd_subcmd_enter_ps, wait_option, 0, NULL); + libertas_prepare_and_send_command(priv, CMD_802_11_PS_MODE, + CMD_SUBCMD_ENTER_PS, wait_option, 0, NULL); - lbs_deb_leave(LBS_DEB_CMD); + lbs_deb_leave(LBS_DEB_HOST); } /** - * @brief This function sends Eixt_PS command to firmware. + * @brief This function sends Exit_PS command to firmware. * * @param priv A pointer to wlan_private structure * @param wait_option wait response or not @@ -1863,17 +1869,15 @@ void libertas_ps_wakeup(wlan_private * priv, int wait_option) { __le32 Localpsmode; - lbs_deb_enter(LBS_DEB_CMD); - - Localpsmode = cpu_to_le32(wlan802_11powermodecam); + lbs_deb_enter(LBS_DEB_HOST); - lbs_deb_cmd("Exit_PS: Localpsmode = %d\n", wlan802_11powermodecam); + Localpsmode = cpu_to_le32(WLAN802_11POWERMODECAM); - libertas_prepare_and_send_command(priv, cmd_802_11_ps_mode, - cmd_subcmd_exit_ps, + libertas_prepare_and_send_command(priv, CMD_802_11_PS_MODE, + CMD_SUBCMD_EXIT_PS, wait_option, 0, &Localpsmode); - lbs_deb_leave(LBS_DEB_CMD); + lbs_deb_leave(LBS_DEB_HOST); } /** @@ -1890,31 +1894,31 @@ void libertas_ps_confirm_sleep(wlan_private * priv, u16 psmode) wlan_adapter *adapter = priv->adapter; u8 allowed = 1; - lbs_deb_enter(LBS_DEB_CMD); + lbs_deb_enter(LBS_DEB_HOST); if (priv->dnld_sent) { allowed = 0; - lbs_deb_cmd("D"); + lbs_deb_host("dnld_sent was set"); } spin_lock_irqsave(&adapter->driver_lock, flags); if (adapter->cur_cmd) { allowed = 0; - lbs_deb_cmd("C"); + lbs_deb_host("cur_cmd was set"); } if (adapter->intcounter > 0) { allowed = 0; - lbs_deb_cmd("I%d", adapter->intcounter); + lbs_deb_host("intcounter %d", adapter->intcounter); } spin_unlock_irqrestore(&adapter->driver_lock, flags); if (allowed) { - lbs_deb_cmd("Sending libertas_ps_confirm_sleep\n"); + lbs_deb_host("sending libertas_ps_confirm_sleep\n"); sendconfirmsleep(priv, (u8 *) & adapter->libertas_ps_confirm_sleep, sizeof(struct PS_CMD_ConfirmSleep)); } else { - lbs_deb_cmd("Sleep Confirm has been delayed\n"); + lbs_deb_host("sleep confirm has been delayed\n"); } - lbs_deb_leave(LBS_DEB_CMD); + lbs_deb_leave(LBS_DEB_HOST); } diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index 6ac0d4752fa..8f90892ea22 100644 --- a/drivers/net/wireless/libertas/cmdresp.c +++ b/drivers/net/wireless/libertas/cmdresp.c @@ -28,10 +28,10 @@ void libertas_mac_event_disconnected(wlan_private * priv) wlan_adapter *adapter = priv->adapter; union iwreq_data wrqu; - if (adapter->connect_status != libertas_connected) + if (adapter->connect_status != LIBERTAS_CONNECTED) return; - lbs_deb_cmd("Handles disconnect event.\n"); + lbs_deb_enter(LBS_DEB_CMD); memset(wrqu.ap_addr.sa_data, 0x00, ETH_ALEN); wrqu.ap_addr.sa_family = ARPHRD_ETHER; @@ -60,22 +60,12 @@ void libertas_mac_event_disconnected(wlan_private * priv) memset(adapter->rawNF, 0x00, sizeof(adapter->rawNF)); adapter->nextSNRNF = 0; adapter->numSNRNF = 0; - adapter->rxpd_rate = 0; - lbs_deb_cmd("Current SSID='%s', ssid length=%u\n", + lbs_deb_cmd("current SSID '%s', 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; - /* 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); + adapter->connect_status = LIBERTAS_DISCONNECTED; /* Clear out associated SSID and BSSID since connection is * no longer valid. @@ -86,9 +76,10 @@ void libertas_mac_event_disconnected(wlan_private * priv) if (adapter->psstate != PS_STATE_FULL_POWER) { /* make firmware to exit PS mode */ - lbs_deb_cmd("Disconnected, so exit PS mode.\n"); + lbs_deb_cmd("disconnected, so exit PS mode\n"); libertas_ps_wakeup(priv, 0); } + lbs_deb_leave(LBS_DEB_CMD); } /** @@ -102,6 +93,7 @@ static void handle_mic_failureevent(wlan_private * priv, u32 event) { char buf[50]; + lbs_deb_enter(LBS_DEB_CMD); memset(buf, 0, sizeof(buf)); sprintf(buf, "%s", "MLME-MICHAELMICFAILURE.indication "); @@ -113,6 +105,7 @@ static void handle_mic_failureevent(wlan_private * priv, u32 event) } libertas_send_iwevcustom_event(priv, buf); + lbs_deb_leave(LBS_DEB_CMD); } static int wlan_ret_reg_access(wlan_private * priv, @@ -124,7 +117,7 @@ static int wlan_ret_reg_access(wlan_private * priv, lbs_deb_enter(LBS_DEB_CMD); switch (type) { - case cmd_ret_mac_reg_access: + case CMD_RET(CMD_MAC_REG_ACCESS): { struct cmd_ds_mac_reg_access *reg = &resp->params.macreg; @@ -133,7 +126,7 @@ static int wlan_ret_reg_access(wlan_private * priv, break; } - case cmd_ret_bbp_reg_access: + case CMD_RET(CMD_BBP_REG_ACCESS): { struct cmd_ds_bbp_reg_access *reg = &resp->params.bbpreg; @@ -142,7 +135,7 @@ static int wlan_ret_reg_access(wlan_private * priv, break; } - case cmd_ret_rf_reg_access: + case CMD_RET(CMD_RF_REG_ACCESS): { struct cmd_ds_rf_reg_access *reg = &resp->params.rfreg; @@ -155,7 +148,7 @@ static int wlan_ret_reg_access(wlan_private * priv, ret = -1; } - lbs_deb_enter_args(LBS_DEB_CMD, "ret %d", ret); + lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); return ret; } @@ -166,6 +159,7 @@ static int wlan_ret_get_hw_spec(wlan_private * priv, struct cmd_ds_get_hw_spec *hwspec = &resp->params.hwspec; wlan_adapter *adapter = priv->adapter; int ret = 0; + DECLARE_MAC_BUF(mac); lbs_deb_enter(LBS_DEB_CMD); @@ -173,22 +167,23 @@ static int wlan_ret_get_hw_spec(wlan_private * priv, memcpy(adapter->fwreleasenumber, hwspec->fwreleasenumber, 4); - lbs_deb_cmd("GET_HW_SPEC: FWReleaseVersion- %u.%u.%u.p%u\n", + lbs_deb_cmd("GET_HW_SPEC: firmware release %u.%u.%up%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_deb_cmd("GET_HW_SPEC: hwifversion=0x%X version=0x%X\n", + lbs_deb_cmd("GET_HW_SPEC: MAC addr %s\n", + print_mac(mac, hwspec->permanentaddr)); + lbs_deb_cmd("GET_HW_SPEC: hardware interface 0x%x, hardware spec 0x%04x\n", hwspec->hwifversion, hwspec->version); - adapter->regioncode = le16_to_cpu(hwspec->regioncode); + /* Clamp region code to 8-bit since FW spec indicates that it should + * only ever be 8-bit, even though the field size is 16-bit. Some firmware + * returns non-zero high 8 bits here. + */ + adapter->regioncode = le16_to_cpu(hwspec->regioncode) & 0xFF; for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) { /* use the region code to search for the index */ if (adapter->regioncode == libertas_region_code_to_index[i]) { - adapter->regiontableindex = (u16) i; break; } } @@ -196,7 +191,6 @@ static int wlan_ret_get_hw_spec(wlan_private * priv, /* if it's unidentified region code, use the default (USA) */ if (i >= MRVDRV_MAX_REGION_CODE) { adapter->regioncode = 0x10; - adapter->regiontableindex = 0; lbs_pr_info("unidentified region code; using the default (USA)\n"); } @@ -230,8 +224,8 @@ static int wlan_ret_802_11_sleep_params(wlan_private * priv, 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), + lbs_deb_cmd("error 0x%x, offset 0x%x, stabletime 0x%x, calcontrol 0x%x " + "extsleepclk 0x%x\n", le16_to_cpu(sp->error), le16_to_cpu(sp->offset), le16_to_cpu(sp->stabletime), sp->calcontrol, sp->externalsleepclk); @@ -249,6 +243,7 @@ static int wlan_ret_802_11_sleep_params(wlan_private * priv, static int wlan_ret_802_11_stat(wlan_private * priv, struct cmd_ds_command *resp) { + lbs_deb_enter(LBS_DEB_CMD); /* currently adapter->wlan802_11Stat is unused struct cmd_ds_802_11_get_stat *p11Stat = &resp->params.gstat; @@ -258,6 +253,7 @@ static int wlan_ret_802_11_stat(wlan_private * priv, memcpy(&adapter->wlan802_11Stat, p11Stat, sizeof(struct cmd_ds_802_11_get_stat)); */ + lbs_deb_leave(LBS_DEB_CMD); return 0; } @@ -270,28 +266,28 @@ static int wlan_ret_802_11_snmp_mib(wlan_private * priv, lbs_deb_enter(LBS_DEB_CMD); - lbs_deb_cmd("SNMP_RESP: value of the oid = %x, querytype=%x\n", oid, + lbs_deb_cmd("SNMP_RESP: oid 0x%x, querytype 0x%x\n", oid, querytype); - lbs_deb_cmd("SNMP_RESP: Buf size = %x\n", le16_to_cpu(smib->bufsize)); + lbs_deb_cmd("SNMP_RESP: Buf size %d\n", le16_to_cpu(smib->bufsize)); - if (querytype == cmd_act_get) { + if (querytype == CMD_ACT_GET) { switch (oid) { - case fragthresh_i: + case FRAGTHRESH_I: priv->adapter->fragthsd = le16_to_cpu(*((__le16 *)(smib->value))); - lbs_deb_cmd("SNMP_RESP: fragthsd =%u\n", + lbs_deb_cmd("SNMP_RESP: frag threshold %u\n", priv->adapter->fragthsd); break; - case rtsthresh_i: + case RTSTHRESH_I: priv->adapter->rtsthsd = le16_to_cpu(*((__le16 *)(smib->value))); - lbs_deb_cmd("SNMP_RESP: rtsthsd =%u\n", + lbs_deb_cmd("SNMP_RESP: rts threshold %u\n", priv->adapter->rtsthsd); break; - case short_retrylim_i: + case SHORT_RETRYLIM_I: priv->adapter->txretrycount = le16_to_cpu(*((__le16 *)(smib->value))); - lbs_deb_cmd("SNMP_RESP: txretrycount =%u\n", + lbs_deb_cmd("SNMP_RESP: tx retry count %u\n", priv->adapter->rtsthsd); break; default: @@ -314,18 +310,19 @@ static int wlan_ret_802_11_key_material(wlan_private * priv, lbs_deb_enter(LBS_DEB_CMD); /* Copy the returned key to driver private data */ - if (action == cmd_act_get) { + if (action == CMD_ACT_GET) { u8 * buf_ptr = (u8 *) &pkeymaterial->keyParamSet; u8 * resp_end = (u8 *) (resp + le16_to_cpu(resp->size)); while (buf_ptr < resp_end) { struct MrvlIEtype_keyParamSet * pkeyparamset = (struct MrvlIEtype_keyParamSet *) buf_ptr; - struct WLAN_802_11_KEY * pkey; - u16 key_info = le16_to_cpu(pkeyparamset->keyinfo); + struct enc_key * pkey; u16 param_set_len = le16_to_cpu(pkeyparamset->length); - u8 * end; u16 key_len = le16_to_cpu(pkeyparamset->keylen); + u16 key_flags = le16_to_cpu(pkeyparamset->keyinfo); + u16 key_type = le16_to_cpu(pkeyparamset->keytypeid); + u8 * end; end = (u8 *) pkeyparamset + sizeof (pkeyparamset->type) + sizeof (pkeyparamset->length) @@ -334,20 +331,20 @@ static int wlan_ret_802_11_key_material(wlan_private * priv, if (end > resp_end) break; - if (key_info & KEY_INFO_WPA_UNICAST) + if (key_flags & KEY_INFO_WPA_UNICAST) pkey = &adapter->wpa_unicast_key; - else if (key_info & KEY_INFO_WPA_MCAST) + else if (key_flags & KEY_INFO_WPA_MCAST) pkey = &adapter->wpa_mcast_key; else break; /* Copy returned key into driver */ - memset(pkey, 0, sizeof(struct WLAN_802_11_KEY)); + memset(pkey, 0, sizeof(struct enc_key)); if (key_len > sizeof(pkey->key)) break; - pkey->type = le16_to_cpu(pkeyparamset->keytypeid); - pkey->flags = le16_to_cpu(pkeyparamset->keyinfo); - pkey->len = le16_to_cpu(pkeyparamset->keylen); + pkey->type = key_type; + pkey->flags = key_flags; + pkey->len = key_len; memcpy(pkey->key, pkeyparamset->key, pkey->len); buf_ptr = end + 1; @@ -382,28 +379,9 @@ static int wlan_ret_802_11_rf_tx_power(wlan_private * priv, adapter->txpowerlevel = le16_to_cpu(rtp->currentlevel); - lbs_deb_cmd("Current TxPower Level = %d\n", adapter->txpowerlevel); - - lbs_deb_enter(LBS_DEB_CMD); - return 0; -} - -static int wlan_ret_802_11_rf_antenna(wlan_private * priv, - struct cmd_ds_command *resp) -{ - struct cmd_ds_802_11_rf_antenna *pAntenna = &resp->params.rant; - wlan_adapter *adapter = priv->adapter; - u16 action = le16_to_cpu(pAntenna->action); - - if (action == cmd_act_get_rx) - adapter->rxantennamode = le16_to_cpu(pAntenna->antennamode); - - if (action == cmd_act_get_tx) - adapter->txantennamode = le16_to_cpu(pAntenna->antennamode); - - lbs_deb_cmd("RF_ANT_RESP: action = 0x%x, mode = 0x%04x\n", - action, le16_to_cpu(pAntenna->antennamode)); + lbs_deb_cmd("TX power currently %d\n", adapter->txpowerlevel); + lbs_deb_leave(LBS_DEB_CMD); return 0; } @@ -415,12 +393,12 @@ static int wlan_ret_802_11_rate_adapt_rateset(wlan_private * priv, lbs_deb_enter(LBS_DEB_CMD); - if (rates->action == cmd_act_get) { + if (rates->action == CMD_ACT_GET) { adapter->enablehwauto = le16_to_cpu(rates->enablehwauto); adapter->ratebitmap = le16_to_cpu(rates->bitmap); } - lbs_deb_enter(LBS_DEB_CMD); + lbs_deb_leave(LBS_DEB_CMD); return 0; } @@ -429,21 +407,19 @@ static int wlan_ret_802_11_data_rate(wlan_private * priv, { struct cmd_ds_802_11_data_rate *pdatarate = &resp->params.drate; wlan_adapter *adapter = priv->adapter; - u8 dot11datarate; lbs_deb_enter(LBS_DEB_CMD); - lbs_dbg_hex("DATA_RATE_RESP: data_rate- ", - (u8 *) pdatarate, sizeof(struct cmd_ds_802_11_data_rate)); + lbs_deb_hex(LBS_DEB_CMD, "DATA_RATE_RESP", (u8 *) pdatarate, + sizeof(struct cmd_ds_802_11_data_rate)); - dot11datarate = pdatarate->datarate[0]; - 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); + /* FIXME: get actual rates FW can do if this command actually returns + * all data rates supported. + */ + adapter->cur_rate = libertas_fw_index_to_data_rate(pdatarate->rates[0]); + lbs_deb_cmd("DATA_RATE: current rate 0x%02x\n", adapter->cur_rate); - lbs_deb_enter(LBS_DEB_CMD); + lbs_deb_leave(LBS_DEB_CMD); return 0; } @@ -457,9 +433,9 @@ static int wlan_ret_802_11_rf_channel(wlan_private * priv, lbs_deb_enter(LBS_DEB_CMD); - if (action == cmd_opt_802_11_rf_channel_get + if (action == CMD_OPT_802_11_RF_CHANNEL_GET && adapter->curbssparams.channel != newchannel) { - lbs_deb_cmd("channel Switch: %d to %d\n", + lbs_deb_cmd("channel switch from %d to %d\n", adapter->curbssparams.channel, newchannel); /* Update the channel again */ @@ -476,6 +452,8 @@ static int wlan_ret_802_11_rssi(wlan_private * priv, struct cmd_ds_802_11_rssi_rsp *rssirsp = &resp->params.rssirsp; wlan_adapter *adapter = priv->adapter; + lbs_deb_enter(LBS_DEB_CMD); + /* 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); @@ -491,9 +469,11 @@ 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_deb_cmd("Beacon RSSI value = 0x%x\n", + lbs_deb_cmd("RSSI: beacon %d, avg %d\n", + adapter->RSSI[TYPE_BEACON][TYPE_NOAVG], adapter->RSSI[TYPE_BEACON][TYPE_AVG]); + lbs_deb_leave(LBS_DEB_CMD); return 0; } @@ -504,11 +484,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_deb_cmd("eeprom read len=%x\n", + lbs_deb_enter_args(LBS_DEB_CMD, "len %d", le16_to_cpu(resp->params.rdeeprom.bytecount)); if (pbuf->NOB < le16_to_cpu(resp->params.rdeeprom.bytecount)) { pbuf->NOB = 0; - lbs_deb_cmd("eeprom read return length is too big\n"); + lbs_deb_cmd("EEPROM read length too big\n"); return -1; } pbuf->NOB = le16_to_cpu(resp->params.rdeeprom.bytecount); @@ -516,9 +496,10 @@ static int wlan_ret_802_11_eeprom_access(wlan_private * priv, memcpy(&pbuf->value, (u8 *) & resp->params.rdeeprom.value, le16_to_cpu(resp->params.rdeeprom.bytecount)); - lbs_dbg_hex("adapter", (char *)&pbuf->value, + lbs_deb_hex(LBS_DEB_CMD, "EEPROM", (char *)&pbuf->value, le16_to_cpu(resp->params.rdeeprom.bytecount)); } + lbs_deb_leave(LBS_DEB_CMD); return 0; } @@ -533,7 +514,7 @@ static int wlan_ret_get_log(wlan_private * priv, /* Stored little-endian */ memcpy(&adapter->logmsg, logmessage, sizeof(struct cmd_ds_802_11_get_log)); - lbs_deb_enter(LBS_DEB_CMD); + lbs_deb_leave(LBS_DEB_CMD); return 0; } @@ -546,12 +527,12 @@ static int libertas_ret_802_11_enable_rsn(wlan_private * priv, lbs_deb_enter(LBS_DEB_CMD); - if (enable_rsn->action == cpu_to_le16(cmd_act_get)) { + 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); + lbs_deb_leave(LBS_DEB_CMD); return 0; } @@ -563,135 +544,134 @@ static inline int handle_cmd_response(u16 respcmd, unsigned long flags; wlan_adapter *adapter = priv->adapter; + lbs_deb_enter(LBS_DEB_HOST); + switch (respcmd) { - case cmd_ret_mac_reg_access: - case cmd_ret_bbp_reg_access: - case cmd_ret_rf_reg_access: + case CMD_RET(CMD_MAC_REG_ACCESS): + case CMD_RET(CMD_BBP_REG_ACCESS): + case CMD_RET(CMD_RF_REG_ACCESS): ret = wlan_ret_reg_access(priv, respcmd, resp); break; - case cmd_ret_hw_spec_info: + case CMD_RET(CMD_GET_HW_SPEC): ret = wlan_ret_get_hw_spec(priv, resp); break; - case cmd_ret_802_11_scan: + case CMD_RET(CMD_802_11_SCAN): ret = libertas_ret_80211_scan(priv, resp); break; - case cmd_ret_802_11_get_log: + case CMD_RET(CMD_802_11_GET_LOG): ret = wlan_ret_get_log(priv, resp); break; - case cmd_ret_802_11_associate: - case cmd_ret_802_11_reassociate: + case CMD_RET_802_11_ASSOCIATE: + case CMD_RET(CMD_802_11_ASSOCIATE): + case CMD_RET(CMD_802_11_REASSOCIATE): ret = libertas_ret_80211_associate(priv, resp); break; - case cmd_ret_802_11_disassociate: - case cmd_ret_802_11_deauthenticate: + case CMD_RET(CMD_802_11_DISASSOCIATE): + case CMD_RET(CMD_802_11_DEAUTHENTICATE): ret = libertas_ret_80211_disassociate(priv, resp); break; - case cmd_ret_802_11_ad_hoc_start: - case cmd_ret_802_11_ad_hoc_join: + case CMD_RET(CMD_802_11_AD_HOC_START): + case CMD_RET(CMD_802_11_AD_HOC_JOIN): ret = libertas_ret_80211_ad_hoc_start(priv, resp); break; - case cmd_ret_802_11_stat: + case CMD_RET(CMD_802_11_GET_STAT): ret = wlan_ret_802_11_stat(priv, resp); break; - case cmd_ret_802_11_snmp_mib: + case CMD_RET(CMD_802_11_SNMP_MIB): ret = wlan_ret_802_11_snmp_mib(priv, resp); break; - case cmd_ret_802_11_rf_tx_power: + case CMD_RET(CMD_802_11_RF_TX_POWER): ret = wlan_ret_802_11_rf_tx_power(priv, resp); break; - case cmd_ret_802_11_set_afc: - case cmd_ret_802_11_get_afc: + case CMD_RET(CMD_802_11_SET_AFC): + case CMD_RET(CMD_802_11_GET_AFC): spin_lock_irqsave(&adapter->driver_lock, flags); memmove(adapter->cur_cmd->pdata_buf, &resp->params.afc, sizeof(struct cmd_ds_802_11_afc)); spin_unlock_irqrestore(&adapter->driver_lock, flags); break; - case cmd_ret_802_11_rf_antenna: - ret = wlan_ret_802_11_rf_antenna(priv, resp); - break; - case cmd_ret_mac_multicast_adr: - case cmd_ret_mac_control: - case cmd_ret_802_11_set_wep: - case cmd_ret_802_11_reset: - case cmd_ret_802_11_authenticate: - case cmd_ret_802_11_radio_control: - case cmd_ret_802_11_beacon_stop: + case CMD_RET(CMD_MAC_MULTICAST_ADR): + case CMD_RET(CMD_MAC_CONTROL): + case CMD_RET(CMD_802_11_SET_WEP): + case CMD_RET(CMD_802_11_RESET): + case CMD_RET(CMD_802_11_AUTHENTICATE): + case CMD_RET(CMD_802_11_RADIO_CONTROL): + case CMD_RET(CMD_802_11_BEACON_STOP): break; - case cmd_ret_802_11_enable_rsn: + case CMD_RET(CMD_802_11_ENABLE_RSN): ret = libertas_ret_802_11_enable_rsn(priv, resp); break; - case cmd_ret_802_11_data_rate: + case CMD_RET(CMD_802_11_DATA_RATE): ret = wlan_ret_802_11_data_rate(priv, resp); break; - case cmd_ret_802_11_rate_adapt_rateset: + case CMD_RET(CMD_802_11_RATE_ADAPT_RATESET): ret = wlan_ret_802_11_rate_adapt_rateset(priv, resp); break; - case cmd_ret_802_11_rf_channel: + case CMD_RET(CMD_802_11_RF_CHANNEL): ret = wlan_ret_802_11_rf_channel(priv, resp); break; - case cmd_ret_802_11_rssi: + case CMD_RET(CMD_802_11_RSSI): ret = wlan_ret_802_11_rssi(priv, resp); break; - case cmd_ret_802_11_mac_address: + case CMD_RET(CMD_802_11_MAC_ADDRESS): ret = wlan_ret_802_11_mac_address(priv, resp); break; - case cmd_ret_802_11_ad_hoc_stop: + case CMD_RET(CMD_802_11_AD_HOC_STOP): ret = libertas_ret_80211_ad_hoc_stop(priv, resp); break; - case cmd_ret_802_11_key_material: - lbs_deb_cmd("CMD_RESP: KEY_MATERIAL command response\n"); + case CMD_RET(CMD_802_11_KEY_MATERIAL): ret = wlan_ret_802_11_key_material(priv, resp); break; - case cmd_ret_802_11_eeprom_access: + case CMD_RET(CMD_802_11_EEPROM_ACCESS): ret = wlan_ret_802_11_eeprom_access(priv, resp); break; - case cmd_ret_802_11d_domain_info: + case CMD_RET(CMD_802_11D_DOMAIN_INFO): ret = libertas_ret_802_11d_domain_info(priv, resp); break; - case cmd_ret_802_11_sleep_params: + case CMD_RET(CMD_802_11_SLEEP_PARAMS): ret = wlan_ret_802_11_sleep_params(priv, resp); break; - case cmd_ret_802_11_inactivity_timeout: + case CMD_RET(CMD_802_11_INACTIVITY_TIMEOUT): spin_lock_irqsave(&adapter->driver_lock, flags); *((u16 *) adapter->cur_cmd->pdata_buf) = le16_to_cpu(resp->params.inactivity_timeout.timeout); spin_unlock_irqrestore(&adapter->driver_lock, flags); break; - case cmd_ret_802_11_tpc_cfg: + case CMD_RET(CMD_802_11_TPC_CFG): spin_lock_irqsave(&adapter->driver_lock, flags); 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: + case CMD_RET(CMD_802_11_LED_GPIO_CTRL): spin_lock_irqsave(&adapter->driver_lock, flags); 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: + case CMD_RET(CMD_802_11_PWR_CFG): spin_lock_irqsave(&adapter->driver_lock, flags); memmove(adapter->cur_cmd->pdata_buf, &resp->params.pwrcfg, sizeof(struct cmd_ds_802_11_pwr_cfg)); @@ -699,39 +679,37 @@ static inline int handle_cmd_response(u16 respcmd, break; - case cmd_ret_get_tsf: + case CMD_RET(CMD_GET_TSF): spin_lock_irqsave(&adapter->driver_lock, flags); memcpy(priv->adapter->cur_cmd->pdata_buf, &resp->params.gettsf.tsfvalue, sizeof(u64)); spin_unlock_irqrestore(&adapter->driver_lock, flags); break; - case cmd_ret_bt_access: + case CMD_RET(CMD_BT_ACCESS): spin_lock_irqsave(&adapter->driver_lock, flags); if (adapter->cur_cmd->pdata_buf) memcpy(adapter->cur_cmd->pdata_buf, &resp->params.bt.addr1, 2 * ETH_ALEN); spin_unlock_irqrestore(&adapter->driver_lock, flags); break; - case cmd_ret_fwt_access: + case CMD_RET(CMD_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)); spin_unlock_irqrestore(&adapter->driver_lock, flags); break; - case cmd_ret_mesh_access: + case CMD_RET(CMD_MESH_ACCESS): if (adapter->cur_cmd->pdata_buf) 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_deb_cmd("CMD_RESP: Unknown command response %#x\n", + lbs_deb_host("CMD_RESP: unknown cmd response 0x%04x\n", resp->command); break; } + lbs_deb_leave(LBS_DEB_HOST); return ret; } @@ -744,9 +722,7 @@ int libertas_process_rx_command(wlan_private * priv) ulong flags; u16 result; - lbs_deb_enter(LBS_DEB_CMD); - - lbs_deb_cmd("CMD_RESP: @ %lu\n", jiffies); + lbs_deb_enter(LBS_DEB_HOST); /* Now we got response from FW, cancel the command timer */ del_timer(&adapter->command_timer); @@ -755,25 +731,23 @@ int libertas_process_rx_command(wlan_private * priv) spin_lock_irqsave(&adapter->driver_lock, flags); if (!adapter->cur_cmd) { - lbs_deb_cmd("CMD_RESP: NULL cur_cmd=%p\n", adapter->cur_cmd); + lbs_deb_host("CMD_RESP: cur_cmd is NULL\n"); ret = -1; spin_unlock_irqrestore(&adapter->driver_lock, flags); goto done; } resp = (struct cmd_ds_command *)(adapter->cur_cmd->bufvirtualaddr); - lbs_dbg_hex("CMD_RESP:", adapter->cur_cmd->bufvirtualaddr, - priv->upld_len); - respcmd = le16_to_cpu(resp->command); - result = le16_to_cpu(resp->result); - lbs_deb_cmd("CMD_RESP: %x result: %d length: %d\n", respcmd, - result, priv->upld_len); + lbs_deb_host("CMD_RESP: response 0x%04x, size %d, jiffies %lu\n", + respcmd, priv->upld_len, jiffies); + lbs_deb_hex(LBS_DEB_HOST, "CMD_RESP", adapter->cur_cmd->bufvirtualaddr, + priv->upld_len); if (!(respcmd & 0x8000)) { - lbs_deb_cmd("Invalid response to command!"); + lbs_deb_host("invalid response!\n"); adapter->cur_cmd_retcode = -1; __libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd); adapter->nr_cmd_pending--; @@ -786,16 +760,16 @@ int libertas_process_rx_command(wlan_private * priv) /* Store the response code to cur_cmd_retcode. */ adapter->cur_cmd_retcode = result;; - if (respcmd == cmd_ret_802_11_ps_mode) { + if (respcmd == CMD_RET(CMD_802_11_PS_MODE)) { struct cmd_ds_802_11_ps_mode *psmode = &resp->params.psmode; u16 action = le16_to_cpu(psmode->action); - lbs_deb_cmd( - "CMD_RESP: PS_MODE cmd reply result=%#x action=0x%X\n", + lbs_deb_host( + "CMD_RESP: PS_MODE cmd reply result 0x%x, action 0x%x\n", result, action); if (result) { - lbs_deb_cmd("CMD_RESP: PS command failed- %#x \n", + lbs_deb_host("CMD_RESP: PS command failed with 0x%x\n", result); /* * We should not re-try enter-ps command in @@ -803,20 +777,20 @@ int libertas_process_rx_command(wlan_private * priv) * 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) { + 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_deb_cmd("CMD_RESP: Enter_PS command response\n"); - if (adapter->connect_status != libertas_connected) { + lbs_deb_host("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_deb_cmd( - "Disconnected, Going to invoke libertas_ps_wakeup\n"); + lbs_deb_host( + "disconnected, invoking libertas_ps_wakeup\n"); spin_unlock_irqrestore(&adapter->driver_lock, flags); mutex_unlock(&adapter->lock); @@ -824,12 +798,12 @@ int libertas_process_rx_command(wlan_private * priv) mutex_lock(&adapter->lock); spin_lock_irqsave(&adapter->driver_lock, flags); } - } else if (action == cmd_subcmd_exit_ps) { + } else if (action == CMD_SUBCMD_EXIT_PS) { adapter->needtowakeup = 0; adapter->psstate = PS_STATE_FULL_POWER; - lbs_deb_cmd("CMD_RESP: Exit_PS command response\n"); + lbs_deb_host("CMD_RESP: EXIT_PS command response\n"); } else { - lbs_deb_cmd("CMD_RESP: PS- action=0x%X\n", action); + lbs_deb_host("CMD_RESP: PS action 0x%X\n", action); } __libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd); @@ -843,22 +817,22 @@ int libertas_process_rx_command(wlan_private * priv) if (adapter->cur_cmd->cmdflags & CMD_F_HOSTCMD) { /* Copy the response back to response buffer */ - memcpy(adapter->cur_cmd->pdata_buf, resp, resp->size); - + memcpy(adapter->cur_cmd->pdata_buf, resp, + le16_to_cpu(resp->size)); adapter->cur_cmd->cmdflags &= ~CMD_F_HOSTCMD; } /* If the command is not successful, cleanup and return failure */ if ((result != 0 || !(respcmd & 0x8000))) { - lbs_deb_cmd("CMD_RESP: command reply %#x result=%#x\n", - respcmd, result); + lbs_deb_host("CMD_RESP: error 0x%04x in command reply 0x%04x\n", + result, respcmd); /* * Handling errors here */ switch (respcmd) { - case cmd_ret_hw_spec_info: - case cmd_ret_802_11_reset: - lbs_deb_cmd("CMD_RESP: Reset command failed\n"); + case CMD_RET(CMD_GET_HW_SPEC): + case CMD_RET(CMD_802_11_RESET): + lbs_deb_host("CMD_RESP: reset failed\n"); break; } @@ -888,7 +862,7 @@ int libertas_process_rx_command(wlan_private * priv) done: mutex_unlock(&adapter->lock); - lbs_deb_enter_args(LBS_DEB_CMD, "ret %d", ret); + lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret); return ret; } @@ -898,13 +872,13 @@ int libertas_process_event(wlan_private * priv) wlan_adapter *adapter = priv->adapter; u32 eventcause; + lbs_deb_enter(LBS_DEB_CMD); + spin_lock_irq(&adapter->driver_lock); eventcause = adapter->eventcause; spin_unlock_irq(&adapter->driver_lock); - lbs_deb_enter(LBS_DEB_CMD); - - lbs_deb_cmd("EVENT Cause %x\n", eventcause); + lbs_deb_cmd("event cause 0x%x\n", eventcause); switch (eventcause >> SBI_EVENT_CAUSE_SHIFT) { case MACREG_INT_CODE_LINK_SENSED: @@ -912,28 +886,27 @@ int libertas_process_event(wlan_private * priv) break; case MACREG_INT_CODE_DEAUTHENTICATED: - lbs_deb_cmd("EVENT: Deauthenticated\n"); + lbs_deb_cmd("EVENT: deauthenticated\n"); libertas_mac_event_disconnected(priv); break; case MACREG_INT_CODE_DISASSOCIATED: - lbs_deb_cmd("EVENT: Disassociated\n"); + lbs_deb_cmd("EVENT: disassociated\n"); libertas_mac_event_disconnected(priv); break; case MACREG_INT_CODE_LINK_LOSE_NO_SCAN: - lbs_deb_cmd("EVENT: Link lost\n"); + lbs_deb_cmd("EVENT: link lost\n"); libertas_mac_event_disconnected(priv); break; case MACREG_INT_CODE_PS_SLEEP: - lbs_deb_cmd("EVENT: SLEEP\n"); - lbs_deb_cmd("_"); + lbs_deb_cmd("EVENT: sleep\n"); /* handle unexpected PS SLEEP event */ if (adapter->psstate == PS_STATE_FULL_POWER) { lbs_deb_cmd( - "EVENT: In FULL POWER mode - ignore PS SLEEP\n"); + "EVENT: in FULL POWER mode, ignoreing PS_SLEEP\n"); break; } adapter->psstate = PS_STATE_PRE_SLEEP; @@ -943,8 +916,7 @@ int libertas_process_event(wlan_private * priv) break; case MACREG_INT_CODE_PS_AWAKE: - lbs_deb_cmd("EVENT: AWAKE \n"); - lbs_deb_cmd("|"); + lbs_deb_cmd("EVENT: awake\n"); /* handle unexpected PS AWAKE event */ if (adapter->psstate == PS_STATE_FULL_POWER) { @@ -962,7 +934,7 @@ int libertas_process_event(wlan_private * priv) * adapter->needtowakeup will be set to FALSE * in libertas_ps_wakeup() */ - lbs_deb_cmd("Waking up...\n"); + lbs_deb_cmd("waking up ...\n"); libertas_ps_wakeup(priv, 0); } break; @@ -981,38 +953,43 @@ int libertas_process_event(wlan_private * priv) break; case MACREG_INT_CODE_ADHOC_BCN_LOST: - lbs_deb_cmd("EVENT: HWAC - ADHOC BCN LOST\n"); + lbs_deb_cmd("EVENT: ADHOC beacon lost\n"); break; case MACREG_INT_CODE_RSSI_LOW: - lbs_pr_alert( "EVENT: RSSI_LOW\n"); + lbs_pr_alert("EVENT: rssi low\n"); break; case MACREG_INT_CODE_SNR_LOW: - lbs_pr_alert( "EVENT: SNR_LOW\n"); + lbs_pr_alert("EVENT: snr low\n"); break; case MACREG_INT_CODE_MAX_FAIL: - lbs_pr_alert( "EVENT: MAX_FAIL\n"); + lbs_pr_alert("EVENT: max fail\n"); break; case MACREG_INT_CODE_RSSI_HIGH: - lbs_pr_alert( "EVENT: RSSI_HIGH\n"); + lbs_pr_alert("EVENT: rssi high\n"); break; case MACREG_INT_CODE_SNR_HIGH: - lbs_pr_alert( "EVENT: SNR_HIGH\n"); + 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 ; + /* Ignore spurious autostart events if autostart is disabled */ + if (!priv->mesh_autostart_enabled) { + lbs_pr_info("EVENT: MESH_AUTO_STARTED (ignoring)\n"); + break; + } + lbs_pr_info("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) ; + netif_wake_queue(priv->mesh_dev); + netif_carrier_on(priv->mesh_dev); } - adapter->mode = IW_MODE_ADHOC ; + adapter->mode = IW_MODE_ADHOC; schedule_work(&priv->sync_channel); break; default: - lbs_pr_alert( "EVENT: unknown event id: %#x\n", + lbs_pr_alert("EVENT: unknown event id 0x%04x\n", eventcause >> SBI_EVENT_CAUSE_SHIFT); break; } @@ -1021,6 +998,6 @@ int libertas_process_event(wlan_private * priv) adapter->eventcause = 0; spin_unlock_irq(&adapter->driver_lock); - lbs_deb_enter_args(LBS_DEB_CMD, "ret %d", ret); + lbs_deb_leave_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 715cbdaa1d4..0bda0b51191 100644 --- a/drivers/net/wireless/libertas/debugfs.c +++ b/drivers/net/wireless/libertas/debugfs.c @@ -3,6 +3,7 @@ #include <linux/debugfs.h> #include <linux/delay.h> #include <linux/mm.h> +#include <linux/string.h> #include <net/iw_handler.h> #include "dev.h" @@ -63,27 +64,27 @@ 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; + DECLARE_MAC_BUF(mac); struct bss_descriptor * iter_bss; pos += snprintf(buf+pos, len-pos, - "# | ch | ss | bssid | cap | TSF | Qual | SSID \n"); + "# | ch | rssi | bssid | cap | Qual | SSID \n"); mutex_lock(&priv->adapter->lock); list_for_each_entry (iter_bss, &priv->adapter->network_list, list) { - u16 cap; + u16 ibss = (iter_bss->capability & WLAN_CAPABILITY_IBSS); + u16 privacy = (iter_bss->capability & WLAN_CAPABILITY_PRIVACY); + u16 spectrum_mgmt = (iter_bss->capability & WLAN_CAPABILITY_SPECTRUM_MGMT); - memcpy(&cap, &iter_bss->cap, sizeof(cap)); pos += snprintf(buf+pos, len-pos, - "%02u| %03d | %03ld | " MAC_FMT " |", + "%02u| %03d | %04ld | %s |", numscansdone, iter_bss->channel, iter_bss->rssi, - MAC_ARG(iter_bss->bssid)); - pos += snprintf(buf+pos, len-pos, " %04x-", cap); + print_mac(mac, iter_bss->bssid)); + pos += snprintf(buf+pos, len-pos, " %04x-", iter_bss->capability); pos += snprintf(buf+pos, len-pos, "%c%c%c |", - 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)); + ibss ? 'A' : 'I', privacy ? 'P' : ' ', + spectrum_mgmt ? 'S' : ' '); + pos += snprintf(buf+pos, len-pos, " %04d |", SCAN_RSSI(iter_bss->rssi)); pos += snprintf(buf+pos, len-pos, " %s\n", escape_essid(iter_bss->ssid, iter_bss->ssid_len)); @@ -125,9 +126,9 @@ static ssize_t libertas_sleepparams_write(struct file *file, priv->adapter->sp.sp_reserved = p6; res = libertas_prepare_and_send_command(priv, - cmd_802_11_sleep_params, - cmd_act_set, - cmd_option_waitforrsp, 0, NULL); + CMD_802_11_SLEEP_PARAMS, + CMD_ACT_SET, + CMD_OPTION_WAITFORRSP, 0, NULL); if (!res) res = count; @@ -150,9 +151,9 @@ static ssize_t libertas_sleepparams_read(struct file *file, char __user *userbuf char *buf = (char *)addr; res = libertas_prepare_and_send_command(priv, - cmd_802_11_sleep_params, - cmd_act_get, - cmd_option_waitforrsp, 0, NULL); + CMD_802_11_SLEEP_PARAMS, + CMD_ACT_GET, + CMD_OPTION_WAITFORRSP, 0, NULL); if (res) { res = -EFAULT; goto out_unlock; @@ -205,7 +206,7 @@ static int libertas_parse_chan(char *buf, size_t count, if (!start) return -EINVAL; start += 5; - end = strstr(start, " "); + end = strchr(start, ' '); if (!end) end = buf + count; hold = kzalloc((end - start)+1, GFP_KERNEL); @@ -256,7 +257,7 @@ static void libertas_parse_ssid(char *buf, size_t count, if (!hold) return; hold += 5; - end = strstr(hold, " "); + end = strchr(hold, ' '); if (!end) end = buf + count - 1; @@ -386,7 +387,7 @@ static int libertas_event_initcmd(wlan_private *priv, void **response_buf, struct cmd_ctrl_node **cmdnode, struct cmd_ds_command **cmd) { - u16 wait_option = cmd_option_waitforrsp; + u16 wait_option = CMD_OPTION_WAITFORRSP; if (!(*cmdnode = libertas_get_free_cmd_ctrl_node(priv))) { lbs_deb_debugfs("failed libertas_get_free_cmd_ctrl_node\n"); @@ -402,7 +403,7 @@ 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 = cpu_to_le16(cmd_802_11_subscribe_event); + (*cmd)->command = cpu_to_le16(CMD_802_11_SUBSCRIBE_EVENT); (*cmd)->seqnum = cpu_to_le16(++priv->adapter->seqnum); (*cmd)->result = 0; return 0; @@ -429,10 +430,10 @@ static ssize_t libertas_lowrssi_read(struct file *file, char __user *userbuf, } event = &pcmdptr->params.subscribe_event; - event->action = cpu_to_le16(cmd_act_get); + 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); + wake_up_interruptible(&priv->waitq); /* Sleep until response is generated by FW */ wait_event_interruptible(pcmdnode->cmdwait_q, @@ -447,7 +448,7 @@ static ssize_t libertas_lowrssi_read(struct file *file, char __user *userbuf, return 0; } - if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) { + if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) { lbs_pr_err("command response incorrect!\n"); kfree(response_buf); free_page(addr); @@ -493,10 +494,10 @@ static u16 libertas_get_events_bitmap(wlan_private *priv) return res; event = &pcmdptr->params.subscribe_event; - event->action = cpu_to_le16(cmd_act_get); + 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); + wake_up_interruptible(&priv->waitq); /* Sleep until response is generated by FW */ wait_event_interruptible(pcmdnode->cmdwait_q, @@ -511,7 +512,7 @@ static u16 libertas_get_events_bitmap(wlan_private *priv) return 0; } - if (pcmdptr->command != cmd_ret_802_11_subscribe_event) { + if (le16_to_cpu(pcmdptr->command) != CMD_RET(CMD_802_11_SUBSCRIBE_EVENT)) { lbs_pr_err("command response incorrect!\n"); kfree(response_buf); return 0; @@ -559,7 +560,7 @@ static ssize_t libertas_lowrssi_write(struct file *file, goto out_unlock; event = &pcmdptr->params.subscribe_event; - event->action = cpu_to_le16(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)); @@ -575,7 +576,7 @@ static ssize_t libertas_lowrssi_write(struct file *file, event->events = cpu_to_le16(event_bitmap); libertas_queue_cmd(adapter, pcmdnode, 1); - wake_up_interruptible(&priv->mainthread.waitq); + wake_up_interruptible(&priv->waitq); /* Sleep until response is generated by FW */ wait_event_interruptible(pcmdnode->cmdwait_q, @@ -591,7 +592,7 @@ static ssize_t libertas_lowrssi_write(struct file *file, return 0; } - if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) { + if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) { lbs_pr_err("command response incorrect!\n"); kfree(response_buf); free_page(addr); @@ -625,10 +626,10 @@ static ssize_t libertas_lowsnr_read(struct file *file, char __user *userbuf, } event = &pcmdptr->params.subscribe_event; - event->action = cpu_to_le16(cmd_act_get); + 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); + wake_up_interruptible(&priv->waitq); /* Sleep until response is generated by FW */ wait_event_interruptible(pcmdnode->cmdwait_q, @@ -644,7 +645,7 @@ static ssize_t libertas_lowsnr_read(struct file *file, char __user *userbuf, return 0; } - if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) { + if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) { lbs_pr_err("command response incorrect!\n"); kfree(response_buf); free_page(addr); @@ -712,7 +713,7 @@ static ssize_t libertas_lowsnr_write(struct file *file, goto out_unlock; event = &pcmdptr->params.subscribe_event; - event->action = cpu_to_le16(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)); @@ -727,7 +728,7 @@ static ssize_t libertas_lowsnr_write(struct file *file, event->events = cpu_to_le16(event_bitmap); libertas_queue_cmd(adapter, pcmdnode, 1); - wake_up_interruptible(&priv->mainthread.waitq); + wake_up_interruptible(&priv->waitq); /* Sleep until response is generated by FW */ wait_event_interruptible(pcmdnode->cmdwait_q, @@ -743,7 +744,7 @@ static ssize_t libertas_lowsnr_write(struct file *file, return 0; } - if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) { + if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) { lbs_pr_err("command response incorrect!\n"); kfree(response_buf); free_page(addr); @@ -778,10 +779,10 @@ static ssize_t libertas_failcount_read(struct file *file, char __user *userbuf, } event = &pcmdptr->params.subscribe_event; - event->action = cpu_to_le16(cmd_act_get); + 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); + wake_up_interruptible(&priv->waitq); /* Sleep until response is generated by FW */ wait_event_interruptible(pcmdnode->cmdwait_q, @@ -797,7 +798,7 @@ static ssize_t libertas_failcount_read(struct file *file, char __user *userbuf, return 0; } - if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) { + if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) { lbs_pr_err("command response incorrect!\n"); kfree(response_buf); free_page(addr); @@ -864,7 +865,7 @@ static ssize_t libertas_failcount_write(struct file *file, goto out_unlock; event = &pcmdptr->params.subscribe_event; - event->action = cpu_to_le16(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)); @@ -879,7 +880,7 @@ static ssize_t libertas_failcount_write(struct file *file, event->events = cpu_to_le16(event_bitmap); libertas_queue_cmd(adapter, pcmdnode, 1); - wake_up_interruptible(&priv->mainthread.waitq); + wake_up_interruptible(&priv->waitq); /* Sleep until response is generated by FW */ wait_event_interruptible(pcmdnode->cmdwait_q, @@ -895,7 +896,7 @@ static ssize_t libertas_failcount_write(struct file *file, return 0; } - if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) { + if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) { lbs_pr_err("command response incorrect!\n"); kfree(response_buf); free_page(addr); @@ -929,10 +930,10 @@ static ssize_t libertas_bcnmiss_read(struct file *file, char __user *userbuf, } event = &pcmdptr->params.subscribe_event; - event->action = cpu_to_le16(cmd_act_get); + 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); + wake_up_interruptible(&priv->waitq); /* Sleep until response is generated by FW */ wait_event_interruptible(pcmdnode->cmdwait_q, @@ -948,7 +949,7 @@ static ssize_t libertas_bcnmiss_read(struct file *file, char __user *userbuf, return 0; } - if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) { + if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) { lbs_pr_err("command response incorrect!\n"); free_page(addr); kfree(response_buf); @@ -1015,7 +1016,7 @@ static ssize_t libertas_bcnmiss_write(struct file *file, goto out_unlock; event = &pcmdptr->params.subscribe_event; - event->action = cpu_to_le16(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)); @@ -1029,7 +1030,7 @@ static ssize_t libertas_bcnmiss_write(struct file *file, event->events = cpu_to_le16(event_bitmap); libertas_queue_cmd(adapter, pcmdnode, 1); - wake_up_interruptible(&priv->mainthread.waitq); + wake_up_interruptible(&priv->waitq); /* Sleep until response is generated by FW */ wait_event_interruptible(pcmdnode->cmdwait_q, @@ -1045,7 +1046,7 @@ static ssize_t libertas_bcnmiss_write(struct file *file, return 0; } - if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) { + if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) { lbs_pr_err("command response incorrect!\n"); free_page(addr); kfree(response_buf); @@ -1079,10 +1080,10 @@ static ssize_t libertas_highrssi_read(struct file *file, char __user *userbuf, } event = &pcmdptr->params.subscribe_event; - event->action = cpu_to_le16(cmd_act_get); + 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); + wake_up_interruptible(&priv->waitq); /* Sleep until response is generated by FW */ wait_event_interruptible(pcmdnode->cmdwait_q, @@ -1098,7 +1099,7 @@ static ssize_t libertas_highrssi_read(struct file *file, char __user *userbuf, return 0; } - if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) { + if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) { lbs_pr_err("command response incorrect!\n"); kfree(response_buf); free_page(addr); @@ -1166,7 +1167,7 @@ static ssize_t libertas_highrssi_write(struct file *file, goto out_unlock; event = &pcmdptr->params.subscribe_event; - event->action = cpu_to_le16(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)); @@ -1181,7 +1182,7 @@ static ssize_t libertas_highrssi_write(struct file *file, event->events = cpu_to_le16(event_bitmap); libertas_queue_cmd(adapter, pcmdnode, 1); - wake_up_interruptible(&priv->mainthread.waitq); + wake_up_interruptible(&priv->waitq); /* Sleep until response is generated by FW */ wait_event_interruptible(pcmdnode->cmdwait_q, @@ -1196,7 +1197,7 @@ static ssize_t libertas_highrssi_write(struct file *file, return 0; } - if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) { + if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) { lbs_pr_err("command response incorrect!\n"); kfree(response_buf); return 0; @@ -1229,10 +1230,10 @@ static ssize_t libertas_highsnr_read(struct file *file, char __user *userbuf, } event = &pcmdptr->params.subscribe_event; - event->action = cpu_to_le16(cmd_act_get); + 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); + wake_up_interruptible(&priv->waitq); /* Sleep until response is generated by FW */ wait_event_interruptible(pcmdnode->cmdwait_q, @@ -1248,7 +1249,7 @@ static ssize_t libertas_highsnr_read(struct file *file, char __user *userbuf, return 0; } - if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) { + if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) { lbs_pr_err("command response incorrect!\n"); kfree(response_buf); free_page(addr); @@ -1316,7 +1317,7 @@ static ssize_t libertas_highsnr_write(struct file *file, goto out_unlock; event = &pcmdptr->params.subscribe_event; - event->action = cpu_to_le16(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)); @@ -1331,7 +1332,7 @@ static ssize_t libertas_highsnr_write(struct file *file, event->events = cpu_to_le16(event_bitmap); libertas_queue_cmd(adapter, pcmdnode, 1); - wake_up_interruptible(&priv->mainthread.waitq); + wake_up_interruptible(&priv->waitq); /* Sleep until response is generated by FW */ wait_event_interruptible(pcmdnode->cmdwait_q, @@ -1347,7 +1348,7 @@ static ssize_t libertas_highsnr_write(struct file *file, return 0; } - if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) { + if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) { lbs_pr_err("command response incorrect!\n"); kfree(response_buf); free_page(addr); @@ -1375,8 +1376,8 @@ static ssize_t libertas_rdmac_read(struct file *file, char __user *userbuf, offval.value = 0; ret = libertas_prepare_and_send_command(priv, - cmd_mac_reg_access, 0, - cmd_option_waitforrsp, 0, &offval); + CMD_MAC_REG_ACCESS, 0, + CMD_OPTION_WAITFORRSP, 0, &offval); mdelay(10); pos += snprintf(buf+pos, len-pos, "MAC[0x%x] = 0x%08x\n", priv->mac_offset, adapter->offsetvalue.value); @@ -1433,8 +1434,8 @@ static ssize_t libertas_wrmac_write(struct file *file, offval.offset = offset; offval.value = value; res = libertas_prepare_and_send_command(priv, - cmd_mac_reg_access, 1, - cmd_option_waitforrsp, 0, &offval); + CMD_MAC_REG_ACCESS, 1, + CMD_OPTION_WAITFORRSP, 0, &offval); mdelay(10); res = count; @@ -1458,8 +1459,8 @@ static ssize_t libertas_rdbbp_read(struct file *file, char __user *userbuf, offval.value = 0; ret = libertas_prepare_and_send_command(priv, - cmd_bbp_reg_access, 0, - cmd_option_waitforrsp, 0, &offval); + CMD_BBP_REG_ACCESS, 0, + CMD_OPTION_WAITFORRSP, 0, &offval); mdelay(10); pos += snprintf(buf+pos, len-pos, "BBP[0x%x] = 0x%08x\n", priv->bbp_offset, adapter->offsetvalue.value); @@ -1517,8 +1518,8 @@ static ssize_t libertas_wrbbp_write(struct file *file, offval.offset = offset; offval.value = value; res = libertas_prepare_and_send_command(priv, - cmd_bbp_reg_access, 1, - cmd_option_waitforrsp, 0, &offval); + CMD_BBP_REG_ACCESS, 1, + CMD_OPTION_WAITFORRSP, 0, &offval); mdelay(10); res = count; @@ -1542,8 +1543,8 @@ static ssize_t libertas_rdrf_read(struct file *file, char __user *userbuf, offval.value = 0; ret = libertas_prepare_and_send_command(priv, - cmd_rf_reg_access, 0, - cmd_option_waitforrsp, 0, &offval); + CMD_RF_REG_ACCESS, 0, + CMD_OPTION_WAITFORRSP, 0, &offval); mdelay(10); pos += snprintf(buf+pos, len-pos, "RF[0x%x] = 0x%08x\n", priv->rf_offset, adapter->offsetvalue.value); @@ -1601,8 +1602,8 @@ static ssize_t libertas_wrrf_write(struct file *file, offval.offset = offset; offval.value = value; res = libertas_prepare_and_send_command(priv, - cmd_rf_reg_access, 1, - cmd_option_waitforrsp, 0, &offval); + CMD_RF_REG_ACCESS, 1, + CMD_OPTION_WAITFORRSP, 0, &offval); mdelay(10); res = count; @@ -1839,7 +1840,7 @@ static ssize_t wlan_debugfs_write(struct file *f, const char __user *buf, char *p2; struct debug_data *d = (struct debug_data *)f->private_data; - pdata = (char *)kmalloc(cnt, GFP_KERNEL); + pdata = kmalloc(cnt, GFP_KERNEL); if (pdata == NULL) return 0; diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h index 40f56bb1eac..87fea9d5b90 100644 --- a/drivers/net/wireless/libertas/decl.h +++ b/drivers/net/wireless/libertas/decl.h @@ -15,14 +15,9 @@ struct wlan_private; struct sk_buff; struct net_device; -extern char *libertas_fw_name; - -void libertas_free_adapter(wlan_private * priv); int libertas_set_mac_packet_filter(wlan_private * priv); -int libertas_send_null_packet(wlan_private * priv, u8 pwr_mgmt); void libertas_send_tx_feedback(wlan_private * priv); -u8 libertas_check_last_packet_indication(wlan_private * priv); int libertas_free_cmd_buffer(wlan_private * priv); struct cmd_ctrl_node; @@ -44,8 +39,8 @@ int libertas_execute_next_command(wlan_private * priv); int libertas_process_event(wlan_private * priv); void libertas_interrupt(struct net_device *); int libertas_set_radio_control(wlan_private * priv); -u32 libertas_index_to_data_rate(u8 index); -u8 libertas_data_rate_to_index(u32 rate); +u32 libertas_fw_index_to_data_rate(u8 index); +u8 libertas_data_rate_to_fw_index(u32 rate); void libertas_get_fwversion(wlan_adapter * adapter, char *fwversion, int maxlen); void libertas_upload_rx_packet(wlan_private * priv, struct sk_buff *skb); @@ -53,8 +48,6 @@ void libertas_upload_rx_packet(wlan_private * priv, struct sk_buff *skb); /** The proc fs interface */ int libertas_process_rx_command(wlan_private * priv); int libertas_process_tx(wlan_private * priv, struct sk_buff *skb); -void libertas_cleanup_and_insert_cmd(wlan_private * priv, - struct cmd_ctrl_node *ptempcmd); void __libertas_cleanup_and_insert_cmd(wlan_private * priv, struct cmd_ctrl_node *ptempcmd); @@ -75,17 +68,15 @@ void libertas_mac_event_disconnected(wlan_private * priv); void libertas_send_iwevcustom_event(wlan_private * priv, s8 * str); -/* fw.c */ -int libertas_init_fw(wlan_private * priv, char *fw_name); - /* main.c */ struct chan_freq_power *libertas_get_region_cfp_table(u8 region, u8 band, int *cfp_no); 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_start_card(wlan_private *priv); +int libertas_stop_card(wlan_private *priv); int libertas_add_mesh(wlan_private *priv, struct device *dev); void libertas_remove_mesh(wlan_private *priv); - +int libertas_reset_device(wlan_private *priv); #endif /* _WLAN_DECL_H_ */ diff --git a/drivers/net/wireless/libertas/defs.h b/drivers/net/wireless/libertas/defs.h index 4dd43e59bda..7c5b7f7b45d 100644 --- a/drivers/net/wireless/libertas/defs.h +++ b/drivers/net/wireless/libertas/defs.h @@ -43,43 +43,43 @@ extern unsigned int libertas_debug; #ifdef DEBUG -#define LBS_DEB_LL(grp, fmt, args...) \ +#define LBS_DEB_LL(grp, grpnam, fmt, args...) \ do { if ((libertas_debug & (grp)) == (grp)) \ - printk(KERN_DEBUG DRV_NAME "%s: " fmt, \ + printk(KERN_DEBUG DRV_NAME grpnam "%s: " fmt, \ in_interrupt() ? " (INT)" : "", ## args); } while (0) #else -#define LBS_DEB_LL(grp, fmt, args...) do {} while (0) +#define LBS_DEB_LL(grp, grpnam, fmt, args...) do {} while (0) #endif #define lbs_deb_enter(grp) \ - LBS_DEB_LL(grp | LBS_DEB_ENTER, "%s():%d enter\n", __FUNCTION__, __LINE__); + LBS_DEB_LL(grp | LBS_DEB_ENTER, " enter", "%s():%d\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__); + LBS_DEB_LL(grp | LBS_DEB_ENTER, " 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__); + LBS_DEB_LL(grp | LBS_DEB_LEAVE, " leave", "%s():%d\n", __FUNCTION__, __LINE__); #define lbs_deb_leave_args(grp, fmt, args...) \ - LBS_DEB_LL(grp | LBS_DEB_LEAVE, "%s():%d leave, " fmt "\n", \ + LBS_DEB_LL(grp | LBS_DEB_LEAVE, " leave", "%s():%d, " 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_deb_main(fmt, args...) LBS_DEB_LL(LBS_DEB_MAIN, " main", fmt, ##args) +#define lbs_deb_net(fmt, args...) LBS_DEB_LL(LBS_DEB_NET, " net", fmt, ##args) +#define lbs_deb_mesh(fmt, args...) LBS_DEB_LL(LBS_DEB_MESH, " mesh", fmt, ##args) +#define lbs_deb_wext(fmt, args...) LBS_DEB_LL(LBS_DEB_WEXT, " wext", fmt, ##args) +#define lbs_deb_ioctl(fmt, args...) LBS_DEB_LL(LBS_DEB_IOCTL, " ioctl", fmt, ##args) +#define lbs_deb_scan(fmt, args...) LBS_DEB_LL(LBS_DEB_SCAN, " scan", fmt, ##args) +#define lbs_deb_assoc(fmt, args...) LBS_DEB_LL(LBS_DEB_ASSOC, " assoc", fmt, ##args) +#define lbs_deb_join(fmt, args...) LBS_DEB_LL(LBS_DEB_JOIN, " join", fmt, ##args) +#define lbs_deb_11d(fmt, args...) LBS_DEB_LL(LBS_DEB_11D, " 11d", fmt, ##args) +#define lbs_deb_debugfs(fmt, args...) LBS_DEB_LL(LBS_DEB_DEBUGFS, " debugfs", fmt, ##args) +#define lbs_deb_ethtool(fmt, args...) LBS_DEB_LL(LBS_DEB_ETHTOOL, " ethtool", fmt, ##args) +#define lbs_deb_host(fmt, args...) LBS_DEB_LL(LBS_DEB_HOST, " host", fmt, ##args) +#define lbs_deb_cmd(fmt, args...) LBS_DEB_LL(LBS_DEB_CMD, " cmd", fmt, ##args) +#define lbs_deb_rx(fmt, args...) LBS_DEB_LL(LBS_DEB_RX, " rx", fmt, ##args) +#define lbs_deb_tx(fmt, args...) LBS_DEB_LL(LBS_DEB_TX, " tx", fmt, ##args) +#define lbs_deb_fw(fmt, args...) LBS_DEB_LL(LBS_DEB_FW, " fw", fmt, ##args) +#define lbs_deb_usb(fmt, args...) LBS_DEB_LL(LBS_DEB_USB, " usb", fmt, ##args) +#define lbs_deb_usbd(dev, fmt, args...) LBS_DEB_LL(LBS_DEB_USB, " usbd", "%s:" fmt, (dev)->bus_id, ##args) +#define lbs_deb_cs(fmt, args...) LBS_DEB_LL(LBS_DEB_CS, " cs", fmt, ##args) +#define lbs_deb_thread(fmt, args...) LBS_DEB_LL(LBS_DEB_THREAD, " thread", fmt, ##args) #define lbs_pr_info(format, args...) \ printk(KERN_INFO DRV_NAME": " format, ## args) @@ -89,22 +89,28 @@ do { if ((libertas_debug & (grp)) == (grp)) \ printk(KERN_ALERT DRV_NAME": " format, ## args) #ifdef DEBUG -static inline void lbs_dbg_hex(char *prompt, u8 * buf, int len) +static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, int len) { int i = 0; - if (!(libertas_debug & LBS_DEB_HEX)) - return; - - printk(KERN_DEBUG "%s: ", prompt); - for (i = 1; i <= len; i++) { - printk("%02x ", (u8) * buf); - buf++; + if (len && + (libertas_debug & LBS_DEB_HEX) && + (libertas_debug & grp)) + { + for (i = 1; i <= len; i++) { + if ((i & 0xf) == 1) { + if (i != 1) + printk("\n"); + printk(DRV_NAME " %s: ", prompt); + } + printk("%02x ", (u8) * buf); + buf++; + } + printk("\n"); } - printk("\n"); } #else -#define lbs_dbg_hex(x,y,z) do {} while (0) +#define lbs_deb_hex(grp,prompt,buf,len) do {} while (0) #endif @@ -149,17 +155,18 @@ static inline void lbs_dbg_hex(char *prompt, u8 * buf, int len) #define MRVDRV_CHANNELS_PER_SCAN 4 #define MRVDRV_MAX_CHANNELS_PER_SCAN 14 -#define MRVDRV_DEBUG_RX_PATH 0x00000001 -#define MRVDRV_DEBUG_TX_PATH 0x00000002 - #define MRVDRV_MIN_BEACON_INTERVAL 20 #define MRVDRV_MAX_BEACON_INTERVAL 1000 #define MRVDRV_BEACON_INTERVAL 100 +#define MARVELL_MESH_IE_LENGTH 9 + /** INT status Bit Definition*/ -#define his_cmddnldrdy 0x01 -#define his_cardevent 0x02 -#define his_cmdupldrdy 0x04 +#define MRVDRV_TX_DNLD_RDY 0x0001 +#define MRVDRV_RX_UPLD_RDY 0x0002 +#define MRVDRV_CMD_DNLD_RDY 0x0004 +#define MRVDRV_CMD_UPLD_RDY 0x0008 +#define MRVDRV_CARDEVENT 0x0010 #define SBI_EVENT_CAUSE_SHIFT 3 @@ -218,9 +225,6 @@ static inline void lbs_dbg_hex(char *prompt, u8 * buf, int len) #define CMD_F_HOSTCMD (1 << 0) #define FW_CAPINFO_WPA (1 << 0) -/** WPA key LENGTH*/ -#define MRVL_MAX_KEY_WPA_KEY_LENGTH 32 - #define KEY_LEN_WPA_AES 16 #define KEY_LEN_WPA_TKIP 32 #define KEY_LEN_WEP_104 13 @@ -247,10 +251,7 @@ static inline void lbs_dbg_hex(char *prompt, u8 * buf, int len) ((((int)(AVG) * (N -1)) + ((u16)(SNRNF) * \ AVG_SCALE)) / N)) -#define B_SUPPORTED_RATES 8 -#define G_SUPPORTED_RATES 14 - -#define WLAN_SUPPORTED_RATES 14 +#define MAX_RATES 14 #define MAX_LEDS 8 @@ -264,11 +265,7 @@ 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_supported_rates[G_SUPPORTED_RATES]; - -extern u8 libertas_adhoc_rates_g[G_SUPPORTED_RATES]; - -extern u8 libertas_adhoc_rates_b[4]; +extern u8 libertas_bg_rates[MAX_RATES]; /** ENUM definition*/ /** SNRNF_TYPE */ @@ -287,11 +284,11 @@ enum SNRNF_DATA { /** WLAN_802_11_POWER_MODE */ enum WLAN_802_11_POWER_MODE { - wlan802_11powermodecam, - wlan802_11powermodemax_psp, - wlan802_11Powermodefast_psp, + WLAN802_11POWERMODECAM, + WLAN802_11POWERMODEMAX_PSP, + WLAN802_11POWERMODEFAST_PSP, /*not a real mode, defined as an upper bound */ - wlan802_11powemodemax + WLAN802_11POWEMODEMAX }; /** PS_STATE */ @@ -311,14 +308,14 @@ enum DNLD_STATE { /** WLAN_MEDIA_STATE */ enum WLAN_MEDIA_STATE { - libertas_connected, - libertas_disconnected + LIBERTAS_CONNECTED, + LIBERTAS_DISCONNECTED }; /** WLAN_802_11_PRIVACY_FILTER */ enum WLAN_802_11_PRIVACY_FILTER { - wlan802_11privfilteracceptall, - wlan802_11privfilter8021xWEP + WLAN802_11PRIVFILTERACCEPTALL, + WLAN802_11PRIVFILTER8021XWEP }; /** mv_ms_type */ @@ -331,23 +328,23 @@ enum mv_ms_type { /** SNMP_MIB_INDEX_e */ enum SNMP_MIB_INDEX_e { - desired_bsstype_i = 0, - op_rateset_i, - bcnperiod_i, - dtimperiod_i, - assocrsp_timeout_i, - rtsthresh_i, - short_retrylim_i, - long_retrylim_i, - fragthresh_i, - dot11d_i, - dot11h_i, - manufid_i, - prodID_i, - manuf_oui_i, - manuf_name_i, - manuf_prodname_i, - manuf_prodver_i, + DESIRED_BSSTYPE_I = 0, + OP_RATESET_I, + BCNPERIOD_I, + DTIMPERIOD_I, + ASSOCRSP_TIMEOUT_I, + RTSTHRESH_I, + SHORT_RETRYLIM_I, + LONG_RETRYLIM_I, + FRAGTHRESH_I, + DOT11D_I, + DOT11H_I, + MANUFID_I, + PRODID_I, + MANUF_OUI_I, + MANUF_NAME_I, + MANUF_PRODNAME_I, + MANUF_PRODVER_I, }; /** KEY_TYPE_ID */ diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h index 785192b884b..1fb807aa91b 100644 --- a/drivers/net/wireless/libertas/dev.h +++ b/drivers/net/wireless/libertas/dev.h @@ -14,7 +14,6 @@ #include "defs.h" #include "scan.h" -#include "thread.h" extern struct ethtool_ops libertas_ethtool_ops; @@ -73,10 +72,8 @@ struct current_bss_params { u8 band; /** channel */ u8 channel; - /** number of rates supported */ - int numofrates; - /** supported rates*/ - u8 datarates[WLAN_SUPPORTED_RATES]; + /** zero-terminated array of supported data rates */ + u8 rates[MAX_RATES + 1]; }; /** sleep_params */ @@ -106,6 +103,8 @@ struct _wlan_private { int open; int mesh_open; int infra_open; + int mesh_autostart_enabled; + __le16 boot2_version; char name[DEV_NAME_LEN]; @@ -114,7 +113,9 @@ struct _wlan_private { struct net_device *dev; struct net_device_stats stats; - struct net_device *mesh_dev ; /* Virtual device */ + struct net_device *mesh_dev; /* Virtual device */ + struct net_device *rtap_net_dev; + struct ieee80211_device *ieee; struct iw_statistics wstats; struct wlan_mesh_stats mstats; @@ -142,20 +143,18 @@ struct _wlan_private { all other bits reserved 0 */ u8 dnld_sent; - const struct firmware *firmware; struct device *hotplug_device; /** thread to service interrupts */ - struct wlan_thread mainthread; + struct task_struct *main_thread; + wait_queue_head_t waitq; + struct workqueue_struct *work_thread; + struct delayed_work scan_work; 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 *); @@ -188,12 +187,12 @@ struct assoc_request { u8 bssid[ETH_ALEN]; /** WEP keys */ - struct WLAN_802_11_KEY wep_keys[4]; + struct enc_key wep_keys[4]; u16 wep_tx_keyidx; /** WPA keys */ - struct WLAN_802_11_KEY wpa_mcast_key; - struct WLAN_802_11_KEY wpa_unicast_key; + struct enc_key wpa_mcast_key; + struct enc_key wpa_unicast_key; struct wlan_802_11_security secinfo; @@ -259,23 +258,15 @@ struct _wlan_adapter { /* IW_MODE_* */ u8 mode; - u8 prev_ssid[IW_ESSID_MAX_SIZE + 1]; - u8 prev_ssid_len; - u8 prev_bssid[ETH_ALEN]; - /* Scan results list */ struct list_head network_list; struct list_head network_free_list; struct bss_descriptor *networks; - u8 scantype; - u32 scanmode; - - u16 beaconperiod; u8 adhoccreate; /** capability Info used in Association, start, join */ - struct ieeetypes_capinfo capinfo; + u16 capability; /** MAC address information */ u8 current_addr[ETH_ALEN]; @@ -287,20 +278,10 @@ struct _wlan_adapter { u16 enablehwauto; u16 ratebitmap; - /** control G rates */ - u8 adhoc_grate_enabled; - - u32 txantenna; - u32 rxantenna; u32 fragthsd; u32 rtsthsd; - u32 datarate; - u8 is_datarate_auto; - - u16 listeninterval; - u16 prescan; u8 txretrycount; /** Tx-related variables (for single packet tx) */ @@ -311,22 +292,17 @@ struct _wlan_adapter { u16 currentpacketfilter; u32 connect_status; u16 regioncode; - u16 regiontableindex; u16 txpowerlevel; /** POWER MANAGEMENT AND PnP SUPPORT */ u8 surpriseremoved; - u16 atimwindow; u16 psmode; /* Wlan802_11PowermodeCAM=disable Wlan802_11PowermodeMAX_PSP=enable */ - u16 multipledtim; u32 psstate; u8 needtowakeup; struct PS_CMD_ConfirmSleep libertas_ps_confirm_sleep; - u16 locallisteninterval; - u16 nullpktinterval; struct assoc_request * pending_assoc_req; struct assoc_request * in_progress_assoc_req; @@ -335,23 +311,18 @@ struct _wlan_adapter { struct wlan_802_11_security secinfo; /** WEP keys */ - struct WLAN_802_11_KEY wep_keys[4]; + struct enc_key wep_keys[4]; u16 wep_tx_keyidx; /** WPA keys */ - struct WLAN_802_11_KEY wpa_mcast_key; - struct WLAN_802_11_KEY wpa_unicast_key; + struct enc_key wpa_mcast_key; + struct enc_key wpa_unicast_key; /** WPA Information Elements*/ u8 wpa_ie[MAX_WPA_IE_LEN]; u8 wpa_ie_len; - u16 rxantennamode; - u16 txantennamode; - /** Requested Signal Strength*/ - u16 bcn_avg_factor; - u16 data_avg_factor; u16 SNR[MAX_TYPE_B][MAX_TYPE_AVG]; u16 NF[MAX_TYPE_B][MAX_TYPE_AVG]; u8 RSSI[MAX_TYPE_B][MAX_TYPE_AVG]; @@ -359,15 +330,13 @@ struct _wlan_adapter { u8 rawNF[DEFAULT_DATA_AVG_FACTOR]; u16 nextSNRNF; u16 numSNRNF; - u16 rxpd_rate; u8 radioon; u32 preamble; - /** Multi bands Parameter*/ - u8 libertas_supported_rates[G_SUPPORTED_RATES]; - - /** Blue Tooth Co-existence Arbitration */ + /** data rate stuff */ + u8 cur_rate; + u8 auto_rate; /** sleep_params */ struct sleep_params sp; @@ -392,14 +361,8 @@ struct _wlan_adapter { struct wlan_offset_value offsetvalue; struct cmd_ds_802_11_get_log logmsg; - u16 scanprobes; - - u32 pkttxctrl; - u16 txrate; - u32 linkmode; - u32 radiomode; - u32 debugmode; + u32 monitormode; u8 fw_ready; u8 last_scanned_channel; diff --git a/drivers/net/wireless/libertas/ethtool.c b/drivers/net/wireless/libertas/ethtool.c index 96f1974685d..3dae15211b6 100644 --- a/drivers/net/wireless/libertas/ethtool.c +++ b/drivers/net/wireless/libertas/ethtool.c @@ -60,8 +60,7 @@ static int libertas_ethtool_get_eeprom(struct net_device *dev, // mutex_lock(&priv->mutex); - adapter->prdeeprom = - (char *)kmalloc(eeprom->len+sizeof(regctrl), GFP_KERNEL); + adapter->prdeeprom = kmalloc(eeprom->len+sizeof(regctrl), GFP_KERNEL); if (!adapter->prdeeprom) return -ENOMEM; memcpy(adapter->prdeeprom, ®ctrl, sizeof(regctrl)); @@ -72,9 +71,9 @@ static int libertas_ethtool_get_eeprom(struct net_device *dev, regctrl.action, regctrl.offset, regctrl.NOB); ret = libertas_prepare_and_send_command(priv, - cmd_802_11_eeprom_access, + CMD_802_11_EEPROM_ACCESS, regctrl.action, - cmd_option_waitforrsp, 0, + CMD_OPTION_WAITFORRSP, 0, ®ctrl); if (ret) { @@ -110,56 +109,48 @@ static void libertas_ethtool_get_stats(struct net_device * dev, struct ethtool_stats * stats, u64 * data) { wlan_private *priv = dev->priv; + struct cmd_ds_mesh_access mesh_access; + int ret; lbs_deb_enter(LBS_DEB_ETHTOOL); - stats->cmd = ETHTOOL_GSTATS; - BUG_ON(stats->n_stats != MESH_STATS_NUM); - - data[0] = priv->mstats.fwd_drop_rbt; - data[1] = priv->mstats.fwd_drop_ttl; - data[2] = priv->mstats.fwd_drop_noroute; - data[3] = priv->mstats.fwd_drop_nobuf; - 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; + /* 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) + return; + + 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]); + + data[0] = priv->mstats.fwd_drop_rbt; + data[1] = priv->mstats.fwd_drop_ttl; + data[2] = priv->mstats.fwd_drop_noroute; + data[3] = priv->mstats.fwd_drop_nobuf; + 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; lbs_deb_enter(LBS_DEB_ETHTOOL); } -static int libertas_ethtool_get_stats_count(struct net_device * dev) +static int libertas_ethtool_get_sset_count(struct net_device * dev, int sset) { - int ret; - wlan_private *priv = dev->priv; - struct cmd_ds_mesh_access mesh_access; - - 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) { - ret = 0; - goto done; + switch (sset) { + case ETH_SS_STATS: + return MESH_STATS_NUM; + default: + return -EOPNOTSUPP; } - - 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]); - - 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, @@ -186,7 +177,7 @@ struct ethtool_ops libertas_ethtool_ops = { .get_drvinfo = libertas_ethtool_get_drvinfo, .get_eeprom = libertas_ethtool_get_eeprom, .get_eeprom_len = libertas_ethtool_get_eeprom_len, - .get_stats_count = libertas_ethtool_get_stats_count, + .get_sset_count = libertas_ethtool_get_sset_count, .get_ethtool_stats = libertas_ethtool_get_stats, .get_strings = libertas_ethtool_get_strings, }; diff --git a/drivers/net/wireless/libertas/fw.c b/drivers/net/wireless/libertas/fw.c deleted file mode 100644 index 2dc84ff7a54..00000000000 --- a/drivers/net/wireless/libertas/fw.c +++ /dev/null @@ -1,349 +0,0 @@ -/** - * This file contains the initialization for FW and HW - */ -#include <linux/firmware.h> - -#include "host.h" -#include "defs.h" -#include "decl.h" -#include "dev.h" -#include "wext.h" -#include "if_usb.h" - -/** - * @brief This function checks the validity of Boot2/FW image. - * - * @param data pointer to image - * len image length - * @return 0 or -1 - */ -static int check_fwfile_format(u8 *data, u32 totlen) -{ - u32 bincmd, exit; - u32 blksize, offset, len; - int ret; - - ret = 1; - exit = len = 0; - - do { - 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; - data += offset; - len += offset; - if (len >= totlen) - exit = 1; - break; - case FW_HAS_LAST_BLOCK: - exit = 1; - ret = 0; - break; - default: - exit = 1; - break; - } - } while (!exit); - - if (ret) - lbs_pr_err("firmware file format check FAIL\n"); - else - lbs_deb_fw("firmware file format check PASS\n"); - - return ret; -} - -/** - * @brief This function downloads firmware image, gets - * HW spec from firmware and set basic parameters to - * firmware. - * - * @param priv A pointer to wlan_private structure - * @return 0 or -1 - */ -static int wlan_setup_station_hw(wlan_private * priv, char *fw_name) -{ - int ret = -1; - wlan_adapter *adapter = priv->adapter; - - lbs_deb_enter(LBS_DEB_FW); - - if ((ret = request_firmware(&priv->firmware, fw_name, - priv->hotplug_device)) < 0) { - 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)) { - release_firmware(priv->firmware); - goto done; - } - - ret = priv->hw_prog_firmware(priv); - - release_firmware(priv->firmware); - - if (ret) { - lbs_deb_fw("bootloader in invalid state\n"); - ret = -1; - goto done; - } - - /* - * Read MAC address from HW - */ - memset(adapter->current_addr, 0xff, ETH_ALEN); - - ret = libertas_prepare_and_send_command(priv, cmd_get_hw_spec, - 0, cmd_option_waitforrsp, 0, NULL); - - if (ret) { - ret = -1; - goto done; - } - - libertas_set_mac_packet_filter(priv); - - /* Get the supported Data rates */ - ret = libertas_prepare_and_send_command(priv, cmd_802_11_data_rate, - cmd_act_get_tx_rate, - cmd_option_waitforrsp, 0, NULL); - - if (ret) { - ret = -1; - goto done; - } - - ret = 0; -done: - lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret); - return ret; -} - -static int wlan_allocate_adapter(wlan_private * priv) -{ - size_t bufsize; - wlan_adapter *adapter = priv->adapter; - - /* Allocate buffer to store the BSSID list */ - 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 -ENOMEM; - } - - /* Allocate the command buffers */ - libertas_allocate_cmd_buffer(priv); - - memset(&adapter->libertas_ps_confirm_sleep, 0, sizeof(struct PS_CMD_ConfirmSleep)); - adapter->libertas_ps_confirm_sleep.seqnum = cpu_to_le16(++adapter->seqnum); - adapter->libertas_ps_confirm_sleep.command = - cpu_to_le16(cmd_802_11_ps_mode); - adapter->libertas_ps_confirm_sleep.size = - cpu_to_le16(sizeof(struct PS_CMD_ConfirmSleep)); - adapter->libertas_ps_confirm_sleep.result = 0; - adapter->libertas_ps_confirm_sleep.action = - cpu_to_le16(cmd_subcmd_sleep_confirmed); - - return 0; -} - -static void wlan_init_adapter(wlan_private * priv) -{ - wlan_adapter *adapter = priv->adapter; - int i; - - adapter->scanprobes = 0; - - adapter->bcn_avg_factor = DEFAULT_BCN_AVG_FACTOR; - adapter->data_avg_factor = DEFAULT_DATA_AVG_FACTOR; - - /* ATIM params */ - adapter->atimwindow = 0; - - adapter->connect_status = libertas_disconnected; - memset(adapter->current_addr, 0xff, ETH_ALEN); - - /* scan type */ - adapter->scantype = cmd_scan_type_active; - - /* scan mode */ - adapter->scanmode = cmd_bss_type_any; - - /* 802.11 specific */ - adapter->secinfo.wep_enabled = 0; - for (i = 0; i < sizeof(adapter->wep_keys) / sizeof(adapter->wep_keys[0]); - i++) - memset(&adapter->wep_keys[i], 0, sizeof(struct WLAN_802_11_KEY)); - adapter->wep_tx_keyidx = 0; - adapter->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; - adapter->mode = IW_MODE_INFRA; - - 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); - } - - 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; - - adapter->currentpacketfilter = - cmd_act_mac_rx_on | cmd_act_mac_tx_on; - - adapter->radioon = RADIO_ON; - adapter->txantenna = RF_ANTENNA_2; - adapter->rxantenna = RF_ANTENNA_AUTO; - - adapter->is_datarate_auto = 1; - adapter->beaconperiod = MRVDRV_BEACON_INTERVAL; - - // set default value of capinfo. -#define SHORT_PREAMBLE_ALLOWED 1 - memset(&adapter->capinfo, 0, sizeof(adapter->capinfo)); - adapter->capinfo.shortpreamble = SHORT_PREAMBLE_ALLOWED; - - adapter->psmode = wlan802_11powermodecam; - adapter->multipledtim = MRVDRV_DEFAULT_MULTIPLE_DTIM; - - adapter->listeninterval = MRVDRV_DEFAULT_LISTEN_INTERVAL; - - adapter->psstate = PS_STATE_FULL_POWER; - adapter->needtowakeup = 0; - adapter->locallisteninterval = 0; /* default value in firmware will be used */ - - adapter->datarate = 0; // Initially indicate the rate as auto - - adapter->adhoc_grate_enabled = 0; - - adapter->intcounter = 0; - - adapter->currenttxskb = NULL; - adapter->pkttxctrl = 0; - - memset(&adapter->tx_queue_ps, 0, NR_TX_QUEUE*sizeof(struct sk_buff*)); - adapter->tx_queue_idx = 0; - spin_lock_init(&adapter->txqueue_lock); - - return; -} - -static void command_timer_fn(unsigned long data); - -int libertas_init_fw(wlan_private * priv, char *fw_name) -{ - int ret = -1; - wlan_adapter *adapter = priv->adapter; - - lbs_deb_enter(LBS_DEB_FW); - - /* Allocate adapter structure */ - if ((ret = wlan_allocate_adapter(priv)) != 0) - goto done; - - /* init adapter structure */ - wlan_init_adapter(priv); - - /* init timer etc. */ - setup_timer(&adapter->command_timer, command_timer_fn, - (unsigned long)priv); - - /* download fimrware etc. */ - if ((ret = wlan_setup_station_hw(priv, fw_name)) != 0) { - del_timer_sync(&adapter->command_timer); - goto done; - } - - /* init 802.11d */ - libertas_init_11d(priv); - - ret = 0; -done: - lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret); - return ret; -} - -void libertas_free_adapter(wlan_private * priv) -{ - wlan_adapter *adapter = priv->adapter; - - if (!adapter) { - lbs_deb_fw("why double free adapter?\n"); - return; - } - - lbs_deb_fw("free command buffer\n"); - libertas_free_cmd_buffer(priv); - - lbs_deb_fw("free command_timer\n"); - del_timer(&adapter->command_timer); - - 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; -} - -/** - * This function handles the timeout of command sending. - * It will re-send the same command again. - */ -static void command_timer_fn(unsigned long data) -{ - wlan_private *priv = (wlan_private *)data; - wlan_adapter *adapter = priv->adapter; - struct cmd_ctrl_node *ptempnode; - struct cmd_ds_command *cmd; - unsigned long flags; - - ptempnode = adapter->cur_cmd; - if (ptempnode == NULL) { - lbs_deb_fw("ptempnode empty\n"); - return; - } - - cmd = (struct cmd_ds_command *)ptempnode->bufvirtualaddr; - if (!cmd) { - lbs_deb_fw("cmd is NULL\n"); - return; - } - - lbs_deb_fw("command_timer_fn fired, cmd %x\n", cmd->command); - - if (!adapter->fw_ready) - return; - - spin_lock_irqsave(&adapter->driver_lock, flags); - adapter->cur_cmd = NULL; - spin_unlock_irqrestore(&adapter->driver_lock, flags); - - lbs_deb_fw("re-sending same command because of timeout\n"); - libertas_queue_cmd(adapter, ptempnode, 0); - - wake_up_interruptible(&priv->mainthread.waitq); - - return; -} diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h index 7509cc10af3..b37ddbca969 100644 --- a/drivers/net/wireless/libertas/host.h +++ b/drivers/net/wireless/libertas/host.h @@ -20,224 +20,163 @@ #define OID_802_11_TX_RETRYCOUNT 0x0000801D #define OID_802_11D_ENABLE 0x00008020 -#define cmd_option_waitforrsp 0x0002 +#define CMD_OPTION_WAITFORRSP 0x0002 -/** Host command ID */ -#define cmd_code_dnld 0x0002 -#define cmd_get_hw_spec 0x0003 -#define cmd_eeprom_update 0x0004 -#define cmd_802_11_reset 0x0005 -#define cmd_802_11_scan 0x0006 -#define cmd_802_11_get_log 0x000b -#define cmd_mac_multicast_adr 0x0010 -#define cmd_802_11_authenticate 0x0011 -#define cmd_802_11_eeprom_access 0x0059 -#define cmd_802_11_associate 0x0050 -#define cmd_802_11_set_wep 0x0013 -#define cmd_802_11_get_stat 0x0014 -#define cmd_802_3_get_stat 0x0015 -#define cmd_802_11_snmp_mib 0x0016 -#define cmd_mac_reg_map 0x0017 -#define cmd_bbp_reg_map 0x0018 -#define cmd_mac_reg_access 0x0019 -#define cmd_bbp_reg_access 0x001a -#define cmd_rf_reg_access 0x001b -#define cmd_802_11_radio_control 0x001c -#define cmd_802_11_rf_channel 0x001d -#define cmd_802_11_rf_tx_power 0x001e -#define cmd_802_11_rssi 0x001f -#define cmd_802_11_rf_antenna 0x0020 +/** Host command IDs */ -#define cmd_802_11_ps_mode 0x0021 +/* Return command are almost always the same as the host command, but with + * bit 15 set high. There are a few exceptions, though... + */ +#define CMD_RET(cmd) (0x8000 | cmd) -#define cmd_802_11_data_rate 0x0022 -#define cmd_rf_reg_map 0x0023 -#define cmd_802_11_deauthenticate 0x0024 -#define cmd_802_11_reassociate 0x0025 -#define cmd_802_11_disassociate 0x0026 -#define cmd_mac_control 0x0028 -#define cmd_802_11_ad_hoc_start 0x002b -#define cmd_802_11_ad_hoc_join 0x002c +/* Return command convention exceptions: */ +#define CMD_RET_802_11_ASSOCIATE 0x8012 -#define cmd_802_11_query_tkip_reply_cntrs 0x002e -#define cmd_802_11_enable_rsn 0x002f -#define cmd_802_11_pairwise_tsc 0x0036 -#define cmd_802_11_group_tsc 0x0037 -#define cmd_802_11_key_material 0x005e +/* Command codes */ +#define CMD_CODE_DNLD 0x0002 +#define CMD_GET_HW_SPEC 0x0003 +#define CMD_EEPROM_UPDATE 0x0004 +#define CMD_802_11_RESET 0x0005 +#define CMD_802_11_SCAN 0x0006 +#define CMD_802_11_GET_LOG 0x000b +#define CMD_MAC_MULTICAST_ADR 0x0010 +#define CMD_802_11_AUTHENTICATE 0x0011 +#define CMD_802_11_EEPROM_ACCESS 0x0059 +#define CMD_802_11_ASSOCIATE 0x0050 +#define CMD_802_11_SET_WEP 0x0013 +#define CMD_802_11_GET_STAT 0x0014 +#define CMD_802_3_GET_STAT 0x0015 +#define CMD_802_11_SNMP_MIB 0x0016 +#define CMD_MAC_REG_MAP 0x0017 +#define CMD_BBP_REG_MAP 0x0018 +#define CMD_MAC_REG_ACCESS 0x0019 +#define CMD_BBP_REG_ACCESS 0x001a +#define CMD_RF_REG_ACCESS 0x001b +#define CMD_802_11_RADIO_CONTROL 0x001c +#define CMD_802_11_RF_CHANNEL 0x001d +#define CMD_802_11_RF_TX_POWER 0x001e +#define CMD_802_11_RSSI 0x001f +#define CMD_802_11_RF_ANTENNA 0x0020 -#define cmd_802_11_set_afc 0x003c -#define cmd_802_11_get_afc 0x003d +#define CMD_802_11_PS_MODE 0x0021 -#define cmd_802_11_ad_hoc_stop 0x0040 +#define CMD_802_11_DATA_RATE 0x0022 +#define CMD_RF_REG_MAP 0x0023 +#define CMD_802_11_DEAUTHENTICATE 0x0024 +#define CMD_802_11_REASSOCIATE 0x0025 +#define CMD_802_11_DISASSOCIATE 0x0026 +#define CMD_MAC_CONTROL 0x0028 +#define CMD_802_11_AD_HOC_START 0x002b +#define CMD_802_11_AD_HOC_JOIN 0x002c -#define cmd_802_11_beacon_stop 0x0049 +#define CMD_802_11_QUERY_TKIP_REPLY_CNTRS 0x002e +#define CMD_802_11_ENABLE_RSN 0x002f +#define CMD_802_11_PAIRWISE_TSC 0x0036 +#define CMD_802_11_GROUP_TSC 0x0037 +#define CMD_802_11_KEY_MATERIAL 0x005e -#define cmd_802_11_mac_address 0x004D -#define cmd_802_11_eeprom_access 0x0059 +#define CMD_802_11_SET_AFC 0x003c +#define CMD_802_11_GET_AFC 0x003d -#define cmd_802_11_band_config 0x0058 +#define CMD_802_11_AD_HOC_STOP 0x0040 -#define cmd_802_11d_domain_info 0x005b +#define CMD_802_11_BEACON_STOP 0x0049 -#define cmd_802_11_sleep_params 0x0066 +#define CMD_802_11_MAC_ADDRESS 0x004D +#define CMD_802_11_EEPROM_ACCESS 0x0059 -#define cmd_802_11_inactivity_timeout 0x0067 +#define CMD_802_11_BAND_CONFIG 0x0058 -#define cmd_802_11_tpc_cfg 0x0072 -#define cmd_802_11_pwr_cfg 0x0073 +#define CMD_802_11D_DOMAIN_INFO 0x005b -#define cmd_802_11_led_gpio_ctrl 0x004e +#define CMD_802_11_SLEEP_PARAMS 0x0066 -#define cmd_802_11_subscribe_event 0x0075 +#define CMD_802_11_INACTIVITY_TIMEOUT 0x0067 -#define cmd_802_11_rate_adapt_rateset 0x0076 +#define CMD_802_11_TPC_CFG 0x0072 +#define CMD_802_11_PWR_CFG 0x0073 -#define cmd_802_11_tx_rate_query 0x007f +#define CMD_802_11_LED_GPIO_CTRL 0x004e -#define cmd_get_tsf 0x0080 +#define CMD_802_11_SUBSCRIBE_EVENT 0x0075 -#define cmd_bt_access 0x0087 -#define cmd_ret_bt_access 0x8087 +#define CMD_802_11_RATE_ADAPT_RATESET 0x0076 -#define cmd_fwt_access 0x0095 -#define cmd_ret_fwt_access 0x8095 +#define CMD_802_11_TX_RATE_QUERY 0x007f -#define cmd_mesh_access 0x009b -#define cmd_ret_mesh_access 0x809b +#define CMD_GET_TSF 0x0080 + +#define CMD_BT_ACCESS 0x0087 + +#define CMD_FWT_ACCESS 0x0095 + +#define CMD_802_11_MONITOR_MODE 0x0098 + +#define CMD_MESH_ACCESS 0x009b + +#define CMD_SET_BOOT2_VER 0x00a5 /* For the IEEE Power Save */ -#define cmd_subcmd_enter_ps 0x0030 -#define cmd_subcmd_exit_ps 0x0031 -#define cmd_subcmd_sleep_confirmed 0x0034 -#define cmd_subcmd_full_powerdown 0x0035 -#define cmd_subcmd_full_powerup 0x0036 +#define CMD_SUBCMD_ENTER_PS 0x0030 +#define CMD_SUBCMD_EXIT_PS 0x0031 +#define CMD_SUBCMD_SLEEP_CONFIRMED 0x0034 +#define CMD_SUBCMD_FULL_POWERDOWN 0x0035 +#define CMD_SUBCMD_FULL_POWERUP 0x0036 + +#define CMD_ENABLE_RSN 0x0001 +#define CMD_DISABLE_RSN 0x0000 + +#define CMD_ACT_SET 0x0001 +#define CMD_ACT_GET 0x0000 + +#define CMD_ACT_GET_AES (CMD_ACT_GET + 2) +#define CMD_ACT_SET_AES (CMD_ACT_SET + 2) +#define CMD_ACT_REMOVE_AES (CMD_ACT_SET + 3) + +/* Define action or option for CMD_802_11_SET_WEP */ +#define CMD_ACT_ADD 0x0002 +#define CMD_ACT_REMOVE 0x0004 +#define CMD_ACT_USE_DEFAULT 0x0008 + +#define CMD_TYPE_WEP_40_BIT 0x01 +#define CMD_TYPE_WEP_104_BIT 0x02 + +#define CMD_NUM_OF_WEP_KEYS 4 + +#define CMD_WEP_KEY_INDEX_MASK 0x3fff -/* command RET code, MSB is set to 1 */ -#define cmd_ret_hw_spec_info 0x8003 -#define cmd_ret_eeprom_update 0x8004 -#define cmd_ret_802_11_reset 0x8005 -#define cmd_ret_802_11_scan 0x8006 -#define cmd_ret_802_11_get_log 0x800b -#define cmd_ret_mac_control 0x8028 -#define cmd_ret_mac_multicast_adr 0x8010 -#define cmd_ret_802_11_authenticate 0x8011 -#define cmd_ret_802_11_deauthenticate 0x8024 -#define cmd_ret_802_11_associate 0x8012 -#define cmd_ret_802_11_reassociate 0x8025 -#define cmd_ret_802_11_disassociate 0x8026 -#define cmd_ret_802_11_set_wep 0x8013 -#define cmd_ret_802_11_stat 0x8014 -#define cmd_ret_802_3_stat 0x8015 -#define cmd_ret_802_11_snmp_mib 0x8016 -#define cmd_ret_mac_reg_map 0x8017 -#define cmd_ret_bbp_reg_map 0x8018 -#define cmd_ret_rf_reg_map 0x8023 -#define cmd_ret_mac_reg_access 0x8019 -#define cmd_ret_bbp_reg_access 0x801a -#define cmd_ret_rf_reg_access 0x801b -#define cmd_ret_802_11_radio_control 0x801c -#define cmd_ret_802_11_rf_channel 0x801d -#define cmd_ret_802_11_rssi 0x801f -#define cmd_ret_802_11_rf_tx_power 0x801e -#define cmd_ret_802_11_rf_antenna 0x8020 -#define cmd_ret_802_11_ps_mode 0x8021 -#define cmd_ret_802_11_data_rate 0x8022 - -#define cmd_ret_802_11_ad_hoc_start 0x802B -#define cmd_ret_802_11_ad_hoc_join 0x802C - -#define cmd_ret_802_11_query_tkip_reply_cntrs 0x802e -#define cmd_ret_802_11_enable_rsn 0x802f -#define cmd_ret_802_11_pairwise_tsc 0x8036 -#define cmd_ret_802_11_group_tsc 0x8037 -#define cmd_ret_802_11_key_material 0x805e - -#define cmd_enable_rsn 0x0001 -#define cmd_disable_rsn 0x0000 - -#define cmd_act_set 0x0001 -#define cmd_act_get 0x0000 - -#define cmd_act_get_AES (cmd_act_get + 2) -#define cmd_act_set_AES (cmd_act_set + 2) -#define cmd_act_remove_aes (cmd_act_set + 3) - -#define cmd_ret_802_11_set_afc 0x803c -#define cmd_ret_802_11_get_afc 0x803d - -#define cmd_ret_802_11_ad_hoc_stop 0x8040 - -#define cmd_ret_802_11_beacon_stop 0x8049 - -#define cmd_ret_802_11_mac_address 0x804D -#define cmd_ret_802_11_eeprom_access 0x8059 - -#define cmd_ret_802_11_band_config 0x8058 - -#define cmd_ret_802_11_sleep_params 0x8066 - -#define cmd_ret_802_11_inactivity_timeout 0x8067 - -#define cmd_ret_802_11d_domain_info (0x8000 | \ - cmd_802_11d_domain_info) - -#define cmd_ret_802_11_tpc_cfg (cmd_802_11_tpc_cfg | 0x8000) -#define cmd_ret_802_11_pwr_cfg (cmd_802_11_pwr_cfg | 0x8000) - -#define cmd_ret_802_11_led_gpio_ctrl 0x804e - -#define cmd_ret_802_11_subscribe_event (cmd_802_11_subscribe_event | 0x8000) - -#define cmd_ret_802_11_rate_adapt_rateset (cmd_802_11_rate_adapt_rateset | 0x8000) - -#define cmd_rte_802_11_tx_rate_query (cmd_802_11_tx_rate_query | 0x8000) - -#define cmd_ret_get_tsf 0x8080 - -/* Define action or option for cmd_802_11_set_wep */ -#define cmd_act_add 0x0002 -#define cmd_act_remove 0x0004 -#define cmd_act_use_default 0x0008 - -#define cmd_type_wep_40_bit 0x0001 -#define cmd_type_wep_104_bit 0x0002 - -#define cmd_NUM_OF_WEP_KEYS 4 - -#define cmd_WEP_KEY_INDEX_MASK 0x3fff - -/* Define action or option for cmd_802_11_reset */ -#define cmd_act_halt 0x0003 +/* Define action or option for CMD_802_11_RESET */ +#define CMD_ACT_HALT 0x0003 -/* Define action or option for cmd_802_11_scan */ -#define cmd_bss_type_bss 0x0001 -#define cmd_bss_type_ibss 0x0002 -#define cmd_bss_type_any 0x0003 +/* Define action or option for CMD_802_11_SCAN */ +#define CMD_BSS_TYPE_BSS 0x0001 +#define CMD_BSS_TYPE_IBSS 0x0002 +#define CMD_BSS_TYPE_ANY 0x0003 -/* Define action or option for cmd_802_11_scan */ -#define cmd_scan_type_active 0x0000 -#define cmd_scan_type_passive 0x0001 +/* Define action or option for CMD_802_11_SCAN */ +#define CMD_SCAN_TYPE_ACTIVE 0x0000 +#define CMD_SCAN_TYPE_PASSIVE 0x0001 -#define cmd_scan_radio_type_bg 0 +#define CMD_SCAN_RADIO_TYPE_BG 0 -#define cmd_scan_probe_delay_time 0 +#define CMD_SCAN_PROBE_DELAY_TIME 0 -/* Define action or option for cmd_mac_control */ -#define cmd_act_mac_rx_on 0x0001 -#define cmd_act_mac_tx_on 0x0002 -#define cmd_act_mac_loopback_on 0x0004 -#define cmd_act_mac_wep_enable 0x0008 -#define cmd_act_mac_int_enable 0x0010 -#define cmd_act_mac_multicast_enable 0x0020 -#define cmd_act_mac_broadcast_enable 0x0040 -#define cmd_act_mac_promiscuous_enable 0x0080 -#define cmd_act_mac_all_multicast_enable 0x0100 -#define cmd_act_mac_strict_protection_enable 0x0400 +/* Define action or option for CMD_MAC_CONTROL */ +#define CMD_ACT_MAC_RX_ON 0x0001 +#define CMD_ACT_MAC_TX_ON 0x0002 +#define CMD_ACT_MAC_LOOPBACK_ON 0x0004 +#define CMD_ACT_MAC_WEP_ENABLE 0x0008 +#define CMD_ACT_MAC_INT_ENABLE 0x0010 +#define CMD_ACT_MAC_MULTICAST_ENABLE 0x0020 +#define CMD_ACT_MAC_BROADCAST_ENABLE 0x0040 +#define CMD_ACT_MAC_PROMISCUOUS_ENABLE 0x0080 +#define CMD_ACT_MAC_ALL_MULTICAST_ENABLE 0x0100 +#define CMD_ACT_MAC_STRICT_PROTECTION_ENABLE 0x0400 -/* Define action or option for cmd_802_11_radio_control */ -#define cmd_type_auto_preamble 0x0001 -#define cmd_type_short_preamble 0x0002 -#define cmd_type_long_preamble 0x0003 +/* Define action or option for CMD_802_11_RADIO_CONTROL */ +#define CMD_TYPE_AUTO_PREAMBLE 0x0001 +#define CMD_TYPE_SHORT_PREAMBLE 0x0002 +#define CMD_TYPE_LONG_PREAMBLE 0x0003 #define TURN_ON_RF 0x01 #define RADIO_ON 0x01 @@ -248,70 +187,80 @@ #define SET_LONG_PREAMBLE 0x01 /* Define action or option for CMD_802_11_RF_CHANNEL */ -#define cmd_opt_802_11_rf_channel_get 0x00 -#define cmd_opt_802_11_rf_channel_set 0x01 - -/* Define action or option for cmd_802_11_rf_tx_power */ -#define cmd_act_tx_power_opt_get 0x0000 -#define cmd_act_tx_power_opt_set_high 0x8007 -#define cmd_act_tx_power_opt_set_mid 0x8004 -#define cmd_act_tx_power_opt_set_low 0x8000 - -#define cmd_act_tx_power_index_high 0x0007 -#define cmd_act_tx_power_index_mid 0x0004 -#define cmd_act_tx_power_index_low 0x0000 - -/* Define action or option for cmd_802_11_data_rate */ -#define cmd_act_set_tx_auto 0x0000 -#define cmd_act_set_tx_fix_rate 0x0001 -#define cmd_act_get_tx_rate 0x0002 - -#define cmd_act_set_rx 0x0001 -#define cmd_act_set_tx 0x0002 -#define cmd_act_set_both 0x0003 -#define cmd_act_get_rx 0x0004 -#define cmd_act_get_tx 0x0008 -#define cmd_act_get_both 0x000c - -/* Define action or option for cmd_802_11_ps_mode */ -#define cmd_type_cam 0x0000 -#define cmd_type_max_psp 0x0001 -#define cmd_type_fast_psp 0x0002 - -/* Define action or option for cmd_bt_access */ +#define CMD_OPT_802_11_RF_CHANNEL_GET 0x00 +#define CMD_OPT_802_11_RF_CHANNEL_SET 0x01 + +/* Define action or option for CMD_802_11_RF_TX_POWER */ +#define CMD_ACT_TX_POWER_OPT_GET 0x0000 +#define CMD_ACT_TX_POWER_OPT_SET_HIGH 0x8007 +#define CMD_ACT_TX_POWER_OPT_SET_MID 0x8004 +#define CMD_ACT_TX_POWER_OPT_SET_LOW 0x8000 + +#define CMD_ACT_TX_POWER_INDEX_HIGH 0x0007 +#define CMD_ACT_TX_POWER_INDEX_MID 0x0004 +#define CMD_ACT_TX_POWER_INDEX_LOW 0x0000 + +/* Define action or option for CMD_802_11_DATA_RATE */ +#define CMD_ACT_SET_TX_AUTO 0x0000 +#define CMD_ACT_SET_TX_FIX_RATE 0x0001 +#define CMD_ACT_GET_TX_RATE 0x0002 + +#define CMD_ACT_SET_RX 0x0001 +#define CMD_ACT_SET_TX 0x0002 +#define CMD_ACT_SET_BOTH 0x0003 +#define CMD_ACT_GET_RX 0x0004 +#define CMD_ACT_GET_TX 0x0008 +#define CMD_ACT_GET_BOTH 0x000c + +/* Define action or option for CMD_802_11_PS_MODE */ +#define CMD_TYPE_CAM 0x0000 +#define CMD_TYPE_MAX_PSP 0x0001 +#define CMD_TYPE_FAST_PSP 0x0002 + +/* Define action or option for CMD_BT_ACCESS */ enum cmd_bt_access_opts { /* The bt commands start at 5 instead of 1 because the old dft commands * are mapped to 1-4. These old commands are no longer maintained and * should not be called. */ - 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_set_invert, - cmd_act_bt_access_get_invert + 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_SET_INVERT, + CMD_ACT_BT_ACCESS_GET_INVERT }; -/* Define action or option for cmd_fwt_access */ +/* Define action or option for CMD_FWT_ACCESS */ enum cmd_fwt_access_opts { - cmd_act_fwt_access_add = 1, - cmd_act_fwt_access_del, - cmd_act_fwt_access_lookup, - cmd_act_fwt_access_list, - cmd_act_fwt_access_list_route, - cmd_act_fwt_access_list_neighbor, - cmd_act_fwt_access_reset, - cmd_act_fwt_access_cleanup, - cmd_act_fwt_access_time, + CMD_ACT_FWT_ACCESS_ADD = 1, + CMD_ACT_FWT_ACCESS_DEL, + CMD_ACT_FWT_ACCESS_LOOKUP, + CMD_ACT_FWT_ACCESS_LIST, + CMD_ACT_FWT_ACCESS_LIST_route, + CMD_ACT_FWT_ACCESS_LIST_neighbor, + CMD_ACT_FWT_ACCESS_RESET, + CMD_ACT_FWT_ACCESS_CLEANUP, + CMD_ACT_FWT_ACCESS_TIME, }; -/* Define action or option for cmd_mesh_access */ +/* Define action or option for CMD_MESH_ACCESS */ 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_anycast, - cmd_act_mesh_set_anycast, + CMD_ACT_MESH_GET_TTL = 1, + CMD_ACT_MESH_SET_TTL, + CMD_ACT_MESH_GET_STATS, + CMD_ACT_MESH_GET_ANYCAST, + CMD_ACT_MESH_SET_ANYCAST, + CMD_ACT_MESH_SET_LINK_COSTS, + CMD_ACT_MESH_GET_LINK_COSTS, + CMD_ACT_MESH_SET_BCAST_RATE, + CMD_ACT_MESH_GET_BCAST_RATE, + CMD_ACT_MESH_SET_RREQ_DELAY, + CMD_ACT_MESH_GET_RREQ_DELAY, + CMD_ACT_MESH_SET_ROUTE_EXP, + CMD_ACT_MESH_GET_ROUTE_EXP, + CMD_ACT_MESH_SET_AUTOSTART_ENABLED, + CMD_ACT_MESH_GET_AUTOSTART_ENABLED, }; /** Card Event definition */ diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h index 09b898f6719..e1045dc02cc 100644 --- a/drivers/net/wireless/libertas/hostcmd.h +++ b/drivers/net/wireless/libertas/hostcmd.h @@ -83,23 +83,12 @@ struct cmd_ctrl_node { wait_queue_head_t cmdwait_q; }; -/* WLAN_802_11_KEY - * - * Generic structure to hold all key types. key type (WEP40, WEP104, TKIP, AES) - * is determined from the keylength field. - */ -struct WLAN_802_11_KEY { - __le32 len; - __le32 flags; /* KEY_INFO_* from wlan_defs.h */ - u8 key[MRVL_MAX_KEY_WPA_KEY_LENGTH]; - __le16 type; /* KEY_TYPE_* from wlan_defs.h */ -}; - -struct IE_WPA { - u8 elementid; - u8 len; - u8 oui[4]; - __le16 version; +/* Generic structure to hold all key types. */ +struct enc_key { + u16 len; + u16 flags; /* KEY_INFO_* from wlan_defs.h */ + u16 type; /* KEY_TYPE_* from wlan_defs.h */ + u8 key[32]; }; /* wlan_offset_value */ @@ -108,18 +97,6 @@ struct wlan_offset_value { u32 value; }; -struct WLAN_802_11_FIXED_IEs { - __le64 timestamp; - __le16 beaconinterval; - u16 capabilities; /* Actually struct ieeetypes_capinfo */ -}; - -struct WLAN_802_11_VARIABLE_IEs { - u8 elementid; - u8 length; - u8 data[1]; -}; - /* Define general data structure */ /* cmd_DS_GEN */ struct cmd_ds_gen { @@ -131,7 +108,7 @@ struct cmd_ds_gen { #define S_DS_GEN sizeof(struct cmd_ds_gen) /* - * Define data structure for cmd_get_hw_spec + * Define data structure for CMD_GET_HW_SPEC * This structure defines the response for the GET_HW_SPEC command */ struct cmd_ds_get_hw_spec { @@ -178,11 +155,11 @@ struct cmd_ds_802_11_subscribe_event { /* * This scan handle Country Information IE(802.11d compliant) - * Define data structure for cmd_802_11_scan + * Define data structure for CMD_802_11_SCAN */ struct cmd_ds_802_11_scan { u8 bsstype; - u8 BSSID[ETH_ALEN]; + u8 bssid[ETH_ALEN]; u8 tlvbuffer[1]; #if 0 mrvlietypes_ssidparamset_t ssidParamSet; @@ -237,7 +214,7 @@ struct cmd_ds_802_11_deauthenticate { struct cmd_ds_802_11_associate { u8 peerstaaddr[6]; - struct ieeetypes_capinfo capinfo; + __le16 capability; __le16 listeninterval; __le16 bcnperiod; u8 dtimperiod; @@ -260,8 +237,8 @@ struct cmd_ds_802_11_associate_rsp { }; struct cmd_ds_802_11_ad_hoc_result { - u8 PAD[3]; - u8 BSSID[ETH_ALEN]; + u8 pad[3]; + u8 bssid[ETH_ALEN]; }; struct cmd_ds_802_11_set_wep { @@ -428,6 +405,16 @@ struct cmd_ds_802_11_rf_antenna { }; +struct cmd_ds_802_11_monitor_mode { + u16 action; + u16 mode; +}; + +struct cmd_ds_set_boot2_ver { + u16 action; + u16 version; +}; + struct cmd_ds_802_11_ps_mode { __le16 action; __le16 nullpktinterval; @@ -451,8 +438,8 @@ struct PS_CMD_ConfirmSleep { struct cmd_ds_802_11_data_rate { __le16 action; - __le16 reserverd; - u8 datarate[G_SUPPORTED_RATES]; + __le16 reserved; + u8 rates[MAX_RATES]; }; struct cmd_ds_802_11_rate_adapt_rateset { @@ -462,30 +449,30 @@ struct cmd_ds_802_11_rate_adapt_rateset { }; struct cmd_ds_802_11_ad_hoc_start { - u8 SSID[IW_ESSID_MAX_SIZE]; + u8 ssid[IW_ESSID_MAX_SIZE]; u8 bsstype; __le16 beaconperiod; u8 dtimperiod; union IEEEtypes_ssparamset ssparamset; union ieeetypes_phyparamset phyparamset; __le16 probedelay; - struct ieeetypes_capinfo cap; - u8 datarate[G_SUPPORTED_RATES]; + __le16 capability; + u8 rates[MAX_RATES]; u8 tlv_memory_size_pad[100]; } __attribute__ ((packed)); struct adhoc_bssdesc { - u8 BSSID[6]; - u8 SSID[32]; - u8 bsstype; + u8 bssid[6]; + u8 ssid[32]; + u8 type; __le16 beaconperiod; u8 dtimperiod; __le64 timestamp; __le64 localtime; union ieeetypes_phyparamset phyparamset; union IEEEtypes_ssparamset ssparamset; - struct ieeetypes_capinfo cap; - u8 datarates[G_SUPPORTED_RATES]; + __le16 capability; + u8 rates[MAX_RATES]; /* DO NOT ADD ANY FIELDS TO THIS STRUCTURE. It is used below in the * Adhoc join command and will cause a binary layout mismatch with @@ -494,7 +481,7 @@ struct adhoc_bssdesc { } __attribute__ ((packed)); struct cmd_ds_802_11_ad_hoc_join { - struct adhoc_bssdesc bssdescriptor; + struct adhoc_bssdesc bss; __le16 failtimeout; __le16 probedelay; @@ -646,6 +633,7 @@ struct cmd_ds_command { struct cmd_ds_802_11_snmp_mib smib; struct cmd_ds_802_11_rf_tx_power txp; struct cmd_ds_802_11_rf_antenna rant; + struct cmd_ds_802_11_monitor_mode monitor; struct cmd_ds_802_11_data_rate drate; struct cmd_ds_802_11_rate_adapt_rateset rateset; struct cmd_ds_mac_multicast_adr madr; @@ -677,6 +665,7 @@ struct cmd_ds_command { struct cmd_ds_bt_access bt; struct cmd_ds_fwt_access fwt; struct cmd_ds_mesh_access mesh; + struct cmd_ds_set_boot2_ver boot2_ver; struct cmd_ds_get_tsf gettsf; struct cmd_ds_802_11_subscribe_event subscribe_event; } params; diff --git a/drivers/net/wireless/libertas/if_bootcmd.c b/drivers/net/wireless/libertas/if_bootcmd.c deleted file mode 100644 index 8bca306ffad..00000000000 --- a/drivers/net/wireless/libertas/if_bootcmd.c +++ /dev/null @@ -1,40 +0,0 @@ -/** - * This file contains functions used in USB Boot command - * and Boot2/FW update - */ - -#include <linux/delay.h> -#include <linux/firmware.h> -#include <linux/netdevice.h> -#include <linux/usb.h> - -#define DRV_NAME "usb8xxx" - -#include "defs.h" -#include "dev.h" -#include "if_usb.h" - -/** - * @brief This function issues Boot command to the Boot2 code - * @param ivalue 1:Boot from FW by USB-Download - * 2:Boot from FW in EEPROM - * @return 0 - */ -int if_usb_issue_boot_command(wlan_private *priv, int ivalue) -{ - struct usb_card_rec *cardp = priv->card; - struct bootcmdstr sbootcmd; - int i; - - /* Prepare command */ - sbootcmd.u32magicnumber = cpu_to_le32(BOOT_CMD_MAGIC_NUMBER); - sbootcmd.u8cmd_tag = ivalue; - for (i=0; i<11; i++) - sbootcmd.au8dumy[i]=0x00; - memcpy(cardp->bulk_out_buffer, &sbootcmd, sizeof(struct bootcmdstr)); - - /* Issue command */ - usb_tx_block(priv, cardp->bulk_out_buffer, sizeof(struct bootcmdstr)); - - return 0; -} diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c new file mode 100644 index 00000000000..0360cad363a --- /dev/null +++ b/drivers/net/wireless/libertas/if_cs.c @@ -0,0 +1,969 @@ +/* + + Driver for the Marvell 8385 based compact flash WLAN cards. + + (C) 2007 by Holger Schurig <hs4233@mail.mn-solutions.de> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#include <linux/module.h> +#include <linux/delay.h> +#include <linux/moduleparam.h> +#include <linux/firmware.h> +#include <linux/netdevice.h> + +#include <pcmcia/cs_types.h> +#include <pcmcia/cs.h> +#include <pcmcia/cistpl.h> +#include <pcmcia/ds.h> + +#include <linux/io.h> + +#define DRV_NAME "libertas_cs" + +#include "decl.h" +#include "defs.h" +#include "dev.h" + + +/********************************************************************/ +/* Module stuff */ +/********************************************************************/ + +MODULE_AUTHOR("Holger Schurig <hs4233@mail.mn-solutions.de>"); +MODULE_DESCRIPTION("Driver for Marvell 83xx compact flash WLAN cards"); +MODULE_LICENSE("GPL"); + + + +/********************************************************************/ +/* Data structures */ +/********************************************************************/ + +struct if_cs_card { + struct pcmcia_device *p_dev; + wlan_private *priv; + void __iomem *iobase; +}; + + + +/********************************************************************/ +/* Hardware access */ +/********************************************************************/ + +/* This define enables wrapper functions which allow you + to dump all register accesses. You normally won't this, + except for development */ +/* #define DEBUG_IO */ + +#ifdef DEBUG_IO +static int debug_output = 0; +#else +/* This way the compiler optimizes the printk's away */ +#define debug_output 0 +#endif + +static inline unsigned int if_cs_read8(struct if_cs_card *card, uint reg) +{ + unsigned int val = ioread8(card->iobase + reg); + if (debug_output) + printk(KERN_INFO "##inb %08x<%02x\n", reg, val); + return val; +} +static inline unsigned int if_cs_read16(struct if_cs_card *card, uint reg) +{ + unsigned int val = ioread16(card->iobase + reg); + if (debug_output) + printk(KERN_INFO "##inw %08x<%04x\n", reg, val); + return val; +} +static inline void if_cs_read16_rep( + struct if_cs_card *card, + uint reg, + void *buf, + unsigned long count) +{ + if (debug_output) + printk(KERN_INFO "##insw %08x<(0x%lx words)\n", + reg, count); + ioread16_rep(card->iobase + reg, buf, count); +} + +static inline void if_cs_write8(struct if_cs_card *card, uint reg, u8 val) +{ + if (debug_output) + printk(KERN_INFO "##outb %08x>%02x\n", reg, val); + iowrite8(val, card->iobase + reg); +} + +static inline void if_cs_write16(struct if_cs_card *card, uint reg, u16 val) +{ + if (debug_output) + printk(KERN_INFO "##outw %08x>%04x\n", reg, val); + iowrite16(val, card->iobase + reg); +} + +static inline void if_cs_write16_rep( + struct if_cs_card *card, + uint reg, + void *buf, + unsigned long count) +{ + if (debug_output) + printk(KERN_INFO "##outsw %08x>(0x%lx words)\n", + reg, count); + iowrite16_rep(card->iobase + reg, buf, count); +} + + +/* + * I know that polling/delaying is frowned upon. However, this procedure + * with polling is needed while downloading the firmware. At this stage, + * the hardware does unfortunately not create any interrupts. + * + * Fortunately, this function is never used once the firmware is in + * the card. :-) + * + * As a reference, see the "Firmware Specification v5.1", page 18 + * and 19. I did not follow their suggested timing to the word, + * but this works nice & fast anyway. + */ +static int if_cs_poll_while_fw_download(struct if_cs_card *card, uint addr, u8 reg) +{ + int i; + + for (i = 0; i < 500; i++) { + u8 val = if_cs_read8(card, addr); + if (val == reg) + return i; + udelay(100); + } + return -ETIME; +} + + + +/* Host control registers and their bit definitions */ + +#define IF_CS_H_STATUS 0x00000000 +#define IF_CS_H_STATUS_TX_OVER 0x0001 +#define IF_CS_H_STATUS_RX_OVER 0x0002 +#define IF_CS_H_STATUS_DNLD_OVER 0x0004 + +#define IF_CS_H_INT_CAUSE 0x00000002 +#define IF_CS_H_IC_TX_OVER 0x0001 +#define IF_CS_H_IC_RX_OVER 0x0002 +#define IF_CS_H_IC_DNLD_OVER 0x0004 +#define IF_CS_H_IC_HOST_EVENT 0x0008 +#define IF_CS_H_IC_MASK 0x001f + +#define IF_CS_H_INT_MASK 0x00000004 +#define IF_CS_H_IM_MASK 0x001f + +#define IF_CS_H_WRITE_LEN 0x00000014 + +#define IF_CS_H_WRITE 0x00000016 + +#define IF_CS_H_CMD_LEN 0x00000018 + +#define IF_CS_H_CMD 0x0000001A + +#define IF_CS_C_READ_LEN 0x00000024 + +#define IF_CS_H_READ 0x00000010 + +/* Card control registers and their bit definitions */ + +#define IF_CS_C_STATUS 0x00000020 +#define IF_CS_C_S_TX_DNLD_RDY 0x0001 +#define IF_CS_C_S_RX_UPLD_RDY 0x0002 +#define IF_CS_C_S_CMD_DNLD_RDY 0x0004 +#define IF_CS_C_S_CMD_UPLD_RDY 0x0008 +#define IF_CS_C_S_CARDEVENT 0x0010 +#define IF_CS_C_S_MASK 0x001f +#define IF_CS_C_S_STATUS_MASK 0x7f00 +/* The following definitions should be the same as the MRVDRV_ ones */ + +#if MRVDRV_CMD_DNLD_RDY != IF_CS_C_S_CMD_DNLD_RDY +#error MRVDRV_CMD_DNLD_RDY and IF_CS_C_S_CMD_DNLD_RDY not in sync +#endif +#if MRVDRV_CMD_UPLD_RDY != IF_CS_C_S_CMD_UPLD_RDY +#error MRVDRV_CMD_UPLD_RDY and IF_CS_C_S_CMD_UPLD_RDY not in sync +#endif +#if MRVDRV_CARDEVENT != IF_CS_C_S_CARDEVENT +#error MRVDRV_CARDEVENT and IF_CS_C_S_CARDEVENT not in sync +#endif + +#define IF_CS_C_INT_CAUSE 0x00000022 +#define IF_CS_C_IC_MASK 0x001f + +#define IF_CS_C_SQ_READ_LOW 0x00000028 +#define IF_CS_C_SQ_HELPER_OK 0x10 + +#define IF_CS_C_CMD_LEN 0x00000030 + +#define IF_CS_C_CMD 0x00000012 + +#define IF_CS_SCRATCH 0x0000003F + + + +/********************************************************************/ +/* Interrupts */ +/********************************************************************/ + +static inline void if_cs_enable_ints(struct if_cs_card *card) +{ + lbs_deb_enter(LBS_DEB_CS); + if_cs_write16(card, IF_CS_H_INT_MASK, 0); +} + +static inline void if_cs_disable_ints(struct if_cs_card *card) +{ + lbs_deb_enter(LBS_DEB_CS); + if_cs_write16(card, IF_CS_H_INT_MASK, IF_CS_H_IM_MASK); +} + +static irqreturn_t if_cs_interrupt(int irq, void *data) +{ + struct if_cs_card *card = (struct if_cs_card *)data; + u16 int_cause; + + lbs_deb_enter(LBS_DEB_CS); + + int_cause = if_cs_read16(card, IF_CS_C_INT_CAUSE); + if(int_cause == 0x0) { + /* Not for us */ + return IRQ_NONE; + + } else if(int_cause == 0xffff) { + /* Read in junk, the card has probably been removed */ + card->priv->adapter->surpriseremoved = 1; + + } else { + if(int_cause & IF_CS_H_IC_TX_OVER) { + card->priv->dnld_sent = DNLD_RES_RECEIVED; + if (!card->priv->adapter->cur_cmd) + wake_up_interruptible(&card->priv->waitq); + + if (card->priv->adapter->connect_status == LIBERTAS_CONNECTED) + netif_wake_queue(card->priv->dev); + } + + /* clear interrupt */ + if_cs_write16(card, IF_CS_C_INT_CAUSE, int_cause & IF_CS_C_IC_MASK); + } + + libertas_interrupt(card->priv->dev); + + return IRQ_HANDLED; +} + + + + +/********************************************************************/ +/* I/O */ +/********************************************************************/ + +/* + * Called from if_cs_host_to_card to send a command to the hardware + */ +static int if_cs_send_cmd(wlan_private *priv, u8 *buf, u16 nb) +{ + struct if_cs_card *card = (struct if_cs_card *)priv->card; + int ret = -1; + int loops = 0; + + lbs_deb_enter(LBS_DEB_CS); + + /* Is hardware ready? */ + while (1) { + u16 val = if_cs_read16(card, IF_CS_C_STATUS); + if (val & IF_CS_C_S_CMD_DNLD_RDY) + break; + if (++loops > 100) { + lbs_pr_err("card not ready for commands\n"); + goto done; + } + mdelay(1); + } + + if_cs_write16(card, IF_CS_H_CMD_LEN, nb); + + if_cs_write16_rep(card, IF_CS_H_CMD, buf, nb / 2); + /* Are we supposed to transfer an odd amount of bytes? */ + if (nb & 1) + if_cs_write8(card, IF_CS_H_CMD, buf[nb-1]); + + /* "Assert the download over interrupt command in the Host + * status register" */ + if_cs_write16(card, IF_CS_H_STATUS, IF_CS_H_STATUS_DNLD_OVER); + + /* "Assert the download over interrupt command in the Card + * interrupt case register" */ + if_cs_write16(card, IF_CS_H_INT_CAUSE, IF_CS_H_IC_DNLD_OVER); + ret = 0; + +done: + lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret); + return ret; +} + + +/* + * Called from if_cs_host_to_card to send a data to the hardware + */ +static void if_cs_send_data(wlan_private *priv, u8 *buf, u16 nb) +{ + struct if_cs_card *card = (struct if_cs_card *)priv->card; + + lbs_deb_enter(LBS_DEB_CS); + + if_cs_write16(card, IF_CS_H_WRITE_LEN, nb); + + /* write even number of bytes, then odd byte if necessary */ + if_cs_write16_rep(card, IF_CS_H_WRITE, buf, nb / 2); + if (nb & 1) + if_cs_write8(card, IF_CS_H_WRITE, buf[nb-1]); + + if_cs_write16(card, IF_CS_H_STATUS, IF_CS_H_STATUS_TX_OVER); + if_cs_write16(card, IF_CS_H_INT_CAUSE, IF_CS_H_STATUS_TX_OVER); + + lbs_deb_leave(LBS_DEB_CS); +} + + +/* + * Get the command result out of the card. + */ +static int if_cs_receive_cmdres(wlan_private *priv, u8* data, u32 *len) +{ + int ret = -1; + u16 val; + + lbs_deb_enter(LBS_DEB_CS); + + /* is hardware ready? */ + val = if_cs_read16(priv->card, IF_CS_C_STATUS); + if ((val & IF_CS_C_S_CMD_UPLD_RDY) == 0) { + lbs_pr_err("card not ready for CMD\n"); + goto out; + } + + *len = if_cs_read16(priv->card, IF_CS_C_CMD_LEN); + if ((*len == 0) || (*len > MRVDRV_SIZE_OF_CMD_BUFFER)) { + lbs_pr_err("card cmd buffer has invalid # of bytes (%d)\n", *len); + goto out; + } + + /* read even number of bytes, then odd byte if necessary */ + if_cs_read16_rep(priv->card, IF_CS_C_CMD, data, *len/sizeof(u16)); + if (*len & 1) + data[*len-1] = if_cs_read8(priv->card, IF_CS_C_CMD); + + ret = 0; +out: + lbs_deb_leave_args(LBS_DEB_CS, "ret %d, len %d", ret, *len); + return ret; +} + + +static struct sk_buff *if_cs_receive_data(wlan_private *priv) +{ + struct sk_buff *skb = NULL; + u16 len; + u8 *data; + + lbs_deb_enter(LBS_DEB_CS); + + len = if_cs_read16(priv->card, IF_CS_C_READ_LEN); + if (len == 0 || len > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) { + lbs_pr_err("card data buffer has invalid # of bytes (%d)\n", len); + priv->stats.rx_dropped++; + printk(KERN_INFO "##HS %s:%d TODO\n", __FUNCTION__, __LINE__); + goto dat_err; + } + + //TODO: skb = dev_alloc_skb(len+ETH_FRAME_LEN+MRVDRV_SNAP_HEADER_LEN+EXTRA_LEN); + skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE + 2); + if (!skb) + goto out; + skb_put(skb, len); + skb_reserve(skb, 2);/* 16 byte align */ + data = skb->data; + + /* read even number of bytes, then odd byte if necessary */ + if_cs_read16_rep(priv->card, IF_CS_H_READ, data, len/sizeof(u16)); + if (len & 1) + data[len-1] = if_cs_read8(priv->card, IF_CS_H_READ); + +dat_err: + if_cs_write16(priv->card, IF_CS_H_STATUS, IF_CS_H_STATUS_RX_OVER); + if_cs_write16(priv->card, IF_CS_H_INT_CAUSE, IF_CS_H_IC_RX_OVER); + +out: + lbs_deb_leave_args(LBS_DEB_CS, "ret %p", skb); + return skb; +} + + + +/********************************************************************/ +/* Firmware */ +/********************************************************************/ + +/* + * Tries to program the helper firmware. + * + * Return 0 on success + */ +static int if_cs_prog_helper(struct if_cs_card *card) +{ + int ret = 0; + int sent = 0; + u8 scratch; + const struct firmware *fw; + + lbs_deb_enter(LBS_DEB_CS); + + scratch = if_cs_read8(card, IF_CS_SCRATCH); + + /* "If the value is 0x5a, the firmware is already + * downloaded successfully" + */ + if (scratch == 0x5a) + goto done; + + /* "If the value is != 00, it is invalid value of register */ + if (scratch != 0x00) { + ret = -ENODEV; + goto done; + } + + /* TODO: make firmware file configurable */ + ret = request_firmware(&fw, "libertas_cs_helper.fw", + &handle_to_dev(card->p_dev)); + if (ret) { + lbs_pr_err("can't load helper firmware\n"); + ret = -ENODEV; + goto done; + } + lbs_deb_cs("helper size %td\n", fw->size); + + /* "Set the 5 bytes of the helper image to 0" */ + /* Not needed, this contains an ARM branch instruction */ + + for (;;) { + /* "the number of bytes to send is 256" */ + int count = 256; + int remain = fw->size - sent; + + if (remain < count) + count = remain; + /* printk(KERN_INFO "//HS %d loading %d of %d bytes\n", + __LINE__, sent, fw->size); */ + + /* "write the number of bytes to be sent to the I/O Command + * write length register" */ + if_cs_write16(card, IF_CS_H_CMD_LEN, count); + + /* "write this to I/O Command port register as 16 bit writes */ + if (count) + if_cs_write16_rep(card, IF_CS_H_CMD, + &fw->data[sent], + count >> 1); + + /* "Assert the download over interrupt command in the Host + * status register" */ + if_cs_write8(card, IF_CS_H_STATUS, IF_CS_H_STATUS_DNLD_OVER); + + /* "Assert the download over interrupt command in the Card + * interrupt case register" */ + if_cs_write16(card, IF_CS_H_INT_CAUSE, IF_CS_H_IC_DNLD_OVER); + + /* "The host polls the Card Status register ... for 50 ms before + declaring a failure */ + ret = if_cs_poll_while_fw_download(card, IF_CS_C_STATUS, + IF_CS_C_S_CMD_DNLD_RDY); + if (ret < 0) { + lbs_pr_err("can't download helper at 0x%x, ret %d\n", + sent, ret); + goto done; + } + + if (count == 0) + break; + + sent += count; + } + + release_firmware(fw); + ret = 0; + +done: + lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret); + return ret; +} + + +static int if_cs_prog_real(struct if_cs_card *card) +{ + const struct firmware *fw; + int ret = 0; + int retry = 0; + int len = 0; + int sent; + + lbs_deb_enter(LBS_DEB_CS); + + /* TODO: make firmware file configurable */ + ret = request_firmware(&fw, "libertas_cs.fw", + &handle_to_dev(card->p_dev)); + if (ret) { + lbs_pr_err("can't load firmware\n"); + ret = -ENODEV; + goto done; + } + lbs_deb_cs("fw size %td\n", fw->size); + + ret = if_cs_poll_while_fw_download(card, IF_CS_C_SQ_READ_LOW, IF_CS_C_SQ_HELPER_OK); + if (ret < 0) { + int i; + lbs_pr_err("helper firmware doesn't answer\n"); + for (i = 0; i < 0x50; i += 2) + printk(KERN_INFO "## HS %02x: %04x\n", + i, if_cs_read16(card, i)); + goto err_release; + } + + for (sent = 0; sent < fw->size; sent += len) { + len = if_cs_read16(card, IF_CS_C_SQ_READ_LOW); + /* printk(KERN_INFO "//HS %d loading %d of %d bytes\n", + __LINE__, sent, fw->size); */ + if (len & 1) { + retry++; + lbs_pr_info("odd, need to retry this firmware block\n"); + } else { + retry = 0; + } + + if (retry > 20) { + lbs_pr_err("could not download firmware\n"); + ret = -ENODEV; + goto err_release; + } + if (retry) { + sent -= len; + } + + + if_cs_write16(card, IF_CS_H_CMD_LEN, len); + + if_cs_write16_rep(card, IF_CS_H_CMD, + &fw->data[sent], + (len+1) >> 1); + if_cs_write8(card, IF_CS_H_STATUS, IF_CS_H_STATUS_DNLD_OVER); + if_cs_write16(card, IF_CS_H_INT_CAUSE, IF_CS_H_IC_DNLD_OVER); + + ret = if_cs_poll_while_fw_download(card, IF_CS_C_STATUS, + IF_CS_C_S_CMD_DNLD_RDY); + if (ret < 0) { + lbs_pr_err("can't download firmware at 0x%x\n", sent); + goto err_release; + } + } + + ret = if_cs_poll_while_fw_download(card, IF_CS_SCRATCH, 0x5a); + if (ret < 0) { + lbs_pr_err("firmware download failed\n"); + goto err_release; + } + + ret = 0; + goto done; + + +err_release: + release_firmware(fw); + +done: + lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret); + return ret; +} + + + +/********************************************************************/ +/* Callback functions for libertas.ko */ +/********************************************************************/ + +/* Send commands or data packets to the card */ +static int if_cs_host_to_card(wlan_private *priv, u8 type, u8 *buf, u16 nb) +{ + int ret = -1; + + lbs_deb_enter_args(LBS_DEB_CS, "type %d, bytes %d", type, nb); + + switch (type) { + case MVMS_DAT: + priv->dnld_sent = DNLD_DATA_SENT; + if_cs_send_data(priv, buf, nb); + ret = 0; + break; + case MVMS_CMD: + priv->dnld_sent = DNLD_CMD_SENT; + ret = if_cs_send_cmd(priv, buf, nb); + break; + default: + lbs_pr_err("%s: unsupported type %d\n", __FUNCTION__, type); + } + + lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret); + return ret; +} + + +static int if_cs_get_int_status(wlan_private *priv, u8 *ireg) +{ + struct if_cs_card *card = (struct if_cs_card *)priv->card; + //wlan_adapter *adapter = priv->adapter; + int ret = 0; + u16 int_cause; + u8 *cmdbuf; + *ireg = 0; + + lbs_deb_enter(LBS_DEB_CS); + + if (priv->adapter->surpriseremoved) + goto out; + + int_cause = if_cs_read16(card, IF_CS_C_INT_CAUSE) & IF_CS_C_IC_MASK; + if_cs_write16(card, IF_CS_C_INT_CAUSE, int_cause); + + *ireg = if_cs_read16(card, IF_CS_C_STATUS) & IF_CS_C_S_MASK; + + if (!*ireg) + goto sbi_get_int_status_exit; + +sbi_get_int_status_exit: + + /* is there a data packet for us? */ + if (*ireg & IF_CS_C_S_RX_UPLD_RDY) { + struct sk_buff *skb = if_cs_receive_data(priv); + libertas_process_rxed_packet(priv, skb); + *ireg &= ~IF_CS_C_S_RX_UPLD_RDY; + } + + if (*ireg & IF_CS_C_S_TX_DNLD_RDY) { + priv->dnld_sent = DNLD_RES_RECEIVED; + } + + /* Card has a command result for us */ + if (*ireg & IF_CS_C_S_CMD_UPLD_RDY) { + spin_lock(&priv->adapter->driver_lock); + if (!priv->adapter->cur_cmd) { + cmdbuf = priv->upld_buf; + priv->adapter->hisregcpy &= ~IF_CS_C_S_RX_UPLD_RDY; + } else { + cmdbuf = priv->adapter->cur_cmd->bufvirtualaddr; + } + + ret = if_cs_receive_cmdres(priv, cmdbuf, &priv->upld_len); + spin_unlock(&priv->adapter->driver_lock); + if (ret < 0) + lbs_pr_err("could not receive cmd from card\n"); + } + +out: + lbs_deb_leave_args(LBS_DEB_CS, "ret %d, ireg 0x%x, hisregcpy 0x%x", ret, *ireg, priv->adapter->hisregcpy); + return ret; +} + + +static int if_cs_read_event_cause(wlan_private *priv) +{ + lbs_deb_enter(LBS_DEB_CS); + + priv->adapter->eventcause = (if_cs_read16(priv->card, IF_CS_C_STATUS) & IF_CS_C_S_STATUS_MASK) >> 5; + if_cs_write16(priv->card, IF_CS_H_INT_CAUSE, IF_CS_H_IC_HOST_EVENT); + + return 0; +} + + + +/********************************************************************/ +/* Card Services */ +/********************************************************************/ + +/* + * After a card is removed, if_cs_release() will unregister the + * device, and release the PCMCIA configuration. If the device is + * still open, this will be postponed until it is closed. + */ +static void if_cs_release(struct pcmcia_device *p_dev) +{ + struct if_cs_card *card = p_dev->priv; + + lbs_deb_enter(LBS_DEB_CS); + + pcmcia_disable_device(p_dev); + free_irq(p_dev->irq.AssignedIRQ, card); + if (card->iobase) + ioport_unmap(card->iobase); + + lbs_deb_leave(LBS_DEB_CS); +} + + +/* + * This creates an "instance" of the driver, allocating local data + * structures for one device. The device is registered with Card + * Services. + * + * The dev_link structure is initialized, but we don't actually + * configure the card at this point -- we wait until we receive a card + * insertion event. + */ +static int if_cs_probe(struct pcmcia_device *p_dev) +{ + int ret = -ENOMEM; + wlan_private *priv; + struct if_cs_card *card; + /* CIS parsing */ + tuple_t tuple; + cisparse_t parse; + cistpl_cftable_entry_t *cfg = &parse.cftable_entry; + cistpl_io_t *io = &cfg->io; + u_char buf[64]; + + lbs_deb_enter(LBS_DEB_CS); + + card = kzalloc(sizeof(struct if_cs_card), GFP_KERNEL); + if (!card) { + lbs_pr_err("error in kzalloc\n"); + goto out; + } + card->p_dev = p_dev; + p_dev->priv = card; + + p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; + p_dev->irq.Handler = NULL; + p_dev->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID; + + p_dev->conf.Attributes = 0; + p_dev->conf.IntType = INT_MEMORY_AND_IO; + + tuple.Attributes = 0; + tuple.TupleData = buf; + tuple.TupleDataMax = sizeof(buf); + tuple.TupleOffset = 0; + + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + if ((ret = pcmcia_get_first_tuple(p_dev, &tuple)) != 0 || + (ret = pcmcia_get_tuple_data(p_dev, &tuple)) != 0 || + (ret = pcmcia_parse_tuple(p_dev, &tuple, &parse)) != 0) + { + lbs_pr_err("error in pcmcia_get_first_tuple etc\n"); + goto out1; + } + + p_dev->conf.ConfigIndex = cfg->index; + + /* Do we need to allocate an interrupt? */ + if (cfg->irq.IRQInfo1) { + p_dev->conf.Attributes |= CONF_ENABLE_IRQ; + } + + /* IO window settings */ + if (cfg->io.nwin != 1) { + lbs_pr_err("wrong CIS (check number of IO windows)\n"); + ret = -ENODEV; + goto out1; + } + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; + p_dev->io.BasePort1 = io->win[0].base; + p_dev->io.NumPorts1 = io->win[0].len; + + /* This reserves IO space but doesn't actually enable it */ + ret = pcmcia_request_io(p_dev, &p_dev->io); + if (ret) { + lbs_pr_err("error in pcmcia_request_io\n"); + goto out1; + } + + /* + * Allocate an interrupt line. Note that this does not assign + * a handler to the interrupt, unless the 'Handler' member of + * the irq structure is initialized. + */ + if (p_dev->conf.Attributes & CONF_ENABLE_IRQ) { + ret = pcmcia_request_irq(p_dev, &p_dev->irq); + if (ret) { + lbs_pr_err("error in pcmcia_request_irq\n"); + goto out1; + } + } + + /* Initialize io access */ + card->iobase = ioport_map(p_dev->io.BasePort1, p_dev->io.NumPorts1); + if (!card->iobase) { + lbs_pr_err("error in ioport_map\n"); + ret = -EIO; + goto out1; + } + + /* + * This actually configures the PCMCIA socket -- setting up + * the I/O windows and the interrupt mapping, and putting the + * card and host interface into "Memory and IO" mode. + */ + ret = pcmcia_request_configuration(p_dev, &p_dev->conf); + if (ret) { + lbs_pr_err("error in pcmcia_request_configuration\n"); + goto out2; + } + + /* Finally, report what we've done */ + lbs_deb_cs("irq %d, io 0x%04x-0x%04x\n", + p_dev->irq.AssignedIRQ, p_dev->io.BasePort1, + p_dev->io.BasePort1 + p_dev->io.NumPorts1 - 1); + + + /* Load the firmware early, before calling into libertas.ko */ + ret = if_cs_prog_helper(card); + if (ret == 0) + ret = if_cs_prog_real(card); + if (ret) + goto out2; + + /* Make this card known to the libertas driver */ + priv = libertas_add_card(card, &p_dev->dev); + if (!priv) { + ret = -ENOMEM; + goto out2; + } + + /* Store pointers to our call-back functions */ + card->priv = priv; + priv->card = card; + priv->hw_host_to_card = if_cs_host_to_card; + priv->hw_get_int_status = if_cs_get_int_status; + priv->hw_read_event_cause = if_cs_read_event_cause; + + priv->adapter->fw_ready = 1; + + /* Now actually get the IRQ */ + ret = request_irq(p_dev->irq.AssignedIRQ, if_cs_interrupt, + IRQF_SHARED, DRV_NAME, card); + if (ret) { + lbs_pr_err("error in request_irq\n"); + goto out3; + } + + if_cs_enable_ints(card); + + /* And finally bring the card up */ + if (libertas_start_card(priv) != 0) { + lbs_pr_err("could not activate card\n"); + goto out3; + } + + ret = 0; + goto out; + +out3: + libertas_remove_card(priv); +out2: + ioport_unmap(card->iobase); +out1: + pcmcia_disable_device(p_dev); +out: + lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret); + return ret; +} + + +/* + * This deletes a driver "instance". The device is de-registered with + * Card Services. If it has been released, all local data structures + * are freed. Otherwise, the structures will be freed when the device + * is released. + */ +static void if_cs_detach(struct pcmcia_device *p_dev) +{ + struct if_cs_card *card = p_dev->priv; + + lbs_deb_enter(LBS_DEB_CS); + + libertas_stop_card(card->priv); + libertas_remove_card(card->priv); + if_cs_disable_ints(card); + if_cs_release(p_dev); + kfree(card); + + lbs_deb_leave(LBS_DEB_CS); +} + + + +/********************************************************************/ +/* Module initialization */ +/********************************************************************/ + +static struct pcmcia_device_id if_cs_ids[] = { + PCMCIA_DEVICE_MANF_CARD(0x02df, 0x8103), + PCMCIA_DEVICE_NULL, +}; +MODULE_DEVICE_TABLE(pcmcia, if_cs_ids); + + +static struct pcmcia_driver libertas_driver = { + .owner = THIS_MODULE, + .drv = { + .name = DRV_NAME, + }, + .probe = if_cs_probe, + .remove = if_cs_detach, + .id_table = if_cs_ids, +}; + + +static int __init if_cs_init(void) +{ + int ret; + + lbs_deb_enter(LBS_DEB_CS); + ret = pcmcia_register_driver(&libertas_driver); + lbs_deb_leave(LBS_DEB_CS); + return ret; +} + + +static void __exit if_cs_exit(void) +{ + lbs_deb_enter(LBS_DEB_CS); + pcmcia_unregister_driver(&libertas_driver); + lbs_deb_leave(LBS_DEB_CS); +} + + +module_init(if_cs_init); +module_exit(if_cs_exit); diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c index 998317571ec..cb59f46ed12 100644 --- a/drivers/net/wireless/libertas/if_usb.c +++ b/drivers/net/wireless/libertas/if_usb.c @@ -21,7 +21,7 @@ static const char usbdriver_name[] = "usb8xxx"; static u8 *default_fw_name = "usb8388.bin"; -char *libertas_fw_name = NULL; +static char *libertas_fw_name = NULL; module_param_named(fw_name, libertas_fw_name, charp, 0644); /* @@ -44,13 +44,14 @@ 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_prog_firmware(struct usb_card_rec *cardp); 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 *); +static int usb_tx_block(struct usb_card_rec *cardp, u8 *payload, u16 nb); +static void if_usb_free(struct usb_card_rec *cardp); +static int if_usb_submit_rx_urb(struct usb_card_rec *cardp); +static int if_usb_reset_device(struct usb_card_rec *cardp); /** * @brief call back function to handle the status of the URB @@ -59,29 +60,40 @@ static int if_usb_read_event_cause(wlan_private *); */ 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->dev; + struct usb_card_rec *cardp = (struct usb_card_rec *) urb->context; /* handle the transmission complete validations */ - if (urb->status != 0) { - /* print the failure status number for debug */ - lbs_pr_info("URB in failure status: %d\n", urb->status); - } else { + if (urb->status == 0) { + wlan_private *priv = cardp->priv; + /* 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->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)) { - netif_wake_queue(dev); - netif_wake_queue(priv->mesh_dev); + + /* Used for both firmware TX and regular TX. priv isn't + * valid at firmware load time. + */ + if (priv) { + wlan_adapter *adapter = priv->adapter; + struct net_device *dev = priv->dev; + + priv->dnld_sent = DNLD_RES_RECEIVED; + + /* Wake main thread if commands are pending */ + if (!adapter->cur_cmd) + wake_up_interruptible(&priv->waitq); + + if ((adapter->connect_status == LIBERTAS_CONNECTED)) { + netif_wake_queue(dev); + netif_wake_queue(priv->mesh_dev); + } } + } else { + /* print the failure status number for debug */ + lbs_pr_info("URB in failure status: %d\n", urb->status); } return; @@ -92,7 +104,7 @@ static void if_usb_write_bulk_callback(struct urb *urb) * @param cardp pointer usb_card_rec * @return N/A */ -void if_usb_free(struct usb_card_rec *cardp) +static void if_usb_free(struct usb_card_rec *cardp) { lbs_deb_enter(LBS_DEB_USB); @@ -203,21 +215,35 @@ static int if_usb_probe(struct usb_interface *intf, } } + /* Upload firmware */ + cardp->rinfo.cardp = cardp; + if (if_usb_prog_firmware(cardp)) { + lbs_deb_usbd(&udev->dev, "FW upload failed"); + goto err_prog_firmware; + } + if (!(priv = libertas_add_card(cardp, &udev->dev))) - goto dealloc; + goto err_prog_firmware; + + cardp->priv = priv; 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; + cardp->eth_dev = priv->dev; + 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; + priv->boot2_version = udev->descriptor.bcdDevice; - if (libertas_activate_card(priv, libertas_fw_name)) - goto err_activate_card; + /* Delay 200 ms to waiting for the FW ready */ + if_usb_submit_rx_urb(cardp); + msleep_interruptible(200); + priv->adapter->fw_ready = 1; + + if (libertas_start_card(priv)) + goto err_start_card; list_add_tail(&cardp->list, &usb_devices); @@ -226,11 +252,12 @@ static int if_usb_probe(struct usb_interface *intf, return 0; -err_activate_card: +err_start_card: libertas_remove_mesh(priv); err_add_mesh: - free_netdev(priv->dev); - kfree(priv->adapter); + libertas_remove_card(priv); +err_prog_firmware: + if_usb_reset_device(cardp); dealloc: if_usb_free(cardp); @@ -247,21 +274,22 @@ static void if_usb_disconnect(struct usb_interface *intf) { struct usb_card_rec *cardp = usb_get_intfdata(intf); wlan_private *priv = (wlan_private *) cardp->priv; - wlan_adapter *adapter = NULL; - adapter = priv->adapter; + lbs_deb_enter(LBS_DEB_MAIN); - /* - * Update Surprise removed to TRUE - */ - adapter->surpriseremoved = 1; + /* Update Surprise removed to TRUE */ + cardp->surprise_removed = 1; list_del(&cardp->list); - /* card is removed and we can call wlan_remove_card */ - lbs_deb_usbd(&cardp->udev->dev, "call remove card\n"); - libertas_remove_mesh(priv); - libertas_remove_card(priv); + if (priv) { + wlan_adapter *adapter = priv->adapter; + + adapter->surpriseremoved = 1; + libertas_stop_card(priv); + libertas_remove_mesh(priv); + libertas_remove_card(priv); + } /* Unlink and free urb */ if_usb_free(cardp); @@ -269,7 +297,7 @@ static void if_usb_disconnect(struct usb_interface *intf) usb_set_intfdata(intf, NULL); usb_put_dev(interface_to_usbdev(intf)); - return; + lbs_deb_leave(LBS_DEB_MAIN); } /** @@ -277,12 +305,11 @@ static void if_usb_disconnect(struct usb_interface *intf) * @param priv pointer to wlan_private * @return 0 */ -static int if_prog_firmware(wlan_private * priv) +static int if_prog_firmware(struct usb_card_rec *cardp) { - struct usb_card_rec *cardp = priv->card; struct FWData *fwdata; struct fwheader *fwheader; - u8 *firmware = priv->firmware->data; + u8 *firmware = cardp->fw->data; fwdata = kmalloc(sizeof(struct FWData), GFP_ATOMIC); @@ -330,7 +357,7 @@ static int if_prog_firmware(wlan_private * priv) cardp->totalbytes); */ memcpy(cardp->bulk_out_buffer, fwheader, FW_DATA_XMIT_SIZE); - usb_tx_block(priv, cardp->bulk_out_buffer, FW_DATA_XMIT_SIZE); + usb_tx_block(cardp, cardp->bulk_out_buffer, FW_DATA_XMIT_SIZE); } else if (fwdata->fwheader.dnldcmd == cpu_to_le32(FW_HAS_LAST_BLOCK)) { /* @@ -340,7 +367,7 @@ static int if_prog_firmware(wlan_private * priv) "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); + usb_tx_block(cardp, cardp->bulk_out_buffer, FW_DATA_XMIT_SIZE); cardp->fwfinalblk = 1; } @@ -355,17 +382,20 @@ static int if_prog_firmware(wlan_private * priv) return 0; } -static int libertas_do_reset(wlan_private *priv) +static int if_usb_reset_device(struct usb_card_rec *cardp) { int ret; - struct usb_card_rec *cardp = priv->card; + wlan_private * priv = cardp->priv; lbs_deb_enter(LBS_DEB_USB); + /* Try a USB port reset first, if that fails send the reset + * command to the firmware. + */ ret = usb_reset_device(cardp->udev); - if (!ret) { + if (!ret && priv) { msleep(10); - if_usb_reset_device(priv); + ret = libertas_reset_device(priv); msleep(10); } @@ -381,14 +411,12 @@ static int libertas_do_reset(wlan_private *priv) * @param nb data length * @return 0 or -1 */ -int usb_tx_block(wlan_private * priv, u8 * payload, u16 nb) +static int usb_tx_block(struct usb_card_rec *cardp, u8 * payload, u16 nb) { - /* pointer to card structure */ - struct usb_card_rec *cardp = priv->card; int ret = -1; /* check if device is removed */ - if (priv->adapter->surpriseremoved) { + if (cardp->surprise_removed) { lbs_deb_usbd(&cardp->udev->dev, "Device removed\n"); goto tx_ret; } @@ -396,7 +424,7 @@ int usb_tx_block(wlan_private * priv, u8 * payload, u16 nb) usb_fill_bulk_urb(cardp->tx_urb, cardp->udev, usb_sndbulkpipe(cardp->udev, cardp->bulk_out_endpointAddr), - payload, nb, if_usb_write_bulk_callback, priv); + payload, nb, if_usb_write_bulk_callback, cardp); cardp->tx_urb->transfer_flags |= URB_ZERO_PACKET; @@ -413,11 +441,9 @@ tx_ret: return ret; } -static int __if_usb_submit_rx_urb(wlan_private * priv, - void (*callbackfn) - (struct urb *urb)) +static int __if_usb_submit_rx_urb(struct usb_card_rec *cardp, + void (*callbackfn)(struct urb *urb)) { - struct usb_card_rec *cardp = priv->card; struct sk_buff *skb; struct read_cb_info *rinfo = &cardp->rinfo; int ret = -1; @@ -453,22 +479,21 @@ rx_ret: return ret; } -static inline int if_usb_submit_rx_urb_fwload(wlan_private * priv) +static int if_usb_submit_rx_urb_fwload(struct usb_card_rec *cardp) { - return __if_usb_submit_rx_urb(priv, &if_usb_receive_fwload); + return __if_usb_submit_rx_urb(cardp, &if_usb_receive_fwload); } -static inline int if_usb_submit_rx_urb(wlan_private * priv) +static int if_usb_submit_rx_urb(struct usb_card_rec *cardp) { - return __if_usb_submit_rx_urb(priv, &if_usb_receive); + return __if_usb_submit_rx_urb(cardp, &if_usb_receive); } 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->card; + struct usb_card_rec *cardp = (struct usb_card_rec *)rinfo->cardp; struct fwsyncheader *syncfwheader; struct bootcmdrespStr bootcmdresp; @@ -484,7 +509,7 @@ static void if_usb_receive_fwload(struct urb *urb) sizeof(bootcmdresp)); if (le16_to_cpu(cardp->udev->descriptor.bcdDevice) < 0x3106) { kfree_skb(skb); - if_usb_submit_rx_urb_fwload(priv); + if_usb_submit_rx_urb_fwload(cardp); cardp->bootcmdresp = 1; lbs_deb_usbd(&cardp->udev->dev, "Received valid boot command response\n"); @@ -508,7 +533,7 @@ static void if_usb_receive_fwload(struct urb *urb) "Received valid boot command response\n"); } kfree_skb(skb); - if_usb_submit_rx_urb_fwload(priv); + if_usb_submit_rx_urb_fwload(cardp); return; } @@ -544,9 +569,9 @@ static void if_usb_receive_fwload(struct urb *urb) goto exit; } - if_prog_firmware(priv); + if_prog_firmware(cardp); - if_usb_submit_rx_urb_fwload(priv); + if_usb_submit_rx_urb_fwload(cardp); exit: kfree(syncfwheader); @@ -596,11 +621,11 @@ static inline void process_cmdrequest(int recvlength, u8 *recvbuff, * data to clear the interrupt */ if (!priv->adapter->cur_cmd) { cmdbuf = priv->upld_buf; - priv->adapter->hisregcpy &= ~his_cmdupldrdy; + priv->adapter->hisregcpy &= ~MRVDRV_CMD_UPLD_RDY; } else cmdbuf = priv->adapter->cur_cmd->bufvirtualaddr; - cardp->usb_int_cause |= his_cmdupldrdy; + cardp->usb_int_cause |= MRVDRV_CMD_UPLD_RDY; priv->upld_len = (recvlength - MESSAGE_HEADER_LEN); memcpy(cmdbuf, recvbuff + MESSAGE_HEADER_LEN, priv->upld_len); @@ -625,17 +650,19 @@ static inline void process_cmdrequest(int recvlength, u8 *recvbuff, 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->card; + struct usb_card_rec *cardp = (struct usb_card_rec *) rinfo->cardp; + wlan_private * priv = cardp->priv; int recvlength = urb->actual_length; u8 *recvbuff = NULL; - u32 recvtype; + u32 recvtype = 0; lbs_deb_enter(LBS_DEB_USB); if (recvlength) { + __le32 tmp; + if (urb->status) { lbs_deb_usbd(&cardp->udev->dev, "URB status is failed\n"); @@ -644,18 +671,14 @@ static void if_usb_receive(struct urb *urb) } recvbuff = skb->data + IPFIELD_ALIGN_OFFSET; - memcpy(&recvtype, recvbuff, sizeof(u32)); - lbs_deb_usbd(&cardp->udev->dev, - "Recv length = 0x%x\n", recvlength); - lbs_deb_usbd(&cardp->udev->dev, - "Receive type = 0x%X\n", recvtype); - recvtype = le32_to_cpu(recvtype); + memcpy(&tmp, recvbuff, sizeof(u32)); + recvtype = le32_to_cpu(tmp); lbs_deb_usbd(&cardp->udev->dev, - "Receive type after = 0x%X\n", recvtype); + "Recv length = 0x%x, Recv type = 0x%X\n", + recvlength, recvtype); } else if (urb->status) goto rx_exit; - switch (recvtype) { case CMD_TYPE_DATA: process_cmdtypedata(recvlength, skb, cardp, priv); @@ -677,18 +700,20 @@ static void if_usb_receive(struct urb *urb) break; } cardp->usb_event_cause <<= 3; - cardp->usb_int_cause |= his_cardevent; + cardp->usb_int_cause |= MRVDRV_CARDEVENT; kfree_skb(skb); libertas_interrupt(priv->dev); spin_unlock(&priv->adapter->driver_lock); goto rx_exit; default: + lbs_deb_usbd(&cardp->udev->dev, "Unknown command type 0x%X\n", + recvtype); kfree_skb(skb); break; } setup_for_next: - if_usb_submit_rx_urb(priv); + if_usb_submit_rx_urb(cardp); rx_exit: lbs_deb_leave(LBS_DEB_USB); } @@ -703,21 +728,19 @@ rx_exit: */ 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->card; 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); + __le32 tmp = cpu_to_le32(CMD_TYPE_REQUEST); priv->dnld_sent = DNLD_CMD_SENT; memcpy(cardp->bulk_out_buffer, (u8 *) & tmp, MESSAGE_HEADER_LEN); } else { - tmp = cpu_to_le32(CMD_TYPE_DATA); + __le32 tmp = cpu_to_le32(CMD_TYPE_DATA); priv->dnld_sent = DNLD_DATA_SENT; memcpy(cardp->bulk_out_buffer, (u8 *) & tmp, MESSAGE_HEADER_LEN); @@ -725,10 +748,8 @@ static int if_usb_host_to_card(wlan_private * priv, u8 type, u8 * payload, u16 n memcpy((cardp->bulk_out_buffer + MESSAGE_HEADER_LEN), payload, nb); - ret = - usb_tx_block(priv, cardp->bulk_out_buffer, nb + MESSAGE_HEADER_LEN); - - return ret; + return usb_tx_block(cardp, cardp->bulk_out_buffer, + nb + MESSAGE_HEADER_LEN); } /* called with adapter->driver_lock held */ @@ -747,80 +768,109 @@ static int if_usb_get_int_status(wlan_private * priv, u8 * ireg) static int if_usb_read_event_cause(wlan_private * priv) { 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); + if_usb_submit_rx_urb(cardp); return 0; } -static int if_usb_reset_device(wlan_private *priv) +/** + * @brief This function issues Boot command to the Boot2 code + * @param ivalue 1:Boot from FW by USB-Download + * 2:Boot from FW in EEPROM + * @return 0 + */ +static int if_usb_issue_boot_command(struct usb_card_rec *cardp, int ivalue) { - 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; -} + struct bootcmdstr sbootcmd; + int i; -static int if_usb_unregister_dev(wlan_private * priv) -{ - int ret = 0; + /* Prepare command */ + sbootcmd.u32magicnumber = cpu_to_le32(BOOT_CMD_MAGIC_NUMBER); + sbootcmd.u8cmd_tag = ivalue; + for (i=0; i<11; i++) + sbootcmd.au8dumy[i]=0x00; + memcpy(cardp->bulk_out_buffer, &sbootcmd, sizeof(struct bootcmdstr)); - /* Need to send a Reset command to device before USB resources freed - * and wlan_remove_card() called, then device can handle FW download - * again. - */ - if (priv) - if_usb_reset_device(priv); + /* Issue command */ + usb_tx_block(cardp, cardp->bulk_out_buffer, sizeof(struct bootcmdstr)); - return ret; + return 0; } /** - * @brief This function register usb device and initialize parameter - * @param priv pointer to wlan_private - * @return 0 or -1 + * @brief This function checks the validity of Boot2/FW image. + * + * @param data pointer to image + * len image length + * @return 0 or -1 */ -static int if_usb_register_dev(wlan_private * priv) +static int check_fwfile_format(u8 *data, u32 totlen) { - struct usb_card_rec *cardp = (struct usb_card_rec *)priv->card; + u32 bincmd, exit; + u32 blksize, offset, len; + int ret; - lbs_deb_enter(LBS_DEB_USB); + ret = 1; + exit = len = 0; - cardp->priv = priv; - cardp->eth_dev = priv->dev; - priv->hotplug_device = &(cardp->udev->dev); + do { + 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; + data += offset; + len += offset; + if (len >= totlen) + exit = 1; + break; + case FW_HAS_LAST_BLOCK: + exit = 1; + ret = 0; + break; + default: + exit = 1; + break; + } + } while (!exit); - lbs_deb_usbd(&cardp->udev->dev, "udev pointer is at %p\n", - cardp->udev); + if (ret) + lbs_pr_err("firmware file format check FAIL\n"); + else + lbs_deb_fw("firmware file format check PASS\n"); - lbs_deb_leave(LBS_DEB_USB); - return 0; + return ret; } - -static int if_usb_prog_firmware(wlan_private * priv) +static int if_usb_prog_firmware(struct usb_card_rec *cardp) { - struct usb_card_rec *cardp = priv->card; int i = 0; static int reset_count = 10; int ret = 0; lbs_deb_enter(LBS_DEB_USB); - cardp->rinfo.priv = priv; + if ((ret = request_firmware(&cardp->fw, libertas_fw_name, + &cardp->udev->dev)) < 0) { + lbs_pr_err("request_firmware() failed with %#x\n", ret); + lbs_pr_err("firmware %s not found\n", libertas_fw_name); + goto done; + } + + if (check_fwfile_format(cardp->fw->data, cardp->fw->size)) + goto release_fw; restart: - if (if_usb_submit_rx_urb_fwload(priv) < 0) { + if (if_usb_submit_rx_urb_fwload(cardp) < 0) { lbs_deb_usbd(&cardp->udev->dev, "URB submission is failed\n"); ret = -1; - goto done; + goto release_fw; } cardp->bootcmdresp = 0; @@ -828,7 +878,7 @@ restart: int j = 0; i++; /* Issue Boot command = 1, Boot from Download-FW */ - if_usb_issue_boot_command(priv, BOOT_CMD_FW_BY_USB); + if_usb_issue_boot_command(cardp, BOOT_CMD_FW_BY_USB); /* wait for command response */ do { j++; @@ -838,14 +888,13 @@ restart: if (cardp->bootcmdresp == 0) { if (--reset_count >= 0) { - libertas_do_reset(priv); + if_usb_reset_device(cardp); goto restart; } return -1; } i = 0; - priv->adapter->fw_ready = 0; cardp->totalbytes = 0; cardp->fwlastblksent = 0; @@ -855,40 +904,38 @@ restart: cardp->totalbytes = 0; cardp->fwfinalblk = 0; - if_prog_firmware(priv); + if_prog_firmware(cardp); do { lbs_deb_usbd(&cardp->udev->dev,"Wlan sched timeout\n"); i++; msleep_interruptible(100); - if (priv->adapter->surpriseremoved || i >= 20) + if (cardp->surprise_removed || i >= 20) break; } while (!cardp->fwdnldover); if (!cardp->fwdnldover) { lbs_pr_info("failed to load fw, resetting device!\n"); if (--reset_count >= 0) { - libertas_do_reset(priv); + if_usb_reset_device(cardp); goto restart; } lbs_pr_info("FW download failure, time = %d ms\n", i * 100); ret = -1; - goto done; + goto release_fw; } - if_usb_submit_rx_urb(priv); - - /* Delay 200 ms to waiting for the FW ready */ - msleep_interruptible(200); - - priv->adapter->fw_ready = 1; +release_fw: + release_firmware(cardp->fw); + cardp->fw = NULL; done: lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret); return ret; } + #ifdef CONFIG_PM static int if_usb_suspend(struct usb_interface *intf, pm_message_t message) { @@ -900,6 +947,19 @@ static int if_usb_suspend(struct usb_interface *intf, pm_message_t message) if (priv->adapter->psstate != PS_STATE_FULL_POWER) return -1; + if (priv->mesh_dev && !priv->mesh_autostart_enabled) { + /* Mesh autostart must be activated while sleeping + * On resume it will go back to the current state + */ + struct cmd_ds_mesh_access mesh_access; + memset(&mesh_access, 0, sizeof(mesh_access)); + mesh_access.data[0] = cpu_to_le32(1); + libertas_prepare_and_send_command(priv, + CMD_MESH_ACCESS, + CMD_ACT_MESH_SET_AUTOSTART_ENABLED, + CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access); + } + netif_device_detach(cardp->eth_dev); netif_device_detach(priv->mesh_dev); @@ -927,6 +987,19 @@ static int if_usb_resume(struct usb_interface *intf) netif_device_attach(cardp->eth_dev); netif_device_attach(priv->mesh_dev); + if (priv->mesh_dev && !priv->mesh_autostart_enabled) { + /* Mesh autostart was activated while sleeping + * Disable it if appropriate + */ + struct cmd_ds_mesh_access mesh_access; + memset(&mesh_access, 0, sizeof(mesh_access)); + mesh_access.data[0] = cpu_to_le32(0); + libertas_prepare_and_send_command(priv, + CMD_MESH_ACCESS, + CMD_ACT_MESH_SET_AUTOSTART_ENABLED, + CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access); + } + lbs_deb_leave(LBS_DEB_USB); return 0; } @@ -970,8 +1043,10 @@ static void if_usb_exit_module(void) 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); + list_for_each_entry_safe(cardp, cardp_temp, &usb_devices, list) { + libertas_prepare_and_send_command(cardp->priv, CMD_802_11_RESET, + CMD_ACT_HALT, 0, 0, NULL); + } /* API unregisters the driver from USB subsystem */ usb_deregister(&if_usb_driver); diff --git a/drivers/net/wireless/libertas/if_usb.h b/drivers/net/wireless/libertas/if_usb.h index 156bb485e1a..e07a10ed28b 100644 --- a/drivers/net/wireless/libertas/if_usb.h +++ b/drivers/net/wireless/libertas/if_usb.h @@ -38,7 +38,7 @@ struct bootcmdrespStr /* read callback private data */ struct read_cb_info { - wlan_private *priv; + struct usb_card_rec *cardp; struct sk_buff *skb; }; @@ -58,6 +58,7 @@ struct usb_card_rec { int bulk_out_size; u8 bulk_out_endpointAddr; + const struct firmware *fw; u8 CRC_OK; u32 fwseqnum; u32 lastseqnum; @@ -65,6 +66,7 @@ struct usb_card_rec { u32 fwlastblksent; u8 fwdnldover; u8 fwfinalblk; + u8 surprise_removed; u32 usb_event_cause; u8 usb_int_cause; @@ -102,8 +104,4 @@ struct fwsyncheader { #define FW_DATA_XMIT_SIZE \ 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/join.c b/drivers/net/wireless/libertas/join.c index 78ac3064a0b..dc24a05c944 100644 --- a/drivers/net/wireless/libertas/join.c +++ b/drivers/net/wireless/libertas/join.c @@ -17,10 +17,13 @@ #include "dev.h" #include "assoc.h" -#define AD_HOC_CAP_PRIVACY_ON 1 +/* The firmware needs certain bits masked out of the beacon-derviced capability + * field when associating/joining to BSSs. + */ +#define CAPINFO_MASK (~(0xda00)) /** - * @brief This function finds out the common rates between rate1 and rate2. + * @brief This function finds common rates between rate1 and card rates. * * It will fill common rates in rate1 as output if found. * @@ -29,75 +32,87 @@ * * @param adapter A pointer to wlan_adapter structure * @param rate1 the buffer which keeps input and output - * @param rate1_size the size of rate1 buffer - * @param rate2 the buffer which keeps rate2 - * @param rate2_size the size of rate2 buffer. + * @param rate1_size the size of rate1 buffer; new size of buffer on return * * @return 0 or -1 */ -static int get_common_rates(wlan_adapter * adapter, u8 * rate1, - int rate1_size, u8 * rate2, int rate2_size) +static int get_common_rates(wlan_adapter * adapter, u8 * rates, u16 *rates_size) { - u8 *ptr = rate1; - int ret = 0; + u8 *card_rates = libertas_bg_rates; + size_t num_card_rates = sizeof(libertas_bg_rates); + int ret = 0, i, j; u8 tmp[30]; - int i; + size_t tmp_size = 0; - memset(&tmp, 0, sizeof(tmp)); - memcpy(&tmp, rate1, min_t(size_t, rate1_size, sizeof(tmp))); - memset(rate1, 0, rate1_size); - - /* Mask the top bit of the original values */ - for (i = 0; tmp[i] && i < sizeof(tmp); i++) - tmp[i] &= 0x7F; - - for (i = 0; rate2[i] && i < rate2_size; i++) { - /* Check for Card Rate in tmp, excluding the top bit */ - if (strchr(tmp, rate2[i] & 0x7F)) { - /* values match, so copy the Card Rate to rate1 */ - *rate1++ = rate2[i]; + /* For each rate in card_rates that exists in rate1, copy to tmp */ + for (i = 0; card_rates[i] && (i < num_card_rates); i++) { + for (j = 0; rates[j] && (j < *rates_size); j++) { + if (rates[j] == card_rates[i]) + tmp[tmp_size++] = card_rates[i]; } } - 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_deb_join("Tx datarate is set to 0x%X\n", adapter->datarate); + lbs_deb_hex(LBS_DEB_JOIN, "AP rates ", rates, *rates_size); + lbs_deb_hex(LBS_DEB_JOIN, "card rates ", card_rates, num_card_rates); + lbs_deb_hex(LBS_DEB_JOIN, "common rates", tmp, tmp_size); + lbs_deb_join("Tx datarate is currently 0x%X\n", adapter->cur_rate); - if (!adapter->is_datarate_auto) { - while (*ptr) { - if ((*ptr & 0x7f) == adapter->datarate) { - ret = 0; + if (!adapter->auto_rate) { + for (i = 0; i < tmp_size; i++) { + if (tmp[i] == adapter->cur_rate) goto done; - } - ptr++; } - lbs_pr_alert( "Previously set fixed data rate %#x isn't " - "compatible with the network.\n", adapter->datarate); - + lbs_pr_alert("Previously set fixed data rate %#x isn't " + "compatible with the network.\n", adapter->cur_rate); ret = -1; goto done; } - ret = 0; + done: + memset(rates, 0, *rates_size); + *rates_size = min_t(int, tmp_size, *rates_size); + memcpy(rates, tmp, *rates_size); return ret; } -int libertas_send_deauth(wlan_private * priv) + +/** + * @brief Sets the MSB on basic rates as the firmware requires + * + * Scan through an array and set the MSB for basic data rates. + * + * @param rates buffer of data rates + * @param len size of buffer + */ +static void libertas_set_basic_rate_flags(u8 * rates, size_t len) { - wlan_adapter *adapter = priv->adapter; - int ret = 0; + int i; - if (adapter->mode == IW_MODE_INFRA && - adapter->connect_status == libertas_connected) - ret = libertas_send_deauthentication(priv); - else - ret = -ENOTSUPP; + for (i = 0; i < len; i++) { + if (rates[i] == 0x02 || rates[i] == 0x04 || + rates[i] == 0x0b || rates[i] == 0x16) + rates[i] |= 0x80; + } +} - return ret; +/** + * @brief Unsets the MSB on basic rates + * + * Scan through an array and unset the MSB for basic data rates. + * + * @param rates buffer of data rates + * @param len size of buffer + */ +void libertas_unset_basic_rate_flags(u8 * rates, size_t len) +{ + int i; + + for (i = 0; i < len; i++) + rates[i] &= 0x7f; } + /** * @brief Associate to a specific BSS discovered in a scan * @@ -113,23 +128,24 @@ int wlan_associate(wlan_private * priv, struct assoc_request * assoc_req) lbs_deb_enter(LBS_DEB_JOIN); - ret = libertas_prepare_and_send_command(priv, cmd_802_11_authenticate, - 0, cmd_option_waitforrsp, + ret = libertas_prepare_and_send_command(priv, CMD_802_11_AUTHENTICATE, + 0, CMD_OPTION_WAITFORRSP, 0, assoc_req->bss.bssid); if (ret) goto done; /* set preamble to firmware */ - if (adapter->capinfo.shortpreamble && assoc_req->bss.cap.shortpreamble) - adapter->preamble = cmd_type_short_preamble; + if ( (adapter->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) + && (assoc_req->bss.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)) + adapter->preamble = CMD_TYPE_SHORT_PREAMBLE; else - adapter->preamble = cmd_type_long_preamble; + adapter->preamble = CMD_TYPE_LONG_PREAMBLE; libertas_set_radio_control(priv); - ret = libertas_prepare_and_send_command(priv, cmd_802_11_associate, - 0, cmd_option_waitforrsp, 0, assoc_req); + ret = libertas_prepare_and_send_command(priv, CMD_802_11_ASSOCIATE, + 0, CMD_OPTION_WAITFORRSP, 0, assoc_req); done: lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret); @@ -150,12 +166,12 @@ int libertas_start_adhoc_network(wlan_private * priv, struct assoc_request * ass adapter->adhoccreate = 1; - if (!adapter->capinfo.shortpreamble) { - lbs_deb_join("AdhocStart: Long preamble\n"); - adapter->preamble = cmd_type_long_preamble; - } else { + if (adapter->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) { lbs_deb_join("AdhocStart: Short preamble\n"); - adapter->preamble = cmd_type_short_preamble; + adapter->preamble = CMD_TYPE_SHORT_PREAMBLE; + } else { + lbs_deb_join("AdhocStart: Long preamble\n"); + adapter->preamble = CMD_TYPE_LONG_PREAMBLE; } libertas_set_radio_control(priv); @@ -163,8 +179,8 @@ int libertas_start_adhoc_network(wlan_private * priv, struct assoc_request * ass 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, assoc_req); + ret = libertas_prepare_and_send_command(priv, CMD_802_11_AD_HOC_START, + 0, CMD_OPTION_WAITFORRSP, 0, assoc_req); return ret; } @@ -194,25 +210,37 @@ int libertas_join_adhoc_network(wlan_private * priv, struct assoc_request * asso bss->ssid_len); /* check if the requested SSID is already joined */ - if (adapter->curbssparams.ssid_len + 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_deb_join( - "ADHOC_J_CMD: New ad-hoc SSID is the same as current, " - "not attempting to re-join"); - return -1; + && (adapter->mode == IW_MODE_ADHOC) + && (adapter->connect_status == LIBERTAS_CONNECTED)) { + union iwreq_data wrqu; + + lbs_deb_join("ADHOC_J_CMD: New ad-hoc SSID is the same as " + "current, not attempting to re-join"); + + /* Send the re-association event though, because the association + * request really was successful, even if just a null-op. + */ + 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->dev, SIOCGIWAP, &wrqu, NULL); + goto out; } - /*Use shortpreamble only when both creator and card supports + /* Use shortpreamble only when both creator and card supports short preamble */ - if (!bss->cap.shortpreamble || !adapter->capinfo.shortpreamble) { + if ( !(bss->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) + || !(adapter->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)) { lbs_deb_join("AdhocJoin: Long preamble\n"); - adapter->preamble = cmd_type_long_preamble; + adapter->preamble = CMD_TYPE_LONG_PREAMBLE; } else { lbs_deb_join("AdhocJoin: Short preamble\n"); - adapter->preamble = cmd_type_short_preamble; + adapter->preamble = CMD_TYPE_SHORT_PREAMBLE; } libertas_set_radio_control(priv); @@ -222,17 +250,18 @@ int libertas_join_adhoc_network(wlan_private * priv, struct assoc_request * asso adapter->adhoccreate = 0; - ret = libertas_prepare_and_send_command(priv, cmd_802_11_ad_hoc_join, - 0, cmd_option_waitforrsp, + ret = libertas_prepare_and_send_command(priv, CMD_802_11_AD_HOC_JOIN, + 0, CMD_OPTION_WAITFORRSP, OID_802_11_SSID, assoc_req); +out: return ret; } int libertas_stop_adhoc_network(wlan_private * priv) { - return libertas_prepare_and_send_command(priv, cmd_802_11_ad_hoc_stop, - 0, cmd_option_waitforrsp, 0, NULL); + return libertas_prepare_and_send_command(priv, CMD_802_11_AD_HOC_STOP, + 0, CMD_OPTION_WAITFORRSP, 0, NULL); } /** @@ -243,8 +272,8 @@ int libertas_stop_adhoc_network(wlan_private * priv) */ int libertas_send_deauthentication(wlan_private * priv) { - return libertas_prepare_and_send_command(priv, cmd_802_11_deauthenticate, - 0, cmd_option_waitforrsp, 0, NULL); + return libertas_prepare_and_send_command(priv, CMD_802_11_DEAUTHENTICATE, + 0, CMD_OPTION_WAITFORRSP, 0, NULL); } /** @@ -264,10 +293,11 @@ int libertas_cmd_80211_authenticate(wlan_private * priv, struct cmd_ds_802_11_authenticate *pauthenticate = &cmd->params.auth; int ret = -1; u8 *bssid = pdata_buf; + DECLARE_MAC_BUF(mac); lbs_deb_enter(LBS_DEB_JOIN); - cmd->command = cpu_to_le16(cmd_802_11_authenticate); + cmd->command = cpu_to_le16(CMD_802_11_AUTHENTICATE); cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_authenticate) + S_DS_GEN); @@ -290,8 +320,8 @@ int libertas_cmd_80211_authenticate(wlan_private * priv, memcpy(pauthenticate->macaddr, bssid, ETH_ALEN); - lbs_deb_join("AUTH_CMD: BSSID is : " MAC_FMT " auth=0x%X\n", - MAC_ARG(bssid), pauthenticate->authtype); + lbs_deb_join("AUTH_CMD: BSSID is : %s auth=0x%X\n", + print_mac(mac, bssid), pauthenticate->authtype); ret = 0; out: @@ -307,7 +337,7 @@ int libertas_cmd_80211_deauthenticate(wlan_private * priv, lbs_deb_enter(LBS_DEB_JOIN); - cmd->command = cpu_to_le16(cmd_802_11_deauthenticate); + cmd->command = cpu_to_le16(CMD_802_11_DEAUTHENTICATE); cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_deauthenticate) + S_DS_GEN); @@ -330,9 +360,7 @@ int libertas_cmd_80211_associate(wlan_private * priv, int ret = 0; 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, tmplen; struct mrvlietypes_ssidparamset *ssid; struct mrvlietypes_phyparamset *phy; @@ -349,15 +377,15 @@ int libertas_cmd_80211_associate(wlan_private * priv, goto done; } - cmd->command = cpu_to_le16(cmd_802_11_associate); + cmd->command = cpu_to_le16(CMD_802_11_ASSOCIATE); memcpy(passo->peerstaaddr, bss->bssid, sizeof(passo->peerstaaddr)); pos += sizeof(passo->peerstaaddr); /* set the listen interval */ - passo->listeninterval = cpu_to_le16(adapter->listeninterval); + passo->listeninterval = cpu_to_le16(MRVDRV_DEFAULT_LISTEN_INTERVAL); - pos += sizeof(passo->capinfo); + pos += sizeof(passo->capability); pos += sizeof(passo->listeninterval); pos += sizeof(passo->bcnperiod); pos += sizeof(passo->dtimperiod); @@ -386,23 +414,24 @@ int libertas_cmd_80211_associate(wlan_private * priv, rates = (struct mrvlietypes_ratesparamset *) pos; rates->header.type = cpu_to_le16(TLV_TYPE_RATES); - - memcpy(&rates->rates, &bss->libertas_supported_rates, WLAN_SUPPORTED_RATES); - - card_rates = libertas_supported_rates; - card_rates_size = sizeof(libertas_supported_rates); - - if (get_common_rates(adapter, rates->rates, WLAN_SUPPORTED_RATES, - card_rates, card_rates_size)) { + memcpy(&rates->rates, &bss->rates, MAX_RATES); + tmplen = MAX_RATES; + if (get_common_rates(adapter, rates->rates, &tmplen)) { ret = -1; goto done; } - - tmplen = min_t(size_t, strlen(rates->rates), WLAN_SUPPORTED_RATES); - adapter->curbssparams.numofrates = tmplen; - pos += sizeof(rates->header) + tmplen; rates->header.len = cpu_to_le16(tmplen); + lbs_deb_join("ASSOC_CMD: num rates = %u\n", tmplen); + + /* Copy the infra. association rates into Current BSS state structure */ + memset(&adapter->curbssparams.rates, 0, sizeof(adapter->curbssparams.rates)); + memcpy(&adapter->curbssparams.rates, &rates->rates, tmplen); + + /* Set MSB on basic rates as the firmware requires, but _after_ + * copying to current bss rates. + */ + libertas_set_basic_rate_flags(rates->rates, tmplen); if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) { rsn = (struct mrvlietypes_rsnparamset *) pos; @@ -411,7 +440,7 @@ int libertas_cmd_80211_associate(wlan_private * priv, 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, + lbs_deb_hex(LBS_DEB_JOIN, "ASSOC_CMD: RSN IE", (u8 *) rsn, sizeof(rsn->header) + tmplen); pos += sizeof(rsn->header) + tmplen; } @@ -419,20 +448,6 @@ int libertas_cmd_80211_associate(wlan_private * priv, /* update curbssparams */ 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), - cpu_to_le16(rates->header.len))); - - lbs_deb_join("ASSOC_CMD: rates->header.len = %d\n", - cpu_to_le16(rates->header.len)); - - /* set IBSS field */ - if (bss->mode == IW_MODE_INFRA) { -#define CAPINFO_ESS_MODE 1 - passo->capinfo.ess = CAPINFO_ESS_MODE; - } - if (libertas_parse_dnld_countryinfo_11d(priv, bss)) { ret = -1; goto done; @@ -440,12 +455,13 @@ 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, &bss->cap, sizeof(passo->capinfo)); - tmpcap &= CAPINFO_MASK; - lbs_deb_join("ASSOC_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n", + /* set the capability info */ + tmpcap = (bss->capability & CAPINFO_MASK); + if (bss->mode == IW_MODE_INFRA) + tmpcap |= WLAN_CAPABILITY_ESS; + passo->capability = cpu_to_le16(tmpcap); + lbs_deb_join("ASSOC_CMD: capability=%4X CAPINFO_MASK=%4X\n", tmpcap, CAPINFO_MASK); - memcpy(&passo->capinfo, &tmpcap, sizeof(passo->capinfo)); done: lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret); @@ -459,8 +475,9 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv, struct cmd_ds_802_11_ad_hoc_start *adhs = &cmd->params.ads; int ret = 0; int cmdappendsize = 0; - int i; struct assoc_request * assoc_req = pdata_buf; + u16 tmpcap = 0; + size_t ratesize = 0; lbs_deb_enter(LBS_DEB_JOIN); @@ -469,7 +486,7 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv, goto done; } - cmd->command = cpu_to_le16(cmd_802_11_ad_hoc_start); + cmd->command = cpu_to_le16(CMD_802_11_AD_HOC_START); /* * Fill in the parameters for 2 data structures: @@ -483,17 +500,17 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv, * and operational rates. */ - memset(adhs->SSID, 0, IW_ESSID_MAX_SIZE); - memcpy(adhs->SSID, assoc_req->ssid, assoc_req->ssid_len); + memset(adhs->ssid, 0, IW_ESSID_MAX_SIZE); + memcpy(adhs->ssid, assoc_req->ssid, assoc_req->ssid_len); 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; + adhs->bsstype = CMD_BSS_TYPE_IBSS; adapter->mode = IW_MODE_ADHOC; - adhs->beaconperiod = cpu_to_le16(adapter->beaconperiod); + adhs->beaconperiod = cpu_to_le16(MRVDRV_BEACON_INTERVAL); /* set Physical param set */ #define DS_PARA_IE_ID 3 @@ -515,45 +532,36 @@ 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 = cpu_to_le16(adapter->atimwindow); + adhs->ssparamset.ibssparamset.atimwindow = 0; /* set capability info */ - adhs->cap.ess = 0; - adhs->cap.ibss = 1; - - /* probedelay */ - adhs->probedelay = cpu_to_le16(cmd_scan_probe_delay_time); - - /* set up privacy in adapter->scantable[i] */ + tmpcap = WLAN_CAPABILITY_IBSS; 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; + tmpcap |= WLAN_CAPABILITY_PRIVACY; } else { lbs_deb_join("ADHOC_S_CMD: WEP disabled, setting privacy off\n"); } + adhs->capability = cpu_to_le16(tmpcap); - memset(adhs->datarate, 0, sizeof(adhs->datarate)); - - if (adapter->adhoc_grate_enabled) { - memcpy(adhs->datarate, libertas_adhoc_rates_g, - min(sizeof(adhs->datarate), sizeof(libertas_adhoc_rates_g))); - } else { - memcpy(adhs->datarate, libertas_adhoc_rates_b, - min(sizeof(adhs->datarate), sizeof(libertas_adhoc_rates_b))); - } - - /* Find the last non zero */ - for (i = 0; i < sizeof(adhs->datarate) && adhs->datarate[i]; i++) ; + /* probedelay */ + adhs->probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME); - adapter->curbssparams.numofrates = i; + memset(adhs->rates, 0, sizeof(adhs->rates)); + ratesize = min(sizeof(adhs->rates), sizeof(libertas_bg_rates)); + memcpy(adhs->rates, libertas_bg_rates, ratesize); /* Copy the ad-hoc creating rates into Current BSS state structure */ - memcpy(&adapter->curbssparams.datarates, - &adhs->datarate, adapter->curbssparams.numofrates); + memset(&adapter->curbssparams.rates, 0, sizeof(adapter->curbssparams.rates)); + memcpy(&adapter->curbssparams.rates, &adhs->rates, ratesize); + + /* Set MSB on basic rates as the firmware requires, but _after_ + * copying to current bss rates. + */ + libertas_set_basic_rate_flags(adhs->rates, ratesize); lbs_deb_join("ADHOC_S_CMD: rates=%02x %02x %02x %02x \n", - adhs->datarate[0], adhs->datarate[1], - adhs->datarate[2], adhs->datarate[3]); + adhs->rates[0], adhs->rates[1], adhs->rates[2], adhs->rates[3]); lbs_deb_join("ADHOC_S_CMD: AD HOC Start command is ready\n"); @@ -575,7 +583,7 @@ done: int libertas_cmd_80211_ad_hoc_stop(wlan_private * priv, struct cmd_ds_command *cmd) { - cmd->command = cpu_to_le16(cmd_802_11_ad_hoc_stop); + cmd->command = cpu_to_le16(CMD_802_11_AD_HOC_STOP); cmd->size = cpu_to_le16(S_DS_GEN); return 0; @@ -585,101 +593,84 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv, struct cmd_ds_command *cmd, void *pdata_buf) { wlan_adapter *adapter = priv->adapter; - struct cmd_ds_802_11_ad_hoc_join *padhocjoin = &cmd->params.adj; + struct cmd_ds_802_11_ad_hoc_join *join_cmd = &cmd->params.adj; struct assoc_request * assoc_req = pdata_buf; struct bss_descriptor *bss = &assoc_req->bss; int cmdappendsize = 0; int ret = 0; - u8 *card_rates; - int card_rates_size; - u16 tmpcap; - int i; + u16 ratesize = 0; + DECLARE_MAC_BUF(mac); lbs_deb_enter(LBS_DEB_JOIN); - cmd->command = cpu_to_le16(cmd_802_11_ad_hoc_join); + cmd->command = cpu_to_le16(CMD_802_11_AD_HOC_JOIN); - padhocjoin->bssdescriptor.bsstype = cmd_bss_type_ibss; + join_cmd->bss.type = CMD_BSS_TYPE_IBSS; + join_cmd->bss.beaconperiod = cpu_to_le16(bss->beaconperiod); - padhocjoin->bssdescriptor.beaconperiod = cpu_to_le16(bss->beaconperiod); + memcpy(&join_cmd->bss.bssid, &bss->bssid, ETH_ALEN); + memcpy(&join_cmd->bss.ssid, &bss->ssid, bss->ssid_len); - memcpy(&padhocjoin->bssdescriptor.BSSID, &bss->bssid, ETH_ALEN); - memcpy(&padhocjoin->bssdescriptor.SSID, &bss->ssid, bss->ssid_len); + memcpy(&join_cmd->bss.phyparamset, &bss->phyparamset, + sizeof(union ieeetypes_phyparamset)); - memcpy(&padhocjoin->bssdescriptor.phyparamset, - &bss->phyparamset, sizeof(union ieeetypes_phyparamset)); - - memcpy(&padhocjoin->bssdescriptor.ssparamset, - &bss->ssparamset, sizeof(union IEEEtypes_ssparamset)); - - memcpy(&tmpcap, &bss->cap, sizeof(struct ieeetypes_capinfo)); - tmpcap &= CAPINFO_MASK; + memcpy(&join_cmd->bss.ssparamset, &bss->ssparamset, + sizeof(union IEEEtypes_ssparamset)); + join_cmd->bss.capability = cpu_to_le16(bss->capability & CAPINFO_MASK); lbs_deb_join("ADHOC_J_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n", - tmpcap, CAPINFO_MASK); - memcpy(&padhocjoin->bssdescriptor.cap, &tmpcap, - sizeof(struct ieeetypes_capinfo)); + bss->capability, CAPINFO_MASK); /* information on BSSID descriptor passed to FW */ lbs_deb_join( - "ADHOC_J_CMD: BSSID = " MAC_FMT ", SSID = '%s'\n", - MAC_ARG(padhocjoin->bssdescriptor.BSSID), - padhocjoin->bssdescriptor.SSID); + "ADHOC_J_CMD: BSSID = %s, SSID = '%s'\n", + print_mac(mac, join_cmd->bss.bssid), + join_cmd->bss.ssid); /* failtimeout */ - padhocjoin->failtimeout = cpu_to_le16(MRVDRV_ASSOCIATION_TIME_OUT); + join_cmd->failtimeout = cpu_to_le16(MRVDRV_ASSOCIATION_TIME_OUT); /* probedelay */ - 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, bss->datarates, - min(sizeof(padhocjoin->bssdescriptor.datarates), - sizeof(bss->datarates))); - - card_rates = libertas_supported_rates; - card_rates_size = sizeof(libertas_supported_rates); + join_cmd->probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME); adapter->curbssparams.channel = bss->channel; - if (get_common_rates(adapter, padhocjoin->bssdescriptor.datarates, - sizeof(padhocjoin->bssdescriptor.datarates), - card_rates, card_rates_size)) { + /* Copy Data rates from the rates recorded in scan response */ + memset(join_cmd->bss.rates, 0, sizeof(join_cmd->bss.rates)); + ratesize = min_t(u16, sizeof(join_cmd->bss.rates), MAX_RATES); + memcpy(join_cmd->bss.rates, bss->rates, ratesize); + if (get_common_rates(adapter, join_cmd->bss.rates, &ratesize)) { lbs_deb_join("ADHOC_J_CMD: get_common_rates returns error.\n"); ret = -1; goto done; } - /* Find the last non zero */ - for (i = 0; i < sizeof(padhocjoin->bssdescriptor.datarates) - && padhocjoin->bssdescriptor.datarates[i]; i++) ; - - adapter->curbssparams.numofrates = i; + /* Copy the ad-hoc creating rates into Current BSS state structure */ + memset(&adapter->curbssparams.rates, 0, sizeof(adapter->curbssparams.rates)); + memcpy(&adapter->curbssparams.rates, join_cmd->bss.rates, ratesize); - /* - * Copy the adhoc joining rates to Current BSS State structure + /* Set MSB on basic rates as the firmware requires, but _after_ + * copying to current bss rates. */ - memcpy(adapter->curbssparams.datarates, - padhocjoin->bssdescriptor.datarates, - adapter->curbssparams.numofrates); + libertas_set_basic_rate_flags(join_cmd->bss.rates, ratesize); - padhocjoin->bssdescriptor.ssparamset.ibssparamset.atimwindow = + join_cmd->bss.ssparamset.ibssparamset.atimwindow = cpu_to_le16(bss->atimwindow); if (assoc_req->secinfo.wep_enabled) { - padhocjoin->bssdescriptor.cap.privacy = AD_HOC_CAP_PRIVACY_ON; + u16 tmp = le16_to_cpu(join_cmd->bss.capability); + tmp |= WLAN_CAPABILITY_PRIVACY; + join_cmd->bss.capability = cpu_to_le16(tmp); } - if (adapter->psmode == wlan802_11powermodemax_psp) { + if (adapter->psmode == WLAN802_11POWERMODEMAX_PSP) { /* wake up first */ __le32 Localpsmode; - Localpsmode = cpu_to_le32(wlan802_11powermodecam); + Localpsmode = cpu_to_le32(WLAN802_11POWERMODECAM); ret = libertas_prepare_and_send_command(priv, - cmd_802_11_ps_mode, - cmd_act_set, + CMD_802_11_PS_MODE, + CMD_ACT_SET, 0, 0, &Localpsmode); if (ret) { @@ -709,6 +700,7 @@ int libertas_ret_80211_associate(wlan_private * priv, union iwreq_data wrqu; struct ieeetypes_assocrsp *passocrsp; struct bss_descriptor * bss; + u16 status_code; lbs_deb_enter(LBS_DEB_JOIN); @@ -721,21 +713,65 @@ int libertas_ret_80211_associate(wlan_private * priv, passocrsp = (struct ieeetypes_assocrsp *) & resp->params; - if (le16_to_cpu(passocrsp->statuscode)) { - libertas_mac_event_disconnected(priv); + /* + * Older FW versions map the IEEE 802.11 Status Code in the association + * response to the following values returned in passocrsp->statuscode: + * + * IEEE Status Code Marvell Status Code + * 0 -> 0x0000 ASSOC_RESULT_SUCCESS + * 13 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED + * 14 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED + * 15 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED + * 16 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED + * others -> 0x0003 ASSOC_RESULT_REFUSED + * + * Other response codes: + * 0x0001 -> ASSOC_RESULT_INVALID_PARAMETERS (unused) + * 0x0002 -> ASSOC_RESULT_TIMEOUT (internal timer expired waiting for + * association response from the AP) + */ - lbs_deb_join("ASSOC_RESP: Association failed, status code = %d\n", - le16_to_cpu(passocrsp->statuscode)); + status_code = le16_to_cpu(passocrsp->statuscode); + switch (status_code) { + case 0x00: + lbs_deb_join("ASSOC_RESP: Association succeeded\n"); + break; + case 0x01: + lbs_deb_join("ASSOC_RESP: Association failed; invalid " + "parameters (status code %d)\n", status_code); + break; + case 0x02: + lbs_deb_join("ASSOC_RESP: Association failed; internal timer " + "expired while waiting for the AP (status code %d)" + "\n", status_code); + break; + case 0x03: + lbs_deb_join("ASSOC_RESP: Association failed; association " + "was refused by the AP (status code %d)\n", + status_code); + break; + case 0x04: + lbs_deb_join("ASSOC_RESP: Association failed; authentication " + "was refused by the AP (status code %d)\n", + status_code); + break; + default: + lbs_deb_join("ASSOC_RESP: Association failed; reason unknown " + "(status code %d)\n", status_code); + break; + } + if (status_code) { + libertas_mac_event_disconnected(priv); ret = -1; goto done; } - lbs_dbg_hex("ASSOC_RESP:", (void *)&resp->params, + lbs_deb_hex(LBS_DEB_JOIN, "ASSOC_RESP", (void *)&resp->params, le16_to_cpu(resp->size) - S_DS_GEN); /* Send a Media Connected event, according to the Spec */ - adapter->connect_status = libertas_connected; + adapter->connect_status = LIBERTAS_CONNECTED; lbs_deb_join("ASSOC_RESP: assocated to '%s'\n", escape_essid(bss->ssid, bss->ssid_len)); @@ -759,10 +795,10 @@ int libertas_ret_80211_associate(wlan_private * priv, netif_carrier_on(priv->dev); netif_wake_queue(priv->dev); - netif_carrier_on(priv->mesh_dev); - netif_wake_queue(priv->mesh_dev); - - lbs_deb_join("ASSOC_RESP: Associated \n"); + if (priv->mesh_dev) { + netif_carrier_on(priv->mesh_dev); + netif_wake_queue(priv->mesh_dev); + } memcpy(wrqu.ap_addr.sa_data, adapter->curbssparams.bssid, ETH_ALEN); wrqu.ap_addr.sa_family = ARPHRD_ETHER; @@ -794,6 +830,7 @@ int libertas_ret_80211_ad_hoc_start(wlan_private * priv, struct cmd_ds_802_11_ad_hoc_result *padhocresult; union iwreq_data wrqu; struct bss_descriptor *bss; + DECLARE_MAC_BUF(mac); lbs_deb_enter(LBS_DEB_JOIN); @@ -815,7 +852,7 @@ int libertas_ret_80211_ad_hoc_start(wlan_private * priv, */ if (result) { lbs_deb_join("ADHOC_RESP: failed\n"); - if (adapter->connect_status == libertas_connected) { + if (adapter->connect_status == LIBERTAS_CONNECTED) { libertas_mac_event_disconnected(priv); } ret = -1; @@ -830,11 +867,11 @@ int libertas_ret_80211_ad_hoc_start(wlan_private * priv, escape_essid(bss->ssid, bss->ssid_len)); /* Send a Media Connected event, according to the Spec */ - adapter->connect_status = libertas_connected; + adapter->connect_status = LIBERTAS_CONNECTED; - if (command == cmd_ret_802_11_ad_hoc_start) { + if (command == CMD_RET(CMD_802_11_AD_HOC_START)) { /* Update the created network descriptor with the new BSSID */ - memcpy(bss->bssid, padhocresult->BSSID, ETH_ALEN); + memcpy(bss->bssid, padhocresult->bssid, ETH_ALEN); } /* Set the BSSID from the joined/started descriptor */ @@ -847,8 +884,10 @@ int libertas_ret_80211_ad_hoc_start(wlan_private * priv, netif_carrier_on(priv->dev); netif_wake_queue(priv->dev); - netif_carrier_on(priv->mesh_dev); - netif_wake_queue(priv->mesh_dev); + if (priv->mesh_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); @@ -857,8 +896,8 @@ int libertas_ret_80211_ad_hoc_start(wlan_private * priv, 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)); + lbs_deb_join("ADHOC_RESP: BSSID = %s\n", + print_mac(mac, padhocresult->bssid)); done: lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret); diff --git a/drivers/net/wireless/libertas/join.h b/drivers/net/wireless/libertas/join.h index d522630ff8c..894a072b9f8 100644 --- a/drivers/net/wireless/libertas/join.h +++ b/drivers/net/wireless/libertas/join.h @@ -12,45 +12,42 @@ #include "dev.h" struct cmd_ds_command; -extern int libertas_cmd_80211_authenticate(wlan_private * priv, +int libertas_cmd_80211_authenticate(wlan_private * priv, struct cmd_ds_command *cmd, void *pdata_buf); -extern int libertas_cmd_80211_ad_hoc_join(wlan_private * priv, +int libertas_cmd_80211_ad_hoc_join(wlan_private * priv, struct cmd_ds_command *cmd, void *pdata_buf); -extern int libertas_cmd_80211_ad_hoc_stop(wlan_private * priv, +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, +int libertas_cmd_80211_ad_hoc_start(wlan_private * priv, struct cmd_ds_command *cmd, void *pdata_buf); -extern int libertas_cmd_80211_deauthenticate(wlan_private * priv, +int libertas_cmd_80211_deauthenticate(wlan_private * priv, struct cmd_ds_command *cmd); -extern int libertas_cmd_80211_associate(wlan_private * priv, +int libertas_cmd_80211_associate(wlan_private * priv, struct cmd_ds_command *cmd, void *pdata_buf); -extern int libertas_ret_80211_ad_hoc_start(wlan_private * priv, +int libertas_ret_80211_ad_hoc_start(wlan_private * priv, struct cmd_ds_command *resp); -extern int libertas_ret_80211_ad_hoc_stop(wlan_private * priv, +int libertas_ret_80211_ad_hoc_stop(wlan_private * priv, struct cmd_ds_command *resp); -extern int libertas_ret_80211_disassociate(wlan_private * priv, +int libertas_ret_80211_disassociate(wlan_private * priv, struct cmd_ds_command *resp); -extern int libertas_ret_80211_associate(wlan_private * priv, +int libertas_ret_80211_associate(wlan_private * priv, struct cmd_ds_command *resp); -extern int libertas_reassociation_thread(void *data); - -extern int libertas_start_adhoc_network(wlan_private * priv, +int libertas_start_adhoc_network(wlan_private * priv, struct assoc_request * assoc_req); -extern int libertas_join_adhoc_network(wlan_private * priv, +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); -extern int libertas_send_deauth(wlan_private * priv); +int libertas_stop_adhoc_network(wlan_private * priv); -extern int libertas_do_adhocstop_ioctl(wlan_private * priv); +int libertas_send_deauthentication(wlan_private * priv); int wlan_associate(wlan_private * priv, struct assoc_request * assoc_req); +void libertas_unset_basic_rate_flags(u8 * rates, size_t len); + #endif diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 9f366242c39..5ead08312e1 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -10,6 +10,7 @@ #include <linux/etherdevice.h> #include <linux/netdevice.h> #include <linux/if_arp.h> +#include <linux/kthread.h> #include <net/iw_handler.h> #include <net/ieee80211.h> @@ -20,8 +21,9 @@ #include "wext.h" #include "debugfs.h" #include "assoc.h" +#include "join.h" -#define DRIVER_RELEASE_VERSION "322.p0" +#define DRIVER_RELEASE_VERSION "323.p0" const char libertas_driver_version[] = "COMM-USB8388-" DRIVER_RELEASE_VERSION #ifdef DEBUG "-dbg" @@ -121,57 +123,88 @@ struct region_cfp_table { static struct region_cfp_table region_cfp_table[] = { {0x10, /*US FCC */ channel_freq_power_US_BG, - sizeof(channel_freq_power_US_BG) / sizeof(struct chan_freq_power), + ARRAY_SIZE(channel_freq_power_US_BG), } , {0x20, /*CANADA IC */ channel_freq_power_US_BG, - sizeof(channel_freq_power_US_BG) / sizeof(struct chan_freq_power), + ARRAY_SIZE(channel_freq_power_US_BG), } , {0x30, /*EU*/ channel_freq_power_EU_BG, - sizeof(channel_freq_power_EU_BG) / sizeof(struct chan_freq_power), + ARRAY_SIZE(channel_freq_power_EU_BG), } , {0x31, /*SPAIN*/ channel_freq_power_SPN_BG, - sizeof(channel_freq_power_SPN_BG) / sizeof(struct chan_freq_power), + ARRAY_SIZE(channel_freq_power_SPN_BG), } , {0x32, /*FRANCE*/ channel_freq_power_FR_BG, - sizeof(channel_freq_power_FR_BG) / sizeof(struct chan_freq_power), + ARRAY_SIZE(channel_freq_power_FR_BG), } , {0x40, /*JAPAN*/ channel_freq_power_JPN_BG, - sizeof(channel_freq_power_JPN_BG) / sizeof(struct chan_freq_power), + ARRAY_SIZE(channel_freq_power_JPN_BG), } , /*Add new region here */ }; /** - * the rates supported + * the table to keep region code */ -u8 libertas_supported_rates[G_SUPPORTED_RATES] = - { 0x82, 0x84, 0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c, -0 }; +u16 libertas_region_code_to_index[MRVDRV_MAX_REGION_CODE] = + { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40 }; /** - * the rates supported for ad-hoc G mode + * 802.11b/g supported bitrates (in 500Kb/s units) */ -u8 libertas_adhoc_rates_g[G_SUPPORTED_RATES] = - { 0x82, 0x84, 0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c, -0 }; +u8 libertas_bg_rates[MAX_RATES] = + { 0x02, 0x04, 0x0b, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c, +0x00, 0x00 }; /** - * the rates supported for ad-hoc B mode + * FW rate table. FW refers to rates by their index in this table, not by the + * rate value itself. Values of 0x00 are + * reserved positions. */ -u8 libertas_adhoc_rates_b[4] = { 0x82, 0x84, 0x8b, 0x96 }; +static u8 fw_data_rates[MAX_RATES] = + { 0x02, 0x04, 0x0B, 0x16, 0x00, 0x0C, 0x12, + 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x00 +}; /** - * the table to keep region code + * @brief use index to get the data rate + * + * @param idx The index of data rate + * @return data rate or 0 */ -u16 libertas_region_code_to_index[MRVDRV_MAX_REGION_CODE] = - { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40 }; +u32 libertas_fw_index_to_data_rate(u8 idx) +{ + if (idx >= sizeof(fw_data_rates)) + idx = 0; + return fw_data_rates[idx]; +} + +/** + * @brief use rate to get the index + * + * @param rate data rate + * @return index or 0 + */ +u8 libertas_data_rate_to_fw_index(u32 rate) +{ + u8 i; + + if (!rate) + return 0; + + for (i = 0; i < sizeof(fw_data_rates); i++) { + if (rate == fw_data_rates[i]) + return i; + } + return 0; +} /** * Attributes exported through sysfs @@ -187,9 +220,9 @@ static ssize_t libertas_anycast_get(struct device * dev, memset(&mesh_access, 0, sizeof(mesh_access)); libertas_prepare_and_send_command(to_net_dev(dev)->priv, - cmd_mesh_access, - cmd_act_mesh_get_anycast, - cmd_option_waitforrsp, 0, (void *)&mesh_access); + CMD_MESH_ACCESS, + CMD_ACT_MESH_GET_ANYCAST, + CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access); return snprintf(buf, 12, "0x%X\n", le32_to_cpu(mesh_access.data[0])); } @@ -208,18 +241,127 @@ static ssize_t libertas_anycast_set(struct device * dev, 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_anycast, - cmd_option_waitforrsp, 0, (void *)&mesh_access); + CMD_MESH_ACCESS, + CMD_ACT_MESH_SET_ANYCAST, + CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access); + return strlen(buf); +} + +int libertas_add_rtap(wlan_private *priv); +void libertas_remove_rtap(wlan_private *priv); + +/** + * Get function for sysfs attribute rtap + */ +static ssize_t libertas_rtap_get(struct device * dev, + struct device_attribute *attr, char * buf) +{ + wlan_private *priv = (wlan_private *) (to_net_dev(dev))->priv; + wlan_adapter *adapter = priv->adapter; + return snprintf(buf, 5, "0x%X\n", adapter->monitormode); +} + +/** + * Set function for sysfs attribute rtap + */ +static ssize_t libertas_rtap_set(struct device * dev, + struct device_attribute *attr, const char * buf, size_t count) +{ + int monitor_mode; + wlan_private *priv = (wlan_private *) (to_net_dev(dev))->priv; + wlan_adapter *adapter = priv->adapter; + + sscanf(buf, "%x", &monitor_mode); + if (monitor_mode != WLAN_MONITOR_OFF) { + if(adapter->monitormode == monitor_mode) + return strlen(buf); + if (adapter->monitormode == WLAN_MONITOR_OFF) { + if (adapter->mode == IW_MODE_INFRA) + libertas_send_deauthentication(priv); + else if (adapter->mode == IW_MODE_ADHOC) + libertas_stop_adhoc_network(priv); + libertas_add_rtap(priv); + } + adapter->monitormode = monitor_mode; + } + + else { + if(adapter->monitormode == WLAN_MONITOR_OFF) + return strlen(buf); + adapter->monitormode = WLAN_MONITOR_OFF; + libertas_remove_rtap(priv); + netif_wake_queue(priv->dev); + netif_wake_queue(priv->mesh_dev); + } + + libertas_prepare_and_send_command(priv, + CMD_802_11_MONITOR_MODE, CMD_ACT_SET, + CMD_OPTION_WAITFORRSP, 0, &adapter->monitormode); return strlen(buf); } /** + * libertas_rtap attribute to be exported per mshX interface + * through sysfs (/sys/class/net/mshX/libertas-rtap) + */ +static DEVICE_ATTR(libertas_rtap, 0644, libertas_rtap_get, + libertas_rtap_set ); + +/** * anycast_mask attribute to be exported per mshX interface * through sysfs (/sys/class/net/mshX/anycast_mask) */ static DEVICE_ATTR(anycast_mask, 0644, libertas_anycast_get, libertas_anycast_set); +static ssize_t libertas_autostart_enabled_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_AUTOSTART_ENABLED, + CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access); + + return sprintf(buf, "%d\n", le32_to_cpu(mesh_access.data[0])); +} + +static ssize_t libertas_autostart_enabled_set(struct device * dev, + struct device_attribute *attr, const char * buf, size_t count) +{ + struct cmd_ds_mesh_access mesh_access; + uint32_t datum; + wlan_private * priv = (to_net_dev(dev))->priv; + int ret; + + memset(&mesh_access, 0, sizeof(mesh_access)); + sscanf(buf, "%d", &datum); + mesh_access.data[0] = cpu_to_le32(datum); + + ret = libertas_prepare_and_send_command(priv, + CMD_MESH_ACCESS, + CMD_ACT_MESH_SET_AUTOSTART_ENABLED, + CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access); + if (ret == 0) + priv->mesh_autostart_enabled = datum ? 1 : 0; + + return strlen(buf); +} + +static DEVICE_ATTR(autostart_enabled, 0644, + libertas_autostart_enabled_get, libertas_autostart_enabled_set); + +static struct attribute *libertas_mesh_sysfs_entries[] = { + &dev_attr_anycast_mask.attr, + &dev_attr_autostart_enabled.attr, + NULL, +}; + +static struct attribute_group libertas_mesh_attr_group = { + .attrs = libertas_mesh_sysfs_entries, +}; + /** * @brief Check if the device can be open and wait if necessary. * @@ -255,7 +397,7 @@ static int pre_open_check(struct net_device *dev) * @param dev A pointer to net_device structure * @return 0 */ -static int wlan_dev_open(struct net_device *dev) +static int libertas_dev_open(struct net_device *dev) { wlan_private *priv = (wlan_private *) dev->priv; wlan_adapter *adapter = priv->adapter; @@ -264,12 +406,14 @@ static int wlan_dev_open(struct net_device *dev) priv->open = 1; - if (adapter->connect_status == libertas_connected) { + if (adapter->connect_status == LIBERTAS_CONNECTED) { netif_carrier_on(priv->dev); - netif_carrier_on(priv->mesh_dev); + if (priv->mesh_dev) + netif_carrier_on(priv->mesh_dev); } else { netif_carrier_off(priv->dev); - netif_carrier_off(priv->mesh_dev); + if (priv->mesh_dev) + netif_carrier_off(priv->mesh_dev); } lbs_deb_leave(LBS_DEB_NET); @@ -281,7 +425,7 @@ static int wlan_dev_open(struct net_device *dev) * @param dev A pointer to net_device structure * @return 0 */ -static int mesh_open(struct net_device *dev) +static int libertas_mesh_open(struct net_device *dev) { wlan_private *priv = (wlan_private *) dev->priv ; @@ -290,7 +434,7 @@ static int mesh_open(struct net_device *dev) priv->mesh_open = 1 ; netif_wake_queue(priv->mesh_dev); if (priv->infra_open == 0) - return wlan_dev_open(priv->dev) ; + return libertas_dev_open(priv->dev) ; return 0; } @@ -300,7 +444,7 @@ static int mesh_open(struct net_device *dev) * @param dev A pointer to net_device structure * @return 0 */ -static int wlan_open(struct net_device *dev) +static int libertas_open(struct net_device *dev) { wlan_private *priv = (wlan_private *) dev->priv ; @@ -309,11 +453,11 @@ static int wlan_open(struct net_device *dev) priv->infra_open = 1 ; netif_wake_queue(priv->dev); if (priv->open == 0) - return wlan_dev_open(priv->dev) ; + return libertas_dev_open(priv->dev) ; return 0; } -static int wlan_dev_close(struct net_device *dev) +static int libertas_dev_close(struct net_device *dev) { wlan_private *priv = dev->priv; @@ -332,14 +476,14 @@ static int wlan_dev_close(struct net_device *dev) * @param dev A pointer to net_device structure * @return 0 */ -static int mesh_close(struct net_device *dev) +static int libertas_mesh_close(struct net_device *dev) { wlan_private *priv = (wlan_private *) (dev->priv); priv->mesh_open = 0; netif_stop_queue(priv->mesh_dev); if (priv->infra_open == 0) - return wlan_dev_close(dev); + return libertas_dev_close(dev); else return 0; } @@ -350,20 +494,20 @@ 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 libertas_close(struct net_device *dev) { wlan_private *priv = (wlan_private *) dev->priv; netif_stop_queue(dev); priv->infra_open = 0; if (priv->mesh_open == 0) - return wlan_dev_close(dev); + return libertas_dev_close(dev); else return 0; } -static int wlan_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) +static int libertas_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) { int ret = 0; wlan_private *priv = dev->priv; @@ -376,7 +520,8 @@ static int wlan_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) } netif_stop_queue(priv->dev); - netif_stop_queue(priv->mesh_dev); + if (priv->mesh_dev) + netif_stop_queue(priv->mesh_dev); if (libertas_process_tx(priv, skb) == 0) dev->trans_start = jiffies; @@ -386,41 +531,52 @@ done: } /** - * @brief Mark mesh packets and handover them to wlan_hard_start_xmit + * @brief Mark mesh packets and handover them to libertas_hard_start_xmit * */ -static int mesh_pre_start_xmit(struct sk_buff *skb, struct net_device *dev) +static int libertas_mesh_pre_start_xmit(struct sk_buff *skb, + struct net_device *dev) { wlan_private *priv = dev->priv; int ret; lbs_deb_enter(LBS_DEB_MESH); + if(priv->adapter->monitormode != WLAN_MONITOR_OFF) { + netif_stop_queue(dev); + return -EOPNOTSUPP; + } SET_MESH_FRAME(skb); - ret = wlan_hard_start_xmit(skb, priv->dev); + ret = libertas_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 + * @brief Mark non-mesh packets and handover them to libertas_hard_start_xmit * */ -static int wlan_pre_start_xmit(struct sk_buff *skb, struct net_device *dev) +static int libertas_pre_start_xmit(struct sk_buff *skb, struct net_device *dev) { + wlan_private *priv = dev->priv; int ret; lbs_deb_enter(LBS_DEB_NET); + if(priv->adapter->monitormode != WLAN_MONITOR_OFF) { + netif_stop_queue(dev); + return -EOPNOTSUPP; + } + UNSET_MESH_FRAME(skb); - ret = wlan_hard_start_xmit(skb, dev); + ret = libertas_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) +static void libertas_tx_timeout(struct net_device *dev) { wlan_private *priv = (wlan_private *) dev->priv; @@ -432,16 +588,17 @@ static void wlan_tx_timeout(struct net_device *dev) dev->trans_start = jiffies; if (priv->adapter->currenttxskb) { - if (priv->adapter->radiomode == WLAN_RADIOMODE_RADIOTAP) { + if (priv->adapter->monitormode != WLAN_MONITOR_OFF) { /* If we are here, we have not received feedback from the previous packet. Assume TX_FAIL and move on. */ priv->adapter->eventcause = 0x01000000; libertas_send_tx_feedback(priv); } else - wake_up_interruptible(&priv->mainthread.waitq); - } else if (priv->adapter->connect_status == libertas_connected) { + wake_up_interruptible(&priv->waitq); + } else if (priv->adapter->connect_status == LIBERTAS_CONNECTED) { netif_wake_queue(priv->dev); - netif_wake_queue(priv->mesh_dev); + if (priv->mesh_dev) + netif_wake_queue(priv->mesh_dev); } lbs_deb_leave(LBS_DEB_TX); @@ -453,14 +610,14 @@ static void wlan_tx_timeout(struct net_device *dev) * @param dev A pointer to wlan_private structure * @return A pointer to net_device_stats structure */ -static struct net_device_stats *wlan_get_stats(struct net_device *dev) +static struct net_device_stats *libertas_get_stats(struct net_device *dev) { wlan_private *priv = (wlan_private *) dev->priv; return &priv->stats; } -static int wlan_set_mac_address(struct net_device *dev, void *addr) +static int libertas_set_mac_address(struct net_device *dev, void *addr) { int ret = 0; wlan_private *priv = (wlan_private *) dev->priv; @@ -475,14 +632,14 @@ static int wlan_set_mac_address(struct net_device *dev, void *addr) memset(adapter->current_addr, 0, ETH_ALEN); /* dev->dev_addr is 8 bytes */ - lbs_dbg_hex("dev->dev_addr:", dev->dev_addr, ETH_ALEN); + lbs_deb_hex(LBS_DEB_NET, "dev->dev_addr", dev->dev_addr, ETH_ALEN); - lbs_dbg_hex("addr:", phwaddr->sa_data, ETH_ALEN); + lbs_deb_hex(LBS_DEB_NET, "addr", phwaddr->sa_data, ETH_ALEN); memcpy(adapter->current_addr, phwaddr->sa_data, ETH_ALEN); - ret = libertas_prepare_and_send_command(priv, cmd_802_11_mac_address, - cmd_act_set, - cmd_option_waitforrsp, 0, NULL); + ret = libertas_prepare_and_send_command(priv, CMD_802_11_MAC_ADDRESS, + CMD_ACT_SET, + CMD_OPTION_WAITFORRSP, 0, NULL); if (ret) { lbs_deb_net("set MAC address failed\n"); @@ -490,7 +647,7 @@ static int wlan_set_mac_address(struct net_device *dev, void *addr) goto done; } - lbs_dbg_hex("adapter->macaddr:", adapter->current_addr, ETH_ALEN); + lbs_deb_hex(LBS_DEB_NET, "adapter->macaddr", adapter->current_addr, ETH_ALEN); memcpy(dev->dev_addr, adapter->current_addr, ETH_ALEN); if (priv->mesh_dev) memcpy(priv->mesh_dev->dev_addr, adapter->current_addr, ETH_ALEN); @@ -500,7 +657,7 @@ done: return ret; } -static int wlan_copy_multicast_address(wlan_adapter * adapter, +static int libertas_copy_multicast_address(wlan_adapter * adapter, struct net_device *dev) { int i = 0; @@ -515,11 +672,12 @@ static int wlan_copy_multicast_address(wlan_adapter * adapter, } -static void wlan_set_multicast_list(struct net_device *dev) +static void libertas_set_multicast_list(struct net_device *dev) { wlan_private *priv = dev->priv; wlan_adapter *adapter = priv->adapter; int oldpacketfilter; + DECLARE_MAC_BUF(mac); lbs_deb_enter(LBS_DEB_NET); @@ -528,57 +686,52 @@ static void wlan_set_multicast_list(struct net_device *dev) if (dev->flags & IFF_PROMISC) { lbs_deb_net("enable promiscuous mode\n"); adapter->currentpacketfilter |= - cmd_act_mac_promiscuous_enable; + CMD_ACT_MAC_PROMISCUOUS_ENABLE; adapter->currentpacketfilter &= - ~(cmd_act_mac_all_multicast_enable | - cmd_act_mac_multicast_enable); + ~(CMD_ACT_MAC_ALL_MULTICAST_ENABLE | + CMD_ACT_MAC_MULTICAST_ENABLE); } else { /* Multicast */ adapter->currentpacketfilter &= - ~cmd_act_mac_promiscuous_enable; + ~CMD_ACT_MAC_PROMISCUOUS_ENABLE; if (dev->flags & IFF_ALLMULTI || dev->mc_count > MRVDRV_MAX_MULTICAST_LIST_SIZE) { lbs_deb_net( "enabling all multicast\n"); adapter->currentpacketfilter |= - cmd_act_mac_all_multicast_enable; + CMD_ACT_MAC_ALL_MULTICAST_ENABLE; adapter->currentpacketfilter &= - ~cmd_act_mac_multicast_enable; + ~CMD_ACT_MAC_MULTICAST_ENABLE; } else { adapter->currentpacketfilter &= - ~cmd_act_mac_all_multicast_enable; + ~CMD_ACT_MAC_ALL_MULTICAST_ENABLE; if (!dev->mc_count) { lbs_deb_net("no multicast addresses, " "disabling multicast\n"); adapter->currentpacketfilter &= - ~cmd_act_mac_multicast_enable; + ~CMD_ACT_MAC_MULTICAST_ENABLE; } else { int i; adapter->currentpacketfilter |= - cmd_act_mac_multicast_enable; + CMD_ACT_MAC_MULTICAST_ENABLE; adapter->nr_of_multicastmacaddr = - wlan_copy_multicast_address(adapter, dev); + libertas_copy_multicast_address(adapter, dev); lbs_deb_net("multicast addresses: %d\n", dev->mc_count); for (i = 0; i < dev->mc_count; i++) { - lbs_deb_net("Multicast address %d:" - MAC_FMT "\n", i, - adapter->multicastlist[i][0], - adapter->multicastlist[i][1], - adapter->multicastlist[i][2], - adapter->multicastlist[i][3], - adapter->multicastlist[i][4], - adapter->multicastlist[i][5]); + lbs_deb_net("Multicast address %d:%s\n", + i, print_mac(mac, + adapter->multicastlist[i])); } /* send multicast addresses to firmware */ libertas_prepare_and_send_command(priv, - cmd_mac_multicast_adr, - cmd_act_set, 0, 0, + CMD_MAC_MULTICAST_ADR, + CMD_ACT_SET, 0, 0, NULL); } } @@ -599,18 +752,16 @@ static void wlan_set_multicast_list(struct net_device *dev) * @param data A pointer to wlan_thread structure * @return 0 */ -static int wlan_service_main_thread(void *data) +static int libertas_thread(void *data) { - struct wlan_thread *thread = data; - wlan_private *priv = thread->priv; + struct net_device *dev = data; + wlan_private *priv = dev->priv; wlan_adapter *adapter = priv->adapter; wait_queue_t wait; u8 ireg = 0; lbs_deb_enter(LBS_DEB_THREAD); - wlan_activate_thread(thread); - init_waitqueue_entry(&wait, current); set_freezable(); @@ -620,7 +771,7 @@ static int wlan_service_main_thread(void *data) adapter->intcounter, adapter->currenttxskb, priv->dnld_sent); - add_wait_queue(&thread->waitq, &wait); + add_wait_queue(&priv->waitq, &wait); set_current_state(TASK_INTERRUPTIBLE); spin_lock_irq(&adapter->driver_lock); if ((adapter->psstate == PS_STATE_SLEEP) || @@ -636,14 +787,13 @@ static int wlan_service_main_thread(void *data) } else spin_unlock_irq(&adapter->driver_lock); - lbs_deb_thread( "main-thread 222 (waking up): intcounter=%d currenttxskb=%p " "dnld_sent=%d\n", adapter->intcounter, adapter->currenttxskb, priv->dnld_sent); set_current_state(TASK_RUNNING); - remove_wait_queue(&thread->waitq, &wait); + remove_wait_queue(&priv->waitq, &wait); try_to_freeze(); lbs_deb_thread("main-thread 333: intcounter=%d currenttxskb=%p " @@ -681,20 +831,20 @@ static int wlan_service_main_thread(void *data) adapter->currenttxskb, priv->dnld_sent); /* command response? */ - if (adapter->hisregcpy & his_cmdupldrdy) { + if (adapter->hisregcpy & MRVDRV_CMD_UPLD_RDY) { lbs_deb_thread("main-thread: cmd response ready\n"); - adapter->hisregcpy &= ~his_cmdupldrdy; + adapter->hisregcpy &= ~MRVDRV_CMD_UPLD_RDY; spin_unlock_irq(&adapter->driver_lock); libertas_process_rx_command(priv); spin_lock_irq(&adapter->driver_lock); } /* Any Card Event */ - if (adapter->hisregcpy & his_cardevent) { + if (adapter->hisregcpy & MRVDRV_CARDEVENT) { lbs_deb_thread("main-thread: Card Event Activity\n"); - adapter->hisregcpy &= ~his_cardevent; + adapter->hisregcpy &= ~MRVDRV_CARDEVENT; if (priv->hw_read_event_cause(priv)) { lbs_pr_alert( @@ -711,7 +861,7 @@ static int wlan_service_main_thread(void *data) if (adapter->psstate == PS_STATE_PRE_SLEEP) { if (!priv->dnld_sent && !adapter->cur_cmd) { if (adapter->connect_status == - libertas_connected) { + LIBERTAS_CONNECTED) { lbs_deb_thread( "main_thread: PRE_SLEEP--intcounter=%d currenttxskb=%p " "dnld_sent=%d cur_cmd=%p, confirm now\n", @@ -758,13 +908,214 @@ static int wlan_service_main_thread(void *data) del_timer(&adapter->command_timer); adapter->nr_cmd_pending = 0; wake_up_all(&adapter->cmd_pending); - wlan_deactivate_thread(thread); lbs_deb_leave(LBS_DEB_THREAD); return 0; } /** + * @brief This function downloads firmware image, gets + * HW spec from firmware and set basic parameters to + * firmware. + * + * @param priv A pointer to wlan_private structure + * @return 0 or -1 + */ +static int wlan_setup_firmware(wlan_private * priv) +{ + int ret = -1; + wlan_adapter *adapter = priv->adapter; + struct cmd_ds_mesh_access mesh_access; + + lbs_deb_enter(LBS_DEB_FW); + + /* + * Read MAC address from HW + */ + memset(adapter->current_addr, 0xff, ETH_ALEN); + + ret = libertas_prepare_and_send_command(priv, CMD_GET_HW_SPEC, + 0, CMD_OPTION_WAITFORRSP, 0, NULL); + + if (ret) { + ret = -1; + goto done; + } + + libertas_set_mac_packet_filter(priv); + + /* Get the supported Data rates */ + ret = libertas_prepare_and_send_command(priv, CMD_802_11_DATA_RATE, + CMD_ACT_GET_TX_RATE, + CMD_OPTION_WAITFORRSP, 0, NULL); + + if (ret) { + ret = -1; + goto done; + } + + /* Disable mesh autostart */ + if (priv->mesh_dev) { + memset(&mesh_access, 0, sizeof(mesh_access)); + mesh_access.data[0] = cpu_to_le32(0); + ret = libertas_prepare_and_send_command(priv, + CMD_MESH_ACCESS, + CMD_ACT_MESH_SET_AUTOSTART_ENABLED, + CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access); + if (ret) { + ret = -1; + goto done; + } + priv->mesh_autostart_enabled = 0; + } + + /* Set the boot2 version in firmware */ + ret = libertas_prepare_and_send_command(priv, CMD_SET_BOOT2_VER, + 0, CMD_OPTION_WAITFORRSP, 0, NULL); + + ret = 0; +done: + lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret); + return ret; +} + +/** + * This function handles the timeout of command sending. + * It will re-send the same command again. + */ +static void command_timer_fn(unsigned long data) +{ + wlan_private *priv = (wlan_private *)data; + wlan_adapter *adapter = priv->adapter; + struct cmd_ctrl_node *ptempnode; + struct cmd_ds_command *cmd; + unsigned long flags; + + ptempnode = adapter->cur_cmd; + if (ptempnode == NULL) { + lbs_deb_fw("ptempnode empty\n"); + return; + } + + cmd = (struct cmd_ds_command *)ptempnode->bufvirtualaddr; + if (!cmd) { + lbs_deb_fw("cmd is NULL\n"); + return; + } + + lbs_deb_fw("command_timer_fn fired, cmd %x\n", cmd->command); + + if (!adapter->fw_ready) + return; + + spin_lock_irqsave(&adapter->driver_lock, flags); + adapter->cur_cmd = NULL; + spin_unlock_irqrestore(&adapter->driver_lock, flags); + + lbs_deb_fw("re-sending same command because of timeout\n"); + libertas_queue_cmd(adapter, ptempnode, 0); + + wake_up_interruptible(&priv->waitq); + + return; +} + +static int libertas_init_adapter(wlan_private * priv) +{ + wlan_adapter *adapter = priv->adapter; + size_t bufsize; + int i, ret = 0; + + /* Allocate buffer to store the BSSID list */ + 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"); + ret = -1; + goto out; + } + + /* 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->libertas_ps_confirm_sleep.seqnum = cpu_to_le16(++adapter->seqnum); + adapter->libertas_ps_confirm_sleep.command = + cpu_to_le16(CMD_802_11_PS_MODE); + adapter->libertas_ps_confirm_sleep.size = + cpu_to_le16(sizeof(struct PS_CMD_ConfirmSleep)); + adapter->libertas_ps_confirm_sleep.action = + cpu_to_le16(CMD_SUBCMD_SLEEP_CONFIRMED); + + memset(adapter->current_addr, 0xff, ETH_ALEN); + + adapter->connect_status = LIBERTAS_DISCONNECTED; + adapter->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; + adapter->mode = IW_MODE_INFRA; + adapter->curbssparams.channel = DEFAULT_AD_HOC_CHANNEL; + adapter->currentpacketfilter = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON; + adapter->radioon = RADIO_ON; + adapter->auto_rate = 1; + adapter->capability = WLAN_CAPABILITY_SHORT_PREAMBLE; + adapter->psmode = WLAN802_11POWERMODECAM; + adapter->psstate = PS_STATE_FULL_POWER; + + mutex_init(&adapter->lock); + + memset(&adapter->tx_queue_ps, 0, NR_TX_QUEUE*sizeof(struct sk_buff*)); + adapter->tx_queue_idx = 0; + spin_lock_init(&adapter->txqueue_lock); + + setup_timer(&adapter->command_timer, command_timer_fn, + (unsigned long)priv); + + INIT_LIST_HEAD(&adapter->cmdfreeq); + INIT_LIST_HEAD(&adapter->cmdpendingq); + + spin_lock_init(&adapter->driver_lock); + init_waitqueue_head(&adapter->cmd_pending); + adapter->nr_cmd_pending = 0; + + /* Allocate the command buffers */ + if (libertas_allocate_cmd_buffer(priv)) { + lbs_pr_err("Out of memory allocating command buffers\n"); + ret = -1; + } + +out: + return ret; +} + +static void libertas_free_adapter(wlan_private * priv) +{ + wlan_adapter *adapter = priv->adapter; + + if (!adapter) { + lbs_deb_fw("why double free adapter?\n"); + return; + } + + lbs_deb_fw("free command buffer\n"); + libertas_free_cmd_buffer(priv); + + lbs_deb_fw("free command_timer\n"); + del_timer(&adapter->command_timer); + + 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; +} + +/** * @brief This function adds the card. it will probe the * card, allocate the wlan_priv and initialize the device. * @@ -781,7 +1132,7 @@ wlan_private *libertas_add_card(void *card, struct device *dmdev) /* Allocate an Ethernet device and register it */ if (!(dev = alloc_etherdev(sizeof(wlan_private)))) { lbs_pr_err("init ethX device failed\n"); - return NULL; + goto done; } priv = dev->priv; @@ -791,20 +1142,24 @@ wlan_private *libertas_add_card(void *card, struct device *dmdev) goto err_kzalloc; } + if (libertas_init_adapter(priv)) { + lbs_pr_err("failed to initialize adapter structure.\n"); + goto err_init_adapter; + } + priv->dev = dev; priv->card = card; priv->mesh_open = 0; priv->infra_open = 0; - - SET_MODULE_OWNER(dev); + priv->hotplug_device = dmdev; /* Setup the OS Interface to our functions */ - dev->open = wlan_open; - dev->hard_start_xmit = wlan_pre_start_xmit; - dev->stop = wlan_close; - dev->set_mac_address = wlan_set_mac_address; - dev->tx_timeout = wlan_tx_timeout; - dev->get_stats = wlan_get_stats; + dev->open = libertas_open; + dev->hard_start_xmit = libertas_pre_start_xmit; + dev->stop = libertas_close; + dev->set_mac_address = libertas_set_mac_address; + dev->tx_timeout = libertas_tx_timeout; + dev->get_stats = libertas_get_stats; dev->watchdog_timeo = 5 * HZ; dev->ethtool_ops = &libertas_ethtool_ops; #ifdef WIRELESS_EXT @@ -813,84 +1168,148 @@ wlan_private *libertas_add_card(void *card, struct device *dmdev) #define NETIF_F_DYNALLOC 16 dev->features |= NETIF_F_DYNALLOC; dev->flags |= IFF_BROADCAST | IFF_MULTICAST; - dev->set_multicast_list = wlan_set_multicast_list; + dev->set_multicast_list = libertas_set_multicast_list; SET_NETDEV_DEV(dev, dmdev); - INIT_LIST_HEAD(&priv->adapter->cmdfreeq); - INIT_LIST_HEAD(&priv->adapter->cmdpendingq); + priv->rtap_net_dev = NULL; + if (device_create_file(dmdev, &dev_attr_libertas_rtap)) + goto err_init_adapter; + + lbs_deb_thread("Starting main thread...\n"); + init_waitqueue_head(&priv->waitq); + priv->main_thread = kthread_run(libertas_thread, dev, "libertas_main"); + if (IS_ERR(priv->main_thread)) { + lbs_deb_thread("Error creating main thread.\n"); + goto err_kthread_run; + } + + priv->work_thread = create_singlethread_workqueue("libertas_worker"); + INIT_DELAYED_WORK(&priv->assoc_work, libertas_association_worker); + INIT_DELAYED_WORK(&priv->scan_work, libertas_scan_worker); + INIT_WORK(&priv->sync_channel, libertas_sync_channel); - spin_lock_init(&priv->adapter->driver_lock); - init_waitqueue_head(&priv->adapter->cmd_pending); - priv->adapter->nr_cmd_pending = 0; goto done; +err_kthread_run: + device_remove_file(dmdev, &dev_attr_libertas_rtap); + +err_init_adapter: + libertas_free_adapter(priv); + 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); -int libertas_activate_card(wlan_private *priv, char *fw_name) + +int libertas_remove_card(wlan_private *priv) { + wlan_adapter *adapter = priv->adapter; struct net_device *dev = priv->dev; - int ret = -1; + union iwreq_data wrqu; 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"); + libertas_remove_rtap(priv); - priv->assoc_thread = - create_singlethread_workqueue("libertas_assoc"); - INIT_DELAYED_WORK(&priv->assoc_work, libertas_association_worker); - INIT_WORK(&priv->sync_channel, libertas_sync_channel); + dev = priv->dev; + device_remove_file(priv->hotplug_device, &dev_attr_libertas_rtap); - /* - * Register the device. Fillup the private data structure with - * relevant information from the card and request for the required - * IRQ. - */ - if (priv->hw_register_dev(priv) < 0) { - lbs_pr_err("failed to register WLAN device\n"); - goto err_registerdev; - } + cancel_delayed_work(&priv->scan_work); + cancel_delayed_work(&priv->assoc_work); + destroy_workqueue(priv->work_thread); - /* init FW and HW */ - if (fw_name && libertas_init_fw(priv, fw_name)) { - lbs_pr_err("firmware init failed\n"); - goto err_registerdev; + if (adapter->psmode == WLAN802_11POWERMODEMAX_PSP) { + adapter->psmode = WLAN802_11POWERMODECAM; + libertas_ps_wakeup(priv, CMD_OPTION_WAITFORRSP); } + memset(wrqu.ap_addr.sa_data, 0xaa, ETH_ALEN); + wrqu.ap_addr.sa_family = ARPHRD_ETHER; + wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL); + + /* Stop the thread servicing the interrupts */ + adapter->surpriseremoved = 1; + kthread_stop(priv->main_thread); + + libertas_free_adapter(priv); + + priv->dev = NULL; + free_netdev(dev); + + lbs_deb_leave(LBS_DEB_MAIN); + return 0; +} +EXPORT_SYMBOL_GPL(libertas_remove_card); + + +int libertas_start_card(wlan_private *priv) +{ + struct net_device *dev = priv->dev; + int ret = -1; + + lbs_deb_enter(LBS_DEB_MAIN); + + /* poke the firmware */ + ret = wlan_setup_firmware(priv); + if (ret) + goto done; + + /* init 802.11d */ + libertas_init_11d(priv); + if (register_netdev(dev)) { lbs_pr_err("cannot register ethX device\n"); - goto err_init_fw; + goto done; } - lbs_pr_info("%s: Marvell WLAN 802.11 adapter\n", dev->name); - libertas_debugfs_init_one(priv, dev); + lbs_pr_info("%s: Marvell WLAN 802.11 adapter\n", dev->name); + ret = 0; - goto done; -err_init_fw: - 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); done: - lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret); + lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret); return ret; } -EXPORT_SYMBOL_GPL(libertas_activate_card); +EXPORT_SYMBOL_GPL(libertas_start_card); + + +int libertas_stop_card(wlan_private *priv) +{ + struct net_device *dev = priv->dev; + int ret = -1; + struct cmd_ctrl_node *cmdnode; + unsigned long flags; + + lbs_deb_enter(LBS_DEB_MAIN); + + netif_stop_queue(priv->dev); + netif_carrier_off(priv->dev); + + libertas_debugfs_remove_one(priv); + + /* Flush pending command nodes */ + spin_lock_irqsave(&priv->adapter->driver_lock, flags); + list_for_each_entry(cmdnode, &priv->adapter->cmdpendingq, list) { + cmdnode->cmdwaitqwoken = 1; + wake_up_interruptible(&cmdnode->cmdwait_q); + } + spin_unlock_irqrestore(&priv->adapter->driver_lock, flags); + + unregister_netdev(dev); + + lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret); + return ret; +} +EXPORT_SYMBOL_GPL(libertas_stop_card); /** @@ -915,13 +1334,11 @@ int libertas_add_mesh(wlan_private *priv, struct device *dev) 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->open = libertas_mesh_open; + mesh_dev->hard_start_xmit = libertas_mesh_pre_start_xmit; + mesh_dev->stop = libertas_mesh_close; + mesh_dev->get_stats = libertas_get_stats; + mesh_dev->set_mac_address = libertas_set_mac_address; mesh_dev->ethtool_ops = &libertas_ethtool_ops; memcpy(mesh_dev->dev_addr, priv->dev->dev_addr, sizeof(priv->dev->dev_addr)); @@ -940,7 +1357,7 @@ int libertas_add_mesh(wlan_private *priv, struct device *dev) goto err_free; } - ret = device_create_file(&(mesh_dev->dev), &dev_attr_anycast_mask); + ret = sysfs_create_group(&(mesh_dev->dev.kobj), &libertas_mesh_attr_group); if (ret) goto err_unregister; @@ -948,7 +1365,6 @@ int libertas_add_mesh(wlan_private *priv, struct device *dev) ret = 0; goto done; - err_unregister: unregister_netdev(mesh_dev); @@ -961,86 +1377,12 @@ done: } 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; - wake_up_interruptible(&cmdnode->cmdwait_q); - } - spin_unlock_irqrestore(&priv->adapter->driver_lock, flags); -} - - -int libertas_remove_card(wlan_private *priv) -{ - wlan_adapter *adapter; - struct net_device *dev; - union iwreq_data wrqu; - - lbs_deb_enter(LBS_DEB_NET); - - if (!priv) - goto out; - - adapter = priv->adapter; - - if (!adapter) - goto out; - - dev = priv->dev; - - netif_stop_queue(priv->dev); - netif_carrier_off(priv->dev); - - wake_pending_cmdnodes(priv); - - unregister_netdev(dev); - - cancel_delayed_work(&priv->assoc_work); - destroy_workqueue(priv->assoc_thread); - - if (adapter->psmode == wlan802_11powermodemax_psp) { - adapter->psmode = wlan802_11powermodecam; - libertas_ps_wakeup(priv, cmd_option_waitforrsp); - } - - memset(wrqu.ap_addr.sa_data, 0xaa, ETH_ALEN); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL); - - adapter->surpriseremoved = 1; - - /* Stop the thread servicing the interrupts */ - wlan_terminate_thread(&priv->mainthread); - - libertas_debugfs_remove_one(priv); - - lbs_deb_net("free adapter\n"); - libertas_free_adapter(priv); - - 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); + lbs_deb_enter(LBS_DEB_MAIN); if (!priv) goto out; @@ -1050,14 +1392,14 @@ void libertas_remove_mesh(wlan_private *priv) netif_stop_queue(mesh_dev); netif_carrier_off(priv->mesh_dev); - device_remove_file(&(mesh_dev->dev), &dev_attr_anycast_mask); + sysfs_remove_group(&(mesh_dev->dev.kobj), &libertas_mesh_attr_group); unregister_netdev(mesh_dev); priv->mesh_dev = NULL ; free_netdev(mesh_dev); out: - lbs_deb_leave(LBS_DEB_NET); + lbs_deb_leave(LBS_DEB_MAIN); } EXPORT_SYMBOL_GPL(libertas_remove_mesh); @@ -1076,7 +1418,7 @@ struct chan_freq_power *libertas_get_region_cfp_table(u8 region, u8 band, int *c lbs_deb_enter(LBS_DEB_MAIN); - end = sizeof(region_cfp_table)/sizeof(struct region_cfp_table); + end = ARRAY_SIZE(region_cfp_table); for (i = 0; i < end ; i++) { lbs_deb_main("region_cfp_table[i].region=%d\n", @@ -1148,15 +1490,30 @@ 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); + if (priv->mesh_dev) + netif_wake_queue(priv->mesh_dev); } - wake_up_interruptible(&priv->mainthread.waitq); + wake_up_interruptible(&priv->waitq); lbs_deb_leave(LBS_DEB_THREAD); } EXPORT_SYMBOL_GPL(libertas_interrupt); +int libertas_reset_device(wlan_private *priv) +{ + int ret; + + lbs_deb_enter(LBS_DEB_MAIN); + 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_MAIN, "ret %d", ret); + return ret; +} +EXPORT_SYMBOL_GPL(libertas_reset_device); + static int libertas_init_module(void) { lbs_deb_enter(LBS_DEB_MAIN); @@ -1174,6 +1531,81 @@ static void libertas_exit_module(void) lbs_deb_leave(LBS_DEB_MAIN); } +/* + * rtap interface support fuctions + */ + +static int libertas_rtap_open(struct net_device *dev) +{ + netif_carrier_off(dev); + netif_stop_queue(dev); + return 0; +} + +static int libertas_rtap_stop(struct net_device *dev) +{ + return 0; +} + +static int libertas_rtap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + netif_stop_queue(dev); + return -EOPNOTSUPP; +} + +static struct net_device_stats *libertas_rtap_get_stats(struct net_device *dev) +{ + wlan_private *priv = dev->priv; + return &priv->ieee->stats; +} + + +void libertas_remove_rtap(wlan_private *priv) +{ + if (priv->rtap_net_dev == NULL) + return; + unregister_netdev(priv->rtap_net_dev); + free_ieee80211(priv->rtap_net_dev); + priv->rtap_net_dev = NULL; +} + +int libertas_add_rtap(wlan_private *priv) +{ + int rc = 0; + + if (priv->rtap_net_dev) + return -EPERM; + + priv->rtap_net_dev = alloc_ieee80211(0); + if (priv->rtap_net_dev == NULL) + return -ENOMEM; + + + priv->ieee = netdev_priv(priv->rtap_net_dev); + + strcpy(priv->rtap_net_dev->name, "rtap%d"); + + priv->rtap_net_dev->type = ARPHRD_IEEE80211_RADIOTAP; + priv->rtap_net_dev->open = libertas_rtap_open; + priv->rtap_net_dev->stop = libertas_rtap_stop; + priv->rtap_net_dev->get_stats = libertas_rtap_get_stats; + priv->rtap_net_dev->hard_start_xmit = libertas_rtap_hard_start_xmit; + priv->rtap_net_dev->set_multicast_list = libertas_set_multicast_list; + priv->rtap_net_dev->priv = priv; + + priv->ieee->iw_mode = IW_MODE_MONITOR; + + rc = register_netdev(priv->rtap_net_dev); + if (rc) { + free_ieee80211(priv->rtap_net_dev); + priv->rtap_net_dev = NULL; + return rc; + } + + return 0; +} + + module_init(libertas_init_module); module_exit(libertas_exit_module); diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c index 769c86fb950..0420e5b9ff9 100644 --- a/drivers/net/wireless/libertas/rx.c +++ b/drivers/net/wireless/libertas/rx.c @@ -85,12 +85,12 @@ static u8 wlan_getavgnf(wlan_private * priv) static void wlan_save_rawSNRNF(wlan_private * priv, struct rxpd *p_rx_pd) { wlan_adapter *adapter = priv->adapter; - if (adapter->numSNRNF < adapter->data_avg_factor) + if (adapter->numSNRNF < DEFAULT_DATA_AVG_FACTOR) adapter->numSNRNF++; adapter->rawSNR[adapter->nextSNRNF] = p_rx_pd->snr; adapter->rawNF[adapter->nextSNRNF] = p_rx_pd->nf; adapter->nextSNRNF++; - if (adapter->nextSNRNF >= adapter->data_avg_factor) + if (adapter->nextSNRNF >= DEFAULT_DATA_AVG_FACTOR) adapter->nextSNRNF = 0; return; } @@ -117,8 +117,6 @@ static void wlan_compute_rssi(wlan_private * priv, struct rxpd *p_rx_pd) adapter->NF[TYPE_RXPD][TYPE_NOAVG] = p_rx_pd->nf; wlan_save_rawSNRNF(priv, p_rx_pd); - adapter->rxpd_rate = p_rx_pd->rx_rate; - adapter->SNR[TYPE_RXPD][TYPE_AVG] = wlan_getavgsnr(priv) * AVG_SCALE; adapter->NF[TYPE_RXPD][TYPE_AVG] = wlan_getavgnf(priv) * AVG_SCALE; lbs_deb_rx("after computing SNR: SNR-avg = %d, NF-avg = %d\n", @@ -140,12 +138,15 @@ void libertas_upload_rx_packet(wlan_private * priv, struct sk_buff *skb) { lbs_deb_rx("skb->data %p\n", skb->data); - if (priv->mesh_dev && IS_MESH_FRAME(skb)) - skb->protocol = eth_type_trans(skb, priv->mesh_dev); - else - skb->protocol = eth_type_trans(skb, priv->dev); + if (priv->adapter->monitormode != WLAN_MONITOR_OFF) { + skb->protocol = eth_type_trans(skb, priv->rtap_net_dev); + } else { + if (priv->mesh_dev && IS_MESH_FRAME(skb)) + skb->protocol = eth_type_trans(skb, priv->mesh_dev); + else + skb->protocol = eth_type_trans(skb, priv->dev); + } skb->ip_summed = CHECKSUM_UNNECESSARY; - netif_rx(skb); } @@ -172,11 +173,7 @@ int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *skb) lbs_deb_enter(LBS_DEB_RX); - if (priv->adapter->debugmode & MRVDRV_DEBUG_RX_PATH) - lbs_dbg_hex("RX packet: ", skb->data, - min_t(unsigned int, skb->len, 100)); - - if (priv->adapter->linkmode == WLAN_LINKMODE_802_11) + if (priv->adapter->monitormode != WLAN_MONITOR_OFF) return process_rxed_802_11_packet(priv, skb); p_rx_pkt = (struct rxpackethdr *) skb->data; @@ -186,7 +183,7 @@ int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *skb) else UNSET_MESH_FRAME(skb); - lbs_dbg_hex("RX Data: Before chop rxpd", skb->data, + lbs_deb_hex(LBS_DEB_RX, "RX Data: Before chop rxpd", skb->data, min_t(unsigned int, skb->len, 100)); if (skb->len < (ETH_HLEN + 8 + sizeof(struct rxpd))) { @@ -210,9 +207,9 @@ int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *skb) 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, + lbs_deb_hex(LBS_DEB_RX, "RX Data: Dest", p_rx_pkt->eth803_hdr.dest_addr, sizeof(p_rx_pkt->eth803_hdr.dest_addr)); - lbs_dbg_hex("RX Data: Src", p_rx_pkt->eth803_hdr.src_addr, + lbs_deb_hex(LBS_DEB_RX, "RX Data: Src", p_rx_pkt->eth803_hdr.src_addr, sizeof(p_rx_pkt->eth803_hdr.src_addr)); if (memcmp(&p_rx_pkt->rfc1042_hdr, @@ -244,7 +241,7 @@ int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *skb) */ hdrchop = (u8 *) p_ethhdr - (u8 *) p_rx_pkt; } else { - lbs_dbg_hex("RX Data: LLC/SNAP", + lbs_deb_hex(LBS_DEB_RX, "RX Data: LLC/SNAP", (u8 *) & p_rx_pkt->rfc1042_hdr, sizeof(p_rx_pkt->rfc1042_hdr)); @@ -260,8 +257,8 @@ int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *skb) /* Take the data rate from the rxpd structure * only if the rate is auto */ - if (adapter->is_datarate_auto) - adapter->datarate = libertas_index_to_data_rate(p_rx_pd->rx_rate); + if (adapter->auto_rate) + adapter->cur_rate = libertas_fw_index_to_data_rate(p_rx_pd->rx_rate); wlan_compute_rssi(priv, p_rx_pd); @@ -296,21 +293,22 @@ static u8 convert_mv_rate_to_radiotap(u8 rate) return 11; case 3: /* 11 Mbps */ return 22; - case 4: /* 6 Mbps */ + /* case 4: reserved */ + case 5: /* 6 Mbps */ return 12; - case 5: /* 9 Mbps */ + case 6: /* 9 Mbps */ return 18; - case 6: /* 12 Mbps */ + case 7: /* 12 Mbps */ return 24; - case 7: /* 18 Mbps */ + case 8: /* 18 Mbps */ return 36; - case 8: /* 24 Mbps */ + case 9: /* 24 Mbps */ return 48; - case 9: /* 36 Mbps */ + case 10: /* 36 Mbps */ return 72; - case 10: /* 48 Mbps */ + case 11: /* 48 Mbps */ return 96; - case 11: /* 54 Mbps */ + case 12: /* 54 Mbps */ return 108; } lbs_pr_alert("Invalid Marvell WLAN rate %i\n", rate); @@ -340,7 +338,7 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb) p_rx_pkt = (struct rx80211packethdr *) skb->data; prxpd = &p_rx_pkt->rx_pd; - // lbs_dbg_hex("RX Data: Before chop rxpd", skb->data, min(skb->len, 100)); + // lbs_deb_hex(LBS_DEB_RX, "RX Data: Before chop rxpd", skb->data, min(skb->len, 100)); if (skb->len < (ETH_HLEN + 8 + sizeof(struct rxpd))) { lbs_deb_rx("rx err: frame received wit bad length\n"); @@ -361,20 +359,19 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb) skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd)); /* create the exported radio header */ - switch (priv->adapter->radiomode) { - case WLAN_RADIOMODE_NONE: + if(priv->adapter->monitormode == WLAN_MONITOR_OFF) { /* no radio header */ /* chop the rxpd */ skb_pull(skb, sizeof(struct rxpd)); - break; + } - case WLAN_RADIOMODE_RADIOTAP: + else { /* radiotap header */ radiotap_hdr.hdr.it_version = 0; /* XXX must check this value for pad */ radiotap_hdr.hdr.it_pad = 0; - radiotap_hdr.hdr.it_len = sizeof(struct rx_radiotap_hdr); - radiotap_hdr.hdr.it_present = RX_RADIOTAP_PRESENT; + radiotap_hdr.hdr.it_len = cpu_to_le16 (sizeof(struct rx_radiotap_hdr)); + radiotap_hdr.hdr.it_present = cpu_to_le32 (RX_RADIOTAP_PRESENT); /* unknown values */ radiotap_hdr.flags = 0; radiotap_hdr.chan_freq = 0; @@ -389,8 +386,6 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb) radiotap_hdr.rx_flags |= IEEE80211_RADIOTAP_F_RX_BADFCS; //memset(radiotap_hdr.pad, 0x11, IEEE80211_RADIOTAP_HDRLEN - 18); - // lbs_dbg_hex1("RX radiomode packet BEF: ", skb->data, min(skb->len, 100)); - /* chop the rxpd */ skb_pull(skb, sizeof(struct rxpd)); @@ -408,25 +403,13 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb) rx_radiotap_hdr)); memcpy(pradiotap_hdr, &radiotap_hdr, sizeof(struct rx_radiotap_hdr)); - //lbs_dbg_hex1("RX radiomode packet AFT: ", skb->data, min(skb->len, 100)); - break; - - default: - /* unknown header */ - lbs_pr_alert("Unknown radiomode %i\n", - priv->adapter->radiomode); - /* don't export any header */ - /* chop the rxpd */ - skb_pull(skb, sizeof(struct rxpd)); - break; } /* Take the data rate from the rxpd structure * only if the rate is auto */ - if (adapter->is_datarate_auto) { - adapter->datarate = libertas_index_to_data_rate(prxpd->rx_rate); - } + if (adapter->auto_rate) + adapter->cur_rate = libertas_fw_index_to_data_rate(prxpd->rx_rate); wlan_compute_rssi(priv, prxpd); diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c index c3043dcb541..ad1e67d984c 100644 --- a/drivers/net/wireless/libertas/scan.c +++ b/drivers/net/wireless/libertas/scan.c @@ -13,10 +13,13 @@ #include <net/ieee80211.h> #include <net/iw_handler.h> +#include <asm/unaligned.h> + #include "host.h" #include "decl.h" #include "dev.h" #include "scan.h" +#include "join.h" //! Approximate amount of data needed to pass a scan result back to iwlist #define MAX_SCAN_CELL_SIZE (IW_EV_ADDR_LEN \ @@ -62,6 +65,15 @@ static const u8 zeromac[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static const u8 bcastmac[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + + + +/*********************************************************************/ +/* */ +/* Misc helper functions */ +/* */ +/*********************************************************************/ + static inline void clear_bss_descriptor (struct bss_descriptor * bss) { /* Don't blow away ->list, just BSS data */ @@ -74,9 +86,9 @@ static inline int match_bss_no_security(struct wlan_802_11_security * secinfo, 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) { + && match_bss->wpa_ie[0] != MFIE_TYPE_GENERIC + && match_bss->rsn_ie[0] != MFIE_TYPE_RSN + && !(match_bss->capability & WLAN_CAPABILITY_PRIVACY)) { return 1; } return 0; @@ -88,7 +100,7 @@ static inline int match_bss_static_wep(struct wlan_802_11_security * secinfo, if ( secinfo->wep_enabled && !secinfo->WPAenabled && !secinfo->WPA2enabled - && match_bss->privacy) { + && (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) { return 1; } return 0; @@ -99,9 +111,10 @@ static inline int match_bss_wpa(struct wlan_802_11_security * secinfo, { if ( !secinfo->wep_enabled && secinfo->WPAenabled - && (match_bss->wpa_ie[0] == WPA_IE) + && (match_bss->wpa_ie[0] == MFIE_TYPE_GENERIC) /* privacy bit may NOT be set in some APs like LinkSys WRT54G - && bss->privacy */ + && (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) { + */ ) { return 1; } @@ -113,9 +126,10 @@ static inline int match_bss_wpa2(struct wlan_802_11_security * secinfo, { if ( !secinfo->wep_enabled && secinfo->WPA2enabled - && (match_bss->rsn_ie[0] == WPA2_IE) + && (match_bss->rsn_ie[0] == MFIE_TYPE_RSN) /* privacy bit may NOT be set in some APs like LinkSys WRT54G - && bss->privacy */ + && (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) { + */ ) { return 1; } @@ -128,9 +142,9 @@ static inline int match_bss_dynamic_wep(struct wlan_802_11_security * secinfo, 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) { + && (match_bss->wpa_ie[0] != MFIE_TYPE_GENERIC) + && (match_bss->rsn_ie[0] != MFIE_TYPE_RSN) + && (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) { return 1; } return 0; @@ -160,7 +174,7 @@ static int is_network_compatible(wlan_adapter * adapter, { int matched = 0; - lbs_deb_enter(LBS_DEB_ASSOC); + lbs_deb_enter(LBS_DEB_SCAN); if (bss->mode != mode) goto done; @@ -177,7 +191,7 @@ static int is_network_compatible(wlan_adapter * adapter, adapter->secinfo.wep_enabled ? "e" : "d", adapter->secinfo.WPAenabled ? "e" : "d", adapter->secinfo.WPA2enabled ? "e" : "d", - bss->privacy); + (bss->capability & WLAN_CAPABILITY_PRIVACY)); goto done; } else if ((matched = match_bss_wpa2(&adapter->secinfo, bss))) { lbs_deb_scan( @@ -187,15 +201,14 @@ static int is_network_compatible(wlan_adapter * adapter, adapter->secinfo.wep_enabled ? "e" : "d", adapter->secinfo.WPAenabled ? "e" : "d", adapter->secinfo.WPA2enabled ? "e" : "d", - bss->privacy); + (bss->capability & WLAN_CAPABILITY_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); + bss->wpa_ie[0], bss->rsn_ie[0], + (bss->capability & WLAN_CAPABILITY_PRIVACY)); goto done; } @@ -207,16 +220,44 @@ static int is_network_compatible(wlan_adapter * adapter, adapter->secinfo.wep_enabled ? "e" : "d", adapter->secinfo.WPAenabled ? "e" : "d", adapter->secinfo.WPA2enabled ? "e" : "d", - bss->privacy); + (bss->capability & WLAN_CAPABILITY_PRIVACY)); done: - lbs_deb_leave(LBS_DEB_SCAN); + lbs_deb_leave_args(LBS_DEB_SCAN, "matched: %d", matched); return matched; } /** + * @brief Compare two SSIDs + * + * @param ssid1 A pointer to ssid to compare + * @param ssid2 A pointer to ssid to compare + * + * @return 0--ssid is same, otherwise is different + */ +int libertas_ssid_cmp(u8 *ssid1, u8 ssid1_len, u8 *ssid2, u8 ssid2_len) +{ + if (ssid1_len != ssid2_len) + return -1; + + return memcmp(ssid1, ssid2, ssid1_len); +} + + + + +/*********************************************************************/ +/* */ +/* Main scanning support */ +/* */ +/*********************************************************************/ + + +/** * @brief Create a channel list for the driver to scan based on region info * + * Only used from wlan_scan_setup_scan_config() + * * Use the driver region/band information to construct a comprehensive list * of channels to scan. This routine is used for any scan that is not * provided a specific channel list to scan. @@ -244,17 +285,19 @@ static void wlan_scan_create_channel_list(wlan_private * priv, int nextchan; u8 scantype; + lbs_deb_enter_args(LBS_DEB_SCAN, "filteredscan %d", filteredscan); + chanidx = 0; /* Set the default scan type to the user specified type, will later * be changed to passive on a per channel basis if restricted by * regulatory requirements (11d or 11h) */ - scantype = adapter->scantype; + scantype = CMD_SCAN_TYPE_ACTIVE; for (rgnidx = 0; rgnidx < ARRAY_SIZE(adapter->region_channel); rgnidx++) { if (priv->adapter->enable11d && - adapter->connect_status != libertas_connected) { + adapter->connect_status != LIBERTAS_CONNECTED) { /* Scan all the supported chan for the first scan */ if (!adapter->universal_channel[rgnidx].valid) continue; @@ -286,11 +329,11 @@ static void wlan_scan_create_channel_list(wlan_private * priv, case BAND_G: default: scanchanlist[chanidx].radiotype = - cmd_scan_radio_type_bg; + CMD_SCAN_RADIO_TYPE_BG; break; } - if (scantype == cmd_scan_type_passive) { + if (scantype == CMD_SCAN_TYPE_PASSIVE) { scanchanlist[chanidx].maxscantime = cpu_to_le16(MRVDRV_PASSIVE_SCAN_CHAN_TIME); scanchanlist[chanidx].chanscanmode.passivescan = @@ -312,6 +355,16 @@ static void wlan_scan_create_channel_list(wlan_private * priv, } } + +/* Delayed partial scan worker */ +void libertas_scan_worker(struct work_struct *work) +{ + wlan_private *priv = container_of(work, wlan_private, scan_work.work); + + wlan_scan_networks(priv, NULL, 0); +} + + /** * @brief Construct a wlan_scan_cmd_config structure to use in issue scan cmds * @@ -359,7 +412,6 @@ wlan_scan_setup_scan_config(wlan_private * priv, u8 * pfilteredscan, u8 * pscancurrentonly) { - wlan_adapter *adapter = priv->adapter; struct mrvlietypes_numprobes *pnumprobestlv; struct mrvlietypes_ssidparamset *pssidtlv; struct wlan_scan_cmd_config * pscancfgout = NULL; @@ -371,6 +423,8 @@ wlan_scan_setup_scan_config(wlan_private * priv, int channel; int radiotype; + lbs_deb_enter(LBS_DEB_SCAN); + pscancfgout = kzalloc(MAX_SCAN_CFG_ALLOC, GFP_KERNEL); if (pscancfgout == NULL) goto out; @@ -407,15 +461,12 @@ wlan_scan_setup_scan_config(wlan_private * priv, *pscancurrentonly = 0; if (puserscanin) { - /* Set the bss type scan filter, use adapter setting if unset */ pscancfgout->bsstype = - (puserscanin->bsstype ? puserscanin->bsstype : adapter-> - scanmode); + puserscanin->bsstype ? puserscanin->bsstype : CMD_BSS_TYPE_ANY; /* Set the number of probes to send, use adapter setting if unset */ - numprobes = (puserscanin->numprobes ? puserscanin->numprobes : - adapter->scanprobes); + numprobes = puserscanin->numprobes ? puserscanin->numprobes : 0; /* * Set the BSSID filter to the incoming configuration, @@ -447,8 +498,8 @@ wlan_scan_setup_scan_config(wlan_private * priv, *pfilteredscan = 1; } } else { - pscancfgout->bsstype = adapter->scanmode; - numprobes = adapter->scanprobes; + pscancfgout->bsstype = CMD_BSS_TYPE_ANY; + numprobes = 0; } /* If the input config or adapter has the number of Probes set, add tlv */ @@ -469,59 +520,56 @@ wlan_scan_setup_scan_config(wlan_private * priv, */ *ppchantlvout = (struct mrvlietypes_chanlistparamset *) ptlvpos; - if (puserscanin && puserscanin->chanlist[0].channumber) { - - lbs_deb_scan("Scan: Using supplied channel list\n"); + if (!puserscanin || !puserscanin->chanlist[0].channumber) { + /* Create a default channel scan list */ + lbs_deb_scan("creating full region channel list\n"); + wlan_scan_create_channel_list(priv, pscanchanlist, + *pfilteredscan); + goto out; + } - for (chanidx = 0; - chanidx < WLAN_IOCTL_USER_SCAN_CHAN_MAX - && puserscanin->chanlist[chanidx].channumber; chanidx++) { + for (chanidx = 0; + chanidx < WLAN_IOCTL_USER_SCAN_CHAN_MAX + && puserscanin->chanlist[chanidx].channumber; chanidx++) { - channel = puserscanin->chanlist[chanidx].channumber; - (pscanchanlist + chanidx)->channumber = channel; + channel = puserscanin->chanlist[chanidx].channumber; + (pscanchanlist + chanidx)->channumber = channel; - radiotype = puserscanin->chanlist[chanidx].radiotype; - (pscanchanlist + chanidx)->radiotype = radiotype; + radiotype = puserscanin->chanlist[chanidx].radiotype; + (pscanchanlist + chanidx)->radiotype = radiotype; - scantype = puserscanin->chanlist[chanidx].scantype; + scantype = puserscanin->chanlist[chanidx].scantype; - if (scantype == cmd_scan_type_passive) { - (pscanchanlist + - chanidx)->chanscanmode.passivescan = 1; - } else { - (pscanchanlist + - chanidx)->chanscanmode.passivescan = 0; - } + if (scantype == CMD_SCAN_TYPE_PASSIVE) { + (pscanchanlist + + chanidx)->chanscanmode.passivescan = 1; + } else { + (pscanchanlist + + chanidx)->chanscanmode.passivescan = 0; + } - if (puserscanin->chanlist[chanidx].scantime) { - scandur = - puserscanin->chanlist[chanidx].scantime; + if (puserscanin->chanlist[chanidx].scantime) { + scandur = puserscanin->chanlist[chanidx].scantime; + } else { + if (scantype == CMD_SCAN_TYPE_PASSIVE) { + scandur = MRVDRV_PASSIVE_SCAN_CHAN_TIME; } else { - if (scantype == cmd_scan_type_passive) { - scandur = MRVDRV_PASSIVE_SCAN_CHAN_TIME; - } else { - scandur = MRVDRV_ACTIVE_SCAN_CHAN_TIME; - } + scandur = MRVDRV_ACTIVE_SCAN_CHAN_TIME; } - - (pscanchanlist + chanidx)->minscantime = - cpu_to_le16(scandur); - (pscanchanlist + chanidx)->maxscantime = - cpu_to_le16(scandur); } - /* Check if we are only scanning the current channel */ - if ((chanidx == 1) && (puserscanin->chanlist[0].channumber - == - priv->adapter->curbssparams.channel)) { - *pscancurrentonly = 1; - lbs_deb_scan("Scan: Scanning current channel only"); - } + (pscanchanlist + chanidx)->minscantime = + cpu_to_le16(scandur); + (pscanchanlist + chanidx)->maxscantime = + cpu_to_le16(scandur); + } - } else { - lbs_deb_scan("Scan: Creating full region channel list\n"); - wlan_scan_create_channel_list(priv, pscanchanlist, - *pfilteredscan); + /* Check if we are only scanning the current channel */ + if ((chanidx == 1) && + (puserscanin->chanlist[0].channumber == + priv->adapter->curbssparams.channel)) { + *pscancurrentonly = 1; + lbs_deb_scan("scanning current channel only"); } out: @@ -531,6 +579,8 @@ out: /** * @brief Construct and send multiple scan config commands to the firmware * + * Only used from wlan_scan_networks() + * * Previous routines have created a wlan_scan_cmd_config with any requested * TLVs. This function splits the channel TLV into maxchanperscan lists * and sends the portion of the channel TLV along with the other TLVs @@ -568,12 +618,14 @@ static int wlan_scan_channel_list(wlan_private * priv, int scanned = 0; union iwreq_data wrqu; - lbs_deb_enter(LBS_DEB_ASSOC); + lbs_deb_enter_args(LBS_DEB_SCAN, "maxchanperscan %d, filteredscan %d, " + "full_scan %d", maxchanperscan, filteredscan, full_scan); - if (pscancfgout == 0 || pchantlvout == 0 || pscanchanlist == 0) { - lbs_deb_scan("Scan: Null detect: %p, %p, %p\n", - pscancfgout, pchantlvout, pscanchanlist); - return -1; + if (!pscancfgout || !pchantlvout || !pscanchanlist) { + lbs_deb_scan("pscancfgout, pchantlvout or " + "pscanchanlist is NULL\n"); + ret = -1; + goto out; } pchantlvout->header.type = cpu_to_le16(TLV_TYPE_CHANLIST); @@ -605,12 +657,13 @@ static int wlan_scan_channel_list(wlan_private * priv, while (tlvidx < maxchanperscan && ptmpchan->channumber && !doneearly && scanned < 2) { - lbs_deb_scan( - "Scan: Chan(%3d), Radio(%d), mode(%d,%d), Dur(%d)\n", - ptmpchan->channumber, ptmpchan->radiotype, - ptmpchan->chanscanmode.passivescan, - ptmpchan->chanscanmode.disablechanfilt, - ptmpchan->maxscantime); + lbs_deb_scan("channel %d, radio %d, passive %d, " + "dischanflt %d, maxscantime %d\n", + ptmpchan->channumber, + ptmpchan->radiotype, + ptmpchan->chanscanmode.passivescan, + ptmpchan->chanscanmode.disablechanfilt, + ptmpchan->maxscantime); /* Copy the current channel TLV to the command being prepared */ memcpy(pchantlvout->chanscanparam + tlvidx, @@ -667,7 +720,7 @@ 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, + ret = libertas_prepare_and_send_command(priv, CMD_802_11_SCAN, 0, 0, 0, pscancfgout); if (scanned >= 2 && !full_scan) { ret = 0; @@ -679,24 +732,38 @@ static int wlan_scan_channel_list(wlan_private * priv, 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); + if (priv->adapter->last_scanned_channel) { + /* Schedule the next part of the partial scan */ + if (!full_scan && !priv->adapter->surpriseremoved) { + cancel_delayed_work(&priv->scan_work); + queue_delayed_work(priv->work_thread, &priv->scan_work, + msecs_to_jiffies(300)); + } + } else { + /* All done, tell userspace the scan table has been updated */ + memset(&wrqu, 0, sizeof(union iwreq_data)); + wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL); + } +out: 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) +/* + * Only used from wlan_scan_networks() +*/ +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; + struct bss_descriptor *bss; + struct bss_descriptor *safe; u32 clear_ssid_flag = 0, clear_bssid_flag = 0; + lbs_deb_enter(LBS_DEB_SCAN); + if (!scan_cfg) - return; + goto out; if (scan_cfg->clear_ssid && scan_cfg->ssid_len) clear_ssid_flag = 1; @@ -708,7 +775,7 @@ clear_selected_scan_list_entries(wlan_adapter * adapter, } if (!clear_ssid_flag && !clear_bssid_flag) - return; + goto out; mutex_lock(&adapter->lock); list_for_each_entry_safe (bss, safe, &adapter->network_list, list) { @@ -731,12 +798,16 @@ clear_selected_scan_list_entries(wlan_adapter * adapter, } } mutex_unlock(&adapter->lock); +out: + lbs_deb_leave(LBS_DEB_SCAN); } /** * @brief Internal function used to start a scan based on an input config * + * Also used from debugfs + * * Use the input user scan configuration information when provided in * order to send the appropriate scan commands to firmware to populate or * update the internal driver scan table @@ -744,12 +815,13 @@ clear_selected_scan_list_entries(wlan_adapter * adapter, * @param priv A pointer to wlan_private structure * @param puserscanin Pointer to the input configuration for the requested * scan. + * @param full_scan ??? * * @return 0 or < 0 if error */ int wlan_scan_networks(wlan_private * priv, - const struct wlan_ioctl_user_scan_cfg * puserscanin, - int full_scan) + const struct wlan_ioctl_user_scan_cfg * puserscanin, + int full_scan) { wlan_adapter * adapter = priv->adapter; struct mrvlietypes_chanlistparamset *pchantlvout; @@ -762,9 +834,16 @@ int wlan_scan_networks(wlan_private * priv, #ifdef CONFIG_LIBERTAS_DEBUG struct bss_descriptor * iter_bss; int i = 0; + DECLARE_MAC_BUF(mac); #endif - lbs_deb_enter(LBS_DEB_ASSOC); + lbs_deb_enter_args(LBS_DEB_SCAN, "full_scan %d", full_scan); + + /* Cancel any partial outstanding partial scans if this scan + * is a full scan. + */ + if (full_scan && delayed_work_pending(&priv->scan_work)) + cancel_delayed_work(&priv->scan_work); scan_chan_list = kzalloc(sizeof(struct chanscanparamset) * WLAN_IOCTL_USER_SCAN_CHAN_MAX, GFP_KERNEL); @@ -791,8 +870,10 @@ int wlan_scan_networks(wlan_private * priv, if (!scancurrentchanonly) { netif_stop_queue(priv->dev); netif_carrier_off(priv->dev); - netif_stop_queue(priv->mesh_dev); - netif_carrier_off(priv->mesh_dev); + if (priv->mesh_dev) { + netif_stop_queue(priv->mesh_dev); + netif_carrier_off(priv->mesh_dev); + } } ret = wlan_scan_channel_list(priv, @@ -807,19 +888,22 @@ int wlan_scan_networks(wlan_private * priv, #ifdef CONFIG_LIBERTAS_DEBUG /* Dump the scan table */ mutex_lock(&adapter->lock); + lbs_deb_scan("The scan table contains:\n"); 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, + lbs_deb_scan("scan %02d, %s, RSSI, %d, SSID '%s'\n", + i++, print_mac(mac, 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) { + if (priv->adapter->connect_status == LIBERTAS_CONNECTED) { netif_carrier_on(priv->dev); netif_wake_queue(priv->dev); - netif_carrier_on(priv->mesh_dev); - netif_wake_queue(priv->mesh_dev); + if (priv->mesh_dev) { + netif_carrier_on(priv->mesh_dev); + netif_wake_queue(priv->mesh_dev); + } } out: @@ -834,58 +918,6 @@ out: } /** - * @brief Inspect the scan response buffer for pointers to expected TLVs - * - * TLVs can be included at the end of the scan response BSS information. - * Parse the data in the buffer for pointers to TLVs that can potentially - * be passed back in the response - * - * @param ptlv Pointer to the start of the TLV buffer to parse - * @param tlvbufsize size of the TLV buffer - * @param ptsftlv Output parameter: Pointer to the TSF TLV if found - * - * @return void - */ -static -void wlan_ret_802_11_scan_get_tlv_ptrs(struct mrvlietypes_data * ptlv, - int tlvbufsize, - struct mrvlietypes_tsftimestamp ** ptsftlv) -{ - struct mrvlietypes_data *pcurrenttlv; - int tlvbufleft; - u16 tlvtype; - u16 tlvlen; - - pcurrenttlv = ptlv; - tlvbufleft = tlvbufsize; - *ptsftlv = NULL; - - lbs_deb_scan("SCAN_RESP: tlvbufsize = %d\n", tlvbufsize); - lbs_dbg_hex("SCAN_RESP: TLV Buf", (u8 *) ptlv, tlvbufsize); - - while (tlvbufleft >= sizeof(struct mrvlietypesheader)) { - tlvtype = le16_to_cpu(pcurrenttlv->header.type); - tlvlen = le16_to_cpu(pcurrenttlv->header.len); - - switch (tlvtype) { - case TLV_TYPE_TSFTIMESTAMP: - *ptsftlv = (struct mrvlietypes_tsftimestamp *) pcurrenttlv; - break; - - default: - lbs_deb_scan("SCAN_RESP: Unhandled TLV = %d\n", - tlvtype); - /* Give up, this seems corrupted */ - return; - } /* switch */ - - tlvbufleft -= (sizeof(ptlv->header) + tlvlen); - pcurrenttlv = - (struct mrvlietypes_data *) (pcurrenttlv->Data + tlvlen); - } /* while */ -} - -/** * @brief Interpret a BSS scan response returned from the firmware * * Parse the various fixed fields and IEs passed back for a a BSS probe @@ -899,67 +931,49 @@ void wlan_ret_802_11_scan_get_tlv_ptrs(struct mrvlietypes_data * ptlv, static int libertas_process_bss(struct bss_descriptor * bss, u8 ** pbeaconinfo, int *bytesleft) { - enum ieeetypes_elementid elemID; struct ieeetypes_fhparamset *pFH; struct ieeetypes_dsparamset *pDS; struct ieeetypes_cfparamset *pCF; struct ieeetypes_ibssparamset *pibss; - struct ieeetypes_capinfo *pcap; - struct WLAN_802_11_FIXED_IEs fixedie; - u8 *pcurrentptr; - u8 *pRate; - u8 elemlen; - u8 bytestocopy; - u8 ratesize; - u16 beaconsize; - u8 founddatarateie; - int bytesleftforcurrentbeacon; - int ret; - - struct IE_WPA *pIe; - const u8 oui01[4] = { 0x00, 0x50, 0xf2, 0x01 }; - + DECLARE_MAC_BUF(mac); struct ieeetypes_countryinfoset *pcountryinfo; + u8 *pos, *end, *p; + u8 n_ex_rates = 0, got_basic_rates = 0, n_basic_rates = 0; + u16 beaconsize = 0; + int ret; - lbs_deb_enter(LBS_DEB_ASSOC); - - founddatarateie = 0; - ratesize = 0; - beaconsize = 0; + lbs_deb_enter(LBS_DEB_SCAN); if (*bytesleft >= sizeof(beaconsize)) { /* Extract & convert beacon size from the command buffer */ - beaconsize = le16_to_cpup((void *)*pbeaconinfo); + beaconsize = le16_to_cpu(get_unaligned((u16 *)*pbeaconinfo)); *bytesleft -= sizeof(beaconsize); *pbeaconinfo += sizeof(beaconsize); } if (beaconsize == 0 || beaconsize > *bytesleft) { - *pbeaconinfo += *bytesleft; *bytesleft = 0; - - return -1; + ret = -1; + goto done; } /* Initialize the current working beacon pointer for this BSS iteration */ - pcurrentptr = *pbeaconinfo; + pos = *pbeaconinfo; + end = pos + beaconsize; /* Advance the return beacon pointer past the current beacon */ *pbeaconinfo += beaconsize; *bytesleft -= beaconsize; - bytesleftforcurrentbeacon = beaconsize; - - memcpy(bss->bssid, pcurrentptr, ETH_ALEN); - lbs_deb_scan("process_bss: AP BSSID " MAC_FMT "\n", MAC_ARG(bss->bssid)); + memcpy(bss->bssid, pos, ETH_ALEN); + lbs_deb_scan("process_bss: AP BSSID %s\n", print_mac(mac, bss->bssid)); + pos += ETH_ALEN; - pcurrentptr += ETH_ALEN; - bytesleftforcurrentbeacon -= ETH_ALEN; - - if (bytesleftforcurrentbeacon < 12) { + if ((end - pos) < 12) { lbs_deb_scan("process_bss: Not enough bytes left\n"); - return -1; + ret = -1; + goto done; } /* @@ -968,85 +982,61 @@ static int libertas_process_bss(struct bss_descriptor * bss, */ /* RSSI is 1 byte long */ - bss->rssi = *pcurrentptr; - lbs_deb_scan("process_bss: RSSI=%02X\n", *pcurrentptr); - pcurrentptr += 1; - bytesleftforcurrentbeacon -= 1; + bss->rssi = *pos; + lbs_deb_scan("process_bss: RSSI=%02X\n", *pos); + pos++; /* time stamp is 8 bytes long */ - fixedie.timestamp = bss->timestamp = le64_to_cpup((void *)pcurrentptr); - pcurrentptr += 8; - bytesleftforcurrentbeacon -= 8; + pos += 8; /* beacon interval is 2 bytes long */ - fixedie.beaconinterval = bss->beaconperiod = le16_to_cpup((void *)pcurrentptr); - pcurrentptr += 2; - bytesleftforcurrentbeacon -= 2; + bss->beaconperiod = le16_to_cpup((void *) pos); + pos += 2; /* capability information is 2 bytes long */ - memcpy(&fixedie.capabilities, pcurrentptr, 2); - lbs_deb_scan("process_bss: fixedie.capabilities=0x%X\n", - fixedie.capabilities); - pcap = (struct ieeetypes_capinfo *) & fixedie.capabilities; - memcpy(&bss->cap, pcap, sizeof(struct ieeetypes_capinfo)); - pcurrentptr += 2; - bytesleftforcurrentbeacon -= 2; - - /* rest of the current buffer are IE's */ - lbs_deb_scan("process_bss: IE length for this AP = %d\n", - bytesleftforcurrentbeacon); + bss->capability = le16_to_cpup((void *) pos); + lbs_deb_scan("process_bss: capabilities = 0x%4X\n", bss->capability); + pos += 2; - lbs_dbg_hex("process_bss: IE info", (u8 *) pcurrentptr, - bytesleftforcurrentbeacon); - - if (pcap->privacy) { + if (bss->capability & WLAN_CAPABILITY_PRIVACY) lbs_deb_scan("process_bss: AP WEP enabled\n"); - bss->privacy = wlan802_11privfilter8021xWEP; - } else { - bss->privacy = wlan802_11privfilteracceptall; - } - - if (pcap->ibss == 1) { + if (bss->capability & WLAN_CAPABILITY_IBSS) bss->mode = IW_MODE_ADHOC; - } else { + else bss->mode = IW_MODE_INFRA; - } + + /* rest of the current buffer are IE's */ + lbs_deb_scan("process_bss: IE length for this AP = %zd\n", end - pos); + lbs_deb_hex(LBS_DEB_SCAN, "process_bss: IE info", pos, end - pos); /* process variable IE */ - while (bytesleftforcurrentbeacon >= 2) { - elemID = (enum ieeetypes_elementid) (*((u8 *) pcurrentptr)); - elemlen = *((u8 *) pcurrentptr + 1); + while (pos <= end - 2) { + struct ieee80211_info_element * elem = + (struct ieee80211_info_element *) pos; - if (bytesleftforcurrentbeacon < elemlen) { + if (pos + elem->len > end) { lbs_deb_scan("process_bss: error in processing IE, " "bytes left < IE length\n"); - bytesleftforcurrentbeacon = 0; - continue; + break; } - switch (elemID) { - case SSID: - bss->ssid_len = elemlen; - memcpy(bss->ssid, (pcurrentptr + 2), elemlen); + switch (elem->id) { + case MFIE_TYPE_SSID: + bss->ssid_len = elem->len; + memcpy(bss->ssid, elem->data, elem->len); lbs_deb_scan("ssid '%s', ssid length %u\n", escape_essid(bss->ssid, bss->ssid_len), bss->ssid_len); break; - case SUPPORTED_RATES: - memcpy(bss->datarates, (pcurrentptr + 2), elemlen); - memmove(bss->libertas_supported_rates, (pcurrentptr + 2), - elemlen); - ratesize = elemlen; - founddatarateie = 1; + case MFIE_TYPE_RATES: + n_basic_rates = min_t(u8, MAX_RATES, elem->len); + memcpy(bss->rates, elem->data, n_basic_rates); + got_basic_rates = 1; break; - case EXTRA_IE: - lbs_deb_scan("process_bss: EXTRA_IE Found!\n"); - break; - - case FH_PARAM_SET: - pFH = (struct ieeetypes_fhparamset *) pcurrentptr; + case MFIE_TYPE_FH_SET: + pFH = (struct ieeetypes_fhparamset *) pos; memmove(&bss->phyparamset.fhparamset, pFH, sizeof(struct ieeetypes_fhparamset)); #if 0 /* I think we can store these LE */ @@ -1055,21 +1045,21 @@ static int libertas_process_bss(struct bss_descriptor * bss, #endif break; - case DS_PARAM_SET: - pDS = (struct ieeetypes_dsparamset *) pcurrentptr; + case MFIE_TYPE_DS_SET: + pDS = (struct ieeetypes_dsparamset *) pos; bss->channel = pDS->currentchan; memcpy(&bss->phyparamset.dsparamset, pDS, sizeof(struct ieeetypes_dsparamset)); break; - case CF_PARAM_SET: - pCF = (struct ieeetypes_cfparamset *) pcurrentptr; + case MFIE_TYPE_CF_SET: + pCF = (struct ieeetypes_cfparamset *) pos; memcpy(&bss->ssparamset.cfparamset, pCF, sizeof(struct ieeetypes_cfparamset)); break; - case IBSS_PARAM_SET: - pibss = (struct ieeetypes_ibssparamset *) pcurrentptr; + case MFIE_TYPE_IBSS_SET: + pibss = (struct ieeetypes_ibssparamset *) pos; bss->atimwindow = le32_to_cpu(pibss->atimwindow); memmove(&bss->ssparamset.ibssparamset, pibss, sizeof(struct ieeetypes_ibssparamset)); @@ -1079,9 +1069,8 @@ static int libertas_process_bss(struct bss_descriptor * bss, #endif break; - /* Handle Country Info IE */ - case COUNTRY_INFO: - pcountryinfo = (struct ieeetypes_countryinfoset *) pcurrentptr; + case MFIE_TYPE_COUNTRY: + pcountryinfo = (struct ieeetypes_countryinfoset *) pos; if (pcountryinfo->len < sizeof(pcountryinfo->countrycode) || pcountryinfo->len > 254) { lbs_deb_scan("process_bss: 11D- Err " @@ -1094,70 +1083,63 @@ static int libertas_process_bss(struct bss_descriptor * bss, memcpy(&bss->countryinfo, pcountryinfo, pcountryinfo->len + 2); - lbs_dbg_hex("process_bss: 11D- CountryInfo:", + lbs_deb_hex(LBS_DEB_SCAN, "process_bss: 11d countryinfo", (u8 *) pcountryinfo, (u32) (pcountryinfo->len + 2)); break; - case EXTENDED_SUPPORTED_RATES: - /* - * only process extended supported rate - * if data rate is already found. - * data rate IE should come before + case MFIE_TYPE_RATES_EX: + /* only process extended supported rate if data rate is + * already found. Data rate IE should come before * extended supported rate IE */ - if (founddatarateie) { - if ((elemlen + ratesize) > WLAN_SUPPORTED_RATES) { - bytestocopy = - (WLAN_SUPPORTED_RATES - ratesize); - } else { - bytestocopy = elemlen; - } - - pRate = (u8 *) bss->datarates; - pRate += ratesize; - memmove(pRate, (pcurrentptr + 2), bytestocopy); - pRate = (u8 *) bss->libertas_supported_rates; - pRate += ratesize; - memmove(pRate, (pcurrentptr + 2), bytestocopy); - } - break; - - case VENDOR_SPECIFIC_221: -#define IE_ID_LEN_FIELDS_BYTES 2 - pIe = (struct IE_WPA *)pcurrentptr; - - if (memcmp(pIe->oui, oui01, sizeof(oui01))) + if (!got_basic_rates) break; - 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); + n_ex_rates = elem->len; + if (n_basic_rates + n_ex_rates > MAX_RATES) + n_ex_rates = MAX_RATES - n_basic_rates; + + p = bss->rates + n_basic_rates; + memcpy(p, elem->data, n_ex_rates); break; - case WPA2_IE: - pIe = (struct IE_WPA *)pcurrentptr; - 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); + + case MFIE_TYPE_GENERIC: + if (elem->len >= 4 && + elem->data[0] == 0x00 && + elem->data[1] == 0x50 && + elem->data[2] == 0xf2 && + elem->data[3] == 0x01) { + bss->wpa_ie_len = min(elem->len + 2, + MAX_WPA_IE_LEN); + memcpy(bss->wpa_ie, elem, bss->wpa_ie_len); + lbs_deb_hex(LBS_DEB_SCAN, "process_bss: WPA IE", bss->wpa_ie, + elem->len); + } else if (elem->len >= MARVELL_MESH_IE_LENGTH && + elem->data[0] == 0x00 && + elem->data[1] == 0x50 && + elem->data[2] == 0x43 && + elem->data[3] == 0x04) { + bss->mesh = 1; + } break; - case TIM: + + case MFIE_TYPE_RSN: + bss->rsn_ie_len = min(elem->len + 2, MAX_WPA_IE_LEN); + memcpy(bss->rsn_ie, elem, bss->rsn_ie_len); + lbs_deb_hex(LBS_DEB_SCAN, "process_bss: RSN_IE", bss->rsn_ie, elem->len); break; - case CHALLENGE_TEXT: + default: break; } - pcurrentptr += elemlen + 2; - - /* need to account for IE ID and IE len */ - bytesleftforcurrentbeacon -= (elemlen + 2); - - } /* while (bytesleftforcurrentbeacon > 2) */ + pos += elem->len + 2; + } /* Timestamp */ bss->last_scanned = jiffies; + libertas_unset_basic_rate_flags(bss->rates, sizeof(bss->rates)); ret = 0; @@ -1167,40 +1149,28 @@ done: } /** - * @brief Compare two SSIDs - * - * @param ssid1 A pointer to ssid to compare - * @param ssid2 A pointer to ssid to compare - * - * @return 0--ssid is same, otherwise is different - */ -int libertas_ssid_cmp(u8 *ssid1, u8 ssid1_len, u8 *ssid2, u8 ssid2_len) -{ - if (ssid1_len != ssid2_len) - return -1; - - return memcmp(ssid1, ssid2, ssid1_len); -} - -/** * @brief This function finds a specific compatible BSSID in the scan list * + * Used in association code + * * @param adapter A pointer to wlan_adapter * @param bssid BSSID to find in the scan list * @param mode Network mode: Infrastructure or IBSS * * @return index in BSSID list, or error return code (< 0) */ -struct bss_descriptor * libertas_find_bssid_in_list(wlan_adapter * adapter, +struct bss_descriptor *libertas_find_bssid_in_list(wlan_adapter * adapter, u8 * bssid, u8 mode) { struct bss_descriptor * iter_bss; struct bss_descriptor * found_bss = NULL; + lbs_deb_enter(LBS_DEB_SCAN); + if (!bssid) - return NULL; + goto out; - lbs_dbg_hex("libertas_find_BSSID_in_list: looking for ", + lbs_deb_hex(LBS_DEB_SCAN, "looking for", bssid, ETH_ALEN); /* Look through the scan table for a compatible match. The loop will @@ -1225,12 +1195,16 @@ struct bss_descriptor * libertas_find_bssid_in_list(wlan_adapter * adapter, } mutex_unlock(&adapter->lock); +out: + lbs_deb_leave_args(LBS_DEB_SCAN, "found_bss %p", found_bss); return found_bss; } /** * @brief This function finds ssid in ssid list. * + * Used in association code + * * @param adapter A pointer to wlan_adapter * @param ssid SSID to find in the list * @param bssid BSSID to qualify the SSID selection (if provided) @@ -1247,6 +1221,8 @@ struct bss_descriptor * libertas_find_ssid_in_list(wlan_adapter * adapter, struct bss_descriptor * found_bss = NULL; struct bss_descriptor * tmp_oldest = NULL; + lbs_deb_enter(LBS_DEB_SCAN); + mutex_lock(&adapter->lock); list_for_each_entry (iter_bss, &adapter->network_list, list) { @@ -1291,6 +1267,7 @@ struct bss_descriptor * libertas_find_ssid_in_list(wlan_adapter * adapter, out: mutex_unlock(&adapter->lock); + lbs_deb_leave_args(LBS_DEB_SCAN, "found_bss %p", found_bss); return found_bss; } @@ -1304,13 +1281,15 @@ out: * * @return index in BSSID list */ -struct bss_descriptor * libertas_find_best_ssid_in_list(wlan_adapter * adapter, +static struct bss_descriptor * libertas_find_best_ssid_in_list(wlan_adapter * adapter, u8 mode) { u8 bestrssi = 0; struct bss_descriptor * iter_bss; struct bss_descriptor * best_bss = NULL; + lbs_deb_enter(LBS_DEB_SCAN); + mutex_lock(&adapter->lock); list_for_each_entry (iter_bss, &adapter->network_list, list) { @@ -1335,12 +1314,15 @@ struct bss_descriptor * libertas_find_best_ssid_in_list(wlan_adapter * adapter, } mutex_unlock(&adapter->lock); + lbs_deb_leave_args(LBS_DEB_SCAN, "best_bss %p", best_bss); return best_bss; } /** * @brief Find the AP with specific ssid in the scan list * + * Used from association worker. + * * @param priv A pointer to wlan_private structure * @param pSSID A pointer to AP's ssid * @@ -1353,11 +1335,11 @@ int libertas_find_best_network_ssid(wlan_private * priv, int ret = -1; struct bss_descriptor * found; - lbs_deb_enter(LBS_DEB_ASSOC); + lbs_deb_enter(LBS_DEB_SCAN); wlan_scan_networks(priv, NULL, 1); if (adapter->surpriseremoved) - return -1; + goto out; wait_event_interruptible(adapter->cmd_pending, !adapter->nr_cmd_pending); @@ -1369,6 +1351,7 @@ int libertas_find_best_network_ssid(wlan_private * priv, ret = 0; } +out: lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret); return ret; } @@ -1391,7 +1374,10 @@ int libertas_set_scan(struct net_device *dev, struct iw_request_info *info, lbs_deb_enter(LBS_DEB_SCAN); - wlan_scan_networks(priv, NULL, 0); + if (!delayed_work_pending(&priv->scan_work)) { + queue_delayed_work(priv->work_thread, &priv->scan_work, + msecs_to_jiffies(50)); + } if (adapter->surpriseremoved) return -1; @@ -1400,10 +1386,17 @@ int libertas_set_scan(struct net_device *dev, struct iw_request_info *info, return 0; } + /** * @brief Send a scan command for all available channels filtered on a spec * + * Used in association code and from debugfs + * * @param priv A pointer to wlan_private structure + * @param ssid A pointer to the SSID to scan for + * @param ssid_len Length of the SSID + * @param clear_ssid Should existing scan results with this SSID + * be cleared? * @param prequestedssid A pointer to AP's ssid * @param keeppreviousscan Flag used to save/clear scan table before scan * @@ -1416,7 +1409,8 @@ int libertas_send_specific_ssid_scan(wlan_private * priv, struct wlan_ioctl_user_scan_cfg scancfg; int ret = 0; - lbs_deb_enter(LBS_DEB_ASSOC); + lbs_deb_enter_args(LBS_DEB_SCAN, "SSID '%s', clear %d", + escape_essid(ssid, ssid_len), clear_ssid); if (!ssid_len) goto out; @@ -1427,47 +1421,27 @@ int libertas_send_specific_ssid_scan(wlan_private * priv, scancfg.clear_ssid = clear_ssid; wlan_scan_networks(priv, &scancfg, 1); - if (adapter->surpriseremoved) - return -1; + if (adapter->surpriseremoved) { + ret = -1; + goto out; + } wait_event_interruptible(adapter->cmd_pending, !adapter->nr_cmd_pending); out: - lbs_deb_leave(LBS_DEB_ASSOC); + lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret); return ret; } -/** - * @brief scan an AP with specific BSSID - * - * @param priv A pointer to wlan_private structure - * @param bssid A pointer to AP's bssid - * @param keeppreviousscan Flag used to save/clear scan table before scan - * - * @return 0-success, otherwise fail - */ -int libertas_send_specific_bssid_scan(wlan_private * priv, u8 * bssid, u8 clear_bssid) -{ - struct wlan_ioctl_user_scan_cfg scancfg; - - lbs_deb_enter(LBS_DEB_ASSOC); - if (bssid == NULL) - goto out; - memset(&scancfg, 0x00, sizeof(scancfg)); - memcpy(scancfg.bssid, bssid, ETH_ALEN); - scancfg.clear_bssid = clear_bssid; - wlan_scan_networks(priv, &scancfg, 1); - if (priv->adapter->surpriseremoved) - return -1; - wait_event_interruptible(priv->adapter->cmd_pending, - !priv->adapter->nr_cmd_pending); +/*********************************************************************/ +/* */ +/* Support for Wireless Extensions */ +/* */ +/*********************************************************************/ -out: - lbs_deb_leave(LBS_DEB_ASSOC); - return 0; -} +#define MAX_CUSTOM_LEN 64 static inline char *libertas_translate_scan(wlan_private *priv, char *start, char *stop, @@ -1483,10 +1457,13 @@ static inline char *libertas_translate_scan(wlan_private *priv, #define RSSI_DIFF ((u8)(PERFECT_RSSI - WORST_RSSI)) u8 rssi; + lbs_deb_enter(LBS_DEB_SCAN); + 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; + start = NULL; + goto out; } /* First entry *MUST* be the AP BSSID */ @@ -1550,7 +1527,7 @@ static inline char *libertas_translate_scan(wlan_private *priv, /* Add encryption capability */ iwe.cmd = SIOCGIWENCODE; - if (bss->privacy) { + if (bss->capability & WLAN_CAPABILITY_PRIVACY) { iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; } else { iwe.u.data.flags = IW_ENCODE_DISABLED; @@ -1565,12 +1542,9 @@ static inline char *libertas_translate_scan(wlan_private *priv, 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) */ - iwe.u.bitrate.value = (rate & 0x7f) * 500000; + for (j = 0; bss->rates[j] && (j < sizeof(bss->rates)); j++) { + /* Bit rate given in 500 kb/s units */ + iwe.u.bitrate.value = bss->rates[j] * 500000; current_val = iwe_stream_add_value(start, current_val, stop, &iwe, IW_EV_PARAM_LEN); } @@ -1605,11 +1579,25 @@ static inline char *libertas_translate_scan(wlan_private *priv, start = iwe_stream_add_point(start, stop, &iwe, buf); } + if (bss->mesh) { + char custom[MAX_CUSTOM_LEN]; + char *p = custom; + + iwe.cmd = IWEVCUSTOM; + p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), + "mesh-type: olpc"); + iwe.u.data.length = p - custom; + if (iwe.u.data.length) + start = iwe_stream_add_point(start, stop, &iwe, custom); + } + +out: + lbs_deb_leave_args(LBS_DEB_SCAN, "start %p", start); return start; } /** - * @brief Retrieve the scan table entries via wireless tools IOCTL call + * @brief Handle Retrieve scan table ioctl * * @param dev A pointer to net_device structure * @param info A pointer to iw_request_info structure @@ -1630,16 +1618,12 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info, 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); + lbs_deb_enter(LBS_DEB_SCAN); /* 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); + libertas_prepare_and_send_command(priv, CMD_802_11_RSSI, 0, + CMD_OPTION_WAITFORRSP, 0, NULL); } mutex_lock(&adapter->lock); @@ -1652,6 +1636,10 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info, break; } + /* For mesh device, list only mesh networks */ + if (dev == priv->mesh_dev && !iter_bss->mesh) + continue; + /* Prune old an old scan result */ stale_time = iter_bss->last_scanned + DEFAULT_MAX_SCAN_AGE; if (time_after(jiffies, stale_time)) { @@ -1672,19 +1660,27 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info, dwrq->length = (ev - extra); dwrq->flags = 0; - lbs_deb_leave(LBS_DEB_ASSOC); + lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", err); return err; } + + + +/*********************************************************************/ +/* */ +/* Command execution */ +/* */ +/*********************************************************************/ + + /** * @brief Prepare a scan command to be sent to the firmware * - * Use the wlan_scan_cmd_config sent to the command processing module in - * the libertas_prepare_and_send_command to configure a cmd_ds_802_11_scan command - * struct to send to firmware. + * Called from libertas_prepare_and_send_command() in cmd.c * - * The fixed fields specifying the BSS type and BSSID filters as well as a - * variable number/length of TLVs are sent in the command to firmware. + * Sends a fixed lenght data part (specifying the BSS type and BSSID filters) + * as well as a variable number/length of TLVs to the firmware. * * @param priv A pointer to wlan_private structure * @param cmd A pointer to cmd_ds_command structure to be sent to @@ -1693,36 +1689,31 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info, * to set the fields/TLVs for the command sent to firmware * * @return 0 or -1 - * - * @sa wlan_scan_create_channel_list */ int libertas_cmd_80211_scan(wlan_private * priv, struct cmd_ds_command *cmd, void *pdata_buf) { struct cmd_ds_802_11_scan *pscan = &cmd->params.scan; - struct wlan_scan_cmd_config *pscancfg; + struct wlan_scan_cmd_config *pscancfg = pdata_buf; - lbs_deb_enter(LBS_DEB_ASSOC); - - pscancfg = pdata_buf; + lbs_deb_enter(LBS_DEB_SCAN); /* Set fixed field variables in scan command */ pscan->bsstype = pscancfg->bsstype; - memcpy(pscan->BSSID, pscancfg->bssid, sizeof(pscan->BSSID)); + memcpy(pscan->bssid, pscancfg->bssid, ETH_ALEN); memcpy(pscan->tlvbuffer, pscancfg->tlvbuffer, pscancfg->tlvbufferlen); - cmd->command = cpu_to_le16(cmd_802_11_scan); + cmd->command = cpu_to_le16(CMD_802_11_SCAN); /* size is equal to the sizeof(fixed portions) + the TLV len + header */ - cmd->size = cpu_to_le16(sizeof(pscan->bsstype) - + sizeof(pscan->BSSID) - + pscancfg->tlvbufferlen + S_DS_GEN); + cmd->size = cpu_to_le16(sizeof(pscan->bsstype) + ETH_ALEN + + pscancfg->tlvbufferlen + S_DS_GEN); - lbs_deb_scan("SCAN_CMD: command=%x, size=%x, seqnum=%x\n", + lbs_deb_scan("SCAN_CMD: command 0x%04x, size %d, seqnum %d\n", le16_to_cpu(cmd->command), le16_to_cpu(cmd->size), le16_to_cpu(cmd->seqnum)); - lbs_deb_leave(LBS_DEB_ASSOC); + lbs_deb_leave(LBS_DEB_SCAN); return 0; } @@ -1741,6 +1732,8 @@ static inline int is_same_network(struct bss_descriptor *src, /** * @brief This function handles the command response of scan * + * Called from handle_cmd_response() in cmdrespc. + * * The response buffer for the scan command has the following * memory layout: * @@ -1766,8 +1759,6 @@ 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 mrvlietypes_data *ptlv; - struct mrvlietypes_tsftimestamp *ptsftlv; struct bss_descriptor * iter_bss; struct bss_descriptor * safe; u8 *pbssinfo; @@ -1777,7 +1768,7 @@ int libertas_ret_80211_scan(wlan_private * priv, struct cmd_ds_command *resp) int tlvbufsize; int ret; - lbs_deb_enter(LBS_DEB_ASSOC); + lbs_deb_enter(LBS_DEB_SCAN); /* Prune old entries from scan table */ list_for_each_entry_safe (iter_bss, safe, &adapter->network_list, list) { @@ -1798,10 +1789,10 @@ int libertas_ret_80211_scan(wlan_private * priv, struct cmd_ds_command *resp) goto done; } - bytesleft = le16_to_cpu(pscan->bssdescriptsize); + bytesleft = le16_to_cpu(get_unaligned((u16*)&pscan->bssdescriptsize)); lbs_deb_scan("SCAN_RESP: bssdescriptsize %d\n", bytesleft); - scanrespsize = le16_to_cpu(resp->size); + scanrespsize = le16_to_cpu(get_unaligned((u16*)&resp->size)); lbs_deb_scan("SCAN_RESP: returned %d AP before parsing\n", pscan->nr_sets); @@ -1816,11 +1807,6 @@ int libertas_ret_80211_scan(wlan_private * priv, struct cmd_ds_command *resp) + sizeof(pscan->nr_sets) + S_DS_GEN); - ptlv = (struct mrvlietypes_data *) (pscan->bssdesc_and_tlvbuffer + bytesleft); - - /* Search the TLV buffer space in the scan response for any valid TLVs */ - wlan_ret_802_11_scan_get_tlv_ptrs(ptlv, tlvbufsize, &ptsftlv); - /* * Process each scan response returned (pscan->nr_sets). Save * the information in the newbssentry and then insert into the @@ -1831,6 +1817,7 @@ int libertas_ret_80211_scan(wlan_private * priv, struct cmd_ds_command *resp) struct bss_descriptor new; struct bss_descriptor * found = NULL; struct bss_descriptor * oldest = NULL; + DECLARE_MAC_BUF(mac); /* Process the data fields and IEs returned for this BSS */ memset(&new, 0, sizeof (struct bss_descriptor)); @@ -1869,19 +1856,8 @@ int libertas_ret_80211_scan(wlan_private * priv, struct cmd_ds_command *resp) 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]); - - /* - * 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_deb_scan("SCAN_RESP: BSSID = %s\n", + print_mac(mac, new.bssid)); /* Copy the locally created newbssentry to the scan table */ memcpy(found, &new, offsetof(struct bss_descriptor, list)); diff --git a/drivers/net/wireless/libertas/scan.h b/drivers/net/wireless/libertas/scan.h index bd019e5ff1e..c29c031bef8 100644 --- a/drivers/net/wireless/libertas/scan.h +++ b/drivers/net/wireless/libertas/scan.h @@ -140,8 +140,7 @@ struct bss_descriptor { u8 ssid[IW_ESSID_MAX_SIZE + 1]; u8 ssid_len; - /* WEP encryption requirement */ - u32 privacy; + u16 capability; /* receive signal strength in dBm */ long rssi; @@ -152,18 +151,16 @@ struct bss_descriptor { u32 atimwindow; + /* IW_MODE_AUTO, IW_MODE_ADHOC, IW_MODE_INFRA */ u8 mode; - u8 libertas_supported_rates[WLAN_SUPPORTED_RATES]; - __le64 timestamp; //!< TSF value included in the beacon/probe response + /* zero-terminated array of supported data rates */ + u8 rates[MAX_RATES + 1]; + unsigned long last_scanned; union ieeetypes_phyparamset phyparamset; union IEEEtypes_ssparamset ssparamset; - struct ieeetypes_capinfo cap; - u8 datarates[WLAN_SUPPORTED_RATES]; - - u64 networktsf; //!< TSF timestamp from the current firmware TSF struct ieeetypes_countryinfofullset countryinfo; @@ -172,34 +169,31 @@ struct bss_descriptor { u8 rsn_ie[MAX_WPA_IE_LEN]; size_t rsn_ie_len; + u8 mesh; + struct list_head list; }; -extern int libertas_ssid_cmp(u8 *ssid1, u8 ssid1_len, u8 *ssid2, u8 ssid2_len); +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, +struct bss_descriptor * libertas_find_bssid_in_list(wlan_adapter * adapter, u8 * bssid, u8 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, u8 *ssid, +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, +int libertas_cmd_80211_scan(wlan_private * priv, struct cmd_ds_command *cmd, void *pdata_buf); -extern int libertas_ret_80211_scan(wlan_private * priv, +int libertas_ret_80211_scan(wlan_private * priv, struct cmd_ds_command *resp); int wlan_scan_networks(wlan_private * priv, @@ -211,9 +205,11 @@ struct ifreq; struct iw_point; struct iw_param; struct iw_request_info; -extern int libertas_get_scan(struct net_device *dev, struct iw_request_info *info, +int libertas_get_scan(struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, char *extra); -extern int libertas_set_scan(struct net_device *dev, struct iw_request_info *info, +int libertas_set_scan(struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra); +void libertas_scan_worker(struct work_struct *work); + #endif /* _WLAN_SCAN_H */ diff --git a/drivers/net/wireless/libertas/thread.h b/drivers/net/wireless/libertas/thread.h deleted file mode 100644 index b1f34d92ff3..00000000000 --- a/drivers/net/wireless/libertas/thread.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef __WLAN_THREAD_H_ -#define __WLAN_THREAD_H_ - -#include <linux/kthread.h> - -struct wlan_thread { - struct task_struct *task; - wait_queue_head_t waitq; - pid_t pid; - void *priv; -}; - -static inline void wlan_activate_thread(struct wlan_thread * thr) -{ - /** Record the thread pid */ - thr->pid = current->pid; - - /** Initialize the wait queue */ - init_waitqueue_head(&thr->waitq); -} - -static inline void wlan_deactivate_thread(struct wlan_thread * thr) -{ - lbs_deb_enter(LBS_DEB_THREAD); - - thr->pid = 0; - - lbs_deb_leave(LBS_DEB_THREAD); -} - -static inline void wlan_create_thread(int (*wlanfunc) (void *), - struct wlan_thread * thr, char *name) -{ - thr->task = kthread_run(wlanfunc, thr, "%s", name); -} - -static inline int wlan_terminate_thread(struct wlan_thread * thr) -{ - lbs_deb_enter(LBS_DEB_THREAD); - - /* Check if the thread is active or not */ - if (!thr->pid) { - printk(KERN_ERR "Thread does not exist\n"); - return -1; - } - kthread_stop(thr->task); - - lbs_deb_leave(LBS_DEB_THREAD); - return 0; -} - -#endif diff --git a/drivers/net/wireless/libertas/tx.c b/drivers/net/wireless/libertas/tx.c index 17c437635a0..fbec06c10dd 100644 --- a/drivers/net/wireless/libertas/tx.c +++ b/drivers/net/wireless/libertas/tx.c @@ -58,7 +58,6 @@ static u32 convert_radiotap_rate_to_mv(u8 rate) */ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb) { - wlan_adapter *adapter = priv->adapter; int ret = 0; struct txpd localtxpd; struct txpd *plocaltxpd = &localtxpd; @@ -72,10 +71,6 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb) if (priv->adapter->surpriseremoved) return -1; - if ((priv->adapter->debugmode & MRVDRV_DEBUG_TX_PATH) != 0) - lbs_dbg_hex("TX packet: ", skb->data, - min_t(unsigned int, skb->len, 100)); - if (!skb->len || (skb->len > MRVDRV_ETH_TX_PACKET_BUFFER_SIZE)) { lbs_deb_tx("tx err: skb length %d 0 or > %zd\n", skb->len, MRVDRV_ETH_TX_PACKET_BUFFER_SIZE); @@ -90,11 +85,8 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb) /* offset of actual data */ plocaltxpd->tx_packet_location = cpu_to_le32(sizeof(struct txpd)); - /* TxCtrl set by user or default */ - plocaltxpd->tx_control = cpu_to_le32(adapter->pkttxctrl); - p802x_hdr = skb->data; - if (priv->adapter->radiomode == WLAN_RADIOMODE_RADIOTAP) { + if (priv->adapter->monitormode != WLAN_MONITOR_OFF) { /* locate radiotap header */ pradiotap_hdr = (struct tx_radiotap_hdr *)skb->data; @@ -103,7 +95,6 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb) new_rate = convert_radiotap_rate_to_mv(pradiotap_hdr->rate); if (new_rate != 0) { /* use new tx_control[4:0] */ - new_rate |= (adapter->pkttxctrl & ~0x1f); plocaltxpd->tx_control = cpu_to_le32(new_rate); } @@ -115,12 +106,12 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb) } /* copy destination address from 802.3 or 802.11 header */ - if (priv->adapter->linkmode == WLAN_LINKMODE_802_11) + if (priv->adapter->monitormode != WLAN_MONITOR_OFF) memcpy(plocaltxpd->tx_dest_addr_high, p802x_hdr + 4, ETH_ALEN); else memcpy(plocaltxpd->tx_dest_addr_high, p802x_hdr, ETH_ALEN); - lbs_dbg_hex("txpd", (u8 *) plocaltxpd, sizeof(struct txpd)); + lbs_deb_hex(LBS_DEB_TX, "txpd", (u8 *) plocaltxpd, sizeof(struct txpd)); if (IS_MESH_FRAME(skb)) { plocaltxpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME); @@ -130,7 +121,7 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb) ptr += sizeof(struct txpd); - lbs_dbg_hex("Tx Data", (u8 *) p802x_hdr, le16_to_cpu(plocaltxpd->tx_packet_length)); + lbs_deb_hex(LBS_DEB_TX, "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, @@ -153,13 +144,14 @@ done: priv->stats.tx_errors++; } - if (!ret && priv->adapter->radiomode == WLAN_RADIOMODE_RADIOTAP) { + if (!ret && priv->adapter->monitormode != WLAN_MONITOR_OFF) { /* Keep the skb to echo it back once Tx feedback is received from FW */ skb_orphan(skb); /* stop processing outgoing pkts */ netif_stop_queue(priv->dev); - netif_stop_queue(priv->mesh_dev); + if (priv->mesh_dev) + netif_stop_queue(priv->mesh_dev); /* freeze any packets already in our queues */ priv->adapter->TxLockFlag = 1; } else { @@ -198,10 +190,12 @@ static void wlan_tx_queue(wlan_private *priv, struct sk_buff *skb) adapter->tx_queue_ps[adapter->tx_queue_idx++] = skb; if (adapter->tx_queue_idx == NR_TX_QUEUE) { netif_stop_queue(priv->dev); - netif_stop_queue(priv->mesh_dev); + if (priv->mesh_dev) + netif_stop_queue(priv->mesh_dev); } else { netif_start_queue(priv->dev); - netif_start_queue(priv->mesh_dev); + if (priv->mesh_dev) + netif_start_queue(priv->mesh_dev); } spin_unlock(&adapter->txqueue_lock); @@ -219,7 +213,7 @@ int libertas_process_tx(wlan_private * priv, struct sk_buff *skb) int ret = -1; lbs_deb_enter(LBS_DEB_TX); - lbs_dbg_hex("TX Data", skb->data, min_t(unsigned int, skb->len, 100)); + lbs_deb_hex(LBS_DEB_TX, "TX Data", skb->data, min_t(unsigned int, skb->len, 100)); if (priv->dnld_sent) { lbs_pr_alert( "TX error: dnld_sent = %d, not sending\n", @@ -258,16 +252,12 @@ void libertas_send_tx_feedback(wlan_private * priv) int txfail; int try_count; - if (adapter->radiomode != WLAN_RADIOMODE_RADIOTAP || + if (adapter->monitormode == WLAN_MONITOR_OFF || adapter->currenttxskb == NULL) return; radiotap_hdr = (struct tx_radiotap_hdr *)adapter->currenttxskb->data; - if ((adapter->debugmode & MRVDRV_DEBUG_TX_PATH) != 0) - lbs_dbg_hex("TX feedback: ", (u8 *) radiotap_hdr, - min_t(unsigned int, adapter->currenttxskb->len, 100)); - txfail = (status >> 24); #if 0 @@ -283,9 +273,10 @@ 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) { + if (priv->adapter->connect_status == LIBERTAS_CONNECTED) { netif_wake_queue(priv->dev); - netif_wake_queue(priv->mesh_dev); + if (priv->mesh_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 028e2f3b53d..a43a5f63c87 100644 --- a/drivers/net/wireless/libertas/types.h +++ b/drivers/net/wireless/libertas/types.h @@ -7,71 +7,6 @@ #include <linux/if_ether.h> #include <asm/byteorder.h> -/** IEEE type definitions */ -enum ieeetypes_elementid { - SSID = 0, - SUPPORTED_RATES, - FH_PARAM_SET, - DS_PARAM_SET, - CF_PARAM_SET, - TIM, - IBSS_PARAM_SET, - COUNTRY_INFO = 7, - - CHALLENGE_TEXT = 16, - - EXTENDED_SUPPORTED_RATES = 50, - - VENDOR_SPECIFIC_221 = 221, - - WPA_IE = 221, - WPA2_IE = 48, - - 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; - u8 cfpollrqst:1; - u8 privacy:1; - u8 shortpreamble:1; - u8 pbcc:1; - u8 chanagility:1; - u8 spectrummgmt:1; - u8 rsrvd3:1; - u8 shortslottime:1; - u8 apsd:1; - u8 rsvrd2:1; - u8 dsssofdm:1; - u8 rsrvd1:2; -#endif -} __attribute__ ((packed)); - struct ieeetypes_cfparamset { u8 elementid; u8 len; @@ -114,7 +49,7 @@ union ieeetypes_phyparamset { } __attribute__ ((packed)); struct ieeetypes_assocrsp { - struct ieeetypes_capinfo capability; + __le16 capability; __le16 statuscode; __le16 aid; u8 iebuffer[1]; diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c index 2fcc3bf2108..c6f5aa3cb46 100644 --- a/drivers/net/wireless/libertas/wext.c +++ b/drivers/net/wireless/libertas/wext.c @@ -22,60 +22,6 @@ /** - * 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 - * @return the value of dbm - */ -static int mw_to_dbm(int mw) -{ - if (mw < 2) - return 0; - else if (mw < 3) - return 3; - else if (mw < 4) - return 5; - else if (mw < 6) - return 7; - else if (mw < 7) - return 8; - else if (mw < 8) - return 9; - else if (mw < 10) - return 10; - else if (mw < 13) - return 11; - else if (mw < 16) - return 12; - else if (mw < 20) - return 13; - else if (mw < 25) - return 14; - else if (mw < 32) - return 15; - else if (mw < 40) - return 16; - else if (mw < 50) - return 17; - else if (mw < 63) - return 18; - else if (mw < 79) - return 19; - else if (mw < 100) - return 20; - else - return 21; -} - -/** * @brief Find the channel frequency power info with specific channel * * @param adapter A pointer to wlan_adapter structure @@ -165,7 +111,7 @@ static struct chan_freq_power *find_cfp_by_band_and_freq(wlan_adapter * adapter, * @option Radio Option * @return 0 --success, otherwise fail */ -int wlan_radio_ioctl(wlan_private * priv, u8 option) +static int wlan_radio_ioctl(wlan_private * priv, u8 option) { int ret = 0; wlan_adapter *adapter = priv->adapter; @@ -177,9 +123,9 @@ int wlan_radio_ioctl(wlan_private * priv, u8 option) adapter->radioon = option; ret = libertas_prepare_and_send_command(priv, - cmd_802_11_radio_control, - cmd_act_set, - cmd_option_waitforrsp, 0, NULL); + CMD_802_11_RADIO_CONTROL, + CMD_ACT_SET, + CMD_OPTION_WAITFORRSP, 0, NULL); } lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); @@ -187,84 +133,31 @@ int wlan_radio_ioctl(wlan_private * priv, u8 option) } /** - * @brief Copy rates - * - * @param dest A pointer to Dest Buf - * @param src A pointer to Src Buf - * @param len The len of Src Buf - * @return Number of rates copyed - */ -static inline int copyrates(u8 * dest, int pos, u8 * src, int len) -{ - int i; - - for (i = 0; i < len && src[i]; i++, pos++) { - if (pos >= sizeof(u8) * WLAN_SUPPORTED_RATES) - break; - dest[pos] = src[i]; - } - - return pos; -} - -/** - * @brief Get active data rates + * @brief Copy active data rates based on adapter mode and status * * @param adapter A pointer to wlan_adapter structure * @param rate The buf to return the active rates - * @return The number of rates */ -static int get_active_data_rates(wlan_adapter * adapter, - u8* rates) +static void copy_active_data_rates(wlan_adapter * adapter, u8 * rates) { - int k = 0; - lbs_deb_enter(LBS_DEB_WEXT); - if (adapter->connect_status != libertas_connected) { - if (adapter->mode == IW_MODE_INFRA) { - lbs_deb_wext("infra\n"); - k = copyrates(rates, k, libertas_supported_rates, - sizeof(libertas_supported_rates)); - } else { - lbs_deb_wext("Adhoc G\n"); - k = copyrates(rates, k, libertas_adhoc_rates_g, - sizeof(libertas_adhoc_rates_g)); - } - } else { - k = copyrates(rates, 0, adapter->curbssparams.datarates, - adapter->curbssparams.numofrates); - } + if (adapter->connect_status != LIBERTAS_CONNECTED) + memcpy(rates, libertas_bg_rates, MAX_RATES); + else + memcpy(rates, adapter->curbssparams.rates, MAX_RATES); - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", k); - return k; + lbs_deb_leave(LBS_DEB_WEXT); } static int wlan_get_name(struct net_device *dev, struct iw_request_info *info, char *cwrq, char *extra) { - const char *cp; - char comm[6] = { "COMM-" }; - char mrvl[6] = { "MRVL-" }; - int cnt; lbs_deb_enter(LBS_DEB_WEXT); - strcpy(cwrq, mrvl); - - cp = strstr(libertas_driver_version, comm); - if (cp == libertas_driver_version) //skip leading "COMM-" - cp = libertas_driver_version + strlen(comm); - else - cp = libertas_driver_version; - - cnt = strlen(mrvl); - cwrq += cnt; - while (cnt < 16 && (*cp != '-')) { - *cwrq++ = toupper(*cp++); - cnt++; - } - *cwrq = '\0'; + /* We could add support for 802.11n here as needed. Jean II */ + snprintf(cwrq, IFNAMSIZ, "IEEE 802.11b/g"); lbs_deb_leave(LBS_DEB_WEXT); return 0; @@ -305,7 +198,7 @@ static int wlan_get_wap(struct net_device *dev, struct iw_request_info *info, lbs_deb_enter(LBS_DEB_WEXT); - if (adapter->connect_status == libertas_connected) { + if (adapter->connect_status == LIBERTAS_CONNECTED) { memcpy(awrq->sa_data, adapter->curbssparams.bssid, ETH_ALEN); } else { memset(awrq->sa_data, 0, ETH_ALEN); @@ -349,24 +242,11 @@ static int wlan_get_nick(struct net_device *dev, struct iw_request_info *info, lbs_deb_enter(LBS_DEB_WEXT); - /* - * Get the Nick Name saved - */ - - mutex_lock(&adapter->lock); - strncpy(extra, adapter->nodename, 16); - mutex_unlock(&adapter->lock); - - extra[16] = '\0'; + dwrq->length = strlen(adapter->nodename); + memcpy(extra, adapter->nodename, dwrq->length); + extra[dwrq->length] = '\0'; - /* - * If none, we may want to get the one that was set - */ - - /* - * Push it out ! - */ - dwrq->length = strlen(extra) + 1; + dwrq->flags = 1; /* active */ lbs_deb_leave(LBS_DEB_WEXT); return 0; @@ -382,20 +262,21 @@ static int mesh_get_nick(struct net_device *dev, struct iw_request_info *info, /* Use nickname to indicate that mesh is on */ - if (adapter->connect_status == libertas_connected) { + if (adapter->connect_status == LIBERTAS_CONNECTED) { strncpy(extra, "Mesh", 12); extra[12] = '\0'; - dwrq->length = strlen(extra) + 1; + dwrq->length = strlen(extra); } else { extra[0] = '\0'; - dwrq->length = 1 ; + dwrq->length = 0; } 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) { @@ -414,8 +295,8 @@ static int wlan_set_rts(struct net_device *dev, struct iw_request_info *info, adapter->rtsthsd = rthr; } - ret = libertas_prepare_and_send_command(priv, cmd_802_11_snmp_mib, - cmd_act_set, cmd_option_waitforrsp, + ret = libertas_prepare_and_send_command(priv, CMD_802_11_SNMP_MIB, + CMD_ACT_SET, CMD_OPTION_WAITFORRSP, OID_802_11_RTS_THRESHOLD, &rthr); lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); @@ -432,8 +313,8 @@ static int wlan_get_rts(struct net_device *dev, struct iw_request_info *info, 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, + 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) goto out; @@ -467,8 +348,8 @@ static int wlan_set_frag(struct net_device *dev, struct iw_request_info *info, adapter->fragthsd = fthr; } - ret = libertas_prepare_and_send_command(priv, cmd_802_11_snmp_mib, - cmd_act_set, cmd_option_waitforrsp, + ret = libertas_prepare_and_send_command(priv, CMD_802_11_SNMP_MIB, + CMD_ACT_SET, CMD_OPTION_WAITFORRSP, OID_802_11_FRAGMENTATION_THRESHOLD, &fthr); lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); @@ -486,8 +367,8 @@ static int wlan_get_frag(struct net_device *dev, struct iw_request_info *info, adapter->fragthsd = 0; ret = libertas_prepare_and_send_command(priv, - cmd_802_11_snmp_mib, - cmd_act_get, cmd_option_waitforrsp, + CMD_802_11_SNMP_MIB, + CMD_ACT_GET, CMD_OPTION_WAITFORRSP, OID_802_11_FRAGMENTATION_THRESHOLD, NULL); if (ret) goto out; @@ -539,9 +420,9 @@ static int wlan_get_txpow(struct net_device *dev, 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); + CMD_802_11_RF_TX_POWER, + CMD_ACT_TX_POWER_OPT_GET, + CMD_OPTION_WAITFORRSP, 0, NULL); if (ret) goto out; @@ -581,9 +462,9 @@ static int wlan_set_retry(struct net_device *dev, struct iw_request_info *info, /* Adding 1 to convert retry count to try count */ adapter->txretrycount = vwrq->value + 1; - ret = libertas_prepare_and_send_command(priv, cmd_802_11_snmp_mib, - cmd_act_set, - cmd_option_waitforrsp, + ret = libertas_prepare_and_send_command(priv, CMD_802_11_SNMP_MIB, + CMD_ACT_SET, + CMD_OPTION_WAITFORRSP, OID_802_11_TX_RETRYCOUNT, NULL); if (ret) @@ -608,8 +489,8 @@ static int wlan_get_retry(struct net_device *dev, struct iw_request_info *info, adapter->txretrycount = 0; ret = libertas_prepare_and_send_command(priv, - cmd_802_11_snmp_mib, - cmd_act_get, cmd_option_waitforrsp, + CMD_802_11_SNMP_MIB, + CMD_ACT_GET, CMD_OPTION_WAITFORRSP, OID_802_11_TX_RETRYCOUNT, NULL); if (ret) goto out; @@ -673,7 +554,7 @@ static int wlan_get_range(struct net_device *dev, struct iw_request_info *info, wlan_adapter *adapter = priv->adapter; struct iw_range *range = (struct iw_range *)extra; struct chan_freq_power *cfp; - u8 rates[WLAN_SUPPORTED_RATES]; + u8 rates[MAX_RATES + 1]; u8 flag = 0; @@ -686,19 +567,17 @@ static int wlan_get_range(struct net_device *dev, struct iw_request_info *info, range->max_nwid = 0; memset(rates, 0, sizeof(rates)); - range->num_bitrates = get_active_data_rates(adapter, rates); - - for (i = 0; i < min_t(__u8, range->num_bitrates, IW_MAX_BITRATES) && rates[i]; - i++) { - range->bitrate[i] = (rates[i] & 0x7f) * 500000; - } + copy_active_data_rates(adapter, rates); + range->num_bitrates = strnlen(rates, IW_MAX_BITRATES); + for (i = 0; i < range->num_bitrates; i++) + range->bitrate[i] = rates[i] * 500000; range->num_bitrates = i; lbs_deb_wext("IW_MAX_BITRATES %d, num_bitrates %d\n", IW_MAX_BITRATES, range->num_bitrates); range->num_frequency = 0; if (priv->adapter->enable11d && - adapter->connect_status == libertas_connected) { + adapter->connect_status == LIBERTAS_CONNECTED) { u8 chan_no; u8 band; @@ -858,9 +737,9 @@ static int wlan_set_power(struct net_device *dev, struct iw_request_info *info, */ if (vwrq->disabled) { - adapter->psmode = wlan802_11powermodecam; + adapter->psmode = WLAN802_11POWERMODECAM; if (adapter->psstate != PS_STATE_FULL_POWER) { - libertas_ps_wakeup(priv, cmd_option_waitforrsp); + libertas_ps_wakeup(priv, CMD_OPTION_WAITFORRSP); } return 0; @@ -875,14 +754,14 @@ static int wlan_set_power(struct net_device *dev, struct iw_request_info *info, return -EINVAL; } - if (adapter->psmode != wlan802_11powermodecam) { + if (adapter->psmode != WLAN802_11POWERMODECAM) { return 0; } - adapter->psmode = wlan802_11powermodemax_psp; + adapter->psmode = WLAN802_11POWERMODEMAX_PSP; - if (adapter->connect_status == libertas_connected) { - libertas_ps_sleep(priv, cmd_option_waitforrsp); + if (adapter->connect_status == LIBERTAS_CONNECTED) { + libertas_ps_sleep(priv, CMD_OPTION_WAITFORRSP); } lbs_deb_leave(LBS_DEB_WEXT); @@ -900,8 +779,8 @@ static int wlan_get_power(struct net_device *dev, struct iw_request_info *info, mode = adapter->psmode; - if ((vwrq->disabled = (mode == wlan802_11powermodecam)) - || adapter->connect_status == libertas_disconnected) + if ((vwrq->disabled = (mode == WLAN802_11POWERMODECAM)) + || adapter->connect_status == LIBERTAS_DISCONNECTED) { goto out; } @@ -937,7 +816,7 @@ static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev) priv->wstats.status = adapter->mode; /* If we're not associated, all quality values are meaningless */ - if (adapter->connect_status != libertas_connected) + if (adapter->connect_status != LIBERTAS_CONNECTED) goto out; /* Quality by RSSI */ @@ -973,7 +852,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 = le16_to_cpu(adapter->logmsg.retry); + tx_retries = le32_to_cpu(adapter->logmsg.retry); if (tx_retries > 75) tx_qual = (90 - tx_retries) * POOR / 15; @@ -989,20 +868,20 @@ 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 = le16_to_cpu(adapter->logmsg.wepundecryptable); - priv->wstats.discard.fragment = le16_to_cpu(adapter->logmsg.rxfrag); + priv->wstats.discard.code = le32_to_cpu(adapter->logmsg.wepundecryptable); + priv->wstats.discard.fragment = le32_to_cpu(adapter->logmsg.rxfrag); priv->wstats.discard.retries = tx_retries; - priv->wstats.discard.misc = le16_to_cpu(adapter->logmsg.ackfailure); + priv->wstats.discard.misc = le32_to_cpu(adapter->logmsg.ackfailure); /* Calculate quality */ - priv->wstats.qual.qual = max(quality, (u32)100); + priv->wstats.qual.qual = min_t(u8, quality, 100); priv->wstats.qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; stats_valid = 1; /* update stats asynchronously for future calls */ - libertas_prepare_and_send_command(priv, cmd_802_11_rssi, 0, + libertas_prepare_and_send_command(priv, CMD_802_11_RSSI, 0, 0, 0, NULL); - libertas_prepare_and_send_command(priv, cmd_802_11_get_log, 0, + libertas_prepare_and_send_command(priv, CMD_802_11_GET_LOG, 0, 0, 0, NULL); out: if (!stats_valid) { @@ -1080,88 +959,46 @@ out: return ret; } -/** - * @brief use index to get the data rate - * - * @param index The index of data rate - * @return data rate or 0 - */ -u32 libertas_index_to_data_rate(u8 index) -{ - if (index >= sizeof(libertas_wlan_data_rates)) - index = 0; - - return libertas_wlan_data_rates[index]; -} - -/** - * @brief use rate to get the index - * - * @param rate data rate - * @return index or 0 - */ -u8 libertas_data_rate_to_index(u32 rate) -{ - u8 *ptr; - - if (rate) - if ((ptr = memchr(libertas_wlan_data_rates, (u8) rate, - sizeof(libertas_wlan_data_rates)))) - return (ptr - libertas_wlan_data_rates); - - return 0; -} - static int wlan_set_rate(struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra) { wlan_private *priv = dev->priv; wlan_adapter *adapter = priv->adapter; - u32 data_rate; + u32 new_rate; u16 action; - int ret = 0; - u8 rates[WLAN_SUPPORTED_RATES]; - u8 *rate; + int ret = -EINVAL; + u8 rates[MAX_RATES + 1]; lbs_deb_enter(LBS_DEB_WEXT); - lbs_deb_wext("vwrq->value %d\n", vwrq->value); + /* Auto rate? */ if (vwrq->value == -1) { - action = cmd_act_set_tx_auto; // Auto - adapter->is_datarate_auto = 1; - adapter->datarate = 0; + action = CMD_ACT_SET_TX_AUTO; + adapter->auto_rate = 1; + adapter->cur_rate = 0; } else { - if (vwrq->value % 100000) { - return -EINVAL; - } - - data_rate = vwrq->value / 500000; + if (vwrq->value % 100000) + goto out; memset(rates, 0, sizeof(rates)); - get_active_data_rates(adapter, rates); - rate = rates; - while (*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("fixed data rate 0x%X out " - "of range\n", data_rate); - return -EINVAL; + copy_active_data_rates(adapter, rates); + new_rate = vwrq->value / 500000; + if (!memchr(rates, new_rate, sizeof(rates))) { + lbs_pr_alert("fixed data rate 0x%X out of range\n", + new_rate); + goto out; } - adapter->datarate = data_rate; - action = cmd_act_set_tx_fix_rate; - adapter->is_datarate_auto = 0; + adapter->cur_rate = new_rate; + action = CMD_ACT_SET_TX_FIX_RATE; + adapter->auto_rate = 0; } - ret = libertas_prepare_and_send_command(priv, cmd_802_11_data_rate, - action, cmd_option_waitforrsp, 0, NULL); + ret = libertas_prepare_and_send_command(priv, CMD_802_11_DATA_RATE, + action, CMD_OPTION_WAITFORRSP, 0, NULL); +out: lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); return ret; } @@ -1174,14 +1011,19 @@ static int wlan_get_rate(struct net_device *dev, struct iw_request_info *info, lbs_deb_enter(LBS_DEB_WEXT); - if (adapter->is_datarate_auto) { - vwrq->fixed = 0; + if (adapter->connect_status == LIBERTAS_CONNECTED) { + vwrq->value = adapter->cur_rate * 500000; + + if (adapter->auto_rate) + vwrq->fixed = 0; + else + vwrq->fixed = 1; + } else { - vwrq->fixed = 1; + vwrq->fixed = 0; + vwrq->value = 0; } - vwrq->value = adapter->datarate * 500000; - lbs_deb_leave(LBS_DEB_WEXT); return 0; } @@ -1298,7 +1140,7 @@ static int wlan_get_encode(struct net_device *dev, dwrq->flags |= IW_ENCODE_NOKEY; - lbs_deb_wext("key: " MAC_FMT ", keylen %d\n", + lbs_deb_wext("key: %02x:%02x:%02x:%02x:%02x:%02x, keylen %d\n", extra[0], extra[1], extra[2], extra[3], extra[4], extra[5], dwrq->length); @@ -1325,7 +1167,7 @@ static int wlan_set_wep_key(struct assoc_request *assoc_req, int set_tx_key) { int ret = 0; - struct WLAN_802_11_KEY *pkey; + struct enc_key *pkey; lbs_deb_enter(LBS_DEB_WEXT); @@ -1344,7 +1186,7 @@ static int wlan_set_wep_key(struct assoc_request *assoc_req, pkey = &assoc_req->wep_keys[index]; if (key_length > 0) { - memset(pkey, 0, sizeof(struct WLAN_802_11_KEY)); + memset(pkey, 0, sizeof(struct enc_key)); pkey->type = KEY_TYPE_ID_WEP; /* Standardize the key length */ @@ -1412,11 +1254,11 @@ 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)); + memset(&assoc_req->wpa_mcast_key, 0, sizeof (struct enc_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)); + memset(&assoc_req->wpa_unicast_key, 0, sizeof (struct enc_key)); assoc_req->wpa_unicast_key.flags = KEY_INFO_WPA_UNICAST; set_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags); @@ -1567,7 +1409,7 @@ static int wlan_get_encodeext(struct net_device *dev, && (adapter->secinfo.WPAenabled || adapter->secinfo.WPA2enabled)) { /* WPA */ - struct WLAN_802_11_KEY * pkey = NULL; + struct enc_key * pkey = NULL; if ( adapter->wpa_mcast_key.len && (adapter->wpa_mcast_key.flags & KEY_INFO_WPA_ENABLED)) @@ -1679,7 +1521,7 @@ static int wlan_set_encodeext(struct net_device *dev, 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; + struct enc_key * pkey; /* validate key length */ if (((alg == IW_ENCODE_ALG_TKIP) @@ -1702,7 +1544,7 @@ static int wlan_set_encodeext(struct net_device *dev, set_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags); } - memset(pkey, 0, sizeof (struct WLAN_802_11_KEY)); + memset(pkey, 0, sizeof (struct enc_key)); memcpy(pkey->key, ext->key, ext->key_len); pkey->len = ext->key_len; if (pkey->len) @@ -1976,12 +1818,14 @@ static int wlan_set_txpow(struct net_device *dev, struct iw_request_info *info, return 0; } - adapter->preamble = cmd_type_auto_preamble; + adapter->preamble = CMD_TYPE_AUTO_PREAMBLE; wlan_radio_ioctl(priv, RADIO_ON); + /* Userspace check in iwrange if it should use dBm or mW, + * therefore this should never happen... Jean II */ if ((vwrq->flags & IW_TXPOW_TYPE) == IW_TXPOW_MWATT) { - dbm = (u16) mw_to_dbm(vwrq->value); + return -EOPNOTSUPP; } else dbm = (u16) vwrq->value; @@ -1993,9 +1837,9 @@ static int wlan_set_txpow(struct net_device *dev, struct iw_request_info *info, 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); + CMD_802_11_RF_TX_POWER, + CMD_ACT_TX_POWER_OPT_SET_LOW, + CMD_OPTION_WAITFORRSP, 0, (void *)&dbm); lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); return ret; @@ -2017,7 +1861,7 @@ static int wlan_get_essid(struct net_device *dev, struct iw_request_info *info, /* * Get the current SSID */ - if (adapter->connect_status == libertas_connected) { + if (adapter->connect_status == LIBERTAS_CONNECTED) { memcpy(extra, adapter->curbssparams.ssid, adapter->curbssparams.ssid_len); extra[adapter->curbssparams.ssid_len] = '\0'; @@ -2029,12 +1873,7 @@ static int wlan_get_essid(struct net_device *dev, struct iw_request_info *info, * If none, we may want to get the one that was set */ - /* 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_len, - IW_ESSID_MAX_SIZE); - else - dwrq->length = adapter->curbssparams.ssid_len + 1; + dwrq->length = adapter->curbssparams.ssid_len; dwrq->flags = 1; /* active */ @@ -2055,14 +1894,6 @@ static int wlan_set_essid(struct net_device *dev, struct iw_request_info *info, 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 ((in_ssid_len > 0) && (extra[in_ssid_len - 1] == '\0')) - in_ssid_len--; - /* Check the size of the string */ if (in_ssid_len > IW_ESSID_MAX_SIZE) { ret = -E2BIG; @@ -2129,13 +1960,14 @@ static int wlan_set_wap(struct net_device *dev, struct iw_request_info *info, wlan_adapter *adapter = priv->adapter; struct assoc_request * assoc_req; int ret = 0; + DECLARE_MAC_BUF(mac); lbs_deb_enter(LBS_DEB_WEXT); if (awrq->sa_family != ARPHRD_ETHER) return -EINVAL; - lbs_deb_wext("ASSOC: WAP: sa_data " MAC_FMT "\n", MAC_ARG(awrq->sa_data)); + lbs_deb_wext("ASSOC: WAP: sa_data %s\n", print_mac(mac, awrq->sa_data)); mutex_lock(&adapter->lock); @@ -2298,13 +2130,13 @@ static const iw_handler mesh_wlan_handler[] = { (iw_handler) NULL, /* SIOCSIWPMKSA */ }; struct iw_handler_def libertas_handler_def = { - .num_standard = sizeof(wlan_handler) / sizeof(iw_handler), + .num_standard = ARRAY_SIZE(wlan_handler), .standard = (iw_handler *) wlan_handler, .get_wireless_stats = wlan_get_wireless_stats, }; struct iw_handler_def mesh_handler_def = { - .num_standard = sizeof(mesh_wlan_handler) / sizeof(iw_handler), + .num_standard = ARRAY_SIZE(mesh_wlan_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 3d5196c9553..6aa444c7de8 100644 --- a/drivers/net/wireless/libertas/wext.h +++ b/drivers/net/wireless/libertas/wext.h @@ -4,9 +4,6 @@ #ifndef _WLAN_WEXT_H_ #define _WLAN_WEXT_H_ -#define SUBCMD_OFFSET 4 -#define SUBCMD_DATA(x) *((int *)(x->u.name + SUBCMD_OFFSET)) - /** wlan_ioctl_regrdwr */ struct wlan_ioctl_regrdwr { /** Which register to access */ @@ -18,13 +15,9 @@ 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 +#define WLAN_MONITOR_OFF 0 extern struct iw_handler_def libertas_handler_def; extern struct iw_handler_def mesh_handler_def; -int wlan_radio_ioctl(wlan_private * priv, u8 option); #endif /* _WLAN_WEXT_H_ */ |