2011-10-12 18:51:51

by Arend van Spriel

[permalink] [raw]
Subject: [PATCH 00/22] brcm80211: mainline patch related cleanup

The mainline patch (version 3) did receive some comments from
Johannes Berg and Hauke Mehrtens that we started working on. This
series contains several of those cleanup patches.

This series applies to the wireless-testing repository and depends
upon the linux-next merge patches as posted by Stephen Rothwell:

Message-ID: <[email protected]>
Message-ID: <[email protected]>

There was a third patch from Stephen Rothwell to include linux/export.h
but that file is not yet in the wireless-testing repository so I did not
use that preparing this series:

Message-ID: <[email protected]>

Alwin Beukers (9):
brcm80211: cleanup function prototypes
brcm80211: removed unused functions
brcm80211: moved power conversion functions
brcm80211: moved function brcmu_chipname
brcm80211: moved function brcmu_parse_tlvs
brcm80211: moved function brcmu_chspec_malformed
brcm80211: moved function brcmu_mkiovar
brcm80211: moved function brcmu_format_flags
brcm80211: removed file wifi.c

Arend van Spriel (10):
brcm80211: remove sparse warning in fullmac debug function
brcm80211: fix sparse endianess error in mac80211_if.c
brcm80211: add endian annotation to packet filter structures
brcm80211: rename variable in _brcmf_set_multicast_list()
brcm80211: fix annotations in TOE configuration functions
brcm80211: use endian annotations in scan related function
brcm80211: use endian annotation for pmk related structure
brcm80211: use endian annotations for assoc ie length request
brcm80211: use endian annotation for roaming related parameters
brcm80211: use endian annotation for scan time configuration

Roland Vossen (3):
brcm80211: smac: removed redundant timer function parameters
brcm80211: smac: decreased timer callback irq level
brcm80211: fmac: fixed weird indentation

drivers/net/wireless/brcm80211/brcmfmac/dhd.h | 27 +-
.../net/wireless/brcm80211/brcmfmac/dhd_common.c | 71 +-
.../net/wireless/brcm80211/brcmfmac/dhd_linux.c | 55 +-
drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 11 +-
.../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 332 ++-
.../net/wireless/brcm80211/brcmfmac/wl_cfg80211.h | 6 +-
drivers/net/wireless/brcm80211/brcmsmac/channel.c | 28 +-
.../net/wireless/brcm80211/brcmsmac/mac80211_if.c | 53 +-
.../net/wireless/brcm80211/brcmsmac/mac80211_if.h | 19 +-
drivers/net/wireless/brcm80211/brcmsmac/main.c | 3430 ++++++++++----------
drivers/net/wireless/brcm80211/brcmsmac/main.h | 84 -
.../net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c | 12 +-
drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c | 13 +-
drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h | 9 +-
drivers/net/wireless/brcm80211/brcmsmac/pub.h | 49 +-
drivers/net/wireless/brcm80211/brcmsmac/stf.c | 2 -
drivers/net/wireless/brcm80211/brcmutil/Makefile | 3 +-
drivers/net/wireless/brcm80211/brcmutil/utils.c | 215 --
drivers/net/wireless/brcm80211/brcmutil/wifi.c | 136 -
.../net/wireless/brcm80211/include/brcmu_utils.h | 28 -
.../net/wireless/brcm80211/include/brcmu_wifi.h | 38 +-
21 files changed, 2112 insertions(+), 2509 deletions(-)
delete mode 100644 drivers/net/wireless/brcm80211/brcmutil/wifi.c

--
1.7.4.1




2011-10-13 18:32:53

by Arend van Spriel

[permalink] [raw]
Subject: Re: [PATCH 22/22] brcm80211: removed file wifi.c

On 10/13/2011 08:23 PM, John W. Linville wrote:
> On Thu, Oct 13, 2011 at 11:08:15AM -0700, Luis R. Rodriguez wrote:
>> On Thu, Oct 13, 2011 at 1:51 AM, Arend van Spriel <[email protected]> wrote:
>>> On 10/12/2011 11:54 PM, Luis R. Rodriguez wrote:
>>>> On Wed, Oct 12, 2011 at 11:51 AM, Arend van Spriel <[email protected]> wrote:
>>>>> From: Alwin Beukers <[email protected]>
>>>>>
>>>>> Wifi.c was empty after previous cleanups, so it was removed.
>>>>>
>>>>> Reviewed-by: Arend van Spriel <[email protected]>
>>>>> Signed-off-by: Arend van Spriel <[email protected]>
>>>>
>>>> Heh, remove Reviewed-by dude.
>>>>
>>>> Luis
>>>>
>>>
>>> I had a remark on this in earlier commits. So I am clearly missing the
>>> point here. The author submitted this change and others for review to me
>>> and I reviewed it as requested. Hence the Reviewed-by: entry.
>>>
>>> I have been given the task to publish these patches and I sign them off
>>> for the "Developer's Certificate of Origin". Hence the Signed-off-by: entry.
>>>
>>> Is there something wrong with this reasoning?
>>
>> Yeah this all makes no sense. If someone submits you a patch for you
>> to review *and* push upstream you simply add *their* SOB first, and
>> then after that your own.
>
> For my $0.02, having both a Reviewed-by and a Signed-off-by looks
> a little funny, but it isn't necessarily wrong. The Signed-off-by
> really only says that you believe that patch is legally contributed.
>
> Oh, and IANAL...
>
> John

IANALE

Gr. AvS


Attachments:
0xB5E1A116.asc (3.04 kB)
signature.asc (900.00 B)
OpenPGP digital signature
Download all attachments

2011-10-12 18:51:51

by Arend van Spriel

[permalink] [raw]
Subject: [PATCH 06/22] brcm80211: add endian annotation to packet filter structures

The packet filter structures were byte copied and transferred over the
host bus to the device. As such they are little endian and have been
annotated accordingly.

Reported-by: Johannes Berg <[email protected]>
Reviewed-by: Franky (Zhenhui) Lin <[email protected]>
Reviewed-by: Roland Vossen <[email protected]>
Signed-off-by: Arend van Spriel <[email protected]>
---
drivers/net/wireless/brcm80211/brcmfmac/dhd.h | 22 ++++++------
.../net/wireless/brcm80211/brcmfmac/dhd_common.c | 34 ++++++++++---------
2 files changed, 29 insertions(+), 27 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
index f58c0eb..951910e 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
@@ -330,14 +330,14 @@ enum brcmf_bus_state {
* start matching, the pattern to match, the size of the pattern, and a bitmask
* that indicates which bits within the pattern should be matched.
*/
-struct brcmf_pkt_filter_pattern {
+struct brcmf_pkt_filter_pattern_le {
/*
* Offset within received packet to start pattern matching.
* Offset '0' is the first byte of the ethernet header.
*/
- u32 offset;
+ __le32 offset;
/* Size of the pattern. Bitmask must be the same size.*/
- u32 size_bytes;
+ __le32 size_bytes;
/*
* Variable length mask and pattern data. mask starts at offset 0.
* Pattern immediately follows mask.
@@ -346,19 +346,19 @@ struct brcmf_pkt_filter_pattern {
};

/* IOVAR "pkt_filter_add" parameter. Used to install packet filters. */
-struct brcmf_pkt_filter {
- u32 id; /* Unique filter id, specified by app. */
- u32 type; /* Filter type (WL_PKT_FILTER_TYPE_xxx). */
- u32 negate_match; /* Negate the result of filter matches */
+struct brcmf_pkt_filter_le {
+ __le32 id; /* Unique filter id, specified by app. */
+ __le32 type; /* Filter type (WL_PKT_FILTER_TYPE_xxx). */
+ __le32 negate_match; /* Negate the result of filter matches */
union { /* Filter definitions */
- struct brcmf_pkt_filter_pattern pattern; /* Filter pattern */
+ struct brcmf_pkt_filter_pattern_le pattern; /* Filter pattern */
} u;
};

/* IOVAR "pkt_filter_enable" parameter. */
-struct brcmf_pkt_filter_enable {
- u32 id; /* Unique filter id */
- u32 enable; /* Enable/disable bool */
+struct brcmf_pkt_filter_enable_le {
+ __le32 id; /* Unique filter id */
+ __le32 enable; /* Enable/disable bool */
};

/* BSS info structure
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
index 4075fd7..a43b3da 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
@@ -36,9 +36,9 @@ int brcmf_msg_level;

#define MSGTRACE_VERSION 1

-#define BRCMF_PKT_FILTER_FIXED_LEN offsetof(struct brcmf_pkt_filter, u)
+#define BRCMF_PKT_FILTER_FIXED_LEN offsetof(struct brcmf_pkt_filter_le, u)
#define BRCMF_PKT_FILTER_PATTERN_FIXED_LEN \
- offsetof(struct brcmf_pkt_filter_pattern, mask_and_pattern)
+ offsetof(struct brcmf_pkt_filter_pattern_le, mask_and_pattern)

#ifdef BCMDBG
static const char brcmf_version[] =
@@ -558,8 +558,9 @@ brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg, int enable,
char *arg_save = NULL, *arg_org = NULL;
int rc;
char buf[128];
- struct brcmf_pkt_filter_enable enable_parm;
- struct brcmf_pkt_filter_enable *pkt_filterp;
+ struct brcmf_pkt_filter_enable_le enable_parm;
+ struct brcmf_pkt_filter_enable_le *pkt_filterp;
+ __le32 mmode_le;

arg_save = kmalloc(strlen(arg) + 1, GFP_ATOMIC);
if (!arg_save)
@@ -582,15 +583,15 @@ brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg, int enable,
buf[str_len] = '\0';
buf_len = str_len + 1;

- pkt_filterp = (struct brcmf_pkt_filter_enable *) (buf + str_len + 1);
+ pkt_filterp = (struct brcmf_pkt_filter_enable_le *) (buf + str_len + 1);

/* Parse packet filter id. */
enable_parm.id = 0;
if (!kstrtoul(argv[i], 0, &res))
- enable_parm.id = (u32)res;
+ enable_parm.id = cpu_to_le32((u32)res);

/* Parse enable/disable value. */
- enable_parm.enable = enable;
+ enable_parm.enable = cpu_to_le32(enable);

buf_len += sizeof(enable_parm);
memcpy((char *)pkt_filterp, &enable_parm, sizeof(enable_parm));
@@ -605,7 +606,8 @@ brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg, int enable,
brcmf_dbg(TRACE, "successfully added pktfilter %s\n", arg);

/* Contorl the master mode */
- brcmu_mkiovar("pkt_filter_mode", (char *)&master_mode, 4, buf,
+ mmode_le = cpu_to_le32(master_mode);
+ brcmu_mkiovar("pkt_filter_mode", (char *)&mmode_le, 4, buf,
sizeof(buf));
rc = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, buf,
sizeof(buf));
@@ -621,8 +623,8 @@ fail:
void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg)
{
const char *str;
- struct brcmf_pkt_filter pkt_filter;
- struct brcmf_pkt_filter *pkt_filterp;
+ struct brcmf_pkt_filter_le pkt_filter;
+ struct brcmf_pkt_filter_le *pkt_filterp;
unsigned long res;
int buf_len;
int str_len;
@@ -658,12 +660,12 @@ void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg)
str_len = strlen(str);
buf_len = str_len + 1;

- pkt_filterp = (struct brcmf_pkt_filter *) (buf + str_len + 1);
+ pkt_filterp = (struct brcmf_pkt_filter_le *) (buf + str_len + 1);

/* Parse packet filter id. */
pkt_filter.id = 0;
if (!kstrtoul(argv[i], 0, &res))
- pkt_filter.id = (u32)res;
+ pkt_filter.id = cpu_to_le32((u32)res);

if (NULL == argv[++i]) {
brcmf_dbg(ERROR, "Polarity not provided\n");
@@ -673,7 +675,7 @@ void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg)
/* Parse filter polarity. */
pkt_filter.negate_match = 0;
if (!kstrtoul(argv[i], 0, &res))
- pkt_filter.negate_match = (u32)res;
+ pkt_filter.negate_match = cpu_to_le32((u32)res);

if (NULL == argv[++i]) {
brcmf_dbg(ERROR, "Filter type not provided\n");
@@ -683,7 +685,7 @@ void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg)
/* Parse filter type. */
pkt_filter.type = 0;
if (!kstrtoul(argv[i], 0, &res))
- pkt_filter.type = (u32)res;
+ pkt_filter.type = cpu_to_le32((u32)res);

if (NULL == argv[++i]) {
brcmf_dbg(ERROR, "Offset not provided\n");
@@ -693,7 +695,7 @@ void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg)
/* Parse pattern filter offset. */
pkt_filter.u.pattern.offset = 0;
if (!kstrtoul(argv[i], 0, &res))
- pkt_filter.u.pattern.offset = (u32)res;
+ pkt_filter.u.pattern.offset = cpu_to_le32((u32)res);

if (NULL == argv[++i]) {
brcmf_dbg(ERROR, "Bitmask not provided\n");
@@ -721,7 +723,7 @@ void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg)
goto fail;
}

- pkt_filter.u.pattern.size_bytes = mask_size;
+ pkt_filter.u.pattern.size_bytes = cpu_to_le32(mask_size);
buf_len += BRCMF_PKT_FILTER_FIXED_LEN;
buf_len += (BRCMF_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size);

--
1.7.4.1



2011-10-12 18:51:47

by Arend van Spriel

[permalink] [raw]
Subject: [PATCH 05/22] brcm80211: fix sparse endianess error in mac80211_if.c

The ht capabilities provided upon registration with mac80211 must
be in little endian. This was fixed adding cpu_to_le16() conversion.

Signed-off-by: Arend van Spriel <[email protected]>
---
.../net/wireless/brcm80211/brcmsmac/mac80211_if.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
index 6ce773a..ac8d02b 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -963,7 +963,7 @@ static int ieee_hw_rate_init(struct ieee80211_hw *hw)
if (phy_type == PHY_TYPE_LCN) {
/* Single stream */
band->ht_cap.mcs.rx_mask[1] = 0;
- band->ht_cap.mcs.rx_highest = 72;
+ band->ht_cap.mcs.rx_highest = cpu_to_le16(72);
}
hw->wiphy->bands[IEEE80211_BAND_2GHZ] = band;
} else {
--
1.7.4.1



2011-10-12 18:51:51

by Arend van Spriel

[permalink] [raw]
Subject: [PATCH 07/22] brcm80211: rename variable in _brcmf_set_multicast_list()

The variable allmulti was used to provision IFF_ALLMULTI to the
device as well as IFF_PROMISC. For clarity the variable has been
renamed.

Reviewed-by: Roland Vossen <[email protected]>
Reviewed-by: Franky (Zhenhui) Lin <[email protected]>
Signed-off-by: Arend van Spriel <[email protected]>
---
.../net/wireless/brcm80211/brcmfmac/dhd_linux.c | 30 ++++++++++----------
1 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index 7f5003e..fb9f808 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -137,9 +137,9 @@ static void _brcmf_set_multicast_list(struct work_struct *work)
{
struct net_device *ndev;
struct netdev_hw_addr *ha;
- u32 allmulti, cnt;
+ u32 dcmd_value, cnt;
__le32 cnt_le;
- __le32 allmulti_le;
+ __le32 dcmd_le_value;

struct brcmf_dcmd dcmd;
char *buf, *bufp;
@@ -153,7 +153,7 @@ static void _brcmf_set_multicast_list(struct work_struct *work)
cnt = netdev_mc_count(ndev);

/* Determine initial value of allmulti flag */
- allmulti = (ndev->flags & IFF_ALLMULTI) ? true : false;
+ dcmd_value = (ndev->flags & IFF_ALLMULTI) ? true : false;

/* Send down the multicast list first. */

@@ -187,7 +187,7 @@ static void _brcmf_set_multicast_list(struct work_struct *work)
if (ret < 0) {
brcmf_dbg(ERROR, "%s: set mcast_list failed, cnt %d\n",
brcmf_ifname(&drvr_priv->pub, 0), cnt);
- allmulti = cnt ? true : allmulti;
+ dcmd_value = cnt ? true : dcmd_value;
}

kfree(buf);
@@ -197,19 +197,19 @@ static void _brcmf_set_multicast_list(struct work_struct *work)
* were trying to set some addresses and dongle rejected it...
*/

- buflen = sizeof("allmulti") + sizeof(allmulti);
+ buflen = sizeof("allmulti") + sizeof(dcmd_value);
buf = kmalloc(buflen, GFP_ATOMIC);
if (!buf)
return;

- allmulti_le = cpu_to_le32(allmulti);
+ dcmd_le_value = cpu_to_le32(dcmd_value);

if (!brcmu_mkiovar
- ("allmulti", (void *)&allmulti_le,
- sizeof(allmulti_le), buf, buflen)) {
+ ("allmulti", (void *)&dcmd_le_value,
+ sizeof(dcmd_le_value), buf, buflen)) {
brcmf_dbg(ERROR, "%s: mkiovar failed for allmulti, datalen %d buflen %u\n",
brcmf_ifname(&drvr_priv->pub, 0),
- (int)sizeof(allmulti), buflen);
+ (int)sizeof(dcmd_value), buflen);
kfree(buf);
return;
}
@@ -224,7 +224,7 @@ static void _brcmf_set_multicast_list(struct work_struct *work)
if (ret < 0) {
brcmf_dbg(ERROR, "%s: set allmulti %d failed\n",
brcmf_ifname(&drvr_priv->pub, 0),
- le32_to_cpu(allmulti_le));
+ le32_to_cpu(dcmd_le_value));
}

kfree(buf);
@@ -232,20 +232,20 @@ static void _brcmf_set_multicast_list(struct work_struct *work)
/* Finally, pick up the PROMISC flag as well, like the NIC
driver does */

- allmulti = (ndev->flags & IFF_PROMISC) ? true : false;
- allmulti_le = cpu_to_le32(allmulti);
+ dcmd_value = (ndev->flags & IFF_PROMISC) ? true : false;
+ dcmd_le_value = cpu_to_le32(dcmd_value);

memset(&dcmd, 0, sizeof(dcmd));
dcmd.cmd = BRCMF_C_SET_PROMISC;
- dcmd.buf = &allmulti_le;
- dcmd.len = sizeof(allmulti_le);
+ dcmd.buf = &dcmd_le_value;
+ dcmd.len = sizeof(dcmd_le_value);
dcmd.set = true;

ret = brcmf_proto_dcmd(&drvr_priv->pub, 0, &dcmd, dcmd.len);
if (ret < 0) {
brcmf_dbg(ERROR, "%s: set promisc %d failed\n",
brcmf_ifname(&drvr_priv->pub, 0),
- le32_to_cpu(allmulti_le));
+ le32_to_cpu(dcmd_le_value));
}
}

--
1.7.4.1



2011-10-12 18:51:47

by Arend van Spriel

[permalink] [raw]
Subject: [PATCH 19/22] brcm80211: moved function brcmu_chspec_malformed

From: Alwin Beukers <[email protected]>

Moved brcmu_chspec_malformed into the only file using it. The
function name was adjusted accordingly.

Reported-by: Johannes Berg <[email protected]>
Reviewed-by: Roland Vossen <[email protected]>
Reviewed-by: Arend van Spriel <[email protected]>
Signed-off-by: Arend van Spriel <[email protected]>
---
drivers/net/wireless/brcm80211/brcmsmac/channel.c | 28 +++++++++++++++++++-
drivers/net/wireless/brcm80211/brcmutil/wifi.c | 27 -------------------
.../net/wireless/brcm80211/include/brcmu_wifi.h | 8 -----
3 files changed, 27 insertions(+), 36 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.c b/drivers/net/wireless/brcm80211/brcmsmac/channel.c
index a1b415d..89ad1b7 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/channel.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.c
@@ -1485,6 +1485,32 @@ brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, u16 chanspec,
}

/*
+ * Verify the chanspec is using a legal set of parameters, i.e. that the
+ * chanspec specified a band, bw, ctl_sb and channel and that the
+ * combination could be legal given any set of circumstances.
+ * RETURNS: true is the chanspec is malformed, false if it looks good.
+ */
+static bool brcms_c_chspec_malformed(u16 chanspec)
+{
+ /* must be 2G or 5G band */
+ if (!CHSPEC_IS5G(chanspec) && !CHSPEC_IS2G(chanspec))
+ return true;
+ /* must be 20 or 40 bandwidth */
+ if (!CHSPEC_IS40(chanspec) && !CHSPEC_IS20(chanspec))
+ return true;
+
+ /* 20MHZ b/w must have no ctl sb, 40 must have a ctl sb */
+ if (CHSPEC_IS20(chanspec)) {
+ if (!CHSPEC_SB_NONE(chanspec))
+ return true;
+ } else if (!CHSPEC_SB_UPPER(chanspec) && !CHSPEC_SB_LOWER(chanspec)) {
+ return true;
+ }
+
+ return false;
+}
+
+/*
* Validate the chanspec for this locale, for 40MHZ we need to also
* check that the sidebands are valid 20MZH channels in this locale
* and they are also a legal HT combination
@@ -1497,7 +1523,7 @@ brcms_c_valid_chanspec_ext(struct brcms_cm_info *wlc_cm, u16 chspec,
u8 channel = CHSPEC_CHANNEL(chspec);

/* check the chanspec */
- if (brcmu_chspec_malformed(chspec)) {
+ if (brcms_c_chspec_malformed(chspec)) {
wiphy_err(wlc->wiphy, "wl%d: malformed chanspec 0x%x\n",
wlc->pub->unit, chspec);
return false;
diff --git a/drivers/net/wireless/brcm80211/brcmutil/wifi.c b/drivers/net/wireless/brcm80211/brcmutil/wifi.c
index e8d3bf2..8483f24 100644
--- a/drivers/net/wireless/brcm80211/brcmutil/wifi.c
+++ b/drivers/net/wireless/brcm80211/brcmutil/wifi.c
@@ -14,30 +14,3 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <brcmu_wifi.h>
-
-/*
- * Verify the chanspec is using a legal set of parameters, i.e. that the
- * chanspec specified a band, bw, ctl_sb and channel and that the
- * combination could be legal given any set of circumstances.
- * RETURNS: true is the chanspec is malformed, false if it looks good.
- */
-bool brcmu_chspec_malformed(u16 chanspec)
-{
- /* must be 2G or 5G band */
- if (!CHSPEC_IS5G(chanspec) && !CHSPEC_IS2G(chanspec))
- return true;
- /* must be 20 or 40 bandwidth */
- if (!CHSPEC_IS40(chanspec) && !CHSPEC_IS20(chanspec))
- return true;
-
- /* 20MHZ b/w must have no ctl sb, 40 must have a ctl sb */
- if (CHSPEC_IS20(chanspec)) {
- if (!CHSPEC_SB_NONE(chanspec))
- return true;
- } else if (!CHSPEC_SB_UPPER(chanspec) && !CHSPEC_SB_LOWER(chanspec)) {
- return true;
- }
-
- return false;
-}
-EXPORT_SYMBOL(brcmu_chspec_malformed);
diff --git a/drivers/net/wireless/brcm80211/include/brcmu_wifi.h b/drivers/net/wireless/brcm80211/include/brcmu_wifi.h
index 5b1aca7..f10d302 100644
--- a/drivers/net/wireless/brcm80211/include/brcmu_wifi.h
+++ b/drivers/net/wireless/brcm80211/include/brcmu_wifi.h
@@ -168,14 +168,6 @@ static inline bool ac_bitmap_tst(u8 bitmap, int prec)
return (bitmap & (1 << (prec))) != 0;
}

-/*
- * Verify the chanspec is using a legal set of parameters, i.e. that the
- * chanspec specified a band, bw, ctl_sb and channel and that the
- * combination could be legal given any set of circumstances.
- * RETURNS: true is the chanspec is malformed, false if it looks good.
- */
-extern bool brcmu_chspec_malformed(u16 chanspec);
-
/* Enumerate crypto algorithms */
#define CRYPTO_ALGO_OFF 0
#define CRYPTO_ALGO_WEP1 1
--
1.7.4.1



2011-10-12 18:51:47

by Arend van Spriel

[permalink] [raw]
Subject: [PATCH 20/22] brcm80211: moved function brcmu_mkiovar

From: Alwin Beukers <[email protected]>

Moved the brcmu_mkiovar function into fmac, adjusting the
name accordingly.

Reported-by: Johannes Berg <[email protected]>
Reviewed-by: Roland Vossen <[email protected]>
Reviewed-by: Arend van Spriel <[email protected]>
Signed-off-by: Arend van Spriel <[email protected]>
---
drivers/net/wireless/brcm80211/brcmfmac/dhd.h | 3 ++
.../net/wireless/brcm80211/brcmfmac/dhd_common.c | 39 +++++++++++++++-----
.../net/wireless/brcm80211/brcmfmac/dhd_linux.c | 6 ++--
.../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 24 ++++++------
drivers/net/wireless/brcm80211/brcmutil/utils.c | 20 ----------
.../net/wireless/brcm80211/include/brcmu_utils.h | 3 --
6 files changed, 48 insertions(+), 47 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
index 951910e..4645766 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
@@ -680,6 +680,9 @@ struct bcmevent_name {

extern const struct bcmevent_name bcmevent_names[];

+extern uint brcmf_c_mkiovar(char *name, char *data, uint datalen,
+ char *buf, uint len);
+
/* Indication from bus module regarding presence/insertion of dongle.
* Return struct brcmf_pub pointer, used as handle to OS module in later calls.
* Returned structure should have bus and prot pointers filled in.
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
index a43b3da..8918261 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
@@ -65,6 +65,26 @@ struct msgtrace_hdr {
because of trace overflow */
} __packed;

+
+uint
+brcmf_c_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen)
+{
+ uint len;
+
+ len = strlen(name) + 1;
+
+ if ((len + datalen) > buflen)
+ return 0;
+
+ strncpy(buf, name, buflen);
+
+ /* append data onto the end of the name string */
+ memcpy(&buf[len], data, datalen);
+ len += datalen;
+
+ return len;
+}
+
void brcmf_c_init(void)
{
/* Init global variables at run-time, not as part of the declaration.
@@ -607,7 +627,7 @@ brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg, int enable,

/* Contorl the master mode */
mmode_le = cpu_to_le32(master_mode);
- brcmu_mkiovar("pkt_filter_mode", (char *)&mmode_le, 4, buf,
+ brcmf_c_mkiovar("pkt_filter_mode", (char *)&mmode_le, 4, buf,
sizeof(buf));
rc = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, buf,
sizeof(buf));
@@ -756,7 +776,7 @@ static void brcmf_c_arp_offload_set(struct brcmf_pub *drvr, int arp_mode)
char iovbuf[32];
int retcode;

- brcmu_mkiovar("arp_ol", (char *)&arp_mode, 4, iovbuf, sizeof(iovbuf));
+ brcmf_c_mkiovar("arp_ol", (char *)&arp_mode, 4, iovbuf, sizeof(iovbuf));
retcode = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR,
iovbuf, sizeof(iovbuf));
retcode = retcode >= 0 ? 0 : retcode;
@@ -773,7 +793,8 @@ static void brcmf_c_arp_offload_enable(struct brcmf_pub *drvr, int arp_enable)
char iovbuf[32];
int retcode;

- brcmu_mkiovar("arpoe", (char *)&arp_enable, 4, iovbuf, sizeof(iovbuf));
+ brcmf_c_mkiovar("arpoe", (char *)&arp_enable, 4,
+ iovbuf, sizeof(iovbuf));
retcode = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR,
iovbuf, sizeof(iovbuf));
retcode = retcode >= 0 ? 0 : retcode;
@@ -812,33 +833,33 @@ int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr)
/* query for 'ver' to get version info from firmware */
memset(buf, 0, sizeof(buf));
ptr = buf;
- brcmu_mkiovar("ver", NULL, 0, buf, sizeof(buf));
+ brcmf_c_mkiovar("ver", NULL, 0, buf, sizeof(buf));
brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR, buf, sizeof(buf));
strsep(&ptr, "\n");
/* Print fw version info */
brcmf_dbg(ERROR, "Firmware version = %s\n", buf);

/* Match Host and Dongle rx alignment */
- brcmu_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf,
+ brcmf_c_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf,
sizeof(iovbuf));
brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
sizeof(iovbuf));

/* disable glom option per default */
- brcmu_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf));
+ brcmf_c_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf));
brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
sizeof(iovbuf));

/* Setup timeout if Beacons are lost and roam is off to report
link down */
- brcmu_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf,
+ brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf,
sizeof(iovbuf));
brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
sizeof(iovbuf));

/* Enable/Disable build-in roaming to allowed ext supplicant to take
of romaing */
- brcmu_mkiovar("roam_off", (char *)&roaming, 4,
+ brcmf_c_mkiovar("roam_off", (char *)&roaming, 4,
iovbuf, sizeof(iovbuf));
brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
sizeof(iovbuf));
@@ -847,7 +868,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr)
brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_UP, (char *)&up, sizeof(up));

/* Setup event_msgs */
- brcmu_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN,
+ brcmf_c_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN,
iovbuf, sizeof(iovbuf));
brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
sizeof(iovbuf));
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index b05f177..4acbac5 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -204,7 +204,7 @@ static void _brcmf_set_multicast_list(struct work_struct *work)

dcmd_le_value = cpu_to_le32(dcmd_value);

