diff options
198 files changed, 1833 insertions, 1458 deletions
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 2dc7a1d9768..2571a62d923 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -487,6 +487,30 @@ tcp_dma_copybreak - INTEGER and CONFIG_NET_DMA is enabled. Default: 4096 +tcp_thin_linear_timeouts - BOOLEAN + Enable dynamic triggering of linear timeouts for thin streams. + If set, a check is performed upon retransmission by timeout to + determine if the stream is thin (less than 4 packets in flight). + As long as the stream is found to be thin, up to 6 linear + timeouts may be performed before exponential backoff mode is + initiated. This improves retransmission latency for + non-aggressive thin streams, often found to be time-dependent. + For more information on thin streams, see + Documentation/networking/tcp-thin.txt + Default: 0 + +tcp_thin_dupack - BOOLEAN + Enable dynamic triggering of retransmissions after one dupACK + for thin streams. If set, a check is performed upon reception + of a dupACK to determine if the stream is thin (less than 4 + packets in flight). As long as the stream is found to be thin, + data is retransmitted on the first received dupACK. This + improves retransmission latency for non-aggressive thin + streams, often found to be time-dependent. + For more information on thin streams, see + Documentation/networking/tcp-thin.txt + Default: 0 + UDP variables: udp_mem - vector of 3 INTEGERs: min, pressure, max diff --git a/Documentation/networking/tcp-thin.txt b/Documentation/networking/tcp-thin.txt new file mode 100644 index 00000000000..151e229980f --- /dev/null +++ b/Documentation/networking/tcp-thin.txt @@ -0,0 +1,47 @@ +Thin-streams and TCP +==================== +A wide range of Internet-based services that use reliable transport +protocols display what we call thin-stream properties. This means +that the application sends data with such a low rate that the +retransmission mechanisms of the transport protocol are not fully +effective. In time-dependent scenarios (like online games, control +systems, stock trading etc.) where the user experience depends +on the data delivery latency, packet loss can be devastating for +the service quality. Extreme latencies are caused by TCP's +dependency on the arrival of new data from the application to trigger +retransmissions effectively through fast retransmit instead of +waiting for long timeouts. + +After analysing a large number of time-dependent interactive +applications, we have seen that they often produce thin streams +and also stay with this traffic pattern throughout its entire +lifespan. The combination of time-dependency and the fact that the +streams provoke high latencies when using TCP is unfortunate. + +In order to reduce application-layer latency when packets are lost, +a set of mechanisms has been made, which address these latency issues +for thin streams. In short, if the kernel detects a thin stream, +the retransmission mechanisms are modified in the following manner: + +1) If the stream is thin, fast retransmit on the first dupACK. +2) If the stream is thin, do not apply exponential backoff. + +These enhancements are applied only if the stream is detected as +thin. This is accomplished by defining a threshold for the number +of packets in flight. If there are less than 4 packets in flight, +fast retransmissions can not be triggered, and the stream is prone +to experience high retransmission latencies. + +Since these mechanisms are targeted at time-dependent applications, +they must be specifically activated by the application using the +TCP_THIN_LINEAR_TIMEOUTS and TCP_THIN_DUPACK IOCTLS or the +tcp_thin_linear_timeouts and tcp_thin_dupack sysctls. Both +modifications are turned off by default. + +References +========== +More information on the modifications, as well as a wide range of +experimental data can be found here: +"Improving latency for interactive, thin-stream applications over +reliable transport" +http://simula.no/research/nd/publications/Simula.nd.477/simula_pdf_file diff --git a/MAINTAINERS b/MAINTAINERS index 32f6915ae0e..9b0557a42a9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1733,10 +1733,9 @@ F: include/linux/tfrc.h F: net/dccp/ DECnet NETWORK LAYER -M: Christine Caulfield <christine.caulfield@googlemail.com> W: http://linux-decnet.sourceforge.net L: linux-decnet-user@lists.sourceforge.net -S: Maintained +S: Orphan F: Documentation/networking/decnet.txt F: net/decnet/ @@ -4845,6 +4844,8 @@ F: drivers/scsi/be2iscsi/ SERVER ENGINES 10Gbps NIC - BladeEngine 2 DRIVER M: Sathya Perla <sathyap@serverengines.com> M: Subbu Seetharaman <subbus@serverengines.com> +M: Sarveshwar Bandi <sarveshwarb@serverengines.com> +M: Ajit Khaparde <ajitk@serverengines.com> L: netdev@vger.kernel.org W: http://www.serverengines.com S: Supported diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 30bdf427ee6..83a7751c38d 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c @@ -1374,7 +1374,7 @@ static void ipoib_cm_skb_reap(struct work_struct *work) icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu)); #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) else if (skb->protocol == htons(ETH_P_IPV6)) - icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, priv->dev); + icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); #endif dev_kfree_skb_any(skb); diff --git a/drivers/isdn/Kconfig b/drivers/isdn/Kconfig index 022a1945295..4fb601670de 100644 --- a/drivers/isdn/Kconfig +++ b/drivers/isdn/Kconfig @@ -7,15 +7,14 @@ menuconfig ISDN depends on NET depends on !S390 ---help--- - ISDN ("Integrated Services Digital Networks", called RNIS in France) - is a special type of fully digital telephone service; it's mostly - used to connect to your Internet service provider (with SLIP or - PPP). The main advantage is that the speed is higher than ordinary - modem/telephone connections, and that you can have voice - conversations while downloading stuff. It only works if your - computer is equipped with an ISDN card and both you and your service - provider purchased an ISDN line from the phone company. For - details, read <http://www.alumni.caltech.edu/~dank/isdn/> on the WWW. + ISDN ("Integrated Services Digital Network", called RNIS in France) + is a fully digital telephone service that can be used for voice and + data connections. If your computer is equipped with an ISDN + adapter you can use it to connect to your Internet service provider + (with SLIP or PPP) faster than via a conventional telephone modem + (though still much slower than with DSL) or to make and accept + voice calls (eg. turning your PC into a software answering machine + or PABX). Select this option if you want your kernel to support ISDN. @@ -39,17 +38,22 @@ menuconfig ISDN_I4L It is still available, though, for use with adapters that are not supported by the new CAPI subsystem yet. -source "drivers/isdn/mISDN/Kconfig" - source "drivers/isdn/i4l/Kconfig" menuconfig ISDN_CAPI tristate "CAPI 2.0 subsystem" help - This provides the CAPI (Common ISDN Application Programming - Interface, a standard making it easy for programs to access ISDN - hardware, see <http://www.capi.org/>. This is needed for AVM's set - of active ISDN controllers like B1, T1, M1. + This provides CAPI (the Common ISDN Application Programming + Interface) Version 2.0, a standard making it easy for programs to + access ISDN hardware in a device independent way. (For details see + <http://www.capi.org/>.) CAPI supports making and accepting voice + and data connections, controlling call options and protocols, + as well as ISDN supplementary services like call forwarding or + three-party conferences (if supported by the specific hardware + driver). + + Select this option and the appropriate hardware driver below if + you have an ISDN adapter supported by the CAPI subsystem. if ISDN_CAPI @@ -61,4 +65,13 @@ endif # ISDN_CAPI source "drivers/isdn/gigaset/Kconfig" +source "drivers/isdn/hysdn/Kconfig" + +source "drivers/isdn/mISDN/Kconfig" + +config ISDN_HDLC + tristate + select CRC_CCITT + select BITREVERSE + endif # ISDN diff --git a/drivers/isdn/i4l/Kconfig b/drivers/isdn/i4l/Kconfig index 07c4e49f9e7..9c6650ea848 100644 --- a/drivers/isdn/i4l/Kconfig +++ b/drivers/isdn/i4l/Kconfig @@ -134,14 +134,7 @@ source "drivers/isdn/sc/Kconfig" source "drivers/isdn/act2000/Kconfig" -source "drivers/isdn/hysdn/Kconfig" - endmenu # end ISDN_I4L endif -config ISDN_HDLC - tristate - select CRC_CCITT - select BITREVERSE - diff --git a/drivers/net/3c501.c b/drivers/net/3c501.c index 4d4cad393dc..b6de7b1e2a5 100644 --- a/drivers/net/3c501.c +++ b/drivers/net/3c501.c @@ -812,7 +812,7 @@ static void set_multicast_list(struct net_device *dev) if (dev->flags & IFF_PROMISC) { outb(RX_PROM, RX_CMD); inb(RX_STATUS); - } else if (dev->mc_list || dev->flags & IFF_ALLMULTI) { + } else if (!netdev_mc_empty(dev) || dev->flags & IFF_ALLMULTI) { /* Multicast or all multicast is the same */ outb(RX_MULT, RX_CMD); inb(RX_STATUS); /* Clear status. */ diff --git a/drivers/net/3c505.c b/drivers/net/3c505.c index dadb46a8833..04b5bba1902 100644 --- a/drivers/net/3c505.c +++ b/drivers/net/3c505.c @@ -1216,7 +1216,7 @@ static int elp_close(struct net_device *dev) static void elp_set_mc_list(struct net_device *dev) { elp_device *adapter = netdev_priv(dev); - struct dev_mc_list *dmi = dev->mc_list; + struct dev_mc_list *dmi; int i; unsigned long flags; @@ -1230,10 +1230,9 @@ static void elp_set_mc_list(struct net_device *dev) /* if num_addrs==0 the list will be cleared */ adapter->tx_pcb.command = CMD_LOAD_MULTICAST_LIST; adapter->tx_pcb.length = 6 * netdev_mc_count(dev); - for (i = 0; i < netdev_mc_count(dev); i++) { - memcpy(adapter->tx_pcb.data.multicast[i], dmi->dmi_addr, 6); - dmi = dmi->next; - } + i = 0; + netdev_for_each_mc_addr(dmi, dev) + memcpy(adapter->tx_pcb.data.multicast[i++], dmi->dmi_addr, 6); adapter->got[CMD_LOAD_MULTICAST_LIST] = 0; if (!send_pcb(dev, &adapter->tx_pcb)) pr_err("%s: couldn't send set_multicast command\n", dev->name); diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c index 063b049ffe5..1e898b1c806 100644 --- a/drivers/net/3c515.c +++ b/drivers/net/3c515.c @@ -1536,7 +1536,7 @@ static void set_rx_mode(struct net_device *dev) pr_debug("%s: Setting promiscuous mode.\n", dev->name); new_mode = SetRxFilter | RxStation | RxMulticast | RxBroadcast | RxProm; - } else if ((dev->mc_list) || (dev->flags & IFF_ALLMULTI)) { + } else if (!netdev_mc_empty(dev) || dev->flags & IFF_ALLMULTI) { new_mode = SetRxFilter | RxStation | RxMulticast | RxBroadcast; } else new_mode = SetRxFilter | RxStation | RxBroadcast; diff --git a/drivers/net/3c523.c b/drivers/net/3c523.c index 6948d667fc5..beed4fa10c6 100644 --- a/drivers/net/3c523.c +++ b/drivers/net/3c523.c @@ -625,7 +625,7 @@ static int init586(struct net_device *dev) volatile struct iasetup_cmd_struct *ias_cmd; volatile struct tdr_cmd_struct *tdr_cmd; volatile struct mcsetup_cmd_struct *mc_cmd; - struct dev_mc_list *dmi = dev->mc_list; + struct dev_mc_list *dmi; int num_addrs = netdev_mc_count(dev); ptr = (void *) ((char *) p->scb + sizeof(struct scb_struct)); @@ -787,10 +787,9 @@ static int init586(struct net_device *dev) mc_cmd->cmd_cmd = CMD_MCSETUP | CMD_LAST; mc_cmd->cmd_link = 0xffff; mc_cmd->mc_cnt = num_addrs * 6; - for (i = 0; i < num_addrs; i++) { - memcpy((char *) mc_cmd->mc_list[i], dmi->dmi_addr, 6); - dmi = dmi->next; - } + i = 0; + netdev_for_each_mc_addr(dmi, dev) + memcpy((char *) mc_cmd->mc_list[i++], dmi->dmi_addr, 6); p->scb->cbl_offset = make16(mc_cmd); p->scb->cmd = CUC_START; elmc_id_attn586(); diff --git a/drivers/net/3c527.c b/drivers/net/3c527.c index ce982698051..5c07b147ec9 100644 --- a/drivers/net/3c527.c +++ b/drivers/net/3c527.c @@ -1533,9 +1533,7 @@ static void do_mc32_set_multicast_list(struct net_device *dev, int retry) { unsigned char block[62]; unsigned char *bp; - struct dev_mc_list *dmc=dev->mc_list; - - int i; + struct dev_mc_list *dmc; if(retry==0) lp->mc_list_valid = 0; @@ -1545,11 +1543,9 @@ static void do_mc32_set_multicast_list(struct net_device *dev, int retry) block[0]=netdev_mc_count(dev); bp=block+2; - for(i=0;i<netdev_mc_count(dev);i++) - { + netdev_for_each_mc_addr(dmc, dev) { memcpy(bp, dmc->dmi_addr, 6); bp+=6; - dmc=dmc->next; } if(mc32_command_nowait(dev, 2, block, 2+6*netdev_mc_count(dev))==-1) diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index 5df46c230b0..f965431f492 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c @@ -2970,7 +2970,7 @@ static void set_rx_mode(struct net_device *dev) if (vortex_debug > 3) pr_notice("%s: Setting promiscuous mode.\n", dev->name); new_mode = SetRxFilter|RxStation|RxMulticast|RxBroadcast|RxProm; - } else if ((dev->mc_list) || (dev->flags & IFF_ALLMULTI)) { + } else if (!netdev_mc_empty(dev) || dev->flags & IFF_ALLMULTI) { new_mode = SetRxFilter|RxStation|RxMulticast|RxBroadcast; } else new_mode = SetRxFilter | RxStation | RxBroadcast; diff --git a/drivers/net/7990.c b/drivers/net/7990.c index 079d0be3782..4e9a5a20b6a 100644 --- a/drivers/net/7990.c +++ b/drivers/net/7990.c @@ -595,9 +595,8 @@ static void lance_load_multicast (struct net_device *dev) struct lance_private *lp = netdev_priv(dev); volatile struct lance_init_block *ib = lp->init_block; volatile u16 *mcast_table = (u16 *)&ib->filter; - struct dev_mc_list *dmi=dev->mc_list; + struct dev_mc_list *dmi; char *addrs; - int i; u32 crc; /* set all multicast bits */ @@ -611,9 +610,8 @@ static void lance_load_multicast (struct net_device *dev) ib->filter [1] = 0; /* Add addresses */ - for (i = 0; i < netdev_mc_count(dev); i++){ + netdev_for_each_mc_addr(dmi, dev) { addrs = dmi->dmi_addr; - dmi = dmi->next; /* multicast address? */ if (!(*addrs & 1)) diff --git a/drivers/net/82596.c b/drivers/net/82596.c index 638ce3b2985..f94d17d78bb 100644 --- a/drivers/net/82596.c +++ b/drivers/net/82596.c @@ -1550,13 +1550,16 @@ static void set_multicast_list(struct net_device *dev) return; cmd = &lp->mc_cmd; cmd->cmd.command = CmdMulticastList; - cmd->mc_cnt = netdev_mc_count(dev) * 6; + cmd->mc_cnt = cnt * ETH_ALEN; cp = cmd->mc_addrs; - for (dmi = dev->mc_list; cnt && dmi != NULL; dmi = dmi->next, cnt--, cp += 6) { - memcpy(cp, dmi->dmi_addr, 6); + netdev_for_each_mc_addr(dmi, dev) { + if (!cnt--) + break; + memcpy(cp, dmi->dmi_addr, ETH_ALEN); if (i596_debug > 1) DEB(DEB_MULTI,printk(KERN_INFO "%s: Adding address %pM\n", dev->name, cp)); + cp += ETH_ALEN; } i596_add_cmd(dev, &cmd->cmd); } diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 17ff15f6099..46af867af85 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -997,7 +997,7 @@ config ETHOC config GRETH tristate "Aeroflex Gaisler GRETH Ethernet MAC support" - depends on OF + depends on SPARC select PHYLIB select CRC32 help diff --git a/drivers/net/a2065.c b/drivers/net/a2065.c index 6a65f660c19..bd4d829eca1 100644 --- a/drivers/net/a2065.c +++ b/drivers/net/a2065.c @@ -603,9 +603,8 @@ static void lance_load_multicast (struct net_device *dev) struct lance_private *lp = netdev_priv(dev); volatile struct lance_init_block *ib = lp->init_block; volatile u16 *mcast_table = (u16 *)&ib->filter; - struct dev_mc_list *dmi=dev->mc_list; + struct dev_mc_list *dmi; char *addrs; - int i; u32 crc; /* set all multicast bits */ @@ -619,9 +618,8 @@ static void lance_load_multicast (struct net_device *dev) ib->filter [1] = 0; /* Add addresses */ - for (i = 0; i < netdev_mc_count(dev); i++){ + netdev_for_each_mc_addr(dmi, dev) { addrs = dmi->dmi_addr; - dmi = dmi->next; /* multicast address? */ if (!(*addrs & 1)) diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c index bdffdfb4c88..b8a59d255b4 100644 --- a/drivers/net/amd8111e.c +++ b/drivers/net/amd8111e.c @@ -1377,10 +1377,11 @@ list to the device. */ static void amd8111e_set_multicast_list(struct net_device *dev) { - struct dev_mc_list* mc_ptr; + struct dev_mc_list *mc_ptr; struct amd8111e_priv *lp = netdev_priv(dev); u32 mc_filter[2] ; - int i,bit_num; + int bit_num; + if(dev->flags & IFF_PROMISC){ writel( VAL2 | PROM, lp->mmio + CMD2); return; @@ -1391,7 +1392,6 @@ static void amd8111e_set_multicast_list(struct net_device *dev) netdev_mc_count(dev) > MAX_FILTER_SIZE) { /* get all multicast packet */ mc_filter[1] = mc_filter[0] = 0xffffffff; - lp->mc_list = dev->mc_list; lp->options |= OPTION_MULTICAST_ENABLE; amd8111e_writeq(*(u64*)mc_filter,lp->mmio + LADRF); return; @@ -1399,7 +1399,6 @@ static void amd8111e_set_multicast_list(struct net_device *dev) if (netdev_mc_empty(dev)) { /* get only own packets */ mc_filter[1] = mc_filter[0] = 0; - lp->mc_list = NULL; lp->options &= ~OPTION_MULTICAST_ENABLE; amd8111e_writeq(*(u64*)mc_filter,lp->mmio + LADRF); /* disable promiscous mode */ @@ -1408,10 +1407,8 @@ static void amd8111e_set_multicast_list(struct net_device *dev) } /* load all the multicast addresses in the logic filter */ lp->options |= OPTION_MULTICAST_ENABLE; - lp->mc_list = dev->mc_list; mc_filter[1] = mc_filter[0] = 0; - for (i = 0, mc_ptr = dev->mc_list; mc_ptr && i < netdev_mc_count(dev); - i++, mc_ptr = mc_ptr->next) { + netdev_for_each_mc_addr(mc_ptr, dev) { bit_num = (ether_crc_le(ETH_ALEN, mc_ptr->dmi_addr) >> 26) & 0x3f; mc_filter[bit_num >> 5] |= 1 << (bit_num & 31); } diff --git a/drivers/net/amd8111e.h b/drivers/net/amd8111e.h index 28c60a71ed5..ac36eb6981e 100644 --- a/drivers/net/amd8111e.h +++ b/drivers/net/amd8111e.h @@ -789,7 +789,6 @@ struct amd8111e_priv{ char opened; struct net_device_stats stats; unsigned int drv_rx_errors; - struct dev_mc_list* mc_list; struct amd8111e_coalesce_conf coal_conf; struct ipg_info ipg_data; diff --git a/drivers/net/appletalk/ltpc.c b/drivers/net/appletalk/ltpc.c index dbfbd3b7ff8..8ea4ec705be 100644 --- a/drivers/net/appletalk/ltpc.c +++ b/drivers/net/appletalk/ltpc.c @@ -1125,7 +1125,6 @@ struct net_device * __init ltpc_probe(void) printk(KERN_INFO "Apple/Farallon LocalTalk-PC card at %03x, DMA%d. Using polled mode.\n",io,dma); dev->netdev_ops = <pc_netdev; - dev->mc_list = NULL; dev->base_addr = io; dev->irq = irq; dev->dma = dma; diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c index 1c3c1f94268..f1f58c5e27b 100644 --- a/drivers/net/arm/am79c961a.c +++ b/drivers/net/arm/am79c961a.c @@ -351,13 +351,13 @@ static struct net_device_stats *am79c961_getstats (struct net_device *dev) return &priv->stats; } -static void am79c961_mc_hash(struct dev_mc_list *dmi, unsigned short *hash) +static void am79c961_mc_hash(char *addr, unsigned short *hash) { - if (dmi->dmi_addrlen == ETH_ALEN && dmi->dmi_addr[0] & 0x01) { + if (addr[0] & 0x01) { int idx, bit; u32 crc; - crc = ether_crc_le(ETH_ALEN, dmi->dmi_addr); + crc = ether_crc_le(ETH_ALEN, addr); idx = crc >> 30; bit = (crc >> 26) & 15; @@ -387,8 +387,8 @@ static void am79c961_setmulticastlist (struct net_device *dev) memset(multi_hash, 0x00, sizeof(multi_hash)); - for (dmi = dev->mc_list; dmi; dmi = dmi->next) - am79c961_mc_hash(dmi, multi_hash); + netdev_for_each_mc_addr(dmi, dev) + am79c961_mc_hash(dmi->dmi_addr, multi_hash); } spin_lock_irqsave(&priv->chip_lock, flags); diff --git a/drivers/net/arm/at91_ether.c b/drivers/net/arm/at91_ether.c index 17d85d98987..8b23d5a175b 100644 --- a/drivers/net/arm/at91_ether.c +++ b/drivers/net/arm/at91_ether.c @@ -558,14 +558,11 @@ static void at91ether_sethashtable(struct net_device *dev) { struct dev_mc_list *curr; unsigned long mc_filter[2]; - unsigned int i, bitnr; + unsigned int bitnr; mc_filter[0] = mc_filter[1] = 0; - curr = dev->mc_list; - for (i = 0; i < netdev_mc_count(dev); i++, curr = curr->next) { - if (!curr) break; /* unexpected end of list */ - + netdev_for_each_mc_addr(curr, dev) { bitnr = hash_get_index(curr->dmi_addr); mc_filter[bitnr >> 5] |= 1 << (bitnr & 31); } diff --git a/drivers/net/arm/ixp4xx_eth.c b/drivers/net/arm/ixp4xx_eth.c index 1a5f78b160f..6e2ae1d06df 100644 --- a/drivers/net/arm/ixp4xx_eth.c +++ b/drivers/net/arm/ixp4xx_eth.c @@ -735,22 +735,25 @@ static int eth_xmit(struct sk_buff *skb, struct net_device *dev) static void eth_set_mcast_list(struct net_device *dev) { struct port *port = netdev_priv(dev); - struct dev_mc_list *mclist = dev->mc_list; + struct dev_mc_list *mclist; u8 diffs[ETH_ALEN], *addr; - int cnt = netdev_mc_count(dev), i; + int i; - if ((dev->flags & IFF_PROMISC) || !mclist || !cnt) { + if ((dev->flags & IFF_PROMISC) || netdev_mc_empty(dev)) { __raw_writel(DEFAULT_RX_CNTRL0 & ~RX_CNTRL0_ADDR_FLTR_EN, &port->regs->rx_control[0]); return; } memset(diffs, 0, ETH_ALEN); - addr = mclist->dmi_addr; /* first MAC address */ - while (--cnt && (mclist = mclist->next)) + addr = NULL; + netdev_for_each_mc_addr(mclist, dev) { + if (!addr) + addr = mclist->dmi_addr; /* first MAC address */ for (i = 0; i < ETH_ALEN; i++) diffs[i] |= addr[i] ^ mclist->dmi_addr[i]; + } for (i = 0; i < ETH_ALEN; i++) { __raw_writel(addr[i], &port->regs->mcast_addr[i]); diff --git a/drivers/net/arm/ks8695net.c b/drivers/net/arm/ks8695net.c index 1dc181a9fbc..23806969951 100644 --- a/drivers/net/arm/ks8695net.c +++ b/drivers/net/arm/ks8695net.c @@ -327,25 +327,24 @@ ks8695_refill_rxbuffers(struct ks8695_priv *ksp) */ static void ks8695_init_partial_multicast(struct ks8695_priv *ksp, - struct dev_mc_list *addr, - int nr_addr) + struct net_device *ndev) { u32 low, high; int i; + struct dev_mc_list *dmi; - for (i = 0; i < nr_addr; i++, addr = addr->next) { - /* Ran out of addresses? */ - if (!addr) - break; + i = 0; + netdev_for_each_mc_addr(dmi, ndev) { /* Ran out of space in chip? */ BUG_ON(i == KS8695_NR_ADDRESSES); - low = (addr->dmi_addr[2] << 24) | (addr->dmi_addr[3] << 16) | - (addr->dmi_addr[4] << 8) | (addr->dmi_addr[5]); - high = (addr->dmi_addr[0] << 8) | (addr->dmi_addr[1]); + low = (dmi->dmi_addr[2] << 24) | (dmi->dmi_addr[3] << 16) | + (dmi->dmi_addr[4] << 8) | (dmi->dmi_addr[5]); + high = (dmi->dmi_addr[0] << 8) | (dmi->dmi_addr[1]); ks8695_writereg(ksp, KS8695_AAL_(i), low); ks8695_writereg(ksp, KS8695_AAH_(i), AAH_E | high); + i++; } /* Clear the remaining Additional Station Addresses */ @@ -1215,8 +1214,7 @@ ks8695_set_multicast(struct net_device *ndev) } else { /* enable specific multicasts */ ctrl &= ~DRXC_RM; - ks8695_init_partial_multicast(ksp, ndev->mc_list, - netdev_mc_count(ndev)); + ks8695_init_partial_multicast(ksp, ndev); } ks8695_writereg(ksp, KS8695_DRXC, ctrl); diff --git a/drivers/net/arm/w90p910_ether.c b/drivers/net/arm/w90p910_ether.c index b7f3866d546..febd813c916 100644 --- a/drivers/net/arm/w90p910_ether.c +++ b/drivers/net/arm/w90p910_ether.c @@ -858,10 +858,10 @@ static void w90p910_ether_set_multicast_list(struct net_device *dev) if (dev->flags & IFF_PROMISC) rx_mode = CAMCMR_AUP | CAMCMR_AMP | CAMCMR_ABP | CAMCMR_ECMP; - else if ((dev->flags & IFF_ALLMULTI) || dev->mc_list) - rx_mode = CAMCMR_AMP | CAMCMR_ABP | CAMCMR_ECMP; - else - rx_mode = CAMCMR_ECMP | CAMCMR_ABP; + else if ((dev->flags & IFF_ALLMULTI) || !netdev_mc_empty(dev)) + rx_mode = CAMCMR_AMP | CAMCMR_ABP | CAMCMR_ECMP; + else + rx_mode = CAMCMR_ECMP | CAMCMR_ABP; __raw_writel(rx_mode, ether->reg + REG_CAMCMR); } diff --git a/drivers/net/at1700.c b/drivers/net/at1700.c index fe60cd02c86..309843ab886 100644 --- a/drivers/net/at1700.c +++ b/drivers/net/at1700.c @@ -849,11 +849,9 @@ set_rx_mode(struct net_device *dev) outb(1, ioaddr + RX_MODE); /* Ignore almost all multicasts. */ } else { struct dev_mc_list *mclist; - int i; memset(mc_filter, 0, sizeof(mc_filter)); - for (i = 0, mclist = dev->mc_list; mclist && i < netdev_mc_count(dev); - i++, mclist = mclist->next) { + netdev_for_each_mc_addr(mclist, dev) { unsigned int bit = ether_crc_le(ETH_ALEN, mclist->dmi_addr) >> 26; mc_filter[bit >> 3] |= (1 << bit); diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c index 3d4c0a5a77e..50dc531a02d 100644 --- a/drivers/net/atl1c/atl1c_main.c +++ b/drivers/net/atl1c/atl1c_main.c @@ -377,7 +377,7 @@ static void atl1c_set_multi(struct net_device *netdev) AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0); /* comoute mc addresses' hash value ,and put it into hash table */ - for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) { + netdev_for_each_mc_addr(mc_ptr, netdev) { hash_value = atl1c_hash_mc_addr(hw, mc_ptr->dmi_addr); atl1c_hash_set(hw, hash_value); } diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c index 7d8de10ba62..73302ae468a 100644 --- a/drivers/net/atl1e/atl1e_main.c +++ b/drivers/net/atl1e/atl1e_main.c @@ -307,7 +307,7 @@ static void atl1e_set_multi(struct net_device *netdev) AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0); /* comoute mc addresses' hash value ,and put it into hash table */ - for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) { + netdev_for_each_mc_addr(mc_ptr, netdev) { hash_value = atl1e_hash_mc_addr(hw, mc_ptr->dmi_addr); atl1e_hash_set(hw, hash_value); } diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c index 40cf9e5cb9e..7061d7108f0 100644 --- a/drivers/net/atlx/atl2.c +++ b/drivers/net/atlx/atl2.c @@ -157,7 +157,7 @@ static void atl2_set_multi(struct net_device *netdev) ATL2_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0); /* comoute mc addresses' hash value ,and put it into hash table */ - for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) { + netdev_for_each_mc_addr(mc_ptr, netdev) { hash_value = atl2_hash_mc_addr(hw, mc_ptr->dmi_addr); atl2_hash_set(hw, hash_value); } diff --git a/drivers/net/atlx/atlx.c b/drivers/net/atlx/atlx.c index 3dc01421567..72f3306352e 100644 --- a/drivers/net/atlx/atlx.c +++ b/drivers/net/atlx/atlx.c @@ -144,7 +144,7 @@ static void atlx_set_multi(struct net_device *netdev) iowrite32(0, (hw->hw_addr + REG_RX_HASH_TABLE) + (1 << 2)); /* compute mc addresses' hash value ,and put it into hash table */ - for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) { + netdev_for_each_mc_addr(mc_ptr, netdev) { hash_value = atlx_hash_mc_addr(hw, mc_ptr->dmi_addr); atlx_hash_set(hw, hash_value); } diff --git a/drivers/net/atp.c b/drivers/net/atp.c index a841feb5df2..6ad16205dc1 100644 --- a/drivers/net/atp.c +++ b/drivers/net/atp.c @@ -886,9 +886,7 @@ static void set_rx_mode_8012(struct net_device *dev) struct dev_mc_list *mclist; memset(mc_filter, 0, sizeof(mc_filter)); - for (i = 0, mclist = dev->mc_list; mclist && i < netdev_mc_count(dev); - i++, mclist = mclist->next) - { + netdev_for_each_mc_addr(mclist, dev) { int filterbit = ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x3f; mc_filter[filterbit >> 5] |= 1 << (filterbit & 31); } diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index 9337d023919..a66b06aa1f0 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c @@ -1018,16 +1018,13 @@ static void au1000_multicast_list(struct net_device *dev) aup->mac->control &= ~MAC_PROMISCUOUS; printk(KERN_INFO "%s: Pass all multicast\n", dev->name); } else { - int i; struct dev_mc_list *mclist; u32 mc_filter[2]; /* Multicast hash filter */ mc_filter[1] = mc_filter[0] = 0; - for (i = 0, mclist = dev->mc_list; mclist && i < netdev_mc_count(dev); - i++, mclist = mclist->next) { + netdev_for_each_mc_addr(mclist, dev) set_bit(ether_crc(ETH_ALEN, mclist->dmi_addr)>>26, (long *)mc_filter); - } aup->mac->multi_hash_high = mc_filter[1]; aup->mac->multi_hash_low = mc_filter[0]; aup->mac->control &= ~MAC_PROMISCUOUS; diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 180510ed92a..332c6035628 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -338,7 +338,7 @@ static int b44_phy_reset(struct b44 *bp) } } - return 0; + return err; } static void __b44_set_flow_ctrl(struct b44 *bp, u32 pause_flags) @@ -809,7 +809,7 @@ static int b44_rx(struct b44 *bp, int budget) struct sk_buff *copy_skb; b44_recycle_rx(bp, cons, bp->rx_prod); - copy_skb = dev_alloc_skb(len + 2); + copy_skb = netdev_alloc_skb(bp->dev, len + 2); if (copy_skb == NULL) goto drop_it_no_recycle; @@ -1684,9 +1684,11 @@ static int __b44_load_mcast(struct b44 *bp, struct net_device *dev) int i, num_ents; num_ents = min_t(int, netdev_mc_count(dev), B44_MCAST_TABLE_SIZE); - mclist = dev->mc_list; - for (i = 0; mclist && i < num_ents; i++, mclist = mclist->next) { - __b44_cam_write(bp, mclist->dmi_addr, i + 1); + i = 0; + netdev_for_each_mc_addr(mclist, dev) { + if (i == num_ents) + break; + __b44_cam_write(bp, mclist->dmi_addr, i++ + 1); } return i+1; } @@ -2215,6 +2217,10 @@ static int __devinit b44_init_one(struct ssb_device *sdev, */ b44_chip_reset(bp, B44_CHIP_RESET_FULL); + /* do a phy reset to test if there is an active phy */ + if (b44_phy_reset(bp) < 0) + bp->phy_addr = B44_PHY_ADDR_NO_PHY; + netdev_info(dev, "Broadcom 44xx/47xx 10/100BaseT Ethernet %pM\n", dev->dev_addr); diff --git a/drivers/net/bcm63xx_enet.c b/drivers/net/bcm63xx_enet.c index 0927ffa0d75..8cdcab7655c 100644 --- a/drivers/net/bcm63xx_enet.c +++ b/drivers/net/bcm63xx_enet.c @@ -631,16 +631,13 @@ static void bcm_enet_set_multicast_list(struct net_device *dev) return; } - for (i = 0, mc_list = dev->mc_list; - (mc_list != NULL) && (i < netdev_mc_count(dev)) && (i < 3); - i++, mc_list = mc_list->next) { + i = 0; + netdev_for_each_mc_addr(mc_list, dev) { u8 *dmi_addr; u32 tmp; - /* filter non ethernet address */ - if (mc_list->dmi_addrlen != 6) - continue; - + if (i == 3) + break; /* update perfect match registers */ dmi_addr = mc_list->dmi_addr; tmp = (dmi_addr[2] << 24) | (dmi_addr[3] << 16) | @@ -649,7 +646,7 @@ static void bcm_enet_set_multicast_list(struct net_device *dev) tmp = (dmi_addr[0] << 8 | dmi_addr[1]); tmp |= ENET_PMH_DATAVALID_MASK; - enet_writel(priv, tmp, ENET_PMH_REG(i + 1)); + enet_writel(priv, tmp, ENET_PMH_REG(i++ + 1)); } for (; i < 3; i++) { diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 2734a41a462..be81fb2d10f 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005 - 2009 ServerEngines + * Copyright (C) 2005 - 2010 ServerEngines * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -32,7 +32,7 @@ #include "be_hw.h" -#define DRV_VER "2.101.346u" +#define DRV_VER "2.102.147u" #define DRV_NAME "be2net" #define BE_NAME "ServerEngines BladeEngine2 10Gbps NIC" #define BE3_NAME "ServerEngines BladeEngine3 10Gbps NIC" @@ -164,6 +164,7 @@ struct be_drvr_stats { ulong be_tx_jiffies; u64 be_tx_bytes; u64 be_tx_bytes_prev; + u64 be_tx_pkts; u32 be_tx_rate; u32 cache_barrier[16]; @@ -175,6 +176,7 @@ struct be_drvr_stats { ulong be_rx_jiffies; u64 be_rx_bytes; u64 be_rx_bytes_prev; + u64 be_rx_pkts; u32 be_rx_rate; /* number of non ether type II frames dropped where * frame len > length field of Mac Hdr */ diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index d7546b45050..c8a2bacb1d1 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005 - 2009 ServerEngines + * Copyright (C) 2005 - 2010 ServerEngines * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -1134,8 +1134,7 @@ err: * (mc == NULL) => multicast promiscous */ int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id, - struct dev_mc_list *mc_list, u32 mc_count, - struct be_dma_mem *mem) + struct net_device *netdev, struct be_dma_mem *mem) { struct be_mcc_wrb *wrb; struct be_cmd_req_mcast_mac_config *req = mem->va; @@ -1162,13 +1161,14 @@ int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id, OPCODE_COMMON_NTWK_MULTICAST_SET, sizeof(*req)); req->interface_id = if_id; - if (mc_list) { + if (netdev) { int i; struct dev_mc_list *mc; - req->num_mac = cpu_to_le16(mc_count); + req->num_mac = cpu_to_le16(netdev_mc_count(netdev)); - for (mc = mc_list, i = 0; mc; mc = mc->next, i++) + i = 0; + netdev_for_each_mc_addr(mc, netdev) memcpy(req->mac[i].byte, mc->dmi_addr, ETH_ALEN); } else { req->promiscuous = 1; diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index 01501dbae00..728b0d73692 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005 - 2009 ServerEngines + * Copyright (C) 2005 - 2010 ServerEngines * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -912,8 +912,7 @@ extern int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id, extern int be_cmd_promiscuous_config(struct be_adapter *adapter, u8 port_num, bool en); extern int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id, - struct dev_mc_list *mc_list, u32 mc_count, - struct be_dma_mem *mem); + struct net_device *netdev, struct be_dma_mem *mem); extern int be_cmd_set_flow_control(struct be_adapter *adapter, u32 tx_fc, u32 rx_fc); extern int be_cmd_get_flow_control(struct be_adapter *adapter, diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index dcc7f37b542..9560d48944a 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005 - 2009 ServerEngines + * Copyright (C) 2005 - 2010 ServerEngines * All rights reserved. * * This program is free software; you can redistribute it and/or diff --git a/drivers/net/benet/be_hw.h b/drivers/net/benet/be_hw.h index bb2ae6f924d..5ffb149181a 100644 --- a/drivers/net/benet/be_hw.h +++ b/drivers/net/benet/be_hw.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005 - 2009 ServerEngines + * Copyright (C) 2005 - 2010 ServerEngines * All rights reserved. * * This program is free software; you can redistribute it and/or diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 68e7848ac0b..27ccdd80257 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005 - 2009 ServerEngines + * Copyright (C) 2005 - 2010 ServerEngines * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -159,13 +159,10 @@ void netdev_stats_update(struct be_adapter *adapter) struct net_device_stats *dev_stats = &adapter->netdev->stats; struct be_erx_stats *erx_stats = &hw_stats->erx; - dev_stats->rx_packets = port_stats->rx_total_frames; - dev_stats->tx_packets = port_stats->tx_unicastframes + - port_stats->tx_multicastframes + port_stats->tx_broadcastframes; - dev_stats->rx_bytes = (u64) port_stats->rx_bytes_msd << 32 | - (u64) port_stats->rx_bytes_lsd; - dev_stats->tx_bytes = (u64) port_stats->tx_bytes_msd << 32 | - (u64) port_stats->tx_bytes_lsd; + dev_stats->rx_packets = drvr_stats(adapter)->be_rx_pkts; + dev_stats->tx_packets = drvr_stats(adapter)->be_tx_pkts; + dev_stats->rx_bytes = drvr_stats(adapter)->be_rx_bytes; + dev_stats->tx_bytes = drvr_stats(adapter)->be_tx_bytes; /* bad pkts received */ dev_stats->rx_errors = port_stats->rx_crc_errors + @@ -322,12 +319,13 @@ static void be_tx_rate_update(struct be_adapter *adapter) } static void be_tx_stats_update(struct be_adapter *adapter, - u32 wrb_cnt, u32 copied, bool stopped) + u32 wrb_cnt, u32 copied, u32 gso_segs, bool stopped) { struct be_drvr_stats *stats = drvr_stats(adapter); stats->be_tx_reqs++; stats->be_tx_wrbs += wrb_cnt; stats->be_tx_bytes += copied; + stats->be_tx_pkts += (gso_segs ? gso_segs : 1); if (stopped) stats->be_tx_stops++; } @@ -472,7 +470,8 @@ static netdev_tx_t be_xmit(struct sk_buff *skb, be_txq_notify(adapter, txq->id, wrb_cnt); - be_tx_stats_update(adapter, wrb_cnt, copied, stopped); + be_tx_stats_update(adapter, wrb_cnt, copied, + skb_shinfo(skb)->gso_segs, stopped); } else { txq->head = start; dev_kfree_skb_any(skb); @@ -578,13 +577,13 @@ static void be_set_multicast_list(struct net_device *netdev) /* Enable multicast promisc if num configured exceeds what we support */ if (netdev->flags & IFF_ALLMULTI || netdev_mc_count(netdev) > BE_MAX_MC) { - be_cmd_multicast_set(adapter, adapter->if_handle, NULL, 0, + be_cmd_multicast_set(adapter, adapter->if_handle, NULL, &adapter->mc_cmd_mem); goto done; } - be_cmd_multicast_set(adapter, adapter->if_handle, netdev->mc_list, - netdev_mc_count(netdev), &adapter->mc_cmd_mem); + be_cmd_multicast_set(adapter, adapter->if_handle, netdev, + &adapter->mc_cmd_mem); done: return; } @@ -619,6 +618,7 @@ static void be_rx_stats_update(struct be_adapter *adapter, stats->be_rx_compl++; stats->be_rx_frags += numfrags; stats->be_rx_bytes += pktsize; + stats->be_rx_pkts++; } static inline bool do_pkt_csum(struct be_eth_rx_compl *rxcp, bool cso) @@ -1128,6 +1128,9 @@ static void be_tx_compl_clean(struct be_adapter *adapter) struct be_queue_info *txq = &adapter->tx_obj.q; struct be_eth_tx_compl *txcp; u16 end_idx, cmpl = 0, timeo = 0; + struct sk_buff **sent_skbs = adapter->tx_obj.sent_skb_list; + struct sk_buff *sent_skb; + bool dummy_wrb; /* Wait for a max of 200ms for all the tx-completions to arrive. */ do { @@ -1151,6 +1154,15 @@ static void be_tx_compl_clean(struct be_adapter *adapter) if (atomic_read(&txq->used)) dev_err(&adapter->pdev->dev, "%d pending tx-completions\n", atomic_read(&txq->used)); + + /* free posted tx for which compls will never arrive */ + while (atomic_read(&txq->used)) { + sent_skb = sent_skbs[txq->tail]; + end_idx = txq->tail; + index_adv(&end_idx, + wrb_cnt_for_skb(sent_skb, &dummy_wrb) - 1, txq->len); + be_tx_compl_process(adapter, end_idx); + } } static void be_mcc_queues_destroy(struct be_adapter *adapter) diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c index ef7f77113e2..587f93cf03f 100644 --- a/drivers/net/bfin_mac.c +++ b/drivers/net/bfin_mac.c @@ -812,16 +812,14 @@ static void bfin_mac_timeout(struct net_device *dev) static void bfin_mac_multicast_hash(struct net_device *dev) { u32 emac_hashhi, emac_hashlo; - struct dev_mc_list *dmi = dev->mc_list; + struct dev_mc_list *dmi; char *addrs; - int i; u32 crc; emac_hashhi = emac_hashlo = 0; - for (i = 0; i < netdev_mc_count(dev); i++) { + netdev_for_each_mc_addr(dmi, dev) { addrs = dmi->dmi_addr; - dmi = dmi->next; /* skip non-multicast addresses */ if (!(*addrs & 1)) diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c index 189fa69c209..119468e7632 100644 --- a/drivers/net/bmac.c +++ b/drivers/net/bmac.c @@ -1000,7 +1000,7 @@ static void bmac_set_multicast(struct net_device *dev) rx_cfg = bmac_rx_on(dev, 0, 0); XXDEBUG(("bmac: multi disabled, rx_cfg=%#08x\n", rx_cfg)); } else { - for (dmi=dev->mc_list; dmi!=NULL; dmi=dmi->next) + netdev_for_each_mc_addr(dmi, dev) bmac_addhash(bp, dmi->dmi_addr); bmac_update_hash_table_mask(dev, bp); rx_cfg = bmac_rx_on(dev, 1, 0); @@ -1015,7 +1015,7 @@ static void bmac_set_multicast(struct net_device *dev) static void bmac_set_multicast(struct net_device *dev) { - struct dev_mc_list *dmi = dev->mc_list; + struct dev_mc_list *dmi; char *addrs; int i; unsigned short rx_cfg; @@ -1039,9 +1039,8 @@ static void bmac_set_multicast(struct net_device *dev) for(i = 0; i < 4; i++) hash_table[i] = 0; - for(i = 0; i < netdev_mc_count(dev); i++) { + netdev_for_each_mc_addr(dmi, dev) { addrs = dmi->dmi_addr; - dmi = dmi->next; if(!(*addrs & 1)) continue; diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index a6cc9d02e58..d3f739a295d 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -3552,9 +3552,7 @@ bnx2_set_rx_mode(struct net_device *dev) memset(mc_filter, 0, 4 * NUM_MC_HASH_REGISTERS); - for (i = 0, mclist = dev->mc_list; mclist && i < netdev_mc_count(dev); - i++, mclist = mclist->next) { - + netdev_for_each_mc_addr(mclist, dev) { crc = ether_crc_le(ETH_ALEN, mclist->dmi_addr); bit = crc & 0xff; regidx = (bit & 0xe0) >> 5; diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 7f9db47e8cc..5adf2a05246 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -11483,10 +11483,8 @@ static void bnx2x_set_rx_mode(struct net_device *dev) struct mac_configuration_cmd *config = bnx2x_sp(bp, mcast_config); - for (i = 0, mclist = dev->mc_list; - mclist && (i < netdev_mc_count(dev)); - i++, mclist = mclist->next) { - + i = 0; + netdev_for_each_mc_addr(mclist, dev) { config->config_table[i]. cam_entry.msb_mac_addr = swab16(*(u16 *)&mclist->dmi_addr[0]); @@ -11514,6 +11512,7 @@ static void bnx2x_set_rx_mode(struct net_device *dev) cam_entry.middle_mac_addr, config->config_table[i]. cam_entry.lsb_mac_addr); + i++; } old = config->hdr.length; if (old > i) { @@ -11555,10 +11554,7 @@ static void bnx2x_set_rx_mode(struct net_device *dev) memset(mc_filter, 0, 4 * MC_HASH_SIZE); - for (i = 0, mclist = dev->mc_list; - mclist && (i < netdev_mc_count(dev)); - i++, mclist = mclist->next) { - + netdev_for_each_mc_addr(mclist, dev) { DP(NETIF_MSG_IFUP, "Adding mcast MAC: %pM\n", mclist->dmi_addr); diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c index 8332e242b0b..b861cd56107 100644 --- a/drivers/net/can/ti_hecc.c +++ b/drivers/net/can/ti_hecc.c @@ -826,7 +826,6 @@ static int ti_hecc_open(struct net_device *ndev) return err; } - clk_enable(priv->clk); ti_hecc_start(ndev); napi_enable(&priv->napi); netif_start_queue(ndev); @@ -842,7 +841,6 @@ static int ti_hecc_close(struct net_device *ndev) napi_disable(&priv->napi); ti_hecc_stop(ndev); free_irq(ndev->irq, ndev); - clk_disable(priv->clk); close_candev(ndev); return 0; @@ -928,6 +926,7 @@ static int ti_hecc_probe(struct platform_device *pdev) netif_napi_add(ndev, &priv->napi, ti_hecc_rx_poll, HECC_DEF_NAPI_WEIGHT); + clk_enable(priv->clk); err = register_candev(ndev); if (err) { dev_err(&pdev->dev, "register_candev() failed\n"); @@ -956,6 +955,7 @@ static int __devexit ti_hecc_remove(struct platform_device *pdev) struct net_device *ndev = platform_get_drvdata(pdev); struct ti_hecc_priv *priv = netdev_priv(ndev); + clk_disable(priv->clk); clk_put(priv->clk); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); iounmap(priv->base); @@ -967,6 +967,48 @@ static int __devexit ti_hecc_remove(struct platform_device *pdev) return 0; } + +#ifdef CONFIG_PM +static int ti_hecc_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct net_device *dev = platform_get_drvdata(pdev); + struct ti_hecc_priv *priv = netdev_priv(dev); + + if (netif_running(dev)) { + netif_stop_queue(dev); + netif_device_detach(dev); + } + + hecc_set_bit(priv, HECC_CANMC, HECC_CANMC_PDR); + priv->can.state = CAN_STATE_SLEEPING; + + clk_disable(priv->clk); + + return 0; +} + +static int ti_hecc_resume(struct platform_device *pdev) +{ + struct net_device *dev = platform_get_drvdata(pdev); + struct ti_hecc_priv *priv = netdev_priv(dev); + + clk_enable(priv->clk); + + hecc_clear_bit(priv, HECC_CANMC, HECC_CANMC_PDR); + priv->can.state = CAN_STATE_ERROR_ACTIVE; + + if (netif_running(dev)) { + netif_device_attach(dev); + netif_start_queue(dev); + } + + return 0; +} +#else +#define ti_hecc_suspend NULL +#define ti_hecc_resume NULL +#endif + /* TI HECC netdevice driver: platform driver structure */ static struct platform_driver ti_hecc_driver = { .driver = { @@ -975,6 +1017,8 @@ static struct platform_driver ti_hecc_driver = { }, .probe = ti_hecc_probe, .remove = __devexit_p(ti_hecc_remove), + .suspend = ti_hecc_suspend, + .resume = ti_hecc_resume, }; static int __init ti_hecc_init_driver(void) @@ -982,14 +1026,15 @@ static int __init ti_hecc_init_driver(void) printk(KERN_INFO DRV_DESC "\n"); return platform_driver_register(&ti_hecc_driver); } -module_init(ti_hecc_init_driver); static void __exit ti_hecc_exit_driver(void) { printk(KERN_INFO DRV_DESC " unloaded\n"); platform_driver_unregister(&ti_hecc_driver); } + module_exit(ti_hecc_exit_driver); +module_init(ti_hecc_init_driver); MODULE_AUTHOR("Anant Gole <anantgole@ti.com>"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index d1e03b5984c..3f5db83c7cb 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c @@ -965,10 +965,9 @@ static void emac_dev_mcast_set(struct net_device *ndev) mbp_enable = (mbp_enable | EMAC_MBP_RXMCAST); emac_add_mcast(priv, EMAC_ALL_MULTI_CLR, NULL); /* program multicast address list into EMAC hardware */ - for (mc_ptr = ndev->mc_list; mc_ptr; - mc_ptr = mc_ptr->next) { + netdev_for_each_mc_addr(mc_ptr, ndev) { emac_add_mcast(priv, EMAC_MULTICAST_ADD, - (u8 *)mc_ptr->dmi_addr); + (u8 *) mc_ptr->dmi_addr); } } else { mbp_enable = (mbp_enable & ~EMAC_MBP_RXMCAST); diff --git a/drivers/net/depca.c b/drivers/net/depca.c index 64a569bc92a..744c1928dfc 100644 --- a/drivers/net/depca.c +++ b/drivers/net/depca.c @@ -1272,7 +1272,7 @@ static void set_multicast_list(struct net_device *dev) static void SetMulticastFilter(struct net_device *dev) { struct depca_private *lp = netdev_priv(dev); - struct dev_mc_list *dmi = dev->mc_list; + struct dev_mc_list *dmi; char *addrs; int i, j, bit, byte; u16 hashcode; diff --git a/drivers/net/e100.c b/drivers/net/e100.c index e8c0e823a06..a26ccab057d 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -1537,14 +1537,18 @@ static int e100_hw_init(struct nic *nic) static void e100_multi(struct nic *nic, struct cb *cb, struct sk_buff *skb) { struct net_device *netdev = nic->netdev; - struct dev_mc_list *list = netdev->mc_list; + struct dev_mc_list *list; u16 i, count = min(netdev_mc_count(netdev), E100_MAX_MULTICAST_ADDRS); cb->command = cpu_to_le16(cb_multi); cb->u.multi.count = cpu_to_le16(count * ETH_ALEN); - for (i = 0; list && i < count; i++, list = list->next) - memcpy(&cb->u.multi.addr[i*ETH_ALEN], &list->dmi_addr, + i = 0; + netdev_for_each_mc_addr(list, netdev) { + if (i == count) + break; + memcpy(&cb->u.multi.addr[i++ * ETH_ALEN], &list->dmi_addr, ETH_ALEN); + } } static void e100_set_multicast_list(struct net_device *netdev) diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 3b14dd718ab..319c2b5281e 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -2161,29 +2161,25 @@ static void e1000_set_rx_mode(struct net_device *netdev) WARN_ON(i == rar_entries); - mc_ptr = netdev->mc_list; - - for (; i < rar_entries; i++) { - if (mc_ptr) { - e1000_rar_set(hw, mc_ptr->da_addr, i); - mc_ptr = mc_ptr->next; + netdev_for_each_mc_addr(mc_ptr, netdev) { + if (i == rar_entries) { + /* load any remaining addresses into the hash table */ + u32 hash_reg, hash_bit, mta; + hash_value = e1000_hash_mc_addr(hw, mc_ptr->da_addr); + hash_reg = (hash_value >> 5) & 0x7F; + hash_bit = hash_value & 0x1F; + mta = (1 << hash_bit); + mcarray[hash_reg] |= mta; } else { - E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0); - E1000_WRITE_FLUSH(); - E1000_WRITE_REG_ARRAY(hw, RA, (i << 1) + 1, 0); - E1000_WRITE_FLUSH(); + e1000_rar_set(hw, mc_ptr->da_addr, i++); } } - /* load any remaining addresses into the hash table */ - - for (; mc_ptr; mc_ptr = mc_ptr->next) { - u32 hash_reg, hash_bit, mta; - hash_value = e1000_hash_mc_addr(hw, mc_ptr->da_addr); - hash_reg = (hash_value >> 5) & 0x7F; - hash_bit = hash_value & 0x1F; - mta = (1 << hash_bit); - mcarray[hash_reg] |= mta; + for (; i < rar_entries; i++) { + E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0); + E1000_WRITE_FLUSH(); + E1000_WRITE_REG_ARRAY(hw, RA, (i << 1) + 1, 0); + E1000_WRITE_FLUSH(); } /* write the hash table completely, write from bottom to avoid diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c index 488bc13cc7e..1b05bdf62c3 100644 --- a/drivers/net/eepro.c +++ b/drivers/net/eepro.c @@ -1287,8 +1287,8 @@ set_multicast_list(struct net_device *dev) struct eepro_local *lp = netdev_priv(dev); short ioaddr = dev->base_addr; unsigned short mode; - struct dev_mc_list *dmi=dev->mc_list; - int mc_count = mc_count; + struct dev_mc_list *dmi; + int mc_count = netdev_mc_count(dev); if (dev->flags&(IFF_ALLMULTI|IFF_PROMISC) || mc_count > 63) { @@ -1332,10 +1332,8 @@ set_multicast_list(struct net_device *dev) outw(0, ioaddr + IO_PORT); outw(6 * (mc_count + 1), ioaddr + IO_PORT); - for (i = 0; i < mc_count; i++) - { - eaddrs=(unsigned short *)dmi->dmi_addr; - dmi=dmi->next; + netdev_for_each_mc_addr(dmi, dev) { + eaddrs = (unsigned short *) dmi->dmi_addr; outw(*eaddrs++, ioaddr + IO_PORT); outw(*eaddrs++, ioaddr + IO_PORT); outw(*eaddrs++, ioaddr + IO_PORT); diff --git a/drivers/net/eexpress.c b/drivers/net/eexpress.c index d804ff18eda..7013dc8a6cb 100644 --- a/drivers/net/eexpress.c +++ b/drivers/net/eexpress.c @@ -1588,23 +1588,19 @@ static void eexp_setup_filter(struct net_device *dev) outw(CONF_NR_MULTICAST & ~31, ioaddr+SM_PTR); outw(6*count, ioaddr+SHADOW(CONF_NR_MULTICAST)); - for (i = 0, dmi = dev->mc_list; i < count; i++, dmi = dmi->next) { - unsigned short *data; - if (!dmi) { - printk(KERN_INFO "%s: too few multicast addresses\n", dev->name); + i = 0; + netdev_for_each_mc_addr(dmi, dev) { + unsigned short *data = (unsigned short *) dmi->dmi_addr; + + if (i == count) break; - } - if (dmi->dmi_addrlen != ETH_ALEN) { - printk(KERN_INFO "%s: invalid multicast address length given.\n", dev->name); - continue; - } - data = (unsigned short *)dmi->dmi_addr; outw((CONF_MULTICAST+(6*i)) & ~31, ioaddr+SM_PTR); outw(data[0], ioaddr+SHADOW(CONF_MULTICAST+(6*i))); outw((CONF_MULTICAST+(6*i)+2) & ~31, ioaddr+SM_PTR); outw(data[1], ioaddr+SHADOW(CONF_MULTICAST+(6*i)+2)); outw((CONF_MULTICAST+(6*i)+4) & ~31, ioaddr+SM_PTR); outw(data[2], ioaddr+SHADOW(CONF_MULTICAST+(6*i)+4)); + i++; } } diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 99e4f8360d2..b004eaba3d7 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -1967,7 +1967,7 @@ static void ehea_set_multicast_list(struct net_device *dev) { struct ehea_port *port = netdev_priv(dev); struct dev_mc_list *k_mcl_entry; - int ret, i; + int ret; if (dev->flags & IFF_PROMISC) { ehea_promiscuous(dev, 1); @@ -1997,8 +1997,7 @@ static void ehea_set_multicast_list(struct net_device *dev) goto out; } - for (i = 0, k_mcl_entry = dev->mc_list; i < netdev_mc_count(dev); i++, - k_mcl_entry = k_mcl_entry->next) + netdev_for_each_mc_addr(k_mcl_entry, dev) ehea_add_multicast_entry(port, k_mcl_entry->dmi_addr); } diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 94749ebaaea..cf098bb636b 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -822,7 +822,7 @@ static int enic_set_mac_addr(struct net_device *netdev, char *addr) static void enic_set_multicast_list(struct net_device *netdev) { struct enic *enic = netdev_priv(netdev); - struct dev_mc_list *list = netdev->mc_list; + struct dev_mc_list *list; int directed = 1; int multicast = (netdev->flags & IFF_MULTICAST) ? 1 : 0; int broadcast = (netdev->flags & IFF_BROADCAST) ? 1 : 0; @@ -851,9 +851,11 @@ static void enic_set_multicast_list(struct net_device *netdev) * look for changes to add/del. */ - for (i = 0; list && i < mc_count; i++) { - memcpy(mc_addr[i], list->dmi_addr, ETH_ALEN); - list = list->next; + i = 0; + netdev_for_each_mc_addr(list, netdev) { + if (i == mc_count) + break; + memcpy(mc_addr[i++], list->dmi_addr, ETH_ALEN); } for (i = 0; i < enic->mc_count; i++) { diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c index 31a3adb6556..39c271b6be4 100644 --- a/drivers/net/epic100.c +++ b/drivers/net/epic100.c @@ -1403,8 +1403,7 @@ static void set_rx_mode(struct net_device *dev) struct dev_mc_list *mclist; memset(mc_filter, 0, sizeof(mc_filter)); - for (i = 0, mclist = dev->mc_list; mclist && i < netdev_mc_count(dev); - i++, mclist = mclist->next) { + netdev_for_each_mc_addr(mclist, dev) { unsigned int bit_nr = ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x3f; mc_filter[bit_nr >> 3] |= (1 << bit_nr); diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c index f9d5ca07874..209742304e2 100644 --- a/drivers/net/ethoc.c +++ b/drivers/net/ethoc.c @@ -755,7 +755,7 @@ static void ethoc_set_multicast_list(struct net_device *dev) { struct ethoc *priv = netdev_priv(dev); u32 mode = ethoc_read(priv, MODER); - struct dev_mc_list *mc = NULL; + struct dev_mc_list *mc; u32 hash[2] = { 0, 0 }; /* set loopback mode if requested */ @@ -783,8 +783,8 @@ static void ethoc_set_multicast_list(struct net_device *dev) hash[0] = 0xffffffff; hash[1] = 0xffffffff; } else { - for (mc = dev->mc_list; mc; mc = mc->next) { - u32 crc = ether_crc(mc->dmi_addrlen, mc->dmi_addr); + netdev_for_each_mc_addr(mc, dev) { + u32 crc = ether_crc(ETH_ALEN, mc->dmi_addr); int bit = (crc >> 26) & 0x3f; hash[bit >> 5] |= 1 << (bit & 0x1f); } diff --git a/drivers/net/ewrk3.c b/drivers/net/ewrk3.c index 96817a872f4..91e59f3a9d6 100644 --- a/drivers/net/ewrk3.c +++ b/drivers/net/ewrk3.c @@ -1169,7 +1169,7 @@ static void set_multicast_list(struct net_device *dev) static void SetMulticastFilter(struct net_device *dev) { struct ewrk3_private *lp = netdev_priv(dev); - struct dev_mc_list *dmi = dev->mc_list; + struct dev_mc_list *dmi; u_long iobase = dev->base_addr; int i; char *addrs, bit, byte; @@ -1213,9 +1213,8 @@ static void SetMulticastFilter(struct net_device *dev) } /* Update table */ - for (i = 0; i < netdev_mc_count(dev); i++) { /* for each address in the list */ + netdev_for_each_mc_addr(dmi, dev) { addrs = dmi->dmi_addr; - dmi = dmi->next; if ((*addrs & 0x01) == 1) { /* multicast address? */ crc = ether_crc_le(ETH_ALEN, addrs); hashcode = crc & ((1 << 9) - 1); /* hashcode is 9 LSb of CRC */ diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c index f95b5ff0587..9d5ad08a119 100644 --- a/drivers/net/fealnx.c +++ b/drivers/net/fealnx.c @@ -1793,11 +1793,9 @@ static void __set_rx_mode(struct net_device *dev) rx_mode = CR_W_AB | CR_W_AM; } else { struct dev_mc_list *mclist; - int i; memset(mc_filter, 0, sizeof(mc_filter)); - for (i = 0, mclist = dev->mc_list; mclist && i < netdev_mc_count(dev); - i++, mclist = mclist->next) { + netdev_for_each_mc_addr(mclist, dev) { unsigned int bit; bit = (ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26) ^ 0x3F; mc_filter[bit >> 5] |= (1 << bit); diff --git a/drivers/net/fec.c b/drivers/net/fec.c index d9d14c83f51..9f98c1c4a34 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -1575,7 +1575,7 @@ static void set_multicast_list(struct net_device *dev) { struct fec_enet_private *fep = netdev_priv(dev); struct dev_mc_list *dmi; - unsigned int i, j, bit, data, crc, tmp; + unsigned int i, bit, data, crc, tmp; unsigned char hash; if (dev->flags & IFF_PROMISC) { @@ -1604,9 +1604,7 @@ static void set_multicast_list(struct net_device *dev) writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH); writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW); - dmi = dev->mc_list; - - for (j = 0; j < netdev_mc_count(dev); j++, dmi = dmi->next) { + netdev_for_each_mc_addr(dmi, dev) { /* Only support group multicast for now */ if (!(dmi->dmi_addr[0] & 1)) continue; diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c index 10903b75802..0dbd7219bbd 100644 --- a/drivers/net/fec_mpc52xx.c +++ b/drivers/net/fec_mpc52xx.c @@ -575,19 +575,16 @@ static void mpc52xx_fec_set_multicast_list(struct net_device *dev) out_be32(&fec->gaddr2, 0xffffffff); } else { u32 crc; - int i; struct dev_mc_list *dmi; u32 gaddr1 = 0x00000000; u32 gaddr2 = 0x00000000; - dmi = dev->mc_list; - for (i=0; i<netdev_mc_count(dev); i++) { + netdev_for_each_mc_addr(dmi, dev) { crc = ether_crc_le(6, dmi->dmi_addr) >> 26; if (crc >= 32) gaddr1 |= 1 << (crc-32); else gaddr2 |= 1 << crc; - dmi = dmi->next; } out_be32(&fec->gaddr1, gaddr1); out_be32(&fec->gaddr2, gaddr2); diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 3eb713b014f..ca05e566202 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -3095,7 +3095,7 @@ static void nv_set_multicast(struct net_device *dev) } else { pff |= NVREG_PFF_MYADDR; - if (dev->flags & IFF_ALLMULTI || dev->mc_list) { + if (dev->flags & IFF_ALLMULTI || !netdev_mc_empty(dev)) { u32 alwaysOff[2]; u32 alwaysOn[2]; @@ -3105,8 +3105,7 @@ static void nv_set_multicast(struct net_device *dev) } else { struct dev_mc_list *walk; - walk = dev->mc_list; - while (walk != NULL) { + netdev_for_each_mc_addr(walk, dev) { u32 a, b; a = le32_to_cpu(*(__le32 *) walk->dmi_addr); b = le16_to_cpu(*(__le16 *) (&walk->dmi_addr[4])); @@ -3114,7 +3113,6 @@ static void nv_set_multicast(struct net_device *dev) alwaysOff[0] &= ~a; alwaysOn[1] &= b; alwaysOff[1] &= ~b; - walk = walk->next; } } addr[0] = alwaysOn[0]; diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c index 482f27d5f7d..a761d31e3d6 100644 --- a/drivers/net/fs_enet/mac-fcc.c +++ b/drivers/net/fs_enet/mac-fcc.c @@ -235,7 +235,7 @@ static void set_multicast_list(struct net_device *dev) if ((dev->flags & IFF_PROMISC) == 0) { set_multicast_start(dev); - for (pmc = dev->mc_list; pmc != NULL; pmc = pmc->next) + netdev_for_each_mc_addr(pmc, dev) set_multicast_one(dev, pmc->dmi_addr); set_multicast_finish(dev); } else diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c index ddf13ef8ac8..ca806d1ab3f 100644 --- a/drivers/net/fs_enet/mac-fec.c +++ b/drivers/net/fs_enet/mac-fec.c @@ -236,7 +236,7 @@ static void set_multicast_list(struct net_device *dev) if ((dev->flags & IFF_PROMISC) == 0) { set_multicast_start(dev); - for (pmc = dev->mc_list; pmc != NULL; pmc = pmc->next) + netdev_for_each_mc_addr(pmc, dev) set_multicast_one(dev, pmc->dmi_addr); set_multicast_finish(dev); } else diff --git a/drivers/net/fs_enet/mac-scc.c b/drivers/net/fs_enet/mac-scc.c index 141dbc91e5e..5bfc99b9475 100644 --- a/drivers/net/fs_enet/mac-scc.c +++ b/drivers/net/fs_enet/mac-scc.c @@ -228,7 +228,7 @@ static void set_multicast_list(struct net_device *dev) if ((dev->flags & IFF_PROMISC) == 0) { set_multicast_start(dev); - for (pmc = dev->mc_list; pmc != NULL; pmc = pmc->next) + netdev_for_each_mc_addr(pmc, dev) set_multicast_one(dev, pmc->dmi_addr); set_multicast_finish(dev); } else diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index c9be090485d..6aa526ee909 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -2867,7 +2867,7 @@ static void gfar_set_multi(struct net_device *dev) return; /* Parse the list, and set the appropriate bits */ - for(mc_ptr = dev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) { + netdev_for_each_mc_addr(mc_ptr, dev) { if (idx < em_num) { gfar_set_mac_for_addr(dev, idx, mc_ptr->dmi_addr); diff --git a/drivers/net/greth.c b/drivers/net/greth.c index 457da1c2383..d2032339f6d 100644 --- a/drivers/net/greth.c +++ b/drivers/net/greth.c @@ -965,7 +965,7 @@ static int greth_set_mac_add(struct net_device *dev, void *p) struct greth_private *greth; struct greth_regs *regs; - greth = (struct greth_private *) netdev_priv(dev); + greth = netdev_priv(dev); regs = (struct greth_regs *) greth->regs; if (!is_valid_ether_addr(addr->sa_data)) @@ -988,20 +988,14 @@ static u32 greth_hash_get_index(__u8 *addr) static void greth_set_hash_filter(struct net_device *dev) { struct dev_mc_list *curr; - struct greth_private *greth = (struct greth_private *) netdev_priv(dev); + struct greth_private *greth = netdev_priv(dev); struct greth_regs *regs = (struct greth_regs *) greth->regs; u32 mc_filter[2]; - unsigned int i, bitnr; + unsigned int bitnr; mc_filter[0] = mc_filter[1] = 0; - curr = dev->mc_list; - - for (i = 0; i < dev->mc_count; i++, curr = curr->next) { - - if (!curr) - break; /* unexpected end of list */ - + netdev_for_each_mc_addr(curr, dev) { bitnr = greth_hash_get_index(curr->dmi_addr); mc_filter[bitnr >> 5] |= 1 << (bitnr & 31); } @@ -1031,7 +1025,7 @@ static void greth_set_multicast_list(struct net_device *dev) return; } - if (dev->mc_count == 0) { + if (netdev_mc_empty(dev)) { cfg &= ~GRETH_CTRL_MCEN; GRETH_REGSAVE(regs->control, cfg); return; @@ -1160,6 +1154,7 @@ static struct net_device_ops greth_netdev_ops = { .ndo_stop = greth_close, .ndo_start_xmit = greth_start_xmit, .ndo_set_mac_address = greth_set_mac_add, + .ndo_validate_addr = eth_validate_addr, }; static inline int wait_for_mdio(struct greth_private *greth) @@ -1275,28 +1270,26 @@ static int greth_mdio_probe(struct net_device *dev) { struct greth_private *greth = netdev_priv(dev); struct phy_device *phy = NULL; - u32 interface; - int i; + int ret; /* Find the first PHY */ - for (i = 0; i < PHY_MAX_ADDR; i++) { - if (greth->mdio->phy_map[i]) { - phy = greth->mdio->phy_map[i]; - break; - } - } + phy = phy_find_first(greth->mdio); + if (!phy) { if (netif_msg_probe(greth)) dev_err(&dev->dev, "no PHY found\n"); return -ENXIO; } - if (greth->gbit_mac) - interface = PHY_INTERFACE_MODE_GMII; - else - interface = PHY_INTERFACE_MODE_MII; - - phy = phy_connect(dev, dev_name(&phy->dev), &greth_link_change, 0, interface); + ret = phy_connect_direct(dev, phy, &greth_link_change, + 0, greth->gbit_mac ? + PHY_INTERFACE_MODE_GMII : + PHY_INTERFACE_MODE_MII); + if (ret) { + if (netif_msg_ifup(greth)) + dev_err(&dev->dev, "could not attach to PHY\n"); + return ret; + } if (greth->gbit_mac) phy->supported &= PHY_GBIT_FEATURES; @@ -1305,12 +1298,6 @@ static int greth_mdio_probe(struct net_device *dev) phy->advertising = phy->supported; - if (IS_ERR(phy)) { - if (netif_msg_ifup(greth)) - dev_err(&dev->dev, "could not attach to PHY\n"); - return PTR_ERR(phy); - } - greth->link = 0; greth->speed = 0; greth->duplex = -1; diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c index c70b147b4fe..373546dd083 100644 --- a/drivers/net/hamachi.c +++ b/drivers/net/hamachi.c @@ -1859,12 +1859,13 @@ static void set_rx_mode(struct net_device *dev) writew(0x000B, ioaddr + AddrMode); } else if (!netdev_mc_empty(dev)) { /* Must use the CAM filter. */ struct dev_mc_list *mclist; - int i; - for (i = 0, mclist = dev->mc_list; mclist && i < netdev_mc_count(dev); - i++, mclist = mclist->next) { + int i = 0; + + netdev_for_each_mc_addr(mclist, dev) { writel(*(u32*)(mclist->dmi_addr), ioaddr + 0x100 + i*8); writel(0x20000 | (*(u16*)&mclist->dmi_addr[4]), ioaddr + 0x104 + i*8); + i++; } /* Clear remaining entries. */ for (; i < 64; i++) diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c index debac1bc679..b766a69bf0c 100644 --- a/drivers/net/hp100.c +++ b/drivers/net/hp100.c @@ -2098,7 +2098,7 @@ static void hp100_set_multicast_list(struct net_device *dev) /* set hash filter to receive all multicast packets */ memset(&lp->hash_bytes, 0xff, 8); } else { - int i, j, idx; + int i, idx; u_char *addrs; struct dev_mc_list *dmi; @@ -2107,14 +2107,14 @@ static void hp100_set_multicast_list(struct net_device *dev) printk("hp100: %s: computing hash filter - mc_count = %i\n", dev->name, netdev_mc_count(dev)); #endif - for (i = 0, dmi = dev->mc_list; i < netdev_mc_count(dev); i++, dmi = dmi->next) { + netdev_for_each_mc_addr(dmi, dev) { addrs = dmi->dmi_addr; if ((*addrs & 0x01) == 0x01) { /* multicast address? */ #ifdef HP100_DEBUG printk("hp100: %s: multicast = %pM, ", dev->name, addrs); #endif - for (j = idx = 0; j < 6; j++) { + for (i = idx = 0; i < 6; i++) { idx ^= *addrs++ & 0x3f; printk(":%02x:", idx); } diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index b75d27e82a3..fb0ac6d7c04 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c @@ -395,7 +395,7 @@ static void emac_hash_mc(struct emac_instance *dev) memset(gaht_temp, 0, sizeof (gaht_temp)); - for (dmi = dev->ndev->mc_list; dmi; dmi = dmi->next) { + netdev_for_each_mc_addr(dmi, dev->ndev) { int slot, reg, mask; DBG2(dev, "mc %pM" NL, dmi->dmi_addr); diff --git a/drivers/net/ibmlana.c b/drivers/net/ibmlana.c index 052c74091d9..b5d0f4e973f 100644 --- a/drivers/net/ibmlana.c +++ b/drivers/net/ibmlana.c @@ -420,7 +420,7 @@ static void InitBoard(struct net_device *dev) /* start putting the multicast addresses into the CAM list. Stop if it is full. */ - for (mcptr = dev->mc_list; mcptr != NULL; mcptr = mcptr->next) { + netdev_for_each_mc_addr(mcptr, dev) { putcam(cams, &camcnt, mcptr->dmi_addr); if (camcnt == 16) break; diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 41b9c0efcbd..f2b93796695 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -1072,8 +1072,7 @@ static void ibmveth_set_multicast_list(struct net_device *netdev) ibmveth_error_printk("h_multicast_ctrl rc=%ld when entering promisc mode\n", lpar_rc); } } else { - struct dev_mc_list *mclist = netdev->mc_list; - int i; + struct dev_mc_list *mclist; /* clear the filter table & disable filtering */ lpar_rc = h_multicast_ctrl(adapter->vdev->unit_address, IbmVethMcastEnableRecv | @@ -1084,7 +1083,7 @@ static void ibmveth_set_multicast_list(struct net_device *netdev) ibmveth_error_printk("h_multicast_ctrl rc=%ld when attempting to clear filter table\n", lpar_rc); } /* add the addresses to the filter table */ - for(i = 0; i < netdev_mc_count(netdev); ++i, mclist = mclist->next) { + netdev_for_each_mc_addr(mclist, netdev) { // add the multicast address to the filter table unsigned long mcast_addr = 0; memcpy(((char *)&mcast_addr)+2, mclist->dmi_addr, 6); diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index f588e49c65f..583a21c1def 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -2877,7 +2877,7 @@ static int igb_write_mc_addr_list(struct net_device *netdev) { struct igb_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; - struct dev_mc_list *mc_ptr = netdev->mc_list; + struct dev_mc_list *mc_ptr; u8 *mta_list; int i; @@ -2893,14 +2893,10 @@ static int igb_write_mc_addr_list(struct net_device *netdev) return -ENOMEM; /* The shared function expects a packed array of only addresses. */ - mc_ptr = netdev->mc_list; + i = 0; + netdev_for_each_mc_addr(mc_ptr, netdev) + memcpy(mta_list + (i++ * ETH_ALEN), mc_ptr->dmi_addr, ETH_ALEN); - for (i = 0; i < netdev_mc_count(netdev); i++) { - if (!mc_ptr) - break; - memcpy(mta_list + (i*ETH_ALEN), mc_ptr->dmi_addr, ETH_ALEN); - mc_ptr = mc_ptr->next; - } igb_update_mc_addr_list(hw, mta_list, i); kfree(mta_list); diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c index 6029c400f2b..a77afd8a14b 100644 --- a/drivers/net/igbvf/netdev.c +++ b/drivers/net/igbvf/netdev.c @@ -1413,15 +1413,9 @@ static void igbvf_set_multi(struct net_device *netdev) } /* prepare a packed array of only addresses. */ - mc_ptr = netdev->mc_list; - - for (i = 0; i < netdev_mc_count(netdev); i++) { - if (!mc_ptr) - break; - memcpy(mta_list + (i*ETH_ALEN), mc_ptr->dmi_addr, - ETH_ALEN); - mc_ptr = mc_ptr->next; - } + i = 0; + netdev_for_each_mc_addr(mc_ptr, netdev) + memcpy(mta_list + (i++ * ETH_ALEN), mc_ptr->dmi_addr, ETH_ALEN); hw->mac.ops.update_mc_addr_list(hw, mta_list, i, 0, 0); kfree(mta_list); diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c index 0bd5fef22d4..70871b9b045 100644 --- a/drivers/net/ioc3-eth.c +++ b/drivers/net/ioc3-eth.c @@ -1664,11 +1664,10 @@ static int ioc3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) static void ioc3_set_multicast_list(struct net_device *dev) { - struct dev_mc_list *dmi = dev->mc_list; + struct dev_mc_list *dmi; struct ioc3_private *ip = netdev_priv(dev); struct ioc3 *ioc3 = ip->regs; u64 ehar = 0; - int i; netif_stop_queue(dev); /* Lock out others. */ @@ -1689,9 +1688,8 @@ static void ioc3_set_multicast_list(struct net_device *dev) ip->ehar_h = 0xffffffff; ip->ehar_l = 0xffffffff; } else { - for (i = 0; i < netdev_mc_count(dev); i++) { + netdev_for_each_mc_addr(dmi, dev) { char *addr = dmi->dmi_addr; - dmi = dmi->next; if (!(*addr & 1)) continue; diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c index 3ca49e348c9..150415e83f6 100644 --- a/drivers/net/ipg.c +++ b/drivers/net/ipg.c @@ -608,8 +608,7 @@ static void ipg_nic_set_multicast_list(struct net_device *dev) hashtable[1] = 0x00000000; /* Cycle through all multicast addresses to filter. */ - for (mc_list_ptr = dev->mc_list; - mc_list_ptr != NULL; mc_list_ptr = mc_list_ptr->next) { + netdev_for_each_mc_addr(mc_list_ptr, dev) { /* Calculate CRC result for each multicast address. */ hashindex = crc32_le(0xffffffff, mc_list_ptr->dmi_addr, ETH_ALEN); diff --git a/drivers/net/isa-skeleton.c b/drivers/net/isa-skeleton.c index bb4a3cda6e4..d09e4d3a15a 100644 --- a/drivers/net/isa-skeleton.c +++ b/drivers/net/isa-skeleton.c @@ -666,7 +666,7 @@ set_multicast_list(struct net_device *dev) else if (!netdev_mc_empty(dev)) { /* Walk the address list, and load the filter */ - hardware_set_filter(dev->mc_list); + hardware_set_filter(dev); outw(MULTICAST, ioaddr); } diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index ff015e15f5d..966de5d6952 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c @@ -961,15 +961,14 @@ static void veth_set_multicast_list(struct net_device *dev) (netdev_mc_count(dev) > VETH_MAX_MCAST)) { port->promiscuous = 1; } else { - struct dev_mc_list *dmi = dev->mc_list; - int i; + struct dev_mc_list *dmi; port->promiscuous = 0; /* Update table */ port->num_mcast = 0; - for (i = 0; i < netdev_mc_count(dev); i++) { + netdev_for_each_mc_addr(dmi, dev) { u8 *addr = dmi->dmi_addr; u64 xaddr = 0; @@ -978,7 +977,6 @@ static void veth_set_multicast_list(struct net_device *dev) port->mcast_addr[port->num_mcast] = xaddr; port->num_mcast++; } - dmi = dmi->next; } } diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index 93d018505eb..c9fef65cb98 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -1088,10 +1088,9 @@ ixgb_set_multi(struct net_device *netdev) IXGB_WRITE_REG(hw, RCTL, rctl); - for (i = 0, mc_ptr = netdev->mc_list; - mc_ptr; - i++, mc_ptr = mc_ptr->next) - memcpy(&mta[i * IXGB_ETH_LENGTH_OF_ADDRESS], + i = 0; + netdev_for_each_mc_addr(mc_ptr, netdev) + memcpy(&mta[i++ * IXGB_ETH_LENGTH_OF_ADDRESS], mc_ptr->dmi_addr, IXGB_ETH_LENGTH_OF_ADDRESS); ixgb_mc_addr_list_update(hw, mta, netdev_mc_count(netdev), 0); diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 43a8de3dc4d..330879004ea 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -849,6 +849,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, break; (*work_done)++; + rmb(); /* read descriptor and rx_buffer_info after status DD */ if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) { hdr_info = le16_to_cpu(ixgbe_get_hdr_info(rx_desc)); len = (hdr_info & IXGBE_RXDADV_HDRBUFLEN_MASK) >> diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index fe7656bf68c..55ceae09738 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -17,6 +17,7 @@ #include <net/net_namespace.h> #include <net/rtnetlink.h> #include <net/sock.h> +#include <linux/virtio_net.h> /* * A macvtap queue is the central object of this driver, it connects @@ -37,6 +38,7 @@ struct macvtap_queue { struct socket sock; struct macvlan_dev *vlan; struct file *file; + unsigned int flags; }; static struct proto macvtap_proto = { @@ -58,32 +60,23 @@ static unsigned int macvtap_major; static struct class *macvtap_class; static struct cdev macvtap_cdev; +static const struct proto_ops macvtap_socket_ops; + /* * RCU usage: - * The macvtap_queue is referenced both from the chardev struct file - * and from the struct macvlan_dev using rcu_read_lock. - * - * We never actually update the contents of a macvtap_queue atomically - * with RCU but it is used for race-free destruction of a queue when - * either the file or the macvlan_dev goes away. Pointers back to - * the dev and the file are implicitly valid as long as the queue - * exists. - * - * The callbacks from macvlan are always done with rcu_read_lock held - * already. For calls from file_operations, we use the rcu_read_lock_bh - * to get a reference count on the socket and the device. + * The macvtap_queue and the macvlan_dev are loosely coupled, the + * pointers from one to the other can only be read while rcu_read_lock + * or macvtap_lock is held. * - * When destroying a queue, we remove the pointers from the file and - * from the dev and then synchronize_rcu to make sure no thread is - * still using the queue. There may still be references to the struct - * sock inside of the queue from outbound SKBs, but these never - * reference back to the file or the dev. The data structure is freed - * through __sk_free when both our references and any pending SKBs - * are gone. + * Both the file and the macvlan_dev hold a reference on the macvtap_queue + * through sock_hold(&q->sk). When the macvlan_dev goes away first, + * q->vlan becomes inaccessible. When the files gets closed, + * macvtap_get_queue() fails. * - * macvtap_lock is only used to prevent multiple concurrent open() - * calls to assign a new vlan->tap pointer. It could be moved into - * the macvlan_dev itself but is extremely rarely used. + * There may still be references to the struct sock inside of the + * queue from outbound SKBs, but these never reference back to the + * file or the dev. The data structure is freed through __sk_free + * when both our references and any pending SKBs are gone. */ static DEFINE_SPINLOCK(macvtap_lock); @@ -101,11 +94,12 @@ static int macvtap_set_queue(struct net_device *dev, struct file *file, goto out; err = 0; - q->vlan = vlan; + rcu_assign_pointer(q->vlan, vlan); rcu_assign_pointer(vlan->tap, q); + sock_hold(&q->sk); q->file = file; - rcu_assign_pointer(file->private_data, q); + file->private_data = q; out: spin_unlock(&macvtap_lock); @@ -113,28 +107,25 @@ out: } /* - * We must destroy each queue exactly once, when either - * the netdev or the file go away. + * The file owning the queue got closed, give up both + * the reference that the files holds as well as the + * one from the macvlan_dev if that still exists. * * Using the spinlock makes sure that we don't get * to the queue again after destroying it. - * - * synchronize_rcu serializes with the packet flow - * that uses rcu_read_lock. */ -static void macvtap_del_queue(struct macvtap_queue **qp) +static void macvtap_put_queue(struct macvtap_queue *q) { - struct macvtap_queue *q; + struct macvlan_dev *vlan; spin_lock(&macvtap_lock); - q = rcu_dereference(*qp); - if (!q) { - spin_unlock(&macvtap_lock); - return; + vlan = rcu_dereference(q->vlan); + if (vlan) { + rcu_assign_pointer(vlan->tap, NULL); + rcu_assign_pointer(q->vlan, NULL); + sock_put(&q->sk); } - rcu_assign_pointer(q->vlan->tap, NULL); - rcu_assign_pointer(q->file->private_data, NULL); spin_unlock(&macvtap_lock); synchronize_rcu(); @@ -152,29 +143,29 @@ static struct macvtap_queue *macvtap_get_queue(struct net_device *dev, return rcu_dereference(vlan->tap); } +/* + * The net_device is going away, give up the reference + * that it holds on the queue (all the queues one day) + * and safely set the pointer from the queues to NULL. + */ static void macvtap_del_queues(struct net_device *dev) { struct macvlan_dev *vlan = netdev_priv(dev); - macvtap_del_queue(&vlan->tap); -} - -static inline struct macvtap_queue *macvtap_file_get_queue(struct file *file) -{ struct macvtap_queue *q; - rcu_read_lock_bh(); - q = rcu_dereference(file->private_data); - if (q) { - sock_hold(&q->sk); - dev_hold(q->vlan->dev); + + spin_lock(&macvtap_lock); + q = rcu_dereference(vlan->tap); + if (!q) { + spin_unlock(&macvtap_lock); + return; } - rcu_read_unlock_bh(); - return q; -} -static inline void macvtap_file_put_queue(struct macvtap_queue *q) -{ + rcu_assign_pointer(vlan->tap, NULL); + rcu_assign_pointer(q->vlan, NULL); + spin_unlock(&macvtap_lock); + + synchronize_rcu(); sock_put(&q->sk); - dev_put(q->vlan->dev); } /* @@ -189,7 +180,7 @@ static int macvtap_forward(struct net_device *dev, struct sk_buff *skb) return -ENOLINK; skb_queue_tail(&q->sk.sk_receive_queue, skb); - wake_up(q->sk.sk_sleep); + wake_up_interruptible_poll(q->sk.sk_sleep, POLLIN | POLLRDNORM | POLLRDBAND); return 0; } @@ -255,7 +246,7 @@ static void macvtap_sock_write_space(struct sock *sk) return; if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) - wake_up_interruptible_sync(sk->sk_sleep); + wake_up_interruptible_poll(sk->sk_sleep, POLLOUT | POLLWRNORM | POLLWRBAND); } static int macvtap_open(struct inode *inode, struct file *file) @@ -283,9 +274,11 @@ static int macvtap_open(struct inode *inode, struct file *file) init_waitqueue_head(&q->sock.wait); q->sock.type = SOCK_RAW; q->sock.state = SS_CONNECTED; + q->sock.file = file; + q->sock.ops = &macvtap_socket_ops; sock_init_data(&q->sock, &q->sk); - q->sk.sk_allocation = GFP_ATOMIC; /* for now */ q->sk.sk_write_space = macvtap_sock_write_space; + q->flags = IFF_VNET_HDR | IFF_NO_PI | IFF_TAP; err = macvtap_set_queue(dev, file, q); if (err) @@ -300,13 +293,14 @@ out: static int macvtap_release(struct inode *inode, struct file *file) { - macvtap_del_queue((struct macvtap_queue **)&file->private_data); + struct macvtap_queue *q = file->private_data; + macvtap_put_queue(q); return 0; } static unsigned int macvtap_poll(struct file *file, poll_table * wait) { - struct macvtap_queue *q = macvtap_file_get_queue(file); + struct macvtap_queue *q = file->private_data; unsigned int mask = POLLERR; if (!q) @@ -323,44 +317,192 @@ static unsigned int macvtap_poll(struct file *file, poll_table * wait) sock_writeable(&q->sk))) mask |= POLLOUT | POLLWRNORM; - macvtap_file_put_queue(q); out: return mask; } +static inline struct sk_buff *macvtap_alloc_skb(struct sock *sk, size_t prepad, + size_t len, size_t linear, + int noblock, int *err) +{ + struct sk_buff *skb; + + /* Under a page? Don't bother with paged skb. */ + if (prepad + len < PAGE_SIZE || !linear) + linear = len; + + skb = sock_alloc_send_pskb(sk, prepad + linear, len - linear, noblock, + err); + if (!skb) + return NULL; + + skb_reserve(skb, prepad); + skb_put(skb, linear); + skb->data_len = len - linear; + skb->len += len - linear; + + return skb; +} + +/* + * macvtap_skb_from_vnet_hdr and macvtap_skb_to_vnet_hdr should + * be shared with the tun/tap driver. + */ +static int macvtap_skb_from_vnet_hdr(struct sk_buff *skb, + struct virtio_net_hdr *vnet_hdr) +{ + unsigned short gso_type = 0; + if (vnet_hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) { + switch (vnet_hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) { + case VIRTIO_NET_HDR_GSO_TCPV4: + gso_type = SKB_GSO_TCPV4; + break; + case VIRTIO_NET_HDR_GSO_TCPV6: + gso_type = SKB_GSO_TCPV6; + break; + case VIRTIO_NET_HDR_GSO_UDP: + gso_type = SKB_GSO_UDP; + break; + default: + return -EINVAL; + } + + if (vnet_hdr->gso_type & VIRTIO_NET_HDR_GSO_ECN) + gso_type |= SKB_GSO_TCP_ECN; + + if (vnet_hdr->gso_size == 0) + return -EINVAL; + } + + if (vnet_hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) { + if (!skb_partial_csum_set(skb, vnet_hdr->csum_start, + vnet_hdr->csum_offset)) + return -EINVAL; + } + + if (vnet_hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) { + skb_shinfo(skb)->gso_size = vnet_hdr->gso_size; + skb_shinfo(skb)->gso_type = gso_type; + + /* Header must be checked, and gso_segs computed. */ + skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY; + skb_shinfo(skb)->gso_segs = 0; + } + return 0; +} + +static int macvtap_skb_to_vnet_hdr(const struct sk_buff *skb, + struct virtio_net_hdr *vnet_hdr) +{ + memset(vnet_hdr, 0, sizeof(*vnet_hdr)); + + if (skb_is_gso(skb)) { + struct skb_shared_info *sinfo = skb_shinfo(skb); + + /* This is a hint as to how much should be linear. */ + vnet_hdr->hdr_len = skb_headlen(skb); + vnet_hdr->gso_size = sinfo->gso_size; + if (sinfo->gso_type & SKB_GSO_TCPV4) + vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4; + else if (sinfo->gso_type & SKB_GSO_TCPV6) + vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6; + else if (sinfo->gso_type & SKB_GSO_UDP) + vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_UDP; + else + BUG(); + if (sinfo->gso_type & SKB_GSO_TCP_ECN) + vnet_hdr->gso_type |= VIRTIO_NET_HDR_GSO_ECN; + } else + vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_NONE; + + if (skb->ip_summed == CHECKSUM_PARTIAL) { + vnet_hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; + vnet_hdr->csum_start = skb->csum_start - + skb_headroom(skb); + vnet_hdr->csum_offset = skb->csum_offset; + } /* else everything is zero */ + + return 0; +} + + /* Get packet from user space buffer */ static ssize_t macvtap_get_user(struct macvtap_queue *q, const struct iovec *iv, size_t count, int noblock) { struct sk_buff *skb; + struct macvlan_dev *vlan; size_t len = count; int err; + struct virtio_net_hdr vnet_hdr = { 0 }; + int vnet_hdr_len = 0; + + if (q->flags & IFF_VNET_HDR) { + vnet_hdr_len = sizeof(vnet_hdr); + + err = -EINVAL; + if ((len -= vnet_hdr_len) < 0) + goto err; + + err = memcpy_fromiovecend((void *)&vnet_hdr, iv, 0, + vnet_hdr_len); + if (err < 0) + goto err; + if ((vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) && + vnet_hdr.csum_start + vnet_hdr.csum_offset + 2 > + vnet_hdr.hdr_len) + vnet_hdr.hdr_len = vnet_hdr.csum_start + + vnet_hdr.csum_offset + 2; + err = -EINVAL; + if (vnet_hdr.hdr_len > len) + goto err; + } + err = -EINVAL; if (unlikely(len < ETH_HLEN)) - return -EINVAL; + goto err; - skb = sock_alloc_send_skb(&q->sk, NET_IP_ALIGN + len, noblock, &err); + skb = macvtap_alloc_skb(&q->sk, NET_IP_ALIGN, len, vnet_hdr.hdr_len, + noblock, &err); + if (!skb) + goto err; - if (!skb) { - macvlan_count_rx(q->vlan, 0, false, false); - return err; - } + err = skb_copy_datagram_from_iovec(skb, 0, iv, vnet_hdr_len, len); + if (err) + goto err_kfree; + + skb_set_network_header(skb, ETH_HLEN); + skb_reset_mac_header(skb); + skb->protocol = eth_hdr(skb)->h_proto; - skb_reserve(skb, NET_IP_ALIGN); - skb_put(skb, count); + if (vnet_hdr_len) { + err = macvtap_skb_from_vnet_hdr(skb, &vnet_hdr); + if (err) + goto err_kfree; + } - if (skb_copy_datagram_from_iovec(skb, 0, iv, 0, len)) { - macvlan_count_rx(q->vlan, 0, false, false); + rcu_read_lock_bh(); + vlan = rcu_dereference(q->vlan); + if (vlan) + macvlan_start_xmit(skb, vlan->dev); + else kfree_skb(skb); - return -EFAULT; - } + rcu_read_unlock_bh(); - skb_set_network_header(skb, ETH_HLEN); + return count; - macvlan_start_xmit(skb, q->vlan->dev); +err_kfree: + kfree_skb(skb); - return count; +err: + rcu_read_lock_bh(); + vlan = rcu_dereference(q->vlan); + if (vlan) + netdev_get_tx_queue(vlan->dev, 0)->tx_dropped++; + rcu_read_unlock_bh(); + + return err; } static ssize_t macvtap_aio_write(struct kiocb *iocb, const struct iovec *iv, @@ -368,15 +510,10 @@ static ssize_t macvtap_aio_write(struct kiocb *iocb, const struct iovec *iv, { struct file *file = iocb->ki_filp; ssize_t result = -ENOLINK; - struct macvtap_queue *q = macvtap_file_get_queue(file); - - if (!q) - goto out; + struct macvtap_queue *q = file->private_data; result = macvtap_get_user(q, iv, iov_length(iv, count), file->f_flags & O_NONBLOCK); - macvtap_file_put_queue(q); -out: return result; } @@ -385,36 +522,44 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q, const struct sk_buff *skb, const struct iovec *iv, int len) { - struct macvlan_dev *vlan = q->vlan; + struct macvlan_dev *vlan; int ret; + int vnet_hdr_len = 0; + + if (q->flags & IFF_VNET_HDR) { + struct virtio_net_hdr vnet_hdr; + vnet_hdr_len = sizeof (vnet_hdr); + if ((len -= vnet_hdr_len) < 0) + return -EINVAL; + + ret = macvtap_skb_to_vnet_hdr(skb, &vnet_hdr); + if (ret) + return ret; + + if (memcpy_toiovecend(iv, (void *)&vnet_hdr, 0, vnet_hdr_len)) + return -EFAULT; + } len = min_t(int, skb->len, len); - ret = skb_copy_datagram_const_iovec(skb, 0, iv, 0, len); + ret = skb_copy_datagram_const_iovec(skb, 0, iv, vnet_hdr_len, len); - macvlan_count_rx(vlan, len, ret == 0, 0); + rcu_read_lock_bh(); + vlan = rcu_dereference(q->vlan); + if (vlan) + macvlan_count_rx(vlan, len, ret == 0, 0); + rcu_read_unlock_bh(); - return ret ? ret : len; + return ret ? ret : (len + vnet_hdr_len); } -static ssize_t macvtap_aio_read(struct kiocb *iocb, const struct iovec *iv, - unsigned long count, loff_t pos) +static ssize_t macvtap_do_read(struct macvtap_queue *q, struct kiocb *iocb, + const struct iovec *iv, unsigned long len, + int noblock) { - struct file *file = iocb->ki_filp; - struct macvtap_queue *q = macvtap_file_get_queue(file); - DECLARE_WAITQUEUE(wait, current); struct sk_buff *skb; - ssize_t len, ret = 0; - - if (!q) - return -ENOLINK; - - len = iov_length(iv, count); - if (len < 0) { - ret = -EINVAL; - goto out; - } + ssize_t ret = 0; add_wait_queue(q->sk.sk_sleep, &wait); while (len) { @@ -423,7 +568,7 @@ static ssize_t macvtap_aio_read(struct kiocb *iocb, const struct iovec *iv, /* Read frames from the queue */ skb = skb_dequeue(&q->sk.sk_receive_queue); if (!skb) { - if (file->f_flags & O_NONBLOCK) { + if (noblock) { ret = -EAGAIN; break; } @@ -442,9 +587,25 @@ static ssize_t macvtap_aio_read(struct kiocb *iocb, const struct iovec *iv, current->state = TASK_RUNNING; remove_wait_queue(q->sk.sk_sleep, &wait); + return ret; +} + +static ssize_t macvtap_aio_read(struct kiocb *iocb, const struct iovec *iv, + unsigned long count, loff_t pos) +{ + struct file *file = iocb->ki_filp; + struct macvtap_queue *q = file->private_data; + ssize_t len, ret = 0; + + len = iov_length(iv, count); + if (len < 0) { + ret = -EINVAL; + goto out; + } + ret = macvtap_do_read(q, iocb, iv, len, file->f_flags & O_NONBLOCK); + ret = min_t(ssize_t, ret, len); /* XXX copied from tun.c. Why? */ out: - macvtap_file_put_queue(q); return ret; } @@ -454,36 +615,47 @@ out: static long macvtap_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - struct macvtap_queue *q; + struct macvtap_queue *q = file->private_data; + struct macvlan_dev *vlan; void __user *argp = (void __user *)arg; struct ifreq __user *ifr = argp; unsigned int __user *up = argp; unsigned int u; - char devname[IFNAMSIZ]; + int ret; switch (cmd) { case TUNSETIFF: /* ignore the name, just look at flags */ if (get_user(u, &ifr->ifr_flags)) return -EFAULT; - if (u != (IFF_TAP | IFF_NO_PI)) - return -EINVAL; - return 0; + + ret = 0; + if ((u & ~IFF_VNET_HDR) != (IFF_NO_PI | IFF_TAP)) + ret = -EINVAL; + else + q->flags = u; + + return ret; case TUNGETIFF: - q = macvtap_file_get_queue(file); - if (!q) + rcu_read_lock_bh(); + vlan = rcu_dereference(q->vlan); + if (vlan) + dev_hold(vlan->dev); + rcu_read_unlock_bh(); + + if (!vlan) return -ENOLINK; - memcpy(devname, q->vlan->dev->name, sizeof(devname)); - macvtap_file_put_queue(q); + ret = 0; if (copy_to_user(&ifr->ifr_name, q->vlan->dev->name, IFNAMSIZ) || - put_user((TUN_TAP_DEV | TUN_NO_PI), &ifr->ifr_flags)) - return -EFAULT; - return 0; + put_user(q->flags, &ifr->ifr_flags)) + ret = -EFAULT; + dev_put(vlan->dev); + return ret; case TUNGETFEATURES: - if (put_user((IFF_TAP | IFF_NO_PI), up)) + if (put_user(IFF_TAP | IFF_NO_PI | IFF_VNET_HDR, up)) return -EFAULT; return 0; @@ -491,25 +663,19 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd, if (get_user(u, up)) return -EFAULT; - q = macvtap_file_get_queue(file); - if (!q) - return -ENOLINK; q->sk.sk_sndbuf = u; - macvtap_file_put_queue(q); return 0; case TUNSETOFFLOAD: /* let the user check for future flags */ if (arg & ~(TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 | - TUN_F_TSO_ECN | TUN_F_UFO)) - return -EINVAL; - - /* TODO: add support for these, so far we don't - support any offload */ - if (arg & (TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 | - TUN_F_TSO_ECN | TUN_F_UFO)) + TUN_F_TSO_ECN | TUN_F_UFO)) return -EINVAL; + /* TODO: only accept frames with the features that + got enabled for forwarded frames */ + if (!(q->flags & IFF_VNET_HDR)) + return -EINVAL; return 0; default: @@ -539,6 +705,53 @@ static const struct file_operations macvtap_fops = { #endif }; +static int macvtap_sendmsg(struct kiocb *iocb, struct socket *sock, + struct msghdr *m, size_t total_len) +{ + struct macvtap_queue *q = container_of(sock, struct macvtap_queue, sock); + return macvtap_get_user(q, m->msg_iov, total_len, + m->msg_flags & MSG_DONTWAIT); +} + +static int macvtap_recvmsg(struct kiocb *iocb, struct socket *sock, + struct msghdr *m, size_t total_len, + int flags) +{ + struct macvtap_queue *q = container_of(sock, struct macvtap_queue, sock); + int ret; + if (flags & ~(MSG_DONTWAIT|MSG_TRUNC)) + return -EINVAL; + ret = macvtap_do_read(q, iocb, m->msg_iov, total_len, + flags & MSG_DONTWAIT); + if (ret > total_len) { + m->msg_flags |= MSG_TRUNC; + ret = flags & MSG_TRUNC ? ret : total_len; + } + return ret; +} + +/* Ops structure to mimic raw sockets with tun */ +static const struct proto_ops macvtap_socket_ops = { + .sendmsg = macvtap_sendmsg, + .recvmsg = macvtap_recvmsg, +}; + +/* Get an underlying socket object from tun file. Returns error unless file is + * attached to a device. The returned object works like a packet socket, it + * can be used for sock_sendmsg/sock_recvmsg. The caller is responsible for + * holding a reference to the file for as long as the socket is in use. */ +struct socket *macvtap_get_socket(struct file *file) +{ + struct macvtap_queue *q; + if (file->f_op != &macvtap_fops) + return ERR_PTR(-EINVAL); + q = file->private_data; + if (!q) + return ERR_PTR(-EBADFD); + return &q->sock; +} +EXPORT_SYMBOL_GPL(macvtap_get_socket); + static int macvtap_init(void) { int err; diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c index 829b9ec9ff6..64394647ddd 100644 --- a/drivers/net/mlx4/en_rx.c +++ b/drivers/net/mlx4/en_rx.c @@ -508,11 +508,11 @@ static struct sk_buff *mlx4_en_rx_skb(struct mlx4_en_priv *priv, /* We are copying all relevant data to the skb - temporarily * synch buffers for the copy */ dma = be64_to_cpu(rx_desc->data[0].addr); - dma_sync_single_range_for_cpu(&mdev->pdev->dev, dma, 0, - length, DMA_FROM_DEVICE); + dma_sync_single_for_cpu(&mdev->pdev->dev, dma, length, + DMA_FROM_DEVICE); skb_copy_to_linear_data(skb, va, length); - dma_sync_single_range_for_device(&mdev->pdev->dev, dma, 0, - length, DMA_FROM_DEVICE); + dma_sync_single_for_device(&mdev->pdev->dev, dma, length, + DMA_FROM_DEVICE); skb->tail += length; } else { diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index 2ee57bd52a0..d90e0fcdbce 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c @@ -1625,8 +1625,7 @@ static inline void make_mc_bits(u8 *bits, struct net_device *dev) struct dev_mc_list *dmi; u32 crc; - for (dmi=dev->mc_list; dmi; dmi=dmi->next) { - + netdev_for_each_mc_addr(dmi, dev) { crc = ether_crc(ETH_ALEN, dmi->dmi_addr); /* * The 8390 uses the 6 most significant bits of the @@ -1652,7 +1651,7 @@ static void do_set_multicast_list(struct net_device *dev) if (!(dev->flags&(IFF_PROMISC|IFF_ALLMULTI))) { memset(ei_local->mcfilter, 0, 8); - if (dev->mc_list) + if (!netdev_mc_empty(dev)) make_mc_bits(ei_local->mcfilter, dev); } else { /* set to accept-all */ @@ -1668,7 +1667,7 @@ static void do_set_multicast_list(struct net_device *dev) if(dev->flags&IFF_PROMISC) outb_p(E8390_RXCONFIG | 0x58, e8390_base + EN0_RXCR); - else if(dev->flags&IFF_ALLMULTI || dev->mc_list) + else if (dev->flags & IFF_ALLMULTI || !netdev_mc_empty(dev)) outb_p(E8390_RXCONFIG | 0x48, e8390_base + EN0_RXCR); else outb_p(E8390_RXCONFIG | 0x40, e8390_base + EN0_RXCR); diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index 3d573ed5f7c..b9dc80b9d04 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c @@ -1199,10 +1199,8 @@ static void set_rx_mode(struct net_device *dev) struct dev_mc_list *mclist; memset(mc_filter, 0, sizeof(mc_filter)); - for (i = 0, mclist = dev->mc_list; mclist && i < netdev_mc_count(dev); - i++, mclist = mclist->next) { - unsigned int bit = - ether_crc_le(ETH_ALEN, mclist->dmi_addr) >> 26; + netdev_for_each_mc_addr(mclist, dev) { + unsigned int bit = ether_crc_le(ETH_ALEN, mclist->dmi_addr) >> 26; mc_filter[bit >> 3] |= (1 << (bit & 7)); } outb(2, ioaddr + RX_MODE); /* Use normal mode. */ diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c index c42a31a97fa..c717b143f11 100644 --- a/drivers/net/pcmcia/nmclan_cs.c +++ b/drivers/net/pcmcia/nmclan_cs.c @@ -1475,8 +1475,7 @@ static void set_multicast_list(struct net_device *dev) { mace_private *lp = netdev_priv(dev); int adr[ETHER_ADDR_LEN] = {0}; /* Ethernet address */ - int i; - struct dev_mc_list *dmi = dev->mc_list; + struct dev_mc_list *dmi; #ifdef PCMCIA_DEBUG { @@ -1496,9 +1495,8 @@ static void set_multicast_list(struct net_device *dev) if (num_addrs > 0) { /* Calculate multicast logical address filter */ memset(lp->multicast_ladrf, 0, MACE_LADRF_LEN); - for (i = 0; i < netdev_mc_count(dev); i++) { + netdev_for_each_mc_addr(dmi, dev) { memcpy(adr, dmi->dmi_addr, ETHER_ADDR_LEN); - dmi = dmi->next; BuildLAF(lp->multicast_ladrf, adr); } } diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index d2e86b8887c..d29c22a80a0 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c @@ -1595,27 +1595,6 @@ static void smc_rx(struct net_device *dev) /*====================================================================== - Calculate values for the hardware multicast filter hash table. - -======================================================================*/ - -static void fill_multicast_tbl(int count, struct dev_mc_list *addrs, - u_char *multicast_table) -{ - struct dev_mc_list *mc_addr; - - for (mc_addr = addrs; mc_addr && count-- > 0; mc_addr = mc_addr->next) { - u_int position = ether_crc(6, mc_addr->dmi_addr); -#ifndef final_version /* Verify multicast address. */ - if ((mc_addr->dmi_addr[0] & 1) == 0) - continue; -#endif - multicast_table[position >> 29] |= 1 << ((position >> 26) & 7); - } -} - -/*====================================================================== - Set the receive mode. This routine is used by both the protocol level to notify us of @@ -1639,8 +1618,16 @@ static void set_rx_mode(struct net_device *dev) rx_cfg_setting = RxStripCRC | RxEnable | RxAllMulti; else { if (!netdev_mc_empty(dev)) { - fill_multicast_tbl(netdev_mc_count(dev), dev->mc_list, - (u_char *)multicast_table); + struct dev_mc_list *mc_addr; + + netdev_for_each_mc_addr(mc_addr, dev) { + u_int position = ether_crc(6, mc_addr->dmi_addr); +#ifndef final_version /* Verify multicast address. */ + if ((mc_addr->dmi_addr[0] & 1) == 0) + continue; +#endif + multicast_table[position >> 29] |= 1 << ((position >> 26) & 7); + } } rx_cfg_setting = RxStripCRC | RxEnable; } diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c index 4ace18a7115..4d1802e457b 100644 --- a/drivers/net/pcmcia/xirc2ps_cs.c +++ b/drivers/net/pcmcia/xirc2ps_cs.c @@ -1364,47 +1364,63 @@ do_start_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } +struct set_address_info { + int reg_nr; + int page_nr; + int mohawk; + unsigned int ioaddr; +}; + +static void set_address(struct set_address_info *sa_info, char *addr) +{ + unsigned int ioaddr = sa_info->ioaddr; + int i; + + for (i = 0; i < 6; i++) { + if (sa_info->reg_nr > 15) { + sa_info->reg_nr = 8; + sa_info->page_nr++; + SelectPage(sa_info->page_nr); + } + if (sa_info->mohawk) + PutByte(sa_info->reg_nr++, addr[5 - i]); + else + PutByte(sa_info->reg_nr++, addr[i]); + } +} + /**************** * Set all addresses: This first one is the individual address, * the next 9 addresses are taken from the multicast list and * the rest is filled with the individual address. */ -static void -set_addresses(struct net_device *dev) +static void set_addresses(struct net_device *dev) { - unsigned int ioaddr = dev->base_addr; - local_info_t *lp = netdev_priv(dev); - struct dev_mc_list *dmi = dev->mc_list; - unsigned char *addr; - int i,j,k,n; - - SelectPage(k=0x50); - for (i=0,j=8,n=0; ; i++, j++) { - if (i > 5) { - if (++n > 9) - break; - i = 0; - if (n > 1 && n <= netdev_mc_count(dev) && dmi) { - dmi = dmi->next; - } - } - if (j > 15) { - j = 8; - k++; - SelectPage(k); - } - - if (n && n <= netdev_mc_count(dev) && dmi) - addr = dmi->dmi_addr; - else - addr = dev->dev_addr; + unsigned int ioaddr = dev->base_addr; + local_info_t *lp = netdev_priv(dev); + struct dev_mc_list *dmi; + struct set_address_info sa_info; + int i; - if (lp->mohawk) - PutByte(j, addr[5-i]); - else - PutByte(j, addr[i]); - } - SelectPage(0); + /* + * Setup the info structure so that by first set_address call it will do + * SelectPage with the right page number. Hence these ones here. + */ + sa_info.reg_nr = 15 + 1; + sa_info.page_nr = 0x50 - 1; + sa_info.mohawk = lp->mohawk; + sa_info.ioaddr = ioaddr; + + set_address(&sa_info, dev->dev_addr); + i = 0; + netdev_for_each_mc_addr(dmi, dev) { + if (i++ == 9) + break; + set_address(&sa_info, dmi->dmi_addr); + } + while (i++ < 9) + set_address(&sa_info, dev->dev_addr); + SelectPage(0); } /**************** diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 616ae5aa66a..83965eeba45 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -187,7 +187,7 @@ static DEFINE_PCI_DEVICE_TABLE(rtl8169_pci_tbl) = { MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl); static int rx_copybreak = 200; -static int use_dac; +static int use_dac = -1; static struct { u32 msg_enable; } debug = { -1 }; @@ -511,7 +511,8 @@ MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver"); module_param(rx_copybreak, int, 0); MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames"); module_param(use_dac, int, 0); -MODULE_PARM_DESC(use_dac, "Enable PCI DAC. Unsafe on 32 bit PCI slot."); +MODULE_PARM_DESC(use_dac, "Enable PCI DAC. -1 defaults on for PCI Express only." +" Unsafe on 32 bit PCI slot."); module_param_named(debug, debug.msg_enable, int, 0); MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., 16=all)"); MODULE_LICENSE("GPL"); @@ -2973,6 +2974,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) void __iomem *ioaddr; unsigned int i; int rc; + int this_use_dac = use_dac; if (netif_msg_drv(&debug)) { printk(KERN_INFO "%s Gigabit Ethernet driver %s loaded\n", @@ -3038,8 +3040,17 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) tp->cp_cmd = PCIMulRW | RxChkSum; + tp->pcie_cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); + if (!tp->pcie_cap) + netif_info(tp, probe, dev, "no PCI Express capability\n"); + + if (this_use_dac < 0) + this_use_dac = tp->pcie_cap != 0; + if ((sizeof(dma_addr_t) > 4) && - !pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) && use_dac) { + this_use_dac && + !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { + netif_info(tp, probe, dev, "using 64-bit DMA\n"); tp->cp_cmd |= PCIDAC; dev->features |= NETIF_F_HIGHDMA; } else { @@ -3058,10 +3069,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_free_res_4; } - tp->pcie_cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); - if (!tp->pcie_cap) - netif_info(tp, probe, dev, "no PCI Express capability\n"); - RTL_W16(IntrMask, 0x0000); /* Soft reset the chip. */ diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 102be16e9b5..43bc66aa840 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -5092,8 +5092,8 @@ static void s2io_set_multicast(struct net_device *dev) } /* Create the new Rx filter list and update the same in H/W. */ - for (i = 0, mclist = dev->mc_list; i < netdev_mc_count(dev); - i++, mclist = mclist->next) { + i = 0; + netdev_for_each_mc_addr(mclist, dev) { memcpy(sp->usr_addrs[i].addr, mclist->dmi_addr, ETH_ALEN); mac_addr = 0; @@ -5121,6 +5121,7 @@ static void s2io_set_multicast(struct net_device *dev) dev->name); return; } + i++; } } } diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c index 564d4d7f855..9944e5d662c 100644 --- a/drivers/net/sb1250-mac.c +++ b/drivers/net/sb1250-mac.c @@ -2161,13 +2161,13 @@ static void sbmac_setmulti(struct sbmac_softc *sc) * XXX if the table overflows */ idx = 1; /* skip station address */ - mclist = dev->mc_list; - while (mclist && (idx < MAC_ADDR_COUNT)) { + netdev_for_each_mc_addr(mclist, dev) { + if (idx == MAC_ADDR_COUNT) + break; reg = sbmac_addr2reg(mclist->dmi_addr); port = sc->sbm_base + R_MAC_ADDR_BASE+(idx * sizeof(uint64_t)); __raw_writeq(reg, port); idx++; - mclist = mclist->next; } /* diff --git a/drivers/net/sc92031.c b/drivers/net/sc92031.c index 00ff8995ad6..d87c4787fff 100644 --- a/drivers/net/sc92031.c +++ b/drivers/net/sc92031.c @@ -435,7 +435,7 @@ static void _sc92031_set_mar(struct net_device *dev) else if (dev->flags & IFF_MULTICAST) { struct dev_mc_list *mc_list; - for (mc_list = dev->mc_list; mc_list; mc_list = mc_list->next) { + netdev_for_each_mc_addr(mc_list, dev) { u32 crc; unsigned bit = 0; diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index dc58d9fd0f3..88f2fb193ab 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -1602,11 +1602,10 @@ static int efx_set_mac_address(struct net_device *net_dev, void *data) static void efx_set_multicast_list(struct net_device *net_dev) { struct efx_nic *efx = netdev_priv(net_dev); - struct dev_mc_list *mc_list = net_dev->mc_list; + struct dev_mc_list *mc_list; union efx_multicast_hash *mc_hash = &efx->multicast_hash; u32 crc; int bit; - int i; efx->promiscuous = !!(net_dev->flags & IFF_PROMISC); @@ -1615,11 +1614,10 @@ static void efx_set_multicast_list(struct net_device *net_dev) memset(mc_hash, 0xff, sizeof(*mc_hash)); } else { memset(mc_hash, 0x00, sizeof(*mc_hash)); - for (i = 0; i < netdev_mc_count(net_dev); i++) { + netdev_for_each_mc_addr(mc_list, net_dev) { crc = ether_crc_le(ETH_ALEN, mc_list->dmi_addr); bit = crc & (EFX_MCAST_HASH_ENTRIES - 1); set_bit_le(bit, mc_hash->byte); - mc_list = mc_list->next; } /* Broadcast packets go through the multicast hash filter. diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c index bf2ffbb913f..4487b065ef7 100644 --- a/drivers/net/sis190.c +++ b/drivers/net/sis190.c @@ -17,7 +17,9 @@ See the file COPYING in this distribution for more information. - */ +*/ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/module.h> #include <linux/moduleparam.h> @@ -32,17 +34,6 @@ #include <linux/dma-mapping.h> #include <asm/irq.h> -#define net_drv(p, arg...) if (netif_msg_drv(p)) \ - printk(arg) -#define net_probe(p, arg...) if (netif_msg_probe(p)) \ - printk(arg) -#define net_link(p, arg...) if (netif_msg_link(p)) \ - printk(arg) -#define net_intr(p, arg...) if (netif_msg_intr(p)) \ - printk(arg) -#define net_tx_err(p, arg...) if (netif_msg_tx_err(p)) \ - printk(arg) - #define PHY_MAX_ADDR 32 #define PHY_ID_ANY 0x1f #define MII_REG_ANY 0x1f @@ -50,7 +41,6 @@ #define DRV_VERSION "1.4" #define DRV_NAME "sis190" #define SIS190_DRIVER_NAME DRV_NAME " Gigabit Ethernet driver " DRV_VERSION -#define PFX DRV_NAME ": " #define sis190_rx_skb netif_rx #define sis190_rx_quota(count, quota) count @@ -382,7 +372,7 @@ static void __mdio_cmd(void __iomem *ioaddr, u32 ctl) } if (i > 99) - printk(KERN_ERR PFX "PHY command failed !\n"); + pr_err("PHY command failed !\n"); } static void mdio_write(void __iomem *ioaddr, int phy_id, int reg, int val) @@ -590,8 +580,7 @@ static int sis190_rx_interrupt(struct net_device *dev, status = le32_to_cpu(desc->PSize); - // net_intr(tp, KERN_INFO "%s: Rx PSize = %08x.\n", dev->name, - // status); + //netif_info(tp, intr, dev, "Rx PSize = %08x\n", status); if (sis190_rx_pkt_err(status, stats) < 0) sis190_give_to_asic(desc, tp->rx_buf_sz); @@ -602,9 +591,8 @@ static int sis190_rx_interrupt(struct net_device *dev, struct pci_dev *pdev = tp->pci_dev; if (unlikely(pkt_size > tp->rx_buf_sz)) { - net_intr(tp, KERN_INFO - "%s: (frag) status = %08x.\n", - dev->name, status); + netif_info(tp, intr, dev, + "(frag) status = %08x\n", status); stats->rx_dropped++; stats->rx_length_errors++; sis190_give_to_asic(desc, tp->rx_buf_sz); @@ -638,12 +626,12 @@ static int sis190_rx_interrupt(struct net_device *dev, tp->cur_rx = cur_rx; delta = sis190_rx_fill(tp, dev, tp->dirty_rx, tp->cur_rx); - if (!delta && count && netif_msg_intr(tp)) - printk(KERN_INFO "%s: no Rx buffer allocated.\n", dev->name); + if (!delta && count) + netif_info(tp, intr, dev, "no Rx buffer allocated\n"); tp->dirty_rx += delta; - if (((tp->dirty_rx + NUM_RX_DESC) == tp->cur_rx) && netif_msg_intr(tp)) - printk(KERN_EMERG "%s: Rx buffers exhausted.\n", dev->name); + if ((tp->dirty_rx + NUM_RX_DESC) == tp->cur_rx) + netif_emerg(tp, intr, dev, "Rx buffers exhausted\n"); return count; } @@ -752,10 +740,10 @@ static irqreturn_t sis190_interrupt(int irq, void *__dev) SIS_W32(IntrStatus, status); - // net_intr(tp, KERN_INFO "%s: status = %08x.\n", dev->name, status); +// netif_info(tp, intr, dev, "status = %08x\n", status); if (status & LinkChange) { - net_intr(tp, KERN_INFO "%s: link change.\n", dev->name); + netif_info(tp, intr, dev, "link change\n"); schedule_work(&tp->phy_task); } @@ -849,12 +837,10 @@ static void sis190_set_rx_mode(struct net_device *dev) mc_filter[1] = mc_filter[0] = 0xffffffff; } else { struct dev_mc_list *mclist; - unsigned int i; rx_mode = AcceptBroadcast | AcceptMyPhys; mc_filter[1] = mc_filter[0] = 0; - for (i = 0, mclist = dev->mc_list; mclist && i < netdev_mc_count(dev); - i++, mclist = mclist->next) { + netdev_for_each_mc_addr(mclist, dev) { int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) & 0x3f; mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31); @@ -933,8 +919,7 @@ static void sis190_phy_task(struct work_struct *work) } else if (!(mdio_read_latched(ioaddr, phy_id, MII_BMSR) & BMSR_ANEGCOMPLETE)) { netif_carrier_off(dev); - net_link(tp, KERN_WARNING "%s: auto-negotiating...\n", - dev->name); + netif_warn(tp, link, dev, "auto-negotiating...\n"); mod_timer(&tp->timer, jiffies + SIS190_PHY_TIMEOUT); } else { /* Rejoice ! */ @@ -960,13 +945,13 @@ static void sis190_phy_task(struct work_struct *work) u16 adv, autoexp, gigadv, gigrec; val = mdio_read(ioaddr, phy_id, 0x1f); - net_link(tp, KERN_INFO "%s: mii ext = %04x.\n", dev->name, val); + netif_info(tp, link, dev, "mii ext = %04x\n", val); val = mdio_read(ioaddr, phy_id, MII_LPA); adv = mdio_read(ioaddr, phy_id, MII_ADVERTISE); autoexp = mdio_read(ioaddr, phy_id, MII_EXPANSION); - net_link(tp, KERN_INFO "%s: mii lpa=%04x adv=%04x exp=%04x.\n", - dev->name, val, adv, autoexp); + netif_info(tp, link, dev, "mii lpa=%04x adv=%04x exp=%04x\n", + val, adv, autoexp); if (val & LPA_NPAGE && autoexp & EXPANSION_NWAY) { /* check for gigabit speed */ @@ -1007,8 +992,7 @@ static void sis190_phy_task(struct work_struct *work) tp->negotiated_lpa = p->val; - net_link(tp, KERN_INFO "%s: link on %s mode.\n", dev->name, - p->msg); + netif_info(tp, link, dev, "link on %s mode\n", p->msg); netif_carrier_on(dev); } @@ -1194,9 +1178,8 @@ static netdev_tx_t sis190_start_xmit(struct sk_buff *skb, if (unlikely(le32_to_cpu(desc->status) & OWNbit)) { netif_stop_queue(dev); - net_tx_err(tp, KERN_ERR PFX - "%s: BUG! Tx Ring full when queue awake!\n", - dev->name); + netif_err(tp, tx_err, dev, + "BUG! Tx Ring full when queue awake!\n"); return NETDEV_TX_BUSY; } @@ -1296,9 +1279,9 @@ static u16 sis190_default_phy(struct net_device *dev) if (mii_if->phy_id != phy_default->phy_id) { mii_if->phy_id = phy_default->phy_id; - net_probe(tp, KERN_INFO - "%s: Using transceiver at address %d as default.\n", - pci_name(tp->pci_dev), mii_if->phy_id); + if (netif_msg_probe(tp)) + pr_info("%s: Using transceiver at address %d as default\n", + pci_name(tp->pci_dev), mii_if->phy_id); } status = mdio_read(ioaddr, mii_if->phy_id, MII_BMCR); @@ -1336,14 +1319,15 @@ static void sis190_init_phy(struct net_device *dev, struct sis190_private *tp, ((mii_status & (BMSR_100FULL | BMSR_100HALF)) ? LAN : HOME) : p->type; tp->features |= p->feature; - net_probe(tp, KERN_INFO "%s: %s transceiver at address %d.\n", - pci_name(tp->pci_dev), p->name, phy_id); + if (netif_msg_probe(tp)) + pr_info("%s: %s transceiver at address %d\n", + pci_name(tp->pci_dev), p->name, phy_id); } else { phy->type = UNKNOWN; - net_probe(tp, KERN_INFO - "%s: unknown PHY 0x%x:0x%x transceiver at address %d\n", - pci_name(tp->pci_dev), - phy->id[0], (phy->id[1] & 0xfff0), phy_id); + if (netif_msg_probe(tp)) + pr_info("%s: unknown PHY 0x%x:0x%x transceiver at address %d\n", + pci_name(tp->pci_dev), + phy->id[0], (phy->id[1] & 0xfff0), phy_id); } } @@ -1407,8 +1391,9 @@ static int __devinit sis190_mii_probe(struct net_device *dev) } if (list_empty(&tp->first_phy)) { - net_probe(tp, KERN_INFO "%s: No MII transceivers found!\n", - pci_name(tp->pci_dev)); + if (netif_msg_probe(tp)) + pr_info("%s: No MII transceivers found!\n", + pci_name(tp->pci_dev)); rc = -EIO; goto out; } @@ -1454,7 +1439,8 @@ static struct net_device * __devinit sis190_init_board(struct pci_dev *pdev) dev = alloc_etherdev(sizeof(*tp)); if (!dev) { - net_drv(&debug, KERN_ERR PFX "unable to alloc new ethernet\n"); + if (netif_msg_drv(&debug)) + pr_err("unable to alloc new ethernet\n"); rc = -ENOMEM; goto err_out_0; } @@ -1467,34 +1453,39 @@ static struct net_device * __devinit sis190_init_board(struct pci_dev *pdev) rc = pci_enable_device(pdev); if (rc < 0) { - net_probe(tp, KERN_ERR "%s: enable failure\n", pci_name(pdev)); + if (netif_msg_probe(tp)) + pr_err("%s: enable failure\n", pci_name(pdev)); goto err_free_dev_1; } rc = -ENODEV; if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { - net_probe(tp, KERN_ERR "%s: region #0 is no MMIO resource.\n", - pci_name(pdev)); + if (netif_msg_probe(tp)) + pr_err("%s: region #0 is no MMIO resource\n", + pci_name(pdev)); goto err_pci_disable_2; } if (pci_resource_len(pdev, 0) < SIS190_REGS_SIZE) { - net_probe(tp, KERN_ERR "%s: invalid PCI region size(s).\n", - pci_name(pdev)); + if (netif_msg_probe(tp)) + pr_err("%s: invalid PCI region size(s)\n", + pci_name(pdev)); goto err_pci_disable_2; } rc = pci_request_regions(pdev, DRV_NAME); if (rc < 0) { - net_probe(tp, KERN_ERR PFX "%s: could not request regions.\n", - pci_name(pdev)); + if (netif_msg_probe(tp)) + pr_err("%s: could not request regions\n", + pci_name(pdev)); goto err_pci_disable_2; } rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); if (rc < 0) { - net_probe(tp, KERN_ERR "%s: DMA configuration failed.\n", - pci_name(pdev)); + if (netif_msg_probe(tp)) + pr_err("%s: DMA configuration failed\n", + pci_name(pdev)); goto err_free_res_3; } @@ -1502,8 +1493,9 @@ static struct net_device * __devinit sis190_init_board(struct pci_dev *pdev) ioaddr = ioremap(pci_resource_start(pdev, 0), SIS190_REGS_SIZE); if (!ioaddr) { - net_probe(tp, KERN_ERR "%s: cannot remap MMIO, aborting\n", - pci_name(pdev)); + if (netif_msg_probe(tp)) + pr_err("%s: cannot remap MMIO, aborting\n", + pci_name(pdev)); rc = -EIO; goto err_free_res_3; } @@ -1539,9 +1531,8 @@ static void sis190_tx_timeout(struct net_device *dev) if (tmp8 & CmdTxEnb) SIS_W8(TxControl, tmp8 & ~CmdTxEnb); - - net_tx_err(tp, KERN_INFO "%s: Transmit timeout, status %08x %08x.\n", - dev->name, SIS_R32(TxControl), SIS_R32(TxSts)); + netif_info(tp, tx_err, dev, "Transmit timeout, status %08x %08x\n", + SIS_R32(TxControl), SIS_R32(TxSts)); /* Disable interrupts by clearing the interrupt mask. */ SIS_W32(IntrMask, 0x0000); @@ -1570,15 +1561,16 @@ static int __devinit sis190_get_mac_addr_from_eeprom(struct pci_dev *pdev, u16 sig; int i; - net_probe(tp, KERN_INFO "%s: Read MAC address from EEPROM\n", - pci_name(pdev)); + if (netif_msg_probe(tp)) + pr_info("%s: Read MAC address from EEPROM\n", pci_name(pdev)); /* Check to see if there is a sane EEPROM */ sig = (u16) sis190_read_eeprom(ioaddr, EEPROMSignature); if ((sig == 0xffff) || (sig == 0x0000)) { - net_probe(tp, KERN_INFO "%s: Error EEPROM read %x.\n", - pci_name(pdev), sig); + if (netif_msg_probe(tp)) + pr_info("%s: Error EEPROM read %x\n", + pci_name(pdev), sig); return -EIO; } @@ -1612,8 +1604,8 @@ static int __devinit sis190_get_mac_addr_from_apc(struct pci_dev *pdev, u8 reg, tmp8; unsigned int i; - net_probe(tp, KERN_INFO "%s: Read MAC address from APC.\n", - pci_name(pdev)); + if (netif_msg_probe(tp)) + pr_info("%s: Read MAC address from APC\n", pci_name(pdev)); for (i = 0; i < ARRAY_SIZE(ids); i++) { isa_bridge = pci_get_device(PCI_VENDOR_ID_SI, ids[i], NULL); @@ -1622,8 +1614,9 @@ static int __devinit sis190_get_mac_addr_from_apc(struct pci_dev *pdev, } if (!isa_bridge) { - net_probe(tp, KERN_INFO "%s: Can not find ISA bridge.\n", - pci_name(pdev)); + if (netif_msg_probe(tp)) + pr_info("%s: Can not find ISA bridge\n", + pci_name(pdev)); return -EIO; } @@ -1704,7 +1697,7 @@ static void sis190_set_speed_auto(struct net_device *dev) int phy_id = tp->mii_if.phy_id; int val; - net_link(tp, KERN_INFO "%s: Enabling Auto-negotiation.\n", dev->name); + netif_info(tp, link, dev, "Enabling Auto-negotiation\n"); val = mdio_read(ioaddr, phy_id, MII_ADVERTISE); @@ -1831,7 +1824,8 @@ static int __devinit sis190_init_one(struct pci_dev *pdev, int rc; if (!printed_version) { - net_drv(&debug, KERN_INFO SIS190_DRIVER_NAME " loaded.\n"); + if (netif_msg_drv(&debug)) + pr_info(SIS190_DRIVER_NAME " loaded\n"); printed_version = 1; } @@ -1871,12 +1865,14 @@ static int __devinit sis190_init_one(struct pci_dev *pdev, if (rc < 0) goto err_remove_mii; - net_probe(tp, KERN_INFO "%s: %s at %p (IRQ: %d), %pM\n", - pci_name(pdev), sis_chip_info[ent->driver_data].name, - ioaddr, dev->irq, dev->dev_addr); - - net_probe(tp, KERN_INFO "%s: %s mode.\n", dev->name, - (tp->features & F_HAS_RGMII) ? "RGMII" : "GMII"); + if (netif_msg_probe(tp)) { + netdev_info(dev, "%s: %s at %p (IRQ: %d), %pM\n", + pci_name(pdev), + sis_chip_info[ent->driver_data].name, + ioaddr, dev->irq, dev->dev_addr); + netdev_info(dev, "%s mode.\n", + (tp->features & F_HAS_RGMII) ? "RGMII" : "GMII"); + } netif_carrier_off(dev); diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c index 32ae87c09f5..cc0c731c4f0 100644 --- a/drivers/net/sis900.c +++ b/drivers/net/sis900.c @@ -2300,9 +2300,8 @@ static void set_rx_mode(struct net_device *net_dev) * packets */ struct dev_mc_list *mclist; rx_mode = RFAAB; - for (i = 0, mclist = net_dev->mc_list; - mclist && i < netdev_mc_count(net_dev); - i++, mclist = mclist->next) { + + netdev_for_each_mc_addr(mclist, net_dev) { unsigned int bit_nr = sis900_mcast_bitnr(mclist->dmi_addr, sis_priv->chipset_rev); mc_filter[bit_nr >> 4] |= (1 << (bit_nr & 0xf)); diff --git a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c index 346adfae986..1921a54ea99 100644 --- a/drivers/net/skfp/skfddi.c +++ b/drivers/net/skfp/skfddi.c @@ -852,8 +852,7 @@ static void skfp_ctl_set_multicast_list(struct net_device *dev) static void skfp_ctl_set_multicast_list_wo_lock(struct net_device *dev) { struct s_smc *smc = netdev_priv(dev); - struct dev_mc_list *dmi; /* ptr to multicast addr entry */ - int i; + struct dev_mc_list *dmi; /* Enable promiscuous mode, if necessary */ if (dev->flags & IFF_PROMISC) { @@ -877,17 +876,14 @@ static void skfp_ctl_set_multicast_list_wo_lock(struct net_device *dev) /* use exact filtering */ // point to first multicast addr - dmi = dev->mc_list; - - for (i = 0; i < netdev_mc_count(dev); i++) { + netdev_for_each_mc_addr(dmi, dev) { mac_add_multicast(smc, (struct fddi_addr *)dmi->dmi_addr, 1); pr_debug(KERN_INFO "ENABLE MC ADDRESS: %pMF\n", dmi->dmi_addr); - dmi = dmi->next; - } // for + } } else { // more MC addresses than HW supports diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 720af1c7854..d0058e5bb6a 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -2917,8 +2917,7 @@ static void genesis_set_multicast(struct net_device *dev) struct skge_port *skge = netdev_priv(dev); struct skge_hw *hw = skge->hw; int port = skge->port; - int i, count = netdev_mc_count(dev); - struct dev_mc_list *list = dev->mc_list; + struct dev_mc_list *list; u32 mode; u8 filter[8]; @@ -2938,7 +2937,7 @@ static void genesis_set_multicast(struct net_device *dev) skge->flow_status == FLOW_STAT_SYMMETRIC) genesis_add_filter(filter, pause_mc_addr); - for (i = 0; list && i < count; i++, list = list->next) + netdev_for_each_mc_addr(list, dev) genesis_add_filter(filter, list->dmi_addr); } @@ -2957,7 +2956,7 @@ static void yukon_set_multicast(struct net_device *dev) struct skge_port *skge = netdev_priv(dev); struct skge_hw *hw = skge->hw; int port = skge->port; - struct dev_mc_list *list = dev->mc_list; + struct dev_mc_list *list; int rx_pause = (skge->flow_status == FLOW_STAT_REM_SEND || skge->flow_status == FLOW_STAT_SYMMETRIC); u16 reg; @@ -2975,13 +2974,12 @@ static void yukon_set_multicast(struct net_device *dev) else if (netdev_mc_empty(dev) && !rx_pause)/* no multicast */ reg &= ~GM_RXCR_MCF_ENA; else { - int i; reg |= GM_RXCR_MCF_ENA; if (rx_pause) yukon_add_filter(filter, pause_mc_addr); - for (i = 0; list && i < netdev_mc_count(dev); i++, list = list->next) + netdev_for_each_mc_addr(list, dev) yukon_add_filter(filter, list->dmi_addr); } diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index d1e98e2170c..653bdd76ef4 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -3621,7 +3621,7 @@ static void sky2_set_multicast(struct net_device *dev) struct sky2_port *sky2 = netdev_priv(dev); struct sky2_hw *hw = sky2->hw; unsigned port = sky2->port; - struct dev_mc_list *list = dev->mc_list; + struct dev_mc_list *list; u16 reg; u8 filter[8]; int rx_pause; @@ -3640,13 +3640,12 @@ static void sky2_set_multicast(struct net_device *dev) else if (netdev_mc_empty(dev) && !rx_pause) reg &= ~GM_RXCR_MCF_ENA; else { - int i; reg |= GM_RXCR_MCF_ENA; if (rx_pause) sky2_add_filter(filter, pause_mc_addr); - for (i = 0; list && i < netdev_mc_count(dev); i++, list = list->next) + netdev_for_each_mc_addr(list, dev) sky2_add_filter(filter, list->dmi_addr); } diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index 13c0b76dec4..4fd1d8b3878 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c @@ -1383,29 +1383,20 @@ static void smsc911x_set_multicast_list(struct net_device *dev) /* Enabling specific multicast addresses */ unsigned int hash_high = 0; unsigned int hash_low = 0; - unsigned int count = 0; - struct dev_mc_list *mc_list = dev->mc_list; + struct dev_mc_list *mc_list; pdata->set_bits_mask = MAC_CR_HPFILT_; pdata->clear_bits_mask = (MAC_CR_PRMS_ | MAC_CR_MCPAS_); - while (mc_list) { - count++; - if ((mc_list->dmi_addrlen) == ETH_ALEN) { - unsigned int bitnum = - smsc911x_hash(mc_list->dmi_addr); - unsigned int mask = 0x01 << (bitnum & 0x1F); - if (bitnum & 0x20) - hash_high |= mask; - else - hash_low |= mask; - } else { - SMSC_WARNING(DRV, "dmi_addrlen != 6"); - } - mc_list = mc_list->next; + netdev_for_each_mc_addr(mc_list, dev) { + unsigned int bitnum = smsc911x_hash(mc_list->dmi_addr); + unsigned int mask = 0x01 << (bitnum & 0x1F); + + if (bitnum & 0x20) + hash_high |= mask; + else + hash_low |= mask; } - if (count != (unsigned int)netdev_mc_count(dev)) - SMSC_WARNING(DRV, "mc_count != dev->mc_count"); pdata->hashhi = hash_high; pdata->hashlo = hash_low; diff --git a/drivers/net/smsc9420.c b/drivers/net/smsc9420.c index 2bd3c986559..30110a11d73 100644 --- a/drivers/net/smsc9420.c +++ b/drivers/net/smsc9420.c @@ -1063,11 +1063,11 @@ static void smsc9420_set_multicast_list(struct net_device *dev) mac_cr |= MAC_CR_MCPAS_; mac_cr &= (~MAC_CR_HPFILT_); } else if (!netdev_mc_empty(dev)) { - struct dev_mc_list *mc_list = dev->mc_list; + struct dev_mc_list *mc_list; u32 hash_lo = 0, hash_hi = 0; smsc_dbg(HW, "Multicast filter enabled"); - while (mc_list) { + netdev_for_each_mc_addr(mc_list, dev) { u32 bit_num = smsc9420_hash(mc_list->dmi_addr); u32 mask = 1 << (bit_num & 0x1F); @@ -1076,7 +1076,6 @@ static void smsc9420_set_multicast_list(struct net_device *dev) else hash_lo |= mask; - mc_list = mc_list->next; } smsc9420_reg_write(pd, HASHH, hash_hi); smsc9420_reg_write(pd, HASHL, hash_lo); diff --git a/drivers/net/sonic.c b/drivers/net/sonic.c index bd8bc66f2e0..287c251075e 100644 --- a/drivers/net/sonic.c +++ b/drivers/net/sonic.c @@ -531,7 +531,7 @@ static void sonic_multicast_list(struct net_device *dev) { struct sonic_local *lp = netdev_priv(dev); unsigned int rcr; - struct dev_mc_list *dmi = dev->mc_list; + struct dev_mc_list *dmi; unsigned char *addr; int i; @@ -549,13 +549,14 @@ static void sonic_multicast_list(struct net_device *dev) printk("sonic_multicast_list: mc_count %d\n", netdev_mc_count(dev)); sonic_set_cam_enable(dev, 1); /* always enable our own address */ - for (i = 1; i <= netdev_mc_count(dev); i++) { + i = 1; + netdev_for_each_mc_addr(dmi, dev) { addr = dmi->dmi_addr; - dmi = dmi->next; sonic_cda_put(dev, i, SONIC_CD_CAP0, addr[1] << 8 | addr[0]); sonic_cda_put(dev, i, SONIC_CD_CAP1, addr[3] << 8 | addr[2]); sonic_cda_put(dev, i, SONIC_CD_CAP2, addr[5] << 8 | addr[4]); sonic_set_cam_enable(dev, sonic_get_cam_enable(dev) | (1 << i)); + i++; } SONIC_WRITE(SONIC_CDC, 16); /* issue Load CAM command */ diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index 16191998ac6..2f8a8c32021 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c @@ -646,7 +646,7 @@ spider_net_set_multi(struct net_device *netdev) hash = spider_net_get_multicast_hash(netdev, netdev->broadcast); */ set_bit(0xfd, bitmask); - for (mc = netdev->mc_list; mc; mc = mc->next) { + netdev_for_each_mc_addr(mc, netdev) { hash = spider_net_get_multicast_hash(netdev, mc->dmi_addr); set_bit(hash, bitmask); } diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c index 58bc7ac086c..0f405ef5185 100644 --- a/drivers/net/starfire.c +++ b/drivers/net/starfire.c @@ -1804,14 +1804,14 @@ static void set_rx_mode(struct net_device *dev) /* Use the 16 element perfect filter, skip first two entries. */ void __iomem *filter_addr = ioaddr + PerfFilterTable + 2 * 16; __be16 *eaddrs; - for (i = 2, mclist = dev->mc_list; mclist && i < netdev_mc_count(dev) + 2; - i++, mclist = mclist->next) { + netdev_for_each_mc_addr(mclist, dev) { eaddrs = (__be16 *)mclist->dmi_addr; writew(be16_to_cpu(eaddrs[2]), filter_addr); filter_addr += 4; writew(be16_to_cpu(eaddrs[1]), filter_addr); filter_addr += 4; writew(be16_to_cpu(eaddrs[0]), filter_addr); filter_addr += 8; } eaddrs = (__be16 *)dev->dev_addr; + i = netdev_mc_count(dev) + 2; while (i++ < 16) { writew(be16_to_cpu(eaddrs[0]), filter_addr); filter_addr += 4; writew(be16_to_cpu(eaddrs[1]), filter_addr); filter_addr += 4; diff --git a/drivers/net/stmmac/dwmac100.c b/drivers/net/stmmac/dwmac100.c index 576b256ee38..803b0373d84 100644 --- a/drivers/net/stmmac/dwmac100.c +++ b/drivers/net/stmmac/dwmac100.c @@ -315,7 +315,6 @@ static void dwmac100_set_filter(struct net_device *dev) value &= ~(MAC_CONTROL_PM | MAC_CONTROL_PR | MAC_CONTROL_IF | MAC_CONTROL_HO | MAC_CONTROL_HP); } else { - int i; u32 mc_filter[2]; struct dev_mc_list *mclist; @@ -326,8 +325,7 @@ static void dwmac100_set_filter(struct net_device *dev) MAC_CONTROL_IF | MAC_CONTROL_HO); memset(mc_filter, 0, sizeof(mc_filter)); - for (i = 0, mclist = dev->mc_list; - mclist && i < netdev_mc_count(dev); i++, mclist = mclist->next) { + netdev_for_each_mc_addr(mclist, dev) { /* The upper 6 bits of the calculated CRC are used to * index the contens of the hash table */ int bit_nr = diff --git a/drivers/net/stmmac/dwmac1000_core.c b/drivers/net/stmmac/dwmac1000_core.c index 90dbb4f41ef..a6538ae4694 100644 --- a/drivers/net/stmmac/dwmac1000_core.c +++ b/drivers/net/stmmac/dwmac1000_core.c @@ -93,7 +93,6 @@ static void dwmac1000_set_filter(struct net_device *dev) writel(0xffffffff, ioaddr + GMAC_HASH_HIGH); writel(0xffffffff, ioaddr + GMAC_HASH_LOW); } else if (!netdev_mc_empty(dev)) { - int i; u32 mc_filter[2]; struct dev_mc_list *mclist; @@ -101,8 +100,7 @@ static void dwmac1000_set_filter(struct net_device *dev) value = GMAC_FRAME_FILTER_HMC; memset(mc_filter, 0, sizeof(mc_filter)); - for (i = 0, mclist = dev->mc_list; - mclist && i < netdev_mc_count(dev); i++, mclist = mclist->next) { + netdev_for_each_mc_addr(mclist, dev) { /* The upper 6 bits of the calculated CRC are used to index the contens of the hash table */ int bit_nr = diff --git a/drivers/net/sun3_82586.c b/drivers/net/sun3_82586.c index efedc252e4b..2f6a760e5f2 100644 --- a/drivers/net/sun3_82586.c +++ b/drivers/net/sun3_82586.c @@ -413,7 +413,7 @@ static int init586(struct net_device *dev) volatile struct iasetup_cmd_struct *ias_cmd; volatile struct tdr_cmd_struct *tdr_cmd; volatile struct mcsetup_cmd_struct *mc_cmd; - struct dev_mc_list *dmi=dev->mc_list; + struct dev_mc_list *dmi; int num_addrs=netdev_mc_count(dev); ptr = (void *) ((char *)p->scb + sizeof(struct scb_struct)); @@ -536,8 +536,10 @@ static int init586(struct net_device *dev) mc_cmd->cmd_link = 0xffff; mc_cmd->mc_cnt = swab16(num_addrs * 6); - for(i=0;i<num_addrs;i++,dmi=dmi->next) - memcpy((char *) mc_cmd->mc_list[i], dmi->dmi_addr,6); + i = 0; + netdev_for_each_mc_addr(dmi, dev) + memcpy((char *) mc_cmd->mc_list[i++], + dmi->dmi_addr, ETH_ALEN); p->scb->cbl_offset = make16(mc_cmd); p->scb->cmd_cuc = CUC_START; diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c index dfea56fa39e..a0bd361d5ec 100644 --- a/drivers/net/sunbmac.c +++ b/drivers/net/sunbmac.c @@ -999,7 +999,7 @@ static void bigmac_set_multicast(struct net_device *dev) { struct bigmac *bp = netdev_priv(dev); void __iomem *bregs = bp->bregs; - struct dev_mc_list *dmi = dev->mc_list; + struct dev_mc_list *dmi; char *addrs; int i; u32 tmp, crc; @@ -1028,9 +1028,8 @@ static void bigmac_set_multicast(struct net_device *dev) for (i = 0; i < 4; i++) hash_table[i] = 0; - for (i = 0; i < netdev_mc_count(dev); i++) { + netdev_for_each_mc_addr(dmi, dev) { addrs = dmi->dmi_addr; - dmi = dmi->next; if (!(*addrs & 1)) continue; diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c index 4171259590b..a855934dfc3 100644 --- a/drivers/net/sundance.c +++ b/drivers/net/sundance.c @@ -1528,8 +1528,7 @@ static void set_rx_mode(struct net_device *dev) int index; int crc; memset (mc_filter, 0, sizeof (mc_filter)); - for (i = 0, mclist = dev->mc_list; mclist && i < netdev_mc_count(dev); - i++, mclist = mclist->next) { + netdev_for_each_mc_addr(mclist, dev) { crc = ether_crc_le (ETH_ALEN, mclist->dmi_addr); for (index=0, bit=0; bit < 6; bit++, crc <<= 1) if (crc & 0x80000000) index |= 1 << bit; diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index d497ec05395..4344017bfae 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c @@ -1846,17 +1846,13 @@ static u32 gem_setup_multicast(struct gem *gp) } else { u16 hash_table[16]; u32 crc; - struct dev_mc_list *dmi = gp->dev->mc_list; + struct dev_mc_list *dmi; int i; - for (i = 0; i < 16; i++) - hash_table[i] = 0; - - for (i = 0; i < netdev_mc_count(gp->dev); i++) { + memset(hash_table, 0, sizeof(hash_table)); + netdev_for_each_mc_addr(dmi, gp->dev) { char *addrs = dmi->dmi_addr; - dmi = dmi->next; - if (!(*addrs & 1)) continue; diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index 905df35ff78..b17dbb11bd6 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c @@ -1523,17 +1523,13 @@ static int happy_meal_init(struct happy_meal *hp) hme_write32(hp, bregs + BMAC_HTABLE3, 0xffff); } else if ((hp->dev->flags & IFF_PROMISC) == 0) { u16 hash_table[4]; - struct dev_mc_list *dmi = hp->dev->mc_list; + struct dev_mc_list *dmi; char *addrs; - int i; u32 crc; - for (i = 0; i < 4; i++) - hash_table[i] = 0; - - for (i = 0; i < netdev_mc_count(hp->dev); i++) { + memset(hash_table, 0, sizeof(hash_table)); + netdev_for_each_mc_addr(dmi, hp->dev) { addrs = dmi->dmi_addr; - dmi = dmi->next; if (!(*addrs & 1)) continue; @@ -2366,9 +2362,8 @@ static void happy_meal_set_multicast(struct net_device *dev) { struct happy_meal *hp = netdev_priv(dev); void __iomem *bregs = hp->bigmacregs; - struct dev_mc_list *dmi = dev->mc_list; + struct dev_mc_list *dmi; char *addrs; - int i; u32 crc; spin_lock_irq(&hp->happy_lock); @@ -2384,12 +2379,9 @@ static void happy_meal_set_multicast(struct net_device *dev) } else { u16 hash_table[4]; - for (i = 0; i < 4; i++) - hash_table[i] = 0; - - for (i = 0; i < netdev_mc_count(dev); i++) { + memset(hash_table, 0, sizeof(hash_table)); + netdev_for_each_mc_addr(dmi, dev) { addrs = dmi->dmi_addr; - dmi = dmi->next; if (!(*addrs & 1)) continue; diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c index cf9d5bb9e1e..d7c73f478ef 100644 --- a/drivers/net/sunlance.c +++ b/drivers/net/sunlance.c @@ -1170,9 +1170,8 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev) static void lance_load_multicast(struct net_device *dev) { struct lance_private *lp = netdev_priv(dev); - struct dev_mc_list *dmi = dev->mc_list; + struct dev_mc_list *dmi; char *addrs; - int i; u32 crc; u32 val; @@ -1196,9 +1195,8 @@ static void lance_load_multicast(struct net_device *dev) return; /* Add addresses */ - for (i = 0; i < netdev_mc_count(dev); i++) { + netdev_for_each_mc_addr(dmi, dev) { addrs = dmi->dmi_addr; - dmi = dmi->next; /* multicast address? */ if (!(*addrs & 1)) diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c index 3bc35d86ed6..be637dce944 100644 --- a/drivers/net/sunqe.c +++ b/drivers/net/sunqe.c @@ -627,7 +627,7 @@ static int qe_start_xmit(struct sk_buff *skb, struct net_device *dev) static void qe_set_multicast(struct net_device *dev) { struct sunqe *qep = netdev_priv(dev); - struct dev_mc_list *dmi = dev->mc_list; + struct dev_mc_list *dmi; u8 new_mconfig = qep->mconfig; char *addrs; int i; @@ -650,12 +650,9 @@ static void qe_set_multicast(struct net_device *dev) u16 hash_table[4]; u8 *hbytes = (unsigned char *) &hash_table[0]; - for (i = 0; i < 4; i++) - hash_table[i] = 0; - - for (i = 0; i < netdev_mc_count(dev); i++) { + memset(hash_table, 0, sizeof(hash_table)); + netdev_for_each_mc_addr(dmi, dev) { addrs = dmi->dmi_addr; - dmi = dmi->next; if (!(*addrs & 1)) continue; diff --git a/drivers/net/sunvnet.c b/drivers/net/sunvnet.c index d65764ea1d8..6b1b7cea7f6 100644 --- a/drivers/net/sunvnet.c +++ b/drivers/net/sunvnet.c @@ -765,7 +765,7 @@ static void __update_mc_list(struct vnet *vp, struct net_device *dev) { struct dev_addr_list *p; - for (p = dev->mc_list; p; p = p->next) { + netdev_for_each_mc_addr(p, dev) { struct vnet_mcast_entry *m; m = __vnet_mc_find(vp, p->dmi_addr); diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index ddf66155f5e..f204f73c4f9 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -67,7 +67,6 @@ #include "tg3.h" #define DRV_MODULE_NAME "tg3" -#define PFX DRV_MODULE_NAME ": " #define DRV_MODULE_VERSION "3.108" #define DRV_MODULE_RELDATE "February 17, 2010" @@ -158,7 +157,7 @@ #define FIRMWARE_TG3TSO5 "tigon/tg3_tso5.bin" static char version[] __devinitdata = - DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; + DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")"; MODULE_AUTHOR("David S. Miller (davem@redhat.com) and Jeff Garzik (jgarzik@pobox.com)"); MODULE_DESCRIPTION("Broadcom Tigon3 ethernet driver"); @@ -1099,8 +1098,7 @@ static int tg3_mdio_init(struct tg3 *tp) i = mdiobus_register(tp->mdio_bus); if (i) { - printk(KERN_WARNING "%s: mdiobus_reg failed (0x%x)\n", - tp->dev->name, i); + netdev_warn(tp->dev, "mdiobus_reg failed (0x%x)\n", i); mdiobus_free(tp->mdio_bus); return i; } @@ -1108,7 +1106,7 @@ static int tg3_mdio_init(struct tg3 *tp) phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]; if (!phydev || !phydev->drv) { - printk(KERN_WARNING "%s: No PHY devices\n", tp->dev->name); + netdev_warn(tp->dev, "No PHY devices\n"); mdiobus_unregister(tp->mdio_bus); mdiobus_free(tp->mdio_bus); return -ENODEV; @@ -1252,27 +1250,22 @@ static void tg3_ump_link_report(struct tg3 *tp) static void tg3_link_report(struct tg3 *tp) { if (!netif_carrier_ok(tp->dev)) { - if (netif_msg_link(tp)) - printk(KERN_INFO PFX "%s: Link is down.\n", - tp->dev->name); + netif_info(tp, link, tp->dev, "Link is down\n"); tg3_ump_link_report(tp); } else if (netif_msg_link(tp)) { - printk(KERN_INFO PFX "%s: Link is up at %d Mbps, %s duplex.\n", - tp->dev->name, - (tp->link_config.active_speed == SPEED_1000 ? - 1000 : - (tp->link_config.active_speed == SPEED_100 ? - 100 : 10)), - (tp->link_config.active_duplex == DUPLEX_FULL ? - "full" : "half")); - - printk(KERN_INFO PFX - "%s: Flow control is %s for TX and %s for RX.\n", - tp->dev->name, - (tp->link_config.active_flowctrl & FLOW_CTRL_TX) ? - "on" : "off", - (tp->link_config.active_flowctrl & FLOW_CTRL_RX) ? - "on" : "off"); + netdev_info(tp->dev, "Link is up at %d Mbps, %s duplex\n", + (tp->link_config.active_speed == SPEED_1000 ? + 1000 : + (tp->link_config.active_speed == SPEED_100 ? + 100 : 10)), + (tp->link_config.active_duplex == DUPLEX_FULL ? + "full" : "half")); + + netdev_info(tp->dev, "Flow control is %s for TX and %s for RX\n", + (tp->link_config.active_flowctrl & FLOW_CTRL_TX) ? + "on" : "off", + (tp->link_config.active_flowctrl & FLOW_CTRL_RX) ? + "on" : "off"); tg3_ump_link_report(tp); } } @@ -1471,7 +1464,7 @@ static int tg3_phy_init(struct tg3 *tp) phydev = phy_connect(tp->dev, dev_name(&phydev->dev), tg3_adjust_link, phydev->dev_flags, phydev->interface); if (IS_ERR(phydev)) { - printk(KERN_ERR "%s: Could not attach to PHY\n", tp->dev->name); + netdev_err(tp->dev, "Could not attach to PHY\n"); return PTR_ERR(phydev); } @@ -2500,8 +2493,8 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) break; default: - printk(KERN_ERR PFX "%s: Invalid power state (D%d) requested\n", - tp->dev->name, state); + netdev_err(tp->dev, "Invalid power state (D%d) requested\n", + state); return -EINVAL; } @@ -4342,10 +4335,8 @@ static void tg3_tx_recover(struct tg3 *tp) BUG_ON((tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) || tp->write32_tx_mbox == tg3_write_indirect_mbox); - printk(KERN_WARNING PFX "%s: The system may be re-ordering memory-" - "mapped I/O cycles to the network device, attempting to " - "recover. Please report the problem to the driver maintainer " - "and include system chipset information.\n", tp->dev->name); + netdev_warn(tp->dev, "The system may be re-ordering memory-mapped I/O cycles to the network device, attempting to recover\n" + "Please report the problem to the driver maintainer and include system chipset information.\n"); spin_lock(&tp->lock); tp->tg3_flags |= TG3_FLAG_TX_RECOVERY_PENDING; @@ -5269,8 +5260,7 @@ static int tg3_restart_hw(struct tg3 *tp, int reset_phy) err = tg3_init_hw(tp, reset_phy); if (err) { - printk(KERN_ERR PFX "%s: Failed to re-initialize device, " - "aborting.\n", tp->dev->name); + netdev_err(tp->dev, "Failed to re-initialize device, aborting\n"); tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); tg3_full_unlock(tp); del_timer_sync(&tp->timer); @@ -5343,10 +5333,10 @@ out: static void tg3_dump_short_state(struct tg3 *tp) { - printk(KERN_ERR PFX "DEBUG: MAC_TX_STATUS[%08x] MAC_RX_STATUS[%08x]\n", - tr32(MAC_TX_STATUS), tr32(MAC_RX_STATUS)); - printk(KERN_ERR PFX "DEBUG: RDMAC_STATUS[%08x] WDMAC_STATUS[%08x]\n", - tr32(RDMAC_STATUS), tr32(WDMAC_STATUS)); + netdev_err(tp->dev, "DEBUG: MAC_TX_STATUS[%08x] MAC_RX_STATUS[%08x]\n", + tr32(MAC_TX_STATUS), tr32(MAC_RX_STATUS)); + netdev_err(tp->dev, "DEBUG: RDMAC_STATUS[%08x] WDMAC_STATUS[%08x]\n", + tr32(RDMAC_STATUS), tr32(WDMAC_STATUS)); } static void tg3_tx_timeout(struct net_device *dev) @@ -5354,8 +5344,7 @@ static void tg3_tx_timeout(struct net_device *dev) struct tg3 *tp = netdev_priv(dev); if (netif_msg_tx_err(tp)) { - printk(KERN_ERR PFX "%s: transmit timed out, resetting\n", - dev->name); + netdev_err(dev, "transmit timed out, resetting\n"); tg3_dump_short_state(tp); } @@ -5519,8 +5508,7 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, netif_tx_stop_queue(txq); /* This is a hard error, log it. */ - printk(KERN_ERR PFX "%s: BUG! Tx Ring full when " - "queue awake!\n", dev->name); + netdev_err(dev, "BUG! Tx Ring full when queue awake!\n"); } return NETDEV_TX_BUSY; } @@ -5723,8 +5711,7 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb, netif_tx_stop_queue(txq); /* This is a hard error, log it. */ - printk(KERN_ERR PFX "%s: BUG! Tx Ring full when " - "queue awake!\n", dev->name); + netdev_err(dev, "BUG! Tx Ring full when queue awake!\n"); } return NETDEV_TX_BUSY; } @@ -6071,11 +6058,8 @@ static int tg3_rx_prodring_alloc(struct tg3 *tp, /* Now allocate fresh SKBs for each rx ring. */ for (i = 0; i < tp->rx_pending; i++) { if (tg3_alloc_rx_skb(tp, tpr, RXD_OPAQUE_RING_STD, i) < 0) { - printk(KERN_WARNING PFX - "%s: Using a smaller RX standard ring, " - "only %d out of %d buffers were allocated " - "successfully.\n", - tp->dev->name, i, tp->rx_pending); + netdev_warn(tp->dev, "Using a smaller RX standard ring, only %d out of %d buffers were allocated successfully\n", + i, tp->rx_pending); if (i == 0) goto initfail; tp->rx_pending = i; @@ -6104,11 +6088,8 @@ static int tg3_rx_prodring_alloc(struct tg3 *tp, for (i = 0; i < tp->rx_jumbo_pending; i++) { if (tg3_alloc_rx_skb(tp, tpr, RXD_OPAQUE_RING_JUMBO, i) < 0) { - printk(KERN_WARNING PFX - "%s: Using a smaller RX jumbo ring, " - "only %d out of %d buffers were " - "allocated successfully.\n", - tp->dev->name, i, tp->rx_jumbo_pending); + netdev_warn(tp->dev, "Using a smaller RX jumbo ring, only %d out of %d buffers were allocated successfully\n", + i, tp->rx_jumbo_pending); if (i == 0) goto initfail; tp->rx_jumbo_pending = i; @@ -6452,8 +6433,7 @@ static int tg3_stop_block(struct tg3 *tp, unsigned long ofs, u32 enable_bit, int } if (i == MAX_WAIT_CNT && !silent) { - printk(KERN_ERR PFX "tg3_stop_block timed out, " - "ofs=%lx enable_bit=%x\n", + pr_err("tg3_stop_block timed out, ofs=%lx enable_bit=%x\n", ofs, enable_bit); return -ENODEV; } @@ -6500,9 +6480,8 @@ static int tg3_abort_hw(struct tg3 *tp, int silent) break; } if (i >= MAX_WAIT_CNT) { - printk(KERN_ERR PFX "tg3_abort_hw timed out for %s, " - "TX_MODE_ENABLE will not clear MAC_TX_MODE=%08x\n", - tp->dev->name, tr32(MAC_TX_MODE)); + netdev_err(tp->dev, "%s timed out, TX_MODE_ENABLE will not clear MAC_TX_MODE=%08x\n", + __func__, tr32(MAC_TX_MODE)); err |= -ENODEV; } @@ -6723,8 +6702,7 @@ static int tg3_poll_fw(struct tg3 *tp) !(tp->tg3_flags2 & TG3_FLG2_NO_FWARE_REPORTED)) { tp->tg3_flags2 |= TG3_FLG2_NO_FWARE_REPORTED; - printk(KERN_INFO PFX "%s: No firmware running.\n", - tp->dev->name); + netdev_info(tp->dev, "No firmware running\n"); } if (tp->pci_chip_rev_id == CHIPREV_ID_57765_A0) { @@ -7152,10 +7130,8 @@ static int tg3_halt_cpu(struct tg3 *tp, u32 offset) } if (i >= 10000) { - printk(KERN_ERR PFX "tg3_reset_cpu timed out for %s, " - "and %s CPU\n", - tp->dev->name, - (offset == RX_CPU_BASE ? "RX" : "TX")); + netdev_err(tp->dev, "%s timed out, %s CPU\n", + __func__, offset == RX_CPU_BASE ? "RX" : "TX"); return -ENODEV; } @@ -7180,9 +7156,8 @@ static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_b if (cpu_base == TX_CPU_BASE && (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { - printk(KERN_ERR PFX "tg3_load_firmware_cpu: Trying to load " - "TX cpu firmware on %s which is 5705.\n", - tp->dev->name); + netdev_err(tp->dev, "%s: Trying to load TX cpu firmware which is 5705\n", + __func__); return -EINVAL; } @@ -7261,10 +7236,8 @@ static int tg3_load_5701_a0_firmware_fix(struct tg3 *tp) udelay(1000); } if (i >= 5) { - printk(KERN_ERR PFX "tg3_load_firmware fails for %s " - "to set RX CPU PC, is %08x should be %08x\n", - tp->dev->name, tr32(RX_CPU_BASE + CPU_PC), - info.fw_base); + netdev_err(tp->dev, "tg3_load_firmware fails to set RX CPU PC, is %08x should be %08x\n", + tr32(RX_CPU_BASE + CPU_PC), info.fw_base); return -ENODEV; } tw32(RX_CPU_BASE + CPU_STATE, 0xffffffff); @@ -7327,10 +7300,8 @@ static int tg3_load_tso_firmware(struct tg3 *tp) udelay(1000); } if (i >= 5) { - printk(KERN_ERR PFX "tg3_load_tso_firmware fails for %s " - "to set CPU PC, is %08x should be %08x\n", - tp->dev->name, tr32(cpu_base + CPU_PC), - info.fw_base); + netdev_err(tp->dev, "%s fails to set CPU PC, is %08x should be %08x\n", + __func__, tr32(cpu_base + CPU_PC), info.fw_base); return -ENODEV; } tw32(cpu_base + CPU_STATE, 0xffffffff); @@ -7791,8 +7762,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) udelay(10); } if (i >= 2000) { - printk(KERN_ERR PFX "tg3_reset_hw cannot enable BUFMGR for %s.\n", - tp->dev->name); + netdev_err(tp->dev, "%s cannot enable BUFMGR\n", __func__); return -ENODEV; } @@ -8655,10 +8625,8 @@ static int tg3_test_msi(struct tg3 *tp) return err; /* MSI test failed, go back to INTx mode */ - printk(KERN_WARNING PFX "%s: No interrupt was generated using MSI, " - "switching to INTx mode. Please report this failure to " - "the PCI maintainer and include system chipset information.\n", - tp->dev->name); + netdev_warn(tp->dev, "No interrupt was generated using MSI, switching to INTx mode\n" + "Please report this failure to the PCI maintainer and include system chipset information\n"); free_irq(tp->napi[0].irq_vec, &tp->napi[0]); @@ -8691,8 +8659,8 @@ static int tg3_request_firmware(struct tg3 *tp) const __be32 *fw_data; if (request_firmware(&tp->fw, tp->fw_needed, &tp->pdev->dev)) { - printk(KERN_ERR "%s: Failed to load firmware \"%s\"\n", - tp->dev->name, tp->fw_needed); + netdev_err(tp->dev, "Failed to load firmware \"%s\"\n", + tp->fw_needed); return -ENOENT; } @@ -8705,8 +8673,8 @@ static int tg3_request_firmware(struct tg3 *tp) tp->fw_len = be32_to_cpu(fw_data[2]); /* includes bss */ if (tp->fw_len < (tp->fw->size - 12)) { - printk(KERN_ERR "%s: bogus length %d in \"%s\"\n", - tp->dev->name, tp->fw_len, tp->fw_needed); + netdev_err(tp->dev, "bogus length %d in \"%s\"\n", + tp->fw_len, tp->fw_needed); release_firmware(tp->fw); tp->fw = NULL; return -EINVAL; @@ -8744,9 +8712,8 @@ static bool tg3_enable_msix(struct tg3 *tp) return false; if (pci_enable_msix(tp->pdev, msix_ent, rc)) return false; - printk(KERN_NOTICE - "%s: Requested %d MSI-X vectors, received %d\n", - tp->dev->name, tp->irq_cnt, rc); + netdev_notice(tp->dev, "Requested %d MSI-X vectors, received %d\n", + tp->irq_cnt, rc); tp->irq_cnt = rc; } @@ -8771,8 +8738,7 @@ static void tg3_ints_init(struct tg3 *tp) /* All MSI supporting chips should support tagged * status. Assert that this is the case. */ - printk(KERN_WARNING PFX "%s: MSI without TAGGED? " - "Not using MSI.\n", tp->dev->name); + netdev_warn(tp->dev, "MSI without TAGGED? Not using MSI\n"); goto defcfg; } @@ -8817,12 +8783,10 @@ static int tg3_open(struct net_device *dev) if (err) return err; } else if (err) { - printk(KERN_WARNING "%s: TSO capability disabled.\n", - tp->dev->name); + netdev_warn(tp->dev, "TSO capability disabled\n"); tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE; } else if (!(tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE)) { - printk(KERN_NOTICE "%s: TSO capability restored.\n", - tp->dev->name); + netdev_notice(tp->dev, "TSO capability restored\n"); tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE; } } @@ -10687,8 +10651,7 @@ static int tg3_test_registers(struct tg3 *tp) out: if (netif_msg_hw(tp)) - printk(KERN_ERR PFX "Register test failed at offset %x\n", - offset); + pr_err("Register test failed at offset %x\n", offset); tw32(offset, save_val); return -EIO; } @@ -11815,8 +11778,8 @@ static void __devinit tg3_nvram_init(struct tg3 *tp) tp->tg3_flags |= TG3_FLAG_NVRAM; if (tg3_nvram_lock(tp)) { - printk(KERN_WARNING PFX "%s: Cannot get nvarm lock, " - "tg3_nvram_init failed.\n", tp->dev->name); + netdev_warn(tp->dev, "Cannot get nvram lock, %s failed\n", + __func__); return; } tg3_enable_nvram_access(tp); @@ -13280,8 +13243,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) { tp->pcix_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_PCIX); if (!tp->pcix_cap) { - printk(KERN_ERR PFX "Cannot find PCI-X " - "capability, aborting.\n"); + pr_err("Cannot find PCI-X capability, aborting\n"); return -EIO; } @@ -13478,8 +13440,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) /* Force the chip into D0. */ err = tg3_set_power_state(tp, PCI_D0); if (err) { - printk(KERN_ERR PFX "(%s) transition to D0 failed\n", - pci_name(tp->pdev)); + pr_err("(%s) transition to D0 failed\n", pci_name(tp->pdev)); return err; } @@ -13653,7 +13614,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) err = tg3_phy_probe(tp); if (err) { - printk(KERN_ERR PFX "(%s) phy probe failed, err %d\n", + pr_err("(%s) phy probe failed, err %d\n", pci_name(tp->pdev), err); /* ... but do not return immediately ... */ tg3_mdio_fini(tp); @@ -14163,7 +14124,8 @@ static int __devinit tg3_test_dma(struct tg3 *tp) /* Send the buffer to the chip. */ ret = tg3_do_test_dma(tp, buf, buf_dma, TEST_BUFFER_SIZE, 1); if (ret) { - printk(KERN_ERR "tg3_test_dma() Write the buffer failed %d\n", ret); + pr_err("tg3_test_dma() Write the buffer failed %d\n", + ret); break; } @@ -14173,7 +14135,8 @@ static int __devinit tg3_test_dma(struct tg3 *tp) u32 val; tg3_read_mem(tp, 0x2100 + (i*4), &val); if (le32_to_cpu(val) != p[i]) { - printk(KERN_ERR " tg3_test_dma() Card buffer corrupted on write! (%d != %d)\n", val, i); + pr_err(" tg3_test_dma() Card buffer corrupted on write! (%d != %d)\n", + val, i); /* ret = -ENODEV here? */ } p[i] = 0; @@ -14182,7 +14145,8 @@ static int __devinit tg3_test_dma(struct tg3 *tp) /* Now read it back. */ ret = tg3_do_test_dma(tp, buf, buf_dma, TEST_BUFFER_SIZE, 0); if (ret) { - printk(KERN_ERR "tg3_test_dma() Read the buffer failed %d\n", ret); + pr_err("tg3_test_dma() Read the buffer failed %d\n", + ret); break; } @@ -14199,7 +14163,8 @@ static int __devinit tg3_test_dma(struct tg3 *tp) tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl); break; } else { - printk(KERN_ERR "tg3_test_dma() buffer corrupted on read back! (%d != %d)\n", p[i], i); + pr_err("tg3_test_dma() buffer corrupted on read back! (%d != %d)\n", + p[i], i); ret = -ENODEV; goto out; } @@ -14480,7 +14445,6 @@ static const struct net_device_ops tg3_netdev_ops_dma_bug = { static int __devinit tg3_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { - static int tg3_version_printed = 0; struct net_device *dev; struct tg3 *tp; int i, err, pm_cap; @@ -14488,20 +14452,17 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, char str[40]; u64 dma_mask, persist_dma_mask; - if (tg3_version_printed++ == 0) - printk(KERN_INFO "%s", version); + printk_once(KERN_INFO "%s\n", version); err = pci_enable_device(pdev); if (err) { - printk(KERN_ERR PFX "Cannot enable PCI device, " - "aborting.\n"); + pr_err("Cannot enable PCI device, aborting\n"); return err; } err = pci_request_regions(pdev, DRV_MODULE_NAME); if (err) { - printk(KERN_ERR PFX "Cannot obtain PCI resources, " - "aborting.\n"); + pr_err("Cannot obtain PCI resources, aborting\n"); goto err_out_disable_pdev; } @@ -14510,15 +14471,14 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, /* Find power-management capability. */ pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM); if (pm_cap == 0) { - printk(KERN_ERR PFX "Cannot find PowerManagement capability, " - "aborting.\n"); + pr_err("Cannot find PowerManagement capability, aborting\n"); err = -EIO; goto err_out_free_res; } dev = alloc_etherdev_mq(sizeof(*tp), TG3_IRQ_MAX_VECS); if (!dev) { - printk(KERN_ERR PFX "Etherdev alloc failed, aborting.\n"); + pr_err("Etherdev alloc failed, aborting\n"); err = -ENOMEM; goto err_out_free_res; } @@ -14568,8 +14528,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, tp->regs = pci_ioremap_bar(pdev, BAR_0); if (!tp->regs) { - printk(KERN_ERR PFX "Cannot map device registers, " - "aborting.\n"); + netdev_err(dev, "Cannot map device registers, aborting\n"); err = -ENOMEM; goto err_out_free_dev; } @@ -14585,8 +14544,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, err = tg3_get_invariants(tp); if (err) { - printk(KERN_ERR PFX "Problem fetching invariants of chip, " - "aborting.\n"); + netdev_err(dev, "Problem fetching invariants of chip, aborting\n"); goto err_out_iounmap; } @@ -14621,8 +14579,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, err = pci_set_consistent_dma_mask(pdev, persist_dma_mask); if (err < 0) { - printk(KERN_ERR PFX "Unable to obtain 64 bit " - "DMA for consistent allocations\n"); + netdev_err(dev, "Unable to obtain 64 bit DMA for consistent allocations\n"); goto err_out_iounmap; } } @@ -14630,8 +14587,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, if (err || dma_mask == DMA_BIT_MASK(32)) { err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); if (err) { - printk(KERN_ERR PFX "No usable DMA configuration, " - "aborting.\n"); + netdev_err(dev, "No usable DMA configuration, aborting\n"); goto err_out_iounmap; } } @@ -14680,16 +14636,14 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, err = tg3_get_device_address(tp); if (err) { - printk(KERN_ERR PFX "Could not obtain valid ethernet address, " - "aborting.\n"); + netdev_err(dev, "Could not obtain valid ethernet address, aborting\n"); goto err_out_iounmap; } if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) { tp->aperegs = pci_ioremap_bar(pdev, BAR_2); if (!tp->aperegs) { - printk(KERN_ERR PFX "Cannot map APE registers, " - "aborting.\n"); + netdev_err(dev, "Cannot map APE registers, aborting\n"); err = -ENOMEM; goto err_out_iounmap; } @@ -14713,7 +14667,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, err = tg3_test_dma(tp); if (err) { - printk(KERN_ERR PFX "DMA engine test failed, aborting.\n"); + netdev_err(dev, "DMA engine test failed, aborting\n"); goto err_out_apeunmap; } @@ -14774,45 +14728,39 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, err = register_netdev(dev); if (err) { - printk(KERN_ERR PFX "Cannot register net device, " - "aborting.\n"); + netdev_err(dev, "Cannot register net device, aborting\n"); goto err_out_apeunmap; } - printk(KERN_INFO "%s: Tigon3 [partno(%s) rev %04x] (%s) MAC address %pM\n", - dev->name, - tp->board_part_number, - tp->pci_chip_rev_id, - tg3_bus_string(tp, str), - dev->dev_addr); + netdev_info(dev, "Tigon3 [partno(%s) rev %04x] (%s) MAC address %pM\n", + tp->board_part_number, + tp->pci_chip_rev_id, + tg3_bus_string(tp, str), + dev->dev_addr); if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) { struct phy_device *phydev; phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]; - printk(KERN_INFO - "%s: attached PHY driver [%s] (mii_bus:phy_addr=%s)\n", - tp->dev->name, phydev->drv->name, - dev_name(&phydev->dev)); + netdev_info(dev, "attached PHY driver [%s] (mii_bus:phy_addr=%s)\n", + phydev->drv->name, dev_name(&phydev->dev)); } else - printk(KERN_INFO - "%s: attached PHY is %s (%s Ethernet) (WireSpeed[%d])\n", - tp->dev->name, tg3_phy_string(tp), - ((tp->tg3_flags & TG3_FLAG_10_100_ONLY) ? "10/100Base-TX" : - ((tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) ? "1000Base-SX" : - "10/100/1000Base-T")), - (tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED) == 0); - - printk(KERN_INFO "%s: RXcsums[%d] LinkChgREG[%d] MIirq[%d] ASF[%d] TSOcap[%d]\n", - dev->name, - (tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) != 0, - (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) != 0, - (tp->tg3_flags & TG3_FLAG_USE_MI_INTERRUPT) != 0, - (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0, - (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) != 0); - printk(KERN_INFO "%s: dma_rwctrl[%08x] dma_mask[%d-bit]\n", - dev->name, tp->dma_rwctrl, - (pdev->dma_mask == DMA_BIT_MASK(32)) ? 32 : - (((u64) pdev->dma_mask == DMA_BIT_MASK(40)) ? 40 : 64)); + netdev_info(dev, "attached PHY is %s (%s Ethernet) (WireSpeed[%d])\n", + tg3_phy_string(tp), + ((tp->tg3_flags & TG3_FLAG_10_100_ONLY) ? "10/100Base-TX" : + ((tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) ? "1000Base-SX" : + "10/100/1000Base-T")), + (tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED) == 0); + + netdev_info(dev, "RXcsums[%d] LinkChgREG[%d] MIirq[%d] ASF[%d] TSOcap[%d]\n", + (tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) != 0, + (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) != 0, + (tp->tg3_flags & TG3_FLAG_USE_MI_INTERRUPT) != 0, + (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0, + (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) != 0); + netdev_info(dev, "dma_rwctrl[%08x] dma_mask[%d-bit]\n", + tp->dma_rwctrl, + pdev->dma_mask == DMA_BIT_MASK(32) ? 32 : + ((u64)pdev->dma_mask) == DMA_BIT_MASK(40) ? 40 : 64); return 0; diff --git a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c index eff68e1d107..0fb930feea4 100644 --- a/drivers/net/tokenring/3c359.c +++ b/drivers/net/tokenring/3c359.c @@ -1390,10 +1390,9 @@ static int xl_close(struct net_device *dev) static void xl_set_rx_mode(struct net_device *dev) { struct xl_private *xl_priv = netdev_priv(dev); - struct dev_mc_list *dmi ; + struct dev_mc_list *dmi; unsigned char dev_mc_address[4] ; u16 options ; - int i ; if (dev->flags & IFF_PROMISC) options = 0x0004 ; @@ -1408,7 +1407,7 @@ static void xl_set_rx_mode(struct net_device *dev) dev_mc_address[0] = dev_mc_address[1] = dev_mc_address[2] = dev_mc_address[3] = 0 ; - for (i=0,dmi=dev->mc_list;i < netdev_mc_count(dev); i++,dmi = dmi->next) { + netdev_for_each_mc_addr(dmi, dev) { dev_mc_address[0] |= dmi->dmi_addr[2] ; dev_mc_address[1] |= dmi->dmi_addr[3] ; dev_mc_address[2] |= dmi->dmi_addr[4] ; diff --git a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c index 1ce8f85a89a..1a0967246e2 100644 --- a/drivers/net/tokenring/ibmtr.c +++ b/drivers/net/tokenring/ibmtr.c @@ -995,13 +995,11 @@ static void tok_set_multicast_list(struct net_device *dev) /*BMS ifconfig tr down or hot unplug a PCMCIA card ??hownowbrowncow*/ if (/*BMSHELPdev->start == 0 ||*/ ti->open_status != OPEN) return; address[0] = address[1] = address[2] = address[3] = 0; - mclist = dev->mc_list; - for (i = 0; i < netdev_mc_count(dev); i++) { + netdev_for_each_mc_addr(mclist, dev) { address[0] |= mclist->dmi_addr[2]; address[1] |= mclist->dmi_addr[3]; address[2] |= mclist->dmi_addr[4]; address[3] |= mclist->dmi_addr[5]; - mclist = mclist->next; } SET_PAGE(ti->srb_page); for (i = 0; i < sizeof(struct srb_set_funct_addr); i++) diff --git a/drivers/net/tokenring/lanstreamer.c b/drivers/net/tokenring/lanstreamer.c index 26d84daf660..dd028fee9dc 100644 --- a/drivers/net/tokenring/lanstreamer.c +++ b/drivers/net/tokenring/lanstreamer.c @@ -1268,7 +1268,6 @@ static void streamer_set_rx_mode(struct net_device *dev) __u8 options = 0; struct dev_mc_list *dmi; unsigned char dev_mc_address[5]; - int i; writel(streamer_priv->srb, streamer_mmio + LAPA); options = streamer_priv->streamer_copy_all_options; @@ -1303,8 +1302,7 @@ static void streamer_set_rx_mode(struct net_device *dev) writel(streamer_priv->srb,streamer_mmio+LAPA); dev_mc_address[0] = dev_mc_address[1] = dev_mc_address[2] = dev_mc_address[3] = 0 ; - for (i=0,dmi=dev->mc_list;i < netdev_mc_count(dev); i++,dmi = dmi->next) - { + netdev_for_each_mc_addr(dmi, dev) { dev_mc_address[0] |= dmi->dmi_addr[2] ; dev_mc_address[1] |= dmi->dmi_addr[3] ; dev_mc_address[2] |= dmi->dmi_addr[4] ; diff --git a/drivers/net/tokenring/olympic.c b/drivers/net/tokenring/olympic.c index a242d125b34..3a25e0434ae 100644 --- a/drivers/net/tokenring/olympic.c +++ b/drivers/net/tokenring/olympic.c @@ -1139,9 +1139,8 @@ static void olympic_set_rx_mode(struct net_device *dev) u8 __iomem *olympic_mmio = olympic_priv->olympic_mmio ; u8 options = 0; u8 __iomem *srb; - struct dev_mc_list *dmi ; + struct dev_mc_list *dmi; unsigned char dev_mc_address[4] ; - int i ; writel(olympic_priv->srb,olympic_mmio+LAPA); srb=olympic_priv->olympic_lap + (olympic_priv->srb & (~0xf800)); @@ -1178,7 +1177,7 @@ static void olympic_set_rx_mode(struct net_device *dev) dev_mc_address[0] = dev_mc_address[1] = dev_mc_address[2] = dev_mc_address[3] = 0 ; - for (i=0,dmi=dev->mc_list;i < netdev_mc_count(dev); i++,dmi = dmi->next) { + netdev_for_each_mc_addr(dmi, dev) { dev_mc_address[0] |= dmi->dmi_addr[2] ; dev_mc_address[1] |= dmi->dmi_addr[3] ; dev_mc_address[2] |= dmi->dmi_addr[4] ; diff --git a/drivers/net/tokenring/tms380tr.c b/drivers/net/tokenring/tms380tr.c index 6b8868959b8..21a01753312 100644 --- a/drivers/net/tokenring/tms380tr.c +++ b/drivers/net/tokenring/tms380tr.c @@ -1212,10 +1212,9 @@ static void tms380tr_set_multicast_list(struct net_device *dev) } else { - int i; - struct dev_mc_list *mclist = dev->mc_list; - for (i=0; i< netdev_mc_count(dev); i++) - { + struct dev_mc_list *mclist; + + netdev_for_each_mc_addr(mclist, dev) { ((char *)(&tp->ocpl.FunctAddr))[0] |= mclist->dmi_addr[2]; ((char *)(&tp->ocpl.FunctAddr))[1] |= @@ -1224,7 +1223,6 @@ static void tms380tr_set_multicast_list(struct net_device *dev) mclist->dmi_addr[4]; ((char *)(&tp->ocpl.FunctAddr))[3] |= mclist->dmi_addr[5]; - mclist = mclist->next; } } tms380tr_exec_cmd(dev, OC_SET_FUNCT_ADDR); diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index a4cff23dcdf..cb429723b2c 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c @@ -677,18 +677,17 @@ static void build_setup_frame_hash(u16 *setup_frm, struct net_device *dev) memset(hash_table, 0, sizeof(hash_table)); set_bit_le(255, hash_table); /* Broadcast entry */ /* This should work on big-endian machines as well. */ - for (i = 0, mclist = dev->mc_list; mclist && i < netdev_mc_count(dev); - i++, mclist = mclist->next) { + netdev_for_each_mc_addr(mclist, dev) { int index = ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x1ff; set_bit_le(index, hash_table); + } - for (i = 0; i < 32; i++) { - *setup_frm++ = hash_table[i]; - *setup_frm++ = hash_table[i]; - } - setup_frm = &de->setup_frame[13*6]; + for (i = 0; i < 32; i++) { + *setup_frm++ = hash_table[i]; + *setup_frm++ = hash_table[i]; } + setup_frm = &de->setup_frame[13*6]; /* Fill the final entry with our physical address. */ eaddrs = (u16 *)dev->dev_addr; @@ -701,20 +700,18 @@ static void build_setup_frame_perfect(u16 *setup_frm, struct net_device *dev) { struct de_private *de = netdev_priv(dev); struct dev_mc_list *mclist; - int i; u16 *eaddrs; /* We have <= 14 addresses so we can use the wonderful 16 address perfect filtering of the Tulip. */ - for (i = 0, mclist = dev->mc_list; i < netdev_mc_count(dev); - i++, mclist = mclist->next) { + netdev_for_each_mc_addr(mclist, dev) { eaddrs = (u16 *)mclist->dmi_addr; *setup_frm++ = *eaddrs; *setup_frm++ = *eaddrs++; *setup_frm++ = *eaddrs; *setup_frm++ = *eaddrs++; *setup_frm++ = *eaddrs; *setup_frm++ = *eaddrs++; } /* Fill the unused entries with the broadcast address. */ - memset(setup_frm, 0xff, (15-i)*12); + memset(setup_frm, 0xff, (15 - netdev_mc_count(dev)) * 12); setup_frm = &de->setup_frame[15*6]; /* Fill the final entry with our physical address. */ diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c index 0b6a9731091..c4ecb9a9540 100644 --- a/drivers/net/tulip/de4x5.c +++ b/drivers/net/tulip/de4x5.c @@ -1951,9 +1951,9 @@ static void SetMulticastFilter(struct net_device *dev) { struct de4x5_private *lp = netdev_priv(dev); - struct dev_mc_list *dmi=dev->mc_list; + struct dev_mc_list *dmi; u_long iobase = dev->base_addr; - int i, j, bit, byte; + int i, bit, byte; u16 hashcode; u32 omr, crc; char *pa; @@ -1966,9 +1966,8 @@ SetMulticastFilter(struct net_device *dev) if ((dev->flags & IFF_ALLMULTI) || (netdev_mc_count(dev) > 14)) { omr |= OMR_PM; /* Pass all multicasts */ } else if (lp->setup_f == HASH_PERF) { /* Hash Filtering */ - for (i = 0; i < netdev_mc_count(dev) ;i++) { - addrs=dmi->dmi_addr; - dmi=dmi->next; + netdev_for_each_mc_addr(dmi, dev) { + addrs = dmi->dmi_addr; if ((*addrs & 0x01) == 1) { /* multicast address? */ crc = ether_crc_le(ETH_ALEN, addrs); hashcode = crc & HASH_BITS; /* hashcode is 9 LSb of CRC */ @@ -1984,9 +1983,8 @@ SetMulticastFilter(struct net_device *dev) } } } else { /* Perfect filtering */ - for (j=0; j<netdev_mc_count(dev); j++) { - addrs=dmi->dmi_addr; - dmi=dmi->next; + netdev_for_each_mc_addr(dmi, dev) { + addrs = dmi->dmi_addr; for (i=0; i<ETH_ALEN; i++) { *(pa + (i&1)) = *addrs++; if (i & 0x01) pa += 4; diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c index 534afbdb9c9..95b38d803e9 100644 --- a/drivers/net/tulip/dmfe.c +++ b/drivers/net/tulip/dmfe.c @@ -330,8 +330,8 @@ static void poll_dmfe (struct net_device *dev); static void dmfe_descriptor_init(struct dmfe_board_info *, unsigned long); static void allocate_rx_buffer(struct dmfe_board_info *); static void update_cr6(u32, unsigned long); -static void send_filter_frame(struct DEVICE * ,int); -static void dm9132_id_table(struct DEVICE * ,int); +static void send_filter_frame(struct DEVICE *); +static void dm9132_id_table(struct DEVICE *); static u16 phy_read(unsigned long, u8, u8, u32); static void phy_write(unsigned long, u8, u8, u16, u32); static void phy_write_1bit(unsigned long, u32); @@ -658,9 +658,9 @@ static void dmfe_init_dm910x(struct DEVICE *dev) /* Send setup frame */ if (db->chip_id == PCI_DM9132_ID) - dm9132_id_table(dev, netdev_mc_count(dev)); /* DM9132 */ + dm9132_id_table(dev); /* DM9132 */ else - send_filter_frame(dev, netdev_mc_count(dev)); /* DM9102/DM9102A */ + send_filter_frame(dev); /* DM9102/DM9102A */ /* Init CR7, interrupt active bit */ db->cr7_data = CR7_DEFAULT; @@ -1075,9 +1075,9 @@ static void dmfe_set_filter_mode(struct DEVICE * dev) DMFE_DBUG(0, "Set multicast address", mc_count); if (db->chip_id == PCI_DM9132_ID) - dm9132_id_table(dev, mc_count); /* DM9132 */ + dm9132_id_table(dev); /* DM9132 */ else - send_filter_frame(dev, mc_count); /* DM9102/DM9102A */ + send_filter_frame(dev); /* DM9102/DM9102A */ spin_unlock_irqrestore(&db->lock, flags); } @@ -1452,7 +1452,7 @@ static void update_cr6(u32 cr6_data, unsigned long ioaddr) * This setup frame initilize DM910X address filter mode */ -static void dm9132_id_table(struct DEVICE *dev, int mc_cnt) +static void dm9132_id_table(struct DEVICE *dev) { struct dev_mc_list *mcptr; u16 * addrptr; @@ -1472,15 +1472,14 @@ static void dm9132_id_table(struct DEVICE *dev, int mc_cnt) ioaddr += 4; /* Clear Hash Table */ - for (i = 0; i < 4; i++) - hash_table[i] = 0x0; + memset(hash_table, 0, sizeof(hash_table)); /* broadcast address */ hash_table[3] = 0x8000; /* the multicast address in Hash Table : 64 bits */ - for (mcptr = dev->mc_list, i = 0; i < mc_cnt; i++, mcptr = mcptr->next) { - hash_val = cal_CRC( (char *) mcptr->dmi_addr, 6, 0) & 0x3f; + netdev_for_each_mc_addr(mcptr, dev) { + hash_val = cal_CRC((char *) mcptr->dmi_addr, 6, 0) & 0x3f; hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16); } @@ -1495,7 +1494,7 @@ static void dm9132_id_table(struct DEVICE *dev, int mc_cnt) * This setup frame initilize DM910X address filter mode */ -static void send_filter_frame(struct DEVICE *dev, int mc_cnt) +static void send_filter_frame(struct DEVICE *dev) { struct dmfe_board_info *db = netdev_priv(dev); struct dev_mc_list *mcptr; @@ -1521,14 +1520,14 @@ static void send_filter_frame(struct DEVICE *dev, int mc_cnt) *suptr++ = 0xffff; /* fit the multicast address */ - for (mcptr = dev->mc_list, i = 0; i < mc_cnt; i++, mcptr = mcptr->next) { + netdev_for_each_mc_addr(mcptr, dev) { addrptr = (u16 *) mcptr->dmi_addr; *suptr++ = addrptr[0]; *suptr++ = addrptr[1]; *suptr++ = addrptr[2]; } - for (; i<14; i++) { + for (i = netdev_mc_count(dev); i < 14; i++) { *suptr++ = 0xffff; *suptr++ = 0xffff; *suptr++ = 0xffff; diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index cce2ada0795..7f544ef2f5f 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c @@ -997,12 +997,10 @@ static void build_setup_frame_hash(u16 *setup_frm, struct net_device *dev) memset(hash_table, 0, sizeof(hash_table)); set_bit_le(255, hash_table); /* Broadcast entry */ /* This should work on big-endian machines as well. */ - for (i = 0, mclist = dev->mc_list; mclist && i < netdev_mc_count(dev); - i++, mclist = mclist->next) { + netdev_for_each_mc_addr(mclist, dev) { int index = ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x1ff; set_bit_le(index, hash_table); - } for (i = 0; i < 32; i++) { *setup_frm++ = hash_table[i]; @@ -1021,20 +1019,18 @@ static void build_setup_frame_perfect(u16 *setup_frm, struct net_device *dev) { struct tulip_private *tp = netdev_priv(dev); struct dev_mc_list *mclist; - int i; u16 *eaddrs; /* We have <= 14 addresses so we can use the wonderful 16 address perfect filtering of the Tulip. */ - for (i = 0, mclist = dev->mc_list; i < netdev_mc_count(dev); - i++, mclist = mclist->next) { + netdev_for_each_mc_addr(mclist, dev) { eaddrs = (u16 *)mclist->dmi_addr; *setup_frm++ = *eaddrs; *setup_frm++ = *eaddrs++; *setup_frm++ = *eaddrs; *setup_frm++ = *eaddrs++; *setup_frm++ = *eaddrs; *setup_frm++ = *eaddrs++; } /* Fill the unused entries with the broadcast address. */ - memset(setup_frm, 0xff, (15-i)*12); + memset(setup_frm, 0xff, (15 - netdev_mc_count(dev)) * 12); setup_frm = &tp->setup_frame[15*6]; /* Fill the final entry with our physical address. */ @@ -1066,7 +1062,6 @@ static void set_rx_mode(struct net_device *dev) /* Some work-alikes have only a 64-entry hash filter table. */ /* Should verify correctness on big-endian/__powerpc__ */ struct dev_mc_list *mclist; - int i; if (netdev_mc_count(dev) > 64) { /* Arbitrary non-effective limit. */ tp->csr6 |= AcceptAllMulticast; @@ -1074,9 +1069,7 @@ static void set_rx_mode(struct net_device *dev) } else { u32 mc_filter[2] = {0, 0}; /* Multicast hash filter */ int filterbit; - for (i = 0, mclist = dev->mc_list; - mclist && i < netdev_mc_count(dev); - i++, mclist = mclist->next) { + netdev_for_each_mc_addr(mclist, dev) { if (tp->flags & COMET_MAC_ADDR) filterbit = ether_crc_le(ETH_ALEN, mclist->dmi_addr); else diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c index 216ceb322ed..0ab05af237e 100644 --- a/drivers/net/tulip/uli526x.c +++ b/drivers/net/tulip/uli526x.c @@ -1415,14 +1415,14 @@ static void send_filter_frame(struct net_device *dev, int mc_cnt) *suptr++ = 0xffff << FLT_SHIFT; /* fit the multicast address */ - for (mcptr = dev->mc_list, i = 0; i < mc_cnt; i++, mcptr = mcptr->next) { + netdev_for_each_mc_addr(mcptr, dev) { addrptr = (u16 *) mcptr->dmi_addr; *suptr++ = addrptr[0] << FLT_SHIFT; *suptr++ = addrptr[1] << FLT_SHIFT; *suptr++ = addrptr[2] << FLT_SHIFT; } - for (; i<14; i++) { + for (i = netdev_mc_count(dev); i < 14; i++) { *suptr++ = 0xffff << FLT_SHIFT; *suptr++ = 0xffff << FLT_SHIFT; *suptr++ = 0xffff << FLT_SHIFT; diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c index 98711a9f35a..304f43866c4 100644 --- a/drivers/net/tulip/winbond-840.c +++ b/drivers/net/tulip/winbond-840.c @@ -1368,11 +1368,9 @@ static u32 __set_rx_mode(struct net_device *dev) rx_mode = RxAcceptBroadcast | AcceptMulticast | AcceptMyPhys; } else { struct dev_mc_list *mclist; - int i; + memset(mc_filter, 0, sizeof(mc_filter)); - for (i = 0, mclist = dev->mc_list; - mclist && i < netdev_mc_count(dev); - i++, mclist = mclist->next) { + netdev_for_each_mc_addr(mclist, dev) { int filterbit = (ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26) ^ 0x3F; filterbit &= 0x3f; mc_filter[filterbit >> 5] |= 1 << (filterbit & 31); diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index edabc49a49b..38c216132ef 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c @@ -98,14 +98,10 @@ static const int multicast_filter_limit = 32; #define TX_TIMEOUT (2*HZ) #define PKT_BUF_SZ 1536 - -#define DRV_MODULE_NAME "typhoon" -#define DRV_MODULE_VERSION "1.5.9" -#define DRV_MODULE_RELDATE "Mar 2, 2009" -#define PFX DRV_MODULE_NAME ": " -#define ERR_PFX KERN_ERR PFX #define FIRMWARE_NAME "3com/typhoon.bin" +#define pr_fmt(fmt) KBUILD_MODNAME " " fmt + #include <linux/module.h> #include <linux/kernel.h> #include <linux/sched.h> @@ -132,14 +128,12 @@ static const int multicast_filter_limit = 32; #include <linux/in6.h> #include <linux/dma-mapping.h> #include <linux/firmware.h> +#include <generated/utsrelease.h> #include "typhoon.h" -static char version[] __devinitdata = - "typhoon.c: version " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; - MODULE_AUTHOR("David Dillow <dave@thedillows.org>"); -MODULE_VERSION(DRV_MODULE_VERSION); +MODULE_VERSION(UTS_RELEASE); MODULE_LICENSE("GPL"); MODULE_FIRMWARE(FIRMWARE_NAME); MODULE_DESCRIPTION("3Com Typhoon Family (3C990, 3CR990, and variants)"); @@ -161,8 +155,8 @@ module_param(use_mmio, int, 0); #endif struct typhoon_card_info { - char *name; - int capabilities; + const char *name; + const int capabilities; }; #define TYPHOON_CRYPTO_NONE 0x00 @@ -299,7 +293,6 @@ struct typhoon { struct basic_ring respRing; struct net_device_stats stats; struct net_device_stats stats_saved; - const char * name; struct typhoon_shared * shared; dma_addr_t shared_dma; __le16 xcvr_select; @@ -534,13 +527,13 @@ typhoon_process_response(struct typhoon *tp, int resp_size, } else if(resp->cmd == TYPHOON_CMD_HELLO_RESP) { typhoon_hello(tp); } else { - printk(KERN_ERR "%s: dumping unexpected response " - "0x%04x:%d:0x%02x:0x%04x:%08x:%08x\n", - tp->name, le16_to_cpu(resp->cmd), - resp->numDesc, resp->flags, - le16_to_cpu(resp->parm1), - le32_to_cpu(resp->parm2), - le32_to_cpu(resp->parm3)); + netdev_err(tp->dev, + "dumping unexpected response 0x%04x:%d:0x%02x:0x%04x:%08x:%08x\n", + le16_to_cpu(resp->cmd), + resp->numDesc, resp->flags, + le16_to_cpu(resp->parm1), + le32_to_cpu(resp->parm2), + le32_to_cpu(resp->parm3)); } cleanup: @@ -606,9 +599,8 @@ typhoon_issue_command(struct typhoon *tp, int num_cmd, struct cmd_desc *cmd, freeResp = typhoon_num_free_resp(tp); if(freeCmd < num_cmd || freeResp < num_resp) { - printk("%s: no descs for cmd, had (needed) %d (%d) cmd, " - "%d (%d) resp\n", tp->name, freeCmd, num_cmd, - freeResp, num_resp); + netdev_err(tp->dev, "no descs for cmd, had (needed) %d (%d) cmd, %d (%d) resp\n", + freeCmd, num_cmd, freeResp, num_resp); err = -ENOMEM; goto out; } @@ -733,7 +725,7 @@ typhoon_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) spin_unlock_bh(&tp->state_lock); err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); if(err < 0) - printk("%s: vlan offload error %d\n", tp->name, -err); + netdev_err(tp->dev, "vlan offload error %d\n", -err); spin_lock_bh(&tp->state_lock); } @@ -1021,7 +1013,7 @@ typhoon_get_stats(struct net_device *dev) return saved; if(typhoon_do_get_stats(tp) < 0) { - printk(KERN_ERR "%s: error getting stats\n", dev->name); + netdev_err(dev, "error getting stats\n"); return saved; } @@ -1063,8 +1055,8 @@ typhoon_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) } } - strcpy(info->driver, DRV_MODULE_NAME); - strcpy(info->version, DRV_MODULE_VERSION); + strcpy(info->driver, KBUILD_MODNAME); + strcpy(info->version, UTS_RELEASE); strcpy(info->bus_info, pci_name(pci_dev)); } @@ -1366,8 +1358,8 @@ typhoon_request_firmware(struct typhoon *tp) err = request_firmware(&typhoon_fw, FIRMWARE_NAME, &tp->pdev->dev); if (err) { - printk(KERN_ERR "%s: Failed to load firmware \"%s\"\n", - tp->name, FIRMWARE_NAME); + netdev_err(tp->dev, "Failed to load firmware \"%s\"\n", + FIRMWARE_NAME); return err; } @@ -1402,7 +1394,7 @@ typhoon_request_firmware(struct typhoon *tp) return 0; invalid_fw: - printk(KERN_ERR "%s: Invalid firmware image\n", tp->name); + netdev_err(tp->dev, "Invalid firmware image\n"); release_firmware(typhoon_fw); typhoon_fw = NULL; return -EINVAL; @@ -1439,7 +1431,7 @@ typhoon_download_firmware(struct typhoon *tp) err = -ENOMEM; dpage = pci_alloc_consistent(pdev, PAGE_SIZE, &dpage_dma); if(!dpage) { - printk(KERN_ERR "%s: no DMA mem for firmware\n", tp->name); + netdev_err(tp->dev, "no DMA mem for firmware\n"); goto err_out; } @@ -1452,7 +1444,7 @@ typhoon_download_firmware(struct typhoon *tp) err = -ETIMEDOUT; if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_WAITING_FOR_HOST) < 0) { - printk(KERN_ERR "%s: card ready timeout\n", tp->name); + netdev_err(tp->dev, "card ready timeout\n"); goto err_out_irq; } @@ -1492,8 +1484,7 @@ typhoon_download_firmware(struct typhoon *tp) if(typhoon_wait_interrupt(ioaddr) < 0 || ioread32(ioaddr + TYPHOON_REG_STATUS) != TYPHOON_STATUS_WAITING_FOR_SEGMENT) { - printk(KERN_ERR "%s: segment ready timeout\n", - tp->name); + netdev_err(tp->dev, "segment ready timeout\n"); goto err_out_irq; } @@ -1503,8 +1494,8 @@ typhoon_download_firmware(struct typhoon *tp) * the checksum, we can do this once, at the end. */ csum = csum_fold(csum_partial_copy_nocheck(image_data, - dpage, len, - 0)); + dpage, len, + 0)); iowrite32(len, ioaddr + TYPHOON_REG_BOOT_LENGTH); iowrite32(le16_to_cpu((__force __le16)csum), @@ -1515,7 +1506,7 @@ typhoon_download_firmware(struct typhoon *tp) iowrite32(dpage_dma, ioaddr + TYPHOON_REG_BOOT_DATA_LO); typhoon_post_pci_writes(ioaddr); iowrite32(TYPHOON_BOOTCMD_SEG_AVAILABLE, - ioaddr + TYPHOON_REG_COMMAND); + ioaddr + TYPHOON_REG_COMMAND); image_data += len; load_addr += len; @@ -1526,15 +1517,15 @@ typhoon_download_firmware(struct typhoon *tp) if(typhoon_wait_interrupt(ioaddr) < 0 || ioread32(ioaddr + TYPHOON_REG_STATUS) != TYPHOON_STATUS_WAITING_FOR_SEGMENT) { - printk(KERN_ERR "%s: final segment ready timeout\n", tp->name); + netdev_err(tp->dev, "final segment ready timeout\n"); goto err_out_irq; } iowrite32(TYPHOON_BOOTCMD_DNLD_COMPLETE, ioaddr + TYPHOON_REG_COMMAND); if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_WAITING_FOR_BOOT) < 0) { - printk(KERN_ERR "%s: boot ready timeout, status 0x%0x\n", - tp->name, ioread32(ioaddr + TYPHOON_REG_STATUS)); + netdev_err(tp->dev, "boot ready timeout, status 0x%0x\n", + ioread32(ioaddr + TYPHOON_REG_STATUS)); goto err_out_irq; } @@ -1556,7 +1547,7 @@ typhoon_boot_3XP(struct typhoon *tp, u32 initial_status) void __iomem *ioaddr = tp->ioaddr; if(typhoon_wait_status(ioaddr, initial_status) < 0) { - printk(KERN_ERR "%s: boot ready timeout\n", tp->name); + netdev_err(tp->dev, "boot ready timeout\n"); goto out_timeout; } @@ -1567,8 +1558,8 @@ typhoon_boot_3XP(struct typhoon *tp, u32 initial_status) ioaddr + TYPHOON_REG_COMMAND); if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_RUNNING) < 0) { - printk(KERN_ERR "%s: boot finish timeout (status 0x%x)\n", - tp->name, ioread32(ioaddr + TYPHOON_REG_STATUS)); + netdev_err(tp->dev, "boot finish timeout (status 0x%x)\n", + ioread32(ioaddr + TYPHOON_REG_STATUS)); goto out_timeout; } @@ -1867,8 +1858,7 @@ typhoon_interrupt(int irq, void *dev_instance) typhoon_post_pci_writes(ioaddr); __napi_schedule(&tp->napi); } else { - printk(KERN_ERR "%s: Error, poll already scheduled\n", - dev->name); + netdev_err(dev, "Error, poll already scheduled\n"); } return IRQ_HANDLED; } @@ -1901,16 +1891,15 @@ typhoon_sleep(struct typhoon *tp, pci_power_t state, __le16 events) xp_cmd.parm1 = events; err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); if(err < 0) { - printk(KERN_ERR "%s: typhoon_sleep(): wake events cmd err %d\n", - tp->name, err); + netdev_err(tp->dev, "typhoon_sleep(): wake events cmd err %d\n", + err); return err; } INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_GOTO_SLEEP); err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); if(err < 0) { - printk(KERN_ERR "%s: typhoon_sleep(): sleep cmd err %d\n", - tp->name, err); + netdev_err(tp->dev, "typhoon_sleep(): sleep cmd err %d\n", err); return err; } @@ -1961,12 +1950,12 @@ typhoon_start_runtime(struct typhoon *tp) err = typhoon_download_firmware(tp); if(err < 0) { - printk("%s: cannot load runtime on 3XP\n", tp->name); + netdev_err(tp->dev, "cannot load runtime on 3XP\n"); goto error_out; } if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_BOOT) < 0) { - printk("%s: cannot boot 3XP\n", tp->name); + netdev_err(tp->dev, "cannot boot 3XP\n"); err = -EIO; goto error_out; } @@ -2070,9 +2059,7 @@ typhoon_stop_runtime(struct typhoon *tp, int wait_type) } if(i == TYPHOON_WAIT_TIMEOUT) - printk(KERN_ERR - "%s: halt timed out waiting for Tx to complete\n", - tp->name); + netdev_err(tp->dev, "halt timed out waiting for Tx to complete\n"); INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_TX_DISABLE); typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); @@ -2089,11 +2076,10 @@ typhoon_stop_runtime(struct typhoon *tp, int wait_type) typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_HALTED) < 0) - printk(KERN_ERR "%s: timed out waiting for 3XP to halt\n", - tp->name); + netdev_err(tp->dev, "timed out waiting for 3XP to halt\n"); if(typhoon_reset(ioaddr, wait_type) < 0) { - printk(KERN_ERR "%s: unable to reset 3XP\n", tp->name); + netdev_err(tp->dev, "unable to reset 3XP\n"); return -ETIMEDOUT; } @@ -2112,8 +2098,7 @@ typhoon_tx_timeout(struct net_device *dev) struct typhoon *tp = netdev_priv(dev); if(typhoon_reset(tp->ioaddr, WaitNoSleep) < 0) { - printk(KERN_WARNING "%s: could not reset in tx timeout\n", - dev->name); + netdev_warn(dev, "could not reset in tx timeout\n"); goto truely_dead; } @@ -2122,8 +2107,7 @@ typhoon_tx_timeout(struct net_device *dev) typhoon_free_rx_rings(tp); if(typhoon_start_runtime(tp) < 0) { - printk(KERN_ERR "%s: could not start runtime in tx timeout\n", - dev->name); + netdev_err(dev, "could not start runtime in tx timeout\n"); goto truely_dead; } @@ -2148,7 +2132,7 @@ typhoon_open(struct net_device *dev) err = typhoon_wakeup(tp, WaitSleep); if(err < 0) { - printk(KERN_ERR "%s: unable to wakeup device\n", dev->name); + netdev_err(dev, "unable to wakeup device\n"); goto out_sleep; } @@ -2173,14 +2157,13 @@ out_irq: out_sleep: if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_HOST) < 0) { - printk(KERN_ERR "%s: unable to reboot into sleep img\n", - dev->name); + netdev_err(dev, "unable to reboot into sleep img\n"); typhoon_reset(tp->ioaddr, NoWait); goto out; } if(typhoon_sleep(tp, PCI_D3hot, 0) < 0) - printk(KERN_ERR "%s: unable to go back to sleep\n", dev->name); + netdev_err(dev, "unable to go back to sleep\n"); out: return err; @@ -2195,7 +2178,7 @@ typhoon_close(struct net_device *dev) napi_disable(&tp->napi); if(typhoon_stop_runtime(tp, WaitSleep) < 0) - printk(KERN_ERR "%s: unable to stop runtime\n", dev->name); + netdev_err(dev, "unable to stop runtime\n"); /* Make sure there is no irq handler running on a different CPU. */ free_irq(dev->irq, dev); @@ -2204,10 +2187,10 @@ typhoon_close(struct net_device *dev) typhoon_init_rings(tp); if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_HOST) < 0) - printk(KERN_ERR "%s: unable to boot sleep image\n", dev->name); + netdev_err(dev, "unable to boot sleep image\n"); if(typhoon_sleep(tp, PCI_D3hot, 0) < 0) - printk(KERN_ERR "%s: unable to put card to sleep\n", dev->name); + netdev_err(dev, "unable to put card to sleep\n"); return 0; } @@ -2225,14 +2208,12 @@ typhoon_resume(struct pci_dev *pdev) return 0; if(typhoon_wakeup(tp, WaitNoSleep) < 0) { - printk(KERN_ERR "%s: critical: could not wake up in resume\n", - dev->name); + netdev_err(dev, "critical: could not wake up in resume\n"); goto reset; } if(typhoon_start_runtime(tp) < 0) { - printk(KERN_ERR "%s: critical: could not start runtime in " - "resume\n", dev->name); + netdev_err(dev, "critical: could not start runtime in resume\n"); goto reset; } @@ -2259,8 +2240,7 @@ typhoon_suspend(struct pci_dev *pdev, pm_message_t state) spin_lock_bh(&tp->state_lock); if(tp->vlgrp && tp->wol_events & TYPHOON_WAKE_MAGIC_PKT) { spin_unlock_bh(&tp->state_lock); - printk(KERN_ERR "%s: cannot do WAKE_MAGIC with VLANS\n", - dev->name); + netdev_err(dev, "cannot do WAKE_MAGIC with VLANS\n"); return -EBUSY; } spin_unlock_bh(&tp->state_lock); @@ -2268,7 +2248,7 @@ typhoon_suspend(struct pci_dev *pdev, pm_message_t state) netif_device_detach(dev); if(typhoon_stop_runtime(tp, WaitNoSleep) < 0) { - printk(KERN_ERR "%s: unable to stop runtime\n", dev->name); + netdev_err(dev, "unable to stop runtime\n"); goto need_resume; } @@ -2276,7 +2256,7 @@ typhoon_suspend(struct pci_dev *pdev, pm_message_t state) typhoon_init_rings(tp); if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_HOST) < 0) { - printk(KERN_ERR "%s: unable to boot sleep image\n", dev->name); + netdev_err(dev, "unable to boot sleep image\n"); goto need_resume; } @@ -2284,21 +2264,19 @@ typhoon_suspend(struct pci_dev *pdev, pm_message_t state) xp_cmd.parm1 = cpu_to_le16(ntohs(*(__be16 *)&dev->dev_addr[0])); xp_cmd.parm2 = cpu_to_le32(ntohl(*(__be32 *)&dev->dev_addr[2])); if(typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL) < 0) { - printk(KERN_ERR "%s: unable to set mac address in suspend\n", - dev->name); + netdev_err(dev, "unable to set mac address in suspend\n"); goto need_resume; } INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_SET_RX_FILTER); xp_cmd.parm1 = TYPHOON_RX_FILTER_DIRECTED | TYPHOON_RX_FILTER_BROADCAST; if(typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL) < 0) { - printk(KERN_ERR "%s: unable to set rx filter in suspend\n", - dev->name); + netdev_err(dev, "unable to set rx filter in suspend\n"); goto need_resume; } if(typhoon_sleep(tp, pci_choose_state(pdev, state), tp->wol_events) < 0) { - printk(KERN_ERR "%s: unable to put card to sleep\n", dev->name); + netdev_err(dev, "unable to put card to sleep\n"); goto need_resume; } @@ -2352,7 +2330,7 @@ out_unmap: out: if(!mode) - printk(KERN_INFO PFX "falling back to port IO\n"); + pr_info("%s: falling back to port IO\n", pci_name(pdev)); return mode; } @@ -2372,7 +2350,6 @@ static const struct net_device_ops typhoon_netdev_ops = { static int __devinit typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { - static int did_version = 0; struct net_device *dev; struct typhoon *tp; int card_id = (int) ent->driver_data; @@ -2382,14 +2359,11 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) struct cmd_desc xp_cmd; struct resp_desc xp_resp[3]; int err = 0; - - if(!did_version++) - printk(KERN_INFO "%s", version); + const char *err_msg; dev = alloc_etherdev(sizeof(*tp)); if(dev == NULL) { - printk(ERR_PFX "%s: unable to alloc new net device\n", - pci_name(pdev)); + err_msg = "unable to alloc new net device"; err = -ENOMEM; goto error_out; } @@ -2397,57 +2371,48 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) err = pci_enable_device(pdev); if(err < 0) { - printk(ERR_PFX "%s: unable to enable device\n", - pci_name(pdev)); + err_msg = "unable to enable device"; goto error_out_dev; } err = pci_set_mwi(pdev); if(err < 0) { - printk(ERR_PFX "%s: unable to set MWI\n", pci_name(pdev)); + err_msg = "unable to set MWI"; goto error_out_disable; } err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); if(err < 0) { - printk(ERR_PFX "%s: No usable DMA configuration\n", - pci_name(pdev)); + err_msg = "No usable DMA configuration"; goto error_out_mwi; } /* sanity checks on IO and MMIO BARs */ if(!(pci_resource_flags(pdev, 0) & IORESOURCE_IO)) { - printk(ERR_PFX - "%s: region #1 not a PCI IO resource, aborting\n", - pci_name(pdev)); + err_msg = "region #1 not a PCI IO resource, aborting"; err = -ENODEV; goto error_out_mwi; } if(pci_resource_len(pdev, 0) < 128) { - printk(ERR_PFX "%s: Invalid PCI IO region size, aborting\n", - pci_name(pdev)); + err_msg = "Invalid PCI IO region size, aborting"; err = -ENODEV; goto error_out_mwi; } if(!(pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) { - printk(ERR_PFX - "%s: region #1 not a PCI MMIO resource, aborting\n", - pci_name(pdev)); + err_msg = "region #1 not a PCI MMIO resource, aborting"; err = -ENODEV; goto error_out_mwi; } if(pci_resource_len(pdev, 1) < 128) { - printk(ERR_PFX "%s: Invalid PCI MMIO region size, aborting\n", - pci_name(pdev)); + err_msg = "Invalid PCI MMIO region size, aborting"; err = -ENODEV; goto error_out_mwi; } - err = pci_request_regions(pdev, "typhoon"); + err = pci_request_regions(pdev, KBUILD_MODNAME); if(err < 0) { - printk(ERR_PFX "%s: could not request regions\n", - pci_name(pdev)); + err_msg = "could not request regions"; goto error_out_mwi; } @@ -2458,8 +2423,7 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ioaddr = pci_iomap(pdev, use_mmio, 128); if (!ioaddr) { - printk(ERR_PFX "%s: cannot remap registers, aborting\n", - pci_name(pdev)); + err_msg = "cannot remap registers, aborting"; err = -EIO; goto error_out_regions; } @@ -2469,8 +2433,7 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) shared = pci_alloc_consistent(pdev, sizeof(struct typhoon_shared), &shared_dma); if(!shared) { - printk(ERR_PFX "%s: could not allocate DMA memory\n", - pci_name(pdev)); + err_msg = "could not allocate DMA memory"; err = -ENOMEM; goto error_out_remap; } @@ -2493,7 +2456,7 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) * 5) Put the card to sleep. */ if (typhoon_reset(ioaddr, WaitSleep) < 0) { - printk(ERR_PFX "%s: could not reset 3XP\n", pci_name(pdev)); + err_msg = "could not reset 3XP"; err = -EIO; goto error_out_dma; } @@ -2505,26 +2468,18 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_master(pdev); pci_save_state(pdev); - /* dev->name is not valid until we register, but we need to - * use some common routines to initialize the card. So that those - * routines print the right name, we keep our oun pointer to the name - */ - tp->name = pci_name(pdev); - typhoon_init_interface(tp); typhoon_init_rings(tp); if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_HOST) < 0) { - printk(ERR_PFX "%s: cannot boot 3XP sleep image\n", - pci_name(pdev)); + err_msg = "cannot boot 3XP sleep image"; err = -EIO; goto error_out_reset; } INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_READ_MAC_ADDRESS); if(typhoon_issue_command(tp, 1, &xp_cmd, 1, xp_resp) < 0) { - printk(ERR_PFX "%s: cannot read MAC address\n", - pci_name(pdev)); + err_msg = "cannot read MAC address"; err = -EIO; goto error_out_reset; } @@ -2533,8 +2488,7 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) *(__be32 *)&dev->dev_addr[2] = htonl(le32_to_cpu(xp_resp[0].parm2)); if(!is_valid_ether_addr(dev->dev_addr)) { - printk(ERR_PFX "%s: Could not obtain valid ethernet address, " - "aborting\n", pci_name(pdev)); + err_msg = "Could not obtain valid ethernet address, aborting"; goto error_out_reset; } @@ -2543,8 +2497,7 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) */ INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_READ_VERSIONS); if(typhoon_issue_command(tp, 1, &xp_cmd, 3, xp_resp) < 0) { - printk(ERR_PFX "%s: Could not get Sleep Image version\n", - pci_name(pdev)); + err_msg = "Could not get Sleep Image version"; goto error_out_reset; } @@ -2561,8 +2514,7 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) tp->capabilities |= TYPHOON_WAKEUP_NEEDS_RESET; if(typhoon_sleep(tp, PCI_D3hot, 0) < 0) { - printk(ERR_PFX "%s: cannot put adapter to sleep\n", - pci_name(pdev)); + err_msg = "cannot put adapter to sleep"; err = -EIO; goto error_out_reset; } @@ -2581,19 +2533,18 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; dev->features |= NETIF_F_TSO; - if(register_netdev(dev) < 0) + if(register_netdev(dev) < 0) { + err_msg = "unable to register netdev"; goto error_out_reset; - - /* fixup our local name */ - tp->name = dev->name; + } pci_set_drvdata(pdev, dev); - printk(KERN_INFO "%s: %s at %s 0x%llx, %pM\n", - dev->name, typhoon_card_info[card_id].name, - use_mmio ? "MMIO" : "IO", - (unsigned long long)pci_resource_start(pdev, use_mmio), - dev->dev_addr); + netdev_info(dev, "%s at %s 0x%llx, %pM\n", + typhoon_card_info[card_id].name, + use_mmio ? "MMIO" : "IO", + (unsigned long long)pci_resource_start(pdev, use_mmio), + dev->dev_addr); /* xp_resp still contains the response to the READ_VERSIONS command. * For debugging, let the user know what version he has. @@ -2603,23 +2554,20 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) * of version is Month/Day of build. */ u16 monthday = le32_to_cpu(xp_resp[0].parm2) & 0xffff; - printk(KERN_INFO "%s: Typhoon 1.0 Sleep Image built " - "%02u/%02u/2000\n", dev->name, monthday >> 8, - monthday & 0xff); + netdev_info(dev, "Typhoon 1.0 Sleep Image built %02u/%02u/2000\n", + monthday >> 8, monthday & 0xff); } else if(xp_resp[0].numDesc == 2) { /* This is the Typhoon 1.1+ type Sleep Image */ u32 sleep_ver = le32_to_cpu(xp_resp[0].parm2); u8 *ver_string = (u8 *) &xp_resp[1]; ver_string[25] = 0; - printk(KERN_INFO "%s: Typhoon 1.1+ Sleep Image version " - "%02x.%03x.%03x %s\n", dev->name, sleep_ver >> 24, - (sleep_ver >> 12) & 0xfff, sleep_ver & 0xfff, - ver_string); + netdev_info(dev, "Typhoon 1.1+ Sleep Image version %02x.%03x.%03x %s\n", + sleep_ver >> 24, (sleep_ver >> 12) & 0xfff, + sleep_ver & 0xfff, ver_string); } else { - printk(KERN_WARNING "%s: Unknown Sleep Image version " - "(%u:%04x)\n", dev->name, xp_resp[0].numDesc, - le32_to_cpu(xp_resp[0].parm2)); + netdev_warn(dev, "Unknown Sleep Image version (%u:%04x)\n", + xp_resp[0].numDesc, le32_to_cpu(xp_resp[0].parm2)); } return 0; @@ -2641,6 +2589,7 @@ error_out_disable: error_out_dev: free_netdev(dev); error_out: + pr_err("%s: %s\n", pci_name(pdev), err_msg); return err; } @@ -2665,7 +2614,7 @@ typhoon_remove_one(struct pci_dev *pdev) } static struct pci_driver typhoon_driver = { - .name = DRV_MODULE_NAME, + .name = KBUILD_MODNAME, .id_table = typhoon_pci_tbl, .probe = typhoon_init_one, .remove = __devexit_p(typhoon_remove_one), diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index f605204de3e..20e34608fa4 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -555,20 +555,18 @@ static void asix_set_multicast(struct net_device *net) * for our 8 byte filter buffer * to avoid allocating memory that * is tricky to free later */ - struct dev_mc_list *mc_list = net->mc_list; + struct dev_mc_list *mc_list; u32 crc_bits; - int i; memset(data->multi_filter, 0, AX_MCAST_FILTER_SIZE); /* Build the multicast hash filter. */ - for (i = 0; i < netdev_mc_count(net); i++) { + netdev_for_each_mc_addr(mc_list, net) { crc_bits = ether_crc(ETH_ALEN, mc_list->dmi_addr) >> 26; data->multi_filter[crc_bits >> 3] |= 1 << (crc_bits & 7); - mc_list = mc_list->next; } asix_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0, @@ -769,20 +767,18 @@ static void ax88172_set_multicast(struct net_device *net) * for our 8 byte filter buffer * to avoid allocating memory that * is tricky to free later */ - struct dev_mc_list *mc_list = net->mc_list; + struct dev_mc_list *mc_list; u32 crc_bits; - int i; memset(data->multi_filter, 0, AX_MCAST_FILTER_SIZE); /* Build the multicast hash filter. */ - for (i = 0; i < netdev_mc_count(net); i++) { + netdev_for_each_mc_addr(mc_list, net) { crc_bits = ether_crc(ETH_ALEN, mc_list->dmi_addr) >> 26; data->multi_filter[crc_bits >> 3] |= 1 << (crc_bits & 7); - mc_list = mc_list->next; } asix_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0, diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c index 5a13660ebd1..96f1ebe0d34 100644 --- a/drivers/net/usb/catc.c +++ b/drivers/net/usb/catc.c @@ -632,7 +632,6 @@ static void catc_set_multicast_list(struct net_device *netdev) struct dev_mc_list *mc; u8 broadcast[6]; u8 rx = RxEnable | RxPolarity | RxMultiCast; - int i; memset(broadcast, 0xff, 6); memset(catc->multicast, 0, 64); @@ -648,9 +647,7 @@ static void catc_set_multicast_list(struct net_device *netdev) if (netdev->flags & IFF_ALLMULTI) { memset(catc->multicast, 0xff, 64); } else { - for (i = 0, mc = netdev->mc_list; - mc && i < netdev_mc_count(netdev); - i++, mc = mc->next) { + netdev_for_each_mc_addr(mc, netdev) { u32 crc = ether_crc_le(6, mc->dmi_addr); if (!catc->is_f5u011) { catc->multicast[(crc >> 3) & 0x3f] |= 1 << (crc & 7); diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c index 34665137f2c..70978219e98 100644 --- a/drivers/net/usb/mcs7830.c +++ b/drivers/net/usb/mcs7830.c @@ -452,15 +452,13 @@ static void mcs7830_data_set_multicast(struct net_device *net) * for our 8 byte filter buffer * to avoid allocating memory that * is tricky to free later */ - struct dev_mc_list *mc_list = net->mc_list; + struct dev_mc_list *mc_list; u32 crc_bits; - int i; /* Build the multicast hash filter. */ - for (i = 0; i < netdev_mc_count(net); i++) { + netdev_for_each_mc_addr(mc_list, net) { crc_bits = ether_crc(ETH_ALEN, mc_list->dmi_addr) >> 26; data->multi_filter[crc_bits >> 3] |= 1 << (crc_bits & 7); - mc_list = mc_list->next; } } } diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index 1ada51eb71f..df9179a1c93 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -384,30 +384,20 @@ static void smsc95xx_set_multicast(struct net_device *netdev) pdata->mac_cr |= MAC_CR_MCPAS_; pdata->mac_cr &= ~(MAC_CR_PRMS_ | MAC_CR_HPFILT_); } else if (!netdev_mc_empty(dev->net)) { - struct dev_mc_list *mc_list = dev->net->mc_list; - int count = 0; + struct dev_mc_list *mc_list; pdata->mac_cr |= MAC_CR_HPFILT_; pdata->mac_cr &= ~(MAC_CR_PRMS_ | MAC_CR_MCPAS_); - while (mc_list) { - count++; - if (mc_list->dmi_addrlen == ETH_ALEN) { - u32 bitnum = smsc95xx_hash(mc_list->dmi_addr); - u32 mask = 0x01 << (bitnum & 0x1F); - if (bitnum & 0x20) - hash_hi |= mask; - else - hash_lo |= mask; - } else { - netdev_warn(dev->net, "dmi_addrlen != 6\n"); - } - mc_list = mc_list->next; + netdev_for_each_mc_addr(mc_list, netdev) { + u32 bitnum = smsc95xx_hash(mc_list->dmi_addr); + u32 mask = 0x01 << (bitnum & 0x1F); + if (bitnum & 0x20) + hash_hi |= mask; + else + hash_lo |= mask; } - if (count != ((u32) netdev_mc_count(dev->net))) - netdev_warn(dev->net, "mc_count != dev->mc_count\n"); - netif_dbg(dev, drv, dev->net, "HASHH=0x%08X, HASHL=0x%08X\n", hash_hi, hash_lo); } else { diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index d58b94030ef..456c265b1fe 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -2534,6 +2534,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e7, quirk_i82576_sriov); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e8, quirk_i82576_sriov); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x150a, quirk_i82576_sriov); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x150d, quirk_i82576_sriov); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1518, quirk_i82576_sriov); #endif /* CONFIG_PCI_IOV */ diff --git a/drivers/staging/arlan/arlan-main.c b/drivers/staging/arlan/arlan-main.c index 921a082487a..88fdd53cf5d 100644 --- a/drivers/staging/arlan/arlan-main.c +++ b/drivers/staging/arlan/arlan-main.c @@ -1455,10 +1455,10 @@ static void arlan_rx_interrupt(struct net_device *dev, u_char rxStatus, u_short #ifdef ARLAN_MULTICAST if (!(dev->flags & IFF_ALLMULTI) && !(dev->flags & IFF_PROMISC) && - dev->mc_list) + !netdev_mc_empty(dev)) { char hw_dst_addr[6]; - struct dev_mc_list *dmi = dev->mc_list; + struct dev_mc_list *dmi; int i; memcpy_fromio(hw_dst_addr, arlan->ultimateDestAddress, 6); @@ -1469,20 +1469,15 @@ static void arlan_rx_interrupt(struct net_device *dev, u_char rxStatus, u_short printk(KERN_ERR "%s mcast 0x0100 \n", dev->name); else if (hw_dst_addr[1] == 0x40) printk(KERN_ERR "%s m/bcast 0x0140 \n", dev->name); - while (dmi) - { - if (dmi->dmi_addrlen == 6) { - if (arlan_debug & ARLAN_DEBUG_HEADER_DUMP) - printk(KERN_ERR "%s mcl %pM\n", - dev->name, dmi->dmi_addr); - for (i = 0; i < 6; i++) - if (dmi->dmi_addr[i] != hw_dst_addr[i]) - break; - if (i == 6) + netdev_for_each_mc_entry(dmi, dev) { + if (arlan_debug & ARLAN_DEBUG_HEADER_DUMP) + printk(KERN_ERR "%s mcl %pM\n", + dev->name, dmi->dmi_addr); + for (i = 0; i < 6; i++) + if (dmi->dmi_addr[i] != hw_dst_addr[i]) break; - } else - printk(KERN_ERR "%s: invalid multicast address length given.\n", dev->name); - dmi = dmi->next; + if (i == 6) + break; } /* we reach here if multicast filtering is on and packet * is multicast and not for receive */ diff --git a/drivers/staging/et131x/et131x_netdev.c b/drivers/staging/et131x/et131x_netdev.c index bc1fad24895..edb78ae9e59 100644 --- a/drivers/staging/et131x/et131x_netdev.c +++ b/drivers/staging/et131x/et131x_netdev.c @@ -411,9 +411,9 @@ void et131x_multicast(struct net_device *netdev) { struct et131x_adapter *adapter = netdev_priv(netdev); uint32_t PacketFilter = 0; - uint32_t count; unsigned long flags; - struct dev_mc_list *mclist = netdev->mc_list; + struct dev_mc_list *mclist; + int i; spin_lock_irqsave(&adapter->Lock, flags); @@ -456,12 +456,13 @@ void et131x_multicast(struct net_device *netdev) } /* Set values in the private adapter struct */ - adapter->MCAddressCount = netdev_mc_count(netdev); - - if (!netdev_mc_empty(netdev)) { - count = netdev_mc_count(netdev) - 1; - memcpy(adapter->MCList[count], mclist->dmi_addr, ETH_ALEN); + i = 0; + netdev_for_each_mc_addr(mclist, netdev) { + if (i == NIC_MAX_MCAST_LIST) + break; + memcpy(adapter->MCList[i++], mclist->dmi_addr, ETH_ALEN); } + adapter->MCAddressCount = i; /* Are the new flags different from the previous ones? If not, then no * action is required diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c index 4cfd4b136b3..220de133a6a 100644 --- a/drivers/staging/octeon/ethernet.c +++ b/drivers/staging/octeon/ethernet.c @@ -382,7 +382,7 @@ static void cvm_oct_common_set_multicast_list(struct net_device *dev) control.u64 = 0; control.s.bcst = 1; /* Allow broadcast MAC addresses */ - if (dev->mc_list || (dev->flags & IFF_ALLMULTI) || + if (!netdev_mc_empty(dev) || (dev->flags & IFF_ALLMULTI) || (dev->flags & IFF_PROMISC)) /* Force accept multicast packets */ control.s.mcst = 2; diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c index 8c9d5e5c770..f5cc01ba414 100644 --- a/drivers/staging/slicoss/slicoss.c +++ b/drivers/staging/slicoss/slicoss.c @@ -1362,25 +1362,17 @@ static void slic_mcast_set_list(struct net_device *dev) { struct adapter *adapter = (struct adapter *)netdev_priv(dev); int status = STATUS_SUCCESS; - int i; char *addresses; - struct dev_mc_list *mc_list = dev->mc_list; - int mc_count = netdev_mc_count(dev); + struct dev_mc_list *mc_list; ASSERT(adapter); - for (i = 1; i <= mc_count; i++) { + netdev_for_each_mc_addr(mc_list, dev) { addresses = (char *) &mc_list->dmi_addr; - if (mc_list->dmi_addrlen == 6) { - status = slic_mcast_add_list(adapter, addresses); - if (status != STATUS_SUCCESS) - break; - } else { - status = -EINVAL; + status = slic_mcast_add_list(adapter, addresses); + if (status != STATUS_SUCCESS) break; - } slic_mcast_set_bit(adapter, addresses); - mc_list = mc_list->next; } if (adapter->devflags_prev != dev->flags) { diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 82b3a6e0b15..0dadb765fec 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -3082,8 +3082,7 @@ static void device_set_multi(struct net_device *dev) { PSMgmtObject pMgmt = pDevice->pMgmt; u32 mc_filter[2]; - int i; - struct dev_mc_list *mclist; + struct dev_mc_list *mclist; VNSvInPortB(pDevice->PortOffset + MAC_REG_RCR, &(pDevice->byRxMode)); @@ -3103,8 +3102,7 @@ static void device_set_multi(struct net_device *dev) { } else { memset(mc_filter, 0, sizeof(mc_filter)); - for (i = 0, mclist = dev->mc_list; mclist && i < netdev_mc_count(dev); - i++, mclist = mclist->next) { + netdev_for_each_mc_addr(mclist, dev) { int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26; mc_filter[bit_nr >> 5] |= cpu_to_le32(1 << (bit_nr & 31)); } diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index 2c6a5350547..a8e1adbc959 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -1596,7 +1596,7 @@ static void device_set_multi(struct net_device *dev) { PSMgmtObject pMgmt = &(pDevice->sMgmtObj); u32 mc_filter[2]; int ii; - struct dev_mc_list *mclist; + struct dev_mc_list *mclist; BYTE pbyData[8] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; BYTE byTmpMode = 0; int rc; @@ -1632,8 +1632,7 @@ static void device_set_multi(struct net_device *dev) { } else { memset(mc_filter, 0, sizeof(mc_filter)); - for (ii = 0, mclist = dev->mc_list; mclist && ii < netdev_mc_count(dev); - ii++, mclist = mclist->next) { + netdev_for_each_mc_addr(mclist, dev) { int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26; mc_filter[bit_nr >> 5] |= cpu_to_le32(1 << (bit_nr & 31)); } diff --git a/drivers/staging/wavelan/wavelan.c b/drivers/staging/wavelan/wavelan.c index 961f1417fb5..54ca63196fd 100644 --- a/drivers/staging/wavelan/wavelan.c +++ b/drivers/staging/wavelan/wavelan.c @@ -1387,7 +1387,7 @@ static void wavelan_set_multicast_list(struct net_device * dev) } } else /* Are there multicast addresses to send? */ - if (dev->mc_list != (struct dev_mc_list *) NULL) { + if (!netdev_mc_empty(dev)) { /* * Disable promiscuous mode, but receive all packets * in multicast list @@ -3531,7 +3531,7 @@ static void wv_82586_config(struct net_device * dev) /* Any address to set? */ if (lp->mc_count) { - for (dmi = dev->mc_list; dmi; dmi = dmi->next) + netdev_for_each_mc_addr(dmi, dev) outsw(PIOP1(ioaddr), (u16 *) dmi->dmi_addr, WAVELAN_ADDR_SIZE >> 1); @@ -3539,7 +3539,7 @@ static void wv_82586_config(struct net_device * dev) printk(KERN_DEBUG "%s: wv_82586_config(): set %d multicast addresses:\n", dev->name, lp->mc_count); - for (dmi = dev->mc_list; dmi; dmi = dmi->next) + netdev_for_each_mc_addr(dmi, dev) printk(KERN_DEBUG " %pM\n", dmi->dmi_addr); #endif } diff --git a/drivers/staging/wavelan/wavelan_cs.c b/drivers/staging/wavelan/wavelan_cs.c index 08fcb226d7d..04f691d127b 100644 --- a/drivers/staging/wavelan/wavelan_cs.c +++ b/drivers/staging/wavelan/wavelan_cs.c @@ -1410,8 +1410,7 @@ wavelan_set_multicast_list(struct net_device * dev) } else /* If there is some multicast addresses to send */ - if(dev->mc_list != (struct dev_mc_list *) NULL) - { + if (!netdev_mc_empty(dev)) { /* * Disable promiscuous mode, but receive all packets * in multicast list @@ -3598,13 +3597,13 @@ wv_82593_config(struct net_device * dev) /* If any multicast address to set */ if(lp->mc_count) { - struct dev_mc_list * dmi; + struct dev_mc_list *dmi; int addrs_len = WAVELAN_ADDR_SIZE * lp->mc_count; #ifdef DEBUG_CONFIG_INFO printk(KERN_DEBUG "%s: wv_hw_config(): set %d multicast addresses:\n", dev->name, lp->mc_count); - for(dmi=dev->mc_list; dmi; dmi=dmi->next) + netdev_for_each_mc_addr(dmi, dev) printk(KERN_DEBUG " %pM\n", dmi->dmi_addr); #endif @@ -3613,7 +3612,7 @@ wv_82593_config(struct net_device * dev) outb(((TX_BASE >> 8) & PIORH_MASK) | PIORH_SEL_TX, PIORH(base)); outb(addrs_len & 0xff, PIOP(base)); /* byte count lsb */ outb((addrs_len >> 8), PIOP(base)); /* byte count msb */ - for(dmi=dev->mc_list; dmi; dmi=dmi->next) + netdev_for_each_mc_addr(dmi, dev) outsb(PIOP(base), dmi->dmi_addr, dmi->dmi_addrlen); /* reset transmit DMA pointer */ diff --git a/drivers/staging/wlags49_h2/wl_netdev.c b/drivers/staging/wlags49_h2/wl_netdev.c index a95ebf881fc..c33e225bc0e 100644 --- a/drivers/staging/wlags49_h2/wl_netdev.c +++ b/drivers/staging/wlags49_h2/wl_netdev.c @@ -1049,7 +1049,7 @@ void wl_multicast( struct net_device *dev ) //;?seems reasonable that even an AP-only driver could afford this small additional footprint int x; - struct dev_mc_list *mclist; + struct dev_mc_list *mclist; struct wl_private *lp = wl_priv(dev); unsigned long flags; /*------------------------------------------------------------------------*/ @@ -1072,11 +1072,9 @@ void wl_multicast( struct net_device *dev ) DBG_PRINT( " mc_count: %d\n", netdev_mc_count(dev)); - for( x = 0, mclist = dev->mc_list; mclist && x < netdev_mc_count(dev); - x++, mclist = mclist->next ) { + netdev_for_each_mc_addr(mclist, dev) DBG_PRINT( " %s (%d)\n", DbgHwAddr(mclist->dmi_addr), mclist->dmi_addrlen ); - } } #endif /* DBG */ @@ -1120,12 +1118,10 @@ void wl_multicast( struct net_device *dev ) lp->ltvRecord.len = ( netdev_mc_count(dev) * 3 ) + 1; lp->ltvRecord.typ = CFG_GROUP_ADDR; - for( x = 0, mclist = dev->mc_list; - ( x < netdev_mc_count(dev)) && ( mclist != NULL ); - x++, mclist = mclist->next ) { - memcpy( &( lp->ltvRecord.u.u8[x * ETH_ALEN] ), - mclist->dmi_addr, ETH_ALEN ); - } + x = 0; + netdev_for_each_mc_addr(mclist, dev) + memcpy(&(lp->ltvRecord.u.u8[x++ * ETH_ALEN]), + mclist->dmi_addr, ETH_ALEN); DBG_PRINT( "Setting multicast list\n" ); hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord )); } else { diff --git a/drivers/vhost/Kconfig b/drivers/vhost/Kconfig index 9e9355367bb..e4e2fd1b510 100644 --- a/drivers/vhost/Kconfig +++ b/drivers/vhost/Kconfig @@ -1,6 +1,6 @@ config VHOST_NET tristate "Host kernel accelerator for virtio net (EXPERIMENTAL)" - depends on NET && EVENTFD && (TUN || !TUN) && EXPERIMENTAL + depends on NET && EVENTFD && (TUN || !TUN) && (MACVTAP || !MACVTAP) && EXPERIMENTAL ---help--- This kernel module can be loaded in host kernel to accelerate guest networking with virtio_net. Not to be confused with virtio_net diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 4c8928319e1..91a324cc229 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c @@ -22,6 +22,7 @@ #include <linux/if_packet.h> #include <linux/if_arp.h> #include <linux/if_tun.h> +#include <linux/if_macvlan.h> #include <net/sock.h> @@ -452,13 +453,16 @@ err: return ERR_PTR(r); } -static struct socket *get_tun_socket(int fd) +static struct socket *get_tap_socket(int fd) { struct file *file = fget(fd); struct socket *sock; if (!file) return ERR_PTR(-EBADF); sock = tun_get_socket(file); + if (!IS_ERR(sock)) + return sock; + sock = macvtap_get_socket(file); if (IS_ERR(sock)) fput(file); return sock; @@ -473,7 +477,7 @@ static struct socket *get_socket(int fd) sock = get_raw_socket(fd); if (!IS_ERR(sock)) return sock; - sock = get_tun_socket(fd); + sock = get_tap_socket(fd); if (!IS_ERR(sock)) return sock; return ERR_PTR(-ENOTSOCK); diff --git a/fs/seq_file.c b/fs/seq_file.c index f65b16f02da..5afd554efad 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c @@ -750,3 +750,74 @@ struct hlist_node *seq_hlist_next(void *v, struct hlist_head *head, return node->next; } EXPORT_SYMBOL(seq_hlist_next); + +/** + * seq_hlist_start_rcu - start an iteration of a hlist protected by RCU + * @head: the head of the hlist + * @pos: the start position of the sequence + * + * Called at seq_file->op->start(). + * + * This list-traversal primitive may safely run concurrently with + * the _rcu list-mutation primitives such as hlist_add_head_rcu() + * as long as the traversal is guarded by rcu_read_lock(). + */ +struct hlist_node *seq_hlist_start_rcu(struct hlist_head *head, + loff_t pos) +{ + struct hlist_node *node; + + __hlist_for_each_rcu(node, head) + if (pos-- == 0) + return node; + return NULL; +} +EXPORT_SYMBOL(seq_hlist_start_rcu); + +/** + * seq_hlist_start_head_rcu - start an iteration of a hlist protected by RCU + * @head: the head of the hlist + * @pos: the start position of the sequence + * + * Called at seq_file->op->start(). Call this function if you want to + * print a header at the top of the output. + * + * This list-traversal primitive may safely run concurrently with + * the _rcu list-mutation primitives such as hlist_add_head_rcu() + * as long as the traversal is guarded by rcu_read_lock(). + */ +struct hlist_node *seq_hlist_start_head_rcu(struct hlist_head *head, + loff_t pos) +{ + if (!pos) + return SEQ_START_TOKEN; + + return seq_hlist_start_rcu(head, pos - 1); +} +EXPORT_SYMBOL(seq_hlist_start_head_rcu); + +/** + * seq_hlist_next_rcu - move to the next position of the hlist protected by RCU + * @v: the current iterator + * @head: the head of the hlist + * @pos: the current posision + * + * Called at seq_file->op->next(). + * + * This list-traversal primitive may safely run concurrently with + * the _rcu list-mutation primitives such as hlist_add_head_rcu() + * as long as the traversal is guarded by rcu_read_lock(). + */ +struct hlist_node *seq_hlist_next_rcu(void *v, + struct hlist_head *head, + loff_t *ppos) +{ + struct hlist_node *node = v; + + ++*ppos; + if (v == SEQ_START_TOKEN) + return rcu_dereference(head->first); + else + return rcu_dereference(node->next); +} +EXPORT_SYMBOL(seq_hlist_next_rcu); diff --git a/include/linux/icmpv6.h b/include/linux/icmpv6.h index c0d8357917e..4c4c74ec598 100644 --- a/include/linux/icmpv6.h +++ b/include/linux/icmpv6.h @@ -174,8 +174,7 @@ struct icmp6_filter { extern void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, - __u32 info, - struct net_device *dev); + __u32 info); extern int icmpv6_init(void); extern int icmpv6_err_convert(u8 type, u8 code, diff --git a/include/linux/if_macvlan.h b/include/linux/if_macvlan.h index f9cb9ba1475..b78a712247d 100644 --- a/include/linux/if_macvlan.h +++ b/include/linux/if_macvlan.h @@ -7,6 +7,19 @@ #include <linux/netlink.h> #include <net/netlink.h> +#if defined(CONFIG_MACVTAP) || defined(CONFIG_MACVTAP_MODULE) +struct socket *macvtap_get_socket(struct file *); +#else +#include <linux/err.h> +#include <linux/errno.h> +struct file; +struct socket; +static inline struct socket *macvtap_get_socket(struct file *f) +{ + return ERR_PTR(-EINVAL); +} +#endif /* CONFIG_MACVTAP */ + struct macvlan_port; struct macvtap_queue; diff --git a/include/linux/rculist.h b/include/linux/rculist.h index 1bf0f708c4f..701fe9cb552 100644 --- a/include/linux/rculist.h +++ b/include/linux/rculist.h @@ -406,6 +406,11 @@ static inline void hlist_add_after_rcu(struct hlist_node *prev, n->next->pprev = &n->next; } +#define __hlist_for_each_rcu(pos, head) \ + for (pos = rcu_dereference((head)->first); \ + pos && ({ prefetch(pos->next); 1; }); \ + pos = rcu_dereference(pos->next)) + /** * hlist_for_each_entry_rcu - iterate over rcu list of given type * @tpos: the type * to use as a loop cursor. diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h index c95bcdc18f4..03c0232b416 100644 --- a/include/linux/seq_file.h +++ b/include/linux/seq_file.h @@ -140,10 +140,17 @@ extern struct list_head *seq_list_next(void *v, struct list_head *head, */ extern struct hlist_node *seq_hlist_start(struct hlist_head *head, - loff_t pos); + loff_t pos); extern struct hlist_node *seq_hlist_start_head(struct hlist_head *head, - loff_t pos); + loff_t pos); extern struct hlist_node *seq_hlist_next(void *v, struct hlist_head *head, - loff_t *ppos); - + loff_t *ppos); + +extern struct hlist_node *seq_hlist_start_rcu(struct hlist_head *head, + loff_t pos); +extern struct hlist_node *seq_hlist_start_head_rcu(struct hlist_head *head, + loff_t pos); +extern struct hlist_node *seq_hlist_next_rcu(void *v, + struct hlist_head *head, + loff_t *ppos); #endif diff --git a/include/linux/snmp.h b/include/linux/snmp.h index 0f953fe4041..e28f5a0182e 100644 --- a/include/linux/snmp.h +++ b/include/linux/snmp.h @@ -257,6 +257,7 @@ enum LINUX_MIB_XFRMOUTPOLBLOCK, /* XfrmOutPolBlock */ LINUX_MIB_XFRMOUTPOLDEAD, /* XfrmOutPolDead */ LINUX_MIB_XFRMOUTPOLERROR, /* XfrmOutPolError */ + LINUX_MIB_XFRMFWDHDRERROR, /* XfrmFwdHdrError*/ __LINUX_MIB_XFRMMAX }; diff --git a/include/linux/tcp.h b/include/linux/tcp.h index 7fee8a4df93..a778ee02459 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -103,6 +103,8 @@ enum { #define TCP_CONGESTION 13 /* Congestion control algorithm */ #define TCP_MD5SIG 14 /* TCP MD5 Signature (RFC2385) */ #define TCP_COOKIE_TRANSACTIONS 15 /* TCP Cookie Transactions */ +#define TCP_THIN_LINEAR_TIMEOUTS 16 /* Use linear timeouts for thin streams*/ +#define TCP_THIN_DUPACK 17 /* Fast retrans. after 1 dupack */ /* for TCP_INFO socket option */ #define TCPI_OPT_TIMESTAMPS 1 @@ -340,7 +342,10 @@ struct tcp_sock { u32 frto_highmark; /* snd_nxt when RTO occurred */ u16 advmss; /* Advertised MSS */ u8 frto_counter; /* Number of new acks after RTO */ - u8 nonagle; /* Disable Nagle algorithm? */ + u8 nonagle : 4,/* Disable Nagle algorithm? */ + thin_lto : 1,/* Use linear timeouts for thin streams */ + thin_dupack : 1,/* Fast retransmit on first dupack */ + unused : 2; /* RTT measurement */ u32 srtt; /* smoothed round trip time << 3 */ diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h index 29e04beb1fc..b971e384849 100644 --- a/include/linux/xfrm.h +++ b/include/linux/xfrm.h @@ -267,8 +267,8 @@ enum xfrm_attr_type_t { XFRMA_ALG_COMP, /* struct xfrm_algo */ XFRMA_ENCAP, /* struct xfrm_algo + struct xfrm_encap_tmpl */ XFRMA_TMPL, /* 1 or more struct xfrm_user_tmpl */ - XFRMA_SA, - XFRMA_POLICY, + XFRMA_SA, /* struct xfrm_usersa_info */ + XFRMA_POLICY, /*struct xfrm_userpolicy_info */ XFRMA_SEC_CTX, /* struct xfrm_sec_ctx */ XFRMA_LTIME_VAL, XFRMA_REPLAY_VAL, @@ -276,17 +276,23 @@ enum xfrm_attr_type_t { XFRMA_ETIMER_THRESH, XFRMA_SRCADDR, /* xfrm_address_t */ XFRMA_COADDR, /* xfrm_address_t */ - XFRMA_LASTUSED, + XFRMA_LASTUSED, /* unsigned long */ XFRMA_POLICY_TYPE, /* struct xfrm_userpolicy_type */ XFRMA_MIGRATE, XFRMA_ALG_AEAD, /* struct xfrm_algo_aead */ XFRMA_KMADDRESS, /* struct xfrm_user_kmaddress */ XFRMA_ALG_AUTH_TRUNC, /* struct xfrm_algo_auth */ + XFRMA_MARK, /* struct xfrm_mark */ __XFRMA_MAX #define XFRMA_MAX (__XFRMA_MAX - 1) }; +struct xfrm_mark { + __u32 v; /* value */ + __u32 m; /* mask */ +}; + enum xfrm_sadattr_type_t { XFRMA_SAD_UNSPEC, XFRMA_SAD_CNT, diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h index 8f279ddb359..86f46c49e31 100644 --- a/include/net/ip6_fib.h +++ b/include/net/ip6_fib.h @@ -124,7 +124,7 @@ static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst) } struct fib6_walker_t { - struct fib6_walker_t *prev, *next; + struct list_head lh; struct fib6_node *root, *node; struct rt6_info *leaf; unsigned char state; diff --git a/include/net/netlink.h b/include/net/netlink.h index a63b2192ac1..f82e463c875 100644 --- a/include/net/netlink.h +++ b/include/net/netlink.h @@ -196,7 +196,7 @@ enum { * All other Exact length of attribute payload * * Example: - * static struct nla_policy my_policy[ATTR_MAX+1] __read_mostly = { + * static const struct nla_policy my_policy[ATTR_MAX+1] = { * [ATTR_FOO] = { .type = NLA_U16 }, * [ATTR_BAR] = { .type = NLA_STRING, .len = BARSIZ }, * [ATTR_BAZ] = { .len = sizeof(struct mystruct) }, diff --git a/include/net/netns/packet.h b/include/net/netns/packet.h index 637daf69888..cb4e894c0f8 100644 --- a/include/net/netns/packet.h +++ b/include/net/netns/packet.h @@ -4,11 +4,11 @@ #ifndef __NETNS_PACKET_H__ #define __NETNS_PACKET_H__ -#include <linux/list.h> +#include <linux/rculist.h> #include <linux/spinlock.h> struct netns_packet { - rwlock_t sklist_lock; + spinlock_t sklist_lock; struct hlist_head sklist; }; diff --git a/include/net/sock.h b/include/net/sock.h index 580d51fa28e..6cb1676e409 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -381,6 +381,7 @@ static __inline__ void __sk_del_node(struct sock *sk) __hlist_del(&sk->sk_node); } +/* NB: equivalent to hlist_del_init_rcu */ static __inline__ int __sk_del_node_init(struct sock *sk) { if (sk_hashed(sk)) { @@ -421,6 +422,7 @@ static __inline__ int sk_del_node_init(struct sock *sk) } return rc; } +#define sk_del_node_init_rcu(sk) sk_del_node_init(sk) static __inline__ int __sk_nulls_del_node_init_rcu(struct sock *sk) { @@ -454,6 +456,12 @@ static __inline__ void sk_add_node(struct sock *sk, struct hlist_head *list) __sk_add_node(sk, list); } +static __inline__ void sk_add_node_rcu(struct sock *sk, struct hlist_head *list) +{ + sock_hold(sk); + hlist_add_head_rcu(&sk->sk_node, list); +} + static __inline__ void __sk_nulls_add_node_rcu(struct sock *sk, struct hlist_nulls_head *list) { hlist_nulls_add_head_rcu(&sk->sk_nulls_node, list); @@ -478,6 +486,8 @@ static __inline__ void sk_add_bind_node(struct sock *sk, #define sk_for_each(__sk, node, list) \ hlist_for_each_entry(__sk, node, list, sk_node) +#define sk_for_each_rcu(__sk, node, list) \ + hlist_for_each_entry_rcu(__sk, node, list, sk_node) #define sk_nulls_for_each(__sk, node, list) \ hlist_nulls_for_each_entry(__sk, node, list, sk_nulls_node) #define sk_nulls_for_each_rcu(__sk, node, list) \ diff --git a/include/net/tcp.h b/include/net/tcp.h index 75a00c80bdd..56f0aec40ed 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -196,6 +196,9 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo); #define TCP_NAGLE_CORK 2 /* Socket is corked */ #define TCP_NAGLE_PUSH 4 /* Cork is overridden for already queued data */ +/* TCP thin-stream limits */ +#define TCP_THIN_LINEAR_RETRIES 6 /* After 6 linear retries, do exp. backoff */ + extern struct inet_timewait_death_row tcp_death_row; /* sysctl variables for tcp */ @@ -241,6 +244,8 @@ extern int sysctl_tcp_workaround_signed_windows; extern int sysctl_tcp_slow_start_after_idle; extern int sysctl_tcp_max_ssthresh; extern int sysctl_tcp_cookie_size; +extern int sysctl_tcp_thin_linear_timeouts; +extern int sysctl_tcp_thin_dupack; extern atomic_t tcp_memory_allocated; extern struct percpu_counter tcp_sockets_allocated; @@ -1386,6 +1391,14 @@ static inline void tcp_highest_sack_combine(struct sock *sk, tcp_sk(sk)->highest_sack = new; } +/* Determines whether this is a thin stream (which may suffer from + * increased latency). Used to trigger latency-reducing mechanisms. + */ +static inline unsigned int tcp_stream_is_thin(struct tcp_sock *tp) +{ + return tp->packets_out < 4 && !tcp_in_initial_slowstart(tp); +} + /* /proc */ enum tcp_seq_states { TCP_SEQ_STATE_LISTENING, diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 0beb413c01c..a7df3275b86 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -140,6 +140,7 @@ struct xfrm_state { struct xfrm_id id; struct xfrm_selector sel; + struct xfrm_mark mark; u32 genid; @@ -481,6 +482,7 @@ struct xfrm_policy { u32 priority; u32 index; + struct xfrm_mark mark; struct xfrm_selector selector; struct xfrm_lifetime_cfg lft; struct xfrm_lifetime_cur curlft; @@ -1317,7 +1319,7 @@ extern struct xfrm_state *xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t struct flowi *fl, struct xfrm_tmpl *tmpl, struct xfrm_policy *pol, int *err, unsigned short family); -extern struct xfrm_state * xfrm_stateonly_find(struct net *net, +extern struct xfrm_state *xfrm_stateonly_find(struct net *net, u32 mark, xfrm_address_t *daddr, xfrm_address_t *saddr, unsigned short family, @@ -1326,8 +1328,14 @@ extern int xfrm_state_check_expire(struct xfrm_state *x); extern void xfrm_state_insert(struct xfrm_state *x); extern int xfrm_state_add(struct xfrm_state *x); extern int xfrm_state_update(struct xfrm_state *x); -extern struct xfrm_state *xfrm_state_lookup(struct net *net, xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family); -extern struct xfrm_state *xfrm_state_lookup_byaddr(struct net *net, xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto, unsigned short family); +extern struct xfrm_state *xfrm_state_lookup(struct net *net, u32 mark, + xfrm_address_t *daddr, __be32 spi, + u8 proto, unsigned short family); +extern struct xfrm_state *xfrm_state_lookup_byaddr(struct net *net, u32 mark, + xfrm_address_t *daddr, + xfrm_address_t *saddr, + u8 proto, + unsigned short family); #ifdef CONFIG_XFRM_SUB_POLICY extern int xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n, unsigned short family); @@ -1364,7 +1372,8 @@ struct xfrmk_spdinfo { u32 spdhmcnt; }; -extern struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 seq); +extern struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 mark, + u32 seq); extern int xfrm_state_delete(struct xfrm_state *x); extern int xfrm_state_flush(struct net *net, u8 proto, struct xfrm_audit *audit_info); extern void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si); @@ -1441,17 +1450,20 @@ extern int xfrm_policy_walk(struct net *net, struct xfrm_policy_walk *walk, int (*func)(struct xfrm_policy *, int, int, void*), void *); extern void xfrm_policy_walk_done(struct xfrm_policy_walk *walk); int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl); -struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u8 type, int dir, +struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u32 mark, + u8 type, int dir, struct xfrm_selector *sel, struct xfrm_sec_ctx *ctx, int delete, int *err); -struct xfrm_policy *xfrm_policy_byid(struct net *net, u8, int dir, u32 id, int delete, int *err); +struct xfrm_policy *xfrm_policy_byid(struct net *net, u32 mark, u8, int dir, u32 id, int delete, int *err); int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info); u32 xfrm_get_acqseq(void); extern int xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi); -struct xfrm_state * xfrm_find_acq(struct net *net, u8 mode, u32 reqid, u8 proto, - xfrm_address_t *daddr, xfrm_address_t *saddr, - int create, unsigned short family); +struct xfrm_state *xfrm_find_acq(struct net *net, struct xfrm_mark *mark, + u8 mode, u32 reqid, u8 proto, + xfrm_address_t *daddr, + xfrm_address_t *saddr, int create, + unsigned short family); extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol); extern int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *xdst, struct flowi *fl, int family, int strict); @@ -1570,4 +1582,24 @@ static inline struct xfrm_state *xfrm_input_state(struct sk_buff *skb) } #endif +static inline int xfrm_mark_get(struct nlattr **attrs, struct xfrm_mark *m) +{ + if (attrs[XFRMA_MARK]) + memcpy(m, nla_data(attrs[XFRMA_MARK]), sizeof(m)); + else + m->v = m->m = 0; + + return m->v & m->m; +} + +static inline int xfrm_mark_put(struct sk_buff *skb, struct xfrm_mark *m) +{ + if (m->m | m->v) + NLA_PUT(skb, XFRMA_MARK, sizeof(struct xfrm_mark), m); + return 0; + +nla_put_failure: + return -1; +} + #endif /* _NET_XFRM_H */ diff --git a/kernel/taskstats.c b/kernel/taskstats.c index ea8384d3caa..899ca51be5e 100644 --- a/kernel/taskstats.c +++ b/kernel/taskstats.c @@ -46,15 +46,13 @@ static struct genl_family family = { .maxattr = TASKSTATS_CMD_ATTR_MAX, }; -static struct nla_policy taskstats_cmd_get_policy[TASKSTATS_CMD_ATTR_MAX+1] -__read_mostly = { +static const struct nla_policy taskstats_cmd_get_policy[TASKSTATS_CMD_ATTR_MAX+1] = { [TASKSTATS_CMD_ATTR_PID] = { .type = NLA_U32 }, [TASKSTATS_CMD_ATTR_TGID] = { .type = NLA_U32 }, [TASKSTATS_CMD_ATTR_REGISTER_CPUMASK] = { .type = NLA_STRING }, [TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK] = { .type = NLA_STRING },}; -static struct nla_policy -cgroupstats_cmd_get_policy[CGROUPSTATS_CMD_ATTR_MAX+1] __read_mostly = { +static const struct nla_policy cgroupstats_cmd_get_policy[CGROUPSTATS_CMD_ATTR_MAX+1] = { [CGROUPSTATS_CMD_ATTR_FD] = { .type = NLA_U32 }, }; diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 2e692afdc55..43923811bd6 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -2188,12 +2188,13 @@ static inline int f_pick(struct pktgen_dev *pkt_dev) /* If there was already an IPSEC SA, we keep it as is, else * we go look for it ... */ +#define DUMMY_MARK 0 static void get_ipsec_sa(struct pktgen_dev *pkt_dev, int flow) { struct xfrm_state *x = pkt_dev->flows[flow].x; if (!x) { /*slow path: we dont already have xfrm_state*/ - x = xfrm_stateonly_find(&init_net, + x = xfrm_stateonly_find(&init_net, DUMMY_MARK, (xfrm_address_t *)&pkt_dev->cur_daddr, (xfrm_address_t *)&pkt_dev->cur_saddr, AF_INET, diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index db9f5b39388..813e399220a 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c @@ -54,7 +54,7 @@ MODULE_LICENSE("GPL"); /**************** DCB attribute policies *************************************/ /* DCB netlink attributes policy */ -static struct nla_policy dcbnl_rtnl_policy[DCB_ATTR_MAX + 1] = { +static const struct nla_policy dcbnl_rtnl_policy[DCB_ATTR_MAX + 1] = { [DCB_ATTR_IFNAME] = {.type = NLA_NUL_STRING, .len = IFNAMSIZ - 1}, [DCB_ATTR_STATE] = {.type = NLA_U8}, [DCB_ATTR_PFC_CFG] = {.type = NLA_NESTED}, @@ -68,7 +68,7 @@ static struct nla_policy dcbnl_rtnl_policy[DCB_ATTR_MAX + 1] = { }; /* DCB priority flow control to User Priority nested attributes */ -static struct nla_policy dcbnl_pfc_up_nest[DCB_PFC_UP_ATTR_MAX + 1] = { +static const struct nla_policy dcbnl_pfc_up_nest[DCB_PFC_UP_ATTR_MAX + 1] = { [DCB_PFC_UP_ATTR_0] = {.type = NLA_U8}, [DCB_PFC_UP_ATTR_1] = {.type = NLA_U8}, [DCB_PFC_UP_ATTR_2] = {.type = NLA_U8}, @@ -81,7 +81,7 @@ static struct nla_policy dcbnl_pfc_up_nest[DCB_PFC_UP_ATTR_MAX + 1] = { }; /* DCB priority grouping nested attributes */ -static struct nla_policy dcbnl_pg_nest[DCB_PG_ATTR_MAX + 1] = { +static const struct nla_policy dcbnl_pg_nest[DCB_PG_ATTR_MAX + 1] = { [DCB_PG_ATTR_TC_0] = {.type = NLA_NESTED}, [DCB_PG_ATTR_TC_1] = {.type = NLA_NESTED}, [DCB_PG_ATTR_TC_2] = {.type = NLA_NESTED}, @@ -103,7 +103,7 @@ static struct nla_policy dcbnl_pg_nest[DCB_PG_ATTR_MAX + 1] = { }; /* DCB traffic class nested attributes. */ -static struct nla_policy dcbnl_tc_param_nest[DCB_TC_ATTR_PARAM_MAX + 1] = { +static const struct nla_policy dcbnl_tc_param_nest[DCB_TC_ATTR_PARAM_MAX + 1] = { [DCB_TC_ATTR_PARAM_PGID] = {.type = NLA_U8}, [DCB_TC_ATTR_PARAM_UP_MAPPING] = {.type = NLA_U8}, [DCB_TC_ATTR_PARAM_STRICT_PRIO] = {.type = NLA_U8}, @@ -112,7 +112,7 @@ static struct nla_policy dcbnl_tc_param_nest[DCB_TC_ATTR_PARAM_MAX + 1] = { }; /* DCB capabilities nested attributes. */ -static struct nla_policy dcbnl_cap_nest[DCB_CAP_ATTR_MAX + 1] = { +static const struct nla_policy dcbnl_cap_nest[DCB_CAP_ATTR_MAX + 1] = { [DCB_CAP_ATTR_ALL] = {.type = NLA_FLAG}, [DCB_CAP_ATTR_PG] = {.type = NLA_U8}, [DCB_CAP_ATTR_PFC] = {.type = NLA_U8}, @@ -124,14 +124,14 @@ static struct nla_policy dcbnl_cap_nest[DCB_CAP_ATTR_MAX + 1] = { }; /* DCB capabilities nested attributes. */ -static struct nla_policy dcbnl_numtcs_nest[DCB_NUMTCS_ATTR_MAX + 1] = { +static const struct nla_policy dcbnl_numtcs_nest[DCB_NUMTCS_ATTR_MAX + 1] = { [DCB_NUMTCS_ATTR_ALL] = {.type = NLA_FLAG}, [DCB_NUMTCS_ATTR_PG] = {.type = NLA_U8}, [DCB_NUMTCS_ATTR_PFC] = {.type = NLA_U8}, }; /* DCB BCN nested attributes. */ -static struct nla_policy dcbnl_bcn_nest[DCB_BCN_ATTR_MAX + 1] = { +static const struct nla_policy dcbnl_bcn_nest[DCB_BCN_ATTR_MAX + 1] = { [DCB_BCN_ATTR_RP_0] = {.type = NLA_U8}, [DCB_BCN_ATTR_RP_1] = {.type = NLA_U8}, [DCB_BCN_ATTR_RP_2] = {.type = NLA_U8}, @@ -160,7 +160,7 @@ static struct nla_policy dcbnl_bcn_nest[DCB_BCN_ATTR_MAX + 1] = { }; /* DCB APP nested attributes. */ -static struct nla_policy dcbnl_app_nest[DCB_APP_ATTR_MAX + 1] = { +static const struct nla_policy dcbnl_app_nest[DCB_APP_ATTR_MAX + 1] = { [DCB_APP_ATTR_IDTYPE] = {.type = NLA_U8}, [DCB_APP_ATTR_ID] = {.type = NLA_U16}, [DCB_APP_ATTR_PRIORITY] = {.type = NLA_U8}, diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c index 7ed3e4ae93a..987b47dc69a 100644 --- a/net/ipv4/ah4.c +++ b/net/ipv4/ah4.c @@ -393,7 +393,7 @@ static void ah4_err(struct sk_buff *skb, u32 info) icmp_hdr(skb)->code != ICMP_FRAG_NEEDED) return; - x = xfrm_state_lookup(net, (xfrm_address_t *)&iph->daddr, ah->spi, IPPROTO_AH, AF_INET); + x = xfrm_state_lookup(net, skb->mark, (xfrm_address_t *)&iph->daddr, ah->spi, IPPROTO_AH, AF_INET); if (!x) return; printk(KERN_DEBUG "pmtu discovery on SA AH/%08x/%08x\n", diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 1948895beb6..14ca1f1c3fb 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c @@ -422,7 +422,7 @@ static void esp4_err(struct sk_buff *skb, u32 info) icmp_hdr(skb)->code != ICMP_FRAG_NEEDED) return; - x = xfrm_state_lookup(net, (xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET); + x = xfrm_state_lookup(net, skb->mark, (xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET); if (!x) return; NETDEBUG(KERN_DEBUG "pmtu discovery on SA ESP/%08x/%08x\n", diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index a2a5983dbf0..c0c5274d027 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -793,7 +793,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev } if (mtu >= IPV6_MIN_MTU && mtu < skb->len - tunnel->hlen + gre_hlen) { - icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, dev); + icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); ip_rt_put(rt); goto tx_error; } diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c index 83ed7150089..629067571f0 100644 --- a/net/ipv4/ipcomp.c +++ b/net/ipv4/ipcomp.c @@ -36,7 +36,7 @@ static void ipcomp4_err(struct sk_buff *skb, u32 info) return; spi = htonl(ntohs(ipch->cpi)); - x = xfrm_state_lookup(net, (xfrm_address_t *)&iph->daddr, + x = xfrm_state_lookup(net, skb->mark, (xfrm_address_t *)&iph->daddr, spi, IPPROTO_COMP, AF_INET); if (!x) return; @@ -63,6 +63,7 @@ static struct xfrm_state *ipcomp_tunnel_create(struct xfrm_state *x) t->props.mode = x->props.mode; t->props.saddr.a4 = x->props.saddr.a4; t->props.flags = x->props.flags; + memcpy(&t->mark, &x->mark, sizeof(t->mark)); if (xfrm_init_state(t)) goto error; @@ -87,8 +88,9 @@ static int ipcomp_tunnel_attach(struct xfrm_state *x) struct net *net = xs_net(x); int err = 0; struct xfrm_state *t; + u32 mark = x->mark.v & x->mark.m; - t = xfrm_state_lookup(net, (xfrm_address_t *)&x->id.daddr.a4, + t = xfrm_state_lookup(net, mark, (xfrm_address_t *)&x->id.daddr.a4, x->props.saddr.a4, IPPROTO_IPIP, AF_INET); if (!t) { t = ipcomp_tunnel_create(x); diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index 7e3712ce399..c1bc074f61b 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -576,6 +576,20 @@ static struct ctl_table ipv4_table[] = { .proc_handler = proc_dointvec }, { + .procname = "tcp_thin_linear_timeouts", + .data = &sysctl_tcp_thin_linear_timeouts, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec + }, + { + .procname = "tcp_thin_dupack", + .data = &sysctl_tcp_thin_dupack, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec + }, + { .procname = "udp_mem", .data = &sysctl_udp_mem, .maxlen = sizeof(sysctl_udp_mem), diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index e471d037fcc..5901010fad5 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2229,6 +2229,20 @@ static int do_tcp_setsockopt(struct sock *sk, int level, } break; + case TCP_THIN_LINEAR_TIMEOUTS: + if (val < 0 || val > 1) + err = -EINVAL; + else + tp->thin_lto = val; + break; + + case TCP_THIN_DUPACK: + if (val < 0 || val > 1) + err = -EINVAL; + else + tp->thin_dupack = val; + break; + case TCP_CORK: /* When set indicates to always queue non-full frames. * Later the user clears this option and we transmit diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 3fddc69cccc..788851ca8c5 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -89,6 +89,8 @@ int sysctl_tcp_frto __read_mostly = 2; int sysctl_tcp_frto_response __read_mostly; int sysctl_tcp_nometrics_save __read_mostly; +int sysctl_tcp_thin_dupack __read_mostly; + int sysctl_tcp_moderate_rcvbuf __read_mostly = 1; int sysctl_tcp_abc __read_mostly; @@ -2447,6 +2449,16 @@ static int tcp_time_to_recover(struct sock *sk) return 1; } + /* If a thin stream is detected, retransmit after first + * received dupack. Employ only if SACK is supported in order + * to avoid possible corner-case series of spurious retransmissions + * Use only if there are no unsent data. + */ + if ((tp->thin_dupack || sysctl_tcp_thin_dupack) && + tcp_stream_is_thin(tp) && tcp_dupack_heuristics(tp) > 1 && + tcp_is_sack(tp) && !tcp_send_head(sk)) + return 1; + return 0; } diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index de7d1bf9114..a17629b8912 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -29,6 +29,7 @@ int sysctl_tcp_keepalive_intvl __read_mostly = TCP_KEEPALIVE_INTVL; int sysctl_tcp_retries1 __read_mostly = TCP_RETR1; int sysctl_tcp_retries2 __read_mostly = TCP_RETR2; int sysctl_tcp_orphan_retries __read_mostly; +int sysctl_tcp_thin_linear_timeouts __read_mostly; static void tcp_write_timer(unsigned long); static void tcp_delack_timer(unsigned long); @@ -415,7 +416,25 @@ void tcp_retransmit_timer(struct sock *sk) icsk->icsk_retransmits++; out_reset_timer: - icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX); + /* If stream is thin, use linear timeouts. Since 'icsk_backoff' is + * used to reset timer, set to 0. Recalculate 'icsk_rto' as this + * might be increased if the stream oscillates between thin and thick, + * thus the old value might already be too high compared to the value + * set by 'tcp_set_rto' in tcp_input.c which resets the rto without + * backoff. Limit to TCP_THIN_LINEAR_RETRIES before initiating + * exponential backoff behaviour to avoid continue hammering + * linear-timeout retransmissions into a black hole + */ + if (sk->sk_state == TCP_ESTABLISHED && + (tp->thin_lto || sysctl_tcp_thin_linear_timeouts) && + tcp_stream_is_thin(tp) && + icsk->icsk_retransmits <= TCP_THIN_LINEAR_RETRIES) { + icsk->icsk_backoff = 0; + icsk->icsk_rto = min(__tcp_set_rto(tp), TCP_RTO_MAX); + } else { + /* Use normal (exponential) backoff */ + icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX); + } inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto, TCP_RTO_MAX); if (retransmits_timed_out(sk, sysctl_tcp_retries1 + 1)) __sk_dst_reset(sk); diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c index c2f300c314b..5ac89025f9d 100644 --- a/net/ipv6/ah6.c +++ b/net/ipv6/ah6.c @@ -614,7 +614,7 @@ static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, type != ICMPV6_PKT_TOOBIG) return; - x = xfrm_state_lookup(net, (xfrm_address_t *)&iph->daddr, ah->spi, IPPROTO_AH, AF_INET6); + x = xfrm_state_lookup(net, skb->mark, (xfrm_address_t *)&iph->daddr, ah->spi, IPPROTO_AH, AF_INET6); if (!x) return; diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index 668a46b655e..ee9b93bdd6a 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c @@ -365,7 +365,7 @@ static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, type != ICMPV6_PKT_TOOBIG) return; - x = xfrm_state_lookup(net, (xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET6); + x = xfrm_state_lookup(net, skb->mark, (xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET6); if (!x) return; printk(KERN_DEBUG "pmtu discovery on SA ESP/%08x/%pI6\n", diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index 4bac362b133..074f2c084f9 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c @@ -481,7 +481,7 @@ looped_back: IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_INHDRERRORS); icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, - 0, skb->dev); + 0); kfree_skb(skb); return -1; } diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 217dbc2e28d..eb9abe24bdf 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -67,11 +67,6 @@ #include <asm/uaccess.h> #include <asm/system.h> -DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics) __read_mostly; -EXPORT_SYMBOL(icmpv6_statistics); -DEFINE_SNMP_STAT(struct icmpv6msg_mib, icmpv6msg_statistics) __read_mostly; -EXPORT_SYMBOL(icmpv6msg_statistics); - /* * The ICMP socket(s). This is the most convenient way to flow control * our ICMP output as well as maintain a clean interface throughout @@ -119,7 +114,7 @@ static __inline__ void icmpv6_xmit_unlock(struct sock *sk) */ void icmpv6_param_prob(struct sk_buff *skb, u8 code, int pos) { - icmpv6_send(skb, ICMPV6_PARAMPROB, code, pos, skb->dev); + icmpv6_send(skb, ICMPV6_PARAMPROB, code, pos); kfree_skb(skb); } @@ -305,8 +300,7 @@ static inline void mip6_addr_swap(struct sk_buff *skb) {} /* * Send an ICMP message in response to a packet in error */ -void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info, - struct net_device *dev) +void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info) { struct net *net = dev_net(skb->dev); struct inet6_dev *idev = NULL; diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 77e122f53ea..2f9847924fa 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -93,29 +93,20 @@ static __u32 rt_sernum; static void fib6_gc_timer_cb(unsigned long arg); -static struct fib6_walker_t fib6_walker_list = { - .prev = &fib6_walker_list, - .next = &fib6_walker_list, -}; - -#define FOR_WALKERS(w) for ((w)=fib6_walker_list.next; (w) != &fib6_walker_list; (w)=(w)->next) +static LIST_HEAD(fib6_walkers); +#define FOR_WALKERS(w) list_for_each_entry(w, &fib6_walkers, lh) static inline void fib6_walker_link(struct fib6_walker_t *w) { write_lock_bh(&fib6_walker_lock); - w->next = fib6_walker_list.next; - w->prev = &fib6_walker_list; - w->next->prev = w; - w->prev->next = w; + list_add(&w->lh, &fib6_walkers); write_unlock_bh(&fib6_walker_lock); } static inline void fib6_walker_unlink(struct fib6_walker_t *w) { write_lock_bh(&fib6_walker_lock); - w->next->prev = w->prev; - w->prev->next = w->next; - w->prev = w->next = w; + list_del(&w->lh); write_unlock_bh(&fib6_walker_lock); } static __inline__ u32 fib6_new_sernum(void) diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index 237e2dba6e9..e28f9203dec 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c @@ -216,8 +216,7 @@ resubmit: IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INUNKNOWNPROTOS); icmpv6_send(skb, ICMPV6_PARAMPROB, - ICMPV6_UNK_NEXTHDR, nhoff, - skb->dev); + ICMPV6_UNK_NEXTHDR, nhoff); } } else IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INDELIVERS); diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index eb6d0972863..1a5fe9ad194 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -267,7 +267,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, if (net_ratelimit()) printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n"); skb->dev = dst->dev; - icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); + icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_FRAGFAILS); kfree_skb(skb); return -EMSGSIZE; @@ -441,8 +441,7 @@ int ip6_forward(struct sk_buff *skb) if (hdr->hop_limit <= 1) { /* Force OUTPUT device used as source address */ skb->dev = dst->dev; - icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, - 0, skb->dev); + icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, 0); IP6_INC_STATS_BH(net, ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS); @@ -504,7 +503,7 @@ int ip6_forward(struct sk_buff *skb) goto error; if (addrtype & IPV6_ADDR_LINKLOCAL) { icmpv6_send(skb, ICMPV6_DEST_UNREACH, - ICMPV6_NOT_NEIGHBOUR, 0, skb->dev); + ICMPV6_NOT_NEIGHBOUR, 0); goto error; } } @@ -512,7 +511,7 @@ int ip6_forward(struct sk_buff *skb) if (skb->len > dst_mtu(dst)) { /* Again, force OUTPUT device used as source address */ skb->dev = dst->dev; - icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, dst_mtu(dst), skb->dev); + icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, dst_mtu(dst)); IP6_INC_STATS_BH(net, ip6_dst_idev(dst), IPSTATS_MIB_INTOOBIGERRORS); IP6_INC_STATS_BH(net, @@ -627,7 +626,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) */ if (!skb->local_df) { skb->dev = skb_dst(skb)->dev; - icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); + icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_FRAGFAILS); kfree_skb(skb); diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 9b02492d870..138980eec21 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -622,7 +622,7 @@ ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, if (rt && rt->rt6i_dev) skb2->dev = rt->rt6i_dev; - icmpv6_send(skb2, rel_type, rel_code, rel_info, skb2->dev); + icmpv6_send(skb2, rel_type, rel_code, rel_info); if (rt) dst_release(&rt->u.dst); @@ -1014,7 +1014,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) tel = (struct ipv6_tlv_tnl_enc_lim *)&skb_network_header(skb)[offset]; if (tel->encap_limit == 0) { icmpv6_send(skb, ICMPV6_PARAMPROB, - ICMPV6_HDR_FIELD, offset + 2, skb->dev); + ICMPV6_HDR_FIELD, offset + 2); return -1; } encap_limit = tel->encap_limit - 1; @@ -1033,7 +1033,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) err = ip6_tnl_xmit2(skb, dev, dsfield, &fl, encap_limit, &mtu); if (err != 0) { if (err == -EMSGSIZE) - icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, dev); + icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); return -1; } diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c index bb42f39c1db..85cccd6ed0b 100644 --- a/net/ipv6/ipcomp6.c +++ b/net/ipv6/ipcomp6.c @@ -64,7 +64,7 @@ static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, return; spi = htonl(ntohs(ipcomph->cpi)); - x = xfrm_state_lookup(net, (xfrm_address_t *)&iph->daddr, spi, IPPROTO_COMP, AF_INET6); + x = xfrm_state_lookup(net, skb->mark, (xfrm_address_t *)&iph->daddr, spi, IPPROTO_COMP, AF_INET6); if (!x) return; @@ -92,6 +92,7 @@ static struct xfrm_state *ipcomp6_tunnel_create(struct xfrm_state *x) t->props.family = AF_INET6; t->props.mode = x->props.mode; memcpy(t->props.saddr.a6, x->props.saddr.a6, sizeof(struct in6_addr)); + memcpy(&t->mark, &x->mark, sizeof(t->mark)); if (xfrm_init_state(t)) goto error; @@ -114,10 +115,11 @@ static int ipcomp6_tunnel_attach(struct xfrm_state *x) int err = 0; struct xfrm_state *t = NULL; __be32 spi; + u32 mark = x->mark.m & x->mark.v; spi = xfrm6_tunnel_spi_lookup(net, (xfrm_address_t *)&x->props.saddr); if (spi) - t = xfrm_state_lookup(net, (xfrm_address_t *)&x->id.daddr, + t = xfrm_state_lookup(net, mark, (xfrm_address_t *)&x->id.daddr, spi, IPPROTO_IPV6, AF_INET6); if (!t) { t = ipcomp6_tunnel_create(x); diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c index f797e8c6f3b..2794b600283 100644 --- a/net/ipv6/mip6.c +++ b/net/ipv6/mip6.c @@ -56,7 +56,7 @@ static inline void *mip6_padn(__u8 *data, __u8 padlen) static inline void mip6_param_prob(struct sk_buff *skb, u8 code, int pos) { - icmpv6_send(skb, ICMPV6_PARAMPROB, code, pos, skb->dev); + icmpv6_send(skb, ICMPV6_PARAMPROB, code, pos); } static int mip6_mh_len(int type) diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c index 8311ca31816..dd8afbaf00a 100644 --- a/net/ipv6/netfilter/ip6t_REJECT.c +++ b/net/ipv6/netfilter/ip6t_REJECT.c @@ -169,7 +169,7 @@ send_unreach(struct net *net, struct sk_buff *skb_in, unsigned char code, if (hooknum == NF_INET_LOCAL_OUT && skb_in->dev == NULL) skb_in->dev = net->loopback_dev; - icmpv6_send(skb_in, ICMPV6_DEST_UNREACH, code, 0, NULL); + icmpv6_send(skb_in, ICMPV6_DEST_UNREACH, code, 0); } static unsigned int diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index b2847ed6a7d..a555156e977 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c @@ -228,7 +228,7 @@ static void ip6_frag_expire(unsigned long data) pointer directly, device might already disappeared. */ fq->q.fragments->dev = dev; - icmpv6_send(fq->q.fragments, ICMPV6_TIME_EXCEED, ICMPV6_EXC_FRAGTIME, 0, dev); + icmpv6_send(fq->q.fragments, ICMPV6_TIME_EXCEED, ICMPV6_EXC_FRAGTIME, 0); out_rcu_unlock: rcu_read_unlock(); out: diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 8500156f263..88c0a5c49ae 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -909,7 +909,7 @@ static void ip6_link_failure(struct sk_buff *skb) { struct rt6_info *rt; - icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0, skb->dev); + icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0); rt = (struct rt6_info *) skb_dst(skb); if (rt) { @@ -1884,7 +1884,7 @@ static int ip6_pkt_drop(struct sk_buff *skb, u8 code, int ipstats_mib_noroutes) ipstats_mib_noroutes); break; } - icmpv6_send(skb, ICMPV6_DEST_UNREACH, code, 0, skb->dev); + icmpv6_send(skb, ICMPV6_DEST_UNREACH, code, 0); kfree_skb(skb); return 0; } diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 96eb2d4641c..b1eea811be4 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -743,7 +743,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); if (skb->len > mtu) { - icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, dev); + icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); ip_rt_put(rt); goto tx_error; } diff --git a/net/ipv6/tunnel6.c b/net/ipv6/tunnel6.c index 51e2832d13a..e17bc1dfc1a 100644 --- a/net/ipv6/tunnel6.c +++ b/net/ipv6/tunnel6.c @@ -98,7 +98,7 @@ static int tunnel6_rcv(struct sk_buff *skb) if (!handler->handler(skb)) return 0; - icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, skb->dev); + icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0); drop: kfree_skb(skb); @@ -116,7 +116,7 @@ static int tunnel46_rcv(struct sk_buff *skb) if (!handler->handler(skb)) return 0; - icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, skb->dev); + icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0); drop: kfree_skb(skb); diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index a7af9d68cd6..52b8347ae3b 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -680,12 +680,11 @@ static inline int udp6_csum_init(struct sk_buff *skb, struct udphdr *uh, int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, int proto) { + struct net *net = dev_net(skb->dev); struct sock *sk; struct udphdr *uh; - struct net_device *dev = skb->dev; struct in6_addr *saddr, *daddr; u32 ulen = 0; - struct net *net = dev_net(skb->dev); if (!pskb_may_pull(skb, sizeof(struct udphdr))) goto short_packet; @@ -744,7 +743,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, UDP6_INC_STATS_BH(net, UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE); - icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, dev); + icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0); kfree_skb(skb); return 0; diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c index 9084582d236..2bc98ede123 100644 --- a/net/ipv6/xfrm6_input.c +++ b/net/ipv6/xfrm6_input.c @@ -101,7 +101,7 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, break; } - x = xfrm_state_lookup_byaddr(net, dst, src, proto, AF_INET6); + x = xfrm_state_lookup_byaddr(net, skb->mark, dst, src, proto, AF_INET6); if (!x) continue; diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c index c4f4eef032a..0c92112dcba 100644 --- a/net/ipv6/xfrm6_output.c +++ b/net/ipv6/xfrm6_output.c @@ -38,7 +38,7 @@ static int xfrm6_tunnel_check_size(struct sk_buff *skb) if (!skb->local_df && skb->len > mtu) { skb->dev = dst->dev; - icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); + icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); ret = -EMSGSIZE; } diff --git a/net/irda/irnetlink.c b/net/irda/irnetlink.c index 476b307bd80..69b5b75f543 100644 --- a/net/irda/irnetlink.c +++ b/net/irda/irnetlink.c @@ -124,7 +124,7 @@ static int irda_nl_get_mode(struct sk_buff *skb, struct genl_info *info) return ret; } -static struct nla_policy irda_nl_policy[IRDA_NL_ATTR_MAX + 1] = { +static const struct nla_policy irda_nl_policy[IRDA_NL_ATTR_MAX + 1] = { [IRDA_NL_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 }, [IRDA_NL_ATTR_MODE] = { .type = NLA_U32 }, diff --git a/net/key/af_key.c b/net/key/af_key.c index 79d2c0f3c33..36870788264 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -41,10 +41,10 @@ struct netns_pfkey { struct hlist_head table; atomic_t socks_nr; }; -static DECLARE_WAIT_QUEUE_HEAD(pfkey_table_wait); -static DEFINE_RWLOCK(pfkey_table_lock); -static atomic_t pfkey_table_users = ATOMIC_INIT(0); +static DEFINE_MUTEX(pfkey_mutex); +#define DUMMY_MARK 0 +static struct xfrm_mark dummy_mark = {0, 0}; struct pfkey_sock { /* struct sock must be the first member of struct pfkey_sock */ struct sock sk; @@ -108,50 +108,6 @@ static void pfkey_sock_destruct(struct sock *sk) atomic_dec(&net_pfkey->socks_nr); } -static void pfkey_table_grab(void) -{ - write_lock_bh(&pfkey_table_lock); - - if (atomic_read(&pfkey_table_users)) { - DECLARE_WAITQUEUE(wait, current); - - add_wait_queue_exclusive(&pfkey_table_wait, &wait); - for(;;) { - set_current_state(TASK_UNINTERRUPTIBLE); - if (atomic_read(&pfkey_table_users) == 0) - break; - write_unlock_bh(&pfkey_table_lock); - schedule(); - write_lock_bh(&pfkey_table_lock); - } - - __set_current_state(TASK_RUNNING); - remove_wait_queue(&pfkey_table_wait, &wait); - } -} - -static __inline__ void pfkey_table_ungrab(void) -{ - write_unlock_bh(&pfkey_table_lock); - wake_up(&pfkey_table_wait); -} - -static __inline__ void pfkey_lock_table(void) -{ - /* read_lock() synchronizes us to pfkey_table_grab */ - - read_lock(&pfkey_table_lock); - atomic_inc(&pfkey_table_users); - read_unlock(&pfkey_table_lock); -} - -static __inline__ void pfkey_unlock_table(void) -{ - if (atomic_dec_and_test(&pfkey_table_users)) - wake_up(&pfkey_table_wait); -} - - static const struct proto_ops pfkey_ops; static void pfkey_insert(struct sock *sk) @@ -159,16 +115,16 @@ static void pfkey_insert(struct sock *sk) struct net *net = sock_net(sk); struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id); - pfkey_table_grab(); - sk_add_node(sk, &net_pfkey->table); - pfkey_table_ungrab(); + mutex_lock(&pfkey_mutex); + sk_add_node_rcu(sk, &net_pfkey->table); + mutex_unlock(&pfkey_mutex); } static void pfkey_remove(struct sock *sk) { - pfkey_table_grab(); - sk_del_node_init(sk); - pfkey_table_ungrab(); + mutex_lock(&pfkey_mutex); + sk_del_node_init_rcu(sk); + mutex_unlock(&pfkey_mutex); } static struct proto key_proto = { @@ -223,6 +179,8 @@ static int pfkey_release(struct socket *sock) sock_orphan(sk); sock->sk = NULL; skb_queue_purge(&sk->sk_write_queue); + + synchronize_rcu(); sock_put(sk); return 0; @@ -277,8 +235,8 @@ static int pfkey_broadcast(struct sk_buff *skb, gfp_t allocation, if (!skb) return -ENOMEM; - pfkey_lock_table(); - sk_for_each(sk, node, &net_pfkey->table) { + rcu_read_lock(); + sk_for_each_rcu(sk, node, &net_pfkey->table) { struct pfkey_sock *pfk = pfkey_sk(sk); int err2; @@ -309,7 +267,7 @@ static int pfkey_broadcast(struct sk_buff *skb, gfp_t allocation, if ((broadcast_flags & BROADCAST_REGISTERED) && err) err = err2; } - pfkey_unlock_table(); + rcu_read_unlock(); if (one_sk != NULL) err = pfkey_broadcast_one(skb, &skb2, allocation, one_sk); @@ -691,7 +649,7 @@ static struct xfrm_state *pfkey_xfrm_state_lookup(struct net *net, struct sadb_ if (!xaddr) return NULL; - return xfrm_state_lookup(net, xaddr, sa->sadb_sa_spi, proto, family); + return xfrm_state_lookup(net, DUMMY_MARK, xaddr, sa->sadb_sa_spi, proto, family); } #define PFKEY_ALIGN8(a) (1 + (((a) - 1) | (8 - 1))) @@ -1360,7 +1318,7 @@ static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h } if (hdr->sadb_msg_seq) { - x = xfrm_find_acq_byseq(net, hdr->sadb_msg_seq); + x = xfrm_find_acq_byseq(net, DUMMY_MARK, hdr->sadb_msg_seq); if (x && xfrm_addr_cmp(&x->id.daddr, xdaddr, family)) { xfrm_state_put(x); x = NULL; @@ -1368,7 +1326,7 @@ static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h } if (!x) - x = xfrm_find_acq(net, mode, reqid, proto, xdaddr, xsaddr, 1, family); + x = xfrm_find_acq(net, &dummy_mark, mode, reqid, proto, xdaddr, xsaddr, 1, family); if (x == NULL) return -ENOENT; @@ -1417,7 +1375,7 @@ static int pfkey_acquire(struct sock *sk, struct sk_buff *skb, struct sadb_msg * if (hdr->sadb_msg_seq == 0 || hdr->sadb_msg_errno == 0) return 0; - x = xfrm_find_acq_byseq(net, hdr->sadb_msg_seq); + x = xfrm_find_acq_byseq(net, DUMMY_MARK, hdr->sadb_msg_seq); if (x == NULL) return 0; @@ -1712,6 +1670,23 @@ static int pfkey_register(struct sock *sk, struct sk_buff *skb, struct sadb_msg return 0; } +static int unicast_flush_resp(struct sock *sk, struct sadb_msg *ihdr) +{ + struct sk_buff *skb; + struct sadb_msg *hdr; + + skb = alloc_skb(sizeof(struct sadb_msg) + 16, GFP_ATOMIC); + if (!skb) + return -ENOBUFS; + + hdr = (struct sadb_msg *) skb_put(skb, sizeof(struct sadb_msg)); + memcpy(hdr, ihdr, sizeof(struct sadb_msg)); + hdr->sadb_msg_errno = (uint8_t) 0; + hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); + + return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ONE, sk, sock_net(sk)); +} + static int key_notify_sa_flush(struct km_event *c) { struct sk_buff *skb; @@ -1740,7 +1715,7 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hd unsigned proto; struct km_event c; struct xfrm_audit audit_info; - int err; + int err, err2; proto = pfkey_satype2proto(hdr->sadb_msg_satype); if (proto == 0) @@ -1750,8 +1725,13 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hd audit_info.sessionid = audit_get_sessionid(current); audit_info.secid = 0; err = xfrm_state_flush(net, proto, &audit_info); - if (err) - return err; + err2 = unicast_flush_resp(sk, hdr); + if (err || err2) { + if (err == -ESRCH) /* empty table - go quietly */ + err = 0; + return err ? err : err2; + } + c.data.proto = proto; c.seq = hdr->sadb_msg_seq; c.pid = hdr->sadb_msg_pid; @@ -2346,7 +2326,7 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg return err; } - xp = xfrm_policy_bysel_ctx(net, XFRM_POLICY_TYPE_MAIN, + xp = xfrm_policy_bysel_ctx(net, DUMMY_MARK, XFRM_POLICY_TYPE_MAIN, pol->sadb_x_policy_dir - 1, &sel, pol_ctx, 1, &err); security_xfrm_policy_free(pol_ctx); @@ -2594,8 +2574,8 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h return -EINVAL; delete = (hdr->sadb_msg_type == SADB_X_SPDDELETE2); - xp = xfrm_policy_byid(net, XFRM_POLICY_TYPE_MAIN, dir, - pol->sadb_x_policy_id, delete, &err); + xp = xfrm_policy_byid(net, DUMMY_MARK, XFRM_POLICY_TYPE_MAIN, + dir, pol->sadb_x_policy_id, delete, &err); if (xp == NULL) return -ENOENT; @@ -2706,14 +2686,19 @@ static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg struct net *net = sock_net(sk); struct km_event c; struct xfrm_audit audit_info; - int err; + int err, err2; audit_info.loginuid = audit_get_loginuid(current); audit_info.sessionid = audit_get_sessionid(current); audit_info.secid = 0; err = xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, &audit_info); - if (err) + err2 = unicast_flush_resp(sk, hdr); + if (err || err2) { + if (err == -ESRCH) /* empty table - old silent behavior */ + return 0; return err; + } + c.data.type = XFRM_POLICY_TYPE_MAIN; c.event = XFRM_MSG_FLUSHPOLICY; c.pid = hdr->sadb_msg_pid; @@ -3675,8 +3660,8 @@ static void *pfkey_seq_start(struct seq_file *f, loff_t *ppos) struct net *net = seq_file_net(f); struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id); - read_lock(&pfkey_table_lock); - return seq_hlist_start_head(&net_pfkey->table, *ppos); + rcu_read_lock(); + return seq_hlist_start_head_rcu(&net_pfkey->table, *ppos); } static void *pfkey_seq_next(struct seq_file *f, void *v, loff_t *ppos) @@ -3684,12 +3669,12 @@ static void *pfkey_seq_next(struct seq_file *f, void *v, loff_t *ppos) struct net *net = seq_file_net(f); struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id); - return seq_hlist_next(v, &net_pfkey->table, ppos); + return seq_hlist_next_rcu(v, &net_pfkey->table, ppos); } static void pfkey_seq_stop(struct seq_file *f, void *v) { - read_unlock(&pfkey_table_lock); + rcu_read_unlock(); } static const struct seq_operations pfkey_seq_ops = { diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index 72e96d823eb..44590887a92 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c @@ -515,8 +515,7 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb, */ #ifdef CONFIG_IP_VS_IPV6 if (svc->af == AF_INET6) - icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, - skb->dev); + icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0); else #endif icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); @@ -1048,7 +1047,7 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, - 0, skb->dev); + 0); else #endif icmp_send(skb, diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c index 30b3189bd29..223b5018c7d 100644 --- a/net/netfilter/ipvs/ip_vs_xmit.c +++ b/net/netfilter/ipvs/ip_vs_xmit.c @@ -311,7 +311,7 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, mtu = dst_mtu(&rt->u.dst); if (skb->len > mtu) { dst_release(&rt->u.dst); - icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); + icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); IP_VS_DBG_RL("%s(): frag needed\n", __func__); goto tx_error; } @@ -454,7 +454,7 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, mtu = dst_mtu(&rt->u.dst); if (skb->len > mtu) { dst_release(&rt->u.dst); - icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); + icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); IP_VS_DBG_RL_PKT(0, pp, skb, 0, "ip_vs_nat_xmit_v6(): frag needed for"); goto tx_error; @@ -672,7 +672,7 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); if (mtu < ntohs(old_iph->payload_len) + sizeof(struct ipv6hdr)) { - icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); + icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); dst_release(&rt->u.dst); IP_VS_DBG_RL("%s(): frag needed\n", __func__); goto tx_error; @@ -814,7 +814,7 @@ ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, /* MTU checking */ mtu = dst_mtu(&rt->u.dst); if (skb->len > mtu) { - icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); + icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); dst_release(&rt->u.dst); IP_VS_DBG_RL("%s(): frag needed\n", __func__); goto tx_error; @@ -965,7 +965,7 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, mtu = dst_mtu(&rt->u.dst); if (skb->len > mtu) { dst_release(&rt->u.dst); - icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); + icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); IP_VS_DBG_RL("%s(): frag needed\n", __func__); goto tx_error; } diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 10f7295bcef..2f0369367ee 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -1262,24 +1262,22 @@ static int packet_release(struct socket *sock) net = sock_net(sk); po = pkt_sk(sk); - write_lock_bh(&net->packet.sklist_lock); - sk_del_node_init(sk); + spin_lock_bh(&net->packet.sklist_lock); + sk_del_node_init_rcu(sk); sock_prot_inuse_add(net, sk->sk_prot, -1); - write_unlock_bh(&net->packet.sklist_lock); - - /* - * Unhook packet receive handler. - */ + spin_unlock_bh(&net->packet.sklist_lock); + spin_lock(&po->bind_lock); if (po->running) { /* - * Remove the protocol hook + * Remove from protocol table */ - dev_remove_pack(&po->prot_hook); po->running = 0; po->num = 0; + __dev_remove_pack(&po->prot_hook); __sock_put(sk); } + spin_unlock(&po->bind_lock); packet_flush_mclist(sk); @@ -1291,10 +1289,10 @@ static int packet_release(struct socket *sock) if (po->tx_ring.pg_vec) packet_set_ring(sk, &req, 1, 1); + synchronize_net(); /* * Now the socket is dead. No more input will appear. */ - sock_orphan(sk); sock->sk = NULL; @@ -1478,10 +1476,11 @@ static int packet_create(struct net *net, struct socket *sock, int protocol, po->running = 1; } - write_lock_bh(&net->packet.sklist_lock); - sk_add_node(sk, &net->packet.sklist); + spin_lock_bh(&net->packet.sklist_lock); + sk_add_node_rcu(sk, &net->packet.sklist); sock_prot_inuse_add(net, &packet_proto, 1); - write_unlock_bh(&net->packet.sklist_lock); + spin_unlock_bh(&net->packet.sklist_lock); + return 0; out: return err; @@ -2075,8 +2074,8 @@ static int packet_notifier(struct notifier_block *this, unsigned long msg, void struct net_device *dev = data; struct net *net = dev_net(dev); - read_lock(&net->packet.sklist_lock); - sk_for_each(sk, node, &net->packet.sklist) { + rcu_read_lock(); + sk_for_each_rcu(sk, node, &net->packet.sklist) { struct packet_sock *po = pkt_sk(sk); switch (msg) { @@ -2104,18 +2103,19 @@ static int packet_notifier(struct notifier_block *this, unsigned long msg, void } break; case NETDEV_UP: - spin_lock(&po->bind_lock); - if (dev->ifindex == po->ifindex && po->num && - !po->running) { - dev_add_pack(&po->prot_hook); - sock_hold(sk); - po->running = 1; + if (dev->ifindex == po->ifindex) { + spin_lock(&po->bind_lock); + if (po->num && !po->running) { + dev_add_pack(&po->prot_hook); + sock_hold(sk); + po->running = 1; + } + spin_unlock(&po->bind_lock); } - spin_unlock(&po->bind_lock); break; } } - read_unlock(&net->packet.sklist_lock); + rcu_read_unlock(); return NOTIFY_DONE; } @@ -2512,24 +2512,24 @@ static struct notifier_block packet_netdev_notifier = { #ifdef CONFIG_PROC_FS static void *packet_seq_start(struct seq_file *seq, loff_t *pos) - __acquires(seq_file_net(seq)->packet.sklist_lock) + __acquires(RCU) { struct net *net = seq_file_net(seq); - read_lock(&net->packet.sklist_lock); - return seq_hlist_start_head(&net->packet.sklist, *pos); + + rcu_read_lock(); + return seq_hlist_start_head_rcu(&net->packet.sklist, *pos); } static void *packet_seq_next(struct seq_file *seq, void *v, loff_t *pos) { struct net *net = seq_file_net(seq); - return seq_hlist_next(v, &net->packet.sklist, pos); + return seq_hlist_next_rcu(v, &net->packet.sklist, pos); } static void packet_seq_stop(struct seq_file *seq, void *v) - __releases(seq_file_net(seq)->packet.sklist_lock) + __releases(RCU) { - struct net *net = seq_file_net(seq); - read_unlock(&net->packet.sklist_lock); + rcu_read_unlock(); } static int packet_seq_show(struct seq_file *seq, void *v) @@ -2581,7 +2581,7 @@ static const struct file_operations packet_seq_fops = { static int __net_init packet_net_init(struct net *net) { - rwlock_init(&net->packet.sklist_lock); + spin_lock_init(&net->packet.sklist_lock); INIT_HLIST_HEAD(&net->packet.sklist); if (!proc_net_fops_create(net, "packet", 0, &packet_seq_fops)) diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 9bc9b92bc09..3d9122e78f4 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -144,7 +144,7 @@ static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb) /* * SMP locking strategy: * hash table is protected with spinlock unix_table_lock - * each socket state is protected by separate rwlock. + * each socket state is protected by separate spin lock. */ static inline unsigned unix_hash_fold(__wsum n) diff --git a/net/wimax/op-msg.c b/net/wimax/op-msg.c index d3bfb6ef13a..7718657e93d 100644 --- a/net/wimax/op-msg.c +++ b/net/wimax/op-msg.c @@ -320,8 +320,7 @@ int wimax_msg(struct wimax_dev *wimax_dev, const char *pipe_name, EXPORT_SYMBOL_GPL(wimax_msg); -static const -struct nla_policy wimax_gnl_msg_policy[WIMAX_GNL_ATTR_MAX + 1] = { +static const struct nla_policy wimax_gnl_msg_policy[WIMAX_GNL_ATTR_MAX + 1] = { [WIMAX_GNL_MSG_IFIDX] = { .type = NLA_U32, }, diff --git a/net/wimax/op-reset.c b/net/wimax/op-reset.c index 35f370091f4..4dc82a54ba3 100644 --- a/net/wimax/op-reset.c +++ b/net/wimax/op-reset.c @@ -91,8 +91,7 @@ int wimax_reset(struct wimax_dev *wimax_dev) EXPORT_SYMBOL(wimax_reset); -static const -struct nla_policy wimax_gnl_reset_policy[WIMAX_GNL_ATTR_MAX + 1] = { +static const struct nla_policy wimax_gnl_reset_policy[WIMAX_GNL_ATTR_MAX + 1] = { [WIMAX_GNL_RESET_IFIDX] = { .type = NLA_U32, }, diff --git a/net/wimax/op-rfkill.c b/net/wimax/op-rfkill.c index ae752a64d92..e978c7136c9 100644 --- a/net/wimax/op-rfkill.c +++ b/net/wimax/op-rfkill.c @@ -410,8 +410,7 @@ void wimax_rfkill_rm(struct wimax_dev *wimax_dev) * just query). */ -static const -struct nla_policy wimax_gnl_rfkill_policy[WIMAX_GNL_ATTR_MAX + 1] = { +static const struct nla_policy wimax_gnl_rfkill_policy[WIMAX_GNL_ATTR_MAX + 1] = { [WIMAX_GNL_RFKILL_IFIDX] = { .type = NLA_U32, }, diff --git a/net/wimax/op-state-get.c b/net/wimax/op-state-get.c index a76b8fcb056..11ad3356eb5 100644 --- a/net/wimax/op-state-get.c +++ b/net/wimax/op-state-get.c @@ -33,8 +33,7 @@ #include "debug-levels.h" -static const -struct nla_policy wimax_gnl_state_get_policy[WIMAX_GNL_ATTR_MAX + 1] = { +static const struct nla_policy wimax_gnl_state_get_policy[WIMAX_GNL_ATTR_MAX + 1] = { [WIMAX_GNL_STGET_IFIDX] = { .type = NLA_U32, }, diff --git a/net/wimax/stack.c b/net/wimax/stack.c index c8866412f83..813e1eaea29 100644 --- a/net/wimax/stack.c +++ b/net/wimax/stack.c @@ -75,8 +75,7 @@ MODULE_PARM_DESC(debug, * close to where the data is generated. */ /* -static const -struct nla_policy wimax_gnl_re_status_change[WIMAX_GNL_ATTR_MAX + 1] = { +static const struct nla_policy wimax_gnl_re_status_change[WIMAX_GNL_ATTR_MAX + 1] = { [WIMAX_GNL_STCH_STATE_OLD] = { .type = NLA_U8 }, [WIMAX_GNL_STCH_STATE_NEW] = { .type = NLA_U8 }, }; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 5b79ecf17be..a001ea32cb7 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -58,7 +58,7 @@ static int get_rdev_dev_by_info_ifindex(struct genl_info *info, } /* policy for the attributes */ -static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = { +static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { [NL80211_ATTR_WIPHY] = { .type = NLA_U32 }, [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING, .len = 20-1 }, @@ -148,8 +148,7 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = { }; /* policy for the attributes */ -static struct nla_policy -nl80211_key_policy[NL80211_KEY_MAX + 1] __read_mostly = { +static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = { [NL80211_KEY_DATA] = { .type = NLA_BINARY, .len = WLAN_MAX_KEY_LEN }, [NL80211_KEY_IDX] = { .type = NLA_U8 }, [NL80211_KEY_CIPHER] = { .type = NLA_U32 }, @@ -2501,8 +2500,7 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info) return err; } -static const struct nla_policy - reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = { +static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = { [NL80211_ATTR_REG_RULE_FLAGS] = { .type = NLA_U32 }, [NL80211_ATTR_FREQ_RANGE_START] = { .type = NLA_U32 }, [NL80211_ATTR_FREQ_RANGE_END] = { .type = NLA_U32 }, @@ -2671,8 +2669,7 @@ do {\ } \ } while (0);\ -static struct nla_policy -nl80211_meshconf_params_policy[NL80211_MESHCONF_ATTR_MAX+1] __read_mostly = { +static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_ATTR_MAX+1] = { [NL80211_MESHCONF_RETRY_TIMEOUT] = { .type = NLA_U16 }, [NL80211_MESHCONF_CONFIRM_TIMEOUT] = { .type = NLA_U16 }, [NL80211_MESHCONF_HOLDING_TIMEOUT] = { .type = NLA_U16 }, @@ -4470,8 +4467,7 @@ static u32 rateset_to_mask(struct ieee80211_supported_band *sband, return mask; } -static struct nla_policy -nl80211_txattr_policy[NL80211_TXRATE_MAX + 1] __read_mostly = { +static const struct nla_policy nl80211_txattr_policy[NL80211_TXRATE_MAX + 1] = { [NL80211_TXRATE_LEGACY] = { .type = NLA_BINARY, .len = NL80211_MAX_SUPP_RATES }, }; diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c index e0009c17d80..45f1c98d4fc 100644 --- a/net/xfrm/xfrm_input.c +++ b/net/xfrm/xfrm_input.c @@ -152,7 +152,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) goto drop; } - x = xfrm_state_lookup(net, daddr, spi, nexthdr, family); + x = xfrm_state_lookup(net, skb->mark, daddr, spi, nexthdr, family); if (x == NULL) { XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOSTATES); xfrm_audit_state_notfound(skb, family, spi, seq); diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 2c5d93181f1..34a5ef8316e 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -556,6 +556,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) struct hlist_head *chain; struct hlist_node *entry, *newpos; struct dst_entry *gc_list; + u32 mark = policy->mark.v & policy->mark.m; write_lock_bh(&xfrm_policy_lock); chain = policy_hash_bysel(net, &policy->selector, policy->family, dir); @@ -564,6 +565,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) hlist_for_each_entry(pol, entry, chain, bydst) { if (pol->type == policy->type && !selector_cmp(&pol->selector, &policy->selector) && + (mark & pol->mark.m) == pol->mark.v && xfrm_sec_ctx_match(pol->security, policy->security) && !WARN_ON(delpol)) { if (excl) { @@ -635,8 +637,8 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) } EXPORT_SYMBOL(xfrm_policy_insert); -struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u8 type, int dir, - struct xfrm_selector *sel, +struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u32 mark, u8 type, + int dir, struct xfrm_selector *sel, struct xfrm_sec_ctx *ctx, int delete, int *err) { @@ -650,6 +652,7 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u8 type, int dir, ret = NULL; hlist_for_each_entry(pol, entry, chain, bydst) { if (pol->type == type && + (mark & pol->mark.m) == pol->mark.v && !selector_cmp(sel, &pol->selector) && xfrm_sec_ctx_match(ctx, pol->security)) { xfrm_pol_hold(pol); @@ -676,8 +679,8 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u8 type, int dir, } EXPORT_SYMBOL(xfrm_policy_bysel_ctx); -struct xfrm_policy *xfrm_policy_byid(struct net *net, u8 type, int dir, u32 id, - int delete, int *err) +struct xfrm_policy *xfrm_policy_byid(struct net *net, u32 mark, u8 type, + int dir, u32 id, int delete, int *err) { struct xfrm_policy *pol, *ret; struct hlist_head *chain; @@ -692,7 +695,8 @@ struct xfrm_policy *xfrm_policy_byid(struct net *net, u8 type, int dir, u32 id, chain = net->xfrm.policy_byidx + idx_hash(net, id); ret = NULL; hlist_for_each_entry(pol, entry, chain, byidx) { - if (pol->type == type && pol->index == id) { + if (pol->type == type && pol->index == id && + (mark & pol->mark.m) == pol->mark.v) { xfrm_pol_hold(pol); if (delete) { *err = security_xfrm_policy_delete( @@ -771,7 +775,8 @@ xfrm_policy_flush_secctx_check(struct net *net, u8 type, struct xfrm_audit *audi int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info) { - int dir, err = 0; + int dir, err = 0, cnt = 0; + struct xfrm_policy *dp; write_lock_bh(&xfrm_policy_lock); @@ -789,8 +794,10 @@ int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info) &net->xfrm.policy_inexact[dir], bydst) { if (pol->type != type) continue; - __xfrm_policy_unlink(pol, dir); + dp = __xfrm_policy_unlink(pol, dir); write_unlock_bh(&xfrm_policy_lock); + if (dp) + cnt++; xfrm_audit_policy_delete(pol, 1, audit_info->loginuid, audit_info->sessionid, @@ -809,8 +816,10 @@ int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info) bydst) { if (pol->type != type) continue; - __xfrm_policy_unlink(pol, dir); + dp = __xfrm_policy_unlink(pol, dir); write_unlock_bh(&xfrm_policy_lock); + if (dp) + cnt++; xfrm_audit_policy_delete(pol, 1, audit_info->loginuid, @@ -824,6 +833,8 @@ int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info) } } + if (!cnt) + err = -ESRCH; atomic_inc(&flow_cache_genid); out: write_unlock_bh(&xfrm_policy_lock); @@ -909,6 +920,7 @@ static int xfrm_policy_match(struct xfrm_policy *pol, struct flowi *fl, int match, ret = -ESRCH; if (pol->family != family || + (fl->mark & pol->mark.m) != pol->mark.v || pol->type != type) return ret; @@ -1033,6 +1045,10 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struc int err = 0; if (match) { + if ((sk->sk_mark & pol->mark.m) != pol->mark.v) { + pol = NULL; + goto out; + } err = security_xfrm_policy_lookup(pol->security, fl->secid, policy_to_flow_dir(dir)); @@ -1045,6 +1061,7 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struc } else pol = NULL; } +out: read_unlock_bh(&xfrm_policy_lock); return pol; } @@ -1137,6 +1154,7 @@ static struct xfrm_policy *clone_policy(struct xfrm_policy *old, int dir) } newp->lft = old->lft; newp->curlft = old->curlft; + newp->mark = old->mark; newp->action = old->action; newp->flags = old->flags; newp->xfrm_nr = old->xfrm_nr; @@ -2045,8 +2063,7 @@ int __xfrm_route_forward(struct sk_buff *skb, unsigned short family) int res; if (xfrm_decode_session(skb, &fl, family) < 0) { - /* XXX: we should have something like FWDHDRERROR here. */ - XFRM_INC_STATS(net, LINUX_MIB_XFRMINHDRERROR); + XFRM_INC_STATS(net, LINUX_MIB_XFRMFWDHDRERROR); return 0; } diff --git a/net/xfrm/xfrm_proc.c b/net/xfrm/xfrm_proc.c index 003f2c437ac..58d9ae00559 100644 --- a/net/xfrm/xfrm_proc.c +++ b/net/xfrm/xfrm_proc.c @@ -41,6 +41,7 @@ static const struct snmp_mib xfrm_mib_list[] = { SNMP_MIB_ITEM("XfrmOutPolBlock", LINUX_MIB_XFRMOUTPOLBLOCK), SNMP_MIB_ITEM("XfrmOutPolDead", LINUX_MIB_XFRMOUTPOLDEAD), SNMP_MIB_ITEM("XfrmOutPolError", LINUX_MIB_XFRMOUTPOLERROR), + SNMP_MIB_ITEM("XfrmFwdHdrError", LINUX_MIB_XFRMFWDHDRERROR), SNMP_MIB_SENTINEL }; diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index c9d6a5f1348..17d5b96f2fc 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -603,13 +603,14 @@ xfrm_state_flush_secctx_check(struct net *net, u8 proto, struct xfrm_audit *audi int xfrm_state_flush(struct net *net, u8 proto, struct xfrm_audit *audit_info) { - int i, err = 0; + int i, err = 0, cnt = 0; spin_lock_bh(&xfrm_state_lock); err = xfrm_state_flush_secctx_check(net, proto, audit_info); if (err) goto out; + err = -ESRCH; for (i = 0; i <= net->xfrm.state_hmask; i++) { struct hlist_node *entry; struct xfrm_state *x; @@ -626,13 +627,16 @@ restart: audit_info->sessionid, audit_info->secid); xfrm_state_put(x); + if (!err) + cnt++; spin_lock_bh(&xfrm_state_lock); goto restart; } } } - err = 0; + if (cnt) + err = 0; out: spin_unlock_bh(&xfrm_state_lock); @@ -665,7 +669,7 @@ xfrm_init_tempsel(struct xfrm_state *x, struct flowi *fl, return 0; } -static struct xfrm_state *__xfrm_state_lookup(struct net *net, xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family) +static struct xfrm_state *__xfrm_state_lookup(struct net *net, u32 mark, xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family) { unsigned int h = xfrm_spi_hash(net, daddr, spi, proto, family); struct xfrm_state *x; @@ -678,6 +682,8 @@ static struct xfrm_state *__xfrm_state_lookup(struct net *net, xfrm_address_t *d xfrm_addr_cmp(&x->id.daddr, daddr, family)) continue; + if ((mark & x->mark.m) != x->mark.v) + continue; xfrm_state_hold(x); return x; } @@ -685,7 +691,7 @@ static struct xfrm_state *__xfrm_state_lookup(struct net *net, xfrm_address_t *d return NULL; } -static struct xfrm_state *__xfrm_state_lookup_byaddr(struct net *net, xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto, unsigned short family) +static struct xfrm_state *__xfrm_state_lookup_byaddr(struct net *net, u32 mark, xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto, unsigned short family) { unsigned int h = xfrm_src_hash(net, daddr, saddr, family); struct xfrm_state *x; @@ -698,6 +704,8 @@ static struct xfrm_state *__xfrm_state_lookup_byaddr(struct net *net, xfrm_addre xfrm_addr_cmp(&x->props.saddr, saddr, family)) continue; + if ((mark & x->mark.m) != x->mark.v) + continue; xfrm_state_hold(x); return x; } @@ -709,12 +717,14 @@ static inline struct xfrm_state * __xfrm_state_locate(struct xfrm_state *x, int use_spi, int family) { struct net *net = xs_net(x); + u32 mark = x->mark.v & x->mark.m; if (use_spi) - return __xfrm_state_lookup(net, &x->id.daddr, x->id.spi, - x->id.proto, family); + return __xfrm_state_lookup(net, mark, &x->id.daddr, + x->id.spi, x->id.proto, family); else - return __xfrm_state_lookup_byaddr(net, &x->id.daddr, + return __xfrm_state_lookup_byaddr(net, mark, + &x->id.daddr, &x->props.saddr, x->id.proto, family); } @@ -779,6 +789,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, int acquire_in_progress = 0; int error = 0; struct xfrm_state *best = NULL; + u32 mark = pol->mark.v & pol->mark.m; to_put = NULL; @@ -787,6 +798,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h, bydst) { if (x->props.family == family && x->props.reqid == tmpl->reqid && + (mark & x->mark.m) == x->mark.v && !(x->props.flags & XFRM_STATE_WILDRECV) && xfrm_state_addr_check(x, daddr, saddr, family) && tmpl->mode == x->props.mode && @@ -802,6 +814,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h_wildcard, bydst) { if (x->props.family == family && x->props.reqid == tmpl->reqid && + (mark & x->mark.m) == x->mark.v && !(x->props.flags & XFRM_STATE_WILDRECV) && xfrm_state_addr_check(x, daddr, saddr, family) && tmpl->mode == x->props.mode && @@ -815,7 +828,7 @@ found: x = best; if (!x && !error && !acquire_in_progress) { if (tmpl->id.spi && - (x0 = __xfrm_state_lookup(net, daddr, tmpl->id.spi, + (x0 = __xfrm_state_lookup(net, mark, daddr, tmpl->id.spi, tmpl->id.proto, family)) != NULL) { to_put = x0; error = -EEXIST; @@ -829,6 +842,7 @@ found: /* Initialize temporary selector matching only * to current session. */ xfrm_init_tempsel(x, fl, tmpl, daddr, saddr, family); + memcpy(&x->mark, &pol->mark, sizeof(x->mark)); error = security_xfrm_state_alloc_acquire(x, pol->security, fl->secid); if (error) { @@ -871,7 +885,7 @@ out: } struct xfrm_state * -xfrm_stateonly_find(struct net *net, +xfrm_stateonly_find(struct net *net, u32 mark, xfrm_address_t *daddr, xfrm_address_t *saddr, unsigned short family, u8 mode, u8 proto, u32 reqid) { @@ -884,6 +898,7 @@ xfrm_stateonly_find(struct net *net, hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h, bydst) { if (x->props.family == family && x->props.reqid == reqid && + (mark & x->mark.m) == x->mark.v && !(x->props.flags & XFRM_STATE_WILDRECV) && xfrm_state_addr_check(x, daddr, saddr, family) && mode == x->props.mode && @@ -946,11 +961,13 @@ static void __xfrm_state_bump_genids(struct xfrm_state *xnew) struct xfrm_state *x; struct hlist_node *entry; unsigned int h; + u32 mark = xnew->mark.v & xnew->mark.m; h = xfrm_dst_hash(net, &xnew->id.daddr, &xnew->props.saddr, reqid, family); hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h, bydst) { if (x->props.family == family && x->props.reqid == reqid && + (mark & x->mark.m) == x->mark.v && !xfrm_addr_cmp(&x->id.daddr, &xnew->id.daddr, family) && !xfrm_addr_cmp(&x->props.saddr, &xnew->props.saddr, family)) x->genid = xfrm_state_genid; @@ -967,11 +984,12 @@ void xfrm_state_insert(struct xfrm_state *x) EXPORT_SYMBOL(xfrm_state_insert); /* xfrm_state_lock is held */ -static struct xfrm_state *__find_acq_core(struct net *net, unsigned short family, u8 mode, u32 reqid, u8 proto, xfrm_address_t *daddr, xfrm_address_t *saddr, int create) +static struct xfrm_state *__find_acq_core(struct net *net, struct xfrm_mark *m, unsigned short family, u8 mode, u32 reqid, u8 proto, xfrm_address_t *daddr, xfrm_address_t *saddr, int create) { unsigned int h = xfrm_dst_hash(net, daddr, saddr, reqid, family); struct hlist_node *entry; struct xfrm_state *x; + u32 mark = m->v & m->m; hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h, bydst) { if (x->props.reqid != reqid || @@ -980,6 +998,7 @@ static struct xfrm_state *__find_acq_core(struct net *net, unsigned short family x->km.state != XFRM_STATE_ACQ || x->id.spi != 0 || x->id.proto != proto || + (mark & x->mark.m) != x->mark.v || xfrm_addr_cmp(&x->id.daddr, daddr, family) || xfrm_addr_cmp(&x->props.saddr, saddr, family)) continue; @@ -1022,6 +1041,8 @@ static struct xfrm_state *__find_acq_core(struct net *net, unsigned short family x->props.family = family; x->props.mode = mode; x->props.reqid = reqid; + x->mark.v = m->v; + x->mark.m = m->m; x->lft.hard_add_expires_seconds = net->xfrm.sysctl_acq_expires; xfrm_state_hold(x); tasklet_hrtimer_start(&x->mtimer, ktime_set(net->xfrm.sysctl_acq_expires, 0), HRTIMER_MODE_REL); @@ -1038,7 +1059,7 @@ static struct xfrm_state *__find_acq_core(struct net *net, unsigned short family return x; } -static struct xfrm_state *__xfrm_find_acq_byseq(struct net *net, u32 seq); +static struct xfrm_state *__xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq); int xfrm_state_add(struct xfrm_state *x) { @@ -1046,6 +1067,7 @@ int xfrm_state_add(struct xfrm_state *x) struct xfrm_state *x1, *to_put; int family; int err; + u32 mark = x->mark.v & x->mark.m; int use_spi = xfrm_id_proto_match(x->id.proto, IPSEC_PROTO_ANY); family = x->props.family; @@ -1063,7 +1085,7 @@ int xfrm_state_add(struct xfrm_state *x) } if (use_spi && x->km.seq) { - x1 = __xfrm_find_acq_byseq(net, x->km.seq); + x1 = __xfrm_find_acq_byseq(net, mark, x->km.seq); if (x1 && ((x1->id.proto != x->id.proto) || xfrm_addr_cmp(&x1->id.daddr, &x->id.daddr, family))) { to_put = x1; @@ -1072,8 +1094,8 @@ int xfrm_state_add(struct xfrm_state *x) } if (use_spi && !x1) - x1 = __find_acq_core(net, family, x->props.mode, x->props.reqid, - x->id.proto, + x1 = __find_acq_core(net, &x->mark, family, x->props.mode, + x->props.reqid, x->id.proto, &x->id.daddr, &x->props.saddr, 0); __xfrm_state_bump_genids(x); @@ -1147,6 +1169,8 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, int *errp) goto error; } + memcpy(&x->mark, &orig->mark, sizeof(x->mark)); + err = xfrm_init_state(x); if (err) goto error; @@ -1338,41 +1362,41 @@ int xfrm_state_check_expire(struct xfrm_state *x) EXPORT_SYMBOL(xfrm_state_check_expire); struct xfrm_state * -xfrm_state_lookup(struct net *net, xfrm_address_t *daddr, __be32 spi, u8 proto, - unsigned short family) +xfrm_state_lookup(struct net *net, u32 mark, xfrm_address_t *daddr, __be32 spi, + u8 proto, unsigned short family) { struct xfrm_state *x; spin_lock_bh(&xfrm_state_lock); - x = __xfrm_state_lookup(net, daddr, spi, proto, family); + x = __xfrm_state_lookup(net, mark, daddr, spi, proto, family); spin_unlock_bh(&xfrm_state_lock); return x; } EXPORT_SYMBOL(xfrm_state_lookup); struct xfrm_state * -xfrm_state_lookup_byaddr(struct net *net, +xfrm_state_lookup_byaddr(struct net *net, u32 mark, xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto, unsigned short family) { struct xfrm_state *x; spin_lock_bh(&xfrm_state_lock); - x = __xfrm_state_lookup_byaddr(net, daddr, saddr, proto, family); + x = __xfrm_state_lookup_byaddr(net, mark, daddr, saddr, proto, family); spin_unlock_bh(&xfrm_state_lock); return x; } EXPORT_SYMBOL(xfrm_state_lookup_byaddr); struct xfrm_state * -xfrm_find_acq(struct net *net, u8 mode, u32 reqid, u8 proto, +xfrm_find_acq(struct net *net, struct xfrm_mark *mark, u8 mode, u32 reqid, u8 proto, xfrm_address_t *daddr, xfrm_address_t *saddr, int create, unsigned short family) { struct xfrm_state *x; spin_lock_bh(&xfrm_state_lock); - x = __find_acq_core(net, family, mode, reqid, proto, daddr, saddr, create); + x = __find_acq_core(net, mark, family, mode, reqid, proto, daddr, saddr, create); spin_unlock_bh(&xfrm_state_lock); return x; @@ -1419,7 +1443,7 @@ EXPORT_SYMBOL(xfrm_state_sort); /* Silly enough, but I'm lazy to build resolution list */ -static struct xfrm_state *__xfrm_find_acq_byseq(struct net *net, u32 seq) +static struct xfrm_state *__xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq) { int i; @@ -1429,6 +1453,7 @@ static struct xfrm_state *__xfrm_find_acq_byseq(struct net *net, u32 seq) hlist_for_each_entry(x, entry, net->xfrm.state_bydst+i, bydst) { if (x->km.seq == seq && + (mark & x->mark.m) == x->mark.v && x->km.state == XFRM_STATE_ACQ) { xfrm_state_hold(x); return x; @@ -1438,12 +1463,12 @@ static struct xfrm_state *__xfrm_find_acq_byseq(struct net *net, u32 seq) return NULL; } -struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 seq) +struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq) { struct xfrm_state *x; spin_lock_bh(&xfrm_state_lock); - x = __xfrm_find_acq_byseq(net, seq); + x = __xfrm_find_acq_byseq(net, mark, seq); spin_unlock_bh(&xfrm_state_lock); return x; } @@ -1470,6 +1495,7 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high) int err = -ENOENT; __be32 minspi = htonl(low); __be32 maxspi = htonl(high); + u32 mark = x->mark.v & x->mark.m; spin_lock_bh(&x->lock); if (x->km.state == XFRM_STATE_DEAD) @@ -1482,7 +1508,7 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high) err = -ENOENT; if (minspi == maxspi) { - x0 = xfrm_state_lookup(net, &x->id.daddr, minspi, x->id.proto, x->props.family); + x0 = xfrm_state_lookup(net, mark, &x->id.daddr, minspi, x->id.proto, x->props.family); if (x0) { xfrm_state_put(x0); goto unlock; @@ -1492,7 +1518,7 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high) u32 spi = 0; for (h=0; h<high-low+1; h++) { spi = low + net_random()%(high-low+1); - x0 = xfrm_state_lookup(net, &x->id.daddr, htonl(spi), x->id.proto, x->props.family); + x0 = xfrm_state_lookup(net, mark, &x->id.daddr, htonl(spi), x->id.proto, x->props.family); if (x0 == NULL) { x->id.spi = htonl(spi); break; diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 943c8712bd9..6106b72826d 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -446,6 +446,8 @@ static struct xfrm_state *xfrm_state_construct(struct net *net, goto error; } + xfrm_mark_get(attrs, &x->mark); + err = xfrm_init_state(x); if (err) goto error; @@ -526,11 +528,13 @@ static struct xfrm_state *xfrm_user_state_lookup(struct net *net, int *errp) { struct xfrm_state *x = NULL; + struct xfrm_mark m; int err; + u32 mark = xfrm_mark_get(attrs, &m); if (xfrm_id_proto_match(p->proto, IPSEC_PROTO_ANY)) { err = -ESRCH; - x = xfrm_state_lookup(net, &p->daddr, p->spi, p->proto, p->family); + x = xfrm_state_lookup(net, mark, &p->daddr, p->spi, p->proto, p->family); } else { xfrm_address_t *saddr = NULL; @@ -541,7 +545,8 @@ static struct xfrm_state *xfrm_user_state_lookup(struct net *net, } err = -ESRCH; - x = xfrm_state_lookup_byaddr(net, &p->daddr, saddr, + x = xfrm_state_lookup_byaddr(net, mark, + &p->daddr, saddr, p->proto, p->family); } @@ -683,6 +688,9 @@ static int copy_to_user_state_extra(struct xfrm_state *x, if (x->encap) NLA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap); + if (xfrm_mark_put(skb, &x->mark)) + goto nla_put_failure; + if (x->security && copy_sec_ctx(x->security, skb) < 0) goto nla_put_failure; @@ -947,6 +955,8 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, xfrm_address_t *daddr; int family; int err; + u32 mark; + struct xfrm_mark m; p = nlmsg_data(nlh); err = verify_userspi_info(p); @@ -957,8 +967,10 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, daddr = &p->info.id.daddr; x = NULL; + + mark = xfrm_mark_get(attrs, &m); if (p->info.seq) { - x = xfrm_find_acq_byseq(net, p->info.seq); + x = xfrm_find_acq_byseq(net, mark, p->info.seq); if (x && xfrm_addr_cmp(&x->id.daddr, daddr, family)) { xfrm_state_put(x); x = NULL; @@ -966,7 +978,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, } if (!x) - x = xfrm_find_acq(net, p->info.mode, p->info.reqid, + x = xfrm_find_acq(net, &m, p->info.mode, p->info.reqid, p->info.id.proto, daddr, &p->info.saddr, 1, family); @@ -1220,6 +1232,8 @@ static struct xfrm_policy *xfrm_policy_construct(struct net *net, struct xfrm_us if (err) goto error; + xfrm_mark_get(attrs, &xp->mark); + return xp; error: *errp = err; @@ -1366,10 +1380,13 @@ static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr goto nlmsg_failure; if (copy_to_user_policy_type(xp->type, skb) < 0) goto nlmsg_failure; + if (xfrm_mark_put(skb, &xp->mark)) + goto nla_put_failure; nlmsg_end(skb, nlh); return 0; +nla_put_failure: nlmsg_failure: nlmsg_cancel(skb, nlh); return -EMSGSIZE; @@ -1441,6 +1458,8 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, int err; struct km_event c; int delete; + struct xfrm_mark m; + u32 mark = xfrm_mark_get(attrs, &m); p = nlmsg_data(nlh); delete = nlh->nlmsg_type == XFRM_MSG_DELPOLICY; @@ -1454,7 +1473,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, return err; if (p->index) - xp = xfrm_policy_byid(net, type, p->dir, p->index, delete, &err); + xp = xfrm_policy_byid(net, mark, type, p->dir, p->index, delete, &err); else { struct nlattr *rt = attrs[XFRMA_SEC_CTX]; struct xfrm_sec_ctx *ctx; @@ -1471,8 +1490,8 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, if (err) return err; } - xp = xfrm_policy_bysel_ctx(net, type, p->dir, &p->sel, ctx, - delete, &err); + xp = xfrm_policy_bysel_ctx(net, mark, type, p->dir, &p->sel, + ctx, delete, &err); security_xfrm_policy_free(ctx); } if (xp == NULL) @@ -1524,8 +1543,11 @@ static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh, audit_info.sessionid = NETLINK_CB(skb).sessionid; audit_info.secid = NETLINK_CB(skb).sid; err = xfrm_state_flush(net, p->proto, &audit_info); - if (err) + if (err) { + if (err == -ESRCH) /* empty table */ + return 0; return err; + } c.data.proto = p->proto; c.event = nlh->nlmsg_type; c.seq = nlh->nlmsg_seq; @@ -1541,6 +1563,7 @@ static inline size_t xfrm_aevent_msgsize(void) return NLMSG_ALIGN(sizeof(struct xfrm_aevent_id)) + nla_total_size(sizeof(struct xfrm_replay_state)) + nla_total_size(sizeof(struct xfrm_lifetime_cur)) + + nla_total_size(sizeof(struct xfrm_mark)) + nla_total_size(4) /* XFRM_AE_RTHR */ + nla_total_size(4); /* XFRM_AE_ETHR */ } @@ -1573,6 +1596,9 @@ static int build_aevent(struct sk_buff *skb, struct xfrm_state *x, struct km_eve NLA_PUT_U32(skb, XFRMA_ETIMER_THRESH, x->replay_maxage * 10 / HZ); + if (xfrm_mark_put(skb, &x->mark)) + goto nla_put_failure; + return nlmsg_end(skb, nlh); nla_put_failure: @@ -1588,6 +1614,8 @@ static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh, struct sk_buff *r_skb; int err; struct km_event c; + u32 mark; + struct xfrm_mark m; struct xfrm_aevent_id *p = nlmsg_data(nlh); struct xfrm_usersa_id *id = &p->sa_id; @@ -1595,7 +1623,9 @@ static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh, if (r_skb == NULL) return -ENOMEM; - x = xfrm_state_lookup(net, &id->daddr, id->spi, id->proto, id->family); + mark = xfrm_mark_get(attrs, &m); + + x = xfrm_state_lookup(net, mark, &id->daddr, id->spi, id->proto, id->family); if (x == NULL) { kfree_skb(r_skb); return -ESRCH; @@ -1626,6 +1656,8 @@ static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh, struct xfrm_state *x; struct km_event c; int err = - EINVAL; + u32 mark = 0; + struct xfrm_mark m; struct xfrm_aevent_id *p = nlmsg_data(nlh); struct nlattr *rp = attrs[XFRMA_REPLAY_VAL]; struct nlattr *lt = attrs[XFRMA_LTIME_VAL]; @@ -1637,7 +1669,9 @@ static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh, if (!(nlh->nlmsg_flags&NLM_F_REPLACE)) return err; - x = xfrm_state_lookup(net, &p->sa_id.daddr, p->sa_id.spi, p->sa_id.proto, p->sa_id.family); + mark = xfrm_mark_get(attrs, &m); + + x = xfrm_state_lookup(net, mark, &p->sa_id.daddr, p->sa_id.spi, p->sa_id.proto, p->sa_id.family); if (x == NULL) return -ESRCH; @@ -1676,8 +1710,12 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, audit_info.sessionid = NETLINK_CB(skb).sessionid; audit_info.secid = NETLINK_CB(skb).sid; err = xfrm_policy_flush(net, type, &audit_info); - if (err) + if (err) { + if (err == -ESRCH) /* empty table */ + return 0; return err; + } + c.data.type = type; c.event = nlh->nlmsg_type; c.seq = nlh->nlmsg_seq; @@ -1696,13 +1734,15 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, struct xfrm_userpolicy_info *p = &up->pol; u8 type = XFRM_POLICY_TYPE_MAIN; int err = -ENOENT; + struct xfrm_mark m; + u32 mark = xfrm_mark_get(attrs, &m); err = copy_from_user_policy_type(&type, attrs); if (err) return err; if (p->index) - xp = xfrm_policy_byid(net, type, p->dir, p->index, 0, &err); + xp = xfrm_policy_byid(net, mark, type, p->dir, p->index, 0, &err); else { struct nlattr *rt = attrs[XFRMA_SEC_CTX]; struct xfrm_sec_ctx *ctx; @@ -1719,7 +1759,8 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, if (err) return err; } - xp = xfrm_policy_bysel_ctx(net, type, p->dir, &p->sel, ctx, 0, &err); + xp = xfrm_policy_bysel_ctx(net, mark, type, p->dir, + &p->sel, ctx, 0, &err); security_xfrm_policy_free(ctx); } if (xp == NULL) @@ -1759,8 +1800,10 @@ static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh, int err; struct xfrm_user_expire *ue = nlmsg_data(nlh); struct xfrm_usersa_info *p = &ue->state; + struct xfrm_mark m; + u32 mark = xfrm_mark_get(attrs, &m);; - x = xfrm_state_lookup(net, &p->id.daddr, p->id.spi, p->id.proto, p->family); + x = xfrm_state_lookup(net, mark, &p->id.daddr, p->id.spi, p->id.proto, p->family); err = -ENOENT; if (x == NULL) @@ -1794,6 +1837,7 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh, struct xfrm_user_tmpl *ut; int i; struct nlattr *rt = attrs[XFRMA_TMPL]; + struct xfrm_mark mark; struct xfrm_user_acquire *ua = nlmsg_data(nlh); struct xfrm_state *x = xfrm_state_alloc(net); @@ -1802,6 +1846,8 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh, if (!x) goto nomem; + xfrm_mark_get(attrs, &mark); + err = verify_newpolicy_info(&ua->policy); if (err) goto bad_policy; @@ -1814,7 +1860,8 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh, memcpy(&x->id, &ua->id, sizeof(ua->id)); memcpy(&x->props.saddr, &ua->saddr, sizeof(ua->saddr)); memcpy(&x->sel, &ua->sel, sizeof(ua->sel)); - + xp->mark.m = x->mark.m = mark.m; + xp->mark.v = x->mark.v = mark.v; ut = nla_data(rt); /* extract the templates and for each call km_key */ for (i = 0; i < xp->xfrm_nr; i++, ut++) { @@ -2074,6 +2121,7 @@ static const struct nla_policy xfrma_policy[XFRMA_MAX+1] = { [XFRMA_POLICY_TYPE] = { .len = sizeof(struct xfrm_userpolicy_type)}, [XFRMA_MIGRATE] = { .len = sizeof(struct xfrm_user_migrate) }, [XFRMA_KMADDRESS] = { .len = sizeof(struct xfrm_user_kmaddress) }, + [XFRMA_MARK] = { .len = sizeof(struct xfrm_mark) }, }; static struct xfrm_link { @@ -2153,7 +2201,8 @@ static void xfrm_netlink_rcv(struct sk_buff *skb) static inline size_t xfrm_expire_msgsize(void) { - return NLMSG_ALIGN(sizeof(struct xfrm_user_expire)); + return NLMSG_ALIGN(sizeof(struct xfrm_user_expire)) + + nla_total_size(sizeof(struct xfrm_mark)); } static int build_expire(struct sk_buff *skb, struct xfrm_state *x, struct km_event *c) @@ -2169,7 +2218,13 @@ static int build_expire(struct sk_buff *skb, struct xfrm_state *x, struct km_eve copy_to_user_state(x, &ue->state); ue->hard = (c->data.hard != 0) ? 1 : 0; + if (xfrm_mark_put(skb, &x->mark)) + goto nla_put_failure; + return nlmsg_end(skb, nlh); + +nla_put_failure: + return -EMSGSIZE; } static int xfrm_exp_state_notify(struct xfrm_state *x, struct km_event *c) @@ -2181,8 +2236,10 @@ static int xfrm_exp_state_notify(struct xfrm_state *x, struct km_event *c) if (skb == NULL) return -ENOMEM; - if (build_expire(skb, x, c) < 0) - BUG(); + if (build_expire(skb, x, c) < 0) { + kfree_skb(skb); + return -EMSGSIZE; + } return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_EXPIRE, GFP_ATOMIC); } @@ -2270,6 +2327,7 @@ static int xfrm_notify_sa(struct xfrm_state *x, struct km_event *c) if (c->event == XFRM_MSG_DELSA) { len += nla_total_size(headlen); headlen = sizeof(*id); + len += nla_total_size(sizeof(struct xfrm_mark)); } len += NLMSG_ALIGN(headlen); @@ -2340,6 +2398,7 @@ static inline size_t xfrm_acquire_msgsize(struct xfrm_state *x, { return NLMSG_ALIGN(sizeof(struct xfrm_user_acquire)) + nla_total_size(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr) + + nla_total_size(sizeof(struct xfrm_mark)) + nla_total_size(xfrm_user_sec_ctx_size(x->security)) + userpolicy_type_attrsize(); } @@ -2372,9 +2431,12 @@ static int build_acquire(struct sk_buff *skb, struct xfrm_state *x, goto nlmsg_failure; if (copy_to_user_policy_type(xp->type, skb) < 0) goto nlmsg_failure; + if (xfrm_mark_put(skb, &xp->mark)) + goto nla_put_failure; return nlmsg_end(skb, nlh); +nla_put_failure: nlmsg_failure: nlmsg_cancel(skb, nlh); return -EMSGSIZE; @@ -2461,6 +2523,7 @@ static inline size_t xfrm_polexpire_msgsize(struct xfrm_policy *xp) return NLMSG_ALIGN(sizeof(struct xfrm_user_polexpire)) + nla_total_size(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr) + nla_total_size(xfrm_user_sec_ctx_size(xp->security)) + + nla_total_size(sizeof(struct xfrm_mark)) + userpolicy_type_attrsize(); } @@ -2483,10 +2546,13 @@ static int build_polexpire(struct sk_buff *skb, struct xfrm_policy *xp, goto nlmsg_failure; if (copy_to_user_policy_type(xp->type, skb) < 0) goto nlmsg_failure; + if (xfrm_mark_put(skb, &xp->mark)) + goto nla_put_failure; upe->hard = !!hard; return nlmsg_end(skb, nlh); +nla_put_failure: nlmsg_failure: nlmsg_cancel(skb, nlh); return -EMSGSIZE; @@ -2523,6 +2589,7 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event * headlen = sizeof(*id); } len += userpolicy_type_attrsize(); + len += nla_total_size(sizeof(struct xfrm_mark)); len += NLMSG_ALIGN(headlen); skb = nlmsg_new(len, GFP_ATOMIC); @@ -2558,10 +2625,14 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event * if (copy_to_user_policy_type(xp->type, skb) < 0) goto nlmsg_failure; + if (xfrm_mark_put(skb, &xp->mark)) + goto nla_put_failure; + nlmsg_end(skb, nlh); return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC); +nla_put_failure: nlmsg_failure: kfree_skb(skb); return -1; |