From bc5892c9ec250b36c9287bd52a74d08d75a40152 Mon Sep 17 00:00:00 2001 From: Chaoming Li Date: Fri, 21 Jan 2011 13:57:37 -0600 Subject: rtlwifi: Fix firmware upload errors When the source code from Realtek was prepared for kernel inclusion, some routines were refactored to reduce the level of indentation. This patch repairs errors introduced in that process. Signed-off-by: Chaoming Li Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/efuse.c | 40 ++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c index b8433f3a9bc2..62876cd5c41a 100644 --- a/drivers/net/wireless/rtlwifi/efuse.c +++ b/drivers/net/wireless/rtlwifi/efuse.c @@ -726,9 +726,9 @@ static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data) } static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, - u8 efuse_data, u8 offset, int *bcontinual, - u8 *write_state, struct pgpkt_struct target_pkt, - int *repeat_times, int *bresult, u8 word_en) + u8 efuse_data, u8 offset, int *bcontinual, + u8 *write_state, struct pgpkt_struct *target_pkt, + int *repeat_times, int *bresult, u8 word_en) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct pgpkt_struct tmp_pkt; @@ -744,8 +744,8 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, tmp_pkt.word_en = tmp_header & 0x0F; tmp_word_cnts = efuse_calculate_word_cnts(tmp_pkt.word_en); - if (tmp_pkt.offset != target_pkt.offset) { - efuse_addr = efuse_addr + (tmp_word_cnts * 2) + 1; + if (tmp_pkt.offset != target_pkt->offset) { + *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1; *write_state = PG_STATE_HEADER; } else { for (tmpindex = 0; tmpindex < (tmp_word_cnts * 2); tmpindex++) { @@ -756,23 +756,23 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, } if (bdataempty == false) { - efuse_addr = efuse_addr + (tmp_word_cnts * 2) + 1; + *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1; *write_state = PG_STATE_HEADER; } else { match_word_en = 0x0F; - if (!((target_pkt.word_en & BIT(0)) | + if (!((target_pkt->word_en & BIT(0)) | (tmp_pkt.word_en & BIT(0)))) match_word_en &= (~BIT(0)); - if (!((target_pkt.word_en & BIT(1)) | + if (!((target_pkt->word_en & BIT(1)) | (tmp_pkt.word_en & BIT(1)))) match_word_en &= (~BIT(1)); - if (!((target_pkt.word_en & BIT(2)) | + if (!((target_pkt->word_en & BIT(2)) | (tmp_pkt.word_en & BIT(2)))) match_word_en &= (~BIT(2)); - if (!((target_pkt.word_en & BIT(3)) | + if (!((target_pkt->word_en & BIT(3)) | (tmp_pkt.word_en & BIT(3)))) match_word_en &= (~BIT(3)); @@ -780,7 +780,7 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, badworden = efuse_word_enable_data_write( hw, *efuse_addr + 1, tmp_pkt.word_en, - target_pkt.data); + target_pkt->data); if (0x0F != (badworden & 0x0F)) { u8 reorg_offset = offset; @@ -791,26 +791,26 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, } tmp_word_en = 0x0F; - if ((target_pkt.word_en & BIT(0)) ^ + if ((target_pkt->word_en & BIT(0)) ^ (match_word_en & BIT(0))) tmp_word_en &= (~BIT(0)); - if ((target_pkt.word_en & BIT(1)) ^ + if ((target_pkt->word_en & BIT(1)) ^ (match_word_en & BIT(1))) tmp_word_en &= (~BIT(1)); - if ((target_pkt.word_en & BIT(2)) ^ + if ((target_pkt->word_en & BIT(2)) ^ (match_word_en & BIT(2))) tmp_word_en &= (~BIT(2)); - if ((target_pkt.word_en & BIT(3)) ^ + if ((target_pkt->word_en & BIT(3)) ^ (match_word_en & BIT(3))) tmp_word_en &= (~BIT(3)); if ((tmp_word_en & 0x0F) != 0x0F) { *efuse_addr = efuse_get_current_size(hw); - target_pkt.offset = offset; - target_pkt.word_en = tmp_word_en; + target_pkt->offset = offset; + target_pkt->word_en = tmp_word_en; } else *bcontinual = false; *write_state = PG_STATE_HEADER; @@ -821,8 +821,8 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, } } else { *efuse_addr += (2 * tmp_word_cnts) + 1; - target_pkt.offset = offset; - target_pkt.word_en = word_en; + target_pkt->offset = offset; + target_pkt->word_en = word_en; *write_state = PG_STATE_HEADER; } } @@ -938,7 +938,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, efuse_write_data_case1(hw, &efuse_addr, efuse_data, offset, &bcontinual, - &write_state, target_pkt, + &write_state, &target_pkt, &repeat_times, &bresult, word_en); else -- cgit v1.2.3 From 15411c27d203e363592d30ab00803254ebe77b90 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Mon, 24 Jan 2011 23:31:43 -0500 Subject: ath5k: fix error handling in ath5k_hw_dma_stop Review spotted a problem with the error handling in ath5k_hw_dma_stop: a successful return from ath5k_hw_stop_tx_dma will be treated as an error, so we always bail out of the loop after processing a single active queue. As a result, we may not actually stop some queues during reset. Signed-off-by: Bob Copeland Acked-by: Bruno Randolf Acked-by: Nick Kossifidis Reviewed-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/dma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c index 0064be7ce5c9..21091c26a9a5 100644 --- a/drivers/net/wireless/ath/ath5k/dma.c +++ b/drivers/net/wireless/ath/ath5k/dma.c @@ -838,9 +838,9 @@ int ath5k_hw_dma_stop(struct ath5k_hw *ah) for (i = 0; i < qmax; i++) { err = ath5k_hw_stop_tx_dma(ah, i); /* -EINVAL -> queue inactive */ - if (err != -EINVAL) + if (err && err != -EINVAL) return err; } - return err; + return 0; } -- cgit v1.2.3 From c9234a662e38309d6fe272ad80e6cdb8d24654f0 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Mon, 24 Jan 2011 23:31:44 -0500 Subject: ath5k: correct endianness of frame duration The ath5k version of ieee80211_generic_frame_duration() returns an __le16 for standard modes but a cpu-endian int for turbo/half/ quarter rates. Make it always return cpu-endian values. Signed-off-by: Bob Copeland Acked-by: Bruno Randolf Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/pcu.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index e5f2b96a4c63..a702817daf72 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c @@ -86,7 +86,7 @@ int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, if (!ah->ah_bwmode) { dur = ieee80211_generic_frame_duration(sc->hw, NULL, len, rate); - return dur; + return le16_to_cpu(dur); } bitrate = rate->bitrate; @@ -265,8 +265,6 @@ static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah) * what rate we should choose to TX ACKs. */ tx_time = ath5k_hw_get_frame_duration(ah, 10, rate); - tx_time = le16_to_cpu(tx_time); - ath5k_hw_reg_write(ah, tx_time, reg); if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)) -- cgit v1.2.3 From 203043f579ece44bb30291442cd56332651dd37d Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 25 Jan 2011 14:08:40 +0100 Subject: ath9k: fix race conditions when stop device We do not kill any scheduled tasklets when stopping device, that may cause usage of resources after free. Moreover we enable interrupts in tasklet function, so we could potentially end with interrupts enabled when driver is not ready to receive them. I think patch should fix Ben's kernel crash from: http://marc.info/?l=linux-wireless&m=129438358921501&w=2 Cc: stable@kernel.org Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/init.c | 5 ----- drivers/net/wireless/ath/ath9k/main.c | 9 +++++++++ 2 files changed, 9 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 767d8b86f1e1..b3254a3484a5 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -598,8 +598,6 @@ err_btcoex: err_queues: ath9k_hw_deinit(ah); err_hw: - tasklet_kill(&sc->intr_tq); - tasklet_kill(&sc->bcon_tasklet); kfree(ah); sc->sc_ah = NULL; @@ -807,9 +805,6 @@ static void ath9k_deinit_softc(struct ath_softc *sc) ath9k_hw_deinit(sc->sc_ah); - tasklet_kill(&sc->intr_tq); - tasklet_kill(&sc->bcon_tasklet); - kfree(sc->sc_ah); sc->sc_ah = NULL; } diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index c79c97be6cd4..ace9f066fa20 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1309,6 +1309,9 @@ static void ath9k_stop(struct ieee80211_hw *hw) spin_lock_bh(&sc->sc_pcu_lock); + /* prevent tasklets to enable interrupts once we disable them */ + ah->imask &= ~ATH9K_INT_GLOBAL; + /* make sure h/w will not generate any interrupt * before setting the invalid flag. */ ath9k_hw_disable_interrupts(ah); @@ -1326,6 +1329,12 @@ static void ath9k_stop(struct ieee80211_hw *hw) spin_unlock_bh(&sc->sc_pcu_lock); + /* we can now sync irq and kill any running tasklets, since we already + * disabled interrupts and not holding a spin lock */ + synchronize_irq(sc->irq); + tasklet_kill(&sc->intr_tq); + tasklet_kill(&sc->bcon_tasklet); + ath9k_ps_restore(sc); sc->ps_idle = true; -- cgit v1.2.3 From ea888357ec005abffb95acee2e61aac68dff429c Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 25 Jan 2011 14:15:12 +0100 Subject: ath9k_htc: fix race conditions when stop device We do not kill any scheduled tasklets when stopping device, that may cause usage of resources after free. Disable interrupts, kill tasklets and then works in correct order. Cc: stable@kernel.org Tested-by: Sujith Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 3 --- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 21 +++++++++++++++------ 2 files changed, 15 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 38433f9bfe59..0352f0994caa 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -142,9 +142,6 @@ static void ath9k_deinit_priv(struct ath9k_htc_priv *priv) { ath9k_htc_exit_debug(priv->ah); ath9k_hw_deinit(priv->ah); - tasklet_kill(&priv->swba_tasklet); - tasklet_kill(&priv->rx_tasklet); - tasklet_kill(&priv->tx_tasklet); kfree(priv->ah); priv->ah = NULL; } diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index f4d576bc3ccd..6bb59958f71e 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1025,12 +1025,6 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) int ret = 0; u8 cmd_rsp; - /* Cancel all the running timers/work .. */ - cancel_work_sync(&priv->fatal_work); - cancel_work_sync(&priv->ps_work); - cancel_delayed_work_sync(&priv->ath9k_led_blink_work); - ath9k_led_stop_brightness(priv); - mutex_lock(&priv->mutex); if (priv->op_flags & OP_INVALID) { @@ -1044,8 +1038,23 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) WMI_CMD(WMI_DISABLE_INTR_CMDID); WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); WMI_CMD(WMI_STOP_RECV_CMDID); + + tasklet_kill(&priv->swba_tasklet); + tasklet_kill(&priv->rx_tasklet); + tasklet_kill(&priv->tx_tasklet); + skb_queue_purge(&priv->tx_queue); + mutex_unlock(&priv->mutex); + + /* Cancel all the running timers/work .. */ + cancel_work_sync(&priv->fatal_work); + cancel_work_sync(&priv->ps_work); + cancel_delayed_work_sync(&priv->ath9k_led_blink_work); + ath9k_led_stop_brightness(priv); + + mutex_lock(&priv->mutex); + /* Remove monitor interface here */ if (ah->opmode == NL80211_IFTYPE_MONITOR) { if (ath9k_htc_remove_monitor_interface(priv)) -- cgit v1.2.3 From e0ce4af920eb028f38bfd680b1d733f4c7a0b7cf Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 27 Jan 2011 04:14:03 +0000 Subject: xen: netfront: handle incoming GSO SKBs which are not CHECKSUM_PARTIAL The Linux network stack expects all GSO SKBs to have ip_summed == CHECKSUM_PARTIAL (which implies that the frame contains a partial checksum) and the Xen network ring protocol similarly expects an SKB which has GSO set to also have NETRX_csum_blank (which also implies a partial checksum). However there have been cases of buggy guests which mark a frame as GSO but do not set csum_blank. If we detect that we a receiving such a frame (which manifests as ip_summed != PARTIAL && skb_is_gso) then force the SKB to partial and recalculate the checksum, since we cannot rely on the peer having done so if they have not set csum_blank. Add an ethtool stat to track occurances of this event. Signed-off-by: Ian Campbell Cc: Jeremy Fitzhardinge Cc: David Miller Cc: xen-devel@lists.xensource.com Cc: netdev@vger.kernel.org Signed-off-by: David S. Miller --- drivers/net/xen-netfront.c | 96 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 88 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 546de5749824..da1f12120346 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -120,6 +120,9 @@ struct netfront_info { unsigned long rx_pfn_array[NET_RX_RING_SIZE]; struct multicall_entry rx_mcl[NET_RX_RING_SIZE+1]; struct mmu_update rx_mmu[NET_RX_RING_SIZE]; + + /* Statistics */ + int rx_gso_checksum_fixup; }; struct netfront_rx_info { @@ -770,11 +773,29 @@ static RING_IDX xennet_fill_frags(struct netfront_info *np, return cons; } -static int skb_checksum_setup(struct sk_buff *skb) +static int checksum_setup(struct net_device *dev, struct sk_buff *skb) { struct iphdr *iph; unsigned char *th; int err = -EPROTO; + int recalculate_partial_csum = 0; + + /* + * A GSO SKB must be CHECKSUM_PARTIAL. However some buggy + * peers can fail to set NETRXF_csum_blank when sending a GSO + * frame. In this case force the SKB to CHECKSUM_PARTIAL and + * recalculate the partial checksum. + */ + if (skb->ip_summed != CHECKSUM_PARTIAL && skb_is_gso(skb)) { + struct netfront_info *np = netdev_priv(dev); + np->rx_gso_checksum_fixup++; + skb->ip_summed = CHECKSUM_PARTIAL; + recalculate_partial_csum = 1; + } + + /* A non-CHECKSUM_PARTIAL SKB does not require setup. */ + if (skb->ip_summed != CHECKSUM_PARTIAL) + return 0; if (skb->protocol != htons(ETH_P_IP)) goto out; @@ -788,9 +809,23 @@ static int skb_checksum_setup(struct sk_buff *skb) switch (iph->protocol) { case IPPROTO_TCP: skb->csum_offset = offsetof(struct tcphdr, check); + + if (recalculate_partial_csum) { + struct tcphdr *tcph = (struct tcphdr *)th; + tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, + skb->len - iph->ihl*4, + IPPROTO_TCP, 0); + } break; case IPPROTO_UDP: skb->csum_offset = offsetof(struct udphdr, check); + + if (recalculate_partial_csum) { + struct udphdr *udph = (struct udphdr *)th; + udph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, + skb->len - iph->ihl*4, + IPPROTO_UDP, 0); + } break; default: if (net_ratelimit()) @@ -829,13 +864,11 @@ static int handle_incoming_queue(struct net_device *dev, /* Ethernet work: Delayed to here as it peeks the header. */ skb->protocol = eth_type_trans(skb, dev); - if (skb->ip_summed == CHECKSUM_PARTIAL) { - if (skb_checksum_setup(skb)) { - kfree_skb(skb); - packets_dropped++; - dev->stats.rx_errors++; - continue; - } + if (checksum_setup(dev, skb)) { + kfree_skb(skb); + packets_dropped++; + dev->stats.rx_errors++; + continue; } dev->stats.rx_packets++; @@ -1632,12 +1665,59 @@ static void netback_changed(struct xenbus_device *dev, } } +static const struct xennet_stat { + char name[ETH_GSTRING_LEN]; + u16 offset; +} xennet_stats[] = { + { + "rx_gso_checksum_fixup", + offsetof(struct netfront_info, rx_gso_checksum_fixup) + }, +}; + +static int xennet_get_sset_count(struct net_device *dev, int string_set) +{ + switch (string_set) { + case ETH_SS_STATS: + return ARRAY_SIZE(xennet_stats); + default: + return -EINVAL; + } +} + +static void xennet_get_ethtool_stats(struct net_device *dev, + struct ethtool_stats *stats, u64 * data) +{ + void *np = netdev_priv(dev); + int i; + + for (i = 0; i < ARRAY_SIZE(xennet_stats); i++) + data[i] = *(int *)(np + xennet_stats[i].offset); +} + +static void xennet_get_strings(struct net_device *dev, u32 stringset, u8 * data) +{ + int i; + + switch (stringset) { + case ETH_SS_STATS: + for (i = 0; i < ARRAY_SIZE(xennet_stats); i++) + memcpy(data + i * ETH_GSTRING_LEN, + xennet_stats[i].name, ETH_GSTRING_LEN); + break; + } +} + static const struct ethtool_ops xennet_ethtool_ops = { .set_tx_csum = ethtool_op_set_tx_csum, .set_sg = xennet_set_sg, .set_tso = xennet_set_tso, .get_link = ethtool_op_get_link, + + .get_sset_count = xennet_get_sset_count, + .get_ethtool_stats = xennet_get_ethtool_stats, + .get_strings = xennet_get_strings, }; #ifdef CONFIG_SYSFS -- cgit v1.2.3 From 9eb710797a21fa4a9e09ae9c86c4b3ec9d291c2d Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 26 Jan 2011 00:45:42 +0000 Subject: dl2k: nulify fraginfo after unmap Patch fixes: "DMA-API: device driver tries to free an invalid DMA memory address" warning reported here: https://bugzilla.redhat.com/show_bug.cgi?id=639824 Reported-by: Frantisek Hanzlik Signed-off-by: Stanislaw Gruszka Signed-off-by: David S. Miller --- drivers/net/dl2k.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c index e1a8216ff692..c05db6046050 100644 --- a/drivers/net/dl2k.c +++ b/drivers/net/dl2k.c @@ -1753,8 +1753,6 @@ rio_close (struct net_device *dev) /* Free all the skbuffs in the queue. */ for (i = 0; i < RX_RING_SIZE; i++) { - np->rx_ring[i].status = 0; - np->rx_ring[i].fraginfo = 0; skb = np->rx_skbuff[i]; if (skb) { pci_unmap_single(np->pdev, @@ -1763,6 +1761,8 @@ rio_close (struct net_device *dev) dev_kfree_skb (skb); np->rx_skbuff[i] = NULL; } + np->rx_ring[i].status = 0; + np->rx_ring[i].fraginfo = 0; } for (i = 0; i < TX_RING_SIZE; i++) { skb = np->tx_skbuff[i]; -- cgit v1.2.3 From 5b64aa72ead6f8be488d2be7af579f0d69fb7a6e Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Thu, 27 Jan 2011 18:39:37 +0530 Subject: ath9k_hw: Fix system hang when resuming from S3/S4 The bit 6 & 7 of AR_WA (0x4004) should be enabled only for the chips that are supporting L0s functionality while resuming back from S3/S4. Enabling these bits for AR9280 is causing system hang within a few S3/S4-resume cycles. Cc: stable@kernel.org Cc: Jack Lee Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9002_hw.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c index f8a7771faee2..f44c84ab5dce 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c @@ -426,9 +426,8 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah, } /* WAR for ASPM system hang */ - if (AR_SREV_9280(ah) || AR_SREV_9285(ah) || AR_SREV_9287(ah)) { + if (AR_SREV_9285(ah) || AR_SREV_9287(ah)) val |= (AR_WA_BIT6 | AR_WA_BIT7); - } if (AR_SREV_9285E_20(ah)) val |= AR_WA_BIT23; -- cgit v1.2.3 From c7c1806098752c1f46943d8db2c69aff07f5d4bc Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Thu, 27 Jan 2011 18:39:38 +0530 Subject: ath9k: Fix power save usage count imbalance on deinit While unloading the driver, the ps_usecount is incremented before configuring gpio registers in deinit_device. But it is failed to restore the ps_usecount after that. The problem is that the chip is forcibly moved to FULL SLEEP by radio_disable when mac80211 is reporting as idle though ps_usecount is not zero. This patch retores ps_usecount properly and ensures that the chip is always moved to full sleep only if ps usage count is zero which also helps in debugging deadbeef on multivif case. And also fixes the following warning. ath: DMA failed to stop in 10 ms AR_CR=0xdeadbeef AR_DIAG_SW=0xdeadbeef ath: Could not stop RX, we could be confusing the DMA engine when we start RX up ------------[ cut here ]------------ WARNING: at drivers/net/wireless/ath/ath9k/recv.c:536 ath_stoprecv+0xf4/0x100 [ath9k]() Cc: stable@kernel.org Cc: Paul Stewart Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/init.c | 2 ++ drivers/net/wireless/ath/ath9k/main.c | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index b3254a3484a5..087a6a95edd5 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -819,6 +819,8 @@ void ath9k_deinit_device(struct ath_softc *sc) wiphy_rfkill_stop_polling(sc->hw->wiphy); ath_deinit_leds(sc); + ath9k_ps_restore(sc); + for (i = 0; i < sc->num_sec_wiphy; i++) { struct ath_wiphy *aphy = sc->sec_wiphy[i]; if (aphy == NULL) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index ace9f066fa20..568f7be2ec75 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -953,8 +953,6 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) spin_unlock_bh(&sc->sc_pcu_lock); ath9k_ps_restore(sc); - - ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP); } int ath_reset(struct ath_softc *sc, bool retry_tx) -- cgit v1.2.3 From c128df731862e90ec9292c5d3eb264ac73b522b8 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Sun, 30 Jan 2011 01:09:37 -0800 Subject: slcan: fix referenced website in Kconfig help text Fix the referenced project website to www.mictronics.de in the Kconfig help text for the slcan driver. Signed-off-by: Oliver Hartkopp Signed-off-by: David S. Miller --- drivers/net/can/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index 986195eaa57c..5dec456fd4a4 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig @@ -23,7 +23,7 @@ config CAN_SLCAN As only the sending and receiving of CAN frames is implemented, this driver should work with the (serial/USB) CAN hardware from: - www.canusb.com / www.can232.com / www.mictronic.com / www.canhack.de + www.canusb.com / www.can232.com / www.mictronics.de / www.canhack.de Userspace tools to attach the SLCAN line discipline (slcan_attach, slcand) can be found in the can-utils at the SocketCAN SVN, see -- cgit v1.2.3 From 81a3516c4c127a75cc69f03d2a858f55a56eda1e Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Sun, 30 Jan 2011 04:14:48 +0000 Subject: bnx2x: Remove setting XAUI low-power for BCM8073 A rare link issue with the BCM8073 PHY may occur due to setting XAUI low power mode, while the PHY microcode already does that. The fix is not to set set XAUI low power mode for this PHY. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 44 ------------------------------------------ 1 file changed, 44 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 7160ec51093e..53a95a2c5e02 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -3948,48 +3948,6 @@ static u8 bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp, return rc; } -static void bnx2x_8073_set_xaui_low_power_mode(struct bnx2x *bp, - struct bnx2x_phy *phy) -{ - u16 val; - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV, &val); - - if (val == 0) { - /* Mustn't set low power mode in 8073 A0 */ - return; - } - - /* Disable PLL sequencer (use read-modify-write to clear bit 13) */ - bnx2x_cl45_read(bp, phy, - MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, &val); - val &= ~(1<<13); - bnx2x_cl45_write(bp, phy, - MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val); - - /* PLL controls */ - bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805E, 0x1077); - bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805D, 0x0000); - bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805C, 0x030B); - bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805B, 0x1240); - bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805A, 0x2490); - - /* Tx Controls */ - bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80A7, 0x0C74); - bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80A6, 0x9041); - bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80A5, 0x4640); - - /* Rx Controls */ - bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80FE, 0x01C4); - bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80FD, 0x9249); - bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80FC, 0x2015); - - /* Enable PLL sequencer (use read-modify-write to set bit 13) */ - bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, &val); - val |= (1<<13); - bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val); -} - /******************************************************************/ /* BCM8073 PHY SECTION */ /******************************************************************/ @@ -4148,8 +4106,6 @@ static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy, bnx2x_8073_set_pause_cl37(params, phy, vars); - bnx2x_8073_set_xaui_low_power_mode(bp, phy); - bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1); -- cgit v1.2.3 From 53eda06def26862c0a3c57348c71a240429fbaac Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Sun, 30 Jan 2011 04:14:55 +0000 Subject: bnx2x: Fix LED blink rate on BCM84823 Fix blink rate of activity LED of the BCM84823 on 10G link Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 53a95a2c5e02..b1c667a0031e 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -6475,6 +6475,18 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LED1_MASK, 0x80); + + /* Tell LED3 to blink on source */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LINK_SIGNAL, + &val); + val &= ~(7<<6); + val |= (1<<6); /* A83B[8:6]= 1 */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LINK_SIGNAL, + val); } break; } -- cgit v1.2.3 From c8e64df48a814be1e7066f07b4f709ff63727abf Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Sun, 30 Jan 2011 04:15:00 +0000 Subject: bnx2x: Fix port swap for BCM8073 Fix link on BCM57712 + BCM8073 when port swap is enabled. Common PHY reset was done on the wrong port. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index b1c667a0031e..dd1210fddfff 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -7688,10 +7688,13 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, struct bnx2x_phy phy[PORT_MAX]; struct bnx2x_phy *phy_blk[PORT_MAX]; u16 val; - s8 port; + s8 port = 0; s8 port_of_path = 0; - - bnx2x_ext_phy_hw_reset(bp, 0); + u32 swap_val, swap_override; + swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); + swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); + port ^= (swap_val && swap_override); + bnx2x_ext_phy_hw_reset(bp, port); /* PART1 - Reset both phys */ for (port = PORT_MAX - 1; port >= PORT_0; port--) { u32 shmem_base, shmem2_base; -- cgit v1.2.3 From 5866df6d07cf22749557a0804253c8fee9e87f06 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Sun, 30 Jan 2011 04:15:07 +0000 Subject: bnx2x: Fix potential link loss in multi-function mode All functions on a port should be set to take the MDC/MDIO lock to avoid contention on the bus Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_main.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 8cdcf5b39d1e..404d93e6df21 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -5296,10 +5296,6 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) } } - bp->port.need_hw_lock = bnx2x_hw_lock_required(bp, - bp->common.shmem_base, - bp->common.shmem2_base); - bnx2x_setup_fan_failure_detection(bp); /* clear PXP2 attentions */ @@ -5503,9 +5499,6 @@ static int bnx2x_init_hw_port(struct bnx2x *bp) bnx2x_init_block(bp, MCP_BLOCK, init_stage); bnx2x_init_block(bp, DMAE_BLOCK, init_stage); - bp->port.need_hw_lock = bnx2x_hw_lock_required(bp, - bp->common.shmem_base, - bp->common.shmem2_base); if (bnx2x_fan_failure_det_req(bp, bp->common.shmem_base, bp->common.shmem2_base, port)) { u32 reg_addr = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 : @@ -8379,6 +8372,17 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) bp->mdio.prtad = XGXS_EXT_PHY_ADDR(ext_phy_config); + + /* + * Check if hw lock is required to access MDC/MDIO bus to the PHY(s) + * In MF mode, it is set to cover self test cases + */ + if (IS_MF(bp)) + bp->port.need_hw_lock = 1; + else + bp->port.need_hw_lock = bnx2x_hw_lock_required(bp, + bp->common.shmem_base, + bp->common.shmem2_base); } static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp) -- cgit v1.2.3 From c4c93106741bbf61ecd05a2a835af8e3bf31c1bd Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Sun, 30 Jan 2011 04:15:13 +0000 Subject: bnx2x: Update bnx2x version to 1.62.00-5 Update bnx2x version to 1.62.00-5 Signed-off-by: Yaniv Rosner 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') diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 8e4183717d91..653c62475cb6 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -22,8 +22,8 @@ * (you will need to reboot afterwards) */ /* #define BNX2X_STOP_ON_ERROR */ -#define DRV_MODULE_VERSION "1.62.00-4" -#define DRV_MODULE_RELDATE "2011/01/18" +#define DRV_MODULE_VERSION "1.62.00-5" +#define DRV_MODULE_RELDATE "2011/01/30" #define BNX2X_BC_VER 0x040200 #define BNX2X_MULTI_QUEUE -- cgit v1.2.3 From 9b00b4157f7b3265de291ac8979a5f1611ce64ab Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Sun, 30 Jan 2011 11:29:47 +0100 Subject: wl12xx: fix use after free When DEBUG_SPI is included in the debug log level wl1271_spi_reset() will dump the already freed memory instead of the SPI buffer. This bug was spotted by the semantic patch tool coccinelle using the script found at scripts/coccinelle/free/kfree.cocci. More information about semantic patching is available at http://coccinelle.lip6.fr/ Signed-off-by: Mathias Krause Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/spi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/spi.c b/drivers/net/wireless/wl12xx/spi.c index 46714910f98c..7145ea543783 100644 --- a/drivers/net/wireless/wl12xx/spi.c +++ b/drivers/net/wireless/wl12xx/spi.c @@ -110,9 +110,8 @@ static void wl1271_spi_reset(struct wl1271 *wl) spi_message_add_tail(&t, &m); spi_sync(wl_to_spi(wl), &m); - kfree(cmd); - wl1271_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN); + kfree(cmd); } static void wl1271_spi_init(struct wl1271 *wl) -- cgit v1.2.3 From cc09b5f6466528867b280f6eb4077311aa099588 Mon Sep 17 00:00:00 2001 From: Chuck Ebbert Date: Mon, 31 Jan 2011 05:44:07 +0000 Subject: CAN: softing driver depends on IOMEM Without this dependency the softing driver will be buildable on s390, where it fails. Signed-Off-By: Chuck Ebbert Acked-by: Kurt Van Dijck Signed-off-by: David S. Miller --- drivers/net/can/softing/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/can/softing/Kconfig b/drivers/net/can/softing/Kconfig index 92bd6bdde5e3..8ba81b3ddd90 100644 --- a/drivers/net/can/softing/Kconfig +++ b/drivers/net/can/softing/Kconfig @@ -1,6 +1,6 @@ config CAN_SOFTING tristate "Softing Gmbh CAN generic support" - depends on CAN_DEV + depends on CAN_DEV && HAS_IOMEM ---help--- Support for CAN cards from Softing Gmbh & some cards from Vector Gmbh. -- cgit v1.2.3 From 785e8cc39baf31d5c18a2d198ded03a003c9c190 Mon Sep 17 00:00:00 2001 From: Ken Kawasaki Date: Sun, 30 Jan 2011 11:16:16 +0000 Subject: axnet_cs: reduce delay time at ei_rx_overrun axnet_cs: mdelay of 10ms is too long at ei_rx_overrun. It should be reduced to 2ms. Signed-off-by: Ken Kawasaki Signed-off-by: David S. Miller --- drivers/net/pcmcia/axnet_cs.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index 1f42f6ac8551..d3cb77205863 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c @@ -1488,12 +1488,10 @@ static void ei_rx_overrun(struct net_device *dev) /* * Wait a full Tx time (1.2ms) + some guard time, NS says 1.6ms total. - * Early datasheets said to poll the reset bit, but now they say that - * it "is not a reliable indicator and subsequently should be ignored." - * We wait at least 10ms. + * We wait at least 2ms. */ - mdelay(10); + mdelay(2); /* * Reset RBCR[01] back to zero as per magic incantation. -- cgit v1.2.3 From fca540ab5f4718c6133f71f7be1793066008bf89 Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Mon, 31 Jan 2011 20:56:54 -0800 Subject: enc28j60: Fix reading of transmit status vector This error was reported by cppcheck: drivers/net/enc28j60.c:815: error: Using sizeof for array given as function argument returns the size of pointer. The original code reads 4 or 8 bytes instead of TSV_SIZE (= 100) bytes. I just fixed the code, but did not run any tests. Signed-off-by: Stefan Weil Signed-off-by: David S. Miller --- drivers/net/enc28j60.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/enc28j60.c b/drivers/net/enc28j60.c index 112c5aa9af7f..907b05a1c659 100644 --- a/drivers/net/enc28j60.c +++ b/drivers/net/enc28j60.c @@ -812,7 +812,7 @@ static void enc28j60_read_tsv(struct enc28j60_net *priv, u8 tsv[TSV_SIZE]) if (netif_msg_hw(priv)) printk(KERN_DEBUG DRV_NAME ": reading TSV at addr:0x%04x\n", endptr + 1); - enc28j60_mem_read(priv, endptr + 1, sizeof(tsv), tsv); + enc28j60_mem_read(priv, endptr + 1, TSV_SIZE, tsv); } static void enc28j60_dump_tsv(struct enc28j60_net *priv, const char *msg, -- cgit v1.2.3 From 5e18247b02d60a1ea4bf98c05e139461ca9aec64 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 18 Jan 2011 13:04:43 +0200 Subject: vhost: rcu annotation fixup When built with rcu checks enabled, vhost triggers bogus warnings as vhost features are read without dev->mutex sometimes, and private pointer is read with our kind of rcu where work serves as a read side critical section. Fixing it properly is not trivial. Disable the warnings by stubbing out the checks for now. Signed-off-by: Michael S. Tsirkin --- drivers/vhost/net.c | 9 +++++---- drivers/vhost/vhost.h | 6 +++--- 2 files changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 9b3ca103135f..f616cefc95ba 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c @@ -128,8 +128,7 @@ static void handle_tx(struct vhost_net *net) size_t hdr_size; struct socket *sock; - /* TODO: check that we are running from vhost_worker? - * Not sure it's worth it, it's straight-forward enough. */ + /* TODO: check that we are running from vhost_worker? */ sock = rcu_dereference_check(vq->private_data, 1); if (!sock) return; @@ -306,7 +305,8 @@ static void handle_rx_big(struct vhost_net *net) size_t len, total_len = 0; int err; size_t hdr_size; - struct socket *sock = rcu_dereference(vq->private_data); + /* TODO: check that we are running from vhost_worker? */ + struct socket *sock = rcu_dereference_check(vq->private_data, 1); if (!sock || skb_queue_empty(&sock->sk->sk_receive_queue)) return; @@ -415,7 +415,8 @@ static void handle_rx_mergeable(struct vhost_net *net) int err, headcount; size_t vhost_hlen, sock_hlen; size_t vhost_len, sock_len; - struct socket *sock = rcu_dereference(vq->private_data); + /* TODO: check that we are running from vhost_worker? */ + struct socket *sock = rcu_dereference_check(vq->private_data, 1); if (!sock || skb_queue_empty(&sock->sk->sk_receive_queue)) return; diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h index 2af44b7b1f3f..b3363ae38518 100644 --- a/drivers/vhost/vhost.h +++ b/drivers/vhost/vhost.h @@ -173,9 +173,9 @@ static inline int vhost_has_feature(struct vhost_dev *dev, int bit) { unsigned acked_features; - acked_features = - rcu_dereference_index_check(dev->acked_features, - lockdep_is_held(&dev->mutex)); + /* TODO: check that we are running from vhost_worker or dev mutex is + * held? */ + acked_features = rcu_dereference_index_check(dev->acked_features, 1); return acked_features & (1 << bit); } -- cgit v1.2.3 From 479600777bb588724d044815415f7d708d06644b Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Mon, 31 Jan 2011 13:25:29 +0530 Subject: ath9k: Fix memory leak due to failed PAPRD frames free the skb's when the Tx of PAPRD frames fails and also add a debug message indicating that. Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 568f7be2ec75..9040c2ff1909 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -325,6 +325,8 @@ static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int { struct ieee80211_hw *hw = sc->hw; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); struct ath_tx_control txctl; int time_left; @@ -342,8 +344,12 @@ static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int init_completion(&sc->paprd_complete); sc->paprd_pending = true; txctl.paprd = BIT(chain); - if (ath_tx_start(hw, skb, &txctl) != 0) + + if (ath_tx_start(hw, skb, &txctl) != 0) { + ath_dbg(common, ATH_DBG_XMIT, "PAPRD TX failed\n"); + dev_kfree_skb_any(skb); return false; + } time_left = wait_for_completion_timeout(&sc->paprd_complete, msecs_to_jiffies(ATH_PAPRD_TIMEOUT)); -- cgit v1.2.3 From 48bc9a2ccec98de007117495123bba78a4bbdd9c Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Fri, 28 Jan 2011 12:30:17 +0000 Subject: vxge: Fix wrong boolean operator This error is reported by cppcheck: drivers/net/vxge/vxge-config.c:3693: warning: Mutual exclusion over || always evaluates to true. Did you intend to use && instead? It looks like cppcheck is correct, so fix this. No test was run. Cc: Ramkrishna Vepa Cc: Sivakumar Subramani Cc: Sreenivasa Honnur Cc: Jon Mason Cc: netdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Stefan Weil Acked-by: Ram Vepa Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/vxge/vxge-config.c b/drivers/net/vxge/vxge-config.c index 01c05f53e2f9..228d4f7a58af 100644 --- a/drivers/net/vxge/vxge-config.c +++ b/drivers/net/vxge/vxge-config.c @@ -3690,7 +3690,7 @@ __vxge_hw_vpath_rts_table_get(struct __vxge_hw_vpath_handle *vp, if (status != VXGE_HW_OK) goto exit; - if ((rts_table != VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA) || + if ((rts_table != VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA) && (rts_table != VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT)) *data1 = 0; -- cgit v1.2.3 From f97f3057fd2febbd7f34a60f09a2cb9cef8bf403 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 1 Feb 2011 13:19:07 -0800 Subject: depca: Fix warnings Replace the rather weird use of ++ with + 1 as the value is being assigned Signed-off-by: Alan Cox --- drivers/net/depca.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/depca.c b/drivers/net/depca.c index 1b48b68ad4fd..8b0084d17c8c 100644 --- a/drivers/net/depca.c +++ b/drivers/net/depca.c @@ -1094,7 +1094,7 @@ static int depca_rx(struct net_device *dev) } } /* Change buffer ownership for this last frame, back to the adapter */ - for (; lp->rx_old != entry; lp->rx_old = (++lp->rx_old) & lp->rxRingMask) { + for (; lp->rx_old != entry; lp->rx_old = (lp->rx_old + 1) & lp->rxRingMask) { writel(readl(&lp->rx_ring[lp->rx_old].base) | R_OWN, &lp->rx_ring[lp->rx_old].base); } writel(readl(&lp->rx_ring[entry].base) | R_OWN, &lp->rx_ring[entry].base); @@ -1103,7 +1103,7 @@ static int depca_rx(struct net_device *dev) /* ** Update entry information */ - lp->rx_new = (++lp->rx_new) & lp->rxRingMask; + lp->rx_new = (lp->rx_new + 1) & lp->rxRingMask; } return 0; @@ -1148,7 +1148,7 @@ static int depca_tx(struct net_device *dev) } /* Update all the pointers */ - lp->tx_old = (++lp->tx_old) & lp->txRingMask; + lp->tx_old = (lp->tx_old + 1) & lp->txRingMask; } return 0; -- cgit v1.2.3 From d9c8f498c3b41e686d3306dcf01d95941fcc6b48 Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Tue, 1 Feb 2011 14:05:30 -0800 Subject: bnx2x: multicasts in NPAR mode The chip was erroneously configured to accept all multicast frames in a normal (none-promisc) rx mode both on the RSS and on the FCoE L2 rings when in an NPAR mode. This caused packet duplication for every received multicast frame in this mode. Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_main.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 404d93e6df21..f40740e68ea5 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -2301,15 +2301,10 @@ static void bnx2x_rxq_set_mac_filters(struct bnx2x *bp, u16 cl_id, u32 filters) /* accept matched ucast */ drop_all_ucast = 0; } - if (filters & BNX2X_ACCEPT_MULTICAST) { + if (filters & BNX2X_ACCEPT_MULTICAST) /* accept matched mcast */ drop_all_mcast = 0; - if (IS_MF_SI(bp)) - /* since mcast addresses won't arrive with ovlan, - * fw needs to accept all of them in - * switch-independent mode */ - accp_all_mcast = 1; - } + if (filters & BNX2X_ACCEPT_ALL_UNICAST) { /* accept all mcast */ drop_all_ucast = 0; -- cgit v1.2.3 From a29ae23f687649c35b1520a8f986497637a0cc62 Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Sun, 30 Jan 2011 10:31:26 +0000 Subject: isdn: icn: Fix potentially wrong string handling This warning was reported by cppcheck: drivers/isdn/icn/icn.c:1641: error: Dangerous usage of 'rev' (strncpy doesn't always 0-terminate it) If strncpy copied 20 bytes, the destination string rev was not terminated. The patch adds one more byte to rev and makes sure that this byte is always 0. Cc: Karsten Keil Cc: "David S. Miller" Cc: Tejun Heo Cc: Steven Rostedt Cc: netdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Stefan Weil Signed-off-by: David S. Miller --- drivers/isdn/icn/icn.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/isdn/icn/icn.c b/drivers/isdn/icn/icn.c index f2b5bab5e6a1..1f355bb85e54 100644 --- a/drivers/isdn/icn/icn.c +++ b/drivers/isdn/icn/icn.c @@ -1627,7 +1627,7 @@ __setup("icn=", icn_setup); static int __init icn_init(void) { char *p; - char rev[20]; + char rev[21]; memset(&dev, 0, sizeof(icn_dev)); dev.memaddr = (membase & 0x0ffc000); @@ -1638,6 +1638,7 @@ static int __init icn_init(void) if ((p = strchr(revision, ':'))) { strncpy(rev, p + 1, 20); + rev[20] = '\0'; p = strchr(rev, '$'); if (p) *p = 0; -- cgit v1.2.3 From a89e828397abbefdc5c3b707521f6b73471b43c8 Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Tue, 1 Feb 2011 15:41:13 -0800 Subject: be2net: fix a crash seen during insmod/rmmod test While running insmod/rmood in a loop, an unnecessary netif_stop_queue causes the system to crash. Remove the netif_stop_queue call and netif_start_queue in the link status update path. Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index de40d3b7152f..9aaf1ef704e9 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -312,11 +312,9 @@ void be_link_status_update(struct be_adapter *adapter, bool link_up) if (adapter->link_up != link_up) { adapter->link_speed = -1; if (link_up) { - netif_start_queue(netdev); netif_carrier_on(netdev); printk(KERN_INFO "%s: Link up\n", netdev->name); } else { - netif_stop_queue(netdev); netif_carrier_off(netdev); printk(KERN_INFO "%s: Link down\n", netdev->name); } -- cgit v1.2.3 From 9b6cefd6593c2b661e0052d53f2fff6fc5463975 Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Tue, 1 Feb 2011 15:41:59 -0800 Subject: be2net: remove netif_stop_queue being called before register_netdev. It is illegal to call netif_stop_queue before register_netdev. Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 9aaf1ef704e9..28a32a6c8bf1 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -2626,8 +2626,6 @@ static void be_netdev_init(struct net_device *netdev) netif_napi_add(netdev, &adapter->tx_eq.napi, be_poll_tx_mcc, BE_NAPI_WEIGHT); - - netif_stop_queue(netdev); } static void be_unmap_pci_bars(struct be_adapter *adapter) -- cgit v1.2.3 From 221c17fe87033aa154df68679b437c83d835c284 Mon Sep 17 00:00:00 2001 From: Ursula Braun Date: Wed, 2 Feb 2011 06:04:31 +0000 Subject: qeth: show new mac-address if its setting fails Setting of a MAC-address may fail because an already used MAC-address is to bet set or because of authorization problems. In those cases qeth issues a message, but the mentioned MAC-address is not the new MAC-address to be set, but the actual MAC-address. This patch chooses now the new MAC-address to be set for the error messages. Signed-off-by: Ursula Braun Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/qeth_l2_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 2ac8f6aff5a4..ada0fe782373 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -573,13 +573,13 @@ static int qeth_l2_send_setmac_cb(struct qeth_card *card, case IPA_RC_L2_DUP_LAYER3_MAC: dev_warn(&card->gdev->dev, "MAC address %pM already exists\n", - card->dev->dev_addr); + cmd->data.setdelmac.mac); break; case IPA_RC_L2_MAC_NOT_AUTH_BY_HYP: case IPA_RC_L2_MAC_NOT_AUTH_BY_ADP: dev_warn(&card->gdev->dev, "MAC address %pM is not authorized\n", - card->dev->dev_addr); + cmd->data.setdelmac.mac); break; default: break; -- cgit v1.2.3 From 9853b97bccbd2b08ce5fef497f21fa7395f68823 Mon Sep 17 00:00:00 2001 From: Frank Blaschka Date: Wed, 2 Feb 2011 06:04:32 +0000 Subject: qeth: add more strict MTU checking HiperSockets and OSA hardware report a maximum MTU size. Add checking to reject larger MTUs than allowed by hardware. Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core_main.c | 35 ++++------------------------------- 1 file changed, 4 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 29f848bfc12f..ddeef41049ae 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -1832,33 +1832,6 @@ static inline int qeth_get_initial_mtu_for_card(struct qeth_card *card) } } -static inline int qeth_get_max_mtu_for_card(int cardtype) -{ - switch (cardtype) { - - case QETH_CARD_TYPE_UNKNOWN: - case QETH_CARD_TYPE_OSD: - case QETH_CARD_TYPE_OSN: - case QETH_CARD_TYPE_OSM: - case QETH_CARD_TYPE_OSX: - return 61440; - case QETH_CARD_TYPE_IQD: - return 57344; - default: - return 1500; - } -} - -static inline int qeth_get_mtu_out_of_mpc(int cardtype) -{ - switch (cardtype) { - case QETH_CARD_TYPE_IQD: - return 1; - default: - return 0; - } -} - static inline int qeth_get_mtu_outof_framesize(int framesize) { switch (framesize) { @@ -1881,10 +1854,9 @@ static inline int qeth_mtu_is_valid(struct qeth_card *card, int mtu) case QETH_CARD_TYPE_OSD: case QETH_CARD_TYPE_OSM: case QETH_CARD_TYPE_OSX: - return ((mtu >= 576) && (mtu <= 61440)); case QETH_CARD_TYPE_IQD: return ((mtu >= 576) && - (mtu <= card->info.max_mtu + 4096 - 32)); + (mtu <= card->info.max_mtu)); case QETH_CARD_TYPE_OSN: case QETH_CARD_TYPE_UNKNOWN: default: @@ -1907,7 +1879,7 @@ static int qeth_ulp_enable_cb(struct qeth_card *card, struct qeth_reply *reply, memcpy(&card->token.ulp_filter_r, QETH_ULP_ENABLE_RESP_FILTER_TOKEN(iob->data), QETH_MPC_TOKEN_LENGTH); - if (qeth_get_mtu_out_of_mpc(card->info.type)) { + if (card->info.type == QETH_CARD_TYPE_IQD) { memcpy(&framesize, QETH_ULP_ENABLE_RESP_MAX_MTU(iob->data), 2); mtu = qeth_get_mtu_outof_framesize(framesize); if (!mtu) { @@ -1920,7 +1892,8 @@ static int qeth_ulp_enable_cb(struct qeth_card *card, struct qeth_reply *reply, card->qdio.in_buf_size = mtu + 2 * PAGE_SIZE; } else { card->info.initial_mtu = qeth_get_initial_mtu_for_card(card); - card->info.max_mtu = qeth_get_max_mtu_for_card(card->info.type); + card->info.max_mtu = *(__u16 *)QETH_ULP_ENABLE_RESP_MAX_MTU( + iob->data); card->qdio.in_buf_size = QETH_IN_BUF_SIZE_DEFAULT; } -- cgit v1.2.3 From 8b2e18f662939fb3d9b0ffe5da953ba56d259e3a Mon Sep 17 00:00:00 2001 From: Ursula Braun Date: Wed, 2 Feb 2011 06:04:33 +0000 Subject: qeth: allow HiperSockets framesize change in suspend For HiperSockets the framesize-definition determines the selected mtu-size and the size of the allocated qdio buffers. A framesize-change may occur while a Linux system with probed HiperSockets device is in suspend state. This patch enables proper resuming of a HiperSockets device in this case. Signed-off-by: Ursula Braun Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core_main.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index ddeef41049ae..eca3e094031a 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -1887,8 +1887,16 @@ static int qeth_ulp_enable_cb(struct qeth_card *card, struct qeth_reply *reply, QETH_DBF_TEXT_(SETUP, 2, " rc%d", iob->rc); return 0; } - card->info.max_mtu = mtu; + if (card->info.initial_mtu && (card->info.initial_mtu != mtu)) { + /* frame size has changed */ + if (card->dev && + ((card->dev->mtu == card->info.initial_mtu) || + (card->dev->mtu > mtu))) + card->dev->mtu = mtu; + qeth_free_qdio_buffers(card); + } card->info.initial_mtu = mtu; + card->info.max_mtu = mtu; card->qdio.in_buf_size = mtu + 2 * PAGE_SIZE; } else { card->info.initial_mtu = qeth_get_initial_mtu_for_card(card); -- cgit v1.2.3 From d0ff1f52361d714863c49abb721a8714ea4e76d6 Mon Sep 17 00:00:00 2001 From: Ursula Braun Date: Wed, 2 Feb 2011 06:04:34 +0000 Subject: qeth: allow OSA CHPARM change in suspend state For OSA the CHPARM-definition determines the number of available outbound queues. A CHPARM-change may occur while a Linux system with probed OSA device is in suspend state. This patch enables proper resuming of an OSA device in this case. Signed-off-by: Ursula braun Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core_main.c | 104 +++++++++++++++++++++++--------------- 1 file changed, 63 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index eca3e094031a..019ae58ab913 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -988,16 +988,30 @@ static void qeth_get_channel_path_desc(struct qeth_card *card) chp_dsc = (struct channelPath_dsc *)ccw_device_get_chp_desc(ccwdev, 0); if (chp_dsc != NULL) { /* CHPP field bit 6 == 1 -> single queue */ - if ((chp_dsc->chpp & 0x02) == 0x02) + if ((chp_dsc->chpp & 0x02) == 0x02) { + if ((atomic_read(&card->qdio.state) != + QETH_QDIO_UNINITIALIZED) && + (card->qdio.no_out_queues == 4)) + /* change from 4 to 1 outbound queues */ + qeth_free_qdio_buffers(card); card->qdio.no_out_queues = 1; + if (card->qdio.default_out_queue != 0) + dev_info(&card->gdev->dev, + "Priority Queueing not supported\n"); + card->qdio.default_out_queue = 0; + } else { + if ((atomic_read(&card->qdio.state) != + QETH_QDIO_UNINITIALIZED) && + (card->qdio.no_out_queues == 1)) { + /* change from 1 to 4 outbound queues */ + qeth_free_qdio_buffers(card); + card->qdio.default_out_queue = 2; + } + card->qdio.no_out_queues = 4; + } card->info.func_level = 0x4100 + chp_dsc->desc; kfree(chp_dsc); } - if (card->qdio.no_out_queues == 1) { - card->qdio.default_out_queue = 0; - dev_info(&card->gdev->dev, - "Priority Queueing not supported\n"); - } QETH_DBF_TEXT_(SETUP, 2, "nr:%x", card->qdio.no_out_queues); QETH_DBF_TEXT_(SETUP, 2, "lvl:%02x", card->info.func_level); return; @@ -3756,6 +3770,47 @@ static inline int qeth_get_qdio_q_format(struct qeth_card *card) } } +static void qeth_determine_capabilities(struct qeth_card *card) +{ + int rc; + int length; + char *prcd; + struct ccw_device *ddev; + int ddev_offline = 0; + + QETH_DBF_TEXT(SETUP, 2, "detcapab"); + ddev = CARD_DDEV(card); + if (!ddev->online) { + ddev_offline = 1; + rc = ccw_device_set_online(ddev); + if (rc) { + QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc); + goto out; + } + } + + rc = qeth_read_conf_data(card, (void **) &prcd, &length); + if (rc) { + QETH_DBF_MESSAGE(2, "%s qeth_read_conf_data returned %i\n", + dev_name(&card->gdev->dev), rc); + QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc); + goto out_offline; + } + qeth_configure_unitaddr(card, prcd); + qeth_configure_blkt_default(card, prcd); + kfree(prcd); + + rc = qdio_get_ssqd_desc(ddev, &card->ssqd); + if (rc) + QETH_DBF_TEXT_(SETUP, 2, "6err%d", rc); + +out_offline: + if (ddev_offline == 1) + ccw_device_set_offline(ddev); +out: + return; +} + static int qeth_qdio_establish(struct qeth_card *card) { struct qdio_initialize init_data; @@ -3886,6 +3941,7 @@ int qeth_core_hardsetup_card(struct qeth_card *card) QETH_DBF_TEXT(SETUP, 2, "hrdsetup"); atomic_set(&card->force_alloc_skb, 0); + qeth_get_channel_path_desc(card); retry: if (retries) QETH_DBF_MESSAGE(2, "%s Retrying to do IDX activates.\n", @@ -3914,6 +3970,7 @@ retriable: else goto retry; } + qeth_determine_capabilities(card); qeth_init_tokens(card); qeth_init_func_level(card); rc = qeth_idx_activate_channel(&card->read, qeth_idx_read_cb); @@ -4183,41 +4240,6 @@ void qeth_core_free_discipline(struct qeth_card *card) card->discipline.ccwgdriver = NULL; } -static void qeth_determine_capabilities(struct qeth_card *card) -{ - int rc; - int length; - char *prcd; - - QETH_DBF_TEXT(SETUP, 2, "detcapab"); - rc = ccw_device_set_online(CARD_DDEV(card)); - if (rc) { - QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc); - goto out; - } - - - rc = qeth_read_conf_data(card, (void **) &prcd, &length); - if (rc) { - QETH_DBF_MESSAGE(2, "%s qeth_read_conf_data returned %i\n", - dev_name(&card->gdev->dev), rc); - QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc); - goto out_offline; - } - qeth_configure_unitaddr(card, prcd); - qeth_configure_blkt_default(card, prcd); - kfree(prcd); - - rc = qdio_get_ssqd_desc(CARD_DDEV(card), &card->ssqd); - if (rc) - QETH_DBF_TEXT_(SETUP, 2, "6err%d", rc); - -out_offline: - ccw_device_set_offline(CARD_DDEV(card)); -out: - return; -} - static int qeth_core_probe_device(struct ccwgroup_device *gdev) { struct qeth_card *card; -- cgit v1.2.3 From 5df979d6922d50cc12bfbe83721c143a5d0d31b7 Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Wed, 2 Feb 2011 06:04:35 +0000 Subject: s390: Fix wrong size in memcmp (netiucv) This error was reported by cppcheck: drivers/s390/net/netiucv.c:568: error: Using sizeof for array given as function argument returns the size of pointer. sizeof(ipuser) did not result in 16 (as many programmers would have expected) but sizeof(u8 *), so it is 4 or 8, too small here. Signed-off-by: Stefan Weil Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/netiucv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c index 65ebee0a3266..b6a6356d09b3 100644 --- a/drivers/s390/net/netiucv.c +++ b/drivers/s390/net/netiucv.c @@ -565,7 +565,7 @@ static int netiucv_callback_connreq(struct iucv_path *path, struct iucv_event ev; int rc; - if (memcmp(iucvMagic, ipuser, sizeof(ipuser))) + if (memcmp(iucvMagic, ipuser, 16)) /* ipuser must match iucvMagic. */ return -EINVAL; rc = -EINVAL; -- cgit v1.2.3 From 08b018327c2e8412fd76f821e9bb9de36ef48cb1 Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Wed, 2 Feb 2011 06:04:36 +0000 Subject: s390: Fix possibly wrong size in strncmp (smsgiucv) This error was reported by cppcheck: drivers/s390/net/smsgiucv.c:63: error: Using sizeof for array given as function argument returns the size of pointer. Although there is no runtime problem as long as sizeof(u8 *) == 8, this misleading code should get fixed. Signed-off-by: Stefan Weil Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/smsgiucv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c index 65e1cf104943..207b7d742443 100644 --- a/drivers/s390/net/smsgiucv.c +++ b/drivers/s390/net/smsgiucv.c @@ -60,7 +60,7 @@ static struct iucv_handler smsg_handler = { static int smsg_path_pending(struct iucv_path *path, u8 ipvmid[8], u8 ipuser[16]) { - if (strncmp(ipvmid, "*MSG ", sizeof(ipvmid)) != 0) + if (strncmp(ipvmid, "*MSG ", 8) != 0) return -EINVAL; /* Path pending from *MSG. */ return iucv_path_accept(path, &smsg_handler, "SMSGIUCV ", NULL); -- cgit v1.2.3 From 94dde7e451fa70749fa68df3d70e4b20debe96a6 Mon Sep 17 00:00:00 2001 From: Chuck Ebbert Date: Wed, 2 Feb 2011 15:02:08 -0800 Subject: atl1c: Add missing PCI device ID Commit 8f574b35f22fbb9b5e5f1d11ad6b55b6f35f4533 ("atl1c: Add AR8151 v2 support and change L0s/L1 routine") added support for a new adapter but failed to add it to the PCI device table. Signed-Off-By: Chuck Ebbert Signed-off-by: David S. Miller --- drivers/net/atl1c/atl1c_main.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c index a699bbf20eb5..3824382faecc 100644 --- a/drivers/net/atl1c/atl1c_main.c +++ b/drivers/net/atl1c/atl1c_main.c @@ -48,6 +48,7 @@ static DEFINE_PCI_DEVICE_TABLE(atl1c_pci_tbl) = { {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATHEROS_L2C_B)}, {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATHEROS_L2C_B2)}, {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATHEROS_L1D)}, + {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATHEROS_L1D_2_0)}, /* required last entry */ { 0 } }; -- cgit v1.2.3 From 9690c636ac118b6662f28308bee817343d9932d8 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 3 Feb 2011 16:12:50 -0800 Subject: niu: Fix races between up/down and get_stats. As reported by Flavio Leitner, there is no synchronization to protect NIU's get_stats method from seeing a NULL pointer in either np->rx_rings or np->tx_rings. In fact, as far as ->ndo_get_stats is concerned, these values are set completely asynchronously. Flavio attempted to fix this using a RW semaphore, which in fact works most of the time. However, dev_get_stats() can be invoked from non-sleepable contexts in some cases, so this fix doesn't work in all cases. So instead, control the visibility of the np->{rx,tx}_ring pointers when the device is being brough up, and use properties of the device down sequence to our advantage. In niu_get_stats(), return immediately if netif_running() is false. The device shutdown sequence first marks the device as not running (by clearing the __LINK_STATE_START bit), then it performans a synchronize_rcu() (in dev_deactive_many()), and then finally it invokes the driver ->ndo_stop() method. This guarentees that all invocations of niu_get_stats() either see netif_running() as false, or they see the channel pointers before ->ndo_stop() clears them out. If netif_running() is true, protect against startup races by loading the np->{rx,tx}_rings pointer into a local variable, and punting if it is NULL. Use ACCESS_ONCE to prevent the compiler from reloading the pointer on us. Also, during open, control the order in which the pointers and the ring counts become visible globally using SMP write memory barriers. We make sure the np->num_{rx,tx}_rings value is stable and visible before np->{rx,tx}_rings is. Such visibility control is not necessary on the niu_free_channels() side because of the RCU sequencing that happens during device down as described above. We are always guarenteed that all niu_get_stats calls are finished, or will see netif_running() false, by the time ->ndo_stop is invoked. Reported-by: Flavio Leitner Signed-off-by: David S. Miller --- drivers/net/niu.c | 61 ++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 45 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 2541321bad82..9fb59d3f9c92 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -4489,6 +4489,9 @@ static int niu_alloc_channels(struct niu *np) { struct niu_parent *parent = np->parent; int first_rx_channel, first_tx_channel; + int num_rx_rings, num_tx_rings; + struct rx_ring_info *rx_rings; + struct tx_ring_info *tx_rings; int i, port, err; port = np->port; @@ -4498,18 +4501,21 @@ static int niu_alloc_channels(struct niu *np) first_tx_channel += parent->txchan_per_port[i]; } - np->num_rx_rings = parent->rxchan_per_port[port]; - np->num_tx_rings = parent->txchan_per_port[port]; + num_rx_rings = parent->rxchan_per_port[port]; + num_tx_rings = parent->txchan_per_port[port]; - netif_set_real_num_rx_queues(np->dev, np->num_rx_rings); - netif_set_real_num_tx_queues(np->dev, np->num_tx_rings); - - np->rx_rings = kcalloc(np->num_rx_rings, sizeof(struct rx_ring_info), - GFP_KERNEL); + rx_rings = kcalloc(num_rx_rings, sizeof(struct rx_ring_info), + GFP_KERNEL); err = -ENOMEM; - if (!np->rx_rings) + if (!rx_rings) goto out_err; + np->num_rx_rings = num_rx_rings; + smp_wmb(); + np->rx_rings = rx_rings; + + netif_set_real_num_rx_queues(np->dev, num_rx_rings); + for (i = 0; i < np->num_rx_rings; i++) { struct rx_ring_info *rp = &np->rx_rings[i]; @@ -4538,12 +4544,18 @@ static int niu_alloc_channels(struct niu *np) return err; } - np->tx_rings = kcalloc(np->num_tx_rings, sizeof(struct tx_ring_info), - GFP_KERNEL); + tx_rings = kcalloc(num_tx_rings, sizeof(struct tx_ring_info), + GFP_KERNEL); err = -ENOMEM; - if (!np->tx_rings) + if (!tx_rings) goto out_err; + np->num_tx_rings = num_tx_rings; + smp_wmb(); + np->tx_rings = tx_rings; + + netif_set_real_num_tx_queues(np->dev, num_tx_rings); + for (i = 0; i < np->num_tx_rings; i++) { struct tx_ring_info *rp = &np->tx_rings[i]; @@ -6246,11 +6258,17 @@ static void niu_sync_mac_stats(struct niu *np) static void niu_get_rx_stats(struct niu *np) { unsigned long pkts, dropped, errors, bytes; + struct rx_ring_info *rx_rings; int i; pkts = dropped = errors = bytes = 0; + + rx_rings = ACCESS_ONCE(np->rx_rings); + if (!rx_rings) + goto no_rings; + for (i = 0; i < np->num_rx_rings; i++) { - struct rx_ring_info *rp = &np->rx_rings[i]; + struct rx_ring_info *rp = &rx_rings[i]; niu_sync_rx_discard_stats(np, rp, 0); @@ -6259,6 +6277,8 @@ static void niu_get_rx_stats(struct niu *np) dropped += rp->rx_dropped; errors += rp->rx_errors; } + +no_rings: np->dev->stats.rx_packets = pkts; np->dev->stats.rx_bytes = bytes; np->dev->stats.rx_dropped = dropped; @@ -6268,16 +6288,24 @@ static void niu_get_rx_stats(struct niu *np) static void niu_get_tx_stats(struct niu *np) { unsigned long pkts, errors, bytes; + struct tx_ring_info *tx_rings; int i; pkts = errors = bytes = 0; + + tx_rings = ACCESS_ONCE(np->tx_rings); + if (!tx_rings) + goto no_rings; + for (i = 0; i < np->num_tx_rings; i++) { - struct tx_ring_info *rp = &np->tx_rings[i]; + struct tx_ring_info *rp = &tx_rings[i]; pkts += rp->tx_packets; bytes += rp->tx_bytes; errors += rp->tx_errors; } + +no_rings: np->dev->stats.tx_packets = pkts; np->dev->stats.tx_bytes = bytes; np->dev->stats.tx_errors = errors; @@ -6287,9 +6315,10 @@ static struct net_device_stats *niu_get_stats(struct net_device *dev) { struct niu *np = netdev_priv(dev); - niu_get_rx_stats(np); - niu_get_tx_stats(np); - + if (netif_running(dev)) { + niu_get_rx_stats(np); + niu_get_tx_stats(np); + } return &dev->stats; } -- cgit v1.2.3 From b5ba6d12bdac21bc0620a5089e0f24e362645efd Mon Sep 17 00:00:00 2001 From: Ivan Vecera Date: Thu, 27 Jan 2011 12:24:11 +0100 Subject: r8169: use RxFIFO overflow workaround for 8168c chipset. I found that one of the 8168c chipsets (concretely XID 1c4000c0) starts generating RxFIFO overflow errors. The result is an infinite loop in interrupt handler as the RxFIFOOver is handled only for ...MAC_VER_11. With the workaround everything goes fine. Signed-off-by: Ivan Vecera Acked-by: Francois Romieu Cc: Hayes --- drivers/net/r8169.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index bde7d61f1930..9ab3b43c7d04 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -3757,7 +3757,8 @@ static void rtl_hw_start_8168(struct net_device *dev) RTL_W16(IntrMitigate, 0x5151); /* Work around for RxFIFO overflow. */ - if (tp->mac_version == RTL_GIGA_MAC_VER_11) { + if (tp->mac_version == RTL_GIGA_MAC_VER_11 || + tp->mac_version == RTL_GIGA_MAC_VER_22) { tp->intr_event |= RxFIFOOver | PCSTimeout; tp->intr_event &= ~RxOverflow; } @@ -4641,7 +4642,8 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) /* Work around for rx fifo overflow */ if (unlikely(status & RxFIFOOver) && - (tp->mac_version == RTL_GIGA_MAC_VER_11)) { + (tp->mac_version == RTL_GIGA_MAC_VER_11 || + tp->mac_version == RTL_GIGA_MAC_VER_22)) { netif_stop_queue(dev); rtl8169_tx_timeout(dev); break; -- cgit v1.2.3 From 1519e57fe81c14bb8fa4855579f19264d1ef63b4 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Thu, 3 Feb 2011 12:02:36 +0100 Subject: r8169: RxFIFO overflow oddities with 8168 chipsets. Some experiment-based action to prevent my 8168 chipsets locking-up hard in the irq handler under load (pktgen ~1Mpps). Apparently a reset is not always mandatory (is it at all ?). - RTL_GIGA_MAC_VER_12 - RTL_GIGA_MAC_VER_25 Missed ~55% packets. Note: - this is an old SiS 965L motherboard - the 8168 chipset emits (lots of) control frames towards the sender - RTL_GIGA_MAC_VER_26 The chipset does not go into a frenzy of mac control pause when it crashes yet but it can still be crashed. It needs more work. Signed-off-by: Francois Romieu Cc: Ivan Vecera Cc: Hayes --- drivers/net/r8169.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 9ab3b43c7d04..40dabe2b3dae 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -973,7 +973,8 @@ static void __rtl8169_check_link_status(struct net_device *dev, if (pm) pm_request_resume(&tp->pci_dev->dev); netif_carrier_on(dev); - netif_info(tp, ifup, dev, "link up\n"); + if (net_ratelimit()) + netif_info(tp, ifup, dev, "link up\n"); } else { netif_carrier_off(dev); netif_info(tp, ifdown, dev, "link down\n"); @@ -4640,13 +4641,24 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) break; } - /* Work around for rx fifo overflow */ - if (unlikely(status & RxFIFOOver) && - (tp->mac_version == RTL_GIGA_MAC_VER_11 || - tp->mac_version == RTL_GIGA_MAC_VER_22)) { - netif_stop_queue(dev); - rtl8169_tx_timeout(dev); - break; + if (unlikely(status & RxFIFOOver)) { + switch (tp->mac_version) { + /* Work around for rx fifo overflow */ + case RTL_GIGA_MAC_VER_11: + case RTL_GIGA_MAC_VER_22: + case RTL_GIGA_MAC_VER_26: + netif_stop_queue(dev); + rtl8169_tx_timeout(dev); + goto done; + /* Experimental science. Pktgen proof. */ + case RTL_GIGA_MAC_VER_12: + case RTL_GIGA_MAC_VER_25: + if (status == RxFIFOOver) + goto done; + break; + default: + break; + } } if (unlikely(status & SYSErr)) { @@ -4682,7 +4694,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) (status & RxFIFOOver) ? (status | RxOverflow) : status); status = RTL_R16(IntrStatus); } - +done: return IRQ_RETVAL(handled); } -- cgit v1.2.3 From f60ac8e7ab7cbb413a0131d5665b053f9f386526 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Thu, 3 Feb 2011 17:27:52 +0100 Subject: r8169: prevent RxFIFO induced loops in the irq handler. While the RxFIFO interruption is masked for most 8168, nothing prevents it to appear in the irq status word. This is no excuse to crash. Signed-off-by: Francois Romieu Cc: Ivan Vecera Cc: Hayes --- drivers/net/r8169.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 40dabe2b3dae..59ccf0c5c610 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -4650,6 +4650,15 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) netif_stop_queue(dev); rtl8169_tx_timeout(dev); goto done; + /* Testers needed. */ + case RTL_GIGA_MAC_VER_17: + case RTL_GIGA_MAC_VER_19: + case RTL_GIGA_MAC_VER_20: + case RTL_GIGA_MAC_VER_21: + case RTL_GIGA_MAC_VER_23: + case RTL_GIGA_MAC_VER_24: + case RTL_GIGA_MAC_VER_27: + case RTL_GIGA_MAC_VER_28: /* Experimental science. Pktgen proof. */ case RTL_GIGA_MAC_VER_12: case RTL_GIGA_MAC_VER_25: -- cgit v1.2.3 From fef52b0171dfd7dd9b85c9cc201bd433b42a8ded Mon Sep 17 00:00:00 2001 From: Vasiliy Kulikov Date: Fri, 4 Feb 2011 02:23:50 +0000 Subject: net: can: at91_can: world-writable sysfs files Don't allow everybody to write to mb0_id file. Signed-off-by: Vasiliy Kulikov Acked-by: Kurt Van Dijck Signed-off-by: David S. Miller --- drivers/net/can/at91_can.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index 2532b9631538..57d2ffbbb433 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c @@ -1109,7 +1109,7 @@ static ssize_t at91_sysfs_set_mb0_id(struct device *dev, return ret; } -static DEVICE_ATTR(mb0_id, S_IWUGO | S_IRUGO, +static DEVICE_ATTR(mb0_id, S_IWUSR | S_IRUGO, at91_sysfs_show_mb0_id, at91_sysfs_set_mb0_id); static struct attribute *at91_sysfs_attrs[] = { -- cgit v1.2.3 From 1e6d93e45b231b3ae87c01902ede2315aacfe976 Mon Sep 17 00:00:00 2001 From: Vasiliy Kulikov Date: Fri, 4 Feb 2011 02:23:53 +0000 Subject: net: can: janz-ican3: world-writable sysfs termination file Don't allow everybody to set terminator via sysfs. Signed-off-by: Vasiliy Kulikov Signed-off-by: David S. Miller --- drivers/net/can/janz-ican3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/can/janz-ican3.c b/drivers/net/can/janz-ican3.c index b9a6d7a5a739..366f5cc050ae 100644 --- a/drivers/net/can/janz-ican3.c +++ b/drivers/net/can/janz-ican3.c @@ -1618,7 +1618,7 @@ static ssize_t ican3_sysfs_set_term(struct device *dev, return count; } -static DEVICE_ATTR(termination, S_IWUGO | S_IRUGO, ican3_sysfs_show_term, +static DEVICE_ATTR(termination, S_IWUSR | S_IRUGO, ican3_sysfs_show_term, ican3_sysfs_set_term); static struct attribute *ican3_sysfs_attrs[] = { -- cgit v1.2.3