- if (!brcmu_mkiovar
+ if (!brcmf_c_mkiovar
("allmulti", (void *)&dcmd_le_value,
sizeof(dcmd_le_value), buf, buflen)) {
brcmf_dbg(ERROR, "%s: mkiovar failed for allmulti, datalen %d buflen %u\n",
@@ -260,7 +260,7 @@ _brcmf_set_mac_address(struct work_struct *work)
setmacaddr_work);

brcmf_dbg(TRACE, "enter\n");
- if (!brcmu_mkiovar("cur_etheraddr", (char *)drvr_priv->macvalue,
+ if (!brcmf_c_mkiovar("cur_etheraddr", (char *)drvr_priv->macvalue,
ETH_ALEN, buf, 32)) {
brcmf_dbg(ERROR, "%s: mkiovar failed for cur_etheraddr\n",
brcmf_ifname(&drvr_priv->pub, 0));
@@ -1084,7 +1084,7 @@ int brcmf_bus_start(struct brcmf_pub *drvr)
return -ENODEV;
}

- brcmu_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN,
+ brcmf_c_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN,
iovbuf, sizeof(iovbuf));
brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR, iovbuf,
sizeof(iovbuf));
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 857b328..5eddabe 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -437,7 +437,7 @@ static s32 brcmf_dev_intvar_set(struct net_device *ndev, s8 *name, s32 val)
__le32 val_le;

val_le = cpu_to_le32(val);
- len = brcmu_mkiovar(name, (char *)(&val_le), sizeof(val_le), buf,
+ len = brcmf_c_mkiovar(name, (char *)(&val_le), sizeof(val_le), buf,
sizeof(buf));
BUG_ON(!len);

@@ -460,7 +460,7 @@ brcmf_dev_intvar_get(struct net_device *ndev, s8 *name, s32 *retval)
s32 err = 0;

len =
- brcmu_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
+ brcmf_c_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
sizeof(var.buf));
BUG_ON(!len);
err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, &var, len);
@@ -508,7 +508,7 @@ brcmf_dev_iovar_setbuf(struct net_device *ndev, s8 * iovar, void *param,
{
s32 iolen;

- iolen = brcmu_mkiovar(iovar, param, paramlen, bufptr, buflen);
+ iolen = brcmf_c_mkiovar(iovar, param, paramlen, bufptr, buflen);
BUG_ON(!iolen);

return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, bufptr, iolen);
@@ -520,7 +520,7 @@ brcmf_dev_iovar_getbuf(struct net_device *ndev, s8 * iovar, void *param,
{
s32 iolen;

- iolen = brcmu_mkiovar(iovar, param, paramlen, bufptr, buflen);
+ iolen = brcmf_c_mkiovar(iovar, param, paramlen, bufptr, buflen);
BUG_ON(!iolen);

return brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, bufptr, buflen);
@@ -2554,7 +2554,7 @@ brcmf_dev_bufvar_set(struct net_device *ndev, s8 *name, s8 *buf, s32 len)
struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
u32 buflen;

- buflen = brcmu_mkiovar(name, buf, len, cfg_priv->dcmd_buf,
+ buflen = brcmf_c_mkiovar(name, buf, len, cfg_priv->dcmd_buf,
WL_DCMD_LEN_MAX);
BUG_ON(!buflen);

@@ -2570,7 +2570,7 @@ brcmf_dev_bufvar_get(struct net_device *ndev, s8 *name, s8 *buf,
u32 len;
s32 err = 0;

- len = brcmu_mkiovar(name, NULL, 0, cfg_priv->dcmd_buf,
+ len = brcmf_c_mkiovar(name, NULL, 0, cfg_priv->dcmd_buf,
WL_DCMD_LEN_MAX);
BUG_ON(!len);
err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, cfg_priv->dcmd_buf,
@@ -3513,8 +3513,8 @@ static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
WL_TRACE("Enter\n");

/* Setup event_msgs */
- brcmu_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN, iovbuf,
- sizeof(iovbuf));
+ brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
+ iovbuf, sizeof(iovbuf));
err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, iovbuf, sizeof(iovbuf));
if (err) {
WL_ERR("Get event_msgs error (%d)\n", err);
@@ -3542,8 +3542,8 @@ static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
setbit(eventmask, BRCMF_E_JOIN_START);
setbit(eventmask, BRCMF_E_SCAN_COMPLETE);

- brcmu_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN, iovbuf,
- sizeof(iovbuf));
+ brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
+ iovbuf, sizeof(iovbuf));
err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
if (err) {
WL_ERR("Set event_msgs error (%d)\n", err);
@@ -3571,7 +3571,7 @@ brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
*/
if (roamvar) {
bcn_to_le = cpu_to_le32(bcn_timeout);
- brcmu_mkiovar("bcn_timeout", (char *)&bcn_to_le,
+ brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_to_le,
sizeof(bcn_to_le), iovbuf, sizeof(iovbuf));
err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR,
iovbuf, sizeof(iovbuf));
@@ -3587,7 +3587,7 @@ brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
*/
WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
roamvar_le = cpu_to_le32(roamvar);
- brcmu_mkiovar("roam_off", (char *)&roamvar_le,
+ brcmf_c_mkiovar("roam_off", (char *)&roamvar_le,
sizeof(roamvar_le), iovbuf, sizeof(iovbuf));
err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
if (err) {
diff --git a/drivers/net/wireless/brcm80211/brcmutil/utils.c b/drivers/net/wireless/brcm80211/brcmutil/utils.c
index 2d903ba..d55595a 100644
--- a/drivers/net/wireless/brcm80211/brcmutil/utils.c
+++ b/drivers/net/wireless/brcm80211/brcmutil/utils.c
@@ -439,23 +439,3 @@ int brcmu_format_hex(char *str, const void *bytes, int len)
}
EXPORT_SYMBOL(brcmu_format_hex);
#endif /* defined(BCMDBG) */
-
-uint brcmu_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen)
-{
- uint len;
-
- len = strlen(name) + 1;
-
- if ((len + datalen) > buflen)
- return 0;
-
- strncpy(buf, name, buflen);
-
- /* append data onto the end of the name string */
- memcpy(&buf[len], data, datalen);
- len += datalen;
-
- return len;
-}
-EXPORT_SYMBOL(brcmu_mkiovar);
-
diff --git a/drivers/net/wireless/brcm80211/include/brcmu_utils.h b/drivers/net/wireless/brcm80211/include/brcmu_utils.h
index c19490c..f8664b2 100644
--- a/drivers/net/wireless/brcm80211/include/brcmu_utils.h
+++ b/drivers/net/wireless/brcm80211/include/brcmu_utils.h
@@ -200,7 +200,4 @@ extern int brcmu_format_flags(const struct brcmu_bit_desc *bd, u32 flags,
extern int brcmu_format_hex(char *str, const void *bytes, int len);
#endif

-extern uint brcmu_mkiovar(char *name, char *data, uint datalen,
- char *buf, uint len);
-
#endif /* _BRCMU_UTILS_H_ */
--
1.7.4.1



2011-10-12 18:51:47

by Arend van Spriel

[permalink] [raw]
Subject: [PATCH 18/22] brcm80211: moved function brcmu_parse_tlvs

From: Alwin Beukers <[email protected]>

Moved the brcmu_parse_tlvs function and brcmu_tlv structure into
the only file using them. Names were adjusted accordingly.

Reported-by: Johannes Berg <[email protected]>
Reviewed-by: Roland Vossen <[email protected]>
Reviewed-by: Arend van Spriel <[email protected]>
Signed-off-by: Arend van Spriel <[email protected]>
---
.../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 39 +++++++++++++++++++-
drivers/net/wireless/brcm80211/brcmutil/utils.c | 30 ---------------
.../net/wireless/brcm80211/include/brcmu_utils.h | 10 -----
3 files changed, 37 insertions(+), 42 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index db9176d..857b328 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -247,6 +247,13 @@ static const u32 __wl_cipher_suites[] = {
WLAN_CIPHER_SUITE_AES_CMAC,
};

+/* tag_ID/length/value_buffer tuple */
+struct brcmf_tlv {
+ u8 id;
+ u8 len;
+ u8 data[1];
+};
+
/* Quarter dBm units to mW
* Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
* Table is offset so the last entry is largest mW value that fits in
@@ -2151,11 +2158,39 @@ static bool brcmf_is_ibssmode(struct brcmf_cfg80211_priv *cfg_priv)
return cfg_priv->conf->mode == WL_MODE_IBSS;
}

+/*
+ * Traverse a string of 1-byte tag/1-byte length/variable-length value
+ * triples, returning a pointer to the substring whose first element
+ * matches tag
+ */
+static struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key)
+{
+ struct brcmf_tlv *elt;
+ int totlen;
+
+ elt = (struct brcmf_tlv *) buf;
+ totlen = buflen;
+
+ /* find tagged parameter */
+ while (totlen >= 2) {
+ int len = elt->len;
+
+ /* validate remaining totlen */
+ if ((elt->id == key) && (totlen >= (len + 2)))
+ return elt;
+
+ elt = (struct brcmf_tlv *) ((u8 *) elt + (len + 2));
+ totlen -= (len + 2);
+ }
+
+ return NULL;
+}
+
static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv)
{
struct brcmf_bss_info *bi;
struct brcmf_ssid *ssid;
- struct brcmu_tlv *tim;
+ struct brcmf_tlv *tim;
u16 beacon_interval;
u8 dtim_period;
size_t ie_len;
@@ -2185,7 +2220,7 @@ static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv)
ie_len = le32_to_cpu(bi->ie_length);
beacon_interval = le16_to_cpu(bi->beacon_period);

- tim = brcmu_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
+ tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
if (tim)
dtim_period = tim->data[1];
else {
diff --git a/drivers/net/wireless/brcm80211/brcmutil/utils.c b/drivers/net/wireless/brcm80211/brcmutil/utils.c
index 28480e7..2d903ba 100644
--- a/drivers/net/wireless/brcm80211/brcmutil/utils.c
+++ b/drivers/net/wireless/brcm80211/brcmutil/utils.c
@@ -365,36 +365,6 @@ void brcmu_prpkt(const char *msg, struct sk_buff *p0)
EXPORT_SYMBOL(brcmu_prpkt);
#endif /* defined(BCMDBG) */

-/*
- * Traverse a string of 1-byte tag/1-byte length/variable-length value
- * triples, returning a pointer to the substring whose first element
- * matches tag
- */
-struct brcmu_tlv *brcmu_parse_tlvs(void *buf, int buflen, uint key)
-{
- struct brcmu_tlv *elt;
- int totlen;
-
- elt = (struct brcmu_tlv *) buf;
- totlen = buflen;
-
- /* find tagged parameter */
- while (totlen >= 2) {
- int len = elt->len;
-
- /* validate remaining totlen */
- if ((elt->id == key) && (totlen >= (len + 2)))
- return elt;
-
- elt = (struct brcmu_tlv *) ((u8 *) elt + (len + 2));
- totlen -= (len + 2);
- }
-
- return NULL;
-}
-EXPORT_SYMBOL(brcmu_parse_tlvs);
-
-
#if defined(BCMDBG)
int
brcmu_format_flags(const struct brcmu_bit_desc *bd, u32 flags, char *buf,
diff --git a/drivers/net/wireless/brcm80211/include/brcmu_utils.h b/drivers/net/wireless/brcm80211/include/brcmu_utils.h
index e53883c..c19490c 100644
--- a/drivers/net/wireless/brcm80211/include/brcmu_utils.h
+++ b/drivers/net/wireless/brcm80211/include/brcmu_utils.h
@@ -192,13 +192,6 @@ struct brcmu_bit_desc {
const char *name;
};

-/* tag_ID/length/value_buffer tuple */
-struct brcmu_tlv {
- u8 id;
- u8 len;
- u8 data[1];
-};
-
/* externs */
/* format/print */
#if defined(BCMDBG)
@@ -207,9 +200,6 @@ extern int brcmu_format_flags(const struct brcmu_bit_desc *bd, u32 flags,
extern int brcmu_format_hex(char *str, const void *bytes, int len);
#endif

-extern struct brcmu_tlv *brcmu_parse_tlvs(void *buf, int buflen,
- uint key);
-
extern uint brcmu_mkiovar(char *name, char *data, uint datalen,
char *buf, uint len);

--
1.7.4.1



2011-10-12 19:28:58

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 22/22] brcm80211: removed file wifi.c

On Wed, 2011-10-12 at 21:20 +0200, Arend van Spriel wrote:
> On 10/12/2011 09:13 PM, Johannes Berg wrote:
> > On Wed, 2011-10-12 at 20:51 +0200, Arend van Spriel wrote:
> >
> >> -#include <brcmu_wifi.h>
> >
> > Does that header file have any content left?
> >
> > johannes
> >
> >
>
> It has, but we intend to get rid of brcmutil

Ok, I didn't check :)

> although the pktq functions
> are giving me a headache or it is due to the cold I caught.

Oh. Hope you feel better soon!

johannes


2011-10-12 18:51:51

by Arend van Spriel

[permalink] [raw]
Subject: [PATCH 21/22] brcm80211: moved function brcmu_format_flags

From: Alwin Beukers <[email protected]>

Moved the brcmu_format_flags function and brcmu_bit_desc structure
into smac. Names were adjusted accordingly.

Reported-by: Johannes Berg <[email protected]>
Reviewed-by: Roland Vossen <[email protected]>
Reviewed-by: Arend van Spriel <[email protected]>
Signed-off-by: Arend van Spriel <[email protected]>
---
drivers/net/wireless/brcm80211/brcmsmac/main.c | 66 +++++++++++++++++++-
drivers/net/wireless/brcm80211/brcmutil/utils.c | 55 ----------------
.../net/wireless/brcm80211/include/brcmu_utils.h | 8 ---
3 files changed, 64 insertions(+), 65 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index cce6228..510e9bb 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -325,6 +325,12 @@ static u16 frametype(u32 rspec, u8 mimoframe)
*/
#define SSID_FMT_BUF_LEN ((4 * IEEE80211_MAX_SSID_LEN) + 1)

+/* brcmu_format_flags() bit description structure */
+struct brcms_c_bit_desc {
+ u32 bit;
+ const char *name;
+};
+
/*
* The following table lists the buffer memory allocated to xmt fifos in HW.
* the size is in units of 256bytes(one block), total size is HW dependent
@@ -6152,6 +6158,62 @@ void brcms_c_print_txdesc(struct d11txh *txh)
#endif /* defined(BCMDBG) */

#if defined(BCMDBG)
+int
+brcms_c_format_flags(const struct brcms_c_bit_desc *bd, u32 flags, char *buf,
+ int len)
+{
+ int i;
+ char *p = buf;
+ char hexstr[16];
+ int slen = 0, nlen = 0;
+ u32 bit;
+ const char *name;
+
+ if (len < 2 || !buf)
+ return 0;
+
+ buf[0] = '\0';
+
+ for (i = 0; flags != 0; i++) {
+ bit = bd[i].bit;
+ name = bd[i].name;
+ if (bit == 0 && flags != 0) {
+ /* print any unnamed bits */
+ snprintf(hexstr, 16, "0x%X", flags);
+ name = hexstr;
+ flags = 0; /* exit loop */
+ } else if ((flags & bit) == 0)
+ continue;
+ flags &= ~bit;
+ nlen = strlen(name);
+ slen += nlen;
+ /* count btwn flag space */
+ if (flags != 0)
+ slen += 1;
+ /* need NULL char as well */
+ if (len <= slen)
+ break;
+ /* copy NULL char but don't count it */
+ strncpy(p, name, nlen + 1);
+ p += nlen;
+ /* copy btwn flag space and NULL char */
+ if (flags != 0)
+ p += snprintf(p, 2, " ");
+ len -= slen;
+ }
+
+ /* indicate the str was too short */
+ if (flags != 0) {
+ if (len < 2)
+ p -= 2 - len; /* overwrite last char */
+ p += snprintf(p, 2, ">");
+ }
+
+ return (int)(p - buf);
+}
+#endif /* defined(BCMDBG) */
+
+#if defined(BCMDBG)
void brcms_c_print_rxh(struct d11rxhdr *rxh)
{
u16 len = rxh->RxFrameSize;
@@ -6163,7 +6225,7 @@ void brcms_c_print_rxh(struct d11rxhdr *rxh)
u16 macstatus2 = rxh->RxStatus2;
char flagstr[64];
char lenbuf[20];
- static const struct brcmu_bit_desc macstat_flags[] = {
+ static const struct brcms_c_bit_desc macstat_flags[] = {
{RXS_FCSERR, "FCSErr"},
{RXS_RESPFRAMETX, "Reply"},
{RXS_PBPRES, "PADDING"},
@@ -6177,7 +6239,7 @@ void brcms_c_print_rxh(struct d11rxhdr *rxh)
print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, rxh,
sizeof(struct d11rxhdr));

- brcmu_format_flags(macstat_flags, macstatus1, flagstr, 64);
+ brcms_c_format_flags(macstat_flags, macstatus1, flagstr, 64);

snprintf(lenbuf, sizeof(lenbuf), "0x%x", len);

diff --git a/drivers/net/wireless/brcm80211/brcmutil/utils.c b/drivers/net/wireless/brcm80211/brcmutil/utils.c
index d55595a..f27c489 100644
--- a/drivers/net/wireless/brcm80211/brcmutil/utils.c
+++ b/drivers/net/wireless/brcm80211/brcmutil/utils.c
@@ -366,61 +366,6 @@ EXPORT_SYMBOL(brcmu_prpkt);
#endif /* defined(BCMDBG) */

#if defined(BCMDBG)
-int
-brcmu_format_flags(const struct brcmu_bit_desc *bd, u32 flags, char *buf,
- int len)
-{
- int i;
- char *p = buf;
- char hexstr[16];
- int slen = 0, nlen = 0;
- u32 bit;
- const char *name;
-
- if (len < 2 || !buf)
- return 0;
-
- buf[0] = '\0';
-
- for (i = 0; flags != 0; i++) {
- bit = bd[i].bit;
- name = bd[i].name;
- if (bit == 0 && flags != 0) {
- /* print any unnamed bits */
- snprintf(hexstr, 16, "0x%X", flags);
- name = hexstr;
- flags = 0; /* exit loop */
- } else if ((flags & bit) == 0)
- continue;
- flags &= ~bit;
- nlen = strlen(name);
- slen += nlen;
- /* count btwn flag space */
- if (flags != 0)
- slen += 1;
- /* need NULL char as well */
- if (len <= slen)
- break;
- /* copy NULL char but don't count it */
- strncpy(p, name, nlen + 1);
- p += nlen;
- /* copy btwn flag space and NULL char */
- if (flags != 0)
- p += snprintf(p, 2, " ");
- len -= slen;
- }
-
- /* indicate the str was too short */
- if (flags != 0) {
- if (len < 2)
- p -= 2 - len; /* overwrite last char */
- p += snprintf(p, 2, ">");
- }
-
- return (int)(p - buf);
-}
-EXPORT_SYMBOL(brcmu_format_flags);
-
/*
* print bytes formatted as hex to a string. return the resulting
* string length
diff --git a/drivers/net/wireless/brcm80211/include/brcmu_utils.h b/drivers/net/wireless/brcm80211/include/brcmu_utils.h
index f8664b2..7d0f46e 100644
--- a/drivers/net/wireless/brcm80211/include/brcmu_utils.h
+++ b/drivers/net/wireless/brcm80211/include/brcmu_utils.h
@@ -186,17 +186,9 @@ extern void brcmu_prpkt(const char *msg, struct sk_buff *p0);
#define brcmu_prpkt(a, b)
#endif /* BCMDBG */

-/* brcmu_format_flags() bit description structure */
-struct brcmu_bit_desc {
- u32 bit;
- const char *name;
-};
-
/* externs */
/* format/print */
#if defined(BCMDBG)
-extern int brcmu_format_flags(const struct brcmu_bit_desc *bd, u32 flags,
- char *buf, int len);
extern int brcmu_format_hex(char *str, const void *bytes, int len);
#endif

--
1.7.4.1



2011-10-12 19:13:44

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 22/22] brcm80211: removed file wifi.c

On Wed, 2011-10-12 at 20:51 +0200, Arend van Spriel wrote:

> -#include <brcmu_wifi.h>

Does that header file have any content left?

johannes


2011-10-12 18:51:51

by Arend van Spriel

[permalink] [raw]
Subject: [PATCH 14/22] brcm80211: fmac: fixed weird indentation

From: Roland Vossen <[email protected]>

And changed function name to something more appropriate.

Reported-by: Johannes Berg <[email protected]>
Reviewed-by: Alwin Beukers <[email protected]>
Reviewed-by: Arend van Spriel <[email protected]>
Signed-off-by: Arend van Spriel <[email protected]>
---
.../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 99 ++++++++++----------
1 files changed, 51 insertions(+), 48 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 1b09be0..27a748e 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -1152,7 +1152,7 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
}

static s32
-brcmf_set_set_sharedkey(struct net_device *ndev,
+brcmf_set_wep_sharedkey(struct net_device *ndev,
struct cfg80211_connect_params *sme)
{
struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
@@ -1162,52 +1162,55 @@ brcmf_set_set_sharedkey(struct net_device *ndev,
s32 err = 0;

WL_CONN("key len (%d)\n", sme->key_len);
- if (sme->key_len) {
- sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
- WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
- sec->wpa_versions, sec->cipher_pairwise);
- if (!
- (sec->wpa_versions & (NL80211_WPA_VERSION_1 |
- NL80211_WPA_VERSION_2))
-&& (sec->cipher_pairwise & (WLAN_CIPHER_SUITE_WEP40 |
- WLAN_CIPHER_SUITE_WEP104))) {
- memset(&key, 0, sizeof(key));
- key.len = (u32) sme->key_len;
- key.index = (u32) sme->key_idx;
- if (key.len > sizeof(key.data)) {
- WL_ERR("Too long key length (%u)\n", key.len);
- return -EINVAL;
- }
- memcpy(key.data, sme->key, key.len);
- key.flags = BRCMF_PRIMARY_KEY;
- switch (sec->cipher_pairwise) {
- case WLAN_CIPHER_SUITE_WEP40:
- key.algo = CRYPTO_ALGO_WEP1;
- break;
- case WLAN_CIPHER_SUITE_WEP104:
- key.algo = CRYPTO_ALGO_WEP128;
- break;
- default:
- WL_ERR("Invalid algorithm (%d)\n",
- sme->crypto.ciphers_pairwise[0]);
- return -EINVAL;
- }
- /* Set the new key/index */
- WL_CONN("key length (%d) key index (%d) algo (%d)\n",
- key.len, key.index, key.algo);
- WL_CONN("key \"%s\"\n", key.data);
- err = send_key_to_dongle(ndev, &key);
- if (err)
- return err;

- if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
- WL_CONN("set auth_type to shared key\n");
- val = 1; /* shared key */
- err = brcmf_dev_intvar_set(ndev, "auth", val);
- if (err) {
- WL_ERR("set auth failed (%d)\n", err);
- return err;
- }
+ if (sme->key_len == 0)
+ return 0;
+
+ sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
+ WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
+ sec->wpa_versions, sec->cipher_pairwise);
+
+ if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
+ return 0;
+
+ if (sec->cipher_pairwise &
+ (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)) {
+ memset(&key, 0, sizeof(key));
+ key.len = (u32) sme->key_len;
+ key.index = (u32) sme->key_idx;
+ if (key.len > sizeof(key.data)) {
+ WL_ERR("Too long key length (%u)\n", key.len);
+ return -EINVAL;
+ }
+ memcpy(key.data, sme->key, key.len);
+ key.flags = BRCMF_PRIMARY_KEY;
+ switch (sec->cipher_pairwise) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ key.algo = CRYPTO_ALGO_WEP1;
+ break;
+ case WLAN_CIPHER_SUITE_WEP104:
+ key.algo = CRYPTO_ALGO_WEP128;
+ break;
+ default:
+ WL_ERR("Invalid algorithm (%d)\n",
+ sme->crypto.ciphers_pairwise[0]);
+ return -EINVAL;
+ }
+ /* Set the new key/index */
+ WL_CONN("key length (%d) key index (%d) algo (%d)\n",
+ key.len, key.index, key.algo);
+ WL_CONN("key \"%s\"\n", key.data);
+ err = send_key_to_dongle(ndev, &key);
+ if (err)
+ return err;
+
+ if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
+ WL_CONN("set auth_type to shared key\n");
+ val = 1; /* shared key */
+ err = brcmf_dev_intvar_set(ndev, "auth", val);
+ if (err) {
+ WL_ERR("set auth failed (%d)\n", err);
+ return err;
}
}
}
@@ -1271,9 +1274,9 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
goto done;
}

- err = brcmf_set_set_sharedkey(ndev, sme);
+ err = brcmf_set_wep_sharedkey(ndev, sme);
if (err) {
- WL_ERR("wl_set_set_sharedkey failed (%d)\n", err);
+ WL_ERR("brcmf_set_wep_sharedkey failed (%d)\n", err);
goto done;
}

--
1.7.4.1



2011-10-12 18:51:51

by Arend van Spriel

[permalink] [raw]
Subject: [PATCH 08/22] brcm80211: fix annotations in TOE configuration functions

The configuration function for the TCP offload engine were not
taking CPU endianess into account. Proper annotations and conversions
have been added.

Reported-by: Johannes Berg <[email protected]>
Reviewed-by: Roland Vossen <[email protected]>
Reviewed-by: Franky (Zhenhui) Lin <[email protected]>
Signed-off-by: Arend van Spriel <[email protected]>
---
.../net/wireless/brcm80211/brcmfmac/dhd_linux.c | 15 ++++++++-------
1 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index fb9f808..b05f177 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -560,6 +560,7 @@ static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev)
static int brcmf_toe_get(struct brcmf_info *drvr_priv, int ifidx, u32 *toe_ol)
{
struct brcmf_dcmd dcmd;
+ __le32 toe_le;
char buf[32];
int ret;

@@ -585,7 +586,8 @@ static int brcmf_toe_get(struct brcmf_info *drvr_priv, int ifidx, u32 *toe_ol)
return ret;
}

- memcpy(toe_ol, buf, sizeof(u32));
+ memcpy(&toe_le, buf, sizeof(u32));
+ *toe_ol = le32_to_cpu(toe_le);
return 0;
}

@@ -595,7 +597,8 @@ static int brcmf_toe_set(struct brcmf_info *drvr_priv, int ifidx, u32 toe_ol)
{
struct brcmf_dcmd dcmd;
char buf[32];
- int toe, ret;
+ int ret;
+ __le32 toe_le = cpu_to_le32(toe_ol);

memset(&dcmd, 0, sizeof(dcmd));

@@ -605,9 +608,8 @@ static int brcmf_toe_set(struct brcmf_info *drvr_priv, int ifidx, u32 toe_ol)
dcmd.set = true;

/* Set toe_ol as requested */
-
strcpy(buf, "toe_ol");
- memcpy(&buf[sizeof("toe_ol")], &toe_ol, sizeof(u32));
+ memcpy(&buf[sizeof("toe_ol")], &toe_le, sizeof(u32));

ret = brcmf_proto_dcmd(&drvr_priv->pub, ifidx, &dcmd, dcmd.len);
if (ret < 0) {
@@ -617,11 +619,10 @@ static int brcmf_toe_set(struct brcmf_info *drvr_priv, int ifidx, u32 toe_ol)
}

/* Enable toe globally only if any components are enabled. */
-
- toe = (toe_ol != 0);
+ toe_le = cpu_to_le32(toe_ol != 0);

strcpy(buf, "toe");
- memcpy(&buf[sizeof("toe")], &toe, sizeof(u32));
+ memcpy(&buf[sizeof("toe")], &toe_le, sizeof(u32));

ret = brcmf_proto_dcmd(&drvr_priv->pub, ifidx, &dcmd, dcmd.len);
if (ret < 0) {
--
1.7.4.1



2011-10-12 21:54:30

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [PATCH 22/22] brcm80211: removed file wifi.c

On Wed, Oct 12, 2011 at 11:51 AM, Arend van Spriel <[email protected]> wrote:
> From: Alwin Beukers <[email protected]>
>
> Wifi.c was empty after previous cleanups, so it was removed.
>
> Reviewed-by: Arend van Spriel <[email protected]>
> Signed-off-by: Arend van Spriel <[email protected]>

Heh, remove Reviewed-by dude.

Luis

2011-10-12 18:51:47

by Arend van Spriel

[permalink] [raw]
Subject: [PATCH 15/22] brcm80211: removed unused functions

From: Alwin Beukers <[email protected]>

Removed brcmu_bitcount, brcmu_mhz2channel, brcmu_chspec_ctlchan.

Reported-by: Johannes Berg <[email protected]>
Reviewed-by: Roland Vossen <[email protected]>
Reviewed-by: Arend van Spriel <[email protected]>
Signed-off-by: Arend van Spriel <[email protected]>
---
drivers/net/wireless/brcm80211/brcmsmac/stf.c | 2 -
drivers/net/wireless/brcm80211/brcmutil/utils.c | 14 ---
drivers/net/wireless/brcm80211/brcmutil/wifi.c | 93 --------------------
.../net/wireless/brcm80211/include/brcmu_utils.h | 1 -
.../net/wireless/brcm80211/include/brcmu_wifi.h | 28 ------
5 files changed, 0 insertions(+), 138 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/stf.c b/drivers/net/wireless/brcm80211/brcmsmac/stf.c
index f1bd1bf..d8f528e 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/stf.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/stf.c
@@ -30,8 +30,6 @@
#define BRCMS_STF_SS_STBC_RX(wlc) (BRCMS_ISNPHY(wlc->band) && \
NREV_GT(wlc->band->phyrev, 3) && NREV_LE(wlc->band->phyrev, 6))

-#define BRCMS_BITSCNT(x) brcmu_bitcount((u8 *)&(x), sizeof(u8))
-
#define NSTS_1 1
#define NSTS_2 2
#define NSTS_3 3
diff --git a/drivers/net/wireless/brcm80211/brcmutil/utils.c b/drivers/net/wireless/brcm80211/brcmutil/utils.c
index e96bdbf..990cb2e 100644
--- a/drivers/net/wireless/brcm80211/brcmutil/utils.c
+++ b/drivers/net/wireless/brcm80211/brcmutil/utils.c
@@ -585,17 +585,3 @@ u8 brcmu_mw_to_qdbm(u16 mw)
}
EXPORT_SYMBOL(brcmu_mw_to_qdbm);

-uint brcmu_bitcount(u8 *bitmap, uint length)
-{
- uint bitcount = 0, i;
- u8 tmp;
- for (i = 0; i < length; i++) {
- tmp = bitmap[i];
- while (tmp) {
- bitcount++;
- tmp &= (tmp - 1);
- }
- }
- return bitcount;
-}
-EXPORT_SYMBOL(brcmu_bitcount);
diff --git a/drivers/net/wireless/brcm80211/brcmutil/wifi.c b/drivers/net/wireless/brcm80211/brcmutil/wifi.c
index 509e25c..e8d3bf2 100644
--- a/drivers/net/wireless/brcm80211/brcmutil/wifi.c
+++ b/drivers/net/wireless/brcm80211/brcmutil/wifi.c
@@ -41,96 +41,3 @@ bool brcmu_chspec_malformed(u16 chanspec)
return false;
}
EXPORT_SYMBOL(brcmu_chspec_malformed);
-
-/*
- * This function returns the channel number that control traffic is being sent
- * on, for legacy channels this is just the channel number, for 40MHZ channels
- * it is the upper or lower 20MHZ sideband depending on the chanspec selected.
- */
-u8 brcmu_chspec_ctlchan(u16 chspec)
-{
- u8 ctl_chan;
-
- /* Is there a sideband ? */
- if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_NONE) {
- return CHSPEC_CHANNEL(chspec);
- } else {
- /*
- * we only support 40MHZ with sidebands. chanspec channel holds
- * the centre frequency, use that and the side band information
- * to reconstruct the control channel number
- */
- if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_UPPER)
- /*
- * control chan is the upper 20 MHZ SB of the
- * 40MHZ channel
- */
- ctl_chan = upper_20_sb(CHSPEC_CHANNEL(chspec));
- else
- /*
- * control chan is the lower 20 MHZ SB of the
- * 40MHZ channel
- */
- ctl_chan = lower_20_sb(CHSPEC_CHANNEL(chspec));
- }
-
- return ctl_chan;
-}
-EXPORT_SYMBOL(brcmu_chspec_ctlchan);
-
-/*
- * Return the channel number for a given frequency and base frequency.
- * The returned channel number is relative to the given base frequency.
- * If the given base frequency is zero, a base frequency of 5 GHz is assumed for
- * frequencies from 5 - 6 GHz, and 2.407 GHz is assumed for 2.4 - 2.5 GHz.
- *
- * Frequency is specified in MHz.
- * The base frequency is specified as (start_factor * 500 kHz).
- * Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_5_G are defined for
- * 2.4 GHz and 5 GHz bands.
- *
- * The returned channel will be in the range [1, 14] in the 2.4 GHz band
- * and [0, 200] otherwise.
- * -1 is returned if the start_factor is WF_CHAN_FACTOR_2_4_G and the
- * frequency is not a 2.4 GHz channel, or if the frequency is not and even
- * multiple of 5 MHz from the base frequency to the base plus 1 GHz.
- *
- * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2
- */
-int brcmu_mhz2channel(uint freq, uint start_factor)
-{
- int ch = -1;
- uint base;
- int offset;
-
- /* take the default channel start frequency */
- if (start_factor == 0) {
- if (freq >= 2400 && freq <= 2500)
- start_factor = WF_CHAN_FACTOR_2_4_G;
- else if (freq >= 5000 && freq <= 6000)
- start_factor = WF_CHAN_FACTOR_5_G;
- }
-
- if (freq == 2484 && start_factor == WF_CHAN_FACTOR_2_4_G)
- return 14;
-
- base = start_factor / 2;
-
- /* check that the frequency is in 1GHz range of the base */
- if ((freq < base) || (freq > base + 1000))
- return -1;
-
- offset = freq - base;
- ch = offset / 5;
-
- /* check that frequency is a 5MHz multiple from the base */
- if (offset != (ch * 5))
- return -1;
-
- /* restricted channel range check for 2.4G */
- if (start_factor == WF_CHAN_FACTOR_2_4_G && (ch < 1 || ch > 13))
- return -1;
-
- return ch;
-}
-EXPORT_SYMBOL(brcmu_mhz2channel);
diff --git a/drivers/net/wireless/brcm80211/include/brcmu_utils.h b/drivers/net/wireless/brcm80211/include/brcmu_utils.h
index a7d3df2..96f05d7 100644
--- a/drivers/net/wireless/brcm80211/include/brcmu_utils.h
+++ b/drivers/net/wireless/brcm80211/include/brcmu_utils.h
@@ -218,6 +218,5 @@ extern u8 brcmu_mw_to_qdbm(u16 mw);

extern uint brcmu_mkiovar(char *name, char *data, uint datalen,
char *buf, uint len);
-extern uint brcmu_bitcount(u8 *bitmap, uint bytelength);

#endif /* _BRCMU_UTILS_H_ */
diff --git a/drivers/net/wireless/brcm80211/include/brcmu_wifi.h b/drivers/net/wireless/brcm80211/include/brcmu_wifi.h
index 452bd42..5b1aca7 100644
--- a/drivers/net/wireless/brcm80211/include/brcmu_wifi.h
+++ b/drivers/net/wireless/brcm80211/include/brcmu_wifi.h
@@ -176,34 +176,6 @@ static inline bool ac_bitmap_tst(u8 bitmap, int prec)
*/
extern bool brcmu_chspec_malformed(u16 chanspec);

-/*
- * This function returns the channel number that control traffic is being sent
- * on, for legacy channels this is just the channel number, for 40MHZ channels
- * it is the upper or lower 20MHZ sideband depending on the chanspec selected.
- */
-extern u8 brcmu_chspec_ctlchan(u16 chspec);
-
-/*
- * Return the channel number for a given frequency and base frequency.
- * The returned channel number is relative to the given base frequency.
- * If the given base frequency is zero, a base frequency of 5 GHz is assumed for
- * frequencies from 5 - 6 GHz, and 2.407 GHz is assumed for 2.4 - 2.5 GHz.
- *
- * Frequency is specified in MHz.
- * The base frequency is specified as (start_factor * 500 kHz).
- * Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_5_G are defined for
- * 2.4 GHz and 5 GHz bands.
- *
- * The returned channel will be in the range [1, 14] in the 2.4 GHz band
- * and [0, 200] otherwise.
- * -1 is returned if the start_factor is WF_CHAN_FACTOR_2_4_G and the
- * frequency is not a 2.4 GHz channel, or if the frequency is not and even
- * multiple of 5 MHz from the base frequency to the base plus 1 GHz.
- *
- * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2
- */
-extern int brcmu_mhz2channel(uint freq, uint start_factor);
-
/* Enumerate crypto algorithms */
#define CRYPTO_ALGO_OFF 0
#define CRYPTO_ALGO_WEP1 1
--
1.7.4.1



2011-10-13 18:30:49

by John W. Linville

[permalink] [raw]
Subject: Re: [PATCH 22/22] brcm80211: removed file wifi.c

On Thu, Oct 13, 2011 at 11:08:15AM -0700, Luis R. Rodriguez wrote:
> On Thu, Oct 13, 2011 at 1:51 AM, Arend van Spriel <[email protected]> wrote:
> > On 10/12/2011 11:54 PM, Luis R. Rodriguez wrote:
> >> On Wed, Oct 12, 2011 at 11:51 AM, Arend van Spriel <[email protected]> wrote:
> >>> From: Alwin Beukers <[email protected]>
> >>>
> >>> Wifi.c was empty after previous cleanups, so it was removed.
> >>>
> >>> Reviewed-by: Arend van Spriel <[email protected]>
> >>> Signed-off-by: Arend van Spriel <[email protected]>
> >>
> >> Heh, remove Reviewed-by dude.
> >>
> >> ? Luis
> >>
> >
> > I had a remark on this in earlier commits. So I am clearly missing the
> > point here. The author submitted this change and others for review to me
> > and I reviewed it as requested. Hence the Reviewed-by: entry.
> >
> > I have been given the task to publish these patches and I sign them off
> > for the "Developer's Certificate of Origin". Hence the Signed-off-by: entry.
> >
> > Is there something wrong with this reasoning?
>
> Yeah this all makes no sense. If someone submits you a patch for you
> to review *and* push upstream you simply add *their* SOB first, and
> then after that your own.

For my $0.02, having both a Reviewed-by and a Signed-off-by looks
a little funny, but it isn't necessarily wrong. The Signed-off-by
really only says that you believe that patch is legally contributed.

Oh, and IANAL...

John
--
John W. Linville Someday the world will need a hero, and you
[email protected] might be all we have. Be ready.

2011-10-13 18:08:36

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [PATCH 22/22] brcm80211: removed file wifi.c

On Thu, Oct 13, 2011 at 1:51 AM, Arend van Spriel <[email protected]> wrote:
> On 10/12/2011 11:54 PM, Luis R. Rodriguez wrote:
>> On Wed, Oct 12, 2011 at 11:51 AM, Arend van Spriel <[email protected]> wrote:
>>> From: Alwin Beukers <[email protected]>
>>>
>>> Wifi.c was empty after previous cleanups, so it was removed.
>>>
>>> Reviewed-by: Arend van Spriel <[email protected]>
>>> Signed-off-by: Arend van Spriel <[email protected]>
>>
>> Heh, remove Reviewed-by dude.
>>
>>   Luis
>>
>
> I had a remark on this in earlier commits. So I am clearly missing the
> point here. The author submitted this change and others for review to me
> and I reviewed it as requested. Hence the Reviewed-by: entry.
>
> I have been given the task to publish these patches and I sign them off
> for the "Developer's Certificate of Origin". Hence the Signed-off-by: entry.
>
> Is there something wrong with this reasoning?

Yeah this all makes no sense. If someone submits you a patch for you
to review *and* push upstream you simply add *their* SOB first, and
then after that your own.

