diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-06-20 23:10:18 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-06-20 23:10:18 -0400 |
| commit | 6e158d21986fa15d21fd32cf241d167d4d741ae3 (patch) | |
| tree | b2377e488386e613028e1d02ac7f788d5ecf165b | |
| parent | 36698206504fca9198b8563f1fc2c9e38e063e11 (diff) | |
| parent | 384420409d9b5d4443940abace49363d26135412 (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: (40 commits)
pxa168_eth: fix race in transmit path.
ipv4, ping: Remove duplicate icmp.h include
netxen: fix race in skb->len access
sgi-xp: fix a use after free
hp100: fix an skb->len race
netpoll: copy dev name of slaves to struct netpoll
ipv4: fix multicast losses
r8169: fix static initializers.
inet_diag: fix inet_diag_bc_audit()
gigaset: call module_put before restart of if_open()
farsync: add module_put to error path in fst_open()
net: rfs: enable RFS before first data packet is received
fs_enet: fix freescale FCC ethernet dp buffer alignment
netdev: bfin_mac: fix memory leak when freeing dma descriptors
vlan: don't call ndo_vlan_rx_register on hardware that doesn't have vlan support
caif: Bugfix - XOFF removed channel from caif-mux
tun: teach the tun/tap driver to support netpoll
dp83640: drop PHY status frames in the driver.
dp83640: fix phy status frame event parsing
phylib: Allow BCM63XX PHY to be selected only on BCM63XX.
...
48 files changed, 563 insertions, 77 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index b12b8c13f53a..f0358cd91de3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -2291,8 +2291,7 @@ F: drivers/scsi/eata_pio.* | |||
| 2291 | 2291 | ||
| 2292 | EBTABLES | 2292 | EBTABLES |
| 2293 | M: Bart De Schuymer <bart.de.schuymer@pandora.be> | 2293 | M: Bart De Schuymer <bart.de.schuymer@pandora.be> |
| 2294 | L: ebtables-user@lists.sourceforge.net | 2294 | L: netfilter-devel@vger.kernel.org |
| 2295 | L: ebtables-devel@lists.sourceforge.net | ||
| 2296 | W: http://ebtables.sourceforge.net/ | 2295 | W: http://ebtables.sourceforge.net/ |
| 2297 | S: Maintained | 2296 | S: Maintained |
| 2298 | F: include/linux/netfilter_bridge/ebt_*.h | 2297 | F: include/linux/netfilter_bridge/ebt_*.h |
diff --git a/drivers/bluetooth/btmrvl_debugfs.c b/drivers/bluetooth/btmrvl_debugfs.c index fd6305bf953e..8ecf4c6c2874 100644 --- a/drivers/bluetooth/btmrvl_debugfs.c +++ b/drivers/bluetooth/btmrvl_debugfs.c | |||
| @@ -64,6 +64,8 @@ static ssize_t btmrvl_hscfgcmd_write(struct file *file, | |||
| 64 | return -EFAULT; | 64 | return -EFAULT; |
| 65 | 65 | ||
| 66 | ret = strict_strtol(buf, 10, &result); | 66 | ret = strict_strtol(buf, 10, &result); |
| 67 | if (ret) | ||
| 68 | return ret; | ||
| 67 | 69 | ||
| 68 | priv->btmrvl_dev.hscfgcmd = result; | 70 | priv->btmrvl_dev.hscfgcmd = result; |
| 69 | 71 | ||
| @@ -108,6 +110,8 @@ static ssize_t btmrvl_psmode_write(struct file *file, const char __user *ubuf, | |||
| 108 | return -EFAULT; | 110 | return -EFAULT; |
| 109 | 111 | ||
| 110 | ret = strict_strtol(buf, 10, &result); | 112 | ret = strict_strtol(buf, 10, &result); |
| 113 | if (ret) | ||
| 114 | return ret; | ||
| 111 | 115 | ||
| 112 | priv->btmrvl_dev.psmode = result; | 116 | priv->btmrvl_dev.psmode = result; |
| 113 | 117 | ||
| @@ -147,6 +151,8 @@ static ssize_t btmrvl_pscmd_write(struct file *file, const char __user *ubuf, | |||
| 147 | return -EFAULT; | 151 | return -EFAULT; |
| 148 | 152 | ||
| 149 | ret = strict_strtol(buf, 10, &result); | 153 | ret = strict_strtol(buf, 10, &result); |
| 154 | if (ret) | ||
| 155 | return ret; | ||
| 150 | 156 | ||
| 151 | priv->btmrvl_dev.pscmd = result; | 157 | priv->btmrvl_dev.pscmd = result; |
| 152 | 158 | ||
| @@ -191,6 +197,8 @@ static ssize_t btmrvl_gpiogap_write(struct file *file, const char __user *ubuf, | |||
| 191 | return -EFAULT; | 197 | return -EFAULT; |
| 192 | 198 | ||
| 193 | ret = strict_strtol(buf, 16, &result); | 199 | ret = strict_strtol(buf, 16, &result); |
| 200 | if (ret) | ||
| 201 | return ret; | ||
| 194 | 202 | ||
| 195 | priv->btmrvl_dev.gpio_gap = result; | 203 | priv->btmrvl_dev.gpio_gap = result; |
| 196 | 204 | ||
| @@ -230,6 +238,8 @@ static ssize_t btmrvl_hscmd_write(struct file *file, const char __user *ubuf, | |||
| 230 | return -EFAULT; | 238 | return -EFAULT; |
| 231 | 239 | ||
| 232 | ret = strict_strtol(buf, 10, &result); | 240 | ret = strict_strtol(buf, 10, &result); |
| 241 | if (ret) | ||
| 242 | return ret; | ||
| 233 | 243 | ||
| 234 | priv->btmrvl_dev.hscmd = result; | 244 | priv->btmrvl_dev.hscmd = result; |
| 235 | if (priv->btmrvl_dev.hscmd) { | 245 | if (priv->btmrvl_dev.hscmd) { |
| @@ -272,6 +282,8 @@ static ssize_t btmrvl_hsmode_write(struct file *file, const char __user *ubuf, | |||
| 272 | return -EFAULT; | 282 | return -EFAULT; |
| 273 | 283 | ||
| 274 | ret = strict_strtol(buf, 10, &result); | 284 | ret = strict_strtol(buf, 10, &result); |
| 285 | if (ret) | ||
| 286 | return ret; | ||
| 275 | 287 | ||
| 276 | priv->btmrvl_dev.hsmode = result; | 288 | priv->btmrvl_dev.hsmode = result; |
| 277 | 289 | ||
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index 59de638225fe..e35058bcd7b9 100644 --- a/drivers/isdn/gigaset/interface.c +++ b/drivers/isdn/gigaset/interface.c | |||
| @@ -156,8 +156,10 @@ static int if_open(struct tty_struct *tty, struct file *filp) | |||
| 156 | if (!cs || !try_module_get(cs->driver->owner)) | 156 | if (!cs || !try_module_get(cs->driver->owner)) |
| 157 | return -ENODEV; | 157 | return -ENODEV; |
| 158 | 158 | ||
| 159 | if (mutex_lock_interruptible(&cs->mutex)) | 159 | if (mutex_lock_interruptible(&cs->mutex)) { |
| 160 | module_put(cs->driver->owner); | ||
| 160 | return -ERESTARTSYS; | 161 | return -ERESTARTSYS; |
| 162 | } | ||
| 161 | tty->driver_data = cs; | 163 | tty->driver_data = cs; |
| 162 | 164 | ||
| 163 | ++cs->open_count; | 165 | ++cs->open_count; |
diff --git a/drivers/misc/sgi-xp/xpnet.c b/drivers/misc/sgi-xp/xpnet.c index ee5109a3cd98..42f067347bc7 100644 --- a/drivers/misc/sgi-xp/xpnet.c +++ b/drivers/misc/sgi-xp/xpnet.c | |||
| @@ -495,14 +495,14 @@ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 495 | } | 495 | } |
| 496 | } | 496 | } |
| 497 | 497 | ||
| 498 | dev->stats.tx_packets++; | ||
| 499 | dev->stats.tx_bytes += skb->len; | ||
| 500 | |||
| 498 | if (atomic_dec_return(&queued_msg->use_count) == 0) { | 501 | if (atomic_dec_return(&queued_msg->use_count) == 0) { |
| 499 | dev_kfree_skb(skb); | 502 | dev_kfree_skb(skb); |
| 500 | kfree(queued_msg); | 503 | kfree(queued_msg); |
| 501 | } | 504 | } |
| 502 | 505 | ||
| 503 | dev->stats.tx_packets++; | ||
| 504 | dev->stats.tx_bytes += skb->len; | ||
| 505 | |||
| 506 | return NETDEV_TX_OK; | 506 | return NETDEV_TX_OK; |
| 507 | } | 507 | } |
| 508 | 508 | ||
diff --git a/drivers/net/3c503.c b/drivers/net/3c503.c index d84f6e8903a5..5b732988d493 100644 --- a/drivers/net/3c503.c +++ b/drivers/net/3c503.c | |||
| @@ -412,7 +412,7 @@ el2_open(struct net_device *dev) | |||
| 412 | outb_p(0x04 << ((*irqp == 9) ? 2 : *irqp), E33G_IDCFR); | 412 | outb_p(0x04 << ((*irqp == 9) ? 2 : *irqp), E33G_IDCFR); |
| 413 | outb_p(0x00, E33G_IDCFR); | 413 | outb_p(0x00, E33G_IDCFR); |
| 414 | msleep(1); | 414 | msleep(1); |
| 415 | free_irq(*irqp, el2_probe_interrupt); | 415 | free_irq(*irqp, &seen); |
| 416 | if (!seen) | 416 | if (!seen) |
| 417 | continue; | 417 | continue; |
| 418 | 418 | ||
| @@ -422,6 +422,7 @@ el2_open(struct net_device *dev) | |||
| 422 | continue; | 422 | continue; |
| 423 | if (retval < 0) | 423 | if (retval < 0) |
| 424 | goto err_disable; | 424 | goto err_disable; |
| 425 | break; | ||
| 425 | } while (*++irqp); | 426 | } while (*++irqp); |
| 426 | 427 | ||
| 427 | if (*irqp == 0) { | 428 | if (*irqp == 0) { |
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c index 68d45ba2d9b9..6c019e148546 100644 --- a/drivers/net/bfin_mac.c +++ b/drivers/net/bfin_mac.c | |||
| @@ -52,13 +52,13 @@ MODULE_DESCRIPTION(DRV_DESC); | |||
| 52 | MODULE_ALIAS("platform:bfin_mac"); | 52 | MODULE_ALIAS("platform:bfin_mac"); |
| 53 | 53 | ||
| 54 | #if defined(CONFIG_BFIN_MAC_USE_L1) | 54 | #if defined(CONFIG_BFIN_MAC_USE_L1) |
| 55 | # define bfin_mac_alloc(dma_handle, size) l1_data_sram_zalloc(size) | 55 | # define bfin_mac_alloc(dma_handle, size, num) l1_data_sram_zalloc(size*num) |
| 56 | # define bfin_mac_free(dma_handle, ptr) l1_data_sram_free(ptr) | 56 | # define bfin_mac_free(dma_handle, ptr, num) l1_data_sram_free(ptr) |
| 57 | #else | 57 | #else |
| 58 | # define bfin_mac_alloc(dma_handle, size) \ | 58 | # define bfin_mac_alloc(dma_handle, size, num) \ |
| 59 | dma_alloc_coherent(NULL, size, dma_handle, GFP_KERNEL) | 59 | dma_alloc_coherent(NULL, size*num, dma_handle, GFP_KERNEL) |
| 60 | # define bfin_mac_free(dma_handle, ptr) \ | 60 | # define bfin_mac_free(dma_handle, ptr, num) \ |
| 61 | dma_free_coherent(NULL, sizeof(*ptr), ptr, dma_handle) | 61 | dma_free_coherent(NULL, sizeof(*ptr)*num, ptr, dma_handle) |
| 62 | #endif | 62 | #endif |
| 63 | 63 | ||
| 64 | #define PKT_BUF_SZ 1580 | 64 | #define PKT_BUF_SZ 1580 |
| @@ -95,7 +95,7 @@ static void desc_list_free(void) | |||
| 95 | t = t->next; | 95 | t = t->next; |
| 96 | } | 96 | } |
| 97 | } | 97 | } |
| 98 | bfin_mac_free(dma_handle, tx_desc); | 98 | bfin_mac_free(dma_handle, tx_desc, CONFIG_BFIN_TX_DESC_NUM); |
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | if (rx_desc) { | 101 | if (rx_desc) { |
| @@ -109,7 +109,7 @@ static void desc_list_free(void) | |||
| 109 | r = r->next; | 109 | r = r->next; |
| 110 | } | 110 | } |
| 111 | } | 111 | } |
| 112 | bfin_mac_free(dma_handle, rx_desc); | 112 | bfin_mac_free(dma_handle, rx_desc, CONFIG_BFIN_RX_DESC_NUM); |
| 113 | } | 113 | } |
| 114 | } | 114 | } |
| 115 | 115 | ||
| @@ -126,13 +126,13 @@ static int desc_list_init(void) | |||
| 126 | #endif | 126 | #endif |
| 127 | 127 | ||
| 128 | tx_desc = bfin_mac_alloc(&dma_handle, | 128 | tx_desc = bfin_mac_alloc(&dma_handle, |
| 129 | sizeof(struct net_dma_desc_tx) * | 129 | sizeof(struct net_dma_desc_tx), |
| 130 | CONFIG_BFIN_TX_DESC_NUM); | 130 | CONFIG_BFIN_TX_DESC_NUM); |
| 131 | if (tx_desc == NULL) | 131 | if (tx_desc == NULL) |
| 132 | goto init_error; | 132 | goto init_error; |
| 133 | 133 | ||
| 134 | rx_desc = bfin_mac_alloc(&dma_handle, | 134 | rx_desc = bfin_mac_alloc(&dma_handle, |
| 135 | sizeof(struct net_dma_desc_rx) * | 135 | sizeof(struct net_dma_desc_rx), |
| 136 | CONFIG_BFIN_RX_DESC_NUM); | 136 | CONFIG_BFIN_RX_DESC_NUM); |
| 137 | if (rx_desc == NULL) | 137 | if (rx_desc == NULL) |
| 138 | goto init_error; | 138 | goto init_error; |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 652b30e525d0..eafe44a528ac 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
| @@ -1297,6 +1297,7 @@ static inline int slave_enable_netpoll(struct slave *slave) | |||
| 1297 | goto out; | 1297 | goto out; |
| 1298 | 1298 | ||
| 1299 | np->dev = slave->dev; | 1299 | np->dev = slave->dev; |
| 1300 | strlcpy(np->dev_name, slave->dev->name, IFNAMSIZ); | ||
| 1300 | err = __netpoll_setup(np); | 1301 | err = __netpoll_setup(np); |
| 1301 | if (err) { | 1302 | if (err) { |
| 1302 | kfree(np); | 1303 | kfree(np); |
diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c index 7a84e45487e8..7583a9572bcc 100644 --- a/drivers/net/fs_enet/mac-fcc.c +++ b/drivers/net/fs_enet/mac-fcc.c | |||
| @@ -105,7 +105,7 @@ static int do_pd_setup(struct fs_enet_private *fep) | |||
| 105 | goto out_ep; | 105 | goto out_ep; |
| 106 | 106 | ||
| 107 | fep->fcc.mem = (void __iomem *)cpm2_immr; | 107 | fep->fcc.mem = (void __iomem *)cpm2_immr; |
| 108 | fpi->dpram_offset = cpm_dpalloc(128, 8); | 108 | fpi->dpram_offset = cpm_dpalloc(128, 32); |
| 109 | if (IS_ERR_VALUE(fpi->dpram_offset)) { | 109 | if (IS_ERR_VALUE(fpi->dpram_offset)) { |
| 110 | ret = fpi->dpram_offset; | 110 | ret = fpi->dpram_offset; |
| 111 | goto out_fcccp; | 111 | goto out_fcccp; |
diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c index 8e10d2f6a5ad..c3ecb118c1df 100644 --- a/drivers/net/hp100.c +++ b/drivers/net/hp100.c | |||
| @@ -1580,12 +1580,12 @@ static netdev_tx_t hp100_start_xmit_bm(struct sk_buff *skb, | |||
| 1580 | hp100_outl(ringptr->pdl_paddr, TX_PDA_L); /* Low Prio. Queue */ | 1580 | hp100_outl(ringptr->pdl_paddr, TX_PDA_L); /* Low Prio. Queue */ |
| 1581 | 1581 | ||
| 1582 | lp->txrcommit++; | 1582 | lp->txrcommit++; |
| 1583 | spin_unlock_irqrestore(&lp->lock, flags); | ||
| 1584 | 1583 | ||
| 1585 | /* Update statistics */ | ||
| 1586 | dev->stats.tx_packets++; | 1584 | dev->stats.tx_packets++; |
| 1587 | dev->stats.tx_bytes += skb->len; | 1585 | dev->stats.tx_bytes += skb->len; |
| 1588 | 1586 | ||
| 1587 | spin_unlock_irqrestore(&lp->lock, flags); | ||
| 1588 | |||
| 1589 | return NETDEV_TX_OK; | 1589 | return NETDEV_TX_OK; |
| 1590 | 1590 | ||
| 1591 | drop: | 1591 | drop: |
diff --git a/drivers/net/hplance.c b/drivers/net/hplance.c index b6060f7538df..a900d5bf2948 100644 --- a/drivers/net/hplance.c +++ b/drivers/net/hplance.c | |||
| @@ -135,7 +135,7 @@ static void __devexit hplance_remove_one(struct dio_dev *d) | |||
| 135 | } | 135 | } |
| 136 | 136 | ||
| 137 | /* Initialise a single lance board at the given DIO device */ | 137 | /* Initialise a single lance board at the given DIO device */ |
| 138 | static void __init hplance_init(struct net_device *dev, struct dio_dev *d) | 138 | static void __devinit hplance_init(struct net_device *dev, struct dio_dev *d) |
| 139 | { | 139 | { |
| 140 | unsigned long va = (d->resource.start + DIO_VIRADDRBASE); | 140 | unsigned long va = (d->resource.start + DIO_VIRADDRBASE); |
| 141 | struct hplance_private *lp; | 141 | struct hplance_private *lp; |
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index b644383017f9..c0788a31ff0f 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
| @@ -1965,11 +1965,11 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
| 1965 | 1965 | ||
| 1966 | netxen_tso_check(netdev, tx_ring, first_desc, skb); | 1966 | netxen_tso_check(netdev, tx_ring, first_desc, skb); |
| 1967 | 1967 | ||
| 1968 | netxen_nic_update_cmd_producer(adapter, tx_ring); | ||
| 1969 | |||
| 1970 | adapter->stats.txbytes += skb->len; | 1968 | adapter->stats.txbytes += skb->len; |
| 1971 | adapter->stats.xmitcalled++; | 1969 | adapter->stats.xmitcalled++; |
| 1972 | 1970 | ||
| 1971 | netxen_nic_update_cmd_producer(adapter, tx_ring); | ||
| 1972 | |||
| 1973 | return NETDEV_TX_OK; | 1973 | return NETDEV_TX_OK; |
| 1974 | 1974 | ||
| 1975 | drop_packet: | 1975 | drop_packet: |
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index 392a6c4b72e5..a70244306c94 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig | |||
| @@ -58,6 +58,7 @@ config BROADCOM_PHY | |||
| 58 | 58 | ||
| 59 | config BCM63XX_PHY | 59 | config BCM63XX_PHY |
| 60 | tristate "Drivers for Broadcom 63xx SOCs internal PHY" | 60 | tristate "Drivers for Broadcom 63xx SOCs internal PHY" |
| 61 | depends on BCM63XX | ||
| 61 | ---help--- | 62 | ---help--- |
| 62 | Currently supports the 6348 and 6358 PHYs. | 63 | Currently supports the 6348 and 6358 PHYs. |
| 63 | 64 | ||
diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c index b0c9522bb535..2cd8dc5847b4 100644 --- a/drivers/net/phy/dp83640.c +++ b/drivers/net/phy/dp83640.c | |||
| @@ -543,11 +543,20 @@ static void recalibrate(struct dp83640_clock *clock) | |||
| 543 | 543 | ||
| 544 | /* time stamping methods */ | 544 | /* time stamping methods */ |
| 545 | 545 | ||
| 546 | static void decode_evnt(struct dp83640_private *dp83640, | 546 | static int decode_evnt(struct dp83640_private *dp83640, |
| 547 | struct phy_txts *phy_txts, u16 ests) | 547 | void *data, u16 ests) |
| 548 | { | 548 | { |
| 549 | struct phy_txts *phy_txts; | ||
| 549 | struct ptp_clock_event event; | 550 | struct ptp_clock_event event; |
| 550 | int words = (ests >> EVNT_TS_LEN_SHIFT) & EVNT_TS_LEN_MASK; | 551 | int words = (ests >> EVNT_TS_LEN_SHIFT) & EVNT_TS_LEN_MASK; |
| 552 | u16 ext_status = 0; | ||
| 553 | |||
| 554 | if (ests & MULT_EVNT) { | ||
| 555 | ext_status = *(u16 *) data; | ||
| 556 | data += sizeof(ext_status); | ||
| 557 | } | ||
| 558 | |||
| 559 | phy_txts = data; | ||
| 551 | 560 | ||
| 552 | switch (words) { /* fall through in every case */ | 561 | switch (words) { /* fall through in every case */ |
| 553 | case 3: | 562 | case 3: |
| @@ -565,6 +574,9 @@ static void decode_evnt(struct dp83640_private *dp83640, | |||
| 565 | event.timestamp = phy2txts(&dp83640->edata); | 574 | event.timestamp = phy2txts(&dp83640->edata); |
| 566 | 575 | ||
| 567 | ptp_clock_event(dp83640->clock->ptp_clock, &event); | 576 | ptp_clock_event(dp83640->clock->ptp_clock, &event); |
| 577 | |||
| 578 | words = ext_status ? words + 2 : words + 1; | ||
| 579 | return words * sizeof(u16); | ||
| 568 | } | 580 | } |
| 569 | 581 | ||
| 570 | static void decode_rxts(struct dp83640_private *dp83640, | 582 | static void decode_rxts(struct dp83640_private *dp83640, |
| @@ -643,9 +655,7 @@ static void decode_status_frame(struct dp83640_private *dp83640, | |||
| 643 | 655 | ||
| 644 | } else if (PSF_EVNT == type && len >= sizeof(*phy_txts)) { | 656 | } else if (PSF_EVNT == type && len >= sizeof(*phy_txts)) { |
| 645 | 657 | ||
| 646 | phy_txts = (struct phy_txts *) ptr; | 658 | size = decode_evnt(dp83640, ptr, ests); |
| 647 | decode_evnt(dp83640, phy_txts, ests); | ||
| 648 | size = sizeof(*phy_txts); | ||
| 649 | 659 | ||
| 650 | } else { | 660 | } else { |
| 651 | size = 0; | 661 | size = 0; |
| @@ -1034,8 +1044,8 @@ static bool dp83640_rxtstamp(struct phy_device *phydev, | |||
| 1034 | 1044 | ||
| 1035 | if (is_status_frame(skb, type)) { | 1045 | if (is_status_frame(skb, type)) { |
| 1036 | decode_status_frame(dp83640, skb); | 1046 | decode_status_frame(dp83640, skb); |
| 1037 | /* Let the stack drop this frame. */ | 1047 | kfree_skb(skb); |
| 1038 | return false; | 1048 | return true; |
| 1039 | } | 1049 | } |
| 1040 | 1050 | ||
| 1041 | SKB_PTP_TYPE(skb) = type; | 1051 | SKB_PTP_TYPE(skb) = type; |
diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c index a1b82c9c67d2..c554a397e558 100644 --- a/drivers/net/ppp_async.c +++ b/drivers/net/ppp_async.c | |||
| @@ -523,7 +523,7 @@ static void ppp_async_process(unsigned long arg) | |||
| 523 | #define PUT_BYTE(ap, buf, c, islcp) do { \ | 523 | #define PUT_BYTE(ap, buf, c, islcp) do { \ |
| 524 | if ((islcp && c < 0x20) || (ap->xaccm[c >> 5] & (1 << (c & 0x1f)))) {\ | 524 | if ((islcp && c < 0x20) || (ap->xaccm[c >> 5] & (1 << (c & 0x1f)))) {\ |
| 525 | *buf++ = PPP_ESCAPE; \ | 525 | *buf++ = PPP_ESCAPE; \ |
| 526 | *buf++ = c ^ 0x20; \ | 526 | *buf++ = c ^ PPP_TRANS; \ |
| 527 | } else \ | 527 | } else \ |
| 528 | *buf++ = c; \ | 528 | *buf++ = c; \ |
| 529 | } while (0) | 529 | } while (0) |
| @@ -896,7 +896,7 @@ ppp_async_input(struct asyncppp *ap, const unsigned char *buf, | |||
| 896 | sp = skb_put(skb, n); | 896 | sp = skb_put(skb, n); |
| 897 | memcpy(sp, buf, n); | 897 | memcpy(sp, buf, n); |
| 898 | if (ap->state & SC_ESCAPE) { | 898 | if (ap->state & SC_ESCAPE) { |
| 899 | sp[0] ^= 0x20; | 899 | sp[0] ^= PPP_TRANS; |
| 900 | ap->state &= ~SC_ESCAPE; | 900 | ap->state &= ~SC_ESCAPE; |
| 901 | } | 901 | } |
| 902 | } | 902 | } |
diff --git a/drivers/net/pxa168_eth.c b/drivers/net/pxa168_eth.c index 89f7540d90f9..5f597ca592bb 100644 --- a/drivers/net/pxa168_eth.c +++ b/drivers/net/pxa168_eth.c | |||
| @@ -1273,7 +1273,7 @@ static int pxa168_eth_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 1273 | wmb(); | 1273 | wmb(); |
| 1274 | wrl(pep, SDMA_CMD, SDMA_CMD_TXDH | SDMA_CMD_ERD); | 1274 | wrl(pep, SDMA_CMD, SDMA_CMD_TXDH | SDMA_CMD_ERD); |
| 1275 | 1275 | ||
| 1276 | stats->tx_bytes += skb->len; | 1276 | stats->tx_bytes += length; |
| 1277 | stats->tx_packets++; | 1277 | stats->tx_packets++; |
| 1278 | dev->trans_start = jiffies; | 1278 | dev->trans_start = jiffies; |
| 1279 | if (pep->tx_ring_size - pep->tx_desc_count <= 1) { | 1279 | if (pep->tx_ring_size - pep->tx_desc_count <= 1) { |
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index ef1ce2ebeb4a..05d81780d1fd 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
| @@ -1621,7 +1621,7 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, | |||
| 1621 | * | 1621 | * |
| 1622 | * (RTL_R32(TxConfig) & 0x700000) == 0x200000 ? 8101Eb : 8101Ec | 1622 | * (RTL_R32(TxConfig) & 0x700000) == 0x200000 ? 8101Eb : 8101Ec |
| 1623 | */ | 1623 | */ |
| 1624 | static const struct { | 1624 | static const struct rtl_mac_info { |
| 1625 | u32 mask; | 1625 | u32 mask; |
| 1626 | u32 val; | 1626 | u32 val; |
| 1627 | int mac_version; | 1627 | int mac_version; |
| @@ -1689,7 +1689,8 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, | |||
| 1689 | 1689 | ||
| 1690 | /* Catch-all */ | 1690 | /* Catch-all */ |
| 1691 | { 0x00000000, 0x00000000, RTL_GIGA_MAC_NONE } | 1691 | { 0x00000000, 0x00000000, RTL_GIGA_MAC_NONE } |
| 1692 | }, *p = mac_info; | 1692 | }; |
| 1693 | const struct rtl_mac_info *p = mac_info; | ||
| 1693 | u32 reg; | 1694 | u32 reg; |
| 1694 | 1695 | ||
| 1695 | reg = RTL_R32(TxConfig); | 1696 | reg = RTL_R32(TxConfig); |
| @@ -3681,7 +3682,7 @@ static void rtl_set_rx_max_size(void __iomem *ioaddr, unsigned int rx_buf_sz) | |||
| 3681 | 3682 | ||
| 3682 | static void rtl8169_set_magic_reg(void __iomem *ioaddr, unsigned mac_version) | 3683 | static void rtl8169_set_magic_reg(void __iomem *ioaddr, unsigned mac_version) |
| 3683 | { | 3684 | { |
| 3684 | static const struct { | 3685 | static const struct rtl_cfg2_info { |
| 3685 | u32 mac_version; | 3686 | u32 mac_version; |
| 3686 | u32 clk; | 3687 | u32 clk; |
| 3687 | u32 val; | 3688 | u32 val; |
| @@ -3690,7 +3691,8 @@ static void rtl8169_set_magic_reg(void __iomem *ioaddr, unsigned mac_version) | |||
| 3690 | { RTL_GIGA_MAC_VER_05, PCI_Clock_66MHz, 0x000fffff }, | 3691 | { RTL_GIGA_MAC_VER_05, PCI_Clock_66MHz, 0x000fffff }, |
| 3691 | { RTL_GIGA_MAC_VER_06, PCI_Clock_33MHz, 0x00ffff00 }, // 8110SCe | 3692 | { RTL_GIGA_MAC_VER_06, PCI_Clock_33MHz, 0x00ffff00 }, // 8110SCe |
| 3692 | { RTL_GIGA_MAC_VER_06, PCI_Clock_66MHz, 0x00ffffff } | 3693 | { RTL_GIGA_MAC_VER_06, PCI_Clock_66MHz, 0x00ffffff } |
| 3693 | }, *p = cfg2_info; | 3694 | }; |
| 3695 | const struct rtl_cfg2_info *p = cfg2_info; | ||
| 3694 | unsigned int i; | 3696 | unsigned int i; |
| 3695 | u32 clk; | 3697 | u32 clk; |
| 3696 | 3698 | ||
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 74e94054ab1a..5235f48be1be 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
| @@ -460,7 +460,23 @@ static u32 tun_net_fix_features(struct net_device *dev, u32 features) | |||
| 460 | 460 | ||
| 461 | return (features & tun->set_features) | (features & ~TUN_USER_FEATURES); | 461 | return (features & tun->set_features) | (features & ~TUN_USER_FEATURES); |
| 462 | } | 462 | } |
| 463 | 463 | #ifdef CONFIG_NET_POLL_CONTROLLER | |
| 464 | static void tun_poll_controller(struct net_device *dev) | ||
| 465 | { | ||
| 466 | /* | ||
| 467 | * Tun only receives frames when: | ||
| 468 | * 1) the char device endpoint gets data from user space | ||
| 469 | * 2) the tun socket gets a sendmsg call from user space | ||
| 470 | * Since both of those are syncronous operations, we are guaranteed | ||
| 471 | * never to have pending data when we poll for it | ||
| 472 | * so theres nothing to do here but return. | ||
| 473 | * We need this though so netpoll recognizes us as an interface that | ||
| 474 | * supports polling, which enables bridge devices in virt setups to | ||
| 475 | * still use netconsole | ||
| 476 | */ | ||
| 477 | return; | ||
| 478 | } | ||
| 479 | #endif | ||
| 464 | static const struct net_device_ops tun_netdev_ops = { | 480 | static const struct net_device_ops tun_netdev_ops = { |
| 465 | .ndo_uninit = tun_net_uninit, | 481 | .ndo_uninit = tun_net_uninit, |
| 466 | .ndo_open = tun_net_open, | 482 | .ndo_open = tun_net_open, |
| @@ -468,6 +484,9 @@ static const struct net_device_ops tun_netdev_ops = { | |||
| 468 | .ndo_start_xmit = tun_net_xmit, | 484 | .ndo_start_xmit = tun_net_xmit, |
| 469 | .ndo_change_mtu = tun_net_change_mtu, | 485 | .ndo_change_mtu = tun_net_change_mtu, |
| 470 | .ndo_fix_features = tun_net_fix_features, | 486 | .ndo_fix_features = tun_net_fix_features, |
| 487 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
| 488 | .ndo_poll_controller = tun_poll_controller, | ||
| 489 | #endif | ||
| 471 | }; | 490 | }; |
| 472 | 491 | ||
| 473 | static const struct net_device_ops tap_netdev_ops = { | 492 | static const struct net_device_ops tap_netdev_ops = { |
| @@ -480,6 +499,9 @@ static const struct net_device_ops tap_netdev_ops = { | |||
| 480 | .ndo_set_multicast_list = tun_net_mclist, | 499 | .ndo_set_multicast_list = tun_net_mclist, |
| 481 | .ndo_set_mac_address = eth_mac_addr, | 500 | .ndo_set_mac_address = eth_mac_addr, |
| 482 | .ndo_validate_addr = eth_validate_addr, | 501 | .ndo_validate_addr = eth_validate_addr, |
| 502 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
| 503 | .ndo_poll_controller = tun_poll_controller, | ||
| 504 | #endif | ||
| 483 | }; | 505 | }; |
| 484 | 506 | ||
| 485 | /* Initialize net device. */ | 507 | /* Initialize net device. */ |
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index 9d4f9117260f..84d4608153c9 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig | |||
| @@ -385,6 +385,16 @@ config USB_NET_CX82310_ETH | |||
| 385 | router with USB ethernet port. This driver is for routers only, | 385 | router with USB ethernet port. This driver is for routers only, |
| 386 | it will not work with ADSL modems (use cxacru driver instead). | 386 | it will not work with ADSL modems (use cxacru driver instead). |
| 387 | 387 | ||
| 388 | config USB_NET_KALMIA | ||
| 389 | tristate "Samsung Kalmia based LTE USB modem" | ||
| 390 | depends on USB_USBNET | ||
| 391 | help | ||
| 392 | Choose this option if you have a Samsung Kalmia based USB modem | ||
| 393 | as Samsung GT-B3730. | ||
| 394 | |||
| 395 | To compile this driver as a module, choose M here: the | ||
| 396 | module will be called kalmia. | ||
| 397 | |||
| 388 | config USB_HSO | 398 | config USB_HSO |
| 389 | tristate "Option USB High Speed Mobile Devices" | 399 | tristate "Option USB High Speed Mobile Devices" |
| 390 | depends on USB && RFKILL | 400 | depends on USB && RFKILL |
diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile index c7ec8a5f0a90..c203fa21f6b1 100644 --- a/drivers/net/usb/Makefile +++ b/drivers/net/usb/Makefile | |||
| @@ -23,6 +23,7 @@ obj-$(CONFIG_USB_NET_MCS7830) += mcs7830.o | |||
| 23 | obj-$(CONFIG_USB_USBNET) += usbnet.o | 23 | obj-$(CONFIG_USB_USBNET) += usbnet.o |
| 24 | obj-$(CONFIG_USB_NET_INT51X1) += int51x1.o | 24 | obj-$(CONFIG_USB_NET_INT51X1) += int51x1.o |
| 25 | obj-$(CONFIG_USB_CDC_PHONET) += cdc-phonet.o | 25 | obj-$(CONFIG_USB_CDC_PHONET) += cdc-phonet.o |
| 26 | obj-$(CONFIG_USB_NET_KALMIA) += kalmia.o | ||
| 26 | obj-$(CONFIG_USB_IPHETH) += ipheth.o | 27 | obj-$(CONFIG_USB_IPHETH) += ipheth.o |
| 27 | obj-$(CONFIG_USB_SIERRA_NET) += sierra_net.o | 28 | obj-$(CONFIG_USB_SIERRA_NET) += sierra_net.o |
| 28 | obj-$(CONFIG_USB_NET_CX82310_ETH) += cx82310_eth.o | 29 | obj-$(CONFIG_USB_NET_CX82310_ETH) += cx82310_eth.o |
diff --git a/drivers/net/usb/kalmia.c b/drivers/net/usb/kalmia.c new file mode 100644 index 000000000000..d965fb1e013e --- /dev/null +++ b/drivers/net/usb/kalmia.c | |||
| @@ -0,0 +1,384 @@ | |||
| 1 | /* | ||
| 2 | * USB network interface driver for Samsung Kalmia based LTE USB modem like the | ||
| 3 | * Samsung GT-B3730 and GT-B3710. | ||
| 4 | * | ||
| 5 | * Copyright (C) 2011 Marius Bjoernstad Kotsbak <marius@kotsbak.com> | ||
| 6 | * | ||
| 7 | * Sponsored by Quicklink Video Distribution Services Ltd. | ||
| 8 | * | ||
| 9 | * Based on the cdc_eem module. | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or modify | ||
| 12 | * it under the terms of the GNU General Public License as published by | ||
| 13 | * the Free Software Foundation; either version 2 of the License, or | ||
| 14 | * (at your option) any later version. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <linux/module.h> | ||
| 18 | #include <linux/init.h> | ||
| 19 | #include <linux/netdevice.h> | ||
| 20 | #include <linux/etherdevice.h> | ||
| 21 | #include <linux/ctype.h> | ||
| 22 | #include <linux/ethtool.h> | ||
| 23 | #include <linux/workqueue.h> | ||
| 24 | #include <linux/mii.h> | ||
| 25 | #include <linux/usb.h> | ||
| 26 | #include <linux/crc32.h> | ||
| 27 | #include <linux/usb/cdc.h> | ||
| 28 | #include <linux/usb/usbnet.h> | ||
| 29 | #include <linux/gfp.h> | ||
| 30 | |||
| 31 | /* | ||
| 32 | * The Samsung Kalmia based LTE USB modems have a CDC ACM port for modem control | ||
| 33 | * handled by the "option" module and an ethernet data port handled by this | ||
| 34 | * module. | ||
| 35 | * | ||
| 36 | * The stick must first be switched into modem mode by usb_modeswitch | ||
| 37 | * or similar tool. Then the modem gets sent two initialization packets by | ||
| 38 | * this module, which gives the MAC address of the device. User space can then | ||
| 39 | * connect the modem using AT commands through the ACM port and then use | ||
| 40 | * DHCP on the network interface exposed by this module. Network packets are | ||
| 41 | * sent to and from the modem in a proprietary format discovered after watching | ||
| 42 | * the behavior of the windows driver for the modem. | ||
| 43 | * | ||
| 44 | * More information about the use of the modem is available in usb_modeswitch | ||
| 45 | * forum and the project page: | ||
| 46 | * | ||
| 47 | * http://www.draisberghof.de/usb_modeswitch/bb/viewtopic.php?t=465 | ||
| 48 | * https://github.com/mkotsbak/Samsung-GT-B3730-linux-driver | ||
| 49 | */ | ||
| 50 | |||
| 51 | /* #define DEBUG */ | ||
| 52 | /* #define VERBOSE */ | ||
| 53 | |||
| 54 | #define KALMIA_HEADER_LENGTH 6 | ||
| 55 | #define KALMIA_ALIGN_SIZE 4 | ||
| 56 | #define KALMIA_USB_TIMEOUT 10000 | ||
| 57 | |||
| 58 | /*-------------------------------------------------------------------------*/ | ||
| 59 | |||
| 60 | static int | ||
| 61 | kalmia_send_init_packet(struct usbnet *dev, u8 *init_msg, u8 init_msg_len, | ||
| 62 | u8 *buffer, u8 expected_len) | ||
| 63 | { | ||
| 64 | int act_len; | ||
| 65 | int status; | ||
| 66 | |||
| 67 | netdev_dbg(dev->net, "Sending init packet"); | ||
| 68 | |||
| 69 | status = usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 0x02), | ||
| 70 | init_msg, init_msg_len, &act_len, KALMIA_USB_TIMEOUT); | ||
| 71 | if (status != 0) { | ||
| 72 | netdev_err(dev->net, | ||
| 73 | "Error sending init packet. Status %i, length %i\n", | ||
| 74 | status, act_len); | ||
| 75 | return status; | ||
| 76 | } | ||
| 77 | else if (act_len != init_msg_len) { | ||
| 78 | netdev_err(dev->net, | ||
| 79 | "Did not send all of init packet. Bytes sent: %i", | ||
| 80 | act_len); | ||
| 81 | } | ||
| 82 | else { | ||
| 83 | netdev_dbg(dev->net, "Successfully sent init packet."); | ||
| 84 | } | ||
| 85 | |||
| 86 | status = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, 0x81), | ||
| 87 | buffer, expected_len, &act_len, KALMIA_USB_TIMEOUT); | ||
| 88 | |||
| 89 | if (status != 0) | ||
| 90 | netdev_err(dev->net, | ||
| 91 | "Error receiving init result. Status %i, length %i\n", | ||
| 92 | status, act_len); | ||
| 93 | else if (act_len != expected_len) | ||
| 94 | netdev_err(dev->net, "Unexpected init result length: %i\n", | ||
| 95 | act_len); | ||
| 96 | |||
| 97 | return status; | ||
| 98 | } | ||
| 99 | |||
| 100 | static int | ||
| 101 | kalmia_init_and_get_ethernet_addr(struct usbnet *dev, u8 *ethernet_addr) | ||
| 102 | { | ||
| 103 | char init_msg_1[] = | ||
| 104 | { 0x57, 0x50, 0x04, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, | ||
| 105 | 0x00, 0x00 }; | ||
| 106 | char init_msg_2[] = | ||
| 107 | { 0x57, 0x50, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xf4, | ||
| 108 | 0x00, 0x00 }; | ||
| 109 | char receive_buf[28]; | ||
| 110 | int status; | ||
| 111 | |||
| 112 | status = kalmia_send_init_packet(dev, init_msg_1, sizeof(init_msg_1) | ||
| 113 | / sizeof(init_msg_1[0]), receive_buf, 24); | ||
| 114 | if (status != 0) | ||
| 115 | return status; | ||
| 116 | |||
| 117 | status = kalmia_send_init_packet(dev, init_msg_2, sizeof(init_msg_2) | ||
| 118 | / sizeof(init_msg_2[0]), receive_buf, 28); | ||
| 119 | if (status != 0) | ||
| 120 | return status; | ||
| 121 | |||
| 122 | memcpy(ethernet_addr, receive_buf + 10, ETH_ALEN); | ||
| 123 | |||
| 124 | return status; | ||
| 125 | } | ||
| 126 | |||
| 127 | static int | ||
| 128 | kalmia_bind(struct usbnet *dev, struct usb_interface *intf) | ||
| 129 | { | ||
| 130 | u8 status; | ||
| 131 | u8 ethernet_addr[ETH_ALEN]; | ||
| 132 | |||
| 133 | /* Don't bind to AT command interface */ | ||
| 134 | if (intf->cur_altsetting->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC) | ||
| 135 | return -EINVAL; | ||
| 136 | |||
| 137 | dev->in = usb_rcvbulkpipe(dev->udev, 0x81 & USB_ENDPOINT_NUMBER_MASK); | ||
| 138 | dev->out = usb_sndbulkpipe(dev->udev, 0x02 & USB_ENDPOINT_NUMBER_MASK); | ||
| 139 | dev->status = NULL; | ||
| 140 | |||
| 141 | dev->net->hard_header_len += KALMIA_HEADER_LENGTH; | ||
| 142 | dev->hard_mtu = 1400; | ||
| 143 | dev->rx_urb_size = dev->hard_mtu * 10; // Found as optimal after testing | ||
| 144 | |||
| 145 | status = kalmia_init_and_get_ethernet_addr(dev, ethernet_addr); | ||
| 146 | |||
| 147 | if (status < 0) { | ||
| 148 | usb_set_intfdata(intf, NULL); | ||
| 149 | usb_driver_release_interface(driver_of(intf), intf); | ||
| 150 | return status; | ||
| 151 | } | ||
| 152 | |||
| 153 | memcpy(dev->net->dev_addr, ethernet_addr, ETH_ALEN); | ||
| 154 | memcpy(dev->net->perm_addr, ethernet_addr, ETH_ALEN); | ||
| 155 | |||
| 156 | return status; | ||
| 157 | } | ||
| 158 | |||
| 159 | static struct sk_buff * | ||
| 160 | kalmia_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) | ||
| 161 | { | ||
| 162 | struct sk_buff *skb2 = NULL; | ||
| 163 | u16 content_len; | ||
| 164 | unsigned char *header_start; | ||
| 165 | unsigned char ether_type_1, ether_type_2; | ||
| 166 | u8 remainder, padlen = 0; | ||
| 167 | |||
| 168 | if (!skb_cloned(skb)) { | ||
| 169 | int headroom = skb_headroom(skb); | ||
| 170 | int tailroom = skb_tailroom(skb); | ||
| 171 | |||
| 172 | if ((tailroom >= KALMIA_ALIGN_SIZE) && (headroom | ||
| 173 | >= KALMIA_HEADER_LENGTH)) | ||
| 174 | goto done; | ||
| 175 | |||
| 176 | if ((headroom + tailroom) > (KALMIA_HEADER_LENGTH | ||
| 177 | + KALMIA_ALIGN_SIZE)) { | ||
| 178 | skb->data = memmove(skb->head + KALMIA_HEADER_LENGTH, | ||
| 179 | skb->data, skb->len); | ||
| 180 | skb_set_tail_pointer(skb, skb->len); | ||
| 181 | goto done; | ||
| 182 | } | ||
| 183 | } | ||
| 184 | |||
| 185 | skb2 = skb_copy_expand(skb, KALMIA_HEADER_LENGTH, | ||
| 186 | KALMIA_ALIGN_SIZE, flags); | ||
| 187 | if (!skb2) | ||
| 188 | return NULL; | ||
| 189 | |||
| 190 | dev_kfree_skb_any(skb); | ||
| 191 | skb = skb2; | ||
| 192 | |||
| 193 | done: header_start = skb_push(skb, KALMIA_HEADER_LENGTH); | ||
| 194 | ether_type_1 = header_start[KALMIA_HEADER_LENGTH + 12]; | ||
| 195 | ether_type_2 = header_start[KALMIA_HEADER_LENGTH + 13]; | ||
| 196 | |||
| 197 | netdev_dbg(dev->net, "Sending etherType: %02x%02x", ether_type_1, | ||
| 198 | ether_type_2); | ||
| 199 | |||
| 200 | /* According to empiric data for data packages */ | ||
| 201 | header_start[0] = 0x57; | ||
| 202 | header_start[1] = 0x44; | ||
| 203 | content_len = skb->len - KALMIA_HEADER_LENGTH; | ||
| 204 | header_start[2] = (content_len & 0xff); /* low byte */ | ||
| 205 | header_start[3] = (content_len >> 8); /* high byte */ | ||
| 206 | |||
| 207 | header_start[4] = ether_type_1; | ||
| 208 | header_start[5] = ether_type_2; | ||
| 209 | |||
| 210 | /* Align to 4 bytes by padding with zeros */ | ||
| 211 | remainder = skb->len % KALMIA_ALIGN_SIZE; | ||
| 212 | if (remainder > 0) { | ||
| 213 | padlen = KALMIA_ALIGN_SIZE - remainder; | ||
| 214 | memset(skb_put(skb, padlen), 0, padlen); | ||
| 215 | } | ||
| 216 | |||
| 217 | netdev_dbg( | ||
| 218 | dev->net, | ||
| 219 | "Sending package with length %i and padding %i. Header: %02x:%02x:%02x:%02x:%02x:%02x.", | ||
| 220 | content_len, padlen, header_start[0], header_start[1], | ||
| 221 | header_start[2], header_start[3], header_start[4], | ||
| 222 | header_start[5]); | ||
| 223 | |||
| 224 | return skb; | ||
| 225 | } | ||
| 226 | |||
| 227 | static int | ||
| 228 | kalmia_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | ||
| 229 | { | ||
| 230 | /* | ||
| 231 | * Our task here is to strip off framing, leaving skb with one | ||
| 232 | * data frame for the usbnet framework code to process. | ||
| 233 | */ | ||
| 234 | const u8 HEADER_END_OF_USB_PACKET[] = | ||
| 235 | { 0x57, 0x5a, 0x00, 0x00, 0x08, 0x00 }; | ||
| 236 | const u8 EXPECTED_UNKNOWN_HEADER_1[] = | ||
| 237 | { 0x57, 0x43, 0x1e, 0x00, 0x15, 0x02 }; | ||
| 238 | const u8 EXPECTED_UNKNOWN_HEADER_2[] = | ||
| 239 | { 0x57, 0x50, 0x0e, 0x00, 0x00, 0x00 }; | ||
| 240 | u8 i = 0; | ||
| 241 | |||
| 242 | /* incomplete header? */ | ||
| 243 | if (skb->len < KALMIA_HEADER_LENGTH) | ||
| 244 | return 0; | ||
| 245 | |||
| 246 | do { | ||
| 247 | struct sk_buff *skb2 = NULL; | ||
| 248 | u8 *header_start; | ||
| 249 | u16 usb_packet_length, ether_packet_length; | ||
| 250 | int is_last; | ||
| 251 | |||
| 252 | header_start = skb->data; | ||
| 253 | |||
| 254 | if (unlikely(header_start[0] != 0x57 || header_start[1] != 0x44)) { | ||
| 255 | if (!memcmp(header_start, EXPECTED_UNKNOWN_HEADER_1, | ||
| 256 | sizeof(EXPECTED_UNKNOWN_HEADER_1)) || !memcmp( | ||
| 257 | header_start, EXPECTED_UNKNOWN_HEADER_2, | ||
| 258 | sizeof(EXPECTED_UNKNOWN_HEADER_2))) { | ||
| 259 | netdev_dbg( | ||
| 260 | dev->net, | ||
| 261 | "Received expected unknown frame header: %02x:%02x:%02x:%02x:%02x:%02x. Package length: %i\n", | ||
| 262 | header_start[0], header_start[1], | ||
| 263 | header_start[2], header_start[3], | ||
| 264 | header_start[4], header_start[5], | ||
| 265 | skb->len - KALMIA_HEADER_LENGTH); | ||
| 266 | } | ||
| 267 | else { | ||
| 268 | netdev_err( | ||
| 269 | dev->net, | ||
| 270 | "Received unknown frame header: %02x:%02x:%02x:%02x:%02x:%02x. Package length: %i\n", | ||
| 271 | header_start[0], header_start[1], | ||
| 272 | header_start[2], header_start[3], | ||
| 273 | header_start[4], header_start[5], | ||
| 274 | skb->len - KALMIA_HEADER_LENGTH); | ||
| 275 | return 0; | ||
| 276 | } | ||
| 277 | } | ||
| 278 | else | ||
| 279 | netdev_dbg( | ||
| 280 | dev->net, | ||
| 281 | "Received header: %02x:%02x:%02x:%02x:%02x:%02x. Package length: %i\n", | ||
| 282 | header_start[0], header_start[1], header_start[2], | ||
| 283 | header_start[3], header_start[4], header_start[5], | ||
| 284 | skb->len - KALMIA_HEADER_LENGTH); | ||
| 285 | |||
| 286 | /* subtract start header and end header */ | ||
| 287 | usb_packet_length = skb->len - (2 * KALMIA_HEADER_LENGTH); | ||
| 288 | ether_packet_length = header_start[2] + (header_start[3] << 8); | ||
| 289 | skb_pull(skb, KALMIA_HEADER_LENGTH); | ||
| 290 | |||
| 291 | /* Some small packets misses end marker */ | ||
| 292 | if (usb_packet_length < ether_packet_length) { | ||
| 293 | ether_packet_length = usb_packet_length | ||
| 294 | + KALMIA_HEADER_LENGTH; | ||
| 295 | is_last = true; | ||
| 296 | } | ||
| 297 | else { | ||
| 298 | netdev_dbg(dev->net, "Correct package length #%i", i | ||
| 299 | + 1); | ||
| 300 | |||
| 301 | is_last = (memcmp(skb->data + ether_packet_length, | ||
| 302 | HEADER_END_OF_USB_PACKET, | ||
| 303 | sizeof(HEADER_END_OF_USB_PACKET)) == 0); | ||
| 304 | if (!is_last) { | ||
| 305 | header_start = skb->data + ether_packet_length; | ||
| 306 | netdev_dbg( | ||
| 307 | dev->net, | ||
| 308 | "End header: %02x:%02x:%02x:%02x:%02x:%02x. Package length: %i\n", | ||
| 309 | header_start[0], header_start[1], | ||
| 310 | header_start[2], header_start[3], | ||
| 311 | header_start[4], header_start[5], | ||
| 312 | skb->len - KALMIA_HEADER_LENGTH); | ||
| 313 | } | ||
| 314 | } | ||
| 315 | |||
| 316 | if (is_last) { | ||
| 317 | skb2 = skb; | ||
| 318 | } | ||
| 319 | else { | ||
| 320 | skb2 = skb_clone(skb, GFP_ATOMIC); | ||
| 321 | if (unlikely(!skb2)) | ||
| 322 | return 0; | ||
| 323 | } | ||
| 324 | |||
| 325 | skb_trim(skb2, ether_packet_length); | ||
| 326 | |||
| 327 | if (is_last) { | ||
| 328 | return 1; | ||
| 329 | } | ||
| 330 | else { | ||
| 331 | usbnet_skb_return(dev, skb2); | ||
| 332 | skb_pull(skb, ether_packet_length); | ||
| 333 | } | ||
| 334 | |||
| 335 | i++; | ||
| 336 | } | ||
| 337 | while (skb->len); | ||
| 338 | |||
| 339 | return 1; | ||
| 340 | } | ||
| 341 | |||
| 342 | static const struct driver_info kalmia_info = { | ||
| 343 | .description = "Samsung Kalmia LTE USB dongle", | ||
| 344 | .flags = FLAG_WWAN, | ||
| 345 | .bind = kalmia_bind, | ||
| 346 | .rx_fixup = kalmia_rx_fixup, | ||
| 347 | .tx_fixup = kalmia_tx_fixup | ||
| 348 | }; | ||
| 349 | |||
| 350 | /*-------------------------------------------------------------------------*/ | ||
| 351 | |||
| 352 | static const struct usb_device_id products[] = { | ||
| 353 | /* The unswitched USB ID, to get the module auto loaded: */ | ||
| 354 | { USB_DEVICE(0x04e8, 0x689a) }, | ||
| 355 | /* The stick swithed into modem (by e.g. usb_modeswitch): */ | ||
| 356 | { USB_DEVICE(0x04e8, 0x6889), | ||
| 357 | .driver_info = (unsigned long) &kalmia_info, }, | ||
| 358 | { /* EMPTY == end of list */} }; | ||
| 359 | MODULE_DEVICE_TABLE( usb, products); | ||
| 360 | |||
| 361 | static struct usb_driver kalmia_driver = { | ||
| 362 | .name = "kalmia", | ||
| 363 | .id_table = products, | ||
| 364 | .probe = usbnet_probe, | ||
| 365 | .disconnect = usbnet_disconnect, | ||
| 366 | .suspend = usbnet_suspend, | ||
| 367 | .resume = usbnet_resume | ||
| 368 | }; | ||
| 369 | |||
| 370 | static int __init kalmia_init(void) | ||
| 371 | { | ||
| 372 | return usb_register(&kalmia_driver); | ||
| 373 | } | ||
| 374 | module_init( kalmia_init); | ||
| 375 | |||
| 376 | static void __exit kalmia_exit(void) | ||
| 377 | { | ||
| 378 | usb_deregister(&kalmia_driver); | ||
| 379 | } | ||
| 380 | module_exit( kalmia_exit); | ||
| 381 | |||
| 382 | MODULE_AUTHOR("Marius Bjoernstad Kotsbak <marius@kotsbak.com>"); | ||
| 383 | MODULE_DESCRIPTION("Samsung Kalmia USB network driver"); | ||
| 384 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c index e050bd65e037..777d1a4e81b2 100644 --- a/drivers/net/wan/farsync.c +++ b/drivers/net/wan/farsync.c | |||
| @@ -2203,8 +2203,10 @@ fst_open(struct net_device *dev) | |||
| 2203 | 2203 | ||
| 2204 | if (port->mode != FST_RAW) { | 2204 | if (port->mode != FST_RAW) { |
| 2205 | err = hdlc_open(dev); | 2205 | err = hdlc_open(dev); |
| 2206 | if (err) | 2206 | if (err) { |
| 2207 | module_put(THIS_MODULE); | ||
| 2207 | return err; | 2208 | return err; |
| 2209 | } | ||
| 2208 | } | 2210 | } |
| 2209 | 2211 | ||
| 2210 | fst_openport(port); | 2212 | fst_openport(port); |
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 660831ce293c..687c1f223497 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c | |||
| @@ -1288,6 +1288,8 @@ int mwifiex_register_cfg80211(struct net_device *dev, u8 *mac, | |||
| 1288 | 1288 | ||
| 1289 | *(unsigned long *) wdev_priv = (unsigned long) priv; | 1289 | *(unsigned long *) wdev_priv = (unsigned long) priv; |
| 1290 | 1290 | ||
| 1291 | set_wiphy_dev(wdev->wiphy, (struct device *) priv->adapter->dev); | ||
| 1292 | |||
| 1291 | ret = wiphy_register(wdev->wiphy); | 1293 | ret = wiphy_register(wdev->wiphy); |
| 1292 | if (ret < 0) { | 1294 | if (ret < 0) { |
| 1293 | dev_err(priv->adapter->dev, "%s: registering cfg80211 device\n", | 1295 | dev_err(priv->adapter->dev, "%s: registering cfg80211 device\n", |
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 32261189bcef..aeac3cc4dbe4 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c | |||
| @@ -2474,6 +2474,7 @@ struct mwl8k_cmd_set_hw_spec { | |||
| 2474 | * faster client. | 2474 | * faster client. |
| 2475 | */ | 2475 | */ |
| 2476 | #define MWL8K_SET_HW_SPEC_FLAG_ENABLE_LIFE_TIME_EXPIRY 0x00000400 | 2476 | #define MWL8K_SET_HW_SPEC_FLAG_ENABLE_LIFE_TIME_EXPIRY 0x00000400 |
| 2477 | #define MWL8K_SET_HW_SPEC_FLAG_GENERATE_CCMP_HDR 0x00000200 | ||
| 2477 | #define MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT 0x00000080 | 2478 | #define MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT 0x00000080 |
| 2478 | #define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP 0x00000020 | 2479 | #define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP 0x00000020 |
| 2479 | #define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON 0x00000010 | 2480 | #define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON 0x00000010 |
| @@ -2510,7 +2511,8 @@ static int mwl8k_cmd_set_hw_spec(struct ieee80211_hw *hw) | |||
| 2510 | cmd->flags = cpu_to_le32(MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT | | 2511 | cmd->flags = cpu_to_le32(MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT | |
| 2511 | MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP | | 2512 | MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP | |
| 2512 | MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON | | 2513 | MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON | |
| 2513 | MWL8K_SET_HW_SPEC_FLAG_ENABLE_LIFE_TIME_EXPIRY); | 2514 | MWL8K_SET_HW_SPEC_FLAG_ENABLE_LIFE_TIME_EXPIRY | |
| 2515 | MWL8K_SET_HW_SPEC_FLAG_GENERATE_CCMP_HDR); | ||
| 2514 | cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS); | 2516 | cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS); |
| 2515 | cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS); | 2517 | cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS); |
| 2516 | 2518 | ||
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h index c7c42e7acc31..5d4f8e586e32 100644 --- a/include/net/netfilter/nf_conntrack.h +++ b/include/net/netfilter/nf_conntrack.h | |||
| @@ -307,6 +307,12 @@ static inline int nf_ct_is_untracked(const struct nf_conn *ct) | |||
| 307 | return test_bit(IPS_UNTRACKED_BIT, &ct->status); | 307 | return test_bit(IPS_UNTRACKED_BIT, &ct->status); |
| 308 | } | 308 | } |
| 309 | 309 | ||
| 310 | /* Packet is received from loopback */ | ||
| 311 | static inline bool nf_is_loopback_packet(const struct sk_buff *skb) | ||
| 312 | { | ||
| 313 | return skb->dev && skb->skb_iif && skb->dev->flags & IFF_LOOPBACK; | ||
| 314 | } | ||
| 315 | |||
| 310 | extern int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp); | 316 | extern int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp); |
| 311 | extern unsigned int nf_conntrack_htable_size; | 317 | extern unsigned int nf_conntrack_htable_size; |
| 312 | extern unsigned int nf_conntrack_max; | 318 | extern unsigned int nf_conntrack_max; |
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index c7a581a96894..917ecb93ea28 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c | |||
| @@ -205,7 +205,7 @@ int register_vlan_dev(struct net_device *dev) | |||
| 205 | grp->nr_vlans++; | 205 | grp->nr_vlans++; |
| 206 | 206 | ||
| 207 | if (ngrp) { | 207 | if (ngrp) { |
| 208 | if (ops->ndo_vlan_rx_register) | 208 | if (ops->ndo_vlan_rx_register && (real_dev->features & NETIF_F_HW_VLAN_RX)) |
| 209 | ops->ndo_vlan_rx_register(real_dev, ngrp); | 209 | ops->ndo_vlan_rx_register(real_dev, ngrp); |
| 210 | rcu_assign_pointer(real_dev->vlgrp, ngrp); | 210 | rcu_assign_pointer(real_dev->vlgrp, ngrp); |
| 211 | } | 211 | } |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index f13ddbf858ba..77930aa522e3 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
| @@ -477,14 +477,16 @@ static void hci_setup_event_mask(struct hci_dev *hdev) | |||
| 477 | * command otherwise */ | 477 | * command otherwise */ |
| 478 | u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 }; | 478 | u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 }; |
| 479 | 479 | ||
| 480 | /* Events for 1.2 and newer controllers */ | 480 | /* CSR 1.1 dongles does not accept any bitfield so don't try to set |
| 481 | if (hdev->lmp_ver > 1) { | 481 | * any event mask for pre 1.2 devices */ |
| 482 | events[4] |= 0x01; /* Flow Specification Complete */ | 482 | if (hdev->lmp_ver <= 1) |
| 483 | events[4] |= 0x02; /* Inquiry Result with RSSI */ | 483 | return; |
| 484 | events[4] |= 0x04; /* Read Remote Extended Features Complete */ | 484 | |
| 485 | events[5] |= 0x08; /* Synchronous Connection Complete */ | 485 | events[4] |= 0x01; /* Flow Specification Complete */ |
| 486 | events[5] |= 0x10; /* Synchronous Connection Changed */ | 486 | events[4] |= 0x02; /* Inquiry Result with RSSI */ |
| 487 | } | 487 | events[4] |= 0x04; /* Read Remote Extended Features Complete */ |
| 488 | events[5] |= 0x08; /* Synchronous Connection Complete */ | ||
| 489 | events[5] |= 0x10; /* Synchronous Connection Changed */ | ||
| 488 | 490 | ||
| 489 | if (hdev->features[3] & LMP_RSSI_INQ) | 491 | if (hdev->features[3] & LMP_RSSI_INQ) |
| 490 | events[4] |= 0x04; /* Inquiry Result with RSSI */ | 492 | events[4] |= 0x04; /* Inquiry Result with RSSI */ |
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 18dc9888d8c2..8248303f44e8 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
| @@ -413,6 +413,7 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us | |||
| 413 | break; | 413 | break; |
| 414 | } | 414 | } |
| 415 | 415 | ||
| 416 | memset(&cinfo, 0, sizeof(cinfo)); | ||
| 416 | cinfo.hci_handle = chan->conn->hcon->handle; | 417 | cinfo.hci_handle = chan->conn->hcon->handle; |
| 417 | memcpy(cinfo.dev_class, chan->conn->hcon->dev_class, 3); | 418 | memcpy(cinfo.dev_class, chan->conn->hcon->dev_class, 3); |
| 418 | 419 | ||
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 386cfaffd4b7..1b10727ce523 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
| @@ -788,6 +788,7 @@ static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __u | |||
| 788 | 788 | ||
| 789 | l2cap_sk = rfcomm_pi(sk)->dlc->session->sock->sk; | 789 | l2cap_sk = rfcomm_pi(sk)->dlc->session->sock->sk; |
| 790 | 790 | ||
| 791 | memset(&cinfo, 0, sizeof(cinfo)); | ||
| 791 | cinfo.hci_handle = conn->hcon->handle; | 792 | cinfo.hci_handle = conn->hcon->handle; |
| 792 | memcpy(cinfo.dev_class, conn->hcon->dev_class, 3); | 793 | memcpy(cinfo.dev_class, conn->hcon->dev_class, 3); |
| 793 | 794 | ||
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 42fdffd1d76c..cb4fb7837e5c 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
| @@ -369,6 +369,15 @@ static void __sco_sock_close(struct sock *sk) | |||
| 369 | 369 | ||
| 370 | case BT_CONNECTED: | 370 | case BT_CONNECTED: |
| 371 | case BT_CONFIG: | 371 | case BT_CONFIG: |
| 372 | if (sco_pi(sk)->conn) { | ||
| 373 | sk->sk_state = BT_DISCONN; | ||
| 374 | sco_sock_set_timer(sk, SCO_DISCONN_TIMEOUT); | ||
| 375 | hci_conn_put(sco_pi(sk)->conn->hcon); | ||
| 376 | sco_pi(sk)->conn->hcon = NULL; | ||
| 377 | } else | ||
| 378 | sco_chan_del(sk, ECONNRESET); | ||
| 379 | break; | ||
| 380 | |||
| 372 | case BT_CONNECT: | 381 | case BT_CONNECT: |
| 373 | case BT_DISCONN: | 382 | case BT_DISCONN: |
| 374 | sco_chan_del(sk, ECONNRESET); | 383 | sco_chan_del(sk, ECONNRESET); |
| @@ -819,7 +828,9 @@ static void sco_chan_del(struct sock *sk, int err) | |||
| 819 | conn->sk = NULL; | 828 | conn->sk = NULL; |
| 820 | sco_pi(sk)->conn = NULL; | 829 | sco_pi(sk)->conn = NULL; |
| 821 | sco_conn_unlock(conn); | 830 | sco_conn_unlock(conn); |
| 822 | hci_conn_put(conn->hcon); | 831 | |
| 832 | if (conn->hcon) | ||
| 833 | hci_conn_put(conn->hcon); | ||
| 823 | } | 834 | } |
| 824 | 835 | ||
| 825 | sk->sk_state = BT_CLOSED; | 836 | sk->sk_state = BT_CLOSED; |
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index a6b2f86378c7..c188c803c09c 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c | |||
| @@ -243,6 +243,7 @@ int br_netpoll_enable(struct net_bridge_port *p) | |||
| 243 | goto out; | 243 | goto out; |
| 244 | 244 | ||
| 245 | np->dev = p->dev; | 245 | np->dev = p->dev; |
| 246 | strlcpy(np->dev_name, p->dev->name, IFNAMSIZ); | ||
| 246 | 247 | ||
| 247 | err = __netpoll_setup(np); | 248 | err = __netpoll_setup(np); |
| 248 | if (err) { | 249 | if (err) { |
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 2f14eafdeeab..29b9812c8da0 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c | |||
| @@ -1424,7 +1424,7 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br, | |||
| 1424 | switch (ih->type) { | 1424 | switch (ih->type) { |
| 1425 | case IGMP_HOST_MEMBERSHIP_REPORT: | 1425 | case IGMP_HOST_MEMBERSHIP_REPORT: |
| 1426 | case IGMPV2_HOST_MEMBERSHIP_REPORT: | 1426 | case IGMPV2_HOST_MEMBERSHIP_REPORT: |
| 1427 | BR_INPUT_SKB_CB(skb2)->mrouters_only = 1; | 1427 | BR_INPUT_SKB_CB(skb)->mrouters_only = 1; |
| 1428 | err = br_ip4_multicast_add_group(br, port, ih->group); | 1428 | err = br_ip4_multicast_add_group(br, port, ih->group); |
| 1429 | break; | 1429 | break; |
| 1430 | case IGMPV3_HOST_MEMBERSHIP_REPORT: | 1430 | case IGMPV3_HOST_MEMBERSHIP_REPORT: |
| @@ -1543,7 +1543,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br, | |||
| 1543 | goto out; | 1543 | goto out; |
| 1544 | } | 1544 | } |
| 1545 | mld = (struct mld_msg *)skb_transport_header(skb2); | 1545 | mld = (struct mld_msg *)skb_transport_header(skb2); |
| 1546 | BR_INPUT_SKB_CB(skb2)->mrouters_only = 1; | 1546 | BR_INPUT_SKB_CB(skb)->mrouters_only = 1; |
| 1547 | err = br_ip6_multicast_add_group(br, port, &mld->mld_mca); | 1547 | err = br_ip6_multicast_add_group(br, port, &mld->mld_mca); |
| 1548 | break; | 1548 | break; |
| 1549 | } | 1549 | } |
diff --git a/net/caif/cfmuxl.c b/net/caif/cfmuxl.c index 3a66b8c10e09..c23979e79dfa 100644 --- a/net/caif/cfmuxl.c +++ b/net/caif/cfmuxl.c | |||
| @@ -255,7 +255,7 @@ static void cfmuxl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, | |||
| 255 | 255 | ||
| 256 | if (cfsrvl_phyid_match(layer, phyid) && layer->ctrlcmd) { | 256 | if (cfsrvl_phyid_match(layer, phyid) && layer->ctrlcmd) { |
| 257 | 257 | ||
| 258 | if ((ctrl == _CAIF_CTRLCMD_PHYIF_FLOW_OFF_IND || | 258 | if ((ctrl == _CAIF_CTRLCMD_PHYIF_DOWN_IND || |
| 259 | ctrl == CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND) && | 259 | ctrl == CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND) && |
| 260 | layer->id != 0) { | 260 | layer->id != 0) { |
| 261 | 261 | ||
diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c index ed0eab39f531..02548b292b53 100644 --- a/net/ieee802154/nl-phy.c +++ b/net/ieee802154/nl-phy.c | |||
| @@ -44,7 +44,7 @@ static int ieee802154_nl_fill_phy(struct sk_buff *msg, u32 pid, | |||
| 44 | pr_debug("%s\n", __func__); | 44 | pr_debug("%s\n", __func__); |
| 45 | 45 | ||
| 46 | if (!buf) | 46 | if (!buf) |
| 47 | goto out; | 47 | return -EMSGSIZE; |
| 48 | 48 | ||
| 49 | hdr = genlmsg_put(msg, 0, seq, &nl802154_family, flags, | 49 | hdr = genlmsg_put(msg, 0, seq, &nl802154_family, flags, |
| 50 | IEEE802154_LIST_PHY); | 50 | IEEE802154_LIST_PHY); |
| @@ -65,6 +65,7 @@ static int ieee802154_nl_fill_phy(struct sk_buff *msg, u32 pid, | |||
| 65 | pages * sizeof(uint32_t), buf); | 65 | pages * sizeof(uint32_t), buf); |
| 66 | 66 | ||
| 67 | mutex_unlock(&phy->pib_lock); | 67 | mutex_unlock(&phy->pib_lock); |
| 68 | kfree(buf); | ||
| 68 | return genlmsg_end(msg, hdr); | 69 | return genlmsg_end(msg, hdr); |
| 69 | 70 | ||
| 70 | nla_put_failure: | 71 | nla_put_failure: |
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 9c1926027a26..eae1f676f870 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
| @@ -676,6 +676,7 @@ int inet_accept(struct socket *sock, struct socket *newsock, int flags) | |||
| 676 | 676 | ||
| 677 | lock_sock(sk2); | 677 | lock_sock(sk2); |
| 678 | 678 | ||
| 679 | sock_rps_record_flow(sk2); | ||
| 679 | WARN_ON(!((1 << sk2->sk_state) & | 680 | WARN_ON(!((1 << sk2->sk_state) & |
| 680 | (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT | TCPF_CLOSE))); | 681 | (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT | TCPF_CLOSE))); |
| 681 | 682 | ||
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index 6ffe94ca5bc9..3267d3898437 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c | |||
| @@ -437,7 +437,7 @@ static int valid_cc(const void *bc, int len, int cc) | |||
| 437 | return 0; | 437 | return 0; |
| 438 | if (cc == len) | 438 | if (cc == len) |
| 439 | return 1; | 439 | return 1; |
| 440 | if (op->yes < 4) | 440 | if (op->yes < 4 || op->yes & 3) |
| 441 | return 0; | 441 | return 0; |
| 442 | len -= op->yes; | 442 | len -= op->yes; |
| 443 | bc += op->yes; | 443 | bc += op->yes; |
| @@ -447,11 +447,11 @@ static int valid_cc(const void *bc, int len, int cc) | |||
| 447 | 447 | ||
| 448 | static int inet_diag_bc_audit(const void *bytecode, int bytecode_len) | 448 | static int inet_diag_bc_audit(const void *bytecode, int bytecode_len) |
| 449 | { | 449 | { |
| 450 | const unsigned char *bc = bytecode; | 450 | const void *bc = bytecode; |
| 451 | int len = bytecode_len; | 451 | int len = bytecode_len; |
| 452 | 452 | ||
| 453 | while (len > 0) { | 453 | while (len > 0) { |
| 454 | struct inet_diag_bc_op *op = (struct inet_diag_bc_op *)bc; | 454 | const struct inet_diag_bc_op *op = bc; |
| 455 | 455 | ||
| 456 | //printk("BC: %d %d %d {%d} / %d\n", op->code, op->yes, op->no, op[1].no, len); | 456 | //printk("BC: %d %d %d {%d} / %d\n", op->code, op->yes, op->no, op[1].no, len); |
| 457 | switch (op->code) { | 457 | switch (op->code) { |
| @@ -462,22 +462,20 @@ static int inet_diag_bc_audit(const void *bytecode, int bytecode_len) | |||
| 462 | case INET_DIAG_BC_S_LE: | 462 | case INET_DIAG_BC_S_LE: |
| 463 | case INET_DIAG_BC_D_GE: | 463 | case INET_DIAG_BC_D_GE: |
| 464 | case INET_DIAG_BC_D_LE: | 464 | case INET_DIAG_BC_D_LE: |
| 465 | if (op->yes < 4 || op->yes > len + 4) | ||
| 466 | return -EINVAL; | ||
| 467 | case INET_DIAG_BC_JMP: | 465 | case INET_DIAG_BC_JMP: |
| 468 | if (op->no < 4 || op->no > len + 4) | 466 | if (op->no < 4 || op->no > len + 4 || op->no & 3) |
| 469 | return -EINVAL; | 467 | return -EINVAL; |
| 470 | if (op->no < len && | 468 | if (op->no < len && |
| 471 | !valid_cc(bytecode, bytecode_len, len - op->no)) | 469 | !valid_cc(bytecode, bytecode_len, len - op->no)) |
| 472 | return -EINVAL; | 470 | return -EINVAL; |
| 473 | break; | 471 | break; |
| 474 | case INET_DIAG_BC_NOP: | 472 | case INET_DIAG_BC_NOP: |
| 475 | if (op->yes < 4 || op->yes > len + 4) | ||
| 476 | return -EINVAL; | ||
| 477 | break; | 473 | break; |
| 478 | default: | 474 | default: |
| 479 | return -EINVAL; | 475 | return -EINVAL; |
| 480 | } | 476 | } |
| 477 | if (op->yes < 4 || op->yes > len + 4 || op->yes & 3) | ||
| 478 | return -EINVAL; | ||
| 481 | bc += op->yes; | 479 | bc += op->yes; |
| 482 | len -= op->yes; | 480 | len -= op->yes; |
| 483 | } | 481 | } |
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index f7f9bd7ba12d..5c9b9d963918 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c | |||
| @@ -203,7 +203,8 @@ ipq_build_packet_message(struct nf_queue_entry *entry, int *errp) | |||
| 203 | else | 203 | else |
| 204 | pmsg->outdev_name[0] = '\0'; | 204 | pmsg->outdev_name[0] = '\0'; |
| 205 | 205 | ||
| 206 | if (entry->indev && entry->skb->dev) { | 206 | if (entry->indev && entry->skb->dev && |
| 207 | entry->skb->mac_header != entry->skb->network_header) { | ||
| 207 | pmsg->hw_type = entry->skb->dev->type; | 208 | pmsg->hw_type = entry->skb->dev->type; |
| 208 | pmsg->hw_addrlen = dev_parse_header(entry->skb, | 209 | pmsg->hw_addrlen = dev_parse_header(entry->skb, |
| 209 | pmsg->hw_addr); | 210 | pmsg->hw_addr); |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 764743843503..24e556e83a3b 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
| @@ -566,7 +566,7 @@ check_entry(const struct ipt_entry *e, const char *name) | |||
| 566 | const struct xt_entry_target *t; | 566 | const struct xt_entry_target *t; |
| 567 | 567 | ||
| 568 | if (!ip_checkentry(&e->ip)) { | 568 | if (!ip_checkentry(&e->ip)) { |
| 569 | duprintf("ip check failed %p %s.\n", e, par->match->name); | 569 | duprintf("ip check failed %p %s.\n", e, name); |
| 570 | return -EINVAL; | 570 | return -EINVAL; |
| 571 | } | 571 | } |
| 572 | 572 | ||
diff --git a/net/ipv4/netfilter/ipt_ecn.c b/net/ipv4/netfilter/ipt_ecn.c index af6e9c778345..2b57e52c746c 100644 --- a/net/ipv4/netfilter/ipt_ecn.c +++ b/net/ipv4/netfilter/ipt_ecn.c | |||
| @@ -25,7 +25,8 @@ MODULE_LICENSE("GPL"); | |||
| 25 | static inline bool match_ip(const struct sk_buff *skb, | 25 | static inline bool match_ip(const struct sk_buff *skb, |
| 26 | const struct ipt_ecn_info *einfo) | 26 | const struct ipt_ecn_info *einfo) |
| 27 | { | 27 | { |
| 28 | return (ip_hdr(skb)->tos & IPT_ECN_IP_MASK) == einfo->ip_ect; | 28 | return ((ip_hdr(skb)->tos & IPT_ECN_IP_MASK) == einfo->ip_ect) ^ |
| 29 | !!(einfo->invert & IPT_ECN_OP_MATCH_IP); | ||
| 29 | } | 30 | } |
| 30 | 31 | ||
| 31 | static inline bool match_tcp(const struct sk_buff *skb, | 32 | static inline bool match_tcp(const struct sk_buff *skb, |
| @@ -76,8 +77,6 @@ static bool ecn_mt(const struct sk_buff *skb, struct xt_action_param *par) | |||
| 76 | return false; | 77 | return false; |
| 77 | 78 | ||
| 78 | if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR)) { | 79 | if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR)) { |
| 79 | if (ip_hdr(skb)->protocol != IPPROTO_TCP) | ||
| 80 | return false; | ||
| 81 | if (!match_tcp(skb, info, &par->hotdrop)) | 80 | if (!match_tcp(skb, info, &par->hotdrop)) |
| 82 | return false; | 81 | return false; |
| 83 | } | 82 | } |
| @@ -97,7 +96,7 @@ static int ecn_mt_check(const struct xt_mtchk_param *par) | |||
| 97 | return -EINVAL; | 96 | return -EINVAL; |
| 98 | 97 | ||
| 99 | if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR) && | 98 | if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR) && |
| 100 | ip->proto != IPPROTO_TCP) { | 99 | (ip->proto != IPPROTO_TCP || ip->invflags & IPT_INV_PROTO)) { |
| 101 | pr_info("cannot match TCP bits in rule for non-tcp packets\n"); | 100 | pr_info("cannot match TCP bits in rule for non-tcp packets\n"); |
| 102 | return -EINVAL; | 101 | return -EINVAL; |
| 103 | } | 102 | } |
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index db10075dd88e..de9da21113a1 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | |||
| @@ -121,7 +121,9 @@ static unsigned int ipv4_confirm(unsigned int hooknum, | |||
| 121 | return ret; | 121 | return ret; |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)) { | 124 | /* adjust seqs for loopback traffic only in outgoing direction */ |
| 125 | if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status) && | ||
| 126 | !nf_is_loopback_packet(skb)) { | ||
| 125 | typeof(nf_nat_seq_adjust_hook) seq_adjust; | 127 | typeof(nf_nat_seq_adjust_hook) seq_adjust; |
| 126 | 128 | ||
| 127 | seq_adjust = rcu_dereference(nf_nat_seq_adjust_hook); | 129 | seq_adjust = rcu_dereference(nf_nat_seq_adjust_hook); |
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index 9aaa67165f42..39b403f854c6 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c | |||
| @@ -41,7 +41,6 @@ | |||
| 41 | #include <linux/proc_fs.h> | 41 | #include <linux/proc_fs.h> |
| 42 | #include <net/sock.h> | 42 | #include <net/sock.h> |
| 43 | #include <net/ping.h> | 43 | #include <net/ping.h> |
| 44 | #include <net/icmp.h> | ||
| 45 | #include <net/udp.h> | 44 | #include <net/udp.h> |
| 46 | #include <net/route.h> | 45 | #include <net/route.h> |
| 47 | #include <net/inet_common.h> | 46 | #include <net/inet_common.h> |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 045f0ec6a4a0..aa13ef105110 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
| @@ -1902,9 +1902,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
| 1902 | 1902 | ||
| 1903 | hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev))); | 1903 | hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev))); |
| 1904 | rth = rt_intern_hash(hash, rth, skb, dev->ifindex); | 1904 | rth = rt_intern_hash(hash, rth, skb, dev->ifindex); |
| 1905 | err = 0; | 1905 | return IS_ERR(rth) ? PTR_ERR(rth) : 0; |
| 1906 | if (IS_ERR(rth)) | ||
| 1907 | err = PTR_ERR(rth); | ||
| 1908 | 1906 | ||
| 1909 | e_nobufs: | 1907 | e_nobufs: |
| 1910 | return -ENOBUFS; | 1908 | return -ENOBUFS; |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index a7d6671e33b8..708dc203b034 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
| @@ -1589,6 +1589,7 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb) | |||
| 1589 | goto discard; | 1589 | goto discard; |
| 1590 | 1590 | ||
| 1591 | if (nsk != sk) { | 1591 | if (nsk != sk) { |
| 1592 | sock_rps_save_rxhash(nsk, skb->rxhash); | ||
| 1592 | if (tcp_child_process(sk, nsk, skb)) { | 1593 | if (tcp_child_process(sk, nsk, skb)) { |
| 1593 | rsk = nsk; | 1594 | rsk = nsk; |
| 1594 | goto reset; | 1595 | goto reset; |
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c index 065fe405fb58..249394863284 100644 --- a/net/ipv6/netfilter/ip6_queue.c +++ b/net/ipv6/netfilter/ip6_queue.c | |||
| @@ -204,7 +204,8 @@ ipq_build_packet_message(struct nf_queue_entry *entry, int *errp) | |||
| 204 | else | 204 | else |
| 205 | pmsg->outdev_name[0] = '\0'; | 205 | pmsg->outdev_name[0] = '\0'; |
| 206 | 206 | ||
| 207 | if (entry->indev && entry->skb->dev) { | 207 | if (entry->indev && entry->skb->dev && |
| 208 | entry->skb->mac_header != entry->skb->network_header) { | ||
| 208 | pmsg->hw_type = entry->skb->dev->type; | 209 | pmsg->hw_type = entry->skb->dev->type; |
| 209 | pmsg->hw_addrlen = dev_parse_header(entry->skb, pmsg->hw_addr); | 210 | pmsg->hw_addrlen = dev_parse_header(entry->skb, pmsg->hw_addr); |
| 210 | } | 211 | } |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index d1fd28711ba5..87551ca568cd 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
| @@ -1644,6 +1644,7 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) | |||
| 1644 | * the new socket.. | 1644 | * the new socket.. |
| 1645 | */ | 1645 | */ |
| 1646 | if(nsk != sk) { | 1646 | if(nsk != sk) { |
| 1647 | sock_rps_save_rxhash(nsk, skb->rxhash); | ||
| 1647 | if (tcp_child_process(sk, nsk, skb)) | 1648 | if (tcp_child_process(sk, nsk, skb)) |
| 1648 | goto reset; | 1649 | goto reset; |
| 1649 | if (opt_skb) | 1650 | if (opt_skb) |
diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c index bf28ac2fc99b..782db275ac53 100644 --- a/net/netfilter/ipvs/ip_vs_conn.c +++ b/net/netfilter/ipvs/ip_vs_conn.c | |||
| @@ -776,8 +776,16 @@ static void ip_vs_conn_expire(unsigned long data) | |||
| 776 | if (cp->control) | 776 | if (cp->control) |
| 777 | ip_vs_control_del(cp); | 777 | ip_vs_control_del(cp); |
| 778 | 778 | ||
| 779 | if (cp->flags & IP_VS_CONN_F_NFCT) | 779 | if (cp->flags & IP_VS_CONN_F_NFCT) { |
| 780 | ip_vs_conn_drop_conntrack(cp); | 780 | ip_vs_conn_drop_conntrack(cp); |
| 781 | /* Do not access conntracks during subsys cleanup | ||
| 782 | * because nf_conntrack_find_get can not be used after | ||
| 783 | * conntrack cleanup for the net. | ||
| 784 | */ | ||
| 785 | smp_rmb(); | ||
| 786 | if (ipvs->enable) | ||
| 787 | ip_vs_conn_drop_conntrack(cp); | ||
| 788 | } | ||
| 781 | 789 | ||
| 782 | ip_vs_pe_put(cp->pe); | 790 | ip_vs_pe_put(cp->pe); |
| 783 | kfree(cp->pe_data); | 791 | kfree(cp->pe_data); |
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index 55af2242bccd..24c28d238dcb 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c | |||
| @@ -1945,6 +1945,7 @@ static void __net_exit __ip_vs_dev_cleanup(struct net *net) | |||
| 1945 | { | 1945 | { |
| 1946 | EnterFunction(2); | 1946 | EnterFunction(2); |
| 1947 | net_ipvs(net)->enable = 0; /* Disable packet reception */ | 1947 | net_ipvs(net)->enable = 0; /* Disable packet reception */ |
| 1948 | smp_wmb(); | ||
| 1948 | __ip_vs_sync_cleanup(net); | 1949 | __ip_vs_sync_cleanup(net); |
| 1949 | LeaveFunction(2); | 1950 | LeaveFunction(2); |
| 1950 | } | 1951 | } |
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index e0ee010935e7..2e7ccbb43ddb 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c | |||
| @@ -456,7 +456,8 @@ __build_packet_message(struct nfulnl_instance *inst, | |||
| 456 | if (skb->mark) | 456 | if (skb->mark) |
| 457 | NLA_PUT_BE32(inst->skb, NFULA_MARK, htonl(skb->mark)); | 457 | NLA_PUT_BE32(inst->skb, NFULA_MARK, htonl(skb->mark)); |
| 458 | 458 | ||
| 459 | if (indev && skb->dev) { | 459 | if (indev && skb->dev && |
| 460 | skb->mac_header != skb->network_header) { | ||
| 460 | struct nfulnl_msg_packet_hw phw; | 461 | struct nfulnl_msg_packet_hw phw; |
| 461 | int len = dev_parse_header(skb, phw.hw_addr); | 462 | int len = dev_parse_header(skb, phw.hw_addr); |
| 462 | if (len > 0) { | 463 | if (len > 0) { |
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index b83123f12b42..fdd2fafe0a14 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c | |||
| @@ -335,7 +335,8 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, | |||
| 335 | if (entskb->mark) | 335 | if (entskb->mark) |
| 336 | NLA_PUT_BE32(skb, NFQA_MARK, htonl(entskb->mark)); | 336 | NLA_PUT_BE32(skb, NFQA_MARK, htonl(entskb->mark)); |
| 337 | 337 | ||
| 338 | if (indev && entskb->dev) { | 338 | if (indev && entskb->dev && |
| 339 | entskb->mac_header != entskb->network_header) { | ||
| 339 | struct nfqnl_msg_packet_hw phw; | 340 | struct nfqnl_msg_packet_hw phw; |
| 340 | int len = dev_parse_header(entskb, phw.hw_addr); | 341 | int len = dev_parse_header(entskb, phw.hw_addr); |
| 341 | if (len) { | 342 | if (len) { |
