diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-02-10 14:48:11 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-02-10 14:48:11 -0500 |
commit | 29ef01179d37168a021293ede77afbf091a49af4 (patch) | |
tree | ed6a36a9fd9294a6f71b572a55e34435a90e4348 /drivers/net | |
parent | 5a6fe125950676015f5108fb71b2a67441755003 (diff) | |
parent | 4906f9985e310fc01f956256b0d58ac28b0dcb19 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (23 commits)
bridge: Fix LRO crash with tun
IPv6: fix to set device name when new IPv6 over IPv6 tunnel device is created.
gianfar: Fix boot hangs while bringing up gianfar ethernet
netfilter: xt_sctp: sctp chunk mapping doesn't work
netfilter: ctnetlink: fix echo if not subscribed to any multicast group
netfilter: ctnetlink: allow changing NAT sequence adjustment in creation
netfilter: nf_conntrack_ipv6: don't track ICMPv6 negotiation message
netfilter: fix tuple inversion for Node information request
netxen: fix msi-x interrupt handling
de2104x: force correct order when writing to rx ring
tun: Fix unicast filter overflow
drivers/isdn: introduce missing kfree
drivers/atm: introduce missing kfree
sunhme: Don't match PCI devices in SBUS probe.
9p: fix endian issues [attempt 3]
net_dma: call dmaengine_get only if NET_DMA enabled
3c509: Fix resume from hibernation for PnP mode.
sungem: Soft lockup in sungem on Netra AC200 when switching interface up
RxRPC: Fix a potential NULL dereference
r8169: Don't update statistics counters when interface is down
...
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/3c509.c | 1 | ||||
-rw-r--r-- | drivers/net/gianfar.c | 6 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic.h | 2 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_main.c | 13 | ||||
-rw-r--r-- | drivers/net/r8169.c | 93 | ||||
-rw-r--r-- | drivers/net/sungem.c | 8 | ||||
-rw-r--r-- | drivers/net/sunhme.c | 12 | ||||
-rw-r--r-- | drivers/net/tulip/de2104x.c | 3 | ||||
-rw-r--r-- | drivers/net/tun.c | 10 |
9 files changed, 100 insertions, 48 deletions
diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c index 535c234286ea..8c694213035b 100644 --- a/drivers/net/3c509.c +++ b/drivers/net/3c509.c | |||
@@ -1475,6 +1475,7 @@ el3_resume(struct device *pdev) | |||
1475 | spin_lock_irqsave(&lp->lock, flags); | 1475 | spin_lock_irqsave(&lp->lock, flags); |
1476 | 1476 | ||
1477 | outw(PowerUp, ioaddr + EL3_CMD); | 1477 | outw(PowerUp, ioaddr + EL3_CMD); |
1478 | EL3WINDOW(0); | ||
1478 | el3_up(dev); | 1479 | el3_up(dev); |
1479 | 1480 | ||
1480 | if (netif_running(dev)) | 1481 | if (netif_running(dev)) |
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index acae2d8cd688..9b12a13a640f 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c | |||
@@ -1629,6 +1629,12 @@ static void gfar_schedule_cleanup(struct net_device *dev) | |||
1629 | if (netif_rx_schedule_prep(&priv->napi)) { | 1629 | if (netif_rx_schedule_prep(&priv->napi)) { |
1630 | gfar_write(&priv->regs->imask, IMASK_RTX_DISABLED); | 1630 | gfar_write(&priv->regs->imask, IMASK_RTX_DISABLED); |
1631 | __netif_rx_schedule(&priv->napi); | 1631 | __netif_rx_schedule(&priv->napi); |
1632 | } else { | ||
1633 | /* | ||
1634 | * Clear IEVENT, so interrupts aren't called again | ||
1635 | * because of the packets that have already arrived. | ||
1636 | */ | ||
1637 | gfar_write(&priv->regs->ievent, IEVENT_RTX_MASK); | ||
1632 | } | 1638 | } |
1633 | 1639 | ||
1634 | spin_unlock(&priv->rxlock); | 1640 | spin_unlock(&priv->rxlock); |
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 9c78c963b721..f4dd9acb6877 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h | |||
@@ -1203,7 +1203,7 @@ typedef struct { | |||
1203 | #define NETXEN_IS_MSI_FAMILY(adapter) \ | 1203 | #define NETXEN_IS_MSI_FAMILY(adapter) \ |
1204 | ((adapter)->flags & (NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED)) | 1204 | ((adapter)->flags & (NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED)) |
1205 | 1205 | ||
1206 | #define MSIX_ENTRIES_PER_ADAPTER 8 | 1206 | #define MSIX_ENTRIES_PER_ADAPTER 1 |
1207 | #define NETXEN_MSIX_TBL_SPACE 8192 | 1207 | #define NETXEN_MSIX_TBL_SPACE 8192 |
1208 | #define NETXEN_PCI_REG_MSIX_TBL 0x44 | 1208 | #define NETXEN_PCI_REG_MSIX_TBL 0x44 |
1209 | 1209 | ||
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 645d384fe87e..3b17a7936147 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -76,6 +76,7 @@ static void netxen_nic_poll_controller(struct net_device *netdev); | |||
76 | #endif | 76 | #endif |
77 | static irqreturn_t netxen_intr(int irq, void *data); | 77 | static irqreturn_t netxen_intr(int irq, void *data); |
78 | static irqreturn_t netxen_msi_intr(int irq, void *data); | 78 | static irqreturn_t netxen_msi_intr(int irq, void *data); |
79 | static irqreturn_t netxen_msix_intr(int irq, void *data); | ||
79 | 80 | ||
80 | /* PCI Device ID Table */ | 81 | /* PCI Device ID Table */ |
81 | #define ENTRY(device) \ | 82 | #define ENTRY(device) \ |
@@ -1084,7 +1085,9 @@ static int netxen_nic_open(struct net_device *netdev) | |||
1084 | for (ring = 0; ring < adapter->max_rds_rings; ring++) | 1085 | for (ring = 0; ring < adapter->max_rds_rings; ring++) |
1085 | netxen_post_rx_buffers(adapter, ctx, ring); | 1086 | netxen_post_rx_buffers(adapter, ctx, ring); |
1086 | } | 1087 | } |
1087 | if (NETXEN_IS_MSI_FAMILY(adapter)) | 1088 | if (adapter->flags & NETXEN_NIC_MSIX_ENABLED) |
1089 | handler = netxen_msix_intr; | ||
1090 | else if (adapter->flags & NETXEN_NIC_MSI_ENABLED) | ||
1088 | handler = netxen_msi_intr; | 1091 | handler = netxen_msi_intr; |
1089 | else { | 1092 | else { |
1090 | flags |= IRQF_SHARED; | 1093 | flags |= IRQF_SHARED; |
@@ -1612,6 +1615,14 @@ static irqreturn_t netxen_msi_intr(int irq, void *data) | |||
1612 | return IRQ_HANDLED; | 1615 | return IRQ_HANDLED; |
1613 | } | 1616 | } |
1614 | 1617 | ||
1618 | static irqreturn_t netxen_msix_intr(int irq, void *data) | ||
1619 | { | ||
1620 | struct netxen_adapter *adapter = data; | ||
1621 | |||
1622 | napi_schedule(&adapter->napi); | ||
1623 | return IRQ_HANDLED; | ||
1624 | } | ||
1625 | |||
1615 | static int netxen_nic_poll(struct napi_struct *napi, int budget) | 1626 | static int netxen_nic_poll(struct napi_struct *napi, int budget) |
1616 | { | 1627 | { |
1617 | struct netxen_adapter *adapter = container_of(napi, struct netxen_adapter, napi); | 1628 | struct netxen_adapter *adapter = container_of(napi, struct netxen_adapter, napi); |
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 2c73ca606b35..0771eb6fc6eb 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
@@ -437,6 +437,22 @@ enum features { | |||
437 | RTL_FEATURE_GMII = (1 << 2), | 437 | RTL_FEATURE_GMII = (1 << 2), |
438 | }; | 438 | }; |
439 | 439 | ||
440 | struct rtl8169_counters { | ||
441 | __le64 tx_packets; | ||
442 | __le64 rx_packets; | ||
443 | __le64 tx_errors; | ||
444 | __le32 rx_errors; | ||
445 | __le16 rx_missed; | ||
446 | __le16 align_errors; | ||
447 | __le32 tx_one_collision; | ||
448 | __le32 tx_multi_collision; | ||
449 | __le64 rx_unicast; | ||
450 | __le64 rx_broadcast; | ||
451 | __le32 rx_multicast; | ||
452 | __le16 tx_aborted; | ||
453 | __le16 tx_underun; | ||
454 | }; | ||
455 | |||
440 | struct rtl8169_private { | 456 | struct rtl8169_private { |
441 | void __iomem *mmio_addr; /* memory map physical address */ | 457 | void __iomem *mmio_addr; /* memory map physical address */ |
442 | struct pci_dev *pci_dev; /* Index of PCI device */ | 458 | struct pci_dev *pci_dev; /* Index of PCI device */ |
@@ -480,6 +496,7 @@ struct rtl8169_private { | |||
480 | unsigned features; | 496 | unsigned features; |
481 | 497 | ||
482 | struct mii_if_info mii; | 498 | struct mii_if_info mii; |
499 | struct rtl8169_counters counters; | ||
483 | }; | 500 | }; |
484 | 501 | ||
485 | MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>"); | 502 | MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>"); |
@@ -1100,22 +1117,6 @@ static const char rtl8169_gstrings[][ETH_GSTRING_LEN] = { | |||
1100 | "tx_underrun", | 1117 | "tx_underrun", |
1101 | }; | 1118 | }; |
1102 | 1119 | ||
1103 | struct rtl8169_counters { | ||
1104 | __le64 tx_packets; | ||
1105 | __le64 rx_packets; | ||
1106 | __le64 tx_errors; | ||
1107 | __le32 rx_errors; | ||
1108 | __le16 rx_missed; | ||
1109 | __le16 align_errors; | ||
1110 | __le32 tx_one_collision; | ||
1111 | __le32 tx_multi_collision; | ||
1112 | __le64 rx_unicast; | ||
1113 | __le64 rx_broadcast; | ||
1114 | __le32 rx_multicast; | ||
1115 | __le16 tx_aborted; | ||
1116 | __le16 tx_underun; | ||
1117 | }; | ||
1118 | |||
1119 | static int rtl8169_get_sset_count(struct net_device *dev, int sset) | 1120 | static int rtl8169_get_sset_count(struct net_device *dev, int sset) |
1120 | { | 1121 | { |
1121 | switch (sset) { | 1122 | switch (sset) { |
@@ -1126,16 +1127,21 @@ static int rtl8169_get_sset_count(struct net_device *dev, int sset) | |||
1126 | } | 1127 | } |
1127 | } | 1128 | } |
1128 | 1129 | ||
1129 | static void rtl8169_get_ethtool_stats(struct net_device *dev, | 1130 | static void rtl8169_update_counters(struct net_device *dev) |
1130 | struct ethtool_stats *stats, u64 *data) | ||
1131 | { | 1131 | { |
1132 | struct rtl8169_private *tp = netdev_priv(dev); | 1132 | struct rtl8169_private *tp = netdev_priv(dev); |
1133 | void __iomem *ioaddr = tp->mmio_addr; | 1133 | void __iomem *ioaddr = tp->mmio_addr; |
1134 | struct rtl8169_counters *counters; | 1134 | struct rtl8169_counters *counters; |
1135 | dma_addr_t paddr; | 1135 | dma_addr_t paddr; |
1136 | u32 cmd; | 1136 | u32 cmd; |
1137 | int wait = 1000; | ||
1137 | 1138 | ||
1138 | ASSERT_RTNL(); | 1139 | /* |
1140 | * Some chips are unable to dump tally counters when the receiver | ||
1141 | * is disabled. | ||
1142 | */ | ||
1143 | if ((RTL_R8(ChipCmd) & CmdRxEnb) == 0) | ||
1144 | return; | ||
1139 | 1145 | ||
1140 | counters = pci_alloc_consistent(tp->pci_dev, sizeof(*counters), &paddr); | 1146 | counters = pci_alloc_consistent(tp->pci_dev, sizeof(*counters), &paddr); |
1141 | if (!counters) | 1147 | if (!counters) |
@@ -1146,31 +1152,45 @@ static void rtl8169_get_ethtool_stats(struct net_device *dev, | |||
1146 | RTL_W32(CounterAddrLow, cmd); | 1152 | RTL_W32(CounterAddrLow, cmd); |
1147 | RTL_W32(CounterAddrLow, cmd | CounterDump); | 1153 | RTL_W32(CounterAddrLow, cmd | CounterDump); |
1148 | 1154 | ||
1149 | while (RTL_R32(CounterAddrLow) & CounterDump) { | 1155 | while (wait--) { |
1150 | if (msleep_interruptible(1)) | 1156 | if ((RTL_R32(CounterAddrLow) & CounterDump) == 0) { |
1157 | /* copy updated counters */ | ||
1158 | memcpy(&tp->counters, counters, sizeof(*counters)); | ||
1151 | break; | 1159 | break; |
1160 | } | ||
1161 | udelay(10); | ||
1152 | } | 1162 | } |
1153 | 1163 | ||
1154 | RTL_W32(CounterAddrLow, 0); | 1164 | RTL_W32(CounterAddrLow, 0); |
1155 | RTL_W32(CounterAddrHigh, 0); | 1165 | RTL_W32(CounterAddrHigh, 0); |
1156 | 1166 | ||
1157 | data[0] = le64_to_cpu(counters->tx_packets); | ||
1158 | data[1] = le64_to_cpu(counters->rx_packets); | ||
1159 | data[2] = le64_to_cpu(counters->tx_errors); | ||
1160 | data[3] = le32_to_cpu(counters->rx_errors); | ||
1161 | data[4] = le16_to_cpu(counters->rx_missed); | ||
1162 | data[5] = le16_to_cpu(counters->align_errors); | ||
1163 | data[6] = le32_to_cpu(counters->tx_one_collision); | ||
1164 | data[7] = le32_to_cpu(counters->tx_multi_collision); | ||
1165 | data[8] = le64_to_cpu(counters->rx_unicast); | ||
1166 | data[9] = le64_to_cpu(counters->rx_broadcast); | ||
1167 | data[10] = le32_to_cpu(counters->rx_multicast); | ||
1168 | data[11] = le16_to_cpu(counters->tx_aborted); | ||
1169 | data[12] = le16_to_cpu(counters->tx_underun); | ||
1170 | |||
1171 | pci_free_consistent(tp->pci_dev, sizeof(*counters), counters, paddr); | 1167 | pci_free_consistent(tp->pci_dev, sizeof(*counters), counters, paddr); |
1172 | } | 1168 | } |
1173 | 1169 | ||
1170 | static void rtl8169_get_ethtool_stats(struct net_device *dev, | ||
1171 | struct ethtool_stats *stats, u64 *data) | ||
1172 | { | ||
1173 | struct rtl8169_private *tp = netdev_priv(dev); | ||
1174 | |||
1175 | ASSERT_RTNL(); | ||
1176 | |||
1177 | rtl8169_update_counters(dev); | ||
1178 | |||
1179 | data[0] = le64_to_cpu(tp->counters.tx_packets); | ||
1180 | data[1] = le64_to_cpu(tp->counters.rx_packets); | ||
1181 | data[2] = le64_to_cpu(tp->counters.tx_errors); | ||
1182 | data[3] = le32_to_cpu(tp->counters.rx_errors); | ||
1183 | data[4] = le16_to_cpu(tp->counters.rx_missed); | ||
1184 | data[5] = le16_to_cpu(tp->counters.align_errors); | ||
1185 | data[6] = le32_to_cpu(tp->counters.tx_one_collision); | ||
1186 | data[7] = le32_to_cpu(tp->counters.tx_multi_collision); | ||
1187 | data[8] = le64_to_cpu(tp->counters.rx_unicast); | ||
1188 | data[9] = le64_to_cpu(tp->counters.rx_broadcast); | ||
1189 | data[10] = le32_to_cpu(tp->counters.rx_multicast); | ||
1190 | data[11] = le16_to_cpu(tp->counters.tx_aborted); | ||
1191 | data[12] = le16_to_cpu(tp->counters.tx_underun); | ||
1192 | } | ||
1193 | |||
1174 | static void rtl8169_get_strings(struct net_device *dev, u32 stringset, u8 *data) | 1194 | static void rtl8169_get_strings(struct net_device *dev, u32 stringset, u8 *data) |
1175 | { | 1195 | { |
1176 | switch(stringset) { | 1196 | switch(stringset) { |
@@ -3682,6 +3702,9 @@ static int rtl8169_close(struct net_device *dev) | |||
3682 | struct rtl8169_private *tp = netdev_priv(dev); | 3702 | struct rtl8169_private *tp = netdev_priv(dev); |
3683 | struct pci_dev *pdev = tp->pci_dev; | 3703 | struct pci_dev *pdev = tp->pci_dev; |
3684 | 3704 | ||
3705 | /* update counters before going down */ | ||
3706 | rtl8169_update_counters(dev); | ||
3707 | |||
3685 | rtl8169_down(dev); | 3708 | rtl8169_down(dev); |
3686 | 3709 | ||
3687 | free_irq(dev->irq, dev); | 3710 | free_irq(dev->irq, dev); |
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index b17efa9cc530..491876341068 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c | |||
@@ -2221,6 +2221,8 @@ static int gem_do_start(struct net_device *dev) | |||
2221 | 2221 | ||
2222 | gp->running = 1; | 2222 | gp->running = 1; |
2223 | 2223 | ||
2224 | napi_enable(&gp->napi); | ||
2225 | |||
2224 | if (gp->lstate == link_up) { | 2226 | if (gp->lstate == link_up) { |
2225 | netif_carrier_on(gp->dev); | 2227 | netif_carrier_on(gp->dev); |
2226 | gem_set_link_modes(gp); | 2228 | gem_set_link_modes(gp); |
@@ -2238,6 +2240,8 @@ static int gem_do_start(struct net_device *dev) | |||
2238 | spin_lock_irqsave(&gp->lock, flags); | 2240 | spin_lock_irqsave(&gp->lock, flags); |
2239 | spin_lock(&gp->tx_lock); | 2241 | spin_lock(&gp->tx_lock); |
2240 | 2242 | ||
2243 | napi_disable(&gp->napi); | ||
2244 | |||
2241 | gp->running = 0; | 2245 | gp->running = 0; |
2242 | gem_reset(gp); | 2246 | gem_reset(gp); |
2243 | gem_clean_rings(gp); | 2247 | gem_clean_rings(gp); |
@@ -2338,8 +2342,6 @@ static int gem_open(struct net_device *dev) | |||
2338 | if (!gp->asleep) | 2342 | if (!gp->asleep) |
2339 | rc = gem_do_start(dev); | 2343 | rc = gem_do_start(dev); |
2340 | gp->opened = (rc == 0); | 2344 | gp->opened = (rc == 0); |
2341 | if (gp->opened) | ||
2342 | napi_enable(&gp->napi); | ||
2343 | 2345 | ||
2344 | mutex_unlock(&gp->pm_mutex); | 2346 | mutex_unlock(&gp->pm_mutex); |
2345 | 2347 | ||
@@ -2476,8 +2478,6 @@ static int gem_resume(struct pci_dev *pdev) | |||
2476 | 2478 | ||
2477 | /* Re-attach net device */ | 2479 | /* Re-attach net device */ |
2478 | netif_device_attach(dev); | 2480 | netif_device_attach(dev); |
2479 | |||
2480 | napi_enable(&gp->napi); | ||
2481 | } | 2481 | } |
2482 | 2482 | ||
2483 | spin_lock_irqsave(&gp->lock, flags); | 2483 | spin_lock_irqsave(&gp->lock, flags); |
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index 7a72a3112f0a..cc4013be5e18 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c | |||
@@ -2629,6 +2629,14 @@ static int __devinit happy_meal_sbus_probe_one(struct of_device *op, int is_qfe) | |||
2629 | int i, qfe_slot = -1; | 2629 | int i, qfe_slot = -1; |
2630 | int err = -ENODEV; | 2630 | int err = -ENODEV; |
2631 | 2631 | ||
2632 | sbus_dp = to_of_device(op->dev.parent)->node; | ||
2633 | if (is_qfe) | ||
2634 | sbus_dp = to_of_device(op->dev.parent->parent)->node; | ||
2635 | |||
2636 | /* We can match PCI devices too, do not accept those here. */ | ||
2637 | if (strcmp(sbus_dp->name, "sbus")) | ||
2638 | return err; | ||
2639 | |||
2632 | if (is_qfe) { | 2640 | if (is_qfe) { |
2633 | qp = quattro_sbus_find(op); | 2641 | qp = quattro_sbus_find(op); |
2634 | if (qp == NULL) | 2642 | if (qp == NULL) |
@@ -2734,10 +2742,6 @@ static int __devinit happy_meal_sbus_probe_one(struct of_device *op, int is_qfe) | |||
2734 | if (qp != NULL) | 2742 | if (qp != NULL) |
2735 | hp->happy_flags |= HFLAG_QUATTRO; | 2743 | hp->happy_flags |= HFLAG_QUATTRO; |
2736 | 2744 | ||
2737 | sbus_dp = to_of_device(op->dev.parent)->node; | ||
2738 | if (is_qfe) | ||
2739 | sbus_dp = to_of_device(op->dev.parent->parent)->node; | ||
2740 | |||
2741 | /* Get the supported DVMA burst sizes from our Happy SBUS. */ | 2745 | /* Get the supported DVMA burst sizes from our Happy SBUS. */ |
2742 | hp->happy_bursts = of_getintprop_default(sbus_dp, | 2746 | hp->happy_bursts = of_getintprop_default(sbus_dp, |
2743 | "burst-sizes", 0x00); | 2747 | "burst-sizes", 0x00); |
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index 0bf2114738be..d4c5ecc51f77 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c | |||
@@ -464,13 +464,14 @@ static void de_rx (struct de_private *de) | |||
464 | drop = 1; | 464 | drop = 1; |
465 | 465 | ||
466 | rx_next: | 466 | rx_next: |
467 | de->rx_ring[rx_tail].opts1 = cpu_to_le32(DescOwn); | ||
468 | if (rx_tail == (DE_RX_RING_SIZE - 1)) | 467 | if (rx_tail == (DE_RX_RING_SIZE - 1)) |
469 | de->rx_ring[rx_tail].opts2 = | 468 | de->rx_ring[rx_tail].opts2 = |
470 | cpu_to_le32(RingEnd | de->rx_buf_sz); | 469 | cpu_to_le32(RingEnd | de->rx_buf_sz); |
471 | else | 470 | else |
472 | de->rx_ring[rx_tail].opts2 = cpu_to_le32(de->rx_buf_sz); | 471 | de->rx_ring[rx_tail].opts2 = cpu_to_le32(de->rx_buf_sz); |
473 | de->rx_ring[rx_tail].addr1 = cpu_to_le32(mapping); | 472 | de->rx_ring[rx_tail].addr1 = cpu_to_le32(mapping); |
473 | wmb(); | ||
474 | de->rx_ring[rx_tail].opts1 = cpu_to_le32(DescOwn); | ||
474 | rx_tail = NEXT_RX(rx_tail); | 475 | rx_tail = NEXT_RX(rx_tail); |
475 | } | 476 | } |
476 | 477 | ||
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index d7b81e4fdd56..09fea31d3e36 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -157,10 +157,16 @@ static int update_filter(struct tap_filter *filter, void __user *arg) | |||
157 | 157 | ||
158 | nexact = n; | 158 | nexact = n; |
159 | 159 | ||
160 | /* The rest is hashed */ | 160 | /* Remaining multicast addresses are hashed, |
161 | * unicast will leave the filter disabled. */ | ||
161 | memset(filter->mask, 0, sizeof(filter->mask)); | 162 | memset(filter->mask, 0, sizeof(filter->mask)); |
162 | for (; n < uf.count; n++) | 163 | for (; n < uf.count; n++) { |
164 | if (!is_multicast_ether_addr(addr[n].u)) { | ||
165 | err = 0; /* no filter */ | ||
166 | goto done; | ||
167 | } | ||
163 | addr_hash_set(filter->mask, addr[n].u); | 168 | addr_hash_set(filter->mask, addr[n].u); |
169 | } | ||
164 | 170 | ||
165 | /* For ALLMULTI just set the mask to all ones. | 171 | /* For ALLMULTI just set the mask to all ones. |
166 | * This overrides the mask populated above. */ | 172 | * This overrides the mask populated above. */ |