Luis

2011-10-12 18:51:51

by Arend van Spriel

[permalink] [raw]
Subject: [PATCH 02/22] brcm80211: smac: decreased timer callback irq level

From: Roland Vossen <[email protected]>

Timer functions were called at soft-irq level, leading to the limitation
that mutexes could not be used. Lifted this limitation by migrating to
work queues.

Reviewed-by: Alwin Beukers <[email protected]>
Reviewed-by: Arend van Spriel <[email protected]>
Signed-off-by: Arend van Spriel <[email protected]>
---
.../net/wireless/brcm80211/brcmsmac/mac80211_if.c | 40 ++++++++-----------
.../net/wireless/brcm80211/brcmsmac/mac80211_if.h | 12 +++--
2 files changed, 24 insertions(+), 28 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
index b665aaf..6ce773a 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -1409,18 +1409,22 @@ void brcms_down(struct brcms_info *wl)
/*
* precondition: perimeter lock is not acquired
*/
-void brcms_timer(struct brcms_timer *t)
+static void _brcms_timer(struct work_struct *work)
{
+ struct brcms_timer *t = container_of(work, struct brcms_timer,
+ dly_wrk.work);
+
spin_lock_bh(&t->wl->lock);

if (t->set) {
if (t->periodic) {
- t->timer.expires = jiffies + t->ms * HZ / 1000;
atomic_inc(&t->wl->callbacks);
- add_timer(&t->timer);
- t->set = true;
- } else
+ ieee80211_queue_delayed_work(t->wl->pub->ieee_hw,
+ &t->dly_wrk,
+ msecs_to_jiffies(t->ms));
+ } else {
t->set = false;
+ }

t->fn(t->arg);
}
@@ -1431,14 +1435,6 @@ void brcms_timer(struct brcms_timer *t)
}

/*
- * is called by the kernel from software irq context
- */
-static void _brcms_timer(unsigned long data)
-{
- brcms_timer((struct brcms_timer *) data);
-}
-
-/*
* Adds a timer to the list. Caller supplies a timer function.
* Is called from wlc.
*
@@ -1454,9 +1450,7 @@ struct brcms_timer *brcms_init_timer(struct brcms_info *wl,
if (!t)
return NULL;

- init_timer(&t->timer);
- t->timer.data = (unsigned long) t;
- t->timer.function = _brcms_timer;
+ INIT_DELAYED_WORK(&t->dly_wrk, _brcms_timer);
t->wl = wl;
t->fn = fn;
t->arg = arg;
@@ -1478,22 +1472,22 @@ struct brcms_timer *brcms_init_timer(struct brcms_info *wl,
*
* precondition: perimeter lock has been acquired
*/
-void brcms_add_timer(struct brcms_timer *t, uint ms,
- int periodic)
+void brcms_add_timer(struct brcms_timer *t, uint ms, int periodic)
{
+ struct ieee80211_hw *hw = t->wl->pub->ieee_hw;
+
#ifdef BCMDBG
if (t->set)
- wiphy_err(t->wl->wiphy, "%s: Already set. Name: %s, per %d\n",
+ wiphy_err(hw->wiphy, "%s: Already set. Name: %s, per %d\n",
__func__, t->name, periodic);
-
#endif
t->ms = ms;
t->periodic = (bool) periodic;
t->set = true;
- t->timer.expires = jiffies + ms * HZ / 1000;

atomic_inc(&t->wl->callbacks);
- add_timer(&t->timer);
+
+ ieee80211_queue_delayed_work(hw, &t->dly_wrk, msecs_to_jiffies(ms));
}

/*
@@ -1505,7 +1499,7 @@ bool brcms_del_timer(struct brcms_timer *t)
{
if (t->set) {
t->set = false;
- if (!del_timer(&t->timer))
+ if (!cancel_delayed_work(&t->dly_wrk))
return false;

atomic_dec(&t->wl->callbacks);
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
index 91e5f2a..177f0e4 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
@@ -19,6 +19,8 @@

#include <linux/timer.h>
#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+
#include "ucode_loader.h"
/*
* Starting index for 5G rates in the
@@ -30,14 +32,14 @@
#define BRCMS_SET_SHORTSLOT_OVERRIDE 146

struct brcms_timer {
- struct timer_list timer;
+ struct delayed_work dly_wrk;
struct brcms_info *wl;
- void (*fn) (void *);
- void *arg; /* argument to fn */
+ void (*fn) (void *); /* function called upon expiration */
+ void *arg; /* fixed argument provided to called function */
uint ms;
bool periodic;
- bool set;
- struct brcms_timer *next;
+ bool set; /* indicates if timer is active */
+ struct brcms_timer *next; /* for freeing on unload */
#ifdef BCMDBG
char *name; /* Description of the timer */
#endif
--
1.7.4.1



2011-10-12 18:51:51

by Arend van Spriel

[permalink] [raw]
Subject: [PATCH 17/22] brcm80211: moved function brcmu_chipname

From: Alwin Beukers <[email protected]>

Moved the brcmu_chipname function into the only file using it.
The function name was adjusted accordingly.

Reported-by: Johannes Berg <[email protected]>
Reviewed-by: Roland Vossen <[email protected]>
Reviewed-by: Arend van Spriel <[email protected]>
Signed-off-by: Arend van Spriel <[email protected]>
---
drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 11 ++++++++++-
drivers/net/wireless/brcm80211/brcmutil/utils.c | 10 ----------
.../net/wireless/brcm80211/include/brcmu_utils.h | 2 --
3 files changed, 10 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index bd9db48..313b8bf 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -3992,6 +3992,15 @@ static const struct sdiod_drive_str sdiod_drive_strength_tab3[] = {

#define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu))

+static char *brcmf_chipname(uint chipid, char *buf, uint len)
+{
+ const char *fmt;
+
+ fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x";
+ snprintf(buf, len, fmt, chipid);
+ return buf;
+}
+
static void brcmf_sdbrcm_sdiod_drive_strength_init(struct brcmf_bus *bus,
u32 drivestrength) {
struct sdiod_drive_str *str_tab = NULL;
@@ -4021,7 +4030,7 @@ static void brcmf_sdbrcm_sdiod_drive_strength_init(struct brcmf_bus *bus,
break;
default:
brcmf_dbg(ERROR, "No SDIO Drive strength init done for chip %s rev %d pmurev %d\n",
- brcmu_chipname(bus->ci->chip, chn, 8),
+ brcmf_chipname(bus->ci->chip, chn, 8),
bus->ci->chiprev, bus->ci->pmurev);
break;
}
diff --git a/drivers/net/wireless/brcm80211/brcmutil/utils.c b/drivers/net/wireless/brcm80211/brcmutil/utils.c
index 7f53a70..28480e7 100644
--- a/drivers/net/wireless/brcm80211/brcmutil/utils.c
+++ b/drivers/net/wireless/brcm80211/brcmutil/utils.c
@@ -470,16 +470,6 @@ int brcmu_format_hex(char *str, const void *bytes, int len)
EXPORT_SYMBOL(brcmu_format_hex);
#endif /* defined(BCMDBG) */

-char *brcmu_chipname(uint chipid, char *buf, uint len)
-{
- const char *fmt;
-
- fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x";
- snprintf(buf, len, fmt, chipid);
- return buf;
-}
-EXPORT_SYMBOL(brcmu_chipname);
-
uint brcmu_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen)
{
uint len;
diff --git a/drivers/net/wireless/brcm80211/include/brcmu_utils.h b/drivers/net/wireless/brcm80211/include/brcmu_utils.h
index d716cd2..e53883c 100644
--- a/drivers/net/wireless/brcm80211/include/brcmu_utils.h
+++ b/drivers/net/wireless/brcm80211/include/brcmu_utils.h
@@ -207,8 +207,6 @@ extern int brcmu_format_flags(const struct brcmu_bit_desc *bd, u32 flags,
extern int brcmu_format_hex(char *str, const void *bytes, int len);
#endif

-extern char *brcmu_chipname(uint chipid, char *buf, uint len);
-
extern struct brcmu_tlv *brcmu_parse_tlvs(void *buf, int buflen,
uint key);

--
1.7.4.1



2011-10-12 18:51:51

by Arend van Spriel

[permalink] [raw]
Subject: [PATCH 10/22] brcm80211: use endian annotation for pmk related structure

The pairwise master key configuration is sent to the device. The
structure has been annotated for endianess checking.

Reported-by: Johannes Berg <[email protected]>
Reviewed-by: Roland Vossen <[email protected]>
Reviewed-by: Franky (Zhenhui) Lin <[email protected]>
Signed-off-by: Arend van Spriel <[email protected]>
---
.../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 34 ++++++++++++-------
.../net/wireless/brcm80211/include/brcmu_wifi.h | 2 +-
2 files changed, 22 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 1218ed7..9e69cd7 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -2467,9 +2467,12 @@ brcmf_update_pmklist(struct net_device *ndev,
struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
{
int i, j;
+ int pmkid_len;

- WL_CONN("No of elements %d\n", pmk_list->pmkids.npmkid);
- for (i = 0; i < pmk_list->pmkids.npmkid; i++) {
+ pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
+
+ WL_CONN("No of elements %d\n", pmkid_len);
+ for (i = 0; i < pmkid_len; i++) {
WL_CONN("PMKID[%d]: %pM =\n", i,
&pmk_list->pmkids.pmkid[i].BSSID);
for (j = 0; j < WLAN_PMKID_LEN; j++)
@@ -2491,26 +2494,30 @@ brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
struct pmkid_list *pmkids = &cfg_priv->pmk_list->pmkids;
s32 err = 0;
int i;
+ int pmkid_len;

WL_TRACE("Enter\n");
if (!check_sys_up(wiphy))
return -EIO;

- for (i = 0; i < pmkids->npmkid; i++)
+ pmkid_len = le32_to_cpu(pmkids->npmkid);
+ for (i = 0; i < pmkid_len; i++)
if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
break;
if (i < WL_NUM_PMKIDS_MAX) {
memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
- if (i == pmkids->npmkid)
- pmkids->npmkid++;
+ if (i == pmkid_len) {
+ pmkid_len++;
+ pmkids->npmkid = cpu_to_le32(pmkid_len);
+ }
} else
err = -EINVAL;

WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
- pmkids->pmkid[pmkids->npmkid].BSSID);
+ pmkids->pmkid[pmkid_len].BSSID);
for (i = 0; i < WLAN_PMKID_LEN; i++)
- WL_CONN("%02x\n", pmkids->pmkid[pmkids->npmkid].PMKID[i]);
+ WL_CONN("%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);

err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);

@@ -2525,7 +2532,7 @@ brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
struct pmkid_list pmkid;
s32 err = 0;
- int i;
+ int i, pmkid_len;

WL_TRACE("Enter\n");
if (!check_sys_up(wiphy))
@@ -2539,17 +2546,18 @@ brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
for (i = 0; i < WLAN_PMKID_LEN; i++)
WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);

- for (i = 0; i < cfg_priv->pmk_list->pmkids.npmkid; i++)
+ pmkid_len = le32_to_cpu(cfg_priv->pmk_list->pmkids.npmkid);
+ for (i = 0; i < pmkid_len; i++)
if (!memcmp
(pmksa->bssid, &cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
ETH_ALEN))
break;

- if ((cfg_priv->pmk_list->pmkids.npmkid > 0)
- && (i < cfg_priv->pmk_list->pmkids.npmkid)) {
+ if ((pmkid_len > 0)
+ && (i < pmkid_len)) {
memset(&cfg_priv->pmk_list->pmkids.pmkid[i], 0,
sizeof(struct pmkid));
- for (; i < (cfg_priv->pmk_list->pmkids.npmkid - 1); i++) {
+ for (; i < (pmkid_len - 1); i++) {
memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
&cfg_priv->pmk_list->pmkids.pmkid[i + 1].BSSID,
ETH_ALEN);
@@ -2557,7 +2565,7 @@ brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
&cfg_priv->pmk_list->pmkids.pmkid[i + 1].PMKID,
WLAN_PMKID_LEN);
}
- cfg_priv->pmk_list->pmkids.npmkid--;
+ cfg_priv->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
} else
err = -EINVAL;

diff --git a/drivers/net/wireless/brcm80211/include/brcmu_wifi.h b/drivers/net/wireless/brcm80211/include/brcmu_wifi.h
index e98ed50..452bd42 100644
--- a/drivers/net/wireless/brcm80211/include/brcmu_wifi.h
+++ b/drivers/net/wireless/brcm80211/include/brcmu_wifi.h
@@ -258,7 +258,7 @@ struct pmkid {
};

struct pmkid_list {
- u32 npmkid;
+ __le32 npmkid;
struct pmkid pmkid[1];
};

--
1.7.4.1



2011-10-12 18:51:47

by Arend van Spriel

[permalink] [raw]
Subject: [PATCH 03/22] brcm80211: cleanup function prototypes

From: Alwin Beukers <[email protected]>

- removed unneeded fn prototypes from include files.
- explicitly marked fn prototypes as extern in include files.
- reordered functions to account for removed forward declarations
in include files.
- removed unused functions: brcms_c_txflowcontrol_override,
brcms_c_txflowcontrol_prio_isset, brcms_c_txflowcontrol.

Reviewed-by: Roland Vossen <[email protected]>
Reviewed-by: Arend van Spriel <[email protected]>
Signed-off-by: Arend van Spriel <[email protected]>
---
drivers/net/wireless/brcm80211/brcmsmac/main.c | 3425 ++++++++++++------------
drivers/net/wireless/brcm80211/brcmsmac/main.h | 84 -
drivers/net/wireless/brcm80211/brcmsmac/pub.h | 49 +-
3 files changed, 1663 insertions(+), 1895 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index 665bf80..cce6228 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -343,53 +343,6 @@ struct d11init {
__le32 value;
};

-/* currently the best mechanism for determining SIFS is the band in use */
-static u16 get_sifs(struct brcms_band *band)
-{
- return band->bandtype == BRCM_BAND_5G ? APHY_SIFS_TIME :
- BPHY_SIFS_TIME;
-}
-
-
-/*
- * Detect Card removed.
- * Even checking an sbconfig register read will not false trigger when the core
- * is in reset it breaks CF address mechanism. Accessing gphy phyversion will
- * cause SB error if aphy is in reset on 4306B0-DB. Need a simple accessible
- * reg with fixed 0/1 pattern (some platforms return all 0).
- * If clocks are present, call the sb routine which will figure out if the
- * device is removed.
- */
-static bool brcms_deviceremoved(struct brcms_c_info *wlc)
-{
- if (!wlc->hw->clk)
- return ai_deviceremoved(wlc->hw->sih);
- return (R_REG(&wlc->hw->regs->maccontrol) &
- (MCTL_PSM_JMP_0 | MCTL_IHR_EN)) != MCTL_IHR_EN;
-}
-
-/* sum the individual fifo tx pending packet counts */
-static s16 brcms_txpktpendtot(struct brcms_c_info *wlc)
-{
- return wlc->core->txpktpend[0] + wlc->core->txpktpend[1] +
- wlc->core->txpktpend[2] + wlc->core->txpktpend[3];
-}
-
-static bool brcms_is_mband_unlocked(struct brcms_c_info *wlc)
-{
- return wlc->pub->_nbands > 1 && !wlc->bandlocked;
-}
-
-static int brcms_chspec_bw(u16 chanspec)
-{
- if (CHSPEC_IS40(chanspec))
- return BRCMS_40_MHZ;
- if (CHSPEC_IS20(chanspec))
- return BRCMS_20_MHZ;
-
- return BRCMS_10_MHZ;
-}
-
struct edcf_acparam {
u8 ACI;
u8 ECW;
@@ -465,6 +418,66 @@ static const char fifo_names[6][0];
static struct brcms_c_info *wlc_info_dbg = (struct brcms_c_info *) (NULL);
#endif

+/* currently the best mechanism for determining SIFS is the band in use */
+static u16 get_sifs(struct brcms_band *band)
+{
+ return band->bandtype == BRCM_BAND_5G ? APHY_SIFS_TIME :
+ BPHY_SIFS_TIME;
+}
+
+/*
+ * Detect Card removed.
+ * Even checking an sbconfig register read will not false trigger when the core
+ * is in reset it breaks CF address mechanism. Accessing gphy phyversion will
+ * cause SB error if aphy is in reset on 4306B0-DB. Need a simple accessible
+ * reg with fixed 0/1 pattern (some platforms return all 0).
+ * If clocks are present, call the sb routine which will figure out if the
+ * device is removed.
+ */
+static bool brcms_deviceremoved(struct brcms_c_info *wlc)
+{
+ if (!wlc->hw->clk)
+ return ai_deviceremoved(wlc->hw->sih);
+ return (R_REG(&wlc->hw->regs->maccontrol) &
+ (MCTL_PSM_JMP_0 | MCTL_IHR_EN)) != MCTL_IHR_EN;
+}
+
+/* sum the individual fifo tx pending packet counts */
+static s16 brcms_txpktpendtot(struct brcms_c_info *wlc)
+{
+ return wlc->core->txpktpend[0] + wlc->core->txpktpend[1] +
+ wlc->core->txpktpend[2] + wlc->core->txpktpend[3];
+}
+
+static bool brcms_is_mband_unlocked(struct brcms_c_info *wlc)
+{
+ return wlc->pub->_nbands > 1 && !wlc->bandlocked;
+}
+
+static int brcms_chspec_bw(u16 chanspec)
+{
+ if (CHSPEC_IS40(chanspec))
+ return BRCMS_40_MHZ;
+ if (CHSPEC_IS20(chanspec))
+ return BRCMS_20_MHZ;
+
+ return BRCMS_10_MHZ;
+}
+
+/*
+ * return true if Minimum Power Consumption should
+ * be entered, false otherwise
+ */
+static bool brcms_c_is_non_delay_mpc(struct brcms_c_info *wlc)
+{
+ return false;
+}
+
+static bool brcms_c_ismpc(struct brcms_c_info *wlc)
+{
+ return (wlc->mpc_delay_off == 0) && (brcms_c_is_non_delay_mpc(wlc));
+}
+
static void brcms_c_bsscfg_mfree(struct brcms_bss_cfg *cfg)
{
if (cfg == NULL)
@@ -646,6 +659,79 @@ static void brcms_b_update_slot_timing(struct brcms_hardware *wlc_hw,
}
}

+/*
+ * calculate frame duration of a given rate and length, return
+ * time in usec unit
+ */
+uint
+brcms_c_calc_frame_time(struct brcms_c_info *wlc, u32 ratespec,
+ u8 preamble_type, uint mac_len)
+{
+ uint nsyms, dur = 0, Ndps, kNdps;
+ uint rate = rspec2rate(ratespec);
+
+ if (rate == 0) {
+ wiphy_err(wlc->wiphy, "wl%d: WAR: using rate of 1 mbps\n",
+ wlc->pub->unit);
+ rate = BRCM_RATE_1M;
+ }
+
+ BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, len%d\n",
+ wlc->pub->unit, ratespec, preamble_type, mac_len);
+
+ if (is_mcs_rate(ratespec)) {
+ uint mcs = ratespec & RSPEC_RATE_MASK;
+ int tot_streams = mcs_2_txstreams(mcs) + rspec_stc(ratespec);
+
+ dur = PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT);
+ if (preamble_type == BRCMS_MM_PREAMBLE)
+ dur += PREN_MM_EXT;
+ /* 1000Ndbps = kbps * 4 */
+ kNdps = mcs_2_rate(mcs, rspec_is40mhz(ratespec),
+ rspec_issgi(ratespec)) * 4;
+
+ if (rspec_stc(ratespec) == 0)
+ nsyms =
+ CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
+ APHY_TAIL_NBITS) * 1000, kNdps);
+ else
+ /* STBC needs to have even number of symbols */
+ nsyms =
+ 2 *
+ CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
+ APHY_TAIL_NBITS) * 1000, 2 * kNdps);
+
+ dur += APHY_SYMBOL_TIME * nsyms;
+ if (wlc->band->bandtype == BRCM_BAND_2G)
+ dur += DOT11_OFDM_SIGNAL_EXTENSION;
+ } else if (is_ofdm_rate(rate)) {
+ dur = APHY_PREAMBLE_TIME;
+ dur += APHY_SIGNAL_TIME;
+ /* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */
+ Ndps = rate * 2;
+ /* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */
+ nsyms =
+ CEIL((APHY_SERVICE_NBITS + 8 * mac_len + APHY_TAIL_NBITS),
+ Ndps);
+ dur += APHY_SYMBOL_TIME * nsyms;
+ if (wlc->band->bandtype == BRCM_BAND_2G)
+ dur += DOT11_OFDM_SIGNAL_EXTENSION;
+ } else {
+ /*
+ * calc # bits * 2 so factor of 2 in rate (1/2 mbps)
+ * will divide out
+ */
+ mac_len = mac_len * 8 * 2;
+ /* calc ceiling of bits/rate = microseconds of air time */
+ dur = (mac_len + rate - 1) / rate;
+ if (preamble_type & BRCMS_SHORT_PREAMBLE)
+ dur += BPHY_PLCP_SHORT_TIME;
+ else
+ dur += BPHY_PLCP_TIME;
+ }
+ return dur;
+}
+
static void brcms_c_write_inits(struct brcms_hardware *wlc_hw,
const struct d11init *inits)
{
@@ -740,6 +826,26 @@ static void brcms_b_core_phy_clk(struct brcms_hardware *wlc_hw, bool clk)
}
}

+/* low-level band switch utility routine */
+static void brcms_c_setxband(struct brcms_hardware *wlc_hw, uint bandunit)
+{
+ BCMMSG(wlc_hw->wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
+ bandunit);
+
+ wlc_hw->band = wlc_hw->bandstate[bandunit];
+
+ /*
+ * BMAC_NOTE:
+ * until we eliminate need for wlc->band refs in low level code
+ */
+ wlc_hw->wlc->band = wlc_hw->wlc->bandstate[bandunit];
+
+ /* set gmode core flag */
+ if (wlc_hw->sbclk && !wlc_hw->noreset)
+ ai_core_cflags(wlc_hw->sih, SICF_GMODE,
+ ((bandunit == 0) ? SICF_GMODE : 0));
+}
+
/* switch to new band but leave it inactive */
static u32 brcms_c_setband_inact(struct brcms_c_info *wlc, uint bandunit)
{
@@ -763,107 +869,45 @@ static u32 brcms_c_setband_inact(struct brcms_c_info *wlc, uint bandunit)
return macintmask;
}

-/* Process received frames */
-/*
- * Return true if more frames need to be processed. false otherwise.
- * Param 'bound' indicates max. # frames to process before break out.
- */
+/* process an individual struct tx_status */
static bool
-brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound)
+brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
{
struct sk_buff *p;
- struct sk_buff *head = NULL;
- struct sk_buff *tail = NULL;
- uint n = 0;
- uint bound_limit = bound ? RXBND : -1;
-
- BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
- /* gather received frames */
- while ((p = dma_rx(wlc_hw->di[fifo]))) {
+ uint queue;
+ struct d11txh *txh;
+ struct scb *scb = NULL;
+ bool free_pdu;
+ int tx_rts, tx_frame_count, tx_rts_count;
+ uint totlen, supr_status;
+ bool lastframe;
+ struct ieee80211_hdr *h;
+ u16 mcl;
+ struct ieee80211_tx_info *tx_info;
+ struct ieee80211_tx_rate *txrate;
+ int i;

- if (!tail)
- head = tail = p;
- else {
- tail->prev = p;
- tail = p;
- }
+ /* discard intermediate indications for ucode with one legitimate case:
+ * e.g. if "useRTS" is set. ucode did a successful rts/cts exchange,
+ * but the subsequent tx of DATA failed. so it will start rts/cts
+ * from the beginning (resetting the rts transmission count)
+ */
+ if (!(txs->status & TX_STATUS_AMPDU)
+ && (txs->status & TX_STATUS_INTERMEDIATE)) {
+ wiphy_err(wlc->wiphy, "%s: INTERMEDIATE but not AMPDU\n",
+ __func__);
+ return false;
+ }

- /* !give others some time to run! */
- if (++n >= bound_limit)
- break;
+ queue = txs->frameid & TXFID_QUEUE_MASK;
+ if (queue >= NFIFO) {
+ p = NULL;
+ goto fatal;
}

- /* post more rbufs */
- dma_rxfill(wlc_hw->di[fifo]);
-
- /* process each frame */
- while ((p = head) != NULL) {
- struct d11rxhdr_le *rxh_le;
- struct d11rxhdr *rxh;
- head = head->prev;
- p->prev = NULL;
-
- rxh_le = (struct d11rxhdr_le *)p->data;
- rxh = (struct d11rxhdr *)p->data;
-
- /* fixup rx header endianness */
- rxh->RxFrameSize = le16_to_cpu(rxh_le->RxFrameSize);
- rxh->PhyRxStatus_0 = le16_to_cpu(rxh_le->PhyRxStatus_0);
- rxh->PhyRxStatus_1 = le16_to_cpu(rxh_le->PhyRxStatus_1);
- rxh->PhyRxStatus_2 = le16_to_cpu(rxh_le->PhyRxStatus_2);
- rxh->PhyRxStatus_3 = le16_to_cpu(rxh_le->PhyRxStatus_3);
- rxh->PhyRxStatus_4 = le16_to_cpu(rxh_le->PhyRxStatus_4);
- rxh->PhyRxStatus_5 = le16_to_cpu(rxh_le->PhyRxStatus_5);
- rxh->RxStatus1 = le16_to_cpu(rxh_le->RxStatus1);
- rxh->RxStatus2 = le16_to_cpu(rxh_le->RxStatus2);
- rxh->RxTSFTime = le16_to_cpu(rxh_le->RxTSFTime);
- rxh->RxChan = le16_to_cpu(rxh_le->RxChan);
-
- brcms_c_recv(wlc_hw->wlc, p);
- }
-
- return n >= bound_limit;
-}
-
-/* process an individual struct tx_status */
-static bool
-brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
-{
- struct sk_buff *p;
- uint queue;
- struct d11txh *txh;
- struct scb *scb = NULL;
- bool free_pdu;
- int tx_rts, tx_frame_count, tx_rts_count;
- uint totlen, supr_status;
- bool lastframe;
- struct ieee80211_hdr *h;
- u16 mcl;
- struct ieee80211_tx_info *tx_info;
- struct ieee80211_tx_rate *txrate;
- int i;
-
- /* discard intermediate indications for ucode with one legitimate case:
- * e.g. if "useRTS" is set. ucode did a successful rts/cts exchange,
- * but the subsequent tx of DATA failed. so it will start rts/cts
- * from the beginning (resetting the rts transmission count)
- */
- if (!(txs->status & TX_STATUS_AMPDU)
- && (txs->status & TX_STATUS_INTERMEDIATE)) {
- wiphy_err(wlc->wiphy, "%s: INTERMEDIATE but not AMPDU\n",
- __func__);
- return false;
- }
-
- queue = txs->frameid & TXFID_QUEUE_MASK;
- if (queue >= NFIFO) {
- p = NULL;
- goto fatal;
- }
-
- p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED);
- if (p == NULL)
- goto fatal;
+ p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED);
+ if (p == NULL)
+ goto fatal;

txh = (struct d11txh *) (p->data);
mcl = le16_to_cpu(txh->MacTxControlLow);
@@ -1054,97 +1098,14 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
return morepending;
}

-/* second-level interrupt processing
- * Return true if another dpc needs to be re-scheduled. false otherwise.
- * Param 'bounded' indicates if applicable loops should be bounded.
- */
-bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded)
+static void brcms_c_tbtt(struct brcms_c_info *wlc)
{
- u32 macintstatus;
- struct brcms_hardware *wlc_hw = wlc->hw;
- struct d11regs __iomem *regs = wlc_hw->regs;
- struct wiphy *wiphy = wlc->wiphy;
-
- if (brcms_deviceremoved(wlc)) {
- wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
- __func__);
- brcms_down(wlc->wl);
- return false;
- }
-
- /* grab and clear the saved software intstatus bits */
- macintstatus = wlc->macintstatus;
- wlc->macintstatus = 0;
-
- BCMMSG(wlc->wiphy, "wl%d: macintstatus 0x%x\n",
- wlc_hw->unit, macintstatus);
-
- WARN_ON(macintstatus & MI_PRQ); /* PRQ Interrupt in non-MBSS */
-
- /* tx status */
- if (macintstatus & MI_TFS) {
- bool fatal;
- if (brcms_b_txstatus(wlc->hw, bounded, &fatal))
- wlc->macintstatus |= MI_TFS;
- if (fatal) {
- wiphy_err(wiphy, "MI_TFS: fatal\n");
- goto fatal;
- }
- }
-
- if (macintstatus & (MI_TBTT | MI_DTIM_TBTT))
- brcms_c_tbtt(wlc);
-
- /* ATIM window end */
- if (macintstatus & MI_ATIMWINEND) {
- BCMMSG(wlc->wiphy, "end of ATIM window\n");
- OR_REG(&regs->maccommand, wlc->qvalid);
- wlc->qvalid = 0;
- }
-
- /*
- * received data or control frame, MI_DMAINT is
- * indication of RX_FIFO interrupt
- */
- if (macintstatus & MI_DMAINT)
- if (brcms_b_recv(wlc_hw, RX_FIFO, bounded))
- wlc->macintstatus |= MI_DMAINT;
-
- /* noise sample collected */
- if (macintstatus & MI_BG_NOISE)
- wlc_phy_noise_sample_intr(wlc_hw->band->pi);
-
- if (macintstatus & MI_GP0) {
- wiphy_err(wiphy, "wl%d: PSM microcode watchdog fired at %d "
- "(seconds). Resetting.\n", wlc_hw->unit, wlc_hw->now);
-
- printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n",
- __func__, wlc_hw->sih->chip,
- wlc_hw->sih->chiprev);
- /* big hammer */
- brcms_init(wlc->wl);
- }
-
- /* gptimer timeout */
- if (macintstatus & MI_TO)
- W_REG(&regs->gptimer, 0);
-
- if (macintstatus & MI_RFDISABLE) {
- BCMMSG(wlc->wiphy, "wl%d: BMAC Detected a change on the"
- " RF Disable Input\n", wlc_hw->unit);
- brcms_rfkill_set_hw_state(wlc->wl);
- }
-
- /* send any enq'd tx packets. Just makes sure to jump start tx */
- if (!pktq_empty(&wlc->pkt_queue->q))
- brcms_c_send_q(wlc);
-
- /* it isn't done and needs to be resched if macintstatus is non-zero */
- return wlc->macintstatus != 0;
-
- fatal:
- brcms_init(wlc->wl);
- return wlc->macintstatus != 0;
+ if (!wlc->bsscfg->BSS)
+ /*
+ * DirFrmQ is now valid...defer setting until end
+ * of ATIM window
+ */
+ wlc->qvalid |= MCMD_DIRFRMQVAL;
}

/* set initial host flags value */
@@ -1922,26 +1883,6 @@ static void brcms_b_setband(struct brcms_hardware *wlc_hw, uint bandunit,
WARN_ON((R_REG(&wlc_hw->regs->maccontrol) & MCTL_EN_MAC) != 0);
}

-/* low-level band switch utility routine */
-void brcms_c_setxband(struct brcms_hardware *wlc_hw, uint bandunit)
-{
- BCMMSG(wlc_hw->wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
- bandunit);
-
- wlc_hw->band = wlc_hw->bandstate[bandunit];
-
- /*
- * BMAC_NOTE:
- * until we eliminate need for wlc->band refs in low level code
- */
- wlc_hw->wlc->band = wlc_hw->wlc->bandstate[bandunit];
-
- /* set gmode core flag */
- if (wlc_hw->sbclk && !wlc_hw->noreset)
- ai_core_cflags(wlc_hw->sih, SICF_GMODE,
- ((bandunit == 0) ? SICF_GMODE : 0));
-}
-
static bool brcms_c_isgoodchip(struct brcms_hardware *wlc_hw)
{

@@ -2405,6 +2346,13 @@ void brcms_b_antsel_type_set(struct brcms_hardware *wlc_hw, u8 antsel_type)
wlc_phy_antsel_type_set(wlc_hw->band->pi, antsel_type);
}

+static void brcms_c_fatal_error(struct brcms_c_info *wlc)
+{
+ wiphy_err(wlc->wiphy, "wl%d: fatal error, reinitializing\n",
+ wlc->pub->unit);
+ brcms_init(wlc->wl);
+}
+
static void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw)
{
bool fatal = false;
@@ -2962,7 +2910,7 @@ void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on)
}
}

-void brcms_c_coredisable(struct brcms_hardware *wlc_hw)
+static void brcms_c_coredisable(struct brcms_hardware *wlc_hw)
{
bool dev_gone;

@@ -3106,6 +3054,16 @@ brcms_b_copyfrom_objmem(struct brcms_hardware *wlc_hw, uint offset, void *buf,
}
}

+/* Copy a buffer to shared memory.
+ * SHM 'offset' needs to be an even address and
+ * Buffer length 'len' must be an even number of bytes
+ */
+static void brcms_c_copyto_shm(struct brcms_c_info *wlc, uint offset,
+ const void *buf, int len)
+{
+ brcms_b_copyto_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL);
+}
+
static void brcms_b_retrylimit_upd(struct brcms_hardware *wlc_hw,
u16 SRL, u16 LRL)
{
@@ -3159,7 +3117,7 @@ static void brcms_b_antsel_set(struct brcms_hardware *wlc_hw, u32 antsel_avail)
* conditions under which the PM bit should be set in outgoing frames
* and STAY_AWAKE is meaningful
*/
-bool brcms_c_ps_allowed(struct brcms_c_info *wlc)
+static bool brcms_c_ps_allowed(struct brcms_c_info *wlc)
{
struct brcms_bss_cfg *cfg = wlc->bsscfg;

@@ -3185,6 +3143,58 @@ bool brcms_c_ps_allowed(struct brcms_c_info *wlc)
return true;
}

+static void brcms_c_statsupd(struct brcms_c_info *wlc)
+{
+ int i;
+ struct macstat macstats;
+#ifdef BCMDBG
+ u16 delta;
+ u16 rxf0ovfl;
+ u16 txfunfl[NFIFO];
+#endif /* BCMDBG */
+
+ /* if driver down, make no sense to update stats */
+ if (!wlc->pub->up)
+ return;
+
+#ifdef BCMDBG
+ /* save last rx fifo 0 overflow count */
+ rxf0ovfl = wlc->core->macstat_snapshot->rxf0ovfl;
+
+ /* save last tx fifo underflow count */
+ for (i = 0; i < NFIFO; i++)
+ txfunfl[i] = wlc->core->macstat_snapshot->txfunfl[i];
+#endif /* BCMDBG */
+
+ /* Read mac stats from contiguous shared memory */
+ brcms_b_copyfrom_objmem(wlc->hw, M_UCODE_MACSTAT, &macstats,
+ sizeof(struct macstat), OBJADDR_SHM_SEL);
+
+#ifdef BCMDBG
+ /* check for rx fifo 0 overflow */
+ delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl);
+ if (delta)
+ wiphy_err(wlc->wiphy, "wl%d: %u rx fifo 0 overflows!\n",
+ wlc->pub->unit, delta);
+
+ /* check for tx fifo underflows */
+ for (i = 0; i < NFIFO; i++) {
+ delta =
+ (u16) (wlc->core->macstat_snapshot->txfunfl[i] -
+ txfunfl[i]);
+ if (delta)
+ wiphy_err(wlc->wiphy, "wl%d: %u tx fifo %d underflows!"
+ "\n", wlc->pub->unit, delta, i);
+ }
+#endif /* BCMDBG */
+
+ /* merge counters from dma module */
+ for (i = 0; i < NFIFO; i++) {
+ if (wlc->hw->di[i])
+ dma_counterreset(wlc->hw->di[i]);
+ }
+}
+
static void brcms_b_reset(struct brcms_hardware *wlc_hw)
{
BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
@@ -3211,13 +3221,6 @@ void brcms_c_reset(struct brcms_c_info *wlc)
brcms_b_reset(wlc->hw);
}

