From b4bf68575c6ca7903f4acba098c557b207453814 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Sun, 14 Nov 2010 17:25:11 +0100 Subject: [PATCH] --- yaml --- r: 224165 b: refs/heads/master c: 5753fdfe8bd8e9a2ff9e5af19b0ffc78bfcd502a h: refs/heads/master i: 224163: 63f45d0da75e3346605691d8bc782949ff1bd81c v: v3 --- [refs] | 2 +- trunk/drivers/net/cxgb4vf/adapter.h | 2 +- trunk/drivers/net/cxgb4vf/cxgb4vf_main.c | 32 ++- trunk/drivers/net/cxgb4vf/sge.c | 9 +- trunk/drivers/net/cxgb4vf/t4vf_hw.c | 5 +- trunk/drivers/net/sh_eth.c | 244 +++++++++++------------ trunk/include/linux/netdevice.h | 10 +- trunk/include/net/flow.h | 2 - trunk/include/net/xfrm.h | 6 - trunk/net/8021q/vlan.c | 6 - trunk/net/8021q/vlan.h | 4 + trunk/net/8021q/vlan_dev.c | 108 +++++++++- trunk/net/8021q/vlanproc.c | 5 + trunk/net/core/dev.c | 73 +++---- trunk/net/core/net-sysfs.c | 7 +- trunk/net/dccp/ackvec.c | 88 ++++++++ trunk/net/dccp/ackvec.h | 1 + trunk/net/dccp/input.c | 4 +- trunk/net/dccp/options.c | 6 +- trunk/net/ipv4/igmp.c | 20 +- trunk/net/ipv4/ip_gre.c | 12 +- trunk/net/ipv4/xfrm4_policy.c | 15 -- 22 files changed, 395 insertions(+), 266 deletions(-) diff --git a/[refs] b/[refs] index 81bbbcda049e..42dde7b98b65 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: fe8222406c8277a21172479d3a8283d31c209028 +refs/heads/master: 5753fdfe8bd8e9a2ff9e5af19b0ffc78bfcd502a diff --git a/trunk/drivers/net/cxgb4vf/adapter.h b/trunk/drivers/net/cxgb4vf/adapter.h index 4766b4116b41..8ea01962e045 100644 --- a/trunk/drivers/net/cxgb4vf/adapter.h +++ b/trunk/drivers/net/cxgb4vf/adapter.h @@ -60,7 +60,7 @@ enum { * MSI-X interrupt index usage. */ MSIX_FW = 0, /* MSI-X index for firmware Q */ - MSIX_IQFLINT = 1, /* MSI-X index base for Ingress Qs */ + MSIX_NIQFLINT = 1, /* MSI-X index base for Ingress Qs */ MSIX_EXTRAS = 1, MSIX_ENTRIES = MAX_ETH_QSETS + MSIX_EXTRAS, diff --git a/trunk/drivers/net/cxgb4vf/cxgb4vf_main.c b/trunk/drivers/net/cxgb4vf/cxgb4vf_main.c index 9246d2fa6cf9..c3449bbc585a 100644 --- a/trunk/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/trunk/drivers/net/cxgb4vf/cxgb4vf_main.c @@ -280,7 +280,9 @@ static void name_msix_vecs(struct adapter *adapter) const struct port_info *pi = netdev_priv(dev); int qs, msi; - for (qs = 0, msi = MSIX_IQFLINT; qs < pi->nqsets; qs++, msi++) { + for (qs = 0, msi = MSIX_NIQFLINT; + qs < pi->nqsets; + qs++, msi++) { snprintf(adapter->msix_info[msi].desc, namelen, "%s-%d", dev->name, qs); adapter->msix_info[msi].desc[namelen] = 0; @@ -307,7 +309,7 @@ static int request_msix_queue_irqs(struct adapter *adapter) /* * Ethernet queues. */ - msi = MSIX_IQFLINT; + msi = MSIX_NIQFLINT; for_each_ethrxq(s, rxq) { err = request_irq(adapter->msix_info[msi].vec, t4vf_sge_intr_msix, 0, @@ -335,7 +337,7 @@ static void free_msix_queue_irqs(struct adapter *adapter) int rxq, msi; free_irq(adapter->msix_info[MSIX_FW].vec, &s->fw_evtq); - msi = MSIX_IQFLINT; + msi = MSIX_NIQFLINT; for_each_ethrxq(s, rxq) free_irq(adapter->msix_info[msi++].vec, &s->ethrxq[rxq].rspq); @@ -525,7 +527,7 @@ static int setup_sge_queues(struct adapter *adapter) * brought up at which point lots of things get nailed down * permanently ... */ - msix = MSIX_IQFLINT; + msix = MSIX_NIQFLINT; for_each_port(adapter, pidx) { struct net_device *dev = adapter->port[pidx]; struct port_info *pi = netdev_priv(dev); @@ -1346,8 +1348,6 @@ struct queue_port_stats { u64 rx_csum; u64 vlan_ex; u64 vlan_ins; - u64 lro_pkts; - u64 lro_merged; }; /* @@ -1385,8 +1385,6 @@ static const char stats_strings[][ETH_GSTRING_LEN] = { "RxCsumGood ", "VLANextractions ", "VLANinsertions ", - "GROPackets ", - "GROMerged ", }; /* @@ -1436,8 +1434,6 @@ static void collect_sge_port_stats(const struct adapter *adapter, stats->rx_csum += rxq->stats.rx_cso; stats->vlan_ex += rxq->stats.vlan_ex; stats->vlan_ins += txq->vlan_ins; - stats->lro_pkts += rxq->stats.lro_pkts; - stats->lro_merged += rxq->stats.lro_merged; } } @@ -1533,20 +1529,15 @@ static void cxgb4vf_get_wol(struct net_device *dev, memset(&wol->sopass, 0, sizeof(wol->sopass)); } -/* - * TCP Segmentation Offload flags which we support. - */ -#define TSO_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN) - /* * Set TCP Segmentation Offloading feature capabilities. */ static int cxgb4vf_set_tso(struct net_device *dev, u32 tso) { if (tso) - dev->features |= TSO_FLAGS; + dev->features |= NETIF_F_TSO | NETIF_F_TSO6; else - dev->features &= ~TSO_FLAGS; + dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6); return 0; } @@ -2037,7 +2028,7 @@ static int __devinit setup_debugfs(struct adapter *adapter) * Tear down the /sys/kernel/debug/cxgb4vf sub-nodes created above. We leave * it to our caller to tear down the directory (debugfs_root). */ -static void cleanup_debugfs(struct adapter *adapter) +static void __devexit cleanup_debugfs(struct adapter *adapter) { BUG_ON(adapter->debugfs_root == NULL); @@ -2055,7 +2046,7 @@ static void cleanup_debugfs(struct adapter *adapter) * adapter parameters we're going to be using and initialize basic adapter * hardware support. */ -static int __devinit adap_init0(struct adapter *adapter) +static int adap_init0(struct adapter *adapter) { struct vf_resources *vfres = &adapter->params.vfres; struct sge_params *sge_params = &adapter->params.sge; @@ -2479,6 +2470,7 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev, version_printed = 1; } + /* * Initialize generic PCI device state. */ @@ -2615,7 +2607,7 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev, netif_carrier_off(netdev); netdev->irq = pdev->irq; - netdev->features = (NETIF_F_SG | TSO_FLAGS | + netdev->features = (NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | NETIF_F_GRO); diff --git a/trunk/drivers/net/cxgb4vf/sge.c b/trunk/drivers/net/cxgb4vf/sge.c index e0b3d1bc2fdf..ecf0770bf0ff 100644 --- a/trunk/drivers/net/cxgb4vf/sge.c +++ b/trunk/drivers/net/cxgb4vf/sge.c @@ -1568,9 +1568,6 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp, } else skb_checksum_none_assert(skb); - /* - * Deliver the packet to the stack. - */ if (unlikely(pkt->vlan_ex)) { struct vlan_group *grp = pi->vlan_grp; @@ -2146,7 +2143,7 @@ int t4vf_sge_alloc_rxq(struct adapter *adapter, struct sge_rspq *rspq, /* * Calculate the size of the hardware free list ring plus - * Status Page (which the SGE will place after the end of the + * status page (which the SGE will place at the end of the * free list ring) in Egress Queue Units. */ flsz = (fl->size / FL_PER_EQ_UNIT + @@ -2243,8 +2240,8 @@ int t4vf_sge_alloc_eth_txq(struct adapter *adapter, struct sge_eth_txq *txq, struct port_info *pi = netdev_priv(dev); /* - * Calculate the size of the hardware TX Queue (including the Status - * Page on the end of the TX Queue) in units of TX Descriptors. + * Calculate the size of the hardware TX Queue (including the + * status age on the end) in units of TX Descriptors. */ nentries = txq->q.size + STAT_LEN / sizeof(struct tx_desc); diff --git a/trunk/drivers/net/cxgb4vf/t4vf_hw.c b/trunk/drivers/net/cxgb4vf/t4vf_hw.c index f7d7f976064b..e306c20dfaee 100644 --- a/trunk/drivers/net/cxgb4vf/t4vf_hw.c +++ b/trunk/drivers/net/cxgb4vf/t4vf_hw.c @@ -1276,7 +1276,7 @@ int t4vf_eth_eq_free(struct adapter *adapter, unsigned int eqid) */ int t4vf_handle_fw_rpl(struct adapter *adapter, const __be64 *rpl) { - const struct fw_cmd_hdr *cmd_hdr = (const struct fw_cmd_hdr *)rpl; + struct fw_cmd_hdr *cmd_hdr = (struct fw_cmd_hdr *)rpl; u8 opcode = FW_CMD_OP_GET(be32_to_cpu(cmd_hdr->hi)); switch (opcode) { @@ -1284,8 +1284,7 @@ int t4vf_handle_fw_rpl(struct adapter *adapter, const __be64 *rpl) /* * Link/module state change message. */ - const struct fw_port_cmd *port_cmd = - (const struct fw_port_cmd *)rpl; + const struct fw_port_cmd *port_cmd = (void *)rpl; u32 word; int action, port_id, link_ok, speed, fc, pidx; diff --git a/trunk/drivers/net/sh_eth.c b/trunk/drivers/net/sh_eth.c index b12660d72338..50259dfec583 100644 --- a/trunk/drivers/net/sh_eth.c +++ b/trunk/drivers/net/sh_eth.c @@ -45,9 +45,9 @@ static void sh_eth_set_duplex(struct net_device *ndev) u32 ioaddr = ndev->base_addr; if (mdp->duplex) /* Full */ - writel(readl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR); + ctrl_outl(ctrl_inl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR); else /* Half */ - writel(readl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR); + ctrl_outl(ctrl_inl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR); } static void sh_eth_set_rate(struct net_device *ndev) @@ -57,10 +57,10 @@ static void sh_eth_set_rate(struct net_device *ndev) switch (mdp->speed) { case 10: /* 10BASE */ - writel(readl(ioaddr + ECMR) & ~ECMR_RTM, ioaddr + ECMR); + ctrl_outl(ctrl_inl(ioaddr + ECMR) & ~ECMR_RTM, ioaddr + ECMR); break; case 100:/* 100BASE */ - writel(readl(ioaddr + ECMR) | ECMR_RTM, ioaddr + ECMR); + ctrl_outl(ctrl_inl(ioaddr + ECMR) | ECMR_RTM, ioaddr + ECMR); break; default: break; @@ -96,9 +96,9 @@ static void sh_eth_set_duplex(struct net_device *ndev) u32 ioaddr = ndev->base_addr; if (mdp->duplex) /* Full */ - writel(readl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR); + ctrl_outl(ctrl_inl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR); else /* Half */ - writel(readl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR); + ctrl_outl(ctrl_inl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR); } static void sh_eth_set_rate(struct net_device *ndev) @@ -108,10 +108,10 @@ static void sh_eth_set_rate(struct net_device *ndev) switch (mdp->speed) { case 10: /* 10BASE */ - writel(0, ioaddr + RTRATE); + ctrl_outl(0, ioaddr + RTRATE); break; case 100:/* 100BASE */ - writel(1, ioaddr + RTRATE); + ctrl_outl(1, ioaddr + RTRATE); break; default: break; @@ -143,7 +143,7 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = { static void sh_eth_chip_reset(struct net_device *ndev) { /* reset device */ - writel(ARSTR_ARSTR, ARSTR); + ctrl_outl(ARSTR_ARSTR, ARSTR); mdelay(1); } @@ -152,10 +152,10 @@ static void sh_eth_reset(struct net_device *ndev) u32 ioaddr = ndev->base_addr; int cnt = 100; - writel(EDSR_ENALL, ioaddr + EDSR); - writel(readl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR); + ctrl_outl(EDSR_ENALL, ioaddr + EDSR); + ctrl_outl(ctrl_inl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR); while (cnt > 0) { - if (!(readl(ioaddr + EDMR) & 0x3)) + if (!(ctrl_inl(ioaddr + EDMR) & 0x3)) break; mdelay(1); cnt--; @@ -164,14 +164,14 @@ static void sh_eth_reset(struct net_device *ndev) printk(KERN_ERR "Device reset fail\n"); /* Table Init */ - writel(0x0, ioaddr + TDLAR); - writel(0x0, ioaddr + TDFAR); - writel(0x0, ioaddr + TDFXR); - writel(0x0, ioaddr + TDFFR); - writel(0x0, ioaddr + RDLAR); - writel(0x0, ioaddr + RDFAR); - writel(0x0, ioaddr + RDFXR); - writel(0x0, ioaddr + RDFFR); + ctrl_outl(0x0, ioaddr + TDLAR); + ctrl_outl(0x0, ioaddr + TDFAR); + ctrl_outl(0x0, ioaddr + TDFXR); + ctrl_outl(0x0, ioaddr + TDFFR); + ctrl_outl(0x0, ioaddr + RDLAR); + ctrl_outl(0x0, ioaddr + RDFAR); + ctrl_outl(0x0, ioaddr + RDFXR); + ctrl_outl(0x0, ioaddr + RDFFR); } static void sh_eth_set_duplex(struct net_device *ndev) @@ -180,9 +180,9 @@ static void sh_eth_set_duplex(struct net_device *ndev) u32 ioaddr = ndev->base_addr; if (mdp->duplex) /* Full */ - writel(readl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR); + ctrl_outl(ctrl_inl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR); else /* Half */ - writel(readl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR); + ctrl_outl(ctrl_inl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR); } static void sh_eth_set_rate(struct net_device *ndev) @@ -192,13 +192,13 @@ static void sh_eth_set_rate(struct net_device *ndev) switch (mdp->speed) { case 10: /* 10BASE */ - writel(GECMR_10, ioaddr + GECMR); + ctrl_outl(GECMR_10, ioaddr + GECMR); break; case 100:/* 100BASE */ - writel(GECMR_100, ioaddr + GECMR); + ctrl_outl(GECMR_100, ioaddr + GECMR); break; case 1000: /* 1000BASE */ - writel(GECMR_1000, ioaddr + GECMR); + ctrl_outl(GECMR_1000, ioaddr + GECMR); break; default: break; @@ -283,9 +283,9 @@ static void sh_eth_reset(struct net_device *ndev) { u32 ioaddr = ndev->base_addr; - writel(readl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR); + ctrl_outl(ctrl_inl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR); mdelay(3); - writel(readl(ioaddr + EDMR) & ~EDMR_SRST, ioaddr + EDMR); + ctrl_outl(ctrl_inl(ioaddr + EDMR) & ~EDMR_SRST, ioaddr + EDMR); } #endif @@ -336,10 +336,10 @@ static void update_mac_address(struct net_device *ndev) { u32 ioaddr = ndev->base_addr; - writel((ndev->dev_addr[0] << 24) | (ndev->dev_addr[1] << 16) | + ctrl_outl((ndev->dev_addr[0] << 24) | (ndev->dev_addr[1] << 16) | (ndev->dev_addr[2] << 8) | (ndev->dev_addr[3]), ioaddr + MAHR); - writel((ndev->dev_addr[4] << 8) | (ndev->dev_addr[5]), + ctrl_outl((ndev->dev_addr[4] << 8) | (ndev->dev_addr[5]), ioaddr + MALR); } @@ -358,12 +358,12 @@ static void read_mac_address(struct net_device *ndev, unsigned char *mac) if (mac[0] || mac[1] || mac[2] || mac[3] || mac[4] || mac[5]) { memcpy(ndev->dev_addr, mac, 6); } else { - ndev->dev_addr[0] = (readl(ioaddr + MAHR) >> 24); - ndev->dev_addr[1] = (readl(ioaddr + MAHR) >> 16) & 0xFF; - ndev->dev_addr[2] = (readl(ioaddr + MAHR) >> 8) & 0xFF; - ndev->dev_addr[3] = (readl(ioaddr + MAHR) & 0xFF); - ndev->dev_addr[4] = (readl(ioaddr + MALR) >> 8) & 0xFF; - ndev->dev_addr[5] = (readl(ioaddr + MALR) & 0xFF); + ndev->dev_addr[0] = (ctrl_inl(ioaddr + MAHR) >> 24); + ndev->dev_addr[1] = (ctrl_inl(ioaddr + MAHR) >> 16) & 0xFF; + ndev->dev_addr[2] = (ctrl_inl(ioaddr + MAHR) >> 8) & 0xFF; + ndev->dev_addr[3] = (ctrl_inl(ioaddr + MAHR) & 0xFF); + ndev->dev_addr[4] = (ctrl_inl(ioaddr + MALR) >> 8) & 0xFF; + ndev->dev_addr[5] = (ctrl_inl(ioaddr + MALR) & 0xFF); } } @@ -379,19 +379,19 @@ struct bb_info { /* PHY bit set */ static void bb_set(u32 addr, u32 msk) { - writel(readl(addr) | msk, addr); + ctrl_outl(ctrl_inl(addr) | msk, addr); } /* PHY bit clear */ static void bb_clr(u32 addr, u32 msk) { - writel((readl(addr) & ~msk), addr); + ctrl_outl((ctrl_inl(addr) & ~msk), addr); } /* PHY bit read */ static int bb_read(u32 addr, u32 msk) { - return (readl(addr) & msk) != 0; + return (ctrl_inl(addr) & msk) != 0; } /* Data I/O pin control */ @@ -506,9 +506,9 @@ static void sh_eth_ring_format(struct net_device *ndev) rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16); /* Rx descriptor address set */ if (i == 0) { - writel(mdp->rx_desc_dma, ioaddr + RDLAR); + ctrl_outl(mdp->rx_desc_dma, ioaddr + RDLAR); #if defined(CONFIG_CPU_SUBTYPE_SH7763) - writel(mdp->rx_desc_dma, ioaddr + RDFAR); + ctrl_outl(mdp->rx_desc_dma, ioaddr + RDFAR); #endif } } @@ -528,9 +528,9 @@ static void sh_eth_ring_format(struct net_device *ndev) txdesc->buffer_length = 0; if (i == 0) { /* Tx descriptor address set */ - writel(mdp->tx_desc_dma, ioaddr + TDLAR); + ctrl_outl(mdp->tx_desc_dma, ioaddr + TDLAR); #if defined(CONFIG_CPU_SUBTYPE_SH7763) - writel(mdp->tx_desc_dma, ioaddr + TDFAR); + ctrl_outl(mdp->tx_desc_dma, ioaddr + TDFAR); #endif } } @@ -623,71 +623,71 @@ static int sh_eth_dev_init(struct net_device *ndev) /* Descriptor format */ sh_eth_ring_format(ndev); if (mdp->cd->rpadir) - writel(mdp->cd->rpadir_value, ioaddr + RPADIR); + ctrl_outl(mdp->cd->rpadir_value, ioaddr + RPADIR); /* all sh_eth int mask */ - writel(0, ioaddr + EESIPR); + ctrl_outl(0, ioaddr + EESIPR); #if defined(__LITTLE_ENDIAN__) if (mdp->cd->hw_swap) - writel(EDMR_EL, ioaddr + EDMR); + ctrl_outl(EDMR_EL, ioaddr + EDMR); else #endif - writel(0, ioaddr + EDMR); + ctrl_outl(0, ioaddr + EDMR); /* FIFO size set */ - writel(mdp->cd->fdr_value, ioaddr + FDR); - writel(0, ioaddr + TFTR); + ctrl_outl(mdp->cd->fdr_value, ioaddr + FDR); + ctrl_outl(0, ioaddr + TFTR); /* Frame recv control */ - writel(mdp->cd->rmcr_value, ioaddr + RMCR); + ctrl_outl(mdp->cd->rmcr_value, ioaddr + RMCR); rx_int_var = mdp->rx_int_var = DESC_I_RINT8 | DESC_I_RINT5; tx_int_var = mdp->tx_int_var = DESC_I_TINT2; - writel(rx_int_var | tx_int_var, ioaddr + TRSCER); + ctrl_outl(rx_int_var | tx_int_var, ioaddr + TRSCER); if (mdp->cd->bculr) - writel(0x800, ioaddr + BCULR); /* Burst sycle set */ + ctrl_outl(0x800, ioaddr + BCULR); /* Burst sycle set */ - writel(mdp->cd->fcftr_value, ioaddr + FCFTR); + ctrl_outl(mdp->cd->fcftr_value, ioaddr + FCFTR); if (!mdp->cd->no_trimd) - writel(0, ioaddr + TRIMD); + ctrl_outl(0, ioaddr + TRIMD); /* Recv frame limit set register */ - writel(RFLR_VALUE, ioaddr + RFLR); + ctrl_outl(RFLR_VALUE, ioaddr + RFLR); - writel(readl(ioaddr + EESR), ioaddr + EESR); - writel(mdp->cd->eesipr_value, ioaddr + EESIPR); + ctrl_outl(ctrl_inl(ioaddr + EESR), ioaddr + EESR); + ctrl_outl(mdp->cd->eesipr_value, ioaddr + EESIPR); /* PAUSE Prohibition */ - val = (readl(ioaddr + ECMR) & ECMR_DM) | + val = (ctrl_inl(ioaddr + ECMR) & ECMR_DM) | ECMR_ZPF | (mdp->duplex ? ECMR_DM : 0) | ECMR_TE | ECMR_RE; - writel(val, ioaddr + ECMR); + ctrl_outl(val, ioaddr + ECMR); if (mdp->cd->set_rate) mdp->cd->set_rate(ndev); /* E-MAC Status Register clear */ - writel(mdp->cd->ecsr_value, ioaddr + ECSR); + ctrl_outl(mdp->cd->ecsr_value, ioaddr + ECSR); /* E-MAC Interrupt Enable register */ - writel(mdp->cd->ecsipr_value, ioaddr + ECSIPR); + ctrl_outl(mdp->cd->ecsipr_value, ioaddr + ECSIPR); /* Set MAC address */ update_mac_address(ndev); /* mask reset */ if (mdp->cd->apr) - writel(APR_AP, ioaddr + APR); + ctrl_outl(APR_AP, ioaddr + APR); if (mdp->cd->mpr) - writel(MPR_MP, ioaddr + MPR); + ctrl_outl(MPR_MP, ioaddr + MPR); if (mdp->cd->tpauser) - writel(TPAUSER_UNLIMITED, ioaddr + TPAUSER); + ctrl_outl(TPAUSER_UNLIMITED, ioaddr + TPAUSER); /* Setting the Rx mode will start the Rx process. */ - writel(EDRRR_R, ioaddr + EDRRR); + ctrl_outl(EDRRR_R, ioaddr + EDRRR); netif_start_queue(ndev); @@ -811,8 +811,8 @@ static int sh_eth_rx(struct net_device *ndev) /* Restart Rx engine if stopped. */ /* If we don't need to check status, don't. -KDU */ - if (!(readl(ndev->base_addr + EDRRR) & EDRRR_R)) - writel(EDRRR_R, ndev->base_addr + EDRRR); + if (!(ctrl_inl(ndev->base_addr + EDRRR) & EDRRR_R)) + ctrl_outl(EDRRR_R, ndev->base_addr + EDRRR); return 0; } @@ -827,8 +827,8 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) u32 mask; if (intr_status & EESR_ECI) { - felic_stat = readl(ioaddr + ECSR); - writel(felic_stat, ioaddr + ECSR); /* clear int */ + felic_stat = ctrl_inl(ioaddr + ECSR); + ctrl_outl(felic_stat, ioaddr + ECSR); /* clear int */ if (felic_stat & ECSR_ICD) mdp->stats.tx_carrier_errors++; if (felic_stat & ECSR_LCHNG) { @@ -839,25 +839,25 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) else link_stat = PHY_ST_LINK; } else { - link_stat = (readl(ioaddr + PSR)); + link_stat = (ctrl_inl(ioaddr + PSR)); if (mdp->ether_link_active_low) link_stat = ~link_stat; } if (!(link_stat & PHY_ST_LINK)) { /* Link Down : disable tx and rx */ - writel(readl(ioaddr + ECMR) & + ctrl_outl(ctrl_inl(ioaddr + ECMR) & ~(ECMR_RE | ECMR_TE), ioaddr + ECMR); } else { /* Link Up */ - writel(readl(ioaddr + EESIPR) & + ctrl_outl(ctrl_inl(ioaddr + EESIPR) & ~DMAC_M_ECI, ioaddr + EESIPR); /*clear int */ - writel(readl(ioaddr + ECSR), + ctrl_outl(ctrl_inl(ioaddr + ECSR), ioaddr + ECSR); - writel(readl(ioaddr + EESIPR) | + ctrl_outl(ctrl_inl(ioaddr + EESIPR) | DMAC_M_ECI, ioaddr + EESIPR); /* enable tx and rx */ - writel(readl(ioaddr + ECMR) | + ctrl_outl(ctrl_inl(ioaddr + ECMR) | (ECMR_RE | ECMR_TE), ioaddr + ECMR); } } @@ -888,8 +888,8 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) /* Receive Descriptor Empty int */ mdp->stats.rx_over_errors++; - if (readl(ioaddr + EDRRR) ^ EDRRR_R) - writel(EDRRR_R, ioaddr + EDRRR); + if (ctrl_inl(ioaddr + EDRRR) ^ EDRRR_R) + ctrl_outl(EDRRR_R, ioaddr + EDRRR); dev_err(&ndev->dev, "Receive Descriptor Empty\n"); } if (intr_status & EESR_RFE) { @@ -903,7 +903,7 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) mask &= ~EESR_ADE; if (intr_status & mask) { /* Tx error */ - u32 edtrr = readl(ndev->base_addr + EDTRR); + u32 edtrr = ctrl_inl(ndev->base_addr + EDTRR); /* dmesg */ dev_err(&ndev->dev, "TX error. status=%8.8x cur_tx=%8.8x ", intr_status, mdp->cur_tx); @@ -915,7 +915,7 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) /* SH7712 BUG */ if (edtrr ^ EDTRR_TRNS) { /* tx dma start */ - writel(EDTRR_TRNS, ndev->base_addr + EDTRR); + ctrl_outl(EDTRR_TRNS, ndev->base_addr + EDTRR); } /* wakeup */ netif_wake_queue(ndev); @@ -934,12 +934,12 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev) spin_lock(&mdp->lock); /* Get interrpt stat */ - intr_status = readl(ioaddr + EESR); + intr_status = ctrl_inl(ioaddr + EESR); /* Clear interrupt */ if (intr_status & (EESR_FRC | EESR_RMAF | EESR_RRF | EESR_RTLF | EESR_RTSF | EESR_PRE | EESR_CERF | cd->tx_check | cd->eesr_err_check)) { - writel(intr_status, ioaddr + EESR); + ctrl_outl(intr_status, ioaddr + EESR); ret = IRQ_HANDLED; } else goto other_irq; @@ -1000,7 +1000,7 @@ static void sh_eth_adjust_link(struct net_device *ndev) mdp->cd->set_rate(ndev); } if (mdp->link == PHY_DOWN) { - writel((readl(ioaddr + ECMR) & ~ECMR_TXF) + ctrl_outl((ctrl_inl(ioaddr + ECMR) & ~ECMR_TXF) | ECMR_DM, ioaddr + ECMR); new_state = 1; mdp->link = phydev->link; @@ -1125,7 +1125,7 @@ static void sh_eth_tx_timeout(struct net_device *ndev) /* worning message out. */ printk(KERN_WARNING "%s: transmit timed out, status %8.8x," - " resetting...\n", ndev->name, (int)readl(ioaddr + EESR)); + " resetting...\n", ndev->name, (int)ctrl_inl(ioaddr + EESR)); /* tx_errors count up */ mdp->stats.tx_errors++; @@ -1196,8 +1196,8 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev) mdp->cur_tx++; - if (!(readl(ndev->base_addr + EDTRR) & EDTRR_TRNS)) - writel(EDTRR_TRNS, ndev->base_addr + EDTRR); + if (!(ctrl_inl(ndev->base_addr + EDTRR) & EDTRR_TRNS)) + ctrl_outl(EDTRR_TRNS, ndev->base_addr + EDTRR); return NETDEV_TX_OK; } @@ -1212,11 +1212,11 @@ static int sh_eth_close(struct net_device *ndev) netif_stop_queue(ndev); /* Disable interrupts by clearing the interrupt mask. */ - writel(0x0000, ioaddr + EESIPR); + ctrl_outl(0x0000, ioaddr + EESIPR); /* Stop the chip's Tx and Rx processes. */ - writel(0, ioaddr + EDTRR); - writel(0, ioaddr + EDRRR); + ctrl_outl(0, ioaddr + EDTRR); + ctrl_outl(0, ioaddr + EDRRR); /* PHY Disconnect */ if (mdp->phydev) { @@ -1251,20 +1251,20 @@ static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev) pm_runtime_get_sync(&mdp->pdev->dev); - mdp->stats.tx_dropped += readl(ioaddr + TROCR); - writel(0, ioaddr + TROCR); /* (write clear) */ - mdp->stats.collisions += readl(ioaddr + CDCR); - writel(0, ioaddr + CDCR); /* (write clear) */ - mdp->stats.tx_carrier_errors += readl(ioaddr + LCCR); - writel(0, ioaddr + LCCR); /* (write clear) */ + mdp->stats.tx_dropped += ctrl_inl(ioaddr + TROCR); + ctrl_outl(0, ioaddr + TROCR); /* (write clear) */ + mdp->stats.collisions += ctrl_inl(ioaddr + CDCR); + ctrl_outl(0, ioaddr + CDCR); /* (write clear) */ + mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + LCCR); + ctrl_outl(0, ioaddr + LCCR); /* (write clear) */ #if defined(CONFIG_CPU_SUBTYPE_SH7763) - mdp->stats.tx_carrier_errors += readl(ioaddr + CERCR);/* CERCR */ - writel(0, ioaddr + CERCR); /* (write clear) */ - mdp->stats.tx_carrier_errors += readl(ioaddr + CEECR);/* CEECR */ - writel(0, ioaddr + CEECR); /* (write clear) */ + mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + CERCR);/* CERCR */ + ctrl_outl(0, ioaddr + CERCR); /* (write clear) */ + mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + CEECR);/* CEECR */ + ctrl_outl(0, ioaddr + CEECR); /* (write clear) */ #else - mdp->stats.tx_carrier_errors += readl(ioaddr + CNDCR); - writel(0, ioaddr + CNDCR); /* (write clear) */ + mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + CNDCR); + ctrl_outl(0, ioaddr + CNDCR); /* (write clear) */ #endif pm_runtime_put_sync(&mdp->pdev->dev); @@ -1295,11 +1295,11 @@ static void sh_eth_set_multicast_list(struct net_device *ndev) if (ndev->flags & IFF_PROMISC) { /* Set promiscuous. */ - writel((readl(ioaddr + ECMR) & ~ECMR_MCT) | ECMR_PRM, + ctrl_outl((ctrl_inl(ioaddr + ECMR) & ~ECMR_MCT) | ECMR_PRM, ioaddr + ECMR); } else { /* Normal, unicast/broadcast-only mode. */ - writel((readl(ioaddr + ECMR) & ~ECMR_PRM) | ECMR_MCT, + ctrl_outl((ctrl_inl(ioaddr + ECMR) & ~ECMR_PRM) | ECMR_MCT, ioaddr + ECMR); } } @@ -1307,30 +1307,30 @@ static void sh_eth_set_multicast_list(struct net_device *ndev) /* SuperH's TSU register init function */ static void sh_eth_tsu_init(u32 ioaddr) { - writel(0, ioaddr + TSU_FWEN0); /* Disable forward(0->1) */ - writel(0, ioaddr + TSU_FWEN1); /* Disable forward(1->0) */ - writel(0, ioaddr + TSU_FCM); /* forward fifo 3k-3k */ - writel(0xc, ioaddr + TSU_BSYSL0); - writel(0xc, ioaddr + TSU_BSYSL1); - writel(0, ioaddr + TSU_PRISL0); - writel(0, ioaddr + TSU_PRISL1); - writel(0, ioaddr + TSU_FWSL0); - writel(0, ioaddr + TSU_FWSL1); - writel(TSU_FWSLC_POSTENU | TSU_FWSLC_POSTENL, ioaddr + TSU_FWSLC); + ctrl_outl(0, ioaddr + TSU_FWEN0); /* Disable forward(0->1) */ + ctrl_outl(0, ioaddr + TSU_FWEN1); /* Disable forward(1->0) */ + ctrl_outl(0, ioaddr + TSU_FCM); /* forward fifo 3k-3k */ + ctrl_outl(0xc, ioaddr + TSU_BSYSL0); + ctrl_outl(0xc, ioaddr + TSU_BSYSL1); + ctrl_outl(0, ioaddr + TSU_PRISL0); + ctrl_outl(0, ioaddr + TSU_PRISL1); + ctrl_outl(0, ioaddr + TSU_FWSL0); + ctrl_outl(0, ioaddr + TSU_FWSL1); + ctrl_outl(TSU_FWSLC_POSTENU | TSU_FWSLC_POSTENL, ioaddr + TSU_FWSLC); #if defined(CONFIG_CPU_SUBTYPE_SH7763) - writel(0, ioaddr + TSU_QTAG0); /* Disable QTAG(0->1) */ - writel(0, ioaddr + TSU_QTAG1); /* Disable QTAG(1->0) */ + ctrl_outl(0, ioaddr + TSU_QTAG0); /* Disable QTAG(0->1) */ + ctrl_outl(0, ioaddr + TSU_QTAG1); /* Disable QTAG(1->0) */ #else - writel(0, ioaddr + TSU_QTAGM0); /* Disable QTAG(0->1) */ - writel(0, ioaddr + TSU_QTAGM1); /* Disable QTAG(1->0) */ + ctrl_outl(0, ioaddr + TSU_QTAGM0); /* Disable QTAG(0->1) */ + ctrl_outl(0, ioaddr + TSU_QTAGM1); /* Disable QTAG(1->0) */ #endif - writel(0, ioaddr + TSU_FWSR); /* all interrupt status clear */ - writel(0, ioaddr + TSU_FWINMK); /* Disable all interrupt */ - writel(0, ioaddr + TSU_TEN); /* Disable all CAM entry */ - writel(0, ioaddr + TSU_POST1); /* Disable CAM entry [ 0- 7] */ - writel(0, ioaddr + TSU_POST2); /* Disable CAM entry [ 8-15] */ - writel(0, ioaddr + TSU_POST3); /* Disable CAM entry [16-23] */ - writel(0, ioaddr + TSU_POST4); /* Disable CAM entry [24-31] */ + ctrl_outl(0, ioaddr + TSU_FWSR); /* all interrupt status clear */ + ctrl_outl(0, ioaddr + TSU_FWINMK); /* Disable all interrupt */ + ctrl_outl(0, ioaddr + TSU_TEN); /* Disable all CAM entry */ + ctrl_outl(0, ioaddr + TSU_POST1); /* Disable CAM entry [ 0- 7] */ + ctrl_outl(0, ioaddr + TSU_POST2); /* Disable CAM entry [ 8-15] */ + ctrl_outl(0, ioaddr + TSU_POST3); /* Disable CAM entry [16-23] */ + ctrl_outl(0, ioaddr + TSU_POST4); /* Disable CAM entry [24-31] */ } #endif /* SH_ETH_HAS_TSU */ diff --git a/trunk/include/linux/netdevice.h b/trunk/include/linux/netdevice.h index fccb11f879e5..578debb801f4 100644 --- a/trunk/include/linux/netdevice.h +++ b/trunk/include/linux/netdevice.h @@ -592,7 +592,8 @@ struct netdev_rx_queue { struct rps_map __rcu *rps_map; struct rps_dev_flow_table __rcu *rps_flow_table; struct kobject kobj; - struct net_device *dev; + struct netdev_rx_queue *first; + atomic_t count; } ____cacheline_aligned_in_smp; #endif /* CONFIG_RPS */ @@ -2238,8 +2239,6 @@ unsigned long netdev_fix_features(unsigned long features, const char *name); void netif_stacked_transfer_operstate(const struct net_device *rootdev, struct net_device *dev); -int netif_get_vlan_features(struct sk_buff *skb, struct net_device *dev); - static inline int net_gso_ok(int features, int gso_type) { int feature = gso_type << NETIF_F_GSO_SHIFT; @@ -2255,7 +2254,10 @@ static inline int skb_gso_ok(struct sk_buff *skb, int features) static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb) { if (skb_is_gso(skb)) { - int features = netif_get_vlan_features(skb, dev); + int features = dev->features; + + if (skb->protocol == htons(ETH_P_8021Q) || skb->vlan_tci) + features &= dev->vlan_features; return (!skb_gso_ok(skb, features) || unlikely(skb->ip_summed != CHECKSUM_PARTIAL)); diff --git a/trunk/include/net/flow.h b/trunk/include/net/flow.h index 7196e6864b8d..0ac3fb5e0973 100644 --- a/trunk/include/net/flow.h +++ b/trunk/include/net/flow.h @@ -67,7 +67,6 @@ struct flowi { } dnports; __be32 spi; - __be32 gre_key; struct { __u8 type; @@ -79,7 +78,6 @@ struct flowi { #define fl_icmp_code uli_u.icmpt.code #define fl_ipsec_spi uli_u.spi #define fl_mh_type uli_u.mht.type -#define fl_gre_key uli_u.gre_key __u32 secid; /* used by xfrm; see secid.txt */ } __attribute__((__aligned__(BITS_PER_LONG/8))); diff --git a/trunk/include/net/xfrm.h b/trunk/include/net/xfrm.h index 54b283229488..bcfb6b24b019 100644 --- a/trunk/include/net/xfrm.h +++ b/trunk/include/net/xfrm.h @@ -805,9 +805,6 @@ __be16 xfrm_flowi_sport(struct flowi *fl) case IPPROTO_MH: port = htons(fl->fl_mh_type); break; - case IPPROTO_GRE: - port = htonl(fl->fl_gre_key) >> 16; - break; default: port = 0; /*XXX*/ } @@ -829,9 +826,6 @@ __be16 xfrm_flowi_dport(struct flowi *fl) case IPPROTO_ICMPV6: port = htons(fl->fl_icmp_code); break; - case IPPROTO_GRE: - port = htonl(fl->fl_gre_key) & 0xffff; - break; default: port = 0; /*XXX*/ } diff --git a/trunk/net/8021q/vlan.c b/trunk/net/8021q/vlan.c index 55d2135889fc..52077ca22072 100644 --- a/trunk/net/8021q/vlan.c +++ b/trunk/net/8021q/vlan.c @@ -334,12 +334,6 @@ static void vlan_transfer_features(struct net_device *dev, vlandev->features &= ~dev->vlan_features; vlandev->features |= dev->features & dev->vlan_features; vlandev->gso_max_size = dev->gso_max_size; - - if (dev->features & NETIF_F_HW_VLAN_TX) - vlandev->hard_header_len = dev->hard_header_len; - else - vlandev->hard_header_len = dev->hard_header_len + VLAN_HLEN; - #if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) vlandev->fcoe_ddp_xid = dev->fcoe_ddp_xid; #endif diff --git a/trunk/net/8021q/vlan.h b/trunk/net/8021q/vlan.h index 4625ba64dfdc..db01b3181fdc 100644 --- a/trunk/net/8021q/vlan.h +++ b/trunk/net/8021q/vlan.h @@ -45,6 +45,8 @@ struct vlan_rx_stats { * @real_dev: underlying netdevice * @real_dev_addr: address of underlying netdevice * @dent: proc dir entry + * @cnt_inc_headroom_on_tx: statistic - number of skb expansions on TX + * @cnt_encap_on_xmit: statistic - number of skb encapsulations on TX * @vlan_rx_stats: ptr to percpu rx stats */ struct vlan_dev_info { @@ -60,6 +62,8 @@ struct vlan_dev_info { unsigned char real_dev_addr[ETH_ALEN]; struct proc_dir_entry *dent; + unsigned long cnt_inc_headroom_on_tx; + unsigned long cnt_encap_on_xmit; struct vlan_rx_stats __percpu *vlan_rx_stats; }; diff --git a/trunk/net/8021q/vlan_dev.c b/trunk/net/8021q/vlan_dev.c index f3c9552f6ba8..14e3d1fa07a0 100644 --- a/trunk/net/8021q/vlan_dev.c +++ b/trunk/net/8021q/vlan_dev.c @@ -274,6 +274,9 @@ static int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev, u16 vlan_tci = 0; int rc; + if (WARN_ON(skb_headroom(skb) < dev->hard_header_len)) + return -ENOSPC; + if (!(vlan_dev_info(dev)->flags & VLAN_FLAG_REORDER_HDR)) { vhdr = (struct vlan_hdr *) skb_push(skb, VLAN_HLEN); @@ -323,12 +326,24 @@ static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb, */ if (veth->h_vlan_proto != htons(ETH_P_8021Q) || vlan_dev_info(dev)->flags & VLAN_FLAG_REORDER_HDR) { + unsigned int orig_headroom = skb_headroom(skb); u16 vlan_tci; + + vlan_dev_info(dev)->cnt_encap_on_xmit++; + vlan_tci = vlan_dev_info(dev)->vlan_id; vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb); - skb = __vlan_hwaccel_put_tag(skb, vlan_tci); + skb = __vlan_put_tag(skb, vlan_tci); + if (!skb) { + txq->tx_dropped++; + return NETDEV_TX_OK; + } + + if (orig_headroom < VLAN_HLEN) + vlan_dev_info(dev)->cnt_inc_headroom_on_tx++; } + skb_set_dev(skb, vlan_dev_info(dev)->real_dev); len = skb->len; ret = dev_queue_xmit(skb); @@ -342,6 +357,32 @@ static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb, return ret; } +static netdev_tx_t vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, + struct net_device *dev) +{ + int i = skb_get_queue_mapping(skb); + struct netdev_queue *txq = netdev_get_tx_queue(dev, i); + u16 vlan_tci; + unsigned int len; + int ret; + + vlan_tci = vlan_dev_info(dev)->vlan_id; + vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb); + skb = __vlan_hwaccel_put_tag(skb, vlan_tci); + + skb->dev = vlan_dev_info(dev)->real_dev; + len = skb->len; + ret = dev_queue_xmit(skb); + + if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) { + txq->tx_packets++; + txq->tx_bytes += len; + } else + txq->tx_dropped++; + + return ret; +} + static u16 vlan_dev_select_queue(struct net_device *dev, struct sk_buff *skb) { struct net_device *rdev = vlan_dev_info(dev)->real_dev; @@ -678,7 +719,8 @@ static const struct header_ops vlan_header_ops = { .parse = eth_header_parse, }; -static const struct net_device_ops vlan_netdev_ops, vlan_netdev_ops_sq; +static const struct net_device_ops vlan_netdev_ops, vlan_netdev_accel_ops, + vlan_netdev_ops_sq, vlan_netdev_accel_ops_sq; static int vlan_dev_init(struct net_device *dev) { @@ -713,16 +755,19 @@ static int vlan_dev_init(struct net_device *dev) if (real_dev->features & NETIF_F_HW_VLAN_TX) { dev->header_ops = real_dev->header_ops; dev->hard_header_len = real_dev->hard_header_len; + if (real_dev->netdev_ops->ndo_select_queue) + dev->netdev_ops = &vlan_netdev_accel_ops_sq; + else + dev->netdev_ops = &vlan_netdev_accel_ops; } else { dev->header_ops = &vlan_header_ops; dev->hard_header_len = real_dev->hard_header_len + VLAN_HLEN; + if (real_dev->netdev_ops->ndo_select_queue) + dev->netdev_ops = &vlan_netdev_ops_sq; + else + dev->netdev_ops = &vlan_netdev_ops; } - if (real_dev->netdev_ops->ndo_select_queue) - dev->netdev_ops = &vlan_netdev_ops_sq; - else - dev->netdev_ops = &vlan_netdev_ops; - if (is_vlan_dev(real_dev)) subclass = 1; @@ -863,6 +908,30 @@ static const struct net_device_ops vlan_netdev_ops = { #endif }; +static const struct net_device_ops vlan_netdev_accel_ops = { + .ndo_change_mtu = vlan_dev_change_mtu, + .ndo_init = vlan_dev_init, + .ndo_uninit = vlan_dev_uninit, + .ndo_open = vlan_dev_open, + .ndo_stop = vlan_dev_stop, + .ndo_start_xmit = vlan_dev_hwaccel_hard_start_xmit, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = vlan_dev_set_mac_address, + .ndo_set_rx_mode = vlan_dev_set_rx_mode, + .ndo_set_multicast_list = vlan_dev_set_rx_mode, + .ndo_change_rx_flags = vlan_dev_change_rx_flags, + .ndo_do_ioctl = vlan_dev_ioctl, + .ndo_neigh_setup = vlan_dev_neigh_setup, + .ndo_get_stats64 = vlan_dev_get_stats64, +#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) + .ndo_fcoe_ddp_setup = vlan_dev_fcoe_ddp_setup, + .ndo_fcoe_ddp_done = vlan_dev_fcoe_ddp_done, + .ndo_fcoe_enable = vlan_dev_fcoe_enable, + .ndo_fcoe_disable = vlan_dev_fcoe_disable, + .ndo_fcoe_get_wwn = vlan_dev_fcoe_get_wwn, +#endif +}; + static const struct net_device_ops vlan_netdev_ops_sq = { .ndo_select_queue = vlan_dev_select_queue, .ndo_change_mtu = vlan_dev_change_mtu, @@ -888,6 +957,31 @@ static const struct net_device_ops vlan_netdev_ops_sq = { #endif }; +static const struct net_device_ops vlan_netdev_accel_ops_sq = { + .ndo_select_queue = vlan_dev_select_queue, + .ndo_change_mtu = vlan_dev_change_mtu, + .ndo_init = vlan_dev_init, + .ndo_uninit = vlan_dev_uninit, + .ndo_open = vlan_dev_open, + .ndo_stop = vlan_dev_stop, + .ndo_start_xmit = vlan_dev_hwaccel_hard_start_xmit, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = vlan_dev_set_mac_address, + .ndo_set_rx_mode = vlan_dev_set_rx_mode, + .ndo_set_multicast_list = vlan_dev_set_rx_mode, + .ndo_change_rx_flags = vlan_dev_change_rx_flags, + .ndo_do_ioctl = vlan_dev_ioctl, + .ndo_neigh_setup = vlan_dev_neigh_setup, + .ndo_get_stats64 = vlan_dev_get_stats64, +#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) + .ndo_fcoe_ddp_setup = vlan_dev_fcoe_ddp_setup, + .ndo_fcoe_ddp_done = vlan_dev_fcoe_ddp_done, + .ndo_fcoe_enable = vlan_dev_fcoe_enable, + .ndo_fcoe_disable = vlan_dev_fcoe_disable, + .ndo_fcoe_get_wwn = vlan_dev_fcoe_get_wwn, +#endif +}; + void vlan_setup(struct net_device *dev) { ether_setup(dev); diff --git a/trunk/net/8021q/vlanproc.c b/trunk/net/8021q/vlanproc.c index d1314cf18adf..80e280f56686 100644 --- a/trunk/net/8021q/vlanproc.c +++ b/trunk/net/8021q/vlanproc.c @@ -280,6 +280,7 @@ static int vlandev_seq_show(struct seq_file *seq, void *offset) const struct vlan_dev_info *dev_info = vlan_dev_info(vlandev); struct rtnl_link_stats64 temp; const struct rtnl_link_stats64 *stats; + static const char fmt[] = "%30s %12lu\n"; static const char fmt64[] = "%30s %12llu\n"; int i; @@ -298,6 +299,10 @@ static int vlandev_seq_show(struct seq_file *seq, void *offset) seq_puts(seq, "\n"); seq_printf(seq, fmt64, "total frames transmitted", stats->tx_packets); seq_printf(seq, fmt64, "total bytes transmitted", stats->tx_bytes); + seq_printf(seq, fmt, "total headroom inc", + dev_info->cnt_inc_headroom_on_tx); + seq_printf(seq, fmt, "total encap on xmit", + dev_info->cnt_encap_on_xmit); seq_printf(seq, "Device: %s", dev_info->real_dev->name); /* now show all PRIORITY mappings relating to this VLAN */ seq_printf(seq, "\nINGRESS priority mappings: " diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index 8725d168d1f5..5968c822c999 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -1794,18 +1794,16 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features) struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT); struct packet_type *ptype; __be16 type = skb->protocol; - int vlan_depth = ETH_HLEN; int err; - while (type == htons(ETH_P_8021Q)) { - struct vlan_hdr *vh; + if (type == htons(ETH_P_8021Q)) { + struct vlan_ethhdr *veh; - if (unlikely(!pskb_may_pull(skb, vlan_depth + VLAN_HLEN))) + if (unlikely(!pskb_may_pull(skb, VLAN_ETH_HLEN))) return ERR_PTR(-EINVAL); - vh = (struct vlan_hdr *)(skb->data + vlan_depth); - type = vh->h_vlan_encapsulated_proto; - vlan_depth += VLAN_HLEN; + veh = (struct vlan_ethhdr *)skb->data; + type = veh->h_vlan_encapsulated_proto; } skb_reset_mac_header(skb); @@ -1968,22 +1966,6 @@ static inline void skb_orphan_try(struct sk_buff *skb) } } -int netif_get_vlan_features(struct sk_buff *skb, struct net_device *dev) -{ - __be16 protocol = skb->protocol; - - if (protocol == htons(ETH_P_8021Q)) { - struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; - protocol = veh->h_vlan_encapsulated_proto; - } else if (!skb->vlan_tci) - return dev->features; - - if (protocol != htons(ETH_P_8021Q)) - return dev->features & dev->vlan_features; - else - return 0; -} - /* * Returns true if either: * 1. skb has frag_list and the device doesn't support FRAGLIST, or @@ -1994,20 +1976,15 @@ int netif_get_vlan_features(struct sk_buff *skb, struct net_device *dev) static inline int skb_needs_linearize(struct sk_buff *skb, struct net_device *dev) { - if (skb_is_nonlinear(skb)) { - int features = dev->features; - - if (vlan_tx_tag_present(skb)) - features &= dev->vlan_features; + int features = dev->features; - return (skb_has_frag_list(skb) && - !(features & NETIF_F_FRAGLIST)) || - (skb_shinfo(skb)->nr_frags && - (!(features & NETIF_F_SG) || - illegal_highdma(dev, skb))); - } + if (skb->protocol == htons(ETH_P_8021Q) || vlan_tx_tag_present(skb)) + features &= dev->vlan_features; - return 0; + return skb_is_nonlinear(skb) && + ((skb_has_frag_list(skb) && !(features & NETIF_F_FRAGLIST)) || + (skb_shinfo(skb)->nr_frags && (!(features & NETIF_F_SG) || + illegal_highdma(dev, skb)))); } int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, @@ -5051,8 +5028,12 @@ static int netif_alloc_rx_queues(struct net_device *dev) } dev->_rx = rx; + /* + * Set a pointer to first element in the array which holds the + * reference count. + */ for (i = 0; i < count; i++) - rx[i].dev = dev; + rx[i].first = rx; #endif return 0; } @@ -5128,6 +5109,14 @@ int register_netdevice(struct net_device *dev) dev->iflink = -1; + ret = netif_alloc_rx_queues(dev); + if (ret) + goto out; + + ret = netif_alloc_netdev_queues(dev); + if (ret) + goto out; + netdev_init_queues(dev); /* Init, if this function is available */ @@ -5587,14 +5576,10 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, dev->num_tx_queues = queue_count; dev->real_num_tx_queues = queue_count; - if (netif_alloc_netdev_queues(dev)) - goto free_pcpu; #ifdef CONFIG_RPS dev->num_rx_queues = queue_count; dev->real_num_rx_queues = queue_count; - if (netif_alloc_rx_queues(dev)) - goto free_pcpu; #endif dev->gso_max_size = GSO_MAX_SIZE; @@ -5611,11 +5596,6 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, free_pcpu: free_percpu(dev->pcpu_refcnt); - kfree(dev->_tx); -#ifdef CONFIG_RPS - kfree(dev->_rx); -#endif - free_p: kfree(p); return NULL; @@ -5637,9 +5617,6 @@ void free_netdev(struct net_device *dev) release_net(dev_net(dev)); kfree(dev->_tx); -#ifdef CONFIG_RPS - kfree(dev->_rx); -#endif kfree(rcu_dereference_raw(dev->ingress_queue)); diff --git a/trunk/net/core/net-sysfs.c b/trunk/net/core/net-sysfs.c index 3ba526b56fe3..a5ff5a89f376 100644 --- a/trunk/net/core/net-sysfs.c +++ b/trunk/net/core/net-sysfs.c @@ -706,6 +706,7 @@ static struct attribute *rx_queue_default_attrs[] = { static void rx_queue_release(struct kobject *kobj) { struct netdev_rx_queue *queue = to_rx_queue(kobj); + struct netdev_rx_queue *first = queue->first; struct rps_map *map; struct rps_dev_flow_table *flow_table; @@ -718,7 +719,8 @@ static void rx_queue_release(struct kobject *kobj) if (flow_table) call_rcu(&flow_table->rcu, rps_dev_flow_table_release); - dev_put(queue->dev); + if (atomic_dec_and_test(&first->count)) + kfree(first); } static struct kobj_type rx_queue_ktype = { @@ -730,6 +732,7 @@ static struct kobj_type rx_queue_ktype = { static int rx_queue_add_kobject(struct net_device *net, int index) { struct netdev_rx_queue *queue = net->_rx + index; + struct netdev_rx_queue *first = queue->first; struct kobject *kobj = &queue->kobj; int error = 0; @@ -742,7 +745,7 @@ static int rx_queue_add_kobject(struct net_device *net, int index) } kobject_uevent(kobj, KOBJ_ADD); - dev_hold(queue->dev); + atomic_inc(&first->count); return error; } diff --git a/trunk/net/dccp/ackvec.c b/trunk/net/dccp/ackvec.c index abaf241c7353..e9a0f66e4afe 100644 --- a/trunk/net/dccp/ackvec.c +++ b/trunk/net/dccp/ackvec.c @@ -92,6 +92,24 @@ int dccp_ackvec_update_records(struct dccp_ackvec *av, u64 seqno, u8 nonce_sum) return 0; } +static struct dccp_ackvec_record *dccp_ackvec_lookup(struct list_head *av_list, + const u64 ackno) +{ + struct dccp_ackvec_record *avr; + /* + * Exploit that records are inserted in descending order of sequence + * number, start with the oldest record first. If @ackno is `before' + * the earliest ack_ackno, the packet is too old to be considered. + */ + list_for_each_entry_reverse(avr, av_list, avr_node) { + if (avr->avr_ack_seqno == ackno) + return avr; + if (before48(ackno, avr->avr_ack_seqno)) + break; + } + return NULL; +} + /* * Buffer index and length computation using modulo-buffersize arithmetic. * Note that, as pointers move from right to left, head is `before' tail. @@ -356,6 +374,76 @@ int dccp_ackvec_parse(struct sock *sk, const struct sk_buff *skb, return 0; } +/** + * dccp_ackvec_clear_state - Perform house-keeping / garbage-collection + * This routine is called when the peer acknowledges the receipt of Ack Vectors + * up to and including @ackno. While based on on section A.3 of RFC 4340, here + * are additional precautions to prevent corrupted buffer state. In particular, + * we use tail_ackno to identify outdated records; it always marks the earliest + * packet of group (2) in 11.4.2. + */ +void dccp_ackvec_clear_state(struct dccp_ackvec *av, const u64 ackno) + { + struct dccp_ackvec_record *avr, *next; + u8 runlen_now, eff_runlen; + s64 delta; + + avr = dccp_ackvec_lookup(&av->av_records, ackno); + if (avr == NULL) + return; + /* + * Deal with outdated acknowledgments: this arises when e.g. there are + * several old records and the acks from the peer come in slowly. In + * that case we may still have records that pre-date tail_ackno. + */ + delta = dccp_delta_seqno(av->av_tail_ackno, avr->avr_ack_ackno); + if (delta < 0) + goto free_records; + /* + * Deal with overlapping Ack Vectors: don't subtract more than the + * number of packets between tail_ackno and ack_ackno. + */ + eff_runlen = delta < avr->avr_ack_runlen ? delta : avr->avr_ack_runlen; + + runlen_now = dccp_ackvec_runlen(av->av_buf + avr->avr_ack_ptr); + /* + * The run length of Ack Vector cells does not decrease over time. If + * the run length is the same as at the time the Ack Vector was sent, we + * free the ack_ptr cell. That cell can however not be freed if the run + * length has increased: in this case we need to move the tail pointer + * backwards (towards higher indices), to its next-oldest neighbour. + */ + if (runlen_now > eff_runlen) { + + av->av_buf[avr->avr_ack_ptr] -= eff_runlen + 1; + av->av_buf_tail = __ackvec_idx_add(avr->avr_ack_ptr, 1); + + /* This move may not have cleared the overflow flag. */ + if (av->av_overflow) + av->av_overflow = (av->av_buf_head == av->av_buf_tail); + } else { + av->av_buf_tail = avr->avr_ack_ptr; + /* + * We have made sure that avr points to a valid cell within the + * buffer. This cell is either older than head, or equals head + * (empty buffer): in both cases we no longer have any overflow. + */ + av->av_overflow = 0; + } + + /* + * The peer has acknowledged up to and including ack_ackno. Hence the + * first packet in group (2) of 11.4.2 is the successor of ack_ackno. + */ + av->av_tail_ackno = ADD48(avr->avr_ack_ackno, 1); + +free_records: + list_for_each_entry_safe_from(avr, next, &av->av_records, avr_node) { + list_del(&avr->avr_node); + kmem_cache_free(dccp_ackvec_record_slab, avr); + } +} + int __init dccp_ackvec_init(void) { dccp_ackvec_slab = kmem_cache_create("dccp_ackvec", diff --git a/trunk/net/dccp/ackvec.h b/trunk/net/dccp/ackvec.h index 23880be8fc29..3f7008187b8e 100644 --- a/trunk/net/dccp/ackvec.h +++ b/trunk/net/dccp/ackvec.h @@ -117,6 +117,7 @@ extern int dccp_ackvec_parse(struct sock *sk, const struct sk_buff *skb, const u8 *value, const u8 len); extern int dccp_ackvec_update_records(struct dccp_ackvec *av, u64 seq, u8 sum); +extern void dccp_ackvec_clear_state(struct dccp_ackvec *av, const u64 ackno); extern u16 dccp_ackvec_buflen(const struct dccp_ackvec *av); static inline bool dccp_ackvec_is_empty(const struct dccp_ackvec *av) diff --git a/trunk/net/dccp/input.c b/trunk/net/dccp/input.c index c7aeeba859d4..f91cf5ada306 100644 --- a/trunk/net/dccp/input.c +++ b/trunk/net/dccp/input.c @@ -165,8 +165,8 @@ static void dccp_event_ack_recv(struct sock *sk, struct sk_buff *skb) struct dccp_sock *dp = dccp_sk(sk); if (dp->dccps_hc_rx_ackvec != NULL) - dccp_ackvec_check_rcv_ackno(dp->dccps_hc_rx_ackvec, sk, - DCCP_SKB_CB(skb)->dccpd_ack_seq); + dccp_ackvec_clear_state(dp->dccps_hc_rx_ackvec, + DCCP_SKB_CB(skb)->dccpd_ack_seq); } static void dccp_deliver_input_to_ccids(struct sock *sk, struct sk_buff *skb) diff --git a/trunk/net/dccp/options.c b/trunk/net/dccp/options.c index 5adeeed5e0d2..7743df00f5b1 100644 --- a/trunk/net/dccp/options.c +++ b/trunk/net/dccp/options.c @@ -54,7 +54,6 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq, struct dccp_sock *dp = dccp_sk(sk); const struct dccp_hdr *dh = dccp_hdr(skb); const u8 pkt_type = DCCP_SKB_CB(skb)->dccpd_type; - u64 ackno = DCCP_SKB_CB(skb)->dccpd_ack_seq; unsigned char *options = (unsigned char *)dh + dccp_hdr_len(skb); unsigned char *opt_ptr = options; const unsigned char *opt_end = (unsigned char *)dh + @@ -133,9 +132,8 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq, case DCCPO_ACK_VECTOR_1: if (dccp_packet_without_ack(skb)) /* RFC 4340, 11.4 */ break; - if (dp->dccps_hc_rx_ackvec != NULL && - dccp_ackvec_parse(sk, skb, &ackno, opt, value, len)) - goto out_invalid_option; + dccp_pr_debug("%s Ack Vector (len=%u)\n", dccp_role(sk), + len); break; case DCCPO_TIMESTAMP: if (len != 4) diff --git a/trunk/net/ipv4/igmp.c b/trunk/net/ipv4/igmp.c index a1bf2f49e716..0f0e0f0279b8 100644 --- a/trunk/net/ipv4/igmp.c +++ b/trunk/net/ipv4/igmp.c @@ -163,16 +163,6 @@ static void ip_ma_put(struct ip_mc_list *im) } } -#define for_each_pmc_rcu(in_dev, pmc) \ - for (pmc = rcu_dereference(in_dev->mc_list); \ - pmc != NULL; \ - pmc = rcu_dereference(pmc->next_rcu)) - -#define for_each_pmc_rtnl(in_dev, pmc) \ - for (pmc = rtnl_dereference(in_dev->mc_list); \ - pmc != NULL; \ - pmc = rtnl_dereference(pmc->next_rcu)) - #ifdef CONFIG_IP_MULTICAST /* @@ -512,6 +502,16 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc, return skb; } +#define for_each_pmc_rcu(in_dev, pmc) \ + for (pmc = rcu_dereference(in_dev->mc_list); \ + pmc != NULL; \ + pmc = rcu_dereference(pmc->next_rcu)) + +#define for_each_pmc_rtnl(in_dev, pmc) \ + for (pmc = rtnl_dereference(in_dev->mc_list); \ + pmc != NULL; \ + pmc = rtnl_dereference(pmc->next_rcu)) + static int igmpv3_send_report(struct in_device *in_dev, struct ip_mc_list *pmc) { struct sk_buff *skb = NULL; diff --git a/trunk/net/ipv4/ip_gre.c b/trunk/net/ipv4/ip_gre.c index aace653710f6..cab2057d5430 100644 --- a/trunk/net/ipv4/ip_gre.c +++ b/trunk/net/ipv4/ip_gre.c @@ -779,9 +779,9 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev .tos = RT_TOS(tos) } }, - .proto = IPPROTO_GRE, - .fl_gre_key = tunnel->parms.o_key - }; + .proto = IPPROTO_GRE + } +; if (ip_route_output_key(dev_net(dev), &rt, &fl)) { dev->stats.tx_carrier_errors++; goto tx_error; @@ -958,8 +958,7 @@ static int ipgre_tunnel_bind_dev(struct net_device *dev) .tos = RT_TOS(iph->tos) } }, - .proto = IPPROTO_GRE, - .fl_gre_key = tunnel->parms.o_key + .proto = IPPROTO_GRE }; struct rtable *rt; @@ -1224,8 +1223,7 @@ static int ipgre_open(struct net_device *dev) .tos = RT_TOS(t->parms.iph.tos) } }, - .proto = IPPROTO_GRE, - .fl_gre_key = t->parms.o_key + .proto = IPPROTO_GRE }; struct rtable *rt; diff --git a/trunk/net/ipv4/xfrm4_policy.c b/trunk/net/ipv4/xfrm4_policy.c index 4a8c5335770c..dd1fd8c473fc 100644 --- a/trunk/net/ipv4/xfrm4_policy.c +++ b/trunk/net/ipv4/xfrm4_policy.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -155,20 +154,6 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse) fl->fl_ipsec_spi = htonl(ntohs(ipcomp_hdr[1])); } break; - - case IPPROTO_GRE: - if (pskb_may_pull(skb, xprth + 12 - skb->data)) { - __be16 *greflags = (__be16 *)xprth; - __be32 *gre_hdr = (__be32 *)xprth; - - if (greflags[0] & GRE_KEY) { - if (greflags[0] & GRE_CSUM) - gre_hdr++; - fl->fl_gre_key = gre_hdr[1]; - } - } - break; - default: fl->fl_ipsec_spi = 0; break;