From cbf68a668d0e41527572c762824a1b6a9225d33f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 30 Nov 2010 11:03:44 -0800 Subject: iwlagn: rename enhanced txpower fields Some fields we didn't previously use from the enhanced TX power structure will be needed in the next patch, so rename them to their correct names to be able to use them and change code reading them accordingly. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c | 3 ++- drivers/net/wireless/iwlwifi/iwl-eeprom.h | 10 ++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c index a650baba0809..96510600b751 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c @@ -419,7 +419,8 @@ void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv) * always check for valid entry before process * the information */ - if (!enhanced_txpower->common || enhanced_txpower->reserved) + if (!(enhanced_txpower->flags || enhanced_txpower->channel) || + enhanced_txpower->delta_20_in_40) continue; for (element = 0; element < eeprom_section_count; element++) { diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index d9b590625ae4..310e34568a41 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -127,21 +127,23 @@ struct iwl_eeprom_channel { * Enhanced regulatory tx power portion of eeprom image can be broken down * into individual structures; each one is 8 bytes in size and contain the * following information - * @common: (desc + channel) not used by driver, should _NOT_ be "zero" + * @flags: entry flags + * @channel: channel number * @chain_a_max_pwr: chain a max power in 1/2 dBm * @chain_b_max_pwr: chain b max power in 1/2 dBm * @chain_c_max_pwr: chain c max power in 1/2 dBm - * @reserved: not used, should be "zero" + * @delta_20_in_40: 20-in-40 deltas (hi/lo) * @mimo2_max_pwr: mimo2 max power in 1/2 dBm * @mimo3_max_pwr: mimo3 max power in 1/2 dBm * */ struct iwl_eeprom_enhanced_txpwr { - __le16 common; + u8 flags; + u8 channel; s8 chain_a_max; s8 chain_b_max; s8 chain_c_max; - s8 reserved; + u8 delta_20_in_40; s8 mimo2_max; s8 mimo3_max; } __packed; -- cgit v1.2.3-59-g8ed1b From 6942fec92d3d1b6918425730de31b4c6d0d5c196 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Thu, 9 Dec 2010 10:09:14 -0800 Subject: iwlagn: implement layout-agnostic EEPROM reading From: Johannes Berg The current EEPROM reading code has some layout assumptions that now turned out to be false with some newer versions of the EEPROM. Luckily, we can avoid all such assumptions by using data in the EEPROM itself, so implement using that. However, for risk mitigation purposes, keep the old reading code for current hardware for now. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 2 + drivers/net/wireless/iwlwifi/iwl-6000.c | 12 ++++ drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c | 85 ++++++++++++++++++++++++++- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 6 ++ drivers/net/wireless/iwlwifi/iwl-core.h | 1 + drivers/net/wireless/iwlwifi/iwl-eeprom.h | 15 +++++ 6 files changed, 120 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index db540910b110..0e027f787fbc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -315,6 +315,7 @@ struct iwl_cfg iwl100_bgn_cfg = { .mod_params = &iwlagn_mod_params, .base_params = &iwl1000_base_params, .ht_params = &iwl1000_ht_params, + .use_new_eeprom_reading = true, }; struct iwl_cfg iwl100_bg_cfg = { @@ -330,6 +331,7 @@ struct iwl_cfg iwl100_bg_cfg = { .ops = &iwl1000_ops, .mod_params = &iwlagn_mod_params, .base_params = &iwl1000_base_params, + .use_new_eeprom_reading = true, }; MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX)); diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 11e6532fc573..0ceeaac85eda 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -561,6 +561,7 @@ struct iwl_cfg iwl6000g2a_2agn_cfg = { .ht_params = &iwl6000_ht_params, .need_dc_calib = true, .need_temp_offset_calib = true, + .use_new_eeprom_reading = true, }; struct iwl_cfg iwl6000g2a_2abg_cfg = { @@ -578,6 +579,7 @@ struct iwl_cfg iwl6000g2a_2abg_cfg = { .base_params = &iwl6000_base_params, .need_dc_calib = true, .need_temp_offset_calib = true, + .use_new_eeprom_reading = true, }; struct iwl_cfg iwl6000g2a_2bg_cfg = { @@ -595,6 +597,7 @@ struct iwl_cfg iwl6000g2a_2bg_cfg = { .base_params = &iwl6000_base_params, .need_dc_calib = true, .need_temp_offset_calib = true, + .use_new_eeprom_reading = true, }; struct iwl_cfg iwl6000g2b_2agn_cfg = { @@ -616,6 +619,7 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = { .need_temp_offset_calib = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, + .use_new_eeprom_reading = true, }; struct iwl_cfg iwl6000g2b_2abg_cfg = { @@ -636,6 +640,7 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = { .need_temp_offset_calib = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, + .use_new_eeprom_reading = true, }; struct iwl_cfg iwl6000g2b_2bgn_cfg = { @@ -657,6 +662,7 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = { .need_temp_offset_calib = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, + .use_new_eeprom_reading = true, }; struct iwl_cfg iwl6000g2b_2bg_cfg = { @@ -677,6 +683,7 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = { .need_temp_offset_calib = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, + .use_new_eeprom_reading = true, }; struct iwl_cfg iwl6000g2b_bgn_cfg = { @@ -698,6 +705,7 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = { .need_temp_offset_calib = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, + .use_new_eeprom_reading = true, }; struct iwl_cfg iwl6000g2b_bg_cfg = { @@ -718,6 +726,7 @@ struct iwl_cfg iwl6000g2b_bg_cfg = { .need_temp_offset_calib = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, + .use_new_eeprom_reading = true, }; /* @@ -804,6 +813,7 @@ struct iwl_cfg iwl6050g2_bgn_cfg = { .base_params = &iwl6050_base_params, .ht_params = &iwl6000_ht_params, .need_dc_calib = true, + .use_new_eeprom_reading = true, }; struct iwl_cfg iwl6050_2abg_cfg = { @@ -857,6 +867,7 @@ struct iwl_cfg iwl130_bgn_cfg = { .need_dc_calib = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, + .use_new_eeprom_reading = true, }; struct iwl_cfg iwl130_bg_cfg = { @@ -876,6 +887,7 @@ struct iwl_cfg iwl130_bg_cfg = { .need_dc_calib = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, + .use_new_eeprom_reading = true, }; MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c index 96510600b751..9eeeda18748d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c @@ -392,7 +392,7 @@ static s8 iwl_update_channel_txpower(struct iwl_priv *priv, /** * iwlcore_eeprom_enhanced_txpower: process enhanced tx power info */ -void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv) +static void iwlcore_eeprom_enhanced_txpower_old(struct iwl_priv *priv) { int eeprom_section_count = 0; int section, element; @@ -453,3 +453,86 @@ void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv) } } } + +static void +iwlcore_eeprom_enh_txp_read_element(struct iwl_priv *priv, + struct iwl_eeprom_enhanced_txpwr *txp, + s8 max_txpower_avg) +{ + int ch_idx; + bool is_ht40 = txp->flags & IWL_EEPROM_ENH_TXP_FL_40MHZ; + enum ieee80211_band band; + + band = txp->flags & IWL_EEPROM_ENH_TXP_FL_BAND_52G ? + IEEE80211_BAND_5GHZ : IEEE80211_BAND_2GHZ; + + for (ch_idx = 0; ch_idx < priv->channel_count; ch_idx++) { + struct iwl_channel_info *ch_info = &priv->channel_info[ch_idx]; + + /* update matching channel or from common data only */ + if (txp->channel != 0 && ch_info->channel != txp->channel) + continue; + + /* update matching band only */ + if (band != ch_info->band) + continue; + + if (ch_info->max_power_avg < max_txpower_avg && !is_ht40) { + ch_info->max_power_avg = max_txpower_avg; + ch_info->curr_txpow = max_txpower_avg; + ch_info->scan_power = max_txpower_avg; + } + + if (is_ht40 && ch_info->ht40_max_power_avg < max_txpower_avg) + ch_info->ht40_max_power_avg = max_txpower_avg; + } +} + +#define EEPROM_TXP_OFFS (0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT) +#define EEPROM_TXP_ENTRY_LEN sizeof(struct iwl_eeprom_enhanced_txpwr) +#define EEPROM_TXP_SZ_OFFS (0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT_SIZE) + +static void iwlcore_eeprom_enhanced_txpower_new(struct iwl_priv *priv) +{ + struct iwl_eeprom_enhanced_txpwr *txp_array, *txp; + int idx, entries; + __le16 *txp_len; + s8 max_txp_avg, max_txp_avg_halfdbm; + + BUILD_BUG_ON(sizeof(struct iwl_eeprom_enhanced_txpwr) != 8); + + /* the length is in 16-bit words, but we want entries */ + txp_len = (__le16 *) iwlagn_eeprom_query_addr(priv, EEPROM_TXP_SZ_OFFS); + entries = le16_to_cpup(txp_len) * 2 / EEPROM_TXP_ENTRY_LEN; + + txp_array = (void *) iwlagn_eeprom_query_addr(priv, EEPROM_TXP_OFFS); + for (idx = 0; idx < entries; idx++) { + txp = &txp_array[idx]; + + /* skip invalid entries */ + if (!(txp->flags & IWL_EEPROM_ENH_TXP_FL_VALID)) + continue; + + max_txp_avg = iwl_get_max_txpower_avg(priv, txp_array, idx, + &max_txp_avg_halfdbm); + + /* + * Update the user limit values values to the highest + * power supported by any channel + */ + if (max_txp_avg > priv->tx_power_user_lmt) + priv->tx_power_user_lmt = max_txp_avg; + if (max_txp_avg_halfdbm > priv->tx_power_lmt_in_half_dbm) + priv->tx_power_lmt_in_half_dbm = max_txp_avg_halfdbm; + + iwlcore_eeprom_enh_txp_read_element(priv, txp, max_txp_avg); + } +} + +void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv) +{ + if (priv->cfg->use_new_eeprom_reading) + iwlcore_eeprom_enhanced_txpower_new(priv); + else + iwlcore_eeprom_enhanced_txpower_old(priv); +} diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index b555edd53354..554afb7d9670 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -569,6 +569,12 @@ static u32 eeprom_indirect_address(const struct iwl_priv *priv, u32 address) case INDIRECT_REGULATORY: offset = iwl_eeprom_query16(priv, EEPROM_LINK_REGULATORY); break; + case INDIRECT_TXP_LIMIT: + offset = iwl_eeprom_query16(priv, EEPROM_LINK_TXP_LIMIT); + break; + case INDIRECT_TXP_LIMIT_SIZE: + offset = iwl_eeprom_query16(priv, EEPROM_LINK_TXP_LIMIT_SIZE); + break; case INDIRECT_CALIBRATION: offset = iwl_eeprom_query16(priv, EEPROM_LINK_CALIBRATION); break; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 64527def059f..954ecc2c34c4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -390,6 +390,7 @@ struct iwl_cfg { const bool need_temp_offset_calib; /* if used set to true */ u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; u8 scan_tx_antennas[IEEE80211_NUM_BANDS]; + const bool use_new_eeprom_reading; /* temporary, remove later */ }; /*************************** diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index 310e34568a41..e3a279d2d0b6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -120,6 +120,17 @@ struct iwl_eeprom_channel { s8 max_power_avg; /* max power (dBm) on this chnl, limit 31 */ } __packed; +enum iwl_eeprom_enhanced_txpwr_flags { + IWL_EEPROM_ENH_TXP_FL_VALID = BIT(0), + IWL_EEPROM_ENH_TXP_FL_BAND_52G = BIT(1), + IWL_EEPROM_ENH_TXP_FL_OFDM = BIT(2), + IWL_EEPROM_ENH_TXP_FL_40MHZ = BIT(3), + IWL_EEPROM_ENH_TXP_FL_HT_AP = BIT(4), + IWL_EEPROM_ENH_TXP_FL_RES1 = BIT(5), + IWL_EEPROM_ENH_TXP_FL_RES2 = BIT(6), + IWL_EEPROM_ENH_TXP_FL_COMMON_TYPE = BIT(7), +}; + /** * iwl_eeprom_enhanced_txpwr structure * This structure presents the enhanced regulatory tx power limit layout @@ -188,6 +199,8 @@ struct iwl_eeprom_enhanced_txpwr { #define EEPROM_LINK_CALIBRATION (2*0x67) #define EEPROM_LINK_PROCESS_ADJST (2*0x68) #define EEPROM_LINK_OTHERS (2*0x69) +#define EEPROM_LINK_TXP_LIMIT (2*0x6a) +#define EEPROM_LINK_TXP_LIMIT_SIZE (2*0x6b) /* agn regulatory - indirect access */ #define EEPROM_REG_BAND_1_CHANNELS ((0x08)\ @@ -391,6 +404,8 @@ struct iwl_eeprom_calib_info { #define INDIRECT_CALIBRATION 0x00040000 #define INDIRECT_PROCESS_ADJST 0x00050000 #define INDIRECT_OTHERS 0x00060000 +#define INDIRECT_TXP_LIMIT 0x00070000 +#define INDIRECT_TXP_LIMIT_SIZE 0x00080000 #define INDIRECT_ADDRESS 0x00100000 /* General */ -- cgit v1.2.3-59-g8ed1b From fb4fa76a1fa59340154c42d998d700e1f8bf21e0 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Mon, 6 Dec 2010 09:05:50 +0000 Subject: net: Convert netpoll blocking api in bonding driver to be a counter A while back I made some changes to enable netpoll in the bonding driver. Among them was a per-cpu flag that indicated we were in a path that held locks which could cause the netpoll path to block in during tx, and as such the tx path should queue the frame for later use. This appears to have given rise to a regression. If one of those paths on which we hold the per-cpu flag yields the cpu, its possible for us to come back on a different cpu, leading to us clearing a different flag than we set. This results in odd netpoll drops, and BUG backtraces appearing in the log, as we check to make sure that we only clear set bits, and only set clear bits. I had though briefly about changing the offending paths so that they wouldn't sleep, but looking at my origional work more closely, it doesn't appear that a per-cpu flag is warranted. We alrady gate the checking of this flag on IFF_IN_NETPOLL, so we don't hit this in the normal tx case anyway. And practically speaking, the normal use case for netpoll is to only have one client anyway, so we're not going to erroneously queue netpoll frames when its actually safe to do so. As such, lets just convert that per-cpu flag to an atomic counter. It fixes the rescheduling bugs, is equivalent from a performance perspective and actually eliminates some code in the process. Tested by the reporter and myself, successfully Reported-by: Liang Zheng CC: Jay Vosburgh CC: Andy Gospodarek CC: David S. Miller Signed-off-by: Neil Horman Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 17 +++++------------ drivers/net/bonding/bonding.h | 12 ++++-------- 2 files changed, 9 insertions(+), 20 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 2fee00a4c9ef..d0ea760ce419 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -171,7 +171,7 @@ MODULE_PARM_DESC(resend_igmp, "Number of IGMP membership reports to send on link /*----------------------------- Global variables ----------------------------*/ #ifdef CONFIG_NET_POLL_CONTROLLER -cpumask_var_t netpoll_block_tx; +atomic_t netpoll_block_tx = ATOMIC_INIT(0); #endif static const char * const version = @@ -5299,13 +5299,6 @@ static int __init bonding_init(void) if (res) goto out; -#ifdef CONFIG_NET_POLL_CONTROLLER - if (!alloc_cpumask_var(&netpoll_block_tx, GFP_KERNEL)) { - res = -ENOMEM; - goto out; - } -#endif - res = register_pernet_subsys(&bond_net_ops); if (res) goto out; @@ -5334,9 +5327,6 @@ err: rtnl_link_unregister(&bond_link_ops); err_link: unregister_pernet_subsys(&bond_net_ops); -#ifdef CONFIG_NET_POLL_CONTROLLER - free_cpumask_var(netpoll_block_tx); -#endif goto out; } @@ -5353,7 +5343,10 @@ static void __exit bonding_exit(void) unregister_pernet_subsys(&bond_net_ops); #ifdef CONFIG_NET_POLL_CONTROLLER - free_cpumask_var(netpoll_block_tx); + /* + * Make sure we don't have an imbalance on our netpoll blocking + */ + WARN_ON(atomic_read(&netpoll_block_tx)); #endif } diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 4eedb12df6ca..c2f081352a03 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -119,26 +119,22 @@ #ifdef CONFIG_NET_POLL_CONTROLLER -extern cpumask_var_t netpoll_block_tx; +extern atomic_t netpoll_block_tx; static inline void block_netpoll_tx(void) { - preempt_disable(); - BUG_ON(cpumask_test_and_set_cpu(smp_processor_id(), - netpoll_block_tx)); + atomic_inc(&netpoll_block_tx); } static inline void unblock_netpoll_tx(void) { - BUG_ON(!cpumask_test_and_clear_cpu(smp_processor_id(), - netpoll_block_tx)); - preempt_enable(); + atomic_dec(&netpoll_block_tx); } static inline int is_netpoll_tx_blocked(struct net_device *dev) { if (unlikely(dev->priv_flags & IFF_IN_NETPOLL)) - return cpumask_test_cpu(smp_processor_id(), netpoll_block_tx); + return atomic_read(&netpoll_block_tx); return 0; } #else -- cgit v1.2.3-59-g8ed1b From 6934d33556b366d22392a415ca09d720fed6a442 Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Tue, 7 Dec 2010 22:21:52 +0000 Subject: hso: IP checksuming doesn't work on GE0301 option cards There is definitly a problem, that some option cards send up broken IP pakets leading to corrupted IP packets. These corruptions aren't detected, because the driver claims that the packets are already checksummed. This change removes the CHECKSUM_UNNECESSARY option and let IP detect broken data. Signed-off-by: Thomas Bogendoerfer Signed-off-by: David S. Miller --- drivers/net/usb/hso.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 62e9e8dc8190..812edf85d6d3 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -958,10 +958,6 @@ static void packetizeRx(struct hso_net *odev, unsigned char *ip_pkt, /* Packet is complete. Inject into stack. */ /* We have IP packet here */ odev->skb_rx_buf->protocol = cpu_to_be16(ETH_P_IP); - /* don't check it */ - odev->skb_rx_buf->ip_summed = - CHECKSUM_UNNECESSARY; - skb_reset_mac_header(odev->skb_rx_buf); /* Ship it off to the kernel */ -- cgit v1.2.3-59-g8ed1b From e4fbce740f078bbc925ba5c86648d9c883968479 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 8 Dec 2010 15:32:14 +0000 Subject: r8169: Fix runtime power management I noticed that one of the post-2.6.36 patches broke runtime PM of the r8169 on my MSI Wind test machine in such a way that the link was not brought up after reconnecting the network cable. In the process of debugging the issue I realized that we only should invoke the runtime PM functions in rtl8169_check_link_status() when link change is reported and if we do so, the problem goes away. Moreover, this allows rtl8169_runtime_idle() to be simplified quite a bit. Signed-off-by: Rafael J. Wysocki Acked-by: Francois Romieu Signed-off-by: David S. Miller --- drivers/net/r8169.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 7d33ef4bcb4a..53b13deade95 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -744,26 +744,36 @@ static void rtl8169_xmii_reset_enable(void __iomem *ioaddr) mdio_write(ioaddr, MII_BMCR, val & 0xffff); } -static void rtl8169_check_link_status(struct net_device *dev, +static void __rtl8169_check_link_status(struct net_device *dev, struct rtl8169_private *tp, - void __iomem *ioaddr) + void __iomem *ioaddr, + bool pm) { unsigned long flags; spin_lock_irqsave(&tp->lock, flags); if (tp->link_ok(ioaddr)) { /* This is to cancel a scheduled suspend if there's one. */ - pm_request_resume(&tp->pci_dev->dev); + if (pm) + pm_request_resume(&tp->pci_dev->dev); netif_carrier_on(dev); netif_info(tp, ifup, dev, "link up\n"); } else { netif_carrier_off(dev); netif_info(tp, ifdown, dev, "link down\n"); - pm_schedule_suspend(&tp->pci_dev->dev, 100); + if (pm) + pm_schedule_suspend(&tp->pci_dev->dev, 100); } spin_unlock_irqrestore(&tp->lock, flags); } +static void rtl8169_check_link_status(struct net_device *dev, + struct rtl8169_private *tp, + void __iomem *ioaddr) +{ + __rtl8169_check_link_status(dev, tp, ioaddr, false); +} + #define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST) static u32 __rtl8169_get_wol(struct rtl8169_private *tp) @@ -4600,7 +4610,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) } if (status & LinkChg) - rtl8169_check_link_status(dev, tp, ioaddr); + __rtl8169_check_link_status(dev, tp, ioaddr, true); /* We need to see the lastest version of tp->intr_mask to * avoid ignoring an MSI interrupt and having to wait for @@ -4890,11 +4900,7 @@ static int rtl8169_runtime_idle(struct device *device) struct net_device *dev = pci_get_drvdata(pdev); struct rtl8169_private *tp = netdev_priv(dev); - if (!tp->TxDescArray) - return 0; - - rtl8169_check_link_status(dev, tp, tp->mmio_addr); - return -EBUSY; + return tp->TxDescArray ? -EBUSY : 0; } static const struct dev_pm_ops rtl8169_pm_ops = { -- cgit v1.2.3-59-g8ed1b From 79aeec5822cea63cf732bbc0c9f3337542352616 Mon Sep 17 00:00:00 2001 From: Vasanthy Kolluri Date: Wed, 8 Dec 2010 13:05:45 +0000 Subject: enic: Bug Fix: Pass napi reference to the isr that services receive queue Pass reference to napi instead of enic device to the isr that services receive queue. Signed-off-by: Vasanthy Kolluri Signed-off-by: Roopa Prabhu Signed-off-by: David Wang Signed-off-by: David S. Miller --- drivers/net/enic/enic_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index a466ef91dd43..aa28b270c045 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -1962,7 +1962,8 @@ static void enic_poll_controller(struct net_device *netdev) case VNIC_DEV_INTR_MODE_MSIX: for (i = 0; i < enic->rq_count; i++) { intr = enic_msix_rq_intr(enic, i); - enic_isr_msix_rq(enic->msix_entry[intr].vector, enic); + enic_isr_msix_rq(enic->msix_entry[intr].vector, + &enic->napi[i]); } intr = enic_msix_wq_intr(enic, i); enic_isr_msix_wq(enic->msix_entry[intr].vector, enic); -- cgit v1.2.3-59-g8ed1b From 377ecca9ba6d98f31517e2322075e94d1be94561 Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Wed, 8 Dec 2010 23:05:13 +0000 Subject: phy: add the IC+ IP1001 driver This patch adds the IC+ IP1001 (Gigabit Ethernet Transceiver) driver. I've had to add an additional delay (2ns) to adjust RX clock phase at GMII/ RGMII interface (according to the PHY data-sheet). This helps to have the RGMII working on some ST platforms. Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- drivers/net/phy/Kconfig | 2 +- drivers/net/phy/icplus.c | 59 ++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 55 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index cb3d13e4e074..35fda5ac8120 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -64,7 +64,7 @@ config BCM63XX_PHY config ICPLUS_PHY tristate "Drivers for ICPlus PHYs" ---help--- - Currently supports the IP175C PHY. + Currently supports the IP175C and IP1001 PHYs. config REALTEK_PHY tristate "Drivers for Realtek PHYs" diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c index c1d2d251fe8b..9a09e24c30bc 100644 --- a/drivers/net/phy/icplus.c +++ b/drivers/net/phy/icplus.c @@ -30,7 +30,7 @@ #include #include -MODULE_DESCRIPTION("ICPlus IP175C PHY driver"); +MODULE_DESCRIPTION("ICPlus IP175C/IC1001 PHY drivers"); MODULE_AUTHOR("Michael Barkowski"); MODULE_LICENSE("GPL"); @@ -89,6 +89,33 @@ static int ip175c_config_init(struct phy_device *phydev) return 0; } +static int ip1001_config_init(struct phy_device *phydev) +{ + int err, value; + + /* Software Reset PHY */ + value = phy_read(phydev, MII_BMCR); + value |= BMCR_RESET; + err = phy_write(phydev, MII_BMCR, value); + if (err < 0) + return err; + + do { + value = phy_read(phydev, MII_BMCR); + } while (value & BMCR_RESET); + + /* Additional delay (2ns) used to adjust RX clock phase + * at GMII/ RGMII interface */ + value = phy_read(phydev, 16); + value |= 0x3; + + err = phy_write(phydev, 16, value); + if (err < 0) + return err; + + return err; +} + static int ip175c_read_status(struct phy_device *phydev) { if (phydev->addr == 4) /* WAN port */ @@ -121,21 +148,43 @@ static struct phy_driver ip175c_driver = { .driver = { .owner = THIS_MODULE,}, }; -static int __init ip175c_init(void) +static struct phy_driver ip1001_driver = { + .phy_id = 0x02430d90, + .name = "ICPlus IP1001", + .phy_id_mask = 0x0ffffff0, + .features = PHY_GBIT_FEATURES | SUPPORTED_Pause | + SUPPORTED_Asym_Pause, + .config_init = &ip1001_config_init, + .config_aneg = &genphy_config_aneg, + .read_status = &genphy_read_status, + .suspend = genphy_suspend, + .resume = genphy_resume, + .driver = { .owner = THIS_MODULE,}, +}; + +static int __init icplus_init(void) { + int ret = 0; + + ret = phy_driver_register(&ip1001_driver); + if (ret < 0) + return -ENODEV; + return phy_driver_register(&ip175c_driver); } -static void __exit ip175c_exit(void) +static void __exit icplus_exit(void) { + phy_driver_unregister(&ip1001_driver); phy_driver_unregister(&ip175c_driver); } -module_init(ip175c_init); -module_exit(ip175c_exit); +module_init(icplus_init); +module_exit(icplus_exit); static struct mdio_device_id __maybe_unused icplus_tbl[] = { { 0x02430d80, 0x0ffffff0 }, + { 0x02430d90, 0x0ffffff0 }, { } }; -- cgit v1.2.3-59-g8ed1b From c710245caa41060e983cc9cb5ffcc020e02ca45f Mon Sep 17 00:00:00 2001 From: Casey Leedom Date: Thu, 9 Dec 2010 09:38:24 +0000 Subject: cxgb4vf: Ingress Queue Entry Size needs to be 64 bytes Was using L1_CACHE_BYTES for the Ingress Queue Entry Size but it really needs to be 64 bytes in order to support the largest message sizes. Signed-off-by: Casey Leedom Signed-off-by: David S. Miller --- drivers/net/cxgb4vf/cxgb4vf_main.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c index d887a76cd39d..6bf464afa90e 100644 --- a/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/cxgb4vf/cxgb4vf_main.c @@ -2269,6 +2269,7 @@ static void __devinit cfg_queues(struct adapter *adapter) { struct sge *s = &adapter->sge; int q10g, n10g, qidx, pidx, qs; + size_t iqe_size; /* * We should not be called till we know how many Queue Sets we can @@ -2312,6 +2313,13 @@ static void __devinit cfg_queues(struct adapter *adapter) } s->ethqsets = qidx; + /* + * The Ingress Queue Entry Size for our various Response Queues needs + * to be big enough to accommodate the largest message we can receive + * from the chip/firmware; which is 64 bytes ... + */ + iqe_size = 64; + /* * Set up default Queue Set parameters ... Start off with the * shortest interrupt holdoff timer. @@ -2320,7 +2328,7 @@ static void __devinit cfg_queues(struct adapter *adapter) struct sge_eth_rxq *rxq = &s->ethrxq[qs]; struct sge_eth_txq *txq = &s->ethtxq[qs]; - init_rspq(&rxq->rspq, 0, 0, 1024, L1_CACHE_BYTES); + init_rspq(&rxq->rspq, 0, 0, 1024, iqe_size); rxq->fl.size = 72; txq->q.size = 1024; } @@ -2329,8 +2337,7 @@ static void __devinit cfg_queues(struct adapter *adapter) * The firmware event queue is used for link state changes and * notifications of TX DMA completions. */ - init_rspq(&s->fw_evtq, SGE_TIMER_RSTRT_CNTR, 0, 512, - L1_CACHE_BYTES); + init_rspq(&s->fw_evtq, SGE_TIMER_RSTRT_CNTR, 0, 512, iqe_size); /* * The forwarded interrupt queue is used when we're in MSI interrupt @@ -2346,7 +2353,7 @@ static void __devinit cfg_queues(struct adapter *adapter) * any time ... */ init_rspq(&s->intrq, SGE_TIMER_RSTRT_CNTR, 0, MSIX_ENTRIES + 1, - L1_CACHE_BYTES); + iqe_size); } /* -- cgit v1.2.3-59-g8ed1b From 4d7b6b5d247aa71ea27709b9eac1ba6e752fbe87 Mon Sep 17 00:00:00 2001 From: Ron Mercer Date: Sat, 11 Dec 2010 11:06:50 +0000 Subject: qlge: Fix deadlock when cancelling worker. Removing usage of rtnl_lock() to protect firmware interface registers. These registers are accessed in some worker threads and can create a deadlock if rtnl_lock is taken by upper layers while the worker is still pending. We remove rtnl_lock and use a driver mutex just while mailboxes are accessed. Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge.h | 1 + drivers/net/qlge/qlge_main.c | 1 + drivers/net/qlge/qlge_mpi.c | 12 ++++-------- 3 files changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h index 22821398fc63..9787dff90d3f 100644 --- a/drivers/net/qlge/qlge.h +++ b/drivers/net/qlge/qlge.h @@ -2083,6 +2083,7 @@ struct ql_adapter { u32 mailbox_in; u32 mailbox_out; struct mbox_params idc_mbc; + struct mutex mpi_mutex; int tx_ring_size; int rx_ring_size; diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 528eaef5308f..2555b1d34f34 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -4629,6 +4629,7 @@ static int __devinit ql_init_device(struct pci_dev *pdev, INIT_DELAYED_WORK(&qdev->mpi_idc_work, ql_mpi_idc_work); INIT_DELAYED_WORK(&qdev->mpi_core_to_log, ql_mpi_core_to_log); init_completion(&qdev->ide_completion); + mutex_init(&qdev->mpi_mutex); if (!cards_found) { dev_info(&pdev->dev, "%s\n", DRV_STRING); diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c index 0e7c7c7ee164..a2e919bcb3c6 100644 --- a/drivers/net/qlge/qlge_mpi.c +++ b/drivers/net/qlge/qlge_mpi.c @@ -534,6 +534,7 @@ static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp) int status; unsigned long count; + mutex_lock(&qdev->mpi_mutex); /* Begin polled mode for MPI */ ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16)); @@ -603,6 +604,7 @@ done: end: /* End polled mode for MPI */ ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI); + mutex_unlock(&qdev->mpi_mutex); return status; } @@ -1099,9 +1101,7 @@ int ql_wait_fifo_empty(struct ql_adapter *qdev) static int ql_set_port_cfg(struct ql_adapter *qdev) { int status; - rtnl_lock(); status = ql_mb_set_port_cfg(qdev); - rtnl_unlock(); if (status) return status; status = ql_idc_wait(qdev); @@ -1122,9 +1122,7 @@ void ql_mpi_port_cfg_work(struct work_struct *work) container_of(work, struct ql_adapter, mpi_port_cfg_work.work); int status; - rtnl_lock(); status = ql_mb_get_port_cfg(qdev); - rtnl_unlock(); if (status) { netif_err(qdev, drv, qdev->ndev, "Bug: Failed to get port config data.\n"); @@ -1167,7 +1165,6 @@ void ql_mpi_idc_work(struct work_struct *work) u32 aen; int timeout; - rtnl_lock(); aen = mbcp->mbox_out[1] >> 16; timeout = (mbcp->mbox_out[1] >> 8) & 0xf; @@ -1231,7 +1228,6 @@ void ql_mpi_idc_work(struct work_struct *work) } break; } - rtnl_unlock(); } void ql_mpi_work(struct work_struct *work) @@ -1242,7 +1238,7 @@ void ql_mpi_work(struct work_struct *work) struct mbox_params *mbcp = &mbc; int err = 0; - rtnl_lock(); + mutex_lock(&qdev->mpi_mutex); /* Begin polled mode for MPI */ ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16)); @@ -1259,7 +1255,7 @@ void ql_mpi_work(struct work_struct *work) /* End polled mode for MPI */ ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI); - rtnl_unlock(); + mutex_unlock(&qdev->mpi_mutex); ql_enable_completion_interrupt(qdev, 0); } -- cgit v1.2.3-59-g8ed1b From 099978b434d4924594516db540ccc50652e7cc94 Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Sun, 12 Dec 2010 04:11:45 +0000 Subject: bnx2x: LSO code was broken on BE platforms Make the LSO code work on BE platforms: parsing_data field of a parsing BD (PBD) for 57712 was improperly composed which made FW read wrong values for TCP header's length and offset and, as a result, the corresponding PCI device was performing bad DMA reads triggering EEH. Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 94d5f59d5a6f..0af361e4e3d1 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -1782,15 +1782,15 @@ exit_lbl: } #endif -static inline void bnx2x_set_pbd_gso_e2(struct sk_buff *skb, - struct eth_tx_parse_bd_e2 *pbd, - u32 xmit_type) +static inline void bnx2x_set_pbd_gso_e2(struct sk_buff *skb, u32 *parsing_data, + u32 xmit_type) { - pbd->parsing_data |= cpu_to_le16(skb_shinfo(skb)->gso_size) << - ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT; + *parsing_data |= (skb_shinfo(skb)->gso_size << + ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT) & + ETH_TX_PARSE_BD_E2_LSO_MSS; if ((xmit_type & XMIT_GSO_V6) && (ipv6_hdr(skb)->nexthdr == NEXTHDR_IPV6)) - pbd->parsing_data |= ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR; + *parsing_data |= ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR; } /** @@ -1835,15 +1835,15 @@ static inline void bnx2x_set_pbd_gso(struct sk_buff *skb, * @return header len */ static inline u8 bnx2x_set_pbd_csum_e2(struct bnx2x *bp, struct sk_buff *skb, - struct eth_tx_parse_bd_e2 *pbd, - u32 xmit_type) + u32 *parsing_data, u32 xmit_type) { - pbd->parsing_data |= cpu_to_le16(tcp_hdrlen(skb)/4) << - ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT; + *parsing_data |= ((tcp_hdrlen(skb)/4) << + ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT) & + ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW; - pbd->parsing_data |= cpu_to_le16(((unsigned char *)tcp_hdr(skb) - - skb->data) / 2) << - ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT; + *parsing_data |= ((((u8 *)tcp_hdr(skb) - skb->data) / 2) << + ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT) & + ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W; return skb_transport_header(skb) + tcp_hdrlen(skb) - skb->data; } @@ -1912,6 +1912,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) struct eth_tx_bd *tx_data_bd, *total_pkt_bd = NULL; struct eth_tx_parse_bd_e1x *pbd_e1x = NULL; struct eth_tx_parse_bd_e2 *pbd_e2 = NULL; + u32 pbd_e2_parsing_data = 0; u16 pkt_prod, bd_prod; int nbd, fp_index; dma_addr_t mapping; @@ -2033,8 +2034,9 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) memset(pbd_e2, 0, sizeof(struct eth_tx_parse_bd_e2)); /* Set PBD in checksum offload case */ if (xmit_type & XMIT_CSUM) - hlen = bnx2x_set_pbd_csum_e2(bp, - skb, pbd_e2, xmit_type); + hlen = bnx2x_set_pbd_csum_e2(bp, skb, + &pbd_e2_parsing_data, + xmit_type); } else { pbd_e1x = &fp->tx_desc_ring[bd_prod].parse_bd_e1x; memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x)); @@ -2076,10 +2078,18 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) bd_prod = bnx2x_tx_split(bp, fp, tx_buf, &tx_start_bd, hlen, bd_prod, ++nbd); if (CHIP_IS_E2(bp)) - bnx2x_set_pbd_gso_e2(skb, pbd_e2, xmit_type); + bnx2x_set_pbd_gso_e2(skb, &pbd_e2_parsing_data, + xmit_type); else bnx2x_set_pbd_gso(skb, pbd_e1x, xmit_type); } + + /* Set the PBD's parsing_data field if not zero + * (for the chips newer than 57711). + */ + if (pbd_e2_parsing_data) + pbd_e2->parsing_data = cpu_to_le32(pbd_e2_parsing_data); + tx_data_bd = (struct eth_tx_bd *)tx_start_bd; /* Handle fragmented skb */ -- cgit v1.2.3-59-g8ed1b From 372e43eb2fc34001250e27d63f99c20e46ea58a7 Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Sun, 12 Dec 2010 04:12:12 +0000 Subject: bnx2x: Fixed a compilation warning bnx2x_src_init_t2() is used only when BCM_CNIC is defined. So, to avoid a compilation warning, we won't define it unless BCM_CNIC is defined. Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_init_ops.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x_init_ops.h b/drivers/net/bnx2x/bnx2x_init_ops.h index a306b0e46b61..66df29fcf751 100644 --- a/drivers/net/bnx2x/bnx2x_init_ops.h +++ b/drivers/net/bnx2x/bnx2x_init_ops.h @@ -838,7 +838,7 @@ static void bnx2x_qm_init_ptr_table(struct bnx2x *bp, int qm_cid_count, /**************************************************************************** * SRC initializations ****************************************************************************/ - +#ifdef BCM_CNIC /* called during init func stage */ static void bnx2x_src_init_t2(struct bnx2x *bp, struct src_ent *t2, dma_addr_t t2_mapping, int src_cid_count) @@ -862,5 +862,5 @@ static void bnx2x_src_init_t2(struct bnx2x *bp, struct src_ent *t2, U64_HI((u64)t2_mapping + (src_cid_count-1) * sizeof(struct src_ent))); } - +#endif #endif /* BNX2X_INIT_OPS_H */ -- cgit v1.2.3-59-g8ed1b From 9f5449611c9d6d7bdcae8020a197d8b4d9b6443c Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Sun, 12 Dec 2010 04:12:29 +0000 Subject: bnx2x: Advance a version number to 1.60.01-0 Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 863e73a85fbe..d255428122fc 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -20,8 +20,8 @@ * (you will need to reboot afterwards) */ /* #define BNX2X_STOP_ON_ERROR */ -#define DRV_MODULE_VERSION "1.60.00-4" -#define DRV_MODULE_RELDATE "2010/11/01" +#define DRV_MODULE_VERSION "1.60.01-0" +#define DRV_MODULE_RELDATE "2010/11/12" #define BNX2X_BC_VER 0x040200 #define BNX2X_MULTI_QUEUE -- cgit v1.2.3-59-g8ed1b From eaff9453d3e2b63969af93e9d42a85e803060121 Mon Sep 17 00:00:00 2001 From: Krzysztof Halasa Date: Sun, 12 Dec 2010 12:06:47 +0000 Subject: WAN: Fix a TX IRQ causing BUG() in PC300 and PCI200SYN drivers. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We must not wake the TX queue without free TX descriptors. sca_xmit() expects at least one free descriptor and BUGs otherwise. Problem reported and fix tested by Bernie Innocenti and Ward Vandewege. Signed-off-by: Krzysztof Hałasa Signed-off-by: David S. Miller --- drivers/net/wan/hd64572.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wan/hd64572.c b/drivers/net/wan/hd64572.c index ea476cbd38b5..e305274f83fb 100644 --- a/drivers/net/wan/hd64572.c +++ b/drivers/net/wan/hd64572.c @@ -293,6 +293,7 @@ static inline void sca_tx_done(port_t *port) struct net_device *dev = port->netdev; card_t* card = port->card; u8 stat; + unsigned count = 0; spin_lock(&port->lock); @@ -316,10 +317,12 @@ static inline void sca_tx_done(port_t *port) dev->stats.tx_bytes += readw(&desc->len); } writeb(0, &desc->stat); /* Free descriptor */ + count++; port->txlast = (port->txlast + 1) % card->tx_ring_buffers; } - netif_wake_queue(dev); + if (count) + netif_wake_queue(dev); spin_unlock(&port->lock); } -- cgit v1.2.3-59-g8ed1b From 2a27a03d3a891e87ca33d27a858b4db734a4cbab Mon Sep 17 00:00:00 2001 From: Andrej Ota Date: Sun, 12 Dec 2010 15:06:16 -0800 Subject: pppoe.c: Fix kernel panic caused by __pppoe_xmit __pppoe_xmit function return value was invalid resulting in additional call to kfree_skb on already freed skb. This resulted in memory corruption and consequent kernel panic after PPPoE peer terminated the link. This fixes commit 55c95e738da85373965cb03b4f975d0fd559865b. Reported-by: Gorik Van Steenberge Reported-by: Daniel Kenzelmann Reported-by: Denys Fedoryshchenko Reported-by: Pawel Staszewski Diagnosed-by: Andrej Ota Diagnosed-by: Eric Dumazet Tested-by: Denys Fedoryshchenko Tested-by: Pawel Staszewski Signed-off-by: Jarek Poplawski Signed-off-by: Andrej Ota Signed-off-by: David S. Miller --- drivers/net/pppoe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index d72fb0519a2a..78c0e3c9b2b5 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c @@ -948,7 +948,7 @@ static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb) abort: kfree_skb(skb); - return 0; + return 1; } /************************************************************************ -- cgit v1.2.3-59-g8ed1b From 4a55d5852adbe66722fb1636c82c7864cd5be441 Mon Sep 17 00:00:00 2001 From: Sven Neumann Date: Thu, 9 Dec 2010 09:38:36 +0100 Subject: libertas: fix potential NULL-pointer dereference The code wants to check if there's a channel and it is not disabled, but it used to check if channel is not NULL and accessed the channel struct if this check failed. Signed-off-by: Sven Neumann Acked-by: Dan Williams Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/cfg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 373930afc26b..113f4f204657 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c @@ -619,7 +619,7 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, print_ssid(ssid_buf, ssid, ssid_len), LBS_SCAN_RSSI_TO_MBM(rssi)/100); - if (channel || + if (channel && !(channel->flags & IEEE80211_CHAN_DISABLED)) cfg80211_inform_bss(wiphy, channel, bssid, le64_to_cpu(*(__le64 *)tsfdesc), -- cgit v1.2.3-59-g8ed1b From 16cad7fba037b34ca32cc0adac65bc089d969fb8 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 11 Dec 2010 12:19:48 +0100 Subject: p54usb: add 5 more USBIDs This patch adds five more USBIDs to the table. Source: http://www.linuxant.com/pipermail/driverloader/2005q3/002307.html http://wireless.kernel.org/en/users/Drivers/p54/devices (by M. Davis) Cc: Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54usb.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index d5bc21e5a02c..610aafe207a3 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c @@ -43,6 +43,7 @@ MODULE_FIRMWARE("isl3887usb"); static struct usb_device_id p54u_table[] __devinitdata = { /* Version 1 devices (pci chip + net2280) */ + {USB_DEVICE(0x0411, 0x0050)}, /* Buffalo WLI2-USB2-G54 */ {USB_DEVICE(0x045e, 0x00c2)}, /* Microsoft MN-710 */ {USB_DEVICE(0x0506, 0x0a11)}, /* 3COM 3CRWE254G72 */ {USB_DEVICE(0x06b9, 0x0120)}, /* Thomson SpeedTouch 120g */ @@ -56,9 +57,12 @@ static struct usb_device_id p54u_table[] __devinitdata = { {USB_DEVICE(0x0846, 0x4220)}, /* Netgear WG111 */ {USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */ {USB_DEVICE(0x0cde, 0x0006)}, /* Medion 40900, Roper Europe */ + {USB_DEVICE(0x0db0, 0x6826)}, /* MSI UB54G (MS-6826) */ {USB_DEVICE(0x107b, 0x55f2)}, /* Gateway WGU-210 (Gemtek) */ {USB_DEVICE(0x124a, 0x4023)}, /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */ + {USB_DEVICE(0x1435, 0x0210)}, /* Inventel UR054G */ {USB_DEVICE(0x1630, 0x0005)}, /* 2Wire 802.11g USB (v1) / Z-Com */ + {USB_DEVICE(0x182d, 0x096b)}, /* Sitecom WL-107 */ {USB_DEVICE(0x1915, 0x2234)}, /* Linksys WUSB54G OEM */ {USB_DEVICE(0x1915, 0x2235)}, /* Linksys WUSB54G Portable OEM */ {USB_DEVICE(0x2001, 0x3701)}, /* DLink DWL-G120 Spinnaker */ @@ -94,6 +98,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */ {USB_DEVICE(0x1668, 0x1050)}, /* Actiontec 802UIG-1 */ {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */ + {USB_DEVICE(0x2001, 0x3705)}, /* D-Link DWL-G120 rev C1 */ {USB_DEVICE(0x413c, 0x5513)}, /* Dell WLA3310 USB Wireless Adapter */ {USB_DEVICE(0x413c, 0x8102)}, /* Spinnaker DUT */ {USB_DEVICE(0x413c, 0x8104)}, /* Cohiba Proto board */ -- cgit v1.2.3-59-g8ed1b From 56e6417b49132d4f56e9f2241d31942b90b46315 Mon Sep 17 00:00:00 2001 From: Eduardo Costa Date: Tue, 14 Dec 2010 14:37:59 -0600 Subject: p54usb: New USB ID for Gemtek WUBI-100GW This USB ID is for the WUBI-100GW 802.11g Wireless LAN USB Device that uses p54usb. Signed-off-by: Larry Finger Signed-off-by: Eduardo Costa Cc: Stable Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54usb.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index 610aafe207a3..2325e56a9b0b 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c @@ -61,6 +61,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { {USB_DEVICE(0x107b, 0x55f2)}, /* Gateway WGU-210 (Gemtek) */ {USB_DEVICE(0x124a, 0x4023)}, /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */ {USB_DEVICE(0x1435, 0x0210)}, /* Inventel UR054G */ + {USB_DEVICE(0x15a9, 0x0002)}, /* Gemtek WUBI-100GW 802.11g */ {USB_DEVICE(0x1630, 0x0005)}, /* 2Wire 802.11g USB (v1) / Z-Com */ {USB_DEVICE(0x182d, 0x096b)}, /* Sitecom WL-107 */ {USB_DEVICE(0x1915, 0x2234)}, /* Linksys WUSB54G OEM */ -- cgit v1.2.3-59-g8ed1b From af3e5bd5f650163c2e12297f572910a1af1b8236 Mon Sep 17 00:00:00 2001 From: Hillf Danton Date: Fri, 10 Dec 2010 18:54:11 +0000 Subject: bonding: Fix slave selection bug. The returned slave is incorrect, if the net device under check is not charged yet by the master. Signed-off-by: Hillf Danton Signed-off-by: David S. Miller --- drivers/net/bonding/bonding.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index c2f081352a03..4feeb2d650a4 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -269,11 +269,11 @@ static inline struct slave *bond_get_slave_by_dev(struct bonding *bond, struct n bond_for_each_slave(bond, slave, i) { if (slave->dev == slave_dev) { - break; + return slave; } } - return slave; + return 0; } static inline struct bonding *bond_get_bond_by_slave(struct slave *slave) -- cgit v1.2.3-59-g8ed1b From 42dccd1f757d674a6604077a61d1577d1578c755 Mon Sep 17 00:00:00 2001 From: Ken Kawasaki Date: Mon, 13 Dec 2010 02:27:24 +0000 Subject: axnet_cs: move id (0x1bf, 0x2328) to axnet_cs axnet_cs: Accton EN2328 or compatible (id: 0x01bf, 0x2328) uses Asix chip. So it works better with axnet_cs instead of pcnet_cs. Signed-off-by: Ken Kawasaki Signed-off-by: David S. Miller --- drivers/net/pcmcia/axnet_cs.c | 1 + drivers/net/pcmcia/pcnet_cs.c | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index 8a4d19e5de06..f1047dd8a526 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c @@ -690,6 +690,7 @@ static void block_output(struct net_device *dev, int count, static struct pcmcia_device_id axnet_ids[] = { PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x016c, 0x0081), PCMCIA_DEVICE_MANF_CARD(0x018a, 0x0301), + PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x2328), PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0301), PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0303), PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0309), diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index d05c44692f08..2c158910f7ea 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -1493,7 +1493,6 @@ static struct pcmcia_device_id pcnet_ids[] = { PCMCIA_DEVICE_MANF_CARD(0x0149, 0x4530), PCMCIA_DEVICE_MANF_CARD(0x0149, 0xc1ab), PCMCIA_DEVICE_MANF_CARD(0x0186, 0x0110), - PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x2328), PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x8041), PCMCIA_DEVICE_MANF_CARD(0x0213, 0x2452), PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0300), -- cgit v1.2.3-59-g8ed1b From 8387451e558853f7b513790c0070e3b6f0c135aa Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 13 Dec 2010 08:19:28 +0000 Subject: bonding/vlan: Remove redundant VLAN tag insertion logic A bond may have a mixture of slave devices with and without hardware VLAN tag insertion capability. Therefore it always claims this capability and performs software VLAN tag insertion if the slave does not. Since commit 7b9c60903714bf0a19d746b228864bad3497284e, this has also been done by dev_hard_start_xmit(). The result is that VLAN- tagged skbs are now double-tagged when transmitted through slave devices without hardware VLAN tag insertion! Remove the now-redundant logic from bond_dev_queue_xmit(). Signed-off-by: Ben Hutchings Signed-off-by: Jay Vosburgh Reviewed-by: Jesse Gross Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index d0ea760ce419..ef370c923341 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -418,36 +418,11 @@ struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr) * @bond: bond device that got this skb for tx. * @skb: hw accel VLAN tagged skb to transmit * @slave_dev: slave that is supposed to xmit this skbuff - * - * When the bond gets an skb to transmit that is - * already hardware accelerated VLAN tagged, and it - * needs to relay this skb to a slave that is not - * hw accel capable, the skb needs to be "unaccelerated", - * i.e. strip the hwaccel tag and re-insert it as part - * of the payload. */ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev) { - unsigned short uninitialized_var(vlan_id); - - /* Test vlan_list not vlgrp to catch and handle 802.1p tags */ - if (!list_empty(&bond->vlan_list) && - !(slave_dev->features & NETIF_F_HW_VLAN_TX) && - vlan_get_tag(skb, &vlan_id) == 0) { - skb->dev = slave_dev; - skb = vlan_put_tag(skb, vlan_id); - if (!skb) { - /* vlan_put_tag() frees the skb in case of error, - * so return success here so the calling functions - * won't attempt to free is again. - */ - return 0; - } - } else { - skb->dev = slave_dev; - } - + skb->dev = slave_dev; skb->priority = 1; #ifdef CONFIG_NET_POLL_CONTROLLER if (unlikely(bond->dev->priv_flags & IFF_IN_NETPOLL)) { -- cgit v1.2.3-59-g8ed1b From ffa95ed50f9fb2d8faaa6bd73086a7056ea46a06 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 13 Dec 2010 08:19:56 +0000 Subject: bonding: Change active slave quietly when bond is down bond_change_active_slave() may be called when a slave is added, even if the bond has not been brought up yet. It may then attempt to send packets, and further it may use mcast_work which is uninitialised before the bond is brought up. Add the necessary checks for netif_running(bond->dev). Signed-off-by: Ben Hutchings Signed-off-by: Jay Vosburgh Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index ef370c923341..3b16c34ed86e 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1178,11 +1178,13 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) bond_do_fail_over_mac(bond, new_active, old_active); - bond->send_grat_arp = bond->params.num_grat_arp; - bond_send_gratuitous_arp(bond); + if (netif_running(bond->dev)) { + bond->send_grat_arp = bond->params.num_grat_arp; + bond_send_gratuitous_arp(bond); - bond->send_unsol_na = bond->params.num_unsol_na; - bond_send_unsolicited_na(bond); + bond->send_unsol_na = bond->params.num_unsol_na; + bond_send_unsolicited_na(bond); + } write_unlock_bh(&bond->curr_slave_lock); read_unlock(&bond->lock); @@ -1196,8 +1198,9 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) /* resend IGMP joins since active slave has changed or * all were sent on curr_active_slave */ - if ((USES_PRIMARY(bond->params.mode) && new_active) || - bond->params.mode == BOND_MODE_ROUNDROBIN) { + if (((USES_PRIMARY(bond->params.mode) && new_active) || + bond->params.mode == BOND_MODE_ROUNDROBIN) && + netif_running(bond->dev)) { bond->igmp_retrans = bond->params.resend_igmp; queue_delayed_work(bond->wq, &bond->mcast_work, 0); } -- cgit v1.2.3-59-g8ed1b From f88a4a9b65a6f3422b81be995535d0e69df11bb8 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 13 Dec 2010 08:20:24 +0000 Subject: bonding/vlan: Fix mangled NAs on slaves without VLAN tag insertion bond_na_send() attempts to insert a VLAN tag in between building and sending packets of the respective formats. If the slave does not implement hardware VLAN tag insertion then vlan_put_tag() will mangle the network-layer header because the Ethernet header is not present at this point (unlike in bond_arp_send()). Fix this by adding the tag out-of-line and relying on dev_hard_start_xmit() to insert it inline if necessary. Signed-off-by: Ben Hutchings Signed-off-by: Jay Vosburgh Reviewed-by: Jesse Gross Signed-off-by: David S. Miller --- drivers/net/bonding/bond_ipv6.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/bonding/bond_ipv6.c b/drivers/net/bonding/bond_ipv6.c index 121b073a6c3f..84fbd4ebd778 100644 --- a/drivers/net/bonding/bond_ipv6.c +++ b/drivers/net/bonding/bond_ipv6.c @@ -88,7 +88,12 @@ static void bond_na_send(struct net_device *slave_dev, } if (vlan_id) { - skb = vlan_put_tag(skb, vlan_id); + /* The Ethernet header is not present yet, so it is + * too early to insert a VLAN tag. Force use of an + * out-of-line tag here and let dev_hard_start_xmit() + * insert it if the slave hardware can't. + */ + skb = __vlan_hwaccel_put_tag(skb, vlan_id); if (!skb) { pr_err("failed to insert VLAN tag\n"); return; -- cgit v1.2.3-59-g8ed1b From 2984961c388381c1830f95e1c2dc2137301b1009 Mon Sep 17 00:00:00 2001 From: Ivan Vecera Date: Tue, 14 Dec 2010 05:43:19 +0000 Subject: be2net: use mutex instead of spin lock for mbox_lock Since the mbox polling uses the schedule_timeout, the mbox_lock should be a mutex and not a spin lock. The commit f25b03a replaced udelay() with schedule_timeout() but didn't change mbox_lock to semaphore or mutex. Signed-off-by: Ivan Vecera Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 2 +- drivers/net/benet/be_cmds.c | 75 +++++++++++++++++++++++++++------------------ drivers/net/benet/be_main.c | 2 +- 3 files changed, 47 insertions(+), 32 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 4594a28b1f66..d64313b7090e 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -234,7 +234,7 @@ struct be_adapter { u8 __iomem *db; /* Door Bell */ u8 __iomem *pcicfg; /* PCI config space */ - spinlock_t mbox_lock; /* For serializing mbox cmds to BE card */ + struct mutex mbox_lock; /* For serializing mbox cmds to BE card */ struct be_dma_mem mbox_mem; /* Mbox mem is adjusted to align to 16 bytes. The allocated addr * is stored for freeing purpose */ diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index e4465d222a7d..1c8c79c9d214 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -462,7 +462,8 @@ int be_cmd_fw_init(struct be_adapter *adapter) u8 *wrb; int status; - spin_lock(&adapter->mbox_lock); + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; wrb = (u8 *)wrb_from_mbox(adapter); *wrb++ = 0xFF; @@ -476,7 +477,7 @@ int be_cmd_fw_init(struct be_adapter *adapter) status = be_mbox_notify_wait(adapter); - spin_unlock(&adapter->mbox_lock); + mutex_unlock(&adapter->mbox_lock); return status; } @@ -491,7 +492,8 @@ int be_cmd_fw_clean(struct be_adapter *adapter) if (adapter->eeh_err) return -EIO; - spin_lock(&adapter->mbox_lock); + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; wrb = (u8 *)wrb_from_mbox(adapter); *wrb++ = 0xFF; @@ -505,7 +507,7 @@ int be_cmd_fw_clean(struct be_adapter *adapter) status = be_mbox_notify_wait(adapter); - spin_unlock(&adapter->mbox_lock); + mutex_unlock(&adapter->mbox_lock); return status; } int be_cmd_eq_create(struct be_adapter *adapter, @@ -516,7 +518,8 @@ int be_cmd_eq_create(struct be_adapter *adapter, struct be_dma_mem *q_mem = &eq->dma_mem; int status; - spin_lock(&adapter->mbox_lock); + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; wrb = wrb_from_mbox(adapter); req = embedded_payload(wrb); @@ -546,7 +549,7 @@ int be_cmd_eq_create(struct be_adapter *adapter, eq->created = true; } - spin_unlock(&adapter->mbox_lock); + mutex_unlock(&adapter->mbox_lock); return status; } @@ -558,7 +561,8 @@ int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, struct be_cmd_req_mac_query *req; int status; - spin_lock(&adapter->mbox_lock); + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; wrb = wrb_from_mbox(adapter); req = embedded_payload(wrb); @@ -583,7 +587,7 @@ int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, memcpy(mac_addr, resp->mac.addr, ETH_ALEN); } - spin_unlock(&adapter->mbox_lock); + mutex_unlock(&adapter->mbox_lock); return status; } @@ -667,7 +671,8 @@ int be_cmd_cq_create(struct be_adapter *adapter, void *ctxt; int status; - spin_lock(&adapter->mbox_lock); + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; wrb = wrb_from_mbox(adapter); req = embedded_payload(wrb); @@ -701,7 +706,7 @@ int be_cmd_cq_create(struct be_adapter *adapter, cq->created = true; } - spin_unlock(&adapter->mbox_lock); + mutex_unlock(&adapter->mbox_lock); return status; } @@ -724,7 +729,8 @@ int be_cmd_mccq_create(struct be_adapter *adapter, void *ctxt; int status; - spin_lock(&adapter->mbox_lock); + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; wrb = wrb_from_mbox(adapter); req = embedded_payload(wrb); @@ -754,7 +760,7 @@ int be_cmd_mccq_create(struct be_adapter *adapter, mccq->id = le16_to_cpu(resp->id); mccq->created = true; } - spin_unlock(&adapter->mbox_lock); + mutex_unlock(&adapter->mbox_lock); return status; } @@ -769,7 +775,8 @@ int be_cmd_txq_create(struct be_adapter *adapter, void *ctxt; int status; - spin_lock(&adapter->mbox_lock); + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; wrb = wrb_from_mbox(adapter); req = embedded_payload(wrb); @@ -801,7 +808,7 @@ int be_cmd_txq_create(struct be_adapter *adapter, txq->created = true; } - spin_unlock(&adapter->mbox_lock); + mutex_unlock(&adapter->mbox_lock); return status; } @@ -816,7 +823,8 @@ int be_cmd_rxq_create(struct be_adapter *adapter, struct be_dma_mem *q_mem = &rxq->dma_mem; int status; - spin_lock(&adapter->mbox_lock); + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; wrb = wrb_from_mbox(adapter); req = embedded_payload(wrb); @@ -843,7 +851,7 @@ int be_cmd_rxq_create(struct be_adapter *adapter, *rss_id = resp->rss_id; } - spin_unlock(&adapter->mbox_lock); + mutex_unlock(&adapter->mbox_lock); return status; } @@ -862,7 +870,8 @@ int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q, if (adapter->eeh_err) return -EIO; - spin_lock(&adapter->mbox_lock); + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; wrb = wrb_from_mbox(adapter); req = embedded_payload(wrb); @@ -899,7 +908,7 @@ int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q, status = be_mbox_notify_wait(adapter); - spin_unlock(&adapter->mbox_lock); + mutex_unlock(&adapter->mbox_lock); return status; } @@ -915,7 +924,8 @@ int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags, struct be_cmd_req_if_create *req; int status; - spin_lock(&adapter->mbox_lock); + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; wrb = wrb_from_mbox(adapter); req = embedded_payload(wrb); @@ -941,7 +951,7 @@ int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags, *pmac_id = le32_to_cpu(resp->pmac_id); } - spin_unlock(&adapter->mbox_lock); + mutex_unlock(&adapter->mbox_lock); return status; } @@ -955,7 +965,8 @@ int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id) if (adapter->eeh_err) return -EIO; - spin_lock(&adapter->mbox_lock); + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; wrb = wrb_from_mbox(adapter); req = embedded_payload(wrb); @@ -970,7 +981,7 @@ int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id) status = be_mbox_notify_wait(adapter); - spin_unlock(&adapter->mbox_lock); + mutex_unlock(&adapter->mbox_lock); return status; } @@ -1060,7 +1071,8 @@ int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver) struct be_cmd_req_get_fw_version *req; int status; - spin_lock(&adapter->mbox_lock); + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; wrb = wrb_from_mbox(adapter); req = embedded_payload(wrb); @@ -1077,7 +1089,7 @@ int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver) strncpy(fw_ver, resp->firmware_version_string, FW_VER_LEN); } - spin_unlock(&adapter->mbox_lock); + mutex_unlock(&adapter->mbox_lock); return status; } @@ -1322,7 +1334,8 @@ int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num, struct be_cmd_req_query_fw_cfg *req; int status; - spin_lock(&adapter->mbox_lock); + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; wrb = wrb_from_mbox(adapter); req = embedded_payload(wrb); @@ -1341,7 +1354,7 @@ int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num, *caps = le32_to_cpu(resp->function_caps); } - spin_unlock(&adapter->mbox_lock); + mutex_unlock(&adapter->mbox_lock); return status; } @@ -1352,7 +1365,8 @@ int be_cmd_reset_function(struct be_adapter *adapter) struct be_cmd_req_hdr *req; int status; - spin_lock(&adapter->mbox_lock); + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; wrb = wrb_from_mbox(adapter); req = embedded_payload(wrb); @@ -1365,7 +1379,7 @@ int be_cmd_reset_function(struct be_adapter *adapter) status = be_mbox_notify_wait(adapter); - spin_unlock(&adapter->mbox_lock); + mutex_unlock(&adapter->mbox_lock); return status; } @@ -1376,7 +1390,8 @@ int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable, u16 table_size) u32 myhash[10]; int status; - spin_lock(&adapter->mbox_lock); + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; wrb = wrb_from_mbox(adapter); req = embedded_payload(wrb); @@ -1396,7 +1411,7 @@ int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable, u16 table_size) status = be_mbox_notify_wait(adapter); - spin_unlock(&adapter->mbox_lock); + mutex_unlock(&adapter->mbox_lock); return status; } diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 93354eee2cfd..fd251b59b7f9 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -2677,7 +2677,7 @@ static int be_ctrl_init(struct be_adapter *adapter) } memset(mc_cmd_mem->va, 0, mc_cmd_mem->size); - spin_lock_init(&adapter->mbox_lock); + mutex_init(&adapter->mbox_lock); spin_lock_init(&adapter->mcc_lock); spin_lock_init(&adapter->mcc_cq_lock); -- cgit v1.2.3-59-g8ed1b From 0b7967503dc97864f283a3a06fbe23e041876138 Mon Sep 17 00:00:00 2001 From: Michał Mirosław Date: Tue, 14 Dec 2010 12:35:13 +0000 Subject: net/veth: Fix packet checksumming MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We can't change ip_summed from CHECKSUM_PARTIAL to CHECKSUM_NONE or CHECKSUM_UNNECESSARY because checksum in packet's headers is not valid and will cause invalid checksum when frame is forwarded. Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/veth.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 0bbc0c323135..cc83fa71c3ff 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -166,7 +166,9 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev) if (!(rcv->flags & IFF_UP)) goto tx_drop; - if (dev->features & NETIF_F_NO_CSUM) + /* don't change ip_summed == CHECKSUM_PARTIAL, as that + will cause bad checksum on forwarded packets */ + if (skb->ip_summed == CHECKSUM_NONE) skb->ip_summed = rcv_priv->ip_summed; length = skb->len + ETH_HLEN; -- cgit v1.2.3-59-g8ed1b From 46814e08d80f87449b5adb3d549a3cae6f9f8148 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 17 Dec 2010 10:16:23 -0800 Subject: tehuti: Firmware filename is tehuti/bdx.bin My conversion of tehuti to use request_firmware() was confused about the filename of the firmware blob. Change the driver to match the blob. Signed-off-by: Ben Hutchings Signed-off-by: Andy Gospodarek Signed-off-by: David S. Miller --- drivers/net/tehuti.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c index 8b3dc1eb4015..296000bf5a25 100644 --- a/drivers/net/tehuti.c +++ b/drivers/net/tehuti.c @@ -324,7 +324,7 @@ static int bdx_fw_load(struct bdx_priv *priv) ENTER; master = READ_REG(priv, regINIT_SEMAPHORE); if (!READ_REG(priv, regINIT_STATUS) && master) { - rc = request_firmware(&fw, "tehuti/firmware.bin", &priv->pdev->dev); + rc = request_firmware(&fw, "tehuti/bdx.bin", &priv->pdev->dev); if (rc) goto out; bdx_tx_push_desc_safe(priv, (char *)fw->data, fw->size); @@ -2510,4 +2510,4 @@ module_exit(bdx_module_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(BDX_DRV_DESC); -MODULE_FIRMWARE("tehuti/firmware.bin"); +MODULE_FIRMWARE("tehuti/bdx.bin"); -- cgit v1.2.3-59-g8ed1b From f4680d3db71f13d2764340a9880745bf54f2469d Mon Sep 17 00:00:00 2001 From: Arnaud Ebalard Date: Wed, 15 Dec 2010 12:16:30 +0000 Subject: asix: add USB ID for Logitec LAN-GTJ U2A Logitec LAN-GTJ U2A (http://www.pro.logitec.co.jp/pro/g/gLAN-GTJU2A/) USB 2.0 10/10/1000 Ethernet adapter is based on ASIX AX88178 chipset. This patch adds missing USB ID for the device. Signed-off-by: Arnaud Ebalard Signed-off-by: David S. Miller --- drivers/net/usb/asix.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index aea4645be7f6..6140b56cce53 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -1507,6 +1507,10 @@ static const struct usb_device_id products [] = { // ASIX AX88178 10/100/1000 USB_DEVICE (0x0b95, 0x1780), .driver_info = (unsigned long) &ax88178_info, +}, { + // Logitec LAN-GTJ/U2A + USB_DEVICE (0x0789, 0x0160), + .driver_info = (unsigned long) &ax88178_info, }, { // Linksys USB200M Rev 2 USB_DEVICE (0x13b1, 0x0018), -- cgit v1.2.3-59-g8ed1b