-void brcms_c_fatal_error(struct brcms_c_info *wlc)
-{
- wiphy_err(wlc->wiphy, "wl%d: fatal error, reinitializing\n",
- wlc->pub->unit);
- brcms_init(wlc->wl);
-}
-
/* Return the channel the driver should initialize during brcms_c_init.
* the channel may have to be changed from the currently configured channel
* if other configurations are in conflict (bandlocked, 11n mode disabled,
@@ -3494,11 +3497,115 @@ static void brcms_c_set_phy_chanspec(struct brcms_c_info *wlc,
chanspec);

brcms_c_stf_ss_update(wlc, wlc->band);
-
}

-static void brcms_c_bandinit_ordered(struct brcms_c_info *wlc,
- u16 chanspec)
+static void
+brcms_default_rateset(struct brcms_c_info *wlc, struct brcms_c_rateset *rs)
+{
+ brcms_c_rateset_default(rs, NULL, wlc->band->phytype,
+ wlc->band->bandtype, false, BRCMS_RATE_MASK_FULL,
+ (bool) (wlc->pub->_n_enab & SUPPORT_11N),
+ brcms_chspec_bw(wlc->default_bss->chanspec),
+ wlc->stf->txstreams);
+}
+
+/* derive wlc->band->basic_rate[] table from 'rateset' */
+static void brcms_c_rate_lookup_init(struct brcms_c_info *wlc,
+ struct brcms_c_rateset *rateset)
+{
+ u8 rate;
+ u8 mandatory;
+ u8 cck_basic = 0;
+ u8 ofdm_basic = 0;
+ u8 *br = wlc->band->basic_rate;
+ uint i;
+
+ /* incoming rates are in 500kbps units as in 802.11 Supported Rates */
+ memset(br, 0, BRCM_MAXRATE + 1);
+
+ /* For each basic rate in the rates list, make an entry in the
+ * best basic lookup.
+ */
+ for (i = 0; i < rateset->count; i++) {
+ /* only make an entry for a basic rate */
+ if (!(rateset->rates[i] & BRCMS_RATE_FLAG))
+ continue;
+
+ /* mask off basic bit */
+ rate = (rateset->rates[i] & BRCMS_RATE_MASK);
+
+ if (rate > BRCM_MAXRATE) {
+ wiphy_err(wlc->wiphy, "brcms_c_rate_lookup_init: "
+ "invalid rate 0x%X in rate set\n",
+ rateset->rates[i]);
+ continue;
+ }
+
+ br[rate] = rate;
+ }
+
+ /* The rate lookup table now has non-zero entries for each
+ * basic rate, equal to the basic rate: br[basicN] = basicN
+ *
+ * To look up the best basic rate corresponding to any
+ * particular rate, code can use the basic_rate table
+ * like this
+ *
+ * basic_rate = wlc->band->basic_rate[tx_rate]
+ *
+ * Make sure there is a best basic rate entry for
+ * every rate by walking up the table from low rates
+ * to high, filling in holes in the lookup table
+ */
+
+ for (i = 0; i < wlc->band->hw_rateset.count; i++) {
+ rate = wlc->band->hw_rateset.rates[i];
+
+ if (br[rate] != 0) {
+ /* This rate is a basic rate.
+ * Keep track of the best basic rate so far by
+ * modulation type.
+ */
+ if (is_ofdm_rate(rate))
+ ofdm_basic = rate;
+ else
+ cck_basic = rate;
+
+ continue;
+ }
+
+ /* This rate is not a basic rate so figure out the
+ * best basic rate less than this rate and fill in
+ * the hole in the table
+ */
+
+ br[rate] = is_ofdm_rate(rate) ? ofdm_basic : cck_basic;
+
+ if (br[rate] != 0)
+ continue;
+
+ if (is_ofdm_rate(rate)) {
+ /*
+ * In 11g and 11a, the OFDM mandatory rates
+ * are 6, 12, and 24 Mbps
+ */
+ if (rate >= BRCM_RATE_24M)
+ mandatory = BRCM_RATE_24M;
+ else if (rate >= BRCM_RATE_12M)
+ mandatory = BRCM_RATE_12M;
+ else
+ mandatory = BRCM_RATE_6M;
+ } else {
+ /* In 11b, all CCK rates are mandatory 1 - 11 Mbps */
+ mandatory = rate;
+ }
+
+ br[rate] = mandatory;
+ }
+}
+
+static void brcms_c_bandinit_ordered(struct brcms_c_info *wlc,
+ u16 chanspec)
{
struct brcms_c_rateset default_rateset;
uint parkband;
@@ -3543,6 +3650,44 @@ static void brcms_c_bandinit_ordered(struct brcms_c_info *wlc,
brcms_c_set_phy_chanspec(wlc, chanspec);
}

+static void brcms_c_mac_bcn_promisc(struct brcms_c_info *wlc)
+{
+ if (wlc->bcnmisc_monitor)
+ brcms_b_mctrl(wlc->hw, MCTL_BCNS_PROMISC, MCTL_BCNS_PROMISC);
+ else
+ brcms_b_mctrl(wlc->hw, MCTL_BCNS_PROMISC, 0);
+}
+
+void brcms_c_mac_bcn_promisc_change(struct brcms_c_info *wlc, bool promisc)
+{
+ wlc->bcnmisc_monitor = promisc;
+ brcms_c_mac_bcn_promisc(wlc);
+}
+
+/* set or clear maccontrol bits MCTL_PROMISC and MCTL_KEEPCONTROL */
+static void brcms_c_mac_promisc(struct brcms_c_info *wlc)
+{
+ u32 promisc_bits = 0;
+
+ /*
+ * promiscuous mode just sets MCTL_PROMISC
+ * Note: APs get all BSS traffic without the need to set
+ * the MCTL_PROMISC bit since all BSS data traffic is
+ * directed at the AP
+ */
+ if (wlc->pub->promisc)
+ promisc_bits |= MCTL_PROMISC;
+
+ /* monitor mode needs both MCTL_PROMISC and MCTL_KEEPCONTROL
+ * Note: monitor mode also needs MCTL_BCNS_PROMISC, but that is
+ * handled in brcms_c_mac_bcn_promisc()
+ */
+ if (wlc->monitor)
+ promisc_bits |= MCTL_PROMISC | MCTL_KEEPCONTROL;
+
+ brcms_b_mctrl(wlc->hw, MCTL_PROMISC | MCTL_KEEPCONTROL, promisc_bits);
+}
+
/*
* ucode, hwmac update
* Channel dependent updates for ucode and hw
@@ -3576,6 +3721,88 @@ static void brcms_c_ucode_mac_upd(struct brcms_c_info *wlc)
brcms_c_mac_promisc(wlc);
}

+static void brcms_c_write_rate_shm(struct brcms_c_info *wlc, u8 rate,
+ u8 basic_rate)
+{
+ u8 phy_rate, index;
+ u8 basic_phy_rate, basic_index;
+ u16 dir_table, basic_table;
+ u16 basic_ptr;
+
+ /* Shared memory address for the table we are reading */
+ dir_table = is_ofdm_rate(basic_rate) ? M_RT_DIRMAP_A : M_RT_DIRMAP_B;
+
+ /* Shared memory address for the table we are writing */
+ basic_table = is_ofdm_rate(rate) ? M_RT_BBRSMAP_A : M_RT_BBRSMAP_B;
+
+ /*
+ * for a given rate, the LS-nibble of the PLCP SIGNAL field is
+ * the index into the rate table.
+ */
+ phy_rate = rate_info[rate] & BRCMS_RATE_MASK;
+ basic_phy_rate = rate_info[basic_rate] & BRCMS_RATE_MASK;
+ index = phy_rate & 0xf;
+ basic_index = basic_phy_rate & 0xf;
+
+ /* Find the SHM pointer to the ACK rate entry by looking in the
+ * Direct-map Table
+ */
+ basic_ptr = brcms_b_read_shm(wlc->hw, (dir_table + basic_index * 2));
+
+ /* Update the SHM BSS-basic-rate-set mapping table with the pointer
+ * to the correct basic rate for the given incoming rate
+ */
+ brcms_b_write_shm(wlc->hw, (basic_table + index * 2), basic_ptr);
+}
+
+static const struct brcms_c_rateset *
+brcms_c_rateset_get_hwrs(struct brcms_c_info *wlc)
+{
+ const struct brcms_c_rateset *rs_dflt;
+
+ if (BRCMS_PHY_11N_CAP(wlc->band)) {
+ if (wlc->band->bandtype == BRCM_BAND_5G)
+ rs_dflt = &ofdm_mimo_rates;
+ else
+ rs_dflt = &cck_ofdm_mimo_rates;
+ } else if (wlc->band->gmode)
+ rs_dflt = &cck_ofdm_rates;
+ else
+ rs_dflt = &cck_rates;
+
+ return rs_dflt;
+}
+
+static void brcms_c_set_ratetable(struct brcms_c_info *wlc)
+{
+ const struct brcms_c_rateset *rs_dflt;
+ struct brcms_c_rateset rs;
+ u8 rate, basic_rate;
+ uint i;
+
+ rs_dflt = brcms_c_rateset_get_hwrs(wlc);
+
+ brcms_c_rateset_copy(rs_dflt, &rs);
+ brcms_c_rateset_mcs_upd(&rs, wlc->stf->txstreams);
+
+ /* walk the phy rate table and update SHM basic rate lookup table */
+ for (i = 0; i < rs.count; i++) {
+ rate = rs.rates[i] & BRCMS_RATE_MASK;
+
+ /* for a given rate brcms_basic_rate returns the rate at
+ * which a response ACK/CTS should be sent.
+ */
+ basic_rate = brcms_basic_rate(wlc, rate);
+ if (basic_rate == 0)
+ /* This should only happen if we are using a
+ * restricted rateset.
+ */
+ basic_rate = rs.rates[0] & BRCMS_RATE_MASK;
+
+ brcms_c_write_rate_shm(wlc, rate, basic_rate);
+ }
+}
+
/* band-specific init */
static void brcms_c_bsinit(struct brcms_c_info *wlc)
{
@@ -3655,183 +3882,35 @@ static void brcms_c_txflowcontrol_reset(struct brcms_c_info *wlc)
}
}

-void brcms_c_init(struct brcms_c_info *wlc)
+/* push sw hps and wake state through hardware */
+static void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc)
{
- struct d11regs __iomem *regs;
- u16 chanspec;
- bool mute = false;
-
- BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
+ u32 v1, v2;
+ bool hps;
+ bool awake_before;

- regs = wlc->regs;
+ hps = brcms_c_ps_allowed(wlc);

- /*
- * This will happen if a big-hammer was executed. In
- * that case, we want to go back to the channel that
- * we were on and not new channel
- */
- if (wlc->pub->associated)
- chanspec = wlc->home_chanspec;
- else
- chanspec = brcms_c_init_chanspec(wlc);
+ BCMMSG(wlc->wiphy, "wl%d: hps %d\n", wlc->pub->unit, hps);

- brcms_b_init(wlc->hw, chanspec, mute);
+ v1 = R_REG(&wlc->regs->maccontrol);
+ v2 = MCTL_WAKE;
+ if (hps)
+ v2 |= MCTL_HPS;

- /* update beacon listen interval */
- brcms_c_bcn_li_upd(wlc);
+ brcms_b_mctrl(wlc->hw, MCTL_WAKE | MCTL_HPS, v2);

- /* write ethernet address to core */
- brcms_c_set_mac(wlc->bsscfg);
- brcms_c_set_bssid(wlc->bsscfg);
-
- /* Update tsf_cfprep if associated and up */
- if (wlc->pub->associated && wlc->bsscfg->up) {
- u32 bi;
-
- /* get beacon period and convert to uS */
- bi = wlc->bsscfg->current_bss->beacon_period << 10;
- /*
- * update since init path would reset
- * to default value
- */
- W_REG(&regs->tsf_cfprep,
- (bi << CFPREP_CBI_SHIFT));
-
- /* Update maccontrol PM related bits */
- brcms_c_set_ps_ctrl(wlc);
- }
-
- brcms_c_bandinit_ordered(wlc, chanspec);
-
- /* init probe response timeout */
- brcms_b_write_shm(wlc->hw, M_PRS_MAXTIME, wlc->prb_resp_timeout);
-
- /* init max burst txop (framebursting) */
- brcms_b_write_shm(wlc->hw, M_MBURST_TXOP,
- (wlc->
- _rifs ? (EDCF_AC_VO_TXOP_AP << 5) : MAXFRAMEBURST_TXOP));
-
- /* initialize maximum allowed duty cycle */
- brcms_c_duty_cycle_set(wlc, wlc->tx_duty_cycle_ofdm, true, true);
- brcms_c_duty_cycle_set(wlc, wlc->tx_duty_cycle_cck, false, true);
-
- /*
- * Update some shared memory locations related to
- * max AMPDU size allowed to received
- */
- brcms_c_ampdu_shm_upd(wlc->ampdu);
-
- /* band-specific inits */
- brcms_c_bsinit(wlc);
-
- /* Enable EDCF mode (while the MAC is suspended) */
- OR_REG(&regs->ifs_ctl, IFS_USEEDCF);
- brcms_c_edcf_setparams(wlc, false);
-
- /* Init precedence maps for empty FIFOs */
- brcms_c_tx_prec_map_init(wlc);
-
- /* read the ucode version if we have not yet done so */
- if (wlc->ucode_rev == 0) {
- wlc->ucode_rev =
- brcms_b_read_shm(wlc->hw, M_BOM_REV_MAJOR) << NBITS(u16);
- wlc->ucode_rev |= brcms_b_read_shm(wlc->hw, M_BOM_REV_MINOR);
- }
-
- /* ..now really unleash hell (allow the MAC out of suspend) */
- brcms_c_enable_mac(wlc);
-
- /* clear tx flow control */
- brcms_c_txflowcontrol_reset(wlc);
-
- /* enable the RF Disable Delay timer */
- W_REG(&wlc->regs->rfdisabledly, RFDISABLE_DEFAULT);
-
- /* initialize mpc delay */
- wlc->mpc_delay_off = wlc->mpc_dlycnt = BRCMS_MPC_MIN_DELAYCNT;
-
- /*
- * Initialize WME parameters; if they haven't been set by some other
- * mechanism (IOVar, etc) then read them from the hardware.
- */
- if (GFIELD(wlc->wme_retries[0], EDCF_SHORT) == 0) {
- /* Uninitialized; read from HW */
- int ac;
-
- for (ac = 0; ac < AC_COUNT; ac++)
- wlc->wme_retries[ac] =
- brcms_b_read_shm(wlc->hw, M_AC_TXLMT_ADDR(ac));
- }
-}
-
-void brcms_c_mac_bcn_promisc_change(struct brcms_c_info *wlc, bool promisc)
-{
- wlc->bcnmisc_monitor = promisc;
- brcms_c_mac_bcn_promisc(wlc);
-}
-
-void brcms_c_mac_bcn_promisc(struct brcms_c_info *wlc)
-{
- if (wlc->bcnmisc_monitor)
- brcms_b_mctrl(wlc->hw, MCTL_BCNS_PROMISC, MCTL_BCNS_PROMISC);
- else
- brcms_b_mctrl(wlc->hw, MCTL_BCNS_PROMISC, 0);
-}
-
-/* set or clear maccontrol bits MCTL_PROMISC and MCTL_KEEPCONTROL */
-void brcms_c_mac_promisc(struct brcms_c_info *wlc)
-{
- u32 promisc_bits = 0;
-
- /*
- * promiscuous mode just sets MCTL_PROMISC
- * Note: APs get all BSS traffic without the need to set
- * the MCTL_PROMISC bit since all BSS data traffic is
- * directed at the AP
- */
- if (wlc->pub->promisc)
- promisc_bits |= MCTL_PROMISC;
-
- /* monitor mode needs both MCTL_PROMISC and MCTL_KEEPCONTROL
- * Note: monitor mode also needs MCTL_BCNS_PROMISC, but that is
- * handled in brcms_c_mac_bcn_promisc()
- */
- if (wlc->monitor)
- promisc_bits |= MCTL_PROMISC | MCTL_KEEPCONTROL;
-
- brcms_b_mctrl(wlc->hw, MCTL_PROMISC | MCTL_KEEPCONTROL, promisc_bits);
-}
-
-/* push sw hps and wake state through hardware */
-void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc)
-{
- u32 v1, v2;
- bool hps;
- bool awake_before;
-
- hps = brcms_c_ps_allowed(wlc);
-
- BCMMSG(wlc->wiphy, "wl%d: hps %d\n", wlc->pub->unit, hps);
-
- v1 = R_REG(&wlc->regs->maccontrol);
- v2 = MCTL_WAKE;
- if (hps)
- v2 |= MCTL_HPS;
-
- brcms_b_mctrl(wlc->hw, MCTL_WAKE | MCTL_HPS, v2);
-
- awake_before = ((v1 & MCTL_WAKE) || ((v1 & MCTL_HPS) == 0));
+ awake_before = ((v1 & MCTL_WAKE) || ((v1 & MCTL_HPS) == 0));

if (!awake_before)
brcms_b_wait_for_wake(wlc->hw);
-
}

/*
* Write this BSS config's MAC address to core.
* Updates RXE match engine.
*/
-int brcms_c_set_mac(struct brcms_bss_cfg *bsscfg)
+static int brcms_c_set_mac(struct brcms_bss_cfg *bsscfg)
{
int err = 0;
struct brcms_c_info *wlc = bsscfg->wlc;
@@ -3847,7 +3926,7 @@ int brcms_c_set_mac(struct brcms_bss_cfg *bsscfg)
/* Write the BSS config's BSSID address to core (set_bssid in d11procs.tcl).
* Updates RXE match engine.
*/
-void brcms_c_set_bssid(struct brcms_bss_cfg *bsscfg)
+static void brcms_c_set_bssid(struct brcms_bss_cfg *bsscfg)
{
/* we need to update BSSID in RXE match registers */
brcms_c_set_addrmatch(bsscfg->wlc, RCM_BSSID_OFFSET, bsscfg->BSSID);
@@ -3868,7 +3947,7 @@ static void brcms_b_set_shortslot(struct brcms_hardware *wlc_hw, bool shortslot)
* Suspend the the MAC and update the slot timing
* for standard 11b/g (20us slots) or shortslot 11g (9us slots).
*/
-void brcms_c_switch_shortslot(struct brcms_c_info *wlc, bool shortslot)
+static void brcms_c_switch_shortslot(struct brcms_c_info *wlc, bool shortslot)
{
/* use the override if it is set */
if (wlc->shortslot_override != BRCMS_SHORTSLOT_AUTO)
@@ -3882,7 +3961,7 @@ void brcms_c_switch_shortslot(struct brcms_c_info *wlc, bool shortslot)
brcms_b_set_shortslot(wlc->hw, shortslot);
}

-void brcms_c_set_home_chanspec(struct brcms_c_info *wlc, u16 chanspec)
+static void brcms_c_set_home_chanspec(struct brcms_c_info *wlc, u16 chanspec)
{
if (wlc->home_chanspec != chanspec) {
wlc->home_chanspec = chanspec;
@@ -3952,7 +4031,7 @@ static void brcms_c_setband(struct brcms_c_info *wlc,
brcms_c_bsinit(wlc);
}

-void brcms_c_set_chanspec(struct brcms_c_info *wlc, u16 chanspec)
+static void brcms_c_set_chanspec(struct brcms_c_info *wlc, u16 chanspec)
{
uint bandunit;
bool switchband = false;
@@ -4006,31 +4085,6 @@ void brcms_c_set_chanspec(struct brcms_c_info *wlc, u16 chanspec)
brcms_c_ucode_mac_upd(wlc);
}

-u32 brcms_c_lowest_basic_rspec(struct brcms_c_info *wlc,
- struct brcms_c_rateset *rs)
-{
- u32 lowest_basic_rspec;
- uint i;
-
- /* Use the lowest basic rate */
- lowest_basic_rspec = rs->rates[0] & BRCMS_RATE_MASK;
- for (i = 0; i < rs->count; i++) {
- if (rs->rates[i] & BRCMS_RATE_FLAG) {
- lowest_basic_rspec = rs->rates[i] & BRCMS_RATE_MASK;
- break;
- }
- }
-
- /*
- * pick siso/cdd as default for OFDM (note no basic
- * rate MCSs are supported yet)
- */
- if (is_ofdm_rate(lowest_basic_rspec))
- lowest_basic_rspec |= (wlc->stf->ss_opmode << RSPEC_STF_SHIFT);
-
- return lowest_basic_rspec;
-}
-
/*
* This function changes the phytxctl for beacon based on current
* beacon ratespec AND txant setting as per this table:
@@ -4239,7 +4293,7 @@ static void brcms_c_radio_monitor_start(struct brcms_c_info *wlc)
brcms_add_timer(wlc->radio_timer, TIMER_INTERVAL_RADIOCHK, true);
}

-void brcms_c_radio_disable(struct brcms_c_info *wlc)
+static void brcms_c_radio_disable(struct brcms_c_info *wlc)
{
if (!wlc->pub->up) {
brcms_c_down_led_upd(wlc);
@@ -4261,7 +4315,7 @@ static void brcms_c_radio_enable(struct brcms_c_info *wlc)
brcms_up(wlc->wl);
}

-bool brcms_c_radio_monitor_stop(struct brcms_c_info *wlc)
+static bool brcms_c_radio_monitor_stop(struct brcms_c_info *wlc)
{
if (!wlc->radio_monitor)
return true;
@@ -4347,6 +4401,60 @@ static void brcms_b_watchdog(void *arg)
wlc_phy_watchdog(wlc_hw->band->pi);
}

+static void brcms_c_radio_mpc_upd(struct brcms_c_info *wlc)
+{
+ bool mpc_radio, radio_state;
+
+ /*
+ * Clear the WL_RADIO_MPC_DISABLE bit when mpc feature is disabled
+ * in case the WL_RADIO_MPC_DISABLE bit was set. Stop the radio
+ * monitor also when WL_RADIO_MPC_DISABLE is the only reason that
+ * the radio is going down.
+ */
+ if (!wlc->mpc) {
+ if (!wlc->pub->radio_disabled)
+ return;
+ mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE);
+ brcms_c_radio_upd(wlc);
+ if (!wlc->pub->radio_disabled)
+ brcms_c_radio_monitor_stop(wlc);
+ return;
+ }
+
+ /*
+ * sync ismpc logic with WL_RADIO_MPC_DISABLE bit in
+ * wlc->pub->radio_disabled to go ON, always call radio_upd
+ * synchronously to go OFF, postpone radio_upd to later when
+ * context is safe(e.g. watchdog)
+ */
+ radio_state =
+ (mboolisset(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE) ? OFF :
+ ON);
+ mpc_radio = (brcms_c_ismpc(wlc) == true) ? OFF : ON;
+
+ if (radio_state == ON && mpc_radio == OFF)
+ wlc->mpc_delay_off = wlc->mpc_dlycnt;
+ else if (radio_state == OFF && mpc_radio == ON) {
+ mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE);
+ brcms_c_radio_upd(wlc);
+ if (wlc->mpc_offcnt < BRCMS_MPC_THRESHOLD)
+ wlc->mpc_dlycnt = BRCMS_MPC_MAX_DELAYCNT;
+ else
+ wlc->mpc_dlycnt = BRCMS_MPC_MIN_DELAYCNT;
+ }
+ /*
+ * Below logic is meant to capture the transition from mpc off
+ * to mpc on for reasons other than wlc->mpc_delay_off keeping
+ * the mpc off. In that case reset wlc->mpc_delay_off to
+ * wlc->mpc_dlycnt, so that we restart the countdown of mpc_delay_off
+ */
+ if ((wlc->prev_non_delay_mpc == false) &&
+ (brcms_c_is_non_delay_mpc(wlc) == true) && wlc->mpc_delay_off)
+ wlc->mpc_delay_off = wlc->mpc_dlycnt;
+
+ wlc->prev_non_delay_mpc = brcms_c_is_non_delay_mpc(wlc);
+}
+
/* common watchdog code */
static void brcms_c_watchdog(void *arg)
{
@@ -4408,7 +4516,7 @@ static void brcms_c_watchdog_by_timer(void *arg)
brcms_c_watchdog(arg);
}

-bool brcms_c_timers_init(struct brcms_c_info *wlc, int unit)
+static bool brcms_c_timers_init(struct brcms_c_info *wlc, int unit)
{
wlc->wdtimer = brcms_init_timer(wlc->wl, brcms_c_watchdog_by_timer,
wlc, "watchdog");
@@ -4436,7 +4544,7 @@ bool brcms_c_timers_init(struct brcms_c_info *wlc, int unit)
* Initialize brcms_c_info default values ...
* may get overrides later in this function
*/
-void brcms_c_info_init(struct brcms_c_info *wlc, int unit)
+static void brcms_c_info_init(struct brcms_c_info *wlc, int unit)
{
int i;

@@ -5025,224 +5133,33 @@ static void brcms_c_update_mimo_band_bwcap(struct brcms_c_info *wlc, u8 bwcap)
}
}

-/*
- * The common driver entry routine. Error codes should be unique
- */
-struct brcms_c_info *
-brcms_c_attach(struct brcms_info *wl, u16 vendor, u16 device, uint unit,
- bool piomode, void __iomem *regsva, struct pci_dev *btparam,
- uint *perr)
+static void brcms_c_timers_deinit(struct brcms_c_info *wlc)
{
- struct brcms_c_info *wlc;
- uint err = 0;
- uint i, j;
- struct brcms_pub *pub;
-
- /* allocate struct brcms_c_info state and its substructures */
- wlc = (struct brcms_c_info *) brcms_c_attach_malloc(unit, &err, device);
- if (wlc == NULL)
- goto fail;
- wlc->wiphy = wl->wiphy;
- pub = wlc->pub;
-
-#if defined(BCMDBG)
- wlc_info_dbg = wlc;
-#endif
+ /* free timer state */
+ if (wlc->wdtimer) {
+ brcms_free_timer(wlc->wdtimer);
+ wlc->wdtimer = NULL;
+ }
+ if (wlc->radio_timer) {
+ brcms_free_timer(wlc->radio_timer);
+ wlc->radio_timer = NULL;
+ }
+}

- wlc->band = wlc->bandstate[0];
- wlc->core = wlc->corestate;
- wlc->wl = wl;
- pub->unit = unit;
- pub->_piomode = piomode;
- wlc->bandinit_pending = false;
+static void brcms_c_detach_module(struct brcms_c_info *wlc)
+{
+ if (wlc->asi) {
+ brcms_c_antsel_detach(wlc->asi);
+ wlc->asi = NULL;
+ }

- /* populate struct brcms_c_info with default values */
- brcms_c_info_init(wlc, unit);
+ if (wlc->ampdu) {
+ brcms_c_ampdu_detach(wlc->ampdu);
+ wlc->ampdu = NULL;
+ }

- /* update sta/ap related parameters */
- brcms_c_ap_upd(wlc);
-
- /*
- * low level attach steps(all hw accesses go
- * inside, no more in rest of the attach)
- */
- err = brcms_b_attach(wlc, vendor, device, unit, piomode, regsva,
- btparam);
- if (err)
- goto fail;
-
- brcms_c_protection_upd(wlc, BRCMS_PROT_N_PAM_OVR, OFF);
-
- pub->phy_11ncapable = BRCMS_PHY_11N_CAP(wlc->band);
-
- /* disable allowed duty cycle */
- wlc->tx_duty_cycle_ofdm = 0;
- wlc->tx_duty_cycle_cck = 0;
-
- brcms_c_stf_phy_chain_calc(wlc);
-
- /* txchain 1: txant 0, txchain 2: txant 1 */
- if (BRCMS_ISNPHY(wlc->band) && (wlc->stf->txstreams == 1))
- wlc->stf->txant = wlc->stf->hw_txchain - 1;
-
- /* push to BMAC driver */
- wlc_phy_stf_chain_init(wlc->band->pi, wlc->stf->hw_txchain,
- wlc->stf->hw_rxchain);
-
- /* pull up some info resulting from the low attach */
- for (i = 0; i < NFIFO; i++)
- wlc->core->txavail[i] = wlc->hw->txavail[i];
-
- memcpy(&wlc->perm_etheraddr, &wlc->hw->etheraddr, ETH_ALEN);
- memcpy(&pub->cur_etheraddr, &wlc->hw->etheraddr, ETH_ALEN);
-
- for (j = 0; j < wlc->pub->_nbands; j++) {
- wlc->band = wlc->bandstate[j];
-
- if (!brcms_c_attach_stf_ant_init(wlc)) {
- err = 24;
- goto fail;
- }
-
- /* default contention windows size limits */
- wlc->band->CWmin = APHY_CWMIN;
- wlc->band->CWmax = PHY_CWMAX;
-
- /* init gmode value */
- if (wlc->band->bandtype == BRCM_BAND_2G) {
- wlc->band->gmode = GMODE_AUTO;
- brcms_c_protection_upd(wlc, BRCMS_PROT_G_USER,
- wlc->band->gmode);
- }
-
- /* init _n_enab supported mode */
- if (BRCMS_PHY_11N_CAP(wlc->band)) {
- pub->_n_enab = SUPPORT_11N;
- brcms_c_protection_upd(wlc, BRCMS_PROT_N_USER,
- ((pub->_n_enab ==
- SUPPORT_11N) ? WL_11N_2x2 :
- WL_11N_3x3));
- }
-
- /* init per-band default rateset, depend on band->gmode */
- brcms_default_rateset(wlc, &wlc->band->defrateset);
-
- /* fill in hw_rateset */
- brcms_c_rateset_filter(&wlc->band->defrateset,
- &wlc->band->hw_rateset, false,
- BRCMS_RATES_CCK_OFDM, BRCMS_RATE_MASK,
- (bool) (wlc->pub->_n_enab & SUPPORT_11N));
- }
-
- /*
- * update antenna config due to
- * wlc->stf->txant/txchain/ant_rx_ovr change
- */
- brcms_c_stf_phy_txant_upd(wlc);
-
- /* attach each modules */
- err = brcms_c_attach_module(wlc);
- if (err != 0)
- goto fail;
-
- if (!brcms_c_timers_init(wlc, unit)) {
- wiphy_err(wl->wiphy, "wl%d: %s: init_timer failed\n", unit,
- __func__);
- err = 32;
- goto fail;
- }
-
- /* depend on rateset, gmode */
- wlc->cmi = brcms_c_channel_mgr_attach(wlc);
- if (!wlc->cmi) {
- wiphy_err(wl->wiphy, "wl%d: %s: channel_mgr_attach failed"
- "\n", unit, __func__);
- err = 33;
- goto fail;
- }
-
- /* init default when all parameters are ready, i.e. ->rateset */
- brcms_c_bss_default_init(wlc);
-
- /*
- * Complete the wlc default state initializations..
- */
-
- /* allocate our initial queue */
- wlc->pkt_queue = brcms_c_txq_alloc(wlc);
- if (wlc->pkt_queue == NULL) {
- wiphy_err(wl->wiphy, "wl%d: %s: failed to malloc tx queue\n",
- unit, __func__);
- err = 100;
- goto fail;
- }
-
- wlc->bsscfg->wlc = wlc;
-
- wlc->mimoft = FT_HT;
- wlc->mimo_40txbw = AUTO;
- wlc->ofdm_40txbw = AUTO;
- wlc->cck_40txbw = AUTO;
- brcms_c_update_mimo_band_bwcap(wlc, BRCMS_N_BW_20IN2G_40IN5G);
-
- /* Set default values of SGI */
- if (BRCMS_SGI_CAP_PHY(wlc)) {
- brcms_c_ht_update_sgi_rx(wlc, (BRCMS_N_SGI_20 |
- BRCMS_N_SGI_40));
- } else if (BRCMS_ISSSLPNPHY(wlc->band)) {
- brcms_c_ht_update_sgi_rx(wlc, (BRCMS_N_SGI_20 |
- BRCMS_N_SGI_40));
- } else {
- brcms_c_ht_update_sgi_rx(wlc, 0);
- }
-
- /* initialize radio_mpc_disable according to wlc->mpc */
- brcms_c_radio_mpc_upd(wlc);
- brcms_b_antsel_set(wlc->hw, wlc->asi->antsel_avail);
-
- if (perr)
- *perr = 0;
-
- return wlc;
-
- fail:
- wiphy_err(wl->wiphy, "wl%d: %s: failed with err %d\n",
- unit, __func__, err);
- if (wlc)
- brcms_c_detach(wlc);
-
- if (perr)
- *perr = err;
- return NULL;
-}
-
-static void brcms_c_timers_deinit(struct brcms_c_info *wlc)
-{
- /* free timer state */
- if (wlc->wdtimer) {
- brcms_free_timer(wlc->wdtimer);
- wlc->wdtimer = NULL;
- }
- if (wlc->radio_timer) {
- brcms_free_timer(wlc->radio_timer);
- wlc->radio_timer = NULL;
- }
-}
-
-static void brcms_c_detach_module(struct brcms_c_info *wlc)
-{
- if (wlc->asi) {
- brcms_c_antsel_detach(wlc->asi);
- wlc->asi = NULL;
- }
-
- if (wlc->ampdu) {
- brcms_c_ampdu_detach(wlc->ampdu);
- wlc->ampdu = NULL;
- }
-
- brcms_c_stf_detach(wlc);
-}
+ brcms_c_stf_detach(wlc);
+}

/*
* low level detach
@@ -5332,7 +5249,7 @@ uint brcms_c_detach(struct brcms_c_info *wlc)
}

/* update state that depends on the current value of "ap" */
-void brcms_c_ap_upd(struct brcms_c_info *wlc)
+static void brcms_c_ap_upd(struct brcms_c_info *wlc)
{
/* STA-BSS; short capable */
wlc->PLCPHdr_override = BRCMS_PLCP_SHORT;
@@ -5341,73 +5258,6 @@ void brcms_c_ap_upd(struct brcms_c_info *wlc)
wlc->mpc = true;
}

-/*
- * return true if Minimum Power Consumption should
- * be entered, false otherwise
- */
-bool brcms_c_is_non_delay_mpc(struct brcms_c_info *wlc)
-{
- return false;
-}
-
-bool brcms_c_ismpc(struct brcms_c_info *wlc)
-{
- return (wlc->mpc_delay_off == 0) && (brcms_c_is_non_delay_mpc(wlc));
-}
-
-void brcms_c_radio_mpc_upd(struct brcms_c_info *wlc)
-{
- bool mpc_radio, radio_state;
-
- /*
- * Clear the WL_RADIO_MPC_DISABLE bit when mpc feature is disabled
- * in case the WL_RADIO_MPC_DISABLE bit was set. Stop the radio
- * monitor also when WL_RADIO_MPC_DISABLE is the only reason that
- * the radio is going down.
- */
- if (!wlc->mpc) {
- if (!wlc->pub->radio_disabled)
- return;
- mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE);
- brcms_c_radio_upd(wlc);
- if (!wlc->pub->radio_disabled)
- brcms_c_radio_monitor_stop(wlc);
- return;
- }
-
- /*
- * sync ismpc logic with WL_RADIO_MPC_DISABLE bit in
- * wlc->pub->radio_disabled to go ON, always call radio_upd
- * synchronously to go OFF, postpone radio_upd to later when
- * context is safe(e.g. watchdog)
- */
- radio_state =
- (mboolisset(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE) ? OFF :
- ON);
- mpc_radio = (brcms_c_ismpc(wlc) == true) ? OFF : ON;
-
- if (radio_state == ON && mpc_radio == OFF)
- wlc->mpc_delay_off = wlc->mpc_dlycnt;
- else if (radio_state == OFF && mpc_radio == ON) {
- mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE);
- brcms_c_radio_upd(wlc);
- if (wlc->mpc_offcnt < BRCMS_MPC_THRESHOLD)
- wlc->mpc_dlycnt = BRCMS_MPC_MAX_DELAYCNT;
- else
- wlc->mpc_dlycnt = BRCMS_MPC_MIN_DELAYCNT;
- }
- /*
- * Below logic is meant to capture the transition from mpc off
- * to mpc on for reasons other than wlc->mpc_delay_off keeping
- * the mpc off. In that case reset wlc->mpc_delay_off to
- * wlc->mpc_dlycnt, so that we restart the countdown of mpc_delay_off
- */
- if ((wlc->prev_non_delay_mpc == false) &&
- (brcms_c_is_non_delay_mpc(wlc) == true) && wlc->mpc_delay_off)
- wlc->mpc_delay_off = wlc->mpc_dlycnt;
-
- wlc->prev_non_delay_mpc = brcms_c_is_non_delay_mpc(wlc);
-}
/* Initialize just the hardware when coming out of POR or S3/S5 system states */
static void brcms_b_hw_up(struct brcms_hardware *wlc_hw)
{
@@ -6195,59 +6045,7 @@ void brcms_c_print_txstatus(struct tx_status *txs)
#endif /* defined(BCMDBG) */
}

-void brcms_c_statsupd(struct brcms_c_info *wlc)
-{
- int i;
- struct macstat macstats;
-#ifdef BCMDBG
- u16 delta;
- u16 rxf0ovfl;
- u16 txfunfl[NFIFO];
-#endif /* BCMDBG */
-
- /* if driver down, make no sense to update stats */
- if (!wlc->pub->up)
- return;
-
-#ifdef BCMDBG
- /* save last rx fifo 0 overflow count */
- rxf0ovfl = wlc->core->macstat_snapshot->rxf0ovfl;
-
- /* save last tx fifo underflow count */
- for (i = 0; i < NFIFO; i++)
- txfunfl[i] = wlc->core->macstat_snapshot->txfunfl[i];
-#endif /* BCMDBG */
-
- /* Read mac stats from contiguous shared memory */
- brcms_b_copyfrom_objmem(wlc->hw, M_UCODE_MACSTAT, &macstats,
- sizeof(struct macstat), OBJADDR_SHM_SEL);
-
-#ifdef BCMDBG
- /* check for rx fifo 0 overflow */
- delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl);
- if (delta)
- wiphy_err(wlc->wiphy, "wl%d: %u rx fifo 0 overflows!\n",
- wlc->pub->unit, delta);
-
- /* check for tx fifo underflows */
- for (i = 0; i < NFIFO; i++) {
- delta =
- (u16) (wlc->core->macstat_snapshot->txfunfl[i] -
- txfunfl[i]);
- if (delta)
- wiphy_err(wlc->wiphy, "wl%d: %u tx fifo %d underflows!"
- "\n", wlc->pub->unit, delta, i);
- }
-#endif /* BCMDBG */
-
- /* merge counters from dma module */
- for (i = 0; i < NFIFO; i++) {
- if (wlc->hw->di[i])
- dma_counterreset(wlc->hw->di[i]);
- }
-}
-
-bool brcms_c_chipmatch(u16 vendor, u16 device)
+bool brcms_c_chipmatch(u16 vendor, u16 device)
{
if (vendor != PCI_VENDOR_ID_BROADCOM) {
pr_err("chipmatch: unknown vendor id %04x\n", vendor);
@@ -6417,24 +6215,7 @@ u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate)
return 2 * brcms_b_read_shm(wlc_hw, table_ptr + (index * 2));
}

-/* Callback for device removed */
-
-/*
- * Attempts to queue a packet onto a multiple-precedence queue,
- * if necessary evicting a lower precedence packet from the queue.
- *
- * 'prec' is the precedence number that has already been mapped
- * from the packet priority.
- *
- * Returns true if packet consumed (queued), false if not.
- */
-static bool brcms_c_prec_enq(struct brcms_c_info *wlc, struct pktq *q,
- struct sk_buff *pkt, int prec)
-{
- return brcms_c_prec_enq_head(wlc, q, pkt, prec, false);
-}
-
-bool
+static bool
brcms_c_prec_enq_head(struct brcms_c_info *wlc, struct pktq *q,
struct sk_buff *pkt, int prec, bool head)
{
@@ -6481,6 +6262,21 @@ brcms_c_prec_enq_head(struct brcms_c_info *wlc, struct pktq *q,
return true;
}

+/*
+ * Attempts to queue a packet onto a multiple-precedence queue,
+ * if necessary evicting a lower precedence packet from the queue.
+ *
+ * 'prec' is the precedence number that has already been mapped
+ * from the packet priority.
+ *
+ * Returns true if packet consumed (queued), false if not.
+ */
+static bool brcms_c_prec_enq(struct brcms_c_info *wlc, struct pktq *q,
+ struct sk_buff *pkt, int prec)
+{
+ return brcms_c_prec_enq_head(wlc, q, pkt, prec, false);
+}
+
void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb,
struct sk_buff *sdu, uint prec)
{
@@ -6647,6 +6443,43 @@ brcms_c_calc_frame_len(struct brcms_c_info *wlc, u32 ratespec,
return mac_len;
}

+/*
+ * Return true if the specified rate is supported by the specified band.
+ * BRCM_BAND_AUTO indicates the current band.
+ */
+static bool brcms_c_valid_rate(struct brcms_c_info *wlc, u32 rspec, int band,
+ bool verbose)
+{
+ struct brcms_c_rateset *hw_rateset;
+ uint i;
+
+ if ((band == BRCM_BAND_AUTO) || (band == wlc->band->bandtype))
+ hw_rateset = &wlc->band->hw_rateset;
+ else if (wlc->pub->_nbands > 1)
+ hw_rateset = &wlc->bandstate[OTHERBANDUNIT(wlc)]->hw_rateset;
+ else
+ /* other band specified and we are a single band device */
+ return false;
+
+ /* check if this is a mimo rate */
+ if (is_mcs_rate(rspec)) {
+ if ((rspec & RSPEC_RATE_MASK) >= MCS_TABLE_SIZE)
+ goto error;
+
+ return isset(hw_rateset->mcs, (rspec & RSPEC_RATE_MASK));
+ }
+
+ for (i = 0; i < hw_rateset->count; i++)
+ if (hw_rateset->rates[i] == rspec2rate(rspec))
+ return true;
+ error:
+ if (verbose)
+ wiphy_err(wlc->wiphy, "wl%d: valid_rate: rate spec 0x%x "
+ "not in hw_rateset\n", wlc->pub->unit, rspec);
+
+ return false;
+}
+
static u32
mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band,
u32 int_val)
@@ -6764,84 +6597,291 @@ done:
}

/*
- * Add struct d11txh, struct cck_phy_hdr.
- *
- * 'p' data must start with 802.11 MAC header
- * 'p' must allow enough bytes of local headers to be "pushed" onto the packet
- *
- * headroom == D11_PHY_HDR_LEN + D11_TXH_LEN (D11_TXH_LEN is now 104 bytes)
- *
+ * Compute PLCP, but only requires actual rate and length of pkt.
+ * Rate is given in the driver standard multiple of 500 kbps.
+ * le is set for 11 Mbps rate if necessary.
+ * Broken out for PRQ.
*/
-static u16
-brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw,
- struct sk_buff *p, struct scb *scb, uint frag,
- uint nfrags, uint queue, uint next_frag_len)
-{
- struct ieee80211_hdr *h;
- struct d11txh *txh;
- u8 *plcp, plcp_fallback[D11_PHY_HDR_LEN];
- int len, phylen, rts_phylen;
- u16 mch, phyctl, xfts, mainrates;
- u16 seq = 0, mcl = 0, status = 0, frameid = 0;
- u32 rspec[2] = { BRCM_RATE_1M, BRCM_RATE_1M };
- u32 rts_rspec[2] = { BRCM_RATE_1M, BRCM_RATE_1M };
- bool use_rts = false;
- bool use_cts = false;
- bool use_rifs = false;
- bool short_preamble[2] = { false, false };
- u8 preamble_type[2] = { BRCMS_LONG_PREAMBLE, BRCMS_LONG_PREAMBLE };
- u8 rts_preamble_type[2] = { BRCMS_LONG_PREAMBLE, BRCMS_LONG_PREAMBLE };
- u8 *rts_plcp, rts_plcp_fallback[D11_PHY_HDR_LEN];
- struct ieee80211_rts *rts = NULL;
- bool qos;
- uint ac;
- bool hwtkmic = false;
- u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ;
-#define ANTCFG_NONE 0xFF
- u8 antcfg = ANTCFG_NONE;
- u8 fbantcfg = ANTCFG_NONE;
- uint phyctl1_stf = 0;
- u16 durid = 0;
- struct ieee80211_tx_rate *txrate[2];
- int k;
- struct ieee80211_tx_info *tx_info;
- bool is_mcs;
- u16 mimo_txbw;
- u8 mimo_preamble_type;

- /* locate 802.11 MAC header */
- h = (struct ieee80211_hdr *)(p->data);
- qos = ieee80211_is_data_qos(h->frame_control);
+static void brcms_c_cck_plcp_set(struct brcms_c_info *wlc, int rate_500,
+ uint length, u8 *plcp)
+{
+ u16 usec = 0;
+ u8 le = 0;

- /* compute length of frame in bytes for use in PLCP computations */
- len = brcmu_pkttotlen(p);
- phylen = len + FCS_LEN;
+ switch (rate_500) {
+ case BRCM_RATE_1M:
+ usec = length << 3;
+ break;
+ case BRCM_RATE_2M:
+ usec = length << 2;
+ break;
+ case BRCM_RATE_5M5:
+ usec = (length << 4) / 11;
+ if ((length << 4) - (usec * 11) > 0)
+ usec++;
+ break;
+ case BRCM_RATE_11M:
+ usec = (length << 3) / 11;
+ if ((length << 3) - (usec * 11) > 0) {
+ usec++;
+ if ((usec * 11) - (length << 3) >= 8)
+ le = D11B_PLCP_SIGNAL_LE;
+ }
+ break;

- /* Get tx_info */
- tx_info = IEEE80211_SKB_CB(p);
+ default:
+ wiphy_err(wlc->wiphy,
+ "brcms_c_cck_plcp_set: unsupported rate %d\n",
+ rate_500);
+ rate_500 = BRCM_RATE_1M;
+ usec = length << 3;
+ break;
+ }
+ /* PLCP signal byte */
+ plcp[0] = rate_500 * 5; /* r (500kbps) * 5 == r (100kbps) */
+ /* PLCP service byte */
+ plcp[1] = (u8) (le | D11B_PLCP_SIGNAL_LOCKED);
+ /* PLCP length u16, little endian */
+ plcp[2] = usec & 0xff;
+ plcp[3] = (usec >> 8) & 0xff;
+ /* PLCP CRC16 */
+ plcp[4] = 0;
+ plcp[5] = 0;
+}

- /* add PLCP */
- plcp = skb_push(p, D11_PHY_HDR_LEN);
+/* Rate: 802.11 rate code, length: PSDU length in octets */
+static void brcms_c_compute_mimo_plcp(u32 rspec, uint length, u8 *plcp)
+{
+ u8 mcs = (u8) (rspec & RSPEC_RATE_MASK);
+ plcp[0] = mcs;
+ if (rspec_is40mhz(rspec) || (mcs == 32))
+ plcp[0] |= MIMO_PLCP_40MHZ;
+ BRCMS_SET_MIMO_PLCP_LEN(plcp, length);
+ plcp[3] = rspec_mimoplcp3(rspec); /* rspec already holds this byte */
+ plcp[3] |= 0x7; /* set smoothing, not sounding ppdu & reserved */
+ plcp[4] = 0; /* number of extension spatial streams bit 0 & 1 */
+ plcp[5] = 0;
+}

- /* add Broadcom tx descriptor header */
- txh = (struct d11txh *) skb_push(p, D11_TXH_LEN);
- memset(txh, 0, D11_TXH_LEN);
+/* Rate: 802.11 rate code, length: PSDU length in octets */
+static void
+brcms_c_compute_ofdm_plcp(u32 rspec, u32 length, u8 *plcp)
+{
+ u8 rate_signal;
+ u32 tmp = 0;
+ int rate = rspec2rate(rspec);

- /* setup frameid */
- if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
- /* non-AP STA should never use BCMC queue */
- if (queue == TX_BCMC_FIFO) {
- wiphy_err(wlc->wiphy, "wl%d: %s: ASSERT queue == "
- "TX_BCMC!\n", wlc->pub->unit, __func__);
- frameid = bcmc_fid_generate(wlc, NULL, txh);
- } else {
- /* Increment the counter for first fragment */
- if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
- scb->seqnum[p->priority]++;
+ /*
+ * encode rate per 802.11a-1999 sec 17.3.4.1, with lsb
+ * transmitted first
+ */
+ rate_signal = rate_info[rate] & BRCMS_RATE_MASK;
+ memset(plcp, 0, D11_PHY_HDR_LEN);
+ D11A_PHY_HDR_SRATE((struct ofdm_phy_hdr *) plcp, rate_signal);

- /* extract fragment number from frame first */
- seq = le16_to_cpu(h->seq_ctrl) & FRAGNUM_MASK;
- seq |= (scb->seqnum[p->priority] << SEQNUM_SHIFT);
+ tmp = (length & 0xfff) << 5;
+ plcp[2] |= (tmp >> 16) & 0xff;
+ plcp[1] |= (tmp >> 8) & 0xff;
+ plcp[0] |= tmp & 0xff;
+}
+
+/* Rate: 802.11 rate code, length: PSDU length in octets */
+static void brcms_c_compute_cck_plcp(struct brcms_c_info *wlc, u32 rspec,
+ uint length, u8 *plcp)
+{
+ int rate = rspec2rate(rspec);
+
+ brcms_c_cck_plcp_set(wlc, rate, length, plcp);
+}
+
+static void
+brcms_c_compute_plcp(struct brcms_c_info *wlc, u32 rspec,
+ uint length, u8 *plcp)
+{
+ if (is_mcs_rate(rspec))
+ brcms_c_compute_mimo_plcp(rspec, length, plcp);
+ else if (is_ofdm_rate(rspec))
+ brcms_c_compute_ofdm_plcp(rspec, length, plcp);
+ else
+ brcms_c_compute_cck_plcp(wlc, rspec, length, plcp);
+}
+
+/* brcms_c_compute_rtscts_dur()
+ *
+ * Calculate the 802.11 MAC header DUR field for an RTS or CTS frame
+ * DUR for normal RTS/CTS w/ frame = 3 SIFS + 1 CTS + next frame time + 1 ACK
+ * DUR for CTS-TO-SELF w/ frame = 2 SIFS + next frame time + 1 ACK
+ *
+ * cts cts-to-self or rts/cts
+ * rts_rate rts or cts rate in unit of 500kbps
+ * rate next MPDU rate in unit of 500kbps
+ * frame_len next MPDU frame length in bytes
+ */
+u16
+brcms_c_compute_rtscts_dur(struct brcms_c_info *wlc, bool cts_only,
+ u32 rts_rate,
+ u32 frame_rate, u8 rts_preamble_type,
+ u8 frame_preamble_type, uint frame_len, bool ba)
+{
+ u16 dur, sifs;
+
+ sifs = get_sifs(wlc->band);
+
+ if (!cts_only) {
+ /* RTS/CTS */
+ dur = 3 * sifs;
+ dur +=
+ (u16) brcms_c_calc_cts_time(wlc, rts_rate,
+ rts_preamble_type);
+ } else {
+ /* CTS-TO-SELF */
+ dur = 2 * sifs;
+ }
+
+ dur +=
+ (u16) brcms_c_calc_frame_time(wlc, frame_rate, frame_preamble_type,
+ frame_len);
+ if (ba)
+ dur +=
+ (u16) brcms_c_calc_ba_time(wlc, frame_rate,
+ BRCMS_SHORT_PREAMBLE);
+ else
+ dur +=
+ (u16) brcms_c_calc_ack_time(wlc, frame_rate,
+ frame_preamble_type);
+ return dur;
+}
+
+static u16 brcms_c_phytxctl1_calc(struct brcms_c_info *wlc, u32 rspec)
+{
+ u16 phyctl1 = 0;
+ u16 bw;
+
+ if (BRCMS_ISLCNPHY(wlc->band)) {
+ bw = PHY_TXC1_BW_20MHZ;
+ } else {
+ bw = rspec_get_bw(rspec);
+ /* 10Mhz is not supported yet */
+ if (bw < PHY_TXC1_BW_20MHZ) {
+ wiphy_err(wlc->wiphy, "phytxctl1_calc: bw %d is "
+ "not supported yet, set to 20L\n", bw);
+ bw = PHY_TXC1_BW_20MHZ;
+ }
+ }
+
+ if (is_mcs_rate(rspec)) {
+ uint mcs = rspec & RSPEC_RATE_MASK;
+
+ /* bw, stf, coding-type is part of rspec_phytxbyte2 returns */
+ phyctl1 = rspec_phytxbyte2(rspec);
+ /* set the upper byte of phyctl1 */
+ phyctl1 |= (mcs_table[mcs].tx_phy_ctl3 << 8);
+ } else if (is_cck_rate(rspec) && !BRCMS_ISLCNPHY(wlc->band)
+ && !BRCMS_ISSSLPNPHY(wlc->band)) {
+ /*
+ * In CCK mode LPPHY overloads OFDM Modulation bits with CCK
+ * Data Rate. Eventually MIMOPHY would also be converted to
+ * this format
+ */
+ /* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps */
+ phyctl1 = (bw | (rspec_stf(rspec) << PHY_TXC1_MODE_SHIFT));
+ } else { /* legacy OFDM/CCK */
+ s16 phycfg;
+ /* get the phyctl byte from rate phycfg table */
+ phycfg = brcms_c_rate_legacy_phyctl(rspec2rate(rspec));
+ if (phycfg == -1) {
+ wiphy_err(wlc->wiphy, "phytxctl1_calc: wrong "
+ "legacy OFDM/CCK rate\n");
+ phycfg = 0;
+ }
+ /* set the upper byte of phyctl1 */
+ phyctl1 =
+ (bw | (phycfg << 8) |
+ (rspec_stf(rspec) << PHY_TXC1_MODE_SHIFT));
+ }
+ return phyctl1;
+}
+
+/*
+ * Add struct d11txh, struct cck_phy_hdr.
+ *
+ * 'p' data must start with 802.11 MAC header
+ * 'p' must allow enough bytes of local headers to be "pushed" onto the packet
+ *
+ * headroom == D11_PHY_HDR_LEN + D11_TXH_LEN (D11_TXH_LEN is now 104 bytes)
+ *
+ */
+static u16
+brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw,
+ struct sk_buff *p, struct scb *scb, uint frag,
+ uint nfrags, uint queue, uint next_frag_len)
+{
+ struct ieee80211_hdr *h;
+ struct d11txh *txh;
+ u8 *plcp, plcp_fallback[D11_PHY_HDR_LEN];
+ int len, phylen, rts_phylen;
+ u16 mch, phyctl, xfts, mainrates;
+ u16 seq = 0, mcl = 0, status = 0, frameid = 0;
+ u32 rspec[2] = { BRCM_RATE_1M, BRCM_RATE_1M };
+ u32 rts_rspec[2] = { BRCM_RATE_1M, BRCM_RATE_1M };
+ bool use_rts = false;
+ bool use_cts = false;
+ bool use_rifs = false;
+ bool short_preamble[2] = { false, false };
+ u8 preamble_type[2] = { BRCMS_LONG_PREAMBLE, BRCMS_LONG_PREAMBLE };
+ u8 rts_preamble_type[2] = { BRCMS_LONG_PREAMBLE, BRCMS_LONG_PREAMBLE };
+ u8 *rts_plcp, rts_plcp_fallback[D11_PHY_HDR_LEN];
+ struct ieee80211_rts *rts = NULL;
+ bool qos;
+ uint ac;
+ bool hwtkmic = false;
+ u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ;
+#define ANTCFG_NONE 0xFF
+ u8 antcfg = ANTCFG_NONE;
+ u8 fbantcfg = ANTCFG_NONE;
+ uint phyctl1_stf = 0;
+ u16 durid = 0;
+ struct ieee80211_tx_rate *txrate[2];
+ int k;
+ struct ieee80211_tx_info *tx_info;
+ bool is_mcs;
+ u16 mimo_txbw;
+ u8 mimo_preamble_type;
+
+ /* locate 802.11 MAC header */
+ h = (struct ieee80211_hdr *)(p->data);
+ qos = ieee80211_is_data_qos(h->frame_control);
+
+ /* compute length of frame in bytes for use in PLCP computations */
+ len = brcmu_pkttotlen(p);
+ phylen = len + FCS_LEN;
+
+ /* Get tx_info */
+ tx_info = IEEE80211_SKB_CB(p);
+
+ /* add PLCP */
+ plcp = skb_push(p, D11_PHY_HDR_LEN);
+
+ /* add Broadcom tx descriptor header */
+ txh = (struct d11txh *) skb_push(p, D11_TXH_LEN);
+ memset(txh, 0, D11_TXH_LEN);
+
+ /* setup frameid */
+ if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
+ /* non-AP STA should never use BCMC queue */
+ if (queue == TX_BCMC_FIFO) {
+ wiphy_err(wlc->wiphy, "wl%d: %s: ASSERT queue == "
+ "TX_BCMC!\n", wlc->pub->unit, __func__);
+ frameid = bcmc_fid_generate(wlc, NULL, txh);
+ } else {
+ /* Increment the counter for first fragment */
+ if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
+ scb->seqnum[p->priority]++;
+
+ /* extract fragment number from frame first */
+ seq = le16_to_cpu(h->seq_ctrl) & FRAGNUM_MASK;
+ seq |= (scb->seqnum[p->priority] << SEQNUM_SHIFT);
h->seq_ctrl = cpu_to_le16(seq);

frameid = ((seq << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) |
@@ -7518,237 +7558,30 @@ brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p,
wiphy_err(wlc->wiphy, "txfifo: fatal, toss frames !!!\n");
}

-/*
- * Compute PLCP, but only requires actual rate and length of pkt.
- * Rate is given in the driver standard multiple of 500 kbps.
- * le is set for 11 Mbps rate if necessary.
- * Broken out for PRQ.
- */
-
-static void brcms_c_cck_plcp_set(struct brcms_c_info *wlc, int rate_500,
- uint length, u8 *plcp)
+u32
+brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, u32 rspec,
+ bool use_rspec, u16 mimo_ctlchbw)
{
- u16 usec = 0;
- u8 le = 0;
+ u32 rts_rspec = 0;

- switch (rate_500) {
- case BRCM_RATE_1M:
- usec = length << 3;
- break;
- case BRCM_RATE_2M:
- usec = length << 2;
- break;
- case BRCM_RATE_5M5:
- usec = (length << 4) / 11;
- if ((length << 4) - (usec * 11) > 0)
- usec++;
- break;
- case BRCM_RATE_11M:
- usec = (length << 3) / 11;
- if ((length << 3) - (usec * 11) > 0) {
- usec++;
- if ((usec * 11) - (length << 3) >= 8)
- le = D11B_PLCP_SIGNAL_LE;
- }
- break;
-
- default:
- wiphy_err(wlc->wiphy,
- "brcms_c_cck_plcp_set: unsupported rate %d\n",
- rate_500);
- rate_500 = BRCM_RATE_1M;
- usec = length << 3;
- break;
- }
- /* PLCP signal byte */
- plcp[0] = rate_500 * 5; /* r (500kbps) * 5 == r (100kbps) */
- /* PLCP service byte */
- plcp[1] = (u8) (le | D11B_PLCP_SIGNAL_LOCKED);
- /* PLCP length u16, little endian */
- plcp[2] = usec & 0xff;
- plcp[3] = (usec >> 8) & 0xff;
- /* PLCP CRC16 */
- plcp[4] = 0;
- plcp[5] = 0;
-}
-
-/* Rate: 802.11 rate code, length: PSDU length in octets */
-static void brcms_c_compute_mimo_plcp(u32 rspec, uint length, u8 *plcp)
-{
- u8 mcs = (u8) (rspec & RSPEC_RATE_MASK);
- plcp[0] = mcs;
- if (rspec_is40mhz(rspec) || (mcs == 32))
- plcp[0] |= MIMO_PLCP_40MHZ;
- BRCMS_SET_MIMO_PLCP_LEN(plcp, length);
- plcp[3] = rspec_mimoplcp3(rspec); /* rspec already holds this byte */
- plcp[3] |= 0x7; /* set smoothing, not sounding ppdu & reserved */
- plcp[4] = 0; /* number of extension spatial streams bit 0 & 1 */
- plcp[5] = 0;
-}
-
-/* Rate: 802.11 rate code, length: PSDU length in octets */
-static void
-brcms_c_compute_ofdm_plcp(u32 rspec, u32 length, u8 *plcp)
-{
- u8 rate_signal;
- u32 tmp = 0;
- int rate = rspec2rate(rspec);
-
- /*
- * encode rate per 802.11a-1999 sec 17.3.4.1, with lsb
- * transmitted first
- */
- rate_signal = rate_info[rate] & BRCMS_RATE_MASK;
- memset(plcp, 0, D11_PHY_HDR_LEN);
- D11A_PHY_HDR_SRATE((struct ofdm_phy_hdr *) plcp, rate_signal);
-
- tmp = (length & 0xfff) << 5;
- plcp[2] |= (tmp >> 16) & 0xff;
- plcp[1] |= (tmp >> 8) & 0xff;
- plcp[0] |= tmp & 0xff;
-}
-
-/* Rate: 802.11 rate code, length: PSDU length in octets */
-static void brcms_c_compute_cck_plcp(struct brcms_c_info *wlc, u32 rspec,
- uint length, u8 *plcp)
-{
- int rate = rspec2rate(rspec);
-
- brcms_c_cck_plcp_set(wlc, rate, length, plcp);
-}
-
-void
-brcms_c_compute_plcp(struct brcms_c_info *wlc, u32 rspec,
- uint length, u8 *plcp)
-{
- if (is_mcs_rate(rspec))
- brcms_c_compute_mimo_plcp(rspec, length, plcp);
- else if (is_ofdm_rate(rspec))
- brcms_c_compute_ofdm_plcp(rspec, length, plcp);
- else
- brcms_c_compute_cck_plcp(wlc, rspec, length, plcp);
-}
-
-/* brcms_c_compute_rtscts_dur()
- *
- * Calculate the 802.11 MAC header DUR field for an RTS or CTS frame
- * DUR for normal RTS/CTS w/ frame = 3 SIFS + 1 CTS + next frame time + 1 ACK
- * DUR for CTS-TO-SELF w/ frame = 2 SIFS + next frame time + 1 ACK
- *
- * cts cts-to-self or rts/cts
- * rts_rate rts or cts rate in unit of 500kbps
- * rate next MPDU rate in unit of 500kbps
- * frame_len next MPDU frame length in bytes
- */
-u16
-brcms_c_compute_rtscts_dur(struct brcms_c_info *wlc, bool cts_only,
- u32 rts_rate,
- u32 frame_rate, u8 rts_preamble_type,
- u8 frame_preamble_type, uint frame_len, bool ba)
-{
- u16 dur, sifs;
-
- sifs = get_sifs(wlc->band);
-
- if (!cts_only) {
- /* RTS/CTS */
- dur = 3 * sifs;
- dur +=
- (u16) brcms_c_calc_cts_time(wlc, rts_rate,
- rts_preamble_type);
- } else {
- /* CTS-TO-SELF */
- dur = 2 * sifs;
- }
-
- dur +=
- (u16) brcms_c_calc_frame_time(wlc, frame_rate, frame_preamble_type,
- frame_len);
- if (ba)
- dur +=
- (u16) brcms_c_calc_ba_time(wlc, frame_rate,
- BRCMS_SHORT_PREAMBLE);
- else
- dur +=
- (u16) brcms_c_calc_ack_time(wlc, frame_rate,
- frame_preamble_type);
- return dur;
-}
-
-u16 brcms_c_phytxctl1_calc(struct brcms_c_info *wlc, u32 rspec)
-{
- u16 phyctl1 = 0;
- u16 bw;
-
- if (BRCMS_ISLCNPHY(wlc->band)) {
- bw = PHY_TXC1_BW_20MHZ;
- } else {
- bw = rspec_get_bw(rspec);
- /* 10Mhz is not supported yet */
- if (bw < PHY_TXC1_BW_20MHZ) {
- wiphy_err(wlc->wiphy, "phytxctl1_calc: bw %d is "
- "not supported yet, set to 20L\n", bw);
- bw = PHY_TXC1_BW_20MHZ;
- }
- }
-
- if (is_mcs_rate(rspec)) {
- uint mcs = rspec & RSPEC_RATE_MASK;
-
- /* bw, stf, coding-type is part of rspec_phytxbyte2 returns */
- phyctl1 = rspec_phytxbyte2(rspec);
- /* set the upper byte of phyctl1 */
- phyctl1 |= (mcs_table[mcs].tx_phy_ctl3 << 8);
- } else if (is_cck_rate(rspec) && !BRCMS_ISLCNPHY(wlc->band)
- && !BRCMS_ISSSLPNPHY(wlc->band)) {
- /*
- * In CCK mode LPPHY overloads OFDM Modulation bits with CCK
- * Data Rate. Eventually MIMOPHY would also be converted to
- * this format
- */
- /* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps */
- phyctl1 = (bw | (rspec_stf(rspec) << PHY_TXC1_MODE_SHIFT));
- } else { /* legacy OFDM/CCK */
- s16 phycfg;
- /* get the phyctl byte from rate phycfg table */
- phycfg = brcms_c_rate_legacy_phyctl(rspec2rate(rspec));
- if (phycfg == -1) {
- wiphy_err(wlc->wiphy, "phytxctl1_calc: wrong "
- "legacy OFDM/CCK rate\n");
- phycfg = 0;
- }
- /* set the upper byte of phyctl1 */
- phyctl1 =
- (bw | (phycfg << 8) |
- (rspec_stf(rspec) << PHY_TXC1_MODE_SHIFT));
- }
- return phyctl1;
-}
-
-u32
-brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, u32 rspec,
- bool use_rspec, u16 mimo_ctlchbw)
-{
- u32 rts_rspec = 0;
-
- if (use_rspec)
- /* use frame rate as rts rate */
- rts_rspec = rspec;
- else if (wlc->band->gmode && wlc->protection->_g && !is_cck_rate(rspec))
- /* Use 11Mbps as the g protection RTS target rate and fallback.
- * Use the brcms_basic_rate() lookup to find the best basic rate
- * under the target in case 11 Mbps is not Basic.
- * 6 and 9 Mbps are not usually selected by rate selection, but
- * even if the OFDM rate we are protecting is 6 or 9 Mbps, 11
- * is more robust.
- */
- rts_rspec = brcms_basic_rate(wlc, BRCM_RATE_11M);
- else
- /* calculate RTS rate and fallback rate based on the frame rate
- * RTS must be sent at a basic rate since it is a
- * control frame, sec 9.6 of 802.11 spec
- */
- rts_rspec = brcms_basic_rate(wlc, rspec);
+ if (use_rspec)
+ /* use frame rate as rts rate */
+ rts_rspec = rspec;
+ else if (wlc->band->gmode && wlc->protection->_g && !is_cck_rate(rspec))
+ /* Use 11Mbps as the g protection RTS target rate and fallback.
+ * Use the brcms_basic_rate() lookup to find the best basic rate
+ * under the target in case 11 Mbps is not Basic.
+ * 6 and 9 Mbps are not usually selected by rate selection, but
+ * even if the OFDM rate we are protecting is 6 or 9 Mbps, 11
+ * is more robust.
+ */
+ rts_rspec = brcms_basic_rate(wlc, BRCM_RATE_11M);
+ else
+ /* calculate RTS rate and fallback rate based on the frame rate
+ * RTS must be sent at a basic rate since it is a
+ * control frame, sec 9.6 of 802.11 spec
+ */
+ rts_rspec = brcms_basic_rate(wlc, rspec);

if (BRCMS_PHY_11N_CAP(wlc->band)) {
/* set rts txbw to correct side band */
@@ -7772,16 +7605,6 @@ brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, u32 rspec,
return rts_rspec;
}

-void brcms_c_tbtt(struct brcms_c_info *wlc)
-{
- if (!wlc->bsscfg->BSS)
- /*
- * DirFrmQ is now valid...defer setting until end
- * of ATIM window
- */
- wlc->qvalid |= MCMD_DIRFRMQVAL;
-}
-
void
brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo, s8 txpktpend)
{
@@ -7796,7 +7619,7 @@ brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo, s8 txpktpend)
}

