From d938a702e5ce8909ea68be97566150507bfea4df Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Wed, 26 May 2010 00:33:43 -0700 Subject: be2net: increase POST timeout for EEH recovery Sometimes BE requires longer time for POST completion after an EEH reset. Increasing the timeout value accordingly. Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/benet/be_cmds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index c911bfb..9d11dbf 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -294,7 +294,7 @@ int be_cmd_POST(struct be_adapter *adapter) } else { return 0; } - } while (timeout < 20); + } while (timeout < 40); dev_err(&adapter->pdev->dev, "POST timeout; stage=0x%x\n", stage); return -1; -- cgit v1.1 From 755fae0ac41672523a3ac00d41fe9bac226b0578 Mon Sep 17 00:00:00 2001 From: Brian Hill Date: Wed, 26 May 2010 20:42:18 -0700 Subject: net: ll_temac: fix interrupt bug when interrupt 0 is used The code is not checking the interrupt for DMA correctly so that an interrupt number of 0 will cause a false error. Signed-off-by: Brian Hill Signed-off-by: John Linn Signed-off-by: David S. Miller --- drivers/net/ll_temac_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c index b59b24d..1bb6e60 100644 --- a/drivers/net/ll_temac_main.c +++ b/drivers/net/ll_temac_main.c @@ -950,7 +950,7 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match) lp->rx_irq = irq_of_parse_and_map(np, 0); lp->tx_irq = irq_of_parse_and_map(np, 1); - if (!lp->rx_irq || !lp->tx_irq) { + if ((lp->rx_irq == NO_IRQ) || (lp->tx_irq == NO_IRQ)) { dev_err(&op->dev, "could not determine irqs\n"); rc = -ENOMEM; goto nodev; -- cgit v1.1 From 23ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3 Mon Sep 17 00:00:00 2001 From: Brian Hill Date: Wed, 26 May 2010 20:44:30 -0700 Subject: net: ll_temac: fix checksum offload logic The current checksum offload code does not work and this corrects that functionality. It also updates the interrupt coallescing initialization so than there are fewer interrupts and performance is increased. Signed-off-by: Brian Hill Signed-off-by: John Linn Signed-off-by: David S. Miller --- drivers/net/ll_temac.h | 5 +++ drivers/net/ll_temac_main.c | 82 ++++++++++++++++++++++++++++++++------------- 2 files changed, 63 insertions(+), 24 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ll_temac.h b/drivers/net/ll_temac.h index c033584..522abe2 100644 --- a/drivers/net/ll_temac.h +++ b/drivers/net/ll_temac.h @@ -295,6 +295,10 @@ This option defaults to enabled (set) */ #define MULTICAST_CAM_TABLE_NUM 4 +/* TEMAC Synthesis features */ +#define TEMAC_FEATURE_RX_CSUM (1 << 0) +#define TEMAC_FEATURE_TX_CSUM (1 << 1) + /* TX/RX CURDESC_PTR points to first descriptor */ /* TX/RX TAILDESC_PTR points to last descriptor in linked list */ @@ -353,6 +357,7 @@ struct temac_local { struct mutex indirect_mutex; u32 options; /* Current options word */ int last_link; + unsigned int temac_features; /* Buffer descriptors */ struct cdmac_bd *tx_bd_v; diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c index 1bb6e60..fbd07de 100644 --- a/drivers/net/ll_temac_main.c +++ b/drivers/net/ll_temac_main.c @@ -245,7 +245,7 @@ static int temac_dma_bd_init(struct net_device *ndev) CHNL_CTRL_IRQ_COAL_EN); /* 0x10220483 */ /* 0x00100483 */ - lp->dma_out(lp, RX_CHNL_CTRL, 0xff010000 | + lp->dma_out(lp, RX_CHNL_CTRL, 0xff070000 | CHNL_CTRL_IRQ_EN | CHNL_CTRL_IRQ_DLY_EN | CHNL_CTRL_IRQ_COAL_EN | @@ -574,6 +574,10 @@ static void temac_start_xmit_done(struct net_device *ndev) if (cur_p->app4) dev_kfree_skb_irq((struct sk_buff *)cur_p->app4); cur_p->app0 = 0; + cur_p->app1 = 0; + cur_p->app2 = 0; + cur_p->app3 = 0; + cur_p->app4 = 0; ndev->stats.tx_packets++; ndev->stats.tx_bytes += cur_p->len; @@ -589,6 +593,29 @@ static void temac_start_xmit_done(struct net_device *ndev) netif_wake_queue(ndev); } +static inline int temac_check_tx_bd_space(struct temac_local *lp, int num_frag) +{ + struct cdmac_bd *cur_p; + int tail; + + tail = lp->tx_bd_tail; + cur_p = &lp->tx_bd_v[tail]; + + do { + if (cur_p->app0) + return NETDEV_TX_BUSY; + + tail++; + if (tail >= TX_BD_NUM) + tail = 0; + + cur_p = &lp->tx_bd_v[tail]; + num_frag--; + } while (num_frag >= 0); + + return 0; +} + static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) { struct temac_local *lp = netdev_priv(ndev); @@ -603,7 +630,7 @@ static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) start_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail; cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; - if (cur_p->app0 & STS_CTRL_APP0_CMPLT) { + if (temac_check_tx_bd_space(lp, num_frag)) { if (!netif_queue_stopped(ndev)) { netif_stop_queue(ndev); return NETDEV_TX_BUSY; @@ -613,29 +640,14 @@ static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) cur_p->app0 = 0; if (skb->ip_summed == CHECKSUM_PARTIAL) { - const struct iphdr *ip = ip_hdr(skb); - int length = 0, start = 0, insert = 0; - - switch (ip->protocol) { - case IPPROTO_TCP: - start = sizeof(struct iphdr) + ETH_HLEN; - insert = sizeof(struct iphdr) + ETH_HLEN + 16; - length = ip->tot_len - sizeof(struct iphdr); - break; - case IPPROTO_UDP: - start = sizeof(struct iphdr) + ETH_HLEN; - insert = sizeof(struct iphdr) + ETH_HLEN + 6; - length = ip->tot_len - sizeof(struct iphdr); - break; - default: - break; - } - cur_p->app1 = ((start << 16) | insert); - cur_p->app2 = csum_tcpudp_magic(ip->saddr, ip->daddr, - length, ip->protocol, 0); - skb->data[insert] = 0; - skb->data[insert + 1] = 0; + unsigned int csum_start_off = skb_transport_offset(skb); + unsigned int csum_index_off = csum_start_off + skb->csum_offset; + + cur_p->app0 |= 1; /* TX Checksum Enabled */ + cur_p->app1 = (csum_start_off << 16) | csum_index_off; + cur_p->app2 = 0; /* initial checksum seed */ } + cur_p->app0 |= STS_CTRL_APP0_SOP; cur_p->len = skb_headlen(skb); cur_p->phys = dma_map_single(ndev->dev.parent, skb->data, skb->len, @@ -699,6 +711,15 @@ static void ll_temac_recv(struct net_device *ndev) skb->protocol = eth_type_trans(skb, ndev); skb->ip_summed = CHECKSUM_NONE; + /* if we're doing rx csum offload, set it up */ + if (((lp->temac_features & TEMAC_FEATURE_RX_CSUM) != 0) && + (skb->protocol == __constant_htons(ETH_P_IP)) && + (skb->len > 64)) { + + skb->csum = cur_p->app3 & 0xFFFF; + skb->ip_summed = CHECKSUM_COMPLETE; + } + netif_rx(skb); ndev->stats.rx_packets++; @@ -883,6 +904,7 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match) struct temac_local *lp; struct net_device *ndev; const void *addr; + __be32 *p; int size, rc = 0; /* Init network device structure */ @@ -926,6 +948,18 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match) goto nodev; } + /* Setup checksum offload, but default to off if not specified */ + lp->temac_features = 0; + p = (__be32 *)of_get_property(op->dev.of_node, "xlnx,txcsum", NULL); + if (p && be32_to_cpu(*p)) { + lp->temac_features |= TEMAC_FEATURE_TX_CSUM; + /* Can checksum TCP/UDP over IPv4. */ + ndev->features |= NETIF_F_IP_CSUM; + } + p = (__be32 *)of_get_property(op->dev.of_node, "xlnx,rxcsum", NULL); + if (p && be32_to_cpu(*p)) + lp->temac_features |= TEMAC_FEATURE_RX_CSUM; + /* Find the DMA node, map the DMA registers, and decode the DMA IRQs */ np = of_parse_phandle(op->node, "llink-connected", 0); if (!np) { -- cgit v1.1 From 84e5b9f75b48fe4a1e4ee72698230701439d0805 Mon Sep 17 00:00:00 2001 From: Sarveshwar Bandi Date: Thu, 27 May 2010 16:28:15 -0700 Subject: be2net: Patch removes redundant while statement in loop. Signed-off-by: Sarveshwar Bandi Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index aa065c7..54b1427 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -1861,7 +1861,7 @@ static int be_setup(struct be_adapter *adapter) goto if_destroy; } vf++; - } while (vf < num_vfs); + } } else if (!be_physfn(adapter)) { status = be_cmd_mac_addr_query(adapter, mac, MAC_ADDRESS_TYPE_NETWORK, false, adapter->if_handle); -- cgit v1.1 From 89dc0be68f4aaa06dba1b5d6ea9ecfe8fa9b7bf0 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 27 May 2010 16:29:05 -0700 Subject: drivers/net/hamradio: Eliminate a NULL pointer dereference At the point of the print, dev is NULL. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r exists@ expression E,E1; identifier f; statement S1,S2,S3; @@ if ((E == NULL && ...) || ...) { ... when != if (...) S1 else S2 when != E = E1 * E->f ... when any return ...; } else S3 // Signed-off-by: Julia Lawall Signed-off-by: David S. Miller --- drivers/net/hamradio/yam.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c index 694132e..4e7d1d0 100644 --- a/drivers/net/hamradio/yam.c +++ b/drivers/net/hamradio/yam.c @@ -1151,8 +1151,7 @@ static int __init yam_init_driver(void) dev = alloc_netdev(sizeof(struct yam_port), name, yam_setup); if (!dev) { - printk(KERN_ERR "yam: cannot allocate net device %s\n", - dev->name); + pr_err("yam: cannot allocate net device\n"); err = -ENOMEM; goto error; } -- cgit v1.1 From 17d95640034c4e0f12e5f1c9d1097d8dba6484ea Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 27 May 2010 16:30:03 -0700 Subject: drivers/net: Eliminate a NULL pointer dereference At the point of the print, dev is NULL. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r exists@ expression E,E1; identifier f; statement S1,S2,S3; @@ if ((E == NULL && ...) || ...) { ... when != if (...) S1 else S2 when != E = E1 * E->f ... when any return ...; } else S3 // Signed-off-by: Julia Lawall Signed-off-by: David S. Miller --- drivers/net/3c507.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/3c507.c b/drivers/net/3c507.c index 82eaf65..ea9b7a0 100644 --- a/drivers/net/3c507.c +++ b/drivers/net/3c507.c @@ -551,8 +551,7 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id) void __iomem *shmem; if (dev == NULL) { - pr_err("%s: net_interrupt(): irq %d for unknown device.\n", - dev->name, irq); + pr_err("net_interrupt(): irq %d for unknown device.\n", irq); return IRQ_NONE; } -- cgit v1.1 From b58ffb41fc09d1ffaca97e5ae801233575be2a7f Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Thu, 27 May 2010 16:31:41 -0700 Subject: cnic: Fix context memory init. on 5709. We need to zero context memory on 5709 in the function cnic_init_context(). Without this, iscsid restart on 5709 will not work because of stale data. TX context blocks should not be initialized by cnic_init_context() because of the special remapping on 5709. Update version to 2.1.2. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/cnic.c | 10 +++------- drivers/net/cnic_if.h | 4 ++-- 2 files changed, 5 insertions(+), 9 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index be90d35..fe92566 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -3367,13 +3367,9 @@ static int cnic_cm_shutdown(struct cnic_dev *dev) static void cnic_init_context(struct cnic_dev *dev, u32 cid) { - struct cnic_local *cp = dev->cnic_priv; u32 cid_addr; int i; - if (CHIP_NUM(cp) == CHIP_NUM_5709) - return; - cid_addr = GET_CID_ADDR(cid); for (i = 0; i < CTX_SIZE; i += 4) @@ -3530,14 +3526,11 @@ static void cnic_init_bnx2_tx_ring(struct cnic_dev *dev) sb_id = cp->status_blk_num; tx_cid = 20; - cnic_init_context(dev, tx_cid); - cnic_init_context(dev, tx_cid + 1); cp->tx_cons_ptr = &s_blk->status_tx_quick_consumer_index2; if (ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX) { struct status_block_msix *sblk = cp->status_blk.bnx2; tx_cid = TX_TSS_CID + sb_id - 1; - cnic_init_context(dev, tx_cid); CNIC_WR(dev, BNX2_TSCH_TSS_CFG, (sb_id << 24) | (TX_TSS_CID << 7)); cp->tx_cons_ptr = &sblk->status_tx_quick_consumer_index; @@ -3556,6 +3549,9 @@ static void cnic_init_bnx2_tx_ring(struct cnic_dev *dev) offset2 = BNX2_L2CTX_TBDR_BHADDR_HI_XI; offset3 = BNX2_L2CTX_TBDR_BHADDR_LO_XI; } else { + cnic_init_context(dev, tx_cid); + cnic_init_context(dev, tx_cid + 1); + offset0 = BNX2_L2CTX_TYPE; offset1 = BNX2_L2CTX_CMD_TYPE; offset2 = BNX2_L2CTX_TBDR_BHADDR_HI; diff --git a/drivers/net/cnic_if.h b/drivers/net/cnic_if.h index 110c620..0c55177 100644 --- a/drivers/net/cnic_if.h +++ b/drivers/net/cnic_if.h @@ -12,8 +12,8 @@ #ifndef CNIC_IF_H #define CNIC_IF_H -#define CNIC_MODULE_VERSION "2.1.1" -#define CNIC_MODULE_RELDATE "Feb 22, 2010" +#define CNIC_MODULE_VERSION "2.1.2" +#define CNIC_MODULE_RELDATE "May 26, 2010" #define CNIC_ULP_RDMA 0 #define CNIC_ULP_ISCSI 1 -- cgit v1.1 From 418bd0d4dfbff25ffe4365ddd3e7cba8c70ccba8 Mon Sep 17 00:00:00 2001 From: Bryan Wu Date: Fri, 28 May 2010 03:40:39 -0700 Subject: netdev/fec: fix ifconfig eth0 down hang issue BugLink: http://bugs.launchpad.net/bugs/559065 In fec open/close function, we need to use phy_connect and phy_disconnect operation before we start/stop phy. Otherwise it will cause system hang. Only call fec_enet_mii_probe() in open function, because the first open action will cause NULL pointer error. Signed-off-by: Bryan Wu Signed-off-by: David S. Miller --- drivers/net/fec.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 326465f..ddf7a86 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -681,6 +681,8 @@ static int fec_enet_mii_probe(struct net_device *dev) struct phy_device *phy_dev = NULL; int phy_addr; + fep->phy_dev = NULL; + /* find the first phy */ for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { if (fep->mii_bus->phy_map[phy_addr]) { @@ -711,6 +713,11 @@ static int fec_enet_mii_probe(struct net_device *dev) fep->link = 0; fep->full_duplex = 0; + printk(KERN_INFO "%s: Freescale FEC PHY driver [%s] " + "(mii_bus:phy_addr=%s, irq=%d)\n", dev->name, + fep->phy_dev->drv->name, dev_name(&fep->phy_dev->dev), + fep->phy_dev->irq); + return 0; } @@ -756,13 +763,8 @@ static int fec_enet_mii_init(struct platform_device *pdev) if (mdiobus_register(fep->mii_bus)) goto err_out_free_mdio_irq; - if (fec_enet_mii_probe(dev) != 0) - goto err_out_unregister_bus; - return 0; -err_out_unregister_bus: - mdiobus_unregister(fep->mii_bus); err_out_free_mdio_irq: kfree(fep->mii_bus->irq); err_out_free_mdiobus: @@ -915,7 +917,12 @@ fec_enet_open(struct net_device *dev) if (ret) return ret; - /* schedule a link state check */ + /* Probe and connect to PHY when open the interface */ + ret = fec_enet_mii_probe(dev); + if (ret) { + fec_enet_free_buffers(dev); + return ret; + } phy_start(fep->phy_dev); netif_start_queue(dev); fep->opened = 1; @@ -929,10 +936,12 @@ fec_enet_close(struct net_device *dev) /* Don't know what to do yet. */ fep->opened = 0; - phy_stop(fep->phy_dev); netif_stop_queue(dev); fec_stop(dev); + if (fep->phy_dev) + phy_disconnect(fep->phy_dev); + fec_enet_free_buffers(dev); return 0; @@ -1316,11 +1325,6 @@ fec_probe(struct platform_device *pdev) if (ret) goto failed_register; - printk(KERN_INFO "%s: Freescale FEC PHY driver [%s] " - "(mii_bus:phy_addr=%s, irq=%d)\n", ndev->name, - fep->phy_dev->drv->name, dev_name(&fep->phy_dev->dev), - fep->phy_dev->irq); - return 0; failed_register: -- cgit v1.1