From 5e071b5d1aa6928f8d695c15f52a949d70b8d7fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Wed, 23 May 2012 23:19:32 +0000 Subject: net: qmi_wwan: Add Sierra Wireless device IDs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some additional Gobi3K IDs found in the BSD/GPL licensed out-of-tree GobiNet driver from Sierra Wireless. Signed-off-by: Bjørn Mork Signed-off-by: David S. Miller --- drivers/net/usb/qmi_wwan.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 380dbea..3b20678 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -547,6 +547,8 @@ static const struct usb_device_id products[] = { {QMI_GOBI_DEVICE(0x16d8, 0x8002)}, /* CMDTech Gobi 2000 Modem device (VU922) */ {QMI_GOBI_DEVICE(0x05c6, 0x9205)}, /* Gobi 2000 Modem device */ {QMI_GOBI_DEVICE(0x1199, 0x9013)}, /* Sierra Wireless Gobi 3000 Modem device (MC8355) */ + {QMI_GOBI_DEVICE(0x1199, 0x9015)}, /* Sierra Wireless Gobi 3000 Modem device */ + {QMI_GOBI_DEVICE(0x1199, 0x9019)}, /* Sierra Wireless Gobi 3000 Modem device */ { } /* END */ }; MODULE_DEVICE_TABLE(usb, products); -- cgit v1.1 From e26b203ede31fffd52571a5ba607a26c79dc5c0d Mon Sep 17 00:00:00 2001 From: Simon Graham Date: Thu, 24 May 2012 06:26:07 +0000 Subject: xen/netback: Calculate the number of SKB slots required correctly When calculating the number of slots required for a packet header, the code was reserving too many slots if the header crossed a page boundary. Since netbk_gop_skb copies the header to the start of the page, the count of slots required for the header should be based solely on the header size. This problem is easy to reproduce if a VIF is bridged to a USB 3G modem device as the skb->data value always starts near the end of the first page. Signed-off-by: Simon Graham Signed-off-by: David S. Miller --- drivers/net/xen-netback/netback.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index 2596401..f4a6fca 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c @@ -325,8 +325,7 @@ unsigned int xen_netbk_count_skb_slots(struct xenvif *vif, struct sk_buff *skb) unsigned int count; int i, copy_off; - count = DIV_ROUND_UP( - offset_in_page(skb->data)+skb_headlen(skb), PAGE_SIZE); + count = DIV_ROUND_UP(skb_headlen(skb), PAGE_SIZE); copy_off = skb_headlen(skb) % PAGE_SIZE; -- cgit v1.1 From 882dde8eb0d49ce0f853f8f4084dde56a21fe55f Mon Sep 17 00:00:00 2001 From: Meenakshi Venkataraman Date: Wed, 16 May 2012 22:35:57 +0200 Subject: iwlwifi: update BT traffic load states correctly When BT traffic load changes from its previous state, a new LQ command needs to be sent down to the firmware. This needs to be done only once per change. The state variable that keeps track of this change is last_bt_traffic_load. However, it was not being updated when the change had been handled. Not updating this variable was causing a flood of advanced BT config commands to be sent to the firmware. Fix this. Cc: stable@vger.kernel.org #2.6.38+ Signed-off-by: Meenakshi Venkataraman Signed-off-by: Wey-Yi Guy Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 51e1a69..8cebd7c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -884,6 +884,7 @@ static void rs_bt_update_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, if ((priv->bt_traffic_load != priv->last_bt_traffic_load) || (priv->bt_full_concurrent != full_concurrent)) { priv->bt_full_concurrent = full_concurrent; + priv->last_bt_traffic_load = priv->bt_traffic_load; /* Update uCode's rate table. */ tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); -- cgit v1.1 From ebed633c61c023e5d1aa4ed159cd67406e9e37c2 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 16 May 2012 22:35:58 +0200 Subject: iwlwifi: fix the Transmit Frame Descriptor rings The logic that allows to have a short TFD queue was completely wrong. We do maintain 256 Transmit Frame Descriptors, but they point to recycled buffers. We used to attach and de-attach different TFDs for the same buffer and it worked since they pointed to the same buffer. Also zero the number of BDs after unmapping a TFD. This seems not necessary since we don't reclaim the same TFD twice, but I like housekeeping. This patch solves this warning: [ 6427.079855] WARNING: at lib/dma-debug.c:866 check_unmap+0x727/0x7a0() [ 6427.079859] Hardware name: Latitude E6410 [ 6427.079865] iwlwifi 0000:02:00.0: DMA-API: device driver tries to free DMA memory it has not allocated [device address=0x00000000296d393c] [size=8 bytes] [ 6427.079870] Modules linked in: ... [ 6427.079950] Pid: 6613, comm: ifconfig Tainted: G O 3.3.3 #5 [ 6427.079954] Call Trace: [ 6427.079963] [] warn_slowpath_common+0x72/0xa0 [ 6427.079982] [] warn_slowpath_fmt+0x33/0x40 [ 6427.079988] [] check_unmap+0x727/0x7a0 [ 6427.079995] [] debug_dma_unmap_page+0x5a/0x80 [ 6427.080024] [] iwlagn_unmap_tfd+0x12c/0x180 [iwlwifi] [ 6427.080048] [] iwlagn_txq_free_tfd+0x49/0xb0 [iwlwifi] [ 6427.080071] [] iwl_tx_queue_unmap+0x67/0x90 [iwlwifi] [ 6427.080095] [] iwl_trans_pcie_stop_device+0x341/0x7b0 [iwlwifi] [ 6427.080113] [] iwl_down+0x17e/0x260 [iwlwifi] [ 6427.080132] [] iwlagn_mac_stop+0x6c/0xf0 [iwlwifi] [ 6427.080168] [] ieee80211_stop_device+0x5e/0x190 [mac80211] [ 6427.080198] [] ieee80211_do_stop+0x288/0x620 [mac80211] [ 6427.080243] [] ieee80211_stop+0x17/0x20 [mac80211] [ 6427.080250] [] __dev_close_many+0x81/0xd0 [ 6427.080270] [] __dev_close+0x2d/0x50 [ 6427.080276] [] __dev_change_flags+0x82/0x150 [ 6427.080282] [] dev_change_flags+0x23/0x60 [ 6427.080289] [] devinet_ioctl+0x6a0/0x770 [ 6427.080296] [] inet_ioctl+0x95/0xb0 [ 6427.080304] [] sock_ioctl+0x70/0x270 Cc: stable@vger.kernel.org Reported-by: Antonio Quartulli Tested-by: Antonio Quartulli Signed-off-by: Emmanuel Grumbach Reviewed-by: Wey-Yi W Guy Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | 2 +- drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | 22 ++++++++++++++-------- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 4 +--- 3 files changed, 16 insertions(+), 12 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index 6213c05..e959207 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h @@ -347,7 +347,7 @@ void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, int queue, int fifo, int sta_id, int tid, int frame_limit, u16 ssn); void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, - int index, enum dma_data_direction dma_dir); + enum dma_data_direction dma_dir); int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, struct sk_buff_head *skbs); int iwl_queue_space(const struct iwl_queue *q); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index 21a8a67..a875023 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c @@ -204,33 +204,39 @@ static void iwlagn_unmap_tfd(struct iwl_trans *trans, struct iwl_cmd_meta *meta, for (i = 1; i < num_tbs; i++) dma_unmap_single(trans->dev, iwl_tfd_tb_get_addr(tfd, i), iwl_tfd_tb_get_len(tfd, i), dma_dir); + + tfd->num_tbs = 0; } /** * iwlagn_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] * @trans - transport private data * @txq - tx queue - * @index - the index of the TFD to be freed - *@dma_dir - the direction of the DMA mapping + * @dma_dir - the direction of the DMA mapping * * Does NOT advance any TFD circular buffer read/write indexes * Does NOT free the TFD itself (which is within circular buffer) */ void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, - int index, enum dma_data_direction dma_dir) + enum dma_data_direction dma_dir) { struct iwl_tfd *tfd_tmp = txq->tfds; + /* rd_ptr is bounded by n_bd and idx is bounded by n_window */ + int rd_ptr = txq->q.read_ptr; + int idx = get_cmd_index(&txq->q, rd_ptr); + lockdep_assert_held(&txq->lock); - iwlagn_unmap_tfd(trans, &txq->entries[index].meta, - &tfd_tmp[index], dma_dir); + /* We have only q->n_window txq->entries, but we use q->n_bd tfds */ + iwlagn_unmap_tfd(trans, &txq->entries[idx].meta, + &tfd_tmp[rd_ptr], dma_dir); /* free SKB */ if (txq->entries) { struct sk_buff *skb; - skb = txq->entries[index].skb; + skb = txq->entries[idx].skb; /* Can be called from irqs-disabled context * If skb is not NULL, it means that the whole queue is being @@ -238,7 +244,7 @@ void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, */ if (skb) { iwl_op_mode_free_skb(trans->op_mode, skb); - txq->entries[index].skb = NULL; + txq->entries[idx].skb = NULL; } } } @@ -973,7 +979,7 @@ int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, iwlagn_txq_inval_byte_cnt_tbl(trans, txq); - iwlagn_txq_free_tfd(trans, txq, txq->q.read_ptr, DMA_TO_DEVICE); + iwlagn_txq_free_tfd(trans, txq, DMA_TO_DEVICE); freed++; } diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 2e57161..ec6fb39 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -435,9 +435,7 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id) spin_lock_bh(&txq->lock); while (q->write_ptr != q->read_ptr) { - /* The read_ptr needs to bound by q->n_window */ - iwlagn_txq_free_tfd(trans, txq, get_cmd_index(q, q->read_ptr), - dma_dir); + iwlagn_txq_free_tfd(trans, txq, dma_dir); q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); } spin_unlock_bh(&txq->lock); -- cgit v1.1 From 66a770729a5cdd24efed8afa5258f81232d8bba2 Mon Sep 17 00:00:00 2001 From: Meenakshi Venkataraman Date: Wed, 16 May 2012 22:35:59 +0200 Subject: iwlwifi: do not use shadow registers by default Shadow registers in the device are meant to allow the driver to update certain device registers without needing to wake up all components of the device. However, using this feature in the device causes communication between the driver and the device to become unreliable, resulting in host command timeouts. Disable this feature by default till a fix is available for the bug. Cc: stable@vger.kernel.org #2.6.38+ Signed-off-by: Meenakshi Venkataraman Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-2000.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-6000.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 7f79341..8133105 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -79,7 +79,7 @@ static const struct iwl_base_params iwl2000_base_params = { .chain_noise_scale = 1000, .wd_timeout = IWL_DEF_WD_TIMEOUT, .max_event_log_size = 512, - .shadow_reg_enable = true, + .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ .hd_v2 = true, }; @@ -97,7 +97,7 @@ static const struct iwl_base_params iwl2030_base_params = { .chain_noise_scale = 1000, .wd_timeout = IWL_LONG_WD_TIMEOUT, .max_event_log_size = 512, - .shadow_reg_enable = true, + .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ .hd_v2 = true, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 381b02c..19f7ee8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -86,7 +86,7 @@ static const struct iwl_base_params iwl6000_base_params = { .chain_noise_scale = 1000, .wd_timeout = IWL_DEF_WD_TIMEOUT, .max_event_log_size = 512, - .shadow_reg_enable = true, + .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ }; static const struct iwl_base_params iwl6050_base_params = { @@ -102,7 +102,7 @@ static const struct iwl_base_params iwl6050_base_params = { .chain_noise_scale = 1500, .wd_timeout = IWL_DEF_WD_TIMEOUT, .max_event_log_size = 1024, - .shadow_reg_enable = true, + .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ }; static const struct iwl_base_params iwl6000_g2_base_params = { @@ -118,7 +118,7 @@ static const struct iwl_base_params iwl6000_g2_base_params = { .chain_noise_scale = 1000, .wd_timeout = IWL_LONG_WD_TIMEOUT, .max_event_log_size = 512, - .shadow_reg_enable = true, + .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ }; static const struct iwl_ht_params iwl6000_ht_params = { -- cgit v1.1 From a7b2ad55caecfa089f0e89202ba368fc2de41794 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 16 May 2012 22:49:47 +0200 Subject: iwlwifi: remove ucode16 option The ucode16 option is still very much work in progress, so there's no need to ask any users about it. Remove the option and code for now, we'll put it back when it's actually working. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/Kconfig | 8 - drivers/net/wireless/iwlwifi/Makefile | 1 - drivers/net/wireless/iwlwifi/iwl-phy-db.c | 288 ------------------------------ drivers/net/wireless/iwlwifi/iwl-phy-db.h | 129 ------------- 4 files changed, 426 deletions(-) delete mode 100644 drivers/net/wireless/iwlwifi/iwl-phy-db.c delete mode 100644 drivers/net/wireless/iwlwifi/iwl-phy-db.h (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index db6c6e5..2463c06 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig @@ -137,11 +137,3 @@ config IWLWIFI_EXPERIMENTAL_MFP even if the microcode doesn't advertise it. Say Y only if you want to experiment with MFP. - -config IWLWIFI_UCODE16 - bool "support uCode 16.0" - depends on IWLWIFI - help - This option enables support for uCode version 16.0. - - Say Y if you want to use 16.0 microcode. diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 406f297..d615eac 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -18,7 +18,6 @@ iwlwifi-objs += iwl-notif-wait.o iwlwifi-objs += iwl-trans-pcie.o iwl-trans-pcie-rx.o iwl-trans-pcie-tx.o -iwlwifi-$(CONFIG_IWLWIFI_UCODE16) += iwl-phy-db.o iwlwifi-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += iwl-testmode.o diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.c b/drivers/net/wireless/iwlwifi/iwl-phy-db.c deleted file mode 100644 index f166955..0000000 --- a/drivers/net/wireless/iwlwifi/iwl-phy-db.c +++ /dev/null @@ -1,288 +0,0 @@ -/****************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - * BSD LICENSE - * - * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - *****************************************************************************/ - -#include -#include - -#include "iwl-debug.h" -#include "iwl-dev.h" - -#include "iwl-phy-db.h" - -#define CHANNEL_NUM_SIZE 4 /* num of channels in calib_ch size */ - -struct iwl_phy_db *iwl_phy_db_init(struct device *dev) -{ - struct iwl_phy_db *phy_db = kzalloc(sizeof(struct iwl_phy_db), - GFP_KERNEL); - - if (!phy_db) - return phy_db; - - phy_db->dev = dev; - - /* TODO: add default values of the phy db. */ - return phy_db; -} - -/* - * get phy db section: returns a pointer to a phy db section specified by - * type and channel group id. - */ -static struct iwl_phy_db_entry * -iwl_phy_db_get_section(struct iwl_phy_db *phy_db, - enum iwl_phy_db_section_type type, - u16 chg_id) -{ - if (!phy_db || type < 0 || type >= IWL_PHY_DB_MAX) - return NULL; - - switch (type) { - case IWL_PHY_DB_CFG: - return &phy_db->cfg; - case IWL_PHY_DB_CALIB_NCH: - return &phy_db->calib_nch; - case IWL_PHY_DB_CALIB_CH: - return &phy_db->calib_ch; - case IWL_PHY_DB_CALIB_CHG_PAPD: - if (chg_id < 0 || chg_id >= IWL_NUM_PAPD_CH_GROUPS) - return NULL; - return &phy_db->calib_ch_group_papd[chg_id]; - case IWL_PHY_DB_CALIB_CHG_TXP: - if (chg_id < 0 || chg_id >= IWL_NUM_TXP_CH_GROUPS) - return NULL; - return &phy_db->calib_ch_group_txp[chg_id]; - default: - return NULL; - } - return NULL; -} - -static void iwl_phy_db_free_section(struct iwl_phy_db *phy_db, - enum iwl_phy_db_section_type type, - u16 chg_id) -{ - struct iwl_phy_db_entry *entry = - iwl_phy_db_get_section(phy_db, type, chg_id); - if (!entry) - return; - - kfree(entry->data); - entry->data = NULL; - entry->size = 0; -} - -void iwl_phy_db_free(struct iwl_phy_db *phy_db) -{ - int i; - - if (!phy_db) - return; - - iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CFG, 0); - iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CALIB_NCH, 0); - iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CALIB_CH, 0); - for (i = 0; i < IWL_NUM_PAPD_CH_GROUPS; i++) - iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CALIB_CHG_PAPD, i); - for (i = 0; i < IWL_NUM_TXP_CH_GROUPS; i++) - iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CALIB_CHG_TXP, i); - - kfree(phy_db); -} - -int iwl_phy_db_set_section(struct iwl_phy_db *phy_db, - enum iwl_phy_db_section_type type, u8 *data, - u16 size, gfp_t alloc_ctx) -{ - struct iwl_phy_db_entry *entry; - u16 chg_id = 0; - - if (!phy_db) - return -EINVAL; - - if (type == IWL_PHY_DB_CALIB_CHG_PAPD || - type == IWL_PHY_DB_CALIB_CHG_TXP) - chg_id = le16_to_cpup((__le16 *)data); - - entry = iwl_phy_db_get_section(phy_db, type, chg_id); - if (!entry) - return -EINVAL; - - kfree(entry->data); - entry->data = kmemdup(data, size, alloc_ctx); - if (!entry->data) { - entry->size = 0; - return -ENOMEM; - } - - entry->size = size; - - if (type == IWL_PHY_DB_CALIB_CH) { - phy_db->channel_num = le32_to_cpup((__le32 *)data); - phy_db->channel_size = - (size - CHANNEL_NUM_SIZE) / phy_db->channel_num; - } - - return 0; -} - -static int is_valid_channel(u16 ch_id) -{ - if (ch_id <= 14 || - (36 <= ch_id && ch_id <= 64 && ch_id % 4 == 0) || - (100 <= ch_id && ch_id <= 140 && ch_id % 4 == 0) || - (145 <= ch_id && ch_id <= 165 && ch_id % 4 == 1)) - return 1; - return 0; -} - -static u8 ch_id_to_ch_index(u16 ch_id) -{ - if (WARN_ON(!is_valid_channel(ch_id))) - return 0xff; - - if (ch_id <= 14) - return ch_id - 1; - if (ch_id <= 64) - return (ch_id + 20) / 4; - if (ch_id <= 140) - return (ch_id - 12) / 4; - return (ch_id - 13) / 4; -} - - -static u16 channel_id_to_papd(u16 ch_id) -{ - if (WARN_ON(!is_valid_channel(ch_id))) - return 0xff; - - if (1 <= ch_id && ch_id <= 14) - return 0; - if (36 <= ch_id && ch_id <= 64) - return 1; - if (100 <= ch_id && ch_id <= 140) - return 2; - return 3; -} - -static u16 channel_id_to_txp(struct iwl_phy_db *phy_db, u16 ch_id) -{ - struct iwl_phy_db_chg_txp *txp_chg; - int i; - u8 ch_index = ch_id_to_ch_index(ch_id); - if (ch_index == 0xff) - return 0xff; - - for (i = 0; i < IWL_NUM_TXP_CH_GROUPS; i++) { - txp_chg = (void *)phy_db->calib_ch_group_txp[i].data; - if (!txp_chg) - return 0xff; - /* - * Looking for the first channel group that its max channel is - * higher then wanted channel. - */ - if (le16_to_cpu(txp_chg->max_channel_idx) >= ch_index) - return i; - } - return 0xff; -} - -int iwl_phy_db_get_section_data(struct iwl_phy_db *phy_db, - enum iwl_phy_db_section_type type, u8 **data, - u16 *size, u16 ch_id) -{ - struct iwl_phy_db_entry *entry; - u32 channel_num; - u32 channel_size; - u16 ch_group_id = 0; - u16 index; - - if (!phy_db) - return -EINVAL; - - /* find wanted channel group */ - if (type == IWL_PHY_DB_CALIB_CHG_PAPD) - ch_group_id = channel_id_to_papd(ch_id); - else if (type == IWL_PHY_DB_CALIB_CHG_TXP) - ch_group_id = channel_id_to_txp(phy_db, ch_id); - - entry = iwl_phy_db_get_section(phy_db, type, ch_group_id); - if (!entry) - return -EINVAL; - - if (type == IWL_PHY_DB_CALIB_CH) { - index = ch_id_to_ch_index(ch_id); - channel_num = phy_db->channel_num; - channel_size = phy_db->channel_size; - if (index >= channel_num) { - IWL_ERR(phy_db, "Wrong channel number %d", ch_id); - return -EINVAL; - } - *data = entry->data + CHANNEL_NUM_SIZE + index * channel_size; - *size = channel_size; - } else { - *data = entry->data; - *size = entry->size; - } - return 0; -} diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.h b/drivers/net/wireless/iwlwifi/iwl-phy-db.h deleted file mode 100644 index c34c6a9..0000000 --- a/drivers/net/wireless/iwlwifi/iwl-phy-db.h +++ /dev/null @@ -1,129 +0,0 @@ -/****************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - * BSD LICENSE - * - * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - *****************************************************************************/ - -#ifndef __IWL_PHYDB_H__ -#define __IWL_PHYDB_H__ - -#include - -#define IWL_NUM_PAPD_CH_GROUPS 4 -#define IWL_NUM_TXP_CH_GROUPS 8 - -struct iwl_phy_db_entry { - u16 size; - u8 *data; -}; - -struct iwl_shared; - -/** - * struct iwl_phy_db - stores phy configuration and calibration data. - * - * @cfg: phy configuration. - * @calib_nch: non channel specific calibration data. - * @calib_ch: channel specific calibration data. - * @calib_ch_group_papd: calibration data related to papd channel group. - * @calib_ch_group_txp: calibration data related to tx power chanel group. - */ -struct iwl_phy_db { - struct iwl_phy_db_entry cfg; - struct iwl_phy_db_entry calib_nch; - struct iwl_phy_db_entry calib_ch; - struct iwl_phy_db_entry calib_ch_group_papd[IWL_NUM_PAPD_CH_GROUPS]; - struct iwl_phy_db_entry calib_ch_group_txp[IWL_NUM_TXP_CH_GROUPS]; - - u32 channel_num; - u32 channel_size; - - /* for an access to the logger */ - struct device *dev; -}; - -enum iwl_phy_db_section_type { - IWL_PHY_DB_CFG = 1, - IWL_PHY_DB_CALIB_NCH, - IWL_PHY_DB_CALIB_CH, - IWL_PHY_DB_CALIB_CHG_PAPD, - IWL_PHY_DB_CALIB_CHG_TXP, - IWL_PHY_DB_MAX -}; - -/* for parsing of tx power channel group data that comes from the firmware*/ -struct iwl_phy_db_chg_txp { - __le32 space; - __le16 max_channel_idx; -} __packed; - -struct iwl_phy_db *iwl_phy_db_init(struct device *dev); - -void iwl_phy_db_free(struct iwl_phy_db *phy_db); - -int iwl_phy_db_set_section(struct iwl_phy_db *phy_db, - enum iwl_phy_db_section_type type, u8 *data, - u16 size, gfp_t alloc_ctx); - -int iwl_phy_db_get_section_data(struct iwl_phy_db *phy_db, - enum iwl_phy_db_section_type type, u8 **data, - u16 *size, u16 ch_id); - -#endif /* __IWL_PHYDB_H__ */ -- cgit v1.1 From f4c37176ef555560a1d13bc4bf2cf3debd442f40 Mon Sep 17 00:00:00 2001 From: Meenakshi Venkataraman Date: Wed, 16 May 2012 22:49:48 +0200 Subject: iwlwifi: do not send lq cmd when station add fails When adding a station fails in iwl_restore_stations, the driver treats it like a successful station add and sends a link quality command, when it it shouldn't. This patch fixes one of the potential sources for kernel warnings like this one: WARNING: at drivers/net/wireless/iwlwifi/iwl-agn-sta.c:905 iwl_send_lq_cmd+0x130/0x217 [iwlwifi]() Hardware name: 3323A2G Modules linked in: ... Pid: 17359, comm: kworker/u:2 Tainted: G O 3.3.0-wl+ #1 Call Trace: [] warn_slowpath_common+0x7e/0x96 [] warn_slowpath_null+0x15/0x17 [] iwl_send_lq_cmd+0x130/0x217 [iwlwifi] [] iwl_restore_stations+0x209/0x289 [iwlwifi] [] iwlagn_commit_rxon+0x602/0x7bd [iwlwifi] [] iwlagn_bss_info_changed+0x247/0x31a [iwlwifi] [] ieee80211_bss_info_change_notify+0x1a5/0x1ba [mac80211] [] ieee80211_destroy_auth_data+0x4b/0x70 [mac80211] [] ieee80211_sta_work+0xb5/0x954 [mac80211] Signed-off-by: Meenakshi Venkataraman Reviewed-by: Wey-Yi W Guy Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-sta.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index b31584e..aea07aa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -772,7 +772,7 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) ~IWL_STA_DRIVER_ACTIVE; priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS; - spin_unlock_bh(&priv->sta_lock); + continue; } /* * Rate scaling has already been initialized, send -- cgit v1.1 From 75813bde1f671aaab3185a9438da7730d356cea6 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 16 May 2012 22:49:49 +0200 Subject: iwlwifi: fix memory leak if opmode fails to init If drv->op_mode is NULL after trying to init the opmode, we go to the wrong label. Fix this, and clean up the code a bit. Reviewed-by: Gregory Greenman Reviewed-by: Guy Cohen Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-drv.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 3c72bad..d742900 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -657,17 +657,17 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, return -EINVAL; } -static int alloc_pci_desc(struct iwl_drv *drv, - struct iwl_firmware_pieces *pieces, - enum iwl_ucode_type type) +static int iwl_alloc_ucode(struct iwl_drv *drv, + struct iwl_firmware_pieces *pieces, + enum iwl_ucode_type type) { int i; for (i = 0; i < IWL_UCODE_SECTION_MAX && get_sec_size(pieces, type, i); i++) if (iwl_alloc_fw_desc(drv, &(drv->fw.img[type].sec[i]), - get_sec(pieces, type, i))) - return -1; + get_sec(pieces, type, i))) + return -ENOMEM; return 0; } @@ -825,8 +825,8 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) * 1) unmodified from disk * 2) backup cache for save/restore during power-downs */ for (i = 0; i < IWL_UCODE_TYPE_MAX; i++) - if (alloc_pci_desc(drv, &pieces, i)) - goto err_pci_alloc; + if (iwl_alloc_ucode(drv, &pieces, i)) + goto out_free_fw; /* Now that we can no longer fail, copy information */ @@ -866,7 +866,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) drv->op_mode = iwl_dvm_ops.start(drv->trans, drv->cfg, &drv->fw); if (!drv->op_mode) - goto out_unbind; + goto out_free_fw; return; @@ -877,7 +877,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) goto out_unbind; return; - err_pci_alloc: + out_free_fw: IWL_ERR(drv, "failed to allocate pci memory\n"); iwl_dealloc_ucode(drv); release_firmware(ucode_raw); -- cgit v1.1 From f380f2c4a12e913356bd49f8790ec1063c4fe9f8 Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Fri, 18 May 2012 03:04:08 +0300 Subject: wl1251: fix oops on early interrupt This driver disables interrupt just after requesting it and enables it later, after interface is up. However currently there is a time window between request_irq() and disable_irq() where if interrupt arrives, the driver oopses because it's not yet ready to process it. This can be reproduced by inserting the module, associating and removing the module multiple times. Eliminate this race by setting IRQF_NOAUTOEN flag before request_irq(). Cc: stable@vger.kernel.org # v2.6.37+ Signed-off-by: Grazvydas Ignotas Signed-off-by: John W. Linville --- drivers/net/wireless/ti/wl1251/sdio.c | 2 +- drivers/net/wireless/ti/wl1251/spi.c | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ti/wl1251/sdio.c b/drivers/net/wireless/ti/wl1251/sdio.c index 1b851f6..e2750a1 100644 --- a/drivers/net/wireless/ti/wl1251/sdio.c +++ b/drivers/net/wireless/ti/wl1251/sdio.c @@ -260,6 +260,7 @@ static int wl1251_sdio_probe(struct sdio_func *func, } if (wl->irq) { + irq_set_status_flags(wl->irq, IRQ_NOAUTOEN); ret = request_irq(wl->irq, wl1251_line_irq, 0, "wl1251", wl); if (ret < 0) { wl1251_error("request_irq() failed: %d", ret); @@ -267,7 +268,6 @@ static int wl1251_sdio_probe(struct sdio_func *func, } irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); - disable_irq(wl->irq); wl1251_sdio_ops.enable_irq = wl1251_enable_line_irq; wl1251_sdio_ops.disable_irq = wl1251_disable_line_irq; diff --git a/drivers/net/wireless/ti/wl1251/spi.c b/drivers/net/wireless/ti/wl1251/spi.c index 6248c35..87f6305 100644 --- a/drivers/net/wireless/ti/wl1251/spi.c +++ b/drivers/net/wireless/ti/wl1251/spi.c @@ -281,6 +281,7 @@ static int __devinit wl1251_spi_probe(struct spi_device *spi) wl->use_eeprom = pdata->use_eeprom; + irq_set_status_flags(wl->irq, IRQ_NOAUTOEN); ret = request_irq(wl->irq, wl1251_irq, 0, DRIVER_NAME, wl); if (ret < 0) { wl1251_error("request_irq() failed: %d", ret); @@ -289,8 +290,6 @@ static int __devinit wl1251_spi_probe(struct spi_device *spi) irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); - disable_irq(wl->irq); - ret = wl1251_init_ieee80211(wl); if (ret) goto out_irq; -- cgit v1.1 From edb9bc9a1e08f54adfdb4f4d31bca5a15aeb8ef0 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Fri, 18 May 2012 20:22:53 +0200 Subject: brcmfmac: use vmalloc to allocate mem for the firmware The firmware is more than 300KB big and you should not use kmalloc for such big allocations. This allocation with kmalloc failed on my mips based device (BCM47186). Signed-off-by: Hauke Mehrtens Acked-by: Franky Lin Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/usb.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index 1d67ecf..3e35247 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -1239,7 +1240,7 @@ static int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo) return -EINVAL; } - devinfo->image = kmalloc(fw->size, GFP_ATOMIC); /* plus nvram */ + devinfo->image = vmalloc(fw->size); /* plus nvram */ if (!devinfo->image) return -ENOMEM; @@ -1602,7 +1603,7 @@ static struct usb_driver brcmf_usbdrvr = { void brcmf_usb_exit(void) { usb_deregister(&brcmf_usbdrvr); - kfree(g_image.data); + vfree(g_image.data); g_image.data = NULL; g_image.len = 0; } -- cgit v1.1 From 9b4760e301e1cceb0b49bd2b921d6b394d364584 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 17 Apr 2012 00:39:27 -0400 Subject: ath5k: add possible wiphy interface combinations Signed-off-by: Felix Fietkau --- drivers/net/wireless/ath/ath5k/base.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 0ba81a6..fbaa309 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -2415,6 +2415,22 @@ ath5k_tx_complete_poll_work(struct work_struct *work) * Initialization routines * \*************************/ +static const struct ieee80211_iface_limit if_limits[] = { + { .max = 2048, .types = BIT(NL80211_IFTYPE_STATION) }, + { .max = 4, .types = +#ifdef CONFIG_MAC80211_MESH + BIT(NL80211_IFTYPE_MESH_POINT) | +#endif + BIT(NL80211_IFTYPE_AP) }, +}; + +static const struct ieee80211_iface_combination if_comb = { + .limits = if_limits, + .n_limits = ARRAY_SIZE(if_limits), + .max_interfaces = 2048, + .num_different_channels = 1, +}; + int __devinit ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops) { @@ -2436,6 +2452,9 @@ ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops) BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_MESH_POINT); + hw->wiphy->iface_combinations = &if_comb; + hw->wiphy->n_iface_combinations = 1; + /* SW support for IBSS_RSN is provided by mac80211 */ hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; -- cgit v1.1 From ceea2a51969f8b578777c99ec2718021427770c3 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 24 May 2012 14:32:19 +0200 Subject: ath9k: stop rx dma before stopping tx It has been found that active Rx can interfere with stopping tx DMA, which could result in at least parts of those "Failed to stop Tx DMA!" messages. Stopping rx before tx should prevent that. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index dfa78e8..4de4473 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -239,7 +239,7 @@ static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush) { struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); - bool ret; + bool ret = true; ieee80211_stop_queues(sc->hw); @@ -250,11 +250,12 @@ static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush) ath9k_debug_samp_bb_mac(sc); ath9k_hw_disable_interrupts(ah); - ret = ath_drain_all_txq(sc, retry_tx); - if (!ath_stoprecv(sc)) ret = false; + if (!ath_drain_all_txq(sc, retry_tx)) + ret = false; + if (!flush) { if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) ath_rx_tasklet(sc, 1, true); -- cgit v1.1 From 81357a281dcc454841532c46b30e6f2ba12b73ea Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 24 May 2012 14:32:20 +0200 Subject: ath9k: fix a use-after-free-bug when ath_tx_setup_buffer() fails ath_tx_setup_buffer() can fail if there is no ath_buf left, or if mapping DMA failed. In this case it frees the skb passed to it. If ath_tx_setup_buffer is called from ath_tx_form_aggr, the skb is still linked into the tid buffer list and must be dequeued before being released. Signed-off-by: Felix Fietkau Cc: stable@vger.kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/xmit.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 23eaa1b..d59dd01 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -64,7 +64,8 @@ static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, struct ath_txq *txq, struct ath_atx_tid *tid, - struct sk_buff *skb); + struct sk_buff *skb, + bool dequeue); enum { MCS_HT20, @@ -811,7 +812,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, fi = get_frame_info(skb); bf = fi->bf; if (!fi->bf) - bf = ath_tx_setup_buffer(sc, txq, tid, skb); + bf = ath_tx_setup_buffer(sc, txq, tid, skb, true); if (!bf) continue; @@ -1726,7 +1727,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, return; } - bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb); + bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb, false); if (!bf) return; @@ -1753,7 +1754,7 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, bf = fi->bf; if (!bf) - bf = ath_tx_setup_buffer(sc, txq, tid, skb); + bf = ath_tx_setup_buffer(sc, txq, tid, skb, false); if (!bf) return; @@ -1814,7 +1815,8 @@ u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate) static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, struct ath_txq *txq, struct ath_atx_tid *tid, - struct sk_buff *skb) + struct sk_buff *skb, + bool dequeue) { struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_frame_info *fi = get_frame_info(skb); @@ -1863,6 +1865,8 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, return bf; error: + if (dequeue) + __skb_unlink(skb, &tid->buf_q); dev_kfree_skb_any(skb); return NULL; } @@ -1893,7 +1897,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb, */ ath_tx_send_ampdu(sc, tid, skb, txctl); } else { - bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb); + bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb, false); if (!bf) return; -- cgit v1.1 From 5a71f134026b17d4000e54c2a5a5ab4e4189f53c Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 24 May 2012 14:32:21 +0200 Subject: ath9k_hw: update AR933x initvals to fix issues with high power devices "> Can you provide more information about the issues with high power devices? Tx being flakey and Rx not working at all." Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- .../net/wireless/ath/ath9k/ar9330_1p1_initvals.h | 178 +++++++++++---------- 1 file changed, 90 insertions(+), 88 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h b/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h index f11d9b2..1bd3a3d 100644 --- a/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2011 Atheros Communications Inc. + * Copyright (c) 2010-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -18,7 +19,7 @@ #define INITVALS_9330_1P1_H static const u32 ar9331_1p1_baseband_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005}, {0x00009820, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e}, {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, @@ -27,10 +28,10 @@ static const u32 ar9331_1p1_baseband_postamble[][5] = { {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c}, {0x00009c00, 0x00000044, 0x00000044, 0x00000044, 0x00000044}, {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a4, 0x037216a4}, - {0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020}, + {0x00009e04, 0x00202020, 0x00202020, 0x00202020, 0x00202020}, {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, {0x00009e10, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e}, - {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e}, + {0x00009e14, 0x31365d5e, 0x3136605e, 0x3136605e, 0x31365d5e}, {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, @@ -55,7 +56,7 @@ static const u32 ar9331_1p1_baseband_postamble[][5] = { {0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, - {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071981}, + {0x0000a2d0, 0x00071982, 0x00071982, 0x00071982, 0x00071982}, {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a}, {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000ae04, 0x00802020, 0x00802020, 0x00802020, 0x00802020}, @@ -63,7 +64,7 @@ static const u32 ar9331_1p1_baseband_postamble[][5] = { }; static const u32 ar9331_modes_lowest_ob_db_tx_gain_1p1[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a}, {0x0000a2dc, 0xffff2a52, 0xffff2a52, 0xffff2a52, 0xffff2a52}, {0x0000a2e0, 0xffffcc84, 0xffffcc84, 0xffffcc84, 0xffffcc84}, @@ -155,7 +156,7 @@ static const u32 ar9331_modes_lowest_ob_db_tx_gain_1p1[][5] = { }; static const u32 ar9331_modes_high_ob_db_tx_gain_1p1[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a}, {0x0000a2dc, 0xffaa9a52, 0xffaa9a52, 0xffaa9a52, 0xffaa9a52}, {0x0000a2e0, 0xffb31c84, 0xffb31c84, 0xffb31c84, 0xffb31c84}, @@ -245,7 +246,7 @@ static const u32 ar9331_modes_high_ob_db_tx_gain_1p1[][5] = { }; static const u32 ar9331_modes_low_ob_db_tx_gain_1p1[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a}, {0x0000a2dc, 0xffff2a52, 0xffff2a52, 0xffff2a52, 0xffff2a52}, {0x0000a2e0, 0xffffcc84, 0xffffcc84, 0xffffcc84, 0xffffcc84}, @@ -377,14 +378,14 @@ static const u32 ar9331_1p1_radio_core[][2] = { {0x000160b4, 0x92480040}, {0x000160c0, 0x006db6db}, {0x000160c4, 0x0186db60}, - {0x000160c8, 0x6db6db6c}, + {0x000160c8, 0x6db4db6c}, {0x000160cc, 0x6de6c300}, {0x000160d0, 0x14500820}, {0x00016100, 0x04cb0001}, {0x00016104, 0xfff80015}, {0x00016108, 0x00080010}, {0x0001610c, 0x00170000}, - {0x00016140, 0x10804000}, + {0x00016140, 0x10800000}, {0x00016144, 0x01884080}, {0x00016148, 0x000080c0}, {0x00016280, 0x01000015}, @@ -417,7 +418,7 @@ static const u32 ar9331_1p1_radio_core[][2] = { }; static const u32 ar9331_1p1_soc_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x00007010, 0x00000022, 0x00000022, 0x00000022, 0x00000022}, }; @@ -691,7 +692,7 @@ static const u32 ar9331_1p1_baseband_core[][2] = { }; static const u32 ar9331_modes_high_power_tx_gain_1p1[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a}, {0x0000a2dc, 0xffff2a52, 0xffff2a52, 0xffff2a52, 0xffff2a52}, {0x0000a2e0, 0xffffcc84, 0xffffcc84, 0xffffcc84, 0xffffcc84}, @@ -783,7 +784,7 @@ static const u32 ar9331_modes_high_power_tx_gain_1p1[][5] = { }; static const u32 ar9331_1p1_mac_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, @@ -973,26 +974,27 @@ static const u32 ar9331_1p1_mac_core[][2] = { static const u32 ar9331_common_rx_gain_1p1[][2] = { /* Addr allmodes */ - {0x0000a000, 0x00010000}, - {0x0000a004, 0x00030002}, - {0x0000a008, 0x00050004}, - {0x0000a00c, 0x00810080}, - {0x0000a010, 0x00830082}, - {0x0000a014, 0x01810180}, - {0x0000a018, 0x01830182}, - {0x0000a01c, 0x01850184}, - {0x0000a020, 0x01890188}, - {0x0000a024, 0x018b018a}, - {0x0000a028, 0x018d018c}, - {0x0000a02c, 0x01910190}, - {0x0000a030, 0x01930192}, - {0x0000a034, 0x01950194}, - {0x0000a038, 0x038a0196}, - {0x0000a03c, 0x038c038b}, - {0x0000a040, 0x0390038d}, - {0x0000a044, 0x03920391}, - {0x0000a048, 0x03940393}, - {0x0000a04c, 0x03960395}, + {0x00009e18, 0x05000000}, + {0x0000a000, 0x00060005}, + {0x0000a004, 0x00810080}, + {0x0000a008, 0x00830082}, + {0x0000a00c, 0x00850084}, + {0x0000a010, 0x01820181}, + {0x0000a014, 0x01840183}, + {0x0000a018, 0x01880185}, + {0x0000a01c, 0x018a0189}, + {0x0000a020, 0x02850284}, + {0x0000a024, 0x02890288}, + {0x0000a028, 0x028b028a}, + {0x0000a02c, 0x03850384}, + {0x0000a030, 0x03890388}, + {0x0000a034, 0x038b038a}, + {0x0000a038, 0x038d038c}, + {0x0000a03c, 0x03910390}, + {0x0000a040, 0x03930392}, + {0x0000a044, 0x03950394}, + {0x0000a048, 0x00000396}, + {0x0000a04c, 0x00000000}, {0x0000a050, 0x00000000}, {0x0000a054, 0x00000000}, {0x0000a058, 0x00000000}, @@ -1005,15 +1007,15 @@ static const u32 ar9331_common_rx_gain_1p1[][2] = { {0x0000a074, 0x00000000}, {0x0000a078, 0x00000000}, {0x0000a07c, 0x00000000}, - {0x0000a080, 0x22222229}, - {0x0000a084, 0x1d1d1d1d}, - {0x0000a088, 0x1d1d1d1d}, - {0x0000a08c, 0x1d1d1d1d}, - {0x0000a090, 0x171d1d1d}, - {0x0000a094, 0x11111717}, - {0x0000a098, 0x00030311}, - {0x0000a09c, 0x00000000}, - {0x0000a0a0, 0x00000000}, + {0x0000a080, 0x28282828}, + {0x0000a084, 0x28282828}, + {0x0000a088, 0x28282828}, + {0x0000a08c, 0x28282828}, + {0x0000a090, 0x28282828}, + {0x0000a094, 0x24242428}, + {0x0000a098, 0x171e1e1e}, + {0x0000a09c, 0x02020b0b}, + {0x0000a0a0, 0x02020202}, {0x0000a0a4, 0x00000000}, {0x0000a0a8, 0x00000000}, {0x0000a0ac, 0x00000000}, @@ -1021,27 +1023,27 @@ static const u32 ar9331_common_rx_gain_1p1[][2] = { {0x0000a0b4, 0x00000000}, {0x0000a0b8, 0x00000000}, {0x0000a0bc, 0x00000000}, - {0x0000a0c0, 0x001f0000}, - {0x0000a0c4, 0x01000101}, - {0x0000a0c8, 0x011e011f}, - {0x0000a0cc, 0x011c011d}, - {0x0000a0d0, 0x02030204}, - {0x0000a0d4, 0x02010202}, - {0x0000a0d8, 0x021f0200}, - {0x0000a0dc, 0x0302021e}, - {0x0000a0e0, 0x03000301}, - {0x0000a0e4, 0x031e031f}, - {0x0000a0e8, 0x0402031d}, - {0x0000a0ec, 0x04000401}, - {0x0000a0f0, 0x041e041f}, - {0x0000a0f4, 0x0502041d}, - {0x0000a0f8, 0x05000501}, - {0x0000a0fc, 0x051e051f}, - {0x0000a100, 0x06010602}, - {0x0000a104, 0x061f0600}, - {0x0000a108, 0x061d061e}, - {0x0000a10c, 0x07020703}, - {0x0000a110, 0x07000701}, + {0x0000a0c0, 0x22072208}, + {0x0000a0c4, 0x22052206}, + {0x0000a0c8, 0x22032204}, + {0x0000a0cc, 0x22012202}, + {0x0000a0d0, 0x221f2200}, + {0x0000a0d4, 0x221d221e}, + {0x0000a0d8, 0x33023303}, + {0x0000a0dc, 0x33003301}, + {0x0000a0e0, 0x331e331f}, + {0x0000a0e4, 0x4402331d}, + {0x0000a0e8, 0x44004401}, + {0x0000a0ec, 0x441e441f}, + {0x0000a0f0, 0x55025503}, + {0x0000a0f4, 0x55005501}, + {0x0000a0f8, 0x551e551f}, + {0x0000a0fc, 0x6602551d}, + {0x0000a100, 0x66006601}, + {0x0000a104, 0x661e661f}, + {0x0000a108, 0x7703661d}, + {0x0000a10c, 0x77017702}, + {0x0000a110, 0x00007700}, {0x0000a114, 0x00000000}, {0x0000a118, 0x00000000}, {0x0000a11c, 0x00000000}, @@ -1054,26 +1056,26 @@ static const u32 ar9331_common_rx_gain_1p1[][2] = { {0x0000a138, 0x00000000}, {0x0000a13c, 0x00000000}, {0x0000a140, 0x001f0000}, - {0x0000a144, 0x01000101}, - {0x0000a148, 0x011e011f}, - {0x0000a14c, 0x011c011d}, - {0x0000a150, 0x02030204}, - {0x0000a154, 0x02010202}, - {0x0000a158, 0x021f0200}, - {0x0000a15c, 0x0302021e}, - {0x0000a160, 0x03000301}, - {0x0000a164, 0x031e031f}, - {0x0000a168, 0x0402031d}, - {0x0000a16c, 0x04000401}, - {0x0000a170, 0x041e041f}, - {0x0000a174, 0x0502041d}, - {0x0000a178, 0x05000501}, - {0x0000a17c, 0x051e051f}, - {0x0000a180, 0x06010602}, - {0x0000a184, 0x061f0600}, - {0x0000a188, 0x061d061e}, - {0x0000a18c, 0x07020703}, - {0x0000a190, 0x07000701}, + {0x0000a144, 0x111f1100}, + {0x0000a148, 0x111d111e}, + {0x0000a14c, 0x111b111c}, + {0x0000a150, 0x22032204}, + {0x0000a154, 0x22012202}, + {0x0000a158, 0x221f2200}, + {0x0000a15c, 0x221d221e}, + {0x0000a160, 0x33013302}, + {0x0000a164, 0x331f3300}, + {0x0000a168, 0x4402331e}, + {0x0000a16c, 0x44004401}, + {0x0000a170, 0x441e441f}, + {0x0000a174, 0x55015502}, + {0x0000a178, 0x551f5500}, + {0x0000a17c, 0x6602551e}, + {0x0000a180, 0x66006601}, + {0x0000a184, 0x661e661f}, + {0x0000a188, 0x7703661d}, + {0x0000a18c, 0x77017702}, + {0x0000a190, 0x00007700}, {0x0000a194, 0x00000000}, {0x0000a198, 0x00000000}, {0x0000a19c, 0x00000000}, @@ -1100,14 +1102,14 @@ static const u32 ar9331_common_rx_gain_1p1[][2] = { {0x0000a1f0, 0x00000396}, {0x0000a1f4, 0x00000396}, {0x0000a1f8, 0x00000396}, - {0x0000a1fc, 0x00000196}, + {0x0000a1fc, 0x00000296}, }; static const u32 ar9331_common_tx_gain_offset1_1[][1] = { - {0}, - {3}, - {0}, - {0}, + {0x00000000}, + {0x00000003}, + {0x00000000}, + {0x00000000}, }; static const u32 ar9331_1p1_chansel_xtal_25M[] = { -- cgit v1.1 From bfc441a4bbe9b7a56d3611cc14c98cce3a573565 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 24 May 2012 14:32:22 +0200 Subject: ath9k_hw: apply internal regulator settings on AR933x On AR933x, the internal regulator settings need to be applied before the PLL init to avoid stability issues. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 2 +- drivers/net/wireless/ath/ath9k/ar9003_eeprom.h | 3 +++ drivers/net/wireless/ath/ath9k/hw.c | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index ac53d90..dfb0441 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -3809,7 +3809,7 @@ static bool is_pmu_set(struct ath_hw *ah, u32 pmu_reg, int pmu_set) return true; } -static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah) +void ar9003_hw_internal_regulator_apply(struct ath_hw *ah) { int internal_regulator = ath9k_hw_ar9300_get_eeprom(ah, EEP_INTERNAL_REGULATOR); diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h index 2505ac4..8396d15 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h @@ -334,4 +334,7 @@ u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is_2ghz); unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah, struct ath9k_channel *chan); + +void ar9003_hw_internal_regulator_apply(struct ath_hw *ah); + #endif diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index abe05ec..7db1890 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1468,6 +1468,9 @@ static bool ath9k_hw_chip_reset(struct ath_hw *ah, return false; ah->chip_fullsleep = false; + + if (AR_SREV_9330(ah)) + ar9003_hw_internal_regulator_apply(ah); ath9k_hw_init_pll(ah, chan); ath9k_hw_set_rfmode(ah, chan); -- cgit v1.1 From 4161923a2410e8d0dd04ebbf93dde46552c07492 Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Tue, 29 May 2012 01:28:42 -0700 Subject: wlcore: fix undefined symbols when CONFIG_PM is not defined commit c21eebb50379a96e1335e933583dcd5b455c6b64 "wl12xx: add RX filters ACX commands" breaks the build when CONFIG_PM isn't defined: ERROR: "wl1271_rx_filter_get_fields_size" [drivers/net/wireless/ti/wlcore/wlcore.ko] undefined! ERROR: "wl1271_rx_filter_flatten_fields" [drivers/net/wireless/ti/wlcore/wlcore.ko] undefined! code in drivers/net/wireless/ti/wlcore/acx.c is using these functions unconditionally while they are #ifdefed CONFIG_PM. Fix it by ifdefing all relevant RX filters code with CONFIG_PM. Reported-by: Geert Uytterhoeven Signed-off-by: Eyal Shapira Acked-by: Luciano Coelho Signed-off-by: John W. Linville --- drivers/net/wireless/ti/wlcore/acx.c | 2 ++ drivers/net/wireless/ti/wlcore/acx.h | 4 +++- drivers/net/wireless/ti/wlcore/rx.c | 2 ++ 3 files changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ti/wlcore/acx.c b/drivers/net/wireless/ti/wlcore/acx.c index 509aa88..f3d6fa5 100644 --- a/drivers/net/wireless/ti/wlcore/acx.c +++ b/drivers/net/wireless/ti/wlcore/acx.c @@ -1715,6 +1715,7 @@ out: } +#ifdef CONFIG_PM /* Set the global behaviour of RX filters - On/Off + default action */ int wl1271_acx_default_rx_filter_enable(struct wl1271 *wl, bool enable, enum rx_filter_action action) @@ -1794,3 +1795,4 @@ out: kfree(acx); return ret; } +#endif /* CONFIG_PM */ diff --git a/drivers/net/wireless/ti/wlcore/acx.h b/drivers/net/wireless/ti/wlcore/acx.h index 8106b2e..e6a7486 100644 --- a/drivers/net/wireless/ti/wlcore/acx.h +++ b/drivers/net/wireless/ti/wlcore/acx.h @@ -1330,9 +1330,11 @@ int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr); int wl1271_acx_fm_coex(struct wl1271 *wl); int wl12xx_acx_set_rate_mgmt_params(struct wl1271 *wl); int wl12xx_acx_config_hangover(struct wl1271 *wl); + +#ifdef CONFIG_PM int wl1271_acx_default_rx_filter_enable(struct wl1271 *wl, bool enable, enum rx_filter_action action); int wl1271_acx_set_rx_filter(struct wl1271 *wl, u8 index, bool enable, struct wl12xx_rx_filter *filter); - +#endif /* CONFIG_PM */ #endif /* __WL1271_ACX_H__ */ diff --git a/drivers/net/wireless/ti/wlcore/rx.c b/drivers/net/wireless/ti/wlcore/rx.c index 1f1d948..d6a3c6b 100644 --- a/drivers/net/wireless/ti/wlcore/rx.c +++ b/drivers/net/wireless/ti/wlcore/rx.c @@ -279,6 +279,7 @@ void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status *status) wl12xx_rearm_rx_streaming(wl, active_hlids); } +#ifdef CONFIG_PM int wl1271_rx_filter_enable(struct wl1271 *wl, int index, bool enable, struct wl12xx_rx_filter *filter) @@ -314,3 +315,4 @@ void wl1271_rx_filter_clear_all(struct wl1271 *wl) wl1271_rx_filter_enable(wl, i, 0, NULL); } } +#endif /* CONFIG_PM */ -- cgit v1.1 From 9dae31009b1a00d926c6fe032d5a88099620adc3 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 28 May 2012 22:31:41 +0000 Subject: asix: allow full size 8021Q frames to be received asix driver drops 8021Q full size frames because it doesn't take into account VLAN header size. Tested on AX88772 adapter. Signed-off-by: Eric Dumazet CC: Greg Kroah-Hartman CC: Allan Chou CC: Trond Wuellner CC: Grant Grundler CC: Paul Stewart Signed-off-by: David S. Miller --- drivers/net/usb/asix.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 71e2b05..3ae80ec 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -35,6 +35,7 @@ #include #include #include +#include #define DRIVER_VERSION "22-Dec-2011" #define DRIVER_NAME "asix" @@ -321,7 +322,7 @@ static int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb) return 0; } - if ((size > dev->net->mtu + ETH_HLEN) || + if ((size > dev->net->mtu + ETH_HLEN + VLAN_HLEN) || (size + offset > skb->len)) { netdev_err(dev->net, "asix_rx_fixup() Bad RX Length %d\n", size); -- cgit v1.1 From 79fba9f51755c704c0a7d7b7f0df10874dc0a744 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Mon, 28 May 2012 23:07:55 +0000 Subject: net: sh_eth: fix the rxdesc pointer when rx descriptor empty happens When Receive Descriptor Empty happens, rxdesc pointer of the driver and actual next descriptor of the controller may be mismatch. This patch fixes it. Signed-off-by: Yoshihiro Shimoda Signed-off-by: David S. Miller --- drivers/net/ethernet/renesas/sh_eth.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index be3c221..667169b 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -1101,8 +1101,12 @@ static int sh_eth_rx(struct net_device *ndev) /* Restart Rx engine if stopped. */ /* If we don't need to check status, don't. -KDU */ - if (!(sh_eth_read(ndev, EDRRR) & EDRRR_R)) + if (!(sh_eth_read(ndev, EDRRR) & EDRRR_R)) { + /* fix the values for the next receiving */ + mdp->cur_rx = mdp->dirty_rx = (sh_eth_read(ndev, RDFAR) - + sh_eth_read(ndev, RDLAR)) >> 4; sh_eth_write(ndev, EDRRR_R, EDRRR); + } return 0; } @@ -1199,8 +1203,6 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) /* Receive Descriptor Empty int */ ndev->stats.rx_over_errors++; - if (sh_eth_read(ndev, EDRRR) ^ EDRRR_R) - sh_eth_write(ndev, EDRRR_R, EDRRR); if (netif_msg_rx_err(mdp)) dev_err(&ndev->dev, "Receive Descriptor Empty\n"); } -- cgit v1.1 From acaf8276823302983d681c2cedaaf01918406935 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Tue, 29 May 2012 13:38:42 +0000 Subject: r6040: disable pci device if the subsequent calls (after pci_enable_device) fails the calls after the pci_enable_device may fail, and will error out with out disabling it. disable the device at error paths. Signed-off-by: Devendra Naga Signed-off-by: David S. Miller --- drivers/net/ethernet/rdc/r6040.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ethernet/rdc/r6040.c b/drivers/net/ethernet/rdc/r6040.c index 4de7364..f5e6f1f 100644 --- a/drivers/net/ethernet/rdc/r6040.c +++ b/drivers/net/ethernet/rdc/r6040.c @@ -1096,20 +1096,20 @@ static int __devinit r6040_init_one(struct pci_dev *pdev, if (err) { dev_err(&pdev->dev, "32-bit PCI DMA addresses" "not supported by the card\n"); - goto err_out; + goto err_out_disable_dev; } err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); if (err) { dev_err(&pdev->dev, "32-bit PCI DMA addresses" "not supported by the card\n"); - goto err_out; + goto err_out_disable_dev; } /* IO Size check */ if (pci_resource_len(pdev, bar) < io_size) { dev_err(&pdev->dev, "Insufficient PCI resources, aborting\n"); err = -EIO; - goto err_out; + goto err_out_disable_dev; } pci_set_master(pdev); @@ -1117,7 +1117,7 @@ static int __devinit r6040_init_one(struct pci_dev *pdev, dev = alloc_etherdev(sizeof(struct r6040_private)); if (!dev) { err = -ENOMEM; - goto err_out; + goto err_out_disable_dev; } SET_NETDEV_DEV(dev, &pdev->dev); lp = netdev_priv(dev); @@ -1238,6 +1238,8 @@ err_out_free_res: pci_release_regions(pdev); err_out_free_dev: free_netdev(dev); +err_out_disable_dev: + pci_disable_device(pdev); err_out: return err; } -- cgit v1.1 From 20571d8894d1ee5a181e34e8d07ed8472acd30c4 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Tue, 29 May 2012 13:43:34 +0000 Subject: r6040: Do a Proper deinit at errorpath and also when driver unloads (calling r6040_remove_one) so if mdiobus_alloc fails, the errorpath doesnt do a netif_napi_del and also doesn't set the priv data of the driver to NULL. at the driver unload stage the driver doesn't remove the NAPI context, and doesnt' set the priv data to NULL, and also doesn't call the pci_iounmap. Signed-off-by: Devendra Naga Signed-off-by: David S. Miller --- drivers/net/ethernet/rdc/r6040.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/ethernet/rdc/r6040.c b/drivers/net/ethernet/rdc/r6040.c index f5e6f1f..d1827e8 100644 --- a/drivers/net/ethernet/rdc/r6040.c +++ b/drivers/net/ethernet/rdc/r6040.c @@ -1233,6 +1233,8 @@ err_out_mdio_irq: err_out_mdio: mdiobus_free(lp->mii_bus); err_out_unmap: + netif_napi_del(&lp->napi); + pci_set_drvdata(pdev, NULL); pci_iounmap(pdev, ioaddr); err_out_free_res: pci_release_regions(pdev); @@ -1253,6 +1255,9 @@ static void __devexit r6040_remove_one(struct pci_dev *pdev) mdiobus_unregister(lp->mii_bus); kfree(lp->mii_bus->irq); mdiobus_free(lp->mii_bus); + netif_napi_del(&lp->napi); + pci_set_drvdata(pdev, NULL); + pci_iounmap(pdev, lp->base); pci_release_regions(pdev); free_netdev(dev); pci_disable_device(pdev); -- cgit v1.1 From 3bbf372c6c60255585783bb08ab477a72b918196 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Wed, 30 May 2012 17:21:29 +0300 Subject: virtio-net: remove useless disable on freeze disable_cb is just an optimization: it can not guarantee that there are no callbacks. In particular it doesn't have any effect when event index is on. Instead, detach, napi disable and reset on freeze ensure we don't run concurrently with a callback. Remove the useless calls so we get same behaviour with and without event index. Signed-off-by: Michael S. Tsirkin Signed-off-by: David S. Miller --- drivers/net/virtio_net.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 9ce6995..5214b1e 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -1231,11 +1231,6 @@ static int virtnet_freeze(struct virtio_device *vdev) vi->config_enable = false; mutex_unlock(&vi->config_lock); - virtqueue_disable_cb(vi->rvq); - virtqueue_disable_cb(vi->svq); - if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ)) - virtqueue_disable_cb(vi->cvq); - netif_device_detach(vi->dev); cancel_delayed_work_sync(&vi->refill); -- cgit v1.1 From 2e1d4a065a77d076a679df22a4eddbc7e33cad98 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Tue, 29 May 2012 18:47:37 +0000 Subject: net/smsc911x: Repair broken failure paths Current failure paths attempt to free resources which we failed to request and disable resources which we failed to enable ones. This leads to kernel oops/panic. This patch does some simple re-ordering to prevent this from happening. Cc: netdev@vger.kernel.org Signed-off-by: Lee Jones Acked-by: Linus Walleij Signed-off-by: David S. Miller --- drivers/net/ethernet/smsc/smsc911x.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c index dab9c6f..1466e5d 100644 --- a/drivers/net/ethernet/smsc/smsc911x.c +++ b/drivers/net/ethernet/smsc/smsc911x.c @@ -2390,11 +2390,11 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev) retval = smsc911x_request_resources(pdev); if (retval) - goto out_return_resources; + goto out_request_resources_fail; retval = smsc911x_enable_resources(pdev); if (retval) - goto out_disable_resources; + goto out_enable_resources_fail; if (pdata->ioaddr == NULL) { SMSC_WARN(pdata, probe, "Error smsc911x base address invalid"); @@ -2501,8 +2501,9 @@ out_free_irq: free_irq(dev->irq, dev); out_disable_resources: (void)smsc911x_disable_resources(pdev); -out_return_resources: +out_enable_resources_fail: smsc911x_free_resources(pdev); +out_request_resources_fail: platform_set_drvdata(pdev, NULL); iounmap(pdata->ioaddr); free_netdev(dev); -- cgit v1.1