/* Update beacon listen interval in shared memory */
-void brcms_c_bcn_li_upd(struct brcms_c_info *wlc)
+static void brcms_c_bcn_li_upd(struct brcms_c_info *wlc)
{
/* wake up every DTIM is the default */
if (wlc->bcn_li_dtim == 1)
@@ -7993,93 +7816,33 @@ brcms_c_recvctl(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p);
}

-/* Process received frames */
-/*
- * Return true if more frames need to be processed. false otherwise.
- * Param 'bound' indicates max. # frames to process before break out.
+/* calculate frame duration for Mixed-mode L-SIG spoofing, return
+ * number of bytes goes in the length field
+ *
+ * Formula given by HT PHY Spec v 1.13
+ * len = 3(nsyms + nstream + 3) - 3
*/
-void brcms_c_recv(struct brcms_c_info *wlc, struct sk_buff *p)
+u16
+brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec,
+ uint mac_len)
{
- struct d11rxhdr *rxh;
- struct ieee80211_hdr *h;
- uint len;
- bool is_amsdu;
-
- BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
-
- /* frame starts with rxhdr */
- rxh = (struct d11rxhdr *) (p->data);
+ uint nsyms, len = 0, kNdps;

- /* strip off rxhdr */
- skb_pull(p, BRCMS_HWRXOFF);
+ BCMMSG(wlc->wiphy, "wl%d: rate %d, len%d\n",
+ wlc->pub->unit, rspec2rate(ratespec), mac_len);

- /* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */
- if (rxh->RxStatus1 & RXS_PBPRES) {
- if (p->len < 2) {
- wiphy_err(wlc->wiphy, "wl%d: recv: rcvd runt of "
- "len %d\n", wlc->pub->unit, p->len);
- goto toss;
- }
- skb_pull(p, 2);
- }
+ if (is_mcs_rate(ratespec)) {
+ uint mcs = ratespec & RSPEC_RATE_MASK;
+ int tot_streams = (mcs_2_txstreams(mcs) + 1) +
+ rspec_stc(ratespec);

- h = (struct ieee80211_hdr *)(p->data + D11_PHY_HDR_LEN);
- len = p->len;
-
- if (rxh->RxStatus1 & RXS_FCSERR) {
- if (wlc->pub->mac80211_state & MAC80211_PROMISC_BCNS) {
- wiphy_err(wlc->wiphy, "FCSERR while scanning******* -"
- " tossing\n");
- goto toss;
- } else {
- wiphy_err(wlc->wiphy, "RCSERR!!!\n");
- goto toss;
- }
- }
-
- /* check received pkt has at least frame control field */
- if (len < D11_PHY_HDR_LEN + sizeof(h->frame_control))
- goto toss;
-
- /* not supporting A-MSDU */
- is_amsdu = rxh->RxStatus2 & RXS_AMSDU_MASK;
- if (is_amsdu)
- goto toss;
-
- brcms_c_recvctl(wlc, rxh, p);
- return;
-
- toss:
- brcmu_pkt_buf_free_skb(p);
-}
-
-/* calculate frame duration for Mixed-mode L-SIG spoofing, return
- * number of bytes goes in the length field
- *
- * Formula given by HT PHY Spec v 1.13
- * len = 3(nsyms + nstream + 3) - 3
- */
-u16
-brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec,
- uint mac_len)
-{
- uint nsyms, len = 0, kNdps;
-
- BCMMSG(wlc->wiphy, "wl%d: rate %d, len%d\n",
- wlc->pub->unit, rspec2rate(ratespec), mac_len);
-
- if (is_mcs_rate(ratespec)) {
- uint mcs = ratespec & RSPEC_RATE_MASK;
- int tot_streams = (mcs_2_txstreams(mcs) + 1) +
- rspec_stc(ratespec);
-
- /*
- * the payload duration calculation matches that
- * of regular ofdm
- */
- /* 1000Ndbps = kbps * 4 */
- kNdps = mcs_2_rate(mcs, rspec_is40mhz(ratespec),
- rspec_issgi(ratespec)) * 4;
+ /*
+ * the payload duration calculation matches that
+ * of regular ofdm
+ */
+ /* 1000Ndbps = kbps * 4 */
+ kNdps = mcs_2_rate(mcs, rspec_is40mhz(ratespec),
+ rspec_issgi(ratespec)) * 4;

if (rspec_stc(ratespec) == 0)
nsyms =
@@ -8104,737 +7867,847 @@ brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec,
return (u16) len;
}

-/*
- * calculate frame duration of a given rate and length, return
- * time in usec unit
- */
-uint
-brcms_c_calc_frame_time(struct brcms_c_info *wlc, u32 ratespec,
- u8 preamble_type, uint mac_len)
+static void
+brcms_c_mod_prb_rsp_rate_table(struct brcms_c_info *wlc, uint frame_len)
{
- uint nsyms, dur = 0, Ndps, kNdps;
- uint rate = rspec2rate(ratespec);
+ const struct brcms_c_rateset *rs_dflt;
+ struct brcms_c_rateset rs;
+ u8 rate;
+ u16 entry_ptr;
+ u8 plcp[D11_PHY_HDR_LEN];
+ u16 dur, sifs;
+ uint i;

- if (rate == 0) {
- wiphy_err(wlc->wiphy, "wl%d: WAR: using rate of 1 mbps\n",
- wlc->pub->unit);
- rate = BRCM_RATE_1M;
- }
+ sifs = get_sifs(wlc->band);

- BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, len%d\n",
- wlc->pub->unit, ratespec, preamble_type, mac_len);
+ rs_dflt = brcms_c_rateset_get_hwrs(wlc);

- if (is_mcs_rate(ratespec)) {
- uint mcs = ratespec & RSPEC_RATE_MASK;
- int tot_streams = mcs_2_txstreams(mcs) + rspec_stc(ratespec);
+ brcms_c_rateset_copy(rs_dflt, &rs);
+ brcms_c_rateset_mcs_upd(&rs, wlc->stf->txstreams);

- dur = PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT);
- if (preamble_type == BRCMS_MM_PREAMBLE)
- dur += PREN_MM_EXT;
- /* 1000Ndbps = kbps * 4 */
- kNdps = mcs_2_rate(mcs, rspec_is40mhz(ratespec),
- rspec_issgi(ratespec)) * 4;
+ /*
+ * walk the phy rate table and update MAC core SHM
+ * basic rate table entries
+ */
+ for (i = 0; i < rs.count; i++) {
+ rate = rs.rates[i] & BRCMS_RATE_MASK;

- if (rspec_stc(ratespec) == 0)
- nsyms =
- CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
- APHY_TAIL_NBITS) * 1000, kNdps);
- else
- /* STBC needs to have even number of symbols */
- nsyms =
- 2 *
- CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
- APHY_TAIL_NBITS) * 1000, 2 * kNdps);
+ entry_ptr = brcms_b_rate_shm_offset(wlc->hw, rate);
+
+ /* Calculate the Probe Response PLCP for the given rate */
+ brcms_c_compute_plcp(wlc, rate, frame_len, plcp);

- dur += APHY_SYMBOL_TIME * nsyms;
- if (wlc->band->bandtype == BRCM_BAND_2G)
- dur += DOT11_OFDM_SIGNAL_EXTENSION;
- } else if (is_ofdm_rate(rate)) {
- dur = APHY_PREAMBLE_TIME;
- dur += APHY_SIGNAL_TIME;
- /* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */
- Ndps = rate * 2;
- /* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */
- nsyms =
- CEIL((APHY_SERVICE_NBITS + 8 * mac_len + APHY_TAIL_NBITS),
- Ndps);
- dur += APHY_SYMBOL_TIME * nsyms;
- if (wlc->band->bandtype == BRCM_BAND_2G)
- dur += DOT11_OFDM_SIGNAL_EXTENSION;
- } else {
/*
- * calc # bits * 2 so factor of 2 in rate (1/2 mbps)
- * will divide out
+ * Calculate the duration of the Probe Response
+ * frame plus SIFS for the MAC
*/
- mac_len = mac_len * 8 * 2;
- /* calc ceiling of bits/rate = microseconds of air time */
- dur = (mac_len + rate - 1) / rate;
- if (preamble_type & BRCMS_SHORT_PREAMBLE)
- dur += BPHY_PLCP_SHORT_TIME;
- else
- dur += BPHY_PLCP_TIME;
+ dur = (u16) brcms_c_calc_frame_time(wlc, rate,
+ BRCMS_LONG_PREAMBLE, frame_len);
+ dur += sifs;
+
+ /* Update the SHM Rate Table entry Probe Response values */
+ brcms_b_write_shm(wlc->hw, entry_ptr + M_RT_PRS_PLCP_POS,
+ (u16) (plcp[0] + (plcp[1] << 8)));
+ brcms_b_write_shm(wlc->hw, entry_ptr + M_RT_PRS_PLCP_POS + 2,
+ (u16) (plcp[2] + (plcp[3] << 8)));
+ brcms_b_write_shm(wlc->hw, entry_ptr + M_RT_PRS_DUR_POS, dur);
}
- return dur;
}

-/* derive wlc->band->basic_rate[] table from 'rateset' */
-void brcms_c_rate_lookup_init(struct brcms_c_info *wlc,
- struct brcms_c_rateset *rateset)
+/* Max buffering needed for beacon template/prb resp template is 142 bytes.
+ *
+ * PLCP header is 6 bytes.
+ * 802.11 A3 header is 24 bytes.
+ * Max beacon frame body template length is 112 bytes.
+ * Max probe resp frame body template length is 110 bytes.
+ *
+ * *len on input contains the max length of the packet available.
+ *
+ * The *len value is set to the number of bytes in buf used, and starts
+ * with the PLCP and included up to, but not including, the 4 byte FCS.
+ */
+static void
+brcms_c_bcn_prb_template(struct brcms_c_info *wlc, u16 type,
+ u32 bcn_rspec,
+ struct brcms_bss_cfg *cfg, u16 *buf, int *len)
{
- u8 rate;
- u8 mandatory;
- u8 cck_basic = 0;
- u8 ofdm_basic = 0;
- u8 *br = wlc->band->basic_rate;
- uint i;
-
- /* incoming rates are in 500kbps units as in 802.11 Supported Rates */
- memset(br, 0, BRCM_MAXRATE + 1);
+ static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
+ struct cck_phy_hdr *plcp;
+ struct ieee80211_mgmt *h;
+ int hdr_len, body_len;

- /* For each basic rate in the rates list, make an entry in the
- * best basic lookup.
- */
- for (i = 0; i < rateset->count; i++) {
- /* only make an entry for a basic rate */
- if (!(rateset->rates[i] & BRCMS_RATE_FLAG))
- continue;
+ hdr_len = D11_PHY_HDR_LEN + DOT11_MAC_HDR_LEN;

- /* mask off basic bit */
- rate = (rateset->rates[i] & BRCMS_RATE_MASK);
+ /* calc buffer size provided for frame body */
+ body_len = *len - hdr_len;
+ /* return actual size */
+ *len = hdr_len + body_len;

- if (rate > BRCM_MAXRATE) {
- wiphy_err(wlc->wiphy, "brcms_c_rate_lookup_init: "
- "invalid rate 0x%X in rate set\n",
- rateset->rates[i]);
- continue;
- }
+ /* format PHY and MAC headers */
+ memset((char *)buf, 0, hdr_len);

- br[rate] = rate;
- }
+ plcp = (struct cck_phy_hdr *) buf;

- /* The rate lookup table now has non-zero entries for each
- * basic rate, equal to the basic rate: br[basicN] = basicN
- *
- * To look up the best basic rate corresponding to any
- * particular rate, code can use the basic_rate table
- * like this
- *
- * basic_rate = wlc->band->basic_rate[tx_rate]
- *
- * Make sure there is a best basic rate entry for
- * every rate by walking up the table from low rates
- * to high, filling in holes in the lookup table
+ /*
+ * PLCP for Probe Response frames are filled in from
+ * core's rate table
*/
+ if (type == IEEE80211_STYPE_BEACON)
+ /* fill in PLCP */
+ brcms_c_compute_plcp(wlc, bcn_rspec,
+ (DOT11_MAC_HDR_LEN + body_len + FCS_LEN),
+ (u8 *) plcp);

- for (i = 0; i < wlc->band->hw_rateset.count; i++) {
- rate = wlc->band->hw_rateset.rates[i];
+ /* "Regular" and 16 MBSS but not for 4 MBSS */
+ /* Update the phytxctl for the beacon based on the rspec */
+ brcms_c_beacon_phytxctl_txant_upd(wlc, bcn_rspec);

- if (br[rate] != 0) {
- /* This rate is a basic rate.
- * Keep track of the best basic rate so far by
- * modulation type.
- */
- if (is_ofdm_rate(rate))
- ofdm_basic = rate;
- else
- cck_basic = rate;
+ h = (struct ieee80211_mgmt *)&plcp[1];

- continue;
- }
+ /* fill in 802.11 header */
+ h->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | type);

- /* This rate is not a basic rate so figure out the
- * best basic rate less than this rate and fill in
- * the hole in the table
- */
+ /* DUR is 0 for multicast bcn, or filled in by MAC for prb resp */
+ /* A1 filled in by MAC for prb resp, broadcast for bcn */
+ if (type == IEEE80211_STYPE_BEACON)
+ memcpy(&h->da, &ether_bcast, ETH_ALEN);
+ memcpy(&h->sa, &cfg->cur_etheraddr, ETH_ALEN);
+ memcpy(&h->bssid, &cfg->BSSID, ETH_ALEN);

- br[rate] = is_ofdm_rate(rate) ? ofdm_basic : cck_basic;
+ /* SEQ filled in by MAC */
+}

- if (br[rate] != 0)
- continue;
+int brcms_c_get_header_len(void)
+{
+ return TXOFF;
+}

- if (is_ofdm_rate(rate)) {
- /*
- * In 11g and 11a, the OFDM mandatory rates
- * are 6, 12, and 24 Mbps
- */
- if (rate >= BRCM_RATE_24M)
- mandatory = BRCM_RATE_24M;
- else if (rate >= BRCM_RATE_12M)
- mandatory = BRCM_RATE_12M;
- else
- mandatory = BRCM_RATE_6M;
- } else {
- /* In 11b, all CCK rates are mandatory 1 - 11 Mbps */
- mandatory = rate;
- }
+/*
+ * Update all beacons for the system.
+ */
+void brcms_c_update_beacon(struct brcms_c_info *wlc)
+{
+ struct brcms_bss_cfg *bsscfg = wlc->bsscfg;

- br[rate] = mandatory;
- }
+ if (bsscfg->up && !bsscfg->BSS)
+ /* Clear the soft intmask */
+ wlc->defmacintmask &= ~MI_BCNTPL;
}

-static void brcms_c_write_rate_shm(struct brcms_c_info *wlc, u8 rate,
- u8 basic_rate)
+/* Write ssid into shared memory */
+static void
+brcms_c_shm_ssid_upd(struct brcms_c_info *wlc, struct brcms_bss_cfg *cfg)
{
- u8 phy_rate, index;
- u8 basic_phy_rate, basic_index;
- u16 dir_table, basic_table;
- u16 basic_ptr;
+ u8 *ssidptr = cfg->SSID;
+ u16 base = M_SSID;
+ u8 ssidbuf[IEEE80211_MAX_SSID_LEN];

- /* Shared memory address for the table we are reading */
- dir_table = is_ofdm_rate(basic_rate) ? M_RT_DIRMAP_A : M_RT_DIRMAP_B;
+ /* padding the ssid with zero and copy it into shm */
+ memset(ssidbuf, 0, IEEE80211_MAX_SSID_LEN);
+ memcpy(ssidbuf, ssidptr, cfg->SSID_len);

- /* Shared memory address for the table we are writing */
- basic_table = is_ofdm_rate(rate) ? M_RT_BBRSMAP_A : M_RT_BBRSMAP_B;
+ brcms_c_copyto_shm(wlc, base, ssidbuf, IEEE80211_MAX_SSID_LEN);
+ brcms_b_write_shm(wlc->hw, M_SSIDLEN, (u16) cfg->SSID_len);
+}
+
+static void
+brcms_c_bss_update_probe_resp(struct brcms_c_info *wlc,
+ struct brcms_bss_cfg *cfg,
+ bool suspend)
+{
+ u16 prb_resp[BCN_TMPL_LEN / 2];
+ int len = BCN_TMPL_LEN;

/*
- * for a given rate, the LS-nibble of the PLCP SIGNAL field is
- * the index into the rate table.
+ * write the probe response to hardware, or save in
+ * the config structure
*/
- phy_rate = rate_info[rate] & BRCMS_RATE_MASK;
- basic_phy_rate = rate_info[basic_rate] & BRCMS_RATE_MASK;
- index = phy_rate & 0xf;
- basic_index = basic_phy_rate & 0xf;

- /* Find the SHM pointer to the ACK rate entry by looking in the
- * Direct-map Table
- */
- basic_ptr = brcms_b_read_shm(wlc->hw, (dir_table + basic_index * 2));
+ /* create the probe response template */
+ brcms_c_bcn_prb_template(wlc, IEEE80211_STYPE_PROBE_RESP, 0,
+ cfg, prb_resp, &len);

- /* Update the SHM BSS-basic-rate-set mapping table with the pointer
- * to the correct basic rate for the given incoming rate
+ if (suspend)
+ brcms_c_suspend_mac_and_wait(wlc);
+
+ /* write the probe response into the template region */
+ brcms_b_write_template_ram(wlc->hw, T_PRS_TPL_BASE,
+ (len + 3) & ~3, prb_resp);
+
+ /* write the length of the probe response frame (+PLCP/-FCS) */
+ brcms_b_write_shm(wlc->hw, M_PRB_RESP_FRM_LEN, (u16) len);
+
+ /* write the SSID and SSID length */
+ brcms_c_shm_ssid_upd(wlc, cfg);
+
+ /*
+ * Write PLCP headers and durations for probe response frames
+ * at all rates. Use the actual frame length covered by the
+ * PLCP header for the call to brcms_c_mod_prb_rsp_rate_table()
+ * by subtracting the PLCP len and adding the FCS.
*/
- brcms_b_write_shm(wlc->hw, (basic_table + index * 2), basic_ptr);
+ len += (-D11_PHY_HDR_LEN + FCS_LEN);
+ brcms_c_mod_prb_rsp_rate_table(wlc, (u16) len);
+
+ if (suspend)
+ brcms_c_enable_mac(wlc);
}

-static const struct brcms_c_rateset *
-brcms_c_rateset_get_hwrs(struct brcms_c_info *wlc)
+void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend)
{
- const struct brcms_c_rateset *rs_dflt;
-
- if (BRCMS_PHY_11N_CAP(wlc->band)) {
- if (wlc->band->bandtype == BRCM_BAND_5G)
- rs_dflt = &ofdm_mimo_rates;
- else
- rs_dflt = &cck_ofdm_mimo_rates;
- } else if (wlc->band->gmode)
- rs_dflt = &cck_ofdm_rates;
- else
- rs_dflt = &cck_rates;
+ struct brcms_bss_cfg *bsscfg = wlc->bsscfg;

- return rs_dflt;
+ /* update AP or IBSS probe responses */
+ if (bsscfg->up && !bsscfg->BSS)
+ brcms_c_bss_update_probe_resp(wlc, bsscfg, suspend);
}

-void brcms_c_set_ratetable(struct brcms_c_info *wlc)
+/* prepares pdu for transmission. returns BCM error codes */
+int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu, uint *fifop)
{
- const struct brcms_c_rateset *rs_dflt;
- struct brcms_c_rateset rs;
- u8 rate, basic_rate;
- uint i;
+ uint fifo;
+ struct d11txh *txh;
+ struct ieee80211_hdr *h;
+ struct scb *scb;

- rs_dflt = brcms_c_rateset_get_hwrs(wlc);
+ txh = (struct d11txh *) (pdu->data);
+ h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN);

- brcms_c_rateset_copy(rs_dflt, &rs);
- brcms_c_rateset_mcs_upd(&rs, wlc->stf->txstreams);
+ /* get the pkt queue info. This was put at brcms_c_sendctl or
+ * brcms_c_send for PDU */
+ fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK;

- /* walk the phy rate table and update SHM basic rate lookup table */
- for (i = 0; i < rs.count; i++) {
- rate = rs.rates[i] & BRCMS_RATE_MASK;
+ scb = NULL;

- /* for a given rate brcms_basic_rate returns the rate at
- * which a response ACK/CTS should be sent.
- */
- basic_rate = brcms_basic_rate(wlc, rate);
- if (basic_rate == 0)
- /* This should only happen if we are using a
- * restricted rateset.
- */
- basic_rate = rs.rates[0] & BRCMS_RATE_MASK;
+ *fifop = fifo;

- brcms_c_write_rate_shm(wlc, rate, basic_rate);
+ /* return if insufficient dma resources */
+ if (*wlc->core->txavail[fifo] < MAX_DMA_SEGS) {
+ /* Mark precedences related to this FIFO, unsendable */
+ /* A fifo is full. Clear precedences related to that FIFO */
+ wlc->tx_prec_map &= ~(wlc->fifo2prec_map[fifo]);
+ return -EBUSY;
}
+ return 0;
}

-/*
- * Return true if the specified rate is supported by the specified band.
- * BRCM_BAND_AUTO indicates the current band.
- */
-bool brcms_c_valid_rate(struct brcms_c_info *wlc, u32 rspec, int band,
- bool verbose)
+int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
+ uint *blocks)
{
- struct brcms_c_rateset *hw_rateset;
- uint i;
+ if (fifo >= NFIFO)
+ return -EINVAL;

- if ((band == BRCM_BAND_AUTO) || (band == wlc->band->bandtype))
- hw_rateset = &wlc->band->hw_rateset;
- else if (wlc->pub->_nbands > 1)
- hw_rateset = &wlc->bandstate[OTHERBANDUNIT(wlc)]->hw_rateset;
- else
- /* other band specified and we are a single band device */
- return false;
+ *blocks = wlc_hw->xmtfifo_sz[fifo];

- /* check if this is a mimo rate */
- if (is_mcs_rate(rspec)) {
- if ((rspec & RSPEC_RATE_MASK) >= MCS_TABLE_SIZE)
- goto error;
+ return 0;
+}

- return isset(hw_rateset->mcs, (rspec & RSPEC_RATE_MASK));
- }
+void
+brcms_c_set_addrmatch(struct brcms_c_info *wlc, int match_reg_offset,
+ const u8 *addr)
+{
+ brcms_b_set_addrmatch(wlc->hw, match_reg_offset, addr);
+ if (match_reg_offset == RCM_BSSID_OFFSET)
+ memcpy(wlc->bsscfg->BSSID, addr, ETH_ALEN);
+}

- for (i = 0; i < hw_rateset->count; i++)
- if (hw_rateset->rates[i] == rspec2rate(rspec))
- return true;
- error:
- if (verbose)
- wiphy_err(wlc->wiphy, "wl%d: valid_rate: rate spec 0x%x "
- "not in hw_rateset\n", wlc->pub->unit, rspec);
+/*
+ * Flag 'scan in progress' to withhold dynamic phy calibration
+ */
+void brcms_c_scan_start(struct brcms_c_info *wlc)
+{
+ wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, true);
+}

- return false;
+void brcms_c_scan_stop(struct brcms_c_info *wlc)
+{
+ wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, false);
}

-void brcms_c_mod_prb_rsp_rate_table(struct brcms_c_info *wlc, uint frame_len)
+void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state)
{
- const struct brcms_c_rateset *rs_dflt;
- struct brcms_c_rateset rs;
- u8 rate;
- u16 entry_ptr;
- u8 plcp[D11_PHY_HDR_LEN];
- u16 dur, sifs;
- uint i;
+ wlc->pub->associated = state;
+ wlc->bsscfg->associated = state;
+}

- sifs = get_sifs(wlc->band);
+/*
+ * When a remote STA/AP is removed by Mac80211, or when it can no longer accept
+ * AMPDU traffic, packets pending in hardware have to be invalidated so that
+ * when later on hardware releases them, they can be handled appropriately.
+ */
+void brcms_c_inval_dma_pkts(struct brcms_hardware *hw,
+ struct ieee80211_sta *sta,
+ void (*dma_callback_fn))
+{
+ struct dma_pub *dmah;
+ int i;
+ for (i = 0; i < NFIFO; i++) {
+ dmah = hw->di[i];
+ if (dmah != NULL)
+ dma_walk_packets(dmah, dma_callback_fn, sta);
+ }
+}

- rs_dflt = brcms_c_rateset_get_hwrs(wlc);
+int brcms_c_get_curband(struct brcms_c_info *wlc)
+{
+ return wlc->band->bandunit;
+}

- brcms_c_rateset_copy(rs_dflt, &rs);
- brcms_c_rateset_mcs_upd(&rs, wlc->stf->txstreams);
+void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, bool drop)
+{
+ /* flush packet queue when requested */
+ if (drop)
+ brcmu_pktq_flush(&wlc->pkt_queue->q, false, NULL, NULL);

- /*
- * walk the phy rate table and update MAC core SHM
- * basic rate table entries
- */
- for (i = 0; i < rs.count; i++) {
- rate = rs.rates[i] & BRCMS_RATE_MASK;
+ /* wait for queue and DMA fifos to run dry */
+ while (!pktq_empty(&wlc->pkt_queue->q) || brcms_txpktpendtot(wlc) > 0)
+ brcms_msleep(wlc->wl, 1);
+}

- entry_ptr = brcms_b_rate_shm_offset(wlc->hw, rate);
+void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, u8 interval)
+{
+ wlc->bcn_li_bcn = interval;
+ if (wlc->pub->up)
+ brcms_c_bcn_li_upd(wlc);
+}

- /* Calculate the Probe Response PLCP for the given rate */
- brcms_c_compute_plcp(wlc, rate, frame_len, plcp);
+int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr)
+{
+ uint qdbm;

- /*
- * Calculate the duration of the Probe Response
- * frame plus SIFS for the MAC
- */
- dur = (u16) brcms_c_calc_frame_time(wlc, rate,
- BRCMS_LONG_PREAMBLE, frame_len);
- dur += sifs;
+ /* Remove override bit and clip to max qdbm value */
+ qdbm = min_t(uint, txpwr * BRCMS_TXPWR_DB_FACTOR, 0xff);
+ return wlc_phy_txpower_set(wlc->band->pi, qdbm, false);
+}

- /* Update the SHM Rate Table entry Probe Response values */
- brcms_b_write_shm(wlc->hw, entry_ptr + M_RT_PRS_PLCP_POS,
- (u16) (plcp[0] + (plcp[1] << 8)));
- brcms_b_write_shm(wlc->hw, entry_ptr + M_RT_PRS_PLCP_POS + 2,
- (u16) (plcp[2] + (plcp[3] << 8)));
- brcms_b_write_shm(wlc->hw, entry_ptr + M_RT_PRS_DUR_POS, dur);
- }
+int brcms_c_get_tx_power(struct brcms_c_info *wlc)
+{
+ uint qdbm;
+ bool override;
+
+ wlc_phy_txpower_get(wlc->band->pi, &qdbm, &override);
+
+ /* Return qdbm units */
+ return (int)(qdbm / BRCMS_TXPWR_DB_FACTOR);
}

-/* Max buffering needed for beacon template/prb resp template is 142 bytes.
- *
- * PLCP header is 6 bytes.
- * 802.11 A3 header is 24 bytes.
- * Max beacon frame body template length is 112 bytes.
- * Max probe resp frame body template length is 110 bytes.
- *
- * *len on input contains the max length of the packet available.
- *
- * The *len value is set to the number of bytes in buf used, and starts
- * with the PLCP and included up to, but not including, the 4 byte FCS.
- */
-static void
-brcms_c_bcn_prb_template(struct brcms_c_info *wlc, u16 type,
- u32 bcn_rspec,
- struct brcms_bss_cfg *cfg, u16 *buf, int *len)
+void brcms_c_set_radio_mpc(struct brcms_c_info *wlc, bool mpc)
{
- static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
- struct cck_phy_hdr *plcp;
- struct ieee80211_mgmt *h;
- int hdr_len, body_len;
+ wlc->mpc = mpc;
+ brcms_c_radio_mpc_upd(wlc);
+}

- hdr_len = D11_PHY_HDR_LEN + DOT11_MAC_HDR_LEN;
+/* Process received frames */
+/*
+ * Return true if more frames need to be processed. false otherwise.
+ * Param 'bound' indicates max. # frames to process before break out.
+ */
+static void brcms_c_recv(struct brcms_c_info *wlc, struct sk_buff *p)
+{
+ struct d11rxhdr *rxh;
+ struct ieee80211_hdr *h;
+ uint len;
+ bool is_amsdu;

- /* calc buffer size provided for frame body */
- body_len = *len - hdr_len;
- /* return actual size */
- *len = hdr_len + body_len;
+ BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);

- /* format PHY and MAC headers */
- memset((char *)buf, 0, hdr_len);
+ /* frame starts with rxhdr */
+ rxh = (struct d11rxhdr *) (p->data);

- plcp = (struct cck_phy_hdr *) buf;
+ /* strip off rxhdr */
+ skb_pull(p, BRCMS_HWRXOFF);

- /*
- * PLCP for Probe Response frames are filled in from
- * core's rate table
- */
- if (type == IEEE80211_STYPE_BEACON)
- /* fill in PLCP */
- brcms_c_compute_plcp(wlc, bcn_rspec,
- (DOT11_MAC_HDR_LEN + body_len + FCS_LEN),
- (u8 *) plcp);
+ /* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */
+ if (rxh->RxStatus1 & RXS_PBPRES) {
+ if (p->len < 2) {
+ wiphy_err(wlc->wiphy, "wl%d: recv: rcvd runt of "
+ "len %d\n", wlc->pub->unit, p->len);
+ goto toss;
+ }
+ skb_pull(p, 2);
+ }

- /* "Regular" and 16 MBSS but not for 4 MBSS */
- /* Update the phytxctl for the beacon based on the rspec */
- brcms_c_beacon_phytxctl_txant_upd(wlc, bcn_rspec);
+ h = (struct ieee80211_hdr *)(p->data + D11_PHY_HDR_LEN);
+ len = p->len;

- h = (struct ieee80211_mgmt *)&plcp[1];
+ if (rxh->RxStatus1 & RXS_FCSERR) {
+ if (wlc->pub->mac80211_state & MAC80211_PROMISC_BCNS) {
+ wiphy_err(wlc->wiphy, "FCSERR while scanning******* -"
+ " tossing\n");
+ goto toss;
+ } else {
+ wiphy_err(wlc->wiphy, "RCSERR!!!\n");
+ goto toss;
+ }
+ }

- /* fill in 802.11 header */
- h->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | type);
+ /* check received pkt has at least frame control field */
+ if (len < D11_PHY_HDR_LEN + sizeof(h->frame_control))
+ goto toss;

- /* DUR is 0 for multicast bcn, or filled in by MAC for prb resp */
- /* A1 filled in by MAC for prb resp, broadcast for bcn */
- if (type == IEEE80211_STYPE_BEACON)
- memcpy(&h->da, &ether_bcast, ETH_ALEN);
- memcpy(&h->sa, &cfg->cur_etheraddr, ETH_ALEN);
- memcpy(&h->bssid, &cfg->BSSID, ETH_ALEN);
+ /* not supporting A-MSDU */
+ is_amsdu = rxh->RxStatus2 & RXS_AMSDU_MASK;
+ if (is_amsdu)
+ goto toss;

- /* SEQ filled in by MAC */
-}
+ brcms_c_recvctl(wlc, rxh, p);
+ return;

-int brcms_c_get_header_len(void)
-{
- return TXOFF;
+ toss:
+ brcmu_pkt_buf_free_skb(p);
}

+/* Process received frames */
/*
- * Update all beacons for the system.
+ * Return true if more frames need to be processed. false otherwise.
+ * Param 'bound' indicates max. # frames to process before break out.
*/
-void brcms_c_update_beacon(struct brcms_c_info *wlc)
+static bool
+brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound)
{
- struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
+ struct sk_buff *p;
+ struct sk_buff *head = NULL;
+ struct sk_buff *tail = NULL;
+ uint n = 0;
+ uint bound_limit = bound ? RXBND : -1;

- if (bsscfg->up && !bsscfg->BSS)
- /* Clear the soft intmask */
- wlc->defmacintmask &= ~MI_BCNTPL;
-}
+ BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+ /* gather received frames */
+ while ((p = dma_rx(wlc_hw->di[fifo]))) {

-/* Write ssid into shared memory */
-void brcms_c_shm_ssid_upd(struct brcms_c_info *wlc, struct brcms_bss_cfg *cfg)
-{
- u8 *ssidptr = cfg->SSID;
- u16 base = M_SSID;
- u8 ssidbuf[IEEE80211_MAX_SSID_LEN];
+ if (!tail)
+ head = tail = p;
+ else {
+ tail->prev = p;
+ tail = p;
+ }

- /* padding the ssid with zero and copy it into shm */
- memset(ssidbuf, 0, IEEE80211_MAX_SSID_LEN);
- memcpy(ssidbuf, ssidptr, cfg->SSID_len);
+ /* !give others some time to run! */
+ if (++n >= bound_limit)
+ break;
+ }

- brcms_c_copyto_shm(wlc, base, ssidbuf, IEEE80211_MAX_SSID_LEN);
- brcms_b_write_shm(wlc->hw, M_SSIDLEN, (u16) cfg->SSID_len);
+ /* post more rbufs */
+ dma_rxfill(wlc_hw->di[fifo]);
+
+ /* process each frame */
+ while ((p = head) != NULL) {
+ struct d11rxhdr_le *rxh_le;
+ struct d11rxhdr *rxh;
+ head = head->prev;
+ p->prev = NULL;
+
+ rxh_le = (struct d11rxhdr_le *)p->data;
+ rxh = (struct d11rxhdr *)p->data;
+
+ /* fixup rx header endianness */
+ rxh->RxFrameSize = le16_to_cpu(rxh_le->RxFrameSize);
+ rxh->PhyRxStatus_0 = le16_to_cpu(rxh_le->PhyRxStatus_0);
+ rxh->PhyRxStatus_1 = le16_to_cpu(rxh_le->PhyRxStatus_1);
+ rxh->PhyRxStatus_2 = le16_to_cpu(rxh_le->PhyRxStatus_2);
+ rxh->PhyRxStatus_3 = le16_to_cpu(rxh_le->PhyRxStatus_3);
+ rxh->PhyRxStatus_4 = le16_to_cpu(rxh_le->PhyRxStatus_4);
+ rxh->PhyRxStatus_5 = le16_to_cpu(rxh_le->PhyRxStatus_5);
+ rxh->RxStatus1 = le16_to_cpu(rxh_le->RxStatus1);
+ rxh->RxStatus2 = le16_to_cpu(rxh_le->RxStatus2);
+ rxh->RxTSFTime = le16_to_cpu(rxh_le->RxTSFTime);
+ rxh->RxChan = le16_to_cpu(rxh_le->RxChan);
+
+ brcms_c_recv(wlc_hw->wlc, p);
+ }
+
+ return n >= bound_limit;
}

