Commit 12b90de6 authored by Jeff Garzik's avatar Jeff Garzik

Merge branch 'libertas' of...

Merge branch 'libertas' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6 into upstream-fixes
parents 6f8a7c66 717c9339
......@@ -266,16 +266,23 @@ config IPW2200_DEBUG
If you are not sure, say N here.
config LIBERTAS_USB
tristate "Marvell Libertas 8388 802.11a/b/g cards"
depends on USB && WLAN_80211
config LIBERTAS
tristate "Marvell 8xxx Libertas WLAN driver support"
depends on WLAN_80211
select IEEE80211
select FW_LOADER
---help---
A library for Marvell Libertas 8xxx devices.
config LIBERTAS_USB
tristate "Marvell Libertas 8388 USB 802.11b/g cards"
depends on LIBERTAS && USB
---help---
A driver for Marvell Libertas 8388 USB devices.
config LIBERTAS_USB_DEBUG
bool "Enable full debugging output in the Libertas USB module."
depends on LIBERTAS_USB
config LIBERTAS_DEBUG
bool "Enable full debugging output in the Libertas module."
depends on LIBERTAS
---help---
Debugging support.
......
......@@ -95,7 +95,7 @@ static u8 wlan_get_chan_11d(u8 band, u8 firstchan, u8 nrchan, u8 * chan)
for (i = 0; i < cfp_no; i++) {
if ((cfp + i)->channel == firstchan) {
lbs_pr_debug(1, "firstchan found\n");
lbs_deb_11d("firstchan found\n");
break;
}
}
......@@ -129,12 +129,12 @@ static u8 wlan_channel_known_11d(u8 chan,
for (i = 0; i < nr_chan; i++) {
if (chan == chanpwr[i].chan) {
lbs_pr_debug(1, "11D: Found Chan:%d\n", chan);
lbs_deb_11d("11D: Found Chan:%d\n", chan);
return 1;
}
}
lbs_pr_debug(1, "11D: Not Find Chan:%d\n", chan);
lbs_deb_11d("11D: Not Find Chan:%d\n", chan);
return 0;
}
......@@ -174,7 +174,7 @@ static int generate_domain_info_11d(struct parsed_region_chan_11d
memcpy(domaininfo->countrycode, parsed_region_chan->countrycode,
COUNTRY_CODE_LEN);
lbs_pr_debug(1, "11D:nrchan=%d\n", nr_chan);
lbs_deb_11d("11D:nrchan=%d\n", nr_chan);
lbs_dbg_hex("11D:parsed_region_chan:", (char *)parsed_region_chan,
sizeof(struct parsed_region_chan_11d));
......@@ -212,7 +212,7 @@ static int generate_domain_info_11d(struct parsed_region_chan_11d
}
domaininfo->nr_subband = nr_subband;
lbs_pr_debug(1, "nr_subband=%x\n", domaininfo->nr_subband);
lbs_deb_11d("nr_subband=%x\n", domaininfo->nr_subband);
lbs_dbg_hex("11D:domaininfo:", (char *)domaininfo,
COUNTRY_CODE_LEN + 1 +
sizeof(struct ieeetypes_subbandset) * nr_subband);
......@@ -233,13 +233,13 @@ static void wlan_generate_parsed_region_chan_11d(struct region_channel * region_
struct chan_freq_power *cfp;
if (region_chan == NULL) {
lbs_pr_debug(1, "11D: region_chan is NULL\n");
lbs_deb_11d("11D: region_chan is NULL\n");
return;
}
cfp = region_chan->CFP;
if (cfp == NULL) {
lbs_pr_debug(1, "11D: cfp equal NULL \n");
lbs_deb_11d("11D: cfp equal NULL \n");
return;
}
......@@ -248,19 +248,19 @@ static void wlan_generate_parsed_region_chan_11d(struct region_channel * region_
memcpy(parsed_region_chan->countrycode,
wlan_code_2_region(region_chan->region), COUNTRY_CODE_LEN);
lbs_pr_debug(1, "11D: region[0x%x] band[%d]\n", parsed_region_chan->region,
lbs_deb_11d("11D: region[0x%x] band[%d]\n", parsed_region_chan->region,
parsed_region_chan->band);
for (i = 0; i < region_chan->nrcfp; i++, cfp++) {
parsed_region_chan->chanpwr[i].chan = cfp->channel;
parsed_region_chan->chanpwr[i].pwr = cfp->maxtxpower;
lbs_pr_debug(1, "11D: Chan[%d] Pwr[%d]\n",
lbs_deb_11d("11D: Chan[%d] Pwr[%d]\n",
parsed_region_chan->chanpwr[i].chan,
parsed_region_chan->chanpwr[i].pwr);
}
parsed_region_chan->nr_chan = region_chan->nrcfp;
lbs_pr_debug(1, "11D: nrchan[%d]\n", parsed_region_chan->nr_chan);
lbs_deb_11d("11D: nrchan[%d]\n", parsed_region_chan->nr_chan);
return;
}
......@@ -277,8 +277,9 @@ static u8 wlan_region_chan_supported_11d(u8 region, u8 band, u8 chan)
struct chan_freq_power *cfp;
int cfp_no;
u8 idx;
int ret = 0;
ENTER();
lbs_deb_enter(LBS_DEB_11D);
cfp = libertas_get_region_cfp_table(region, band, &cfp_no);
if (cfp == NULL)
......@@ -288,16 +289,19 @@ static u8 wlan_region_chan_supported_11d(u8 region, u8 band, u8 chan)
if (chan == (cfp + idx)->channel) {
/* If Mrvl Chip Supported? */
if ((cfp + idx)->unsupported) {
return 0;
ret = 0;
} else {
return 1;
ret = 1;
}
goto done;
}
}
/*chan is not in the region table */
LEAVE();
return 0;
done:
lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret);
return ret;
}
/**
......@@ -321,7 +325,7 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset*
u8 j, i;
ENTER();
lbs_deb_enter(LBS_DEB_11D);
/*validation Rules:
1. valid region Code
......@@ -337,15 +341,14 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset*
if ((*(countryinfo->countrycode)) == 0
|| (countryinfo->len <= COUNTRY_CODE_LEN)) {
/* No region Info or Wrong region info: treat as No 11D info */
LEAVE();
return 0;
goto done;
}
/*Step1: check region_code */
parsed_region_chan->region = region =
wlan_region_2_code(countryinfo->countrycode);
lbs_pr_debug(1, "regioncode=%x\n", (u8) parsed_region_chan->region);
lbs_deb_11d("regioncode=%x\n", (u8) parsed_region_chan->region);
lbs_dbg_hex("CountryCode:", (char *)countryinfo->countrycode,
COUNTRY_CODE_LEN);
......@@ -361,7 +364,7 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset*
if (countryinfo->subband[j].firstchan <= lastchan) {
/*Step2&3. Check First Chan Num increment and no overlap */
lbs_pr_debug(1, "11D: Chan[%d>%d] Overlap\n",
lbs_deb_11d("11D: Chan[%d>%d] Overlap\n",
countryinfo->subband[j].firstchan, lastchan);
continue;
}
......@@ -374,7 +377,7 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset*
if (!wlan_get_chan_11d(band, firstchan, i, &curchan)) {
/* Chan is not found in UN table */
lbs_pr_debug(1, "chan is not supported: %d \n", i);
lbs_deb_11d("chan is not supported: %d \n", i);
break;
}
......@@ -389,7 +392,7 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset*
idx++;
} else {
/*not supported and ignore the chan */
lbs_pr_debug(1,
lbs_deb_11d(
"11D:i[%d] chan[%d] unsupported in region[%x] band[%d]\n",
i, curchan, region, band);
}
......@@ -401,11 +404,12 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset*
parsed_region_chan->nr_chan = idx;
lbs_pr_debug(1, "nrchan=%x\n", parsed_region_chan->nr_chan);
lbs_deb_11d("nrchan=%x\n", parsed_region_chan->nr_chan);
lbs_dbg_hex("11D:parsed_region_chan:", (u8 *) parsed_region_chan,
2 + COUNTRY_CODE_LEN + sizeof(struct parsed_region_chan_11d) * idx);
LEAVE();
done:
lbs_deb_enter(LBS_DEB_11D);
return 0;
}
......@@ -420,16 +424,16 @@ u8 libertas_get_scan_type_11d(u8 chan,
{
u8 scan_type = cmd_scan_type_passive;
ENTER();
lbs_deb_enter(LBS_DEB_11D);
if (wlan_channel_known_11d(chan, parsed_region_chan)) {
lbs_pr_debug(1, "11D: Found and do Active Scan\n");
lbs_deb_11d("11D: Found and do Active Scan\n");
scan_type = cmd_scan_type_active;
} else {
lbs_pr_debug(1, "11D: Not Find and do Passive Scan\n");
lbs_deb_11d("11D: Not Find and do Passive Scan\n");
}
LEAVE();
lbs_deb_leave_args(LBS_DEB_11D, "ret scan_type %d", scan_type);
return scan_type;
}
......@@ -456,7 +460,7 @@ static int wlan_enable_11d(wlan_private * priv, u8 flag)
OID_802_11D_ENABLE,
&priv->adapter->enable11d);
if (ret)
lbs_pr_debug(1, "11D: Fail to enable 11D \n");
lbs_deb_11d("11D: Fail to enable 11D \n");
return 0;
}
......@@ -471,7 +475,7 @@ static int set_domain_info_11d(wlan_private * priv)
int ret;
if (!priv->adapter->enable11d) {
lbs_pr_debug(1, "11D: dnld domain Info with 11d disabled\n");
lbs_deb_11d("11D: dnld domain Info with 11d disabled\n");
return 0;
}
......@@ -479,7 +483,7 @@ static int set_domain_info_11d(wlan_private * priv)
cmd_act_set,
cmd_option_waitforrsp, 0, NULL);
if (ret)
lbs_pr_debug(1, "11D: Fail to dnld domain Info\n");
lbs_deb_11d("11D: Fail to dnld domain Info\n");
return ret;
}
......@@ -501,7 +505,7 @@ int libertas_set_universaltable(wlan_private * priv, u8 band)
adapter->universal_channel[i].nrcfp =
sizeof(channel_freq_power_UN_BG) / size;
lbs_pr_debug(1, "11D: BG-band nrcfp=%d\n",
lbs_deb_11d("11D: BG-band nrcfp=%d\n",
adapter->universal_channel[i].nrcfp);
adapter->universal_channel[i].CFP = channel_freq_power_UN_BG;
......@@ -531,9 +535,9 @@ int libertas_cmd_802_11d_domain_info(wlan_private * priv,
wlan_adapter *adapter = priv->adapter;
u8 nr_subband = adapter->domainreg.nr_subband;
ENTER();
lbs_deb_enter(LBS_DEB_11D);
lbs_pr_debug(1, "nr_subband=%x\n", nr_subband);
lbs_deb_11d("nr_subband=%x\n", nr_subband);
cmd->command = cpu_to_le16(cmdno);
pdomaininfo->action = cpu_to_le16(cmdoption);
......@@ -542,8 +546,7 @@ int libertas_cmd_802_11d_domain_info(wlan_private * priv,
cpu_to_le16(sizeof(pdomaininfo->action) + S_DS_GEN);
lbs_dbg_hex("11D: 802_11D_DOMAIN_INFO:", (u8 *) cmd,
(int)(cmd->size));
LEAVE();
return 0;
goto done;
}
domain->header.type = cpu_to_le16(TLV_TYPE_DOMAIN);
......@@ -567,10 +570,10 @@ int libertas_cmd_802_11d_domain_info(wlan_private * priv,
cpu_to_le16(sizeof(pdomaininfo->action) + S_DS_GEN);
}
lbs_dbg_hex("11D:802_11D_DOMAIN_INFO:", (u8 *) cmd, (int)(cmd->size));
LEAVE();
lbs_dbg_hex("11D:802_11D_DOMAIN_INFO:", (u8 *) cmd, le16_to_cpu(cmd->size));
done:
lbs_deb_enter(LBS_DEB_11D);
return 0;
}
......@@ -585,17 +588,17 @@ int libertas_cmd_enable_11d(wlan_private * priv, struct iwreq *wrq)
int data = 0;
int *val;
ENTER();
lbs_deb_enter(LBS_DEB_11D);
data = SUBCMD_DATA(wrq);
lbs_pr_debug(1, "enable 11D: %s\n",
lbs_deb_11d("enable 11D: %s\n",
(data == 1) ? "enable" : "Disable");
wlan_enable_11d(priv, data);
val = (int *)wrq->u.name;
*val = priv->adapter->enable11d;
LEAVE();
lbs_deb_enter(LBS_DEB_11D);
return 0;
}
......@@ -608,25 +611,24 @@ int libertas_cmd_enable_11d(wlan_private * priv, struct iwreq *wrq)
int libertas_ret_802_11d_domain_info(wlan_private * priv,
struct cmd_ds_command *resp)
{
struct cmd_ds_802_11d_domain_info
*domaininfo = &resp->params.domaininforesp;
struct cmd_ds_802_11d_domain_info *domaininfo = &resp->params.domaininforesp;
struct mrvlietypes_domainparamset *domain = &domaininfo->domain;
u16 action = le16_to_cpu(domaininfo->action);
s16 ret = 0;
u8 nr_subband = 0;
ENTER();
lbs_deb_enter(LBS_DEB_11D);
lbs_dbg_hex("11D DOMAIN Info Rsp Data:", (u8 *) resp,
(int)le16_to_cpu(resp->size));
nr_subband = (domain->header.len - 3) / sizeof(struct ieeetypes_subbandset);
/* countrycode 3 bytes */
nr_subband = (le16_to_cpu(domain->header.len) - COUNTRY_CODE_LEN) /
sizeof(struct ieeetypes_subbandset);
lbs_pr_debug(1, "11D Domain Info Resp: nr_subband=%d\n", nr_subband);
lbs_deb_11d("11D Domain Info Resp: nr_subband=%d\n", nr_subband);
if (nr_subband > MRVDRV_MAX_SUBBAND_802_11D) {
lbs_pr_debug(1, "Invalid Numrer of Subband returned!!\n");
lbs_deb_11d("Invalid Numrer of Subband returned!!\n");
return -1;
}
......@@ -637,12 +639,12 @@ int libertas_ret_802_11d_domain_info(wlan_private * priv,
case cmd_act_get:
break;
default:
lbs_pr_debug(1, "Invalid action:%d\n", domaininfo->action);
lbs_deb_11d("Invalid action:%d\n", domaininfo->action);
ret = -1;
break;
}
LEAVE();
lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret);
return ret;
}
......@@ -651,23 +653,22 @@ int libertas_ret_802_11d_domain_info(wlan_private * priv,
* @param priv pointer to wlan_private
* @return 0; -1
*/
int libertas_parse_dnld_countryinfo_11d(wlan_private * priv)
int libertas_parse_dnld_countryinfo_11d(wlan_private * priv,
struct bss_descriptor * bss)
{
int ret;
wlan_adapter *adapter = priv->adapter;
ENTER();
lbs_deb_enter(LBS_DEB_11D);
if (priv->adapter->enable11d) {
memset(&adapter->parsed_region_chan, 0,
sizeof(struct parsed_region_chan_11d));
ret = parse_domain_info_11d(&adapter->pattemptedbssdesc->
countryinfo, 0,
ret = parse_domain_info_11d(&bss->countryinfo, 0,
&adapter->parsed_region_chan);
if (ret == -1) {
lbs_pr_debug(1, "11D: Err Parse domain_info from AP..\n");
LEAVE();
return ret;
lbs_deb_11d("11D: Err Parse domain_info from AP..\n");
goto done;
}
memset(&adapter->domainreg, 0,
......@@ -678,13 +679,15 @@ int libertas_parse_dnld_countryinfo_11d(wlan_private * priv)
ret = set_domain_info_11d(priv);
if (ret) {
lbs_pr_debug(1, "11D: Err set domainInfo to FW\n");
LEAVE();
return ret;
lbs_deb_11d("11D: Err set domainInfo to FW\n");
goto done;
}
}
LEAVE();
return 0;
ret = 0;
done:
lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret);
return ret;
}
/**
......@@ -699,8 +702,8 @@ int libertas_create_dnld_countryinfo_11d(wlan_private * priv)
struct region_channel *region_chan;
u8 j;
ENTER();
lbs_pr_debug(1, "11D:curbssparams.band[%d]\n", adapter->curbssparams.band);
lbs_deb_enter(LBS_DEB_11D);
lbs_deb_11d("11D:curbssparams.band[%d]\n", adapter->curbssparams.band);
if (priv->adapter->enable11d) {
/* update parsed_region_chan_11; dnld domaininf to FW */
......@@ -709,7 +712,7 @@ int libertas_create_dnld_countryinfo_11d(wlan_private * priv)
sizeof(adapter->region_channel[0]); j++) {
region_chan = &adapter->region_channel[j];
lbs_pr_debug(1, "11D:[%d] region_chan->band[%d]\n", j,
lbs_deb_11d("11D:[%d] region_chan->band[%d]\n", j,
region_chan->band);
if (!region_chan || !region_chan->valid
......@@ -722,10 +725,10 @@ int libertas_create_dnld_countryinfo_11d(wlan_private * priv)
if (j >= sizeof(adapter->region_channel) /
sizeof(adapter->region_channel[0])) {
lbs_pr_debug(1, "11D:region_chan not found. band[%d]\n",
lbs_deb_11d("11D:region_chan not found. band[%d]\n",
adapter->curbssparams.band);
LEAVE();
return -1;
ret = -1;
goto done;
}
memset(&adapter->parsed_region_chan, 0,
......@@ -742,13 +745,14 @@ int libertas_create_dnld_countryinfo_11d(wlan_private * priv)
ret = set_domain_info_11d(priv);
if (ret) {
lbs_pr_debug(1, "11D: Err set domainInfo to FW\n");
LEAVE();
return ret;
lbs_deb_11d("11D: Err set domainInfo to FW\n");
goto done;
}
}
ret = 0;
LEAVE();
return 0;
done:
lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret);
return ret;
}
......@@ -47,7 +47,7 @@ struct mrvlietypes_domainparamset {
} __attribute__ ((packed));
struct cmd_ds_802_11d_domain_info {
u16 action;
__le16 action;
struct mrvlietypes_domainparamset domain;
} __attribute__ ((packed));
......@@ -98,7 +98,9 @@ int libertas_cmd_enable_11d(wlan_private * priv, struct iwreq *wrq);
int libertas_ret_802_11d_domain_info(wlan_private * priv,
struct cmd_ds_command *resp);
int libertas_parse_dnld_countryinfo_11d(wlan_private * priv);
struct bss_descriptor;
int libertas_parse_dnld_countryinfo_11d(wlan_private * priv,
struct bss_descriptor * bss);
int libertas_create_dnld_countryinfo_11d(wlan_private * priv);
......
usb8xxx-objs := main.o fw.o wext.o \
libertas-objs := main.o fw.o wext.o \
rx.o tx.o cmd.o \
cmdresp.o scan.o \
join.o 11d.o \
......@@ -8,5 +8,5 @@ usb8xxx-objs := main.o fw.o wext.o \
usb8xxx-objs += if_bootcmd.o
usb8xxx-objs += if_usb.o
obj-$(CONFIG_LIBERTAS) += libertas.o
obj-$(CONFIG_LIBERTAS_USB) += usb8xxx.o
================================================================================
README for USB8388
(c) Copyright © 2003-2006, Marvell International Ltd.
(c) Copyright © 2003-2006, Marvell International Ltd.
All Rights Reserved
This software file (the "File") is distributed by Marvell International
......@@ -47,15 +47,19 @@ Version 5 Command:
iwpriv ethX ledgpio <n>
BT Commands:
The blinding table (BT) contains a list of mac addresses that should be
ignored by the firmware. It is primarily used for debugging and
testing networks. It can be edited and inspected with the following
commands:
The blinding table (BT) contains a list of mac addresses that will be,
by default, ignored by the firmware. It is also possible to invert this
behavior so that we will ignore all traffic except for the portion
coming from mac addresess in the list. It is primarily used for
debugging and testing networks. It can be edited and inspected with
the following commands:
iwpriv ethX bt_reset
iwpriv ethX bt_add <mac_address>
iwpriv ethX bt_del <mac_address>
iwpriv ethX bt_list <id>
iwpriv ethX bt_get_invert <n>
iwpriv ethX bt_set_invert <n>
FWT Commands:
The forwarding table (FWT) is a feature used to manage mesh network
......@@ -135,7 +139,7 @@ fwt_add
This command is used to insert an entry into the FWT table. The list of
parameters must follow the following structure:
iwpriv ethX fwt_add da ra [metric dir ssn dsn hopcount ttl expiration sleepmode snr]
iwpriv ethX fwt_add da ra [metric dir rate ssn dsn hopcount ttl expiration sleepmode snr]
The parameters between brackets are optional, but they must appear in
the order specified. For example, if you want to specify the metric,
......@@ -150,6 +154,9 @@ fwt_add
preferred, default is 0)
dir -- direction (1 for direct, 0 for reverse,
default is 1)
rate -- data rate used for transmission to the RA,
as specified for the rateadapt command,
default is 3 (11Mbps)
ssn -- Source Sequence Number (time at the RA for
reverse routes. Default is 0)
dsn -- Destination Sequence Number (time at the DA
......@@ -207,13 +214,17 @@ fwt_list
The output is a string of the following form:
da ra metric dir ssn dsn hopcount ttl expiration sleepmode snr
da ra valid metric dir rate ssn dsn hopcount ttl expiration
sleepmode snr precursor
where the different fields are:-
da -- DA MAC address (in the form "00:11:22:33:44:55")
ra -- RA MAC address (in the form "00:11:22:33:44:55")
valid -- whether the route is valid (0 if not valid)
metric -- route metric (cost: smaller-metric routes are preferred)
dir -- direction (1 for direct, 0 for reverse)
rate -- data rate used for transmission to the RA,
as specified for the rateadapt command
ssn -- Source Sequence Number (time at the RA for reverse routes)
dsn -- Destination Sequence Number (time at the DA for direct routes)
hopcount -- hop count (currently unused)
......@@ -221,33 +232,10 @@ fwt_list
expiration -- entry expiration (in ticks, where a tick is 1024us, or ~ 1ms. Use 0 for an indefinite entry)
sleepmode -- RA's sleep mode (currently unused)
snr -- SNR in the link to RA (currently unused)
precursor -- predecessor in direct routes
fwt_list_route
This command is used to list a route from the FWT table. The only
parameter is the route ID. If you want to list all the routes in a
table, start with rid=0, and keep incrementing rid until you get a
"(null)" string. This function is similar to fwt_list. The only
difference is the output format. Also note that this command is meant
for debugging. It is expected that users will use fwt_lookup and
fwt_list. One important reason for this is that the route id may change
as the route table is altered.
iwpriv ethX fwt_list_route rid
The output is a string of the following form:
da metric dir nid ssn dsn hopcount ttl expiration
where the different fields are:-
da -- DA MAC address (in the form "00:11:22:33:44:55")
metric -- route metric (cost: smaller-metric routes are preferred)
dir -- direction (1 for direct, 0 for reverse)
nid -- Next-hop (neighbor) host ID (nid)
ssn -- Source Sequence Number (time at the RA for reverse routes)
dsn -- Destination Sequence Number (time at the DA for direct routes)
hopcount -- hop count (currently unused)
ttl -- TTL count (only used in reverse entries)
expiration -- entry expiration (in ticks, where a tick is 1024us, or ~ 1ms. Use 0 for an indefinite entry)
This command is equivalent to fwt_list.
fwt_list_neigh
This command is used to list a neighbor from the FWT table. The only
......
......@@ -2,6 +2,7 @@
#include <linux/bitops.h>
#include <net/ieee80211.h>
#include <linux/etherdevice.h>
#include "assoc.h"
#include "join.h"
......@@ -13,59 +14,88 @@
static const u8 bssid_any[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
static const u8 bssid_off[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
static void print_assoc_req(const char * extra, struct assoc_request * assoc_req)
{
lbs_deb_assoc(
"#### Association Request: %s\n"
" flags: 0x%08lX\n"
" SSID: '%s'\n"
" channel: %d\n"
" band: %d\n"
" mode: %d\n"
" BSSID: " MAC_FMT "\n"
" Encryption:%s%s%s\n"
" auth: %d\n",
extra, assoc_req->flags,
escape_essid(assoc_req->ssid, assoc_req->ssid_len),
assoc_req->channel, assoc_req->band, assoc_req->mode,
MAC_ARG(assoc_req->bssid),
assoc_req->secinfo.WPAenabled ? " WPA" : "",
assoc_req->secinfo.WPA2enabled ? " WPA2" : "",
assoc_req->secinfo.wep_enabled ? " WEP" : "",
assoc_req->secinfo.auth_mode);
}
static int assoc_helper_essid(wlan_private *priv,
struct assoc_request * assoc_req)
{
wlan_adapter *adapter = priv->adapter;
int ret = 0;
int i;
struct bss_descriptor * bss;
int channel = -1;
ENTER();
lbs_deb_enter(LBS_DEB_ASSOC);
lbs_pr_debug(1, "New SSID requested: %s\n", assoc_req->ssid.ssid);
/* FIXME: take channel into account when picking SSIDs if a channel
* is set.
*/
if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags))
channel = assoc_req->channel;
lbs_deb_assoc("New SSID requested: '%s'\n",
escape_essid(assoc_req->ssid, assoc_req->ssid_len));
if (assoc_req->mode == IW_MODE_INFRA) {
if (adapter->prescan) {
libertas_send_specific_SSID_scan(priv, &assoc_req->ssid, 1);
libertas_send_specific_ssid_scan(priv, assoc_req->ssid,
assoc_req->ssid_len, 0);
}
i = libertas_find_SSID_in_list(adapter, &assoc_req->ssid,
NULL, IW_MODE_INFRA);
if (i >= 0) {
lbs_pr_debug(1,
"SSID found in scan list ... associating...\n");
ret = wlan_associate(priv, &adapter->scantable[i]);
if (ret == 0) {
memcpy(&assoc_req->bssid,
&adapter->scantable[i].macaddress,
ETH_ALEN);
}
bss = libertas_find_ssid_in_list(adapter, assoc_req->ssid,
assoc_req->ssid_len, NULL, IW_MODE_INFRA, channel);
if (bss != NULL) {
lbs_deb_assoc("SSID found in scan list, associating\n");
memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor));
ret = wlan_associate(priv, assoc_req);
} else {
lbs_pr_debug(1, "SSID '%s' not found; cannot associate\n",
assoc_req->ssid.ssid);
lbs_deb_assoc("SSID not found; cannot associate\n");
}
} else if (assoc_req->mode == IW_MODE_ADHOC) {
/* Scan for the network, do not save previous results. Stale
* scan data will cause us to join a non-existant adhoc network
*/
libertas_send_specific_SSID_scan(priv, &assoc_req->ssid, 0);
libertas_send_specific_ssid_scan(priv, assoc_req->ssid,
assoc_req->ssid_len, 1);
/* Search for the requested SSID in the scan table */
i = libertas_find_SSID_in_list(adapter, &assoc_req->ssid, NULL,
IW_MODE_ADHOC);
if (i >= 0) {
lbs_pr_debug(1, "SSID found at %d in List, so join\n", ret);
libertas_join_adhoc_network(priv, &adapter->scantable[i]);
bss = libertas_find_ssid_in_list(adapter, assoc_req->ssid,
assoc_req->ssid_len, NULL, IW_MODE_ADHOC, channel);
if (bss != NULL) {
lbs_deb_assoc("SSID found, will join\n");
memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor));
libertas_join_adhoc_network(priv, assoc_req);
} else {
/* else send START command */
lbs_pr_debug(1, "SSID not found in list, so creating adhoc"
" with SSID '%s'\n", assoc_req->ssid.ssid);
libertas_start_adhoc_network(priv, &assoc_req->ssid);
lbs_deb_assoc("SSID not found, creating adhoc network\n");
memcpy(&assoc_req->bss.ssid, &assoc_req->ssid,
IW_ESSID_MAX_SIZE);
assoc_req->bss.ssid_len = assoc_req->ssid_len;
libertas_start_adhoc_network(priv, assoc_req);
}
memcpy(&assoc_req->bssid, &adapter->current_addr, ETH_ALEN);
}
LEAVE();
lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
return ret;
}
......@@ -74,33 +104,31 @@ static int assoc_helper_bssid(wlan_private *priv,
struct assoc_request * assoc_req)
{
wlan_adapter *adapter = priv->adapter;
int i, ret = 0;
ENTER();
int ret = 0;
struct bss_descriptor * bss;
lbs_pr_debug(1, "ASSOC: WAP: BSSID = " MAC_FMT "\n",
lbs_deb_enter_args(LBS_DEB_ASSOC, "BSSID " MAC_FMT,
MAC_ARG(assoc_req->bssid));
/* Search for index position in list for requested MAC */
i = libertas_find_BSSID_in_list(adapter, assoc_req->bssid,
bss = libertas_find_bssid_in_list(adapter, assoc_req->bssid,
assoc_req->mode);
if (i < 0) {
lbs_pr_debug(1, "ASSOC: WAP: BSSID " MAC_FMT " not found, "
if (bss == NULL) {
lbs_deb_assoc("ASSOC: WAP: BSSID " MAC_FMT " not found, "
"cannot associate.\n", MAC_ARG(assoc_req->bssid));
goto out;
}
memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor));
if (assoc_req->mode == IW_MODE_INFRA) {
ret = wlan_associate(priv, &adapter->scantable[i]);
lbs_pr_debug(1, "ASSOC: return from wlan_associate(bssd) was %d\n", ret);
ret = wlan_associate(priv, assoc_req);
lbs_deb_assoc("ASSOC: wlan_associate(bssid) returned %d\n", ret);
} else if (assoc_req->mode == IW_MODE_ADHOC) {
libertas_join_adhoc_network(priv, &adapter->scantable[i]);
libertas_join_adhoc_network(priv, assoc_req);
}
memcpy(&assoc_req->ssid, &adapter->scantable[i].ssid,
sizeof(struct WLAN_802_11_SSID));
out:
LEAVE();
lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
return ret;
}
......@@ -113,12 +141,12 @@ static int assoc_helper_associate(wlan_private *priv,
/* If we're given and 'any' BSSID, try associating based on SSID */
if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) {
if (memcmp(bssid_any, assoc_req->bssid, ETH_ALEN)
&& memcmp(bssid_off, assoc_req->bssid, ETH_ALEN)) {
if (compare_ether_addr(bssid_any, assoc_req->bssid)
&& compare_ether_addr(bssid_off, assoc_req->bssid)) {
ret = assoc_helper_bssid(priv, assoc_req);
done = 1;
if (ret) {
lbs_pr_debug(1, "ASSOC: bssid: ret = %d\n", ret);
lbs_deb_assoc("ASSOC: bssid: ret = %d\n", ret);
}
}
}
......@@ -126,7 +154,7 @@ static int assoc_helper_associate(wlan_private *priv,
if (!done && test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) {
ret = assoc_helper_essid(priv, assoc_req);
if (ret) {
lbs_pr_debug(1, "ASSOC: bssid: ret = %d\n", ret);
lbs_deb_assoc("ASSOC: bssid: ret = %d\n", ret);
}
}
......@@ -140,12 +168,10 @@ static int assoc_helper_mode(wlan_private *priv,
wlan_adapter *adapter = priv->adapter;
int ret = 0;
ENTER();
lbs_deb_enter(LBS_DEB_ASSOC);
if (assoc_req->mode == adapter->mode) {
LEAVE();
return 0;
}
if (assoc_req->mode == adapter->mode)
goto done;
if (assoc_req->mode == IW_MODE_INFRA) {
if (adapter->psstate != PS_STATE_FULL_POWER)
......@@ -158,9 +184,73 @@ static int assoc_helper_mode(wlan_private *priv,
cmd_802_11_snmp_mib,
0, cmd_option_waitforrsp,
OID_802_11_INFRASTRUCTURE_MODE,
(void *) (size_t) assoc_req->mode);
/* Shoot me now */ (void *) (size_t) assoc_req->mode);
done:
lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
return ret;
}
static int update_channel(wlan_private * priv)
{
/* the channel in f/w could be out of sync, get the current channel */
return libertas_prepare_and_send_command(priv, cmd_802_11_rf_channel,
cmd_opt_802_11_rf_channel_get,
cmd_option_waitforrsp, 0, NULL);
}
static int assoc_helper_channel(wlan_private *priv,
struct assoc_request * assoc_req)
{
wlan_adapter *adapter = priv->adapter;
int ret = 0;
lbs_deb_enter(LBS_DEB_ASSOC);
ret = update_channel(priv);
if (ret < 0) {
lbs_deb_assoc("ASSOC: channel: error getting channel.");
}
if (assoc_req->channel == adapter->curbssparams.channel)
goto done;
lbs_deb_assoc("ASSOC: channel: %d -> %d\n",
adapter->curbssparams.channel, assoc_req->channel);
ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_channel,
cmd_opt_802_11_rf_channel_set,
cmd_option_waitforrsp, 0, &assoc_req->channel);
if (ret < 0) {
lbs_deb_assoc("ASSOC: channel: error setting channel.");
}
ret = update_channel(priv);
if (ret < 0) {
lbs_deb_assoc("ASSOC: channel: error getting channel.");
}
if (assoc_req->channel != adapter->curbssparams.channel) {
lbs_deb_assoc("ASSOC: channel: failed to update channel to %d",
assoc_req->channel);
goto done;
}
if ( assoc_req->secinfo.wep_enabled
&& (assoc_req->wep_keys[0].len
|| assoc_req->wep_keys[1].len
|| assoc_req->wep_keys[2].len
|| assoc_req->wep_keys[3].len)) {
/* Make sure WEP keys are re-sent to firmware */
set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags);
}
/* Must restart/rejoin adhoc networks after channel change */
set_bit(ASSOC_FLAG_SSID, &assoc_req->flags);
LEAVE();
done:
lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
return ret;
}
......@@ -172,7 +262,7 @@ static int assoc_helper_wep_keys(wlan_private *priv,
int i;
int ret = 0;
ENTER();
lbs_deb_enter(LBS_DEB_ASSOC);
/* Set or remove WEP keys */
if ( assoc_req->wep_keys[0].len
......@@ -216,7 +306,7 @@ static int assoc_helper_wep_keys(wlan_private *priv,
mutex_unlock(&adapter->lock);
out:
LEAVE();
lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
return ret;
}
......@@ -226,14 +316,24 @@ static int assoc_helper_secinfo(wlan_private *priv,
wlan_adapter *adapter = priv->adapter;
int ret = 0;
ENTER();
lbs_deb_enter(LBS_DEB_ASSOC);
memcpy(&adapter->secinfo, &assoc_req->secinfo,
sizeof(struct wlan_802_11_security));
ret = libertas_set_mac_packet_filter(priv);
if (ret)
goto out;
/* enable/disable RSN */
ret = libertas_prepare_and_send_command(priv,
cmd_802_11_enable_rsn,
cmd_act_set,
cmd_option_waitforrsp,
0, assoc_req);
LEAVE();
out:
lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
return ret;
}
......@@ -243,16 +343,7 @@ static int assoc_helper_wpa_keys(wlan_private *priv,
{
int ret = 0;
ENTER();
/* enable/Disable RSN */
ret = libertas_prepare_and_send_command(priv,
cmd_802_11_enable_rsn,
cmd_act_set,
cmd_option_waitforrsp,
0, assoc_req);
if (ret)
goto out;
lbs_deb_enter(LBS_DEB_ASSOC);
ret = libertas_prepare_and_send_command(priv,
cmd_802_11_key_material,
......@@ -260,8 +351,7 @@ static int assoc_helper_wpa_keys(wlan_private *priv,
cmd_option_waitforrsp,
0, assoc_req);
out:
LEAVE();
lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
return ret;
}
......@@ -272,7 +362,7 @@ static int assoc_helper_wpa_ie(wlan_private *priv,
wlan_adapter *adapter = priv->adapter;
int ret = 0;
ENTER();
lbs_deb_enter(LBS_DEB_ASSOC);
if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) {
memcpy(&adapter->wpa_ie, &assoc_req->wpa_ie, assoc_req->wpa_ie_len);
......@@ -282,7 +372,7 @@ static int assoc_helper_wpa_ie(wlan_private *priv,
adapter->wpa_ie_len = 0;
}
LEAVE();
lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
return ret;
}
......@@ -294,21 +384,21 @@ static int should_deauth_infrastructure(wlan_adapter *adapter,
return 0;
if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) {
lbs_pr_debug(1, "Deauthenticating due to new SSID in "
lbs_deb_assoc("Deauthenticating due to new SSID in "
" configuration request.\n");
return 1;
}
if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) {
if (adapter->secinfo.auth_mode != assoc_req->secinfo.auth_mode) {
lbs_pr_debug(1, "Deauthenticating due to updated security "
lbs_deb_assoc("Deauthenticating due to updated security "
"info in configuration request.\n");
return 1;
}
}
if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) {
lbs_pr_debug(1, "Deauthenticating due to new BSSID in "
lbs_deb_assoc("Deauthenticating due to new BSSID in "
" configuration request.\n");
return 1;
}
......@@ -329,10 +419,9 @@ static int should_stop_adhoc(wlan_adapter *adapter,
if (adapter->connect_status != libertas_connected)
return 0;
if (adapter->curbssparams.ssid.ssidlength != assoc_req->ssid.ssidlength)
return 1;
if (memcmp(adapter->curbssparams.ssid.ssid, assoc_req->ssid.ssid,
adapter->curbssparams.ssid.ssidlength))
if (libertas_ssid_cmp(adapter->curbssparams.ssid,
adapter->curbssparams.ssid_len,
assoc_req->ssid, assoc_req->ssid_len) != 0)
return 1;
/* FIXME: deal with 'auto' mode somehow */
......@@ -341,11 +430,16 @@ static int should_stop_adhoc(wlan_adapter *adapter,
return 1;
}
if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) {
if (assoc_req->channel != adapter->curbssparams.channel)
return 1;
}
return 0;
}
void wlan_association_worker(struct work_struct *work)
void libertas_association_worker(struct work_struct *work)
{
wlan_private *priv = container_of(work, wlan_private, assoc_work.work);
wlan_adapter *adapter = priv->adapter;
......@@ -353,40 +447,38 @@ void wlan_association_worker(struct work_struct *work)
int ret = 0;
int find_any_ssid = 0;
ENTER();
lbs_deb_enter(LBS_DEB_ASSOC);
mutex_lock(&adapter->lock);
assoc_req = adapter->assoc_req;
adapter->assoc_req = NULL;
assoc_req = adapter->pending_assoc_req;
adapter->pending_assoc_req = NULL;
adapter->in_progress_assoc_req = assoc_req;
mutex_unlock(&adapter->lock);
if (!assoc_req) {
LEAVE();
return;
}
if (!assoc_req)
goto done;
lbs_pr_debug(1, "ASSOC: starting new association request: flags = 0x%lX\n",
assoc_req->flags);
print_assoc_req(__func__, assoc_req);
/* If 'any' SSID was specified, find an SSID to associate with */
if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)
&& !assoc_req->ssid.ssidlength)
&& !assoc_req->ssid_len)
find_any_ssid = 1;
/* But don't use 'any' SSID if there's a valid locked BSSID to use */
if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) {
if (memcmp(&assoc_req->bssid, bssid_any, ETH_ALEN)
&& memcmp(&assoc_req->bssid, bssid_off, ETH_ALEN))
if (compare_ether_addr(assoc_req->bssid, bssid_any)
&& compare_ether_addr(assoc_req->bssid, bssid_off))
find_any_ssid = 0;
}
if (find_any_ssid) {
u8 new_mode;
ret = libertas_find_best_network_SSID(priv, &assoc_req->ssid,
assoc_req->mode, &new_mode);
ret = libertas_find_best_network_ssid(priv, assoc_req->ssid,
&assoc_req->ssid_len, assoc_req->mode, &new_mode);
if (ret) {
lbs_pr_debug(1, "Could not find best network\n");
lbs_deb_assoc("Could not find best network\n");
ret = -ENETUNREACH;
goto out;
}
......@@ -406,7 +498,7 @@ void wlan_association_worker(struct work_struct *work)
if (should_deauth_infrastructure(adapter, assoc_req)) {
ret = libertas_send_deauthentication(priv);
if (ret) {
lbs_pr_debug(1, "Deauthentication due to new "
lbs_deb_assoc("Deauthentication due to new "
"configuration request failed: %d\n",
ret);
}
......@@ -415,7 +507,7 @@ void wlan_association_worker(struct work_struct *work)
if (should_stop_adhoc(adapter, assoc_req)) {
ret = libertas_stop_adhoc_network(priv);
if (ret) {
lbs_pr_debug(1, "Teardown of AdHoc network due to "
lbs_deb_assoc("Teardown of AdHoc network due to "
"new configuration request failed: %d\n",
ret);
}
......@@ -427,7 +519,16 @@ void wlan_association_worker(struct work_struct *work)
if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) {
ret = assoc_helper_mode(priv, assoc_req);
if (ret) {
lbs_pr_debug(1, "ASSOC(:%d) mode: ret = %d\n", __LINE__, ret);
lbs_deb_assoc("ASSOC(:%d) mode: ret = %d\n", __LINE__, ret);
goto out;
}
}
if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) {
ret = assoc_helper_channel(priv, assoc_req);
if (ret) {
lbs_deb_assoc("ASSOC(:%d) channel: ret = %d\n",
__LINE__, ret);
goto out;
}
}
......@@ -436,7 +537,7 @@ lbs_pr_debug(1, "ASSOC(:%d) mode: ret = %d\n", __LINE__, ret);
|| test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) {
ret = assoc_helper_wep_keys(priv, assoc_req);
if (ret) {
lbs_pr_debug(1, "ASSOC(:%d) wep_keys: ret = %d\n", __LINE__, ret);
lbs_deb_assoc("ASSOC(:%d) wep_keys: ret = %d\n", __LINE__, ret);
goto out;
}
}
......@@ -444,7 +545,7 @@ lbs_pr_debug(1, "ASSOC(:%d) wep_keys: ret = %d\n", __LINE__, ret);
if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) {
ret = assoc_helper_secinfo(priv, assoc_req);
if (ret) {
lbs_pr_debug(1, "ASSOC(:%d) secinfo: ret = %d\n", __LINE__, ret);
lbs_deb_assoc("ASSOC(:%d) secinfo: ret = %d\n", __LINE__, ret);
goto out;
}
}
......@@ -452,7 +553,7 @@ lbs_pr_debug(1, "ASSOC(:%d) secinfo: ret = %d\n", __LINE__, ret);
if (test_bit(ASSOC_FLAG_WPA_IE, &assoc_req->flags)) {
ret = assoc_helper_wpa_ie(priv, assoc_req);
if (ret) {
lbs_pr_debug(1, "ASSOC(:%d) wpa_ie: ret = %d\n", __LINE__, ret);
lbs_deb_assoc("ASSOC(:%d) wpa_ie: ret = %d\n", __LINE__, ret);
goto out;
}
}
......@@ -461,7 +562,7 @@ lbs_pr_debug(1, "ASSOC(:%d) wpa_ie: ret = %d\n", __LINE__, ret);
|| test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) {
ret = assoc_helper_wpa_keys(priv, assoc_req);
if (ret) {
lbs_pr_debug(1, "ASSOC(:%d) wpa_keys: ret = %d\n", __LINE__, ret);
lbs_deb_assoc("ASSOC(:%d) wpa_keys: ret = %d\n", __LINE__, ret);
goto out;
}
}
......@@ -475,21 +576,23 @@ lbs_pr_debug(1, "ASSOC(:%d) wpa_keys: ret = %d\n", __LINE__, ret);
ret = assoc_helper_associate(priv, assoc_req);
if (ret) {
lbs_pr_debug(1, "ASSOC: association attempt unsuccessful: %d\n",
lbs_deb_assoc("ASSOC: association attempt unsuccessful: %d\n",
ret);
success = 0;
}
if (adapter->connect_status != libertas_connected) {
lbs_pr_debug(1, "ASSOC: assoication attempt unsuccessful, "
lbs_deb_assoc("ASSOC: assoication attempt unsuccessful, "
"not connected.\n");
success = 0;
}
if (success) {
lbs_pr_debug(1, "ASSOC: association attempt successful. "
lbs_deb_assoc("ASSOC: association attempt successful. "
"Associated to '%s' (" MAC_FMT ")\n",
assoc_req->ssid.ssid, MAC_ARG(assoc_req->bssid));
escape_essid(adapter->curbssparams.ssid,
adapter->curbssparams.ssid_len),
MAC_ARG(adapter->curbssparams.bssid));
libertas_prepare_and_send_command(priv,
cmd_802_11_rssi,
0, cmd_option_waitforrsp, 0, NULL);
......@@ -498,18 +601,23 @@ lbs_pr_debug(1, "ASSOC(:%d) wpa_keys: ret = %d\n", __LINE__, ret);
cmd_802_11_get_log,
0, cmd_option_waitforrsp, 0, NULL);
} else {
ret = -1;
}
}
out:
if (ret) {
lbs_pr_debug(1, "ASSOC: reconfiguration attempt unsuccessful: %d\n",
lbs_deb_assoc("ASSOC: reconfiguration attempt unsuccessful: %d\n",
ret);
}
mutex_lock(&adapter->lock);
adapter->in_progress_assoc_req = NULL;
mutex_unlock(&adapter->lock);
kfree(assoc_req);
LEAVE();
done:
lbs_deb_leave(LBS_DEB_ASSOC);
}
......@@ -520,9 +628,10 @@ struct assoc_request * wlan_get_association_request(wlan_adapter *adapter)
{
struct assoc_request * assoc_req;
if (!adapter->assoc_req) {
adapter->assoc_req = kzalloc(sizeof(struct assoc_request), GFP_KERNEL);
if (!adapter->assoc_req) {
if (!adapter->pending_assoc_req) {
adapter->pending_assoc_req = kzalloc(sizeof(struct assoc_request),
GFP_KERNEL);
if (!adapter->pending_assoc_req) {
lbs_pr_info("Not enough memory to allocate association"
" request!\n");
return NULL;
......@@ -532,15 +641,19 @@ struct assoc_request * wlan_get_association_request(wlan_adapter *adapter)
/* Copy current configuration attributes to the association request,
* but don't overwrite any that are already set.
*/
assoc_req = adapter->assoc_req;
assoc_req = adapter->pending_assoc_req;
if (!test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) {
memcpy(&assoc_req->ssid, adapter->curbssparams.ssid.ssid,
adapter->curbssparams.ssid.ssidlength);
memcpy(&assoc_req->ssid, &adapter->curbssparams.ssid,
IW_ESSID_MAX_SIZE);
assoc_req->ssid_len = adapter->curbssparams.ssid_len;
}
if (!test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags))
assoc_req->channel = adapter->curbssparams.channel;
if (!test_bit(ASSOC_FLAG_BAND, &assoc_req->flags))
assoc_req->band = adapter->curbssparams.band;
if (!test_bit(ASSOC_FLAG_MODE, &assoc_req->flags))
assoc_req->mode = adapter->mode;
......@@ -581,7 +694,7 @@ struct assoc_request * wlan_get_association_request(wlan_adapter *adapter)
assoc_req->wpa_ie_len = adapter->wpa_ie_len;
}
print_assoc_req(__func__, assoc_req);
return assoc_req;
}
......@@ -5,7 +5,7 @@
#include "dev.h"
void wlan_association_worker(struct work_struct *work);
void libertas_association_worker(struct work_struct *work);
struct assoc_request * wlan_get_association_request(wlan_adapter *adapter);
......@@ -21,9 +21,9 @@ static inline void wlan_postpone_association_work(wlan_private *priv)
static inline void wlan_cancel_association_work(wlan_private *priv)
{
cancel_delayed_work(&priv->assoc_work);
if (priv->adapter->assoc_req) {
kfree(priv->adapter->assoc_req);
priv->adapter->assoc_req = NULL;
if (priv->adapter->pending_assoc_req) {
kfree(priv->adapter->pending_assoc_req);
priv->adapter->pending_assoc_req = NULL;
}
}
......
......@@ -6,7 +6,6 @@
#include <net/iw_handler.h>
#include "host.h"
#include "hostcmd.h"
#include "sbi.h"
#include "decl.h"
#include "defs.h"
#include "dev.h"
......@@ -26,13 +25,11 @@ static u16 commands_allowed_in_ps[] = {
* @param command the command ID
* @return TRUE or FALSE
*/
static u8 is_command_allowed_in_ps(u16 command)
static u8 is_command_allowed_in_ps(__le16 command)
{
int count = sizeof(commands_allowed_in_ps)
/ sizeof(commands_allowed_in_ps[0]);
int i;
for (i = 0; i < count; i++) {
for (i = 0; i < ARRAY_SIZE(commands_allowed_in_ps); i++) {
if (command == cpu_to_le16(commands_allowed_in_ps[i]))
return 1;
}
......@@ -44,14 +41,13 @@ static int wlan_cmd_hw_spec(wlan_private * priv, struct cmd_ds_command *cmd)
{
struct cmd_ds_get_hw_spec *hwspec = &cmd->params.hwspec;
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
cmd->command = cpu_to_le16(cmd_get_hw_spec);
cmd->size =
cpu_to_le16(sizeof(struct cmd_ds_get_hw_spec) + S_DS_GEN);
cmd->size = cpu_to_le16(sizeof(struct cmd_ds_get_hw_spec) + S_DS_GEN);
memcpy(hwspec->permanentaddr, priv->adapter->current_addr, ETH_ALEN);
LEAVE();
lbs_deb_leave(LBS_DEB_CMD);
return 0;
}
......@@ -60,21 +56,19 @@ static int wlan_cmd_802_11_ps_mode(wlan_private * priv,
u16 cmd_action)
{
struct cmd_ds_802_11_ps_mode *psm = &cmd->params.psmode;
u16 action = cmd_action;
wlan_adapter *adapter = priv->adapter;
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
cmd->command = cpu_to_le16(cmd_802_11_ps_mode);
cmd->size =
cpu_to_le16(sizeof(struct cmd_ds_802_11_ps_mode) +
cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_ps_mode) +
S_DS_GEN);
psm->action = cpu_to_le16(cmd_action);
psm->multipledtim = 0;
switch (action) {
switch (cmd_action) {
case cmd_subcmd_enter_ps:
lbs_pr_debug(1, "PS command:" "SubCode- Enter PS\n");
lbs_pr_debug(1, "locallisteninterval = %d\n",
lbs_deb_cmd("PS command:" "SubCode- Enter PS\n");
lbs_deb_cmd("locallisteninterval = %d\n",
adapter->locallisteninterval);
psm->locallisteninterval =
......@@ -86,18 +80,18 @@ static int wlan_cmd_802_11_ps_mode(wlan_private * priv,
break;
case cmd_subcmd_exit_ps:
lbs_pr_debug(1, "PS command:" "SubCode- Exit PS\n");
lbs_deb_cmd("PS command:" "SubCode- Exit PS\n");
break;
case cmd_subcmd_sleep_confirmed:
lbs_pr_debug(1, "PS command: SubCode- sleep confirm\n");
lbs_deb_cmd("PS command: SubCode- sleep confirm\n");
break;
default:
break;
}
LEAVE();
lbs_deb_leave(LBS_DEB_CMD);
return 0;
}
......@@ -115,8 +109,7 @@ static int wlan_cmd_802_11_inactivity_timeout(wlan_private * priv,
cmd->params.inactivity_timeout.action = cpu_to_le16(cmd_action);
if (cmd_action)
cmd->params.inactivity_timeout.timeout =
cpu_to_le16(*timeout);
cmd->params.inactivity_timeout.timeout = cpu_to_le16(*timeout);
else
cmd->params.inactivity_timeout.timeout = 0;
......@@ -130,10 +123,9 @@ static int wlan_cmd_802_11_sleep_params(wlan_private * priv,
wlan_adapter *adapter = priv->adapter;
struct cmd_ds_802_11_sleep_params *sp = &cmd->params.sleep_params;
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
cmd->size =
cpu_to_le16((sizeof(struct cmd_ds_802_11_sleep_params)) +
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);
......@@ -151,7 +143,7 @@ static int wlan_cmd_802_11_sleep_params(wlan_private * priv,
sp->reserved = cpu_to_le16(adapter->sp.sp_reserved);
}
LEAVE();
lbs_deb_leave(LBS_DEB_CMD);
return 0;
}
......@@ -165,17 +157,16 @@ static int wlan_cmd_802_11_set_wep(wlan_private * priv,
int ret = 0;
struct assoc_request * assoc_req = pdata_buf;
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
cmd->command = cpu_to_le16(cmd_802_11_set_wep);
cmd->size = cpu_to_le16((sizeof(struct cmd_ds_802_11_set_wep))
+ S_DS_GEN);
cmd->size = cpu_to_le16(sizeof(*wep) + S_DS_GEN);
if (cmd_act == cmd_act_add) {
int i;
if (!assoc_req) {
lbs_pr_debug(1, "Invalid association request!");
lbs_deb_cmd("Invalid association request!");
ret = -1;
goto done;
}
......@@ -183,11 +174,10 @@ static int wlan_cmd_802_11_set_wep(wlan_private * priv,
wep->action = cpu_to_le16(cmd_act_add);
/* default tx key index */
wep->keyindex = cpu_to_le16((u16)
(assoc_req->wep_tx_keyidx &
wep->keyindex = cpu_to_le16((u16)(assoc_req->wep_tx_keyidx &
(u32)cmd_WEP_KEY_INDEX_MASK));
lbs_pr_debug(1, "Tx key Index: %u\n", wep->keyindex);
lbs_deb_cmd("Tx key Index: %u\n", le16_to_cpu(wep->keyindex));
/* Copy key types and material to host command structure */
for (i = 0; i < 4; i++) {
......@@ -195,19 +185,21 @@ static int wlan_cmd_802_11_set_wep(wlan_private * priv,
switch (pkey->len) {
case KEY_LEN_WEP_40:
wep->keytype[i] = cmd_type_wep_40_bit;
wep->keytype[i] =
cpu_to_le16(cmd_type_wep_40_bit);
memmove(&wep->keymaterial[i], pkey->key,
pkey->len);
break;
case KEY_LEN_WEP_104:
wep->keytype[i] = cmd_type_wep_104_bit;
wep->keytype[i] =
cpu_to_le16(cmd_type_wep_104_bit);
memmove(&wep->keymaterial[i], pkey->key,
pkey->len);
break;
case 0:
break;
default:
lbs_pr_debug(1, "Invalid WEP key %d length of %d\n",
lbs_deb_cmd("Invalid WEP key %d length of %d\n",
i, pkey->len);
ret = -1;
goto done;
......@@ -219,36 +211,37 @@ static int wlan_cmd_802_11_set_wep(wlan_private * priv,
wep->action = cpu_to_le16(cmd_act_remove);
/* default tx key index */
wep->keyindex = cpu_to_le16((u16)
(adapter->wep_tx_keyidx &
wep->keyindex = cpu_to_le16((u16)(adapter->wep_tx_keyidx &
(u32)cmd_WEP_KEY_INDEX_MASK));
}
ret = 0;
done:
LEAVE();
lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
return ret;
}
static int wlan_cmd_802_11_enable_rsn(wlan_private * priv,
struct cmd_ds_command *cmd,
u16 cmd_action)
u16 cmd_action,
void * pdata_buf)
{
struct cmd_ds_802_11_enable_rsn *penableRSN = &cmd->params.enbrsn;
wlan_adapter *adapter = priv->adapter;
struct assoc_request * assoc_req = pdata_buf;
lbs_deb_enter(LBS_DEB_CMD);
cmd->command = cpu_to_le16(cmd_802_11_enable_rsn);
cmd->size =
cpu_to_le16(sizeof(struct cmd_ds_802_11_enable_rsn) +
S_DS_GEN);
cmd->size = cpu_to_le16(sizeof(*penableRSN) + S_DS_GEN);
penableRSN->action = cpu_to_le16(cmd_action);
if (adapter->secinfo.WPAenabled || adapter->secinfo.WPA2enabled) {
if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) {
penableRSN->enable = cpu_to_le16(cmd_enable_rsn);
} else {
penableRSN->enable = cpu_to_le16(cmd_disable_rsn);
}
lbs_deb_leave(LBS_DEB_CMD);
return 0;
}
......@@ -259,14 +252,12 @@ static void set_one_wpa_key(struct MrvlIEtype_keyParamSet * pkeyparamset,
pkeyparamset->keytypeid = cpu_to_le16(pkey->type);
if (pkey->flags & KEY_INFO_WPA_ENABLED) {
pkeyparamset->keyinfo = cpu_to_le16(KEY_INFO_WPA_ENABLED);
} else {
pkeyparamset->keyinfo = cpu_to_le16(!KEY_INFO_WPA_ENABLED);
pkeyparamset->keyinfo |= cpu_to_le16(KEY_INFO_WPA_ENABLED);
}
if (pkey->flags & KEY_INFO_WPA_UNICAST) {
pkeyparamset->keyinfo |= cpu_to_le16(KEY_INFO_WPA_UNICAST);
} else if (pkey->flags & KEY_INFO_WPA_MCAST) {
}
if (pkey->flags & KEY_INFO_WPA_MCAST) {
pkeyparamset->keyinfo |= cpu_to_le16(KEY_INFO_WPA_MCAST);
}
......@@ -284,46 +275,45 @@ static int wlan_cmd_802_11_key_material(wlan_private * priv,
u16 cmd_action,
u32 cmd_oid, void *pdata_buf)
{
wlan_adapter *adapter = priv->adapter;
struct cmd_ds_802_11_key_material *pkeymaterial =
&cmd->params.keymaterial;
struct assoc_request * assoc_req = pdata_buf;
int ret = 0;
int index = 0;
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
cmd->command = cpu_to_le16(cmd_802_11_key_material);
pkeymaterial->action = cpu_to_le16(cmd_action);
if (cmd_action == cmd_act_get) {
cmd->size = cpu_to_le16( S_DS_GEN
+ sizeof (pkeymaterial->action));
cmd->size = cpu_to_le16(S_DS_GEN + sizeof (pkeymaterial->action));
ret = 0;
goto done;
}
memset(&pkeymaterial->keyParamSet, 0, sizeof(pkeymaterial->keyParamSet));
if (adapter->wpa_unicast_key.len) {
if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) {
set_one_wpa_key(&pkeymaterial->keyParamSet[index],
&adapter->wpa_unicast_key);
&assoc_req->wpa_unicast_key);
index++;
}
if (adapter->wpa_mcast_key.len) {
if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) {
set_one_wpa_key(&pkeymaterial->keyParamSet[index],
&adapter->wpa_mcast_key);
&assoc_req->wpa_mcast_key);
index++;
}
cmd->size = cpu_to_le16( S_DS_GEN
+ sizeof (pkeymaterial->action)
+ index * sizeof(struct MrvlIEtype_keyParamSet));
+ (index * sizeof(struct MrvlIEtype_keyParamSet)));
ret = 0;
done:
LEAVE();
lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
return ret;
}
......@@ -354,8 +344,7 @@ static int wlan_cmd_802_11_get_stat(wlan_private * priv,
{
cmd->command = cpu_to_le16(cmd_802_11_get_stat);
cmd->size =
cpu_to_le16(sizeof(struct cmd_ds_802_11_get_stat) +
S_DS_GEN);
cpu_to_le16(sizeof(struct cmd_ds_802_11_get_stat) + S_DS_GEN);
return 0;
}
......@@ -369,14 +358,12 @@ static int wlan_cmd_802_11_snmp_mib(wlan_private * priv,
wlan_adapter *adapter = priv->adapter;
u8 ucTemp;
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
lbs_pr_debug(1, "SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid);
lbs_deb_cmd("SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid);
cmd->command = cpu_to_le16(cmd_802_11_snmp_mib);
cmd->size =
cpu_to_le16(sizeof(struct cmd_ds_802_11_snmp_mib) +
S_DS_GEN);
cmd->size = cpu_to_le16(sizeof(*pSNMPMIB) + S_DS_GEN);
switch (cmd_oid) {
case OID_802_11_INFRASTRUCTURE_MODE:
......@@ -407,7 +394,7 @@ static int wlan_cmd_802_11_snmp_mib(wlan_private * priv,
pSNMPMIB->querytype = cmd_act_set;
pSNMPMIB->bufsize = sizeof(u16);
ulTemp = *(u32 *)pdata_buf;
*((unsigned short *)(pSNMPMIB->value)) =
*((__le16 *)(pSNMPMIB->value)) =
cpu_to_le16((u16) ulTemp);
}
break;
......@@ -420,15 +407,12 @@ static int wlan_cmd_802_11_snmp_mib(wlan_private * priv,
pSNMPMIB->oid = cpu_to_le16((u16) fragthresh_i);
if (cmd_action == cmd_act_get) {
pSNMPMIB->querytype =
cpu_to_le16(cmd_act_get);
pSNMPMIB->querytype = cpu_to_le16(cmd_act_get);
} else if (cmd_action == cmd_act_set) {
pSNMPMIB->querytype =
cpu_to_le16(cmd_act_set);
pSNMPMIB->bufsize =
cpu_to_le16(sizeof(u16));
pSNMPMIB->querytype = cpu_to_le16(cmd_act_set);
pSNMPMIB->bufsize = cpu_to_le16(sizeof(u16));
ulTemp = *((u32 *) pdata_buf);
*((unsigned short *)(pSNMPMIB->value)) =
*((__le16 *)(pSNMPMIB->value)) =
cpu_to_le16((u16) ulTemp);
}
......@@ -443,16 +427,12 @@ static int wlan_cmd_802_11_snmp_mib(wlan_private * priv,
pSNMPMIB->oid = le16_to_cpu((u16) rtsthresh_i);
if (cmd_action == cmd_act_get) {
pSNMPMIB->querytype =
cpu_to_le16(cmd_act_get);
pSNMPMIB->querytype = cpu_to_le16(cmd_act_get);
} else if (cmd_action == cmd_act_set) {
pSNMPMIB->querytype =
cpu_to_le16(cmd_act_set);
pSNMPMIB->bufsize =
cpu_to_le16(sizeof(u16));
ulTemp = *((u32 *)
pdata_buf);
*(unsigned short *)(pSNMPMIB->value) =
pSNMPMIB->querytype = cpu_to_le16(cmd_act_set);
pSNMPMIB->bufsize = cpu_to_le16(sizeof(u16));
ulTemp = *((u32 *)pdata_buf);
*(__le16 *)(pSNMPMIB->value) =
cpu_to_le16((u16) ulTemp);
}
......@@ -462,13 +442,11 @@ static int wlan_cmd_802_11_snmp_mib(wlan_private * priv,
pSNMPMIB->oid = cpu_to_le16((u16) short_retrylim_i);
if (cmd_action == cmd_act_get) {
pSNMPMIB->querytype =
cpu_to_le16(cmd_act_get);
pSNMPMIB->querytype = cpu_to_le16(cmd_act_get);
} else if (cmd_action == cmd_act_set) {
pSNMPMIB->querytype =
cpu_to_le16(cmd_act_set);
pSNMPMIB->querytype = cpu_to_le16(cmd_act_set);
pSNMPMIB->bufsize = cpu_to_le16(sizeof(u16));
*((unsigned short *)(pSNMPMIB->value)) =
*((__le16 *)(pSNMPMIB->value)) =
cpu_to_le16((u16) adapter->txretrycount);
}
......@@ -477,16 +455,18 @@ static int wlan_cmd_802_11_snmp_mib(wlan_private * priv,
break;
}
lbs_pr_debug(1,
lbs_deb_cmd(
"SNMP_CMD: command=0x%x, size=0x%x, seqnum=0x%x, result=0x%x\n",
cmd->command, cmd->size, cmd->seqnum, cmd->result);
le16_to_cpu(cmd->command), le16_to_cpu(cmd->size),
le16_to_cpu(cmd->seqnum), le16_to_cpu(cmd->result));
lbs_pr_debug(1,
lbs_deb_cmd(
"SNMP_CMD: action=0x%x, oid=0x%x, oidsize=0x%x, value=0x%x\n",
pSNMPMIB->querytype, pSNMPMIB->oid, pSNMPMIB->bufsize,
*(u16 *) pSNMPMIB->value);
le16_to_cpu(pSNMPMIB->querytype), le16_to_cpu(pSNMPMIB->oid),
le16_to_cpu(pSNMPMIB->bufsize),
le16_to_cpu(*(__le16 *) pSNMPMIB->value));
LEAVE();
lbs_deb_leave(LBS_DEB_CMD);
return 0;
}
......@@ -495,10 +475,9 @@ static int wlan_cmd_802_11_radio_control(wlan_private * priv,
int cmd_action)
{
wlan_adapter *adapter = priv->adapter;
struct cmd_ds_802_11_radio_control *pradiocontrol =
&cmd->params.radio;
struct cmd_ds_802_11_radio_control *pradiocontrol = &cmd->params.radio;
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
cmd->size =
cpu_to_le16((sizeof(struct cmd_ds_802_11_radio_control)) +
......@@ -527,7 +506,7 @@ static int wlan_cmd_802_11_radio_control(wlan_private * priv,
else
pradiocontrol->control &= cpu_to_le16(~TURN_ON_RF);
LEAVE();
lbs_deb_leave(LBS_DEB_CMD);
return 0;
}
......@@ -538,16 +517,16 @@ static int wlan_cmd_802_11_rf_tx_power(wlan_private * priv,
struct cmd_ds_802_11_rf_tx_power *prtp = &cmd->params.txp;
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
cmd->size =
cpu_to_le16((sizeof(struct cmd_ds_802_11_rf_tx_power)) +
S_DS_GEN);
cpu_to_le16((sizeof(struct cmd_ds_802_11_rf_tx_power)) + S_DS_GEN);
cmd->command = cpu_to_le16(cmd_802_11_rf_tx_power);
prtp->action = cmd_action;
prtp->action = cpu_to_le16(cmd_action);
lbs_pr_debug(1, "RF_TX_POWER_CMD: size:%d cmd:0x%x Act:%d\n", cmd->size,
cmd->command, prtp->action);
lbs_deb_cmd("RF_TX_POWER_CMD: size:%d cmd:0x%x Act:%d\n",
le16_to_cpu(cmd->size), le16_to_cpu(cmd->command),
le16_to_cpu(prtp->action));
switch (cmd_action) {
case cmd_act_tx_power_opt_get:
......@@ -557,14 +536,12 @@ static int wlan_cmd_802_11_rf_tx_power(wlan_private * priv,
case cmd_act_tx_power_opt_set_high:
prtp->action = cpu_to_le16(cmd_act_set);
prtp->currentlevel =
cpu_to_le16(cmd_act_tx_power_index_high);
prtp->currentlevel = cpu_to_le16(cmd_act_tx_power_index_high);
break;
case cmd_act_tx_power_opt_set_mid:
prtp->action = cpu_to_le16(cmd_act_set);
prtp->currentlevel =
cpu_to_le16(cmd_act_tx_power_index_mid);
prtp->currentlevel = cpu_to_le16(cmd_act_tx_power_index_mid);
break;
case cmd_act_tx_power_opt_set_low:
......@@ -572,7 +549,8 @@ static int wlan_cmd_802_11_rf_tx_power(wlan_private * priv,
prtp->currentlevel = cpu_to_le16(*((u16 *) pdata_buf));
break;
}
LEAVE();
lbs_deb_leave(LBS_DEB_CMD);
return 0;
}
......@@ -583,15 +561,12 @@ static int wlan_cmd_802_11_rf_antenna(wlan_private * priv,
struct cmd_ds_802_11_rf_antenna *rant = &cmd->params.rant;
cmd->command = cpu_to_le16(cmd_802_11_rf_antenna);
cmd->size =
cpu_to_le16(sizeof(struct cmd_ds_802_11_rf_antenna) +
cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_rf_antenna) +
S_DS_GEN);
rant->action = cpu_to_le16(cmd_action);
if ((cmd_action == cmd_act_set_rx) ||
(cmd_action == cmd_act_set_tx)) {
rant->antennamode =
cpu_to_le16((u16) (*(u32 *) pdata_buf));
if ((cmd_action == cmd_act_set_rx) || (cmd_action == cmd_act_set_tx)) {
rant->antennamode = cpu_to_le16((u16) (*(u32 *) pdata_buf));
}
return 0;
......@@ -610,13 +585,13 @@ static int wlan_cmd_802_11_rate_adapt_rateset(wlan_private * priv,
+ S_DS_GEN);
cmd->command = cpu_to_le16(cmd_802_11_rate_adapt_rateset);
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
rateadapt->action = cmd_action;
rateadapt->enablehwauto = adapter->enablehwauto;
rateadapt->bitmap = adapter->ratebitmap;
rateadapt->action = cpu_to_le16(cmd_action);
rateadapt->enablehwauto = cpu_to_le16(adapter->enablehwauto);
rateadapt->bitmap = cpu_to_le16(adapter->ratebitmap);
LEAVE();
lbs_deb_leave(LBS_DEB_CMD);
return 0;
}
......@@ -626,12 +601,10 @@ static int wlan_cmd_802_11_data_rate(wlan_private * priv,
{
struct cmd_ds_802_11_data_rate *pdatarate = &cmd->params.drate;
wlan_adapter *adapter = priv->adapter;
u16 action = cmd_action;
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
cmd->size =
cpu_to_le16(sizeof(struct cmd_ds_802_11_data_rate) +
cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_data_rate) +
S_DS_GEN);
cmd->command = cpu_to_le16(cmd_802_11_data_rate);
......@@ -640,15 +613,15 @@ static int wlan_cmd_802_11_data_rate(wlan_private * priv,
pdatarate->action = cpu_to_le16(cmd_action);
if (action == cmd_act_set_tx_fix_rate) {
if (cmd_action == cmd_act_set_tx_fix_rate) {
pdatarate->datarate[0] = libertas_data_rate_to_index(adapter->datarate);
lbs_pr_debug(1, "Setting FW for fixed rate 0x%02X\n",
lbs_deb_cmd("Setting FW for fixed rate 0x%02X\n",
adapter->datarate);
} else if (action == cmd_act_set_tx_auto) {
lbs_pr_debug(1, "Setting FW for AUTO rate\n");
} else if (cmd_action == cmd_act_set_tx_auto) {
lbs_deb_cmd("Setting FW for AUTO rate\n");
}
LEAVE();
lbs_deb_leave(LBS_DEB_CMD);
return 0;
}
......@@ -659,8 +632,7 @@ static int wlan_cmd_mac_multicast_adr(wlan_private * priv,
struct cmd_ds_mac_multicast_adr *pMCastAdr = &cmd->params.madr;
wlan_adapter *adapter = priv->adapter;
cmd->size =
cpu_to_le16(sizeof(struct cmd_ds_mac_multicast_adr) +
cmd->size = cpu_to_le16(sizeof(struct cmd_ds_mac_multicast_adr) +
S_DS_GEN);
cmd->command = cpu_to_le16(cmd_mac_multicast_adr);
......@@ -680,8 +652,8 @@ static int wlan_cmd_802_11_rf_channel(wlan_private * priv,
struct cmd_ds_802_11_rf_channel *rfchan = &cmd->params.rfchannel;
cmd->command = cpu_to_le16(cmd_802_11_rf_channel);
cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_rf_channel)
+ S_DS_GEN);
cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_rf_channel) +
S_DS_GEN);
if (option == cmd_opt_802_11_rf_channel_set) {
rfchan->currentchannel = cpu_to_le16(*((u16 *) pdata_buf));
......@@ -698,9 +670,8 @@ static int wlan_cmd_802_11_rssi(wlan_private * priv,
wlan_adapter *adapter = priv->adapter;
cmd->command = cpu_to_le16(cmd_802_11_rssi);
cmd->size =
cpu_to_le16(sizeof(struct cmd_ds_802_11_rssi) + S_DS_GEN);
cmd->params.rssi.N = priv->adapter->bcn_avg_factor;
cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_rssi) + S_DS_GEN);
cmd->params.rssi.N = cpu_to_le16(priv->adapter->bcn_avg_factor);
/* reset Beacon SNR/NF/RSSI values */
adapter->SNR[TYPE_BEACON][TYPE_NOAVG] = 0;
......@@ -719,7 +690,7 @@ static int wlan_cmd_reg_access(wlan_private * priv,
{
struct wlan_offset_value *offval;
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
offval = (struct wlan_offset_value *)pdata_buf;
......@@ -729,8 +700,7 @@ static int wlan_cmd_reg_access(wlan_private * priv,
struct cmd_ds_mac_reg_access *macreg;
cmdptr->size =
cpu_to_le16(sizeof
(struct cmd_ds_mac_reg_access)
cpu_to_le16(sizeof (struct cmd_ds_mac_reg_access)
+ S_DS_GEN);
macreg =
(struct cmd_ds_mac_reg_access *)&cmdptr->params.
......@@ -785,7 +755,7 @@ static int wlan_cmd_reg_access(wlan_private * priv,
break;
}
LEAVE();
lbs_deb_leave(LBS_DEB_CMD);
return 0;
}
......@@ -796,8 +766,7 @@ static int wlan_cmd_802_11_mac_address(wlan_private * priv,
wlan_adapter *adapter = priv->adapter;
cmd->command = cpu_to_le16(cmd_802_11_mac_address);
cmd->size =
cpu_to_le16(sizeof(struct cmd_ds_802_11_mac_address) +
cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_mac_address) +
S_DS_GEN);
cmd->result = 0;
......@@ -818,11 +787,10 @@ static int wlan_cmd_802_11_eeprom_access(wlan_private * priv,
{
struct wlan_ioctl_regrdwr *ea = pdata_buf;
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
cmd->command = cpu_to_le16(cmd_802_11_eeprom_access);
cmd->size =
cpu_to_le16(sizeof(struct cmd_ds_802_11_eeprom_access) +
cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_eeprom_access) +
S_DS_GEN);
cmd->result = 0;
......@@ -839,11 +807,10 @@ static int wlan_cmd_bt_access(wlan_private * priv,
u16 cmd_action, void *pdata_buf)
{
struct cmd_ds_bt_access *bt_access = &cmd->params.bt;
lbs_pr_debug(1, "BT CMD(%d)\n", cmd_action);
lbs_deb_cmd("BT CMD(%d)\n", cmd_action);
cmd->command = cpu_to_le16(cmd_bt_access);
cmd->size = cpu_to_le16(sizeof(struct cmd_ds_bt_access)
+ S_DS_GEN);
cmd->size = cpu_to_le16(sizeof(struct cmd_ds_bt_access) + S_DS_GEN);
cmd->result = 0;
bt_access->action = cpu_to_le16(cmd_action);
......@@ -861,6 +828,11 @@ static int wlan_cmd_bt_access(wlan_private * priv,
break;
case cmd_act_bt_access_reset:
break;
case cmd_act_bt_access_set_invert:
bt_access->id = cpu_to_le32(*(u32 *) pdata_buf);
break;
case cmd_act_bt_access_get_invert:
break;
default:
break;
}
......@@ -872,11 +844,10 @@ static int wlan_cmd_fwt_access(wlan_private * priv,
u16 cmd_action, void *pdata_buf)
{
struct cmd_ds_fwt_access *fwt_access = &cmd->params.fwt;
lbs_pr_debug(1, "FWT CMD(%d)\n", cmd_action);
lbs_deb_cmd("FWT CMD(%d)\n", cmd_action);
cmd->command = cpu_to_le16(cmd_fwt_access);
cmd->size = cpu_to_le16(sizeof(struct cmd_ds_fwt_access)
+ S_DS_GEN);
cmd->size = cpu_to_le16(sizeof(struct cmd_ds_fwt_access) + S_DS_GEN);
cmd->result = 0;
if (pdata_buf)
......@@ -894,11 +865,10 @@ static int wlan_cmd_mesh_access(wlan_private * priv,
u16 cmd_action, void *pdata_buf)
{
struct cmd_ds_mesh_access *mesh_access = &cmd->params.mesh;
lbs_pr_debug(1, "FWT CMD(%d)\n", cmd_action);
lbs_deb_cmd("FWT CMD(%d)\n", cmd_action);
cmd->command = cpu_to_le16(cmd_mesh_access);
cmd->size = cpu_to_le16(sizeof(struct cmd_ds_mesh_access)
+ S_DS_GEN);
cmd->size = cpu_to_le16(sizeof(struct cmd_ds_mesh_access) + S_DS_GEN);
cmd->result = 0;
if (pdata_buf)
......@@ -916,23 +886,23 @@ void libertas_queue_cmd(wlan_adapter * adapter, struct cmd_ctrl_node *cmdnode, u
unsigned long flags;
struct cmd_ds_command *cmdptr;
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
if (!cmdnode) {
lbs_pr_debug(1, "QUEUE_CMD: cmdnode is NULL\n");
lbs_deb_cmd("QUEUE_CMD: cmdnode is NULL\n");
goto done;
}
cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr;
if (!cmdptr) {
lbs_pr_debug(1, "QUEUE_CMD: cmdptr is NULL\n");
lbs_deb_cmd("QUEUE_CMD: cmdptr is NULL\n");
goto done;
}
/* Exit_PS command needs to be queued in the header always. */
if (cmdptr->command == cmd_802_11_ps_mode) {
struct cmd_ds_802_11_ps_mode *psm = &cmdptr->params.psmode;
if (psm->action == cmd_subcmd_exit_ps) {
if (psm->action == cpu_to_le16(cmd_subcmd_exit_ps)) {
if (adapter->psstate != PS_STATE_FULL_POWER)
addtail = 0;
}
......@@ -948,13 +918,12 @@ void libertas_queue_cmd(wlan_adapter * adapter, struct cmd_ctrl_node *cmdnode, u
spin_unlock_irqrestore(&adapter->driver_lock, flags);
lbs_pr_debug(1, "QUEUE_CMD: Inserted node=%p, cmd=0x%x in cmdpendingq\n",
lbs_deb_cmd("QUEUE_CMD: Inserted node=%p, cmd=0x%x in cmdpendingq\n",
cmdnode,
((struct cmd_ds_gen*)cmdnode->bufvirtualaddr)->command);
le16_to_cpu(((struct cmd_ds_gen*)cmdnode->bufvirtualaddr)->command));
done:
LEAVE();
return;
lbs_deb_leave(LBS_DEB_CMD);
}
/*
......@@ -974,10 +943,10 @@ static int DownloadcommandToStation(wlan_private * priv,
u16 cmdsize;
u16 command;
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
if (!adapter || !cmdnode) {
lbs_pr_debug(1, "DNLD_CMD: adapter = %p, cmdnode = %p\n",
lbs_deb_cmd("DNLD_CMD: adapter = %p, cmdnode = %p\n",
adapter, cmdnode);
if (cmdnode) {
spin_lock_irqsave(&adapter->driver_lock, flags);
......@@ -993,7 +962,7 @@ static int DownloadcommandToStation(wlan_private * priv,
spin_lock_irqsave(&adapter->driver_lock, flags);
if (!cmdptr || !cmdptr->size) {
lbs_pr_debug(1, "DNLD_CMD: cmdptr is Null or cmd size is Zero, "
lbs_deb_cmd("DNLD_CMD: cmdptr is Null or cmd size is Zero, "
"Not sending\n");
__libertas_cleanup_and_insert_cmd(priv, cmdnode);
spin_unlock_irqrestore(&adapter->driver_lock, flags);
......@@ -1004,8 +973,8 @@ static int DownloadcommandToStation(wlan_private * priv,
adapter->cur_cmd = cmdnode;
adapter->cur_cmd_retcode = 0;
spin_unlock_irqrestore(&adapter->driver_lock, flags);
lbs_pr_debug(1, "DNLD_CMD:: Before download, size of cmd = %d\n",
cmdptr->size);
lbs_deb_cmd("DNLD_CMD:: Before download, size of cmd = %d\n",
le16_to_cpu(cmdptr->size));
cmdsize = cmdptr->size;
......@@ -1014,10 +983,10 @@ static int DownloadcommandToStation(wlan_private * priv,
cmdnode->cmdwaitqwoken = 0;
cmdsize = cpu_to_le16(cmdsize);
ret = libertas_sbi_host_to_card(priv, MVMS_CMD, (u8 *) cmdptr, cmdsize);
ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmdptr, cmdsize);
if (ret != 0) {
lbs_pr_debug(1, "DNLD_CMD: Host to Card failed\n");
lbs_deb_cmd("DNLD_CMD: Host to Card failed\n");
spin_lock_irqsave(&adapter->driver_lock, flags);
__libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd);
adapter->cur_cmd = NULL;
......@@ -1026,12 +995,11 @@ static int DownloadcommandToStation(wlan_private * priv,
goto done;
}
lbs_pr_debug(1, "DNLD_CMD: Sent command 0x%x @ %lu\n", command, jiffies);
lbs_deb_cmd("DNLD_CMD: Sent command 0x%x @ %lu\n", command, jiffies);
lbs_dbg_hex("DNLD_CMD: command", cmdnode->bufvirtualaddr, cmdsize);
/* Setup the timer after transmit command */
if (command == cmd_802_11_scan
|| command == cmd_802_11_authenticate
if (command == cmd_802_11_scan || command == cmd_802_11_authenticate
|| command == cmd_802_11_associate)
mod_timer(&adapter->command_timer, jiffies + (10*HZ));
else
......@@ -1039,8 +1007,8 @@ static int DownloadcommandToStation(wlan_private * priv,
ret = 0;
done:
LEAVE();
done:
lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
return ret;
}
......@@ -1049,17 +1017,16 @@ static int wlan_cmd_mac_control(wlan_private * priv,
{
struct cmd_ds_mac_control *mac = &cmd->params.macctrl;
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
cmd->command = cpu_to_le16(cmd_mac_control);
cmd->size =
cpu_to_le16(sizeof(struct cmd_ds_mac_control) + S_DS_GEN);
cmd->size = cpu_to_le16(sizeof(struct cmd_ds_mac_control) + S_DS_GEN);
mac->action = cpu_to_le16(priv->adapter->currentpacketfilter);
lbs_pr_debug(1, "wlan_cmd_mac_control(): action=0x%X size=%d\n",
mac->action, cmd->size);
lbs_deb_cmd("wlan_cmd_mac_control(): action=0x%X size=%d\n",
le16_to_cpu(mac->action), le16_to_cpu(cmd->size));
LEAVE();
lbs_deb_leave(LBS_DEB_CMD);
return 0;
}
......@@ -1093,17 +1060,17 @@ int libertas_set_radio_control(wlan_private * priv)
{
int ret = 0;
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
ret = libertas_prepare_and_send_command(priv,
cmd_802_11_radio_control,
cmd_act_set,
cmd_option_waitforrsp, 0, NULL);
lbs_pr_debug(1, "RADIO_SET: on or off: 0x%X, preamble = 0x%X\n",
lbs_deb_cmd("RADIO_SET: on or off: 0x%X, preamble = 0x%X\n",
priv->adapter->radioon, priv->adapter->preamble);
LEAVE();
lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
return ret;
}
......@@ -1111,16 +1078,16 @@ int libertas_set_mac_packet_filter(wlan_private * priv)
{
int ret = 0;
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
lbs_pr_debug(1, "libertas_set_mac_packet_filter value = %x\n",
lbs_deb_cmd("libertas_set_mac_packet_filter value = %x\n",
priv->adapter->currentpacketfilter);
/* Send MAC control command to station */
ret = libertas_prepare_and_send_command(priv,
cmd_mac_control, 0, 0, 0, NULL);
LEAVE();
lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
return ret;
}
......@@ -1146,16 +1113,16 @@ int libertas_prepare_and_send_command(wlan_private * priv,
struct cmd_ds_command *cmdptr;
unsigned long flags;
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
if (!adapter) {
lbs_pr_debug(1, "PREP_CMD: adapter is Null\n");
lbs_deb_cmd("PREP_CMD: adapter is Null\n");
ret = -1;
goto done;
}
if (adapter->surpriseremoved) {
lbs_pr_debug(1, "PREP_CMD: Card is Removed\n");
lbs_deb_cmd("PREP_CMD: Card is Removed\n");
ret = -1;
goto done;
}
......@@ -1163,7 +1130,7 @@ int libertas_prepare_and_send_command(wlan_private * priv,
cmdnode = libertas_get_free_cmd_ctrl_node(priv);
if (cmdnode == NULL) {
lbs_pr_debug(1, "PREP_CMD: No free cmdnode\n");
lbs_deb_cmd("PREP_CMD: No free cmdnode\n");
/* Wake up main thread to execute next command */
wake_up_interruptible(&priv->mainthread.waitq);
......@@ -1175,11 +1142,11 @@ int libertas_prepare_and_send_command(wlan_private * priv,
cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr;
lbs_pr_debug(1, "PREP_CMD: Val of cmd ptr=%p, command=0x%X\n",
lbs_deb_cmd("PREP_CMD: Val of cmd ptr=%p, command=0x%X\n",
cmdptr, cmd_no);
if (!cmdptr) {
lbs_pr_debug(1, "PREP_CMD: bufvirtualaddr of cmdnode is NULL\n");
lbs_deb_cmd("PREP_CMD: bufvirtualaddr of cmdnode is NULL\n");
libertas_cleanup_and_insert_cmd(priv, cmdnode);
ret = -1;
goto done;
......@@ -1189,7 +1156,7 @@ int libertas_prepare_and_send_command(wlan_private * priv,
adapter->seqnum++;
cmdptr->seqnum = cpu_to_le16(adapter->seqnum);
cmdptr->command = cmd_no;
cmdptr->command = cpu_to_le16(cmd_no);
cmdptr->result = 0;
switch (cmd_no) {
......@@ -1298,13 +1265,13 @@ int libertas_prepare_and_send_command(wlan_private * priv,
break;
case cmd_802_11_enable_rsn:
ret = wlan_cmd_802_11_enable_rsn(priv, cmdptr, cmd_action);
ret = wlan_cmd_802_11_enable_rsn(priv, cmdptr, cmd_action,
pdata_buf);
break;
case cmd_802_11_key_material:
ret = wlan_cmd_802_11_key_material(priv, cmdptr,
cmd_action, cmd_oid,
pdata_buf);
ret = wlan_cmd_802_11_key_material(priv, cmdptr, cmd_action,
cmd_oid, pdata_buf);
break;
case cmd_802_11_pairwise_tsc:
......@@ -1325,8 +1292,7 @@ int libertas_prepare_and_send_command(wlan_private * priv,
case cmd_802_11_get_afc:
cmdptr->command = cpu_to_le16(cmd_no);
cmdptr->size =
cpu_to_le16(sizeof(struct cmd_ds_802_11_afc) +
cmdptr->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_afc) +
S_DS_GEN);
memmove(&cmdptr->params.afc,
......@@ -1406,29 +1372,26 @@ int libertas_prepare_and_send_command(wlan_private * priv,
case cmd_get_tsf:
cmdptr->command = cpu_to_le16(cmd_get_tsf);
cmdptr->size =
cpu_to_le16(sizeof(struct cmd_ds_get_tsf)
+ S_DS_GEN);
cmdptr->size = cpu_to_le16(sizeof(struct cmd_ds_get_tsf) +
S_DS_GEN);
ret = 0;
break;
case cmd_802_11_tx_rate_query:
cmdptr->command =
cpu_to_le16(cmd_802_11_tx_rate_query);
cmdptr->size =
cpu_to_le16(sizeof(struct cmd_tx_rate_query) +
cmdptr->command = cpu_to_le16(cmd_802_11_tx_rate_query);
cmdptr->size = cpu_to_le16(sizeof(struct cmd_tx_rate_query) +
S_DS_GEN);
adapter->txrate = 0;
ret = 0;
break;
default:
lbs_pr_debug(1, "PREP_CMD: unknown command- %#x\n", cmd_no);
lbs_deb_cmd("PREP_CMD: unknown command- %#x\n", cmd_no);
ret = -1;
break;
}
/* return error, since the command preparation failed */
if (ret != 0) {
lbs_pr_debug(1, "PREP_CMD: command preparation failed\n");
lbs_deb_cmd("PREP_CMD: command preparation failed\n");
libertas_cleanup_and_insert_cmd(priv, cmdnode);
ret = -1;
goto done;
......@@ -1441,7 +1404,7 @@ int libertas_prepare_and_send_command(wlan_private * priv,
wake_up_interruptible(&priv->mainthread.waitq);
if (wait_option & cmd_option_waitforrsp) {
lbs_pr_debug(1, "PREP_CMD: Wait for CMD response\n");
lbs_deb_cmd("PREP_CMD: Wait for CMD response\n");
might_sleep();
wait_event_interruptible(cmdnode->cmdwait_q,
cmdnode->cmdwaitqwoken);
......@@ -1449,7 +1412,7 @@ int libertas_prepare_and_send_command(wlan_private * priv,
spin_lock_irqsave(&adapter->driver_lock, flags);
if (adapter->cur_cmd_retcode) {
lbs_pr_debug(1, "PREP_CMD: command failed with return code=%d\n",
lbs_deb_cmd("PREP_CMD: command failed with return code=%d\n",
adapter->cur_cmd_retcode);
adapter->cur_cmd_retcode = 0;
ret = -1;
......@@ -1457,9 +1420,10 @@ int libertas_prepare_and_send_command(wlan_private * priv,
spin_unlock_irqrestore(&adapter->driver_lock, flags);
done:
LEAVE();
lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
return ret;
}
EXPORT_SYMBOL_GPL(libertas_prepare_and_send_command);
/**
* @brief This function allocates the command buffer and link
......@@ -1477,33 +1441,29 @@ int libertas_allocate_cmd_buffer(wlan_private * priv)
u8 *ptempvirtualaddr;
wlan_adapter *adapter = priv->adapter;
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
/* Allocate and initialize cmdCtrlNode */
ulbufsize = sizeof(struct cmd_ctrl_node) * MRVDRV_NUM_OF_CMD_BUFFER;
if (!(tempcmd_array = kmalloc(ulbufsize, GFP_KERNEL))) {
lbs_pr_debug(1,
if (!(tempcmd_array = kzalloc(ulbufsize, GFP_KERNEL))) {
lbs_deb_cmd(
"ALLOC_CMD_BUF: failed to allocate tempcmd_array\n");
ret = -1;
goto done;
}
adapter->cmd_array = tempcmd_array;
memset(adapter->cmd_array, 0, ulbufsize);
/* Allocate and initialize command buffers */
ulbufsize = MRVDRV_SIZE_OF_CMD_BUFFER;
for (i = 0; i < MRVDRV_NUM_OF_CMD_BUFFER; i++) {
if (!(ptempvirtualaddr = kmalloc(ulbufsize, GFP_KERNEL))) {
lbs_pr_debug(1,
if (!(ptempvirtualaddr = kzalloc(ulbufsize, GFP_KERNEL))) {
lbs_deb_cmd(
"ALLOC_CMD_BUF: ptempvirtualaddr: out of memory\n");
ret = -1;
goto done;
}
memset(ptempvirtualaddr, 0, ulbufsize);
/* Update command buffer virtual */
tempcmd_array[i].bufvirtualaddr = ptempvirtualaddr;
}
......@@ -1514,8 +1474,9 @@ int libertas_allocate_cmd_buffer(wlan_private * priv)
}
ret = 0;
done:
LEAVE();
done:
lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
return ret;
}
......@@ -1527,16 +1488,16 @@ int libertas_allocate_cmd_buffer(wlan_private * priv)
*/
int libertas_free_cmd_buffer(wlan_private * priv)
{
u32 ulbufsize;
u32 ulbufsize; /* Someone needs to die for this. Slowly and painfully */
unsigned int i;
struct cmd_ctrl_node *tempcmd_array;
wlan_adapter *adapter = priv->adapter;
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
/* need to check if cmd array is allocated or not */
if (adapter->cmd_array == NULL) {
lbs_pr_debug(1, "FREE_CMD_BUF: cmd_array is Null\n");
lbs_deb_cmd("FREE_CMD_BUF: cmd_array is Null\n");
goto done;
}
......@@ -1546,7 +1507,7 @@ int libertas_free_cmd_buffer(wlan_private * priv)
ulbufsize = MRVDRV_SIZE_OF_CMD_BUFFER;
for (i = 0; i < MRVDRV_NUM_OF_CMD_BUFFER; i++) {
if (tempcmd_array[i].bufvirtualaddr) {
lbs_pr_debug(1, "Free all the array\n");
lbs_deb_cmd("Free all the array\n");
kfree(tempcmd_array[i].bufvirtualaddr);
tempcmd_array[i].bufvirtualaddr = NULL;
}
......@@ -1554,13 +1515,13 @@ int libertas_free_cmd_buffer(wlan_private * priv)
/* Release cmd_ctrl_node */
if (adapter->cmd_array) {
lbs_pr_debug(1, "Free cmd_array\n");
lbs_deb_cmd("Free cmd_array\n");
kfree(adapter->cmd_array);
adapter->cmd_array = NULL;
}
done:
LEAVE();
lbs_deb_leave(LBS_DEB_CMD);
return 0;
}
......@@ -1586,16 +1547,18 @@ struct cmd_ctrl_node *libertas_get_free_cmd_ctrl_node(wlan_private * priv)
tempnode = (struct cmd_ctrl_node *)adapter->cmdfreeq.next;
list_del((struct list_head *)tempnode);
} else {
lbs_pr_debug(1, "GET_CMD_NODE: cmd_ctrl_node is not available\n");
lbs_deb_cmd("GET_CMD_NODE: cmd_ctrl_node is not available\n");
tempnode = NULL;
}
spin_unlock_irqrestore(&adapter->driver_lock, flags);
if (tempnode) {
/*
lbs_pr_debug(3, "GET_CMD_NODE: cmdCtrlNode available\n");
lbs_pr_debug(3, "GET_CMD_NODE: cmdCtrlNode Address = %p\n",
tempnode);
*/
cleanup_cmdnode(tempnode);
}
......@@ -1638,7 +1601,7 @@ void libertas_set_cmd_ctrl_node(wlan_private * priv,
struct cmd_ctrl_node *ptempnode,
u32 cmd_oid, u16 wait_option, void *pdata_buf)
{
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
if (!ptempnode)
return;
......@@ -1647,7 +1610,7 @@ void libertas_set_cmd_ctrl_node(wlan_private * priv,
ptempnode->wait_option = wait_option;
ptempnode->pdata_buf = pdata_buf;
LEAVE();
lbs_deb_leave(LBS_DEB_CMD);
}
/**
......@@ -1666,7 +1629,7 @@ int libertas_execute_next_command(wlan_private * priv)
unsigned long flags;
int ret = 0;
lbs_pr_debug(1, "libertas_execute_next_command\n");
lbs_deb_enter(LBS_DEB_CMD);
spin_lock_irqsave(&adapter->driver_lock, flags);
......@@ -1685,23 +1648,24 @@ int libertas_execute_next_command(wlan_private * priv)
spin_unlock_irqrestore(&adapter->driver_lock, flags);
if (cmdnode) {
lbs_pr_debug(1,
lbs_deb_cmd(
"EXEC_NEXT_CMD: Got next command from cmdpendingq\n");
cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr;
if (is_command_allowed_in_ps(cmdptr->command)) {
if ((adapter->psstate == PS_STATE_SLEEP)
|| (adapter->psstate == PS_STATE_PRE_SLEEP)
) {
lbs_pr_debug(1,
if ((adapter->psstate == PS_STATE_SLEEP) ||
(adapter->psstate == PS_STATE_PRE_SLEEP)) {
lbs_deb_cmd(
"EXEC_NEXT_CMD: Cannot send cmd 0x%x in psstate %d\n",
cmdptr->command, adapter->psstate);
le16_to_cpu(cmdptr->command),
adapter->psstate);
ret = -1;
goto done;
}
lbs_pr_debug(1, "EXEC_NEXT_CMD: OK to send command "
lbs_deb_cmd("EXEC_NEXT_CMD: OK to send command "
"0x%x in psstate %d\n",
cmdptr->command, adapter->psstate);
le16_to_cpu(cmdptr->command),
adapter->psstate);
} else if (adapter->psstate != PS_STATE_FULL_POWER) {
/*
* 1. Non-PS command:
......@@ -1737,12 +1701,12 @@ int libertas_execute_next_command(wlan_private * priv)
struct cmd_ds_802_11_ps_mode *psm =
&cmdptr->params.psmode;
lbs_pr_debug(1,
lbs_deb_cmd(
"EXEC_NEXT_CMD: PS cmd- action=0x%x\n",
psm->action);
if (psm->action !=
cpu_to_le16(cmd_subcmd_exit_ps)) {
lbs_pr_debug(1,
lbs_deb_cmd(
"EXEC_NEXT_CMD: Ignore Enter PS cmd\n");
list_del((struct list_head *)cmdnode);
libertas_cleanup_and_insert_cmd(priv, cmdnode);
......@@ -1751,10 +1715,9 @@ int libertas_execute_next_command(wlan_private * priv)
goto done;
}
if ((adapter->psstate == PS_STATE_SLEEP)
|| (adapter->psstate == PS_STATE_PRE_SLEEP)
) {
lbs_pr_debug(1,
if ((adapter->psstate == PS_STATE_SLEEP) ||
(adapter->psstate == PS_STATE_PRE_SLEEP)) {
lbs_deb_cmd(
"EXEC_NEXT_CMD: Ignore ExitPS cmd in sleep\n");
list_del((struct list_head *)cmdnode);
libertas_cleanup_and_insert_cmd(priv, cmdnode);
......@@ -1764,13 +1727,13 @@ int libertas_execute_next_command(wlan_private * priv)
goto done;
}
lbs_pr_debug(1,
lbs_deb_cmd(
"EXEC_NEXT_CMD: Sending Exit_PS down...\n");
}
}
list_del((struct list_head *)cmdnode);
lbs_pr_debug(1, "EXEC_NEXT_CMD: Sending 0x%04X command\n",
cmdptr->command);
lbs_deb_cmd("EXEC_NEXT_CMD: Sending 0x%04X command\n",
le16_to_cpu(cmdptr->command));
DownloadcommandToStation(priv, cmdnode);
} else {
/*
......@@ -1780,18 +1743,18 @@ int libertas_execute_next_command(wlan_private * priv)
if ((adapter->psmode != wlan802_11powermodecam) &&
(adapter->psstate == PS_STATE_FULL_POWER) &&
(adapter->connect_status == libertas_connected)) {
if (adapter->secinfo.WPAenabled
|| adapter->secinfo.WPA2enabled) {
if (adapter->secinfo.WPAenabled ||
adapter->secinfo.WPA2enabled) {
/* check for valid WPA group keys */
if (adapter->wpa_mcast_key.len
|| adapter->wpa_unicast_key.len) {
lbs_pr_debug(1,
if (adapter->wpa_mcast_key.len ||
adapter->wpa_unicast_key.len) {
lbs_deb_cmd(
"EXEC_NEXT_CMD: WPA enabled and GTK_SET"
" go back to PS_SLEEP");
libertas_ps_sleep(priv, 0);
}
} else {
lbs_pr_debug(1,
lbs_deb_cmd(
"EXEC_NEXT_CMD: command PendQ is empty,"
" go back to PS_SLEEP");
libertas_ps_sleep(priv, 0);
......@@ -1801,6 +1764,7 @@ int libertas_execute_next_command(wlan_private * priv)
ret = 0;
done:
lbs_deb_leave(LBS_DEB_CMD);
return ret;
}
......@@ -1809,7 +1773,7 @@ void libertas_send_iwevcustom_event(wlan_private * priv, s8 * str)
union iwreq_data iwrq;
u8 buf[50];
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
memset(&iwrq, 0, sizeof(union iwreq_data));
memset(buf, 0, sizeof(buf));
......@@ -1819,15 +1783,13 @@ void libertas_send_iwevcustom_event(wlan_private * priv, s8 * str)
iwrq.data.length = strlen(buf) + 1 + IW_EV_LCP_LEN;
/* Send Event to upper layer */
lbs_pr_debug(1, "Event Indication string = %s\n",
(char *)buf);
lbs_pr_debug(1, "Event Indication String length = %d\n", iwrq.data.length);
lbs_deb_cmd("Event Indication string = %s\n", (char *)buf);
lbs_deb_cmd("Event Indication String length = %d\n", iwrq.data.length);
lbs_pr_debug(1, "Sending wireless event IWEVCUSTOM for %s\n", str);
wireless_send_event(priv->wlan_dev.netdev, IWEVCUSTOM, &iwrq, buf);
lbs_deb_cmd("Sending wireless event IWEVCUSTOM for %s\n", str);
wireless_send_event(priv->dev, IWEVCUSTOM, &iwrq, buf);
LEAVE();
return;
lbs_deb_leave(LBS_DEB_CMD);
}
static int sendconfirmsleep(wlan_private * priv, u8 * cmdptr, u16 size)
......@@ -1836,19 +1798,19 @@ static int sendconfirmsleep(wlan_private * priv, u8 * cmdptr, u16 size)
wlan_adapter *adapter = priv->adapter;
int ret = 0;
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
lbs_pr_debug(1, "SEND_SLEEPC_CMD: Before download, size of cmd = %d\n",
lbs_deb_cmd("SEND_SLEEPC_CMD: Before download, size of cmd = %d\n",
size);
lbs_dbg_hex("SEND_SLEEPC_CMD: Sleep confirm command", cmdptr, size);
ret = libertas_sbi_host_to_card(priv, MVMS_CMD, cmdptr, size);
priv->wlan_dev.dnld_sent = DNLD_RES_RECEIVED;
ret = priv->hw_host_to_card(priv, MVMS_CMD, cmdptr, size);
priv->dnld_sent = DNLD_RES_RECEIVED;
spin_lock_irqsave(&adapter->driver_lock, flags);
if (adapter->intcounter || adapter->currenttxskb)
lbs_pr_debug(1, "SEND_SLEEPC_CMD: intcounter=%d currenttxskb=%p\n",
lbs_deb_cmd("SEND_SLEEPC_CMD: intcounter=%d currenttxskb=%p\n",
adapter->intcounter, adapter->currenttxskb);
spin_unlock_irqrestore(&adapter->driver_lock, flags);
......@@ -1860,23 +1822,22 @@ static int sendconfirmsleep(wlan_private * priv, u8 * cmdptr, u16 size)
if (!adapter->intcounter) {
adapter->psstate = PS_STATE_SLEEP;
} else {
lbs_pr_debug(1, "SEND_SLEEPC_CMD: After sent,IntC=%d\n",
lbs_deb_cmd("SEND_SLEEPC_CMD: After sent,IntC=%d\n",
adapter->intcounter);
}
spin_unlock_irqrestore(&adapter->driver_lock, flags);
lbs_pr_debug(1, "SEND_SLEEPC_CMD: Sent Confirm Sleep command\n");
lbs_pr_debug(1, "+");
lbs_deb_cmd("SEND_SLEEPC_CMD: Sent Confirm Sleep command\n");
lbs_deb_cmd("+");
}
LEAVE();
lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
return ret;
}
void libertas_ps_sleep(wlan_private * priv, int wait_option)
{
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
/*
* PS is currently supported only in Infrastructure mode
......@@ -1886,8 +1847,7 @@ void libertas_ps_sleep(wlan_private * priv, int wait_option)
libertas_prepare_and_send_command(priv, cmd_802_11_ps_mode,
cmd_subcmd_enter_ps, wait_option, 0, NULL);
LEAVE();
return;
lbs_deb_leave(LBS_DEB_CMD);
}
/**
......@@ -1899,20 +1859,19 @@ void libertas_ps_sleep(wlan_private * priv, int wait_option)
*/
void libertas_ps_wakeup(wlan_private * priv, int wait_option)
{
enum WLAN_802_11_POWER_MODE Localpsmode;
__le32 Localpsmode;
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
Localpsmode = wlan802_11powermodecam;
Localpsmode = cpu_to_le32(wlan802_11powermodecam);
lbs_pr_debug(1, "Exit_PS: Localpsmode = %d\n", Localpsmode);
lbs_deb_cmd("Exit_PS: Localpsmode = %d\n", wlan802_11powermodecam);
libertas_prepare_and_send_command(priv, cmd_802_11_ps_mode,
cmd_subcmd_exit_ps,
wait_option, 0, &Localpsmode);
LEAVE();
return;
lbs_deb_leave(LBS_DEB_CMD);
}
/**
......@@ -1929,31 +1888,31 @@ void libertas_ps_confirm_sleep(wlan_private * priv, u16 psmode)
wlan_adapter *adapter = priv->adapter;
u8 allowed = 1;
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
if (priv->wlan_dev.dnld_sent) {
if (priv->dnld_sent) {
allowed = 0;
lbs_pr_debug(1, "D");
lbs_deb_cmd("D");
}
spin_lock_irqsave(&adapter->driver_lock, flags);
if (adapter->cur_cmd) {
allowed = 0;
lbs_pr_debug(1, "C");
lbs_deb_cmd("C");
}
if (adapter->intcounter > 0) {
allowed = 0;
lbs_pr_debug(1, "I%d", adapter->intcounter);
lbs_deb_cmd("I%d", adapter->intcounter);
}
spin_unlock_irqrestore(&adapter->driver_lock, flags);
if (allowed) {
lbs_pr_debug(1, "Sending libertas_ps_confirm_sleep\n");
lbs_deb_cmd("Sending libertas_ps_confirm_sleep\n");
sendconfirmsleep(priv, (u8 *) & adapter->libertas_ps_confirm_sleep,
sizeof(struct PS_CMD_ConfirmSleep));
} else {
lbs_pr_debug(1, "Sleep Confirm has been delayed\n");
lbs_deb_cmd("Sleep Confirm has been delayed\n");
}
LEAVE();
lbs_deb_leave(LBS_DEB_CMD);
}
......@@ -9,7 +9,6 @@
#include <net/iw_handler.h>
#include "host.h"
#include "sbi.h"
#include "decl.h"
#include "defs.h"
#include "dev.h"
......@@ -32,7 +31,7 @@ void libertas_mac_event_disconnected(wlan_private * priv)
if (adapter->connect_status != libertas_connected)
return;
lbs_pr_debug(1, "Handles disconnect event.\n");
lbs_deb_cmd("Handles disconnect event.\n");
memset(wrqu.ap_addr.sa_data, 0x00, ETH_ALEN);
wrqu.ap_addr.sa_family = ARPHRD_ETHER;
......@@ -43,15 +42,15 @@ void libertas_mac_event_disconnected(wlan_private * priv)
*/
msleep_interruptible(1000);
wireless_send_event(priv->wlan_dev.netdev, SIOCGIWAP, &wrqu, NULL);
wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
/* Free Tx and Rx packets */
kfree_skb(priv->adapter->currenttxskb);
priv->adapter->currenttxskb = NULL;
/* report disconnect to upper layer */
netif_stop_queue(priv->wlan_dev.netdev);
netif_carrier_off(priv->wlan_dev.netdev);
netif_stop_queue(priv->dev);
netif_carrier_off(priv->dev);
/* reset SNR/NF/RSSI values */
memset(adapter->SNR, 0x00, sizeof(adapter->SNR));
......@@ -62,35 +61,32 @@ void libertas_mac_event_disconnected(wlan_private * priv)
adapter->nextSNRNF = 0;
adapter->numSNRNF = 0;
adapter->rxpd_rate = 0;
lbs_pr_debug(1, "Current SSID=%s, ssid length=%u\n",
adapter->curbssparams.ssid.ssid,
adapter->curbssparams.ssid.ssidlength);
lbs_pr_debug(1, "Previous SSID=%s, ssid length=%u\n",
adapter->previousssid.ssid, adapter->previousssid.ssidlength);
/* reset internal flags */
adapter->secinfo.WPAenabled = 0;
adapter->secinfo.WPA2enabled = 0;
adapter->wpa_ie_len = 0;
lbs_deb_cmd("Current SSID='%s', ssid length=%u\n",
escape_essid(adapter->curbssparams.ssid,
adapter->curbssparams.ssid_len),
adapter->curbssparams.ssid_len);
lbs_deb_cmd("Previous SSID='%s', ssid length=%u\n",
escape_essid(adapter->prev_ssid, adapter->prev_ssid_len),
adapter->prev_ssid_len);
adapter->connect_status = libertas_disconnected;
/*
* memorize the previous SSID and BSSID
* it could be used for re-assoc
*/
memcpy(&adapter->previousssid,
&adapter->curbssparams.ssid, sizeof(struct WLAN_802_11_SSID));
memcpy(adapter->previousbssid,
adapter->curbssparams.bssid, ETH_ALEN);
/* Save previous SSID and BSSID for possible reassociation */
memcpy(&adapter->prev_ssid, &adapter->curbssparams.ssid,
IW_ESSID_MAX_SIZE);
adapter->prev_ssid_len = adapter->curbssparams.ssid_len;
memcpy(adapter->prev_bssid, adapter->curbssparams.bssid, ETH_ALEN);
/* need to erase the current SSID and BSSID info */
adapter->pattemptedbssdesc = NULL;
memset(&adapter->curbssparams, 0, sizeof(adapter->curbssparams));
/* Clear out associated SSID and BSSID since connection is
* no longer valid.
*/
memset(&adapter->curbssparams.bssid, 0, ETH_ALEN);
memset(&adapter->curbssparams.ssid, 0, IW_ESSID_MAX_SIZE);
adapter->curbssparams.ssid_len = 0;
if (adapter->psstate != PS_STATE_FULL_POWER) {
/* make firmware to exit PS mode */
lbs_pr_debug(1, "Disconnected, so exit PS mode.\n");
lbs_deb_cmd("Disconnected, so exit PS mode.\n");
libertas_ps_wakeup(priv, 0);
}
}
......@@ -122,55 +118,45 @@ static void handle_mic_failureevent(wlan_private * priv, u32 event)
static int wlan_ret_reg_access(wlan_private * priv,
u16 type, struct cmd_ds_command *resp)
{
int ret = 0;
wlan_adapter *adapter = priv->adapter;
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
switch (type) {
case cmd_ret_mac_reg_access:
{
struct cmd_ds_mac_reg_access *reg;
reg =
(struct cmd_ds_mac_reg_access *)&resp->params.
macreg;
struct cmd_ds_mac_reg_access *reg = &resp->params.macreg;
adapter->offsetvalue.offset = reg->offset;
adapter->offsetvalue.value = reg->value;
adapter->offsetvalue.offset = (u32)le16_to_cpu(reg->offset);
adapter->offsetvalue.value = le32_to_cpu(reg->value);
break;
}
case cmd_ret_bbp_reg_access:
{
struct cmd_ds_bbp_reg_access *reg;
reg =
(struct cmd_ds_bbp_reg_access *)&resp->params.
bbpreg;
struct cmd_ds_bbp_reg_access *reg = &resp->params.bbpreg;
adapter->offsetvalue.offset = reg->offset;
adapter->offsetvalue.offset = (u32)le16_to_cpu(reg->offset);
adapter->offsetvalue.value = reg->value;
break;
}
case cmd_ret_rf_reg_access:
{
struct cmd_ds_rf_reg_access *reg;
reg =
(struct cmd_ds_rf_reg_access *)&resp->params.
rfreg;
struct cmd_ds_rf_reg_access *reg = &resp->params.rfreg;
adapter->offsetvalue.offset = reg->offset;
adapter->offsetvalue.offset = (u32)le16_to_cpu(reg->offset);
adapter->offsetvalue.value = reg->value;
break;
}
default:
LEAVE();
return -1;
ret = -1;
}
LEAVE();
return 0;
lbs_deb_enter_args(LBS_DEB_CMD, "ret %d", ret);
return ret;
}
static int wlan_ret_get_hw_spec(wlan_private * priv,
......@@ -181,19 +167,20 @@ static int wlan_ret_get_hw_spec(wlan_private * priv,
wlan_adapter *adapter = priv->adapter;
int ret = 0;
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
adapter->fwcapinfo = le32_to_cpu(hwspec->fwcapinfo);
adapter->fwreleasenumber = hwspec->fwreleasenumber;
memcpy(adapter->fwreleasenumber, hwspec->fwreleasenumber, 4);
lbs_pr_debug(1, "GET_HW_SPEC: FWReleaseVersion- 0x%X\n",
adapter->fwreleasenumber);
lbs_pr_debug(1, "GET_HW_SPEC: Permanent addr- %2x:%2x:%2x:%2x:%2x:%2x\n",
lbs_deb_cmd("GET_HW_SPEC: FWReleaseVersion- %u.%u.%u.p%u\n",
adapter->fwreleasenumber[2], adapter->fwreleasenumber[1],
adapter->fwreleasenumber[0], adapter->fwreleasenumber[3]);
lbs_deb_cmd("GET_HW_SPEC: Permanent addr- %2x:%2x:%2x:%2x:%2x:%2x\n",
hwspec->permanentaddr[0], hwspec->permanentaddr[1],
hwspec->permanentaddr[2], hwspec->permanentaddr[3],
hwspec->permanentaddr[4], hwspec->permanentaddr[5]);
lbs_pr_debug(1, "GET_HW_SPEC: hwifversion=0x%X version=0x%X\n",
lbs_deb_cmd("GET_HW_SPEC: hwifversion=0x%X version=0x%X\n",
hwspec->hwifversion, hwspec->version);
adapter->regioncode = le16_to_cpu(hwspec->regioncode);
......@@ -210,16 +197,14 @@ static int wlan_ret_get_hw_spec(wlan_private * priv,
if (i >= MRVDRV_MAX_REGION_CODE) {
adapter->regioncode = 0x10;
adapter->regiontableindex = 0;
lbs_pr_info(
"unidentified region code, use the default (USA)\n");
lbs_pr_info("unidentified region code; using the default (USA)\n");
}
if (adapter->current_addr[0] == 0xff) {
memmove(adapter->current_addr, hwspec->permanentaddr,
ETH_ALEN);
}
if (adapter->current_addr[0] == 0xff)
memmove(adapter->current_addr, hwspec->permanentaddr, ETH_ALEN);
memcpy(priv->wlan_dev.netdev->dev_addr, adapter->current_addr, ETH_ALEN);
memcpy(priv->dev->dev_addr, adapter->current_addr, ETH_ALEN);
if (priv->mesh_dev)
memcpy(priv->mesh_dev->dev_addr, adapter->current_addr, ETH_ALEN);
if (libertas_set_regiontable(priv, adapter->regioncode, 0)) {
......@@ -232,8 +217,8 @@ static int wlan_ret_get_hw_spec(wlan_private * priv,
goto done;
}
done:
LEAVE();
done:
lbs_deb_enter_args(LBS_DEB_CMD, "ret %d", ret);
return ret;
}
......@@ -243,19 +228,21 @@ static int wlan_ret_802_11_sleep_params(wlan_private * priv,
struct cmd_ds_802_11_sleep_params *sp = &resp->params.sleep_params;
wlan_adapter *adapter = priv->adapter;
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
lbs_deb_cmd("error=%x offset=%x stabletime=%x calcontrol=%x\n"
" extsleepclk=%x\n", le16_to_cpu(sp->error),
le16_to_cpu(sp->offset), le16_to_cpu(sp->stabletime),
sp->calcontrol, sp->externalsleepclk);
lbs_pr_debug(1, "error=%x offset=%x stabletime=%x calcontrol=%x\n"
" extsleepclk=%x\n", sp->error, sp->offset,
sp->stabletime, sp->calcontrol, sp->externalsleepclk);
adapter->sp.sp_error = le16_to_cpu(sp->error);
adapter->sp.sp_offset = le16_to_cpu(sp->offset);
adapter->sp.sp_stabletime = le16_to_cpu(sp->stabletime);
adapter->sp.sp_calcontrol = le16_to_cpu(sp->calcontrol);
adapter->sp.sp_extsleepclk = le16_to_cpu(sp->externalsleepclk);
adapter->sp.sp_calcontrol = sp->calcontrol;
adapter->sp.sp_extsleepclk = sp->externalsleepclk;
adapter->sp.sp_reserved = le16_to_cpu(sp->reserved);
LEAVE();
lbs_deb_enter(LBS_DEB_CMD);
return 0;
}
......@@ -281,34 +268,30 @@ static int wlan_ret_802_11_snmp_mib(wlan_private * priv,
u16 oid = le16_to_cpu(smib->oid);
u16 querytype = le16_to_cpu(smib->querytype);
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
lbs_pr_debug(1, "SNMP_RESP: value of the oid = %x, querytype=%x\n", oid,
lbs_deb_cmd("SNMP_RESP: value of the oid = %x, querytype=%x\n", oid,
querytype);
lbs_pr_debug(1, "SNMP_RESP: Buf size = %x\n",
le16_to_cpu(smib->bufsize));
lbs_deb_cmd("SNMP_RESP: Buf size = %x\n", le16_to_cpu(smib->bufsize));
if (querytype == cmd_act_get) {
switch (oid) {
case fragthresh_i:
priv->adapter->fragthsd =
le16_to_cpu(*
((unsigned short *)(smib->value)));
lbs_pr_debug(1, "SNMP_RESP: fragthsd =%u\n",
le16_to_cpu(*((__le16 *)(smib->value)));
lbs_deb_cmd("SNMP_RESP: fragthsd =%u\n",
priv->adapter->fragthsd);
break;
case rtsthresh_i:
priv->adapter->rtsthsd =
le16_to_cpu(*
((unsigned short *)(smib->value)));
lbs_pr_debug(1, "SNMP_RESP: rtsthsd =%u\n",
le16_to_cpu(*((__le16 *)(smib->value)));
lbs_deb_cmd("SNMP_RESP: rtsthsd =%u\n",
priv->adapter->rtsthsd);
break;
case short_retrylim_i:
priv->adapter->txretrycount =
le16_to_cpu(*
((unsigned short *)(smib->value)));
lbs_pr_debug(1, "SNMP_RESP: txretrycount =%u\n",
le16_to_cpu(*((__le16 *)(smib->value)));
lbs_deb_cmd("SNMP_RESP: txretrycount =%u\n",
priv->adapter->rtsthsd);
break;
default:
......@@ -316,7 +299,7 @@ static int wlan_ret_802_11_snmp_mib(wlan_private * priv,
}
}
LEAVE();
lbs_deb_enter(LBS_DEB_CMD);
return 0;
}
......@@ -328,7 +311,7 @@ static int wlan_ret_802_11_key_material(wlan_private * priv,
wlan_adapter *adapter = priv->adapter;
u16 action = le16_to_cpu(pkeymaterial->action);
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
/* Copy the returned key to driver private data */
if (action == cmd_act_get) {
......@@ -371,7 +354,7 @@ static int wlan_ret_802_11_key_material(wlan_private * priv,
}
}
LEAVE();
lbs_deb_enter(LBS_DEB_CMD);
return 0;
}
......@@ -381,11 +364,11 @@ static int wlan_ret_802_11_mac_address(wlan_private * priv,
struct cmd_ds_802_11_mac_address *macadd = &resp->params.macadd;
wlan_adapter *adapter = priv->adapter;
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
memcpy(adapter->current_addr, macadd->macadd, ETH_ALEN);
LEAVE();
lbs_deb_enter(LBS_DEB_CMD);
return 0;
}
......@@ -395,13 +378,13 @@ static int wlan_ret_802_11_rf_tx_power(wlan_private * priv,
struct cmd_ds_802_11_rf_tx_power *rtp = &resp->params.txp;
wlan_adapter *adapter = priv->adapter;
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
adapter->txpowerlevel = le16_to_cpu(rtp->currentlevel);
lbs_pr_debug(1, "Current TxPower Level = %d\n", adapter->txpowerlevel);
lbs_deb_cmd("Current TxPower Level = %d\n", adapter->txpowerlevel);
LEAVE();
lbs_deb_enter(LBS_DEB_CMD);
return 0;
}
......@@ -413,14 +396,12 @@ static int wlan_ret_802_11_rf_antenna(wlan_private * priv,
u16 action = le16_to_cpu(pAntenna->action);
if (action == cmd_act_get_rx)
adapter->rxantennamode =
le16_to_cpu(pAntenna->antennamode);
adapter->rxantennamode = le16_to_cpu(pAntenna->antennamode);
if (action == cmd_act_get_tx)
adapter->txantennamode =
le16_to_cpu(pAntenna->antennamode);
adapter->txantennamode = le16_to_cpu(pAntenna->antennamode);
lbs_pr_debug(1, "RF_ANT_RESP: action = 0x%x, mode = 0x%04x\n",
lbs_deb_cmd("RF_ANT_RESP: action = 0x%x, mode = 0x%04x\n",
action, le16_to_cpu(pAntenna->antennamode));
return 0;
......@@ -429,19 +410,17 @@ static int wlan_ret_802_11_rf_antenna(wlan_private * priv,
static int wlan_ret_802_11_rate_adapt_rateset(wlan_private * priv,
struct cmd_ds_command *resp)
{
struct cmd_ds_802_11_rate_adapt_rateset *rates =
&resp->params.rateset;
struct cmd_ds_802_11_rate_adapt_rateset *rates = &resp->params.rateset;
wlan_adapter *adapter = priv->adapter;
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
if (rates->action == cmd_act_get) {
adapter->enablehwauto = rates->enablehwauto;
adapter->ratebitmap = rates->bitmap;
adapter->enablehwauto = le16_to_cpu(rates->enablehwauto);
adapter->ratebitmap = le16_to_cpu(rates->bitmap);
}
LEAVE();
lbs_deb_enter(LBS_DEB_CMD);
return 0;
}
......@@ -452,43 +431,42 @@ static int wlan_ret_802_11_data_rate(wlan_private * priv,
wlan_adapter *adapter = priv->adapter;
u8 dot11datarate;
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
lbs_dbg_hex("DATA_RATE_RESP: data_rate- ",
(u8 *) pdatarate, sizeof(struct cmd_ds_802_11_data_rate));
dot11datarate = pdatarate->datarate[0];
if (pdatarate->action == cmd_act_get_tx_rate) {
if (pdatarate->action == cpu_to_le16(cmd_act_get_tx_rate)) {
memcpy(adapter->libertas_supported_rates, pdatarate->datarate,
sizeof(adapter->libertas_supported_rates));
}
adapter->datarate = libertas_index_to_data_rate(dot11datarate);
LEAVE();
lbs_deb_enter(LBS_DEB_CMD);
return 0;
}
static int wlan_ret_802_11_rf_channel(wlan_private * priv,
struct cmd_ds_command *resp)
{
struct cmd_ds_802_11_rf_channel *rfchannel =
&resp->params.rfchannel;
struct cmd_ds_802_11_rf_channel *rfchannel = &resp->params.rfchannel;
wlan_adapter *adapter = priv->adapter;
u16 action = le16_to_cpu(rfchannel->action);
u16 newchannel = le16_to_cpu(rfchannel->currentchannel);
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
if (action == cmd_opt_802_11_rf_channel_get
&& adapter->curbssparams.channel != newchannel) {
lbs_pr_debug(1, "channel Switch: %d to %d\n",
lbs_deb_cmd("channel Switch: %d to %d\n",
adapter->curbssparams.channel, newchannel);
/* Update the channel again */
adapter->curbssparams.channel = newchannel;
}
LEAVE();
lbs_deb_enter(LBS_DEB_CMD);
return 0;
}
......@@ -500,12 +478,10 @@ static int wlan_ret_802_11_rssi(wlan_private * priv,
/* store the non average value */
adapter->SNR[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->SNR);
adapter->NF[TYPE_BEACON][TYPE_NOAVG] =
le16_to_cpu(rssirsp->noisefloor);
adapter->NF[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->noisefloor);
adapter->SNR[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgSNR);
adapter->NF[TYPE_BEACON][TYPE_AVG] =
le16_to_cpu(rssirsp->avgnoisefloor);
adapter->NF[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgnoisefloor);
adapter->RSSI[TYPE_BEACON][TYPE_NOAVG] =
CAL_RSSI(adapter->SNR[TYPE_BEACON][TYPE_NOAVG],
......@@ -515,7 +491,7 @@ static int wlan_ret_802_11_rssi(wlan_private * priv,
CAL_RSSI(adapter->SNR[TYPE_BEACON][TYPE_AVG] / AVG_SCALE,
adapter->NF[TYPE_BEACON][TYPE_AVG] / AVG_SCALE);
lbs_pr_debug(1, "Beacon RSSI value = 0x%x\n",
lbs_deb_cmd("Beacon RSSI value = 0x%x\n",
adapter->RSSI[TYPE_BEACON][TYPE_AVG]);
return 0;
......@@ -528,11 +504,11 @@ static int wlan_ret_802_11_eeprom_access(wlan_private * priv,
struct wlan_ioctl_regrdwr *pbuf;
pbuf = (struct wlan_ioctl_regrdwr *) adapter->prdeeprom;
lbs_pr_debug(1, "eeprom read len=%x\n",
lbs_deb_cmd("eeprom read len=%x\n",
le16_to_cpu(resp->params.rdeeprom.bytecount));
if (pbuf->NOB < le16_to_cpu(resp->params.rdeeprom.bytecount)) {
pbuf->NOB = 0;
lbs_pr_debug(1, "eeprom read return length is too big\n");
lbs_deb_cmd("eeprom read return length is too big\n");
return -1;
}
pbuf->NOB = le16_to_cpu(resp->params.rdeeprom.bytecount);
......@@ -549,17 +525,15 @@ static int wlan_ret_802_11_eeprom_access(wlan_private * priv,
static int wlan_ret_get_log(wlan_private * priv,
struct cmd_ds_command *resp)
{
struct cmd_ds_802_11_get_log *logmessage =
(struct cmd_ds_802_11_get_log *)&resp->params.glog;
struct cmd_ds_802_11_get_log *logmessage = &resp->params.glog;
wlan_adapter *adapter = priv->adapter;
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
/* TODO Convert it to Big Endian before copy */
memcpy(&adapter->logmsg, logmessage,
sizeof(struct cmd_ds_802_11_get_log));
/* Stored little-endian */
memcpy(&adapter->logmsg, logmessage, sizeof(struct cmd_ds_802_11_get_log));
LEAVE();
lbs_deb_enter(LBS_DEB_CMD);
return 0;
}
......@@ -620,8 +594,7 @@ static inline int handle_cmd_response(u16 respcmd,
case cmd_ret_802_11_set_afc:
case cmd_ret_802_11_get_afc:
spin_lock_irqsave(&adapter->driver_lock, flags);
memmove(adapter->cur_cmd->pdata_buf,
&resp->params.afc,
memmove(adapter->cur_cmd->pdata_buf, &resp->params.afc,
sizeof(struct cmd_ds_802_11_afc));
spin_unlock_irqrestore(&adapter->driver_lock, flags);
......@@ -663,7 +636,7 @@ static inline int handle_cmd_response(u16 respcmd,
break;
case cmd_ret_802_11_key_material:
lbs_pr_debug(1, "CMD_RESP: KEY_MATERIAL command response\n");
lbs_deb_cmd("CMD_RESP: KEY_MATERIAL command response\n");
ret = wlan_ret_802_11_key_material(priv, resp);
break;
......@@ -687,22 +660,19 @@ static inline int handle_cmd_response(u16 respcmd,
case cmd_ret_802_11_tpc_cfg:
spin_lock_irqsave(&adapter->driver_lock, flags);
memmove(adapter->cur_cmd->pdata_buf,
&resp->params.tpccfg,
memmove(adapter->cur_cmd->pdata_buf, &resp->params.tpccfg,
sizeof(struct cmd_ds_802_11_tpc_cfg));
spin_unlock_irqrestore(&adapter->driver_lock, flags);
break;
case cmd_ret_802_11_led_gpio_ctrl:
spin_lock_irqsave(&adapter->driver_lock, flags);
memmove(adapter->cur_cmd->pdata_buf,
&resp->params.ledgpio,
memmove(adapter->cur_cmd->pdata_buf, &resp->params.ledgpio,
sizeof(struct cmd_ds_802_11_led_ctrl));
spin_unlock_irqrestore(&adapter->driver_lock, flags);
break;
case cmd_ret_802_11_pwr_cfg:
spin_lock_irqsave(&adapter->driver_lock, flags);
memmove(adapter->cur_cmd->pdata_buf,
&resp->params.pwrcfg,
memmove(adapter->cur_cmd->pdata_buf, &resp->params.pwrcfg,
sizeof(struct cmd_ds_802_11_pwr_cfg));
spin_unlock_irqrestore(&adapter->driver_lock, flags);
......@@ -724,22 +694,20 @@ static inline int handle_cmd_response(u16 respcmd,
case cmd_ret_fwt_access:
spin_lock_irqsave(&adapter->driver_lock, flags);
if (adapter->cur_cmd->pdata_buf)
memcpy(adapter->cur_cmd->pdata_buf,
&resp->params.fwt,
memcpy(adapter->cur_cmd->pdata_buf, &resp->params.fwt,
sizeof(resp->params.fwt));
spin_unlock_irqrestore(&adapter->driver_lock, flags);
break;
case cmd_ret_mesh_access:
if (adapter->cur_cmd->pdata_buf)
memcpy(adapter->cur_cmd->pdata_buf,
&resp->params.mesh,
memcpy(adapter->cur_cmd->pdata_buf, &resp->params.mesh,
sizeof(resp->params.mesh));
break;
case cmd_rte_802_11_tx_rate_query:
priv->adapter->txrate = resp->params.txrate.txrate;
break;
default:
lbs_pr_debug(1, "CMD_RESP: Unknown command response %#x\n",
lbs_deb_cmd("CMD_RESP: Unknown command response %#x\n",
resp->command);
break;
}
......@@ -755,9 +723,9 @@ int libertas_process_rx_command(wlan_private * priv)
ulong flags;
u16 result;
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
lbs_pr_debug(1, "CMD_RESP: @ %lu\n", jiffies);
lbs_deb_cmd("CMD_RESP: @ %lu\n", jiffies);
/* Now we got response from FW, cancel the command timer */
del_timer(&adapter->command_timer);
......@@ -766,7 +734,7 @@ int libertas_process_rx_command(wlan_private * priv)
spin_lock_irqsave(&adapter->driver_lock, flags);
if (!adapter->cur_cmd) {
lbs_pr_debug(1, "CMD_RESP: NULL cur_cmd=%p\n", adapter->cur_cmd);
lbs_deb_cmd("CMD_RESP: NULL cur_cmd=%p\n", adapter->cur_cmd);
ret = -1;
spin_unlock_irqrestore(&adapter->driver_lock, flags);
goto done;
......@@ -774,17 +742,17 @@ int libertas_process_rx_command(wlan_private * priv)
resp = (struct cmd_ds_command *)(adapter->cur_cmd->bufvirtualaddr);
lbs_dbg_hex("CMD_RESP:", adapter->cur_cmd->bufvirtualaddr,
priv->wlan_dev.upld_len);
priv->upld_len);
respcmd = le16_to_cpu(resp->command);
result = le16_to_cpu(resp->result);
lbs_pr_debug(1, "CMD_RESP: %x result: %d length: %d\n", respcmd,
result, priv->wlan_dev.upld_len);
lbs_deb_cmd("CMD_RESP: %x result: %d length: %d\n", respcmd,
result, priv->upld_len);
if (!(respcmd & 0x8000)) {
lbs_pr_debug(1, "Invalid response to command!");
lbs_deb_cmd("Invalid response to command!");
adapter->cur_cmd_retcode = -1;
__libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd);
adapter->nr_cmd_pending--;
......@@ -795,56 +763,52 @@ int libertas_process_rx_command(wlan_private * priv)
}
/* Store the response code to cur_cmd_retcode. */
adapter->cur_cmd_retcode = le16_to_cpu(resp->result);
adapter->cur_cmd_retcode = result;;
if (respcmd == cmd_ret_802_11_ps_mode) {
struct cmd_ds_802_11_ps_mode *psmode;
struct cmd_ds_802_11_ps_mode *psmode = &resp->params.psmode;
u16 action = le16_to_cpu(psmode->action);
psmode = &resp->params.psmode;
lbs_pr_debug(1,
lbs_deb_cmd(
"CMD_RESP: PS_MODE cmd reply result=%#x action=0x%X\n",
resp->result, psmode->action);
psmode->action = cpu_to_le16(psmode->action);
result, action);
if (result) {
lbs_pr_debug(1, "CMD_RESP: PS command failed- %#x \n",
resp->result);
if (adapter->mode == IW_MODE_ADHOC) {
lbs_deb_cmd("CMD_RESP: PS command failed- %#x \n",
result);
/*
* We should not re-try enter-ps command in
* ad-hoc mode. It takes place in
* libertas_execute_next_command().
*/
if (psmode->action == cmd_subcmd_enter_ps)
adapter->psmode =
wlan802_11powermodecam;
}
} else if (psmode->action == cmd_subcmd_enter_ps) {
if (adapter->mode == IW_MODE_ADHOC &&
action == cmd_subcmd_enter_ps)
adapter->psmode = wlan802_11powermodecam;
} else if (action == cmd_subcmd_enter_ps) {
adapter->needtowakeup = 0;
adapter->psstate = PS_STATE_AWAKE;
lbs_pr_debug(1, "CMD_RESP: Enter_PS command response\n");
lbs_deb_cmd("CMD_RESP: Enter_PS command response\n");
if (adapter->connect_status != libertas_connected) {
/*
* When Deauth Event received before Enter_PS command
* response, We need to wake up the firmware.
*/
lbs_pr_debug(1,
lbs_deb_cmd(
"Disconnected, Going to invoke libertas_ps_wakeup\n");
mutex_unlock(&adapter->lock);
spin_unlock_irqrestore(&adapter->driver_lock, flags);
mutex_unlock(&adapter->lock);
libertas_ps_wakeup(priv, 0);
mutex_lock(&adapter->lock);
spin_lock_irqsave(&adapter->driver_lock, flags);
}
} else if (psmode->action == cmd_subcmd_exit_ps) {
} else if (action == cmd_subcmd_exit_ps) {
adapter->needtowakeup = 0;
adapter->psstate = PS_STATE_FULL_POWER;
lbs_pr_debug(1, "CMD_RESP: Exit_PS command response\n");
lbs_deb_cmd("CMD_RESP: Exit_PS command response\n");
} else {
lbs_pr_debug(1, "CMD_RESP: PS- action=0x%X\n",
psmode->action);
lbs_deb_cmd("CMD_RESP: PS- action=0x%X\n", action);
}
__libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd);
......@@ -865,15 +829,15 @@ int libertas_process_rx_command(wlan_private * priv)
/* If the command is not successful, cleanup and return failure */
if ((result != 0 || !(respcmd & 0x8000))) {
lbs_pr_debug(1, "CMD_RESP: command reply %#x result=%#x\n",
resp->command, resp->result);
lbs_deb_cmd("CMD_RESP: command reply %#x result=%#x\n",
respcmd, result);
/*
* Handling errors here
*/
switch (respcmd) {
case cmd_ret_hw_spec_info:
case cmd_ret_802_11_reset:
lbs_pr_debug(1, "CMD_RESP: Reset command failed\n");
lbs_deb_cmd("CMD_RESP: Reset command failed\n");
break;
}
......@@ -903,7 +867,7 @@ int libertas_process_rx_command(wlan_private * priv)
done:
mutex_unlock(&adapter->lock);
LEAVE();
lbs_deb_enter_args(LBS_DEB_CMD, "ret %d", ret);
return ret;
}
......@@ -917,37 +881,37 @@ int libertas_process_event(wlan_private * priv)
eventcause = adapter->eventcause;
spin_unlock_irq(&adapter->driver_lock);
ENTER();
lbs_deb_enter(LBS_DEB_CMD);
lbs_pr_debug(1, "EVENT Cause %x\n", eventcause);
lbs_deb_cmd("EVENT Cause %x\n", eventcause);
switch (eventcause >> SBI_EVENT_CAUSE_SHIFT) {
case MACREG_INT_CODE_LINK_SENSED:
lbs_pr_debug(1, "EVENT: MACREG_INT_CODE_LINK_SENSED\n");
lbs_deb_cmd("EVENT: MACREG_INT_CODE_LINK_SENSED\n");
break;
case MACREG_INT_CODE_DEAUTHENTICATED:
lbs_pr_debug(1, "EVENT: Deauthenticated\n");
lbs_deb_cmd("EVENT: Deauthenticated\n");
libertas_mac_event_disconnected(priv);
break;
case MACREG_INT_CODE_DISASSOCIATED:
lbs_pr_debug(1, "EVENT: Disassociated\n");
lbs_deb_cmd("EVENT: Disassociated\n");
libertas_mac_event_disconnected(priv);
break;
case MACREG_INT_CODE_LINK_LOSE_NO_SCAN:
lbs_pr_debug(1, "EVENT: Link lost\n");
lbs_deb_cmd("EVENT: Link lost\n");
libertas_mac_event_disconnected(priv);
break;
case MACREG_INT_CODE_PS_SLEEP:
lbs_pr_debug(1, "EVENT: SLEEP\n");
lbs_pr_debug(1, "_");
lbs_deb_cmd("EVENT: SLEEP\n");
lbs_deb_cmd("_");
/* handle unexpected PS SLEEP event */
if (adapter->psstate == PS_STATE_FULL_POWER) {
lbs_pr_debug(1,
lbs_deb_cmd(
"EVENT: In FULL POWER mode - ignore PS SLEEP\n");
break;
}
......@@ -958,12 +922,12 @@ int libertas_process_event(wlan_private * priv)
break;
case MACREG_INT_CODE_PS_AWAKE:
lbs_pr_debug(1, "EVENT: AWAKE \n");
lbs_pr_debug(1, "|");
lbs_deb_cmd("EVENT: AWAKE \n");
lbs_deb_cmd("|");
/* handle unexpected PS AWAKE event */
if (adapter->psstate == PS_STATE_FULL_POWER) {
lbs_pr_debug(1,
lbs_deb_cmd(
"EVENT: In FULL POWER mode - ignore PS AWAKE\n");
break;
}
......@@ -977,18 +941,18 @@ int libertas_process_event(wlan_private * priv)
* adapter->needtowakeup will be set to FALSE
* in libertas_ps_wakeup()
*/
lbs_pr_debug(1, "Waking up...\n");
lbs_deb_cmd("Waking up...\n");
libertas_ps_wakeup(priv, 0);
}
break;
case MACREG_INT_CODE_MIC_ERR_UNICAST:
lbs_pr_debug(1, "EVENT: UNICAST MIC ERROR\n");
lbs_deb_cmd("EVENT: UNICAST MIC ERROR\n");
handle_mic_failureevent(priv, MACREG_INT_CODE_MIC_ERR_UNICAST);
break;
case MACREG_INT_CODE_MIC_ERR_MULTICAST:
lbs_pr_debug(1, "EVENT: MULTICAST MIC ERROR\n");
lbs_deb_cmd("EVENT: MULTICAST MIC ERROR\n");
handle_mic_failureevent(priv, MACREG_INT_CODE_MIC_ERR_MULTICAST);
break;
case MACREG_INT_CODE_MIB_CHANGED:
......@@ -996,7 +960,7 @@ int libertas_process_event(wlan_private * priv)
break;
case MACREG_INT_CODE_ADHOC_BCN_LOST:
lbs_pr_debug(1, "EVENT: HWAC - ADHOC BCN LOST\n");
lbs_deb_cmd("EVENT: HWAC - ADHOC BCN LOST\n");
break;
case MACREG_INT_CODE_RSSI_LOW:
......@@ -1015,6 +979,16 @@ int libertas_process_event(wlan_private * priv)
lbs_pr_alert( "EVENT: SNR_HIGH\n");
break;
case MACREG_INT_CODE_MESH_AUTO_STARTED:
lbs_pr_alert( "EVENT: MESH_AUTO_STARTED\n");
adapter->connect_status = libertas_connected ;
if (priv->mesh_open == 1) {
netif_wake_queue(priv->mesh_dev) ;
netif_carrier_on(priv->mesh_dev) ;
}
adapter->mode = IW_MODE_ADHOC ;
break;
default:
lbs_pr_alert( "EVENT: unknown event id: %#x\n",
eventcause >> SBI_EVENT_CAUSE_SHIFT);
......@@ -1024,6 +998,7 @@ int libertas_process_event(wlan_private * priv)
spin_lock_irq(&adapter->driver_lock);
adapter->eventcause = 0;
spin_unlock_irq(&adapter->driver_lock);
LEAVE();
lbs_deb_enter_args(LBS_DEB_CMD, "ret %d", ret);
return ret;
}
......@@ -4,6 +4,7 @@
#include <linux/delay.h>
#include <linux/mm.h>
#include <net/iw_handler.h>
#include "dev.h"
#include "decl.h"
#include "host.h"
......@@ -15,7 +16,9 @@ static char *szStates[] = {
"Disconnected"
};
void libertas_debug_init(wlan_private * priv, struct net_device *dev);
#ifdef PROC_DEBUG
static void libertas_debug_init(wlan_private * priv, struct net_device *dev);
#endif
static int open_file_generic(struct inode *inode, struct file *file)
{
......@@ -60,43 +63,33 @@ static ssize_t libertas_getscantable(struct file *file, char __user *userbuf,
int numscansdone = 0, res;
unsigned long addr = get_zeroed_page(GFP_KERNEL);
char *buf = (char *)addr;
struct bss_descriptor * iter_bss;
pos += snprintf(buf+pos, len-pos,
"---------------------------------------");
pos += snprintf(buf+pos, len-pos,
"---------------------------------------\n");
pos += snprintf(buf+pos, len-pos,
"# | ch | ss | bssid | cap | TSF | Qual | SSID \n");
pos += snprintf(buf+pos, len-pos,
"---------------------------------------");
pos += snprintf(buf+pos, len-pos,
"---------------------------------------\n");
while (numscansdone < priv->adapter->numinscantable) {
struct bss_descriptor *pbssinfo;
mutex_lock(&priv->adapter->lock);
list_for_each_entry (iter_bss, &priv->adapter->network_list, list) {
u16 cap;
pbssinfo = &priv->adapter->scantable[numscansdone];
memcpy(&cap, &pbssinfo->cap, sizeof(cap));
memcpy(&cap, &iter_bss->cap, sizeof(cap));
pos += snprintf(buf+pos, len-pos,
"%02u| %03d | %03ld | %02x:%02x:%02x:%02x:%02x:%02x |",
numscansdone, pbssinfo->channel, pbssinfo->rssi,
pbssinfo->macaddress[0], pbssinfo->macaddress[1],
pbssinfo->macaddress[2], pbssinfo->macaddress[3],
pbssinfo->macaddress[4], pbssinfo->macaddress[5]);
"%02u| %03d | %03ld | " MAC_FMT " |",
numscansdone, iter_bss->channel, iter_bss->rssi,
MAC_ARG(iter_bss->bssid));
pos += snprintf(buf+pos, len-pos, " %04x-", cap);
pos += snprintf(buf+pos, len-pos, "%c%c%c |",
pbssinfo->cap.ibss ? 'A' : 'I',
pbssinfo->cap.privacy ? 'P' : ' ',
pbssinfo->cap.spectrummgmt ? 'S' : ' ');
pos += snprintf(buf+pos, len-pos, " %08llx |", pbssinfo->networktsf);
pos += snprintf(buf+pos, len-pos, " %d |",
SCAN_RSSI(priv->adapter->scantable[numscansdone].rssi));
pos += snprintf(buf+pos, len-pos, " %s\n", pbssinfo->ssid.ssid);
iter_bss->cap.ibss ? 'A' : 'I',
iter_bss->cap.privacy ? 'P' : ' ',
iter_bss->cap.spectrummgmt ? 'S' : ' ');
pos += snprintf(buf+pos, len-pos, " %08llx |", iter_bss->networktsf);
pos += snprintf(buf+pos, len-pos, " %d |", SCAN_RSSI(iter_bss->rssi));
pos += snprintf(buf+pos, len-pos, " %s\n",
escape_essid(iter_bss->ssid, iter_bss->ssid_len));
numscansdone++;
}
mutex_unlock(&priv->adapter->lock);
res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
......@@ -111,7 +104,6 @@ static ssize_t libertas_sleepparams_write(struct file *file,
wlan_private *priv = file->private_data;
ssize_t buf_size, res;
int p1, p2, p3, p4, p5, p6;
struct sleep_params sp;
unsigned long addr = get_zeroed_page(GFP_KERNEL);
char *buf = (char *)addr;
......@@ -125,14 +117,12 @@ static ssize_t libertas_sleepparams_write(struct file *file,
res = -EFAULT;
goto out_unlock;
}
sp.sp_error = p1;
sp.sp_offset = p2;
sp.sp_stabletime = p3;
sp.sp_calcontrol = p4;
sp.sp_extsleepclk = p5;
sp.sp_reserved = p6;
memcpy(&priv->adapter->sp, &sp, sizeof(struct sleep_params));
priv->adapter->sp.sp_error = p1;
priv->adapter->sp.sp_offset = p2;
priv->adapter->sp.sp_stabletime = p3;
priv->adapter->sp.sp_calcontrol = p4;
priv->adapter->sp.sp_extsleepclk = p5;
priv->adapter->sp.sp_reserved = p6;
res = libertas_prepare_and_send_command(priv,
cmd_802_11_sleep_params,
......@@ -185,7 +175,6 @@ static ssize_t libertas_extscan(struct file *file, const char __user *userbuf,
{
wlan_private *priv = file->private_data;
ssize_t res, buf_size;
struct WLAN_802_11_SSID extscan_ssid;
union iwreq_data wrqu;
unsigned long addr = get_zeroed_page(GFP_KERNEL);
char *buf = (char *)addr;
......@@ -196,13 +185,10 @@ static ssize_t libertas_extscan(struct file *file, const char __user *userbuf,
goto out_unlock;
}
memcpy(&extscan_ssid.ssid, buf, strlen(buf)-1);
extscan_ssid.ssidlength = strlen(buf)-1;
libertas_send_specific_SSID_scan(priv, &extscan_ssid, 1);
libertas_send_specific_ssid_scan(priv, buf, strlen(buf)-1, 0);
memset(&wrqu, 0, sizeof(union iwreq_data));
wireless_send_event(priv->wlan_dev.netdev, SIOCGIWSCAN, &wrqu, NULL);
wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
out_unlock:
free_page(addr);
......@@ -251,16 +237,13 @@ static void libertas_parse_bssid(char *buf, size_t count,
{
char *hold;
unsigned int mac[ETH_ALEN];
int i;
hold = strstr(buf, "bssid=");
if (!hold)
return;
hold += 6;
sscanf(hold, "%2x:%2x:%2x:%2x:%2x:%2x", mac, mac+1, mac+2, mac+3,
mac+4, mac+5);
for(i=0;i<ETH_ALEN;i++)
scan_cfg->specificBSSID[i] = mac[i];
sscanf(hold, MAC_FMT, mac, mac+1, mac+2, mac+3, mac+4, mac+5);
memcpy(scan_cfg->bssid, mac, ETH_ALEN);
}
static void libertas_parse_ssid(char *buf, size_t count,
......@@ -278,28 +261,26 @@ static void libertas_parse_ssid(char *buf, size_t count,
end = buf + count - 1;
size = min((size_t)IW_ESSID_MAX_SIZE, (size_t) (end - hold));
strncpy(scan_cfg->specificSSID, hold, size);
strncpy(scan_cfg->ssid, hold, size);
return;
}
static void libertas_parse_keep(char *buf, size_t count,
struct wlan_ioctl_user_scan_cfg *scan_cfg)
static int libertas_parse_clear(char *buf, size_t count, const char *tag)
{
char *hold;
int val;
hold = strstr(buf, "keep=");
hold = strstr(buf, tag);
if (!hold)
return;
hold += 5;
return 0;
hold += strlen(tag);
sscanf(hold, "%d", &val);
if (val != 0)
val = 1;
scan_cfg->keeppreviousscan = val;
return;
return val;
}
static int libertas_parse_dur(char *buf, size_t count,
......@@ -382,17 +363,18 @@ static ssize_t libertas_setuserscan(struct file *file,
dur = libertas_parse_dur(buf, count, scan_cfg);
libertas_parse_chan(buf, count, scan_cfg, dur);
libertas_parse_bssid(buf, count, scan_cfg);
scan_cfg->clear_bssid = libertas_parse_clear(buf, count, "clear_bssid=");
libertas_parse_ssid(buf, count, scan_cfg);
libertas_parse_keep(buf, count, scan_cfg);
scan_cfg->clear_ssid = libertas_parse_clear(buf, count, "clear_ssid=");
libertas_parse_probes(buf, count, scan_cfg);
libertas_parse_type(buf, count, scan_cfg);
wlan_scan_networks(priv, scan_cfg);
wlan_scan_networks(priv, scan_cfg, 1);
wait_event_interruptible(priv->adapter->cmd_pending,
!priv->adapter->nr_cmd_pending);
memset(&wrqu, 0x00, sizeof(union iwreq_data));
wireless_send_event(priv->wlan_dev.netdev, SIOCGIWSCAN, &wrqu, NULL);
wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
out_unlock:
free_page(addr);
......@@ -407,11 +389,11 @@ static int libertas_event_initcmd(wlan_private *priv, void **response_buf,
u16 wait_option = cmd_option_waitforrsp;
if (!(*cmdnode = libertas_get_free_cmd_ctrl_node(priv))) {
lbs_pr_debug(1, "failed libertas_get_free_cmd_ctrl_node\n");
lbs_deb_debugfs("failed libertas_get_free_cmd_ctrl_node\n");
return -ENOMEM;
}
if (!(*response_buf = kmalloc(3000, GFP_KERNEL))) {
lbs_pr_debug(1, "failed to allocate response buffer!\n");
lbs_deb_debugfs("failed to allocate response buffer!\n");
return -ENOMEM;
}
libertas_set_cmd_ctrl_node(priv, *cmdnode, 0, wait_option, NULL);
......@@ -420,8 +402,8 @@ static int libertas_event_initcmd(wlan_private *priv, void **response_buf,
(*cmdnode)->cmdflags |= CMD_F_HOSTCMD;
(*cmdnode)->cmdwaitqwoken = 0;
*cmd = (struct cmd_ds_command *)(*cmdnode)->bufvirtualaddr;
(*cmd)->command = cmd_802_11_subscribe_event;
(*cmd)->seqnum = ++priv->adapter->seqnum;
(*cmd)->command = cpu_to_le16(cmd_802_11_subscribe_event);
(*cmd)->seqnum = cpu_to_le16(++priv->adapter->seqnum);
(*cmd)->result = 0;
return 0;
}
......@@ -447,9 +429,8 @@ static ssize_t libertas_lowrssi_read(struct file *file, char __user *userbuf,
}
event = &pcmdptr->params.subscribe_event;
event->action = cmd_act_get;
pcmdptr->size =
cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
event->action = cpu_to_le16(cmd_act_get);
pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN);
libertas_queue_cmd(adapter, pcmdnode, 1);
wake_up_interruptible(&priv->mainthread.waitq);
......@@ -459,14 +440,14 @@ static ssize_t libertas_lowrssi_read(struct file *file, char __user *userbuf,
pcmdptr = response_buf;
if (pcmdptr->result) {
lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
pcmdptr->result);
lbs_pr_err("%s: fail, result=%d\n", __func__,
le16_to_cpu(pcmdptr->result));
kfree(response_buf);
free_page(addr);
return 0;
}
if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) {
lbs_pr_err("command response incorrect!\n");
kfree(response_buf);
free_page(addr);
......@@ -474,17 +455,17 @@ static ssize_t libertas_lowrssi_read(struct file *file, char __user *userbuf,
}
cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
while (cmd_len < pcmdptr->size) {
struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
switch(header->type) {
event = (void *)(response_buf + S_DS_GEN);
while (cmd_len < le16_to_cpu(pcmdptr->size)) {
struct mrvlietypesheader *header = (void *)(response_buf + cmd_len);
switch (header->type) {
struct mrvlietypes_rssithreshold *Lowrssi;
case TLV_TYPE_RSSI_LOW:
Lowrssi = (struct mrvlietypes_rssithreshold *)(response_buf + cmd_len);
case __constant_cpu_to_le16(TLV_TYPE_RSSI_LOW):
Lowrssi = (void *)(response_buf + cmd_len);
pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
Lowrssi->rssivalue,
Lowrssi->rssifreq,
(event->events & 0x0001)?1:0);
(event->events & cpu_to_le16(0x0001))?1:0);
default:
cmd_len += sizeof(struct mrvlietypes_snrthreshold);
break;
......@@ -512,9 +493,8 @@ static u16 libertas_get_events_bitmap(wlan_private *priv)
return res;
event = &pcmdptr->params.subscribe_event;
event->action = cmd_act_get;
pcmdptr->size =
cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
event->action = cpu_to_le16(cmd_act_get);
pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN);
libertas_queue_cmd(adapter, pcmdnode, 1);
wake_up_interruptible(&priv->mainthread.waitq);
......@@ -525,8 +505,8 @@ static u16 libertas_get_events_bitmap(wlan_private *priv)
pcmdptr = response_buf;
if (pcmdptr->result) {
lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
pcmdptr->result);
lbs_pr_err("%s: fail, result=%d\n", __func__,
le16_to_cpu(pcmdptr->result));
kfree(response_buf);
return 0;
}
......@@ -538,7 +518,7 @@ static u16 libertas_get_events_bitmap(wlan_private *priv)
}
event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
event_bitmap = event->events;
event_bitmap = le16_to_cpu(event->events);
kfree(response_buf);
return event_bitmap;
}
......@@ -579,7 +559,7 @@ static ssize_t libertas_lowrssi_write(struct file *file,
goto out_unlock;
event = &pcmdptr->params.subscribe_event;
event->action = cmd_act_set;
event->action = cpu_to_le16(cmd_act_set);
pcmdptr->size = cpu_to_le16(S_DS_GEN +
sizeof(struct cmd_ds_802_11_subscribe_event) +
sizeof(struct mrvlietypes_rssithreshold));
......@@ -588,11 +568,11 @@ static ssize_t libertas_lowrssi_write(struct file *file,
ptr = (u8*) pcmdptr+cmd_len;
rssi_threshold = (struct mrvlietypes_rssithreshold *)(ptr);
rssi_threshold->header.type = cpu_to_le16(0x0104);
rssi_threshold->header.len = 2;
rssi_threshold->rssivalue = cpu_to_le16(value);
rssi_threshold->rssifreq = cpu_to_le16(freq);
rssi_threshold->header.len = cpu_to_le16(2);
rssi_threshold->rssivalue = value;
rssi_threshold->rssifreq = freq;
event_bitmap |= subscribed ? 0x0001 : 0x0;
event->events = event_bitmap;
event->events = cpu_to_le16(event_bitmap);
libertas_queue_cmd(adapter, pcmdnode, 1);
wake_up_interruptible(&priv->mainthread.waitq);
......@@ -604,14 +584,14 @@ static ssize_t libertas_lowrssi_write(struct file *file,
pcmdptr = response_buf;
if (pcmdptr->result) {
lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
pcmdptr->result);
lbs_pr_err("%s: fail, result=%d\n", __func__,
le16_to_cpu(pcmdptr->result));
kfree(response_buf);
free_page(addr);
return 0;
}
if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) {
lbs_pr_err("command response incorrect!\n");
kfree(response_buf);
free_page(addr);
......@@ -645,9 +625,8 @@ static ssize_t libertas_lowsnr_read(struct file *file, char __user *userbuf,
}
event = &pcmdptr->params.subscribe_event;
event->action = cmd_act_get;
pcmdptr->size =
cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
event->action = cpu_to_le16(cmd_act_get);
pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN);
libertas_queue_cmd(adapter, pcmdnode, 1);
wake_up_interruptible(&priv->mainthread.waitq);
......@@ -658,14 +637,14 @@ static ssize_t libertas_lowsnr_read(struct file *file, char __user *userbuf,
pcmdptr = response_buf;
if (pcmdptr->result) {
lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
pcmdptr->result);
lbs_pr_err("%s: fail, result=%d\n", __func__,
le16_to_cpu(pcmdptr->result));
kfree(response_buf);
free_page(addr);
return 0;
}
if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) {
lbs_pr_err("command response incorrect!\n");
kfree(response_buf);
free_page(addr);
......@@ -673,17 +652,17 @@ static ssize_t libertas_lowsnr_read(struct file *file, char __user *userbuf,
}
cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
while (cmd_len < pcmdptr->size) {
struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
switch(header->type) {
event = (void *)(response_buf + S_DS_GEN);
while (cmd_len < le16_to_cpu(pcmdptr->size)) {
struct mrvlietypesheader *header = (void *)(response_buf + cmd_len);
switch (header->type) {
struct mrvlietypes_snrthreshold *LowSnr;
case TLV_TYPE_SNR_LOW:
LowSnr = (struct mrvlietypes_snrthreshold *)(response_buf + cmd_len);
case __constant_cpu_to_le16(TLV_TYPE_SNR_LOW):
LowSnr = (void *)(response_buf + cmd_len);
pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
LowSnr->snrvalue,
LowSnr->snrfreq,
(event->events & 0x0002)?1:0);
(event->events & cpu_to_le16(0x0002))?1:0);
default:
cmd_len += sizeof(struct mrvlietypes_snrthreshold);
break;
......@@ -733,7 +712,7 @@ static ssize_t libertas_lowsnr_write(struct file *file,
goto out_unlock;
event = &pcmdptr->params.subscribe_event;
event->action = cmd_act_set;
event->action = cpu_to_le16(cmd_act_set);
pcmdptr->size = cpu_to_le16(S_DS_GEN +
sizeof(struct cmd_ds_802_11_subscribe_event) +
sizeof(struct mrvlietypes_snrthreshold));
......@@ -741,11 +720,11 @@ static ssize_t libertas_lowsnr_write(struct file *file,
ptr = (u8*) pcmdptr+cmd_len;
snr_threshold = (struct mrvlietypes_snrthreshold *)(ptr);
snr_threshold->header.type = cpu_to_le16(TLV_TYPE_SNR_LOW);
snr_threshold->header.len = 2;
snr_threshold->snrvalue = cpu_to_le16(value);
snr_threshold->snrfreq = cpu_to_le16(freq);
snr_threshold->header.len = cpu_to_le16(2);
snr_threshold->snrvalue = value;
snr_threshold->snrfreq = freq;
event_bitmap |= subscribed ? 0x0002 : 0x0;
event->events = event_bitmap;
event->events = cpu_to_le16(event_bitmap);
libertas_queue_cmd(adapter, pcmdnode, 1);
wake_up_interruptible(&priv->mainthread.waitq);
......@@ -757,14 +736,14 @@ static ssize_t libertas_lowsnr_write(struct file *file,
pcmdptr = response_buf;
if (pcmdptr->result) {
lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
pcmdptr->result);
lbs_pr_err("%s: fail, result=%d\n", __func__,
le16_to_cpu(pcmdptr->result));
kfree(response_buf);
free_page(addr);
return 0;
}
if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) {
lbs_pr_err("command response incorrect!\n");
kfree(response_buf);
free_page(addr);
......@@ -799,9 +778,8 @@ static ssize_t libertas_failcount_read(struct file *file, char __user *userbuf,
}
event = &pcmdptr->params.subscribe_event;
event->action = cmd_act_get;
pcmdptr->size =
cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
event->action = cpu_to_le16(cmd_act_get);
pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN);
libertas_queue_cmd(adapter, pcmdnode, 1);
wake_up_interruptible(&priv->mainthread.waitq);
......@@ -812,14 +790,14 @@ static ssize_t libertas_failcount_read(struct file *file, char __user *userbuf,
pcmdptr = response_buf;
if (pcmdptr->result) {
lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
pcmdptr->result);
lbs_pr_err("%s: fail, result=%d\n", __func__,
le16_to_cpu(pcmdptr->result));
kfree(response_buf);
free_page(addr);
return 0;
}
if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) {
lbs_pr_err("command response incorrect!\n");
kfree(response_buf);
free_page(addr);
......@@ -827,17 +805,17 @@ static ssize_t libertas_failcount_read(struct file *file, char __user *userbuf,
}
cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
while (cmd_len < pcmdptr->size) {
struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
switch(header->type) {
event = (void *)(response_buf + S_DS_GEN);
while (cmd_len < le16_to_cpu(pcmdptr->size)) {
struct mrvlietypesheader *header = (void *)(response_buf + cmd_len);
switch (header->type) {
struct mrvlietypes_failurecount *failcount;
case TLV_TYPE_FAILCOUNT:
failcount = (struct mrvlietypes_failurecount *)(response_buf + cmd_len);
case __constant_cpu_to_le16(TLV_TYPE_FAILCOUNT):
failcount = (void *)(response_buf + cmd_len);
pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
failcount->failvalue,
failcount->Failfreq,
(event->events & 0x0004)?1:0);
(event->events & cpu_to_le16(0x0004))?1:0);
default:
cmd_len += sizeof(struct mrvlietypes_failurecount);
break;
......@@ -886,7 +864,7 @@ static ssize_t libertas_failcount_write(struct file *file,
goto out_unlock;
event = &pcmdptr->params.subscribe_event;
event->action = cmd_act_set;
event->action = cpu_to_le16(cmd_act_set);
pcmdptr->size = cpu_to_le16(S_DS_GEN +
sizeof(struct cmd_ds_802_11_subscribe_event) +
sizeof(struct mrvlietypes_failurecount));
......@@ -894,11 +872,11 @@ static ssize_t libertas_failcount_write(struct file *file,
ptr = (u8*) pcmdptr+cmd_len;
failcount = (struct mrvlietypes_failurecount *)(ptr);
failcount->header.type = cpu_to_le16(TLV_TYPE_FAILCOUNT);
failcount->header.len = 2;
failcount->failvalue = cpu_to_le16(value);
failcount->Failfreq = cpu_to_le16(freq);
failcount->header.len = cpu_to_le16(2);
failcount->failvalue = value;
failcount->Failfreq = freq;
event_bitmap |= subscribed ? 0x0004 : 0x0;
event->events = event_bitmap;
event->events = cpu_to_le16(event_bitmap);
libertas_queue_cmd(adapter, pcmdnode, 1);
wake_up_interruptible(&priv->mainthread.waitq);
......@@ -910,14 +888,14 @@ static ssize_t libertas_failcount_write(struct file *file,
pcmdptr = (struct cmd_ds_command *)response_buf;
if (pcmdptr->result) {
lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
pcmdptr->result);
lbs_pr_err("%s: fail, result=%d\n", __func__,
le16_to_cpu(pcmdptr->result));
kfree(response_buf);
free_page(addr);
return 0;
}
if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) {
lbs_pr_err("command response incorrect!\n");
kfree(response_buf);
free_page(addr);
......@@ -951,9 +929,8 @@ static ssize_t libertas_bcnmiss_read(struct file *file, char __user *userbuf,
}
event = &pcmdptr->params.subscribe_event;
event->action = cmd_act_get;
pcmdptr->size =
cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
event->action = cpu_to_le16(cmd_act_get);
pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN);
libertas_queue_cmd(adapter, pcmdnode, 1);
wake_up_interruptible(&priv->mainthread.waitq);
......@@ -964,14 +941,14 @@ static ssize_t libertas_bcnmiss_read(struct file *file, char __user *userbuf,
pcmdptr = response_buf;
if (pcmdptr->result) {
lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
pcmdptr->result);
lbs_pr_err("%s: fail, result=%d\n", __func__,
le16_to_cpu(pcmdptr->result));
free_page(addr);
kfree(response_buf);
return 0;
}
if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) {
lbs_pr_err("command response incorrect!\n");
free_page(addr);
kfree(response_buf);
......@@ -979,16 +956,16 @@ static ssize_t libertas_bcnmiss_read(struct file *file, char __user *userbuf,
}
cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
while (cmd_len < pcmdptr->size) {
struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
switch(header->type) {
event = (void *)(response_buf + S_DS_GEN);
while (cmd_len < le16_to_cpu(pcmdptr->size)) {
struct mrvlietypesheader *header = (void *)(response_buf + cmd_len);
switch (header->type) {
struct mrvlietypes_beaconsmissed *bcnmiss;
case TLV_TYPE_BCNMISS:
bcnmiss = (struct mrvlietypes_beaconsmissed *)(response_buf + cmd_len);
case __constant_cpu_to_le16(TLV_TYPE_BCNMISS):
bcnmiss = (void *)(response_buf + cmd_len);
pos += snprintf(buf+pos, len-pos, "%d N/A %d\n",
bcnmiss->beaconmissed,
(event->events & 0x0008)?1:0);
(event->events & cpu_to_le16(0x0008))?1:0);
default:
cmd_len += sizeof(struct mrvlietypes_beaconsmissed);
break;
......@@ -1038,7 +1015,7 @@ static ssize_t libertas_bcnmiss_write(struct file *file,
goto out_unlock;
event = &pcmdptr->params.subscribe_event;
event->action = cmd_act_set;
event->action = cpu_to_le16(cmd_act_set);
pcmdptr->size = cpu_to_le16(S_DS_GEN +
sizeof(struct cmd_ds_802_11_subscribe_event) +
sizeof(struct mrvlietypes_beaconsmissed));
......@@ -1046,10 +1023,10 @@ static ssize_t libertas_bcnmiss_write(struct file *file,
ptr = (u8*) pcmdptr+cmd_len;
bcnmiss = (struct mrvlietypes_beaconsmissed *)(ptr);
bcnmiss->header.type = cpu_to_le16(TLV_TYPE_BCNMISS);
bcnmiss->header.len = 2;
bcnmiss->beaconmissed = cpu_to_le16(value);
bcnmiss->header.len = cpu_to_le16(2);
bcnmiss->beaconmissed = value;
event_bitmap |= subscribed ? 0x0008 : 0x0;
event->events = event_bitmap;
event->events = cpu_to_le16(event_bitmap);
libertas_queue_cmd(adapter, pcmdnode, 1);
wake_up_interruptible(&priv->mainthread.waitq);
......@@ -1061,14 +1038,14 @@ static ssize_t libertas_bcnmiss_write(struct file *file,
pcmdptr = response_buf;
if (pcmdptr->result) {
lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
pcmdptr->result);
lbs_pr_err("%s: fail, result=%d\n", __func__,
le16_to_cpu(pcmdptr->result));
kfree(response_buf);
free_page(addr);
return 0;
}
if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) {
lbs_pr_err("command response incorrect!\n");
free_page(addr);
kfree(response_buf);
......@@ -1102,9 +1079,8 @@ static ssize_t libertas_highrssi_read(struct file *file, char __user *userbuf,
}
event = &pcmdptr->params.subscribe_event;
event->action = cmd_act_get;
pcmdptr->size =
cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
event->action = cpu_to_le16(cmd_act_get);
pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN);
libertas_queue_cmd(adapter, pcmdnode, 1);
wake_up_interruptible(&priv->mainthread.waitq);
......@@ -1115,14 +1091,14 @@ static ssize_t libertas_highrssi_read(struct file *file, char __user *userbuf,
pcmdptr = response_buf;
if (pcmdptr->result) {
lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
pcmdptr->result);
lbs_pr_err("%s: fail, result=%d\n", __func__,
le16_to_cpu(pcmdptr->result));
kfree(response_buf);
free_page(addr);
return 0;
}
if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) {
lbs_pr_err("command response incorrect!\n");
kfree(response_buf);
free_page(addr);
......@@ -1130,17 +1106,17 @@ static ssize_t libertas_highrssi_read(struct file *file, char __user *userbuf,
}
cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
while (cmd_len < pcmdptr->size) {
struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
switch(header->type) {
event = (void *)(response_buf + S_DS_GEN);
while (cmd_len < le16_to_cpu(pcmdptr->size)) {
struct mrvlietypesheader *header = (void *)(response_buf + cmd_len);
switch (header->type) {
struct mrvlietypes_rssithreshold *Highrssi;
case TLV_TYPE_RSSI_HIGH:
Highrssi = (struct mrvlietypes_rssithreshold *)(response_buf + cmd_len);
case __constant_cpu_to_le16(TLV_TYPE_RSSI_HIGH):
Highrssi = (void *)(response_buf + cmd_len);
pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
Highrssi->rssivalue,
Highrssi->rssifreq,
(event->events & 0x0010)?1:0);
(event->events & cpu_to_le16(0x0010))?1:0);
default:
cmd_len += sizeof(struct mrvlietypes_snrthreshold);
break;
......@@ -1190,7 +1166,7 @@ static ssize_t libertas_highrssi_write(struct file *file,
goto out_unlock;
event = &pcmdptr->params.subscribe_event;
event->action = cmd_act_set;
event->action = cpu_to_le16(cmd_act_set);
pcmdptr->size = cpu_to_le16(S_DS_GEN +
sizeof(struct cmd_ds_802_11_subscribe_event) +
sizeof(struct mrvlietypes_rssithreshold));
......@@ -1198,11 +1174,11 @@ static ssize_t libertas_highrssi_write(struct file *file,
ptr = (u8*) pcmdptr+cmd_len;
rssi_threshold = (struct mrvlietypes_rssithreshold *)(ptr);
rssi_threshold->header.type = cpu_to_le16(TLV_TYPE_RSSI_HIGH);
rssi_threshold->header.len = 2;
rssi_threshold->rssivalue = cpu_to_le16(value);
rssi_threshold->rssifreq = cpu_to_le16(freq);
rssi_threshold->header.len = cpu_to_le16(2);
rssi_threshold->rssivalue = value;
rssi_threshold->rssifreq = freq;
event_bitmap |= subscribed ? 0x0010 : 0x0;
event->events = event_bitmap;
event->events = cpu_to_le16(event_bitmap);
libertas_queue_cmd(adapter, pcmdnode, 1);
wake_up_interruptible(&priv->mainthread.waitq);
......@@ -1214,13 +1190,13 @@ static ssize_t libertas_highrssi_write(struct file *file,
pcmdptr = response_buf;
if (pcmdptr->result) {
lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
pcmdptr->result);
lbs_pr_err("%s: fail, result=%d\n", __func__,
le16_to_cpu(pcmdptr->result));
kfree(response_buf);
return 0;
}
if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) {
lbs_pr_err("command response incorrect!\n");
kfree(response_buf);
return 0;
......@@ -1253,9 +1229,8 @@ static ssize_t libertas_highsnr_read(struct file *file, char __user *userbuf,
}
event = &pcmdptr->params.subscribe_event;
event->action = cmd_act_get;
pcmdptr->size =
cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
event->action = cpu_to_le16(cmd_act_get);
pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN);
libertas_queue_cmd(adapter, pcmdnode, 1);
wake_up_interruptible(&priv->mainthread.waitq);
......@@ -1266,14 +1241,14 @@ static ssize_t libertas_highsnr_read(struct file *file, char __user *userbuf,
pcmdptr = response_buf;
if (pcmdptr->result) {
lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
pcmdptr->result);
lbs_pr_err("%s: fail, result=%d\n", __func__,
le16_to_cpu(pcmdptr->result));
kfree(response_buf);
free_page(addr);
return 0;
}
if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) {
lbs_pr_err("command response incorrect!\n");
kfree(response_buf);
free_page(addr);
......@@ -1281,17 +1256,17 @@ static ssize_t libertas_highsnr_read(struct file *file, char __user *userbuf,
}
cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
while (cmd_len < pcmdptr->size) {
struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
switch(header->type) {
event = (void *)(response_buf + S_DS_GEN);
while (cmd_len < le16_to_cpu(pcmdptr->size)) {
struct mrvlietypesheader *header = (void *)(response_buf + cmd_len);
switch (header->type) {
struct mrvlietypes_snrthreshold *HighSnr;
case TLV_TYPE_SNR_HIGH:
HighSnr = (struct mrvlietypes_snrthreshold *)(response_buf + cmd_len);
case __constant_cpu_to_le16(TLV_TYPE_SNR_HIGH):
HighSnr = (void *)(response_buf + cmd_len);
pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
HighSnr->snrvalue,
HighSnr->snrfreq,
(event->events & 0x0020)?1:0);
(event->events & cpu_to_le16(0x0020))?1:0);
default:
cmd_len += sizeof(struct mrvlietypes_snrthreshold);
break;
......@@ -1341,7 +1316,7 @@ static ssize_t libertas_highsnr_write(struct file *file,
goto out_unlock;
event = &pcmdptr->params.subscribe_event;
event->action = cmd_act_set;
event->action = cpu_to_le16(cmd_act_set);
pcmdptr->size = cpu_to_le16(S_DS_GEN +
sizeof(struct cmd_ds_802_11_subscribe_event) +
sizeof(struct mrvlietypes_snrthreshold));
......@@ -1349,11 +1324,11 @@ static ssize_t libertas_highsnr_write(struct file *file,
ptr = (u8*) pcmdptr+cmd_len;
snr_threshold = (struct mrvlietypes_snrthreshold *)(ptr);
snr_threshold->header.type = cpu_to_le16(TLV_TYPE_SNR_HIGH);
snr_threshold->header.len = 2;
snr_threshold->snrvalue = cpu_to_le16(value);
snr_threshold->snrfreq = cpu_to_le16(freq);
snr_threshold->header.len = cpu_to_le16(2);
snr_threshold->snrvalue = value;
snr_threshold->snrfreq = freq;
event_bitmap |= subscribed ? 0x0020 : 0x0;
event->events = event_bitmap;
event->events = cpu_to_le16(event_bitmap);
libertas_queue_cmd(adapter, pcmdnode, 1);
wake_up_interruptible(&priv->mainthread.waitq);
......@@ -1365,14 +1340,14 @@ static ssize_t libertas_highsnr_write(struct file *file,
pcmdptr = response_buf;
if (pcmdptr->result) {
lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
pcmdptr->result);
lbs_pr_err("%s: fail, result=%d\n", __func__,
le16_to_cpu(pcmdptr->result));
kfree(response_buf);
free_page(addr);
return 0;
}
if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) {
lbs_pr_err("command response incorrect!\n");
kfree(response_buf);
free_page(addr);
......@@ -1760,7 +1735,7 @@ void libertas_debugfs_remove_one(wlan_private *priv)
debugfs_remove(priv->regs_dir);
for(i=0; i<ARRAY_SIZE(debugfs_files); i++)
for(i=0; i<ARRAY_SIZE(debugfs_events_files); i++)
debugfs_remove(priv->debugfs_events_files[i]);
debugfs_remove(priv->events_dir);
......@@ -1769,13 +1744,19 @@ void libertas_debugfs_remove_one(wlan_private *priv)
#endif
for(i=0; i<ARRAY_SIZE(debugfs_files); i++)
debugfs_remove(priv->debugfs_files[i]);
debugfs_remove(priv->debugfs_dir);
}
/* debug entry */
#ifdef PROC_DEBUG
#define item_size(n) (FIELD_SIZEOF(wlan_adapter, n))
#define item_addr(n) (offsetof(wlan_adapter, n))
struct debug_data {
char name[32];
u32 size;
......@@ -1863,7 +1844,7 @@ static ssize_t wlan_debugfs_write(struct file *f, const char __user *buf,
return 0;
if (copy_from_user(pdata, buf, cnt)) {
lbs_pr_debug(1, "Copy from user failed\n");
lbs_deb_debugfs("Copy from user failed\n");
kfree(pdata);
return 0;
}
......@@ -1913,7 +1894,7 @@ static struct file_operations libertas_debug_fops = {
* @param dev pointer net_device
* @return N/A
*/
void libertas_debug_init(wlan_private * priv, struct net_device *dev)
static void libertas_debug_init(wlan_private * priv, struct net_device *dev)
{
int i;
......@@ -1927,4 +1908,5 @@ void libertas_debug_init(wlan_private * priv, struct net_device *dev)
priv->debugfs_dir, &items[0],
&libertas_debug_fops);
}
#endif
......@@ -6,6 +6,8 @@
#ifndef _WLAN_DECL_H_
#define _WLAN_DECL_H_
#include <linux/device.h>
#include "defs.h"
/** Function Prototype Declaration */
......@@ -66,18 +68,24 @@ void libertas_ps_wakeup(wlan_private * priv, int wait_option);
void libertas_tx_runqueue(wlan_private *priv);
extern struct chan_freq_power *libertas_find_cfp_by_band_and_channel(
struct chan_freq_power *libertas_find_cfp_by_band_and_channel(
wlan_adapter * adapter, u8 band, u16 channel);
extern void libertas_mac_event_disconnected(wlan_private * priv);
void libertas_mac_event_disconnected(wlan_private * priv);
void libertas_send_iwevcustom_event(wlan_private * priv, s8 * str);
int reset_device(wlan_private *priv);
/* fw.c */
int libertas_init_fw(wlan_private * priv, char *fw_name);
/* main.c */
extern struct chan_freq_power *libertas_get_region_cfp_table(u8 region, u8 band,
struct chan_freq_power *libertas_get_region_cfp_table(u8 region, u8 band,
int *cfp_no);
wlan_private *wlan_add_card(void *card);
int wlan_remove_card(void *card);
wlan_private *libertas_add_card(void *card, struct device *dmdev);
int libertas_activate_card(wlan_private *priv, char *fw_name);
int libertas_remove_card(wlan_private *priv);
int libertas_add_mesh(wlan_private *priv, struct device *dev);
void libertas_remove_mesh(wlan_private *priv);
#endif /* _WLAN_DECL_H_ */
......@@ -7,14 +7,79 @@
#include <linux/spinlock.h>
extern unsigned int libertas_debug;
#ifdef CONFIG_LIBERTAS_DEBUG
#define DEBUG
#define PROC_DEBUG
#endif
#define DRV_NAME "usb8xxx"
#ifndef DRV_NAME
#define DRV_NAME "libertas"
#endif
#define LBS_DEB_ENTER 0x00000001
#define LBS_DEB_LEAVE 0x00000002
#define LBS_DEB_MAIN 0x00000004
#define LBS_DEB_NET 0x00000008
#define LBS_DEB_MESH 0x00000010
#define LBS_DEB_WEXT 0x00000020
#define LBS_DEB_IOCTL 0x00000040
#define LBS_DEB_SCAN 0x00000080
#define LBS_DEB_ASSOC 0x00000100
#define LBS_DEB_JOIN 0x00000200
#define LBS_DEB_11D 0x00000400
#define LBS_DEB_DEBUGFS 0x00000800
#define LBS_DEB_ETHTOOL 0x00001000
#define LBS_DEB_HOST 0x00002000
#define LBS_DEB_CMD 0x00004000
#define LBS_DEB_RX 0x00008000
#define LBS_DEB_TX 0x00010000
#define LBS_DEB_USB 0x00020000
#define LBS_DEB_CS 0x00040000
#define LBS_DEB_FW 0x00080000
#define LBS_DEB_THREAD 0x00100000
#define LBS_DEB_HEX 0x00200000
extern unsigned int libertas_debug;
#ifdef DEBUG
#define LBS_DEB_LL(grp, fmt, args...) \
do { if ((libertas_debug & (grp)) == (grp)) \
printk(KERN_DEBUG DRV_NAME "%s: " fmt, \
in_interrupt() ? " (INT)" : "", ## args); } while (0)
#else
#define LBS_DEB_LL(grp, fmt, args...) do {} while (0)
#endif
#define lbs_deb_enter(grp) \
LBS_DEB_LL(grp | LBS_DEB_ENTER, "%s():%d enter\n", __FUNCTION__, __LINE__);
#define lbs_deb_enter_args(grp, fmt, args...) \
LBS_DEB_LL(grp | LBS_DEB_ENTER, "%s(" fmt "):%d\n", __FUNCTION__, ## args, __LINE__);
#define lbs_deb_leave(grp) \
LBS_DEB_LL(grp | LBS_DEB_LEAVE, "%s():%d leave\n", __FUNCTION__, __LINE__);
#define lbs_deb_leave_args(grp, fmt, args...) \
LBS_DEB_LL(grp | LBS_DEB_LEAVE, "%s():%d leave, " fmt "\n", \
__FUNCTION__, __LINE__, ##args);
#define lbs_deb_main(fmt, args...) LBS_DEB_LL(LBS_DEB_MAIN, fmt, ##args)
#define lbs_deb_net(fmt, args...) LBS_DEB_LL(LBS_DEB_NET, fmt, ##args)
#define lbs_deb_mesh(fmt, args...) LBS_DEB_LL(LBS_DEB_MESH, fmt, ##args)
#define lbs_deb_wext(fmt, args...) LBS_DEB_LL(LBS_DEB_WEXT, fmt, ##args)
#define lbs_deb_ioctl(fmt, args...) LBS_DEB_LL(LBS_DEB_IOCTL, fmt, ##args)
#define lbs_deb_scan(fmt, args...) LBS_DEB_LL(LBS_DEB_SCAN, fmt, ##args)
#define lbs_deb_assoc(fmt, args...) LBS_DEB_LL(LBS_DEB_ASSOC, fmt, ##args)
#define lbs_deb_join(fmt, args...) LBS_DEB_LL(LBS_DEB_JOIN, fmt, ##args)
#define lbs_deb_11d(fmt, args...) LBS_DEB_LL(LBS_DEB_11D, fmt, ##args)
#define lbs_deb_debugfs(fmt, args...) LBS_DEB_LL(LBS_DEB_DEBUGFS, fmt, ##args)
#define lbs_deb_ethtool(fmt, args...) LBS_DEB_LL(LBS_DEB_ETHTOOL, fmt, ##args)
#define lbs_deb_host(fmt, args...) LBS_DEB_LL(LBS_DEB_HOST, fmt, ##args)
#define lbs_deb_cmd(fmt, args...) LBS_DEB_LL(LBS_DEB_CMD, fmt, ##args)
#define lbs_deb_rx(fmt, args...) LBS_DEB_LL(LBS_DEB_RX, fmt, ##args)
#define lbs_deb_tx(fmt, args...) LBS_DEB_LL(LBS_DEB_TX, fmt, ##args)
#define lbs_deb_fw(fmt, args...) LBS_DEB_LL(LBS_DEB_FW, fmt, ##args)
#define lbs_deb_usb(fmt, args...) LBS_DEB_LL(LBS_DEB_USB, fmt, ##args)
#define lbs_deb_usbd(dev, fmt, args...) LBS_DEB_LL(LBS_DEB_USB, "%s:" fmt, (dev)->bus_id, ##args)
#define lbs_deb_cs(fmt, args...) LBS_DEB_LL(LBS_DEB_CS, fmt, ##args)
#define lbs_deb_thread(fmt, args...) LBS_DEB_LL(LBS_DEB_THREAD, fmt, ##args)
#define lbs_pr_info(format, args...) \
printk(KERN_INFO DRV_NAME": " format, ## args)
......@@ -24,37 +89,25 @@ extern unsigned int libertas_debug;
printk(KERN_ALERT DRV_NAME": " format, ## args)
#ifdef DEBUG
#define lbs_pr_debug(level, format, args...) \
do { if (libertas_debug >= level) \
printk(KERN_INFO DRV_NAME": " format, ##args); } while (0)
#define lbs_dev_dbg(level, device, format, args...) \
lbs_pr_debug(level, "%s: " format, \
(device)->bus_id , ## args)
static inline void lbs_dbg_hex(char *prompt, u8 * buf, int len)
{
int i = 0;
if (!libertas_debug)
if (!(libertas_debug & LBS_DEB_HEX))
return;
printk(KERN_DEBUG "%s: ", prompt);
for (i = 1; i <= len; i++) {
printk(KERN_DEBUG "%02x ", (u8) * buf);
printk("%02x ", (u8) * buf);
buf++;
}
printk("\n");
}
#else
#define lbs_pr_debug(level, format, args...) do {} while (0)
#define lbs_dev_dbg(level, device, format, args...) do {} while (0)
#define lbs_dbg_hex(x,y,z) do {} while (0)
#endif
#define ENTER() lbs_pr_debug(1, "Enter: %s, %s:%i\n", \
__FUNCTION__, __FILE__, __LINE__)
#define LEAVE() lbs_pr_debug(1, "Leave: %s, %s:%i\n", \
__FUNCTION__, __FILE__, __LINE__)
/** Buffer Constants */
......@@ -74,7 +127,6 @@ static inline void lbs_dbg_hex(char *prompt, u8 * buf, int len)
#define MRVDRV_NUM_OF_CMD_BUFFER 10
#define MRVDRV_SIZE_OF_CMD_BUFFER (2 * 1024)
#define MRVDRV_MAX_CHANNEL_SIZE 14
#define MRVDRV_MAX_BSSID_LIST 64
#define MRVDRV_ASSOCIATION_TIME_OUT 255
#define MRVDRV_SNAP_HEADER_LEN 8
......@@ -104,6 +156,13 @@ static inline void lbs_dbg_hex(char *prompt, u8 * buf, int len)
#define MRVDRV_MAX_BEACON_INTERVAL 1000
#define MRVDRV_BEACON_INTERVAL 100
/** INT status Bit Definition*/
#define his_cmddnldrdy 0x01
#define his_cardevent 0x02
#define his_cmdupldrdy 0x04
#define SBI_EVENT_CAUSE_SHIFT 3
/** TxPD status */
/* Station firmware use TxPD status field to report final Tx transmit
......@@ -205,8 +264,6 @@ typedef struct _wlan_adapter wlan_adapter;
extern const char libertas_driver_version[];
extern u16 libertas_region_code_to_index[MRVDRV_MAX_REGION_CODE];
extern u8 libertas_wlan_data_rates[WLAN_SUPPORTED_RATES];
extern u8 libertas_supported_rates[G_SUPPORTED_RATES];
extern u8 libertas_adhoc_rates_g[G_SUPPORTED_RATES];
......@@ -316,6 +373,8 @@ enum SNMP_MIB_VALUE_e {
/* Default values for fwt commands. */
#define FWT_DEFAULT_METRIC 0
#define FWT_DEFAULT_DIR 1
/* Default Rate, 11Mbps */
#define FWT_DEFAULT_RATE 3
#define FWT_DEFAULT_SSN 0xffffffff
#define FWT_DEFAULT_DSN 0
#define FWT_DEFAULT_HOPCOUNT 0
......
......@@ -63,11 +63,11 @@ struct wlan_802_11_security {
/** Current Basic Service Set State Structure */
struct current_bss_params {
struct bss_descriptor bssdescriptor;
/** bssid */
u8 bssid[ETH_ALEN];
/** ssid */
struct WLAN_802_11_SSID ssid;
u8 ssid[IW_ESSID_MAX_SIZE + 1];
u8 ssid_len;
/** band */
u8 band;
......@@ -89,31 +89,6 @@ struct sleep_params {
u16 sp_reserved;
};
/** Data structure for the Marvell WLAN device */
typedef struct _wlan_dev {
/** device name */
char name[DEV_NAME_LEN];
/** card pointer */
void *card;
/** IO port */
u32 ioport;
/** Upload received */
u32 upld_rcv;
/** Upload type */
u32 upld_typ;
/** Upload length */
u32 upld_len;
/** netdev pointer */
struct net_device *netdev;
/* Upload buffer */
u8 upld_buf[WLAN_UPLD_SIZE];
/* Download sent:
bit0 1/0=data_sent/data_tx_done,
bit1 1/0=cmd_sent/cmd_tx_done,
all other bits reserved 0 */
u8 dnld_sent;
} wlan_dev_t, *pwlan_dev_t;
/* Mesh statistics */
struct wlan_mesh_stats {
u32 fwd_bcast_cnt; /* Fwd: Broadcast counter */
......@@ -123,6 +98,7 @@ struct wlan_mesh_stats {
u32 fwd_drop_noroute; /* Fwd: No route to Destination */
u32 fwd_drop_nobuf; /* Fwd: Run out of internal buffers */
u32 drop_blind; /* Rx: Dropped by blinding table */
u32 tx_failed_cnt; /* Tx: Failed transmissions */
};
/** Private structure for the MV device */
......@@ -131,8 +107,11 @@ struct _wlan_private {
int mesh_open;
int infra_open;
char name[DEV_NAME_LEN];
void *card;
wlan_adapter *adapter;
wlan_dev_t wlan_dev;
struct net_device *dev;
struct net_device_stats stats;
struct net_device *mesh_dev ; /* Virtual device */
......@@ -153,6 +132,16 @@ struct _wlan_private {
u32 bbp_offset;
u32 rf_offset;
/** Upload length */
u32 upld_len;
/* Upload buffer */
u8 upld_buf[WLAN_UPLD_SIZE];
/* Download sent:
bit0 1/0=data_sent/data_tx_done,
bit1 1/0=cmd_sent/cmd_tx_done,
all other bits reserved 0 */
u8 dnld_sent;
const struct firmware *firmware;
struct device *hotplug_device;
......@@ -161,6 +150,14 @@ struct _wlan_private {
struct delayed_work assoc_work;
struct workqueue_struct *assoc_thread;
/** Hardware access */
int (*hw_register_dev) (wlan_private * priv);
int (*hw_unregister_dev) (wlan_private *);
int (*hw_prog_firmware) (wlan_private *);
int (*hw_host_to_card) (wlan_private * priv, u8 type, u8 * payload, u16 nb);
int (*hw_get_int_status) (wlan_private * priv, u8 *);
int (*hw_read_event_cause) (wlan_private *);
};
/** Association request
......@@ -171,18 +168,21 @@ struct _wlan_private {
struct assoc_request {
#define ASSOC_FLAG_SSID 1
#define ASSOC_FLAG_CHANNEL 2
#define ASSOC_FLAG_MODE 3
#define ASSOC_FLAG_BSSID 4
#define ASSOC_FLAG_WEP_KEYS 5
#define ASSOC_FLAG_WEP_TX_KEYIDX 6
#define ASSOC_FLAG_WPA_MCAST_KEY 7
#define ASSOC_FLAG_WPA_UCAST_KEY 8
#define ASSOC_FLAG_SECINFO 9
#define ASSOC_FLAG_WPA_IE 10
#define ASSOC_FLAG_BAND 3
#define ASSOC_FLAG_MODE 4
#define ASSOC_FLAG_BSSID 5
#define ASSOC_FLAG_WEP_KEYS 6
#define ASSOC_FLAG_WEP_TX_KEYIDX 7
#define ASSOC_FLAG_WPA_MCAST_KEY 8
#define ASSOC_FLAG_WPA_UCAST_KEY 9
#define ASSOC_FLAG_SECINFO 10
#define ASSOC_FLAG_WPA_IE 11
unsigned long flags;
struct WLAN_802_11_SSID ssid;
u8 ssid[IW_ESSID_MAX_SIZE + 1];
u8 ssid_len;
u8 channel;
u8 band;
u8 mode;
u8 bssid[ETH_ALEN];
......@@ -199,12 +199,15 @@ struct assoc_request {
/** WPA Information Elements*/
u8 wpa_ie[MAX_WPA_IE_LEN];
u8 wpa_ie_len;
/* BSS to associate with for infrastructure of Ad-Hoc join */
struct bss_descriptor bss;
};
/** Wlan adapter data structure*/
struct _wlan_adapter {
/** STATUS variables */
u32 fwreleasenumber;
u8 fwreleasenumber[4];
u32 fwcapinfo;
/* protected with big lock */
......@@ -255,13 +258,14 @@ struct _wlan_adapter {
/* IW_MODE_* */
u8 mode;
struct bss_descriptor *pattemptedbssdesc;
struct WLAN_802_11_SSID previousssid;
u8 previousbssid[ETH_ALEN];
u8 prev_ssid[IW_ESSID_MAX_SIZE + 1];
u8 prev_ssid_len;
u8 prev_bssid[ETH_ALEN];
struct bss_descriptor *scantable;
u32 numinscantable;
/* Scan results list */
struct list_head network_list;
struct list_head network_free_list;
struct bss_descriptor *networks;
u8 scantype;
u32 scanmode;
......@@ -288,7 +292,6 @@ struct _wlan_adapter {
u32 txantenna;
u32 rxantenna;
u8 adhocchannel;
u32 fragthsd;
u32 rtsthsd;
......@@ -324,7 +327,8 @@ struct _wlan_adapter {
u16 locallisteninterval;
u16 nullpktinterval;
struct assoc_request * assoc_req;
struct assoc_request * pending_assoc_req;
struct assoc_request * in_progress_assoc_req;
/** Encryption parameter */
struct wlan_802_11_security secinfo;
......@@ -396,6 +400,8 @@ struct _wlan_adapter {
u32 radiomode;
u32 debugmode;
u8 fw_ready;
u8 last_scanned_channel;
};
#endif /* _WLAN_DEV_H_ */
#include <linux/netdevice.h>
#include <linux/ethtool.h>
#include <linux/delay.h>
#include "host.h"
#include "sbi.h"
#include "decl.h"
#include "defs.h"
#include "dev.h"
......@@ -17,7 +15,8 @@ static const char * mesh_stat_strings[]= {
"drop_no_buffers",
"fwded_unicast_cnt",
"fwded_bcast_cnt",
"drop_blind_table"
"drop_blind_table",
"tx_failed_cnt"
};
static void libertas_ethtool_get_drvinfo(struct net_device *dev,
......@@ -69,7 +68,7 @@ static int libertas_ethtool_get_eeprom(struct net_device *dev,
/* +14 is for action, offset, and NOB in
* response */
lbs_pr_debug(1, "action:%d offset: %x NOB: %02x\n",
lbs_deb_ethtool("action:%d offset: %x NOB: %02x\n",
regctrl.action, regctrl.offset, regctrl.NOB);
ret = libertas_prepare_and_send_command(priv,
......@@ -81,8 +80,7 @@ static int libertas_ethtool_get_eeprom(struct net_device *dev,
if (ret) {
if (adapter->prdeeprom)
kfree(adapter->prdeeprom);
LEAVE();
return ret;
goto done;
}
mdelay(10);
......@@ -101,7 +99,11 @@ static int libertas_ethtool_get_eeprom(struct net_device *dev,
kfree(adapter->prdeeprom);
// mutex_unlock(&priv->mutex);
return 0;
ret = 0;
done:
lbs_deb_enter_args(LBS_DEB_ETHTOOL, "ret %d", ret);
return ret;
}
static void libertas_ethtool_get_stats(struct net_device * dev,
......@@ -109,7 +111,7 @@ static void libertas_ethtool_get_stats(struct net_device * dev,
{
wlan_private *priv = dev->priv;
ENTER();
lbs_deb_enter(LBS_DEB_ETHTOOL);
stats->cmd = ETHTOOL_GSTATS;
BUG_ON(stats->n_stats != MESH_STATS_NUM);
......@@ -121,8 +123,9 @@ static void libertas_ethtool_get_stats(struct net_device * dev,
data[4] = priv->mstats.fwd_unicast_cnt;
data[5] = priv->mstats.fwd_bcast_cnt;
data[6] = priv->mstats.drop_blind;
data[7] = priv->mstats.tx_failed_cnt;
LEAVE();
lbs_deb_enter(LBS_DEB_ETHTOOL);
}
static int libertas_ethtool_get_stats_count(struct net_device * dev)
......@@ -131,27 +134,32 @@ static int libertas_ethtool_get_stats_count(struct net_device * dev)
wlan_private *priv = dev->priv;
struct cmd_ds_mesh_access mesh_access;
ENTER();
lbs_deb_enter(LBS_DEB_ETHTOOL);
/* Get Mesh Statistics */
ret = libertas_prepare_and_send_command(priv,
cmd_mesh_access, cmd_act_mesh_get_stats,
cmd_option_waitforrsp, 0, &mesh_access);
if (ret) {
LEAVE();
return 0;
ret = 0;
goto done;
}
priv->mstats.fwd_drop_rbt = mesh_access.data[0];
priv->mstats.fwd_drop_ttl = mesh_access.data[1];
priv->mstats.fwd_drop_noroute = mesh_access.data[2];
priv->mstats.fwd_drop_nobuf = mesh_access.data[3];
priv->mstats.fwd_unicast_cnt = mesh_access.data[4];
priv->mstats.fwd_bcast_cnt = mesh_access.data[5];
priv->mstats.drop_blind = mesh_access.data[6];
priv->mstats.fwd_drop_rbt = le32_to_cpu(mesh_access.data[0]);
priv->mstats.fwd_drop_ttl = le32_to_cpu(mesh_access.data[1]);
priv->mstats.fwd_drop_noroute = le32_to_cpu(mesh_access.data[2]);
priv->mstats.fwd_drop_nobuf = le32_to_cpu(mesh_access.data[3]);
priv->mstats.fwd_unicast_cnt = le32_to_cpu(mesh_access.data[4]);
priv->mstats.fwd_bcast_cnt = le32_to_cpu(mesh_access.data[5]);
priv->mstats.drop_blind = le32_to_cpu(mesh_access.data[6]);
priv->mstats.tx_failed_cnt = le32_to_cpu(mesh_access.data[7]);
ret = MESH_STATS_NUM;
LEAVE();
return MESH_STATS_NUM;
done:
lbs_deb_enter_args(LBS_DEB_ETHTOOL, "ret %d", ret);
return ret;
}
static void libertas_ethtool_get_strings (struct net_device * dev,
......@@ -160,7 +168,8 @@ static void libertas_ethtool_get_strings (struct net_device * dev,
{
int i;
ENTER();
lbs_deb_enter(LBS_DEB_ETHTOOL);
switch (stringset) {
case ETH_SS_STATS:
for (i=0; i < MESH_STATS_NUM; i++) {
......@@ -170,7 +179,7 @@ static void libertas_ethtool_get_strings (struct net_device * dev,
}
break;
}
LEAVE();
lbs_deb_enter(LBS_DEB_ETHTOOL);
}
struct ethtool_ops libertas_ethtool_ops = {
......
/**
* This file contains the initialization for FW and HW
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/vmalloc.h>
#include <linux/firmware.h>
#include <linux/version.h>
#include "host.h"
#include "sbi.h"
#include "defs.h"
#include "decl.h"
#include "dev.h"
#include "fw.h"
#include "wext.h"
#include "if_usb.h"
char *libertas_fw_name = NULL;
module_param_named(fw_name, libertas_fw_name, charp, 0644);
unsigned int libertas_debug = 0;
module_param(libertas_debug, int, 0);
/**
* @brief This function checks the validity of Boot2/FW image.
*
......@@ -32,7 +19,7 @@ module_param(libertas_debug, int, 0);
*/
static int check_fwfile_format(u8 *data, u32 totlen)
{
u8 bincmd, exit;
u32 bincmd, exit;
u32 blksize, offset, len;
int ret;
......@@ -40,8 +27,10 @@ static int check_fwfile_format(u8 *data, u32 totlen)
exit = len = 0;
do {
bincmd = *data;
blksize = *(u32*)(data + offsetof(struct fwheader, datalength));
struct fwheader *fwh = (void *)data;
bincmd = le32_to_cpu(fwh->dnldcmd);
blksize = le32_to_cpu(fwh->datalength);
switch (bincmd) {
case FW_HAS_DATA_TO_RECV:
offset = sizeof(struct fwheader) + blksize;
......@@ -61,9 +50,9 @@ static int check_fwfile_format(u8 *data, u32 totlen)
} while (!exit);
if (ret)
lbs_pr_err("bin file format check FAIL...\n");
lbs_pr_err("firmware file format check FAIL\n");
else
lbs_pr_debug(1, "bin file format check PASS...\n");
lbs_deb_fw("firmware file format check PASS\n");
return ret;
}
......@@ -76,32 +65,31 @@ static int check_fwfile_format(u8 *data, u32 totlen)
* @param priv A pointer to wlan_private structure
* @return 0 or -1
*/
static int wlan_setup_station_hw(wlan_private * priv)
static int wlan_setup_station_hw(wlan_private * priv, char *fw_name)
{
int ret = -1;
wlan_adapter *adapter = priv->adapter;
ENTER();
lbs_deb_enter(LBS_DEB_FW);
if ((ret = request_firmware(&priv->firmware, libertas_fw_name,
if ((ret = request_firmware(&priv->firmware, fw_name,
priv->hotplug_device)) < 0) {
lbs_pr_err("request_firmware() failed, error code = %#x\n",
ret);
lbs_pr_err("%s not found in /lib/firmware\n", libertas_fw_name);
lbs_pr_err("request_firmware() failed with %#x\n", ret);
lbs_pr_err("firmware %s not found\n", fw_name);
goto done;
}
if(check_fwfile_format(priv->firmware->data, priv->firmware->size)) {
if (check_fwfile_format(priv->firmware->data, priv->firmware->size)) {
release_firmware(priv->firmware);
goto done;
}
ret = libertas_sbi_prog_firmware(priv);
ret = priv->hw_prog_firmware(priv);
release_firmware(priv->firmware);
if (ret) {
lbs_pr_debug(1, "Bootloader in invalid state!\n");
lbs_deb_fw("bootloader in invalid state\n");
ret = -1;
goto done;
}
......@@ -133,28 +121,24 @@ static int wlan_setup_station_hw(wlan_private * priv)
ret = 0;
done:
LEAVE();
return (ret);
lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);
return ret;
}
static int wlan_allocate_adapter(wlan_private * priv)
{
u32 ulbufsize;
size_t bufsize;
wlan_adapter *adapter = priv->adapter;
struct bss_descriptor *ptempscantable;
/* Allocate buffer to store the BSSID list */
ulbufsize = sizeof(struct bss_descriptor) * MRVDRV_MAX_BSSID_LIST;
if (!(ptempscantable = kmalloc(ulbufsize, GFP_KERNEL))) {
bufsize = MAX_NETWORK_COUNT * sizeof(struct bss_descriptor);
adapter->networks = kzalloc(bufsize, GFP_KERNEL);
if (!adapter->networks) {
lbs_pr_err("Out of memory allocating beacons\n");
libertas_free_adapter(priv);
return -1;
return -ENOMEM;
}
adapter->scantable = ptempscantable;
memset(adapter->scantable, 0, ulbufsize);
/* Allocate the command buffers */
libertas_allocate_cmd_buffer(priv);
......@@ -202,15 +186,23 @@ static void wlan_init_adapter(wlan_private * priv)
adapter->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
adapter->mode = IW_MODE_INFRA;
adapter->assoc_req = NULL;
adapter->pending_assoc_req = NULL;
adapter->in_progress_assoc_req = NULL;
/* Initialize scan result lists */
INIT_LIST_HEAD(&adapter->network_free_list);
INIT_LIST_HEAD(&adapter->network_list);
for (i = 0; i < MAX_NETWORK_COUNT; i++) {
list_add_tail(&adapter->networks[i].list,
&adapter->network_free_list);
}
adapter->numinscantable = 0;
adapter->pattemptedbssdesc = NULL;
mutex_init(&adapter->lock);
adapter->prescan = 1;
memset(&adapter->curbssparams, 0, sizeof(adapter->curbssparams));
adapter->curbssparams.channel = DEFAULT_AD_HOC_CHANNEL;
/* PnP and power profile */
adapter->surpriseremoved = 0;
......@@ -230,8 +222,6 @@ static void wlan_init_adapter(wlan_private * priv)
memset(&adapter->capinfo, 0, sizeof(adapter->capinfo));
adapter->capinfo.shortpreamble = SHORT_PREAMBLE_ALLOWED;
adapter->adhocchannel = DEFAULT_AD_HOC_CHANNEL;
adapter->psmode = wlan802_11powermodecam;
adapter->multipledtim = MRVDRV_DEFAULT_MULTIPLE_DTIM;
......@@ -259,12 +249,12 @@ static void wlan_init_adapter(wlan_private * priv)
static void command_timer_fn(unsigned long data);
int libertas_init_fw(wlan_private * priv)
int libertas_init_fw(wlan_private * priv, char *fw_name)
{
int ret = -1;
wlan_adapter *adapter = priv->adapter;
ENTER();
lbs_deb_enter(LBS_DEB_FW);
/* Allocate adapter structure */
if ((ret = wlan_allocate_adapter(priv)) != 0)
......@@ -278,7 +268,7 @@ int libertas_init_fw(wlan_private * priv)
(unsigned long)priv);
/* download fimrware etc. */
if ((ret = wlan_setup_station_hw(priv)) != 0) {
if ((ret = wlan_setup_station_hw(priv, fw_name)) != 0) {
del_timer_sync(&adapter->command_timer);
goto done;
}
......@@ -288,7 +278,7 @@ int libertas_init_fw(wlan_private * priv)
ret = 0;
done:
LEAVE();
lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);
return ret;
}
......@@ -297,25 +287,22 @@ void libertas_free_adapter(wlan_private * priv)
wlan_adapter *adapter = priv->adapter;
if (!adapter) {
lbs_pr_debug(1, "Why double free adapter?:)\n");
lbs_deb_fw("why double free adapter?\n");
return;
}
lbs_pr_debug(1, "Free command buffer\n");
lbs_deb_fw("free command buffer\n");
libertas_free_cmd_buffer(priv);
lbs_pr_debug(1, "Free commandTimer\n");
lbs_deb_fw("free command_timer\n");
del_timer(&adapter->command_timer);
lbs_pr_debug(1, "Free scantable\n");
if (adapter->scantable) {
kfree(adapter->scantable);
adapter->scantable = NULL;
}
lbs_pr_debug(1, "Free adapter\n");
lbs_deb_fw("free scan results table\n");
kfree(adapter->networks);
adapter->networks = NULL;
/* Free the adapter object itself */
lbs_deb_fw("free adapter\n");
kfree(adapter);
priv->adapter = NULL;
}
......@@ -334,17 +321,17 @@ static void command_timer_fn(unsigned long data)
ptempnode = adapter->cur_cmd;
if (ptempnode == NULL) {
lbs_pr_debug(1, "PTempnode Empty\n");
lbs_deb_fw("ptempnode empty\n");
return;
}
cmd = (struct cmd_ds_command *)ptempnode->bufvirtualaddr;
if (!cmd) {
lbs_pr_debug(1, "cmd is NULL\n");
lbs_deb_fw("cmd is NULL\n");
return;
}
lbs_pr_info("command_timer_fn fired (%x)\n", cmd->command);
lbs_deb_fw("command_timer_fn fired, cmd %x\n", cmd->command);
if (!adapter->fw_ready)
return;
......@@ -353,7 +340,7 @@ static void command_timer_fn(unsigned long data)
adapter->cur_cmd = NULL;
spin_unlock_irqrestore(&adapter->driver_lock, flags);
lbs_pr_debug(1, "Re-sending same command as it timeout...!\n");
lbs_deb_fw("re-sending same command because of timeout\n");
libertas_queue_cmd(adapter, ptempnode, 0);
wake_up_interruptible(&priv->mainthread.waitq);
......
/**
* This header file contains FW interface related definitions.
*/
#ifndef _WLAN_FW_H_
#define _WLAN_FW_H_
#ifndef DEV_NAME_LEN
#define DEV_NAME_LEN 32
#endif
int libertas_init_fw(wlan_private * priv);
#endif /* _WLAN_FW_H_ */
......@@ -99,11 +99,11 @@
#define cmd_bt_access 0x0087
#define cmd_ret_bt_access 0x8087
#define cmd_fwt_access 0x0088
#define cmd_ret_fwt_access 0x8088
#define cmd_fwt_access 0x0095
#define cmd_ret_fwt_access 0x8095
#define cmd_mesh_access 0x0090
#define cmd_ret_mesh_access 0x8090
#define cmd_mesh_access 0x009b
#define cmd_ret_mesh_access 0x809b
/* For the IEEE Power Save */
#define cmd_subcmd_enter_ps 0x0030
......@@ -287,7 +287,9 @@ enum cmd_bt_access_opts {
cmd_act_bt_access_add = 5,
cmd_act_bt_access_del,
cmd_act_bt_access_list,
cmd_act_bt_access_reset
cmd_act_bt_access_reset,
cmd_act_bt_access_set_invert,
cmd_act_bt_access_get_invert
};
/* Define action or option for cmd_fwt_access */
......@@ -334,5 +336,6 @@ enum cmd_mesh_access_opts {
#define MACREG_INT_CODE_MAX_FAIL 0x0000001b
#define MACREG_INT_CODE_RSSI_HIGH 0x0000001c
#define MACREG_INT_CODE_SNR_HIGH 0x0000001d
#define MACREG_INT_CODE_MESH_AUTO_STARTED 0x00000023
#endif /* _HOST_H_ */
......@@ -14,12 +14,12 @@
/* TxPD descriptor */
struct txpd {
/* Current Tx packet status */
u32 tx_status;
__le32 tx_status;
/* Tx control */
u32 tx_control;
u32 tx_packet_location;
__le32 tx_control;
__le32 tx_packet_location;
/* Tx packet length */
u16 tx_packet_length;
__le16 tx_packet_length;
/* First 2 byte of destination MAC address */
u8 tx_dest_addr_high[2];
/* Last 4 byte of destination MAC address */
......@@ -37,7 +37,7 @@ struct txpd {
/* RxPD Descriptor */
struct rxpd {
/* Current Rx packet status */
u16 status;
__le16 status;
/* SNR */
u8 snr;
......@@ -46,7 +46,7 @@ struct rxpd {
u8 rx_control;
/* Pkt length */
u16 pkt_len;
__le16 pkt_len;
/* Noise Floor */
u8 nf;
......@@ -55,10 +55,10 @@ struct rxpd {
u8 rx_rate;
/* Pkt addr */
u32 pkt_ptr;
__le32 pkt_ptr;
/* Next Rx RxPD addr */
u32 next_rxpd_ptr;
__le32 next_rxpd_ptr;
/* Pkt Priority */
u8 priority;
......@@ -89,30 +89,17 @@ struct cmd_ctrl_node {
* is determined from the keylength field.
*/
struct WLAN_802_11_KEY {
u32 len;
u32 flags; /* KEY_INFO_* from wlan_defs.h */
__le32 len;
__le32 flags; /* KEY_INFO_* from wlan_defs.h */
u8 key[MRVL_MAX_KEY_WPA_KEY_LENGTH];
u16 type; /* KEY_TYPE_* from wlan_defs.h */
__le16 type; /* KEY_TYPE_* from wlan_defs.h */
};
struct IE_WPA {
u8 elementid;
u8 len;
u8 oui[4];
u16 version;
};
struct WLAN_802_11_SSID {
/* SSID length */
u32 ssidlength;
/* SSID information field */
u8 ssid[IW_ESSID_MAX_SIZE];
};
struct WPA_SUPPLICANT {
u8 wpa_ie[256];
u8 wpa_ie_len;
__le16 version;
};
/* wlan_offset_value */
......@@ -122,9 +109,9 @@ struct wlan_offset_value {
};
struct WLAN_802_11_FIXED_IEs {
u8 timestamp[8];
u16 beaconinterval;
u16 capabilities;
__le64 timestamp;
__le16 beaconinterval;
u16 capabilities; /* Actually struct ieeetypes_capinfo */
};
struct WLAN_802_11_VARIABLE_IEs {
......@@ -136,10 +123,10 @@ struct WLAN_802_11_VARIABLE_IEs {
/* Define general data structure */
/* cmd_DS_GEN */
struct cmd_ds_gen {
u16 command;
u16 size;
u16 seqnum;
u16 result;
__le16 command;
__le16 size;
__le16 seqnum;
__le16 result;
};
#define S_DS_GEN sizeof(struct cmd_ds_gen)
......@@ -149,44 +136,44 @@ struct cmd_ds_gen {
*/
struct cmd_ds_get_hw_spec {
/* HW Interface version number */
u16 hwifversion;
__le16 hwifversion;
/* HW version number */
u16 version;
__le16 version;
/* Max number of TxPD FW can handle */
u16 nr_txpd;
__le16 nr_txpd;
/* Max no of Multicast address */
u16 nr_mcast_adr;
__le16 nr_mcast_adr;
/* MAC address */
u8 permanentaddr[6];
/* region Code */
u16 regioncode;
__le16 regioncode;
/* Number of antenna used */
u16 nr_antenna;
__le16 nr_antenna;
/* FW release number, example 0x1234=1.2.3.4 */
u32 fwreleasenumber;
/* FW release number, example 1,2,3,4 = 3.2.1p4 */
u8 fwreleasenumber[4];
/* Base Address of TxPD queue */
u32 wcb_base;
__le32 wcb_base;
/* Read Pointer of RxPd queue */
u32 rxpd_rdptr;
__le32 rxpd_rdptr;
/* Write Pointer of RxPd queue */
u32 rxpd_wrptr;
__le32 rxpd_wrptr;
/*FW/HW capability */
u32 fwcapinfo;
__le32 fwcapinfo;
} __attribute__ ((packed));
struct cmd_ds_802_11_reset {
u16 action;
__le16 action;
};
struct cmd_ds_802_11_subscribe_event {
u16 action;
u16 events;
__le16 action;
__le16 events;
};
/*
......@@ -205,35 +192,35 @@ struct cmd_ds_802_11_scan {
};
struct cmd_ds_802_11_scan_rsp {
u16 bssdescriptsize;
__le16 bssdescriptsize;
u8 nr_sets;
u8 bssdesc_and_tlvbuffer[1];
};
struct cmd_ds_802_11_get_log {
u32 mcasttxframe;
u32 failed;
u32 retry;
u32 multiretry;
u32 framedup;
u32 rtssuccess;
u32 rtsfailure;
u32 ackfailure;
u32 rxfrag;
u32 mcastrxframe;
u32 fcserror;
u32 txframe;
u32 wepundecryptable;
__le32 mcasttxframe;
__le32 failed;
__le32 retry;
__le32 multiretry;
__le32 framedup;
__le32 rtssuccess;
__le32 rtsfailure;
__le32 ackfailure;
__le32 rxfrag;
__le32 mcastrxframe;
__le32 fcserror;
__le32 txframe;
__le32 wepundecryptable;
};
struct cmd_ds_mac_control {
u16 action;
u16 reserved;
__le16 action;
__le16 reserved;
};
struct cmd_ds_mac_multicast_adr {
u16 action;
u16 nr_of_adrs;
__le16 action;
__le16 nr_of_adrs;
u8 maclist[ETH_ALEN * MRVDRV_MAX_MULTICAST_LIST_SIZE];
};
......@@ -245,14 +232,14 @@ struct cmd_ds_802_11_authenticate {
struct cmd_ds_802_11_deauthenticate {
u8 macaddr[6];
u16 reasoncode;
__le16 reasoncode;
};
struct cmd_ds_802_11_associate {
u8 peerstaaddr[6];
struct ieeetypes_capinfo capinfo;
u16 listeninterval;
u16 bcnperiod;
__le16 listeninterval;
__le16 bcnperiod;
u8 dtimperiod;
#if 0
......@@ -265,7 +252,7 @@ struct cmd_ds_802_11_associate {
struct cmd_ds_802_11_disassociate {
u8 destmacaddr[6];
u16 reasoncode;
__le16 reasoncode;
};
struct cmd_ds_802_11_associate_rsp {
......@@ -279,10 +266,10 @@ struct cmd_ds_802_11_ad_hoc_result {
struct cmd_ds_802_11_set_wep {
/* ACT_ADD, ACT_REMOVE or ACT_ENABLE */
u16 action;
__le16 action;
/* key Index selected for Tx */
u16 keyindex;
__le16 keyindex;
/* 40, 128bit or TXWEP */
u8 keytype[4];
......@@ -290,96 +277,96 @@ struct cmd_ds_802_11_set_wep {
};
struct cmd_ds_802_3_get_stat {
u32 xmitok;
u32 rcvok;
u32 xmiterror;
u32 rcverror;
u32 rcvnobuffer;
u32 rcvcrcerror;
__le32 xmitok;
__le32 rcvok;
__le32 xmiterror;
__le32 rcverror;
__le32 rcvnobuffer;
__le32 rcvcrcerror;
};
struct cmd_ds_802_11_get_stat {
u32 txfragmentcnt;
u32 mcasttxframecnt;
u32 failedcnt;
u32 retrycnt;
u32 Multipleretrycnt;
u32 rtssuccesscnt;
u32 rtsfailurecnt;
u32 ackfailurecnt;
u32 frameduplicatecnt;
u32 rxfragmentcnt;
u32 mcastrxframecnt;
u32 fcserrorcnt;
u32 bcasttxframecnt;
u32 bcastrxframecnt;
u32 txbeacon;
u32 rxbeacon;
u32 wepundecryptable;
__le32 txfragmentcnt;
__le32 mcasttxframecnt;
__le32 failedcnt;
__le32 retrycnt;
__le32 Multipleretrycnt;
__le32 rtssuccesscnt;
__le32 rtsfailurecnt;
__le32 ackfailurecnt;
__le32 frameduplicatecnt;
__le32 rxfragmentcnt;
__le32 mcastrxframecnt;
__le32 fcserrorcnt;
__le32 bcasttxframecnt;
__le32 bcastrxframecnt;
__le32 txbeacon;
__le32 rxbeacon;
__le32 wepundecryptable;
};
struct cmd_ds_802_11_snmp_mib {
u16 querytype;
u16 oid;
u16 bufsize;
__le16 querytype;
__le16 oid;
__le16 bufsize;
u8 value[128];
};
struct cmd_ds_mac_reg_map {
u16 buffersize;
__le16 buffersize;
u8 regmap[128];
u16 reserved;
__le16 reserved;
};
struct cmd_ds_bbp_reg_map {
u16 buffersize;
__le16 buffersize;
u8 regmap[128];
u16 reserved;
__le16 reserved;
};
struct cmd_ds_rf_reg_map {
u16 buffersize;
__le16 buffersize;
u8 regmap[64];
u16 reserved;
__le16 reserved;
};
struct cmd_ds_mac_reg_access {
u16 action;
u16 offset;
u32 value;
__le16 action;
__le16 offset;
__le32 value;
};
struct cmd_ds_bbp_reg_access {
u16 action;
u16 offset;
__le16 action;
__le16 offset;
u8 value;
u8 reserved[3];
};
struct cmd_ds_rf_reg_access {
u16 action;
u16 offset;
__le16 action;
__le16 offset;
u8 value;
u8 reserved[3];
};
struct cmd_ds_802_11_radio_control {
u16 action;
u16 control;
__le16 action;
__le16 control;
};
struct cmd_ds_802_11_sleep_params {
/* ACT_GET/ACT_SET */
u16 action;
__le16 action;
/* Sleep clock error in ppm */
u16 error;
__le16 error;
/* Wakeup offset in usec */
u16 offset;
__le16 offset;
/* Clock stabilization time in usec */
u16 stabletime;
__le16 stabletime;
/* control periodic calibration */
u8 calcontrol;
......@@ -388,100 +375,100 @@ struct cmd_ds_802_11_sleep_params {
u8 externalsleepclk;
/* reserved field, should be set to zero */
u16 reserved;
__le16 reserved;
};
struct cmd_ds_802_11_inactivity_timeout {
/* ACT_GET/ACT_SET */
u16 action;
__le16 action;
/* Inactivity timeout in msec */
u16 timeout;
__le16 timeout;
};
struct cmd_ds_802_11_rf_channel {
u16 action;
u16 currentchannel;
u16 rftype;
u16 reserved;
__le16 action;
__le16 currentchannel;
__le16 rftype;
__le16 reserved;
u8 channellist[32];
};
struct cmd_ds_802_11_rssi {
/* weighting factor */
u16 N;
__le16 N;
u16 reserved_0;
u16 reserved_1;
u16 reserved_2;
__le16 reserved_0;
__le16 reserved_1;
__le16 reserved_2;
};
struct cmd_ds_802_11_rssi_rsp {
u16 SNR;
u16 noisefloor;
u16 avgSNR;
u16 avgnoisefloor;
__le16 SNR;
__le16 noisefloor;
__le16 avgSNR;
__le16 avgnoisefloor;
};
struct cmd_ds_802_11_mac_address {
u16 action;
__le16 action;
u8 macadd[ETH_ALEN];
};
struct cmd_ds_802_11_rf_tx_power {
u16 action;
u16 currentlevel;
__le16 action;
__le16 currentlevel;
};
struct cmd_ds_802_11_rf_antenna {
u16 action;
__le16 action;
/* Number of antennas or 0xffff(diversity) */
u16 antennamode;
__le16 antennamode;
};
struct cmd_ds_802_11_ps_mode {
u16 action;
u16 nullpktinterval;
u16 multipledtim;
u16 reserved;
u16 locallisteninterval;
__le16 action;
__le16 nullpktinterval;
__le16 multipledtim;
__le16 reserved;
__le16 locallisteninterval;
};
struct PS_CMD_ConfirmSleep {
u16 command;
u16 size;
u16 seqnum;
u16 result;
__le16 command;
__le16 size;
__le16 seqnum;
__le16 result;
u16 action;
u16 reserved1;
u16 multipledtim;
u16 reserved;
u16 locallisteninterval;
__le16 action;
__le16 reserved1;
__le16 multipledtim;
__le16 reserved;
__le16 locallisteninterval;
};
struct cmd_ds_802_11_data_rate {
u16 action;
u16 reserverd;
__le16 action;
__le16 reserverd;
u8 datarate[G_SUPPORTED_RATES];
};
struct cmd_ds_802_11_rate_adapt_rateset {
u16 action;
u16 enablehwauto;
u16 bitmap;
__le16 action;
__le16 enablehwauto;
__le16 bitmap;
};
struct cmd_ds_802_11_ad_hoc_start {
u8 SSID[IW_ESSID_MAX_SIZE];
u8 bsstype;
u16 beaconperiod;
__le16 beaconperiod;
u8 dtimperiod;
union IEEEtypes_ssparamset ssparamset;
union ieeetypes_phyparamset phyparamset;
u16 probedelay;
__le16 probedelay;
struct ieeetypes_capinfo cap;
u8 datarate[G_SUPPORTED_RATES];
u8 tlv_memory_size_pad[100];
......@@ -491,10 +478,10 @@ struct adhoc_bssdesc {
u8 BSSID[6];
u8 SSID[32];
u8 bsstype;
u16 beaconperiod;
__le16 beaconperiod;
u8 dtimperiod;
u8 timestamp[8];
u8 localtime[8];
__le64 timestamp;
__le64 localtime;
union ieeetypes_phyparamset phyparamset;
union IEEEtypes_ssparamset ssparamset;
struct ieeetypes_capinfo cap;
......@@ -508,52 +495,52 @@ struct adhoc_bssdesc {
struct cmd_ds_802_11_ad_hoc_join {
struct adhoc_bssdesc bssdescriptor;
u16 failtimeout;
u16 probedelay;
__le16 failtimeout;
__le16 probedelay;
} __attribute__ ((packed));
struct cmd_ds_802_11_enable_rsn {
u16 action;
u16 enable;
__le16 action;
__le16 enable;
};
struct MrvlIEtype_keyParamSet {
/* type ID */
u16 type;
__le16 type;
/* length of Payload */
u16 length;
__le16 length;
/* type of key: WEP=0, TKIP=1, AES=2 */
u16 keytypeid;
__le16 keytypeid;
/* key control Info specific to a keytypeid */
u16 keyinfo;
__le16 keyinfo;
/* length of key */
u16 keylen;
__le16 keylen;
/* key material of size keylen */
u8 key[32];
};
struct cmd_ds_802_11_key_material {
u16 action;
__le16 action;
struct MrvlIEtype_keyParamSet keyParamSet[2];
} __attribute__ ((packed));
struct cmd_ds_802_11_eeprom_access {
u16 action;
__le16 action;
/* multiple 4 */
u16 offset;
u16 bytecount;
__le16 offset;
__le16 bytecount;
u8 value;
} __attribute__ ((packed));
struct cmd_ds_802_11_tpc_cfg {
u16 action;
__le16 action;
u8 enable;
s8 P0;
s8 P1;
......@@ -562,13 +549,13 @@ struct cmd_ds_802_11_tpc_cfg {
} __attribute__ ((packed));
struct cmd_ds_802_11_led_ctrl {
u16 action;
u16 numled;
__le16 action;
__le16 numled;
u8 data[256];
} __attribute__ ((packed));
struct cmd_ds_802_11_pwr_cfg {
u16 action;
__le16 action;
u8 enable;
s8 PA_P0;
s8 PA_P1;
......@@ -576,21 +563,21 @@ struct cmd_ds_802_11_pwr_cfg {
} __attribute__ ((packed));
struct cmd_ds_802_11_afc {
u16 afc_auto;
__le16 afc_auto;
union {
struct {
u16 threshold;
u16 period;
__le16 threshold;
__le16 period;
};
struct {
s16 timing_offset;
s16 carrier_offset;
__le16 timing_offset; /* signed */
__le16 carrier_offset; /* signed */
};
};
} __attribute__ ((packed));
struct cmd_tx_rate_query {
u16 txrate;
__le16 txrate;
} __attribute__ ((packed));
struct cmd_ds_get_tsf {
......@@ -598,41 +585,46 @@ struct cmd_ds_get_tsf {
} __attribute__ ((packed));
struct cmd_ds_bt_access {
u16 action;
u32 id;
__le16 action;
__le32 id;
u8 addr1[ETH_ALEN];
u8 addr2[ETH_ALEN];
} __attribute__ ((packed));
struct cmd_ds_fwt_access {
u16 action;
u32 id;
__le16 action;
__le32 id;
u8 valid;
u8 da[ETH_ALEN];
u8 dir;
u8 ra[ETH_ALEN];
u32 ssn;
u32 dsn;
u32 metric;
__le32 ssn;
__le32 dsn;
__le32 metric;
u8 rate;
u8 hopcount;
u8 ttl;
u32 expiration;
__le32 expiration;
u8 sleepmode;
u32 snr;
u32 references;
__le32 snr;
__le32 references;
u8 prec[ETH_ALEN];
} __attribute__ ((packed));
#define MESH_STATS_NUM 7
struct cmd_ds_mesh_access {
u16 action;
u32 data[MESH_STATS_NUM + 1]; /* last position reserved */
__le16 action;
__le32 data[32]; /* last position reserved */
} __attribute__ ((packed));
/* Number of stats counters returned by the firmware */
#define MESH_STATS_NUM 8
struct cmd_ds_command {
/* command header */
u16 command;
u16 size;
u16 seqnum;
u16 result;
__le16 command;
__le16 size;
__le16 seqnum;
__le16 result;
/* command Body */
union {
......
......@@ -8,6 +8,8 @@
#include <linux/netdevice.h>
#include <linux/usb.h>
#define DRV_NAME "usb8xxx"
#include "defs.h"
#include "dev.h"
#include "if_usb.h"
......@@ -20,12 +22,12 @@
*/
int if_usb_issue_boot_command(wlan_private *priv, int ivalue)
{
struct usb_card_rec *cardp = priv->wlan_dev.card;
struct usb_card_rec *cardp = priv->card;
struct bootcmdstr sbootcmd;
int i;
/* Prepare command */
sbootcmd.u32magicnumber = BOOT_CMD_MAGIC_NUMBER;
sbootcmd.u32magicnumber = cpu_to_le32(BOOT_CMD_MAGIC_NUMBER);
sbootcmd.u8cmd_tag = ivalue;
for (i=0; i<11; i++)
sbootcmd.au8dumy[i]=0x00;
......
......@@ -2,12 +2,15 @@
* This file contains functions used in USB interface module.
*/
#include <linux/delay.h>
#include <linux/moduleparam.h>
#include <linux/firmware.h>
#include <linux/netdevice.h>
#include <linux/list.h>
#include <linux/usb.h>
#define DRV_NAME "usb8xxx"
#include "host.h"
#include "sbi.h"
#include "decl.h"
#include "defs.h"
#include "dev.h"
......@@ -16,15 +19,24 @@
#define MESSAGE_HEADER_LEN 4
static const char usbdriver_name[] = "usb8xxx";
static u8 *default_fw_name = "usb8388.bin";
char *libertas_fw_name = NULL;
module_param_named(fw_name, libertas_fw_name, charp, 0644);
/*
* We need to send a RESET command to all USB devices before
* we tear down the USB connection. Otherwise we would not
* be able to re-init device the device if the module gets
* loaded again. This is a list of all initialized USB devices,
* for the reset code see if_usb_reset_device()
*/
static LIST_HEAD(usb_devices);
static struct usb_device_id if_usb_table[] = {
/* Enter the device signature inside */
{
USB_DEVICE(USB8388_VID_1, USB8388_PID_1),
},
{
USB_DEVICE(USB8388_VID_2, USB8388_PID_2),
},
{ USB_DEVICE(0x1286, 0x2001) },
{ USB_DEVICE(0x05a3, 0x8388) },
{} /* Terminating entry */
};
......@@ -32,6 +44,13 @@ MODULE_DEVICE_TABLE(usb, if_usb_table);
static void if_usb_receive(struct urb *urb);
static void if_usb_receive_fwload(struct urb *urb);
static int if_usb_reset_device(wlan_private *priv);
static int if_usb_register_dev(wlan_private * priv);
static int if_usb_unregister_dev(wlan_private *);
static int if_usb_prog_firmware(wlan_private *);
static int if_usb_host_to_card(wlan_private * priv, u8 type, u8 * payload, u16 nb);
static int if_usb_get_int_status(wlan_private * priv, u8 *);
static int if_usb_read_event_cause(wlan_private *);
/**
* @brief call back function to handle the status of the URB
......@@ -42,23 +61,27 @@ static void if_usb_write_bulk_callback(struct urb *urb)
{
wlan_private *priv = (wlan_private *) (urb->context);
wlan_adapter *adapter = priv->adapter;
struct net_device *dev = priv->wlan_dev.netdev;
struct net_device *dev = priv->dev;
/* handle the transmission complete validations */
if (urb->status != 0) {
/* print the failure status number for debug */
lbs_pr_info("URB in failure status\n");
lbs_pr_info("URB in failure status: %d\n", urb->status);
} else {
lbs_dev_dbg(2, &urb->dev->dev, "URB status is successfull\n");
lbs_dev_dbg(2, &urb->dev->dev, "Actual length transmitted %d\n",
/*
lbs_deb_usbd(&urb->dev->dev, "URB status is successfull\n");
lbs_deb_usbd(&urb->dev->dev, "Actual length transmitted %d\n",
urb->actual_length);
priv->wlan_dev.dnld_sent = DNLD_RES_RECEIVED;
*/
priv->dnld_sent = DNLD_RES_RECEIVED;
/* Wake main thread if commands are pending */
if (!adapter->cur_cmd)
wake_up_interruptible(&priv->mainthread.waitq);
if ((adapter->connect_status == libertas_connected))
if ((adapter->connect_status == libertas_connected)) {
netif_wake_queue(dev);
netif_wake_queue(priv->mesh_dev);
}
}
return;
......@@ -71,7 +94,7 @@ static void if_usb_write_bulk_callback(struct urb *urb)
*/
void if_usb_free(struct usb_card_rec *cardp)
{
ENTER();
lbs_deb_enter(LBS_DEB_USB);
/* Unlink tx & rx urb */
usb_kill_urb(cardp->tx_urb);
......@@ -86,8 +109,7 @@ void if_usb_free(struct usb_card_rec *cardp)
kfree(cardp->bulk_out_buffer);
cardp->bulk_out_buffer = NULL;
LEAVE();
return;
lbs_deb_leave(LBS_DEB_USB);
}
/**
......@@ -102,24 +124,24 @@ static int if_usb_probe(struct usb_interface *intf,
struct usb_device *udev;
struct usb_host_interface *iface_desc;
struct usb_endpoint_descriptor *endpoint;
wlan_private *pwlanpriv;
struct usb_card_rec *usb_cardp;
wlan_private *priv;
struct usb_card_rec *cardp;
int i;
udev = interface_to_usbdev(intf);
usb_cardp = kzalloc(sizeof(struct usb_card_rec), GFP_KERNEL);
if (!usb_cardp) {
cardp = kzalloc(sizeof(struct usb_card_rec), GFP_KERNEL);
if (!cardp) {
lbs_pr_err("Out of memory allocating private data.\n");
goto error;
}
usb_cardp->udev = udev;
cardp->udev = udev;
iface_desc = intf->cur_altsetting;
lbs_dev_dbg(1, &udev->dev, "bcdUSB = 0x%X bDeviceClass = 0x%X"
lbs_deb_usbd(&udev->dev, "bcdUSB = 0x%X bDeviceClass = 0x%X"
" bDeviceSubClass = 0x%X, bDeviceProtocol = 0x%X\n",
udev->descriptor.bcdUSB,
le16_to_cpu(udev->descriptor.bcdUSB),
udev->descriptor.bDeviceClass,
udev->descriptor.bDeviceSubClass,
udev->descriptor.bDeviceProtocol);
......@@ -130,23 +152,21 @@ static int if_usb_probe(struct usb_interface *intf,
&& ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
USB_ENDPOINT_XFER_BULK)) {
/* we found a bulk in endpoint */
lbs_dev_dbg(1, &udev->dev, "Bulk in size is %d\n",
endpoint->wMaxPacketSize);
if (!
(usb_cardp->rx_urb =
usb_alloc_urb(0, GFP_KERNEL))) {
lbs_dev_dbg(1, &udev->dev,
lbs_deb_usbd(&udev->dev, "Bulk in size is %d\n",
le16_to_cpu(endpoint->wMaxPacketSize));
if (!(cardp->rx_urb = usb_alloc_urb(0, GFP_KERNEL))) {
lbs_deb_usbd(&udev->dev,
"Rx URB allocation failed\n");
goto dealloc;
}
usb_cardp->rx_urb_recall = 0;
cardp->rx_urb_recall = 0;
usb_cardp->bulk_in_size =
endpoint->wMaxPacketSize;
usb_cardp->bulk_in_endpointAddr =
cardp->bulk_in_size =
le16_to_cpu(endpoint->wMaxPacketSize);
cardp->bulk_in_endpointAddr =
(endpoint->
bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
lbs_dev_dbg(1, &udev->dev, "in_endpoint = %d\n",
lbs_deb_usbd(&udev->dev, "in_endpoint = %d\n",
endpoint->bEndpointAddress);
}
......@@ -156,55 +176,63 @@ static int if_usb_probe(struct usb_interface *intf,
&& ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
USB_ENDPOINT_XFER_BULK)) {
/* We found bulk out endpoint */
if (!
(usb_cardp->tx_urb =
usb_alloc_urb(0, GFP_KERNEL))) {
lbs_dev_dbg(1,&udev->dev,
if (!(cardp->tx_urb = usb_alloc_urb(0, GFP_KERNEL))) {
lbs_deb_usbd(&udev->dev,
"Tx URB allocation failed\n");
goto dealloc;
}
usb_cardp->bulk_out_size =
endpoint->wMaxPacketSize;
lbs_dev_dbg(1, &udev->dev,
cardp->bulk_out_size =
le16_to_cpu(endpoint->wMaxPacketSize);
lbs_deb_usbd(&udev->dev,
"Bulk out size is %d\n",
endpoint->wMaxPacketSize);
usb_cardp->bulk_out_endpointAddr =
le16_to_cpu(endpoint->wMaxPacketSize));
cardp->bulk_out_endpointAddr =
endpoint->bEndpointAddress;
lbs_dev_dbg(1, &udev->dev, "out_endpoint = %d\n",
lbs_deb_usbd(&udev->dev, "out_endpoint = %d\n",
endpoint->bEndpointAddress);
usb_cardp->bulk_out_buffer =
cardp->bulk_out_buffer =
kmalloc(MRVDRV_ETH_TX_PACKET_BUFFER_SIZE,
GFP_KERNEL);
if (!usb_cardp->bulk_out_buffer) {
lbs_dev_dbg(1, &udev->dev,
if (!cardp->bulk_out_buffer) {
lbs_deb_usbd(&udev->dev,
"Could not allocate buffer\n");
goto dealloc;
}
}
}
/* At this point wlan_add_card() will be called. Don't worry
* about keeping pwlanpriv around since it will be set on our
* usb device data in -> add() -> libertas_sbi_register_dev().
*/
if (!(pwlanpriv = wlan_add_card(usb_cardp)))
if (!(priv = libertas_add_card(cardp, &udev->dev)))
goto dealloc;
if (libertas_add_mesh(priv, &udev->dev))
goto err_add_mesh;
priv->hw_register_dev = if_usb_register_dev;
priv->hw_unregister_dev = if_usb_unregister_dev;
priv->hw_prog_firmware = if_usb_prog_firmware;
priv->hw_host_to_card = if_usb_host_to_card;
priv->hw_get_int_status = if_usb_get_int_status;
priv->hw_read_event_cause = if_usb_read_event_cause;
if (libertas_activate_card(priv, libertas_fw_name))
goto err_activate_card;
list_add_tail(&cardp->list, &usb_devices);
usb_get_dev(udev);
usb_set_intfdata(intf, usb_cardp);
usb_set_intfdata(intf, cardp);
/*
* return card structure, which can be got back in the
* diconnect function as the ptr
* argument.
*/
return 0;
err_activate_card:
libertas_remove_mesh(priv);
err_add_mesh:
free_netdev(priv->dev);
kfree(priv->adapter);
dealloc:
if_usb_free(usb_cardp);
if_usb_free(cardp);
error:
return -ENOMEM;
......@@ -212,8 +240,7 @@ static int if_usb_probe(struct usb_interface *intf,
/**
* @brief free resource and cleanup
* @param udev pointer to usb_device
* @param ptr pointer to usb_cardp
* @param intf USB interface structure
* @return N/A
*/
static void if_usb_disconnect(struct usb_interface *intf)
......@@ -229,9 +256,12 @@ static void if_usb_disconnect(struct usb_interface *intf)
*/
adapter->surpriseremoved = 1;
list_del(&cardp->list);
/* card is removed and we can call wlan_remove_card */
lbs_dev_dbg(1, &cardp->udev->dev, "call remove card\n");
wlan_remove_card(cardp);
lbs_deb_usbd(&cardp->udev->dev, "call remove card\n");
libertas_remove_mesh(priv);
libertas_remove_card(priv);
/* Unlink and free urb */
if_usb_free(cardp);
......@@ -249,7 +279,7 @@ static void if_usb_disconnect(struct usb_interface *intf)
*/
static int if_prog_firmware(wlan_private * priv)
{
struct usb_card_rec *cardp = priv->wlan_dev.card;
struct usb_card_rec *cardp = priv->card;
struct FWData *fwdata;
struct fwheader *fwheader;
u8 *firmware = priv->firmware->data;
......@@ -266,8 +296,10 @@ static int if_prog_firmware(wlan_private * priv)
cardp->fwseqnum = cardp->lastseqnum - 1;
}
lbs_dev_dbg(2, &cardp->udev->dev, "totalbytes = %d\n",
/*
lbs_deb_usbd(&cardp->udev->dev, "totalbytes = %d\n",
cardp->totalbytes);
*/
memcpy(fwheader, &firmware[cardp->totalbytes],
sizeof(struct fwheader));
......@@ -275,40 +307,48 @@ static int if_prog_firmware(wlan_private * priv)
cardp->fwlastblksent = cardp->totalbytes;
cardp->totalbytes += sizeof(struct fwheader);
lbs_dev_dbg(2, &cardp->udev->dev,"Copy Data\n");
/* lbs_deb_usbd(&cardp->udev->dev,"Copy Data\n"); */
memcpy(fwdata->data, &firmware[cardp->totalbytes],
fwdata->fwheader.datalength);
le32_to_cpu(fwdata->fwheader.datalength));
lbs_dev_dbg(2, &cardp->udev->dev,
"Data length = %d\n", fwdata->fwheader.datalength);
/*
lbs_deb_usbd(&cardp->udev->dev,
"Data length = %d\n", le32_to_cpu(fwdata->fwheader.datalength));
*/
cardp->fwseqnum = cardp->fwseqnum + 1;
fwdata->seqnum = cardp->fwseqnum;
cardp->lastseqnum = fwdata->seqnum;
cardp->totalbytes += fwdata->fwheader.datalength;
fwdata->seqnum = cpu_to_le32(cardp->fwseqnum);
cardp->lastseqnum = cardp->fwseqnum;
cardp->totalbytes += le32_to_cpu(fwdata->fwheader.datalength);
if (fwheader->dnldcmd == FW_HAS_DATA_TO_RECV) {
lbs_dev_dbg(2, &cardp->udev->dev, "There is data to follow\n");
lbs_dev_dbg(2, &cardp->udev->dev,
if (fwheader->dnldcmd == cpu_to_le32(FW_HAS_DATA_TO_RECV)) {
/*
lbs_deb_usbd(&cardp->udev->dev, "There are data to follow\n");
lbs_deb_usbd(&cardp->udev->dev,
"seqnum = %d totalbytes = %d\n", cardp->fwseqnum,
cardp->totalbytes);
*/
memcpy(cardp->bulk_out_buffer, fwheader, FW_DATA_XMIT_SIZE);
usb_tx_block(priv, cardp->bulk_out_buffer, FW_DATA_XMIT_SIZE);
} else if (fwdata->fwheader.dnldcmd == FW_HAS_LAST_BLOCK) {
lbs_dev_dbg(2, &cardp->udev->dev,
} else if (fwdata->fwheader.dnldcmd == cpu_to_le32(FW_HAS_LAST_BLOCK)) {
/*
lbs_deb_usbd(&cardp->udev->dev,
"Host has finished FW downloading\n");
lbs_dev_dbg(2, &cardp->udev->dev,
lbs_deb_usbd(&cardp->udev->dev,
"Donwloading FW JUMP BLOCK\n");
*/
memcpy(cardp->bulk_out_buffer, fwheader, FW_DATA_XMIT_SIZE);
usb_tx_block(priv, cardp->bulk_out_buffer, FW_DATA_XMIT_SIZE);
cardp->fwfinalblk = 1;
}
lbs_dev_dbg(2, &cardp->udev->dev,
/*
lbs_deb_usbd(&cardp->udev->dev,
"The firmware download is done size is %d\n",
cardp->totalbytes);
*/
kfree(fwdata);
......@@ -318,14 +358,19 @@ static int if_prog_firmware(wlan_private * priv)
static int libertas_do_reset(wlan_private *priv)
{
int ret;
struct usb_card_rec *cardp = priv->wlan_dev.card;
struct usb_card_rec *cardp = priv->card;
lbs_deb_enter(LBS_DEB_USB);
ret = usb_reset_device(cardp->udev);
if (!ret) {
msleep(10);
reset_device(priv);
if_usb_reset_device(priv);
msleep(10);
}
lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret);
return ret;
}
......@@ -339,12 +384,12 @@ static int libertas_do_reset(wlan_private *priv)
int usb_tx_block(wlan_private * priv, u8 * payload, u16 nb)
{
/* pointer to card structure */
struct usb_card_rec *cardp = priv->wlan_dev.card;
struct usb_card_rec *cardp = priv->card;
int ret = -1;
/* check if device is removed */
if (priv->adapter->surpriseremoved) {
lbs_dev_dbg(1, &cardp->udev->dev, "Device removed\n");
lbs_deb_usbd(&cardp->udev->dev, "Device removed\n");
goto tx_ret;
}
......@@ -357,10 +402,10 @@ int usb_tx_block(wlan_private * priv, u8 * payload, u16 nb)
if ((ret = usb_submit_urb(cardp->tx_urb, GFP_ATOMIC))) {
/* transfer failed */
lbs_dev_dbg(1, &cardp->udev->dev, "usb_submit_urb failed\n");
lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb failed\n");
ret = -1;
} else {
lbs_dev_dbg(2, &cardp->udev->dev, "usb_submit_urb success\n");
/* lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb success\n"); */
ret = 0;
}
......@@ -372,7 +417,7 @@ static int __if_usb_submit_rx_urb(wlan_private * priv,
void (*callbackfn)
(struct urb *urb))
{
struct usb_card_rec *cardp = priv->wlan_dev.card;
struct usb_card_rec *cardp = priv->card;
struct sk_buff *skb;
struct read_cb_info *rinfo = &cardp->rinfo;
int ret = -1;
......@@ -394,13 +439,13 @@ static int __if_usb_submit_rx_urb(wlan_private * priv,
cardp->rx_urb->transfer_flags |= URB_ZERO_PACKET;
lbs_dev_dbg(2, &cardp->udev->dev, "Pointer for rx_urb %p\n", cardp->rx_urb);
/* lbs_deb_usbd(&cardp->udev->dev, "Pointer for rx_urb %p\n", cardp->rx_urb); */
if ((ret = usb_submit_urb(cardp->rx_urb, GFP_ATOMIC))) {
/* handle failure conditions */
lbs_dev_dbg(1, &cardp->udev->dev, "Submit Rx URB failed\n");
lbs_deb_usbd(&cardp->udev->dev, "Submit Rx URB failed\n");
ret = -1;
} else {
lbs_dev_dbg(2, &cardp->udev->dev, "Submit Rx URB success\n");
/* lbs_deb_usbd(&cardp->udev->dev, "Submit Rx URB success\n"); */
ret = 0;
}
......@@ -423,12 +468,12 @@ static void if_usb_receive_fwload(struct urb *urb)
struct read_cb_info *rinfo = (struct read_cb_info *)urb->context;
wlan_private *priv = rinfo->priv;
struct sk_buff *skb = rinfo->skb;
struct usb_card_rec *cardp = (struct usb_card_rec *)priv->wlan_dev.card;
struct usb_card_rec *cardp = (struct usb_card_rec *)priv->card;
struct fwsyncheader *syncfwheader;
struct bootcmdrespStr bootcmdresp;
if (urb->status) {
lbs_dev_dbg(1, &cardp->udev->dev,
lbs_deb_usbd(&cardp->udev->dev,
"URB status is failed during fw load\n");
kfree_skb(skb);
return;
......@@ -437,18 +482,18 @@ static void if_usb_receive_fwload(struct urb *urb)
if (cardp->bootcmdresp == 0) {
memcpy (&bootcmdresp, skb->data + IPFIELD_ALIGN_OFFSET,
sizeof(bootcmdresp));
if (cardp->udev->descriptor.bcdDevice < 0x3106) {
if (le16_to_cpu(cardp->udev->descriptor.bcdDevice) < 0x3106) {
kfree_skb(skb);
if_usb_submit_rx_urb_fwload(priv);
cardp->bootcmdresp = 1;
lbs_dev_dbg(1, &cardp->udev->dev,
lbs_deb_usbd(&cardp->udev->dev,
"Received valid boot command response\n");
return;
}
if (bootcmdresp.u32magicnumber != BOOT_CMD_MAGIC_NUMBER) {
if (bootcmdresp.u32magicnumber != cpu_to_le32(BOOT_CMD_MAGIC_NUMBER)) {
lbs_pr_info(
"boot cmd response wrong magic number (0x%x)\n",
bootcmdresp.u32magicnumber);
le32_to_cpu(bootcmdresp.u32magicnumber));
} else if (bootcmdresp.u8cmd_tag != BOOT_CMD_FW_BY_USB) {
lbs_pr_info(
"boot cmd response cmd_tag error (%d)\n",
......@@ -459,7 +504,7 @@ static void if_usb_receive_fwload(struct urb *urb)
bootcmdresp.u8result);
} else {
cardp->bootcmdresp = 1;
lbs_dev_dbg(1, &cardp->udev->dev,
lbs_deb_usbd(&cardp->udev->dev,
"Received valid boot command response\n");
}
kfree_skb(skb);
......@@ -469,7 +514,7 @@ static void if_usb_receive_fwload(struct urb *urb)
syncfwheader = kmalloc(sizeof(struct fwsyncheader), GFP_ATOMIC);
if (!syncfwheader) {
lbs_dev_dbg(1, &cardp->udev->dev, "Failure to allocate syncfwheader\n");
lbs_deb_usbd(&cardp->udev->dev, "Failure to allocate syncfwheader\n");
kfree_skb(skb);
return;
}
......@@ -478,14 +523,16 @@ static void if_usb_receive_fwload(struct urb *urb)
sizeof(struct fwsyncheader));
if (!syncfwheader->cmd) {
lbs_dev_dbg(2, &cardp->udev->dev,
/*
lbs_deb_usbd(&cardp->udev->dev,
"FW received Blk with correct CRC\n");
lbs_dev_dbg(2, &cardp->udev->dev,
lbs_deb_usbd(&cardp->udev->dev,
"FW received Blk seqnum = %d\n",
syncfwheader->seqnum);
*/
cardp->CRC_OK = 1;
} else {
lbs_dev_dbg(1, &cardp->udev->dev,
lbs_deb_usbd(&cardp->udev->dev,
"FW received Blk with CRC error\n");
cardp->CRC_OK = 0;
}
......@@ -515,7 +562,7 @@ static inline void process_cmdtypedata(int recvlength, struct sk_buff *skb,
{
if (recvlength > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE +
MESSAGE_HEADER_LEN || recvlength < MRVDRV_MIN_PKT_LEN) {
lbs_dev_dbg(1, &cardp->udev->dev,
lbs_deb_usbd(&cardp->udev->dev,
"Packet length is Invalid\n");
kfree_skb(skb);
return;
......@@ -525,7 +572,7 @@ static inline void process_cmdtypedata(int recvlength, struct sk_buff *skb,
skb_put(skb, recvlength);
skb_pull(skb, MESSAGE_HEADER_LEN);
libertas_process_rxed_packet(priv, skb);
priv->wlan_dev.upld_len = (recvlength - MESSAGE_HEADER_LEN);
priv->upld_len = (recvlength - MESSAGE_HEADER_LEN);
}
static inline void process_cmdrequest(int recvlength, u8 *recvbuff,
......@@ -535,7 +582,7 @@ static inline void process_cmdrequest(int recvlength, u8 *recvbuff,
{
u8 *cmdbuf;
if (recvlength > MRVDRV_SIZE_OF_CMD_BUFFER) {
lbs_dev_dbg(1, &cardp->udev->dev,
lbs_deb_usbd(&cardp->udev->dev,
"The receive buffer is too large\n");
kfree_skb(skb);
return;
......@@ -548,21 +595,21 @@ static inline void process_cmdrequest(int recvlength, u8 *recvbuff,
/* take care of cur_cmd = NULL case by reading the
* data to clear the interrupt */
if (!priv->adapter->cur_cmd) {
cmdbuf = priv->wlan_dev.upld_buf;
cmdbuf = priv->upld_buf;
priv->adapter->hisregcpy &= ~his_cmdupldrdy;
} else
cmdbuf = priv->adapter->cur_cmd->bufvirtualaddr;
cardp->usb_int_cause |= his_cmdupldrdy;
priv->wlan_dev.upld_len = (recvlength - MESSAGE_HEADER_LEN);
priv->upld_len = (recvlength - MESSAGE_HEADER_LEN);
memcpy(cmdbuf, recvbuff + MESSAGE_HEADER_LEN,
priv->wlan_dev.upld_len);
priv->upld_len);
kfree_skb(skb);
libertas_interrupt(priv->wlan_dev.netdev);
libertas_interrupt(priv->dev);
spin_unlock(&priv->adapter->driver_lock);
lbs_dev_dbg(1, &cardp->udev->dev,
lbs_deb_usbd(&cardp->udev->dev,
"Wake up main thread to handle cmd response\n");
return;
......@@ -580,17 +627,17 @@ static void if_usb_receive(struct urb *urb)
struct read_cb_info *rinfo = (struct read_cb_info *)urb->context;
wlan_private *priv = rinfo->priv;
struct sk_buff *skb = rinfo->skb;
struct usb_card_rec *cardp = (struct usb_card_rec *)priv->wlan_dev.card;
struct usb_card_rec *cardp = (struct usb_card_rec *)priv->card;
int recvlength = urb->actual_length;
u8 *recvbuff = NULL;
u32 recvtype;
ENTER();
lbs_deb_enter(LBS_DEB_USB);
if (recvlength) {
if (urb->status) {
lbs_dev_dbg(1, &cardp->udev->dev,
lbs_deb_usbd(&cardp->udev->dev,
"URB status is failed\n");
kfree_skb(skb);
goto setup_for_next;
......@@ -598,12 +645,12 @@ static void if_usb_receive(struct urb *urb)
recvbuff = skb->data + IPFIELD_ALIGN_OFFSET;
memcpy(&recvtype, recvbuff, sizeof(u32));
lbs_dev_dbg(1, &cardp->udev->dev,
lbs_deb_usbd(&cardp->udev->dev,
"Recv length = 0x%x\n", recvlength);
lbs_dev_dbg(1, &cardp->udev->dev,
lbs_deb_usbd(&cardp->udev->dev,
"Receive type = 0x%X\n", recvtype);
recvtype = le32_to_cpu(recvtype);
lbs_dev_dbg(1, &cardp->udev->dev,
lbs_deb_usbd(&cardp->udev->dev,
"Receive type after = 0x%X\n", recvtype);
} else if (urb->status)
goto rx_exit;
......@@ -621,18 +668,18 @@ static void if_usb_receive(struct urb *urb)
case CMD_TYPE_INDICATION:
/* Event cause handling */
spin_lock(&priv->adapter->driver_lock);
cardp->usb_event_cause = *(u32 *) (recvbuff + MESSAGE_HEADER_LEN);
lbs_dev_dbg(1, &cardp->udev->dev,"**EVENT** 0x%X\n",
cardp->usb_event_cause = le32_to_cpu(*(__le32 *) (recvbuff + MESSAGE_HEADER_LEN));
lbs_deb_usbd(&cardp->udev->dev,"**EVENT** 0x%X\n",
cardp->usb_event_cause);
if (cardp->usb_event_cause & 0xffff0000) {
libertas_send_tx_feedback(priv);
spin_unlock(&priv->adapter->driver_lock);
break;
}
cardp->usb_event_cause = le32_to_cpu(cardp->usb_event_cause) << 3;
cardp->usb_event_cause <<= 3;
cardp->usb_int_cause |= his_cardevent;
kfree_skb(skb);
libertas_interrupt(priv->wlan_dev.netdev);
libertas_interrupt(priv->dev);
spin_unlock(&priv->adapter->driver_lock);
goto rx_exit;
default:
......@@ -643,8 +690,7 @@ static void if_usb_receive(struct urb *urb)
setup_for_next:
if_usb_submit_rx_urb(priv);
rx_exit:
LEAVE();
return;
lbs_deb_leave(LBS_DEB_USB);
}
/**
......@@ -655,24 +701,24 @@ static void if_usb_receive(struct urb *urb)
* @param len number of bytes
* @return 0 or -1
*/
int libertas_sbi_host_to_card(wlan_private * priv, u8 type, u8 * payload, u16 nb)
static int if_usb_host_to_card(wlan_private * priv, u8 type, u8 * payload, u16 nb)
{
int ret = -1;
u32 tmp;
struct usb_card_rec *cardp = (struct usb_card_rec *)priv->wlan_dev.card;
struct usb_card_rec *cardp = (struct usb_card_rec *)priv->card;
lbs_dev_dbg(1, &cardp->udev->dev,"*** type = %u\n", type);
lbs_dev_dbg(1, &cardp->udev->dev,"size after = %d\n", nb);
lbs_deb_usbd(&cardp->udev->dev,"*** type = %u\n", type);
lbs_deb_usbd(&cardp->udev->dev,"size after = %d\n", nb);
if (type == MVMS_CMD) {
tmp = cpu_to_le32(CMD_TYPE_REQUEST);
priv->wlan_dev.dnld_sent = DNLD_CMD_SENT;
priv->dnld_sent = DNLD_CMD_SENT;
memcpy(cardp->bulk_out_buffer, (u8 *) & tmp,
MESSAGE_HEADER_LEN);
} else {
tmp = cpu_to_le32(CMD_TYPE_DATA);
priv->wlan_dev.dnld_sent = DNLD_DATA_SENT;
priv->dnld_sent = DNLD_DATA_SENT;
memcpy(cardp->bulk_out_buffer, (u8 *) & tmp,
MESSAGE_HEADER_LEN);
}
......@@ -686,39 +732,41 @@ int libertas_sbi_host_to_card(wlan_private * priv, u8 type, u8 * payload, u16 nb
}
/* called with adapter->driver_lock held */
int libertas_sbi_get_int_status(wlan_private * priv, u8 * ireg)
static int if_usb_get_int_status(wlan_private * priv, u8 * ireg)
{
struct usb_card_rec *cardp = priv->wlan_dev.card;
struct usb_card_rec *cardp = priv->card;
*ireg = cardp->usb_int_cause;
cardp->usb_int_cause = 0;
lbs_dev_dbg(1, &cardp->udev->dev,"Int cause is 0x%X\n", *ireg);
lbs_deb_usbd(&cardp->udev->dev,"Int cause is 0x%X\n", *ireg);
return 0;
}
int libertas_sbi_read_event_cause(wlan_private * priv)
static int if_usb_read_event_cause(wlan_private * priv)
{
struct usb_card_rec *cardp = priv->wlan_dev.card;
struct usb_card_rec *cardp = priv->card;
priv->adapter->eventcause = cardp->usb_event_cause;
/* Re-submit rx urb here to avoid event lost issue */
if_usb_submit_rx_urb(priv);
return 0;
}
int reset_device(wlan_private *priv)
static int if_usb_reset_device(wlan_private *priv)
{
int ret;
lbs_deb_enter(LBS_DEB_USB);
ret = libertas_prepare_and_send_command(priv, cmd_802_11_reset,
cmd_act_halt, 0, 0, NULL);
msleep_interruptible(10);
lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret);
return ret;
}
int libertas_sbi_unregister_dev(wlan_private * priv)
static int if_usb_unregister_dev(wlan_private * priv)
{
int ret = 0;
......@@ -727,7 +775,7 @@ int libertas_sbi_unregister_dev(wlan_private * priv)
* again.
*/
if (priv)
reset_device(priv);
if_usb_reset_device(priv);
return ret;
}
......@@ -738,42 +786,41 @@ int libertas_sbi_unregister_dev(wlan_private * priv)
* @param priv pointer to wlan_private
* @return 0 or -1
*/
int libertas_sbi_register_dev(wlan_private * priv)
static int if_usb_register_dev(wlan_private * priv)
{
struct usb_card_rec *cardp = (struct usb_card_rec *)priv->card;
struct usb_card_rec *cardp = (struct usb_card_rec *)priv->wlan_dev.card;
ENTER();
lbs_deb_enter(LBS_DEB_USB);
cardp->priv = priv;
cardp->eth_dev = priv->wlan_dev.netdev;
cardp->eth_dev = priv->dev;
priv->hotplug_device = &(cardp->udev->dev);
SET_NETDEV_DEV(cardp->eth_dev, &(cardp->udev->dev));
lbs_dev_dbg(1, &cardp->udev->dev, "udev pointer is at %p\n",
lbs_deb_usbd(&cardp->udev->dev, "udev pointer is at %p\n",
cardp->udev);
LEAVE();
lbs_deb_leave(LBS_DEB_USB);
return 0;
}
int libertas_sbi_prog_firmware(wlan_private * priv)
static int if_usb_prog_firmware(wlan_private * priv)
{
struct usb_card_rec *cardp = priv->wlan_dev.card;
struct usb_card_rec *cardp = priv->card;
int i = 0;
static int reset_count = 10;
int ret = 0;
ENTER();
lbs_deb_enter(LBS_DEB_USB);
cardp->rinfo.priv = priv;
restart:
if (if_usb_submit_rx_urb_fwload(priv) < 0) {
lbs_dev_dbg(1, &cardp->udev->dev, "URB submission is failed\n");
LEAVE();
return -1;
lbs_deb_usbd(&cardp->udev->dev, "URB submission is failed\n");
ret = -1;
goto done;
}
cardp->bootcmdresp = 0;
......@@ -811,7 +858,7 @@ int libertas_sbi_prog_firmware(wlan_private * priv)
if_prog_firmware(priv);
do {
lbs_dev_dbg(1, &cardp->udev->dev,"Wlan sched timeout\n");
lbs_deb_usbd(&cardp->udev->dev,"Wlan sched timeout\n");
i++;
msleep_interruptible(100);
if (priv->adapter->surpriseremoved || i >= 20)
......@@ -826,8 +873,8 @@ int libertas_sbi_prog_firmware(wlan_private * priv)
}
lbs_pr_info("FW download failure, time = %d ms\n", i * 100);
LEAVE();
return -1;
ret = -1;
goto done;
}
if_usb_submit_rx_urb(priv);
......@@ -837,32 +884,10 @@ int libertas_sbi_prog_firmware(wlan_private * priv)
priv->adapter->fw_ready = 1;
LEAVE();
return 0;
}
/**
* @brief Given a usb_card_rec return its wlan_private
* @param card pointer to a usb_card_rec
* @return pointer to wlan_private
*/
wlan_private *libertas_sbi_get_priv(void *card)
{
struct usb_card_rec *cardp = card;
return cardp->priv;
}
#ifdef ENABLE_PM
int libertas_sbi_suspend(wlan_private * priv)
{
return 0;
}
int libertas_sbi_resume(wlan_private * priv)
{
return 0;
done:
lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret);
return ret;
}
#endif
#ifdef CONFIG_PM
static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
......@@ -870,12 +895,13 @@ static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
struct usb_card_rec *cardp = usb_get_intfdata(intf);
wlan_private *priv = cardp->priv;
ENTER();
lbs_deb_enter(LBS_DEB_USB);
if (priv->adapter->psstate != PS_STATE_FULL_POWER)
return -1;
netif_device_detach(cardp->eth_dev);
netif_device_detach(priv->mesh_dev);
/* Unlink tx & rx urb */
usb_kill_urb(cardp->tx_urb);
......@@ -883,23 +909,25 @@ static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
cardp->rx_urb_recall = 1;
LEAVE();
lbs_deb_leave(LBS_DEB_USB);
return 0;
}
static int if_usb_resume(struct usb_interface *intf)
{
struct usb_card_rec *cardp = usb_get_intfdata(intf);
wlan_private *priv = cardp->priv;
ENTER();
lbs_deb_enter(LBS_DEB_USB);
cardp->rx_urb_recall = 0;
if_usb_submit_rx_urb(cardp->priv);
netif_device_attach(cardp->eth_dev);
netif_device_attach(priv->mesh_dev);
LEAVE();
lbs_deb_leave(LBS_DEB_USB);
return 0;
}
#else
......@@ -920,32 +948,40 @@ static struct usb_driver if_usb_driver = {
.resume = if_usb_resume,
};
/**
* @brief This function registers driver.
* @param add pointer to add_card callback function
* @param remove pointer to remove card callback function
* @param arg pointer to call back function parameter
* @return dummy success variable
*/
int libertas_sbi_register(void)
static int if_usb_init_module(void)
{
/*
* API registers the Marvell USB driver
* to the USB system
*/
usb_register(&if_usb_driver);
int ret = 0;
/* Return success to wlan layer */
return 0;
lbs_deb_enter(LBS_DEB_MAIN);
if (libertas_fw_name == NULL) {
libertas_fw_name = default_fw_name;
}
ret = usb_register(&if_usb_driver);
lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
return ret;
}
/**
* @brief This function removes usb driver.
* @return N/A
*/
void libertas_sbi_unregister(void)
static void if_usb_exit_module(void)
{
struct usb_card_rec *cardp, *cardp_temp;
lbs_deb_enter(LBS_DEB_MAIN);
list_for_each_entry_safe(cardp, cardp_temp, &usb_devices, list)
if_usb_reset_device((wlan_private *) cardp->priv);
/* API unregisters the driver from USB subsystem */
usb_deregister(&if_usb_driver);
return;
lbs_deb_leave(LBS_DEB_MAIN);
}
module_init(if_usb_init_module);
module_exit(if_usb_exit_module);
MODULE_DESCRIPTION("8388 USB WLAN Driver");
MODULE_AUTHOR("Marvell International Ltd.");
MODULE_LICENSE("GPL");
#ifndef _LIBERTAS_IF_USB_H
#define _LIBERTAS_IF_USB_H
#include <linux/list.h>
/**
* This file contains definition for USB interface.
*/
......@@ -7,11 +12,6 @@
#define IPFIELD_ALIGN_OFFSET 2
#define USB8388_VID_1 0x1286
#define USB8388_PID_1 0x2001
#define USB8388_VID_2 0x05a3
#define USB8388_PID_2 0x8388
#define BOOT_CMD_FW_BY_USB 0x01
#define BOOT_CMD_FW_IN_EEPROM 0x02
#define BOOT_CMD_UPDATE_BOOT2 0x03
......@@ -20,7 +20,7 @@
struct bootcmdstr
{
u32 u32magicnumber;
__le32 u32magicnumber;
u8 u8cmd_tag;
u8 au8dumy[11];
};
......@@ -30,7 +30,7 @@ struct bootcmdstr
struct bootcmdrespStr
{
u32 u32magicnumber;
__le32 u32magicnumber;
u8 u8cmd_tag;
u8 u8result;
u8 au8dumy[2];
......@@ -44,6 +44,7 @@ struct read_cb_info {
/** USB card description structure*/
struct usb_card_rec {
struct list_head list;
struct net_device *eth_dev;
struct usb_device *udev;
struct urb *rx_urb, *tx_urb;
......@@ -75,33 +76,34 @@ struct usb_card_rec {
/** fwheader */
struct fwheader {
u32 dnldcmd;
u32 baseaddr;
u32 datalength;
u32 CRC;
__le32 dnldcmd;
__le32 baseaddr;
__le32 datalength;
__le32 CRC;
};
#define FW_MAX_DATA_BLK_SIZE 600
/** FWData */
struct FWData {
struct fwheader fwheader;
u32 seqnum;
__le32 seqnum;
u8 data[FW_MAX_DATA_BLK_SIZE];
};
/** fwsyncheader */
struct fwsyncheader {
u32 cmd;
u32 seqnum;
__le32 cmd;
__le32 seqnum;
};
#define FW_HAS_DATA_TO_RECV 0x00000001
#define FW_HAS_LAST_BLOCK 0x00000004
#define FW_DATA_XMIT_SIZE \
sizeof(struct fwheader) + fwdata->fwheader.datalength + sizeof(u32)
sizeof(struct fwheader) + le32_to_cpu(fwdata->fwheader.datalength) + sizeof(u32)
int usb_tx_block(wlan_private *priv, u8 *payload, u16 nb);
void if_usb_free(struct usb_card_rec *cardp);
int if_usb_issue_boot_command(wlan_private *priv, int ivalue);
#endif
......@@ -30,6 +30,7 @@
static int wlan_set_region(wlan_private * priv, u16 region_code)
{
int i;
int ret = 0;
for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) {
// use the region code to search for the index
......@@ -42,17 +43,18 @@ static int wlan_set_region(wlan_private * priv, u16 region_code)
// if it's unidentified region code
if (i >= MRVDRV_MAX_REGION_CODE) {
lbs_pr_debug(1, "region Code not identified\n");
LEAVE();
return -1;
lbs_deb_ioctl("region Code not identified\n");
ret = -1;
goto done;
}
if (libertas_set_regiontable(priv, priv->adapter->regioncode, 0)) {
LEAVE();
return -EINVAL;
ret = -EINVAL;
}
return 0;
done:
lbs_deb_leave_args(LBS_DEB_IOCTL, "ret %d", ret);
return ret;
}
static inline int hex2int(char c)
......@@ -125,8 +127,10 @@ static int wlan_bt_add_ioctl(wlan_private * priv, struct ifreq *req)
char ethaddrs_str[18];
char *pos;
u8 ethaddr[ETH_ALEN];
int ret;
lbs_deb_enter(LBS_DEB_IOCTL);
ENTER();
if (copy_from_user(ethaddrs_str, wrq->u.data.pointer,
sizeof(ethaddrs_str)))
return -EFAULT;
......@@ -136,11 +140,12 @@ static int wlan_bt_add_ioctl(wlan_private * priv, struct ifreq *req)
return -EINVAL;
}
lbs_pr_debug(1, "BT: adding %s\n", ethaddrs_str);
LEAVE();
return (libertas_prepare_and_send_command(priv, cmd_bt_access,
lbs_deb_ioctl("BT: adding %s\n", ethaddrs_str);
ret = libertas_prepare_and_send_command(priv, cmd_bt_access,
cmd_act_bt_access_add,
cmd_option_waitforrsp, 0, ethaddr));
cmd_option_waitforrsp, 0, ethaddr);
lbs_deb_leave_args(LBS_DEB_IOCTL, "ret %d", ret);
return ret;
}
/**
......@@ -156,7 +161,8 @@ static int wlan_bt_del_ioctl(wlan_private * priv, struct ifreq *req)
u8 ethaddr[ETH_ALEN];
char *pos;
ENTER();
lbs_deb_enter(LBS_DEB_IOCTL);
if (copy_from_user(ethaddrs_str, wrq->u.data.pointer,
sizeof(ethaddrs_str)))
return -EFAULT;
......@@ -166,13 +172,14 @@ static int wlan_bt_del_ioctl(wlan_private * priv, struct ifreq *req)
return -EINVAL;
}
lbs_pr_debug(1, "BT: deleting %s\n", ethaddrs_str);
lbs_deb_ioctl("BT: deleting %s\n", ethaddrs_str);
return (libertas_prepare_and_send_command(priv,
cmd_bt_access,
cmd_act_bt_access_del,
cmd_option_waitforrsp, 0, ethaddr));
LEAVE();
lbs_deb_leave(LBS_DEB_IOCTL);
return 0;
}
......@@ -183,7 +190,7 @@ static int wlan_bt_del_ioctl(wlan_private * priv, struct ifreq *req)
*/
static int wlan_bt_reset_ioctl(wlan_private * priv)
{
ENTER();
lbs_deb_enter(LBS_DEB_IOCTL);
lbs_pr_alert( "BT: resetting\n");
......@@ -192,7 +199,7 @@ static int wlan_bt_reset_ioctl(wlan_private * priv)
cmd_act_bt_access_reset,
cmd_option_waitforrsp, 0, NULL));
LEAVE();
lbs_deb_leave(LBS_DEB_IOCTL);
return 0;
}
......@@ -209,17 +216,17 @@ static int wlan_bt_list_ioctl(wlan_private * priv, struct ifreq *req)
struct iwreq *wrq = (struct iwreq *)req;
/* used to pass id and store the bt entry returned by the FW */
union {
int id;
u32 id;
char addr1addr2[2 * ETH_ALEN];
} param;
static char outstr[64];
char *pbuf = outstr;
int ret;
ENTER();
lbs_deb_enter(LBS_DEB_IOCTL);
if (copy_from_user(outstr, wrq->u.data.pointer, sizeof(outstr))) {
lbs_pr_debug(1, "Copy from user failed\n");
lbs_deb_ioctl("Copy from user failed\n");
return -1;
}
param.id = simple_strtoul(outstr, NULL, 10);
......@@ -234,7 +241,7 @@ static int wlan_bt_list_ioctl(wlan_private * priv, struct ifreq *req)
if (ret == 0) {
addr1 = param.addr1addr2;
pos = sprintf(pbuf, "ignoring traffic from ");
pos = sprintf(pbuf, "BT includes node ");
pbuf += pos;
pos = eth_addr2str(addr1, pbuf);
pbuf += pos;
......@@ -246,11 +253,70 @@ static int wlan_bt_list_ioctl(wlan_private * priv, struct ifreq *req)
wrq->u.data.length = strlen(outstr);
if (copy_to_user(wrq->u.data.pointer, (char *)outstr,
wrq->u.data.length)) {
lbs_pr_debug(1, "BT_LIST: Copy to user failed!\n");
lbs_deb_ioctl("BT_LIST: Copy to user failed!\n");
return -EFAULT;
}
LEAVE();
lbs_deb_leave(LBS_DEB_IOCTL);
return 0 ;
}
/**
* @brief Sets inverted state of blacklist (non-zero if inverted)
* @param priv A pointer to wlan_private structure
* @param req A pointer to ifreq structure
* @return 0 --success, otherwise fail
*/
static int wlan_bt_set_invert_ioctl(wlan_private * priv, struct ifreq *req)
{
int ret;
struct iwreq *wrq = (struct iwreq *)req;
union {
u32 id;
char addr1addr2[2 * ETH_ALEN];
} param;
lbs_deb_enter(LBS_DEB_IOCTL);
param.id = SUBCMD_DATA(wrq) ;
ret = libertas_prepare_and_send_command(priv, cmd_bt_access,
cmd_act_bt_access_set_invert,
cmd_option_waitforrsp, 0,
(char *)&param);
if (ret != 0)
return -EFAULT;
lbs_deb_leave(LBS_DEB_IOCTL);
return 0;
}
/**
* @brief Gets inverted state of blacklist (non-zero if inverted)
* @param priv A pointer to wlan_private structure
* @param req A pointer to ifreq structure
* @return 0 --success, otherwise fail
*/
static int wlan_bt_get_invert_ioctl(wlan_private * priv, struct ifreq *req)
{
struct iwreq *wrq = (struct iwreq *)req;
int ret;
union {
u32 id;
char addr1addr2[2 * ETH_ALEN];
} param;
lbs_deb_enter(LBS_DEB_IOCTL);
ret = libertas_prepare_and_send_command(priv, cmd_bt_access,
cmd_act_bt_access_get_invert,
cmd_option_waitforrsp, 0,
(char *)&param);
if (ret == 0)
wrq->u.param.value = le32_to_cpu(param.id);
else
return -EFAULT;
lbs_deb_leave(LBS_DEB_IOCTL);
return 0;
}
......@@ -278,8 +344,10 @@ static int wlan_fwt_add_ioctl(wlan_private * priv, struct ifreq *req)
char in_str[128];
static struct cmd_ds_fwt_access fwt_access;
char *ptr;
int ret;
lbs_deb_enter(LBS_DEB_IOCTL);
ENTER();
if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str)))
return -EFAULT;
......@@ -297,24 +365,29 @@ static int wlan_fwt_add_ioctl(wlan_private * priv, struct ifreq *req)
fwt_access.metric =
cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
else
fwt_access.metric = FWT_DEFAULT_METRIC;
fwt_access.metric = cpu_to_le32(FWT_DEFAULT_METRIC);
if ((ptr = next_param(ptr)))
fwt_access.dir = (u8)simple_strtoul(ptr, &ptr, 10);
else
fwt_access.dir = FWT_DEFAULT_DIR;
if ((ptr = next_param(ptr)))
fwt_access.rate = (u8) simple_strtoul(ptr, &ptr, 10);
else
fwt_access.rate = FWT_DEFAULT_RATE;
if ((ptr = next_param(ptr)))
fwt_access.ssn =
cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
else
fwt_access.ssn = FWT_DEFAULT_SSN;
fwt_access.ssn = cpu_to_le32(FWT_DEFAULT_SSN);
if ((ptr = next_param(ptr)))
fwt_access.dsn =
cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
else
fwt_access.dsn = FWT_DEFAULT_DSN;
fwt_access.dsn = cpu_to_le32(FWT_DEFAULT_DSN);
if ((ptr = next_param(ptr)))
fwt_access.hopcount = simple_strtoul(ptr, &ptr, 10);
......@@ -330,7 +403,7 @@ static int wlan_fwt_add_ioctl(wlan_private * priv, struct ifreq *req)
fwt_access.expiration =
cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
else
fwt_access.expiration = FWT_DEFAULT_EXPIRATION;
fwt_access.expiration = cpu_to_le32(FWT_DEFAULT_EXPIRATION);
if ((ptr = next_param(ptr)))
fwt_access.sleepmode = (u8)simple_strtoul(ptr, &ptr, 10);
......@@ -341,27 +414,29 @@ static int wlan_fwt_add_ioctl(wlan_private * priv, struct ifreq *req)
fwt_access.snr =
cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
else
fwt_access.snr = FWT_DEFAULT_SNR;
fwt_access.snr = cpu_to_le32(FWT_DEFAULT_SNR);
#ifdef DEBUG
{
char ethaddr1_str[18], ethaddr2_str[18];
eth_addr2str(fwt_access.da, ethaddr1_str);
eth_addr2str(fwt_access.ra, ethaddr2_str);
lbs_pr_debug(1, "FWT_ADD: adding (da:%s,%i,ra:%s)\n", ethaddr1_str,
lbs_deb_ioctl("FWT_ADD: adding (da:%s,%i,ra:%s)\n", ethaddr1_str,
fwt_access.dir, ethaddr2_str);
lbs_pr_debug(1, "FWT_ADD: ssn:%u dsn:%u met:%u hop:%u ttl:%u exp:%u slp:%u snr:%u\n",
lbs_deb_ioctl("FWT_ADD: ssn:%u dsn:%u met:%u hop:%u ttl:%u exp:%u slp:%u snr:%u\n",
fwt_access.ssn, fwt_access.dsn, fwt_access.metric,
fwt_access.hopcount, fwt_access.ttl, fwt_access.expiration,
fwt_access.sleepmode, fwt_access.snr);
}
#endif
LEAVE();
return (libertas_prepare_and_send_command(priv, cmd_fwt_access,
ret = libertas_prepare_and_send_command(priv, cmd_fwt_access,
cmd_act_fwt_access_add,
cmd_option_waitforrsp, 0,
(void *)&fwt_access));
(void *)&fwt_access);
lbs_deb_leave_args(LBS_DEB_IOCTL, "ret %d", ret);
return ret;
}
/**
......@@ -376,8 +451,10 @@ static int wlan_fwt_del_ioctl(wlan_private * priv, struct ifreq *req)
char in_str[64];
static struct cmd_ds_fwt_access fwt_access;
char *ptr;
int ret;
lbs_deb_enter(LBS_DEB_IOCTL);
ENTER();
if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str)))
return -EFAULT;
......@@ -399,20 +476,21 @@ static int wlan_fwt_del_ioctl(wlan_private * priv, struct ifreq *req)
#ifdef DEBUG
{
char ethaddr1_str[18], ethaddr2_str[18];
lbs_pr_debug(1, "FWT_DEL: line is %s\n", in_str);
lbs_deb_ioctl("FWT_DEL: line is %s\n", in_str);
eth_addr2str(fwt_access.da, ethaddr1_str);
eth_addr2str(fwt_access.ra, ethaddr2_str);
lbs_pr_debug(1, "FWT_DEL: removing (da:%s,ra:%s,dir:%d)\n", ethaddr1_str,
lbs_deb_ioctl("FWT_DEL: removing (da:%s,ra:%s,dir:%d)\n", ethaddr1_str,
ethaddr2_str, fwt_access.dir);
}
#endif
LEAVE();
return (libertas_prepare_and_send_command(priv,
ret = libertas_prepare_and_send_command(priv,
cmd_fwt_access,
cmd_act_fwt_access_del,
cmd_option_waitforrsp, 0,
(void *)&fwt_access));
(void *)&fwt_access);
lbs_deb_leave_args(LBS_DEB_IOCTL, "ret %d", ret);
return ret;
}
......@@ -427,15 +505,18 @@ static void print_route(struct cmd_ds_fwt_access fwt_access, char *buf)
buf += eth_addr2str(fwt_access.da, buf);
buf += sprintf(buf, " ");
buf += eth_addr2str(fwt_access.ra, buf);
buf += sprintf(buf, " %u", fwt_access.valid);
buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.metric));
buf += sprintf(buf, " %u", fwt_access.dir);
buf += sprintf(buf, " %u", fwt_access.rate);
buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.ssn));
buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.dsn));
buf += sprintf(buf, " %u", fwt_access.hopcount);
buf += sprintf(buf, " %u", fwt_access.ttl);
buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.expiration));
buf += sprintf(buf, " %u", fwt_access.sleepmode);
buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.snr));
buf += sprintf(buf, " %u ", le32_to_cpu(fwt_access.snr));
buf += eth_addr2str(fwt_access.prec, buf);
}
/**
......@@ -453,7 +534,8 @@ static int wlan_fwt_lookup_ioctl(wlan_private * priv, struct ifreq *req)
static char out_str[128];
int ret;
ENTER();
lbs_deb_enter(LBS_DEB_IOCTL);
if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str)))
return -EFAULT;
......@@ -465,9 +547,9 @@ static int wlan_fwt_lookup_ioctl(wlan_private * priv, struct ifreq *req)
#ifdef DEBUG
{
char ethaddr1_str[18];
lbs_pr_debug(1, "FWT_LOOKUP: line is %s\n", in_str);
lbs_deb_ioctl("FWT_LOOKUP: line is %s\n", in_str);
eth_addr2str(fwt_access.da, ethaddr1_str);
lbs_pr_debug(1, "FWT_LOOKUP: looking for (da:%s)\n", ethaddr1_str);
lbs_deb_ioctl("FWT_LOOKUP: looking for (da:%s)\n", ethaddr1_str);
}
#endif
......@@ -485,11 +567,11 @@ static int wlan_fwt_lookup_ioctl(wlan_private * priv, struct ifreq *req)
wrq->u.data.length = strlen(out_str);
if (copy_to_user(wrq->u.data.pointer, (char *)out_str,
wrq->u.data.length)) {
lbs_pr_debug(1, "FWT_LOOKUP: Copy to user failed!\n");
lbs_deb_ioctl("FWT_LOOKUP: Copy to user failed!\n");
return -EFAULT;
}
LEAVE();
lbs_deb_leave(LBS_DEB_IOCTL);
return 0;
}
......@@ -500,7 +582,7 @@ static int wlan_fwt_lookup_ioctl(wlan_private * priv, struct ifreq *req)
*/
static int wlan_fwt_reset_ioctl(wlan_private * priv)
{
lbs_pr_debug(1, "FWT: resetting\n");
lbs_deb_ioctl("FWT: resetting\n");
return (libertas_prepare_and_send_command(priv,
cmd_fwt_access,
......@@ -522,18 +604,21 @@ static int wlan_fwt_list_ioctl(wlan_private * priv, struct ifreq *req)
char *ptr = in_str;
static char out_str[128];
char *pbuf = out_str;
int ret;
int ret = 0;
ENTER();
if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str)))
return -EFAULT;
lbs_deb_enter(LBS_DEB_IOCTL);
if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str))) {
ret = -EFAULT;
goto out;
}
fwt_access.id = cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
#ifdef DEBUG
{
lbs_pr_debug(1, "FWT_LIST: line is %s\n", in_str);
lbs_pr_debug(1, "FWT_LIST: listing id:%i\n", le32_to_cpu(fwt_access.id));
lbs_deb_ioctl("FWT_LIST: line is %s\n", in_str);
lbs_deb_ioctl("FWT_LIST: listing id:%i\n", le32_to_cpu(fwt_access.id));
}
#endif
......@@ -549,12 +634,16 @@ static int wlan_fwt_list_ioctl(wlan_private * priv, struct ifreq *req)
wrq->u.data.length = strlen(out_str);
if (copy_to_user(wrq->u.data.pointer, (char *)out_str,
wrq->u.data.length)) {
lbs_pr_debug(1, "FWT_LIST: Copy to user failed!\n");
return -EFAULT;
lbs_deb_ioctl("FWT_LIST: Copy to user failed!\n");
ret = -EFAULT;
goto out;
}
LEAVE();
return 0;
ret = 0;
out:
lbs_deb_leave(LBS_DEB_IOCTL);
return ret;
}
/**
......@@ -573,7 +662,8 @@ static int wlan_fwt_list_route_ioctl(wlan_private * priv, struct ifreq *req)
char *pbuf = out_str;
int ret;
ENTER();
lbs_deb_enter(LBS_DEB_IOCTL);
if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str)))
return -EFAULT;
......@@ -581,8 +671,8 @@ static int wlan_fwt_list_route_ioctl(wlan_private * priv, struct ifreq *req)
#ifdef DEBUG
{
lbs_pr_debug(1, "FWT_LIST_ROUTE: line is %s\n", in_str);
lbs_pr_debug(1, "FWT_LIST_ROUTE: listing id:%i\n", le32_to_cpu(fwt_access.id));
lbs_deb_ioctl("FWT_LIST_ROUTE: line is %s\n", in_str);
lbs_deb_ioctl("FWT_LIST_ROUTE: listing id:%i\n", le32_to_cpu(fwt_access.id));
}
#endif
......@@ -591,28 +681,18 @@ static int wlan_fwt_list_route_ioctl(wlan_private * priv, struct ifreq *req)
cmd_option_waitforrsp, 0, (void *)&fwt_access);
if (ret == 0) {
pbuf += sprintf(pbuf, " ");
pbuf += eth_addr2str(fwt_access.da, pbuf);
pbuf += sprintf(pbuf, " %u", le32_to_cpu(fwt_access.metric));
pbuf += sprintf(pbuf, " %u", fwt_access.dir);
/* note that the firmware returns the nid in the id field */
pbuf += sprintf(pbuf, " %u", le32_to_cpu(fwt_access.id));
pbuf += sprintf(pbuf, " %u", le32_to_cpu(fwt_access.ssn));
pbuf += sprintf(pbuf, " %u", le32_to_cpu(fwt_access.dsn));
pbuf += sprintf(pbuf, " hop %u", fwt_access.hopcount);
pbuf += sprintf(pbuf, " ttl %u", fwt_access.ttl);
pbuf += sprintf(pbuf, " %u", le32_to_cpu(fwt_access.expiration));
print_route(fwt_access, pbuf);
} else
pbuf += sprintf(pbuf, " (null)");
wrq->u.data.length = strlen(out_str);
if (copy_to_user(wrq->u.data.pointer, (char *)out_str,
wrq->u.data.length)) {
lbs_pr_debug(1, "FWT_LIST_ROUTE: Copy to user failed!\n");
lbs_deb_ioctl("FWT_LIST_ROUTE: Copy to user failed!\n");
return -EFAULT;
}
LEAVE();
lbs_deb_leave(LBS_DEB_IOCTL);
return 0;
}
......@@ -632,7 +712,8 @@ static int wlan_fwt_list_neighbor_ioctl(wlan_private * priv, struct ifreq *req)
char *pbuf = out_str;
int ret;
ENTER();
lbs_deb_enter(LBS_DEB_IOCTL);
if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str)))
return -EFAULT;
......@@ -641,8 +722,8 @@ static int wlan_fwt_list_neighbor_ioctl(wlan_private * priv, struct ifreq *req)
#ifdef DEBUG
{
lbs_pr_debug(1, "FWT_LIST_NEIGHBOR: line is %s\n", in_str);
lbs_pr_debug(1, "FWT_LIST_NEIGHBOR: listing id:%i\n", le32_to_cpu(fwt_access.id));
lbs_deb_ioctl("FWT_LIST_NEIGHBOR: line is %s\n", in_str);
lbs_deb_ioctl("FWT_LIST_NEIGHBOR: listing id:%i\n", le32_to_cpu(fwt_access.id));
}
#endif
......@@ -663,11 +744,11 @@ static int wlan_fwt_list_neighbor_ioctl(wlan_private * priv, struct ifreq *req)
wrq->u.data.length = strlen(out_str);
if (copy_to_user(wrq->u.data.pointer, (char *)out_str,
wrq->u.data.length)) {
lbs_pr_debug(1, "FWT_LIST_NEIGHBOR: Copy to user failed!\n");
lbs_deb_ioctl("FWT_LIST_NEIGHBOR: Copy to user failed!\n");
return -EFAULT;
}
LEAVE();
lbs_deb_leave(LBS_DEB_IOCTL);
return 0;
}
......@@ -684,9 +765,9 @@ static int wlan_fwt_cleanup_ioctl(wlan_private * priv, struct ifreq *req)
static struct cmd_ds_fwt_access fwt_access;
int ret;
ENTER();
lbs_deb_enter(LBS_DEB_IOCTL);
lbs_pr_debug(1, "FWT: cleaning up\n");
lbs_deb_ioctl("FWT: cleaning up\n");
memset(&fwt_access, 0, sizeof(fwt_access));
......@@ -700,7 +781,7 @@ static int wlan_fwt_cleanup_ioctl(wlan_private * priv, struct ifreq *req)
else
return -EFAULT;
LEAVE();
lbs_deb_leave(LBS_DEB_IOCTL);
return 0;
}
......@@ -716,9 +797,9 @@ static int wlan_fwt_time_ioctl(wlan_private * priv, struct ifreq *req)
static struct cmd_ds_fwt_access fwt_access;
int ret;
ENTER();
lbs_deb_enter(LBS_DEB_IOCTL);
lbs_pr_debug(1, "FWT: getting time\n");
lbs_deb_ioctl("FWT: getting time\n");
memset(&fwt_access, 0, sizeof(fwt_access));
......@@ -732,7 +813,7 @@ static int wlan_fwt_time_ioctl(wlan_private * priv, struct ifreq *req)
else
return -EFAULT;
LEAVE();
lbs_deb_leave(LBS_DEB_IOCTL);
return 0;
}
......@@ -748,7 +829,7 @@ static int wlan_mesh_get_ttl_ioctl(wlan_private * priv, struct ifreq *req)
struct cmd_ds_mesh_access mesh_access;
int ret;
ENTER();
lbs_deb_enter(LBS_DEB_IOCTL);
memset(&mesh_access, 0, sizeof(mesh_access));
......@@ -762,7 +843,7 @@ static int wlan_mesh_get_ttl_ioctl(wlan_private * priv, struct ifreq *req)
else
return -EFAULT;
LEAVE();
lbs_deb_leave(LBS_DEB_IOCTL);
return 0;
}
......@@ -777,13 +858,13 @@ static int wlan_mesh_set_ttl_ioctl(wlan_private * priv, int ttl)
struct cmd_ds_mesh_access mesh_access;
int ret;
ENTER();
lbs_deb_enter(LBS_DEB_IOCTL);
if( (ttl > 0xff) || (ttl < 0) )
return -EINVAL;
memset(&mesh_access, 0, sizeof(mesh_access));
mesh_access.data[0] = ttl;
mesh_access.data[0] = cpu_to_le32(ttl);
ret = libertas_prepare_and_send_command(priv, cmd_mesh_access,
cmd_act_mesh_set_ttl,
......@@ -793,7 +874,7 @@ static int wlan_mesh_set_ttl_ioctl(wlan_private * priv, int ttl)
if (ret != 0)
ret = -EFAULT;
LEAVE();
lbs_deb_leave(LBS_DEB_IOCTL);
return ret;
}
......@@ -815,9 +896,9 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
wlan_adapter *adapter = priv->adapter;
struct iwreq *wrq = (struct iwreq *)req;
ENTER();
lbs_deb_enter(LBS_DEB_IOCTL);
lbs_pr_debug(1, "libertas_do_ioctl: ioctl cmd = 0x%x\n", cmd);
lbs_deb_ioctl("libertas_do_ioctl: ioctl cmd = 0x%x\n", cmd);
switch (cmd) {
case WLAN_SETNONE_GETNONE: /* set WPA mode on/off ioctl #20 */
switch (wrq->u.data.flags) {
......@@ -848,6 +929,10 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
ret = wlan_mesh_set_ttl_ioctl(priv, idata);
break;
case WLAN_SUBCMD_BT_SET_INVERT:
ret = wlan_bt_set_invert_ioctl(priv, req);
break ;
default:
ret = -EOPNOTSUPP;
break;
......@@ -905,6 +990,10 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
ret = wlan_mesh_get_ttl_ioctl(priv, req);
break;
case WLAN_SUBCMD_BT_GET_INVERT:
ret = wlan_bt_get_invert_ioctl(priv, req);
break ;
default:
ret = -EOPNOTSUPP;
......@@ -937,7 +1026,7 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
(data, wrq->u.data.pointer,
sizeof(int) *
wrq->u.data.length)) {
lbs_pr_debug(1,
lbs_deb_ioctl(
"Copy from user failed\n");
return -EFAULT;
}
......@@ -970,7 +1059,7 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
if (copy_to_user(wrq->u.data.pointer, data,
sizeof(int) *
gpio->header.len)) {
lbs_pr_debug(1, "Copy to user failed\n");
lbs_deb_ioctl("Copy to user failed\n");
return -EFAULT;
}
......@@ -984,7 +1073,8 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
ret = -EINVAL;
break;
}
LEAVE();
lbs_deb_leave_args(LBS_DEB_IOCTL, "ret %d", ret);
return ret;
}
......
......@@ -7,6 +7,7 @@
#include <linux/netdevice.h>
#include <linux/if_arp.h>
#include <linux/wireless.h>
#include <linux/etherdevice.h>
#include <net/iw_handler.h>
......@@ -14,6 +15,7 @@
#include "decl.h"
#include "join.h"
#include "dev.h"
#include "assoc.h"
#define AD_HOC_CAP_PRIVACY_ON 1
......@@ -60,7 +62,7 @@ static int get_common_rates(wlan_adapter * adapter, u8 * rate1,
lbs_dbg_hex("rate1 (AP) rates:", tmp, sizeof(tmp));
lbs_dbg_hex("rate2 (Card) rates:", rate2, rate2_size);
lbs_dbg_hex("Common rates:", ptr, rate1_size);
lbs_pr_debug(1, "Tx datarate is set to 0x%X\n", adapter->datarate);
lbs_deb_join("Tx datarate is set to 0x%X\n", adapter->datarate);
if (!adapter->is_datarate_auto) {
while (*ptr) {
......@@ -104,24 +106,22 @@ int libertas_send_deauth(wlan_private * priv)
*
* @return 0-success, otherwise fail
*/
int wlan_associate(wlan_private * priv, struct bss_descriptor * pbssdesc)
int wlan_associate(wlan_private * priv, struct assoc_request * assoc_req)
{
wlan_adapter *adapter = priv->adapter;
int ret;
ENTER();
lbs_deb_enter(LBS_DEB_JOIN);
ret = libertas_prepare_and_send_command(priv, cmd_802_11_authenticate,
0, cmd_option_waitforrsp,
0, pbssdesc->macaddress);
0, assoc_req->bss.bssid);
if (ret) {
LEAVE();
return ret;
}
if (ret)
goto done;
/* set preamble to firmware */
if (adapter->capinfo.shortpreamble && pbssdesc->cap.shortpreamble)
if (adapter->capinfo.shortpreamble && assoc_req->bss.cap.shortpreamble)
adapter->preamble = cmd_type_short_preamble;
else
adapter->preamble = cmd_type_long_preamble;
......@@ -129,9 +129,10 @@ int wlan_associate(wlan_private * priv, struct bss_descriptor * pbssdesc)
libertas_set_radio_control(priv);
ret = libertas_prepare_and_send_command(priv, cmd_802_11_associate,
0, cmd_option_waitforrsp, 0, pbssdesc);
0, cmd_option_waitforrsp, 0, assoc_req);
LEAVE();
done:
lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
return ret;
}
......@@ -142,7 +143,7 @@ int wlan_associate(wlan_private * priv, struct bss_descriptor * pbssdesc)
* @param adhocssid The ssid of the Adhoc Network
* @return 0--success, -1--fail
*/
int libertas_start_adhoc_network(wlan_private * priv, struct WLAN_802_11_SSID *adhocssid)
int libertas_start_adhoc_network(wlan_private * priv, struct assoc_request * assoc_req)
{
wlan_adapter *adapter = priv->adapter;
int ret = 0;
......@@ -150,22 +151,20 @@ int libertas_start_adhoc_network(wlan_private * priv, struct WLAN_802_11_SSID *a
adapter->adhoccreate = 1;
if (!adapter->capinfo.shortpreamble) {
lbs_pr_debug(1, "AdhocStart: Long preamble\n");
lbs_deb_join("AdhocStart: Long preamble\n");
adapter->preamble = cmd_type_long_preamble;
} else {
lbs_pr_debug(1, "AdhocStart: Short preamble\n");
lbs_deb_join("AdhocStart: Short preamble\n");
adapter->preamble = cmd_type_short_preamble;
}
libertas_set_radio_control(priv);
lbs_pr_debug(1, "Adhoc channel = %d\n", adapter->adhocchannel);
lbs_pr_debug(1, "curbssparams.channel = %d\n",
adapter->curbssparams.channel);
lbs_pr_debug(1, "curbssparams.band = %d\n", adapter->curbssparams.band);
lbs_deb_join("AdhocStart: channel = %d\n", assoc_req->channel);
lbs_deb_join("AdhocStart: band = %d\n", assoc_req->band);
ret = libertas_prepare_and_send_command(priv, cmd_802_11_ad_hoc_start,
0, cmd_option_waitforrsp, 0, adhocssid);
0, cmd_option_waitforrsp, 0, assoc_req);
return ret;
}
......@@ -179,52 +178,53 @@ int libertas_start_adhoc_network(wlan_private * priv, struct WLAN_802_11_SSID *a
*
* @return 0--success, -1--fail
*/
int libertas_join_adhoc_network(wlan_private * priv, struct bss_descriptor * pbssdesc)
int libertas_join_adhoc_network(wlan_private * priv, struct assoc_request * assoc_req)
{
wlan_adapter *adapter = priv->adapter;
struct bss_descriptor * bss = &assoc_req->bss;
int ret = 0;
lbs_pr_debug(1, "libertas_join_adhoc_network: CurBss.ssid =%s\n",
adapter->curbssparams.ssid.ssid);
lbs_pr_debug(1, "libertas_join_adhoc_network: CurBss.ssid_len =%u\n",
adapter->curbssparams.ssid.ssidlength);
lbs_pr_debug(1, "libertas_join_adhoc_network: ssid =%s\n", pbssdesc->ssid.ssid);
lbs_pr_debug(1, "libertas_join_adhoc_network: ssid len =%u\n",
pbssdesc->ssid.ssidlength);
lbs_deb_join("%s: Current SSID '%s', ssid length %u\n",
__func__,
escape_essid(adapter->curbssparams.ssid,
adapter->curbssparams.ssid_len),
adapter->curbssparams.ssid_len);
lbs_deb_join("%s: requested ssid '%s', ssid length %u\n",
__func__, escape_essid(bss->ssid, bss->ssid_len),
bss->ssid_len);
/* check if the requested SSID is already joined */
if (adapter->curbssparams.ssid.ssidlength
&& !libertas_SSID_cmp(&pbssdesc->ssid, &adapter->curbssparams.ssid)
if (adapter->curbssparams.ssid_len
&& !libertas_ssid_cmp(adapter->curbssparams.ssid,
adapter->curbssparams.ssid_len,
bss->ssid, bss->ssid_len)
&& (adapter->mode == IW_MODE_ADHOC)) {
lbs_pr_debug(1,
lbs_deb_join(
"ADHOC_J_CMD: New ad-hoc SSID is the same as current, "
"not attempting to re-join");
return -1;
}
/*Use shortpreamble only when both creator and card supports
short preamble */
if (!pbssdesc->cap.shortpreamble || !adapter->capinfo.shortpreamble) {
lbs_pr_debug(1, "AdhocJoin: Long preamble\n");
if (!bss->cap.shortpreamble || !adapter->capinfo.shortpreamble) {
lbs_deb_join("AdhocJoin: Long preamble\n");
adapter->preamble = cmd_type_long_preamble;
} else {
lbs_pr_debug(1, "AdhocJoin: Short preamble\n");
lbs_deb_join("AdhocJoin: Short preamble\n");
adapter->preamble = cmd_type_short_preamble;
}
libertas_set_radio_control(priv);
lbs_pr_debug(1, "curbssparams.channel = %d\n",
adapter->curbssparams.channel);
lbs_pr_debug(1, "curbssparams.band = %c\n", adapter->curbssparams.band);
lbs_deb_join("AdhocJoin: channel = %d\n", assoc_req->channel);
lbs_deb_join("AdhocJoin: band = %c\n", assoc_req->band);
adapter->adhoccreate = 0;
ret = libertas_prepare_and_send_command(priv, cmd_802_11_ad_hoc_join,
0, cmd_option_waitforrsp,
OID_802_11_SSID, pbssdesc);
OID_802_11_SSID, assoc_req);
return ret;
}
......@@ -265,6 +265,8 @@ int libertas_cmd_80211_authenticate(wlan_private * priv,
int ret = -1;
u8 *bssid = pdata_buf;
lbs_deb_enter(LBS_DEB_JOIN);
cmd->command = cpu_to_le16(cmd_802_11_authenticate);
cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_authenticate)
+ S_DS_GEN);
......@@ -281,18 +283,19 @@ int libertas_cmd_80211_authenticate(wlan_private * priv,
pauthenticate->authtype = 0x80;
break;
default:
lbs_pr_debug(1, "AUTH_CMD: invalid auth alg 0x%X\n",
lbs_deb_join("AUTH_CMD: invalid auth alg 0x%X\n",
adapter->secinfo.auth_mode);
goto out;
}
memcpy(pauthenticate->macaddr, bssid, ETH_ALEN);
lbs_pr_debug(1, "AUTH_CMD: Bssid is : %x:%x:%x:%x:%x:%x\n",
bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]);
lbs_deb_join("AUTH_CMD: BSSID is : " MAC_FMT " auth=0x%X\n",
MAC_ARG(bssid), pauthenticate->authtype);
ret = 0;
out:
lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
return ret;
}
......@@ -302,22 +305,20 @@ int libertas_cmd_80211_deauthenticate(wlan_private * priv,
wlan_adapter *adapter = priv->adapter;
struct cmd_ds_802_11_deauthenticate *dauth = &cmd->params.deauth;
ENTER();
lbs_deb_enter(LBS_DEB_JOIN);
cmd->command = cpu_to_le16(cmd_802_11_deauthenticate);
cmd->size =
cpu_to_le16(sizeof(struct cmd_ds_802_11_deauthenticate) +
cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_deauthenticate) +
S_DS_GEN);
/* set AP MAC address */
memmove(dauth->macaddr, adapter->curbssparams.bssid,
ETH_ALEN);
memmove(dauth->macaddr, adapter->curbssparams.bssid, ETH_ALEN);
/* Reason code 3 = Station is leaving */
#define REASON_CODE_STA_LEAVING 3
dauth->reasoncode = cpu_to_le16(REASON_CODE_STA_LEAVING);
LEAVE();
lbs_deb_leave(LBS_DEB_JOIN);
return 0;
}
......@@ -327,20 +328,20 @@ int libertas_cmd_80211_associate(wlan_private * priv,
wlan_adapter *adapter = priv->adapter;
struct cmd_ds_802_11_associate *passo = &cmd->params.associate;
int ret = 0;
struct bss_descriptor *pbssdesc;
struct assoc_request * assoc_req = pdata_buf;
struct bss_descriptor * bss = &assoc_req->bss;
u8 *card_rates;
u8 *pos;
int card_rates_size;
u16 tmpcap;
u16 tmpcap, tmplen;
struct mrvlietypes_ssidparamset *ssid;
struct mrvlietypes_phyparamset *phy;
struct mrvlietypes_ssparamset *ss;
struct mrvlietypes_ratesparamset *rates;
struct mrvlietypes_rsnparamset *rsn;
ENTER();
lbs_deb_enter(LBS_DEB_JOIN);
pbssdesc = pdata_buf;
pos = (u8 *) passo;
if (!adapter) {
......@@ -350,15 +351,11 @@ int libertas_cmd_80211_associate(wlan_private * priv,
cmd->command = cpu_to_le16(cmd_802_11_associate);
/* Save so we know which BSS Desc to use in the response handler */
adapter->pattemptedbssdesc = pbssdesc;
memcpy(passo->peerstaaddr,
pbssdesc->macaddress, sizeof(passo->peerstaaddr));
memcpy(passo->peerstaaddr, bss->bssid, sizeof(passo->peerstaaddr));
pos += sizeof(passo->peerstaaddr);
/* set the listen interval */
passo->listeninterval = adapter->listeninterval;
passo->listeninterval = cpu_to_le16(adapter->listeninterval);
pos += sizeof(passo->capinfo);
pos += sizeof(passo->listeninterval);
......@@ -367,30 +364,30 @@ int libertas_cmd_80211_associate(wlan_private * priv,
ssid = (struct mrvlietypes_ssidparamset *) pos;
ssid->header.type = cpu_to_le16(TLV_TYPE_SSID);
ssid->header.len = pbssdesc->ssid.ssidlength;
memcpy(ssid->ssid, pbssdesc->ssid.ssid, ssid->header.len);
pos += sizeof(ssid->header) + ssid->header.len;
ssid->header.len = cpu_to_le16(ssid->header.len);
tmplen = bss->ssid_len;
ssid->header.len = cpu_to_le16(tmplen);
memcpy(ssid->ssid, bss->ssid, tmplen);
pos += sizeof(ssid->header) + tmplen;
phy = (struct mrvlietypes_phyparamset *) pos;
phy->header.type = cpu_to_le16(TLV_TYPE_PHY_DS);
phy->header.len = sizeof(phy->fh_ds.dsparamset);
tmplen = sizeof(phy->fh_ds.dsparamset);
phy->header.len = cpu_to_le16(tmplen);
memcpy(&phy->fh_ds.dsparamset,
&pbssdesc->phyparamset.dsparamset.currentchan,
sizeof(phy->fh_ds.dsparamset));
pos += sizeof(phy->header) + phy->header.len;
phy->header.len = cpu_to_le16(phy->header.len);
&bss->phyparamset.dsparamset.currentchan,
tmplen);
pos += sizeof(phy->header) + tmplen;
ss = (struct mrvlietypes_ssparamset *) pos;
ss->header.type = cpu_to_le16(TLV_TYPE_CF);
ss->header.len = sizeof(ss->cf_ibss.cfparamset);
pos += sizeof(ss->header) + ss->header.len;
ss->header.len = cpu_to_le16(ss->header.len);
tmplen = sizeof(ss->cf_ibss.cfparamset);
ss->header.len = cpu_to_le16(tmplen);
pos += sizeof(ss->header) + tmplen;
rates = (struct mrvlietypes_ratesparamset *) pos;
rates->header.type = cpu_to_le16(TLV_TYPE_RATES);
memcpy(&rates->rates, &pbssdesc->libertas_supported_rates, WLAN_SUPPORTED_RATES);
memcpy(&rates->rates, &bss->libertas_supported_rates, WLAN_SUPPORTED_RATES);
card_rates = libertas_supported_rates;
card_rates_size = sizeof(libertas_supported_rates);
......@@ -401,41 +398,42 @@ int libertas_cmd_80211_associate(wlan_private * priv,
goto done;
}
rates->header.len = min_t(size_t, strlen(rates->rates), WLAN_SUPPORTED_RATES);
adapter->curbssparams.numofrates = rates->header.len;
tmplen = min_t(size_t, strlen(rates->rates), WLAN_SUPPORTED_RATES);
adapter->curbssparams.numofrates = tmplen;
pos += sizeof(rates->header) + rates->header.len;
rates->header.len = cpu_to_le16(rates->header.len);
pos += sizeof(rates->header) + tmplen;
rates->header.len = cpu_to_le16(tmplen);
if (adapter->secinfo.WPAenabled || adapter->secinfo.WPA2enabled) {
if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) {
rsn = (struct mrvlietypes_rsnparamset *) pos;
rsn->header.type = (u16) adapter->wpa_ie[0]; /* WPA_IE or WPA2_IE */
rsn->header.type = cpu_to_le16(rsn->header.type);
rsn->header.len = (u16) adapter->wpa_ie[1];
memcpy(rsn->rsnie, &adapter->wpa_ie[2], rsn->header.len);
/* WPA_IE or WPA2_IE */
rsn->header.type = cpu_to_le16((u16) assoc_req->wpa_ie[0]);
tmplen = (u16) assoc_req->wpa_ie[1];
rsn->header.len = cpu_to_le16(tmplen);
memcpy(rsn->rsnie, &assoc_req->wpa_ie[2], tmplen);
lbs_dbg_hex("ASSOC_CMD: RSN IE", (u8 *) rsn,
sizeof(rsn->header) + rsn->header.len);
pos += sizeof(rsn->header) + rsn->header.len;
rsn->header.len = cpu_to_le16(rsn->header.len);
sizeof(rsn->header) + tmplen);
pos += sizeof(rsn->header) + tmplen;
}
/* update curbssparams */
adapter->curbssparams.channel =
(pbssdesc->phyparamset.dsparamset.currentchan);
adapter->curbssparams.channel = bss->phyparamset.dsparamset.currentchan;
/* Copy the infra. association rates into Current BSS state structure */
memcpy(&adapter->curbssparams.datarates, &rates->rates,
min_t(size_t, sizeof(adapter->curbssparams.datarates), rates->header.len));
min_t(size_t, sizeof(adapter->curbssparams.datarates),
cpu_to_le16(rates->header.len)));
lbs_pr_debug(1, "ASSOC_CMD: rates->header.len = %d\n", rates->header.len);
lbs_deb_join("ASSOC_CMD: rates->header.len = %d\n",
cpu_to_le16(rates->header.len));
/* set IBSS field */
if (pbssdesc->mode == IW_MODE_INFRA) {
if (bss->mode == IW_MODE_INFRA) {
#define CAPINFO_ESS_MODE 1
passo->capinfo.ess = CAPINFO_ESS_MODE;
}
if (libertas_parse_dnld_countryinfo_11d(priv)) {
if (libertas_parse_dnld_countryinfo_11d(priv, bss)) {
ret = -1;
goto done;
}
......@@ -443,31 +441,28 @@ int libertas_cmd_80211_associate(wlan_private * priv,
cmd->size = cpu_to_le16((u16) (pos - (u8 *) passo) + S_DS_GEN);
/* set the capability info at last */
memcpy(&tmpcap, &pbssdesc->cap, sizeof(passo->capinfo));
memcpy(&tmpcap, &bss->cap, sizeof(passo->capinfo));
tmpcap &= CAPINFO_MASK;
lbs_pr_debug(1, "ASSOC_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n",
lbs_deb_join("ASSOC_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n",
tmpcap, CAPINFO_MASK);
tmpcap = cpu_to_le16(tmpcap);
memcpy(&passo->capinfo, &tmpcap, sizeof(passo->capinfo));
done:
LEAVE();
done:
lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
return ret;
}
int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
struct cmd_ds_command *cmd, void *pssid)
struct cmd_ds_command *cmd, void *pdata_buf)
{
wlan_adapter *adapter = priv->adapter;
struct cmd_ds_802_11_ad_hoc_start *adhs = &cmd->params.ads;
int ret = 0;
int cmdappendsize = 0;
int i;
u16 tmpcap;
struct bss_descriptor *pbssdesc;
struct WLAN_802_11_SSID *ssid = pssid;
struct assoc_request * assoc_req = pdata_buf;
ENTER();
lbs_deb_enter(LBS_DEB_JOIN);
if (!adapter) {
ret = -1;
......@@ -476,9 +471,6 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
cmd->command = cpu_to_le16(cmd_802_11_ad_hoc_start);
pbssdesc = &adapter->curbssparams.bssdescriptor;
adapter->pattemptedbssdesc = pbssdesc;
/*
* Fill in the parameters for 2 data structures:
* 1. cmd_ds_802_11_ad_hoc_start command
......@@ -492,20 +484,16 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
*/
memset(adhs->SSID, 0, IW_ESSID_MAX_SIZE);
memcpy(adhs->SSID, assoc_req->ssid, assoc_req->ssid_len);
memcpy(adhs->SSID, ssid->ssid, ssid->ssidlength);
lbs_pr_debug(1, "ADHOC_S_CMD: SSID = %s\n", adhs->SSID);
memset(pbssdesc->ssid.ssid, 0, IW_ESSID_MAX_SIZE);
memcpy(pbssdesc->ssid.ssid, ssid->ssid, ssid->ssidlength);
pbssdesc->ssid.ssidlength = ssid->ssidlength;
lbs_deb_join("ADHOC_S_CMD: SSID '%s', ssid length %u\n",
escape_essid(assoc_req->ssid, assoc_req->ssid_len),
assoc_req->ssid_len);
/* set the BSS type */
adhs->bsstype = cmd_bss_type_ibss;
pbssdesc->mode = IW_MODE_ADHOC;
adhs->beaconperiod = adapter->beaconperiod;
adapter->mode = IW_MODE_ADHOC;
adhs->beaconperiod = cpu_to_le16(adapter->beaconperiod);
/* set Physical param set */
#define DS_PARA_IE_ID 3
......@@ -514,18 +502,12 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
adhs->phyparamset.dsparamset.elementid = DS_PARA_IE_ID;
adhs->phyparamset.dsparamset.len = DS_PARA_IE_LEN;
WARN_ON(!adapter->adhocchannel);
lbs_pr_debug(1, "ADHOC_S_CMD: Creating ADHOC on channel %d\n",
adapter->adhocchannel);
adapter->curbssparams.channel = adapter->adhocchannel;
WARN_ON(!assoc_req->channel);
pbssdesc->channel = adapter->adhocchannel;
adhs->phyparamset.dsparamset.currentchan = adapter->adhocchannel;
lbs_deb_join("ADHOC_S_CMD: Creating ADHOC on channel %d\n",
assoc_req->channel);
memcpy(&pbssdesc->phyparamset,
&adhs->phyparamset, sizeof(union ieeetypes_phyparamset));
adhs->phyparamset.dsparamset.currentchan = assoc_req->channel;
/* set IBSS param set */
#define IBSS_PARA_IE_ID 6
......@@ -533,26 +515,21 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
adhs->ssparamset.ibssparamset.elementid = IBSS_PARA_IE_ID;
adhs->ssparamset.ibssparamset.len = IBSS_PARA_IE_LEN;
adhs->ssparamset.ibssparamset.atimwindow = adapter->atimwindow;
memcpy(&pbssdesc->ssparamset,
&adhs->ssparamset, sizeof(union IEEEtypes_ssparamset));
adhs->ssparamset.ibssparamset.atimwindow = cpu_to_le16(adapter->atimwindow);
/* set capability info */
adhs->cap.ess = 0;
adhs->cap.ibss = 1;
pbssdesc->cap.ibss = 1;
/* probedelay */
adhs->probedelay = cpu_to_le16(cmd_scan_probe_delay_time);
/* set up privacy in adapter->scantable[i] */
if (adapter->secinfo.wep_enabled) {
lbs_pr_debug(1, "ADHOC_S_CMD: WEP enabled, setting privacy on\n");
pbssdesc->privacy = wlan802_11privfilter8021xWEP;
if (assoc_req->secinfo.wep_enabled) {
lbs_deb_join("ADHOC_S_CMD: WEP enabled, setting privacy on\n");
adhs->cap.privacy = AD_HOC_CAP_PRIVACY_ON;
} else {
lbs_pr_debug(1, "ADHOC_S_CMD: WEP disabled, setting privacy off\n");
pbssdesc->privacy = wlan802_11privfilteracceptall;
lbs_deb_join("ADHOC_S_CMD: WEP disabled, setting privacy off\n");
}
memset(adhs->datarate, 0, sizeof(adhs->datarate));
......@@ -574,29 +551,24 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
memcpy(&adapter->curbssparams.datarates,
&adhs->datarate, adapter->curbssparams.numofrates);
lbs_pr_debug(1, "ADHOC_S_CMD: rates=%02x %02x %02x %02x \n",
lbs_deb_join("ADHOC_S_CMD: rates=%02x %02x %02x %02x \n",
adhs->datarate[0], adhs->datarate[1],
adhs->datarate[2], adhs->datarate[3]);
lbs_pr_debug(1, "ADHOC_S_CMD: AD HOC Start command is ready\n");
lbs_deb_join("ADHOC_S_CMD: AD HOC Start command is ready\n");
if (libertas_create_dnld_countryinfo_11d(priv)) {
lbs_pr_debug(1, "ADHOC_S_CMD: dnld_countryinfo_11d failed\n");
lbs_deb_join("ADHOC_S_CMD: dnld_countryinfo_11d failed\n");
ret = -1;
goto done;
}
cmd->size =
cpu_to_le16(sizeof(struct cmd_ds_802_11_ad_hoc_start)
+ S_DS_GEN + cmdappendsize);
memcpy(&tmpcap, &adhs->cap, sizeof(u16));
tmpcap = cpu_to_le16(tmpcap);
memcpy(&adhs->cap, &tmpcap, sizeof(u16));
cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_ad_hoc_start) +
S_DS_GEN + cmdappendsize);
ret = 0;
done:
LEAVE();
lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
return ret;
}
......@@ -614,7 +586,8 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv,
{
wlan_adapter *adapter = priv->adapter;
struct cmd_ds_802_11_ad_hoc_join *padhocjoin = &cmd->params.adj;
struct bss_descriptor *pbssdesc = pdata_buf;
struct assoc_request * assoc_req = pdata_buf;
struct bss_descriptor *bss = &assoc_req->bss;
int cmdappendsize = 0;
int ret = 0;
u8 *card_rates;
......@@ -622,70 +595,59 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv,
u16 tmpcap;
int i;
ENTER();
adapter->pattemptedbssdesc = pbssdesc;
lbs_deb_enter(LBS_DEB_JOIN);
cmd->command = cpu_to_le16(cmd_802_11_ad_hoc_join);
padhocjoin->bssdescriptor.bsstype = cmd_bss_type_ibss;
padhocjoin->bssdescriptor.beaconperiod = pbssdesc->beaconperiod;
memcpy(&padhocjoin->bssdescriptor.BSSID,
&pbssdesc->macaddress, ETH_ALEN);
padhocjoin->bssdescriptor.beaconperiod = cpu_to_le16(bss->beaconperiod);
memcpy(&padhocjoin->bssdescriptor.SSID,
&pbssdesc->ssid.ssid, pbssdesc->ssid.ssidlength);
memcpy(&padhocjoin->bssdescriptor.BSSID, &bss->bssid, ETH_ALEN);
memcpy(&padhocjoin->bssdescriptor.SSID, &bss->ssid, bss->ssid_len);
memcpy(&padhocjoin->bssdescriptor.phyparamset,
&pbssdesc->phyparamset, sizeof(union ieeetypes_phyparamset));
&bss->phyparamset, sizeof(union ieeetypes_phyparamset));
memcpy(&padhocjoin->bssdescriptor.ssparamset,
&pbssdesc->ssparamset, sizeof(union IEEEtypes_ssparamset));
&bss->ssparamset, sizeof(union IEEEtypes_ssparamset));
memcpy(&tmpcap, &pbssdesc->cap, sizeof(struct ieeetypes_capinfo));
memcpy(&tmpcap, &bss->cap, sizeof(struct ieeetypes_capinfo));
tmpcap &= CAPINFO_MASK;
lbs_pr_debug(1, "ADHOC_J_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n",
lbs_deb_join("ADHOC_J_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n",
tmpcap, CAPINFO_MASK);
memcpy(&padhocjoin->bssdescriptor.cap, &tmpcap,
sizeof(struct ieeetypes_capinfo));
/* information on BSSID descriptor passed to FW */
lbs_pr_debug(1,
"ADHOC_J_CMD: BSSID = %2x-%2x-%2x-%2x-%2x-%2x, SSID = %s\n",
padhocjoin->bssdescriptor.BSSID[0],
padhocjoin->bssdescriptor.BSSID[1],
padhocjoin->bssdescriptor.BSSID[2],
padhocjoin->bssdescriptor.BSSID[3],
padhocjoin->bssdescriptor.BSSID[4],
padhocjoin->bssdescriptor.BSSID[5],
lbs_deb_join(
"ADHOC_J_CMD: BSSID = " MAC_FMT ", SSID = '%s'\n",
MAC_ARG(padhocjoin->bssdescriptor.BSSID),
padhocjoin->bssdescriptor.SSID);
/* failtimeout */
padhocjoin->failtimeout = cpu_to_le16(MRVDRV_ASSOCIATION_TIME_OUT);
/* probedelay */
padhocjoin->probedelay =
cpu_to_le16(cmd_scan_probe_delay_time);
padhocjoin->probedelay = cpu_to_le16(cmd_scan_probe_delay_time);
/* Copy Data rates from the rates recorded in scan response */
memset(padhocjoin->bssdescriptor.datarates, 0,
sizeof(padhocjoin->bssdescriptor.datarates));
memcpy(padhocjoin->bssdescriptor.datarates, pbssdesc->datarates,
memcpy(padhocjoin->bssdescriptor.datarates, bss->datarates,
min(sizeof(padhocjoin->bssdescriptor.datarates),
sizeof(pbssdesc->datarates)));
sizeof(bss->datarates)));
card_rates = libertas_supported_rates;
card_rates_size = sizeof(libertas_supported_rates);
adapter->curbssparams.channel = pbssdesc->channel;
adapter->curbssparams.channel = bss->channel;
if (get_common_rates(adapter, padhocjoin->bssdescriptor.datarates,
sizeof(padhocjoin->bssdescriptor.datarates),
card_rates, card_rates_size)) {
lbs_pr_debug(1, "ADHOC_J_CMD: get_common_rates returns error.\n");
lbs_deb_join("ADHOC_J_CMD: get_common_rates returns error.\n");
ret = -1;
goto done;
}
......@@ -704,17 +666,17 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv,
adapter->curbssparams.numofrates);
padhocjoin->bssdescriptor.ssparamset.ibssparamset.atimwindow =
cpu_to_le16(pbssdesc->atimwindow);
cpu_to_le16(bss->atimwindow);
if (adapter->secinfo.wep_enabled) {
if (assoc_req->secinfo.wep_enabled) {
padhocjoin->bssdescriptor.cap.privacy = AD_HOC_CAP_PRIVACY_ON;
}
if (adapter->psmode == wlan802_11powermodemax_psp) {
/* wake up first */
enum WLAN_802_11_POWER_MODE Localpsmode;
__le32 Localpsmode;
Localpsmode = wlan802_11powermodecam;
Localpsmode = cpu_to_le32(wlan802_11powermodecam);
ret = libertas_prepare_and_send_command(priv,
cmd_802_11_ps_mode,
cmd_act_set,
......@@ -726,24 +688,16 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv,
}
}
if (libertas_parse_dnld_countryinfo_11d(priv)) {
if (libertas_parse_dnld_countryinfo_11d(priv, bss)) {
ret = -1;
goto done;
}
cmd->size =
cpu_to_le16(sizeof(struct cmd_ds_802_11_ad_hoc_join)
+ S_DS_GEN + cmdappendsize);
memcpy(&tmpcap, &padhocjoin->bssdescriptor.cap,
sizeof(struct ieeetypes_capinfo));
tmpcap = cpu_to_le16(tmpcap);
memcpy(&padhocjoin->bssdescriptor.cap,
&tmpcap, sizeof(struct ieeetypes_capinfo));
cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_ad_hoc_join) +
S_DS_GEN + cmdappendsize);
done:
LEAVE();
done:
lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
return ret;
}
......@@ -754,19 +708,24 @@ int libertas_ret_80211_associate(wlan_private * priv,
int ret = 0;
union iwreq_data wrqu;
struct ieeetypes_assocrsp *passocrsp;
struct bss_descriptor *pbssdesc;
struct bss_descriptor * bss;
ENTER();
lbs_deb_enter(LBS_DEB_JOIN);
passocrsp = (struct ieeetypes_assocrsp *) & resp->params;
if (!adapter->in_progress_assoc_req) {
lbs_deb_join("ASSOC_RESP: no in-progress association request\n");
ret = -1;
goto done;
}
bss = &adapter->in_progress_assoc_req->bss;
if (passocrsp->statuscode) {
passocrsp = (struct ieeetypes_assocrsp *) & resp->params;
if (le16_to_cpu(passocrsp->statuscode)) {
libertas_mac_event_disconnected(priv);
lbs_pr_debug(1,
"ASSOC_RESP: Association failed, status code = %d\n",
passocrsp->statuscode);
lbs_deb_join("ASSOC_RESP: Association failed, status code = %d\n",
le16_to_cpu(passocrsp->statuscode));
ret = -1;
goto done;
......@@ -778,24 +737,15 @@ int libertas_ret_80211_associate(wlan_private * priv,
/* Send a Media Connected event, according to the Spec */
adapter->connect_status = libertas_connected;
/* Set the attempted BSSID Index to current */
pbssdesc = adapter->pattemptedbssdesc;
lbs_deb_join("ASSOC_RESP: assocated to '%s'\n",
escape_essid(bss->ssid, bss->ssid_len));
lbs_pr_debug(1, "ASSOC_RESP: %s\n", pbssdesc->ssid.ssid);
/* Update current SSID and BSSID */
memcpy(&adapter->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
adapter->curbssparams.ssid_len = bss->ssid_len;
memcpy(adapter->curbssparams.bssid, bss->bssid, ETH_ALEN);
/* Set the new SSID to current SSID */
memcpy(&adapter->curbssparams.ssid,
&pbssdesc->ssid, sizeof(struct WLAN_802_11_SSID));
/* Set the new BSSID (AP's MAC address) to current BSSID */
memcpy(adapter->curbssparams.bssid,
pbssdesc->macaddress, ETH_ALEN);
/* Make a copy of current BSSID descriptor */
memcpy(&adapter->curbssparams.bssdescriptor,
pbssdesc, sizeof(struct bss_descriptor));
lbs_pr_debug(1, "ASSOC_RESP: currentpacketfilter is %x\n",
lbs_deb_join("ASSOC_RESP: currentpacketfilter is %x\n",
adapter->currentpacketfilter);
adapter->SNR[TYPE_RXPD][TYPE_AVG] = 0;
......@@ -806,28 +756,31 @@ int libertas_ret_80211_associate(wlan_private * priv,
adapter->nextSNRNF = 0;
adapter->numSNRNF = 0;
netif_carrier_on(priv->wlan_dev.netdev);
netif_wake_queue(priv->wlan_dev.netdev);
netif_carrier_on(priv->dev);
netif_wake_queue(priv->dev);
lbs_pr_debug(1, "ASSOC_RESP: Associated \n");
netif_carrier_on(priv->mesh_dev);
netif_wake_queue(priv->mesh_dev);
lbs_deb_join("ASSOC_RESP: Associated \n");
memcpy(wrqu.ap_addr.sa_data, adapter->curbssparams.bssid, ETH_ALEN);
wrqu.ap_addr.sa_family = ARPHRD_ETHER;
wireless_send_event(priv->wlan_dev.netdev, SIOCGIWAP, &wrqu, NULL);
wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
done:
LEAVE();
done:
lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
return ret;
}
int libertas_ret_80211_disassociate(wlan_private * priv,
struct cmd_ds_command *resp)
{
ENTER();
lbs_deb_enter(LBS_DEB_JOIN);
libertas_mac_event_disconnected(priv);
LEAVE();
lbs_deb_leave(LBS_DEB_JOIN);
return 0;
}
......@@ -840,90 +793,85 @@ int libertas_ret_80211_ad_hoc_start(wlan_private * priv,
u16 result = le16_to_cpu(resp->result);
struct cmd_ds_802_11_ad_hoc_result *padhocresult;
union iwreq_data wrqu;
struct bss_descriptor *pbssdesc;
struct bss_descriptor *bss;
ENTER();
lbs_deb_enter(LBS_DEB_JOIN);
padhocresult = &resp->params.result;
lbs_pr_debug(1, "ADHOC_S_RESP: size = %d\n", le16_to_cpu(resp->size));
lbs_pr_debug(1, "ADHOC_S_RESP: command = %x\n", command);
lbs_pr_debug(1, "ADHOC_S_RESP: result = %x\n", result);
lbs_deb_join("ADHOC_RESP: size = %d\n", le16_to_cpu(resp->size));
lbs_deb_join("ADHOC_RESP: command = %x\n", command);
lbs_deb_join("ADHOC_RESP: result = %x\n", result);
pbssdesc = adapter->pattemptedbssdesc;
if (!adapter->in_progress_assoc_req) {
lbs_deb_join("ADHOC_RESP: no in-progress association request\n");
ret = -1;
goto done;
}
bss = &adapter->in_progress_assoc_req->bss;
/*
* Join result code 0 --> SUCCESS
*/
if (result) {
lbs_pr_debug(1, "ADHOC_RESP failed\n");
lbs_deb_join("ADHOC_RESP: failed\n");
if (adapter->connect_status == libertas_connected) {
libertas_mac_event_disconnected(priv);
}
memset(&adapter->curbssparams.bssdescriptor,
0x00, sizeof(adapter->curbssparams.bssdescriptor));
LEAVE();
return -1;
ret = -1;
goto done;
}
/*
* Now the join cmd should be successful
* If BSSID has changed use SSID to compare instead of BSSID
*/
lbs_pr_debug(1, "ADHOC_J_RESP %s\n", pbssdesc->ssid.ssid);
lbs_deb_join("ADHOC_RESP: associated to '%s'\n",
escape_essid(bss->ssid, bss->ssid_len));
/* Send a Media Connected event, according to the Spec */
adapter->connect_status = libertas_connected;
if (command == cmd_ret_802_11_ad_hoc_start) {
/* Update the created network descriptor with the new BSSID */
memcpy(pbssdesc->macaddress,
padhocresult->BSSID, ETH_ALEN);
} else {
/* Make a copy of current BSSID descriptor, only needed for join since
* the current descriptor is already being used for adhoc start
*/
memmove(&adapter->curbssparams.bssdescriptor,
pbssdesc, sizeof(struct bss_descriptor));
memcpy(bss->bssid, padhocresult->BSSID, ETH_ALEN);
}
/* Set the BSSID from the joined/started descriptor */
memcpy(&adapter->curbssparams.bssid,
pbssdesc->macaddress, ETH_ALEN);
memcpy(&adapter->curbssparams.bssid, bss->bssid, ETH_ALEN);
/* Set the new SSID to current SSID */
memcpy(&adapter->curbssparams.ssid,
&pbssdesc->ssid, sizeof(struct WLAN_802_11_SSID));
memcpy(&adapter->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
adapter->curbssparams.ssid_len = bss->ssid_len;
netif_carrier_on(priv->dev);
netif_wake_queue(priv->dev);
netif_carrier_on(priv->wlan_dev.netdev);
netif_wake_queue(priv->wlan_dev.netdev);
netif_carrier_on(priv->mesh_dev);
netif_wake_queue(priv->mesh_dev);
memset(&wrqu, 0, sizeof(wrqu));
memcpy(wrqu.ap_addr.sa_data, adapter->curbssparams.bssid, ETH_ALEN);
wrqu.ap_addr.sa_family = ARPHRD_ETHER;
wireless_send_event(priv->wlan_dev.netdev, SIOCGIWAP, &wrqu, NULL);
wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
lbs_pr_debug(1, "ADHOC_RESP: - Joined/Started Ad Hoc\n");
lbs_pr_debug(1, "ADHOC_RESP: channel = %d\n", adapter->adhocchannel);
lbs_pr_debug(1, "ADHOC_RESP: BSSID = %02x:%02x:%02x:%02x:%02x:%02x\n",
padhocresult->BSSID[0], padhocresult->BSSID[1],
padhocresult->BSSID[2], padhocresult->BSSID[3],
padhocresult->BSSID[4], padhocresult->BSSID[5]);
lbs_deb_join("ADHOC_RESP: - Joined/Started Ad Hoc\n");
lbs_deb_join("ADHOC_RESP: channel = %d\n", adapter->curbssparams.channel);
lbs_deb_join("ADHOC_RESP: BSSID = " MAC_FMT "\n",
MAC_ARG(padhocresult->BSSID));
LEAVE();
done:
lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
return ret;
}
int libertas_ret_80211_ad_hoc_stop(wlan_private * priv,
struct cmd_ds_command *resp)
{
ENTER();
lbs_deb_enter(LBS_DEB_JOIN);
libertas_mac_event_disconnected(priv);
LEAVE();
lbs_deb_leave(LBS_DEB_JOIN);
return 0;
}
......@@ -9,6 +9,7 @@
#define _WLAN_JOIN_H
#include "defs.h"
#include "dev.h"
struct cmd_ds_command;
extern int libertas_cmd_80211_authenticate(wlan_private * priv,
......@@ -21,7 +22,7 @@ extern int libertas_cmd_80211_ad_hoc_stop(wlan_private * priv,
struct cmd_ds_command *cmd);
extern int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
struct cmd_ds_command *cmd,
void *pssid);
void *pdata_buf);
extern int libertas_cmd_80211_deauthenticate(wlan_private * priv,
struct cmd_ds_command *cmd);
extern int libertas_cmd_80211_associate(wlan_private * priv,
......@@ -39,12 +40,10 @@ extern int libertas_ret_80211_associate(wlan_private * priv,
extern int libertas_reassociation_thread(void *data);
struct WLAN_802_11_SSID;
struct bss_descriptor;
extern int libertas_start_adhoc_network(wlan_private * priv,
struct WLAN_802_11_SSID *adhocssid);
extern int libertas_join_adhoc_network(wlan_private * priv, struct bss_descriptor *pbssdesc);
struct assoc_request * assoc_req);
extern int libertas_join_adhoc_network(wlan_private * priv,
struct assoc_request * assoc_req);
extern int libertas_stop_adhoc_network(wlan_private * priv);
extern int libertas_send_deauthentication(wlan_private * priv);
......@@ -52,6 +51,6 @@ extern int libertas_send_deauth(wlan_private * priv);
extern int libertas_do_adhocstop_ioctl(wlan_private * priv);
int wlan_associate(wlan_private * priv, struct bss_descriptor * pbssdesc);
int wlan_associate(wlan_private * priv, struct assoc_request * assoc_req);
#endif
......@@ -4,6 +4,7 @@
* thread etc..
*/
#include <linux/moduleparam.h>
#include <linux/delay.h>
#include <linux/freezer.h>
#include <linux/etherdevice.h>
......@@ -11,26 +12,28 @@
#include <linux/if_arp.h>
#include <net/iw_handler.h>
#include <net/ieee80211.h>
#include "host.h"
#include "sbi.h"
#include "decl.h"
#include "dev.h"
#include "fw.h"
#include "wext.h"
#include "debugfs.h"
#include "assoc.h"
#define DRIVER_RELEASE_VERSION "320.p0"
#define DRIVER_RELEASE_VERSION "322.p0"
const char libertas_driver_version[] = "COMM-USB8388-" DRIVER_RELEASE_VERSION
#ifdef DEBUG
"-dbg"
#endif
"";
#ifdef ENABLE_PM
static struct pm_dev *wlan_pm_dev = NULL;
#endif
/* Module parameters */
unsigned int libertas_debug = 0;
module_param(libertas_debug, int, 0644);
EXPORT_SYMBOL_GPL(libertas_debug);
#define WLAN_TX_PWR_DEFAULT 20 /*100mW */
#define WLAN_TX_PWR_US_DEFAULT 20 /*100mW */
......@@ -145,14 +148,6 @@ static struct region_cfp_table region_cfp_table[] = {
/*Add new region here */
};
/**
* the rates supported by the card
*/
u8 libertas_wlan_data_rates[WLAN_SUPPORTED_RATES] =
{ 0x02, 0x04, 0x0B, 0x16, 0x00, 0x0C, 0x12,
0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x00
};
/**
* the rates supported
*/
......@@ -172,24 +167,12 @@ u8 libertas_adhoc_rates_g[G_SUPPORTED_RATES] =
*/
u8 libertas_adhoc_rates_b[4] = { 0x82, 0x84, 0x8b, 0x96 };
/**
* the global variable of a pointer to wlan_private
* structure variable
*/
static wlan_private *wlanpriv = NULL;
#define MAX_DEVS 5
static struct net_device *libertas_devs[MAX_DEVS];
static int libertas_found = 0;
/**
* the table to keep region code
*/
u16 libertas_region_code_to_index[MRVDRV_MAX_REGION_CODE] =
{ 0x10, 0x20, 0x30, 0x31, 0x32, 0x40 };
static u8 *default_fw_name = "usb8388.bin";
/**
* Attributes exported through sysfs
*/
......@@ -207,7 +190,7 @@ static ssize_t libertas_mpp_get(struct device * dev,
cmd_act_mesh_get_mpp,
cmd_option_waitforrsp, 0, (void *)&mesh_access);
return snprintf(buf, 3, "%d\n", mesh_access.data[0]);
return snprintf(buf, 3, "%d\n", le32_to_cpu(mesh_access.data[0]));
}
/**
......@@ -216,10 +199,12 @@ static ssize_t libertas_mpp_get(struct device * dev,
static ssize_t libertas_mpp_set(struct device * dev,
struct device_attribute *attr, const char * buf, size_t count) {
struct cmd_ds_mesh_access mesh_access;
uint32_t datum;
memset(&mesh_access, 0, sizeof(mesh_access));
sscanf(buf, "%d", &(mesh_access.data[0]));
sscanf(buf, "%d", &datum);
mesh_access.data[0] = cpu_to_le32(datum);
libertas_prepare_and_send_command((to_net_dev(dev))->priv,
cmd_mesh_access,
cmd_act_mesh_set_mpp,
......@@ -231,8 +216,7 @@ static ssize_t libertas_mpp_set(struct device * dev,
* libertas_mpp attribute to be exported per mshX interface
* through sysfs (/sys/class/net/mshX/libertas-mpp)
*/
static DEVICE_ATTR(libertas_mpp, 0644, libertas_mpp_get,
libertas_mpp_set );
static DEVICE_ATTR(libertas_mpp, 0644, libertas_mpp_get, libertas_mpp_set );
/**
* @brief Check if the device can be open and wait if necessary.
......@@ -245,7 +229,8 @@ static DEVICE_ATTR(libertas_mpp, 0644, libertas_mpp_get,
* function to work around the issue.
*
*/
static int pre_open_check(struct net_device *dev) {
static int pre_open_check(struct net_device *dev)
{
wlan_private *priv = (wlan_private *) dev->priv;
wlan_adapter *adapter = priv->adapter;
int i = 0;
......@@ -255,8 +240,7 @@ static int pre_open_check(struct net_device *dev) {
msleep_interruptible(100);
}
if (!adapter->fw_ready) {
lbs_pr_info("FW not ready, pre_open_check() return failure\n");
LEAVE();
lbs_pr_err("firmware not ready\n");
return -1;
}
......@@ -274,17 +258,19 @@ static int wlan_dev_open(struct net_device *dev)
wlan_private *priv = (wlan_private *) dev->priv;
wlan_adapter *adapter = priv->adapter;
ENTER();
lbs_deb_enter(LBS_DEB_NET);
priv->open = 1;
if (adapter->connect_status == libertas_connected) {
netif_carrier_on(priv->wlan_dev.netdev);
} else
netif_carrier_off(priv->wlan_dev.netdev);
netif_carrier_on(priv->dev);
netif_carrier_on(priv->mesh_dev);
} else {
netif_carrier_off(priv->dev);
netif_carrier_off(priv->mesh_dev);
}
LEAVE();
lbs_deb_leave(LBS_DEB_NET);
return 0;
}
/**
......@@ -297,12 +283,12 @@ static int mesh_open(struct net_device *dev)
{
wlan_private *priv = (wlan_private *) dev->priv ;
if(pre_open_check(dev) == -1)
if (pre_open_check(dev) == -1)
return -1;
priv->mesh_open = 1 ;
netif_start_queue(priv->mesh_dev);
netif_wake_queue(priv->mesh_dev);
if (priv->infra_open == 0)
return wlan_dev_open(priv->wlan_dev.netdev) ;
return wlan_dev_open(priv->dev) ;
return 0;
}
......@@ -319,9 +305,9 @@ static int wlan_open(struct net_device *dev)
if(pre_open_check(dev) == -1)
return -1;
priv->infra_open = 1 ;
netif_wake_queue(priv->wlan_dev.netdev);
netif_wake_queue(priv->dev);
if (priv->open == 0)
return wlan_dev_open(priv->wlan_dev.netdev) ;
return wlan_dev_open(priv->dev) ;
return 0;
}
......@@ -329,12 +315,12 @@ static int wlan_dev_close(struct net_device *dev)
{
wlan_private *priv = dev->priv;
ENTER();
lbs_deb_enter(LBS_DEB_NET);
netif_carrier_off(priv->wlan_dev.netdev);
netif_carrier_off(priv->dev);
priv->open = 0;
LEAVE();
lbs_deb_leave(LBS_DEB_NET);
return 0;
}
......@@ -351,7 +337,7 @@ static int mesh_close(struct net_device *dev)
priv->mesh_open = 0;
netif_stop_queue(priv->mesh_dev);
if (priv->infra_open == 0)
return wlan_dev_close( ((wlan_private *) dev->priv)->wlan_dev.netdev) ;
return wlan_dev_close(dev);
else
return 0;
}
......@@ -362,147 +348,38 @@ static int mesh_close(struct net_device *dev)
* @param dev A pointer to net_device structure
* @return 0
*/
static int wlan_close(struct net_device *dev) {
static int wlan_close(struct net_device *dev)
{
wlan_private *priv = (wlan_private *) dev->priv;
netif_stop_queue(priv->wlan_dev.netdev);
netif_stop_queue(dev);
priv->infra_open = 0;
if (priv->mesh_open == 0)
return wlan_dev_close( ((wlan_private *) dev->priv)->wlan_dev.netdev) ;
return wlan_dev_close(dev);
else
return 0;
}
#ifdef ENABLE_PM
/**
* @brief This function is a callback function. it is called by
* kernel to enter or exit power saving mode.
*
* @param pmdev A pointer to pm_dev
* @param pmreq pm_request_t
* @param pmdata A pointer to pmdata
* @return 0 or -1
*/
static int wlan_pm_callback(struct pm_dev *pmdev, pm_request_t pmreq,
void *pmdata)
{
wlan_private *priv = wlanpriv;
wlan_adapter *adapter = priv->adapter;
struct net_device *dev = priv->wlan_dev.netdev;
lbs_pr_debug(1, "WPRM_PM_CALLBACK: pmreq = %d.\n", pmreq);
switch (pmreq) {
case PM_SUSPEND:
lbs_pr_debug(1, "WPRM_PM_CALLBACK: enter PM_SUSPEND.\n");
/* in associated mode */
if (adapter->connect_status == libertas_connected) {
if ((adapter->psstate != PS_STATE_SLEEP)
) {
lbs_pr_debug(1,
"wlan_pm_callback: can't enter sleep mode\n");
return -1;
} else {
/*
* Detach the network interface
* if the network is running
*/
if (netif_running(dev)) {
netif_device_detach(dev);
lbs_pr_debug(1,
"netif_device_detach().\n");
}
libertas_sbi_suspend(priv);
}
break;
}
/* in non associated mode */
/*
* Detach the network interface
* if the network is running
*/
if (netif_running(dev))
netif_device_detach(dev);
/*
* Storing and restoring of the regs be taken care
* at the driver rest will be done at wlan driver
* this makes driver independent of the card
*/
libertas_sbi_suspend(priv);
break;
case PM_RESUME:
/* in associated mode */
if (adapter->connect_status == libertas_connected) {
{
/*
* Bring the inteface up first
* This case should not happen still ...
*/
libertas_sbi_resume(priv);
/*
* Attach the network interface
* if the network is running
*/
if (netif_running(dev)) {
netif_device_attach(dev);
lbs_pr_debug(1,
"after netif_device_attach().\n");
}
lbs_pr_debug(1,
"After netif attach, in associated mode.\n");
}
break;
}
/* in non associated mode */
/*
* Bring the inteface up first
* This case should not happen still ...
*/
libertas_sbi_resume(priv);
if (netif_running(dev))
netif_device_attach(dev);
lbs_pr_debug(1, "after netif attach, in NON associated mode.\n");
break;
}
return 0;
}
#endif /* ENABLE_PM */
static int wlan_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
int ret = 0;
wlan_private *priv = dev->priv;
ENTER();
lbs_deb_enter(LBS_DEB_NET);
if (priv->wlan_dev.dnld_sent || priv->adapter->TxLockFlag) {
if (priv->dnld_sent || priv->adapter->TxLockFlag) {
priv->stats.tx_dropped++;
goto done;
}
netif_stop_queue(priv->wlan_dev.netdev);
netif_stop_queue(priv->dev);
netif_stop_queue(priv->mesh_dev);
if (libertas_process_tx(priv, skb) == 0)
dev->trans_start = jiffies;
done:
LEAVE();
lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
return ret;
}
......@@ -513,33 +390,43 @@ static int wlan_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
static int mesh_pre_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
wlan_private *priv = dev->priv;
ENTER();
int ret;
lbs_deb_enter(LBS_DEB_MESH);
SET_MESH_FRAME(skb);
LEAVE();
return wlan_hard_start_xmit(skb, priv->wlan_dev.netdev);
ret = wlan_hard_start_xmit(skb, priv->dev);
lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
return ret;
}
/**
* @brief Mark non-mesh packets and handover them to wlan_hard_start_xmit
*
*/
static int wlan_pre_start_xmit(struct sk_buff *skb, struct net_device *dev) {
ENTER();
static int wlan_pre_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
int ret;
lbs_deb_enter(LBS_DEB_NET);
UNSET_MESH_FRAME(skb);
LEAVE();
return wlan_hard_start_xmit(skb, dev);
ret = wlan_hard_start_xmit(skb, dev);
lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
return ret;
}
static void wlan_tx_timeout(struct net_device *dev)
{
wlan_private *priv = (wlan_private *) dev->priv;
ENTER();
lbs_deb_enter(LBS_DEB_TX);
lbs_pr_err("tx watch dog timeout!\n");
lbs_pr_err("tx watch dog timeout\n");
priv->wlan_dev.dnld_sent = DNLD_RES_RECEIVED;
priv->dnld_sent = DNLD_RES_RECEIVED;
dev->trans_start = jiffies;
if (priv->adapter->currenttxskb) {
......@@ -550,10 +437,12 @@ static void wlan_tx_timeout(struct net_device *dev)
libertas_send_tx_feedback(priv);
} else
wake_up_interruptible(&priv->mainthread.waitq);
} else if (priv->adapter->connect_status == libertas_connected)
netif_wake_queue(priv->wlan_dev.netdev);
} else if (priv->adapter->connect_status == libertas_connected) {
netif_wake_queue(priv->dev);
netif_wake_queue(priv->mesh_dev);
}
LEAVE();
lbs_deb_leave(LBS_DEB_TX);
}
/**
......@@ -576,7 +465,10 @@ static int wlan_set_mac_address(struct net_device *dev, void *addr)
wlan_adapter *adapter = priv->adapter;
struct sockaddr *phwaddr = addr;
ENTER();
lbs_deb_enter(LBS_DEB_NET);
/* In case it was called from the mesh device */
dev = priv->dev ;
memset(adapter->current_addr, 0, ETH_ALEN);
......@@ -591,17 +483,18 @@ static int wlan_set_mac_address(struct net_device *dev, void *addr)
cmd_option_waitforrsp, 0, NULL);
if (ret) {
lbs_pr_debug(1, "set mac address failed.\n");
lbs_deb_net("set MAC address failed\n");
ret = -1;
goto done;
}
lbs_dbg_hex("adapter->macaddr:", adapter->current_addr, ETH_ALEN);
memcpy(dev->dev_addr, adapter->current_addr, ETH_ALEN);
memcpy(((wlan_private *) dev->priv)->mesh_dev->dev_addr, adapter->current_addr, ETH_ALEN);
if (priv->mesh_dev)
memcpy(priv->mesh_dev->dev_addr, adapter->current_addr, ETH_ALEN);
done:
LEAVE();
lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
return ret;
}
......@@ -626,12 +519,12 @@ static void wlan_set_multicast_list(struct net_device *dev)
wlan_adapter *adapter = priv->adapter;
int oldpacketfilter;
ENTER();
lbs_deb_enter(LBS_DEB_NET);
oldpacketfilter = adapter->currentpacketfilter;
if (dev->flags & IFF_PROMISC) {
lbs_pr_debug(1, "enable Promiscuous mode\n");
lbs_deb_net("enable promiscuous mode\n");
adapter->currentpacketfilter |=
cmd_act_mac_promiscuous_enable;
adapter->currentpacketfilter &=
......@@ -644,7 +537,7 @@ static void wlan_set_multicast_list(struct net_device *dev)
if (dev->flags & IFF_ALLMULTI || dev->mc_count >
MRVDRV_MAX_MULTICAST_LIST_SIZE) {
lbs_pr_debug(1, "Enabling All Multicast!\n");
lbs_deb_net( "enabling all multicast\n");
adapter->currentpacketfilter |=
cmd_act_mac_all_multicast_enable;
adapter->currentpacketfilter &=
......@@ -654,8 +547,8 @@ static void wlan_set_multicast_list(struct net_device *dev)
~cmd_act_mac_all_multicast_enable;
if (!dev->mc_count) {
lbs_pr_debug(1, "No multicast addresses - "
"disabling multicast!\n");
lbs_deb_net("no multicast addresses, "
"disabling multicast\n");
adapter->currentpacketfilter &=
~cmd_act_mac_multicast_enable;
} else {
......@@ -667,12 +560,12 @@ static void wlan_set_multicast_list(struct net_device *dev)
adapter->nr_of_multicastmacaddr =
wlan_copy_multicast_address(adapter, dev);
lbs_pr_debug(1, "Multicast addresses: %d\n",
lbs_deb_net("multicast addresses: %d\n",
dev->mc_count);
for (i = 0; i < dev->mc_count; i++) {
lbs_pr_debug(1, "Multicast address %d:"
"%x %x %x %x %x %x\n", i,
lbs_deb_net("Multicast address %d:"
MAC_FMT "\n", i,
adapter->multicastlist[i][0],
adapter->multicastlist[i][1],
adapter->multicastlist[i][2],
......@@ -680,7 +573,7 @@ static void wlan_set_multicast_list(struct net_device *dev)
adapter->multicastlist[i][4],
adapter->multicastlist[i][5]);
}
/* set multicast addresses to firmware */
/* send multicast addresses to firmware */
libertas_prepare_and_send_command(priv,
cmd_mac_multicast_adr,
cmd_act_set, 0, 0,
......@@ -693,13 +586,13 @@ static void wlan_set_multicast_list(struct net_device *dev)
libertas_set_mac_packet_filter(priv);
}
LEAVE();
lbs_deb_leave(LBS_DEB_NET);
}
/**
* @brief This function hanldes the major job in WLAN driver.
* it handles the event generated by firmware, rx data received
* from firmware and tx data sent from kernel.
* @brief This function handles the major jobs in the WLAN driver.
* It handles all events generated by firmware, RX data received
* from firmware and TX data sent from kernel.
*
* @param data A pointer to wlan_thread structure
* @return 0
......@@ -712,26 +605,26 @@ static int wlan_service_main_thread(void *data)
wait_queue_t wait;
u8 ireg = 0;
ENTER();
lbs_deb_enter(LBS_DEB_THREAD);
wlan_activate_thread(thread);
init_waitqueue_entry(&wait, current);
for (;;) {
lbs_pr_debug(1, "main-thread 111: intcounter=%d "
lbs_deb_thread( "main-thread 111: intcounter=%d "
"currenttxskb=%p dnld_sent=%d\n",
adapter->intcounter,
adapter->currenttxskb, priv->wlan_dev.dnld_sent);
adapter->currenttxskb, priv->dnld_sent);
add_wait_queue(&thread->waitq, &wait);
set_current_state(TASK_INTERRUPTIBLE);
spin_lock_irq(&adapter->driver_lock);
if ((adapter->psstate == PS_STATE_SLEEP) ||
(!adapter->intcounter
&& (priv->wlan_dev.dnld_sent || adapter->cur_cmd ||
&& (priv->dnld_sent || adapter->cur_cmd ||
list_empty(&adapter->cmdpendingq)))) {
lbs_pr_debug(1,
lbs_deb_thread(
"main-thread sleeping... Conn=%d IntC=%d PS_mode=%d PS_State=%d\n",
adapter->connect_status, adapter->intcounter,
adapter->psmode, adapter->psstate);
......@@ -741,23 +634,23 @@ static int wlan_service_main_thread(void *data)
spin_unlock_irq(&adapter->driver_lock);
lbs_pr_debug(1,
lbs_deb_thread(
"main-thread 222 (waking up): intcounter=%d currenttxskb=%p "
"dnld_sent=%d\n", adapter->intcounter,
adapter->currenttxskb, priv->wlan_dev.dnld_sent);
adapter->currenttxskb, priv->dnld_sent);
set_current_state(TASK_RUNNING);
remove_wait_queue(&thread->waitq, &wait);
try_to_freeze();
lbs_pr_debug(1, "main-thread 333: intcounter=%d currenttxskb=%p "
lbs_deb_thread("main-thread 333: intcounter=%d currenttxskb=%p "
"dnld_sent=%d\n",
adapter->intcounter,
adapter->currenttxskb, priv->wlan_dev.dnld_sent);
adapter->currenttxskb, priv->dnld_sent);
if (kthread_should_stop()
|| adapter->surpriseremoved) {
lbs_pr_debug(1,
lbs_deb_thread(
"main-thread: break from main thread: surpriseremoved=0x%x\n",
adapter->surpriseremoved);
break;
......@@ -768,10 +661,10 @@ static int wlan_service_main_thread(void *data)
if (adapter->intcounter) {
u8 int_status;
adapter->intcounter = 0;
int_status = libertas_sbi_get_int_status(priv, &ireg);
int_status = priv->hw_get_int_status(priv, &ireg);
if (int_status) {
lbs_pr_debug(1,
lbs_deb_thread(
"main-thread: reading HOST_INT_STATUS_REG failed\n");
spin_unlock_irq(&adapter->driver_lock);
continue;
......@@ -779,14 +672,14 @@ static int wlan_service_main_thread(void *data)
adapter->hisregcpy |= ireg;
}
lbs_pr_debug(1, "main-thread 444: intcounter=%d currenttxskb=%p "
lbs_deb_thread("main-thread 444: intcounter=%d currenttxskb=%p "
"dnld_sent=%d\n",
adapter->intcounter,
adapter->currenttxskb, priv->wlan_dev.dnld_sent);
adapter->currenttxskb, priv->dnld_sent);
/* command response? */
if (adapter->hisregcpy & his_cmdupldrdy) {
lbs_pr_debug(1, "main-thread: cmd response ready.\n");
lbs_deb_thread("main-thread: cmd response ready\n");
adapter->hisregcpy &= ~his_cmdupldrdy;
spin_unlock_irq(&adapter->driver_lock);
......@@ -796,13 +689,13 @@ static int wlan_service_main_thread(void *data)
/* Any Card Event */
if (adapter->hisregcpy & his_cardevent) {
lbs_pr_debug(1, "main-thread: Card Event Activity.\n");
lbs_deb_thread("main-thread: Card Event Activity\n");
adapter->hisregcpy &= ~his_cardevent;
if (libertas_sbi_read_event_cause(priv)) {
if (priv->hw_read_event_cause(priv)) {
lbs_pr_alert(
"main-thread: libertas_sbi_read_event_cause failed.\n");
"main-thread: hw_read_event_cause failed\n");
spin_unlock_irq(&adapter->driver_lock);
continue;
}
......@@ -813,15 +706,15 @@ static int wlan_service_main_thread(void *data)
/* Check if we need to confirm Sleep Request received previously */
if (adapter->psstate == PS_STATE_PRE_SLEEP) {
if (!priv->wlan_dev.dnld_sent && !adapter->cur_cmd) {
if (!priv->dnld_sent && !adapter->cur_cmd) {
if (adapter->connect_status ==
libertas_connected) {
lbs_pr_debug(1,
lbs_deb_thread(
"main_thread: PRE_SLEEP--intcounter=%d currenttxskb=%p "
"dnld_sent=%d cur_cmd=%p, confirm now\n",
adapter->intcounter,
adapter->currenttxskb,
priv->wlan_dev.dnld_sent,
priv->dnld_sent,
adapter->cur_cmd);
libertas_ps_confirm_sleep(priv,
......@@ -847,7 +740,7 @@ static int wlan_service_main_thread(void *data)
continue;
/* Execute the next command */
if (!priv->wlan_dev.dnld_sent && !priv->adapter->cur_cmd)
if (!priv->dnld_sent && !priv->adapter->cur_cmd)
libertas_execute_next_command(priv);
/* Wake-up command waiters which can't sleep in
......@@ -864,7 +757,7 @@ static int wlan_service_main_thread(void *data)
wake_up_all(&adapter->cmd_pending);
wlan_deactivate_thread(thread);
LEAVE();
lbs_deb_leave(LBS_DEB_THREAD);
return 0;
}
......@@ -875,49 +768,32 @@ static int wlan_service_main_thread(void *data)
* @param card A pointer to card
* @return A pointer to wlan_private structure
*/
wlan_private *wlan_add_card(void *card)
wlan_private *libertas_add_card(void *card, struct device *dmdev)
{
struct net_device *dev = NULL;
struct net_device *mesh_dev = NULL;
wlan_private *priv = NULL;
ENTER();
lbs_deb_enter(LBS_DEB_NET);
/* Allocate an Ethernet device and register it */
if (!(dev = alloc_etherdev(sizeof(wlan_private)))) {
lbs_pr_alert( "Init ethernet device failed!\n");
lbs_pr_err("init ethX device failed\n");
return NULL;
}
priv = dev->priv;
/* allocate buffer for wlan_adapter */
if (!(priv->adapter = kmalloc(sizeof(wlan_adapter), GFP_KERNEL))) {
lbs_pr_alert( "Allocate buffer for wlan_adapter failed!\n");
goto err_kmalloc;
}
/* Allocate a virtual mesh device */
if (!(mesh_dev = alloc_netdev(0, "msh%d", ether_setup))) {
lbs_pr_debug(1, "Init ethernet device failed!\n");
return NULL;
if (!(priv->adapter = kzalloc(sizeof(wlan_adapter), GFP_KERNEL))) {
lbs_pr_err("allocate buffer for wlan_adapter failed\n");
goto err_kzalloc;
}
/* Both intervaces share the priv structure */
mesh_dev->priv = priv;
/* init wlan_adapter */
memset(priv->adapter, 0, sizeof(wlan_adapter));
priv->wlan_dev.netdev = dev;
priv->wlan_dev.card = card;
priv->dev = dev;
priv->card = card;
priv->mesh_open = 0;
priv->infra_open = 0;
priv->mesh_dev = mesh_dev;
wlanpriv = priv;
SET_MODULE_OWNER(dev);
SET_MODULE_OWNER(mesh_dev);
/* Setup the OS Interface to our functions */
dev->open = wlan_open;
......@@ -925,116 +801,171 @@ wlan_private *wlan_add_card(void *card)
dev->stop = wlan_close;
dev->do_ioctl = libertas_do_ioctl;
dev->set_mac_address = wlan_set_mac_address;
mesh_dev->open = mesh_open;
mesh_dev->hard_start_xmit = mesh_pre_start_xmit;
mesh_dev->stop = mesh_close;
mesh_dev->do_ioctl = libertas_do_ioctl;
memcpy(mesh_dev->dev_addr, wlanpriv->wlan_dev.netdev->dev_addr,
sizeof(wlanpriv->wlan_dev.netdev->dev_addr));
#define WLAN_WATCHDOG_TIMEOUT (5 * HZ)
dev->tx_timeout = wlan_tx_timeout;
dev->get_stats = wlan_get_stats;
dev->watchdog_timeo = WLAN_WATCHDOG_TIMEOUT;
dev->watchdog_timeo = 5 * HZ;
dev->ethtool_ops = &libertas_ethtool_ops;
mesh_dev->get_stats = wlan_get_stats;
mesh_dev->ethtool_ops = &libertas_ethtool_ops;
#ifdef WIRELESS_EXT
dev->wireless_handlers = (struct iw_handler_def *)&libertas_handler_def;
mesh_dev->wireless_handlers = (struct iw_handler_def *)&libertas_handler_def;
#endif
#define NETIF_F_DYNALLOC 16
dev->features |= NETIF_F_DYNALLOC;
dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
dev->set_multicast_list = wlan_set_multicast_list;
SET_NETDEV_DEV(dev, dmdev);
INIT_LIST_HEAD(&priv->adapter->cmdfreeq);
INIT_LIST_HEAD(&priv->adapter->cmdpendingq);
spin_lock_init(&priv->adapter->driver_lock);
init_waitqueue_head(&priv->adapter->cmd_pending);
priv->adapter->nr_cmd_pending = 0;
goto done;
err_kzalloc:
free_netdev(dev);
priv = NULL;
done:
lbs_deb_leave_args(LBS_DEB_NET, "priv %p", priv);
return priv;
}
EXPORT_SYMBOL_GPL(libertas_add_card);
int libertas_activate_card(wlan_private *priv, char *fw_name)
{
struct net_device *dev = priv->dev;
int ret = -1;
lbs_pr_debug(1, "Starting kthread...\n");
lbs_deb_enter(LBS_DEB_MAIN);
lbs_deb_thread("Starting kthread...\n");
priv->mainthread.priv = priv;
wlan_create_thread(wlan_service_main_thread,
&priv->mainthread, "wlan_main_service");
priv->assoc_thread =
create_singlethread_workqueue("libertas_assoc");
INIT_DELAYED_WORK(&priv->assoc_work, wlan_association_worker);
INIT_DELAYED_WORK(&priv->assoc_work, libertas_association_worker);
/*
* Register the device. Fillup the private data structure with
* relevant information from the card and request for the required
* IRQ.
*/
if (libertas_sbi_register_dev(priv) < 0) {
lbs_pr_info("failed to register wlan device!\n");
if (priv->hw_register_dev(priv) < 0) {
lbs_pr_err("failed to register WLAN device\n");
goto err_registerdev;
}
/* init FW and HW */
if (libertas_init_fw(priv)) {
lbs_pr_debug(1, "Firmware Init failed\n");
if (fw_name && libertas_init_fw(priv, fw_name)) {
lbs_pr_err("firmware init failed\n");
goto err_registerdev;
}
if (register_netdev(dev)) {
lbs_pr_err("Cannot register network device!\n");
goto err_init_fw;
}
/* Register virtual mesh interface */
if (register_netdev(mesh_dev)) {
lbs_pr_info("Cannot register mesh virtual interface!\n");
lbs_pr_err("cannot register ethX device\n");
goto err_init_fw;
}
lbs_pr_info("%s: Marvell Wlan 802.11 adapter ", dev->name);
lbs_pr_info("%s: Marvell WLAN 802.11 adapter\n", dev->name);
libertas_debugfs_init_one(priv, dev);
if (libertas_found == MAX_DEVS)
goto err_init_fw;
libertas_devs[libertas_found] = dev;
libertas_found++;
#ifdef ENABLE_PM
if (!(wlan_pm_dev = pm_register(PM_UNKNOWN_DEV, 0, wlan_pm_callback)))
lbs_pr_alert( "failed to register PM callback\n");
#endif
if (device_create_file(&(mesh_dev->dev), &dev_attr_libertas_mpp))
goto err_create_file;
LEAVE();
return priv;
ret = 0;
goto done;
err_create_file:
device_remove_file(&(mesh_dev->dev), &dev_attr_libertas_mpp);
err_init_fw:
libertas_sbi_unregister_dev(priv);
priv->hw_unregister_dev(priv);
err_registerdev:
destroy_workqueue(priv->assoc_thread);
/* Stop the thread servicing the interrupts */
wake_up_interruptible(&priv->mainthread.waitq);
wlan_terminate_thread(&priv->mainthread);
kfree(priv->adapter);
err_kmalloc:
free_netdev(dev);
done:
lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
return ret;
}
EXPORT_SYMBOL_GPL(libertas_activate_card);
/**
* @brief This function adds mshX interface
*
* @param priv A pointer to the wlan_private structure
* @return 0 if successful, -X otherwise
*/
int libertas_add_mesh(wlan_private *priv, struct device *dev)
{
struct net_device *mesh_dev = NULL;
int ret = 0;
lbs_deb_enter(LBS_DEB_MESH);
/* Allocate a virtual mesh device */
if (!(mesh_dev = alloc_netdev(0, "msh%d", ether_setup))) {
lbs_deb_mesh("init mshX device failed\n");
ret = -ENOMEM;
goto done;
}
mesh_dev->priv = priv;
priv->mesh_dev = mesh_dev;
SET_MODULE_OWNER(mesh_dev);
mesh_dev->open = mesh_open;
mesh_dev->hard_start_xmit = mesh_pre_start_xmit;
mesh_dev->stop = mesh_close;
mesh_dev->do_ioctl = libertas_do_ioctl;
mesh_dev->get_stats = wlan_get_stats;
mesh_dev->set_mac_address = wlan_set_mac_address;
mesh_dev->ethtool_ops = &libertas_ethtool_ops;
memcpy(mesh_dev->dev_addr, priv->dev->dev_addr,
sizeof(priv->dev->dev_addr));
SET_NETDEV_DEV(priv->mesh_dev, dev);
#ifdef WIRELESS_EXT
mesh_dev->wireless_handlers = (struct iw_handler_def *)&mesh_handler_def;
#endif
#define NETIF_F_DYNALLOC 16
/* Register virtual mesh interface */
ret = register_netdev(mesh_dev);
if (ret) {
lbs_pr_err("cannot register mshX virtual interface\n");
goto err_free;
}
ret = device_create_file(&(mesh_dev->dev), &dev_attr_libertas_mpp);
if (ret)
goto err_unregister;
/* Everything successful */
ret = 0;
goto done;
err_unregister:
unregister_netdev(mesh_dev);
err_free:
free_netdev(mesh_dev);
wlanpriv = NULL;
LEAVE();
return NULL;
done:
lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
return ret;
}
EXPORT_SYMBOL_GPL(libertas_add_mesh);
static void wake_pending_cmdnodes(wlan_private *priv)
{
struct cmd_ctrl_node *cmdnode;
unsigned long flags;
lbs_deb_enter(LBS_DEB_CMD);
spin_lock_irqsave(&priv->adapter->driver_lock, flags);
list_for_each_entry(cmdnode, &priv->adapter->cmdpendingq, list) {
cmdnode->cmdwaitqwoken = 1;
......@@ -1044,40 +975,29 @@ static void wake_pending_cmdnodes(wlan_private *priv)
}
int wlan_remove_card(void *card)
int libertas_remove_card(wlan_private *priv)
{
wlan_private *priv = libertas_sbi_get_priv(card);
wlan_adapter *adapter;
struct net_device *dev;
struct net_device *mesh_dev;
union iwreq_data wrqu;
int i;
ENTER();
lbs_deb_enter(LBS_DEB_NET);
if (!priv) {
LEAVE();
return 0;
}
if (!priv)
goto out;
adapter = priv->adapter;
if (!adapter) {
LEAVE();
return 0;
}
if (!adapter)
goto out;
dev = priv->wlan_dev.netdev;
mesh_dev = priv->mesh_dev;
dev = priv->dev;
netif_stop_queue(mesh_dev);
netif_stop_queue(priv->wlan_dev.netdev);
netif_carrier_off(priv->wlan_dev.netdev);
netif_stop_queue(priv->dev);
netif_carrier_off(priv->dev);
wake_pending_cmdnodes(priv);
device_remove_file(&(mesh_dev->dev), &dev_attr_libertas_mpp);
unregister_netdev(mesh_dev);
unregister_netdev(dev);
cancel_delayed_work(&priv->assoc_work);
......@@ -1090,11 +1010,7 @@ int wlan_remove_card(void *card)
memset(wrqu.ap_addr.sa_data, 0xaa, ETH_ALEN);
wrqu.ap_addr.sa_family = ARPHRD_ETHER;
wireless_send_event(priv->wlan_dev.netdev, SIOCGIWAP, &wrqu, NULL);
#ifdef ENABLE_PM
pm_unregister(wlan_pm_dev);
#endif
wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
adapter->surpriseremoved = 1;
......@@ -1103,28 +1019,45 @@ int wlan_remove_card(void *card)
libertas_debugfs_remove_one(priv);
lbs_pr_debug(1, "Free adapter\n");
lbs_deb_net("free adapter\n");
libertas_free_adapter(priv);
for (i = 0; i<libertas_found; i++) {
if (libertas_devs[i]==priv->wlan_dev.netdev) {
libertas_devs[i] = libertas_devs[--libertas_found];
libertas_devs[libertas_found] = NULL ;
break ;
}
}
lbs_deb_net("unregister finish\n");
priv->dev = NULL;
free_netdev(dev);
out:
lbs_deb_leave(LBS_DEB_NET);
return 0;
}
EXPORT_SYMBOL_GPL(libertas_remove_card);
void libertas_remove_mesh(wlan_private *priv)
{
struct net_device *mesh_dev;
lbs_deb_enter(LBS_DEB_NET);
if (!priv)
goto out;
mesh_dev = priv->mesh_dev;
lbs_pr_debug(1, "Unregister finish\n");
netif_stop_queue(mesh_dev);
netif_carrier_off(priv->mesh_dev);
device_remove_file(&(mesh_dev->dev), &dev_attr_libertas_mpp);
unregister_netdev(mesh_dev);
priv->wlan_dev.netdev = NULL;
priv->mesh_dev = NULL ;
free_netdev(mesh_dev);
free_netdev(dev);
wlanpriv = NULL;
LEAVE();
return 0;
out:
lbs_deb_leave(LBS_DEB_NET);
}
EXPORT_SYMBOL_GPL(libertas_remove_mesh);
/**
* @brief This function finds the CFP in
......@@ -1139,33 +1072,34 @@ struct chan_freq_power *libertas_get_region_cfp_table(u8 region, u8 band, int *c
{
int i, end;
ENTER();
lbs_deb_enter(LBS_DEB_MAIN);
end = sizeof(region_cfp_table)/sizeof(struct region_cfp_table);
for (i = 0; i < end ; i++) {
lbs_pr_debug(1, "region_cfp_table[i].region=%d\n",
lbs_deb_main("region_cfp_table[i].region=%d\n",
region_cfp_table[i].region);
if (region_cfp_table[i].region == region) {
*cfp_no = region_cfp_table[i].cfp_no_BG;
LEAVE();
lbs_deb_leave(LBS_DEB_MAIN);
return region_cfp_table[i].cfp_BG;
}
}
LEAVE();
lbs_deb_leave_args(LBS_DEB_MAIN, "ret NULL");
return NULL;
}
int libertas_set_regiontable(wlan_private * priv, u8 region, u8 band)
{
wlan_adapter *adapter = priv->adapter;
int ret = 0;
int i = 0;
struct chan_freq_power *cfp;
int cfp_no;
ENTER();
lbs_deb_enter(LBS_DEB_MAIN);
memset(adapter->region_channel, 0, sizeof(adapter->region_channel));
......@@ -1175,17 +1109,19 @@ int libertas_set_regiontable(wlan_private * priv, u8 region, u8 band)
adapter->region_channel[i].nrcfp = cfp_no;
adapter->region_channel[i].CFP = cfp;
} else {
lbs_pr_debug(1, "wrong region code %#x in band B-G\n",
lbs_deb_main("wrong region code %#x in band B/G\n",
region);
return -1;
ret = -1;
goto out;
}
adapter->region_channel[i].valid = 1;
adapter->region_channel[i].region = region;
adapter->region_channel[i].band = band;
i++;
}
LEAVE();
return 0;
out:
lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
return ret;
}
/**
......@@ -1200,9 +1136,9 @@ void libertas_interrupt(struct net_device *dev)
{
wlan_private *priv = dev->priv;
ENTER();
lbs_deb_enter(LBS_DEB_THREAD);
lbs_pr_debug(1, "libertas_interrupt: intcounter=%d\n",
lbs_deb_thread("libertas_interrupt: intcounter=%d\n",
priv->adapter->intcounter);
priv->adapter->intcounter++;
......@@ -1210,56 +1146,35 @@ void libertas_interrupt(struct net_device *dev)
if (priv->adapter->psstate == PS_STATE_SLEEP) {
priv->adapter->psstate = PS_STATE_AWAKE;
netif_wake_queue(dev);
netif_wake_queue(priv->mesh_dev);
}
wake_up_interruptible(&priv->mainthread.waitq);
LEAVE();
lbs_deb_leave(LBS_DEB_THREAD);
}
EXPORT_SYMBOL_GPL(libertas_interrupt);
static int wlan_init_module(void)
static int libertas_init_module(void)
{
int ret = 0;
ENTER();
if (libertas_fw_name == NULL) {
libertas_fw_name = default_fw_name;
}
lbs_deb_enter(LBS_DEB_MAIN);
libertas_debugfs_init();
if (libertas_sbi_register()) {
ret = -1;
libertas_debugfs_remove();
goto done;
}
done:
LEAVE();
return ret;
lbs_deb_leave(LBS_DEB_MAIN);
return 0;
}
static void wlan_cleanup_module(void)
static void libertas_exit_module(void)
{
int i;
ENTER();
for (i = 0; i<libertas_found; i++) {
wlan_private *priv = libertas_devs[i]->priv;
reset_device(priv);
}
lbs_deb_enter(LBS_DEB_MAIN);
libertas_sbi_unregister();
libertas_debugfs_remove();
LEAVE();
lbs_deb_leave(LBS_DEB_MAIN);
}
module_init(wlan_init_module);
module_exit(wlan_cleanup_module);
module_init(libertas_init_module);
module_exit(libertas_exit_module);
MODULE_DESCRIPTION("M-WLAN Driver");
MODULE_DESCRIPTION("Libertas WLAN Driver Library");
MODULE_AUTHOR("Marvell International Ltd.");
MODULE_LICENSE("GPL");
......@@ -106,10 +106,10 @@ static void wlan_compute_rssi(wlan_private * priv, struct rxpd *p_rx_pd)
{
wlan_adapter *adapter = priv->adapter;
ENTER();
lbs_deb_enter(LBS_DEB_RX);
lbs_pr_debug(1, "rxpd: SNR = %d, NF = %d\n", p_rx_pd->snr, p_rx_pd->nf);
lbs_pr_debug(1, "Before computing SNR: SNR- avg = %d, NF-avg = %d\n",
lbs_deb_rx("rxpd: SNR %d, NF %d\n", p_rx_pd->snr, p_rx_pd->nf);
lbs_deb_rx("before computing SNR: SNR-avg = %d, NF-avg = %d\n",
adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
......@@ -121,7 +121,7 @@ static void wlan_compute_rssi(wlan_private * priv, struct rxpd *p_rx_pd)
adapter->SNR[TYPE_RXPD][TYPE_AVG] = wlan_getavgsnr(priv) * AVG_SCALE;
adapter->NF[TYPE_RXPD][TYPE_AVG] = wlan_getavgnf(priv) * AVG_SCALE;
lbs_pr_debug(1, "After computing SNR: SNR-avg = %d, NF-avg = %d\n",
lbs_deb_rx("after computing SNR: SNR-avg = %d, NF-avg = %d\n",
adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
......@@ -133,18 +133,18 @@ static void wlan_compute_rssi(wlan_private * priv, struct rxpd *p_rx_pd)
CAL_RSSI(adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
LEAVE();
lbs_deb_leave(LBS_DEB_RX);
}
void libertas_upload_rx_packet(wlan_private * priv, struct sk_buff *skb)
{
lbs_pr_debug(1, "skb->data=%p\n", skb->data);
lbs_deb_rx("skb->data %p\n", skb->data);
if(IS_MESH_FRAME(skb))
if (priv->mesh_dev && IS_MESH_FRAME(skb))
skb->dev = priv->mesh_dev;
else
skb->dev = priv->wlan_dev.netdev;
skb->protocol = eth_type_trans(skb, priv->wlan_dev.netdev);
skb->dev = priv->dev;
skb->protocol = eth_type_trans(skb, priv->dev);
skb->ip_summed = CHECKSUM_UNNECESSARY;
netif_rx(skb);
......@@ -171,7 +171,7 @@ int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *skb)
const u8 rfc1042_eth_hdr[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
ENTER();
lbs_deb_enter(LBS_DEB_RX);
if (priv->adapter->debugmode & MRVDRV_DEBUG_RX_PATH)
lbs_dbg_hex("RX packet: ", skb->data,
......@@ -191,7 +191,7 @@ int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *skb)
min_t(unsigned int, skb->len, 100));
if (skb->len < (ETH_HLEN + 8 + sizeof(struct rxpd))) {
lbs_pr_debug(1, "RX error: FRAME RECEIVED WITH BAD LENGTH\n");
lbs_deb_rx("rx err: frame received with bad length\n");
priv->stats.rx_length_errors++;
ret = 0;
goto done;
......@@ -200,15 +200,15 @@ int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *skb)
/*
* Check rxpd status and update 802.3 stat,
*/
if (!(p_rx_pd->status & MRVDRV_RXPD_STATUS_OK)) {
lbs_pr_debug(1, "RX error: frame received with bad status\n");
lbs_pr_alert("rxpd Not OK\n");
if (!(p_rx_pd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK))) {
lbs_deb_rx("rx err: frame received with bad status\n");
lbs_pr_alert("rxpd not ok\n");
priv->stats.rx_errors++;
ret = 0;
goto done;
}
lbs_pr_debug(1, "RX Data: skb->len - sizeof(RxPd) = %d - %zd = %zd\n",
lbs_deb_rx("rx data: skb->len-sizeof(RxPd) = %d-%zd = %zd\n",
skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd));
lbs_dbg_hex("RX Data: Dest", p_rx_pkt->eth803_hdr.dest_addr,
......@@ -266,7 +266,7 @@ int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *skb)
wlan_compute_rssi(priv, p_rx_pd);
lbs_pr_debug(1, "RX Data: size of actual packet = %d\n", skb->len);
lbs_deb_rx("rx data: size of actual packet %d\n", skb->len);
priv->stats.rx_bytes += skb->len;
priv->stats.rx_packets++;
......@@ -274,10 +274,10 @@ int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *skb)
ret = 0;
done:
LEAVE();
lbs_deb_leave_args(LBS_DEB_RX, "ret %d", ret);
return ret;
}
EXPORT_SYMBOL_GPL(libertas_process_rxed_packet);
/**
* @brief This function converts Tx/Rx rates from the Marvell WLAN format
......@@ -314,7 +314,7 @@ static u8 convert_mv_rate_to_radiotap(u8 rate)
case 11: /* 54 Mbps */
return 108;
}
lbs_pr_alert( "Invalid Marvell WLAN rate (%i)\n", rate);
lbs_pr_alert("Invalid Marvell WLAN rate %i\n", rate);
return 0;
}
......@@ -336,7 +336,7 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb)
struct rx_radiotap_hdr radiotap_hdr;
struct rx_radiotap_hdr *pradiotap_hdr;
ENTER();
lbs_deb_enter(LBS_DEB_RX);
p_rx_pkt = (struct rx80211packethdr *) skb->data;
prxpd = &p_rx_pkt->rx_pd;
......@@ -344,7 +344,7 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb)
// lbs_dbg_hex("RX Data: Before chop rxpd", skb->data, min(skb->len, 100));
if (skb->len < (ETH_HLEN + 8 + sizeof(struct rxpd))) {
lbs_pr_debug(1, "RX error: FRAME RECEIVED WITH BAD LENGTH\n");
lbs_deb_rx("rx err: frame received wit bad length\n");
priv->stats.rx_length_errors++;
ret = 0;
goto done;
......@@ -353,12 +353,12 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb)
/*
* Check rxpd status and update 802.3 stat,
*/
if (!(prxpd->status & MRVDRV_RXPD_STATUS_OK)) {
//lbs_pr_debug(1, "RX error: frame received with bad status\n");
if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK))) {
//lbs_deb_rx("rx err: frame received with bad status\n");
priv->stats.rx_errors++;
}
lbs_pr_debug(1, "RX Data: skb->len - sizeof(RxPd) = %d - %zd = %zd\n",
lbs_deb_rx("rx data: skb->len-sizeof(RxPd) = %d-%zd = %zd\n",
skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd));
/* create the exported radio header */
......@@ -386,7 +386,7 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb)
/* XXX must check no carryout */
radiotap_hdr.antsignal = prxpd->snr + prxpd->nf;
radiotap_hdr.rx_flags = 0;
if (!(prxpd->status & MRVDRV_RXPD_STATUS_OK))
if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK)))
radiotap_hdr.rx_flags |= IEEE80211_RADIOTAP_F_RX_BADFCS;
//memset(radiotap_hdr.pad, 0x11, IEEE80211_RADIOTAP_HDRLEN - 18);
......@@ -399,7 +399,7 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb)
if ((skb_headroom(skb) < sizeof(struct rx_radiotap_hdr)) &&
pskb_expand_head(skb, sizeof(struct rx_radiotap_hdr), 0,
GFP_ATOMIC)) {
lbs_pr_alert( "%s: couldn't pskb_expand_head\n",
lbs_pr_alert("%s: couldn't pskb_expand_head\n",
__func__);
}
......@@ -414,7 +414,7 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb)
default:
/* unknown header */
lbs_pr_alert( "Unknown radiomode (%i)\n",
lbs_pr_alert("Unknown radiomode %i\n",
priv->adapter->radiomode);
/* don't export any header */
/* chop the rxpd */
......@@ -431,15 +431,16 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb)
wlan_compute_rssi(priv, prxpd);
lbs_pr_debug(1, "RX Data: size of actual packet = %d\n", skb->len);
lbs_deb_rx("rx data: size of actual packet %d\n", skb->len);
priv->stats.rx_bytes += skb->len;
priv->stats.rx_packets++;
libertas_upload_rx_packet(priv, skb);
ret = 0;
done:
LEAVE();
return (ret);
done:
skb->protocol = __constant_htons(0x0019); /* ETH_P_80211_RAW */
lbs_deb_leave_args(LBS_DEB_RX, "ret %d", ret);
return ret;
}
/**
* This file contains IF layer definitions.
*/
#ifndef _SBI_H_
#define _SBI_H_
#include <linux/interrupt.h>
#include "defs.h"
/** INT status Bit Definition*/
#define his_cmddnldrdy 0x01
#define his_cardevent 0x02
#define his_cmdupldrdy 0x04
#ifndef DEV_NAME_LEN
#define DEV_NAME_LEN 32
#endif
#define SBI_EVENT_CAUSE_SHIFT 3
/* Probe and Check if the card is present*/
int libertas_sbi_register_dev(wlan_private * priv);
int libertas_sbi_unregister_dev(wlan_private *);
int libertas_sbi_get_int_status(wlan_private * priv, u8 *);
int libertas_sbi_register(void);
void libertas_sbi_unregister(void);
int libertas_sbi_prog_firmware(wlan_private *);
int libertas_sbi_read_event_cause(wlan_private *);
int libertas_sbi_host_to_card(wlan_private * priv, u8 type, u8 * payload, u16 nb);
wlan_private *libertas_sbi_get_priv(void *card);
#ifdef ENABLE_PM
int libertas_sbi_suspend(wlan_private *);
int libertas_sbi_resume(wlan_private *);
#endif
#endif /* _SBI_H */
......@@ -8,6 +8,7 @@
#include <linux/if.h>
#include <linux/netdevice.h>
#include <linux/wireless.h>
#include <linux/etherdevice.h>
#include <net/ieee80211.h>
#include <net/iw_handler.h>
......@@ -58,12 +59,82 @@
//! Scan time specified in the channel TLV for each channel for active scans
#define MRVDRV_ACTIVE_SCAN_CHAN_TIME 100
//! Macro to enable/disable SSID checking before storing a scan table
#ifdef DISCARD_BAD_SSID
#define CHECK_SSID_IS_VALID(x) ssid_valid(&bssidEntry.ssid)
#else
#define CHECK_SSID_IS_VALID(x) 1
#endif
static const u8 zeromac[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
static const u8 bcastmac[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
static inline void clear_bss_descriptor (struct bss_descriptor * bss)
{
/* Don't blow away ->list, just BSS data */
memset(bss, 0, offsetof(struct bss_descriptor, list));
}
static inline int match_bss_no_security(struct wlan_802_11_security * secinfo,
struct bss_descriptor * match_bss)
{
if ( !secinfo->wep_enabled
&& !secinfo->WPAenabled
&& !secinfo->WPA2enabled
&& match_bss->wpa_ie[0] != WPA_IE
&& match_bss->rsn_ie[0] != WPA2_IE
&& !match_bss->privacy) {
return 1;
}
return 0;
}
static inline int match_bss_static_wep(struct wlan_802_11_security * secinfo,
struct bss_descriptor * match_bss)
{
if ( secinfo->wep_enabled
&& !secinfo->WPAenabled
&& !secinfo->WPA2enabled
&& match_bss->privacy) {
return 1;
}
return 0;
}
static inline int match_bss_wpa(struct wlan_802_11_security * secinfo,
struct bss_descriptor * match_bss)
{
if ( !secinfo->wep_enabled
&& secinfo->WPAenabled
&& (match_bss->wpa_ie[0] == WPA_IE)
/* privacy bit may NOT be set in some APs like LinkSys WRT54G
&& bss->privacy */
) {
return 1;
}
return 0;
}
static inline int match_bss_wpa2(struct wlan_802_11_security * secinfo,
struct bss_descriptor * match_bss)
{
if ( !secinfo->wep_enabled
&& secinfo->WPA2enabled
&& (match_bss->rsn_ie[0] == WPA2_IE)
/* privacy bit may NOT be set in some APs like LinkSys WRT54G
&& bss->privacy */
) {
return 1;
}
return 0;
}
static inline int match_bss_dynamic_wep(struct wlan_802_11_security * secinfo,
struct bss_descriptor * match_bss)
{
if ( !secinfo->wep_enabled
&& !secinfo->WPAenabled
&& !secinfo->WPA2enabled
&& (match_bss->wpa_ie[0] != WPA_IE)
&& (match_bss->rsn_ie[0] != WPA2_IE)
&& match_bss->privacy) {
return 1;
}
return 0;
}
/**
* @brief Check if a scanned network compatible with the driver settings
......@@ -84,123 +155,63 @@
*
* @return Index in scantable, or error code if negative
*/
static int is_network_compatible(wlan_adapter * adapter, int index, u8 mode)
static int is_network_compatible(wlan_adapter * adapter,
struct bss_descriptor * bss, u8 mode)
{
ENTER();
if (adapter->scantable[index].mode == mode) {
if ( !adapter->secinfo.wep_enabled
&& !adapter->secinfo.WPAenabled
&& !adapter->secinfo.WPA2enabled
&& adapter->scantable[index].wpa_ie[0] != WPA_IE
&& adapter->scantable[index].rsn_ie[0] != WPA2_IE
&& !adapter->scantable[index].privacy) {
/* no security */
LEAVE();
return index;
} else if ( adapter->secinfo.wep_enabled
&& !adapter->secinfo.WPAenabled
&& !adapter->secinfo.WPA2enabled
&& adapter->scantable[index].privacy) {
/* static WEP enabled */
LEAVE();
return index;
} else if ( !adapter->secinfo.wep_enabled
&& adapter->secinfo.WPAenabled
&& !adapter->secinfo.WPA2enabled
&& (adapter->scantable[index].wpa_ie[0] == WPA_IE)
/* privacy bit may NOT be set in some APs like LinkSys WRT54G
&& adapter->scantable[index].privacy */
) {
/* WPA enabled */
lbs_pr_debug(1,
"is_network_compatible() WPA: index=%d wpa_ie=%#x "
int matched = 0;
lbs_deb_enter(LBS_DEB_ASSOC);
if (bss->mode != mode)
goto done;
if ((matched = match_bss_no_security(&adapter->secinfo, bss))) {
goto done;
} else if ((matched = match_bss_static_wep(&adapter->secinfo, bss))) {
goto done;
} else if ((matched = match_bss_wpa(&adapter->secinfo, bss))) {
lbs_deb_scan(
"is_network_compatible() WPA: wpa_ie=%#x "
"wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s "
"privacy=%#x\n", index,
adapter->scantable[index].wpa_ie[0],
adapter->scantable[index].rsn_ie[0],
"privacy=%#x\n", bss->wpa_ie[0], bss->rsn_ie[0],
adapter->secinfo.wep_enabled ? "e" : "d",
adapter->secinfo.WPAenabled ? "e" : "d",
adapter->secinfo.WPA2enabled ? "e" : "d",
adapter->scantable[index].privacy);
LEAVE();
return index;
} else if ( !adapter->secinfo.wep_enabled
&& !adapter->secinfo.WPAenabled
&& adapter->secinfo.WPA2enabled
&& (adapter->scantable[index].rsn_ie[0] == WPA2_IE)
/* privacy bit may NOT be set in some APs like LinkSys WRT54G
&& adapter->scantable[index].privacy */
) {
/* WPA2 enabled */
lbs_pr_debug(1,
"is_network_compatible() WPA2: index=%d wpa_ie=%#x "
bss->privacy);
goto done;
} else if ((matched = match_bss_wpa2(&adapter->secinfo, bss))) {
lbs_deb_scan(
"is_network_compatible() WPA2: wpa_ie=%#x "
"wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s "
"privacy=%#x\n", index,
adapter->scantable[index].wpa_ie[0],
adapter->scantable[index].rsn_ie[0],
"privacy=%#x\n", bss->wpa_ie[0], bss->rsn_ie[0],
adapter->secinfo.wep_enabled ? "e" : "d",
adapter->secinfo.WPAenabled ? "e" : "d",
adapter->secinfo.WPA2enabled ? "e" : "d",
adapter->scantable[index].privacy);
LEAVE();
return index;
} else if ( !adapter->secinfo.wep_enabled
&& !adapter->secinfo.WPAenabled
&& !adapter->secinfo.WPA2enabled
&& (adapter->scantable[index].wpa_ie[0] != WPA_IE)
&& (adapter->scantable[index].rsn_ie[0] != WPA2_IE)
&& adapter->scantable[index].privacy) {
/* dynamic WEP enabled */
lbs_pr_debug(1,
"is_network_compatible() dynamic WEP: index=%d "
bss->privacy);
goto done;
} else if ((matched = match_bss_dynamic_wep(&adapter->secinfo, bss))) {
lbs_deb_scan(
"is_network_compatible() dynamic WEP: "
"wpa_ie=%#x wpa2_ie=%#x privacy=%#x\n",
index,
adapter->scantable[index].wpa_ie[0],
adapter->scantable[index].rsn_ie[0],
adapter->scantable[index].privacy);
LEAVE();
return index;
bss->wpa_ie[0],
bss->rsn_ie[0],
bss->privacy);
goto done;
}
/* security doesn't match */
lbs_pr_debug(1,
"is_network_compatible() FAILED: index=%d wpa_ie=%#x "
/* bss security settings don't match those configured on card */
lbs_deb_scan(
"is_network_compatible() FAILED: wpa_ie=%#x "
"wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s privacy=%#x\n",
index,
adapter->scantable[index].wpa_ie[0],
adapter->scantable[index].rsn_ie[0],
bss->wpa_ie[0], bss->rsn_ie[0],
adapter->secinfo.wep_enabled ? "e" : "d",
adapter->secinfo.WPAenabled ? "e" : "d",
adapter->secinfo.WPA2enabled ? "e" : "d",
adapter->scantable[index].privacy);
LEAVE();
return -ECONNREFUSED;
}
bss->privacy);
/* mode doesn't match */
LEAVE();
return -ENETUNREACH;
}
/**
* @brief This function validates a SSID as being able to be printed
*
* @param pssid SSID structure to validate
*
* @return TRUE or FALSE
*/
static u8 ssid_valid(struct WLAN_802_11_SSID *pssid)
{
int ssididx;
for (ssididx = 0; ssididx < pssid->ssidlength; ssididx++) {
if (!isprint(pssid->ssid[ssididx])) {
return 0;
}
}
return 1;
done:
lbs_deb_leave(LBS_DEB_SCAN);
return matched;
}
/**
......@@ -220,44 +231,19 @@ static u8 ssid_valid(struct WLAN_802_11_SSID *pssid)
static void wlan_scan_process_results(wlan_private * priv)
{
wlan_adapter *adapter = priv->adapter;
int foundcurrent;
int i;
foundcurrent = 0;
if (adapter->connect_status == libertas_connected) {
/* try to find the current BSSID in the new scan list */
for (i = 0; i < adapter->numinscantable; i++) {
if (!libertas_SSID_cmp(&adapter->scantable[i].ssid,
&adapter->curbssparams.ssid) &&
!memcmp(adapter->curbssparams.bssid,
adapter->scantable[i].macaddress,
ETH_ALEN)) {
foundcurrent = 1;
}
}
struct bss_descriptor * iter_bss;
int i = 0;
if (foundcurrent) {
/* Make a copy of current BSSID descriptor */
memcpy(&adapter->curbssparams.bssdescriptor,
&adapter->scantable[i],
sizeof(adapter->curbssparams.bssdescriptor));
}
}
if (adapter->connect_status == libertas_connected)
return;
for (i = 0; i < adapter->numinscantable; i++) {
lbs_pr_debug(1, "Scan:(%02d) %02x:%02x:%02x:%02x:%02x:%02x, "
"RSSI[%03d], SSID[%s]\n",
i,
adapter->scantable[i].macaddress[0],
adapter->scantable[i].macaddress[1],
adapter->scantable[i].macaddress[2],
adapter->scantable[i].macaddress[3],
adapter->scantable[i].macaddress[4],
adapter->scantable[i].macaddress[5],
(s32) adapter->scantable[i].rssi,
adapter->scantable[i].ssid.ssid);
mutex_lock(&adapter->lock);
list_for_each_entry (iter_bss, &adapter->network_list, list) {
lbs_deb_scan("Scan:(%02d) " MAC_FMT ", RSSI[%03d], SSID[%s]\n",
i++, MAC_ARG(iter_bss->bssid), (s32) iter_bss->rssi,
escape_essid(iter_bss->ssid, iter_bss->ssid_len));
}
mutex_unlock(&adapter->lock);
}
/**
......@@ -338,14 +324,12 @@ static void wlan_scan_create_channel_list(wlan_private * priv,
if (scantype == cmd_scan_type_passive) {
scanchanlist[chanidx].maxscantime =
cpu_to_le16
(MRVDRV_PASSIVE_SCAN_CHAN_TIME);
cpu_to_le16(MRVDRV_PASSIVE_SCAN_CHAN_TIME);
scanchanlist[chanidx].chanscanmode.passivescan =
1;
} else {
scanchanlist[chanidx].maxscantime =
cpu_to_le16
(MRVDRV_ACTIVE_SCAN_CHAN_TIME);
cpu_to_le16(MRVDRV_ACTIVE_SCAN_CHAN_TIME);
scanchanlist[chanidx].chanscanmode.passivescan =
0;
}
......@@ -408,13 +392,11 @@ wlan_scan_setup_scan_config(wlan_private * priv,
u8 * pscancurrentonly)
{
wlan_adapter *adapter = priv->adapter;
const u8 zeromac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
struct mrvlietypes_numprobes *pnumprobestlv;
struct mrvlietypes_ssidparamset *pssidtlv;
struct wlan_scan_cmd_config * pscancfgout = NULL;
u8 *ptlvpos;
u16 numprobes;
u16 ssidlen;
int chanidx;
int scantype;
int scandur;
......@@ -471,21 +453,18 @@ wlan_scan_setup_scan_config(wlan_private * priv,
* Set the BSSID filter to the incoming configuration,
* if non-zero. If not set, it will remain disabled (all zeros).
*/
memcpy(pscancfgout->specificBSSID,
puserscanin->specificBSSID,
sizeof(pscancfgout->specificBSSID));
memcpy(pscancfgout->bssid, puserscanin->bssid,
sizeof(pscancfgout->bssid));
ssidlen = strlen(puserscanin->specificSSID);
if (ssidlen) {
if (puserscanin->ssid_len) {
pssidtlv =
(struct mrvlietypes_ssidparamset *) pscancfgout->
tlvbuffer;
pssidtlv->header.type = cpu_to_le16(TLV_TYPE_SSID);
pssidtlv->header.len = cpu_to_le16(ssidlen);
memcpy(pssidtlv->ssid, puserscanin->specificSSID,
ssidlen);
ptlvpos += sizeof(pssidtlv->header) + ssidlen;
pssidtlv->header.len = cpu_to_le16(puserscanin->ssid_len);
memcpy(pssidtlv->ssid, puserscanin->ssid,
puserscanin->ssid_len);
ptlvpos += sizeof(pssidtlv->header) + puserscanin->ssid_len;
}
/*
......@@ -494,8 +473,8 @@ wlan_scan_setup_scan_config(wlan_private * priv,
* scan results. That is not an issue with an SSID or BSSID
* filter applied to the scan results in the firmware.
*/
if (ssidlen || (memcmp(pscancfgout->specificBSSID,
&zeromac, sizeof(zeromac)) != 0)) {
if ( puserscanin->ssid_len
|| (compare_ether_addr(pscancfgout->bssid, &zeromac[0]) != 0)) {
*pmaxchanperscan = MRVDRV_MAX_CHANNELS_PER_SCAN;
*pfilteredscan = 1;
}
......@@ -507,16 +486,11 @@ wlan_scan_setup_scan_config(wlan_private * priv,
/* If the input config or adapter has the number of Probes set, add tlv */
if (numprobes) {
pnumprobestlv = (struct mrvlietypes_numprobes *) ptlvpos;
pnumprobestlv->header.type =
cpu_to_le16(TLV_TYPE_NUMPROBES);
pnumprobestlv->header.len = sizeof(pnumprobestlv->numprobes);
pnumprobestlv->header.type = cpu_to_le16(TLV_TYPE_NUMPROBES);
pnumprobestlv->header.len = cpu_to_le16(2);
pnumprobestlv->numprobes = cpu_to_le16(numprobes);
ptlvpos +=
sizeof(pnumprobestlv->header) + pnumprobestlv->header.len;
pnumprobestlv->header.len =
cpu_to_le16(pnumprobestlv->header.len);
ptlvpos += sizeof(*pnumprobestlv);
}
/*
......@@ -529,7 +503,7 @@ wlan_scan_setup_scan_config(wlan_private * priv,
if (puserscanin && puserscanin->chanlist[0].channumber) {
lbs_pr_debug(1, "Scan: Using supplied channel list\n");
lbs_deb_scan("Scan: Using supplied channel list\n");
for (chanidx = 0;
chanidx < WLAN_IOCTL_USER_SCAN_CHAN_MAX
......@@ -573,11 +547,11 @@ wlan_scan_setup_scan_config(wlan_private * priv,
==
priv->adapter->curbssparams.channel)) {
*pscancurrentonly = 1;
lbs_pr_debug(1, "Scan: Scanning current channel only");
lbs_deb_scan("Scan: Scanning current channel only");
}
} else {
lbs_pr_debug(1, "Scan: Creating full region channel list\n");
lbs_deb_scan("Scan: Creating full region channel list\n");
wlan_scan_create_channel_list(priv, pscanchanlist,
*pfilteredscan);
}
......@@ -613,7 +587,9 @@ static int wlan_scan_channel_list(wlan_private * priv,
u8 filteredscan,
struct wlan_scan_cmd_config * pscancfgout,
struct mrvlietypes_chanlistparamset * pchantlvout,
struct chanscanparamset * pscanchanlist)
struct chanscanparamset * pscanchanlist,
const struct wlan_ioctl_user_scan_cfg * puserscanin,
int full_scan)
{
struct chanscanparamset *ptmpchan;
struct chanscanparamset *pstartchan;
......@@ -621,11 +597,13 @@ static int wlan_scan_channel_list(wlan_private * priv,
int doneearly;
int tlvidx;
int ret = 0;
int scanned = 0;
union iwreq_data wrqu;
ENTER();
lbs_deb_enter(LBS_DEB_ASSOC);
if (pscancfgout == 0 || pchantlvout == 0 || pscanchanlist == 0) {
lbs_pr_debug(1, "Scan: Null detect: %p, %p, %p\n",
lbs_deb_scan("Scan: Null detect: %p, %p, %p\n",
pscancfgout, pchantlvout, pscanchanlist);
return -1;
}
......@@ -635,6 +613,9 @@ static int wlan_scan_channel_list(wlan_private * priv,
/* Set the temp channel struct pointer to the start of the desired list */
ptmpchan = pscanchanlist;
if (priv->adapter->last_scanned_channel && !puserscanin)
ptmpchan += priv->adapter->last_scanned_channel;
/* Loop through the desired channel list, sending a new firmware scan
* commands for each maxchanperscan channels (or for 1,6,11 individually
* if configured accordingly)
......@@ -654,9 +635,9 @@ static int wlan_scan_channel_list(wlan_private * priv,
* - doneearly is set (controlling individual scanning of 1,6,11)
*/
while (tlvidx < maxchanperscan && ptmpchan->channumber
&& !doneearly) {
&& !doneearly && scanned < 2) {
lbs_pr_debug(1,
lbs_deb_scan(
"Scan: Chan(%3d), Radio(%d), mode(%d,%d), Dur(%d)\n",
ptmpchan->channumber, ptmpchan->radiotype,
ptmpchan->chanscanmode.passivescan,
......@@ -668,8 +649,11 @@ static int wlan_scan_channel_list(wlan_private * priv,
ptmpchan, sizeof(pchantlvout->chanscanparam));
/* Increment the TLV header length by the size appended */
pchantlvout->header.len +=
sizeof(pchantlvout->chanscanparam);
/* Ew, it would be _so_ nice if we could just declare the
variable little-endian and let GCC handle it for us */
pchantlvout->header.len =
cpu_to_le16(le16_to_cpu(pchantlvout->header.len) +
sizeof(pchantlvout->chanscanparam));
/*
* The tlv buffer length is set to the number of bytes of the
......@@ -683,7 +667,7 @@ static int wlan_scan_channel_list(wlan_private * priv,
/* Add the size of the channel tlv header and the data length */
pscancfgout->tlvbufferlen +=
(sizeof(pchantlvout->header)
+ pchantlvout->header.len);
+ le16_to_cpu(pchantlvout->header.len));
/* Increment the index to the channel tlv we are constructing */
tlvidx++;
......@@ -701,6 +685,7 @@ static int wlan_scan_channel_list(wlan_private * priv,
/* Increment the tmp pointer to the next channel to be scanned */
ptmpchan++;
scanned++;
/* Stop the loop if the *next* channel is in the 1,6,11 set.
* This will cause it to be the only channel scanned on the next
......@@ -716,12 +701,71 @@ static int wlan_scan_channel_list(wlan_private * priv,
/* Send the scan command to the firmware with the specified cfg */
ret = libertas_prepare_and_send_command(priv, cmd_802_11_scan, 0,
0, 0, pscancfgout);
if (scanned >= 2 && !full_scan) {
ret = 0;
goto done;
}
scanned = 0;
}
LEAVE();
done:
priv->adapter->last_scanned_channel = ptmpchan->channumber;
/* Tell userspace the scan table has been updated */
memset(&wrqu, 0, sizeof(union iwreq_data));
wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret);
return ret;
}
static void
clear_selected_scan_list_entries(wlan_adapter * adapter,
const struct wlan_ioctl_user_scan_cfg * scan_cfg)
{
struct bss_descriptor * bss;
struct bss_descriptor * safe;
u32 clear_ssid_flag = 0, clear_bssid_flag = 0;
if (!scan_cfg)
return;
if (scan_cfg->clear_ssid && scan_cfg->ssid_len)
clear_ssid_flag = 1;
if (scan_cfg->clear_bssid
&& (compare_ether_addr(scan_cfg->bssid, &zeromac[0]) != 0)
&& (compare_ether_addr(scan_cfg->bssid, &bcastmac[0]) != 0)) {
clear_bssid_flag = 1;
}
if (!clear_ssid_flag && !clear_bssid_flag)
return;
mutex_lock(&adapter->lock);
list_for_each_entry_safe (bss, safe, &adapter->network_list, list) {
u32 clear = 0;
/* Check for an SSID match */
if ( clear_ssid_flag
&& (bss->ssid_len == scan_cfg->ssid_len)
&& !memcmp(bss->ssid, scan_cfg->ssid, bss->ssid_len))
clear = 1;
/* Check for a BSSID match */
if ( clear_bssid_flag
&& !compare_ether_addr(bss->bssid, scan_cfg->bssid))
clear = 1;
if (clear) {
list_move_tail (&bss->list, &adapter->network_free_list);
clear_bss_descriptor(bss);
}
}
mutex_unlock(&adapter->lock);
}
/**
* @brief Internal function used to start a scan based on an input config
*
......@@ -736,19 +780,19 @@ static int wlan_scan_channel_list(wlan_private * priv,
* @return 0 or < 0 if error
*/
int wlan_scan_networks(wlan_private * priv,
const struct wlan_ioctl_user_scan_cfg * puserscanin)
const struct wlan_ioctl_user_scan_cfg * puserscanin,
int full_scan)
{
wlan_adapter *adapter = priv->adapter;
wlan_adapter * adapter = priv->adapter;
struct mrvlietypes_chanlistparamset *pchantlvout;
struct chanscanparamset * scan_chan_list = NULL;
struct wlan_scan_cmd_config * scan_cfg = NULL;
u8 keeppreviousscan;
u8 filteredscan;
u8 scancurrentchanonly;
int maxchanperscan;
int ret;
ENTER();
lbs_deb_enter(LBS_DEB_ASSOC);
scan_chan_list = kzalloc(sizeof(struct chanscanparamset) *
WLAN_IOCTL_USER_SCAN_CHAN_MAX, GFP_KERNEL);
......@@ -769,22 +813,14 @@ int wlan_scan_networks(wlan_private * priv,
goto out;
}
keeppreviousscan = 0;
if (puserscanin) {
keeppreviousscan = puserscanin->keeppreviousscan;
}
if (!keeppreviousscan) {
memset(adapter->scantable, 0x00,
sizeof(struct bss_descriptor) * MRVDRV_MAX_BSSID_LIST);
adapter->numinscantable = 0;
}
clear_selected_scan_list_entries(adapter, puserscanin);
/* Keep the data path active if we are only scanning our current channel */
if (!scancurrentchanonly) {
netif_stop_queue(priv->wlan_dev.netdev);
netif_carrier_off(priv->wlan_dev.netdev);
netif_stop_queue(priv->dev);
netif_carrier_off(priv->dev);
netif_stop_queue(priv->mesh_dev);
netif_carrier_off(priv->mesh_dev);
}
ret = wlan_scan_channel_list(priv,
......@@ -792,7 +828,9 @@ int wlan_scan_networks(wlan_private * priv,
filteredscan,
scan_cfg,
pchantlvout,
scan_chan_list);
scan_chan_list,
puserscanin,
full_scan);
/* Process the resulting scan table:
* - Remove any bad ssids
......@@ -801,8 +839,10 @@ int wlan_scan_networks(wlan_private * priv,
wlan_scan_process_results(priv);
if (priv->adapter->connect_status == libertas_connected) {
netif_carrier_on(priv->wlan_dev.netdev);
netif_wake_queue(priv->wlan_dev.netdev);
netif_carrier_on(priv->dev);
netif_wake_queue(priv->dev);
netif_carrier_on(priv->mesh_dev);
netif_wake_queue(priv->mesh_dev);
}
out:
......@@ -812,7 +852,7 @@ int wlan_scan_networks(wlan_private * priv,
if (scan_chan_list)
kfree(scan_chan_list);
LEAVE();
lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret);
return ret;
}
......@@ -843,7 +883,7 @@ void wlan_ret_802_11_scan_get_tlv_ptrs(struct mrvlietypes_data * ptlv,
tlvbufleft = tlvbufsize;
*ptsftlv = NULL;
lbs_pr_debug(1, "SCAN_RESP: tlvbufsize = %d\n", tlvbufsize);
lbs_deb_scan("SCAN_RESP: tlvbufsize = %d\n", tlvbufsize);
lbs_dbg_hex("SCAN_RESP: TLV Buf", (u8 *) ptlv, tlvbufsize);
while (tlvbufleft >= sizeof(struct mrvlietypesheader)) {
......@@ -856,7 +896,7 @@ void wlan_ret_802_11_scan_get_tlv_ptrs(struct mrvlietypes_data * ptlv,
break;
default:
lbs_pr_debug(1, "SCAN_RESP: Unhandled TLV = %d\n",
lbs_deb_scan("SCAN_RESP: Unhandled TLV = %d\n",
tlvtype);
/* Give up, this seems corrupted */
return;
......@@ -875,11 +915,11 @@ void wlan_ret_802_11_scan_get_tlv_ptrs(struct mrvlietypes_data * ptlv,
* response or beacon from the scan command. Record information as needed
* in the scan table struct bss_descriptor for that entry.
*
* @param pBSSIDEntry Output parameter: Pointer to the BSS Entry
* @param bss Output parameter: Pointer to the BSS Entry
*
* @return 0 or -1
*/
static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry,
static int libertas_process_bss(struct bss_descriptor * bss,
u8 ** pbeaconinfo, int *bytesleft)
{
enum ieeetypes_elementid elemID;
......@@ -897,13 +937,14 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry,
u16 beaconsize;
u8 founddatarateie;
int bytesleftforcurrentbeacon;
int ret;
struct IE_WPA *pIe;
const u8 oui01[4] = { 0x00, 0x50, 0xf2, 0x01 };
struct ieeetypes_countryinfoset *pcountryinfo;
ENTER();
lbs_deb_enter(LBS_DEB_ASSOC);
founddatarateie = 0;
ratesize = 0;
......@@ -911,8 +952,7 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry,
if (*bytesleft >= sizeof(beaconsize)) {
/* Extract & convert beacon size from the command buffer */
memcpy(&beaconsize, *pbeaconinfo, sizeof(beaconsize));
beaconsize = le16_to_cpu(beaconsize);
beaconsize = le16_to_cpup((void *)*pbeaconinfo);
*bytesleft -= sizeof(beaconsize);
*pbeaconinfo += sizeof(beaconsize);
}
......@@ -934,17 +974,14 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry,
bytesleftforcurrentbeacon = beaconsize;
memcpy(pBSSEntry->macaddress, pcurrentptr, ETH_ALEN);
lbs_pr_debug(1, "InterpretIE: AP MAC Addr-%x:%x:%x:%x:%x:%x\n",
pBSSEntry->macaddress[0], pBSSEntry->macaddress[1],
pBSSEntry->macaddress[2], pBSSEntry->macaddress[3],
pBSSEntry->macaddress[4], pBSSEntry->macaddress[5]);
memcpy(bss->bssid, pcurrentptr, ETH_ALEN);
lbs_deb_scan("process_bss: AP BSSID " MAC_FMT "\n", MAC_ARG(bss->bssid));
pcurrentptr += ETH_ALEN;
bytesleftforcurrentbeacon -= ETH_ALEN;
if (bytesleftforcurrentbeacon < 12) {
lbs_pr_debug(1, "InterpretIE: Not enough bytes left\n");
lbs_deb_scan("process_bss: Not enough bytes left\n");
return -1;
}
......@@ -954,51 +991,48 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry,
*/
/* RSSI is 1 byte long */
pBSSEntry->rssi = le32_to_cpu((long)(*pcurrentptr));
lbs_pr_debug(1, "InterpretIE: RSSI=%02X\n", *pcurrentptr);
bss->rssi = *pcurrentptr;
lbs_deb_scan("process_bss: RSSI=%02X\n", *pcurrentptr);
pcurrentptr += 1;
bytesleftforcurrentbeacon -= 1;
/* time stamp is 8 bytes long */
memcpy(fixedie.timestamp, pcurrentptr, 8);
memcpy(pBSSEntry->timestamp, pcurrentptr, 8);
fixedie.timestamp = bss->timestamp = le64_to_cpup((void *)pcurrentptr);
pcurrentptr += 8;
bytesleftforcurrentbeacon -= 8;
/* beacon interval is 2 bytes long */
memcpy(&fixedie.beaconinterval, pcurrentptr, 2);
pBSSEntry->beaconperiod = le16_to_cpu(fixedie.beaconinterval);
fixedie.beaconinterval = bss->beaconperiod = le16_to_cpup((void *)pcurrentptr);
pcurrentptr += 2;
bytesleftforcurrentbeacon -= 2;
/* capability information is 2 bytes long */
memcpy(&fixedie.capabilities, pcurrentptr, 2);
lbs_pr_debug(1, "InterpretIE: fixedie.capabilities=0x%X\n",
lbs_deb_scan("process_bss: fixedie.capabilities=0x%X\n",
fixedie.capabilities);
fixedie.capabilities = le16_to_cpu(fixedie.capabilities);
pcap = (struct ieeetypes_capinfo *) & fixedie.capabilities;
memcpy(&pBSSEntry->cap, pcap, sizeof(struct ieeetypes_capinfo));
memcpy(&bss->cap, pcap, sizeof(struct ieeetypes_capinfo));
pcurrentptr += 2;
bytesleftforcurrentbeacon -= 2;
/* rest of the current buffer are IE's */
lbs_pr_debug(1, "InterpretIE: IElength for this AP = %d\n",
lbs_deb_scan("process_bss: IE length for this AP = %d\n",
bytesleftforcurrentbeacon);
lbs_dbg_hex("InterpretIE: IE info", (u8 *) pcurrentptr,
lbs_dbg_hex("process_bss: IE info", (u8 *) pcurrentptr,
bytesleftforcurrentbeacon);
if (pcap->privacy) {
lbs_pr_debug(1, "InterpretIE: AP WEP enabled\n");
pBSSEntry->privacy = wlan802_11privfilter8021xWEP;
lbs_deb_scan("process_bss: AP WEP enabled\n");
bss->privacy = wlan802_11privfilter8021xWEP;
} else {
pBSSEntry->privacy = wlan802_11privfilteracceptall;
bss->privacy = wlan802_11privfilteracceptall;
}
if (pcap->ibss == 1) {
pBSSEntry->mode = IW_MODE_ADHOC;
bss->mode = IW_MODE_ADHOC;
} else {
pBSSEntry->mode = IW_MODE_INFRA;
bss->mode = IW_MODE_INFRA;
}
/* process variable IE */
......@@ -1007,94 +1041,83 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry,
elemlen = *((u8 *) pcurrentptr + 1);
if (bytesleftforcurrentbeacon < elemlen) {
lbs_pr_debug(1, "InterpretIE: error in processing IE, "
lbs_deb_scan("process_bss: error in processing IE, "
"bytes left < IE length\n");
bytesleftforcurrentbeacon = 0;
continue;
}
switch (elemID) {
case SSID:
pBSSEntry->ssid.ssidlength = elemlen;
memcpy(pBSSEntry->ssid.ssid, (pcurrentptr + 2),
elemlen);
lbs_pr_debug(1, "ssid: %32s", pBSSEntry->ssid.ssid);
bss->ssid_len = elemlen;
memcpy(bss->ssid, (pcurrentptr + 2), elemlen);
lbs_deb_scan("ssid '%s', ssid length %u\n",
escape_essid(bss->ssid, bss->ssid_len),
bss->ssid_len);
break;
case SUPPORTED_RATES:
memcpy(pBSSEntry->datarates, (pcurrentptr + 2),
elemlen);
memmove(pBSSEntry->libertas_supported_rates, (pcurrentptr + 2),
memcpy(bss->datarates, (pcurrentptr + 2), elemlen);
memmove(bss->libertas_supported_rates, (pcurrentptr + 2),
elemlen);
ratesize = elemlen;
founddatarateie = 1;
break;
case EXTRA_IE:
lbs_pr_debug(1, "InterpretIE: EXTRA_IE Found!\n");
pBSSEntry->extra_ie = 1;
lbs_deb_scan("process_bss: EXTRA_IE Found!\n");
break;
case FH_PARAM_SET:
pFH = (struct ieeetypes_fhparamset *) pcurrentptr;
memmove(&pBSSEntry->phyparamset.fhparamset, pFH,
memmove(&bss->phyparamset.fhparamset, pFH,
sizeof(struct ieeetypes_fhparamset));
pBSSEntry->phyparamset.fhparamset.dwelltime
=
le16_to_cpu(pBSSEntry->phyparamset.fhparamset.
dwelltime);
#if 0 /* I think we can store these LE */
bss->phyparamset.fhparamset.dwelltime
= le16_to_cpu(bss->phyparamset.fhparamset.dwelltime);
#endif
break;
case DS_PARAM_SET:
pDS = (struct ieeetypes_dsparamset *) pcurrentptr;
pBSSEntry->channel = pDS->currentchan;
memcpy(&pBSSEntry->phyparamset.dsparamset, pDS,
bss->channel = pDS->currentchan;
memcpy(&bss->phyparamset.dsparamset, pDS,
sizeof(struct ieeetypes_dsparamset));
break;
case CF_PARAM_SET:
pCF = (struct ieeetypes_cfparamset *) pcurrentptr;
memcpy(&pBSSEntry->ssparamset.cfparamset, pCF,
memcpy(&bss->ssparamset.cfparamset, pCF,
sizeof(struct ieeetypes_cfparamset));
break;
case IBSS_PARAM_SET:
pibss = (struct ieeetypes_ibssparamset *) pcurrentptr;
pBSSEntry->atimwindow =
le32_to_cpu(pibss->atimwindow);
memmove(&pBSSEntry->ssparamset.ibssparamset, pibss,
bss->atimwindow = le32_to_cpu(pibss->atimwindow);
memmove(&bss->ssparamset.ibssparamset, pibss,
sizeof(struct ieeetypes_ibssparamset));
pBSSEntry->ssparamset.ibssparamset.atimwindow
=
le16_to_cpu(pBSSEntry->ssparamset.ibssparamset.
atimwindow);
#if 0
bss->ssparamset.ibssparamset.atimwindow
= le16_to_cpu(bss->ssparamset.ibssparamset.atimwindow);
#endif
break;
/* Handle Country Info IE */
case COUNTRY_INFO:
pcountryinfo =
(struct ieeetypes_countryinfoset *) pcurrentptr;
if (pcountryinfo->len <
sizeof(pcountryinfo->countrycode)
pcountryinfo = (struct ieeetypes_countryinfoset *) pcurrentptr;
if (pcountryinfo->len < sizeof(pcountryinfo->countrycode)
|| pcountryinfo->len > 254) {
lbs_pr_debug(1, "InterpretIE: 11D- Err "
lbs_deb_scan("process_bss: 11D- Err "
"CountryInfo len =%d min=%zd max=254\n",
pcountryinfo->len,
sizeof(pcountryinfo->countrycode));
LEAVE();
return -1;
ret = -1;
goto done;
}
memcpy(&pBSSEntry->countryinfo,
memcpy(&bss->countryinfo,
pcountryinfo, pcountryinfo->len + 2);
lbs_dbg_hex("InterpretIE: 11D- CountryInfo:",
lbs_dbg_hex("process_bss: 11D- CountryInfo:",
(u8 *) pcountryinfo,
(u32) (pcountryinfo->len + 2));
break;
......@@ -1114,12 +1137,10 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry,
bytestocopy = elemlen;
}
pRate = (u8 *) pBSSEntry->datarates;
pRate = (u8 *) bss->datarates;
pRate += ratesize;
memmove(pRate, (pcurrentptr + 2), bytestocopy);
pRate = (u8 *) pBSSEntry->libertas_supported_rates;
pRate = (u8 *) bss->libertas_supported_rates;
pRate += ratesize;
memmove(pRate, (pcurrentptr + 2), bytestocopy);
}
......@@ -1132,24 +1153,17 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry,
if (memcmp(pIe->oui, oui01, sizeof(oui01)))
break;
pBSSEntry->wpa_ie_len = min_t(size_t,
elemlen + IE_ID_LEN_FIELDS_BYTES,
sizeof(pBSSEntry->wpa_ie));
memcpy(pBSSEntry->wpa_ie, pcurrentptr,
pBSSEntry->wpa_ie_len);
lbs_dbg_hex("InterpretIE: Resp WPA_IE",
pBSSEntry->wpa_ie, elemlen);
bss->wpa_ie_len = min(elemlen + IE_ID_LEN_FIELDS_BYTES,
MAX_WPA_IE_LEN);
memcpy(bss->wpa_ie, pcurrentptr, bss->wpa_ie_len);
lbs_dbg_hex("process_bss: WPA IE", bss->wpa_ie, elemlen);
break;
case WPA2_IE:
pIe = (struct IE_WPA *)pcurrentptr;
pBSSEntry->rsn_ie_len = min_t(size_t,
elemlen + IE_ID_LEN_FIELDS_BYTES,
sizeof(pBSSEntry->rsn_ie));
memcpy(pBSSEntry->rsn_ie, pcurrentptr,
pBSSEntry->rsn_ie_len);
lbs_dbg_hex("InterpretIE: Resp WPA2_IE",
pBSSEntry->rsn_ie, elemlen);
bss->rsn_ie_len = min(elemlen + IE_ID_LEN_FIELDS_BYTES,
MAX_WPA_IE_LEN);
memcpy(bss->rsn_ie, pcurrentptr, bss->rsn_ie_len);
lbs_dbg_hex("process_bss: RSN_IE", bss->rsn_ie, elemlen);
break;
case TIM:
break;
......@@ -1165,7 +1179,14 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry,
} /* while (bytesleftforcurrentbeacon > 2) */
return 0;
/* Timestamp */
bss->last_scanned = jiffies;
ret = 0;
done:
lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret);
return ret;
}
/**
......@@ -1176,15 +1197,12 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry,
*
* @return 0--ssid is same, otherwise is different
*/
int libertas_SSID_cmp(struct WLAN_802_11_SSID *ssid1, struct WLAN_802_11_SSID *ssid2)
int libertas_ssid_cmp(u8 *ssid1, u8 ssid1_len, u8 *ssid2, u8 ssid2_len)
{
if (!ssid1 || !ssid2)
if (ssid1_len != ssid2_len)
return -1;
if (ssid1->ssidlength != ssid2->ssidlength)
return -1;
return memcmp(ssid1->ssid, ssid2->ssid, ssid1->ssidlength);
return memcmp(ssid1, ssid2, ssid1_len);
}
/**
......@@ -1196,38 +1214,41 @@ int libertas_SSID_cmp(struct WLAN_802_11_SSID *ssid1, struct WLAN_802_11_SSID *s
*
* @return index in BSSID list, or error return code (< 0)
*/
int libertas_find_BSSID_in_list(wlan_adapter * adapter, u8 * bssid, u8 mode)
struct bss_descriptor * libertas_find_bssid_in_list(wlan_adapter * adapter,
u8 * bssid, u8 mode)
{
int ret = -ENETUNREACH;
int i;
struct bss_descriptor * iter_bss;
struct bss_descriptor * found_bss = NULL;
if (!bssid)
return -EFAULT;
return NULL;
lbs_pr_debug(1, "FindBSSID: Num of BSSIDs = %d\n",
adapter->numinscantable);
lbs_dbg_hex("libertas_find_BSSID_in_list: looking for ",
bssid, ETH_ALEN);
/* Look through the scan table for a compatible match. The ret return
* variable will be equal to the index in the scan table (greater
* than zero) if the network is compatible. The loop will continue
* past a matched bssid that is not compatible in case there is an
* AP with multiple SSIDs assigned to the same BSSID
/* Look through the scan table for a compatible match. The loop will
* continue past a matched bssid that is not compatible in case there
* is an AP with multiple SSIDs assigned to the same BSSID
*/
for (i = 0; ret < 0 && i < adapter->numinscantable; i++) {
if (!memcmp(adapter->scantable[i].macaddress, bssid, ETH_ALEN)) {
mutex_lock(&adapter->lock);
list_for_each_entry (iter_bss, &adapter->network_list, list) {
if (compare_ether_addr(iter_bss->bssid, bssid))
continue; /* bssid doesn't match */
switch (mode) {
case IW_MODE_INFRA:
case IW_MODE_ADHOC:
ret = is_network_compatible(adapter, i, mode);
if (!is_network_compatible(adapter, iter_bss, mode))
break;
found_bss = iter_bss;
break;
default:
ret = i;
found_bss = iter_bss;
break;
}
}
}
mutex_unlock(&adapter->lock);
return ret;
return found_bss;
}
/**
......@@ -1240,61 +1261,60 @@ int libertas_find_BSSID_in_list(wlan_adapter * adapter, u8 * bssid, u8 mode)
*
* @return index in BSSID list
*/
int libertas_find_SSID_in_list(wlan_adapter * adapter,
struct WLAN_802_11_SSID *ssid, u8 * bssid, u8 mode)
struct bss_descriptor * libertas_find_ssid_in_list(wlan_adapter * adapter,
u8 *ssid, u8 ssid_len, u8 * bssid, u8 mode,
int channel)
{
int net = -ENETUNREACH;
u8 bestrssi = 0;
int i;
int j;
struct bss_descriptor * iter_bss = NULL;
struct bss_descriptor * found_bss = NULL;
struct bss_descriptor * tmp_oldest = NULL;
mutex_lock(&adapter->lock);
lbs_pr_debug(1, "Num of Entries in Table = %d\n", adapter->numinscantable);
list_for_each_entry (iter_bss, &adapter->network_list, list) {
if ( !tmp_oldest
|| (iter_bss->last_scanned < tmp_oldest->last_scanned))
tmp_oldest = iter_bss;
if (libertas_ssid_cmp(iter_bss->ssid, iter_bss->ssid_len,
ssid, ssid_len) != 0)
continue; /* ssid doesn't match */
if (bssid && compare_ether_addr(iter_bss->bssid, bssid) != 0)
continue; /* bssid doesn't match */
if ((channel > 0) && (iter_bss->channel != channel))
continue; /* channel doesn't match */
for (i = 0; i < adapter->numinscantable; i++) {
if (!libertas_SSID_cmp(&adapter->scantable[i].ssid, ssid) &&
(!bssid ||
!memcmp(adapter->scantable[i].
macaddress, bssid, ETH_ALEN))) {
switch (mode) {
case IW_MODE_INFRA:
case IW_MODE_ADHOC:
j = is_network_compatible(adapter, i, mode);
if (!is_network_compatible(adapter, iter_bss, mode))
break;
if (j >= 0) {
if (bssid) {
return i;
/* Found requested BSSID */
found_bss = iter_bss;
goto out;
}
if (SCAN_RSSI
(adapter->scantable[i].rssi)
> bestrssi) {
bestrssi =
SCAN_RSSI(adapter->
scantable[i].
rssi);
net = i;
}
} else {
if (net == -ENETUNREACH) {
net = j;
}
if (SCAN_RSSI(iter_bss->rssi) > bestrssi) {
bestrssi = SCAN_RSSI(iter_bss->rssi);
found_bss = iter_bss;
}
break;
case IW_MODE_AUTO:
default:
if (SCAN_RSSI(adapter->scantable[i].rssi)
> bestrssi) {
bestrssi =
SCAN_RSSI(adapter->scantable[i].
rssi);
net = i;
if (SCAN_RSSI(iter_bss->rssi) > bestrssi) {
bestrssi = SCAN_RSSI(iter_bss->rssi);
found_bss = iter_bss;
}
break;
}
}
}
return net;
out:
mutex_unlock(&adapter->lock);
return found_bss;
}
/**
......@@ -1307,43 +1327,38 @@ int libertas_find_SSID_in_list(wlan_adapter * adapter,
*
* @return index in BSSID list
*/
int libertas_find_best_SSID_in_list(wlan_adapter * adapter, u8 mode)
struct bss_descriptor * libertas_find_best_ssid_in_list(wlan_adapter * adapter,
u8 mode)
{
int bestnet = -ENETUNREACH;
u8 bestrssi = 0;
int i;
struct bss_descriptor * iter_bss;
struct bss_descriptor * best_bss = NULL;
ENTER();
mutex_lock(&adapter->lock);
lbs_pr_debug(1, "Num of BSSIDs = %d\n", adapter->numinscantable);
for (i = 0; i < adapter->numinscantable; i++) {
list_for_each_entry (iter_bss, &adapter->network_list, list) {
switch (mode) {
case IW_MODE_INFRA:
case IW_MODE_ADHOC:
if (is_network_compatible(adapter, i, mode) >= 0) {
if (SCAN_RSSI(adapter->scantable[i].rssi) >
bestrssi) {
bestrssi =
SCAN_RSSI(adapter->scantable[i].
rssi);
bestnet = i;
}
}
if (!is_network_compatible(adapter, iter_bss, mode))
break;
if (SCAN_RSSI(iter_bss->rssi) <= bestrssi)
break;
bestrssi = SCAN_RSSI(iter_bss->rssi);
best_bss = iter_bss;
break;
case IW_MODE_AUTO:
default:
if (SCAN_RSSI(adapter->scantable[i].rssi) > bestrssi) {
bestrssi =
SCAN_RSSI(adapter->scantable[i].rssi);
bestnet = i;
}
if (SCAN_RSSI(iter_bss->rssi) <= bestrssi)
break;
bestrssi = SCAN_RSSI(iter_bss->rssi);
best_bss = iter_bss;
break;
}
}
LEAVE();
return bestnet;
mutex_unlock(&adapter->lock);
return best_bss;
}
/**
......@@ -1354,41 +1369,30 @@ int libertas_find_best_SSID_in_list(wlan_adapter * adapter, u8 mode)
*
* @return 0--success, otherwise--fail
*/
int libertas_find_best_network_SSID(wlan_private * priv,
struct WLAN_802_11_SSID *pSSID,
u8 preferred_mode, u8 *out_mode)
int libertas_find_best_network_ssid(wlan_private * priv,
u8 *out_ssid, u8 *out_ssid_len, u8 preferred_mode, u8 *out_mode)
{
wlan_adapter *adapter = priv->adapter;
int ret = 0;
struct bss_descriptor *preqbssid;
int i;
ENTER();
int ret = -1;
struct bss_descriptor * found;
memset(pSSID, 0, sizeof(struct WLAN_802_11_SSID));
lbs_deb_enter(LBS_DEB_ASSOC);
wlan_scan_networks(priv, NULL);
wlan_scan_networks(priv, NULL, 1);
if (adapter->surpriseremoved)
return -1;
wait_event_interruptible(adapter->cmd_pending, !adapter->nr_cmd_pending);
i = libertas_find_best_SSID_in_list(adapter, preferred_mode);
if (i < 0) {
ret = -1;
goto out;
}
preqbssid = &adapter->scantable[i];
memcpy(pSSID, &preqbssid->ssid,
sizeof(struct WLAN_802_11_SSID));
*out_mode = preqbssid->mode;
wait_event_interruptible(adapter->cmd_pending, !adapter->nr_cmd_pending);
if (!pSSID->ssidlength) {
ret = -1;
found = libertas_find_best_ssid_in_list(adapter, preferred_mode);
if (found && (found->ssid_len > 0)) {
memcpy(out_ssid, &found->ssid, IW_ESSID_MAX_SIZE);
*out_ssid_len = found->ssid_len;
*out_mode = found->mode;
ret = 0;
}
out:
LEAVE();
lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret);
return ret;
}
......@@ -1407,20 +1411,15 @@ int libertas_set_scan(struct net_device *dev, struct iw_request_info *info,
{
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
union iwreq_data wrqu;
ENTER();
lbs_deb_enter(LBS_DEB_SCAN);
if (!wlan_scan_networks(priv, NULL)) {
memset(&wrqu, 0, sizeof(union iwreq_data));
wireless_send_event(priv->wlan_dev.netdev, SIOCGIWSCAN, &wrqu,
NULL);
}
wlan_scan_networks(priv, NULL, 0);
if (adapter->surpriseremoved)
return -1;
LEAVE();
lbs_deb_leave(LBS_DEB_SCAN);
return 0;
}
......@@ -1433,32 +1432,31 @@ int libertas_set_scan(struct net_device *dev, struct iw_request_info *info,
*
* @return 0-success, otherwise fail
*/
int libertas_send_specific_SSID_scan(wlan_private * priv,
struct WLAN_802_11_SSID *prequestedssid,
u8 keeppreviousscan)
int libertas_send_specific_ssid_scan(wlan_private * priv,
u8 *ssid, u8 ssid_len, u8 clear_ssid)
{
wlan_adapter *adapter = priv->adapter;
struct wlan_ioctl_user_scan_cfg scancfg;
int ret = 0;
ENTER();
lbs_deb_enter(LBS_DEB_ASSOC);
if (prequestedssid == NULL) {
return -1;
}
if (!ssid_len)
goto out;
memset(&scancfg, 0x00, sizeof(scancfg));
memcpy(scancfg.ssid, ssid, ssid_len);
scancfg.ssid_len = ssid_len;
scancfg.clear_ssid = clear_ssid;
memcpy(scancfg.specificSSID, prequestedssid->ssid,
prequestedssid->ssidlength);
scancfg.keeppreviousscan = keeppreviousscan;
wlan_scan_networks(priv, &scancfg);
wlan_scan_networks(priv, &scancfg, 1);
if (adapter->surpriseremoved)
return -1;
wait_event_interruptible(adapter->cmd_pending, !adapter->nr_cmd_pending);
LEAVE();
return 0;
out:
lbs_deb_leave(LBS_DEB_ASSOC);
return ret;
}
/**
......@@ -1470,152 +1468,77 @@ int libertas_send_specific_SSID_scan(wlan_private * priv,
*
* @return 0-success, otherwise fail
*/
int libertas_send_specific_BSSID_scan(wlan_private * priv, u8 * bssid, u8 keeppreviousscan)
int libertas_send_specific_bssid_scan(wlan_private * priv, u8 * bssid, u8 clear_bssid)
{
struct wlan_ioctl_user_scan_cfg scancfg;
ENTER();
lbs_deb_enter(LBS_DEB_ASSOC);
if (bssid == NULL) {
return -1;
}
if (bssid == NULL)
goto out;
memset(&scancfg, 0x00, sizeof(scancfg));
memcpy(scancfg.specificBSSID, bssid, sizeof(scancfg.specificBSSID));
scancfg.keeppreviousscan = keeppreviousscan;
memcpy(scancfg.bssid, bssid, ETH_ALEN);
scancfg.clear_bssid = clear_bssid;
wlan_scan_networks(priv, &scancfg);
wlan_scan_networks(priv, &scancfg, 1);
if (priv->adapter->surpriseremoved)
return -1;
wait_event_interruptible(priv->adapter->cmd_pending,
!priv->adapter->nr_cmd_pending);
LEAVE();
out:
lbs_deb_leave(LBS_DEB_ASSOC);
return 0;
}
/**
* @brief Retrieve the scan table entries via wireless tools IOCTL call
*
* @param dev A pointer to net_device structure
* @param info A pointer to iw_request_info structure
* @param dwrq A pointer to iw_point structure
* @param extra A pointer to extra data buf
*
* @return 0 --success, otherwise fail
*/
int libertas_get_scan(struct net_device *dev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
static inline char *libertas_translate_scan(wlan_private *priv,
char *start, char *stop,
struct bss_descriptor *bss)
{
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
int ret = 0;
char *current_ev = extra;
char *end_buf = extra + IW_SCAN_MAX_DATA;
struct chan_freq_power *cfp;
struct bss_descriptor *pscantable;
char *current_val; /* For rates */
struct iw_event iwe; /* Temporary buffer */
int i;
int j;
int rate;
#define PERFECT_RSSI ((u8)50)
#define WORST_RSSI ((u8)0)
#define RSSI_DIFF ((u8)(PERFECT_RSSI - WORST_RSSI))
u8 rssi;
u8 buf[16 + 256 * 2];
u8 *ptr;
ENTER();
/*
* if there's either commands in the queue or one being
* processed return -EAGAIN for iwlist to retry later.
*/
if (adapter->nr_cmd_pending)
return -EAGAIN;
if (adapter->connect_status == libertas_connected)
lbs_pr_debug(1, "Current ssid: %32s\n",
adapter->curbssparams.ssid.ssid);
lbs_pr_debug(1, "Scan: Get: numinscantable = %d\n",
adapter->numinscantable);
/* The old API using SIOCGIWAPLIST had a hard limit of IW_MAX_AP.
* The new API using SIOCGIWSCAN is only limited by buffer size
* WE-14 -> WE-16 the buffer is limited to IW_SCAN_MAX_DATA bytes
* which is 4096.
*/
for (i = 0; i < adapter->numinscantable; i++) {
if ((current_ev + MAX_SCAN_CELL_SIZE) >= end_buf) {
lbs_pr_debug(1, "i=%d break out: current_ev=%p end_buf=%p "
"MAX_SCAN_CELL_SIZE=%zd\n",
i, current_ev, end_buf, MAX_SCAN_CELL_SIZE);
break;
}
pscantable = &adapter->scantable[i];
lbs_pr_debug(1, "i=%d ssid: %32s\n", i, pscantable->ssid.ssid);
cfp =
libertas_find_cfp_by_band_and_channel(adapter, 0,
pscantable->channel);
cfp = libertas_find_cfp_by_band_and_channel(adapter, 0, bss->channel);
if (!cfp) {
lbs_pr_debug(1, "Invalid channel number %d\n",
pscantable->channel);
continue;
}
if (!ssid_valid(&adapter->scantable[i].ssid)) {
continue;
lbs_deb_scan("Invalid channel number %d\n", bss->channel);
return NULL;
}
/* First entry *MUST* be the AP MAC address */
/* First entry *MUST* be the AP BSSID */
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data,
&adapter->scantable[i].macaddress, ETH_ALEN);
iwe.len = IW_EV_ADDR_LEN;
current_ev =
iwe_stream_add_event(current_ev, end_buf, &iwe, iwe.len);
//Add the ESSID
iwe.u.data.length = adapter->scantable[i].ssid.ssidlength;
if (iwe.u.data.length > 32) {
iwe.u.data.length = 32;
}
memcpy(iwe.u.ap_addr.sa_data, &bss->bssid, ETH_ALEN);
start = iwe_stream_add_event(start, stop, &iwe, IW_EV_ADDR_LEN);
/* SSID */
iwe.cmd = SIOCGIWESSID;
iwe.u.data.flags = 1;
iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
adapter->scantable[i].ssid.
ssid);
iwe.u.data.length = min((u32) bss->ssid_len, (u32) IW_ESSID_MAX_SIZE);
start = iwe_stream_add_point(start, stop, &iwe, bss->ssid);
//Add mode
/* Mode */
iwe.cmd = SIOCGIWMODE;
iwe.u.mode = adapter->scantable[i].mode;
iwe.len = IW_EV_UINT_LEN;
current_ev =
iwe_stream_add_event(current_ev, end_buf, &iwe, iwe.len);
iwe.u.mode = bss->mode;
start = iwe_stream_add_event(start, stop, &iwe, IW_EV_UINT_LEN);
//frequency
/* Frequency */
iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = (long)cfp->freq * 100000;
iwe.u.freq.e = 1;
iwe.len = IW_EV_FREQ_LEN;
current_ev =
iwe_stream_add_event(current_ev, end_buf, &iwe, iwe.len);
start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN);
/* Add quality statistics */
iwe.cmd = IWEVQUAL;
iwe.u.qual.updated = IW_QUAL_ALL_UPDATED;
iwe.u.qual.level = SCAN_RSSI(adapter->scantable[i].rssi);
iwe.u.qual.level = SCAN_RSSI(bss->rssi);
rssi = iwe.u.qual.level - MRVDRV_NF_DEFAULT_SCAN_VALUE;
iwe.u.qual.qual =
......@@ -1624,8 +1547,6 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info,
(RSSI_DIFF * RSSI_DIFF);
if (iwe.u.qual.qual > 100)
iwe.u.qual.qual = 100;
else if (iwe.u.qual.qual < 1)
iwe.u.qual.qual = 0;
if (adapter->NF[TYPE_BEACON][TYPE_NOAVG] == 0) {
iwe.u.qual.noise = MRVDRV_NF_DEFAULT_SCAN_VALUE;
......@@ -1633,141 +1554,149 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info,
iwe.u.qual.noise =
CAL_NF(adapter->NF[TYPE_BEACON][TYPE_NOAVG]);
}
if ((adapter->mode == IW_MODE_ADHOC) &&
!libertas_SSID_cmp(&adapter->curbssparams.ssid,
&adapter->scantable[i].ssid)
&& adapter->adhoccreate) {
ret = libertas_prepare_and_send_command(priv,
cmd_802_11_rssi,
0,
cmd_option_waitforrsp,
0, NULL);
if (!ret) {
iwe.u.qual.level =
CAL_RSSI(adapter->SNR[TYPE_RXPD][TYPE_AVG] /
AVG_SCALE,
adapter->NF[TYPE_RXPD][TYPE_AVG] /
AVG_SCALE);
}
}
iwe.len = IW_EV_QUAL_LEN;
current_ev =
iwe_stream_add_event(current_ev, end_buf, &iwe, iwe.len);
/* Locally created ad-hoc BSSs won't have beacons if this is the
* only station in the adhoc network; so get signal strength
* from receive statistics.
*/
if ((adapter->mode == IW_MODE_ADHOC)
&& adapter->adhoccreate
&& !libertas_ssid_cmp(adapter->curbssparams.ssid,
adapter->curbssparams.ssid_len,
bss->ssid, bss->ssid_len)) {
int snr, nf;
snr = adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
nf = adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
iwe.u.qual.level = CAL_RSSI(snr, nf);
}
start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN);
/* Add encryption capability */
iwe.cmd = SIOCGIWENCODE;
if (adapter->scantable[i].privacy) {
if (bss->privacy) {
iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
} else {
iwe.u.data.flags = IW_ENCODE_DISABLED;
}
iwe.u.data.length = 0;
iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
adapter->scantable->ssid.
ssid);
start = iwe_stream_add_point(start, stop, &iwe, bss->ssid);
current_val = current_ev + IW_EV_LCP_LEN;
current_val = start + IW_EV_LCP_LEN;
iwe.cmd = SIOCGIWRATE;
iwe.u.bitrate.fixed = 0;
iwe.u.bitrate.disabled = 0;
iwe.u.bitrate.value = 0;
for (j = 0; j < sizeof(bss->libertas_supported_rates); j++) {
u8 rate = bss->libertas_supported_rates[j];
if (rate == 0)
break; /* no more rates */
/* Bit rate given in 500 kb/s units (+ 0x80) */
for (j = 0; j < sizeof(adapter->scantable[i].libertas_supported_rates);
j++) {
if (adapter->scantable[i].libertas_supported_rates[j] == 0) {
break;
}
rate =
(adapter->scantable[i].libertas_supported_rates[j] & 0x7F) *
500000;
if (rate > iwe.u.bitrate.value) {
iwe.u.bitrate.value = rate;
}
iwe.u.bitrate.value =
(adapter->scantable[i].libertas_supported_rates[j]
& 0x7f) * 500000;
iwe.len = IW_EV_PARAM_LEN;
current_ev =
iwe_stream_add_value(current_ev, current_val,
end_buf, &iwe, iwe.len);
}
if ((adapter->scantable[i].mode == IW_MODE_ADHOC)
&& !libertas_SSID_cmp(&adapter->curbssparams.ssid,
&adapter->scantable[i].ssid)
iwe.u.bitrate.value = (rate & 0x7f) * 500000;
current_val = iwe_stream_add_value(start, current_val,
stop, &iwe, IW_EV_PARAM_LEN);
}
if ((bss->mode == IW_MODE_ADHOC)
&& !libertas_ssid_cmp(adapter->curbssparams.ssid,
adapter->curbssparams.ssid_len,
bss->ssid, bss->ssid_len)
&& adapter->adhoccreate) {
iwe.u.bitrate.value = 22 * 500000;
current_val = iwe_stream_add_value(start, current_val,
stop, &iwe, IW_EV_PARAM_LEN);
}
iwe.len = IW_EV_PARAM_LEN;
current_ev =
iwe_stream_add_value(current_ev, current_val, end_buf, &iwe,
iwe.len);
/* Check if we added any event */
if((current_val - start) > IW_EV_LCP_LEN)
start = current_val;
/* Add new value to event */
current_val = current_ev + IW_EV_LCP_LEN;
if (adapter->scantable[i].rsn_ie[0] == WPA2_IE) {
memset(&iwe, 0, sizeof(iwe));
memset(buf, 0, sizeof(buf));
memcpy(buf, adapter->scantable[i].rsn_ie,
adapter->scantable[i].rsn_ie_len);
if (bss->wpa_ie_len) {
char buf[MAX_WPA_IE_LEN];
memcpy(buf, bss->wpa_ie, bss->wpa_ie_len);
iwe.cmd = IWEVGENIE;
iwe.u.data.length = adapter->scantable[i].rsn_ie_len;
iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
current_ev = iwe_stream_add_point(current_ev, end_buf,
&iwe, buf);
iwe.u.data.length = bss->wpa_ie_len;
start = iwe_stream_add_point(start, stop, &iwe, buf);
}
if (adapter->scantable[i].wpa_ie[0] == WPA_IE) {
memset(&iwe, 0, sizeof(iwe));
memset(buf, 0, sizeof(buf));
memcpy(buf, adapter->scantable[i].wpa_ie,
adapter->scantable[i].wpa_ie_len);
if (bss->rsn_ie_len) {
char buf[MAX_WPA_IE_LEN];
memcpy(buf, bss->rsn_ie, bss->rsn_ie_len);
iwe.cmd = IWEVGENIE;
iwe.u.data.length = adapter->scantable[i].wpa_ie_len;
iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
current_ev = iwe_stream_add_point(current_ev, end_buf,
&iwe, buf);
iwe.u.data.length = bss->rsn_ie_len;
start = iwe_stream_add_point(start, stop, &iwe, buf);
}
return start;
}
if (adapter->scantable[i].extra_ie != 0) {
memset(&iwe, 0, sizeof(iwe));
memset(buf, 0, sizeof(buf));
ptr = buf;
ptr += sprintf(ptr, "extra_ie");
iwe.u.data.length = strlen(buf);
/**
* @brief Retrieve the scan table entries via wireless tools IOCTL call
*
* @param dev A pointer to net_device structure
* @param info A pointer to iw_request_info structure
* @param dwrq A pointer to iw_point structure
* @param extra A pointer to extra data buf
*
* @return 0 --success, otherwise fail
*/
int libertas_get_scan(struct net_device *dev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
{
#define SCAN_ITEM_SIZE 128
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
int err = 0;
char *ev = extra;
char *stop = ev + dwrq->length;
struct bss_descriptor * iter_bss;
struct bss_descriptor * safe;
lbs_deb_enter(LBS_DEB_ASSOC);
lbs_pr_debug(1, "iwe.u.data.length %d\n",
iwe.u.data.length);
lbs_pr_debug(1, "BUF: %s \n", buf);
/* 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);
iwe.cmd = IWEVCUSTOM;
iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
current_ev =
iwe_stream_add_point(current_ev, end_buf, &iwe,
buf);
/* 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);
}
current_val = current_ev + IW_EV_LCP_LEN;
mutex_lock(&adapter->lock);
list_for_each_entry_safe (iter_bss, safe, &adapter->network_list, list) {
char * next_ev;
unsigned long stale_time;
/*
* Check if we added any event
*/
if ((current_val - current_ev) > IW_EV_LCP_LEN)
current_ev = current_val;
if (stop - ev < SCAN_ITEM_SIZE) {
err = -E2BIG;
break;
}
/* Prune old an old scan result */
stale_time = iter_bss->last_scanned + DEFAULT_MAX_SCAN_AGE;
if (time_after(jiffies, stale_time)) {
list_move_tail (&iter_bss->list,
&adapter->network_free_list);
clear_bss_descriptor(iter_bss);
continue;
}
/* Translate to WE format this entry */
next_ev = libertas_translate_scan(priv, ev, stop, iter_bss);
if (next_ev == NULL)
continue;
ev = next_ev;
}
mutex_unlock(&adapter->lock);
dwrq->length = (current_ev - extra);
dwrq->length = (ev - extra);
dwrq->flags = 0;
LEAVE();
return 0;
lbs_deb_leave(LBS_DEB_ASSOC);
return err;
}
/**
......@@ -1796,13 +1725,13 @@ int libertas_cmd_80211_scan(wlan_private * priv,
struct cmd_ds_802_11_scan *pscan = &cmd->params.scan;
struct wlan_scan_cmd_config *pscancfg;
ENTER();
lbs_deb_enter(LBS_DEB_ASSOC);
pscancfg = pdata_buf;
/* Set fixed field variables in scan command */
pscan->bsstype = pscancfg->bsstype;
memcpy(pscan->BSSID, pscancfg->specificBSSID, sizeof(pscan->BSSID));
memcpy(pscan->BSSID, pscancfg->bssid, sizeof(pscan->BSSID));
memcpy(pscan->tlvbuffer, pscancfg->tlvbuffer, pscancfg->tlvbufferlen);
cmd->command = cpu_to_le16(cmd_802_11_scan);
......@@ -1812,12 +1741,26 @@ int libertas_cmd_80211_scan(wlan_private * priv,
+ sizeof(pscan->BSSID)
+ pscancfg->tlvbufferlen + S_DS_GEN);
lbs_pr_debug(1, "SCAN_CMD: command=%x, size=%x, seqnum=%x\n",
cmd->command, cmd->size, cmd->seqnum);
LEAVE();
lbs_deb_scan("SCAN_CMD: command=%x, size=%x, seqnum=%x\n",
le16_to_cpu(cmd->command), le16_to_cpu(cmd->size),
le16_to_cpu(cmd->seqnum));
lbs_deb_leave(LBS_DEB_ASSOC);
return 0;
}
static inline int is_same_network(struct bss_descriptor *src,
struct bss_descriptor *dst)
{
/* A network is only a duplicate if the channel, BSSID, and ESSID
* all match. We treat all <hidden> with the same BSSID and channel
* as one network */
return ((src->ssid_len == dst->ssid_len) &&
(src->channel == dst->channel) &&
!compare_ether_addr(src->bssid, dst->bssid) &&
!memcmp(src->ssid, dst->ssid, src->ssid_len));
}
/**
* @brief This function handles the command response of scan
*
......@@ -1846,38 +1789,45 @@ int libertas_ret_80211_scan(wlan_private * priv, struct cmd_ds_command *resp)
{
wlan_adapter *adapter = priv->adapter;
struct cmd_ds_802_11_scan_rsp *pscan;
struct bss_descriptor newbssentry;
struct mrvlietypes_data *ptlv;
struct mrvlietypes_tsftimestamp *ptsftlv;
struct bss_descriptor * iter_bss;
struct bss_descriptor * safe;
u8 *pbssinfo;
u16 scanrespsize;
int bytesleft;
int numintable;
int bssIdx;
int idx;
int tlvbufsize;
u64 tsfval;
int ret;
ENTER();
lbs_deb_enter(LBS_DEB_ASSOC);
/* Prune old entries from scan table */
list_for_each_entry_safe (iter_bss, safe, &adapter->network_list, list) {
unsigned long stale_time = iter_bss->last_scanned + DEFAULT_MAX_SCAN_AGE;
if (time_before(jiffies, stale_time))
continue;
list_move_tail (&iter_bss->list, &adapter->network_free_list);
clear_bss_descriptor(iter_bss);
}
pscan = &resp->params.scanresp;
if (pscan->nr_sets > MRVDRV_MAX_BSSID_LIST) {
lbs_pr_debug(1,
"SCAN_RESP: Invalid number of AP returned (%d)!!\n",
pscan->nr_sets);
LEAVE();
return -1;
if (pscan->nr_sets > MAX_NETWORK_COUNT) {
lbs_deb_scan(
"SCAN_RESP: too many scan results (%d, max %d)!!\n",
pscan->nr_sets, MAX_NETWORK_COUNT);
ret = -1;
goto done;
}
bytesleft = le16_to_cpu(pscan->bssdescriptsize);
lbs_pr_debug(1, "SCAN_RESP: bssdescriptsize %d\n", bytesleft);
lbs_deb_scan("SCAN_RESP: bssdescriptsize %d\n", bytesleft);
scanrespsize = le16_to_cpu(resp->size);
lbs_pr_debug(1, "SCAN_RESP: returned %d AP before parsing\n",
lbs_deb_scan("SCAN_RESP: returned %d AP before parsing\n",
pscan->nr_sets);
numintable = adapter->numinscantable;
pbssinfo = pscan->bssdesc_and_tlvbuffer;
/* The size of the TLV buffer is equal to the entire command response
......@@ -1901,70 +1851,51 @@ int libertas_ret_80211_scan(wlan_private * priv, struct cmd_ds_command *resp)
* or as an addition at the end of the table
*/
for (idx = 0; idx < pscan->nr_sets && bytesleft; idx++) {
/* Zero out the newbssentry we are about to store info in */
memset(&newbssentry, 0x00, sizeof(newbssentry));
struct bss_descriptor new;
struct bss_descriptor * found = NULL;
struct bss_descriptor * oldest = NULL;
/* Process the data fields and IEs returned for this BSS */
if ((InterpretBSSDescriptionWithIE(&newbssentry,
&pbssinfo,
&bytesleft) ==
0)
&& CHECK_SSID_IS_VALID(&newbssentry.ssid)) {
lbs_pr_debug(1,
"SCAN_RESP: BSSID = %02x:%02x:%02x:%02x:%02x:%02x\n",
newbssentry.macaddress[0],
newbssentry.macaddress[1],
newbssentry.macaddress[2],
newbssentry.macaddress[3],
newbssentry.macaddress[4],
newbssentry.macaddress[5]);
memset(&new, 0, sizeof (struct bss_descriptor));
if (libertas_process_bss(&new, &pbssinfo, &bytesleft) != 0) {
/* error parsing the scan response, skipped */
lbs_deb_scan("SCAN_RESP: process_bss returned ERROR\n");
continue;
}
/*
* Search the scan table for the same bssid
*/
for (bssIdx = 0; bssIdx < numintable; bssIdx++) {
if (memcmp(newbssentry.macaddress,
adapter->scantable[bssIdx].
macaddress,
sizeof(newbssentry.macaddress)) ==
0) {
/*
* If the SSID matches as well, it is a duplicate of
* this entry. Keep the bssIdx set to this
* entry so we replace the old contents in the table
*/
if ((newbssentry.ssid.ssidlength ==
adapter->scantable[bssIdx].ssid.
ssidlength)
&&
(memcmp
(newbssentry.ssid.ssid,
adapter->scantable[bssIdx].ssid.
ssid,
newbssentry.ssid.ssidlength) ==
0)) {
lbs_pr_debug(1,
"SCAN_RESP: Duplicate of index: %d\n",
bssIdx);
/* Try to find this bss in the scan table */
list_for_each_entry (iter_bss, &adapter->network_list, list) {
if (is_same_network(iter_bss, &new)) {
found = iter_bss;
break;
}
}
}
/*
* If the bssIdx is equal to the number of entries in the table,
* the new entry was not a duplicate; append it to the scan
* table
*/
if (bssIdx == numintable) {
/* Range check the bssIdx, keep it limited to the last entry */
if (bssIdx == MRVDRV_MAX_BSSID_LIST) {
bssIdx--;
if ((oldest == NULL) ||
(iter_bss->last_scanned < oldest->last_scanned))
oldest = iter_bss;
}
if (found) {
/* found, clear it */
clear_bss_descriptor(found);
} else if (!list_empty(&adapter->network_free_list)) {
/* Pull one from the free list */
found = list_entry(adapter->network_free_list.next,
struct bss_descriptor, list);
list_move_tail(&found->list, &adapter->network_list);
} else if (oldest) {
/* If there are no more slots, expire the oldest */
found = oldest;
clear_bss_descriptor(found);
list_move_tail(&found->list, &adapter->network_list);
} else {
numintable++;
}
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
......@@ -1972,34 +1903,16 @@ int libertas_ret_80211_scan(wlan_private * priv, struct cmd_ds_command *resp)
* beacon or probe response was received.
*/
if (ptsftlv) {
memcpy(&tsfval, &ptsftlv->tsftable[idx],
sizeof(tsfval));
tsfval = le64_to_cpu(tsfval);
memcpy(&newbssentry.networktsf,
&tsfval, sizeof(newbssentry.networktsf));
new.networktsf = le64_to_cpup(&ptsftlv->tsftable[idx]);
}
/* Copy the locally created newbssentry to the scan table */
memcpy(&adapter->scantable[bssIdx],
&newbssentry,
sizeof(adapter->scantable[bssIdx]));
} else {
/* error parsing/interpreting the scan response, skipped */
lbs_pr_debug(1, "SCAN_RESP: "
"InterpretBSSDescriptionWithIE returned ERROR\n");
memcpy(found, &new, offsetof(struct bss_descriptor, list));
}
}
lbs_pr_debug(1, "SCAN_RESP: Scanned %2d APs, %d valid, %d total\n",
pscan->nr_sets, numintable - adapter->numinscantable,
numintable);
/* Update the total number of BSSIDs in the scan table */
adapter->numinscantable = numintable;
ret = 0;
LEAVE();
return 0;
done:
lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret);
return ret;
}
......@@ -51,7 +51,7 @@ struct wlan_scan_cmd_config {
/**
* @brief Specific BSSID used to filter scan results in the firmware
*/
u8 specificBSSID[ETH_ALEN];
u8 bssid[ETH_ALEN];
/**
* @brief length of TLVs sent in command starting at tlvBuffer
......@@ -91,15 +91,6 @@ struct wlan_ioctl_user_scan_chan {
* @sa libertas_set_user_scan_ioctl
*/
struct wlan_ioctl_user_scan_cfg {
/**
* @brief Flag set to keep the previous scan table intact
*
* If set, the scan results will accumulate, replacing any previous
* matched entries for a BSS with the new scan data
*/
u8 keeppreviousscan; //!< Do not erase the existing scan results
/**
* @brief BSS type to be sent in the firmware command
*
......@@ -120,12 +111,19 @@ struct wlan_ioctl_user_scan_cfg {
/**
* @brief BSSID filter sent in the firmware command to limit the results
*/
u8 specificBSSID[ETH_ALEN];
u8 bssid[ETH_ALEN];
/* Clear existing scan results matching this BSSID */
u8 clear_bssid;
/**
* @brief SSID filter sent in the firmware command to limit the results
*/
char specificSSID[IW_ESSID_MAX_SIZE + 1];
char ssid[IW_ESSID_MAX_SIZE];
u8 ssid_len;
/* Clear existing scan results matching this SSID */
u8 clear_ssid;
/**
* @brief Variable number (fixed maximum) of channels to scan up
......@@ -137,9 +135,10 @@ struct wlan_ioctl_user_scan_cfg {
* @brief Structure used to store information for each beacon/probe response
*/
struct bss_descriptor {
u8 macaddress[ETH_ALEN];
u8 bssid[ETH_ALEN];
struct WLAN_802_11_SSID ssid;
u8 ssid[IW_ESSID_MAX_SIZE + 1];
u8 ssid_len;
/* WEP encryption requirement */
u32 privacy;
......@@ -156,15 +155,15 @@ struct bss_descriptor {
u8 mode;
u8 libertas_supported_rates[WLAN_SUPPORTED_RATES];
int extra_ie;
__le64 timestamp; //!< TSF value included in the beacon/probe response
unsigned long last_scanned;
u8 timestamp[8]; //!< TSF value included in the beacon/probe response
union ieeetypes_phyparamset phyparamset;
union IEEEtypes_ssparamset ssparamset;
struct ieeetypes_capinfo cap;
u8 datarates[WLAN_SUPPORTED_RATES];
__le64 networktsf; //!< TSF timestamp from the current firmware TSF
u64 networktsf; //!< TSF timestamp from the current firmware TSF
struct ieeetypes_countryinfofullset countryinfo;
......@@ -172,24 +171,29 @@ struct bss_descriptor {
size_t wpa_ie_len;
u8 rsn_ie[MAX_WPA_IE_LEN];
size_t rsn_ie_len;
struct list_head list;
};
extern int libertas_SSID_cmp(struct WLAN_802_11_SSID *ssid1,
struct WLAN_802_11_SSID *ssid2);
extern int libertas_find_SSID_in_list(wlan_adapter * adapter, struct WLAN_802_11_SSID *ssid,
extern int libertas_ssid_cmp(u8 *ssid1, u8 ssid1_len, u8 *ssid2, u8 ssid2_len);
struct bss_descriptor * libertas_find_ssid_in_list(wlan_adapter * adapter,
u8 *ssid, u8 ssid_len, u8 * bssid, u8 mode,
int channel);
struct bss_descriptor * libertas_find_best_ssid_in_list(wlan_adapter * adapter,
u8 mode);
extern struct bss_descriptor * libertas_find_bssid_in_list(wlan_adapter * adapter,
u8 * bssid, u8 mode);
int libertas_find_best_SSID_in_list(wlan_adapter * adapter, u8 mode);
extern int libertas_find_BSSID_in_list(wlan_adapter * adapter, u8 * bssid, u8 mode);
int libertas_find_best_network_SSID(wlan_private * priv,
struct WLAN_802_11_SSID *pSSID,
u8 preferred_mode, u8 *out_mode);
int libertas_find_best_network_ssid(wlan_private * priv, u8 *out_ssid,
u8 *out_ssid_len, u8 preferred_mode, u8 *out_mode);
extern int libertas_send_specific_SSID_scan(wlan_private * priv,
struct WLAN_802_11_SSID *prequestedssid,
u8 keeppreviousscan);
extern int libertas_send_specific_BSSID_scan(wlan_private * priv,
u8 * bssid, u8 keeppreviousscan);
extern int libertas_send_specific_ssid_scan(wlan_private * priv, u8 *ssid,
u8 ssid_len, u8 clear_ssid);
extern int libertas_send_specific_bssid_scan(wlan_private * priv,
u8 * bssid, u8 clear_bssid);
extern int libertas_cmd_80211_scan(wlan_private * priv,
struct cmd_ds_command *cmd,
......@@ -199,7 +203,8 @@ extern int libertas_ret_80211_scan(wlan_private * priv,
struct cmd_ds_command *resp);
int wlan_scan_networks(wlan_private * priv,
const struct wlan_ioctl_user_scan_cfg * puserscanin);
const struct wlan_ioctl_user_scan_cfg * puserscanin,
int full_scan);
struct ifreq;
......
......@@ -21,11 +21,11 @@ static inline void wlan_activate_thread(struct wlan_thread * thr)
static inline void wlan_deactivate_thread(struct wlan_thread * thr)
{
ENTER();
lbs_deb_enter(LBS_DEB_THREAD);
thr->pid = 0;
LEAVE();
lbs_deb_leave(LBS_DEB_THREAD);
}
static inline void wlan_create_thread(int (*wlanfunc) (void *),
......@@ -36,7 +36,7 @@ static inline void wlan_create_thread(int (*wlanfunc) (void *),
static inline int wlan_terminate_thread(struct wlan_thread * thr)
{
ENTER();
lbs_deb_enter(LBS_DEB_THREAD);
/* Check if the thread is active or not */
if (!thr->pid) {
......@@ -45,7 +45,7 @@ static inline int wlan_terminate_thread(struct wlan_thread * thr)
}
kthread_stop(thr->task);
LEAVE();
lbs_deb_leave(LBS_DEB_THREAD);
return 0;
}
......
......@@ -5,7 +5,6 @@
#include "hostcmd.h"
#include "radiotap.h"
#include "sbi.h"
#include "decl.h"
#include "defs.h"
#include "dev.h"
......@@ -68,7 +67,7 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb)
u32 new_rate;
u8 *ptr = priv->adapter->tmptxbuf;
ENTER();
lbs_deb_enter(LBS_DEB_TX);
if (priv->adapter->surpriseremoved)
return -1;
......@@ -78,7 +77,7 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb)
min_t(unsigned int, skb->len, 100));
if (!skb->len || (skb->len > MRVDRV_ETH_TX_PACKET_BUFFER_SIZE)) {
lbs_pr_debug(1, "Tx error: Bad skb length %d : %zd\n",
lbs_deb_tx("tx err: skb length %d 0 or > %zd\n",
skb->len, MRVDRV_ETH_TX_PACKET_BUFFER_SIZE);
ret = -1;
goto done;
......@@ -86,13 +85,13 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb)
memset(plocaltxpd, 0, sizeof(struct txpd));
plocaltxpd->tx_packet_length = skb->len;
plocaltxpd->tx_packet_length = cpu_to_le16(skb->len);
/* offset of actual data */
plocaltxpd->tx_packet_location = sizeof(struct txpd);
plocaltxpd->tx_packet_location = cpu_to_le32(sizeof(struct txpd));
/* TxCtrl set by user or default */
plocaltxpd->tx_control = adapter->pkttxctrl;
plocaltxpd->tx_control = cpu_to_le32(adapter->pkttxctrl);
p802x_hdr = skb->data;
if (priv->adapter->radiomode == WLAN_RADIOMODE_RADIOTAP) {
......@@ -103,15 +102,16 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb)
/* set txpd fields from the radiotap header */
new_rate = convert_radiotap_rate_to_mv(pradiotap_hdr->rate);
if (new_rate != 0) {
/* erase tx_control[4:0] */
plocaltxpd->tx_control &= ~0x1f;
/* write new tx_control[4:0] */
plocaltxpd->tx_control |= new_rate;
/* use new tx_control[4:0] */
new_rate |= (adapter->pkttxctrl & ~0x1f);
plocaltxpd->tx_control = cpu_to_le32(new_rate);
}
/* skip the radiotap header */
p802x_hdr += sizeof(struct tx_radiotap_hdr);
plocaltxpd->tx_packet_length -= sizeof(struct tx_radiotap_hdr);
plocaltxpd->tx_packet_length =
cpu_to_le16(le16_to_cpu(plocaltxpd->tx_packet_length)
- sizeof(struct tx_radiotap_hdr));
}
/* copy destination address from 802.3 or 802.11 header */
......@@ -123,28 +123,28 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb)
lbs_dbg_hex("txpd", (u8 *) plocaltxpd, sizeof(struct txpd));
if (IS_MESH_FRAME(skb)) {
plocaltxpd->tx_control |= TxPD_MESH_FRAME;
plocaltxpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME);
}
memcpy(ptr, plocaltxpd, sizeof(struct txpd));
ptr += sizeof(struct txpd);
lbs_dbg_hex("Tx Data", (u8 *) p802x_hdr, plocaltxpd->tx_packet_length);
memcpy(ptr, p802x_hdr, plocaltxpd->tx_packet_length);
ret = libertas_sbi_host_to_card(priv, MVMS_DAT,
lbs_dbg_hex("Tx Data", (u8 *) p802x_hdr, le16_to_cpu(plocaltxpd->tx_packet_length));
memcpy(ptr, p802x_hdr, le16_to_cpu(plocaltxpd->tx_packet_length));
ret = priv->hw_host_to_card(priv, MVMS_DAT,
priv->adapter->tmptxbuf,
plocaltxpd->tx_packet_length +
le16_to_cpu(plocaltxpd->tx_packet_length) +
sizeof(struct txpd));
if (ret) {
lbs_pr_debug(1, "Tx error: libertas_sbi_host_to_card failed: 0x%X\n", ret);
lbs_deb_tx("tx err: hw_host_to_card returned 0x%X\n", ret);
goto done;
}
lbs_pr_debug(1, "SendSinglePacket succeeds\n");
lbs_deb_tx("SendSinglePacket succeeds\n");
done:
done:
if (!ret) {
priv->stats.tx_packets++;
priv->stats.tx_bytes += skb->len;
......@@ -158,7 +158,8 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb)
received from FW */
skb_orphan(skb);
/* stop processing outgoing pkts */
netif_stop_queue(priv->wlan_dev.netdev);
netif_stop_queue(priv->dev);
netif_stop_queue(priv->mesh_dev);
/* freeze any packets already in our queues */
priv->adapter->TxLockFlag = 1;
} else {
......@@ -166,7 +167,7 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb)
priv->adapter->currenttxskb = NULL;
}
LEAVE();
lbs_deb_leave_args(LBS_DEB_TX, "ret %d", ret);
return ret;
}
......@@ -195,10 +196,13 @@ static void wlan_tx_queue(wlan_private *priv, struct sk_buff *skb)
WARN_ON(priv->adapter->tx_queue_idx >= NR_TX_QUEUE);
adapter->tx_queue_ps[adapter->tx_queue_idx++] = skb;
if (adapter->tx_queue_idx == NR_TX_QUEUE)
netif_stop_queue(priv->wlan_dev.netdev);
else
netif_start_queue(priv->wlan_dev.netdev);
if (adapter->tx_queue_idx == NR_TX_QUEUE) {
netif_stop_queue(priv->dev);
netif_stop_queue(priv->mesh_dev);
} else {
netif_start_queue(priv->dev);
netif_start_queue(priv->mesh_dev);
}
spin_unlock(&adapter->txqueue_lock);
}
......@@ -214,13 +218,12 @@ int libertas_process_tx(wlan_private * priv, struct sk_buff *skb)
{
int ret = -1;
ENTER();
lbs_deb_enter(LBS_DEB_TX);
lbs_dbg_hex("TX Data", skb->data, min_t(unsigned int, skb->len, 100));
if (priv->wlan_dev.dnld_sent) {
if (priv->dnld_sent) {
lbs_pr_alert( "TX error: dnld_sent = %d, not sending\n",
priv->wlan_dev.dnld_sent);
priv->dnld_sent);
goto done;
}
......@@ -234,7 +237,7 @@ int libertas_process_tx(wlan_private * priv, struct sk_buff *skb)
ret = SendSinglePacket(priv, skb);
done:
LEAVE();
lbs_deb_leave_args(LBS_DEB_TX, "ret %d", ret);
return ret;
}
......@@ -280,6 +283,9 @@ void libertas_send_tx_feedback(wlan_private * priv)
libertas_upload_rx_packet(priv, adapter->currenttxskb);
adapter->currenttxskb = NULL;
priv->adapter->TxLockFlag = 0;
if (priv->adapter->connect_status == libertas_connected)
netif_wake_queue(priv->wlan_dev.netdev);
if (priv->adapter->connect_status == libertas_connected) {
netif_wake_queue(priv->dev);
netif_wake_queue(priv->mesh_dev);
}
}
EXPORT_SYMBOL_GPL(libertas_send_tx_feedback);
......@@ -5,6 +5,7 @@
#define _WLAN_TYPES_
#include <linux/if_ether.h>
#include <asm/byteorder.h>
/** IEEE type definitions */
enum ieeetypes_elementid {
......@@ -29,9 +30,30 @@ enum ieeetypes_elementid {
EXTRA_IE = 133,
} __attribute__ ((packed));
#ifdef __BIG_ENDIAN
#define CAPINFO_MASK (~(0xda00))
#else
#define CAPINFO_MASK (~(0x00da))
#endif
struct ieeetypes_capinfo {
#ifdef __BIG_ENDIAN_BITFIELD
u8 chanagility:1;
u8 pbcc:1;
u8 shortpreamble:1;
u8 privacy:1;
u8 cfpollrqst:1;
u8 cfpollable:1;
u8 ibss:1;
u8 ess:1;
u8 rsrvd1:2;
u8 dsssofdm:1;
u8 rsvrd2:1;
u8 apsd:1;
u8 shortslottime:1;
u8 rsrvd3:1;
u8 spectrummgmt:1;
#else
u8 ess:1;
u8 ibss:1;
u8 cfpollable:1;
......@@ -47,6 +69,7 @@ struct ieeetypes_capinfo {
u8 rsvrd2:1;
u8 dsssofdm:1;
u8 rsrvd1:2;
#endif
} __attribute__ ((packed));
struct ieeetypes_cfparamset {
......@@ -54,15 +77,15 @@ struct ieeetypes_cfparamset {
u8 len;
u8 cfpcnt;
u8 cfpperiod;
u16 cfpmaxduration;
u16 cfpdurationremaining;
__le16 cfpmaxduration;
__le16 cfpdurationremaining;
} __attribute__ ((packed));
struct ieeetypes_ibssparamset {
u8 elementid;
u8 len;
u16 atimwindow;
__le16 atimwindow;
} __attribute__ ((packed));
union IEEEtypes_ssparamset {
......@@ -73,7 +96,7 @@ union IEEEtypes_ssparamset {
struct ieeetypes_fhparamset {
u8 elementid;
u8 len;
u16 dwelltime;
__le16 dwelltime;
u8 hopset;
u8 hoppattern;
u8 hopindex;
......@@ -92,8 +115,8 @@ union ieeetypes_phyparamset {
struct ieeetypes_assocrsp {
struct ieeetypes_capinfo capability;
u16 statuscode;
u16 aid;
__le16 statuscode;
__le16 aid;
u8 iebuffer[1];
} __attribute__ ((packed));
......@@ -138,8 +161,8 @@ struct ieeetypes_assocrsp {
/** TLV related data structures*/
struct mrvlietypesheader {
u16 type;
u16 len;
__le16 type;
__le16 len;
} __attribute__ ((packed));
struct mrvlietypes_data {
......@@ -164,17 +187,23 @@ struct mrvlietypes_wildcardssidparamset {
} __attribute__ ((packed));
struct chanscanmode {
#ifdef __BIG_ENDIAN_BITFIELD
u8 reserved_2_7:6;
u8 disablechanfilt:1;
u8 passivescan:1;
#else
u8 passivescan:1;
u8 disablechanfilt:1;
u8 reserved_2_7:6;
#endif
} __attribute__ ((packed));
struct chanscanparamset {
u8 radiotype;
u8 channumber;
struct chanscanmode chanscanmode;
u16 minscantime;
u16 maxscantime;
__le16 minscantime;
__le16 maxscantime;
} __attribute__ ((packed));
struct mrvlietypes_chanlistparamset {
......@@ -185,12 +214,12 @@ struct mrvlietypes_chanlistparamset {
struct cfparamset {
u8 cfpcnt;
u8 cfpperiod;
u16 cfpmaxduration;
u16 cfpdurationremaining;
__le16 cfpmaxduration;
__le16 cfpdurationremaining;
} __attribute__ ((packed));
struct ibssparamset {
u16 atimwindow;
__le16 atimwindow;
} __attribute__ ((packed));
struct mrvlietypes_ssparamset {
......@@ -202,7 +231,7 @@ struct mrvlietypes_ssparamset {
} __attribute__ ((packed));
struct fhparamset {
u16 dwelltime;
__le16 dwelltime;
u8 hopset;
u8 hoppattern;
u8 hopindex;
......@@ -263,17 +292,17 @@ struct mrvlietypes_beaconsmissed {
struct mrvlietypes_numprobes {
struct mrvlietypesheader header;
u16 numprobes;
__le16 numprobes;
} __attribute__ ((packed));
struct mrvlietypes_bcastprobe {
struct mrvlietypesheader header;
u16 bcastprobe;
__le16 bcastprobe;
} __attribute__ ((packed));
struct mrvlietypes_numssidprobe {
struct mrvlietypesheader header;
u16 numssidprobe;
__le16 numssidprobe;
} __attribute__ ((packed));
struct led_pin {
......
......@@ -21,6 +21,14 @@
#include "assoc.h"
/**
* 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
*
......@@ -102,8 +110,8 @@ struct chan_freq_power *libertas_find_cfp_by_band_and_channel(wlan_adapter * ada
}
if (!cfp && channel)
lbs_pr_debug(1, "libertas_find_cfp_by_band_and_channel(): cannot find "
"cfp by band %d & channel %d\n", band, channel);
lbs_deb_wext("libertas_find_cfp_by_band_and_channel: can't find "
"cfp by band %d / channel %d\n", band, channel);
return cfp;
}
......@@ -143,113 +151,12 @@ static struct chan_freq_power *find_cfp_by_band_and_freq(wlan_adapter * adapter,
}
if (!cfp && freq)
lbs_pr_debug(1, "find_cfp_by_band_and_freql(): cannot find cfp by "
"band %d & freq %d\n", band, freq);
lbs_deb_wext("find_cfp_by_band_and_freql: can't find cfp by "
"band %d / freq %d\n", band, freq);
return cfp;
}
static int updatecurrentchannel(wlan_private * priv)
{
int ret;
/*
** the channel in f/w could be out of sync, get the current channel
*/
ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_channel,
cmd_opt_802_11_rf_channel_get,
cmd_option_waitforrsp, 0, NULL);
lbs_pr_debug(1, "Current channel = %d\n",
priv->adapter->curbssparams.channel);
return ret;
}
static int setcurrentchannel(wlan_private * priv, int channel)
{
lbs_pr_debug(1, "Set channel = %d\n", channel);
/*
** Current channel is not set to adhocchannel requested, set channel
*/
return (libertas_prepare_and_send_command(priv, cmd_802_11_rf_channel,
cmd_opt_802_11_rf_channel_set,
cmd_option_waitforrsp, 0, &channel));
}
static int changeadhocchannel(wlan_private * priv, int channel)
{
int ret = 0;
wlan_adapter *adapter = priv->adapter;
adapter->adhocchannel = channel;
updatecurrentchannel(priv);
if (adapter->curbssparams.channel == adapter->adhocchannel) {
/* adhocchannel is set to the current channel already */
LEAVE();
return 0;
}
lbs_pr_debug(1, "Updating channel from %d to %d\n",
adapter->curbssparams.channel, adapter->adhocchannel);
setcurrentchannel(priv, adapter->adhocchannel);
updatecurrentchannel(priv);
if (adapter->curbssparams.channel != adapter->adhocchannel) {
lbs_pr_debug(1, "failed to updated channel to %d, channel = %d\n",
adapter->adhocchannel, adapter->curbssparams.channel);
LEAVE();
return -1;
}
if (adapter->connect_status == libertas_connected) {
int i;
struct WLAN_802_11_SSID curadhocssid;
lbs_pr_debug(1, "channel Changed while in an IBSS\n");
/* Copy the current ssid */
memcpy(&curadhocssid, &adapter->curbssparams.ssid,
sizeof(struct WLAN_802_11_SSID));
/* Exit Adhoc mode */
lbs_pr_debug(1, "In changeadhocchannel(): Sending Adhoc Stop\n");
ret = libertas_stop_adhoc_network(priv);
if (ret) {
LEAVE();
return ret;
}
/* Scan for the network, do not save previous results. Stale
* scan data will cause us to join a non-existant adhoc network
*/
libertas_send_specific_SSID_scan(priv, &curadhocssid, 0);
// find out the BSSID that matches the current SSID
i = libertas_find_SSID_in_list(adapter, &curadhocssid, NULL,
IW_MODE_ADHOC);
if (i >= 0) {
lbs_pr_debug(1, "SSID found at %d in List,"
"so join\n", i);
libertas_join_adhoc_network(priv, &adapter->scantable[i]);
} else {
// else send START command
lbs_pr_debug(1, "SSID not found in list, "
"so creating adhoc with ssid = %s\n",
curadhocssid.ssid);
libertas_start_adhoc_network(priv, &curadhocssid);
} // end of else (START command)
}
LEAVE();
return 0;
}
/**
* @brief Set Radio On/OFF
......@@ -263,10 +170,10 @@ int wlan_radio_ioctl(wlan_private * priv, u8 option)
int ret = 0;
wlan_adapter *adapter = priv->adapter;
ENTER();
lbs_deb_enter(LBS_DEB_WEXT);
if (adapter->radioon != option) {
lbs_pr_debug(1, "Switching %s the Radio\n", option ? "On" : "Off");
lbs_deb_wext("switching radio %s\n", option ? "on" : "off");
adapter->radioon = option;
ret = libertas_prepare_and_send_command(priv,
......@@ -275,7 +182,7 @@ int wlan_radio_ioctl(wlan_private * priv, u8 option)
cmd_option_waitforrsp, 0, NULL);
}
LEAVE();
lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
return ret;
}
......@@ -312,15 +219,15 @@ static int get_active_data_rates(wlan_adapter * adapter,
{
int k = 0;
ENTER();
lbs_deb_enter(LBS_DEB_WEXT);
if (adapter->connect_status != libertas_connected) {
if (adapter->mode == IW_MODE_INFRA) {
lbs_pr_debug(1, "Infra\n");
lbs_deb_wext("infra\n");
k = copyrates(rates, k, libertas_supported_rates,
sizeof(libertas_supported_rates));
} else {
lbs_pr_debug(1, "Adhoc G\n");
lbs_deb_wext("Adhoc G\n");
k = copyrates(rates, k, libertas_adhoc_rates_g,
sizeof(libertas_adhoc_rates_g));
}
......@@ -329,8 +236,7 @@ static int get_active_data_rates(wlan_adapter * adapter,
adapter->curbssparams.numofrates);
}
LEAVE();
lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", k);
return k;
}
......@@ -342,7 +248,7 @@ static int wlan_get_name(struct net_device *dev, struct iw_request_info *info,
char mrvl[6] = { "MRVL-" };
int cnt;
ENTER();
lbs_deb_enter(LBS_DEB_WEXT);
strcpy(cwrq, mrvl);
......@@ -360,8 +266,7 @@ static int wlan_get_name(struct net_device *dev, struct iw_request_info *info,
}
*cwrq = '\0';
LEAVE();
lbs_deb_leave(LBS_DEB_WEXT);
return 0;
}
......@@ -372,14 +277,14 @@ static int wlan_get_freq(struct net_device *dev, struct iw_request_info *info,
wlan_adapter *adapter = priv->adapter;
struct chan_freq_power *cfp;
ENTER();
lbs_deb_enter(LBS_DEB_WEXT);
cfp = libertas_find_cfp_by_band_and_channel(adapter, 0,
adapter->curbssparams.channel);
if (!cfp) {
if (adapter->curbssparams.channel)
lbs_pr_debug(1, "Invalid channel=%d\n",
lbs_deb_wext("invalid channel %d\n",
adapter->curbssparams.channel);
return -EINVAL;
}
......@@ -387,9 +292,8 @@ static int wlan_get_freq(struct net_device *dev, struct iw_request_info *info,
fwrq->m = (long)cfp->freq * 100000;
fwrq->e = 1;
lbs_pr_debug(1, "freq=%u\n", fwrq->m);
LEAVE();
lbs_deb_wext("freq %u\n", fwrq->m);
lbs_deb_leave(LBS_DEB_WEXT);
return 0;
}
......@@ -399,7 +303,7 @@ static int wlan_get_wap(struct net_device *dev, struct iw_request_info *info,
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
ENTER();
lbs_deb_enter(LBS_DEB_WEXT);
if (adapter->connect_status == libertas_connected) {
memcpy(awrq->sa_data, adapter->curbssparams.bssid, ETH_ALEN);
......@@ -408,7 +312,7 @@ static int wlan_get_wap(struct net_device *dev, struct iw_request_info *info,
}
awrq->sa_family = ARPHRD_ETHER;
LEAVE();
lbs_deb_leave(LBS_DEB_WEXT);
return 0;
}
......@@ -418,7 +322,7 @@ static int wlan_set_nick(struct net_device *dev, struct iw_request_info *info,
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
ENTER();
lbs_deb_enter(LBS_DEB_WEXT);
/*
* Check the size of the string
......@@ -433,7 +337,7 @@ static int wlan_set_nick(struct net_device *dev, struct iw_request_info *info,
memcpy(adapter->nodename, extra, dwrq->length);
mutex_unlock(&adapter->lock);
LEAVE();
lbs_deb_leave(LBS_DEB_WEXT);
return 0;
}
......@@ -443,7 +347,7 @@ static int wlan_get_nick(struct net_device *dev, struct iw_request_info *info,
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
ENTER();
lbs_deb_enter(LBS_DEB_WEXT);
/*
* Get the Nick Name saved
......@@ -464,19 +368,43 @@ static int wlan_get_nick(struct net_device *dev, struct iw_request_info *info,
*/
dwrq->length = strlen(extra) + 1;
LEAVE();
lbs_deb_leave(LBS_DEB_WEXT);
return 0;
}
static int mesh_get_nick(struct net_device *dev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
{
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
lbs_deb_enter(LBS_DEB_WEXT);
/* Use nickname to indicate that mesh is on */
if (adapter->connect_status == libertas_connected) {
strncpy(extra, "Mesh", 12);
extra[12] = '\0';
dwrq->length = strlen(extra) + 1;
}
else {
extra[0] = '\0';
dwrq->length = 1 ;
}
lbs_deb_leave(LBS_DEB_WEXT);
return 0;
}
static int wlan_set_rts(struct net_device *dev, struct iw_request_info *info,
struct iw_param *vwrq, char *extra)
{
int ret = 0;
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
int rthr = vwrq->value;
u32 rthr = vwrq->value;
ENTER();
lbs_deb_enter(LBS_DEB_WEXT);
if (vwrq->disabled) {
adapter->rtsthsd = rthr = MRVDRV_RTS_MAX_VALUE;
......@@ -490,7 +418,7 @@ static int wlan_set_rts(struct net_device *dev, struct iw_request_info *info,
cmd_act_set, cmd_option_waitforrsp,
OID_802_11_RTS_THRESHOLD, &rthr);
LEAVE();
lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
return ret;
}
......@@ -501,35 +429,34 @@ static int wlan_get_rts(struct net_device *dev, struct iw_request_info *info,
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
ENTER();
lbs_deb_enter(LBS_DEB_WEXT);
adapter->rtsthsd = 0;
ret = libertas_prepare_and_send_command(priv, cmd_802_11_snmp_mib,
cmd_act_get, cmd_option_waitforrsp,
OID_802_11_RTS_THRESHOLD, NULL);
if (ret) {
LEAVE();
return ret;
}
if (ret)
goto out;
vwrq->value = adapter->rtsthsd;
vwrq->disabled = ((vwrq->value < MRVDRV_RTS_MIN_VALUE)
|| (vwrq->value > MRVDRV_RTS_MAX_VALUE));
vwrq->fixed = 1;
LEAVE();
return 0;
out:
lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
return ret;
}
static int wlan_set_frag(struct net_device *dev, struct iw_request_info *info,
struct iw_param *vwrq, char *extra)
{
int ret = 0;
int fthr = vwrq->value;
u32 fthr = vwrq->value;
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
ENTER();
lbs_deb_enter(LBS_DEB_WEXT);
if (vwrq->disabled) {
adapter->fragthsd = fthr = MRVDRV_FRAG_MAX_VALUE;
......@@ -543,7 +470,8 @@ static int wlan_set_frag(struct net_device *dev, struct iw_request_info *info,
ret = libertas_prepare_and_send_command(priv, cmd_802_11_snmp_mib,
cmd_act_set, cmd_option_waitforrsp,
OID_802_11_FRAGMENTATION_THRESHOLD, &fthr);
LEAVE();
lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
return ret;
}
......@@ -554,24 +482,23 @@ static int wlan_get_frag(struct net_device *dev, struct iw_request_info *info,
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
ENTER();
lbs_deb_enter(LBS_DEB_WEXT);
adapter->fragthsd = 0;
ret = libertas_prepare_and_send_command(priv,
cmd_802_11_snmp_mib,
cmd_act_get, cmd_option_waitforrsp,
OID_802_11_FRAGMENTATION_THRESHOLD, NULL);
if (ret) {
LEAVE();
return ret;
}
if (ret)
goto out;
vwrq->value = adapter->fragthsd;
vwrq->disabled = ((vwrq->value < MRVDRV_FRAG_MIN_VALUE)
|| (vwrq->value > MRVDRV_FRAG_MAX_VALUE));
vwrq->fixed = 1;
LEAVE();
out:
lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
return ret;
}
......@@ -581,11 +508,23 @@ static int wlan_get_mode(struct net_device *dev,
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
ENTER();
lbs_deb_enter(LBS_DEB_WEXT);
*uwrq = adapter->mode;
LEAVE();
lbs_deb_leave(LBS_DEB_WEXT);
return 0;
}
static int mesh_wlan_get_mode(struct net_device *dev,
struct iw_request_info *info, u32 * uwrq,
char *extra)
{
lbs_deb_enter(LBS_DEB_WEXT);
*uwrq = IW_MODE_REPEAT ;
lbs_deb_leave(LBS_DEB_WEXT);
return 0;
}
......@@ -597,19 +536,17 @@ static int wlan_get_txpow(struct net_device *dev,
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
ENTER();
lbs_deb_enter(LBS_DEB_WEXT);
ret = libertas_prepare_and_send_command(priv,
cmd_802_11_rf_tx_power,
cmd_act_tx_power_opt_get,
cmd_option_waitforrsp, 0, NULL);
if (ret) {
LEAVE();
return ret;
}
if (ret)
goto out;
lbs_pr_debug(1, "TXPOWER GET %d dbm.\n", adapter->txpowerlevel);
lbs_deb_wext("tx power level %d dbm\n", adapter->txpowerlevel);
vwrq->value = adapter->txpowerlevel;
vwrq->fixed = 1;
if (adapter->radioon) {
......@@ -619,8 +556,9 @@ static int wlan_get_txpow(struct net_device *dev,
vwrq->disabled = 1;
}
LEAVE();
return 0;
out:
lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
return ret;
}
static int wlan_set_retry(struct net_device *dev, struct iw_request_info *info,
......@@ -630,7 +568,7 @@ static int wlan_set_retry(struct net_device *dev, struct iw_request_info *info,
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
ENTER();
lbs_deb_enter(LBS_DEB_WEXT);
if (vwrq->flags == IW_RETRY_LIMIT) {
/* The MAC has a 4-bit Total_Tx_Count register
......@@ -648,16 +586,15 @@ static int wlan_set_retry(struct net_device *dev, struct iw_request_info *info,
cmd_option_waitforrsp,
OID_802_11_TX_RETRYCOUNT, NULL);
if (ret) {
LEAVE();
return ret;
}
if (ret)
goto out;
} else {
return -EOPNOTSUPP;
}
LEAVE();
return 0;
out:
lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
return ret;
}
static int wlan_get_retry(struct net_device *dev, struct iw_request_info *info,
......@@ -667,16 +604,16 @@ static int wlan_get_retry(struct net_device *dev, struct iw_request_info *info,
wlan_adapter *adapter = priv->adapter;
int ret = 0;
ENTER();
lbs_deb_enter(LBS_DEB_WEXT);
adapter->txretrycount = 0;
ret = libertas_prepare_and_send_command(priv,
cmd_802_11_snmp_mib,
cmd_act_get, cmd_option_waitforrsp,
OID_802_11_TX_RETRYCOUNT, NULL);
if (ret) {
LEAVE();
return ret;
}
if (ret)
goto out;
vwrq->disabled = 0;
if (!vwrq->flags) {
vwrq->flags = IW_RETRY_LIMIT;
......@@ -684,8 +621,9 @@ static int wlan_get_retry(struct net_device *dev, struct iw_request_info *info,
vwrq->value = adapter->txretrycount - 1;
}
LEAVE();
return 0;
out:
lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
return ret;
}
static inline void sort_channels(struct iw_freq *freq, int num)
......@@ -739,7 +677,7 @@ static int wlan_get_range(struct net_device *dev, struct iw_request_info *info,
u8 flag = 0;
ENTER();
lbs_deb_enter(LBS_DEB_WEXT);
dwrq->length = sizeof(struct iw_range);
memset(range, 0, sizeof(struct iw_range));
......@@ -755,7 +693,7 @@ static int wlan_get_range(struct net_device *dev, struct iw_request_info *info,
range->bitrate[i] = (rates[i] & 0x7f) * 500000;
}
range->num_bitrates = i;
lbs_pr_debug(1, "IW_MAX_BITRATES=%d num_bitrates=%d\n", IW_MAX_BITRATES,
lbs_deb_wext("IW_MAX_BITRATES %d, num_bitrates %d\n", IW_MAX_BITRATES,
range->num_bitrates);
range->num_frequency = 0;
......@@ -768,18 +706,17 @@ static int wlan_get_range(struct net_device *dev, struct iw_request_info *info,
&adapter->parsed_region_chan;
if (parsed_region_chan == NULL) {
lbs_pr_debug(1, "11D:parsed_region_chan is NULL\n");
LEAVE();
return 0;
lbs_deb_wext("11d: parsed_region_chan is NULL\n");
goto out;
}
band = parsed_region_chan->band;
lbs_pr_debug(1, "band=%d NoOfChan=%d\n", band,
lbs_deb_wext("band %d, nr_char %d\n", band,
parsed_region_chan->nr_chan);
for (i = 0; (range->num_frequency < IW_MAX_FREQUENCIES)
&& (i < parsed_region_chan->nr_chan); i++) {
chan_no = parsed_region_chan->chanpwr[i].chan;
lbs_pr_debug(1, "chan_no=%d\n", chan_no);
lbs_deb_wext("chan_no %d\n", chan_no);
range->freq[range->num_frequency].i = (long)chan_no;
range->freq[range->num_frequency].m =
(long)libertas_chan_2_freq(chan_no, band) * 100000;
......@@ -808,7 +745,7 @@ static int wlan_get_range(struct net_device *dev, struct iw_request_info *info,
}
}
lbs_pr_debug(1, "IW_MAX_FREQUENCIES=%d num_frequency=%d\n",
lbs_deb_wext("IW_MAX_FREQUENCIES %d, num_frequency %d\n",
IW_MAX_FREQUENCIES, range->num_frequency);
range->num_channels = range->num_frequency;
......@@ -903,7 +840,8 @@ static int wlan_get_range(struct net_device *dev, struct iw_request_info *info,
| IW_ENC_CAPA_CIPHER_CCMP;
}
LEAVE();
out:
lbs_deb_leave(LBS_DEB_WEXT);
return 0;
}
......@@ -913,7 +851,7 @@ static int wlan_set_power(struct net_device *dev, struct iw_request_info *info,
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
ENTER();
lbs_deb_enter(LBS_DEB_WEXT);
/* PS is currently supported only in Infrastructure mode
* Remove this check if it is to be supported in IBSS mode also
......@@ -929,11 +867,11 @@ static int wlan_set_power(struct net_device *dev, struct iw_request_info *info,
}
if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
lbs_pr_debug(1,
"Setting power timeout command is not supported\n");
lbs_deb_wext(
"setting power timeout is not supported\n");
return -EINVAL;
} else if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {
lbs_pr_debug(1, "Setting power period command is not supported\n");
lbs_deb_wext("setting power period not supported\n");
return -EINVAL;
}
......@@ -947,7 +885,7 @@ static int wlan_set_power(struct net_device *dev, struct iw_request_info *info,
libertas_ps_sleep(priv, cmd_option_waitforrsp);
}
LEAVE();
lbs_deb_leave(LBS_DEB_WEXT);
return 0;
}
......@@ -958,19 +896,20 @@ static int wlan_get_power(struct net_device *dev, struct iw_request_info *info,
wlan_adapter *adapter = priv->adapter;
int mode;
ENTER();
lbs_deb_enter(LBS_DEB_WEXT);
mode = adapter->psmode;
if ((vwrq->disabled = (mode == wlan802_11powermodecam))
|| adapter->connect_status == libertas_disconnected) {
LEAVE();
return 0;
|| adapter->connect_status == libertas_disconnected)
{
goto out;
}
vwrq->value = 0;
LEAVE();
out:
lbs_deb_leave(LBS_DEB_WEXT);
return 0;
}
......@@ -1063,6 +1002,16 @@ static const struct iw_priv_args wlan_private_args[] = {
IW_PRIV_TYPE_CHAR | 128,
IW_PRIV_TYPE_CHAR | 128,
"bt_list"},
{
WLAN_SUBCMD_BT_SET_INVERT,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
IW_PRIV_TYPE_NONE,
"bt_set_invert"},
{
WLAN_SUBCMD_BT_GET_INVERT,
IW_PRIV_TYPE_NONE,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
"bt_get_invert"},
/* FWT Management */
{
WLAN_SUBCMD_FWT_ADD,
......@@ -1125,7 +1074,7 @@ static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev)
u8 rssi;
u32 tx_retries;
ENTER();
lbs_deb_enter(LBS_DEB_WEXT);
priv->wstats.status = adapter->mode;
......@@ -1145,8 +1094,8 @@ static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev)
CAL_NF(adapter->NF[TYPE_BEACON][TYPE_NOAVG]);
}
lbs_pr_debug(1, "Signal Level = %#x\n", priv->wstats.qual.level);
lbs_pr_debug(1, "Noise = %#x\n", priv->wstats.qual.noise);
lbs_deb_wext("signal level %#x\n", priv->wstats.qual.level);
lbs_deb_wext("noise %#x\n", priv->wstats.qual.noise);
rssi = priv->wstats.qual.level - priv->wstats.qual.noise;
if (rssi < 15)
......@@ -1166,7 +1115,7 @@ static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev)
/* Quality by TX errors */
priv->wstats.discard.retries = priv->stats.tx_errors;
tx_retries = adapter->logmsg.retry;
tx_retries = le16_to_cpu(adapter->logmsg.retry);
if (tx_retries > 75)
tx_qual = (90 - tx_retries) * POOR / 15;
......@@ -1182,10 +1131,10 @@ static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev)
(PERFECT - VERY_GOOD) / 50 + VERY_GOOD;
quality = min(quality, tx_qual);
priv->wstats.discard.code = adapter->logmsg.wepundecryptable;
priv->wstats.discard.fragment = adapter->logmsg.fcserror;
priv->wstats.discard.code = le16_to_cpu(adapter->logmsg.wepundecryptable);
priv->wstats.discard.fragment = le16_to_cpu(adapter->logmsg.rxfrag);
priv->wstats.discard.retries = tx_retries;
priv->wstats.discard.misc = adapter->logmsg.ackfailure;
priv->wstats.discard.misc = le16_to_cpu(adapter->logmsg.ackfailure);
/* Calculate quality */
priv->wstats.qual.qual = max(quality, (u32)100);
......@@ -1209,7 +1158,7 @@ static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev)
IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID;
}
LEAVE ();
lbs_deb_leave(LBS_DEB_WEXT);
return &priv->wstats;
......@@ -1218,81 +1167,59 @@ static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev)
static int wlan_set_freq(struct net_device *dev, struct iw_request_info *info,
struct iw_freq *fwrq, char *extra)
{
int ret = 0;
int ret = -EINVAL;
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
int rc = -EINPROGRESS; /* Call commit handler */
struct chan_freq_power *cfp;
struct assoc_request * assoc_req;
ENTER();
lbs_deb_enter(LBS_DEB_WEXT);
/*
* If setting by frequency, convert to a channel
*/
if (fwrq->e == 1) {
mutex_lock(&adapter->lock);
assoc_req = wlan_get_association_request(adapter);
if (!assoc_req) {
ret = -ENOMEM;
goto out;
}
/* If setting by frequency, convert to a channel */
if (fwrq->e == 1) {
long f = fwrq->m / 100000;
int c = 0;
cfp = find_cfp_by_band_and_freq(adapter, 0, f);
if (!cfp) {
lbs_pr_debug(1, "Invalid freq=%ld\n", f);
return -EINVAL;
lbs_deb_wext("invalid freq %ld\n", f);
goto out;
}
c = (int)cfp->channel;
if (c < 0)
return -EINVAL;
fwrq->e = 0;
fwrq->m = c;
fwrq->m = (int) cfp->channel;
}
/*
* Setting by channel number
*/
/* Setting by channel number */
if (fwrq->m > 1000 || fwrq->e > 0) {
rc = -EOPNOTSUPP;
} else {
int channel = fwrq->m;
goto out;
}
cfp = libertas_find_cfp_by_band_and_channel(adapter, 0, channel);
cfp = libertas_find_cfp_by_band_and_channel(adapter, 0, fwrq->m);
if (!cfp) {
rc = -EINVAL;
} else {
if (adapter->mode == IW_MODE_ADHOC) {
rc = changeadhocchannel(priv, channel);
/* If station is WEP enabled, send the
* command to set WEP in firmware
*/
if (adapter->secinfo.wep_enabled) {
lbs_pr_debug(1, "set_freq: WEP enabled\n");
ret = libertas_prepare_and_send_command(priv,
cmd_802_11_set_wep,
cmd_act_add,
cmd_option_waitforrsp,
0,
NULL);
if (ret) {
LEAVE();
return ret;
goto out;
}
adapter->currentpacketfilter |=
cmd_act_mac_wep_enable;
assoc_req->channel = fwrq->m;
ret = 0;
libertas_set_mac_packet_filter(priv);
}
out:
if (ret == 0) {
set_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags);
wlan_postpone_association_work(priv);
} else {
rc = -EOPNOTSUPP;
}
}
wlan_cancel_association_work(priv);
}
mutex_unlock(&adapter->lock);
LEAVE();
return rc;
lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
return ret;
}
/**
......@@ -1338,9 +1265,9 @@ static int wlan_set_rate(struct net_device *dev, struct iw_request_info *info,
u8 rates[WLAN_SUPPORTED_RATES];
u8 *rate;
ENTER();
lbs_deb_enter(LBS_DEB_WEXT);
lbs_pr_debug(1, "Vwrq->value = %d\n", vwrq->value);
lbs_deb_wext("vwrq->value %d\n", vwrq->value);
if (vwrq->value == -1) {
action = cmd_act_set_tx_auto; // Auto
......@@ -1357,15 +1284,15 @@ static int wlan_set_rate(struct net_device *dev, struct iw_request_info *info,
get_active_data_rates(adapter, rates);
rate = rates;
while (*rate) {
lbs_pr_debug(1, "Rate=0x%X Wanted=0x%X\n", *rate,
lbs_deb_wext("rate=0x%X, wanted data_rate 0x%X\n", *rate,
data_rate);
if ((*rate & 0x7f) == (data_rate & 0x7f))
break;
rate++;
}
if (!*rate) {
lbs_pr_alert( "The fixed data rate 0x%X is out "
"of range.\n", data_rate);
lbs_pr_alert("fixed data rate 0x%X out "
"of range\n", data_rate);
return -EINVAL;
}
......@@ -1377,7 +1304,7 @@ static int wlan_set_rate(struct net_device *dev, struct iw_request_info *info,
ret = libertas_prepare_and_send_command(priv, cmd_802_11_data_rate,
action, cmd_option_waitforrsp, 0, NULL);
LEAVE();
lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
return ret;
}
......@@ -1387,7 +1314,7 @@ static int wlan_get_rate(struct net_device *dev, struct iw_request_info *info,
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
ENTER();
lbs_deb_enter(LBS_DEB_WEXT);
if (adapter->is_datarate_auto) {
vwrq->fixed = 0;
......@@ -1397,7 +1324,7 @@ static int wlan_get_rate(struct net_device *dev, struct iw_request_info *info,
vwrq->value = adapter->datarate * 500000;
LEAVE();
lbs_deb_leave(LBS_DEB_WEXT);
return 0;
}
......@@ -1409,12 +1336,12 @@ static int wlan_set_mode(struct net_device *dev,
wlan_adapter *adapter = priv->adapter;
struct assoc_request * assoc_req;
ENTER();
lbs_deb_enter(LBS_DEB_WEXT);
if ( (*uwrq != IW_MODE_ADHOC)
&& (*uwrq != IW_MODE_INFRA)
&& (*uwrq != IW_MODE_AUTO)) {
lbs_pr_debug(1, "Invalid mode: 0x%x\n", *uwrq);
lbs_deb_wext("Invalid mode: 0x%x\n", *uwrq);
ret = -EINVAL;
goto out;
}
......@@ -1428,12 +1355,12 @@ static int wlan_set_mode(struct net_device *dev,
assoc_req->mode = *uwrq;
set_bit(ASSOC_FLAG_MODE, &assoc_req->flags);
wlan_postpone_association_work(priv);
lbs_pr_debug(1, "Switching to mode: 0x%x\n", *uwrq);
lbs_deb_wext("Switching to mode: 0x%x\n", *uwrq);
}
mutex_unlock(&adapter->lock);
out:
LEAVE();
lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
return ret;
}
......@@ -1455,9 +1382,9 @@ static int wlan_get_encode(struct net_device *dev,
wlan_adapter *adapter = priv->adapter;
int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
ENTER();
lbs_deb_enter(LBS_DEB_WEXT);
lbs_pr_debug(1, "flags=0x%x index=%d length=%d wep_tx_keyidx=%d\n",
lbs_deb_wext("flags 0x%x, index %d, length %d, wep_tx_keyidx %d\n",
dwrq->flags, index, dwrq->length, adapter->wep_tx_keyidx);
dwrq->flags = 0;
......@@ -1513,13 +1440,13 @@ static int wlan_get_encode(struct net_device *dev,
dwrq->flags |= IW_ENCODE_NOKEY;
lbs_pr_debug(1, "key:%02x:%02x:%02x:%02x:%02x:%02x keylen=%d\n",
lbs_deb_wext("key: " MAC_FMT ", keylen %d\n",
extra[0], extra[1], extra[2],
extra[3], extra[4], extra[5], dwrq->length);
lbs_pr_debug(1, "Return flags=0x%x\n", dwrq->flags);
lbs_deb_wext("return flags 0x%x\n", dwrq->flags);
LEAVE();
lbs_deb_leave(LBS_DEB_WEXT);
return 0;
}
......@@ -1539,20 +1466,21 @@ static int wlan_set_wep_key(struct assoc_request *assoc_req,
u16 index,
int set_tx_key)
{
int ret = 0;
struct WLAN_802_11_KEY *pkey;
ENTER();
lbs_deb_enter(LBS_DEB_WEXT);
/* Paranoid validation of key index */
if (index > 3) {
LEAVE();
return -EINVAL;
ret = -EINVAL;
goto out;
}
/* validate max key length */
if (key_length > KEY_LEN_WEP_104) {
LEAVE();
return -EINVAL;
ret = -EINVAL;
goto out;
}
pkey = &assoc_req->wep_keys[index];
......@@ -1570,17 +1498,18 @@ static int wlan_set_wep_key(struct assoc_request *assoc_req,
if (set_tx_key) {
/* Ensure the chosen key is valid */
if (!pkey->len) {
lbs_pr_debug(1, "key not set, so cannot enable it\n");
LEAVE();
return -EINVAL;
lbs_deb_wext("key not set, so cannot enable it\n");
ret = -EINVAL;
goto out;
}
assoc_req->wep_tx_keyidx = index;
}
assoc_req->secinfo.wep_enabled = 1;
LEAVE();
return 0;
out:
lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
return ret;
}
static int validate_key_index(u16 def_index, u16 raw_index,
......@@ -1605,6 +1534,8 @@ static void disable_wep(struct assoc_request *assoc_req)
{
int i;
lbs_deb_enter(LBS_DEB_WEXT);
/* Set Open System auth mode */
assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
......@@ -1615,6 +1546,27 @@ static void disable_wep(struct assoc_request *assoc_req)
set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags);
set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags);
lbs_deb_leave(LBS_DEB_WEXT);
}
static void disable_wpa(struct assoc_request *assoc_req)
{
lbs_deb_enter(LBS_DEB_WEXT);
memset(&assoc_req->wpa_mcast_key, 0, sizeof (struct WLAN_802_11_KEY));
assoc_req->wpa_mcast_key.flags = KEY_INFO_WPA_MCAST;
set_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags);
memset(&assoc_req->wpa_unicast_key, 0, sizeof (struct WLAN_802_11_KEY));
assoc_req->wpa_unicast_key.flags = KEY_INFO_WPA_UNICAST;
set_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags);
assoc_req->secinfo.WPAenabled = 0;
assoc_req->secinfo.WPA2enabled = 0;
set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags);
lbs_deb_leave(LBS_DEB_WEXT);
}
/**
......@@ -1636,7 +1588,7 @@ static int wlan_set_encode(struct net_device *dev,
struct assoc_request * assoc_req;
u16 is_default = 0, index = 0, set_tx_key = 0;
ENTER();
lbs_deb_enter(LBS_DEB_WEXT);
mutex_lock(&adapter->lock);
assoc_req = wlan_get_association_request(adapter);
......@@ -1647,6 +1599,7 @@ static int wlan_set_encode(struct net_device *dev,
if (dwrq->flags & IW_ENCODE_DISABLED) {
disable_wep (assoc_req);
disable_wpa (assoc_req);
goto out;
}
......@@ -1688,7 +1641,7 @@ static int wlan_set_encode(struct net_device *dev,
}
mutex_unlock(&adapter->lock);
LEAVE();
lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
return ret;
}
......@@ -1712,7 +1665,7 @@ static int wlan_get_encodeext(struct net_device *dev,
struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
int index, max_key_len;
ENTER();
lbs_deb_enter(LBS_DEB_WEXT);
max_key_len = dwrq->length - sizeof(*ext);
if (max_key_len < 0)
......@@ -1748,6 +1701,7 @@ static int wlan_get_encodeext(struct net_device *dev,
if ( adapter->secinfo.wep_enabled
&& !adapter->secinfo.WPAenabled
&& !adapter->secinfo.WPA2enabled) {
/* WEP */
ext->alg = IW_ENCODE_ALG_WEP;
ext->key_len = adapter->wep_keys[index].len;
key = &adapter->wep_keys[index].key[0];
......@@ -1755,8 +1709,27 @@ static int wlan_get_encodeext(struct net_device *dev,
&& (adapter->secinfo.WPAenabled ||
adapter->secinfo.WPA2enabled)) {
/* WPA */
struct WLAN_802_11_KEY * pkey = NULL;
if ( adapter->wpa_mcast_key.len
&& (adapter->wpa_mcast_key.flags & KEY_INFO_WPA_ENABLED))
pkey = &adapter->wpa_mcast_key;
else if ( adapter->wpa_unicast_key.len
&& (adapter->wpa_unicast_key.flags & KEY_INFO_WPA_ENABLED))
pkey = &adapter->wpa_unicast_key;
if (pkey) {
if (pkey->type == KEY_TYPE_ID_AES) {
ext->alg = IW_ENCODE_ALG_CCMP;
} else {
ext->alg = IW_ENCODE_ALG_TKIP;
}
ext->key_len = pkey->len;
key = &pkey->key[0];
} else {
ext->alg = IW_ENCODE_ALG_TKIP;
ext->key_len = 0;
}
} else {
goto out;
}
......@@ -1775,7 +1748,7 @@ static int wlan_get_encodeext(struct net_device *dev,
ret = 0;
out:
LEAVE();
lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
return ret;
}
......@@ -1800,7 +1773,7 @@ static int wlan_set_encodeext(struct net_device *dev,
int alg = ext->alg;
struct assoc_request * assoc_req;
ENTER();
lbs_deb_enter(LBS_DEB_WEXT);
mutex_lock(&adapter->lock);
assoc_req = wlan_get_association_request(adapter);
......@@ -1811,6 +1784,7 @@ static int wlan_set_encodeext(struct net_device *dev,
if ((alg == IW_ENCODE_ALG_NONE) || (dwrq->flags & IW_ENCODE_DISABLED)) {
disable_wep (assoc_req);
disable_wpa (assoc_req);
} else if (alg == IW_ENCODE_ALG_WEP) {
u16 is_default = 0, index, set_tx_key = 0;
......@@ -1846,7 +1820,6 @@ static int wlan_set_encodeext(struct net_device *dev,
set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags);
if (set_tx_key)
set_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags);
} else if ((alg == IW_ENCODE_ALG_TKIP) || (alg == IW_ENCODE_ALG_CCMP)) {
struct WLAN_802_11_KEY * pkey;
......@@ -1855,36 +1828,43 @@ static int wlan_set_encodeext(struct net_device *dev,
&& (ext->key_len != KEY_LEN_WPA_TKIP))
|| ((alg == IW_ENCODE_ALG_CCMP)
&& (ext->key_len != KEY_LEN_WPA_AES))) {
lbs_pr_debug(1, "Invalid size %d for key of alg"
"type %d.\n",
lbs_deb_wext("invalid size %d for key of alg"
"type %d\n",
ext->key_len,
alg);
ret = -EINVAL;
goto out;
}
if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
pkey = &assoc_req->wpa_mcast_key;
else
set_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags);
} else {
pkey = &assoc_req->wpa_unicast_key;
set_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags);
}
memset(pkey, 0, sizeof (struct WLAN_802_11_KEY));
memcpy(pkey->key, ext->key, ext->key_len);
pkey->len = ext->key_len;
pkey->flags = KEY_INFO_WPA_ENABLED;
if (pkey->len)
pkey->flags |= KEY_INFO_WPA_ENABLED;
/* Do this after zeroing key structure */
if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
pkey->flags |= KEY_INFO_WPA_MCAST;
set_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags);
} else {
pkey->flags |= KEY_INFO_WPA_UNICAST;
set_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags);
}
if (alg == IW_ENCODE_ALG_TKIP)
if (alg == IW_ENCODE_ALG_TKIP) {
pkey->type = KEY_TYPE_ID_TKIP;
else if (alg == IW_ENCODE_ALG_CCMP)
} else if (alg == IW_ENCODE_ALG_CCMP) {
pkey->type = KEY_TYPE_ID_AES;
} else {
ret = -EINVAL;
goto out;
}
/* If WPA isn't enabled yet, do that now */
if ( assoc_req->secinfo.WPAenabled == 0
......@@ -1905,7 +1885,7 @@ static int wlan_set_encodeext(struct net_device *dev,
}
mutex_unlock(&adapter->lock);
LEAVE();
lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
return ret;
}
......@@ -1920,7 +1900,7 @@ static int wlan_set_genie(struct net_device *dev,
int ret = 0;
struct assoc_request * assoc_req;
ENTER();
lbs_deb_enter(LBS_DEB_WEXT);
mutex_lock(&adapter->lock);
assoc_req = wlan_get_association_request(adapter);
......@@ -1952,7 +1932,7 @@ static int wlan_set_genie(struct net_device *dev,
}
mutex_unlock(&adapter->lock);
LEAVE();
lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
return ret;
}
......@@ -1961,27 +1941,28 @@ static int wlan_get_genie(struct net_device *dev,
struct iw_point *dwrq,
char *extra)
{
int ret = 0;
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
ENTER();
lbs_deb_enter(LBS_DEB_WEXT);
if (adapter->wpa_ie_len == 0) {
dwrq->length = 0;
LEAVE();
return 0;
goto out;
}
if (dwrq->length < adapter->wpa_ie_len) {
LEAVE();
return -E2BIG;
ret = -E2BIG;
goto out;
}
dwrq->length = adapter->wpa_ie_len;
memcpy(extra, &adapter->wpa_ie[0], adapter->wpa_ie_len);
LEAVE();
return 0;
out:
lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
return ret;
}
......@@ -1996,7 +1977,7 @@ static int wlan_set_auth(struct net_device *dev,
int ret = 0;
int updated = 0;
ENTER();
lbs_deb_enter(LBS_DEB_WEXT);
mutex_lock(&adapter->lock);
assoc_req = wlan_get_association_request(adapter);
......@@ -2010,6 +1991,7 @@ static int wlan_set_auth(struct net_device *dev,
case IW_AUTH_CIPHER_PAIRWISE:
case IW_AUTH_CIPHER_GROUP:
case IW_AUTH_KEY_MGMT:
case IW_AUTH_DROP_UNENCRYPTED:
/*
* libertas does not use these parameters
*/
......@@ -2019,6 +2001,7 @@ static int wlan_set_auth(struct net_device *dev,
if (dwrq->value & IW_AUTH_WPA_VERSION_DISABLED) {
assoc_req->secinfo.WPAenabled = 0;
assoc_req->secinfo.WPA2enabled = 0;
disable_wpa (assoc_req);
}
if (dwrq->value & IW_AUTH_WPA_VERSION_WPA) {
assoc_req->secinfo.WPAenabled = 1;
......@@ -2033,17 +2016,6 @@ static int wlan_set_auth(struct net_device *dev,
updated = 1;
break;
case IW_AUTH_DROP_UNENCRYPTED:
if (dwrq->value) {
adapter->currentpacketfilter |=
cmd_act_mac_strict_protection_enable;
} else {
adapter->currentpacketfilter &=
~cmd_act_mac_strict_protection_enable;
}
updated = 1;
break;
case IW_AUTH_80211_AUTH_ALG:
if (dwrq->value & IW_AUTH_ALG_SHARED_KEY) {
assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY;
......@@ -2069,6 +2041,7 @@ static int wlan_set_auth(struct net_device *dev,
} else {
assoc_req->secinfo.WPAenabled = 0;
assoc_req->secinfo.WPA2enabled = 0;
disable_wpa (assoc_req);
}
updated = 1;
break;
......@@ -2088,7 +2061,7 @@ static int wlan_set_auth(struct net_device *dev,
}
mutex_unlock(&adapter->lock);
LEAVE();
lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
return ret;
}
......@@ -2097,10 +2070,11 @@ static int wlan_get_auth(struct net_device *dev,
struct iw_param *dwrq,
char *extra)
{
int ret = 0;
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
ENTER();
lbs_deb_enter(LBS_DEB_WEXT);
switch (dwrq->flags & IW_AUTH_INDEX) {
case IW_AUTH_WPA_VERSION:
......@@ -2113,13 +2087,6 @@ static int wlan_get_auth(struct net_device *dev,
dwrq->value |= IW_AUTH_WPA_VERSION_DISABLED;
break;
case IW_AUTH_DROP_UNENCRYPTED:
dwrq->value = 0;
if (adapter->currentpacketfilter &
cmd_act_mac_strict_protection_enable)
dwrq->value = 1;
break;
case IW_AUTH_80211_AUTH_ALG:
dwrq->value = adapter->secinfo.auth_mode;
break;
......@@ -2130,12 +2097,11 @@ static int wlan_get_auth(struct net_device *dev,
break;
default:
LEAVE();
return -EOPNOTSUPP;
ret = -EOPNOTSUPP;
}
LEAVE();
return 0;
lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
return ret;
}
......@@ -2148,7 +2114,7 @@ static int wlan_set_txpow(struct net_device *dev, struct iw_request_info *info,
u16 dbm;
ENTER();
lbs_deb_enter(LBS_DEB_WEXT);
if (vwrq->disabled) {
wlan_radio_ioctl(priv, RADIO_OFF);
......@@ -2169,14 +2135,14 @@ static int wlan_set_txpow(struct net_device *dev, struct iw_request_info *info,
if (vwrq->fixed == 0)
dbm = 0xffff;
lbs_pr_debug(1, "<1>TXPOWER SET %d dbm.\n", dbm);
lbs_deb_wext("txpower set %d dbm\n", dbm);
ret = libertas_prepare_and_send_command(priv,
cmd_802_11_rf_tx_power,
cmd_act_tx_power_opt_set_low,
cmd_option_waitforrsp, 0, (void *)&dbm);
LEAVE();
lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
return ret;
}
......@@ -2186,7 +2152,8 @@ static int wlan_get_essid(struct net_device *dev, struct iw_request_info *info,
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
ENTER();
lbs_deb_enter(LBS_DEB_WEXT);
/*
* Note : if dwrq->flags != 0, we should get the relevant SSID from
* the SSID list...
......@@ -2196,12 +2163,12 @@ static int wlan_get_essid(struct net_device *dev, struct iw_request_info *info,
* Get the current SSID
*/
if (adapter->connect_status == libertas_connected) {
memcpy(extra, adapter->curbssparams.ssid.ssid,
adapter->curbssparams.ssid.ssidlength);
extra[adapter->curbssparams.ssid.ssidlength] = '\0';
memcpy(extra, adapter->curbssparams.ssid,
adapter->curbssparams.ssid_len);
extra[adapter->curbssparams.ssid_len] = '\0';
} else {
memset(extra, 0, 32);
extra[adapter->curbssparams.ssid.ssidlength] = '\0';
extra[adapter->curbssparams.ssid_len] = '\0';
}
/*
* If none, we may want to get the one that was set
......@@ -2209,14 +2176,14 @@ static int wlan_get_essid(struct net_device *dev, struct iw_request_info *info,
/* To make the driver backward compatible with WPA supplicant v0.2.4 */
if (dwrq->length == 32) /* check with WPA supplicant buffer size */
dwrq->length = min_t(size_t, adapter->curbssparams.ssid.ssidlength,
dwrq->length = min_t(size_t, adapter->curbssparams.ssid_len,
IW_ESSID_MAX_SIZE);
else
dwrq->length = adapter->curbssparams.ssid.ssidlength + 1;
dwrq->length = adapter->curbssparams.ssid_len + 1;
dwrq->flags = 1; /* active */
LEAVE();
lbs_deb_leave(LBS_DEB_WEXT);
return 0;
}
......@@ -2226,38 +2193,43 @@ static int wlan_set_essid(struct net_device *dev, struct iw_request_info *info,
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
int ret = 0;
struct WLAN_802_11_SSID ssid;
u8 ssid[IW_ESSID_MAX_SIZE];
u8 ssid_len = 0;
struct assoc_request * assoc_req;
int ssid_len = dwrq->length;
int in_ssid_len = dwrq->length;
ENTER();
lbs_deb_enter(LBS_DEB_WEXT);
/*
* WE-20 and earlier NULL pad the end of the SSID and increment
* SSID length so it can be used like a string. WE-21 and later don't,
* but some userspace tools aren't able to cope with the change.
*/
if ((ssid_len > 0) && (extra[ssid_len - 1] == '\0'))
ssid_len--;
if ((in_ssid_len > 0) && (extra[in_ssid_len - 1] == '\0'))
in_ssid_len--;
/* Check the size of the string */
if (ssid_len > IW_ESSID_MAX_SIZE) {
if (in_ssid_len > IW_ESSID_MAX_SIZE) {
ret = -E2BIG;
goto out;
}
memset(&ssid, 0, sizeof(struct WLAN_802_11_SSID));
memset(&ssid, 0, sizeof(ssid));
if (!dwrq->flags || !ssid_len) {
if (!dwrq->flags || !in_ssid_len) {
/* "any" SSID requested; leave SSID blank */
} else {
/* Specific SSID requested */
memcpy(&ssid.ssid, extra, ssid_len);
ssid.ssidlength = ssid_len;
memcpy(&ssid, extra, in_ssid_len);
ssid_len = in_ssid_len;
}
lbs_pr_debug(1, "Requested new SSID = %s\n",
(ssid.ssidlength > 0) ? (char *)ssid.ssid : "any");
if (!ssid_len) {
lbs_deb_wext("requested any SSID\n");
} else {
lbs_deb_wext("requested SSID '%s'\n",
escape_essid(ssid, ssid_len));
}
out:
mutex_lock(&adapter->lock);
......@@ -2268,7 +2240,8 @@ static int wlan_set_essid(struct net_device *dev, struct iw_request_info *info,
ret = -ENOMEM;
} else {
/* Copy the SSID to the association request */
memcpy(&assoc_req->ssid, &ssid, sizeof(struct WLAN_802_11_SSID));
memcpy(&assoc_req->ssid, &ssid, IW_ESSID_MAX_SIZE);
assoc_req->ssid_len = ssid_len;
set_bit(ASSOC_FLAG_SSID, &assoc_req->flags);
wlan_postpone_association_work(priv);
}
......@@ -2281,7 +2254,7 @@ static int wlan_set_essid(struct net_device *dev, struct iw_request_info *info,
mutex_unlock(&adapter->lock);
LEAVE();
lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
return ret;
}
......@@ -2302,12 +2275,12 @@ static int wlan_set_wap(struct net_device *dev, struct iw_request_info *info,
struct assoc_request * assoc_req;
int ret = 0;
ENTER();
lbs_deb_enter(LBS_DEB_WEXT);
if (awrq->sa_family != ARPHRD_ETHER)
return -EINVAL;
lbs_pr_debug(1, "ASSOC: WAP: sa_data: " MAC_FMT "\n", MAC_ARG(awrq->sa_data));
lbs_deb_wext("ASSOC: WAP: sa_data " MAC_FMT "\n", MAC_ARG(awrq->sa_data));
mutex_lock(&adapter->lock);
......@@ -2330,22 +2303,23 @@ static int wlan_set_wap(struct net_device *dev, struct iw_request_info *info,
void libertas_get_fwversion(wlan_adapter * adapter, char *fwversion, int maxlen)
{
union {
u32 l;
u8 c[4];
} ver;
char fwver[32];
mutex_lock(&adapter->lock);
ver.l = adapter->fwreleasenumber;
mutex_unlock(&adapter->lock);
if (ver.c[3] == 0)
sprintf(fwver, "%u.%u.%u", ver.c[2], ver.c[1], ver.c[0]);
if (adapter->fwreleasenumber[3] == 0)
sprintf(fwver, "%u.%u.%u",
adapter->fwreleasenumber[2],
adapter->fwreleasenumber[1],
adapter->fwreleasenumber[0]);
else
sprintf(fwver, "%u.%u.%u.p%u",
ver.c[2], ver.c[1], ver.c[0], ver.c[3]);
adapter->fwreleasenumber[2],
adapter->fwreleasenumber[1],
adapter->fwreleasenumber[0],
adapter->fwreleasenumber[3]);
mutex_unlock(&adapter->lock);
snprintf(fwversion, maxlen, fwver);
}
......@@ -2411,6 +2385,63 @@ static const iw_handler wlan_handler[] = {
(iw_handler) NULL, /* SIOCSIWPMKSA */
};
static const iw_handler mesh_wlan_handler[] = {
(iw_handler) NULL, /* SIOCSIWCOMMIT */
(iw_handler) wlan_get_name, /* SIOCGIWNAME */
(iw_handler) NULL, /* SIOCSIWNWID */
(iw_handler) NULL, /* SIOCGIWNWID */
(iw_handler) wlan_set_freq, /* SIOCSIWFREQ */
(iw_handler) wlan_get_freq, /* SIOCGIWFREQ */
(iw_handler) NULL, /* SIOCSIWMODE */
(iw_handler) mesh_wlan_get_mode, /* SIOCGIWMODE */
(iw_handler) NULL, /* SIOCSIWSENS */
(iw_handler) NULL, /* SIOCGIWSENS */
(iw_handler) NULL, /* SIOCSIWRANGE */
(iw_handler) wlan_get_range, /* SIOCGIWRANGE */
(iw_handler) NULL, /* SIOCSIWPRIV */
(iw_handler) NULL, /* SIOCGIWPRIV */
(iw_handler) NULL, /* SIOCSIWSTATS */
(iw_handler) NULL, /* SIOCGIWSTATS */
iw_handler_set_spy, /* SIOCSIWSPY */
iw_handler_get_spy, /* SIOCGIWSPY */
iw_handler_set_thrspy, /* SIOCSIWTHRSPY */
iw_handler_get_thrspy, /* SIOCGIWTHRSPY */
(iw_handler) NULL, /* SIOCSIWAP */
(iw_handler) NULL, /* SIOCGIWAP */
(iw_handler) NULL, /* SIOCSIWMLME */
(iw_handler) NULL, /* SIOCGIWAPLIST - deprecated */
(iw_handler) libertas_set_scan, /* SIOCSIWSCAN */
(iw_handler) libertas_get_scan, /* SIOCGIWSCAN */
(iw_handler) NULL, /* SIOCSIWESSID */
(iw_handler) NULL, /* SIOCGIWESSID */
(iw_handler) NULL, /* SIOCSIWNICKN */
(iw_handler) mesh_get_nick, /* SIOCGIWNICKN */
(iw_handler) NULL, /* -- hole -- */
(iw_handler) NULL, /* -- hole -- */
(iw_handler) wlan_set_rate, /* SIOCSIWRATE */
(iw_handler) wlan_get_rate, /* SIOCGIWRATE */
(iw_handler) wlan_set_rts, /* SIOCSIWRTS */
(iw_handler) wlan_get_rts, /* SIOCGIWRTS */
(iw_handler) wlan_set_frag, /* SIOCSIWFRAG */
(iw_handler) wlan_get_frag, /* SIOCGIWFRAG */
(iw_handler) wlan_set_txpow, /* SIOCSIWTXPOW */
(iw_handler) wlan_get_txpow, /* SIOCGIWTXPOW */
(iw_handler) wlan_set_retry, /* SIOCSIWRETRY */
(iw_handler) wlan_get_retry, /* SIOCGIWRETRY */
(iw_handler) wlan_set_encode, /* SIOCSIWENCODE */
(iw_handler) wlan_get_encode, /* SIOCGIWENCODE */
(iw_handler) wlan_set_power, /* SIOCSIWPOWER */
(iw_handler) wlan_get_power, /* SIOCGIWPOWER */
(iw_handler) NULL, /* -- hole -- */
(iw_handler) NULL, /* -- hole -- */
(iw_handler) wlan_set_genie, /* SIOCSIWGENIE */
(iw_handler) wlan_get_genie, /* SIOCGIWGENIE */
(iw_handler) wlan_set_auth, /* SIOCSIWAUTH */
(iw_handler) wlan_get_auth, /* SIOCGIWAUTH */
(iw_handler) wlan_set_encodeext,/* SIOCSIWENCODEEXT */
(iw_handler) wlan_get_encodeext,/* SIOCGIWENCODEEXT */
(iw_handler) NULL, /* SIOCSIWPMKSA */
};
struct iw_handler_def libertas_handler_def = {
.num_standard = sizeof(wlan_handler) / sizeof(iw_handler),
.num_private = sizeof(wlan_private_handler) / sizeof(iw_handler),
......@@ -2421,3 +2452,14 @@ struct iw_handler_def libertas_handler_def = {
.private_args = (struct iw_priv_args *)wlan_private_args,
.get_wireless_stats = wlan_get_wireless_stats,
};
struct iw_handler_def mesh_handler_def = {
.num_standard = sizeof(mesh_wlan_handler) / sizeof(iw_handler),
.num_private = sizeof(wlan_private_handler) / sizeof(iw_handler),
.num_private_args = sizeof(wlan_private_args) /
sizeof(struct iw_priv_args),
.standard = (iw_handler *) mesh_wlan_handler,
.private = (iw_handler *) wlan_private_handler,
.private_args = (struct iw_priv_args *)wlan_private_args,
.get_wireless_stats = wlan_get_wireless_stats,
};
......@@ -20,10 +20,12 @@
#define WLAN_SUBCMD_FWT_CLEANUP 15
#define WLAN_SUBCMD_FWT_TIME 16
#define WLAN_SUBCMD_MESH_GET_TTL 17
#define WLAN_SUBCMD_BT_GET_INVERT 18
#define WLAN_SETONEINT_GETNONE (WLANIOCTL + 24)
#define WLANSETREGION 8
#define WLAN_SUBCMD_MESH_SET_TTL 18
#define WLAN_SUBCMD_BT_SET_INVERT 19
#define WLAN_SET128CHAR_GET128CHAR (WLANIOCTL + 25)
#define WLAN_SUBCMD_BT_ADD 18
......@@ -56,6 +58,7 @@ struct wlan_ioctl_regrdwr {
};
extern struct iw_handler_def libertas_handler_def;
extern struct iw_handler_def mesh_handler_def;
int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int i);
int wlan_radio_ioctl(wlan_private * priv, u8 option);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment