diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/3c507.c | 3 | ||||
-rw-r--r-- | drivers/net/benet/be.h | 2 | ||||
-rw-r--r-- | drivers/net/benet/be_cmds.c | 21 | ||||
-rw-r--r-- | drivers/net/benet/be_main.c | 13 | ||||
-rw-r--r-- | drivers/net/bfin_mac.c | 2 | ||||
-rw-r--r-- | drivers/net/cnic.c | 10 | ||||
-rw-r--r-- | drivers/net/cnic_if.h | 4 | ||||
-rw-r--r-- | drivers/net/enic/enic_main.c | 29 | ||||
-rw-r--r-- | drivers/net/ethoc.c | 34 | ||||
-rw-r--r-- | drivers/net/fec.c | 50 | ||||
-rw-r--r-- | drivers/net/fec.h | 2 | ||||
-rw-r--r-- | drivers/net/hamradio/yam.c | 3 | ||||
-rw-r--r-- | drivers/net/irda/bfin_sir.c | 8 | ||||
-rw-r--r-- | drivers/net/ll_temac.h | 5 | ||||
-rw-r--r-- | drivers/net/ll_temac_main.c | 84 | ||||
-rw-r--r-- | drivers/net/macvlan.c | 9 | ||||
-rw-r--r-- | drivers/net/pppoe.c | 1 | ||||
-rw-r--r-- | drivers/net/tun.c | 2 | ||||
-rw-r--r-- | drivers/net/usb/asix.c | 4 | ||||
-rw-r--r-- | drivers/net/usb/hso.c | 3 | ||||
-rw-r--r-- | drivers/net/wimax/i2400m/rx.c | 4 |
21 files changed, 216 insertions, 77 deletions
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; } diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 373c1a5..b46be49 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -283,6 +283,8 @@ struct be_adapter { u8 port_type; u8 transceiver; u8 generation; /* BladeEngine ASIC generation */ + u32 flash_status; + struct completion flash_compl; bool sriov_enabled; u32 vf_if_handle[BE_MAX_VF]; diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index e79bf8b..9d11dbf 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -59,6 +59,13 @@ static int be_mcc_compl_process(struct be_adapter *adapter, compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) & CQE_STATUS_COMPL_MASK; + + if ((compl->tag0 == OPCODE_COMMON_WRITE_FLASHROM) && + (compl->tag1 == CMD_SUBSYSTEM_COMMON)) { + adapter->flash_status = compl_status; + complete(&adapter->flash_compl); + } + if (compl_status == MCC_STATUS_SUCCESS) { if (compl->tag0 == OPCODE_ETH_GET_STATISTICS) { struct be_cmd_resp_get_stats *resp = @@ -287,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; @@ -1417,6 +1424,7 @@ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd, int status; spin_lock_bh(&adapter->mcc_lock); + adapter->flash_status = 0; wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -1428,6 +1436,7 @@ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd, be_wrb_hdr_prepare(wrb, cmd->size, false, 1, OPCODE_COMMON_WRITE_FLASHROM); + wrb->tag1 = CMD_SUBSYSTEM_COMMON; be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, OPCODE_COMMON_WRITE_FLASHROM, cmd->size); @@ -1439,10 +1448,16 @@ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd, req->params.op_code = cpu_to_le32(flash_opcode); req->params.data_buf_size = cpu_to_le32(buf_size); - status = be_mcc_notify_wait(adapter); + be_mcc_notify(adapter); + spin_unlock_bh(&adapter->mcc_lock); + + if (!wait_for_completion_timeout(&adapter->flash_compl, + msecs_to_jiffies(12000))) + status = -1; + else + status = adapter->flash_status; err: - spin_unlock_bh(&adapter->mcc_lock); return status; } diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 058d7f9..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); @@ -2319,6 +2319,7 @@ static int be_ctrl_init(struct be_adapter *adapter) spin_lock_init(&adapter->mcc_lock); spin_lock_init(&adapter->mcc_cq_lock); + init_completion(&adapter->flash_compl); pci_save_state(adapter->pdev); return 0; @@ -2487,10 +2488,6 @@ static int __devinit be_probe(struct pci_dev *pdev, status = be_cmd_POST(adapter); if (status) goto ctrl_clean; - - status = be_cmd_reset_function(adapter); - if (status) - goto ctrl_clean; } /* tell fw we're ready to fire cmds */ @@ -2498,6 +2495,12 @@ static int __devinit be_probe(struct pci_dev *pdev, if (status) goto ctrl_clean; + if (be_physfn(adapter)) { + status = be_cmd_reset_function(adapter); + if (status) + goto ctrl_clean; + } + status = be_stats_init(adapter); if (status) goto ctrl_clean; diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c index 39a54ba..368f333 100644 --- a/drivers/net/bfin_mac.c +++ b/drivers/net/bfin_mac.c @@ -1626,6 +1626,7 @@ static int __devinit bfin_mii_bus_probe(struct platform_device *pdev) return 0; out_err_mdiobus_register: + kfree(miibus->irq); mdiobus_free(miibus); out_err_alloc: peripheral_free_list(pin_req); @@ -1638,6 +1639,7 @@ static int __devexit bfin_mii_bus_remove(struct platform_device *pdev) struct mii_bus *miibus = platform_get_drvdata(pdev); platform_set_drvdata(pdev, NULL); mdiobus_unregister(miibus); + kfree(miibus->irq); mdiobus_free(miibus); peripheral_free_list(pin_req); return 0; 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 diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index e125113..6586b5c 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -1034,9 +1034,10 @@ static int enic_set_port_profile(struct enic *enic, u8 request, u8 *mac, { struct vic_provinfo *vp; u8 oui[3] = VIC_PROVINFO_CISCO_OUI; - unsigned short *uuid; + u8 *uuid; char uuid_str[38]; - static char *uuid_fmt = "%04X%04X-%04X-%04X-%04X-%04X%04X%04X"; + static char *uuid_fmt = "%02X%02X%02X%02X-%02X%02X-%02X%02X-" + "%02X%02X-%02X%02X%02X%02X%0X%02X"; int err; if (!name) @@ -1058,20 +1059,24 @@ static int enic_set_port_profile(struct enic *enic, u8 request, u8 *mac, ETH_ALEN, mac); if (instance_uuid) { - uuid = (unsigned short *)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[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 (host_uuid) { - uuid = (unsigned short *)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[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); @@ -1127,6 +1132,14 @@ static int enic_set_vf_port(struct net_device *netdev, int vf, switch (request) { case PORT_REQUEST_ASSOCIATE: + /* If the interface mac addr hasn't been assigned, + * assign a random mac addr before setting port- + * profile. + */ + + 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]); diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c index 14cbde5..6ed2df1 100644 --- a/drivers/net/ethoc.c +++ b/drivers/net/ethoc.c @@ -174,6 +174,7 @@ MODULE_PARM_DESC(buffer_size, "DMA buffer allocation size"); * @iobase: pointer to I/O memory region * @membase: pointer to buffer memory region * @dma_alloc: dma allocated buffer size + * @io_region_size: I/O memory region size * @num_tx: number of send buffers * @cur_tx: last send buffer written * @dty_tx: last buffer actually sent @@ -193,6 +194,7 @@ struct ethoc { void __iomem *iobase; void __iomem *membase; int dma_alloc; + resource_size_t io_region_size; unsigned int num_tx; unsigned int cur_tx; @@ -943,6 +945,7 @@ static int ethoc_probe(struct platform_device *pdev) priv = netdev_priv(netdev); priv->netdev = netdev; priv->dma_alloc = 0; + priv->io_region_size = mmio->end - mmio->start + 1; priv->iobase = devm_ioremap_nocache(&pdev->dev, netdev->base_addr, resource_size(mmio)); @@ -1047,20 +1050,34 @@ static int ethoc_probe(struct platform_device *pdev) ret = register_netdev(netdev); if (ret < 0) { dev_err(&netdev->dev, "failed to register interface\n"); - goto error; + goto error2; } goto out; +error2: + netif_napi_del(&priv->napi); error: mdiobus_unregister(priv->mdio); free_mdio: kfree(priv->mdio->irq); mdiobus_free(priv->mdio); free: - if (priv->dma_alloc) - dma_free_coherent(NULL, priv->dma_alloc, priv->membase, - netdev->mem_start); + if (priv) { + if (priv->dma_alloc) + dma_free_coherent(NULL, priv->dma_alloc, priv->membase, + netdev->mem_start); + else if (priv->membase) + devm_iounmap(&pdev->dev, priv->membase); + if (priv->iobase) + devm_iounmap(&pdev->dev, priv->iobase); + } + if (mem) + devm_release_mem_region(&pdev->dev, mem->start, + mem->end - mem->start + 1); + if (mmio) + devm_release_mem_region(&pdev->dev, mmio->start, + mmio->end - mmio->start + 1); free_netdev(netdev); out: return ret; @@ -1078,6 +1095,7 @@ static int ethoc_remove(struct platform_device *pdev) platform_set_drvdata(pdev, NULL); if (netdev) { + netif_napi_del(&priv->napi); phy_disconnect(priv->phy); priv->phy = NULL; @@ -1089,6 +1107,14 @@ static int ethoc_remove(struct platform_device *pdev) if (priv->dma_alloc) dma_free_coherent(NULL, priv->dma_alloc, priv->membase, netdev->mem_start); + else { + devm_iounmap(&pdev->dev, priv->membase); + devm_release_mem_region(&pdev->dev, netdev->mem_start, + netdev->mem_end - netdev->mem_start + 1); + } + devm_iounmap(&pdev->dev, priv->iobase); + devm_release_mem_region(&pdev->dev, netdev->base_addr, + priv->io_region_size); unregister_netdev(netdev); free_netdev(netdev); } diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 42d9ac9..ddf7a86 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -41,6 +41,7 @@ #include <linux/clk.h> #include <linux/platform_device.h> #include <linux/phy.h> +#include <linux/fec.h> #include <asm/cacheflush.h> @@ -182,6 +183,7 @@ struct fec_enet_private { struct phy_device *phy_dev; int mii_timeout; uint phy_speed; + phy_interface_t phy_interface; int index; int link; int full_duplex; @@ -679,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]) { @@ -709,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; } @@ -754,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: @@ -913,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; @@ -927,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; @@ -1191,6 +1202,21 @@ fec_restart(struct net_device *dev, int duplex) /* Set MII speed */ writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED); +#ifdef FEC_MIIGSK_ENR + if (fep->phy_interface == PHY_INTERFACE_MODE_RMII) { + /* disable the gasket and wait */ + writel(0, fep->hwp + FEC_MIIGSK_ENR); + while (readl(fep->hwp + FEC_MIIGSK_ENR) & 4) + udelay(1); + + /* configure the gasket: RMII, 50 MHz, no loopback, no echo */ + writel(1, fep->hwp + FEC_MIIGSK_CFGR); + + /* re-enable the gasket */ + writel(2, fep->hwp + FEC_MIIGSK_ENR); + } +#endif + /* And last, enable the transmit and receive processing */ writel(2, fep->hwp + FEC_ECNTRL); writel(0, fep->hwp + FEC_R_DES_ACTIVE); @@ -1226,6 +1252,7 @@ static int __devinit fec_probe(struct platform_device *pdev) { struct fec_enet_private *fep; + struct fec_platform_data *pdata; struct net_device *ndev; int i, irq, ret = 0; struct resource *r; @@ -1259,6 +1286,10 @@ fec_probe(struct platform_device *pdev) platform_set_drvdata(pdev, ndev); + pdata = pdev->dev.platform_data; + if (pdata) + fep->phy_interface = pdata->phy; + /* This device has up to three irqs on some platforms */ for (i = 0; i < 3; i++) { irq = platform_get_irq(pdev, i); @@ -1294,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: diff --git a/drivers/net/fec.h b/drivers/net/fec.h index cc47f3f..2c48b25 100644 --- a/drivers/net/fec.h +++ b/drivers/net/fec.h @@ -43,6 +43,8 @@ #define FEC_R_DES_START 0x180 /* Receive descriptor ring */ #define FEC_X_DES_START 0x184 /* Transmit descriptor ring */ #define FEC_R_BUFF_SIZE 0x188 /* Maximum receive buff size */ +#define FEC_MIIGSK_CFGR 0x300 /* MIIGSK Configuration reg */ +#define FEC_MIIGSK_ENR 0x308 /* MIIGSK Enable reg */ #else 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; } diff --git a/drivers/net/irda/bfin_sir.c b/drivers/net/irda/bfin_sir.c index 911c082..f940dfa 100644 --- a/drivers/net/irda/bfin_sir.c +++ b/drivers/net/irda/bfin_sir.c @@ -107,8 +107,12 @@ static int bfin_sir_set_speed(struct bfin_sir_port *port, int speed) case 57600: case 115200: - quot = (port->clk + (8 * speed)) / (16 * speed)\ - - ANOMALY_05000230; + /* + * IRDA is not affected by anomaly 05000230, so there is no + * need to tweak the divisor like he UART driver (which will + * slightly speed up the baud rate on us). + */ + quot = (port->clk + (8 * speed)) / (16 * speed); do { udelay(utime); 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 b59b24d..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) { @@ -950,7 +984,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; diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 4e238af..87e8d4c 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -634,11 +634,18 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev, err = register_netdevice(dev); if (err < 0) - return err; + goto destroy_port; list_add_tail(&vlan->list, &port->vlans); netif_stacked_transfer_operstate(lowerdev, dev); + return 0; + +destroy_port: + if (list_empty(&port->vlans)) + macvlan_port_destroy(lowerdev); + + return err; } EXPORT_SYMBOL_GPL(macvlan_common_newlink); diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index b1b93ff..805b64d 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c @@ -289,6 +289,7 @@ static void pppoe_flush_dev(struct net_device *dev) struct pppoe_net *pn; int i; + pn = pppoe_pernet(dev_net(dev)); write_lock_bh(&pn->hash_lock); for (i = 0; i < PPPOE_HASH_SIZE; i++) { struct pppox_sock *po = pn->hash_table[i]; diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 97b2553..8793c2b 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -526,6 +526,8 @@ static inline struct sk_buff *tun_alloc_skb(struct tun_struct *tun, struct sk_buff *skb; int err; + sock_update_classid(sk); + /* Under a page? Don't bother with paged skb. */ if (prepad + len < PAGE_SIZE || !linear) linear = len; diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 31b7331..1f802e9 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -322,7 +322,7 @@ static int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb) size = (u16) (header & 0x0000ffff); if ((skb->len) - ((size + 1) & 0xfffe) == 0) { - u8 alignment = (u32)skb->data & 0x3; + u8 alignment = (unsigned long)skb->data & 0x3; if (alignment != 0x2) { /* * not 16bit aligned so use the room provided by @@ -351,7 +351,7 @@ static int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb) } ax_skb = skb_clone(skb, GFP_ATOMIC); if (ax_skb) { - u8 alignment = (u32)packet & 0x3; + u8 alignment = (unsigned long)packet & 0x3; ax_skb->len = size; if (alignment != 0x2) { diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 9964df1..0a3c41f 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -475,6 +475,9 @@ static const struct usb_device_id hso_ids[] = { {USB_DEVICE(0x0af0, 0x8302)}, {USB_DEVICE(0x0af0, 0x8304)}, {USB_DEVICE(0x0af0, 0x8400)}, + {USB_DEVICE(0x0af0, 0x8600)}, + {USB_DEVICE(0x0af0, 0x8800)}, + {USB_DEVICE(0x0af0, 0x8900)}, {USB_DEVICE(0x0af0, 0xd035)}, {USB_DEVICE(0x0af0, 0xd055)}, {USB_DEVICE(0x0af0, 0xd155)}, diff --git a/drivers/net/wimax/i2400m/rx.c b/drivers/net/wimax/i2400m/rx.c index 6537593..8cc9e31 100644 --- a/drivers/net/wimax/i2400m/rx.c +++ b/drivers/net/wimax/i2400m/rx.c @@ -1027,12 +1027,12 @@ void i2400m_rx_edata(struct i2400m *i2400m, struct sk_buff *skb_rx, ro_sn = (reorder >> I2400M_RO_SN_SHIFT) & I2400M_RO_SN; spin_lock_irqsave(&i2400m->rx_lock, flags); - roq = &i2400m->rx_roq[ro_cin]; - if (roq == NULL) { + if (i2400m->rx_roq == NULL) { kfree_skb(skb); /* rx_roq is already destroyed */ spin_unlock_irqrestore(&i2400m->rx_lock, flags); goto error; } + roq = &i2400m->rx_roq[ro_cin]; kref_get(&i2400m->rx_roq_refcount); spin_unlock_irqrestore(&i2400m->rx_lock, flags); |