-void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend)
+/* second-level interrupt processing
+ * Return true if another dpc needs to be re-scheduled. false otherwise.
+ * Param 'bounded' indicates if applicable loops should be bounded.
+ */
+bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded)
{
- struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
+ u32 macintstatus;
+ struct brcms_hardware *wlc_hw = wlc->hw;
+ struct d11regs __iomem *regs = wlc_hw->regs;
+ struct wiphy *wiphy = wlc->wiphy;

- /* update AP or IBSS probe responses */
- if (bsscfg->up && !bsscfg->BSS)
- brcms_c_bss_update_probe_resp(wlc, bsscfg, suspend);
+ if (brcms_deviceremoved(wlc)) {
+ wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
+ __func__);
+ brcms_down(wlc->wl);
+ return false;
+ }
+
+ /* grab and clear the saved software intstatus bits */
+ macintstatus = wlc->macintstatus;
+ wlc->macintstatus = 0;
+
+ BCMMSG(wlc->wiphy, "wl%d: macintstatus 0x%x\n",
+ wlc_hw->unit, macintstatus);
+
+ WARN_ON(macintstatus & MI_PRQ); /* PRQ Interrupt in non-MBSS */
+
+ /* tx status */
+ if (macintstatus & MI_TFS) {
+ bool fatal;
+ if (brcms_b_txstatus(wlc->hw, bounded, &fatal))
+ wlc->macintstatus |= MI_TFS;
+ if (fatal) {
+ wiphy_err(wiphy, "MI_TFS: fatal\n");
+ goto fatal;
+ }
+ }
+
+ if (macintstatus & (MI_TBTT | MI_DTIM_TBTT))
+ brcms_c_tbtt(wlc);
+
+ /* ATIM window end */
+ if (macintstatus & MI_ATIMWINEND) {
+ BCMMSG(wlc->wiphy, "end of ATIM window\n");
+ OR_REG(&regs->maccommand, wlc->qvalid);
+ wlc->qvalid = 0;
+ }
+
+ /*
+ * received data or control frame, MI_DMAINT is
+ * indication of RX_FIFO interrupt
+ */
+ if (macintstatus & MI_DMAINT)
+ if (brcms_b_recv(wlc_hw, RX_FIFO, bounded))
+ wlc->macintstatus |= MI_DMAINT;
+
+ /* noise sample collected */
+ if (macintstatus & MI_BG_NOISE)
+ wlc_phy_noise_sample_intr(wlc_hw->band->pi);
+
+ if (macintstatus & MI_GP0) {
+ wiphy_err(wiphy, "wl%d: PSM microcode watchdog fired at %d "
+ "(seconds). Resetting.\n", wlc_hw->unit, wlc_hw->now);
+
+ printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n",
+ __func__, wlc_hw->sih->chip,
+ wlc_hw->sih->chiprev);
+ /* big hammer */
+ brcms_init(wlc->wl);
+ }
+
+ /* gptimer timeout */
+ if (macintstatus & MI_TO)
+ W_REG(&regs->gptimer, 0);
+
+ if (macintstatus & MI_RFDISABLE) {
+ BCMMSG(wlc->wiphy, "wl%d: BMAC Detected a change on the"
+ " RF Disable Input\n", wlc_hw->unit);
+ brcms_rfkill_set_hw_state(wlc->wl);
+ }
+
+ /* send any enq'd tx packets. Just makes sure to jump start tx */
+ if (!pktq_empty(&wlc->pkt_queue->q))
+ brcms_c_send_q(wlc);
+
+ /* it isn't done and needs to be resched if macintstatus is non-zero */
+ return wlc->macintstatus != 0;
+
+ fatal:
+ brcms_init(wlc->wl);
+ return wlc->macintstatus != 0;
}

-void
-brcms_c_bss_update_probe_resp(struct brcms_c_info *wlc,
- struct brcms_bss_cfg *cfg,
- bool suspend)
+void brcms_c_init(struct brcms_c_info *wlc)
{
- u16 prb_resp[BCN_TMPL_LEN / 2];
- int len = BCN_TMPL_LEN;
+ struct d11regs __iomem *regs;
+ u16 chanspec;
+ bool mute = false;
+
+ BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
+
+ regs = wlc->regs;

/*
- * write the probe response to hardware, or save in
- * the config structure
+ * This will happen if a big-hammer was executed. In
+ * that case, we want to go back to the channel that
+ * we were on and not new channel
*/
+ if (wlc->pub->associated)
+ chanspec = wlc->home_chanspec;
+ else
+ chanspec = brcms_c_init_chanspec(wlc);

- /* create the probe response template */
- brcms_c_bcn_prb_template(wlc, IEEE80211_STYPE_PROBE_RESP, 0,
- cfg, prb_resp, &len);
+ brcms_b_init(wlc->hw, chanspec, mute);

- if (suspend)
- brcms_c_suspend_mac_and_wait(wlc);
+ /* update beacon listen interval */
+ brcms_c_bcn_li_upd(wlc);

- /* write the probe response into the template region */
- brcms_b_write_template_ram(wlc->hw, T_PRS_TPL_BASE,
- (len + 3) & ~3, prb_resp);
+ /* write ethernet address to core */
+ brcms_c_set_mac(wlc->bsscfg);
+ brcms_c_set_bssid(wlc->bsscfg);

- /* write the length of the probe response frame (+PLCP/-FCS) */
- brcms_b_write_shm(wlc->hw, M_PRB_RESP_FRM_LEN, (u16) len);
+ /* Update tsf_cfprep if associated and up */
+ if (wlc->pub->associated && wlc->bsscfg->up) {
+ u32 bi;

- /* write the SSID and SSID length */
- brcms_c_shm_ssid_upd(wlc, cfg);
+ /* get beacon period and convert to uS */
+ bi = wlc->bsscfg->current_bss->beacon_period << 10;
+ /*
+ * update since init path would reset
+ * to default value
+ */
+ W_REG(&regs->tsf_cfprep,
+ (bi << CFPREP_CBI_SHIFT));
+
+ /* Update maccontrol PM related bits */
+ brcms_c_set_ps_ctrl(wlc);
+ }
+
+ brcms_c_bandinit_ordered(wlc, chanspec);
+
+ /* init probe response timeout */
+ brcms_b_write_shm(wlc->hw, M_PRS_MAXTIME, wlc->prb_resp_timeout);
+
+ /* init max burst txop (framebursting) */
+ brcms_b_write_shm(wlc->hw, M_MBURST_TXOP,
+ (wlc->
+ _rifs ? (EDCF_AC_VO_TXOP_AP << 5) : MAXFRAMEBURST_TXOP));
+
+ /* initialize maximum allowed duty cycle */
+ brcms_c_duty_cycle_set(wlc, wlc->tx_duty_cycle_ofdm, true, true);
+ brcms_c_duty_cycle_set(wlc, wlc->tx_duty_cycle_cck, false, true);

/*
- * Write PLCP headers and durations for probe response frames
- * at all rates. Use the actual frame length covered by the
- * PLCP header for the call to brcms_c_mod_prb_rsp_rate_table()
- * by subtracting the PLCP len and adding the FCS.
+ * Update some shared memory locations related to
+ * max AMPDU size allowed to received
*/
- len += (-D11_PHY_HDR_LEN + FCS_LEN);
- brcms_c_mod_prb_rsp_rate_table(wlc, (u16) len);
+ brcms_c_ampdu_shm_upd(wlc->ampdu);

- if (suspend)
- brcms_c_enable_mac(wlc);
-}
+ /* band-specific inits */
+ brcms_c_bsinit(wlc);

-/* prepares pdu for transmission. returns BCM error codes */
-int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu, uint *fifop)
-{
- uint fifo;
- struct d11txh *txh;
- struct ieee80211_hdr *h;
- struct scb *scb;
+ /* Enable EDCF mode (while the MAC is suspended) */
+ OR_REG(&regs->ifs_ctl, IFS_USEEDCF);
+ brcms_c_edcf_setparams(wlc, false);

- txh = (struct d11txh *) (pdu->data);
- h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN);
+ /* Init precedence maps for empty FIFOs */
+ brcms_c_tx_prec_map_init(wlc);

- /* get the pkt queue info. This was put at brcms_c_sendctl or
- * brcms_c_send for PDU */
- fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK;
+ /* read the ucode version if we have not yet done so */
+ if (wlc->ucode_rev == 0) {
+ wlc->ucode_rev =
+ brcms_b_read_shm(wlc->hw, M_BOM_REV_MAJOR) << NBITS(u16);
+ wlc->ucode_rev |= brcms_b_read_shm(wlc->hw, M_BOM_REV_MINOR);
+ }

- scb = NULL;
+ /* ..now really unleash hell (allow the MAC out of suspend) */
+ brcms_c_enable_mac(wlc);

- *fifop = fifo;
+ /* clear tx flow control */
+ brcms_c_txflowcontrol_reset(wlc);

- /* return if insufficient dma resources */
- if (*wlc->core->txavail[fifo] < MAX_DMA_SEGS) {
- /* Mark precedences related to this FIFO, unsendable */
- /* A fifo is full. Clear precedences related to that FIFO */
- wlc->tx_prec_map &= ~(wlc->fifo2prec_map[fifo]);
- return -EBUSY;
- }
- return 0;
-}
+ /* enable the RF Disable Delay timer */
+ W_REG(&wlc->regs->rfdisabledly, RFDISABLE_DEFAULT);

-void brcms_default_rateset(struct brcms_c_info *wlc, struct brcms_c_rateset *rs)
-{
- brcms_c_rateset_default(rs, NULL, wlc->band->phytype,
- wlc->band->bandtype, false, BRCMS_RATE_MASK_FULL,
- (bool) (wlc->pub->_n_enab & SUPPORT_11N),
- brcms_chspec_bw(wlc->default_bss->chanspec),
- wlc->stf->txstreams);
-}
+ /* initialize mpc delay */
+ wlc->mpc_delay_off = wlc->mpc_dlycnt = BRCMS_MPC_MIN_DELAYCNT;

-/* Copy a buffer to shared memory.
- * SHM 'offset' needs to be an even address and
- * Buffer length 'len' must be an even number of bytes
- */
-void brcms_c_copyto_shm(struct brcms_c_info *wlc, uint offset, const void *buf,
- int len)
-{
- brcms_b_copyto_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL);
+ /*
+ * Initialize WME parameters; if they haven't been set by some other
+ * mechanism (IOVar, etc) then read them from the hardware.
+ */
+ if (GFIELD(wlc->wme_retries[0], EDCF_SHORT) == 0) {
+ /* Uninitialized; read from HW */
+ int ac;
+
+ for (ac = 0; ac < AC_COUNT; ac++)
+ wlc->wme_retries[ac] =
+ brcms_b_read_shm(wlc->hw, M_AC_TXLMT_ADDR(ac));
+ }
}

-int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
- uint *blocks)
+/*
+ * The common driver entry routine. Error codes should be unique
+ */
+struct brcms_c_info *
+brcms_c_attach(struct brcms_info *wl, u16 vendor, u16 device, uint unit,
+ bool piomode, void __iomem *regsva, struct pci_dev *btparam,
+ uint *perr)
{
- if (fifo >= NFIFO)
- return -EINVAL;
+ struct brcms_c_info *wlc;
+ uint err = 0;
+ uint i, j;
+ struct brcms_pub *pub;

- *blocks = wlc_hw->xmtfifo_sz[fifo];
+ /* allocate struct brcms_c_info state and its substructures */
+ wlc = (struct brcms_c_info *) brcms_c_attach_malloc(unit, &err, device);
+ if (wlc == NULL)
+ goto fail;
+ wlc->wiphy = wl->wiphy;
+ pub = wlc->pub;

- return 0;
-}
+#if defined(BCMDBG)
+ wlc_info_dbg = wlc;
+#endif

-void
-brcms_c_set_addrmatch(struct brcms_c_info *wlc, int match_reg_offset,
- const u8 *addr)
-{
- brcms_b_set_addrmatch(wlc->hw, match_reg_offset, addr);
- if (match_reg_offset == RCM_BSSID_OFFSET)
- memcpy(wlc->bsscfg->BSSID, addr, ETH_ALEN);
-}
+ wlc->band = wlc->bandstate[0];
+ wlc->core = wlc->corestate;
+ wlc->wl = wl;
+ pub->unit = unit;
+ pub->_piomode = piomode;
+ wlc->bandinit_pending = false;

-/* check for the particular priority flow control bit being set */
-bool
-brcms_c_txflowcontrol_prio_isset(struct brcms_c_info *wlc,
- struct brcms_txq_info *q,
- int prio)
-{
- uint prio_mask;
+ /* populate struct brcms_c_info with default values */
+ brcms_c_info_init(wlc, unit);

- if (prio == ALLPRIO)
- prio_mask = TXQ_STOP_FOR_PRIOFC_MASK;
- else
- prio_mask = NBITVAL(prio);
+ /* update sta/ap related parameters */
+ brcms_c_ap_upd(wlc);

- return (q->stopped & prio_mask) == prio_mask;
-}
+ /*
+ * low level attach steps(all hw accesses go
+ * inside, no more in rest of the attach)
+ */
+ err = brcms_b_attach(wlc, vendor, device, unit, piomode, regsva,
+ btparam);
+ if (err)
+ goto fail;

-/* propagate the flow control to all interfaces using the given tx queue */
-void brcms_c_txflowcontrol(struct brcms_c_info *wlc,
- struct brcms_txq_info *qi,
- bool on, int prio)
-{
- uint prio_bits;
- uint cur_bits;
+ brcms_c_protection_upd(wlc, BRCMS_PROT_N_PAM_OVR, OFF);

- BCMMSG(wlc->wiphy, "flow control kicks in\n");
+ pub->phy_11ncapable = BRCMS_PHY_11N_CAP(wlc->band);

- if (prio == ALLPRIO)
- prio_bits = TXQ_STOP_FOR_PRIOFC_MASK;
- else
- prio_bits = NBITVAL(prio);
+ /* disable allowed duty cycle */
+ wlc->tx_duty_cycle_ofdm = 0;
+ wlc->tx_duty_cycle_cck = 0;

- cur_bits = qi->stopped & prio_bits;
+ brcms_c_stf_phy_chain_calc(wlc);

- /* Check for the case of no change and return early
- * Otherwise update the bit and continue
- */
- if (on) {
- if (cur_bits == prio_bits)
- return;
+ /* txchain 1: txant 0, txchain 2: txant 1 */
+ if (BRCMS_ISNPHY(wlc->band) && (wlc->stf->txstreams == 1))
+ wlc->stf->txant = wlc->stf->hw_txchain - 1;

- mboolset(qi->stopped, prio_bits);
- } else {
- if (cur_bits == 0)
- return;
+ /* push to BMAC driver */
+ wlc_phy_stf_chain_init(wlc->band->pi, wlc->stf->hw_txchain,
+ wlc->stf->hw_rxchain);

- mboolclr(qi->stopped, prio_bits);
- }
+ /* pull up some info resulting from the low attach */
+ for (i = 0; i < NFIFO; i++)
+ wlc->core->txavail[i] = wlc->hw->txavail[i];

- /* If there is a flow control override we will not change the external
- * flow control state.
- */
- if (qi->stopped & ~TXQ_STOP_FOR_PRIOFC_MASK)
- return;
+ memcpy(&wlc->perm_etheraddr, &wlc->hw->etheraddr, ETH_ALEN);
+ memcpy(&pub->cur_etheraddr, &wlc->hw->etheraddr, ETH_ALEN);

- brcms_c_txflowcontrol_signal(wlc, qi, on, prio);
-}
+ for (j = 0; j < wlc->pub->_nbands; j++) {
+ wlc->band = wlc->bandstate[j];

-void
-brcms_c_txflowcontrol_override(struct brcms_c_info *wlc,
- struct brcms_txq_info *qi,
- bool on, uint override)
-{
- uint prev_override;
+ if (!brcms_c_attach_stf_ant_init(wlc)) {
+ err = 24;
+ goto fail;
+ }

- prev_override = (qi->stopped & ~TXQ_STOP_FOR_PRIOFC_MASK);
+ /* default contention windows size limits */
+ wlc->band->CWmin = APHY_CWMIN;
+ wlc->band->CWmax = PHY_CWMAX;

- /* Update the flow control bits and do an early return if there is
- * no change in the external flow control state.
- */
- if (on) {
- mboolset(qi->stopped, override);
- /* if there was a previous override bit on, then setting this
- * makes no difference.
- */
- if (prev_override)
- return;
+ /* init gmode value */
+ if (wlc->band->bandtype == BRCM_BAND_2G) {
+ wlc->band->gmode = GMODE_AUTO;
+ brcms_c_protection_upd(wlc, BRCMS_PROT_G_USER,
+ wlc->band->gmode);
+ }

- brcms_c_txflowcontrol_signal(wlc, qi, ON, ALLPRIO);
- } else {
- mboolclr(qi->stopped, override);
- /* clearing an override bit will only make a difference for
- * flow control if it was the only bit set. For any other
- * override setting, just return
- */
- if (prev_override != override)
- return;
+ /* init _n_enab supported mode */
+ if (BRCMS_PHY_11N_CAP(wlc->band)) {
+ pub->_n_enab = SUPPORT_11N;
+ brcms_c_protection_upd(wlc, BRCMS_PROT_N_USER,
+ ((pub->_n_enab ==
+ SUPPORT_11N) ? WL_11N_2x2 :
+ WL_11N_3x3));
+ }

- if (qi->stopped == 0) {
- brcms_c_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO);
- } else {
- int prio;
+ /* init per-band default rateset, depend on band->gmode */
+ brcms_default_rateset(wlc, &wlc->band->defrateset);

- for (prio = MAXPRIO; prio >= 0; prio--) {
- if (!mboolisset(qi->stopped, NBITVAL(prio)))
- brcms_c_txflowcontrol_signal(
- wlc, qi, OFF, prio);
- }
- }
+ /* fill in hw_rateset */
+ brcms_c_rateset_filter(&wlc->band->defrateset,
+ &wlc->band->hw_rateset, false,
+ BRCMS_RATES_CCK_OFDM, BRCMS_RATE_MASK,
+ (bool) (wlc->pub->_n_enab & SUPPORT_11N));
}
-}

-/*
- * Flag 'scan in progress' to withhold dynamic phy calibration
- */
-void brcms_c_scan_start(struct brcms_c_info *wlc)
-{
- wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, true);
-}
+ /*
+ * update antenna config due to
+ * wlc->stf->txant/txchain/ant_rx_ovr change
+ */
+ brcms_c_stf_phy_txant_upd(wlc);

-void brcms_c_scan_stop(struct brcms_c_info *wlc)
-{
- wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, false);
-}
+ /* attach each modules */
+ err = brcms_c_attach_module(wlc);
+ if (err != 0)
+ goto fail;

-void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state)
-{
- wlc->pub->associated = state;
- wlc->bsscfg->associated = state;
-}
+ if (!brcms_c_timers_init(wlc, unit)) {
+ wiphy_err(wl->wiphy, "wl%d: %s: init_timer failed\n", unit,
+ __func__);
+ err = 32;
+ goto fail;
+ }

-/*
- * When a remote STA/AP is removed by Mac80211, or when it can no longer accept
- * AMPDU traffic, packets pending in hardware have to be invalidated so that
- * when later on hardware releases them, they can be handled appropriately.
- */
-void brcms_c_inval_dma_pkts(struct brcms_hardware *hw,
- struct ieee80211_sta *sta,
- void (*dma_callback_fn))
-{
- struct dma_pub *dmah;
- int i;
- for (i = 0; i < NFIFO; i++) {
- dmah = hw->di[i];
- if (dmah != NULL)
- dma_walk_packets(dmah, dma_callback_fn, sta);
+ /* depend on rateset, gmode */
+ wlc->cmi = brcms_c_channel_mgr_attach(wlc);
+ if (!wlc->cmi) {
+ wiphy_err(wl->wiphy, "wl%d: %s: channel_mgr_attach failed"
+ "\n", unit, __func__);
+ err = 33;
+ goto fail;
}
-}

-int brcms_c_get_curband(struct brcms_c_info *wlc)
-{
- return wlc->band->bandunit;
-}
+ /* init default when all parameters are ready, i.e. ->rateset */
+ brcms_c_bss_default_init(wlc);

-void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, bool drop)
-{
- /* flush packet queue when requested */
- if (drop)
- brcmu_pktq_flush(&wlc->pkt_queue->q, false, NULL, NULL);
+ /*
+ * Complete the wlc default state initializations..
+ */

- /* wait for queue and DMA fifos to run dry */
- while (!pktq_empty(&wlc->pkt_queue->q) || brcms_txpktpendtot(wlc) > 0)
- brcms_msleep(wlc->wl, 1);
-}
+ /* allocate our initial queue */
+ wlc->pkt_queue = brcms_c_txq_alloc(wlc);
+ if (wlc->pkt_queue == NULL) {
+ wiphy_err(wl->wiphy, "wl%d: %s: failed to malloc tx queue\n",
+ unit, __func__);
+ err = 100;
+ goto fail;
+ }

-void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, u8 interval)
-{
- wlc->bcn_li_bcn = interval;
- if (wlc->pub->up)
- brcms_c_bcn_li_upd(wlc);
-}
+ wlc->bsscfg->wlc = wlc;

-int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr)
-{
- uint qdbm;
+ wlc->mimoft = FT_HT;
+ wlc->mimo_40txbw = AUTO;
+ wlc->ofdm_40txbw = AUTO;
+ wlc->cck_40txbw = AUTO;
+ brcms_c_update_mimo_band_bwcap(wlc, BRCMS_N_BW_20IN2G_40IN5G);

- /* Remove override bit and clip to max qdbm value */
- qdbm = min_t(uint, txpwr * BRCMS_TXPWR_DB_FACTOR, 0xff);
- return wlc_phy_txpower_set(wlc->band->pi, qdbm, false);
-}
+ /* Set default values of SGI */
+ if (BRCMS_SGI_CAP_PHY(wlc)) {
+ brcms_c_ht_update_sgi_rx(wlc, (BRCMS_N_SGI_20 |
+ BRCMS_N_SGI_40));
+ } else if (BRCMS_ISSSLPNPHY(wlc->band)) {
+ brcms_c_ht_update_sgi_rx(wlc, (BRCMS_N_SGI_20 |
+ BRCMS_N_SGI_40));
+ } else {
+ brcms_c_ht_update_sgi_rx(wlc, 0);
+ }

-int brcms_c_get_tx_power(struct brcms_c_info *wlc)
-{
- uint qdbm;
- bool override;
+ /* initialize radio_mpc_disable according to wlc->mpc */
+ brcms_c_radio_mpc_upd(wlc);
+ brcms_b_antsel_set(wlc->hw, wlc->asi->antsel_avail);

- wlc_phy_txpower_get(wlc->band->pi, &qdbm, &override);
+ if (perr)
+ *perr = 0;

- /* Return qdbm units */
- return (int)(qdbm / BRCMS_TXPWR_DB_FACTOR);
-}
+ return wlc;

-void brcms_c_set_radio_mpc(struct brcms_c_info *wlc, bool mpc)
-{
- wlc->mpc = mpc;
- brcms_c_radio_mpc_upd(wlc);
+ fail:
+ wiphy_err(wl->wiphy, "wl%d: %s: failed with err %d\n",
+ unit, __func__, err);
+ if (wlc)
+ brcms_c_detach(wlc);
+
+ if (perr)
+ *perr = err;
+ return NULL;
}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.h b/drivers/net/wireless/brcm80211/brcmsmac/main.h
index 7a2554f..c0e0fcf 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h
@@ -653,9 +653,6 @@ struct brcms_bss_cfg {
struct brcms_bss_info *current_bss;
};

-extern void brcms_c_fatal_error(struct brcms_c_info *wlc);
-extern void brcms_b_rpc_watchdog(struct brcms_c_info *wlc);
-extern void brcms_c_recv(struct brcms_c_info *wlc, struct sk_buff *p);
extern void brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo,
struct sk_buff *p,
bool commit, s8 txpktpend);
@@ -663,47 +660,22 @@ extern void brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo,
s8 txpktpend);
extern void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb,
struct sk_buff *sdu, uint prec);
-extern void brcms_c_info_init(struct brcms_c_info *wlc, int unit);
extern void brcms_c_print_txstatus(struct tx_status *txs);
extern int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
uint *blocks);

#if defined(BCMDBG)
-extern void brcms_c_print_rxh(struct d11rxhdr *rxh);
extern void brcms_c_print_txdesc(struct d11txh *txh);
#else
#define brcms_c_print_txdesc(a)
#endif

-extern void brcms_c_setxband(struct brcms_hardware *wlc_hw, uint bandunit);
-extern void brcms_c_coredisable(struct brcms_hardware *wlc_hw);
-
-extern bool brcms_c_valid_rate(struct brcms_c_info *wlc, u32 rate,
- int band, bool verbose);
-extern void brcms_c_ap_upd(struct brcms_c_info *wlc);
-
-/* helper functions */
-extern void brcms_c_shm_ssid_upd(struct brcms_c_info *wlc,
- struct brcms_bss_cfg *cfg);
extern int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config);
-
extern void brcms_c_mac_bcn_promisc_change(struct brcms_c_info *wlc,
bool promisc);
-extern void brcms_c_mac_bcn_promisc(struct brcms_c_info *wlc);
-extern void brcms_c_mac_promisc(struct brcms_c_info *wlc);
-extern void brcms_c_txflowcontrol(struct brcms_c_info *wlc,
- struct brcms_txq_info *qi,
- bool on, int prio);
-extern void brcms_c_txflowcontrol_override(struct brcms_c_info *wlc,
- struct brcms_txq_info *qi,
- bool on, uint override);
-extern bool brcms_c_txflowcontrol_prio_isset(struct brcms_c_info *wlc,
- struct brcms_txq_info *qi,
- int prio);
extern void brcms_c_send_q(struct brcms_c_info *wlc);
extern int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu,
uint *fifo);
-
extern u16 brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec,
uint mac_len);
extern u32 brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc,
@@ -715,82 +687,26 @@ extern u16 brcms_c_compute_rtscts_dur(struct brcms_c_info *wlc, bool cts_only,
u8 rts_preamble_type,
u8 frame_preamble_type, uint frame_len,
bool ba);
-
-extern void brcms_c_tbtt(struct brcms_c_info *wlc);
extern void brcms_c_inval_dma_pkts(struct brcms_hardware *hw,
struct ieee80211_sta *sta,
void (*dma_callback_fn));
-
-/* Shared memory access */
-extern void brcms_c_copyto_shm(struct brcms_c_info *wlc, uint offset,
- const void *buf, int len);
-
extern void brcms_c_update_beacon(struct brcms_c_info *wlc);
-
extern void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend);
-extern void brcms_c_bss_update_probe_resp(struct brcms_c_info *wlc,
- struct brcms_bss_cfg *cfg,
- bool suspend);
-extern bool brcms_c_ismpc(struct brcms_c_info *wlc);
-extern bool brcms_c_is_non_delay_mpc(struct brcms_c_info *wlc);
-extern void brcms_c_radio_mpc_upd(struct brcms_c_info *wlc);
-extern bool brcms_c_prec_enq_head(struct brcms_c_info *wlc, struct pktq *q,
- struct sk_buff *pkt, int prec, bool head);
-extern u16 brcms_c_phytxctl1_calc(struct brcms_c_info *wlc, u32 rspec);
-extern void brcms_c_compute_plcp(struct brcms_c_info *wlc, u32 rate,
- uint length, u8 *plcp);
-extern uint brcms_c_calc_frame_time(struct brcms_c_info *wlc,
- u32 ratespec,
- u8 preamble_type, uint mac_len);
-
-extern void brcms_c_set_chanspec(struct brcms_c_info *wlc,
- u16 chanspec);
-
-extern bool brcms_c_timers_init(struct brcms_c_info *wlc, int unit);
-
extern int brcms_c_set_nmode(struct brcms_c_info *wlc);
-extern void brcms_c_mimops_action_ht_send(struct brcms_c_info *wlc,
- struct brcms_bss_cfg *bsscfg,
- u8 mimops_mode);
-
-extern void brcms_c_switch_shortslot(struct brcms_c_info *wlc, bool shortslot);
-extern void brcms_c_set_bssid(struct brcms_bss_cfg *cfg);
-extern void brcms_c_edcf_setparams(struct brcms_c_info *wlc, bool suspend);
-
-extern void brcms_c_set_ratetable(struct brcms_c_info *wlc);
-extern int brcms_c_set_mac(struct brcms_bss_cfg *cfg);
extern void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc,
u32 bcn_rate);
-extern void brcms_c_mod_prb_rsp_rate_table(struct brcms_c_info *wlc,
- uint frame_len);
-extern u32 brcms_c_lowest_basic_rspec(struct brcms_c_info *wlc,
- struct brcms_c_rateset *rs);
-extern void brcms_c_radio_disable(struct brcms_c_info *wlc);
-extern void brcms_c_bcn_li_upd(struct brcms_c_info *wlc);
-extern void brcms_c_set_home_chanspec(struct brcms_c_info *wlc,
- u16 chanspec);
-extern bool brcms_c_ps_allowed(struct brcms_c_info *wlc);
-extern bool brcms_c_stay_awake(struct brcms_c_info *wlc);
-
extern void brcms_b_antsel_type_set(struct brcms_hardware *wlc_hw,
u8 antsel_type);
-
-/* chanspec, ucode interface */
extern void brcms_b_set_chanspec(struct brcms_hardware *wlc_hw,
u16 chanspec,
bool mute, struct txpwr_limits *txpwr);
-
extern void brcms_b_write_shm(struct brcms_hardware *wlc_hw, uint offset,
u16 v);
extern u16 brcms_b_read_shm(struct brcms_hardware *wlc_hw, uint offset);
-
extern void brcms_b_mhf(struct brcms_hardware *wlc_hw, u8 idx, u16 mask,
u16 val, int bands);
-
extern void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags);
-
extern void brcms_b_mctrl(struct brcms_hardware *wlc_hw, u32 mask, u32 val);
-
extern void brcms_b_phy_reset(struct brcms_hardware *wlc_hw);
extern void brcms_b_bw_set(struct brcms_hardware *wlc_hw, u16 bw);
extern void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw);
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pub.h b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
index 3942f47..37bb2dc 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
@@ -563,7 +563,7 @@ struct brcms_antselcfg {
};

/* common functions for every port */
-struct brcms_c_info *
+extern struct brcms_c_info *
brcms_c_attach(struct brcms_info *wl, u16 vendor, u16 device, uint unit,
bool piomode, void __iomem *regsva, struct pci_dev *btparam,
uint *perr);
@@ -585,14 +585,9 @@ extern void brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc,
struct sk_buff *sdu,
struct ieee80211_hw *hw);
extern bool brcms_c_aggregatable(struct brcms_c_info *wlc, u8 tid);
-
-/* helper functions */
-extern void brcms_c_statsupd(struct brcms_c_info *wlc);
extern void brcms_c_protection_upd(struct brcms_c_info *wlc, uint idx,
int val);
extern int brcms_c_get_header_len(void);
-extern void brcms_c_mac_bcn_promisc_change(struct brcms_c_info *wlc,
- bool promisc);
extern void brcms_c_set_addrmatch(struct brcms_c_info *wlc,
int match_reg_offset,
const u8 *addr);
@@ -600,26 +595,12 @@ extern void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci,
const struct ieee80211_tx_queue_params *arg,
bool suspend);
extern struct brcms_pub *brcms_c_pub(struct brcms_c_info *wlc);
-
-/* common functions for every port */
-extern void brcms_c_mhf(struct brcms_c_info *wlc, u8 idx, u16 mask, u16 val,
- int bands);
-extern void brcms_c_rate_lookup_init(struct brcms_c_info *wlc,
- struct brcms_c_rateset *rateset);
-extern void brcms_default_rateset(struct brcms_c_info *wlc,
- struct brcms_c_rateset *rs);
-
extern void brcms_c_ampdu_flush(struct brcms_c_info *wlc,
struct ieee80211_sta *sta, u16 tid);
extern void brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid,
u8 ba_wsize, uint max_rx_ampdu_bytes);
extern char *getvar(struct si_pub *sih, enum brcms_srom_id id);
extern int getintvar(struct si_pub *sih, enum brcms_srom_id id);
-
-/* wlc_phy.c helper functions */
-extern void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc);
-extern void brcms_c_mctrl(struct brcms_c_info *wlc, u32 mask, u32 val);
-
extern int brcms_c_module_register(struct brcms_pub *pub,
const char *name, struct brcms_info *hdl,
int (*down_fn)(void *handle));
@@ -633,23 +614,21 @@ extern void brcms_c_scan_stop(struct brcms_c_info *wlc);
extern int brcms_c_get_curband(struct brcms_c_info *wlc);
extern void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc,
bool drop);
-
-int brcms_c_set_channel(struct brcms_c_info *wlc, u16 channel);
-int brcms_c_set_rate_limit(struct brcms_c_info *wlc, u16 srl, u16 lrl);
-void brcms_c_get_current_rateset(struct brcms_c_info *wlc,
+extern int brcms_c_set_channel(struct brcms_c_info *wlc, u16 channel);
+extern int brcms_c_set_rate_limit(struct brcms_c_info *wlc, u16 srl, u16 lrl);
+extern void brcms_c_get_current_rateset(struct brcms_c_info *wlc,
struct brcm_rateset *currs);
-int brcms_c_set_rateset(struct brcms_c_info *wlc, struct brcm_rateset *rs);
-int brcms_c_set_beacon_period(struct brcms_c_info *wlc, u16 period);
-u16 brcms_c_get_phy_type(struct brcms_c_info *wlc, int phyidx);
-void brcms_c_set_shortslot_override(struct brcms_c_info *wlc,
+extern int brcms_c_set_rateset(struct brcms_c_info *wlc,
+ struct brcm_rateset *rs);
+extern int brcms_c_set_beacon_period(struct brcms_c_info *wlc, u16 period);
+extern u16 brcms_c_get_phy_type(struct brcms_c_info *wlc, int phyidx);
+extern void brcms_c_set_shortslot_override(struct brcms_c_info *wlc,
s8 sslot_override);
-void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, u8 interval);
-int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr);
-int brcms_c_get_tx_power(struct brcms_c_info *wlc);
-void brcms_c_set_radio_mpc(struct brcms_c_info *wlc, bool mpc);
-
-/* helper functions */
+extern void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc,
+ u8 interval);
+extern int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr);
+extern int brcms_c_get_tx_power(struct brcms_c_info *wlc);
+extern void brcms_c_set_radio_mpc(struct brcms_c_info *wlc, bool mpc);
extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc);
-extern bool brcms_c_radio_monitor_stop(struct brcms_c_info *wlc);

