diff options
69 files changed, 628 insertions, 1393 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 184c434ae305..0dceba1a2ba1 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
| @@ -1648,7 +1648,7 @@ static int __bond_release_one(struct net_device *bond_dev, | |||
| 1648 | /* slave is not a slave or master is not master of this slave */ | 1648 | /* slave is not a slave or master is not master of this slave */ |
| 1649 | if (!(slave_dev->flags & IFF_SLAVE) || | 1649 | if (!(slave_dev->flags & IFF_SLAVE) || |
| 1650 | !netdev_has_upper_dev(slave_dev, bond_dev)) { | 1650 | !netdev_has_upper_dev(slave_dev, bond_dev)) { |
| 1651 | netdev_err(bond_dev, "cannot release %s\n", | 1651 | netdev_dbg(bond_dev, "cannot release %s\n", |
| 1652 | slave_dev->name); | 1652 | slave_dev->name); |
| 1653 | return -EINVAL; | 1653 | return -EINVAL; |
| 1654 | } | 1654 | } |
diff --git a/drivers/net/caif/caif_virtio.c b/drivers/net/caif/caif_virtio.c index a5fefb9059c5..b306210b02b7 100644 --- a/drivers/net/caif/caif_virtio.c +++ b/drivers/net/caif/caif_virtio.c | |||
| @@ -257,7 +257,6 @@ static int cfv_rx_poll(struct napi_struct *napi, int quota) | |||
| 257 | struct vringh_kiov *riov = &cfv->ctx.riov; | 257 | struct vringh_kiov *riov = &cfv->ctx.riov; |
| 258 | unsigned int skb_len; | 258 | unsigned int skb_len; |
| 259 | 259 | ||
| 260 | again: | ||
| 261 | do { | 260 | do { |
| 262 | skb = NULL; | 261 | skb = NULL; |
| 263 | 262 | ||
| @@ -322,7 +321,6 @@ exit: | |||
| 322 | napi_schedule_prep(napi)) { | 321 | napi_schedule_prep(napi)) { |
| 323 | vringh_notify_disable_kern(cfv->vr_rx); | 322 | vringh_notify_disable_kern(cfv->vr_rx); |
| 324 | __napi_schedule(napi); | 323 | __napi_schedule(napi); |
| 325 | goto again; | ||
| 326 | } | 324 | } |
| 327 | break; | 325 | break; |
| 328 | 326 | ||
diff --git a/drivers/net/ethernet/8390/ne2k-pci.c b/drivers/net/ethernet/8390/ne2k-pci.c index 89c8d9fc97de..57e97910c728 100644 --- a/drivers/net/ethernet/8390/ne2k-pci.c +++ b/drivers/net/ethernet/8390/ne2k-pci.c | |||
| @@ -246,13 +246,13 @@ static int ne2k_pci_init_one(struct pci_dev *pdev, | |||
| 246 | 246 | ||
| 247 | if (!ioaddr || ((pci_resource_flags (pdev, 0) & IORESOURCE_IO) == 0)) { | 247 | if (!ioaddr || ((pci_resource_flags (pdev, 0) & IORESOURCE_IO) == 0)) { |
| 248 | dev_err(&pdev->dev, "no I/O resource at PCI BAR #0\n"); | 248 | dev_err(&pdev->dev, "no I/O resource at PCI BAR #0\n"); |
| 249 | return -ENODEV; | 249 | goto err_out; |
| 250 | } | 250 | } |
| 251 | 251 | ||
| 252 | if (request_region (ioaddr, NE_IO_EXTENT, DRV_NAME) == NULL) { | 252 | if (request_region (ioaddr, NE_IO_EXTENT, DRV_NAME) == NULL) { |
| 253 | dev_err(&pdev->dev, "I/O resource 0x%x @ 0x%lx busy\n", | 253 | dev_err(&pdev->dev, "I/O resource 0x%x @ 0x%lx busy\n", |
| 254 | NE_IO_EXTENT, ioaddr); | 254 | NE_IO_EXTENT, ioaddr); |
| 255 | return -EBUSY; | 255 | goto err_out; |
| 256 | } | 256 | } |
| 257 | 257 | ||
| 258 | reg0 = inb(ioaddr); | 258 | reg0 = inb(ioaddr); |
| @@ -392,6 +392,8 @@ err_out_free_netdev: | |||
| 392 | free_netdev (dev); | 392 | free_netdev (dev); |
| 393 | err_out_free_res: | 393 | err_out_free_res: |
| 394 | release_region (ioaddr, NE_IO_EXTENT); | 394 | release_region (ioaddr, NE_IO_EXTENT); |
| 395 | err_out: | ||
| 396 | pci_disable_device(pdev); | ||
| 395 | return -ENODEV; | 397 | return -ENODEV; |
| 396 | } | 398 | } |
| 397 | 399 | ||
diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig index df76050d0a9d..eadcb053807e 100644 --- a/drivers/net/ethernet/Kconfig +++ b/drivers/net/ethernet/Kconfig | |||
| @@ -156,18 +156,6 @@ source "drivers/net/ethernet/realtek/Kconfig" | |||
| 156 | source "drivers/net/ethernet/renesas/Kconfig" | 156 | source "drivers/net/ethernet/renesas/Kconfig" |
| 157 | source "drivers/net/ethernet/rdc/Kconfig" | 157 | source "drivers/net/ethernet/rdc/Kconfig" |
| 158 | source "drivers/net/ethernet/rocker/Kconfig" | 158 | source "drivers/net/ethernet/rocker/Kconfig" |
| 159 | |||
| 160 | config S6GMAC | ||
| 161 | tristate "S6105 GMAC ethernet support" | ||
| 162 | depends on XTENSA_VARIANT_S6000 | ||
| 163 | select PHYLIB | ||
| 164 | ---help--- | ||
| 165 | This driver supports the on chip ethernet device on the | ||
| 166 | S6105 xtensa processor. | ||
| 167 | |||
| 168 | To compile this driver as a module, choose M here. The module | ||
| 169 | will be called s6gmac. | ||
| 170 | |||
| 171 | source "drivers/net/ethernet/samsung/Kconfig" | 159 | source "drivers/net/ethernet/samsung/Kconfig" |
| 172 | source "drivers/net/ethernet/seeq/Kconfig" | 160 | source "drivers/net/ethernet/seeq/Kconfig" |
| 173 | source "drivers/net/ethernet/silan/Kconfig" | 161 | source "drivers/net/ethernet/silan/Kconfig" |
diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile index bf56f8b36e90..1367afcd0a8b 100644 --- a/drivers/net/ethernet/Makefile +++ b/drivers/net/ethernet/Makefile | |||
| @@ -66,7 +66,6 @@ obj-$(CONFIG_NET_VENDOR_REALTEK) += realtek/ | |||
| 66 | obj-$(CONFIG_SH_ETH) += renesas/ | 66 | obj-$(CONFIG_SH_ETH) += renesas/ |
| 67 | obj-$(CONFIG_NET_VENDOR_RDC) += rdc/ | 67 | obj-$(CONFIG_NET_VENDOR_RDC) += rdc/ |
| 68 | obj-$(CONFIG_NET_VENDOR_ROCKER) += rocker/ | 68 | obj-$(CONFIG_NET_VENDOR_ROCKER) += rocker/ |
| 69 | obj-$(CONFIG_S6GMAC) += s6gmac.o | ||
| 70 | obj-$(CONFIG_NET_VENDOR_SAMSUNG) += samsung/ | 69 | obj-$(CONFIG_NET_VENDOR_SAMSUNG) += samsung/ |
| 71 | obj-$(CONFIG_NET_VENDOR_SEEQ) += seeq/ | 70 | obj-$(CONFIG_NET_VENDOR_SEEQ) += seeq/ |
| 72 | obj-$(CONFIG_NET_VENDOR_SILAN) += silan/ | 71 | obj-$(CONFIG_NET_VENDOR_SILAN) += silan/ |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 9f5e38769a29..72eef9fc883e 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | |||
| @@ -12553,9 +12553,11 @@ static int bnx2x_get_phys_port_id(struct net_device *netdev, | |||
| 12553 | return 0; | 12553 | return 0; |
| 12554 | } | 12554 | } |
| 12555 | 12555 | ||
| 12556 | static bool bnx2x_gso_check(struct sk_buff *skb, struct net_device *dev) | 12556 | static netdev_features_t bnx2x_features_check(struct sk_buff *skb, |
| 12557 | struct net_device *dev, | ||
| 12558 | netdev_features_t features) | ||
| 12557 | { | 12559 | { |
| 12558 | return vxlan_gso_check(skb); | 12560 | return vxlan_features_check(skb, features); |
| 12559 | } | 12561 | } |
| 12560 | 12562 | ||
| 12561 | static const struct net_device_ops bnx2x_netdev_ops = { | 12563 | static const struct net_device_ops bnx2x_netdev_ops = { |
| @@ -12589,7 +12591,7 @@ static const struct net_device_ops bnx2x_netdev_ops = { | |||
| 12589 | #endif | 12591 | #endif |
| 12590 | .ndo_get_phys_port_id = bnx2x_get_phys_port_id, | 12592 | .ndo_get_phys_port_id = bnx2x_get_phys_port_id, |
| 12591 | .ndo_set_vf_link_state = bnx2x_set_vf_link_state, | 12593 | .ndo_set_vf_link_state = bnx2x_set_vf_link_state, |
| 12592 | .ndo_gso_check = bnx2x_gso_check, | 12594 | .ndo_features_check = bnx2x_features_check, |
| 12593 | }; | 12595 | }; |
| 12594 | 12596 | ||
| 12595 | static int bnx2x_set_coherency_mask(struct bnx2x *bp) | 12597 | static int bnx2x_set_coherency_mask(struct bnx2x *bp) |
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index bb48a610b72a..553dcd8a9df2 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
| @@ -17800,23 +17800,6 @@ static int tg3_init_one(struct pci_dev *pdev, | |||
| 17800 | goto err_out_apeunmap; | 17800 | goto err_out_apeunmap; |
| 17801 | } | 17801 | } |
| 17802 | 17802 | ||
| 17803 | /* | ||
| 17804 | * Reset chip in case UNDI or EFI driver did not shutdown | ||
| 17805 | * DMA self test will enable WDMAC and we'll see (spurious) | ||
| 17806 | * pending DMA on the PCI bus at that point. | ||
| 17807 | */ | ||
| 17808 | if ((tr32(HOSTCC_MODE) & HOSTCC_MODE_ENABLE) || | ||
| 17809 | (tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) { | ||
| 17810 | tw32(MEMARB_MODE, MEMARB_MODE_ENABLE); | ||
| 17811 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | ||
| 17812 | } | ||
| 17813 | |||
| 17814 | err = tg3_test_dma(tp); | ||
| 17815 | if (err) { | ||
| 17816 | dev_err(&pdev->dev, "DMA engine test failed, aborting\n"); | ||
| 17817 | goto err_out_apeunmap; | ||
| 17818 | } | ||
| 17819 | |||
| 17820 | intmbx = MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW; | 17803 | intmbx = MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW; |
| 17821 | rcvmbx = MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW; | 17804 | rcvmbx = MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW; |
| 17822 | sndmbx = MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW; | 17805 | sndmbx = MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW; |
| @@ -17861,6 +17844,23 @@ static int tg3_init_one(struct pci_dev *pdev, | |||
| 17861 | sndmbx += 0xc; | 17844 | sndmbx += 0xc; |
| 17862 | } | 17845 | } |
| 17863 | 17846 | ||
| 17847 | /* | ||
| 17848 | * Reset chip in case UNDI or EFI driver did not shutdown | ||
| 17849 | * DMA self test will enable WDMAC and we'll see (spurious) | ||
| 17850 | * pending DMA on the PCI bus at that point. | ||
| 17851 | */ | ||
| 17852 | if ((tr32(HOSTCC_MODE) & HOSTCC_MODE_ENABLE) || | ||
| 17853 | (tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) { | ||
| 17854 | tw32(MEMARB_MODE, MEMARB_MODE_ENABLE); | ||
| 17855 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | ||
| 17856 | } | ||
| 17857 | |||
| 17858 | err = tg3_test_dma(tp); | ||
| 17859 | if (err) { | ||
| 17860 | dev_err(&pdev->dev, "DMA engine test failed, aborting\n"); | ||
| 17861 | goto err_out_apeunmap; | ||
| 17862 | } | ||
| 17863 | |||
| 17864 | tg3_init_coal(tp); | 17864 | tg3_init_coal(tp); |
| 17865 | 17865 | ||
| 17866 | pci_set_drvdata(pdev, dev); | 17866 | pci_set_drvdata(pdev, dev); |
diff --git a/drivers/net/ethernet/brocade/bna/bnad_debugfs.c b/drivers/net/ethernet/brocade/bna/bnad_debugfs.c index 7d6aa8c87df8..619083a860a4 100644 --- a/drivers/net/ethernet/brocade/bna/bnad_debugfs.c +++ b/drivers/net/ethernet/brocade/bna/bnad_debugfs.c | |||
| @@ -172,7 +172,7 @@ bnad_get_debug_drvinfo(struct bnad *bnad, void *buffer, u32 len) | |||
| 172 | 172 | ||
| 173 | /* Retrieve flash partition info */ | 173 | /* Retrieve flash partition info */ |
| 174 | fcomp.comp_status = 0; | 174 | fcomp.comp_status = 0; |
| 175 | init_completion(&fcomp.comp); | 175 | reinit_completion(&fcomp.comp); |
| 176 | spin_lock_irqsave(&bnad->bna_lock, flags); | 176 | spin_lock_irqsave(&bnad->bna_lock, flags); |
| 177 | ret = bfa_nw_flash_get_attr(&bnad->bna.flash, &drvinfo->flash_attr, | 177 | ret = bfa_nw_flash_get_attr(&bnad->bna.flash, &drvinfo->flash_attr, |
| 178 | bnad_cb_completion, &fcomp); | 178 | bnad_cb_completion, &fcomp); |
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h b/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h index d00a751f0588..6049f70e110c 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h +++ b/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h | |||
| @@ -96,6 +96,9 @@ struct port_info { | |||
| 96 | s16 xact_addr_filt; /* index of our MAC address filter */ | 96 | s16 xact_addr_filt; /* index of our MAC address filter */ |
| 97 | u16 rss_size; /* size of VI's RSS table slice */ | 97 | u16 rss_size; /* size of VI's RSS table slice */ |
| 98 | u8 pidx; /* index into adapter port[] */ | 98 | u8 pidx; /* index into adapter port[] */ |
| 99 | s8 mdio_addr; | ||
| 100 | u8 port_type; /* firmware port type */ | ||
| 101 | u8 mod_type; /* firmware module type */ | ||
| 99 | u8 port_id; /* physical port ID */ | 102 | u8 port_id; /* physical port ID */ |
| 100 | u8 nqsets; /* # of "Queue Sets" */ | 103 | u8 nqsets; /* # of "Queue Sets" */ |
| 101 | u8 first_qset; /* index of first "Queue Set" */ | 104 | u8 first_qset; /* index of first "Queue Set" */ |
| @@ -522,6 +525,7 @@ static inline struct adapter *netdev2adap(const struct net_device *dev) | |||
| 522 | * is "contracted" to provide for the common code. | 525 | * is "contracted" to provide for the common code. |
| 523 | */ | 526 | */ |
| 524 | void t4vf_os_link_changed(struct adapter *, int, int); | 527 | void t4vf_os_link_changed(struct adapter *, int, int); |
| 528 | void t4vf_os_portmod_changed(struct adapter *, int); | ||
| 525 | 529 | ||
| 526 | /* | 530 | /* |
| 527 | * SGE function prototype declarations. | 531 | * SGE function prototype declarations. |
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index aa74ec34a467..2215d432a059 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c | |||
| @@ -44,6 +44,7 @@ | |||
| 44 | #include <linux/etherdevice.h> | 44 | #include <linux/etherdevice.h> |
| 45 | #include <linux/debugfs.h> | 45 | #include <linux/debugfs.h> |
| 46 | #include <linux/ethtool.h> | 46 | #include <linux/ethtool.h> |
| 47 | #include <linux/mdio.h> | ||
| 47 | 48 | ||
| 48 | #include "t4vf_common.h" | 49 | #include "t4vf_common.h" |
| 49 | #include "t4vf_defs.h" | 50 | #include "t4vf_defs.h" |
| @@ -210,6 +211,38 @@ void t4vf_os_link_changed(struct adapter *adapter, int pidx, int link_ok) | |||
| 210 | } | 211 | } |
| 211 | 212 | ||
| 212 | /* | 213 | /* |
| 214 | * THe port module type has changed on the indicated "port" (Virtual | ||
| 215 | * Interface). | ||
| 216 | */ | ||
| 217 | void t4vf_os_portmod_changed(struct adapter *adapter, int pidx) | ||
| 218 | { | ||
| 219 | static const char * const mod_str[] = { | ||
| 220 | NULL, "LR", "SR", "ER", "passive DA", "active DA", "LRM" | ||
| 221 | }; | ||
| 222 | const struct net_device *dev = adapter->port[pidx]; | ||
| 223 | const struct port_info *pi = netdev_priv(dev); | ||
| 224 | |||
| 225 | if (pi->mod_type == FW_PORT_MOD_TYPE_NONE) | ||
| 226 | dev_info(adapter->pdev_dev, "%s: port module unplugged\n", | ||
| 227 | dev->name); | ||
| 228 | else if (pi->mod_type < ARRAY_SIZE(mod_str)) | ||
| 229 | dev_info(adapter->pdev_dev, "%s: %s port module inserted\n", | ||
| 230 | dev->name, mod_str[pi->mod_type]); | ||
| 231 | else if (pi->mod_type == FW_PORT_MOD_TYPE_NOTSUPPORTED) | ||
| 232 | dev_info(adapter->pdev_dev, "%s: unsupported optical port " | ||
| 233 | "module inserted\n", dev->name); | ||
| 234 | else if (pi->mod_type == FW_PORT_MOD_TYPE_UNKNOWN) | ||
| 235 | dev_info(adapter->pdev_dev, "%s: unknown port module inserted," | ||
| 236 | "forcing TWINAX\n", dev->name); | ||
| 237 | else if (pi->mod_type == FW_PORT_MOD_TYPE_ERROR) | ||
| 238 | dev_info(adapter->pdev_dev, "%s: transceiver module error\n", | ||
| 239 | dev->name); | ||
| 240 | else | ||
| 241 | dev_info(adapter->pdev_dev, "%s: unknown module type %d " | ||
| 242 | "inserted\n", dev->name, pi->mod_type); | ||
| 243 | } | ||
| 244 | |||
| 245 | /* | ||
| 213 | * Net device operations. | 246 | * Net device operations. |
| 214 | * ====================== | 247 | * ====================== |
| 215 | */ | 248 | */ |
| @@ -1193,24 +1226,103 @@ static void cxgb4vf_poll_controller(struct net_device *dev) | |||
| 1193 | * state of the port to which we're linked. | 1226 | * state of the port to which we're linked. |
| 1194 | */ | 1227 | */ |
| 1195 | 1228 | ||
| 1196 | /* | 1229 | static unsigned int t4vf_from_fw_linkcaps(enum fw_port_type type, |
| 1197 | * Return current port link settings. | 1230 | unsigned int caps) |
| 1198 | */ | 1231 | { |
| 1199 | static int cxgb4vf_get_settings(struct net_device *dev, | 1232 | unsigned int v = 0; |
| 1200 | struct ethtool_cmd *cmd) | 1233 | |
| 1201 | { | 1234 | if (type == FW_PORT_TYPE_BT_SGMII || type == FW_PORT_TYPE_BT_XFI || |
| 1202 | const struct port_info *pi = netdev_priv(dev); | 1235 | type == FW_PORT_TYPE_BT_XAUI) { |
| 1236 | v |= SUPPORTED_TP; | ||
| 1237 | if (caps & FW_PORT_CAP_SPEED_100M) | ||
| 1238 | v |= SUPPORTED_100baseT_Full; | ||
| 1239 | if (caps & FW_PORT_CAP_SPEED_1G) | ||
| 1240 | v |= SUPPORTED_1000baseT_Full; | ||
| 1241 | if (caps & FW_PORT_CAP_SPEED_10G) | ||
| 1242 | v |= SUPPORTED_10000baseT_Full; | ||
| 1243 | } else if (type == FW_PORT_TYPE_KX4 || type == FW_PORT_TYPE_KX) { | ||
| 1244 | v |= SUPPORTED_Backplane; | ||
| 1245 | if (caps & FW_PORT_CAP_SPEED_1G) | ||
| 1246 | v |= SUPPORTED_1000baseKX_Full; | ||
| 1247 | if (caps & FW_PORT_CAP_SPEED_10G) | ||
| 1248 | v |= SUPPORTED_10000baseKX4_Full; | ||
| 1249 | } else if (type == FW_PORT_TYPE_KR) | ||
| 1250 | v |= SUPPORTED_Backplane | SUPPORTED_10000baseKR_Full; | ||
| 1251 | else if (type == FW_PORT_TYPE_BP_AP) | ||
| 1252 | v |= SUPPORTED_Backplane | SUPPORTED_10000baseR_FEC | | ||
| 1253 | SUPPORTED_10000baseKR_Full | SUPPORTED_1000baseKX_Full; | ||
| 1254 | else if (type == FW_PORT_TYPE_BP4_AP) | ||
| 1255 | v |= SUPPORTED_Backplane | SUPPORTED_10000baseR_FEC | | ||
| 1256 | SUPPORTED_10000baseKR_Full | SUPPORTED_1000baseKX_Full | | ||
| 1257 | SUPPORTED_10000baseKX4_Full; | ||
| 1258 | else if (type == FW_PORT_TYPE_FIBER_XFI || | ||
| 1259 | type == FW_PORT_TYPE_FIBER_XAUI || | ||
| 1260 | type == FW_PORT_TYPE_SFP || | ||
| 1261 | type == FW_PORT_TYPE_QSFP_10G || | ||
| 1262 | type == FW_PORT_TYPE_QSA) { | ||
| 1263 | v |= SUPPORTED_FIBRE; | ||
| 1264 | if (caps & FW_PORT_CAP_SPEED_1G) | ||
| 1265 | v |= SUPPORTED_1000baseT_Full; | ||
| 1266 | if (caps & FW_PORT_CAP_SPEED_10G) | ||
| 1267 | v |= SUPPORTED_10000baseT_Full; | ||
| 1268 | } else if (type == FW_PORT_TYPE_BP40_BA || | ||
| 1269 | type == FW_PORT_TYPE_QSFP) { | ||
| 1270 | v |= SUPPORTED_40000baseSR4_Full; | ||
| 1271 | v |= SUPPORTED_FIBRE; | ||
| 1272 | } | ||
| 1273 | |||
| 1274 | if (caps & FW_PORT_CAP_ANEG) | ||
| 1275 | v |= SUPPORTED_Autoneg; | ||
| 1276 | return v; | ||
| 1277 | } | ||
| 1278 | |||
| 1279 | static int cxgb4vf_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
| 1280 | { | ||
| 1281 | const struct port_info *p = netdev_priv(dev); | ||
| 1282 | |||
| 1283 | if (p->port_type == FW_PORT_TYPE_BT_SGMII || | ||
| 1284 | p->port_type == FW_PORT_TYPE_BT_XFI || | ||
| 1285 | p->port_type == FW_PORT_TYPE_BT_XAUI) | ||
| 1286 | cmd->port = PORT_TP; | ||
| 1287 | else if (p->port_type == FW_PORT_TYPE_FIBER_XFI || | ||
| 1288 | p->port_type == FW_PORT_TYPE_FIBER_XAUI) | ||
| 1289 | cmd->port = PORT_FIBRE; | ||
| 1290 | else if (p->port_type == FW_PORT_TYPE_SFP || | ||
| 1291 | p->port_type == FW_PORT_TYPE_QSFP_10G || | ||
| 1292 | p->port_type == FW_PORT_TYPE_QSA || | ||
| 1293 | p->port_type == FW_PORT_TYPE_QSFP) { | ||
| 1294 | if (p->mod_type == FW_PORT_MOD_TYPE_LR || | ||
| 1295 | p->mod_type == FW_PORT_MOD_TYPE_SR || | ||
| 1296 | p->mod_type == FW_PORT_MOD_TYPE_ER || | ||
| 1297 | p->mod_type == FW_PORT_MOD_TYPE_LRM) | ||
| 1298 | cmd->port = PORT_FIBRE; | ||
| 1299 | else if (p->mod_type == FW_PORT_MOD_TYPE_TWINAX_PASSIVE || | ||
| 1300 | p->mod_type == FW_PORT_MOD_TYPE_TWINAX_ACTIVE) | ||
| 1301 | cmd->port = PORT_DA; | ||
| 1302 | else | ||
| 1303 | cmd->port = PORT_OTHER; | ||
| 1304 | } else | ||
| 1305 | cmd->port = PORT_OTHER; | ||
| 1203 | 1306 | ||
| 1204 | cmd->supported = pi->link_cfg.supported; | 1307 | if (p->mdio_addr >= 0) { |
| 1205 | cmd->advertising = pi->link_cfg.advertising; | 1308 | cmd->phy_address = p->mdio_addr; |
| 1309 | cmd->transceiver = XCVR_EXTERNAL; | ||
| 1310 | cmd->mdio_support = p->port_type == FW_PORT_TYPE_BT_SGMII ? | ||
| 1311 | MDIO_SUPPORTS_C22 : MDIO_SUPPORTS_C45; | ||
| 1312 | } else { | ||
| 1313 | cmd->phy_address = 0; /* not really, but no better option */ | ||
| 1314 | cmd->transceiver = XCVR_INTERNAL; | ||
| 1315 | cmd->mdio_support = 0; | ||
| 1316 | } | ||
| 1317 | |||
| 1318 | cmd->supported = t4vf_from_fw_linkcaps(p->port_type, | ||
| 1319 | p->link_cfg.supported); | ||
| 1320 | cmd->advertising = t4vf_from_fw_linkcaps(p->port_type, | ||
| 1321 | p->link_cfg.advertising); | ||
| 1206 | ethtool_cmd_speed_set(cmd, | 1322 | ethtool_cmd_speed_set(cmd, |
| 1207 | netif_carrier_ok(dev) ? pi->link_cfg.speed : -1); | 1323 | netif_carrier_ok(dev) ? p->link_cfg.speed : 0); |
| 1208 | cmd->duplex = DUPLEX_FULL; | 1324 | cmd->duplex = DUPLEX_FULL; |
| 1209 | 1325 | cmd->autoneg = p->link_cfg.autoneg; | |
| 1210 | cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE; | ||
| 1211 | cmd->phy_address = pi->port_id; | ||
| 1212 | cmd->transceiver = XCVR_EXTERNAL; | ||
| 1213 | cmd->autoneg = pi->link_cfg.autoneg; | ||
| 1214 | cmd->maxtxpkt = 0; | 1326 | cmd->maxtxpkt = 0; |
| 1215 | cmd->maxrxpkt = 0; | 1327 | cmd->maxrxpkt = 0; |
| 1216 | return 0; | 1328 | return 0; |
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h index 8d3237f5e364..b9debb4f29a3 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h +++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h | |||
| @@ -230,7 +230,7 @@ struct adapter_params { | |||
| 230 | 230 | ||
| 231 | static inline bool is_10g_port(const struct link_config *lc) | 231 | static inline bool is_10g_port(const struct link_config *lc) |
| 232 | { | 232 | { |
| 233 | return (lc->supported & SUPPORTED_10000baseT_Full) != 0; | 233 | return (lc->supported & FW_PORT_CAP_SPEED_10G) != 0; |
| 234 | } | 234 | } |
| 235 | 235 | ||
| 236 | static inline bool is_x_10g_port(const struct link_config *lc) | 236 | static inline bool is_x_10g_port(const struct link_config *lc) |
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c index 02e8833b7797..21dc9a20308c 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | |||
| @@ -245,6 +245,10 @@ static int hash_mac_addr(const u8 *addr) | |||
| 245 | return a & 0x3f; | 245 | return a & 0x3f; |
| 246 | } | 246 | } |
| 247 | 247 | ||
| 248 | #define ADVERT_MASK (FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G |\ | ||
| 249 | FW_PORT_CAP_SPEED_10G | FW_PORT_CAP_SPEED_40G | \ | ||
| 250 | FW_PORT_CAP_SPEED_100G | FW_PORT_CAP_ANEG) | ||
| 251 | |||
| 248 | /** | 252 | /** |
| 249 | * init_link_config - initialize a link's SW state | 253 | * init_link_config - initialize a link's SW state |
| 250 | * @lc: structure holding the link state | 254 | * @lc: structure holding the link state |
| @@ -259,8 +263,8 @@ static void init_link_config(struct link_config *lc, unsigned int caps) | |||
| 259 | lc->requested_speed = 0; | 263 | lc->requested_speed = 0; |
| 260 | lc->speed = 0; | 264 | lc->speed = 0; |
| 261 | lc->requested_fc = lc->fc = PAUSE_RX | PAUSE_TX; | 265 | lc->requested_fc = lc->fc = PAUSE_RX | PAUSE_TX; |
| 262 | if (lc->supported & SUPPORTED_Autoneg) { | 266 | if (lc->supported & FW_PORT_CAP_ANEG) { |
| 263 | lc->advertising = lc->supported; | 267 | lc->advertising = lc->supported & ADVERT_MASK; |
| 264 | lc->autoneg = AUTONEG_ENABLE; | 268 | lc->autoneg = AUTONEG_ENABLE; |
| 265 | lc->requested_fc |= PAUSE_AUTONEG; | 269 | lc->requested_fc |= PAUSE_AUTONEG; |
| 266 | } else { | 270 | } else { |
| @@ -280,7 +284,6 @@ int t4vf_port_init(struct adapter *adapter, int pidx) | |||
| 280 | struct fw_vi_cmd vi_cmd, vi_rpl; | 284 | struct fw_vi_cmd vi_cmd, vi_rpl; |
| 281 | struct fw_port_cmd port_cmd, port_rpl; | 285 | struct fw_port_cmd port_cmd, port_rpl; |
| 282 | int v; | 286 | int v; |
| 283 | u32 word; | ||
| 284 | 287 | ||
| 285 | /* | 288 | /* |
| 286 | * Execute a VI Read command to get our Virtual Interface information | 289 | * Execute a VI Read command to get our Virtual Interface information |
| @@ -319,19 +322,11 @@ int t4vf_port_init(struct adapter *adapter, int pidx) | |||
| 319 | if (v) | 322 | if (v) |
| 320 | return v; | 323 | return v; |
| 321 | 324 | ||
| 322 | v = 0; | 325 | v = be32_to_cpu(port_rpl.u.info.lstatus_to_modtype); |
| 323 | word = be16_to_cpu(port_rpl.u.info.pcap); | 326 | pi->port_type = FW_PORT_CMD_PTYPE_G(v); |
| 324 | if (word & FW_PORT_CAP_SPEED_100M) | 327 | pi->mod_type = FW_PORT_MOD_TYPE_NA; |
| 325 | v |= SUPPORTED_100baseT_Full; | 328 | |
| 326 | if (word & FW_PORT_CAP_SPEED_1G) | 329 | init_link_config(&pi->link_cfg, be16_to_cpu(port_rpl.u.info.pcap)); |
| 327 | v |= SUPPORTED_1000baseT_Full; | ||
| 328 | if (word & FW_PORT_CAP_SPEED_10G) | ||
| 329 | v |= SUPPORTED_10000baseT_Full; | ||
| 330 | if (word & FW_PORT_CAP_SPEED_40G) | ||
| 331 | v |= SUPPORTED_40000baseSR4_Full; | ||
| 332 | if (word & FW_PORT_CAP_ANEG) | ||
| 333 | v |= SUPPORTED_Autoneg; | ||
| 334 | init_link_config(&pi->link_cfg, v); | ||
| 335 | 330 | ||
| 336 | return 0; | 331 | return 0; |
| 337 | } | 332 | } |
| @@ -1491,7 +1486,7 @@ int t4vf_handle_fw_rpl(struct adapter *adapter, const __be64 *rpl) | |||
| 1491 | */ | 1486 | */ |
| 1492 | const struct fw_port_cmd *port_cmd = | 1487 | const struct fw_port_cmd *port_cmd = |
| 1493 | (const struct fw_port_cmd *)rpl; | 1488 | (const struct fw_port_cmd *)rpl; |
| 1494 | u32 word; | 1489 | u32 stat, mod; |
| 1495 | int action, port_id, link_ok, speed, fc, pidx; | 1490 | int action, port_id, link_ok, speed, fc, pidx; |
| 1496 | 1491 | ||
| 1497 | /* | 1492 | /* |
| @@ -1509,21 +1504,21 @@ int t4vf_handle_fw_rpl(struct adapter *adapter, const __be64 *rpl) | |||
| 1509 | port_id = FW_PORT_CMD_PORTID_G( | 1504 | port_id = FW_PORT_CMD_PORTID_G( |
| 1510 | be32_to_cpu(port_cmd->op_to_portid)); | 1505 | be32_to_cpu(port_cmd->op_to_portid)); |
| 1511 | 1506 | ||
| 1512 | word = be32_to_cpu(port_cmd->u.info.lstatus_to_modtype); | 1507 | stat = be32_to_cpu(port_cmd->u.info.lstatus_to_modtype); |
| 1513 | link_ok = (word & FW_PORT_CMD_LSTATUS_F) != 0; | 1508 | link_ok = (stat & FW_PORT_CMD_LSTATUS_F) != 0; |
| 1514 | speed = 0; | 1509 | speed = 0; |
| 1515 | fc = 0; | 1510 | fc = 0; |
| 1516 | if (word & FW_PORT_CMD_RXPAUSE_F) | 1511 | if (stat & FW_PORT_CMD_RXPAUSE_F) |
| 1517 | fc |= PAUSE_RX; | 1512 | fc |= PAUSE_RX; |
| 1518 | if (word & FW_PORT_CMD_TXPAUSE_F) | 1513 | if (stat & FW_PORT_CMD_TXPAUSE_F) |
| 1519 | fc |= PAUSE_TX; | 1514 | fc |= PAUSE_TX; |
| 1520 | if (word & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100M)) | 1515 | if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100M)) |
| 1521 | speed = 100; | 1516 | speed = 100; |
| 1522 | else if (word & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_1G)) | 1517 | else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_1G)) |
| 1523 | speed = 1000; | 1518 | speed = 1000; |
| 1524 | else if (word & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_10G)) | 1519 | else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_10G)) |
| 1525 | speed = 10000; | 1520 | speed = 10000; |
| 1526 | else if (word & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_40G)) | 1521 | else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_40G)) |
| 1527 | speed = 40000; | 1522 | speed = 40000; |
| 1528 | 1523 | ||
| 1529 | /* | 1524 | /* |
| @@ -1540,12 +1535,21 @@ int t4vf_handle_fw_rpl(struct adapter *adapter, const __be64 *rpl) | |||
| 1540 | continue; | 1535 | continue; |
| 1541 | 1536 | ||
| 1542 | lc = &pi->link_cfg; | 1537 | lc = &pi->link_cfg; |
| 1538 | |||
| 1539 | mod = FW_PORT_CMD_MODTYPE_G(stat); | ||
| 1540 | if (mod != pi->mod_type) { | ||
| 1541 | pi->mod_type = mod; | ||
| 1542 | t4vf_os_portmod_changed(adapter, pidx); | ||
| 1543 | } | ||
| 1544 | |||
| 1543 | if (link_ok != lc->link_ok || speed != lc->speed || | 1545 | if (link_ok != lc->link_ok || speed != lc->speed || |
| 1544 | fc != lc->fc) { | 1546 | fc != lc->fc) { |
| 1545 | /* something changed */ | 1547 | /* something changed */ |
| 1546 | lc->link_ok = link_ok; | 1548 | lc->link_ok = link_ok; |
| 1547 | lc->speed = speed; | 1549 | lc->speed = speed; |
| 1548 | lc->fc = fc; | 1550 | lc->fc = fc; |
| 1551 | lc->supported = | ||
| 1552 | be16_to_cpu(port_cmd->u.info.pcap); | ||
| 1549 | t4vf_os_link_changed(adapter, pidx, link_ok); | 1553 | t4vf_os_link_changed(adapter, pidx, link_ok); |
| 1550 | } | 1554 | } |
| 1551 | } | 1555 | } |
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c index 868d0f605d60..705f334ebb85 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c | |||
| @@ -1060,10 +1060,14 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq, | |||
| 1060 | PKT_HASH_TYPE_L4 : PKT_HASH_TYPE_L3); | 1060 | PKT_HASH_TYPE_L4 : PKT_HASH_TYPE_L3); |
| 1061 | } | 1061 | } |
| 1062 | 1062 | ||
| 1063 | if ((netdev->features & NETIF_F_RXCSUM) && !csum_not_calc) { | 1063 | /* Hardware does not provide whole packet checksum. It only |
| 1064 | skb->csum = htons(checksum); | 1064 | * provides pseudo checksum. Since hw validates the packet |
| 1065 | skb->ip_summed = CHECKSUM_COMPLETE; | 1065 | * checksum but not provide us the checksum value. use |
| 1066 | } | 1066 | * CHECSUM_UNNECESSARY. |
| 1067 | */ | ||
| 1068 | if ((netdev->features & NETIF_F_RXCSUM) && tcp_udp_csum_ok && | ||
| 1069 | ipv4_csum_ok) | ||
| 1070 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
| 1067 | 1071 | ||
| 1068 | if (vlan_stripped) | 1072 | if (vlan_stripped) |
| 1069 | __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan_tci); | 1073 | __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan_tci); |
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 196073110e32..41a0a5498da7 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c | |||
| @@ -4459,9 +4459,11 @@ done: | |||
| 4459 | adapter->vxlan_port_count--; | 4459 | adapter->vxlan_port_count--; |
| 4460 | } | 4460 | } |
| 4461 | 4461 | ||
| 4462 | static bool be_gso_check(struct sk_buff *skb, struct net_device *dev) | 4462 | static netdev_features_t be_features_check(struct sk_buff *skb, |
| 4463 | struct net_device *dev, | ||
| 4464 | netdev_features_t features) | ||
| 4463 | { | 4465 | { |
| 4464 | return vxlan_gso_check(skb); | 4466 | return vxlan_features_check(skb, features); |
| 4465 | } | 4467 | } |
| 4466 | #endif | 4468 | #endif |
| 4467 | 4469 | ||
| @@ -4492,7 +4494,7 @@ static const struct net_device_ops be_netdev_ops = { | |||
| 4492 | #ifdef CONFIG_BE2NET_VXLAN | 4494 | #ifdef CONFIG_BE2NET_VXLAN |
| 4493 | .ndo_add_vxlan_port = be_add_vxlan_port, | 4495 | .ndo_add_vxlan_port = be_add_vxlan_port, |
| 4494 | .ndo_del_vxlan_port = be_del_vxlan_port, | 4496 | .ndo_del_vxlan_port = be_del_vxlan_port, |
| 4495 | .ndo_gso_check = be_gso_check, | 4497 | .ndo_features_check = be_features_check, |
| 4496 | #endif | 4498 | #endif |
| 4497 | }; | 4499 | }; |
| 4498 | 4500 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 190cbd931f6b..d0d6dc1b8e46 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c | |||
| @@ -2365,9 +2365,11 @@ static void mlx4_en_del_vxlan_port(struct net_device *dev, | |||
| 2365 | queue_work(priv->mdev->workqueue, &priv->vxlan_del_task); | 2365 | queue_work(priv->mdev->workqueue, &priv->vxlan_del_task); |
| 2366 | } | 2366 | } |
| 2367 | 2367 | ||
| 2368 | static bool mlx4_en_gso_check(struct sk_buff *skb, struct net_device *dev) | 2368 | static netdev_features_t mlx4_en_features_check(struct sk_buff *skb, |
| 2369 | struct net_device *dev, | ||
| 2370 | netdev_features_t features) | ||
| 2369 | { | 2371 | { |
| 2370 | return vxlan_gso_check(skb); | 2372 | return vxlan_features_check(skb, features); |
| 2371 | } | 2373 | } |
| 2372 | #endif | 2374 | #endif |
| 2373 | 2375 | ||
| @@ -2400,7 +2402,7 @@ static const struct net_device_ops mlx4_netdev_ops = { | |||
| 2400 | #ifdef CONFIG_MLX4_EN_VXLAN | 2402 | #ifdef CONFIG_MLX4_EN_VXLAN |
| 2401 | .ndo_add_vxlan_port = mlx4_en_add_vxlan_port, | 2403 | .ndo_add_vxlan_port = mlx4_en_add_vxlan_port, |
| 2402 | .ndo_del_vxlan_port = mlx4_en_del_vxlan_port, | 2404 | .ndo_del_vxlan_port = mlx4_en_del_vxlan_port, |
| 2403 | .ndo_gso_check = mlx4_en_gso_check, | 2405 | .ndo_features_check = mlx4_en_features_check, |
| 2404 | #endif | 2406 | #endif |
| 2405 | }; | 2407 | }; |
| 2406 | 2408 | ||
| @@ -2434,7 +2436,7 @@ static const struct net_device_ops mlx4_netdev_ops_master = { | |||
| 2434 | #ifdef CONFIG_MLX4_EN_VXLAN | 2436 | #ifdef CONFIG_MLX4_EN_VXLAN |
| 2435 | .ndo_add_vxlan_port = mlx4_en_add_vxlan_port, | 2437 | .ndo_add_vxlan_port = mlx4_en_add_vxlan_port, |
| 2436 | .ndo_del_vxlan_port = mlx4_en_del_vxlan_port, | 2438 | .ndo_del_vxlan_port = mlx4_en_del_vxlan_port, |
| 2437 | .ndo_gso_check = mlx4_en_gso_check, | 2439 | .ndo_features_check = mlx4_en_features_check, |
| 2438 | #endif | 2440 | #endif |
| 2439 | }; | 2441 | }; |
| 2440 | 2442 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c index a308d41e4de0..e3357bf523df 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c | |||
| @@ -962,7 +962,17 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 962 | tx_desc->ctrl.owner_opcode = op_own; | 962 | tx_desc->ctrl.owner_opcode = op_own; |
| 963 | if (send_doorbell) { | 963 | if (send_doorbell) { |
| 964 | wmb(); | 964 | wmb(); |
| 965 | iowrite32(ring->doorbell_qpn, | 965 | /* Since there is no iowrite*_native() that writes the |
| 966 | * value as is, without byteswapping - using the one | ||
| 967 | * the doesn't do byteswapping in the relevant arch | ||
| 968 | * endianness. | ||
| 969 | */ | ||
| 970 | #if defined(__LITTLE_ENDIAN) | ||
| 971 | iowrite32( | ||
| 972 | #else | ||
| 973 | iowrite32be( | ||
| 974 | #endif | ||
| 975 | ring->doorbell_qpn, | ||
| 966 | ring->bf.uar->map + MLX4_SEND_DOORBELL); | 976 | ring->bf.uar->map + MLX4_SEND_DOORBELL); |
| 967 | } else { | 977 | } else { |
| 968 | ring->xmit_more++; | 978 | ring->xmit_more++; |
diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c index f1ebed6c63b1..2fa6ae026e4f 100644 --- a/drivers/net/ethernet/micrel/ksz884x.c +++ b/drivers/net/ethernet/micrel/ksz884x.c | |||
| @@ -2303,12 +2303,6 @@ static inline int port_chk_force_flow_ctrl(struct ksz_hw *hw, int p) | |||
| 2303 | 2303 | ||
| 2304 | /* Spanning Tree */ | 2304 | /* Spanning Tree */ |
| 2305 | 2305 | ||
| 2306 | static inline void port_cfg_dis_learn(struct ksz_hw *hw, int p, int set) | ||
| 2307 | { | ||
| 2308 | port_cfg(hw, p, | ||
| 2309 | KS8842_PORT_CTRL_2_OFFSET, PORT_LEARN_DISABLE, set); | ||
| 2310 | } | ||
| 2311 | |||
| 2312 | static inline void port_cfg_rx(struct ksz_hw *hw, int p, int set) | 2306 | static inline void port_cfg_rx(struct ksz_hw *hw, int p, int set) |
| 2313 | { | 2307 | { |
| 2314 | port_cfg(hw, p, | 2308 | port_cfg(hw, p, |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 1aa25b13ace1..9929b97cfb36 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | |||
| @@ -505,9 +505,11 @@ static void qlcnic_del_vxlan_port(struct net_device *netdev, | |||
| 505 | adapter->flags |= QLCNIC_DEL_VXLAN_PORT; | 505 | adapter->flags |= QLCNIC_DEL_VXLAN_PORT; |
| 506 | } | 506 | } |
| 507 | 507 | ||
| 508 | static bool qlcnic_gso_check(struct sk_buff *skb, struct net_device *dev) | 508 | static netdev_features_t qlcnic_features_check(struct sk_buff *skb, |
| 509 | struct net_device *dev, | ||
| 510 | netdev_features_t features) | ||
| 509 | { | 511 | { |
| 510 | return vxlan_gso_check(skb); | 512 | return vxlan_features_check(skb, features); |
| 511 | } | 513 | } |
| 512 | #endif | 514 | #endif |
| 513 | 515 | ||
| @@ -532,7 +534,7 @@ static const struct net_device_ops qlcnic_netdev_ops = { | |||
| 532 | #ifdef CONFIG_QLCNIC_VXLAN | 534 | #ifdef CONFIG_QLCNIC_VXLAN |
| 533 | .ndo_add_vxlan_port = qlcnic_add_vxlan_port, | 535 | .ndo_add_vxlan_port = qlcnic_add_vxlan_port, |
| 534 | .ndo_del_vxlan_port = qlcnic_del_vxlan_port, | 536 | .ndo_del_vxlan_port = qlcnic_del_vxlan_port, |
| 535 | .ndo_gso_check = qlcnic_gso_check, | 537 | .ndo_features_check = qlcnic_features_check, |
| 536 | #endif | 538 | #endif |
| 537 | #ifdef CONFIG_NET_POLL_CONTROLLER | 539 | #ifdef CONFIG_NET_POLL_CONTROLLER |
| 538 | .ndo_poll_controller = qlcnic_poll_controller, | 540 | .ndo_poll_controller = qlcnic_poll_controller, |
diff --git a/drivers/net/ethernet/realtek/8139too.c b/drivers/net/ethernet/realtek/8139too.c index 6d0b9dfac313..78bb4ceb1cdd 100644 --- a/drivers/net/ethernet/realtek/8139too.c +++ b/drivers/net/ethernet/realtek/8139too.c | |||
| @@ -787,10 +787,10 @@ static struct net_device *rtl8139_init_board(struct pci_dev *pdev) | |||
| 787 | if (rc) | 787 | if (rc) |
| 788 | goto err_out; | 788 | goto err_out; |
| 789 | 789 | ||
| 790 | disable_dev_on_err = 1; | ||
| 790 | rc = pci_request_regions (pdev, DRV_NAME); | 791 | rc = pci_request_regions (pdev, DRV_NAME); |
| 791 | if (rc) | 792 | if (rc) |
| 792 | goto err_out; | 793 | goto err_out; |
| 793 | disable_dev_on_err = 1; | ||
| 794 | 794 | ||
| 795 | pci_set_master (pdev); | 795 | pci_set_master (pdev); |
| 796 | 796 | ||
| @@ -1110,6 +1110,7 @@ static int rtl8139_init_one(struct pci_dev *pdev, | |||
| 1110 | return 0; | 1110 | return 0; |
| 1111 | 1111 | ||
| 1112 | err_out: | 1112 | err_out: |
| 1113 | netif_napi_del(&tp->napi); | ||
| 1113 | __rtl8139_cleanup_dev (dev); | 1114 | __rtl8139_cleanup_dev (dev); |
| 1114 | pci_disable_device (pdev); | 1115 | pci_disable_device (pdev); |
| 1115 | return i; | 1116 | return i; |
| @@ -1124,6 +1125,7 @@ static void rtl8139_remove_one(struct pci_dev *pdev) | |||
| 1124 | assert (dev != NULL); | 1125 | assert (dev != NULL); |
| 1125 | 1126 | ||
| 1126 | cancel_delayed_work_sync(&tp->thread); | 1127 | cancel_delayed_work_sync(&tp->thread); |
| 1128 | netif_napi_del(&tp->napi); | ||
| 1127 | 1129 | ||
| 1128 | unregister_netdev (dev); | 1130 | unregister_netdev (dev); |
| 1129 | 1131 | ||
diff --git a/drivers/net/ethernet/s6gmac.c b/drivers/net/ethernet/s6gmac.c deleted file mode 100644 index f537cbea20e5..000000000000 --- a/drivers/net/ethernet/s6gmac.c +++ /dev/null | |||
| @@ -1,1058 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Ethernet driver for S6105 on chip network device | ||
| 3 | * (c)2008 emlix GmbH http://www.emlix.com | ||
| 4 | * Authors: Oskar Schirmer <oskar@scara.com> | ||
| 5 | * Daniel Gloeckner <dg@emlix.com> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU General Public License | ||
| 9 | * as published by the Free Software Foundation; either version | ||
| 10 | * 2 of the License, or (at your option) any later version. | ||
| 11 | */ | ||
| 12 | #include <linux/kernel.h> | ||
| 13 | #include <linux/module.h> | ||
| 14 | #include <linux/interrupt.h> | ||
| 15 | #include <linux/types.h> | ||
| 16 | #include <linux/delay.h> | ||
| 17 | #include <linux/spinlock.h> | ||
| 18 | #include <linux/netdevice.h> | ||
| 19 | #include <linux/etherdevice.h> | ||
| 20 | #include <linux/if.h> | ||
| 21 | #include <linux/stddef.h> | ||
| 22 | #include <linux/mii.h> | ||
| 23 | #include <linux/phy.h> | ||
| 24 | #include <linux/platform_device.h> | ||
| 25 | #include <variant/hardware.h> | ||
| 26 | #include <variant/dmac.h> | ||
| 27 | |||
| 28 | #define DRV_NAME "s6gmac" | ||
| 29 | #define DRV_PRMT DRV_NAME ": " | ||
| 30 | |||
| 31 | |||
| 32 | /* register declarations */ | ||
| 33 | |||
| 34 | #define S6_GMAC_MACCONF1 0x000 | ||
| 35 | #define S6_GMAC_MACCONF1_TXENA 0 | ||
| 36 | #define S6_GMAC_MACCONF1_SYNCTX 1 | ||
| 37 | #define S6_GMAC_MACCONF1_RXENA 2 | ||
| 38 | #define S6_GMAC_MACCONF1_SYNCRX 3 | ||
| 39 | #define S6_GMAC_MACCONF1_TXFLOWCTRL 4 | ||
| 40 | #define S6_GMAC_MACCONF1_RXFLOWCTRL 5 | ||
| 41 | #define S6_GMAC_MACCONF1_LOOPBACK 8 | ||
| 42 | #define S6_GMAC_MACCONF1_RESTXFUNC 16 | ||
| 43 | #define S6_GMAC_MACCONF1_RESRXFUNC 17 | ||
| 44 | #define S6_GMAC_MACCONF1_RESTXMACCTRL 18 | ||
| 45 | #define S6_GMAC_MACCONF1_RESRXMACCTRL 19 | ||
| 46 | #define S6_GMAC_MACCONF1_SIMULRES 30 | ||
| 47 | #define S6_GMAC_MACCONF1_SOFTRES 31 | ||
| 48 | #define S6_GMAC_MACCONF2 0x004 | ||
| 49 | #define S6_GMAC_MACCONF2_FULL 0 | ||
| 50 | #define S6_GMAC_MACCONF2_CRCENA 1 | ||
| 51 | #define S6_GMAC_MACCONF2_PADCRCENA 2 | ||
| 52 | #define S6_GMAC_MACCONF2_LENGTHFCHK 4 | ||
| 53 | #define S6_GMAC_MACCONF2_HUGEFRAMENA 5 | ||
| 54 | #define S6_GMAC_MACCONF2_IFMODE 8 | ||
| 55 | #define S6_GMAC_MACCONF2_IFMODE_NIBBLE 1 | ||
| 56 | #define S6_GMAC_MACCONF2_IFMODE_BYTE 2 | ||
| 57 | #define S6_GMAC_MACCONF2_IFMODE_MASK 3 | ||
| 58 | #define S6_GMAC_MACCONF2_PREAMBLELEN 12 | ||
| 59 | #define S6_GMAC_MACCONF2_PREAMBLELEN_MASK 0x0F | ||
| 60 | #define S6_GMAC_MACIPGIFG 0x008 | ||
| 61 | #define S6_GMAC_MACIPGIFG_B2BINTERPGAP 0 | ||
| 62 | #define S6_GMAC_MACIPGIFG_B2BINTERPGAP_MASK 0x7F | ||
| 63 | #define S6_GMAC_MACIPGIFG_MINIFGENFORCE 8 | ||
| 64 | #define S6_GMAC_MACIPGIFG_B2BINTERPGAP2 16 | ||
| 65 | #define S6_GMAC_MACIPGIFG_B2BINTERPGAP1 24 | ||
| 66 | #define S6_GMAC_MACHALFDUPLEX 0x00C | ||
| 67 | #define S6_GMAC_MACHALFDUPLEX_COLLISWIN 0 | ||
| 68 | #define S6_GMAC_MACHALFDUPLEX_COLLISWIN_MASK 0x3F | ||
| 69 | #define S6_GMAC_MACHALFDUPLEX_RETXMAX 12 | ||
| 70 | #define S6_GMAC_MACHALFDUPLEX_RETXMAX_MASK 0x0F | ||
| 71 | #define S6_GMAC_MACHALFDUPLEX_EXCESSDEF 16 | ||
| 72 | #define S6_GMAC_MACHALFDUPLEX_NOBACKOFF 17 | ||
| 73 | #define S6_GMAC_MACHALFDUPLEX_BPNOBCKOF 18 | ||
| 74 | #define S6_GMAC_MACHALFDUPLEX_ALTBEBENA 19 | ||
| 75 | #define S6_GMAC_MACHALFDUPLEX_ALTBEBTRN 20 | ||
| 76 | #define S6_GMAC_MACHALFDUPLEX_ALTBEBTR_MASK 0x0F | ||
| 77 | #define S6_GMAC_MACMAXFRAMELEN 0x010 | ||
| 78 | #define S6_GMAC_MACMIICONF 0x020 | ||
| 79 | #define S6_GMAC_MACMIICONF_CSEL 0 | ||
| 80 | #define S6_GMAC_MACMIICONF_CSEL_DIV10 0 | ||
| 81 | #define S6_GMAC_MACMIICONF_CSEL_DIV12 1 | ||
| 82 | #define S6_GMAC_MACMIICONF_CSEL_DIV14 2 | ||
| 83 | #define S6_GMAC_MACMIICONF_CSEL_DIV18 3 | ||
| 84 | #define S6_GMAC_MACMIICONF_CSEL_DIV24 4 | ||
| 85 | #define S6_GMAC_MACMIICONF_CSEL_DIV34 5 | ||
| 86 | #define S6_GMAC_MACMIICONF_CSEL_DIV68 6 | ||
| 87 | #define S6_GMAC_MACMIICONF_CSEL_DIV168 7 | ||
| 88 | #define S6_GMAC_MACMIICONF_CSEL_MASK 7 | ||
| 89 | #define S6_GMAC_MACMIICONF_PREAMBLESUPR 4 | ||
| 90 | #define S6_GMAC_MACMIICONF_SCANAUTOINCR 5 | ||
| 91 | #define S6_GMAC_MACMIICMD 0x024 | ||
| 92 | #define S6_GMAC_MACMIICMD_READ 0 | ||
| 93 | #define S6_GMAC_MACMIICMD_SCAN 1 | ||
| 94 | #define S6_GMAC_MACMIIADDR 0x028 | ||
| 95 | #define S6_GMAC_MACMIIADDR_REG 0 | ||
| 96 | #define S6_GMAC_MACMIIADDR_REG_MASK 0x1F | ||
| 97 | #define S6_GMAC_MACMIIADDR_PHY 8 | ||
| 98 | #define S6_GMAC_MACMIIADDR_PHY_MASK 0x1F | ||
| 99 | #define S6_GMAC_MACMIICTRL 0x02C | ||
| 100 | #define S6_GMAC_MACMIISTAT 0x030 | ||
| 101 | #define S6_GMAC_MACMIIINDI 0x034 | ||
| 102 | #define S6_GMAC_MACMIIINDI_BUSY 0 | ||
| 103 | #define S6_GMAC_MACMIIINDI_SCAN 1 | ||
| 104 | #define S6_GMAC_MACMIIINDI_INVAL 2 | ||
| 105 | #define S6_GMAC_MACINTERFSTAT 0x03C | ||
| 106 | #define S6_GMAC_MACINTERFSTAT_LINKFAIL 3 | ||
| 107 | #define S6_GMAC_MACINTERFSTAT_EXCESSDEF 9 | ||
| 108 | #define S6_GMAC_MACSTATADDR1 0x040 | ||
| 109 | #define S6_GMAC_MACSTATADDR2 0x044 | ||
| 110 | |||
| 111 | #define S6_GMAC_FIFOCONF0 0x048 | ||
| 112 | #define S6_GMAC_FIFOCONF0_HSTRSTWT 0 | ||
| 113 | #define S6_GMAC_FIFOCONF0_HSTRSTSR 1 | ||
| 114 | #define S6_GMAC_FIFOCONF0_HSTRSTFR 2 | ||
| 115 | #define S6_GMAC_FIFOCONF0_HSTRSTST 3 | ||
| 116 | #define S6_GMAC_FIFOCONF0_HSTRSTFT 4 | ||
| 117 | #define S6_GMAC_FIFOCONF0_WTMENREQ 8 | ||
| 118 | #define S6_GMAC_FIFOCONF0_SRFENREQ 9 | ||
| 119 | #define S6_GMAC_FIFOCONF0_FRFENREQ 10 | ||
| 120 | #define S6_GMAC_FIFOCONF0_STFENREQ 11 | ||
| 121 | #define S6_GMAC_FIFOCONF0_FTFENREQ 12 | ||
| 122 | #define S6_GMAC_FIFOCONF0_WTMENRPLY 16 | ||
| 123 | #define S6_GMAC_FIFOCONF0_SRFENRPLY 17 | ||
| 124 | #define S6_GMAC_FIFOCONF0_FRFENRPLY 18 | ||
| 125 | #define S6_GMAC_FIFOCONF0_STFENRPLY 19 | ||
| 126 | #define S6_GMAC_FIFOCONF0_FTFENRPLY 20 | ||
| 127 | #define S6_GMAC_FIFOCONF1 0x04C | ||
| 128 | #define S6_GMAC_FIFOCONF2 0x050 | ||
| 129 | #define S6_GMAC_FIFOCONF2_CFGLWM 0 | ||
| 130 | #define S6_GMAC_FIFOCONF2_CFGHWM 16 | ||
| 131 | #define S6_GMAC_FIFOCONF3 0x054 | ||
| 132 | #define S6_GMAC_FIFOCONF3_CFGFTTH 0 | ||
| 133 | #define S6_GMAC_FIFOCONF3_CFGHWMFT 16 | ||
| 134 | #define S6_GMAC_FIFOCONF4 0x058 | ||
| 135 | #define S6_GMAC_FIFOCONF_RSV_PREVDROP 0 | ||
| 136 | #define S6_GMAC_FIFOCONF_RSV_RUNT 1 | ||
| 137 | #define S6_GMAC_FIFOCONF_RSV_FALSECAR 2 | ||
| 138 | #define S6_GMAC_FIFOCONF_RSV_CODEERR 3 | ||
| 139 | #define S6_GMAC_FIFOCONF_RSV_CRCERR 4 | ||
| 140 | #define S6_GMAC_FIFOCONF_RSV_LENGTHERR 5 | ||
| 141 | #define S6_GMAC_FIFOCONF_RSV_LENRANGE 6 | ||
| 142 | #define S6_GMAC_FIFOCONF_RSV_OK 7 | ||
| 143 | #define S6_GMAC_FIFOCONF_RSV_MULTICAST 8 | ||
| 144 | #define S6_GMAC_FIFOCONF_RSV_BROADCAST 9 | ||
| 145 | #define S6_GMAC_FIFOCONF_RSV_DRIBBLE 10 | ||
| 146 | #define S6_GMAC_FIFOCONF_RSV_CTRLFRAME 11 | ||
| 147 | #define S6_GMAC_FIFOCONF_RSV_PAUSECTRL 12 | ||
| 148 | #define S6_GMAC_FIFOCONF_RSV_UNOPCODE 13 | ||
| 149 | #define S6_GMAC_FIFOCONF_RSV_VLANTAG 14 | ||
| 150 | #define S6_GMAC_FIFOCONF_RSV_LONGEVENT 15 | ||
| 151 | #define S6_GMAC_FIFOCONF_RSV_TRUNCATED 16 | ||
| 152 | #define S6_GMAC_FIFOCONF_RSV_MASK 0x3FFFF | ||
| 153 | #define S6_GMAC_FIFOCONF5 0x05C | ||
| 154 | #define S6_GMAC_FIFOCONF5_DROPLT64 18 | ||
| 155 | #define S6_GMAC_FIFOCONF5_CFGBYTM 19 | ||
| 156 | #define S6_GMAC_FIFOCONF5_RXDROPSIZE 20 | ||
| 157 | #define S6_GMAC_FIFOCONF5_RXDROPSIZE_MASK 0xF | ||
| 158 | |||
| 159 | #define S6_GMAC_STAT_REGS 0x080 | ||
| 160 | #define S6_GMAC_STAT_SIZE_MIN 12 | ||
| 161 | #define S6_GMAC_STATTR64 0x080 | ||
| 162 | #define S6_GMAC_STATTR64_SIZE 18 | ||
| 163 | #define S6_GMAC_STATTR127 0x084 | ||
| 164 | #define S6_GMAC_STATTR127_SIZE 18 | ||
| 165 | #define S6_GMAC_STATTR255 0x088 | ||
| 166 | #define S6_GMAC_STATTR255_SIZE 18 | ||
| 167 | #define S6_GMAC_STATTR511 0x08C | ||
| 168 | #define S6_GMAC_STATTR511_SIZE 18 | ||
| 169 | #define S6_GMAC_STATTR1K 0x090 | ||
| 170 | #define S6_GMAC_STATTR1K_SIZE 18 | ||
| 171 | #define S6_GMAC_STATTRMAX 0x094 | ||
| 172 | #define S6_GMAC_STATTRMAX_SIZE 18 | ||
| 173 | #define S6_GMAC_STATTRMGV 0x098 | ||
| 174 | #define S6_GMAC_STATTRMGV_SIZE 18 | ||
| 175 | #define S6_GMAC_STATRBYT 0x09C | ||
| 176 | #define S6_GMAC_STATRBYT_SIZE 24 | ||
| 177 | #define S6_GMAC_STATRPKT 0x0A0 | ||
| 178 | #define S6_GMAC_STATRPKT_SIZE 18 | ||
| 179 | #define S6_GMAC_STATRFCS 0x0A4 | ||
| 180 | #define S6_GMAC_STATRFCS_SIZE 12 | ||
| 181 | #define S6_GMAC_STATRMCA 0x0A8 | ||
| 182 | #define S6_GMAC_STATRMCA_SIZE 18 | ||
| 183 | #define S6_GMAC_STATRBCA 0x0AC | ||
| 184 | #define S6_GMAC_STATRBCA_SIZE 22 | ||
| 185 | #define S6_GMAC_STATRXCF 0x0B0 | ||
| 186 | #define S6_GMAC_STATRXCF_SIZE 18 | ||
| 187 | #define S6_GMAC_STATRXPF 0x0B4 | ||
| 188 | #define S6_GMAC_STATRXPF_SIZE 12 | ||
| 189 | #define S6_GMAC_STATRXUO 0x0B8 | ||
| 190 | #define S6_GMAC_STATRXUO_SIZE 12 | ||
| 191 | #define S6_GMAC_STATRALN 0x0BC | ||
| 192 | #define S6_GMAC_STATRALN_SIZE 12 | ||
| 193 | #define S6_GMAC_STATRFLR 0x0C0 | ||
| 194 | #define S6_GMAC_STATRFLR_SIZE 16 | ||
| 195 | #define S6_GMAC_STATRCDE 0x0C4 | ||
| 196 | #define S6_GMAC_STATRCDE_SIZE 12 | ||
| 197 | #define S6_GMAC_STATRCSE 0x0C8 | ||
| 198 | #define S6_GMAC_STATRCSE_SIZE 12 | ||
| 199 | #define S6_GMAC_STATRUND 0x0CC | ||
| 200 | #define S6_GMAC_STATRUND_SIZE 12 | ||
| 201 | #define S6_GMAC_STATROVR 0x0D0 | ||
| 202 | #define S6_GMAC_STATROVR_SIZE 12 | ||
| 203 | #define S6_GMAC_STATRFRG 0x0D4 | ||
| 204 | #define S6_GMAC_STATRFRG_SIZE 12 | ||
| 205 | #define S6_GMAC_STATRJBR 0x0D8 | ||
| 206 | #define S6_GMAC_STATRJBR_SIZE 12 | ||
| 207 | #define S6_GMAC_STATRDRP 0x0DC | ||
| 208 | #define S6_GMAC_STATRDRP_SIZE 12 | ||
| 209 | #define S6_GMAC_STATTBYT 0x0E0 | ||
| 210 | #define S6_GMAC_STATTBYT_SIZE 24 | ||
| 211 | #define S6_GMAC_STATTPKT 0x0E4 | ||
| 212 | #define S6_GMAC_STATTPKT_SIZE 18 | ||
| 213 | #define S6_GMAC_STATTMCA 0x0E8 | ||
| 214 | #define S6_GMAC_STATTMCA_SIZE 18 | ||
| 215 | #define S6_GMAC_STATTBCA 0x0EC | ||
| 216 | #define S6_GMAC_STATTBCA_SIZE 18 | ||
| 217 | #define S6_GMAC_STATTXPF 0x0F0 | ||
| 218 | #define S6_GMAC_STATTXPF_SIZE 12 | ||
| 219 | #define S6_GMAC_STATTDFR 0x0F4 | ||
| 220 | #define S6_GMAC_STATTDFR_SIZE 12 | ||
| 221 | #define S6_GMAC_STATTEDF 0x0F8 | ||
| 222 | #define S6_GMAC_STATTEDF_SIZE 12 | ||
| 223 | #define S6_GMAC_STATTSCL 0x0FC | ||
| 224 | #define S6_GMAC_STATTSCL_SIZE 12 | ||
| 225 | #define S6_GMAC_STATTMCL 0x100 | ||
| 226 | #define S6_GMAC_STATTMCL_SIZE 12 | ||
| 227 | #define S6_GMAC_STATTLCL 0x104 | ||
| 228 | #define S6_GMAC_STATTLCL_SIZE 12 | ||
| 229 | #define S6_GMAC_STATTXCL 0x108 | ||
| 230 | #define S6_GMAC_STATTXCL_SIZE 12 | ||
| 231 | #define S6_GMAC_STATTNCL 0x10C | ||
| 232 | #define S6_GMAC_STATTNCL_SIZE 13 | ||
| 233 | #define S6_GMAC_STATTPFH 0x110 | ||
| 234 | #define S6_GMAC_STATTPFH_SIZE 12 | ||
| 235 | #define S6_GMAC_STATTDRP 0x114 | ||
| 236 | #define S6_GMAC_STATTDRP_SIZE 12 | ||
| 237 | #define S6_GMAC_STATTJBR 0x118 | ||
| 238 | #define S6_GMAC_STATTJBR_SIZE 12 | ||
| 239 | #define S6_GMAC_STATTFCS 0x11C | ||
| 240 | #define S6_GMAC_STATTFCS_SIZE 12 | ||
| 241 | #define S6_GMAC_STATTXCF 0x120 | ||
| 242 | #define S6_GMAC_STATTXCF_SIZE 12 | ||
| 243 | #define S6_GMAC_STATTOVR 0x124 | ||
| 244 | #define S6_GMAC_STATTOVR_SIZE 12 | ||
| 245 | #define S6_GMAC_STATTUND 0x128 | ||
| 246 | #define S6_GMAC_STATTUND_SIZE 12 | ||
| 247 | #define S6_GMAC_STATTFRG 0x12C | ||
| 248 | #define S6_GMAC_STATTFRG_SIZE 12 | ||
| 249 | #define S6_GMAC_STATCARRY(n) (0x130 + 4*(n)) | ||
| 250 | #define S6_GMAC_STATCARRYMSK(n) (0x138 + 4*(n)) | ||
| 251 | #define S6_GMAC_STATCARRY1_RDRP 0 | ||
| 252 | #define S6_GMAC_STATCARRY1_RJBR 1 | ||
| 253 | #define S6_GMAC_STATCARRY1_RFRG 2 | ||
| 254 | #define S6_GMAC_STATCARRY1_ROVR 3 | ||
| 255 | #define S6_GMAC_STATCARRY1_RUND 4 | ||
| 256 | #define S6_GMAC_STATCARRY1_RCSE 5 | ||
| 257 | #define S6_GMAC_STATCARRY1_RCDE 6 | ||
| 258 | #define S6_GMAC_STATCARRY1_RFLR 7 | ||
| 259 | #define S6_GMAC_STATCARRY1_RALN 8 | ||
| 260 | #define S6_GMAC_STATCARRY1_RXUO 9 | ||
| 261 | #define S6_GMAC_STATCARRY1_RXPF 10 | ||
| 262 | #define S6_GMAC_STATCARRY1_RXCF 11 | ||
| 263 | #define S6_GMAC_STATCARRY1_RBCA 12 | ||
| 264 | #define S6_GMAC_STATCARRY1_RMCA 13 | ||
| 265 | #define S6_GMAC_STATCARRY1_RFCS 14 | ||
| 266 | #define S6_GMAC_STATCARRY1_RPKT 15 | ||
| 267 | #define S6_GMAC_STATCARRY1_RBYT 16 | ||
| 268 | #define S6_GMAC_STATCARRY1_TRMGV 25 | ||
| 269 | #define S6_GMAC_STATCARRY1_TRMAX 26 | ||
| 270 | #define S6_GMAC_STATCARRY1_TR1K 27 | ||
| 271 | #define S6_GMAC_STATCARRY1_TR511 28 | ||
| 272 | #define S6_GMAC_STATCARRY1_TR255 29 | ||
| 273 | #define S6_GMAC_STATCARRY1_TR127 30 | ||
| 274 | #define S6_GMAC_STATCARRY1_TR64 31 | ||
| 275 | #define S6_GMAC_STATCARRY2_TDRP 0 | ||
| 276 | #define S6_GMAC_STATCARRY2_TPFH 1 | ||
| 277 | #define S6_GMAC_STATCARRY2_TNCL 2 | ||
| 278 | #define S6_GMAC_STATCARRY2_TXCL 3 | ||
| 279 | #define S6_GMAC_STATCARRY2_TLCL 4 | ||
| 280 | #define S6_GMAC_STATCARRY2_TMCL 5 | ||
| 281 | #define S6_GMAC_STATCARRY2_TSCL 6 | ||
| 282 | #define S6_GMAC_STATCARRY2_TEDF 7 | ||
| 283 | #define S6_GMAC_STATCARRY2_TDFR 8 | ||
| 284 | #define S6_GMAC_STATCARRY2_TXPF 9 | ||
| 285 | #define S6_GMAC_STATCARRY2_TBCA 10 | ||
| 286 | #define S6_GMAC_STATCARRY2_TMCA 11 | ||
| 287 | #define S6_GMAC_STATCARRY2_TPKT 12 | ||
| 288 | #define S6_GMAC_STATCARRY2_TBYT 13 | ||
| 289 | #define S6_GMAC_STATCARRY2_TFRG 14 | ||
| 290 | #define S6_GMAC_STATCARRY2_TUND 15 | ||
| 291 | #define S6_GMAC_STATCARRY2_TOVR 16 | ||
| 292 | #define S6_GMAC_STATCARRY2_TXCF 17 | ||
| 293 | #define S6_GMAC_STATCARRY2_TFCS 18 | ||
| 294 | #define S6_GMAC_STATCARRY2_TJBR 19 | ||
| 295 | |||
| 296 | #define S6_GMAC_HOST_PBLKCTRL 0x140 | ||
| 297 | #define S6_GMAC_HOST_PBLKCTRL_TXENA 0 | ||
| 298 | #define S6_GMAC_HOST_PBLKCTRL_RXENA 1 | ||
| 299 | #define S6_GMAC_HOST_PBLKCTRL_TXSRES 2 | ||
| 300 | #define S6_GMAC_HOST_PBLKCTRL_RXSRES 3 | ||
| 301 | #define S6_GMAC_HOST_PBLKCTRL_TXBSIZ 8 | ||
| 302 | #define S6_GMAC_HOST_PBLKCTRL_RXBSIZ 12 | ||
| 303 | #define S6_GMAC_HOST_PBLKCTRL_SIZ_16 4 | ||
| 304 | #define S6_GMAC_HOST_PBLKCTRL_SIZ_32 5 | ||
| 305 | #define S6_GMAC_HOST_PBLKCTRL_SIZ_64 6 | ||
| 306 | #define S6_GMAC_HOST_PBLKCTRL_SIZ_128 7 | ||
| 307 | #define S6_GMAC_HOST_PBLKCTRL_SIZ_MASK 0xF | ||
| 308 | #define S6_GMAC_HOST_PBLKCTRL_STATENA 16 | ||
| 309 | #define S6_GMAC_HOST_PBLKCTRL_STATAUTOZ 17 | ||
| 310 | #define S6_GMAC_HOST_PBLKCTRL_STATCLEAR 18 | ||
| 311 | #define S6_GMAC_HOST_PBLKCTRL_RGMII 19 | ||
| 312 | #define S6_GMAC_HOST_INTMASK 0x144 | ||
| 313 | #define S6_GMAC_HOST_INTSTAT 0x148 | ||
| 314 | #define S6_GMAC_HOST_INT_TXBURSTOVER 3 | ||
| 315 | #define S6_GMAC_HOST_INT_TXPREWOVER 4 | ||
| 316 | #define S6_GMAC_HOST_INT_RXBURSTUNDER 5 | ||
| 317 | #define S6_GMAC_HOST_INT_RXPOSTRFULL 6 | ||
| 318 | #define S6_GMAC_HOST_INT_RXPOSTRUNDER 7 | ||
| 319 | #define S6_GMAC_HOST_RXFIFOHWM 0x14C | ||
| 320 | #define S6_GMAC_HOST_CTRLFRAMXP 0x150 | ||
| 321 | #define S6_GMAC_HOST_DSTADDRLO(n) (0x160 + 8*(n)) | ||
| 322 | #define S6_GMAC_HOST_DSTADDRHI(n) (0x164 + 8*(n)) | ||
| 323 | #define S6_GMAC_HOST_DSTMASKLO(n) (0x180 + 8*(n)) | ||
| 324 | #define S6_GMAC_HOST_DSTMASKHI(n) (0x184 + 8*(n)) | ||
| 325 | |||
| 326 | #define S6_GMAC_BURST_PREWR 0x1B0 | ||
| 327 | #define S6_GMAC_BURST_PREWR_LEN 0 | ||
| 328 | #define S6_GMAC_BURST_PREWR_LEN_MASK ((1 << 20) - 1) | ||
| 329 | #define S6_GMAC_BURST_PREWR_CFE 20 | ||
| 330 | #define S6_GMAC_BURST_PREWR_PPE 21 | ||
| 331 | #define S6_GMAC_BURST_PREWR_FCS 22 | ||
| 332 | #define S6_GMAC_BURST_PREWR_PAD 23 | ||
| 333 | #define S6_GMAC_BURST_POSTRD 0x1D0 | ||
| 334 | #define S6_GMAC_BURST_POSTRD_LEN 0 | ||
| 335 | #define S6_GMAC_BURST_POSTRD_LEN_MASK ((1 << 20) - 1) | ||
| 336 | #define S6_GMAC_BURST_POSTRD_DROP 20 | ||
| 337 | |||
| 338 | |||
| 339 | /* data handling */ | ||
| 340 | |||
| 341 | #define S6_NUM_TX_SKB 8 /* must be larger than TX fifo size */ | ||
| 342 | #define S6_NUM_RX_SKB 16 | ||
| 343 | #define S6_MAX_FRLEN 1536 | ||
| 344 | |||
| 345 | struct s6gmac { | ||
| 346 | u32 reg; | ||
| 347 | u32 tx_dma; | ||
| 348 | u32 rx_dma; | ||
| 349 | u32 io; | ||
| 350 | u8 tx_chan; | ||
| 351 | u8 rx_chan; | ||
| 352 | spinlock_t lock; | ||
| 353 | u8 tx_skb_i, tx_skb_o; | ||
| 354 | u8 rx_skb_i, rx_skb_o; | ||
| 355 | struct sk_buff *tx_skb[S6_NUM_TX_SKB]; | ||
| 356 | struct sk_buff *rx_skb[S6_NUM_RX_SKB]; | ||
| 357 | unsigned long carry[sizeof(struct net_device_stats) / sizeof(long)]; | ||
| 358 | unsigned long stats[sizeof(struct net_device_stats) / sizeof(long)]; | ||
| 359 | struct phy_device *phydev; | ||
| 360 | struct { | ||
| 361 | struct mii_bus *bus; | ||
| 362 | int irq[PHY_MAX_ADDR]; | ||
| 363 | } mii; | ||
| 364 | struct { | ||
| 365 | unsigned int mbit; | ||
| 366 | u8 giga; | ||
| 367 | u8 isup; | ||
| 368 | u8 full; | ||
| 369 | } link; | ||
| 370 | }; | ||
| 371 | |||
| 372 | static void s6gmac_rx_fillfifo(struct net_device *dev) | ||
| 373 | { | ||
| 374 | struct s6gmac *pd = netdev_priv(dev); | ||
| 375 | struct sk_buff *skb; | ||
| 376 | while ((((u8)(pd->rx_skb_i - pd->rx_skb_o)) < S6_NUM_RX_SKB) && | ||
| 377 | (!s6dmac_fifo_full(pd->rx_dma, pd->rx_chan)) && | ||
| 378 | (skb = netdev_alloc_skb(dev, S6_MAX_FRLEN + 2))) { | ||
| 379 | pd->rx_skb[(pd->rx_skb_i++) % S6_NUM_RX_SKB] = skb; | ||
| 380 | s6dmac_put_fifo_cache(pd->rx_dma, pd->rx_chan, | ||
| 381 | pd->io, (u32)skb->data, S6_MAX_FRLEN); | ||
| 382 | } | ||
| 383 | } | ||
| 384 | |||
| 385 | static void s6gmac_rx_interrupt(struct net_device *dev) | ||
| 386 | { | ||
| 387 | struct s6gmac *pd = netdev_priv(dev); | ||
| 388 | u32 pfx; | ||
| 389 | struct sk_buff *skb; | ||
| 390 | while (((u8)(pd->rx_skb_i - pd->rx_skb_o)) > | ||
| 391 | s6dmac_pending_count(pd->rx_dma, pd->rx_chan)) { | ||
| 392 | skb = pd->rx_skb[(pd->rx_skb_o++) % S6_NUM_RX_SKB]; | ||
| 393 | pfx = readl(pd->reg + S6_GMAC_BURST_POSTRD); | ||
| 394 | if (pfx & (1 << S6_GMAC_BURST_POSTRD_DROP)) { | ||
| 395 | dev_kfree_skb_irq(skb); | ||
| 396 | } else { | ||
| 397 | skb_put(skb, (pfx >> S6_GMAC_BURST_POSTRD_LEN) | ||
| 398 | & S6_GMAC_BURST_POSTRD_LEN_MASK); | ||
| 399 | skb->protocol = eth_type_trans(skb, dev); | ||
| 400 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
| 401 | netif_rx(skb); | ||
| 402 | } | ||
| 403 | } | ||
| 404 | } | ||
| 405 | |||
| 406 | static void s6gmac_tx_interrupt(struct net_device *dev) | ||
| 407 | { | ||
| 408 | struct s6gmac *pd = netdev_priv(dev); | ||
| 409 | while (((u8)(pd->tx_skb_i - pd->tx_skb_o)) > | ||
| 410 | s6dmac_pending_count(pd->tx_dma, pd->tx_chan)) { | ||
| 411 | dev_kfree_skb_irq(pd->tx_skb[(pd->tx_skb_o++) % S6_NUM_TX_SKB]); | ||
| 412 | } | ||
| 413 | if (!s6dmac_fifo_full(pd->tx_dma, pd->tx_chan)) | ||
| 414 | netif_wake_queue(dev); | ||
| 415 | } | ||
| 416 | |||
| 417 | struct s6gmac_statinf { | ||
| 418 | unsigned reg_size : 4; /* 0: unused */ | ||
| 419 | unsigned reg_off : 6; | ||
| 420 | unsigned net_index : 6; | ||
| 421 | }; | ||
| 422 | |||
| 423 | #define S6_STATS_B (8 * sizeof(u32)) | ||
| 424 | #define S6_STATS_C(b, r, f) [b] = { \ | ||
| 425 | BUILD_BUG_ON_ZERO(r##_SIZE < S6_GMAC_STAT_SIZE_MIN) + \ | ||
| 426 | BUILD_BUG_ON_ZERO((r##_SIZE - (S6_GMAC_STAT_SIZE_MIN - 1)) \ | ||
| 427 | >= (1<<4)) + \ | ||
| 428 | r##_SIZE - (S6_GMAC_STAT_SIZE_MIN - 1), \ | ||
| 429 | BUILD_BUG_ON_ZERO(((unsigned)((r - S6_GMAC_STAT_REGS) / sizeof(u32))) \ | ||
| 430 | >= ((1<<6)-1)) + \ | ||
| 431 | (r - S6_GMAC_STAT_REGS) / sizeof(u32), \ | ||
| 432 | BUILD_BUG_ON_ZERO((offsetof(struct net_device_stats, f)) \ | ||
| 433 | % sizeof(unsigned long)) + \ | ||
| 434 | BUILD_BUG_ON_ZERO((((unsigned)(offsetof(struct net_device_stats, f)) \ | ||
| 435 | / sizeof(unsigned long)) >= (1<<6))) + \ | ||
| 436 | BUILD_BUG_ON_ZERO((sizeof(((struct net_device_stats *)0)->f) \ | ||
| 437 | != sizeof(unsigned long))) + \ | ||
| 438 | (offsetof(struct net_device_stats, f)) / sizeof(unsigned long)}, | ||
| 439 | |||
| 440 | static const struct s6gmac_statinf statinf[2][S6_STATS_B] = { { | ||
| 441 | S6_STATS_C(S6_GMAC_STATCARRY1_RBYT, S6_GMAC_STATRBYT, rx_bytes) | ||
| 442 | S6_STATS_C(S6_GMAC_STATCARRY1_RPKT, S6_GMAC_STATRPKT, rx_packets) | ||
| 443 | S6_STATS_C(S6_GMAC_STATCARRY1_RFCS, S6_GMAC_STATRFCS, rx_crc_errors) | ||
| 444 | S6_STATS_C(S6_GMAC_STATCARRY1_RMCA, S6_GMAC_STATRMCA, multicast) | ||
| 445 | S6_STATS_C(S6_GMAC_STATCARRY1_RALN, S6_GMAC_STATRALN, rx_frame_errors) | ||
| 446 | S6_STATS_C(S6_GMAC_STATCARRY1_RFLR, S6_GMAC_STATRFLR, rx_length_errors) | ||
| 447 | S6_STATS_C(S6_GMAC_STATCARRY1_RCDE, S6_GMAC_STATRCDE, rx_missed_errors) | ||
| 448 | S6_STATS_C(S6_GMAC_STATCARRY1_RUND, S6_GMAC_STATRUND, rx_length_errors) | ||
| 449 | S6_STATS_C(S6_GMAC_STATCARRY1_ROVR, S6_GMAC_STATROVR, rx_length_errors) | ||
| 450 | S6_STATS_C(S6_GMAC_STATCARRY1_RFRG, S6_GMAC_STATRFRG, rx_crc_errors) | ||
| 451 | S6_STATS_C(S6_GMAC_STATCARRY1_RJBR, S6_GMAC_STATRJBR, rx_crc_errors) | ||
| 452 | S6_STATS_C(S6_GMAC_STATCARRY1_RDRP, S6_GMAC_STATRDRP, rx_dropped) | ||
| 453 | }, { | ||
| 454 | S6_STATS_C(S6_GMAC_STATCARRY2_TBYT, S6_GMAC_STATTBYT, tx_bytes) | ||
| 455 | S6_STATS_C(S6_GMAC_STATCARRY2_TPKT, S6_GMAC_STATTPKT, tx_packets) | ||
| 456 | S6_STATS_C(S6_GMAC_STATCARRY2_TEDF, S6_GMAC_STATTEDF, tx_aborted_errors) | ||
| 457 | S6_STATS_C(S6_GMAC_STATCARRY2_TXCL, S6_GMAC_STATTXCL, tx_aborted_errors) | ||
| 458 | S6_STATS_C(S6_GMAC_STATCARRY2_TNCL, S6_GMAC_STATTNCL, collisions) | ||
| 459 | S6_STATS_C(S6_GMAC_STATCARRY2_TDRP, S6_GMAC_STATTDRP, tx_dropped) | ||
| 460 | S6_STATS_C(S6_GMAC_STATCARRY2_TJBR, S6_GMAC_STATTJBR, tx_errors) | ||
| 461 | S6_STATS_C(S6_GMAC_STATCARRY2_TFCS, S6_GMAC_STATTFCS, tx_errors) | ||
| 462 | S6_STATS_C(S6_GMAC_STATCARRY2_TOVR, S6_GMAC_STATTOVR, tx_errors) | ||
| 463 | S6_STATS_C(S6_GMAC_STATCARRY2_TUND, S6_GMAC_STATTUND, tx_errors) | ||
| 464 | S6_STATS_C(S6_GMAC_STATCARRY2_TFRG, S6_GMAC_STATTFRG, tx_errors) | ||
| 465 | } }; | ||
| 466 | |||
| 467 | static void s6gmac_stats_collect(struct s6gmac *pd, | ||
| 468 | const struct s6gmac_statinf *inf) | ||
| 469 | { | ||
| 470 | int b; | ||
| 471 | for (b = 0; b < S6_STATS_B; b++) { | ||
| 472 | if (inf[b].reg_size) { | ||
| 473 | pd->stats[inf[b].net_index] += | ||
| 474 | readl(pd->reg + S6_GMAC_STAT_REGS | ||
| 475 | + sizeof(u32) * inf[b].reg_off); | ||
| 476 | } | ||
| 477 | } | ||
| 478 | } | ||
| 479 | |||
| 480 | static void s6gmac_stats_carry(struct s6gmac *pd, | ||
| 481 | const struct s6gmac_statinf *inf, u32 mask) | ||
| 482 | { | ||
| 483 | int b; | ||
| 484 | while (mask) { | ||
| 485 | b = fls(mask) - 1; | ||
| 486 | mask &= ~(1 << b); | ||
| 487 | pd->carry[inf[b].net_index] += (1 << inf[b].reg_size); | ||
| 488 | } | ||
| 489 | } | ||
| 490 | |||
| 491 | static inline u32 s6gmac_stats_pending(struct s6gmac *pd, int carry) | ||
| 492 | { | ||
| 493 | int r = readl(pd->reg + S6_GMAC_STATCARRY(carry)) & | ||
| 494 | ~readl(pd->reg + S6_GMAC_STATCARRYMSK(carry)); | ||
| 495 | return r; | ||
| 496 | } | ||
| 497 | |||
| 498 | static inline void s6gmac_stats_interrupt(struct s6gmac *pd, int carry) | ||
| 499 | { | ||
| 500 | u32 mask; | ||
| 501 | mask = s6gmac_stats_pending(pd, carry); | ||
| 502 | if (mask) { | ||
| 503 | writel(mask, pd->reg + S6_GMAC_STATCARRY(carry)); | ||
| 504 | s6gmac_stats_carry(pd, &statinf[carry][0], mask); | ||
| 505 | } | ||
| 506 | } | ||
| 507 | |||
| 508 | static irqreturn_t s6gmac_interrupt(int irq, void *dev_id) | ||
| 509 | { | ||
| 510 | struct net_device *dev = (struct net_device *)dev_id; | ||
| 511 | struct s6gmac *pd = netdev_priv(dev); | ||
| 512 | if (!dev) | ||
| 513 | return IRQ_NONE; | ||
| 514 | spin_lock(&pd->lock); | ||
| 515 | if (s6dmac_termcnt_irq(pd->rx_dma, pd->rx_chan)) | ||
| 516 | s6gmac_rx_interrupt(dev); | ||
| 517 | s6gmac_rx_fillfifo(dev); | ||
| 518 | if (s6dmac_termcnt_irq(pd->tx_dma, pd->tx_chan)) | ||
| 519 | s6gmac_tx_interrupt(dev); | ||
| 520 | s6gmac_stats_interrupt(pd, 0); | ||
| 521 | s6gmac_stats_interrupt(pd, 1); | ||
| 522 | spin_unlock(&pd->lock); | ||
| 523 | return IRQ_HANDLED; | ||
| 524 | } | ||
| 525 | |||
| 526 | static inline void s6gmac_set_dstaddr(struct s6gmac *pd, int n, | ||
| 527 | u32 addrlo, u32 addrhi, u32 masklo, u32 maskhi) | ||
| 528 | { | ||
| 529 | writel(addrlo, pd->reg + S6_GMAC_HOST_DSTADDRLO(n)); | ||
| 530 | writel(addrhi, pd->reg + S6_GMAC_HOST_DSTADDRHI(n)); | ||
| 531 | writel(masklo, pd->reg + S6_GMAC_HOST_DSTMASKLO(n)); | ||
| 532 | writel(maskhi, pd->reg + S6_GMAC_HOST_DSTMASKHI(n)); | ||
| 533 | } | ||
| 534 | |||
| 535 | static inline void s6gmac_stop_device(struct net_device *dev) | ||
| 536 | { | ||
| 537 | struct s6gmac *pd = netdev_priv(dev); | ||
| 538 | writel(0, pd->reg + S6_GMAC_MACCONF1); | ||
| 539 | } | ||
| 540 | |||
| 541 | static inline void s6gmac_init_device(struct net_device *dev) | ||
| 542 | { | ||
| 543 | struct s6gmac *pd = netdev_priv(dev); | ||
| 544 | int is_rgmii = !!(pd->phydev->supported | ||
| 545 | & (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half)); | ||
| 546 | #if 0 | ||
| 547 | writel(1 << S6_GMAC_MACCONF1_SYNCTX | | ||
| 548 | 1 << S6_GMAC_MACCONF1_SYNCRX | | ||
| 549 | 1 << S6_GMAC_MACCONF1_TXFLOWCTRL | | ||
| 550 | 1 << S6_GMAC_MACCONF1_RXFLOWCTRL | | ||
| 551 | 1 << S6_GMAC_MACCONF1_RESTXFUNC | | ||
| 552 | 1 << S6_GMAC_MACCONF1_RESRXFUNC | | ||
| 553 | 1 << S6_GMAC_MACCONF1_RESTXMACCTRL | | ||
| 554 | 1 << S6_GMAC_MACCONF1_RESRXMACCTRL, | ||
| 555 | pd->reg + S6_GMAC_MACCONF1); | ||
| 556 | #endif | ||
| 557 | writel(1 << S6_GMAC_MACCONF1_SOFTRES, pd->reg + S6_GMAC_MACCONF1); | ||
| 558 | udelay(1000); | ||
| 559 | writel(1 << S6_GMAC_MACCONF1_TXENA | 1 << S6_GMAC_MACCONF1_RXENA, | ||
| 560 | pd->reg + S6_GMAC_MACCONF1); | ||
| 561 | writel(1 << S6_GMAC_HOST_PBLKCTRL_TXSRES | | ||
| 562 | 1 << S6_GMAC_HOST_PBLKCTRL_RXSRES, | ||
| 563 | pd->reg + S6_GMAC_HOST_PBLKCTRL); | ||
| 564 | writel(S6_GMAC_HOST_PBLKCTRL_SIZ_128 << S6_GMAC_HOST_PBLKCTRL_TXBSIZ | | ||
| 565 | S6_GMAC_HOST_PBLKCTRL_SIZ_128 << S6_GMAC_HOST_PBLKCTRL_RXBSIZ | | ||
| 566 | 1 << S6_GMAC_HOST_PBLKCTRL_STATENA | | ||
| 567 | 1 << S6_GMAC_HOST_PBLKCTRL_STATCLEAR | | ||
| 568 | is_rgmii << S6_GMAC_HOST_PBLKCTRL_RGMII, | ||
| 569 | pd->reg + S6_GMAC_HOST_PBLKCTRL); | ||
| 570 | writel(1 << S6_GMAC_MACCONF1_TXENA | | ||
| 571 | 1 << S6_GMAC_MACCONF1_RXENA | | ||
| 572 | (dev->flags & IFF_LOOPBACK ? 1 : 0) | ||
| 573 | << S6_GMAC_MACCONF1_LOOPBACK, | ||
| 574 | pd->reg + S6_GMAC_MACCONF1); | ||
| 575 | writel(dev->mtu && (dev->mtu < (S6_MAX_FRLEN - ETH_HLEN-ETH_FCS_LEN)) ? | ||
| 576 | dev->mtu+ETH_HLEN+ETH_FCS_LEN : S6_MAX_FRLEN, | ||
| 577 | pd->reg + S6_GMAC_MACMAXFRAMELEN); | ||
| 578 | writel((pd->link.full ? 1 : 0) << S6_GMAC_MACCONF2_FULL | | ||
| 579 | 1 << S6_GMAC_MACCONF2_PADCRCENA | | ||
| 580 | 1 << S6_GMAC_MACCONF2_LENGTHFCHK | | ||
| 581 | (pd->link.giga ? | ||
| 582 | S6_GMAC_MACCONF2_IFMODE_BYTE : | ||
| 583 | S6_GMAC_MACCONF2_IFMODE_NIBBLE) | ||
| 584 | << S6_GMAC_MACCONF2_IFMODE | | ||
| 585 | 7 << S6_GMAC_MACCONF2_PREAMBLELEN, | ||
| 586 | pd->reg + S6_GMAC_MACCONF2); | ||
| 587 | writel(0, pd->reg + S6_GMAC_MACSTATADDR1); | ||
| 588 | writel(0, pd->reg + S6_GMAC_MACSTATADDR2); | ||
| 589 | writel(1 << S6_GMAC_FIFOCONF0_WTMENREQ | | ||
| 590 | 1 << S6_GMAC_FIFOCONF0_SRFENREQ | | ||
| 591 | 1 << S6_GMAC_FIFOCONF0_FRFENREQ | | ||
| 592 | 1 << S6_GMAC_FIFOCONF0_STFENREQ | | ||
| 593 | 1 << S6_GMAC_FIFOCONF0_FTFENREQ, | ||
| 594 | pd->reg + S6_GMAC_FIFOCONF0); | ||
| 595 | writel(128 << S6_GMAC_FIFOCONF3_CFGFTTH | | ||
| 596 | 128 << S6_GMAC_FIFOCONF3_CFGHWMFT, | ||
| 597 | pd->reg + S6_GMAC_FIFOCONF3); | ||
| 598 | writel((S6_GMAC_FIFOCONF_RSV_MASK & ~( | ||
| 599 | 1 << S6_GMAC_FIFOCONF_RSV_RUNT | | ||
| 600 | 1 << S6_GMAC_FIFOCONF_RSV_CRCERR | | ||
| 601 | 1 << S6_GMAC_FIFOCONF_RSV_OK | | ||
| 602 | 1 << S6_GMAC_FIFOCONF_RSV_DRIBBLE | | ||
| 603 | 1 << S6_GMAC_FIFOCONF_RSV_CTRLFRAME | | ||
| 604 | 1 << S6_GMAC_FIFOCONF_RSV_PAUSECTRL | | ||
| 605 | 1 << S6_GMAC_FIFOCONF_RSV_UNOPCODE | | ||
| 606 | 1 << S6_GMAC_FIFOCONF_RSV_TRUNCATED)) | | ||
| 607 | 1 << S6_GMAC_FIFOCONF5_DROPLT64 | | ||
| 608 | pd->link.giga << S6_GMAC_FIFOCONF5_CFGBYTM | | ||
| 609 | 1 << S6_GMAC_FIFOCONF5_RXDROPSIZE, | ||
| 610 | pd->reg + S6_GMAC_FIFOCONF5); | ||
| 611 | writel(1 << S6_GMAC_FIFOCONF_RSV_RUNT | | ||
| 612 | 1 << S6_GMAC_FIFOCONF_RSV_CRCERR | | ||
| 613 | 1 << S6_GMAC_FIFOCONF_RSV_DRIBBLE | | ||
| 614 | 1 << S6_GMAC_FIFOCONF_RSV_CTRLFRAME | | ||
| 615 | 1 << S6_GMAC_FIFOCONF_RSV_PAUSECTRL | | ||
| 616 | 1 << S6_GMAC_FIFOCONF_RSV_UNOPCODE | | ||
| 617 | 1 << S6_GMAC_FIFOCONF_RSV_TRUNCATED, | ||
| 618 | pd->reg + S6_GMAC_FIFOCONF4); | ||
| 619 | s6gmac_set_dstaddr(pd, 0, | ||
| 620 | 0xFFFFFFFF, 0x0000FFFF, 0xFFFFFFFF, 0x0000FFFF); | ||
| 621 | s6gmac_set_dstaddr(pd, 1, | ||
| 622 | dev->dev_addr[5] | | ||
| 623 | dev->dev_addr[4] << 8 | | ||
| 624 | dev->dev_addr[3] << 16 | | ||
| 625 | dev->dev_addr[2] << 24, | ||
| 626 | dev->dev_addr[1] | | ||
| 627 | dev->dev_addr[0] << 8, | ||
| 628 | 0xFFFFFFFF, 0x0000FFFF); | ||
| 629 | s6gmac_set_dstaddr(pd, 2, | ||
| 630 | 0x00000000, 0x00000100, 0x00000000, 0x00000100); | ||
| 631 | s6gmac_set_dstaddr(pd, 3, | ||
| 632 | 0x00000000, 0x00000000, 0x00000000, 0x00000000); | ||
| 633 | writel(1 << S6_GMAC_HOST_PBLKCTRL_TXENA | | ||
| 634 | 1 << S6_GMAC_HOST_PBLKCTRL_RXENA | | ||
| 635 | S6_GMAC_HOST_PBLKCTRL_SIZ_128 << S6_GMAC_HOST_PBLKCTRL_TXBSIZ | | ||
| 636 | S6_GMAC_HOST_PBLKCTRL_SIZ_128 << S6_GMAC_HOST_PBLKCTRL_RXBSIZ | | ||
| 637 | 1 << S6_GMAC_HOST_PBLKCTRL_STATENA | | ||
| 638 | 1 << S6_GMAC_HOST_PBLKCTRL_STATCLEAR | | ||
| 639 | is_rgmii << S6_GMAC_HOST_PBLKCTRL_RGMII, | ||
| 640 | pd->reg + S6_GMAC_HOST_PBLKCTRL); | ||
| 641 | } | ||
| 642 | |||
| 643 | static void s6mii_enable(struct s6gmac *pd) | ||
| 644 | { | ||
| 645 | writel(readl(pd->reg + S6_GMAC_MACCONF1) & | ||
| 646 | ~(1 << S6_GMAC_MACCONF1_SOFTRES), | ||
| 647 | pd->reg + S6_GMAC_MACCONF1); | ||
| 648 | writel((readl(pd->reg + S6_GMAC_MACMIICONF) | ||
| 649 | & ~(S6_GMAC_MACMIICONF_CSEL_MASK << S6_GMAC_MACMIICONF_CSEL)) | ||
| 650 | | (S6_GMAC_MACMIICONF_CSEL_DIV168 << S6_GMAC_MACMIICONF_CSEL), | ||
| 651 | pd->reg + S6_GMAC_MACMIICONF); | ||
| 652 | } | ||
| 653 | |||
| 654 | static int s6mii_busy(struct s6gmac *pd, int tmo) | ||
| 655 | { | ||
| 656 | while (readl(pd->reg + S6_GMAC_MACMIIINDI)) { | ||
| 657 | if (--tmo == 0) | ||
| 658 | return -ETIME; | ||
| 659 | udelay(64); | ||
| 660 | } | ||
| 661 | return 0; | ||
| 662 | } | ||
| 663 | |||
| 664 | static int s6mii_read(struct mii_bus *bus, int phy_addr, int regnum) | ||
| 665 | { | ||
| 666 | struct s6gmac *pd = bus->priv; | ||
| 667 | s6mii_enable(pd); | ||
| 668 | if (s6mii_busy(pd, 256)) | ||
| 669 | return -ETIME; | ||
| 670 | writel(phy_addr << S6_GMAC_MACMIIADDR_PHY | | ||
| 671 | regnum << S6_GMAC_MACMIIADDR_REG, | ||
| 672 | pd->reg + S6_GMAC_MACMIIADDR); | ||
| 673 | writel(1 << S6_GMAC_MACMIICMD_READ, pd->reg + S6_GMAC_MACMIICMD); | ||
| 674 | writel(0, pd->reg + S6_GMAC_MACMIICMD); | ||
| 675 | if (s6mii_busy(pd, 256)) | ||
| 676 | return -ETIME; | ||
| 677 | return (u16)readl(pd->reg + S6_GMAC_MACMIISTAT); | ||
| 678 | } | ||
| 679 | |||
| 680 | static int s6mii_write(struct mii_bus *bus, int phy_addr, int regnum, u16 value) | ||
| 681 | { | ||
| 682 | struct s6gmac *pd = bus->priv; | ||
| 683 | s6mii_enable(pd); | ||
| 684 | if (s6mii_busy(pd, 256)) | ||
| 685 | return -ETIME; | ||
| 686 | writel(phy_addr << S6_GMAC_MACMIIADDR_PHY | | ||
| 687 | regnum << S6_GMAC_MACMIIADDR_REG, | ||
| 688 | pd->reg + S6_GMAC_MACMIIADDR); | ||
| 689 | writel(value, pd->reg + S6_GMAC_MACMIICTRL); | ||
| 690 | if (s6mii_busy(pd, 256)) | ||
| 691 | return -ETIME; | ||
| 692 | return 0; | ||
| 693 | } | ||
| 694 | |||
| 695 | static int s6mii_reset(struct mii_bus *bus) | ||
| 696 | { | ||
| 697 | struct s6gmac *pd = bus->priv; | ||
| 698 | s6mii_enable(pd); | ||
| 699 | if (s6mii_busy(pd, PHY_INIT_TIMEOUT)) | ||
| 700 | return -ETIME; | ||
| 701 | return 0; | ||
| 702 | } | ||
| 703 | |||
| 704 | static void s6gmac_set_rgmii_txclock(struct s6gmac *pd) | ||
| 705 | { | ||
| 706 | u32 pllsel = readl(S6_REG_GREG1 + S6_GREG1_PLLSEL); | ||
| 707 | pllsel &= ~(S6_GREG1_PLLSEL_GMAC_MASK << S6_GREG1_PLLSEL_GMAC); | ||
| 708 | switch (pd->link.mbit) { | ||
| 709 | case 10: | ||
| 710 | pllsel |= S6_GREG1_PLLSEL_GMAC_2500KHZ << S6_GREG1_PLLSEL_GMAC; | ||
| 711 | break; | ||
| 712 | case 100: | ||
| 713 | pllsel |= S6_GREG1_PLLSEL_GMAC_25MHZ << S6_GREG1_PLLSEL_GMAC; | ||
| 714 | break; | ||
| 715 | case 1000: | ||
| 716 | pllsel |= S6_GREG1_PLLSEL_GMAC_125MHZ << S6_GREG1_PLLSEL_GMAC; | ||
| 717 | break; | ||
| 718 | default: | ||
| 719 | return; | ||
| 720 | } | ||
| 721 | writel(pllsel, S6_REG_GREG1 + S6_GREG1_PLLSEL); | ||
| 722 | } | ||
| 723 | |||
| 724 | static inline void s6gmac_linkisup(struct net_device *dev, int isup) | ||
| 725 | { | ||
| 726 | struct s6gmac *pd = netdev_priv(dev); | ||
| 727 | struct phy_device *phydev = pd->phydev; | ||
| 728 | |||
| 729 | pd->link.full = phydev->duplex; | ||
| 730 | pd->link.giga = (phydev->speed == 1000); | ||
| 731 | if (pd->link.mbit != phydev->speed) { | ||
| 732 | pd->link.mbit = phydev->speed; | ||
| 733 | s6gmac_set_rgmii_txclock(pd); | ||
| 734 | } | ||
| 735 | pd->link.isup = isup; | ||
| 736 | if (isup) | ||
| 737 | netif_carrier_on(dev); | ||
| 738 | phy_print_status(phydev); | ||
| 739 | } | ||
| 740 | |||
| 741 | static void s6gmac_adjust_link(struct net_device *dev) | ||
| 742 | { | ||
| 743 | struct s6gmac *pd = netdev_priv(dev); | ||
| 744 | struct phy_device *phydev = pd->phydev; | ||
| 745 | if (pd->link.isup && | ||
| 746 | (!phydev->link || | ||
| 747 | (pd->link.mbit != phydev->speed) || | ||
| 748 | (pd->link.full != phydev->duplex))) { | ||
| 749 | pd->link.isup = 0; | ||
| 750 | netif_tx_disable(dev); | ||
| 751 | if (!phydev->link) { | ||
| 752 | netif_carrier_off(dev); | ||
| 753 | phy_print_status(phydev); | ||
| 754 | } | ||
| 755 | } | ||
| 756 | if (!pd->link.isup && phydev->link) { | ||
| 757 | if (pd->link.full != phydev->duplex) { | ||
| 758 | u32 maccfg = readl(pd->reg + S6_GMAC_MACCONF2); | ||
| 759 | if (phydev->duplex) | ||
| 760 | maccfg |= 1 << S6_GMAC_MACCONF2_FULL; | ||
| 761 | else | ||
| 762 | maccfg &= ~(1 << S6_GMAC_MACCONF2_FULL); | ||
| 763 | writel(maccfg, pd->reg + S6_GMAC_MACCONF2); | ||
| 764 | } | ||
| 765 | |||
| 766 | if (pd->link.giga != (phydev->speed == 1000)) { | ||
| 767 | u32 fifocfg = readl(pd->reg + S6_GMAC_FIFOCONF5); | ||
| 768 | u32 maccfg = readl(pd->reg + S6_GMAC_MACCONF2); | ||
| 769 | maccfg &= ~(S6_GMAC_MACCONF2_IFMODE_MASK | ||
| 770 | << S6_GMAC_MACCONF2_IFMODE); | ||
| 771 | if (phydev->speed == 1000) { | ||
| 772 | fifocfg |= 1 << S6_GMAC_FIFOCONF5_CFGBYTM; | ||
| 773 | maccfg |= S6_GMAC_MACCONF2_IFMODE_BYTE | ||
| 774 | << S6_GMAC_MACCONF2_IFMODE; | ||
| 775 | } else { | ||
| 776 | fifocfg &= ~(1 << S6_GMAC_FIFOCONF5_CFGBYTM); | ||
| 777 | maccfg |= S6_GMAC_MACCONF2_IFMODE_NIBBLE | ||
| 778 | << S6_GMAC_MACCONF2_IFMODE; | ||
| 779 | } | ||
| 780 | writel(fifocfg, pd->reg + S6_GMAC_FIFOCONF5); | ||
| 781 | writel(maccfg, pd->reg + S6_GMAC_MACCONF2); | ||
| 782 | } | ||
| 783 | |||
| 784 | if (!s6dmac_fifo_full(pd->tx_dma, pd->tx_chan)) | ||
| 785 | netif_wake_queue(dev); | ||
| 786 | s6gmac_linkisup(dev, 1); | ||
| 787 | } | ||
| 788 | } | ||
| 789 | |||
| 790 | static inline int s6gmac_phy_start(struct net_device *dev) | ||
| 791 | { | ||
| 792 | struct s6gmac *pd = netdev_priv(dev); | ||
| 793 | int i = 0; | ||
| 794 | struct phy_device *p = NULL; | ||
| 795 | while ((i < PHY_MAX_ADDR) && (!(p = pd->mii.bus->phy_map[i]))) | ||
| 796 | i++; | ||
| 797 | p = phy_connect(dev, dev_name(&p->dev), &s6gmac_adjust_link, | ||
| 798 | PHY_INTERFACE_MODE_RGMII); | ||
| 799 | if (IS_ERR(p)) { | ||
| 800 | printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); | ||
| 801 | return PTR_ERR(p); | ||
| 802 | } | ||
| 803 | p->supported &= PHY_GBIT_FEATURES; | ||
| 804 | p->advertising = p->supported; | ||
| 805 | pd->phydev = p; | ||
| 806 | return 0; | ||
| 807 | } | ||
| 808 | |||
| 809 | static inline void s6gmac_init_stats(struct net_device *dev) | ||
| 810 | { | ||
| 811 | struct s6gmac *pd = netdev_priv(dev); | ||
| 812 | u32 mask; | ||
| 813 | mask = 1 << S6_GMAC_STATCARRY1_RDRP | | ||
| 814 | 1 << S6_GMAC_STATCARRY1_RJBR | | ||
| 815 | 1 << S6_GMAC_STATCARRY1_RFRG | | ||
| 816 | 1 << S6_GMAC_STATCARRY1_ROVR | | ||
| 817 | 1 << S6_GMAC_STATCARRY1_RUND | | ||
| 818 | 1 << S6_GMAC_STATCARRY1_RCDE | | ||
| 819 | 1 << S6_GMAC_STATCARRY1_RFLR | | ||
| 820 | 1 << S6_GMAC_STATCARRY1_RALN | | ||
| 821 | 1 << S6_GMAC_STATCARRY1_RMCA | | ||
| 822 | 1 << S6_GMAC_STATCARRY1_RFCS | | ||
| 823 | 1 << S6_GMAC_STATCARRY1_RPKT | | ||
| 824 | 1 << S6_GMAC_STATCARRY1_RBYT; | ||
| 825 | writel(mask, pd->reg + S6_GMAC_STATCARRY(0)); | ||
| 826 | writel(~mask, pd->reg + S6_GMAC_STATCARRYMSK(0)); | ||
| 827 | mask = 1 << S6_GMAC_STATCARRY2_TDRP | | ||
| 828 | 1 << S6_GMAC_STATCARRY2_TNCL | | ||
| 829 | 1 << S6_GMAC_STATCARRY2_TXCL | | ||
| 830 | 1 << S6_GMAC_STATCARRY2_TEDF | | ||
| 831 | 1 << S6_GMAC_STATCARRY2_TPKT | | ||
| 832 | 1 << S6_GMAC_STATCARRY2_TBYT | | ||
| 833 | 1 << S6_GMAC_STATCARRY2_TFRG | | ||
| 834 | 1 << S6_GMAC_STATCARRY2_TUND | | ||
| 835 | 1 << S6_GMAC_STATCARRY2_TOVR | | ||
| 836 | 1 << S6_GMAC_STATCARRY2_TFCS | | ||
| 837 | 1 << S6_GMAC_STATCARRY2_TJBR; | ||
| 838 | writel(mask, pd->reg + S6_GMAC_STATCARRY(1)); | ||
| 839 | writel(~mask, pd->reg + S6_GMAC_STATCARRYMSK(1)); | ||
| 840 | } | ||
| 841 | |||
| 842 | static inline void s6gmac_init_dmac(struct net_device *dev) | ||
| 843 | { | ||
| 844 | struct s6gmac *pd = netdev_priv(dev); | ||
| 845 | s6dmac_disable_chan(pd->tx_dma, pd->tx_chan); | ||
| 846 | s6dmac_disable_chan(pd->rx_dma, pd->rx_chan); | ||
| 847 | s6dmac_disable_error_irqs(pd->tx_dma, 1 << S6_HIFDMA_GMACTX); | ||
| 848 | s6dmac_disable_error_irqs(pd->rx_dma, 1 << S6_HIFDMA_GMACRX); | ||
| 849 | } | ||
| 850 | |||
| 851 | static int s6gmac_tx(struct sk_buff *skb, struct net_device *dev) | ||
| 852 | { | ||
| 853 | struct s6gmac *pd = netdev_priv(dev); | ||
| 854 | unsigned long flags; | ||
| 855 | |||
| 856 | spin_lock_irqsave(&pd->lock, flags); | ||
| 857 | writel(skb->len << S6_GMAC_BURST_PREWR_LEN | | ||
| 858 | 0 << S6_GMAC_BURST_PREWR_CFE | | ||
| 859 | 1 << S6_GMAC_BURST_PREWR_PPE | | ||
| 860 | 1 << S6_GMAC_BURST_PREWR_FCS | | ||
| 861 | ((skb->len < ETH_ZLEN) ? 1 : 0) << S6_GMAC_BURST_PREWR_PAD, | ||
| 862 | pd->reg + S6_GMAC_BURST_PREWR); | ||
| 863 | s6dmac_put_fifo_cache(pd->tx_dma, pd->tx_chan, | ||
| 864 | (u32)skb->data, pd->io, skb->len); | ||
| 865 | if (s6dmac_fifo_full(pd->tx_dma, pd->tx_chan)) | ||
| 866 | netif_stop_queue(dev); | ||
| 867 | if (((u8)(pd->tx_skb_i - pd->tx_skb_o)) >= S6_NUM_TX_SKB) { | ||
| 868 | printk(KERN_ERR "GMAC BUG: skb tx ring overflow [%x, %x]\n", | ||
| 869 | pd->tx_skb_o, pd->tx_skb_i); | ||
| 870 | BUG(); | ||
| 871 | } | ||
| 872 | pd->tx_skb[(pd->tx_skb_i++) % S6_NUM_TX_SKB] = skb; | ||
| 873 | spin_unlock_irqrestore(&pd->lock, flags); | ||
| 874 | return 0; | ||
| 875 | } | ||
| 876 | |||
| 877 | static void s6gmac_tx_timeout(struct net_device *dev) | ||
| 878 | { | ||
| 879 | struct s6gmac *pd = netdev_priv(dev); | ||
| 880 | unsigned long flags; | ||
| 881 | spin_lock_irqsave(&pd->lock, flags); | ||
| 882 | s6gmac_tx_interrupt(dev); | ||
| 883 | spin_unlock_irqrestore(&pd->lock, flags); | ||
| 884 | } | ||
| 885 | |||
| 886 | static int s6gmac_open(struct net_device *dev) | ||
| 887 | { | ||
| 888 | struct s6gmac *pd = netdev_priv(dev); | ||
| 889 | unsigned long flags; | ||
| 890 | phy_read_status(pd->phydev); | ||
| 891 | spin_lock_irqsave(&pd->lock, flags); | ||
| 892 | pd->link.mbit = 0; | ||
| 893 | s6gmac_linkisup(dev, pd->phydev->link); | ||
| 894 | s6gmac_init_device(dev); | ||
| 895 | s6gmac_init_stats(dev); | ||
| 896 | s6gmac_init_dmac(dev); | ||
| 897 | s6gmac_rx_fillfifo(dev); | ||
| 898 | s6dmac_enable_chan(pd->rx_dma, pd->rx_chan, | ||
| 899 | 2, 1, 0, 1, 0, 0, 0, 7, -1, 2, 0, 1); | ||
| 900 | s6dmac_enable_chan(pd->tx_dma, pd->tx_chan, | ||
| 901 | 2, 0, 1, 0, 0, 0, 0, 7, -1, 2, 0, 1); | ||
| 902 | writel(0 << S6_GMAC_HOST_INT_TXBURSTOVER | | ||
| 903 | 0 << S6_GMAC_HOST_INT_TXPREWOVER | | ||
| 904 | 0 << S6_GMAC_HOST_INT_RXBURSTUNDER | | ||
| 905 | 0 << S6_GMAC_HOST_INT_RXPOSTRFULL | | ||
| 906 | 0 << S6_GMAC_HOST_INT_RXPOSTRUNDER, | ||
| 907 | pd->reg + S6_GMAC_HOST_INTMASK); | ||
| 908 | spin_unlock_irqrestore(&pd->lock, flags); | ||
| 909 | phy_start(pd->phydev); | ||
| 910 | netif_start_queue(dev); | ||
| 911 | return 0; | ||
| 912 | } | ||
| 913 | |||
| 914 | static int s6gmac_stop(struct net_device *dev) | ||
| 915 | { | ||
| 916 | struct s6gmac *pd = netdev_priv(dev); | ||
| 917 | unsigned long flags; | ||
| 918 | netif_stop_queue(dev); | ||
| 919 | phy_stop(pd->phydev); | ||
| 920 | spin_lock_irqsave(&pd->lock, flags); | ||
| 921 | s6gmac_init_dmac(dev); | ||
| 922 | s6gmac_stop_device(dev); | ||
| 923 | while (pd->tx_skb_i != pd->tx_skb_o) | ||
| 924 | dev_kfree_skb(pd->tx_skb[(pd->tx_skb_o++) % S6_NUM_TX_SKB]); | ||
| 925 | while (pd->rx_skb_i != pd->rx_skb_o) | ||
| 926 | dev_kfree_skb(pd->rx_skb[(pd->rx_skb_o++) % S6_NUM_RX_SKB]); | ||
| 927 | spin_unlock_irqrestore(&pd->lock, flags); | ||
| 928 | return 0; | ||
| 929 | } | ||
| 930 | |||
| 931 | static struct net_device_stats *s6gmac_stats(struct net_device *dev) | ||
| 932 | { | ||
| 933 | struct s6gmac *pd = netdev_priv(dev); | ||
| 934 | struct net_device_stats *st = (struct net_device_stats *)&pd->stats; | ||
| 935 | int i; | ||
| 936 | do { | ||
| 937 | unsigned long flags; | ||
| 938 | spin_lock_irqsave(&pd->lock, flags); | ||
| 939 | for (i = 0; i < ARRAY_SIZE(pd->stats); i++) | ||
| 940 | pd->stats[i] = | ||
| 941 | pd->carry[i] << (S6_GMAC_STAT_SIZE_MIN - 1); | ||
| 942 | s6gmac_stats_collect(pd, &statinf[0][0]); | ||
| 943 | s6gmac_stats_collect(pd, &statinf[1][0]); | ||
| 944 | i = s6gmac_stats_pending(pd, 0) | | ||
| 945 | s6gmac_stats_pending(pd, 1); | ||
| 946 | spin_unlock_irqrestore(&pd->lock, flags); | ||
| 947 | } while (i); | ||
| 948 | st->rx_errors = st->rx_crc_errors + | ||
| 949 | st->rx_frame_errors + | ||
| 950 | st->rx_length_errors + | ||
| 951 | st->rx_missed_errors; | ||
| 952 | st->tx_errors += st->tx_aborted_errors; | ||
| 953 | return st; | ||
| 954 | } | ||
| 955 | |||
| 956 | static int s6gmac_probe(struct platform_device *pdev) | ||
| 957 | { | ||
| 958 | struct net_device *dev; | ||
| 959 | struct s6gmac *pd; | ||
| 960 | int res; | ||
| 961 | unsigned long i; | ||
| 962 | struct mii_bus *mb; | ||
| 963 | |||
| 964 | dev = alloc_etherdev(sizeof(*pd)); | ||
| 965 | if (!dev) | ||
| 966 | return -ENOMEM; | ||
| 967 | |||
| 968 | dev->open = s6gmac_open; | ||
| 969 | dev->stop = s6gmac_stop; | ||
| 970 | dev->hard_start_xmit = s6gmac_tx; | ||
| 971 | dev->tx_timeout = s6gmac_tx_timeout; | ||
| 972 | dev->watchdog_timeo = HZ; | ||
| 973 | dev->get_stats = s6gmac_stats; | ||
| 974 | dev->irq = platform_get_irq(pdev, 0); | ||
| 975 | pd = netdev_priv(dev); | ||
| 976 | memset(pd, 0, sizeof(*pd)); | ||
| 977 | spin_lock_init(&pd->lock); | ||
| 978 | pd->reg = platform_get_resource(pdev, IORESOURCE_MEM, 0)->start; | ||
| 979 | i = platform_get_resource(pdev, IORESOURCE_DMA, 0)->start; | ||
| 980 | pd->tx_dma = DMA_MASK_DMAC(i); | ||
| 981 | pd->tx_chan = DMA_INDEX_CHNL(i); | ||
| 982 | i = platform_get_resource(pdev, IORESOURCE_DMA, 1)->start; | ||
| 983 | pd->rx_dma = DMA_MASK_DMAC(i); | ||
| 984 | pd->rx_chan = DMA_INDEX_CHNL(i); | ||
| 985 | pd->io = platform_get_resource(pdev, IORESOURCE_IO, 0)->start; | ||
| 986 | res = request_irq(dev->irq, s6gmac_interrupt, 0, dev->name, dev); | ||
| 987 | if (res) { | ||
| 988 | printk(KERN_ERR DRV_PRMT "irq request failed: %d\n", dev->irq); | ||
| 989 | goto errirq; | ||
| 990 | } | ||
| 991 | res = register_netdev(dev); | ||
| 992 | if (res) { | ||
| 993 | printk(KERN_ERR DRV_PRMT "error registering device %s\n", | ||
| 994 | dev->name); | ||
| 995 | goto errdev; | ||
| 996 | } | ||
| 997 | mb = mdiobus_alloc(); | ||
| 998 | if (!mb) { | ||
| 999 | printk(KERN_ERR DRV_PRMT "error allocating mii bus\n"); | ||
| 1000 | res = -ENOMEM; | ||
| 1001 | goto errmii; | ||
| 1002 | } | ||
| 1003 | mb->name = "s6gmac_mii"; | ||
| 1004 | mb->read = s6mii_read; | ||
| 1005 | mb->write = s6mii_write; | ||
| 1006 | mb->reset = s6mii_reset; | ||
| 1007 | mb->priv = pd; | ||
| 1008 | snprintf(mb->id, MII_BUS_ID_SIZE, "%s-%x", pdev->name, pdev->id); | ||
| 1009 | mb->phy_mask = ~(1 << 0); | ||
| 1010 | mb->irq = &pd->mii.irq[0]; | ||
| 1011 | for (i = 0; i < PHY_MAX_ADDR; i++) { | ||
| 1012 | int n = platform_get_irq(pdev, i + 1); | ||
| 1013 | if (n < 0) | ||
| 1014 | n = PHY_POLL; | ||
| 1015 | pd->mii.irq[i] = n; | ||
| 1016 | } | ||
| 1017 | mdiobus_register(mb); | ||
| 1018 | pd->mii.bus = mb; | ||
| 1019 | res = s6gmac_phy_start(dev); | ||
| 1020 | if (res) | ||
| 1021 | return res; | ||
| 1022 | platform_set_drvdata(pdev, dev); | ||
| 1023 | return 0; | ||
| 1024 | errmii: | ||
| 1025 | unregister_netdev(dev); | ||
| 1026 | errdev: | ||
| 1027 | free_irq(dev->irq, dev); | ||
| 1028 | errirq: | ||
| 1029 | free_netdev(dev); | ||
| 1030 | return res; | ||
| 1031 | } | ||
| 1032 | |||
| 1033 | static int s6gmac_remove(struct platform_device *pdev) | ||
| 1034 | { | ||
| 1035 | struct net_device *dev = platform_get_drvdata(pdev); | ||
| 1036 | if (dev) { | ||
| 1037 | struct s6gmac *pd = netdev_priv(dev); | ||
| 1038 | mdiobus_unregister(pd->mii.bus); | ||
| 1039 | unregister_netdev(dev); | ||
| 1040 | free_irq(dev->irq, dev); | ||
| 1041 | free_netdev(dev); | ||
| 1042 | } | ||
| 1043 | return 0; | ||
| 1044 | } | ||
| 1045 | |||
| 1046 | static struct platform_driver s6gmac_driver = { | ||
| 1047 | .probe = s6gmac_probe, | ||
| 1048 | .remove = s6gmac_remove, | ||
| 1049 | .driver = { | ||
| 1050 | .name = "s6gmac", | ||
| 1051 | }, | ||
| 1052 | }; | ||
| 1053 | |||
| 1054 | module_platform_driver(s6gmac_driver); | ||
| 1055 | |||
| 1056 | MODULE_LICENSE("GPL"); | ||
| 1057 | MODULE_DESCRIPTION("S6105 on chip Ethernet driver"); | ||
| 1058 | MODULE_AUTHOR("Oskar Schirmer <oskar@scara.com>"); | ||
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 118a427d1942..8c6b7c1651e5 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | |||
| @@ -1671,7 +1671,7 @@ static void stmmac_init_tx_coalesce(struct stmmac_priv *priv) | |||
| 1671 | * 0 on success and an appropriate (-)ve integer as defined in errno.h | 1671 | * 0 on success and an appropriate (-)ve integer as defined in errno.h |
| 1672 | * file on failure. | 1672 | * file on failure. |
| 1673 | */ | 1673 | */ |
| 1674 | static int stmmac_hw_setup(struct net_device *dev) | 1674 | static int stmmac_hw_setup(struct net_device *dev, bool init_ptp) |
| 1675 | { | 1675 | { |
| 1676 | struct stmmac_priv *priv = netdev_priv(dev); | 1676 | struct stmmac_priv *priv = netdev_priv(dev); |
| 1677 | int ret; | 1677 | int ret; |
| @@ -1708,9 +1708,11 @@ static int stmmac_hw_setup(struct net_device *dev) | |||
| 1708 | 1708 | ||
| 1709 | stmmac_mmc_setup(priv); | 1709 | stmmac_mmc_setup(priv); |
| 1710 | 1710 | ||
| 1711 | ret = stmmac_init_ptp(priv); | 1711 | if (init_ptp) { |
| 1712 | if (ret && ret != -EOPNOTSUPP) | 1712 | ret = stmmac_init_ptp(priv); |
| 1713 | pr_warn("%s: failed PTP initialisation\n", __func__); | 1713 | if (ret && ret != -EOPNOTSUPP) |
| 1714 | pr_warn("%s: failed PTP initialisation\n", __func__); | ||
| 1715 | } | ||
| 1714 | 1716 | ||
| 1715 | #ifdef CONFIG_DEBUG_FS | 1717 | #ifdef CONFIG_DEBUG_FS |
| 1716 | ret = stmmac_init_fs(dev); | 1718 | ret = stmmac_init_fs(dev); |
| @@ -1787,7 +1789,7 @@ static int stmmac_open(struct net_device *dev) | |||
| 1787 | goto init_error; | 1789 | goto init_error; |
| 1788 | } | 1790 | } |
| 1789 | 1791 | ||
| 1790 | ret = stmmac_hw_setup(dev); | 1792 | ret = stmmac_hw_setup(dev, true); |
| 1791 | if (ret < 0) { | 1793 | if (ret < 0) { |
| 1792 | pr_err("%s: Hw setup failed\n", __func__); | 1794 | pr_err("%s: Hw setup failed\n", __func__); |
| 1793 | goto init_error; | 1795 | goto init_error; |
| @@ -3036,7 +3038,7 @@ int stmmac_resume(struct net_device *ndev) | |||
| 3036 | netif_device_attach(ndev); | 3038 | netif_device_attach(ndev); |
| 3037 | 3039 | ||
| 3038 | init_dma_desc_rings(ndev, GFP_ATOMIC); | 3040 | init_dma_desc_rings(ndev, GFP_ATOMIC); |
| 3039 | stmmac_hw_setup(ndev); | 3041 | stmmac_hw_setup(ndev, false); |
| 3040 | stmmac_init_tx_coalesce(priv); | 3042 | stmmac_init_tx_coalesce(priv); |
| 3041 | 3043 | ||
| 3042 | napi_enable(&priv->napi); | 3044 | napi_enable(&priv->napi); |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index 4032b170fe24..3039de2465ba 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | |||
| @@ -430,7 +430,6 @@ static struct platform_driver stmmac_pltfr_driver = { | |||
| 430 | .remove = stmmac_pltfr_remove, | 430 | .remove = stmmac_pltfr_remove, |
| 431 | .driver = { | 431 | .driver = { |
| 432 | .name = STMMAC_RESOURCE_NAME, | 432 | .name = STMMAC_RESOURCE_NAME, |
| 433 | .owner = THIS_MODULE, | ||
| 434 | .pm = &stmmac_pltfr_pm_ops, | 433 | .pm = &stmmac_pltfr_pm_ops, |
| 435 | .of_match_table = of_match_ptr(stmmac_dt_ids), | 434 | .of_match_table = of_match_ptr(stmmac_dt_ids), |
| 436 | }, | 435 | }, |
diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c index 45c408ef67d0..d2835bf7b4fb 100644 --- a/drivers/net/ethernet/sun/sunvnet.c +++ b/drivers/net/ethernet/sun/sunvnet.c | |||
| @@ -1201,6 +1201,7 @@ static int vnet_handle_offloads(struct vnet_port *port, struct sk_buff *skb) | |||
| 1201 | segs = skb_gso_segment(skb, dev->features & ~NETIF_F_TSO); | 1201 | segs = skb_gso_segment(skb, dev->features & ~NETIF_F_TSO); |
| 1202 | if (IS_ERR(segs)) { | 1202 | if (IS_ERR(segs)) { |
| 1203 | dev->stats.tx_dropped++; | 1203 | dev->stats.tx_dropped++; |
| 1204 | dev_kfree_skb_any(skb); | ||
| 1204 | return NETDEV_TX_OK; | 1205 | return NETDEV_TX_OK; |
| 1205 | } | 1206 | } |
| 1206 | 1207 | ||
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet.h b/drivers/net/ethernet/xilinx/xilinx_axienet.h index 44b8d2bad8c3..4c9b4fa1d3c1 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet.h +++ b/drivers/net/ethernet/xilinx/xilinx_axienet.h | |||
| @@ -388,7 +388,6 @@ struct axidma_bd { | |||
| 388 | * @dma_err_tasklet: Tasklet structure to process Axi DMA errors | 388 | * @dma_err_tasklet: Tasklet structure to process Axi DMA errors |
| 389 | * @tx_irq: Axidma TX IRQ number | 389 | * @tx_irq: Axidma TX IRQ number |
| 390 | * @rx_irq: Axidma RX IRQ number | 390 | * @rx_irq: Axidma RX IRQ number |
| 391 | * @temac_type: axienet type to identify between soft and hard temac | ||
| 392 | * @phy_type: Phy type to identify between MII/GMII/RGMII/SGMII/1000 Base-X | 391 | * @phy_type: Phy type to identify between MII/GMII/RGMII/SGMII/1000 Base-X |
| 393 | * @options: AxiEthernet option word | 392 | * @options: AxiEthernet option word |
| 394 | * @last_link: Phy link state in which the PHY was negotiated earlier | 393 | * @last_link: Phy link state in which the PHY was negotiated earlier |
| @@ -431,7 +430,6 @@ struct axienet_local { | |||
| 431 | 430 | ||
| 432 | int tx_irq; | 431 | int tx_irq; |
| 433 | int rx_irq; | 432 | int rx_irq; |
| 434 | u32 temac_type; | ||
| 435 | u32 phy_type; | 433 | u32 phy_type; |
| 436 | 434 | ||
| 437 | u32 options; /* Current options word */ | 435 | u32 options; /* Current options word */ |
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index 4ea2d4e6f1d1..c18a0c637c44 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c | |||
| @@ -1555,10 +1555,6 @@ static int axienet_of_probe(struct platform_device *op) | |||
| 1555 | if ((be32_to_cpup(p)) >= 0x4000) | 1555 | if ((be32_to_cpup(p)) >= 0x4000) |
| 1556 | lp->jumbo_support = 1; | 1556 | lp->jumbo_support = 1; |
| 1557 | } | 1557 | } |
| 1558 | p = (__be32 *) of_get_property(op->dev.of_node, "xlnx,temac-type", | ||
| 1559 | NULL); | ||
| 1560 | if (p) | ||
| 1561 | lp->temac_type = be32_to_cpup(p); | ||
| 1562 | p = (__be32 *) of_get_property(op->dev.of_node, "xlnx,phy-type", NULL); | 1558 | p = (__be32 *) of_get_property(op->dev.of_node, "xlnx,phy-type", NULL); |
| 1563 | if (p) | 1559 | if (p) |
| 1564 | lp->phy_type = be32_to_cpup(p); | 1560 | lp->phy_type = be32_to_cpup(p); |
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index 2f48f790c9b4..384ca4f4de4a 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h | |||
| @@ -590,6 +590,7 @@ struct nvsp_message { | |||
| 590 | 590 | ||
| 591 | 591 | ||
| 592 | #define NETVSC_RECEIVE_BUFFER_ID 0xcafe | 592 | #define NETVSC_RECEIVE_BUFFER_ID 0xcafe |
| 593 | #define NETVSC_SEND_BUFFER_ID 0 | ||
| 593 | 594 | ||
| 594 | #define NETVSC_PACKET_SIZE 4096 | 595 | #define NETVSC_PACKET_SIZE 4096 |
| 595 | 596 | ||
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index dd867e6cabd6..9f49c0129a78 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c | |||
| @@ -161,8 +161,8 @@ static int netvsc_destroy_buf(struct netvsc_device *net_device) | |||
| 161 | 161 | ||
| 162 | /* Deal with the send buffer we may have setup. | 162 | /* Deal with the send buffer we may have setup. |
| 163 | * If we got a send section size, it means we received a | 163 | * If we got a send section size, it means we received a |
| 164 | * SendsendBufferComplete msg (ie sent | 164 | * NVSP_MSG1_TYPE_SEND_SEND_BUF_COMPLETE msg (ie sent |
| 165 | * NvspMessage1TypeSendReceiveBuffer msg) therefore, we need | 165 | * NVSP_MSG1_TYPE_SEND_SEND_BUF msg) therefore, we need |
| 166 | * to send a revoke msg here | 166 | * to send a revoke msg here |
| 167 | */ | 167 | */ |
| 168 | if (net_device->send_section_size) { | 168 | if (net_device->send_section_size) { |
| @@ -172,7 +172,8 @@ static int netvsc_destroy_buf(struct netvsc_device *net_device) | |||
| 172 | 172 | ||
| 173 | revoke_packet->hdr.msg_type = | 173 | revoke_packet->hdr.msg_type = |
| 174 | NVSP_MSG1_TYPE_REVOKE_SEND_BUF; | 174 | NVSP_MSG1_TYPE_REVOKE_SEND_BUF; |
| 175 | revoke_packet->msg.v1_msg.revoke_recv_buf.id = 0; | 175 | revoke_packet->msg.v1_msg.revoke_send_buf.id = |
| 176 | NETVSC_SEND_BUFFER_ID; | ||
| 176 | 177 | ||
| 177 | ret = vmbus_sendpacket(net_device->dev->channel, | 178 | ret = vmbus_sendpacket(net_device->dev->channel, |
| 178 | revoke_packet, | 179 | revoke_packet, |
| @@ -204,7 +205,7 @@ static int netvsc_destroy_buf(struct netvsc_device *net_device) | |||
| 204 | net_device->send_buf_gpadl_handle = 0; | 205 | net_device->send_buf_gpadl_handle = 0; |
| 205 | } | 206 | } |
| 206 | if (net_device->send_buf) { | 207 | if (net_device->send_buf) { |
| 207 | /* Free up the receive buffer */ | 208 | /* Free up the send buffer */ |
| 208 | vfree(net_device->send_buf); | 209 | vfree(net_device->send_buf); |
| 209 | net_device->send_buf = NULL; | 210 | net_device->send_buf = NULL; |
| 210 | } | 211 | } |
| @@ -339,9 +340,9 @@ static int netvsc_init_buf(struct hv_device *device) | |||
| 339 | init_packet = &net_device->channel_init_pkt; | 340 | init_packet = &net_device->channel_init_pkt; |
| 340 | memset(init_packet, 0, sizeof(struct nvsp_message)); | 341 | memset(init_packet, 0, sizeof(struct nvsp_message)); |
| 341 | init_packet->hdr.msg_type = NVSP_MSG1_TYPE_SEND_SEND_BUF; | 342 | init_packet->hdr.msg_type = NVSP_MSG1_TYPE_SEND_SEND_BUF; |
| 342 | init_packet->msg.v1_msg.send_recv_buf.gpadl_handle = | 343 | init_packet->msg.v1_msg.send_send_buf.gpadl_handle = |
| 343 | net_device->send_buf_gpadl_handle; | 344 | net_device->send_buf_gpadl_handle; |
| 344 | init_packet->msg.v1_msg.send_recv_buf.id = 0; | 345 | init_packet->msg.v1_msg.send_send_buf.id = NETVSC_SEND_BUFFER_ID; |
| 345 | 346 | ||
| 346 | /* Send the gpadl notification request */ | 347 | /* Send the gpadl notification request */ |
| 347 | ret = vmbus_sendpacket(device->channel, init_packet, | 348 | ret = vmbus_sendpacket(device->channel, init_packet, |
| @@ -364,7 +365,7 @@ static int netvsc_init_buf(struct hv_device *device) | |||
| 364 | netdev_err(ndev, "Unable to complete send buffer " | 365 | netdev_err(ndev, "Unable to complete send buffer " |
| 365 | "initialization with NetVsp - status %d\n", | 366 | "initialization with NetVsp - status %d\n", |
| 366 | init_packet->msg.v1_msg. | 367 | init_packet->msg.v1_msg. |
| 367 | send_recv_buf_complete.status); | 368 | send_send_buf_complete.status); |
| 368 | ret = -EINVAL; | 369 | ret = -EINVAL; |
| 369 | goto cleanup; | 370 | goto cleanup; |
| 370 | } | 371 | } |
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index c530de1e63f5..3ad8ca76196d 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c | |||
| @@ -88,6 +88,7 @@ struct kszphy_priv { | |||
| 88 | 88 | ||
| 89 | static const struct kszphy_type ksz8021_type = { | 89 | static const struct kszphy_type ksz8021_type = { |
| 90 | .led_mode_reg = MII_KSZPHY_CTRL_2, | 90 | .led_mode_reg = MII_KSZPHY_CTRL_2, |
| 91 | .has_broadcast_disable = true, | ||
| 91 | .has_rmii_ref_clk_sel = true, | 92 | .has_rmii_ref_clk_sel = true, |
| 92 | }; | 93 | }; |
| 93 | 94 | ||
| @@ -258,19 +259,6 @@ static int kszphy_config_init(struct phy_device *phydev) | |||
| 258 | return 0; | 259 | return 0; |
| 259 | } | 260 | } |
| 260 | 261 | ||
| 261 | static int ksz8021_config_init(struct phy_device *phydev) | ||
| 262 | { | ||
| 263 | int rc; | ||
| 264 | |||
| 265 | rc = kszphy_config_init(phydev); | ||
| 266 | if (rc) | ||
| 267 | return rc; | ||
| 268 | |||
| 269 | rc = kszphy_broadcast_disable(phydev); | ||
| 270 | |||
| 271 | return rc < 0 ? rc : 0; | ||
| 272 | } | ||
| 273 | |||
| 274 | static int ksz9021_load_values_from_of(struct phy_device *phydev, | 262 | static int ksz9021_load_values_from_of(struct phy_device *phydev, |
| 275 | struct device_node *of_node, u16 reg, | 263 | struct device_node *of_node, u16 reg, |
| 276 | char *field1, char *field2, | 264 | char *field1, char *field2, |
| @@ -584,7 +572,7 @@ static struct phy_driver ksphy_driver[] = { | |||
| 584 | .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, | 572 | .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, |
| 585 | .driver_data = &ksz8021_type, | 573 | .driver_data = &ksz8021_type, |
| 586 | .probe = kszphy_probe, | 574 | .probe = kszphy_probe, |
| 587 | .config_init = ksz8021_config_init, | 575 | .config_init = kszphy_config_init, |
| 588 | .config_aneg = genphy_config_aneg, | 576 | .config_aneg = genphy_config_aneg, |
| 589 | .read_status = genphy_read_status, | 577 | .read_status = genphy_read_status, |
| 590 | .ack_interrupt = kszphy_ack_interrupt, | 578 | .ack_interrupt = kszphy_ack_interrupt, |
| @@ -601,7 +589,7 @@ static struct phy_driver ksphy_driver[] = { | |||
| 601 | .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, | 589 | .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, |
| 602 | .driver_data = &ksz8021_type, | 590 | .driver_data = &ksz8021_type, |
| 603 | .probe = kszphy_probe, | 591 | .probe = kszphy_probe, |
| 604 | .config_init = ksz8021_config_init, | 592 | .config_init = kszphy_config_init, |
| 605 | .config_aneg = genphy_config_aneg, | 593 | .config_aneg = genphy_config_aneg, |
| 606 | .read_status = genphy_read_status, | 594 | .read_status = genphy_read_status, |
| 607 | .ack_interrupt = kszphy_ack_interrupt, | 595 | .ack_interrupt = kszphy_ack_interrupt, |
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index b8bd7191572d..5ca97713bfb3 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
| @@ -760,7 +760,6 @@ static int virtnet_poll(struct napi_struct *napi, int budget) | |||
| 760 | container_of(napi, struct receive_queue, napi); | 760 | container_of(napi, struct receive_queue, napi); |
| 761 | unsigned int r, received = 0; | 761 | unsigned int r, received = 0; |
| 762 | 762 | ||
| 763 | again: | ||
| 764 | received += virtnet_receive(rq, budget - received); | 763 | received += virtnet_receive(rq, budget - received); |
| 765 | 764 | ||
| 766 | /* Out of packets? */ | 765 | /* Out of packets? */ |
| @@ -771,7 +770,6 @@ again: | |||
| 771 | napi_schedule_prep(napi)) { | 770 | napi_schedule_prep(napi)) { |
| 772 | virtqueue_disable_cb(rq->vq); | 771 | virtqueue_disable_cb(rq->vq); |
| 773 | __napi_schedule(napi); | 772 | __napi_schedule(napi); |
| 774 | goto again; | ||
| 775 | } | 773 | } |
| 776 | } | 774 | } |
| 777 | 775 | ||
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 49d9f2291998..7fbd89fbe107 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c | |||
| @@ -1579,8 +1579,10 @@ static int vxlan6_xmit_skb(struct vxlan_sock *vs, | |||
| 1579 | bool udp_sum = !udp_get_no_check6_tx(vs->sock->sk); | 1579 | bool udp_sum = !udp_get_no_check6_tx(vs->sock->sk); |
| 1580 | 1580 | ||
| 1581 | skb = udp_tunnel_handle_offloads(skb, udp_sum); | 1581 | skb = udp_tunnel_handle_offloads(skb, udp_sum); |
| 1582 | if (IS_ERR(skb)) | 1582 | if (IS_ERR(skb)) { |
| 1583 | return -EINVAL; | 1583 | err = -EINVAL; |
| 1584 | goto err; | ||
| 1585 | } | ||
| 1584 | 1586 | ||
| 1585 | skb_scrub_packet(skb, xnet); | 1587 | skb_scrub_packet(skb, xnet); |
| 1586 | 1588 | ||
| @@ -1590,12 +1592,16 @@ static int vxlan6_xmit_skb(struct vxlan_sock *vs, | |||
| 1590 | 1592 | ||
| 1591 | /* Need space for new headers (invalidates iph ptr) */ | 1593 | /* Need space for new headers (invalidates iph ptr) */ |
| 1592 | err = skb_cow_head(skb, min_headroom); | 1594 | err = skb_cow_head(skb, min_headroom); |
| 1593 | if (unlikely(err)) | 1595 | if (unlikely(err)) { |
| 1594 | return err; | 1596 | kfree_skb(skb); |
| 1597 | goto err; | ||
| 1598 | } | ||
| 1595 | 1599 | ||
| 1596 | skb = vlan_hwaccel_push_inside(skb); | 1600 | skb = vlan_hwaccel_push_inside(skb); |
| 1597 | if (WARN_ON(!skb)) | 1601 | if (WARN_ON(!skb)) { |
| 1598 | return -ENOMEM; | 1602 | err = -ENOMEM; |
| 1603 | goto err; | ||
| 1604 | } | ||
| 1599 | 1605 | ||
| 1600 | vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh)); | 1606 | vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh)); |
| 1601 | vxh->vx_flags = htonl(VXLAN_FLAGS); | 1607 | vxh->vx_flags = htonl(VXLAN_FLAGS); |
| @@ -1606,6 +1612,9 @@ static int vxlan6_xmit_skb(struct vxlan_sock *vs, | |||
| 1606 | udp_tunnel6_xmit_skb(vs->sock, dst, skb, dev, saddr, daddr, prio, | 1612 | udp_tunnel6_xmit_skb(vs->sock, dst, skb, dev, saddr, daddr, prio, |
| 1607 | ttl, src_port, dst_port); | 1613 | ttl, src_port, dst_port); |
| 1608 | return 0; | 1614 | return 0; |
| 1615 | err: | ||
| 1616 | dst_release(dst); | ||
| 1617 | return err; | ||
| 1609 | } | 1618 | } |
| 1610 | #endif | 1619 | #endif |
| 1611 | 1620 | ||
| @@ -1621,7 +1630,7 @@ int vxlan_xmit_skb(struct vxlan_sock *vs, | |||
| 1621 | 1630 | ||
| 1622 | skb = udp_tunnel_handle_offloads(skb, udp_sum); | 1631 | skb = udp_tunnel_handle_offloads(skb, udp_sum); |
| 1623 | if (IS_ERR(skb)) | 1632 | if (IS_ERR(skb)) |
| 1624 | return -EINVAL; | 1633 | return PTR_ERR(skb); |
| 1625 | 1634 | ||
| 1626 | min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len | 1635 | min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len |
| 1627 | + VXLAN_HLEN + sizeof(struct iphdr) | 1636 | + VXLAN_HLEN + sizeof(struct iphdr) |
| @@ -1629,8 +1638,10 @@ int vxlan_xmit_skb(struct vxlan_sock *vs, | |||
| 1629 | 1638 | ||
| 1630 | /* Need space for new headers (invalidates iph ptr) */ | 1639 | /* Need space for new headers (invalidates iph ptr) */ |
| 1631 | err = skb_cow_head(skb, min_headroom); | 1640 | err = skb_cow_head(skb, min_headroom); |
| 1632 | if (unlikely(err)) | 1641 | if (unlikely(err)) { |
| 1642 | kfree_skb(skb); | ||
| 1633 | return err; | 1643 | return err; |
| 1644 | } | ||
| 1634 | 1645 | ||
| 1635 | skb = vlan_hwaccel_push_inside(skb); | 1646 | skb = vlan_hwaccel_push_inside(skb); |
| 1636 | if (WARN_ON(!skb)) | 1647 | if (WARN_ON(!skb)) |
| @@ -1776,9 +1787,12 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, | |||
| 1776 | tos, ttl, df, src_port, dst_port, | 1787 | tos, ttl, df, src_port, dst_port, |
| 1777 | htonl(vni << 8), | 1788 | htonl(vni << 8), |
| 1778 | !net_eq(vxlan->net, dev_net(vxlan->dev))); | 1789 | !net_eq(vxlan->net, dev_net(vxlan->dev))); |
| 1779 | 1790 | if (err < 0) { | |
| 1780 | if (err < 0) | 1791 | /* skb is already freed. */ |
| 1792 | skb = NULL; | ||
| 1781 | goto rt_tx_error; | 1793 | goto rt_tx_error; |
| 1794 | } | ||
| 1795 | |||
| 1782 | iptunnel_xmit_stats(err, &dev->stats, dev->tstats); | 1796 | iptunnel_xmit_stats(err, &dev->stats, dev->tstats); |
| 1783 | #if IS_ENABLED(CONFIG_IPV6) | 1797 | #if IS_ENABLED(CONFIG_IPV6) |
| 1784 | } else { | 1798 | } else { |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 3c06e9365949..9880dae2a569 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | |||
| @@ -1070,7 +1070,7 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func, | |||
| 1070 | */ | 1070 | */ |
| 1071 | if ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_KEEP_POWER) && | 1071 | if ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_KEEP_POWER) && |
| 1072 | ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_WAKE_SDIO_IRQ) || | 1072 | ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_WAKE_SDIO_IRQ) || |
| 1073 | (sdiodev->pdata->oob_irq_supported))) | 1073 | (sdiodev->pdata && sdiodev->pdata->oob_irq_supported))) |
| 1074 | bus_if->wowl_supported = true; | 1074 | bus_if->wowl_supported = true; |
| 1075 | #endif | 1075 | #endif |
| 1076 | 1076 | ||
| @@ -1167,7 +1167,7 @@ static int brcmf_ops_sdio_resume(struct device *dev) | |||
| 1167 | struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; | 1167 | struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; |
| 1168 | 1168 | ||
| 1169 | brcmf_dbg(SDIO, "Enter\n"); | 1169 | brcmf_dbg(SDIO, "Enter\n"); |
| 1170 | if (sdiodev->pdata->oob_irq_supported) | 1170 | if (sdiodev->pdata && sdiodev->pdata->oob_irq_supported) |
| 1171 | disable_irq_wake(sdiodev->pdata->oob_irq_nr); | 1171 | disable_irq_wake(sdiodev->pdata->oob_irq_nr); |
| 1172 | brcmf_sdio_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS); | 1172 | brcmf_sdio_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS); |
| 1173 | atomic_set(&sdiodev->suspend, false); | 1173 | atomic_set(&sdiodev->suspend, false); |
diff --git a/drivers/net/wireless/ipw2x00/Kconfig b/drivers/net/wireless/ipw2x00/Kconfig index 91c0cb3c368e..21de4fe6cf2d 100644 --- a/drivers/net/wireless/ipw2x00/Kconfig +++ b/drivers/net/wireless/ipw2x00/Kconfig | |||
| @@ -65,7 +65,8 @@ config IPW2100_DEBUG | |||
| 65 | 65 | ||
| 66 | config IPW2200 | 66 | config IPW2200 |
| 67 | tristate "Intel PRO/Wireless 2200BG and 2915ABG Network Connection" | 67 | tristate "Intel PRO/Wireless 2200BG and 2915ABG Network Connection" |
| 68 | depends on PCI && CFG80211 && CFG80211_WEXT | 68 | depends on PCI && CFG80211 |
| 69 | select CFG80211_WEXT | ||
| 69 | select WIRELESS_EXT | 70 | select WIRELESS_EXT |
| 70 | select WEXT_SPY | 71 | select WEXT_SPY |
| 71 | select WEXT_PRIV | 72 | select WEXT_PRIV |
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 38de1513e4de..850b85a47806 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c | |||
| @@ -1323,10 +1323,10 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) | |||
| 1323 | 1323 | ||
| 1324 | try_again: | 1324 | try_again: |
| 1325 | /* try next, if any */ | 1325 | /* try next, if any */ |
| 1326 | kfree(pieces); | ||
| 1327 | release_firmware(ucode_raw); | 1326 | release_firmware(ucode_raw); |
| 1328 | if (iwl_request_firmware(drv, false)) | 1327 | if (iwl_request_firmware(drv, false)) |
| 1329 | goto out_unbind; | 1328 | goto out_unbind; |
| 1329 | kfree(pieces); | ||
| 1330 | return; | 1330 | return; |
| 1331 | 1331 | ||
| 1332 | out_free_fw: | 1332 | out_free_fw: |
diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h index 9564ae173d06..1f7f15eb86da 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/iwlwifi/iwl-fh.h | |||
| @@ -310,6 +310,7 @@ static inline unsigned int FH_MEM_CBBC_QUEUE(unsigned int chnl) | |||
| 310 | #define FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE (0x01000000) | 310 | #define FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE (0x01000000) |
| 311 | 311 | ||
| 312 | #define FH_MEM_TFDIB_REG1_ADDR_BITSHIFT 28 | 312 | #define FH_MEM_TFDIB_REG1_ADDR_BITSHIFT 28 |
| 313 | #define FH_MEM_TB_MAX_LENGTH (0x00020000) | ||
| 313 | 314 | ||
| 314 | /* TFDB Area - TFDs buffer table */ | 315 | /* TFDB Area - TFDs buffer table */ |
| 315 | #define FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK (0xFFFFFFFF) | 316 | #define FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK (0xFFFFFFFF) |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 31a5b3f4266c..e880f9d4717b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c | |||
| @@ -1004,8 +1004,13 @@ void __iwl_mvm_mac_stop(struct iwl_mvm *mvm) | |||
| 1004 | { | 1004 | { |
| 1005 | lockdep_assert_held(&mvm->mutex); | 1005 | lockdep_assert_held(&mvm->mutex); |
| 1006 | 1006 | ||
| 1007 | /* disallow low power states when the FW is down */ | 1007 | /* |
| 1008 | iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); | 1008 | * Disallow low power states when the FW is down by taking |
| 1009 | * the UCODE_DOWN ref. in case of ongoing hw restart the | ||
| 1010 | * ref is already taken, so don't take it again. | ||
| 1011 | */ | ||
| 1012 | if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) | ||
| 1013 | iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); | ||
| 1009 | 1014 | ||
| 1010 | /* async_handlers_wk is now blocked */ | 1015 | /* async_handlers_wk is now blocked */ |
| 1011 | 1016 | ||
| @@ -1023,6 +1028,12 @@ void __iwl_mvm_mac_stop(struct iwl_mvm *mvm) | |||
| 1023 | /* the fw is stopped, the aux sta is dead: clean up driver state */ | 1028 | /* the fw is stopped, the aux sta is dead: clean up driver state */ |
| 1024 | iwl_mvm_del_aux_sta(mvm); | 1029 | iwl_mvm_del_aux_sta(mvm); |
| 1025 | 1030 | ||
| 1031 | /* | ||
| 1032 | * Clear IN_HW_RESTART flag when stopping the hw (as restart_complete() | ||
| 1033 | * won't be called in this case). | ||
| 1034 | */ | ||
| 1035 | clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); | ||
| 1036 | |||
| 1026 | mvm->ucode_loaded = false; | 1037 | mvm->ucode_loaded = false; |
| 1027 | } | 1038 | } |
| 1028 | 1039 | ||
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c index 3ee8e3848876..2f0c4b170344 100644 --- a/drivers/net/wireless/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/iwlwifi/pcie/drv.c | |||
| @@ -367,7 +367,11 @@ static const struct pci_device_id iwl_hw_card_ids[] = { | |||
| 367 | 367 | ||
| 368 | /* 3165 Series */ | 368 | /* 3165 Series */ |
| 369 | {IWL_PCI_DEVICE(0x3165, 0x4010, iwl3165_2ac_cfg)}, | 369 | {IWL_PCI_DEVICE(0x3165, 0x4010, iwl3165_2ac_cfg)}, |
| 370 | {IWL_PCI_DEVICE(0x3165, 0x4012, iwl3165_2ac_cfg)}, | ||
| 371 | {IWL_PCI_DEVICE(0x3165, 0x4110, iwl3165_2ac_cfg)}, | ||
| 370 | {IWL_PCI_DEVICE(0x3165, 0x4210, iwl3165_2ac_cfg)}, | 372 | {IWL_PCI_DEVICE(0x3165, 0x4210, iwl3165_2ac_cfg)}, |
| 373 | {IWL_PCI_DEVICE(0x3165, 0x4410, iwl3165_2ac_cfg)}, | ||
| 374 | {IWL_PCI_DEVICE(0x3165, 0x4510, iwl3165_2ac_cfg)}, | ||
| 371 | 375 | ||
| 372 | /* 7265 Series */ | 376 | /* 7265 Series */ |
| 373 | {IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)}, | 377 | {IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)}, |
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 5d79a1f44b8e..523fe0c88dcb 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c | |||
| @@ -614,7 +614,7 @@ static int iwl_pcie_load_section(struct iwl_trans *trans, u8 section_num, | |||
| 614 | { | 614 | { |
| 615 | u8 *v_addr; | 615 | u8 *v_addr; |
| 616 | dma_addr_t p_addr; | 616 | dma_addr_t p_addr; |
| 617 | u32 offset, chunk_sz = section->len; | 617 | u32 offset, chunk_sz = min_t(u32, FH_MEM_TB_MAX_LENGTH, section->len); |
| 618 | int ret = 0; | 618 | int ret = 0; |
| 619 | 619 | ||
| 620 | IWL_DEBUG_FW(trans, "[%d] uCode section being loaded...\n", | 620 | IWL_DEBUG_FW(trans, "[%d] uCode section being loaded...\n", |
| @@ -1012,16 +1012,21 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | |||
| 1012 | /* Stop the device, and put it in low power state */ | 1012 | /* Stop the device, and put it in low power state */ |
| 1013 | iwl_pcie_apm_stop(trans); | 1013 | iwl_pcie_apm_stop(trans); |
| 1014 | 1014 | ||
| 1015 | /* Upon stop, the APM issues an interrupt if HW RF kill is set. | 1015 | /* stop and reset the on-board processor */ |
| 1016 | * Clean again the interrupt here | 1016 | iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); |
| 1017 | udelay(20); | ||
| 1018 | |||
| 1019 | /* | ||
| 1020 | * Upon stop, the APM issues an interrupt if HW RF kill is set. | ||
| 1021 | * This is a bug in certain verions of the hardware. | ||
| 1022 | * Certain devices also keep sending HW RF kill interrupt all | ||
| 1023 | * the time, unless the interrupt is ACKed even if the interrupt | ||
| 1024 | * should be masked. Re-ACK all the interrupts here. | ||
| 1017 | */ | 1025 | */ |
| 1018 | spin_lock(&trans_pcie->irq_lock); | 1026 | spin_lock(&trans_pcie->irq_lock); |
| 1019 | iwl_disable_interrupts(trans); | 1027 | iwl_disable_interrupts(trans); |
| 1020 | spin_unlock(&trans_pcie->irq_lock); | 1028 | spin_unlock(&trans_pcie->irq_lock); |
| 1021 | 1029 | ||
| 1022 | /* stop and reset the on-board processor */ | ||
| 1023 | iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); | ||
| 1024 | udelay(20); | ||
| 1025 | 1030 | ||
| 1026 | /* clear all status bits */ | 1031 | /* clear all status bits */ |
| 1027 | clear_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status); | 1032 | clear_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status); |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index c31f74d76ebd..679e6e90aa4c 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
| @@ -1012,12 +1012,15 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev, | |||
| 1012 | * Callback to use for xmit over the accelerated station. This | 1012 | * Callback to use for xmit over the accelerated station. This |
| 1013 | * is used in place of ndo_start_xmit on accelerated net | 1013 | * is used in place of ndo_start_xmit on accelerated net |
| 1014 | * devices. | 1014 | * devices. |
| 1015 | * bool (*ndo_gso_check) (struct sk_buff *skb, | 1015 | * netdev_features_t (*ndo_features_check) (struct sk_buff *skb, |
| 1016 | * struct net_device *dev); | 1016 | * struct net_device *dev |
| 1017 | * netdev_features_t features); | ||
| 1017 | * Called by core transmit path to determine if device is capable of | 1018 | * Called by core transmit path to determine if device is capable of |
| 1018 | * performing GSO on a packet. The device returns true if it is | 1019 | * performing offload operations on a given packet. This is to give |
| 1019 | * able to GSO the packet, false otherwise. If the return value is | 1020 | * the device an opportunity to implement any restrictions that cannot |
| 1020 | * false the stack will do software GSO. | 1021 | * be otherwise expressed by feature flags. The check is called with |
| 1022 | * the set of features that the stack has calculated and it returns | ||
| 1023 | * those the driver believes to be appropriate. | ||
| 1021 | * | 1024 | * |
| 1022 | * int (*ndo_switch_parent_id_get)(struct net_device *dev, | 1025 | * int (*ndo_switch_parent_id_get)(struct net_device *dev, |
| 1023 | * struct netdev_phys_item_id *psid); | 1026 | * struct netdev_phys_item_id *psid); |
| @@ -1178,8 +1181,9 @@ struct net_device_ops { | |||
| 1178 | struct net_device *dev, | 1181 | struct net_device *dev, |
| 1179 | void *priv); | 1182 | void *priv); |
| 1180 | int (*ndo_get_lock_subclass)(struct net_device *dev); | 1183 | int (*ndo_get_lock_subclass)(struct net_device *dev); |
| 1181 | bool (*ndo_gso_check) (struct sk_buff *skb, | 1184 | netdev_features_t (*ndo_features_check) (struct sk_buff *skb, |
| 1182 | struct net_device *dev); | 1185 | struct net_device *dev, |
| 1186 | netdev_features_t features); | ||
| 1183 | #ifdef CONFIG_NET_SWITCHDEV | 1187 | #ifdef CONFIG_NET_SWITCHDEV |
| 1184 | int (*ndo_switch_parent_id_get)(struct net_device *dev, | 1188 | int (*ndo_switch_parent_id_get)(struct net_device *dev, |
| 1185 | struct netdev_phys_item_id *psid); | 1189 | struct netdev_phys_item_id *psid); |
| @@ -3611,8 +3615,6 @@ static inline bool netif_needs_gso(struct net_device *dev, struct sk_buff *skb, | |||
| 3611 | netdev_features_t features) | 3615 | netdev_features_t features) |
| 3612 | { | 3616 | { |
| 3613 | return skb_is_gso(skb) && (!skb_gso_ok(skb, features) || | 3617 | return skb_is_gso(skb) && (!skb_gso_ok(skb, features) || |
| 3614 | (dev->netdev_ops->ndo_gso_check && | ||
| 3615 | !dev->netdev_ops->ndo_gso_check(skb, dev)) || | ||
| 3616 | unlikely((skb->ip_summed != CHECKSUM_PARTIAL) && | 3618 | unlikely((skb->ip_summed != CHECKSUM_PARTIAL) && |
| 3617 | (skb->ip_summed != CHECKSUM_UNNECESSARY))); | 3619 | (skb->ip_summed != CHECKSUM_UNNECESSARY))); |
| 3618 | } | 3620 | } |
diff --git a/include/linux/netlink.h b/include/linux/netlink.h index 9e572daa15d5..02fc86d2348e 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h | |||
| @@ -46,8 +46,8 @@ struct netlink_kernel_cfg { | |||
| 46 | unsigned int flags; | 46 | unsigned int flags; |
| 47 | void (*input)(struct sk_buff *skb); | 47 | void (*input)(struct sk_buff *skb); |
| 48 | struct mutex *cb_mutex; | 48 | struct mutex *cb_mutex; |
| 49 | int (*bind)(int group); | 49 | int (*bind)(struct net *net, int group); |
| 50 | void (*unbind)(int group); | 50 | void (*unbind)(struct net *net, int group); |
| 51 | bool (*compare)(struct net *net, struct sock *sk); | 51 | bool (*compare)(struct net *net, struct sock *sk); |
| 52 | }; | 52 | }; |
| 53 | 53 | ||
diff --git a/include/net/genetlink.h b/include/net/genetlink.h index af10c2cf8a1d..84125088c309 100644 --- a/include/net/genetlink.h +++ b/include/net/genetlink.h | |||
| @@ -31,6 +31,9 @@ struct genl_info; | |||
| 31 | * do additional, common, filtering and return an error | 31 | * do additional, common, filtering and return an error |
| 32 | * @post_doit: called after an operation's doit callback, it may | 32 | * @post_doit: called after an operation's doit callback, it may |
| 33 | * undo operations done by pre_doit, for example release locks | 33 | * undo operations done by pre_doit, for example release locks |
| 34 | * @mcast_bind: a socket bound to the given multicast group (which | ||
| 35 | * is given as the offset into the groups array) | ||
| 36 | * @mcast_unbind: a socket was unbound from the given multicast group | ||
| 34 | * @attrbuf: buffer to store parsed attributes | 37 | * @attrbuf: buffer to store parsed attributes |
| 35 | * @family_list: family list | 38 | * @family_list: family list |
| 36 | * @mcgrps: multicast groups used by this family (private) | 39 | * @mcgrps: multicast groups used by this family (private) |
| @@ -53,6 +56,8 @@ struct genl_family { | |||
| 53 | void (*post_doit)(const struct genl_ops *ops, | 56 | void (*post_doit)(const struct genl_ops *ops, |
| 54 | struct sk_buff *skb, | 57 | struct sk_buff *skb, |
| 55 | struct genl_info *info); | 58 | struct genl_info *info); |
| 59 | int (*mcast_bind)(struct net *net, int group); | ||
| 60 | void (*mcast_unbind)(struct net *net, int group); | ||
| 56 | struct nlattr ** attrbuf; /* private */ | 61 | struct nlattr ** attrbuf; /* private */ |
| 57 | const struct genl_ops * ops; /* private */ | 62 | const struct genl_ops * ops; /* private */ |
| 58 | const struct genl_multicast_group *mcgrps; /* private */ | 63 | const struct genl_multicast_group *mcgrps; /* private */ |
| @@ -395,11 +400,11 @@ static inline int genl_set_err(struct genl_family *family, struct net *net, | |||
| 395 | } | 400 | } |
| 396 | 401 | ||
| 397 | static inline int genl_has_listeners(struct genl_family *family, | 402 | static inline int genl_has_listeners(struct genl_family *family, |
| 398 | struct sock *sk, unsigned int group) | 403 | struct net *net, unsigned int group) |
| 399 | { | 404 | { |
| 400 | if (WARN_ON_ONCE(group >= family->n_mcgrps)) | 405 | if (WARN_ON_ONCE(group >= family->n_mcgrps)) |
| 401 | return -EINVAL; | 406 | return -EINVAL; |
| 402 | group = family->mcgrp_offset + group; | 407 | group = family->mcgrp_offset + group; |
| 403 | return netlink_has_listeners(sk, group); | 408 | return netlink_has_listeners(net->genl_sock, group); |
| 404 | } | 409 | } |
| 405 | #endif /* __NET_GENERIC_NETLINK_H */ | 410 | #endif /* __NET_GENERIC_NETLINK_H */ |
diff --git a/include/net/neighbour.h b/include/net/neighbour.h index eb070b3674a1..76f708486aae 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h | |||
| @@ -190,7 +190,6 @@ struct neigh_hash_table { | |||
| 190 | 190 | ||
| 191 | 191 | ||
| 192 | struct neigh_table { | 192 | struct neigh_table { |
| 193 | struct neigh_table *next; | ||
| 194 | int family; | 193 | int family; |
| 195 | int entry_size; | 194 | int entry_size; |
| 196 | int key_len; | 195 | int key_len; |
diff --git a/include/net/vxlan.h b/include/net/vxlan.h index 57cccd0052e5..903461aa5644 100644 --- a/include/net/vxlan.h +++ b/include/net/vxlan.h | |||
| @@ -1,6 +1,9 @@ | |||
| 1 | #ifndef __NET_VXLAN_H | 1 | #ifndef __NET_VXLAN_H |
| 2 | #define __NET_VXLAN_H 1 | 2 | #define __NET_VXLAN_H 1 |
| 3 | 3 | ||
| 4 | #include <linux/ip.h> | ||
| 5 | #include <linux/ipv6.h> | ||
| 6 | #include <linux/if_vlan.h> | ||
| 4 | #include <linux/skbuff.h> | 7 | #include <linux/skbuff.h> |
| 5 | #include <linux/netdevice.h> | 8 | #include <linux/netdevice.h> |
| 6 | #include <linux/udp.h> | 9 | #include <linux/udp.h> |
| @@ -51,16 +54,33 @@ int vxlan_xmit_skb(struct vxlan_sock *vs, | |||
| 51 | __be32 src, __be32 dst, __u8 tos, __u8 ttl, __be16 df, | 54 | __be32 src, __be32 dst, __u8 tos, __u8 ttl, __be16 df, |
| 52 | __be16 src_port, __be16 dst_port, __be32 vni, bool xnet); | 55 | __be16 src_port, __be16 dst_port, __be32 vni, bool xnet); |
| 53 | 56 | ||
| 54 | static inline bool vxlan_gso_check(struct sk_buff *skb) | 57 | static inline netdev_features_t vxlan_features_check(struct sk_buff *skb, |
| 58 | netdev_features_t features) | ||
| 55 | { | 59 | { |
| 56 | if ((skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL) && | 60 | u8 l4_hdr = 0; |
| 61 | |||
| 62 | if (!skb->encapsulation) | ||
| 63 | return features; | ||
| 64 | |||
| 65 | switch (vlan_get_protocol(skb)) { | ||
| 66 | case htons(ETH_P_IP): | ||
| 67 | l4_hdr = ip_hdr(skb)->protocol; | ||
| 68 | break; | ||
| 69 | case htons(ETH_P_IPV6): | ||
| 70 | l4_hdr = ipv6_hdr(skb)->nexthdr; | ||
| 71 | break; | ||
| 72 | default: | ||
| 73 | return features;; | ||
| 74 | } | ||
| 75 | |||
| 76 | if ((l4_hdr == IPPROTO_UDP) && | ||
| 57 | (skb->inner_protocol_type != ENCAP_TYPE_ETHER || | 77 | (skb->inner_protocol_type != ENCAP_TYPE_ETHER || |
| 58 | skb->inner_protocol != htons(ETH_P_TEB) || | 78 | skb->inner_protocol != htons(ETH_P_TEB) || |
| 59 | (skb_inner_mac_header(skb) - skb_transport_header(skb) != | 79 | (skb_inner_mac_header(skb) - skb_transport_header(skb) != |
| 60 | sizeof(struct udphdr) + sizeof(struct vxlanhdr)))) | 80 | sizeof(struct udphdr) + sizeof(struct vxlanhdr)))) |
| 61 | return false; | 81 | return features & ~(NETIF_F_ALL_CSUM | NETIF_F_GSO_MASK); |
| 62 | 82 | ||
| 63 | return true; | 83 | return features; |
| 64 | } | 84 | } |
| 65 | 85 | ||
| 66 | /* IP header + UDP + VXLAN + Ethernet header */ | 86 | /* IP header + UDP + VXLAN + Ethernet header */ |
diff --git a/include/uapi/linux/in6.h b/include/uapi/linux/in6.h index 74a2a1773494..79b12b004ade 100644 --- a/include/uapi/linux/in6.h +++ b/include/uapi/linux/in6.h | |||
| @@ -149,7 +149,7 @@ struct in6_flowlabel_req { | |||
| 149 | /* | 149 | /* |
| 150 | * IPV6 socket options | 150 | * IPV6 socket options |
| 151 | */ | 151 | */ |
| 152 | 152 | #if __UAPI_DEF_IPV6_OPTIONS | |
| 153 | #define IPV6_ADDRFORM 1 | 153 | #define IPV6_ADDRFORM 1 |
| 154 | #define IPV6_2292PKTINFO 2 | 154 | #define IPV6_2292PKTINFO 2 |
| 155 | #define IPV6_2292HOPOPTS 3 | 155 | #define IPV6_2292HOPOPTS 3 |
| @@ -196,6 +196,7 @@ struct in6_flowlabel_req { | |||
| 196 | 196 | ||
| 197 | #define IPV6_IPSEC_POLICY 34 | 197 | #define IPV6_IPSEC_POLICY 34 |
| 198 | #define IPV6_XFRM_POLICY 35 | 198 | #define IPV6_XFRM_POLICY 35 |
| 199 | #endif | ||
| 199 | 200 | ||
| 200 | /* | 201 | /* |
| 201 | * Multicast: | 202 | * Multicast: |
diff --git a/include/uapi/linux/libc-compat.h b/include/uapi/linux/libc-compat.h index c140620dad92..e28807ad17fa 100644 --- a/include/uapi/linux/libc-compat.h +++ b/include/uapi/linux/libc-compat.h | |||
| @@ -69,6 +69,7 @@ | |||
| 69 | #define __UAPI_DEF_SOCKADDR_IN6 0 | 69 | #define __UAPI_DEF_SOCKADDR_IN6 0 |
| 70 | #define __UAPI_DEF_IPV6_MREQ 0 | 70 | #define __UAPI_DEF_IPV6_MREQ 0 |
| 71 | #define __UAPI_DEF_IPPROTO_V6 0 | 71 | #define __UAPI_DEF_IPPROTO_V6 0 |
| 72 | #define __UAPI_DEF_IPV6_OPTIONS 0 | ||
| 72 | 73 | ||
| 73 | #else | 74 | #else |
| 74 | 75 | ||
| @@ -82,6 +83,7 @@ | |||
| 82 | #define __UAPI_DEF_SOCKADDR_IN6 1 | 83 | #define __UAPI_DEF_SOCKADDR_IN6 1 |
| 83 | #define __UAPI_DEF_IPV6_MREQ 1 | 84 | #define __UAPI_DEF_IPV6_MREQ 1 |
| 84 | #define __UAPI_DEF_IPPROTO_V6 1 | 85 | #define __UAPI_DEF_IPPROTO_V6 1 |
| 86 | #define __UAPI_DEF_IPV6_OPTIONS 1 | ||
| 85 | 87 | ||
| 86 | #endif /* _NETINET_IN_H */ | 88 | #endif /* _NETINET_IN_H */ |
| 87 | 89 | ||
| @@ -103,6 +105,7 @@ | |||
| 103 | #define __UAPI_DEF_SOCKADDR_IN6 1 | 105 | #define __UAPI_DEF_SOCKADDR_IN6 1 |
| 104 | #define __UAPI_DEF_IPV6_MREQ 1 | 106 | #define __UAPI_DEF_IPV6_MREQ 1 |
| 105 | #define __UAPI_DEF_IPPROTO_V6 1 | 107 | #define __UAPI_DEF_IPPROTO_V6 1 |
| 108 | #define __UAPI_DEF_IPV6_OPTIONS 1 | ||
| 106 | 109 | ||
| 107 | /* Definitions for xattr.h */ | 110 | /* Definitions for xattr.h */ |
| 108 | #define __UAPI_DEF_XATTR 1 | 111 | #define __UAPI_DEF_XATTR 1 |
diff --git a/kernel/audit.c b/kernel/audit.c index 231b7dcb154b..72ab759a0b43 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
| @@ -1100,7 +1100,7 @@ static void audit_receive(struct sk_buff *skb) | |||
| 1100 | } | 1100 | } |
| 1101 | 1101 | ||
| 1102 | /* Run custom bind function on netlink socket group connect or bind requests. */ | 1102 | /* Run custom bind function on netlink socket group connect or bind requests. */ |
| 1103 | static int audit_bind(int group) | 1103 | static int audit_bind(struct net *net, int group) |
| 1104 | { | 1104 | { |
| 1105 | if (!capable(CAP_AUDIT_READ)) | 1105 | if (!capable(CAP_AUDIT_READ)) |
| 1106 | return -EPERM; | 1106 | return -EPERM; |
diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c index fc1835c6bb40..00f9e144cc97 100644 --- a/net/batman-adv/fragmentation.c +++ b/net/batman-adv/fragmentation.c | |||
| @@ -251,7 +251,7 @@ batadv_frag_merge_packets(struct hlist_head *chain, struct sk_buff *skb) | |||
| 251 | kfree(entry); | 251 | kfree(entry); |
| 252 | 252 | ||
| 253 | /* Make room for the rest of the fragments. */ | 253 | /* Make room for the rest of the fragments. */ |
| 254 | if (pskb_expand_head(skb_out, 0, size - skb->len, GFP_ATOMIC) < 0) { | 254 | if (pskb_expand_head(skb_out, 0, size - skb_out->len, GFP_ATOMIC) < 0) { |
| 255 | kfree_skb(skb_out); | 255 | kfree_skb(skb_out); |
| 256 | skb_out = NULL; | 256 | skb_out = NULL; |
| 257 | goto free; | 257 | goto free; |
| @@ -434,7 +434,7 @@ bool batadv_frag_send_packet(struct sk_buff *skb, | |||
| 434 | * fragments larger than BATADV_FRAG_MAX_FRAG_SIZE | 434 | * fragments larger than BATADV_FRAG_MAX_FRAG_SIZE |
| 435 | */ | 435 | */ |
| 436 | mtu = min_t(unsigned, mtu, BATADV_FRAG_MAX_FRAG_SIZE); | 436 | mtu = min_t(unsigned, mtu, BATADV_FRAG_MAX_FRAG_SIZE); |
| 437 | max_fragment_size = (mtu - header_size - ETH_HLEN); | 437 | max_fragment_size = mtu - header_size; |
| 438 | max_packet_size = max_fragment_size * BATADV_FRAG_MAX_FRAGMENTS; | 438 | max_packet_size = max_fragment_size * BATADV_FRAG_MAX_FRAGMENTS; |
| 439 | 439 | ||
| 440 | /* Don't even try to fragment, if we need more than 16 fragments */ | 440 | /* Don't even try to fragment, if we need more than 16 fragments */ |
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c index 90cff585b37d..e0bcf9e84273 100644 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c | |||
| @@ -810,7 +810,7 @@ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv, | |||
| 810 | goto out; | 810 | goto out; |
| 811 | 811 | ||
| 812 | gw_node = batadv_gw_node_get(bat_priv, orig_dst_node); | 812 | gw_node = batadv_gw_node_get(bat_priv, orig_dst_node); |
| 813 | if (!gw_node->bandwidth_down == 0) | 813 | if (!gw_node) |
| 814 | goto out; | 814 | goto out; |
| 815 | 815 | ||
| 816 | switch (atomic_read(&bat_priv->gw_mode)) { | 816 | switch (atomic_read(&bat_priv->gw_mode)) { |
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index 76617be1e797..c989253737f0 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c | |||
| @@ -390,7 +390,6 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev, | |||
| 390 | 390 | ||
| 391 | drop: | 391 | drop: |
| 392 | dev->stats.rx_dropped++; | 392 | dev->stats.rx_dropped++; |
| 393 | kfree_skb(skb); | ||
| 394 | return NET_RX_DROP; | 393 | return NET_RX_DROP; |
| 395 | } | 394 | } |
| 396 | 395 | ||
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index 85bcc21e84d2..ce82722d049b 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c | |||
| @@ -533,6 +533,9 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock) | |||
| 533 | 533 | ||
| 534 | BT_DBG(""); | 534 | BT_DBG(""); |
| 535 | 535 | ||
| 536 | if (!l2cap_is_socket(sock)) | ||
| 537 | return -EBADFD; | ||
| 538 | |||
| 536 | baswap((void *) dst, &l2cap_pi(sock->sk)->chan->dst); | 539 | baswap((void *) dst, &l2cap_pi(sock->sk)->chan->dst); |
| 537 | baswap((void *) src, &l2cap_pi(sock->sk)->chan->src); | 540 | baswap((void *) src, &l2cap_pi(sock->sk)->chan->src); |
| 538 | 541 | ||
diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index 67fe5e84e68f..278a194e6af4 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c | |||
| @@ -334,6 +334,9 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock) | |||
| 334 | 334 | ||
| 335 | BT_DBG(""); | 335 | BT_DBG(""); |
| 336 | 336 | ||
| 337 | if (!l2cap_is_socket(sock)) | ||
| 338 | return -EBADFD; | ||
| 339 | |||
| 337 | session = kzalloc(sizeof(struct cmtp_session), GFP_KERNEL); | 340 | session = kzalloc(sizeof(struct cmtp_session), GFP_KERNEL); |
| 338 | if (!session) | 341 | if (!session) |
| 339 | return -ENOMEM; | 342 | return -ENOMEM; |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 39a5c8a01726..3f2e8b830cbd 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
| @@ -242,7 +242,8 @@ static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb) | |||
| 242 | if (rp->status) | 242 | if (rp->status) |
| 243 | return; | 243 | return; |
| 244 | 244 | ||
| 245 | if (test_bit(HCI_SETUP, &hdev->dev_flags)) | 245 | if (test_bit(HCI_SETUP, &hdev->dev_flags) || |
| 246 | test_bit(HCI_CONFIG, &hdev->dev_flags)) | ||
| 246 | memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH); | 247 | memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH); |
| 247 | } | 248 | } |
| 248 | 249 | ||
| @@ -509,7 +510,8 @@ static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) | |||
| 509 | if (rp->status) | 510 | if (rp->status) |
| 510 | return; | 511 | return; |
| 511 | 512 | ||
| 512 | if (test_bit(HCI_SETUP, &hdev->dev_flags)) { | 513 | if (test_bit(HCI_SETUP, &hdev->dev_flags) || |
| 514 | test_bit(HCI_CONFIG, &hdev->dev_flags)) { | ||
| 513 | hdev->hci_ver = rp->hci_ver; | 515 | hdev->hci_ver = rp->hci_ver; |
| 514 | hdev->hci_rev = __le16_to_cpu(rp->hci_rev); | 516 | hdev->hci_rev = __le16_to_cpu(rp->hci_rev); |
| 515 | hdev->lmp_ver = rp->lmp_ver; | 517 | hdev->lmp_ver = rp->lmp_ver; |
| @@ -528,7 +530,8 @@ static void hci_cc_read_local_commands(struct hci_dev *hdev, | |||
| 528 | if (rp->status) | 530 | if (rp->status) |
| 529 | return; | 531 | return; |
| 530 | 532 | ||
| 531 | if (test_bit(HCI_SETUP, &hdev->dev_flags)) | 533 | if (test_bit(HCI_SETUP, &hdev->dev_flags) || |
| 534 | test_bit(HCI_CONFIG, &hdev->dev_flags)) | ||
| 532 | memcpy(hdev->commands, rp->commands, sizeof(hdev->commands)); | 535 | memcpy(hdev->commands, rp->commands, sizeof(hdev->commands)); |
| 533 | } | 536 | } |
| 534 | 537 | ||
| @@ -2194,7 +2197,12 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
| 2194 | return; | 2197 | return; |
| 2195 | } | 2198 | } |
| 2196 | 2199 | ||
| 2197 | if (!test_bit(HCI_CONNECTABLE, &hdev->dev_flags) && | 2200 | /* Require HCI_CONNECTABLE or a whitelist entry to accept the |
| 2201 | * connection. These features are only touched through mgmt so | ||
| 2202 | * only do the checks if HCI_MGMT is set. | ||
| 2203 | */ | ||
| 2204 | if (test_bit(HCI_MGMT, &hdev->dev_flags) && | ||
| 2205 | !test_bit(HCI_CONNECTABLE, &hdev->dev_flags) && | ||
| 2198 | !hci_bdaddr_list_lookup(&hdev->whitelist, &ev->bdaddr, | 2206 | !hci_bdaddr_list_lookup(&hdev->whitelist, &ev->bdaddr, |
| 2199 | BDADDR_BREDR)) { | 2207 | BDADDR_BREDR)) { |
| 2200 | hci_reject_conn(hdev, &ev->bdaddr); | 2208 | hci_reject_conn(hdev, &ev->bdaddr); |
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index cc25d0b74b36..07348e142f16 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c | |||
| @@ -1314,13 +1314,14 @@ int hidp_connection_add(struct hidp_connadd_req *req, | |||
| 1314 | { | 1314 | { |
| 1315 | struct hidp_session *session; | 1315 | struct hidp_session *session; |
| 1316 | struct l2cap_conn *conn; | 1316 | struct l2cap_conn *conn; |
| 1317 | struct l2cap_chan *chan = l2cap_pi(ctrl_sock->sk)->chan; | 1317 | struct l2cap_chan *chan; |
| 1318 | int ret; | 1318 | int ret; |
| 1319 | 1319 | ||
| 1320 | ret = hidp_verify_sockets(ctrl_sock, intr_sock); | 1320 | ret = hidp_verify_sockets(ctrl_sock, intr_sock); |
| 1321 | if (ret) | 1321 | if (ret) |
| 1322 | return ret; | 1322 | return ret; |
| 1323 | 1323 | ||
| 1324 | chan = l2cap_pi(ctrl_sock->sk)->chan; | ||
| 1324 | conn = NULL; | 1325 | conn = NULL; |
| 1325 | l2cap_chan_lock(chan); | 1326 | l2cap_chan_lock(chan); |
| 1326 | if (chan->conn) | 1327 | if (chan->conn) |
diff --git a/net/core/dev.c b/net/core/dev.c index f411c28d0a66..683d493aa1bf 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -1694,6 +1694,7 @@ int __dev_forward_skb(struct net_device *dev, struct sk_buff *skb) | |||
| 1694 | 1694 | ||
| 1695 | skb_scrub_packet(skb, true); | 1695 | skb_scrub_packet(skb, true); |
| 1696 | skb->protocol = eth_type_trans(skb, dev); | 1696 | skb->protocol = eth_type_trans(skb, dev); |
| 1697 | skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN); | ||
| 1697 | 1698 | ||
| 1698 | return 0; | 1699 | return 0; |
| 1699 | } | 1700 | } |
| @@ -2522,7 +2523,7 @@ static int illegal_highdma(struct net_device *dev, struct sk_buff *skb) | |||
| 2522 | /* If MPLS offload request, verify we are testing hardware MPLS features | 2523 | /* If MPLS offload request, verify we are testing hardware MPLS features |
| 2523 | * instead of standard features for the netdev. | 2524 | * instead of standard features for the netdev. |
| 2524 | */ | 2525 | */ |
| 2525 | #ifdef CONFIG_NET_MPLS_GSO | 2526 | #if IS_ENABLED(CONFIG_NET_MPLS_GSO) |
| 2526 | static netdev_features_t net_mpls_features(struct sk_buff *skb, | 2527 | static netdev_features_t net_mpls_features(struct sk_buff *skb, |
| 2527 | netdev_features_t features, | 2528 | netdev_features_t features, |
| 2528 | __be16 type) | 2529 | __be16 type) |
| @@ -2562,7 +2563,7 @@ static netdev_features_t harmonize_features(struct sk_buff *skb, | |||
| 2562 | 2563 | ||
| 2563 | netdev_features_t netif_skb_features(struct sk_buff *skb) | 2564 | netdev_features_t netif_skb_features(struct sk_buff *skb) |
| 2564 | { | 2565 | { |
| 2565 | const struct net_device *dev = skb->dev; | 2566 | struct net_device *dev = skb->dev; |
| 2566 | netdev_features_t features = dev->features; | 2567 | netdev_features_t features = dev->features; |
| 2567 | u16 gso_segs = skb_shinfo(skb)->gso_segs; | 2568 | u16 gso_segs = skb_shinfo(skb)->gso_segs; |
| 2568 | __be16 protocol = skb->protocol; | 2569 | __be16 protocol = skb->protocol; |
| @@ -2570,11 +2571,21 @@ netdev_features_t netif_skb_features(struct sk_buff *skb) | |||
| 2570 | if (gso_segs > dev->gso_max_segs || gso_segs < dev->gso_min_segs) | 2571 | if (gso_segs > dev->gso_max_segs || gso_segs < dev->gso_min_segs) |
| 2571 | features &= ~NETIF_F_GSO_MASK; | 2572 | features &= ~NETIF_F_GSO_MASK; |
| 2572 | 2573 | ||
| 2573 | if (protocol == htons(ETH_P_8021Q) || protocol == htons(ETH_P_8021AD)) { | 2574 | /* If encapsulation offload request, verify we are testing |
| 2574 | struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; | 2575 | * hardware encapsulation features instead of standard |
| 2575 | protocol = veh->h_vlan_encapsulated_proto; | 2576 | * features for the netdev |
| 2576 | } else if (!vlan_tx_tag_present(skb)) { | 2577 | */ |
| 2577 | return harmonize_features(skb, features); | 2578 | if (skb->encapsulation) |
| 2579 | features &= dev->hw_enc_features; | ||
| 2580 | |||
| 2581 | if (!vlan_tx_tag_present(skb)) { | ||
| 2582 | if (unlikely(protocol == htons(ETH_P_8021Q) || | ||
| 2583 | protocol == htons(ETH_P_8021AD))) { | ||
| 2584 | struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; | ||
| 2585 | protocol = veh->h_vlan_encapsulated_proto; | ||
| 2586 | } else { | ||
| 2587 | goto finalize; | ||
| 2588 | } | ||
| 2578 | } | 2589 | } |
| 2579 | 2590 | ||
| 2580 | features = netdev_intersect_features(features, | 2591 | features = netdev_intersect_features(features, |
| @@ -2591,6 +2602,11 @@ netdev_features_t netif_skb_features(struct sk_buff *skb) | |||
| 2591 | NETIF_F_HW_VLAN_CTAG_TX | | 2602 | NETIF_F_HW_VLAN_CTAG_TX | |
| 2592 | NETIF_F_HW_VLAN_STAG_TX); | 2603 | NETIF_F_HW_VLAN_STAG_TX); |
| 2593 | 2604 | ||
| 2605 | finalize: | ||
| 2606 | if (dev->netdev_ops->ndo_features_check) | ||
| 2607 | features &= dev->netdev_ops->ndo_features_check(skb, dev, | ||
| 2608 | features); | ||
| 2609 | |||
| 2594 | return harmonize_features(skb, features); | 2610 | return harmonize_features(skb, features); |
| 2595 | } | 2611 | } |
| 2596 | EXPORT_SYMBOL(netif_skb_features); | 2612 | EXPORT_SYMBOL(netif_skb_features); |
| @@ -2661,19 +2677,12 @@ static struct sk_buff *validate_xmit_skb(struct sk_buff *skb, struct net_device | |||
| 2661 | if (unlikely(!skb)) | 2677 | if (unlikely(!skb)) |
| 2662 | goto out_null; | 2678 | goto out_null; |
| 2663 | 2679 | ||
| 2664 | /* If encapsulation offload request, verify we are testing | ||
| 2665 | * hardware encapsulation features instead of standard | ||
| 2666 | * features for the netdev | ||
| 2667 | */ | ||
| 2668 | if (skb->encapsulation) | ||
| 2669 | features &= dev->hw_enc_features; | ||
| 2670 | |||
| 2671 | if (netif_needs_gso(dev, skb, features)) { | 2680 | if (netif_needs_gso(dev, skb, features)) { |
| 2672 | struct sk_buff *segs; | 2681 | struct sk_buff *segs; |
| 2673 | 2682 | ||
| 2674 | segs = skb_gso_segment(skb, features); | 2683 | segs = skb_gso_segment(skb, features); |
| 2675 | if (IS_ERR(segs)) { | 2684 | if (IS_ERR(segs)) { |
| 2676 | segs = NULL; | 2685 | goto out_kfree_skb; |
| 2677 | } else if (segs) { | 2686 | } else if (segs) { |
| 2678 | consume_skb(skb); | 2687 | consume_skb(skb); |
| 2679 | skb = segs; | 2688 | skb = segs; |
| @@ -4557,6 +4566,68 @@ void netif_napi_del(struct napi_struct *napi) | |||
| 4557 | } | 4566 | } |
| 4558 | EXPORT_SYMBOL(netif_napi_del); | 4567 | EXPORT_SYMBOL(netif_napi_del); |
| 4559 | 4568 | ||
| 4569 | static int napi_poll(struct napi_struct *n, struct list_head *repoll) | ||
| 4570 | { | ||
| 4571 | void *have; | ||
| 4572 | int work, weight; | ||
| 4573 | |||
| 4574 | list_del_init(&n->poll_list); | ||
| 4575 | |||
| 4576 | have = netpoll_poll_lock(n); | ||
| 4577 | |||
| 4578 | weight = n->weight; | ||
| 4579 | |||
| 4580 | /* This NAPI_STATE_SCHED test is for avoiding a race | ||
| 4581 | * with netpoll's poll_napi(). Only the entity which | ||
| 4582 | * obtains the lock and sees NAPI_STATE_SCHED set will | ||
| 4583 | * actually make the ->poll() call. Therefore we avoid | ||
| 4584 | * accidentally calling ->poll() when NAPI is not scheduled. | ||
| 4585 | */ | ||
| 4586 | work = 0; | ||
| 4587 | if (test_bit(NAPI_STATE_SCHED, &n->state)) { | ||
| 4588 | work = n->poll(n, weight); | ||
| 4589 | trace_napi_poll(n); | ||
| 4590 | } | ||
| 4591 | |||
| 4592 | WARN_ON_ONCE(work > weight); | ||
| 4593 | |||
| 4594 | if (likely(work < weight)) | ||
| 4595 | goto out_unlock; | ||
| 4596 | |||
| 4597 | /* Drivers must not modify the NAPI state if they | ||
| 4598 | * consume the entire weight. In such cases this code | ||
| 4599 | * still "owns" the NAPI instance and therefore can | ||
| 4600 | * move the instance around on the list at-will. | ||
| 4601 | */ | ||
| 4602 | if (unlikely(napi_disable_pending(n))) { | ||
| 4603 | napi_complete(n); | ||
| 4604 | goto out_unlock; | ||
| 4605 | } | ||
| 4606 | |||
| 4607 | if (n->gro_list) { | ||
| 4608 | /* flush too old packets | ||
| 4609 | * If HZ < 1000, flush all packets. | ||
| 4610 | */ | ||
| 4611 | napi_gro_flush(n, HZ >= 1000); | ||
| 4612 | } | ||
| 4613 | |||
| 4614 | /* Some drivers may have called napi_schedule | ||
| 4615 | * prior to exhausting their budget. | ||
| 4616 | */ | ||
| 4617 | if (unlikely(!list_empty(&n->poll_list))) { | ||
| 4618 | pr_warn_once("%s: Budget exhausted after napi rescheduled\n", | ||
| 4619 | n->dev ? n->dev->name : "backlog"); | ||
| 4620 | goto out_unlock; | ||
| 4621 | } | ||
| 4622 | |||
| 4623 | list_add_tail(&n->poll_list, repoll); | ||
| 4624 | |||
| 4625 | out_unlock: | ||
| 4626 | netpoll_poll_unlock(have); | ||
| 4627 | |||
| 4628 | return work; | ||
| 4629 | } | ||
| 4630 | |||
| 4560 | static void net_rx_action(struct softirq_action *h) | 4631 | static void net_rx_action(struct softirq_action *h) |
| 4561 | { | 4632 | { |
| 4562 | struct softnet_data *sd = this_cpu_ptr(&softnet_data); | 4633 | struct softnet_data *sd = this_cpu_ptr(&softnet_data); |
| @@ -4564,74 +4635,34 @@ static void net_rx_action(struct softirq_action *h) | |||
| 4564 | int budget = netdev_budget; | 4635 | int budget = netdev_budget; |
| 4565 | LIST_HEAD(list); | 4636 | LIST_HEAD(list); |
| 4566 | LIST_HEAD(repoll); | 4637 | LIST_HEAD(repoll); |
| 4567 | void *have; | ||
| 4568 | 4638 | ||
| 4569 | local_irq_disable(); | 4639 | local_irq_disable(); |
| 4570 | list_splice_init(&sd->poll_list, &list); | 4640 | list_splice_init(&sd->poll_list, &list); |
| 4571 | local_irq_enable(); | 4641 | local_irq_enable(); |
| 4572 | 4642 | ||
| 4573 | while (!list_empty(&list)) { | 4643 | for (;;) { |
| 4574 | struct napi_struct *n; | 4644 | struct napi_struct *n; |
| 4575 | int work, weight; | ||
| 4576 | |||
| 4577 | /* If softirq window is exhausted then punt. | ||
| 4578 | * Allow this to run for 2 jiffies since which will allow | ||
| 4579 | * an average latency of 1.5/HZ. | ||
| 4580 | */ | ||
| 4581 | if (unlikely(budget <= 0 || time_after_eq(jiffies, time_limit))) | ||
| 4582 | goto softnet_break; | ||
| 4583 | |||
| 4584 | |||
| 4585 | n = list_first_entry(&list, struct napi_struct, poll_list); | ||
| 4586 | list_del_init(&n->poll_list); | ||
| 4587 | 4645 | ||
| 4588 | have = netpoll_poll_lock(n); | 4646 | if (list_empty(&list)) { |
| 4589 | 4647 | if (!sd_has_rps_ipi_waiting(sd) && list_empty(&repoll)) | |
| 4590 | weight = n->weight; | 4648 | return; |
| 4591 | 4649 | break; | |
| 4592 | /* This NAPI_STATE_SCHED test is for avoiding a race | ||
| 4593 | * with netpoll's poll_napi(). Only the entity which | ||
| 4594 | * obtains the lock and sees NAPI_STATE_SCHED set will | ||
| 4595 | * actually make the ->poll() call. Therefore we avoid | ||
| 4596 | * accidentally calling ->poll() when NAPI is not scheduled. | ||
| 4597 | */ | ||
| 4598 | work = 0; | ||
| 4599 | if (test_bit(NAPI_STATE_SCHED, &n->state)) { | ||
| 4600 | work = n->poll(n, weight); | ||
| 4601 | trace_napi_poll(n); | ||
| 4602 | } | 4650 | } |
| 4603 | 4651 | ||
| 4604 | WARN_ON_ONCE(work > weight); | 4652 | n = list_first_entry(&list, struct napi_struct, poll_list); |
| 4605 | 4653 | budget -= napi_poll(n, &repoll); | |
| 4606 | budget -= work; | ||
| 4607 | 4654 | ||
| 4608 | /* Drivers must not modify the NAPI state if they | 4655 | /* If softirq window is exhausted then punt. |
| 4609 | * consume the entire weight. In such cases this code | 4656 | * Allow this to run for 2 jiffies since which will allow |
| 4610 | * still "owns" the NAPI instance and therefore can | 4657 | * an average latency of 1.5/HZ. |
| 4611 | * move the instance around on the list at-will. | ||
| 4612 | */ | 4658 | */ |
| 4613 | if (unlikely(work == weight)) { | 4659 | if (unlikely(budget <= 0 || |
| 4614 | if (unlikely(napi_disable_pending(n))) { | 4660 | time_after_eq(jiffies, time_limit))) { |
| 4615 | napi_complete(n); | 4661 | sd->time_squeeze++; |
| 4616 | } else { | 4662 | break; |
| 4617 | if (n->gro_list) { | ||
| 4618 | /* flush too old packets | ||
| 4619 | * If HZ < 1000, flush all packets. | ||
| 4620 | */ | ||
| 4621 | napi_gro_flush(n, HZ >= 1000); | ||
| 4622 | } | ||
| 4623 | list_add_tail(&n->poll_list, &repoll); | ||
| 4624 | } | ||
| 4625 | } | 4663 | } |
| 4626 | |||
| 4627 | netpoll_poll_unlock(have); | ||
| 4628 | } | 4664 | } |
| 4629 | 4665 | ||
| 4630 | if (!sd_has_rps_ipi_waiting(sd) && | ||
| 4631 | list_empty(&list) && | ||
| 4632 | list_empty(&repoll)) | ||
| 4633 | return; | ||
| 4634 | out: | ||
| 4635 | local_irq_disable(); | 4666 | local_irq_disable(); |
| 4636 | 4667 | ||
| 4637 | list_splice_tail_init(&sd->poll_list, &list); | 4668 | list_splice_tail_init(&sd->poll_list, &list); |
| @@ -4641,12 +4672,6 @@ out: | |||
| 4641 | __raise_softirq_irqoff(NET_RX_SOFTIRQ); | 4672 | __raise_softirq_irqoff(NET_RX_SOFTIRQ); |
| 4642 | 4673 | ||
| 4643 | net_rps_action_and_irq_enable(sd); | 4674 | net_rps_action_and_irq_enable(sd); |
| 4644 | |||
| 4645 | return; | ||
| 4646 | |||
| 4647 | softnet_break: | ||
| 4648 | sd->time_squeeze++; | ||
| 4649 | goto out; | ||
| 4650 | } | 4675 | } |
| 4651 | 4676 | ||
| 4652 | struct netdev_adjacent { | 4677 | struct netdev_adjacent { |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index ae13ef6b3ea7..395c15b82087 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
| @@ -4148,6 +4148,7 @@ void skb_scrub_packet(struct sk_buff *skb, bool xnet) | |||
| 4148 | skb->ignore_df = 0; | 4148 | skb->ignore_df = 0; |
| 4149 | skb_dst_drop(skb); | 4149 | skb_dst_drop(skb); |
| 4150 | skb->mark = 0; | 4150 | skb->mark = 0; |
| 4151 | skb_init_secmark(skb); | ||
| 4151 | secpath_reset(skb); | 4152 | secpath_reset(skb); |
| 4152 | nf_reset(skb); | 4153 | nf_reset(skb); |
| 4153 | nf_reset_trace(skb); | 4154 | nf_reset_trace(skb); |
diff --git a/net/ipv4/geneve.c b/net/ipv4/geneve.c index 95e47c97585e..394a200f93c1 100644 --- a/net/ipv4/geneve.c +++ b/net/ipv4/geneve.c | |||
| @@ -122,14 +122,18 @@ int geneve_xmit_skb(struct geneve_sock *gs, struct rtable *rt, | |||
| 122 | int err; | 122 | int err; |
| 123 | 123 | ||
| 124 | skb = udp_tunnel_handle_offloads(skb, !gs->sock->sk->sk_no_check_tx); | 124 | skb = udp_tunnel_handle_offloads(skb, !gs->sock->sk->sk_no_check_tx); |
| 125 | if (IS_ERR(skb)) | ||
| 126 | return PTR_ERR(skb); | ||
| 125 | 127 | ||
| 126 | min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len | 128 | min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len |
| 127 | + GENEVE_BASE_HLEN + opt_len + sizeof(struct iphdr) | 129 | + GENEVE_BASE_HLEN + opt_len + sizeof(struct iphdr) |
| 128 | + (vlan_tx_tag_present(skb) ? VLAN_HLEN : 0); | 130 | + (vlan_tx_tag_present(skb) ? VLAN_HLEN : 0); |
| 129 | 131 | ||
| 130 | err = skb_cow_head(skb, min_headroom); | 132 | err = skb_cow_head(skb, min_headroom); |
| 131 | if (unlikely(err)) | 133 | if (unlikely(err)) { |
| 134 | kfree_skb(skb); | ||
| 132 | return err; | 135 | return err; |
| 136 | } | ||
| 133 | 137 | ||
| 134 | skb = vlan_hwaccel_push_inside(skb); | 138 | skb = vlan_hwaccel_push_inside(skb); |
| 135 | if (unlikely(!skb)) | 139 | if (unlikely(!skb)) |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 5ff87805258e..9c0b54e87b47 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
| @@ -1387,6 +1387,28 @@ ipv6_pktoptions: | |||
| 1387 | return 0; | 1387 | return 0; |
| 1388 | } | 1388 | } |
| 1389 | 1389 | ||
| 1390 | static void tcp_v6_fill_cb(struct sk_buff *skb, const struct ipv6hdr *hdr, | ||
| 1391 | const struct tcphdr *th) | ||
| 1392 | { | ||
| 1393 | /* This is tricky: we move IP6CB at its correct location into | ||
| 1394 | * TCP_SKB_CB(). It must be done after xfrm6_policy_check(), because | ||
| 1395 | * _decode_session6() uses IP6CB(). | ||
| 1396 | * barrier() makes sure compiler won't play aliasing games. | ||
| 1397 | */ | ||
| 1398 | memmove(&TCP_SKB_CB(skb)->header.h6, IP6CB(skb), | ||
| 1399 | sizeof(struct inet6_skb_parm)); | ||
| 1400 | barrier(); | ||
| 1401 | |||
| 1402 | TCP_SKB_CB(skb)->seq = ntohl(th->seq); | ||
| 1403 | TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + | ||
| 1404 | skb->len - th->doff*4); | ||
| 1405 | TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq); | ||
| 1406 | TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th); | ||
| 1407 | TCP_SKB_CB(skb)->tcp_tw_isn = 0; | ||
| 1408 | TCP_SKB_CB(skb)->ip_dsfield = ipv6_get_dsfield(hdr); | ||
| 1409 | TCP_SKB_CB(skb)->sacked = 0; | ||
| 1410 | } | ||
| 1411 | |||
| 1390 | static int tcp_v6_rcv(struct sk_buff *skb) | 1412 | static int tcp_v6_rcv(struct sk_buff *skb) |
| 1391 | { | 1413 | { |
| 1392 | const struct tcphdr *th; | 1414 | const struct tcphdr *th; |
| @@ -1418,24 +1440,9 @@ static int tcp_v6_rcv(struct sk_buff *skb) | |||
| 1418 | 1440 | ||
| 1419 | th = tcp_hdr(skb); | 1441 | th = tcp_hdr(skb); |
| 1420 | hdr = ipv6_hdr(skb); | 1442 | hdr = ipv6_hdr(skb); |
| 1421 | /* This is tricky : We move IPCB at its correct location into TCP_SKB_CB() | ||
| 1422 | * barrier() makes sure compiler wont play fool^Waliasing games. | ||
| 1423 | */ | ||
| 1424 | memmove(&TCP_SKB_CB(skb)->header.h6, IP6CB(skb), | ||
| 1425 | sizeof(struct inet6_skb_parm)); | ||
| 1426 | barrier(); | ||
| 1427 | |||
| 1428 | TCP_SKB_CB(skb)->seq = ntohl(th->seq); | ||
| 1429 | TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + | ||
| 1430 | skb->len - th->doff*4); | ||
| 1431 | TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq); | ||
| 1432 | TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th); | ||
| 1433 | TCP_SKB_CB(skb)->tcp_tw_isn = 0; | ||
| 1434 | TCP_SKB_CB(skb)->ip_dsfield = ipv6_get_dsfield(hdr); | ||
| 1435 | TCP_SKB_CB(skb)->sacked = 0; | ||
| 1436 | 1443 | ||
| 1437 | sk = __inet6_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest, | 1444 | sk = __inet6_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest, |
| 1438 | tcp_v6_iif(skb)); | 1445 | inet6_iif(skb)); |
| 1439 | if (!sk) | 1446 | if (!sk) |
| 1440 | goto no_tcp_socket; | 1447 | goto no_tcp_socket; |
| 1441 | 1448 | ||
| @@ -1451,6 +1458,8 @@ process: | |||
| 1451 | if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) | 1458 | if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) |
| 1452 | goto discard_and_relse; | 1459 | goto discard_and_relse; |
| 1453 | 1460 | ||
| 1461 | tcp_v6_fill_cb(skb, hdr, th); | ||
| 1462 | |||
| 1454 | #ifdef CONFIG_TCP_MD5SIG | 1463 | #ifdef CONFIG_TCP_MD5SIG |
| 1455 | if (tcp_v6_inbound_md5_hash(sk, skb)) | 1464 | if (tcp_v6_inbound_md5_hash(sk, skb)) |
| 1456 | goto discard_and_relse; | 1465 | goto discard_and_relse; |
| @@ -1482,6 +1491,8 @@ no_tcp_socket: | |||
| 1482 | if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) | 1491 | if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) |
| 1483 | goto discard_it; | 1492 | goto discard_it; |
| 1484 | 1493 | ||
| 1494 | tcp_v6_fill_cb(skb, hdr, th); | ||
| 1495 | |||
| 1485 | if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) { | 1496 | if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) { |
| 1486 | csum_error: | 1497 | csum_error: |
| 1487 | TCP_INC_STATS_BH(net, TCP_MIB_CSUMERRORS); | 1498 | TCP_INC_STATS_BH(net, TCP_MIB_CSUMERRORS); |
| @@ -1505,6 +1516,8 @@ do_time_wait: | |||
| 1505 | goto discard_it; | 1516 | goto discard_it; |
| 1506 | } | 1517 | } |
| 1507 | 1518 | ||
| 1519 | tcp_v6_fill_cb(skb, hdr, th); | ||
| 1520 | |||
| 1508 | if (skb->len < (th->doff<<2)) { | 1521 | if (skb->len < (th->doff<<2)) { |
| 1509 | inet_twsk_put(inet_twsk(sk)); | 1522 | inet_twsk_put(inet_twsk(sk)); |
| 1510 | goto bad_packet; | 1523 | goto bad_packet; |
diff --git a/net/mpls/mpls_gso.c b/net/mpls/mpls_gso.c index ca27837974fe..349295d21946 100644 --- a/net/mpls/mpls_gso.c +++ b/net/mpls/mpls_gso.c | |||
| @@ -31,10 +31,7 @@ static struct sk_buff *mpls_gso_segment(struct sk_buff *skb, | |||
| 31 | SKB_GSO_TCPV6 | | 31 | SKB_GSO_TCPV6 | |
| 32 | SKB_GSO_UDP | | 32 | SKB_GSO_UDP | |
| 33 | SKB_GSO_DODGY | | 33 | SKB_GSO_DODGY | |
| 34 | SKB_GSO_TCP_ECN | | 34 | SKB_GSO_TCP_ECN))) |
| 35 | SKB_GSO_GRE | | ||
| 36 | SKB_GSO_GRE_CSUM | | ||
| 37 | SKB_GSO_IPIP))) | ||
| 38 | goto out; | 35 | goto out; |
| 39 | 36 | ||
| 40 | /* Setup inner SKB. */ | 37 | /* Setup inner SKB. */ |
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c index 13c2e17bbe27..cde4a6702fa3 100644 --- a/net/netfilter/nfnetlink.c +++ b/net/netfilter/nfnetlink.c | |||
| @@ -463,7 +463,7 @@ static void nfnetlink_rcv(struct sk_buff *skb) | |||
| 463 | } | 463 | } |
| 464 | 464 | ||
| 465 | #ifdef CONFIG_MODULES | 465 | #ifdef CONFIG_MODULES |
| 466 | static int nfnetlink_bind(int group) | 466 | static int nfnetlink_bind(struct net *net, int group) |
| 467 | { | 467 | { |
| 468 | const struct nfnetlink_subsystem *ss; | 468 | const struct nfnetlink_subsystem *ss; |
| 469 | int type; | 469 | int type; |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 074cf3e91c6f..84ea76ca3f1f 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
| @@ -1091,8 +1091,10 @@ static void netlink_remove(struct sock *sk) | |||
| 1091 | mutex_unlock(&nl_sk_hash_lock); | 1091 | mutex_unlock(&nl_sk_hash_lock); |
| 1092 | 1092 | ||
| 1093 | netlink_table_grab(); | 1093 | netlink_table_grab(); |
| 1094 | if (nlk_sk(sk)->subscriptions) | 1094 | if (nlk_sk(sk)->subscriptions) { |
| 1095 | __sk_del_bind_node(sk); | 1095 | __sk_del_bind_node(sk); |
| 1096 | netlink_update_listeners(sk); | ||
| 1097 | } | ||
| 1096 | netlink_table_ungrab(); | 1098 | netlink_table_ungrab(); |
| 1097 | } | 1099 | } |
| 1098 | 1100 | ||
| @@ -1139,8 +1141,8 @@ static int netlink_create(struct net *net, struct socket *sock, int protocol, | |||
| 1139 | struct module *module = NULL; | 1141 | struct module *module = NULL; |
| 1140 | struct mutex *cb_mutex; | 1142 | struct mutex *cb_mutex; |
| 1141 | struct netlink_sock *nlk; | 1143 | struct netlink_sock *nlk; |
| 1142 | int (*bind)(int group); | 1144 | int (*bind)(struct net *net, int group); |
| 1143 | void (*unbind)(int group); | 1145 | void (*unbind)(struct net *net, int group); |
| 1144 | int err = 0; | 1146 | int err = 0; |
| 1145 | 1147 | ||
| 1146 | sock->state = SS_UNCONNECTED; | 1148 | sock->state = SS_UNCONNECTED; |
| @@ -1226,8 +1228,8 @@ static int netlink_release(struct socket *sock) | |||
| 1226 | 1228 | ||
| 1227 | module_put(nlk->module); | 1229 | module_put(nlk->module); |
| 1228 | 1230 | ||
| 1229 | netlink_table_grab(); | ||
| 1230 | if (netlink_is_kernel(sk)) { | 1231 | if (netlink_is_kernel(sk)) { |
| 1232 | netlink_table_grab(); | ||
| 1231 | BUG_ON(nl_table[sk->sk_protocol].registered == 0); | 1233 | BUG_ON(nl_table[sk->sk_protocol].registered == 0); |
| 1232 | if (--nl_table[sk->sk_protocol].registered == 0) { | 1234 | if (--nl_table[sk->sk_protocol].registered == 0) { |
| 1233 | struct listeners *old; | 1235 | struct listeners *old; |
| @@ -1241,11 +1243,16 @@ static int netlink_release(struct socket *sock) | |||
| 1241 | nl_table[sk->sk_protocol].flags = 0; | 1243 | nl_table[sk->sk_protocol].flags = 0; |
| 1242 | nl_table[sk->sk_protocol].registered = 0; | 1244 | nl_table[sk->sk_protocol].registered = 0; |
| 1243 | } | 1245 | } |
| 1244 | } else if (nlk->subscriptions) { | 1246 | netlink_table_ungrab(); |
| 1245 | netlink_update_listeners(sk); | ||
| 1246 | } | 1247 | } |
| 1247 | netlink_table_ungrab(); | ||
| 1248 | 1248 | ||
| 1249 | if (nlk->netlink_unbind) { | ||
| 1250 | int i; | ||
| 1251 | |||
| 1252 | for (i = 0; i < nlk->ngroups; i++) | ||
| 1253 | if (test_bit(i, nlk->groups)) | ||
| 1254 | nlk->netlink_unbind(sock_net(sk), i + 1); | ||
| 1255 | } | ||
| 1249 | kfree(nlk->groups); | 1256 | kfree(nlk->groups); |
| 1250 | nlk->groups = NULL; | 1257 | nlk->groups = NULL; |
| 1251 | 1258 | ||
| @@ -1410,9 +1417,10 @@ static int netlink_realloc_groups(struct sock *sk) | |||
| 1410 | return err; | 1417 | return err; |
| 1411 | } | 1418 | } |
| 1412 | 1419 | ||
| 1413 | static void netlink_unbind(int group, long unsigned int groups, | 1420 | static void netlink_undo_bind(int group, long unsigned int groups, |
| 1414 | struct netlink_sock *nlk) | 1421 | struct sock *sk) |
| 1415 | { | 1422 | { |
| 1423 | struct netlink_sock *nlk = nlk_sk(sk); | ||
| 1416 | int undo; | 1424 | int undo; |
| 1417 | 1425 | ||
| 1418 | if (!nlk->netlink_unbind) | 1426 | if (!nlk->netlink_unbind) |
| @@ -1420,7 +1428,7 @@ static void netlink_unbind(int group, long unsigned int groups, | |||
| 1420 | 1428 | ||
| 1421 | for (undo = 0; undo < group; undo++) | 1429 | for (undo = 0; undo < group; undo++) |
| 1422 | if (test_bit(undo, &groups)) | 1430 | if (test_bit(undo, &groups)) |
| 1423 | nlk->netlink_unbind(undo); | 1431 | nlk->netlink_unbind(sock_net(sk), undo); |
| 1424 | } | 1432 | } |
| 1425 | 1433 | ||
| 1426 | static int netlink_bind(struct socket *sock, struct sockaddr *addr, | 1434 | static int netlink_bind(struct socket *sock, struct sockaddr *addr, |
| @@ -1458,10 +1466,10 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr, | |||
| 1458 | for (group = 0; group < nlk->ngroups; group++) { | 1466 | for (group = 0; group < nlk->ngroups; group++) { |
| 1459 | if (!test_bit(group, &groups)) | 1467 | if (!test_bit(group, &groups)) |
| 1460 | continue; | 1468 | continue; |
| 1461 | err = nlk->netlink_bind(group); | 1469 | err = nlk->netlink_bind(net, group); |
| 1462 | if (!err) | 1470 | if (!err) |
| 1463 | continue; | 1471 | continue; |
| 1464 | netlink_unbind(group, groups, nlk); | 1472 | netlink_undo_bind(group, groups, sk); |
| 1465 | return err; | 1473 | return err; |
| 1466 | } | 1474 | } |
| 1467 | } | 1475 | } |
| @@ -1471,7 +1479,7 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr, | |||
| 1471 | netlink_insert(sk, net, nladdr->nl_pid) : | 1479 | netlink_insert(sk, net, nladdr->nl_pid) : |
| 1472 | netlink_autobind(sock); | 1480 | netlink_autobind(sock); |
| 1473 | if (err) { | 1481 | if (err) { |
| 1474 | netlink_unbind(nlk->ngroups, groups, nlk); | 1482 | netlink_undo_bind(nlk->ngroups, groups, sk); |
| 1475 | return err; | 1483 | return err; |
| 1476 | } | 1484 | } |
| 1477 | } | 1485 | } |
| @@ -2122,7 +2130,7 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname, | |||
| 2122 | if (!val || val - 1 >= nlk->ngroups) | 2130 | if (!val || val - 1 >= nlk->ngroups) |
| 2123 | return -EINVAL; | 2131 | return -EINVAL; |
| 2124 | if (optname == NETLINK_ADD_MEMBERSHIP && nlk->netlink_bind) { | 2132 | if (optname == NETLINK_ADD_MEMBERSHIP && nlk->netlink_bind) { |
| 2125 | err = nlk->netlink_bind(val); | 2133 | err = nlk->netlink_bind(sock_net(sk), val); |
| 2126 | if (err) | 2134 | if (err) |
| 2127 | return err; | 2135 | return err; |
| 2128 | } | 2136 | } |
| @@ -2131,7 +2139,7 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname, | |||
| 2131 | optname == NETLINK_ADD_MEMBERSHIP); | 2139 | optname == NETLINK_ADD_MEMBERSHIP); |
| 2132 | netlink_table_ungrab(); | 2140 | netlink_table_ungrab(); |
| 2133 | if (optname == NETLINK_DROP_MEMBERSHIP && nlk->netlink_unbind) | 2141 | if (optname == NETLINK_DROP_MEMBERSHIP && nlk->netlink_unbind) |
| 2134 | nlk->netlink_unbind(val); | 2142 | nlk->netlink_unbind(sock_net(sk), val); |
| 2135 | 2143 | ||
| 2136 | err = 0; | 2144 | err = 0; |
| 2137 | break; | 2145 | break; |
diff --git a/net/netlink/af_netlink.h b/net/netlink/af_netlink.h index b20a1731759b..f123a88496f8 100644 --- a/net/netlink/af_netlink.h +++ b/net/netlink/af_netlink.h | |||
| @@ -39,8 +39,8 @@ struct netlink_sock { | |||
| 39 | struct mutex *cb_mutex; | 39 | struct mutex *cb_mutex; |
| 40 | struct mutex cb_def_mutex; | 40 | struct mutex cb_def_mutex; |
| 41 | void (*netlink_rcv)(struct sk_buff *skb); | 41 | void (*netlink_rcv)(struct sk_buff *skb); |
| 42 | int (*netlink_bind)(int group); | 42 | int (*netlink_bind)(struct net *net, int group); |
| 43 | void (*netlink_unbind)(int group); | 43 | void (*netlink_unbind)(struct net *net, int group); |
| 44 | struct module *module; | 44 | struct module *module; |
| 45 | #ifdef CONFIG_NETLINK_MMAP | 45 | #ifdef CONFIG_NETLINK_MMAP |
| 46 | struct mutex pg_vec_lock; | 46 | struct mutex pg_vec_lock; |
| @@ -65,8 +65,8 @@ struct netlink_table { | |||
| 65 | unsigned int groups; | 65 | unsigned int groups; |
| 66 | struct mutex *cb_mutex; | 66 | struct mutex *cb_mutex; |
| 67 | struct module *module; | 67 | struct module *module; |
| 68 | int (*bind)(int group); | 68 | int (*bind)(struct net *net, int group); |
| 69 | void (*unbind)(int group); | 69 | void (*unbind)(struct net *net, int group); |
| 70 | bool (*compare)(struct net *net, struct sock *sock); | 70 | bool (*compare)(struct net *net, struct sock *sock); |
| 71 | int registered; | 71 | int registered; |
| 72 | }; | 72 | }; |
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 76393f2f4b22..2e11061ef885 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c | |||
| @@ -983,11 +983,67 @@ static struct genl_multicast_group genl_ctrl_groups[] = { | |||
| 983 | { .name = "notify", }, | 983 | { .name = "notify", }, |
| 984 | }; | 984 | }; |
| 985 | 985 | ||
| 986 | static int genl_bind(struct net *net, int group) | ||
| 987 | { | ||
| 988 | int i, err = 0; | ||
| 989 | |||
| 990 | down_read(&cb_lock); | ||
| 991 | for (i = 0; i < GENL_FAM_TAB_SIZE; i++) { | ||
| 992 | struct genl_family *f; | ||
| 993 | |||
| 994 | list_for_each_entry(f, genl_family_chain(i), family_list) { | ||
| 995 | if (group >= f->mcgrp_offset && | ||
| 996 | group < f->mcgrp_offset + f->n_mcgrps) { | ||
| 997 | int fam_grp = group - f->mcgrp_offset; | ||
| 998 | |||
| 999 | if (!f->netnsok && net != &init_net) | ||
| 1000 | err = -ENOENT; | ||
| 1001 | else if (f->mcast_bind) | ||
| 1002 | err = f->mcast_bind(net, fam_grp); | ||
| 1003 | else | ||
| 1004 | err = 0; | ||
| 1005 | break; | ||
| 1006 | } | ||
| 1007 | } | ||
| 1008 | } | ||
| 1009 | up_read(&cb_lock); | ||
| 1010 | |||
| 1011 | return err; | ||
| 1012 | } | ||
| 1013 | |||
| 1014 | static void genl_unbind(struct net *net, int group) | ||
| 1015 | { | ||
| 1016 | int i; | ||
| 1017 | bool found = false; | ||
| 1018 | |||
| 1019 | down_read(&cb_lock); | ||
| 1020 | for (i = 0; i < GENL_FAM_TAB_SIZE; i++) { | ||
| 1021 | struct genl_family *f; | ||
| 1022 | |||
| 1023 | list_for_each_entry(f, genl_family_chain(i), family_list) { | ||
| 1024 | if (group >= f->mcgrp_offset && | ||
| 1025 | group < f->mcgrp_offset + f->n_mcgrps) { | ||
| 1026 | int fam_grp = group - f->mcgrp_offset; | ||
| 1027 | |||
| 1028 | if (f->mcast_unbind) | ||
| 1029 | f->mcast_unbind(net, fam_grp); | ||
| 1030 | found = true; | ||
| 1031 | break; | ||
| 1032 | } | ||
| 1033 | } | ||
| 1034 | } | ||
| 1035 | up_read(&cb_lock); | ||
| 1036 | |||
| 1037 | WARN_ON(!found); | ||
| 1038 | } | ||
| 1039 | |||
| 986 | static int __net_init genl_pernet_init(struct net *net) | 1040 | static int __net_init genl_pernet_init(struct net *net) |
| 987 | { | 1041 | { |
| 988 | struct netlink_kernel_cfg cfg = { | 1042 | struct netlink_kernel_cfg cfg = { |
| 989 | .input = genl_rcv, | 1043 | .input = genl_rcv, |
| 990 | .flags = NL_CFG_F_NONROOT_RECV, | 1044 | .flags = NL_CFG_F_NONROOT_RECV, |
| 1045 | .bind = genl_bind, | ||
| 1046 | .unbind = genl_unbind, | ||
| 991 | }; | 1047 | }; |
| 992 | 1048 | ||
| 993 | /* we'll bump the group number right afterwards */ | 1049 | /* we'll bump the group number right afterwards */ |
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index 764fdc39c63b..770064c83711 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c | |||
| @@ -147,7 +147,8 @@ static int push_mpls(struct sk_buff *skb, struct sw_flow_key *key, | |||
| 147 | hdr = eth_hdr(skb); | 147 | hdr = eth_hdr(skb); |
| 148 | hdr->h_proto = mpls->mpls_ethertype; | 148 | hdr->h_proto = mpls->mpls_ethertype; |
| 149 | 149 | ||
| 150 | skb_set_inner_protocol(skb, skb->protocol); | 150 | if (!skb->inner_protocol) |
| 151 | skb_set_inner_protocol(skb, skb->protocol); | ||
| 151 | skb->protocol = mpls->mpls_ethertype; | 152 | skb->protocol = mpls->mpls_ethertype; |
| 152 | 153 | ||
| 153 | invalidate_flow_key(key); | 154 | invalidate_flow_key(key); |
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index 332b5a031739..4e9a5f035cbc 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c | |||
| @@ -83,8 +83,7 @@ static bool ovs_must_notify(struct genl_family *family, struct genl_info *info, | |||
| 83 | unsigned int group) | 83 | unsigned int group) |
| 84 | { | 84 | { |
| 85 | return info->nlhdr->nlmsg_flags & NLM_F_ECHO || | 85 | return info->nlhdr->nlmsg_flags & NLM_F_ECHO || |
| 86 | genl_has_listeners(family, genl_info_net(info)->genl_sock, | 86 | genl_has_listeners(family, genl_info_net(info), group); |
| 87 | group); | ||
| 88 | } | 87 | } |
| 89 | 88 | ||
| 90 | static void ovs_notify(struct genl_family *family, | 89 | static void ovs_notify(struct genl_family *family, |
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c index 9645a21d9eaa..d1eecf707613 100644 --- a/net/openvswitch/flow_netlink.c +++ b/net/openvswitch/flow_netlink.c | |||
| @@ -1753,7 +1753,6 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr, | |||
| 1753 | __be16 eth_type, __be16 vlan_tci, bool log) | 1753 | __be16 eth_type, __be16 vlan_tci, bool log) |
| 1754 | { | 1754 | { |
| 1755 | const struct nlattr *a; | 1755 | const struct nlattr *a; |
| 1756 | bool out_tnl_port = false; | ||
| 1757 | int rem, err; | 1756 | int rem, err; |
| 1758 | 1757 | ||
| 1759 | if (depth >= SAMPLE_ACTION_DEPTH) | 1758 | if (depth >= SAMPLE_ACTION_DEPTH) |
| @@ -1796,8 +1795,6 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr, | |||
| 1796 | case OVS_ACTION_ATTR_OUTPUT: | 1795 | case OVS_ACTION_ATTR_OUTPUT: |
| 1797 | if (nla_get_u32(a) >= DP_MAX_PORTS) | 1796 | if (nla_get_u32(a) >= DP_MAX_PORTS) |
| 1798 | return -EINVAL; | 1797 | return -EINVAL; |
| 1799 | out_tnl_port = false; | ||
| 1800 | |||
| 1801 | break; | 1798 | break; |
| 1802 | 1799 | ||
| 1803 | case OVS_ACTION_ATTR_HASH: { | 1800 | case OVS_ACTION_ATTR_HASH: { |
| @@ -1832,12 +1829,6 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr, | |||
| 1832 | case OVS_ACTION_ATTR_PUSH_MPLS: { | 1829 | case OVS_ACTION_ATTR_PUSH_MPLS: { |
| 1833 | const struct ovs_action_push_mpls *mpls = nla_data(a); | 1830 | const struct ovs_action_push_mpls *mpls = nla_data(a); |
| 1834 | 1831 | ||
| 1835 | /* Networking stack do not allow simultaneous Tunnel | ||
| 1836 | * and MPLS GSO. | ||
| 1837 | */ | ||
| 1838 | if (out_tnl_port) | ||
| 1839 | return -EINVAL; | ||
| 1840 | |||
| 1841 | if (!eth_p_mpls(mpls->mpls_ethertype)) | 1832 | if (!eth_p_mpls(mpls->mpls_ethertype)) |
| 1842 | return -EINVAL; | 1833 | return -EINVAL; |
| 1843 | /* Prohibit push MPLS other than to a white list | 1834 | /* Prohibit push MPLS other than to a white list |
| @@ -1873,11 +1864,9 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr, | |||
| 1873 | 1864 | ||
| 1874 | case OVS_ACTION_ATTR_SET: | 1865 | case OVS_ACTION_ATTR_SET: |
| 1875 | err = validate_set(a, key, sfa, | 1866 | err = validate_set(a, key, sfa, |
| 1876 | &out_tnl_port, eth_type, log); | 1867 | &skip_copy, eth_type, log); |
| 1877 | if (err) | 1868 | if (err) |
| 1878 | return err; | 1869 | return err; |
| 1879 | |||
| 1880 | skip_copy = out_tnl_port; | ||
| 1881 | break; | 1870 | break; |
| 1882 | 1871 | ||
| 1883 | case OVS_ACTION_ATTR_SAMPLE: | 1872 | case OVS_ACTION_ATTR_SAMPLE: |
diff --git a/net/openvswitch/vport-geneve.c b/net/openvswitch/vport-geneve.c index 347fa2325b22..484864dd0e68 100644 --- a/net/openvswitch/vport-geneve.c +++ b/net/openvswitch/vport-geneve.c | |||
| @@ -219,7 +219,10 @@ static int geneve_tnl_send(struct vport *vport, struct sk_buff *skb) | |||
| 219 | false); | 219 | false); |
| 220 | if (err < 0) | 220 | if (err < 0) |
| 221 | ip_rt_put(rt); | 221 | ip_rt_put(rt); |
| 222 | return err; | ||
| 223 | |||
| 222 | error: | 224 | error: |
| 225 | kfree_skb(skb); | ||
| 223 | return err; | 226 | return err; |
| 224 | } | 227 | } |
| 225 | 228 | ||
diff --git a/net/openvswitch/vport-gre.c b/net/openvswitch/vport-gre.c index 6b69df545b1d..d4168c442db5 100644 --- a/net/openvswitch/vport-gre.c +++ b/net/openvswitch/vport-gre.c | |||
| @@ -73,7 +73,7 @@ static struct sk_buff *__build_header(struct sk_buff *skb, | |||
| 73 | 73 | ||
| 74 | skb = gre_handle_offloads(skb, !!(tun_key->tun_flags & TUNNEL_CSUM)); | 74 | skb = gre_handle_offloads(skb, !!(tun_key->tun_flags & TUNNEL_CSUM)); |
| 75 | if (IS_ERR(skb)) | 75 | if (IS_ERR(skb)) |
| 76 | return NULL; | 76 | return skb; |
| 77 | 77 | ||
| 78 | tpi.flags = filter_tnl_flags(tun_key->tun_flags); | 78 | tpi.flags = filter_tnl_flags(tun_key->tun_flags); |
| 79 | tpi.proto = htons(ETH_P_TEB); | 79 | tpi.proto = htons(ETH_P_TEB); |
| @@ -144,7 +144,7 @@ static int gre_tnl_send(struct vport *vport, struct sk_buff *skb) | |||
| 144 | 144 | ||
| 145 | if (unlikely(!OVS_CB(skb)->egress_tun_info)) { | 145 | if (unlikely(!OVS_CB(skb)->egress_tun_info)) { |
| 146 | err = -EINVAL; | 146 | err = -EINVAL; |
| 147 | goto error; | 147 | goto err_free_skb; |
| 148 | } | 148 | } |
| 149 | 149 | ||
| 150 | tun_key = &OVS_CB(skb)->egress_tun_info->tunnel; | 150 | tun_key = &OVS_CB(skb)->egress_tun_info->tunnel; |
| @@ -157,8 +157,10 @@ static int gre_tnl_send(struct vport *vport, struct sk_buff *skb) | |||
| 157 | fl.flowi4_proto = IPPROTO_GRE; | 157 | fl.flowi4_proto = IPPROTO_GRE; |
| 158 | 158 | ||
| 159 | rt = ip_route_output_key(net, &fl); | 159 | rt = ip_route_output_key(net, &fl); |
| 160 | if (IS_ERR(rt)) | 160 | if (IS_ERR(rt)) { |
| 161 | return PTR_ERR(rt); | 161 | err = PTR_ERR(rt); |
| 162 | goto err_free_skb; | ||
| 163 | } | ||
| 162 | 164 | ||
| 163 | tunnel_hlen = ip_gre_calc_hlen(tun_key->tun_flags); | 165 | tunnel_hlen = ip_gre_calc_hlen(tun_key->tun_flags); |
| 164 | 166 | ||
| @@ -183,8 +185,9 @@ static int gre_tnl_send(struct vport *vport, struct sk_buff *skb) | |||
| 183 | 185 | ||
| 184 | /* Push Tunnel header. */ | 186 | /* Push Tunnel header. */ |
| 185 | skb = __build_header(skb, tunnel_hlen); | 187 | skb = __build_header(skb, tunnel_hlen); |
| 186 | if (unlikely(!skb)) { | 188 | if (IS_ERR(skb)) { |
| 187 | err = 0; | 189 | err = PTR_ERR(skb); |
| 190 | skb = NULL; | ||
| 188 | goto err_free_rt; | 191 | goto err_free_rt; |
| 189 | } | 192 | } |
| 190 | 193 | ||
| @@ -198,7 +201,8 @@ static int gre_tnl_send(struct vport *vport, struct sk_buff *skb) | |||
| 198 | tun_key->ipv4_tos, tun_key->ipv4_ttl, df, false); | 201 | tun_key->ipv4_tos, tun_key->ipv4_ttl, df, false); |
| 199 | err_free_rt: | 202 | err_free_rt: |
| 200 | ip_rt_put(rt); | 203 | ip_rt_put(rt); |
| 201 | error: | 204 | err_free_skb: |
| 205 | kfree_skb(skb); | ||
| 202 | return err; | 206 | return err; |
| 203 | } | 207 | } |
| 204 | 208 | ||
diff --git a/net/openvswitch/vport-vxlan.c b/net/openvswitch/vport-vxlan.c index 38f95a52241b..d7c46b301024 100644 --- a/net/openvswitch/vport-vxlan.c +++ b/net/openvswitch/vport-vxlan.c | |||
| @@ -187,7 +187,9 @@ static int vxlan_tnl_send(struct vport *vport, struct sk_buff *skb) | |||
| 187 | false); | 187 | false); |
| 188 | if (err < 0) | 188 | if (err < 0) |
| 189 | ip_rt_put(rt); | 189 | ip_rt_put(rt); |
| 190 | return err; | ||
| 190 | error: | 191 | error: |
| 192 | kfree_skb(skb); | ||
| 191 | return err; | 193 | return err; |
| 192 | } | 194 | } |
| 193 | 195 | ||
diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c index 9584526c0778..53f3ebbfceab 100644 --- a/net/openvswitch/vport.c +++ b/net/openvswitch/vport.c | |||
| @@ -519,10 +519,9 @@ int ovs_vport_send(struct vport *vport, struct sk_buff *skb) | |||
| 519 | u64_stats_update_end(&stats->syncp); | 519 | u64_stats_update_end(&stats->syncp); |
| 520 | } else if (sent < 0) { | 520 | } else if (sent < 0) { |
| 521 | ovs_vport_record_error(vport, VPORT_E_TX_ERROR); | 521 | ovs_vport_record_error(vport, VPORT_E_TX_ERROR); |
| 522 | kfree_skb(skb); | 522 | } else { |
| 523 | } else | ||
| 524 | ovs_vport_record_error(vport, VPORT_E_TX_DROPPED); | 523 | ovs_vport_record_error(vport, VPORT_E_TX_DROPPED); |
| 525 | 524 | } | |
| 526 | return sent; | 525 | return sent; |
| 527 | } | 526 | } |
| 528 | 527 | ||
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index e52a44785681..6880f34a529a 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
| @@ -785,6 +785,7 @@ static void prb_close_block(struct tpacket_kbdq_core *pkc1, | |||
| 785 | 785 | ||
| 786 | struct tpacket3_hdr *last_pkt; | 786 | struct tpacket3_hdr *last_pkt; |
| 787 | struct tpacket_hdr_v1 *h1 = &pbd1->hdr.bh1; | 787 | struct tpacket_hdr_v1 *h1 = &pbd1->hdr.bh1; |
| 788 | struct sock *sk = &po->sk; | ||
| 788 | 789 | ||
| 789 | if (po->stats.stats3.tp_drops) | 790 | if (po->stats.stats3.tp_drops) |
| 790 | status |= TP_STATUS_LOSING; | 791 | status |= TP_STATUS_LOSING; |
| @@ -809,6 +810,8 @@ static void prb_close_block(struct tpacket_kbdq_core *pkc1, | |||
| 809 | /* Flush the block */ | 810 | /* Flush the block */ |
| 810 | prb_flush_block(pkc1, pbd1, status); | 811 | prb_flush_block(pkc1, pbd1, status); |
| 811 | 812 | ||
| 813 | sk->sk_data_ready(sk); | ||
| 814 | |||
| 812 | pkc1->kactive_blk_num = GET_NEXT_PRB_BLK_NUM(pkc1); | 815 | pkc1->kactive_blk_num = GET_NEXT_PRB_BLK_NUM(pkc1); |
| 813 | } | 816 | } |
| 814 | 817 | ||
| @@ -2052,12 +2055,12 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, | |||
| 2052 | smp_wmb(); | 2055 | smp_wmb(); |
| 2053 | #endif | 2056 | #endif |
| 2054 | 2057 | ||
| 2055 | if (po->tp_version <= TPACKET_V2) | 2058 | if (po->tp_version <= TPACKET_V2) { |
| 2056 | __packet_set_status(po, h.raw, status); | 2059 | __packet_set_status(po, h.raw, status); |
| 2057 | else | 2060 | sk->sk_data_ready(sk); |
| 2061 | } else { | ||
| 2058 | prb_clear_blk_fill_status(&po->rx_ring); | 2062 | prb_clear_blk_fill_status(&po->rx_ring); |
| 2059 | 2063 | } | |
| 2060 | sk->sk_data_ready(sk); | ||
| 2061 | 2064 | ||
| 2062 | drop_n_restore: | 2065 | drop_n_restore: |
| 2063 | if (skb_head != skb->data && skb_shared(skb)) { | 2066 | if (skb_head != skb->data && skb_shared(skb)) { |
