diff options
Diffstat (limited to 'drivers/net')
23 files changed, 211 insertions, 57 deletions
diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c index 824108cd9fd5..12430be6448a 100644 --- a/drivers/net/can/c_can/c_can_platform.c +++ b/drivers/net/can/c_can/c_can_platform.c | |||
| @@ -287,7 +287,8 @@ static int c_can_plat_probe(struct platform_device *pdev) | |||
| 287 | break; | 287 | break; |
| 288 | } | 288 | } |
| 289 | 289 | ||
| 290 | priv->raminit_ctrlreg = devm_ioremap_resource(&pdev->dev, res); | 290 | priv->raminit_ctrlreg = devm_ioremap(&pdev->dev, res->start, |
| 291 | resource_size(res)); | ||
| 291 | if (IS_ERR(priv->raminit_ctrlreg) || priv->instance < 0) | 292 | if (IS_ERR(priv->raminit_ctrlreg) || priv->instance < 0) |
| 292 | dev_info(&pdev->dev, "control memory is not used for raminit\n"); | 293 | dev_info(&pdev->dev, "control memory is not used for raminit\n"); |
| 293 | else | 294 | else |
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-main.c b/drivers/net/ethernet/amd/xgbe/xgbe-main.c index c83584a26713..5a1891faba8a 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-main.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-main.c | |||
| @@ -339,7 +339,8 @@ static int xgbe_probe(struct platform_device *pdev) | |||
| 339 | /* Calculate the number of Tx and Rx rings to be created */ | 339 | /* Calculate the number of Tx and Rx rings to be created */ |
| 340 | pdata->tx_ring_count = min_t(unsigned int, num_online_cpus(), | 340 | pdata->tx_ring_count = min_t(unsigned int, num_online_cpus(), |
| 341 | pdata->hw_feat.tx_ch_cnt); | 341 | pdata->hw_feat.tx_ch_cnt); |
| 342 | if (netif_set_real_num_tx_queues(netdev, pdata->tx_ring_count)) { | 342 | ret = netif_set_real_num_tx_queues(netdev, pdata->tx_ring_count); |
| 343 | if (ret) { | ||
| 343 | dev_err(dev, "error setting real tx queue count\n"); | 344 | dev_err(dev, "error setting real tx queue count\n"); |
| 344 | goto err_io; | 345 | goto err_io; |
| 345 | } | 346 | } |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 4cab09d3f807..8206a293e6b4 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | |||
| @@ -346,6 +346,7 @@ struct sw_tx_bd { | |||
| 346 | u8 flags; | 346 | u8 flags; |
| 347 | /* Set on the first BD descriptor when there is a split BD */ | 347 | /* Set on the first BD descriptor when there is a split BD */ |
| 348 | #define BNX2X_TSO_SPLIT_BD (1<<0) | 348 | #define BNX2X_TSO_SPLIT_BD (1<<0) |
| 349 | #define BNX2X_HAS_SECOND_PBD (1<<1) | ||
| 349 | }; | 350 | }; |
| 350 | 351 | ||
| 351 | struct sw_rx_page { | 352 | struct sw_rx_page { |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 4b875da1c7ed..c43e7238de21 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | |||
| @@ -227,6 +227,12 @@ static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata, | |||
| 227 | --nbd; | 227 | --nbd; |
| 228 | bd_idx = TX_BD(NEXT_TX_IDX(bd_idx)); | 228 | bd_idx = TX_BD(NEXT_TX_IDX(bd_idx)); |
| 229 | 229 | ||
| 230 | if (tx_buf->flags & BNX2X_HAS_SECOND_PBD) { | ||
| 231 | /* Skip second parse bd... */ | ||
| 232 | --nbd; | ||
| 233 | bd_idx = TX_BD(NEXT_TX_IDX(bd_idx)); | ||
| 234 | } | ||
| 235 | |||
| 230 | /* TSO headers+data bds share a common mapping. See bnx2x_tx_split() */ | 236 | /* TSO headers+data bds share a common mapping. See bnx2x_tx_split() */ |
| 231 | if (tx_buf->flags & BNX2X_TSO_SPLIT_BD) { | 237 | if (tx_buf->flags & BNX2X_TSO_SPLIT_BD) { |
| 232 | tx_data_bd = &txdata->tx_desc_ring[bd_idx].reg_bd; | 238 | tx_data_bd = &txdata->tx_desc_ring[bd_idx].reg_bd; |
| @@ -3889,6 +3895,9 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 3889 | /* set encapsulation flag in start BD */ | 3895 | /* set encapsulation flag in start BD */ |
| 3890 | SET_FLAG(tx_start_bd->general_data, | 3896 | SET_FLAG(tx_start_bd->general_data, |
| 3891 | ETH_TX_START_BD_TUNNEL_EXIST, 1); | 3897 | ETH_TX_START_BD_TUNNEL_EXIST, 1); |
| 3898 | |||
| 3899 | tx_buf->flags |= BNX2X_HAS_SECOND_PBD; | ||
| 3900 | |||
| 3892 | nbd++; | 3901 | nbd++; |
| 3893 | } else if (xmit_type & XMIT_CSUM) { | 3902 | } else if (xmit_type & XMIT_CSUM) { |
| 3894 | /* Set PBD in checksum offload case w/o encapsulation */ | 3903 | /* Set PBD in checksum offload case w/o encapsulation */ |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index bd0600cf7266..25eddd90f482 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | |||
| @@ -379,6 +379,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
| 379 | break; | 379 | break; |
| 380 | case PORT_FIBRE: | 380 | case PORT_FIBRE: |
| 381 | case PORT_DA: | 381 | case PORT_DA: |
| 382 | case PORT_NONE: | ||
| 382 | if (!(bp->port.supported[0] & SUPPORTED_FIBRE || | 383 | if (!(bp->port.supported[0] & SUPPORTED_FIBRE || |
| 383 | bp->port.supported[1] & SUPPORTED_FIBRE)) { | 384 | bp->port.supported[1] & SUPPORTED_FIBRE)) { |
| 384 | DP(BNX2X_MSG_ETHTOOL, | 385 | DP(BNX2X_MSG_ETHTOOL, |
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 16281ad2da12..4e615debe472 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c | |||
| @@ -1149,6 +1149,11 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 1149 | goto out; | 1149 | goto out; |
| 1150 | } | 1150 | } |
| 1151 | 1151 | ||
| 1152 | if (skb_padto(skb, ETH_ZLEN)) { | ||
| 1153 | ret = NETDEV_TX_OK; | ||
| 1154 | goto out; | ||
| 1155 | } | ||
| 1156 | |||
| 1152 | /* set the SKB transmit checksum */ | 1157 | /* set the SKB transmit checksum */ |
| 1153 | if (priv->desc_64b_en) { | 1158 | if (priv->desc_64b_en) { |
| 1154 | ret = bcmgenet_put_tx_csum(dev, skb); | 1159 | ret = bcmgenet_put_tx_csum(dev, skb); |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_cq.c b/drivers/net/ethernet/mellanox/mlx4/en_cq.c index 14c00048bbec..82322b1c8411 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_cq.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_cq.c | |||
| @@ -129,14 +129,15 @@ int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq, | |||
| 129 | name); | 129 | name); |
| 130 | } | 130 | } |
| 131 | 131 | ||
| 132 | cq->irq_desc = | ||
| 133 | irq_to_desc(mlx4_eq_get_irq(mdev->dev, | ||
| 134 | cq->vector)); | ||
| 135 | } | 132 | } |
| 136 | } else { | 133 | } else { |
| 137 | cq->vector = (cq->ring + 1 + priv->port) % | 134 | cq->vector = (cq->ring + 1 + priv->port) % |
| 138 | mdev->dev->caps.num_comp_vectors; | 135 | mdev->dev->caps.num_comp_vectors; |
| 139 | } | 136 | } |
| 137 | |||
| 138 | cq->irq_desc = | ||
| 139 | irq_to_desc(mlx4_eq_get_irq(mdev->dev, | ||
| 140 | cq->vector)); | ||
| 140 | } else { | 141 | } else { |
| 141 | /* For TX we use the same irq per | 142 | /* For TX we use the same irq per |
| 142 | ring we assigned for the RX */ | 143 | ring we assigned for the RX */ |
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 06bdc31a828d..61623e9af574 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c | |||
| @@ -4240,6 +4240,8 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp) | |||
| 4240 | RTL_W32(RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST); | 4240 | RTL_W32(RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST); |
| 4241 | break; | 4241 | break; |
| 4242 | case RTL_GIGA_MAC_VER_40: | 4242 | case RTL_GIGA_MAC_VER_40: |
| 4243 | RTL_W32(RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST | RX_EARLY_OFF); | ||
| 4244 | break; | ||
| 4243 | case RTL_GIGA_MAC_VER_41: | 4245 | case RTL_GIGA_MAC_VER_41: |
| 4244 | case RTL_GIGA_MAC_VER_42: | 4246 | case RTL_GIGA_MAC_VER_42: |
| 4245 | case RTL_GIGA_MAC_VER_43: | 4247 | case RTL_GIGA_MAC_VER_43: |
diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c index 1c24a8f368bd..d813bfb1a847 100644 --- a/drivers/net/ethernet/sun/sunvnet.c +++ b/drivers/net/ethernet/sun/sunvnet.c | |||
| @@ -610,6 +610,13 @@ static int __vnet_tx_trigger(struct vnet_port *port) | |||
| 610 | return err; | 610 | return err; |
| 611 | } | 611 | } |
| 612 | 612 | ||
| 613 | static inline bool port_is_up(struct vnet_port *vnet) | ||
| 614 | { | ||
| 615 | struct vio_driver_state *vio = &vnet->vio; | ||
| 616 | |||
| 617 | return !!(vio->hs_state & VIO_HS_COMPLETE); | ||
| 618 | } | ||
| 619 | |||
| 613 | struct vnet_port *__tx_port_find(struct vnet *vp, struct sk_buff *skb) | 620 | struct vnet_port *__tx_port_find(struct vnet *vp, struct sk_buff *skb) |
| 614 | { | 621 | { |
| 615 | unsigned int hash = vnet_hashfn(skb->data); | 622 | unsigned int hash = vnet_hashfn(skb->data); |
| @@ -617,14 +624,19 @@ struct vnet_port *__tx_port_find(struct vnet *vp, struct sk_buff *skb) | |||
| 617 | struct vnet_port *port; | 624 | struct vnet_port *port; |
| 618 | 625 | ||
| 619 | hlist_for_each_entry(port, hp, hash) { | 626 | hlist_for_each_entry(port, hp, hash) { |
| 627 | if (!port_is_up(port)) | ||
| 628 | continue; | ||
| 620 | if (ether_addr_equal(port->raddr, skb->data)) | 629 | if (ether_addr_equal(port->raddr, skb->data)) |
| 621 | return port; | 630 | return port; |
| 622 | } | 631 | } |
| 623 | port = NULL; | 632 | list_for_each_entry(port, &vp->port_list, list) { |
| 624 | if (!list_empty(&vp->port_list)) | 633 | if (!port->switch_port) |
| 625 | port = list_entry(vp->port_list.next, struct vnet_port, list); | 634 | continue; |
| 626 | 635 | if (!port_is_up(port)) | |
| 627 | return port; | 636 | continue; |
| 637 | return port; | ||
| 638 | } | ||
| 639 | return NULL; | ||
| 628 | } | 640 | } |
| 629 | 641 | ||
| 630 | struct vnet_port *tx_port_find(struct vnet *vp, struct sk_buff *skb) | 642 | struct vnet_port *tx_port_find(struct vnet *vp, struct sk_buff *skb) |
| @@ -1083,6 +1095,24 @@ static struct vnet *vnet_find_or_create(const u64 *local_mac) | |||
| 1083 | return vp; | 1095 | return vp; |
| 1084 | } | 1096 | } |
| 1085 | 1097 | ||
| 1098 | static void vnet_cleanup(void) | ||
| 1099 | { | ||
| 1100 | struct vnet *vp; | ||
| 1101 | struct net_device *dev; | ||
| 1102 | |||
| 1103 | mutex_lock(&vnet_list_mutex); | ||
| 1104 | while (!list_empty(&vnet_list)) { | ||
| 1105 | vp = list_first_entry(&vnet_list, struct vnet, list); | ||
| 1106 | list_del(&vp->list); | ||
| 1107 | dev = vp->dev; | ||
| 1108 | /* vio_unregister_driver() should have cleaned up port_list */ | ||
| 1109 | BUG_ON(!list_empty(&vp->port_list)); | ||
| 1110 | unregister_netdev(dev); | ||
| 1111 | free_netdev(dev); | ||
| 1112 | } | ||
| 1113 | mutex_unlock(&vnet_list_mutex); | ||
| 1114 | } | ||
| 1115 | |||
| 1086 | static const char *local_mac_prop = "local-mac-address"; | 1116 | static const char *local_mac_prop = "local-mac-address"; |
| 1087 | 1117 | ||
| 1088 | static struct vnet *vnet_find_parent(struct mdesc_handle *hp, | 1118 | static struct vnet *vnet_find_parent(struct mdesc_handle *hp, |
| @@ -1240,7 +1270,6 @@ static int vnet_port_remove(struct vio_dev *vdev) | |||
| 1240 | 1270 | ||
| 1241 | kfree(port); | 1271 | kfree(port); |
| 1242 | 1272 | ||
| 1243 | unregister_netdev(vp->dev); | ||
| 1244 | } | 1273 | } |
| 1245 | return 0; | 1274 | return 0; |
| 1246 | } | 1275 | } |
| @@ -1268,6 +1297,7 @@ static int __init vnet_init(void) | |||
| 1268 | static void __exit vnet_exit(void) | 1297 | static void __exit vnet_exit(void) |
| 1269 | { | 1298 | { |
| 1270 | vio_unregister_driver(&vnet_port_driver); | 1299 | vio_unregister_driver(&vnet_port_driver); |
| 1300 | vnet_cleanup(); | ||
| 1271 | } | 1301 | } |
| 1272 | 1302 | ||
| 1273 | module_init(vnet_init); | 1303 | module_init(vnet_init); |
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index 4ed38eaecea8..d97d5f39a04e 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c | |||
| @@ -378,8 +378,10 @@ static int netvsc_init_buf(struct hv_device *device) | |||
| 378 | 378 | ||
| 379 | net_device->send_section_map = | 379 | net_device->send_section_map = |
| 380 | kzalloc(net_device->map_words * sizeof(ulong), GFP_KERNEL); | 380 | kzalloc(net_device->map_words * sizeof(ulong), GFP_KERNEL); |
| 381 | if (net_device->send_section_map == NULL) | 381 | if (net_device->send_section_map == NULL) { |
| 382 | ret = -ENOMEM; | ||
| 382 | goto cleanup; | 383 | goto cleanup; |
| 384 | } | ||
| 383 | 385 | ||
| 384 | goto exit; | 386 | goto exit; |
| 385 | 387 | ||
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 4eaadcfcb0fe..203651ebccb0 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c | |||
| @@ -255,6 +255,7 @@ int mdiobus_register(struct mii_bus *bus) | |||
| 255 | 255 | ||
| 256 | bus->dev.parent = bus->parent; | 256 | bus->dev.parent = bus->parent; |
| 257 | bus->dev.class = &mdio_bus_class; | 257 | bus->dev.class = &mdio_bus_class; |
| 258 | bus->dev.driver = bus->parent->driver; | ||
| 258 | bus->dev.groups = NULL; | 259 | bus->dev.groups = NULL; |
| 259 | dev_set_name(&bus->dev, "%s", bus->id); | 260 | dev_set_name(&bus->dev, "%s", bus->id); |
| 260 | 261 | ||
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 35d753d22f78..22c57be4dfa0 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c | |||
| @@ -355,7 +355,7 @@ int phy_device_register(struct phy_device *phydev) | |||
| 355 | phydev->bus->phy_map[phydev->addr] = phydev; | 355 | phydev->bus->phy_map[phydev->addr] = phydev; |
| 356 | 356 | ||
| 357 | /* Run all of the fixups for this PHY */ | 357 | /* Run all of the fixups for this PHY */ |
| 358 | err = phy_init_hw(phydev); | 358 | err = phy_scan_fixups(phydev); |
| 359 | if (err) { | 359 | if (err) { |
| 360 | pr_err("PHY %d failed to initialize\n", phydev->addr); | 360 | pr_err("PHY %d failed to initialize\n", phydev->addr); |
| 361 | goto out; | 361 | goto out; |
| @@ -575,6 +575,7 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, | |||
| 575 | u32 flags, phy_interface_t interface) | 575 | u32 flags, phy_interface_t interface) |
| 576 | { | 576 | { |
| 577 | struct device *d = &phydev->dev; | 577 | struct device *d = &phydev->dev; |
| 578 | struct module *bus_module; | ||
| 578 | int err; | 579 | int err; |
| 579 | 580 | ||
| 580 | /* Assume that if there is no driver, that it doesn't | 581 | /* Assume that if there is no driver, that it doesn't |
| @@ -599,6 +600,14 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, | |||
| 599 | return -EBUSY; | 600 | return -EBUSY; |
| 600 | } | 601 | } |
| 601 | 602 | ||
| 603 | /* Increment the bus module reference count */ | ||
| 604 | bus_module = phydev->bus->dev.driver ? | ||
| 605 | phydev->bus->dev.driver->owner : NULL; | ||
| 606 | if (!try_module_get(bus_module)) { | ||
| 607 | dev_err(&dev->dev, "failed to get the bus module\n"); | ||
| 608 | return -EIO; | ||
| 609 | } | ||
| 610 | |||
| 602 | phydev->attached_dev = dev; | 611 | phydev->attached_dev = dev; |
| 603 | dev->phydev = phydev; | 612 | dev->phydev = phydev; |
| 604 | 613 | ||
| @@ -664,6 +673,10 @@ EXPORT_SYMBOL(phy_attach); | |||
| 664 | void phy_detach(struct phy_device *phydev) | 673 | void phy_detach(struct phy_device *phydev) |
| 665 | { | 674 | { |
| 666 | int i; | 675 | int i; |
| 676 | |||
| 677 | if (phydev->bus->dev.driver) | ||
| 678 | module_put(phydev->bus->dev.driver->owner); | ||
| 679 | |||
| 667 | phydev->attached_dev->phydev = NULL; | 680 | phydev->attached_dev->phydev = NULL; |
| 668 | phydev->attached_dev = NULL; | 681 | phydev->attached_dev = NULL; |
| 669 | phy_suspend(phydev); | 682 | phy_suspend(phydev); |
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index e2f20f807de8..d5b77ef3a210 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c | |||
| @@ -757,10 +757,15 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
| 757 | }; | 757 | }; |
| 758 | 758 | ||
| 759 | ppp_lock(ppp); | 759 | ppp_lock(ppp); |
| 760 | if (ppp->pass_filter) | 760 | if (ppp->pass_filter) { |
| 761 | sk_unattached_filter_destroy(ppp->pass_filter); | 761 | sk_unattached_filter_destroy(ppp->pass_filter); |
| 762 | err = sk_unattached_filter_create(&ppp->pass_filter, | 762 | ppp->pass_filter = NULL; |
| 763 | &fprog); | 763 | } |
| 764 | if (fprog.filter != NULL) | ||
| 765 | err = sk_unattached_filter_create(&ppp->pass_filter, | ||
| 766 | &fprog); | ||
| 767 | else | ||
| 768 | err = 0; | ||
| 764 | kfree(code); | 769 | kfree(code); |
| 765 | ppp_unlock(ppp); | 770 | ppp_unlock(ppp); |
| 766 | } | 771 | } |
| @@ -778,10 +783,15 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
| 778 | }; | 783 | }; |
| 779 | 784 | ||
| 780 | ppp_lock(ppp); | 785 | ppp_lock(ppp); |
| 781 | if (ppp->active_filter) | 786 | if (ppp->active_filter) { |
| 782 | sk_unattached_filter_destroy(ppp->active_filter); | 787 | sk_unattached_filter_destroy(ppp->active_filter); |
| 783 | err = sk_unattached_filter_create(&ppp->active_filter, | 788 | ppp->active_filter = NULL; |
| 784 | &fprog); | 789 | } |
| 790 | if (fprog.filter != NULL) | ||
| 791 | err = sk_unattached_filter_create(&ppp->active_filter, | ||
| 792 | &fprog); | ||
| 793 | else | ||
| 794 | err = 0; | ||
| 785 | kfree(code); | 795 | kfree(code); |
| 786 | ppp_unlock(ppp); | 796 | ppp_unlock(ppp); |
| 787 | } | 797 | } |
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 9ea4bfe5d318..2a32d9167d3b 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c | |||
| @@ -341,6 +341,22 @@ next_desc: | |||
| 341 | usb_driver_release_interface(driver, info->data); | 341 | usb_driver_release_interface(driver, info->data); |
| 342 | return -ENODEV; | 342 | return -ENODEV; |
| 343 | } | 343 | } |
| 344 | |||
| 345 | /* Some devices don't initialise properly. In particular | ||
| 346 | * the packet filter is not reset. There are devices that | ||
| 347 | * don't do reset all the way. So the packet filter should | ||
| 348 | * be set to a sane initial value. | ||
| 349 | */ | ||
| 350 | usb_control_msg(dev->udev, | ||
| 351 | usb_sndctrlpipe(dev->udev, 0), | ||
| 352 | USB_CDC_SET_ETHERNET_PACKET_FILTER, | ||
| 353 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | ||
| 354 | USB_CDC_PACKET_TYPE_ALL_MULTICAST | USB_CDC_PACKET_TYPE_DIRECTED | USB_CDC_PACKET_TYPE_BROADCAST, | ||
| 355 | intf->cur_altsetting->desc.bInterfaceNumber, | ||
| 356 | NULL, | ||
| 357 | 0, | ||
| 358 | USB_CTRL_SET_TIMEOUT | ||
| 359 | ); | ||
| 344 | return 0; | 360 | return 0; |
| 345 | 361 | ||
| 346 | bad_desc: | 362 | bad_desc: |
diff --git a/drivers/net/usb/huawei_cdc_ncm.c b/drivers/net/usb/huawei_cdc_ncm.c index 5d95a13dbe2a..735f7dadb9a0 100644 --- a/drivers/net/usb/huawei_cdc_ncm.c +++ b/drivers/net/usb/huawei_cdc_ncm.c | |||
| @@ -194,6 +194,9 @@ static const struct usb_device_id huawei_cdc_ncm_devs[] = { | |||
| 194 | { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x76), | 194 | { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x76), |
| 195 | .driver_info = (unsigned long)&huawei_cdc_ncm_info, | 195 | .driver_info = (unsigned long)&huawei_cdc_ncm_info, |
| 196 | }, | 196 | }, |
| 197 | { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x03, 0x16), | ||
| 198 | .driver_info = (unsigned long)&huawei_cdc_ncm_info, | ||
| 199 | }, | ||
| 197 | 200 | ||
| 198 | /* Terminating entry */ | 201 | /* Terminating entry */ |
| 199 | { | 202 | { |
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index c4638c67f6b9..22756db53dca 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c | |||
| @@ -667,6 +667,7 @@ static const struct usb_device_id products[] = { | |||
| 667 | {QMI_FIXED_INTF(0x05c6, 0x9084, 4)}, | 667 | {QMI_FIXED_INTF(0x05c6, 0x9084, 4)}, |
| 668 | {QMI_FIXED_INTF(0x05c6, 0x920d, 0)}, | 668 | {QMI_FIXED_INTF(0x05c6, 0x920d, 0)}, |
| 669 | {QMI_FIXED_INTF(0x05c6, 0x920d, 5)}, | 669 | {QMI_FIXED_INTF(0x05c6, 0x920d, 5)}, |
| 670 | {QMI_FIXED_INTF(0x0846, 0x68a2, 8)}, | ||
| 670 | {QMI_FIXED_INTF(0x12d1, 0x140c, 1)}, /* Huawei E173 */ | 671 | {QMI_FIXED_INTF(0x12d1, 0x140c, 1)}, /* Huawei E173 */ |
| 671 | {QMI_FIXED_INTF(0x12d1, 0x14ac, 1)}, /* Huawei E1820 */ | 672 | {QMI_FIXED_INTF(0x12d1, 0x14ac, 1)}, /* Huawei E1820 */ |
| 672 | {QMI_FIXED_INTF(0x16d8, 0x6003, 0)}, /* CMOTech 6003 */ | 673 | {QMI_FIXED_INTF(0x16d8, 0x6003, 0)}, /* CMOTech 6003 */ |
| @@ -757,6 +758,7 @@ static const struct usb_device_id products[] = { | |||
| 757 | {QMI_FIXED_INTF(0x1199, 0x9054, 8)}, /* Sierra Wireless Modem */ | 758 | {QMI_FIXED_INTF(0x1199, 0x9054, 8)}, /* Sierra Wireless Modem */ |
| 758 | {QMI_FIXED_INTF(0x1199, 0x9055, 8)}, /* Netgear AirCard 341U */ | 759 | {QMI_FIXED_INTF(0x1199, 0x9055, 8)}, /* Netgear AirCard 341U */ |
| 759 | {QMI_FIXED_INTF(0x1199, 0x9056, 8)}, /* Sierra Wireless Modem */ | 760 | {QMI_FIXED_INTF(0x1199, 0x9056, 8)}, /* Sierra Wireless Modem */ |
| 761 | {QMI_FIXED_INTF(0x1199, 0x9057, 8)}, | ||
| 760 | {QMI_FIXED_INTF(0x1199, 0x9061, 8)}, /* Sierra Wireless Modem */ | 762 | {QMI_FIXED_INTF(0x1199, 0x9061, 8)}, /* Sierra Wireless Modem */ |
| 761 | {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */ | 763 | {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */ |
| 762 | {QMI_FIXED_INTF(0x1bbb, 0x0203, 2)}, /* Alcatel L800MA */ | 764 | {QMI_FIXED_INTF(0x1bbb, 0x0203, 2)}, /* Alcatel L800MA */ |
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 7bad2d316637..3eab74c7c554 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c | |||
| @@ -282,7 +282,7 @@ | |||
| 282 | /* USB_DEV_STAT */ | 282 | /* USB_DEV_STAT */ |
| 283 | #define STAT_SPEED_MASK 0x0006 | 283 | #define STAT_SPEED_MASK 0x0006 |
| 284 | #define STAT_SPEED_HIGH 0x0000 | 284 | #define STAT_SPEED_HIGH 0x0000 |
| 285 | #define STAT_SPEED_FULL 0x0001 | 285 | #define STAT_SPEED_FULL 0x0002 |
| 286 | 286 | ||
| 287 | /* USB_TX_AGG */ | 287 | /* USB_TX_AGG */ |
| 288 | #define TX_AGG_MAX_THRESHOLD 0x03 | 288 | #define TX_AGG_MAX_THRESHOLD 0x03 |
| @@ -2292,9 +2292,8 @@ static void r8152b_exit_oob(struct r8152 *tp) | |||
| 2292 | /* rx share fifo credit full threshold */ | 2292 | /* rx share fifo credit full threshold */ |
| 2293 | ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL0, RXFIFO_THR1_NORMAL); | 2293 | ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL0, RXFIFO_THR1_NORMAL); |
| 2294 | 2294 | ||
| 2295 | ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_DEV_STAT); | 2295 | if (tp->udev->speed == USB_SPEED_FULL || |
| 2296 | ocp_data &= STAT_SPEED_MASK; | 2296 | tp->udev->speed == USB_SPEED_LOW) { |
| 2297 | if (ocp_data == STAT_SPEED_FULL) { | ||
| 2298 | /* rx share fifo credit near full threshold */ | 2297 | /* rx share fifo credit near full threshold */ |
| 2299 | ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL1, | 2298 | ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL1, |
| 2300 | RXFIFO_THR2_FULL); | 2299 | RXFIFO_THR2_FULL); |
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index ade33ef82823..9f79192c9aa0 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c | |||
| @@ -339,7 +339,7 @@ static int vxlan_fdb_info(struct sk_buff *skb, struct vxlan_dev *vxlan, | |||
| 339 | ndm->ndm_state = fdb->state; | 339 | ndm->ndm_state = fdb->state; |
| 340 | ndm->ndm_ifindex = vxlan->dev->ifindex; | 340 | ndm->ndm_ifindex = vxlan->dev->ifindex; |
| 341 | ndm->ndm_flags = fdb->flags; | 341 | ndm->ndm_flags = fdb->flags; |
| 342 | ndm->ndm_type = NDA_DST; | 342 | ndm->ndm_type = RTN_UNICAST; |
| 343 | 343 | ||
| 344 | if (send_eth && nla_put(skb, NDA_LLADDR, ETH_ALEN, &fdb->eth_addr)) | 344 | if (send_eth && nla_put(skb, NDA_LLADDR, ETH_ALEN, &fdb->eth_addr)) |
| 345 | goto nla_put_failure; | 345 | goto nla_put_failure; |
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c index 5895f1978691..fa9fdfa128c1 100644 --- a/drivers/net/wan/x25_asy.c +++ b/drivers/net/wan/x25_asy.c | |||
| @@ -122,8 +122,12 @@ static int x25_asy_change_mtu(struct net_device *dev, int newmtu) | |||
| 122 | { | 122 | { |
| 123 | struct x25_asy *sl = netdev_priv(dev); | 123 | struct x25_asy *sl = netdev_priv(dev); |
| 124 | unsigned char *xbuff, *rbuff; | 124 | unsigned char *xbuff, *rbuff; |
| 125 | int len = 2 * newmtu; | 125 | int len; |
| 126 | 126 | ||
| 127 | if (newmtu > 65534) | ||
| 128 | return -EINVAL; | ||
| 129 | |||
| 130 | len = 2 * newmtu; | ||
| 127 | xbuff = kmalloc(len + 4, GFP_ATOMIC); | 131 | xbuff = kmalloc(len + 4, GFP_ATOMIC); |
| 128 | rbuff = kmalloc(len + 4, GFP_ATOMIC); | 132 | rbuff = kmalloc(len + 4, GFP_ATOMIC); |
| 129 | 133 | ||
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 66acb2cbd9df..7c28cb55610b 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
| @@ -887,6 +887,15 @@ ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq, | |||
| 887 | 887 | ||
| 888 | tx_info = IEEE80211_SKB_CB(skb); | 888 | tx_info = IEEE80211_SKB_CB(skb); |
| 889 | tx_info->flags &= ~IEEE80211_TX_CTL_CLEAR_PS_FILT; | 889 | tx_info->flags &= ~IEEE80211_TX_CTL_CLEAR_PS_FILT; |
| 890 | |||
| 891 | /* | ||
| 892 | * No aggregation session is running, but there may be frames | ||
| 893 | * from a previous session or a failed attempt in the queue. | ||
| 894 | * Send them out as normal data frames | ||
| 895 | */ | ||
| 896 | if (!tid->active) | ||
| 897 | tx_info->flags &= ~IEEE80211_TX_CTL_AMPDU; | ||
| 898 | |||
| 890 | if (!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) { | 899 | if (!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) { |
| 891 | bf->bf_state.bf_type = 0; | 900 | bf->bf_state.bf_type = 0; |
| 892 | return bf; | 901 | return bf; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c index 725ba49576bf..8b79081d4885 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | |||
| @@ -1072,8 +1072,12 @@ static int iwl_mvm_mac_ctxt_cmd_ap(struct iwl_mvm *mvm, | |||
| 1072 | /* Fill the common data for all mac context types */ | 1072 | /* Fill the common data for all mac context types */ |
| 1073 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); | 1073 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); |
| 1074 | 1074 | ||
| 1075 | /* Also enable probe requests to pass */ | 1075 | /* |
| 1076 | cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_PROBE_REQUEST); | 1076 | * pass probe requests and beacons from other APs (needed |
| 1077 | * for ht protection) | ||
| 1078 | */ | ||
| 1079 | cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_PROBE_REQUEST | | ||
| 1080 | MAC_FILTER_IN_BEACON); | ||
| 1077 | 1081 | ||
| 1078 | /* Fill the data specific for ap mode */ | 1082 | /* Fill the data specific for ap mode */ |
| 1079 | iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.ap, | 1083 | iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.ap, |
| @@ -1094,6 +1098,13 @@ static int iwl_mvm_mac_ctxt_cmd_go(struct iwl_mvm *mvm, | |||
| 1094 | /* Fill the common data for all mac context types */ | 1098 | /* Fill the common data for all mac context types */ |
| 1095 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); | 1099 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); |
| 1096 | 1100 | ||
| 1101 | /* | ||
| 1102 | * pass probe requests and beacons from other APs (needed | ||
| 1103 | * for ht protection) | ||
| 1104 | */ | ||
| 1105 | cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_PROBE_REQUEST | | ||
| 1106 | MAC_FILTER_IN_BEACON); | ||
| 1107 | |||
| 1097 | /* Fill the data specific for GO mode */ | 1108 | /* Fill the data specific for GO mode */ |
| 1098 | iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.go.ap, | 1109 | iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.go.ap, |
| 1099 | action == FW_CTXT_ACTION_ADD); | 1110 | action == FW_CTXT_ACTION_ADD); |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 9bfb90680cdc..98556d03c1ed 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c | |||
| @@ -303,13 +303,6 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) | |||
| 303 | hw->uapsd_max_sp_len = IWL_UAPSD_MAX_SP; | 303 | hw->uapsd_max_sp_len = IWL_UAPSD_MAX_SP; |
| 304 | } | 304 | } |
| 305 | 305 | ||
| 306 | if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT && | ||
| 307 | !iwlwifi_mod_params.uapsd_disable) { | ||
| 308 | hw->flags |= IEEE80211_HW_SUPPORTS_UAPSD; | ||
| 309 | hw->uapsd_queues = IWL_UAPSD_AC_INFO; | ||
| 310 | hw->uapsd_max_sp_len = IWL_UAPSD_MAX_SP; | ||
| 311 | } | ||
| 312 | |||
| 313 | hw->sta_data_size = sizeof(struct iwl_mvm_sta); | 306 | hw->sta_data_size = sizeof(struct iwl_mvm_sta); |
| 314 | hw->vif_data_size = sizeof(struct iwl_mvm_vif); | 307 | hw->vif_data_size = sizeof(struct iwl_mvm_vif); |
| 315 | hw->chanctx_data_size = sizeof(u16); | 308 | hw->chanctx_data_size = sizeof(u16); |
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index 1844a47636b6..c65b636bcab9 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c | |||
| @@ -1030,14 +1030,21 @@ static int xenvif_tx_check_gop(struct xenvif_queue *queue, | |||
| 1030 | { | 1030 | { |
| 1031 | struct gnttab_map_grant_ref *gop_map = *gopp_map; | 1031 | struct gnttab_map_grant_ref *gop_map = *gopp_map; |
| 1032 | u16 pending_idx = XENVIF_TX_CB(skb)->pending_idx; | 1032 | u16 pending_idx = XENVIF_TX_CB(skb)->pending_idx; |
| 1033 | /* This always points to the shinfo of the skb being checked, which | ||
| 1034 | * could be either the first or the one on the frag_list | ||
| 1035 | */ | ||
| 1033 | struct skb_shared_info *shinfo = skb_shinfo(skb); | 1036 | struct skb_shared_info *shinfo = skb_shinfo(skb); |
| 1037 | /* If this is non-NULL, we are currently checking the frag_list skb, and | ||
| 1038 | * this points to the shinfo of the first one | ||
| 1039 | */ | ||
| 1040 | struct skb_shared_info *first_shinfo = NULL; | ||
| 1034 | int nr_frags = shinfo->nr_frags; | 1041 | int nr_frags = shinfo->nr_frags; |
| 1042 | const bool sharedslot = nr_frags && | ||
| 1043 | frag_get_pending_idx(&shinfo->frags[0]) == pending_idx; | ||
| 1035 | int i, err; | 1044 | int i, err; |
| 1036 | struct sk_buff *first_skb = NULL; | ||
| 1037 | 1045 | ||
| 1038 | /* Check status of header. */ | 1046 | /* Check status of header. */ |
| 1039 | err = (*gopp_copy)->status; | 1047 | err = (*gopp_copy)->status; |
| 1040 | (*gopp_copy)++; | ||
| 1041 | if (unlikely(err)) { | 1048 | if (unlikely(err)) { |
| 1042 | if (net_ratelimit()) | 1049 | if (net_ratelimit()) |
| 1043 | netdev_dbg(queue->vif->dev, | 1050 | netdev_dbg(queue->vif->dev, |
| @@ -1045,8 +1052,12 @@ static int xenvif_tx_check_gop(struct xenvif_queue *queue, | |||
| 1045 | (*gopp_copy)->status, | 1052 | (*gopp_copy)->status, |
| 1046 | pending_idx, | 1053 | pending_idx, |
| 1047 | (*gopp_copy)->source.u.ref); | 1054 | (*gopp_copy)->source.u.ref); |
| 1048 | xenvif_idx_release(queue, pending_idx, XEN_NETIF_RSP_ERROR); | 1055 | /* The first frag might still have this slot mapped */ |
| 1056 | if (!sharedslot) | ||
| 1057 | xenvif_idx_release(queue, pending_idx, | ||
| 1058 | XEN_NETIF_RSP_ERROR); | ||
| 1049 | } | 1059 | } |
| 1060 | (*gopp_copy)++; | ||
| 1050 | 1061 | ||
| 1051 | check_frags: | 1062 | check_frags: |
| 1052 | for (i = 0; i < nr_frags; i++, gop_map++) { | 1063 | for (i = 0; i < nr_frags; i++, gop_map++) { |
| @@ -1062,8 +1073,19 @@ check_frags: | |||
| 1062 | pending_idx, | 1073 | pending_idx, |
| 1063 | gop_map->handle); | 1074 | gop_map->handle); |
| 1064 | /* Had a previous error? Invalidate this fragment. */ | 1075 | /* Had a previous error? Invalidate this fragment. */ |
| 1065 | if (unlikely(err)) | 1076 | if (unlikely(err)) { |
| 1066 | xenvif_idx_unmap(queue, pending_idx); | 1077 | xenvif_idx_unmap(queue, pending_idx); |
| 1078 | /* If the mapping of the first frag was OK, but | ||
| 1079 | * the header's copy failed, and they are | ||
| 1080 | * sharing a slot, send an error | ||
| 1081 | */ | ||
| 1082 | if (i == 0 && sharedslot) | ||
| 1083 | xenvif_idx_release(queue, pending_idx, | ||
| 1084 | XEN_NETIF_RSP_ERROR); | ||
| 1085 | else | ||
| 1086 | xenvif_idx_release(queue, pending_idx, | ||
| 1087 | XEN_NETIF_RSP_OKAY); | ||
| 1088 | } | ||
| 1067 | continue; | 1089 | continue; |
| 1068 | } | 1090 | } |
| 1069 | 1091 | ||
| @@ -1075,42 +1097,53 @@ check_frags: | |||
| 1075 | gop_map->status, | 1097 | gop_map->status, |
| 1076 | pending_idx, | 1098 | pending_idx, |
| 1077 | gop_map->ref); | 1099 | gop_map->ref); |
| 1100 | |||
| 1078 | xenvif_idx_release(queue, pending_idx, XEN_NETIF_RSP_ERROR); | 1101 | xenvif_idx_release(queue, pending_idx, XEN_NETIF_RSP_ERROR); |
| 1079 | 1102 | ||
| 1080 | /* Not the first error? Preceding frags already invalidated. */ | 1103 | /* Not the first error? Preceding frags already invalidated. */ |
| 1081 | if (err) | 1104 | if (err) |
| 1082 | continue; | 1105 | continue; |
| 1083 | /* First error: invalidate preceding fragments. */ | 1106 | |
| 1107 | /* First error: if the header haven't shared a slot with the | ||
| 1108 | * first frag, release it as well. | ||
| 1109 | */ | ||
| 1110 | if (!sharedslot) | ||
| 1111 | xenvif_idx_release(queue, | ||
| 1112 | XENVIF_TX_CB(skb)->pending_idx, | ||
| 1113 | XEN_NETIF_RSP_OKAY); | ||
| 1114 | |||
| 1115 | /* Invalidate preceding fragments of this skb. */ | ||
| 1084 | for (j = 0; j < i; j++) { | 1116 | for (j = 0; j < i; j++) { |
| 1085 | pending_idx = frag_get_pending_idx(&shinfo->frags[j]); | 1117 | pending_idx = frag_get_pending_idx(&shinfo->frags[j]); |
| 1086 | xenvif_idx_unmap(queue, pending_idx); | 1118 | xenvif_idx_unmap(queue, pending_idx); |
| 1119 | xenvif_idx_release(queue, pending_idx, | ||
| 1120 | XEN_NETIF_RSP_OKAY); | ||
| 1121 | } | ||
| 1122 | |||
| 1123 | /* And if we found the error while checking the frag_list, unmap | ||
| 1124 | * the first skb's frags | ||
| 1125 | */ | ||
| 1126 | if (first_shinfo) { | ||
| 1127 | for (j = 0; j < first_shinfo->nr_frags; j++) { | ||
| 1128 | pending_idx = frag_get_pending_idx(&first_shinfo->frags[j]); | ||
| 1129 | xenvif_idx_unmap(queue, pending_idx); | ||
| 1130 | xenvif_idx_release(queue, pending_idx, | ||
| 1131 | XEN_NETIF_RSP_OKAY); | ||
| 1132 | } | ||
| 1087 | } | 1133 | } |
| 1088 | 1134 | ||
| 1089 | /* Remember the error: invalidate all subsequent fragments. */ | 1135 | /* Remember the error: invalidate all subsequent fragments. */ |
| 1090 | err = newerr; | 1136 | err = newerr; |
| 1091 | } | 1137 | } |
| 1092 | 1138 | ||
| 1093 | if (skb_has_frag_list(skb)) { | 1139 | if (skb_has_frag_list(skb) && !first_shinfo) { |
| 1094 | first_skb = skb; | 1140 | first_shinfo = skb_shinfo(skb); |
| 1095 | skb = shinfo->frag_list; | 1141 | shinfo = skb_shinfo(skb_shinfo(skb)->frag_list); |
| 1096 | shinfo = skb_shinfo(skb); | ||
| 1097 | nr_frags = shinfo->nr_frags; | 1142 | nr_frags = shinfo->nr_frags; |
| 1098 | 1143 | ||
| 1099 | goto check_frags; | 1144 | goto check_frags; |
| 1100 | } | 1145 | } |
| 1101 | 1146 | ||
| 1102 | /* There was a mapping error in the frag_list skb. We have to unmap | ||
| 1103 | * the first skb's frags | ||
| 1104 | */ | ||
| 1105 | if (first_skb && err) { | ||
| 1106 | int j; | ||
| 1107 | shinfo = skb_shinfo(first_skb); | ||
| 1108 | for (j = 0; j < shinfo->nr_frags; j++) { | ||
| 1109 | pending_idx = frag_get_pending_idx(&shinfo->frags[j]); | ||
| 1110 | xenvif_idx_unmap(queue, pending_idx); | ||
| 1111 | } | ||
| 1112 | } | ||
| 1113 | |||
| 1114 | *gopp_map = gop_map; | 1147 | *gopp_map = gop_map; |
| 1115 | return err; | 1148 | return err; |
| 1116 | } | 1149 | } |
| @@ -1518,7 +1551,16 @@ static int xenvif_tx_submit(struct xenvif_queue *queue) | |||
| 1518 | 1551 | ||
| 1519 | /* Check the remap error code. */ | 1552 | /* Check the remap error code. */ |
| 1520 | if (unlikely(xenvif_tx_check_gop(queue, skb, &gop_map, &gop_copy))) { | 1553 | if (unlikely(xenvif_tx_check_gop(queue, skb, &gop_map, &gop_copy))) { |
| 1554 | /* If there was an error, xenvif_tx_check_gop is | ||
| 1555 | * expected to release all the frags which were mapped, | ||
| 1556 | * so kfree_skb shouldn't do it again | ||
| 1557 | */ | ||
| 1521 | skb_shinfo(skb)->nr_frags = 0; | 1558 | skb_shinfo(skb)->nr_frags = 0; |
| 1559 | if (skb_has_frag_list(skb)) { | ||
| 1560 | struct sk_buff *nskb = | ||
| 1561 | skb_shinfo(skb)->frag_list; | ||
| 1562 | skb_shinfo(nskb)->nr_frags = 0; | ||
| 1563 | } | ||
| 1522 | kfree_skb(skb); | 1564 | kfree_skb(skb); |
| 1523 | continue; | 1565 | continue; |
| 1524 | } | 1566 | } |
| @@ -1822,8 +1864,6 @@ void xenvif_idx_unmap(struct xenvif_queue *queue, u16 pending_idx) | |||
| 1822 | tx_unmap_op.status); | 1864 | tx_unmap_op.status); |
| 1823 | BUG(); | 1865 | BUG(); |
| 1824 | } | 1866 | } |
| 1825 | |||
| 1826 | xenvif_idx_release(queue, pending_idx, XEN_NETIF_RSP_OKAY); | ||
| 1827 | } | 1867 | } |
| 1828 | 1868 | ||
| 1829 | static inline int rx_work_todo(struct xenvif_queue *queue) | 1869 | static inline int rx_work_todo(struct xenvif_queue *queue) |