#endif /* _BRCM_PUB_H_ */
--
1.7.4.1



2011-10-12 18:51:47

by Arend van Spriel

[permalink] [raw]
Subject: [PATCH 09/22] brcm80211: use endian annotations in scan related function

The scan related functions provide scan parameters to the device
which need to be in little-endian. These parameters have been
annotated and conversions were placed as needed.

Reported-by: Johannes Berg <[email protected]>
Reviewed-by: Roland Vossen <[email protected]>
Reviewed-by: Franky (Zhenhui) Lin <[email protected]>
Signed-off-by: Arend van Spriel <[email protected]>
---
.../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index fc643c1..1218ed7 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -475,7 +475,7 @@ static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv)
struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
struct net_device *ndev = cfg_to_ndev(cfg_priv);
struct brcmf_ssid ssid;
- s32 passive_scan;
+ __le32 passive_scan;
s32 err = 0;

/* Broadcast scan by default */
@@ -483,7 +483,7 @@ static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv)

iscan->state = WL_ISCAN_STATE_SCANING;

- passive_scan = cfg_priv->active_scan ? 0 : 1;
+ passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1);
err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_SET_PASSIVE_SCAN,
&passive_scan, sizeof(passive_scan));
if (err) {
@@ -511,7 +511,7 @@ __brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
struct cfg80211_ssid *ssids;
struct brcmf_cfg80211_scan_req *sr = cfg_priv->scan_req_int;
- s32 passive_scan;
+ __le32 passive_scan;
bool iscan_req;
bool spec_scan;
s32 err = 0;
@@ -567,7 +567,7 @@ __brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
WL_SCAN("Broadcast scan\n");
}

- passive_scan = cfg_priv->active_scan ? 0 : 1;
+ passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1);
err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
&passive_scan, sizeof(passive_scan));
if (err) {
--
1.7.4.1



2011-10-12 18:51:51

by Arend van Spriel

[permalink] [raw]
Subject: [PATCH 04/22] brcm80211: remove sparse warning in fullmac debug function

The debug function did a write operation which required a different
pointer type resulting in a sparse warning.

Reviewed-by: Roland Vossen <[email protected]>
Reviewed-by: Alwin Beukers <[email protected]>
Signed-off-by: Arend van Spriel <[email protected]>
---
drivers/net/wireless/brcm80211/brcmfmac/dhd.h | 2 +-
.../net/wireless/brcm80211/brcmfmac/dhd_linux.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
index 3ec7477..f58c0eb 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
@@ -720,7 +720,7 @@ extern int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx,
extern int brcmf_os_proto_block(struct brcmf_pub *drvr);
extern int brcmf_os_proto_unblock(struct brcmf_pub *drvr);
#ifdef BCMDBG
-extern int brcmf_write_to_file(struct brcmf_pub *drvr, u8 *buf, int size);
+extern int brcmf_write_to_file(struct brcmf_pub *drvr, const u8 *buf, int size);
#endif /* BCMDBG */

extern int brcmf_ifname2idx(struct brcmf_info *drvr_priv, char *name);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index 1adc3be..7f5003e 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -1319,7 +1319,7 @@ int brcmf_netdev_wait_pend8021x(struct net_device *ndev)
}

#ifdef BCMDBG
-int brcmf_write_to_file(struct brcmf_pub *drvr, u8 *buf, int size)
+int brcmf_write_to_file(struct brcmf_pub *drvr, const u8 *buf, int size)
{
int ret = 0;
struct file *fp;
@@ -1339,7 +1339,7 @@ int brcmf_write_to_file(struct brcmf_pub *drvr, u8 *buf, int size)
}

/* Write buf to file */
- fp->f_op->write(fp, buf, size, &pos);
+ fp->f_op->write(fp, (char __user *)buf, size, &pos);

exit:
/* free buf before return */
--
1.7.4.1



2011-10-13 08:51:51

by Arend van Spriel

[permalink] [raw]
Subject: Re: [PATCH 22/22] brcm80211: removed file wifi.c

On 10/12/2011 11:54 PM, Luis R. Rodriguez wrote:
> On Wed, Oct 12, 2011 at 11:51 AM, Arend van Spriel <[email protected]> wrote:
>> From: Alwin Beukers <[email protected]>
>>
>> Wifi.c was empty after previous cleanups, so it was removed.
>>
>> Reviewed-by: Arend van Spriel <[email protected]>
>> Signed-off-by: Arend van Spriel <[email protected]>
>
> Heh, remove Reviewed-by dude.
>
> Luis
>

I had a remark on this in earlier commits. So I am clearly missing the
point here. The author submitted this change and others for review to me
and I reviewed it as requested. Hence the Reviewed-by: entry.

I have been given the task to publish these patches and I sign them off
for the "Developer's Certificate of Origin". Hence the Signed-off-by: entry.

Is there something wrong with this reasoning?

Gr. AvS


Attachments:
signature.asc (900.00 B)
OpenPGP digital signature

2011-10-12 19:21:06

by Arend van Spriel

[permalink] [raw]
Subject: Re: [PATCH 22/22] brcm80211: removed file wifi.c

On 10/12/2011 09:13 PM, Johannes Berg wrote:
> On Wed, 2011-10-12 at 20:51 +0200, Arend van Spriel wrote:
>
>> -#include <brcmu_wifi.h>
>
> Does that header file have any content left?
>
> johannes
>
>

It has, but we intend to get rid of brcmutil although the pktq functions
are giving me a headache or it is due to the cold I caught.

Gr. AvS


2011-10-13 18:28:09

by Arend van Spriel

[permalink] [raw]
Subject: Re: [PATCH 22/22] brcm80211: removed file wifi.c

On 10/13/2011 08:08 PM, Luis R. Rodriguez wrote:
> On Thu, Oct 13, 2011 at 1:51 AM, Arend van Spriel <[email protected]> wrote:
>> On 10/12/2011 11:54 PM, Luis R. Rodriguez wrote:
>>> On Wed, Oct 12, 2011 at 11:51 AM, Arend van Spriel <[email protected]> wrote:
>>>> From: Alwin Beukers <[email protected]>
>>>>
>>>> Wifi.c was empty after previous cleanups, so it was removed.
>>>>
>>>> Reviewed-by: Arend van Spriel <[email protected]>
>>>> Signed-off-by: Arend van Spriel <[email protected]>
>>>
>>> Heh, remove Reviewed-by dude.
>>>
>>> Luis
>>>
>>
>> I had a remark on this in earlier commits. So I am clearly missing the
>> point here. The author submitted this change and others for review to me
>> and I reviewed it as requested. Hence the Reviewed-by: entry.
>>
>> I have been given the task to publish these patches and I sign them off
>> for the "Developer's Certificate of Origin". Hence the Signed-off-by: entry.
>>
>> Is there something wrong with this reasoning?
>
> Yeah this all makes no sense. If someone submits you a patch for you
> to review *and* push upstream you simply add *their* SOB first, and
> then after that your own.
>
> Luis
>

Ok, dude

Not trying to be rude, but in my opinion these are two separate things.
Your statement is that Signed-off-by: entry also covers the "Reviewer's
statement of oversight", but I could not find any confirmation to your
statement in the SubmittingPatches documentation.

The only miss I see is that the author did not sign off on this patch.

Gr. AvS


Attachments:
signature.asc (900.00 B)
OpenPGP digital signature

2011-10-12 18:51:51

by Arend van Spriel

[permalink] [raw]
Subject: [PATCH 16/22] brcm80211: moved power conversion functions

From: Alwin Beukers <[email protected]>

Moved brcmu_mw_to_qdbm and brcmu_qdbm_to_mw functions into the only
file using them. Names were adjusted accordingly.

Reported-by: Johannes Berg <[email protected]>
Reviewed-by: Roland Vossen <[email protected]>
Reviewed-by: Arend van Spriel <[email protected]>
Signed-off-by: Arend van Spriel <[email protected]>
---
.../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 88 +++++++++++++++++++-
drivers/net/wireless/brcm80211/brcmutil/utils.c | 86 -------------------
.../net/wireless/brcm80211/include/brcmu_utils.h | 4 -
3 files changed, 86 insertions(+), 92 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 27a748e..db9176d 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -247,6 +247,90 @@ static const u32 __wl_cipher_suites[] = {
WLAN_CIPHER_SUITE_AES_CMAC,
};

+/* Quarter dBm units to mW
+ * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
+ * Table is offset so the last entry is largest mW value that fits in
+ * a u16.
+ */
+
+#define QDBM_OFFSET 153 /* Offset for first entry */
+#define QDBM_TABLE_LEN 40 /* Table size */
+
+/* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
+ * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
+ */
+#define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */
+
+/* Largest mW value that will round down to the last table entry,
+ * QDBM_OFFSET + QDBM_TABLE_LEN-1.
+ * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
+ * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
+ */
+#define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */
+
+static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
+/* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */
+/* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
+/* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
+/* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
+/* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
+/* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
+};
+
+static u16 brcmf_qdbm_to_mw(u8 qdbm)
+{
+ uint factor = 1;
+ int idx = qdbm - QDBM_OFFSET;
+
+ if (idx >= QDBM_TABLE_LEN)
+ /* clamp to max u16 mW value */
+ return 0xFFFF;
+
+ /* scale the qdBm index up to the range of the table 0-40
+ * where an offset of 40 qdBm equals a factor of 10 mW.
+ */
+ while (idx < 0) {
+ idx += 40;
+ factor *= 10;
+ }
+
+ /* return the mW value scaled down to the correct factor of 10,
+ * adding in factor/2 to get proper rounding.
+ */
+ return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
+}
+
+static u8 brcmf_mw_to_qdbm(u16 mw)
+{
+ u8 qdbm;
+ int offset;
+ uint mw_uint = mw;
+ uint boundary;
+
+ /* handle boundary case */
+ if (mw_uint <= 1)
+ return 0;
+
+ offset = QDBM_OFFSET;
+
+ /* move mw into the range of the table */
+ while (mw_uint < QDBM_TABLE_LOW_BOUND) {
+ mw_uint *= 10;
+ offset -= 40;
+ }
+
+ for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) {
+ boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
+ nqdBm_to_mW_map[qdbm]) / 2;
+ if (mw_uint < boundary)
+ break;
+ }
+
+ qdbm += (u8) offset;
+
+ return qdbm;
+}
+
/* function for reading/writing a single u32 from/to the dongle */
static int
brcmf_exec_dcmd_u32(struct net_device *ndev, u32 cmd, u32 *par)
@@ -1380,7 +1464,7 @@ brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
else
txpwrmw = (u16) dbm;
err = brcmf_dev_intvar_set(ndev, "qtxpower",
- (s32) (brcmu_mw_to_qdbm(txpwrmw)));
+ (s32) (brcmf_mw_to_qdbm(txpwrmw)));
if (err)
WL_ERR("qtxpower error (%d)\n", err);
cfg_priv->conf->tx_power = dbm;
@@ -1409,7 +1493,7 @@ static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
}

result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
- *dbm = (s32) brcmu_qdbm_to_mw(result);
+ *dbm = (s32) brcmf_qdbm_to_mw(result);

done:
WL_TRACE("Exit\n");
diff --git a/drivers/net/wireless/brcm80211/brcmutil/utils.c b/drivers/net/wireless/brcm80211/brcmutil/utils.c
index 990cb2e..7f53a70 100644
--- a/drivers/net/wireless/brcm80211/brcmutil/utils.c
+++ b/drivers/net/wireless/brcm80211/brcmutil/utils.c
@@ -499,89 +499,3 @@ uint brcmu_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen)
}
EXPORT_SYMBOL(brcmu_mkiovar);

-/* Quarter dBm units to mW
- * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
- * Table is offset so the last entry is largest mW value that fits in
- * a u16.
- */
-
-#define QDBM_OFFSET 153 /* Offset for first entry */
-#define QDBM_TABLE_LEN 40 /* Table size */
-
-/* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
- * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
- */
-#define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */
-
-/* Largest mW value that will round down to the last table entry,
- * QDBM_OFFSET + QDBM_TABLE_LEN-1.
- * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
- * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
- */
-#define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */
-
-static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
-/* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */
-/* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
-/* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
-/* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
-/* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
-/* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
-};
-
-u16 brcmu_qdbm_to_mw(u8 qdbm)
-{
- uint factor = 1;
- int idx = qdbm - QDBM_OFFSET;
-
- if (idx >= QDBM_TABLE_LEN)
- /* clamp to max u16 mW value */
- return 0xFFFF;
-
- /* scale the qdBm index up to the range of the table 0-40
- * where an offset of 40 qdBm equals a factor of 10 mW.
- */
- while (idx < 0) {
- idx += 40;
- factor *= 10;
- }
-
- /* return the mW value scaled down to the correct factor of 10,
- * adding in factor/2 to get proper rounding.
- */
- return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
-}
-EXPORT_SYMBOL(brcmu_qdbm_to_mw);
-
-u8 brcmu_mw_to_qdbm(u16 mw)
-{
- u8 qdbm;
- int offset;
- uint mw_uint = mw;
- uint boundary;
-
- /* handle boundary case */
- if (mw_uint <= 1)
- return 0;
-
- offset = QDBM_OFFSET;
-
- /* move mw into the range of the table */
- while (mw_uint < QDBM_TABLE_LOW_BOUND) {
- mw_uint *= 10;
- offset -= 40;
- }
-
- for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) {
- boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
- nqdBm_to_mW_map[qdbm]) / 2;
- if (mw_uint < boundary)
- break;
- }
-
- qdbm += (u8) offset;
-
- return qdbm;
-}
-EXPORT_SYMBOL(brcmu_mw_to_qdbm);
-
diff --git a/drivers/net/wireless/brcm80211/include/brcmu_utils.h b/drivers/net/wireless/brcm80211/include/brcmu_utils.h
index 96f05d7..d716cd2 100644
--- a/drivers/net/wireless/brcm80211/include/brcmu_utils.h
+++ b/drivers/net/wireless/brcm80211/include/brcmu_utils.h
@@ -212,10 +212,6 @@ extern char *brcmu_chipname(uint chipid, char *buf, uint len);
extern struct brcmu_tlv *brcmu_parse_tlvs(void *buf, int buflen,
uint key);

-/* power conversion */
-extern u16 brcmu_qdbm_to_mw(u8 qdbm);
-extern u8 brcmu_mw_to_qdbm(u16 mw);
-
extern uint brcmu_mkiovar(char *name, char *data, uint datalen,
char *buf, uint len);

--
1.7.4.1



2011-10-12 18:51:47

by Arend van Spriel

[permalink] [raw]
Subject: [PATCH 22/22] brcm80211: removed file wifi.c

From: Alwin Beukers <[email protected]>

Wifi.c was empty after previous cleanups, so it was removed.

Reviewed-by: Arend van Spriel <[email protected]>
Signed-off-by: Arend van Spriel <[email protected]>
---
drivers/net/wireless/brcm80211/brcmutil/Makefile | 3 +--
drivers/net/wireless/brcm80211/brcmutil/wifi.c | 16 ----------------
2 files changed, 1 insertions(+), 18 deletions(-)
delete mode 100644 drivers/net/wireless/brcm80211/brcmutil/wifi.c

diff --git a/drivers/net/wireless/brcm80211/brcmutil/Makefile b/drivers/net/wireless/brcm80211/brcmutil/Makefile
index 720e261..6281c41 100644
--- a/drivers/net/wireless/brcm80211/brcmutil/Makefile
+++ b/drivers/net/wireless/brcm80211/brcmutil/Makefile
@@ -20,8 +20,7 @@ ccflags-y := \
-Idrivers/net/wireless/brcm80211/include

BRCMUTIL_OFILES := \
- utils.o \
- wifi.o
+ utils.o

MODULEPFX := brcmutil

diff --git a/drivers/net/wireless/brcm80211/brcmutil/wifi.c b/drivers/net/wireless/brcm80211/brcmutil/wifi.c
deleted file mode 100644
index 8483f24..0000000
--- a/drivers/net/wireless/brcm80211/brcmutil/wifi.c
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * Copyright (c) 2010 Broadcom Corporation
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#include <brcmu_wifi.h>
--
1.7.4.1



2011-10-12 18:51:51

by Arend van Spriel

[permalink] [raw]
Subject: [PATCH 01/22] brcm80211: smac: removed redundant timer function parameters

From: Roland Vossen <[email protected]>

Parameter 'wl' is already stored in struct brcms_timer, so the number of
function parameters could be decreased.

Reviewed-by: Alwin Beukers <[email protected]>
Reviewed-by: Arend van Spriel <[email protected]>
Signed-off-by: Arend van Spriel <[email protected]>
---
.../net/wireless/brcm80211/brcmsmac/mac80211_if.c | 15 ++++++++-------
.../net/wireless/brcm80211/brcmsmac/mac80211_if.h | 7 +++----
drivers/net/wireless/brcm80211/brcmsmac/main.c | 13 ++++++-------
.../net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c | 12 ++++++------
drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c | 13 ++++++-------
drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h | 9 +++------
6 files changed, 32 insertions(+), 37 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
index 4dcf9ef..b665aaf 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -1478,12 +1478,12 @@ struct brcms_timer *brcms_init_timer(struct brcms_info *wl,
*
* precondition: perimeter lock has been acquired
*/
-void brcms_add_timer(struct brcms_info *wl, struct brcms_timer *t, uint ms,
+void brcms_add_timer(struct brcms_timer *t, uint ms,
int periodic)
{
#ifdef BCMDBG
if (t->set)
- wiphy_err(wl->wiphy, "%s: Already set. Name: %s, per %d\n",
+ wiphy_err(t->wl->wiphy, "%s: Already set. Name: %s, per %d\n",
__func__, t->name, periodic);

#endif
@@ -1492,7 +1492,7 @@ void brcms_add_timer(struct brcms_info *wl, struct brcms_timer *t, uint ms,
t->set = true;
t->timer.expires = jiffies + ms * HZ / 1000;

- atomic_inc(&wl->callbacks);
+ atomic_inc(&t->wl->callbacks);
add_timer(&t->timer);
}

@@ -1501,14 +1501,14 @@ void brcms_add_timer(struct brcms_info *wl, struct brcms_timer *t, uint ms,
*
* precondition: perimeter lock has been acquired
*/
-bool brcms_del_timer(struct brcms_info *wl, struct brcms_timer *t)
+bool brcms_del_timer(struct brcms_timer *t)
{
if (t->set) {
t->set = false;
if (!del_timer(&t->timer))
return false;

- atomic_dec(&wl->callbacks);
+ atomic_dec(&t->wl->callbacks);
}

return true;
@@ -1517,12 +1517,13 @@ bool brcms_del_timer(struct brcms_info *wl, struct brcms_timer *t)
/*
* precondition: perimeter lock has been acquired
*/
-void brcms_free_timer(struct brcms_info *wl, struct brcms_timer *t)
+void brcms_free_timer(struct brcms_timer *t)
{
+ struct brcms_info *wl = t->wl;
struct brcms_timer *tmp;

/* delete the timer in case it is active */
- brcms_del_timer(wl, t);
+ brcms_del_timer(t);

if (wl->timers == t) {
wl->timers = wl->timers->next;
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
index 92256d0..91e5f2a 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
@@ -96,10 +96,9 @@ extern bool brcms_rfkill_set_hw_state(struct brcms_info *wl);
extern struct brcms_timer *brcms_init_timer(struct brcms_info *wl,
void (*fn) (void *arg), void *arg,
const char *name);
-extern void brcms_free_timer(struct brcms_info *wl, struct brcms_timer *timer);
-extern void brcms_add_timer(struct brcms_info *wl, struct brcms_timer *timer,
- uint ms, int periodic);
-extern bool brcms_del_timer(struct brcms_info *wl, struct brcms_timer *timer);
+extern void brcms_free_timer(struct brcms_timer *timer);
+extern void brcms_add_timer(struct brcms_timer *timer, uint ms, int periodic);
+extern bool brcms_del_timer(struct brcms_timer *timer);
extern void brcms_msleep(struct brcms_info *wl, uint ms);
extern void brcms_dpc(unsigned long data);
extern void brcms_timer(struct brcms_timer *t);
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index 5fb999b..665bf80 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -4236,8 +4236,7 @@ static void brcms_c_radio_monitor_start(struct brcms_c_info *wlc)

wlc->radio_monitor = true;
brcms_b_pllreq(wlc->hw, true, BRCMS_PLLREQ_RADIO_MON);
- brcms_add_timer(wlc->wl, wlc->radio_timer, TIMER_INTERVAL_RADIOCHK,
- true);
+ brcms_add_timer(wlc->radio_timer, TIMER_INTERVAL_RADIOCHK, true);
}

void brcms_c_radio_disable(struct brcms_c_info *wlc)
@@ -4269,7 +4268,7 @@ bool brcms_c_radio_monitor_stop(struct brcms_c_info *wlc)

wlc->radio_monitor = false;
brcms_b_pllreq(wlc->hw, false, BRCMS_PLLREQ_RADIO_MON);
- return brcms_del_timer(wlc->wl, wlc->radio_timer);
+ return brcms_del_timer(wlc->radio_timer);
}

/* read hwdisable state and propagate to wlc flag */
@@ -5221,11 +5220,11 @@ static void brcms_c_timers_deinit(struct brcms_c_info *wlc)
{
/* free timer state */
if (wlc->wdtimer) {
- brcms_free_timer(wlc->wl, wlc->wdtimer);
+ brcms_free_timer(wlc->wdtimer);
wlc->wdtimer = NULL;
}
if (wlc->radio_timer) {
- brcms_free_timer(wlc->wl, wlc->radio_timer);
+ brcms_free_timer(wlc->radio_timer);
wlc->radio_timer = NULL;
}
}
@@ -5607,7 +5606,7 @@ int brcms_c_up(struct brcms_c_info *wlc)
brcms_c_wme_retries_write(wlc);

/* start one second watchdog timer */
- brcms_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, true);
+ brcms_add_timer(wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, true);
wlc->WDarmed = true;

/* ensure antenna config is up to date */
@@ -5736,7 +5735,7 @@ uint brcms_c_down(struct brcms_c_info *wlc)

/* cancel the watchdog timer */
if (wlc->WDarmed) {
- if (!brcms_del_timer(wlc->wl, wlc->wdtimer))
+ if (!brcms_del_timer(wlc->wdtimer))
callbacks++;
wlc->WDarmed = false;
}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c
index d54cfdb..a314925 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c
@@ -442,7 +442,7 @@ static void wlc_phy_timercb_phycal(struct brcms_phy *pi)
wlc_phy_cal_perical_mphase_restart(pi);
} else
wlc_phy_cal_perical_nphy_run(pi, PHY_PERICAL_AUTO);
- wlapi_add_timer(pi->sh->physhim, pi->phycal_timer, delay, 0);
+ wlapi_add_timer(pi->phycal_timer, delay, 0);
return;
}

@@ -625,7 +625,7 @@ void wlc_phy_detach(struct brcms_phy_pub *pih)
return;

if (pi->phycal_timer) {
- wlapi_free_timer(pi->sh->physhim, pi->phycal_timer);
+ wlapi_free_timer(pi->phycal_timer);
pi->phycal_timer = NULL;
}

@@ -852,7 +852,7 @@ int wlc_phy_down(struct brcms_phy_pub *pih)
int callbacks = 0;

if (pi->phycal_timer
- && !wlapi_del_timer(pi->sh->physhim, pi->phycal_timer))
+ && !wlapi_del_timer(pi->phycal_timer))
callbacks++;

pi->nphy_iqcal_chanspec_2G = 0;
@@ -2715,7 +2715,7 @@ wlc_phy_papd_decode_epsilon(u32 epsilon, s32 *eps_real, s32 *eps_imag)

void wlc_phy_cal_perical_mphase_reset(struct brcms_phy *pi)
{
- wlapi_del_timer(pi->sh->physhim, pi->phycal_timer);
+ wlapi_del_timer(pi->phycal_timer);

pi->cal_type_override = PHY_PERICAL_AUTO;
pi->mphase_cal_phase_id = MPHASE_CAL_STATE_IDLE;
@@ -2730,10 +2730,10 @@ wlc_phy_cal_perical_mphase_schedule(struct brcms_phy *pi, uint delay)
(pi->nphy_perical != PHY_PERICAL_MANUAL))
return;

- wlapi_del_timer(pi->sh->physhim, pi->phycal_timer);
+ wlapi_del_timer(pi->phycal_timer);

pi->mphase_cal_phase_id = MPHASE_CAL_STATE_INIT;
- wlapi_add_timer(pi->sh->physhim, pi->phycal_timer, delay, 0);
+ wlapi_add_timer(pi->phycal_timer, delay, 0);
}

void wlc_phy_cal_perical(struct brcms_phy_pub *pih, u8 reason)
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c b/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c
index 676222e..5926854 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c
@@ -65,21 +65,20 @@ struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim,
arg, name);
}

-void wlapi_free_timer(struct phy_shim_info *physhim, struct wlapi_timer *t)
+void wlapi_free_timer(struct wlapi_timer *t)
{
- brcms_free_timer(physhim->wl, (struct brcms_timer *)t);
+ brcms_free_timer((struct brcms_timer *)t);
}

void
-wlapi_add_timer(struct phy_shim_info *physhim, struct wlapi_timer *t, uint ms,
- int periodic)
+wlapi_add_timer(struct wlapi_timer *t, uint ms, int periodic)
{
- brcms_add_timer(physhim->wl, (struct brcms_timer *)t, ms, periodic);
+ brcms_add_timer((struct brcms_timer *)t, ms, periodic);
}

-bool wlapi_del_timer(struct phy_shim_info *physhim, struct wlapi_timer *t)
+bool wlapi_del_timer(struct wlapi_timer *t)
{
- return brcms_del_timer(physhim->wl, (struct brcms_timer *)t);
+ return brcms_del_timer((struct brcms_timer *)t);
}

void wlapi_intrson(struct phy_shim_info *physhim)
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h b/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h
index 8de549d..9168c45 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h
@@ -133,12 +133,9 @@ extern void wlc_phy_shim_detach(struct phy_shim_info *physhim);
extern struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim,
void (*fn) (struct brcms_phy *pi),
void *arg, const char *name);
-extern void wlapi_free_timer(struct phy_shim_info *physhim,
- struct wlapi_timer *t);
-extern void wlapi_add_timer(struct phy_shim_info *physhim,
- struct wlapi_timer *t, uint ms, int periodic);
-extern bool wlapi_del_timer(struct phy_shim_info *physhim,
- struct wlapi_timer *t);
+extern void wlapi_free_timer(struct wlapi_timer *t);
+extern void wlapi_add_timer(struct wlapi_timer *t, uint ms, int periodic);
+extern bool wlapi_del_timer(struct wlapi_timer *t);
extern void wlapi_intrson(struct phy_shim_info *physhim);
extern u32 wlapi_intrsoff(struct phy_shim_info *physhim);
extern void wlapi_intrsrestore(struct phy_shim_info *physhim,
--
1.7.4.1



2011-10-12 18:51:47

by Arend van Spriel

[permalink] [raw]
Subject: [PATCH 13/22] brcm80211: use endian annotation for scan time configuration

For scanning several timeout parameters are configured on the device.
These parameters have been endian annotated and converted appropriately.

Reported-by: Johannes Berg <[email protected]>
Reviewed-by: Roland Vossen <[email protected]>
Reviewed-by: Franky (Zhenhui) Lin <[email protected]>
Signed-off-by: Arend van Spriel <[email protected]>
---
.../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 11 +++++++----
1 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 8fc8173..1b09be0 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -3497,12 +3497,15 @@ dongle_rom_out:

static s32
brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
- s32 scan_unassoc_time, s32 scan_passive_time)
+ s32 scan_unassoc_time, s32 scan_passive_time)
{
s32 err = 0;
+ __le32 scan_assoc_tm_le = cpu_to_le32(scan_assoc_time);
+ __le32 scan_unassoc_tm_le = cpu_to_le32(scan_unassoc_time);
+ __le32 scan_passive_tm_le = cpu_to_le32(scan_passive_time);

err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_CHANNEL_TIME,
- &scan_assoc_time, sizeof(scan_assoc_time));
+ &scan_assoc_tm_le, sizeof(scan_assoc_tm_le));
if (err) {
if (err == -EOPNOTSUPP)
WL_INFO("Scan assoc time is not supported\n");
@@ -3511,7 +3514,7 @@ brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
goto dongle_scantime_out;
}
err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_UNASSOC_TIME,
- &scan_unassoc_time, sizeof(scan_unassoc_time));
+ &scan_unassoc_tm_le, sizeof(scan_unassoc_tm_le));
if (err) {
if (err == -EOPNOTSUPP)
WL_INFO("Scan unassoc time is not supported\n");
@@ -3521,7 +3524,7 @@ brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
}

err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_PASSIVE_TIME,
- &scan_passive_time, sizeof(scan_passive_time));
+ &scan_passive_tm_le, sizeof(scan_passive_tm_le));
if (err) {
if (err == -EOPNOTSUPP)
WL_INFO("Scan passive time is not supported\n");
--
1.7.4.1



2011-10-12 18:51:51

by Arend van Spriel

[permalink] [raw]
Subject: [PATCH 12/22] brcm80211: use endian annotation for roaming related parameters

The parameters for roaming are sent to the device and should be little
endian. These have been annotated and converted appropriately.

Reported-by: Johannes Berg <[email protected]>
Reviewed-by: Roland Vossen <[email protected]>
Reviewed-by: Franky (Zhenhui) Lin <[email protected]>
Signed-off-by: Arend van Spriel <[email protected]>
---
.../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 24 +++++++++++--------
1 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 8e20753..8fc8173 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -3437,17 +3437,20 @@ static s32
brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
{
s8 iovbuf[32];
- s32 roamtrigger[2];
- s32 roam_delta[2];
s32 err = 0;
+ __le32 roamtrigger[2];
+ __le32 roam_delta[2];
+ __le32 bcn_to_le;
+ __le32 roamvar_le;

/*
* Setup timeout if Beacons are lost and roam is
* off to report link down
*/
if (roamvar) {
- brcmu_mkiovar("bcn_timeout", (char *)&bcn_timeout,
- sizeof(bcn_timeout), iovbuf, sizeof(iovbuf));
+ bcn_to_le = cpu_to_le32(bcn_timeout);
+ brcmu_mkiovar("bcn_timeout", (char *)&bcn_to_le,
+ sizeof(bcn_to_le), iovbuf, sizeof(iovbuf));
err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR,
iovbuf, sizeof(iovbuf));
if (err) {
@@ -3461,16 +3464,17 @@ brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
* to take care of roaming
*/
WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
- brcmu_mkiovar("roam_off", (char *)&roamvar,
- sizeof(roamvar), iovbuf, sizeof(iovbuf));
+ roamvar_le = cpu_to_le32(roamvar);
+ brcmu_mkiovar("roam_off", (char *)&roamvar_le,
+ sizeof(roamvar_le), iovbuf, sizeof(iovbuf));
err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
if (err) {
WL_ERR("roam_off error (%d)\n", err);
goto dongle_rom_out;
}

- roamtrigger[0] = WL_ROAM_TRIGGER_LEVEL;
- roamtrigger[1] = BRCM_BAND_ALL;
+ roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
+ roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_TRIGGER,
(void *)roamtrigger, sizeof(roamtrigger));
if (err) {
@@ -3478,8 +3482,8 @@ brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
goto dongle_rom_out;
}

- roam_delta[0] = WL_ROAM_DELTA;
- roam_delta[1] = BRCM_BAND_ALL;
+ roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
+ roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_DELTA,
(void *)roam_delta, sizeof(roam_delta));
if (err) {
--
1.7.4.1



2011-10-12 18:51:51

by Arend van Spriel

[permalink] [raw]
Subject: [PATCH 11/22] brcm80211: use endian annotations for assoc ie length request

The driver requests the device for number of ie's in assoc request
and response. This needed to be endian annotated.

Reported-by: Johannes Berg <[email protected]>
Reviewed-by: Roland Vossen <[email protected]>
Reviewed-by: Franky (Zhenhui) Lin <[email protected]>
Signed-off-by: Arend van Spriel <[email protected]>
---
.../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 9 +++++----
.../net/wireless/brcm80211/brcmfmac/wl_cfg80211.h | 6 +++---
2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 9e69cd7..8e20753 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -2767,7 +2767,7 @@ static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
{
struct net_device *ndev = cfg_to_ndev(cfg_priv);
- struct brcmf_cfg80211_assoc_ielen *assoc_info;
+ struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
u32 req_len;
u32 resp_len;
@@ -2781,9 +2781,10 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
WL_ERR("could not get assoc info (%d)\n", err);
return err;
}
- assoc_info = (struct brcmf_cfg80211_assoc_ielen *)cfg_priv->extra_buf;
- req_len = assoc_info->req_len;
- resp_len = assoc_info->resp_len;
+ assoc_info =
+ (struct brcmf_cfg80211_assoc_ielen_le *)cfg_priv->extra_buf;
+ req_len = le32_to_cpu(assoc_info->req_len);
+ resp_len = le32_to_cpu(assoc_info->resp_len);
if (req_len) {
err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies",
cfg_priv->extra_buf,
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
index e69f4f6..62dc461 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
@@ -264,9 +264,9 @@ struct brcmf_cfg80211_connect_info {
};

/* assoc ie length */
-struct brcmf_cfg80211_assoc_ielen {
- u32 req_len;
- u32 resp_len;
+struct brcmf_cfg80211_assoc_ielen_le {
+ __le32 req_len;
+ __le32 resp_len;
};

/* wpa2 pmk list */
--
1.7.4.1