From 397f385bdba6cdf7752467a7ae81810340929e44 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Wed, 19 May 2010 10:30:49 +0900 Subject: ath5k: wake queues on reset We can wake all queues after a chip reset since everything should be set up and we are ready to transmit. If we don't do that we might end up starting up with stopped queues, not beeing able to transmit. (This started to happen after "ath5k: clean up queue manipulation" but since periodic calibration also stopped and started the queues this effect was hidden most of the time). This way we can also get rid of the superfluous ath5k_reset_wake() function. Signed-off-by: Bruno Randolf Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index cc6d41dec332..2978359c4366 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -222,7 +222,6 @@ static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb); static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, struct ath5k_txq *txq); static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan); -static int ath5k_reset_wake(struct ath5k_softc *sc); static int ath5k_start(struct ieee80211_hw *hw); static void ath5k_stop(struct ieee80211_hw *hw); static int ath5k_add_interface(struct ieee80211_hw *hw, @@ -2770,7 +2769,7 @@ ath5k_tasklet_reset(unsigned long data) { struct ath5k_softc *sc = (void *)data; - ath5k_reset_wake(sc); + ath5k_reset(sc, sc->curchan); } /* @@ -2941,23 +2940,13 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan) ath5k_beacon_config(sc); /* intrs are enabled by ath5k_beacon_config */ + ieee80211_wake_queues(sc->hw); + return 0; err: return ret; } -static int -ath5k_reset_wake(struct ath5k_softc *sc) -{ - int ret; - - ret = ath5k_reset(sc, sc->curchan); - if (!ret) - ieee80211_wake_queues(sc->hw); - - return ret; -} - static int ath5k_start(struct ieee80211_hw *hw) { return ath5k_init(hw->priv); -- cgit v1.2.3 From f048fa9c8686119c3858a463cab6121dced7c0bf Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Tue, 1 Jun 2010 15:05:36 +0000 Subject: bnx2: Fix hang during rmmod bnx2. The regression is caused by: commit 4327ba435a56ada13eedf3eb332e583c7a0586a9 bnx2: Fix netpoll crash. If ->open() and ->close() are called multiple times, the same napi structs will be added to dev->napi_list multiple times, corrupting the dev->napi_list. This causes free_netdev() to hang during rmmod. We fix this by calling netif_napi_del() during ->close(). Also, bnx2_init_napi() must not be in the __devinit section since it is called by ->open(). Signed-off-by: Michael Chan Signed-off-by: Benjamin Li Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 188e356c30a3..949d7a9dcf92 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -247,6 +247,7 @@ static const struct flash_spec flash_5709 = { MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl); static void bnx2_init_napi(struct bnx2 *bp); +static void bnx2_del_napi(struct bnx2 *bp); static inline u32 bnx2_tx_avail(struct bnx2 *bp, struct bnx2_tx_ring_info *txr) { @@ -6270,6 +6271,7 @@ open_err: bnx2_free_skbs(bp); bnx2_free_irq(bp); bnx2_free_mem(bp); + bnx2_del_napi(bp); return rc; } @@ -6537,6 +6539,7 @@ bnx2_close(struct net_device *dev) bnx2_free_irq(bp); bnx2_free_skbs(bp); bnx2_free_mem(bp); + bnx2_del_napi(bp); bp->link_up = 0; netif_carrier_off(bp->dev); bnx2_set_power_state(bp, PCI_D3hot); @@ -8227,7 +8230,16 @@ bnx2_bus_string(struct bnx2 *bp, char *str) return str; } -static void __devinit +static void +bnx2_del_napi(struct bnx2 *bp) +{ + int i; + + for (i = 0; i < bp->irq_nvecs; i++) + netif_napi_del(&bp->bnx2_napi[i].napi); +} + +static void bnx2_init_napi(struct bnx2 *bp) { int i; -- cgit v1.2.3 From 08f382ebb8a9efb898840aa74cf55148c7a98af6 Mon Sep 17 00:00:00 2001 From: Scott Feldman Date: Tue, 1 Jun 2010 08:59:33 +0000 Subject: enic: bug fix: make the set/get netlink VF_PORT support symmetrical To make get/set netlink VF_PORT truly symmetrical, we need to keep track of what items are set and only return those items on get. Previously, the driver wasn't differentiating between a set of attr with a NULL string, for example, and not setting the attr at all. We only want to return the NULL string if the attr was actually set with a NULL string. Otherwise, don't return the attr. Signed-off-by: Scott Feldman Signed-off-by: David S. Miller --- drivers/net/enic/enic.h | 7 ++ drivers/net/enic/enic_main.c | 200 +++++++++++++++++++++---------------------- 2 files changed, 104 insertions(+), 103 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index 85f2a2e7030a..45e86d1e5b1b 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -74,7 +74,14 @@ struct enic_msix_entry { void *devid; }; +#define ENIC_SET_APPLIED (1 << 0) +#define ENIC_SET_REQUEST (1 << 1) +#define ENIC_SET_NAME (1 << 2) +#define ENIC_SET_INSTANCE (1 << 3) +#define ENIC_SET_HOST (1 << 4) + struct enic_port_profile { + u32 set; u8 request; char name[PORT_PROFILE_MAX]; u8 instance_uuid[PORT_UUID_MAX]; diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 6586b5c7e4b6..bc7d6b96de3d 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -1029,8 +1029,7 @@ static int enic_dev_init_done(struct enic *enic, int *done, int *error) return err; } -static int enic_set_port_profile(struct enic *enic, u8 request, u8 *mac, - char *name, u8 *instance_uuid, u8 *host_uuid) +static int enic_set_port_profile(struct enic *enic, u8 *mac) { struct vic_provinfo *vp; u8 oui[3] = VIC_PROVINFO_CISCO_OUI; @@ -1040,97 +1039,112 @@ static int enic_set_port_profile(struct enic *enic, u8 request, u8 *mac, "%02X%02X-%02X%02X%02X%02X%0X%02X"; int err; - if (!name) - return -EINVAL; + err = enic_vnic_dev_deinit(enic); + if (err) + return err; - if (!is_valid_ether_addr(mac)) - return -EADDRNOTAVAIL; + switch (enic->pp.request) { - vp = vic_provinfo_alloc(GFP_KERNEL, oui, VIC_PROVINFO_LINUX_TYPE); - if (!vp) - return -ENOMEM; + case PORT_REQUEST_ASSOCIATE: - vic_provinfo_add_tlv(vp, - VIC_LINUX_PROV_TLV_PORT_PROFILE_NAME_STR, - strlen(name) + 1, name); - - vic_provinfo_add_tlv(vp, - VIC_LINUX_PROV_TLV_CLIENT_MAC_ADDR, - ETH_ALEN, mac); - - if (instance_uuid) { - uuid = instance_uuid; - sprintf(uuid_str, uuid_fmt, - uuid[0], uuid[1], uuid[2], uuid[3], - uuid[4], uuid[5], uuid[6], uuid[7], - uuid[8], uuid[9], uuid[10], uuid[11], - uuid[12], uuid[13], uuid[14], uuid[15]); - vic_provinfo_add_tlv(vp, - VIC_LINUX_PROV_TLV_CLIENT_UUID_STR, - sizeof(uuid_str), uuid_str); - } + if (!(enic->pp.set & ENIC_SET_NAME) || !strlen(enic->pp.name)) + return -EINVAL; - if (host_uuid) { - uuid = host_uuid; - sprintf(uuid_str, uuid_fmt, - uuid[0], uuid[1], uuid[2], uuid[3], - uuid[4], uuid[5], uuid[6], uuid[7], - uuid[8], uuid[9], uuid[10], uuid[11], - uuid[12], uuid[13], uuid[14], uuid[15]); - vic_provinfo_add_tlv(vp, - VIC_LINUX_PROV_TLV_HOST_UUID_STR, - sizeof(uuid_str), uuid_str); - } + if (!is_valid_ether_addr(mac)) + return -EADDRNOTAVAIL; - err = enic_vnic_dev_deinit(enic); - if (err) - goto err_out; + vp = vic_provinfo_alloc(GFP_KERNEL, oui, + VIC_PROVINFO_LINUX_TYPE); + if (!vp) + return -ENOMEM; - memset(&enic->pp, 0, sizeof(enic->pp)); + vic_provinfo_add_tlv(vp, + VIC_LINUX_PROV_TLV_PORT_PROFILE_NAME_STR, + strlen(enic->pp.name) + 1, enic->pp.name); - err = enic_dev_init_prov(enic, vp); - if (err) - goto err_out; + vic_provinfo_add_tlv(vp, + VIC_LINUX_PROV_TLV_CLIENT_MAC_ADDR, + ETH_ALEN, mac); + + if (enic->pp.set & ENIC_SET_INSTANCE) { + uuid = enic->pp.instance_uuid; + sprintf(uuid_str, uuid_fmt, + uuid[0], uuid[1], uuid[2], uuid[3], + uuid[4], uuid[5], uuid[6], uuid[7], + uuid[8], uuid[9], uuid[10], uuid[11], + uuid[12], uuid[13], uuid[14], uuid[15]); + vic_provinfo_add_tlv(vp, + VIC_LINUX_PROV_TLV_CLIENT_UUID_STR, + sizeof(uuid_str), uuid_str); + } - enic->pp.request = request; - memcpy(enic->pp.name, name, PORT_PROFILE_MAX); - if (instance_uuid) - memcpy(enic->pp.instance_uuid, - instance_uuid, PORT_UUID_MAX); - if (host_uuid) - memcpy(enic->pp.host_uuid, - host_uuid, PORT_UUID_MAX); + if (enic->pp.set & ENIC_SET_HOST) { + uuid = enic->pp.host_uuid; + sprintf(uuid_str, uuid_fmt, + uuid[0], uuid[1], uuid[2], uuid[3], + uuid[4], uuid[5], uuid[6], uuid[7], + uuid[8], uuid[9], uuid[10], uuid[11], + uuid[12], uuid[13], uuid[14], uuid[15]); + vic_provinfo_add_tlv(vp, + VIC_LINUX_PROV_TLV_HOST_UUID_STR, + sizeof(uuid_str), uuid_str); + } -err_out: - vic_provinfo_free(vp); + err = enic_dev_init_prov(enic, vp); + vic_provinfo_free(vp); + if (err) + return err; + break; - return err; -} + case PORT_REQUEST_DISASSOCIATE: + break; -static int enic_unset_port_profile(struct enic *enic) -{ - memset(&enic->pp, 0, sizeof(enic->pp)); - return enic_vnic_dev_deinit(enic); + default: + return -EINVAL; + } + + enic->pp.set |= ENIC_SET_APPLIED; + return 0; } static int enic_set_vf_port(struct net_device *netdev, int vf, struct nlattr *port[]) { struct enic *enic = netdev_priv(netdev); - char *name = NULL; - u8 *instance_uuid = NULL; - u8 *host_uuid = NULL; - u8 request = PORT_REQUEST_DISASSOCIATE; + + memset(&enic->pp, 0, sizeof(enic->pp)); + + if (port[IFLA_PORT_REQUEST]) { + enic->pp.set |= ENIC_SET_REQUEST; + enic->pp.request = nla_get_u8(port[IFLA_PORT_REQUEST]); + } + + if (port[IFLA_PORT_PROFILE]) { + enic->pp.set |= ENIC_SET_NAME; + memcpy(enic->pp.name, nla_data(port[IFLA_PORT_PROFILE]), + PORT_PROFILE_MAX); + } + + if (port[IFLA_PORT_INSTANCE_UUID]) { + enic->pp.set |= ENIC_SET_INSTANCE; + memcpy(enic->pp.instance_uuid, + nla_data(port[IFLA_PORT_INSTANCE_UUID]), PORT_UUID_MAX); + } + + if (port[IFLA_PORT_HOST_UUID]) { + enic->pp.set |= ENIC_SET_HOST; + memcpy(enic->pp.host_uuid, + nla_data(port[IFLA_PORT_HOST_UUID]), PORT_UUID_MAX); + } /* don't support VFs, yet */ if (vf != PORT_SELF_VF) return -EOPNOTSUPP; - if (port[IFLA_PORT_REQUEST]) - request = nla_get_u8(port[IFLA_PORT_REQUEST]); + if (!(enic->pp.set & ENIC_SET_REQUEST)) + return -EOPNOTSUPP; - switch (request) { - case PORT_REQUEST_ASSOCIATE: + if (enic->pp.request == PORT_REQUEST_ASSOCIATE) { /* If the interface mac addr hasn't been assigned, * assign a random mac addr before setting port- @@ -1139,30 +1153,9 @@ static int enic_set_vf_port(struct net_device *netdev, int vf, if (is_zero_ether_addr(netdev->dev_addr)) random_ether_addr(netdev->dev_addr); - - if (port[IFLA_PORT_PROFILE]) - name = nla_data(port[IFLA_PORT_PROFILE]); - - if (port[IFLA_PORT_INSTANCE_UUID]) - instance_uuid = - nla_data(port[IFLA_PORT_INSTANCE_UUID]); - - if (port[IFLA_PORT_HOST_UUID]) - host_uuid = nla_data(port[IFLA_PORT_HOST_UUID]); - - return enic_set_port_profile(enic, request, - netdev->dev_addr, name, - instance_uuid, host_uuid); - - case PORT_REQUEST_DISASSOCIATE: - - return enic_unset_port_profile(enic); - - default: - break; } - return -EOPNOTSUPP; + return enic_set_port_profile(enic, netdev->dev_addr); } static int enic_get_vf_port(struct net_device *netdev, int vf, @@ -1172,14 +1165,12 @@ static int enic_get_vf_port(struct net_device *netdev, int vf, int err, error, done; u16 response = PORT_PROFILE_RESPONSE_SUCCESS; - /* don't support VFs, yet */ - if (vf != PORT_SELF_VF) - return -EOPNOTSUPP; + if (!(enic->pp.set & ENIC_SET_APPLIED)) + return -ENODATA; err = enic_dev_init_done(enic, &done, &error); - if (err) - return err; + error = err; switch (error) { case ERR_SUCCESS: @@ -1202,12 +1193,15 @@ static int enic_get_vf_port(struct net_device *netdev, int vf, NLA_PUT_U16(skb, IFLA_PORT_REQUEST, enic->pp.request); NLA_PUT_U16(skb, IFLA_PORT_RESPONSE, response); - NLA_PUT(skb, IFLA_PORT_PROFILE, PORT_PROFILE_MAX, - enic->pp.name); - NLA_PUT(skb, IFLA_PORT_INSTANCE_UUID, PORT_UUID_MAX, - enic->pp.instance_uuid); - NLA_PUT(skb, IFLA_PORT_HOST_UUID, PORT_UUID_MAX, - enic->pp.host_uuid); + if (enic->pp.set & ENIC_SET_NAME) + NLA_PUT(skb, IFLA_PORT_PROFILE, PORT_PROFILE_MAX, + enic->pp.name); + if (enic->pp.set & ENIC_SET_INSTANCE) + NLA_PUT(skb, IFLA_PORT_INSTANCE_UUID, PORT_UUID_MAX, + enic->pp.instance_uuid); + if (enic->pp.set & ENIC_SET_HOST) + NLA_PUT(skb, IFLA_PORT_HOST_UUID, PORT_UUID_MAX, + enic->pp.host_uuid); return 0; -- cgit v1.2.3 From ceb3d2394532540a52ce34f71e67c8d008913f79 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Sat, 29 May 2010 13:23:34 +0000 Subject: korina: fix deadlock on RX FIFO overrun By calling korina_restart(), the IRQ handler tries to disable the interrupt it's currently serving. This leads to a deadlock since disable_irq() waits for any running IRQ handlers to finish before returning. This patch addresses the issue by turning korina_restart() into a workqueue task, which is then scheduled when needed. Reproducing the deadlock is easily done using e.g. GNU netcat to send large amounts of UDP data to the host running this driver. Note that the same problem (and fix) applies to TX FIFO underruns, but apparently these are less easy to trigger. Signed-off-by: Phil Sutter Signed-off-by: David S. Miller --- drivers/net/korina.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/korina.c b/drivers/net/korina.c index 26bf1b76b997..13533f937e05 100644 --- a/drivers/net/korina.c +++ b/drivers/net/korina.c @@ -135,6 +135,7 @@ struct korina_private { struct napi_struct napi; struct timer_list media_check_timer; struct mii_if_info mii_if; + struct work_struct restart_task; struct net_device *dev; int phy_addr; }; @@ -890,12 +891,12 @@ static int korina_init(struct net_device *dev) /* * Restart the RC32434 ethernet controller. - * FIXME: check the return status where we call it */ -static int korina_restart(struct net_device *dev) +static void korina_restart_task(struct work_struct *work) { - struct korina_private *lp = netdev_priv(dev); - int ret; + struct korina_private *lp = container_of(work, + struct korina_private, restart_task); + struct net_device *dev = lp->dev; /* * Disable interrupts @@ -916,10 +917,9 @@ static int korina_restart(struct net_device *dev) napi_disable(&lp->napi); - ret = korina_init(dev); - if (ret < 0) { + if (korina_init(dev) < 0) { printk(KERN_ERR "%s: cannot restart device\n", dev->name); - return ret; + return; } korina_multicast_list(dev); @@ -927,8 +927,6 @@ static int korina_restart(struct net_device *dev) enable_irq(lp->ovr_irq); enable_irq(lp->tx_irq); enable_irq(lp->rx_irq); - - return ret; } static void korina_clear_and_restart(struct net_device *dev, u32 value) @@ -937,7 +935,7 @@ static void korina_clear_and_restart(struct net_device *dev, u32 value) netif_stop_queue(dev); writel(value, &lp->eth_regs->ethintfc); - korina_restart(dev); + schedule_work(&lp->restart_task); } /* Ethernet Tx Underflow interrupt */ @@ -962,11 +960,8 @@ static irqreturn_t korina_und_interrupt(int irq, void *dev_id) static void korina_tx_timeout(struct net_device *dev) { struct korina_private *lp = netdev_priv(dev); - unsigned long flags; - spin_lock_irqsave(&lp->lock, flags); - korina_restart(dev); - spin_unlock_irqrestore(&lp->lock, flags); + schedule_work(&lp->restart_task); } /* Ethernet Rx Overflow interrupt */ @@ -1086,6 +1081,8 @@ static int korina_close(struct net_device *dev) napi_disable(&lp->napi); + cancel_work_sync(&lp->restart_task); + free_irq(lp->rx_irq, dev); free_irq(lp->tx_irq, dev); free_irq(lp->ovr_irq, dev); @@ -1198,6 +1195,8 @@ static int korina_probe(struct platform_device *pdev) } setup_timer(&lp->media_check_timer, korina_poll_media, (unsigned long) dev); + INIT_WORK(&lp->restart_task, korina_restart_task); + printk(KERN_INFO "%s: " DRV_NAME "-" DRV_VERSION " " DRV_RELDATE "\n", dev->name); out: -- cgit v1.2.3 From 53ee490ac5836d506ea5830f821045aafa3c196f Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Sat, 29 May 2010 13:23:35 +0000 Subject: korina: use netdev_alloc_skb_ip_align() here, too This patch completes commit 89d71a66c40d629e3b1285def543ab1425558cd5 which missed this spot, as it seems. Signed-off-by: Phil Sutter Signed-off-by: David S. Miller --- drivers/net/korina.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/korina.c b/drivers/net/korina.c index 13533f937e05..3e9b6b7be42e 100644 --- a/drivers/net/korina.c +++ b/drivers/net/korina.c @@ -765,10 +765,9 @@ static int korina_alloc_ring(struct net_device *dev) /* Initialize the receive descriptors */ for (i = 0; i < KORINA_NUM_RDS; i++) { - skb = dev_alloc_skb(KORINA_RBSIZE + 2); + skb = netdev_alloc_skb_ip_align(dev, KORINA_RBSIZE); if (!skb) return -ENOMEM; - skb_reserve(skb, 2); lp->rx_skb[i] = skb; lp->rd_ring[i].control = DMA_DESC_IOD | DMA_COUNT(KORINA_RBSIZE); -- cgit v1.2.3 From b1011b375be106e0a312baafc981a26165283efe Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Sat, 29 May 2010 13:23:36 +0000 Subject: korina: count RX DMA OVR as rx_fifo_error This way, RX DMA overruns (actually being caused by overrun of the 512byte input FIFO) show up in ifconfig output. The rx_fifo_errors counter is unused otherwise. Signed-off-by: Phil Sutter Signed-off-by: David S. Miller --- drivers/net/korina.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/korina.c b/drivers/net/korina.c index 3e9b6b7be42e..c7a9bef4dfb0 100644 --- a/drivers/net/korina.c +++ b/drivers/net/korina.c @@ -376,7 +376,7 @@ static int korina_rx(struct net_device *dev, int limit) if (devcs & ETH_RX_LE) dev->stats.rx_length_errors++; if (devcs & ETH_RX_OVR) - dev->stats.rx_over_errors++; + dev->stats.rx_fifo_errors++; if (devcs & ETH_RX_CV) dev->stats.rx_frame_errors++; if (devcs & ETH_RX_CES) -- cgit v1.2.3 From e3fe8558c7fc182972c3d947d88744482111f304 Mon Sep 17 00:00:00 2001 From: Eric Bénard Date: Wed, 2 Jun 2010 06:13:34 -0700 Subject: net/fec: fix pm to survive to suspend/resume MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * in the actual driver, calling fec_stop and fec_enet_init doesn't allow to have a working network interface at resume (where a ifconfig down and up is required to recover the interface) * by using fec_enet_close and fec_enet_open, this patch solves this problem and handle the case where the link changed between suspend and resume * this patch also disable clock at suspend and reenable it at resume Signed-off-by: Eric Bénard Signed-off-by: David S. Miller --- drivers/net/fec.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/fec.c b/drivers/net/fec.c index ddf7a86cd466..edfff92a6d8e 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -1373,10 +1373,9 @@ fec_suspend(struct platform_device *dev, pm_message_t state) if (ndev) { fep = netdev_priv(ndev); - if (netif_running(ndev)) { - netif_device_detach(ndev); - fec_stop(ndev); - } + if (netif_running(ndev)) + fec_enet_close(ndev); + clk_disable(fep->clk); } return 0; } @@ -1385,12 +1384,13 @@ static int fec_resume(struct platform_device *dev) { struct net_device *ndev = platform_get_drvdata(dev); + struct fec_enet_private *fep; if (ndev) { - if (netif_running(ndev)) { - fec_enet_init(ndev, 0); - netif_device_attach(ndev); - } + fep = netdev_priv(ndev); + clk_enable(fep->clk); + if (netif_running(ndev)) + fec_enet_open(ndev); } return 0; } -- cgit v1.2.3 From d42a8f464ba14467e5d45dc0eb8f789c82bd0679 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 1 Jun 2010 11:32:43 +0000 Subject: sfc: Get port number from CS_PORT_NUM, not PCI function number A single shared memory region used to communicate with firmware is mapped into both PCI PFs of the SFC9020 and SFL9021. Drivers must be able to identify which port they are addressing in order to use the correct sub-region. Currently we use the PCI function number, but the PCI address may be virtualised. Use the CS_PORT_NUM register field defined for just this purpose. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/net_driver.h | 4 +++- drivers/net/sfc/siena.c | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 2e6fd89f2a72..5fffd9abffde 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -645,6 +645,7 @@ union efx_multicast_hash { * struct efx_nic - an Efx NIC * @name: Device name (net device name or bus id before net device registered) * @pci_dev: The PCI device + * @port_num: Index of this host port within the controller * @type: Controller type attributes * @legacy_irq: IRQ number * @workqueue: Workqueue for port reconfigures and the HW monitor. @@ -728,6 +729,7 @@ union efx_multicast_hash { struct efx_nic { char name[IFNAMSIZ]; struct pci_dev *pci_dev; + unsigned port_num; const struct efx_nic_type *type; int legacy_irq; struct workqueue_struct *workqueue; @@ -830,7 +832,7 @@ static inline const char *efx_dev_name(struct efx_nic *efx) static inline unsigned int efx_port_num(struct efx_nic *efx) { - return PCI_FUNC(efx->pci_dev->devfn); + return efx->port_num; } /** diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c index 727b4228e081..7ecd255a7cc0 100644 --- a/drivers/net/sfc/siena.c +++ b/drivers/net/sfc/siena.c @@ -206,6 +206,7 @@ static int siena_probe_nic(struct efx_nic *efx) { struct siena_nic_data *nic_data; bool already_attached = 0; + efx_oword_t reg; int rc; /* Allocate storage for hardware specific data */ @@ -220,6 +221,9 @@ static int siena_probe_nic(struct efx_nic *efx) goto fail1; } + efx_reado(efx, ®, FR_AZ_CS_DEBUG); + efx->port_num = EFX_OWORD_FIELD(reg, FRF_CZ_CS_PORT_NUM) - 1; + efx_mcdi_init(efx); /* Recover from a failed assertion before probing */ -- cgit v1.2.3 From 3b21b508ecc9e043839a5337563cfc77f9fcedb9 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 2 Jun 2010 13:43:15 +0000 Subject: e1000e: change logical negate to bitwise The bitwise negate is intended here. With the logical negate the condition is always false. Signed-off-by: Dan Carpenter Acked-by: Bruce Allan Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/e1000e/netdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 24507f3b8b17..57a7e41da69e 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -2554,7 +2554,7 @@ static void e1000_init_manageability_pt(struct e1000_adapter *adapter) mdef = er32(MDEF(i)); /* Ignore filters with anything other than IPMI ports */ - if (mdef & !(E1000_MDEF_PORT_623 | E1000_MDEF_PORT_664)) + if (mdef & ~(E1000_MDEF_PORT_623 | E1000_MDEF_PORT_664)) continue; /* Enable this decision filter in MANC2H */ -- cgit v1.2.3 From d23380701876dd93d310b2548c51d0f78f25d7aa Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 3 Jun 2010 00:05:35 +0000 Subject: tehuti: return -EFAULT on copy_to_user errors copy_to_user() returns the number of bytes remaining but we want to return a negative error code here. Signed-off-by: Dan Carpenter 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 20ab16192325..737df6032bbc 100644 --- a/drivers/net/tehuti.c +++ b/drivers/net/tehuti.c @@ -646,7 +646,7 @@ static int bdx_ioctl_priv(struct net_device *ndev, struct ifreq *ifr, int cmd) error = copy_from_user(data, ifr->ifr_data, sizeof(data)); if (error) { pr_err("cant copy from user\n"); - RET(error); + RET(-EFAULT); } DBG("%d 0x%x 0x%x\n", data[0], data[1], data[2]); } @@ -665,7 +665,7 @@ static int bdx_ioctl_priv(struct net_device *ndev, struct ifreq *ifr, int cmd) data[2]); error = copy_to_user(ifr->ifr_data, data, sizeof(data)); if (error) - RET(error); + RET(-EFAULT); break; case BDX_OP_WRITE: -- cgit v1.2.3 From 9e2d11b926765681f72db0373d2ecbbac28359b3 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Wed, 2 Jun 2010 10:36:53 +0000 Subject: epic100: Test __BIG_ENDIAN instead of (non-existent) CONFIG_BIG_ENDIAN Probably no one has used this driver on big-endian systems, since it was setting up descriptor swapping if CONFIG_BIG_ENDIAN is set, which it never is, since that symbol is not mentioned anywhere else in the kernel source. Switch this test to a check for __BIG_ENDIAN so it has a chance at working. Signed-off-by: Roland Dreier Acked-by: Jeff Garzik Signed-off-by: David S. Miller --- drivers/net/epic100.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c index 6838dfc9ef23..4c274657283c 100644 --- a/drivers/net/epic100.c +++ b/drivers/net/epic100.c @@ -87,6 +87,7 @@ static int rx_copybreak; #include #include #include +#include /* These identify the driver base version and may not be removed. */ static char version[] __devinitdata = @@ -230,7 +231,7 @@ static const u16 media2miictl[16] = { * The EPIC100 Rx and Tx buffer descriptors. Note that these * really ARE host-endian; it's not a misannotation. We tell * the card to byteswap them internally on big-endian hosts - - * look for #ifdef CONFIG_BIG_ENDIAN in epic_open(). + * look for #ifdef __BIG_ENDIAN in epic_open(). */ struct epic_tx_desc { @@ -690,7 +691,7 @@ static int epic_open(struct net_device *dev) outl((inl(ioaddr + NVCTL) & ~0x003C) | 0x4800, ioaddr + NVCTL); /* Tell the chip to byteswap descriptors on big-endian hosts */ -#ifdef CONFIG_BIG_ENDIAN +#ifdef __BIG_ENDIAN outl(0x4432 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL); inl(ioaddr + GENCTL); outl(0x0432 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL); @@ -806,7 +807,7 @@ static void epic_restart(struct net_device *dev) for (i = 16; i > 0; i--) outl(0x0008, ioaddr + TEST1); -#ifdef CONFIG_BIG_ENDIAN +#ifdef __BIG_ENDIAN outl(0x0432 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL); #else outl(0x0412 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL); -- cgit v1.2.3 From 3df95ce948dc8ceef07b49003ab944aa047f2a79 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 2 Jun 2010 10:39:56 +0000 Subject: sfc: Store port number in net_device::dev_id This exposes the port number to userland through sysfs. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/net_driver.h | 4 +--- drivers/net/sfc/siena.c | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 5fffd9abffde..4762c91cb587 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -645,7 +645,6 @@ union efx_multicast_hash { * struct efx_nic - an Efx NIC * @name: Device name (net device name or bus id before net device registered) * @pci_dev: The PCI device - * @port_num: Index of this host port within the controller * @type: Controller type attributes * @legacy_irq: IRQ number * @workqueue: Workqueue for port reconfigures and the HW monitor. @@ -729,7 +728,6 @@ union efx_multicast_hash { struct efx_nic { char name[IFNAMSIZ]; struct pci_dev *pci_dev; - unsigned port_num; const struct efx_nic_type *type; int legacy_irq; struct workqueue_struct *workqueue; @@ -832,7 +830,7 @@ static inline const char *efx_dev_name(struct efx_nic *efx) static inline unsigned int efx_port_num(struct efx_nic *efx) { - return efx->port_num; + return efx->net_dev->dev_id; } /** diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c index 7ecd255a7cc0..f2b1e6180753 100644 --- a/drivers/net/sfc/siena.c +++ b/drivers/net/sfc/siena.c @@ -222,7 +222,7 @@ static int siena_probe_nic(struct efx_nic *efx) } efx_reado(efx, ®, FR_AZ_CS_DEBUG); - efx->port_num = EFX_OWORD_FIELD(reg, FRF_CZ_CS_PORT_NUM) - 1; + efx->net_dev->dev_id = EFX_OWORD_FIELD(reg, FRF_CZ_CS_PORT_NUM) - 1; efx_mcdi_init(efx); -- cgit v1.2.3 From a1868dc2878e61778b9d6d8c61d5368e51d68a29 Mon Sep 17 00:00:00 2001 From: Jeff Kirsher Date: Wed, 2 Jun 2010 12:44:05 +0000 Subject: ixgbe: return IXGBE_ERR_RAR_INDEX when out of range Based on original patch from Shirley Ma Return IXGBE_ERR_RAR_INDEX when RAR index is out of range, instead of returning IXGBE_SUCCESS. CC: Shirley Ma Signed-off-by: Jeff Kirsher Acked-by: Don Skidmore Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_common.c | 2 ++ drivers/net/ixgbe/ixgbe_type.h | 1 + 2 files changed, 3 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index 1159d9138f05..9595b1bfb8dd 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -1188,6 +1188,7 @@ s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq, IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high); } else { hw_dbg(hw, "RAR index %d is out of range.\n", index); + return IXGBE_ERR_RAR_INDEX; } return 0; @@ -1219,6 +1220,7 @@ s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index) IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high); } else { hw_dbg(hw, "RAR index %d is out of range.\n", index); + return IXGBE_ERR_RAR_INDEX; } /* clear VMDq pool/queue selection for this RAR */ diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 2eb6e151016c..cdd1998f18c7 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -2609,6 +2609,7 @@ struct ixgbe_info { #define IXGBE_ERR_EEPROM_VERSION -24 #define IXGBE_ERR_NO_SPACE -25 #define IXGBE_ERR_OVERTEMP -26 +#define IXGBE_ERR_RAR_INDEX -27 #define IXGBE_NOT_IMPLEMENTED 0x7FFFFFFF #endif /* _IXGBE_TYPE_H_ */ -- cgit v1.2.3 From ca739481662137b8f717bc21f16719cda3c33d6b Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Thu, 3 Jun 2010 17:03:45 +0000 Subject: ixgbe: only check pfc bits in hang logic if pfc is enabled Only check pfc bits in hang logic if PFC is enabled. Previously, if DCB was enabled but PFC was disabled the incorrect pause bits would be checked. Signed-off-by: John Fastabend Acked-by: Don Skidmore Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index d571d101de08..b2af2f67f604 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -642,7 +642,7 @@ static inline bool ixgbe_tx_xon_state(struct ixgbe_adapter *adapter, u32 txoff = IXGBE_TFCS_TXOFF; #ifdef CONFIG_IXGBE_DCB - if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { + if (adapter->dcb_cfg.pfc_mode_enable) { int tc; int reg_idx = tx_ring->reg_idx; int dcb_i = adapter->ring_feature[RING_F_DCB].indices; -- cgit v1.2.3 From 536e00e570c87f258554e919c444b81a7002e46d Mon Sep 17 00:00:00 2001 From: Ben McKeegan Date: Wed, 2 Jun 2010 23:14:33 +0000 Subject: ppp_generic: fix multilink fragment sizes Fix bug in multilink fragment size calculation introduced by commit 9c705260feea6ae329bc6b6d5f6d2ef0227eda0a "ppp: ppp_mp_explode() redesign" Signed-off-by: Ben McKeegan Signed-off-by: David S. Miller --- drivers/net/ppp_generic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index c5f8eb102bf7..1b2c29150202 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -1422,7 +1422,7 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb) flen = len; if (nfree > 0) { if (pch->speed == 0) { - flen = totlen/nfree; + flen = len/nfree; if (nbigger > 0) { flen++; nbigger--; -- cgit v1.2.3 From ca7335948e294faf8adf65f2c95ca18ea78540db Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Fri, 4 Jun 2010 16:14:15 -0700 Subject: X25: remove duplicated #include Remove duplicated #include('s) in drivers/net/wan/x25_asy.c Signed-off-by: Huang Weiyi Signed-off-by: David S. Miller --- drivers/net/wan/x25_asy.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c index 166e77dfffda..e47f5a986b1c 100644 --- a/drivers/net/wan/x25_asy.c +++ b/drivers/net/wan/x25_asy.c @@ -37,8 +37,6 @@ #include #include "x25_asy.h" -#include - static struct net_device **x25_asy_devs; static int x25_asy_maxdev = SL_NRUNIT; -- cgit v1.2.3