* [PATCH] ath9k: Fix DEBUG_FS dependency for ath9k
From: Sujith Manoharan @ 2013-08-26 7:53 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
Reported-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath9k/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index c91bc61..7944c25 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -56,7 +56,7 @@ config ATH9K_AHB
config ATH9K_DEBUGFS
bool "Atheros ath9k debugging"
- depends on ATH9K
+ depends on ATH9K && DEBUG_FS
select MAC80211_DEBUGFS
select RELAY
---help---
--
1.8.3.4
^ permalink raw reply related
* Re: [PATCH] mac80211_hwsim: fix error return code in init_mac80211_hwsim()
From: Johannes Berg @ 2013-08-26 7:37 UTC (permalink / raw)
To: Wei Yongjun; +Cc: linville, yongjun_wei, linux-wireless
In-Reply-To: <CAPgLHd-GQuhYuKXBj6FVjtpGYWZYVwuGR-Sj3w19JSMcTm1JLg@mail.gmail.com>
On Mon, 2013-08-26 at 15:32 +0800, Wei Yongjun wrote:
> From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
>
> Fix to return -ENOMEM in the netdev alloc error handling
> case instead of 0, as done elsewhere in this function.
Makes sense, applied.
johannes
^ permalink raw reply
* [PATCH] mac80211: fix change_interface queue assignments
From: Johannes Berg @ 2013-08-26 7:35 UTC (permalink / raw)
To: linux-wireless; +Cc: Jouni Malinen, Johannes Berg
From: Johannes Berg <johannes.berg@intel.com>
Jouni reported that with mac80211_hwsim, multicast TX was causing
crashes due to invalid vif->cab_queue assignment. It turns out that
this is caused by change_interface() getting invoked and not having
the vif->type/vif->p2p assigned correctly before calling the queue
check (ieee80211_check_queues). Fix this by passing the 'external'
interface type to the function and adjusting it accordingly.
While at it, also fix the error path in change_interface, it wasn't
correctly resetting to the external type but using the internal one
instead.
Fortunately this affects on hwsim because all other drivers set the
vif->type/vif->p2p variables when changing iftype. This shouldn't
be needed, but almost all implementations actually do it for their
own internal handling.
Reported-by: Jouni Malinen <j@w1.fi>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
net/mac80211/iface.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 7ca534b..fcecd63 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -308,12 +308,13 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata,
return 0;
}
-static int ieee80211_check_queues(struct ieee80211_sub_if_data *sdata)
+static int ieee80211_check_queues(struct ieee80211_sub_if_data *sdata,
+ enum nl80211_iftype iftype)
{
int n_queues = sdata->local->hw.queues;
int i;
- if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE) {
+ if (iftype != NL80211_IFTYPE_P2P_DEVICE) {
for (i = 0; i < IEEE80211_NUM_ACS; i++) {
if (WARN_ON_ONCE(sdata->vif.hw_queue[i] ==
IEEE80211_INVAL_HW_QUEUE))
@@ -324,8 +325,9 @@ static int ieee80211_check_queues(struct ieee80211_sub_if_data *sdata)
}
}
- if ((sdata->vif.type != NL80211_IFTYPE_AP &&
- sdata->vif.type != NL80211_IFTYPE_MESH_POINT) ||
+ if ((iftype != NL80211_IFTYPE_AP &&
+ iftype != NL80211_IFTYPE_P2P_GO &&
+ iftype != NL80211_IFTYPE_MESH_POINT) ||
!(sdata->local->hw.flags & IEEE80211_HW_QUEUE_CONTROL)) {
sdata->vif.cab_queue = IEEE80211_INVAL_HW_QUEUE;
return 0;
@@ -408,7 +410,7 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
return ret;
}
- ret = ieee80211_check_queues(sdata);
+ ret = ieee80211_check_queues(sdata, NL80211_IFTYPE_MONITOR);
if (ret) {
kfree(sdata);
return ret;
@@ -592,7 +594,8 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
res = drv_add_interface(local, sdata);
if (res)
goto err_stop;
- res = ieee80211_check_queues(sdata);
+ res = ieee80211_check_queues(sdata,
+ ieee80211_vif_type_p2p(&sdata->vif));
if (res)
goto err_del_interface;
}
@@ -1389,14 +1392,14 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata,
ret = drv_change_interface(local, sdata, internal_type, p2p);
if (ret)
- type = sdata->vif.type;
+ type = ieee80211_vif_type_p2p(&sdata->vif);
/*
* Ignore return value here, there's not much we can do since
* the driver changed the interface type internally already.
* The warnings will hopefully make driver authors fix it :-)
*/
- ieee80211_check_queues(sdata);
+ ieee80211_check_queues(sdata, type);
ieee80211_setup_sdata(sdata, type);
--
1.8.4.rc3
^ permalink raw reply related
* [PATCH] mac80211_hwsim: fix error return code in init_mac80211_hwsim()
From: Wei Yongjun @ 2013-08-26 7:32 UTC (permalink / raw)
To: linville; +Cc: yongjun_wei, linux-wireless
From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
Fix to return -ENOMEM in the netdev alloc error handling
case instead of 0, as done elsewhere in this function.
Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
---
drivers/net/wireless/mac80211_hwsim.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index cb34c78..9e0ebee 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -2525,8 +2525,10 @@ static int __init init_mac80211_hwsim(void)
}
hwsim_mon = alloc_netdev(0, "hwsim%d", hwsim_mon_setup);
- if (hwsim_mon == NULL)
+ if (hwsim_mon == NULL) {
+ err = -ENOMEM;
goto failed;
+ }
rtnl_lock();
^ permalink raw reply related
* [PATCH] zd1201: fix error return code
From: Wei Yongjun @ 2013-08-26 7:32 UTC (permalink / raw)
To: linville; +Cc: yongjun_wei, linux-wireless
From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
Fix to return -ENOMEM in the memory alloc error handling
case instead of 0, as done elsewhere in this function.
Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
---
drivers/net/wireless/zd1201.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c
index 4941f20..73aa738 100644
--- a/drivers/net/wireless/zd1201.c
+++ b/drivers/net/wireless/zd1201.c
@@ -75,8 +75,10 @@ static int zd1201_fw_upload(struct usb_device *dev, int apfw)
len = fw_entry->size;
buf = kmalloc(1024, GFP_ATOMIC);
- if (!buf)
+ if (!buf) {
+ err = -ENOMEM;
goto exit;
+ }
while (len > 0) {
int translen = (len > 1024) ? 1024 : len;
@@ -1762,8 +1764,10 @@ static int zd1201_probe(struct usb_interface *interface,
zd->endp_out2 = 2;
zd->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
zd->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!zd->rx_urb || !zd->tx_urb)
+ if (!zd->rx_urb || !zd->tx_urb) {
+ err = -ENOMEM;
goto err_zd;
+ }
mdelay(100);
err = zd1201_drvr_start(zd);
^ permalink raw reply related
* Re: [PATCH v2 13/16] wcn36xx: add wcn36xx.h
From: Eugene Krasnikov @ 2013-08-26 7:23 UTC (permalink / raw)
To: Joe Perches; +Cc: linux-wireless, wcn36xx
In-Reply-To: <1377298929.2816.15.camel@joe-AO722>
Since wcn36xx soon will become a part of ath family and all ath
drivers are using printk i thought it's reasonable to use common
approach everywhere:) May be in future all ath debug functions will be
united into one debug framework and the same code will be used
everywhere.
2013/8/24 Joe Perches <joe@perches.com>:
> On Fri, 2013-08-23 at 10:58 +0200, Eugene Krasnikov wrote:
>> Adding wcn36xx.h
> []
>> +#define wcn36xx_err(fmt, arg...) \
>> + printk(KERN_ERR pr_fmt("ERROR " fmt), ##arg);
>> +
>> +#define wcn36xx_warn(fmt, arg...) \
>> + printk(KERN_WARNING pr_fmt("WARNING " fmt), ##arg)
>> +
>> +#define wcn36xx_info(fmt, arg...) \
>> + printk(KERN_INFO pr_fmt(fmt), ##arg)
>> +
>
> I these would be better using:
>
> #define wcn36xx_err(fmt, ...) \
> pr_err("ERROR " fmt, ##__VA_ARGS__)
>
> etc...
>
>> +#define wcn36xx_dbg(mask, fmt, arg...) do { \
>> + if (debug_mask & mask) \
>> + printk(KERN_DEBUG pr_fmt(fmt), ##arg); \
>> +} while (0)
>
> And maybe this one using pr_debug so dynamic_debug
> can work too.
>
>
--
Best regards,
Eugene
^ permalink raw reply
* [PATCH] mwifiex: add missing endian conversions
From: Tobias Waldekranz @ 2013-08-26 7:18 UTC (permalink / raw)
To: linux-wireless
Fixes multiple locations where a little endian host is assumed during
ser/des of messages sent to/received from the chip.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
---
drivers/net/wireless/mwifiex/11n_aggr.c | 2 +-
drivers/net/wireless/mwifiex/main.h | 2 +-
drivers/net/wireless/mwifiex/sdio.c | 6 +++---
drivers/net/wireless/mwifiex/sta_cmdresp.c | 2 +-
4 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c
index a78e065..b53c73c 100644
--- a/drivers/net/wireless/mwifiex/11n_aggr.c
+++ b/drivers/net/wireless/mwifiex/11n_aggr.c
@@ -69,7 +69,7 @@ mwifiex_11n_form_amsdu_pkt(struct sk_buff *skb_aggr,
memcpy(&tx_header->eth803_hdr, skb_src->data, dt_offset);
/* Copy SNAP header */
- snap.snap_type = *(u16 *) ((u8 *)skb_src->data + dt_offset);
+ snap.snap_type = le16_to_cpu(*(__le16 *) ((u8 *)skb_src->data + dt_offset));
dt_offset += sizeof(u16);
memcpy(&tx_header->rfc1042_hdr, &snap, sizeof(struct rfc_1042_hdr));
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 4ef67fc..7797512 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -1014,7 +1014,7 @@ mwifiex_netdev_get_priv(struct net_device *dev)
*/
static inline bool mwifiex_is_skb_mgmt_frame(struct sk_buff *skb)
{
- return (*(u32 *)skb->data == PKT_TYPE_MGMT);
+ return (le32_to_cpu(*(__le32 *)skb->data) == PKT_TYPE_MGMT);
}
int mwifiex_init_shutdown_fw(struct mwifiex_private *priv,
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index 139c958..27fdbe2 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -963,7 +963,7 @@ static int mwifiex_decode_rx_packet(struct mwifiex_adapter *adapter,
case MWIFIEX_TYPE_EVENT:
dev_dbg(adapter->dev, "info: --- Rx: Event ---\n");
- adapter->event_cause = *(u32 *) skb->data;
+ adapter->event_cause = le32_to_cpu(*(__le32 *) skb->data);
if ((skb->len > 0) && (skb->len < MAX_EVENT_SIZE))
memcpy(adapter->event_body,
@@ -1088,8 +1088,8 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
for (pind = 0; pind < card->mpa_rx.pkt_cnt; pind++) {
/* get curr PKT len & type */
- pkt_len = *(u16 *) &curr_ptr[0];
- pkt_type = *(u16 *) &curr_ptr[2];
+ pkt_len = le16_to_cpu(*(__le16 *) &curr_ptr[0]);
+ pkt_type = le16_to_cpu(*(__le16 *) &curr_ptr[2]);
/* copy pkt to deaggr buf */
skb_deaggr = card->mpa_rx.skb_arr[pind];
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index 9f990e1..f12468a8 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -280,7 +280,7 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv,
tlv_buf = ((u8 *)rate_cfg) +
sizeof(struct host_cmd_ds_tx_rate_cfg);
- tlv_buf_len = *(u16 *) (tlv_buf + sizeof(u16));
+ tlv_buf_len = le16_to_cpu(*(__le16 *) (tlv_buf + sizeof(u16)));
while (tlv_buf && tlv_buf_len > 0) {
tlv = (*tlv_buf);
--
1.8.3
^ permalink raw reply related
* [PATCH] ath9k: Fix TX poll work locking
From: Sujith Manoharan @ 2013-08-26 6:17 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
There is no need to call ath_txq_unlock_complete() in the
TX poll routine - frame completion is not done here,
so use ath_txq_unlock().
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath9k/link.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c
index fff5d3c..2f831db 100644
--- a/drivers/net/wireless/ath/ath9k/link.c
+++ b/drivers/net/wireless/ath/ath9k/link.c
@@ -41,7 +41,7 @@ void ath_tx_complete_poll_work(struct work_struct *work)
txq->axq_tx_inprogress = true;
}
}
- ath_txq_unlock_complete(sc, txq);
+ ath_txq_unlock(sc, txq);
}
if (needreset) {
--
1.8.3.4
^ permalink raw reply related
* Re: [PATCH] mac80211: implement STA CSA for drivers using channel contexts
From: Arik Nemtsov @ 2013-08-25 13:14 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <1377266513.14021.37.camel@jlt4.sipsolutions.net>
On Fri, Aug 23, 2013 at 5:01 PM, Johannes Berg
<johannes@sipsolutions.net> wrote:
> On Fri, 2013-08-16 at 23:09 +0300, Arik Nemtsov wrote:
>
>> > Well, it can't. If you look carefully then the old chan_switch op
>> > behaviour is to let the driver switch, not switch in software
>> > afterwards.
>>
>> The right thing for chan_switch drivers would be not to call hw_config()..
>
> chan_switch? or chanctx?
both. the hw_config(channel) is meaningless for chanctx drivers. The
legacy code for op_chan_switch drivers didn't call hw_config() as
well, assuming they'd already get notified internally by their op.
>> The TI driver implements the chan_switch op and uses channel contexts.
>
> Huh, ok, that was a combination I didn't think was going to exist, since
> the chanswitch API doesn't really tell you what channel context etc.
> OTOH, it does give you the vif so you have the chanctx implicitly.
Yep, it's good enough. The driver gets the chandef from the vif.
>
>> Note that with the above, the channel_contexts + software chan-switch
>> drivers will still need the kind of code that I wrote. So it would
>> just lead to replicated code. Or maybe you meant something else?
>
> We have too many possibilities I guess ... I think for MVM I want the
> disconnect, not the channel context change in software. You're taking
> that possibility away, hence my suggestion of a new hardware flag for it
> or so.
I was thinking it's equivalent to to AP case - currently mac80211 is
the dictator and simply changes the chandef once the lower drv
completes the switch.
Anyway IMHO the simplest approach to handle all the legacy stuff +
chanctx it to keep the current patch as is, and add a mac80211 HW flag
to support it, keeping the deauth option as default.
That's what I think you're suggesting?
>
>> Also, where would you put csa_active = true (if at all) for a STA
>> interface? Unlike AP, the trigger here is mac80211 code. So putting it
>> there seemed appropriate.
>
> Yeah, I was really just trying to say that current chanctx drivers need
> not really expect a chanctx to change channel unless they implement CSA,
> but that currently means AP-CSA - basically what I just said above with
> taking away the possibility of doing the deauth instead.
Let's keep the csa_active as I've used it, and just do a deauth when
the csa-support HW flag is not given?
Arik
^ permalink raw reply
* [PATCH] ath9k: Fix ASPM workaround usage
From: Sujith Manoharan @ 2013-08-25 11:00 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
The PCIE Workaround register (AR_WA/0x4004) is used to handle
various hardware quirks. For AR9002 chips, AR_WA_D3_L1_DISABLE
is used to prevent the HW from automatically entering L1 state
when D3 is enforced.
AR_WA_D3_L1_DISABLE has to be enabled for a few AR9280 based
cards, mark them based on their PCI subdevice/subvendor IDs
and enforce it in ar9002_hw_configpcipowersave().
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath9k/ar9002_hw.c | 29 +++++++------------
drivers/net/wireless/ath/ath9k/ar9003_hw.c | 7 +----
drivers/net/wireless/ath/ath9k/ath9k.h | 1 +
drivers/net/wireless/ath/ath9k/hw.c | 1 -
drivers/net/wireless/ath/ath9k/init.c | 5 ++++
drivers/net/wireless/ath/ath9k/pci.c | 46 ++++++++++++++++++++++++++++++
6 files changed, 64 insertions(+), 25 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
index 8dc2d08..fb61b08 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
@@ -269,13 +269,12 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah,
if (ah->config.pcie_waen & AR_WA_D3_L1_DISABLE)
val |= AR_WA_D3_L1_DISABLE;
} else {
- if (((AR_SREV_9285(ah) ||
- AR_SREV_9271(ah) ||
- AR_SREV_9287(ah)) &&
- (AR9285_WA_DEFAULT & AR_WA_D3_L1_DISABLE)) ||
- (AR_SREV_9280(ah) &&
- (AR9280_WA_DEFAULT & AR_WA_D3_L1_DISABLE))) {
- val |= AR_WA_D3_L1_DISABLE;
+ if (AR_SREV_9285(ah) || AR_SREV_9271(ah) || AR_SREV_9287(ah)) {
+ if (AR9285_WA_DEFAULT & AR_WA_D3_L1_DISABLE)
+ val |= AR_WA_D3_L1_DISABLE;
+ } else if (AR_SREV_9280(ah)) {
+ if (AR9280_WA_DEFAULT & AR_WA_D3_L1_DISABLE)
+ val |= AR_WA_D3_L1_DISABLE;
}
}
@@ -297,24 +296,18 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah,
} else {
if (ah->config.pcie_waen) {
val = ah->config.pcie_waen;
- if (!power_off)
- val &= (~AR_WA_D3_L1_DISABLE);
+ val &= (~AR_WA_D3_L1_DISABLE);
} else {
- if (AR_SREV_9285(ah) ||
- AR_SREV_9271(ah) ||
- AR_SREV_9287(ah)) {
+ if (AR_SREV_9285(ah) || AR_SREV_9271(ah) || AR_SREV_9287(ah)) {
val = AR9285_WA_DEFAULT;
- if (!power_off)
- val &= (~AR_WA_D3_L1_DISABLE);
- }
- else if (AR_SREV_9280(ah)) {
+ val &= (~AR_WA_D3_L1_DISABLE);
+ } else if (AR_SREV_9280(ah)) {
/*
* For AR9280 chips, bit 22 of 0x4004
* needs to be set.
*/
val = AR9280_WA_DEFAULT;
- if (!power_off)
- val &= (~AR_WA_D3_L1_DISABLE);
+ val &= (~AR_WA_D3_L1_DISABLE);
} else {
val = AR_WA_DEFAULT;
}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index 582cddd..608bb48 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -763,12 +763,7 @@ static void ar9003_hw_configpcipowersave(struct ath_hw *ah,
if (!power_off /* !restore */) {
/* set bit 19 to allow forcing of pcie core into L1 state */
REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
-
- /* Several PCIe massages to ensure proper behaviour */
- if (ah->config.pcie_waen)
- REG_WRITE(ah, AR_WA, ah->config.pcie_waen);
- else
- REG_WRITE(ah, AR_WA, ah->WARegVal);
+ REG_WRITE(ah, AR_WA, ah->WARegVal);
}
/*
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 8519e75..2ee35f6 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -631,6 +631,7 @@ void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs);
#define ATH9K_PCI_CUS217 0x0004
#define ATH9K_PCI_WOW 0x0008
#define ATH9K_PCI_BT_ANT_DIV 0x0010
+#define ATH9K_PCI_D3_L1_WAR 0x0020
/*
* Default cache line size, in bytes.
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index b3a6891..2670bf6 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -450,7 +450,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
ah->config.ack_6mb = 0x0;
ah->config.cwm_ignore_extcca = 0;
ah->config.pcie_clock_req = 0;
- ah->config.pcie_waen = 0;
ah->config.analog_shiftreg = 1;
for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index b897183..9a1f349 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -551,6 +551,11 @@ static void ath9k_init_platform(struct ath_softc *sc)
pCap->hw_caps |= ATH9K_HW_CAP_BT_ANT_DIV;
ath_info(common, "Set BT/WLAN RX diversity capability\n");
}
+
+ if (sc->driver_data & ATH9K_PCI_D3_L1_WAR) {
+ ah->config.pcie_waen = 0x0040473b;
+ ath_info(common, "Enable WAR for ASPM D3/L1\n");
+ }
}
static void ath9k_eeprom_request_cb(const struct firmware *eeprom_blob,
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index e7996a6..d089a7c 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -30,6 +30,52 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
{ PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */
{ PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */
+ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+ 0x002A,
+ PCI_VENDOR_ID_AZWAVE,
+ 0x1C71),
+ .driver_data = ATH9K_PCI_D3_L1_WAR },
+ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+ 0x002A,
+ PCI_VENDOR_ID_FOXCONN,
+ 0xE01F),
+ .driver_data = ATH9K_PCI_D3_L1_WAR },
+ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+ 0x002A,
+ 0x11AD, /* LITEON */
+ 0x6632),
+ .driver_data = ATH9K_PCI_D3_L1_WAR },
+ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+ 0x002A,
+ 0x11AD, /* LITEON */
+ 0x6642),
+ .driver_data = ATH9K_PCI_D3_L1_WAR },
+ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+ 0x002A,
+ PCI_VENDOR_ID_QMI,
+ 0x0306),
+ .driver_data = ATH9K_PCI_D3_L1_WAR },
+ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+ 0x002A,
+ 0x185F, /* WNC */
+ 0x309D),
+ .driver_data = ATH9K_PCI_D3_L1_WAR },
+ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+ 0x002A,
+ 0x10CF, /* Fujitsu */
+ 0x147C),
+ .driver_data = ATH9K_PCI_D3_L1_WAR },
+ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+ 0x002A,
+ 0x10CF, /* Fujitsu */
+ 0x147D),
+ .driver_data = ATH9K_PCI_D3_L1_WAR },
+ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+ 0x002A,
+ 0x10CF, /* Fujitsu */
+ 0x1536),
+ .driver_data = ATH9K_PCI_D3_L1_WAR },
+
/* AR9285 card for Asus */
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
0x002B,
--
1.8.3.4
^ permalink raw reply related
* [PATCH] ath5k: debugfs: NULL-terminate strings
From: Djalal Harouni @ 2013-08-25 10:50 UTC (permalink / raw)
To: Jiri Slaby, Nick Kossifidis, John W. Linville, linux-wireless,
linux-kernel
Cc: Djalal Harouni
Avoid processing garbage data by NULL terminating the strings.
Signed-off-by: Djalal Harouni <tixxdz@opendz.org>
---
Patch compile tested only.
drivers/net/wireless/ath/ath5k/debug.c | 24 ++++++++++++++++++------
1 file changed, 18 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c
index 9d00dab..b8d031a 100644
--- a/drivers/net/wireless/ath/ath5k/debug.c
+++ b/drivers/net/wireless/ath/ath5k/debug.c
@@ -245,9 +245,11 @@ static ssize_t write_file_beacon(struct file *file,
struct ath5k_hw *ah = file->private_data;
char buf[20];
- if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
+ count = min_t(size_t, count, sizeof(buf) - 1);
+ if (copy_from_user(buf, userbuf, count))
return -EFAULT;
+ buf[count] = '\0';
if (strncmp(buf, "disable", 7) == 0) {
AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
pr_info("debugfs disable beacons\n");
@@ -345,9 +347,11 @@ static ssize_t write_file_debug(struct file *file,
unsigned int i;
char buf[20];
- if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
+ count = min_t(size_t, count, sizeof(buf) - 1);
+ if (copy_from_user(buf, userbuf, count))
return -EFAULT;
+ buf[count] = '\0';
for (i = 0; i < ARRAY_SIZE(dbg_info); i++) {
if (strncmp(buf, dbg_info[i].name,
strlen(dbg_info[i].name)) == 0) {
@@ -448,9 +452,11 @@ static ssize_t write_file_antenna(struct file *file,
unsigned int i;
char buf[20];
- if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
+ count = min_t(size_t, count, sizeof(buf) - 1);
+ if (copy_from_user(buf, userbuf, count))
return -EFAULT;
+ buf[count] = '\0';
if (strncmp(buf, "diversity", 9) == 0) {
ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_DEFAULT);
pr_info("debug: enable diversity\n");
@@ -619,9 +625,11 @@ static ssize_t write_file_frameerrors(struct file *file,
struct ath5k_statistics *st = &ah->stats;
char buf[20];
- if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
+ count = min_t(size_t, count, sizeof(buf) - 1);
+ if (copy_from_user(buf, userbuf, count))
return -EFAULT;
+ buf[count] = '\0';
if (strncmp(buf, "clear", 5) == 0) {
st->rxerr_crc = 0;
st->rxerr_phy = 0;
@@ -766,9 +774,11 @@ static ssize_t write_file_ani(struct file *file,
struct ath5k_hw *ah = file->private_data;
char buf[20];
- if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
+ count = min_t(size_t, count, sizeof(buf) - 1);
+ if (copy_from_user(buf, userbuf, count))
return -EFAULT;
+ buf[count] = '\0';
if (strncmp(buf, "sens-low", 8) == 0) {
ath5k_ani_init(ah, ATH5K_ANI_MODE_MANUAL_HIGH);
} else if (strncmp(buf, "sens-high", 9) == 0) {
@@ -862,9 +872,11 @@ static ssize_t write_file_queue(struct file *file,
struct ath5k_hw *ah = file->private_data;
char buf[20];
- if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
+ count = min_t(size_t, count, sizeof(buf) - 1);
+ if (copy_from_user(buf, userbuf, count))
return -EFAULT;
+ buf[count] = '\0';
if (strncmp(buf, "start", 5) == 0)
ieee80211_wake_queues(ah->hw);
else if (strncmp(buf, "stop", 4) == 0)
--
1.7.11.7
^ permalink raw reply related
* [PATCH] ath9k: Fix ASPM for AR9462
From: Sujith Manoharan @ 2013-08-25 9:13 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
If the L1 entrance latency is not calibrated properly
in the EEPROM in WB222 boards, there could be problems
in connectivity. Check and correct the calibrated value
if it doesn't match the optimal value for WB222, 4us.
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath9k/ar9003_hw.c | 14 ++++++++++++++
drivers/net/wireless/ath/ath9k/hw.h | 1 +
drivers/net/wireless/ath/ath9k/pci.c | 16 ++++++++++++++++
3 files changed, 31 insertions(+)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index 738aa7e..582cddd 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -745,6 +745,20 @@ static void ar9003_hw_init_mode_gain_regs(struct ath_hw *ah)
static void ar9003_hw_configpcipowersave(struct ath_hw *ah,
bool power_off)
{
+ /*
+ * Increase L1 Entry Latency. Some WB222 boards don't have
+ * this change in eeprom/OTP.
+ *
+ */
+ if (AR_SREV_9462(ah)) {
+ u32 val = ah->config.aspm_l1_fix;
+ if ((val & 0xff000000) == 0x17000000) {
+ val &= 0x00ffffff;
+ val |= 0x27000000;
+ REG_WRITE(ah, 0x570c, val);
+ }
+ }
+
/* Nothing to do on restore for 11N */
if (!power_off /* !restore */) {
/* set bit 19 to allow forcing of pcie core into L1 state */
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index fa543a6..69a907b 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -311,6 +311,7 @@ struct ath9k_ops_config {
u16 ani_poll_interval; /* ANI poll interval in ms */
/* Platform specific config */
+ u32 aspm_l1_fix;
u32 xlna_gpio;
u32 ant_ctrl_comm2g_switch_enable;
bool xatten_margin_cfg;
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 3280798..e7996a6 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -314,6 +314,22 @@ static void ath_pci_aspm_init(struct ath_common *common)
return;
}
+ /*
+ * 0x70c - Ack Frequency Register.
+ *
+ * Bits 27:29 - DEFAULT_L1_ENTRANCE_LATENCY.
+ *
+ * 000 : 1 us
+ * 001 : 2 us
+ * 010 : 4 us
+ * 011 : 8 us
+ * 100 : 16 us
+ * 101 : 32 us
+ * 110/111 : 64 us
+ */
+ if (AR_SREV_9462(ah))
+ pci_read_config_dword(pdev, 0x70c, &ah->config.aspm_l1_fix);
+
pcie_capability_read_word(parent, PCI_EXP_LNKCTL, &aspm);
if (aspm & (PCI_EXP_LNKCTL_ASPM_L0S | PCI_EXP_LNKCTL_ASPM_L1)) {
ah->aspm_enabled = true;
--
1.8.3.4
^ permalink raw reply related
* RE: [Ilw] Re: iwlwifi micorcode errors and hardware resets problems
From: Grumbach, Emmanuel @ 2013-08-25 8:21 UTC (permalink / raw)
To: Luca Coelho, Stanislaw Gruszka
Cc: ilw@linux.intel.com, linux-wireless@vger.kernel.org
In-Reply-To: <1377345177.5589.3.camel@porter.coelho.fi>
PiBPbiBGcmksIDIwMTMtMDgtMjMgYXQgMTE6MDggKzAyMDAsIFN0YW5pc2xhdyBHcnVzemthIHdy
b3RlOg0KPiA+IFdlIGhhdmUgdGhvc2UgYnVnIHJlcG9ydHMgb24gUkggYnVnemlsbGEsIGFuZCB2
YXJpb3VzIG90aGVyIGl3bHdpZmkNCj4gPiBwcm9ibGVtcywgYnV0IHRob3NlIGhhdmUgc29tZSBj
b21tb24gc2NlbmFyaW86DQo+ID4NCj4gPiBodHRwczovL2J1Z3ppbGxhLnJlZGhhdC5jb20vc2hv
d19idWcuY2dpP2lkPTk3OTg3Mw0KPiA+IGh0dHBzOi8vYnVnemlsbGEucmVkaGF0LmNvbS9zaG93
X2J1Zy5jZ2k/aWQ9OTkwNTM2DQo+ID4gaHR0cHM6Ly9idWd6aWxsYS5yZWRoYXQuY29tL3Nob3df
YnVnLmNnaT9pZD05OTQzMjINCj4gPiBodHRwczovL2J1Z3ppbGxhLnJlZGhhdC5jb20vc2hvd19i
dWcuY2dpP2lkPTk5NjUwMg0KPiA+IGh0dHBzOi8vYnVnemlsbGEucmVkaGF0LmNvbS9zaG93X2J1
Zy5jZ2k/aWQ9OTY5NjEwDQo+ID4gaHR0cHM6Ly9idWd6aWxsYS5yZWRoYXQuY29tL3Nob3dfYnVn
LmNnaT9pZD05OTkwNTMNCj4gPg0KPiA+IEZpcnN0IHRoZXJlIGlzIE1pY3JvY29kZSBlcnJvciBv
ciBvdGhlciBmaXJtd2FyZSBwcm9ibGVtLCB3aGF0IG1ha2Ugd2UNCj4gPiBkbyBpd2xfdHJhbnNf
c3RvcF9kZXZpY2UoKSB3aGljaCBzZXQgdHJhbnMtPnN0YXRlIHRvIElXTF9UUkFOU19OT19GVy4N
Cj4gPiBJZiBtYWM4MDIxMSBoYXMgc29tZSBwZW5kaW5nIHdvcmtzL3RpbWVycyBpLmUuIGllZWU4
MDIxMV9zdGFfd29yaygpLA0KPiA+IGl0IGNhbGxzIGRydiBhbmQgd2UgdHJpZ2dlciBvbiBvZiB0
aG9zZSB3YXJuaW5ncw0KPiA+DQo+ID4gICAgICAgICBXQVJOX09OQ0UodHJhbnMtPnN0YXRlICE9
IElXTF9UUkFOU19GV19BTElWRSwNCj4gPiAgICAgICAgICAgICAgICAgICAiJXMgYmFkIHN0YXRl
ID0gJWQiLCBfX2Z1bmNfXywgdHJhbnMtPnN0YXRlKTsNCj4gPg0KPiA+IG9uIHNvbWUgdHJhbnMg
b3BlcmF0aW9uLg0KPiA+DQo+ID4gSSB0aGluayB0aGlzIGNhbiBiZSBmaXhlZCBieSBmaXJzdCBk
byBxdWllc2NlIG9uIG1hYzgwMjExIChmb3IgZXhhbXBsZQ0KPiA+IGJ5IGllZWU4MDIxMV9zdGFf
cXVpZXNjZSgpIHByb2NlZHVyZSwgd2hpY2ggSSByZW1vdmVkIGJ1dCBjYW4gYmUgYWRkZWQNCj4g
PiBiYWNrKSBhbmQgdGhlbiBkbyBpd2xhZ25fcHJlcGFyZV9yZXN0YXJ0KCkgJiBpZWVlODAyMTFf
cmVzdGFydF9odygpLg0KPiA+DQo+ID4gVGhvdWdoIEknbSBub3Qgc3VyZSBpZiBpdCdzIHdvcnRo
IHRvIGRvIHRoaXMgc2luY2UgdGhvc2Ugd2FybmluZ3MgYXJlDQo+ID4gaW5kaWNhdG9yIGZvciBt
YWxmdW5jdGlvbmluZyBpd2x3aWZpIGZpcm13YXJlIChvciBkcml2ZXIgbm90IGNvcnJlY3RseQ0K
PiA+IGNvbW11bmljYXRpbmcgd2l0aCBmaXJtd2FyZSksIHdoaWNoIHdpbGwgYmUgdW5ub3RpY2Vk
IGlmIG5vdCByZXBvcnRlZA0KPiA+IGF1dG9tYXRpY2FsbHkgYnkgdG9vbCBsaWtlIEFCUlQuIEJ1
dCBwZXJoYXBzIHdlIGNvdWxkIGFkZCBXQVJOX09OQ0Ugb24NCj4gPiBNaWNyb2NvZGUgZXJyb3Ig
Y29uZGl0aW9uID8NCj4gDQo+IEkgdGhpbmsgdGhhdCwgaWYgdGhlIHF1aWVzY2UgcmVhbGx5IGhl
bHBzIHdpdGggdGhpcywgd2Ugc2hvdWxkIGRvIGl0Lg0KPiBUaGlzIFdBUk4gaXMgYSBzaWRlLWVm
ZmVjdCBvZiB0aGUgcHJvYmxlbSBhbmQgbm90IHRoZSBwcm9ibGVtIGl0c2VsZi4NCj4gSWYgeW91
IHdhbnQgdG8gY2F0Y2ggdGhlIEZXIHByb2JsZW0sIHRoZXJlIHNob3VsZCBiZSBhIFdBUk4gZWxz
ZXdoZXJlLg0KPiANCj4gSSdtIG5vdCBzYXlpbmcgdGhhdCB0aGlzIFdBUk4gc2hvdWxkIGJlIHJl
bW92ZWQgYW5kIEkgYWxzbyB0aGluayBpdCdzIGEgZ29vZA0KPiBpZGVhIHRvIGNoYW5nZSBpdCB0
byBXQVJOX09OX09OQ0UoKS4gIEkganVzdCB0aGluayB0aGF0LCBpZiB0aGVyZSdzIGFueXRoaW5n
DQo+IHRoZSBkcml2ZXIgY2FuIGRvIHRvIGtlZXAgdGhpbmdzIHJ1bm5pbmcgbmljZWx5LCB3ZSBz
aG91bGQgZG8gaXQuDQo+IA0KPiBJbiBhbnkgY2FzZSwgSSdsbCBsZWF2ZSB0aGlzIGZvciBKb2hh
bm5lcywgRW1tYW51ZWwgb3Igc29tZSBvZiB0aGUgb3RoZXIgZ3V5cw0KPiB3aXRoIG1vcmUgZXhw
ZXJpZW5jZSBpbiBpd2x3aWZpIHRvIGNvbW1lbnQuIDspDQoNCllvdSBnb3QgbXkgQUNLIGhlcmUu
IFdlIGhhdmUgc29tZSBpc3N1ZXMgd2l0aCBmaXJtd2FyZS4gT2J2aW91c2x5LiBCdXQgbW9zdCBv
ZiB0aGUgaXNzdWVzIGFyZSB2ZXJ5IGhhcmQgdG8gZGVidWcuIE1vc3Qgb2YgdGhlbSBJIGFtIHNl
ZWluZyBhcmUgbW9yZSBsaWtlIHRoZSBmaXJtd2FyZSBnZXR0aW5nIHN0dWNrIGV0Yy4uLiAgQWZ0
ZXIgYWxsIHRoaXMgaXMgd2h5IHdlIGhhdmUgYSByZXN0YXJ0IGZsb3csIGZvciB0aGVzZSBpc3N1
ZXMgdGhhdCBkb24ndCBoYXBwZW4gZnJlcXVlbnRseSBidXQgYXJlIHNvbHZhYmxlIGJ5IGEgcmVz
ZXQuIFNpbmNlIHdlIHN0aWxsIHdhbnQgdG8ga25vdyB3aGVuIHRoaXMga2luZCBvZiB0aGluZ3Mg
aGFwcGVuLCBhZGRpbmcgYSBXQVJOX09OX09OQ0Ugc291bmRzIGdvb2QuDQo=
^ permalink raw reply
* mac80211 kernel panic due to invalid cab_queue value with hwsim
From: Jouni Malinen @ 2013-08-24 16:00 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless
Something is cab_queue handling is broken (and has been broken for a
while) in mac80211. At least mac80211_hwsim shows this, but I guess it
could happen with some other drivers, too. The error shows up as
group-addressed Data frames from a P2P GO not being transmitted if
CONFIG_MAC80211_VERBOSE_DEBUG is defined and kernel panic if that is not
defined. ieee80211_tx_h_multicast_ps_buf() can assign
IEEE80211_INVAL_HW_QUEUE (0xff) into info->hw_queue in some cases and
that results in the issues in ieee80211_tx_frags where q >=
local->hw.queues check is done only with verbose debugging enabled. If
that check is not there, kernel panic shows up at least in
skb_queue_splice_tail_init() when that invalid hw_queue 0xff value is
used to index the local->pending array.
I'm not sure where cab_queue should be cleared to avoid this, but for
now, I'm using following workaround to avoid the symptoms:
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 098ae85..41655a4 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -413,8 +413,13 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx)
if (ieee80211_has_order(hdr->frame_control))
return TX_CONTINUE;
- if (tx->local->hw.flags & IEEE80211_HW_QUEUE_CONTROL)
- info->hw_queue = tx->sdata->vif.cab_queue;
+ if (tx->local->hw.flags & IEEE80211_HW_QUEUE_CONTROL) {
+ if (tx->sdata->vif.cab_queue == IEEE80211_INVAL_HW_QUEUE) {
+ printk(KERN_DEBUG "%s:trying to assign invalid cab_queue for skb %p vif.type=%d\n",
+ __func__, tx->skb, tx->sdata->vif.type);
+ } else
+ info->hw_queue = tx->sdata->vif.cab_queue;
+ }
/* no stations in PS mode */
if (!atomic_read(&ps->num_sta_ps))
--
Jouni Malinen PGP id EFC895FA
^ permalink raw reply related
* [PATCH v2] iwlwifi: mvm: make debugfs write() operations write up to count bytes
From: Djalal Harouni @ 2013-08-24 13:35 UTC (permalink / raw)
To: Johannes Berg, Intel Linux Wireless, John W. Linville,
Emmanuel Grumbach, linux-wireless, linux-kernel
Cc: Djalal Harouni
Some debugfs write() operations of the MVM Firmware will ignore the
count argument, and will copy more bytes than what was specified.
Fix this by getting the right count of bytes.
This will honor restrictions put on the number of bytes to write and
avoid strcmp() calls on garbage data.
Signed-off-by: Djalal Harouni <tixxdz@opendz.org>
Cc: "Berg, Johannes" <johannes.berg@intel.com>
---
Patch compile tested only.
v2 Clean patch and use min_t() as noted by Berg Johannes
drivers/net/wireless/iwlwifi/mvm/debugfs.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
index aac81b8..299966a 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -257,7 +257,8 @@ static ssize_t iwl_dbgfs_power_down_allow_write(struct file *file,
if (!mvm->ucode_loaded)
return -EIO;
- if (copy_from_user(buf, user_buf, sizeof(buf)))
+ count = min_t(size_t, count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, count))
return -EFAULT;
if (sscanf(buf, "%d", &allow) != 1)
@@ -281,7 +282,8 @@ static ssize_t iwl_dbgfs_power_down_d3_allow_write(struct file *file,
char buf[8] = {};
int allow;
- if (copy_from_user(buf, user_buf, sizeof(buf)))
+ count = min_t(size_t, count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, count))
return -EFAULT;
if (sscanf(buf, "%d", &allow) != 1)
@@ -371,7 +373,8 @@ static ssize_t iwl_dbgfs_pm_params_write(struct file *file,
int val;
int ret;
- if (copy_from_user(buf, user_buf, sizeof(buf)))
+ count = min_t(size_t, count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, count))
return -EFAULT;
if (!strncmp("keep_alive=", buf, 11)) {
@@ -968,7 +971,8 @@ static ssize_t iwl_dbgfs_d3_sram_write(struct file *file,
char buf[8] = {};
int store;
- if (copy_from_user(buf, user_buf, sizeof(buf)))
+ count = min_t(size_t, count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, count))
return -EFAULT;
if (sscanf(buf, "%d", &store) != 1)
--
1.7.11.7
^ permalink raw reply related
* [PATCH 5/5] staging: vt6656: s_vGenerateTxParameter pvRrvTime should never be NULL
From: Malcolm Priestley @ 2013-08-24 12:15 UTC (permalink / raw)
To: gregkh; +Cc: linux-wireless
If pvRrvTime is NULL the whole structure is NULL, so
remove if statements and consolidate to single return.
Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
---
drivers/staging/vt6656/rxtx.c | 16 +++-------------
1 file changed, 3 insertions(+), 13 deletions(-)
diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c
index 64ce7f0..dd2bfc9 100644
--- a/drivers/staging/vt6656/rxtx.c
+++ b/drivers/staging/vt6656/rxtx.c
@@ -860,6 +860,9 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice,
byFBOption = AUTO_FB_1;
}
+ if (!pvRrvTime)
+ return;
+
if (pDevice->bLongHeader)
cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6;
@@ -867,7 +870,6 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice,
if (pvRTS != NULL) { //RTS_need
//Fill RsvTime
- if (pvRrvTime) {
struct vnt_rrv_time_rts *pBuf =
(struct vnt_rrv_time_rts *)pvRrvTime;
pBuf->wRTSTxRrvTime_aa = s_uGetRTSCTSRsvTime(pDevice, 2,
@@ -881,15 +883,12 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice,
pBuf->wTxRrvTime_b = vnt_rxtx_rsvtime_le16(pDevice,
PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate,
bNeedACK);
- }
//Fill RTS
s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK,
psEthHeader, wCurrentRate, byFBOption);
}
else {//RTS_needless, PCF mode
-
//Fill RsvTime
- if (pvRrvTime) {
struct vnt_rrv_time_cts *pBuf =
(struct vnt_rrv_time_cts *)pvRrvTime;
pBuf->wTxRrvTime_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType,
@@ -899,7 +898,6 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice,
pDevice->byTopCCKBasicRate, bNeedACK);
pBuf->wCTSTxRrvTime_ba = s_uGetRTSCTSRsvTime(pDevice, 3,
byPktType, cbFrameSize, wCurrentRate);
- }
//Fill CTS
s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize,
bNeedACK, wCurrentRate, byFBOption);
@@ -909,52 +907,44 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice,
if (pvRTS != NULL) {//RTS_need, non PCF mode
//Fill RsvTime
- if (pvRrvTime) {
struct vnt_rrv_time_ab *pBuf =
(struct vnt_rrv_time_ab *)pvRrvTime;
pBuf->wRTSTxRrvTime = s_uGetRTSCTSRsvTime(pDevice, 2,
byPktType, cbFrameSize, wCurrentRate);
pBuf->wTxRrvTime = vnt_rxtx_rsvtime_le16(pDevice, byPktType,
cbFrameSize, wCurrentRate, bNeedACK);
- }
//Fill RTS
s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK,
psEthHeader, wCurrentRate, byFBOption);
}
else if (pvRTS == NULL) {//RTS_needless, non PCF mode
//Fill RsvTime
- if (pvRrvTime) {
struct vnt_rrv_time_ab *pBuf =
(struct vnt_rrv_time_ab *)pvRrvTime;
pBuf->wTxRrvTime = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11A,
cbFrameSize, wCurrentRate, bNeedACK);
- }
}
}
else if (byPktType == PK_TYPE_11B) {
if ((pvRTS != NULL)) {//RTS_need, non PCF mode
//Fill RsvTime
- if (pvRrvTime) {
struct vnt_rrv_time_ab *pBuf =
(struct vnt_rrv_time_ab *)pvRrvTime;
pBuf->wRTSTxRrvTime = s_uGetRTSCTSRsvTime(pDevice, 0,
byPktType, cbFrameSize, wCurrentRate);
pBuf->wTxRrvTime = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B,
cbFrameSize, wCurrentRate, bNeedACK);
- }
//Fill RTS
s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK,
psEthHeader, wCurrentRate, byFBOption);
}
else { //RTS_needless, non PCF mode
//Fill RsvTime
- if (pvRrvTime) {
struct vnt_rrv_time_ab *pBuf =
(struct vnt_rrv_time_ab *)pvRrvTime;
pBuf->wTxRrvTime = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B,
cbFrameSize, wCurrentRate, bNeedACK);
- }
}
}
//DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter END.\n");
--
1.8.1.2
^ permalink raw reply related
* [PATCH 4/5] staging: vt6656: s_vGenerateTxParameter dead code bDisCRC
From: Malcolm Priestley @ 2013-08-24 12:01 UTC (permalink / raw)
To: gregkh; +Cc: linux-wireless
As result of patch
vt6656: rxtx.c s_vFillCTSHead remove dead code bDisCRC
bDisCRC is unused.
Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
---
drivers/staging/vt6656/rxtx.c | 5 -----
1 file changed, 5 deletions(-)
diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c
index 7b94a77..64ce7f0 100644
--- a/drivers/staging/vt6656/rxtx.c
+++ b/drivers/staging/vt6656/rxtx.c
@@ -846,7 +846,6 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice,
{
u32 cbMACHdLen = WLAN_HDR_ADDR3_LEN; /* 24 */
u16 wFifoCtl;
- int bDisCRC = false;
u8 byFBOption = AUTO_FB_NONE;
//DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter...\n");
@@ -854,10 +853,6 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice,
pFifoHead->wReserved = wCurrentRate;
wFifoCtl = pFifoHead->wFIFOCtl;
- if (wFifoCtl & FIFOCTL_CRCDIS) {
- bDisCRC = true;
- }
-
if (wFifoCtl & FIFOCTL_AUTO_FB_0) {
byFBOption = AUTO_FB_0;
}
--
1.8.1.2
^ permalink raw reply related
* [PATCH 3/5] staging: vt6656: rxtx.c s_vFillCTSHead remove dead code bDisCRC
From: Malcolm Priestley @ 2013-08-24 11:56 UTC (permalink / raw)
To: gregkh; +Cc: linux-wireless
As result of patch
vt6656: device.h Remove dead code bSoftwareGenCrcErr.
dDiscCRC is unused.
Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
---
drivers/staging/vt6656/rxtx.c | 13 ++++---------
1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c
index 1b2effc..7b94a77 100644
--- a/drivers/staging/vt6656/rxtx.c
+++ b/drivers/staging/vt6656/rxtx.c
@@ -126,7 +126,7 @@ static u16 s_uGetRTSCTSRsvTime(struct vnt_private *pDevice, u8 byRTSRsvType,
static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
u8 byPktType, void *pvCTS, u32 cbFrameLength, int bNeedAck,
- int bDisCRC, u16 wCurrentRate, u8 byFBOption);
+ u16 wCurrentRate, u8 byFBOption);
static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
void *pvRTS, u32 cbFrameLength, int bNeedAck,
@@ -769,7 +769,7 @@ static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
u8 byPktType, void *pvCTS, u32 cbFrameLength, int bNeedAck,
- int bDisCRC, u16 wCurrentRate, u8 byFBOption)
+ u16 wCurrentRate, u8 byFBOption)
{
u32 uCTSFrameLen = 14;
@@ -777,12 +777,6 @@ static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
return;
}
- if (bDisCRC) {
- // When CRCDIS bit is on, H/W forgot to generate FCS for CTS frame,
- // in this case we need to decrease its length by 4.
- uCTSFrameLen -= 4;
- }
-
if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
if (byFBOption != AUTO_FB_NONE) {
/* Auto Fall back */
@@ -912,7 +906,8 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice,
byPktType, cbFrameSize, wCurrentRate);
}
//Fill CTS
- s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);
+ s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize,
+ bNeedACK, wCurrentRate, byFBOption);
}
}
else if (byPktType == PK_TYPE_11A) {
--
1.8.1.2
^ permalink raw reply related
* Re: iwlwifi micorcode errors and hardware resets problems
From: Luca Coelho @ 2013-08-24 11:52 UTC (permalink / raw)
To: Stanislaw Gruszka; +Cc: ilw, linux-wireless
In-Reply-To: <20130823090821.GB2632@redhat.com>
On Fri, 2013-08-23 at 11:08 +0200, Stanislaw Gruszka wrote:
> We have those bug reports on RH bugzilla, and various other iwlwifi
> problems, but those have some common scenario:
>
> https://bugzilla.redhat.com/show_bug.cgi?id=979873
> https://bugzilla.redhat.com/show_bug.cgi?id=990536
> https://bugzilla.redhat.com/show_bug.cgi?id=994322
> https://bugzilla.redhat.com/show_bug.cgi?id=996502
> https://bugzilla.redhat.com/show_bug.cgi?id=969610
> https://bugzilla.redhat.com/show_bug.cgi?id=999053
>
> First there is Microcode error or other firmware problem, what make we
> do iwl_trans_stop_device() which set trans->state to IWL_TRANS_NO_FW.
> If mac80211 has some pending works/timers i.e. ieee80211_sta_work(),
> it calls drv and we trigger on of those warnings
>
> WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
> "%s bad state = %d", __func__, trans->state);
>
> on some trans operation.
>
> I think this can be fixed by first do quiesce on mac80211 (for example
> by ieee80211_sta_quiesce() procedure, which I removed but can be added
> back) and then do iwlagn_prepare_restart() & ieee80211_restart_hw().
>
> Though I'm not sure if it's worth to do this since those warnings are
> indicator for malfunctioning iwlwifi firmware (or driver not correctly
> communicating with firmware), which will be unnoticed if not reported
> automatically by tool like ABRT. But perhaps we could add WARN_ONCE on
> Microcode error condition ?
I think that, if the quiesce really helps with this, we should do it.
This WARN is a side-effect of the problem and not the problem itself.
If you want to catch the FW problem, there should be a WARN elsewhere.
I'm not saying that this WARN should be removed and I also think it's a
good idea to change it to WARN_ON_ONCE(). I just think that, if there's
anything the driver can do to keep things running nicely, we should do
it.
In any case, I'll leave this for Johannes, Emmanuel or some of the other
guys with more experience in iwlwifi to comment. ;)
--
Cheers,
Luca.
^ permalink raw reply
* [PATCH 2/5] staging: vt6656: rxtx.c s_vFillRTSHead remove dead bDiscCRC
From: Malcolm Priestley @ 2013-08-24 11:50 UTC (permalink / raw)
To: gregkh; +Cc: linux-wireless
As result of patch
vt6656: device.h Remove dead code bSoftwareGenCrcErr.
dDiscCRC is unused.
Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
---
drivers/staging/vt6656/rxtx.c | 19 ++++++++-----------
1 file changed, 8 insertions(+), 11 deletions(-)
diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c
index 80741c0..1b2effc 100644
--- a/drivers/staging/vt6656/rxtx.c
+++ b/drivers/staging/vt6656/rxtx.c
@@ -129,7 +129,7 @@ static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
int bDisCRC, u16 wCurrentRate, u8 byFBOption);
static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
- void *pvRTS, u32 cbFrameLength, int bNeedAck, int bDisCRC,
+ void *pvRTS, u32 cbFrameLength, int bNeedAck,
struct ethhdr *psEthHeader, u16 wCurrentRate, u8 byFBOption);
static u16 s_uGetDataDuration(struct vnt_private *pDevice,
@@ -596,7 +596,7 @@ static u32 s_uFillDataHead(struct vnt_private *pDevice,
}
static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
- void *pvRTS, u32 cbFrameLength, int bNeedAck, int bDisCRC,
+ void *pvRTS, u32 cbFrameLength, int bNeedAck,
struct ethhdr *psEthHeader, u16 wCurrentRate, u8 byFBOption)
{
u32 uRTSFrameLen = 20;
@@ -604,12 +604,6 @@ static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
if (pvRTS == NULL)
return;
- if (bDisCRC) {
- // When CRCDIS bit is on, H/W forgot to generate FCS for RTS frame,
- // in this case we need to decrease its length by 4.
- uRTSFrameLen -= 4;
- }
-
// Note: So far RTSHead doesn't appear in ATIM & Beacom DMA, so we don't need to take them into account.
// Otherwise, we need to modified codes for them.
if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
@@ -900,7 +894,8 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice,
bNeedACK);
}
//Fill RTS
- s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
+ s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK,
+ psEthHeader, wCurrentRate, byFBOption);
}
else {//RTS_needless, PCF mode
@@ -933,7 +928,8 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice,
cbFrameSize, wCurrentRate, bNeedACK);
}
//Fill RTS
- s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
+ s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK,
+ psEthHeader, wCurrentRate, byFBOption);
}
else if (pvRTS == NULL) {//RTS_needless, non PCF mode
//Fill RsvTime
@@ -958,7 +954,8 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice,
cbFrameSize, wCurrentRate, bNeedACK);
}
//Fill RTS
- s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
+ s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK,
+ psEthHeader, wCurrentRate, byFBOption);
}
else { //RTS_needless, non PCF mode
//Fill RsvTime
--
1.8.1.2
^ permalink raw reply related
* [PATCH 1/5] staging: vt6656: device.h Remove dead code bSoftwareGenCrcErr.
From: Malcolm Priestley @ 2013-08-24 11:42 UTC (permalink / raw)
To: gregkh; +Cc: linux-wireless
Probably an error in earlier firmware is never enabled so remove.
bPacketToWirelessUsb remove dead if/else and variables.
Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
---
drivers/staging/vt6656/device.h | 1 -
drivers/staging/vt6656/rxtx.c | 21 +--------------------
2 files changed, 1 insertion(+), 21 deletions(-)
diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h
index 4986910..e8f4b19 100644
--- a/drivers/staging/vt6656/device.h
+++ b/drivers/staging/vt6656/device.h
@@ -596,7 +596,6 @@ struct vnt_private {
int bCCK;
int bEncryptionEnable;
int bLongHeader;
- int bSoftwareGenCrcErr;
int bShortSlotTime;
int bProtectMode;
int bNonERPPresent;
diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c
index 14b7def..80741c0 100644
--- a/drivers/staging/vt6656/rxtx.c
+++ b/drivers/staging/vt6656/rxtx.c
@@ -1003,7 +1003,7 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
void *pvTxDataHd;
u8 byFBOption = AUTO_FB_NONE, byFragType;
u16 wTxBufSize;
- u32 dwMICKey0, dwMICKey1, dwMIC_Priority, dwCRC;
+ u32 dwMICKey0, dwMICKey1, dwMIC_Priority;
u32 *pdwMIC_L, *pdwMIC_R;
int bSoftWEP = false;
@@ -1058,10 +1058,6 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
if (pDevice->bLongHeader)
pTxBufHead->wFIFOCtl |= FIFOCTL_LHEAD;
- if (pDevice->bSoftwareGenCrcErr) {
- pTxBufHead->wFIFOCtl |= FIFOCTL_CRCDIS; // set tx descriptors to NO hardware CRC
- }
-
//Set FRAGCTL_MACHDCNT
if (pDevice->bLongHeader) {
cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6;
@@ -1386,22 +1382,7 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
cbFrameSize -= cbICVlen;
}
- if (pDevice->bSoftwareGenCrcErr == true) {
- unsigned int cbLen;
- u32 * pdwCRC;
-
- dwCRC = 0xFFFFFFFFL;
- cbLen = cbFrameSize - cbFCSlen;
- // calculate CRC, and wrtie CRC value to end of TD
- dwCRC = CRCdwGetCrc32Ex(pbyMacHdr, cbLen, dwCRC);
- pdwCRC = (u32 *)(pbyMacHdr + cbLen);
- // finally, we must invert dwCRC to get the correct answer
- *pdwCRC = ~dwCRC;
- // Force Error
- *pdwCRC -= 1;
- } else {
cbFrameSize -= cbFCSlen;
- }
*pcbHeaderLen = cbHeaderLength;
*pcbTotalLen = cbHeaderLength + cbFrameSize ;
--
1.8.1.2
^ permalink raw reply related
* [PATCH 3/3] mwifiex: drop gratuitous ARP frames
From: Bing Zhao @ 2013-08-23 23:48 UTC (permalink / raw)
To: linux-wireless
Cc: John W. Linville, Amitkumar Karwar, Avinash Patil,
Nishant Sarmukadam, Frank Huang, Bing Zhao
In-Reply-To: <1377301703-8853-1-git-send-email-bzhao@marvell.com>
From: Avinash Patil <patila@marvell.com>
This patch adds support for dropping gratuitous ARP frames which is
requirement for WFA Hotspot2.0.
Hotspot2.0 capability is enabled in driver if extended capabilities
IE from BSS descriptor has 11u interworking enabled.
Signed-off-by: Avinash Patil <patila@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
drivers/net/wireless/mwifiex/11n.c | 6 ++++
drivers/net/wireless/mwifiex/cfg80211.c | 1 +
drivers/net/wireless/mwifiex/decl.h | 9 ++++++
drivers/net/wireless/mwifiex/init.c | 1 +
drivers/net/wireless/mwifiex/main.h | 1 +
drivers/net/wireless/mwifiex/sta_rx.c | 49 +++++++++++++++++++++++++++++++++
6 files changed, 67 insertions(+)
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c
index b579a2e..0b803c0 100644
--- a/drivers/net/wireless/mwifiex/11n.c
+++ b/drivers/net/wireless/mwifiex/11n.c
@@ -399,6 +399,12 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv,
bss_desc->bcn_ext_cap + sizeof(struct ieee_types_header),
le16_to_cpu(ext_cap->header.len));
+ if (hdr->len > 3 &&
+ ext_cap->ext_capab[3] & WLAN_EXT_CAPA4_INTERWORKING_ENABLED)
+ priv->hs2_enabled = true;
+ else
+ priv->hs2_enabled = false;
+
*buffer += sizeof(struct mwifiex_ie_types_extcap) + hdr->len;
ret_len += sizeof(struct mwifiex_ie_types_extcap) + hdr->len;
}
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index ca149ae..fbad00a 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1508,6 +1508,7 @@ mwifiex_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
" reason code %d\n", priv->cfg_bssid, reason_code);
memset(priv->cfg_bssid, 0, ETH_ALEN);
+ priv->hs2_enabled = false;
return 0;
}
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index a599347..5c85d78 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -26,6 +26,7 @@
#include <linux/wait.h>
#include <linux/timer.h>
#include <linux/ieee80211.h>
+#include <uapi/linux/if_arp.h>
#include <net/mac80211.h>
@@ -152,4 +153,12 @@ struct mwifiex_types_wmm_info {
u8 reserved;
struct ieee_types_wmm_ac_parameters ac_params[IEEE80211_NUM_ACS];
} __packed;
+
+struct mwifiex_arp_eth_header {
+ struct arphdr hdr;
+ u8 ar_sha[ETH_ALEN];
+ u8 ar_sip[4];
+ u8 ar_tha[ETH_ALEN];
+ u8 ar_tip[4];
+} __packed;
#endif /* !_MWIFIEX_DECL_H_ */
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index e021a58..6499117 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -136,6 +136,7 @@ int mwifiex_init_priv(struct mwifiex_private *priv)
priv->csa_chan = 0;
priv->csa_expire_time = 0;
priv->del_list_idx = 0;
+ priv->hs2_enabled = false;
return mwifiex_add_bss_prio_tbl(priv);
}
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index d2e5ccd..7d4d137 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -516,6 +516,7 @@ struct mwifiex_private {
u8 csa_chan;
unsigned long csa_expire_time;
u8 del_list_idx;
+ bool hs2_enabled;
};
enum mwifiex_ba_status {
diff --git a/drivers/net/wireless/mwifiex/sta_rx.c b/drivers/net/wireless/mwifiex/sta_rx.c
index b5c1095..bb22664 100644
--- a/drivers/net/wireless/mwifiex/sta_rx.c
+++ b/drivers/net/wireless/mwifiex/sta_rx.c
@@ -17,6 +17,8 @@
* this warranty disclaimer.
*/
+#include <uapi/linux/ipv6.h>
+#include <net/ndisc.h>
#include "decl.h"
#include "ioctl.h"
#include "util.h"
@@ -25,6 +27,46 @@
#include "11n_aggr.h"
#include "11n_rxreorder.h"
+/* This function checks if a frame is IPv4 ARP or IPv6 Neighbour advertisement
+ * frame. If frame has both source and destination mac address as same, this
+ * function drops such gratuitous frames.
+ */
+static bool
+mwifiex_discard_gratuitous_arp(struct mwifiex_private *priv,
+ struct sk_buff *skb)
+{
+ const struct mwifiex_arp_eth_header *arp;
+ struct ethhdr *eth_hdr;
+ struct ipv6hdr *ipv6;
+ struct icmp6hdr *icmpv6;
+
+ eth_hdr = (struct ethhdr *)skb->data;
+ switch (ntohs(eth_hdr->h_proto)) {
+ case ETH_P_ARP:
+ arp = (void *)(skb->data + sizeof(struct ethhdr));
+ if (arp->hdr.ar_op == htons(ARPOP_REPLY) ||
+ arp->hdr.ar_op == htons(ARPOP_REQUEST)) {
+ if (!memcmp(arp->ar_sip, arp->ar_tip, 4))
+ return true;
+ }
+ break;
+ case ETH_P_IPV6:
+ ipv6 = (void *)(skb->data + sizeof(struct ethhdr));
+ icmpv6 = (void *)(skb->data + sizeof(struct ethhdr) +
+ sizeof(struct ipv6hdr));
+ if (NDISC_NEIGHBOUR_ADVERTISEMENT == icmpv6->icmp6_type) {
+ if (!memcmp(&ipv6->saddr, &ipv6->daddr,
+ sizeof(struct in6_addr)))
+ return true;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return false;
+}
+
/*
* This function processes the received packet and forwards it
* to kernel/upper layer.
@@ -90,6 +132,13 @@ int mwifiex_process_rx_packet(struct mwifiex_private *priv,
either the reconstructed EthII frame or the 802.2/llc/snap frame */
skb_pull(skb, hdr_chop);
+ if (priv->hs2_enabled &&
+ mwifiex_discard_gratuitous_arp(priv, skb)) {
+ dev_dbg(priv->adapter->dev, "Bypassed Gratuitous ARP\n");
+ dev_kfree_skb_any(skb);
+ return 0;
+ }
+
priv->rxpd_rate = local_rx_pd->rx_rate;
priv->rxpd_htinfo = local_rx_pd->ht_info;
--
1.8.2.3
^ permalink raw reply related
* [PATCH 1/3] mwifiex: fix driver unload problem for usb chipsets
From: Bing Zhao @ 2013-08-23 23:48 UTC (permalink / raw)
To: linux-wireless
Cc: John W. Linville, Amitkumar Karwar, Avinash Patil,
Nishant Sarmukadam, Frank Huang, Bing Zhao
From: Amitkumar Karwar <akarwar@marvell.com>
We have usb_deregister() call in our rmmod routine. deauth,
shutdown etc. commands will be sent to FW later when bus
driver calls disconnect handler.
This mechanism works fine with SDIO and PCIe interfaces, but
there is an issue with USB.
USB bus driver returns all URBs submitted for receiving data
and command response immediately after usb_deregister() with
failure status. Hence we don't send deauth, shutdown etc.
command to firmware.
The problem is fixed by moving code from disconnect handler to
rmmod routine for USB interface.
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
drivers/net/wireless/mwifiex/usb.c | 50 +++++++++++++++++++-------------------
1 file changed, 25 insertions(+), 25 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c
index fca98b5..2472d4b 100644
--- a/drivers/net/wireless/mwifiex/usb.c
+++ b/drivers/net/wireless/mwifiex/usb.c
@@ -24,9 +24,9 @@
static const char usbdriver_name[] = "usb8797";
-static u8 user_rmmod;
static struct mwifiex_if_ops usb_ops;
static struct semaphore add_remove_card_sem;
+static struct usb_card_rec *usb_card;
static struct usb_device_id mwifiex_usb_table[] = {
{USB_DEVICE(USB8797_VID, USB8797_PID_1)},
@@ -350,6 +350,7 @@ static int mwifiex_usb_probe(struct usb_interface *intf,
card->udev = udev;
card->intf = intf;
+ usb_card = card;
pr_debug("info: bcdUSB=%#x Device Class=%#x SubClass=%#x Protocol=%#x\n",
udev->descriptor.bcdUSB, udev->descriptor.bDeviceClass,
@@ -532,7 +533,6 @@ static void mwifiex_usb_disconnect(struct usb_interface *intf)
{
struct usb_card_rec *card = usb_get_intfdata(intf);
struct mwifiex_adapter *adapter;
- int i;
if (!card || !card->adapter) {
pr_err("%s: card or card->adapter is NULL\n", __func__);
@@ -543,27 +543,6 @@ static void mwifiex_usb_disconnect(struct usb_interface *intf)
if (!adapter->priv_num)
return;
- /* In case driver is removed when asynchronous FW downloading is
- * in progress
- */
- wait_for_completion(&adapter->fw_load);
-
- if (user_rmmod) {
-#ifdef CONFIG_PM
- if (adapter->is_suspended)
- mwifiex_usb_resume(intf);
-#endif
- for (i = 0; i < adapter->priv_num; i++)
- if ((GET_BSS_ROLE(adapter->priv[i]) ==
- MWIFIEX_BSS_ROLE_STA) &&
- adapter->priv[i]->media_connected)
- mwifiex_deauthenticate(adapter->priv[i], NULL);
-
- mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter,
- MWIFIEX_BSS_ROLE_ANY),
- MWIFIEX_FUNC_SHUTDOWN);
- }
-
mwifiex_usb_free(card);
dev_dbg(adapter->dev, "%s: removing card\n", __func__);
@@ -1032,8 +1011,29 @@ static void mwifiex_usb_cleanup_module(void)
if (!down_interruptible(&add_remove_card_sem))
up(&add_remove_card_sem);
- /* set the flag as user is removing this module */
- user_rmmod = 1;
+ if (usb_card) {
+ struct mwifiex_adapter *adapter = usb_card->adapter;
+ int i;
+
+ /* In case driver is removed when asynchronous FW downloading is
+ * in progress
+ */
+ wait_for_completion(&adapter->fw_load);
+
+#ifdef CONFIG_PM
+ if (adapter->is_suspended)
+ mwifiex_usb_resume(usb_card->intf);
+#endif
+ for (i = 0; i < adapter->priv_num; i++)
+ if ((GET_BSS_ROLE(adapter->priv[i]) ==
+ MWIFIEX_BSS_ROLE_STA) &&
+ adapter->priv[i]->media_connected)
+ mwifiex_deauthenticate(adapter->priv[i], NULL);
+
+ mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter,
+ MWIFIEX_BSS_ROLE_ANY),
+ MWIFIEX_FUNC_SHUTDOWN);
+ }
usb_deregister(&mwifiex_usb_driver);
}
--
1.8.2.3
^ permalink raw reply related
* [PATCH 2/3] mwifiex: fix ext_capab IE structure definition
From: Bing Zhao @ 2013-08-23 23:48 UTC (permalink / raw)
To: linux-wireless
Cc: John W. Linville, Amitkumar Karwar, Avinash Patil,
Nishant Sarmukadam, Frank Huang, Bing Zhao
In-Reply-To: <1377301703-8853-1-git-send-email-bzhao@marvell.com>
From: Avinash Patil <patila@marvell.com>
EXT_CAPAB_IE format involves IEEE header followed by bytestream of
capabilities. Current structure has incorrect member u8 for data;
fix it by defining it as u8[0].
Signed-off-by: Avinash Patil <patila@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
drivers/net/wireless/mwifiex/11n.c | 10 ++++++----
drivers/net/wireless/mwifiex/fw.h | 2 +-
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c
index 41e9d25..b579a2e 100644
--- a/drivers/net/wireless/mwifiex/11n.c
+++ b/drivers/net/wireless/mwifiex/11n.c
@@ -292,6 +292,7 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv,
struct mwifiex_ie_types_extcap *ext_cap;
int ret_len = 0;
struct ieee80211_supported_band *sband;
+ struct ieee_types_header *hdr;
u8 radio_type;
if (!buffer || !*buffer)
@@ -388,17 +389,18 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv,
}
if (bss_desc->bcn_ext_cap) {
+ hdr = (void *)bss_desc->bcn_ext_cap;
ext_cap = (struct mwifiex_ie_types_extcap *) *buffer;
memset(ext_cap, 0, sizeof(struct mwifiex_ie_types_extcap));
ext_cap->header.type = cpu_to_le16(WLAN_EID_EXT_CAPABILITY);
- ext_cap->header.len = cpu_to_le16(sizeof(ext_cap->ext_cap));
+ ext_cap->header.len = cpu_to_le16(hdr->len);
- memcpy((u8 *)ext_cap + sizeof(struct mwifiex_ie_types_header),
+ memcpy((u8 *)ext_cap->ext_capab,
bss_desc->bcn_ext_cap + sizeof(struct ieee_types_header),
le16_to_cpu(ext_cap->header.len));
- *buffer += sizeof(struct mwifiex_ie_types_extcap);
- ret_len += sizeof(struct mwifiex_ie_types_extcap);
+ *buffer += sizeof(struct mwifiex_ie_types_extcap) + hdr->len;
+ ret_len += sizeof(struct mwifiex_ie_types_extcap) + hdr->len;
}
return ret_len;
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index c9ad1c0..f80f30b 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -1330,7 +1330,7 @@ struct mwifiex_ie_types_2040bssco {
struct mwifiex_ie_types_extcap {
struct mwifiex_ie_types_header header;
- u8 ext_cap;
+ u8 ext_capab[0];
} __packed;
struct host_cmd_ds_mac_reg_access {
--
1.8.2.3
^ permalink raw reply related
* Re: [PATCH v2 13/16] wcn36xx: add wcn36xx.h
From: Joe Perches @ 2013-08-23 23:02 UTC (permalink / raw)
To: Eugene Krasnikov; +Cc: linux-wireless, wcn36xx
In-Reply-To: <1377248299-21007-14-git-send-email-k.eugene.e@gmail.com>
On Fri, 2013-08-23 at 10:58 +0200, Eugene Krasnikov wrote:
> Adding wcn36xx.h
[]
> +#define wcn36xx_err(fmt, arg...) \
> + printk(KERN_ERR pr_fmt("ERROR " fmt), ##arg);
> +
> +#define wcn36xx_warn(fmt, arg...) \
> + printk(KERN_WARNING pr_fmt("WARNING " fmt), ##arg)
> +
> +#define wcn36xx_info(fmt, arg...) \
> + printk(KERN_INFO pr_fmt(fmt), ##arg)
> +
I these would be better using:
#define wcn36xx_err(fmt, ...) \
pr_err("ERROR " fmt, ##__VA_ARGS__)
etc...
> +#define wcn36xx_dbg(mask, fmt, arg...) do { \
> + if (debug_mask & mask) \
> + printk(KERN_DEBUG pr_fmt(fmt), ##arg); \
> +} while (0)
And maybe this one using pr_debug so dynamic_debug
can work too.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox