summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/bpf/bpf_devel_QA.txt12
-rw-r--r--Documentation/devicetree/bindings/net/dsa/marvell.txt11
-rw-r--r--Documentation/devicetree/bindings/net/ieee802154/mcr20a.txt23
-rw-r--r--Documentation/devicetree/bindings/net/macb.txt1
-rw-r--r--Documentation/devicetree/bindings/net/sff,sfp.txt5
-rw-r--r--Documentation/devicetree/bindings/net/ti,dp83867.txt2
-rw-r--r--Documentation/networking/ip-sysctl.txt13
-rw-r--r--Documentation/networking/msg_zerocopy.rst5
-rw-r--r--Documentation/networking/net_dim.txt174
-rw-r--r--Documentation/networking/packet_mmap.txt22
-rw-r--r--Documentation/sysctl/net.txt12
-rw-r--r--MAINTAINERS16
-rw-r--r--arch/arm/boot/dts/armada-370-rd.dts32
-rw-r--r--arch/m68k/mac/config.c4
-rw-r--r--arch/x86/net/bpf_jit_comp.c234
-rw-r--r--drivers/atm/idt77252.c12
-rw-r--r--drivers/bluetooth/ath3k.c28
-rw-r--r--drivers/bluetooth/btmrvl_main.c2
-rw-r--r--drivers/bluetooth/btrtl.c119
-rw-r--r--drivers/bluetooth/btusb.c10
-rw-r--r--drivers/bluetooth/hci_ath.c4
-rw-r--r--drivers/bluetooth/hci_ll.c2
-rw-r--r--drivers/infiniband/core/cma.c3
-rw-r--r--drivers/infiniband/hw/cxgb4/device.c1
-rw-r--r--drivers/infiniband/hw/mlx5/Makefile1
-rw-r--r--drivers/infiniband/hw/mlx5/cq.c64
-rw-r--r--drivers/infiniband/hw/mlx5/ib_rep.c192
-rw-r--r--drivers/infiniband/hw/mlx5/ib_rep.h72
-rw-r--r--drivers/infiniband/hw/mlx5/main.c394
-rw-r--r--drivers/infiniband/hw/mlx5/mlx5_ib.h38
-rw-r--r--drivers/infiniband/hw/mlx5/mr.c5
-rw-r--r--drivers/infiniband/hw/mlx5/qp.c27
-rw-r--r--drivers/infiniband/hw/usnic/usnic_transport.c5
-rw-r--r--drivers/isdn/mISDN/socket.c5
-rw-r--r--drivers/net/Kconfig4
-rw-r--r--drivers/net/Space.c6
-rw-r--r--drivers/net/bonding/bond_main.c1
-rw-r--r--drivers/net/dsa/b53/b53_common.c2
-rw-r--r--drivers/net/dsa/b53/b53_priv.h2
-rw-r--r--drivers/net/dsa/dsa_loop.c2
-rw-r--r--drivers/net/dsa/lan9303-core.c2
-rw-r--r--drivers/net/dsa/microchip/ksz_common.c2
-rw-r--r--drivers/net/dsa/mt7530.c2
-rw-r--r--drivers/net/dsa/mv88e6xxx/Kconfig10
-rw-r--r--drivers/net/dsa/mv88e6xxx/Makefile4
-rw-r--r--drivers/net/dsa/mv88e6xxx/chip.c399
-rw-r--r--drivers/net/dsa/mv88e6xxx/chip.h130
-rw-r--r--drivers/net/dsa/mv88e6xxx/global2.c43
-rw-r--r--drivers/net/dsa/mv88e6xxx/global2.h115
-rw-r--r--drivers/net/dsa/mv88e6xxx/global2_avb.c193
-rw-r--r--drivers/net/dsa/mv88e6xxx/global2_scratch.c291
-rw-r--r--drivers/net/dsa/mv88e6xxx/hwtstamp.c576
-rw-r--r--drivers/net/dsa/mv88e6xxx/hwtstamp.h172
-rw-r--r--drivers/net/dsa/mv88e6xxx/ptp.c381
-rw-r--r--drivers/net/dsa/mv88e6xxx/ptp.h108
-rw-r--r--drivers/net/dsa/mv88e6xxx/serdes.c106
-rw-r--r--drivers/net/dsa/mv88e6xxx/serdes.h6
-rw-r--r--drivers/net/dsa/qca8k.c2
-rw-r--r--drivers/net/ethernet/8390/Makefile6
-rw-r--r--drivers/net/ethernet/8390/ax88796.c3
-rw-r--r--drivers/net/ethernet/8390/axnet_cs.c2
-rw-r--r--drivers/net/ethernet/8390/etherh.c17
-rw-r--r--drivers/net/ethernet/8390/hydra.c4
-rw-r--r--drivers/net/ethernet/8390/lib8390.c2
-rw-r--r--drivers/net/ethernet/8390/mac8390.c171
-rw-r--r--drivers/net/ethernet/8390/mcf8390.c4
-rw-r--r--drivers/net/ethernet/8390/ne.c2
-rw-r--r--drivers/net/ethernet/8390/pcnet_cs.c4
-rw-r--r--drivers/net/ethernet/8390/wd.c2
-rw-r--r--drivers/net/ethernet/8390/zorro8390.c5
-rw-r--r--drivers/net/ethernet/amd/amd8111e.c2
-rw-r--r--drivers/net/ethernet/apple/macmace.c25
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/hw_atl/Makefile2
-rw-r--r--drivers/net/ethernet/cadence/macb_main.c84
-rw-r--r--drivers/net/ethernet/cavium/liquidio/lio_core.c104
-rw-r--r--drivers/net/ethernet/cavium/liquidio/lio_ethtool.c24
-rw-r--r--drivers/net/ethernet/cavium/liquidio/lio_main.c182
-rw-r--r--drivers/net/ethernet/cavium/liquidio/lio_vf_main.c67
-rw-r--r--drivers/net/ethernet/cavium/liquidio/liquidio_common.h22
-rw-r--r--drivers/net/ethernet/cavium/liquidio/octeon_device.h2
-rw-r--r--drivers/net/ethernet/cavium/liquidio/octeon_droq.c83
-rw-r--r--drivers/net/ethernet/cavium/liquidio/octeon_droq.h11
-rw-r--r--drivers/net/ethernet/cavium/liquidio/octeon_mailbox.c5
-rw-r--r--drivers/net/ethernet/cavium/liquidio/octeon_network.h20
-rw-r--r--drivers/net/ethernet/cavium/liquidio/request_manager.c5
-rw-r--r--drivers/net/ethernet/cavium/liquidio/response_manager.c6
-rw-r--r--drivers/net/ethernet/chelsio/cxgb3/t3_hw.c8
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/Makefile2
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c86
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4.h23
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c10
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c24
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c6
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c279
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c3
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h6
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/sched.h4
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/srq.c138
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/srq.h65
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4_hw.c194
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4_msg.h71
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h61
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c51
-rw-r--r--drivers/net/ethernet/cirrus/mac89x0.c158
-rw-r--r--drivers/net/ethernet/cisco/enic/enic.h3
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_ethtool.c36
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_main.c86
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_dev.c22
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_dev.h3
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_devcmd.h5
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_nic.h1
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.c2
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.h2
-rw-r--r--drivers/net/ethernet/freescale/dpaa/dpaa_eth.c65
-rw-r--r--drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c2
-rw-r--r--drivers/net/ethernet/freescale/fman/fman_dtsec.c19
-rw-r--r--drivers/net/ethernet/freescale/fman/fman_dtsec.h1
-rw-r--r--drivers/net/ethernet/freescale/fman/fman_memac.c32
-rw-r--r--drivers/net/ethernet/freescale/fman/fman_memac.h1
-rw-r--r--drivers/net/ethernet/freescale/fman/fman_tgec.c33
-rw-r--r--drivers/net/ethernet/freescale/fman/fman_tgec.h1
-rw-r--r--drivers/net/ethernet/freescale/fman/mac.c3
-rw-r--r--drivers/net/ethernet/freescale/fman/mac.h2
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h18
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hnae3.h18
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3_enet.c392
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3_enet.h18
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c149
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h4
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c16
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c540
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h27
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c94
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c76
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h8
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c6
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h2
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c475
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h35
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c95
-rw-r--r--drivers/net/ethernet/ibm/ibmvnic.c600
-rw-r--r--drivers/net/ethernet/ibm/ibmvnic.h16
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_common.c5
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_main.c4
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_netdev.c10
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_pci.c13
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_pf.c4
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_tlv.c7
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e.h11
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h37
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_client.c16
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_common.c63
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_debugfs.c52
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_ethtool.c111
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_fcoe.c1571
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_fcoe.h127
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_main.c375
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_prototype.h4
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_txrx.c437
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_txrx.h70
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_type.h5
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c1090
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h20
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_txrx.c427
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_txrx.h67
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40evf.h78
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c52
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40evf_main.c933
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c338
-rw-r--r--drivers/net/ethernet/intel/igb/igb.h1
-rw-r--r--drivers/net/ethernet/intel/igb/igb_main.c35
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c5
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c53
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h1
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c1
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_main.c3
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c6
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/ethtool.c48
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/ixgbevf.h72
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c825
-rw-r--r--drivers/net/ethernet/marvell/mvpp2.c927
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_ethtool.c14
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_netdev.c8
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_port.c38
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_rx.c31
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4_en.h1
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4_stats.h10
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.c59
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.h98
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/alloc.c37
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/cq.c113
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/dev.c8
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/diag/fs_tracepoint.c3
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/diag/fs_tracepoint.h4
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c323
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h24
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c39
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.h5
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_rep.c11
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_rx.c11
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_tc.c1
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/eq.c92
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/eswitch.c23
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/eswitch.h42
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c104
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c1289
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.h76
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c207
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.h72
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/fs_core.c141
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/fs_core.h8
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/main.c49
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h28
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/wq.c18
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/wq.h22
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/Kconfig2
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/Makefile2
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c19
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.h9
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/pci.c9
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/reg.h156
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum.c542
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum.h45
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c52
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_actions.c34
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c5
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.c174
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.h15
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_kvdl.c189
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c21
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_qdisc.c206
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c46
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c804
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h107
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c16
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/switchx2.c8
-rw-r--r--drivers/net/ethernet/microchip/Kconfig10
-rw-r--r--drivers/net/ethernet/microchip/Makefile3
-rw-r--r--drivers/net/ethernet/microchip/lan743x_main.c2771
-rw-r--r--drivers/net/ethernet/microchip/lan743x_main.h597
-rw-r--r--drivers/net/ethernet/natsemi/jazzsonic.c32
-rw-r--r--drivers/net/ethernet/natsemi/macsonic.c244
-rw-r--r--drivers/net/ethernet/natsemi/sonic.c99
-rw-r--r--drivers/net/ethernet/natsemi/sonic.h2
-rw-r--r--drivers/net/ethernet/natsemi/xtsonic.c30
-rw-r--r--drivers/net/ethernet/netronome/nfp/bpf/Makefile2
-rw-r--r--drivers/net/ethernet/netronome/nfp/flower/Makefile2
-rw-r--r--drivers/net/ethernet/netronome/nfp/flower/cmsg.h11
-rw-r--r--drivers/net/ethernet/netronome/nfp/flower/main.h1
-rw-r--r--drivers/net/ethernet/netronome/nfp/flower/match.c20
-rw-r--r--drivers/net/ethernet/netronome/nfp/flower/offload.c34
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_main.c1
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h280
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfpcore/Makefile2
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000/Makefile2
-rw-r--r--drivers/net/ethernet/netronome/nfp/nic/Makefile2
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_iwarp.c2
-rw-r--r--drivers/net/ethernet/qualcomm/qca_spi.c1
-rw-r--r--drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c73
-rw-r--r--drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h2
-rw-r--r--drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c12
-rw-r--r--drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h8
-rw-r--r--drivers/net/ethernet/qualcomm/rmnet/rmnet_map_command.c4
-rw-r--r--drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c5
-rw-r--r--drivers/net/ethernet/qualcomm/rmnet/rmnet_private.h8
-rw-r--r--drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c2
-rw-r--r--drivers/net/ethernet/realtek/r8169.c1154
-rw-r--r--drivers/net/ethernet/renesas/ravb.h1
-rw-r--r--drivers/net/ethernet/renesas/ravb_main.c33
-rw-r--r--drivers/net/ethernet/renesas/sh_eth.c37
-rw-r--r--drivers/net/ethernet/renesas/sh_eth.h5
-rw-r--r--drivers/net/ethernet/sfc/ef10.c273
-rw-r--r--drivers/net/ethernet/sfc/efx.c65
-rw-r--r--drivers/net/ethernet/sfc/efx.h12
-rw-r--r--drivers/net/ethernet/sfc/ethtool.c185
-rw-r--r--drivers/net/ethernet/sfc/falcon/enum.h1
-rw-r--r--drivers/net/ethernet/sfc/farch.c11
-rw-r--r--drivers/net/ethernet/sfc/filter.h7
-rw-r--r--drivers/net/ethernet/sfc/mcdi_pcol.h2822
-rw-r--r--drivers/net/ethernet/sfc/mcdi_port.c150
-rw-r--r--drivers/net/ethernet/sfc/net_driver.h52
-rw-r--r--drivers/net/ethernet/sfc/nic.h2
-rw-r--r--drivers/net/ethernet/sfc/siena.c26
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c208
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c6
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c2
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac.h2
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c41
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c34
-rw-r--r--drivers/net/ethernet/ti/cpsw.c67
-rw-r--r--drivers/net/ethernet/ti/davinci_cpdma.c2
-rw-r--r--drivers/net/ethernet/ti/davinci_cpdma.h2
-rw-r--r--drivers/net/geneve.c1
-rw-r--r--drivers/net/gtp.c1
-rw-r--r--drivers/net/hyperv/Makefile2
-rw-r--r--drivers/net/hyperv/netvsc.c26
-rw-r--r--drivers/net/hyperv/netvsc_trace.c7
-rw-r--r--drivers/net/hyperv/netvsc_trace.h182
-rw-r--r--drivers/net/hyperv/rndis_filter.c12
-rw-r--r--drivers/net/ieee802154/Kconfig11
-rw-r--r--drivers/net/ieee802154/Makefile1
-rw-r--r--drivers/net/ieee802154/mcr20a.c1413
-rw-r--r--drivers/net/ieee802154/mcr20a.h498
-rw-r--r--drivers/net/ipvlan/ipvlan.h7
-rw-r--r--drivers/net/ipvlan/ipvlan_core.c103
-rw-r--r--drivers/net/ipvlan/ipvlan_main.c119
-rw-r--r--drivers/net/loopback.c1
-rw-r--r--drivers/net/phy/aquantia.c20
-rw-r--r--drivers/net/phy/bcm7xxx.c2
-rw-r--r--drivers/net/phy/cortina.c18
-rw-r--r--drivers/net/phy/dp83867.c19
-rw-r--r--drivers/net/phy/marvell.c2
-rw-r--r--drivers/net/phy/marvell10g.c13
-rw-r--r--drivers/net/phy/mdio-mux-mmioreg.c5
-rw-r--r--drivers/net/phy/phy-c45.c28
-rw-r--r--drivers/net/phy/phy-core.c4
-rw-r--r--drivers/net/phy/phy.c22
-rw-r--r--drivers/net/phy/phy_device.c2
-rw-r--r--drivers/net/phy/phylink.c45
-rw-r--r--drivers/net/phy/sfp-bus.c162
-rw-r--r--drivers/net/phy/sfp.c150
-rw-r--r--drivers/net/phy/teranetics.c32
-rw-r--r--drivers/net/ppp/ppp_generic.c1
-rw-r--r--drivers/net/ppp/pppoe.c7
-rw-r--r--drivers/net/ppp/pptp.c6
-rw-r--r--drivers/net/team/team.c16
-rw-r--r--drivers/net/tun.c91
-rw-r--r--drivers/net/usb/ax88179_178a.c118
-rw-r--r--drivers/net/usb/cdc_eem.c5
-rw-r--r--drivers/net/usb/kalmia.c14
-rw-r--r--drivers/net/usb/lg-vl600.c6
-rw-r--r--drivers/net/vrf.c13
-rw-r--r--drivers/net/vxlan.c1
-rw-r--r--drivers/net/wimax/i2400m/usb-rx.c3
-rw-r--r--drivers/net/wireless/ath/wil6210/cfg80211.c3
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c96
-rw-r--r--drivers/net/wireless/mac80211_hwsim.h9
-rw-r--r--drivers/net/wireless/ti/wl1251/tx.c4
-rw-r--r--drivers/net/xen-netback/rx.c2
-rw-r--r--drivers/s390/net/qeth_core.h8
-rw-r--r--drivers/s390/net/qeth_core_main.c40
-rw-r--r--drivers/s390/net/qeth_l2_main.c34
-rw-r--r--drivers/s390/net/qeth_l3.h34
-rw-r--r--drivers/s390/net/qeth_l3_main.c419
-rw-r--r--drivers/s390/net/qeth_l3_sys.c51
-rw-r--r--drivers/scsi/iscsi_tcp.c14
-rw-r--r--drivers/soc/qcom/qmi_interface.c3
-rw-r--r--drivers/staging/ipx/af_ipx.c6
-rw-r--r--drivers/staging/irda/net/af_irda.c8
-rw-r--r--drivers/staging/lustre/lnet/lnet/lib-socket.c7
-rw-r--r--drivers/target/iscsi/iscsi_target_login.c18
-rw-r--r--drivers/usb/gadget/function/f_eem.c1
-rw-r--r--drivers/vhost/net.c7
-rw-r--r--drivers/vhost/vsock.c4
-rw-r--r--fs/dlm/lowcomms.c7
-rw-r--r--fs/lockd/svc.c1
-rw-r--r--fs/nfs/inode.c1
-rw-r--r--fs/nfs_common/grace.c1
-rw-r--r--fs/nsfs.c1
-rw-r--r--fs/ocfs2/cluster/tcp.c6
-rw-r--r--fs/proc/proc_net.c1
-rw-r--r--include/dt-bindings/net/ti-dp83867.h14
-rw-r--r--include/linux/atalk.h2
-rw-r--r--include/linux/avf/virtchnl.h107
-rw-r--r--include/linux/bpf-cgroup.h2
-rw-r--r--include/linux/bpf.h1
-rw-r--r--include/linux/bpf_types.h1
-rw-r--r--include/linux/ethtool.h5
-rw-r--r--include/linux/filter.h19
-rw-r--r--include/linux/ieee80211.h14
-rw-r--r--include/linux/mlx5/accel.h144
-rw-r--r--include/linux/mlx5/cq.h14
-rw-r--r--include/linux/mlx5/driver.h94
-rw-r--r--include/linux/mlx5/eswitch.h58
-rw-r--r--include/linux/mlx5/fs.h5
-rw-r--r--include/linux/mlx5/fs_helpers.h134
-rw-r--r--include/linux/mlx5/mlx5_ifc.h9
-rw-r--r--include/linux/mlx5/mlx5_ifc_fpga.h92
-rw-r--r--include/linux/mroute.h88
-rw-r--r--include/linux/mroute6.h62
-rw-r--r--include/linux/mroute_base.h346
-rw-r--r--include/linux/net.h8
-rw-r--r--include/linux/netdevice.h50
-rw-r--r--include/linux/phy.h8
-rw-r--r--include/linux/ptp_classify.h4
-rw-r--r--include/linux/ptr_ring.h7
-rw-r--r--include/linux/rtnetlink.h3
-rw-r--r--include/linux/sfp.h18
-rw-r--r--include/linux/skbuff.h3
-rw-r--r--include/linux/socket.h3
-rw-r--r--include/net/Space.h2
-rw-r--r--include/net/act_api.h19
-rw-r--r--include/net/addrconf.h4
-rw-r--r--include/net/ax25.h2
-rw-r--r--include/net/cfg80211.h110
-rw-r--r--include/net/devlink.h5
-rw-r--r--include/net/dsa.h22
-rw-r--r--include/net/dst.h1
-rw-r--r--include/net/dst_cache.h4
-rw-r--r--include/net/ethoc.h1
-rw-r--r--include/net/fib_rules.h45
-rw-r--r--include/net/flow.h18
-rw-r--r--include/net/gre.h3
-rw-r--r--include/net/ieee80211_radiotap.h2
-rw-r--r--include/net/inet_common.h2
-rw-r--r--include/net/inet_connection_sock.h10
-rw-r--r--include/net/ip.h25
-rw-r--r--include/net/ip6_fib.h29
-rw-r--r--include/net/ip6_route.h15
-rw-r--r--include/net/ip_fib.h31
-rw-r--r--include/net/ip_tunnels.h18
-rw-r--r--include/net/ipv6.h23
-rw-r--r--include/net/lwtunnel.h15
-rw-r--r--include/net/mac80211.h19
-rw-r--r--include/net/net_namespace.h34
-rw-r--r--include/net/netevent.h3
-rw-r--r--include/net/netns/ipv4.h6
-rw-r--r--include/net/netns/ipv6.h6
-rw-r--r--include/net/pkt_cls.h8
-rw-r--r--include/net/route.h2
-rw-r--r--include/net/sch_generic.h2
-rw-r--r--include/net/sctp/auth.h21
-rw-r--r--include/net/sctp/command.h1
-rw-r--r--include/net/sctp/sctp.h11
-rw-r--r--include/net/sctp/sm.h3
-rw-r--r--include/net/sctp/structs.h12
-rw-r--r--include/net/sock.h16
-rw-r--r--include/net/tcp.h9
-rw-r--r--include/net/tcp_states.h26
-rw-r--r--include/net/xfrm.h14
-rw-r--r--include/uapi/linux/batadv_packet.h15
-rw-r--r--include/uapi/linux/batman_adv.h84
-rw-r--r--include/uapi/linux/bpf.h48
-rw-r--r--include/uapi/linux/bpf_perf_event.h1
-rw-r--r--include/uapi/linux/ethtool.h32
-rw-r--r--include/uapi/linux/fib_rules.h11
-rw-r--r--include/uapi/linux/if_ether.h1
-rw-r--r--include/uapi/linux/if_link.h39
-rw-r--r--include/uapi/linux/ncsi.h115
-rw-r--r--include/uapi/linux/nl80211.h90
-rw-r--r--include/uapi/linux/pkt_cls.h4
-rw-r--r--include/uapi/linux/rds.h8
-rw-r--r--include/uapi/linux/sctp.h43
-rw-r--r--include/uapi/linux/tc_ematch/tc_em_ipt.h20
-rw-r--r--include/uapi/linux/tcp.h3
-rw-r--r--include/uapi/linux/tipc.h102
-rw-r--r--include/uapi/linux/tipc_netlink.h19
-rw-r--r--include/uapi/linux/tipc_sockets_diag.h17
-rw-r--r--kernel/audit.c1
-rw-r--r--kernel/bpf/inode.c3
-rw-r--r--kernel/bpf/sockmap.c733
-rw-r--r--kernel/bpf/stackmap.c257
-rw-r--r--kernel/bpf/syscall.c14
-rw-r--r--kernel/bpf/verifier.c9
-rw-r--r--kernel/trace/bpf_trace.c20
-rw-r--r--lib/kobject_uevent.c97
-rw-r--r--net/8021q/vlan.c1
-rw-r--r--net/appletalk/ddp.c5
-rw-r--r--net/atm/pvc.c5
-rw-r--r--net/atm/svc.c5
-rw-r--r--net/ax25/af_ax25.c4
-rw-r--r--net/batman-adv/Kconfig2
-rw-r--r--net/batman-adv/Makefile2
-rw-r--r--net/batman-adv/bat_algo.c2
-rw-r--r--net/batman-adv/bat_algo.h2
-rw-r--r--net/batman-adv/bat_iv_ogm.c2
-rw-r--r--net/batman-adv/bat_iv_ogm.h2
-rw-r--r--net/batman-adv/bat_v.c2
-rw-r--r--net/batman-adv/bat_v.h2
-rw-r--r--net/batman-adv/bat_v_elp.c2
-rw-r--r--net/batman-adv/bat_v_elp.h2
-rw-r--r--net/batman-adv/bat_v_ogm.c2
-rw-r--r--net/batman-adv/bat_v_ogm.h2
-rw-r--r--net/batman-adv/bitarray.c2
-rw-r--r--net/batman-adv/bitarray.h2
-rw-r--r--net/batman-adv/bridge_loop_avoidance.c2
-rw-r--r--net/batman-adv/bridge_loop_avoidance.h2
-rw-r--r--net/batman-adv/debugfs.c2
-rw-r--r--net/batman-adv/debugfs.h2
-rw-r--r--net/batman-adv/distributed-arp-table.c156
-rw-r--r--net/batman-adv/distributed-arp-table.h10
-rw-r--r--net/batman-adv/fragmentation.c2
-rw-r--r--net/batman-adv/fragmentation.h2
-rw-r--r--net/batman-adv/gateway_client.c2
-rw-r--r--net/batman-adv/gateway_client.h2
-rw-r--r--net/batman-adv/gateway_common.c2
-rw-r--r--net/batman-adv/gateway_common.h2
-rw-r--r--net/batman-adv/hard-interface.c2
-rw-r--r--net/batman-adv/hard-interface.h2
-rw-r--r--net/batman-adv/hash.c2
-rw-r--r--net/batman-adv/hash.h2
-rw-r--r--net/batman-adv/icmp_socket.c2
-rw-r--r--net/batman-adv/icmp_socket.h2
-rw-r--r--net/batman-adv/log.c2
-rw-r--r--net/batman-adv/log.h2
-rw-r--r--net/batman-adv/main.c2
-rw-r--r--net/batman-adv/main.h16
-rw-r--r--net/batman-adv/multicast.c295
-rw-r--r--net/batman-adv/multicast.h20
-rw-r--r--net/batman-adv/netlink.c90
-rw-r--r--net/batman-adv/netlink.h2
-rw-r--r--net/batman-adv/network-coding.c2
-rw-r--r--net/batman-adv/network-coding.h2
-rw-r--r--net/batman-adv/originator.c2
-rw-r--r--net/batman-adv/originator.h2
-rw-r--r--net/batman-adv/routing.c2
-rw-r--r--net/batman-adv/routing.h2
-rw-r--r--net/batman-adv/send.c2
-rw-r--r--net/batman-adv/send.h2
-rw-r--r--net/batman-adv/soft-interface.c2
-rw-r--r--net/batman-adv/soft-interface.h2
-rw-r--r--net/batman-adv/sysfs.c2
-rw-r--r--net/batman-adv/sysfs.h2
-rw-r--r--net/batman-adv/tp_meter.c2
-rw-r--r--net/batman-adv/tp_meter.h2
-rw-r--r--net/batman-adv/translation-table.c2
-rw-r--r--net/batman-adv/translation-table.h2
-rw-r--r--net/batman-adv/tvlv.c2
-rw-r--r--net/batman-adv/tvlv.h2
-rw-r--r--net/batman-adv/types.h2
-rw-r--r--net/bluetooth/hci_request.c6
-rw-r--r--net/bluetooth/hci_sock.c4
-rw-r--r--net/bluetooth/l2cap_sock.c5
-rw-r--r--net/bluetooth/rfcomm/sock.c5
-rw-r--r--net/bluetooth/sco.c5
-rw-r--r--net/bridge/br.c1
-rw-r--r--net/bridge/br_netfilter_hooks.c1
-rw-r--r--net/bridge/netfilter/ebtable_broute.c1
-rw-r--r--net/bridge/netfilter/ebtable_filter.c1
-rw-r--r--net/bridge/netfilter/ebtable_nat.c1
-rw-r--r--net/bridge/netfilter/nf_log_bridge.c1
-rw-r--r--net/caif/caif_dev.c1
-rw-r--r--net/can/af_can.c1
-rw-r--r--net/can/bcm.c1
-rw-r--r--net/can/gw.c1
-rw-r--r--net/can/raw.c6
-rw-r--r--net/core/dev.c26
-rw-r--r--net/core/devlink.c44
-rw-r--r--net/core/dst_cache.c4
-rw-r--r--net/core/ethtool.c64
-rw-r--r--net/core/fib_notifier.c1
-rw-r--r--net/core/fib_rules.c105
-rw-r--r--net/core/filter.c277
-rw-r--r--net/core/flow_dissector.c16
-rw-r--r--net/core/net-procfs.c2
-rw-r--r--net/core/net_namespace.c139
-rw-r--r--net/core/pktgen.c16
-rw-r--r--net/core/rtnetlink.c11
-rw-r--r--net/core/skbuff.c10
-rw-r--r--net/core/sock.c90
-rw-r--r--net/core/sock_diag.c1
-rw-r--r--net/core/sysctl_net_core.c13
-rw-r--r--net/dccp/ipv4.c1
-rw-r--r--net/dccp/ipv6.c1
-rw-r--r--net/decnet/af_decnet.c6
-rw-r--r--net/dsa/dsa.c36
-rw-r--r--net/dsa/master.c4
-rw-r--r--net/dsa/slave.c61
-rw-r--r--net/ieee802154/6lowpan/core.c1
-rw-r--r--net/ieee802154/6lowpan/reassembly.c1
-rw-r--r--net/ieee802154/core.c1
-rw-r--r--net/ipv4/Kconfig5
-rw-r--r--net/ipv4/Makefile1
-rw-r--r--net/ipv4/af_inet.c7
-rw-r--r--net/ipv4/arp.c1
-rw-r--r--net/ipv4/devinet.c1
-rw-r--r--net/ipv4/fib_frontend.c1
-rw-r--r--net/ipv4/fib_rules.c19
-rw-r--r--net/ipv4/fib_semantics.c16
-rw-r--r--net/ipv4/fib_trie.c5
-rw-r--r--net/ipv4/fou.c1
-rw-r--r--net/ipv4/icmp.c1
-rw-r--r--net/ipv4/igmp.c1
-rw-r--r--net/ipv4/inetpeer.c3
-rw-r--r--net/ipv4/ip_fragment.c1
-rw-r--r--net/ipv4/ip_gre.c16
-rw-r--r--net/ipv4/ip_input.c5
-rw-r--r--net/ipv4/ip_sockglue.c34
-rw-r--r--net/ipv4/ip_tunnel.c54
-rw-r--r--net/ipv4/ip_vti.c1
-rw-r--r--net/ipv4/ipip.c1
-rw-r--r--net/ipv4/ipmr.c597
-rw-r--r--net/ipv4/ipmr_base.c323
-rw-r--r--net/ipv4/netfilter/arp_tables.c1
-rw-r--r--net/ipv4/netfilter/arptable_filter.c1
-rw-r--r--net/ipv4/netfilter/ip_tables.c1
-rw-r--r--net/ipv4/netfilter/ipt_CLUSTERIP.c1
-rw-r--r--net/ipv4/netfilter/iptable_filter.c1
-rw-r--r--net/ipv4/netfilter/iptable_mangle.c1
-rw-r--r--net/ipv4/netfilter/iptable_nat.c1
-rw-r--r--net/ipv4/netfilter/iptable_raw.c1
-rw-r--r--net/ipv4/netfilter/iptable_security.c1
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c1
-rw-r--r--net/ipv4/netfilter/nf_defrag_ipv4.c1
-rw-r--r--net/ipv4/netfilter/nf_log_arp.c1
-rw-r--r--net/ipv4/netfilter/nf_log_ipv4.c1
-rw-r--r--net/ipv4/ping.c1
-rw-r--r--net/ipv4/proc.c2
-rw-r--r--net/ipv4/raw.c3
-rw-r--r--net/ipv4/route.c91
-rw-r--r--net/ipv4/sysctl_net_ipv4.c35
-rw-r--r--net/ipv4/tcp.c69
-rw-r--r--net/ipv4/tcp_bbr.c38
-rw-r--r--net/ipv4/tcp_input.c7
-rw-r--r--net/ipv4/tcp_ipv4.c28
-rw-r--r--net/ipv4/tcp_metrics.c1
-rw-r--r--net/ipv4/tcp_minisocks.c3
-rw-r--r--net/ipv4/tcp_output.c55
-rw-r--r--net/ipv4/tunnel4.c2
-rw-r--r--net/ipv4/udp.c87
-rw-r--r--net/ipv4/udplite.c1
-rw-r--r--net/ipv4/xfrm4_policy.c3
-rw-r--r--net/ipv6/Kconfig1
-rw-r--r--net/ipv6/addrconf.c63
-rw-r--r--net/ipv6/addrlabel.c1
-rw-r--r--net/ipv6/af_inet6.c6
-rw-r--r--net/ipv6/anycast.c12
-rw-r--r--net/ipv6/datagram.c5
-rw-r--r--net/ipv6/exthdrs_core.c1
-rw-r--r--net/ipv6/fib6_rules.c36
-rw-r--r--net/ipv6/icmp.c6
-rw-r--r--net/ipv6/ila/ila_xlat.c1
-rw-r--r--net/ipv6/ip6_fib.c4
-rw-r--r--net/ipv6/ip6_flowlabel.c1
-rw-r--r--net/ipv6/ip6_gre.c26
-rw-r--r--net/ipv6/ip6_output.c2
-rw-r--r--net/ipv6/ip6_tunnel.c19
-rw-r--r--net/ipv6/ip6_vti.c3
-rw-r--r--net/ipv6/ip6mr.c993
-rw-r--r--net/ipv6/ipv6_sockglue.c1
-rw-r--r--net/ipv6/mcast.c5
-rw-r--r--net/ipv6/ndisc.c5
-rw-r--r--net/ipv6/netfilter/ip6_tables.c1
-rw-r--r--net/ipv6/netfilter/ip6t_rpfilter.c2
-rw-r--r--net/ipv6/netfilter/ip6table_filter.c1
-rw-r--r--net/ipv6/netfilter/ip6table_mangle.c1
-rw-r--r--net/ipv6/netfilter/ip6table_nat.c1
-rw-r--r--net/ipv6/netfilter/ip6table_raw.c1
-rw-r--r--net/ipv6/netfilter/ip6table_security.c1
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c1
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c1
-rw-r--r--net/ipv6/netfilter/nf_defrag_ipv6_hooks.c1
-rw-r--r--net/ipv6/netfilter/nf_log_ipv6.c1
-rw-r--r--net/ipv6/netfilter/nft_fib_ipv6.c3
-rw-r--r--net/ipv6/ping.c1
-rw-r--r--net/ipv6/proc.c2
-rw-r--r--net/ipv6/raw.c1
-rw-r--r--net/ipv6/reassembly.c1
-rw-r--r--net/ipv6/route.c301
-rw-r--r--net/ipv6/seg6.c1
-rw-r--r--net/ipv6/seg6_local.c4
-rw-r--r--net/ipv6/sit.c6
-rw-r--r--net/ipv6/sysctl_net_ipv6.c28
-rw-r--r--net/ipv6/tcp_ipv6.c14
-rw-r--r--net/ipv6/udp.c52
-rw-r--r--net/ipv6/udplite.c1
-rw-r--r--net/ipv6/xfrm6_policy.c1
-rw-r--r--net/ipv6/xfrm6_state.c1
-rw-r--r--net/ipv6/xfrm6_tunnel.c1
-rw-r--r--net/iucv/af_iucv.c5
-rw-r--r--net/kcm/kcmproc.c1
-rw-r--r--net/kcm/kcmsock.c2
-rw-r--r--net/key/af_key.c1
-rw-r--r--net/l2tp/l2tp_core.c1
-rw-r--r--net/l2tp/l2tp_ip.c5
-rw-r--r--net/l2tp/l2tp_ip6.c5
-rw-r--r--net/l2tp/l2tp_ppp.c6
-rw-r--r--net/llc/af_llc.c5
-rw-r--r--net/llc/llc_sap.c7
-rw-r--r--net/mac80211/agg-rx.c14
-rw-r--r--net/mac80211/cfg.c1
-rw-r--r--net/mac80211/debugfs.c1
-rw-r--r--net/mac80211/debugfs_sta.c10
-rw-r--r--net/mac80211/iface.c3
-rw-r--r--net/mac80211/michael.c2
-rw-r--r--net/mac80211/mlme.c18
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c2
-rw-r--r--net/mac80211/rx.c188
-rw-r--r--net/mac80211/sta_info.c6
-rw-r--r--net/mac80211/sta_info.h2
-rw-r--r--net/mac80211/status.c11
-rw-r--r--net/mac80211/tx.c11
-rw-r--r--net/mac80211/vht.c9
-rw-r--r--net/mac80211/wpa.c8
-rw-r--r--net/mpls/af_mpls.c1
-rw-r--r--net/ncsi/Makefile2
-rw-r--r--net/ncsi/internal.h3
-rw-r--r--net/ncsi/ncsi-manage.c30
-rw-r--r--net/ncsi/ncsi-netlink.c423
-rw-r--r--net/ncsi/ncsi-netlink.h20
-rw-r--r--net/netfilter/core.c1
-rw-r--r--net/netfilter/ipset/ip_set_core.c3
-rw-r--r--net/netfilter/ipvs/ip_vs_core.c2
-rw-r--r--net/netfilter/ipvs/ip_vs_ftp.c1
-rw-r--r--net/netfilter/ipvs/ip_vs_lblc.c1
-rw-r--r--net/netfilter/ipvs/ip_vs_lblcr.c1
-rw-r--r--net/netfilter/nf_conntrack_netlink.c1
-rw-r--r--net/netfilter/nf_conntrack_proto_gre.c1
-rw-r--r--net/netfilter/nf_conntrack_standalone.c1
-rw-r--r--net/netfilter/nf_log.c1
-rw-r--r--net/netfilter/nf_log_netdev.c1
-rw-r--r--net/netfilter/nf_synproxy_core.c1
-rw-r--r--net/netfilter/nf_tables_api.c1
-rw-r--r--net/netfilter/nfnetlink.c1
-rw-r--r--net/netfilter/nfnetlink_acct.c1
-rw-r--r--net/netfilter/nfnetlink_cttimeout.c1
-rw-r--r--net/netfilter/nfnetlink_log.c1
-rw-r--r--net/netfilter/nfnetlink_queue.c6
-rw-r--r--net/netfilter/x_tables.c1
-rw-r--r--net/netfilter/xt_hashlimit.c1
-rw-r--r--net/netfilter/xt_recent.c1
-rw-r--r--net/netlink/af_netlink.c7
-rw-r--r--net/netlink/genetlink.c1
-rw-r--r--net/netrom/af_netrom.c9
-rw-r--r--net/nfc/llcp_sock.c5
-rw-r--r--net/openvswitch/datapath.c1
-rw-r--r--net/openvswitch/vport.c8
-rw-r--r--net/packet/af_packet.c11
-rw-r--r--net/phonet/pn_dev.c1
-rw-r--r--net/phonet/socket.c5
-rw-r--r--net/qrtr/qrtr.c5
-rw-r--r--net/rds/af_rds.c14
-rw-r--r--net/rds/connection.c7
-rw-r--r--net/rds/ib.c3
-rw-r--r--net/rds/message.c163
-rw-r--r--net/rds/rds.h31
-rw-r--r--net/rds/recv.c42
-rw-r--r--net/rds/send.c54
-rw-r--r--net/rds/tcp.c116
-rw-r--r--net/rose/af_rose.c5
-rw-r--r--net/rxrpc/recvmsg.c2
-rw-r--r--net/sched/Kconfig12
-rw-r--r--net/sched/Makefile1
-rw-r--r--net/sched/act_api.c192
-rw-r--r--net/sched/act_bpf.c11
-rw-r--r--net/sched/act_connmark.c12
-rw-r--r--net/sched/act_csum.c11
-rw-r--r--net/sched/act_gact.c25
-rw-r--r--net/sched/act_ife.c11
-rw-r--r--net/sched/act_ipt.c22
-rw-r--r--net/sched/act_mirred.c26
-rw-r--r--net/sched/act_nat.c12
-rw-r--r--net/sched/act_pedit.c11
-rw-r--r--net/sched/act_police.c12
-rw-r--r--net/sched/act_sample.c11
-rw-r--r--net/sched/act_simple.c11
-rw-r--r--net/sched/act_skbedit.c11
-rw-r--r--net/sched/act_skbmod.c11
-rw-r--r--net/sched/act_tunnel_key.c11
-rw-r--r--net/sched/act_vlan.c11
-rw-r--r--net/sched/cls_api.c6
-rw-r--r--net/sched/cls_flower.c6
-rw-r--r--net/sched/em_ipt.c257
-rw-r--r--net/sched/sch_api.c8
-rw-r--r--net/sched/sch_prio.c45
-rw-r--r--net/sctp/Makefile2
-rw-r--r--net/sctp/auth.c146
-rw-r--r--net/sctp/chunk.c14
-rw-r--r--net/sctp/diag.c (renamed from net/sctp/sctp_diag.c)31
-rw-r--r--net/sctp/ipv6.c8
-rw-r--r--net/sctp/objcnt.c8
-rw-r--r--net/sctp/output.c18
-rw-r--r--net/sctp/proc.c90
-rw-r--r--net/sctp/protocol.c61
-rw-r--r--net/sctp/sm_make_chunk.c33
-rw-r--r--net/sctp/sm_sideeffect.c13
-rw-r--r--net/sctp/sm_statefuns.c56
-rw-r--r--net/sctp/socket.c828
-rw-r--r--net/smc/af_smc.c211
-rw-r--r--net/smc/smc.h9
-rw-r--r--net/smc/smc_clc.c214
-rw-r--r--net/smc/smc_clc.h22
-rw-r--r--net/smc/smc_core.c100
-rw-r--r--net/smc/smc_core.h16
-rw-r--r--net/smc/smc_ib.c10
-rw-r--r--net/smc/smc_llc.c408
-rw-r--r--net/smc/smc_llc.h41
-rw-r--r--net/smc/smc_wr.h1
-rw-r--r--net/socket.c51
-rw-r--r--net/sunrpc/clnt.c6
-rw-r--r--net/sunrpc/svcsock.c13
-rw-r--r--net/sunrpc/xprtsock.c3
-rw-r--r--net/sysctl_net.c1
-rw-r--r--net/tipc/Kconfig8
-rw-r--r--net/tipc/Makefile7
-rw-r--r--net/tipc/addr.c31
-rw-r--r--net/tipc/addr.h10
-rw-r--r--net/tipc/bcast.c2
-rw-r--r--net/tipc/bearer.c8
-rw-r--r--net/tipc/core.c1
-rw-r--r--net/tipc/core.h11
-rw-r--r--net/tipc/diag.c114
-rw-r--r--net/tipc/group.c2
-rw-r--r--net/tipc/link.c3
-rw-r--r--net/tipc/msg.c2
-rw-r--r--net/tipc/name_distr.c63
-rw-r--r--net/tipc/name_distr.h2
-rw-r--r--net/tipc/name_table.c271
-rw-r--r--net/tipc/name_table.h56
-rw-r--r--net/tipc/net.c2
-rw-r--r--net/tipc/node.c24
-rw-r--r--net/tipc/node.h1
-rw-r--r--net/tipc/server.c710
-rw-r--r--net/tipc/socket.c168
-rw-r--r--net/tipc/socket.h10
-rw-r--r--net/tipc/subscr.c361
-rw-r--r--net/tipc/subscr.h66
-rw-r--r--net/tipc/topsrv.c703
-rw-r--r--net/tipc/topsrv.h (renamed from net/tipc/server.h)57
-rw-r--r--net/tls/tls_sw.c69
-rw-r--r--net/unix/af_unix.c11
-rw-r--r--net/vmw_vsock/af_vsock.c4
-rw-r--r--net/wireless/core.c1
-rw-r--r--net/wireless/nl80211.c203
-rw-r--r--net/wireless/rdev-ops.h15
-rw-r--r--net/wireless/trace.h23
-rw-r--r--net/wireless/util.c5
-rw-r--r--net/wireless/wext-core.c1
-rw-r--r--net/x25/af_x25.c4
-rw-r--r--net/x25/x25_subr.c3
-rw-r--r--net/xfrm/xfrm_policy.c1
-rw-r--r--net/xfrm/xfrm_user.c1
-rw-r--r--samples/bpf/Makefile4
-rw-r--r--samples/bpf/bpf_load.c8
-rw-r--r--samples/bpf/cpustat_kern.c281
-rw-r--r--samples/bpf/cpustat_user.c219
-rw-r--r--samples/bpf/tcbpf2_kern.c6
-rwxr-xr-xsamples/bpf/test_cgrp2_sock.sh1
-rwxr-xr-xsamples/bpf/test_cgrp2_sock2.sh3
-rwxr-xr-xsamples/bpf/test_tunnel_bpf.sh5
-rw-r--r--samples/bpf/trace_event_kern.c4
-rw-r--r--samples/bpf/trace_event_user.c15
-rw-r--r--samples/bpf/xdp_redirect_user.c7
-rw-r--r--samples/sockmap/Makefile2
-rw-r--r--samples/sockmap/sockmap_kern.c197
-rwxr-xr-xsamples/sockmap/sockmap_test.sh450
-rw-r--r--samples/sockmap/sockmap_user.c302
-rw-r--r--security/selinux/hooks.c1
-rw-r--r--security/smack/smack_netfilter.c1
-rw-r--r--security/tomoyo/network.c5
-rw-r--r--tools/bpf/Makefile78
-rw-r--r--tools/bpf/bpftool/Documentation/bpftool-prog.rst18
-rw-r--r--tools/bpf/bpftool/Makefile6
-rw-r--r--tools/bpf/bpftool/bash-completion/bpftool13
-rw-r--r--tools/bpf/bpftool/cfg.c514
-rw-r--r--tools/bpf/bpftool/cfg.h43
-rw-r--r--tools/bpf/bpftool/main.c104
-rw-r--r--tools/bpf/bpftool/prog.c305
-rw-r--r--tools/bpf/bpftool/xlated_dumper.c338
-rw-r--r--tools/bpf/bpftool/xlated_dumper.h64
-rw-r--r--tools/include/uapi/linux/bpf.h47
-rw-r--r--tools/lib/bpf/libbpf.c1
-rw-r--r--tools/testing/selftests/bpf/Makefile17
-rw-r--r--tools/testing/selftests/bpf/bpf_helpers.h10
-rw-r--r--tools/testing/selftests/bpf/bpf_rlimit.h28
-rw-r--r--tools/testing/selftests/bpf/sockmap_parse_prog.c15
-rw-r--r--tools/testing/selftests/bpf/sockmap_tcp_msg_prog.c33
-rw-r--r--tools/testing/selftests/bpf/sockmap_verdict_prog.c7
-rw-r--r--tools/testing/selftests/bpf/test_align.c6
-rw-r--r--tools/testing/selftests/bpf/test_dev_cgroup.c6
-rw-r--r--tools/testing/selftests/bpf/test_lpm_map.c14
-rw-r--r--tools/testing/selftests/bpf/test_lru_map.c6
-rw-r--r--tools/testing/selftests/bpf/test_maps.c62
-rw-r--r--tools/testing/selftests/bpf/test_progs.c169
-rw-r--r--tools/testing/selftests/bpf/test_stacktrace_build_id.c60
-rw-r--r--tools/testing/selftests/bpf/test_tag.c4
-rw-r--r--tools/testing/selftests/bpf/test_tcpbpf_user.c2
-rw-r--r--tools/testing/selftests/bpf/test_verifier.c304
-rw-r--r--tools/testing/selftests/bpf/test_verifier_log.c8
-rw-r--r--tools/testing/selftests/bpf/urandom_read.c22
-rw-r--r--tools/testing/selftests/net/Makefile2
-rw-r--r--tools/testing/selftests/net/config5
-rwxr-xr-xtools/testing/selftests/net/fib-onlink-tests.sh467
-rwxr-xr-xtools/testing/selftests/net/fib_tests.sh664
-rw-r--r--tools/testing/selftests/net/forwarding/.gitignore1
-rw-r--r--tools/testing/selftests/net/forwarding/README56
-rwxr-xr-xtools/testing/selftests/net/forwarding/bridge_vlan_aware.sh88
-rwxr-xr-xtools/testing/selftests/net/forwarding/bridge_vlan_unaware.sh86
-rw-r--r--tools/testing/selftests/net/forwarding/config12
-rw-r--r--tools/testing/selftests/net/forwarding/forwarding.config.sample35
-rw-r--r--tools/testing/selftests/net/forwarding/lib.sh577
-rwxr-xr-xtools/testing/selftests/net/forwarding/router.sh125
-rwxr-xr-xtools/testing/selftests/net/forwarding/router_multipath.sh376
-rwxr-xr-xtools/testing/selftests/net/forwarding/tc_actions.sh202
-rwxr-xr-xtools/testing/selftests/net/forwarding/tc_chains.sh122
-rw-r--r--tools/testing/selftests/net/forwarding/tc_common.sh25
-rwxr-xr-xtools/testing/selftests/net/forwarding/tc_flower.sh196
-rwxr-xr-xtools/testing/selftests/net/forwarding/tc_shblocks.sh122
-rwxr-xr-xtools/testing/selftests/net/in_netns.sh23
-rw-r--r--tools/testing/selftests/net/msg_zerocopy.c131
-rwxr-xr-xtools/testing/selftests/net/pmtu.sh471
-rw-r--r--tools/testing/selftests/net/psock_fanout.c35
-rwxr-xr-xtools/testing/selftests/net/rtnetlink.sh6
-rwxr-xr-xtools/testing/selftests/net/run_afpackettests4
-rw-r--r--tools/testing/selftests/networking/timestamping/txtimestamp.c21
-rw-r--r--tools/testing/selftests/tc-testing/README173
-rw-r--r--tools/testing/selftests/tc-testing/TODO.txt25
-rw-r--r--tools/testing/selftests/tc-testing/TdcPlugin.py74
-rw-r--r--tools/testing/selftests/tc-testing/creating-plugins/AddingPlugins.txt104
-rw-r--r--tools/testing/selftests/tc-testing/creating-testcases/AddingTestCases.txt35
-rw-r--r--tools/testing/selftests/tc-testing/plugin-lib/README-PLUGINS27
-rw-r--r--tools/testing/selftests/tc-testing/plugin-lib/nsPlugin.py141
-rw-r--r--tools/testing/selftests/tc-testing/plugin-lib/rootPlugin.py19
-rw-r--r--tools/testing/selftests/tc-testing/plugin-lib/valgrindPlugin.py142
-rw-r--r--tools/testing/selftests/tc-testing/plugins/__init__.py0
-rw-r--r--tools/testing/selftests/tc-testing/tc-tests/actions/csum.json410
-rw-r--r--tools/testing/selftests/tc-testing/tc-tests/actions/gact.json73
-rw-r--r--tools/testing/selftests/tc-testing/tc-tests/actions/vlan.json410
-rwxr-xr-xtools/testing/selftests/tc-testing/tdc.py575
-rwxr-xr-xtools/testing/selftests/tc-testing/tdc_batch.py8
-rw-r--r--tools/testing/selftests/tc-testing/tdc_helper.py15
911 files changed, 46116 insertions, 15720 deletions
diff --git a/Documentation/bpf/bpf_devel_QA.txt b/Documentation/bpf/bpf_devel_QA.txt
index 84cbb302f2b5..1a0b704e1a38 100644
--- a/Documentation/bpf/bpf_devel_QA.txt
+++ b/Documentation/bpf/bpf_devel_QA.txt
@@ -539,6 +539,18 @@ A: Although LLVM IR generation and optimization try to stay architecture
539 The clang option "-fno-jump-tables" can be used to disable 539 The clang option "-fno-jump-tables" can be used to disable
540 switch table generation. 540 switch table generation.
541 541
542 - For clang -target bpf, it is guaranteed that pointer or long /
543 unsigned long types will always have a width of 64 bit, no matter
544 whether underlying clang binary or default target (or kernel) is
545 32 bit. However, when native clang target is used, then it will
546 compile these types based on the underlying architecture's conventions,
547 meaning in case of 32 bit architecture, pointer or long / unsigned
548 long types e.g. in BPF context structure will have width of 32 bit
549 while the BPF LLVM back end still operates in 64 bit. The native
550 target is mostly needed in tracing for the case of walking pt_regs
551 or other kernel structures where CPU's register width matters.
552 Otherwise, clang -target bpf is generally recommended.
553
542 You should use default target when: 554 You should use default target when:
543 555
544 - Your program includes a header file, e.g., ptrace.h, which eventually 556 - Your program includes a header file, e.g., ptrace.h, which eventually
diff --git a/Documentation/devicetree/bindings/net/dsa/marvell.txt b/Documentation/devicetree/bindings/net/dsa/marvell.txt
index 8c033d48e2ba..60d50a2b0323 100644
--- a/Documentation/devicetree/bindings/net/dsa/marvell.txt
+++ b/Documentation/devicetree/bindings/net/dsa/marvell.txt
@@ -13,9 +13,18 @@ placed as a child node of an mdio device.
13The properties described here are those specific to Marvell devices. 13The properties described here are those specific to Marvell devices.
14Additional required and optional properties can be found in dsa.txt. 14Additional required and optional properties can be found in dsa.txt.
15 15
16The compatibility string is used only to find an identification register,
17which is at a different MDIO base address in different switch families.
18- "marvell,mv88e6085" : Switch has base address 0x10. Use with models:
19 6085, 6095, 6097, 6123, 6131, 6141, 6161, 6165,
20 6171, 6172, 6175, 6176, 6185, 6240, 6320, 6321,
21 6341, 6350, 6351, 6352
22- "marvell,mv88e6190" : Switch has base address 0x00. Use with models:
23 6190, 6190X, 6191, 6290, 6390, 6390X
24
16Required properties: 25Required properties:
17- compatible : Should be one of "marvell,mv88e6085" or 26- compatible : Should be one of "marvell,mv88e6085" or
18 "marvell,mv88e6190" 27 "marvell,mv88e6190" as indicated above
19- reg : Address on the MII bus for the switch. 28- reg : Address on the MII bus for the switch.
20 29
21Optional properties: 30Optional properties:
diff --git a/Documentation/devicetree/bindings/net/ieee802154/mcr20a.txt b/Documentation/devicetree/bindings/net/ieee802154/mcr20a.txt
new file mode 100644
index 000000000000..2aaef567c5be
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/ieee802154/mcr20a.txt
@@ -0,0 +1,23 @@
1* MCR20A IEEE 802.15.4 *
2
3Required properties:
4 - compatible: should be "nxp,mcr20a"
5 - spi-max-frequency: maximal bus speed, should be set to a frequency
6 lower than 9000000 depends sync or async operation mode
7 - reg: the chipselect index
8 - interrupts: the interrupt generated by the device. Non high-level
9 can occur deadlocks while handling isr.
10
11Optional properties:
12 - rst_b-gpio: GPIO spec for the RST_B pin
13
14Example:
15
16 mcr20a@0 {
17 compatible = "nxp,mcr20a";
18 spi-max-frequency = <9000000>;
19 reg = <0>;
20 interrupts = <17 2>;
21 interrupt-parent = <&gpio>;
22 rst_b-gpio = <&gpio 27 1>
23 };
diff --git a/Documentation/devicetree/bindings/net/macb.txt b/Documentation/devicetree/bindings/net/macb.txt
index 27966ae741e0..457d5ae16f23 100644
--- a/Documentation/devicetree/bindings/net/macb.txt
+++ b/Documentation/devicetree/bindings/net/macb.txt
@@ -29,6 +29,7 @@ Optional properties for PHY child node:
29- reset-gpios : Should specify the gpio for phy reset 29- reset-gpios : Should specify the gpio for phy reset
30- magic-packet : If present, indicates that the hardware supports waking 30- magic-packet : If present, indicates that the hardware supports waking
31 up via magic packet. 31 up via magic packet.
32- phy-handle : see ethernet.txt file in the same directory
32 33
33Examples: 34Examples:
34 35
diff --git a/Documentation/devicetree/bindings/net/sff,sfp.txt b/Documentation/devicetree/bindings/net/sff,sfp.txt
index f1c441bedf68..929591d52ed6 100644
--- a/Documentation/devicetree/bindings/net/sff,sfp.txt
+++ b/Documentation/devicetree/bindings/net/sff,sfp.txt
@@ -33,6 +33,10 @@ Optional Properties:
33 Select (AKA RS1) output gpio signal (SFP+ only), low: low Tx rate, high: 33 Select (AKA RS1) output gpio signal (SFP+ only), low: low Tx rate, high:
34 high Tx rate. Must not be present for SFF modules 34 high Tx rate. Must not be present for SFF modules
35 35
36- maximum-power-milliwatt : Maximum module power consumption
37 Specifies the maximum power consumption allowable by a module in the
38 slot, in milli-Watts. Presently, modules can be up to 1W, 1.5W or 2W.
39
36Example #1: Direct serdes to SFP connection 40Example #1: Direct serdes to SFP connection
37 41
38sfp_eth3: sfp-eth3 { 42sfp_eth3: sfp-eth3 {
@@ -40,6 +44,7 @@ sfp_eth3: sfp-eth3 {
40 i2c-bus = <&sfp_1g_i2c>; 44 i2c-bus = <&sfp_1g_i2c>;
41 los-gpios = <&cpm_gpio2 22 GPIO_ACTIVE_HIGH>; 45 los-gpios = <&cpm_gpio2 22 GPIO_ACTIVE_HIGH>;
42 mod-def0-gpios = <&cpm_gpio2 21 GPIO_ACTIVE_LOW>; 46 mod-def0-gpios = <&cpm_gpio2 21 GPIO_ACTIVE_LOW>;
47 maximum-power-milliwatt = <1000>;
43 pinctrl-names = "default"; 48 pinctrl-names = "default";
44 pinctrl-0 = <&cpm_sfp_1g_pins &cps_sfp_1g_pins>; 49 pinctrl-0 = <&cpm_sfp_1g_pins &cps_sfp_1g_pins>;
45 tx-disable-gpios = <&cps_gpio1 24 GPIO_ACTIVE_HIGH>; 50 tx-disable-gpios = <&cps_gpio1 24 GPIO_ACTIVE_HIGH>;
diff --git a/Documentation/devicetree/bindings/net/ti,dp83867.txt b/Documentation/devicetree/bindings/net/ti,dp83867.txt
index 02c4353b5cf2..9ef9338aaee1 100644
--- a/Documentation/devicetree/bindings/net/ti,dp83867.txt
+++ b/Documentation/devicetree/bindings/net/ti,dp83867.txt
@@ -25,6 +25,8 @@ Optional property:
25 software needs to take when this pin is 25 software needs to take when this pin is
26 strapped in these modes. See data manual 26 strapped in these modes. See data manual
27 for details. 27 for details.
28 - ti,clk-output-sel - Muxing option for CLK_OUT pin - see dt-bindings/net/ti-dp83867.h
29 for applicable values.
28 30
29Note: ti,min-output-impedance and ti,max-output-impedance are mutually 31Note: ti,min-output-impedance and ti,max-output-impedance are mutually
30 exclusive. When both properties are present ti,max-output-impedance 32 exclusive. When both properties are present ti,max-output-impedance
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index a553d4e4a0fb..1d1120753ae8 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -755,13 +755,13 @@ udp_rmem_min - INTEGER
755 Minimal size of receive buffer used by UDP sockets in moderation. 755 Minimal size of receive buffer used by UDP sockets in moderation.
756 Each UDP socket is able to use the size for receiving data, even if 756 Each UDP socket is able to use the size for receiving data, even if
757 total pages of UDP sockets exceed udp_mem pressure. The unit is byte. 757 total pages of UDP sockets exceed udp_mem pressure. The unit is byte.
758 Default: 1 page 758 Default: 4K
759 759
760udp_wmem_min - INTEGER 760udp_wmem_min - INTEGER
761 Minimal size of send buffer used by UDP sockets in moderation. 761 Minimal size of send buffer used by UDP sockets in moderation.
762 Each UDP socket is able to use the size for sending data, even if 762 Each UDP socket is able to use the size for sending data, even if
763 total pages of UDP sockets exceed udp_mem pressure. The unit is byte. 763 total pages of UDP sockets exceed udp_mem pressure. The unit is byte.
764 Default: 1 page 764 Default: 4K
765 765
766CIPSOv4 Variables: 766CIPSOv4 Variables:
767 767
@@ -1363,6 +1363,13 @@ flowlabel_reflect - BOOLEAN
1363 FALSE: disabled 1363 FALSE: disabled
1364 Default: FALSE 1364 Default: FALSE
1365 1365
1366fib_multipath_hash_policy - INTEGER
1367 Controls which hash policy to use for multipath routes.
1368 Default: 0 (Layer 3)
1369 Possible values:
1370 0 - Layer 3 (source and destination addresses plus flow label)
1371 1 - Layer 4 (standard 5-tuple)
1372
1366anycast_src_echo_reply - BOOLEAN 1373anycast_src_echo_reply - BOOLEAN
1367 Controls the use of anycast addresses as source addresses for ICMPv6 1374 Controls the use of anycast addresses as source addresses for ICMPv6
1368 echo reply 1375 echo reply
@@ -2094,7 +2101,7 @@ sctp_rmem - vector of 3 INTEGERs: min, default, max
2094 It is guaranteed to each SCTP socket (but not association) even 2101 It is guaranteed to each SCTP socket (but not association) even
2095 under moderate memory pressure. 2102 under moderate memory pressure.
2096 2103
2097 Default: 1 page 2104 Default: 4K
2098 2105
2099sctp_wmem - vector of 3 INTEGERs: min, default, max 2106sctp_wmem - vector of 3 INTEGERs: min, default, max
2100 Currently this tunable has no effect. 2107 Currently this tunable has no effect.
diff --git a/Documentation/networking/msg_zerocopy.rst b/Documentation/networking/msg_zerocopy.rst
index 291a01264967..fe46d4867e2d 100644
--- a/Documentation/networking/msg_zerocopy.rst
+++ b/Documentation/networking/msg_zerocopy.rst
@@ -72,11 +72,6 @@ this flag, a process must first signal intent by setting a socket option:
72 if (setsockopt(fd, SOL_SOCKET, SO_ZEROCOPY, &one, sizeof(one))) 72 if (setsockopt(fd, SOL_SOCKET, SO_ZEROCOPY, &one, sizeof(one)))
73 error(1, errno, "setsockopt zerocopy"); 73 error(1, errno, "setsockopt zerocopy");
74 74
75Setting the socket option only works when the socket is in its initial
76(TCP_CLOSED) state. Trying to set the option for a socket returned by accept(),
77for example, will lead to an EBUSY error. In this case, the option should be set
78to the listening socket and it will be inherited by the accepted sockets.
79
80Transmission 75Transmission
81------------ 76------------
82 77
diff --git a/Documentation/networking/net_dim.txt b/Documentation/networking/net_dim.txt
new file mode 100644
index 000000000000..9cb31c5e2dcd
--- /dev/null
+++ b/Documentation/networking/net_dim.txt
@@ -0,0 +1,174 @@
1Net DIM - Generic Network Dynamic Interrupt Moderation
2======================================================
3
4Author:
5 Tal Gilboa <talgi@mellanox.com>
6
7
8Contents
9=========
10
11- Assumptions
12- Introduction
13- The Net DIM Algorithm
14- Registering a Network Device to DIM
15- Example
16
17Part 0: Assumptions
18======================
19
20This document assumes the reader has basic knowledge in network drivers
21and in general interrupt moderation.
22
23
24Part I: Introduction
25======================
26
27Dynamic Interrupt Moderation (DIM) (in networking) refers to changing the
28interrupt moderation configuration of a channel in order to optimize packet
29processing. The mechanism includes an algorithm which decides if and how to
30change moderation parameters for a channel, usually by performing an analysis on
31runtime data sampled from the system. Net DIM is such a mechanism. In each
32iteration of the algorithm, it analyses a given sample of the data, compares it
33to the previous sample and if required, it can decide to change some of the
34interrupt moderation configuration fields. The data sample is composed of data
35bandwidth, the number of packets and the number of events. The time between
36samples is also measured. Net DIM compares the current and the previous data and
37returns an adjusted interrupt moderation configuration object. In some cases,
38the algorithm might decide not to change anything. The configuration fields are
39the minimum duration (microseconds) allowed between events and the maximum
40number of wanted packets per event. The Net DIM algorithm ascribes importance to
41increase bandwidth over reducing interrupt rate.
42
43
44Part II: The Net DIM Algorithm
45===============================
46
47Each iteration of the Net DIM algorithm follows these steps:
481. Calculates new data sample.
492. Compares it to previous sample.
503. Makes a decision - suggests interrupt moderation configuration fields.
514. Applies a schedule work function, which applies suggested configuration.
52
53The first two steps are straightforward, both the new and the previous data are
54supplied by the driver registered to Net DIM. The previous data is the new data
55supplied to the previous iteration. The comparison step checks the difference
56between the new and previous data and decides on the result of the last step.
57A step would result as "better" if bandwidth increases and as "worse" if
58bandwidth reduces. If there is no change in bandwidth, the packet rate is
59compared in a similar fashion - increase == "better" and decrease == "worse".
60In case there is no change in the packet rate as well, the interrupt rate is
61compared. Here the algorithm tries to optimize for lower interrupt rate so an
62increase in the interrupt rate is considered "worse" and a decrease is
63considered "better". Step #2 has an optimization for avoiding false results: it
64only considers a difference between samples as valid if it is greater than a
65certain percentage. Also, since Net DIM does not measure anything by itself, it
66assumes the data provided by the driver is valid.
67
68Step #3 decides on the suggested configuration based on the result from step #2
69and the internal state of the algorithm. The states reflect the "direction" of
70the algorithm: is it going left (reducing moderation), right (increasing
71moderation) or standing still. Another optimization is that if a decision
72to stay still is made multiple times, the interval between iterations of the
73algorithm would increase in order to reduce calculation overhead. Also, after
74"parking" on one of the most left or most right decisions, the algorithm may
75decide to verify this decision by taking a step in the other direction. This is
76done in order to avoid getting stuck in a "deep sleep" scenario. Once a
77decision is made, an interrupt moderation configuration is selected from
78the predefined profiles.
79
80The last step is to notify the registered driver that it should apply the
81suggested configuration. This is done by scheduling a work function, defined by
82the Net DIM API and provided by the registered driver.
83
84As you can see, Net DIM itself does not actively interact with the system. It
85would have trouble making the correct decisions if the wrong data is supplied to
86it and it would be useless if the work function would not apply the suggested
87configuration. This does, however, allow the registered driver some room for
88manoeuvre as it may provide partial data or ignore the algorithm suggestion
89under some conditions.
90
91
92Part III: Registering a Network Device to DIM
93==============================================
94
95Net DIM API exposes the main function net_dim(struct net_dim *dim,
96struct net_dim_sample end_sample). This function is the entry point to the Net
97DIM algorithm and has to be called every time the driver would like to check if
98it should change interrupt moderation parameters. The driver should provide two
99data structures: struct net_dim and struct net_dim_sample. Struct net_dim
100describes the state of DIM for a specific object (RX queue, TX queue,
101other queues, etc.). This includes the current selected profile, previous data
102samples, the callback function provided by the driver and more.
103Struct net_dim_sample describes a data sample, which will be compared to the
104data sample stored in struct net_dim in order to decide on the algorithm's next
105step. The sample should include bytes, packets and interrupts, measured by
106the driver.
107
108In order to use Net DIM from a networking driver, the driver needs to call the
109main net_dim() function. The recommended method is to call net_dim() on each
110interrupt. Since Net DIM has a built-in moderation and it might decide to skip
111iterations under certain conditions, there is no need to moderate the net_dim()
112calls as well. As mentioned above, the driver needs to provide an object of type
113struct net_dim to the net_dim() function call. It is advised for each entity
114using Net DIM to hold a struct net_dim as part of its data structure and use it
115as the main Net DIM API object. The struct net_dim_sample should hold the latest
116bytes, packets and interrupts count. No need to perform any calculations, just
117include the raw data.
118
119The net_dim() call itself does not return anything. Instead Net DIM relies on
120the driver to provide a callback function, which is called when the algorithm
121decides to make a change in the interrupt moderation parameters. This callback
122will be scheduled and run in a separate thread in order not to add overhead to
123the data flow. After the work is done, Net DIM algorithm needs to be set to
124the proper state in order to move to the next iteration.
125
126
127Part IV: Example
128=================
129
130The following code demonstrates how to register a driver to Net DIM. The actual
131usage is not complete but it should make the outline of the usage clear.
132
133my_driver.c:
134
135#include <linux/net_dim.h>
136
137/* Callback for net DIM to schedule on a decision to change moderation */
138void my_driver_do_dim_work(struct work_struct *work)
139{
140 /* Get struct net_dim from struct work_struct */
141 struct net_dim *dim = container_of(work, struct net_dim,
142 work);
143 /* Do interrupt moderation related stuff */
144 ...
145
146 /* Signal net DIM work is done and it should move to next iteration */
147 dim->state = NET_DIM_START_MEASURE;
148}
149
150/* My driver's interrupt handler */
151int my_driver_handle_interrupt(struct my_driver_entity *my_entity, ...)
152{
153 ...
154 /* A struct to hold current measured data */
155 struct net_dim_sample dim_sample;
156 ...
157 /* Initiate data sample struct with current data */
158 net_dim_sample(my_entity->events,
159 my_entity->packets,
160 my_entity->bytes,
161 &dim_sample);
162 /* Call net DIM */
163 net_dim(&my_entity->dim, dim_sample);
164 ...
165}
166
167/* My entity's initialization function (my_entity was already allocated) */
168int my_driver_init_my_entity(struct my_driver_entity *my_entity, ...)
169{
170 ...
171 /* Initiate struct work_struct with my driver's callback function */
172 INIT_WORK(&my_entity->dim.work, my_driver_do_dim_work);
173 ...
174}
diff --git a/Documentation/networking/packet_mmap.txt b/Documentation/networking/packet_mmap.txt
index bf654845556e..999eb41da81d 100644
--- a/Documentation/networking/packet_mmap.txt
+++ b/Documentation/networking/packet_mmap.txt
@@ -7,15 +7,12 @@ socket interface on 2.4/2.6/3.x kernels. This type of sockets is used for
7i) capture network traffic with utilities like tcpdump, ii) transmit network 7i) capture network traffic with utilities like tcpdump, ii) transmit network
8traffic, or any other that needs raw access to network interface. 8traffic, or any other that needs raw access to network interface.
9 9
10You can find the latest version of this document at:
11 http://wiki.ipxwarzone.com/index.php5?title=Linux_packet_mmap
12
13Howto can be found at: 10Howto can be found at:
14 http://wiki.gnu-log.net (packet_mmap) 11 https://sites.google.com/site/packetmmap/
15 12
16Please send your comments to 13Please send your comments to
17 Ulisses Alonso Camaró <uaca@i.hate.spam.alumni.uv.es> 14 Ulisses Alonso Camaró <uaca@i.hate.spam.alumni.uv.es>
18 Johann Baudy <johann.baudy@gnu-log.net> 15 Johann Baudy
19 16
20------------------------------------------------------------------------------- 17-------------------------------------------------------------------------------
21+ Why use PACKET_MMAP 18+ Why use PACKET_MMAP
@@ -51,17 +48,8 @@ From the user standpoint, you should use the higher level libpcap library, which
51is a de facto standard, portable across nearly all operating systems 48is a de facto standard, portable across nearly all operating systems
52including Win32. 49including Win32.
53 50
54Said that, at time of this writing, official libpcap 0.8.1 is out and doesn't include 51Packet MMAP support was integrated into libpcap around the time of version 1.3.0;
55support for PACKET_MMAP, and also probably the libpcap included in your distribution. 52TPACKET_V3 support was added in version 1.5.0
56
57I'm aware of two implementations of PACKET_MMAP in libpcap:
58
59 http://wiki.ipxwarzone.com/ (by Simon Patarin, based on libpcap 0.6.2)
60 http://public.lanl.gov/cpw/ (by Phil Wood, based on lastest libpcap)
61
62The rest of this document is intended for people who want to understand
63the low level details or want to improve libpcap by including PACKET_MMAP
64support.
65 53
66-------------------------------------------------------------------------------- 54--------------------------------------------------------------------------------
67+ How to use mmap() directly to improve capture process 55+ How to use mmap() directly to improve capture process
@@ -174,7 +162,7 @@ As capture, each frame contains two parts:
174 /* bind socket to eth0 */ 162 /* bind socket to eth0 */
175 bind(this->socket, (struct sockaddr *)&my_addr, sizeof(struct sockaddr_ll)); 163 bind(this->socket, (struct sockaddr *)&my_addr, sizeof(struct sockaddr_ll));
176 164
177 A complete tutorial is available at: http://wiki.gnu-log.net/ 165 A complete tutorial is available at: https://sites.google.com/site/packetmmap/
178 166
179By default, the user should put data at : 167By default, the user should put data at :
180 frame base + TPACKET_HDRLEN - sizeof(struct sockaddr_ll) 168 frame base + TPACKET_HDRLEN - sizeof(struct sockaddr_ll)
diff --git a/Documentation/sysctl/net.txt b/Documentation/sysctl/net.txt
index 35c62f522754..5992602469d8 100644
--- a/Documentation/sysctl/net.txt
+++ b/Documentation/sysctl/net.txt
@@ -270,6 +270,18 @@ optmem_max
270Maximum ancillary buffer size allowed per socket. Ancillary data is a sequence 270Maximum ancillary buffer size allowed per socket. Ancillary data is a sequence
271of struct cmsghdr structures with appended data. 271of struct cmsghdr structures with appended data.
272 272
273fb_tunnels_only_for_init_net
274----------------------------
275
276Controls if fallback tunnels (like tunl0, gre0, gretap0, erspan0,
277sit0, ip6tnl0, ip6gre0) are automatically created when a new
278network namespace is created, if corresponding tunnel is present
279in initial network namespace.
280If set to 1, these devices are not automatically created, and
281user space is responsible for creating them if needed.
282
283Default : 0 (for compatibility reasons)
284
2732. /proc/sys/net/unix - Parameters for Unix domain sockets 2852. /proc/sys/net/unix - Parameters for Unix domain sockets
274------------------------------------------------------- 286-------------------------------------------------------
275 287
diff --git a/MAINTAINERS b/MAINTAINERS
index 73c0cdabf755..b3ea844cf228 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8596,6 +8596,15 @@ S: Maintained
8596F: Documentation/ABI/testing/sysfs-bus-iio-potentiometer-mcp4531 8596F: Documentation/ABI/testing/sysfs-bus-iio-potentiometer-mcp4531
8597F: drivers/iio/potentiometer/mcp4531.c 8597F: drivers/iio/potentiometer/mcp4531.c
8598 8598
8599MCR20A IEEE-802.15.4 RADIO DRIVER
8600M: Xue Liu <liuxuenetmail@gmail.com>
8601L: linux-wpan@vger.kernel.org
8602W: https://github.com/xueliu/mcr20a-linux
8603S: Maintained
8604F: drivers/net/ieee802154/mcr20a.c
8605F: drivers/net/ieee802154/mcr20a.h
8606F: Documentation/devicetree/bindings/net/ieee802154/mcr20a.txt
8607
8599MEASUREMENT COMPUTING CIO-DAC IIO DRIVER 8608MEASUREMENT COMPUTING CIO-DAC IIO DRIVER
8600M: William Breathitt Gray <vilhelm.gray@gmail.com> 8609M: William Breathitt Gray <vilhelm.gray@gmail.com>
8601L: linux-iio@vger.kernel.org 8610L: linux-iio@vger.kernel.org
@@ -9152,6 +9161,13 @@ F: drivers/net/dsa/microchip/*
9152F: include/linux/platform_data/microchip-ksz.h 9161F: include/linux/platform_data/microchip-ksz.h
9153F: Documentation/devicetree/bindings/net/dsa/ksz.txt 9162F: Documentation/devicetree/bindings/net/dsa/ksz.txt
9154 9163
9164MICROCHIP LAN743X ETHERNET DRIVER
9165M: Bryan Whitehead <bryan.whitehead@microchip.com>
9166M: Microchip Linux Driver Support <UNGLinuxDriver@microchip.com>
9167L: netdev@vger.kernel.org
9168S: Maintained
9169F: drivers/net/ethernet/microchip/lan743x_*
9170
9155MICROCHIP USB251XB DRIVER 9171MICROCHIP USB251XB DRIVER
9156M: Richard Leitner <richard.leitner@skidata.com> 9172M: Richard Leitner <richard.leitner@skidata.com>
9157L: linux-usb@vger.kernel.org 9173L: linux-usb@vger.kernel.org
diff --git a/arch/arm/boot/dts/armada-370-rd.dts b/arch/arm/boot/dts/armada-370-rd.dts
index 8b2fa9a49967..c28afb242393 100644
--- a/arch/arm/boot/dts/armada-370-rd.dts
+++ b/arch/arm/boot/dts/armada-370-rd.dts
@@ -56,6 +56,7 @@
56 56
57/dts-v1/; 57/dts-v1/;
58#include <dt-bindings/input/input.h> 58#include <dt-bindings/input/input.h>
59#include <dt-bindings/interrupt-controller/irq.h>
59#include <dt-bindings/gpio/gpio.h> 60#include <dt-bindings/gpio/gpio.h>
60#include "armada-370.dtsi" 61#include "armada-370.dtsi"
61 62
@@ -243,6 +244,8 @@
243 #address-cells = <1>; 244 #address-cells = <1>;
244 #size-cells = <0>; 245 #size-cells = <0>;
245 reg = <0x10>; 246 reg = <0x10>;
247 interrupt-controller;
248 #interrupt-cells = <2>;
246 249
247 ports { 250 ports {
248 #address-cells = <1>; 251 #address-cells = <1>;
@@ -278,6 +281,35 @@
278 }; 281 };
279 }; 282 };
280 }; 283 };
284
285 mdio {
286 #address-cells = <1>;
287 #size-cells = <0>;
288
289 switchphy0: switchphy@0 {
290 reg = <0>;
291 interrupt-parent = <&switch>;
292 interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
293 };
294
295 switchphy1: switchphy@1 {
296 reg = <1>;
297 interrupt-parent = <&switch>;
298 interrupts = <1 IRQ_TYPE_LEVEL_HIGH>;
299 };
300
301 switchphy2: switchphy@2 {
302 reg = <2>;
303 interrupt-parent = <&switch>;
304 interrupts = <2 IRQ_TYPE_LEVEL_HIGH>;
305 };
306
307 switchphy3: switchphy@3 {
308 reg = <3>;
309 interrupt-parent = <&switch>;
310 interrupts = <3 IRQ_TYPE_LEVEL_HIGH>;
311 };
312 };
281 }; 313 };
282}; 314};
283 315
diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c
index d3d435248a24..c73eb8209555 100644
--- a/arch/m68k/mac/config.c
+++ b/arch/m68k/mac/config.c
@@ -1088,6 +1088,10 @@ int __init mac_platform_init(void)
1088 macintosh_config->expansion_type == MAC_EXP_PDS_COMM) 1088 macintosh_config->expansion_type == MAC_EXP_PDS_COMM)
1089 platform_device_register_simple("macsonic", -1, NULL, 0); 1089 platform_device_register_simple("macsonic", -1, NULL, 0);
1090 1090
1091 if (macintosh_config->expansion_type == MAC_EXP_PDS ||
1092 macintosh_config->expansion_type == MAC_EXP_PDS_COMM)
1093 platform_device_register_simple("mac89x0", -1, NULL, 0);
1094
1091 if (macintosh_config->ether_type == MAC_ETHER_MACE) 1095 if (macintosh_config->ether_type == MAC_ETHER_MACE)
1092 platform_device_register_simple("macmace", -1, NULL, 0); 1096 platform_device_register_simple("macmace", -1, NULL, 0);
1093 1097
diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
index ce5b2ebd5701..b725154182cc 100644
--- a/arch/x86/net/bpf_jit_comp.c
+++ b/arch/x86/net/bpf_jit_comp.c
@@ -11,10 +11,10 @@
11#include <linux/netdevice.h> 11#include <linux/netdevice.h>
12#include <linux/filter.h> 12#include <linux/filter.h>
13#include <linux/if_vlan.h> 13#include <linux/if_vlan.h>
14#include <asm/cacheflush.h> 14#include <linux/bpf.h>
15
15#include <asm/set_memory.h> 16#include <asm/set_memory.h>
16#include <asm/nospec-branch.h> 17#include <asm/nospec-branch.h>
17#include <linux/bpf.h>
18 18
19/* 19/*
20 * assembly code in arch/x86/net/bpf_jit.S 20 * assembly code in arch/x86/net/bpf_jit.S
@@ -61,7 +61,12 @@ static bool is_imm8(int value)
61 61
62static bool is_simm32(s64 value) 62static bool is_simm32(s64 value)
63{ 63{
64 return value == (s64) (s32) value; 64 return value == (s64)(s32)value;
65}
66
67static bool is_uimm32(u64 value)
68{
69 return value == (u64)(u32)value;
65} 70}
66 71
67/* mov dst, src */ 72/* mov dst, src */
@@ -98,16 +103,6 @@ static int bpf_size_to_x86_bytes(int bpf_size)
98#define X86_JLE 0x7E 103#define X86_JLE 0x7E
99#define X86_JG 0x7F 104#define X86_JG 0x7F
100 105
101static void bpf_flush_icache(void *start, void *end)
102{
103 mm_segment_t old_fs = get_fs();
104
105 set_fs(KERNEL_DS);
106 smp_wmb();
107 flush_icache_range((unsigned long)start, (unsigned long)end);
108 set_fs(old_fs);
109}
110
111#define CHOOSE_LOAD_FUNC(K, func) \ 106#define CHOOSE_LOAD_FUNC(K, func) \
112 ((int)K < 0 ? ((int)K >= SKF_LL_OFF ? func##_negative_offset : func) : func##_positive_offset) 107 ((int)K < 0 ? ((int)K >= SKF_LL_OFF ? func##_negative_offset : func) : func##_positive_offset)
113 108
@@ -212,7 +207,7 @@ struct jit_context {
212/* emit x64 prologue code for BPF program and check it's size. 207/* emit x64 prologue code for BPF program and check it's size.
213 * bpf_tail_call helper will skip it while jumping into another program 208 * bpf_tail_call helper will skip it while jumping into another program
214 */ 209 */
215static void emit_prologue(u8 **pprog, u32 stack_depth) 210static void emit_prologue(u8 **pprog, u32 stack_depth, bool ebpf_from_cbpf)
216{ 211{
217 u8 *prog = *pprog; 212 u8 *prog = *pprog;
218 int cnt = 0; 213 int cnt = 0;
@@ -247,18 +242,21 @@ static void emit_prologue(u8 **pprog, u32 stack_depth)
247 /* mov qword ptr [rbp+24],r15 */ 242 /* mov qword ptr [rbp+24],r15 */
248 EMIT4(0x4C, 0x89, 0x7D, 24); 243 EMIT4(0x4C, 0x89, 0x7D, 24);
249 244
250 /* Clear the tail call counter (tail_call_cnt): for eBPF tail calls 245 if (!ebpf_from_cbpf) {
251 * we need to reset the counter to 0. It's done in two instructions, 246 /* Clear the tail call counter (tail_call_cnt): for eBPF tail
252 * resetting rax register to 0 (xor on eax gets 0 extended), and 247 * calls we need to reset the counter to 0. It's done in two
253 * moving it to the counter location. 248 * instructions, resetting rax register to 0, and moving it
254 */ 249 * to the counter location.
250 */
255 251
256 /* xor eax, eax */ 252 /* xor eax, eax */
257 EMIT2(0x31, 0xc0); 253 EMIT2(0x31, 0xc0);
258 /* mov qword ptr [rbp+32], rax */ 254 /* mov qword ptr [rbp+32], rax */
259 EMIT4(0x48, 0x89, 0x45, 32); 255 EMIT4(0x48, 0x89, 0x45, 32);
256
257 BUILD_BUG_ON(cnt != PROLOGUE_SIZE);
258 }
260 259
261 BUILD_BUG_ON(cnt != PROLOGUE_SIZE);
262 *pprog = prog; 260 *pprog = prog;
263} 261}
264 262
@@ -356,6 +354,86 @@ static void emit_load_skb_data_hlen(u8 **pprog)
356 *pprog = prog; 354 *pprog = prog;
357} 355}
358 356
357static void emit_mov_imm32(u8 **pprog, bool sign_propagate,
358 u32 dst_reg, const u32 imm32)
359{
360 u8 *prog = *pprog;
361 u8 b1, b2, b3;
362 int cnt = 0;
363
364 /* optimization: if imm32 is positive, use 'mov %eax, imm32'
365 * (which zero-extends imm32) to save 2 bytes.
366 */
367 if (sign_propagate && (s32)imm32 < 0) {
368 /* 'mov %rax, imm32' sign extends imm32 */
369 b1 = add_1mod(0x48, dst_reg);
370 b2 = 0xC7;
371 b3 = 0xC0;
372 EMIT3_off32(b1, b2, add_1reg(b3, dst_reg), imm32);
373 goto done;
374 }
375
376 /* optimization: if imm32 is zero, use 'xor %eax, %eax'
377 * to save 3 bytes.
378 */
379 if (imm32 == 0) {
380 if (is_ereg(dst_reg))
381 EMIT1(add_2mod(0x40, dst_reg, dst_reg));
382 b2 = 0x31; /* xor */
383 b3 = 0xC0;
384 EMIT2(b2, add_2reg(b3, dst_reg, dst_reg));
385 goto done;
386 }
387
388 /* mov %eax, imm32 */
389 if (is_ereg(dst_reg))
390 EMIT1(add_1mod(0x40, dst_reg));
391 EMIT1_off32(add_1reg(0xB8, dst_reg), imm32);
392done:
393 *pprog = prog;
394}
395
396static void emit_mov_imm64(u8 **pprog, u32 dst_reg,
397 const u32 imm32_hi, const u32 imm32_lo)
398{
399 u8 *prog = *pprog;
400 int cnt = 0;
401
402 if (is_uimm32(((u64)imm32_hi << 32) | (u32)imm32_lo)) {
403 /* For emitting plain u32, where sign bit must not be
404 * propagated LLVM tends to load imm64 over mov32
405 * directly, so save couple of bytes by just doing
406 * 'mov %eax, imm32' instead.
407 */
408 emit_mov_imm32(&prog, false, dst_reg, imm32_lo);
409 } else {
410 /* movabsq %rax, imm64 */
411 EMIT2(add_1mod(0x48, dst_reg), add_1reg(0xB8, dst_reg));
412 EMIT(imm32_lo, 4);
413 EMIT(imm32_hi, 4);
414 }
415
416 *pprog = prog;
417}
418
419static void emit_mov_reg(u8 **pprog, bool is64, u32 dst_reg, u32 src_reg)
420{
421 u8 *prog = *pprog;
422 int cnt = 0;
423
424 if (is64) {
425 /* mov dst, src */
426 EMIT_mov(dst_reg, src_reg);
427 } else {
428 /* mov32 dst, src */
429 if (is_ereg(dst_reg) || is_ereg(src_reg))
430 EMIT1(add_2mod(0x40, dst_reg, src_reg));
431 EMIT2(0x89, add_2reg(0xC0, dst_reg, src_reg));
432 }
433
434 *pprog = prog;
435}
436
359static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, 437static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
360 int oldproglen, struct jit_context *ctx) 438 int oldproglen, struct jit_context *ctx)
361{ 439{
@@ -369,7 +447,8 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
369 int proglen = 0; 447 int proglen = 0;
370 u8 *prog = temp; 448 u8 *prog = temp;
371 449
372 emit_prologue(&prog, bpf_prog->aux->stack_depth); 450 emit_prologue(&prog, bpf_prog->aux->stack_depth,
451 bpf_prog_was_classic(bpf_prog));
373 452
374 if (seen_ld_abs) 453 if (seen_ld_abs)
375 emit_load_skb_data_hlen(&prog); 454 emit_load_skb_data_hlen(&prog);
@@ -378,7 +457,7 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
378 const s32 imm32 = insn->imm; 457 const s32 imm32 = insn->imm;
379 u32 dst_reg = insn->dst_reg; 458 u32 dst_reg = insn->dst_reg;
380 u32 src_reg = insn->src_reg; 459 u32 src_reg = insn->src_reg;
381 u8 b1 = 0, b2 = 0, b3 = 0; 460 u8 b2 = 0, b3 = 0;
382 s64 jmp_offset; 461 s64 jmp_offset;
383 u8 jmp_cond; 462 u8 jmp_cond;
384 bool reload_skb_data; 463 bool reload_skb_data;
@@ -414,16 +493,11 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
414 EMIT2(b2, add_2reg(0xC0, dst_reg, src_reg)); 493 EMIT2(b2, add_2reg(0xC0, dst_reg, src_reg));
415 break; 494 break;
416 495
417 /* mov dst, src */
418 case BPF_ALU64 | BPF_MOV | BPF_X: 496 case BPF_ALU64 | BPF_MOV | BPF_X:
419 EMIT_mov(dst_reg, src_reg);
420 break;
421
422 /* mov32 dst, src */
423 case BPF_ALU | BPF_MOV | BPF_X: 497 case BPF_ALU | BPF_MOV | BPF_X:
424 if (is_ereg(dst_reg) || is_ereg(src_reg)) 498 emit_mov_reg(&prog,
425 EMIT1(add_2mod(0x40, dst_reg, src_reg)); 499 BPF_CLASS(insn->code) == BPF_ALU64,
426 EMIT2(0x89, add_2reg(0xC0, dst_reg, src_reg)); 500 dst_reg, src_reg);
427 break; 501 break;
428 502
429 /* neg dst */ 503 /* neg dst */
@@ -486,58 +560,13 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
486 break; 560 break;
487 561
488 case BPF_ALU64 | BPF_MOV | BPF_K: 562 case BPF_ALU64 | BPF_MOV | BPF_K:
489 /* optimization: if imm32 is positive,
490 * use 'mov eax, imm32' (which zero-extends imm32)
491 * to save 2 bytes
492 */
493 if (imm32 < 0) {
494 /* 'mov rax, imm32' sign extends imm32 */
495 b1 = add_1mod(0x48, dst_reg);
496 b2 = 0xC7;
497 b3 = 0xC0;
498 EMIT3_off32(b1, b2, add_1reg(b3, dst_reg), imm32);
499 break;
500 }
501
502 case BPF_ALU | BPF_MOV | BPF_K: 563 case BPF_ALU | BPF_MOV | BPF_K:
503 /* optimization: if imm32 is zero, use 'xor <dst>,<dst>' 564 emit_mov_imm32(&prog, BPF_CLASS(insn->code) == BPF_ALU64,
504 * to save 3 bytes. 565 dst_reg, imm32);
505 */
506 if (imm32 == 0) {
507 if (is_ereg(dst_reg))
508 EMIT1(add_2mod(0x40, dst_reg, dst_reg));
509 b2 = 0x31; /* xor */
510 b3 = 0xC0;
511 EMIT2(b2, add_2reg(b3, dst_reg, dst_reg));
512 break;
513 }
514
515 /* mov %eax, imm32 */
516 if (is_ereg(dst_reg))
517 EMIT1(add_1mod(0x40, dst_reg));
518 EMIT1_off32(add_1reg(0xB8, dst_reg), imm32);
519 break; 566 break;
520 567
521 case BPF_LD | BPF_IMM | BPF_DW: 568 case BPF_LD | BPF_IMM | BPF_DW:
522 /* optimization: if imm64 is zero, use 'xor <dst>,<dst>' 569 emit_mov_imm64(&prog, dst_reg, insn[1].imm, insn[0].imm);
523 * to save 7 bytes.
524 */
525 if (insn[0].imm == 0 && insn[1].imm == 0) {
526 b1 = add_2mod(0x48, dst_reg, dst_reg);
527 b2 = 0x31; /* xor */
528 b3 = 0xC0;
529 EMIT3(b1, b2, add_2reg(b3, dst_reg, dst_reg));
530
531 insn++;
532 i++;
533 break;
534 }
535
536 /* movabsq %rax, imm64 */
537 EMIT2(add_1mod(0x48, dst_reg), add_1reg(0xB8, dst_reg));
538 EMIT(insn[0].imm, 4);
539 EMIT(insn[1].imm, 4);
540
541 insn++; 570 insn++;
542 i++; 571 i++;
543 break; 572 break;
@@ -594,36 +623,38 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
594 case BPF_ALU | BPF_MUL | BPF_X: 623 case BPF_ALU | BPF_MUL | BPF_X:
595 case BPF_ALU64 | BPF_MUL | BPF_K: 624 case BPF_ALU64 | BPF_MUL | BPF_K:
596 case BPF_ALU64 | BPF_MUL | BPF_X: 625 case BPF_ALU64 | BPF_MUL | BPF_X:
597 EMIT1(0x50); /* push rax */ 626 {
598 EMIT1(0x52); /* push rdx */ 627 bool is64 = BPF_CLASS(insn->code) == BPF_ALU64;
628
629 if (dst_reg != BPF_REG_0)
630 EMIT1(0x50); /* push rax */
631 if (dst_reg != BPF_REG_3)
632 EMIT1(0x52); /* push rdx */
599 633
600 /* mov r11, dst_reg */ 634 /* mov r11, dst_reg */
601 EMIT_mov(AUX_REG, dst_reg); 635 EMIT_mov(AUX_REG, dst_reg);
602 636
603 if (BPF_SRC(insn->code) == BPF_X) 637 if (BPF_SRC(insn->code) == BPF_X)
604 /* mov rax, src_reg */ 638 emit_mov_reg(&prog, is64, BPF_REG_0, src_reg);
605 EMIT_mov(BPF_REG_0, src_reg);
606 else 639 else
607 /* mov rax, imm32 */ 640 emit_mov_imm32(&prog, is64, BPF_REG_0, imm32);
608 EMIT3_off32(0x48, 0xC7, 0xC0, imm32);
609 641
610 if (BPF_CLASS(insn->code) == BPF_ALU64) 642 if (is64)
611 EMIT1(add_1mod(0x48, AUX_REG)); 643 EMIT1(add_1mod(0x48, AUX_REG));
612 else if (is_ereg(AUX_REG)) 644 else if (is_ereg(AUX_REG))
613 EMIT1(add_1mod(0x40, AUX_REG)); 645 EMIT1(add_1mod(0x40, AUX_REG));
614 /* mul(q) r11 */ 646 /* mul(q) r11 */
615 EMIT2(0xF7, add_1reg(0xE0, AUX_REG)); 647 EMIT2(0xF7, add_1reg(0xE0, AUX_REG));
616 648
617 /* mov r11, rax */ 649 if (dst_reg != BPF_REG_3)
618 EMIT_mov(AUX_REG, BPF_REG_0); 650 EMIT1(0x5A); /* pop rdx */
619 651 if (dst_reg != BPF_REG_0) {
620 EMIT1(0x5A); /* pop rdx */ 652 /* mov dst_reg, rax */
621 EMIT1(0x58); /* pop rax */ 653 EMIT_mov(dst_reg, BPF_REG_0);
622 654 EMIT1(0x58); /* pop rax */
623 /* mov dst_reg, r11 */ 655 }
624 EMIT_mov(dst_reg, AUX_REG);
625 break; 656 break;
626 657 }
627 /* shifts */ 658 /* shifts */
628 case BPF_ALU | BPF_LSH | BPF_K: 659 case BPF_ALU | BPF_LSH | BPF_K:
629 case BPF_ALU | BPF_RSH | BPF_K: 660 case BPF_ALU | BPF_RSH | BPF_K:
@@ -641,7 +672,11 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
641 case BPF_RSH: b3 = 0xE8; break; 672 case BPF_RSH: b3 = 0xE8; break;
642 case BPF_ARSH: b3 = 0xF8; break; 673 case BPF_ARSH: b3 = 0xF8; break;
643 } 674 }
644 EMIT3(0xC1, add_1reg(b3, dst_reg), imm32); 675
676 if (imm32 == 1)
677 EMIT2(0xD1, add_1reg(b3, dst_reg));
678 else
679 EMIT3(0xC1, add_1reg(b3, dst_reg), imm32);
645 break; 680 break;
646 681
647 case BPF_ALU | BPF_LSH | BPF_X: 682 case BPF_ALU | BPF_LSH | BPF_X:
@@ -1222,7 +1257,6 @@ skip_init_addrs:
1222 bpf_jit_dump(prog->len, proglen, pass + 1, image); 1257 bpf_jit_dump(prog->len, proglen, pass + 1, image);
1223 1258
1224 if (image) { 1259 if (image) {
1225 bpf_flush_icache(header, image + proglen);
1226 if (!prog->is_func || extra_pass) { 1260 if (!prog->is_func || extra_pass) {
1227 bpf_jit_binary_lock_ro(header); 1261 bpf_jit_binary_lock_ro(header);
1228 } else { 1262 } else {
diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c
index 0277f36be85b..6e737142ceaa 100644
--- a/drivers/atm/idt77252.c
+++ b/drivers/atm/idt77252.c
@@ -3173,14 +3173,10 @@ static void init_sram(struct idt77252_dev *card)
3173 (u32) 0xffffffff); 3173 (u32) 0xffffffff);
3174 } 3174 }
3175 3175
3176 writel((SAR_FBQ0_LOW << 28) | 0x00000000 | 0x00000000 | 3176 writel((SAR_FBQ0_LOW << 28) | (SAR_FB_SIZE_0 / 48), SAR_REG_FBQS0);
3177 (SAR_FB_SIZE_0 / 48), SAR_REG_FBQS0); 3177 writel((SAR_FBQ1_LOW << 28) | (SAR_FB_SIZE_1 / 48), SAR_REG_FBQS1);
3178 writel((SAR_FBQ1_LOW << 28) | 0x00000000 | 0x00000000 | 3178 writel((SAR_FBQ2_LOW << 28) | (SAR_FB_SIZE_2 / 48), SAR_REG_FBQS2);
3179 (SAR_FB_SIZE_1 / 48), SAR_REG_FBQS1); 3179 writel((SAR_FBQ3_LOW << 28) | (SAR_FB_SIZE_3 / 48), SAR_REG_FBQS3);
3180 writel((SAR_FBQ2_LOW << 28) | 0x00000000 | 0x00000000 |
3181 (SAR_FB_SIZE_2 / 48), SAR_REG_FBQS2);
3182 writel((SAR_FBQ3_LOW << 28) | 0x00000000 | 0x00000000 |
3183 (SAR_FB_SIZE_3 / 48), SAR_REG_FBQS3);
3184 3180
3185 /* Initialize rate table */ 3181 /* Initialize rate table */
3186 for (i = 0; i < 256; i++) { 3182 for (i = 0; i < 256; i++) {
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index 204afe66de92..3d7a5c149af3 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -203,6 +203,12 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
203 { } /* Terminating entry */ 203 { } /* Terminating entry */
204}; 204};
205 205
206static inline void ath3k_log_failed_loading(int err, int len, int size)
207{
208 BT_ERR("Error in firmware loading err = %d, len = %d, size = %d",
209 err, len, size);
210}
211
206#define USB_REQ_DFU_DNLOAD 1 212#define USB_REQ_DFU_DNLOAD 1
207#define BULK_SIZE 4096 213#define BULK_SIZE 4096
208#define FW_HDR_SIZE 20 214#define FW_HDR_SIZE 20
@@ -227,15 +233,16 @@ static int ath3k_load_firmware(struct usb_device *udev,
227 return -ENOMEM; 233 return -ENOMEM;
228 } 234 }
229 235
230 memcpy(send_buf, firmware->data, 20); 236 memcpy(send_buf, firmware->data, FW_HDR_SIZE);
231 err = usb_control_msg(udev, pipe, USB_REQ_DFU_DNLOAD, USB_TYPE_VENDOR, 237 err = usb_control_msg(udev, pipe, USB_REQ_DFU_DNLOAD, USB_TYPE_VENDOR,
232 0, 0, send_buf, 20, USB_CTRL_SET_TIMEOUT); 238 0, 0, send_buf, FW_HDR_SIZE,
239 USB_CTRL_SET_TIMEOUT);
233 if (err < 0) { 240 if (err < 0) {
234 BT_ERR("Can't change to loading configuration err"); 241 BT_ERR("Can't change to loading configuration err");
235 goto error; 242 goto error;
236 } 243 }
237 sent += 20; 244 sent += FW_HDR_SIZE;
238 count -= 20; 245 count -= FW_HDR_SIZE;
239 246
240 pipe = usb_sndbulkpipe(udev, 0x02); 247 pipe = usb_sndbulkpipe(udev, 0x02);
241 248
@@ -250,8 +257,7 @@ static int ath3k_load_firmware(struct usb_device *udev,
250 &len, 3000); 257 &len, 3000);
251 258
252 if (err || (len != size)) { 259 if (err || (len != size)) {
253 BT_ERR("Error in firmware loading err = %d," 260 ath3k_log_failed_loading(err, len, size);
254 "len = %d, size = %d", err, len, size);
255 goto error; 261 goto error;
256 } 262 }
257 263
@@ -350,8 +356,7 @@ static int ath3k_load_fwfile(struct usb_device *udev,
350 err = usb_bulk_msg(udev, pipe, send_buf, size, 356 err = usb_bulk_msg(udev, pipe, send_buf, size,
351 &len, 3000); 357 &len, 3000);
352 if (err || (len != size)) { 358 if (err || (len != size)) {
353 BT_ERR("Error in firmware loading err = %d," 359 ath3k_log_failed_loading(err, len, size);
354 "len = %d, size = %d", err, len, size);
355 kfree(send_buf); 360 kfree(send_buf);
356 return err; 361 return err;
357 } 362 }
@@ -398,7 +403,7 @@ static int ath3k_set_normal_mode(struct usb_device *udev)
398static int ath3k_load_patch(struct usb_device *udev) 403static int ath3k_load_patch(struct usb_device *udev)
399{ 404{
400 unsigned char fw_state; 405 unsigned char fw_state;
401 char filename[ATH3K_NAME_LEN] = {0}; 406 char filename[ATH3K_NAME_LEN];
402 const struct firmware *firmware; 407 const struct firmware *firmware;
403 struct ath3k_version fw_version; 408 struct ath3k_version fw_version;
404 __u32 pt_rom_version, pt_build_version; 409 __u32 pt_rom_version, pt_build_version;
@@ -451,7 +456,7 @@ static int ath3k_load_patch(struct usb_device *udev)
451static int ath3k_load_syscfg(struct usb_device *udev) 456static int ath3k_load_syscfg(struct usb_device *udev)
452{ 457{
453 unsigned char fw_state; 458 unsigned char fw_state;
454 char filename[ATH3K_NAME_LEN] = {0}; 459 char filename[ATH3K_NAME_LEN];
455 const struct firmware *firmware; 460 const struct firmware *firmware;
456 struct ath3k_version fw_version; 461 struct ath3k_version fw_version;
457 int clk_value, ret; 462 int clk_value, ret;
@@ -522,7 +527,6 @@ static int ath3k_probe(struct usb_interface *intf,
522 527
523 /* load patch and sysconfig files for AR3012 */ 528 /* load patch and sysconfig files for AR3012 */
524 if (id->driver_info & BTUSB_ATH3012) { 529 if (id->driver_info & BTUSB_ATH3012) {
525
526 /* New firmware with patch and sysconfig files already loaded */ 530 /* New firmware with patch and sysconfig files already loaded */
527 if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x0001) 531 if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x0001)
528 return -ENODEV; 532 return -ENODEV;
@@ -565,7 +569,7 @@ static int ath3k_probe(struct usb_interface *intf,
565 569
566static void ath3k_disconnect(struct usb_interface *intf) 570static void ath3k_disconnect(struct usb_interface *intf)
567{ 571{
568 BT_DBG("ath3k_disconnect intf %p", intf); 572 BT_DBG("%s intf %p", __func__, intf);
569} 573}
570 574
571static struct usb_driver ath3k_driver = { 575static struct usb_driver ath3k_driver = {
diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c
index b280d466f05b..f6c694a1b9b0 100644
--- a/drivers/bluetooth/btmrvl_main.c
+++ b/drivers/bluetooth/btmrvl_main.c
@@ -183,7 +183,7 @@ static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 opcode,
183 return -EFAULT; 183 return -EFAULT;
184 } 184 }
185 185
186 skb = bt_skb_alloc(HCI_COMMAND_HDR_SIZE + len, GFP_ATOMIC); 186 skb = bt_skb_alloc(HCI_COMMAND_HDR_SIZE + len, GFP_KERNEL);
187 if (!skb) { 187 if (!skb) {
188 BT_ERR("No free skb"); 188 BT_ERR("No free skb");
189 return -ENOMEM; 189 return -ENOMEM;
diff --git a/drivers/bluetooth/btrtl.c b/drivers/bluetooth/btrtl.c
index 6e2ad748abba..437f080deaab 100644
--- a/drivers/bluetooth/btrtl.c
+++ b/drivers/bluetooth/btrtl.c
@@ -35,6 +35,60 @@
35#define RTL_ROM_LMP_8761A 0x8761 35#define RTL_ROM_LMP_8761A 0x8761
36#define RTL_ROM_LMP_8822B 0x8822 36#define RTL_ROM_LMP_8822B 0x8822
37 37
38#define IC_MATCH_FL_LMPSUBV (1 << 0)
39#define IC_MATCH_FL_HCIREV (1 << 1)
40#define IC_INFO(lmps, hcir) \
41 .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_HCIREV, \
42 .lmp_subver = (lmps), \
43 .hci_rev = (hcir)
44
45struct id_table {
46 __u16 match_flags;
47 __u16 lmp_subver;
48 __u16 hci_rev;
49 bool config_needed;
50 char *fw_name;
51 char *cfg_name;
52};
53
54static const struct id_table ic_id_table[] = {
55 /* 8723B */
56 { IC_INFO(RTL_ROM_LMP_8723B, 0xb),
57 .config_needed = false,
58 .fw_name = "rtl_bt/rtl8723b_fw.bin",
59 .cfg_name = "rtl_bt/rtl8723b_config.bin" },
60
61 /* 8723D */
62 { IC_INFO(RTL_ROM_LMP_8723B, 0xd),
63 .config_needed = true,
64 .fw_name = "rtl_bt/rtl8723d_fw.bin",
65 .cfg_name = "rtl_bt/rtl8723d_config.bin" },
66
67 /* 8821A */
68 { IC_INFO(RTL_ROM_LMP_8821A, 0xa),
69 .config_needed = false,
70 .fw_name = "rtl_bt/rtl8821a_fw.bin",
71 .cfg_name = "rtl_bt/rtl8821a_config.bin" },
72
73 /* 8821C */
74 { IC_INFO(RTL_ROM_LMP_8821A, 0xc),
75 .config_needed = false,
76 .fw_name = "rtl_bt/rtl8821c_fw.bin",
77 .cfg_name = "rtl_bt/rtl8821c_config.bin" },
78
79 /* 8761A */
80 { IC_MATCH_FL_LMPSUBV, RTL_ROM_LMP_8761A, 0x0,
81 .config_needed = false,
82 .fw_name = "rtl_bt/rtl8761a_fw.bin",
83 .cfg_name = "rtl_bt/rtl8761a_config.bin" },
84
85 /* 8822B */
86 { IC_INFO(RTL_ROM_LMP_8822B, 0xb),
87 .config_needed = true,
88 .fw_name = "rtl_bt/rtl8822b_fw.bin",
89 .cfg_name = "rtl_bt/rtl8822b_config.bin" },
90 };
91
38static int rtl_read_rom_version(struct hci_dev *hdev, u8 *version) 92static int rtl_read_rom_version(struct hci_dev *hdev, u8 *version)
39{ 93{
40 struct rtl_rom_version_evt *rom_version; 94 struct rtl_rom_version_evt *rom_version;
@@ -64,9 +118,9 @@ static int rtl_read_rom_version(struct hci_dev *hdev, u8 *version)
64 return 0; 118 return 0;
65} 119}
66 120
67static int rtl8723b_parse_firmware(struct hci_dev *hdev, u16 lmp_subver, 121static int rtlbt_parse_firmware(struct hci_dev *hdev, u16 lmp_subver,
68 const struct firmware *fw, 122 const struct firmware *fw,
69 unsigned char **_buf) 123 unsigned char **_buf)
70{ 124{
71 const u8 extension_sig[] = { 0x51, 0x04, 0xfd, 0x77 }; 125 const u8 extension_sig[] = { 0x51, 0x04, 0xfd, 0x77 };
72 struct rtl_epatch_header *epatch_info; 126 struct rtl_epatch_header *epatch_info;
@@ -88,6 +142,8 @@ static int rtl8723b_parse_firmware(struct hci_dev *hdev, u16 lmp_subver,
88 { RTL_ROM_LMP_8821A, 2 }, 142 { RTL_ROM_LMP_8821A, 2 },
89 { RTL_ROM_LMP_8761A, 3 }, 143 { RTL_ROM_LMP_8761A, 3 },
90 { RTL_ROM_LMP_8822B, 8 }, 144 { RTL_ROM_LMP_8822B, 8 },
145 { RTL_ROM_LMP_8723B, 9 }, /* 8723D */
146 { RTL_ROM_LMP_8821A, 10 }, /* 8821C */
91 }; 147 };
92 148
93 ret = rtl_read_rom_version(hdev, &rom_version); 149 ret = rtl_read_rom_version(hdev, &rom_version);
@@ -320,8 +376,8 @@ out:
320 return ret; 376 return ret;
321} 377}
322 378
323static int btrtl_setup_rtl8723b(struct hci_dev *hdev, u16 lmp_subver, 379static int btrtl_setup_rtl8723b(struct hci_dev *hdev, u16 hci_rev,
324 const char *fw_name) 380 u16 lmp_subver)
325{ 381{
326 unsigned char *fw_data = NULL; 382 unsigned char *fw_data = NULL;
327 const struct firmware *fw; 383 const struct firmware *fw;
@@ -330,39 +386,40 @@ static int btrtl_setup_rtl8723b(struct hci_dev *hdev, u16 lmp_subver,
330 u8 *cfg_buff = NULL; 386 u8 *cfg_buff = NULL;
331 u8 *tbuff; 387 u8 *tbuff;
332 char *cfg_name = NULL; 388 char *cfg_name = NULL;
333 bool config_needed = false; 389 char *fw_name = NULL;
390 int i;
391
392 for (i = 0; i < ARRAY_SIZE(ic_id_table); i++) {
393 if ((ic_id_table[i].match_flags & IC_MATCH_FL_LMPSUBV) &&
394 (ic_id_table[i].lmp_subver != lmp_subver))
395 continue;
396 if ((ic_id_table[i].match_flags & IC_MATCH_FL_HCIREV) &&
397 (ic_id_table[i].hci_rev != hci_rev))
398 continue;
334 399
335 switch (lmp_subver) {
336 case RTL_ROM_LMP_8723B:
337 cfg_name = "rtl_bt/rtl8723b_config.bin";
338 break;
339 case RTL_ROM_LMP_8821A:
340 cfg_name = "rtl_bt/rtl8821a_config.bin";
341 break;
342 case RTL_ROM_LMP_8761A:
343 cfg_name = "rtl_bt/rtl8761a_config.bin";
344 break;
345 case RTL_ROM_LMP_8822B:
346 cfg_name = "rtl_bt/rtl8822b_config.bin";
347 config_needed = true;
348 break;
349 default:
350 BT_ERR("%s: rtl: no config according to lmp_subver %04x",
351 hdev->name, lmp_subver);
352 break; 400 break;
353 } 401 }
354 402
403 if (i >= ARRAY_SIZE(ic_id_table)) {
404 BT_ERR("%s: unknown IC info, lmp subver %04x, hci rev %04x",
405 hdev->name, lmp_subver, hci_rev);
406 return -EINVAL;
407 }
408
409 cfg_name = ic_id_table[i].cfg_name;
410
355 if (cfg_name) { 411 if (cfg_name) {
356 cfg_sz = rtl_load_config(hdev, cfg_name, &cfg_buff); 412 cfg_sz = rtl_load_config(hdev, cfg_name, &cfg_buff);
357 if (cfg_sz < 0) { 413 if (cfg_sz < 0) {
358 cfg_sz = 0; 414 cfg_sz = 0;
359 if (config_needed) 415 if (ic_id_table[i].config_needed)
360 BT_ERR("Necessary config file %s not found\n", 416 BT_ERR("Necessary config file %s not found\n",
361 cfg_name); 417 cfg_name);
362 } 418 }
363 } else 419 } else
364 cfg_sz = 0; 420 cfg_sz = 0;
365 421
422 fw_name = ic_id_table[i].fw_name;
366 bt_dev_info(hdev, "rtl: loading %s", fw_name); 423 bt_dev_info(hdev, "rtl: loading %s", fw_name);
367 ret = request_firmware(&fw, fw_name, &hdev->dev); 424 ret = request_firmware(&fw, fw_name, &hdev->dev);
368 if (ret < 0) { 425 if (ret < 0) {
@@ -370,7 +427,7 @@ static int btrtl_setup_rtl8723b(struct hci_dev *hdev, u16 lmp_subver,
370 goto err_req_fw; 427 goto err_req_fw;
371 } 428 }
372 429
373 ret = rtl8723b_parse_firmware(hdev, lmp_subver, fw, &fw_data); 430 ret = rtlbt_parse_firmware(hdev, lmp_subver, fw, &fw_data);
374 if (ret < 0) 431 if (ret < 0)
375 goto out; 432 goto out;
376 433
@@ -429,7 +486,7 @@ int btrtl_setup_realtek(struct hci_dev *hdev)
429{ 486{
430 struct sk_buff *skb; 487 struct sk_buff *skb;
431 struct hci_rp_read_local_version *resp; 488 struct hci_rp_read_local_version *resp;
432 u16 lmp_subver; 489 u16 hci_rev, lmp_subver;
433 490
434 skb = btrtl_read_local_version(hdev); 491 skb = btrtl_read_local_version(hdev);
435 if (IS_ERR(skb)) 492 if (IS_ERR(skb))
@@ -441,6 +498,7 @@ int btrtl_setup_realtek(struct hci_dev *hdev)
441 resp->hci_ver, resp->hci_rev, 498 resp->hci_ver, resp->hci_rev,
442 resp->lmp_ver, resp->lmp_subver); 499 resp->lmp_ver, resp->lmp_subver);
443 500
501 hci_rev = le16_to_cpu(resp->hci_rev);
444 lmp_subver = le16_to_cpu(resp->lmp_subver); 502 lmp_subver = le16_to_cpu(resp->lmp_subver);
445 kfree_skb(skb); 503 kfree_skb(skb);
446 504
@@ -455,17 +513,10 @@ int btrtl_setup_realtek(struct hci_dev *hdev)
455 case RTL_ROM_LMP_3499: 513 case RTL_ROM_LMP_3499:
456 return btrtl_setup_rtl8723a(hdev); 514 return btrtl_setup_rtl8723a(hdev);
457 case RTL_ROM_LMP_8723B: 515 case RTL_ROM_LMP_8723B:
458 return btrtl_setup_rtl8723b(hdev, lmp_subver,
459 "rtl_bt/rtl8723b_fw.bin");
460 case RTL_ROM_LMP_8821A: 516 case RTL_ROM_LMP_8821A:
461 return btrtl_setup_rtl8723b(hdev, lmp_subver,
462 "rtl_bt/rtl8821a_fw.bin");
463 case RTL_ROM_LMP_8761A: 517 case RTL_ROM_LMP_8761A:
464 return btrtl_setup_rtl8723b(hdev, lmp_subver,
465 "rtl_bt/rtl8761a_fw.bin");
466 case RTL_ROM_LMP_8822B: 518 case RTL_ROM_LMP_8822B:
467 return btrtl_setup_rtl8723b(hdev, lmp_subver, 519 return btrtl_setup_rtl8723b(hdev, hci_rev, lmp_subver);
468 "rtl_bt/rtl8822b_fw.bin");
469 default: 520 default:
470 bt_dev_info(hdev, "rtl: assuming no firmware upload needed"); 521 bt_dev_info(hdev, "rtl: assuming no firmware upload needed");
471 return 0; 522 return 0;
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 366a49c7c08f..5cd868ea28ed 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -340,6 +340,7 @@ static const struct usb_device_id blacklist_table[] = {
340 340
341 /* Intel Bluetooth devices */ 341 /* Intel Bluetooth devices */
342 { USB_DEVICE(0x8087, 0x0025), .driver_info = BTUSB_INTEL_NEW }, 342 { USB_DEVICE(0x8087, 0x0025), .driver_info = BTUSB_INTEL_NEW },
343 { USB_DEVICE(0x8087, 0x0026), .driver_info = BTUSB_INTEL_NEW },
343 { USB_DEVICE(0x8087, 0x07da), .driver_info = BTUSB_CSR }, 344 { USB_DEVICE(0x8087, 0x07da), .driver_info = BTUSB_CSR },
344 { USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL }, 345 { USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL },
345 { USB_DEVICE(0x8087, 0x0a2a), .driver_info = BTUSB_INTEL }, 346 { USB_DEVICE(0x8087, 0x0a2a), .driver_info = BTUSB_INTEL },
@@ -374,6 +375,9 @@ static const struct usb_device_id blacklist_table[] = {
374 { USB_DEVICE(0x13d3, 0x3461), .driver_info = BTUSB_REALTEK }, 375 { USB_DEVICE(0x13d3, 0x3461), .driver_info = BTUSB_REALTEK },
375 { USB_DEVICE(0x13d3, 0x3462), .driver_info = BTUSB_REALTEK }, 376 { USB_DEVICE(0x13d3, 0x3462), .driver_info = BTUSB_REALTEK },
376 377
378 /* Additional Realtek 8822BE Bluetooth devices */
379 { USB_DEVICE(0x0b05, 0x185c), .driver_info = BTUSB_REALTEK },
380
377 /* Silicon Wave based devices */ 381 /* Silicon Wave based devices */
378 { USB_DEVICE(0x0c10, 0x0000), .driver_info = BTUSB_SWAVE }, 382 { USB_DEVICE(0x0c10, 0x0000), .driver_info = BTUSB_SWAVE },
379 383
@@ -2073,6 +2077,8 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
2073 case 0x0c: /* WsP */ 2077 case 0x0c: /* WsP */
2074 case 0x11: /* JfP */ 2078 case 0x11: /* JfP */
2075 case 0x12: /* ThP */ 2079 case 0x12: /* ThP */
2080 case 0x13: /* HrP */
2081 case 0x14: /* QnJ, IcP */
2076 break; 2082 break;
2077 default: 2083 default:
2078 BT_ERR("%s: Unsupported Intel hardware variant (%u)", 2084 BT_ERR("%s: Unsupported Intel hardware variant (%u)",
@@ -2165,6 +2171,8 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
2165 break; 2171 break;
2166 case 0x11: /* JfP */ 2172 case 0x11: /* JfP */
2167 case 0x12: /* ThP */ 2173 case 0x12: /* ThP */
2174 case 0x13: /* HrP */
2175 case 0x14: /* QnJ, IcP */
2168 snprintf(fwname, sizeof(fwname), "intel/ibt-%u-%u-%u.sfi", 2176 snprintf(fwname, sizeof(fwname), "intel/ibt-%u-%u-%u.sfi",
2169 le16_to_cpu(ver.hw_variant), 2177 le16_to_cpu(ver.hw_variant),
2170 le16_to_cpu(ver.hw_revision), 2178 le16_to_cpu(ver.hw_revision),
@@ -2196,6 +2204,8 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
2196 break; 2204 break;
2197 case 0x11: /* JfP */ 2205 case 0x11: /* JfP */
2198 case 0x12: /* ThP */ 2206 case 0x12: /* ThP */
2207 case 0x13: /* HrP */
2208 case 0x14: /* QnJ, IcP */
2199 snprintf(fwname, sizeof(fwname), "intel/ibt-%u-%u-%u.ddc", 2209 snprintf(fwname, sizeof(fwname), "intel/ibt-%u-%u-%u.ddc",
2200 le16_to_cpu(ver.hw_variant), 2210 le16_to_cpu(ver.hw_variant),
2201 le16_to_cpu(ver.hw_revision), 2211 le16_to_cpu(ver.hw_revision),
diff --git a/drivers/bluetooth/hci_ath.c b/drivers/bluetooth/hci_ath.c
index 14ae7ee88acb..d568fbd94d6c 100644
--- a/drivers/bluetooth/hci_ath.c
+++ b/drivers/bluetooth/hci_ath.c
@@ -71,12 +71,12 @@ static int ath_wakeup_ar3k(struct tty_struct *tty)
71 /* Clear RTS first */ 71 /* Clear RTS first */
72 tty->driver->ops->tiocmget(tty); 72 tty->driver->ops->tiocmget(tty);
73 tty->driver->ops->tiocmset(tty, 0x00, TIOCM_RTS); 73 tty->driver->ops->tiocmset(tty, 0x00, TIOCM_RTS);
74 mdelay(20); 74 msleep(20);
75 75
76 /* Set RTS, wake up board */ 76 /* Set RTS, wake up board */
77 tty->driver->ops->tiocmget(tty); 77 tty->driver->ops->tiocmget(tty);
78 tty->driver->ops->tiocmset(tty, TIOCM_RTS, 0x00); 78 tty->driver->ops->tiocmset(tty, TIOCM_RTS, 0x00);
79 mdelay(20); 79 msleep(20);
80 80
81 status = tty->driver->ops->tiocmget(tty); 81 status = tty->driver->ops->tiocmget(tty);
82 return status; 82 return status;
diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c
index 1b4417a623a4..2f30dcad96bd 100644
--- a/drivers/bluetooth/hci_ll.c
+++ b/drivers/bluetooth/hci_ll.c
@@ -650,7 +650,7 @@ static int download_firmware(struct ll_device *lldev)
650 break; 650 break;
651 case ACTION_DELAY: /* sleep */ 651 case ACTION_DELAY: /* sleep */
652 bt_dev_info(lldev->hu.hdev, "sleep command in scr"); 652 bt_dev_info(lldev->hu.hdev, "sleep command in scr");
653 mdelay(((struct bts_action_delay *)action_ptr)->msec); 653 msleep(((struct bts_action_delay *)action_ptr)->msec);
654 break; 654 break;
655 } 655 }
656 len -= (sizeof(struct bts_action) + 656 len -= (sizeof(struct bts_action) +
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index a5367c5efbe7..66f203730e80 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -1334,7 +1334,7 @@ static bool validate_ipv6_net_dev(struct net_device *net_dev,
1334 IPV6_ADDR_LINKLOCAL; 1334 IPV6_ADDR_LINKLOCAL;
1335 struct rt6_info *rt = rt6_lookup(dev_net(net_dev), &dst_addr->sin6_addr, 1335 struct rt6_info *rt = rt6_lookup(dev_net(net_dev), &dst_addr->sin6_addr,
1336 &src_addr->sin6_addr, net_dev->ifindex, 1336 &src_addr->sin6_addr, net_dev->ifindex,
1337 strict); 1337 NULL, strict);
1338 bool ret; 1338 bool ret;
1339 1339
1340 if (!rt) 1340 if (!rt)
@@ -4554,6 +4554,7 @@ static struct pernet_operations cma_pernet_operations = {
4554 .exit = cma_exit_net, 4554 .exit = cma_exit_net,
4555 .id = &cma_pernet_id, 4555 .id = &cma_pernet_id,
4556 .size = sizeof(struct cma_pernet), 4556 .size = sizeof(struct cma_pernet),
4557 .async = true,
4557}; 4558};
4558 4559
4559static int __init cma_init(void) 4560static int __init cma_init(void)
diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c
index 7a9d0de89d6a..e96771ddc9a7 100644
--- a/drivers/infiniband/hw/cxgb4/device.c
+++ b/drivers/infiniband/hw/cxgb4/device.c
@@ -1217,6 +1217,7 @@ static int c4iw_uld_state_change(void *handle, enum cxgb4_state new_state)
1217 if (ctx->dev) 1217 if (ctx->dev)
1218 c4iw_remove(ctx); 1218 c4iw_remove(ctx);
1219 break; 1219 break;
1220 case CXGB4_STATE_FATAL_ERROR:
1220 case CXGB4_STATE_START_RECOVERY: 1221 case CXGB4_STATE_START_RECOVERY:
1221 pr_info("%s: Fatal Error\n", pci_name(ctx->lldi.pdev)); 1222 pr_info("%s: Fatal Error\n", pci_name(ctx->lldi.pdev));
1222 if (ctx->dev) { 1223 if (ctx->dev) {
diff --git a/drivers/infiniband/hw/mlx5/Makefile b/drivers/infiniband/hw/mlx5/Makefile
index bc6299697dda..d42b922bede8 100644
--- a/drivers/infiniband/hw/mlx5/Makefile
+++ b/drivers/infiniband/hw/mlx5/Makefile
@@ -2,3 +2,4 @@ obj-$(CONFIG_MLX5_INFINIBAND) += mlx5_ib.o
2 2
3mlx5_ib-y := main.o cq.o doorbell.o qp.o mem.o srq.o mr.o ah.o mad.o gsi.o ib_virt.o cmd.o cong.o 3mlx5_ib-y := main.o cq.o doorbell.o qp.o mem.o srq.o mr.o ah.o mad.o gsi.o ib_virt.o cmd.o cong.o
4mlx5_ib-$(CONFIG_INFINIBAND_ON_DEMAND_PAGING) += odp.o 4mlx5_ib-$(CONFIG_INFINIBAND_ON_DEMAND_PAGING) += odp.o
5mlx5_ib-$(CONFIG_MLX5_ESWITCH) += ib_rep.o
diff --git a/drivers/infiniband/hw/mlx5/cq.c b/drivers/infiniband/hw/mlx5/cq.c
index 15457c9569a7..94a27d89a303 100644
--- a/drivers/infiniband/hw/mlx5/cq.c
+++ b/drivers/infiniband/hw/mlx5/cq.c
@@ -64,14 +64,9 @@ static void mlx5_ib_cq_event(struct mlx5_core_cq *mcq, enum mlx5_event type)
64 } 64 }
65} 65}
66 66
67static void *get_cqe_from_buf(struct mlx5_ib_cq_buf *buf, int n, int size)
68{
69 return mlx5_buf_offset(&buf->buf, n * size);
70}
71
72static void *get_cqe(struct mlx5_ib_cq *cq, int n) 67static void *get_cqe(struct mlx5_ib_cq *cq, int n)
73{ 68{
74 return get_cqe_from_buf(&cq->buf, n, cq->mcq.cqe_sz); 69 return mlx5_frag_buf_get_wqe(&cq->buf.fbc, n);
75} 70}
76 71
77static u8 sw_ownership_bit(int n, int nent) 72static u8 sw_ownership_bit(int n, int nent)
@@ -404,7 +399,7 @@ static void handle_atomics(struct mlx5_ib_qp *qp, struct mlx5_cqe64 *cqe64,
404 399
405static void free_cq_buf(struct mlx5_ib_dev *dev, struct mlx5_ib_cq_buf *buf) 400static void free_cq_buf(struct mlx5_ib_dev *dev, struct mlx5_ib_cq_buf *buf)
406{ 401{
407 mlx5_buf_free(dev->mdev, &buf->buf); 402 mlx5_frag_buf_free(dev->mdev, &buf->fbc.frag_buf);
408} 403}
409 404
410static void get_sig_err_item(struct mlx5_sig_err_cqe *cqe, 405static void get_sig_err_item(struct mlx5_sig_err_cqe *cqe,
@@ -725,12 +720,25 @@ int mlx5_ib_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags)
725 return ret; 720 return ret;
726} 721}
727 722
728static int alloc_cq_buf(struct mlx5_ib_dev *dev, struct mlx5_ib_cq_buf *buf, 723static int alloc_cq_frag_buf(struct mlx5_ib_dev *dev,
729 int nent, int cqe_size) 724 struct mlx5_ib_cq_buf *buf,
725 int nent,
726 int cqe_size)
730{ 727{
728 struct mlx5_frag_buf_ctrl *c = &buf->fbc;
729 struct mlx5_frag_buf *frag_buf = &c->frag_buf;
730 u32 cqc_buff[MLX5_ST_SZ_DW(cqc)] = {0};
731 int err; 731 int err;
732 732
733 err = mlx5_buf_alloc(dev->mdev, nent * cqe_size, &buf->buf); 733 MLX5_SET(cqc, cqc_buff, log_cq_size, ilog2(cqe_size));
734 MLX5_SET(cqc, cqc_buff, cqe_sz, (cqe_size == 128) ? 1 : 0);
735
736 mlx5_core_init_cq_frag_buf(&buf->fbc, cqc_buff);
737
738 err = mlx5_frag_buf_alloc_node(dev->mdev,
739 nent * cqe_size,
740 frag_buf,
741 dev->mdev->priv.numa_node);
734 if (err) 742 if (err)
735 return err; 743 return err;
736 744
@@ -863,14 +871,15 @@ static void destroy_cq_user(struct mlx5_ib_cq *cq, struct ib_ucontext *context)
863 ib_umem_release(cq->buf.umem); 871 ib_umem_release(cq->buf.umem);
864} 872}
865 873
866static void init_cq_buf(struct mlx5_ib_cq *cq, struct mlx5_ib_cq_buf *buf) 874static void init_cq_frag_buf(struct mlx5_ib_cq *cq,
875 struct mlx5_ib_cq_buf *buf)
867{ 876{
868 int i; 877 int i;
869 void *cqe; 878 void *cqe;
870 struct mlx5_cqe64 *cqe64; 879 struct mlx5_cqe64 *cqe64;
871 880
872 for (i = 0; i < buf->nent; i++) { 881 for (i = 0; i < buf->nent; i++) {
873 cqe = get_cqe_from_buf(buf, i, buf->cqe_size); 882 cqe = get_cqe(cq, i);
874 cqe64 = buf->cqe_size == 64 ? cqe : cqe + 64; 883 cqe64 = buf->cqe_size == 64 ? cqe : cqe + 64;
875 cqe64->op_own = MLX5_CQE_INVALID << 4; 884 cqe64->op_own = MLX5_CQE_INVALID << 4;
876 } 885 }
@@ -892,14 +901,15 @@ static int create_cq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *cq,
892 cq->mcq.arm_db = cq->db.db + 1; 901 cq->mcq.arm_db = cq->db.db + 1;
893 cq->mcq.cqe_sz = cqe_size; 902 cq->mcq.cqe_sz = cqe_size;
894 903
895 err = alloc_cq_buf(dev, &cq->buf, entries, cqe_size); 904 err = alloc_cq_frag_buf(dev, &cq->buf, entries, cqe_size);
896 if (err) 905 if (err)
897 goto err_db; 906 goto err_db;
898 907
899 init_cq_buf(cq, &cq->buf); 908 init_cq_frag_buf(cq, &cq->buf);
900 909
901 *inlen = MLX5_ST_SZ_BYTES(create_cq_in) + 910 *inlen = MLX5_ST_SZ_BYTES(create_cq_in) +
902 MLX5_FLD_SZ_BYTES(create_cq_in, pas[0]) * cq->buf.buf.npages; 911 MLX5_FLD_SZ_BYTES(create_cq_in, pas[0]) *
912 cq->buf.fbc.frag_buf.npages;
903 *cqb = kvzalloc(*inlen, GFP_KERNEL); 913 *cqb = kvzalloc(*inlen, GFP_KERNEL);
904 if (!*cqb) { 914 if (!*cqb) {
905 err = -ENOMEM; 915 err = -ENOMEM;
@@ -907,11 +917,12 @@ static int create_cq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *cq,
907 } 917 }
908 918
909 pas = (__be64 *)MLX5_ADDR_OF(create_cq_in, *cqb, pas); 919 pas = (__be64 *)MLX5_ADDR_OF(create_cq_in, *cqb, pas);
910 mlx5_fill_page_array(&cq->buf.buf, pas); 920 mlx5_fill_page_frag_array(&cq->buf.fbc.frag_buf, pas);
911 921
912 cqc = MLX5_ADDR_OF(create_cq_in, *cqb, cq_context); 922 cqc = MLX5_ADDR_OF(create_cq_in, *cqb, cq_context);
913 MLX5_SET(cqc, cqc, log_page_size, 923 MLX5_SET(cqc, cqc, log_page_size,
914 cq->buf.buf.page_shift - MLX5_ADAPTER_PAGE_SHIFT); 924 cq->buf.fbc.frag_buf.page_shift -
925 MLX5_ADAPTER_PAGE_SHIFT);
915 926
916 *index = dev->mdev->priv.uar->index; 927 *index = dev->mdev->priv.uar->index;
917 928
@@ -1213,11 +1224,11 @@ static int resize_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *cq,
1213 if (!cq->resize_buf) 1224 if (!cq->resize_buf)
1214 return -ENOMEM; 1225 return -ENOMEM;
1215 1226
1216 err = alloc_cq_buf(dev, cq->resize_buf, entries, cqe_size); 1227 err = alloc_cq_frag_buf(dev, cq->resize_buf, entries, cqe_size);
1217 if (err) 1228 if (err)
1218 goto ex; 1229 goto ex;
1219 1230
1220 init_cq_buf(cq, cq->resize_buf); 1231 init_cq_frag_buf(cq, cq->resize_buf);
1221 1232
1222 return 0; 1233 return 0;
1223 1234
@@ -1262,9 +1273,8 @@ static int copy_resize_cqes(struct mlx5_ib_cq *cq)
1262 } 1273 }
1263 1274
1264 while ((scqe64->op_own >> 4) != MLX5_CQE_RESIZE_CQ) { 1275 while ((scqe64->op_own >> 4) != MLX5_CQE_RESIZE_CQ) {
1265 dcqe = get_cqe_from_buf(cq->resize_buf, 1276 dcqe = mlx5_frag_buf_get_wqe(&cq->resize_buf->fbc,
1266 (i + 1) & (cq->resize_buf->nent), 1277 (i + 1) & cq->resize_buf->nent);
1267 dsize);
1268 dcqe64 = dsize == 64 ? dcqe : dcqe + 64; 1278 dcqe64 = dsize == 64 ? dcqe : dcqe + 64;
1269 sw_own = sw_ownership_bit(i + 1, cq->resize_buf->nent); 1279 sw_own = sw_ownership_bit(i + 1, cq->resize_buf->nent);
1270 memcpy(dcqe, scqe, dsize); 1280 memcpy(dcqe, scqe, dsize);
@@ -1330,8 +1340,11 @@ int mlx5_ib_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *udata)
1330 cqe_size = 64; 1340 cqe_size = 64;
1331 err = resize_kernel(dev, cq, entries, cqe_size); 1341 err = resize_kernel(dev, cq, entries, cqe_size);
1332 if (!err) { 1342 if (!err) {
1333 npas = cq->resize_buf->buf.npages; 1343 struct mlx5_frag_buf_ctrl *c;
1334 page_shift = cq->resize_buf->buf.page_shift; 1344
1345 c = &cq->resize_buf->fbc;
1346 npas = c->frag_buf.npages;
1347 page_shift = c->frag_buf.page_shift;
1335 } 1348 }
1336 } 1349 }
1337 1350
@@ -1352,7 +1365,8 @@ int mlx5_ib_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *udata)
1352 mlx5_ib_populate_pas(dev, cq->resize_umem, page_shift, 1365 mlx5_ib_populate_pas(dev, cq->resize_umem, page_shift,
1353 pas, 0); 1366 pas, 0);
1354 else 1367 else
1355 mlx5_fill_page_array(&cq->resize_buf->buf, pas); 1368 mlx5_fill_page_frag_array(&cq->resize_buf->fbc.frag_buf,
1369 pas);
1356 1370
1357 MLX5_SET(modify_cq_in, in, 1371 MLX5_SET(modify_cq_in, in,
1358 modify_field_select_resize_field_select.resize_field_select.resize_field_select, 1372 modify_field_select_resize_field_select.resize_field_select.resize_field_select,
diff --git a/drivers/infiniband/hw/mlx5/ib_rep.c b/drivers/infiniband/hw/mlx5/ib_rep.c
new file mode 100644
index 000000000000..0e04fdddf670
--- /dev/null
+++ b/drivers/infiniband/hw/mlx5/ib_rep.c
@@ -0,0 +1,192 @@
1/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
2/*
3 * Copyright (c) 2018 Mellanox Technologies. All rights reserved.
4 */
5
6#include "ib_rep.h"
7
8static const struct mlx5_ib_profile rep_profile = {
9 STAGE_CREATE(MLX5_IB_STAGE_INIT,
10 mlx5_ib_stage_init_init,
11 mlx5_ib_stage_init_cleanup),
12 STAGE_CREATE(MLX5_IB_STAGE_FLOW_DB,
13 mlx5_ib_stage_rep_flow_db_init,
14 NULL),
15 STAGE_CREATE(MLX5_IB_STAGE_CAPS,
16 mlx5_ib_stage_caps_init,
17 NULL),
18 STAGE_CREATE(MLX5_IB_STAGE_NON_DEFAULT_CB,
19 mlx5_ib_stage_rep_non_default_cb,
20 NULL),
21 STAGE_CREATE(MLX5_IB_STAGE_ROCE,
22 mlx5_ib_stage_rep_roce_init,
23 mlx5_ib_stage_rep_roce_cleanup),
24 STAGE_CREATE(MLX5_IB_STAGE_DEVICE_RESOURCES,
25 mlx5_ib_stage_dev_res_init,
26 mlx5_ib_stage_dev_res_cleanup),
27 STAGE_CREATE(MLX5_IB_STAGE_COUNTERS,
28 mlx5_ib_stage_counters_init,
29 mlx5_ib_stage_counters_cleanup),
30 STAGE_CREATE(MLX5_IB_STAGE_BFREG,
31 mlx5_ib_stage_bfrag_init,
32 mlx5_ib_stage_bfrag_cleanup),
33 STAGE_CREATE(MLX5_IB_STAGE_PRE_IB_REG_UMR,
34 NULL,
35 mlx5_ib_stage_pre_ib_reg_umr_cleanup),
36 STAGE_CREATE(MLX5_IB_STAGE_IB_REG,
37 mlx5_ib_stage_ib_reg_init,
38 mlx5_ib_stage_ib_reg_cleanup),
39 STAGE_CREATE(MLX5_IB_STAGE_POST_IB_REG_UMR,
40 mlx5_ib_stage_post_ib_reg_umr_init,
41 NULL),
42 STAGE_CREATE(MLX5_IB_STAGE_CLASS_ATTR,
43 mlx5_ib_stage_class_attr_init,
44 NULL),
45};
46
47static int
48mlx5_ib_nic_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
49{
50 return 0;
51}
52
53static void
54mlx5_ib_nic_rep_unload(struct mlx5_eswitch_rep *rep)
55{
56 rep->rep_if[REP_IB].priv = NULL;
57}
58
59static int
60mlx5_ib_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
61{
62 struct mlx5_ib_dev *ibdev;
63
64 ibdev = (struct mlx5_ib_dev *)ib_alloc_device(sizeof(*ibdev));
65 if (!ibdev)
66 return -ENOMEM;
67
68 ibdev->rep = rep;
69 ibdev->mdev = dev;
70 ibdev->num_ports = max(MLX5_CAP_GEN(dev, num_ports),
71 MLX5_CAP_GEN(dev, num_vhca_ports));
72 if (!__mlx5_ib_add(ibdev, &rep_profile))
73 return -EINVAL;
74
75 rep->rep_if[REP_IB].priv = ibdev;
76
77 return 0;
78}
79
80static void
81mlx5_ib_vport_rep_unload(struct mlx5_eswitch_rep *rep)
82{
83 struct mlx5_ib_dev *dev;
84
85 if (!rep->rep_if[REP_IB].priv)
86 return;
87
88 dev = mlx5_ib_rep_to_dev(rep);
89 __mlx5_ib_remove(dev, dev->profile, MLX5_IB_STAGE_MAX);
90 rep->rep_if[REP_IB].priv = NULL;
91}
92
93static void *mlx5_ib_vport_get_proto_dev(struct mlx5_eswitch_rep *rep)
94{
95 return mlx5_ib_rep_to_dev(rep);
96}
97
98static void mlx5_ib_rep_register_vf_vports(struct mlx5_ib_dev *dev)
99{
100 struct mlx5_eswitch *esw = dev->mdev->priv.eswitch;
101 int total_vfs = MLX5_TOTAL_VPORTS(dev->mdev);
102 int vport;
103
104 for (vport = 1; vport < total_vfs; vport++) {
105 struct mlx5_eswitch_rep_if rep_if = {};
106
107 rep_if.load = mlx5_ib_vport_rep_load;
108 rep_if.unload = mlx5_ib_vport_rep_unload;
109 rep_if.get_proto_dev = mlx5_ib_vport_get_proto_dev;
110 mlx5_eswitch_register_vport_rep(esw, vport, &rep_if, REP_IB);
111 }
112}
113
114static void mlx5_ib_rep_unregister_vf_vports(struct mlx5_ib_dev *dev)
115{
116 struct mlx5_eswitch *esw = dev->mdev->priv.eswitch;
117 int total_vfs = MLX5_TOTAL_VPORTS(dev->mdev);
118 int vport;
119
120 for (vport = 1; vport < total_vfs; vport++)
121 mlx5_eswitch_unregister_vport_rep(esw, vport, REP_IB);
122}
123
124void mlx5_ib_register_vport_reps(struct mlx5_ib_dev *dev)
125{
126 struct mlx5_eswitch *esw = dev->mdev->priv.eswitch;
127 struct mlx5_eswitch_rep_if rep_if = {};
128
129 rep_if.load = mlx5_ib_nic_rep_load;
130 rep_if.unload = mlx5_ib_nic_rep_unload;
131 rep_if.get_proto_dev = mlx5_ib_vport_get_proto_dev;
132 rep_if.priv = dev;
133
134 mlx5_eswitch_register_vport_rep(esw, 0, &rep_if, REP_IB);
135
136 mlx5_ib_rep_register_vf_vports(dev);
137}
138
139void mlx5_ib_unregister_vport_reps(struct mlx5_ib_dev *dev)
140{
141 struct mlx5_eswitch *esw = dev->mdev->priv.eswitch;
142
143 mlx5_ib_rep_unregister_vf_vports(dev); /* VFs vports */
144 mlx5_eswitch_unregister_vport_rep(esw, 0, REP_IB); /* UPLINK PF*/
145}
146
147u8 mlx5_ib_eswitch_mode(struct mlx5_eswitch *esw)
148{
149 return mlx5_eswitch_mode(esw);
150}
151
152struct mlx5_ib_dev *mlx5_ib_get_rep_ibdev(struct mlx5_eswitch *esw,
153 int vport_index)
154{
155 return mlx5_eswitch_get_proto_dev(esw, vport_index, REP_IB);
156}
157
158struct net_device *mlx5_ib_get_rep_netdev(struct mlx5_eswitch *esw,
159 int vport_index)
160{
161 return mlx5_eswitch_get_proto_dev(esw, vport_index, REP_ETH);
162}
163
164struct mlx5_ib_dev *mlx5_ib_get_uplink_ibdev(struct mlx5_eswitch *esw)
165{
166 return mlx5_eswitch_uplink_get_proto_dev(esw, REP_IB);
167}
168
169struct mlx5_eswitch_rep *mlx5_ib_vport_rep(struct mlx5_eswitch *esw, int vport)
170{
171 return mlx5_eswitch_vport_rep(esw, vport);
172}
173
174int create_flow_rule_vport_sq(struct mlx5_ib_dev *dev,
175 struct mlx5_ib_sq *sq)
176{
177 struct mlx5_flow_handle *flow_rule;
178 struct mlx5_eswitch *esw = dev->mdev->priv.eswitch;
179
180 if (!dev->rep)
181 return 0;
182
183 flow_rule =
184 mlx5_eswitch_add_send_to_vport_rule(esw,
185 dev->rep->vport,
186 sq->base.mqp.qpn);
187 if (IS_ERR(flow_rule))
188 return PTR_ERR(flow_rule);
189 sq->flow_rule = flow_rule;
190
191 return 0;
192}
diff --git a/drivers/infiniband/hw/mlx5/ib_rep.h b/drivers/infiniband/hw/mlx5/ib_rep.h
new file mode 100644
index 000000000000..046fd942fd46
--- /dev/null
+++ b/drivers/infiniband/hw/mlx5/ib_rep.h
@@ -0,0 +1,72 @@
1/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
2/*
3 * Copyright (c) 2018 Mellanox Technologies. All rights reserved.
4 */
5
6#ifndef __MLX5_IB_REP_H__
7#define __MLX5_IB_REP_H__
8
9#include <linux/mlx5/eswitch.h>
10#include "mlx5_ib.h"
11
12#ifdef CONFIG_MLX5_ESWITCH
13u8 mlx5_ib_eswitch_mode(struct mlx5_eswitch *esw);
14struct mlx5_ib_dev *mlx5_ib_get_rep_ibdev(struct mlx5_eswitch *esw,
15 int vport_index);
16struct mlx5_ib_dev *mlx5_ib_get_uplink_ibdev(struct mlx5_eswitch *esw);
17struct mlx5_eswitch_rep *mlx5_ib_vport_rep(struct mlx5_eswitch *esw,
18 int vport_index);
19void mlx5_ib_register_vport_reps(struct mlx5_ib_dev *dev);
20void mlx5_ib_unregister_vport_reps(struct mlx5_ib_dev *dev);
21int create_flow_rule_vport_sq(struct mlx5_ib_dev *dev,
22 struct mlx5_ib_sq *sq);
23struct net_device *mlx5_ib_get_rep_netdev(struct mlx5_eswitch *esw,
24 int vport_index);
25#else /* CONFIG_MLX5_ESWITCH */
26static inline u8 mlx5_ib_eswitch_mode(struct mlx5_eswitch *esw)
27{
28 return SRIOV_NONE;
29}
30
31static inline
32struct mlx5_ib_dev *mlx5_ib_get_rep_ibdev(struct mlx5_eswitch *esw,
33 int vport_index)
34{
35 return NULL;
36}
37
38static inline
39struct mlx5_ib_dev *mlx5_ib_get_uplink_ibdev(struct mlx5_eswitch *esw)
40{
41 return NULL;
42}
43
44static inline
45struct mlx5_eswitch_rep *mlx5_ib_vport_rep(struct mlx5_eswitch *esw,
46 int vport_index)
47{
48 return NULL;
49}
50
51static inline void mlx5_ib_register_vport_reps(struct mlx5_ib_dev *dev) {}
52static inline void mlx5_ib_unregister_vport_reps(struct mlx5_ib_dev *dev) {}
53static inline int create_flow_rule_vport_sq(struct mlx5_ib_dev *dev,
54 struct mlx5_ib_sq *sq)
55{
56 return 0;
57}
58
59static inline
60struct net_device *mlx5_ib_get_rep_netdev(struct mlx5_eswitch *esw,
61 int vport_index)
62{
63 return NULL;
64}
65#endif
66
67static inline
68struct mlx5_ib_dev *mlx5_ib_rep_to_dev(struct mlx5_eswitch_rep *rep)
69{
70 return (struct mlx5_ib_dev *)rep->rep_if[REP_IB].priv;
71}
72#endif /* __MLX5_IB_REP_H__ */
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
index da091de4e69d..390e4375647e 100644
--- a/drivers/infiniband/hw/mlx5/main.c
+++ b/drivers/infiniband/hw/mlx5/main.c
@@ -57,7 +57,9 @@
57#include <linux/in.h> 57#include <linux/in.h>
58#include <linux/etherdevice.h> 58#include <linux/etherdevice.h>
59#include "mlx5_ib.h" 59#include "mlx5_ib.h"
60#include "ib_rep.h"
60#include "cmd.h" 61#include "cmd.h"
62#include <linux/mlx5/fs_helpers.h>
61 63
62#define DRIVER_NAME "mlx5_ib" 64#define DRIVER_NAME "mlx5_ib"
63#define DRIVER_VERSION "5.0-0" 65#define DRIVER_VERSION "5.0-0"
@@ -130,7 +132,7 @@ static int get_port_state(struct ib_device *ibdev,
130 int ret; 132 int ret;
131 133
132 memset(&attr, 0, sizeof(attr)); 134 memset(&attr, 0, sizeof(attr));
133 ret = mlx5_ib_query_port(ibdev, port_num, &attr); 135 ret = ibdev->query_port(ibdev, port_num, &attr);
134 if (!ret) 136 if (!ret)
135 *state = attr.state; 137 *state = attr.state;
136 return ret; 138 return ret;
@@ -154,10 +156,19 @@ static int mlx5_netdev_event(struct notifier_block *this,
154 case NETDEV_REGISTER: 156 case NETDEV_REGISTER:
155 case NETDEV_UNREGISTER: 157 case NETDEV_UNREGISTER:
156 write_lock(&roce->netdev_lock); 158 write_lock(&roce->netdev_lock);
157 159 if (ibdev->rep) {
158 if (ndev->dev.parent == &mdev->pdev->dev) 160 struct mlx5_eswitch *esw = ibdev->mdev->priv.eswitch;
159 roce->netdev = (event == NETDEV_UNREGISTER) ? 161 struct net_device *rep_ndev;
162
163 rep_ndev = mlx5_ib_get_rep_netdev(esw,
164 ibdev->rep->vport);
165 if (rep_ndev == ndev)
166 roce->netdev = (event == NETDEV_UNREGISTER) ?
160 NULL : ndev; 167 NULL : ndev;
168 } else if (ndev->dev.parent == &ibdev->mdev->pdev->dev) {
169 roce->netdev = (event == NETDEV_UNREGISTER) ?
170 NULL : ndev;
171 }
161 write_unlock(&roce->netdev_lock); 172 write_unlock(&roce->netdev_lock);
162 break; 173 break;
163 174
@@ -1272,6 +1283,22 @@ int mlx5_ib_query_port(struct ib_device *ibdev, u8 port,
1272 return ret; 1283 return ret;
1273} 1284}
1274 1285
1286static int mlx5_ib_rep_query_port(struct ib_device *ibdev, u8 port,
1287 struct ib_port_attr *props)
1288{
1289 int ret;
1290
1291 /* Only link layer == ethernet is valid for representors */
1292 ret = mlx5_query_port_roce(ibdev, port, props);
1293 if (ret || !props)
1294 return ret;
1295
1296 /* We don't support GIDS */
1297 props->gid_tbl_len = 0;
1298
1299 return ret;
1300}
1301
1275static int mlx5_ib_query_gid(struct ib_device *ibdev, u8 port, int index, 1302static int mlx5_ib_query_gid(struct ib_device *ibdev, u8 port, int index,
1276 union ib_gid *gid) 1303 union ib_gid *gid)
1277{ 1304{
@@ -2290,11 +2317,9 @@ static void set_tos(void *outer_c, void *outer_v, u8 mask, u8 val)
2290 offsetof(typeof(filter), field) -\ 2317 offsetof(typeof(filter), field) -\
2291 sizeof(filter.field)) 2318 sizeof(filter.field))
2292 2319
2293#define IPV4_VERSION 4
2294#define IPV6_VERSION 6
2295static int parse_flow_attr(struct mlx5_core_dev *mdev, u32 *match_c, 2320static int parse_flow_attr(struct mlx5_core_dev *mdev, u32 *match_c,
2296 u32 *match_v, const union ib_flow_spec *ib_spec, 2321 u32 *match_v, const union ib_flow_spec *ib_spec,
2297 u32 *tag_id, bool *is_drop) 2322 struct mlx5_flow_act *action)
2298{ 2323{
2299 void *misc_params_c = MLX5_ADDR_OF(fte_match_param, match_c, 2324 void *misc_params_c = MLX5_ADDR_OF(fte_match_param, match_c,
2300 misc_parameters); 2325 misc_parameters);
@@ -2377,7 +2402,7 @@ static int parse_flow_attr(struct mlx5_core_dev *mdev, u32 *match_c,
2377 MLX5_SET(fte_match_set_lyr_2_4, headers_c, 2402 MLX5_SET(fte_match_set_lyr_2_4, headers_c,
2378 ip_version, 0xf); 2403 ip_version, 0xf);
2379 MLX5_SET(fte_match_set_lyr_2_4, headers_v, 2404 MLX5_SET(fte_match_set_lyr_2_4, headers_v,
2380 ip_version, IPV4_VERSION); 2405 ip_version, MLX5_FS_IPV4_VERSION);
2381 } else { 2406 } else {
2382 MLX5_SET(fte_match_set_lyr_2_4, headers_c, 2407 MLX5_SET(fte_match_set_lyr_2_4, headers_c,
2383 ethertype, 0xffff); 2408 ethertype, 0xffff);
@@ -2416,7 +2441,7 @@ static int parse_flow_attr(struct mlx5_core_dev *mdev, u32 *match_c,
2416 MLX5_SET(fte_match_set_lyr_2_4, headers_c, 2441 MLX5_SET(fte_match_set_lyr_2_4, headers_c,
2417 ip_version, 0xf); 2442 ip_version, 0xf);
2418 MLX5_SET(fte_match_set_lyr_2_4, headers_v, 2443 MLX5_SET(fte_match_set_lyr_2_4, headers_v,
2419 ip_version, IPV6_VERSION); 2444 ip_version, MLX5_FS_IPV6_VERSION);
2420 } else { 2445 } else {
2421 MLX5_SET(fte_match_set_lyr_2_4, headers_c, 2446 MLX5_SET(fte_match_set_lyr_2_4, headers_c,
2422 ethertype, 0xffff); 2447 ethertype, 0xffff);
@@ -2512,13 +2537,14 @@ static int parse_flow_attr(struct mlx5_core_dev *mdev, u32 *match_c,
2512 if (ib_spec->flow_tag.tag_id >= BIT(24)) 2537 if (ib_spec->flow_tag.tag_id >= BIT(24))
2513 return -EINVAL; 2538 return -EINVAL;
2514 2539
2515 *tag_id = ib_spec->flow_tag.tag_id; 2540 action->flow_tag = ib_spec->flow_tag.tag_id;
2541 action->has_flow_tag = true;
2516 break; 2542 break;
2517 case IB_FLOW_SPEC_ACTION_DROP: 2543 case IB_FLOW_SPEC_ACTION_DROP:
2518 if (FIELDS_NOT_SUPPORTED(ib_spec->drop, 2544 if (FIELDS_NOT_SUPPORTED(ib_spec->drop,
2519 LAST_DROP_FIELD)) 2545 LAST_DROP_FIELD))
2520 return -EOPNOTSUPP; 2546 return -EOPNOTSUPP;
2521 *is_drop = true; 2547 action->action |= MLX5_FLOW_CONTEXT_ACTION_DROP;
2522 break; 2548 break;
2523 default: 2549 default:
2524 return -EINVAL; 2550 return -EINVAL;
@@ -2635,7 +2661,7 @@ static int mlx5_ib_destroy_flow(struct ib_flow *flow_id)
2635 ibflow); 2661 ibflow);
2636 struct mlx5_ib_flow_handler *iter, *tmp; 2662 struct mlx5_ib_flow_handler *iter, *tmp;
2637 2663
2638 mutex_lock(&dev->flow_db.lock); 2664 mutex_lock(&dev->flow_db->lock);
2639 2665
2640 list_for_each_entry_safe(iter, tmp, &handler->list, list) { 2666 list_for_each_entry_safe(iter, tmp, &handler->list, list) {
2641 mlx5_del_flow_rules(iter->rule); 2667 mlx5_del_flow_rules(iter->rule);
@@ -2646,7 +2672,7 @@ static int mlx5_ib_destroy_flow(struct ib_flow *flow_id)
2646 2672
2647 mlx5_del_flow_rules(handler->rule); 2673 mlx5_del_flow_rules(handler->rule);
2648 put_flow_table(dev, handler->prio, true); 2674 put_flow_table(dev, handler->prio, true);
2649 mutex_unlock(&dev->flow_db.lock); 2675 mutex_unlock(&dev->flow_db->lock);
2650 2676
2651 kfree(handler); 2677 kfree(handler);
2652 2678
@@ -2695,7 +2721,7 @@ static struct mlx5_ib_flow_prio *get_flow_table(struct mlx5_ib_dev *dev,
2695 MLX5_FLOW_NAMESPACE_BYPASS); 2721 MLX5_FLOW_NAMESPACE_BYPASS);
2696 num_entries = MLX5_FS_MAX_ENTRIES; 2722 num_entries = MLX5_FS_MAX_ENTRIES;
2697 num_groups = MLX5_FS_MAX_TYPES; 2723 num_groups = MLX5_FS_MAX_TYPES;
2698 prio = &dev->flow_db.prios[priority]; 2724 prio = &dev->flow_db->prios[priority];
2699 } else if (flow_attr->type == IB_FLOW_ATTR_ALL_DEFAULT || 2725 } else if (flow_attr->type == IB_FLOW_ATTR_ALL_DEFAULT ||
2700 flow_attr->type == IB_FLOW_ATTR_MC_DEFAULT) { 2726 flow_attr->type == IB_FLOW_ATTR_MC_DEFAULT) {
2701 ns = mlx5_get_flow_namespace(dev->mdev, 2727 ns = mlx5_get_flow_namespace(dev->mdev,
@@ -2703,7 +2729,7 @@ static struct mlx5_ib_flow_prio *get_flow_table(struct mlx5_ib_dev *dev,
2703 build_leftovers_ft_param(&priority, 2729 build_leftovers_ft_param(&priority,
2704 &num_entries, 2730 &num_entries,
2705 &num_groups); 2731 &num_groups);
2706 prio = &dev->flow_db.prios[MLX5_IB_FLOW_LEFTOVERS_PRIO]; 2732 prio = &dev->flow_db->prios[MLX5_IB_FLOW_LEFTOVERS_PRIO];
2707 } else if (flow_attr->type == IB_FLOW_ATTR_SNIFFER) { 2733 } else if (flow_attr->type == IB_FLOW_ATTR_SNIFFER) {
2708 if (!MLX5_CAP_FLOWTABLE(dev->mdev, 2734 if (!MLX5_CAP_FLOWTABLE(dev->mdev,
2709 allow_sniffer_and_nic_rx_shared_tir)) 2735 allow_sniffer_and_nic_rx_shared_tir))
@@ -2713,7 +2739,7 @@ static struct mlx5_ib_flow_prio *get_flow_table(struct mlx5_ib_dev *dev,
2713 MLX5_FLOW_NAMESPACE_SNIFFER_RX : 2739 MLX5_FLOW_NAMESPACE_SNIFFER_RX :
2714 MLX5_FLOW_NAMESPACE_SNIFFER_TX); 2740 MLX5_FLOW_NAMESPACE_SNIFFER_TX);
2715 2741
2716 prio = &dev->flow_db.sniffer[ft_type]; 2742 prio = &dev->flow_db->sniffer[ft_type];
2717 priority = 0; 2743 priority = 0;
2718 num_entries = 1; 2744 num_entries = 1;
2719 num_groups = 1; 2745 num_groups = 1;
@@ -2771,13 +2797,11 @@ static struct mlx5_ib_flow_handler *_create_flow_rule(struct mlx5_ib_dev *dev,
2771{ 2797{
2772 struct mlx5_flow_table *ft = ft_prio->flow_table; 2798 struct mlx5_flow_table *ft = ft_prio->flow_table;
2773 struct mlx5_ib_flow_handler *handler; 2799 struct mlx5_ib_flow_handler *handler;
2774 struct mlx5_flow_act flow_act = {0}; 2800 struct mlx5_flow_act flow_act = {.flow_tag = MLX5_FS_DEFAULT_FLOW_TAG};
2775 struct mlx5_flow_spec *spec; 2801 struct mlx5_flow_spec *spec;
2776 struct mlx5_flow_destination *rule_dst = dst; 2802 struct mlx5_flow_destination *rule_dst = dst;
2777 const void *ib_flow = (const void *)flow_attr + sizeof(*flow_attr); 2803 const void *ib_flow = (const void *)flow_attr + sizeof(*flow_attr);
2778 unsigned int spec_index; 2804 unsigned int spec_index;
2779 u32 flow_tag = MLX5_FS_DEFAULT_FLOW_TAG;
2780 bool is_drop = false;
2781 int err = 0; 2805 int err = 0;
2782 int dest_num = 1; 2806 int dest_num = 1;
2783 2807
@@ -2796,7 +2820,7 @@ static struct mlx5_ib_flow_handler *_create_flow_rule(struct mlx5_ib_dev *dev,
2796 for (spec_index = 0; spec_index < flow_attr->num_of_specs; spec_index++) { 2820 for (spec_index = 0; spec_index < flow_attr->num_of_specs; spec_index++) {
2797 err = parse_flow_attr(dev->mdev, spec->match_criteria, 2821 err = parse_flow_attr(dev->mdev, spec->match_criteria,
2798 spec->match_value, 2822 spec->match_value,
2799 ib_flow, &flow_tag, &is_drop); 2823 ib_flow, &flow_act);
2800 if (err < 0) 2824 if (err < 0)
2801 goto free; 2825 goto free;
2802 2826
@@ -2806,9 +2830,20 @@ static struct mlx5_ib_flow_handler *_create_flow_rule(struct mlx5_ib_dev *dev,
2806 if (!flow_is_multicast_only(flow_attr)) 2830 if (!flow_is_multicast_only(flow_attr))
2807 set_underlay_qp(dev, spec, underlay_qpn); 2831 set_underlay_qp(dev, spec, underlay_qpn);
2808 2832
2833 if (dev->rep) {
2834 void *misc;
2835
2836 misc = MLX5_ADDR_OF(fte_match_param, spec->match_value,
2837 misc_parameters);
2838 MLX5_SET(fte_match_set_misc, misc, source_port,
2839 dev->rep->vport);
2840 misc = MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
2841 misc_parameters);
2842 MLX5_SET_TO_ONES(fte_match_set_misc, misc, source_port);
2843 }
2844
2809 spec->match_criteria_enable = get_match_criteria_enable(spec->match_criteria); 2845 spec->match_criteria_enable = get_match_criteria_enable(spec->match_criteria);
2810 if (is_drop) { 2846 if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_DROP) {
2811 flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP;
2812 rule_dst = NULL; 2847 rule_dst = NULL;
2813 dest_num = 0; 2848 dest_num = 0;
2814 } else { 2849 } else {
@@ -2816,15 +2851,14 @@ static struct mlx5_ib_flow_handler *_create_flow_rule(struct mlx5_ib_dev *dev,
2816 MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO; 2851 MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO;
2817 } 2852 }
2818 2853
2819 if (flow_tag != MLX5_FS_DEFAULT_FLOW_TAG && 2854 if (flow_act.has_flow_tag &&
2820 (flow_attr->type == IB_FLOW_ATTR_ALL_DEFAULT || 2855 (flow_attr->type == IB_FLOW_ATTR_ALL_DEFAULT ||
2821 flow_attr->type == IB_FLOW_ATTR_MC_DEFAULT)) { 2856 flow_attr->type == IB_FLOW_ATTR_MC_DEFAULT)) {
2822 mlx5_ib_warn(dev, "Flow tag %u and attribute type %x isn't allowed in leftovers\n", 2857 mlx5_ib_warn(dev, "Flow tag %u and attribute type %x isn't allowed in leftovers\n",
2823 flow_tag, flow_attr->type); 2858 flow_act.flow_tag, flow_attr->type);
2824 err = -EINVAL; 2859 err = -EINVAL;
2825 goto free; 2860 goto free;
2826 } 2861 }
2827 flow_act.flow_tag = flow_tag;
2828 handler->rule = mlx5_add_flow_rules(ft, spec, 2862 handler->rule = mlx5_add_flow_rules(ft, spec,
2829 &flow_act, 2863 &flow_act,
2830 rule_dst, dest_num); 2864 rule_dst, dest_num);
@@ -3003,7 +3037,7 @@ static struct ib_flow *mlx5_ib_create_flow(struct ib_qp *qp,
3003 if (!dst) 3037 if (!dst)
3004 return ERR_PTR(-ENOMEM); 3038 return ERR_PTR(-ENOMEM);
3005 3039
3006 mutex_lock(&dev->flow_db.lock); 3040 mutex_lock(&dev->flow_db->lock);
3007 3041
3008 ft_prio = get_flow_table(dev, flow_attr, MLX5_IB_FT_RX); 3042 ft_prio = get_flow_table(dev, flow_attr, MLX5_IB_FT_RX);
3009 if (IS_ERR(ft_prio)) { 3043 if (IS_ERR(ft_prio)) {
@@ -3052,7 +3086,7 @@ static struct ib_flow *mlx5_ib_create_flow(struct ib_qp *qp,
3052 goto destroy_ft; 3086 goto destroy_ft;
3053 } 3087 }
3054 3088
3055 mutex_unlock(&dev->flow_db.lock); 3089 mutex_unlock(&dev->flow_db->lock);
3056 kfree(dst); 3090 kfree(dst);
3057 3091
3058 return &handler->ibflow; 3092 return &handler->ibflow;
@@ -3062,7 +3096,7 @@ destroy_ft:
3062 if (ft_prio_tx) 3096 if (ft_prio_tx)
3063 put_flow_table(dev, ft_prio_tx, false); 3097 put_flow_table(dev, ft_prio_tx, false);
3064unlock: 3098unlock:
3065 mutex_unlock(&dev->flow_db.lock); 3099 mutex_unlock(&dev->flow_db->lock);
3066 kfree(dst); 3100 kfree(dst);
3067 kfree(handler); 3101 kfree(handler);
3068 return ERR_PTR(err); 3102 return ERR_PTR(err);
@@ -3769,6 +3803,25 @@ static int mlx5_port_immutable(struct ib_device *ibdev, u8 port_num,
3769 return 0; 3803 return 0;
3770} 3804}
3771 3805
3806static int mlx5_port_rep_immutable(struct ib_device *ibdev, u8 port_num,
3807 struct ib_port_immutable *immutable)
3808{
3809 struct ib_port_attr attr;
3810 int err;
3811
3812 immutable->core_cap_flags = RDMA_CORE_PORT_RAW_PACKET;
3813
3814 err = ib_query_port(ibdev, port_num, &attr);
3815 if (err)
3816 return err;
3817
3818 immutable->pkey_tbl_len = attr.pkey_tbl_len;
3819 immutable->gid_tbl_len = attr.gid_tbl_len;
3820 immutable->core_cap_flags = RDMA_CORE_PORT_RAW_PACKET;
3821
3822 return 0;
3823}
3824
3772static void get_dev_fw_str(struct ib_device *ibdev, char *str) 3825static void get_dev_fw_str(struct ib_device *ibdev, char *str)
3773{ 3826{
3774 struct mlx5_ib_dev *dev = 3827 struct mlx5_ib_dev *dev =
@@ -3799,7 +3852,7 @@ static int mlx5_eth_lag_init(struct mlx5_ib_dev *dev)
3799 goto err_destroy_vport_lag; 3852 goto err_destroy_vport_lag;
3800 } 3853 }
3801 3854
3802 dev->flow_db.lag_demux_ft = ft; 3855 dev->flow_db->lag_demux_ft = ft;
3803 return 0; 3856 return 0;
3804 3857
3805err_destroy_vport_lag: 3858err_destroy_vport_lag:
@@ -3811,9 +3864,9 @@ static void mlx5_eth_lag_cleanup(struct mlx5_ib_dev *dev)
3811{ 3864{
3812 struct mlx5_core_dev *mdev = dev->mdev; 3865 struct mlx5_core_dev *mdev = dev->mdev;
3813 3866
3814 if (dev->flow_db.lag_demux_ft) { 3867 if (dev->flow_db->lag_demux_ft) {
3815 mlx5_destroy_flow_table(dev->flow_db.lag_demux_ft); 3868 mlx5_destroy_flow_table(dev->flow_db->lag_demux_ft);
3816 dev->flow_db.lag_demux_ft = NULL; 3869 dev->flow_db->lag_demux_ft = NULL;
3817 3870
3818 mlx5_cmd_destroy_vport_lag(mdev); 3871 mlx5_cmd_destroy_vport_lag(mdev);
3819 } 3872 }
@@ -3845,14 +3898,10 @@ static int mlx5_enable_eth(struct mlx5_ib_dev *dev, u8 port_num)
3845{ 3898{
3846 int err; 3899 int err;
3847 3900
3848 err = mlx5_add_netdev_notifier(dev, port_num);
3849 if (err)
3850 return err;
3851
3852 if (MLX5_CAP_GEN(dev->mdev, roce)) { 3901 if (MLX5_CAP_GEN(dev->mdev, roce)) {
3853 err = mlx5_nic_vport_enable_roce(dev->mdev); 3902 err = mlx5_nic_vport_enable_roce(dev->mdev);
3854 if (err) 3903 if (err)
3855 goto err_unregister_netdevice_notifier; 3904 return err;
3856 } 3905 }
3857 3906
3858 err = mlx5_eth_lag_init(dev); 3907 err = mlx5_eth_lag_init(dev);
@@ -3865,8 +3914,6 @@ err_disable_roce:
3865 if (MLX5_CAP_GEN(dev->mdev, roce)) 3914 if (MLX5_CAP_GEN(dev->mdev, roce))
3866 mlx5_nic_vport_disable_roce(dev->mdev); 3915 mlx5_nic_vport_disable_roce(dev->mdev);
3867 3916
3868err_unregister_netdevice_notifier:
3869 mlx5_remove_netdev_notifier(dev, port_num);
3870 return err; 3917 return err;
3871} 3918}
3872 3919
@@ -4500,7 +4547,7 @@ static void mlx5_ib_cleanup_multiport_master(struct mlx5_ib_dev *dev)
4500 mlx5_nic_vport_disable_roce(dev->mdev); 4547 mlx5_nic_vport_disable_roce(dev->mdev);
4501} 4548}
4502 4549
4503static void mlx5_ib_stage_init_cleanup(struct mlx5_ib_dev *dev) 4550void mlx5_ib_stage_init_cleanup(struct mlx5_ib_dev *dev)
4504{ 4551{
4505 mlx5_ib_cleanup_multiport_master(dev); 4552 mlx5_ib_cleanup_multiport_master(dev);
4506#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING 4553#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING
@@ -4509,7 +4556,7 @@ static void mlx5_ib_stage_init_cleanup(struct mlx5_ib_dev *dev)
4509 kfree(dev->port); 4556 kfree(dev->port);
4510} 4557}
4511 4558
4512static int mlx5_ib_stage_init_init(struct mlx5_ib_dev *dev) 4559int mlx5_ib_stage_init_init(struct mlx5_ib_dev *dev)
4513{ 4560{
4514 struct mlx5_core_dev *mdev = dev->mdev; 4561 struct mlx5_core_dev *mdev = dev->mdev;
4515 const char *name; 4562 const char *name;
@@ -4531,8 +4578,6 @@ static int mlx5_ib_stage_init_init(struct mlx5_ib_dev *dev)
4531 goto err_free_port; 4578 goto err_free_port;
4532 4579
4533 if (!mlx5_core_mp_enabled(mdev)) { 4580 if (!mlx5_core_mp_enabled(mdev)) {
4534 int i;
4535
4536 for (i = 1; i <= dev->num_ports; i++) { 4581 for (i = 1; i <= dev->num_ports; i++) {
4537 err = get_port_caps(dev, i); 4582 err = get_port_caps(dev, i);
4538 if (err) 4583 if (err)
@@ -4561,7 +4606,6 @@ static int mlx5_ib_stage_init_init(struct mlx5_ib_dev *dev)
4561 dev->mdev->priv.eq_table.num_comp_vectors; 4606 dev->mdev->priv.eq_table.num_comp_vectors;
4562 dev->ib_dev.dev.parent = &mdev->pdev->dev; 4607 dev->ib_dev.dev.parent = &mdev->pdev->dev;
4563 4608
4564 mutex_init(&dev->flow_db.lock);
4565 mutex_init(&dev->cap_mask_mutex); 4609 mutex_init(&dev->cap_mask_mutex);
4566 INIT_LIST_HEAD(&dev->qp_list); 4610 INIT_LIST_HEAD(&dev->qp_list);
4567 spin_lock_init(&dev->reset_flow_resource_lock); 4611 spin_lock_init(&dev->reset_flow_resource_lock);
@@ -4582,7 +4626,38 @@ err_free_port:
4582 return -ENOMEM; 4626 return -ENOMEM;
4583} 4627}
4584 4628
4585static int mlx5_ib_stage_caps_init(struct mlx5_ib_dev *dev) 4629static int mlx5_ib_stage_flow_db_init(struct mlx5_ib_dev *dev)
4630{
4631 dev->flow_db = kzalloc(sizeof(*dev->flow_db), GFP_KERNEL);
4632
4633 if (!dev->flow_db)
4634 return -ENOMEM;
4635
4636 mutex_init(&dev->flow_db->lock);
4637
4638 return 0;
4639}
4640
4641int mlx5_ib_stage_rep_flow_db_init(struct mlx5_ib_dev *dev)
4642{
4643 struct mlx5_ib_dev *nic_dev;
4644
4645 nic_dev = mlx5_ib_get_uplink_ibdev(dev->mdev->priv.eswitch);
4646
4647 if (!nic_dev)
4648 return -EINVAL;
4649
4650 dev->flow_db = nic_dev->flow_db;
4651
4652 return 0;
4653}
4654
4655static void mlx5_ib_stage_flow_db_cleanup(struct mlx5_ib_dev *dev)
4656{
4657 kfree(dev->flow_db);
4658}
4659
4660int mlx5_ib_stage_caps_init(struct mlx5_ib_dev *dev)
4586{ 4661{
4587 struct mlx5_core_dev *mdev = dev->mdev; 4662 struct mlx5_core_dev *mdev = dev->mdev;
4588 int err; 4663 int err;
@@ -4623,7 +4698,6 @@ static int mlx5_ib_stage_caps_init(struct mlx5_ib_dev *dev)
4623 (1ull << IB_USER_VERBS_EX_CMD_MODIFY_CQ); 4698 (1ull << IB_USER_VERBS_EX_CMD_MODIFY_CQ);
4624 4699
4625 dev->ib_dev.query_device = mlx5_ib_query_device; 4700 dev->ib_dev.query_device = mlx5_ib_query_device;
4626 dev->ib_dev.query_port = mlx5_ib_query_port;
4627 dev->ib_dev.get_link_layer = mlx5_ib_port_link_layer; 4701 dev->ib_dev.get_link_layer = mlx5_ib_port_link_layer;
4628 dev->ib_dev.query_gid = mlx5_ib_query_gid; 4702 dev->ib_dev.query_gid = mlx5_ib_query_gid;
4629 dev->ib_dev.add_gid = mlx5_ib_add_gid; 4703 dev->ib_dev.add_gid = mlx5_ib_add_gid;
@@ -4666,7 +4740,6 @@ static int mlx5_ib_stage_caps_init(struct mlx5_ib_dev *dev)
4666 dev->ib_dev.alloc_mr = mlx5_ib_alloc_mr; 4740 dev->ib_dev.alloc_mr = mlx5_ib_alloc_mr;
4667 dev->ib_dev.map_mr_sg = mlx5_ib_map_mr_sg; 4741 dev->ib_dev.map_mr_sg = mlx5_ib_map_mr_sg;
4668 dev->ib_dev.check_mr_status = mlx5_ib_check_mr_status; 4742 dev->ib_dev.check_mr_status = mlx5_ib_check_mr_status;
4669 dev->ib_dev.get_port_immutable = mlx5_port_immutable;
4670 dev->ib_dev.get_dev_fw_str = get_dev_fw_str; 4743 dev->ib_dev.get_dev_fw_str = get_dev_fw_str;
4671 dev->ib_dev.get_vector_affinity = mlx5_ib_get_vector_affinity; 4744 dev->ib_dev.get_vector_affinity = mlx5_ib_get_vector_affinity;
4672 if (MLX5_CAP_GEN(mdev, ipoib_enhanced_offloads)) 4745 if (MLX5_CAP_GEN(mdev, ipoib_enhanced_offloads))
@@ -4717,6 +4790,80 @@ static int mlx5_ib_stage_caps_init(struct mlx5_ib_dev *dev)
4717 return 0; 4790 return 0;
4718} 4791}
4719 4792
4793static int mlx5_ib_stage_non_default_cb(struct mlx5_ib_dev *dev)
4794{
4795 dev->ib_dev.get_port_immutable = mlx5_port_immutable;
4796 dev->ib_dev.query_port = mlx5_ib_query_port;
4797
4798 return 0;
4799}
4800
4801int mlx5_ib_stage_rep_non_default_cb(struct mlx5_ib_dev *dev)
4802{
4803 dev->ib_dev.get_port_immutable = mlx5_port_rep_immutable;
4804 dev->ib_dev.query_port = mlx5_ib_rep_query_port;
4805
4806 return 0;
4807}
4808
4809static int mlx5_ib_stage_common_roce_init(struct mlx5_ib_dev *dev,
4810 u8 port_num)
4811{
4812 int i;
4813
4814 for (i = 0; i < dev->num_ports; i++) {
4815 dev->roce[i].dev = dev;
4816 dev->roce[i].native_port_num = i + 1;
4817 dev->roce[i].last_port_state = IB_PORT_DOWN;
4818 }
4819
4820 dev->ib_dev.get_netdev = mlx5_ib_get_netdev;
4821 dev->ib_dev.create_wq = mlx5_ib_create_wq;
4822 dev->ib_dev.modify_wq = mlx5_ib_modify_wq;
4823 dev->ib_dev.destroy_wq = mlx5_ib_destroy_wq;
4824 dev->ib_dev.create_rwq_ind_table = mlx5_ib_create_rwq_ind_table;
4825 dev->ib_dev.destroy_rwq_ind_table = mlx5_ib_destroy_rwq_ind_table;
4826
4827 dev->ib_dev.uverbs_ex_cmd_mask |=
4828 (1ull << IB_USER_VERBS_EX_CMD_CREATE_WQ) |
4829 (1ull << IB_USER_VERBS_EX_CMD_MODIFY_WQ) |
4830 (1ull << IB_USER_VERBS_EX_CMD_DESTROY_WQ) |
4831 (1ull << IB_USER_VERBS_EX_CMD_CREATE_RWQ_IND_TBL) |
4832 (1ull << IB_USER_VERBS_EX_CMD_DESTROY_RWQ_IND_TBL);
4833
4834 return mlx5_add_netdev_notifier(dev, port_num);
4835}
4836
4837static void mlx5_ib_stage_common_roce_cleanup(struct mlx5_ib_dev *dev)
4838{
4839 u8 port_num = mlx5_core_native_port_num(dev->mdev) - 1;
4840
4841 mlx5_remove_netdev_notifier(dev, port_num);
4842}
4843
4844int mlx5_ib_stage_rep_roce_init(struct mlx5_ib_dev *dev)
4845{
4846 struct mlx5_core_dev *mdev = dev->mdev;
4847 enum rdma_link_layer ll;
4848 int port_type_cap;
4849 int err = 0;
4850 u8 port_num;
4851
4852 port_num = mlx5_core_native_port_num(dev->mdev) - 1;
4853 port_type_cap = MLX5_CAP_GEN(mdev, port_type);
4854 ll = mlx5_port_type_cap_to_rdma_ll(port_type_cap);
4855
4856 if (ll == IB_LINK_LAYER_ETHERNET)
4857 err = mlx5_ib_stage_common_roce_init(dev, port_num);
4858
4859 return err;
4860}
4861
4862void mlx5_ib_stage_rep_roce_cleanup(struct mlx5_ib_dev *dev)
4863{
4864 mlx5_ib_stage_common_roce_cleanup(dev);
4865}
4866
4720static int mlx5_ib_stage_roce_init(struct mlx5_ib_dev *dev) 4867static int mlx5_ib_stage_roce_init(struct mlx5_ib_dev *dev)
4721{ 4868{
4722 struct mlx5_core_dev *mdev = dev->mdev; 4869 struct mlx5_core_dev *mdev = dev->mdev;
@@ -4724,37 +4871,26 @@ static int mlx5_ib_stage_roce_init(struct mlx5_ib_dev *dev)
4724 int port_type_cap; 4871 int port_type_cap;
4725 u8 port_num; 4872 u8 port_num;
4726 int err; 4873 int err;
4727 int i;
4728 4874
4729 port_num = mlx5_core_native_port_num(dev->mdev) - 1; 4875 port_num = mlx5_core_native_port_num(dev->mdev) - 1;
4730 port_type_cap = MLX5_CAP_GEN(mdev, port_type); 4876 port_type_cap = MLX5_CAP_GEN(mdev, port_type);
4731 ll = mlx5_port_type_cap_to_rdma_ll(port_type_cap); 4877 ll = mlx5_port_type_cap_to_rdma_ll(port_type_cap);
4732 4878
4733 if (ll == IB_LINK_LAYER_ETHERNET) { 4879 if (ll == IB_LINK_LAYER_ETHERNET) {
4734 for (i = 0; i < dev->num_ports; i++) { 4880 err = mlx5_ib_stage_common_roce_init(dev, port_num);
4735 dev->roce[i].dev = dev; 4881 if (err)
4736 dev->roce[i].native_port_num = i + 1; 4882 return err;
4737 dev->roce[i].last_port_state = IB_PORT_DOWN;
4738 }
4739 4883
4740 dev->ib_dev.get_netdev = mlx5_ib_get_netdev;
4741 dev->ib_dev.create_wq = mlx5_ib_create_wq;
4742 dev->ib_dev.modify_wq = mlx5_ib_modify_wq;
4743 dev->ib_dev.destroy_wq = mlx5_ib_destroy_wq;
4744 dev->ib_dev.create_rwq_ind_table = mlx5_ib_create_rwq_ind_table;
4745 dev->ib_dev.destroy_rwq_ind_table = mlx5_ib_destroy_rwq_ind_table;
4746 dev->ib_dev.uverbs_ex_cmd_mask |=
4747 (1ull << IB_USER_VERBS_EX_CMD_CREATE_WQ) |
4748 (1ull << IB_USER_VERBS_EX_CMD_MODIFY_WQ) |
4749 (1ull << IB_USER_VERBS_EX_CMD_DESTROY_WQ) |
4750 (1ull << IB_USER_VERBS_EX_CMD_CREATE_RWQ_IND_TBL) |
4751 (1ull << IB_USER_VERBS_EX_CMD_DESTROY_RWQ_IND_TBL);
4752 err = mlx5_enable_eth(dev, port_num); 4884 err = mlx5_enable_eth(dev, port_num);
4753 if (err) 4885 if (err)
4754 return err; 4886 goto cleanup;
4755 } 4887 }
4756 4888
4757 return 0; 4889 return 0;
4890cleanup:
4891 mlx5_ib_stage_common_roce_cleanup(dev);
4892
4893 return err;
4758} 4894}
4759 4895
4760static void mlx5_ib_stage_roce_cleanup(struct mlx5_ib_dev *dev) 4896static void mlx5_ib_stage_roce_cleanup(struct mlx5_ib_dev *dev)
@@ -4770,16 +4906,16 @@ static void mlx5_ib_stage_roce_cleanup(struct mlx5_ib_dev *dev)
4770 4906
4771 if (ll == IB_LINK_LAYER_ETHERNET) { 4907 if (ll == IB_LINK_LAYER_ETHERNET) {
4772 mlx5_disable_eth(dev); 4908 mlx5_disable_eth(dev);
4773 mlx5_remove_netdev_notifier(dev, port_num); 4909 mlx5_ib_stage_common_roce_cleanup(dev);
4774 } 4910 }
4775} 4911}
4776 4912
4777static int mlx5_ib_stage_dev_res_init(struct mlx5_ib_dev *dev) 4913int mlx5_ib_stage_dev_res_init(struct mlx5_ib_dev *dev)
4778{ 4914{
4779 return create_dev_resources(&dev->devr); 4915 return create_dev_resources(&dev->devr);
4780} 4916}
4781 4917
4782static void mlx5_ib_stage_dev_res_cleanup(struct mlx5_ib_dev *dev) 4918void mlx5_ib_stage_dev_res_cleanup(struct mlx5_ib_dev *dev)
4783{ 4919{
4784 destroy_dev_resources(&dev->devr); 4920 destroy_dev_resources(&dev->devr);
4785} 4921}
@@ -4791,7 +4927,7 @@ static int mlx5_ib_stage_odp_init(struct mlx5_ib_dev *dev)
4791 return mlx5_ib_odp_init_one(dev); 4927 return mlx5_ib_odp_init_one(dev);
4792} 4928}
4793 4929
4794static int mlx5_ib_stage_counters_init(struct mlx5_ib_dev *dev) 4930int mlx5_ib_stage_counters_init(struct mlx5_ib_dev *dev)
4795{ 4931{
4796 if (MLX5_CAP_GEN(dev->mdev, max_qp_cnt)) { 4932 if (MLX5_CAP_GEN(dev->mdev, max_qp_cnt)) {
4797 dev->ib_dev.get_hw_stats = mlx5_ib_get_hw_stats; 4933 dev->ib_dev.get_hw_stats = mlx5_ib_get_hw_stats;
@@ -4803,7 +4939,7 @@ static int mlx5_ib_stage_counters_init(struct mlx5_ib_dev *dev)
4803 return 0; 4939 return 0;
4804} 4940}
4805 4941
4806static void mlx5_ib_stage_counters_cleanup(struct mlx5_ib_dev *dev) 4942void mlx5_ib_stage_counters_cleanup(struct mlx5_ib_dev *dev)
4807{ 4943{
4808 if (MLX5_CAP_GEN(dev->mdev, max_qp_cnt)) 4944 if (MLX5_CAP_GEN(dev->mdev, max_qp_cnt))
4809 mlx5_ib_dealloc_counters(dev); 4945 mlx5_ib_dealloc_counters(dev);
@@ -4834,7 +4970,7 @@ static void mlx5_ib_stage_uar_cleanup(struct mlx5_ib_dev *dev)
4834 mlx5_put_uars_page(dev->mdev, dev->mdev->priv.uar); 4970 mlx5_put_uars_page(dev->mdev, dev->mdev->priv.uar);
4835} 4971}
4836 4972
4837static int mlx5_ib_stage_bfrag_init(struct mlx5_ib_dev *dev) 4973int mlx5_ib_stage_bfrag_init(struct mlx5_ib_dev *dev)
4838{ 4974{
4839 int err; 4975 int err;
4840 4976
@@ -4849,28 +4985,28 @@ static int mlx5_ib_stage_bfrag_init(struct mlx5_ib_dev *dev)
4849 return err; 4985 return err;
4850} 4986}
4851 4987
4852static void mlx5_ib_stage_bfrag_cleanup(struct mlx5_ib_dev *dev) 4988void mlx5_ib_stage_bfrag_cleanup(struct mlx5_ib_dev *dev)
4853{ 4989{
4854 mlx5_free_bfreg(dev->mdev, &dev->fp_bfreg); 4990 mlx5_free_bfreg(dev->mdev, &dev->fp_bfreg);
4855 mlx5_free_bfreg(dev->mdev, &dev->bfreg); 4991 mlx5_free_bfreg(dev->mdev, &dev->bfreg);
4856} 4992}
4857 4993
4858static int mlx5_ib_stage_ib_reg_init(struct mlx5_ib_dev *dev) 4994int mlx5_ib_stage_ib_reg_init(struct mlx5_ib_dev *dev)
4859{ 4995{
4860 return ib_register_device(&dev->ib_dev, NULL); 4996 return ib_register_device(&dev->ib_dev, NULL);
4861} 4997}
4862 4998
4863static void mlx5_ib_stage_pre_ib_reg_umr_cleanup(struct mlx5_ib_dev *dev) 4999void mlx5_ib_stage_pre_ib_reg_umr_cleanup(struct mlx5_ib_dev *dev)
4864{ 5000{
4865 destroy_umrc_res(dev); 5001 destroy_umrc_res(dev);
4866} 5002}
4867 5003
4868static void mlx5_ib_stage_ib_reg_cleanup(struct mlx5_ib_dev *dev) 5004void mlx5_ib_stage_ib_reg_cleanup(struct mlx5_ib_dev *dev)
4869{ 5005{
4870 ib_unregister_device(&dev->ib_dev); 5006 ib_unregister_device(&dev->ib_dev);
4871} 5007}
4872 5008
4873static int mlx5_ib_stage_post_ib_reg_umr_init(struct mlx5_ib_dev *dev) 5009int mlx5_ib_stage_post_ib_reg_umr_init(struct mlx5_ib_dev *dev)
4874{ 5010{
4875 return create_umr_res(dev); 5011 return create_umr_res(dev);
4876} 5012}
@@ -4887,7 +5023,7 @@ static void mlx5_ib_stage_delay_drop_cleanup(struct mlx5_ib_dev *dev)
4887 cancel_delay_drop(dev); 5023 cancel_delay_drop(dev);
4888} 5024}
4889 5025
4890static int mlx5_ib_stage_class_attr_init(struct mlx5_ib_dev *dev) 5026int mlx5_ib_stage_class_attr_init(struct mlx5_ib_dev *dev)
4891{ 5027{
4892 int err; 5028 int err;
4893 int i; 5029 int i;
@@ -4902,9 +5038,21 @@ static int mlx5_ib_stage_class_attr_init(struct mlx5_ib_dev *dev)
4902 return 0; 5038 return 0;
4903} 5039}
4904 5040
4905static void __mlx5_ib_remove(struct mlx5_ib_dev *dev, 5041static int mlx5_ib_stage_rep_reg_init(struct mlx5_ib_dev *dev)
4906 const struct mlx5_ib_profile *profile, 5042{
4907 int stage) 5043 mlx5_ib_register_vport_reps(dev);
5044
5045 return 0;
5046}
5047
5048static void mlx5_ib_stage_rep_reg_cleanup(struct mlx5_ib_dev *dev)
5049{
5050 mlx5_ib_unregister_vport_reps(dev);
5051}
5052
5053void __mlx5_ib_remove(struct mlx5_ib_dev *dev,
5054 const struct mlx5_ib_profile *profile,
5055 int stage)
4908{ 5056{
4909 /* Number of stages to cleanup */ 5057 /* Number of stages to cleanup */
4910 while (stage) { 5058 while (stage) {
@@ -4918,23 +5066,14 @@ static void __mlx5_ib_remove(struct mlx5_ib_dev *dev,
4918 5066
4919static void *mlx5_ib_add_slave_port(struct mlx5_core_dev *mdev, u8 port_num); 5067static void *mlx5_ib_add_slave_port(struct mlx5_core_dev *mdev, u8 port_num);
4920 5068
4921static void *__mlx5_ib_add(struct mlx5_core_dev *mdev, 5069void *__mlx5_ib_add(struct mlx5_ib_dev *dev,
4922 const struct mlx5_ib_profile *profile) 5070 const struct mlx5_ib_profile *profile)
4923{ 5071{
4924 struct mlx5_ib_dev *dev;
4925 int err; 5072 int err;
4926 int i; 5073 int i;
4927 5074
4928 printk_once(KERN_INFO "%s", mlx5_version); 5075 printk_once(KERN_INFO "%s", mlx5_version);
4929 5076
4930 dev = (struct mlx5_ib_dev *)ib_alloc_device(sizeof(*dev));
4931 if (!dev)
4932 return NULL;
4933
4934 dev->mdev = mdev;
4935 dev->num_ports = max(MLX5_CAP_GEN(mdev, num_ports),
4936 MLX5_CAP_GEN(mdev, num_vhca_ports));
4937
4938 for (i = 0; i < MLX5_IB_STAGE_MAX; i++) { 5077 for (i = 0; i < MLX5_IB_STAGE_MAX; i++) {
4939 if (profile->stage[i].init) { 5078 if (profile->stage[i].init) {
4940 err = profile->stage[i].init(dev); 5079 err = profile->stage[i].init(dev);
@@ -4958,9 +5097,15 @@ static const struct mlx5_ib_profile pf_profile = {
4958 STAGE_CREATE(MLX5_IB_STAGE_INIT, 5097 STAGE_CREATE(MLX5_IB_STAGE_INIT,
4959 mlx5_ib_stage_init_init, 5098 mlx5_ib_stage_init_init,
4960 mlx5_ib_stage_init_cleanup), 5099 mlx5_ib_stage_init_cleanup),
5100 STAGE_CREATE(MLX5_IB_STAGE_FLOW_DB,
5101 mlx5_ib_stage_flow_db_init,
5102 mlx5_ib_stage_flow_db_cleanup),
4961 STAGE_CREATE(MLX5_IB_STAGE_CAPS, 5103 STAGE_CREATE(MLX5_IB_STAGE_CAPS,
4962 mlx5_ib_stage_caps_init, 5104 mlx5_ib_stage_caps_init,
4963 NULL), 5105 NULL),
5106 STAGE_CREATE(MLX5_IB_STAGE_NON_DEFAULT_CB,
5107 mlx5_ib_stage_non_default_cb,
5108 NULL),
4964 STAGE_CREATE(MLX5_IB_STAGE_ROCE, 5109 STAGE_CREATE(MLX5_IB_STAGE_ROCE,
4965 mlx5_ib_stage_roce_init, 5110 mlx5_ib_stage_roce_init,
4966 mlx5_ib_stage_roce_cleanup), 5111 mlx5_ib_stage_roce_cleanup),
@@ -4999,6 +5144,51 @@ static const struct mlx5_ib_profile pf_profile = {
4999 NULL), 5144 NULL),
5000}; 5145};
5001 5146
5147static const struct mlx5_ib_profile nic_rep_profile = {
5148 STAGE_CREATE(MLX5_IB_STAGE_INIT,
5149 mlx5_ib_stage_init_init,
5150 mlx5_ib_stage_init_cleanup),
5151 STAGE_CREATE(MLX5_IB_STAGE_FLOW_DB,
5152 mlx5_ib_stage_flow_db_init,
5153 mlx5_ib_stage_flow_db_cleanup),
5154 STAGE_CREATE(MLX5_IB_STAGE_CAPS,
5155 mlx5_ib_stage_caps_init,
5156 NULL),
5157 STAGE_CREATE(MLX5_IB_STAGE_NON_DEFAULT_CB,
5158 mlx5_ib_stage_rep_non_default_cb,
5159 NULL),
5160 STAGE_CREATE(MLX5_IB_STAGE_ROCE,
5161 mlx5_ib_stage_rep_roce_init,
5162 mlx5_ib_stage_rep_roce_cleanup),
5163 STAGE_CREATE(MLX5_IB_STAGE_DEVICE_RESOURCES,
5164 mlx5_ib_stage_dev_res_init,
5165 mlx5_ib_stage_dev_res_cleanup),
5166 STAGE_CREATE(MLX5_IB_STAGE_COUNTERS,
5167 mlx5_ib_stage_counters_init,
5168 mlx5_ib_stage_counters_cleanup),
5169 STAGE_CREATE(MLX5_IB_STAGE_UAR,
5170 mlx5_ib_stage_uar_init,
5171 mlx5_ib_stage_uar_cleanup),
5172 STAGE_CREATE(MLX5_IB_STAGE_BFREG,
5173 mlx5_ib_stage_bfrag_init,
5174 mlx5_ib_stage_bfrag_cleanup),
5175 STAGE_CREATE(MLX5_IB_STAGE_PRE_IB_REG_UMR,
5176 NULL,
5177 mlx5_ib_stage_pre_ib_reg_umr_cleanup),
5178 STAGE_CREATE(MLX5_IB_STAGE_IB_REG,
5179 mlx5_ib_stage_ib_reg_init,
5180 mlx5_ib_stage_ib_reg_cleanup),
5181 STAGE_CREATE(MLX5_IB_STAGE_POST_IB_REG_UMR,
5182 mlx5_ib_stage_post_ib_reg_umr_init,
5183 NULL),
5184 STAGE_CREATE(MLX5_IB_STAGE_CLASS_ATTR,
5185 mlx5_ib_stage_class_attr_init,
5186 NULL),
5187 STAGE_CREATE(MLX5_IB_STAGE_REP_REG,
5188 mlx5_ib_stage_rep_reg_init,
5189 mlx5_ib_stage_rep_reg_cleanup),
5190};
5191
5002static void *mlx5_ib_add_slave_port(struct mlx5_core_dev *mdev, u8 port_num) 5192static void *mlx5_ib_add_slave_port(struct mlx5_core_dev *mdev, u8 port_num)
5003{ 5193{
5004 struct mlx5_ib_multiport_info *mpi; 5194 struct mlx5_ib_multiport_info *mpi;
@@ -5044,8 +5234,11 @@ static void *mlx5_ib_add_slave_port(struct mlx5_core_dev *mdev, u8 port_num)
5044static void *mlx5_ib_add(struct mlx5_core_dev *mdev) 5234static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
5045{ 5235{
5046 enum rdma_link_layer ll; 5236 enum rdma_link_layer ll;
5237 struct mlx5_ib_dev *dev;
5047 int port_type_cap; 5238 int port_type_cap;
5048 5239
5240 printk_once(KERN_INFO "%s", mlx5_version);
5241
5049 port_type_cap = MLX5_CAP_GEN(mdev, port_type); 5242 port_type_cap = MLX5_CAP_GEN(mdev, port_type);
5050 ll = mlx5_port_type_cap_to_rdma_ll(port_type_cap); 5243 ll = mlx5_port_type_cap_to_rdma_ll(port_type_cap);
5051 5244
@@ -5055,7 +5248,22 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
5055 return mlx5_ib_add_slave_port(mdev, port_num); 5248 return mlx5_ib_add_slave_port(mdev, port_num);
5056 } 5249 }
5057 5250
5058 return __mlx5_ib_add(mdev, &pf_profile); 5251 dev = (struct mlx5_ib_dev *)ib_alloc_device(sizeof(*dev));
5252 if (!dev)
5253 return NULL;
5254
5255 dev->mdev = mdev;
5256 dev->num_ports = max(MLX5_CAP_GEN(mdev, num_ports),
5257 MLX5_CAP_GEN(mdev, num_vhca_ports));
5258
5259 if (MLX5_VPORT_MANAGER(mdev) &&
5260 mlx5_ib_eswitch_mode(mdev->priv.eswitch) == SRIOV_OFFLOADS) {
5261 dev->rep = mlx5_ib_vport_rep(mdev->priv.eswitch, 0);
5262
5263 return __mlx5_ib_add(dev, &nic_rep_profile);
5264 }
5265
5266 return __mlx5_ib_add(dev, &pf_profile);
5059} 5267}
5060 5268
5061static void mlx5_ib_remove(struct mlx5_core_dev *mdev, void *context) 5269static void mlx5_ib_remove(struct mlx5_core_dev *mdev, void *context)
diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h
index a5272499b600..c33bf1523d67 100644
--- a/drivers/infiniband/hw/mlx5/mlx5_ib.h
+++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h
@@ -343,6 +343,7 @@ struct mlx5_ib_sq {
343 struct mlx5_ib_wq *sq; 343 struct mlx5_ib_wq *sq;
344 struct mlx5_ib_ubuffer ubuffer; 344 struct mlx5_ib_ubuffer ubuffer;
345 struct mlx5_db *doorbell; 345 struct mlx5_db *doorbell;
346 struct mlx5_flow_handle *flow_rule;
346 u32 tisn; 347 u32 tisn;
347 u8 state; 348 u8 state;
348}; 349};
@@ -371,7 +372,7 @@ struct mlx5_ib_qp {
371 struct mlx5_ib_rss_qp rss_qp; 372 struct mlx5_ib_rss_qp rss_qp;
372 struct mlx5_ib_dct dct; 373 struct mlx5_ib_dct dct;
373 }; 374 };
374 struct mlx5_buf buf; 375 struct mlx5_frag_buf buf;
375 376
376 struct mlx5_db db; 377 struct mlx5_db db;
377 struct mlx5_ib_wq rq; 378 struct mlx5_ib_wq rq;
@@ -413,7 +414,7 @@ struct mlx5_ib_qp {
413}; 414};
414 415
415struct mlx5_ib_cq_buf { 416struct mlx5_ib_cq_buf {
416 struct mlx5_buf buf; 417 struct mlx5_frag_buf_ctrl fbc;
417 struct ib_umem *umem; 418 struct ib_umem *umem;
418 int cqe_size; 419 int cqe_size;
419 int nent; 420 int nent;
@@ -495,7 +496,7 @@ struct mlx5_ib_wc {
495struct mlx5_ib_srq { 496struct mlx5_ib_srq {
496 struct ib_srq ibsrq; 497 struct ib_srq ibsrq;
497 struct mlx5_core_srq msrq; 498 struct mlx5_core_srq msrq;
498 struct mlx5_buf buf; 499 struct mlx5_frag_buf buf;
499 struct mlx5_db db; 500 struct mlx5_db db;
500 u64 *wrid; 501 u64 *wrid;
501 /* protect SRQ hanlding 502 /* protect SRQ hanlding
@@ -731,7 +732,9 @@ struct mlx5_ib_delay_drop {
731 732
732enum mlx5_ib_stages { 733enum mlx5_ib_stages {
733 MLX5_IB_STAGE_INIT, 734 MLX5_IB_STAGE_INIT,
735 MLX5_IB_STAGE_FLOW_DB,
734 MLX5_IB_STAGE_CAPS, 736 MLX5_IB_STAGE_CAPS,
737 MLX5_IB_STAGE_NON_DEFAULT_CB,
735 MLX5_IB_STAGE_ROCE, 738 MLX5_IB_STAGE_ROCE,
736 MLX5_IB_STAGE_DEVICE_RESOURCES, 739 MLX5_IB_STAGE_DEVICE_RESOURCES,
737 MLX5_IB_STAGE_ODP, 740 MLX5_IB_STAGE_ODP,
@@ -744,6 +747,7 @@ enum mlx5_ib_stages {
744 MLX5_IB_STAGE_POST_IB_REG_UMR, 747 MLX5_IB_STAGE_POST_IB_REG_UMR,
745 MLX5_IB_STAGE_DELAY_DROP, 748 MLX5_IB_STAGE_DELAY_DROP,
746 MLX5_IB_STAGE_CLASS_ATTR, 749 MLX5_IB_STAGE_CLASS_ATTR,
750 MLX5_IB_STAGE_REP_REG,
747 MLX5_IB_STAGE_MAX, 751 MLX5_IB_STAGE_MAX,
748}; 752};
749 753
@@ -798,7 +802,7 @@ struct mlx5_ib_dev {
798 struct srcu_struct mr_srcu; 802 struct srcu_struct mr_srcu;
799 u32 null_mkey; 803 u32 null_mkey;
800#endif 804#endif
801 struct mlx5_ib_flow_db flow_db; 805 struct mlx5_ib_flow_db *flow_db;
802 /* protect resources needed as part of reset flow */ 806 /* protect resources needed as part of reset flow */
803 spinlock_t reset_flow_resource_lock; 807 spinlock_t reset_flow_resource_lock;
804 struct list_head qp_list; 808 struct list_head qp_list;
@@ -808,6 +812,7 @@ struct mlx5_ib_dev {
808 struct mlx5_sq_bfreg fp_bfreg; 812 struct mlx5_sq_bfreg fp_bfreg;
809 struct mlx5_ib_delay_drop delay_drop; 813 struct mlx5_ib_delay_drop delay_drop;
810 const struct mlx5_ib_profile *profile; 814 const struct mlx5_ib_profile *profile;
815 struct mlx5_eswitch_rep *rep;
811 816
812 /* protect the user_td */ 817 /* protect the user_td */
813 struct mutex lb_mutex; 818 struct mutex lb_mutex;
@@ -1050,6 +1055,31 @@ static inline void mlx5_odp_populate_klm(struct mlx5_klm *pklm, size_t offset,
1050 1055
1051#endif /* CONFIG_INFINIBAND_ON_DEMAND_PAGING */ 1056#endif /* CONFIG_INFINIBAND_ON_DEMAND_PAGING */
1052 1057
1058/* Needed for rep profile */
1059int mlx5_ib_stage_init_init(struct mlx5_ib_dev *dev);
1060void mlx5_ib_stage_init_cleanup(struct mlx5_ib_dev *dev);
1061int mlx5_ib_stage_rep_flow_db_init(struct mlx5_ib_dev *dev);
1062int mlx5_ib_stage_caps_init(struct mlx5_ib_dev *dev);
1063int mlx5_ib_stage_rep_non_default_cb(struct mlx5_ib_dev *dev);
1064int mlx5_ib_stage_rep_roce_init(struct mlx5_ib_dev *dev);
1065void mlx5_ib_stage_rep_roce_cleanup(struct mlx5_ib_dev *dev);
1066int mlx5_ib_stage_dev_res_init(struct mlx5_ib_dev *dev);
1067void mlx5_ib_stage_dev_res_cleanup(struct mlx5_ib_dev *dev);
1068int mlx5_ib_stage_counters_init(struct mlx5_ib_dev *dev);
1069void mlx5_ib_stage_counters_cleanup(struct mlx5_ib_dev *dev);
1070int mlx5_ib_stage_bfrag_init(struct mlx5_ib_dev *dev);
1071void mlx5_ib_stage_bfrag_cleanup(struct mlx5_ib_dev *dev);
1072void mlx5_ib_stage_pre_ib_reg_umr_cleanup(struct mlx5_ib_dev *dev);
1073int mlx5_ib_stage_ib_reg_init(struct mlx5_ib_dev *dev);
1074void mlx5_ib_stage_ib_reg_cleanup(struct mlx5_ib_dev *dev);
1075int mlx5_ib_stage_post_ib_reg_umr_init(struct mlx5_ib_dev *dev);
1076int mlx5_ib_stage_class_attr_init(struct mlx5_ib_dev *dev);
1077void __mlx5_ib_remove(struct mlx5_ib_dev *dev,
1078 const struct mlx5_ib_profile *profile,
1079 int stage);
1080void *__mlx5_ib_add(struct mlx5_ib_dev *dev,
1081 const struct mlx5_ib_profile *profile);
1082
1053int mlx5_ib_get_vf_config(struct ib_device *device, int vf, 1083int mlx5_ib_get_vf_config(struct ib_device *device, int vf,
1054 u8 port, struct ifla_vf_info *info); 1084 u8 port, struct ifla_vf_info *info);
1055int mlx5_ib_set_vf_link_state(struct ib_device *device, int vf, 1085int mlx5_ib_set_vf_link_state(struct ib_device *device, int vf,
diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c
index c51c602f06d6..95a36e9ea552 100644
--- a/drivers/infiniband/hw/mlx5/mr.c
+++ b/drivers/infiniband/hw/mlx5/mr.c
@@ -587,7 +587,7 @@ static void clean_keys(struct mlx5_ib_dev *dev, int c)
587 587
588static void mlx5_mr_cache_debugfs_cleanup(struct mlx5_ib_dev *dev) 588static void mlx5_mr_cache_debugfs_cleanup(struct mlx5_ib_dev *dev)
589{ 589{
590 if (!mlx5_debugfs_root) 590 if (!mlx5_debugfs_root || dev->rep)
591 return; 591 return;
592 592
593 debugfs_remove_recursive(dev->cache.root); 593 debugfs_remove_recursive(dev->cache.root);
@@ -600,7 +600,7 @@ static int mlx5_mr_cache_debugfs_init(struct mlx5_ib_dev *dev)
600 struct mlx5_cache_ent *ent; 600 struct mlx5_cache_ent *ent;
601 int i; 601 int i;
602 602
603 if (!mlx5_debugfs_root) 603 if (!mlx5_debugfs_root || dev->rep)
604 return 0; 604 return 0;
605 605
606 cache->root = debugfs_create_dir("mr_cache", dev->mdev->priv.dbg_root); 606 cache->root = debugfs_create_dir("mr_cache", dev->mdev->priv.dbg_root);
@@ -690,6 +690,7 @@ int mlx5_mr_cache_init(struct mlx5_ib_dev *dev)
690 MLX5_IB_UMR_OCTOWORD; 690 MLX5_IB_UMR_OCTOWORD;
691 ent->access_mode = MLX5_MKC_ACCESS_MODE_MTT; 691 ent->access_mode = MLX5_MKC_ACCESS_MODE_MTT;
692 if ((dev->mdev->profile->mask & MLX5_PROF_MASK_MR_CACHE) && 692 if ((dev->mdev->profile->mask & MLX5_PROF_MASK_MR_CACHE) &&
693 !dev->rep &&
693 mlx5_core_is_pf(dev->mdev)) 694 mlx5_core_is_pf(dev->mdev))
694 ent->limit = dev->mdev->profile->mr_cache[i].limit; 695 ent->limit = dev->mdev->profile->mr_cache[i].limit;
695 else 696 else
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index a2e1aa86e133..85c612ac547a 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -36,6 +36,7 @@
36#include <rdma/ib_user_verbs.h> 36#include <rdma/ib_user_verbs.h>
37#include <linux/mlx5/fs.h> 37#include <linux/mlx5/fs.h>
38#include "mlx5_ib.h" 38#include "mlx5_ib.h"
39#include "ib_rep.h"
39 40
40/* not supported currently */ 41/* not supported currently */
41static int wq_signature; 42static int wq_signature;
@@ -1082,6 +1083,13 @@ static void destroy_raw_packet_qp_tis(struct mlx5_ib_dev *dev,
1082 mlx5_core_destroy_tis(dev->mdev, sq->tisn); 1083 mlx5_core_destroy_tis(dev->mdev, sq->tisn);
1083} 1084}
1084 1085
1086static void destroy_flow_rule_vport_sq(struct mlx5_ib_dev *dev,
1087 struct mlx5_ib_sq *sq)
1088{
1089 if (sq->flow_rule)
1090 mlx5_del_flow_rules(sq->flow_rule);
1091}
1092
1085static int create_raw_packet_qp_sq(struct mlx5_ib_dev *dev, 1093static int create_raw_packet_qp_sq(struct mlx5_ib_dev *dev,
1086 struct mlx5_ib_sq *sq, void *qpin, 1094 struct mlx5_ib_sq *sq, void *qpin,
1087 struct ib_pd *pd) 1095 struct ib_pd *pd)
@@ -1145,8 +1153,15 @@ static int create_raw_packet_qp_sq(struct mlx5_ib_dev *dev,
1145 if (err) 1153 if (err)
1146 goto err_umem; 1154 goto err_umem;
1147 1155
1156 err = create_flow_rule_vport_sq(dev, sq);
1157 if (err)
1158 goto err_flow;
1159
1148 return 0; 1160 return 0;
1149 1161
1162err_flow:
1163 mlx5_core_destroy_sq_tracked(dev->mdev, &sq->base.mqp);
1164
1150err_umem: 1165err_umem:
1151 ib_umem_release(sq->ubuffer.umem); 1166 ib_umem_release(sq->ubuffer.umem);
1152 sq->ubuffer.umem = NULL; 1167 sq->ubuffer.umem = NULL;
@@ -1157,6 +1172,7 @@ err_umem:
1157static void destroy_raw_packet_qp_sq(struct mlx5_ib_dev *dev, 1172static void destroy_raw_packet_qp_sq(struct mlx5_ib_dev *dev,
1158 struct mlx5_ib_sq *sq) 1173 struct mlx5_ib_sq *sq)
1159{ 1174{
1175 destroy_flow_rule_vport_sq(dev, sq);
1160 mlx5_core_destroy_sq_tracked(dev->mdev, &sq->base.mqp); 1176 mlx5_core_destroy_sq_tracked(dev->mdev, &sq->base.mqp);
1161 ib_umem_release(sq->ubuffer.umem); 1177 ib_umem_release(sq->ubuffer.umem);
1162} 1178}
@@ -1267,6 +1283,10 @@ static int create_raw_packet_qp_tir(struct mlx5_ib_dev *dev,
1267 if (tunnel_offload_en) 1283 if (tunnel_offload_en)
1268 MLX5_SET(tirc, tirc, tunneled_offload_en, 1); 1284 MLX5_SET(tirc, tirc, tunneled_offload_en, 1);
1269 1285
1286 if (dev->rep)
1287 MLX5_SET(tirc, tirc, self_lb_block,
1288 MLX5_TIRC_SELF_LB_BLOCK_BLOCK_UNICAST_);
1289
1270 err = mlx5_core_create_tir(dev->mdev, in, inlen, &rq->tirn); 1290 err = mlx5_core_create_tir(dev->mdev, in, inlen, &rq->tirn);
1271 1291
1272 kvfree(in); 1292 kvfree(in);
@@ -1558,6 +1578,10 @@ static int create_rss_raw_qp_tir(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
1558 MLX5_SET(rx_hash_field_select, hfso, selected_fields, selected_fields); 1578 MLX5_SET(rx_hash_field_select, hfso, selected_fields, selected_fields);
1559 1579
1560create_tir: 1580create_tir:
1581 if (dev->rep)
1582 MLX5_SET(tirc, tirc, self_lb_block,
1583 MLX5_TIRC_SELF_LB_BLOCK_BLOCK_UNICAST_);
1584
1561 err = mlx5_core_create_tir(dev->mdev, in, inlen, &qp->rss_qp.tirn); 1585 err = mlx5_core_create_tir(dev->mdev, in, inlen, &qp->rss_qp.tirn);
1562 1586
1563 if (err) 1587 if (err)
@@ -2143,7 +2167,6 @@ static struct ib_qp *mlx5_ib_create_dct(struct ib_pd *pd,
2143 struct ib_qp_init_attr *attr, 2167 struct ib_qp_init_attr *attr,
2144 struct mlx5_ib_create_qp *ucmd) 2168 struct mlx5_ib_create_qp *ucmd)
2145{ 2169{
2146 struct mlx5_ib_dev *dev;
2147 struct mlx5_ib_qp *qp; 2170 struct mlx5_ib_qp *qp;
2148 int err = 0; 2171 int err = 0;
2149 u32 uidx = MLX5_IB_DEFAULT_UIDX; 2172 u32 uidx = MLX5_IB_DEFAULT_UIDX;
@@ -2152,8 +2175,6 @@ static struct ib_qp *mlx5_ib_create_dct(struct ib_pd *pd,
2152 if (!attr->srq || !attr->recv_cq) 2175 if (!attr->srq || !attr->recv_cq)
2153 return ERR_PTR(-EINVAL); 2176 return ERR_PTR(-EINVAL);
2154 2177
2155 dev = to_mdev(pd->device);
2156
2157 err = get_qp_user_index(to_mucontext(pd->uobject->context), 2178 err = get_qp_user_index(to_mucontext(pd->uobject->context),
2158 ucmd, sizeof(*ucmd), &uidx); 2179 ucmd, sizeof(*ucmd), &uidx);
2159 if (err) 2180 if (err)
diff --git a/drivers/infiniband/hw/usnic/usnic_transport.c b/drivers/infiniband/hw/usnic/usnic_transport.c
index de318389a301..67de94343cb4 100644
--- a/drivers/infiniband/hw/usnic/usnic_transport.c
+++ b/drivers/infiniband/hw/usnic/usnic_transport.c
@@ -174,14 +174,13 @@ void usnic_transport_put_socket(struct socket *sock)
174int usnic_transport_sock_get_addr(struct socket *sock, int *proto, 174int usnic_transport_sock_get_addr(struct socket *sock, int *proto,
175 uint32_t *addr, uint16_t *port) 175 uint32_t *addr, uint16_t *port)
176{ 176{
177 int len;
178 int err; 177 int err;
179 struct sockaddr_in sock_addr; 178 struct sockaddr_in sock_addr;
180 179
181 err = sock->ops->getname(sock, 180 err = sock->ops->getname(sock,
182 (struct sockaddr *)&sock_addr, 181 (struct sockaddr *)&sock_addr,
183 &len, 0); 182 0);
184 if (err) 183 if (err < 0)
185 return err; 184 return err;
186 185
187 if (sock_addr.sin_family != AF_INET) 186 if (sock_addr.sin_family != AF_INET)
diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c
index c5603d1a07d6..1f8f489b4167 100644
--- a/drivers/isdn/mISDN/socket.c
+++ b/drivers/isdn/mISDN/socket.c
@@ -560,7 +560,7 @@ done:
560 560
561static int 561static int
562data_sock_getname(struct socket *sock, struct sockaddr *addr, 562data_sock_getname(struct socket *sock, struct sockaddr *addr,
563 int *addr_len, int peer) 563 int peer)
564{ 564{
565 struct sockaddr_mISDN *maddr = (struct sockaddr_mISDN *) addr; 565 struct sockaddr_mISDN *maddr = (struct sockaddr_mISDN *) addr;
566 struct sock *sk = sock->sk; 566 struct sock *sk = sock->sk;
@@ -570,14 +570,13 @@ data_sock_getname(struct socket *sock, struct sockaddr *addr,
570 570
571 lock_sock(sk); 571 lock_sock(sk);
572 572
573 *addr_len = sizeof(*maddr);
574 maddr->family = AF_ISDN; 573 maddr->family = AF_ISDN;
575 maddr->dev = _pms(sk)->dev->id; 574 maddr->dev = _pms(sk)->dev->id;
576 maddr->channel = _pms(sk)->ch.nr; 575 maddr->channel = _pms(sk)->ch.nr;
577 maddr->sapi = _pms(sk)->ch.addr & 0xff; 576 maddr->sapi = _pms(sk)->ch.addr & 0xff;
578 maddr->tei = (_pms(sk)->ch.addr >> 8) & 0xff; 577 maddr->tei = (_pms(sk)->ch.addr >> 8) & 0xff;
579 release_sock(sk); 578 release_sock(sk);
580 return 0; 579 return sizeof(*maddr);
581} 580}
582 581
583static const struct proto_ops data_sock_ops = { 582static const struct proto_ops data_sock_ops = {
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 944ec3c9282c..08b85215c2be 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -149,9 +149,9 @@ config MACVTAP
149config IPVLAN 149config IPVLAN
150 tristate "IP-VLAN support" 150 tristate "IP-VLAN support"
151 depends on INET 151 depends on INET
152 depends on IPV6 152 depends on IPV6 || !IPV6
153 depends on NETFILTER 153 depends on NETFILTER
154 depends on NET_L3_MASTER_DEV 154 select NET_L3_MASTER_DEV
155 ---help--- 155 ---help---
156 This allows one to create virtual devices off of a main interface 156 This allows one to create virtual devices off of a main interface
157 and packets will be delivered based on the dest L3 (IPv6/IPv4 addr) 157 and packets will be delivered based on the dest L3 (IPv6/IPv4 addr)
diff --git a/drivers/net/Space.c b/drivers/net/Space.c
index 11fe71278f40..3afda6561434 100644
--- a/drivers/net/Space.c
+++ b/drivers/net/Space.c
@@ -114,12 +114,6 @@ static struct devprobe2 m68k_probes[] __initdata = {
114#ifdef CONFIG_MVME147_NET /* MVME147 internal Ethernet */ 114#ifdef CONFIG_MVME147_NET /* MVME147 internal Ethernet */
115 {mvme147lance_probe, 0}, 115 {mvme147lance_probe, 0},
116#endif 116#endif
117#ifdef CONFIG_MAC8390 /* NuBus NS8390-based cards */
118 {mac8390_probe, 0},
119#endif
120#ifdef CONFIG_MAC89x0
121 {mac89x0_probe, 0},
122#endif
123 {NULL, 0}, 117 {NULL, 0},
124}; 118};
125 119
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index c669554d70bb..4c19d23dd282 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4791,6 +4791,7 @@ static struct pernet_operations bond_net_ops = {
4791 .exit = bond_net_exit, 4791 .exit = bond_net_exit,
4792 .id = &bond_net_id, 4792 .id = &bond_net_id,
4793 .size = sizeof(struct bond_net), 4793 .size = sizeof(struct bond_net),
4794 .async = true,
4794}; 4795};
4795 4796
4796static int __init bonding_init(void) 4797static int __init bonding_init(void)
diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
index 63e02a54d537..78616787f2a3 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -852,7 +852,7 @@ void b53_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data)
852} 852}
853EXPORT_SYMBOL(b53_get_ethtool_stats); 853EXPORT_SYMBOL(b53_get_ethtool_stats);
854 854
855int b53_get_sset_count(struct dsa_switch *ds) 855int b53_get_sset_count(struct dsa_switch *ds, int port)
856{ 856{
857 struct b53_device *dev = ds->priv; 857 struct b53_device *dev = ds->priv;
858 858
diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h
index d954cf36ecd8..1187ebd79287 100644
--- a/drivers/net/dsa/b53/b53_priv.h
+++ b/drivers/net/dsa/b53/b53_priv.h
@@ -288,7 +288,7 @@ void b53_imp_vlan_setup(struct dsa_switch *ds, int cpu_port);
288int b53_configure_vlan(struct dsa_switch *ds); 288int b53_configure_vlan(struct dsa_switch *ds);
289void b53_get_strings(struct dsa_switch *ds, int port, uint8_t *data); 289void b53_get_strings(struct dsa_switch *ds, int port, uint8_t *data);
290void b53_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data); 290void b53_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data);
291int b53_get_sset_count(struct dsa_switch *ds); 291int b53_get_sset_count(struct dsa_switch *ds, int port);
292int b53_br_join(struct dsa_switch *ds, int port, struct net_device *bridge); 292int b53_br_join(struct dsa_switch *ds, int port, struct net_device *bridge);
293void b53_br_leave(struct dsa_switch *ds, int port, struct net_device *bridge); 293void b53_br_leave(struct dsa_switch *ds, int port, struct net_device *bridge);
294void b53_br_set_stp_state(struct dsa_switch *ds, int port, u8 state); 294void b53_br_set_stp_state(struct dsa_switch *ds, int port, u8 state);
diff --git a/drivers/net/dsa/dsa_loop.c b/drivers/net/dsa/dsa_loop.c
index 7aa84ee4e771..f77be9f85cb3 100644
--- a/drivers/net/dsa/dsa_loop.c
+++ b/drivers/net/dsa/dsa_loop.c
@@ -86,7 +86,7 @@ static int dsa_loop_setup(struct dsa_switch *ds)
86 return 0; 86 return 0;
87} 87}
88 88
89static int dsa_loop_get_sset_count(struct dsa_switch *ds) 89static int dsa_loop_get_sset_count(struct dsa_switch *ds, int port)
90{ 90{
91 return __DSA_LOOP_CNT_MAX; 91 return __DSA_LOOP_CNT_MAX;
92} 92}
diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c
index 6171c0853ff1..fefa454f3e56 100644
--- a/drivers/net/dsa/lan9303-core.c
+++ b/drivers/net/dsa/lan9303-core.c
@@ -1007,7 +1007,7 @@ static void lan9303_get_ethtool_stats(struct dsa_switch *ds, int port,
1007 } 1007 }
1008} 1008}
1009 1009
1010static int lan9303_get_sset_count(struct dsa_switch *ds) 1010static int lan9303_get_sset_count(struct dsa_switch *ds, int port)
1011{ 1011{
1012 return ARRAY_SIZE(lan9303_mib); 1012 return ARRAY_SIZE(lan9303_mib);
1013} 1013}
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index 663b0d5b982b..bcb3e6c734f2 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -439,7 +439,7 @@ static void ksz_disable_port(struct dsa_switch *ds, int port,
439 ksz_port_cfg(dev, port, REG_PORT_CTRL_0, PORT_MAC_LOOPBACK, true); 439 ksz_port_cfg(dev, port, REG_PORT_CTRL_0, PORT_MAC_LOOPBACK, true);
440} 440}
441 441
442static int ksz_sset_count(struct dsa_switch *ds) 442static int ksz_sset_count(struct dsa_switch *ds, int port)
443{ 443{
444 return TOTAL_SWITCH_COUNTER_NUM; 444 return TOTAL_SWITCH_COUNTER_NUM;
445} 445}
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 8a0bb000d056..511ca134f13f 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -604,7 +604,7 @@ mt7530_get_ethtool_stats(struct dsa_switch *ds, int port,
604} 604}
605 605
606static int 606static int
607mt7530_get_sset_count(struct dsa_switch *ds) 607mt7530_get_sset_count(struct dsa_switch *ds, int port)
608{ 608{
609 return ARRAY_SIZE(mt7530_mib); 609 return ARRAY_SIZE(mt7530_mib);
610} 610}
diff --git a/drivers/net/dsa/mv88e6xxx/Kconfig b/drivers/net/dsa/mv88e6xxx/Kconfig
index 1aaa7a95ebc4..ae9e7f7cb31c 100644
--- a/drivers/net/dsa/mv88e6xxx/Kconfig
+++ b/drivers/net/dsa/mv88e6xxx/Kconfig
@@ -18,3 +18,13 @@ config NET_DSA_MV88E6XXX_GLOBAL2
18 18
19 It is required on most chips. If the chip you compile the support for 19 It is required on most chips. If the chip you compile the support for
20 doesn't have such registers set, say N here. In doubt, say Y. 20 doesn't have such registers set, say N here. In doubt, say Y.
21
22config NET_DSA_MV88E6XXX_PTP
23 bool "PTP support for Marvell 88E6xxx"
24 default n
25 depends on NET_DSA_MV88E6XXX_GLOBAL2
26 imply NETWORK_PHY_TIMESTAMPING
27 imply PTP_1588_CLOCK
28 help
29 Say Y to enable PTP hardware timestamping on Marvell 88E6xxx switch
30 chips that support it.
diff --git a/drivers/net/dsa/mv88e6xxx/Makefile b/drivers/net/dsa/mv88e6xxx/Makefile
index 58a4a0014e59..50de304abe2f 100644
--- a/drivers/net/dsa/mv88e6xxx/Makefile
+++ b/drivers/net/dsa/mv88e6xxx/Makefile
@@ -5,6 +5,10 @@ mv88e6xxx-objs += global1.o
5mv88e6xxx-objs += global1_atu.o 5mv88e6xxx-objs += global1_atu.o
6mv88e6xxx-objs += global1_vtu.o 6mv88e6xxx-objs += global1_vtu.o
7mv88e6xxx-$(CONFIG_NET_DSA_MV88E6XXX_GLOBAL2) += global2.o 7mv88e6xxx-$(CONFIG_NET_DSA_MV88E6XXX_GLOBAL2) += global2.o
8mv88e6xxx-$(CONFIG_NET_DSA_MV88E6XXX_GLOBAL2) += global2_avb.o
9mv88e6xxx-$(CONFIG_NET_DSA_MV88E6XXX_GLOBAL2) += global2_scratch.o
10mv88e6xxx-$(CONFIG_NET_DSA_MV88E6XXX_PTP) += hwtstamp.o
8mv88e6xxx-objs += phy.o 11mv88e6xxx-objs += phy.o
9mv88e6xxx-objs += port.o 12mv88e6xxx-objs += port.o
13mv88e6xxx-$(CONFIG_NET_DSA_MV88E6XXX_PTP) += ptp.o
10mv88e6xxx-objs += serdes.o 14mv88e6xxx-objs += serdes.o
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index eb328bade225..fd78378ad6b1 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -36,8 +36,10 @@
36#include "chip.h" 36#include "chip.h"
37#include "global1.h" 37#include "global1.h"
38#include "global2.h" 38#include "global2.h"
39#include "hwtstamp.h"
39#include "phy.h" 40#include "phy.h"
40#include "port.h" 41#include "port.h"
42#include "ptp.h"
41#include "serdes.h" 43#include "serdes.h"
42 44
43static void assert_reg_lock(struct mv88e6xxx_chip *chip) 45static void assert_reg_lock(struct mv88e6xxx_chip *chip)
@@ -251,9 +253,8 @@ static void mv88e6xxx_g1_irq_unmask(struct irq_data *d)
251 chip->g1_irq.masked &= ~(1 << n); 253 chip->g1_irq.masked &= ~(1 << n);
252} 254}
253 255
254static irqreturn_t mv88e6xxx_g1_irq_thread_fn(int irq, void *dev_id) 256static irqreturn_t mv88e6xxx_g1_irq_thread_work(struct mv88e6xxx_chip *chip)
255{ 257{
256 struct mv88e6xxx_chip *chip = dev_id;
257 unsigned int nhandled = 0; 258 unsigned int nhandled = 0;
258 unsigned int sub_irq; 259 unsigned int sub_irq;
259 unsigned int n; 260 unsigned int n;
@@ -278,6 +279,13 @@ out:
278 return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE); 279 return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE);
279} 280}
280 281
282static irqreturn_t mv88e6xxx_g1_irq_thread_fn(int irq, void *dev_id)
283{
284 struct mv88e6xxx_chip *chip = dev_id;
285
286 return mv88e6xxx_g1_irq_thread_work(chip);
287}
288
281static void mv88e6xxx_g1_irq_bus_lock(struct irq_data *d) 289static void mv88e6xxx_g1_irq_bus_lock(struct irq_data *d)
282{ 290{
283 struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d); 291 struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
@@ -333,7 +341,7 @@ static const struct irq_domain_ops mv88e6xxx_g1_irq_domain_ops = {
333 .xlate = irq_domain_xlate_twocell, 341 .xlate = irq_domain_xlate_twocell,
334}; 342};
335 343
336static void mv88e6xxx_g1_irq_free(struct mv88e6xxx_chip *chip) 344static void mv88e6xxx_g1_irq_free_common(struct mv88e6xxx_chip *chip)
337{ 345{
338 int irq, virq; 346 int irq, virq;
339 u16 mask; 347 u16 mask;
@@ -342,8 +350,6 @@ static void mv88e6xxx_g1_irq_free(struct mv88e6xxx_chip *chip)
342 mask &= ~GENMASK(chip->g1_irq.nirqs, 0); 350 mask &= ~GENMASK(chip->g1_irq.nirqs, 0);
343 mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, mask); 351 mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, mask);
344 352
345 free_irq(chip->irq, chip);
346
347 for (irq = 0; irq < chip->g1_irq.nirqs; irq++) { 353 for (irq = 0; irq < chip->g1_irq.nirqs; irq++) {
348 virq = irq_find_mapping(chip->g1_irq.domain, irq); 354 virq = irq_find_mapping(chip->g1_irq.domain, irq);
349 irq_dispose_mapping(virq); 355 irq_dispose_mapping(virq);
@@ -352,7 +358,14 @@ static void mv88e6xxx_g1_irq_free(struct mv88e6xxx_chip *chip)
352 irq_domain_remove(chip->g1_irq.domain); 358 irq_domain_remove(chip->g1_irq.domain);
353} 359}
354 360
355static int mv88e6xxx_g1_irq_setup(struct mv88e6xxx_chip *chip) 361static void mv88e6xxx_g1_irq_free(struct mv88e6xxx_chip *chip)
362{
363 mv88e6xxx_g1_irq_free_common(chip);
364
365 free_irq(chip->irq, chip);
366}
367
368static int mv88e6xxx_g1_irq_setup_common(struct mv88e6xxx_chip *chip)
356{ 369{
357 int err, irq, virq; 370 int err, irq, virq;
358 u16 reg, mask; 371 u16 reg, mask;
@@ -385,13 +398,6 @@ static int mv88e6xxx_g1_irq_setup(struct mv88e6xxx_chip *chip)
385 if (err) 398 if (err)
386 goto out_disable; 399 goto out_disable;
387 400
388 err = request_threaded_irq(chip->irq, NULL,
389 mv88e6xxx_g1_irq_thread_fn,
390 IRQF_ONESHOT | IRQF_TRIGGER_FALLING,
391 dev_name(chip->dev), chip);
392 if (err)
393 goto out_disable;
394
395 return 0; 401 return 0;
396 402
397out_disable: 403out_disable:
@@ -409,6 +415,62 @@ out_mapping:
409 return err; 415 return err;
410} 416}
411 417
418static int mv88e6xxx_g1_irq_setup(struct mv88e6xxx_chip *chip)
419{
420 int err;
421
422 err = mv88e6xxx_g1_irq_setup_common(chip);
423 if (err)
424 return err;
425
426 err = request_threaded_irq(chip->irq, NULL,
427 mv88e6xxx_g1_irq_thread_fn,
428 IRQF_ONESHOT | IRQF_TRIGGER_FALLING,
429 dev_name(chip->dev), chip);
430 if (err)
431 mv88e6xxx_g1_irq_free_common(chip);
432
433 return err;
434}
435
436static void mv88e6xxx_irq_poll(struct kthread_work *work)
437{
438 struct mv88e6xxx_chip *chip = container_of(work,
439 struct mv88e6xxx_chip,
440 irq_poll_work.work);
441 mv88e6xxx_g1_irq_thread_work(chip);
442
443 kthread_queue_delayed_work(chip->kworker, &chip->irq_poll_work,
444 msecs_to_jiffies(100));
445}
446
447static int mv88e6xxx_irq_poll_setup(struct mv88e6xxx_chip *chip)
448{
449 int err;
450
451 err = mv88e6xxx_g1_irq_setup_common(chip);
452 if (err)
453 return err;
454
455 kthread_init_delayed_work(&chip->irq_poll_work,
456 mv88e6xxx_irq_poll);
457
458 chip->kworker = kthread_create_worker(0, dev_name(chip->dev));
459 if (IS_ERR(chip->kworker))
460 return PTR_ERR(chip->kworker);
461
462 kthread_queue_delayed_work(chip->kworker, &chip->irq_poll_work,
463 msecs_to_jiffies(100));
464
465 return 0;
466}
467
468static void mv88e6xxx_irq_poll_free(struct mv88e6xxx_chip *chip)
469{
470 kthread_cancel_delayed_work_sync(&chip->irq_poll_work);
471 kthread_destroy_worker(chip->kworker);
472}
473
412int mv88e6xxx_wait(struct mv88e6xxx_chip *chip, int addr, int reg, u16 mask) 474int mv88e6xxx_wait(struct mv88e6xxx_chip *chip, int addr, int reg, u16 mask)
413{ 475{
414 int i; 476 int i;
@@ -604,7 +666,7 @@ static uint64_t _mv88e6xxx_get_ethtool_stat(struct mv88e6xxx_chip *chip,
604 return UINT64_MAX; 666 return UINT64_MAX;
605 667
606 low = reg; 668 low = reg;
607 if (s->sizeof_stat == 4) { 669 if (s->size == 4) {
608 err = mv88e6xxx_port_read(chip, port, s->reg + 1, &reg); 670 err = mv88e6xxx_port_read(chip, port, s->reg + 1, &reg);
609 if (err) 671 if (err)
610 return UINT64_MAX; 672 return UINT64_MAX;
@@ -617,7 +679,7 @@ static uint64_t _mv88e6xxx_get_ethtool_stat(struct mv88e6xxx_chip *chip,
617 case STATS_TYPE_BANK0: 679 case STATS_TYPE_BANK0:
618 reg |= s->reg | histogram; 680 reg |= s->reg | histogram;
619 mv88e6xxx_g1_stats_read(chip, reg, &low); 681 mv88e6xxx_g1_stats_read(chip, reg, &low);
620 if (s->sizeof_stat == 8) 682 if (s->size == 8)
621 mv88e6xxx_g1_stats_read(chip, reg + 1, &high); 683 mv88e6xxx_g1_stats_read(chip, reg + 1, &high);
622 break; 684 break;
623 default: 685 default:
@@ -627,8 +689,8 @@ static uint64_t _mv88e6xxx_get_ethtool_stat(struct mv88e6xxx_chip *chip,
627 return value; 689 return value;
628} 690}
629 691
630static void mv88e6xxx_stats_get_strings(struct mv88e6xxx_chip *chip, 692static int mv88e6xxx_stats_get_strings(struct mv88e6xxx_chip *chip,
631 uint8_t *data, int types) 693 uint8_t *data, int types)
632{ 694{
633 struct mv88e6xxx_hw_stat *stat; 695 struct mv88e6xxx_hw_stat *stat;
634 int i, j; 696 int i, j;
@@ -641,29 +703,41 @@ static void mv88e6xxx_stats_get_strings(struct mv88e6xxx_chip *chip,
641 j++; 703 j++;
642 } 704 }
643 } 705 }
706
707 return j;
644} 708}
645 709
646static void mv88e6095_stats_get_strings(struct mv88e6xxx_chip *chip, 710static int mv88e6095_stats_get_strings(struct mv88e6xxx_chip *chip,
647 uint8_t *data) 711 uint8_t *data)
648{ 712{
649 mv88e6xxx_stats_get_strings(chip, data, 713 return mv88e6xxx_stats_get_strings(chip, data,
650 STATS_TYPE_BANK0 | STATS_TYPE_PORT); 714 STATS_TYPE_BANK0 | STATS_TYPE_PORT);
651} 715}
652 716
653static void mv88e6320_stats_get_strings(struct mv88e6xxx_chip *chip, 717static int mv88e6320_stats_get_strings(struct mv88e6xxx_chip *chip,
654 uint8_t *data) 718 uint8_t *data)
655{ 719{
656 mv88e6xxx_stats_get_strings(chip, data, 720 return mv88e6xxx_stats_get_strings(chip, data,
657 STATS_TYPE_BANK0 | STATS_TYPE_BANK1); 721 STATS_TYPE_BANK0 | STATS_TYPE_BANK1);
658} 722}
659 723
660static void mv88e6xxx_get_strings(struct dsa_switch *ds, int port, 724static void mv88e6xxx_get_strings(struct dsa_switch *ds, int port,
661 uint8_t *data) 725 uint8_t *data)
662{ 726{
663 struct mv88e6xxx_chip *chip = ds->priv; 727 struct mv88e6xxx_chip *chip = ds->priv;
728 int count = 0;
729
730 mutex_lock(&chip->reg_lock);
664 731
665 if (chip->info->ops->stats_get_strings) 732 if (chip->info->ops->stats_get_strings)
666 chip->info->ops->stats_get_strings(chip, data); 733 count = chip->info->ops->stats_get_strings(chip, data);
734
735 if (chip->info->ops->serdes_get_strings) {
736 data += count * ETH_GSTRING_LEN;
737 chip->info->ops->serdes_get_strings(chip, port, data);
738 }
739
740 mutex_unlock(&chip->reg_lock);
667} 741}
668 742
669static int mv88e6xxx_stats_get_sset_count(struct mv88e6xxx_chip *chip, 743static int mv88e6xxx_stats_get_sset_count(struct mv88e6xxx_chip *chip,
@@ -692,19 +766,34 @@ static int mv88e6320_stats_get_sset_count(struct mv88e6xxx_chip *chip)
692 STATS_TYPE_BANK1); 766 STATS_TYPE_BANK1);
693} 767}
694 768
695static int mv88e6xxx_get_sset_count(struct dsa_switch *ds) 769static int mv88e6xxx_get_sset_count(struct dsa_switch *ds, int port)
696{ 770{
697 struct mv88e6xxx_chip *chip = ds->priv; 771 struct mv88e6xxx_chip *chip = ds->priv;
772 int serdes_count = 0;
773 int count = 0;
698 774
775 mutex_lock(&chip->reg_lock);
699 if (chip->info->ops->stats_get_sset_count) 776 if (chip->info->ops->stats_get_sset_count)
700 return chip->info->ops->stats_get_sset_count(chip); 777 count = chip->info->ops->stats_get_sset_count(chip);
778 if (count < 0)
779 goto out;
701 780
702 return 0; 781 if (chip->info->ops->serdes_get_sset_count)
782 serdes_count = chip->info->ops->serdes_get_sset_count(chip,
783 port);
784 if (serdes_count < 0)
785 count = serdes_count;
786 else
787 count += serdes_count;
788out:
789 mutex_unlock(&chip->reg_lock);
790
791 return count;
703} 792}
704 793
705static void mv88e6xxx_stats_get_stats(struct mv88e6xxx_chip *chip, int port, 794static int mv88e6xxx_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
706 uint64_t *data, int types, 795 uint64_t *data, int types,
707 u16 bank1_select, u16 histogram) 796 u16 bank1_select, u16 histogram)
708{ 797{
709 struct mv88e6xxx_hw_stat *stat; 798 struct mv88e6xxx_hw_stat *stat;
710 int i, j; 799 int i, j;
@@ -712,24 +801,28 @@ static void mv88e6xxx_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
712 for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) { 801 for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) {
713 stat = &mv88e6xxx_hw_stats[i]; 802 stat = &mv88e6xxx_hw_stats[i];
714 if (stat->type & types) { 803 if (stat->type & types) {
804 mutex_lock(&chip->reg_lock);
715 data[j] = _mv88e6xxx_get_ethtool_stat(chip, stat, port, 805 data[j] = _mv88e6xxx_get_ethtool_stat(chip, stat, port,
716 bank1_select, 806 bank1_select,
717 histogram); 807 histogram);
808 mutex_unlock(&chip->reg_lock);
809
718 j++; 810 j++;
719 } 811 }
720 } 812 }
813 return j;
721} 814}
722 815
723static void mv88e6095_stats_get_stats(struct mv88e6xxx_chip *chip, int port, 816static int mv88e6095_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
724 uint64_t *data) 817 uint64_t *data)
725{ 818{
726 return mv88e6xxx_stats_get_stats(chip, port, data, 819 return mv88e6xxx_stats_get_stats(chip, port, data,
727 STATS_TYPE_BANK0 | STATS_TYPE_PORT, 820 STATS_TYPE_BANK0 | STATS_TYPE_PORT,
728 0, MV88E6XXX_G1_STATS_OP_HIST_RX_TX); 821 0, MV88E6XXX_G1_STATS_OP_HIST_RX_TX);
729} 822}
730 823
731static void mv88e6320_stats_get_stats(struct mv88e6xxx_chip *chip, int port, 824static int mv88e6320_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
732 uint64_t *data) 825 uint64_t *data)
733{ 826{
734 return mv88e6xxx_stats_get_stats(chip, port, data, 827 return mv88e6xxx_stats_get_stats(chip, port, data,
735 STATS_TYPE_BANK0 | STATS_TYPE_BANK1, 828 STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
@@ -737,8 +830,8 @@ static void mv88e6320_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
737 MV88E6XXX_G1_STATS_OP_HIST_RX_TX); 830 MV88E6XXX_G1_STATS_OP_HIST_RX_TX);
738} 831}
739 832
740static void mv88e6390_stats_get_stats(struct mv88e6xxx_chip *chip, int port, 833static int mv88e6390_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
741 uint64_t *data) 834 uint64_t *data)
742{ 835{
743 return mv88e6xxx_stats_get_stats(chip, port, data, 836 return mv88e6xxx_stats_get_stats(chip, port, data,
744 STATS_TYPE_BANK0 | STATS_TYPE_BANK1, 837 STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
@@ -749,8 +842,17 @@ static void mv88e6390_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
749static void mv88e6xxx_get_stats(struct mv88e6xxx_chip *chip, int port, 842static void mv88e6xxx_get_stats(struct mv88e6xxx_chip *chip, int port,
750 uint64_t *data) 843 uint64_t *data)
751{ 844{
845 int count = 0;
846
752 if (chip->info->ops->stats_get_stats) 847 if (chip->info->ops->stats_get_stats)
753 chip->info->ops->stats_get_stats(chip, port, data); 848 count = chip->info->ops->stats_get_stats(chip, port, data);
849
850 if (chip->info->ops->serdes_get_stats) {
851 data += count;
852 mutex_lock(&chip->reg_lock);
853 chip->info->ops->serdes_get_stats(chip, port, data);
854 mutex_unlock(&chip->reg_lock);
855 }
754} 856}
755 857
756static void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port, 858static void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port,
@@ -762,14 +864,13 @@ static void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port,
762 mutex_lock(&chip->reg_lock); 864 mutex_lock(&chip->reg_lock);
763 865
764 ret = mv88e6xxx_stats_snapshot(chip, port); 866 ret = mv88e6xxx_stats_snapshot(chip, port);
765 if (ret < 0) { 867 mutex_unlock(&chip->reg_lock);
766 mutex_unlock(&chip->reg_lock); 868
869 if (ret < 0)
767 return; 870 return;
768 }
769 871
770 mv88e6xxx_get_stats(chip, port, data); 872 mv88e6xxx_get_stats(chip, port, data);
771 873
772 mutex_unlock(&chip->reg_lock);
773} 874}
774 875
775static int mv88e6xxx_stats_set_histogram(struct mv88e6xxx_chip *chip) 876static int mv88e6xxx_stats_set_histogram(struct mv88e6xxx_chip *chip)
@@ -1433,7 +1534,9 @@ static int mv88e6xxx_port_db_dump_fid(struct mv88e6xxx_chip *chip,
1433 eth_broadcast_addr(addr.mac); 1534 eth_broadcast_addr(addr.mac);
1434 1535
1435 do { 1536 do {
1537 mutex_lock(&chip->reg_lock);
1436 err = mv88e6xxx_g1_atu_getnext(chip, fid, &addr); 1538 err = mv88e6xxx_g1_atu_getnext(chip, fid, &addr);
1539 mutex_unlock(&chip->reg_lock);
1437 if (err) 1540 if (err)
1438 return err; 1541 return err;
1439 1542
@@ -1466,7 +1569,10 @@ static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port,
1466 int err; 1569 int err;
1467 1570
1468 /* Dump port's default Filtering Information Database (VLAN ID 0) */ 1571 /* Dump port's default Filtering Information Database (VLAN ID 0) */
1572 mutex_lock(&chip->reg_lock);
1469 err = mv88e6xxx_port_get_fid(chip, port, &fid); 1573 err = mv88e6xxx_port_get_fid(chip, port, &fid);
1574 mutex_unlock(&chip->reg_lock);
1575
1470 if (err) 1576 if (err)
1471 return err; 1577 return err;
1472 1578
@@ -1476,7 +1582,9 @@ static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port,
1476 1582
1477 /* Dump VLANs' Filtering Information Databases */ 1583 /* Dump VLANs' Filtering Information Databases */
1478 do { 1584 do {
1585 mutex_lock(&chip->reg_lock);
1479 err = mv88e6xxx_vtu_getnext(chip, &vlan); 1586 err = mv88e6xxx_vtu_getnext(chip, &vlan);
1587 mutex_unlock(&chip->reg_lock);
1480 if (err) 1588 if (err)
1481 return err; 1589 return err;
1482 1590
@@ -1496,13 +1604,8 @@ static int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port,
1496 dsa_fdb_dump_cb_t *cb, void *data) 1604 dsa_fdb_dump_cb_t *cb, void *data)
1497{ 1605{
1498 struct mv88e6xxx_chip *chip = ds->priv; 1606 struct mv88e6xxx_chip *chip = ds->priv;
1499 int err;
1500
1501 mutex_lock(&chip->reg_lock);
1502 err = mv88e6xxx_port_db_dump(chip, port, cb, data);
1503 mutex_unlock(&chip->reg_lock);
1504 1607
1505 return err; 1608 return mv88e6xxx_port_db_dump(chip, port, cb, data);
1506} 1609}
1507 1610
1508static int mv88e6xxx_bridge_map(struct mv88e6xxx_chip *chip, 1611static int mv88e6xxx_bridge_map(struct mv88e6xxx_chip *chip,
@@ -2092,6 +2195,17 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
2092 if (err) 2195 if (err)
2093 goto unlock; 2196 goto unlock;
2094 2197
2198 /* Setup PTP Hardware Clock and timestamping */
2199 if (chip->info->ptp_support) {
2200 err = mv88e6xxx_ptp_setup(chip);
2201 if (err)
2202 goto unlock;
2203
2204 err = mv88e6xxx_hwtstamp_setup(chip);
2205 if (err)
2206 goto unlock;
2207 }
2208
2095unlock: 2209unlock:
2096 mutex_unlock(&chip->reg_lock); 2210 mutex_unlock(&chip->reg_lock);
2097 2211
@@ -2148,6 +2262,15 @@ static int mv88e6xxx_mdio_register(struct mv88e6xxx_chip *chip,
2148 struct mii_bus *bus; 2262 struct mii_bus *bus;
2149 int err; 2263 int err;
2150 2264
2265 if (external) {
2266 mutex_lock(&chip->reg_lock);
2267 err = mv88e6xxx_g2_scratch_gpio_set_smi(chip, true);
2268 mutex_unlock(&chip->reg_lock);
2269
2270 if (err)
2271 return err;
2272 }
2273
2151 bus = devm_mdiobus_alloc_size(chip->dev, sizeof(*mdio_bus)); 2274 bus = devm_mdiobus_alloc_size(chip->dev, sizeof(*mdio_bus));
2152 if (!bus) 2275 if (!bus)
2153 return -ENOMEM; 2276 return -ENOMEM;
@@ -2170,12 +2293,19 @@ static int mv88e6xxx_mdio_register(struct mv88e6xxx_chip *chip,
2170 bus->write = mv88e6xxx_mdio_write; 2293 bus->write = mv88e6xxx_mdio_write;
2171 bus->parent = chip->dev; 2294 bus->parent = chip->dev;
2172 2295
2296 if (!external) {
2297 err = mv88e6xxx_g2_irq_mdio_setup(chip, bus);
2298 if (err)
2299 return err;
2300 }
2301
2173 if (np) 2302 if (np)
2174 err = of_mdiobus_register(bus, np); 2303 err = of_mdiobus_register(bus, np);
2175 else 2304 else
2176 err = mdiobus_register(bus); 2305 err = mdiobus_register(bus);
2177 if (err) { 2306 if (err) {
2178 dev_err(chip->dev, "Cannot register MDIO bus (%d)\n", err); 2307 dev_err(chip->dev, "Cannot register MDIO bus (%d)\n", err);
2308 mv88e6xxx_g2_irq_mdio_free(chip, bus);
2179 return err; 2309 return err;
2180 } 2310 }
2181 2311
@@ -2202,6 +2332,9 @@ static void mv88e6xxx_mdios_unregister(struct mv88e6xxx_chip *chip)
2202 list_for_each_entry(mdio_bus, &chip->mdios, list) { 2332 list_for_each_entry(mdio_bus, &chip->mdios, list) {
2203 bus = mdio_bus->bus; 2333 bus = mdio_bus->bus;
2204 2334
2335 if (!mdio_bus->external)
2336 mv88e6xxx_g2_irq_mdio_free(chip, bus);
2337
2205 mdiobus_unregister(bus); 2338 mdiobus_unregister(bus);
2206 } 2339 }
2207} 2340}
@@ -2472,6 +2605,7 @@ static const struct mv88e6xxx_ops mv88e6141_ops = {
2472 .reset = mv88e6352_g1_reset, 2605 .reset = mv88e6352_g1_reset,
2473 .vtu_getnext = mv88e6352_g1_vtu_getnext, 2606 .vtu_getnext = mv88e6352_g1_vtu_getnext,
2474 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, 2607 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
2608 .gpio_ops = &mv88e6352_gpio_ops,
2475}; 2609};
2476 2610
2477static const struct mv88e6xxx_ops mv88e6161_ops = { 2611static const struct mv88e6xxx_ops mv88e6161_ops = {
@@ -2602,6 +2736,7 @@ static const struct mv88e6xxx_ops mv88e6172_ops = {
2602 .vtu_getnext = mv88e6352_g1_vtu_getnext, 2736 .vtu_getnext = mv88e6352_g1_vtu_getnext,
2603 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, 2737 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
2604 .serdes_power = mv88e6352_serdes_power, 2738 .serdes_power = mv88e6352_serdes_power,
2739 .gpio_ops = &mv88e6352_gpio_ops,
2605}; 2740};
2606 2741
2607static const struct mv88e6xxx_ops mv88e6175_ops = { 2742static const struct mv88e6xxx_ops mv88e6175_ops = {
@@ -2673,6 +2808,7 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
2673 .vtu_getnext = mv88e6352_g1_vtu_getnext, 2808 .vtu_getnext = mv88e6352_g1_vtu_getnext,
2674 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, 2809 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
2675 .serdes_power = mv88e6352_serdes_power, 2810 .serdes_power = mv88e6352_serdes_power,
2811 .gpio_ops = &mv88e6352_gpio_ops,
2676}; 2812};
2677 2813
2678static const struct mv88e6xxx_ops mv88e6185_ops = { 2814static const struct mv88e6xxx_ops mv88e6185_ops = {
@@ -2736,6 +2872,7 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
2736 .vtu_getnext = mv88e6390_g1_vtu_getnext, 2872 .vtu_getnext = mv88e6390_g1_vtu_getnext,
2737 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, 2873 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
2738 .serdes_power = mv88e6390_serdes_power, 2874 .serdes_power = mv88e6390_serdes_power,
2875 .gpio_ops = &mv88e6352_gpio_ops,
2739}; 2876};
2740 2877
2741static const struct mv88e6xxx_ops mv88e6190x_ops = { 2878static const struct mv88e6xxx_ops mv88e6190x_ops = {
@@ -2771,6 +2908,7 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
2771 .vtu_getnext = mv88e6390_g1_vtu_getnext, 2908 .vtu_getnext = mv88e6390_g1_vtu_getnext,
2772 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, 2909 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
2773 .serdes_power = mv88e6390_serdes_power, 2910 .serdes_power = mv88e6390_serdes_power,
2911 .gpio_ops = &mv88e6352_gpio_ops,
2774}; 2912};
2775 2913
2776static const struct mv88e6xxx_ops mv88e6191_ops = { 2914static const struct mv88e6xxx_ops mv88e6191_ops = {
@@ -2843,6 +2981,8 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
2843 .vtu_getnext = mv88e6352_g1_vtu_getnext, 2981 .vtu_getnext = mv88e6352_g1_vtu_getnext,
2844 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, 2982 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
2845 .serdes_power = mv88e6352_serdes_power, 2983 .serdes_power = mv88e6352_serdes_power,
2984 .gpio_ops = &mv88e6352_gpio_ops,
2985 .avb_ops = &mv88e6352_avb_ops,
2846}; 2986};
2847 2987
2848static const struct mv88e6xxx_ops mv88e6290_ops = { 2988static const struct mv88e6xxx_ops mv88e6290_ops = {
@@ -2879,6 +3019,8 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
2879 .vtu_getnext = mv88e6390_g1_vtu_getnext, 3019 .vtu_getnext = mv88e6390_g1_vtu_getnext,
2880 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, 3020 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
2881 .serdes_power = mv88e6390_serdes_power, 3021 .serdes_power = mv88e6390_serdes_power,
3022 .gpio_ops = &mv88e6352_gpio_ops,
3023 .avb_ops = &mv88e6390_avb_ops,
2882}; 3024};
2883 3025
2884static const struct mv88e6xxx_ops mv88e6320_ops = { 3026static const struct mv88e6xxx_ops mv88e6320_ops = {
@@ -2913,6 +3055,8 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
2913 .reset = mv88e6352_g1_reset, 3055 .reset = mv88e6352_g1_reset,
2914 .vtu_getnext = mv88e6185_g1_vtu_getnext, 3056 .vtu_getnext = mv88e6185_g1_vtu_getnext,
2915 .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge, 3057 .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
3058 .gpio_ops = &mv88e6352_gpio_ops,
3059 .avb_ops = &mv88e6352_avb_ops,
2916}; 3060};
2917 3061
2918static const struct mv88e6xxx_ops mv88e6321_ops = { 3062static const struct mv88e6xxx_ops mv88e6321_ops = {
@@ -2945,6 +3089,8 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
2945 .reset = mv88e6352_g1_reset, 3089 .reset = mv88e6352_g1_reset,
2946 .vtu_getnext = mv88e6185_g1_vtu_getnext, 3090 .vtu_getnext = mv88e6185_g1_vtu_getnext,
2947 .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge, 3091 .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
3092 .gpio_ops = &mv88e6352_gpio_ops,
3093 .avb_ops = &mv88e6352_avb_ops,
2948}; 3094};
2949 3095
2950static const struct mv88e6xxx_ops mv88e6341_ops = { 3096static const struct mv88e6xxx_ops mv88e6341_ops = {
@@ -2981,6 +3127,8 @@ static const struct mv88e6xxx_ops mv88e6341_ops = {
2981 .reset = mv88e6352_g1_reset, 3127 .reset = mv88e6352_g1_reset,
2982 .vtu_getnext = mv88e6352_g1_vtu_getnext, 3128 .vtu_getnext = mv88e6352_g1_vtu_getnext,
2983 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, 3129 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
3130 .gpio_ops = &mv88e6352_gpio_ops,
3131 .avb_ops = &mv88e6390_avb_ops,
2984}; 3132};
2985 3133
2986static const struct mv88e6xxx_ops mv88e6350_ops = { 3134static const struct mv88e6xxx_ops mv88e6350_ops = {
@@ -3049,6 +3197,7 @@ static const struct mv88e6xxx_ops mv88e6351_ops = {
3049 .reset = mv88e6352_g1_reset, 3197 .reset = mv88e6352_g1_reset,
3050 .vtu_getnext = mv88e6352_g1_vtu_getnext, 3198 .vtu_getnext = mv88e6352_g1_vtu_getnext,
3051 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, 3199 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
3200 .avb_ops = &mv88e6352_avb_ops,
3052}; 3201};
3053 3202
3054static const struct mv88e6xxx_ops mv88e6352_ops = { 3203static const struct mv88e6xxx_ops mv88e6352_ops = {
@@ -3086,6 +3235,11 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
3086 .vtu_getnext = mv88e6352_g1_vtu_getnext, 3235 .vtu_getnext = mv88e6352_g1_vtu_getnext,
3087 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, 3236 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
3088 .serdes_power = mv88e6352_serdes_power, 3237 .serdes_power = mv88e6352_serdes_power,
3238 .gpio_ops = &mv88e6352_gpio_ops,
3239 .avb_ops = &mv88e6352_avb_ops,
3240 .serdes_get_sset_count = mv88e6352_serdes_get_sset_count,
3241 .serdes_get_strings = mv88e6352_serdes_get_strings,
3242 .serdes_get_stats = mv88e6352_serdes_get_stats,
3089}; 3243};
3090 3244
3091static const struct mv88e6xxx_ops mv88e6390_ops = { 3245static const struct mv88e6xxx_ops mv88e6390_ops = {
@@ -3124,6 +3278,8 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
3124 .vtu_getnext = mv88e6390_g1_vtu_getnext, 3278 .vtu_getnext = mv88e6390_g1_vtu_getnext,
3125 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, 3279 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
3126 .serdes_power = mv88e6390_serdes_power, 3280 .serdes_power = mv88e6390_serdes_power,
3281 .gpio_ops = &mv88e6352_gpio_ops,
3282 .avb_ops = &mv88e6390_avb_ops,
3127}; 3283};
3128 3284
3129static const struct mv88e6xxx_ops mv88e6390x_ops = { 3285static const struct mv88e6xxx_ops mv88e6390x_ops = {
@@ -3162,6 +3318,8 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
3162 .vtu_getnext = mv88e6390_g1_vtu_getnext, 3318 .vtu_getnext = mv88e6390_g1_vtu_getnext,
3163 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, 3319 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
3164 .serdes_power = mv88e6390_serdes_power, 3320 .serdes_power = mv88e6390_serdes_power,
3321 .gpio_ops = &mv88e6352_gpio_ops,
3322 .avb_ops = &mv88e6390_avb_ops,
3165}; 3323};
3166 3324
3167static const struct mv88e6xxx_info mv88e6xxx_table[] = { 3325static const struct mv88e6xxx_info mv88e6xxx_table[] = {
@@ -3171,6 +3329,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
3171 .name = "Marvell 88E6085", 3329 .name = "Marvell 88E6085",
3172 .num_databases = 4096, 3330 .num_databases = 4096,
3173 .num_ports = 10, 3331 .num_ports = 10,
3332 .num_internal_phys = 5,
3174 .max_vid = 4095, 3333 .max_vid = 4095,
3175 .port_base_addr = 0x10, 3334 .port_base_addr = 0x10,
3176 .global1_addr = 0x1b, 3335 .global1_addr = 0x1b,
@@ -3191,6 +3350,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
3191 .name = "Marvell 88E6095/88E6095F", 3350 .name = "Marvell 88E6095/88E6095F",
3192 .num_databases = 256, 3351 .num_databases = 256,
3193 .num_ports = 11, 3352 .num_ports = 11,
3353 .num_internal_phys = 0,
3194 .max_vid = 4095, 3354 .max_vid = 4095,
3195 .port_base_addr = 0x10, 3355 .port_base_addr = 0x10,
3196 .global1_addr = 0x1b, 3356 .global1_addr = 0x1b,
@@ -3209,6 +3369,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
3209 .name = "Marvell 88E6097/88E6097F", 3369 .name = "Marvell 88E6097/88E6097F",
3210 .num_databases = 4096, 3370 .num_databases = 4096,
3211 .num_ports = 11, 3371 .num_ports = 11,
3372 .num_internal_phys = 8,
3212 .max_vid = 4095, 3373 .max_vid = 4095,
3213 .port_base_addr = 0x10, 3374 .port_base_addr = 0x10,
3214 .global1_addr = 0x1b, 3375 .global1_addr = 0x1b,
@@ -3229,6 +3390,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
3229 .name = "Marvell 88E6123", 3390 .name = "Marvell 88E6123",
3230 .num_databases = 4096, 3391 .num_databases = 4096,
3231 .num_ports = 3, 3392 .num_ports = 3,
3393 .num_internal_phys = 5,
3232 .max_vid = 4095, 3394 .max_vid = 4095,
3233 .port_base_addr = 0x10, 3395 .port_base_addr = 0x10,
3234 .global1_addr = 0x1b, 3396 .global1_addr = 0x1b,
@@ -3249,6 +3411,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
3249 .name = "Marvell 88E6131", 3411 .name = "Marvell 88E6131",
3250 .num_databases = 256, 3412 .num_databases = 256,
3251 .num_ports = 8, 3413 .num_ports = 8,
3414 .num_internal_phys = 0,
3252 .max_vid = 4095, 3415 .max_vid = 4095,
3253 .port_base_addr = 0x10, 3416 .port_base_addr = 0x10,
3254 .global1_addr = 0x1b, 3417 .global1_addr = 0x1b,
@@ -3264,15 +3427,18 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
3264 [MV88E6141] = { 3427 [MV88E6141] = {
3265 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6141, 3428 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6141,
3266 .family = MV88E6XXX_FAMILY_6341, 3429 .family = MV88E6XXX_FAMILY_6341,
3267 .name = "Marvell 88E6341", 3430 .name = "Marvell 88E6141",
3268 .num_databases = 4096, 3431 .num_databases = 4096,
3269 .num_ports = 6, 3432 .num_ports = 6,
3433 .num_internal_phys = 5,
3434 .num_gpio = 11,
3270 .max_vid = 4095, 3435 .max_vid = 4095,
3271 .port_base_addr = 0x10, 3436 .port_base_addr = 0x10,
3272 .global1_addr = 0x1b, 3437 .global1_addr = 0x1b,
3273 .global2_addr = 0x1c, 3438 .global2_addr = 0x1c,
3274 .age_time_coeff = 3750, 3439 .age_time_coeff = 3750,
3275 .atu_move_port_mask = 0x1f, 3440 .atu_move_port_mask = 0x1f,
3441 .g1_irqs = 9,
3276 .g2_irqs = 10, 3442 .g2_irqs = 10,
3277 .pvt = true, 3443 .pvt = true,
3278 .multi_chip = true, 3444 .multi_chip = true,
@@ -3286,6 +3452,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
3286 .name = "Marvell 88E6161", 3452 .name = "Marvell 88E6161",
3287 .num_databases = 4096, 3453 .num_databases = 4096,
3288 .num_ports = 6, 3454 .num_ports = 6,
3455 .num_internal_phys = 5,
3289 .max_vid = 4095, 3456 .max_vid = 4095,
3290 .port_base_addr = 0x10, 3457 .port_base_addr = 0x10,
3291 .global1_addr = 0x1b, 3458 .global1_addr = 0x1b,
@@ -3306,6 +3473,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
3306 .name = "Marvell 88E6165", 3473 .name = "Marvell 88E6165",
3307 .num_databases = 4096, 3474 .num_databases = 4096,
3308 .num_ports = 6, 3475 .num_ports = 6,
3476 .num_internal_phys = 0,
3309 .max_vid = 4095, 3477 .max_vid = 4095,
3310 .port_base_addr = 0x10, 3478 .port_base_addr = 0x10,
3311 .global1_addr = 0x1b, 3479 .global1_addr = 0x1b,
@@ -3326,6 +3494,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
3326 .name = "Marvell 88E6171", 3494 .name = "Marvell 88E6171",
3327 .num_databases = 4096, 3495 .num_databases = 4096,
3328 .num_ports = 7, 3496 .num_ports = 7,
3497 .num_internal_phys = 5,
3329 .max_vid = 4095, 3498 .max_vid = 4095,
3330 .port_base_addr = 0x10, 3499 .port_base_addr = 0x10,
3331 .global1_addr = 0x1b, 3500 .global1_addr = 0x1b,
@@ -3346,6 +3515,8 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
3346 .name = "Marvell 88E6172", 3515 .name = "Marvell 88E6172",
3347 .num_databases = 4096, 3516 .num_databases = 4096,
3348 .num_ports = 7, 3517 .num_ports = 7,
3518 .num_internal_phys = 5,
3519 .num_gpio = 15,
3349 .max_vid = 4095, 3520 .max_vid = 4095,
3350 .port_base_addr = 0x10, 3521 .port_base_addr = 0x10,
3351 .global1_addr = 0x1b, 3522 .global1_addr = 0x1b,
@@ -3366,6 +3537,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
3366 .name = "Marvell 88E6175", 3537 .name = "Marvell 88E6175",
3367 .num_databases = 4096, 3538 .num_databases = 4096,
3368 .num_ports = 7, 3539 .num_ports = 7,
3540 .num_internal_phys = 5,
3369 .max_vid = 4095, 3541 .max_vid = 4095,
3370 .port_base_addr = 0x10, 3542 .port_base_addr = 0x10,
3371 .global1_addr = 0x1b, 3543 .global1_addr = 0x1b,
@@ -3386,6 +3558,8 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
3386 .name = "Marvell 88E6176", 3558 .name = "Marvell 88E6176",
3387 .num_databases = 4096, 3559 .num_databases = 4096,
3388 .num_ports = 7, 3560 .num_ports = 7,
3561 .num_internal_phys = 5,
3562 .num_gpio = 15,
3389 .max_vid = 4095, 3563 .max_vid = 4095,
3390 .port_base_addr = 0x10, 3564 .port_base_addr = 0x10,
3391 .global1_addr = 0x1b, 3565 .global1_addr = 0x1b,
@@ -3406,6 +3580,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
3406 .name = "Marvell 88E6185", 3580 .name = "Marvell 88E6185",
3407 .num_databases = 256, 3581 .num_databases = 256,
3408 .num_ports = 10, 3582 .num_ports = 10,
3583 .num_internal_phys = 0,
3409 .max_vid = 4095, 3584 .max_vid = 4095,
3410 .port_base_addr = 0x10, 3585 .port_base_addr = 0x10,
3411 .global1_addr = 0x1b, 3586 .global1_addr = 0x1b,
@@ -3424,6 +3599,8 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
3424 .name = "Marvell 88E6190", 3599 .name = "Marvell 88E6190",
3425 .num_databases = 4096, 3600 .num_databases = 4096,
3426 .num_ports = 11, /* 10 + Z80 */ 3601 .num_ports = 11, /* 10 + Z80 */
3602 .num_internal_phys = 11,
3603 .num_gpio = 16,
3427 .max_vid = 8191, 3604 .max_vid = 8191,
3428 .port_base_addr = 0x0, 3605 .port_base_addr = 0x0,
3429 .global1_addr = 0x1b, 3606 .global1_addr = 0x1b,
@@ -3444,6 +3621,8 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
3444 .name = "Marvell 88E6190X", 3621 .name = "Marvell 88E6190X",
3445 .num_databases = 4096, 3622 .num_databases = 4096,
3446 .num_ports = 11, /* 10 + Z80 */ 3623 .num_ports = 11, /* 10 + Z80 */
3624 .num_internal_phys = 11,
3625 .num_gpio = 16,
3447 .max_vid = 8191, 3626 .max_vid = 8191,
3448 .port_base_addr = 0x0, 3627 .port_base_addr = 0x0,
3449 .global1_addr = 0x1b, 3628 .global1_addr = 0x1b,
@@ -3464,6 +3643,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
3464 .name = "Marvell 88E6191", 3643 .name = "Marvell 88E6191",
3465 .num_databases = 4096, 3644 .num_databases = 4096,
3466 .num_ports = 11, /* 10 + Z80 */ 3645 .num_ports = 11, /* 10 + Z80 */
3646 .num_internal_phys = 11,
3467 .max_vid = 8191, 3647 .max_vid = 8191,
3468 .port_base_addr = 0x0, 3648 .port_base_addr = 0x0,
3469 .global1_addr = 0x1b, 3649 .global1_addr = 0x1b,
@@ -3475,6 +3655,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
3475 .pvt = true, 3655 .pvt = true,
3476 .multi_chip = true, 3656 .multi_chip = true,
3477 .tag_protocol = DSA_TAG_PROTO_DSA, 3657 .tag_protocol = DSA_TAG_PROTO_DSA,
3658 .ptp_support = true,
3478 .ops = &mv88e6191_ops, 3659 .ops = &mv88e6191_ops,
3479 }, 3660 },
3480 3661
@@ -3484,6 +3665,8 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
3484 .name = "Marvell 88E6240", 3665 .name = "Marvell 88E6240",
3485 .num_databases = 4096, 3666 .num_databases = 4096,
3486 .num_ports = 7, 3667 .num_ports = 7,
3668 .num_internal_phys = 5,
3669 .num_gpio = 15,
3487 .max_vid = 4095, 3670 .max_vid = 4095,
3488 .port_base_addr = 0x10, 3671 .port_base_addr = 0x10,
3489 .global1_addr = 0x1b, 3672 .global1_addr = 0x1b,
@@ -3495,6 +3678,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
3495 .pvt = true, 3678 .pvt = true,
3496 .multi_chip = true, 3679 .multi_chip = true,
3497 .tag_protocol = DSA_TAG_PROTO_EDSA, 3680 .tag_protocol = DSA_TAG_PROTO_EDSA,
3681 .ptp_support = true,
3498 .ops = &mv88e6240_ops, 3682 .ops = &mv88e6240_ops,
3499 }, 3683 },
3500 3684
@@ -3504,6 +3688,8 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
3504 .name = "Marvell 88E6290", 3688 .name = "Marvell 88E6290",
3505 .num_databases = 4096, 3689 .num_databases = 4096,
3506 .num_ports = 11, /* 10 + Z80 */ 3690 .num_ports = 11, /* 10 + Z80 */
3691 .num_internal_phys = 11,
3692 .num_gpio = 16,
3507 .max_vid = 8191, 3693 .max_vid = 8191,
3508 .port_base_addr = 0x0, 3694 .port_base_addr = 0x0,
3509 .global1_addr = 0x1b, 3695 .global1_addr = 0x1b,
@@ -3515,6 +3701,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
3515 .pvt = true, 3701 .pvt = true,
3516 .multi_chip = true, 3702 .multi_chip = true,
3517 .tag_protocol = DSA_TAG_PROTO_DSA, 3703 .tag_protocol = DSA_TAG_PROTO_DSA,
3704 .ptp_support = true,
3518 .ops = &mv88e6290_ops, 3705 .ops = &mv88e6290_ops,
3519 }, 3706 },
3520 3707
@@ -3524,16 +3711,20 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
3524 .name = "Marvell 88E6320", 3711 .name = "Marvell 88E6320",
3525 .num_databases = 4096, 3712 .num_databases = 4096,
3526 .num_ports = 7, 3713 .num_ports = 7,
3714 .num_internal_phys = 5,
3715 .num_gpio = 15,
3527 .max_vid = 4095, 3716 .max_vid = 4095,
3528 .port_base_addr = 0x10, 3717 .port_base_addr = 0x10,
3529 .global1_addr = 0x1b, 3718 .global1_addr = 0x1b,
3530 .global2_addr = 0x1c, 3719 .global2_addr = 0x1c,
3531 .age_time_coeff = 15000, 3720 .age_time_coeff = 15000,
3532 .g1_irqs = 8, 3721 .g1_irqs = 8,
3722 .g2_irqs = 10,
3533 .atu_move_port_mask = 0xf, 3723 .atu_move_port_mask = 0xf,
3534 .pvt = true, 3724 .pvt = true,
3535 .multi_chip = true, 3725 .multi_chip = true,
3536 .tag_protocol = DSA_TAG_PROTO_EDSA, 3726 .tag_protocol = DSA_TAG_PROTO_EDSA,
3727 .ptp_support = true,
3537 .ops = &mv88e6320_ops, 3728 .ops = &mv88e6320_ops,
3538 }, 3729 },
3539 3730
@@ -3543,15 +3734,19 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
3543 .name = "Marvell 88E6321", 3734 .name = "Marvell 88E6321",
3544 .num_databases = 4096, 3735 .num_databases = 4096,
3545 .num_ports = 7, 3736 .num_ports = 7,
3737 .num_internal_phys = 5,
3738 .num_gpio = 15,
3546 .max_vid = 4095, 3739 .max_vid = 4095,
3547 .port_base_addr = 0x10, 3740 .port_base_addr = 0x10,
3548 .global1_addr = 0x1b, 3741 .global1_addr = 0x1b,
3549 .global2_addr = 0x1c, 3742 .global2_addr = 0x1c,
3550 .age_time_coeff = 15000, 3743 .age_time_coeff = 15000,
3551 .g1_irqs = 8, 3744 .g1_irqs = 8,
3745 .g2_irqs = 10,
3552 .atu_move_port_mask = 0xf, 3746 .atu_move_port_mask = 0xf,
3553 .multi_chip = true, 3747 .multi_chip = true,
3554 .tag_protocol = DSA_TAG_PROTO_EDSA, 3748 .tag_protocol = DSA_TAG_PROTO_EDSA,
3749 .ptp_support = true,
3555 .ops = &mv88e6321_ops, 3750 .ops = &mv88e6321_ops,
3556 }, 3751 },
3557 3752
@@ -3560,17 +3755,21 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
3560 .family = MV88E6XXX_FAMILY_6341, 3755 .family = MV88E6XXX_FAMILY_6341,
3561 .name = "Marvell 88E6341", 3756 .name = "Marvell 88E6341",
3562 .num_databases = 4096, 3757 .num_databases = 4096,
3758 .num_internal_phys = 5,
3563 .num_ports = 6, 3759 .num_ports = 6,
3760 .num_gpio = 11,
3564 .max_vid = 4095, 3761 .max_vid = 4095,
3565 .port_base_addr = 0x10, 3762 .port_base_addr = 0x10,
3566 .global1_addr = 0x1b, 3763 .global1_addr = 0x1b,
3567 .global2_addr = 0x1c, 3764 .global2_addr = 0x1c,
3568 .age_time_coeff = 3750, 3765 .age_time_coeff = 3750,
3569 .atu_move_port_mask = 0x1f, 3766 .atu_move_port_mask = 0x1f,
3767 .g1_irqs = 9,
3570 .g2_irqs = 10, 3768 .g2_irqs = 10,
3571 .pvt = true, 3769 .pvt = true,
3572 .multi_chip = true, 3770 .multi_chip = true,
3573 .tag_protocol = DSA_TAG_PROTO_EDSA, 3771 .tag_protocol = DSA_TAG_PROTO_EDSA,
3772 .ptp_support = true,
3574 .ops = &mv88e6341_ops, 3773 .ops = &mv88e6341_ops,
3575 }, 3774 },
3576 3775
@@ -3580,6 +3779,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
3580 .name = "Marvell 88E6350", 3779 .name = "Marvell 88E6350",
3581 .num_databases = 4096, 3780 .num_databases = 4096,
3582 .num_ports = 7, 3781 .num_ports = 7,
3782 .num_internal_phys = 5,
3583 .max_vid = 4095, 3783 .max_vid = 4095,
3584 .port_base_addr = 0x10, 3784 .port_base_addr = 0x10,
3585 .global1_addr = 0x1b, 3785 .global1_addr = 0x1b,
@@ -3600,6 +3800,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
3600 .name = "Marvell 88E6351", 3800 .name = "Marvell 88E6351",
3601 .num_databases = 4096, 3801 .num_databases = 4096,
3602 .num_ports = 7, 3802 .num_ports = 7,
3803 .num_internal_phys = 5,
3603 .max_vid = 4095, 3804 .max_vid = 4095,
3604 .port_base_addr = 0x10, 3805 .port_base_addr = 0x10,
3605 .global1_addr = 0x1b, 3806 .global1_addr = 0x1b,
@@ -3620,6 +3821,8 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
3620 .name = "Marvell 88E6352", 3821 .name = "Marvell 88E6352",
3621 .num_databases = 4096, 3822 .num_databases = 4096,
3622 .num_ports = 7, 3823 .num_ports = 7,
3824 .num_internal_phys = 5,
3825 .num_gpio = 15,
3623 .max_vid = 4095, 3826 .max_vid = 4095,
3624 .port_base_addr = 0x10, 3827 .port_base_addr = 0x10,
3625 .global1_addr = 0x1b, 3828 .global1_addr = 0x1b,
@@ -3631,6 +3834,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
3631 .pvt = true, 3834 .pvt = true,
3632 .multi_chip = true, 3835 .multi_chip = true,
3633 .tag_protocol = DSA_TAG_PROTO_EDSA, 3836 .tag_protocol = DSA_TAG_PROTO_EDSA,
3837 .ptp_support = true,
3634 .ops = &mv88e6352_ops, 3838 .ops = &mv88e6352_ops,
3635 }, 3839 },
3636 [MV88E6390] = { 3840 [MV88E6390] = {
@@ -3639,6 +3843,8 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
3639 .name = "Marvell 88E6390", 3843 .name = "Marvell 88E6390",
3640 .num_databases = 4096, 3844 .num_databases = 4096,
3641 .num_ports = 11, /* 10 + Z80 */ 3845 .num_ports = 11, /* 10 + Z80 */
3846 .num_internal_phys = 11,
3847 .num_gpio = 16,
3642 .max_vid = 8191, 3848 .max_vid = 8191,
3643 .port_base_addr = 0x0, 3849 .port_base_addr = 0x0,
3644 .global1_addr = 0x1b, 3850 .global1_addr = 0x1b,
@@ -3650,6 +3856,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
3650 .pvt = true, 3856 .pvt = true,
3651 .multi_chip = true, 3857 .multi_chip = true,
3652 .tag_protocol = DSA_TAG_PROTO_DSA, 3858 .tag_protocol = DSA_TAG_PROTO_DSA,
3859 .ptp_support = true,
3653 .ops = &mv88e6390_ops, 3860 .ops = &mv88e6390_ops,
3654 }, 3861 },
3655 [MV88E6390X] = { 3862 [MV88E6390X] = {
@@ -3658,6 +3865,8 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
3658 .name = "Marvell 88E6390X", 3865 .name = "Marvell 88E6390X",
3659 .num_databases = 4096, 3866 .num_databases = 4096,
3660 .num_ports = 11, /* 10 + Z80 */ 3867 .num_ports = 11, /* 10 + Z80 */
3868 .num_internal_phys = 11,
3869 .num_gpio = 16,
3661 .max_vid = 8191, 3870 .max_vid = 8191,
3662 .port_base_addr = 0x0, 3871 .port_base_addr = 0x0,
3663 .global1_addr = 0x1b, 3872 .global1_addr = 0x1b,
@@ -3669,6 +3878,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
3669 .pvt = true, 3878 .pvt = true,
3670 .multi_chip = true, 3879 .multi_chip = true,
3671 .tag_protocol = DSA_TAG_PROTO_DSA, 3880 .tag_protocol = DSA_TAG_PROTO_DSA,
3881 .ptp_support = true,
3672 .ops = &mv88e6390x_ops, 3882 .ops = &mv88e6390x_ops,
3673 }, 3883 },
3674}; 3884};
@@ -3880,6 +4090,11 @@ static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
3880 .port_mdb_del = mv88e6xxx_port_mdb_del, 4090 .port_mdb_del = mv88e6xxx_port_mdb_del,
3881 .crosschip_bridge_join = mv88e6xxx_crosschip_bridge_join, 4091 .crosschip_bridge_join = mv88e6xxx_crosschip_bridge_join,
3882 .crosschip_bridge_leave = mv88e6xxx_crosschip_bridge_leave, 4092 .crosschip_bridge_leave = mv88e6xxx_crosschip_bridge_leave,
4093 .port_hwtstamp_set = mv88e6xxx_port_hwtstamp_set,
4094 .port_hwtstamp_get = mv88e6xxx_port_hwtstamp_get,
4095 .port_txtstamp = mv88e6xxx_port_txtstamp,
4096 .port_rxtstamp = mv88e6xxx_port_rxtstamp,
4097 .get_ts_info = mv88e6xxx_get_ts_info,
3883}; 4098};
3884 4099
3885static struct dsa_switch_driver mv88e6xxx_switch_drv = { 4100static struct dsa_switch_driver mv88e6xxx_switch_drv = {
@@ -3959,33 +4174,34 @@ static int mv88e6xxx_probe(struct mdio_device *mdiodev)
3959 goto out; 4174 goto out;
3960 } 4175 }
3961 4176
3962 if (chip->irq > 0) { 4177 /* Has to be performed before the MDIO bus is created, because
3963 /* Has to be performed before the MDIO bus is created, 4178 * the PHYs will link their interrupts to these interrupt
3964 * because the PHYs will link there interrupts to these 4179 * controllers
3965 * interrupt controllers 4180 */
3966 */ 4181 mutex_lock(&chip->reg_lock);
3967 mutex_lock(&chip->reg_lock); 4182 if (chip->irq > 0)
3968 err = mv88e6xxx_g1_irq_setup(chip); 4183 err = mv88e6xxx_g1_irq_setup(chip);
3969 mutex_unlock(&chip->reg_lock); 4184 else
3970 4185 err = mv88e6xxx_irq_poll_setup(chip);
3971 if (err) 4186 mutex_unlock(&chip->reg_lock);
3972 goto out;
3973
3974 if (chip->info->g2_irqs > 0) {
3975 err = mv88e6xxx_g2_irq_setup(chip);
3976 if (err)
3977 goto out_g1_irq;
3978 }
3979 4187
3980 err = mv88e6xxx_g1_atu_prob_irq_setup(chip); 4188 if (err)
3981 if (err) 4189 goto out;
3982 goto out_g2_irq;
3983 4190
3984 err = mv88e6xxx_g1_vtu_prob_irq_setup(chip); 4191 if (chip->info->g2_irqs > 0) {
4192 err = mv88e6xxx_g2_irq_setup(chip);
3985 if (err) 4193 if (err)
3986 goto out_g1_atu_prob_irq; 4194 goto out_g1_irq;
3987 } 4195 }
3988 4196
4197 err = mv88e6xxx_g1_atu_prob_irq_setup(chip);
4198 if (err)
4199 goto out_g2_irq;
4200
4201 err = mv88e6xxx_g1_vtu_prob_irq_setup(chip);
4202 if (err)
4203 goto out_g1_atu_prob_irq;
4204
3989 err = mv88e6xxx_mdios_register(chip, np); 4205 err = mv88e6xxx_mdios_register(chip, np);
3990 if (err) 4206 if (err)
3991 goto out_g1_vtu_prob_irq; 4207 goto out_g1_vtu_prob_irq;
@@ -3999,20 +4215,19 @@ static int mv88e6xxx_probe(struct mdio_device *mdiodev)
3999out_mdio: 4215out_mdio:
4000 mv88e6xxx_mdios_unregister(chip); 4216 mv88e6xxx_mdios_unregister(chip);
4001out_g1_vtu_prob_irq: 4217out_g1_vtu_prob_irq:
4002 if (chip->irq > 0) 4218 mv88e6xxx_g1_vtu_prob_irq_free(chip);
4003 mv88e6xxx_g1_vtu_prob_irq_free(chip);
4004out_g1_atu_prob_irq: 4219out_g1_atu_prob_irq:
4005 if (chip->irq > 0) 4220 mv88e6xxx_g1_atu_prob_irq_free(chip);
4006 mv88e6xxx_g1_atu_prob_irq_free(chip);
4007out_g2_irq: 4221out_g2_irq:
4008 if (chip->info->g2_irqs > 0 && chip->irq > 0) 4222 if (chip->info->g2_irqs > 0)
4009 mv88e6xxx_g2_irq_free(chip); 4223 mv88e6xxx_g2_irq_free(chip);
4010out_g1_irq: 4224out_g1_irq:
4011 if (chip->irq > 0) { 4225 mutex_lock(&chip->reg_lock);
4012 mutex_lock(&chip->reg_lock); 4226 if (chip->irq > 0)
4013 mv88e6xxx_g1_irq_free(chip); 4227 mv88e6xxx_g1_irq_free(chip);
4014 mutex_unlock(&chip->reg_lock); 4228 else
4015 } 4229 mv88e6xxx_irq_poll_free(chip);
4230 mutex_unlock(&chip->reg_lock);
4016out: 4231out:
4017 return err; 4232 return err;
4018} 4233}
@@ -4022,19 +4237,27 @@ static void mv88e6xxx_remove(struct mdio_device *mdiodev)
4022 struct dsa_switch *ds = dev_get_drvdata(&mdiodev->dev); 4237 struct dsa_switch *ds = dev_get_drvdata(&mdiodev->dev);
4023 struct mv88e6xxx_chip *chip = ds->priv; 4238 struct mv88e6xxx_chip *chip = ds->priv;
4024 4239
4240 if (chip->info->ptp_support) {
4241 mv88e6xxx_hwtstamp_free(chip);
4242 mv88e6xxx_ptp_free(chip);
4243 }
4244
4025 mv88e6xxx_phy_destroy(chip); 4245 mv88e6xxx_phy_destroy(chip);
4026 mv88e6xxx_unregister_switch(chip); 4246 mv88e6xxx_unregister_switch(chip);
4027 mv88e6xxx_mdios_unregister(chip); 4247 mv88e6xxx_mdios_unregister(chip);
4028 4248
4029 if (chip->irq > 0) { 4249 mv88e6xxx_g1_vtu_prob_irq_free(chip);
4030 mv88e6xxx_g1_vtu_prob_irq_free(chip); 4250 mv88e6xxx_g1_atu_prob_irq_free(chip);
4031 mv88e6xxx_g1_atu_prob_irq_free(chip); 4251
4032 if (chip->info->g2_irqs > 0) 4252 if (chip->info->g2_irqs > 0)
4033 mv88e6xxx_g2_irq_free(chip); 4253 mv88e6xxx_g2_irq_free(chip);
4034 mutex_lock(&chip->reg_lock); 4254
4255 mutex_lock(&chip->reg_lock);
4256 if (chip->irq > 0)
4035 mv88e6xxx_g1_irq_free(chip); 4257 mv88e6xxx_g1_irq_free(chip);
4036 mutex_unlock(&chip->reg_lock); 4258 else
4037 } 4259 mv88e6xxx_irq_poll_free(chip);
4260 mutex_unlock(&chip->reg_lock);
4038} 4261}
4039 4262
4040static const struct of_device_id mv88e6xxx_of_match[] = { 4263static const struct of_device_id mv88e6xxx_of_match[] = {
diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h
index 3dba6e90adcf..bad211014e91 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.h
+++ b/drivers/net/dsa/mv88e6xxx/chip.h
@@ -15,7 +15,10 @@
15#include <linux/if_vlan.h> 15#include <linux/if_vlan.h>
16#include <linux/irq.h> 16#include <linux/irq.h>
17#include <linux/gpio/consumer.h> 17#include <linux/gpio/consumer.h>
18#include <linux/kthread.h>
18#include <linux/phy.h> 19#include <linux/phy.h>
20#include <linux/ptp_clock_kernel.h>
21#include <linux/timecounter.h>
19#include <net/dsa.h> 22#include <net/dsa.h>
20 23
21#ifndef UINT64_MAX 24#ifndef UINT64_MAX
@@ -39,6 +42,8 @@
39#define MV88E6XXX_MAX_PVT_SWITCHES 32 42#define MV88E6XXX_MAX_PVT_SWITCHES 32
40#define MV88E6XXX_MAX_PVT_PORTS 16 43#define MV88E6XXX_MAX_PVT_PORTS 16
41 44
45#define MV88E6XXX_MAX_GPIO 16
46
42enum mv88e6xxx_egress_mode { 47enum mv88e6xxx_egress_mode {
43 MV88E6XXX_EGRESS_MODE_UNMODIFIED, 48 MV88E6XXX_EGRESS_MODE_UNMODIFIED,
44 MV88E6XXX_EGRESS_MODE_UNTAGGED, 49 MV88E6XXX_EGRESS_MODE_UNTAGGED,
@@ -105,6 +110,8 @@ struct mv88e6xxx_info {
105 const char *name; 110 const char *name;
106 unsigned int num_databases; 111 unsigned int num_databases;
107 unsigned int num_ports; 112 unsigned int num_ports;
113 unsigned int num_internal_phys;
114 unsigned int num_gpio;
108 unsigned int max_vid; 115 unsigned int max_vid;
109 unsigned int port_base_addr; 116 unsigned int port_base_addr;
110 unsigned int global1_addr; 117 unsigned int global1_addr;
@@ -126,6 +133,9 @@ struct mv88e6xxx_info {
126 */ 133 */
127 u8 atu_move_port_mask; 134 u8 atu_move_port_mask;
128 const struct mv88e6xxx_ops *ops; 135 const struct mv88e6xxx_ops *ops;
136
137 /* Supports PTP */
138 bool ptp_support;
129}; 139};
130 140
131struct mv88e6xxx_atu_entry { 141struct mv88e6xxx_atu_entry {
@@ -146,6 +156,8 @@ struct mv88e6xxx_vtu_entry {
146 156
147struct mv88e6xxx_bus_ops; 157struct mv88e6xxx_bus_ops;
148struct mv88e6xxx_irq_ops; 158struct mv88e6xxx_irq_ops;
159struct mv88e6xxx_gpio_ops;
160struct mv88e6xxx_avb_ops;
149 161
150struct mv88e6xxx_irq { 162struct mv88e6xxx_irq {
151 u16 masked; 163 u16 masked;
@@ -154,6 +166,36 @@ struct mv88e6xxx_irq {
154 unsigned int nirqs; 166 unsigned int nirqs;
155}; 167};
156 168
169/* state flags for mv88e6xxx_port_hwtstamp::state */
170enum {
171 MV88E6XXX_HWTSTAMP_ENABLED,
172 MV88E6XXX_HWTSTAMP_TX_IN_PROGRESS,
173};
174
175struct mv88e6xxx_port_hwtstamp {
176 /* Port index */
177 int port_id;
178
179 /* Timestamping state */
180 unsigned long state;
181
182 /* Resources for receive timestamping */
183 struct sk_buff_head rx_queue;
184 struct sk_buff_head rx_queue2;
185
186 /* Resources for transmit timestamping */
187 unsigned long tx_tstamp_start;
188 struct sk_buff *tx_skb;
189 u16 tx_seq_id;
190
191 /* Current timestamp configuration */
192 struct hwtstamp_config tstamp_config;
193};
194
195struct mv88e6xxx_port {
196 u64 serdes_stats[2];
197};
198
157struct mv88e6xxx_chip { 199struct mv88e6xxx_chip {
158 const struct mv88e6xxx_info *info; 200 const struct mv88e6xxx_info *info;
159 201
@@ -207,8 +249,34 @@ struct mv88e6xxx_chip {
207 int irq; 249 int irq;
208 int device_irq; 250 int device_irq;
209 int watchdog_irq; 251 int watchdog_irq;
252
210 int atu_prob_irq; 253 int atu_prob_irq;
211 int vtu_prob_irq; 254 int vtu_prob_irq;
255 struct kthread_worker *kworker;
256 struct kthread_delayed_work irq_poll_work;
257
258 /* GPIO resources */
259 u8 gpio_data[2];
260
261 /* This cyclecounter abstracts the switch PTP time.
262 * reg_lock must be held for any operation that read()s.
263 */
264 struct cyclecounter tstamp_cc;
265 struct timecounter tstamp_tc;
266 struct delayed_work overflow_work;
267
268 struct ptp_clock *ptp_clock;
269 struct ptp_clock_info ptp_clock_info;
270 struct delayed_work tai_event_work;
271 struct ptp_pin_desc pin_config[MV88E6XXX_MAX_GPIO];
272 u16 trig_config;
273 u16 evcap_config;
274
275 /* Per-port timestamping resources. */
276 struct mv88e6xxx_port_hwtstamp port_hwtstamp[DSA_MAX_PORTS];
277
278 /* Array of port structures. */
279 struct mv88e6xxx_port ports[DSA_MAX_PORTS];
212}; 280};
213 281
214struct mv88e6xxx_bus_ops { 282struct mv88e6xxx_bus_ops {
@@ -327,9 +395,9 @@ struct mv88e6xxx_ops {
327 395
328 /* Return the number of strings describing statistics */ 396 /* Return the number of strings describing statistics */
329 int (*stats_get_sset_count)(struct mv88e6xxx_chip *chip); 397 int (*stats_get_sset_count)(struct mv88e6xxx_chip *chip);
330 void (*stats_get_strings)(struct mv88e6xxx_chip *chip, uint8_t *data); 398 int (*stats_get_strings)(struct mv88e6xxx_chip *chip, uint8_t *data);
331 void (*stats_get_stats)(struct mv88e6xxx_chip *chip, int port, 399 int (*stats_get_stats)(struct mv88e6xxx_chip *chip, int port,
332 uint64_t *data); 400 uint64_t *data);
333 int (*set_cpu_port)(struct mv88e6xxx_chip *chip, int port); 401 int (*set_cpu_port)(struct mv88e6xxx_chip *chip, int port);
334 int (*set_egress_port)(struct mv88e6xxx_chip *chip, int port); 402 int (*set_egress_port)(struct mv88e6xxx_chip *chip, int port);
335 const struct mv88e6xxx_irq_ops *watchdog_ops; 403 const struct mv88e6xxx_irq_ops *watchdog_ops;
@@ -339,11 +407,24 @@ struct mv88e6xxx_ops {
339 /* Power on/off a SERDES interface */ 407 /* Power on/off a SERDES interface */
340 int (*serdes_power)(struct mv88e6xxx_chip *chip, int port, bool on); 408 int (*serdes_power)(struct mv88e6xxx_chip *chip, int port, bool on);
341 409
410 /* Statistics from the SERDES interface */
411 int (*serdes_get_sset_count)(struct mv88e6xxx_chip *chip, int port);
412 void (*serdes_get_strings)(struct mv88e6xxx_chip *chip, int port,
413 uint8_t *data);
414 void (*serdes_get_stats)(struct mv88e6xxx_chip *chip, int port,
415 uint64_t *data);
416
342 /* VLAN Translation Unit operations */ 417 /* VLAN Translation Unit operations */
343 int (*vtu_getnext)(struct mv88e6xxx_chip *chip, 418 int (*vtu_getnext)(struct mv88e6xxx_chip *chip,
344 struct mv88e6xxx_vtu_entry *entry); 419 struct mv88e6xxx_vtu_entry *entry);
345 int (*vtu_loadpurge)(struct mv88e6xxx_chip *chip, 420 int (*vtu_loadpurge)(struct mv88e6xxx_chip *chip,
346 struct mv88e6xxx_vtu_entry *entry); 421 struct mv88e6xxx_vtu_entry *entry);
422
423 /* GPIO operations */
424 const struct mv88e6xxx_gpio_ops *gpio_ops;
425
426 /* Interface to the AVB/PTP registers */
427 const struct mv88e6xxx_avb_ops *avb_ops;
347}; 428};
348 429
349struct mv88e6xxx_irq_ops { 430struct mv88e6xxx_irq_ops {
@@ -355,13 +436,49 @@ struct mv88e6xxx_irq_ops {
355 void (*irq_free)(struct mv88e6xxx_chip *chip); 436 void (*irq_free)(struct mv88e6xxx_chip *chip);
356}; 437};
357 438
439struct mv88e6xxx_gpio_ops {
440 /* Get/set data on GPIO pin */
441 int (*get_data)(struct mv88e6xxx_chip *chip, unsigned int pin);
442 int (*set_data)(struct mv88e6xxx_chip *chip, unsigned int pin,
443 int value);
444
445 /* get/set GPIO direction */
446 int (*get_dir)(struct mv88e6xxx_chip *chip, unsigned int pin);
447 int (*set_dir)(struct mv88e6xxx_chip *chip, unsigned int pin,
448 bool input);
449
450 /* get/set GPIO pin control */
451 int (*get_pctl)(struct mv88e6xxx_chip *chip, unsigned int pin,
452 int *func);
453 int (*set_pctl)(struct mv88e6xxx_chip *chip, unsigned int pin,
454 int func);
455};
456
457struct mv88e6xxx_avb_ops {
458 /* Access port-scoped Precision Time Protocol registers */
459 int (*port_ptp_read)(struct mv88e6xxx_chip *chip, int port, int addr,
460 u16 *data, int len);
461 int (*port_ptp_write)(struct mv88e6xxx_chip *chip, int port, int addr,
462 u16 data);
463
464 /* Access global Precision Time Protocol registers */
465 int (*ptp_read)(struct mv88e6xxx_chip *chip, int addr, u16 *data,
466 int len);
467 int (*ptp_write)(struct mv88e6xxx_chip *chip, int addr, u16 data);
468
469 /* Access global Time Application Interface registers */
470 int (*tai_read)(struct mv88e6xxx_chip *chip, int addr, u16 *data,
471 int len);
472 int (*tai_write)(struct mv88e6xxx_chip *chip, int addr, u16 data);
473};
474
358#define STATS_TYPE_PORT BIT(0) 475#define STATS_TYPE_PORT BIT(0)
359#define STATS_TYPE_BANK0 BIT(1) 476#define STATS_TYPE_BANK0 BIT(1)
360#define STATS_TYPE_BANK1 BIT(2) 477#define STATS_TYPE_BANK1 BIT(2)
361 478
362struct mv88e6xxx_hw_stat { 479struct mv88e6xxx_hw_stat {
363 char string[ETH_GSTRING_LEN]; 480 char string[ETH_GSTRING_LEN];
364 int sizeof_stat; 481 size_t size;
365 int reg; 482 int reg;
366 int type; 483 int type;
367}; 484};
@@ -386,6 +503,11 @@ static inline u16 mv88e6xxx_port_mask(struct mv88e6xxx_chip *chip)
386 return GENMASK(mv88e6xxx_num_ports(chip) - 1, 0); 503 return GENMASK(mv88e6xxx_num_ports(chip) - 1, 0);
387} 504}
388 505
506static inline unsigned int mv88e6xxx_num_gpio(struct mv88e6xxx_chip *chip)
507{
508 return chip->info->num_gpio;
509}
510
389int mv88e6xxx_read(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val); 511int mv88e6xxx_read(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val);
390int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val); 512int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val);
391int mv88e6xxx_update(struct mv88e6xxx_chip *chip, int addr, int reg, 513int mv88e6xxx_update(struct mv88e6xxx_chip *chip, int addr, int reg,
diff --git a/drivers/net/dsa/mv88e6xxx/global2.c b/drivers/net/dsa/mv88e6xxx/global2.c
index af0727877825..0ce627fded48 100644
--- a/drivers/net/dsa/mv88e6xxx/global2.c
+++ b/drivers/net/dsa/mv88e6xxx/global2.c
@@ -20,22 +20,22 @@
20#include "global1.h" /* for MV88E6XXX_G1_STS_IRQ_DEVICE */ 20#include "global1.h" /* for MV88E6XXX_G1_STS_IRQ_DEVICE */
21#include "global2.h" 21#include "global2.h"
22 22
23static int mv88e6xxx_g2_read(struct mv88e6xxx_chip *chip, int reg, u16 *val) 23int mv88e6xxx_g2_read(struct mv88e6xxx_chip *chip, int reg, u16 *val)
24{ 24{
25 return mv88e6xxx_read(chip, chip->info->global2_addr, reg, val); 25 return mv88e6xxx_read(chip, chip->info->global2_addr, reg, val);
26} 26}
27 27
28static int mv88e6xxx_g2_write(struct mv88e6xxx_chip *chip, int reg, u16 val) 28int mv88e6xxx_g2_write(struct mv88e6xxx_chip *chip, int reg, u16 val)
29{ 29{
30 return mv88e6xxx_write(chip, chip->info->global2_addr, reg, val); 30 return mv88e6xxx_write(chip, chip->info->global2_addr, reg, val);
31} 31}
32 32
33static int mv88e6xxx_g2_update(struct mv88e6xxx_chip *chip, int reg, u16 update) 33int mv88e6xxx_g2_update(struct mv88e6xxx_chip *chip, int reg, u16 update)
34{ 34{
35 return mv88e6xxx_update(chip, chip->info->global2_addr, reg, update); 35 return mv88e6xxx_update(chip, chip->info->global2_addr, reg, update);
36} 36}
37 37
38static int mv88e6xxx_g2_wait(struct mv88e6xxx_chip *chip, int reg, u16 mask) 38int mv88e6xxx_g2_wait(struct mv88e6xxx_chip *chip, int reg, u16 mask)
39{ 39{
40 return mv88e6xxx_wait(chip, chip->info->global2_addr, reg, mask); 40 return mv88e6xxx_wait(chip, chip->info->global2_addr, reg, mask);
41} 41}
@@ -798,6 +798,7 @@ int mv88e6xxx_g2_smi_phy_write(struct mv88e6xxx_chip *chip, struct mii_bus *bus,
798 val); 798 val);
799} 799}
800 800
801/* Offset 0x1B: Watchdog Control */
801static int mv88e6097_watchdog_action(struct mv88e6xxx_chip *chip, int irq) 802static int mv88e6097_watchdog_action(struct mv88e6xxx_chip *chip, int irq)
802{ 803{
803 u16 reg; 804 u16 reg;
@@ -1089,7 +1090,7 @@ int mv88e6xxx_g2_irq_setup(struct mv88e6xxx_chip *chip)
1089 1090
1090 err = request_threaded_irq(chip->device_irq, NULL, 1091 err = request_threaded_irq(chip->device_irq, NULL,
1091 mv88e6xxx_g2_irq_thread_fn, 1092 mv88e6xxx_g2_irq_thread_fn,
1092 IRQF_ONESHOT, "mv88e6xxx-g1", chip); 1093 IRQF_ONESHOT, "mv88e6xxx-g2", chip);
1093 if (err) 1094 if (err)
1094 goto out; 1095 goto out;
1095 1096
@@ -1106,6 +1107,38 @@ out:
1106 return err; 1107 return err;
1107} 1108}
1108 1109
1110int mv88e6xxx_g2_irq_mdio_setup(struct mv88e6xxx_chip *chip,
1111 struct mii_bus *bus)
1112{
1113 int phy, irq, err, err_phy;
1114
1115 for (phy = 0; phy < chip->info->num_internal_phys; phy++) {
1116 irq = irq_find_mapping(chip->g2_irq.domain, phy);
1117 if (irq < 0) {
1118 err = irq;
1119 goto out;
1120 }
1121 bus->irq[chip->info->port_base_addr + phy] = irq;
1122 }
1123 return 0;
1124out:
1125 err_phy = phy;
1126
1127 for (phy = 0; phy < err_phy; phy++)
1128 irq_dispose_mapping(bus->irq[phy]);
1129
1130 return err;
1131}
1132
1133void mv88e6xxx_g2_irq_mdio_free(struct mv88e6xxx_chip *chip,
1134 struct mii_bus *bus)
1135{
1136 int phy;
1137
1138 for (phy = 0; phy < chip->info->num_internal_phys; phy++)
1139 irq_dispose_mapping(bus->irq[phy]);
1140}
1141
1109int mv88e6xxx_g2_setup(struct mv88e6xxx_chip *chip) 1142int mv88e6xxx_g2_setup(struct mv88e6xxx_chip *chip)
1110{ 1143{
1111 u16 reg; 1144 u16 reg;
diff --git a/drivers/net/dsa/mv88e6xxx/global2.h b/drivers/net/dsa/mv88e6xxx/global2.h
index 669f59017b12..520ec70d32e8 100644
--- a/drivers/net/dsa/mv88e6xxx/global2.h
+++ b/drivers/net/dsa/mv88e6xxx/global2.h
@@ -149,7 +149,26 @@
149#define MV88E6390_G2_EEPROM_ADDR_MASK 0xffff 149#define MV88E6390_G2_EEPROM_ADDR_MASK 0xffff
150 150
151/* Offset 0x16: AVB Command Register */ 151/* Offset 0x16: AVB Command Register */
152#define MV88E6352_G2_AVB_CMD 0x16 152#define MV88E6352_G2_AVB_CMD 0x16
153#define MV88E6352_G2_AVB_CMD_BUSY 0x8000
154#define MV88E6352_G2_AVB_CMD_OP_READ 0x4000
155#define MV88E6352_G2_AVB_CMD_OP_READ_INCR 0x6000
156#define MV88E6352_G2_AVB_CMD_OP_WRITE 0x3000
157#define MV88E6390_G2_AVB_CMD_OP_READ 0x0000
158#define MV88E6390_G2_AVB_CMD_OP_READ_INCR 0x4000
159#define MV88E6390_G2_AVB_CMD_OP_WRITE 0x6000
160#define MV88E6352_G2_AVB_CMD_PORT_MASK 0x0f00
161#define MV88E6352_G2_AVB_CMD_PORT_TAIGLOBAL 0xe
162#define MV88E6352_G2_AVB_CMD_PORT_PTPGLOBAL 0xf
163#define MV88E6390_G2_AVB_CMD_PORT_MASK 0x1f00
164#define MV88E6390_G2_AVB_CMD_PORT_TAIGLOBAL 0x1e
165#define MV88E6390_G2_AVB_CMD_PORT_PTPGLOBAL 0x1f
166#define MV88E6352_G2_AVB_CMD_BLOCK_PTP 0
167#define MV88E6352_G2_AVB_CMD_BLOCK_AVB 1
168#define MV88E6352_G2_AVB_CMD_BLOCK_QAV 2
169#define MV88E6352_G2_AVB_CMD_BLOCK_QVB 3
170#define MV88E6352_G2_AVB_CMD_BLOCK_MASK 0x00e0
171#define MV88E6352_G2_AVB_CMD_ADDR_MASK 0x001f
153 172
154/* Offset 0x17: AVB Data Register */ 173/* Offset 0x17: AVB Data Register */
155#define MV88E6352_G2_AVB_DATA 0x17 174#define MV88E6352_G2_AVB_DATA 0x17
@@ -223,6 +242,40 @@
223#define MV88E6352_G2_NOEGR_POLICY 0x2000 242#define MV88E6352_G2_NOEGR_POLICY 0x2000
224#define MV88E6390_G2_LAG_ID_4 0x2000 243#define MV88E6390_G2_LAG_ID_4 0x2000
225 244
245/* Scratch/Misc registers accessed through MV88E6XXX_G2_SCRATCH_MISC */
246/* Offset 0x02: Misc Configuration */
247#define MV88E6352_G2_SCRATCH_MISC_CFG 0x02
248#define MV88E6352_G2_SCRATCH_MISC_CFG_NORMALSMI 0x80
249/* Offset 0x60-0x61: GPIO Configuration */
250#define MV88E6352_G2_SCRATCH_GPIO_CFG0 0x60
251#define MV88E6352_G2_SCRATCH_GPIO_CFG1 0x61
252/* Offset 0x62-0x63: GPIO Direction */
253#define MV88E6352_G2_SCRATCH_GPIO_DIR0 0x62
254#define MV88E6352_G2_SCRATCH_GPIO_DIR1 0x63
255#define MV88E6352_G2_SCRATCH_GPIO_DIR_OUT 0
256#define MV88E6352_G2_SCRATCH_GPIO_DIR_IN 1
257/* Offset 0x64-0x65: GPIO Data */
258#define MV88E6352_G2_SCRATCH_GPIO_DATA0 0x64
259#define MV88E6352_G2_SCRATCH_GPIO_DATA1 0x65
260/* Offset 0x68-0x6F: GPIO Pin Control */
261#define MV88E6352_G2_SCRATCH_GPIO_PCTL0 0x68
262#define MV88E6352_G2_SCRATCH_GPIO_PCTL1 0x69
263#define MV88E6352_G2_SCRATCH_GPIO_PCTL2 0x6A
264#define MV88E6352_G2_SCRATCH_GPIO_PCTL3 0x6B
265#define MV88E6352_G2_SCRATCH_GPIO_PCTL4 0x6C
266#define MV88E6352_G2_SCRATCH_GPIO_PCTL5 0x6D
267#define MV88E6352_G2_SCRATCH_GPIO_PCTL6 0x6E
268#define MV88E6352_G2_SCRATCH_GPIO_PCTL7 0x6F
269#define MV88E6352_G2_SCRATCH_CONFIG_DATA0 0x70
270#define MV88E6352_G2_SCRATCH_CONFIG_DATA1 0x71
271#define MV88E6352_G2_SCRATCH_CONFIG_DATA1_NO_CPU BIT(2)
272#define MV88E6352_G2_SCRATCH_CONFIG_DATA2 0x72
273#define MV88E6352_G2_SCRATCH_CONFIG_DATA2_P0_MODE_MASK 0x3
274
275#define MV88E6352_G2_SCRATCH_GPIO_PCTL_GPIO 0
276#define MV88E6352_G2_SCRATCH_GPIO_PCTL_TRIG 1
277#define MV88E6352_G2_SCRATCH_GPIO_PCTL_EVREQ 2
278
226#ifdef CONFIG_NET_DSA_MV88E6XXX_GLOBAL2 279#ifdef CONFIG_NET_DSA_MV88E6XXX_GLOBAL2
227 280
228static inline int mv88e6xxx_g2_require(struct mv88e6xxx_chip *chip) 281static inline int mv88e6xxx_g2_require(struct mv88e6xxx_chip *chip)
@@ -230,6 +283,11 @@ static inline int mv88e6xxx_g2_require(struct mv88e6xxx_chip *chip)
230 return 0; 283 return 0;
231} 284}
232 285
286int mv88e6xxx_g2_read(struct mv88e6xxx_chip *chip, int reg, u16 *val);
287int mv88e6xxx_g2_write(struct mv88e6xxx_chip *chip, int reg, u16 val);
288int mv88e6xxx_g2_update(struct mv88e6xxx_chip *chip, int reg, u16 update);
289int mv88e6xxx_g2_wait(struct mv88e6xxx_chip *chip, int reg, u16 mask);
290
233int mv88e6352_g2_irl_init_all(struct mv88e6xxx_chip *chip, int port); 291int mv88e6352_g2_irl_init_all(struct mv88e6xxx_chip *chip, int port);
234int mv88e6390_g2_irl_init_all(struct mv88e6xxx_chip *chip, int port); 292int mv88e6390_g2_irl_init_all(struct mv88e6xxx_chip *chip, int port);
235 293
@@ -259,6 +317,11 @@ int mv88e6xxx_g2_setup(struct mv88e6xxx_chip *chip);
259int mv88e6xxx_g2_irq_setup(struct mv88e6xxx_chip *chip); 317int mv88e6xxx_g2_irq_setup(struct mv88e6xxx_chip *chip);
260void mv88e6xxx_g2_irq_free(struct mv88e6xxx_chip *chip); 318void mv88e6xxx_g2_irq_free(struct mv88e6xxx_chip *chip);
261 319
320int mv88e6xxx_g2_irq_mdio_setup(struct mv88e6xxx_chip *chip,
321 struct mii_bus *bus);
322void mv88e6xxx_g2_irq_mdio_free(struct mv88e6xxx_chip *chip,
323 struct mii_bus *bus);
324
262int mv88e6185_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip); 325int mv88e6185_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip);
263int mv88e6352_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip); 326int mv88e6352_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip);
264 327
@@ -267,6 +330,14 @@ int mv88e6xxx_g2_pot_clear(struct mv88e6xxx_chip *chip);
267extern const struct mv88e6xxx_irq_ops mv88e6097_watchdog_ops; 330extern const struct mv88e6xxx_irq_ops mv88e6097_watchdog_ops;
268extern const struct mv88e6xxx_irq_ops mv88e6390_watchdog_ops; 331extern const struct mv88e6xxx_irq_ops mv88e6390_watchdog_ops;
269 332
333extern const struct mv88e6xxx_avb_ops mv88e6352_avb_ops;
334extern const struct mv88e6xxx_avb_ops mv88e6390_avb_ops;
335
336extern const struct mv88e6xxx_gpio_ops mv88e6352_gpio_ops;
337
338int mv88e6xxx_g2_scratch_gpio_set_smi(struct mv88e6xxx_chip *chip,
339 bool external);
340
270#else /* !CONFIG_NET_DSA_MV88E6XXX_GLOBAL2 */ 341#else /* !CONFIG_NET_DSA_MV88E6XXX_GLOBAL2 */
271 342
272static inline int mv88e6xxx_g2_require(struct mv88e6xxx_chip *chip) 343static inline int mv88e6xxx_g2_require(struct mv88e6xxx_chip *chip)
@@ -279,6 +350,26 @@ static inline int mv88e6xxx_g2_require(struct mv88e6xxx_chip *chip)
279 return 0; 350 return 0;
280} 351}
281 352
353static inline int mv88e6xxx_g2_read(struct mv88e6xxx_chip *chip, int reg, u16 *val)
354{
355 return -EOPNOTSUPP;
356}
357
358static inline int mv88e6xxx_g2_write(struct mv88e6xxx_chip *chip, int reg, u16 val)
359{
360 return -EOPNOTSUPP;
361}
362
363static inline int mv88e6xxx_g2_update(struct mv88e6xxx_chip *chip, int reg, u16 update)
364{
365 return -EOPNOTSUPP;
366}
367
368static inline int mv88e6xxx_g2_wait(struct mv88e6xxx_chip *chip, int reg, u16 mask)
369{
370 return -EOPNOTSUPP;
371}
372
282static inline int mv88e6352_g2_irl_init_all(struct mv88e6xxx_chip *chip, 373static inline int mv88e6352_g2_irl_init_all(struct mv88e6xxx_chip *chip,
283 int port) 374 int port)
284{ 375{
@@ -364,6 +455,17 @@ static inline void mv88e6xxx_g2_irq_free(struct mv88e6xxx_chip *chip)
364{ 455{
365} 456}
366 457
458static inline int mv88e6xxx_g2_irq_mdio_setup(struct mv88e6xxx_chip *chip,
459 struct mii_bus *bus)
460{
461 return 0;
462}
463
464static inline void mv88e6xxx_g2_irq_mdio_free(struct mv88e6xxx_chip *chip,
465 struct mii_bus *bus)
466{
467}
468
367static inline int mv88e6185_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip) 469static inline int mv88e6185_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip)
368{ 470{
369 return -EOPNOTSUPP; 471 return -EOPNOTSUPP;
@@ -382,6 +484,17 @@ static inline int mv88e6xxx_g2_pot_clear(struct mv88e6xxx_chip *chip)
382static const struct mv88e6xxx_irq_ops mv88e6097_watchdog_ops = {}; 484static const struct mv88e6xxx_irq_ops mv88e6097_watchdog_ops = {};
383static const struct mv88e6xxx_irq_ops mv88e6390_watchdog_ops = {}; 485static const struct mv88e6xxx_irq_ops mv88e6390_watchdog_ops = {};
384 486
487static const struct mv88e6xxx_avb_ops mv88e6352_avb_ops = {};
488static const struct mv88e6xxx_avb_ops mv88e6390_avb_ops = {};
489
490static const struct mv88e6xxx_gpio_ops mv88e6352_gpio_ops = {};
491
492static inline int mv88e6xxx_g2_scratch_gpio_set_smi(struct mv88e6xxx_chip *chip,
493 bool external)
494{
495 return -EOPNOTSUPP;
496}
497
385#endif /* CONFIG_NET_DSA_MV88E6XXX_GLOBAL2 */ 498#endif /* CONFIG_NET_DSA_MV88E6XXX_GLOBAL2 */
386 499
387#endif /* _MV88E6XXX_GLOBAL2_H */ 500#endif /* _MV88E6XXX_GLOBAL2_H */
diff --git a/drivers/net/dsa/mv88e6xxx/global2_avb.c b/drivers/net/dsa/mv88e6xxx/global2_avb.c
new file mode 100644
index 000000000000..2e398ccb88ca
--- /dev/null
+++ b/drivers/net/dsa/mv88e6xxx/global2_avb.c
@@ -0,0 +1,193 @@
1/*
2 * Marvell 88E6xxx Switch Global 2 Registers support
3 *
4 * Copyright (c) 2008 Marvell Semiconductor
5 *
6 * Copyright (c) 2016-2017 Savoir-faire Linux Inc.
7 * Vivien Didelot <vivien.didelot@savoirfairelinux.com>
8 *
9 * Copyright (c) 2017 National Instruments
10 * Brandon Streiff <brandon.streiff@ni.com>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 */
17
18#include "global2.h"
19
20/* Offset 0x16: AVB Command Register
21 * Offset 0x17: AVB Data Register
22 *
23 * There are two different versions of this register interface:
24 * "6352": 3-bit "op" field, 4-bit "port" field.
25 * "6390": 2-bit "op" field, 5-bit "port" field.
26 *
27 * The "op" codes are different between the two, as well as the special
28 * port fields for global PTP and TAI configuration.
29 */
30
31/* mv88e6xxx_g2_avb_read -- Read one or multiple 16-bit words.
32 * The hardware supports snapshotting up to four contiguous registers.
33 */
34static int mv88e6xxx_g2_avb_read(struct mv88e6xxx_chip *chip, u16 readop,
35 u16 *data, int len)
36{
37 int err;
38 int i;
39
40 /* Hardware can only snapshot four words. */
41 if (len > 4)
42 return -E2BIG;
43
44 err = mv88e6xxx_g2_update(chip, MV88E6352_G2_AVB_CMD, readop);
45 if (err)
46 return err;
47
48 for (i = 0; i < len; ++i) {
49 err = mv88e6xxx_g2_read(chip, MV88E6352_G2_AVB_DATA,
50 &data[i]);
51 if (err)
52 return err;
53 }
54
55 return 0;
56}
57
58/* mv88e6xxx_g2_avb_write -- Write one 16-bit word. */
59static int mv88e6xxx_g2_avb_write(struct mv88e6xxx_chip *chip, u16 writeop,
60 u16 data)
61{
62 int err;
63
64 err = mv88e6xxx_g2_write(chip, MV88E6352_G2_AVB_DATA, data);
65 if (err)
66 return err;
67
68 return mv88e6xxx_g2_update(chip, MV88E6352_G2_AVB_CMD, writeop);
69}
70
71static int mv88e6352_g2_avb_port_ptp_read(struct mv88e6xxx_chip *chip,
72 int port, int addr, u16 *data,
73 int len)
74{
75 u16 readop = (len == 1 ? MV88E6352_G2_AVB_CMD_OP_READ :
76 MV88E6352_G2_AVB_CMD_OP_READ_INCR) |
77 (port << 8) | (MV88E6352_G2_AVB_CMD_BLOCK_PTP << 5) |
78 addr;
79
80 return mv88e6xxx_g2_avb_read(chip, readop, data, len);
81}
82
83static int mv88e6352_g2_avb_port_ptp_write(struct mv88e6xxx_chip *chip,
84 int port, int addr, u16 data)
85{
86 u16 writeop = MV88E6352_G2_AVB_CMD_OP_WRITE | (port << 8) |
87 (MV88E6352_G2_AVB_CMD_BLOCK_PTP << 5) | addr;
88
89 return mv88e6xxx_g2_avb_write(chip, writeop, data);
90}
91
92static int mv88e6352_g2_avb_ptp_read(struct mv88e6xxx_chip *chip, int addr,
93 u16 *data, int len)
94{
95 return mv88e6352_g2_avb_port_ptp_read(chip,
96 MV88E6352_G2_AVB_CMD_PORT_PTPGLOBAL,
97 addr, data, len);
98}
99
100static int mv88e6352_g2_avb_ptp_write(struct mv88e6xxx_chip *chip, int addr,
101 u16 data)
102{
103 return mv88e6352_g2_avb_port_ptp_write(chip,
104 MV88E6352_G2_AVB_CMD_PORT_PTPGLOBAL,
105 addr, data);
106}
107
108static int mv88e6352_g2_avb_tai_read(struct mv88e6xxx_chip *chip, int addr,
109 u16 *data, int len)
110{
111 return mv88e6352_g2_avb_port_ptp_read(chip,
112 MV88E6352_G2_AVB_CMD_PORT_TAIGLOBAL,
113 addr, data, len);
114}
115
116static int mv88e6352_g2_avb_tai_write(struct mv88e6xxx_chip *chip, int addr,
117 u16 data)
118{
119 return mv88e6352_g2_avb_port_ptp_write(chip,
120 MV88E6352_G2_AVB_CMD_PORT_TAIGLOBAL,
121 addr, data);
122}
123
124const struct mv88e6xxx_avb_ops mv88e6352_avb_ops = {
125 .port_ptp_read = mv88e6352_g2_avb_port_ptp_read,
126 .port_ptp_write = mv88e6352_g2_avb_port_ptp_write,
127 .ptp_read = mv88e6352_g2_avb_ptp_read,
128 .ptp_write = mv88e6352_g2_avb_ptp_write,
129 .tai_read = mv88e6352_g2_avb_tai_read,
130 .tai_write = mv88e6352_g2_avb_tai_write,
131};
132
133static int mv88e6390_g2_avb_port_ptp_read(struct mv88e6xxx_chip *chip,
134 int port, int addr, u16 *data,
135 int len)
136{
137 u16 readop = (len == 1 ? MV88E6390_G2_AVB_CMD_OP_READ :
138 MV88E6390_G2_AVB_CMD_OP_READ_INCR) |
139 (port << 8) | (MV88E6352_G2_AVB_CMD_BLOCK_PTP << 5) |
140 addr;
141
142 return mv88e6xxx_g2_avb_read(chip, readop, data, len);
143}
144
145static int mv88e6390_g2_avb_port_ptp_write(struct mv88e6xxx_chip *chip,
146 int port, int addr, u16 data)
147{
148 u16 writeop = MV88E6390_G2_AVB_CMD_OP_WRITE | (port << 8) |
149 (MV88E6352_G2_AVB_CMD_BLOCK_PTP << 5) | addr;
150
151 return mv88e6xxx_g2_avb_write(chip, writeop, data);
152}
153
154static int mv88e6390_g2_avb_ptp_read(struct mv88e6xxx_chip *chip, int addr,
155 u16 *data, int len)
156{
157 return mv88e6390_g2_avb_port_ptp_read(chip,
158 MV88E6390_G2_AVB_CMD_PORT_PTPGLOBAL,
159 addr, data, len);
160}
161
162static int mv88e6390_g2_avb_ptp_write(struct mv88e6xxx_chip *chip, int addr,
163 u16 data)
164{
165 return mv88e6390_g2_avb_port_ptp_write(chip,
166 MV88E6390_G2_AVB_CMD_PORT_PTPGLOBAL,
167 addr, data);
168}
169
170static int mv88e6390_g2_avb_tai_read(struct mv88e6xxx_chip *chip, int addr,
171 u16 *data, int len)
172{
173 return mv88e6390_g2_avb_port_ptp_read(chip,
174 MV88E6390_G2_AVB_CMD_PORT_TAIGLOBAL,
175 addr, data, len);
176}
177
178static int mv88e6390_g2_avb_tai_write(struct mv88e6xxx_chip *chip, int addr,
179 u16 data)
180{
181 return mv88e6390_g2_avb_port_ptp_write(chip,
182 MV88E6390_G2_AVB_CMD_PORT_TAIGLOBAL,
183 addr, data);
184}
185
186const struct mv88e6xxx_avb_ops mv88e6390_avb_ops = {
187 .port_ptp_read = mv88e6390_g2_avb_port_ptp_read,
188 .port_ptp_write = mv88e6390_g2_avb_port_ptp_write,
189 .ptp_read = mv88e6390_g2_avb_ptp_read,
190 .ptp_write = mv88e6390_g2_avb_ptp_write,
191 .tai_read = mv88e6390_g2_avb_tai_read,
192 .tai_write = mv88e6390_g2_avb_tai_write,
193};
diff --git a/drivers/net/dsa/mv88e6xxx/global2_scratch.c b/drivers/net/dsa/mv88e6xxx/global2_scratch.c
new file mode 100644
index 000000000000..3f92b8892dc7
--- /dev/null
+++ b/drivers/net/dsa/mv88e6xxx/global2_scratch.c
@@ -0,0 +1,291 @@
1/*
2 * Marvell 88E6xxx Switch Global 2 Scratch & Misc Registers support
3 *
4 * Copyright (c) 2008 Marvell Semiconductor
5 *
6 * Copyright (c) 2017 National Instruments
7 * Brandon Streiff <brandon.streiff@ni.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 */
14
15#include "chip.h"
16#include "global2.h"
17
18/* Offset 0x1A: Scratch and Misc. Register */
19static int mv88e6xxx_g2_scratch_read(struct mv88e6xxx_chip *chip, int reg,
20 u8 *data)
21{
22 u16 value;
23 int err;
24
25 err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SCRATCH_MISC_MISC,
26 reg << 8);
27 if (err)
28 return err;
29
30 err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_SCRATCH_MISC_MISC, &value);
31 if (err)
32 return err;
33
34 *data = (value & MV88E6XXX_G2_SCRATCH_MISC_DATA_MASK);
35
36 return 0;
37}
38
39static int mv88e6xxx_g2_scratch_write(struct mv88e6xxx_chip *chip, int reg,
40 u8 data)
41{
42 u16 value = (reg << 8) | data;
43
44 return mv88e6xxx_g2_update(chip, MV88E6XXX_G2_SCRATCH_MISC_MISC, value);
45}
46
47/**
48 * mv88e6xxx_g2_scratch_gpio_get_bit - get a bit
49 * @chip: chip private data
50 * @nr: bit index
51 * @set: is bit set?
52 */
53static int mv88e6xxx_g2_scratch_get_bit(struct mv88e6xxx_chip *chip,
54 int base_reg, unsigned int offset,
55 int *set)
56{
57 int reg = base_reg + (offset / 8);
58 u8 mask = (1 << (offset & 0x7));
59 u8 val;
60 int err;
61
62 err = mv88e6xxx_g2_scratch_read(chip, reg, &val);
63 if (err)
64 return err;
65
66 *set = !!(mask & val);
67
68 return 0;
69}
70
71/**
72 * mv88e6xxx_g2_scratch_gpio_set_bit - set (or clear) a bit
73 * @chip: chip private data
74 * @nr: bit index
75 * @set: set if true, clear if false
76 *
77 * Helper function for dealing with the direction and data registers.
78 */
79static int mv88e6xxx_g2_scratch_set_bit(struct mv88e6xxx_chip *chip,
80 int base_reg, unsigned int offset,
81 int set)
82{
83 int reg = base_reg + (offset / 8);
84 u8 mask = (1 << (offset & 0x7));
85 u8 val;
86 int err;
87
88 err = mv88e6xxx_g2_scratch_read(chip, reg, &val);
89 if (err)
90 return err;
91
92 if (set)
93 val |= mask;
94 else
95 val &= ~mask;
96
97 return mv88e6xxx_g2_scratch_write(chip, reg, val);
98}
99
100/**
101 * mv88e6352_g2_scratch_gpio_get_data - get data on gpio pin
102 * @chip: chip private data
103 * @pin: gpio index
104 *
105 * Return: 0 for low, 1 for high, negative error
106 */
107static int mv88e6352_g2_scratch_gpio_get_data(struct mv88e6xxx_chip *chip,
108 unsigned int pin)
109{
110 int val = 0;
111 int err;
112
113 err = mv88e6xxx_g2_scratch_get_bit(chip,
114 MV88E6352_G2_SCRATCH_GPIO_DATA0,
115 pin, &val);
116 if (err)
117 return err;
118
119 return val;
120}
121
122/**
123 * mv88e6352_g2_scratch_gpio_set_data - set data on gpio pin
124 * @chip: chip private data
125 * @pin: gpio index
126 * @value: value to set
127 */
128static int mv88e6352_g2_scratch_gpio_set_data(struct mv88e6xxx_chip *chip,
129 unsigned int pin, int value)
130{
131 u8 mask = (1 << (pin & 0x7));
132 int offset = (pin / 8);
133 int reg;
134
135 reg = MV88E6352_G2_SCRATCH_GPIO_DATA0 + offset;
136
137 if (value)
138 chip->gpio_data[offset] |= mask;
139 else
140 chip->gpio_data[offset] &= ~mask;
141
142 return mv88e6xxx_g2_scratch_write(chip, reg, chip->gpio_data[offset]);
143}
144
145/**
146 * mv88e6352_g2_scratch_gpio_get_dir - get direction of gpio pin
147 * @chip: chip private data
148 * @pin: gpio index
149 *
150 * Return: 0 for output, 1 for input (same as GPIOF_DIR_XXX).
151 */
152static int mv88e6352_g2_scratch_gpio_get_dir(struct mv88e6xxx_chip *chip,
153 unsigned int pin)
154{
155 int val = 0;
156 int err;
157
158 err = mv88e6xxx_g2_scratch_get_bit(chip,
159 MV88E6352_G2_SCRATCH_GPIO_DIR0,
160 pin, &val);
161 if (err)
162 return err;
163
164 return val;
165}
166
167/**
168 * mv88e6352_g2_scratch_gpio_set_dir - set direction of gpio pin
169 * @chip: chip private data
170 * @pin: gpio index
171 */
172static int mv88e6352_g2_scratch_gpio_set_dir(struct mv88e6xxx_chip *chip,
173 unsigned int pin, bool input)
174{
175 int value = (input ? MV88E6352_G2_SCRATCH_GPIO_DIR_IN :
176 MV88E6352_G2_SCRATCH_GPIO_DIR_OUT);
177
178 return mv88e6xxx_g2_scratch_set_bit(chip,
179 MV88E6352_G2_SCRATCH_GPIO_DIR0,
180 pin, value);
181}
182
183/**
184 * mv88e6352_g2_scratch_gpio_get_pctl - get pin control setting
185 * @chip: chip private data
186 * @pin: gpio index
187 * @func: function number
188 *
189 * Note that the function numbers themselves may vary by chipset.
190 */
191static int mv88e6352_g2_scratch_gpio_get_pctl(struct mv88e6xxx_chip *chip,
192 unsigned int pin, int *func)
193{
194 int reg = MV88E6352_G2_SCRATCH_GPIO_PCTL0 + (pin / 2);
195 int offset = (pin & 0x1) ? 4 : 0;
196 u8 mask = (0x7 << offset);
197 int err;
198 u8 val;
199
200 err = mv88e6xxx_g2_scratch_read(chip, reg, &val);
201 if (err)
202 return err;
203
204 *func = (val & mask) >> offset;
205
206 return 0;
207}
208
209/**
210 * mv88e6352_g2_scratch_gpio_set_pctl - set pin control setting
211 * @chip: chip private data
212 * @pin: gpio index
213 * @func: function number
214 */
215static int mv88e6352_g2_scratch_gpio_set_pctl(struct mv88e6xxx_chip *chip,
216 unsigned int pin, int func)
217{
218 int reg = MV88E6352_G2_SCRATCH_GPIO_PCTL0 + (pin / 2);
219 int offset = (pin & 0x1) ? 4 : 0;
220 u8 mask = (0x7 << offset);
221 int err;
222 u8 val;
223
224 err = mv88e6xxx_g2_scratch_read(chip, reg, &val);
225 if (err)
226 return err;
227
228 val = (val & ~mask) | ((func & mask) << offset);
229
230 return mv88e6xxx_g2_scratch_write(chip, reg, val);
231}
232
233const struct mv88e6xxx_gpio_ops mv88e6352_gpio_ops = {
234 .get_data = mv88e6352_g2_scratch_gpio_get_data,
235 .set_data = mv88e6352_g2_scratch_gpio_set_data,
236 .get_dir = mv88e6352_g2_scratch_gpio_get_dir,
237 .set_dir = mv88e6352_g2_scratch_gpio_set_dir,
238 .get_pctl = mv88e6352_g2_scratch_gpio_get_pctl,
239 .set_pctl = mv88e6352_g2_scratch_gpio_set_pctl,
240};
241
242/**
243 * mv88e6xxx_g2_gpio_set_smi - set gpio muxing for external smi
244 * @chip: chip private data
245 * @external: set mux for external smi, or free for gpio usage
246 *
247 * Some mv88e6xxx models have GPIO pins that may be configured as
248 * an external SMI interface, or they may be made free for other
249 * GPIO uses.
250 */
251int mv88e6xxx_g2_scratch_gpio_set_smi(struct mv88e6xxx_chip *chip,
252 bool external)
253{
254 int misc_cfg = MV88E6352_G2_SCRATCH_MISC_CFG;
255 int config_data1 = MV88E6352_G2_SCRATCH_CONFIG_DATA1;
256 int config_data2 = MV88E6352_G2_SCRATCH_CONFIG_DATA2;
257 bool no_cpu;
258 u8 p0_mode;
259 int err;
260 u8 val;
261
262 err = mv88e6xxx_g2_scratch_read(chip, config_data2, &val);
263 if (err)
264 return err;
265
266 p0_mode = val & MV88E6352_G2_SCRATCH_CONFIG_DATA2_P0_MODE_MASK;
267
268 if (p0_mode == 0x01 || p0_mode == 0x02)
269 return -EBUSY;
270
271 err = mv88e6xxx_g2_scratch_read(chip, config_data1, &val);
272 if (err)
273 return err;
274
275 no_cpu = !!(val & MV88E6352_G2_SCRATCH_CONFIG_DATA1_NO_CPU);
276
277 err = mv88e6xxx_g2_scratch_read(chip, misc_cfg, &val);
278 if (err)
279 return err;
280
281 /* NO_CPU being 0 inverts the meaning of the bit */
282 if (!no_cpu)
283 external = !external;
284
285 if (external)
286 val |= MV88E6352_G2_SCRATCH_MISC_CFG_NORMALSMI;
287 else
288 val &= ~MV88E6352_G2_SCRATCH_MISC_CFG_NORMALSMI;
289
290 return mv88e6xxx_g2_scratch_write(chip, misc_cfg, val);
291}
diff --git a/drivers/net/dsa/mv88e6xxx/hwtstamp.c b/drivers/net/dsa/mv88e6xxx/hwtstamp.c
new file mode 100644
index 000000000000..ac7694c71266
--- /dev/null
+++ b/drivers/net/dsa/mv88e6xxx/hwtstamp.c
@@ -0,0 +1,576 @@
1/*
2 * Marvell 88E6xxx Switch hardware timestamping support
3 *
4 * Copyright (c) 2008 Marvell Semiconductor
5 *
6 * Copyright (c) 2017 National Instruments
7 * Erik Hons <erik.hons@ni.com>
8 * Brandon Streiff <brandon.streiff@ni.com>
9 * Dane Wagner <dane.wagner@ni.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 */
16
17#include "chip.h"
18#include "global2.h"
19#include "hwtstamp.h"
20#include "ptp.h"
21#include <linux/ptp_classify.h>
22
23#define SKB_PTP_TYPE(__skb) (*(unsigned int *)((__skb)->cb))
24
25static int mv88e6xxx_port_ptp_read(struct mv88e6xxx_chip *chip, int port,
26 int addr, u16 *data, int len)
27{
28 if (!chip->info->ops->avb_ops->port_ptp_read)
29 return -EOPNOTSUPP;
30
31 return chip->info->ops->avb_ops->port_ptp_read(chip, port, addr,
32 data, len);
33}
34
35static int mv88e6xxx_port_ptp_write(struct mv88e6xxx_chip *chip, int port,
36 int addr, u16 data)
37{
38 if (!chip->info->ops->avb_ops->port_ptp_write)
39 return -EOPNOTSUPP;
40
41 return chip->info->ops->avb_ops->port_ptp_write(chip, port, addr,
42 data);
43}
44
45static int mv88e6xxx_ptp_write(struct mv88e6xxx_chip *chip, int addr,
46 u16 data)
47{
48 if (!chip->info->ops->avb_ops->ptp_write)
49 return -EOPNOTSUPP;
50
51 return chip->info->ops->avb_ops->ptp_write(chip, addr, data);
52}
53
54/* TX_TSTAMP_TIMEOUT: This limits the time spent polling for a TX
55 * timestamp. When working properly, hardware will produce a timestamp
56 * within 1ms. Software may enounter delays due to MDIO contention, so
57 * the timeout is set accordingly.
58 */
59#define TX_TSTAMP_TIMEOUT msecs_to_jiffies(20)
60
61int mv88e6xxx_get_ts_info(struct dsa_switch *ds, int port,
62 struct ethtool_ts_info *info)
63{
64 struct mv88e6xxx_chip *chip = ds->priv;
65
66 if (!chip->info->ptp_support)
67 return -EOPNOTSUPP;
68
69 info->so_timestamping =
70 SOF_TIMESTAMPING_TX_HARDWARE |
71 SOF_TIMESTAMPING_RX_HARDWARE |
72 SOF_TIMESTAMPING_RAW_HARDWARE;
73 info->phc_index = ptp_clock_index(chip->ptp_clock);
74 info->tx_types =
75 (1 << HWTSTAMP_TX_OFF) |
76 (1 << HWTSTAMP_TX_ON);
77 info->rx_filters =
78 (1 << HWTSTAMP_FILTER_NONE) |
79 (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
80 (1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC) |
81 (1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ) |
82 (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
83 (1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC) |
84 (1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ) |
85 (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
86 (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
87 (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ);
88
89 return 0;
90}
91
92static int mv88e6xxx_set_hwtstamp_config(struct mv88e6xxx_chip *chip, int port,
93 struct hwtstamp_config *config)
94{
95 struct mv88e6xxx_port_hwtstamp *ps = &chip->port_hwtstamp[port];
96 bool tstamp_enable = false;
97 u16 port_config0;
98 int err;
99
100 /* Prevent the TX/RX paths from trying to interact with the
101 * timestamp hardware while we reconfigure it.
102 */
103 clear_bit_unlock(MV88E6XXX_HWTSTAMP_ENABLED, &ps->state);
104
105 /* reserved for future extensions */
106 if (config->flags)
107 return -EINVAL;
108
109 switch (config->tx_type) {
110 case HWTSTAMP_TX_OFF:
111 tstamp_enable = false;
112 break;
113 case HWTSTAMP_TX_ON:
114 tstamp_enable = true;
115 break;
116 default:
117 return -ERANGE;
118 }
119
120 /* The switch supports timestamping both L2 and L4; one cannot be
121 * disabled independently of the other.
122 */
123 switch (config->rx_filter) {
124 case HWTSTAMP_FILTER_NONE:
125 tstamp_enable = false;
126 break;
127 case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
128 case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
129 case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
130 case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
131 case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
132 case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
133 case HWTSTAMP_FILTER_PTP_V2_EVENT:
134 case HWTSTAMP_FILTER_PTP_V2_SYNC:
135 case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
136 config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
137 break;
138 case HWTSTAMP_FILTER_ALL:
139 default:
140 config->rx_filter = HWTSTAMP_FILTER_NONE;
141 return -ERANGE;
142 }
143
144 if (tstamp_enable) {
145 /* Disable transportSpecific value matching, so that packets
146 * with either 1588 (0) and 802.1AS (1) will be timestamped.
147 */
148 port_config0 = MV88E6XXX_PORT_PTP_CFG0_DISABLE_TSPEC_MATCH;
149 } else {
150 /* Disable PTP. This disables both RX and TX timestamping. */
151 port_config0 = MV88E6XXX_PORT_PTP_CFG0_DISABLE_PTP;
152 }
153
154 mutex_lock(&chip->reg_lock);
155 err = mv88e6xxx_port_ptp_write(chip, port, MV88E6XXX_PORT_PTP_CFG0,
156 port_config0);
157 mutex_unlock(&chip->reg_lock);
158
159 if (err < 0)
160 return err;
161
162 /* Once hardware has been configured, enable timestamp checks
163 * in the RX/TX paths.
164 */
165 if (tstamp_enable)
166 set_bit(MV88E6XXX_HWTSTAMP_ENABLED, &ps->state);
167
168 return 0;
169}
170
171int mv88e6xxx_port_hwtstamp_set(struct dsa_switch *ds, int port,
172 struct ifreq *ifr)
173{
174 struct mv88e6xxx_chip *chip = ds->priv;
175 struct mv88e6xxx_port_hwtstamp *ps = &chip->port_hwtstamp[port];
176 struct hwtstamp_config config;
177 int err;
178
179 if (!chip->info->ptp_support)
180 return -EOPNOTSUPP;
181
182 if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
183 return -EFAULT;
184
185 err = mv88e6xxx_set_hwtstamp_config(chip, port, &config);
186 if (err)
187 return err;
188
189 /* Save the chosen configuration to be returned later. */
190 memcpy(&ps->tstamp_config, &config, sizeof(config));
191
192 return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
193 -EFAULT : 0;
194}
195
196int mv88e6xxx_port_hwtstamp_get(struct dsa_switch *ds, int port,
197 struct ifreq *ifr)
198{
199 struct mv88e6xxx_chip *chip = ds->priv;
200 struct mv88e6xxx_port_hwtstamp *ps = &chip->port_hwtstamp[port];
201 struct hwtstamp_config *config = &ps->tstamp_config;
202
203 if (!chip->info->ptp_support)
204 return -EOPNOTSUPP;
205
206 return copy_to_user(ifr->ifr_data, config, sizeof(*config)) ?
207 -EFAULT : 0;
208}
209
210/* Get the start of the PTP header in this skb */
211static u8 *parse_ptp_header(struct sk_buff *skb, unsigned int type)
212{
213 u8 *data = skb_mac_header(skb);
214 unsigned int offset = 0;
215
216 if (type & PTP_CLASS_VLAN)
217 offset += VLAN_HLEN;
218
219 switch (type & PTP_CLASS_PMASK) {
220 case PTP_CLASS_IPV4:
221 offset += ETH_HLEN + IPV4_HLEN(data + offset) + UDP_HLEN;
222 break;
223 case PTP_CLASS_IPV6:
224 offset += ETH_HLEN + IP6_HLEN + UDP_HLEN;
225 break;
226 case PTP_CLASS_L2:
227 offset += ETH_HLEN;
228 break;
229 default:
230 return NULL;
231 }
232
233 /* Ensure that the entire header is present in this packet. */
234 if (skb->len + ETH_HLEN < offset + 34)
235 return NULL;
236
237 return data + offset;
238}
239
240/* Returns a pointer to the PTP header if the caller should time stamp,
241 * or NULL if the caller should not.
242 */
243static u8 *mv88e6xxx_should_tstamp(struct mv88e6xxx_chip *chip, int port,
244 struct sk_buff *skb, unsigned int type)
245{
246 struct mv88e6xxx_port_hwtstamp *ps = &chip->port_hwtstamp[port];
247 u8 *hdr;
248
249 if (!chip->info->ptp_support)
250 return NULL;
251
252 hdr = parse_ptp_header(skb, type);
253 if (!hdr)
254 return NULL;
255
256 if (!test_bit(MV88E6XXX_HWTSTAMP_ENABLED, &ps->state))
257 return NULL;
258
259 return hdr;
260}
261
262static int mv88e6xxx_ts_valid(u16 status)
263{
264 if (!(status & MV88E6XXX_PTP_TS_VALID))
265 return 0;
266 if (status & MV88E6XXX_PTP_TS_STATUS_MASK)
267 return 0;
268 return 1;
269}
270
271static int seq_match(struct sk_buff *skb, u16 ts_seqid)
272{
273 unsigned int type = SKB_PTP_TYPE(skb);
274 u8 *hdr = parse_ptp_header(skb, type);
275 __be16 *seqid;
276
277 seqid = (__be16 *)(hdr + OFF_PTP_SEQUENCE_ID);
278
279 return ts_seqid == ntohs(*seqid);
280}
281
282static void mv88e6xxx_get_rxts(struct mv88e6xxx_chip *chip,
283 struct mv88e6xxx_port_hwtstamp *ps,
284 struct sk_buff *skb, u16 reg,
285 struct sk_buff_head *rxq)
286{
287 u16 buf[4] = { 0 }, status, seq_id;
288 u64 ns, timelo, timehi;
289 struct skb_shared_hwtstamps *shwt;
290 int err;
291
292 mutex_lock(&chip->reg_lock);
293 err = mv88e6xxx_port_ptp_read(chip, ps->port_id,
294 reg, buf, ARRAY_SIZE(buf));
295 mutex_unlock(&chip->reg_lock);
296 if (err)
297 pr_err("failed to get the receive time stamp\n");
298
299 status = buf[0];
300 timelo = buf[1];
301 timehi = buf[2];
302 seq_id = buf[3];
303
304 if (status & MV88E6XXX_PTP_TS_VALID) {
305 mutex_lock(&chip->reg_lock);
306 err = mv88e6xxx_port_ptp_write(chip, ps->port_id, reg, 0);
307 mutex_unlock(&chip->reg_lock);
308 if (err)
309 pr_err("failed to clear the receive status\n");
310 }
311 /* Since the device can only handle one time stamp at a time,
312 * we purge any extra frames from the queue.
313 */
314 for ( ; skb; skb = skb_dequeue(rxq)) {
315 if (mv88e6xxx_ts_valid(status) && seq_match(skb, seq_id)) {
316 ns = timehi << 16 | timelo;
317
318 mutex_lock(&chip->reg_lock);
319 ns = timecounter_cyc2time(&chip->tstamp_tc, ns);
320 mutex_unlock(&chip->reg_lock);
321 shwt = skb_hwtstamps(skb);
322 memset(shwt, 0, sizeof(*shwt));
323 shwt->hwtstamp = ns_to_ktime(ns);
324 status &= ~MV88E6XXX_PTP_TS_VALID;
325 }
326 netif_rx_ni(skb);
327 }
328}
329
330static void mv88e6xxx_rxtstamp_work(struct mv88e6xxx_chip *chip,
331 struct mv88e6xxx_port_hwtstamp *ps)
332{
333 struct sk_buff *skb;
334
335 skb = skb_dequeue(&ps->rx_queue);
336
337 if (skb)
338 mv88e6xxx_get_rxts(chip, ps, skb, MV88E6XXX_PORT_PTP_ARR0_STS,
339 &ps->rx_queue);
340
341 skb = skb_dequeue(&ps->rx_queue2);
342 if (skb)
343 mv88e6xxx_get_rxts(chip, ps, skb, MV88E6XXX_PORT_PTP_ARR1_STS,
344 &ps->rx_queue2);
345}
346
347static int is_pdelay_resp(u8 *msgtype)
348{
349 return (*msgtype & 0xf) == 3;
350}
351
352bool mv88e6xxx_port_rxtstamp(struct dsa_switch *ds, int port,
353 struct sk_buff *skb, unsigned int type)
354{
355 struct mv88e6xxx_port_hwtstamp *ps;
356 struct mv88e6xxx_chip *chip;
357 u8 *hdr;
358
359 chip = ds->priv;
360 ps = &chip->port_hwtstamp[port];
361
362 if (ps->tstamp_config.rx_filter != HWTSTAMP_FILTER_PTP_V2_EVENT)
363 return false;
364
365 hdr = mv88e6xxx_should_tstamp(chip, port, skb, type);
366 if (!hdr)
367 return false;
368
369 SKB_PTP_TYPE(skb) = type;
370
371 if (is_pdelay_resp(hdr))
372 skb_queue_tail(&ps->rx_queue2, skb);
373 else
374 skb_queue_tail(&ps->rx_queue, skb);
375
376 ptp_schedule_worker(chip->ptp_clock, 0);
377
378 return true;
379}
380
381static int mv88e6xxx_txtstamp_work(struct mv88e6xxx_chip *chip,
382 struct mv88e6xxx_port_hwtstamp *ps)
383{
384 struct skb_shared_hwtstamps shhwtstamps;
385 u16 departure_block[4], status;
386 struct sk_buff *tmp_skb;
387 u32 time_raw;
388 int err;
389 u64 ns;
390
391 if (!ps->tx_skb)
392 return 0;
393
394 mutex_lock(&chip->reg_lock);
395 err = mv88e6xxx_port_ptp_read(chip, ps->port_id,
396 MV88E6XXX_PORT_PTP_DEP_STS,
397 departure_block,
398 ARRAY_SIZE(departure_block));
399 mutex_unlock(&chip->reg_lock);
400
401 if (err)
402 goto free_and_clear_skb;
403
404 if (!(departure_block[0] & MV88E6XXX_PTP_TS_VALID)) {
405 if (time_is_before_jiffies(ps->tx_tstamp_start +
406 TX_TSTAMP_TIMEOUT)) {
407 dev_warn(chip->dev, "p%d: clearing tx timestamp hang\n",
408 ps->port_id);
409 goto free_and_clear_skb;
410 }
411 /* The timestamp should be available quickly, while getting it
412 * is high priority and time bounded to only 10ms. A poll is
413 * warranted so restart the work.
414 */
415 return 1;
416 }
417
418 /* We have the timestamp; go ahead and clear valid now */
419 mutex_lock(&chip->reg_lock);
420 mv88e6xxx_port_ptp_write(chip, ps->port_id,
421 MV88E6XXX_PORT_PTP_DEP_STS, 0);
422 mutex_unlock(&chip->reg_lock);
423
424 status = departure_block[0] & MV88E6XXX_PTP_TS_STATUS_MASK;
425 if (status != MV88E6XXX_PTP_TS_STATUS_NORMAL) {
426 dev_warn(chip->dev, "p%d: tx timestamp overrun\n", ps->port_id);
427 goto free_and_clear_skb;
428 }
429
430 if (departure_block[3] != ps->tx_seq_id) {
431 dev_warn(chip->dev, "p%d: unexpected seq. id\n", ps->port_id);
432 goto free_and_clear_skb;
433 }
434
435 memset(&shhwtstamps, 0, sizeof(shhwtstamps));
436 time_raw = ((u32)departure_block[2] << 16) | departure_block[1];
437 mutex_lock(&chip->reg_lock);
438 ns = timecounter_cyc2time(&chip->tstamp_tc, time_raw);
439 mutex_unlock(&chip->reg_lock);
440 shhwtstamps.hwtstamp = ns_to_ktime(ns);
441
442 dev_dbg(chip->dev,
443 "p%d: txtstamp %llx status 0x%04x skb ID 0x%04x hw ID 0x%04x\n",
444 ps->port_id, ktime_to_ns(shhwtstamps.hwtstamp),
445 departure_block[0], ps->tx_seq_id, departure_block[3]);
446
447 /* skb_complete_tx_timestamp() will free up the client to make
448 * another timestamp-able transmit. We have to be ready for it
449 * -- by clearing the ps->tx_skb "flag" -- beforehand.
450 */
451
452 tmp_skb = ps->tx_skb;
453 ps->tx_skb = NULL;
454 clear_bit_unlock(MV88E6XXX_HWTSTAMP_TX_IN_PROGRESS, &ps->state);
455 skb_complete_tx_timestamp(tmp_skb, &shhwtstamps);
456
457 return 0;
458
459free_and_clear_skb:
460 dev_kfree_skb_any(ps->tx_skb);
461 ps->tx_skb = NULL;
462 clear_bit_unlock(MV88E6XXX_HWTSTAMP_TX_IN_PROGRESS, &ps->state);
463
464 return 0;
465}
466
467long mv88e6xxx_hwtstamp_work(struct ptp_clock_info *ptp)
468{
469 struct mv88e6xxx_chip *chip = ptp_to_chip(ptp);
470 struct dsa_switch *ds = chip->ds;
471 struct mv88e6xxx_port_hwtstamp *ps;
472 int i, restart = 0;
473
474 for (i = 0; i < ds->num_ports; i++) {
475 if (!dsa_is_user_port(ds, i))
476 continue;
477
478 ps = &chip->port_hwtstamp[i];
479 if (test_bit(MV88E6XXX_HWTSTAMP_TX_IN_PROGRESS, &ps->state))
480 restart |= mv88e6xxx_txtstamp_work(chip, ps);
481
482 mv88e6xxx_rxtstamp_work(chip, ps);
483 }
484
485 return restart ? 1 : -1;
486}
487
488bool mv88e6xxx_port_txtstamp(struct dsa_switch *ds, int port,
489 struct sk_buff *clone, unsigned int type)
490{
491 struct mv88e6xxx_chip *chip = ds->priv;
492 struct mv88e6xxx_port_hwtstamp *ps = &chip->port_hwtstamp[port];
493 __be16 *seq_ptr;
494 u8 *hdr;
495
496 if (!(skb_shinfo(clone)->tx_flags & SKBTX_HW_TSTAMP))
497 return false;
498
499 hdr = mv88e6xxx_should_tstamp(chip, port, clone, type);
500 if (!hdr)
501 return false;
502
503 seq_ptr = (__be16 *)(hdr + OFF_PTP_SEQUENCE_ID);
504
505 if (test_and_set_bit_lock(MV88E6XXX_HWTSTAMP_TX_IN_PROGRESS,
506 &ps->state))
507 return false;
508
509 ps->tx_skb = clone;
510 ps->tx_tstamp_start = jiffies;
511 ps->tx_seq_id = be16_to_cpup(seq_ptr);
512
513 ptp_schedule_worker(chip->ptp_clock, 0);
514 return true;
515}
516
517static int mv88e6xxx_hwtstamp_port_setup(struct mv88e6xxx_chip *chip, int port)
518{
519 struct mv88e6xxx_port_hwtstamp *ps = &chip->port_hwtstamp[port];
520
521 ps->port_id = port;
522
523 skb_queue_head_init(&ps->rx_queue);
524 skb_queue_head_init(&ps->rx_queue2);
525
526 return mv88e6xxx_port_ptp_write(chip, port, MV88E6XXX_PORT_PTP_CFG0,
527 MV88E6XXX_PORT_PTP_CFG0_DISABLE_PTP);
528}
529
530int mv88e6xxx_hwtstamp_setup(struct mv88e6xxx_chip *chip)
531{
532 int err;
533 int i;
534
535 /* Disable timestamping on all ports. */
536 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
537 err = mv88e6xxx_hwtstamp_port_setup(chip, i);
538 if (err)
539 return err;
540 }
541
542 /* MV88E6XXX_PTP_MSG_TYPE is a mask of PTP message types to
543 * timestamp. This affects all ports that have timestamping enabled,
544 * but the timestamp config is per-port; thus we configure all events
545 * here and only support the HWTSTAMP_FILTER_*_EVENT filter types.
546 */
547 err = mv88e6xxx_ptp_write(chip, MV88E6XXX_PTP_MSGTYPE,
548 MV88E6XXX_PTP_MSGTYPE_ALL_EVENT);
549 if (err)
550 return err;
551
552 /* Use ARRIVAL1 for peer delay response messages. */
553 err = mv88e6xxx_ptp_write(chip, MV88E6XXX_PTP_TS_ARRIVAL_PTR,
554 MV88E6XXX_PTP_MSGTYPE_PDLAY_RES);
555 if (err)
556 return err;
557
558 /* 88E6341 devices default to timestamping at the PHY, but this has
559 * a hardware issue that results in unreliable timestamps. Force
560 * these devices to timestamp at the MAC.
561 */
562 if (chip->info->family == MV88E6XXX_FAMILY_6341) {
563 u16 val = MV88E6341_PTP_CFG_UPDATE |
564 MV88E6341_PTP_CFG_MODE_IDX |
565 MV88E6341_PTP_CFG_MODE_TS_AT_MAC;
566 err = mv88e6xxx_ptp_write(chip, MV88E6341_PTP_CFG, val);
567 if (err)
568 return err;
569 }
570
571 return 0;
572}
573
574void mv88e6xxx_hwtstamp_free(struct mv88e6xxx_chip *chip)
575{
576}
diff --git a/drivers/net/dsa/mv88e6xxx/hwtstamp.h b/drivers/net/dsa/mv88e6xxx/hwtstamp.h
new file mode 100644
index 000000000000..bc71c9212a08
--- /dev/null
+++ b/drivers/net/dsa/mv88e6xxx/hwtstamp.h
@@ -0,0 +1,172 @@
1/*
2 * Marvell 88E6xxx Switch hardware timestamping support
3 *
4 * Copyright (c) 2008 Marvell Semiconductor
5 *
6 * Copyright (c) 2017 National Instruments
7 * Erik Hons <erik.hons@ni.com>
8 * Brandon Streiff <brandon.streiff@ni.com>
9 * Dane Wagner <dane.wagner@ni.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 */
16
17#ifndef _MV88E6XXX_HWTSTAMP_H
18#define _MV88E6XXX_HWTSTAMP_H
19
20#include "chip.h"
21
22/* Global PTP registers */
23/* Offset 0x00: PTP EtherType */
24#define MV88E6XXX_PTP_ETHERTYPE 0x00
25
26/* Offset 0x01: Message Type Timestamp Enables */
27#define MV88E6XXX_PTP_MSGTYPE 0x01
28#define MV88E6XXX_PTP_MSGTYPE_SYNC 0x0001
29#define MV88E6XXX_PTP_MSGTYPE_DELAY_REQ 0x0002
30#define MV88E6XXX_PTP_MSGTYPE_PDLAY_REQ 0x0004
31#define MV88E6XXX_PTP_MSGTYPE_PDLAY_RES 0x0008
32#define MV88E6XXX_PTP_MSGTYPE_ALL_EVENT 0x000f
33
34/* Offset 0x02: Timestamp Arrival Capture Pointers */
35#define MV88E6XXX_PTP_TS_ARRIVAL_PTR 0x02
36
37/* Offset 0x07: PTP Global Configuration */
38#define MV88E6341_PTP_CFG 0x07
39#define MV88E6341_PTP_CFG_UPDATE 0x8000
40#define MV88E6341_PTP_CFG_IDX_MASK 0x7f00
41#define MV88E6341_PTP_CFG_DATA_MASK 0x00ff
42#define MV88E6341_PTP_CFG_MODE_IDX 0x0
43#define MV88E6341_PTP_CFG_MODE_TS_AT_PHY 0x00
44#define MV88E6341_PTP_CFG_MODE_TS_AT_MAC 0x80
45
46/* Offset 0x08: PTP Interrupt Status */
47#define MV88E6XXX_PTP_IRQ_STATUS 0x08
48
49/* Per-Port PTP Registers */
50/* Offset 0x00: PTP Configuration 0 */
51#define MV88E6XXX_PORT_PTP_CFG0 0x00
52#define MV88E6XXX_PORT_PTP_CFG0_TSPEC_SHIFT 12
53#define MV88E6XXX_PORT_PTP_CFG0_TSPEC_MASK 0xf000
54#define MV88E6XXX_PORT_PTP_CFG0_TSPEC_1588 0x0000
55#define MV88E6XXX_PORT_PTP_CFG0_TSPEC_8021AS 0x1000
56#define MV88E6XXX_PORT_PTP_CFG0_DISABLE_TSPEC_MATCH 0x0800
57#define MV88E6XXX_PORT_PTP_CFG0_DISABLE_OVERWRITE 0x0002
58#define MV88E6XXX_PORT_PTP_CFG0_DISABLE_PTP 0x0001
59
60/* Offset 0x01: PTP Configuration 1 */
61#define MV88E6XXX_PORT_PTP_CFG1 0x01
62
63/* Offset 0x02: PTP Configuration 2 */
64#define MV88E6XXX_PORT_PTP_CFG2 0x02
65#define MV88E6XXX_PORT_PTP_CFG2_EMBED_ARRIVAL 0x1000
66#define MV88E6XXX_PORT_PTP_CFG2_DEP_IRQ_EN 0x0002
67#define MV88E6XXX_PORT_PTP_CFG2_ARR_IRQ_EN 0x0001
68
69/* Offset 0x03: PTP LED Configuration */
70#define MV88E6XXX_PORT_PTP_LED_CFG 0x03
71
72/* Offset 0x08: PTP Arrival 0 Status */
73#define MV88E6XXX_PORT_PTP_ARR0_STS 0x08
74
75/* Offset 0x09/0x0A: PTP Arrival 0 Time */
76#define MV88E6XXX_PORT_PTP_ARR0_TIME_LO 0x09
77#define MV88E6XXX_PORT_PTP_ARR0_TIME_HI 0x0a
78
79/* Offset 0x0B: PTP Arrival 0 Sequence ID */
80#define MV88E6XXX_PORT_PTP_ARR0_SEQID 0x0b
81
82/* Offset 0x0C: PTP Arrival 1 Status */
83#define MV88E6XXX_PORT_PTP_ARR1_STS 0x0c
84
85/* Offset 0x0D/0x0E: PTP Arrival 1 Time */
86#define MV88E6XXX_PORT_PTP_ARR1_TIME_LO 0x0d
87#define MV88E6XXX_PORT_PTP_ARR1_TIME_HI 0x0e
88
89/* Offset 0x0F: PTP Arrival 1 Sequence ID */
90#define MV88E6XXX_PORT_PTP_ARR1_SEQID 0x0f
91
92/* Offset 0x10: PTP Departure Status */
93#define MV88E6XXX_PORT_PTP_DEP_STS 0x10
94
95/* Offset 0x11/0x12: PTP Deperture Time */
96#define MV88E6XXX_PORT_PTP_DEP_TIME_LO 0x11
97#define MV88E6XXX_PORT_PTP_DEP_TIME_HI 0x12
98
99/* Offset 0x13: PTP Departure Sequence ID */
100#define MV88E6XXX_PORT_PTP_DEP_SEQID 0x13
101
102/* Status fields for arrival and depature timestamp status registers */
103#define MV88E6XXX_PTP_TS_STATUS_MASK 0x0006
104#define MV88E6XXX_PTP_TS_STATUS_NORMAL 0x0000
105#define MV88E6XXX_PTP_TS_STATUS_OVERWITTEN 0x0002
106#define MV88E6XXX_PTP_TS_STATUS_DISCARDED 0x0004
107#define MV88E6XXX_PTP_TS_VALID 0x0001
108
109#ifdef CONFIG_NET_DSA_MV88E6XXX_PTP
110
111int mv88e6xxx_port_hwtstamp_set(struct dsa_switch *ds, int port,
112 struct ifreq *ifr);
113int mv88e6xxx_port_hwtstamp_get(struct dsa_switch *ds, int port,
114 struct ifreq *ifr);
115
116bool mv88e6xxx_port_rxtstamp(struct dsa_switch *ds, int port,
117 struct sk_buff *clone, unsigned int type);
118bool mv88e6xxx_port_txtstamp(struct dsa_switch *ds, int port,
119 struct sk_buff *clone, unsigned int type);
120
121int mv88e6xxx_get_ts_info(struct dsa_switch *ds, int port,
122 struct ethtool_ts_info *info);
123
124int mv88e6xxx_hwtstamp_setup(struct mv88e6xxx_chip *chip);
125void mv88e6xxx_hwtstamp_free(struct mv88e6xxx_chip *chip);
126
127#else /* !CONFIG_NET_DSA_MV88E6XXX_PTP */
128
129static inline int mv88e6xxx_port_hwtstamp_set(struct dsa_switch *ds,
130 int port, struct ifreq *ifr)
131{
132 return -EOPNOTSUPP;
133}
134
135static inline int mv88e6xxx_port_hwtstamp_get(struct dsa_switch *ds,
136 int port, struct ifreq *ifr)
137{
138 return -EOPNOTSUPP;
139}
140
141static inline bool mv88e6xxx_port_rxtstamp(struct dsa_switch *ds, int port,
142 struct sk_buff *clone,
143 unsigned int type)
144{
145 return false;
146}
147
148static inline bool mv88e6xxx_port_txtstamp(struct dsa_switch *ds, int port,
149 struct sk_buff *clone,
150 unsigned int type)
151{
152 return false;
153}
154
155static inline int mv88e6xxx_get_ts_info(struct dsa_switch *ds, int port,
156 struct ethtool_ts_info *info)
157{
158 return -EOPNOTSUPP;
159}
160
161static inline int mv88e6xxx_hwtstamp_setup(struct mv88e6xxx_chip *chip)
162{
163 return 0;
164}
165
166static inline void mv88e6xxx_hwtstamp_free(struct mv88e6xxx_chip *chip)
167{
168}
169
170#endif /* CONFIG_NET_DSA_MV88E6XXX_PTP */
171
172#endif /* _MV88E6XXX_HWTSTAMP_H */
diff --git a/drivers/net/dsa/mv88e6xxx/ptp.c b/drivers/net/dsa/mv88e6xxx/ptp.c
new file mode 100644
index 000000000000..bd85e2c390e1
--- /dev/null
+++ b/drivers/net/dsa/mv88e6xxx/ptp.c
@@ -0,0 +1,381 @@
1/*
2 * Marvell 88E6xxx Switch PTP support
3 *
4 * Copyright (c) 2008 Marvell Semiconductor
5 *
6 * Copyright (c) 2017 National Instruments
7 * Erik Hons <erik.hons@ni.com>
8 * Brandon Streiff <brandon.streiff@ni.com>
9 * Dane Wagner <dane.wagner@ni.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 */
16
17#include "chip.h"
18#include "global2.h"
19#include "ptp.h"
20
21/* Raw timestamps are in units of 8-ns clock periods. */
22#define CC_SHIFT 28
23#define CC_MULT (8 << CC_SHIFT)
24#define CC_MULT_NUM (1 << 9)
25#define CC_MULT_DEM 15625ULL
26
27#define TAI_EVENT_WORK_INTERVAL msecs_to_jiffies(100)
28
29#define cc_to_chip(cc) container_of(cc, struct mv88e6xxx_chip, tstamp_cc)
30#define dw_overflow_to_chip(dw) container_of(dw, struct mv88e6xxx_chip, \
31 overflow_work)
32#define dw_tai_event_to_chip(dw) container_of(dw, struct mv88e6xxx_chip, \
33 tai_event_work)
34
35static int mv88e6xxx_tai_read(struct mv88e6xxx_chip *chip, int addr,
36 u16 *data, int len)
37{
38 if (!chip->info->ops->avb_ops->tai_read)
39 return -EOPNOTSUPP;
40
41 return chip->info->ops->avb_ops->tai_read(chip, addr, data, len);
42}
43
44static int mv88e6xxx_tai_write(struct mv88e6xxx_chip *chip, int addr, u16 data)
45{
46 if (!chip->info->ops->avb_ops->tai_write)
47 return -EOPNOTSUPP;
48
49 return chip->info->ops->avb_ops->tai_write(chip, addr, data);
50}
51
52/* TODO: places where this are called should be using pinctrl */
53static int mv88e6xxx_set_gpio_func(struct mv88e6xxx_chip *chip, int pin,
54 int func, int input)
55{
56 int err;
57
58 if (!chip->info->ops->gpio_ops)
59 return -EOPNOTSUPP;
60
61 err = chip->info->ops->gpio_ops->set_dir(chip, pin, input);
62 if (err)
63 return err;
64
65 return chip->info->ops->gpio_ops->set_pctl(chip, pin, func);
66}
67
68static u64 mv88e6xxx_ptp_clock_read(const struct cyclecounter *cc)
69{
70 struct mv88e6xxx_chip *chip = cc_to_chip(cc);
71 u16 phc_time[2];
72 int err;
73
74 err = mv88e6xxx_tai_read(chip, MV88E6XXX_TAI_TIME_LO, phc_time,
75 ARRAY_SIZE(phc_time));
76 if (err)
77 return 0;
78 else
79 return ((u32)phc_time[1] << 16) | phc_time[0];
80}
81
82/* mv88e6xxx_config_eventcap - configure TAI event capture
83 * @event: PTP_CLOCK_PPS (internal) or PTP_CLOCK_EXTTS (external)
84 * @rising: zero for falling-edge trigger, else rising-edge trigger
85 *
86 * This will also reset the capture sequence counter.
87 */
88static int mv88e6xxx_config_eventcap(struct mv88e6xxx_chip *chip, int event,
89 int rising)
90{
91 u16 global_config;
92 u16 cap_config;
93 int err;
94
95 chip->evcap_config = MV88E6XXX_TAI_CFG_CAP_OVERWRITE |
96 MV88E6XXX_TAI_CFG_CAP_CTR_START;
97 if (!rising)
98 chip->evcap_config |= MV88E6XXX_TAI_CFG_EVREQ_FALLING;
99
100 global_config = (chip->evcap_config | chip->trig_config);
101 err = mv88e6xxx_tai_write(chip, MV88E6XXX_TAI_CFG, global_config);
102 if (err)
103 return err;
104
105 if (event == PTP_CLOCK_PPS) {
106 cap_config = MV88E6XXX_TAI_EVENT_STATUS_CAP_TRIG;
107 } else if (event == PTP_CLOCK_EXTTS) {
108 /* if STATUS_CAP_TRIG is unset we capture PTP_EVREQ events */
109 cap_config = 0;
110 } else {
111 return -EINVAL;
112 }
113
114 /* Write the capture config; this also clears the capture counter */
115 err = mv88e6xxx_tai_write(chip, MV88E6XXX_TAI_EVENT_STATUS,
116 cap_config);
117
118 return err;
119}
120
121static void mv88e6xxx_tai_event_work(struct work_struct *ugly)
122{
123 struct delayed_work *dw = to_delayed_work(ugly);
124 struct mv88e6xxx_chip *chip = dw_tai_event_to_chip(dw);
125 struct ptp_clock_event ev;
126 u16 status[4];
127 u32 raw_ts;
128 int err;
129
130 mutex_lock(&chip->reg_lock);
131 err = mv88e6xxx_tai_read(chip, MV88E6XXX_TAI_EVENT_STATUS,
132 status, ARRAY_SIZE(status));
133 mutex_unlock(&chip->reg_lock);
134
135 if (err) {
136 dev_err(chip->dev, "failed to read TAI status register\n");
137 return;
138 }
139 if (status[0] & MV88E6XXX_TAI_EVENT_STATUS_ERROR) {
140 dev_warn(chip->dev, "missed event capture\n");
141 return;
142 }
143 if (!(status[0] & MV88E6XXX_TAI_EVENT_STATUS_VALID))
144 goto out;
145
146 raw_ts = ((u32)status[2] << 16) | status[1];
147
148 /* Clear the valid bit so the next timestamp can come in */
149 status[0] &= ~MV88E6XXX_TAI_EVENT_STATUS_VALID;
150 mutex_lock(&chip->reg_lock);
151 err = mv88e6xxx_tai_write(chip, MV88E6XXX_TAI_EVENT_STATUS, status[0]);
152 mutex_unlock(&chip->reg_lock);
153
154 /* This is an external timestamp */
155 ev.type = PTP_CLOCK_EXTTS;
156
157 /* We only have one timestamping channel. */
158 ev.index = 0;
159 mutex_lock(&chip->reg_lock);
160 ev.timestamp = timecounter_cyc2time(&chip->tstamp_tc, raw_ts);
161 mutex_unlock(&chip->reg_lock);
162
163 ptp_clock_event(chip->ptp_clock, &ev);
164out:
165 schedule_delayed_work(&chip->tai_event_work, TAI_EVENT_WORK_INTERVAL);
166}
167
168static int mv88e6xxx_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
169{
170 struct mv88e6xxx_chip *chip = ptp_to_chip(ptp);
171 int neg_adj = 0;
172 u32 diff, mult;
173 u64 adj;
174
175 if (scaled_ppm < 0) {
176 neg_adj = 1;
177 scaled_ppm = -scaled_ppm;
178 }
179 mult = CC_MULT;
180 adj = CC_MULT_NUM;
181 adj *= scaled_ppm;
182 diff = div_u64(adj, CC_MULT_DEM);
183
184 mutex_lock(&chip->reg_lock);
185
186 timecounter_read(&chip->tstamp_tc);
187 chip->tstamp_cc.mult = neg_adj ? mult - diff : mult + diff;
188
189 mutex_unlock(&chip->reg_lock);
190
191 return 0;
192}
193
194static int mv88e6xxx_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
195{
196 struct mv88e6xxx_chip *chip = ptp_to_chip(ptp);
197
198 mutex_lock(&chip->reg_lock);
199 timecounter_adjtime(&chip->tstamp_tc, delta);
200 mutex_unlock(&chip->reg_lock);
201
202 return 0;
203}
204
205static int mv88e6xxx_ptp_gettime(struct ptp_clock_info *ptp,
206 struct timespec64 *ts)
207{
208 struct mv88e6xxx_chip *chip = ptp_to_chip(ptp);
209 u64 ns;
210
211 mutex_lock(&chip->reg_lock);
212 ns = timecounter_read(&chip->tstamp_tc);
213 mutex_unlock(&chip->reg_lock);
214
215 *ts = ns_to_timespec64(ns);
216
217 return 0;
218}
219
220static int mv88e6xxx_ptp_settime(struct ptp_clock_info *ptp,
221 const struct timespec64 *ts)
222{
223 struct mv88e6xxx_chip *chip = ptp_to_chip(ptp);
224 u64 ns;
225
226 ns = timespec64_to_ns(ts);
227
228 mutex_lock(&chip->reg_lock);
229 timecounter_init(&chip->tstamp_tc, &chip->tstamp_cc, ns);
230 mutex_unlock(&chip->reg_lock);
231
232 return 0;
233}
234
235static int mv88e6xxx_ptp_enable_extts(struct mv88e6xxx_chip *chip,
236 struct ptp_clock_request *rq, int on)
237{
238 int rising = (rq->extts.flags & PTP_RISING_EDGE);
239 int func;
240 int pin;
241 int err;
242
243 pin = ptp_find_pin(chip->ptp_clock, PTP_PF_EXTTS, rq->extts.index);
244
245 if (pin < 0)
246 return -EBUSY;
247
248 mutex_lock(&chip->reg_lock);
249
250 if (on) {
251 func = MV88E6352_G2_SCRATCH_GPIO_PCTL_EVREQ;
252
253 err = mv88e6xxx_set_gpio_func(chip, pin, func, true);
254 if (err)
255 goto out;
256
257 schedule_delayed_work(&chip->tai_event_work,
258 TAI_EVENT_WORK_INTERVAL);
259
260 err = mv88e6xxx_config_eventcap(chip, PTP_CLOCK_EXTTS, rising);
261 } else {
262 func = MV88E6352_G2_SCRATCH_GPIO_PCTL_GPIO;
263
264 err = mv88e6xxx_set_gpio_func(chip, pin, func, true);
265
266 cancel_delayed_work_sync(&chip->tai_event_work);
267 }
268
269out:
270 mutex_unlock(&chip->reg_lock);
271
272 return err;
273}
274
275static int mv88e6xxx_ptp_enable(struct ptp_clock_info *ptp,
276 struct ptp_clock_request *rq, int on)
277{
278 struct mv88e6xxx_chip *chip = ptp_to_chip(ptp);
279
280 switch (rq->type) {
281 case PTP_CLK_REQ_EXTTS:
282 return mv88e6xxx_ptp_enable_extts(chip, rq, on);
283 default:
284 return -EOPNOTSUPP;
285 }
286}
287
288static int mv88e6xxx_ptp_verify(struct ptp_clock_info *ptp, unsigned int pin,
289 enum ptp_pin_function func, unsigned int chan)
290{
291 switch (func) {
292 case PTP_PF_NONE:
293 case PTP_PF_EXTTS:
294 break;
295 case PTP_PF_PEROUT:
296 case PTP_PF_PHYSYNC:
297 return -EOPNOTSUPP;
298 }
299 return 0;
300}
301
302/* With a 125MHz input clock, the 32-bit timestamp counter overflows in ~34.3
303 * seconds; this task forces periodic reads so that we don't miss any.
304 */
305#define MV88E6XXX_TAI_OVERFLOW_PERIOD (HZ * 16)
306static void mv88e6xxx_ptp_overflow_check(struct work_struct *work)
307{
308 struct delayed_work *dw = to_delayed_work(work);
309 struct mv88e6xxx_chip *chip = dw_overflow_to_chip(dw);
310 struct timespec64 ts;
311
312 mv88e6xxx_ptp_gettime(&chip->ptp_clock_info, &ts);
313
314 schedule_delayed_work(&chip->overflow_work,
315 MV88E6XXX_TAI_OVERFLOW_PERIOD);
316}
317
318int mv88e6xxx_ptp_setup(struct mv88e6xxx_chip *chip)
319{
320 int i;
321
322 /* Set up the cycle counter */
323 memset(&chip->tstamp_cc, 0, sizeof(chip->tstamp_cc));
324 chip->tstamp_cc.read = mv88e6xxx_ptp_clock_read;
325 chip->tstamp_cc.mask = CYCLECOUNTER_MASK(32);
326 chip->tstamp_cc.mult = CC_MULT;
327 chip->tstamp_cc.shift = CC_SHIFT;
328
329 timecounter_init(&chip->tstamp_tc, &chip->tstamp_cc,
330 ktime_to_ns(ktime_get_real()));
331
332 INIT_DELAYED_WORK(&chip->overflow_work, mv88e6xxx_ptp_overflow_check);
333 INIT_DELAYED_WORK(&chip->tai_event_work, mv88e6xxx_tai_event_work);
334
335 chip->ptp_clock_info.owner = THIS_MODULE;
336 snprintf(chip->ptp_clock_info.name, sizeof(chip->ptp_clock_info.name),
337 dev_name(chip->dev));
338 chip->ptp_clock_info.max_adj = 1000000;
339
340 chip->ptp_clock_info.n_ext_ts = 1;
341 chip->ptp_clock_info.n_per_out = 0;
342 chip->ptp_clock_info.n_pins = mv88e6xxx_num_gpio(chip);
343 chip->ptp_clock_info.pps = 0;
344
345 for (i = 0; i < chip->ptp_clock_info.n_pins; ++i) {
346 struct ptp_pin_desc *ppd = &chip->pin_config[i];
347
348 snprintf(ppd->name, sizeof(ppd->name), "mv88e6xxx_gpio%d", i);
349 ppd->index = i;
350 ppd->func = PTP_PF_NONE;
351 }
352 chip->ptp_clock_info.pin_config = chip->pin_config;
353
354 chip->ptp_clock_info.adjfine = mv88e6xxx_ptp_adjfine;
355 chip->ptp_clock_info.adjtime = mv88e6xxx_ptp_adjtime;
356 chip->ptp_clock_info.gettime64 = mv88e6xxx_ptp_gettime;
357 chip->ptp_clock_info.settime64 = mv88e6xxx_ptp_settime;
358 chip->ptp_clock_info.enable = mv88e6xxx_ptp_enable;
359 chip->ptp_clock_info.verify = mv88e6xxx_ptp_verify;
360 chip->ptp_clock_info.do_aux_work = mv88e6xxx_hwtstamp_work;
361
362 chip->ptp_clock = ptp_clock_register(&chip->ptp_clock_info, chip->dev);
363 if (IS_ERR(chip->ptp_clock))
364 return PTR_ERR(chip->ptp_clock);
365
366 schedule_delayed_work(&chip->overflow_work,
367 MV88E6XXX_TAI_OVERFLOW_PERIOD);
368
369 return 0;
370}
371
372void mv88e6xxx_ptp_free(struct mv88e6xxx_chip *chip)
373{
374 if (chip->ptp_clock) {
375 cancel_delayed_work_sync(&chip->overflow_work);
376 cancel_delayed_work_sync(&chip->tai_event_work);
377
378 ptp_clock_unregister(chip->ptp_clock);
379 chip->ptp_clock = NULL;
380 }
381}
diff --git a/drivers/net/dsa/mv88e6xxx/ptp.h b/drivers/net/dsa/mv88e6xxx/ptp.h
new file mode 100644
index 000000000000..10f271ab650d
--- /dev/null
+++ b/drivers/net/dsa/mv88e6xxx/ptp.h
@@ -0,0 +1,108 @@
1/*
2 * Marvell 88E6xxx Switch PTP support
3 *
4 * Copyright (c) 2008 Marvell Semiconductor
5 *
6 * Copyright (c) 2017 National Instruments
7 * Erik Hons <erik.hons@ni.com>
8 * Brandon Streiff <brandon.streiff@ni.com>
9 * Dane Wagner <dane.wagner@ni.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 */
16
17#ifndef _MV88E6XXX_PTP_H
18#define _MV88E6XXX_PTP_H
19
20#include "chip.h"
21
22/* Offset 0x00: TAI Global Config */
23#define MV88E6XXX_TAI_CFG 0x00
24#define MV88E6XXX_TAI_CFG_CAP_OVERWRITE 0x8000
25#define MV88E6XXX_TAI_CFG_CAP_CTR_START 0x4000
26#define MV88E6XXX_TAI_CFG_EVREQ_FALLING 0x2000
27#define MV88E6XXX_TAI_CFG_TRIG_ACTIVE_LO 0x1000
28#define MV88E6XXX_TAI_CFG_IRL_ENABLE 0x0400
29#define MV88E6XXX_TAI_CFG_TRIG_IRQ_EN 0x0200
30#define MV88E6XXX_TAI_CFG_EVREQ_IRQ_EN 0x0100
31#define MV88E6XXX_TAI_CFG_TRIG_LOCK 0x0080
32#define MV88E6XXX_TAI_CFG_BLOCK_UPDATE 0x0008
33#define MV88E6XXX_TAI_CFG_MULTI_PTP 0x0004
34#define MV88E6XXX_TAI_CFG_TRIG_MODE_ONESHOT 0x0002
35#define MV88E6XXX_TAI_CFG_TRIG_ENABLE 0x0001
36
37/* Offset 0x01: Timestamp Clock Period (ps) */
38#define MV88E6XXX_TAI_CLOCK_PERIOD 0x01
39
40/* Offset 0x02/0x03: Trigger Generation Amount */
41#define MV88E6XXX_TAI_TRIG_GEN_AMOUNT_LO 0x02
42#define MV88E6XXX_TAI_TRIG_GEN_AMOUNT_HI 0x03
43
44/* Offset 0x04: Clock Compensation */
45#define MV88E6XXX_TAI_TRIG_CLOCK_COMP 0x04
46
47/* Offset 0x05: Trigger Configuration */
48#define MV88E6XXX_TAI_TRIG_CFG 0x05
49
50/* Offset 0x06: Ingress Rate Limiter Clock Generation Amount */
51#define MV88E6XXX_TAI_IRL_AMOUNT 0x06
52
53/* Offset 0x07: Ingress Rate Limiter Compensation */
54#define MV88E6XXX_TAI_IRL_COMP 0x07
55
56/* Offset 0x08: Ingress Rate Limiter Compensation */
57#define MV88E6XXX_TAI_IRL_COMP_PS 0x08
58
59/* Offset 0x09: Event Status */
60#define MV88E6XXX_TAI_EVENT_STATUS 0x09
61#define MV88E6XXX_TAI_EVENT_STATUS_CAP_TRIG 0x4000
62#define MV88E6XXX_TAI_EVENT_STATUS_ERROR 0x0200
63#define MV88E6XXX_TAI_EVENT_STATUS_VALID 0x0100
64#define MV88E6XXX_TAI_EVENT_STATUS_CTR_MASK 0x00ff
65
66/* Offset 0x0A/0x0B: Event Time */
67#define MV88E6XXX_TAI_EVENT_TIME_LO 0x0a
68#define MV88E6XXX_TAI_EVENT_TYPE_HI 0x0b
69
70/* Offset 0x0E/0x0F: PTP Global Time */
71#define MV88E6XXX_TAI_TIME_LO 0x0e
72#define MV88E6XXX_TAI_TIME_HI 0x0f
73
74/* Offset 0x10/0x11: Trig Generation Time */
75#define MV88E6XXX_TAI_TRIG_TIME_LO 0x10
76#define MV88E6XXX_TAI_TRIG_TIME_HI 0x11
77
78/* Offset 0x12: Lock Status */
79#define MV88E6XXX_TAI_LOCK_STATUS 0x12
80
81#ifdef CONFIG_NET_DSA_MV88E6XXX_PTP
82
83long mv88e6xxx_hwtstamp_work(struct ptp_clock_info *ptp);
84int mv88e6xxx_ptp_setup(struct mv88e6xxx_chip *chip);
85void mv88e6xxx_ptp_free(struct mv88e6xxx_chip *chip);
86
87#define ptp_to_chip(ptp) container_of(ptp, struct mv88e6xxx_chip, \
88 ptp_clock_info)
89
90#else /* !CONFIG_NET_DSA_MV88E6XXX_PTP */
91
92static inline long mv88e6xxx_hwtstamp_work(struct ptp_clock_info *ptp)
93{
94 return -1;
95}
96
97static inline int mv88e6xxx_ptp_setup(struct mv88e6xxx_chip *chip)
98{
99 return 0;
100}
101
102static inline void mv88e6xxx_ptp_free(struct mv88e6xxx_chip *chip)
103{
104}
105
106#endif /* CONFIG_NET_DSA_MV88E6XXX_PTP */
107
108#endif /* _MV88E6XXX_PTP_H */
diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c
index f3c01119b3d1..b6166424216a 100644
--- a/drivers/net/dsa/mv88e6xxx/serdes.c
+++ b/drivers/net/dsa/mv88e6xxx/serdes.c
@@ -55,18 +55,30 @@ static int mv88e6352_serdes_power_set(struct mv88e6xxx_chip *chip, bool on)
55 return err; 55 return err;
56} 56}
57 57
58int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on) 58static bool mv88e6352_port_has_serdes(struct mv88e6xxx_chip *chip, int port)
59{ 59{
60 int err;
61 u8 cmode; 60 u8 cmode;
61 int err;
62 62
63 err = mv88e6xxx_port_get_cmode(chip, port, &cmode); 63 err = mv88e6xxx_port_get_cmode(chip, port, &cmode);
64 if (err) 64 if (err) {
65 return err; 65 dev_err(chip->dev, "failed to read cmode\n");
66 return false;
67 }
66 68
67 if ((cmode == MV88E6XXX_PORT_STS_CMODE_100BASE_X) || 69 if ((cmode == MV88E6XXX_PORT_STS_CMODE_100BASE_X) ||
68 (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASE_X) || 70 (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASE_X) ||
69 (cmode == MV88E6XXX_PORT_STS_CMODE_SGMII)) { 71 (cmode == MV88E6XXX_PORT_STS_CMODE_SGMII))
72 return true;
73
74 return false;
75}
76
77int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on)
78{
79 int err;
80
81 if (mv88e6352_port_has_serdes(chip, port)) {
70 err = mv88e6352_serdes_power_set(chip, on); 82 err = mv88e6352_serdes_power_set(chip, on);
71 if (err < 0) 83 if (err < 0)
72 return err; 84 return err;
@@ -75,6 +87,90 @@ int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on)
75 return 0; 87 return 0;
76} 88}
77 89
90struct mv88e6352_serdes_hw_stat {
91 char string[ETH_GSTRING_LEN];
92 int sizeof_stat;
93 int reg;
94};
95
96static struct mv88e6352_serdes_hw_stat mv88e6352_serdes_hw_stats[] = {
97 { "serdes_fibre_rx_error", 16, 21 },
98 { "serdes_PRBS_error", 32, 24 },
99};
100
101int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port)
102{
103 if (mv88e6352_port_has_serdes(chip, port))
104 return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
105
106 return 0;
107}
108
109void mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip,
110 int port, uint8_t *data)
111{
112 struct mv88e6352_serdes_hw_stat *stat;
113 int i;
114
115 if (!mv88e6352_port_has_serdes(chip, port))
116 return;
117
118 for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_hw_stats); i++) {
119 stat = &mv88e6352_serdes_hw_stats[i];
120 memcpy(data + i * ETH_GSTRING_LEN, stat->string,
121 ETH_GSTRING_LEN);
122 }
123}
124
125static uint64_t mv88e6352_serdes_get_stat(struct mv88e6xxx_chip *chip,
126 struct mv88e6352_serdes_hw_stat *stat)
127{
128 u64 val = 0;
129 u16 reg;
130 int err;
131
132 err = mv88e6352_serdes_read(chip, stat->reg, &reg);
133 if (err) {
134 dev_err(chip->dev, "failed to read statistic\n");
135 return 0;
136 }
137
138 val = reg;
139
140 if (stat->sizeof_stat == 32) {
141 err = mv88e6352_serdes_read(chip, stat->reg + 1, &reg);
142 if (err) {
143 dev_err(chip->dev, "failed to read statistic\n");
144 return 0;
145 }
146 val = val << 16 | reg;
147 }
148
149 return val;
150}
151
152void mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
153 uint64_t *data)
154{
155 struct mv88e6xxx_port *mv88e6xxx_port = &chip->ports[port];
156 struct mv88e6352_serdes_hw_stat *stat;
157 u64 value;
158 int i;
159
160 if (!mv88e6352_port_has_serdes(chip, port))
161 return;
162
163 BUILD_BUG_ON(ARRAY_SIZE(mv88e6352_serdes_hw_stats) >
164 ARRAY_SIZE(mv88e6xxx_port->serdes_stats));
165
166 for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_hw_stats); i++) {
167 stat = &mv88e6352_serdes_hw_stats[i];
168 value = mv88e6352_serdes_get_stat(chip, stat);
169 mv88e6xxx_port->serdes_stats[i] += value;
170 data[i] = mv88e6xxx_port->serdes_stats[i];
171 }
172}
173
78/* Set the power on/off for 10GBASE-R and 10GBASE-X4/X2 */ 174/* Set the power on/off for 10GBASE-R and 10GBASE-X4/X2 */
79static int mv88e6390_serdes_10g(struct mv88e6xxx_chip *chip, int addr, bool on) 175static int mv88e6390_serdes_10g(struct mv88e6xxx_chip *chip, int addr, bool on)
80{ 176{
diff --git a/drivers/net/dsa/mv88e6xxx/serdes.h b/drivers/net/dsa/mv88e6xxx/serdes.h
index 5c1cd6d8e9a5..641baa75f910 100644
--- a/drivers/net/dsa/mv88e6xxx/serdes.h
+++ b/drivers/net/dsa/mv88e6xxx/serdes.h
@@ -44,5 +44,9 @@
44 44
45int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on); 45int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on);
46int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on); 46int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on);
47 47int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port);
48void mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip,
49 int port, uint8_t *data);
50void mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
51 uint64_t *data);
48#endif 52#endif
diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index 9df22ebee822..600d5ad1fbde 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -631,7 +631,7 @@ qca8k_get_ethtool_stats(struct dsa_switch *ds, int port,
631} 631}
632 632
633static int 633static int
634qca8k_get_sset_count(struct dsa_switch *ds) 634qca8k_get_sset_count(struct dsa_switch *ds, int port)
635{ 635{
636 return ARRAY_SIZE(ar8327_mib); 636 return ARRAY_SIZE(ar8327_mib);
637} 637}
diff --git a/drivers/net/ethernet/8390/Makefile b/drivers/net/ethernet/8390/Makefile
index f975c2fc88a3..1d650e66cc6e 100644
--- a/drivers/net/ethernet/8390/Makefile
+++ b/drivers/net/ethernet/8390/Makefile
@@ -7,8 +7,8 @@ obj-$(CONFIG_MAC8390) += mac8390.o
7obj-$(CONFIG_APNE) += apne.o 8390.o 7obj-$(CONFIG_APNE) += apne.o 8390.o
8obj-$(CONFIG_ARM_ETHERH) += etherh.o 8obj-$(CONFIG_ARM_ETHERH) += etherh.o
9obj-$(CONFIG_AX88796) += ax88796.o 9obj-$(CONFIG_AX88796) += ax88796.o
10obj-$(CONFIG_HYDRA) += hydra.o 8390.o 10obj-$(CONFIG_HYDRA) += hydra.o
11obj-$(CONFIG_MCF8390) += mcf8390.o 8390.o 11obj-$(CONFIG_MCF8390) += mcf8390.o
12obj-$(CONFIG_NE2000) += ne.o 8390p.o 12obj-$(CONFIG_NE2000) += ne.o 8390p.o
13obj-$(CONFIG_NE2K_PCI) += ne2k-pci.o 8390.o 13obj-$(CONFIG_NE2K_PCI) += ne2k-pci.o 8390.o
14obj-$(CONFIG_PCMCIA_AXNET) += axnet_cs.o 8390.o 14obj-$(CONFIG_PCMCIA_AXNET) += axnet_cs.o 8390.o
@@ -16,4 +16,4 @@ obj-$(CONFIG_PCMCIA_PCNET) += pcnet_cs.o 8390.o
16obj-$(CONFIG_STNIC) += stnic.o 8390.o 16obj-$(CONFIG_STNIC) += stnic.o 8390.o
17obj-$(CONFIG_ULTRA) += smc-ultra.o 8390.o 17obj-$(CONFIG_ULTRA) += smc-ultra.o 8390.o
18obj-$(CONFIG_WD80x3) += wd.o 8390.o 18obj-$(CONFIG_WD80x3) += wd.o 8390.o
19obj-$(CONFIG_ZORRO8390) += zorro8390.o 8390.o 19obj-$(CONFIG_ZORRO8390) += zorro8390.o
diff --git a/drivers/net/ethernet/8390/ax88796.c b/drivers/net/ethernet/8390/ax88796.c
index 245554707163..da61cf3cb3a9 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -77,8 +77,6 @@ static unsigned char version[] = "ax88796.c: Copyright 2005,2007 Simtec Electron
77 77
78#define AX_GPOC_PPDSET BIT(6) 78#define AX_GPOC_PPDSET BIT(6)
79 79
80static u32 ax_msg_enable;
81
82/* device private data */ 80/* device private data */
83 81
84struct ax_device { 82struct ax_device {
@@ -747,7 +745,6 @@ static int ax_init_dev(struct net_device *dev)
747 ei_local->block_output = &ax_block_output; 745 ei_local->block_output = &ax_block_output;
748 ei_local->get_8390_hdr = &ax_get_8390_hdr; 746 ei_local->get_8390_hdr = &ax_get_8390_hdr;
749 ei_local->priv = 0; 747 ei_local->priv = 0;
750 ei_local->msg_enable = ax_msg_enable;
751 748
752 dev->netdev_ops = &ax_netdev_ops; 749 dev->netdev_ops = &ax_netdev_ops;
753 dev->ethtool_ops = &ax_ethtool_ops; 750 dev->ethtool_ops = &ax_ethtool_ops;
diff --git a/drivers/net/ethernet/8390/axnet_cs.c b/drivers/net/ethernet/8390/axnet_cs.c
index 7bddb8efb6d5..d422a124cd7c 100644
--- a/drivers/net/ethernet/8390/axnet_cs.c
+++ b/drivers/net/ethernet/8390/axnet_cs.c
@@ -104,7 +104,6 @@ static void AX88190_init(struct net_device *dev, int startp);
104static int ax_open(struct net_device *dev); 104static int ax_open(struct net_device *dev);
105static int ax_close(struct net_device *dev); 105static int ax_close(struct net_device *dev);
106static irqreturn_t ax_interrupt(int irq, void *dev_id); 106static irqreturn_t ax_interrupt(int irq, void *dev_id);
107static u32 axnet_msg_enable;
108 107
109/*====================================================================*/ 108/*====================================================================*/
110 109
@@ -151,7 +150,6 @@ static int axnet_probe(struct pcmcia_device *link)
151 return -ENOMEM; 150 return -ENOMEM;
152 151
153 ei_local = netdev_priv(dev); 152 ei_local = netdev_priv(dev);
154 ei_local->msg_enable = axnet_msg_enable;
155 spin_lock_init(&ei_local->page_lock); 153 spin_lock_init(&ei_local->page_lock);
156 154
157 info = PRIV(dev); 155 info = PRIV(dev);
diff --git a/drivers/net/ethernet/8390/etherh.c b/drivers/net/ethernet/8390/etherh.c
index 11cbf22ad201..32e9627e3880 100644
--- a/drivers/net/ethernet/8390/etherh.c
+++ b/drivers/net/ethernet/8390/etherh.c
@@ -64,8 +64,6 @@ static char version[] =
64 64
65#include "lib8390.c" 65#include "lib8390.c"
66 66
67static u32 etherh_msg_enable;
68
69struct etherh_priv { 67struct etherh_priv {
70 void __iomem *ioc_fast; 68 void __iomem *ioc_fast;
71 void __iomem *memc; 69 void __iomem *memc;
@@ -502,18 +500,6 @@ etherh_close(struct net_device *dev)
502} 500}
503 501
504/* 502/*
505 * Initialisation
506 */
507
508static void __init etherh_banner(void)
509{
510 static int version_printed;
511
512 if ((etherh_msg_enable & NETIF_MSG_DRV) && (version_printed++ == 0))
513 pr_info("%s", version);
514}
515
516/*
517 * Read the ethernet address string from the on board rom. 503 * Read the ethernet address string from the on board rom.
518 * This is an ascii string... 504 * This is an ascii string...
519 */ 505 */
@@ -671,8 +657,6 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id)
671 struct etherh_priv *eh; 657 struct etherh_priv *eh;
672 int ret; 658 int ret;
673 659
674 etherh_banner();
675
676 ret = ecard_request_resources(ec); 660 ret = ecard_request_resources(ec);
677 if (ret) 661 if (ret)
678 goto out; 662 goto out;
@@ -757,7 +741,6 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id)
757 ei_local->block_output = etherh_block_output; 741 ei_local->block_output = etherh_block_output;
758 ei_local->get_8390_hdr = etherh_get_header; 742 ei_local->get_8390_hdr = etherh_get_header;
759 ei_local->interface_num = 0; 743 ei_local->interface_num = 0;
760 ei_local->msg_enable = etherh_msg_enable;
761 744
762 etherh_reset(dev); 745 etherh_reset(dev);
763 __NS8390_init(dev, 0); 746 __NS8390_init(dev, 0);
diff --git a/drivers/net/ethernet/8390/hydra.c b/drivers/net/ethernet/8390/hydra.c
index 8ae249195301..941754ea78ec 100644
--- a/drivers/net/ethernet/8390/hydra.c
+++ b/drivers/net/ethernet/8390/hydra.c
@@ -66,7 +66,6 @@ static void hydra_block_input(struct net_device *dev, int count,
66static void hydra_block_output(struct net_device *dev, int count, 66static void hydra_block_output(struct net_device *dev, int count,
67 const unsigned char *buf, int start_page); 67 const unsigned char *buf, int start_page);
68static void hydra_remove_one(struct zorro_dev *z); 68static void hydra_remove_one(struct zorro_dev *z);
69static u32 hydra_msg_enable;
70 69
71static struct zorro_device_id hydra_zorro_tbl[] = { 70static struct zorro_device_id hydra_zorro_tbl[] = {
72 { ZORRO_PROD_HYDRA_SYSTEMS_AMIGANET }, 71 { ZORRO_PROD_HYDRA_SYSTEMS_AMIGANET },
@@ -119,7 +118,6 @@ static int hydra_init(struct zorro_dev *z)
119 int start_page, stop_page; 118 int start_page, stop_page;
120 int j; 119 int j;
121 int err; 120 int err;
122 struct ei_device *ei_local;
123 121
124 static u32 hydra_offsets[16] = { 122 static u32 hydra_offsets[16] = {
125 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 123 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e,
@@ -138,8 +136,6 @@ static int hydra_init(struct zorro_dev *z)
138 start_page = NESM_START_PG; 136 start_page = NESM_START_PG;
139 stop_page = NESM_STOP_PG; 137 stop_page = NESM_STOP_PG;
140 138
141 ei_local = netdev_priv(dev);
142 ei_local->msg_enable = hydra_msg_enable;
143 dev->base_addr = ioaddr; 139 dev->base_addr = ioaddr;
144 dev->irq = IRQ_AMIGA_PORTS; 140 dev->irq = IRQ_AMIGA_PORTS;
145 141
diff --git a/drivers/net/ethernet/8390/lib8390.c b/drivers/net/ethernet/8390/lib8390.c
index 60f8e2c8e726..5d9bbde9fe68 100644
--- a/drivers/net/ethernet/8390/lib8390.c
+++ b/drivers/net/ethernet/8390/lib8390.c
@@ -975,6 +975,8 @@ static void ethdev_setup(struct net_device *dev)
975 ether_setup(dev); 975 ether_setup(dev);
976 976
977 spin_lock_init(&ei_local->page_lock); 977 spin_lock_init(&ei_local->page_lock);
978
979 ei_local->msg_enable = msg_enable;
978} 980}
979 981
980/** 982/**
diff --git a/drivers/net/ethernet/8390/mac8390.c b/drivers/net/ethernet/8390/mac8390.c
index 2f91ce8dc614..b6d735bf8011 100644
--- a/drivers/net/ethernet/8390/mac8390.c
+++ b/drivers/net/ethernet/8390/mac8390.c
@@ -123,8 +123,7 @@ enum mac8390_access {
123}; 123};
124 124
125extern int mac8390_memtest(struct net_device *dev); 125extern int mac8390_memtest(struct net_device *dev);
126static int mac8390_initdev(struct net_device *dev, 126static int mac8390_initdev(struct net_device *dev, struct nubus_board *board,
127 struct nubus_rsrc *ndev,
128 enum mac8390_type type); 127 enum mac8390_type type);
129 128
130static int mac8390_open(struct net_device *dev); 129static int mac8390_open(struct net_device *dev);
@@ -168,9 +167,8 @@ static void slow_sane_block_output(struct net_device *dev, int count,
168 const unsigned char *buf, int start_page); 167 const unsigned char *buf, int start_page);
169static void word_memcpy_tocard(unsigned long tp, const void *fp, int count); 168static void word_memcpy_tocard(unsigned long tp, const void *fp, int count);
170static void word_memcpy_fromcard(void *tp, unsigned long fp, int count); 169static void word_memcpy_fromcard(void *tp, unsigned long fp, int count);
171static u32 mac8390_msg_enable;
172 170
173static enum mac8390_type __init mac8390_ident(struct nubus_rsrc *fres) 171static enum mac8390_type mac8390_ident(struct nubus_rsrc *fres)
174{ 172{
175 switch (fres->dr_sw) { 173 switch (fres->dr_sw) {
176 case NUBUS_DRSW_3COM: 174 case NUBUS_DRSW_3COM:
@@ -236,7 +234,7 @@ static enum mac8390_type __init mac8390_ident(struct nubus_rsrc *fres)
236 return MAC8390_NONE; 234 return MAC8390_NONE;
237} 235}
238 236
239static enum mac8390_access __init mac8390_testio(volatile unsigned long membase) 237static enum mac8390_access mac8390_testio(unsigned long membase)
240{ 238{
241 unsigned long outdata = 0xA5A0B5B0; 239 unsigned long outdata = 0xA5A0B5B0;
242 unsigned long indata = 0x00000000; 240 unsigned long indata = 0x00000000;
@@ -254,7 +252,7 @@ static enum mac8390_access __init mac8390_testio(volatile unsigned long membase)
254 return ACCESS_UNKNOWN; 252 return ACCESS_UNKNOWN;
255} 253}
256 254
257static int __init mac8390_memsize(unsigned long membase) 255static int mac8390_memsize(unsigned long membase)
258{ 256{
259 unsigned long flags; 257 unsigned long flags;
260 int i, j; 258 int i, j;
@@ -290,36 +288,34 @@ static int __init mac8390_memsize(unsigned long membase)
290 return i * 0x1000; 288 return i * 0x1000;
291} 289}
292 290
293static bool __init mac8390_init(struct net_device *dev, 291static bool mac8390_rsrc_init(struct net_device *dev,
294 struct nubus_rsrc *ndev, 292 struct nubus_rsrc *fres,
295 enum mac8390_type cardtype) 293 enum mac8390_type cardtype)
296{ 294{
295 struct nubus_board *board = fres->board;
297 struct nubus_dir dir; 296 struct nubus_dir dir;
298 struct nubus_dirent ent; 297 struct nubus_dirent ent;
299 int offset; 298 int offset;
300 volatile unsigned short *i; 299 volatile unsigned short *i;
301 300
302 printk_once(KERN_INFO pr_fmt("%s"), version); 301 dev->irq = SLOT2IRQ(board->slot);
303
304 dev->irq = SLOT2IRQ(ndev->board->slot);
305 /* This is getting to be a habit */ 302 /* This is getting to be a habit */
306 dev->base_addr = (ndev->board->slot_addr | 303 dev->base_addr = board->slot_addr | ((board->slot & 0xf) << 20);
307 ((ndev->board->slot & 0xf) << 20));
308 304
309 /* 305 /*
310 * Get some Nubus info - we will trust the card's idea 306 * Get some Nubus info - we will trust the card's idea
311 * of where its memory and registers are. 307 * of where its memory and registers are.
312 */ 308 */
313 309
314 if (nubus_get_func_dir(ndev, &dir) == -1) { 310 if (nubus_get_func_dir(fres, &dir) == -1) {
315 pr_err("%s: Unable to get Nubus functional directory for slot %X!\n", 311 dev_err(&board->dev,
316 dev->name, ndev->board->slot); 312 "Unable to get Nubus functional directory\n");
317 return false; 313 return false;
318 } 314 }
319 315
320 /* Get the MAC address */ 316 /* Get the MAC address */
321 if (nubus_find_rsrc(&dir, NUBUS_RESID_MAC_ADDRESS, &ent) == -1) { 317 if (nubus_find_rsrc(&dir, NUBUS_RESID_MAC_ADDRESS, &ent) == -1) {
322 pr_info("%s: Couldn't get MAC address!\n", dev->name); 318 dev_info(&board->dev, "MAC address resource not found\n");
323 return false; 319 return false;
324 } 320 }
325 321
@@ -329,8 +325,8 @@ static bool __init mac8390_init(struct net_device *dev,
329 nubus_rewinddir(&dir); 325 nubus_rewinddir(&dir);
330 if (nubus_find_rsrc(&dir, NUBUS_RESID_MINOR_BASEOS, 326 if (nubus_find_rsrc(&dir, NUBUS_RESID_MINOR_BASEOS,
331 &ent) == -1) { 327 &ent) == -1) {
332 pr_err("%s: Memory offset resource for slot %X not found!\n", 328 dev_err(&board->dev,
333 dev->name, ndev->board->slot); 329 "Memory offset resource not found\n");
334 return false; 330 return false;
335 } 331 }
336 nubus_get_rsrc_mem(&offset, &ent, 4); 332 nubus_get_rsrc_mem(&offset, &ent, 4);
@@ -340,8 +336,8 @@ static bool __init mac8390_init(struct net_device *dev,
340 nubus_rewinddir(&dir); 336 nubus_rewinddir(&dir);
341 if (nubus_find_rsrc(&dir, NUBUS_RESID_MINOR_LENGTH, 337 if (nubus_find_rsrc(&dir, NUBUS_RESID_MINOR_LENGTH,
342 &ent) == -1) { 338 &ent) == -1) {
343 pr_info("%s: Memory length resource for slot %X not found, probing\n", 339 dev_info(&board->dev,
344 dev->name, ndev->board->slot); 340 "Memory length resource not found, probing\n");
345 offset = mac8390_memsize(dev->mem_start); 341 offset = mac8390_memsize(dev->mem_start);
346 } else { 342 } else {
347 nubus_get_rsrc_mem(&offset, &ent, 4); 343 nubus_get_rsrc_mem(&offset, &ent, 4);
@@ -351,25 +347,25 @@ static bool __init mac8390_init(struct net_device *dev,
351 switch (cardtype) { 347 switch (cardtype) {
352 case MAC8390_KINETICS: 348 case MAC8390_KINETICS:
353 case MAC8390_DAYNA: /* it's the same */ 349 case MAC8390_DAYNA: /* it's the same */
354 dev->base_addr = (int)(ndev->board->slot_addr + 350 dev->base_addr = (int)(board->slot_addr +
355 DAYNA_8390_BASE); 351 DAYNA_8390_BASE);
356 dev->mem_start = (int)(ndev->board->slot_addr + 352 dev->mem_start = (int)(board->slot_addr +
357 DAYNA_8390_MEM); 353 DAYNA_8390_MEM);
358 dev->mem_end = dev->mem_start + 354 dev->mem_end = dev->mem_start +
359 mac8390_memsize(dev->mem_start); 355 mac8390_memsize(dev->mem_start);
360 break; 356 break;
361 case MAC8390_INTERLAN: 357 case MAC8390_INTERLAN:
362 dev->base_addr = (int)(ndev->board->slot_addr + 358 dev->base_addr = (int)(board->slot_addr +
363 INTERLAN_8390_BASE); 359 INTERLAN_8390_BASE);
364 dev->mem_start = (int)(ndev->board->slot_addr + 360 dev->mem_start = (int)(board->slot_addr +
365 INTERLAN_8390_MEM); 361 INTERLAN_8390_MEM);
366 dev->mem_end = dev->mem_start + 362 dev->mem_end = dev->mem_start +
367 mac8390_memsize(dev->mem_start); 363 mac8390_memsize(dev->mem_start);
368 break; 364 break;
369 case MAC8390_CABLETRON: 365 case MAC8390_CABLETRON:
370 dev->base_addr = (int)(ndev->board->slot_addr + 366 dev->base_addr = (int)(board->slot_addr +
371 CABLETRON_8390_BASE); 367 CABLETRON_8390_BASE);
372 dev->mem_start = (int)(ndev->board->slot_addr + 368 dev->mem_start = (int)(board->slot_addr +
373 CABLETRON_8390_MEM); 369 CABLETRON_8390_MEM);
374 /* The base address is unreadable if 0x00 370 /* The base address is unreadable if 0x00
375 * has been written to the command register 371 * has been written to the command register
@@ -384,8 +380,8 @@ static bool __init mac8390_init(struct net_device *dev,
384 break; 380 break;
385 381
386 default: 382 default:
387 pr_err("Card type %s is unsupported, sorry\n", 383 dev_err(&board->dev,
388 ndev->board->name); 384 "No known base address for card type\n");
389 return false; 385 return false;
390 } 386 }
391 } 387 }
@@ -393,91 +389,83 @@ static bool __init mac8390_init(struct net_device *dev,
393 return true; 389 return true;
394} 390}
395 391
396struct net_device * __init mac8390_probe(int unit) 392static int mac8390_device_probe(struct nubus_board *board)
397{ 393{
398 struct net_device *dev; 394 struct net_device *dev;
399 struct nubus_rsrc *ndev = NULL;
400 int err = -ENODEV; 395 int err = -ENODEV;
401 struct ei_device *ei_local; 396 struct nubus_rsrc *fres;
402 397 enum mac8390_type cardtype = MAC8390_NONE;
403 static unsigned int slots;
404
405 enum mac8390_type cardtype;
406
407 /* probably should check for Nubus instead */
408
409 if (!MACH_IS_MAC)
410 return ERR_PTR(-ENODEV);
411 398
412 dev = ____alloc_ei_netdev(0); 399 dev = ____alloc_ei_netdev(0);
413 if (!dev) 400 if (!dev)
414 return ERR_PTR(-ENOMEM); 401 return -ENOMEM;
415
416 if (unit >= 0)
417 sprintf(dev->name, "eth%d", unit);
418 402
419 for_each_func_rsrc(ndev) { 403 SET_NETDEV_DEV(dev, &board->dev);
420 if (ndev->category != NUBUS_CAT_NETWORK ||
421 ndev->type != NUBUS_TYPE_ETHERNET)
422 continue;
423 404
424 /* Have we seen it already? */ 405 for_each_board_func_rsrc(board, fres) {
425 if (slots & (1 << ndev->board->slot)) 406 if (fres->category != NUBUS_CAT_NETWORK ||
407 fres->type != NUBUS_TYPE_ETHERNET)
426 continue; 408 continue;
427 slots |= 1 << ndev->board->slot;
428 409
429 cardtype = mac8390_ident(ndev); 410 cardtype = mac8390_ident(fres);
430 if (cardtype == MAC8390_NONE) 411 if (cardtype == MAC8390_NONE)
431 continue; 412 continue;
432 413
433 if (!mac8390_init(dev, ndev, cardtype)) 414 if (mac8390_rsrc_init(dev, fres, cardtype))
434 continue;
435
436 /* Do the nasty 8390 stuff */
437 if (!mac8390_initdev(dev, ndev, cardtype))
438 break; 415 break;
439 } 416 }
440 417 if (!fres)
441 if (!ndev)
442 goto out; 418 goto out;
443 419
444 ei_local = netdev_priv(dev); 420 err = mac8390_initdev(dev, board, cardtype);
445 ei_local->msg_enable = mac8390_msg_enable; 421 if (err)
422 goto out;
446 423
447 err = register_netdev(dev); 424 err = register_netdev(dev);
448 if (err) 425 if (err)
449 goto out; 426 goto out;
450 return dev; 427
428 nubus_set_drvdata(board, dev);
429 return 0;
451 430
452out: 431out:
453 free_netdev(dev); 432 free_netdev(dev);
454 return ERR_PTR(err); 433 return err;
434}
435
436static int mac8390_device_remove(struct nubus_board *board)
437{
438 struct net_device *dev = nubus_get_drvdata(board);
439
440 unregister_netdev(dev);
441 free_netdev(dev);
442 return 0;
455} 443}
456 444
457#ifdef MODULE 445static struct nubus_driver mac8390_driver = {
446 .probe = mac8390_device_probe,
447 .remove = mac8390_device_remove,
448 .driver = {
449 .name = KBUILD_MODNAME,
450 .owner = THIS_MODULE,
451 }
452};
453
458MODULE_AUTHOR("David Huggins-Daines <dhd@debian.org> and others"); 454MODULE_AUTHOR("David Huggins-Daines <dhd@debian.org> and others");
459MODULE_DESCRIPTION("Macintosh NS8390-based Nubus Ethernet driver"); 455MODULE_DESCRIPTION("Macintosh NS8390-based Nubus Ethernet driver");
460MODULE_LICENSE("GPL"); 456MODULE_LICENSE("GPL");
461 457
462static struct net_device *dev_mac8390; 458static int __init mac8390_init(void)
463
464int __init init_module(void)
465{ 459{
466 dev_mac8390 = mac8390_probe(-1); 460 return nubus_driver_register(&mac8390_driver);
467 if (IS_ERR(dev_mac8390)) {
468 pr_warn("mac8390: No card found\n");
469 return PTR_ERR(dev_mac8390);
470 }
471 return 0;
472} 461}
462module_init(mac8390_init);
473 463
474void __exit cleanup_module(void) 464static void __exit mac8390_exit(void)
475{ 465{
476 unregister_netdev(dev_mac8390); 466 nubus_driver_unregister(&mac8390_driver);
477 free_netdev(dev_mac8390);
478} 467}
479 468module_exit(mac8390_exit);
480#endif /* MODULE */
481 469
482static const struct net_device_ops mac8390_netdev_ops = { 470static const struct net_device_ops mac8390_netdev_ops = {
483 .ndo_open = mac8390_open, 471 .ndo_open = mac8390_open,
@@ -493,9 +481,8 @@ static const struct net_device_ops mac8390_netdev_ops = {
493#endif 481#endif
494}; 482};
495 483
496static int __init mac8390_initdev(struct net_device *dev, 484static int mac8390_initdev(struct net_device *dev, struct nubus_board *board,
497 struct nubus_rsrc *ndev, 485 enum mac8390_type type)
498 enum mac8390_type type)
499{ 486{
500 static u32 fwrd4_offsets[16] = { 487 static u32 fwrd4_offsets[16] = {
501 0, 4, 8, 12, 488 0, 4, 8, 12,
@@ -546,7 +533,8 @@ static int __init mac8390_initdev(struct net_device *dev,
546 case MAC8390_APPLE: 533 case MAC8390_APPLE:
547 switch (mac8390_testio(dev->mem_start)) { 534 switch (mac8390_testio(dev->mem_start)) {
548 case ACCESS_UNKNOWN: 535 case ACCESS_UNKNOWN:
549 pr_err("Don't know how to access card memory!\n"); 536 dev_err(&board->dev,
537 "Don't know how to access card memory\n");
550 return -ENODEV; 538 return -ENODEV;
551 539
552 case ACCESS_16: 540 case ACCESS_16:
@@ -612,21 +600,18 @@ static int __init mac8390_initdev(struct net_device *dev,
612 break; 600 break;
613 601
614 default: 602 default:
615 pr_err("Card type %s is unsupported, sorry\n", 603 dev_err(&board->dev, "Unsupported card type\n");
616 ndev->board->name);
617 return -ENODEV; 604 return -ENODEV;
618 } 605 }
619 606
620 __NS8390_init(dev, 0); 607 __NS8390_init(dev, 0);
621 608
622 /* Good, done, now spit out some messages */ 609 /* Good, done, now spit out some messages */
623 pr_info("%s: %s in slot %X (type %s)\n", 610 dev_info(&board->dev, "%s (type %s)\n", board->name, cardname[type]);
624 dev->name, ndev->board->name, ndev->board->slot, 611 dev_info(&board->dev, "MAC %pM, IRQ %d, %d KB shared memory at %#lx, %d-bit access.\n",
625 cardname[type]); 612 dev->dev_addr, dev->irq,
626 pr_info("MAC %pM IRQ %d, %d KB shared memory at %#lx, %d-bit access.\n", 613 (unsigned int)(dev->mem_end - dev->mem_start) >> 10,
627 dev->dev_addr, dev->irq, 614 dev->mem_start, access_bitmode ? 32 : 16);
628 (unsigned int)(dev->mem_end - dev->mem_start) >> 10,
629 dev->mem_start, access_bitmode ? 32 : 16);
630 return 0; 615 return 0;
631} 616}
632 617
diff --git a/drivers/net/ethernet/8390/mcf8390.c b/drivers/net/ethernet/8390/mcf8390.c
index 4bb967bc879e..4ad8031ab669 100644
--- a/drivers/net/ethernet/8390/mcf8390.c
+++ b/drivers/net/ethernet/8390/mcf8390.c
@@ -38,7 +38,6 @@ static const char version[] =
38 38
39#define NESM_START_PG 0x40 /* First page of TX buffer */ 39#define NESM_START_PG 0x40 /* First page of TX buffer */
40#define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */ 40#define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */
41static u32 mcf8390_msg_enable;
42 41
43#ifdef NE2000_ODDOFFSET 42#ifdef NE2000_ODDOFFSET
44/* 43/*
@@ -407,7 +406,6 @@ static int mcf8390_init(struct net_device *dev)
407static int mcf8390_probe(struct platform_device *pdev) 406static int mcf8390_probe(struct platform_device *pdev)
408{ 407{
409 struct net_device *dev; 408 struct net_device *dev;
410 struct ei_device *ei_local;
411 struct resource *mem, *irq; 409 struct resource *mem, *irq;
412 resource_size_t msize; 410 resource_size_t msize;
413 int ret; 411 int ret;
@@ -435,8 +433,6 @@ static int mcf8390_probe(struct platform_device *pdev)
435 433
436 SET_NETDEV_DEV(dev, &pdev->dev); 434 SET_NETDEV_DEV(dev, &pdev->dev);
437 platform_set_drvdata(pdev, dev); 435 platform_set_drvdata(pdev, dev);
438 ei_local = netdev_priv(dev);
439 ei_local->msg_enable = mcf8390_msg_enable;
440 436
441 dev->irq = irq->start; 437 dev->irq = irq->start;
442 dev->base_addr = mem->start; 438 dev->base_addr = mem->start;
diff --git a/drivers/net/ethernet/8390/ne.c b/drivers/net/ethernet/8390/ne.c
index 66f47987e2a2..4cdff6e6af89 100644
--- a/drivers/net/ethernet/8390/ne.c
+++ b/drivers/net/ethernet/8390/ne.c
@@ -485,7 +485,7 @@ static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr)
485 mdelay(10); /* wait 10ms for interrupt to propagate */ 485 mdelay(10); /* wait 10ms for interrupt to propagate */
486 outb_p(0x00, ioaddr + EN0_IMR); /* Mask it again. */ 486 outb_p(0x00, ioaddr + EN0_IMR); /* Mask it again. */
487 dev->irq = probe_irq_off(cookie); 487 dev->irq = probe_irq_off(cookie);
488 if (netif_msg_probe(ei_local)) 488 if (ne_msg_enable & NETIF_MSG_PROBE)
489 pr_cont(" autoirq is %d", dev->irq); 489 pr_cont(" autoirq is %d", dev->irq);
490 } else if (dev->irq == 2) 490 } else if (dev->irq == 2)
491 /* Fixup for users that don't know that IRQ 2 is really IRQ 9, 491 /* Fixup for users that don't know that IRQ 2 is really IRQ 9,
diff --git a/drivers/net/ethernet/8390/pcnet_cs.c b/drivers/net/ethernet/8390/pcnet_cs.c
index bcad4a7fac9f..61e43802b9a5 100644
--- a/drivers/net/ethernet/8390/pcnet_cs.c
+++ b/drivers/net/ethernet/8390/pcnet_cs.c
@@ -66,7 +66,6 @@
66#define PCNET_RDC_TIMEOUT (2*HZ/100) /* Max wait in jiffies for Tx RDC */ 66#define PCNET_RDC_TIMEOUT (2*HZ/100) /* Max wait in jiffies for Tx RDC */
67 67
68static const char *if_names[] = { "auto", "10baseT", "10base2"}; 68static const char *if_names[] = { "auto", "10baseT", "10base2"};
69static u32 pcnet_msg_enable;
70 69
71/*====================================================================*/ 70/*====================================================================*/
72 71
@@ -556,7 +555,6 @@ static int pcnet_config(struct pcmcia_device *link)
556 int start_pg, stop_pg, cm_offset; 555 int start_pg, stop_pg, cm_offset;
557 int has_shmem = 0; 556 int has_shmem = 0;
558 struct hw_info *local_hw_info; 557 struct hw_info *local_hw_info;
559 struct ei_device *ei_local;
560 558
561 dev_dbg(&link->dev, "pcnet_config\n"); 559 dev_dbg(&link->dev, "pcnet_config\n");
562 560
@@ -606,8 +604,6 @@ static int pcnet_config(struct pcmcia_device *link)
606 mii_phy_probe(dev); 604 mii_phy_probe(dev);
607 605
608 SET_NETDEV_DEV(dev, &link->dev); 606 SET_NETDEV_DEV(dev, &link->dev);
609 ei_local = netdev_priv(dev);
610 ei_local->msg_enable = pcnet_msg_enable;
611 607
612 if (register_netdev(dev) != 0) { 608 if (register_netdev(dev) != 0) {
613 pr_notice("register_netdev() failed\n"); 609 pr_notice("register_netdev() failed\n");
diff --git a/drivers/net/ethernet/8390/wd.c b/drivers/net/ethernet/8390/wd.c
index 6efa2722f850..fb17c2c7e1dd 100644
--- a/drivers/net/ethernet/8390/wd.c
+++ b/drivers/net/ethernet/8390/wd.c
@@ -299,7 +299,7 @@ static int __init wd_probe1(struct net_device *dev, int ioaddr)
299 299
300 outb_p(0x00, nic_addr+EN0_IMR); /* Mask all intrs. again. */ 300 outb_p(0x00, nic_addr+EN0_IMR); /* Mask all intrs. again. */
301 301
302 if (netif_msg_drv(ei_local)) 302 if (wd_msg_enable & NETIF_MSG_PROBE)
303 pr_cont(" autoirq is %d", dev->irq); 303 pr_cont(" autoirq is %d", dev->irq);
304 if (dev->irq < 2) 304 if (dev->irq < 2)
305 dev->irq = word16 ? 10 : 5; 305 dev->irq = word16 ? 10 : 5;
diff --git a/drivers/net/ethernet/8390/zorro8390.c b/drivers/net/ethernet/8390/zorro8390.c
index 6d93956b293b..35a500a21521 100644
--- a/drivers/net/ethernet/8390/zorro8390.c
+++ b/drivers/net/ethernet/8390/zorro8390.c
@@ -44,8 +44,6 @@
44static const char version[] = 44static const char version[] =
45 "8390.c:v1.10cvs 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n"; 45 "8390.c:v1.10cvs 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
46 46
47static u32 zorro8390_msg_enable;
48
49#include "lib8390.c" 47#include "lib8390.c"
50 48
51#define DRV_NAME "zorro8390" 49#define DRV_NAME "zorro8390"
@@ -296,7 +294,6 @@ static int zorro8390_init(struct net_device *dev, unsigned long board,
296 int err; 294 int err;
297 unsigned char SA_prom[32]; 295 unsigned char SA_prom[32];
298 int start_page, stop_page; 296 int start_page, stop_page;
299 struct ei_device *ei_local = netdev_priv(dev);
300 static u32 zorro8390_offsets[16] = { 297 static u32 zorro8390_offsets[16] = {
301 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 298 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e,
302 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, 299 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
@@ -388,8 +385,6 @@ static int zorro8390_init(struct net_device *dev, unsigned long board,
388 dev->netdev_ops = &zorro8390_netdev_ops; 385 dev->netdev_ops = &zorro8390_netdev_ops;
389 __NS8390_init(dev, 0); 386 __NS8390_init(dev, 0);
390 387
391 ei_local->msg_enable = zorro8390_msg_enable;
392
393 err = register_netdev(dev); 388 err = register_netdev(dev);
394 if (err) { 389 if (err) {
395 free_irq(IRQ_AMIGA_PORTS, dev); 390 free_irq(IRQ_AMIGA_PORTS, dev);
diff --git a/drivers/net/ethernet/amd/amd8111e.c b/drivers/net/ethernet/amd/amd8111e.c
index 358f7ab77c70..c99e3e845ac0 100644
--- a/drivers/net/ethernet/amd/amd8111e.c
+++ b/drivers/net/ethernet/amd/amd8111e.c
@@ -649,7 +649,7 @@ static void amd8111e_free_ring(struct amd8111e_priv *lp)
649static int amd8111e_tx(struct net_device *dev) 649static int amd8111e_tx(struct net_device *dev)
650{ 650{
651 struct amd8111e_priv *lp = netdev_priv(dev); 651 struct amd8111e_priv *lp = netdev_priv(dev);
652 int tx_index = lp->tx_complete_idx & TX_RING_DR_MOD_MASK; 652 int tx_index;
653 int status; 653 int status;
654 /* Complete all the transmit packet */ 654 /* Complete all the transmit packet */
655 while (lp->tx_complete_idx != lp->tx_idx){ 655 while (lp->tx_complete_idx != lp->tx_idx){
diff --git a/drivers/net/ethernet/apple/macmace.c b/drivers/net/ethernet/apple/macmace.c
index f17a160dbff2..137cbb470af2 100644
--- a/drivers/net/ethernet/apple/macmace.c
+++ b/drivers/net/ethernet/apple/macmace.c
@@ -247,8 +247,8 @@ static int mace_probe(struct platform_device *pdev)
247 dev->netdev_ops = &mace_netdev_ops; 247 dev->netdev_ops = &mace_netdev_ops;
248 dev->watchdog_timeo = TX_TIMEOUT; 248 dev->watchdog_timeo = TX_TIMEOUT;
249 249
250 printk(KERN_INFO "%s: 68K MACE, hardware address %pM\n", 250 pr_info("Onboard MACE, hardware address %pM, chip revision 0x%04X\n",
251 dev->name, dev->dev_addr); 251 dev->dev_addr, mp->chipid);
252 252
253 err = register_netdev(dev); 253 err = register_netdev(dev);
254 if (!err) 254 if (!err)
@@ -589,7 +589,6 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id)
589 else if (fs & (UFLO|LCOL|RTRY)) { 589 else if (fs & (UFLO|LCOL|RTRY)) {
590 ++dev->stats.tx_aborted_errors; 590 ++dev->stats.tx_aborted_errors;
591 if (mb->xmtfs & UFLO) { 591 if (mb->xmtfs & UFLO) {
592 printk(KERN_ERR "%s: DMA underrun.\n", dev->name);
593 dev->stats.tx_fifo_errors++; 592 dev->stats.tx_fifo_errors++;
594 mace_txdma_reset(dev); 593 mace_txdma_reset(dev);
595 } 594 }
@@ -644,10 +643,8 @@ static void mace_dma_rx_frame(struct net_device *dev, struct mace_frame *mf)
644 643
645 if (frame_status & (RS_OFLO | RS_CLSN | RS_FRAMERR | RS_FCSERR)) { 644 if (frame_status & (RS_OFLO | RS_CLSN | RS_FRAMERR | RS_FCSERR)) {
646 dev->stats.rx_errors++; 645 dev->stats.rx_errors++;
647 if (frame_status & RS_OFLO) { 646 if (frame_status & RS_OFLO)
648 printk(KERN_DEBUG "%s: fifo overflow.\n", dev->name);
649 dev->stats.rx_fifo_errors++; 647 dev->stats.rx_fifo_errors++;
650 }
651 if (frame_status & RS_CLSN) 648 if (frame_status & RS_CLSN)
652 dev->stats.collisions++; 649 dev->stats.collisions++;
653 if (frame_status & RS_FRAMERR) 650 if (frame_status & RS_FRAMERR)
@@ -770,18 +767,4 @@ static struct platform_driver mac_mace_driver = {
770 }, 767 },
771}; 768};
772 769
773static int __init mac_mace_init_module(void) 770module_platform_driver(mac_mace_driver);
774{
775 if (!MACH_IS_MAC)
776 return -ENODEV;
777
778 return platform_driver_register(&mac_mace_driver);
779}
780
781static void __exit mac_mace_cleanup_module(void)
782{
783 platform_driver_unregister(&mac_mace_driver);
784}
785
786module_init(mac_mace_init_module);
787module_exit(mac_mace_cleanup_module);
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/Makefile b/drivers/net/ethernet/aquantia/atlantic/hw_atl/Makefile
new file mode 100644
index 000000000000..805fa28f391a
--- /dev/null
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/Makefile
@@ -0,0 +1,2 @@
1# SPDX-License-Identifier: GPL-2.0
2# kbuild requires Makefile in a directory to build individual objects
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index e84afcf1ecb5..d09bd43680b3 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -472,8 +472,44 @@ static int macb_mii_probe(struct net_device *dev)
472 struct macb *bp = netdev_priv(dev); 472 struct macb *bp = netdev_priv(dev);
473 struct macb_platform_data *pdata; 473 struct macb_platform_data *pdata;
474 struct phy_device *phydev; 474 struct phy_device *phydev;
475 int phy_irq; 475 struct device_node *np;
476 int ret; 476 int phy_irq, ret, i;
477
478 pdata = dev_get_platdata(&bp->pdev->dev);
479 np = bp->pdev->dev.of_node;
480 ret = 0;
481
482 if (np) {
483 if (of_phy_is_fixed_link(np)) {
484 if (of_phy_register_fixed_link(np) < 0) {
485 dev_err(&bp->pdev->dev,
486 "broken fixed-link specification\n");
487 return -ENODEV;
488 }
489 bp->phy_node = of_node_get(np);
490 } else {
491 bp->phy_node = of_parse_phandle(np, "phy-handle", 0);
492 /* fallback to standard phy registration if no
493 * phy-handle was found nor any phy found during
494 * dt phy registration
495 */
496 if (!bp->phy_node && !phy_find_first(bp->mii_bus)) {
497 for (i = 0; i < PHY_MAX_ADDR; i++) {
498 struct phy_device *phydev;
499
500 phydev = mdiobus_scan(bp->mii_bus, i);
501 if (IS_ERR(phydev) &&
502 PTR_ERR(phydev) != -ENODEV) {
503 ret = PTR_ERR(phydev);
504 break;
505 }
506 }
507
508 if (ret)
509 return -ENODEV;
510 }
511 }
512 }
477 513
478 if (bp->phy_node) { 514 if (bp->phy_node) {
479 phydev = of_phy_connect(dev, bp->phy_node, 515 phydev = of_phy_connect(dev, bp->phy_node,
@@ -488,7 +524,6 @@ static int macb_mii_probe(struct net_device *dev)
488 return -ENXIO; 524 return -ENXIO;
489 } 525 }
490 526
491 pdata = dev_get_platdata(&bp->pdev->dev);
492 if (pdata) { 527 if (pdata) {
493 if (gpio_is_valid(pdata->phy_irq_pin)) { 528 if (gpio_is_valid(pdata->phy_irq_pin)) {
494 ret = devm_gpio_request(&bp->pdev->dev, 529 ret = devm_gpio_request(&bp->pdev->dev,
@@ -533,7 +568,7 @@ static int macb_mii_init(struct macb *bp)
533{ 568{
534 struct macb_platform_data *pdata; 569 struct macb_platform_data *pdata;
535 struct device_node *np; 570 struct device_node *np;
536 int err = -ENXIO, i; 571 int err;
537 572
538 /* Enable management port */ 573 /* Enable management port */
539 macb_writel(bp, NCR, MACB_BIT(MPE)); 574 macb_writel(bp, NCR, MACB_BIT(MPE));
@@ -556,43 +591,10 @@ static int macb_mii_init(struct macb *bp)
556 dev_set_drvdata(&bp->dev->dev, bp->mii_bus); 591 dev_set_drvdata(&bp->dev->dev, bp->mii_bus);
557 592
558 np = bp->pdev->dev.of_node; 593 np = bp->pdev->dev.of_node;
559 if (np) {
560 if (of_phy_is_fixed_link(np)) {
561 if (of_phy_register_fixed_link(np) < 0) {
562 dev_err(&bp->pdev->dev,
563 "broken fixed-link specification\n");
564 goto err_out_unregister_bus;
565 }
566 bp->phy_node = of_node_get(np);
567
568 err = mdiobus_register(bp->mii_bus);
569 } else {
570 /* try dt phy registration */
571 err = of_mdiobus_register(bp->mii_bus, np);
572
573 /* fallback to standard phy registration if no phy were
574 * found during dt phy registration
575 */
576 if (!err && !phy_find_first(bp->mii_bus)) {
577 for (i = 0; i < PHY_MAX_ADDR; i++) {
578 struct phy_device *phydev;
579
580 phydev = mdiobus_scan(bp->mii_bus, i);
581 if (IS_ERR(phydev) &&
582 PTR_ERR(phydev) != -ENODEV) {
583 err = PTR_ERR(phydev);
584 break;
585 }
586 }
587 594
588 if (err) 595 if (np) {
589 goto err_out_unregister_bus; 596 err = of_mdiobus_register(bp->mii_bus, np);
590 }
591 }
592 } else { 597 } else {
593 for (i = 0; i < PHY_MAX_ADDR; i++)
594 bp->mii_bus->irq[i] = PHY_POLL;
595
596 if (pdata) 598 if (pdata)
597 bp->mii_bus->phy_mask = pdata->phy_mask; 599 bp->mii_bus->phy_mask = pdata->phy_mask;
598 600
@@ -610,10 +612,10 @@ static int macb_mii_init(struct macb *bp)
610 612
611err_out_unregister_bus: 613err_out_unregister_bus:
612 mdiobus_unregister(bp->mii_bus); 614 mdiobus_unregister(bp->mii_bus);
613err_out_free_mdiobus:
614 of_node_put(bp->phy_node);
615 if (np && of_phy_is_fixed_link(np)) 615 if (np && of_phy_is_fixed_link(np))
616 of_phy_deregister_fixed_link(np); 616 of_phy_deregister_fixed_link(np);
617err_out_free_mdiobus:
618 of_node_put(bp->phy_node);
617 mdiobus_free(bp->mii_bus); 619 mdiobus_free(bp->mii_bus);
618err_out: 620err_out:
619 return err; 621 return err;
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_core.c b/drivers/net/ethernet/cavium/liquidio/lio_core.c
index 32ae63b6f20e..666cf7e9cd09 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_core.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_core.c
@@ -164,15 +164,6 @@ void liquidio_link_ctrl_cmd_completion(void *nctrl_ptr)
164 } 164 }
165 break; 165 break;
166 166
167 case OCTNET_CMD_CHANGE_MTU:
168 /* If command is successful, change the MTU. */
169 netif_info(lio, probe, lio->netdev, "MTU Changed from %d to %d\n",
170 netdev->mtu, nctrl->ncmd.s.param1);
171 netdev->mtu = nctrl->ncmd.s.param1;
172 queue_delayed_work(lio->link_status_wq.wq,
173 &lio->link_status_wq.wk.work, 0);
174 break;
175
176 case OCTNET_CMD_GPIO_ACCESS: 167 case OCTNET_CMD_GPIO_ACCESS:
177 netif_info(lio, probe, lio->netdev, "LED Flashing visual identification\n"); 168 netif_info(lio, probe, lio->netdev, "LED Flashing visual identification\n");
178 169
@@ -571,7 +562,8 @@ liquidio_push_packet(u32 octeon_id __attribute__((unused)),
571 562
572 napi_gro_receive(napi, skb); 563 napi_gro_receive(napi, skb);
573 564
574 droq->stats.rx_bytes_received += len; 565 droq->stats.rx_bytes_received += len -
566 rh->r_dh.len * BYTES_PER_DHLEN_UNIT;
575 droq->stats.rx_pkts_received++; 567 droq->stats.rx_pkts_received++;
576 } else { 568 } else {
577 recv_buffer_free(skb); 569 recv_buffer_free(skb);
@@ -635,9 +627,7 @@ static int liquidio_napi_poll(struct napi_struct *napi, int budget)
635 iq_no = droq->q_no; 627 iq_no = droq->q_no;
636 628
637 /* Handle Droq descriptors */ 629 /* Handle Droq descriptors */
638 work_done = octeon_process_droq_poll_cmd(oct, droq->q_no, 630 work_done = octeon_droq_process_poll_pkts(oct, droq, budget);
639 POLL_EVENT_PROCESS_PKTS,
640 budget);
641 631
642 /* Flush the instruction queue */ 632 /* Flush the instruction queue */
643 iq = oct->instr_queue[iq_no]; 633 iq = oct->instr_queue[iq_no];
@@ -668,8 +658,7 @@ static int liquidio_napi_poll(struct napi_struct *napi, int budget)
668 tx_done = 1; 658 tx_done = 1;
669 napi_complete_done(napi, work_done); 659 napi_complete_done(napi, work_done);
670 660
671 octeon_process_droq_poll_cmd(droq->oct_dev, droq->q_no, 661 octeon_enable_irq(droq->oct_dev, droq->q_no);
672 POLL_EVENT_ENABLE_INTR, 0);
673 return 0; 662 return 0;
674 } 663 }
675 664
@@ -1080,3 +1069,88 @@ int octeon_setup_interrupt(struct octeon_device *oct, u32 num_ioqs)
1080 } 1069 }
1081 return 0; 1070 return 0;
1082} 1071}
1072
1073static void liquidio_change_mtu_completion(struct octeon_device *oct,
1074 u32 status, void *buf)
1075{
1076 struct octeon_soft_command *sc = (struct octeon_soft_command *)buf;
1077 struct liquidio_if_cfg_context *ctx;
1078
1079 ctx = (struct liquidio_if_cfg_context *)sc->ctxptr;
1080
1081 if (status) {
1082 dev_err(&oct->pci_dev->dev, "MTU change failed. Status: %llx\n",
1083 CVM_CAST64(status));
1084 WRITE_ONCE(ctx->cond, LIO_CHANGE_MTU_FAIL);
1085 } else {
1086 WRITE_ONCE(ctx->cond, LIO_CHANGE_MTU_SUCCESS);
1087 }
1088
1089 /* This barrier is required to be sure that the response has been
1090 * written fully before waking up the handler
1091 */
1092 wmb();
1093
1094 wake_up_interruptible(&ctx->wc);
1095}
1096
1097/**
1098 * \brief Net device change_mtu
1099 * @param netdev network device
1100 */
1101int liquidio_change_mtu(struct net_device *netdev, int new_mtu)
1102{
1103 struct lio *lio = GET_LIO(netdev);
1104 struct octeon_device *oct = lio->oct_dev;
1105 struct liquidio_if_cfg_context *ctx;
1106 struct octeon_soft_command *sc;
1107 union octnet_cmd *ncmd;
1108 int ctx_size;
1109 int ret = 0;
1110
1111 ctx_size = sizeof(struct liquidio_if_cfg_context);
1112 sc = (struct octeon_soft_command *)
1113 octeon_alloc_soft_command(oct, OCTNET_CMD_SIZE, 16, ctx_size);
1114
1115 ncmd = (union octnet_cmd *)sc->virtdptr;
1116 ctx = (struct liquidio_if_cfg_context *)sc->ctxptr;
1117
1118 WRITE_ONCE(ctx->cond, 0);
1119 ctx->octeon_id = lio_get_device_id(oct);
1120 init_waitqueue_head(&ctx->wc);
1121
1122 ncmd->u64 = 0;
1123 ncmd->s.cmd = OCTNET_CMD_CHANGE_MTU;
1124 ncmd->s.param1 = new_mtu;
1125
1126 octeon_swap_8B_data((u64 *)ncmd, (OCTNET_CMD_SIZE >> 3));
1127
1128 sc->iq_no = lio->linfo.txpciq[0].s.q_no;
1129
1130 octeon_prepare_soft_command(oct, sc, OPCODE_NIC,
1131 OPCODE_NIC_CMD, 0, 0, 0);
1132
1133 sc->callback = liquidio_change_mtu_completion;
1134 sc->callback_arg = sc;
1135 sc->wait_time = 100;
1136
1137 ret = octeon_send_soft_command(oct, sc);
1138 if (ret == IQ_SEND_FAILED) {
1139 netif_info(lio, rx_err, lio->netdev, "Failed to change MTU\n");
1140 return -EINVAL;
1141 }
1142 /* Sleep on a wait queue till the cond flag indicates that the
1143 * response arrived or timed-out.
1144 */
1145 if (sleep_cond(&ctx->wc, &ctx->cond) == -EINTR ||
1146 ctx->cond == LIO_CHANGE_MTU_FAIL) {
1147 octeon_free_soft_command(oct, sc);
1148 return -EINVAL;
1149 }
1150
1151 netdev->mtu = new_mtu;
1152 lio->mtu = new_mtu;
1153
1154 octeon_free_soft_command(oct, sc);
1155 return 0;
1156}
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_ethtool.c b/drivers/net/ethernet/cavium/liquidio/lio_ethtool.c
index a63ddf07f168..550ac29682a5 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_ethtool.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_ethtool.c
@@ -232,10 +232,16 @@ static int lio_get_link_ksettings(struct net_device *netdev,
232 232
233 linfo = &lio->linfo; 233 linfo = &lio->linfo;
234 234
235 if (linfo->link.s.if_mode == INTERFACE_MODE_XAUI || 235 switch (linfo->link.s.phy_type) {
236 linfo->link.s.if_mode == INTERFACE_MODE_RXAUI || 236 case LIO_PHY_PORT_TP:
237 linfo->link.s.if_mode == INTERFACE_MODE_XLAUI || 237 ecmd->base.port = PORT_TP;
238 linfo->link.s.if_mode == INTERFACE_MODE_XFI) { 238 supported = (SUPPORTED_10000baseT_Full |
239 SUPPORTED_TP | SUPPORTED_Pause);
240 advertising = (ADVERTISED_10000baseT_Full | ADVERTISED_Pause);
241 ecmd->base.autoneg = AUTONEG_DISABLE;
242 break;
243
244 case LIO_PHY_PORT_FIBRE:
239 ecmd->base.port = PORT_FIBRE; 245 ecmd->base.port = PORT_FIBRE;
240 246
241 if (linfo->link.s.speed == SPEED_10000) { 247 if (linfo->link.s.speed == SPEED_10000) {
@@ -245,12 +251,18 @@ static int lio_get_link_ksettings(struct net_device *netdev,
245 251
246 supported |= SUPPORTED_FIBRE | SUPPORTED_Pause; 252 supported |= SUPPORTED_FIBRE | SUPPORTED_Pause;
247 advertising |= ADVERTISED_Pause; 253 advertising |= ADVERTISED_Pause;
254 ecmd->base.autoneg = AUTONEG_DISABLE;
255 break;
256 }
257
258 if (linfo->link.s.if_mode == INTERFACE_MODE_XAUI ||
259 linfo->link.s.if_mode == INTERFACE_MODE_RXAUI ||
260 linfo->link.s.if_mode == INTERFACE_MODE_XLAUI ||
261 linfo->link.s.if_mode == INTERFACE_MODE_XFI) {
248 ethtool_convert_legacy_u32_to_link_mode( 262 ethtool_convert_legacy_u32_to_link_mode(
249 ecmd->link_modes.supported, supported); 263 ecmd->link_modes.supported, supported);
250 ethtool_convert_legacy_u32_to_link_mode( 264 ethtool_convert_legacy_u32_to_link_mode(
251 ecmd->link_modes.advertising, advertising); 265 ecmd->link_modes.advertising, advertising);
252 ecmd->base.autoneg = AUTONEG_DISABLE;
253
254 } else { 266 } else {
255 dev_err(&oct->pci_dev->dev, "Unknown link interface reported %d\n", 267 dev_err(&oct->pci_dev->dev, "Unknown link interface reported %d\n",
256 linfo->link.s.if_mode); 268 linfo->link.s.if_mode);
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c
index a5eecd895a82..21280cb66550 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_main.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c
@@ -91,18 +91,9 @@ static int octeon_console_debug_enabled(u32 console)
91 */ 91 */
92#define LIO_SYNC_OCTEON_TIME_INTERVAL_MS 60000 92#define LIO_SYNC_OCTEON_TIME_INTERVAL_MS 60000
93 93
94struct liquidio_if_cfg_context { 94struct lio_trusted_vf_ctx {
95 int octeon_id; 95 struct completion complete;
96 96 int status;
97 wait_queue_head_t wc;
98
99 int cond;
100};
101
102struct liquidio_if_cfg_resp {
103 u64 rh;
104 struct liquidio_if_cfg_info cfg_info;
105 u64 status;
106}; 97};
107 98
108struct liquidio_rx_ctl_context { 99struct liquidio_rx_ctl_context {
@@ -841,8 +832,12 @@ static void octnet_link_status_change(struct work_struct *work)
841 struct cavium_wk *wk = (struct cavium_wk *)work; 832 struct cavium_wk *wk = (struct cavium_wk *)work;
842 struct lio *lio = (struct lio *)wk->ctxptr; 833 struct lio *lio = (struct lio *)wk->ctxptr;
843 834
835 /* lio->linfo.link.s.mtu always contains max MTU of the lio interface.
836 * this API is invoked only when new max-MTU of the interface is
837 * less than current MTU.
838 */
844 rtnl_lock(); 839 rtnl_lock();
845 call_netdevice_notifiers(NETDEV_CHANGEMTU, lio->netdev); 840 dev_set_mtu(lio->netdev, lio->linfo.link.s.mtu);
846 rtnl_unlock(); 841 rtnl_unlock();
847} 842}
848 843
@@ -891,7 +886,11 @@ static inline void update_link_status(struct net_device *netdev,
891{ 886{
892 struct lio *lio = GET_LIO(netdev); 887 struct lio *lio = GET_LIO(netdev);
893 int changed = (lio->linfo.link.u64 != ls->u64); 888 int changed = (lio->linfo.link.u64 != ls->u64);
889 int current_max_mtu = lio->linfo.link.s.mtu;
890 struct octeon_device *oct = lio->oct_dev;
894 891
892 dev_dbg(&oct->pci_dev->dev, "%s: lio->linfo.link.u64=%llx, ls->u64=%llx\n",
893 __func__, lio->linfo.link.u64, ls->u64);
895 lio->linfo.link.u64 = ls->u64; 894 lio->linfo.link.u64 = ls->u64;
896 895
897 if ((lio->intf_open) && (changed)) { 896 if ((lio->intf_open) && (changed)) {
@@ -899,12 +898,26 @@ static inline void update_link_status(struct net_device *netdev,
899 lio->link_changes++; 898 lio->link_changes++;
900 899
901 if (lio->linfo.link.s.link_up) { 900 if (lio->linfo.link.s.link_up) {
901 dev_dbg(&oct->pci_dev->dev, "%s: link_up", __func__);
902 netif_carrier_on(netdev); 902 netif_carrier_on(netdev);
903 txqs_wake(netdev); 903 txqs_wake(netdev);
904 } else { 904 } else {
905 dev_dbg(&oct->pci_dev->dev, "%s: link_off", __func__);
905 netif_carrier_off(netdev); 906 netif_carrier_off(netdev);
906 stop_txq(netdev); 907 stop_txq(netdev);
907 } 908 }
909 if (lio->linfo.link.s.mtu != current_max_mtu) {
910 netif_info(lio, probe, lio->netdev, "Max MTU changed from %d to %d\n",
911 current_max_mtu, lio->linfo.link.s.mtu);
912 netdev->max_mtu = lio->linfo.link.s.mtu;
913 }
914 if (lio->linfo.link.s.mtu < netdev->mtu) {
915 dev_warn(&oct->pci_dev->dev,
916 "Current MTU is higher than new max MTU; Reducing the current mtu from %d to %d\n",
917 netdev->mtu, lio->linfo.link.s.mtu);
918 queue_delayed_work(lio->link_status_wq.wq,
919 &lio->link_status_wq.wk.work, 0);
920 }
908 } 921 }
909} 922}
910 923
@@ -2449,38 +2462,6 @@ static struct net_device_stats *liquidio_get_stats(struct net_device *netdev)
2449} 2462}
2450 2463
2451/** 2464/**
2452 * \brief Net device change_mtu
2453 * @param netdev network device
2454 */
2455static int liquidio_change_mtu(struct net_device *netdev, int new_mtu)
2456{
2457 struct lio *lio = GET_LIO(netdev);
2458 struct octeon_device *oct = lio->oct_dev;
2459 struct octnic_ctrl_pkt nctrl;
2460 int ret = 0;
2461
2462 memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt));
2463
2464 nctrl.ncmd.u64 = 0;
2465 nctrl.ncmd.s.cmd = OCTNET_CMD_CHANGE_MTU;
2466 nctrl.ncmd.s.param1 = new_mtu;
2467 nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
2468 nctrl.wait_time = 100;
2469 nctrl.netpndev = (u64)netdev;
2470 nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
2471
2472 ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
2473 if (ret < 0) {
2474 dev_err(&oct->pci_dev->dev, "Failed to set MTU\n");
2475 return -1;
2476 }
2477
2478 lio->mtu = new_mtu;
2479
2480 return 0;
2481}
2482
2483/**
2484 * \brief Handler for SIOCSHWTSTAMP ioctl 2465 * \brief Handler for SIOCSHWTSTAMP ioctl
2485 * @param netdev network device 2466 * @param netdev network device
2486 * @param ifr interface request 2467 * @param ifr interface request
@@ -3289,10 +3270,120 @@ static int liquidio_get_vf_config(struct net_device *netdev, int vfidx,
3289 ether_addr_copy(&ivi->mac[0], macaddr); 3270 ether_addr_copy(&ivi->mac[0], macaddr);
3290 ivi->vlan = oct->sriov_info.vf_vlantci[vfidx] & VLAN_VID_MASK; 3271 ivi->vlan = oct->sriov_info.vf_vlantci[vfidx] & VLAN_VID_MASK;
3291 ivi->qos = oct->sriov_info.vf_vlantci[vfidx] >> VLAN_PRIO_SHIFT; 3272 ivi->qos = oct->sriov_info.vf_vlantci[vfidx] >> VLAN_PRIO_SHIFT;
3273 if (oct->sriov_info.trusted_vf.active &&
3274 oct->sriov_info.trusted_vf.id == vfidx)
3275 ivi->trusted = true;
3276 else
3277 ivi->trusted = false;
3292 ivi->linkstate = oct->sriov_info.vf_linkstate[vfidx]; 3278 ivi->linkstate = oct->sriov_info.vf_linkstate[vfidx];
3293 return 0; 3279 return 0;
3294} 3280}
3295 3281
3282static void trusted_vf_callback(struct octeon_device *oct_dev,
3283 u32 status, void *ptr)
3284{
3285 struct octeon_soft_command *sc = (struct octeon_soft_command *)ptr;
3286 struct lio_trusted_vf_ctx *ctx;
3287
3288 ctx = (struct lio_trusted_vf_ctx *)sc->ctxptr;
3289 ctx->status = status;
3290
3291 complete(&ctx->complete);
3292}
3293
3294static int liquidio_send_vf_trust_cmd(struct lio *lio, int vfidx, bool trusted)
3295{
3296 struct octeon_device *oct = lio->oct_dev;
3297 struct lio_trusted_vf_ctx *ctx;
3298 struct octeon_soft_command *sc;
3299 int ctx_size, retval;
3300
3301 ctx_size = sizeof(struct lio_trusted_vf_ctx);
3302 sc = octeon_alloc_soft_command(oct, 0, 0, ctx_size);
3303
3304 ctx = (struct lio_trusted_vf_ctx *)sc->ctxptr;
3305 init_completion(&ctx->complete);
3306
3307 sc->iq_no = lio->linfo.txpciq[0].s.q_no;
3308
3309 /* vfidx is 0 based, but vf_num (param1) is 1 based */
3310 octeon_prepare_soft_command(oct, sc, OPCODE_NIC,
3311 OPCODE_NIC_SET_TRUSTED_VF, 0, vfidx + 1,
3312 trusted);
3313
3314 sc->callback = trusted_vf_callback;
3315 sc->callback_arg = sc;
3316 sc->wait_time = 1000;
3317
3318 retval = octeon_send_soft_command(oct, sc);
3319 if (retval == IQ_SEND_FAILED) {
3320 retval = -1;
3321 } else {
3322 /* Wait for response or timeout */
3323 if (wait_for_completion_timeout(&ctx->complete,
3324 msecs_to_jiffies(2000)))
3325 retval = ctx->status;
3326 else
3327 retval = -1;
3328 }
3329
3330 octeon_free_soft_command(oct, sc);
3331
3332 return retval;
3333}
3334
3335static int liquidio_set_vf_trust(struct net_device *netdev, int vfidx,
3336 bool setting)
3337{
3338 struct lio *lio = GET_LIO(netdev);
3339 struct octeon_device *oct = lio->oct_dev;
3340
3341 if (strcmp(oct->fw_info.liquidio_firmware_version, "1.7.1") < 0) {
3342 /* trusted vf is not supported by firmware older than 1.7.1 */
3343 return -EOPNOTSUPP;
3344 }
3345
3346 if (vfidx < 0 || vfidx >= oct->sriov_info.num_vfs_alloced) {
3347 netif_info(lio, drv, lio->netdev, "Invalid vfidx %d\n", vfidx);
3348 return -EINVAL;
3349 }
3350
3351 if (setting) {
3352 /* Set */
3353
3354 if (oct->sriov_info.trusted_vf.active &&
3355 oct->sriov_info.trusted_vf.id == vfidx)
3356 return 0;
3357
3358 if (oct->sriov_info.trusted_vf.active) {
3359 netif_info(lio, drv, lio->netdev, "More than one trusted VF is not allowed\n");
3360 return -EPERM;
3361 }
3362 } else {
3363 /* Clear */
3364
3365 if (!oct->sriov_info.trusted_vf.active)
3366 return 0;
3367 }
3368
3369 if (!liquidio_send_vf_trust_cmd(lio, vfidx, setting)) {
3370 if (setting) {
3371 oct->sriov_info.trusted_vf.id = vfidx;
3372 oct->sriov_info.trusted_vf.active = true;
3373 } else {
3374 oct->sriov_info.trusted_vf.active = false;
3375 }
3376
3377 netif_info(lio, drv, lio->netdev, "VF %u is %strusted\n", vfidx,
3378 setting ? "" : "not ");
3379 } else {
3380 netif_info(lio, drv, lio->netdev, "Failed to set VF trusted\n");
3381 return -1;
3382 }
3383
3384 return 0;
3385}
3386
3296static int liquidio_set_vf_link_state(struct net_device *netdev, int vfidx, 3387static int liquidio_set_vf_link_state(struct net_device *netdev, int vfidx,
3297 int linkstate) 3388 int linkstate)
3298{ 3389{
@@ -3423,6 +3514,7 @@ static const struct net_device_ops lionetdevops = {
3423 .ndo_set_vf_mac = liquidio_set_vf_mac, 3514 .ndo_set_vf_mac = liquidio_set_vf_mac,
3424 .ndo_set_vf_vlan = liquidio_set_vf_vlan, 3515 .ndo_set_vf_vlan = liquidio_set_vf_vlan,
3425 .ndo_get_vf_config = liquidio_get_vf_config, 3516 .ndo_get_vf_config = liquidio_get_vf_config,
3517 .ndo_set_vf_trust = liquidio_set_vf_trust,
3426 .ndo_set_vf_link_state = liquidio_set_vf_link_state, 3518 .ndo_set_vf_link_state = liquidio_set_vf_link_state,
3427}; 3519};
3428 3520
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c
index fd70a4844e2d..3342d64b7081 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c
@@ -40,20 +40,6 @@ MODULE_PARM_DESC(debug, "NETIF_MSG debug bits");
40 40
41#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK) 41#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK)
42 42
43struct liquidio_if_cfg_context {
44 int octeon_id;
45
46 wait_queue_head_t wc;
47
48 int cond;
49};
50
51struct liquidio_if_cfg_resp {
52 u64 rh;
53 struct liquidio_if_cfg_info cfg_info;
54 u64 status;
55};
56
57struct liquidio_rx_ctl_context { 43struct liquidio_rx_ctl_context {
58 int octeon_id; 44 int octeon_id;
59 45
@@ -564,8 +550,12 @@ static void octnet_link_status_change(struct work_struct *work)
564 struct cavium_wk *wk = (struct cavium_wk *)work; 550 struct cavium_wk *wk = (struct cavium_wk *)work;
565 struct lio *lio = (struct lio *)wk->ctxptr; 551 struct lio *lio = (struct lio *)wk->ctxptr;
566 552
553 /* lio->linfo.link.s.mtu always contains max MTU of the lio interface.
554 * this API is invoked only when new max-MTU of the interface is
555 * less than current MTU.
556 */
567 rtnl_lock(); 557 rtnl_lock();
568 call_netdevice_notifiers(NETDEV_CHANGEMTU, lio->netdev); 558 dev_set_mtu(lio->netdev, lio->linfo.link.s.mtu);
569 rtnl_unlock(); 559 rtnl_unlock();
570} 560}
571 561
@@ -613,6 +603,7 @@ static void update_link_status(struct net_device *netdev,
613 union oct_link_status *ls) 603 union oct_link_status *ls)
614{ 604{
615 struct lio *lio = GET_LIO(netdev); 605 struct lio *lio = GET_LIO(netdev);
606 int current_max_mtu = lio->linfo.link.s.mtu;
616 struct octeon_device *oct = lio->oct_dev; 607 struct octeon_device *oct = lio->oct_dev;
617 608
618 if ((lio->intf_open) && (lio->linfo.link.u64 != ls->u64)) { 609 if ((lio->intf_open) && (lio->linfo.link.u64 != ls->u64)) {
@@ -629,18 +620,17 @@ static void update_link_status(struct net_device *netdev,
629 txqs_stop(netdev); 620 txqs_stop(netdev);
630 } 621 }
631 622
632 if (lio->linfo.link.s.mtu != netdev->max_mtu) { 623 if (lio->linfo.link.s.mtu != current_max_mtu) {
633 dev_info(&oct->pci_dev->dev, "Max MTU Changed from %d to %d\n", 624 dev_info(&oct->pci_dev->dev,
634 netdev->max_mtu, lio->linfo.link.s.mtu); 625 "Max MTU Changed from %d to %d\n",
626 current_max_mtu, lio->linfo.link.s.mtu);
635 netdev->max_mtu = lio->linfo.link.s.mtu; 627 netdev->max_mtu = lio->linfo.link.s.mtu;
636 } 628 }
637 629
638 if (lio->linfo.link.s.mtu < netdev->mtu) { 630 if (lio->linfo.link.s.mtu < netdev->mtu) {
639 dev_warn(&oct->pci_dev->dev, 631 dev_warn(&oct->pci_dev->dev,
640 "PF has changed the MTU for gmx port. Reducing the mtu from %d to %d\n", 632 "Current MTU is higher than new max MTU; Reducing the current mtu from %d to %d\n",
641 netdev->mtu, lio->linfo.link.s.mtu); 633 netdev->mtu, lio->linfo.link.s.mtu);
642 lio->mtu = lio->linfo.link.s.mtu;
643 netdev->mtu = lio->linfo.link.s.mtu;
644 queue_delayed_work(lio->link_status_wq.wq, 634 queue_delayed_work(lio->link_status_wq.wq,
645 &lio->link_status_wq.wk.work, 0); 635 &lio->link_status_wq.wk.work, 0);
646 } 636 }
@@ -1538,41 +1528,6 @@ static struct net_device_stats *liquidio_get_stats(struct net_device *netdev)
1538} 1528}
1539 1529
1540/** 1530/**
1541 * \brief Net device change_mtu
1542 * @param netdev network device
1543 */
1544static int liquidio_change_mtu(struct net_device *netdev, int new_mtu)
1545{
1546 struct octnic_ctrl_pkt nctrl;
1547 struct octeon_device *oct;
1548 struct lio *lio;
1549 int ret = 0;
1550
1551 lio = GET_LIO(netdev);
1552 oct = lio->oct_dev;
1553
1554 memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt));
1555
1556 nctrl.ncmd.u64 = 0;
1557 nctrl.ncmd.s.cmd = OCTNET_CMD_CHANGE_MTU;
1558 nctrl.ncmd.s.param1 = new_mtu;
1559 nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
1560 nctrl.wait_time = LIO_CMD_WAIT_TM;
1561 nctrl.netpndev = (u64)netdev;
1562 nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
1563
1564 ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
1565 if (ret < 0) {
1566 dev_err(&oct->pci_dev->dev, "Failed to set MTU\n");
1567 return -EIO;
1568 }
1569
1570 lio->mtu = new_mtu;
1571
1572 return 0;
1573}
1574
1575/**
1576 * \brief Handler for SIOCSHWTSTAMP ioctl 1531 * \brief Handler for SIOCSHWTSTAMP ioctl
1577 * @param netdev network device 1532 * @param netdev network device
1578 * @param ifr interface request 1533 * @param ifr interface request
diff --git a/drivers/net/ethernet/cavium/liquidio/liquidio_common.h b/drivers/net/ethernet/cavium/liquidio/liquidio_common.h
index 522dcc4dcff7..82a783db5baf 100644
--- a/drivers/net/ethernet/cavium/liquidio/liquidio_common.h
+++ b/drivers/net/ethernet/cavium/liquidio/liquidio_common.h
@@ -84,6 +84,7 @@ enum octeon_tag_type {
84#define OPCODE_NIC_IF_CFG 0x09 84#define OPCODE_NIC_IF_CFG 0x09
85#define OPCODE_NIC_VF_DRV_NOTICE 0x0A 85#define OPCODE_NIC_VF_DRV_NOTICE 0x0A
86#define OPCODE_NIC_INTRMOD_PARAMS 0x0B 86#define OPCODE_NIC_INTRMOD_PARAMS 0x0B
87#define OPCODE_NIC_SET_TRUSTED_VF 0x13
87#define OPCODE_NIC_SYNC_OCTEON_TIME 0x14 88#define OPCODE_NIC_SYNC_OCTEON_TIME 0x14
88#define VF_DRV_LOADED 1 89#define VF_DRV_LOADED 1
89#define VF_DRV_REMOVED -1 90#define VF_DRV_REMOVED -1
@@ -192,7 +193,8 @@ static inline void add_sg_size(struct octeon_sg_entry *sg_entry,
192 193
193#define OCTNET_MAX_FRM_SIZE (16000 + OCTNET_FRM_HEADER_SIZE) 194#define OCTNET_MAX_FRM_SIZE (16000 + OCTNET_FRM_HEADER_SIZE)
194 195
195#define OCTNET_DEFAULT_FRM_SIZE (1500 + OCTNET_FRM_HEADER_SIZE) 196#define OCTNET_DEFAULT_MTU (1500)
197#define OCTNET_DEFAULT_FRM_SIZE (OCTNET_DEFAULT_MTU + OCTNET_FRM_HEADER_SIZE)
196 198
197/** NIC Commands are sent using this Octeon Input Queue */ 199/** NIC Commands are sent using this Octeon Input Queue */
198#define OCTNET_CMD_Q 0 200#define OCTNET_CMD_Q 0
@@ -675,9 +677,11 @@ union oct_link_status {
675 u64 if_mode:5; 677 u64 if_mode:5;
676 u64 pause:1; 678 u64 pause:1;
677 u64 flashing:1; 679 u64 flashing:1;
678 u64 reserved:15; 680 u64 phy_type:5;
681 u64 reserved:10;
679#else 682#else
680 u64 reserved:15; 683 u64 reserved:10;
684 u64 phy_type:5;
681 u64 flashing:1; 685 u64 flashing:1;
682 u64 pause:1; 686 u64 pause:1;
683 u64 if_mode:5; 687 u64 if_mode:5;
@@ -690,6 +694,12 @@ union oct_link_status {
690 } s; 694 } s;
691}; 695};
692 696
697enum lio_phy_type {
698 LIO_PHY_PORT_TP = 0x0,
699 LIO_PHY_PORT_FIBRE = 0x1,
700 LIO_PHY_PORT_UNKNOWN,
701};
702
693/** The txpciq info passed to host from the firmware */ 703/** The txpciq info passed to host from the firmware */
694 704
695union oct_txpciq { 705union oct_txpciq {
@@ -909,6 +919,12 @@ union oct_nic_if_cfg {
909 } s; 919 } s;
910}; 920};
911 921
922struct lio_trusted_vf {
923 uint64_t active: 1;
924 uint64_t id : 8;
925 uint64_t reserved: 55;
926};
927
912struct lio_time { 928struct lio_time {
913 s64 sec; /* seconds */ 929 s64 sec; /* seconds */
914 s64 nsec; /* nanoseconds */ 930 s64 nsec; /* nanoseconds */
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_device.h b/drivers/net/ethernet/cavium/liquidio/octeon_device.h
index 63b0c758a0a6..91937cc5c1d7 100644
--- a/drivers/net/ethernet/cavium/liquidio/octeon_device.h
+++ b/drivers/net/ethernet/cavium/liquidio/octeon_device.h
@@ -370,6 +370,8 @@ struct octeon_sriov_info {
370 370
371 u32 sriov_enabled; 371 u32 sriov_enabled;
372 372
373 struct lio_trusted_vf trusted_vf;
374
373 /*lookup table that maps DPI ring number to VF pci_dev struct pointer*/ 375 /*lookup table that maps DPI ring number to VF pci_dev struct pointer*/
374 struct pci_dev *dpiring_to_vfpcidev_lut[MAX_POSSIBLE_VFS]; 376 struct pci_dev *dpiring_to_vfpcidev_lut[MAX_POSSIBLE_VFS];
375 377
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_droq.c b/drivers/net/ethernet/cavium/liquidio/octeon_droq.c
index 3461d65ff4eb..f044718cea52 100644
--- a/drivers/net/ethernet/cavium/liquidio/octeon_droq.c
+++ b/drivers/net/ethernet/cavium/liquidio/octeon_droq.c
@@ -788,7 +788,7 @@ octeon_droq_process_packets(struct octeon_device *oct,
788 * called before calling this routine. 788 * called before calling this routine.
789 */ 789 */
790 790
791static int 791int
792octeon_droq_process_poll_pkts(struct octeon_device *oct, 792octeon_droq_process_poll_pkts(struct octeon_device *oct,
793 struct octeon_droq *droq, u32 budget) 793 struct octeon_droq *droq, u32 budget)
794{ 794{
@@ -835,71 +835,46 @@ octeon_droq_process_poll_pkts(struct octeon_device *oct,
835 return total_pkts_processed; 835 return total_pkts_processed;
836} 836}
837 837
838/* Enable Pkt Interrupt */
838int 839int
839octeon_process_droq_poll_cmd(struct octeon_device *oct, u32 q_no, int cmd, 840octeon_enable_irq(struct octeon_device *oct, u32 q_no)
840 u32 arg)
841{ 841{
842 struct octeon_droq *droq; 842 switch (oct->chip_id) {
843 843 case OCTEON_CN66XX:
844 droq = oct->droq[q_no]; 844 case OCTEON_CN68XX: {
845 struct octeon_cn6xxx *cn6xxx =
846 (struct octeon_cn6xxx *)oct->chip;
847 unsigned long flags;
848 u32 value;
845 849
846 if (cmd == POLL_EVENT_PROCESS_PKTS) 850 spin_lock_irqsave
847 return octeon_droq_process_poll_pkts(oct, droq, arg); 851 (&cn6xxx->lock_for_droq_int_enb_reg, flags);
852 value = octeon_read_csr(oct, CN6XXX_SLI_PKT_TIME_INT_ENB);
853 value |= (1 << q_no);
854 octeon_write_csr(oct, CN6XXX_SLI_PKT_TIME_INT_ENB, value);
855 value = octeon_read_csr(oct, CN6XXX_SLI_PKT_CNT_INT_ENB);
856 value |= (1 << q_no);
857 octeon_write_csr(oct, CN6XXX_SLI_PKT_CNT_INT_ENB, value);
848 858
849 if (cmd == POLL_EVENT_PENDING_PKTS) { 859 /* don't bother flushing the enables */
850 u32 pkt_cnt = atomic_read(&droq->pkts_pending);
851 860
852 return octeon_droq_process_packets(oct, droq, pkt_cnt); 861 spin_unlock_irqrestore
862 (&cn6xxx->lock_for_droq_int_enb_reg, flags);
853 } 863 }
854
855 if (cmd == POLL_EVENT_ENABLE_INTR) {
856 u32 value;
857 unsigned long flags;
858
859 /* Enable Pkt Interrupt */
860 switch (oct->chip_id) {
861 case OCTEON_CN66XX:
862 case OCTEON_CN68XX: {
863 struct octeon_cn6xxx *cn6xxx =
864 (struct octeon_cn6xxx *)oct->chip;
865 spin_lock_irqsave
866 (&cn6xxx->lock_for_droq_int_enb_reg, flags);
867 value =
868 octeon_read_csr(oct,
869 CN6XXX_SLI_PKT_TIME_INT_ENB);
870 value |= (1 << q_no);
871 octeon_write_csr(oct,
872 CN6XXX_SLI_PKT_TIME_INT_ENB,
873 value);
874 value =
875 octeon_read_csr(oct,
876 CN6XXX_SLI_PKT_CNT_INT_ENB);
877 value |= (1 << q_no);
878 octeon_write_csr(oct,
879 CN6XXX_SLI_PKT_CNT_INT_ENB,
880 value);
881
882 /* don't bother flushing the enables */
883
884 spin_unlock_irqrestore
885 (&cn6xxx->lock_for_droq_int_enb_reg, flags);
886 return 0;
887 }
888 break; 864 break;
889 case OCTEON_CN23XX_PF_VID: { 865 case OCTEON_CN23XX_PF_VID:
890 lio_enable_irq(oct->droq[q_no], oct->instr_queue[q_no]); 866 lio_enable_irq(oct->droq[q_no], oct->instr_queue[q_no]);
891 }
892 break; 867 break;
893 868
894 case OCTEON_CN23XX_VF_VID: 869 case OCTEON_CN23XX_VF_VID:
895 lio_enable_irq(oct->droq[q_no], oct->instr_queue[q_no]); 870 lio_enable_irq(oct->droq[q_no], oct->instr_queue[q_no]);
896 break; 871 break;
897 } 872 default:
898 return 0; 873 dev_err(&oct->pci_dev->dev, "%s Unknown Chip\n", __func__);
874 return 1;
899 } 875 }
900 876
901 dev_err(&oct->pci_dev->dev, "%s Unknown command: %d\n", __func__, cmd); 877 return 0;
902 return -EINVAL;
903} 878}
904 879
905int octeon_register_droq_ops(struct octeon_device *oct, u32 q_no, 880int octeon_register_droq_ops(struct octeon_device *oct, u32 q_no,
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_droq.h b/drivers/net/ethernet/cavium/liquidio/octeon_droq.h
index 815a9f56fd59..f28f262d4ab6 100644
--- a/drivers/net/ethernet/cavium/liquidio/octeon_droq.h
+++ b/drivers/net/ethernet/cavium/liquidio/octeon_droq.h
@@ -123,11 +123,6 @@ struct oct_droq_stats {
123 123
124}; 124};
125 125
126#define POLL_EVENT_INTR_ARRIVED 1
127#define POLL_EVENT_PROCESS_PKTS 2
128#define POLL_EVENT_PENDING_PKTS 3
129#define POLL_EVENT_ENABLE_INTR 4
130
131/* The maximum number of buffers that can be dispatched from the 126/* The maximum number of buffers that can be dispatched from the
132 * output/dma queue. Set to 64 assuming 1K buffers in DROQ and the fact that 127 * output/dma queue. Set to 64 assuming 1K buffers in DROQ and the fact that
133 * max packet size from DROQ is 64K. 128 * max packet size from DROQ is 64K.
@@ -414,8 +409,10 @@ int octeon_droq_process_packets(struct octeon_device *oct,
414 struct octeon_droq *droq, 409 struct octeon_droq *droq,
415 u32 budget); 410 u32 budget);
416 411
417int octeon_process_droq_poll_cmd(struct octeon_device *oct, u32 q_no, 412int octeon_droq_process_poll_pkts(struct octeon_device *oct,
418 int cmd, u32 arg); 413 struct octeon_droq *droq, u32 budget);
414
415int octeon_enable_irq(struct octeon_device *oct, u32 q_no);
419 416
420void octeon_droq_check_oom(struct octeon_droq *droq); 417void octeon_droq_check_oom(struct octeon_droq *droq);
421 418
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_mailbox.c b/drivers/net/ethernet/cavium/liquidio/octeon_mailbox.c
index 57af7df74ced..28e74ee23ff8 100644
--- a/drivers/net/ethernet/cavium/liquidio/octeon_mailbox.c
+++ b/drivers/net/ethernet/cavium/liquidio/octeon_mailbox.c
@@ -87,7 +87,7 @@ int octeon_mbox_read(struct octeon_mbox *mbox)
87 } 87 }
88 88
89 if (mbox->state & OCTEON_MBOX_STATE_REQUEST_RECEIVING) { 89 if (mbox->state & OCTEON_MBOX_STATE_REQUEST_RECEIVING) {
90 if (mbox->mbox_req.recv_len < msg.s.len) { 90 if (mbox->mbox_req.recv_len < mbox->mbox_req.msg.s.len) {
91 ret = 0; 91 ret = 0;
92 } else { 92 } else {
93 mbox->state &= ~OCTEON_MBOX_STATE_REQUEST_RECEIVING; 93 mbox->state &= ~OCTEON_MBOX_STATE_REQUEST_RECEIVING;
@@ -96,7 +96,8 @@ int octeon_mbox_read(struct octeon_mbox *mbox)
96 } 96 }
97 } else { 97 } else {
98 if (mbox->state & OCTEON_MBOX_STATE_RESPONSE_RECEIVING) { 98 if (mbox->state & OCTEON_MBOX_STATE_RESPONSE_RECEIVING) {
99 if (mbox->mbox_resp.recv_len < msg.s.len) { 99 if (mbox->mbox_resp.recv_len <
100 mbox->mbox_resp.msg.s.len) {
100 ret = 0; 101 ret = 0;
101 } else { 102 } else {
102 mbox->state &= 103 mbox->state &=
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_network.h b/drivers/net/ethernet/cavium/liquidio/octeon_network.h
index f2d1a076a038..76803a569794 100644
--- a/drivers/net/ethernet/cavium/liquidio/octeon_network.h
+++ b/drivers/net/ethernet/cavium/liquidio/octeon_network.h
@@ -35,6 +35,18 @@
35#define LIO_IFSTATE_RX_TIMESTAMP_ENABLED 0x08 35#define LIO_IFSTATE_RX_TIMESTAMP_ENABLED 0x08
36#define LIO_IFSTATE_RESETTING 0x10 36#define LIO_IFSTATE_RESETTING 0x10
37 37
38struct liquidio_if_cfg_context {
39 u32 octeon_id;
40 wait_queue_head_t wc;
41 int cond;
42};
43
44struct liquidio_if_cfg_resp {
45 u64 rh;
46 struct liquidio_if_cfg_info cfg_info;
47 u64 status;
48};
49
38struct oct_nic_stats_resp { 50struct oct_nic_stats_resp {
39 u64 rh; 51 u64 rh;
40 struct oct_link_stats stats; 52 struct oct_link_stats stats;
@@ -184,6 +196,14 @@ int octeon_setup_interrupt(struct octeon_device *oct, u32 num_ioqs);
184 */ 196 */
185void liquidio_set_ethtool_ops(struct net_device *netdev); 197void liquidio_set_ethtool_ops(struct net_device *netdev);
186 198
199/**
200 * \brief Net device change_mtu
201 * @param netdev network device
202 */
203int liquidio_change_mtu(struct net_device *netdev, int new_mtu);
204#define LIO_CHANGE_MTU_SUCCESS 1
205#define LIO_CHANGE_MTU_FAIL 2
206
187#define SKB_ADJ_MASK 0x3F 207#define SKB_ADJ_MASK 0x3F
188#define SKB_ADJ (SKB_ADJ_MASK + 1) 208#define SKB_ADJ (SKB_ADJ_MASK + 1)
189 209
diff --git a/drivers/net/ethernet/cavium/liquidio/request_manager.c b/drivers/net/ethernet/cavium/liquidio/request_manager.c
index e07d2093b971..2766af05b89e 100644
--- a/drivers/net/ethernet/cavium/liquidio/request_manager.c
+++ b/drivers/net/ethernet/cavium/liquidio/request_manager.c
@@ -366,6 +366,7 @@ int
366lio_process_iq_request_list(struct octeon_device *oct, 366lio_process_iq_request_list(struct octeon_device *oct,
367 struct octeon_instr_queue *iq, u32 napi_budget) 367 struct octeon_instr_queue *iq, u32 napi_budget)
368{ 368{
369 struct cavium_wq *cwq = &oct->dma_comp_wq;
369 int reqtype; 370 int reqtype;
370 void *buf; 371 void *buf;
371 u32 old = iq->flush_index; 372 u32 old = iq->flush_index;
@@ -450,6 +451,10 @@ lio_process_iq_request_list(struct octeon_device *oct,
450 bytes_compl); 451 bytes_compl);
451 iq->flush_index = old; 452 iq->flush_index = old;
452 453
454 if (atomic_read(&oct->response_list
455 [OCTEON_ORDERED_SC_LIST].pending_req_count))
456 queue_delayed_work(cwq->wq, &cwq->wk.work, msecs_to_jiffies(1));
457
453 return inst_count; 458 return inst_count;
454} 459}
455 460
diff --git a/drivers/net/ethernet/cavium/liquidio/response_manager.c b/drivers/net/ethernet/cavium/liquidio/response_manager.c
index 3d691c69f74d..fe5b53700576 100644
--- a/drivers/net/ethernet/cavium/liquidio/response_manager.c
+++ b/drivers/net/ethernet/cavium/liquidio/response_manager.c
@@ -49,7 +49,6 @@ int octeon_setup_response_list(struct octeon_device *oct)
49 INIT_DELAYED_WORK(&cwq->wk.work, oct_poll_req_completion); 49 INIT_DELAYED_WORK(&cwq->wk.work, oct_poll_req_completion);
50 cwq->wk.ctxptr = oct; 50 cwq->wk.ctxptr = oct;
51 oct->cmd_resp_state = OCT_DRV_ONLINE; 51 oct->cmd_resp_state = OCT_DRV_ONLINE;
52 queue_delayed_work(cwq->wq, &cwq->wk.work, msecs_to_jiffies(50));
53 52
54 return ret; 53 return ret;
55} 54}
@@ -164,5 +163,8 @@ static void oct_poll_req_completion(struct work_struct *work)
164 struct cavium_wq *cwq = &oct->dma_comp_wq; 163 struct cavium_wq *cwq = &oct->dma_comp_wq;
165 164
166 lio_process_ordered_list(oct, 0); 165 lio_process_ordered_list(oct, 0);
167 queue_delayed_work(cwq->wq, &cwq->wk.work, msecs_to_jiffies(50)); 166
167 if (atomic_read(&oct->response_list
168 [OCTEON_ORDERED_SC_LIST].pending_req_count))
169 queue_delayed_work(cwq->wq, &cwq->wk.work, msecs_to_jiffies(1));
168} 170}
diff --git a/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c b/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c
index a89721fad633..080918af773c 100644
--- a/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c
@@ -681,18 +681,18 @@ int t3_seeprom_wp(struct adapter *adapter, int enable)
681 return t3_seeprom_write(adapter, EEPROM_STAT_ADDR, enable ? 0xc : 0); 681 return t3_seeprom_write(adapter, EEPROM_STAT_ADDR, enable ? 0xc : 0);
682} 682}
683 683
684static int vpdstrtouint(char *s, int len, unsigned int base, unsigned int *val) 684static int vpdstrtouint(char *s, u8 len, unsigned int base, unsigned int *val)
685{ 685{
686 char tok[len + 1]; 686 char tok[256];
687 687
688 memcpy(tok, s, len); 688 memcpy(tok, s, len);
689 tok[len] = 0; 689 tok[len] = 0;
690 return kstrtouint(strim(tok), base, val); 690 return kstrtouint(strim(tok), base, val);
691} 691}
692 692
693static int vpdstrtou16(char *s, int len, unsigned int base, u16 *val) 693static int vpdstrtou16(char *s, u8 len, unsigned int base, u16 *val)
694{ 694{
695 char tok[len + 1]; 695 char tok[256];
696 696
697 memcpy(tok, s, len); 697 memcpy(tok, s, len);
698 tok[len] = 0; 698 tok[len] = 0;
diff --git a/drivers/net/ethernet/chelsio/cxgb4/Makefile b/drivers/net/ethernet/chelsio/cxgb4/Makefile
index 53b6a02c778e..bea6a059a8f1 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/Makefile
+++ b/drivers/net/ethernet/chelsio/cxgb4/Makefile
@@ -6,7 +6,7 @@
6obj-$(CONFIG_CHELSIO_T4) += cxgb4.o 6obj-$(CONFIG_CHELSIO_T4) += cxgb4.o
7 7
8cxgb4-objs := cxgb4_main.o l2t.o smt.o t4_hw.o sge.o clip_tbl.o cxgb4_ethtool.o \ 8cxgb4-objs := cxgb4_main.o l2t.o smt.o t4_hw.o sge.o clip_tbl.o cxgb4_ethtool.o \
9 cxgb4_uld.o sched.o cxgb4_filter.o cxgb4_tc_u32.o \ 9 cxgb4_uld.o srq.o sched.o cxgb4_filter.o cxgb4_tc_u32.o \
10 cxgb4_ptp.o cxgb4_tc_flower.o cxgb4_cudbg.o \ 10 cxgb4_ptp.o cxgb4_tc_flower.o cxgb4_cudbg.o \
11 cudbg_common.o cudbg_lib.o cudbg_zlib.o 11 cudbg_common.o cudbg_lib.o cudbg_zlib.o
12cxgb4-$(CONFIG_CHELSIO_T4_DCB) += cxgb4_dcb.o 12cxgb4-$(CONFIG_CHELSIO_T4_DCB) += cxgb4_dcb.o
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c b/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c
index 00a1d2d13169..9da6f57901a9 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c
@@ -878,6 +878,86 @@ static int cudbg_get_payload_range(struct adapter *padap, u8 mem_type,
878 &payload->start, &payload->end); 878 &payload->start, &payload->end);
879} 879}
880 880
881static int cudbg_memory_read(struct cudbg_init *pdbg_init, int win,
882 int mtype, u32 addr, u32 len, void *hbuf)
883{
884 u32 win_pf, memoffset, mem_aperture, mem_base;
885 struct adapter *adap = pdbg_init->adap;
886 u32 pos, offset, resid;
887 u32 *res_buf;
888 u64 *buf;
889 int ret;
890
891 /* Argument sanity checks ...
892 */
893 if (addr & 0x3 || (uintptr_t)hbuf & 0x3)
894 return -EINVAL;
895
896 buf = (u64 *)hbuf;
897
898 /* Try to do 64-bit reads. Residual will be handled later. */
899 resid = len & 0x7;
900 len -= resid;
901
902 ret = t4_memory_rw_init(adap, win, mtype, &memoffset, &mem_base,
903 &mem_aperture);
904 if (ret)
905 return ret;
906
907 addr = addr + memoffset;
908 win_pf = is_t4(adap->params.chip) ? 0 : PFNUM_V(adap->pf);
909
910 pos = addr & ~(mem_aperture - 1);
911 offset = addr - pos;
912
913 /* Set up initial PCI-E Memory Window to cover the start of our
914 * transfer.
915 */
916 t4_memory_update_win(adap, win, pos | win_pf);
917
918 /* Transfer data from the adapter */
919 while (len > 0) {
920 *buf++ = le64_to_cpu((__force __le64)
921 t4_read_reg64(adap, mem_base + offset));
922 offset += sizeof(u64);
923 len -= sizeof(u64);
924
925 /* If we've reached the end of our current window aperture,
926 * move the PCI-E Memory Window on to the next.
927 */
928 if (offset == mem_aperture) {
929 pos += mem_aperture;
930 offset = 0;
931 t4_memory_update_win(adap, win, pos | win_pf);
932 }
933 }
934
935 res_buf = (u32 *)buf;
936 /* Read residual in 32-bit multiples */
937 while (resid > sizeof(u32)) {
938 *res_buf++ = le32_to_cpu((__force __le32)
939 t4_read_reg(adap, mem_base + offset));
940 offset += sizeof(u32);
941 resid -= sizeof(u32);
942
943 /* If we've reached the end of our current window aperture,
944 * move the PCI-E Memory Window on to the next.
945 */
946 if (offset == mem_aperture) {
947 pos += mem_aperture;
948 offset = 0;
949 t4_memory_update_win(adap, win, pos | win_pf);
950 }
951 }
952
953 /* Transfer residual < 32-bits */
954 if (resid)
955 t4_memory_rw_residual(adap, resid, mem_base + offset,
956 (u8 *)res_buf, T4_MEMORY_READ);
957
958 return 0;
959}
960
881#define CUDBG_YIELD_ITERATION 256 961#define CUDBG_YIELD_ITERATION 256
882 962
883static int cudbg_read_fw_mem(struct cudbg_init *pdbg_init, 963static int cudbg_read_fw_mem(struct cudbg_init *pdbg_init,
@@ -937,10 +1017,8 @@ static int cudbg_read_fw_mem(struct cudbg_init *pdbg_init,
937 goto skip_read; 1017 goto skip_read;
938 1018
939 spin_lock(&padap->win0_lock); 1019 spin_lock(&padap->win0_lock);
940 rc = t4_memory_rw(padap, MEMWIN_NIC, mem_type, 1020 rc = cudbg_memory_read(pdbg_init, MEMWIN_NIC, mem_type,
941 bytes_read, bytes, 1021 bytes_read, bytes, temp_buff.data);
942 (__be32 *)temp_buff.data,
943 1);
944 spin_unlock(&padap->win0_lock); 1022 spin_unlock(&padap->win0_lock);
945 if (rc) { 1023 if (rc) {
946 cudbg_err->sys_err = rc; 1024 cudbg_err->sys_err = rc;
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index 9040e13ce4b7..688f95440af2 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -390,6 +390,8 @@ struct adapter_params {
390 * used by the Port 390 * used by the Port
391 */ 391 */
392 u8 mps_bg_map[MAX_NPORTS]; /* MPS Buffer Group Map */ 392 u8 mps_bg_map[MAX_NPORTS]; /* MPS Buffer Group Map */
393 bool write_w_imm_support; /* FW supports WRITE_WITH_IMMEDIATE */
394 bool write_cmpl_support; /* FW supports WRITE_CMPL */
393}; 395};
394 396
395/* State needed to monitor the forward progress of SGE Ingress DMA activities 397/* State needed to monitor the forward progress of SGE Ingress DMA activities
@@ -831,6 +833,16 @@ struct vf_info {
831 u16 vlan; 833 u16 vlan;
832}; 834};
833 835
836enum {
837 HMA_DMA_MAPPED_FLAG = 1
838};
839
840struct hma_data {
841 unsigned char flags;
842 struct sg_table *sgt;
843 dma_addr_t *phy_addr; /* physical address of the page */
844};
845
834struct mbox_list { 846struct mbox_list {
835 struct list_head list; 847 struct list_head list;
836}; 848};
@@ -907,6 +919,7 @@ struct adapter {
907 struct work_struct tid_release_task; 919 struct work_struct tid_release_task;
908 struct work_struct db_full_task; 920 struct work_struct db_full_task;
909 struct work_struct db_drop_task; 921 struct work_struct db_drop_task;
922 struct work_struct fatal_err_notify_task;
910 bool tid_release_task_busy; 923 bool tid_release_task_busy;
911 924
912 /* lock for mailbox cmd list */ 925 /* lock for mailbox cmd list */
@@ -946,6 +959,11 @@ struct adapter {
946 959
947 /* Ethtool Dump */ 960 /* Ethtool Dump */
948 struct ethtool_dump eth_dump; 961 struct ethtool_dump eth_dump;
962
963 /* HMA */
964 struct hma_data hma;
965
966 struct srq_data *srq;
949}; 967};
950 968
951/* Support for "sched-class" command to allow a TX Scheduling Class to be 969/* Support for "sched-class" command to allow a TX Scheduling Class to be
@@ -1488,6 +1506,11 @@ u32 t4_read_pcie_cfg4(struct adapter *adap, int reg);
1488u32 t4_get_util_window(struct adapter *adap); 1506u32 t4_get_util_window(struct adapter *adap);
1489void t4_setup_memwin(struct adapter *adap, u32 memwin_base, u32 window); 1507void t4_setup_memwin(struct adapter *adap, u32 memwin_base, u32 window);
1490 1508
1509int t4_memory_rw_init(struct adapter *adap, int win, int mtype, u32 *mem_off,
1510 u32 *mem_base, u32 *mem_aperture);
1511void t4_memory_update_win(struct adapter *adap, int win, u32 addr);
1512void t4_memory_rw_residual(struct adapter *adap, u32 off, u32 addr, u8 *buf,
1513 int dir);
1491#define T4_MEMORY_WRITE 0 1514#define T4_MEMORY_WRITE 0
1492#define T4_MEMORY_READ 1 1515#define T4_MEMORY_READ 1
1493int t4_memory_rw(struct adapter *adap, int win, int mtype, u32 addr, u32 len, 1516int t4_memory_rw(struct adapter *adap, int win, int mtype, u32 addr, u32 len,
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
index 2822bbff73e8..de2ba86eccfd 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
@@ -2617,7 +2617,7 @@ int mem_open(struct inode *inode, struct file *file)
2617 2617
2618 file->private_data = inode->i_private; 2618 file->private_data = inode->i_private;
2619 2619
2620 mem = (uintptr_t)file->private_data & 0x3; 2620 mem = (uintptr_t)file->private_data & 0x7;
2621 adap = file->private_data - mem; 2621 adap = file->private_data - mem;
2622 2622
2623 (void)t4_fwcache(adap, FW_PARAM_DEV_FWCACHE_FLUSH); 2623 (void)t4_fwcache(adap, FW_PARAM_DEV_FWCACHE_FLUSH);
@@ -2630,7 +2630,7 @@ static ssize_t mem_read(struct file *file, char __user *buf, size_t count,
2630{ 2630{
2631 loff_t pos = *ppos; 2631 loff_t pos = *ppos;
2632 loff_t avail = file_inode(file)->i_size; 2632 loff_t avail = file_inode(file)->i_size;
2633 unsigned int mem = (uintptr_t)file->private_data & 3; 2633 unsigned int mem = (uintptr_t)file->private_data & 0x7;
2634 struct adapter *adap = file->private_data - mem; 2634 struct adapter *adap = file->private_data - mem;
2635 __be32 *data; 2635 __be32 *data;
2636 int ret; 2636 int ret;
@@ -3042,6 +3042,12 @@ int t4_setup_debugfs(struct adapter *adap)
3042 add_debugfs_mem(adap, "mc", MEM_MC, 3042 add_debugfs_mem(adap, "mc", MEM_MC,
3043 EXT_MEM_SIZE_G(size)); 3043 EXT_MEM_SIZE_G(size));
3044 } 3044 }
3045
3046 if (i & HMA_MUX_F) {
3047 size = t4_read_reg(adap, MA_EXT_MEMORY1_BAR_A);
3048 add_debugfs_mem(adap, "hma", MEM_HMA,
3049 EXT_MEM1_SIZE_G(size));
3050 }
3045 } 3051 }
3046 3052
3047 de = debugfs_create_file_size("flash", S_IRUSR, adap->debugfs_root, adap, 3053 de = debugfs_create_file_size("flash", S_IRUSR, adap->debugfs_root, adap,
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c
index 7852d98bad75..59d04d73c672 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c
@@ -597,22 +597,22 @@ static void fw_caps_to_lmm(enum fw_port_type port_type,
597 597
598 case FW_PORT_TYPE_KR: 598 case FW_PORT_TYPE_KR:
599 SET_LMM(Backplane); 599 SET_LMM(Backplane);
600 SET_LMM(10000baseKR_Full); 600 FW_CAPS_TO_LMM(SPEED_10G, 10000baseKR_Full);
601 break; 601 break;
602 602
603 case FW_PORT_TYPE_BP_AP: 603 case FW_PORT_TYPE_BP_AP:
604 SET_LMM(Backplane); 604 SET_LMM(Backplane);
605 SET_LMM(10000baseR_FEC); 605 FW_CAPS_TO_LMM(SPEED_1G, 1000baseKX_Full);
606 SET_LMM(10000baseKR_Full); 606 FW_CAPS_TO_LMM(SPEED_10G, 10000baseR_FEC);
607 SET_LMM(1000baseKX_Full); 607 FW_CAPS_TO_LMM(SPEED_10G, 10000baseKR_Full);
608 break; 608 break;
609 609
610 case FW_PORT_TYPE_BP4_AP: 610 case FW_PORT_TYPE_BP4_AP:
611 SET_LMM(Backplane); 611 SET_LMM(Backplane);
612 SET_LMM(10000baseR_FEC); 612 FW_CAPS_TO_LMM(SPEED_1G, 1000baseKX_Full);
613 SET_LMM(10000baseKR_Full); 613 FW_CAPS_TO_LMM(SPEED_10G, 10000baseR_FEC);
614 SET_LMM(1000baseKX_Full); 614 FW_CAPS_TO_LMM(SPEED_10G, 10000baseKR_Full);
615 SET_LMM(10000baseKX4_Full); 615 FW_CAPS_TO_LMM(SPEED_10G, 10000baseKX4_Full);
616 break; 616 break;
617 617
618 case FW_PORT_TYPE_FIBER_XFI: 618 case FW_PORT_TYPE_FIBER_XFI:
@@ -628,7 +628,9 @@ static void fw_caps_to_lmm(enum fw_port_type port_type,
628 case FW_PORT_TYPE_BP40_BA: 628 case FW_PORT_TYPE_BP40_BA:
629 case FW_PORT_TYPE_QSFP: 629 case FW_PORT_TYPE_QSFP:
630 SET_LMM(FIBRE); 630 SET_LMM(FIBRE);
631 SET_LMM(40000baseSR4_Full); 631 FW_CAPS_TO_LMM(SPEED_1G, 1000baseT_Full);
632 FW_CAPS_TO_LMM(SPEED_10G, 10000baseT_Full);
633 FW_CAPS_TO_LMM(SPEED_40G, 40000baseSR4_Full);
632 break; 634 break;
633 635
634 case FW_PORT_TYPE_CR_QSFP: 636 case FW_PORT_TYPE_CR_QSFP:
@@ -655,12 +657,14 @@ static void fw_caps_to_lmm(enum fw_port_type port_type,
655 657
656 case FW_PORT_TYPE_CR2_QSFP: 658 case FW_PORT_TYPE_CR2_QSFP:
657 SET_LMM(FIBRE); 659 SET_LMM(FIBRE);
658 SET_LMM(50000baseSR2_Full); 660 FW_CAPS_TO_LMM(SPEED_50G, 50000baseSR2_Full);
659 break; 661 break;
660 662
661 case FW_PORT_TYPE_KR4_100G: 663 case FW_PORT_TYPE_KR4_100G:
662 case FW_PORT_TYPE_CR4_QSFP: 664 case FW_PORT_TYPE_CR4_QSFP:
663 SET_LMM(FIBRE); 665 SET_LMM(FIBRE);
666 FW_CAPS_TO_LMM(SPEED_1G, 1000baseT_Full);
667 FW_CAPS_TO_LMM(SPEED_10G, 10000baseSR_Full);
664 FW_CAPS_TO_LMM(SPEED_40G, 40000baseSR4_Full); 668 FW_CAPS_TO_LMM(SPEED_40G, 40000baseSR4_Full);
665 FW_CAPS_TO_LMM(SPEED_25G, 25000baseCR_Full); 669 FW_CAPS_TO_LMM(SPEED_25G, 25000baseCR_Full);
666 FW_CAPS_TO_LMM(SPEED_50G, 50000baseCR2_Full); 670 FW_CAPS_TO_LMM(SPEED_50G, 50000baseCR2_Full);
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c
index 3177b0c9bd2d..db92f1858060 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c
@@ -1335,12 +1335,6 @@ int __cxgb4_set_filter(struct net_device *dev, int filter_id,
1335 return ret; 1335 return ret;
1336 } 1336 }
1337 1337
1338 /* Clear out any old resources being used by the filter before
1339 * we start constructing the new filter.
1340 */
1341 if (f->valid)
1342 clear_filter(adapter, f);
1343
1344 if (is_t6(adapter->params.chip) && fs->type && 1338 if (is_t6(adapter->params.chip) && fs->type &&
1345 ipv6_addr_type((const struct in6_addr *)fs->val.lip) != 1339 ipv6_addr_type((const struct in6_addr *)fs->val.lip) !=
1346 IPV6_ADDR_ANY) { 1340 IPV6_ADDR_ANY) {
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 61022b5f6743..e880be8e3c45 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -75,6 +75,7 @@
75#include "t4fw_api.h" 75#include "t4fw_api.h"
76#include "t4fw_version.h" 76#include "t4fw_version.h"
77#include "cxgb4_dcb.h" 77#include "cxgb4_dcb.h"
78#include "srq.h"
78#include "cxgb4_debugfs.h" 79#include "cxgb4_debugfs.h"
79#include "clip_tbl.h" 80#include "clip_tbl.h"
80#include "l2t.h" 81#include "l2t.h"
@@ -210,6 +211,9 @@ static void link_report(struct net_device *dev)
210 case 40000: 211 case 40000:
211 s = "40Gbps"; 212 s = "40Gbps";
212 break; 213 break;
214 case 50000:
215 s = "50Gbps";
216 break;
213 case 100000: 217 case 100000:
214 s = "100Gbps"; 218 s = "100Gbps";
215 break; 219 break;
@@ -583,6 +587,10 @@ static int fwevtq_handler(struct sge_rspq *q, const __be64 *rsp,
583 const struct cpl_abort_rpl_rss *p = (void *)rsp; 587 const struct cpl_abort_rpl_rss *p = (void *)rsp;
584 588
585 hash_del_filter_rpl(q->adap, p); 589 hash_del_filter_rpl(q->adap, p);
590 } else if (opcode == CPL_SRQ_TABLE_RPL) {
591 const struct cpl_srq_table_rpl *p = (void *)rsp;
592
593 do_srq_table_rpl(q->adap, p);
586 } else 594 } else
587 dev_err(q->adap->pdev_dev, 595 dev_err(q->adap->pdev_dev,
588 "unexpected CPL %#x on FW event queue\n", opcode); 596 "unexpected CPL %#x on FW event queue\n", opcode);
@@ -1733,10 +1741,11 @@ EXPORT_SYMBOL(cxgb4_sync_txq_pidx);
1733 1741
1734int cxgb4_read_tpte(struct net_device *dev, u32 stag, __be32 *tpte) 1742int cxgb4_read_tpte(struct net_device *dev, u32 stag, __be32 *tpte)
1735{ 1743{
1736 struct adapter *adap;
1737 u32 offset, memtype, memaddr;
1738 u32 edc0_size, edc1_size, mc0_size, mc1_size, size; 1744 u32 edc0_size, edc1_size, mc0_size, mc1_size, size;
1739 u32 edc0_end, edc1_end, mc0_end, mc1_end; 1745 u32 edc0_end, edc1_end, mc0_end, mc1_end;
1746 u32 offset, memtype, memaddr;
1747 struct adapter *adap;
1748 u32 hma_size = 0;
1740 int ret; 1749 int ret;
1741 1750
1742 adap = netdev2adap(dev); 1751 adap = netdev2adap(dev);
@@ -1756,6 +1765,10 @@ int cxgb4_read_tpte(struct net_device *dev, u32 stag, __be32 *tpte)
1756 size = t4_read_reg(adap, MA_EXT_MEMORY0_BAR_A); 1765 size = t4_read_reg(adap, MA_EXT_MEMORY0_BAR_A);
1757 mc0_size = EXT_MEM0_SIZE_G(size) << 20; 1766 mc0_size = EXT_MEM0_SIZE_G(size) << 20;
1758 1767
1768 if (t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A) & HMA_MUX_F) {
1769 size = t4_read_reg(adap, MA_EXT_MEMORY1_BAR_A);
1770 hma_size = EXT_MEM1_SIZE_G(size) << 20;
1771 }
1759 edc0_end = edc0_size; 1772 edc0_end = edc0_size;
1760 edc1_end = edc0_end + edc1_size; 1773 edc1_end = edc0_end + edc1_size;
1761 mc0_end = edc1_end + mc0_size; 1774 mc0_end = edc1_end + mc0_size;
@@ -1767,7 +1780,10 @@ int cxgb4_read_tpte(struct net_device *dev, u32 stag, __be32 *tpte)
1767 memtype = MEM_EDC1; 1780 memtype = MEM_EDC1;
1768 memaddr = offset - edc0_end; 1781 memaddr = offset - edc0_end;
1769 } else { 1782 } else {
1770 if (offset < mc0_end) { 1783 if (hma_size && (offset < (edc1_end + hma_size))) {
1784 memtype = MEM_HMA;
1785 memaddr = offset - edc1_end;
1786 } else if (offset < mc0_end) {
1771 memtype = MEM_MC0; 1787 memtype = MEM_MC0;
1772 memaddr = offset - edc1_end; 1788 memaddr = offset - edc1_end;
1773 } else if (is_t5(adap->params.chip)) { 1789 } else if (is_t5(adap->params.chip)) {
@@ -2870,11 +2886,11 @@ static int cxgb_set_tx_maxrate(struct net_device *dev, int index, u32 rate)
2870 /* Convert from Mbps to Kbps */ 2886 /* Convert from Mbps to Kbps */
2871 req_rate = rate << 10; 2887 req_rate = rate << 10;
2872 2888
2873 /* Max rate is 10 Gbps */ 2889 /* Max rate is 100 Gbps */
2874 if (req_rate >= SCHED_MAX_RATE_KBPS) { 2890 if (req_rate >= SCHED_MAX_RATE_KBPS) {
2875 dev_err(adap->pdev_dev, 2891 dev_err(adap->pdev_dev,
2876 "Invalid rate %u Mbps, Max rate is %u Gbps\n", 2892 "Invalid rate %u Mbps, Max rate is %u Mbps\n",
2877 rate, SCHED_MAX_RATE_KBPS); 2893 rate, SCHED_MAX_RATE_KBPS >> 10);
2878 return -ERANGE; 2894 return -ERANGE;
2879 } 2895 }
2880 2896
@@ -3244,6 +3260,14 @@ static const struct ethtool_ops cxgb4_mgmt_ethtool_ops = {
3244 .get_drvinfo = cxgb4_mgmt_get_drvinfo, 3260 .get_drvinfo = cxgb4_mgmt_get_drvinfo,
3245}; 3261};
3246 3262
3263static void notify_fatal_err(struct work_struct *work)
3264{
3265 struct adapter *adap;
3266
3267 adap = container_of(work, struct adapter, fatal_err_notify_task);
3268 notify_ulds(adap, CXGB4_STATE_FATAL_ERROR);
3269}
3270
3247void t4_fatal_err(struct adapter *adap) 3271void t4_fatal_err(struct adapter *adap)
3248{ 3272{
3249 int port; 3273 int port;
@@ -3268,6 +3292,7 @@ void t4_fatal_err(struct adapter *adap)
3268 netif_carrier_off(dev); 3292 netif_carrier_off(dev);
3269 } 3293 }
3270 dev_alert(adap->pdev_dev, "encountered fatal error, adapter stopped\n"); 3294 dev_alert(adap->pdev_dev, "encountered fatal error, adapter stopped\n");
3295 queue_work(adap->workq, &adap->fatal_err_notify_task);
3271} 3296}
3272 3297
3273static void setup_memwin(struct adapter *adap) 3298static void setup_memwin(struct adapter *adap)
@@ -3298,6 +3323,206 @@ static void setup_memwin_rdma(struct adapter *adap)
3298 } 3323 }
3299} 3324}
3300 3325
3326/* HMA Definitions */
3327
3328/* The maximum number of address that can be send in a single FW cmd */
3329#define HMA_MAX_ADDR_IN_CMD 5
3330
3331#define HMA_PAGE_SIZE PAGE_SIZE
3332
3333#define HMA_MAX_NO_FW_ADDRESS (16 << 10) /* FW supports 16K addresses */
3334
3335#define HMA_PAGE_ORDER \
3336 ((HMA_PAGE_SIZE < HMA_MAX_NO_FW_ADDRESS) ? \
3337 ilog2(HMA_MAX_NO_FW_ADDRESS / HMA_PAGE_SIZE) : 0)
3338
3339/* The minimum and maximum possible HMA sizes that can be specified in the FW
3340 * configuration(in units of MB).
3341 */
3342#define HMA_MIN_TOTAL_SIZE 1
3343#define HMA_MAX_TOTAL_SIZE \
3344 (((HMA_PAGE_SIZE << HMA_PAGE_ORDER) * \
3345 HMA_MAX_NO_FW_ADDRESS) >> 20)
3346
3347static void adap_free_hma_mem(struct adapter *adapter)
3348{
3349 struct scatterlist *iter;
3350 struct page *page;
3351 int i;
3352
3353 if (!adapter->hma.sgt)
3354 return;
3355
3356 if (adapter->hma.flags & HMA_DMA_MAPPED_FLAG) {
3357 dma_unmap_sg(adapter->pdev_dev, adapter->hma.sgt->sgl,
3358 adapter->hma.sgt->nents, PCI_DMA_BIDIRECTIONAL);
3359 adapter->hma.flags &= ~HMA_DMA_MAPPED_FLAG;
3360 }
3361
3362 for_each_sg(adapter->hma.sgt->sgl, iter,
3363 adapter->hma.sgt->orig_nents, i) {
3364 page = sg_page(iter);
3365 if (page)
3366 __free_pages(page, HMA_PAGE_ORDER);
3367 }
3368
3369 kfree(adapter->hma.phy_addr);
3370 sg_free_table(adapter->hma.sgt);
3371 kfree(adapter->hma.sgt);
3372 adapter->hma.sgt = NULL;
3373}
3374
3375static int adap_config_hma(struct adapter *adapter)
3376{
3377 struct scatterlist *sgl, *iter;
3378 struct sg_table *sgt;
3379 struct page *newpage;
3380 unsigned int i, j, k;
3381 u32 param, hma_size;
3382 unsigned int ncmds;
3383 size_t page_size;
3384 u32 page_order;
3385 int node, ret;
3386
3387 /* HMA is supported only for T6+ cards.
3388 * Avoid initializing HMA in kdump kernels.
3389 */
3390 if (is_kdump_kernel() ||
3391 CHELSIO_CHIP_VERSION(adapter->params.chip) < CHELSIO_T6)
3392 return 0;
3393
3394 /* Get the HMA region size required by fw */
3395 param = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) |
3396 FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_HMA_SIZE));
3397 ret = t4_query_params(adapter, adapter->mbox, adapter->pf, 0,
3398 1, &param, &hma_size);
3399 /* An error means card has its own memory or HMA is not supported by
3400 * the firmware. Return without any errors.
3401 */
3402 if (ret || !hma_size)
3403 return 0;
3404
3405 if (hma_size < HMA_MIN_TOTAL_SIZE ||
3406 hma_size > HMA_MAX_TOTAL_SIZE) {
3407 dev_err(adapter->pdev_dev,
3408 "HMA size %uMB beyond bounds(%u-%lu)MB\n",
3409 hma_size, HMA_MIN_TOTAL_SIZE, HMA_MAX_TOTAL_SIZE);
3410 return -EINVAL;
3411 }
3412
3413 page_size = HMA_PAGE_SIZE;
3414 page_order = HMA_PAGE_ORDER;
3415 adapter->hma.sgt = kzalloc(sizeof(*adapter->hma.sgt), GFP_KERNEL);
3416 if (unlikely(!adapter->hma.sgt)) {
3417 dev_err(adapter->pdev_dev, "HMA SG table allocation failed\n");
3418 return -ENOMEM;
3419 }
3420 sgt = adapter->hma.sgt;
3421 /* FW returned value will be in MB's
3422 */
3423 sgt->orig_nents = (hma_size << 20) / (page_size << page_order);
3424 if (sg_alloc_table(sgt, sgt->orig_nents, GFP_KERNEL)) {
3425 dev_err(adapter->pdev_dev, "HMA SGL allocation failed\n");
3426 kfree(adapter->hma.sgt);
3427 adapter->hma.sgt = NULL;
3428 return -ENOMEM;
3429 }
3430
3431 sgl = adapter->hma.sgt->sgl;
3432 node = dev_to_node(adapter->pdev_dev);
3433 for_each_sg(sgl, iter, sgt->orig_nents, i) {
3434 newpage = alloc_pages_node(node, __GFP_NOWARN | GFP_KERNEL,
3435 page_order);
3436 if (!newpage) {
3437 dev_err(adapter->pdev_dev,
3438 "Not enough memory for HMA page allocation\n");
3439 ret = -ENOMEM;
3440 goto free_hma;
3441 }
3442 sg_set_page(iter, newpage, page_size << page_order, 0);
3443 }
3444
3445 sgt->nents = dma_map_sg(adapter->pdev_dev, sgl, sgt->orig_nents,
3446 DMA_BIDIRECTIONAL);
3447 if (!sgt->nents) {
3448 dev_err(adapter->pdev_dev,
3449 "Not enough memory for HMA DMA mapping");
3450 ret = -ENOMEM;
3451 goto free_hma;
3452 }
3453 adapter->hma.flags |= HMA_DMA_MAPPED_FLAG;
3454
3455 adapter->hma.phy_addr = kcalloc(sgt->nents, sizeof(dma_addr_t),
3456 GFP_KERNEL);
3457 if (unlikely(!adapter->hma.phy_addr))
3458 goto free_hma;
3459
3460 for_each_sg(sgl, iter, sgt->nents, i) {
3461 newpage = sg_page(iter);
3462 adapter->hma.phy_addr[i] = sg_dma_address(iter);
3463 }
3464
3465 ncmds = DIV_ROUND_UP(sgt->nents, HMA_MAX_ADDR_IN_CMD);
3466 /* Pass on the addresses to firmware */
3467 for (i = 0, k = 0; i < ncmds; i++, k += HMA_MAX_ADDR_IN_CMD) {
3468 struct fw_hma_cmd hma_cmd;
3469 u8 naddr = HMA_MAX_ADDR_IN_CMD;
3470 u8 soc = 0, eoc = 0;
3471 u8 hma_mode = 1; /* Presently we support only Page table mode */
3472
3473 soc = (i == 0) ? 1 : 0;
3474 eoc = (i == ncmds - 1) ? 1 : 0;
3475
3476 /* For last cmd, set naddr corresponding to remaining
3477 * addresses
3478 */
3479 if (i == ncmds - 1) {
3480 naddr = sgt->nents % HMA_MAX_ADDR_IN_CMD;
3481 naddr = naddr ? naddr : HMA_MAX_ADDR_IN_CMD;
3482 }
3483 memset(&hma_cmd, 0, sizeof(hma_cmd));
3484 hma_cmd.op_pkd = htonl(FW_CMD_OP_V(FW_HMA_CMD) |
3485 FW_CMD_REQUEST_F | FW_CMD_WRITE_F);
3486 hma_cmd.retval_len16 = htonl(FW_LEN16(hma_cmd));
3487
3488 hma_cmd.mode_to_pcie_params =
3489 htonl(FW_HMA_CMD_MODE_V(hma_mode) |
3490 FW_HMA_CMD_SOC_V(soc) | FW_HMA_CMD_EOC_V(eoc));
3491
3492 /* HMA cmd size specified in MB's */
3493 hma_cmd.naddr_size =
3494 htonl(FW_HMA_CMD_SIZE_V(hma_size) |
3495 FW_HMA_CMD_NADDR_V(naddr));
3496
3497 /* Total Page size specified in units of 4K */
3498 hma_cmd.addr_size_pkd =
3499 htonl(FW_HMA_CMD_ADDR_SIZE_V
3500 ((page_size << page_order) >> 12));
3501
3502 /* Fill the 5 addresses */
3503 for (j = 0; j < naddr; j++) {
3504 hma_cmd.phy_address[j] =
3505 cpu_to_be64(adapter->hma.phy_addr[j + k]);
3506 }
3507 ret = t4_wr_mbox(adapter, adapter->mbox, &hma_cmd,
3508 sizeof(hma_cmd), &hma_cmd);
3509 if (ret) {
3510 dev_err(adapter->pdev_dev,
3511 "HMA FW command failed with err %d\n", ret);
3512 goto free_hma;
3513 }
3514 }
3515
3516 if (!ret)
3517 dev_info(adapter->pdev_dev,
3518 "Reserved %uMB host memory for HMA\n", hma_size);
3519 return ret;
3520
3521free_hma:
3522 adap_free_hma_mem(adapter);
3523 return ret;
3524}
3525
3301static int adap_init1(struct adapter *adap, struct fw_caps_config_cmd *c) 3526static int adap_init1(struct adapter *adap, struct fw_caps_config_cmd *c)
3302{ 3527{
3303 u32 v; 3528 u32 v;
@@ -3751,6 +3976,12 @@ static int adap_init0_config(struct adapter *adapter, int reset)
3751 if (ret < 0) 3976 if (ret < 0)
3752 goto bye; 3977 goto bye;
3753 3978
3979 /* We will proceed even if HMA init fails. */
3980 ret = adap_config_hma(adapter);
3981 if (ret)
3982 dev_err(adapter->pdev_dev,
3983 "HMA configuration failed with error %d\n", ret);
3984
3754 /* 3985 /*
3755 * And finally tell the firmware to initialize itself using the 3986 * And finally tell the firmware to initialize itself using the
3756 * parameters from the Configuration File. 3987 * parameters from the Configuration File.
@@ -3957,6 +4188,11 @@ static int adap_init0(struct adapter *adap)
3957 * effect. Otherwise, it's time to try initializing the adapter. 4188 * effect. Otherwise, it's time to try initializing the adapter.
3958 */ 4189 */
3959 if (state == DEV_STATE_INIT) { 4190 if (state == DEV_STATE_INIT) {
4191 ret = adap_config_hma(adap);
4192 if (ret)
4193 dev_err(adap->pdev_dev,
4194 "HMA configuration failed with error %d\n",
4195 ret);
3960 dev_info(adap->pdev_dev, "Coming up as %s: "\ 4196 dev_info(adap->pdev_dev, "Coming up as %s: "\
3961 "Adapter already initialized\n", 4197 "Adapter already initialized\n",
3962 adap->flags & MASTER_PF ? "MASTER" : "SLAVE"); 4198 adap->flags & MASTER_PF ? "MASTER" : "SLAVE");
@@ -4236,6 +4472,20 @@ static int adap_init0(struct adapter *adap)
4236 adap->vres.pbl.start = val[4]; 4472 adap->vres.pbl.start = val[4];
4237 adap->vres.pbl.size = val[5] - val[4] + 1; 4473 adap->vres.pbl.size = val[5] - val[4] + 1;
4238 4474
4475 params[0] = FW_PARAM_PFVF(SRQ_START);
4476 params[1] = FW_PARAM_PFVF(SRQ_END);
4477 ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 2,
4478 params, val);
4479 if (!ret) {
4480 adap->vres.srq.start = val[0];
4481 adap->vres.srq.size = val[1] - val[0] + 1;
4482 }
4483 if (adap->vres.srq.size) {
4484 adap->srq = t4_init_srq(adap->vres.srq.size);
4485 if (!adap->srq)
4486 dev_warn(&adap->pdev->dev, "could not allocate SRQ, continuing\n");
4487 }
4488
4239 params[0] = FW_PARAM_PFVF(SQRQ_START); 4489 params[0] = FW_PARAM_PFVF(SQRQ_START);
4240 params[1] = FW_PARAM_PFVF(SQRQ_END); 4490 params[1] = FW_PARAM_PFVF(SQRQ_END);
4241 params[2] = FW_PARAM_PFVF(CQ_START); 4491 params[2] = FW_PARAM_PFVF(CQ_START);
@@ -4269,6 +4519,18 @@ static int adap_init0(struct adapter *adap)
4269 "max_ordird_qp %d max_ird_adapter %d\n", 4519 "max_ordird_qp %d max_ird_adapter %d\n",
4270 adap->params.max_ordird_qp, 4520 adap->params.max_ordird_qp,
4271 adap->params.max_ird_adapter); 4521 adap->params.max_ird_adapter);
4522
4523 /* Enable write_with_immediate if FW supports it */
4524 params[0] = FW_PARAM_DEV(RDMA_WRITE_WITH_IMM);
4525 ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 1, params,
4526 val);
4527 adap->params.write_w_imm_support = (ret == 0 && val[0] != 0);
4528
4529 /* Enable write_cmpl if FW supports it */
4530 params[0] = FW_PARAM_DEV(RI_WRITE_CMPL_WR);
4531 ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 1, params,
4532 val);
4533 adap->params.write_cmpl_support = (ret == 0 && val[0] != 0);
4272 adap->num_ofld_uld += 2; 4534 adap->num_ofld_uld += 2;
4273 } 4535 }
4274 if (caps_cmd.iscsicaps) { 4536 if (caps_cmd.iscsicaps) {
@@ -4346,6 +4608,7 @@ static int adap_init0(struct adapter *adap)
4346 * happened to HW/FW, stop issuing commands. 4608 * happened to HW/FW, stop issuing commands.
4347 */ 4609 */
4348bye: 4610bye:
4611 adap_free_hma_mem(adap);
4349 kfree(adap->sge.egr_map); 4612 kfree(adap->sge.egr_map);
4350 kfree(adap->sge.ingr_map); 4613 kfree(adap->sge.ingr_map);
4351 kfree(adap->sge.starving_fl); 4614 kfree(adap->sge.starving_fl);
@@ -4903,6 +5166,7 @@ static void free_some_resources(struct adapter *adapter)
4903 5166
4904 kvfree(adapter->smt); 5167 kvfree(adapter->smt);
4905 kvfree(adapter->l2t); 5168 kvfree(adapter->l2t);
5169 kvfree(adapter->srq);
4906 t4_cleanup_sched(adapter); 5170 t4_cleanup_sched(adapter);
4907 kvfree(adapter->tids.tid_tab); 5171 kvfree(adapter->tids.tid_tab);
4908 cxgb4_cleanup_tc_flower(adapter); 5172 cxgb4_cleanup_tc_flower(adapter);
@@ -5257,6 +5521,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
5257 INIT_WORK(&adapter->tid_release_task, process_tid_release_list); 5521 INIT_WORK(&adapter->tid_release_task, process_tid_release_list);
5258 INIT_WORK(&adapter->db_full_task, process_db_full); 5522 INIT_WORK(&adapter->db_full_task, process_db_full);
5259 INIT_WORK(&adapter->db_drop_task, process_db_drop); 5523 INIT_WORK(&adapter->db_drop_task, process_db_drop);
5524 INIT_WORK(&adapter->fatal_err_notify_task, notify_fatal_err);
5260 5525
5261 err = t4_prep_adapter(adapter); 5526 err = t4_prep_adapter(adapter);
5262 if (err) 5527 if (err)
@@ -5574,6 +5839,8 @@ static void remove_one(struct pci_dev *pdev)
5574 t4_uld_clean_up(adapter); 5839 t4_uld_clean_up(adapter);
5575 } 5840 }
5576 5841
5842 adap_free_hma_mem(adapter);
5843
5577 disable_interrupts(adapter); 5844 disable_interrupts(adapter);
5578 5845
5579 for_each_port(adapter, i) 5846 for_each_port(adapter, i)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c
index 6b5fea4532f3..a95cde0fadf7 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c
@@ -342,6 +342,7 @@ static void free_queues_uld(struct adapter *adap, unsigned int uld_type)
342{ 342{
343 struct sge_uld_rxq_info *rxq_info = adap->sge.uld_rxq_info[uld_type]; 343 struct sge_uld_rxq_info *rxq_info = adap->sge.uld_rxq_info[uld_type];
344 344
345 adap->sge.uld_rxq_info[uld_type] = NULL;
345 kfree(rxq_info->rspq_id); 346 kfree(rxq_info->rspq_id);
346 kfree(rxq_info->uldrxq); 347 kfree(rxq_info->uldrxq);
347 kfree(rxq_info); 348 kfree(rxq_info);
@@ -665,6 +666,8 @@ static void uld_init(struct adapter *adap, struct cxgb4_lld_info *lld)
665 lld->ulptx_memwrite_dsgl = adap->params.ulptx_memwrite_dsgl; 666 lld->ulptx_memwrite_dsgl = adap->params.ulptx_memwrite_dsgl;
666 lld->nodeid = dev_to_node(adap->pdev_dev); 667 lld->nodeid = dev_to_node(adap->pdev_dev);
667 lld->fr_nsmr_tpte_wr_support = adap->params.fr_nsmr_tpte_wr_support; 668 lld->fr_nsmr_tpte_wr_support = adap->params.fr_nsmr_tpte_wr_support;
669 lld->write_w_imm_support = adap->params.write_w_imm_support;
670 lld->write_cmpl_support = adap->params.write_cmpl_support;
668} 671}
669 672
670static void uld_attach(struct adapter *adap, unsigned int uld) 673static void uld_attach(struct adapter *adap, unsigned int uld)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
index a14e8db51cdc..b0ca06edaa7c 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
@@ -257,7 +257,8 @@ enum cxgb4_state {
257 CXGB4_STATE_UP, 257 CXGB4_STATE_UP,
258 CXGB4_STATE_START_RECOVERY, 258 CXGB4_STATE_START_RECOVERY,
259 CXGB4_STATE_DOWN, 259 CXGB4_STATE_DOWN,
260 CXGB4_STATE_DETACH 260 CXGB4_STATE_DETACH,
261 CXGB4_STATE_FATAL_ERROR
261}; 262};
262 263
263enum cxgb4_control { 264enum cxgb4_control {
@@ -283,6 +284,7 @@ struct cxgb4_virt_res { /* virtualized HW resources */
283 struct cxgb4_range iscsi; 284 struct cxgb4_range iscsi;
284 struct cxgb4_range stag; 285 struct cxgb4_range stag;
285 struct cxgb4_range rq; 286 struct cxgb4_range rq;
287 struct cxgb4_range srq;
286 struct cxgb4_range pbl; 288 struct cxgb4_range pbl;
287 struct cxgb4_range qp; 289 struct cxgb4_range qp;
288 struct cxgb4_range cq; 290 struct cxgb4_range cq;
@@ -352,6 +354,8 @@ struct cxgb4_lld_info {
352 void **iscsi_ppm; /* iscsi page pod manager */ 354 void **iscsi_ppm; /* iscsi page pod manager */
353 int nodeid; /* device numa node id */ 355 int nodeid; /* device numa node id */
354 bool fr_nsmr_tpte_wr_support; /* FW supports FR_NSMR_TPTE_WR */ 356 bool fr_nsmr_tpte_wr_support; /* FW supports FR_NSMR_TPTE_WR */
357 bool write_w_imm_support; /* FW supports WRITE_WITH_IMMEDIATE */
358 bool write_cmpl_support; /* FW supports WRITE_CMPL WR */
355}; 359};
356 360
357struct cxgb4_uld_info { 361struct cxgb4_uld_info {
diff --git a/drivers/net/ethernet/chelsio/cxgb4/sched.h b/drivers/net/ethernet/chelsio/cxgb4/sched.h
index 77b2b3fd9021..3a49e00a38a1 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/sched.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/sched.h
@@ -42,8 +42,8 @@
42 42
43#define FW_SCHED_CLS_NONE 0xffffffff 43#define FW_SCHED_CLS_NONE 0xffffffff
44 44
45/* Max rate that can be set to a scheduling class is 10 Gbps */ 45/* Max rate that can be set to a scheduling class is 100 Gbps */
46#define SCHED_MAX_RATE_KBPS 10000000U 46#define SCHED_MAX_RATE_KBPS 100000000U
47 47
48enum { 48enum {
49 SCHED_STATE_ACTIVE, 49 SCHED_STATE_ACTIVE,
diff --git a/drivers/net/ethernet/chelsio/cxgb4/srq.c b/drivers/net/ethernet/chelsio/cxgb4/srq.c
new file mode 100644
index 000000000000..6228a5708307
--- /dev/null
+++ b/drivers/net/ethernet/chelsio/cxgb4/srq.c
@@ -0,0 +1,138 @@
1/*
2 * This file is part of the Chelsio T6 Ethernet driver for Linux.
3 *
4 * Copyright (c) 2017-2018 Chelsio Communications, Inc. All rights reserved.
5 *
6 * This software is available to you under a choice of one of two
7 * licenses. You may choose to be licensed under the terms of the GNU
8 * General Public License (GPL) Version 2, available from the file
9 * COPYING in the main directory of this source tree, or the
10 * OpenIB.org BSD license below:
11 *
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
14 * conditions are met:
15 *
16 * - Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
18 * disclaimer.
19 *
20 * - Redistributions in binary form must reproduce the above
21 * copyright notice, this list of conditions and the following
22 * disclaimer in the documentation and/or other materials
23 * provided with the distribution.
24 *
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 * SOFTWARE.
33 */
34
35#include "cxgb4.h"
36#include "t4_msg.h"
37#include "srq.h"
38
39struct srq_data *t4_init_srq(int srq_size)
40{
41 struct srq_data *s;
42
43 s = kvzalloc(sizeof(*s), GFP_KERNEL);
44 if (!s)
45 return NULL;
46
47 s->srq_size = srq_size;
48 init_completion(&s->comp);
49 mutex_init(&s->lock);
50
51 return s;
52}
53
54/* cxgb4_get_srq_entry: read the SRQ table entry
55 * @dev: Pointer to the net_device
56 * @idx: Index to the srq
57 * @entryp: pointer to the srq entry
58 *
59 * Sends CPL_SRQ_TABLE_REQ message for the given index.
60 * Contents will be returned in CPL_SRQ_TABLE_RPL message.
61 *
62 * Returns zero if the read is successful, else a error
63 * number will be returned. Caller should not use the srq
64 * entry if the return value is non-zero.
65 *
66 *
67 */
68int cxgb4_get_srq_entry(struct net_device *dev,
69 int srq_idx, struct srq_entry *entryp)
70{
71 struct cpl_srq_table_req *req;
72 struct adapter *adap;
73 struct sk_buff *skb;
74 struct srq_data *s;
75 int rc = -ENODEV;
76
77 adap = netdev2adap(dev);
78 s = adap->srq;
79
80 if (!(adap->flags & FULL_INIT_DONE) || !s)
81 goto out;
82
83 skb = alloc_skb(sizeof(*req), GFP_KERNEL);
84 if (!skb)
85 return -ENOMEM;
86 req = (struct cpl_srq_table_req *)
87 __skb_put(skb, sizeof(*req));
88 memset(req, 0, sizeof(*req));
89 INIT_TP_WR(req, 0);
90 OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SRQ_TABLE_REQ,
91 TID_TID_V(srq_idx) |
92 TID_QID_V(adap->sge.fw_evtq.abs_id)));
93 req->idx = srq_idx;
94
95 mutex_lock(&s->lock);
96
97 s->entryp = entryp;
98 t4_mgmt_tx(adap, skb);
99
100 rc = wait_for_completion_timeout(&s->comp, SRQ_WAIT_TO);
101 if (rc)
102 rc = 0;
103 else /* !rc means we timed out */
104 rc = -ETIMEDOUT;
105
106 WARN_ON_ONCE(entryp->idx != srq_idx);
107 mutex_unlock(&s->lock);
108out:
109 return rc;
110}
111EXPORT_SYMBOL(cxgb4_get_srq_entry);
112
113void do_srq_table_rpl(struct adapter *adap,
114 const struct cpl_srq_table_rpl *rpl)
115{
116 unsigned int idx = TID_TID_G(GET_TID(rpl));
117 struct srq_data *s = adap->srq;
118 struct srq_entry *e;
119
120 if (unlikely(rpl->status != CPL_CONTAINS_READ_RPL)) {
121 dev_err(adap->pdev_dev,
122 "Unexpected SRQ_TABLE_RPL status %u for entry %u\n",
123 rpl->status, idx);
124 goto out;
125 }
126
127 /* Store the read entry */
128 e = s->entryp;
129 e->valid = 1;
130 e->idx = idx;
131 e->pdid = SRQT_PDID_G(be64_to_cpu(rpl->rsvd_pdid));
132 e->qlen = SRQT_QLEN_G(be32_to_cpu(rpl->qlen_qbase));
133 e->qbase = SRQT_QBASE_G(be32_to_cpu(rpl->qlen_qbase));
134 e->cur_msn = be16_to_cpu(rpl->cur_msn);
135 e->max_msn = be16_to_cpu(rpl->max_msn);
136out:
137 complete(&s->comp);
138}
diff --git a/drivers/net/ethernet/chelsio/cxgb4/srq.h b/drivers/net/ethernet/chelsio/cxgb4/srq.h
new file mode 100644
index 000000000000..ec85cf93865a
--- /dev/null
+++ b/drivers/net/ethernet/chelsio/cxgb4/srq.h
@@ -0,0 +1,65 @@
1/*
2 * This file is part of the Chelsio T6 Ethernet driver for Linux.
3 *
4 * Copyright (c) 2017-2018 Chelsio Communications, Inc. All rights reserved.
5 *
6 * This software is available to you under a choice of one of two
7 * licenses. You may choose to be licensed under the terms of the GNU
8 * General Public License (GPL) Version 2, available from the file
9 * COPYING in the main directory of this source tree, or the
10 * OpenIB.org BSD license below:
11 *
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
14 * conditions are met:
15 *
16 * - Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
18 * disclaimer.
19 *
20 * - Redistributions in binary form must reproduce the above
21 * copyright notice, this list of conditions and the following
22 * disclaimer in the documentation and/or other materials
23 * provided with the distribution.
24 *
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 * SOFTWARE.
33 */
34
35#ifndef __CXGB4_SRQ_H
36#define __CXGB4_SRQ_H
37
38struct adapter;
39struct cpl_srq_table_rpl;
40
41#define SRQ_WAIT_TO (HZ * 5)
42
43struct srq_entry {
44 u8 valid;
45 u8 idx;
46 u8 qlen;
47 u16 pdid;
48 u16 cur_msn;
49 u16 max_msn;
50 u32 qbase;
51};
52
53struct srq_data {
54 unsigned int srq_size;
55 struct srq_entry *entryp;
56 struct completion comp;
57 struct mutex lock; /* generic mutex for srq data */
58};
59
60struct srq_data *t4_init_srq(int srq_size);
61int cxgb4_get_srq_entry(struct net_device *dev,
62 int srq_idx, struct srq_entry *entryp);
63void do_srq_table_rpl(struct adapter *adap,
64 const struct cpl_srq_table_rpl *rpl);
65#endif /* __CXGB4_SRQ_H */
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
index 920bccd6bc40..38e38dcfff91 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
@@ -484,6 +484,117 @@ static int t4_edc_err_read(struct adapter *adap, int idx)
484} 484}
485 485
486/** 486/**
487 * t4_memory_rw_init - Get memory window relative offset, base, and size.
488 * @adap: the adapter
489 * @win: PCI-E Memory Window to use
490 * @mtype: memory type: MEM_EDC0, MEM_EDC1, MEM_HMA or MEM_MC
491 * @mem_off: memory relative offset with respect to @mtype.
492 * @mem_base: configured memory base address.
493 * @mem_aperture: configured memory window aperture.
494 *
495 * Get the configured memory window's relative offset, base, and size.
496 */
497int t4_memory_rw_init(struct adapter *adap, int win, int mtype, u32 *mem_off,
498 u32 *mem_base, u32 *mem_aperture)
499{
500 u32 edc_size, mc_size, mem_reg;
501
502 /* Offset into the region of memory which is being accessed
503 * MEM_EDC0 = 0
504 * MEM_EDC1 = 1
505 * MEM_MC = 2 -- MEM_MC for chips with only 1 memory controller
506 * MEM_MC1 = 3 -- for chips with 2 memory controllers (e.g. T5)
507 * MEM_HMA = 4
508 */
509 edc_size = EDRAM0_SIZE_G(t4_read_reg(adap, MA_EDRAM0_BAR_A));
510 if (mtype == MEM_HMA) {
511 *mem_off = 2 * (edc_size * 1024 * 1024);
512 } else if (mtype != MEM_MC1) {
513 *mem_off = (mtype * (edc_size * 1024 * 1024));
514 } else {
515 mc_size = EXT_MEM0_SIZE_G(t4_read_reg(adap,
516 MA_EXT_MEMORY0_BAR_A));
517 *mem_off = (MEM_MC0 * edc_size + mc_size) * 1024 * 1024;
518 }
519
520 /* Each PCI-E Memory Window is programmed with a window size -- or
521 * "aperture" -- which controls the granularity of its mapping onto
522 * adapter memory. We need to grab that aperture in order to know
523 * how to use the specified window. The window is also programmed
524 * with the base address of the Memory Window in BAR0's address
525 * space. For T4 this is an absolute PCI-E Bus Address. For T5
526 * the address is relative to BAR0.
527 */
528 mem_reg = t4_read_reg(adap,
529 PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN_A,
530 win));
531 /* a dead adapter will return 0xffffffff for PIO reads */
532 if (mem_reg == 0xffffffff)
533 return -ENXIO;
534
535 *mem_aperture = 1 << (WINDOW_G(mem_reg) + WINDOW_SHIFT_X);
536 *mem_base = PCIEOFST_G(mem_reg) << PCIEOFST_SHIFT_X;
537 if (is_t4(adap->params.chip))
538 *mem_base -= adap->t4_bar0;
539
540 return 0;
541}
542
543/**
544 * t4_memory_update_win - Move memory window to specified address.
545 * @adap: the adapter
546 * @win: PCI-E Memory Window to use
547 * @addr: location to move.
548 *
549 * Move memory window to specified address.
550 */
551void t4_memory_update_win(struct adapter *adap, int win, u32 addr)
552{
553 t4_write_reg(adap,
554 PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_OFFSET_A, win),
555 addr);
556 /* Read it back to ensure that changes propagate before we
557 * attempt to use the new value.
558 */
559 t4_read_reg(adap,
560 PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_OFFSET_A, win));
561}
562
563/**
564 * t4_memory_rw_residual - Read/Write residual data.
565 * @adap: the adapter
566 * @off: relative offset within residual to start read/write.
567 * @addr: address within indicated memory type.
568 * @buf: host memory buffer
569 * @dir: direction of transfer T4_MEMORY_READ (1) or T4_MEMORY_WRITE (0)
570 *
571 * Read/Write residual data less than 32-bits.
572 */
573void t4_memory_rw_residual(struct adapter *adap, u32 off, u32 addr, u8 *buf,
574 int dir)
575{
576 union {
577 u32 word;
578 char byte[4];
579 } last;
580 unsigned char *bp;
581 int i;
582
583 if (dir == T4_MEMORY_READ) {
584 last.word = le32_to_cpu((__force __le32)
585 t4_read_reg(adap, addr));
586 for (bp = (unsigned char *)buf, i = off; i < 4; i++)
587 bp[i] = last.byte[i];
588 } else {
589 last.word = *buf;
590 for (i = off; i < 4; i++)
591 last.byte[i] = 0;
592 t4_write_reg(adap, addr,
593 (__force u32)cpu_to_le32(last.word));
594 }
595}
596
597/**
487 * t4_memory_rw - read/write EDC 0, EDC 1 or MC via PCIE memory window 598 * t4_memory_rw - read/write EDC 0, EDC 1 or MC via PCIE memory window
488 * @adap: the adapter 599 * @adap: the adapter
489 * @win: PCI-E Memory Window to use 600 * @win: PCI-E Memory Window to use
@@ -504,8 +615,9 @@ int t4_memory_rw(struct adapter *adap, int win, int mtype, u32 addr,
504 u32 len, void *hbuf, int dir) 615 u32 len, void *hbuf, int dir)
505{ 616{
506 u32 pos, offset, resid, memoffset; 617 u32 pos, offset, resid, memoffset;
507 u32 edc_size, mc_size, win_pf, mem_reg, mem_aperture, mem_base; 618 u32 win_pf, mem_aperture, mem_base;
508 u32 *buf; 619 u32 *buf;
620 int ret;
509 621
510 /* Argument sanity checks ... 622 /* Argument sanity checks ...
511 */ 623 */
@@ -521,59 +633,26 @@ int t4_memory_rw(struct adapter *adap, int win, int mtype, u32 addr,
521 resid = len & 0x3; 633 resid = len & 0x3;
522 len -= resid; 634 len -= resid;
523 635
524 /* Offset into the region of memory which is being accessed 636 ret = t4_memory_rw_init(adap, win, mtype, &memoffset, &mem_base,
525 * MEM_EDC0 = 0 637 &mem_aperture);
526 * MEM_EDC1 = 1 638 if (ret)
527 * MEM_MC = 2 -- MEM_MC for chips with only 1 memory controller 639 return ret;
528 * MEM_MC1 = 3 -- for chips with 2 memory controllers (e.g. T5)
529 * MEM_HMA = 4
530 */
531 edc_size = EDRAM0_SIZE_G(t4_read_reg(adap, MA_EDRAM0_BAR_A));
532 if (mtype == MEM_HMA) {
533 memoffset = 2 * (edc_size * 1024 * 1024);
534 } else if (mtype != MEM_MC1) {
535 memoffset = (mtype * (edc_size * 1024 * 1024));
536 } else {
537 mc_size = EXT_MEM0_SIZE_G(t4_read_reg(adap,
538 MA_EXT_MEMORY0_BAR_A));
539 memoffset = (MEM_MC0 * edc_size + mc_size) * 1024 * 1024;
540 }
541 640
542 /* Determine the PCIE_MEM_ACCESS_OFFSET */ 641 /* Determine the PCIE_MEM_ACCESS_OFFSET */
543 addr = addr + memoffset; 642 addr = addr + memoffset;
544 643
545 /* Each PCI-E Memory Window is programmed with a window size -- or
546 * "aperture" -- which controls the granularity of its mapping onto
547 * adapter memory. We need to grab that aperture in order to know
548 * how to use the specified window. The window is also programmed
549 * with the base address of the Memory Window in BAR0's address
550 * space. For T4 this is an absolute PCI-E Bus Address. For T5
551 * the address is relative to BAR0.
552 */
553 mem_reg = t4_read_reg(adap,
554 PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN_A,
555 win));
556 mem_aperture = 1 << (WINDOW_G(mem_reg) + WINDOW_SHIFT_X);
557 mem_base = PCIEOFST_G(mem_reg) << PCIEOFST_SHIFT_X;
558 if (is_t4(adap->params.chip))
559 mem_base -= adap->t4_bar0;
560 win_pf = is_t4(adap->params.chip) ? 0 : PFNUM_V(adap->pf); 644 win_pf = is_t4(adap->params.chip) ? 0 : PFNUM_V(adap->pf);
561 645
562 /* Calculate our initial PCI-E Memory Window Position and Offset into 646 /* Calculate our initial PCI-E Memory Window Position and Offset into
563 * that Window. 647 * that Window.
564 */ 648 */
565 pos = addr & ~(mem_aperture-1); 649 pos = addr & ~(mem_aperture - 1);
566 offset = addr - pos; 650 offset = addr - pos;
567 651
568 /* Set up initial PCI-E Memory Window to cover the start of our 652 /* Set up initial PCI-E Memory Window to cover the start of our
569 * transfer. (Read it back to ensure that changes propagate before we 653 * transfer.
570 * attempt to use the new value.)
571 */ 654 */
572 t4_write_reg(adap, 655 t4_memory_update_win(adap, win, pos | win_pf);
573 PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_OFFSET_A, win),
574 pos | win_pf);
575 t4_read_reg(adap,
576 PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_OFFSET_A, win));
577 656
578 /* Transfer data to/from the adapter as long as there's an integral 657 /* Transfer data to/from the adapter as long as there's an integral
579 * number of 32-bit transfers to complete. 658 * number of 32-bit transfers to complete.
@@ -628,12 +707,7 @@ int t4_memory_rw(struct adapter *adap, int win, int mtype, u32 addr,
628 if (offset == mem_aperture) { 707 if (offset == mem_aperture) {
629 pos += mem_aperture; 708 pos += mem_aperture;
630 offset = 0; 709 offset = 0;
631 t4_write_reg(adap, 710 t4_memory_update_win(adap, win, pos | win_pf);
632 PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_OFFSET_A,
633 win), pos | win_pf);
634 t4_read_reg(adap,
635 PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_OFFSET_A,
636 win));
637 } 711 }
638 } 712 }
639 713
@@ -642,28 +716,9 @@ int t4_memory_rw(struct adapter *adap, int win, int mtype, u32 addr,
642 * residual amount. The PCI-E Memory Window has already been moved 716 * residual amount. The PCI-E Memory Window has already been moved
643 * above (if necessary) to cover this final transfer. 717 * above (if necessary) to cover this final transfer.
644 */ 718 */
645 if (resid) { 719 if (resid)
646 union { 720 t4_memory_rw_residual(adap, resid, mem_base + offset,
647 u32 word; 721 (u8 *)buf, dir);
648 char byte[4];
649 } last;
650 unsigned char *bp;
651 int i;
652
653 if (dir == T4_MEMORY_READ) {
654 last.word = le32_to_cpu(
655 (__force __le32)t4_read_reg(adap,
656 mem_base + offset));
657 for (bp = (unsigned char *)buf, i = resid; i < 4; i++)
658 bp[i] = last.byte[i];
659 } else {
660 last.word = *buf;
661 for (i = resid; i < 4; i++)
662 last.byte[i] = 0;
663 t4_write_reg(adap, mem_base + offset,
664 (__force u32)cpu_to_le32(last.word));
665 }
666 }
667 722
668 return 0; 723 return 0;
669} 724}
@@ -6036,6 +6091,7 @@ unsigned int t4_get_tp_ch_map(struct adapter *adap, int pidx)
6036 6091
6037 case CHELSIO_T6: 6092 case CHELSIO_T6:
6038 switch (nports) { 6093 switch (nports) {
6094 case 1:
6039 case 2: return 1 << pidx; 6095 case 2: return 1 << pidx;
6040 } 6096 }
6041 break; 6097 break;
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h b/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h
index d0db4427b77e..5e8f5ca8e3ee 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h
@@ -52,6 +52,7 @@ enum {
52 CPL_L2T_WRITE_REQ = 0x12, 52 CPL_L2T_WRITE_REQ = 0x12,
53 CPL_SMT_WRITE_REQ = 0x14, 53 CPL_SMT_WRITE_REQ = 0x14,
54 CPL_TID_RELEASE = 0x1A, 54 CPL_TID_RELEASE = 0x1A,
55 CPL_SRQ_TABLE_REQ = 0x1C,
55 CPL_TX_DATA_ISO = 0x1F, 56 CPL_TX_DATA_ISO = 0x1F,
56 57
57 CPL_CLOSE_LISTSRV_RPL = 0x20, 58 CPL_CLOSE_LISTSRV_RPL = 0x20,
@@ -102,6 +103,7 @@ enum {
102 CPL_FW4_MSG = 0xC0, 103 CPL_FW4_MSG = 0xC0,
103 CPL_FW4_PLD = 0xC1, 104 CPL_FW4_PLD = 0xC1,
104 CPL_FW4_ACK = 0xC3, 105 CPL_FW4_ACK = 0xC3,
106 CPL_SRQ_TABLE_RPL = 0xCC,
105 107
106 CPL_RX_PHYS_DSGL = 0xD0, 108 CPL_RX_PHYS_DSGL = 0xD0,
107 109
@@ -136,6 +138,8 @@ enum CPL_error {
136 CPL_ERR_KEEPALV_NEG_ADVICE = 37, 138 CPL_ERR_KEEPALV_NEG_ADVICE = 37,
137 CPL_ERR_ABORT_FAILED = 42, 139 CPL_ERR_ABORT_FAILED = 42,
138 CPL_ERR_IWARP_FLM = 50, 140 CPL_ERR_IWARP_FLM = 50,
141 CPL_CONTAINS_READ_RPL = 60,
142 CPL_CONTAINS_WRITE_RPL = 61,
139}; 143};
140 144
141enum { 145enum {
@@ -198,6 +202,7 @@ union opcode_tid {
198/* partitioning of TID fields that also carry a queue id */ 202/* partitioning of TID fields that also carry a queue id */
199#define TID_TID_S 0 203#define TID_TID_S 0
200#define TID_TID_M 0x3fff 204#define TID_TID_M 0x3fff
205#define TID_TID_V(x) ((x) << TID_TID_S)
201#define TID_TID_G(x) (((x) >> TID_TID_S) & TID_TID_M) 206#define TID_TID_G(x) (((x) >> TID_TID_S) & TID_TID_M)
202 207
203#define TID_QID_S 14 208#define TID_QID_S 14
@@ -743,6 +748,22 @@ struct cpl_abort_req_rss {
743 u8 status; 748 u8 status;
744}; 749};
745 750
751struct cpl_abort_req_rss6 {
752 WR_HDR;
753 union opcode_tid ot;
754 __u32 srqidx_status;
755};
756
757#define ABORT_RSS_STATUS_S 0
758#define ABORT_RSS_STATUS_M 0xff
759#define ABORT_RSS_STATUS_V(x) ((x) << ABORT_RSS_STATUS_S)
760#define ABORT_RSS_STATUS_G(x) (((x) >> ABORT_RSS_STATUS_S) & ABORT_RSS_STATUS_M)
761
762#define ABORT_RSS_SRQIDX_S 8
763#define ABORT_RSS_SRQIDX_M 0xffffff
764#define ABORT_RSS_SRQIDX_V(x) ((x) << ABORT_RSS_SRQIDX_S)
765#define ABORT_RSS_SRQIDX_G(x) (((x) >> ABORT_RSS_SRQIDX_S) & ABORT_RSS_SRQIDX_M)
766
746struct cpl_abort_req { 767struct cpl_abort_req {
747 WR_HDR; 768 WR_HDR;
748 union opcode_tid ot; 769 union opcode_tid ot;
@@ -758,6 +779,11 @@ struct cpl_abort_rpl_rss {
758 u8 status; 779 u8 status;
759}; 780};
760 781
782struct cpl_abort_rpl_rss6 {
783 union opcode_tid ot;
784 __u32 srqidx_status;
785};
786
761struct cpl_abort_rpl { 787struct cpl_abort_rpl {
762 WR_HDR; 788 WR_HDR;
763 union opcode_tid ot; 789 union opcode_tid ot;
@@ -2112,4 +2138,49 @@ enum {
2112 X_CPL_RX_MPS_PKT_TYPE_QFC = 1 << 2, 2138 X_CPL_RX_MPS_PKT_TYPE_QFC = 1 << 2,
2113 X_CPL_RX_MPS_PKT_TYPE_PTP = 1 << 3 2139 X_CPL_RX_MPS_PKT_TYPE_PTP = 1 << 3
2114}; 2140};
2141
2142struct cpl_srq_table_req {
2143 WR_HDR;
2144 union opcode_tid ot;
2145 __u8 status;
2146 __u8 rsvd[2];
2147 __u8 idx;
2148 __be64 rsvd_pdid;
2149 __be32 qlen_qbase;
2150 __be16 cur_msn;
2151 __be16 max_msn;
2152};
2153
2154struct cpl_srq_table_rpl {
2155 union opcode_tid ot;
2156 __u8 status;
2157 __u8 rsvd[2];
2158 __u8 idx;
2159 __be64 rsvd_pdid;
2160 __be32 qlen_qbase;
2161 __be16 cur_msn;
2162 __be16 max_msn;
2163};
2164
2165/* cpl_srq_table_{req,rpl}.params fields */
2166#define SRQT_QLEN_S 28
2167#define SRQT_QLEN_M 0xF
2168#define SRQT_QLEN_V(x) ((x) << SRQT_QLEN_S)
2169#define SRQT_QLEN_G(x) (((x) >> SRQT_QLEN_S) & SRQT_QLEN_M)
2170
2171#define SRQT_QBASE_S 0
2172#define SRQT_QBASE_M 0x3FFFFFF
2173#define SRQT_QBASE_V(x) ((x) << SRQT_QBASE_S)
2174#define SRQT_QBASE_G(x) (((x) >> SRQT_QBASE_S) & SRQT_QBASE_M)
2175
2176#define SRQT_PDID_S 0
2177#define SRQT_PDID_M 0xFF
2178#define SRQT_PDID_V(x) ((x) << SRQT_PDID_S)
2179#define SRQT_PDID_G(x) (((x) >> SRQT_PDID_S) & SRQT_PDID_M)
2180
2181#define SRQT_IDX_S 0
2182#define SRQT_IDX_M 0xF
2183#define SRQT_IDX_V(x) ((x) << SRQT_IDX_S)
2184#define SRQT_IDX_G(x) (((x) >> SRQT_IDX_S) & SRQT_IDX_M)
2185
2115#endif /* __T4_MSG_H */ 2186#endif /* __T4_MSG_H */
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h
index 0d83b4064a78..544757f6ab3a 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h
@@ -101,6 +101,7 @@ enum fw_wr_opcodes {
101 FW_RI_BIND_MW_WR = 0x18, 101 FW_RI_BIND_MW_WR = 0x18,
102 FW_RI_FR_NSMR_WR = 0x19, 102 FW_RI_FR_NSMR_WR = 0x19,
103 FW_RI_FR_NSMR_TPTE_WR = 0x20, 103 FW_RI_FR_NSMR_TPTE_WR = 0x20,
104 FW_RI_RDMA_WRITE_CMPL_WR = 0x21,
104 FW_RI_INV_LSTAG_WR = 0x1a, 105 FW_RI_INV_LSTAG_WR = 0x1a,
105 FW_ISCSI_TX_DATA_WR = 0x45, 106 FW_ISCSI_TX_DATA_WR = 0x45,
106 FW_PTP_TX_PKT_WR = 0x46, 107 FW_PTP_TX_PKT_WR = 0x46,
@@ -766,6 +767,7 @@ enum fw_cmd_opcodes {
766 FW_DEVLOG_CMD = 0x25, 767 FW_DEVLOG_CMD = 0x25,
767 FW_CLIP_CMD = 0x28, 768 FW_CLIP_CMD = 0x28,
768 FW_PTP_CMD = 0x3e, 769 FW_PTP_CMD = 0x3e,
770 FW_HMA_CMD = 0x3f,
769 FW_LASTC2E_CMD = 0x40, 771 FW_LASTC2E_CMD = 0x40,
770 FW_ERROR_CMD = 0x80, 772 FW_ERROR_CMD = 0x80,
771 FW_DEBUG_CMD = 0x81, 773 FW_DEBUG_CMD = 0x81,
@@ -1132,6 +1134,7 @@ enum fw_memtype_cf {
1132 FW_MEMTYPE_CF_FLASH = 0x4, 1134 FW_MEMTYPE_CF_FLASH = 0x4,
1133 FW_MEMTYPE_CF_INTERNAL = 0x5, 1135 FW_MEMTYPE_CF_INTERNAL = 0x5,
1134 FW_MEMTYPE_CF_EXTMEM1 = 0x6, 1136 FW_MEMTYPE_CF_EXTMEM1 = 0x6,
1137 FW_MEMTYPE_CF_HMA = 0x7,
1135}; 1138};
1136 1139
1137struct fw_caps_config_cmd { 1140struct fw_caps_config_cmd {
@@ -1210,6 +1213,9 @@ enum fw_params_param_dev {
1210 FW_PARAMS_PARAM_DEV_RI_FR_NSMR_TPTE_WR = 0x1C, 1213 FW_PARAMS_PARAM_DEV_RI_FR_NSMR_TPTE_WR = 0x1C,
1211 FW_PARAMS_PARAM_DEV_FILTER2_WR = 0x1D, 1214 FW_PARAMS_PARAM_DEV_FILTER2_WR = 0x1D,
1212 FW_PARAMS_PARAM_DEV_MPSBGMAP = 0x1E, 1215 FW_PARAMS_PARAM_DEV_MPSBGMAP = 0x1E,
1216 FW_PARAMS_PARAM_DEV_HMA_SIZE = 0x20,
1217 FW_PARAMS_PARAM_DEV_RDMA_WRITE_WITH_IMM = 0x21,
1218 FW_PARAMS_PARAM_DEV_RI_WRITE_CMPL_WR = 0x24,
1213}; 1219};
1214 1220
1215/* 1221/*
@@ -1241,6 +1247,8 @@ enum fw_params_param_pfvf {
1241 FW_PARAMS_PARAM_PFVF_SQRQ_END = 0x16, 1247 FW_PARAMS_PARAM_PFVF_SQRQ_END = 0x16,
1242 FW_PARAMS_PARAM_PFVF_CQ_START = 0x17, 1248 FW_PARAMS_PARAM_PFVF_CQ_START = 0x17,
1243 FW_PARAMS_PARAM_PFVF_CQ_END = 0x18, 1249 FW_PARAMS_PARAM_PFVF_CQ_END = 0x18,
1250 FW_PARAMS_PARAM_PFVF_SRQ_START = 0x19,
1251 FW_PARAMS_PARAM_PFVF_SRQ_END = 0x1A,
1244 FW_PARAMS_PARAM_PFVF_SCHEDCLASS_ETH = 0x20, 1252 FW_PARAMS_PARAM_PFVF_SCHEDCLASS_ETH = 0x20,
1245 FW_PARAMS_PARAM_PFVF_VIID = 0x24, 1253 FW_PARAMS_PARAM_PFVF_VIID = 0x24,
1246 FW_PARAMS_PARAM_PFVF_CPMASK = 0x25, 1254 FW_PARAMS_PARAM_PFVF_CPMASK = 0x25,
@@ -3435,6 +3443,59 @@ struct fw_debug_cmd {
3435#define FW_DEBUG_CMD_TYPE_G(x) \ 3443#define FW_DEBUG_CMD_TYPE_G(x) \
3436 (((x) >> FW_DEBUG_CMD_TYPE_S) & FW_DEBUG_CMD_TYPE_M) 3444 (((x) >> FW_DEBUG_CMD_TYPE_S) & FW_DEBUG_CMD_TYPE_M)
3437 3445
3446struct fw_hma_cmd {
3447 __be32 op_pkd;
3448 __be32 retval_len16;
3449 __be32 mode_to_pcie_params;
3450 __be32 naddr_size;
3451 __be32 addr_size_pkd;
3452 __be32 r6;
3453 __be64 phy_address[5];
3454};
3455
3456#define FW_HMA_CMD_MODE_S 31
3457#define FW_HMA_CMD_MODE_M 0x1
3458#define FW_HMA_CMD_MODE_V(x) ((x) << FW_HMA_CMD_MODE_S)
3459#define FW_HMA_CMD_MODE_G(x) \
3460 (((x) >> FW_HMA_CMD_MODE_S) & FW_HMA_CMD_MODE_M)
3461#define FW_HMA_CMD_MODE_F FW_HMA_CMD_MODE_V(1U)
3462
3463#define FW_HMA_CMD_SOC_S 30
3464#define FW_HMA_CMD_SOC_M 0x1
3465#define FW_HMA_CMD_SOC_V(x) ((x) << FW_HMA_CMD_SOC_S)
3466#define FW_HMA_CMD_SOC_G(x) (((x) >> FW_HMA_CMD_SOC_S) & FW_HMA_CMD_SOC_M)
3467#define FW_HMA_CMD_SOC_F FW_HMA_CMD_SOC_V(1U)
3468
3469#define FW_HMA_CMD_EOC_S 29
3470#define FW_HMA_CMD_EOC_M 0x1
3471#define FW_HMA_CMD_EOC_V(x) ((x) << FW_HMA_CMD_EOC_S)
3472#define FW_HMA_CMD_EOC_G(x) (((x) >> FW_HMA_CMD_EOC_S) & FW_HMA_CMD_EOC_M)
3473#define FW_HMA_CMD_EOC_F FW_HMA_CMD_EOC_V(1U)
3474
3475#define FW_HMA_CMD_PCIE_PARAMS_S 0
3476#define FW_HMA_CMD_PCIE_PARAMS_M 0x7ffffff
3477#define FW_HMA_CMD_PCIE_PARAMS_V(x) ((x) << FW_HMA_CMD_PCIE_PARAMS_S)
3478#define FW_HMA_CMD_PCIE_PARAMS_G(x) \
3479 (((x) >> FW_HMA_CMD_PCIE_PARAMS_S) & FW_HMA_CMD_PCIE_PARAMS_M)
3480
3481#define FW_HMA_CMD_NADDR_S 12
3482#define FW_HMA_CMD_NADDR_M 0x3f
3483#define FW_HMA_CMD_NADDR_V(x) ((x) << FW_HMA_CMD_NADDR_S)
3484#define FW_HMA_CMD_NADDR_G(x) \
3485 (((x) >> FW_HMA_CMD_NADDR_S) & FW_HMA_CMD_NADDR_M)
3486
3487#define FW_HMA_CMD_SIZE_S 0
3488#define FW_HMA_CMD_SIZE_M 0xfff
3489#define FW_HMA_CMD_SIZE_V(x) ((x) << FW_HMA_CMD_SIZE_S)
3490#define FW_HMA_CMD_SIZE_G(x) \
3491 (((x) >> FW_HMA_CMD_SIZE_S) & FW_HMA_CMD_SIZE_M)
3492
3493#define FW_HMA_CMD_ADDR_SIZE_S 11
3494#define FW_HMA_CMD_ADDR_SIZE_M 0x1fffff
3495#define FW_HMA_CMD_ADDR_SIZE_V(x) ((x) << FW_HMA_CMD_ADDR_SIZE_S)
3496#define FW_HMA_CMD_ADDR_SIZE_G(x) \
3497 (((x) >> FW_HMA_CMD_ADDR_SIZE_S) & FW_HMA_CMD_ADDR_SIZE_M)
3498
3438enum pcie_fw_eval { 3499enum pcie_fw_eval {
3439 PCIE_FW_EVAL_CRASH = 0, 3500 PCIE_FW_EVAL_CRASH = 0,
3440}; 3501};
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
index b7e79e64d2ed..7bd8497fd9be 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
@@ -155,8 +155,6 @@ void t4vf_os_link_changed(struct adapter *adapter, int pidx, int link_ok)
155 const char *fc; 155 const char *fc;
156 const struct port_info *pi = netdev_priv(dev); 156 const struct port_info *pi = netdev_priv(dev);
157 157
158 netif_carrier_on(dev);
159
160 switch (pi->link_cfg.speed) { 158 switch (pi->link_cfg.speed) {
161 case 100: 159 case 100:
162 s = "100Mbps"; 160 s = "100Mbps";
@@ -202,7 +200,6 @@ void t4vf_os_link_changed(struct adapter *adapter, int pidx, int link_ok)
202 200
203 netdev_info(dev, "link up, %s, full-duplex, %s PAUSE\n", s, fc); 201 netdev_info(dev, "link up, %s, full-duplex, %s PAUSE\n", s, fc);
204 } else { 202 } else {
205 netif_carrier_off(dev);
206 netdev_info(dev, "link down\n"); 203 netdev_info(dev, "link down\n");
207 } 204 }
208} 205}
@@ -278,6 +275,17 @@ static int link_start(struct net_device *dev)
278 */ 275 */
279 if (ret == 0) 276 if (ret == 0)
280 ret = t4vf_enable_vi(pi->adapter, pi->viid, true, true); 277 ret = t4vf_enable_vi(pi->adapter, pi->viid, true, true);
278
279 /* The Virtual Interfaces are connected to an internal switch on the
280 * chip which allows VIs attached to the same port to talk to each
281 * other even when the port link is down. As a result, we generally
282 * want to always report a VI's link as being "up", provided there are
283 * no errors in enabling vi.
284 */
285
286 if (ret == 0)
287 netif_carrier_on(dev);
288
281 return ret; 289 return ret;
282} 290}
283 291
@@ -1281,22 +1289,22 @@ static void fw_caps_to_lmm(enum fw_port_type port_type,
1281 1289
1282 case FW_PORT_TYPE_KR: 1290 case FW_PORT_TYPE_KR:
1283 SET_LMM(Backplane); 1291 SET_LMM(Backplane);
1284 SET_LMM(10000baseKR_Full); 1292 FW_CAPS_TO_LMM(SPEED_10G, 10000baseKR_Full);
1285 break; 1293 break;
1286 1294
1287 case FW_PORT_TYPE_BP_AP: 1295 case FW_PORT_TYPE_BP_AP:
1288 SET_LMM(Backplane); 1296 SET_LMM(Backplane);
1289 SET_LMM(10000baseR_FEC); 1297 FW_CAPS_TO_LMM(SPEED_1G, 1000baseKX_Full);
1290 SET_LMM(10000baseKR_Full); 1298 FW_CAPS_TO_LMM(SPEED_10G, 10000baseR_FEC);
1291 SET_LMM(1000baseKX_Full); 1299 FW_CAPS_TO_LMM(SPEED_10G, 10000baseKR_Full);
1292 break; 1300 break;
1293 1301
1294 case FW_PORT_TYPE_BP4_AP: 1302 case FW_PORT_TYPE_BP4_AP:
1295 SET_LMM(Backplane); 1303 SET_LMM(Backplane);
1296 SET_LMM(10000baseR_FEC); 1304 FW_CAPS_TO_LMM(SPEED_1G, 1000baseKX_Full);
1297 SET_LMM(10000baseKR_Full); 1305 FW_CAPS_TO_LMM(SPEED_10G, 10000baseR_FEC);
1298 SET_LMM(1000baseKX_Full); 1306 FW_CAPS_TO_LMM(SPEED_10G, 10000baseKR_Full);
1299 SET_LMM(10000baseKX4_Full); 1307 FW_CAPS_TO_LMM(SPEED_10G, 10000baseKX4_Full);
1300 break; 1308 break;
1301 1309
1302 case FW_PORT_TYPE_FIBER_XFI: 1310 case FW_PORT_TYPE_FIBER_XFI:
@@ -1312,18 +1320,24 @@ static void fw_caps_to_lmm(enum fw_port_type port_type,
1312 case FW_PORT_TYPE_BP40_BA: 1320 case FW_PORT_TYPE_BP40_BA:
1313 case FW_PORT_TYPE_QSFP: 1321 case FW_PORT_TYPE_QSFP:
1314 SET_LMM(FIBRE); 1322 SET_LMM(FIBRE);
1315 SET_LMM(40000baseSR4_Full); 1323 FW_CAPS_TO_LMM(SPEED_1G, 1000baseT_Full);
1324 FW_CAPS_TO_LMM(SPEED_10G, 10000baseT_Full);
1325 FW_CAPS_TO_LMM(SPEED_40G, 40000baseSR4_Full);
1316 break; 1326 break;
1317 1327
1318 case FW_PORT_TYPE_CR_QSFP: 1328 case FW_PORT_TYPE_CR_QSFP:
1319 case FW_PORT_TYPE_SFP28: 1329 case FW_PORT_TYPE_SFP28:
1320 SET_LMM(FIBRE); 1330 SET_LMM(FIBRE);
1321 SET_LMM(25000baseCR_Full); 1331 FW_CAPS_TO_LMM(SPEED_1G, 1000baseT_Full);
1332 FW_CAPS_TO_LMM(SPEED_10G, 10000baseT_Full);
1333 FW_CAPS_TO_LMM(SPEED_25G, 25000baseCR_Full);
1322 break; 1334 break;
1323 1335
1324 case FW_PORT_TYPE_KR_SFP28: 1336 case FW_PORT_TYPE_KR_SFP28:
1325 SET_LMM(Backplane); 1337 SET_LMM(Backplane);
1326 SET_LMM(25000baseKR_Full); 1338 FW_CAPS_TO_LMM(SPEED_1G, 1000baseT_Full);
1339 FW_CAPS_TO_LMM(SPEED_10G, 10000baseKR_Full);
1340 FW_CAPS_TO_LMM(SPEED_25G, 25000baseKR_Full);
1327 break; 1341 break;
1328 1342
1329 case FW_PORT_TYPE_KR_XLAUI: 1343 case FW_PORT_TYPE_KR_XLAUI:
@@ -1335,13 +1349,18 @@ static void fw_caps_to_lmm(enum fw_port_type port_type,
1335 1349
1336 case FW_PORT_TYPE_CR2_QSFP: 1350 case FW_PORT_TYPE_CR2_QSFP:
1337 SET_LMM(FIBRE); 1351 SET_LMM(FIBRE);
1338 SET_LMM(50000baseSR2_Full); 1352 FW_CAPS_TO_LMM(SPEED_50G, 50000baseSR2_Full);
1339 break; 1353 break;
1340 1354
1341 case FW_PORT_TYPE_KR4_100G: 1355 case FW_PORT_TYPE_KR4_100G:
1342 case FW_PORT_TYPE_CR4_QSFP: 1356 case FW_PORT_TYPE_CR4_QSFP:
1343 SET_LMM(FIBRE); 1357 SET_LMM(FIBRE);
1344 SET_LMM(100000baseCR4_Full); 1358 FW_CAPS_TO_LMM(SPEED_1G, 1000baseT_Full);
1359 FW_CAPS_TO_LMM(SPEED_10G, 10000baseSR_Full);
1360 FW_CAPS_TO_LMM(SPEED_40G, 40000baseSR4_Full);
1361 FW_CAPS_TO_LMM(SPEED_25G, 25000baseCR_Full);
1362 FW_CAPS_TO_LMM(SPEED_50G, 50000baseCR2_Full);
1363 FW_CAPS_TO_LMM(SPEED_100G, 100000baseCR4_Full);
1345 break; 1364 break;
1346 1365
1347 default: 1366 default:
diff --git a/drivers/net/ethernet/cirrus/mac89x0.c b/drivers/net/ethernet/cirrus/mac89x0.c
index 977d4c2c759d..3f8fe8fd79cc 100644
--- a/drivers/net/ethernet/cirrus/mac89x0.c
+++ b/drivers/net/ethernet/cirrus/mac89x0.c
@@ -56,21 +56,11 @@
56 local_irq_{dis,en}able() 56 local_irq_{dis,en}able()
57*/ 57*/
58 58
59#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
60
59static const char version[] = 61static const char version[] =
60"cs89x0.c:v1.02 11/26/96 Russell Nelson <nelson@crynwr.com>\n"; 62"cs89x0.c:v1.02 11/26/96 Russell Nelson <nelson@crynwr.com>\n";
61 63
62/* ======================= configure the driver here ======================= */
63
64/* use 0 for production, 1 for verification, >2 for debug */
65#ifndef NET_DEBUG
66#define NET_DEBUG 0
67#endif
68
69/* ======================= end of configuration ======================= */
70
71
72/* Always include 'config.h' first in case the user wants to turn on
73 or override something. */
74#include <linux/module.h> 64#include <linux/module.h>
75 65
76/* 66/*
@@ -93,6 +83,7 @@ static const char version[] =
93#include <linux/errno.h> 83#include <linux/errno.h>
94#include <linux/init.h> 84#include <linux/init.h>
95#include <linux/netdevice.h> 85#include <linux/netdevice.h>
86#include <linux/platform_device.h>
96#include <linux/etherdevice.h> 87#include <linux/etherdevice.h>
97#include <linux/skbuff.h> 88#include <linux/skbuff.h>
98#include <linux/delay.h> 89#include <linux/delay.h>
@@ -105,24 +96,22 @@ static const char version[] =
105 96
106#include "cs89x0.h" 97#include "cs89x0.h"
107 98
108static unsigned int net_debug = NET_DEBUG; 99static int debug = -1;
100module_param(debug, int, 0);
101MODULE_PARM_DESC(debug, "debug message level");
109 102
110/* Information that need to be kept for each board. */ 103/* Information that need to be kept for each board. */
111struct net_local { 104struct net_local {
105 int msg_enable;
112 int chip_type; /* one of: CS8900, CS8920, CS8920M */ 106 int chip_type; /* one of: CS8900, CS8920, CS8920M */
113 char chip_revision; /* revision letter of the chip ('A'...) */ 107 char chip_revision; /* revision letter of the chip ('A'...) */
114 int send_cmd; /* the propercommand used to send a packet. */ 108 int send_cmd; /* the propercommand used to send a packet. */
115 int rx_mode; 109 int rx_mode;
116 int curr_rx_cfg; 110 int curr_rx_cfg;
117 int send_underrun; /* keep track of how many underruns in a row we get */ 111 int send_underrun; /* keep track of how many underruns in a row we get */
118 struct sk_buff *skb;
119}; 112};
120 113
121/* Index to functions, as function prototypes. */ 114/* Index to functions, as function prototypes. */
122
123#if 0
124extern void reset_chip(struct net_device *dev);
125#endif
126static int net_open(struct net_device *dev); 115static int net_open(struct net_device *dev);
127static int net_send_packet(struct sk_buff *skb, struct net_device *dev); 116static int net_send_packet(struct sk_buff *skb, struct net_device *dev);
128static irqreturn_t net_interrupt(int irq, void *dev_id); 117static irqreturn_t net_interrupt(int irq, void *dev_id);
@@ -132,10 +121,6 @@ static int net_close(struct net_device *dev);
132static struct net_device_stats *net_get_stats(struct net_device *dev); 121static struct net_device_stats *net_get_stats(struct net_device *dev);
133static int set_mac_address(struct net_device *dev, void *addr); 122static int set_mac_address(struct net_device *dev, void *addr);
134 123
135
136/* Example routines you must write ;->. */
137#define tx_done(dev) 1
138
139/* For reading/writing registers ISA-style */ 124/* For reading/writing registers ISA-style */
140static inline int 125static inline int
141readreg_io(struct net_device *dev, int portno) 126readreg_io(struct net_device *dev, int portno)
@@ -176,12 +161,10 @@ static const struct net_device_ops mac89x0_netdev_ops = {
176 161
177/* Probe for the CS8900 card in slot E. We won't bother looking 162/* Probe for the CS8900 card in slot E. We won't bother looking
178 anywhere else until we have a really good reason to do so. */ 163 anywhere else until we have a really good reason to do so. */
179struct net_device * __init mac89x0_probe(int unit) 164static int mac89x0_device_probe(struct platform_device *pdev)
180{ 165{
181 struct net_device *dev; 166 struct net_device *dev;
182 static int once_is_enough;
183 struct net_local *lp; 167 struct net_local *lp;
184 static unsigned version_printed;
185 int i, slot; 168 int i, slot;
186 unsigned rev_type = 0; 169 unsigned rev_type = 0;
187 unsigned long ioaddr; 170 unsigned long ioaddr;
@@ -189,21 +172,9 @@ struct net_device * __init mac89x0_probe(int unit)
189 int err = -ENODEV; 172 int err = -ENODEV;
190 struct nubus_rsrc *fres; 173 struct nubus_rsrc *fres;
191 174
192 if (!MACH_IS_MAC)
193 return ERR_PTR(-ENODEV);
194
195 dev = alloc_etherdev(sizeof(struct net_local)); 175 dev = alloc_etherdev(sizeof(struct net_local));
196 if (!dev) 176 if (!dev)
197 return ERR_PTR(-ENOMEM); 177 return -ENOMEM;
198
199 if (unit >= 0) {
200 sprintf(dev->name, "eth%d", unit);
201 netdev_boot_setup_check(dev);
202 }
203
204 if (once_is_enough)
205 goto out;
206 once_is_enough = 1;
207 178
208 /* We might have to parameterize this later */ 179 /* We might have to parameterize this later */
209 slot = 0xE; 180 slot = 0xE;
@@ -230,9 +201,13 @@ struct net_device * __init mac89x0_probe(int unit)
230 if (sig != swab16(CHIP_EISA_ID_SIG)) 201 if (sig != swab16(CHIP_EISA_ID_SIG))
231 goto out; 202 goto out;
232 203
204 SET_NETDEV_DEV(dev, &pdev->dev);
205
233 /* Initialize the net_device structure. */ 206 /* Initialize the net_device structure. */
234 lp = netdev_priv(dev); 207 lp = netdev_priv(dev);
235 208
209 lp->msg_enable = netif_msg_init(debug, 0);
210
236 /* Fill in the 'dev' fields. */ 211 /* Fill in the 'dev' fields. */
237 dev->base_addr = ioaddr; 212 dev->base_addr = ioaddr;
238 dev->mem_start = (unsigned long) 213 dev->mem_start = (unsigned long)
@@ -255,19 +230,16 @@ struct net_device * __init mac89x0_probe(int unit)
255 if (lp->chip_type != CS8900 && lp->chip_revision >= 'C') 230 if (lp->chip_type != CS8900 && lp->chip_revision >= 'C')
256 lp->send_cmd = TX_NOW; 231 lp->send_cmd = TX_NOW;
257 232
258 if (net_debug && version_printed++ == 0) 233 netif_dbg(lp, drv, dev, "%s", version);
259 printk(version);
260 234
261 printk(KERN_INFO "%s: cs89%c0%s rev %c found at %#8lx", 235 pr_info("cs89%c0%s rev %c found at %#8lx\n",
262 dev->name, 236 lp->chip_type == CS8900 ? '0' : '2',
263 lp->chip_type==CS8900?'0':'2', 237 lp->chip_type == CS8920M ? "M" : "",
264 lp->chip_type==CS8920M?"M":"", 238 lp->chip_revision, dev->base_addr);
265 lp->chip_revision,
266 dev->base_addr);
267 239
268 /* Try to read the MAC address */ 240 /* Try to read the MAC address */
269 if ((readreg(dev, PP_SelfST) & (EEPROM_PRESENT | EEPROM_OK)) == 0) { 241 if ((readreg(dev, PP_SelfST) & (EEPROM_PRESENT | EEPROM_OK)) == 0) {
270 printk("\nmac89x0: No EEPROM, giving up now.\n"); 242 pr_info("No EEPROM, giving up now.\n");
271 goto out1; 243 goto out1;
272 } else { 244 } else {
273 for (i = 0; i < ETH_ALEN; i += 2) { 245 for (i = 0; i < ETH_ALEN; i += 2) {
@@ -282,39 +254,23 @@ struct net_device * __init mac89x0_probe(int unit)
282 254
283 /* print the IRQ and ethernet address. */ 255 /* print the IRQ and ethernet address. */
284 256
285 printk(" IRQ %d ADDR %pM\n", dev->irq, dev->dev_addr); 257 pr_info("MAC %pM, IRQ %d\n", dev->dev_addr, dev->irq);
286 258
287 dev->netdev_ops = &mac89x0_netdev_ops; 259 dev->netdev_ops = &mac89x0_netdev_ops;
288 260
289 err = register_netdev(dev); 261 err = register_netdev(dev);
290 if (err) 262 if (err)
291 goto out1; 263 goto out1;
292 return NULL; 264
265 platform_set_drvdata(pdev, dev);
266 return 0;
293out1: 267out1:
294 nubus_writew(0, dev->base_addr + ADD_PORT); 268 nubus_writew(0, dev->base_addr + ADD_PORT);
295out: 269out:
296 free_netdev(dev); 270 free_netdev(dev);
297 return ERR_PTR(err); 271 return err;
298} 272}
299 273
300#if 0
301/* This is useful for something, but I don't know what yet. */
302void __init reset_chip(struct net_device *dev)
303{
304 int reset_start_time;
305
306 writereg(dev, PP_SelfCTL, readreg(dev, PP_SelfCTL) | POWER_ON_RESET);
307
308 /* wait 30 ms */
309 msleep_interruptible(30);
310
311 /* Wait until the chip is reset */
312 reset_start_time = jiffies;
313 while( (readreg(dev, PP_SelfST) & INIT_DONE) == 0 && jiffies - reset_start_time < 2)
314 ;
315}
316#endif
317
318/* Open/initialize the board. This is called (in the current kernel) 274/* Open/initialize the board. This is called (in the current kernel)
319 sometime after booting when the 'ifconfig' program is run. 275 sometime after booting when the 'ifconfig' program is run.
320 276
@@ -374,11 +330,9 @@ net_send_packet(struct sk_buff *skb, struct net_device *dev)
374 struct net_local *lp = netdev_priv(dev); 330 struct net_local *lp = netdev_priv(dev);
375 unsigned long flags; 331 unsigned long flags;
376 332
377 if (net_debug > 3) 333 netif_dbg(lp, tx_queued, dev, "sent %d byte packet of type %x\n",
378 printk("%s: sent %d byte packet of type %x\n", 334 skb->len, skb->data[ETH_ALEN + ETH_ALEN] << 8 |
379 dev->name, skb->len, 335 skb->data[ETH_ALEN + ETH_ALEN + 1]);
380 (skb->data[ETH_ALEN+ETH_ALEN] << 8)
381 | skb->data[ETH_ALEN+ETH_ALEN+1]);
382 336
383 /* keep the upload from being interrupted, since we 337 /* keep the upload from being interrupted, since we
384 ask the chip to start transmitting before the 338 ask the chip to start transmitting before the
@@ -416,11 +370,6 @@ static irqreturn_t net_interrupt(int irq, void *dev_id)
416 struct net_local *lp; 370 struct net_local *lp;
417 int ioaddr, status; 371 int ioaddr, status;
418 372
419 if (dev == NULL) {
420 printk ("net_interrupt(): irq %d for unknown device.\n", irq);
421 return IRQ_NONE;
422 }
423
424 ioaddr = dev->base_addr; 373 ioaddr = dev->base_addr;
425 lp = netdev_priv(dev); 374 lp = netdev_priv(dev);
426 375
@@ -432,7 +381,7 @@ static irqreturn_t net_interrupt(int irq, void *dev_id)
432 faster than you can read them off, you're screwed. Hasta la 381 faster than you can read them off, you're screwed. Hasta la
433 vista, baby! */ 382 vista, baby! */
434 while ((status = swab16(nubus_readw(dev->base_addr + ISQ_PORT)))) { 383 while ((status = swab16(nubus_readw(dev->base_addr + ISQ_PORT)))) {
435 if (net_debug > 4)printk("%s: event=%04x\n", dev->name, status); 384 netif_dbg(lp, intr, dev, "status=%04x\n", status);
436 switch(status & ISQ_EVENT_MASK) { 385 switch(status & ISQ_EVENT_MASK) {
437 case ISQ_RECEIVER_EVENT: 386 case ISQ_RECEIVER_EVENT:
438 /* Got a packet(s). */ 387 /* Got a packet(s). */
@@ -462,7 +411,7 @@ static irqreturn_t net_interrupt(int irq, void *dev_id)
462 netif_wake_queue(dev); 411 netif_wake_queue(dev);
463 } 412 }
464 if (status & TX_UNDERRUN) { 413 if (status & TX_UNDERRUN) {
465 if (net_debug > 0) printk("%s: transmit underrun\n", dev->name); 414 netif_dbg(lp, tx_err, dev, "transmit underrun\n");
466 lp->send_underrun++; 415 lp->send_underrun++;
467 if (lp->send_underrun == 3) lp->send_cmd = TX_AFTER_381; 416 if (lp->send_underrun == 3) lp->send_cmd = TX_AFTER_381;
468 else if (lp->send_underrun == 6) lp->send_cmd = TX_AFTER_ALL; 417 else if (lp->send_underrun == 6) lp->send_cmd = TX_AFTER_ALL;
@@ -483,6 +432,7 @@ static irqreturn_t net_interrupt(int irq, void *dev_id)
483static void 432static void
484net_rx(struct net_device *dev) 433net_rx(struct net_device *dev)
485{ 434{
435 struct net_local *lp = netdev_priv(dev);
486 struct sk_buff *skb; 436 struct sk_buff *skb;
487 int status, length; 437 int status, length;
488 438
@@ -506,7 +456,6 @@ net_rx(struct net_device *dev)
506 /* Malloc up new buffer. */ 456 /* Malloc up new buffer. */
507 skb = alloc_skb(length, GFP_ATOMIC); 457 skb = alloc_skb(length, GFP_ATOMIC);
508 if (skb == NULL) { 458 if (skb == NULL) {
509 printk("%s: Memory squeeze, dropping packet.\n", dev->name);
510 dev->stats.rx_dropped++; 459 dev->stats.rx_dropped++;
511 return; 460 return;
512 } 461 }
@@ -515,10 +464,9 @@ net_rx(struct net_device *dev)
515 skb_copy_to_linear_data(skb, (void *)(dev->mem_start + PP_RxFrame), 464 skb_copy_to_linear_data(skb, (void *)(dev->mem_start + PP_RxFrame),
516 length); 465 length);
517 466
518 if (net_debug > 3)printk("%s: received %d byte packet of type %x\n", 467 netif_dbg(lp, rx_status, dev, "received %d byte packet of type %x\n",
519 dev->name, length, 468 length, skb->data[ETH_ALEN + ETH_ALEN] << 8 |
520 (skb->data[ETH_ALEN+ETH_ALEN] << 8) 469 skb->data[ETH_ALEN + ETH_ALEN + 1]);
521 | skb->data[ETH_ALEN+ETH_ALEN+1]);
522 470
523 skb->protocol=eth_type_trans(skb,dev); 471 skb->protocol=eth_type_trans(skb,dev);
524 netif_rx(skb); 472 netif_rx(skb);
@@ -594,7 +542,7 @@ static int set_mac_address(struct net_device *dev, void *addr)
594 return -EADDRNOTAVAIL; 542 return -EADDRNOTAVAIL;
595 543
596 memcpy(dev->dev_addr, saddr->sa_data, ETH_ALEN); 544 memcpy(dev->dev_addr, saddr->sa_data, ETH_ALEN);
597 printk("%s: Setting MAC address to %pM\n", dev->name, dev->dev_addr); 545 netdev_info(dev, "Setting MAC address to %pM\n", dev->dev_addr);
598 546
599 /* set the Ethernet address */ 547 /* set the Ethernet address */
600 for (i=0; i < ETH_ALEN/2; i++) 548 for (i=0; i < ETH_ALEN/2; i++)
@@ -603,32 +551,24 @@ static int set_mac_address(struct net_device *dev, void *addr)
603 return 0; 551 return 0;
604} 552}
605 553
606#ifdef MODULE
607
608static struct net_device *dev_cs89x0;
609static int debug;
610
611module_param(debug, int, 0);
612MODULE_PARM_DESC(debug, "CS89[02]0 debug level (0-5)");
613MODULE_LICENSE("GPL"); 554MODULE_LICENSE("GPL");
614 555
615int __init 556static int mac89x0_device_remove(struct platform_device *pdev)
616init_module(void)
617{ 557{
618 net_debug = debug; 558 struct net_device *dev = platform_get_drvdata(pdev);
619 dev_cs89x0 = mac89x0_probe(-1); 559
620 if (IS_ERR(dev_cs89x0)) { 560 unregister_netdev(dev);
621 printk(KERN_WARNING "mac89x0.c: No card found\n"); 561 nubus_writew(0, dev->base_addr + ADD_PORT);
622 return PTR_ERR(dev_cs89x0); 562 free_netdev(dev);
623 }
624 return 0; 563 return 0;
625} 564}
626 565
627void 566static struct platform_driver mac89x0_platform_driver = {
628cleanup_module(void) 567 .probe = mac89x0_device_probe,
629{ 568 .remove = mac89x0_device_remove,
630 unregister_netdev(dev_cs89x0); 569 .driver = {
631 nubus_writew(0, dev_cs89x0->base_addr + ADD_PORT); 570 .name = "mac89x0",
632 free_netdev(dev_cs89x0); 571 },
633} 572};
634#endif /* MODULE */ 573
574module_platform_driver(mac89x0_platform_driver);
diff --git a/drivers/net/ethernet/cisco/enic/enic.h b/drivers/net/ethernet/cisco/enic/enic.h
index 9b218f0e5a4c..0dd64acd2a3f 100644
--- a/drivers/net/ethernet/cisco/enic/enic.h
+++ b/drivers/net/ethernet/cisco/enic/enic.h
@@ -33,7 +33,7 @@
33 33
34#define DRV_NAME "enic" 34#define DRV_NAME "enic"
35#define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" 35#define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver"
36#define DRV_VERSION "2.3.0.45" 36#define DRV_VERSION "2.3.0.53"
37#define DRV_COPYRIGHT "Copyright 2008-2013 Cisco Systems, Inc" 37#define DRV_COPYRIGHT "Copyright 2008-2013 Cisco Systems, Inc"
38 38
39#define ENIC_BARS_MAX 6 39#define ENIC_BARS_MAX 6
@@ -140,6 +140,7 @@ struct enic_rfs_flw_tbl {
140struct vxlan_offload { 140struct vxlan_offload {
141 u16 vxlan_udp_port_number; 141 u16 vxlan_udp_port_number;
142 u8 patch_level; 142 u8 patch_level;
143 u8 flags;
143}; 144};
144 145
145/* Per-instance private data structure */ 146/* Per-instance private data structure */
diff --git a/drivers/net/ethernet/cisco/enic/enic_ethtool.c b/drivers/net/ethernet/cisco/enic/enic_ethtool.c
index efb9333c7cf8..869006c2002d 100644
--- a/drivers/net/ethernet/cisco/enic/enic_ethtool.c
+++ b/drivers/net/ethernet/cisco/enic/enic_ethtool.c
@@ -474,6 +474,39 @@ static int enic_grxclsrule(struct enic *enic, struct ethtool_rxnfc *cmd)
474 return 0; 474 return 0;
475} 475}
476 476
477static int enic_get_rx_flow_hash(struct enic *enic, struct ethtool_rxnfc *cmd)
478{
479 cmd->data = 0;
480
481 switch (cmd->flow_type) {
482 case TCP_V6_FLOW:
483 case TCP_V4_FLOW:
484 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
485 /* Fall through */
486 case UDP_V6_FLOW:
487 case UDP_V4_FLOW:
488 if (vnic_dev_capable_udp_rss(enic->vdev))
489 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
490 /* Fall through */
491 case SCTP_V4_FLOW:
492 case AH_ESP_V4_FLOW:
493 case AH_V4_FLOW:
494 case ESP_V4_FLOW:
495 case SCTP_V6_FLOW:
496 case AH_ESP_V6_FLOW:
497 case AH_V6_FLOW:
498 case ESP_V6_FLOW:
499 case IPV4_FLOW:
500 case IPV6_FLOW:
501 cmd->data |= RXH_IP_SRC | RXH_IP_DST;
502 break;
503 default:
504 return -EINVAL;
505 }
506
507 return 0;
508}
509
477static int enic_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, 510static int enic_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
478 u32 *rule_locs) 511 u32 *rule_locs)
479{ 512{
@@ -500,6 +533,9 @@ static int enic_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
500 ret = enic_grxclsrule(enic, cmd); 533 ret = enic_grxclsrule(enic, cmd);
501 spin_unlock_bh(&enic->rfs_h.lock); 534 spin_unlock_bh(&enic->rfs_h.lock);
502 break; 535 break;
536 case ETHTOOL_GRXFH:
537 ret = enic_get_rx_flow_hash(enic, cmd);
538 break;
503 default: 539 default:
504 ret = -EOPNOTSUPP; 540 ret = -EOPNOTSUPP;
505 break; 541 break;
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index f202ba72a811..81684acf52af 100644
--- a/drivers/net/ethernet/cisco/enic/enic_main.c
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -191,8 +191,16 @@ static void enic_udp_tunnel_add(struct net_device *netdev,
191 goto error; 191 goto error;
192 } 192 }
193 193
194 if (ti->sa_family != AF_INET) { 194 switch (ti->sa_family) {
195 netdev_info(netdev, "vxlan: only IPv4 offload supported"); 195 case AF_INET6:
196 if (!(enic->vxlan.flags & ENIC_VXLAN_OUTER_IPV6)) {
197 netdev_info(netdev, "vxlan: only IPv4 offload supported");
198 goto error;
199 }
200 /* Fall through */
201 case AF_INET:
202 break;
203 default:
196 goto error; 204 goto error;
197 } 205 }
198 206
@@ -204,6 +212,11 @@ static void enic_udp_tunnel_add(struct net_device *netdev,
204 212
205 goto error; 213 goto error;
206 } 214 }
215 if ((vnic_dev_get_res_count(enic->vdev, RES_TYPE_WQ) != 1) &&
216 !(enic->vxlan.flags & ENIC_VXLAN_MULTI_WQ)) {
217 netdev_info(netdev, "vxlan: vxlan offload with multi wq not supported on this adapter");
218 goto error;
219 }
207 220
208 err = vnic_dev_overlay_offload_cfg(enic->vdev, 221 err = vnic_dev_overlay_offload_cfg(enic->vdev,
209 OVERLAY_CFG_VXLAN_PORT_UPDATE, 222 OVERLAY_CFG_VXLAN_PORT_UPDATE,
@@ -238,9 +251,8 @@ static void enic_udp_tunnel_del(struct net_device *netdev,
238 251
239 spin_lock_bh(&enic->devcmd_lock); 252 spin_lock_bh(&enic->devcmd_lock);
240 253
241 if ((ti->sa_family != AF_INET) || 254 if ((ntohs(ti->port) != enic->vxlan.vxlan_udp_port_number) ||
242 ((ntohs(ti->port) != enic->vxlan.vxlan_udp_port_number)) || 255 ti->type != UDP_TUNNEL_TYPE_VXLAN) {
243 (ti->type != UDP_TUNNEL_TYPE_VXLAN)) {
244 netdev_info(netdev, "udp_tnl: port:%d, sa_family: %d, type: %d not offloaded", 256 netdev_info(netdev, "udp_tnl: port:%d, sa_family: %d, type: %d not offloaded",
245 ntohs(ti->port), ti->sa_family, ti->type); 257 ntohs(ti->port), ti->sa_family, ti->type);
246 goto unlock; 258 goto unlock;
@@ -271,22 +283,37 @@ static netdev_features_t enic_features_check(struct sk_buff *skb,
271 struct enic *enic = netdev_priv(dev); 283 struct enic *enic = netdev_priv(dev);
272 struct udphdr *udph; 284 struct udphdr *udph;
273 u16 port = 0; 285 u16 port = 0;
274 u16 proto; 286 u8 proto;
275 287
276 if (!skb->encapsulation) 288 if (!skb->encapsulation)
277 return features; 289 return features;
278 290
279 features = vxlan_features_check(skb, features); 291 features = vxlan_features_check(skb, features);
280 292
281 /* hardware only supports IPv4 vxlan tunnel */ 293 switch (vlan_get_protocol(skb)) {
282 if (vlan_get_protocol(skb) != htons(ETH_P_IP)) 294 case htons(ETH_P_IPV6):
295 if (!(enic->vxlan.flags & ENIC_VXLAN_OUTER_IPV6))
296 goto out;
297 proto = ipv6_hdr(skb)->nexthdr;
298 break;
299 case htons(ETH_P_IP):
300 proto = ip_hdr(skb)->protocol;
301 break;
302 default:
283 goto out; 303 goto out;
304 }
284 305
285 /* hardware does not support offload of ipv6 inner pkt */ 306 switch (eth->h_proto) {
286 if (eth->h_proto != ntohs(ETH_P_IP)) 307 case ntohs(ETH_P_IPV6):
308 if (!(enic->vxlan.flags & ENIC_VXLAN_INNER_IPV6))
309 goto out;
310 /* Fall through */
311 case ntohs(ETH_P_IP):
312 break;
313 default:
287 goto out; 314 goto out;
315 }
288 316
289 proto = ip_hdr(skb)->protocol;
290 317
291 if (proto == IPPROTO_UDP) { 318 if (proto == IPPROTO_UDP) {
292 udph = udp_hdr(skb); 319 udph = udp_hdr(skb);
@@ -635,12 +662,25 @@ static int enic_queue_wq_skb_csum_l4(struct enic *enic, struct vnic_wq *wq,
635 662
636static void enic_preload_tcp_csum_encap(struct sk_buff *skb) 663static void enic_preload_tcp_csum_encap(struct sk_buff *skb)
637{ 664{
638 if (skb->protocol == cpu_to_be16(ETH_P_IP)) { 665 const struct ethhdr *eth = (struct ethhdr *)skb_inner_mac_header(skb);
666
667 switch (eth->h_proto) {
668 case ntohs(ETH_P_IP):
639 inner_ip_hdr(skb)->check = 0; 669 inner_ip_hdr(skb)->check = 0;
640 inner_tcp_hdr(skb)->check = 670 inner_tcp_hdr(skb)->check =
641 ~csum_tcpudp_magic(inner_ip_hdr(skb)->saddr, 671 ~csum_tcpudp_magic(inner_ip_hdr(skb)->saddr,
642 inner_ip_hdr(skb)->daddr, 0, 672 inner_ip_hdr(skb)->daddr, 0,
643 IPPROTO_TCP, 0); 673 IPPROTO_TCP, 0);
674 break;
675 case ntohs(ETH_P_IPV6):
676 inner_tcp_hdr(skb)->check =
677 ~csum_ipv6_magic(&inner_ipv6_hdr(skb)->saddr,
678 &inner_ipv6_hdr(skb)->daddr, 0,
679 IPPROTO_TCP, 0);
680 break;
681 default:
682 WARN_ONCE(1, "Non ipv4/ipv6 inner pkt for encap offload");
683 break;
644 } 684 }
645} 685}
646 686
@@ -1898,6 +1938,8 @@ static int enic_open(struct net_device *netdev)
1898 } 1938 }
1899 1939
1900 for (i = 0; i < enic->rq_count; i++) { 1940 for (i = 0; i < enic->rq_count; i++) {
1941 /* enable rq before updating rq desc */
1942 vnic_rq_enable(&enic->rq[i]);
1901 vnic_rq_fill(&enic->rq[i], enic_rq_alloc_buf); 1943 vnic_rq_fill(&enic->rq[i], enic_rq_alloc_buf);
1902 /* Need at least one buffer on ring to get going */ 1944 /* Need at least one buffer on ring to get going */
1903 if (vnic_rq_desc_used(&enic->rq[i]) == 0) { 1945 if (vnic_rq_desc_used(&enic->rq[i]) == 0) {
@@ -1909,8 +1951,6 @@ static int enic_open(struct net_device *netdev)
1909 1951
1910 for (i = 0; i < enic->wq_count; i++) 1952 for (i = 0; i < enic->wq_count; i++)
1911 vnic_wq_enable(&enic->wq[i]); 1953 vnic_wq_enable(&enic->wq[i]);
1912 for (i = 0; i < enic->rq_count; i++)
1913 vnic_rq_enable(&enic->rq[i]);
1914 1954
1915 if (!enic_is_dynamic(enic) && !enic_is_sriov_vf(enic)) 1955 if (!enic_is_dynamic(enic) && !enic_is_sriov_vf(enic))
1916 enic_dev_add_station_addr(enic); 1956 enic_dev_add_station_addr(enic);
@@ -1936,8 +1976,12 @@ static int enic_open(struct net_device *netdev)
1936 return 0; 1976 return 0;
1937 1977
1938err_out_free_rq: 1978err_out_free_rq:
1939 for (i = 0; i < enic->rq_count; i++) 1979 for (i = 0; i < enic->rq_count; i++) {
1980 err = vnic_rq_disable(&enic->rq[i]);
1981 if (err)
1982 return err;
1940 vnic_rq_clean(&enic->rq[i], enic_free_rq_buf); 1983 vnic_rq_clean(&enic->rq[i], enic_free_rq_buf);
1984 }
1941 enic_dev_notify_unset(enic); 1985 enic_dev_notify_unset(enic);
1942err_out_free_intr: 1986err_out_free_intr:
1943 enic_unset_affinity_hint(enic); 1987 enic_unset_affinity_hint(enic);
@@ -2151,9 +2195,10 @@ static int enic_dev_wait(struct vnic_dev *vdev,
2151static int enic_dev_open(struct enic *enic) 2195static int enic_dev_open(struct enic *enic)
2152{ 2196{
2153 int err; 2197 int err;
2198 u32 flags = CMD_OPENF_IG_DESCCACHE;
2154 2199
2155 err = enic_dev_wait(enic->vdev, vnic_dev_open, 2200 err = enic_dev_wait(enic->vdev, vnic_dev_open,
2156 vnic_dev_open_done, 0); 2201 vnic_dev_open_done, flags);
2157 if (err) 2202 if (err)
2158 dev_err(enic_get_dev(enic), "vNIC device open failed, err %d\n", 2203 dev_err(enic_get_dev(enic), "vNIC device open failed, err %d\n",
2159 err); 2204 err);
@@ -2275,7 +2320,7 @@ static int enic_set_rss_nic_cfg(struct enic *enic)
2275{ 2320{
2276 struct device *dev = enic_get_dev(enic); 2321 struct device *dev = enic_get_dev(enic);
2277 const u8 rss_default_cpu = 0; 2322 const u8 rss_default_cpu = 0;
2278 const u8 rss_hash_type = NIC_CFG_RSS_HASH_TYPE_IPV4 | 2323 u8 rss_hash_type = NIC_CFG_RSS_HASH_TYPE_IPV4 |
2279 NIC_CFG_RSS_HASH_TYPE_TCP_IPV4 | 2324 NIC_CFG_RSS_HASH_TYPE_TCP_IPV4 |
2280 NIC_CFG_RSS_HASH_TYPE_IPV6 | 2325 NIC_CFG_RSS_HASH_TYPE_IPV6 |
2281 NIC_CFG_RSS_HASH_TYPE_TCP_IPV6; 2326 NIC_CFG_RSS_HASH_TYPE_TCP_IPV6;
@@ -2283,6 +2328,8 @@ static int enic_set_rss_nic_cfg(struct enic *enic)
2283 const u8 rss_base_cpu = 0; 2328 const u8 rss_base_cpu = 0;
2284 u8 rss_enable = ENIC_SETTING(enic, RSS) && (enic->rq_count > 1); 2329 u8 rss_enable = ENIC_SETTING(enic, RSS) && (enic->rq_count > 1);
2285 2330
2331 if (vnic_dev_capable_udp_rss(enic->vdev))
2332 rss_hash_type |= NIC_CFG_RSS_HASH_TYPE_UDP;
2286 if (rss_enable) { 2333 if (rss_enable) {
2287 if (!enic_set_rsskey(enic)) { 2334 if (!enic_set_rsskey(enic)) {
2288 if (enic_set_rsscpu(enic, rss_hash_bits)) { 2335 if (enic_set_rsscpu(enic, rss_hash_bits)) {
@@ -2901,9 +2948,11 @@ static int enic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
2901 netdev->hw_features |= NETIF_F_RXCSUM; 2948 netdev->hw_features |= NETIF_F_RXCSUM;
2902 if (ENIC_SETTING(enic, VXLAN)) { 2949 if (ENIC_SETTING(enic, VXLAN)) {
2903 u64 patch_level; 2950 u64 patch_level;
2951 u64 a1 = 0;
2904 2952
2905 netdev->hw_enc_features |= NETIF_F_RXCSUM | 2953 netdev->hw_enc_features |= NETIF_F_RXCSUM |
2906 NETIF_F_TSO | 2954 NETIF_F_TSO |
2955 NETIF_F_TSO6 |
2907 NETIF_F_TSO_ECN | 2956 NETIF_F_TSO_ECN |
2908 NETIF_F_GSO_UDP_TUNNEL | 2957 NETIF_F_GSO_UDP_TUNNEL |
2909 NETIF_F_HW_CSUM | 2958 NETIF_F_HW_CSUM |
@@ -2922,9 +2971,10 @@ static int enic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
2922 */ 2971 */
2923 err = vnic_dev_get_supported_feature_ver(enic->vdev, 2972 err = vnic_dev_get_supported_feature_ver(enic->vdev,
2924 VIC_FEATURE_VXLAN, 2973 VIC_FEATURE_VXLAN,
2925 &patch_level); 2974 &patch_level, &a1);
2926 if (err) 2975 if (err)
2927 patch_level = 0; 2976 patch_level = 0;
2977 enic->vxlan.flags = (u8)a1;
2928 /* mask bits that are supported by driver 2978 /* mask bits that are supported by driver
2929 */ 2979 */
2930 patch_level &= BIT_ULL(0) | BIT_ULL(2); 2980 patch_level &= BIT_ULL(0) | BIT_ULL(2);
diff --git a/drivers/net/ethernet/cisco/enic/vnic_dev.c b/drivers/net/ethernet/cisco/enic/vnic_dev.c
index 39bad67422dd..76cdd4c9d11f 100644
--- a/drivers/net/ethernet/cisco/enic/vnic_dev.c
+++ b/drivers/net/ethernet/cisco/enic/vnic_dev.c
@@ -1269,16 +1269,32 @@ int vnic_dev_overlay_offload_cfg(struct vnic_dev *vdev, u8 overlay,
1269} 1269}
1270 1270
1271int vnic_dev_get_supported_feature_ver(struct vnic_dev *vdev, u8 feature, 1271int vnic_dev_get_supported_feature_ver(struct vnic_dev *vdev, u8 feature,
1272 u64 *supported_versions) 1272 u64 *supported_versions, u64 *a1)
1273{ 1273{
1274 u64 a0 = feature; 1274 u64 a0 = feature;
1275 int wait = 1000; 1275 int wait = 1000;
1276 u64 a1 = 0;
1277 int ret; 1276 int ret;
1278 1277
1279 ret = vnic_dev_cmd(vdev, CMD_GET_SUPP_FEATURE_VER, &a0, &a1, wait); 1278 ret = vnic_dev_cmd(vdev, CMD_GET_SUPP_FEATURE_VER, &a0, a1, wait);
1280 if (!ret) 1279 if (!ret)
1281 *supported_versions = a0; 1280 *supported_versions = a0;
1282 1281
1283 return ret; 1282 return ret;
1284} 1283}
1284
1285bool vnic_dev_capable_udp_rss(struct vnic_dev *vdev)
1286{
1287 u64 a0 = CMD_NIC_CFG, a1 = 0;
1288 u64 rss_hash_type;
1289 int wait = 1000;
1290 int err;
1291
1292 err = vnic_dev_cmd(vdev, CMD_CAPABILITY, &a0, &a1, wait);
1293 if (err || !a0)
1294 return false;
1295
1296 rss_hash_type = (a1 >> NIC_CFG_RSS_HASH_TYPE_SHIFT) &
1297 NIC_CFG_RSS_HASH_TYPE_MASK_FIELD;
1298
1299 return (rss_hash_type & NIC_CFG_RSS_HASH_TYPE_UDP);
1300}
diff --git a/drivers/net/ethernet/cisco/enic/vnic_dev.h b/drivers/net/ethernet/cisco/enic/vnic_dev.h
index 9d43d6bb9907..59d4cc8fbb85 100644
--- a/drivers/net/ethernet/cisco/enic/vnic_dev.h
+++ b/drivers/net/ethernet/cisco/enic/vnic_dev.h
@@ -183,6 +183,7 @@ int vnic_dev_overlay_offload_ctrl(struct vnic_dev *vdev, u8 overlay, u8 config);
183int vnic_dev_overlay_offload_cfg(struct vnic_dev *vdev, u8 overlay, 183int vnic_dev_overlay_offload_cfg(struct vnic_dev *vdev, u8 overlay,
184 u16 vxlan_udp_port_number); 184 u16 vxlan_udp_port_number);
185int vnic_dev_get_supported_feature_ver(struct vnic_dev *vdev, u8 feature, 185int vnic_dev_get_supported_feature_ver(struct vnic_dev *vdev, u8 feature,
186 u64 *supported_versions); 186 u64 *supported_versions, u64 *a1);
187bool vnic_dev_capable_udp_rss(struct vnic_dev *vdev);
187 188
188#endif /* _VNIC_DEV_H_ */ 189#endif /* _VNIC_DEV_H_ */
diff --git a/drivers/net/ethernet/cisco/enic/vnic_devcmd.h b/drivers/net/ethernet/cisco/enic/vnic_devcmd.h
index d83880b0d468..41de4ba622a1 100644
--- a/drivers/net/ethernet/cisco/enic/vnic_devcmd.h
+++ b/drivers/net/ethernet/cisco/enic/vnic_devcmd.h
@@ -439,6 +439,7 @@ enum vnic_devcmd_cmd {
439 439
440/* flags for CMD_OPEN */ 440/* flags for CMD_OPEN */
441#define CMD_OPENF_OPROM 0x1 /* open coming from option rom */ 441#define CMD_OPENF_OPROM 0x1 /* open coming from option rom */
442#define CMD_OPENF_IG_DESCCACHE 0x2 /* Do not flush IG DESC cache */
442 443
443/* flags for CMD_INIT */ 444/* flags for CMD_INIT */
444#define CMD_INITF_DEFAULT_MAC 0x1 /* init with default mac addr */ 445#define CMD_INITF_DEFAULT_MAC 0x1 /* init with default mac addr */
@@ -697,6 +698,10 @@ enum overlay_ofld_cmd {
697 698
698#define OVERLAY_CFG_VXLAN_PORT_UPDATE 0 699#define OVERLAY_CFG_VXLAN_PORT_UPDATE 0
699 700
701#define ENIC_VXLAN_INNER_IPV6 BIT(0)
702#define ENIC_VXLAN_OUTER_IPV6 BIT(1)
703#define ENIC_VXLAN_MULTI_WQ BIT(2)
704
700/* Use this enum to get the supported versions for each of these features 705/* Use this enum to get the supported versions for each of these features
701 * If you need to use the devcmd_get_supported_feature_version(), add 706 * If you need to use the devcmd_get_supported_feature_version(), add
702 * the new feature into this enum and install function handler in devcmd.c 707 * the new feature into this enum and install function handler in devcmd.c
diff --git a/drivers/net/ethernet/cisco/enic/vnic_nic.h b/drivers/net/ethernet/cisco/enic/vnic_nic.h
index 995a50dd4c99..5a93db0d7afc 100644
--- a/drivers/net/ethernet/cisco/enic/vnic_nic.h
+++ b/drivers/net/ethernet/cisco/enic/vnic_nic.h
@@ -47,6 +47,7 @@
47#define NIC_CFG_RSS_HASH_TYPE_TCP_IPV6 (1 << 4) 47#define NIC_CFG_RSS_HASH_TYPE_TCP_IPV6 (1 << 4)
48#define NIC_CFG_RSS_HASH_TYPE_IPV6_EX (1 << 5) 48#define NIC_CFG_RSS_HASH_TYPE_IPV6_EX (1 << 5)
49#define NIC_CFG_RSS_HASH_TYPE_TCP_IPV6_EX (1 << 6) 49#define NIC_CFG_RSS_HASH_TYPE_TCP_IPV6_EX (1 << 6)
50#define NIC_CFG_RSS_HASH_TYPE_UDP (1 << 7)
50 51
51static inline void vnic_set_nic_cfg(u32 *nic_cfg, 52static inline void vnic_set_nic_cfg(u32 *nic_cfg,
52 u8 rss_default_cpu, u8 rss_hash_type, 53 u8 rss_default_cpu, u8 rss_hash_type,
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index 1a49297224ed..ff92ab1daeb8 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -19,7 +19,7 @@
19#include "be.h" 19#include "be.h"
20#include "be_cmds.h" 20#include "be_cmds.h"
21 21
22char *be_misconfig_evt_port_state[] = { 22const char * const be_misconfig_evt_port_state[] = {
23 "Physical Link is functional", 23 "Physical Link is functional",
24 "Optics faulted/incorrectly installed/not installed - Reseat optics. If issue not resolved, replace.", 24 "Optics faulted/incorrectly installed/not installed - Reseat optics. If issue not resolved, replace.",
25 "Optics of two types installed – Remove one optic or install matching pair of optics.", 25 "Optics of two types installed – Remove one optic or install matching pair of optics.",
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
index 09da2d82c2f0..e8b43cf44b6f 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
@@ -201,7 +201,7 @@ enum {
201 phy_state == BE_PHY_UNQUALIFIED || \ 201 phy_state == BE_PHY_UNQUALIFIED || \
202 phy_state == BE_PHY_UNCERTIFIED) 202 phy_state == BE_PHY_UNCERTIFIED)
203 203
204extern char *be_misconfig_evt_port_state[]; 204extern const char * const be_misconfig_evt_port_state[];
205 205
206/* async event indicating misconfigured port */ 206/* async event indicating misconfigured port */
207struct be_async_event_misconfig_port { 207struct be_async_event_misconfig_port {
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index e4ec32a9ca15..fd43f98ddbe7 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -454,6 +454,16 @@ static void dpaa_set_rx_mode(struct net_device *net_dev)
454 err); 454 err);
455 } 455 }
456 456
457 if (!!(net_dev->flags & IFF_ALLMULTI) != priv->mac_dev->allmulti) {
458 priv->mac_dev->allmulti = !priv->mac_dev->allmulti;
459 err = priv->mac_dev->set_allmulti(priv->mac_dev->fman_mac,
460 priv->mac_dev->allmulti);
461 if (err < 0)
462 netif_err(priv, drv, net_dev,
463 "mac_dev->set_allmulti() = %d\n",
464 err);
465 }
466
457 err = priv->mac_dev->set_multi(net_dev, priv->mac_dev); 467 err = priv->mac_dev->set_multi(net_dev, priv->mac_dev);
458 if (err < 0) 468 if (err < 0)
459 netif_err(priv, drv, net_dev, "mac_dev->set_multi() = %d\n", 469 netif_err(priv, drv, net_dev, "mac_dev->set_multi() = %d\n",
@@ -1916,8 +1926,10 @@ static int skb_to_sg_fd(struct dpaa_priv *priv,
1916 goto csum_failed; 1926 goto csum_failed;
1917 } 1927 }
1918 1928
1929 /* SGT[0] is used by the linear part */
1919 sgt = (struct qm_sg_entry *)(sgt_buf + priv->tx_headroom); 1930 sgt = (struct qm_sg_entry *)(sgt_buf + priv->tx_headroom);
1920 qm_sg_entry_set_len(&sgt[0], skb_headlen(skb)); 1931 frag_len = skb_headlen(skb);
1932 qm_sg_entry_set_len(&sgt[0], frag_len);
1921 sgt[0].bpid = FSL_DPAA_BPID_INV; 1933 sgt[0].bpid = FSL_DPAA_BPID_INV;
1922 sgt[0].offset = 0; 1934 sgt[0].offset = 0;
1923 addr = dma_map_single(dev, skb->data, 1935 addr = dma_map_single(dev, skb->data,
@@ -1930,9 +1942,9 @@ static int skb_to_sg_fd(struct dpaa_priv *priv,
1930 qm_sg_entry_set64(&sgt[0], addr); 1942 qm_sg_entry_set64(&sgt[0], addr);
1931 1943
1932 /* populate the rest of SGT entries */ 1944 /* populate the rest of SGT entries */
1933 frag = &skb_shinfo(skb)->frags[0]; 1945 for (i = 0; i < nr_frags; i++) {
1934 frag_len = frag->size; 1946 frag = &skb_shinfo(skb)->frags[i];
1935 for (i = 1; i <= nr_frags; i++, frag++) { 1947 frag_len = frag->size;
1936 WARN_ON(!skb_frag_page(frag)); 1948 WARN_ON(!skb_frag_page(frag));
1937 addr = skb_frag_dma_map(dev, frag, 0, 1949 addr = skb_frag_dma_map(dev, frag, 0,
1938 frag_len, dma_dir); 1950 frag_len, dma_dir);
@@ -1942,15 +1954,16 @@ static int skb_to_sg_fd(struct dpaa_priv *priv,
1942 goto sg_map_failed; 1954 goto sg_map_failed;
1943 } 1955 }
1944 1956
1945 qm_sg_entry_set_len(&sgt[i], frag_len); 1957 qm_sg_entry_set_len(&sgt[i + 1], frag_len);
1946 sgt[i].bpid = FSL_DPAA_BPID_INV; 1958 sgt[i + 1].bpid = FSL_DPAA_BPID_INV;
1947 sgt[i].offset = 0; 1959 sgt[i + 1].offset = 0;
1948 1960
1949 /* keep the offset in the address */ 1961 /* keep the offset in the address */
1950 qm_sg_entry_set64(&sgt[i], addr); 1962 qm_sg_entry_set64(&sgt[i + 1], addr);
1951 frag_len = frag->size;
1952 } 1963 }
1953 qm_sg_entry_set_f(&sgt[i - 1], frag_len); 1964
1965 /* Set the final bit in the last used entry of the SGT */
1966 qm_sg_entry_set_f(&sgt[nr_frags], frag_len);
1954 1967
1955 qm_fd_set_sg(fd, priv->tx_headroom, skb->len); 1968 qm_fd_set_sg(fd, priv->tx_headroom, skb->len);
1956 1969
@@ -2051,19 +2064,23 @@ static int dpaa_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
2051 /* MAX_SKB_FRAGS is equal or larger than our dpaa_SGT_MAX_ENTRIES; 2064 /* MAX_SKB_FRAGS is equal or larger than our dpaa_SGT_MAX_ENTRIES;
2052 * make sure we don't feed FMan with more fragments than it supports. 2065 * make sure we don't feed FMan with more fragments than it supports.
2053 */ 2066 */
2054 if (nonlinear && 2067 if (unlikely(nonlinear &&
2055 likely(skb_shinfo(skb)->nr_frags < DPAA_SGT_MAX_ENTRIES)) { 2068 (skb_shinfo(skb)->nr_frags >= DPAA_SGT_MAX_ENTRIES))) {
2056 /* Just create a S/G fd based on the skb */
2057 err = skb_to_sg_fd(priv, skb, &fd);
2058 percpu_priv->tx_frag_skbuffs++;
2059 } else {
2060 /* If the egress skb contains more fragments than we support 2069 /* If the egress skb contains more fragments than we support
2061 * we have no choice but to linearize it ourselves. 2070 * we have no choice but to linearize it ourselves.
2062 */ 2071 */
2063 if (unlikely(nonlinear) && __skb_linearize(skb)) 2072 if (__skb_linearize(skb))
2064 goto enomem; 2073 goto enomem;
2065 2074
2066 /* Finally, create a contig FD from this skb */ 2075 nonlinear = skb_is_nonlinear(skb);
2076 }
2077
2078 if (nonlinear) {
2079 /* Just create a S/G fd based on the skb */
2080 err = skb_to_sg_fd(priv, skb, &fd);
2081 percpu_priv->tx_frag_skbuffs++;
2082 } else {
2083 /* Create a contig FD from this skb */
2067 err = skb_to_contig_fd(priv, skb, &fd, &offset); 2084 err = skb_to_contig_fd(priv, skb, &fd, &offset);
2068 } 2085 }
2069 if (unlikely(err < 0)) 2086 if (unlikely(err < 0))
@@ -2200,14 +2217,8 @@ static enum qman_cb_dqrr_result rx_error_dqrr(struct qman_portal *portal,
2200 if (dpaa_eth_napi_schedule(percpu_priv, portal)) 2217 if (dpaa_eth_napi_schedule(percpu_priv, portal))
2201 return qman_cb_dqrr_stop; 2218 return qman_cb_dqrr_stop;
2202 2219
2203 if (dpaa_eth_refill_bpools(priv)) 2220 dpaa_eth_refill_bpools(priv);
2204 /* Unable to refill the buffer pool due to insufficient 2221 dpaa_rx_error(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
2205 * system memory. Just release the frame back into the pool,
2206 * otherwise we'll soon end up with an empty buffer pool.
2207 */
2208 dpaa_fd_release(net_dev, &dq->fd);
2209 else
2210 dpaa_rx_error(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
2211 2222
2212 return qman_cb_dqrr_consume; 2223 return qman_cb_dqrr_consume;
2213} 2224}
@@ -2766,7 +2777,7 @@ static int dpaa_eth_probe(struct platform_device *pdev)
2766 2777
2767 priv->channel = (u16)channel; 2778 priv->channel = (u16)channel;
2768 2779
2769 /* Start a thread that will walk the CPUs with affine portals 2780 /* Walk the CPUs with affine portals
2770 * and add this pool channel to each's dequeue mask. 2781 * and add this pool channel to each's dequeue mask.
2771 */ 2782 */
2772 dpaa_eth_add_channel(priv->channel); 2783 dpaa_eth_add_channel(priv->channel);
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
index faea674094b9..85306d1b2acf 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
@@ -211,7 +211,7 @@ static int dpaa_set_pauseparam(struct net_device *net_dev,
211 if (epause->rx_pause) 211 if (epause->rx_pause)
212 newadv = ADVERTISED_Pause | ADVERTISED_Asym_Pause; 212 newadv = ADVERTISED_Pause | ADVERTISED_Asym_Pause;
213 if (epause->tx_pause) 213 if (epause->tx_pause)
214 newadv |= ADVERTISED_Asym_Pause; 214 newadv ^= ADVERTISED_Asym_Pause;
215 215
216 oldadv = phydev->advertising & 216 oldadv = phydev->advertising &
217 (ADVERTISED_Pause | ADVERTISED_Asym_Pause); 217 (ADVERTISED_Pause | ADVERTISED_Asym_Pause);
diff --git a/drivers/net/ethernet/freescale/fman/fman_dtsec.c b/drivers/net/ethernet/freescale/fman/fman_dtsec.c
index 7af31ddd093f..57b1e2b47c0a 100644
--- a/drivers/net/ethernet/freescale/fman/fman_dtsec.c
+++ b/drivers/net/ethernet/freescale/fman/fman_dtsec.c
@@ -1117,6 +1117,25 @@ int dtsec_add_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr)
1117 return 0; 1117 return 0;
1118} 1118}
1119 1119
1120int dtsec_set_allmulti(struct fman_mac *dtsec, bool enable)
1121{
1122 u32 tmp;
1123 struct dtsec_regs __iomem *regs = dtsec->regs;
1124
1125 if (!is_init_done(dtsec->dtsec_drv_param))
1126 return -EINVAL;
1127
1128 tmp = ioread32be(&regs->rctrl);
1129 if (enable)
1130 tmp |= RCTRL_MPROM;
1131 else
1132 tmp &= ~RCTRL_MPROM;
1133
1134 iowrite32be(tmp, &regs->rctrl);
1135
1136 return 0;
1137}
1138
1120int dtsec_del_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr) 1139int dtsec_del_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr)
1121{ 1140{
1122 struct dtsec_regs __iomem *regs = dtsec->regs; 1141 struct dtsec_regs __iomem *regs = dtsec->regs;
diff --git a/drivers/net/ethernet/freescale/fman/fman_dtsec.h b/drivers/net/ethernet/freescale/fman/fman_dtsec.h
index c4467c072058..1a689adf5a22 100644
--- a/drivers/net/ethernet/freescale/fman/fman_dtsec.h
+++ b/drivers/net/ethernet/freescale/fman/fman_dtsec.h
@@ -55,5 +55,6 @@ int dtsec_set_exception(struct fman_mac *dtsec,
55int dtsec_add_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr); 55int dtsec_add_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr);
56int dtsec_del_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr); 56int dtsec_del_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr);
57int dtsec_get_version(struct fman_mac *dtsec, u32 *mac_version); 57int dtsec_get_version(struct fman_mac *dtsec, u32 *mac_version);
58int dtsec_set_allmulti(struct fman_mac *dtsec, bool enable);
58 59
59#endif /* __DTSEC_H */ 60#endif /* __DTSEC_H */
diff --git a/drivers/net/ethernet/freescale/fman/fman_memac.c b/drivers/net/ethernet/freescale/fman/fman_memac.c
index c0296880feba..446a97b792e3 100644
--- a/drivers/net/ethernet/freescale/fman/fman_memac.c
+++ b/drivers/net/ethernet/freescale/fman/fman_memac.c
@@ -350,6 +350,7 @@ struct fman_mac {
350 struct fman_rev_info fm_rev_info; 350 struct fman_rev_info fm_rev_info;
351 bool basex_if; 351 bool basex_if;
352 struct phy_device *pcsphy; 352 struct phy_device *pcsphy;
353 bool allmulti_enabled;
353}; 354};
354 355
355static void add_addr_in_paddr(struct memac_regs __iomem *regs, u8 *adr, 356static void add_addr_in_paddr(struct memac_regs __iomem *regs, u8 *adr,
@@ -940,6 +941,29 @@ int memac_add_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr)
940 return 0; 941 return 0;
941} 942}
942 943
944int memac_set_allmulti(struct fman_mac *memac, bool enable)
945{
946 u32 entry;
947 struct memac_regs __iomem *regs = memac->regs;
948
949 if (!is_init_done(memac->memac_drv_param))
950 return -EINVAL;
951
952 if (enable) {
953 for (entry = 0; entry < HASH_TABLE_SIZE; entry++)
954 iowrite32be(entry | HASH_CTRL_MCAST_EN,
955 &regs->hashtable_ctrl);
956 } else {
957 for (entry = 0; entry < HASH_TABLE_SIZE; entry++)
958 iowrite32be(entry & ~HASH_CTRL_MCAST_EN,
959 &regs->hashtable_ctrl);
960 }
961
962 memac->allmulti_enabled = enable;
963
964 return 0;
965}
966
943int memac_del_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr) 967int memac_del_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr)
944{ 968{
945 struct memac_regs __iomem *regs = memac->regs; 969 struct memac_regs __iomem *regs = memac->regs;
@@ -963,8 +987,12 @@ int memac_del_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr)
963 break; 987 break;
964 } 988 }
965 } 989 }
966 if (list_empty(&memac->multicast_addr_hash->lsts[hash])) 990
967 iowrite32be(hash & ~HASH_CTRL_MCAST_EN, &regs->hashtable_ctrl); 991 if (!memac->allmulti_enabled) {
992 if (list_empty(&memac->multicast_addr_hash->lsts[hash]))
993 iowrite32be(hash & ~HASH_CTRL_MCAST_EN,
994 &regs->hashtable_ctrl);
995 }
968 996
969 return 0; 997 return 0;
970} 998}
diff --git a/drivers/net/ethernet/freescale/fman/fman_memac.h b/drivers/net/ethernet/freescale/fman/fman_memac.h
index c4a66469a907..b5a50338ed9a 100644
--- a/drivers/net/ethernet/freescale/fman/fman_memac.h
+++ b/drivers/net/ethernet/freescale/fman/fman_memac.h
@@ -57,5 +57,6 @@ int memac_set_exception(struct fman_mac *memac,
57 enum fman_mac_exceptions exception, bool enable); 57 enum fman_mac_exceptions exception, bool enable);
58int memac_add_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr); 58int memac_add_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr);
59int memac_del_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr); 59int memac_del_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr);
60int memac_set_allmulti(struct fman_mac *memac, bool enable);
60 61
61#endif /* __MEMAC_H */ 62#endif /* __MEMAC_H */
diff --git a/drivers/net/ethernet/freescale/fman/fman_tgec.c b/drivers/net/ethernet/freescale/fman/fman_tgec.c
index 4b0f3a50b293..284735d4ebe9 100644
--- a/drivers/net/ethernet/freescale/fman/fman_tgec.c
+++ b/drivers/net/ethernet/freescale/fman/fman_tgec.c
@@ -217,6 +217,7 @@ struct fman_mac {
217 struct tgec_cfg *cfg; 217 struct tgec_cfg *cfg;
218 void *fm; 218 void *fm;
219 struct fman_rev_info fm_rev_info; 219 struct fman_rev_info fm_rev_info;
220 bool allmulti_enabled;
220}; 221};
221 222
222static void set_mac_address(struct tgec_regs __iomem *regs, u8 *adr) 223static void set_mac_address(struct tgec_regs __iomem *regs, u8 *adr)
@@ -564,6 +565,29 @@ int tgec_add_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr)
564 return 0; 565 return 0;
565} 566}
566 567
568int tgec_set_allmulti(struct fman_mac *tgec, bool enable)
569{
570 u32 entry;
571 struct tgec_regs __iomem *regs = tgec->regs;
572
573 if (!is_init_done(tgec->cfg))
574 return -EINVAL;
575
576 if (enable) {
577 for (entry = 0; entry < TGEC_HASH_TABLE_SIZE; entry++)
578 iowrite32be(entry | TGEC_HASH_MCAST_EN,
579 &regs->hashtable_ctrl);
580 } else {
581 for (entry = 0; entry < TGEC_HASH_TABLE_SIZE; entry++)
582 iowrite32be(entry & ~TGEC_HASH_MCAST_EN,
583 &regs->hashtable_ctrl);
584 }
585
586 tgec->allmulti_enabled = enable;
587
588 return 0;
589}
590
567int tgec_del_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr) 591int tgec_del_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr)
568{ 592{
569 struct tgec_regs __iomem *regs = tgec->regs; 593 struct tgec_regs __iomem *regs = tgec->regs;
@@ -591,9 +615,12 @@ int tgec_del_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr)
591 break; 615 break;
592 } 616 }
593 } 617 }
594 if (list_empty(&tgec->multicast_addr_hash->lsts[hash])) 618
595 iowrite32be((hash & ~TGEC_HASH_MCAST_EN), 619 if (!tgec->allmulti_enabled) {
596 &regs->hashtable_ctrl); 620 if (list_empty(&tgec->multicast_addr_hash->lsts[hash]))
621 iowrite32be((hash & ~TGEC_HASH_MCAST_EN),
622 &regs->hashtable_ctrl);
623 }
597 624
598 return 0; 625 return 0;
599} 626}
diff --git a/drivers/net/ethernet/freescale/fman/fman_tgec.h b/drivers/net/ethernet/freescale/fman/fman_tgec.h
index 514bba9f47ce..cbbd3b422a98 100644
--- a/drivers/net/ethernet/freescale/fman/fman_tgec.h
+++ b/drivers/net/ethernet/freescale/fman/fman_tgec.h
@@ -51,5 +51,6 @@ int tgec_set_exception(struct fman_mac *tgec,
51int tgec_add_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr); 51int tgec_add_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr);
52int tgec_del_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr); 52int tgec_del_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr);
53int tgec_get_version(struct fman_mac *tgec, u32 *mac_version); 53int tgec_get_version(struct fman_mac *tgec, u32 *mac_version);
54int tgec_set_allmulti(struct fman_mac *tgec, bool enable);
54 55
55#endif /* __TGEC_H */ 56#endif /* __TGEC_H */
diff --git a/drivers/net/ethernet/freescale/fman/mac.c b/drivers/net/ethernet/freescale/fman/mac.c
index 88c0a0636b44..4829dcd9e077 100644
--- a/drivers/net/ethernet/freescale/fman/mac.c
+++ b/drivers/net/ethernet/freescale/fman/mac.c
@@ -470,6 +470,7 @@ static void setup_dtsec(struct mac_device *mac_dev)
470 mac_dev->set_tx_pause = dtsec_set_tx_pause_frames; 470 mac_dev->set_tx_pause = dtsec_set_tx_pause_frames;
471 mac_dev->set_rx_pause = dtsec_accept_rx_pause_frames; 471 mac_dev->set_rx_pause = dtsec_accept_rx_pause_frames;
472 mac_dev->set_exception = dtsec_set_exception; 472 mac_dev->set_exception = dtsec_set_exception;
473 mac_dev->set_allmulti = dtsec_set_allmulti;
473 mac_dev->set_multi = set_multi; 474 mac_dev->set_multi = set_multi;
474 mac_dev->start = start; 475 mac_dev->start = start;
475 mac_dev->stop = stop; 476 mac_dev->stop = stop;
@@ -488,6 +489,7 @@ static void setup_tgec(struct mac_device *mac_dev)
488 mac_dev->set_tx_pause = tgec_set_tx_pause_frames; 489 mac_dev->set_tx_pause = tgec_set_tx_pause_frames;
489 mac_dev->set_rx_pause = tgec_accept_rx_pause_frames; 490 mac_dev->set_rx_pause = tgec_accept_rx_pause_frames;
490 mac_dev->set_exception = tgec_set_exception; 491 mac_dev->set_exception = tgec_set_exception;
492 mac_dev->set_allmulti = tgec_set_allmulti;
491 mac_dev->set_multi = set_multi; 493 mac_dev->set_multi = set_multi;
492 mac_dev->start = start; 494 mac_dev->start = start;
493 mac_dev->stop = stop; 495 mac_dev->stop = stop;
@@ -506,6 +508,7 @@ static void setup_memac(struct mac_device *mac_dev)
506 mac_dev->set_tx_pause = memac_set_tx_pause_frames; 508 mac_dev->set_tx_pause = memac_set_tx_pause_frames;
507 mac_dev->set_rx_pause = memac_accept_rx_pause_frames; 509 mac_dev->set_rx_pause = memac_accept_rx_pause_frames;
508 mac_dev->set_exception = memac_set_exception; 510 mac_dev->set_exception = memac_set_exception;
511 mac_dev->set_allmulti = memac_set_allmulti;
509 mac_dev->set_multi = set_multi; 512 mac_dev->set_multi = set_multi;
510 mac_dev->start = start; 513 mac_dev->start = start;
511 mac_dev->stop = stop; 514 mac_dev->stop = stop;
diff --git a/drivers/net/ethernet/freescale/fman/mac.h b/drivers/net/ethernet/freescale/fman/mac.h
index eefb3357e304..b520cec120ee 100644
--- a/drivers/net/ethernet/freescale/fman/mac.h
+++ b/drivers/net/ethernet/freescale/fman/mac.h
@@ -59,6 +59,7 @@ struct mac_device {
59 bool rx_pause_active; 59 bool rx_pause_active;
60 bool tx_pause_active; 60 bool tx_pause_active;
61 bool promisc; 61 bool promisc;
62 bool allmulti;
62 63
63 int (*init)(struct mac_device *mac_dev); 64 int (*init)(struct mac_device *mac_dev);
64 int (*start)(struct mac_device *mac_dev); 65 int (*start)(struct mac_device *mac_dev);
@@ -66,6 +67,7 @@ struct mac_device {
66 void (*adjust_link)(struct mac_device *mac_dev); 67 void (*adjust_link)(struct mac_device *mac_dev);
67 int (*set_promisc)(struct fman_mac *mac_dev, bool enable); 68 int (*set_promisc)(struct fman_mac *mac_dev, bool enable);
68 int (*change_addr)(struct fman_mac *mac_dev, enet_addr_t *enet_addr); 69 int (*change_addr)(struct fman_mac *mac_dev, enet_addr_t *enet_addr);
70 int (*set_allmulti)(struct fman_mac *mac_dev, bool enable);
69 int (*set_multi)(struct net_device *net_dev, 71 int (*set_multi)(struct net_device *net_dev,
70 struct mac_device *mac_dev); 72 struct mac_device *mac_dev);
71 int (*set_rx_pause)(struct fman_mac *mac_dev, bool en); 73 int (*set_rx_pause)(struct fman_mac *mac_dev, bool en);
diff --git a/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h b/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h
index 3e9203ea42a6..519e2bd6aa60 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h
@@ -11,6 +11,7 @@
11 11
12enum HCLGE_MBX_OPCODE { 12enum HCLGE_MBX_OPCODE {
13 HCLGE_MBX_RESET = 0x01, /* (VF -> PF) assert reset */ 13 HCLGE_MBX_RESET = 0x01, /* (VF -> PF) assert reset */
14 HCLGE_MBX_ASSERTING_RESET, /* (PF -> VF) PF is asserting reset*/
14 HCLGE_MBX_SET_UNICAST, /* (VF -> PF) set UC addr */ 15 HCLGE_MBX_SET_UNICAST, /* (VF -> PF) set UC addr */
15 HCLGE_MBX_SET_MULTICAST, /* (VF -> PF) set MC addr */ 16 HCLGE_MBX_SET_MULTICAST, /* (VF -> PF) set MC addr */
16 HCLGE_MBX_SET_VLAN, /* (VF -> PF) set VLAN */ 17 HCLGE_MBX_SET_VLAN, /* (VF -> PF) set VLAN */
@@ -57,6 +58,8 @@ enum hclge_mbx_vlan_cfg_subcode {
57 58
58#define HCLGE_MBX_MAX_MSG_SIZE 16 59#define HCLGE_MBX_MAX_MSG_SIZE 16
59#define HCLGE_MBX_MAX_RESP_DATA_SIZE 8 60#define HCLGE_MBX_MAX_RESP_DATA_SIZE 8
61#define HCLGE_MBX_RING_MAP_BASIC_MSG_NUM 3
62#define HCLGE_MBX_RING_NODE_VARIABLE_NUM 3
60 63
61struct hclgevf_mbx_resp_status { 64struct hclgevf_mbx_resp_status {
62 struct mutex mbx_mutex; /* protects against contending sync cmd resp */ 65 struct mutex mbx_mutex; /* protects against contending sync cmd resp */
@@ -83,6 +86,21 @@ struct hclge_mbx_pf_to_vf_cmd {
83 u16 msg[8]; 86 u16 msg[8];
84}; 87};
85 88
89/* used by VF to store the received Async responses from PF */
90struct hclgevf_mbx_arq_ring {
91#define HCLGE_MBX_MAX_ARQ_MSG_SIZE 8
92#define HCLGE_MBX_MAX_ARQ_MSG_NUM 1024
93 struct hclgevf_dev *hdev;
94 u32 head;
95 u32 tail;
96 u32 count;
97 u16 msg_q[HCLGE_MBX_MAX_ARQ_MSG_NUM][HCLGE_MBX_MAX_ARQ_MSG_SIZE];
98};
99
86#define hclge_mbx_ring_ptr_move_crq(crq) \ 100#define hclge_mbx_ring_ptr_move_crq(crq) \
87 (crq->next_to_use = (crq->next_to_use + 1) % crq->desc_num) 101 (crq->next_to_use = (crq->next_to_use + 1) % crq->desc_num)
102#define hclge_mbx_tail_ptr_move_arq(arq) \
103 (arq.tail = (arq.tail + 1) % HCLGE_MBX_MAX_ARQ_MSG_SIZE)
104#define hclge_mbx_head_ptr_move_arq(arq) \
105 (arq.head = (arq.head + 1) % HCLGE_MBX_MAX_ARQ_MSG_SIZE)
88#endif 106#endif
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index fd06bc78c58e..37ec1b3286c6 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -118,6 +118,8 @@ enum hnae3_reset_notify_type {
118}; 118};
119 119
120enum hnae3_reset_type { 120enum hnae3_reset_type {
121 HNAE3_VF_RESET,
122 HNAE3_VF_FULL_RESET,
121 HNAE3_FUNC_RESET, 123 HNAE3_FUNC_RESET,
122 HNAE3_CORE_RESET, 124 HNAE3_CORE_RESET,
123 HNAE3_GLOBAL_RESET, 125 HNAE3_GLOBAL_RESET,
@@ -265,6 +267,8 @@ struct hnae3_ae_dev {
265 * Get tc size of handle 267 * Get tc size of handle
266 * get_vector() 268 * get_vector()
267 * Get vector number and vector information 269 * Get vector number and vector information
270 * put_vector()
271 * Put the vector in hdev
268 * map_ring_to_vector() 272 * map_ring_to_vector()
269 * Map rings to vector 273 * Map rings to vector
270 * unmap_ring_from_vector() 274 * unmap_ring_from_vector()
@@ -336,7 +340,8 @@ struct hnae3_ae_ops {
336 u32 *tx_usecs_high, u32 *rx_usecs_high); 340 u32 *tx_usecs_high, u32 *rx_usecs_high);
337 341
338 void (*get_mac_addr)(struct hnae3_handle *handle, u8 *p); 342 void (*get_mac_addr)(struct hnae3_handle *handle, u8 *p);
339 int (*set_mac_addr)(struct hnae3_handle *handle, void *p); 343 int (*set_mac_addr)(struct hnae3_handle *handle, void *p,
344 bool is_first);
340 int (*add_uc_addr)(struct hnae3_handle *handle, 345 int (*add_uc_addr)(struct hnae3_handle *handle,
341 const unsigned char *addr); 346 const unsigned char *addr);
342 int (*rm_uc_addr)(struct hnae3_handle *handle, 347 int (*rm_uc_addr)(struct hnae3_handle *handle,
@@ -375,6 +380,7 @@ struct hnae3_ae_ops {
375 380
376 int (*get_vector)(struct hnae3_handle *handle, u16 vector_num, 381 int (*get_vector)(struct hnae3_handle *handle, u16 vector_num,
377 struct hnae3_vector_info *vector_info); 382 struct hnae3_vector_info *vector_info);
383 int (*put_vector)(struct hnae3_handle *handle, int vector_num);
378 int (*map_ring_to_vector)(struct hnae3_handle *handle, 384 int (*map_ring_to_vector)(struct hnae3_handle *handle,
379 int vector_num, 385 int vector_num,
380 struct hnae3_ring_chain_node *vr_chain); 386 struct hnae3_ring_chain_node *vr_chain);
@@ -396,8 +402,7 @@ struct hnae3_ae_ops {
396 int (*set_vf_vlan_filter)(struct hnae3_handle *handle, int vfid, 402 int (*set_vf_vlan_filter)(struct hnae3_handle *handle, int vfid,
397 u16 vlan, u8 qos, __be16 proto); 403 u16 vlan, u8 qos, __be16 proto);
398 int (*enable_hw_strip_rxvtag)(struct hnae3_handle *handle, bool enable); 404 int (*enable_hw_strip_rxvtag)(struct hnae3_handle *handle, bool enable);
399 void (*reset_event)(struct hnae3_handle *handle, 405 void (*reset_event)(struct hnae3_handle *handle);
400 enum hnae3_reset_type reset);
401 void (*get_channels)(struct hnae3_handle *handle, 406 void (*get_channels)(struct hnae3_handle *handle,
402 struct ethtool_channels *ch); 407 struct ethtool_channels *ch);
403 void (*get_tqps_and_rss_info)(struct hnae3_handle *h, 408 void (*get_tqps_and_rss_info)(struct hnae3_handle *h,
@@ -407,6 +412,10 @@ struct hnae3_ae_ops {
407 u32 *flowctrl_adv); 412 u32 *flowctrl_adv);
408 int (*set_led_id)(struct hnae3_handle *handle, 413 int (*set_led_id)(struct hnae3_handle *handle,
409 enum ethtool_phys_id_state status); 414 enum ethtool_phys_id_state status);
415 void (*get_link_mode)(struct hnae3_handle *handle,
416 unsigned long *supported,
417 unsigned long *advertising);
418 void (*get_port_type)(struct hnae3_handle *handle, u8 *port_type);
410}; 419};
411 420
412struct hnae3_dcb_ops { 421struct hnae3_dcb_ops {
@@ -487,6 +496,9 @@ struct hnae3_handle {
487 struct hnae3_ae_algo *ae_algo; /* the class who provides this handle */ 496 struct hnae3_ae_algo *ae_algo; /* the class who provides this handle */
488 u64 flags; /* Indicate the capabilities for this handle*/ 497 u64 flags; /* Indicate the capabilities for this handle*/
489 498
499 unsigned long last_reset_time;
500 enum hnae3_reset_type reset_level;
501
490 union { 502 union {
491 struct net_device *netdev; /* first member */ 503 struct net_device *netdev; /* first member */
492 struct hnae3_knic_private_info kinfo; 504 struct hnae3_knic_private_info kinfo;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 601b6295d3f8..40a3eb70629e 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -168,8 +168,8 @@ void hns3_set_vector_coalesce_rl(struct hns3_enet_tqp_vector *tqp_vector,
168 * GL and RL(Rate Limiter) are 2 ways to acheive interrupt coalescing 168 * GL and RL(Rate Limiter) are 2 ways to acheive interrupt coalescing
169 */ 169 */
170 170
171 if (rl_reg > 0 && !tqp_vector->tx_group.gl_adapt_enable && 171 if (rl_reg > 0 && !tqp_vector->tx_group.coal.gl_adapt_enable &&
172 !tqp_vector->rx_group.gl_adapt_enable) 172 !tqp_vector->rx_group.coal.gl_adapt_enable)
173 /* According to the hardware, the range of rl_reg is 173 /* According to the hardware, the range of rl_reg is
174 * 0-59 and the unit is 4. 174 * 0-59 and the unit is 4.
175 */ 175 */
@@ -205,23 +205,30 @@ static void hns3_vector_gl_rl_init(struct hns3_enet_tqp_vector *tqp_vector,
205 */ 205 */
206 206
207 /* Default: enable interrupt coalescing self-adaptive and GL */ 207 /* Default: enable interrupt coalescing self-adaptive and GL */
208 tqp_vector->tx_group.gl_adapt_enable = 1; 208 tqp_vector->tx_group.coal.gl_adapt_enable = 1;
209 tqp_vector->rx_group.gl_adapt_enable = 1; 209 tqp_vector->rx_group.coal.gl_adapt_enable = 1;
210 210
211 tqp_vector->tx_group.int_gl = HNS3_INT_GL_50K; 211 tqp_vector->tx_group.coal.int_gl = HNS3_INT_GL_50K;
212 tqp_vector->rx_group.int_gl = HNS3_INT_GL_50K; 212 tqp_vector->rx_group.coal.int_gl = HNS3_INT_GL_50K;
213
214 hns3_set_vector_coalesce_tx_gl(tqp_vector,
215 tqp_vector->tx_group.int_gl);
216 hns3_set_vector_coalesce_rx_gl(tqp_vector,
217 tqp_vector->rx_group.int_gl);
218 213
219 /* Default: disable RL */ 214 /* Default: disable RL */
220 h->kinfo.int_rl_setting = 0; 215 h->kinfo.int_rl_setting = 0;
221 hns3_set_vector_coalesce_rl(tqp_vector, h->kinfo.int_rl_setting);
222 216
223 tqp_vector->rx_group.flow_level = HNS3_FLOW_LOW; 217 tqp_vector->int_adapt_down = HNS3_INT_ADAPT_DOWN_START;
224 tqp_vector->tx_group.flow_level = HNS3_FLOW_LOW; 218 tqp_vector->rx_group.coal.flow_level = HNS3_FLOW_LOW;
219 tqp_vector->tx_group.coal.flow_level = HNS3_FLOW_LOW;
220}
221
222static void hns3_vector_gl_rl_init_hw(struct hns3_enet_tqp_vector *tqp_vector,
223 struct hns3_nic_priv *priv)
224{
225 struct hnae3_handle *h = priv->ae_handle;
226
227 hns3_set_vector_coalesce_tx_gl(tqp_vector,
228 tqp_vector->tx_group.coal.int_gl);
229 hns3_set_vector_coalesce_rx_gl(tqp_vector,
230 tqp_vector->rx_group.coal.int_gl);
231 hns3_set_vector_coalesce_rl(tqp_vector, h->kinfo.int_rl_setting);
225} 232}
226 233
227static int hns3_nic_set_real_num_queue(struct net_device *netdev) 234static int hns3_nic_set_real_num_queue(struct net_device *netdev)
@@ -249,6 +256,16 @@ static int hns3_nic_set_real_num_queue(struct net_device *netdev)
249 return 0; 256 return 0;
250} 257}
251 258
259static u16 hns3_get_max_available_channels(struct hnae3_handle *h)
260{
261 u16 free_tqps, max_rss_size, max_tqps;
262
263 h->ae_algo->ops->get_tqps_and_rss_info(h, &free_tqps, &max_rss_size);
264 max_tqps = h->kinfo.num_tc * max_rss_size;
265
266 return min_t(u16, max_tqps, (free_tqps + h->kinfo.num_tqps));
267}
268
252static int hns3_nic_net_up(struct net_device *netdev) 269static int hns3_nic_net_up(struct net_device *netdev)
253{ 270{
254 struct hns3_nic_priv *priv = netdev_priv(netdev); 271 struct hns3_nic_priv *priv = netdev_priv(netdev);
@@ -303,7 +320,7 @@ static int hns3_nic_net_open(struct net_device *netdev)
303 return ret; 320 return ret;
304 } 321 }
305 322
306 priv->last_reset_time = jiffies; 323 priv->ae_handle->last_reset_time = jiffies;
307 return 0; 324 return 0;
308} 325}
309 326
@@ -1104,7 +1121,7 @@ static int hns3_nic_net_set_mac_address(struct net_device *netdev, void *p)
1104 if (!mac_addr || !is_valid_ether_addr((const u8 *)mac_addr->sa_data)) 1121 if (!mac_addr || !is_valid_ether_addr((const u8 *)mac_addr->sa_data))
1105 return -EADDRNOTAVAIL; 1122 return -EADDRNOTAVAIL;
1106 1123
1107 ret = h->ae_algo->ops->set_mac_addr(h, mac_addr->sa_data); 1124 ret = h->ae_algo->ops->set_mac_addr(h, mac_addr->sa_data, false);
1108 if (ret) { 1125 if (ret) {
1109 netdev_err(netdev, "set_mac_address fail, ret=%d!\n", ret); 1126 netdev_err(netdev, "set_mac_address fail, ret=%d!\n", ret);
1110 return ret; 1127 return ret;
@@ -1388,11 +1405,15 @@ static int hns3_vlan_rx_add_vid(struct net_device *netdev,
1388 __be16 proto, u16 vid) 1405 __be16 proto, u16 vid)
1389{ 1406{
1390 struct hnae3_handle *h = hns3_get_handle(netdev); 1407 struct hnae3_handle *h = hns3_get_handle(netdev);
1408 struct hns3_nic_priv *priv = netdev_priv(netdev);
1391 int ret = -EIO; 1409 int ret = -EIO;
1392 1410
1393 if (h->ae_algo->ops->set_vlan_filter) 1411 if (h->ae_algo->ops->set_vlan_filter)
1394 ret = h->ae_algo->ops->set_vlan_filter(h, proto, vid, false); 1412 ret = h->ae_algo->ops->set_vlan_filter(h, proto, vid, false);
1395 1413
1414 if (!ret)
1415 set_bit(vid, priv->active_vlans);
1416
1396 return ret; 1417 return ret;
1397} 1418}
1398 1419
@@ -1400,14 +1421,32 @@ static int hns3_vlan_rx_kill_vid(struct net_device *netdev,
1400 __be16 proto, u16 vid) 1421 __be16 proto, u16 vid)
1401{ 1422{
1402 struct hnae3_handle *h = hns3_get_handle(netdev); 1423 struct hnae3_handle *h = hns3_get_handle(netdev);
1424 struct hns3_nic_priv *priv = netdev_priv(netdev);
1403 int ret = -EIO; 1425 int ret = -EIO;
1404 1426
1405 if (h->ae_algo->ops->set_vlan_filter) 1427 if (h->ae_algo->ops->set_vlan_filter)
1406 ret = h->ae_algo->ops->set_vlan_filter(h, proto, vid, true); 1428 ret = h->ae_algo->ops->set_vlan_filter(h, proto, vid, true);
1407 1429
1430 if (!ret)
1431 clear_bit(vid, priv->active_vlans);
1432
1408 return ret; 1433 return ret;
1409} 1434}
1410 1435
1436static void hns3_restore_vlan(struct net_device *netdev)
1437{
1438 struct hns3_nic_priv *priv = netdev_priv(netdev);
1439 u16 vid;
1440 int ret;
1441
1442 for_each_set_bit(vid, priv->active_vlans, VLAN_N_VID) {
1443 ret = hns3_vlan_rx_add_vid(netdev, htons(ETH_P_8021Q), vid);
1444 if (ret)
1445 netdev_warn(netdev, "Restore vlan: %d filter, ret:%d\n",
1446 vid, ret);
1447 }
1448}
1449
1411static int hns3_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, 1450static int hns3_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan,
1412 u8 qos, __be16 vlan_proto) 1451 u8 qos, __be16 vlan_proto)
1413{ 1452{
@@ -1504,7 +1543,6 @@ static bool hns3_get_tx_timeo_queue_info(struct net_device *ndev)
1504static void hns3_nic_net_timeout(struct net_device *ndev) 1543static void hns3_nic_net_timeout(struct net_device *ndev)
1505{ 1544{
1506 struct hns3_nic_priv *priv = netdev_priv(ndev); 1545 struct hns3_nic_priv *priv = netdev_priv(ndev);
1507 unsigned long last_reset_time = priv->last_reset_time;
1508 struct hnae3_handle *h = priv->ae_handle; 1546 struct hnae3_handle *h = priv->ae_handle;
1509 1547
1510 if (!hns3_get_tx_timeo_queue_info(ndev)) 1548 if (!hns3_get_tx_timeo_queue_info(ndev))
@@ -1512,24 +1550,12 @@ static void hns3_nic_net_timeout(struct net_device *ndev)
1512 1550
1513 priv->tx_timeout_count++; 1551 priv->tx_timeout_count++;
1514 1552
1515 /* This timeout is far away enough from last timeout, 1553 if (time_before(jiffies, (h->last_reset_time + ndev->watchdog_timeo)))
1516 * if timeout again,set the reset type to PF reset
1517 */
1518 if (time_after(jiffies, (last_reset_time + 20 * HZ)))
1519 priv->reset_level = HNAE3_FUNC_RESET;
1520
1521 /* Don't do any new action before the next timeout */
1522 else if (time_before(jiffies, (last_reset_time + ndev->watchdog_timeo)))
1523 return; 1554 return;
1524 1555
1525 priv->last_reset_time = jiffies; 1556 /* request the reset */
1526
1527 if (h->ae_algo->ops->reset_event) 1557 if (h->ae_algo->ops->reset_event)
1528 h->ae_algo->ops->reset_event(h, priv->reset_level); 1558 h->ae_algo->ops->reset_event(h);
1529
1530 priv->reset_level++;
1531 if (priv->reset_level > HNAE3_GLOBAL_RESET)
1532 priv->reset_level = HNAE3_GLOBAL_RESET;
1533} 1559}
1534 1560
1535static const struct net_device_ops hns3_nic_netdev_ops = { 1561static const struct net_device_ops hns3_nic_netdev_ops = {
@@ -2064,15 +2090,13 @@ static void hns3_nic_reuse_page(struct sk_buff *skb, int i,
2064 desc = &ring->desc[ring->next_to_clean]; 2090 desc = &ring->desc[ring->next_to_clean];
2065 size = le16_to_cpu(desc->rx.size); 2091 size = le16_to_cpu(desc->rx.size);
2066 2092
2067 if (twobufs) { 2093 truesize = hnae_buf_size(ring);
2068 truesize = hnae_buf_size(ring); 2094
2069 } else { 2095 if (!twobufs)
2070 truesize = ALIGN(size, L1_CACHE_BYTES);
2071 last_offset = hnae_page_size(ring) - hnae_buf_size(ring); 2096 last_offset = hnae_page_size(ring) - hnae_buf_size(ring);
2072 }
2073 2097
2074 skb_add_rx_frag(skb, i, desc_cb->priv, desc_cb->page_offset + pull_len, 2098 skb_add_rx_frag(skb, i, desc_cb->priv, desc_cb->page_offset + pull_len,
2075 size - pull_len, truesize - pull_len); 2099 size - pull_len, truesize);
2076 2100
2077 /* Avoid re-using remote pages,flag default unreuse */ 2101 /* Avoid re-using remote pages,flag default unreuse */
2078 if (unlikely(page_to_nid(desc_cb->priv) != numa_node_id())) 2102 if (unlikely(page_to_nid(desc_cb->priv) != numa_node_id()))
@@ -2369,20 +2393,20 @@ out:
2369 2393
2370static bool hns3_get_new_int_gl(struct hns3_enet_ring_group *ring_group) 2394static bool hns3_get_new_int_gl(struct hns3_enet_ring_group *ring_group)
2371{ 2395{
2372#define HNS3_RX_ULTRA_PACKET_RATE 40000 2396 struct hns3_enet_tqp_vector *tqp_vector =
2397 ring_group->ring->tqp_vector;
2373 enum hns3_flow_level_range new_flow_level; 2398 enum hns3_flow_level_range new_flow_level;
2374 struct hns3_enet_tqp_vector *tqp_vector; 2399 int packets_per_msecs;
2375 int packets_per_secs; 2400 int bytes_per_msecs;
2376 int bytes_per_usecs; 2401 u32 time_passed_ms;
2377 u16 new_int_gl; 2402 u16 new_int_gl;
2378 int usecs;
2379 2403
2380 if (!ring_group->int_gl) 2404 if (!ring_group->coal.int_gl || !tqp_vector->last_jiffies)
2381 return false; 2405 return false;
2382 2406
2383 if (ring_group->total_packets == 0) { 2407 if (ring_group->total_packets == 0) {
2384 ring_group->int_gl = HNS3_INT_GL_50K; 2408 ring_group->coal.int_gl = HNS3_INT_GL_50K;
2385 ring_group->flow_level = HNS3_FLOW_LOW; 2409 ring_group->coal.flow_level = HNS3_FLOW_LOW;
2386 return true; 2410 return true;
2387 } 2411 }
2388 2412
@@ -2392,35 +2416,46 @@ static bool hns3_get_new_int_gl(struct hns3_enet_ring_group *ring_group)
2392 * 20-1249MB/s high (18000 ints/s) 2416 * 20-1249MB/s high (18000 ints/s)
2393 * > 40000pps ultra (8000 ints/s) 2417 * > 40000pps ultra (8000 ints/s)
2394 */ 2418 */
2395 new_flow_level = ring_group->flow_level; 2419 new_flow_level = ring_group->coal.flow_level;
2396 new_int_gl = ring_group->int_gl; 2420 new_int_gl = ring_group->coal.int_gl;
2397 tqp_vector = ring_group->ring->tqp_vector; 2421 time_passed_ms =
2398 usecs = (ring_group->int_gl << 1); 2422 jiffies_to_msecs(jiffies - tqp_vector->last_jiffies);
2399 bytes_per_usecs = ring_group->total_bytes / usecs; 2423
2400 /* 1000000 microseconds */ 2424 if (!time_passed_ms)
2401 packets_per_secs = ring_group->total_packets * 1000000 / usecs; 2425 return false;
2426
2427 do_div(ring_group->total_packets, time_passed_ms);
2428 packets_per_msecs = ring_group->total_packets;
2429
2430 do_div(ring_group->total_bytes, time_passed_ms);
2431 bytes_per_msecs = ring_group->total_bytes;
2432
2433#define HNS3_RX_LOW_BYTE_RATE 10000
2434#define HNS3_RX_MID_BYTE_RATE 20000
2402 2435
2403 switch (new_flow_level) { 2436 switch (new_flow_level) {
2404 case HNS3_FLOW_LOW: 2437 case HNS3_FLOW_LOW:
2405 if (bytes_per_usecs > 10) 2438 if (bytes_per_msecs > HNS3_RX_LOW_BYTE_RATE)
2406 new_flow_level = HNS3_FLOW_MID; 2439 new_flow_level = HNS3_FLOW_MID;
2407 break; 2440 break;
2408 case HNS3_FLOW_MID: 2441 case HNS3_FLOW_MID:
2409 if (bytes_per_usecs > 20) 2442 if (bytes_per_msecs > HNS3_RX_MID_BYTE_RATE)
2410 new_flow_level = HNS3_FLOW_HIGH; 2443 new_flow_level = HNS3_FLOW_HIGH;
2411 else if (bytes_per_usecs <= 10) 2444 else if (bytes_per_msecs <= HNS3_RX_LOW_BYTE_RATE)
2412 new_flow_level = HNS3_FLOW_LOW; 2445 new_flow_level = HNS3_FLOW_LOW;
2413 break; 2446 break;
2414 case HNS3_FLOW_HIGH: 2447 case HNS3_FLOW_HIGH:
2415 case HNS3_FLOW_ULTRA: 2448 case HNS3_FLOW_ULTRA:
2416 default: 2449 default:
2417 if (bytes_per_usecs <= 20) 2450 if (bytes_per_msecs <= HNS3_RX_MID_BYTE_RATE)
2418 new_flow_level = HNS3_FLOW_MID; 2451 new_flow_level = HNS3_FLOW_MID;
2419 break; 2452 break;
2420 } 2453 }
2421 2454
2422 if ((packets_per_secs > HNS3_RX_ULTRA_PACKET_RATE) && 2455#define HNS3_RX_ULTRA_PACKET_RATE 40
2423 (&tqp_vector->rx_group == ring_group)) 2456
2457 if (packets_per_msecs > HNS3_RX_ULTRA_PACKET_RATE &&
2458 &tqp_vector->rx_group == ring_group)
2424 new_flow_level = HNS3_FLOW_ULTRA; 2459 new_flow_level = HNS3_FLOW_ULTRA;
2425 2460
2426 switch (new_flow_level) { 2461 switch (new_flow_level) {
@@ -2442,9 +2477,9 @@ static bool hns3_get_new_int_gl(struct hns3_enet_ring_group *ring_group)
2442 2477
2443 ring_group->total_bytes = 0; 2478 ring_group->total_bytes = 0;
2444 ring_group->total_packets = 0; 2479 ring_group->total_packets = 0;
2445 ring_group->flow_level = new_flow_level; 2480 ring_group->coal.flow_level = new_flow_level;
2446 if (new_int_gl != ring_group->int_gl) { 2481 if (new_int_gl != ring_group->coal.int_gl) {
2447 ring_group->int_gl = new_int_gl; 2482 ring_group->coal.int_gl = new_int_gl;
2448 return true; 2483 return true;
2449 } 2484 }
2450 return false; 2485 return false;
@@ -2456,19 +2491,27 @@ static void hns3_update_new_int_gl(struct hns3_enet_tqp_vector *tqp_vector)
2456 struct hns3_enet_ring_group *tx_group = &tqp_vector->tx_group; 2491 struct hns3_enet_ring_group *tx_group = &tqp_vector->tx_group;
2457 bool rx_update, tx_update; 2492 bool rx_update, tx_update;
2458 2493
2459 if (rx_group->gl_adapt_enable) { 2494 if (tqp_vector->int_adapt_down > 0) {
2495 tqp_vector->int_adapt_down--;
2496 return;
2497 }
2498
2499 if (rx_group->coal.gl_adapt_enable) {
2460 rx_update = hns3_get_new_int_gl(rx_group); 2500 rx_update = hns3_get_new_int_gl(rx_group);
2461 if (rx_update) 2501 if (rx_update)
2462 hns3_set_vector_coalesce_rx_gl(tqp_vector, 2502 hns3_set_vector_coalesce_rx_gl(tqp_vector,
2463 rx_group->int_gl); 2503 rx_group->coal.int_gl);
2464 } 2504 }
2465 2505
2466 if (tx_group->gl_adapt_enable) { 2506 if (tx_group->coal.gl_adapt_enable) {
2467 tx_update = hns3_get_new_int_gl(&tqp_vector->tx_group); 2507 tx_update = hns3_get_new_int_gl(&tqp_vector->tx_group);
2468 if (tx_update) 2508 if (tx_update)
2469 hns3_set_vector_coalesce_tx_gl(tqp_vector, 2509 hns3_set_vector_coalesce_tx_gl(tqp_vector,
2470 tx_group->int_gl); 2510 tx_group->coal.int_gl);
2471 } 2511 }
2512
2513 tqp_vector->last_jiffies = jiffies;
2514 tqp_vector->int_adapt_down = HNS3_INT_ADAPT_DOWN_START;
2472} 2515}
2473 2516
2474static int hns3_nic_common_poll(struct napi_struct *napi, int budget) 2517static int hns3_nic_common_poll(struct napi_struct *napi, int budget)
@@ -2615,32 +2658,18 @@ static int hns3_nic_init_vector_data(struct hns3_nic_priv *priv)
2615 struct hnae3_ring_chain_node vector_ring_chain; 2658 struct hnae3_ring_chain_node vector_ring_chain;
2616 struct hnae3_handle *h = priv->ae_handle; 2659 struct hnae3_handle *h = priv->ae_handle;
2617 struct hns3_enet_tqp_vector *tqp_vector; 2660 struct hns3_enet_tqp_vector *tqp_vector;
2618 struct hnae3_vector_info *vector;
2619 struct pci_dev *pdev = h->pdev;
2620 u16 tqp_num = h->kinfo.num_tqps;
2621 u16 vector_num;
2622 int ret = 0; 2661 int ret = 0;
2623 u16 i; 2662 u16 i;
2624 2663
2625 /* RSS size, cpu online and vector_num should be the same */ 2664 for (i = 0; i < priv->vector_num; i++) {
2626 /* Should consider 2p/4p later */ 2665 tqp_vector = &priv->tqp_vector[i];
2627 vector_num = min_t(u16, num_online_cpus(), tqp_num); 2666 hns3_vector_gl_rl_init_hw(tqp_vector, priv);
2628 vector = devm_kcalloc(&pdev->dev, vector_num, sizeof(*vector), 2667 tqp_vector->num_tqps = 0;
2629 GFP_KERNEL); 2668 }
2630 if (!vector)
2631 return -ENOMEM;
2632
2633 vector_num = h->ae_algo->ops->get_vector(h, vector_num, vector);
2634
2635 priv->vector_num = vector_num;
2636 priv->tqp_vector = (struct hns3_enet_tqp_vector *)
2637 devm_kcalloc(&pdev->dev, vector_num, sizeof(*priv->tqp_vector),
2638 GFP_KERNEL);
2639 if (!priv->tqp_vector)
2640 return -ENOMEM;
2641 2669
2642 for (i = 0; i < tqp_num; i++) { 2670 for (i = 0; i < h->kinfo.num_tqps; i++) {
2643 u16 vector_i = i % vector_num; 2671 u16 vector_i = i % priv->vector_num;
2672 u16 tqp_num = h->kinfo.num_tqps;
2644 2673
2645 tqp_vector = &priv->tqp_vector[vector_i]; 2674 tqp_vector = &priv->tqp_vector[vector_i];
2646 2675
@@ -2650,52 +2679,94 @@ static int hns3_nic_init_vector_data(struct hns3_nic_priv *priv)
2650 hns3_add_ring_to_group(&tqp_vector->rx_group, 2679 hns3_add_ring_to_group(&tqp_vector->rx_group,
2651 priv->ring_data[i + tqp_num].ring); 2680 priv->ring_data[i + tqp_num].ring);
2652 2681
2653 tqp_vector->idx = vector_i;
2654 tqp_vector->mask_addr = vector[vector_i].io_addr;
2655 tqp_vector->vector_irq = vector[vector_i].vector;
2656 tqp_vector->num_tqps++;
2657
2658 priv->ring_data[i].ring->tqp_vector = tqp_vector; 2682 priv->ring_data[i].ring->tqp_vector = tqp_vector;
2659 priv->ring_data[i + tqp_num].ring->tqp_vector = tqp_vector; 2683 priv->ring_data[i + tqp_num].ring->tqp_vector = tqp_vector;
2684 tqp_vector->num_tqps++;
2660 } 2685 }
2661 2686
2662 for (i = 0; i < vector_num; i++) { 2687 for (i = 0; i < priv->vector_num; i++) {
2663 tqp_vector = &priv->tqp_vector[i]; 2688 tqp_vector = &priv->tqp_vector[i];
2664 2689
2665 tqp_vector->rx_group.total_bytes = 0; 2690 tqp_vector->rx_group.total_bytes = 0;
2666 tqp_vector->rx_group.total_packets = 0; 2691 tqp_vector->rx_group.total_packets = 0;
2667 tqp_vector->tx_group.total_bytes = 0; 2692 tqp_vector->tx_group.total_bytes = 0;
2668 tqp_vector->tx_group.total_packets = 0; 2693 tqp_vector->tx_group.total_packets = 0;
2669 hns3_vector_gl_rl_init(tqp_vector, priv);
2670 tqp_vector->handle = h; 2694 tqp_vector->handle = h;
2671 2695
2672 ret = hns3_get_vector_ring_chain(tqp_vector, 2696 ret = hns3_get_vector_ring_chain(tqp_vector,
2673 &vector_ring_chain); 2697 &vector_ring_chain);
2674 if (ret) 2698 if (ret)
2675 goto out; 2699 return ret;
2676 2700
2677 ret = h->ae_algo->ops->map_ring_to_vector(h, 2701 ret = h->ae_algo->ops->map_ring_to_vector(h,
2678 tqp_vector->vector_irq, &vector_ring_chain); 2702 tqp_vector->vector_irq, &vector_ring_chain);
2679 if (ret)
2680 goto out;
2681 2703
2682 hns3_free_vector_ring_chain(tqp_vector, &vector_ring_chain); 2704 hns3_free_vector_ring_chain(tqp_vector, &vector_ring_chain);
2683 2705
2706 if (ret)
2707 return ret;
2708
2684 netif_napi_add(priv->netdev, &tqp_vector->napi, 2709 netif_napi_add(priv->netdev, &tqp_vector->napi,
2685 hns3_nic_common_poll, NAPI_POLL_WEIGHT); 2710 hns3_nic_common_poll, NAPI_POLL_WEIGHT);
2686 } 2711 }
2687 2712
2713 return 0;
2714}
2715
2716static int hns3_nic_alloc_vector_data(struct hns3_nic_priv *priv)
2717{
2718 struct hnae3_handle *h = priv->ae_handle;
2719 struct hns3_enet_tqp_vector *tqp_vector;
2720 struct hnae3_vector_info *vector;
2721 struct pci_dev *pdev = h->pdev;
2722 u16 tqp_num = h->kinfo.num_tqps;
2723 u16 vector_num;
2724 int ret = 0;
2725 u16 i;
2726
2727 /* RSS size, cpu online and vector_num should be the same */
2728 /* Should consider 2p/4p later */
2729 vector_num = min_t(u16, num_online_cpus(), tqp_num);
2730 vector = devm_kcalloc(&pdev->dev, vector_num, sizeof(*vector),
2731 GFP_KERNEL);
2732 if (!vector)
2733 return -ENOMEM;
2734
2735 vector_num = h->ae_algo->ops->get_vector(h, vector_num, vector);
2736
2737 priv->vector_num = vector_num;
2738 priv->tqp_vector = (struct hns3_enet_tqp_vector *)
2739 devm_kcalloc(&pdev->dev, vector_num, sizeof(*priv->tqp_vector),
2740 GFP_KERNEL);
2741 if (!priv->tqp_vector) {
2742 ret = -ENOMEM;
2743 goto out;
2744 }
2745
2746 for (i = 0; i < priv->vector_num; i++) {
2747 tqp_vector = &priv->tqp_vector[i];
2748 tqp_vector->idx = i;
2749 tqp_vector->mask_addr = vector[i].io_addr;
2750 tqp_vector->vector_irq = vector[i].vector;
2751 hns3_vector_gl_rl_init(tqp_vector, priv);
2752 }
2753
2688out: 2754out:
2689 devm_kfree(&pdev->dev, vector); 2755 devm_kfree(&pdev->dev, vector);
2690 return ret; 2756 return ret;
2691} 2757}
2692 2758
2759static void hns3_clear_ring_group(struct hns3_enet_ring_group *group)
2760{
2761 group->ring = NULL;
2762 group->count = 0;
2763}
2764
2693static int hns3_nic_uninit_vector_data(struct hns3_nic_priv *priv) 2765static int hns3_nic_uninit_vector_data(struct hns3_nic_priv *priv)
2694{ 2766{
2695 struct hnae3_ring_chain_node vector_ring_chain; 2767 struct hnae3_ring_chain_node vector_ring_chain;
2696 struct hnae3_handle *h = priv->ae_handle; 2768 struct hnae3_handle *h = priv->ae_handle;
2697 struct hns3_enet_tqp_vector *tqp_vector; 2769 struct hns3_enet_tqp_vector *tqp_vector;
2698 struct pci_dev *pdev = h->pdev;
2699 int i, ret; 2770 int i, ret;
2700 2771
2701 for (i = 0; i < priv->vector_num; i++) { 2772 for (i = 0; i < priv->vector_num; i++) {
@@ -2711,6 +2782,10 @@ static int hns3_nic_uninit_vector_data(struct hns3_nic_priv *priv)
2711 if (ret) 2782 if (ret)
2712 return ret; 2783 return ret;
2713 2784
2785 ret = h->ae_algo->ops->put_vector(h, tqp_vector->vector_irq);
2786 if (ret)
2787 return ret;
2788
2714 hns3_free_vector_ring_chain(tqp_vector, &vector_ring_chain); 2789 hns3_free_vector_ring_chain(tqp_vector, &vector_ring_chain);
2715 2790
2716 if (priv->tqp_vector[i].irq_init_flag == HNS3_VECTOR_INITED) { 2791 if (priv->tqp_vector[i].irq_init_flag == HNS3_VECTOR_INITED) {
@@ -2722,12 +2797,30 @@ static int hns3_nic_uninit_vector_data(struct hns3_nic_priv *priv)
2722 } 2797 }
2723 2798
2724 priv->ring_data[i].ring->irq_init_flag = HNS3_VECTOR_NOT_INITED; 2799 priv->ring_data[i].ring->irq_init_flag = HNS3_VECTOR_NOT_INITED;
2725 2800 hns3_clear_ring_group(&tqp_vector->rx_group);
2801 hns3_clear_ring_group(&tqp_vector->tx_group);
2726 netif_napi_del(&priv->tqp_vector[i].napi); 2802 netif_napi_del(&priv->tqp_vector[i].napi);
2727 } 2803 }
2728 2804
2729 devm_kfree(&pdev->dev, priv->tqp_vector); 2805 return 0;
2806}
2730 2807
2808static int hns3_nic_dealloc_vector_data(struct hns3_nic_priv *priv)
2809{
2810 struct hnae3_handle *h = priv->ae_handle;
2811 struct pci_dev *pdev = h->pdev;
2812 int i, ret;
2813
2814 for (i = 0; i < priv->vector_num; i++) {
2815 struct hns3_enet_tqp_vector *tqp_vector;
2816
2817 tqp_vector = &priv->tqp_vector[i];
2818 ret = h->ae_algo->ops->put_vector(h, tqp_vector->vector_irq);
2819 if (ret)
2820 return ret;
2821 }
2822
2823 devm_kfree(&pdev->dev, priv->tqp_vector);
2731 return 0; 2824 return 0;
2732} 2825}
2733 2826
@@ -2957,13 +3050,8 @@ int hns3_uninit_all_ring(struct hns3_nic_priv *priv)
2957 h->ae_algo->ops->reset_queue(h, i); 3050 h->ae_algo->ops->reset_queue(h, i);
2958 3051
2959 hns3_fini_ring(priv->ring_data[i].ring); 3052 hns3_fini_ring(priv->ring_data[i].ring);
2960 devm_kfree(priv->dev, priv->ring_data[i].ring);
2961 hns3_fini_ring(priv->ring_data[i + h->kinfo.num_tqps].ring); 3053 hns3_fini_ring(priv->ring_data[i + h->kinfo.num_tqps].ring);
2962 devm_kfree(priv->dev,
2963 priv->ring_data[i + h->kinfo.num_tqps].ring);
2964 } 3054 }
2965 devm_kfree(priv->dev, priv->ring_data);
2966
2967 return 0; 3055 return 0;
2968} 3056}
2969 3057
@@ -2987,7 +3075,7 @@ static void hns3_init_mac_addr(struct net_device *netdev)
2987 } 3075 }
2988 3076
2989 if (h->ae_algo->ops->set_mac_addr) 3077 if (h->ae_algo->ops->set_mac_addr)
2990 h->ae_algo->ops->set_mac_addr(h, netdev->dev_addr); 3078 h->ae_algo->ops->set_mac_addr(h, netdev->dev_addr, true);
2991 3079
2992} 3080}
2993 3081
@@ -3013,7 +3101,7 @@ static int hns3_client_init(struct hnae3_handle *handle)
3013 int ret; 3101 int ret;
3014 3102
3015 netdev = alloc_etherdev_mq(sizeof(struct hns3_nic_priv), 3103 netdev = alloc_etherdev_mq(sizeof(struct hns3_nic_priv),
3016 handle->kinfo.num_tqps); 3104 hns3_get_max_available_channels(handle));
3017 if (!netdev) 3105 if (!netdev)
3018 return -ENOMEM; 3106 return -ENOMEM;
3019 3107
@@ -3021,8 +3109,8 @@ static int hns3_client_init(struct hnae3_handle *handle)
3021 priv->dev = &pdev->dev; 3109 priv->dev = &pdev->dev;
3022 priv->netdev = netdev; 3110 priv->netdev = netdev;
3023 priv->ae_handle = handle; 3111 priv->ae_handle = handle;
3024 priv->last_reset_time = jiffies; 3112 priv->ae_handle->reset_level = HNAE3_NONE_RESET;
3025 priv->reset_level = HNAE3_FUNC_RESET; 3113 priv->ae_handle->last_reset_time = jiffies;
3026 priv->tx_timeout_count = 0; 3114 priv->tx_timeout_count = 0;
3027 3115
3028 handle->kinfo.netdev = netdev; 3116 handle->kinfo.netdev = netdev;
@@ -3048,6 +3136,12 @@ static int hns3_client_init(struct hnae3_handle *handle)
3048 goto out_get_ring_cfg; 3136 goto out_get_ring_cfg;
3049 } 3137 }
3050 3138
3139 ret = hns3_nic_alloc_vector_data(priv);
3140 if (ret) {
3141 ret = -ENOMEM;
3142 goto out_alloc_vector_data;
3143 }
3144
3051 ret = hns3_nic_init_vector_data(priv); 3145 ret = hns3_nic_init_vector_data(priv);
3052 if (ret) { 3146 if (ret) {
3053 ret = -ENOMEM; 3147 ret = -ENOMEM;
@@ -3076,8 +3170,10 @@ static int hns3_client_init(struct hnae3_handle *handle)
3076out_reg_netdev_fail: 3170out_reg_netdev_fail:
3077out_init_ring_data: 3171out_init_ring_data:
3078 (void)hns3_nic_uninit_vector_data(priv); 3172 (void)hns3_nic_uninit_vector_data(priv);
3079 priv->ring_data = NULL;
3080out_init_vector_data: 3173out_init_vector_data:
3174 hns3_nic_dealloc_vector_data(priv);
3175out_alloc_vector_data:
3176 priv->ring_data = NULL;
3081out_get_ring_cfg: 3177out_get_ring_cfg:
3082 priv->ae_handle = NULL; 3178 priv->ae_handle = NULL;
3083 free_netdev(netdev); 3179 free_netdev(netdev);
@@ -3097,10 +3193,16 @@ static void hns3_client_uninit(struct hnae3_handle *handle, bool reset)
3097 if (ret) 3193 if (ret)
3098 netdev_err(netdev, "uninit vector error\n"); 3194 netdev_err(netdev, "uninit vector error\n");
3099 3195
3196 ret = hns3_nic_dealloc_vector_data(priv);
3197 if (ret)
3198 netdev_err(netdev, "dealloc vector error\n");
3199
3100 ret = hns3_uninit_all_ring(priv); 3200 ret = hns3_uninit_all_ring(priv);
3101 if (ret) 3201 if (ret)
3102 netdev_err(netdev, "uninit ring error\n"); 3202 netdev_err(netdev, "uninit ring error\n");
3103 3203
3204 hns3_put_ring_config(priv);
3205
3104 priv->ring_data = NULL; 3206 priv->ring_data = NULL;
3105 3207
3106 free_netdev(netdev); 3208 free_netdev(netdev);
@@ -3240,7 +3342,6 @@ static int hns3_reset_notify_down_enet(struct hnae3_handle *handle)
3240static int hns3_reset_notify_up_enet(struct hnae3_handle *handle) 3342static int hns3_reset_notify_up_enet(struct hnae3_handle *handle)
3241{ 3343{
3242 struct hnae3_knic_private_info *kinfo = &handle->kinfo; 3344 struct hnae3_knic_private_info *kinfo = &handle->kinfo;
3243 struct hns3_nic_priv *priv = netdev_priv(kinfo->netdev);
3244 int ret = 0; 3345 int ret = 0;
3245 3346
3246 if (netif_running(kinfo->netdev)) { 3347 if (netif_running(kinfo->netdev)) {
@@ -3250,8 +3351,7 @@ static int hns3_reset_notify_up_enet(struct hnae3_handle *handle)
3250 "hns net up fail, ret=%d!\n", ret); 3351 "hns net up fail, ret=%d!\n", ret);
3251 return ret; 3352 return ret;
3252 } 3353 }
3253 3354 handle->last_reset_time = jiffies;
3254 priv->last_reset_time = jiffies;
3255 } 3355 }
3256 3356
3257 return ret; 3357 return ret;
@@ -3263,11 +3363,14 @@ static int hns3_reset_notify_init_enet(struct hnae3_handle *handle)
3263 struct hns3_nic_priv *priv = netdev_priv(netdev); 3363 struct hns3_nic_priv *priv = netdev_priv(netdev);
3264 int ret; 3364 int ret;
3265 3365
3266 priv->reset_level = 1;
3267 hns3_init_mac_addr(netdev); 3366 hns3_init_mac_addr(netdev);
3268 hns3_nic_set_rx_mode(netdev); 3367 hns3_nic_set_rx_mode(netdev);
3269 hns3_recover_hw_addr(netdev); 3368 hns3_recover_hw_addr(netdev);
3270 3369
3370 /* Hardware table is only clear when pf resets */
3371 if (!(handle->flags & HNAE3_SUPPORT_VF))
3372 hns3_restore_vlan(netdev);
3373
3271 /* Carrier off reporting is important to ethtool even BEFORE open */ 3374 /* Carrier off reporting is important to ethtool even BEFORE open */
3272 netif_carrier_off(netdev); 3375 netif_carrier_off(netdev);
3273 3376
@@ -3306,6 +3409,8 @@ static int hns3_reset_notify_uninit_enet(struct hnae3_handle *handle)
3306 if (ret) 3409 if (ret)
3307 netdev_err(netdev, "uninit ring error\n"); 3410 netdev_err(netdev, "uninit ring error\n");
3308 3411
3412 hns3_put_ring_config(priv);
3413
3309 priv->ring_data = NULL; 3414 priv->ring_data = NULL;
3310 3415
3311 return ret; 3416 return ret;
@@ -3336,18 +3441,24 @@ static int hns3_reset_notify(struct hnae3_handle *handle,
3336 return ret; 3441 return ret;
3337} 3442}
3338 3443
3339static u16 hns3_get_max_available_channels(struct net_device *netdev) 3444static void hns3_restore_coal(struct hns3_nic_priv *priv,
3445 struct hns3_enet_coalesce *tx,
3446 struct hns3_enet_coalesce *rx)
3340{ 3447{
3341 struct hnae3_handle *h = hns3_get_handle(netdev); 3448 u16 vector_num = priv->vector_num;
3342 u16 free_tqps, max_rss_size, max_tqps; 3449 int i;
3343
3344 h->ae_algo->ops->get_tqps_and_rss_info(h, &free_tqps, &max_rss_size);
3345 max_tqps = h->kinfo.num_tc * max_rss_size;
3346 3450
3347 return min_t(u16, max_tqps, (free_tqps + h->kinfo.num_tqps)); 3451 for (i = 0; i < vector_num; i++) {
3452 memcpy(&priv->tqp_vector[i].tx_group.coal, tx,
3453 sizeof(struct hns3_enet_coalesce));
3454 memcpy(&priv->tqp_vector[i].rx_group.coal, rx,
3455 sizeof(struct hns3_enet_coalesce));
3456 }
3348} 3457}
3349 3458
3350static int hns3_modify_tqp_num(struct net_device *netdev, u16 new_tqp_num) 3459static int hns3_modify_tqp_num(struct net_device *netdev, u16 new_tqp_num,
3460 struct hns3_enet_coalesce *tx,
3461 struct hns3_enet_coalesce *rx)
3351{ 3462{
3352 struct hns3_nic_priv *priv = netdev_priv(netdev); 3463 struct hns3_nic_priv *priv = netdev_priv(netdev);
3353 struct hnae3_handle *h = hns3_get_handle(netdev); 3464 struct hnae3_handle *h = hns3_get_handle(netdev);
@@ -3361,6 +3472,12 @@ static int hns3_modify_tqp_num(struct net_device *netdev, u16 new_tqp_num)
3361 if (ret) 3472 if (ret)
3362 return ret; 3473 return ret;
3363 3474
3475 ret = hns3_nic_alloc_vector_data(priv);
3476 if (ret)
3477 goto err_alloc_vector;
3478
3479 hns3_restore_coal(priv, tx, rx);
3480
3364 ret = hns3_nic_init_vector_data(priv); 3481 ret = hns3_nic_init_vector_data(priv);
3365 if (ret) 3482 if (ret)
3366 goto err_uninit_vector; 3483 goto err_uninit_vector;
@@ -3375,6 +3492,8 @@ err_put_ring:
3375 hns3_put_ring_config(priv); 3492 hns3_put_ring_config(priv);
3376err_uninit_vector: 3493err_uninit_vector:
3377 hns3_nic_uninit_vector_data(priv); 3494 hns3_nic_uninit_vector_data(priv);
3495err_alloc_vector:
3496 hns3_nic_dealloc_vector_data(priv);
3378 return ret; 3497 return ret;
3379} 3498}
3380 3499
@@ -3389,6 +3508,7 @@ int hns3_set_channels(struct net_device *netdev,
3389 struct hns3_nic_priv *priv = netdev_priv(netdev); 3508 struct hns3_nic_priv *priv = netdev_priv(netdev);
3390 struct hnae3_handle *h = hns3_get_handle(netdev); 3509 struct hnae3_handle *h = hns3_get_handle(netdev);
3391 struct hnae3_knic_private_info *kinfo = &h->kinfo; 3510 struct hnae3_knic_private_info *kinfo = &h->kinfo;
3511 struct hns3_enet_coalesce tx_coal, rx_coal;
3392 bool if_running = netif_running(netdev); 3512 bool if_running = netif_running(netdev);
3393 u32 new_tqp_num = ch->combined_count; 3513 u32 new_tqp_num = ch->combined_count;
3394 u16 org_tqp_num; 3514 u16 org_tqp_num;
@@ -3397,12 +3517,12 @@ int hns3_set_channels(struct net_device *netdev,
3397 if (ch->rx_count || ch->tx_count) 3517 if (ch->rx_count || ch->tx_count)
3398 return -EINVAL; 3518 return -EINVAL;
3399 3519
3400 if (new_tqp_num > hns3_get_max_available_channels(netdev) || 3520 if (new_tqp_num > hns3_get_max_available_channels(h) ||
3401 new_tqp_num < kinfo->num_tc) { 3521 new_tqp_num < kinfo->num_tc) {
3402 dev_err(&netdev->dev, 3522 dev_err(&netdev->dev,
3403 "Change tqps fail, the tqp range is from %d to %d", 3523 "Change tqps fail, the tqp range is from %d to %d",
3404 kinfo->num_tc, 3524 kinfo->num_tc,
3405 hns3_get_max_available_channels(netdev)); 3525 hns3_get_max_available_channels(h));
3406 return -EINVAL; 3526 return -EINVAL;
3407 } 3527 }
3408 3528
@@ -3411,7 +3531,7 @@ int hns3_set_channels(struct net_device *netdev,
3411 return 0; 3531 return 0;
3412 3532
3413 if (if_running) 3533 if (if_running)
3414 dev_close(netdev); 3534 hns3_nic_net_stop(netdev);
3415 3535
3416 hns3_clear_all_ring(h); 3536 hns3_clear_all_ring(h);
3417 3537
@@ -3422,12 +3542,26 @@ int hns3_set_channels(struct net_device *netdev,
3422 goto open_netdev; 3542 goto open_netdev;
3423 } 3543 }
3424 3544
3545 /* Changing the tqp num may also change the vector num,
3546 * ethtool only support setting and querying one coal
3547 * configuation for now, so save the vector 0' coal
3548 * configuation here in order to restore it.
3549 */
3550 memcpy(&tx_coal, &priv->tqp_vector[0].tx_group.coal,
3551 sizeof(struct hns3_enet_coalesce));
3552 memcpy(&rx_coal, &priv->tqp_vector[0].rx_group.coal,
3553 sizeof(struct hns3_enet_coalesce));
3554
3555 hns3_nic_dealloc_vector_data(priv);
3556
3425 hns3_uninit_all_ring(priv); 3557 hns3_uninit_all_ring(priv);
3558 hns3_put_ring_config(priv);
3426 3559
3427 org_tqp_num = h->kinfo.num_tqps; 3560 org_tqp_num = h->kinfo.num_tqps;
3428 ret = hns3_modify_tqp_num(netdev, new_tqp_num); 3561 ret = hns3_modify_tqp_num(netdev, new_tqp_num, &tx_coal, &rx_coal);
3429 if (ret) { 3562 if (ret) {
3430 ret = hns3_modify_tqp_num(netdev, org_tqp_num); 3563 ret = hns3_modify_tqp_num(netdev, org_tqp_num,
3564 &tx_coal, &rx_coal);
3431 if (ret) { 3565 if (ret) {
3432 /* If revert to old tqp failed, fatal error occurred */ 3566 /* If revert to old tqp failed, fatal error occurred */
3433 dev_err(&netdev->dev, 3567 dev_err(&netdev->dev,
@@ -3440,7 +3574,7 @@ int hns3_set_channels(struct net_device *netdev,
3440 3574
3441open_netdev: 3575open_netdev:
3442 if (if_running) 3576 if (if_running)
3443 dev_open(netdev); 3577 hns3_nic_net_open(netdev);
3444 3578
3445 return ret; 3579 return ret;
3446} 3580}
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
index 213f501b30bb..9e4cfbbf8dcd 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
@@ -10,6 +10,8 @@
10#ifndef __HNS3_ENET_H 10#ifndef __HNS3_ENET_H
11#define __HNS3_ENET_H 11#define __HNS3_ENET_H
12 12
13#include <linux/if_vlan.h>
14
13#include "hnae3.h" 15#include "hnae3.h"
14 16
15extern const char hns3_driver_version[]; 17extern const char hns3_driver_version[];
@@ -460,15 +462,21 @@ enum hns3_link_mode_bits {
460#define HNS3_INT_RL_MAX 0x00EC 462#define HNS3_INT_RL_MAX 0x00EC
461#define HNS3_INT_RL_ENABLE_MASK 0x40 463#define HNS3_INT_RL_ENABLE_MASK 0x40
462 464
465#define HNS3_INT_ADAPT_DOWN_START 100
466
467struct hns3_enet_coalesce {
468 u16 int_gl;
469 u8 gl_adapt_enable;
470 enum hns3_flow_level_range flow_level;
471};
472
463struct hns3_enet_ring_group { 473struct hns3_enet_ring_group {
464 /* array of pointers to rings */ 474 /* array of pointers to rings */
465 struct hns3_enet_ring *ring; 475 struct hns3_enet_ring *ring;
466 u64 total_bytes; /* total bytes processed this group */ 476 u64 total_bytes; /* total bytes processed this group */
467 u64 total_packets; /* total packets processed this group */ 477 u64 total_packets; /* total packets processed this group */
468 u16 count; 478 u16 count;
469 enum hns3_flow_level_range flow_level; 479 struct hns3_enet_coalesce coal;
470 u16 int_gl;
471 u8 gl_adapt_enable;
472}; 480};
473 481
474struct hns3_enet_tqp_vector { 482struct hns3_enet_tqp_vector {
@@ -491,6 +499,7 @@ struct hns3_enet_tqp_vector {
491 499
492 /* when 0 should adjust interrupt coalesce parameter */ 500 /* when 0 should adjust interrupt coalesce parameter */
493 u8 int_adapt_down; 501 u8 int_adapt_down;
502 unsigned long last_jiffies;
494} ____cacheline_internodealigned_in_smp; 503} ____cacheline_internodealigned_in_smp;
495 504
496enum hns3_udp_tnl_type { 505enum hns3_udp_tnl_type {
@@ -523,8 +532,6 @@ struct hns3_nic_priv {
523 /* The most recently read link state */ 532 /* The most recently read link state */
524 int link; 533 int link;
525 u64 tx_timeout_count; 534 u64 tx_timeout_count;
526 enum hnae3_reset_type reset_level;
527 unsigned long last_reset_time;
528 535
529 unsigned long state; 536 unsigned long state;
530 537
@@ -535,6 +542,7 @@ struct hns3_nic_priv {
535 struct notifier_block notifier_block; 542 struct notifier_block notifier_block;
536 /* Vxlan/Geneve information */ 543 /* Vxlan/Geneve information */
537 struct hns3_udp_tunnel udp_tnl[HNS3_UDP_TNL_MAX]; 544 struct hns3_udp_tunnel udp_tnl[HNS3_UDP_TNL_MAX];
545 unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
538}; 546};
539 547
540union l3_hdr_info { 548union l3_hdr_info {
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
index b034c7f24eda..9d07116a4426 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -74,19 +74,6 @@ struct hns3_link_mode_mapping {
74 u32 ethtool_link_mode; 74 u32 ethtool_link_mode;
75}; 75};
76 76
77static const struct hns3_link_mode_mapping hns3_lm_map[] = {
78 {HNS3_LM_FIBRE_BIT, ETHTOOL_LINK_MODE_FIBRE_BIT},
79 {HNS3_LM_AUTONEG_BIT, ETHTOOL_LINK_MODE_Autoneg_BIT},
80 {HNS3_LM_TP_BIT, ETHTOOL_LINK_MODE_TP_BIT},
81 {HNS3_LM_PAUSE_BIT, ETHTOOL_LINK_MODE_Pause_BIT},
82 {HNS3_LM_BACKPLANE_BIT, ETHTOOL_LINK_MODE_Backplane_BIT},
83 {HNS3_LM_10BASET_HALF_BIT, ETHTOOL_LINK_MODE_10baseT_Half_BIT},
84 {HNS3_LM_10BASET_FULL_BIT, ETHTOOL_LINK_MODE_10baseT_Full_BIT},
85 {HNS3_LM_100BASET_HALF_BIT, ETHTOOL_LINK_MODE_100baseT_Half_BIT},
86 {HNS3_LM_100BASET_FULL_BIT, ETHTOOL_LINK_MODE_100baseT_Full_BIT},
87 {HNS3_LM_1000BASET_FULL_BIT, ETHTOOL_LINK_MODE_1000baseT_Full_BIT},
88};
89
90static int hns3_lp_setup(struct net_device *ndev, enum hnae3_loop loop) 77static int hns3_lp_setup(struct net_device *ndev, enum hnae3_loop loop)
91{ 78{
92 struct hnae3_handle *h = hns3_get_handle(ndev); 79 struct hnae3_handle *h = hns3_get_handle(ndev);
@@ -309,6 +296,9 @@ static void hns3_self_test(struct net_device *ndev,
309 struct hnae3_handle *h = priv->ae_handle; 296 struct hnae3_handle *h = priv->ae_handle;
310 int st_param[HNS3_SELF_TEST_TPYE_NUM][2]; 297 int st_param[HNS3_SELF_TEST_TPYE_NUM][2];
311 bool if_running = netif_running(ndev); 298 bool if_running = netif_running(ndev);
299#if IS_ENABLED(CONFIG_VLAN_8021Q)
300 bool dis_vlan_filter;
301#endif
312 int test_index = 0; 302 int test_index = 0;
313 u32 i; 303 u32 i;
314 304
@@ -323,6 +313,14 @@ static void hns3_self_test(struct net_device *ndev,
323 if (if_running) 313 if (if_running)
324 dev_close(ndev); 314 dev_close(ndev);
325 315
316#if IS_ENABLED(CONFIG_VLAN_8021Q)
317 /* Disable the vlan filter for selftest does not support it */
318 dis_vlan_filter = (ndev->features & NETIF_F_HW_VLAN_CTAG_FILTER) &&
319 h->ae_algo->ops->enable_vlan_filter;
320 if (dis_vlan_filter)
321 h->ae_algo->ops->enable_vlan_filter(h, false);
322#endif
323
326 set_bit(HNS3_NIC_STATE_TESTING, &priv->state); 324 set_bit(HNS3_NIC_STATE_TESTING, &priv->state);
327 325
328 for (i = 0; i < HNS3_SELF_TEST_TPYE_NUM; i++) { 326 for (i = 0; i < HNS3_SELF_TEST_TPYE_NUM; i++) {
@@ -345,28 +343,15 @@ static void hns3_self_test(struct net_device *ndev,
345 343
346 clear_bit(HNS3_NIC_STATE_TESTING, &priv->state); 344 clear_bit(HNS3_NIC_STATE_TESTING, &priv->state);
347 345
346#if IS_ENABLED(CONFIG_VLAN_8021Q)
347 if (dis_vlan_filter)
348 h->ae_algo->ops->enable_vlan_filter(h, true);
349#endif
350
348 if (if_running) 351 if (if_running)
349 dev_open(ndev); 352 dev_open(ndev);
350} 353}
351 354
352static void hns3_driv_to_eth_caps(u32 caps, struct ethtool_link_ksettings *cmd,
353 bool is_advertised)
354{
355 int i;
356
357 for (i = 0; i < ARRAY_SIZE(hns3_lm_map); i++) {
358 if (!(caps & hns3_lm_map[i].hns3_link_mode))
359 continue;
360
361 if (is_advertised)
362 __set_bit(hns3_lm_map[i].ethtool_link_mode,
363 cmd->link_modes.advertising);
364 else
365 __set_bit(hns3_lm_map[i].ethtool_link_mode,
366 cmd->link_modes.supported);
367 }
368}
369
370static int hns3_get_sset_count(struct net_device *netdev, int stringset) 355static int hns3_get_sset_count(struct net_device *netdev, int stringset)
371{ 356{
372 struct hnae3_handle *h = hns3_get_handle(netdev); 357 struct hnae3_handle *h = hns3_get_handle(netdev);
@@ -578,18 +563,19 @@ static int hns3_get_link_ksettings(struct net_device *netdev,
578{ 563{
579 struct hnae3_handle *h = hns3_get_handle(netdev); 564 struct hnae3_handle *h = hns3_get_handle(netdev);
580 u32 flowctrl_adv = 0; 565 u32 flowctrl_adv = 0;
581 u32 supported_caps;
582 u32 advertised_caps;
583 u8 media_type = HNAE3_MEDIA_TYPE_UNKNOWN;
584 u8 link_stat; 566 u8 link_stat;
585 567
586 if (!h->ae_algo || !h->ae_algo->ops) 568 if (!h->ae_algo || !h->ae_algo->ops)
587 return -EOPNOTSUPP; 569 return -EOPNOTSUPP;
588 570
589 /* 1.auto_neg & speed & duplex from cmd */ 571 /* 1.auto_neg & speed & duplex from cmd */
590 if (netdev->phydev) 572 if (netdev->phydev) {
591 phy_ethtool_ksettings_get(netdev->phydev, cmd); 573 phy_ethtool_ksettings_get(netdev->phydev, cmd);
592 else if (h->ae_algo->ops->get_ksettings_an_result) 574
575 return 0;
576 }
577
578 if (h->ae_algo->ops->get_ksettings_an_result)
593 h->ae_algo->ops->get_ksettings_an_result(h, 579 h->ae_algo->ops->get_ksettings_an_result(h,
594 &cmd->base.autoneg, 580 &cmd->base.autoneg,
595 &cmd->base.speed, 581 &cmd->base.speed,
@@ -603,62 +589,16 @@ static int hns3_get_link_ksettings(struct net_device *netdev,
603 cmd->base.duplex = DUPLEX_UNKNOWN; 589 cmd->base.duplex = DUPLEX_UNKNOWN;
604 } 590 }
605 591
606 /* 2.media_type get from bios parameter block */ 592 /* 2.get link mode and port type*/
607 if (h->ae_algo->ops->get_media_type) { 593 if (h->ae_algo->ops->get_link_mode)
608 h->ae_algo->ops->get_media_type(h, &media_type); 594 h->ae_algo->ops->get_link_mode(h,
609 595 cmd->link_modes.supported,
610 switch (media_type) { 596 cmd->link_modes.advertising);
611 case HNAE3_MEDIA_TYPE_FIBER:
612 cmd->base.port = PORT_FIBRE;
613 supported_caps = HNS3_LM_FIBRE_BIT |
614 HNS3_LM_AUTONEG_BIT |
615 HNS3_LM_PAUSE_BIT |
616 HNS3_LM_1000BASET_FULL_BIT;
617
618 advertised_caps = supported_caps;
619 break;
620 case HNAE3_MEDIA_TYPE_COPPER:
621 cmd->base.port = PORT_TP;
622 supported_caps = HNS3_LM_TP_BIT |
623 HNS3_LM_AUTONEG_BIT |
624 HNS3_LM_PAUSE_BIT |
625 HNS3_LM_1000BASET_FULL_BIT |
626 HNS3_LM_100BASET_FULL_BIT |
627 HNS3_LM_100BASET_HALF_BIT |
628 HNS3_LM_10BASET_FULL_BIT |
629 HNS3_LM_10BASET_HALF_BIT;
630 advertised_caps = supported_caps;
631 break;
632 case HNAE3_MEDIA_TYPE_BACKPLANE:
633 cmd->base.port = PORT_NONE;
634 supported_caps = HNS3_LM_BACKPLANE_BIT |
635 HNS3_LM_PAUSE_BIT |
636 HNS3_LM_AUTONEG_BIT |
637 HNS3_LM_1000BASET_FULL_BIT |
638 HNS3_LM_100BASET_FULL_BIT |
639 HNS3_LM_100BASET_HALF_BIT |
640 HNS3_LM_10BASET_FULL_BIT |
641 HNS3_LM_10BASET_HALF_BIT;
642
643 advertised_caps = supported_caps;
644 break;
645 case HNAE3_MEDIA_TYPE_UNKNOWN:
646 default:
647 cmd->base.port = PORT_OTHER;
648 supported_caps = 0;
649 advertised_caps = 0;
650 break;
651 }
652
653 if (!cmd->base.autoneg)
654 advertised_caps &= ~HNS3_LM_AUTONEG_BIT;
655 597
656 advertised_caps &= ~HNS3_LM_PAUSE_BIT; 598 cmd->base.port = PORT_NONE;
657 599 if (h->ae_algo->ops->get_port_type)
658 /* now, map driver link modes to ethtool link modes */ 600 h->ae_algo->ops->get_port_type(h,
659 hns3_driv_to_eth_caps(supported_caps, cmd, false); 601 &cmd->base.port);
660 hns3_driv_to_eth_caps(advertised_caps, cmd, true);
661 }
662 602
663 /* 3.mdix_ctrl&mdix get from phy reg */ 603 /* 3.mdix_ctrl&mdix get from phy reg */
664 if (h->ae_algo->ops->get_mdix_mode) 604 if (h->ae_algo->ops->get_mdix_mode)
@@ -905,11 +845,13 @@ static int hns3_get_coalesce_per_queue(struct net_device *netdev, u32 queue,
905 tx_vector = priv->ring_data[queue].ring->tqp_vector; 845 tx_vector = priv->ring_data[queue].ring->tqp_vector;
906 rx_vector = priv->ring_data[queue_num + queue].ring->tqp_vector; 846 rx_vector = priv->ring_data[queue_num + queue].ring->tqp_vector;
907 847
908 cmd->use_adaptive_tx_coalesce = tx_vector->tx_group.gl_adapt_enable; 848 cmd->use_adaptive_tx_coalesce =
909 cmd->use_adaptive_rx_coalesce = rx_vector->rx_group.gl_adapt_enable; 849 tx_vector->tx_group.coal.gl_adapt_enable;
850 cmd->use_adaptive_rx_coalesce =
851 rx_vector->rx_group.coal.gl_adapt_enable;
910 852
911 cmd->tx_coalesce_usecs = tx_vector->tx_group.int_gl; 853 cmd->tx_coalesce_usecs = tx_vector->tx_group.coal.int_gl;
912 cmd->rx_coalesce_usecs = rx_vector->rx_group.int_gl; 854 cmd->rx_coalesce_usecs = rx_vector->rx_group.coal.int_gl;
913 855
914 cmd->tx_coalesce_usecs_high = h->kinfo.int_rl_setting; 856 cmd->tx_coalesce_usecs_high = h->kinfo.int_rl_setting;
915 cmd->rx_coalesce_usecs_high = h->kinfo.int_rl_setting; 857 cmd->rx_coalesce_usecs_high = h->kinfo.int_rl_setting;
@@ -1029,14 +971,18 @@ static void hns3_set_coalesce_per_queue(struct net_device *netdev,
1029 tx_vector = priv->ring_data[queue].ring->tqp_vector; 971 tx_vector = priv->ring_data[queue].ring->tqp_vector;
1030 rx_vector = priv->ring_data[queue_num + queue].ring->tqp_vector; 972 rx_vector = priv->ring_data[queue_num + queue].ring->tqp_vector;
1031 973
1032 tx_vector->tx_group.gl_adapt_enable = cmd->use_adaptive_tx_coalesce; 974 tx_vector->tx_group.coal.gl_adapt_enable =
1033 rx_vector->rx_group.gl_adapt_enable = cmd->use_adaptive_rx_coalesce; 975 cmd->use_adaptive_tx_coalesce;
976 rx_vector->rx_group.coal.gl_adapt_enable =
977 cmd->use_adaptive_rx_coalesce;
1034 978
1035 tx_vector->tx_group.int_gl = cmd->tx_coalesce_usecs; 979 tx_vector->tx_group.coal.int_gl = cmd->tx_coalesce_usecs;
1036 rx_vector->rx_group.int_gl = cmd->rx_coalesce_usecs; 980 rx_vector->rx_group.coal.int_gl = cmd->rx_coalesce_usecs;
1037 981
1038 hns3_set_vector_coalesce_tx_gl(tx_vector, tx_vector->tx_group.int_gl); 982 hns3_set_vector_coalesce_tx_gl(tx_vector,
1039 hns3_set_vector_coalesce_rx_gl(rx_vector, rx_vector->rx_group.int_gl); 983 tx_vector->tx_group.coal.int_gl);
984 hns3_set_vector_coalesce_rx_gl(rx_vector,
985 rx_vector->rx_group.coal.int_gl);
1040 986
1041 hns3_set_vector_coalesce_rl(tx_vector, h->kinfo.int_rl_setting); 987 hns3_set_vector_coalesce_rl(tx_vector, h->kinfo.int_rl_setting);
1042 hns3_set_vector_coalesce_rl(rx_vector, h->kinfo.int_rl_setting); 988 hns3_set_vector_coalesce_rl(rx_vector, h->kinfo.int_rl_setting);
@@ -1111,6 +1057,7 @@ static const struct ethtool_ops hns3vf_ethtool_ops = {
1111 .get_channels = hns3_get_channels, 1057 .get_channels = hns3_get_channels,
1112 .get_coalesce = hns3_get_coalesce, 1058 .get_coalesce = hns3_get_coalesce,
1113 .set_coalesce = hns3_set_coalesce, 1059 .set_coalesce = hns3_set_coalesce,
1060 .get_link = hns3_get_link,
1114}; 1061};
1115 1062
1116static const struct ethtool_ops hns3_ethtool_ops = { 1063static const struct ethtool_ops hns3_ethtool_ops = {
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
index 3fd10a6bec53..ee3cbac6dfaa 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
@@ -12,7 +12,7 @@
12#include <linux/types.h> 12#include <linux/types.h>
13#include <linux/io.h> 13#include <linux/io.h>
14 14
15#define HCLGE_CMDQ_TX_TIMEOUT 1000 15#define HCLGE_CMDQ_TX_TIMEOUT 30000
16 16
17struct hclge_dev; 17struct hclge_dev;
18struct hclge_desc { 18struct hclge_desc {
@@ -414,6 +414,8 @@ struct hclge_pf_res_cmd {
414#define HCLGE_CFG_DEFAULT_SPEED_M GENMASK(23, 16) 414#define HCLGE_CFG_DEFAULT_SPEED_M GENMASK(23, 16)
415#define HCLGE_CFG_RSS_SIZE_S 24 415#define HCLGE_CFG_RSS_SIZE_S 24
416#define HCLGE_CFG_RSS_SIZE_M GENMASK(31, 24) 416#define HCLGE_CFG_RSS_SIZE_M GENMASK(31, 24)
417#define HCLGE_CFG_SPEED_ABILITY_S 0
418#define HCLGE_CFG_SPEED_ABILITY_M GENMASK(7, 0)
417 419
418struct hclge_cfg_param_cmd { 420struct hclge_cfg_param_cmd {
419 __le32 offset; 421 __le32 offset;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
index 5018d6633133..955f0e3d5c95 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
@@ -144,6 +144,8 @@ static int hclge_map_update(struct hnae3_handle *h)
144 if (ret) 144 if (ret)
145 return ret; 145 return ret;
146 146
147 hclge_rss_indir_init_cfg(hdev);
148
147 return hclge_rss_init_hw(hdev); 149 return hclge_rss_init_hw(hdev);
148} 150}
149 151
@@ -203,9 +205,11 @@ static int hclge_ieee_setets(struct hnae3_handle *h, struct ieee_ets *ets)
203 205
204static int hclge_ieee_getpfc(struct hnae3_handle *h, struct ieee_pfc *pfc) 206static int hclge_ieee_getpfc(struct hnae3_handle *h, struct ieee_pfc *pfc)
205{ 207{
208 u64 requests[HNAE3_MAX_TC], indications[HNAE3_MAX_TC];
206 struct hclge_vport *vport = hclge_get_vport(h); 209 struct hclge_vport *vport = hclge_get_vport(h);
207 struct hclge_dev *hdev = vport->back; 210 struct hclge_dev *hdev = vport->back;
208 u8 i, j, pfc_map, *prio_tc; 211 u8 i, j, pfc_map, *prio_tc;
212 int ret;
209 213
210 memset(pfc, 0, sizeof(*pfc)); 214 memset(pfc, 0, sizeof(*pfc));
211 pfc->pfc_cap = hdev->pfc_max; 215 pfc->pfc_cap = hdev->pfc_max;
@@ -220,6 +224,18 @@ static int hclge_ieee_getpfc(struct hnae3_handle *h, struct ieee_pfc *pfc)
220 } 224 }
221 } 225 }
222 226
227 ret = hclge_pfc_tx_stats_get(hdev, requests);
228 if (ret)
229 return ret;
230
231 ret = hclge_pfc_rx_stats_get(hdev, indications);
232 if (ret)
233 return ret;
234
235 for (i = 0; i < HCLGE_MAX_TC_NUM; i++) {
236 pfc->requests[i] = requests[i];
237 pfc->indications[i] = indications[i];
238 }
223 return 0; 239 return 0;
224} 240}
225 241
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 32bc6f68e297..bede4117bad9 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -55,6 +55,8 @@ static const struct pci_device_id ae_algo_pci_tbl[] = {
55 {0, } 55 {0, }
56}; 56};
57 57
58MODULE_DEVICE_TABLE(pci, ae_algo_pci_tbl);
59
58static const char hns3_nic_test_strs[][ETH_GSTRING_LEN] = { 60static const char hns3_nic_test_strs[][ETH_GSTRING_LEN] = {
59 "Mac Loopback test", 61 "Mac Loopback test",
60 "Serdes Loopback test", 62 "Serdes Loopback test",
@@ -1024,6 +1026,45 @@ static int hclge_parse_speed(int speed_cmd, int *speed)
1024 return 0; 1026 return 0;
1025} 1027}
1026 1028
1029static void hclge_parse_fiber_link_mode(struct hclge_dev *hdev,
1030 u8 speed_ability)
1031{
1032 unsigned long *supported = hdev->hw.mac.supported;
1033
1034 if (speed_ability & HCLGE_SUPPORT_1G_BIT)
1035 set_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
1036 supported);
1037
1038 if (speed_ability & HCLGE_SUPPORT_10G_BIT)
1039 set_bit(ETHTOOL_LINK_MODE_10000baseSR_Full_BIT,
1040 supported);
1041
1042 if (speed_ability & HCLGE_SUPPORT_25G_BIT)
1043 set_bit(ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,
1044 supported);
1045
1046 if (speed_ability & HCLGE_SUPPORT_50G_BIT)
1047 set_bit(ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT,
1048 supported);
1049
1050 if (speed_ability & HCLGE_SUPPORT_100G_BIT)
1051 set_bit(ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT,
1052 supported);
1053
1054 set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, supported);
1055 set_bit(ETHTOOL_LINK_MODE_Pause_BIT, supported);
1056}
1057
1058static void hclge_parse_link_mode(struct hclge_dev *hdev, u8 speed_ability)
1059{
1060 u8 media_type = hdev->hw.mac.media_type;
1061
1062 if (media_type != HNAE3_MEDIA_TYPE_FIBER)
1063 return;
1064
1065 hclge_parse_fiber_link_mode(hdev, speed_ability);
1066}
1067
1027static void hclge_parse_cfg(struct hclge_cfg *cfg, struct hclge_desc *desc) 1068static void hclge_parse_cfg(struct hclge_cfg *cfg, struct hclge_desc *desc)
1028{ 1069{
1029 struct hclge_cfg_param_cmd *req; 1070 struct hclge_cfg_param_cmd *req;
@@ -1072,6 +1113,10 @@ static void hclge_parse_cfg(struct hclge_cfg *cfg, struct hclge_desc *desc)
1072 1113
1073 req = (struct hclge_cfg_param_cmd *)desc[1].data; 1114 req = (struct hclge_cfg_param_cmd *)desc[1].data;
1074 cfg->numa_node_map = __le32_to_cpu(req->param[0]); 1115 cfg->numa_node_map = __le32_to_cpu(req->param[0]);
1116
1117 cfg->speed_ability = hnae_get_field(__le32_to_cpu(req->param[1]),
1118 HCLGE_CFG_SPEED_ABILITY_M,
1119 HCLGE_CFG_SPEED_ABILITY_S);
1075} 1120}
1076 1121
1077/* hclge_get_cfg: query the static parameter from flash 1122/* hclge_get_cfg: query the static parameter from flash
@@ -1160,6 +1205,8 @@ static int hclge_configure(struct hclge_dev *hdev)
1160 return ret; 1205 return ret;
1161 } 1206 }
1162 1207
1208 hclge_parse_link_mode(hdev, cfg.speed_ability);
1209
1163 if ((hdev->tc_max > HNAE3_MAX_TC) || 1210 if ((hdev->tc_max > HNAE3_MAX_TC) ||
1164 (hdev->tc_max < 1)) { 1211 (hdev->tc_max < 1)) {
1165 dev_warn(&hdev->pdev->dev, "TC num = %d.\n", 1212 dev_warn(&hdev->pdev->dev, "TC num = %d.\n",
@@ -2702,7 +2749,7 @@ static int hclge_reset_wait(struct hclge_dev *hdev)
2702 return 0; 2749 return 0;
2703} 2750}
2704 2751
2705static int hclge_func_reset_cmd(struct hclge_dev *hdev, int func_id) 2752int hclge_func_reset_cmd(struct hclge_dev *hdev, int func_id)
2706{ 2753{
2707 struct hclge_desc desc; 2754 struct hclge_desc desc;
2708 struct hclge_reset_cmd *req = (struct hclge_reset_cmd *)desc.data; 2755 struct hclge_reset_cmd *req = (struct hclge_reset_cmd *)desc.data;
@@ -2798,27 +2845,31 @@ static void hclge_reset(struct hclge_dev *hdev)
2798 hclge_notify_client(hdev, HNAE3_UP_CLIENT); 2845 hclge_notify_client(hdev, HNAE3_UP_CLIENT);
2799} 2846}
2800 2847
2801static void hclge_reset_event(struct hnae3_handle *handle, 2848static void hclge_reset_event(struct hnae3_handle *handle)
2802 enum hnae3_reset_type reset)
2803{ 2849{
2804 struct hclge_vport *vport = hclge_get_vport(handle); 2850 struct hclge_vport *vport = hclge_get_vport(handle);
2805 struct hclge_dev *hdev = vport->back; 2851 struct hclge_dev *hdev = vport->back;
2806 2852
2807 dev_info(&hdev->pdev->dev, 2853 /* check if this is a new reset request and we are not here just because
2808 "Receive reset event , reset_type is %d", reset); 2854 * last reset attempt did not succeed and watchdog hit us again. We will
2855 * know this if last reset request did not occur very recently (watchdog
2856 * timer = 5*HZ, let us check after sufficiently large time, say 4*5*Hz)
2857 * In case of new request we reset the "reset level" to PF reset.
2858 */
2859 if (time_after(jiffies, (handle->last_reset_time + 4 * 5 * HZ)))
2860 handle->reset_level = HNAE3_FUNC_RESET;
2809 2861
2810 switch (reset) { 2862 dev_info(&hdev->pdev->dev, "received reset event , reset type is %d",
2811 case HNAE3_FUNC_RESET: 2863 handle->reset_level);
2812 case HNAE3_CORE_RESET: 2864
2813 case HNAE3_GLOBAL_RESET: 2865 /* request reset & schedule reset task */
2814 /* request reset & schedule reset task */ 2866 set_bit(handle->reset_level, &hdev->reset_request);
2815 set_bit(reset, &hdev->reset_request); 2867 hclge_reset_task_schedule(hdev);
2816 hclge_reset_task_schedule(hdev); 2868
2817 break; 2869 if (handle->reset_level < HNAE3_GLOBAL_RESET)
2818 default: 2870 handle->reset_level++;
2819 dev_warn(&hdev->pdev->dev, "Unsupported reset event:%d", reset); 2871
2820 break; 2872 handle->last_reset_time = jiffies;
2821 }
2822} 2873}
2823 2874
2824static void hclge_reset_subtask(struct hclge_dev *hdev) 2875static void hclge_reset_subtask(struct hclge_dev *hdev)
@@ -2969,6 +3020,24 @@ static int hclge_get_vector_index(struct hclge_dev *hdev, int vector)
2969 return -EINVAL; 3020 return -EINVAL;
2970} 3021}
2971 3022
3023static int hclge_put_vector(struct hnae3_handle *handle, int vector)
3024{
3025 struct hclge_vport *vport = hclge_get_vport(handle);
3026 struct hclge_dev *hdev = vport->back;
3027 int vector_id;
3028
3029 vector_id = hclge_get_vector_index(hdev, vector);
3030 if (vector_id < 0) {
3031 dev_err(&hdev->pdev->dev,
3032 "Get vector index fail. vector_id =%d\n", vector_id);
3033 return vector_id;
3034 }
3035
3036 hclge_free_vector(hdev, vector_id);
3037
3038 return 0;
3039}
3040
2972static u32 hclge_get_rss_key_size(struct hnae3_handle *handle) 3041static u32 hclge_get_rss_key_size(struct hnae3_handle *handle)
2973{ 3042{
2974 return HCLGE_RSS_KEY_SIZE; 3043 return HCLGE_RSS_KEY_SIZE;
@@ -2979,31 +3048,6 @@ static u32 hclge_get_rss_indir_size(struct hnae3_handle *handle)
2979 return HCLGE_RSS_IND_TBL_SIZE; 3048 return HCLGE_RSS_IND_TBL_SIZE;
2980} 3049}
2981 3050
2982static int hclge_get_rss_algo(struct hclge_dev *hdev)
2983{
2984 struct hclge_rss_config_cmd *req;
2985 struct hclge_desc desc;
2986 int rss_hash_algo;
2987 int ret;
2988
2989 hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_RSS_GENERIC_CONFIG, true);
2990
2991 ret = hclge_cmd_send(&hdev->hw, &desc, 1);
2992 if (ret) {
2993 dev_err(&hdev->pdev->dev,
2994 "Get link status error, status =%d\n", ret);
2995 return ret;
2996 }
2997
2998 req = (struct hclge_rss_config_cmd *)desc.data;
2999 rss_hash_algo = (req->hash_config & HCLGE_RSS_HASH_ALGO_MASK);
3000
3001 if (rss_hash_algo == HCLGE_RSS_HASH_ALGO_TOEPLITZ)
3002 return ETH_RSS_HASH_TOP;
3003
3004 return -EINVAL;
3005}
3006
3007static int hclge_set_rss_algo_key(struct hclge_dev *hdev, 3051static int hclge_set_rss_algo_key(struct hclge_dev *hdev,
3008 const u8 hfunc, const u8 *key) 3052 const u8 hfunc, const u8 *key)
3009{ 3053{
@@ -3042,7 +3086,7 @@ static int hclge_set_rss_algo_key(struct hclge_dev *hdev,
3042 return 0; 3086 return 0;
3043} 3087}
3044 3088
3045static int hclge_set_rss_indir_table(struct hclge_dev *hdev, const u32 *indir) 3089static int hclge_set_rss_indir_table(struct hclge_dev *hdev, const u8 *indir)
3046{ 3090{
3047 struct hclge_rss_indirection_table_cmd *req; 3091 struct hclge_rss_indirection_table_cmd *req;
3048 struct hclge_desc desc; 3092 struct hclge_desc desc;
@@ -3116,14 +3160,16 @@ static int hclge_set_rss_input_tuple(struct hclge_dev *hdev)
3116 hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_RSS_INPUT_TUPLE, false); 3160 hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_RSS_INPUT_TUPLE, false);
3117 3161
3118 req = (struct hclge_rss_input_tuple_cmd *)desc.data; 3162 req = (struct hclge_rss_input_tuple_cmd *)desc.data;
3119 req->ipv4_tcp_en = HCLGE_RSS_INPUT_TUPLE_OTHER; 3163
3120 req->ipv4_udp_en = HCLGE_RSS_INPUT_TUPLE_OTHER; 3164 /* Get the tuple cfg from pf */
3121 req->ipv4_sctp_en = HCLGE_RSS_INPUT_TUPLE_SCTP; 3165 req->ipv4_tcp_en = hdev->vport[0].rss_tuple_sets.ipv4_tcp_en;
3122 req->ipv4_fragment_en = HCLGE_RSS_INPUT_TUPLE_OTHER; 3166 req->ipv4_udp_en = hdev->vport[0].rss_tuple_sets.ipv4_udp_en;
3123 req->ipv6_tcp_en = HCLGE_RSS_INPUT_TUPLE_OTHER; 3167 req->ipv4_sctp_en = hdev->vport[0].rss_tuple_sets.ipv4_sctp_en;
3124 req->ipv6_udp_en = HCLGE_RSS_INPUT_TUPLE_OTHER; 3168 req->ipv4_fragment_en = hdev->vport[0].rss_tuple_sets.ipv4_fragment_en;
3125 req->ipv6_sctp_en = HCLGE_RSS_INPUT_TUPLE_SCTP; 3169 req->ipv6_tcp_en = hdev->vport[0].rss_tuple_sets.ipv6_tcp_en;
3126 req->ipv6_fragment_en = HCLGE_RSS_INPUT_TUPLE_OTHER; 3170 req->ipv6_udp_en = hdev->vport[0].rss_tuple_sets.ipv6_udp_en;
3171 req->ipv6_sctp_en = hdev->vport[0].rss_tuple_sets.ipv6_sctp_en;
3172 req->ipv6_fragment_en = hdev->vport[0].rss_tuple_sets.ipv6_fragment_en;
3127 ret = hclge_cmd_send(&hdev->hw, &desc, 1); 3173 ret = hclge_cmd_send(&hdev->hw, &desc, 1);
3128 if (ret) { 3174 if (ret) {
3129 dev_err(&hdev->pdev->dev, 3175 dev_err(&hdev->pdev->dev,
@@ -3138,12 +3184,11 @@ static int hclge_get_rss(struct hnae3_handle *handle, u32 *indir,
3138 u8 *key, u8 *hfunc) 3184 u8 *key, u8 *hfunc)
3139{ 3185{
3140 struct hclge_vport *vport = hclge_get_vport(handle); 3186 struct hclge_vport *vport = hclge_get_vport(handle);
3141 struct hclge_dev *hdev = vport->back;
3142 int i; 3187 int i;
3143 3188
3144 /* Get hash algorithm */ 3189 /* Get hash algorithm */
3145 if (hfunc) 3190 if (hfunc)
3146 *hfunc = hclge_get_rss_algo(hdev); 3191 *hfunc = vport->rss_algo;
3147 3192
3148 /* Get the RSS Key required by the user */ 3193 /* Get the RSS Key required by the user */
3149 if (key) 3194 if (key)
@@ -3167,8 +3212,6 @@ static int hclge_set_rss(struct hnae3_handle *handle, const u32 *indir,
3167 3212
3168 /* Set the RSS Hash Key if specififed by the user */ 3213 /* Set the RSS Hash Key if specififed by the user */
3169 if (key) { 3214 if (key) {
3170 /* Update the shadow RSS key with user specified qids */
3171 memcpy(vport->rss_hash_key, key, HCLGE_RSS_KEY_SIZE);
3172 3215
3173 if (hfunc == ETH_RSS_HASH_TOP || 3216 if (hfunc == ETH_RSS_HASH_TOP ||
3174 hfunc == ETH_RSS_HASH_NO_CHANGE) 3217 hfunc == ETH_RSS_HASH_NO_CHANGE)
@@ -3178,6 +3221,10 @@ static int hclge_set_rss(struct hnae3_handle *handle, const u32 *indir,
3178 ret = hclge_set_rss_algo_key(hdev, hash_algo, key); 3221 ret = hclge_set_rss_algo_key(hdev, hash_algo, key);
3179 if (ret) 3222 if (ret)
3180 return ret; 3223 return ret;
3224
3225 /* Update the shadow RSS key with user specified qids */
3226 memcpy(vport->rss_hash_key, key, HCLGE_RSS_KEY_SIZE);
3227 vport->rss_algo = hash_algo;
3181 } 3228 }
3182 3229
3183 /* Update the shadow RSS table with user specified qids */ 3230 /* Update the shadow RSS table with user specified qids */
@@ -3185,8 +3232,7 @@ static int hclge_set_rss(struct hnae3_handle *handle, const u32 *indir,
3185 vport->rss_indirection_tbl[i] = indir[i]; 3232 vport->rss_indirection_tbl[i] = indir[i];
3186 3233
3187 /* Update the hardware */ 3234 /* Update the hardware */
3188 ret = hclge_set_rss_indir_table(hdev, indir); 3235 return hclge_set_rss_indir_table(hdev, vport->rss_indirection_tbl);
3189 return ret;
3190} 3236}
3191 3237
3192static u8 hclge_get_rss_hash_bits(struct ethtool_rxnfc *nfc) 3238static u8 hclge_get_rss_hash_bits(struct ethtool_rxnfc *nfc)
@@ -3229,15 +3275,16 @@ static int hclge_set_rss_tuple(struct hnae3_handle *handle,
3229 return -EINVAL; 3275 return -EINVAL;
3230 3276
3231 req = (struct hclge_rss_input_tuple_cmd *)desc.data; 3277 req = (struct hclge_rss_input_tuple_cmd *)desc.data;
3232 hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_RSS_INPUT_TUPLE, true); 3278 hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_RSS_INPUT_TUPLE, false);
3233 ret = hclge_cmd_send(&hdev->hw, &desc, 1);
3234 if (ret) {
3235 dev_err(&hdev->pdev->dev,
3236 "Read rss tuple fail, status = %d\n", ret);
3237 return ret;
3238 }
3239 3279
3240 hclge_cmd_reuse_desc(&desc, false); 3280 req->ipv4_tcp_en = vport->rss_tuple_sets.ipv4_tcp_en;
3281 req->ipv4_udp_en = vport->rss_tuple_sets.ipv4_udp_en;
3282 req->ipv4_sctp_en = vport->rss_tuple_sets.ipv4_sctp_en;
3283 req->ipv4_fragment_en = vport->rss_tuple_sets.ipv4_fragment_en;
3284 req->ipv6_tcp_en = vport->rss_tuple_sets.ipv6_tcp_en;
3285 req->ipv6_udp_en = vport->rss_tuple_sets.ipv6_udp_en;
3286 req->ipv6_sctp_en = vport->rss_tuple_sets.ipv6_sctp_en;
3287 req->ipv6_fragment_en = vport->rss_tuple_sets.ipv6_fragment_en;
3241 3288
3242 tuple_sets = hclge_get_rss_hash_bits(nfc); 3289 tuple_sets = hclge_get_rss_hash_bits(nfc);
3243 switch (nfc->flow_type) { 3290 switch (nfc->flow_type) {
@@ -3274,52 +3321,49 @@ static int hclge_set_rss_tuple(struct hnae3_handle *handle,
3274 } 3321 }
3275 3322
3276 ret = hclge_cmd_send(&hdev->hw, &desc, 1); 3323 ret = hclge_cmd_send(&hdev->hw, &desc, 1);
3277 if (ret) 3324 if (ret) {
3278 dev_err(&hdev->pdev->dev, 3325 dev_err(&hdev->pdev->dev,
3279 "Set rss tuple fail, status = %d\n", ret); 3326 "Set rss tuple fail, status = %d\n", ret);
3327 return ret;
3328 }
3280 3329
3281 return ret; 3330 vport->rss_tuple_sets.ipv4_tcp_en = req->ipv4_tcp_en;
3331 vport->rss_tuple_sets.ipv4_udp_en = req->ipv4_udp_en;
3332 vport->rss_tuple_sets.ipv4_sctp_en = req->ipv4_sctp_en;
3333 vport->rss_tuple_sets.ipv4_fragment_en = req->ipv4_fragment_en;
3334 vport->rss_tuple_sets.ipv6_tcp_en = req->ipv6_tcp_en;
3335 vport->rss_tuple_sets.ipv6_udp_en = req->ipv6_udp_en;
3336 vport->rss_tuple_sets.ipv6_sctp_en = req->ipv6_sctp_en;
3337 vport->rss_tuple_sets.ipv6_fragment_en = req->ipv6_fragment_en;
3338 return 0;
3282} 3339}
3283 3340
3284static int hclge_get_rss_tuple(struct hnae3_handle *handle, 3341static int hclge_get_rss_tuple(struct hnae3_handle *handle,
3285 struct ethtool_rxnfc *nfc) 3342 struct ethtool_rxnfc *nfc)
3286{ 3343{
3287 struct hclge_vport *vport = hclge_get_vport(handle); 3344 struct hclge_vport *vport = hclge_get_vport(handle);
3288 struct hclge_dev *hdev = vport->back;
3289 struct hclge_rss_input_tuple_cmd *req;
3290 struct hclge_desc desc;
3291 u8 tuple_sets; 3345 u8 tuple_sets;
3292 int ret;
3293 3346
3294 nfc->data = 0; 3347 nfc->data = 0;
3295 3348
3296 req = (struct hclge_rss_input_tuple_cmd *)desc.data;
3297 hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_RSS_INPUT_TUPLE, true);
3298 ret = hclge_cmd_send(&hdev->hw, &desc, 1);
3299 if (ret) {
3300 dev_err(&hdev->pdev->dev,
3301 "Read rss tuple fail, status = %d\n", ret);
3302 return ret;
3303 }
3304
3305 switch (nfc->flow_type) { 3349 switch (nfc->flow_type) {
3306 case TCP_V4_FLOW: 3350 case TCP_V4_FLOW:
3307 tuple_sets = req->ipv4_tcp_en; 3351 tuple_sets = vport->rss_tuple_sets.ipv4_tcp_en;
3308 break; 3352 break;
3309 case UDP_V4_FLOW: 3353 case UDP_V4_FLOW:
3310 tuple_sets = req->ipv4_udp_en; 3354 tuple_sets = vport->rss_tuple_sets.ipv4_udp_en;
3311 break; 3355 break;
3312 case TCP_V6_FLOW: 3356 case TCP_V6_FLOW:
3313 tuple_sets = req->ipv6_tcp_en; 3357 tuple_sets = vport->rss_tuple_sets.ipv6_tcp_en;
3314 break; 3358 break;
3315 case UDP_V6_FLOW: 3359 case UDP_V6_FLOW:
3316 tuple_sets = req->ipv6_udp_en; 3360 tuple_sets = vport->rss_tuple_sets.ipv6_udp_en;
3317 break; 3361 break;
3318 case SCTP_V4_FLOW: 3362 case SCTP_V4_FLOW:
3319 tuple_sets = req->ipv4_sctp_en; 3363 tuple_sets = vport->rss_tuple_sets.ipv4_sctp_en;
3320 break; 3364 break;
3321 case SCTP_V6_FLOW: 3365 case SCTP_V6_FLOW:
3322 tuple_sets = req->ipv6_sctp_en; 3366 tuple_sets = vport->rss_tuple_sets.ipv6_sctp_en;
3323 break; 3367 break;
3324 case IPV4_FLOW: 3368 case IPV4_FLOW:
3325 case IPV6_FLOW: 3369 case IPV6_FLOW:
@@ -3354,50 +3398,28 @@ static int hclge_get_tc_size(struct hnae3_handle *handle)
3354 3398
3355int hclge_rss_init_hw(struct hclge_dev *hdev) 3399int hclge_rss_init_hw(struct hclge_dev *hdev)
3356{ 3400{
3357 const u8 hfunc = HCLGE_RSS_HASH_ALGO_TOEPLITZ;
3358 struct hclge_vport *vport = hdev->vport; 3401 struct hclge_vport *vport = hdev->vport;
3402 u8 *rss_indir = vport[0].rss_indirection_tbl;
3403 u16 rss_size = vport[0].alloc_rss_size;
3404 u8 *key = vport[0].rss_hash_key;
3405 u8 hfunc = vport[0].rss_algo;
3359 u16 tc_offset[HCLGE_MAX_TC_NUM]; 3406 u16 tc_offset[HCLGE_MAX_TC_NUM];
3360 u8 rss_key[HCLGE_RSS_KEY_SIZE];
3361 u16 tc_valid[HCLGE_MAX_TC_NUM]; 3407 u16 tc_valid[HCLGE_MAX_TC_NUM];
3362 u16 tc_size[HCLGE_MAX_TC_NUM]; 3408 u16 tc_size[HCLGE_MAX_TC_NUM];
3363 u32 *rss_indir = NULL; 3409 u16 roundup_size;
3364 u16 rss_size = 0, roundup_size; 3410 int i, ret;
3365 const u8 *key;
3366 int i, ret, j;
3367
3368 rss_indir = kcalloc(HCLGE_RSS_IND_TBL_SIZE, sizeof(u32), GFP_KERNEL);
3369 if (!rss_indir)
3370 return -ENOMEM;
3371
3372 /* Get default RSS key */
3373 netdev_rss_key_fill(rss_key, HCLGE_RSS_KEY_SIZE);
3374
3375 /* Initialize RSS indirect table for each vport */
3376 for (j = 0; j < hdev->num_vmdq_vport + 1; j++) {
3377 for (i = 0; i < HCLGE_RSS_IND_TBL_SIZE; i++) {
3378 vport[j].rss_indirection_tbl[i] =
3379 i % vport[j].alloc_rss_size;
3380
3381 /* vport 0 is for PF */
3382 if (j != 0)
3383 continue;
3384 3411
3385 rss_size = vport[j].alloc_rss_size;
3386 rss_indir[i] = vport[j].rss_indirection_tbl[i];
3387 }
3388 }
3389 ret = hclge_set_rss_indir_table(hdev, rss_indir); 3412 ret = hclge_set_rss_indir_table(hdev, rss_indir);
3390 if (ret) 3413 if (ret)
3391 goto err; 3414 return ret;
3392 3415
3393 key = rss_key;
3394 ret = hclge_set_rss_algo_key(hdev, hfunc, key); 3416 ret = hclge_set_rss_algo_key(hdev, hfunc, key);
3395 if (ret) 3417 if (ret)
3396 goto err; 3418 return ret;
3397 3419
3398 ret = hclge_set_rss_input_tuple(hdev); 3420 ret = hclge_set_rss_input_tuple(hdev);
3399 if (ret) 3421 if (ret)
3400 goto err; 3422 return ret;
3401 3423
3402 /* Each TC have the same queue size, and tc_size set to hardware is 3424 /* Each TC have the same queue size, and tc_size set to hardware is
3403 * the log2 of roundup power of two of rss_size, the acutal queue 3425 * the log2 of roundup power of two of rss_size, the acutal queue
@@ -3407,8 +3429,7 @@ int hclge_rss_init_hw(struct hclge_dev *hdev)
3407 dev_err(&hdev->pdev->dev, 3429 dev_err(&hdev->pdev->dev,
3408 "Configure rss tc size failed, invalid TC_SIZE = %d\n", 3430 "Configure rss tc size failed, invalid TC_SIZE = %d\n",
3409 rss_size); 3431 rss_size);
3410 ret = -EINVAL; 3432 return -EINVAL;
3411 goto err;
3412 } 3433 }
3413 3434
3414 roundup_size = roundup_pow_of_two(rss_size); 3435 roundup_size = roundup_pow_of_two(rss_size);
@@ -3425,12 +3446,50 @@ int hclge_rss_init_hw(struct hclge_dev *hdev)
3425 tc_offset[i] = rss_size * i; 3446 tc_offset[i] = rss_size * i;
3426 } 3447 }
3427 3448
3428 ret = hclge_set_rss_tc_mode(hdev, tc_valid, tc_size, tc_offset); 3449 return hclge_set_rss_tc_mode(hdev, tc_valid, tc_size, tc_offset);
3450}
3429 3451
3430err: 3452void hclge_rss_indir_init_cfg(struct hclge_dev *hdev)
3431 kfree(rss_indir); 3453{
3454 struct hclge_vport *vport = hdev->vport;
3455 int i, j;
3432 3456
3433 return ret; 3457 for (j = 0; j < hdev->num_vmdq_vport + 1; j++) {
3458 for (i = 0; i < HCLGE_RSS_IND_TBL_SIZE; i++)
3459 vport[j].rss_indirection_tbl[i] =
3460 i % vport[j].alloc_rss_size;
3461 }
3462}
3463
3464static void hclge_rss_init_cfg(struct hclge_dev *hdev)
3465{
3466 struct hclge_vport *vport = hdev->vport;
3467 int i;
3468
3469 netdev_rss_key_fill(vport->rss_hash_key, HCLGE_RSS_KEY_SIZE);
3470
3471 for (i = 0; i < hdev->num_vmdq_vport + 1; i++) {
3472 vport[i].rss_tuple_sets.ipv4_tcp_en =
3473 HCLGE_RSS_INPUT_TUPLE_OTHER;
3474 vport[i].rss_tuple_sets.ipv4_udp_en =
3475 HCLGE_RSS_INPUT_TUPLE_OTHER;
3476 vport[i].rss_tuple_sets.ipv4_sctp_en =
3477 HCLGE_RSS_INPUT_TUPLE_SCTP;
3478 vport[i].rss_tuple_sets.ipv4_fragment_en =
3479 HCLGE_RSS_INPUT_TUPLE_OTHER;
3480 vport[i].rss_tuple_sets.ipv6_tcp_en =
3481 HCLGE_RSS_INPUT_TUPLE_OTHER;
3482 vport[i].rss_tuple_sets.ipv6_udp_en =
3483 HCLGE_RSS_INPUT_TUPLE_OTHER;
3484 vport[i].rss_tuple_sets.ipv6_sctp_en =
3485 HCLGE_RSS_INPUT_TUPLE_SCTP;
3486 vport[i].rss_tuple_sets.ipv6_fragment_en =
3487 HCLGE_RSS_INPUT_TUPLE_OTHER;
3488
3489 vport[i].rss_algo = HCLGE_RSS_HASH_ALGO_TOEPLITZ;
3490 }
3491
3492 hclge_rss_indir_init_cfg(hdev);
3434} 3493}
3435 3494
3436int hclge_bind_ring_with_vector(struct hclge_vport *vport, 3495int hclge_bind_ring_with_vector(struct hclge_vport *vport,
@@ -3533,18 +3592,13 @@ static int hclge_unmap_ring_frm_vector(struct hnae3_handle *handle,
3533 } 3592 }
3534 3593
3535 ret = hclge_bind_ring_with_vector(vport, vector_id, false, ring_chain); 3594 ret = hclge_bind_ring_with_vector(vport, vector_id, false, ring_chain);
3536 if (ret) { 3595 if (ret)
3537 dev_err(&handle->pdev->dev, 3596 dev_err(&handle->pdev->dev,
3538 "Unmap ring from vector fail. vectorid=%d, ret =%d\n", 3597 "Unmap ring from vector fail. vectorid=%d, ret =%d\n",
3539 vector_id, 3598 vector_id,
3540 ret); 3599 ret);
3541 return ret;
3542 }
3543
3544 /* Free this MSIX or MSI vector */
3545 hclge_free_vector(hdev, vector_id);
3546 3600
3547 return 0; 3601 return ret;
3548} 3602}
3549 3603
3550int hclge_cmd_set_promisc_mode(struct hclge_dev *hdev, 3604int hclge_cmd_set_promisc_mode(struct hclge_dev *hdev,
@@ -3717,20 +3771,11 @@ static int hclge_ae_start(struct hnae3_handle *handle)
3717{ 3771{
3718 struct hclge_vport *vport = hclge_get_vport(handle); 3772 struct hclge_vport *vport = hclge_get_vport(handle);
3719 struct hclge_dev *hdev = vport->back; 3773 struct hclge_dev *hdev = vport->back;
3720 int i, queue_id, ret; 3774 int i, ret;
3721 3775
3722 for (i = 0; i < vport->alloc_tqps; i++) { 3776 for (i = 0; i < vport->alloc_tqps; i++)
3723 /* todo clear interrupt */ 3777 hclge_tqp_enable(hdev, i, 0, true);
3724 /* ring enable */
3725 queue_id = hclge_get_queue_id(handle->kinfo.tqp[i]);
3726 if (queue_id < 0) {
3727 dev_warn(&hdev->pdev->dev,
3728 "Get invalid queue id, ignore it\n");
3729 continue;
3730 }
3731 3778
3732 hclge_tqp_enable(hdev, queue_id, 0, true);
3733 }
3734 /* mac enable */ 3779 /* mac enable */
3735 hclge_cfg_mac_mode(hdev, true); 3780 hclge_cfg_mac_mode(hdev, true);
3736 clear_bit(HCLGE_STATE_DOWN, &hdev->state); 3781 clear_bit(HCLGE_STATE_DOWN, &hdev->state);
@@ -3750,19 +3795,11 @@ static void hclge_ae_stop(struct hnae3_handle *handle)
3750{ 3795{
3751 struct hclge_vport *vport = hclge_get_vport(handle); 3796 struct hclge_vport *vport = hclge_get_vport(handle);
3752 struct hclge_dev *hdev = vport->back; 3797 struct hclge_dev *hdev = vport->back;
3753 int i, queue_id; 3798 int i;
3754 3799
3755 for (i = 0; i < vport->alloc_tqps; i++) { 3800 for (i = 0; i < vport->alloc_tqps; i++)
3756 /* Ring disable */ 3801 hclge_tqp_enable(hdev, i, 0, false);
3757 queue_id = hclge_get_queue_id(handle->kinfo.tqp[i]);
3758 if (queue_id < 0) {
3759 dev_warn(&hdev->pdev->dev,
3760 "Get invalid queue id, ignore it\n");
3761 continue;
3762 }
3763 3802
3764 hclge_tqp_enable(hdev, queue_id, 0, false);
3765 }
3766 /* Mac disable */ 3803 /* Mac disable */
3767 hclge_cfg_mac_mode(hdev, false); 3804 hclge_cfg_mac_mode(hdev, false);
3768 3805
@@ -3770,6 +3807,9 @@ static void hclge_ae_stop(struct hnae3_handle *handle)
3770 3807
3771 /* reset tqp stats */ 3808 /* reset tqp stats */
3772 hclge_reset_tqp_stats(handle); 3809 hclge_reset_tqp_stats(handle);
3810 del_timer_sync(&hdev->service_timer);
3811 cancel_work_sync(&hdev->service_task);
3812 hclge_update_link_status(hdev);
3773} 3813}
3774 3814
3775static int hclge_get_mac_vlan_cmd_status(struct hclge_vport *vport, 3815static int hclge_get_mac_vlan_cmd_status(struct hclge_vport *vport,
@@ -3790,11 +3830,11 @@ static int hclge_get_mac_vlan_cmd_status(struct hclge_vport *vport,
3790 if ((!resp_code) || (resp_code == 1)) { 3830 if ((!resp_code) || (resp_code == 1)) {
3791 return_status = 0; 3831 return_status = 0;
3792 } else if (resp_code == 2) { 3832 } else if (resp_code == 2) {
3793 return_status = -EIO; 3833 return_status = -ENOSPC;
3794 dev_err(&hdev->pdev->dev, 3834 dev_err(&hdev->pdev->dev,
3795 "add mac addr failed for uc_overflow.\n"); 3835 "add mac addr failed for uc_overflow.\n");
3796 } else if (resp_code == 3) { 3836 } else if (resp_code == 3) {
3797 return_status = -EIO; 3837 return_status = -ENOSPC;
3798 dev_err(&hdev->pdev->dev, 3838 dev_err(&hdev->pdev->dev,
3799 "add mac addr failed for mc_overflow.\n"); 3839 "add mac addr failed for mc_overflow.\n");
3800 } else { 3840 } else {
@@ -3806,7 +3846,7 @@ static int hclge_get_mac_vlan_cmd_status(struct hclge_vport *vport,
3806 if (!resp_code) { 3846 if (!resp_code) {
3807 return_status = 0; 3847 return_status = 0;
3808 } else if (resp_code == 1) { 3848 } else if (resp_code == 1) {
3809 return_status = -EIO; 3849 return_status = -ENOENT;
3810 dev_dbg(&hdev->pdev->dev, 3850 dev_dbg(&hdev->pdev->dev,
3811 "remove mac addr failed for miss.\n"); 3851 "remove mac addr failed for miss.\n");
3812 } else { 3852 } else {
@@ -3818,7 +3858,7 @@ static int hclge_get_mac_vlan_cmd_status(struct hclge_vport *vport,
3818 if (!resp_code) { 3858 if (!resp_code) {
3819 return_status = 0; 3859 return_status = 0;
3820 } else if (resp_code == 1) { 3860 } else if (resp_code == 1) {
3821 return_status = -EIO; 3861 return_status = -ENOENT;
3822 dev_dbg(&hdev->pdev->dev, 3862 dev_dbg(&hdev->pdev->dev,
3823 "lookup mac addr failed for miss.\n"); 3863 "lookup mac addr failed for miss.\n");
3824 } else { 3864 } else {
@@ -3827,7 +3867,7 @@ static int hclge_get_mac_vlan_cmd_status(struct hclge_vport *vport,
3827 resp_code); 3867 resp_code);
3828 } 3868 }
3829 } else { 3869 } else {
3830 return_status = -EIO; 3870 return_status = -EINVAL;
3831 dev_err(&hdev->pdev->dev, 3871 dev_err(&hdev->pdev->dev,
3832 "unknown opcode for get_mac_vlan_cmd_status,opcode=%d.\n", 3872 "unknown opcode for get_mac_vlan_cmd_status,opcode=%d.\n",
3833 op); 3873 op);
@@ -4118,8 +4158,9 @@ int hclge_add_uc_addr_common(struct hclge_vport *vport,
4118{ 4158{
4119 struct hclge_dev *hdev = vport->back; 4159 struct hclge_dev *hdev = vport->back;
4120 struct hclge_mac_vlan_tbl_entry_cmd req; 4160 struct hclge_mac_vlan_tbl_entry_cmd req;
4121 enum hclge_cmd_status status; 4161 struct hclge_desc desc;
4122 u16 egress_port = 0; 4162 u16 egress_port = 0;
4163 int ret;
4123 4164
4124 /* mac addr check */ 4165 /* mac addr check */
4125 if (is_zero_ether_addr(addr) || 4166 if (is_zero_ether_addr(addr) ||
@@ -4151,9 +4192,23 @@ int hclge_add_uc_addr_common(struct hclge_vport *vport,
4151 4192
4152 hclge_prepare_mac_addr(&req, addr); 4193 hclge_prepare_mac_addr(&req, addr);
4153 4194
4154 status = hclge_add_mac_vlan_tbl(vport, &req, NULL); 4195 /* Lookup the mac address in the mac_vlan table, and add
4196 * it if the entry is inexistent. Repeated unicast entry
4197 * is not allowed in the mac vlan table.
4198 */
4199 ret = hclge_lookup_mac_vlan_tbl(vport, &req, &desc, false);
4200 if (ret == -ENOENT)
4201 return hclge_add_mac_vlan_tbl(vport, &req, NULL);
4202
4203 /* check if we just hit the duplicate */
4204 if (!ret)
4205 ret = -EINVAL;
4155 4206
4156 return status; 4207 dev_err(&hdev->pdev->dev,
4208 "PF failed to add unicast entry(%pM) in the MAC table\n",
4209 addr);
4210
4211 return ret;
4157} 4212}
4158 4213
4159static int hclge_rm_uc_addr(struct hnae3_handle *handle, 4214static int hclge_rm_uc_addr(struct hnae3_handle *handle,
@@ -4169,7 +4224,7 @@ int hclge_rm_uc_addr_common(struct hclge_vport *vport,
4169{ 4224{
4170 struct hclge_dev *hdev = vport->back; 4225 struct hclge_dev *hdev = vport->back;
4171 struct hclge_mac_vlan_tbl_entry_cmd req; 4226 struct hclge_mac_vlan_tbl_entry_cmd req;
4172 enum hclge_cmd_status status; 4227 int ret;
4173 4228
4174 /* mac addr check */ 4229 /* mac addr check */
4175 if (is_zero_ether_addr(addr) || 4230 if (is_zero_ether_addr(addr) ||
@@ -4185,9 +4240,9 @@ int hclge_rm_uc_addr_common(struct hclge_vport *vport,
4185 hnae_set_bit(req.flags, HCLGE_MAC_VLAN_BIT0_EN_B, 1); 4240 hnae_set_bit(req.flags, HCLGE_MAC_VLAN_BIT0_EN_B, 1);
4186 hnae_set_bit(req.entry_type, HCLGE_MAC_VLAN_BIT0_EN_B, 0); 4241 hnae_set_bit(req.entry_type, HCLGE_MAC_VLAN_BIT0_EN_B, 0);
4187 hclge_prepare_mac_addr(&req, addr); 4242 hclge_prepare_mac_addr(&req, addr);
4188 status = hclge_remove_mac_vlan_tbl(vport, &req); 4243 ret = hclge_remove_mac_vlan_tbl(vport, &req);
4189 4244
4190 return status; 4245 return ret;
4191} 4246}
4192 4247
4193static int hclge_add_mc_addr(struct hnae3_handle *handle, 4248static int hclge_add_mc_addr(struct hnae3_handle *handle,
@@ -4392,7 +4447,8 @@ static void hclge_get_mac_addr(struct hnae3_handle *handle, u8 *p)
4392 ether_addr_copy(p, hdev->hw.mac.mac_addr); 4447 ether_addr_copy(p, hdev->hw.mac.mac_addr);
4393} 4448}
4394 4449
4395static int hclge_set_mac_addr(struct hnae3_handle *handle, void *p) 4450static int hclge_set_mac_addr(struct hnae3_handle *handle, void *p,
4451 bool is_first)
4396{ 4452{
4397 const unsigned char *new_addr = (const unsigned char *)p; 4453 const unsigned char *new_addr = (const unsigned char *)p;
4398 struct hclge_vport *vport = hclge_get_vport(handle); 4454 struct hclge_vport *vport = hclge_get_vport(handle);
@@ -4409,11 +4465,9 @@ static int hclge_set_mac_addr(struct hnae3_handle *handle, void *p)
4409 return -EINVAL; 4465 return -EINVAL;
4410 } 4466 }
4411 4467
4412 ret = hclge_rm_uc_addr(handle, hdev->hw.mac.mac_addr); 4468 if (!is_first && hclge_rm_uc_addr(handle, hdev->hw.mac.mac_addr))
4413 if (ret)
4414 dev_warn(&hdev->pdev->dev, 4469 dev_warn(&hdev->pdev->dev,
4415 "remove old uc mac address fail, ret =%d.\n", 4470 "remove old uc mac address fail.\n");
4416 ret);
4417 4471
4418 ret = hclge_add_uc_addr(handle, new_addr); 4472 ret = hclge_add_uc_addr(handle, new_addr);
4419 if (ret) { 4473 if (ret) {
@@ -4421,17 +4475,15 @@ static int hclge_set_mac_addr(struct hnae3_handle *handle, void *p)
4421 "add uc mac address fail, ret =%d.\n", 4475 "add uc mac address fail, ret =%d.\n",
4422 ret); 4476 ret);
4423 4477
4424 ret = hclge_add_uc_addr(handle, hdev->hw.mac.mac_addr); 4478 if (!is_first &&
4425 if (ret) { 4479 hclge_add_uc_addr(handle, hdev->hw.mac.mac_addr))
4426 dev_err(&hdev->pdev->dev, 4480 dev_err(&hdev->pdev->dev,
4427 "restore uc mac address fail, ret =%d.\n", 4481 "restore uc mac address fail.\n");
4428 ret);
4429 }
4430 4482
4431 return -EIO; 4483 return -EIO;
4432 } 4484 }
4433 4485
4434 ret = hclge_mac_pause_addr_cfg(hdev, new_addr); 4486 ret = hclge_pause_addr_cfg(hdev, new_addr);
4435 if (ret) { 4487 if (ret) {
4436 dev_err(&hdev->pdev->dev, 4488 dev_err(&hdev->pdev->dev,
4437 "configure mac pause address fail, ret =%d.\n", 4489 "configure mac pause address fail, ret =%d.\n",
@@ -4771,11 +4823,9 @@ static int hclge_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable)
4771 return hclge_set_vlan_rx_offload_cfg(vport); 4823 return hclge_set_vlan_rx_offload_cfg(vport);
4772} 4824}
4773 4825
4774static int hclge_set_mtu(struct hnae3_handle *handle, int new_mtu) 4826static int hclge_set_mac_mtu(struct hclge_dev *hdev, int new_mtu)
4775{ 4827{
4776 struct hclge_vport *vport = hclge_get_vport(handle);
4777 struct hclge_config_max_frm_size_cmd *req; 4828 struct hclge_config_max_frm_size_cmd *req;
4778 struct hclge_dev *hdev = vport->back;
4779 struct hclge_desc desc; 4829 struct hclge_desc desc;
4780 int max_frm_size; 4830 int max_frm_size;
4781 int ret; 4831 int ret;
@@ -4804,6 +4854,27 @@ static int hclge_set_mtu(struct hnae3_handle *handle, int new_mtu)
4804 return 0; 4854 return 0;
4805} 4855}
4806 4856
4857static int hclge_set_mtu(struct hnae3_handle *handle, int new_mtu)
4858{
4859 struct hclge_vport *vport = hclge_get_vport(handle);
4860 struct hclge_dev *hdev = vport->back;
4861 int ret;
4862
4863 ret = hclge_set_mac_mtu(hdev, new_mtu);
4864 if (ret) {
4865 dev_err(&hdev->pdev->dev,
4866 "Change mtu fail, ret =%d\n", ret);
4867 return ret;
4868 }
4869
4870 ret = hclge_buffer_alloc(hdev);
4871 if (ret)
4872 dev_err(&hdev->pdev->dev,
4873 "Allocate buffer fail, ret =%d\n", ret);
4874
4875 return ret;
4876}
4877
4807static int hclge_send_reset_tqp_cmd(struct hclge_dev *hdev, u16 queue_id, 4878static int hclge_send_reset_tqp_cmd(struct hclge_dev *hdev, u16 queue_id,
4808 bool enable) 4879 bool enable)
4809{ 4880{
@@ -4848,21 +4919,36 @@ static int hclge_get_reset_status(struct hclge_dev *hdev, u16 queue_id)
4848 return hnae_get_bit(req->ready_to_reset, HCLGE_TQP_RESET_B); 4919 return hnae_get_bit(req->ready_to_reset, HCLGE_TQP_RESET_B);
4849} 4920}
4850 4921
4922static u16 hclge_covert_handle_qid_global(struct hnae3_handle *handle,
4923 u16 queue_id)
4924{
4925 struct hnae3_queue *queue;
4926 struct hclge_tqp *tqp;
4927
4928 queue = handle->kinfo.tqp[queue_id];
4929 tqp = container_of(queue, struct hclge_tqp, q);
4930
4931 return tqp->index;
4932}
4933
4851void hclge_reset_tqp(struct hnae3_handle *handle, u16 queue_id) 4934void hclge_reset_tqp(struct hnae3_handle *handle, u16 queue_id)
4852{ 4935{
4853 struct hclge_vport *vport = hclge_get_vport(handle); 4936 struct hclge_vport *vport = hclge_get_vport(handle);
4854 struct hclge_dev *hdev = vport->back; 4937 struct hclge_dev *hdev = vport->back;
4855 int reset_try_times = 0; 4938 int reset_try_times = 0;
4856 int reset_status; 4939 int reset_status;
4940 u16 queue_gid;
4857 int ret; 4941 int ret;
4858 4942
4943 queue_gid = hclge_covert_handle_qid_global(handle, queue_id);
4944
4859 ret = hclge_tqp_enable(hdev, queue_id, 0, false); 4945 ret = hclge_tqp_enable(hdev, queue_id, 0, false);
4860 if (ret) { 4946 if (ret) {
4861 dev_warn(&hdev->pdev->dev, "Disable tqp fail, ret = %d\n", ret); 4947 dev_warn(&hdev->pdev->dev, "Disable tqp fail, ret = %d\n", ret);
4862 return; 4948 return;
4863 } 4949 }
4864 4950
4865 ret = hclge_send_reset_tqp_cmd(hdev, queue_id, true); 4951 ret = hclge_send_reset_tqp_cmd(hdev, queue_gid, true);
4866 if (ret) { 4952 if (ret) {
4867 dev_warn(&hdev->pdev->dev, 4953 dev_warn(&hdev->pdev->dev,
4868 "Send reset tqp cmd fail, ret = %d\n", ret); 4954 "Send reset tqp cmd fail, ret = %d\n", ret);
@@ -4873,7 +4959,7 @@ void hclge_reset_tqp(struct hnae3_handle *handle, u16 queue_id)
4873 while (reset_try_times++ < HCLGE_TQP_RESET_TRY_TIMES) { 4959 while (reset_try_times++ < HCLGE_TQP_RESET_TRY_TIMES) {
4874 /* Wait for tqp hw reset */ 4960 /* Wait for tqp hw reset */
4875 msleep(20); 4961 msleep(20);
4876 reset_status = hclge_get_reset_status(hdev, queue_id); 4962 reset_status = hclge_get_reset_status(hdev, queue_gid);
4877 if (reset_status) 4963 if (reset_status)
4878 break; 4964 break;
4879 } 4965 }
@@ -4883,7 +4969,7 @@ void hclge_reset_tqp(struct hnae3_handle *handle, u16 queue_id)
4883 return; 4969 return;
4884 } 4970 }
4885 4971
4886 ret = hclge_send_reset_tqp_cmd(hdev, queue_id, false); 4972 ret = hclge_send_reset_tqp_cmd(hdev, queue_gid, false);
4887 if (ret) { 4973 if (ret) {
4888 dev_warn(&hdev->pdev->dev, 4974 dev_warn(&hdev->pdev->dev,
4889 "Deassert the soft reset fail, ret = %d\n", ret); 4975 "Deassert the soft reset fail, ret = %d\n", ret);
@@ -4891,6 +4977,43 @@ void hclge_reset_tqp(struct hnae3_handle *handle, u16 queue_id)
4891 } 4977 }
4892} 4978}
4893 4979
4980void hclge_reset_vf_queue(struct hclge_vport *vport, u16 queue_id)
4981{
4982 struct hclge_dev *hdev = vport->back;
4983 int reset_try_times = 0;
4984 int reset_status;
4985 u16 queue_gid;
4986 int ret;
4987
4988 queue_gid = hclge_covert_handle_qid_global(&vport->nic, queue_id);
4989
4990 ret = hclge_send_reset_tqp_cmd(hdev, queue_gid, true);
4991 if (ret) {
4992 dev_warn(&hdev->pdev->dev,
4993 "Send reset tqp cmd fail, ret = %d\n", ret);
4994 return;
4995 }
4996
4997 reset_try_times = 0;
4998 while (reset_try_times++ < HCLGE_TQP_RESET_TRY_TIMES) {
4999 /* Wait for tqp hw reset */
5000 msleep(20);
5001 reset_status = hclge_get_reset_status(hdev, queue_gid);
5002 if (reset_status)
5003 break;
5004 }
5005
5006 if (reset_try_times >= HCLGE_TQP_RESET_TRY_TIMES) {
5007 dev_warn(&hdev->pdev->dev, "Reset TQP fail\n");
5008 return;
5009 }
5010
5011 ret = hclge_send_reset_tqp_cmd(hdev, queue_gid, false);
5012 if (ret)
5013 dev_warn(&hdev->pdev->dev,
5014 "Deassert the soft reset fail, ret = %d\n", ret);
5015}
5016
4894static u32 hclge_get_fw_version(struct hnae3_handle *handle) 5017static u32 hclge_get_fw_version(struct hnae3_handle *handle)
4895{ 5018{
4896 struct hclge_vport *vport = hclge_get_vport(handle); 5019 struct hclge_vport *vport = hclge_get_vport(handle);
@@ -5376,11 +5499,6 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
5376 dev_err(&pdev->dev, "Mac init error, ret = %d\n", ret); 5499 dev_err(&pdev->dev, "Mac init error, ret = %d\n", ret);
5377 return ret; 5500 return ret;
5378 } 5501 }
5379 ret = hclge_buffer_alloc(hdev);
5380 if (ret) {
5381 dev_err(&pdev->dev, "Buffer allocate fail, ret =%d\n", ret);
5382 return ret;
5383 }
5384 5502
5385 ret = hclge_config_tso(hdev, HCLGE_TSO_MSS_MIN, HCLGE_TSO_MSS_MAX); 5503 ret = hclge_config_tso(hdev, HCLGE_TSO_MSS_MIN, HCLGE_TSO_MSS_MAX);
5386 if (ret) { 5504 if (ret) {
@@ -5400,6 +5518,7 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
5400 return ret; 5518 return ret;
5401 } 5519 }
5402 5520
5521 hclge_rss_init_cfg(hdev);
5403 ret = hclge_rss_init_hw(hdev); 5522 ret = hclge_rss_init_hw(hdev);
5404 if (ret) { 5523 if (ret) {
5405 dev_err(&pdev->dev, "Rss init fail, ret =%d\n", ret); 5524 dev_err(&pdev->dev, "Rss init fail, ret =%d\n", ret);
@@ -5486,12 +5605,6 @@ static int hclge_reset_ae_dev(struct hnae3_ae_dev *ae_dev)
5486 return ret; 5605 return ret;
5487 } 5606 }
5488 5607
5489 ret = hclge_buffer_alloc(hdev);
5490 if (ret) {
5491 dev_err(&pdev->dev, "Buffer allocate fail, ret =%d\n", ret);
5492 return ret;
5493 }
5494
5495 ret = hclge_config_tso(hdev, HCLGE_TSO_MSS_MIN, HCLGE_TSO_MSS_MAX); 5608 ret = hclge_config_tso(hdev, HCLGE_TSO_MSS_MIN, HCLGE_TSO_MSS_MAX);
5496 if (ret) { 5609 if (ret) {
5497 dev_err(&pdev->dev, "Enable tso fail, ret =%d\n", ret); 5610 dev_err(&pdev->dev, "Enable tso fail, ret =%d\n", ret);
@@ -5504,9 +5617,9 @@ static int hclge_reset_ae_dev(struct hnae3_ae_dev *ae_dev)
5504 return ret; 5617 return ret;
5505 } 5618 }
5506 5619
5507 ret = hclge_tm_schd_init(hdev); 5620 ret = hclge_tm_init_hw(hdev);
5508 if (ret) { 5621 if (ret) {
5509 dev_err(&pdev->dev, "tm schd init fail, ret =%d\n", ret); 5622 dev_err(&pdev->dev, "tm init hw fail, ret =%d\n", ret);
5510 return ret; 5623 return ret;
5511 } 5624 }
5512 5625
@@ -5997,6 +6110,42 @@ static int hclge_update_led_status(struct hclge_dev *hdev)
5997 HCLGE_LED_NO_CHANGE); 6110 HCLGE_LED_NO_CHANGE);
5998} 6111}
5999 6112
6113static void hclge_get_link_mode(struct hnae3_handle *handle,
6114 unsigned long *supported,
6115 unsigned long *advertising)
6116{
6117 unsigned int size = BITS_TO_LONGS(__ETHTOOL_LINK_MODE_MASK_NBITS);
6118 struct hclge_vport *vport = hclge_get_vport(handle);
6119 struct hclge_dev *hdev = vport->back;
6120 unsigned int idx = 0;
6121
6122 for (; idx < size; idx++) {
6123 supported[idx] = hdev->hw.mac.supported[idx];
6124 advertising[idx] = hdev->hw.mac.advertising[idx];
6125 }
6126}
6127
6128static void hclge_get_port_type(struct hnae3_handle *handle,
6129 u8 *port_type)
6130{
6131 struct hclge_vport *vport = hclge_get_vport(handle);
6132 struct hclge_dev *hdev = vport->back;
6133 u8 media_type = hdev->hw.mac.media_type;
6134
6135 switch (media_type) {
6136 case HNAE3_MEDIA_TYPE_FIBER:
6137 *port_type = PORT_FIBRE;
6138 break;
6139 case HNAE3_MEDIA_TYPE_COPPER:
6140 *port_type = PORT_TP;
6141 break;
6142 case HNAE3_MEDIA_TYPE_UNKNOWN:
6143 default:
6144 *port_type = PORT_OTHER;
6145 break;
6146 }
6147}
6148
6000static const struct hnae3_ae_ops hclge_ops = { 6149static const struct hnae3_ae_ops hclge_ops = {
6001 .init_ae_dev = hclge_init_ae_dev, 6150 .init_ae_dev = hclge_init_ae_dev,
6002 .uninit_ae_dev = hclge_uninit_ae_dev, 6151 .uninit_ae_dev = hclge_uninit_ae_dev,
@@ -6005,6 +6154,7 @@ static const struct hnae3_ae_ops hclge_ops = {
6005 .map_ring_to_vector = hclge_map_ring_to_vector, 6154 .map_ring_to_vector = hclge_map_ring_to_vector,
6006 .unmap_ring_from_vector = hclge_unmap_ring_frm_vector, 6155 .unmap_ring_from_vector = hclge_unmap_ring_frm_vector,
6007 .get_vector = hclge_get_vector, 6156 .get_vector = hclge_get_vector,
6157 .put_vector = hclge_put_vector,
6008 .set_promisc_mode = hclge_set_promisc_mode, 6158 .set_promisc_mode = hclge_set_promisc_mode,
6009 .set_loopback = hclge_set_loopback, 6159 .set_loopback = hclge_set_loopback,
6010 .start = hclge_ae_start, 6160 .start = hclge_ae_start,
@@ -6051,6 +6201,8 @@ static const struct hnae3_ae_ops hclge_ops = {
6051 .get_regs_len = hclge_get_regs_len, 6201 .get_regs_len = hclge_get_regs_len,
6052 .get_regs = hclge_get_regs, 6202 .get_regs = hclge_get_regs,
6053 .set_led_id = hclge_set_led_id, 6203 .set_led_id = hclge_set_led_id,
6204 .get_link_mode = hclge_get_link_mode,
6205 .get_port_type = hclge_get_port_type,
6054}; 6206};
6055 6207
6056static struct hnae3_ae_algo ae_algo = { 6208static struct hnae3_ae_algo ae_algo = {
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
index d99a76a9557c..0f4157e71282 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
@@ -106,6 +106,12 @@
106#define HCLGE_MAC_MIN_FRAME 64 106#define HCLGE_MAC_MIN_FRAME 64
107#define HCLGE_MAC_MAX_FRAME 9728 107#define HCLGE_MAC_MAX_FRAME 9728
108 108
109#define HCLGE_SUPPORT_1G_BIT BIT(0)
110#define HCLGE_SUPPORT_10G_BIT BIT(1)
111#define HCLGE_SUPPORT_25G_BIT BIT(2)
112#define HCLGE_SUPPORT_50G_BIT BIT(3)
113#define HCLGE_SUPPORT_100G_BIT BIT(4)
114
109enum HCLGE_DEV_STATE { 115enum HCLGE_DEV_STATE {
110 HCLGE_STATE_REINITING, 116 HCLGE_STATE_REINITING,
111 HCLGE_STATE_DOWN, 117 HCLGE_STATE_DOWN,
@@ -170,6 +176,8 @@ struct hclge_mac {
170 struct phy_device *phydev; 176 struct phy_device *phydev;
171 struct mii_bus *mdio_bus; 177 struct mii_bus *mdio_bus;
172 phy_interface_t phy_if; 178 phy_interface_t phy_if;
179 __ETHTOOL_DECLARE_LINK_MODE_MASK(supported);
180 __ETHTOOL_DECLARE_LINK_MODE_MASK(advertising);
173}; 181};
174 182
175struct hclge_hw { 183struct hclge_hw {
@@ -236,6 +244,7 @@ struct hclge_cfg {
236 u8 mac_addr[ETH_ALEN]; 244 u8 mac_addr[ETH_ALEN];
237 u8 default_speed; 245 u8 default_speed;
238 u32 numa_node_map; 246 u32 numa_node_map;
247 u8 speed_ability;
239}; 248};
240 249
241struct hclge_tm_info { 250struct hclge_tm_info {
@@ -573,12 +582,27 @@ struct hclge_rx_vtag_cfg {
573 bool vlan2_vlan_prionly;/* Outer VLAN Tag up to descriptor Enable */ 582 bool vlan2_vlan_prionly;/* Outer VLAN Tag up to descriptor Enable */
574}; 583};
575 584
585struct hclge_rss_tuple_cfg {
586 u8 ipv4_tcp_en;
587 u8 ipv4_udp_en;
588 u8 ipv4_sctp_en;
589 u8 ipv4_fragment_en;
590 u8 ipv6_tcp_en;
591 u8 ipv6_udp_en;
592 u8 ipv6_sctp_en;
593 u8 ipv6_fragment_en;
594};
595
576struct hclge_vport { 596struct hclge_vport {
577 u16 alloc_tqps; /* Allocated Tx/Rx queues */ 597 u16 alloc_tqps; /* Allocated Tx/Rx queues */
578 598
579 u8 rss_hash_key[HCLGE_RSS_KEY_SIZE]; /* User configured hash keys */ 599 u8 rss_hash_key[HCLGE_RSS_KEY_SIZE]; /* User configured hash keys */
580 /* User configured lookup table entries */ 600 /* User configured lookup table entries */
581 u8 rss_indirection_tbl[HCLGE_RSS_IND_TBL_SIZE]; 601 u8 rss_indirection_tbl[HCLGE_RSS_IND_TBL_SIZE];
602 int rss_algo; /* User configured hash algorithm */
603 /* User configured rss tuple sets */
604 struct hclge_rss_tuple_cfg rss_tuple_sets;
605
582 u16 alloc_rss_size; 606 u16 alloc_rss_size;
583 607
584 u16 qs_offset; 608 u16 qs_offset;
@@ -627,8 +651,11 @@ int hclge_set_vf_vlan_common(struct hclge_dev *vport, int vfid,
627 651
628int hclge_buffer_alloc(struct hclge_dev *hdev); 652int hclge_buffer_alloc(struct hclge_dev *hdev);
629int hclge_rss_init_hw(struct hclge_dev *hdev); 653int hclge_rss_init_hw(struct hclge_dev *hdev);
654void hclge_rss_indir_init_cfg(struct hclge_dev *hdev);
630 655
631void hclge_mbx_handler(struct hclge_dev *hdev); 656void hclge_mbx_handler(struct hclge_dev *hdev);
632void hclge_reset_tqp(struct hnae3_handle *handle, u16 queue_id); 657void hclge_reset_tqp(struct hnae3_handle *handle, u16 queue_id);
658void hclge_reset_vf_queue(struct hclge_vport *vport, u16 queue_id);
633int hclge_cfg_flowctrl(struct hclge_dev *hdev); 659int hclge_cfg_flowctrl(struct hclge_dev *hdev);
660int hclge_func_reset_cmd(struct hclge_dev *hdev, int func_id);
634#endif 661#endif
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
index f38fc5ce9f51..39013334a613 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
@@ -79,6 +79,18 @@ static int hclge_send_mbx_msg(struct hclge_vport *vport, u8 *msg, u16 msg_len,
79 return status; 79 return status;
80} 80}
81 81
82int hclge_inform_reset_assert_to_vf(struct hclge_vport *vport)
83{
84 u8 msg_data[2];
85 u8 dest_vfid;
86
87 dest_vfid = (u8)vport->vport_id;
88
89 /* send this requested info to VF */
90 return hclge_send_mbx_msg(vport, msg_data, sizeof(u8),
91 HCLGE_MBX_ASSERTING_RESET, dest_vfid);
92}
93
82static void hclge_free_vector_ring_chain(struct hnae3_ring_chain_node *head) 94static void hclge_free_vector_ring_chain(struct hnae3_ring_chain_node *head)
83{ 95{
84 struct hnae3_ring_chain_node *chain_tmp, *chain; 96 struct hnae3_ring_chain_node *chain_tmp, *chain;
@@ -105,14 +117,17 @@ static int hclge_get_ring_chain_from_mbx(
105 struct hnae3_ring_chain_node *ring_chain, 117 struct hnae3_ring_chain_node *ring_chain,
106 struct hclge_vport *vport) 118 struct hclge_vport *vport)
107{ 119{
108#define HCLGE_RING_NODE_VARIABLE_NUM 3
109#define HCLGE_RING_MAP_MBX_BASIC_MSG_NUM 3
110 struct hnae3_ring_chain_node *cur_chain, *new_chain; 120 struct hnae3_ring_chain_node *cur_chain, *new_chain;
111 int ring_num; 121 int ring_num;
112 int i; 122 int i;
113 123
114 ring_num = req->msg[2]; 124 ring_num = req->msg[2];
115 125
126 if (ring_num > ((HCLGE_MBX_VF_MSG_DATA_NUM -
127 HCLGE_MBX_RING_MAP_BASIC_MSG_NUM) /
128 HCLGE_MBX_RING_NODE_VARIABLE_NUM))
129 return -ENOMEM;
130
116 hnae_set_bit(ring_chain->flag, HNAE3_RING_TYPE_B, req->msg[3]); 131 hnae_set_bit(ring_chain->flag, HNAE3_RING_TYPE_B, req->msg[3]);
117 ring_chain->tqp_index = 132 ring_chain->tqp_index =
118 hclge_get_queue_id(vport->nic.kinfo.tqp[req->msg[4]]); 133 hclge_get_queue_id(vport->nic.kinfo.tqp[req->msg[4]]);
@@ -128,18 +143,18 @@ static int hclge_get_ring_chain_from_mbx(
128 goto err; 143 goto err;
129 144
130 hnae_set_bit(new_chain->flag, HNAE3_RING_TYPE_B, 145 hnae_set_bit(new_chain->flag, HNAE3_RING_TYPE_B,
131 req->msg[HCLGE_RING_NODE_VARIABLE_NUM * i + 146 req->msg[HCLGE_MBX_RING_NODE_VARIABLE_NUM * i +
132 HCLGE_RING_MAP_MBX_BASIC_MSG_NUM]); 147 HCLGE_MBX_RING_MAP_BASIC_MSG_NUM]);
133 148
134 new_chain->tqp_index = 149 new_chain->tqp_index =
135 hclge_get_queue_id(vport->nic.kinfo.tqp 150 hclge_get_queue_id(vport->nic.kinfo.tqp
136 [req->msg[HCLGE_RING_NODE_VARIABLE_NUM * i + 151 [req->msg[HCLGE_MBX_RING_NODE_VARIABLE_NUM * i +
137 HCLGE_RING_MAP_MBX_BASIC_MSG_NUM + 1]]); 152 HCLGE_MBX_RING_MAP_BASIC_MSG_NUM + 1]]);
138 153
139 hnae_set_field(new_chain->int_gl_idx, HCLGE_INT_GL_IDX_M, 154 hnae_set_field(new_chain->int_gl_idx, HCLGE_INT_GL_IDX_M,
140 HCLGE_INT_GL_IDX_S, 155 HCLGE_INT_GL_IDX_S,
141 req->msg[HCLGE_RING_NODE_VARIABLE_NUM * i + 156 req->msg[HCLGE_MBX_RING_NODE_VARIABLE_NUM * i +
142 HCLGE_RING_MAP_MBX_BASIC_MSG_NUM + 2]); 157 HCLGE_MBX_RING_MAP_BASIC_MSG_NUM + 2]);
143 158
144 cur_chain->next = new_chain; 159 cur_chain->next = new_chain;
145 cur_chain = new_chain; 160 cur_chain = new_chain;
@@ -196,6 +211,8 @@ static int hclge_set_vf_uc_mac_addr(struct hclge_vport *vport,
196 211
197 hclge_rm_uc_addr_common(vport, old_addr); 212 hclge_rm_uc_addr_common(vport, old_addr);
198 status = hclge_add_uc_addr_common(vport, mac_addr); 213 status = hclge_add_uc_addr_common(vport, mac_addr);
214 if (status)
215 hclge_add_uc_addr_common(vport, old_addr);
199 } else if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_UC_ADD) { 216 } else if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_UC_ADD) {
200 status = hclge_add_uc_addr_common(vport, mac_addr); 217 status = hclge_add_uc_addr_common(vport, mac_addr);
201 } else if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_UC_REMOVE) { 218 } else if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_UC_REMOVE) {
@@ -291,7 +308,7 @@ static int hclge_get_vf_queue_info(struct hclge_vport *vport,
291 308
292 /* get the queue related info */ 309 /* get the queue related info */
293 memcpy(&resp_data[0], &vport->alloc_tqps, sizeof(u16)); 310 memcpy(&resp_data[0], &vport->alloc_tqps, sizeof(u16));
294 memcpy(&resp_data[2], &hdev->rss_size_max, sizeof(u16)); 311 memcpy(&resp_data[2], &vport->nic.kinfo.rss_size, sizeof(u16));
295 memcpy(&resp_data[4], &hdev->num_desc, sizeof(u16)); 312 memcpy(&resp_data[4], &hdev->num_desc, sizeof(u16));
296 memcpy(&resp_data[6], &hdev->rx_buf_len, sizeof(u16)); 313 memcpy(&resp_data[6], &hdev->rx_buf_len, sizeof(u16));
297 314
@@ -304,27 +321,61 @@ static int hclge_get_link_info(struct hclge_vport *vport,
304{ 321{
305 struct hclge_dev *hdev = vport->back; 322 struct hclge_dev *hdev = vport->back;
306 u16 link_status; 323 u16 link_status;
307 u8 msg_data[2]; 324 u8 msg_data[8];
308 u8 dest_vfid; 325 u8 dest_vfid;
326 u16 duplex;
309 327
310 /* mac.link can only be 0 or 1 */ 328 /* mac.link can only be 0 or 1 */
311 link_status = (u16)hdev->hw.mac.link; 329 link_status = (u16)hdev->hw.mac.link;
330 duplex = hdev->hw.mac.duplex;
312 memcpy(&msg_data[0], &link_status, sizeof(u16)); 331 memcpy(&msg_data[0], &link_status, sizeof(u16));
332 memcpy(&msg_data[2], &hdev->hw.mac.speed, sizeof(u32));
333 memcpy(&msg_data[6], &duplex, sizeof(u16));
313 dest_vfid = mbx_req->mbx_src_vfid; 334 dest_vfid = mbx_req->mbx_src_vfid;
314 335
315 /* send this requested info to VF */ 336 /* send this requested info to VF */
316 return hclge_send_mbx_msg(vport, msg_data, sizeof(u8), 337 return hclge_send_mbx_msg(vport, msg_data, sizeof(msg_data),
317 HCLGE_MBX_LINK_STAT_CHANGE, dest_vfid); 338 HCLGE_MBX_LINK_STAT_CHANGE, dest_vfid);
318} 339}
319 340
320static void hclge_reset_vf_queue(struct hclge_vport *vport, 341static void hclge_mbx_reset_vf_queue(struct hclge_vport *vport,
321 struct hclge_mbx_vf_to_pf_cmd *mbx_req) 342 struct hclge_mbx_vf_to_pf_cmd *mbx_req)
322{ 343{
323 u16 queue_id; 344 u16 queue_id;
324 345
325 memcpy(&queue_id, &mbx_req->msg[2], sizeof(queue_id)); 346 memcpy(&queue_id, &mbx_req->msg[2], sizeof(queue_id));
326 347
327 hclge_reset_tqp(&vport->nic, queue_id); 348 hclge_reset_vf_queue(vport, queue_id);
349
350 /* send response msg to VF after queue reset complete*/
351 hclge_gen_resp_to_vf(vport, mbx_req, 0, NULL, 0);
352}
353
354static void hclge_reset_vf(struct hclge_vport *vport,
355 struct hclge_mbx_vf_to_pf_cmd *mbx_req)
356{
357 struct hclge_dev *hdev = vport->back;
358 int ret;
359
360 dev_warn(&hdev->pdev->dev, "PF received VF reset request from VF %d!",
361 mbx_req->mbx_src_vfid);
362
363 /* Acknowledge VF that PF is now about to assert the reset for the VF.
364 * On receiving this message VF will get into pending state and will
365 * start polling for the hardware reset completion status.
366 */
367 ret = hclge_inform_reset_assert_to_vf(vport);
368 if (ret) {
369 dev_err(&hdev->pdev->dev,
370 "PF fail(%d) to inform VF(%d)of reset, reset failed!\n",
371 ret, vport->vport_id);
372 return;
373 }
374
375 dev_warn(&hdev->pdev->dev, "PF is now resetting VF %d.\n",
376 mbx_req->mbx_src_vfid);
377 /* reset this virtual function */
378 hclge_func_reset_cmd(hdev, mbx_req->mbx_src_vfid);
328} 379}
329 380
330void hclge_mbx_handler(struct hclge_dev *hdev) 381void hclge_mbx_handler(struct hclge_dev *hdev)
@@ -333,11 +384,11 @@ void hclge_mbx_handler(struct hclge_dev *hdev)
333 struct hclge_mbx_vf_to_pf_cmd *req; 384 struct hclge_mbx_vf_to_pf_cmd *req;
334 struct hclge_vport *vport; 385 struct hclge_vport *vport;
335 struct hclge_desc *desc; 386 struct hclge_desc *desc;
336 int ret; 387 int ret, flag;
337 388
389 flag = le16_to_cpu(crq->desc[crq->next_to_use].flag);
338 /* handle all the mailbox requests in the queue */ 390 /* handle all the mailbox requests in the queue */
339 while (hnae_get_bit(crq->desc[crq->next_to_use].flag, 391 while (hnae_get_bit(flag, HCLGE_CMDQ_RX_OUTVLD_B)) {
340 HCLGE_CMDQ_RX_OUTVLD_B)) {
341 desc = &crq->desc[crq->next_to_use]; 392 desc = &crq->desc[crq->next_to_use];
342 req = (struct hclge_mbx_vf_to_pf_cmd *)desc->data; 393 req = (struct hclge_mbx_vf_to_pf_cmd *)desc->data;
343 394
@@ -360,7 +411,7 @@ void hclge_mbx_handler(struct hclge_dev *hdev)
360 ret); 411 ret);
361 break; 412 break;
362 case HCLGE_MBX_SET_UNICAST: 413 case HCLGE_MBX_SET_UNICAST:
363 ret = hclge_set_vf_uc_mac_addr(vport, req, false); 414 ret = hclge_set_vf_uc_mac_addr(vport, req, true);
364 if (ret) 415 if (ret)
365 dev_err(&hdev->pdev->dev, 416 dev_err(&hdev->pdev->dev,
366 "PF fail(%d) to set VF UC MAC Addr\n", 417 "PF fail(%d) to set VF UC MAC Addr\n",
@@ -402,7 +453,10 @@ void hclge_mbx_handler(struct hclge_dev *hdev)
402 ret); 453 ret);
403 break; 454 break;
404 case HCLGE_MBX_QUEUE_RESET: 455 case HCLGE_MBX_QUEUE_RESET:
405 hclge_reset_vf_queue(vport, req); 456 hclge_mbx_reset_vf_queue(vport, req);
457 break;
458 case HCLGE_MBX_RESET:
459 hclge_reset_vf(vport, req);
406 break; 460 break;
407 default: 461 default:
408 dev_err(&hdev->pdev->dev, 462 dev_err(&hdev->pdev->dev,
@@ -410,7 +464,9 @@ void hclge_mbx_handler(struct hclge_dev *hdev)
410 req->msg[0]); 464 req->msg[0]);
411 break; 465 break;
412 } 466 }
467 crq->desc[crq->next_to_use].flag = 0;
413 hclge_mbx_ring_ptr_move_crq(crq); 468 hclge_mbx_ring_ptr_move_crq(crq);
469 flag = le16_to_cpu(crq->desc[crq->next_to_use].flag);
414 } 470 }
415 471
416 /* Write back CMDQ_RQ header pointer, M7 need this pointer */ 472 /* Write back CMDQ_RQ header pointer, M7 need this pointer */
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
index 36bd79a77940..885f25cd7be4 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
@@ -23,6 +23,9 @@ enum hclge_shaper_level {
23 HCLGE_SHAPER_LVL_PF = 1, 23 HCLGE_SHAPER_LVL_PF = 1,
24}; 24};
25 25
26#define HCLGE_TM_PFC_PKT_GET_CMD_NUM 3
27#define HCLGE_TM_PFC_NUM_GET_PER_CMD 3
28
26#define HCLGE_SHAPER_BS_U_DEF 5 29#define HCLGE_SHAPER_BS_U_DEF 5
27#define HCLGE_SHAPER_BS_S_DEF 20 30#define HCLGE_SHAPER_BS_S_DEF 20
28 31
@@ -112,6 +115,56 @@ static int hclge_shaper_para_calc(u32 ir, u8 shaper_level,
112 return 0; 115 return 0;
113} 116}
114 117
118static int hclge_pfc_stats_get(struct hclge_dev *hdev,
119 enum hclge_opcode_type opcode, u64 *stats)
120{
121 struct hclge_desc desc[HCLGE_TM_PFC_PKT_GET_CMD_NUM];
122 int ret, i, j;
123
124 if (!(opcode == HCLGE_OPC_QUERY_PFC_RX_PKT_CNT ||
125 opcode == HCLGE_OPC_QUERY_PFC_TX_PKT_CNT))
126 return -EINVAL;
127
128 for (i = 0; i < HCLGE_TM_PFC_PKT_GET_CMD_NUM; i++) {
129 hclge_cmd_setup_basic_desc(&desc[i], opcode, true);
130 if (i != (HCLGE_TM_PFC_PKT_GET_CMD_NUM - 1))
131 desc[i].flag |= cpu_to_le16(HCLGE_CMD_FLAG_NEXT);
132 else
133 desc[i].flag &= ~cpu_to_le16(HCLGE_CMD_FLAG_NEXT);
134 }
135
136 ret = hclge_cmd_send(&hdev->hw, desc, HCLGE_TM_PFC_PKT_GET_CMD_NUM);
137 if (ret) {
138 dev_err(&hdev->pdev->dev,
139 "Get pfc pause stats fail, ret = %d.\n", ret);
140 return ret;
141 }
142
143 for (i = 0; i < HCLGE_TM_PFC_PKT_GET_CMD_NUM; i++) {
144 struct hclge_pfc_stats_cmd *pfc_stats =
145 (struct hclge_pfc_stats_cmd *)desc[i].data;
146
147 for (j = 0; j < HCLGE_TM_PFC_NUM_GET_PER_CMD; j++) {
148 u32 index = i * HCLGE_TM_PFC_PKT_GET_CMD_NUM + j;
149
150 if (index < HCLGE_MAX_TC_NUM)
151 stats[index] =
152 le64_to_cpu(pfc_stats->pkt_num[j]);
153 }
154 }
155 return 0;
156}
157
158int hclge_pfc_rx_stats_get(struct hclge_dev *hdev, u64 *stats)
159{
160 return hclge_pfc_stats_get(hdev, HCLGE_OPC_QUERY_PFC_RX_PKT_CNT, stats);
161}
162
163int hclge_pfc_tx_stats_get(struct hclge_dev *hdev, u64 *stats)
164{
165 return hclge_pfc_stats_get(hdev, HCLGE_OPC_QUERY_PFC_TX_PKT_CNT, stats);
166}
167
115int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, bool tx, bool rx) 168int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, bool tx, bool rx)
116{ 169{
117 struct hclge_desc desc; 170 struct hclge_desc desc;
@@ -138,8 +191,8 @@ static int hclge_pfc_pause_en_cfg(struct hclge_dev *hdev, u8 tx_rx_bitmap,
138 return hclge_cmd_send(&hdev->hw, &desc, 1); 191 return hclge_cmd_send(&hdev->hw, &desc, 1);
139} 192}
140 193
141static int hclge_mac_pause_param_cfg(struct hclge_dev *hdev, const u8 *addr, 194static int hclge_pause_param_cfg(struct hclge_dev *hdev, const u8 *addr,
142 u8 pause_trans_gap, u16 pause_trans_time) 195 u8 pause_trans_gap, u16 pause_trans_time)
143{ 196{
144 struct hclge_cfg_pause_param_cmd *pause_param; 197 struct hclge_cfg_pause_param_cmd *pause_param;
145 struct hclge_desc desc; 198 struct hclge_desc desc;
@@ -155,7 +208,7 @@ static int hclge_mac_pause_param_cfg(struct hclge_dev *hdev, const u8 *addr,
155 return hclge_cmd_send(&hdev->hw, &desc, 1); 208 return hclge_cmd_send(&hdev->hw, &desc, 1);
156} 209}
157 210
158int hclge_mac_pause_addr_cfg(struct hclge_dev *hdev, const u8 *mac_addr) 211int hclge_pause_addr_cfg(struct hclge_dev *hdev, const u8 *mac_addr)
159{ 212{
160 struct hclge_cfg_pause_param_cmd *pause_param; 213 struct hclge_cfg_pause_param_cmd *pause_param;
161 struct hclge_desc desc; 214 struct hclge_desc desc;
@@ -174,7 +227,7 @@ int hclge_mac_pause_addr_cfg(struct hclge_dev *hdev, const u8 *mac_addr)
174 trans_gap = pause_param->pause_trans_gap; 227 trans_gap = pause_param->pause_trans_gap;
175 trans_time = le16_to_cpu(pause_param->pause_trans_time); 228 trans_time = le16_to_cpu(pause_param->pause_trans_time);
176 229
177 return hclge_mac_pause_param_cfg(hdev, mac_addr, trans_gap, 230 return hclge_pause_param_cfg(hdev, mac_addr, trans_gap,
178 trans_time); 231 trans_time);
179} 232}
180 233
@@ -1096,11 +1149,11 @@ static int hclge_tm_schd_setup_hw(struct hclge_dev *hdev)
1096 return hclge_tm_schd_mode_hw(hdev); 1149 return hclge_tm_schd_mode_hw(hdev);
1097} 1150}
1098 1151
1099static int hclge_mac_pause_param_setup_hw(struct hclge_dev *hdev) 1152static int hclge_pause_param_setup_hw(struct hclge_dev *hdev)
1100{ 1153{
1101 struct hclge_mac *mac = &hdev->hw.mac; 1154 struct hclge_mac *mac = &hdev->hw.mac;
1102 1155
1103 return hclge_mac_pause_param_cfg(hdev, mac->mac_addr, 1156 return hclge_pause_param_cfg(hdev, mac->mac_addr,
1104 HCLGE_DEFAULT_PAUSE_TRANS_GAP, 1157 HCLGE_DEFAULT_PAUSE_TRANS_GAP,
1105 HCLGE_DEFAULT_PAUSE_TRANS_TIME); 1158 HCLGE_DEFAULT_PAUSE_TRANS_TIME);
1106} 1159}
@@ -1151,13 +1204,12 @@ int hclge_pause_setup_hw(struct hclge_dev *hdev)
1151 int ret; 1204 int ret;
1152 u8 i; 1205 u8 i;
1153 1206
1154 if (hdev->tm_info.fc_mode != HCLGE_FC_PFC) { 1207 ret = hclge_pause_param_setup_hw(hdev);
1155 ret = hclge_mac_pause_setup_hw(hdev); 1208 if (ret)
1156 if (ret) 1209 return ret;
1157 return ret;
1158 1210
1159 return hclge_mac_pause_param_setup_hw(hdev); 1211 if (hdev->tm_info.fc_mode != HCLGE_FC_PFC)
1160 } 1212 return hclge_mac_pause_setup_hw(hdev);
1161 1213
1162 /* Only DCB-supported dev supports qset back pressure and pfc cmd */ 1214 /* Only DCB-supported dev supports qset back pressure and pfc cmd */
1163 if (!hnae3_dev_dcb_supported(hdev)) 1215 if (!hnae3_dev_dcb_supported(hdev))
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
index 5401e7559437..2dbe177581e9 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
@@ -109,6 +109,10 @@ struct hclge_cfg_pause_param_cmd {
109 __le16 pause_trans_time; 109 __le16 pause_trans_time;
110}; 110};
111 111
112struct hclge_pfc_stats_cmd {
113 __le64 pkt_num[3];
114};
115
112struct hclge_port_shapping_cmd { 116struct hclge_port_shapping_cmd {
113 __le32 port_shapping_para; 117 __le32 port_shapping_para;
114}; 118};
@@ -129,5 +133,7 @@ int hclge_tm_dwrr_cfg(struct hclge_dev *hdev);
129int hclge_tm_map_cfg(struct hclge_dev *hdev); 133int hclge_tm_map_cfg(struct hclge_dev *hdev);
130int hclge_tm_init_hw(struct hclge_dev *hdev); 134int hclge_tm_init_hw(struct hclge_dev *hdev);
131int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, bool tx, bool rx); 135int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, bool tx, bool rx);
132int hclge_mac_pause_addr_cfg(struct hclge_dev *hdev, const u8 *mac_addr); 136int hclge_pause_addr_cfg(struct hclge_dev *hdev, const u8 *mac_addr);
137int hclge_pfc_rx_stats_get(struct hclge_dev *hdev, u64 *stats);
138int hclge_pfc_tx_stats_get(struct hclge_dev *hdev, u64 *stats);
133#endif 139#endif
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c
index 85985e731311..1bbfe131b596 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c
@@ -315,6 +315,12 @@ int hclgevf_cmd_init(struct hclgevf_dev *hdev)
315 goto err_csq; 315 goto err_csq;
316 } 316 }
317 317
318 /* initialize the pointers of async rx queue of mailbox */
319 hdev->arq.hdev = hdev;
320 hdev->arq.head = 0;
321 hdev->arq.tail = 0;
322 hdev->arq.count = 0;
323
318 /* get firmware version */ 324 /* get firmware version */
319 ret = hclgevf_cmd_query_firmware_version(&hdev->hw, &version); 325 ret = hclgevf_cmd_query_firmware_version(&hdev->hw, &version);
320 if (ret) { 326 if (ret) {
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h
index 2caca9317f8c..621c6cbacf76 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h
@@ -7,7 +7,7 @@
7#include <linux/types.h> 7#include <linux/types.h>
8#include "hnae3.h" 8#include "hnae3.h"
9 9
10#define HCLGEVF_CMDQ_TX_TIMEOUT 200 10#define HCLGEVF_CMDQ_TX_TIMEOUT 30000
11#define HCLGEVF_CMDQ_RX_INVLD_B 0 11#define HCLGEVF_CMDQ_RX_INVLD_B 0
12#define HCLGEVF_CMDQ_RX_OUTVLD_B 1 12#define HCLGEVF_CMDQ_RX_OUTVLD_B 1
13 13
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
index 0d89965f7928..2b8426412cc9 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
@@ -2,6 +2,7 @@
2// Copyright (c) 2016-2017 Hisilicon Limited. 2// Copyright (c) 2016-2017 Hisilicon Limited.
3 3
4#include <linux/etherdevice.h> 4#include <linux/etherdevice.h>
5#include <net/rtnetlink.h>
5#include "hclgevf_cmd.h" 6#include "hclgevf_cmd.h"
6#include "hclgevf_main.h" 7#include "hclgevf_main.h"
7#include "hclge_mbx.h" 8#include "hclge_mbx.h"
@@ -9,6 +10,8 @@
9 10
10#define HCLGEVF_NAME "hclgevf" 11#define HCLGEVF_NAME "hclgevf"
11 12
13static int hclgevf_init_hdev(struct hclgevf_dev *hdev);
14static void hclgevf_uninit_hdev(struct hclgevf_dev *hdev);
12static struct hnae3_ae_algo ae_algovf; 15static struct hnae3_ae_algo ae_algovf;
13 16
14static const struct pci_device_id ae_algovf_pci_tbl[] = { 17static const struct pci_device_id ae_algovf_pci_tbl[] = {
@@ -18,6 +21,8 @@ static const struct pci_device_id ae_algovf_pci_tbl[] = {
18 {0, } 21 {0, }
19}; 22};
20 23
24MODULE_DEVICE_TABLE(pci, ae_algovf_pci_tbl);
25
21static inline struct hclgevf_dev *hclgevf_ae_get_hdev( 26static inline struct hclgevf_dev *hclgevf_ae_get_hdev(
22 struct hnae3_handle *handle) 27 struct hnae3_handle *handle)
23{ 28{
@@ -206,6 +211,12 @@ static int hclgevf_alloc_tqps(struct hclgevf_dev *hdev)
206 struct hclgevf_tqp *tqp; 211 struct hclgevf_tqp *tqp;
207 int i; 212 int i;
208 213
214 /* if this is on going reset then we need to re-allocate the TPQs
215 * since we cannot assume we would get same number of TPQs back from PF
216 */
217 if (hclgevf_dev_ongoing_reset(hdev))
218 devm_kfree(&hdev->pdev->dev, hdev->htqp);
219
209 hdev->htqp = devm_kcalloc(&hdev->pdev->dev, hdev->num_tqps, 220 hdev->htqp = devm_kcalloc(&hdev->pdev->dev, hdev->num_tqps,
210 sizeof(struct hclgevf_tqp), GFP_KERNEL); 221 sizeof(struct hclgevf_tqp), GFP_KERNEL);
211 if (!hdev->htqp) 222 if (!hdev->htqp)
@@ -249,6 +260,12 @@ static int hclgevf_knic_setup(struct hclgevf_dev *hdev)
249 new_tqps = kinfo->rss_size * kinfo->num_tc; 260 new_tqps = kinfo->rss_size * kinfo->num_tc;
250 kinfo->num_tqps = min(new_tqps, hdev->num_tqps); 261 kinfo->num_tqps = min(new_tqps, hdev->num_tqps);
251 262
263 /* if this is on going reset then we need to re-allocate the hnae queues
264 * as well since number of TPQs from PF might have changed.
265 */
266 if (hclgevf_dev_ongoing_reset(hdev))
267 devm_kfree(&hdev->pdev->dev, kinfo->tqp);
268
252 kinfo->tqp = devm_kcalloc(&hdev->pdev->dev, kinfo->num_tqps, 269 kinfo->tqp = devm_kcalloc(&hdev->pdev->dev, kinfo->num_tqps,
253 sizeof(struct hnae3_queue *), GFP_KERNEL); 270 sizeof(struct hnae3_queue *), GFP_KERNEL);
254 if (!kinfo->tqp) 271 if (!kinfo->tqp)
@@ -533,13 +550,11 @@ static int hclgevf_bind_ring_to_vector(struct hnae3_handle *handle, bool en,
533 int vector, 550 int vector,
534 struct hnae3_ring_chain_node *ring_chain) 551 struct hnae3_ring_chain_node *ring_chain)
535{ 552{
536#define HCLGEVF_RING_NODE_VARIABLE_NUM 3
537#define HCLGEVF_RING_MAP_MBX_BASIC_MSG_NUM 3
538 struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 553 struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
539 struct hnae3_ring_chain_node *node; 554 struct hnae3_ring_chain_node *node;
540 struct hclge_mbx_vf_to_pf_cmd *req; 555 struct hclge_mbx_vf_to_pf_cmd *req;
541 struct hclgevf_desc desc; 556 struct hclgevf_desc desc;
542 int i, vector_id; 557 int i = 0, vector_id;
543 int status; 558 int status;
544 u8 type; 559 u8 type;
545 560
@@ -551,28 +566,33 @@ static int hclgevf_bind_ring_to_vector(struct hnae3_handle *handle, bool en,
551 return vector_id; 566 return vector_id;
552 } 567 }
553 568
554 hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_MBX_VF_TO_PF, false);
555 type = en ?
556 HCLGE_MBX_MAP_RING_TO_VECTOR : HCLGE_MBX_UNMAP_RING_TO_VECTOR;
557 req->msg[0] = type;
558 req->msg[1] = vector_id; /* vector_id should be id in VF */
559
560 i = 0;
561 for (node = ring_chain; node; node = node->next) { 569 for (node = ring_chain; node; node = node->next) {
562 i++; 570 int idx_offset = HCLGE_MBX_RING_MAP_BASIC_MSG_NUM +
563 /* msg[2] is cause num */ 571 HCLGE_MBX_RING_NODE_VARIABLE_NUM * i;
564 req->msg[HCLGEVF_RING_NODE_VARIABLE_NUM * i] = 572
573 if (i == 0) {
574 hclgevf_cmd_setup_basic_desc(&desc,
575 HCLGEVF_OPC_MBX_VF_TO_PF,
576 false);
577 type = en ?
578 HCLGE_MBX_MAP_RING_TO_VECTOR :
579 HCLGE_MBX_UNMAP_RING_TO_VECTOR;
580 req->msg[0] = type;
581 req->msg[1] = vector_id;
582 }
583
584 req->msg[idx_offset] =
565 hnae_get_bit(node->flag, HNAE3_RING_TYPE_B); 585 hnae_get_bit(node->flag, HNAE3_RING_TYPE_B);
566 req->msg[HCLGEVF_RING_NODE_VARIABLE_NUM * i + 1] = 586 req->msg[idx_offset + 1] = node->tqp_index;
567 node->tqp_index; 587 req->msg[idx_offset + 2] = hnae_get_field(node->int_gl_idx,
568 req->msg[HCLGEVF_RING_NODE_VARIABLE_NUM * i + 2] = 588 HNAE3_RING_GL_IDX_M,
569 hnae_get_field(node->int_gl_idx, 589 HNAE3_RING_GL_IDX_S);
570 HNAE3_RING_GL_IDX_M, 590
571 HNAE3_RING_GL_IDX_S); 591 i++;
572 592 if ((i == (HCLGE_MBX_VF_MSG_DATA_NUM -
573 if (i == (HCLGE_MBX_VF_MSG_DATA_NUM - 593 HCLGE_MBX_RING_MAP_BASIC_MSG_NUM) /
574 HCLGEVF_RING_MAP_MBX_BASIC_MSG_NUM) / 594 HCLGE_MBX_RING_NODE_VARIABLE_NUM) ||
575 HCLGEVF_RING_NODE_VARIABLE_NUM) { 595 !node->next) {
576 req->msg[2] = i; 596 req->msg[2] = i;
577 597
578 status = hclgevf_cmd_send(&hdev->hw, &desc, 1); 598 status = hclgevf_cmd_send(&hdev->hw, &desc, 1);
@@ -591,17 +611,6 @@ static int hclgevf_bind_ring_to_vector(struct hnae3_handle *handle, bool en,
591 } 611 }
592 } 612 }
593 613
594 if (i > 0) {
595 req->msg[2] = i;
596
597 status = hclgevf_cmd_send(&hdev->hw, &desc, 1);
598 if (status) {
599 dev_err(&hdev->pdev->dev,
600 "Map TQP fail, status is %d.\n", status);
601 return status;
602 }
603 }
604
605 return 0; 614 return 0;
606} 615}
607 616
@@ -627,13 +636,18 @@ static int hclgevf_unmap_ring_from_vector(
627 } 636 }
628 637
629 ret = hclgevf_bind_ring_to_vector(handle, false, vector, ring_chain); 638 ret = hclgevf_bind_ring_to_vector(handle, false, vector, ring_chain);
630 if (ret) { 639 if (ret)
631 dev_err(&handle->pdev->dev, 640 dev_err(&handle->pdev->dev,
632 "Unmap ring from vector fail. vector=%d, ret =%d\n", 641 "Unmap ring from vector fail. vector=%d, ret =%d\n",
633 vector_id, 642 vector_id,
634 ret); 643 ret);
635 return ret; 644
636 } 645 return ret;
646}
647
648static int hclgevf_put_vector(struct hnae3_handle *handle, int vector)
649{
650 struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
637 651
638 hclgevf_free_vector(hdev, vector); 652 hclgevf_free_vector(hdev, vector);
639 653
@@ -729,21 +743,25 @@ static void hclgevf_get_mac_addr(struct hnae3_handle *handle, u8 *p)
729 ether_addr_copy(p, hdev->hw.mac.mac_addr); 743 ether_addr_copy(p, hdev->hw.mac.mac_addr);
730} 744}
731 745
732static int hclgevf_set_mac_addr(struct hnae3_handle *handle, void *p) 746static int hclgevf_set_mac_addr(struct hnae3_handle *handle, void *p,
747 bool is_first)
733{ 748{
734 struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 749 struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
735 u8 *old_mac_addr = (u8 *)hdev->hw.mac.mac_addr; 750 u8 *old_mac_addr = (u8 *)hdev->hw.mac.mac_addr;
736 u8 *new_mac_addr = (u8 *)p; 751 u8 *new_mac_addr = (u8 *)p;
737 u8 msg_data[ETH_ALEN * 2]; 752 u8 msg_data[ETH_ALEN * 2];
753 u16 subcode;
738 int status; 754 int status;
739 755
740 ether_addr_copy(msg_data, new_mac_addr); 756 ether_addr_copy(msg_data, new_mac_addr);
741 ether_addr_copy(&msg_data[ETH_ALEN], old_mac_addr); 757 ether_addr_copy(&msg_data[ETH_ALEN], old_mac_addr);
742 758
759 subcode = is_first ? HCLGE_MBX_MAC_VLAN_UC_ADD :
760 HCLGE_MBX_MAC_VLAN_UC_MODIFY;
761
743 status = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_UNICAST, 762 status = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_UNICAST,
744 HCLGE_MBX_MAC_VLAN_UC_MODIFY, 763 subcode, msg_data, ETH_ALEN * 2,
745 msg_data, ETH_ALEN * 2, 764 true, NULL, 0);
746 false, NULL, 0);
747 if (!status) 765 if (!status)
748 ether_addr_copy(hdev->hw.mac.mac_addr, new_mac_addr); 766 ether_addr_copy(hdev->hw.mac.mac_addr, new_mac_addr);
749 767
@@ -816,11 +834,149 @@ static void hclgevf_reset_tqp(struct hnae3_handle *handle, u16 queue_id)
816{ 834{
817 struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 835 struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
818 u8 msg_data[2]; 836 u8 msg_data[2];
837 int ret;
819 838
820 memcpy(&msg_data[0], &queue_id, sizeof(queue_id)); 839 memcpy(&msg_data[0], &queue_id, sizeof(queue_id));
821 840
822 hclgevf_send_mbx_msg(hdev, HCLGE_MBX_QUEUE_RESET, 0, msg_data, 2, false, 841 /* disable vf queue before send queue reset msg to PF */
823 NULL, 0); 842 ret = hclgevf_tqp_enable(hdev, queue_id, 0, false);
843 if (ret)
844 return;
845
846 hclgevf_send_mbx_msg(hdev, HCLGE_MBX_QUEUE_RESET, 0, msg_data,
847 2, true, NULL, 0);
848}
849
850static int hclgevf_notify_client(struct hclgevf_dev *hdev,
851 enum hnae3_reset_notify_type type)
852{
853 struct hnae3_client *client = hdev->nic_client;
854 struct hnae3_handle *handle = &hdev->nic;
855
856 if (!client->ops->reset_notify)
857 return -EOPNOTSUPP;
858
859 return client->ops->reset_notify(handle, type);
860}
861
862static int hclgevf_reset_wait(struct hclgevf_dev *hdev)
863{
864#define HCLGEVF_RESET_WAIT_MS 500
865#define HCLGEVF_RESET_WAIT_CNT 20
866 u32 val, cnt = 0;
867
868 /* wait to check the hardware reset completion status */
869 val = hclgevf_read_dev(&hdev->hw, HCLGEVF_FUN_RST_ING);
870 while (hnae_get_bit(val, HCLGEVF_FUN_RST_ING_B) &&
871 (cnt < HCLGEVF_RESET_WAIT_CNT)) {
872 msleep(HCLGEVF_RESET_WAIT_MS);
873 val = hclgevf_read_dev(&hdev->hw, HCLGEVF_FUN_RST_ING);
874 cnt++;
875 }
876
877 /* hardware completion status should be available by this time */
878 if (cnt >= HCLGEVF_RESET_WAIT_CNT) {
879 dev_warn(&hdev->pdev->dev,
880 "could'nt get reset done status from h/w, timeout!\n");
881 return -EBUSY;
882 }
883
884 /* we will wait a bit more to let reset of the stack to complete. This
885 * might happen in case reset assertion was made by PF. Yes, this also
886 * means we might end up waiting bit more even for VF reset.
887 */
888 msleep(5000);
889
890 return 0;
891}
892
893static int hclgevf_reset_stack(struct hclgevf_dev *hdev)
894{
895 int ret;
896
897 /* uninitialize the nic client */
898 hclgevf_notify_client(hdev, HNAE3_UNINIT_CLIENT);
899
900 /* re-initialize the hclge device */
901 ret = hclgevf_init_hdev(hdev);
902 if (ret) {
903 dev_err(&hdev->pdev->dev,
904 "hclge device re-init failed, VF is disabled!\n");
905 return ret;
906 }
907
908 /* bring up the nic client again */
909 hclgevf_notify_client(hdev, HNAE3_INIT_CLIENT);
910
911 return 0;
912}
913
914static int hclgevf_reset(struct hclgevf_dev *hdev)
915{
916 int ret;
917
918 rtnl_lock();
919
920 /* bring down the nic to stop any ongoing TX/RX */
921 hclgevf_notify_client(hdev, HNAE3_DOWN_CLIENT);
922
923 /* check if VF could successfully fetch the hardware reset completion
924 * status from the hardware
925 */
926 ret = hclgevf_reset_wait(hdev);
927 if (ret) {
928 /* can't do much in this situation, will disable VF */
929 dev_err(&hdev->pdev->dev,
930 "VF failed(=%d) to fetch H/W reset completion status\n",
931 ret);
932
933 dev_warn(&hdev->pdev->dev, "VF reset failed, disabling VF!\n");
934 hclgevf_notify_client(hdev, HNAE3_UNINIT_CLIENT);
935
936 rtnl_unlock();
937 return ret;
938 }
939
940 /* now, re-initialize the nic client and ae device*/
941 ret = hclgevf_reset_stack(hdev);
942 if (ret)
943 dev_err(&hdev->pdev->dev, "failed to reset VF stack\n");
944
945 /* bring up the nic to enable TX/RX again */
946 hclgevf_notify_client(hdev, HNAE3_UP_CLIENT);
947
948 rtnl_unlock();
949
950 return ret;
951}
952
953static int hclgevf_do_reset(struct hclgevf_dev *hdev)
954{
955 int status;
956 u8 respmsg;
957
958 status = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_RESET, 0, NULL,
959 0, false, &respmsg, sizeof(u8));
960 if (status)
961 dev_err(&hdev->pdev->dev,
962 "VF reset request to PF failed(=%d)\n", status);
963
964 return status;
965}
966
967static void hclgevf_reset_event(struct hnae3_handle *handle)
968{
969 struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
970
971 dev_info(&hdev->pdev->dev, "received reset request from VF enet\n");
972
973 handle->reset_level = HNAE3_VF_RESET;
974
975 /* reset of this VF requested */
976 set_bit(HCLGEVF_RESET_REQUESTED, &hdev->reset_state);
977 hclgevf_reset_task_schedule(hdev);
978
979 handle->last_reset_time = jiffies;
824} 980}
825 981
826static u32 hclgevf_get_fw_version(struct hnae3_handle *handle) 982static u32 hclgevf_get_fw_version(struct hnae3_handle *handle)
@@ -845,10 +1001,22 @@ static void hclgevf_get_misc_vector(struct hclgevf_dev *hdev)
845 hdev->num_msi_used += 1; 1001 hdev->num_msi_used += 1;
846} 1002}
847 1003
848static void hclgevf_mbx_task_schedule(struct hclgevf_dev *hdev) 1004void hclgevf_reset_task_schedule(struct hclgevf_dev *hdev)
1005{
1006 if (!test_bit(HCLGEVF_STATE_RST_SERVICE_SCHED, &hdev->state) &&
1007 !test_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state)) {
1008 set_bit(HCLGEVF_STATE_RST_SERVICE_SCHED, &hdev->state);
1009 schedule_work(&hdev->rst_service_task);
1010 }
1011}
1012
1013void hclgevf_mbx_task_schedule(struct hclgevf_dev *hdev)
849{ 1014{
850 if (!test_and_set_bit(HCLGEVF_STATE_MBX_SERVICE_SCHED, &hdev->state)) 1015 if (!test_bit(HCLGEVF_STATE_MBX_SERVICE_SCHED, &hdev->state) &&
1016 !test_bit(HCLGEVF_STATE_MBX_HANDLING, &hdev->state)) {
1017 set_bit(HCLGEVF_STATE_MBX_SERVICE_SCHED, &hdev->state);
851 schedule_work(&hdev->mbx_service_task); 1018 schedule_work(&hdev->mbx_service_task);
1019 }
852} 1020}
853 1021
854static void hclgevf_task_schedule(struct hclgevf_dev *hdev) 1022static void hclgevf_task_schedule(struct hclgevf_dev *hdev)
@@ -858,6 +1026,16 @@ static void hclgevf_task_schedule(struct hclgevf_dev *hdev)
858 schedule_work(&hdev->service_task); 1026 schedule_work(&hdev->service_task);
859} 1027}
860 1028
1029static void hclgevf_deferred_task_schedule(struct hclgevf_dev *hdev)
1030{
1031 /* if we have any pending mailbox event then schedule the mbx task */
1032 if (hdev->mbx_event_pending)
1033 hclgevf_mbx_task_schedule(hdev);
1034
1035 if (test_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state))
1036 hclgevf_reset_task_schedule(hdev);
1037}
1038
861static void hclgevf_service_timer(struct timer_list *t) 1039static void hclgevf_service_timer(struct timer_list *t)
862{ 1040{
863 struct hclgevf_dev *hdev = from_timer(hdev, t, service_timer); 1041 struct hclgevf_dev *hdev = from_timer(hdev, t, service_timer);
@@ -867,6 +1045,75 @@ static void hclgevf_service_timer(struct timer_list *t)
867 hclgevf_task_schedule(hdev); 1045 hclgevf_task_schedule(hdev);
868} 1046}
869 1047
1048static void hclgevf_reset_service_task(struct work_struct *work)
1049{
1050 struct hclgevf_dev *hdev =
1051 container_of(work, struct hclgevf_dev, rst_service_task);
1052 int ret;
1053
1054 if (test_and_set_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state))
1055 return;
1056
1057 clear_bit(HCLGEVF_STATE_RST_SERVICE_SCHED, &hdev->state);
1058
1059 if (test_and_clear_bit(HCLGEVF_RESET_PENDING,
1060 &hdev->reset_state)) {
1061 /* PF has initmated that it is about to reset the hardware.
1062 * We now have to poll & check if harware has actually completed
1063 * the reset sequence. On hardware reset completion, VF needs to
1064 * reset the client and ae device.
1065 */
1066 hdev->reset_attempts = 0;
1067
1068 ret = hclgevf_reset(hdev);
1069 if (ret)
1070 dev_err(&hdev->pdev->dev, "VF stack reset failed.\n");
1071 } else if (test_and_clear_bit(HCLGEVF_RESET_REQUESTED,
1072 &hdev->reset_state)) {
1073 /* we could be here when either of below happens:
1074 * 1. reset was initiated due to watchdog timeout due to
1075 * a. IMP was earlier reset and our TX got choked down and
1076 * which resulted in watchdog reacting and inducing VF
1077 * reset. This also means our cmdq would be unreliable.
1078 * b. problem in TX due to other lower layer(example link
1079 * layer not functioning properly etc.)
1080 * 2. VF reset might have been initiated due to some config
1081 * change.
1082 *
1083 * NOTE: Theres no clear way to detect above cases than to react
1084 * to the response of PF for this reset request. PF will ack the
1085 * 1b and 2. cases but we will not get any intimation about 1a
1086 * from PF as cmdq would be in unreliable state i.e. mailbox
1087 * communication between PF and VF would be broken.
1088 */
1089
1090 /* if we are never geting into pending state it means either:
1091 * 1. PF is not receiving our request which could be due to IMP
1092 * reset
1093 * 2. PF is screwed
1094 * We cannot do much for 2. but to check first we can try reset
1095 * our PCIe + stack and see if it alleviates the problem.
1096 */
1097 if (hdev->reset_attempts > 3) {
1098 /* prepare for full reset of stack + pcie interface */
1099 hdev->nic.reset_level = HNAE3_VF_FULL_RESET;
1100
1101 /* "defer" schedule the reset task again */
1102 set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state);
1103 } else {
1104 hdev->reset_attempts++;
1105
1106 /* request PF for resetting this VF via mailbox */
1107 ret = hclgevf_do_reset(hdev);
1108 if (ret)
1109 dev_warn(&hdev->pdev->dev,
1110 "VF rst fail, stack will call\n");
1111 }
1112 }
1113
1114 clear_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state);
1115}
1116
870static void hclgevf_mailbox_service_task(struct work_struct *work) 1117static void hclgevf_mailbox_service_task(struct work_struct *work)
871{ 1118{
872 struct hclgevf_dev *hdev; 1119 struct hclgevf_dev *hdev;
@@ -878,7 +1125,7 @@ static void hclgevf_mailbox_service_task(struct work_struct *work)
878 1125
879 clear_bit(HCLGEVF_STATE_MBX_SERVICE_SCHED, &hdev->state); 1126 clear_bit(HCLGEVF_STATE_MBX_SERVICE_SCHED, &hdev->state);
880 1127
881 hclgevf_mbx_handler(hdev); 1128 hclgevf_mbx_async_handler(hdev);
882 1129
883 clear_bit(HCLGEVF_STATE_MBX_HANDLING, &hdev->state); 1130 clear_bit(HCLGEVF_STATE_MBX_HANDLING, &hdev->state);
884} 1131}
@@ -894,6 +1141,8 @@ static void hclgevf_service_task(struct work_struct *work)
894 */ 1141 */
895 hclgevf_request_link_info(hdev); 1142 hclgevf_request_link_info(hdev);
896 1143
1144 hclgevf_deferred_task_schedule(hdev);
1145
897 clear_bit(HCLGEVF_STATE_SERVICE_SCHED, &hdev->state); 1146 clear_bit(HCLGEVF_STATE_SERVICE_SCHED, &hdev->state);
898} 1147}
899 1148
@@ -936,8 +1185,7 @@ static irqreturn_t hclgevf_misc_irq_handle(int irq, void *data)
936 if (!hclgevf_check_event_cause(hdev, &clearval)) 1185 if (!hclgevf_check_event_cause(hdev, &clearval))
937 goto skip_sched; 1186 goto skip_sched;
938 1187
939 /* schedule the VF mailbox service task, if not already scheduled */ 1188 hclgevf_mbx_handler(hdev);
940 hclgevf_mbx_task_schedule(hdev);
941 1189
942 hclgevf_clear_event_cause(hdev, clearval); 1190 hclgevf_clear_event_cause(hdev, clearval);
943 1191
@@ -959,6 +1207,22 @@ static int hclgevf_configure(struct hclgevf_dev *hdev)
959 return hclgevf_get_tc_info(hdev); 1207 return hclgevf_get_tc_info(hdev);
960} 1208}
961 1209
1210static int hclgevf_alloc_hdev(struct hnae3_ae_dev *ae_dev)
1211{
1212 struct pci_dev *pdev = ae_dev->pdev;
1213 struct hclgevf_dev *hdev = ae_dev->priv;
1214
1215 hdev = devm_kzalloc(&pdev->dev, sizeof(*hdev), GFP_KERNEL);
1216 if (!hdev)
1217 return -ENOMEM;
1218
1219 hdev->pdev = pdev;
1220 hdev->ae_dev = ae_dev;
1221 ae_dev->priv = hdev;
1222
1223 return 0;
1224}
1225
962static int hclgevf_init_roce_base_info(struct hclgevf_dev *hdev) 1226static int hclgevf_init_roce_base_info(struct hclgevf_dev *hdev)
963{ 1227{
964 struct hnae3_handle *roce = &hdev->roce; 1228 struct hnae3_handle *roce = &hdev->roce;
@@ -1057,10 +1321,17 @@ static void hclgevf_ae_stop(struct hnae3_handle *handle)
1057 1321
1058 /* reset tqp stats */ 1322 /* reset tqp stats */
1059 hclgevf_reset_tqp_stats(handle); 1323 hclgevf_reset_tqp_stats(handle);
1324 del_timer_sync(&hdev->service_timer);
1325 cancel_work_sync(&hdev->service_task);
1326 hclgevf_update_link_status(hdev, 0);
1060} 1327}
1061 1328
1062static void hclgevf_state_init(struct hclgevf_dev *hdev) 1329static void hclgevf_state_init(struct hclgevf_dev *hdev)
1063{ 1330{
1331 /* if this is on going reset then skip this initialization */
1332 if (hclgevf_dev_ongoing_reset(hdev))
1333 return;
1334
1064 /* setup tasks for the MBX */ 1335 /* setup tasks for the MBX */
1065 INIT_WORK(&hdev->mbx_service_task, hclgevf_mailbox_service_task); 1336 INIT_WORK(&hdev->mbx_service_task, hclgevf_mailbox_service_task);
1066 clear_bit(HCLGEVF_STATE_MBX_SERVICE_SCHED, &hdev->state); 1337 clear_bit(HCLGEVF_STATE_MBX_SERVICE_SCHED, &hdev->state);
@@ -1072,6 +1343,8 @@ static void hclgevf_state_init(struct hclgevf_dev *hdev)
1072 INIT_WORK(&hdev->service_task, hclgevf_service_task); 1343 INIT_WORK(&hdev->service_task, hclgevf_service_task);
1073 clear_bit(HCLGEVF_STATE_SERVICE_SCHED, &hdev->state); 1344 clear_bit(HCLGEVF_STATE_SERVICE_SCHED, &hdev->state);
1074 1345
1346 INIT_WORK(&hdev->rst_service_task, hclgevf_reset_service_task);
1347
1075 mutex_init(&hdev->mbx_resp.mbx_mutex); 1348 mutex_init(&hdev->mbx_resp.mbx_mutex);
1076 1349
1077 /* bring the device down */ 1350 /* bring the device down */
@@ -1088,6 +1361,8 @@ static void hclgevf_state_uninit(struct hclgevf_dev *hdev)
1088 cancel_work_sync(&hdev->service_task); 1361 cancel_work_sync(&hdev->service_task);
1089 if (hdev->mbx_service_task.func) 1362 if (hdev->mbx_service_task.func)
1090 cancel_work_sync(&hdev->mbx_service_task); 1363 cancel_work_sync(&hdev->mbx_service_task);
1364 if (hdev->rst_service_task.func)
1365 cancel_work_sync(&hdev->rst_service_task);
1091 1366
1092 mutex_destroy(&hdev->mbx_resp.mbx_mutex); 1367 mutex_destroy(&hdev->mbx_resp.mbx_mutex);
1093} 1368}
@@ -1098,6 +1373,10 @@ static int hclgevf_init_msi(struct hclgevf_dev *hdev)
1098 int vectors; 1373 int vectors;
1099 int i; 1374 int i;
1100 1375
1376 /* if this is on going reset then skip this initialization */
1377 if (hclgevf_dev_ongoing_reset(hdev))
1378 return 0;
1379
1101 hdev->num_msi = HCLGEVF_MAX_VF_VECTOR_NUM; 1380 hdev->num_msi = HCLGEVF_MAX_VF_VECTOR_NUM;
1102 1381
1103 vectors = pci_alloc_irq_vectors(pdev, 1, hdev->num_msi, 1382 vectors = pci_alloc_irq_vectors(pdev, 1, hdev->num_msi,
@@ -1148,6 +1427,10 @@ static int hclgevf_misc_irq_init(struct hclgevf_dev *hdev)
1148{ 1427{
1149 int ret = 0; 1428 int ret = 0;
1150 1429
1430 /* if this is on going reset then skip this initialization */
1431 if (hclgevf_dev_ongoing_reset(hdev))
1432 return 0;
1433
1151 hclgevf_get_misc_vector(hdev); 1434 hclgevf_get_misc_vector(hdev);
1152 1435
1153 ret = request_irq(hdev->misc_vector.vector_irq, hclgevf_misc_irq_handle, 1436 ret = request_irq(hdev->misc_vector.vector_irq, hclgevf_misc_irq_handle,
@@ -1258,6 +1541,14 @@ static int hclgevf_pci_init(struct hclgevf_dev *hdev)
1258 struct hclgevf_hw *hw; 1541 struct hclgevf_hw *hw;
1259 int ret; 1542 int ret;
1260 1543
1544 /* check if we need to skip initialization of pci. This will happen if
1545 * device is undergoing VF reset. Otherwise, we would need to
1546 * re-initialize pci interface again i.e. when device is not going
1547 * through *any* reset or actually undergoing full reset.
1548 */
1549 if (hclgevf_dev_ongoing_reset(hdev))
1550 return 0;
1551
1261 ret = pci_enable_device(pdev); 1552 ret = pci_enable_device(pdev);
1262 if (ret) { 1553 if (ret) {
1263 dev_err(&pdev->dev, "failed to enable PCI device\n"); 1554 dev_err(&pdev->dev, "failed to enable PCI device\n");
@@ -1309,19 +1600,16 @@ static void hclgevf_pci_uninit(struct hclgevf_dev *hdev)
1309 pci_set_drvdata(pdev, NULL); 1600 pci_set_drvdata(pdev, NULL);
1310} 1601}
1311 1602
1312static int hclgevf_init_ae_dev(struct hnae3_ae_dev *ae_dev) 1603static int hclgevf_init_hdev(struct hclgevf_dev *hdev)
1313{ 1604{
1314 struct pci_dev *pdev = ae_dev->pdev; 1605 struct pci_dev *pdev = hdev->pdev;
1315 struct hclgevf_dev *hdev;
1316 int ret; 1606 int ret;
1317 1607
1318 hdev = devm_kzalloc(&pdev->dev, sizeof(*hdev), GFP_KERNEL); 1608 /* check if device is on-going full reset(i.e. pcie as well) */
1319 if (!hdev) 1609 if (hclgevf_dev_ongoing_full_reset(hdev)) {
1320 return -ENOMEM; 1610 dev_warn(&pdev->dev, "device is going full reset\n");
1321 1611 hclgevf_uninit_hdev(hdev);
1322 hdev->pdev = pdev; 1612 }
1323 hdev->ae_dev = ae_dev;
1324 ae_dev->priv = hdev;
1325 1613
1326 ret = hclgevf_pci_init(hdev); 1614 ret = hclgevf_pci_init(hdev);
1327 if (ret) { 1615 if (ret) {
@@ -1406,15 +1694,38 @@ err_irq_init:
1406 return ret; 1694 return ret;
1407} 1695}
1408 1696
1409static void hclgevf_uninit_ae_dev(struct hnae3_ae_dev *ae_dev) 1697static void hclgevf_uninit_hdev(struct hclgevf_dev *hdev)
1410{ 1698{
1411 struct hclgevf_dev *hdev = ae_dev->priv;
1412
1413 hclgevf_cmd_uninit(hdev); 1699 hclgevf_cmd_uninit(hdev);
1414 hclgevf_misc_irq_uninit(hdev); 1700 hclgevf_misc_irq_uninit(hdev);
1415 hclgevf_state_uninit(hdev); 1701 hclgevf_state_uninit(hdev);
1416 hclgevf_uninit_msi(hdev); 1702 hclgevf_uninit_msi(hdev);
1417 hclgevf_pci_uninit(hdev); 1703 hclgevf_pci_uninit(hdev);
1704}
1705
1706static int hclgevf_init_ae_dev(struct hnae3_ae_dev *ae_dev)
1707{
1708 struct pci_dev *pdev = ae_dev->pdev;
1709 int ret;
1710
1711 ret = hclgevf_alloc_hdev(ae_dev);
1712 if (ret) {
1713 dev_err(&pdev->dev, "hclge device allocation failed\n");
1714 return ret;
1715 }
1716
1717 ret = hclgevf_init_hdev(ae_dev->priv);
1718 if (ret)
1719 dev_err(&pdev->dev, "hclge device initialization failed\n");
1720
1721 return ret;
1722}
1723
1724static void hclgevf_uninit_ae_dev(struct hnae3_ae_dev *ae_dev)
1725{
1726 struct hclgevf_dev *hdev = ae_dev->priv;
1727
1728 hclgevf_uninit_hdev(hdev);
1418 ae_dev->priv = NULL; 1729 ae_dev->priv = NULL;
1419} 1730}
1420 1731
@@ -1447,6 +1758,43 @@ static void hclgevf_get_channels(struct hnae3_handle *handle,
1447 ch->combined_count = hdev->num_tqps; 1758 ch->combined_count = hdev->num_tqps;
1448} 1759}
1449 1760
1761static void hclgevf_get_tqps_and_rss_info(struct hnae3_handle *handle,
1762 u16 *free_tqps, u16 *max_rss_size)
1763{
1764 struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
1765
1766 *free_tqps = 0;
1767 *max_rss_size = hdev->rss_size_max;
1768}
1769
1770static int hclgevf_get_status(struct hnae3_handle *handle)
1771{
1772 struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
1773
1774 return hdev->hw.mac.link;
1775}
1776
1777static void hclgevf_get_ksettings_an_result(struct hnae3_handle *handle,
1778 u8 *auto_neg, u32 *speed,
1779 u8 *duplex)
1780{
1781 struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
1782
1783 if (speed)
1784 *speed = hdev->hw.mac.speed;
1785 if (duplex)
1786 *duplex = hdev->hw.mac.duplex;
1787 if (auto_neg)
1788 *auto_neg = AUTONEG_DISABLE;
1789}
1790
1791void hclgevf_update_speed_duplex(struct hclgevf_dev *hdev, u32 speed,
1792 u8 duplex)
1793{
1794 hdev->hw.mac.speed = speed;
1795 hdev->hw.mac.duplex = duplex;
1796}
1797
1450static const struct hnae3_ae_ops hclgevf_ops = { 1798static const struct hnae3_ae_ops hclgevf_ops = {
1451 .init_ae_dev = hclgevf_init_ae_dev, 1799 .init_ae_dev = hclgevf_init_ae_dev,
1452 .uninit_ae_dev = hclgevf_uninit_ae_dev, 1800 .uninit_ae_dev = hclgevf_uninit_ae_dev,
@@ -1457,6 +1805,7 @@ static const struct hnae3_ae_ops hclgevf_ops = {
1457 .map_ring_to_vector = hclgevf_map_ring_to_vector, 1805 .map_ring_to_vector = hclgevf_map_ring_to_vector,
1458 .unmap_ring_from_vector = hclgevf_unmap_ring_from_vector, 1806 .unmap_ring_from_vector = hclgevf_unmap_ring_from_vector,
1459 .get_vector = hclgevf_get_vector, 1807 .get_vector = hclgevf_get_vector,
1808 .put_vector = hclgevf_put_vector,
1460 .reset_queue = hclgevf_reset_tqp, 1809 .reset_queue = hclgevf_reset_tqp,
1461 .set_promisc_mode = hclgevf_set_promisc_mode, 1810 .set_promisc_mode = hclgevf_set_promisc_mode,
1462 .get_mac_addr = hclgevf_get_mac_addr, 1811 .get_mac_addr = hclgevf_get_mac_addr,
@@ -1476,7 +1825,11 @@ static const struct hnae3_ae_ops hclgevf_ops = {
1476 .get_tc_size = hclgevf_get_tc_size, 1825 .get_tc_size = hclgevf_get_tc_size,
1477 .get_fw_version = hclgevf_get_fw_version, 1826 .get_fw_version = hclgevf_get_fw_version,
1478 .set_vlan_filter = hclgevf_set_vlan_filter, 1827 .set_vlan_filter = hclgevf_set_vlan_filter,
1828 .reset_event = hclgevf_reset_event,
1479 .get_channels = hclgevf_get_channels, 1829 .get_channels = hclgevf_get_channels,
1830 .get_tqps_and_rss_info = hclgevf_get_tqps_and_rss_info,
1831 .get_status = hclgevf_get_status,
1832 .get_ksettings_an_result = hclgevf_get_ksettings_an_result,
1480}; 1833};
1481 1834
1482static struct hnae3_ae_algo ae_algovf = { 1835static struct hnae3_ae_algo ae_algovf = {
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h
index a63bee4a3674..a477a7c36bbd 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h
@@ -34,6 +34,9 @@
34#define HCLGEVF_VECTOR0_RX_CMDQ_INT_B 1 34#define HCLGEVF_VECTOR0_RX_CMDQ_INT_B 1
35 35
36#define HCLGEVF_TQP_RESET_TRY_TIMES 10 36#define HCLGEVF_TQP_RESET_TRY_TIMES 10
37/* Reset related Registers */
38#define HCLGEVF_FUN_RST_ING 0x20C00
39#define HCLGEVF_FUN_RST_ING_B 0
37 40
38#define HCLGEVF_RSS_IND_TBL_SIZE 512 41#define HCLGEVF_RSS_IND_TBL_SIZE 512
39#define HCLGEVF_RSS_SET_BITMAP_MSK 0xffff 42#define HCLGEVF_RSS_SET_BITMAP_MSK 0xffff
@@ -52,6 +55,8 @@ enum hclgevf_states {
52 HCLGEVF_STATE_DISABLED, 55 HCLGEVF_STATE_DISABLED,
53 /* task states */ 56 /* task states */
54 HCLGEVF_STATE_SERVICE_SCHED, 57 HCLGEVF_STATE_SERVICE_SCHED,
58 HCLGEVF_STATE_RST_SERVICE_SCHED,
59 HCLGEVF_STATE_RST_HANDLING,
55 HCLGEVF_STATE_MBX_SERVICE_SCHED, 60 HCLGEVF_STATE_MBX_SERVICE_SCHED,
56 HCLGEVF_STATE_MBX_HANDLING, 61 HCLGEVF_STATE_MBX_HANDLING,
57}; 62};
@@ -61,6 +66,8 @@ enum hclgevf_states {
61struct hclgevf_mac { 66struct hclgevf_mac {
62 u8 mac_addr[ETH_ALEN]; 67 u8 mac_addr[ETH_ALEN];
63 int link; 68 int link;
69 u8 duplex;
70 u32 speed;
64}; 71};
65 72
66struct hclgevf_hw { 73struct hclgevf_hw {
@@ -120,6 +127,11 @@ struct hclgevf_dev {
120 struct hclgevf_rss_cfg rss_cfg; 127 struct hclgevf_rss_cfg rss_cfg;
121 unsigned long state; 128 unsigned long state;
122 129
130#define HCLGEVF_RESET_REQUESTED 0
131#define HCLGEVF_RESET_PENDING 1
132 unsigned long reset_state; /* requested, pending */
133 u32 reset_attempts;
134
123 u32 fw_version; 135 u32 fw_version;
124 u16 num_tqps; /* num task queue pairs of this PF */ 136 u16 num_tqps; /* num task queue pairs of this PF */
125 137
@@ -140,10 +152,13 @@ struct hclgevf_dev {
140 int *vector_irq; 152 int *vector_irq;
141 153
142 bool accept_mta_mc; /* whether to accept mta filter multicast */ 154 bool accept_mta_mc; /* whether to accept mta filter multicast */
155 bool mbx_event_pending;
143 struct hclgevf_mbx_resp_status mbx_resp; /* mailbox response */ 156 struct hclgevf_mbx_resp_status mbx_resp; /* mailbox response */
157 struct hclgevf_mbx_arq_ring arq; /* mailbox async rx queue */
144 158
145 struct timer_list service_timer; 159 struct timer_list service_timer;
146 struct work_struct service_task; 160 struct work_struct service_task;
161 struct work_struct rst_service_task;
147 struct work_struct mbx_service_task; 162 struct work_struct mbx_service_task;
148 163
149 struct hclgevf_tqp *htqp; 164 struct hclgevf_tqp *htqp;
@@ -156,9 +171,29 @@ struct hclgevf_dev {
156 u32 flag; 171 u32 flag;
157}; 172};
158 173
174static inline bool hclgevf_dev_ongoing_reset(struct hclgevf_dev *hdev)
175{
176 return (hdev &&
177 (test_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state)) &&
178 (hdev->nic.reset_level == HNAE3_VF_RESET));
179}
180
181static inline bool hclgevf_dev_ongoing_full_reset(struct hclgevf_dev *hdev)
182{
183 return (hdev &&
184 (test_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state)) &&
185 (hdev->nic.reset_level == HNAE3_VF_FULL_RESET));
186}
187
159int hclgevf_send_mbx_msg(struct hclgevf_dev *hdev, u16 code, u16 subcode, 188int hclgevf_send_mbx_msg(struct hclgevf_dev *hdev, u16 code, u16 subcode,
160 const u8 *msg_data, u8 msg_len, bool need_resp, 189 const u8 *msg_data, u8 msg_len, bool need_resp,
161 u8 *resp_data, u16 resp_len); 190 u8 *resp_data, u16 resp_len);
162void hclgevf_mbx_handler(struct hclgevf_dev *hdev); 191void hclgevf_mbx_handler(struct hclgevf_dev *hdev);
192void hclgevf_mbx_async_handler(struct hclgevf_dev *hdev);
193
163void hclgevf_update_link_status(struct hclgevf_dev *hdev, int link_state); 194void hclgevf_update_link_status(struct hclgevf_dev *hdev, int link_state);
195void hclgevf_update_speed_duplex(struct hclgevf_dev *hdev, u32 speed,
196 u8 duplex);
197void hclgevf_reset_task_schedule(struct hclgevf_dev *hdev);
198void hclgevf_mbx_task_schedule(struct hclgevf_dev *hdev);
164#endif 199#endif
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c
index e39cad285fa9..a28618428338 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c
@@ -54,6 +54,10 @@ static int hclgevf_get_mbx_resp(struct hclgevf_dev *hdev, u16 code0, u16 code1,
54 mbx_resp = &hdev->mbx_resp; 54 mbx_resp = &hdev->mbx_resp;
55 r_code0 = (u16)(mbx_resp->origin_mbx_msg >> 16); 55 r_code0 = (u16)(mbx_resp->origin_mbx_msg >> 16);
56 r_code1 = (u16)(mbx_resp->origin_mbx_msg & 0xff); 56 r_code1 = (u16)(mbx_resp->origin_mbx_msg & 0xff);
57
58 if (mbx_resp->resp_status)
59 return mbx_resp->resp_status;
60
57 if (resp_data) 61 if (resp_data)
58 memcpy(resp_data, &mbx_resp->additional_info[0], resp_len); 62 memcpy(resp_data, &mbx_resp->additional_info[0], resp_len);
59 63
@@ -128,7 +132,8 @@ void hclgevf_mbx_handler(struct hclgevf_dev *hdev)
128 struct hclge_mbx_pf_to_vf_cmd *req; 132 struct hclge_mbx_pf_to_vf_cmd *req;
129 struct hclgevf_cmq_ring *crq; 133 struct hclgevf_cmq_ring *crq;
130 struct hclgevf_desc *desc; 134 struct hclgevf_desc *desc;
131 u16 link_status, flag; 135 u16 *msg_q;
136 u16 flag;
132 u8 *temp; 137 u8 *temp;
133 int i; 138 int i;
134 139
@@ -140,6 +145,12 @@ void hclgevf_mbx_handler(struct hclgevf_dev *hdev)
140 desc = &crq->desc[crq->next_to_use]; 145 desc = &crq->desc[crq->next_to_use];
141 req = (struct hclge_mbx_pf_to_vf_cmd *)desc->data; 146 req = (struct hclge_mbx_pf_to_vf_cmd *)desc->data;
142 147
148 /* synchronous messages are time critical and need preferential
149 * treatment. Therefore, we need to acknowledge all the sync
150 * responses as quickly as possible so that waiting tasks do not
151 * timeout and simultaneously queue the async messages for later
152 * prcessing in context of mailbox task i.e. the slow path.
153 */
143 switch (req->msg[0]) { 154 switch (req->msg[0]) {
144 case HCLGE_MBX_PF_VF_RESP: 155 case HCLGE_MBX_PF_VF_RESP:
145 if (resp->received_resp) 156 if (resp->received_resp)
@@ -159,10 +170,31 @@ void hclgevf_mbx_handler(struct hclgevf_dev *hdev)
159 } 170 }
160 break; 171 break;
161 case HCLGE_MBX_LINK_STAT_CHANGE: 172 case HCLGE_MBX_LINK_STAT_CHANGE:
162 link_status = le16_to_cpu(req->msg[1]); 173 case HCLGE_MBX_ASSERTING_RESET:
174 /* set this mbx event as pending. This is required as we
175 * might loose interrupt event when mbx task is busy
176 * handling. This shall be cleared when mbx task just
177 * enters handling state.
178 */
179 hdev->mbx_event_pending = true;
163 180
164 /* update upper layer with new link link status */ 181 /* we will drop the async msg if we find ARQ as full
165 hclgevf_update_link_status(hdev, link_status); 182 * and continue with next message
183 */
184 if (hdev->arq.count >= HCLGE_MBX_MAX_ARQ_MSG_NUM) {
185 dev_warn(&hdev->pdev->dev,
186 "Async Q full, dropping msg(%d)\n",
187 req->msg[1]);
188 break;
189 }
190
191 /* tail the async message in arq */
192 msg_q = hdev->arq.msg_q[hdev->arq.tail];
193 memcpy(&msg_q[0], req->msg, HCLGE_MBX_MAX_ARQ_MSG_SIZE);
194 hclge_mbx_tail_ptr_move_arq(hdev->arq);
195 hdev->arq.count++;
196
197 hclgevf_mbx_task_schedule(hdev);
166 198
167 break; 199 break;
168 default: 200 default:
@@ -171,6 +203,7 @@ void hclgevf_mbx_handler(struct hclgevf_dev *hdev)
171 req->msg[0]); 203 req->msg[0]);
172 break; 204 break;
173 } 205 }
206 crq->desc[crq->next_to_use].flag = 0;
174 hclge_mbx_ring_ptr_move_crq(crq); 207 hclge_mbx_ring_ptr_move_crq(crq);
175 flag = le16_to_cpu(crq->desc[crq->next_to_use].flag); 208 flag = le16_to_cpu(crq->desc[crq->next_to_use].flag);
176 } 209 }
@@ -179,3 +212,57 @@ void hclgevf_mbx_handler(struct hclgevf_dev *hdev)
179 hclgevf_write_dev(&hdev->hw, HCLGEVF_NIC_CRQ_HEAD_REG, 212 hclgevf_write_dev(&hdev->hw, HCLGEVF_NIC_CRQ_HEAD_REG,
180 crq->next_to_use); 213 crq->next_to_use);
181} 214}
215
216void hclgevf_mbx_async_handler(struct hclgevf_dev *hdev)
217{
218 u16 link_status;
219 u16 *msg_q;
220 u8 duplex;
221 u32 speed;
222 u32 tail;
223
224 /* we can safely clear it now as we are at start of the async message
225 * processing
226 */
227 hdev->mbx_event_pending = false;
228
229 tail = hdev->arq.tail;
230
231 /* process all the async queue messages */
232 while (tail != hdev->arq.head) {
233 msg_q = hdev->arq.msg_q[hdev->arq.head];
234
235 switch (msg_q[0]) {
236 case HCLGE_MBX_LINK_STAT_CHANGE:
237 link_status = le16_to_cpu(msg_q[1]);
238 memcpy(&speed, &msg_q[2], sizeof(speed));
239 duplex = (u8)le16_to_cpu(msg_q[4]);
240
241 /* update upper layer with new link link status */
242 hclgevf_update_link_status(hdev, link_status);
243 hclgevf_update_speed_duplex(hdev, speed, duplex);
244
245 break;
246 case HCLGE_MBX_ASSERTING_RESET:
247 /* PF has asserted reset hence VF should go in pending
248 * state and poll for the hardware reset status till it
249 * has been completely reset. After this stack should
250 * eventually be re-initialized.
251 */
252 hdev->nic.reset_level = HNAE3_VF_RESET;
253 set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state);
254 hclgevf_reset_task_schedule(hdev);
255
256 break;
257 default:
258 dev_err(&hdev->pdev->dev,
259 "fetched unsupported(%d) message from arq\n",
260 msg_q[0]);
261 break;
262 }
263
264 hclge_mbx_head_ptr_move_arq(hdev->arq);
265 hdev->arq.count--;
266 msg_q = hdev->arq.msg_q[hdev->arq.head];
267 }
268}
diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
index 1b3cc8bb0705..5632c030811b 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -90,7 +90,7 @@ MODULE_VERSION(IBMVNIC_DRIVER_VERSION);
90 90
91static int ibmvnic_version = IBMVNIC_INITIAL_VERSION; 91static int ibmvnic_version = IBMVNIC_INITIAL_VERSION;
92static int ibmvnic_remove(struct vio_dev *); 92static int ibmvnic_remove(struct vio_dev *);
93static void release_sub_crqs(struct ibmvnic_adapter *); 93static void release_sub_crqs(struct ibmvnic_adapter *, bool);
94static int ibmvnic_reset_crq(struct ibmvnic_adapter *); 94static int ibmvnic_reset_crq(struct ibmvnic_adapter *);
95static int ibmvnic_send_crq_init(struct ibmvnic_adapter *); 95static int ibmvnic_send_crq_init(struct ibmvnic_adapter *);
96static int ibmvnic_reenable_crq_queue(struct ibmvnic_adapter *); 96static int ibmvnic_reenable_crq_queue(struct ibmvnic_adapter *);
@@ -111,7 +111,7 @@ static int ibmvnic_poll(struct napi_struct *napi, int data);
111static void send_map_query(struct ibmvnic_adapter *adapter); 111static void send_map_query(struct ibmvnic_adapter *adapter);
112static void send_request_map(struct ibmvnic_adapter *, dma_addr_t, __be32, u8); 112static void send_request_map(struct ibmvnic_adapter *, dma_addr_t, __be32, u8);
113static void send_request_unmap(struct ibmvnic_adapter *, u8); 113static void send_request_unmap(struct ibmvnic_adapter *, u8);
114static void send_login(struct ibmvnic_adapter *adapter); 114static int send_login(struct ibmvnic_adapter *adapter);
115static void send_cap_queries(struct ibmvnic_adapter *adapter); 115static void send_cap_queries(struct ibmvnic_adapter *adapter);
116static int init_sub_crqs(struct ibmvnic_adapter *); 116static int init_sub_crqs(struct ibmvnic_adapter *);
117static int init_sub_crq_irqs(struct ibmvnic_adapter *adapter); 117static int init_sub_crq_irqs(struct ibmvnic_adapter *adapter);
@@ -361,14 +361,14 @@ static void release_stats_buffers(struct ibmvnic_adapter *adapter)
361static int init_stats_buffers(struct ibmvnic_adapter *adapter) 361static int init_stats_buffers(struct ibmvnic_adapter *adapter)
362{ 362{
363 adapter->tx_stats_buffers = 363 adapter->tx_stats_buffers =
364 kcalloc(adapter->req_tx_queues, 364 kcalloc(IBMVNIC_MAX_QUEUES,
365 sizeof(struct ibmvnic_tx_queue_stats), 365 sizeof(struct ibmvnic_tx_queue_stats),
366 GFP_KERNEL); 366 GFP_KERNEL);
367 if (!adapter->tx_stats_buffers) 367 if (!adapter->tx_stats_buffers)
368 return -ENOMEM; 368 return -ENOMEM;
369 369
370 adapter->rx_stats_buffers = 370 adapter->rx_stats_buffers =
371 kcalloc(adapter->req_rx_queues, 371 kcalloc(IBMVNIC_MAX_QUEUES,
372 sizeof(struct ibmvnic_rx_queue_stats), 372 sizeof(struct ibmvnic_rx_queue_stats),
373 GFP_KERNEL); 373 GFP_KERNEL);
374 if (!adapter->rx_stats_buffers) 374 if (!adapter->rx_stats_buffers)
@@ -509,7 +509,7 @@ static int init_rx_pools(struct net_device *netdev)
509 return -1; 509 return -1;
510 } 510 }
511 511
512 adapter->num_active_rx_pools = 0; 512 adapter->num_active_rx_pools = rxadd_subcrqs;
513 513
514 for (i = 0; i < rxadd_subcrqs; i++) { 514 for (i = 0; i < rxadd_subcrqs; i++) {
515 rx_pool = &adapter->rx_pool[i]; 515 rx_pool = &adapter->rx_pool[i];
@@ -554,41 +554,44 @@ static int init_rx_pools(struct net_device *netdev)
554 rx_pool->next_free = 0; 554 rx_pool->next_free = 0;
555 } 555 }
556 556
557 adapter->num_active_rx_pools = rxadd_subcrqs; 557 return 0;
558}
559
560static int reset_one_tx_pool(struct ibmvnic_adapter *adapter,
561 struct ibmvnic_tx_pool *tx_pool)
562{
563 int rc, i;
564
565 rc = reset_long_term_buff(adapter, &tx_pool->long_term_buff);
566 if (rc)
567 return rc;
568
569 memset(tx_pool->tx_buff, 0,
570 tx_pool->num_buffers *
571 sizeof(struct ibmvnic_tx_buff));
572
573 for (i = 0; i < tx_pool->num_buffers; i++)
574 tx_pool->free_map[i] = i;
575
576 tx_pool->consumer_index = 0;
577 tx_pool->producer_index = 0;
558 578
559 return 0; 579 return 0;
560} 580}
561 581
562static int reset_tx_pools(struct ibmvnic_adapter *adapter) 582static int reset_tx_pools(struct ibmvnic_adapter *adapter)
563{ 583{
564 struct ibmvnic_tx_pool *tx_pool;
565 int tx_scrqs; 584 int tx_scrqs;
566 int i, j, rc; 585 int i, rc;
567 586
568 tx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_txsubm_subcrqs); 587 tx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_txsubm_subcrqs);
569 for (i = 0; i < tx_scrqs; i++) { 588 for (i = 0; i < tx_scrqs; i++) {
570 netdev_dbg(adapter->netdev, "Re-setting tx_pool[%d]\n", i); 589 rc = reset_one_tx_pool(adapter, &adapter->tso_pool[i]);
571
572 tx_pool = &adapter->tx_pool[i];
573
574 rc = reset_long_term_buff(adapter, &tx_pool->long_term_buff);
575 if (rc) 590 if (rc)
576 return rc; 591 return rc;
577 592 rc = reset_one_tx_pool(adapter, &adapter->tx_pool[i]);
578 rc = reset_long_term_buff(adapter, &tx_pool->tso_ltb);
579 if (rc) 593 if (rc)
580 return rc; 594 return rc;
581
582 memset(tx_pool->tx_buff, 0,
583 adapter->req_tx_entries_per_subcrq *
584 sizeof(struct ibmvnic_tx_buff));
585
586 for (j = 0; j < adapter->req_tx_entries_per_subcrq; j++)
587 tx_pool->free_map[j] = j;
588
589 tx_pool->consumer_index = 0;
590 tx_pool->producer_index = 0;
591 tx_pool->tso_index = 0;
592 } 595 }
593 596
594 return 0; 597 return 0;
@@ -605,35 +608,70 @@ static void release_vpd_data(struct ibmvnic_adapter *adapter)
605 adapter->vpd = NULL; 608 adapter->vpd = NULL;
606} 609}
607 610
611static void release_one_tx_pool(struct ibmvnic_adapter *adapter,
612 struct ibmvnic_tx_pool *tx_pool)
613{
614 kfree(tx_pool->tx_buff);
615 kfree(tx_pool->free_map);
616 free_long_term_buff(adapter, &tx_pool->long_term_buff);
617}
618
608static void release_tx_pools(struct ibmvnic_adapter *adapter) 619static void release_tx_pools(struct ibmvnic_adapter *adapter)
609{ 620{
610 struct ibmvnic_tx_pool *tx_pool;
611 int i; 621 int i;
612 622
613 if (!adapter->tx_pool) 623 if (!adapter->tx_pool)
614 return; 624 return;
615 625
616 for (i = 0; i < adapter->num_active_tx_pools; i++) { 626 for (i = 0; i < adapter->num_active_tx_pools; i++) {
617 netdev_dbg(adapter->netdev, "Releasing tx_pool[%d]\n", i); 627 release_one_tx_pool(adapter, &adapter->tx_pool[i]);
618 tx_pool = &adapter->tx_pool[i]; 628 release_one_tx_pool(adapter, &adapter->tso_pool[i]);
619 kfree(tx_pool->tx_buff);
620 free_long_term_buff(adapter, &tx_pool->long_term_buff);
621 free_long_term_buff(adapter, &tx_pool->tso_ltb);
622 kfree(tx_pool->free_map);
623 } 629 }
624 630
625 kfree(adapter->tx_pool); 631 kfree(adapter->tx_pool);
626 adapter->tx_pool = NULL; 632 adapter->tx_pool = NULL;
633 kfree(adapter->tso_pool);
634 adapter->tso_pool = NULL;
627 adapter->num_active_tx_pools = 0; 635 adapter->num_active_tx_pools = 0;
628} 636}
629 637
638static int init_one_tx_pool(struct net_device *netdev,
639 struct ibmvnic_tx_pool *tx_pool,
640 int num_entries, int buf_size)
641{
642 struct ibmvnic_adapter *adapter = netdev_priv(netdev);
643 int i;
644
645 tx_pool->tx_buff = kcalloc(num_entries,
646 sizeof(struct ibmvnic_tx_buff),
647 GFP_KERNEL);
648 if (!tx_pool->tx_buff)
649 return -1;
650
651 if (alloc_long_term_buff(adapter, &tx_pool->long_term_buff,
652 num_entries * buf_size))
653 return -1;
654
655 tx_pool->free_map = kcalloc(num_entries, sizeof(int), GFP_KERNEL);
656 if (!tx_pool->free_map)
657 return -1;
658
659 for (i = 0; i < num_entries; i++)
660 tx_pool->free_map[i] = i;
661
662 tx_pool->consumer_index = 0;
663 tx_pool->producer_index = 0;
664 tx_pool->num_buffers = num_entries;
665 tx_pool->buf_size = buf_size;
666
667 return 0;
668}
669
630static int init_tx_pools(struct net_device *netdev) 670static int init_tx_pools(struct net_device *netdev)
631{ 671{
632 struct ibmvnic_adapter *adapter = netdev_priv(netdev); 672 struct ibmvnic_adapter *adapter = netdev_priv(netdev);
633 struct device *dev = &adapter->vdev->dev;
634 struct ibmvnic_tx_pool *tx_pool;
635 int tx_subcrqs; 673 int tx_subcrqs;
636 int i, j; 674 int i, rc;
637 675
638 tx_subcrqs = be32_to_cpu(adapter->login_rsp_buf->num_txsubm_subcrqs); 676 tx_subcrqs = be32_to_cpu(adapter->login_rsp_buf->num_txsubm_subcrqs);
639 adapter->tx_pool = kcalloc(tx_subcrqs, 677 adapter->tx_pool = kcalloc(tx_subcrqs,
@@ -641,57 +679,31 @@ static int init_tx_pools(struct net_device *netdev)
641 if (!adapter->tx_pool) 679 if (!adapter->tx_pool)
642 return -1; 680 return -1;
643 681
644 adapter->num_active_tx_pools = 0; 682 adapter->tso_pool = kcalloc(tx_subcrqs,
645 683 sizeof(struct ibmvnic_tx_pool), GFP_KERNEL);
646 for (i = 0; i < tx_subcrqs; i++) { 684 if (!adapter->tso_pool)
647 tx_pool = &adapter->tx_pool[i]; 685 return -1;
648
649 netdev_dbg(adapter->netdev,
650 "Initializing tx_pool[%d], %lld buffs\n",
651 i, adapter->req_tx_entries_per_subcrq);
652
653 tx_pool->tx_buff = kcalloc(adapter->req_tx_entries_per_subcrq,
654 sizeof(struct ibmvnic_tx_buff),
655 GFP_KERNEL);
656 if (!tx_pool->tx_buff) {
657 dev_err(dev, "tx pool buffer allocation failed\n");
658 release_tx_pools(adapter);
659 return -1;
660 }
661 686
662 if (alloc_long_term_buff(adapter, &tx_pool->long_term_buff, 687 adapter->num_active_tx_pools = tx_subcrqs;
663 adapter->req_tx_entries_per_subcrq *
664 adapter->req_mtu)) {
665 release_tx_pools(adapter);
666 return -1;
667 }
668 688
669 /* alloc TSO ltb */ 689 for (i = 0; i < tx_subcrqs; i++) {
670 if (alloc_long_term_buff(adapter, &tx_pool->tso_ltb, 690 rc = init_one_tx_pool(netdev, &adapter->tx_pool[i],
671 IBMVNIC_TSO_BUFS * 691 adapter->req_tx_entries_per_subcrq,
672 IBMVNIC_TSO_BUF_SZ)) { 692 adapter->req_mtu + VLAN_HLEN);
693 if (rc) {
673 release_tx_pools(adapter); 694 release_tx_pools(adapter);
674 return -1; 695 return rc;
675 } 696 }
676 697
677 tx_pool->tso_index = 0; 698 init_one_tx_pool(netdev, &adapter->tso_pool[i],
678 699 IBMVNIC_TSO_BUFS,
679 tx_pool->free_map = kcalloc(adapter->req_tx_entries_per_subcrq, 700 IBMVNIC_TSO_BUF_SZ);
680 sizeof(int), GFP_KERNEL); 701 if (rc) {
681 if (!tx_pool->free_map) {
682 release_tx_pools(adapter); 702 release_tx_pools(adapter);
683 return -1; 703 return rc;
684 } 704 }
685
686 for (j = 0; j < adapter->req_tx_entries_per_subcrq; j++)
687 tx_pool->free_map[j] = j;
688
689 tx_pool->consumer_index = 0;
690 tx_pool->producer_index = 0;
691 } 705 }
692 706
693 adapter->num_active_tx_pools = tx_subcrqs;
694
695 return 0; 707 return 0;
696} 708}
697 709
@@ -740,6 +752,45 @@ static void ibmvnic_napi_disable(struct ibmvnic_adapter *adapter)
740 adapter->napi_enabled = false; 752 adapter->napi_enabled = false;
741} 753}
742 754
755static int init_napi(struct ibmvnic_adapter *adapter)
756{
757 int i;
758
759 adapter->napi = kcalloc(adapter->req_rx_queues,
760 sizeof(struct napi_struct), GFP_KERNEL);
761 if (!adapter->napi)
762 return -ENOMEM;
763
764 for (i = 0; i < adapter->req_rx_queues; i++) {
765 netdev_dbg(adapter->netdev, "Adding napi[%d]\n", i);
766 netif_napi_add(adapter->netdev, &adapter->napi[i],
767 ibmvnic_poll, NAPI_POLL_WEIGHT);
768 }
769
770 adapter->num_active_rx_napi = adapter->req_rx_queues;
771 return 0;
772}
773
774static void release_napi(struct ibmvnic_adapter *adapter)
775{
776 int i;
777
778 if (!adapter->napi)
779 return;
780
781 for (i = 0; i < adapter->num_active_rx_napi; i++) {
782 if (&adapter->napi[i]) {
783 netdev_dbg(adapter->netdev,
784 "Releasing napi[%d]\n", i);
785 netif_napi_del(&adapter->napi[i]);
786 }
787 }
788
789 kfree(adapter->napi);
790 adapter->napi = NULL;
791 adapter->num_active_rx_napi = 0;
792}
793
743static int ibmvnic_login(struct net_device *netdev) 794static int ibmvnic_login(struct net_device *netdev)
744{ 795{
745 struct ibmvnic_adapter *adapter = netdev_priv(netdev); 796 struct ibmvnic_adapter *adapter = netdev_priv(netdev);
@@ -750,7 +801,7 @@ static int ibmvnic_login(struct net_device *netdev)
750 do { 801 do {
751 if (adapter->renegotiate) { 802 if (adapter->renegotiate) {
752 adapter->renegotiate = false; 803 adapter->renegotiate = false;
753 release_sub_crqs(adapter); 804 release_sub_crqs(adapter, 1);
754 805
755 reinit_completion(&adapter->init_done); 806 reinit_completion(&adapter->init_done);
756 send_cap_queries(adapter); 807 send_cap_queries(adapter);
@@ -774,8 +825,11 @@ static int ibmvnic_login(struct net_device *netdev)
774 } 825 }
775 826
776 reinit_completion(&adapter->init_done); 827 reinit_completion(&adapter->init_done);
777 send_login(adapter); 828 rc = send_login(adapter);
778 if (!wait_for_completion_timeout(&adapter->init_done, 829 if (rc) {
830 dev_err(dev, "Unable to attempt device login\n");
831 return rc;
832 } else if (!wait_for_completion_timeout(&adapter->init_done,
779 timeout)) { 833 timeout)) {
780 dev_err(dev, "Login timeout\n"); 834 dev_err(dev, "Login timeout\n");
781 return -1; 835 return -1;
@@ -805,29 +859,13 @@ static void release_login_rsp_buffer(struct ibmvnic_adapter *adapter)
805 859
806static void release_resources(struct ibmvnic_adapter *adapter) 860static void release_resources(struct ibmvnic_adapter *adapter)
807{ 861{
808 int i;
809
810 release_vpd_data(adapter); 862 release_vpd_data(adapter);
811 863
812 release_tx_pools(adapter); 864 release_tx_pools(adapter);
813 release_rx_pools(adapter); 865 release_rx_pools(adapter);
814 866
815 release_stats_token(adapter);
816 release_stats_buffers(adapter);
817 release_error_buffers(adapter); 867 release_error_buffers(adapter);
818 868 release_napi(adapter);
819 if (adapter->napi) {
820 for (i = 0; i < adapter->req_rx_queues; i++) {
821 if (&adapter->napi[i]) {
822 netdev_dbg(adapter->netdev,
823 "Releasing napi[%d]\n", i);
824 netif_napi_del(&adapter->napi[i]);
825 }
826 }
827 }
828 kfree(adapter->napi);
829 adapter->napi = NULL;
830
831 release_login_rsp_buffer(adapter); 869 release_login_rsp_buffer(adapter);
832} 870}
833 871
@@ -947,20 +985,12 @@ static int ibmvnic_get_vpd(struct ibmvnic_adapter *adapter)
947static int init_resources(struct ibmvnic_adapter *adapter) 985static int init_resources(struct ibmvnic_adapter *adapter)
948{ 986{
949 struct net_device *netdev = adapter->netdev; 987 struct net_device *netdev = adapter->netdev;
950 int i, rc; 988 int rc;
951 989
952 rc = set_real_num_queues(netdev); 990 rc = set_real_num_queues(netdev);
953 if (rc) 991 if (rc)
954 return rc; 992 return rc;
955 993
956 rc = init_stats_buffers(adapter);
957 if (rc)
958 return rc;
959
960 rc = init_stats_token(adapter);
961 if (rc)
962 return rc;
963
964 adapter->vpd = kzalloc(sizeof(*adapter->vpd), GFP_KERNEL); 994 adapter->vpd = kzalloc(sizeof(*adapter->vpd), GFP_KERNEL);
965 if (!adapter->vpd) 995 if (!adapter->vpd)
966 return -ENOMEM; 996 return -ENOMEM;
@@ -973,16 +1003,10 @@ static int init_resources(struct ibmvnic_adapter *adapter)
973 } 1003 }
974 1004
975 adapter->map_id = 1; 1005 adapter->map_id = 1;
976 adapter->napi = kcalloc(adapter->req_rx_queues,
977 sizeof(struct napi_struct), GFP_KERNEL);
978 if (!adapter->napi)
979 return -ENOMEM;
980 1006
981 for (i = 0; i < adapter->req_rx_queues; i++) { 1007 rc = init_napi(adapter);
982 netdev_dbg(netdev, "Adding napi[%d]\n", i); 1008 if (rc)
983 netif_napi_add(netdev, &adapter->napi[i], ibmvnic_poll, 1009 return rc;
984 NAPI_POLL_WEIGHT);
985 }
986 1010
987 send_map_query(adapter); 1011 send_map_query(adapter);
988 1012
@@ -1076,6 +1100,7 @@ static int ibmvnic_open(struct net_device *netdev)
1076static void clean_rx_pools(struct ibmvnic_adapter *adapter) 1100static void clean_rx_pools(struct ibmvnic_adapter *adapter)
1077{ 1101{
1078 struct ibmvnic_rx_pool *rx_pool; 1102 struct ibmvnic_rx_pool *rx_pool;
1103 struct ibmvnic_rx_buff *rx_buff;
1079 u64 rx_entries; 1104 u64 rx_entries;
1080 int rx_scrqs; 1105 int rx_scrqs;
1081 int i, j; 1106 int i, j;
@@ -1089,56 +1114,64 @@ static void clean_rx_pools(struct ibmvnic_adapter *adapter)
1089 /* Free any remaining skbs in the rx buffer pools */ 1114 /* Free any remaining skbs in the rx buffer pools */
1090 for (i = 0; i < rx_scrqs; i++) { 1115 for (i = 0; i < rx_scrqs; i++) {
1091 rx_pool = &adapter->rx_pool[i]; 1116 rx_pool = &adapter->rx_pool[i];
1092 if (!rx_pool) 1117 if (!rx_pool || !rx_pool->rx_buff)
1093 continue; 1118 continue;
1094 1119
1095 netdev_dbg(adapter->netdev, "Cleaning rx_pool[%d]\n", i); 1120 netdev_dbg(adapter->netdev, "Cleaning rx_pool[%d]\n", i);
1096 for (j = 0; j < rx_entries; j++) { 1121 for (j = 0; j < rx_entries; j++) {
1097 if (rx_pool->rx_buff[j].skb) { 1122 rx_buff = &rx_pool->rx_buff[j];
1098 dev_kfree_skb_any(rx_pool->rx_buff[j].skb); 1123 if (rx_buff && rx_buff->skb) {
1099 rx_pool->rx_buff[j].skb = NULL; 1124 dev_kfree_skb_any(rx_buff->skb);
1125 rx_buff->skb = NULL;
1100 } 1126 }
1101 } 1127 }
1102 } 1128 }
1103} 1129}
1104 1130
1105static void clean_tx_pools(struct ibmvnic_adapter *adapter) 1131static void clean_one_tx_pool(struct ibmvnic_adapter *adapter,
1132 struct ibmvnic_tx_pool *tx_pool)
1106{ 1133{
1107 struct ibmvnic_tx_pool *tx_pool; 1134 struct ibmvnic_tx_buff *tx_buff;
1108 u64 tx_entries; 1135 u64 tx_entries;
1136 int i;
1137
1138 if (!tx_pool && !tx_pool->tx_buff)
1139 return;
1140
1141 tx_entries = tx_pool->num_buffers;
1142
1143 for (i = 0; i < tx_entries; i++) {
1144 tx_buff = &tx_pool->tx_buff[i];
1145 if (tx_buff && tx_buff->skb) {
1146 dev_kfree_skb_any(tx_buff->skb);
1147 tx_buff->skb = NULL;
1148 }
1149 }
1150}
1151
1152static void clean_tx_pools(struct ibmvnic_adapter *adapter)
1153{
1109 int tx_scrqs; 1154 int tx_scrqs;
1110 int i, j; 1155 int i;
1111 1156
1112 if (!adapter->tx_pool) 1157 if (!adapter->tx_pool || !adapter->tso_pool)
1113 return; 1158 return;
1114 1159
1115 tx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_txsubm_subcrqs); 1160 tx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_txsubm_subcrqs);
1116 tx_entries = adapter->req_tx_entries_per_subcrq;
1117 1161
1118 /* Free any remaining skbs in the tx buffer pools */ 1162 /* Free any remaining skbs in the tx buffer pools */
1119 for (i = 0; i < tx_scrqs; i++) { 1163 for (i = 0; i < tx_scrqs; i++) {
1120 tx_pool = &adapter->tx_pool[i];
1121 if (!tx_pool)
1122 continue;
1123
1124 netdev_dbg(adapter->netdev, "Cleaning tx_pool[%d]\n", i); 1164 netdev_dbg(adapter->netdev, "Cleaning tx_pool[%d]\n", i);
1125 for (j = 0; j < tx_entries; j++) { 1165 clean_one_tx_pool(adapter, &adapter->tx_pool[i]);
1126 if (tx_pool->tx_buff[j].skb) { 1166 clean_one_tx_pool(adapter, &adapter->tso_pool[i]);
1127 dev_kfree_skb_any(tx_pool->tx_buff[j].skb);
1128 tx_pool->tx_buff[j].skb = NULL;
1129 }
1130 }
1131 } 1167 }
1132} 1168}
1133 1169
1134static int __ibmvnic_close(struct net_device *netdev) 1170static void ibmvnic_cleanup(struct net_device *netdev)
1135{ 1171{
1136 struct ibmvnic_adapter *adapter = netdev_priv(netdev); 1172 struct ibmvnic_adapter *adapter = netdev_priv(netdev);
1137 int rc = 0;
1138 int i; 1173 int i;
1139 1174
1140 adapter->state = VNIC_CLOSING;
1141
1142 /* ensure that transmissions are stopped if called by do_reset */ 1175 /* ensure that transmissions are stopped if called by do_reset */
1143 if (adapter->resetting) 1176 if (adapter->resetting)
1144 netif_tx_disable(netdev); 1177 netif_tx_disable(netdev);
@@ -1150,30 +1183,16 @@ static int __ibmvnic_close(struct net_device *netdev)
1150 if (adapter->tx_scrq) { 1183 if (adapter->tx_scrq) {
1151 for (i = 0; i < adapter->req_tx_queues; i++) 1184 for (i = 0; i < adapter->req_tx_queues; i++)
1152 if (adapter->tx_scrq[i]->irq) { 1185 if (adapter->tx_scrq[i]->irq) {
1153 netdev_dbg(adapter->netdev, 1186 netdev_dbg(netdev,
1154 "Disabling tx_scrq[%d] irq\n", i); 1187 "Disabling tx_scrq[%d] irq\n", i);
1155 disable_irq(adapter->tx_scrq[i]->irq); 1188 disable_irq(adapter->tx_scrq[i]->irq);
1156 } 1189 }
1157 } 1190 }
1158 1191
1159 rc = set_link_state(adapter, IBMVNIC_LOGICAL_LNK_DN);
1160 if (rc)
1161 return rc;
1162
1163 if (adapter->rx_scrq) { 1192 if (adapter->rx_scrq) {
1164 for (i = 0; i < adapter->req_rx_queues; i++) { 1193 for (i = 0; i < adapter->req_rx_queues; i++) {
1165 int retries = 10;
1166
1167 while (pending_scrq(adapter, adapter->rx_scrq[i])) {
1168 retries--;
1169 mdelay(100);
1170
1171 if (retries == 0)
1172 break;
1173 }
1174
1175 if (adapter->rx_scrq[i]->irq) { 1194 if (adapter->rx_scrq[i]->irq) {
1176 netdev_dbg(adapter->netdev, 1195 netdev_dbg(netdev,
1177 "Disabling rx_scrq[%d] irq\n", i); 1196 "Disabling rx_scrq[%d] irq\n", i);
1178 disable_irq(adapter->rx_scrq[i]->irq); 1197 disable_irq(adapter->rx_scrq[i]->irq);
1179 } 1198 }
@@ -1181,8 +1200,20 @@ static int __ibmvnic_close(struct net_device *netdev)
1181 } 1200 }
1182 clean_rx_pools(adapter); 1201 clean_rx_pools(adapter);
1183 clean_tx_pools(adapter); 1202 clean_tx_pools(adapter);
1203}
1204
1205static int __ibmvnic_close(struct net_device *netdev)
1206{
1207 struct ibmvnic_adapter *adapter = netdev_priv(netdev);
1208 int rc = 0;
1209
1210 adapter->state = VNIC_CLOSING;
1211 rc = set_link_state(adapter, IBMVNIC_LOGICAL_LNK_DN);
1212 if (rc)
1213 return rc;
1214 ibmvnic_cleanup(netdev);
1184 adapter->state = VNIC_CLOSED; 1215 adapter->state = VNIC_CLOSED;
1185 return rc; 1216 return 0;
1186} 1217}
1187 1218
1188static int ibmvnic_close(struct net_device *netdev) 1219static int ibmvnic_close(struct net_device *netdev)
@@ -1214,7 +1245,10 @@ static int build_hdr_data(u8 hdr_field, struct sk_buff *skb,
1214 int len = 0; 1245 int len = 0;
1215 u8 *hdr; 1246 u8 *hdr;
1216 1247
1217 hdr_len[0] = sizeof(struct ethhdr); 1248 if (skb_vlan_tagged(skb) && !skb_vlan_tag_present(skb))
1249 hdr_len[0] = sizeof(struct vlan_ethhdr);
1250 else
1251 hdr_len[0] = sizeof(struct ethhdr);
1218 1252
1219 if (skb->protocol == htons(ETH_P_IP)) { 1253 if (skb->protocol == htons(ETH_P_IP)) {
1220 hdr_len[1] = ip_hdr(skb)->ihl * 4; 1254 hdr_len[1] = ip_hdr(skb)->ihl * 4;
@@ -1330,6 +1364,21 @@ static void build_hdr_descs_arr(struct ibmvnic_tx_buff *txbuff,
1330 txbuff->indir_arr + 1); 1364 txbuff->indir_arr + 1);
1331} 1365}
1332 1366
1367static int ibmvnic_xmit_workarounds(struct sk_buff *skb,
1368 struct net_device *netdev)
1369{
1370 /* For some backing devices, mishandling of small packets
1371 * can result in a loss of connection or TX stall. Device
1372 * architects recommend that no packet should be smaller
1373 * than the minimum MTU value provided to the driver, so
1374 * pad any packets to that length
1375 */
1376 if (skb->len < netdev->min_mtu)
1377 return skb_put_padto(skb, netdev->min_mtu);
1378
1379 return 0;
1380}
1381
1333static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) 1382static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
1334{ 1383{
1335 struct ibmvnic_adapter *adapter = netdev_priv(netdev); 1384 struct ibmvnic_adapter *adapter = netdev_priv(netdev);
@@ -1367,7 +1416,17 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
1367 goto out; 1416 goto out;
1368 } 1417 }
1369 1418
1370 tx_pool = &adapter->tx_pool[queue_num]; 1419 if (ibmvnic_xmit_workarounds(skb, netdev)) {
1420 tx_dropped++;
1421 tx_send_failed++;
1422 ret = NETDEV_TX_OK;
1423 goto out;
1424 }
1425 if (skb_is_gso(skb))
1426 tx_pool = &adapter->tso_pool[queue_num];
1427 else
1428 tx_pool = &adapter->tx_pool[queue_num];
1429
1371 tx_scrq = adapter->tx_scrq[queue_num]; 1430 tx_scrq = adapter->tx_scrq[queue_num];
1372 txq = netdev_get_tx_queue(netdev, skb_get_queue_mapping(skb)); 1431 txq = netdev_get_tx_queue(netdev, skb_get_queue_mapping(skb));
1373 handle_array = (u64 *)((u8 *)(adapter->login_rsp_buf) + 1432 handle_array = (u64 *)((u8 *)(adapter->login_rsp_buf) +
@@ -1375,21 +1434,21 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
1375 1434
1376 index = tx_pool->free_map[tx_pool->consumer_index]; 1435 index = tx_pool->free_map[tx_pool->consumer_index];
1377 1436
1378 if (skb_is_gso(skb)) { 1437 if (index == IBMVNIC_INVALID_MAP) {
1379 offset = tx_pool->tso_index * IBMVNIC_TSO_BUF_SZ; 1438 dev_kfree_skb_any(skb);
1380 dst = tx_pool->tso_ltb.buff + offset; 1439 tx_send_failed++;
1381 memset(dst, 0, IBMVNIC_TSO_BUF_SZ); 1440 tx_dropped++;
1382 data_dma_addr = tx_pool->tso_ltb.addr + offset; 1441 ret = NETDEV_TX_OK;
1383 tx_pool->tso_index++; 1442 goto out;
1384 if (tx_pool->tso_index == IBMVNIC_TSO_BUFS)
1385 tx_pool->tso_index = 0;
1386 } else {
1387 offset = index * adapter->req_mtu;
1388 dst = tx_pool->long_term_buff.buff + offset;
1389 memset(dst, 0, adapter->req_mtu);
1390 data_dma_addr = tx_pool->long_term_buff.addr + offset;
1391 } 1443 }
1392 1444
1445 tx_pool->free_map[tx_pool->consumer_index] = IBMVNIC_INVALID_MAP;
1446
1447 offset = index * tx_pool->buf_size;
1448 dst = tx_pool->long_term_buff.buff + offset;
1449 memset(dst, 0, tx_pool->buf_size);
1450 data_dma_addr = tx_pool->long_term_buff.addr + offset;
1451
1393 if (skb_shinfo(skb)->nr_frags) { 1452 if (skb_shinfo(skb)->nr_frags) {
1394 int cur, i; 1453 int cur, i;
1395 1454
@@ -1411,8 +1470,7 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
1411 } 1470 }
1412 1471
1413 tx_pool->consumer_index = 1472 tx_pool->consumer_index =
1414 (tx_pool->consumer_index + 1) % 1473 (tx_pool->consumer_index + 1) % tx_pool->num_buffers;
1415 adapter->req_tx_entries_per_subcrq;
1416 1474
1417 tx_buff = &tx_pool->tx_buff[index]; 1475 tx_buff = &tx_pool->tx_buff[index];
1418 tx_buff->skb = skb; 1476 tx_buff->skb = skb;
@@ -1428,11 +1486,13 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
1428 tx_crq.v1.n_crq_elem = 1; 1486 tx_crq.v1.n_crq_elem = 1;
1429 tx_crq.v1.n_sge = 1; 1487 tx_crq.v1.n_sge = 1;
1430 tx_crq.v1.flags1 = IBMVNIC_TX_COMP_NEEDED; 1488 tx_crq.v1.flags1 = IBMVNIC_TX_COMP_NEEDED;
1431 tx_crq.v1.correlator = cpu_to_be32(index); 1489
1432 if (skb_is_gso(skb)) 1490 if (skb_is_gso(skb))
1433 tx_crq.v1.dma_reg = cpu_to_be16(tx_pool->tso_ltb.map_id); 1491 tx_crq.v1.correlator =
1492 cpu_to_be32(index | IBMVNIC_TSO_POOL_MASK);
1434 else 1493 else
1435 tx_crq.v1.dma_reg = cpu_to_be16(tx_pool->long_term_buff.map_id); 1494 tx_crq.v1.correlator = cpu_to_be32(index);
1495 tx_crq.v1.dma_reg = cpu_to_be16(tx_pool->long_term_buff.map_id);
1436 tx_crq.v1.sge_len = cpu_to_be32(skb->len); 1496 tx_crq.v1.sge_len = cpu_to_be32(skb->len);
1437 tx_crq.v1.ioba = cpu_to_be64(data_dma_addr); 1497 tx_crq.v1.ioba = cpu_to_be64(data_dma_addr);
1438 1498
@@ -1467,6 +1527,7 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
1467 if ((*hdrs >> 7) & 1) { 1527 if ((*hdrs >> 7) & 1) {
1468 build_hdr_descs_arr(tx_buff, &num_entries, *hdrs); 1528 build_hdr_descs_arr(tx_buff, &num_entries, *hdrs);
1469 tx_crq.v1.n_crq_elem = num_entries; 1529 tx_crq.v1.n_crq_elem = num_entries;
1530 tx_buff->num_entries = num_entries;
1470 tx_buff->indir_arr[0] = tx_crq; 1531 tx_buff->indir_arr[0] = tx_crq;
1471 tx_buff->indir_dma = dma_map_single(dev, tx_buff->indir_arr, 1532 tx_buff->indir_dma = dma_map_single(dev, tx_buff->indir_arr,
1472 sizeof(tx_buff->indir_arr), 1533 sizeof(tx_buff->indir_arr),
@@ -1479,24 +1540,18 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
1479 tx_map_failed++; 1540 tx_map_failed++;
1480 tx_dropped++; 1541 tx_dropped++;
1481 ret = NETDEV_TX_OK; 1542 ret = NETDEV_TX_OK;
1482 goto out; 1543 goto tx_err_out;
1483 } 1544 }
1484 lpar_rc = send_subcrq_indirect(adapter, handle_array[queue_num], 1545 lpar_rc = send_subcrq_indirect(adapter, handle_array[queue_num],
1485 (u64)tx_buff->indir_dma, 1546 (u64)tx_buff->indir_dma,
1486 (u64)num_entries); 1547 (u64)num_entries);
1487 } else { 1548 } else {
1549 tx_buff->num_entries = num_entries;
1488 lpar_rc = send_subcrq(adapter, handle_array[queue_num], 1550 lpar_rc = send_subcrq(adapter, handle_array[queue_num],
1489 &tx_crq); 1551 &tx_crq);
1490 } 1552 }
1491 if (lpar_rc != H_SUCCESS) { 1553 if (lpar_rc != H_SUCCESS) {
1492 dev_err(dev, "tx failed with code %ld\n", lpar_rc); 1554 dev_err(dev, "tx failed with code %ld\n", lpar_rc);
1493
1494 if (tx_pool->consumer_index == 0)
1495 tx_pool->consumer_index =
1496 adapter->req_tx_entries_per_subcrq - 1;
1497 else
1498 tx_pool->consumer_index--;
1499
1500 dev_kfree_skb_any(skb); 1555 dev_kfree_skb_any(skb);
1501 tx_buff->skb = NULL; 1556 tx_buff->skb = NULL;
1502 1557
@@ -1512,12 +1567,12 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
1512 tx_send_failed++; 1567 tx_send_failed++;
1513 tx_dropped++; 1568 tx_dropped++;
1514 ret = NETDEV_TX_OK; 1569 ret = NETDEV_TX_OK;
1515 goto out; 1570 goto tx_err_out;
1516 } 1571 }
1517 1572
1518 if (atomic_inc_return(&tx_scrq->used) 1573 if (atomic_add_return(num_entries, &tx_scrq->used)
1519 >= adapter->req_tx_entries_per_subcrq) { 1574 >= adapter->req_tx_entries_per_subcrq) {
1520 netdev_info(netdev, "Stopping queue %d\n", queue_num); 1575 netdev_dbg(netdev, "Stopping queue %d\n", queue_num);
1521 netif_stop_subqueue(netdev, queue_num); 1576 netif_stop_subqueue(netdev, queue_num);
1522 } 1577 }
1523 1578
@@ -1525,7 +1580,16 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
1525 tx_bytes += skb->len; 1580 tx_bytes += skb->len;
1526 txq->trans_start = jiffies; 1581 txq->trans_start = jiffies;
1527 ret = NETDEV_TX_OK; 1582 ret = NETDEV_TX_OK;
1583 goto out;
1528 1584
1585tx_err_out:
1586 /* roll back consumer index and map array*/
1587 if (tx_pool->consumer_index == 0)
1588 tx_pool->consumer_index =
1589 tx_pool->num_buffers - 1;
1590 else
1591 tx_pool->consumer_index--;
1592 tx_pool->free_map[tx_pool->consumer_index] = index;
1529out: 1593out:
1530 netdev->stats.tx_dropped += tx_dropped; 1594 netdev->stats.tx_dropped += tx_dropped;
1531 netdev->stats.tx_bytes += tx_bytes; 1595 netdev->stats.tx_bytes += tx_bytes;
@@ -1644,16 +1708,19 @@ static int do_reset(struct ibmvnic_adapter *adapter,
1644 rc = ibmvnic_reenable_crq_queue(adapter); 1708 rc = ibmvnic_reenable_crq_queue(adapter);
1645 if (rc) 1709 if (rc)
1646 return 0; 1710 return 0;
1711 ibmvnic_cleanup(netdev);
1712 } else if (rwi->reset_reason == VNIC_RESET_FAILOVER) {
1713 ibmvnic_cleanup(netdev);
1714 } else {
1715 rc = __ibmvnic_close(netdev);
1716 if (rc)
1717 return rc;
1647 } 1718 }
1648 1719
1649 rc = __ibmvnic_close(netdev);
1650 if (rc)
1651 return rc;
1652
1653 if (adapter->reset_reason == VNIC_RESET_CHANGE_PARAM || 1720 if (adapter->reset_reason == VNIC_RESET_CHANGE_PARAM ||
1654 adapter->wait_for_reset) { 1721 adapter->wait_for_reset) {
1655 release_resources(adapter); 1722 release_resources(adapter);
1656 release_sub_crqs(adapter); 1723 release_sub_crqs(adapter, 1);
1657 release_crq_queue(adapter); 1724 release_crq_queue(adapter);
1658 } 1725 }
1659 1726
@@ -1691,6 +1758,9 @@ static int do_reset(struct ibmvnic_adapter *adapter,
1691 release_tx_pools(adapter); 1758 release_tx_pools(adapter);
1692 init_rx_pools(netdev); 1759 init_rx_pools(netdev);
1693 init_tx_pools(netdev); 1760 init_tx_pools(netdev);
1761
1762 release_napi(adapter);
1763 init_napi(adapter);
1694 } else { 1764 } else {
1695 rc = reset_tx_pools(adapter); 1765 rc = reset_tx_pools(adapter);
1696 if (rc) 1766 if (rc)
@@ -1699,12 +1769,14 @@ static int do_reset(struct ibmvnic_adapter *adapter,
1699 rc = reset_rx_pools(adapter); 1769 rc = reset_rx_pools(adapter);
1700 if (rc) 1770 if (rc)
1701 return rc; 1771 return rc;
1702
1703 if (reset_state == VNIC_CLOSED)
1704 return 0;
1705 } 1772 }
1706 } 1773 }
1707 1774
1775 adapter->state = VNIC_CLOSED;
1776
1777 if (reset_state == VNIC_CLOSED)
1778 return 0;
1779
1708 rc = __ibmvnic_open(netdev); 1780 rc = __ibmvnic_open(netdev);
1709 if (rc) { 1781 if (rc) {
1710 if (list_empty(&adapter->rwi_list)) 1782 if (list_empty(&adapter->rwi_list))
@@ -2011,6 +2083,23 @@ static int ibmvnic_change_mtu(struct net_device *netdev, int new_mtu)
2011 return wait_for_reset(adapter); 2083 return wait_for_reset(adapter);
2012} 2084}
2013 2085
2086static netdev_features_t ibmvnic_features_check(struct sk_buff *skb,
2087 struct net_device *dev,
2088 netdev_features_t features)
2089{
2090 /* Some backing hardware adapters can not
2091 * handle packets with a MSS less than 224
2092 * or with only one segment.
2093 */
2094 if (skb_is_gso(skb)) {
2095 if (skb_shinfo(skb)->gso_size < 224 ||
2096 skb_shinfo(skb)->gso_segs == 1)
2097 features &= ~NETIF_F_GSO_MASK;
2098 }
2099
2100 return features;
2101}
2102
2014static const struct net_device_ops ibmvnic_netdev_ops = { 2103static const struct net_device_ops ibmvnic_netdev_ops = {
2015 .ndo_open = ibmvnic_open, 2104 .ndo_open = ibmvnic_open,
2016 .ndo_stop = ibmvnic_close, 2105 .ndo_stop = ibmvnic_close,
@@ -2023,6 +2112,7 @@ static const struct net_device_ops ibmvnic_netdev_ops = {
2023 .ndo_poll_controller = ibmvnic_netpoll_controller, 2112 .ndo_poll_controller = ibmvnic_netpoll_controller,
2024#endif 2113#endif
2025 .ndo_change_mtu = ibmvnic_change_mtu, 2114 .ndo_change_mtu = ibmvnic_change_mtu,
2115 .ndo_features_check = ibmvnic_features_check,
2026}; 2116};
2027 2117
2028/* ethtool functions */ 2118/* ethtool functions */
@@ -2295,24 +2385,27 @@ static int reset_sub_crq_queues(struct ibmvnic_adapter *adapter)
2295} 2385}
2296 2386
2297static void release_sub_crq_queue(struct ibmvnic_adapter *adapter, 2387static void release_sub_crq_queue(struct ibmvnic_adapter *adapter,
2298 struct ibmvnic_sub_crq_queue *scrq) 2388 struct ibmvnic_sub_crq_queue *scrq,
2389 bool do_h_free)
2299{ 2390{
2300 struct device *dev = &adapter->vdev->dev; 2391 struct device *dev = &adapter->vdev->dev;
2301 long rc; 2392 long rc;
2302 2393
2303 netdev_dbg(adapter->netdev, "Releasing sub-CRQ\n"); 2394 netdev_dbg(adapter->netdev, "Releasing sub-CRQ\n");
2304 2395
2305 /* Close the sub-crqs */ 2396 if (do_h_free) {
2306 do { 2397 /* Close the sub-crqs */
2307 rc = plpar_hcall_norets(H_FREE_SUB_CRQ, 2398 do {
2308 adapter->vdev->unit_address, 2399 rc = plpar_hcall_norets(H_FREE_SUB_CRQ,
2309 scrq->crq_num); 2400 adapter->vdev->unit_address,
2310 } while (rc == H_BUSY || H_IS_LONG_BUSY(rc)); 2401 scrq->crq_num);
2402 } while (rc == H_BUSY || H_IS_LONG_BUSY(rc));
2311 2403
2312 if (rc) { 2404 if (rc) {
2313 netdev_err(adapter->netdev, 2405 netdev_err(adapter->netdev,
2314 "Failed to release sub-CRQ %16lx, rc = %ld\n", 2406 "Failed to release sub-CRQ %16lx, rc = %ld\n",
2315 scrq->crq_num, rc); 2407 scrq->crq_num, rc);
2408 }
2316 } 2409 }
2317 2410
2318 dma_unmap_single(dev, scrq->msg_token, 4 * PAGE_SIZE, 2411 dma_unmap_single(dev, scrq->msg_token, 4 * PAGE_SIZE,
@@ -2380,12 +2473,12 @@ zero_page_failed:
2380 return NULL; 2473 return NULL;
2381} 2474}
2382 2475
2383static void release_sub_crqs(struct ibmvnic_adapter *adapter) 2476static void release_sub_crqs(struct ibmvnic_adapter *adapter, bool do_h_free)
2384{ 2477{
2385 int i; 2478 int i;
2386 2479
2387 if (adapter->tx_scrq) { 2480 if (adapter->tx_scrq) {
2388 for (i = 0; i < adapter->req_tx_queues; i++) { 2481 for (i = 0; i < adapter->num_active_tx_scrqs; i++) {
2389 if (!adapter->tx_scrq[i]) 2482 if (!adapter->tx_scrq[i])
2390 continue; 2483 continue;
2391 2484
@@ -2398,15 +2491,17 @@ static void release_sub_crqs(struct ibmvnic_adapter *adapter)
2398 adapter->tx_scrq[i]->irq = 0; 2491 adapter->tx_scrq[i]->irq = 0;
2399 } 2492 }
2400 2493
2401 release_sub_crq_queue(adapter, adapter->tx_scrq[i]); 2494 release_sub_crq_queue(adapter, adapter->tx_scrq[i],
2495 do_h_free);
2402 } 2496 }
2403 2497
2404 kfree(adapter->tx_scrq); 2498 kfree(adapter->tx_scrq);
2405 adapter->tx_scrq = NULL; 2499 adapter->tx_scrq = NULL;
2500 adapter->num_active_tx_scrqs = 0;
2406 } 2501 }
2407 2502
2408 if (adapter->rx_scrq) { 2503 if (adapter->rx_scrq) {
2409 for (i = 0; i < adapter->req_rx_queues; i++) { 2504 for (i = 0; i < adapter->num_active_rx_scrqs; i++) {
2410 if (!adapter->rx_scrq[i]) 2505 if (!adapter->rx_scrq[i])
2411 continue; 2506 continue;
2412 2507
@@ -2419,11 +2514,13 @@ static void release_sub_crqs(struct ibmvnic_adapter *adapter)
2419 adapter->rx_scrq[i]->irq = 0; 2514 adapter->rx_scrq[i]->irq = 0;
2420 } 2515 }
2421 2516
2422 release_sub_crq_queue(adapter, adapter->rx_scrq[i]); 2517 release_sub_crq_queue(adapter, adapter->rx_scrq[i],
2518 do_h_free);
2423 } 2519 }
2424 2520
2425 kfree(adapter->rx_scrq); 2521 kfree(adapter->rx_scrq);
2426 adapter->rx_scrq = NULL; 2522 adapter->rx_scrq = NULL;
2523 adapter->num_active_rx_scrqs = 0;
2427 } 2524 }
2428} 2525}
2429 2526
@@ -2464,6 +2561,7 @@ static int ibmvnic_complete_tx(struct ibmvnic_adapter *adapter,
2464 struct ibmvnic_sub_crq_queue *scrq) 2561 struct ibmvnic_sub_crq_queue *scrq)
2465{ 2562{
2466 struct device *dev = &adapter->vdev->dev; 2563 struct device *dev = &adapter->vdev->dev;
2564 struct ibmvnic_tx_pool *tx_pool;
2467 struct ibmvnic_tx_buff *txbuff; 2565 struct ibmvnic_tx_buff *txbuff;
2468 union sub_crq *next; 2566 union sub_crq *next;
2469 int index; 2567 int index;
@@ -2473,6 +2571,7 @@ static int ibmvnic_complete_tx(struct ibmvnic_adapter *adapter,
2473restart_loop: 2571restart_loop:
2474 while (pending_scrq(adapter, scrq)) { 2572 while (pending_scrq(adapter, scrq)) {
2475 unsigned int pool = scrq->pool_index; 2573 unsigned int pool = scrq->pool_index;
2574 int num_entries = 0;
2476 2575
2477 next = ibmvnic_next_scrq(adapter, scrq); 2576 next = ibmvnic_next_scrq(adapter, scrq);
2478 for (i = 0; i < next->tx_comp.num_comps; i++) { 2577 for (i = 0; i < next->tx_comp.num_comps; i++) {
@@ -2482,7 +2581,14 @@ restart_loop:
2482 continue; 2581 continue;
2483 } 2582 }
2484 index = be32_to_cpu(next->tx_comp.correlators[i]); 2583 index = be32_to_cpu(next->tx_comp.correlators[i]);
2485 txbuff = &adapter->tx_pool[pool].tx_buff[index]; 2584 if (index & IBMVNIC_TSO_POOL_MASK) {
2585 tx_pool = &adapter->tso_pool[pool];
2586 index &= ~IBMVNIC_TSO_POOL_MASK;
2587 } else {
2588 tx_pool = &adapter->tx_pool[pool];
2589 }
2590
2591 txbuff = &tx_pool->tx_buff[index];
2486 2592
2487 for (j = 0; j < IBMVNIC_MAX_FRAGS_PER_CRQ; j++) { 2593 for (j = 0; j < IBMVNIC_MAX_FRAGS_PER_CRQ; j++) {
2488 if (!txbuff->data_dma[j]) 2594 if (!txbuff->data_dma[j])
@@ -2503,22 +2609,23 @@ restart_loop:
2503 txbuff->skb = NULL; 2609 txbuff->skb = NULL;
2504 } 2610 }
2505 2611
2506 adapter->tx_pool[pool].free_map[adapter->tx_pool[pool]. 2612 num_entries += txbuff->num_entries;
2507 producer_index] = index; 2613
2508 adapter->tx_pool[pool].producer_index = 2614 tx_pool->free_map[tx_pool->producer_index] = index;
2509 (adapter->tx_pool[pool].producer_index + 1) % 2615 tx_pool->producer_index =
2510 adapter->req_tx_entries_per_subcrq; 2616 (tx_pool->producer_index + 1) %
2617 tx_pool->num_buffers;
2511 } 2618 }
2512 /* remove tx_comp scrq*/ 2619 /* remove tx_comp scrq*/
2513 next->tx_comp.first = 0; 2620 next->tx_comp.first = 0;
2514 2621
2515 if (atomic_sub_return(next->tx_comp.num_comps, &scrq->used) <= 2622 if (atomic_sub_return(num_entries, &scrq->used) <=
2516 (adapter->req_tx_entries_per_subcrq / 2) && 2623 (adapter->req_tx_entries_per_subcrq / 2) &&
2517 __netif_subqueue_stopped(adapter->netdev, 2624 __netif_subqueue_stopped(adapter->netdev,
2518 scrq->pool_index)) { 2625 scrq->pool_index)) {
2519 netif_wake_subqueue(adapter->netdev, scrq->pool_index); 2626 netif_wake_subqueue(adapter->netdev, scrq->pool_index);
2520 netdev_info(adapter->netdev, "Started queue %d\n", 2627 netdev_dbg(adapter->netdev, "Started queue %d\n",
2521 scrq->pool_index); 2628 scrq->pool_index);
2522 } 2629 }
2523 } 2630 }
2524 2631
@@ -2590,7 +2697,7 @@ static int init_sub_crq_irqs(struct ibmvnic_adapter *adapter)
2590 dev_err(dev, "Couldn't register tx irq 0x%x. rc=%d\n", 2697 dev_err(dev, "Couldn't register tx irq 0x%x. rc=%d\n",
2591 scrq->irq, rc); 2698 scrq->irq, rc);
2592 irq_dispose_mapping(scrq->irq); 2699 irq_dispose_mapping(scrq->irq);
2593 goto req_rx_irq_failed; 2700 goto req_tx_irq_failed;
2594 } 2701 }
2595 } 2702 }
2596 2703
@@ -2626,7 +2733,7 @@ req_tx_irq_failed:
2626 free_irq(adapter->tx_scrq[j]->irq, adapter->tx_scrq[j]); 2733 free_irq(adapter->tx_scrq[j]->irq, adapter->tx_scrq[j]);
2627 irq_dispose_mapping(adapter->rx_scrq[j]->irq); 2734 irq_dispose_mapping(adapter->rx_scrq[j]->irq);
2628 } 2735 }
2629 release_sub_crqs(adapter); 2736 release_sub_crqs(adapter, 1);
2630 return rc; 2737 return rc;
2631} 2738}
2632 2739
@@ -2688,6 +2795,7 @@ static int init_sub_crqs(struct ibmvnic_adapter *adapter)
2688 for (i = 0; i < adapter->req_tx_queues; i++) { 2795 for (i = 0; i < adapter->req_tx_queues; i++) {
2689 adapter->tx_scrq[i] = allqueues[i]; 2796 adapter->tx_scrq[i] = allqueues[i];
2690 adapter->tx_scrq[i]->pool_index = i; 2797 adapter->tx_scrq[i]->pool_index = i;
2798 adapter->num_active_tx_scrqs++;
2691 } 2799 }
2692 2800
2693 adapter->rx_scrq = kcalloc(adapter->req_rx_queues, 2801 adapter->rx_scrq = kcalloc(adapter->req_rx_queues,
@@ -2698,6 +2806,7 @@ static int init_sub_crqs(struct ibmvnic_adapter *adapter)
2698 for (i = 0; i < adapter->req_rx_queues; i++) { 2806 for (i = 0; i < adapter->req_rx_queues; i++) {
2699 adapter->rx_scrq[i] = allqueues[i + adapter->req_tx_queues]; 2807 adapter->rx_scrq[i] = allqueues[i + adapter->req_tx_queues];
2700 adapter->rx_scrq[i]->scrq_num = i; 2808 adapter->rx_scrq[i]->scrq_num = i;
2809 adapter->num_active_rx_scrqs++;
2701 } 2810 }
2702 2811
2703 kfree(allqueues); 2812 kfree(allqueues);
@@ -2708,7 +2817,7 @@ rx_failed:
2708 adapter->tx_scrq = NULL; 2817 adapter->tx_scrq = NULL;
2709tx_failed: 2818tx_failed:
2710 for (i = 0; i < registered_queues; i++) 2819 for (i = 0; i < registered_queues; i++)
2711 release_sub_crq_queue(adapter, allqueues[i]); 2820 release_sub_crq_queue(adapter, allqueues[i], 1);
2712 kfree(allqueues); 2821 kfree(allqueues);
2713 return -1; 2822 return -1;
2714} 2823}
@@ -3048,7 +3157,7 @@ static void vnic_add_client_data(struct ibmvnic_adapter *adapter,
3048 strncpy(&vlcd->name, adapter->netdev->name, len); 3157 strncpy(&vlcd->name, adapter->netdev->name, len);
3049} 3158}
3050 3159
3051static void send_login(struct ibmvnic_adapter *adapter) 3160static int send_login(struct ibmvnic_adapter *adapter)
3052{ 3161{
3053 struct ibmvnic_login_rsp_buffer *login_rsp_buffer; 3162 struct ibmvnic_login_rsp_buffer *login_rsp_buffer;
3054 struct ibmvnic_login_buffer *login_buffer; 3163 struct ibmvnic_login_buffer *login_buffer;
@@ -3064,6 +3173,12 @@ static void send_login(struct ibmvnic_adapter *adapter)
3064 struct vnic_login_client_data *vlcd; 3173 struct vnic_login_client_data *vlcd;
3065 int i; 3174 int i;
3066 3175
3176 if (!adapter->tx_scrq || !adapter->rx_scrq) {
3177 netdev_err(adapter->netdev,
3178 "RX or TX queues are not allocated, device login failed\n");
3179 return -1;
3180 }
3181
3067 release_login_rsp_buffer(adapter); 3182 release_login_rsp_buffer(adapter);
3068 client_data_len = vnic_client_data_len(adapter); 3183 client_data_len = vnic_client_data_len(adapter);
3069 3184
@@ -3161,7 +3276,7 @@ static void send_login(struct ibmvnic_adapter *adapter)
3161 crq.login.len = cpu_to_be32(buffer_size); 3276 crq.login.len = cpu_to_be32(buffer_size);
3162 ibmvnic_send_crq(adapter, &crq); 3277 ibmvnic_send_crq(adapter, &crq);
3163 3278
3164 return; 3279 return 0;
3165 3280
3166buf_rsp_map_failed: 3281buf_rsp_map_failed:
3167 kfree(login_rsp_buffer); 3282 kfree(login_rsp_buffer);
@@ -3170,7 +3285,7 @@ buf_rsp_alloc_failed:
3170buf_map_failed: 3285buf_map_failed:
3171 kfree(login_buffer); 3286 kfree(login_buffer);
3172buf_alloc_failed: 3287buf_alloc_failed:
3173 return; 3288 return -1;
3174} 3289}
3175 3290
3176static void send_request_map(struct ibmvnic_adapter *adapter, dma_addr_t addr, 3291static void send_request_map(struct ibmvnic_adapter *adapter, dma_addr_t addr,
@@ -4335,6 +4450,7 @@ static int ibmvnic_init(struct ibmvnic_adapter *adapter)
4335{ 4450{
4336 struct device *dev = &adapter->vdev->dev; 4451 struct device *dev = &adapter->vdev->dev;
4337 unsigned long timeout = msecs_to_jiffies(30000); 4452 unsigned long timeout = msecs_to_jiffies(30000);
4453 u64 old_num_rx_queues, old_num_tx_queues;
4338 int rc; 4454 int rc;
4339 4455
4340 if (adapter->resetting && !adapter->wait_for_reset) { 4456 if (adapter->resetting && !adapter->wait_for_reset) {
@@ -4352,6 +4468,9 @@ static int ibmvnic_init(struct ibmvnic_adapter *adapter)
4352 4468
4353 adapter->from_passive_init = false; 4469 adapter->from_passive_init = false;
4354 4470
4471 old_num_rx_queues = adapter->req_rx_queues;
4472 old_num_tx_queues = adapter->req_tx_queues;
4473
4355 init_completion(&adapter->init_done); 4474 init_completion(&adapter->init_done);
4356 adapter->init_done_rc = 0; 4475 adapter->init_done_rc = 0;
4357 ibmvnic_send_crq_init(adapter); 4476 ibmvnic_send_crq_init(adapter);
@@ -4371,10 +4490,18 @@ static int ibmvnic_init(struct ibmvnic_adapter *adapter)
4371 return -1; 4490 return -1;
4372 } 4491 }
4373 4492
4374 if (adapter->resetting && !adapter->wait_for_reset) 4493 if (adapter->resetting && !adapter->wait_for_reset) {
4375 rc = reset_sub_crq_queues(adapter); 4494 if (adapter->req_rx_queues != old_num_rx_queues ||
4376 else 4495 adapter->req_tx_queues != old_num_tx_queues) {
4496 release_sub_crqs(adapter, 0);
4497 rc = init_sub_crqs(adapter);
4498 } else {
4499 rc = reset_sub_crq_queues(adapter);
4500 }
4501 } else {
4377 rc = init_sub_crqs(adapter); 4502 rc = init_sub_crqs(adapter);
4503 }
4504
4378 if (rc) { 4505 if (rc) {
4379 dev_err(dev, "Initialization of sub crqs failed\n"); 4506 dev_err(dev, "Initialization of sub crqs failed\n");
4380 release_crq_queue(adapter); 4507 release_crq_queue(adapter);
@@ -4387,6 +4514,14 @@ static int ibmvnic_init(struct ibmvnic_adapter *adapter)
4387 release_crq_queue(adapter); 4514 release_crq_queue(adapter);
4388 } 4515 }
4389 4516
4517 rc = init_stats_buffers(adapter);
4518 if (rc)
4519 return rc;
4520
4521 rc = init_stats_token(adapter);
4522 if (rc)
4523 return rc;
4524
4390 return rc; 4525 return rc;
4391} 4526}
4392 4527
@@ -4474,7 +4609,7 @@ ibmvnic_register_fail:
4474 device_remove_file(&dev->dev, &dev_attr_failover); 4609 device_remove_file(&dev->dev, &dev_attr_failover);
4475 4610
4476ibmvnic_init_fail: 4611ibmvnic_init_fail:
4477 release_sub_crqs(adapter); 4612 release_sub_crqs(adapter, 1);
4478 release_crq_queue(adapter); 4613 release_crq_queue(adapter);
4479 free_netdev(netdev); 4614 free_netdev(netdev);
4480 4615
@@ -4491,9 +4626,12 @@ static int ibmvnic_remove(struct vio_dev *dev)
4491 mutex_lock(&adapter->reset_lock); 4626 mutex_lock(&adapter->reset_lock);
4492 4627
4493 release_resources(adapter); 4628 release_resources(adapter);
4494 release_sub_crqs(adapter); 4629 release_sub_crqs(adapter, 1);
4495 release_crq_queue(adapter); 4630 release_crq_queue(adapter);
4496 4631
4632 release_stats_token(adapter);
4633 release_stats_buffers(adapter);
4634
4497 adapter->state = VNIC_REMOVED; 4635 adapter->state = VNIC_REMOVED;
4498 4636
4499 mutex_unlock(&adapter->reset_lock); 4637 mutex_unlock(&adapter->reset_lock);
diff --git a/drivers/net/ethernet/ibm/ibmvnic.h b/drivers/net/ethernet/ibm/ibmvnic.h
index fe21a6e2ddae..89efe700eafe 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.h
+++ b/drivers/net/ethernet/ibm/ibmvnic.h
@@ -43,6 +43,7 @@
43 43
44#define IBMVNIC_TSO_BUF_SZ 65536 44#define IBMVNIC_TSO_BUF_SZ 65536
45#define IBMVNIC_TSO_BUFS 64 45#define IBMVNIC_TSO_BUFS 64
46#define IBMVNIC_TSO_POOL_MASK 0x80000000
46 47
47#define IBMVNIC_MAX_LTB_SIZE ((1 << (MAX_ORDER - 1)) * PAGE_SIZE) 48#define IBMVNIC_MAX_LTB_SIZE ((1 << (MAX_ORDER - 1)) * PAGE_SIZE)
48#define IBMVNIC_BUFFER_HLEN 500 49#define IBMVNIC_BUFFER_HLEN 500
@@ -909,6 +910,7 @@ struct ibmvnic_tx_buff {
909 union sub_crq indir_arr[6]; 910 union sub_crq indir_arr[6];
910 u8 hdr_data[140]; 911 u8 hdr_data[140];
911 dma_addr_t indir_dma; 912 dma_addr_t indir_dma;
913 int num_entries;
912}; 914};
913 915
914struct ibmvnic_tx_pool { 916struct ibmvnic_tx_pool {
@@ -916,11 +918,9 @@ struct ibmvnic_tx_pool {
916 int *free_map; 918 int *free_map;
917 int consumer_index; 919 int consumer_index;
918 int producer_index; 920 int producer_index;
919 wait_queue_head_t ibmvnic_tx_comp_q;
920 struct task_struct *work_thread;
921 struct ibmvnic_long_term_buff long_term_buff; 921 struct ibmvnic_long_term_buff long_term_buff;
922 struct ibmvnic_long_term_buff tso_ltb; 922 int num_buffers;
923 int tso_index; 923 int buf_size;
924}; 924};
925 925
926struct ibmvnic_rx_buff { 926struct ibmvnic_rx_buff {
@@ -1043,6 +1043,7 @@ struct ibmvnic_adapter {
1043 u64 promisc; 1043 u64 promisc;
1044 1044
1045 struct ibmvnic_tx_pool *tx_pool; 1045 struct ibmvnic_tx_pool *tx_pool;
1046 struct ibmvnic_tx_pool *tso_pool;
1046 struct completion init_done; 1047 struct completion init_done;
1047 int init_done_rc; 1048 int init_done_rc;
1048 1049
@@ -1091,8 +1092,11 @@ struct ibmvnic_adapter {
1091 u64 opt_rxba_entries_per_subcrq; 1092 u64 opt_rxba_entries_per_subcrq;
1092 __be64 tx_rx_desc_req; 1093 __be64 tx_rx_desc_req;
1093 u8 map_id; 1094 u8 map_id;
1094 u64 num_active_rx_pools; 1095 u32 num_active_rx_scrqs;
1095 u64 num_active_tx_pools; 1096 u32 num_active_rx_pools;
1097 u32 num_active_rx_napi;
1098 u32 num_active_tx_scrqs;
1099 u32 num_active_tx_pools;
1096 1100
1097 struct tasklet_struct tasklet; 1101 struct tasklet_struct tasklet;
1098 enum vnic_state state; 1102 enum vnic_state state;
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_common.c b/drivers/net/ethernet/intel/fm10k/fm10k_common.c
index 736a9f087bc9..c58a5377a287 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_common.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_common.c
@@ -1,5 +1,5 @@
1/* Intel(R) Ethernet Switch Host Interface Driver 1/* Intel(R) Ethernet Switch Host Interface Driver
2 * Copyright(c) 2013 - 2017 Intel Corporation. 2 * Copyright(c) 2013 - 2018 Intel Corporation.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License, 5 * under the terms and conditions of the GNU General Public License,
@@ -262,6 +262,7 @@ s32 fm10k_stop_hw_generic(struct fm10k_hw *hw)
262 * fm10k_read_hw_stats_32b - Reads value of 32-bit registers 262 * fm10k_read_hw_stats_32b - Reads value of 32-bit registers
263 * @hw: pointer to the hardware structure 263 * @hw: pointer to the hardware structure
264 * @addr: address of register containing a 32-bit value 264 * @addr: address of register containing a 32-bit value
265 * @stat: pointer to structure holding hw stat information
265 * 266 *
266 * Function reads the content of the register and returns the delta 267 * Function reads the content of the register and returns the delta
267 * between the base and the current value. 268 * between the base and the current value.
@@ -281,6 +282,7 @@ u32 fm10k_read_hw_stats_32b(struct fm10k_hw *hw, u32 addr,
281 * fm10k_read_hw_stats_48b - Reads value of 48-bit registers 282 * fm10k_read_hw_stats_48b - Reads value of 48-bit registers
282 * @hw: pointer to the hardware structure 283 * @hw: pointer to the hardware structure
283 * @addr: address of register containing the lower 32-bit value 284 * @addr: address of register containing the lower 32-bit value
285 * @stat: pointer to structure holding hw stat information
284 * 286 *
285 * Function reads the content of 2 registers, combined to represent a 48-bit 287 * Function reads the content of 2 registers, combined to represent a 48-bit
286 * statistical value. Extra processing is required to handle overflowing. 288 * statistical value. Extra processing is required to handle overflowing.
@@ -461,7 +463,6 @@ void fm10k_update_hw_stats_q(struct fm10k_hw *hw, struct fm10k_hw_stats_q *q,
461 463
462/** 464/**
463 * fm10k_unbind_hw_stats_q - Unbind the queue counters from their queues 465 * fm10k_unbind_hw_stats_q - Unbind the queue counters from their queues
464 * @hw: pointer to the hardware structure
465 * @q: pointer to the ring of hardware statistics queue 466 * @q: pointer to the ring of hardware statistics queue
466 * @idx: index pointing to the start of the ring iteration 467 * @idx: index pointing to the start of the ring iteration
467 * @count: number of queues to iterate over 468 * @count: number of queues to iterate over
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_main.c b/drivers/net/ethernet/intel/fm10k/fm10k_main.c
index 8e12aae065d8..2c93d719438f 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_main.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_main.c
@@ -28,13 +28,13 @@
28 28
29#include "fm10k.h" 29#include "fm10k.h"
30 30
31#define DRV_VERSION "0.22.1-k" 31#define DRV_VERSION "0.23.4-k"
32#define DRV_SUMMARY "Intel(R) Ethernet Switch Host Interface Driver" 32#define DRV_SUMMARY "Intel(R) Ethernet Switch Host Interface Driver"
33const char fm10k_driver_version[] = DRV_VERSION; 33const char fm10k_driver_version[] = DRV_VERSION;
34char fm10k_driver_name[] = "fm10k"; 34char fm10k_driver_name[] = "fm10k";
35static const char fm10k_driver_string[] = DRV_SUMMARY; 35static const char fm10k_driver_string[] = DRV_SUMMARY;
36static const char fm10k_copyright[] = 36static const char fm10k_copyright[] =
37 "Copyright(c) 2013 - 2017 Intel Corporation."; 37 "Copyright(c) 2013 - 2018 Intel Corporation.";
38 38
39MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>"); 39MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
40MODULE_DESCRIPTION(DRV_SUMMARY); 40MODULE_DESCRIPTION(DRV_SUMMARY);
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
index a38ae5c54da3..75c99aed3c41 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
@@ -1,5 +1,5 @@
1/* Intel(R) Ethernet Switch Host Interface Driver 1/* Intel(R) Ethernet Switch Host Interface Driver
2 * Copyright(c) 2013 - 2017 Intel Corporation. 2 * Copyright(c) 2013 - 2018 Intel Corporation.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License, 5 * under the terms and conditions of the GNU General Public License,
@@ -486,7 +486,7 @@ static void fm10k_insert_tunnel_port(struct list_head *ports,
486 486
487/** 487/**
488 * fm10k_udp_tunnel_add 488 * fm10k_udp_tunnel_add
489 * @netdev: network interface device structure 489 * @dev: network interface device structure
490 * @ti: Tunnel endpoint information 490 * @ti: Tunnel endpoint information
491 * 491 *
492 * This function is called when a new UDP tunnel port has been added. 492 * This function is called when a new UDP tunnel port has been added.
@@ -518,8 +518,8 @@ static void fm10k_udp_tunnel_add(struct net_device *dev,
518 518
519/** 519/**
520 * fm10k_udp_tunnel_del 520 * fm10k_udp_tunnel_del
521 * @netdev: network interface device structure 521 * @dev: network interface device structure
522 * @ti: Tunnel endpoint information 522 * @ti: Tunnel end point information
523 * 523 *
524 * This function is called when a new UDP tunnel port is deleted. The freed 524 * This function is called when a new UDP tunnel port is deleted. The freed
525 * port will be removed from the list, then we reprogram the offloaded port 525 * port will be removed from the list, then we reprogram the offloaded port
@@ -803,7 +803,7 @@ int fm10k_queue_vlan_request(struct fm10k_intfc *interface,
803 * @glort: the target glort for this update 803 * @glort: the target glort for this update
804 * @addr: the address to update 804 * @addr: the address to update
805 * @vid: the vid to update 805 * @vid: the vid to update
806 * @sync: whether to add or remove 806 * @set: whether to add or remove
807 * 807 *
808 * This function queues up a MAC request for sending to the switch manager. 808 * This function queues up a MAC request for sending to the switch manager.
809 * A separate thread monitors the queue and sends updates to the switch 809 * A separate thread monitors the queue and sends updates to the switch
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c
index a434fecfdfeb..50f53e403ef5 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c
@@ -1,5 +1,5 @@
1/* Intel(R) Ethernet Switch Host Interface Driver 1/* Intel(R) Ethernet Switch Host Interface Driver
2 * Copyright(c) 2013 - 2017 Intel Corporation. 2 * Copyright(c) 2013 - 2018 Intel Corporation.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License, 5 * under the terms and conditions of the GNU General Public License,
@@ -29,7 +29,7 @@ static const struct fm10k_info *fm10k_info_tbl[] = {
29 [fm10k_device_vf] = &fm10k_vf_info, 29 [fm10k_device_vf] = &fm10k_vf_info,
30}; 30};
31 31
32/** 32/*
33 * fm10k_pci_tbl - PCI Device ID Table 33 * fm10k_pci_tbl - PCI Device ID Table
34 * 34 *
35 * Wildcard entries (PCI_ANY_ID) should come last 35 * Wildcard entries (PCI_ANY_ID) should come last
@@ -211,7 +211,7 @@ static void fm10k_start_service_event(struct fm10k_intfc *interface)
211 211
212/** 212/**
213 * fm10k_service_timer - Timer Call-back 213 * fm10k_service_timer - Timer Call-back
214 * @data: pointer to interface cast into an unsigned long 214 * @t: pointer to timer data
215 **/ 215 **/
216static void fm10k_service_timer(struct timer_list *t) 216static void fm10k_service_timer(struct timer_list *t)
217{ 217{
@@ -649,7 +649,7 @@ void fm10k_update_stats(struct fm10k_intfc *interface)
649 649
650/** 650/**
651 * fm10k_watchdog_flush_tx - flush queues on host not ready 651 * fm10k_watchdog_flush_tx - flush queues on host not ready
652 * @interface - pointer to the device interface structure 652 * @interface: pointer to the device interface structure
653 **/ 653 **/
654static void fm10k_watchdog_flush_tx(struct fm10k_intfc *interface) 654static void fm10k_watchdog_flush_tx(struct fm10k_intfc *interface)
655{ 655{
@@ -679,7 +679,7 @@ static void fm10k_watchdog_flush_tx(struct fm10k_intfc *interface)
679 679
680/** 680/**
681 * fm10k_watchdog_subtask - check and bring link up 681 * fm10k_watchdog_subtask - check and bring link up
682 * @interface - pointer to the device interface structure 682 * @interface: pointer to the device interface structure
683 **/ 683 **/
684static void fm10k_watchdog_subtask(struct fm10k_intfc *interface) 684static void fm10k_watchdog_subtask(struct fm10k_intfc *interface)
685{ 685{
@@ -703,7 +703,7 @@ static void fm10k_watchdog_subtask(struct fm10k_intfc *interface)
703 703
704/** 704/**
705 * fm10k_check_hang_subtask - check for hung queues and dropped interrupts 705 * fm10k_check_hang_subtask - check for hung queues and dropped interrupts
706 * @interface - pointer to the device interface structure 706 * @interface: pointer to the device interface structure
707 * 707 *
708 * This function serves two purposes. First it strobes the interrupt lines 708 * This function serves two purposes. First it strobes the interrupt lines
709 * in order to make certain interrupts are occurring. Secondly it sets the 709 * in order to make certain interrupts are occurring. Secondly it sets the
@@ -1995,6 +1995,7 @@ skip_tx_dma_drain:
1995/** 1995/**
1996 * fm10k_sw_init - Initialize general software structures 1996 * fm10k_sw_init - Initialize general software structures
1997 * @interface: host interface private structure to initialize 1997 * @interface: host interface private structure to initialize
1998 * @ent: PCI device ID entry
1998 * 1999 *
1999 * fm10k_sw_init initializes the interface private data structure. 2000 * fm10k_sw_init initializes the interface private data structure.
2000 * Fields are initialized based on PCI device information and 2001 * Fields are initialized based on PCI device information and
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_pf.c b/drivers/net/ethernet/intel/fm10k/fm10k_pf.c
index d6406fc31ffb..bee192fe2ffb 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_pf.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_pf.c
@@ -1,5 +1,5 @@
1/* Intel(R) Ethernet Switch Host Interface Driver 1/* Intel(R) Ethernet Switch Host Interface Driver
2 * Copyright(c) 2013 - 2017 Intel Corporation. 2 * Copyright(c) 2013 - 2018 Intel Corporation.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License, 5 * under the terms and conditions of the GNU General Public License,
@@ -1180,7 +1180,7 @@ s32 fm10k_iov_msg_msix_pf(struct fm10k_hw *hw, u32 **results,
1180 1180
1181/** 1181/**
1182 * fm10k_iov_select_vid - Select correct default VLAN ID 1182 * fm10k_iov_select_vid - Select correct default VLAN ID
1183 * @hw: Pointer to hardware structure 1183 * @vf_info: pointer to VF information structure
1184 * @vid: VLAN ID to correct 1184 * @vid: VLAN ID to correct
1185 * 1185 *
1186 * Will report an error if the VLAN ID is out of range. For VID = 0, it will 1186 * Will report an error if the VLAN ID is out of range. For VID = 0, it will
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_tlv.c b/drivers/net/ethernet/intel/fm10k/fm10k_tlv.c
index f8e87bf086b9..9d0d31da426b 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_tlv.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_tlv.c
@@ -1,5 +1,5 @@
1/* Intel(R) Ethernet Switch Host Interface Driver 1/* Intel(R) Ethernet Switch Host Interface Driver
2 * Copyright(c) 2013 - 2016 Intel Corporation. 2 * Copyright(c) 2013 - 2018 Intel Corporation.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License, 5 * under the terms and conditions of the GNU General Public License,
@@ -120,6 +120,7 @@ static s32 fm10k_tlv_attr_get_null_string(u32 *attr, unsigned char *string)
120 * @msg: Pointer to message block 120 * @msg: Pointer to message block
121 * @attr_id: Attribute ID 121 * @attr_id: Attribute ID
122 * @mac_addr: MAC address to be stored 122 * @mac_addr: MAC address to be stored
123 * @vlan: VLAN to be stored
123 * 124 *
124 * This function will reorder a MAC address to be CPU endian and store it 125 * This function will reorder a MAC address to be CPU endian and store it
125 * in the attribute buffer. It will return success if provided with a 126 * in the attribute buffer. It will return success if provided with a
@@ -155,8 +156,8 @@ s32 fm10k_tlv_attr_put_mac_vlan(u32 *msg, u16 attr_id,
155/** 156/**
156 * fm10k_tlv_attr_get_mac_vlan - Get MAC/VLAN stored in attribute 157 * fm10k_tlv_attr_get_mac_vlan - Get MAC/VLAN stored in attribute
157 * @attr: Pointer to attribute 158 * @attr: Pointer to attribute
158 * @attr_id: Attribute ID
159 * @mac_addr: location of buffer to store MAC address 159 * @mac_addr: location of buffer to store MAC address
160 * @vlan: location of buffer to store VLAN
160 * 161 *
161 * This function pulls the MAC address back out of the attribute and will 162 * This function pulls the MAC address back out of the attribute and will
162 * place it in the array pointed by by mac_addr. It will return success 163 * place it in the array pointed by by mac_addr. It will return success
@@ -549,7 +550,7 @@ static s32 fm10k_tlv_attr_parse(u32 *attr, u32 **results,
549 * @hw: Pointer to hardware structure 550 * @hw: Pointer to hardware structure
550 * @msg: Pointer to message 551 * @msg: Pointer to message
551 * @mbx: Pointer to mailbox information structure 552 * @mbx: Pointer to mailbox information structure
552 * @func: Function array containing list of message handling functions 553 * @data: Pointer to message handler data structure
553 * 554 *
554 * This function should be the first function called upon receiving a 555 * This function should be the first function called upon receiving a
555 * message. The handler will identify the message type and call the correct 556 * message. The handler will identify the message type and call the correct
diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h
index 46e9f4e0a02c..271ab1a861b7 100644
--- a/drivers/net/ethernet/intel/i40e/i40e.h
+++ b/drivers/net/ethernet/intel/i40e/i40e.h
@@ -507,6 +507,7 @@ struct i40e_pf {
507#define I40E_HW_STOP_FW_LLDP BIT(16) 507#define I40E_HW_STOP_FW_LLDP BIT(16)
508#define I40E_HW_PORT_ID_VALID BIT(17) 508#define I40E_HW_PORT_ID_VALID BIT(17)
509#define I40E_HW_RESTART_AUTONEG BIT(18) 509#define I40E_HW_RESTART_AUTONEG BIT(18)
510#define I40E_HW_STOPPABLE_FW_LLDP BIT(19)
510 511
511 u64 flags; 512 u64 flags;
512#define I40E_FLAG_RX_CSUM_ENABLED BIT_ULL(0) 513#define I40E_FLAG_RX_CSUM_ENABLED BIT_ULL(0)
@@ -824,6 +825,7 @@ struct i40e_q_vector {
824 struct i40e_ring_container rx; 825 struct i40e_ring_container rx;
825 struct i40e_ring_container tx; 826 struct i40e_ring_container tx;
826 827
828 u8 itr_countdown; /* when 0 should adjust adaptive ITR */
827 u8 num_ringpairs; /* total number of ring pairs in vector */ 829 u8 num_ringpairs; /* total number of ring pairs in vector */
828 830
829 cpumask_t affinity_mask; 831 cpumask_t affinity_mask;
@@ -832,8 +834,6 @@ struct i40e_q_vector {
832 struct rcu_head rcu; /* to avoid race with update stats on free */ 834 struct rcu_head rcu; /* to avoid race with update stats on free */
833 char name[I40E_INT_NAME_STR_LEN]; 835 char name[I40E_INT_NAME_STR_LEN];
834 bool arm_wb_state; 836 bool arm_wb_state;
835#define ITR_COUNTDOWN_START 100
836 u8 itr_countdown; /* when 0 should adjust ITR */
837} ____cacheline_internodealigned_in_smp; 837} ____cacheline_internodealigned_in_smp;
838 838
839/* lan device */ 839/* lan device */
@@ -1041,6 +1041,7 @@ void i40e_notify_client_of_l2_param_changes(struct i40e_vsi *vsi);
1041void i40e_notify_client_of_netdev_close(struct i40e_vsi *vsi, bool reset); 1041void i40e_notify_client_of_netdev_close(struct i40e_vsi *vsi, bool reset);
1042void i40e_notify_client_of_vf_enable(struct i40e_pf *pf, u32 num_vfs); 1042void i40e_notify_client_of_vf_enable(struct i40e_pf *pf, u32 num_vfs);
1043void i40e_notify_client_of_vf_reset(struct i40e_pf *pf, u32 vf_id); 1043void i40e_notify_client_of_vf_reset(struct i40e_pf *pf, u32 vf_id);
1044void i40e_client_update_msix_info(struct i40e_pf *pf);
1044int i40e_vf_client_capable(struct i40e_pf *pf, u32 vf_id); 1045int i40e_vf_client_capable(struct i40e_pf *pf, u32 vf_id);
1045/** 1046/**
1046 * i40e_irq_dynamic_enable - Enable default interrupt generation settings 1047 * i40e_irq_dynamic_enable - Enable default interrupt generation settings
@@ -1109,4 +1110,10 @@ static inline bool i40e_enabled_xdp_vsi(struct i40e_vsi *vsi)
1109 1110
1110int i40e_create_queue_channel(struct i40e_vsi *vsi, struct i40e_channel *ch); 1111int i40e_create_queue_channel(struct i40e_vsi *vsi, struct i40e_channel *ch);
1111int i40e_set_bw_limit(struct i40e_vsi *vsi, u16 seid, u64 max_tx_rate); 1112int i40e_set_bw_limit(struct i40e_vsi *vsi, u16 seid, u64 max_tx_rate);
1113int i40e_add_del_cloud_filter(struct i40e_vsi *vsi,
1114 struct i40e_cloud_filter *filter,
1115 bool add);
1116int i40e_add_del_cloud_filter_big_buf(struct i40e_vsi *vsi,
1117 struct i40e_cloud_filter *filter,
1118 bool add);
1112#endif /* _I40E_H_ */ 1119#endif /* _I40E_H_ */
diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h b/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h
index a852775d3059..0dfc52772c45 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h
@@ -1914,6 +1914,43 @@ enum i40e_aq_phy_type {
1914 I40E_PHY_TYPE_DEFAULT = 0xFF, 1914 I40E_PHY_TYPE_DEFAULT = 0xFF,
1915}; 1915};
1916 1916
1917#define I40E_PHY_TYPES_BITMASK (BIT_ULL(I40E_PHY_TYPE_SGMII) | \
1918 BIT_ULL(I40E_PHY_TYPE_1000BASE_KX) | \
1919 BIT_ULL(I40E_PHY_TYPE_10GBASE_KX4) | \
1920 BIT_ULL(I40E_PHY_TYPE_10GBASE_KR) | \
1921 BIT_ULL(I40E_PHY_TYPE_40GBASE_KR4) | \
1922 BIT_ULL(I40E_PHY_TYPE_XAUI) | \
1923 BIT_ULL(I40E_PHY_TYPE_XFI) | \
1924 BIT_ULL(I40E_PHY_TYPE_SFI) | \
1925 BIT_ULL(I40E_PHY_TYPE_XLAUI) | \
1926 BIT_ULL(I40E_PHY_TYPE_XLPPI) | \
1927 BIT_ULL(I40E_PHY_TYPE_40GBASE_CR4_CU) | \
1928 BIT_ULL(I40E_PHY_TYPE_10GBASE_CR1_CU) | \
1929 BIT_ULL(I40E_PHY_TYPE_10GBASE_AOC) | \
1930 BIT_ULL(I40E_PHY_TYPE_40GBASE_AOC) | \
1931 BIT_ULL(I40E_PHY_TYPE_UNRECOGNIZED) | \
1932 BIT_ULL(I40E_PHY_TYPE_UNSUPPORTED) | \
1933 BIT_ULL(I40E_PHY_TYPE_100BASE_TX) | \
1934 BIT_ULL(I40E_PHY_TYPE_1000BASE_T) | \
1935 BIT_ULL(I40E_PHY_TYPE_10GBASE_T) | \
1936 BIT_ULL(I40E_PHY_TYPE_10GBASE_SR) | \
1937 BIT_ULL(I40E_PHY_TYPE_10GBASE_LR) | \
1938 BIT_ULL(I40E_PHY_TYPE_10GBASE_SFPP_CU) | \
1939 BIT_ULL(I40E_PHY_TYPE_10GBASE_CR1) | \
1940 BIT_ULL(I40E_PHY_TYPE_40GBASE_CR4) | \
1941 BIT_ULL(I40E_PHY_TYPE_40GBASE_SR4) | \
1942 BIT_ULL(I40E_PHY_TYPE_40GBASE_LR4) | \
1943 BIT_ULL(I40E_PHY_TYPE_1000BASE_SX) | \
1944 BIT_ULL(I40E_PHY_TYPE_1000BASE_LX) | \
1945 BIT_ULL(I40E_PHY_TYPE_1000BASE_T_OPTICAL) | \
1946 BIT_ULL(I40E_PHY_TYPE_20GBASE_KR2) | \
1947 BIT_ULL(I40E_PHY_TYPE_25GBASE_KR) | \
1948 BIT_ULL(I40E_PHY_TYPE_25GBASE_CR) | \
1949 BIT_ULL(I40E_PHY_TYPE_25GBASE_SR) | \
1950 BIT_ULL(I40E_PHY_TYPE_25GBASE_LR) | \
1951 BIT_ULL(I40E_PHY_TYPE_25GBASE_AOC) | \
1952 BIT_ULL(I40E_PHY_TYPE_25GBASE_ACC))
1953
1917#define I40E_LINK_SPEED_100MB_SHIFT 0x1 1954#define I40E_LINK_SPEED_100MB_SHIFT 0x1
1918#define I40E_LINK_SPEED_1000MB_SHIFT 0x2 1955#define I40E_LINK_SPEED_1000MB_SHIFT 0x2
1919#define I40E_LINK_SPEED_10GB_SHIFT 0x3 1956#define I40E_LINK_SPEED_10GB_SHIFT 0x3
diff --git a/drivers/net/ethernet/intel/i40e/i40e_client.c b/drivers/net/ethernet/intel/i40e/i40e_client.c
index 0de9610c1d8d..704695a61645 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_client.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_client.c
@@ -287,6 +287,17 @@ out:
287 return capable; 287 return capable;
288} 288}
289 289
290void i40e_client_update_msix_info(struct i40e_pf *pf)
291{
292 struct i40e_client_instance *cdev = pf->cinst;
293
294 if (!cdev || !cdev->client)
295 return;
296
297 cdev->lan_info.msix_count = pf->num_iwarp_msix;
298 cdev->lan_info.msix_entries = &pf->msix_entries[pf->iwarp_base_vector];
299}
300
290/** 301/**
291 * i40e_client_add_instance - add a client instance struct to the instance list 302 * i40e_client_add_instance - add a client instance struct to the instance list
292 * @pf: pointer to the board struct 303 * @pf: pointer to the board struct
@@ -328,9 +339,6 @@ static void i40e_client_add_instance(struct i40e_pf *pf)
328 return; 339 return;
329 } 340 }
330 341
331 cdev->lan_info.msix_count = pf->num_iwarp_msix;
332 cdev->lan_info.msix_entries = &pf->msix_entries[pf->iwarp_base_vector];
333
334 mac = list_first_entry(&cdev->lan_info.netdev->dev_addrs.list, 342 mac = list_first_entry(&cdev->lan_info.netdev->dev_addrs.list,
335 struct netdev_hw_addr, list); 343 struct netdev_hw_addr, list);
336 if (mac) 344 if (mac)
@@ -340,6 +348,8 @@ static void i40e_client_add_instance(struct i40e_pf *pf)
340 348
341 cdev->client = registered_client; 349 cdev->client = registered_client;
342 pf->cinst = cdev; 350 pf->cinst = cdev;
351
352 i40e_client_update_msix_info(pf);
343} 353}
344 354
345/** 355/**
diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c
index ef5a868aae46..4fa31d87d9d2 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_common.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_common.c
@@ -1208,6 +1208,29 @@ static enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw)
1208 return media; 1208 return media;
1209} 1209}
1210 1210
1211/**
1212 * i40e_poll_globr - Poll for Global Reset completion
1213 * @hw: pointer to the hardware structure
1214 * @retry_limit: how many times to retry before failure
1215 **/
1216static i40e_status i40e_poll_globr(struct i40e_hw *hw,
1217 u32 retry_limit)
1218{
1219 u32 cnt, reg = 0;
1220
1221 for (cnt = 0; cnt < retry_limit; cnt++) {
1222 reg = rd32(hw, I40E_GLGEN_RSTAT);
1223 if (!(reg & I40E_GLGEN_RSTAT_DEVSTATE_MASK))
1224 return 0;
1225 msleep(100);
1226 }
1227
1228 hw_dbg(hw, "Global reset failed.\n");
1229 hw_dbg(hw, "I40E_GLGEN_RSTAT = 0x%x\n", reg);
1230
1231 return I40E_ERR_RESET_FAILED;
1232}
1233
1211#define I40E_PF_RESET_WAIT_COUNT_A0 200 1234#define I40E_PF_RESET_WAIT_COUNT_A0 200
1212#define I40E_PF_RESET_WAIT_COUNT 200 1235#define I40E_PF_RESET_WAIT_COUNT 200
1213/** 1236/**
@@ -1284,14 +1307,14 @@ i40e_status i40e_pf_reset(struct i40e_hw *hw)
1284 if (!(reg & I40E_PFGEN_CTRL_PFSWR_MASK)) 1307 if (!(reg & I40E_PFGEN_CTRL_PFSWR_MASK))
1285 break; 1308 break;
1286 reg2 = rd32(hw, I40E_GLGEN_RSTAT); 1309 reg2 = rd32(hw, I40E_GLGEN_RSTAT);
1287 if (reg2 & I40E_GLGEN_RSTAT_DEVSTATE_MASK) { 1310 if (reg2 & I40E_GLGEN_RSTAT_DEVSTATE_MASK)
1288 hw_dbg(hw, "Core reset upcoming. Skipping PF reset request.\n"); 1311 break;
1289 hw_dbg(hw, "I40E_GLGEN_RSTAT = 0x%x\n", reg2);
1290 return I40E_ERR_NOT_READY;
1291 }
1292 usleep_range(1000, 2000); 1312 usleep_range(1000, 2000);
1293 } 1313 }
1294 if (reg & I40E_PFGEN_CTRL_PFSWR_MASK) { 1314 if (reg2 & I40E_GLGEN_RSTAT_DEVSTATE_MASK) {
1315 if (i40e_poll_globr(hw, grst_del))
1316 return I40E_ERR_RESET_FAILED;
1317 } else if (reg & I40E_PFGEN_CTRL_PFSWR_MASK) {
1295 hw_dbg(hw, "PF reset polling failed to complete.\n"); 1318 hw_dbg(hw, "PF reset polling failed to complete.\n");
1296 return I40E_ERR_RESET_FAILED; 1319 return I40E_ERR_RESET_FAILED;
1297 } 1320 }
@@ -2415,6 +2438,7 @@ i40e_status i40e_aq_get_switch_config(struct i40e_hw *hw,
2415 * i40e_aq_set_switch_config 2438 * i40e_aq_set_switch_config
2416 * @hw: pointer to the hardware structure 2439 * @hw: pointer to the hardware structure
2417 * @flags: bit flag values to set 2440 * @flags: bit flag values to set
2441 * @mode: cloud filter mode
2418 * @valid_flags: which bit flags to set 2442 * @valid_flags: which bit flags to set
2419 * @mode: cloud filter mode 2443 * @mode: cloud filter mode
2420 * @cmd_details: pointer to command details structure or NULL 2444 * @cmd_details: pointer to command details structure or NULL
@@ -3200,9 +3224,10 @@ static void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff,
3200 u32 valid_functions, num_functions; 3224 u32 valid_functions, num_functions;
3201 u32 number, logical_id, phys_id; 3225 u32 number, logical_id, phys_id;
3202 struct i40e_hw_capabilities *p; 3226 struct i40e_hw_capabilities *p;
3227 u16 id, ocp_cfg_word0;
3228 i40e_status status;
3203 u8 major_rev; 3229 u8 major_rev;
3204 u32 i = 0; 3230 u32 i = 0;
3205 u16 id;
3206 3231
3207 cap = (struct i40e_aqc_list_capabilities_element_resp *) buff; 3232 cap = (struct i40e_aqc_list_capabilities_element_resp *) buff;
3208 3233
@@ -3389,6 +3414,26 @@ static void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff,
3389 hw->num_ports++; 3414 hw->num_ports++;
3390 } 3415 }
3391 3416
3417 /* OCP cards case: if a mezz is removed the Ethernet port is at
3418 * disabled state in PRTGEN_CNF register. Additional NVM read is
3419 * needed in order to check if we are dealing with OCP card.
3420 * Those cards have 4 PFs at minimum, so using PRTGEN_CNF for counting
3421 * physical ports results in wrong partition id calculation and thus
3422 * not supporting WoL.
3423 */
3424 if (hw->mac.type == I40E_MAC_X722) {
3425 if (!i40e_acquire_nvm(hw, I40E_RESOURCE_READ)) {
3426 status = i40e_aq_read_nvm(hw, I40E_SR_EMP_MODULE_PTR,
3427 2 * I40E_SR_OCP_CFG_WORD0,
3428 sizeof(ocp_cfg_word0),
3429 &ocp_cfg_word0, true, NULL);
3430 if (!status &&
3431 (ocp_cfg_word0 & I40E_SR_OCP_ENABLED))
3432 hw->num_ports = 4;
3433 i40e_release_nvm(hw);
3434 }
3435 }
3436
3392 valid_functions = p->valid_functions; 3437 valid_functions = p->valid_functions;
3393 num_functions = 0; 3438 num_functions = 0;
3394 while (valid_functions) { 3439 while (valid_functions) {
@@ -5531,7 +5576,7 @@ i40e_aq_add_cloud_filters(struct i40e_hw *hw, u16 seid,
5531 * function. 5576 * function.
5532 * 5577 *
5533 **/ 5578 **/
5534i40e_status 5579enum i40e_status_code
5535i40e_aq_add_cloud_filters_bb(struct i40e_hw *hw, u16 seid, 5580i40e_aq_add_cloud_filters_bb(struct i40e_hw *hw, u16 seid,
5536 struct i40e_aqc_cloud_filters_element_bb *filters, 5581 struct i40e_aqc_cloud_filters_element_bb *filters,
5537 u8 filter_count) 5582 u8 filter_count)
@@ -5625,7 +5670,7 @@ i40e_aq_rem_cloud_filters(struct i40e_hw *hw, u16 seid,
5625 * function. 5670 * function.
5626 * 5671 *
5627 **/ 5672 **/
5628i40e_status 5673enum i40e_status_code
5629i40e_aq_rem_cloud_filters_bb(struct i40e_hw *hw, u16 seid, 5674i40e_aq_rem_cloud_filters_bb(struct i40e_hw *hw, u16 seid,
5630 struct i40e_aqc_cloud_filters_element_bb *filters, 5675 struct i40e_aqc_cloud_filters_element_bb *filters,
5631 u8 filter_count) 5676 u8 filter_count)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
index 4c3b4243cf65..b829fd365693 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
@@ -155,8 +155,8 @@ static void i40e_dbg_dump_vsi_seid(struct i40e_pf *pf, int seid)
155 dev_info(&pf->pdev->dev, " vlan_features = 0x%08lx\n", 155 dev_info(&pf->pdev->dev, " vlan_features = 0x%08lx\n",
156 (unsigned long int)nd->vlan_features); 156 (unsigned long int)nd->vlan_features);
157 } 157 }
158 dev_info(&pf->pdev->dev, 158 dev_info(&pf->pdev->dev, " active_vlans is %s\n",
159 " vlgrp: & = %p\n", vsi->active_vlans); 159 vsi->active_vlans ? "<valid>" : "<null>");
160 dev_info(&pf->pdev->dev, 160 dev_info(&pf->pdev->dev,
161 " flags = 0x%08lx, netdev_registered = %i, current_netdev_flags = 0x%04x\n", 161 " flags = 0x%08lx, netdev_registered = %i, current_netdev_flags = 0x%04x\n",
162 vsi->flags, vsi->netdev_registered, vsi->current_netdev_flags); 162 vsi->flags, vsi->netdev_registered, vsi->current_netdev_flags);
@@ -270,14 +270,6 @@ static void i40e_dbg_dump_vsi_seid(struct i40e_pf *pf, int seid)
270 continue; 270 continue;
271 271
272 dev_info(&pf->pdev->dev, 272 dev_info(&pf->pdev->dev,
273 " rx_rings[%i]: desc = %p\n",
274 i, rx_ring->desc);
275 dev_info(&pf->pdev->dev,
276 " rx_rings[%i]: dev = %p, netdev = %p, rx_bi = %p\n",
277 i, rx_ring->dev,
278 rx_ring->netdev,
279 rx_ring->rx_bi);
280 dev_info(&pf->pdev->dev,
281 " rx_rings[%i]: state = %lu, queue_index = %d, reg_idx = %d\n", 273 " rx_rings[%i]: state = %lu, queue_index = %d, reg_idx = %d\n",
282 i, *rx_ring->state, 274 i, *rx_ring->state,
283 rx_ring->queue_index, 275 rx_ring->queue_index,
@@ -307,17 +299,12 @@ static void i40e_dbg_dump_vsi_seid(struct i40e_pf *pf, int seid)
307 rx_ring->rx_stats.realloc_count, 299 rx_ring->rx_stats.realloc_count,
308 rx_ring->rx_stats.page_reuse_count); 300 rx_ring->rx_stats.page_reuse_count);
309 dev_info(&pf->pdev->dev, 301 dev_info(&pf->pdev->dev,
310 " rx_rings[%i]: size = %i, dma = 0x%08lx\n", 302 " rx_rings[%i]: size = %i\n",
311 i, rx_ring->size, 303 i, rx_ring->size);
312 (unsigned long int)rx_ring->dma);
313 dev_info(&pf->pdev->dev,
314 " rx_rings[%i]: vsi = %p, q_vector = %p\n",
315 i, rx_ring->vsi,
316 rx_ring->q_vector);
317 dev_info(&pf->pdev->dev, 304 dev_info(&pf->pdev->dev,
318 " rx_rings[%i]: rx_itr_setting = %d (%s)\n", 305 " rx_rings[%i]: itr_setting = %d (%s)\n",
319 i, rx_ring->rx_itr_setting, 306 i, rx_ring->itr_setting,
320 ITR_IS_DYNAMIC(rx_ring->rx_itr_setting) ? "dynamic" : "fixed"); 307 ITR_IS_DYNAMIC(rx_ring->itr_setting) ? "dynamic" : "fixed");
321 } 308 }
322 for (i = 0; i < vsi->num_queue_pairs; i++) { 309 for (i = 0; i < vsi->num_queue_pairs; i++) {
323 struct i40e_ring *tx_ring = READ_ONCE(vsi->tx_rings[i]); 310 struct i40e_ring *tx_ring = READ_ONCE(vsi->tx_rings[i]);
@@ -326,14 +313,6 @@ static void i40e_dbg_dump_vsi_seid(struct i40e_pf *pf, int seid)
326 continue; 313 continue;
327 314
328 dev_info(&pf->pdev->dev, 315 dev_info(&pf->pdev->dev,
329 " tx_rings[%i]: desc = %p\n",
330 i, tx_ring->desc);
331 dev_info(&pf->pdev->dev,
332 " tx_rings[%i]: dev = %p, netdev = %p, tx_bi = %p\n",
333 i, tx_ring->dev,
334 tx_ring->netdev,
335 tx_ring->tx_bi);
336 dev_info(&pf->pdev->dev,
337 " tx_rings[%i]: state = %lu, queue_index = %d, reg_idx = %d\n", 316 " tx_rings[%i]: state = %lu, queue_index = %d, reg_idx = %d\n",
338 i, *tx_ring->state, 317 i, *tx_ring->state,
339 tx_ring->queue_index, 318 tx_ring->queue_index,
@@ -355,20 +334,15 @@ static void i40e_dbg_dump_vsi_seid(struct i40e_pf *pf, int seid)
355 tx_ring->tx_stats.tx_busy, 334 tx_ring->tx_stats.tx_busy,
356 tx_ring->tx_stats.tx_done_old); 335 tx_ring->tx_stats.tx_done_old);
357 dev_info(&pf->pdev->dev, 336 dev_info(&pf->pdev->dev,
358 " tx_rings[%i]: size = %i, dma = 0x%08lx\n", 337 " tx_rings[%i]: size = %i\n",
359 i, tx_ring->size, 338 i, tx_ring->size);
360 (unsigned long int)tx_ring->dma);
361 dev_info(&pf->pdev->dev,
362 " tx_rings[%i]: vsi = %p, q_vector = %p\n",
363 i, tx_ring->vsi,
364 tx_ring->q_vector);
365 dev_info(&pf->pdev->dev, 339 dev_info(&pf->pdev->dev,
366 " tx_rings[%i]: DCB tc = %d\n", 340 " tx_rings[%i]: DCB tc = %d\n",
367 i, tx_ring->dcb_tc); 341 i, tx_ring->dcb_tc);
368 dev_info(&pf->pdev->dev, 342 dev_info(&pf->pdev->dev,
369 " tx_rings[%i]: tx_itr_setting = %d (%s)\n", 343 " tx_rings[%i]: itr_setting = %d (%s)\n",
370 i, tx_ring->tx_itr_setting, 344 i, tx_ring->itr_setting,
371 ITR_IS_DYNAMIC(tx_ring->tx_itr_setting) ? "dynamic" : "fixed"); 345 ITR_IS_DYNAMIC(tx_ring->itr_setting) ? "dynamic" : "fixed");
372 } 346 }
373 rcu_read_unlock(); 347 rcu_read_unlock();
374 dev_info(&pf->pdev->dev, 348 dev_info(&pf->pdev->dev,
@@ -466,8 +440,6 @@ static void i40e_dbg_dump_vsi_seid(struct i40e_pf *pf, int seid)
466 vsi->info.resp_reserved[6], vsi->info.resp_reserved[7], 440 vsi->info.resp_reserved[6], vsi->info.resp_reserved[7],
467 vsi->info.resp_reserved[8], vsi->info.resp_reserved[9], 441 vsi->info.resp_reserved[8], vsi->info.resp_reserved[9],
468 vsi->info.resp_reserved[10], vsi->info.resp_reserved[11]); 442 vsi->info.resp_reserved[10], vsi->info.resp_reserved[11]);
469 if (vsi->back)
470 dev_info(&pf->pdev->dev, " PF = %p\n", vsi->back);
471 dev_info(&pf->pdev->dev, " idx = %d\n", vsi->idx); 443 dev_info(&pf->pdev->dev, " idx = %d\n", vsi->idx);
472 dev_info(&pf->pdev->dev, 444 dev_info(&pf->pdev->dev,
473 " tc_config: numtc = %d, enabled_tc = 0x%x\n", 445 " tc_config: numtc = %d, enabled_tc = 0x%x\n",
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
index 2f5bee713fef..0c7e7de595d3 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
@@ -230,6 +230,8 @@ static const struct i40e_priv_flags i40e_gstrings_priv_flags[] = {
230 I40E_PRIV_FLAG("flow-director-atr", I40E_FLAG_FD_ATR_ENABLED, 0), 230 I40E_PRIV_FLAG("flow-director-atr", I40E_FLAG_FD_ATR_ENABLED, 0),
231 I40E_PRIV_FLAG("veb-stats", I40E_FLAG_VEB_STATS_ENABLED, 0), 231 I40E_PRIV_FLAG("veb-stats", I40E_FLAG_VEB_STATS_ENABLED, 0),
232 I40E_PRIV_FLAG("hw-atr-eviction", I40E_FLAG_HW_ATR_EVICT_ENABLED, 0), 232 I40E_PRIV_FLAG("hw-atr-eviction", I40E_FLAG_HW_ATR_EVICT_ENABLED, 0),
233 I40E_PRIV_FLAG("link-down-on-close",
234 I40E_FLAG_LINK_DOWN_ON_CLOSE_ENABLED, 0),
233 I40E_PRIV_FLAG("legacy-rx", I40E_FLAG_LEGACY_RX, 0), 235 I40E_PRIV_FLAG("legacy-rx", I40E_FLAG_LEGACY_RX, 0),
234 I40E_PRIV_FLAG("disable-source-pruning", 236 I40E_PRIV_FLAG("disable-source-pruning",
235 I40E_FLAG_SOURCE_PRUNING_DISABLED, 0), 237 I40E_FLAG_SOURCE_PRUNING_DISABLED, 0),
@@ -857,7 +859,9 @@ static int i40e_set_link_ksettings(struct net_device *netdev,
857 if (hw->device_id == I40E_DEV_ID_KX_B || 859 if (hw->device_id == I40E_DEV_ID_KX_B ||
858 hw->device_id == I40E_DEV_ID_KX_C || 860 hw->device_id == I40E_DEV_ID_KX_C ||
859 hw->device_id == I40E_DEV_ID_20G_KR2 || 861 hw->device_id == I40E_DEV_ID_20G_KR2 ||
860 hw->device_id == I40E_DEV_ID_20G_KR2_A) { 862 hw->device_id == I40E_DEV_ID_20G_KR2_A ||
863 hw->device_id == I40E_DEV_ID_25G_B ||
864 hw->device_id == I40E_DEV_ID_KX_X722) {
861 netdev_info(netdev, "Changing settings is not supported on backplane.\n"); 865 netdev_info(netdev, "Changing settings is not supported on backplane.\n");
862 return -EOPNOTSUPP; 866 return -EOPNOTSUPP;
863 } 867 }
@@ -868,23 +872,21 @@ static int i40e_set_link_ksettings(struct net_device *netdev,
868 /* save autoneg out of ksettings */ 872 /* save autoneg out of ksettings */
869 autoneg = copy_ks.base.autoneg; 873 autoneg = copy_ks.base.autoneg;
870 874
871 memset(&safe_ks, 0, sizeof(safe_ks)); 875 /* get our own copy of the bits to check against */
876 memset(&safe_ks, 0, sizeof(struct ethtool_link_ksettings));
877 safe_ks.base.cmd = copy_ks.base.cmd;
878 safe_ks.base.link_mode_masks_nwords =
879 copy_ks.base.link_mode_masks_nwords;
880 i40e_get_link_ksettings(netdev, &safe_ks);
881
872 /* Get link modes supported by hardware and check against modes 882 /* Get link modes supported by hardware and check against modes
873 * requested by the user. Return an error if unsupported mode was set. 883 * requested by the user. Return an error if unsupported mode was set.
874 */ 884 */
875 i40e_phy_type_to_ethtool(pf, &safe_ks);
876 if (!bitmap_subset(copy_ks.link_modes.advertising, 885 if (!bitmap_subset(copy_ks.link_modes.advertising,
877 safe_ks.link_modes.supported, 886 safe_ks.link_modes.supported,
878 __ETHTOOL_LINK_MODE_MASK_NBITS)) 887 __ETHTOOL_LINK_MODE_MASK_NBITS))
879 return -EINVAL; 888 return -EINVAL;
880 889
881 /* get our own copy of the bits to check against */
882 memset(&safe_ks, 0, sizeof(struct ethtool_link_ksettings));
883 safe_ks.base.cmd = copy_ks.base.cmd;
884 safe_ks.base.link_mode_masks_nwords =
885 copy_ks.base.link_mode_masks_nwords;
886 i40e_get_link_ksettings(netdev, &safe_ks);
887
888 /* set autoneg back to what it currently is */ 890 /* set autoneg back to what it currently is */
889 copy_ks.base.autoneg = safe_ks.base.autoneg; 891 copy_ks.base.autoneg = safe_ks.base.autoneg;
890 892
@@ -2244,14 +2246,14 @@ static int __i40e_get_coalesce(struct net_device *netdev,
2244 rx_ring = vsi->rx_rings[queue]; 2246 rx_ring = vsi->rx_rings[queue];
2245 tx_ring = vsi->tx_rings[queue]; 2247 tx_ring = vsi->tx_rings[queue];
2246 2248
2247 if (ITR_IS_DYNAMIC(rx_ring->rx_itr_setting)) 2249 if (ITR_IS_DYNAMIC(rx_ring->itr_setting))
2248 ec->use_adaptive_rx_coalesce = 1; 2250 ec->use_adaptive_rx_coalesce = 1;
2249 2251
2250 if (ITR_IS_DYNAMIC(tx_ring->tx_itr_setting)) 2252 if (ITR_IS_DYNAMIC(tx_ring->itr_setting))
2251 ec->use_adaptive_tx_coalesce = 1; 2253 ec->use_adaptive_tx_coalesce = 1;
2252 2254
2253 ec->rx_coalesce_usecs = rx_ring->rx_itr_setting & ~I40E_ITR_DYNAMIC; 2255 ec->rx_coalesce_usecs = rx_ring->itr_setting & ~I40E_ITR_DYNAMIC;
2254 ec->tx_coalesce_usecs = tx_ring->tx_itr_setting & ~I40E_ITR_DYNAMIC; 2256 ec->tx_coalesce_usecs = tx_ring->itr_setting & ~I40E_ITR_DYNAMIC;
2255 2257
2256 /* we use the _usecs_high to store/set the interrupt rate limit 2258 /* we use the _usecs_high to store/set the interrupt rate limit
2257 * that the hardware supports, that almost but not quite 2259 * that the hardware supports, that almost but not quite
@@ -2311,34 +2313,35 @@ static void i40e_set_itr_per_queue(struct i40e_vsi *vsi,
2311 struct i40e_pf *pf = vsi->back; 2313 struct i40e_pf *pf = vsi->back;
2312 struct i40e_hw *hw = &pf->hw; 2314 struct i40e_hw *hw = &pf->hw;
2313 struct i40e_q_vector *q_vector; 2315 struct i40e_q_vector *q_vector;
2314 u16 vector, intrl; 2316 u16 intrl;
2315 2317
2316 intrl = i40e_intrl_usec_to_reg(vsi->int_rate_limit); 2318 intrl = i40e_intrl_usec_to_reg(vsi->int_rate_limit);
2317 2319
2318 rx_ring->rx_itr_setting = ec->rx_coalesce_usecs; 2320 rx_ring->itr_setting = ITR_REG_ALIGN(ec->rx_coalesce_usecs);
2319 tx_ring->tx_itr_setting = ec->tx_coalesce_usecs; 2321 tx_ring->itr_setting = ITR_REG_ALIGN(ec->tx_coalesce_usecs);
2320 2322
2321 if (ec->use_adaptive_rx_coalesce) 2323 if (ec->use_adaptive_rx_coalesce)
2322 rx_ring->rx_itr_setting |= I40E_ITR_DYNAMIC; 2324 rx_ring->itr_setting |= I40E_ITR_DYNAMIC;
2323 else 2325 else
2324 rx_ring->rx_itr_setting &= ~I40E_ITR_DYNAMIC; 2326 rx_ring->itr_setting &= ~I40E_ITR_DYNAMIC;
2325 2327
2326 if (ec->use_adaptive_tx_coalesce) 2328 if (ec->use_adaptive_tx_coalesce)
2327 tx_ring->tx_itr_setting |= I40E_ITR_DYNAMIC; 2329 tx_ring->itr_setting |= I40E_ITR_DYNAMIC;
2328 else 2330 else
2329 tx_ring->tx_itr_setting &= ~I40E_ITR_DYNAMIC; 2331 tx_ring->itr_setting &= ~I40E_ITR_DYNAMIC;
2330 2332
2331 q_vector = rx_ring->q_vector; 2333 q_vector = rx_ring->q_vector;
2332 q_vector->rx.itr = ITR_TO_REG(rx_ring->rx_itr_setting); 2334 q_vector->rx.target_itr = ITR_TO_REG(rx_ring->itr_setting);
2333 vector = vsi->base_vector + q_vector->v_idx;
2334 wr32(hw, I40E_PFINT_ITRN(I40E_RX_ITR, vector - 1), q_vector->rx.itr);
2335 2335
2336 q_vector = tx_ring->q_vector; 2336 q_vector = tx_ring->q_vector;
2337 q_vector->tx.itr = ITR_TO_REG(tx_ring->tx_itr_setting); 2337 q_vector->tx.target_itr = ITR_TO_REG(tx_ring->itr_setting);
2338 vector = vsi->base_vector + q_vector->v_idx;
2339 wr32(hw, I40E_PFINT_ITRN(I40E_TX_ITR, vector - 1), q_vector->tx.itr);
2340 2338
2341 wr32(hw, I40E_PFINT_RATEN(vector - 1), intrl); 2339 /* The interrupt handler itself will take care of programming
2340 * the Tx and Rx ITR values based on the values we have entered
2341 * into the q_vector, no need to write the values now.
2342 */
2343
2344 wr32(hw, I40E_PFINT_RATEN(q_vector->reg_idx), intrl);
2342 i40e_flush(hw); 2345 i40e_flush(hw);
2343} 2346}
2344 2347
@@ -2364,11 +2367,11 @@ static int __i40e_set_coalesce(struct net_device *netdev,
2364 vsi->work_limit = ec->tx_max_coalesced_frames_irq; 2367 vsi->work_limit = ec->tx_max_coalesced_frames_irq;
2365 2368
2366 if (queue < 0) { 2369 if (queue < 0) {
2367 cur_rx_itr = vsi->rx_rings[0]->rx_itr_setting; 2370 cur_rx_itr = vsi->rx_rings[0]->itr_setting;
2368 cur_tx_itr = vsi->tx_rings[0]->tx_itr_setting; 2371 cur_tx_itr = vsi->tx_rings[0]->itr_setting;
2369 } else if (queue < vsi->num_queue_pairs) { 2372 } else if (queue < vsi->num_queue_pairs) {
2370 cur_rx_itr = vsi->rx_rings[queue]->rx_itr_setting; 2373 cur_rx_itr = vsi->rx_rings[queue]->itr_setting;
2371 cur_tx_itr = vsi->tx_rings[queue]->tx_itr_setting; 2374 cur_tx_itr = vsi->tx_rings[queue]->itr_setting;
2372 } else { 2375 } else {
2373 netif_info(pf, drv, netdev, "Invalid queue value, queue range is 0 - %d\n", 2376 netif_info(pf, drv, netdev, "Invalid queue value, queue range is 0 - %d\n",
2374 vsi->num_queue_pairs - 1); 2377 vsi->num_queue_pairs - 1);
@@ -2396,7 +2399,7 @@ static int __i40e_set_coalesce(struct net_device *netdev,
2396 return -EINVAL; 2399 return -EINVAL;
2397 } 2400 }
2398 2401
2399 if (ec->rx_coalesce_usecs > (I40E_MAX_ITR << 1)) { 2402 if (ec->rx_coalesce_usecs > I40E_MAX_ITR) {
2400 netif_info(pf, drv, netdev, "Invalid value, rx-usecs range is 0-8160\n"); 2403 netif_info(pf, drv, netdev, "Invalid value, rx-usecs range is 0-8160\n");
2401 return -EINVAL; 2404 return -EINVAL;
2402 } 2405 }
@@ -2407,16 +2410,16 @@ static int __i40e_set_coalesce(struct net_device *netdev,
2407 return -EINVAL; 2410 return -EINVAL;
2408 } 2411 }
2409 2412
2410 if (ec->tx_coalesce_usecs > (I40E_MAX_ITR << 1)) { 2413 if (ec->tx_coalesce_usecs > I40E_MAX_ITR) {
2411 netif_info(pf, drv, netdev, "Invalid value, tx-usecs range is 0-8160\n"); 2414 netif_info(pf, drv, netdev, "Invalid value, tx-usecs range is 0-8160\n");
2412 return -EINVAL; 2415 return -EINVAL;
2413 } 2416 }
2414 2417
2415 if (ec->use_adaptive_rx_coalesce && !cur_rx_itr) 2418 if (ec->use_adaptive_rx_coalesce && !cur_rx_itr)
2416 ec->rx_coalesce_usecs = I40E_MIN_ITR << 1; 2419 ec->rx_coalesce_usecs = I40E_MIN_ITR;
2417 2420
2418 if (ec->use_adaptive_tx_coalesce && !cur_tx_itr) 2421 if (ec->use_adaptive_tx_coalesce && !cur_tx_itr)
2419 ec->tx_coalesce_usecs = I40E_MIN_ITR << 1; 2422 ec->tx_coalesce_usecs = I40E_MIN_ITR;
2420 2423
2421 intrl_reg = i40e_intrl_usec_to_reg(ec->rx_coalesce_usecs_high); 2424 intrl_reg = i40e_intrl_usec_to_reg(ec->rx_coalesce_usecs_high);
2422 vsi->int_rate_limit = INTRL_REG_TO_USEC(intrl_reg); 2425 vsi->int_rate_limit = INTRL_REG_TO_USEC(intrl_reg);
@@ -4406,6 +4409,8 @@ static int i40e_set_priv_flags(struct net_device *dev, u32 flags)
4406 } 4409 }
4407 4410
4408flags_complete: 4411flags_complete:
4412 changed_flags = orig_flags ^ new_flags;
4413
4409 /* Before we finalize any flag changes, we need to perform some 4414 /* Before we finalize any flag changes, we need to perform some
4410 * checks to ensure that the changes are supported and safe. 4415 * checks to ensure that the changes are supported and safe.
4411 */ 4416 */
@@ -4415,21 +4420,17 @@ flags_complete:
4415 !(pf->hw_features & I40E_HW_ATR_EVICT_CAPABLE)) 4420 !(pf->hw_features & I40E_HW_ATR_EVICT_CAPABLE))
4416 return -EOPNOTSUPP; 4421 return -EOPNOTSUPP;
4417 4422
4418 /* Disable FW LLDP not supported if NPAR active or if FW 4423 /* If the driver detected FW LLDP was disabled on init, this flag could
4419 * API version < 1.7 4424 * be set, however we do not support _changing_ the flag if NPAR is
4425 * enabled or FW API version < 1.7. There are situations where older
4426 * FW versions/NPAR enabled PFs could disable LLDP, however we _must_
4427 * not allow the user to enable/disable LLDP with this flag on
4428 * unsupported FW versions.
4420 */ 4429 */
4421 if (new_flags & I40E_FLAG_DISABLE_FW_LLDP) { 4430 if (changed_flags & I40E_FLAG_DISABLE_FW_LLDP) {
4422 if (pf->hw.func_caps.npar_enable) { 4431 if (!(pf->hw_features & I40E_HW_STOPPABLE_FW_LLDP)) {
4423 dev_warn(&pf->pdev->dev,
4424 "Unable to stop FW LLDP if NPAR active\n");
4425 return -EOPNOTSUPP;
4426 }
4427
4428 if (pf->hw.aq.api_maj_ver < 1 ||
4429 (pf->hw.aq.api_maj_ver == 1 &&
4430 pf->hw.aq.api_min_ver < 7)) {
4431 dev_warn(&pf->pdev->dev, 4432 dev_warn(&pf->pdev->dev,
4432 "FW ver does not support stopping FW LLDP\n"); 4433 "Device does not support changing FW LLDP\n");
4433 return -EOPNOTSUPP; 4434 return -EOPNOTSUPP;
4434 } 4435 }
4435 } 4436 }
@@ -4439,6 +4440,10 @@ flags_complete:
4439 * something else has modified the flags variable since we copied it 4440 * something else has modified the flags variable since we copied it
4440 * originally. We'll just punt with an error and log something in the 4441 * originally. We'll just punt with an error and log something in the
4441 * message buffer. 4442 * message buffer.
4443 *
4444 * This is the point of no return for this function. We need to have
4445 * checked any discrepancies or misconfigurations and returned
4446 * EOPNOTSUPP before updating pf->flags here.
4442 */ 4447 */
4443 if (cmpxchg64(&pf->flags, orig_flags, new_flags) != orig_flags) { 4448 if (cmpxchg64(&pf->flags, orig_flags, new_flags) != orig_flags) {
4444 dev_warn(&pf->pdev->dev, 4449 dev_warn(&pf->pdev->dev,
@@ -4446,8 +4451,6 @@ flags_complete:
4446 return -EAGAIN; 4451 return -EAGAIN;
4447 } 4452 }
4448 4453
4449 changed_flags = orig_flags ^ new_flags;
4450
4451 /* Process any additional changes needed as a result of flag changes. 4454 /* Process any additional changes needed as a result of flag changes.
4452 * The changed_flags value reflects the list of bits that were 4455 * The changed_flags value reflects the list of bits that were
4453 * changed in the code above. 4456 * changed in the code above.
@@ -4479,6 +4482,12 @@ flags_complete:
4479 } 4482 }
4480 } 4483 }
4481 4484
4485 if ((changed_flags & pf->flags &
4486 I40E_FLAG_LINK_DOWN_ON_CLOSE_ENABLED) &&
4487 (pf->flags & I40E_FLAG_MFP_ENABLED))
4488 dev_warn(&pf->pdev->dev,
4489 "Turning on link-down-on-close flag may affect other partitions\n");
4490
4482 if (changed_flags & I40E_FLAG_DISABLE_FW_LLDP) { 4491 if (changed_flags & I40E_FLAG_DISABLE_FW_LLDP) {
4483 if (pf->flags & I40E_FLAG_DISABLE_FW_LLDP) { 4492 if (pf->flags & I40E_FLAG_DISABLE_FW_LLDP) {
4484 struct i40e_dcbx_config *dcbcfg; 4493 struct i40e_dcbx_config *dcbcfg;
diff --git a/drivers/net/ethernet/intel/i40e/i40e_fcoe.c b/drivers/net/ethernet/intel/i40e/i40e_fcoe.c
deleted file mode 100644
index 2d1253c5b7a1..000000000000
--- a/drivers/net/ethernet/intel/i40e/i40e_fcoe.c
+++ /dev/null
@@ -1,1571 +0,0 @@
1/*******************************************************************************
2 *
3 * Intel Ethernet Controller XL710 Family Linux Driver
4 * Copyright(c) 2013 - 2016 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
23 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24 *
25 ******************************************************************************/
26
27#include <linux/if_ether.h>
28#include <scsi/scsi_cmnd.h>
29#include <scsi/scsi_device.h>
30#include <scsi/fc/fc_fs.h>
31#include <scsi/fc/fc_fip.h>
32#include <scsi/fc/fc_fcoe.h>
33#include <scsi/libfc.h>
34#include <scsi/libfcoe.h>
35#include <uapi/linux/dcbnl.h>
36
37#include "i40e.h"
38#include "i40e_fcoe.h"
39
40/**
41 * i40e_fcoe_sof_is_class2 - returns true if this is a FC Class 2 SOF
42 * @sof: the FCoE start of frame delimiter
43 **/
44static inline bool i40e_fcoe_sof_is_class2(u8 sof)
45{
46 return (sof == FC_SOF_I2) || (sof == FC_SOF_N2);
47}
48
49/**
50 * i40e_fcoe_sof_is_class3 - returns true if this is a FC Class 3 SOF
51 * @sof: the FCoE start of frame delimiter
52 **/
53static inline bool i40e_fcoe_sof_is_class3(u8 sof)
54{
55 return (sof == FC_SOF_I3) || (sof == FC_SOF_N3);
56}
57
58/**
59 * i40e_fcoe_sof_is_supported - returns true if the FC SOF is supported by HW
60 * @sof: the input SOF value from the frame
61 **/
62static inline bool i40e_fcoe_sof_is_supported(u8 sof)
63{
64 return i40e_fcoe_sof_is_class2(sof) ||
65 i40e_fcoe_sof_is_class3(sof);
66}
67
68/**
69 * i40e_fcoe_fc_sof - pull the SOF from FCoE header in the frame
70 * @skb: the frame whose EOF is to be pulled from
71 **/
72static inline int i40e_fcoe_fc_sof(struct sk_buff *skb, u8 *sof)
73{
74 *sof = ((struct fcoe_hdr *)skb_network_header(skb))->fcoe_sof;
75
76 if (!i40e_fcoe_sof_is_supported(*sof))
77 return -EINVAL;
78 return 0;
79}
80
81/**
82 * i40e_fcoe_eof_is_supported - returns true if the EOF is supported by HW
83 * @eof: the input EOF value from the frame
84 **/
85static inline bool i40e_fcoe_eof_is_supported(u8 eof)
86{
87 return (eof == FC_EOF_N) || (eof == FC_EOF_T) ||
88 (eof == FC_EOF_NI) || (eof == FC_EOF_A);
89}
90
91/**
92 * i40e_fcoe_fc_eof - pull EOF from FCoE trailer in the frame
93 * @skb: the frame whose EOF is to be pulled from
94 **/
95static inline int i40e_fcoe_fc_eof(struct sk_buff *skb, u8 *eof)
96{
97 /* the first byte of the last dword is EOF */
98 skb_copy_bits(skb, skb->len - 4, eof, 1);
99
100 if (!i40e_fcoe_eof_is_supported(*eof))
101 return -EINVAL;
102 return 0;
103}
104
105/**
106 * i40e_fcoe_ctxt_eof - convert input FC EOF for descriptor programming
107 * @eof: the input eof value from the frame
108 *
109 * The FC EOF is converted to the value understood by HW for descriptor
110 * programming. Never call this w/o calling i40e_fcoe_eof_is_supported()
111 * first and that already checks for all supported valid eof values.
112 **/
113static inline u32 i40e_fcoe_ctxt_eof(u8 eof)
114{
115 switch (eof) {
116 case FC_EOF_N:
117 return I40E_TX_DESC_CMD_L4T_EOFT_EOF_N;
118 case FC_EOF_T:
119 return I40E_TX_DESC_CMD_L4T_EOFT_EOF_T;
120 case FC_EOF_NI:
121 return I40E_TX_DESC_CMD_L4T_EOFT_EOF_NI;
122 case FC_EOF_A:
123 return I40E_TX_DESC_CMD_L4T_EOFT_EOF_A;
124 default:
125 /* Supported valid eof shall be already checked by
126 * calling i40e_fcoe_eof_is_supported() first,
127 * therefore this default case shall never hit.
128 */
129 WARN_ON(1);
130 return -EINVAL;
131 }
132}
133
134/**
135 * i40e_fcoe_xid_is_valid - returns true if the exchange id is valid
136 * @xid: the exchange id
137 **/
138static inline bool i40e_fcoe_xid_is_valid(u16 xid)
139{
140 return (xid != FC_XID_UNKNOWN) && (xid < I40E_FCOE_DDP_MAX);
141}
142
143/**
144 * i40e_fcoe_ddp_unmap - unmap the mapped sglist associated
145 * @pf: pointer to PF
146 * @ddp: sw DDP context
147 *
148 * Unmap the scatter-gather list associated with the given SW DDP context
149 *
150 * Returns: data length already ddp-ed in bytes
151 *
152 **/
153static inline void i40e_fcoe_ddp_unmap(struct i40e_pf *pf,
154 struct i40e_fcoe_ddp *ddp)
155{
156 if (test_and_set_bit(__I40E_FCOE_DDP_UNMAPPED, &ddp->flags))
157 return;
158
159 if (ddp->sgl) {
160 dma_unmap_sg(&pf->pdev->dev, ddp->sgl, ddp->sgc,
161 DMA_FROM_DEVICE);
162 ddp->sgl = NULL;
163 ddp->sgc = 0;
164 }
165
166 if (ddp->pool) {
167 dma_pool_free(ddp->pool, ddp->udl, ddp->udp);
168 ddp->pool = NULL;
169 }
170}
171
172/**
173 * i40e_fcoe_ddp_clear - clear the given SW DDP context
174 * @ddp - SW DDP context
175 **/
176static inline void i40e_fcoe_ddp_clear(struct i40e_fcoe_ddp *ddp)
177{
178 memset(ddp, 0, sizeof(struct i40e_fcoe_ddp));
179 ddp->xid = FC_XID_UNKNOWN;
180 ddp->flags = __I40E_FCOE_DDP_NONE;
181}
182
183/**
184 * i40e_fcoe_progid_is_fcoe - check if the prog_id is for FCoE
185 * @id: the prog id for the programming status Rx descriptor write-back
186 **/
187static inline bool i40e_fcoe_progid_is_fcoe(u8 id)
188{
189 return (id == I40E_RX_PROG_STATUS_DESC_FCOE_CTXT_PROG_STATUS) ||
190 (id == I40E_RX_PROG_STATUS_DESC_FCOE_CTXT_INVL_STATUS);
191}
192
193/**
194 * i40e_fcoe_fc_get_xid - get xid from the frame header
195 * @fh: the fc frame header
196 *
197 * In case the incoming frame's exchange is originated from
198 * the initiator, then received frame's exchange id is ANDed
199 * with fc_cpu_mask bits to get the same cpu on which exchange
200 * was originated, otherwise just use the current cpu.
201 *
202 * Returns ox_id if exchange originator, rx_id if responder
203 **/
204static inline u16 i40e_fcoe_fc_get_xid(struct fc_frame_header *fh)
205{
206 u32 f_ctl = ntoh24(fh->fh_f_ctl);
207
208 return (f_ctl & FC_FC_EX_CTX) ?
209 be16_to_cpu(fh->fh_ox_id) :
210 be16_to_cpu(fh->fh_rx_id);
211}
212
213/**
214 * i40e_fcoe_fc_frame_header - get fc frame header from skb
215 * @skb: packet
216 *
217 * This checks if there is a VLAN header and returns the data
218 * pointer to the start of the fc_frame_header.
219 *
220 * Returns pointer to the fc_frame_header
221 **/
222static inline struct fc_frame_header *i40e_fcoe_fc_frame_header(
223 struct sk_buff *skb)
224{
225 void *fh = skb->data + sizeof(struct fcoe_hdr);
226
227 if (eth_hdr(skb)->h_proto == htons(ETH_P_8021Q))
228 fh += sizeof(struct vlan_hdr);
229
230 return (struct fc_frame_header *)fh;
231}
232
233/**
234 * i40e_fcoe_ddp_put - release the DDP context for a given exchange id
235 * @netdev: the corresponding net_device
236 * @xid: the exchange id that corresponding DDP context will be released
237 *
238 * This is the implementation of net_device_ops.ndo_fcoe_ddp_done
239 * and it is expected to be called by ULD, i.e., FCP layer of libfc
240 * to release the corresponding ddp context when the I/O is done.
241 *
242 * Returns : data length already ddp-ed in bytes
243 **/
244static int i40e_fcoe_ddp_put(struct net_device *netdev, u16 xid)
245{
246 struct i40e_netdev_priv *np = netdev_priv(netdev);
247 struct i40e_pf *pf = np->vsi->back;
248 struct i40e_fcoe *fcoe = &pf->fcoe;
249 int len = 0;
250 struct i40e_fcoe_ddp *ddp = &fcoe->ddp[xid];
251
252 if (!fcoe || !ddp)
253 goto out;
254
255 if (test_bit(__I40E_FCOE_DDP_DONE, &ddp->flags))
256 len = ddp->len;
257 i40e_fcoe_ddp_unmap(pf, ddp);
258out:
259 return len;
260}
261
262/**
263 * i40e_fcoe_sw_init - sets up the HW for FCoE
264 * @pf: pointer to PF
265 **/
266void i40e_init_pf_fcoe(struct i40e_pf *pf)
267{
268 struct i40e_hw *hw = &pf->hw;
269 u32 val;
270
271 pf->flags &= ~I40E_FLAG_FCOE_ENABLED;
272 pf->num_fcoe_qps = 0;
273 pf->fcoe_hmc_cntx_num = 0;
274 pf->fcoe_hmc_filt_num = 0;
275
276 if (!pf->hw.func_caps.fcoe) {
277 dev_dbg(&pf->pdev->dev, "FCoE capability is disabled\n");
278 return;
279 }
280
281 if (!pf->hw.func_caps.dcb) {
282 dev_warn(&pf->pdev->dev,
283 "Hardware is not DCB capable not enabling FCoE.\n");
284 return;
285 }
286
287 /* enable FCoE hash filter */
288 val = i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1));
289 val |= BIT(I40E_FILTER_PCTYPE_FCOE_OX - 32);
290 val |= BIT(I40E_FILTER_PCTYPE_FCOE_RX - 32);
291 val &= I40E_PFQF_HENA_PTYPE_ENA_MASK;
292 i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), val);
293
294 /* enable flag */
295 pf->flags |= I40E_FLAG_FCOE_ENABLED;
296 pf->num_fcoe_qps = I40E_DEFAULT_FCOE;
297
298 /* Reserve 4K DDP contexts and 20K filter size for FCoE */
299 pf->fcoe_hmc_cntx_num = BIT(I40E_DMA_CNTX_SIZE_4K) *
300 I40E_DMA_CNTX_BASE_SIZE;
301 pf->fcoe_hmc_filt_num = pf->fcoe_hmc_cntx_num +
302 BIT(I40E_HASH_FILTER_SIZE_16K) *
303 I40E_HASH_FILTER_BASE_SIZE;
304
305 /* FCoE object: max 16K filter buckets and 4K DMA contexts */
306 pf->filter_settings.fcoe_filt_num = I40E_HASH_FILTER_SIZE_16K;
307 pf->filter_settings.fcoe_cntx_num = I40E_DMA_CNTX_SIZE_4K;
308
309 /* Setup max frame with FCoE_MTU plus L2 overheads */
310 val = i40e_read_rx_ctl(hw, I40E_GLFCOE_RCTL);
311 val &= ~I40E_GLFCOE_RCTL_MAX_SIZE_MASK;
312 val |= ((FCOE_MTU + ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN)
313 << I40E_GLFCOE_RCTL_MAX_SIZE_SHIFT);
314 i40e_write_rx_ctl(hw, I40E_GLFCOE_RCTL, val);
315
316 dev_info(&pf->pdev->dev, "FCoE is supported.\n");
317}
318
319/**
320 * i40e_get_fcoe_tc_map - Return TC map for FCoE APP
321 * @pf: pointer to PF
322 *
323 **/
324u8 i40e_get_fcoe_tc_map(struct i40e_pf *pf)
325{
326 struct i40e_dcb_app_priority_table app;
327 struct i40e_hw *hw = &pf->hw;
328 u8 enabled_tc = 0;
329 u8 tc, i;
330 /* Get the FCoE APP TLV */
331 struct i40e_dcbx_config *dcbcfg = &hw->local_dcbx_config;
332
333 for (i = 0; i < dcbcfg->numapps; i++) {
334 app = dcbcfg->app[i];
335 if (app.selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE &&
336 app.protocolid == ETH_P_FCOE) {
337 tc = dcbcfg->etscfg.prioritytable[app.priority];
338 enabled_tc |= BIT(tc);
339 break;
340 }
341 }
342
343 /* TC0 if there is no TC defined for FCoE APP TLV */
344 enabled_tc = enabled_tc ? enabled_tc : 0x1;
345
346 return enabled_tc;
347}
348
349/**
350 * i40e_fcoe_vsi_init - prepares the VSI context for creating a FCoE VSI
351 * @vsi: pointer to the associated VSI struct
352 * @ctxt: pointer to the associated VSI context to be passed to HW
353 *
354 * Returns 0 on success or < 0 on error
355 **/
356int i40e_fcoe_vsi_init(struct i40e_vsi *vsi, struct i40e_vsi_context *ctxt)
357{
358 struct i40e_aqc_vsi_properties_data *info = &ctxt->info;
359 struct i40e_pf *pf = vsi->back;
360 struct i40e_hw *hw = &pf->hw;
361 u8 enabled_tc = 0;
362
363 if (!(pf->flags & I40E_FLAG_FCOE_ENABLED)) {
364 dev_err(&pf->pdev->dev,
365 "FCoE is not enabled for this device\n");
366 return -EPERM;
367 }
368
369 /* initialize the hardware for FCoE */
370 ctxt->pf_num = hw->pf_id;
371 ctxt->vf_num = 0;
372 ctxt->uplink_seid = vsi->uplink_seid;
373 ctxt->connection_type = I40E_AQ_VSI_CONN_TYPE_NORMAL;
374 ctxt->flags = I40E_AQ_VSI_TYPE_PF;
375
376 /* FCoE VSI would need the following sections */
377 info->valid_sections |= cpu_to_le16(I40E_AQ_VSI_PROP_QUEUE_OPT_VALID);
378
379 /* FCoE VSI does not need these sections */
380 info->valid_sections &= cpu_to_le16(~(I40E_AQ_VSI_PROP_SECURITY_VALID |
381 I40E_AQ_VSI_PROP_VLAN_VALID |
382 I40E_AQ_VSI_PROP_CAS_PV_VALID |
383 I40E_AQ_VSI_PROP_INGRESS_UP_VALID |
384 I40E_AQ_VSI_PROP_EGRESS_UP_VALID));
385
386 if (i40e_is_vsi_uplink_mode_veb(vsi)) {
387 info->valid_sections |=
388 cpu_to_le16(I40E_AQ_VSI_PROP_SWITCH_VALID);
389 info->switch_id =
390 cpu_to_le16(I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB);
391 }
392 enabled_tc = i40e_get_fcoe_tc_map(pf);
393 i40e_vsi_setup_queue_map(vsi, ctxt, enabled_tc, true);
394
395 /* set up queue option section: only enable FCoE */
396 info->queueing_opt_flags = I40E_AQ_VSI_QUE_OPT_FCOE_ENA;
397
398 return 0;
399}
400
401/**
402 * i40e_fcoe_enable - this is the implementation of ndo_fcoe_enable,
403 * indicating the upper FCoE protocol stack is ready to use FCoE
404 * offload features.
405 *
406 * @netdev: pointer to the netdev that FCoE is created on
407 *
408 * Returns 0 on success
409 *
410 * in RTNL
411 *
412 **/
413int i40e_fcoe_enable(struct net_device *netdev)
414{
415 struct i40e_netdev_priv *np = netdev_priv(netdev);
416 struct i40e_vsi *vsi = np->vsi;
417 struct i40e_pf *pf = vsi->back;
418 struct i40e_fcoe *fcoe = &pf->fcoe;
419
420 if (!(pf->flags & I40E_FLAG_FCOE_ENABLED)) {
421 netdev_err(netdev, "HW does not support FCoE.\n");
422 return -ENODEV;
423 }
424
425 if (vsi->type != I40E_VSI_FCOE) {
426 netdev_err(netdev, "interface does not support FCoE.\n");
427 return -EBUSY;
428 }
429
430 atomic_inc(&fcoe->refcnt);
431
432 return 0;
433}
434
435/**
436 * i40e_fcoe_disable- disables FCoE for upper FCoE protocol stack.
437 * @dev: pointer to the netdev that FCoE is created on
438 *
439 * Returns 0 on success
440 *
441 **/
442int i40e_fcoe_disable(struct net_device *netdev)
443{
444 struct i40e_netdev_priv *np = netdev_priv(netdev);
445 struct i40e_vsi *vsi = np->vsi;
446 struct i40e_pf *pf = vsi->back;
447 struct i40e_fcoe *fcoe = &pf->fcoe;
448
449 if (!(pf->flags & I40E_FLAG_FCOE_ENABLED)) {
450 netdev_err(netdev, "device does not support FCoE\n");
451 return -ENODEV;
452 }
453 if (vsi->type != I40E_VSI_FCOE)
454 return -EBUSY;
455
456 if (!atomic_dec_and_test(&fcoe->refcnt))
457 return -EINVAL;
458
459 netdev_info(netdev, "FCoE disabled\n");
460
461 return 0;
462}
463
464/**
465 * i40e_fcoe_dma_pool_free - free the per cpu pool for FCoE DDP
466 * @fcoe: the FCoE sw object
467 * @dev: the device that the pool is associated with
468 * @cpu: the cpu for this pool
469 *
470 **/
471static void i40e_fcoe_dma_pool_free(struct i40e_fcoe *fcoe,
472 struct device *dev,
473 unsigned int cpu)
474{
475 struct i40e_fcoe_ddp_pool *ddp_pool;
476
477 ddp_pool = per_cpu_ptr(fcoe->ddp_pool, cpu);
478 if (!ddp_pool->pool) {
479 dev_warn(dev, "DDP pool already freed for cpu %d\n", cpu);
480 return;
481 }
482 dma_pool_destroy(ddp_pool->pool);
483 ddp_pool->pool = NULL;
484}
485
486/**
487 * i40e_fcoe_dma_pool_create - per cpu pool for FCoE DDP
488 * @fcoe: the FCoE sw object
489 * @dev: the device that the pool is associated with
490 * @cpu: the cpu for this pool
491 *
492 * Returns 0 on successful or non zero on failure
493 *
494 **/
495static int i40e_fcoe_dma_pool_create(struct i40e_fcoe *fcoe,
496 struct device *dev,
497 unsigned int cpu)
498{
499 struct i40e_fcoe_ddp_pool *ddp_pool;
500 struct dma_pool *pool;
501 char pool_name[32];
502
503 ddp_pool = per_cpu_ptr(fcoe->ddp_pool, cpu);
504 if (ddp_pool && ddp_pool->pool) {
505 dev_warn(dev, "DDP pool already allocated for cpu %d\n", cpu);
506 return 0;
507 }
508 snprintf(pool_name, sizeof(pool_name), "i40e_fcoe_ddp_%d", cpu);
509 pool = dma_pool_create(pool_name, dev, I40E_FCOE_DDP_PTR_MAX,
510 I40E_FCOE_DDP_PTR_ALIGN, PAGE_SIZE);
511 if (!pool) {
512 dev_err(dev, "dma_pool_create %s failed\n", pool_name);
513 return -ENOMEM;
514 }
515 ddp_pool->pool = pool;
516 return 0;
517}
518
519/**
520 * i40e_fcoe_free_ddp_resources - release FCoE DDP resources
521 * @vsi: the vsi FCoE is associated with
522 *
523 **/
524void i40e_fcoe_free_ddp_resources(struct i40e_vsi *vsi)
525{
526 struct i40e_pf *pf = vsi->back;
527 struct i40e_fcoe *fcoe = &pf->fcoe;
528 int cpu, i;
529
530 /* do nothing if not FCoE VSI */
531 if (vsi->type != I40E_VSI_FCOE)
532 return;
533
534 /* do nothing if no DDP pools were allocated */
535 if (!fcoe->ddp_pool)
536 return;
537
538 for (i = 0; i < I40E_FCOE_DDP_MAX; i++)
539 i40e_fcoe_ddp_put(vsi->netdev, i);
540
541 for_each_possible_cpu(cpu)
542 i40e_fcoe_dma_pool_free(fcoe, &pf->pdev->dev, cpu);
543
544 free_percpu(fcoe->ddp_pool);
545 fcoe->ddp_pool = NULL;
546
547 netdev_info(vsi->netdev, "VSI %d,%d FCoE DDP resources released\n",
548 vsi->id, vsi->seid);
549}
550
551/**
552 * i40e_fcoe_setup_ddp_resources - allocate per cpu DDP resources
553 * @vsi: the VSI FCoE is associated with
554 *
555 * Returns 0 on successful or non zero on failure
556 *
557 **/
558int i40e_fcoe_setup_ddp_resources(struct i40e_vsi *vsi)
559{
560 struct i40e_pf *pf = vsi->back;
561 struct device *dev = &pf->pdev->dev;
562 struct i40e_fcoe *fcoe = &pf->fcoe;
563 unsigned int cpu;
564 int i;
565
566 if (vsi->type != I40E_VSI_FCOE)
567 return -ENODEV;
568
569 /* do nothing if no DDP pools were allocated */
570 if (fcoe->ddp_pool)
571 return -EEXIST;
572
573 /* allocate per CPU memory to track DDP pools */
574 fcoe->ddp_pool = alloc_percpu(struct i40e_fcoe_ddp_pool);
575 if (!fcoe->ddp_pool) {
576 dev_err(&pf->pdev->dev, "failed to allocate percpu DDP\n");
577 return -ENOMEM;
578 }
579
580 /* allocate pci pool for each cpu */
581 for_each_possible_cpu(cpu) {
582 if (!i40e_fcoe_dma_pool_create(fcoe, dev, cpu))
583 continue;
584
585 dev_err(dev, "failed to alloc DDP pool on cpu:%d\n", cpu);
586 i40e_fcoe_free_ddp_resources(vsi);
587 return -ENOMEM;
588 }
589
590 /* initialize the sw context */
591 for (i = 0; i < I40E_FCOE_DDP_MAX; i++)
592 i40e_fcoe_ddp_clear(&fcoe->ddp[i]);
593
594 netdev_info(vsi->netdev, "VSI %d,%d FCoE DDP resources allocated\n",
595 vsi->id, vsi->seid);
596
597 return 0;
598}
599
600/**
601 * i40e_fcoe_handle_status - check the Programming Status for FCoE
602 * @rx_ring: the Rx ring for this descriptor
603 * @rx_desc: the Rx descriptor for Programming Status, not a packet descriptor.
604 *
605 * Check if this is the Rx Programming Status descriptor write-back for FCoE.
606 * This is used to verify if the context/filter programming or invalidation
607 * requested by SW to the HW is successful or not and take actions accordingly.
608 **/
609void i40e_fcoe_handle_status(struct i40e_ring *rx_ring,
610 union i40e_rx_desc *rx_desc, u8 prog_id)
611{
612 struct i40e_pf *pf = rx_ring->vsi->back;
613 struct i40e_fcoe *fcoe = &pf->fcoe;
614 struct i40e_fcoe_ddp *ddp;
615 u32 error;
616 u16 xid;
617 u64 qw;
618
619 /* we only care for FCoE here */
620 if (!i40e_fcoe_progid_is_fcoe(prog_id))
621 return;
622
623 xid = le32_to_cpu(rx_desc->wb.qword0.hi_dword.fcoe_param) &
624 (I40E_FCOE_DDP_MAX - 1);
625
626 if (!i40e_fcoe_xid_is_valid(xid))
627 return;
628
629 ddp = &fcoe->ddp[xid];
630 WARN_ON(xid != ddp->xid);
631
632 qw = le64_to_cpu(rx_desc->wb.qword1.status_error_len);
633 error = (qw & I40E_RX_PROG_STATUS_DESC_QW1_ERROR_MASK) >>
634 I40E_RX_PROG_STATUS_DESC_QW1_ERROR_SHIFT;
635
636 /* DDP context programming status: failure or success */
637 if (prog_id == I40E_RX_PROG_STATUS_DESC_FCOE_CTXT_PROG_STATUS) {
638 if (I40E_RX_PROG_FCOE_ERROR_TBL_FULL(error)) {
639 dev_err(&pf->pdev->dev, "xid %x ddp->xid %x TABLE FULL\n",
640 xid, ddp->xid);
641 ddp->prerr |= I40E_RX_PROG_FCOE_ERROR_TBL_FULL_BIT;
642 }
643 if (I40E_RX_PROG_FCOE_ERROR_CONFLICT(error)) {
644 dev_err(&pf->pdev->dev, "xid %x ddp->xid %x CONFLICT\n",
645 xid, ddp->xid);
646 ddp->prerr |= I40E_RX_PROG_FCOE_ERROR_CONFLICT_BIT;
647 }
648 }
649
650 /* DDP context invalidation status: failure or success */
651 if (prog_id == I40E_RX_PROG_STATUS_DESC_FCOE_CTXT_INVL_STATUS) {
652 if (I40E_RX_PROG_FCOE_ERROR_INVLFAIL(error)) {
653 dev_err(&pf->pdev->dev, "xid %x ddp->xid %x INVALIDATION FAILURE\n",
654 xid, ddp->xid);
655 ddp->prerr |= I40E_RX_PROG_FCOE_ERROR_INVLFAIL_BIT;
656 }
657 /* clear the flag so we can retry invalidation */
658 clear_bit(__I40E_FCOE_DDP_ABORTED, &ddp->flags);
659 }
660
661 /* unmap DMA */
662 i40e_fcoe_ddp_unmap(pf, ddp);
663 i40e_fcoe_ddp_clear(ddp);
664}
665
666/**
667 * i40e_fcoe_handle_offload - check ddp status and mark it done
668 * @adapter: i40e adapter
669 * @rx_desc: advanced rx descriptor
670 * @skb: the skb holding the received data
671 *
672 * This checks ddp status.
673 *
674 * Returns : < 0 indicates an error or not a FCOE ddp, 0 indicates
675 * not passing the skb to ULD, > 0 indicates is the length of data
676 * being ddped.
677 *
678 **/
679int i40e_fcoe_handle_offload(struct i40e_ring *rx_ring,
680 union i40e_rx_desc *rx_desc,
681 struct sk_buff *skb)
682{
683 struct i40e_pf *pf = rx_ring->vsi->back;
684 struct i40e_fcoe *fcoe = &pf->fcoe;
685 struct fc_frame_header *fh = NULL;
686 struct i40e_fcoe_ddp *ddp = NULL;
687 u32 status, fltstat;
688 u32 error, fcerr;
689 int rc = -EINVAL;
690 u16 ptype;
691 u16 xid;
692 u64 qw;
693
694 /* check this rxd is for programming status */
695 qw = le64_to_cpu(rx_desc->wb.qword1.status_error_len);
696 /* packet descriptor, check packet type */
697 ptype = (qw & I40E_RXD_QW1_PTYPE_MASK) >> I40E_RXD_QW1_PTYPE_SHIFT;
698 if (!i40e_rx_is_fcoe(ptype))
699 goto out_no_ddp;
700
701 error = (qw & I40E_RXD_QW1_ERROR_MASK) >> I40E_RXD_QW1_ERROR_SHIFT;
702 fcerr = (error >> I40E_RX_DESC_ERROR_L3L4E_SHIFT) &
703 I40E_RX_DESC_FCOE_ERROR_MASK;
704
705 /* check stateless offload error */
706 if (unlikely(fcerr == I40E_RX_DESC_ERROR_L3L4E_PROT)) {
707 dev_err(&pf->pdev->dev, "Protocol Error\n");
708 skb->ip_summed = CHECKSUM_NONE;
709 } else {
710 skb->ip_summed = CHECKSUM_UNNECESSARY;
711 }
712
713 /* check hw status on ddp */
714 status = (qw & I40E_RXD_QW1_STATUS_MASK) >> I40E_RXD_QW1_STATUS_SHIFT;
715 fltstat = (status >> I40E_RX_DESC_STATUS_FLTSTAT_SHIFT) &
716 I40E_RX_DESC_FLTSTAT_FCMASK;
717
718 /* now we are ready to check DDP */
719 fh = i40e_fcoe_fc_frame_header(skb);
720 xid = i40e_fcoe_fc_get_xid(fh);
721 if (!i40e_fcoe_xid_is_valid(xid))
722 goto out_no_ddp;
723
724 /* non DDP normal receive, return to the protocol stack */
725 if (fltstat == I40E_RX_DESC_FLTSTAT_NOMTCH)
726 goto out_no_ddp;
727
728 /* do we have a sw ddp context setup ? */
729 ddp = &fcoe->ddp[xid];
730 if (!ddp->sgl)
731 goto out_no_ddp;
732
733 /* fetch xid from hw rxd wb, which should match up the sw ctxt */
734 xid = le16_to_cpu(rx_desc->wb.qword0.lo_dword.mirr_fcoe.fcoe_ctx_id);
735 if (ddp->xid != xid) {
736 dev_err(&pf->pdev->dev, "xid 0x%x does not match ctx_xid 0x%x\n",
737 ddp->xid, xid);
738 goto out_put_ddp;
739 }
740
741 /* the same exchange has already errored out */
742 if (ddp->fcerr) {
743 dev_err(&pf->pdev->dev, "xid 0x%x fcerr 0x%x reported fcer 0x%x\n",
744 xid, ddp->fcerr, fcerr);
745 goto out_put_ddp;
746 }
747
748 /* fcoe param is valid by now with correct DDPed length */
749 ddp->len = le32_to_cpu(rx_desc->wb.qword0.hi_dword.fcoe_param);
750 ddp->fcerr = fcerr;
751 /* header posting only, useful only for target mode and debugging */
752 if (fltstat == I40E_RX_DESC_FLTSTAT_DDP) {
753 /* For target mode, we get header of the last packet but it
754 * does not have the FCoE trailer field, i.e., CRC and EOF
755 * Ordered Set since they are offloaded by the HW, so fill
756 * it up correspondingly to allow the packet to pass through
757 * to the upper protocol stack.
758 */
759 u32 f_ctl = ntoh24(fh->fh_f_ctl);
760
761 if ((f_ctl & FC_FC_END_SEQ) &&
762 (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA)) {
763 struct fcoe_crc_eof *crc = NULL;
764
765 crc = skb_put(skb, sizeof(*crc));
766 crc->fcoe_eof = FC_EOF_T;
767 } else {
768 /* otherwise, drop the header only frame */
769 rc = 0;
770 goto out_no_ddp;
771 }
772 }
773
774out_put_ddp:
775 /* either we got RSP or we have an error, unmap DMA in both cases */
776 i40e_fcoe_ddp_unmap(pf, ddp);
777 if (ddp->len && !ddp->fcerr) {
778 int pkts;
779
780 rc = ddp->len;
781 i40e_fcoe_ddp_clear(ddp);
782 ddp->len = rc;
783 pkts = DIV_ROUND_UP(rc, 2048);
784 rx_ring->stats.bytes += rc;
785 rx_ring->stats.packets += pkts;
786 rx_ring->q_vector->rx.total_bytes += rc;
787 rx_ring->q_vector->rx.total_packets += pkts;
788 set_bit(__I40E_FCOE_DDP_DONE, &ddp->flags);
789 }
790
791out_no_ddp:
792 return rc;
793}
794
795/**
796 * i40e_fcoe_ddp_setup - called to set up ddp context
797 * @netdev: the corresponding net_device
798 * @xid: the exchange id requesting ddp
799 * @sgl: the scatter-gather list for this request
800 * @sgc: the number of scatter-gather items
801 * @target_mode: indicates this is a DDP request for target
802 *
803 * Returns : 1 for success and 0 for no DDP on this I/O
804 **/
805static int i40e_fcoe_ddp_setup(struct net_device *netdev, u16 xid,
806 struct scatterlist *sgl, unsigned int sgc,
807 int target_mode)
808{
809 static const unsigned int bufflen = I40E_FCOE_DDP_BUF_MIN;
810 struct i40e_netdev_priv *np = netdev_priv(netdev);
811 struct i40e_fcoe_ddp_pool *ddp_pool;
812 struct i40e_pf *pf = np->vsi->back;
813 struct i40e_fcoe *fcoe = &pf->fcoe;
814 unsigned int i, j, dmacount;
815 struct i40e_fcoe_ddp *ddp;
816 unsigned int firstoff = 0;
817 unsigned int thisoff = 0;
818 unsigned int thislen = 0;
819 struct scatterlist *sg;
820 dma_addr_t addr = 0;
821 unsigned int len;
822
823 if (xid >= I40E_FCOE_DDP_MAX) {
824 dev_warn(&pf->pdev->dev, "xid=0x%x out-of-range\n", xid);
825 return 0;
826 }
827
828 /* no DDP if we are already down or resetting */
829 if (test_bit(__I40E_DOWN, &pf->state) ||
830 test_bit(__I40E_NEEDS_RESTART, &pf->state)) {
831 dev_info(&pf->pdev->dev, "xid=0x%x device in reset/down\n",
832 xid);
833 return 0;
834 }
835
836 ddp = &fcoe->ddp[xid];
837 if (ddp->sgl) {
838 dev_info(&pf->pdev->dev, "xid 0x%x w/ non-null sgl=%p nents=%d\n",
839 xid, ddp->sgl, ddp->sgc);
840 return 0;
841 }
842 i40e_fcoe_ddp_clear(ddp);
843
844 if (!fcoe->ddp_pool) {
845 dev_info(&pf->pdev->dev, "No DDP pool, xid 0x%x\n", xid);
846 return 0;
847 }
848
849 ddp_pool = per_cpu_ptr(fcoe->ddp_pool, get_cpu());
850 if (!ddp_pool->pool) {
851 dev_info(&pf->pdev->dev, "No percpu ddp pool, xid 0x%x\n", xid);
852 goto out_noddp;
853 }
854
855 /* setup dma from scsi command sgl */
856 dmacount = dma_map_sg(&pf->pdev->dev, sgl, sgc, DMA_FROM_DEVICE);
857 if (dmacount == 0) {
858 dev_info(&pf->pdev->dev, "dma_map_sg for sgl %p, sgc %d failed\n",
859 sgl, sgc);
860 goto out_noddp_unmap;
861 }
862
863 /* alloc the udl from our ddp pool */
864 ddp->udl = dma_pool_alloc(ddp_pool->pool, GFP_ATOMIC, &ddp->udp);
865 if (!ddp->udl) {
866 dev_info(&pf->pdev->dev,
867 "Failed allocated ddp context, xid 0x%x\n", xid);
868 goto out_noddp_unmap;
869 }
870
871 j = 0;
872 ddp->len = 0;
873 for_each_sg(sgl, sg, dmacount, i) {
874 addr = sg_dma_address(sg);
875 len = sg_dma_len(sg);
876 ddp->len += len;
877 while (len) {
878 /* max number of buffers allowed in one DDP context */
879 if (j >= I40E_FCOE_DDP_BUFFCNT_MAX) {
880 dev_info(&pf->pdev->dev,
881 "xid=%x:%d,%d,%d:addr=%llx not enough descriptors\n",
882 xid, i, j, dmacount, (u64)addr);
883 goto out_noddp_free;
884 }
885
886 /* get the offset of length of current buffer */
887 thisoff = addr & ((dma_addr_t)bufflen - 1);
888 thislen = min_t(unsigned int, (bufflen - thisoff), len);
889 /* all but the 1st buffer (j == 0)
890 * must be aligned on bufflen
891 */
892 if ((j != 0) && (thisoff))
893 goto out_noddp_free;
894
895 /* all but the last buffer
896 * ((i == (dmacount - 1)) && (thislen == len))
897 * must end at bufflen
898 */
899 if (((i != (dmacount - 1)) || (thislen != len)) &&
900 ((thislen + thisoff) != bufflen))
901 goto out_noddp_free;
902
903 ddp->udl[j] = (u64)(addr - thisoff);
904 /* only the first buffer may have none-zero offset */
905 if (j == 0)
906 firstoff = thisoff;
907 len -= thislen;
908 addr += thislen;
909 j++;
910 }
911 }
912 /* only the last buffer may have non-full bufflen */
913 ddp->lastsize = thisoff + thislen;
914 ddp->firstoff = firstoff;
915 ddp->list_len = j;
916 ddp->pool = ddp_pool->pool;
917 ddp->sgl = sgl;
918 ddp->sgc = sgc;
919 ddp->xid = xid;
920 if (target_mode)
921 set_bit(__I40E_FCOE_DDP_TARGET, &ddp->flags);
922 set_bit(__I40E_FCOE_DDP_INITALIZED, &ddp->flags);
923
924 put_cpu();
925 return 1; /* Success */
926
927out_noddp_free:
928 dma_pool_free(ddp->pool, ddp->udl, ddp->udp);
929 i40e_fcoe_ddp_clear(ddp);
930
931out_noddp_unmap:
932 dma_unmap_sg(&pf->pdev->dev, sgl, sgc, DMA_FROM_DEVICE);
933out_noddp:
934 put_cpu();
935 return 0;
936}
937
938/**
939 * i40e_fcoe_ddp_get - called to set up ddp context in initiator mode
940 * @netdev: the corresponding net_device
941 * @xid: the exchange id requesting ddp
942 * @sgl: the scatter-gather list for this request
943 * @sgc: the number of scatter-gather items
944 *
945 * This is the implementation of net_device_ops.ndo_fcoe_ddp_setup
946 * and is expected to be called from ULD, e.g., FCP layer of libfc
947 * to set up ddp for the corresponding xid of the given sglist for
948 * the corresponding I/O.
949 *
950 * Returns : 1 for success and 0 for no ddp
951 **/
952static int i40e_fcoe_ddp_get(struct net_device *netdev, u16 xid,
953 struct scatterlist *sgl, unsigned int sgc)
954{
955 return i40e_fcoe_ddp_setup(netdev, xid, sgl, sgc, 0);
956}
957
958/**
959 * i40e_fcoe_ddp_target - called to set up ddp context in target mode
960 * @netdev: the corresponding net_device
961 * @xid: the exchange id requesting ddp
962 * @sgl: the scatter-gather list for this request
963 * @sgc: the number of scatter-gather items
964 *
965 * This is the implementation of net_device_ops.ndo_fcoe_ddp_target
966 * and is expected to be called from ULD, e.g., FCP layer of libfc
967 * to set up ddp for the corresponding xid of the given sglist for
968 * the corresponding I/O. The DDP in target mode is a write I/O request
969 * from the initiator.
970 *
971 * Returns : 1 for success and 0 for no ddp
972 **/
973static int i40e_fcoe_ddp_target(struct net_device *netdev, u16 xid,
974 struct scatterlist *sgl, unsigned int sgc)
975{
976 return i40e_fcoe_ddp_setup(netdev, xid, sgl, sgc, 1);
977}
978
979/**
980 * i40e_fcoe_program_ddp - programs the HW DDP related descriptors
981 * @tx_ring: transmit ring for this packet
982 * @skb: the packet to be sent out
983 * @sof: the SOF to indicate class of service
984 *
985 * Determine if it is READ/WRITE command, and finds out if there is
986 * a matching SW DDP context for this command. DDP is applicable
987 * only in case of READ if initiator or WRITE in case of
988 * responder (via checking XFER_RDY).
989 *
990 * Note: caller checks sof and ddp sw context
991 *
992 * Returns : none
993 *
994 **/
995static void i40e_fcoe_program_ddp(struct i40e_ring *tx_ring,
996 struct sk_buff *skb,
997 struct i40e_fcoe_ddp *ddp, u8 sof)
998{
999 struct i40e_fcoe_filter_context_desc *filter_desc = NULL;
1000 struct i40e_fcoe_queue_context_desc *queue_desc = NULL;
1001 struct i40e_fcoe_ddp_context_desc *ddp_desc = NULL;
1002 struct i40e_pf *pf = tx_ring->vsi->back;
1003 u16 i = tx_ring->next_to_use;
1004 struct fc_frame_header *fh;
1005 u64 flags_rsvd_lanq = 0;
1006 bool target_mode;
1007
1008 /* check if abort is still pending */
1009 if (test_bit(__I40E_FCOE_DDP_ABORTED, &ddp->flags)) {
1010 dev_warn(&pf->pdev->dev,
1011 "DDP abort is still pending xid:%hx and ddp->flags:%lx:\n",
1012 ddp->xid, ddp->flags);
1013 return;
1014 }
1015
1016 /* set the flag to indicate this is programmed */
1017 if (test_and_set_bit(__I40E_FCOE_DDP_PROGRAMMED, &ddp->flags)) {
1018 dev_warn(&pf->pdev->dev,
1019 "DDP is already programmed for xid:%hx and ddp->flags:%lx:\n",
1020 ddp->xid, ddp->flags);
1021 return;
1022 }
1023
1024 /* Prepare the DDP context descriptor */
1025 ddp_desc = I40E_DDP_CONTEXT_DESC(tx_ring, i);
1026 i++;
1027 if (i == tx_ring->count)
1028 i = 0;
1029
1030 ddp_desc->type_cmd_foff_lsize =
1031 cpu_to_le64(I40E_TX_DESC_DTYPE_DDP_CTX |
1032 ((u64)I40E_FCOE_DDP_CTX_DESC_BSIZE_4K <<
1033 I40E_FCOE_DDP_CTX_QW1_CMD_SHIFT) |
1034 ((u64)ddp->firstoff <<
1035 I40E_FCOE_DDP_CTX_QW1_FOFF_SHIFT) |
1036 ((u64)ddp->lastsize <<
1037 I40E_FCOE_DDP_CTX_QW1_LSIZE_SHIFT));
1038 ddp_desc->rsvd = cpu_to_le64(0);
1039
1040 /* target mode needs last packet in the sequence */
1041 target_mode = test_bit(__I40E_FCOE_DDP_TARGET, &ddp->flags);
1042 if (target_mode)
1043 ddp_desc->type_cmd_foff_lsize |=
1044 cpu_to_le64(I40E_FCOE_DDP_CTX_DESC_LASTSEQH);
1045
1046 /* Prepare queue_context descriptor */
1047 queue_desc = I40E_QUEUE_CONTEXT_DESC(tx_ring, i++);
1048 if (i == tx_ring->count)
1049 i = 0;
1050 queue_desc->dmaindx_fbase = cpu_to_le64(ddp->xid | ((u64)ddp->udp));
1051 queue_desc->flen_tph = cpu_to_le64(ddp->list_len |
1052 ((u64)(I40E_FCOE_QUEUE_CTX_DESC_TPHRDESC |
1053 I40E_FCOE_QUEUE_CTX_DESC_TPHDATA) <<
1054 I40E_FCOE_QUEUE_CTX_QW1_TPH_SHIFT));
1055
1056 /* Prepare filter_context_desc */
1057 filter_desc = I40E_FILTER_CONTEXT_DESC(tx_ring, i);
1058 i++;
1059 if (i == tx_ring->count)
1060 i = 0;
1061
1062 fh = (struct fc_frame_header *)skb_transport_header(skb);
1063 filter_desc->param = cpu_to_le32(ntohl(fh->fh_parm_offset));
1064 filter_desc->seqn = cpu_to_le16(ntohs(fh->fh_seq_cnt));
1065 filter_desc->rsvd_dmaindx = cpu_to_le16(ddp->xid <<
1066 I40E_FCOE_FILTER_CTX_QW0_DMAINDX_SHIFT);
1067
1068 flags_rsvd_lanq = I40E_FCOE_FILTER_CTX_DESC_CTYP_DDP;
1069 flags_rsvd_lanq |= (u64)(target_mode ?
1070 I40E_FCOE_FILTER_CTX_DESC_ENODE_RSP :
1071 I40E_FCOE_FILTER_CTX_DESC_ENODE_INIT);
1072
1073 flags_rsvd_lanq |= (u64)((sof == FC_SOF_I2 || sof == FC_SOF_N2) ?
1074 I40E_FCOE_FILTER_CTX_DESC_FC_CLASS2 :
1075 I40E_FCOE_FILTER_CTX_DESC_FC_CLASS3);
1076
1077 flags_rsvd_lanq |= ((u64)skb->queue_mapping <<
1078 I40E_FCOE_FILTER_CTX_QW1_LANQINDX_SHIFT);
1079 filter_desc->flags_rsvd_lanq = cpu_to_le64(flags_rsvd_lanq);
1080
1081 /* By this time, all offload related descriptors has been programmed */
1082 tx_ring->next_to_use = i;
1083}
1084
1085/**
1086 * i40e_fcoe_invalidate_ddp - invalidates DDP in case of abort
1087 * @tx_ring: transmit ring for this packet
1088 * @skb: the packet associated w/ this DDP invalidation, i.e., ABTS
1089 * @ddp: the SW DDP context for this DDP
1090 *
1091 * Programs the Tx context descriptor to do DDP invalidation.
1092 **/
1093static void i40e_fcoe_invalidate_ddp(struct i40e_ring *tx_ring,
1094 struct sk_buff *skb,
1095 struct i40e_fcoe_ddp *ddp)
1096{
1097 struct i40e_tx_context_desc *context_desc;
1098 int i;
1099
1100 if (test_and_set_bit(__I40E_FCOE_DDP_ABORTED, &ddp->flags))
1101 return;
1102
1103 i = tx_ring->next_to_use;
1104 context_desc = I40E_TX_CTXTDESC(tx_ring, i);
1105 i++;
1106 if (i == tx_ring->count)
1107 i = 0;
1108
1109 context_desc->tunneling_params = cpu_to_le32(0);
1110 context_desc->l2tag2 = cpu_to_le16(0);
1111 context_desc->rsvd = cpu_to_le16(0);
1112 context_desc->type_cmd_tso_mss = cpu_to_le64(
1113 I40E_TX_DESC_DTYPE_FCOE_CTX |
1114 (I40E_FCOE_TX_CTX_DESC_OPCODE_DDP_CTX_INVL <<
1115 I40E_TXD_CTX_QW1_CMD_SHIFT) |
1116 (I40E_FCOE_TX_CTX_DESC_OPCODE_SINGLE_SEND <<
1117 I40E_TXD_CTX_QW1_CMD_SHIFT));
1118 tx_ring->next_to_use = i;
1119}
1120
1121/**
1122 * i40e_fcoe_handle_ddp - check we should setup or invalidate DDP
1123 * @tx_ring: transmit ring for this packet
1124 * @skb: the packet to be sent out
1125 * @sof: the SOF to indicate class of service
1126 *
1127 * Determine if it is ABTS/READ/XFER_RDY, and finds out if there is
1128 * a matching SW DDP context for this command. DDP is applicable
1129 * only in case of READ if initiator or WRITE in case of
1130 * responder (via checking XFER_RDY). In case this is an ABTS, send
1131 * just invalidate the context.
1132 **/
1133static void i40e_fcoe_handle_ddp(struct i40e_ring *tx_ring,
1134 struct sk_buff *skb, u8 sof)
1135{
1136 struct i40e_pf *pf = tx_ring->vsi->back;
1137 struct i40e_fcoe *fcoe = &pf->fcoe;
1138 struct fc_frame_header *fh;
1139 struct i40e_fcoe_ddp *ddp;
1140 u32 f_ctl;
1141 u8 r_ctl;
1142 u16 xid;
1143
1144 fh = (struct fc_frame_header *)skb_transport_header(skb);
1145 f_ctl = ntoh24(fh->fh_f_ctl);
1146 r_ctl = fh->fh_r_ctl;
1147 ddp = NULL;
1148
1149 if ((r_ctl == FC_RCTL_DD_DATA_DESC) && (f_ctl & FC_FC_EX_CTX)) {
1150 /* exchange responder? if so, XFER_RDY for write */
1151 xid = ntohs(fh->fh_rx_id);
1152 if (i40e_fcoe_xid_is_valid(xid)) {
1153 ddp = &fcoe->ddp[xid];
1154 if ((ddp->xid == xid) &&
1155 (test_bit(__I40E_FCOE_DDP_TARGET, &ddp->flags)))
1156 i40e_fcoe_program_ddp(tx_ring, skb, ddp, sof);
1157 }
1158 } else if (r_ctl == FC_RCTL_DD_UNSOL_CMD) {
1159 /* exchange originator, check READ cmd */
1160 xid = ntohs(fh->fh_ox_id);
1161 if (i40e_fcoe_xid_is_valid(xid)) {
1162 ddp = &fcoe->ddp[xid];
1163 if ((ddp->xid == xid) &&
1164 (!test_bit(__I40E_FCOE_DDP_TARGET, &ddp->flags)))
1165 i40e_fcoe_program_ddp(tx_ring, skb, ddp, sof);
1166 }
1167 } else if (r_ctl == FC_RCTL_BA_ABTS) {
1168 /* exchange originator, check ABTS */
1169 xid = ntohs(fh->fh_ox_id);
1170 if (i40e_fcoe_xid_is_valid(xid)) {
1171 ddp = &fcoe->ddp[xid];
1172 if ((ddp->xid == xid) &&
1173 (!test_bit(__I40E_FCOE_DDP_TARGET, &ddp->flags)))
1174 i40e_fcoe_invalidate_ddp(tx_ring, skb, ddp);
1175 }
1176 }
1177}
1178
1179/**
1180 * i40e_fcoe_tso - set up FCoE TSO
1181 * @tx_ring: ring to send buffer on
1182 * @skb: send buffer
1183 * @tx_flags: collected send information
1184 * @hdr_len: the tso header length
1185 * @sof: the SOF to indicate class of service
1186 *
1187 * Note must already have sof checked to be either class 2 or class 3 before
1188 * calling this function.
1189 *
1190 * Returns 1 to indicate sequence segmentation offload is properly setup
1191 * or returns 0 to indicate no tso is needed, otherwise returns error
1192 * code to drop the frame.
1193 **/
1194static int i40e_fcoe_tso(struct i40e_ring *tx_ring,
1195 struct sk_buff *skb,
1196 u32 tx_flags, u8 *hdr_len, u8 sof)
1197{
1198 struct i40e_tx_context_desc *context_desc;
1199 u32 cd_type, cd_cmd, cd_tso_len, cd_mss;
1200 struct fc_frame_header *fh;
1201 u64 cd_type_cmd_tso_mss;
1202
1203 /* must match gso type as FCoE */
1204 if (!skb_is_gso(skb))
1205 return 0;
1206
1207 /* is it the expected gso type for FCoE ?*/
1208 if (skb_shinfo(skb)->gso_type != SKB_GSO_FCOE) {
1209 netdev_err(skb->dev,
1210 "wrong gso type %d:expecting SKB_GSO_FCOE\n",
1211 skb_shinfo(skb)->gso_type);
1212 return -EINVAL;
1213 }
1214
1215 /* header and trailer are inserted by hw */
1216 *hdr_len = skb_transport_offset(skb) + sizeof(struct fc_frame_header) +
1217 sizeof(struct fcoe_crc_eof);
1218
1219 /* check sof to decide a class 2 or 3 TSO */
1220 if (likely(i40e_fcoe_sof_is_class3(sof)))
1221 cd_cmd = I40E_FCOE_TX_CTX_DESC_OPCODE_TSO_FC_CLASS3;
1222 else
1223 cd_cmd = I40E_FCOE_TX_CTX_DESC_OPCODE_TSO_FC_CLASS2;
1224
1225 /* param field valid? */
1226 fh = (struct fc_frame_header *)skb_transport_header(skb);
1227 if (fh->fh_f_ctl[2] & FC_FC_REL_OFF)
1228 cd_cmd |= I40E_FCOE_TX_CTX_DESC_RELOFF;
1229
1230 /* fill the field values */
1231 cd_type = I40E_TX_DESC_DTYPE_FCOE_CTX;
1232 cd_tso_len = skb->len - *hdr_len;
1233 cd_mss = skb_shinfo(skb)->gso_size;
1234 cd_type_cmd_tso_mss =
1235 ((u64)cd_type << I40E_TXD_CTX_QW1_DTYPE_SHIFT) |
1236 ((u64)cd_cmd << I40E_TXD_CTX_QW1_CMD_SHIFT) |
1237 ((u64)cd_tso_len << I40E_TXD_CTX_QW1_TSO_LEN_SHIFT) |
1238 ((u64)cd_mss << I40E_TXD_CTX_QW1_MSS_SHIFT);
1239
1240 /* grab the next descriptor */
1241 context_desc = I40E_TX_CTXTDESC(tx_ring, tx_ring->next_to_use);
1242 tx_ring->next_to_use++;
1243 if (tx_ring->next_to_use == tx_ring->count)
1244 tx_ring->next_to_use = 0;
1245
1246 context_desc->tunneling_params = 0;
1247 context_desc->l2tag2 = cpu_to_le16((tx_flags & I40E_TX_FLAGS_VLAN_MASK)
1248 >> I40E_TX_FLAGS_VLAN_SHIFT);
1249 context_desc->type_cmd_tso_mss = cpu_to_le64(cd_type_cmd_tso_mss);
1250
1251 return 1;
1252}
1253
1254/**
1255 * i40e_fcoe_tx_map - build the tx descriptor
1256 * @tx_ring: ring to send buffer on
1257 * @skb: send buffer
1258 * @first: first buffer info buffer to use
1259 * @tx_flags: collected send information
1260 * @hdr_len: ptr to the size of the packet header
1261 * @eof: the frame eof value
1262 *
1263 * Note, for FCoE, sof and eof are already checked
1264 **/
1265static void i40e_fcoe_tx_map(struct i40e_ring *tx_ring,
1266 struct sk_buff *skb,
1267 struct i40e_tx_buffer *first,
1268 u32 tx_flags, u8 hdr_len, u8 eof)
1269{
1270 u32 td_offset = 0;
1271 u32 td_cmd = 0;
1272 u32 maclen;
1273
1274 /* insert CRC */
1275 td_cmd = I40E_TX_DESC_CMD_ICRC;
1276
1277 /* setup MACLEN */
1278 maclen = skb_network_offset(skb);
1279 if (tx_flags & I40E_TX_FLAGS_SW_VLAN)
1280 maclen += sizeof(struct vlan_hdr);
1281
1282 if (skb->protocol == htons(ETH_P_FCOE)) {
1283 /* for FCoE, maclen should exclude ether type */
1284 maclen -= 2;
1285 /* setup type as FCoE and EOF insertion */
1286 td_cmd |= (I40E_TX_DESC_CMD_FCOET | i40e_fcoe_ctxt_eof(eof));
1287 /* setup FCoELEN and FCLEN */
1288 td_offset |= ((((sizeof(struct fcoe_hdr) + 2) >> 2) <<
1289 I40E_TX_DESC_LENGTH_IPLEN_SHIFT) |
1290 ((sizeof(struct fc_frame_header) >> 2) <<
1291 I40E_TX_DESC_LENGTH_L4_FC_LEN_SHIFT));
1292 /* trim to exclude trailer */
1293 pskb_trim(skb, skb->len - sizeof(struct fcoe_crc_eof));
1294 }
1295
1296 /* MACLEN is ether header length in words not bytes */
1297 td_offset |= (maclen >> 1) << I40E_TX_DESC_LENGTH_MACLEN_SHIFT;
1298
1299 i40e_tx_map(tx_ring, skb, first, tx_flags, hdr_len, td_cmd, td_offset);
1300}
1301
1302/**
1303 * i40e_fcoe_set_skb_header - adjust skb header point for FIP/FCoE/FC
1304 * @skb: the skb to be adjusted
1305 *
1306 * Returns true if this skb is a FCoE/FIP or VLAN carried FCoE/FIP and then
1307 * adjusts the skb header pointers correspondingly. Otherwise, returns false.
1308 **/
1309static inline int i40e_fcoe_set_skb_header(struct sk_buff *skb)
1310{
1311 __be16 protocol = skb->protocol;
1312
1313 skb_reset_mac_header(skb);
1314 skb->mac_len = sizeof(struct ethhdr);
1315 if (protocol == htons(ETH_P_8021Q)) {
1316 struct vlan_ethhdr *veth = (struct vlan_ethhdr *)eth_hdr(skb);
1317
1318 protocol = veth->h_vlan_encapsulated_proto;
1319 skb->mac_len += sizeof(struct vlan_hdr);
1320 }
1321
1322 /* FCoE or FIP only */
1323 if ((protocol != htons(ETH_P_FIP)) &&
1324 (protocol != htons(ETH_P_FCOE)))
1325 return -EINVAL;
1326
1327 /* set header to L2 of FCoE/FIP */
1328 skb_set_network_header(skb, skb->mac_len);
1329 if (protocol == htons(ETH_P_FIP))
1330 return 0;
1331
1332 /* set header to L3 of FC */
1333 skb_set_transport_header(skb, skb->mac_len + sizeof(struct fcoe_hdr));
1334 return 0;
1335}
1336
1337/**
1338 * i40e_fcoe_xmit_frame - transmit buffer
1339 * @skb: send buffer
1340 * @netdev: the fcoe netdev
1341 *
1342 * Returns 0 if sent, else an error code
1343 **/
1344static netdev_tx_t i40e_fcoe_xmit_frame(struct sk_buff *skb,
1345 struct net_device *netdev)
1346{
1347 struct i40e_netdev_priv *np = netdev_priv(skb->dev);
1348 struct i40e_vsi *vsi = np->vsi;
1349 struct i40e_ring *tx_ring = vsi->tx_rings[skb->queue_mapping];
1350 struct i40e_tx_buffer *first;
1351 u32 tx_flags = 0;
1352 int fso, count;
1353 u8 hdr_len = 0;
1354 u8 sof = 0;
1355 u8 eof = 0;
1356
1357 if (i40e_fcoe_set_skb_header(skb))
1358 goto out_drop;
1359
1360 count = i40e_xmit_descriptor_count(skb);
1361 if (i40e_chk_linearize(skb, count)) {
1362 if (__skb_linearize(skb))
1363 goto out_drop;
1364 count = i40e_txd_use_count(skb->len);
1365 tx_ring->tx_stats.tx_linearize++;
1366 }
1367
1368 /* need: 1 descriptor per page * PAGE_SIZE/I40E_MAX_DATA_PER_TXD,
1369 * + 1 desc for skb_head_len/I40E_MAX_DATA_PER_TXD,
1370 * + 4 desc gap to avoid the cache line where head is,
1371 * + 1 desc for context descriptor,
1372 * otherwise try next time
1373 */
1374 if (i40e_maybe_stop_tx(tx_ring, count + 4 + 1)) {
1375 tx_ring->tx_stats.tx_busy++;
1376 return NETDEV_TX_BUSY;
1377 }
1378
1379 /* prepare the xmit flags */
1380 if (i40e_tx_prepare_vlan_flags(skb, tx_ring, &tx_flags))
1381 goto out_drop;
1382
1383 /* record the location of the first descriptor for this packet */
1384 first = &tx_ring->tx_bi[tx_ring->next_to_use];
1385
1386 /* FIP is a regular L2 traffic w/o offload */
1387 if (skb->protocol == htons(ETH_P_FIP))
1388 goto out_send;
1389
1390 /* check sof and eof, only supports FC Class 2 or 3 */
1391 if (i40e_fcoe_fc_sof(skb, &sof) || i40e_fcoe_fc_eof(skb, &eof)) {
1392 netdev_err(netdev, "SOF/EOF error:%02x - %02x\n", sof, eof);
1393 goto out_drop;
1394 }
1395
1396 /* always do FCCRC for FCoE */
1397 tx_flags |= I40E_TX_FLAGS_FCCRC;
1398
1399 /* check we should do sequence offload */
1400 fso = i40e_fcoe_tso(tx_ring, skb, tx_flags, &hdr_len, sof);
1401 if (fso < 0)
1402 goto out_drop;
1403 else if (fso)
1404 tx_flags |= I40E_TX_FLAGS_FSO;
1405 else
1406 i40e_fcoe_handle_ddp(tx_ring, skb, sof);
1407
1408out_send:
1409 /* send out the packet */
1410 i40e_fcoe_tx_map(tx_ring, skb, first, tx_flags, hdr_len, eof);
1411
1412 i40e_maybe_stop_tx(tx_ring, DESC_NEEDED);
1413 return NETDEV_TX_OK;
1414
1415out_drop:
1416 dev_kfree_skb_any(skb);
1417 return NETDEV_TX_OK;
1418}
1419
1420/**
1421 * i40e_fcoe_change_mtu - NDO callback to change the Maximum Transfer Unit
1422 * @netdev: network interface device structure
1423 * @new_mtu: new value for maximum frame size
1424 *
1425 * Returns error as operation not permitted
1426 *
1427 **/
1428static int i40e_fcoe_change_mtu(struct net_device *netdev, int new_mtu)
1429{
1430 netdev_warn(netdev, "MTU change is not supported on FCoE interfaces\n");
1431 return -EPERM;
1432}
1433
1434/**
1435 * i40e_fcoe_set_features - set the netdev feature flags
1436 * @netdev: ptr to the netdev being adjusted
1437 * @features: the feature set that the stack is suggesting
1438 *
1439 **/
1440static int i40e_fcoe_set_features(struct net_device *netdev,
1441 netdev_features_t features)
1442{
1443 struct i40e_netdev_priv *np = netdev_priv(netdev);
1444 struct i40e_vsi *vsi = np->vsi;
1445
1446 if (features & NETIF_F_HW_VLAN_CTAG_RX)
1447 i40e_vlan_stripping_enable(vsi);
1448 else
1449 i40e_vlan_stripping_disable(vsi);
1450
1451 return 0;
1452}
1453
1454static const struct net_device_ops i40e_fcoe_netdev_ops = {
1455 .ndo_open = i40e_open,
1456 .ndo_stop = i40e_close,
1457 .ndo_get_stats64 = i40e_get_netdev_stats_struct,
1458 .ndo_set_rx_mode = i40e_set_rx_mode,
1459 .ndo_validate_addr = eth_validate_addr,
1460 .ndo_set_mac_address = i40e_set_mac,
1461 .ndo_change_mtu = i40e_fcoe_change_mtu,
1462 .ndo_do_ioctl = i40e_ioctl,
1463 .ndo_tx_timeout = i40e_tx_timeout,
1464 .ndo_vlan_rx_add_vid = i40e_vlan_rx_add_vid,
1465 .ndo_vlan_rx_kill_vid = i40e_vlan_rx_kill_vid,
1466 .ndo_setup_tc = __i40e_setup_tc,
1467
1468#ifdef CONFIG_NET_POLL_CONTROLLER
1469 .ndo_poll_controller = i40e_netpoll,
1470#endif
1471 .ndo_start_xmit = i40e_fcoe_xmit_frame,
1472 .ndo_fcoe_enable = i40e_fcoe_enable,
1473 .ndo_fcoe_disable = i40e_fcoe_disable,
1474 .ndo_fcoe_ddp_setup = i40e_fcoe_ddp_get,
1475 .ndo_fcoe_ddp_done = i40e_fcoe_ddp_put,
1476 .ndo_fcoe_ddp_target = i40e_fcoe_ddp_target,
1477 .ndo_set_features = i40e_fcoe_set_features,
1478};
1479
1480/* fcoe network device type */
1481static struct device_type fcoe_netdev_type = {
1482 .name = "fcoe",
1483};
1484
1485/**
1486 * i40e_fcoe_config_netdev - prepares the VSI context for creating a FCoE VSI
1487 * @vsi: pointer to the associated VSI struct
1488 * @ctxt: pointer to the associated VSI context to be passed to HW
1489 *
1490 * Returns 0 on success or < 0 on error
1491 **/
1492void i40e_fcoe_config_netdev(struct net_device *netdev, struct i40e_vsi *vsi)
1493{
1494 struct i40e_hw *hw = &vsi->back->hw;
1495 struct i40e_pf *pf = vsi->back;
1496
1497 if (vsi->type != I40E_VSI_FCOE)
1498 return;
1499
1500 netdev->features = (NETIF_F_HW_VLAN_CTAG_TX |
1501 NETIF_F_HW_VLAN_CTAG_RX |
1502 NETIF_F_HW_VLAN_CTAG_FILTER);
1503
1504 netdev->vlan_features = netdev->features;
1505 netdev->vlan_features &= ~(NETIF_F_HW_VLAN_CTAG_TX |
1506 NETIF_F_HW_VLAN_CTAG_RX |
1507 NETIF_F_HW_VLAN_CTAG_FILTER);
1508 netdev->fcoe_ddp_xid = I40E_FCOE_DDP_MAX - 1;
1509 netdev->features |= NETIF_F_ALL_FCOE;
1510 netdev->vlan_features |= NETIF_F_ALL_FCOE;
1511 netdev->hw_features |= netdev->features;
1512 netdev->priv_flags |= IFF_UNICAST_FLT;
1513 netdev->priv_flags |= IFF_SUPP_NOFCS;
1514
1515 strlcpy(netdev->name, "fcoe%d", IFNAMSIZ-1);
1516 netdev->mtu = FCOE_MTU;
1517 SET_NETDEV_DEV(netdev, &pf->pdev->dev);
1518 SET_NETDEV_DEVTYPE(netdev, &fcoe_netdev_type);
1519 /* set different dev_port value 1 for FCoE netdev than the default
1520 * zero dev_port value for PF netdev, this helps biosdevname user
1521 * tool to differentiate them correctly while both attached to the
1522 * same PCI function.
1523 */
1524 netdev->dev_port = 1;
1525 spin_lock_bh(&vsi->mac_filter_hash_lock);
1526 i40e_add_filter(vsi, hw->mac.san_addr, 0);
1527 i40e_add_filter(vsi, (u8[6]) FC_FCOE_FLOGI_MAC, 0);
1528 i40e_add_filter(vsi, FIP_ALL_FCOE_MACS, 0);
1529 i40e_add_filter(vsi, FIP_ALL_ENODE_MACS, 0);
1530 spin_unlock_bh(&vsi->mac_filter_hash_lock);
1531
1532 /* use san mac */
1533 ether_addr_copy(netdev->dev_addr, hw->mac.san_addr);
1534 ether_addr_copy(netdev->perm_addr, hw->mac.san_addr);
1535 /* fcoe netdev ops */
1536 netdev->netdev_ops = &i40e_fcoe_netdev_ops;
1537}
1538
1539/**
1540 * i40e_fcoe_vsi_setup - allocate and set up FCoE VSI
1541 * @pf: the PF that VSI is associated with
1542 *
1543 **/
1544void i40e_fcoe_vsi_setup(struct i40e_pf *pf)
1545{
1546 struct i40e_vsi *vsi;
1547 u16 seid;
1548 int i;
1549
1550 if (!(pf->flags & I40E_FLAG_FCOE_ENABLED))
1551 return;
1552
1553 for (i = 0; i < pf->num_alloc_vsi; i++) {
1554 vsi = pf->vsi[i];
1555 if (vsi && vsi->type == I40E_VSI_FCOE) {
1556 dev_warn(&pf->pdev->dev,
1557 "FCoE VSI already created\n");
1558 return;
1559 }
1560 }
1561
1562 seid = pf->vsi[pf->lan_vsi]->seid;
1563 vsi = i40e_vsi_setup(pf, I40E_VSI_FCOE, seid, 0);
1564 if (vsi) {
1565 dev_dbg(&pf->pdev->dev,
1566 "Successfully created FCoE VSI seid %d id %d uplink_seid %d PF seid %d\n",
1567 vsi->seid, vsi->id, vsi->uplink_seid, seid);
1568 } else {
1569 dev_info(&pf->pdev->dev, "Failed to create FCoE VSI\n");
1570 }
1571}
diff --git a/drivers/net/ethernet/intel/i40e/i40e_fcoe.h b/drivers/net/ethernet/intel/i40e/i40e_fcoe.h
deleted file mode 100644
index a93174ddeaba..000000000000
--- a/drivers/net/ethernet/intel/i40e/i40e_fcoe.h
+++ /dev/null
@@ -1,127 +0,0 @@
1/*******************************************************************************
2 *
3 * Intel Ethernet Controller XL710 Family Linux Driver
4 * Copyright(c) 2013 - 2014 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
23 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24 *
25 ******************************************************************************/
26
27#ifndef _I40E_FCOE_H_
28#define _I40E_FCOE_H_
29
30/* FCoE HW context helper macros */
31#define I40E_DDP_CONTEXT_DESC(R, i) \
32 (&(((struct i40e_fcoe_ddp_context_desc *)((R)->desc))[i]))
33
34#define I40E_QUEUE_CONTEXT_DESC(R, i) \
35 (&(((struct i40e_fcoe_queue_context_desc *)((R)->desc))[i]))
36
37#define I40E_FILTER_CONTEXT_DESC(R, i) \
38 (&(((struct i40e_fcoe_filter_context_desc *)((R)->desc))[i]))
39
40/* receive queue descriptor filter status for FCoE */
41#define I40E_RX_DESC_FLTSTAT_FCMASK 0x3
42#define I40E_RX_DESC_FLTSTAT_NOMTCH 0x0 /* no ddp context match */
43#define I40E_RX_DESC_FLTSTAT_NODDP 0x1 /* no ddp due to error */
44#define I40E_RX_DESC_FLTSTAT_DDP 0x2 /* DDPed payload, post header */
45#define I40E_RX_DESC_FLTSTAT_FCPRSP 0x3 /* FCP_RSP */
46
47/* receive queue descriptor error codes for FCoE */
48#define I40E_RX_DESC_FCOE_ERROR_MASK \
49 (I40E_RX_DESC_ERROR_L3L4E_PROT | \
50 I40E_RX_DESC_ERROR_L3L4E_FC | \
51 I40E_RX_DESC_ERROR_L3L4E_DMAC_ERR | \
52 I40E_RX_DESC_ERROR_L3L4E_DMAC_WARN)
53
54/* receive queue descriptor programming error */
55#define I40E_RX_PROG_FCOE_ERROR_TBL_FULL(e) \
56 (((e) >> I40E_RX_PROG_STATUS_DESC_FCOE_TBL_FULL_SHIFT) & 0x1)
57
58#define I40E_RX_PROG_FCOE_ERROR_CONFLICT(e) \
59 (((e) >> I40E_RX_PROG_STATUS_DESC_FCOE_CONFLICT_SHIFT) & 0x1)
60
61#define I40E_RX_PROG_FCOE_ERROR_TBL_FULL_BIT \
62 BIT(I40E_RX_PROG_STATUS_DESC_FCOE_TBL_FULL_SHIFT)
63#define I40E_RX_PROG_FCOE_ERROR_CONFLICT_BIT \
64 BIT(I40E_RX_PROG_STATUS_DESC_FCOE_CONFLICT_SHIFT)
65
66#define I40E_RX_PROG_FCOE_ERROR_INVLFAIL(e) \
67 I40E_RX_PROG_FCOE_ERROR_CONFLICT(e)
68#define I40E_RX_PROG_FCOE_ERROR_INVLFAIL_BIT \
69 I40E_RX_PROG_FCOE_ERROR_CONFLICT_BIT
70
71/* FCoE DDP related definitions */
72#define I40E_FCOE_MIN_XID 0x0000 /* the min xid supported by fcoe_sw */
73#define I40E_FCOE_MAX_XID 0x0FFF /* the max xid supported by fcoe_sw */
74#define I40E_FCOE_DDP_BUFFCNT_MAX 512 /* 9 bits bufcnt */
75#define I40E_FCOE_DDP_PTR_ALIGN 16
76#define I40E_FCOE_DDP_PTR_MAX (I40E_FCOE_DDP_BUFFCNT_MAX * sizeof(dma_addr_t))
77#define I40E_FCOE_DDP_BUF_MIN 4096
78#define I40E_FCOE_DDP_MAX 2048
79#define I40E_FCOE_FILTER_CTX_QW1_PCTYPE_SHIFT 8
80
81/* supported netdev features for FCoE */
82#define I40E_FCOE_NETIF_FEATURES (NETIF_F_ALL_FCOE | \
83 NETIF_F_HW_VLAN_CTAG_TX | \
84 NETIF_F_HW_VLAN_CTAG_RX | \
85 NETIF_F_HW_VLAN_CTAG_FILTER)
86
87/* DDP context flags */
88enum i40e_fcoe_ddp_flags {
89 __I40E_FCOE_DDP_NONE = 1,
90 __I40E_FCOE_DDP_TARGET,
91 __I40E_FCOE_DDP_INITALIZED,
92 __I40E_FCOE_DDP_PROGRAMMED,
93 __I40E_FCOE_DDP_DONE,
94 __I40E_FCOE_DDP_ABORTED,
95 __I40E_FCOE_DDP_UNMAPPED,
96};
97
98/* DDP SW context struct */
99struct i40e_fcoe_ddp {
100 int len;
101 u16 xid;
102 u16 firstoff;
103 u16 lastsize;
104 u16 list_len;
105 u8 fcerr;
106 u8 prerr;
107 unsigned long flags;
108 unsigned int sgc;
109 struct scatterlist *sgl;
110 dma_addr_t udp;
111 u64 *udl;
112 struct dma_pool *pool;
113
114};
115
116struct i40e_fcoe_ddp_pool {
117 struct dma_pool *pool;
118};
119
120struct i40e_fcoe {
121 unsigned long mode;
122 atomic_t refcnt;
123 struct i40e_fcoe_ddp_pool __percpu *ddp_pool;
124 struct i40e_fcoe_ddp ddp[I40E_FCOE_DDP_MAX];
125};
126
127#endif /* _I40E_FCOE_H_ */
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index e31adbc75f9c..4a4401c61089 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -69,12 +69,6 @@ static int i40e_reset(struct i40e_pf *pf);
69static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired); 69static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired);
70static void i40e_fdir_sb_setup(struct i40e_pf *pf); 70static void i40e_fdir_sb_setup(struct i40e_pf *pf);
71static int i40e_veb_get_bw_info(struct i40e_veb *veb); 71static int i40e_veb_get_bw_info(struct i40e_veb *veb);
72static int i40e_add_del_cloud_filter(struct i40e_vsi *vsi,
73 struct i40e_cloud_filter *filter,
74 bool add);
75static int i40e_add_del_cloud_filter_big_buf(struct i40e_vsi *vsi,
76 struct i40e_cloud_filter *filter,
77 bool add);
78static int i40e_get_capabilities(struct i40e_pf *pf, 72static int i40e_get_capabilities(struct i40e_pf *pf,
79 enum i40e_admin_queue_opc list_type); 73 enum i40e_admin_queue_opc list_type);
80 74
@@ -215,8 +209,8 @@ static int i40e_get_lump(struct i40e_pf *pf, struct i40e_lump_tracking *pile,
215 209
216 if (!pile || needed == 0 || id >= I40E_PILE_VALID_BIT) { 210 if (!pile || needed == 0 || id >= I40E_PILE_VALID_BIT) {
217 dev_info(&pf->pdev->dev, 211 dev_info(&pf->pdev->dev,
218 "param err: pile=%p needed=%d id=0x%04x\n", 212 "param err: pile=%s needed=%d id=0x%04x\n",
219 pile, needed, id); 213 pile ? "<valid>" : "<null>", needed, id);
220 return -EINVAL; 214 return -EINVAL;
221 } 215 }
222 216
@@ -1380,14 +1374,7 @@ struct i40e_mac_filter *i40e_add_filter(struct i40e_vsi *vsi,
1380 1374
1381 ether_addr_copy(f->macaddr, macaddr); 1375 ether_addr_copy(f->macaddr, macaddr);
1382 f->vlan = vlan; 1376 f->vlan = vlan;
1383 /* If we're in overflow promisc mode, set the state directly 1377 f->state = I40E_FILTER_NEW;
1384 * to failed, so we don't bother to try sending the filter
1385 * to the hardware.
1386 */
1387 if (test_bit(__I40E_VSI_OVERFLOW_PROMISC, vsi->state))
1388 f->state = I40E_FILTER_FAILED;
1389 else
1390 f->state = I40E_FILTER_NEW;
1391 INIT_HLIST_NODE(&f->hlist); 1378 INIT_HLIST_NODE(&f->hlist);
1392 1379
1393 key = i40e_addr_to_hkey(macaddr); 1380 key = i40e_addr_to_hkey(macaddr);
@@ -2116,17 +2103,16 @@ void i40e_aqc_del_filters(struct i40e_vsi *vsi, const char *vsi_name,
2116 * @list: the list of filters to send to firmware 2103 * @list: the list of filters to send to firmware
2117 * @add_head: Position in the add hlist 2104 * @add_head: Position in the add hlist
2118 * @num_add: the number of filters to add 2105 * @num_add: the number of filters to add
2119 * @promisc_change: set to true on exit if promiscuous mode was forced on
2120 * 2106 *
2121 * Send a request to firmware via AdminQ to add a chunk of filters. Will set 2107 * Send a request to firmware via AdminQ to add a chunk of filters. Will set
2122 * promisc_changed to true if the firmware has run out of space for more 2108 * __I40E_VSI_OVERFLOW_PROMISC bit in vsi->state if the firmware has run out of
2123 * filters. 2109 * space for more filters.
2124 */ 2110 */
2125static 2111static
2126void i40e_aqc_add_filters(struct i40e_vsi *vsi, const char *vsi_name, 2112void i40e_aqc_add_filters(struct i40e_vsi *vsi, const char *vsi_name,
2127 struct i40e_aqc_add_macvlan_element_data *list, 2113 struct i40e_aqc_add_macvlan_element_data *list,
2128 struct i40e_new_mac_filter *add_head, 2114 struct i40e_new_mac_filter *add_head,
2129 int num_add, bool *promisc_changed) 2115 int num_add)
2130{ 2116{
2131 struct i40e_hw *hw = &vsi->back->hw; 2117 struct i40e_hw *hw = &vsi->back->hw;
2132 int aq_err, fcnt; 2118 int aq_err, fcnt;
@@ -2136,7 +2122,6 @@ void i40e_aqc_add_filters(struct i40e_vsi *vsi, const char *vsi_name,
2136 fcnt = i40e_update_filter_state(num_add, list, add_head); 2122 fcnt = i40e_update_filter_state(num_add, list, add_head);
2137 2123
2138 if (fcnt != num_add) { 2124 if (fcnt != num_add) {
2139 *promisc_changed = true;
2140 set_bit(__I40E_VSI_OVERFLOW_PROMISC, vsi->state); 2125 set_bit(__I40E_VSI_OVERFLOW_PROMISC, vsi->state);
2141 dev_warn(&vsi->back->pdev->dev, 2126 dev_warn(&vsi->back->pdev->dev,
2142 "Error %s adding RX filters on %s, promiscuous mode forced on\n", 2127 "Error %s adding RX filters on %s, promiscuous mode forced on\n",
@@ -2177,11 +2162,13 @@ i40e_aqc_broadcast_filter(struct i40e_vsi *vsi, const char *vsi_name,
2177 NULL); 2162 NULL);
2178 } 2163 }
2179 2164
2180 if (aq_ret) 2165 if (aq_ret) {
2166 set_bit(__I40E_VSI_OVERFLOW_PROMISC, vsi->state);
2181 dev_warn(&vsi->back->pdev->dev, 2167 dev_warn(&vsi->back->pdev->dev,
2182 "Error %s setting broadcast promiscuous mode on %s\n", 2168 "Error %s, forcing overflow promiscuous on %s\n",
2183 i40e_aq_str(hw, hw->aq.asq_last_status), 2169 i40e_aq_str(hw, hw->aq.asq_last_status),
2184 vsi_name); 2170 vsi_name);
2171 }
2185 2172
2186 return aq_ret; 2173 return aq_ret;
2187} 2174}
@@ -2267,9 +2254,9 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
2267 struct i40e_mac_filter *f; 2254 struct i40e_mac_filter *f;
2268 struct i40e_new_mac_filter *new, *add_head = NULL; 2255 struct i40e_new_mac_filter *new, *add_head = NULL;
2269 struct i40e_hw *hw = &vsi->back->hw; 2256 struct i40e_hw *hw = &vsi->back->hw;
2257 bool old_overflow, new_overflow;
2270 unsigned int failed_filters = 0; 2258 unsigned int failed_filters = 0;
2271 unsigned int vlan_filters = 0; 2259 unsigned int vlan_filters = 0;
2272 bool promisc_changed = false;
2273 char vsi_name[16] = "PF"; 2260 char vsi_name[16] = "PF";
2274 int filter_list_len = 0; 2261 int filter_list_len = 0;
2275 i40e_status aq_ret = 0; 2262 i40e_status aq_ret = 0;
@@ -2291,6 +2278,8 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
2291 usleep_range(1000, 2000); 2278 usleep_range(1000, 2000);
2292 pf = vsi->back; 2279 pf = vsi->back;
2293 2280
2281 old_overflow = test_bit(__I40E_VSI_OVERFLOW_PROMISC, vsi->state);
2282
2294 if (vsi->netdev) { 2283 if (vsi->netdev) {
2295 changed_flags = vsi->current_netdev_flags ^ vsi->netdev->flags; 2284 changed_flags = vsi->current_netdev_flags ^ vsi->netdev->flags;
2296 vsi->current_netdev_flags = vsi->netdev->flags; 2285 vsi->current_netdev_flags = vsi->netdev->flags;
@@ -2423,12 +2412,6 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
2423 2412
2424 num_add = 0; 2413 num_add = 0;
2425 hlist_for_each_entry_safe(new, h, &tmp_add_list, hlist) { 2414 hlist_for_each_entry_safe(new, h, &tmp_add_list, hlist) {
2426 if (test_bit(__I40E_VSI_OVERFLOW_PROMISC,
2427 vsi->state)) {
2428 new->state = I40E_FILTER_FAILED;
2429 continue;
2430 }
2431
2432 /* handle broadcast filters by updating the broadcast 2415 /* handle broadcast filters by updating the broadcast
2433 * promiscuous flag instead of adding a MAC filter. 2416 * promiscuous flag instead of adding a MAC filter.
2434 */ 2417 */
@@ -2464,15 +2447,14 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
2464 /* flush a full buffer */ 2447 /* flush a full buffer */
2465 if (num_add == filter_list_len) { 2448 if (num_add == filter_list_len) {
2466 i40e_aqc_add_filters(vsi, vsi_name, add_list, 2449 i40e_aqc_add_filters(vsi, vsi_name, add_list,
2467 add_head, num_add, 2450 add_head, num_add);
2468 &promisc_changed);
2469 memset(add_list, 0, list_size); 2451 memset(add_list, 0, list_size);
2470 num_add = 0; 2452 num_add = 0;
2471 } 2453 }
2472 } 2454 }
2473 if (num_add) { 2455 if (num_add) {
2474 i40e_aqc_add_filters(vsi, vsi_name, add_list, add_head, 2456 i40e_aqc_add_filters(vsi, vsi_name, add_list, add_head,
2475 num_add, &promisc_changed); 2457 num_add);
2476 } 2458 }
2477 /* Now move all of the filters from the temp add list back to 2459 /* Now move all of the filters from the temp add list back to
2478 * the VSI's list. 2460 * the VSI's list.
@@ -2501,24 +2483,16 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
2501 } 2483 }
2502 spin_unlock_bh(&vsi->mac_filter_hash_lock); 2484 spin_unlock_bh(&vsi->mac_filter_hash_lock);
2503 2485
2504 /* If promiscuous mode has changed, we need to calculate a new
2505 * threshold for when we are safe to exit
2506 */
2507 if (promisc_changed)
2508 vsi->promisc_threshold = (vsi->active_filters * 3) / 4;
2509
2510 /* Check if we are able to exit overflow promiscuous mode. We can 2486 /* Check if we are able to exit overflow promiscuous mode. We can
2511 * safely exit if we didn't just enter, we no longer have any failed 2487 * safely exit if we didn't just enter, we no longer have any failed
2512 * filters, and we have reduced filters below the threshold value. 2488 * filters, and we have reduced filters below the threshold value.
2513 */ 2489 */
2514 if (test_bit(__I40E_VSI_OVERFLOW_PROMISC, vsi->state) && 2490 if (old_overflow && !failed_filters &&
2515 !promisc_changed && !failed_filters && 2491 vsi->active_filters < vsi->promisc_threshold) {
2516 (vsi->active_filters < vsi->promisc_threshold)) {
2517 dev_info(&pf->pdev->dev, 2492 dev_info(&pf->pdev->dev,
2518 "filter logjam cleared on %s, leaving overflow promiscuous mode\n", 2493 "filter logjam cleared on %s, leaving overflow promiscuous mode\n",
2519 vsi_name); 2494 vsi_name);
2520 clear_bit(__I40E_VSI_OVERFLOW_PROMISC, vsi->state); 2495 clear_bit(__I40E_VSI_OVERFLOW_PROMISC, vsi->state);
2521 promisc_changed = true;
2522 vsi->promisc_threshold = 0; 2496 vsi->promisc_threshold = 0;
2523 } 2497 }
2524 2498
@@ -2528,6 +2502,14 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
2528 goto out; 2502 goto out;
2529 } 2503 }
2530 2504
2505 new_overflow = test_bit(__I40E_VSI_OVERFLOW_PROMISC, vsi->state);
2506
2507 /* If we are entering overflow promiscuous, we need to calculate a new
2508 * threshold for when we are safe to exit
2509 */
2510 if (!old_overflow && new_overflow)
2511 vsi->promisc_threshold = (vsi->active_filters * 3) / 4;
2512
2531 /* check for changes in promiscuous modes */ 2513 /* check for changes in promiscuous modes */
2532 if (changed_flags & IFF_ALLMULTI) { 2514 if (changed_flags & IFF_ALLMULTI) {
2533 bool cur_multipromisc; 2515 bool cur_multipromisc;
@@ -2548,12 +2530,11 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
2548 } 2530 }
2549 } 2531 }
2550 2532
2551 if ((changed_flags & IFF_PROMISC) || promisc_changed) { 2533 if ((changed_flags & IFF_PROMISC) || old_overflow != new_overflow) {
2552 bool cur_promisc; 2534 bool cur_promisc;
2553 2535
2554 cur_promisc = (!!(vsi->current_netdev_flags & IFF_PROMISC) || 2536 cur_promisc = (!!(vsi->current_netdev_flags & IFF_PROMISC) ||
2555 test_bit(__I40E_VSI_OVERFLOW_PROMISC, 2537 new_overflow);
2556 vsi->state));
2557 aq_ret = i40e_set_promiscuous(pf, cur_promisc); 2538 aq_ret = i40e_set_promiscuous(pf, cur_promisc);
2558 if (aq_ret) { 2539 if (aq_ret) {
2559 retval = i40e_aq_rc_to_posix(aq_ret, 2540 retval = i40e_aq_rc_to_posix(aq_ret,
@@ -2738,22 +2719,6 @@ void i40e_vlan_stripping_disable(struct i40e_vsi *vsi)
2738} 2719}
2739 2720
2740/** 2721/**
2741 * i40e_vlan_rx_register - Setup or shutdown vlan offload
2742 * @netdev: network interface to be adjusted
2743 * @features: netdev features to test if VLAN offload is enabled or not
2744 **/
2745static void i40e_vlan_rx_register(struct net_device *netdev, u32 features)
2746{
2747 struct i40e_netdev_priv *np = netdev_priv(netdev);
2748 struct i40e_vsi *vsi = np->vsi;
2749
2750 if (features & NETIF_F_HW_VLAN_CTAG_RX)
2751 i40e_vlan_stripping_enable(vsi);
2752 else
2753 i40e_vlan_stripping_disable(vsi);
2754}
2755
2756/**
2757 * i40e_add_vlan_all_mac - Add a MAC/VLAN filter for each existing MAC address 2722 * i40e_add_vlan_all_mac - Add a MAC/VLAN filter for each existing MAC address
2758 * @vsi: the vsi being configured 2723 * @vsi: the vsi being configured
2759 * @vid: vlan id to be added (0 = untagged only , -1 = any) 2724 * @vid: vlan id to be added (0 = untagged only , -1 = any)
@@ -2928,7 +2893,10 @@ static void i40e_restore_vlan(struct i40e_vsi *vsi)
2928 if (!vsi->netdev) 2893 if (!vsi->netdev)
2929 return; 2894 return;
2930 2895
2931 i40e_vlan_rx_register(vsi->netdev, vsi->netdev->features); 2896 if (vsi->netdev->features & NETIF_F_HW_VLAN_CTAG_RX)
2897 i40e_vlan_stripping_enable(vsi);
2898 else
2899 i40e_vlan_stripping_disable(vsi);
2932 2900
2933 for_each_set_bit(vid, vsi->active_vlans, VLAN_N_VID) 2901 for_each_set_bit(vid, vsi->active_vlans, VLAN_N_VID)
2934 i40e_vlan_rx_add_vid(vsi->netdev, htons(ETH_P_8021Q), 2902 i40e_vlan_rx_add_vid(vsi->netdev, htons(ETH_P_8021Q),
@@ -3449,15 +3417,20 @@ static void i40e_vsi_configure_msix(struct i40e_vsi *vsi)
3449 for (i = 0; i < vsi->num_q_vectors; i++, vector++) { 3417 for (i = 0; i < vsi->num_q_vectors; i++, vector++) {
3450 struct i40e_q_vector *q_vector = vsi->q_vectors[i]; 3418 struct i40e_q_vector *q_vector = vsi->q_vectors[i];
3451 3419
3452 q_vector->itr_countdown = ITR_COUNTDOWN_START; 3420 q_vector->rx.next_update = jiffies + 1;
3453 q_vector->rx.itr = ITR_TO_REG(vsi->rx_rings[i]->rx_itr_setting); 3421 q_vector->rx.target_itr =
3454 q_vector->rx.latency_range = I40E_LOW_LATENCY; 3422 ITR_TO_REG(vsi->rx_rings[i]->itr_setting);
3455 wr32(hw, I40E_PFINT_ITRN(I40E_RX_ITR, vector - 1), 3423 wr32(hw, I40E_PFINT_ITRN(I40E_RX_ITR, vector - 1),
3456 q_vector->rx.itr); 3424 q_vector->rx.target_itr);
3457 q_vector->tx.itr = ITR_TO_REG(vsi->tx_rings[i]->tx_itr_setting); 3425 q_vector->rx.current_itr = q_vector->rx.target_itr;
3458 q_vector->tx.latency_range = I40E_LOW_LATENCY; 3426
3427 q_vector->tx.next_update = jiffies + 1;
3428 q_vector->tx.target_itr =
3429 ITR_TO_REG(vsi->tx_rings[i]->itr_setting);
3459 wr32(hw, I40E_PFINT_ITRN(I40E_TX_ITR, vector - 1), 3430 wr32(hw, I40E_PFINT_ITRN(I40E_TX_ITR, vector - 1),
3460 q_vector->tx.itr); 3431 q_vector->tx.target_itr);
3432 q_vector->tx.current_itr = q_vector->tx.target_itr;
3433
3461 wr32(hw, I40E_PFINT_RATEN(vector - 1), 3434 wr32(hw, I40E_PFINT_RATEN(vector - 1),
3462 i40e_intrl_usec_to_reg(vsi->int_rate_limit)); 3435 i40e_intrl_usec_to_reg(vsi->int_rate_limit));
3463 3436
@@ -3558,13 +3531,14 @@ static void i40e_configure_msi_and_legacy(struct i40e_vsi *vsi)
3558 u32 val; 3531 u32 val;
3559 3532
3560 /* set the ITR configuration */ 3533 /* set the ITR configuration */
3561 q_vector->itr_countdown = ITR_COUNTDOWN_START; 3534 q_vector->rx.next_update = jiffies + 1;
3562 q_vector->rx.itr = ITR_TO_REG(vsi->rx_rings[0]->rx_itr_setting); 3535 q_vector->rx.target_itr = ITR_TO_REG(vsi->rx_rings[0]->itr_setting);
3563 q_vector->rx.latency_range = I40E_LOW_LATENCY; 3536 wr32(hw, I40E_PFINT_ITR0(I40E_RX_ITR), q_vector->rx.target_itr);
3564 wr32(hw, I40E_PFINT_ITR0(I40E_RX_ITR), q_vector->rx.itr); 3537 q_vector->rx.current_itr = q_vector->rx.target_itr;
3565 q_vector->tx.itr = ITR_TO_REG(vsi->tx_rings[0]->tx_itr_setting); 3538 q_vector->tx.next_update = jiffies + 1;
3566 q_vector->tx.latency_range = I40E_LOW_LATENCY; 3539 q_vector->tx.target_itr = ITR_TO_REG(vsi->tx_rings[0]->itr_setting);
3567 wr32(hw, I40E_PFINT_ITR0(I40E_TX_ITR), q_vector->tx.itr); 3540 wr32(hw, I40E_PFINT_ITR0(I40E_TX_ITR), q_vector->tx.target_itr);
3541 q_vector->tx.current_itr = q_vector->tx.target_itr;
3568 3542
3569 i40e_enable_misc_int_causes(pf); 3543 i40e_enable_misc_int_causes(pf);
3570 3544
@@ -5375,7 +5349,7 @@ out:
5375 * @vsi: VSI to be configured 5349 * @vsi: VSI to be configured
5376 * 5350 *
5377 **/ 5351 **/
5378int i40e_get_link_speed(struct i40e_vsi *vsi) 5352static int i40e_get_link_speed(struct i40e_vsi *vsi)
5379{ 5353{
5380 struct i40e_pf *pf = vsi->back; 5354 struct i40e_pf *pf = vsi->back;
5381 5355
@@ -6560,6 +6534,75 @@ int i40e_up(struct i40e_vsi *vsi)
6560} 6534}
6561 6535
6562/** 6536/**
6537 * i40e_force_link_state - Force the link status
6538 * @pf: board private structure
6539 * @is_up: whether the link state should be forced up or down
6540 **/
6541static i40e_status i40e_force_link_state(struct i40e_pf *pf, bool is_up)
6542{
6543 struct i40e_aq_get_phy_abilities_resp abilities;
6544 struct i40e_aq_set_phy_config config = {0};
6545 struct i40e_hw *hw = &pf->hw;
6546 i40e_status err;
6547 u64 mask;
6548
6549 /* Get the current phy config */
6550 err = i40e_aq_get_phy_capabilities(hw, false, false, &abilities,
6551 NULL);
6552 if (err) {
6553 dev_err(&pf->pdev->dev,
6554 "failed to get phy cap., ret = %s last_status = %s\n",
6555 i40e_stat_str(hw, err),
6556 i40e_aq_str(hw, hw->aq.asq_last_status));
6557 return err;
6558 }
6559
6560 /* If link needs to go up, but was not forced to go down,
6561 * no need for a flap
6562 */
6563 if (is_up && abilities.phy_type != 0)
6564 return I40E_SUCCESS;
6565
6566 /* To force link we need to set bits for all supported PHY types,
6567 * but there are now more than 32, so we need to split the bitmap
6568 * across two fields.
6569 */
6570 mask = I40E_PHY_TYPES_BITMASK;
6571 config.phy_type = is_up ? cpu_to_le32((u32)(mask & 0xffffffff)) : 0;
6572 config.phy_type_ext = is_up ? (u8)((mask >> 32) & 0xff) : 0;
6573 /* Copy the old settings, except of phy_type */
6574 config.abilities = abilities.abilities;
6575 config.link_speed = abilities.link_speed;
6576 config.eee_capability = abilities.eee_capability;
6577 config.eeer = abilities.eeer_val;
6578 config.low_power_ctrl = abilities.d3_lpan;
6579 err = i40e_aq_set_phy_config(hw, &config, NULL);
6580
6581 if (err) {
6582 dev_err(&pf->pdev->dev,
6583 "set phy config ret = %s last_status = %s\n",
6584 i40e_stat_str(&pf->hw, err),
6585 i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
6586 return err;
6587 }
6588
6589 /* Update the link info */
6590 err = i40e_update_link_info(hw);
6591 if (err) {
6592 /* Wait a little bit (on 40G cards it sometimes takes a really
6593 * long time for link to come back from the atomic reset)
6594 * and try once more
6595 */
6596 msleep(1000);
6597 i40e_update_link_info(hw);
6598 }
6599
6600 i40e_aq_set_link_restart_an(hw, true, NULL);
6601
6602 return I40E_SUCCESS;
6603}
6604
6605/**
6563 * i40e_down - Shutdown the connection processing 6606 * i40e_down - Shutdown the connection processing
6564 * @vsi: the VSI being stopped 6607 * @vsi: the VSI being stopped
6565 **/ 6608 **/
@@ -6576,6 +6619,9 @@ void i40e_down(struct i40e_vsi *vsi)
6576 } 6619 }
6577 i40e_vsi_disable_irq(vsi); 6620 i40e_vsi_disable_irq(vsi);
6578 i40e_vsi_stop_rings(vsi); 6621 i40e_vsi_stop_rings(vsi);
6622 if (vsi->type == I40E_VSI_MAIN &&
6623 vsi->back->flags & I40E_FLAG_LINK_DOWN_ON_CLOSE_ENABLED)
6624 i40e_force_link_state(vsi->back, false);
6579 i40e_napi_disable_all(vsi); 6625 i40e_napi_disable_all(vsi);
6580 6626
6581 for (i = 0; i < vsi->num_queue_pairs; i++) { 6627 for (i = 0; i < vsi->num_queue_pairs; i++) {
@@ -6848,8 +6894,8 @@ i40e_set_cld_element(struct i40e_cloud_filter *filter,
6848 * Add or delete a cloud filter for a specific flow spec. 6894 * Add or delete a cloud filter for a specific flow spec.
6849 * Returns 0 if the filter were successfully added. 6895 * Returns 0 if the filter were successfully added.
6850 **/ 6896 **/
6851static int i40e_add_del_cloud_filter(struct i40e_vsi *vsi, 6897int i40e_add_del_cloud_filter(struct i40e_vsi *vsi,
6852 struct i40e_cloud_filter *filter, bool add) 6898 struct i40e_cloud_filter *filter, bool add)
6853{ 6899{
6854 struct i40e_aqc_cloud_filters_element_data cld_filter; 6900 struct i40e_aqc_cloud_filters_element_data cld_filter;
6855 struct i40e_pf *pf = vsi->back; 6901 struct i40e_pf *pf = vsi->back;
@@ -6915,9 +6961,9 @@ static int i40e_add_del_cloud_filter(struct i40e_vsi *vsi,
6915 * Add or delete a cloud filter for a specific flow spec using big buffer. 6961 * Add or delete a cloud filter for a specific flow spec using big buffer.
6916 * Returns 0 if the filter were successfully added. 6962 * Returns 0 if the filter were successfully added.
6917 **/ 6963 **/
6918static int i40e_add_del_cloud_filter_big_buf(struct i40e_vsi *vsi, 6964int i40e_add_del_cloud_filter_big_buf(struct i40e_vsi *vsi,
6919 struct i40e_cloud_filter *filter, 6965 struct i40e_cloud_filter *filter,
6920 bool add) 6966 bool add)
6921{ 6967{
6922 struct i40e_aqc_cloud_filters_element_bb cld_filter; 6968 struct i40e_aqc_cloud_filters_element_bb cld_filter;
6923 struct i40e_pf *pf = vsi->back; 6969 struct i40e_pf *pf = vsi->back;
@@ -7537,6 +7583,9 @@ int i40e_open(struct net_device *netdev)
7537 7583
7538 netif_carrier_off(netdev); 7584 netif_carrier_off(netdev);
7539 7585
7586 if (i40e_force_link_state(pf, true))
7587 return -EAGAIN;
7588
7540 err = i40e_vsi_open(vsi); 7589 err = i40e_vsi_open(vsi);
7541 if (err) 7590 if (err)
7542 return err; 7591 return err;
@@ -8087,6 +8136,88 @@ u32 i40e_get_global_fd_count(struct i40e_pf *pf)
8087} 8136}
8088 8137
8089/** 8138/**
8139 * i40e_reenable_fdir_sb - Restore FDir SB capability
8140 * @pf: board private structure
8141 **/
8142static void i40e_reenable_fdir_sb(struct i40e_pf *pf)
8143{
8144 if (pf->flags & I40E_FLAG_FD_SB_AUTO_DISABLED) {
8145 pf->flags &= ~I40E_FLAG_FD_SB_AUTO_DISABLED;
8146 if ((pf->flags & I40E_FLAG_FD_SB_ENABLED) &&
8147 (I40E_DEBUG_FD & pf->hw.debug_mask))
8148 dev_info(&pf->pdev->dev, "FD Sideband/ntuple is being enabled since we have space in the table now\n");
8149 }
8150}
8151
8152/**
8153 * i40e_reenable_fdir_atr - Restore FDir ATR capability
8154 * @pf: board private structure
8155 **/
8156static void i40e_reenable_fdir_atr(struct i40e_pf *pf)
8157{
8158 if (pf->flags & I40E_FLAG_FD_ATR_AUTO_DISABLED) {
8159 /* ATR uses the same filtering logic as SB rules. It only
8160 * functions properly if the input set mask is at the default
8161 * settings. It is safe to restore the default input set
8162 * because there are no active TCPv4 filter rules.
8163 */
8164 i40e_write_fd_input_set(pf, I40E_FILTER_PCTYPE_NONF_IPV4_TCP,
8165 I40E_L3_SRC_MASK | I40E_L3_DST_MASK |
8166 I40E_L4_SRC_MASK | I40E_L4_DST_MASK);
8167
8168 pf->flags &= ~I40E_FLAG_FD_ATR_AUTO_DISABLED;
8169 if ((pf->flags & I40E_FLAG_FD_ATR_ENABLED) &&
8170 (I40E_DEBUG_FD & pf->hw.debug_mask))
8171 dev_info(&pf->pdev->dev, "ATR is being enabled since we have space in the table and there are no conflicting ntuple rules\n");
8172 }
8173}
8174
8175/**
8176 * i40e_delete_invalid_filter - Delete an invalid FDIR filter
8177 * @pf: board private structure
8178 * @filter: FDir filter to remove
8179 */
8180static void i40e_delete_invalid_filter(struct i40e_pf *pf,
8181 struct i40e_fdir_filter *filter)
8182{
8183 /* Update counters */
8184 pf->fdir_pf_active_filters--;
8185 pf->fd_inv = 0;
8186
8187 switch (filter->flow_type) {
8188 case TCP_V4_FLOW:
8189 pf->fd_tcp4_filter_cnt--;
8190 break;
8191 case UDP_V4_FLOW:
8192 pf->fd_udp4_filter_cnt--;
8193 break;
8194 case SCTP_V4_FLOW:
8195 pf->fd_sctp4_filter_cnt--;
8196 break;
8197 case IP_USER_FLOW:
8198 switch (filter->ip4_proto) {
8199 case IPPROTO_TCP:
8200 pf->fd_tcp4_filter_cnt--;
8201 break;
8202 case IPPROTO_UDP:
8203 pf->fd_udp4_filter_cnt--;
8204 break;
8205 case IPPROTO_SCTP:
8206 pf->fd_sctp4_filter_cnt--;
8207 break;
8208 case IPPROTO_IP:
8209 pf->fd_ip4_filter_cnt--;
8210 break;
8211 }
8212 break;
8213 }
8214
8215 /* Remove the filter from the list and free memory */
8216 hlist_del(&filter->fdir_node);
8217 kfree(filter);
8218}
8219
8220/**
8090 * i40e_fdir_check_and_reenable - Function to reenabe FD ATR or SB if disabled 8221 * i40e_fdir_check_and_reenable - Function to reenabe FD ATR or SB if disabled
8091 * @pf: board private structure 8222 * @pf: board private structure
8092 **/ 8223 **/
@@ -8104,40 +8235,23 @@ void i40e_fdir_check_and_reenable(struct i40e_pf *pf)
8104 fcnt_avail = pf->fdir_pf_filter_count; 8235 fcnt_avail = pf->fdir_pf_filter_count;
8105 if ((fcnt_prog < (fcnt_avail - I40E_FDIR_BUFFER_HEAD_ROOM)) || 8236 if ((fcnt_prog < (fcnt_avail - I40E_FDIR_BUFFER_HEAD_ROOM)) ||
8106 (pf->fd_add_err == 0) || 8237 (pf->fd_add_err == 0) ||
8107 (i40e_get_current_atr_cnt(pf) < pf->fd_atr_cnt)) { 8238 (i40e_get_current_atr_cnt(pf) < pf->fd_atr_cnt))
8108 if (pf->flags & I40E_FLAG_FD_SB_AUTO_DISABLED) { 8239 i40e_reenable_fdir_sb(pf);
8109 pf->flags &= ~I40E_FLAG_FD_SB_AUTO_DISABLED;
8110 if ((pf->flags & I40E_FLAG_FD_SB_ENABLED) &&
8111 (I40E_DEBUG_FD & pf->hw.debug_mask))
8112 dev_info(&pf->pdev->dev, "FD Sideband/ntuple is being enabled since we have space in the table now\n");
8113 }
8114 }
8115 8240
8116 /* We should wait for even more space before re-enabling ATR. 8241 /* We should wait for even more space before re-enabling ATR.
8117 * Additionally, we cannot enable ATR as long as we still have TCP SB 8242 * Additionally, we cannot enable ATR as long as we still have TCP SB
8118 * rules active. 8243 * rules active.
8119 */ 8244 */
8120 if ((fcnt_prog < (fcnt_avail - I40E_FDIR_BUFFER_HEAD_ROOM_FOR_ATR)) && 8245 if ((fcnt_prog < (fcnt_avail - I40E_FDIR_BUFFER_HEAD_ROOM_FOR_ATR)) &&
8121 (pf->fd_tcp4_filter_cnt == 0)) { 8246 (pf->fd_tcp4_filter_cnt == 0))
8122 if (pf->flags & I40E_FLAG_FD_ATR_AUTO_DISABLED) { 8247 i40e_reenable_fdir_atr(pf);
8123 pf->flags &= ~I40E_FLAG_FD_ATR_AUTO_DISABLED;
8124 if ((pf->flags & I40E_FLAG_FD_ATR_ENABLED) &&
8125 (I40E_DEBUG_FD & pf->hw.debug_mask))
8126 dev_info(&pf->pdev->dev, "ATR is being enabled since we have space in the table and there are no conflicting ntuple rules\n");
8127 }
8128 }
8129 8248
8130 /* if hw had a problem adding a filter, delete it */ 8249 /* if hw had a problem adding a filter, delete it */
8131 if (pf->fd_inv > 0) { 8250 if (pf->fd_inv > 0) {
8132 hlist_for_each_entry_safe(filter, node, 8251 hlist_for_each_entry_safe(filter, node,
8133 &pf->fdir_filter_list, fdir_node) { 8252 &pf->fdir_filter_list, fdir_node)
8134 if (filter->fd_id == pf->fd_inv) { 8253 if (filter->fd_id == pf->fd_inv)
8135 hlist_del(&filter->fdir_node); 8254 i40e_delete_invalid_filter(pf, filter);
8136 kfree(filter);
8137 pf->fdir_pf_active_filters--;
8138 pf->fd_inv = 0;
8139 }
8140 }
8141 } 8255 }
8142} 8256}
8143 8257
@@ -9215,6 +9329,17 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)
9215 } 9329 }
9216 i40e_get_oem_version(&pf->hw); 9330 i40e_get_oem_version(&pf->hw);
9217 9331
9332 if (test_bit(__I40E_EMP_RESET_INTR_RECEIVED, pf->state) &&
9333 ((hw->aq.fw_maj_ver == 4 && hw->aq.fw_min_ver <= 33) ||
9334 hw->aq.fw_maj_ver < 4) && hw->mac.type == I40E_MAC_XL710) {
9335 /* The following delay is necessary for 4.33 firmware and older
9336 * to recover after EMP reset. 200 ms should suffice but we
9337 * put here 300 ms to be sure that FW is ready to operate
9338 * after reset.
9339 */
9340 mdelay(300);
9341 }
9342
9218 /* re-verify the eeprom if we just had an EMP reset */ 9343 /* re-verify the eeprom if we just had an EMP reset */
9219 if (test_and_clear_bit(__I40E_EMP_RESET_INTR_RECEIVED, pf->state)) 9344 if (test_and_clear_bit(__I40E_EMP_RESET_INTR_RECEIVED, pf->state))
9220 i40e_verify_eeprom(pf); 9345 i40e_verify_eeprom(pf);
@@ -9937,18 +10062,17 @@ static int i40e_vsi_clear(struct i40e_vsi *vsi)
9937 10062
9938 mutex_lock(&pf->switch_mutex); 10063 mutex_lock(&pf->switch_mutex);
9939 if (!pf->vsi[vsi->idx]) { 10064 if (!pf->vsi[vsi->idx]) {
9940 dev_err(&pf->pdev->dev, "pf->vsi[%d] is NULL, just free vsi[%d](%p,type %d)\n", 10065 dev_err(&pf->pdev->dev, "pf->vsi[%d] is NULL, just free vsi[%d](type %d)\n",
9941 vsi->idx, vsi->idx, vsi, vsi->type); 10066 vsi->idx, vsi->idx, vsi->type);
9942 goto unlock_vsi; 10067 goto unlock_vsi;
9943 } 10068 }
9944 10069
9945 if (pf->vsi[vsi->idx] != vsi) { 10070 if (pf->vsi[vsi->idx] != vsi) {
9946 dev_err(&pf->pdev->dev, 10071 dev_err(&pf->pdev->dev,
9947 "pf->vsi[%d](%p, type %d) != vsi[%d](%p,type %d): no free!\n", 10072 "pf->vsi[%d](type %d) != vsi[%d](type %d): no free!\n",
9948 pf->vsi[vsi->idx]->idx, 10073 pf->vsi[vsi->idx]->idx,
9949 pf->vsi[vsi->idx],
9950 pf->vsi[vsi->idx]->type, 10074 pf->vsi[vsi->idx]->type,
9951 vsi->idx, vsi, vsi->type); 10075 vsi->idx, vsi->type);
9952 goto unlock_vsi; 10076 goto unlock_vsi;
9953 } 10077 }
9954 10078
@@ -10018,7 +10142,7 @@ static int i40e_alloc_rings(struct i40e_vsi *vsi)
10018 ring->dcb_tc = 0; 10142 ring->dcb_tc = 0;
10019 if (vsi->back->hw_features & I40E_HW_WB_ON_ITR_CAPABLE) 10143 if (vsi->back->hw_features & I40E_HW_WB_ON_ITR_CAPABLE)
10020 ring->flags = I40E_TXR_FLAGS_WB_ON_ITR; 10144 ring->flags = I40E_TXR_FLAGS_WB_ON_ITR;
10021 ring->tx_itr_setting = pf->tx_itr_default; 10145 ring->itr_setting = pf->tx_itr_default;
10022 vsi->tx_rings[i] = ring++; 10146 vsi->tx_rings[i] = ring++;
10023 10147
10024 if (!i40e_enabled_xdp_vsi(vsi)) 10148 if (!i40e_enabled_xdp_vsi(vsi))
@@ -10036,7 +10160,7 @@ static int i40e_alloc_rings(struct i40e_vsi *vsi)
10036 if (vsi->back->hw_features & I40E_HW_WB_ON_ITR_CAPABLE) 10160 if (vsi->back->hw_features & I40E_HW_WB_ON_ITR_CAPABLE)
10037 ring->flags = I40E_TXR_FLAGS_WB_ON_ITR; 10161 ring->flags = I40E_TXR_FLAGS_WB_ON_ITR;
10038 set_ring_xdp(ring); 10162 set_ring_xdp(ring);
10039 ring->tx_itr_setting = pf->tx_itr_default; 10163 ring->itr_setting = pf->tx_itr_default;
10040 vsi->xdp_rings[i] = ring++; 10164 vsi->xdp_rings[i] = ring++;
10041 10165
10042setup_rx: 10166setup_rx:
@@ -10049,7 +10173,7 @@ setup_rx:
10049 ring->count = vsi->num_desc; 10173 ring->count = vsi->num_desc;
10050 ring->size = 0; 10174 ring->size = 0;
10051 ring->dcb_tc = 0; 10175 ring->dcb_tc = 0;
10052 ring->rx_itr_setting = pf->rx_itr_default; 10176 ring->itr_setting = pf->rx_itr_default;
10053 vsi->rx_rings[i] = ring; 10177 vsi->rx_rings[i] = ring;
10054 } 10178 }
10055 10179
@@ -10328,9 +10452,6 @@ static int i40e_vsi_alloc_q_vector(struct i40e_vsi *vsi, int v_idx, int cpu)
10328 netif_napi_add(vsi->netdev, &q_vector->napi, 10452 netif_napi_add(vsi->netdev, &q_vector->napi,
10329 i40e_napi_poll, NAPI_POLL_WEIGHT); 10453 i40e_napi_poll, NAPI_POLL_WEIGHT);
10330 10454
10331 q_vector->rx.latency_range = I40E_LOW_LATENCY;
10332 q_vector->tx.latency_range = I40E_LOW_LATENCY;
10333
10334 /* tie q_vector and vsi together */ 10455 /* tie q_vector and vsi together */
10335 vsi->q_vectors[v_idx] = q_vector; 10456 vsi->q_vectors[v_idx] = q_vector;
10336 10457
@@ -10473,6 +10594,9 @@ static int i40e_restore_interrupt_scheme(struct i40e_pf *pf)
10473 if (err) 10594 if (err)
10474 goto err_unwind; 10595 goto err_unwind;
10475 10596
10597 if (pf->flags & I40E_FLAG_IWARP_ENABLED)
10598 i40e_client_update_msix_info(pf);
10599
10476 return 0; 10600 return 0;
10477 10601
10478err_unwind: 10602err_unwind:
@@ -11089,6 +11213,16 @@ static int i40e_sw_init(struct i40e_pf *pf)
11089 /* IWARP needs one extra vector for CQP just like MISC.*/ 11213 /* IWARP needs one extra vector for CQP just like MISC.*/
11090 pf->num_iwarp_msix = (int)num_online_cpus() + 1; 11214 pf->num_iwarp_msix = (int)num_online_cpus() + 1;
11091 } 11215 }
11216 /* Stopping the FW LLDP engine is only supported on the
11217 * XL710 with a FW ver >= 1.7. Also, stopping FW LLDP
11218 * engine is not supported if NPAR is functioning on this
11219 * part
11220 */
11221 if (pf->hw.mac.type == I40E_MAC_XL710 &&
11222 !pf->hw.func_caps.npar_enable &&
11223 (pf->hw.aq.api_maj_ver > 1 ||
11224 (pf->hw.aq.api_maj_ver == 1 && pf->hw.aq.api_min_ver > 6)))
11225 pf->hw_features |= I40E_HW_STOPPABLE_FW_LLDP;
11092 11226
11093#ifdef CONFIG_PCI_IOV 11227#ifdef CONFIG_PCI_IOV
11094 if (pf->hw.func_caps.num_vfs && pf->hw.partition_id == 1) { 11228 if (pf->hw.func_caps.num_vfs && pf->hw.partition_id == 1) {
@@ -14213,6 +14347,11 @@ static int __maybe_unused i40e_suspend(struct device *dev)
14213 del_timer_sync(&pf->service_timer); 14347 del_timer_sync(&pf->service_timer);
14214 cancel_work_sync(&pf->service_task); 14348 cancel_work_sync(&pf->service_task);
14215 14349
14350 /* Client close must be called explicitly here because the timer
14351 * has been stopped.
14352 */
14353 i40e_notify_client_of_netdev_close(pf->vsi[pf->lan_vsi], false);
14354
14216 if (pf->wol_en && (pf->hw_features & I40E_HW_WOL_MC_MAGIC_PKT_WAKE)) 14355 if (pf->wol_en && (pf->hw_features & I40E_HW_WOL_MC_MAGIC_PKT_WAKE))
14217 i40e_enable_mc_magic_wake(pf); 14356 i40e_enable_mc_magic_wake(pf);
14218 14357
diff --git a/drivers/net/ethernet/intel/i40e/i40e_prototype.h b/drivers/net/ethernet/intel/i40e/i40e_prototype.h
index 83798b7841b9..eabb636f6a19 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_prototype.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_prototype.h
@@ -287,7 +287,7 @@ i40e_status i40e_aq_query_switch_comp_bw_config(struct i40e_hw *hw,
287 struct i40e_asq_cmd_details *cmd_details); 287 struct i40e_asq_cmd_details *cmd_details);
288i40e_status i40e_aq_resume_port_tx(struct i40e_hw *hw, 288i40e_status i40e_aq_resume_port_tx(struct i40e_hw *hw,
289 struct i40e_asq_cmd_details *cmd_details); 289 struct i40e_asq_cmd_details *cmd_details);
290i40e_status 290enum i40e_status_code
291i40e_aq_add_cloud_filters_bb(struct i40e_hw *hw, u16 seid, 291i40e_aq_add_cloud_filters_bb(struct i40e_hw *hw, u16 seid,
292 struct i40e_aqc_cloud_filters_element_bb *filters, 292 struct i40e_aqc_cloud_filters_element_bb *filters,
293 u8 filter_count); 293 u8 filter_count);
@@ -299,7 +299,7 @@ enum i40e_status_code
299i40e_aq_rem_cloud_filters(struct i40e_hw *hw, u16 vsi, 299i40e_aq_rem_cloud_filters(struct i40e_hw *hw, u16 vsi,
300 struct i40e_aqc_cloud_filters_element_data *filters, 300 struct i40e_aqc_cloud_filters_element_data *filters,
301 u8 filter_count); 301 u8 filter_count);
302i40e_status 302enum i40e_status_code
303i40e_aq_rem_cloud_filters_bb(struct i40e_hw *hw, u16 seid, 303i40e_aq_rem_cloud_filters_bb(struct i40e_hw *hw, u16 seid,
304 struct i40e_aqc_cloud_filters_element_bb *filters, 304 struct i40e_aqc_cloud_filters_element_bb *filters,
305 u8 filter_count); 305 u8 filter_count);
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
index e554aa6cf070..97cfe944b568 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
@@ -708,16 +708,22 @@ void i40e_free_tx_resources(struct i40e_ring *tx_ring)
708/** 708/**
709 * i40e_get_tx_pending - how many tx descriptors not processed 709 * i40e_get_tx_pending - how many tx descriptors not processed
710 * @tx_ring: the ring of descriptors 710 * @tx_ring: the ring of descriptors
711 * @in_sw: use SW variables
711 * 712 *
712 * Since there is no access to the ring head register 713 * Since there is no access to the ring head register
713 * in XL710, we need to use our local copies 714 * in XL710, we need to use our local copies
714 **/ 715 **/
715u32 i40e_get_tx_pending(struct i40e_ring *ring) 716u32 i40e_get_tx_pending(struct i40e_ring *ring, bool in_sw)
716{ 717{
717 u32 head, tail; 718 u32 head, tail;
718 719
719 head = i40e_get_head(ring); 720 if (!in_sw) {
720 tail = readl(ring->tail); 721 head = i40e_get_head(ring);
722 tail = readl(ring->tail);
723 } else {
724 head = ring->next_to_clean;
725 tail = ring->next_to_use;
726 }
721 727
722 if (head != tail) 728 if (head != tail)
723 return (head < tail) ? 729 return (head < tail) ?
@@ -774,7 +780,7 @@ void i40e_detect_recover_hung(struct i40e_vsi *vsi)
774 */ 780 */
775 smp_rmb(); 781 smp_rmb();
776 tx_ring->tx_stats.prev_pkt_ctr = 782 tx_ring->tx_stats.prev_pkt_ctr =
777 i40e_get_tx_pending(tx_ring) ? packets : -1; 783 i40e_get_tx_pending(tx_ring, true) ? packets : -1;
778 } 784 }
779 } 785 }
780} 786}
@@ -898,7 +904,7 @@ static bool i40e_clean_tx_irq(struct i40e_vsi *vsi,
898 * them to be written back in case we stay in NAPI. 904 * them to be written back in case we stay in NAPI.
899 * In this mode on X722 we do not enable Interrupt. 905 * In this mode on X722 we do not enable Interrupt.
900 */ 906 */
901 unsigned int j = i40e_get_tx_pending(tx_ring); 907 unsigned int j = i40e_get_tx_pending(tx_ring, false);
902 908
903 if (budget && 909 if (budget &&
904 ((j / WB_STRIDE) == 0) && (j > 0) && 910 ((j / WB_STRIDE) == 0) && (j > 0) &&
@@ -995,99 +1001,241 @@ void i40e_force_wb(struct i40e_vsi *vsi, struct i40e_q_vector *q_vector)
995 } 1001 }
996} 1002}
997 1003
1004static inline bool i40e_container_is_rx(struct i40e_q_vector *q_vector,
1005 struct i40e_ring_container *rc)
1006{
1007 return &q_vector->rx == rc;
1008}
1009
1010static inline unsigned int i40e_itr_divisor(struct i40e_q_vector *q_vector)
1011{
1012 unsigned int divisor;
1013
1014 switch (q_vector->vsi->back->hw.phy.link_info.link_speed) {
1015 case I40E_LINK_SPEED_40GB:
1016 divisor = I40E_ITR_ADAPTIVE_MIN_INC * 1024;
1017 break;
1018 case I40E_LINK_SPEED_25GB:
1019 case I40E_LINK_SPEED_20GB:
1020 divisor = I40E_ITR_ADAPTIVE_MIN_INC * 512;
1021 break;
1022 default:
1023 case I40E_LINK_SPEED_10GB:
1024 divisor = I40E_ITR_ADAPTIVE_MIN_INC * 256;
1025 break;
1026 case I40E_LINK_SPEED_1GB:
1027 case I40E_LINK_SPEED_100MB:
1028 divisor = I40E_ITR_ADAPTIVE_MIN_INC * 32;
1029 break;
1030 }
1031
1032 return divisor;
1033}
1034
998/** 1035/**
999 * i40e_set_new_dynamic_itr - Find new ITR level 1036 * i40e_update_itr - update the dynamic ITR value based on statistics
1037 * @q_vector: structure containing interrupt and ring information
1000 * @rc: structure containing ring performance data 1038 * @rc: structure containing ring performance data
1001 * 1039 *
1002 * Returns true if ITR changed, false if not 1040 * Stores a new ITR value based on packets and byte
1003 * 1041 * counts during the last interrupt. The advantage of per interrupt
1004 * Stores a new ITR value based on packets and byte counts during 1042 * computation is faster updates and more accurate ITR for the current
1005 * the last interrupt. The advantage of per interrupt computation 1043 * traffic pattern. Constants in this function were computed
1006 * is faster updates and more accurate ITR for the current traffic 1044 * based on theoretical maximum wire speed and thresholds were set based
1007 * pattern. Constants in this function were computed based on 1045 * on testing data as well as attempting to minimize response time
1008 * theoretical maximum wire speed and thresholds were set based on
1009 * testing data as well as attempting to minimize response time
1010 * while increasing bulk throughput. 1046 * while increasing bulk throughput.
1011 **/ 1047 **/
1012static bool i40e_set_new_dynamic_itr(struct i40e_ring_container *rc) 1048static void i40e_update_itr(struct i40e_q_vector *q_vector,
1049 struct i40e_ring_container *rc)
1013{ 1050{
1014 enum i40e_latency_range new_latency_range = rc->latency_range; 1051 unsigned int avg_wire_size, packets, bytes, itr;
1015 u32 new_itr = rc->itr; 1052 unsigned long next_update = jiffies;
1016 int bytes_per_usec;
1017 unsigned int usecs, estimated_usecs;
1018 1053
1019 if (rc->total_packets == 0 || !rc->itr) 1054 /* If we don't have any rings just leave ourselves set for maximum
1020 return false; 1055 * possible latency so we take ourselves out of the equation.
1056 */
1057 if (!rc->ring || !ITR_IS_DYNAMIC(rc->ring->itr_setting))
1058 return;
1059
1060 /* For Rx we want to push the delay up and default to low latency.
1061 * for Tx we want to pull the delay down and default to high latency.
1062 */
1063 itr = i40e_container_is_rx(q_vector, rc) ?
1064 I40E_ITR_ADAPTIVE_MIN_USECS | I40E_ITR_ADAPTIVE_LATENCY :
1065 I40E_ITR_ADAPTIVE_MAX_USECS | I40E_ITR_ADAPTIVE_LATENCY;
1066
1067 /* If we didn't update within up to 1 - 2 jiffies we can assume
1068 * that either packets are coming in so slow there hasn't been
1069 * any work, or that there is so much work that NAPI is dealing
1070 * with interrupt moderation and we don't need to do anything.
1071 */
1072 if (time_after(next_update, rc->next_update))
1073 goto clear_counts;
1074
1075 /* If itr_countdown is set it means we programmed an ITR within
1076 * the last 4 interrupt cycles. This has a side effect of us
1077 * potentially firing an early interrupt. In order to work around
1078 * this we need to throw out any data received for a few
1079 * interrupts following the update.
1080 */
1081 if (q_vector->itr_countdown) {
1082 itr = rc->target_itr;
1083 goto clear_counts;
1084 }
1085
1086 packets = rc->total_packets;
1087 bytes = rc->total_bytes;
1021 1088
1022 usecs = (rc->itr << 1) * ITR_COUNTDOWN_START; 1089 if (i40e_container_is_rx(q_vector, rc)) {
1023 bytes_per_usec = rc->total_bytes / usecs; 1090 /* If Rx there are 1 to 4 packets and bytes are less than
1091 * 9000 assume insufficient data to use bulk rate limiting
1092 * approach unless Tx is already in bulk rate limiting. We
1093 * are likely latency driven.
1094 */
1095 if (packets && packets < 4 && bytes < 9000 &&
1096 (q_vector->tx.target_itr & I40E_ITR_ADAPTIVE_LATENCY)) {
1097 itr = I40E_ITR_ADAPTIVE_LATENCY;
1098 goto adjust_by_size;
1099 }
1100 } else if (packets < 4) {
1101 /* If we have Tx and Rx ITR maxed and Tx ITR is running in
1102 * bulk mode and we are receiving 4 or fewer packets just
1103 * reset the ITR_ADAPTIVE_LATENCY bit for latency mode so
1104 * that the Rx can relax.
1105 */
1106 if (rc->target_itr == I40E_ITR_ADAPTIVE_MAX_USECS &&
1107 (q_vector->rx.target_itr & I40E_ITR_MASK) ==
1108 I40E_ITR_ADAPTIVE_MAX_USECS)
1109 goto clear_counts;
1110 } else if (packets > 32) {
1111 /* If we have processed over 32 packets in a single interrupt
1112 * for Tx assume we need to switch over to "bulk" mode.
1113 */
1114 rc->target_itr &= ~I40E_ITR_ADAPTIVE_LATENCY;
1115 }
1024 1116
1025 /* The calculations in this algorithm depend on interrupts actually 1117 /* We have no packets to actually measure against. This means
1026 * firing at the ITR rate. This may not happen if the packet rate is 1118 * either one of the other queues on this vector is active or
1027 * really low, or if we've been napi polling. Check to make sure 1119 * we are a Tx queue doing TSO with too high of an interrupt rate.
1028 * that's not the case before we continue. 1120 *
1121 * Between 4 and 56 we can assume that our current interrupt delay
1122 * is only slightly too low. As such we should increase it by a small
1123 * fixed amount.
1029 */ 1124 */
1030 estimated_usecs = jiffies_to_usecs(jiffies - rc->last_itr_update); 1125 if (packets < 56) {
1031 if (estimated_usecs > usecs) { 1126 itr = rc->target_itr + I40E_ITR_ADAPTIVE_MIN_INC;
1032 new_latency_range = I40E_LOW_LATENCY; 1127 if ((itr & I40E_ITR_MASK) > I40E_ITR_ADAPTIVE_MAX_USECS) {
1033 goto reset_latency; 1128 itr &= I40E_ITR_ADAPTIVE_LATENCY;
1129 itr += I40E_ITR_ADAPTIVE_MAX_USECS;
1130 }
1131 goto clear_counts;
1132 }
1133
1134 if (packets <= 256) {
1135 itr = min(q_vector->tx.current_itr, q_vector->rx.current_itr);
1136 itr &= I40E_ITR_MASK;
1137
1138 /* Between 56 and 112 is our "goldilocks" zone where we are
1139 * working out "just right". Just report that our current
1140 * ITR is good for us.
1141 */
1142 if (packets <= 112)
1143 goto clear_counts;
1144
1145 /* If packet count is 128 or greater we are likely looking
1146 * at a slight overrun of the delay we want. Try halving
1147 * our delay to see if that will cut the number of packets
1148 * in half per interrupt.
1149 */
1150 itr /= 2;
1151 itr &= I40E_ITR_MASK;
1152 if (itr < I40E_ITR_ADAPTIVE_MIN_USECS)
1153 itr = I40E_ITR_ADAPTIVE_MIN_USECS;
1154
1155 goto clear_counts;
1034 } 1156 }
1035 1157
1036 /* simple throttlerate management 1158 /* The paths below assume we are dealing with a bulk ITR since
1037 * 0-10MB/s lowest (50000 ints/s) 1159 * number of packets is greater than 256. We are just going to have
1038 * 10-20MB/s low (20000 ints/s) 1160 * to compute a value and try to bring the count under control,
1039 * 20-1249MB/s bulk (18000 ints/s) 1161 * though for smaller packet sizes there isn't much we can do as
1162 * NAPI polling will likely be kicking in sooner rather than later.
1163 */
1164 itr = I40E_ITR_ADAPTIVE_BULK;
1165
1166adjust_by_size:
1167 /* If packet counts are 256 or greater we can assume we have a gross
1168 * overestimation of what the rate should be. Instead of trying to fine
1169 * tune it just use the formula below to try and dial in an exact value
1170 * give the current packet size of the frame.
1171 */
1172 avg_wire_size = bytes / packets;
1173
1174 /* The following is a crude approximation of:
1175 * wmem_default / (size + overhead) = desired_pkts_per_int
1176 * rate / bits_per_byte / (size + ethernet overhead) = pkt_rate
1177 * (desired_pkt_rate / pkt_rate) * usecs_per_sec = ITR value
1178 *
1179 * Assuming wmem_default is 212992 and overhead is 640 bytes per
1180 * packet, (256 skb, 64 headroom, 320 shared info), we can reduce the
1181 * formula down to
1040 * 1182 *
1041 * The math works out because the divisor is in 10^(-6) which 1183 * (170 * (size + 24)) / (size + 640) = ITR
1042 * turns the bytes/us input value into MB/s values, but 1184 *
1043 * make sure to use usecs, as the register values written 1185 * We first do some math on the packet size and then finally bitshift
1044 * are in 2 usec increments in the ITR registers, and make sure 1186 * by 8 after rounding up. We also have to account for PCIe link speed
1045 * to use the smoothed values that the countdown timer gives us. 1187 * difference as ITR scales based on this.
1046 */ 1188 */
1047 switch (new_latency_range) { 1189 if (avg_wire_size <= 60) {
1048 case I40E_LOWEST_LATENCY: 1190 /* Start at 250k ints/sec */
1049 if (bytes_per_usec > 10) 1191 avg_wire_size = 4096;
1050 new_latency_range = I40E_LOW_LATENCY; 1192 } else if (avg_wire_size <= 380) {
1051 break; 1193 /* 250K ints/sec to 60K ints/sec */
1052 case I40E_LOW_LATENCY: 1194 avg_wire_size *= 40;
1053 if (bytes_per_usec > 20) 1195 avg_wire_size += 1696;
1054 new_latency_range = I40E_BULK_LATENCY; 1196 } else if (avg_wire_size <= 1084) {
1055 else if (bytes_per_usec <= 10) 1197 /* 60K ints/sec to 36K ints/sec */
1056 new_latency_range = I40E_LOWEST_LATENCY; 1198 avg_wire_size *= 15;
1057 break; 1199 avg_wire_size += 11452;
1058 case I40E_BULK_LATENCY: 1200 } else if (avg_wire_size <= 1980) {
1059 default: 1201 /* 36K ints/sec to 30K ints/sec */
1060 if (bytes_per_usec <= 20) 1202 avg_wire_size *= 5;
1061 new_latency_range = I40E_LOW_LATENCY; 1203 avg_wire_size += 22420;
1062 break; 1204 } else {
1205 /* plateau at a limit of 30K ints/sec */
1206 avg_wire_size = 32256;
1063 } 1207 }
1064 1208
1065reset_latency: 1209 /* If we are in low latency mode halve our delay which doubles the
1066 rc->latency_range = new_latency_range; 1210 * rate to somewhere between 100K to 16K ints/sec
1211 */
1212 if (itr & I40E_ITR_ADAPTIVE_LATENCY)
1213 avg_wire_size /= 2;
1067 1214
1068 switch (new_latency_range) { 1215 /* Resultant value is 256 times larger than it needs to be. This
1069 case I40E_LOWEST_LATENCY: 1216 * gives us room to adjust the value as needed to either increase
1070 new_itr = I40E_ITR_50K; 1217 * or decrease the value based on link speeds of 10G, 2.5G, 1G, etc.
1071 break; 1218 *
1072 case I40E_LOW_LATENCY: 1219 * Use addition as we have already recorded the new latency flag
1073 new_itr = I40E_ITR_20K; 1220 * for the ITR value.
1074 break; 1221 */
1075 case I40E_BULK_LATENCY: 1222 itr += DIV_ROUND_UP(avg_wire_size, i40e_itr_divisor(q_vector)) *
1076 new_itr = I40E_ITR_18K; 1223 I40E_ITR_ADAPTIVE_MIN_INC;
1077 break; 1224
1078 default: 1225 if ((itr & I40E_ITR_MASK) > I40E_ITR_ADAPTIVE_MAX_USECS) {
1079 break; 1226 itr &= I40E_ITR_ADAPTIVE_LATENCY;
1227 itr += I40E_ITR_ADAPTIVE_MAX_USECS;
1080 } 1228 }
1081 1229
1230clear_counts:
1231 /* write back value */
1232 rc->target_itr = itr;
1233
1234 /* next update should occur within next jiffy */
1235 rc->next_update = next_update + 1;
1236
1082 rc->total_bytes = 0; 1237 rc->total_bytes = 0;
1083 rc->total_packets = 0; 1238 rc->total_packets = 0;
1084 rc->last_itr_update = jiffies;
1085
1086 if (new_itr != rc->itr) {
1087 rc->itr = new_itr;
1088 return true;
1089 }
1090 return false;
1091} 1239}
1092 1240
1093/** 1241/**
@@ -1991,7 +2139,7 @@ static struct sk_buff *i40e_build_skb(struct i40e_ring *rx_ring,
1991 * @rx_buffer: rx buffer to pull data from 2139 * @rx_buffer: rx buffer to pull data from
1992 * 2140 *
1993 * This function will clean up the contents of the rx_buffer. It will 2141 * This function will clean up the contents of the rx_buffer. It will
1994 * either recycle the bufer or unmap it and free the associated resources. 2142 * either recycle the buffer or unmap it and free the associated resources.
1995 */ 2143 */
1996static void i40e_put_rx_buffer(struct i40e_ring *rx_ring, 2144static void i40e_put_rx_buffer(struct i40e_ring *rx_ring,
1997 struct i40e_rx_buffer *rx_buffer) 2145 struct i40e_rx_buffer *rx_buffer)
@@ -2274,29 +2422,45 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget)
2274 return failure ? budget : (int)total_rx_packets; 2422 return failure ? budget : (int)total_rx_packets;
2275} 2423}
2276 2424
2277static u32 i40e_buildreg_itr(const int type, const u16 itr) 2425static inline u32 i40e_buildreg_itr(const int type, u16 itr)
2278{ 2426{
2279 u32 val; 2427 u32 val;
2280 2428
2429 /* We don't bother with setting the CLEARPBA bit as the data sheet
2430 * points out doing so is "meaningless since it was already
2431 * auto-cleared". The auto-clearing happens when the interrupt is
2432 * asserted.
2433 *
2434 * Hardware errata 28 for also indicates that writing to a
2435 * xxINT_DYN_CTLx CSR with INTENA_MSK (bit 31) set to 0 will clear
2436 * an event in the PBA anyway so we need to rely on the automask
2437 * to hold pending events for us until the interrupt is re-enabled
2438 *
2439 * The itr value is reported in microseconds, and the register
2440 * value is recorded in 2 microsecond units. For this reason we
2441 * only need to shift by the interval shift - 1 instead of the
2442 * full value.
2443 */
2444 itr &= I40E_ITR_MASK;
2445
2281 val = I40E_PFINT_DYN_CTLN_INTENA_MASK | 2446 val = I40E_PFINT_DYN_CTLN_INTENA_MASK |
2282 I40E_PFINT_DYN_CTLN_CLEARPBA_MASK |
2283 (type << I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT) | 2447 (type << I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT) |
2284 (itr << I40E_PFINT_DYN_CTLN_INTERVAL_SHIFT); 2448 (itr << (I40E_PFINT_DYN_CTLN_INTERVAL_SHIFT - 1));
2285 2449
2286 return val; 2450 return val;
2287} 2451}
2288 2452
2289/* a small macro to shorten up some long lines */ 2453/* a small macro to shorten up some long lines */
2290#define INTREG I40E_PFINT_DYN_CTLN 2454#define INTREG I40E_PFINT_DYN_CTLN
2291static inline int get_rx_itr(struct i40e_vsi *vsi, int idx)
2292{
2293 return vsi->rx_rings[idx]->rx_itr_setting;
2294}
2295 2455
2296static inline int get_tx_itr(struct i40e_vsi *vsi, int idx) 2456/* The act of updating the ITR will cause it to immediately trigger. In order
2297{ 2457 * to prevent this from throwing off adaptive update statistics we defer the
2298 return vsi->tx_rings[idx]->tx_itr_setting; 2458 * update so that it can only happen so often. So after either Tx or Rx are
2299} 2459 * updated we make the adaptive scheme wait until either the ITR completely
2460 * expires via the next_update expiration or we have been through at least
2461 * 3 interrupts.
2462 */
2463#define ITR_COUNTDOWN_START 3
2300 2464
2301/** 2465/**
2302 * i40e_update_enable_itr - Update itr and re-enable MSIX interrupt 2466 * i40e_update_enable_itr - Update itr and re-enable MSIX interrupt
@@ -2308,10 +2472,7 @@ static inline void i40e_update_enable_itr(struct i40e_vsi *vsi,
2308 struct i40e_q_vector *q_vector) 2472 struct i40e_q_vector *q_vector)
2309{ 2473{
2310 struct i40e_hw *hw = &vsi->back->hw; 2474 struct i40e_hw *hw = &vsi->back->hw;
2311 bool rx = false, tx = false; 2475 u32 intval;
2312 u32 rxval, txval;
2313 int idx = q_vector->v_idx;
2314 int rx_itr_setting, tx_itr_setting;
2315 2476
2316 /* If we don't have MSIX, then we only need to re-enable icr0 */ 2477 /* If we don't have MSIX, then we only need to re-enable icr0 */
2317 if (!(vsi->back->flags & I40E_FLAG_MSIX_ENABLED)) { 2478 if (!(vsi->back->flags & I40E_FLAG_MSIX_ENABLED)) {
@@ -2319,65 +2480,49 @@ static inline void i40e_update_enable_itr(struct i40e_vsi *vsi,
2319 return; 2480 return;
2320 } 2481 }
2321 2482
2322 /* avoid dynamic calculation if in countdown mode OR if 2483 /* These will do nothing if dynamic updates are not enabled */
2323 * all dynamic is disabled 2484 i40e_update_itr(q_vector, &q_vector->tx);
2324 */ 2485 i40e_update_itr(q_vector, &q_vector->rx);
2325 rxval = txval = i40e_buildreg_itr(I40E_ITR_NONE, 0);
2326
2327 rx_itr_setting = get_rx_itr(vsi, idx);
2328 tx_itr_setting = get_tx_itr(vsi, idx);
2329
2330 if (q_vector->itr_countdown > 0 ||
2331 (!ITR_IS_DYNAMIC(rx_itr_setting) &&
2332 !ITR_IS_DYNAMIC(tx_itr_setting))) {
2333 goto enable_int;
2334 }
2335
2336 if (ITR_IS_DYNAMIC(rx_itr_setting)) {
2337 rx = i40e_set_new_dynamic_itr(&q_vector->rx);
2338 rxval = i40e_buildreg_itr(I40E_RX_ITR, q_vector->rx.itr);
2339 }
2340
2341 if (ITR_IS_DYNAMIC(tx_itr_setting)) {
2342 tx = i40e_set_new_dynamic_itr(&q_vector->tx);
2343 txval = i40e_buildreg_itr(I40E_TX_ITR, q_vector->tx.itr);
2344 }
2345 2486
2346 if (rx || tx) { 2487 /* This block of logic allows us to get away with only updating
2347 /* get the higher of the two ITR adjustments and 2488 * one ITR value with each interrupt. The idea is to perform a
2348 * use the same value for both ITR registers 2489 * pseudo-lazy update with the following criteria.
2349 * when in adaptive mode (Rx and/or Tx) 2490 *
2350 */ 2491 * 1. Rx is given higher priority than Tx if both are in same state
2351 u16 itr = max(q_vector->tx.itr, q_vector->rx.itr); 2492 * 2. If we must reduce an ITR that is given highest priority.
2352 2493 * 3. We then give priority to increasing ITR based on amount.
2353 q_vector->tx.itr = q_vector->rx.itr = itr;
2354 txval = i40e_buildreg_itr(I40E_TX_ITR, itr);
2355 tx = true;
2356 rxval = i40e_buildreg_itr(I40E_RX_ITR, itr);
2357 rx = true;
2358 }
2359
2360 /* only need to enable the interrupt once, but need
2361 * to possibly update both ITR values
2362 */ 2494 */
2363 if (rx) { 2495 if (q_vector->rx.target_itr < q_vector->rx.current_itr) {
2364 /* set the INTENA_MSK_MASK so that this first write 2496 /* Rx ITR needs to be reduced, this is highest priority */
2365 * won't actually enable the interrupt, instead just 2497 intval = i40e_buildreg_itr(I40E_RX_ITR,
2366 * updating the ITR (it's bit 31 PF and VF) 2498 q_vector->rx.target_itr);
2499 q_vector->rx.current_itr = q_vector->rx.target_itr;
2500 q_vector->itr_countdown = ITR_COUNTDOWN_START;
2501 } else if ((q_vector->tx.target_itr < q_vector->tx.current_itr) ||
2502 ((q_vector->rx.target_itr - q_vector->rx.current_itr) <
2503 (q_vector->tx.target_itr - q_vector->tx.current_itr))) {
2504 /* Tx ITR needs to be reduced, this is second priority
2505 * Tx ITR needs to be increased more than Rx, fourth priority
2367 */ 2506 */
2368 rxval |= BIT(31); 2507 intval = i40e_buildreg_itr(I40E_TX_ITR,
2369 /* don't check _DOWN because interrupt isn't being enabled */ 2508 q_vector->tx.target_itr);
2370 wr32(hw, INTREG(q_vector->reg_idx), rxval); 2509 q_vector->tx.current_itr = q_vector->tx.target_itr;
2510 q_vector->itr_countdown = ITR_COUNTDOWN_START;
2511 } else if (q_vector->rx.current_itr != q_vector->rx.target_itr) {
2512 /* Rx ITR needs to be increased, third priority */
2513 intval = i40e_buildreg_itr(I40E_RX_ITR,
2514 q_vector->rx.target_itr);
2515 q_vector->rx.current_itr = q_vector->rx.target_itr;
2516 q_vector->itr_countdown = ITR_COUNTDOWN_START;
2517 } else {
2518 /* No ITR update, lowest priority */
2519 intval = i40e_buildreg_itr(I40E_ITR_NONE, 0);
2520 if (q_vector->itr_countdown)
2521 q_vector->itr_countdown--;
2371 } 2522 }
2372 2523
2373enable_int:
2374 if (!test_bit(__I40E_VSI_DOWN, vsi->state)) 2524 if (!test_bit(__I40E_VSI_DOWN, vsi->state))
2375 wr32(hw, INTREG(q_vector->reg_idx), txval); 2525 wr32(hw, INTREG(q_vector->reg_idx), intval);
2376
2377 if (q_vector->itr_countdown)
2378 q_vector->itr_countdown--;
2379 else
2380 q_vector->itr_countdown = ITR_COUNTDOWN_START;
2381} 2526}
2382 2527
2383/** 2528/**
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.h b/drivers/net/ethernet/intel/i40e/i40e_txrx.h
index 701b708628b0..3c80ea784389 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.h
@@ -30,32 +30,37 @@
30#include <net/xdp.h> 30#include <net/xdp.h>
31 31
32/* Interrupt Throttling and Rate Limiting Goodies */ 32/* Interrupt Throttling and Rate Limiting Goodies */
33
34#define I40E_MAX_ITR 0x0FF0 /* reg uses 2 usec resolution */
35#define I40E_MIN_ITR 0x0001 /* reg uses 2 usec resolution */
36#define I40E_ITR_100K 0x0005
37#define I40E_ITR_50K 0x000A
38#define I40E_ITR_20K 0x0019
39#define I40E_ITR_18K 0x001B
40#define I40E_ITR_8K 0x003E
41#define I40E_ITR_4K 0x007A
42#define I40E_MAX_INTRL 0x3B /* reg uses 4 usec resolution */
43#define I40E_ITR_RX_DEF (ITR_REG_TO_USEC(I40E_ITR_20K) | \
44 I40E_ITR_DYNAMIC)
45#define I40E_ITR_TX_DEF (ITR_REG_TO_USEC(I40E_ITR_20K) | \
46 I40E_ITR_DYNAMIC)
47#define I40E_ITR_DYNAMIC 0x8000 /* use top bit as a flag */
48#define I40E_MIN_INT_RATE 250 /* ~= 1000000 / (I40E_MAX_ITR * 2) */
49#define I40E_MAX_INT_RATE 500000 /* == 1000000 / (I40E_MIN_ITR * 2) */
50#define I40E_DEFAULT_IRQ_WORK 256 33#define I40E_DEFAULT_IRQ_WORK 256
51#define ITR_TO_REG(setting) ((setting & ~I40E_ITR_DYNAMIC) >> 1) 34
52#define ITR_IS_DYNAMIC(setting) (!!(setting & I40E_ITR_DYNAMIC)) 35/* The datasheet for the X710 and XL710 indicate that the maximum value for
53#define ITR_REG_TO_USEC(itr_reg) (itr_reg << 1) 36 * the ITR is 8160usec which is then called out as 0xFF0 with a 2usec
37 * resolution. 8160 is 0x1FE0 when written out in hex. So instead of storing
38 * the register value which is divided by 2 lets use the actual values and
39 * avoid an excessive amount of translation.
40 */
41#define I40E_ITR_DYNAMIC 0x8000 /* use top bit as a flag */
42#define I40E_ITR_MASK 0x1FFE /* mask for ITR register value */
43#define I40E_MIN_ITR 2 /* reg uses 2 usec resolution */
44#define I40E_ITR_100K 10 /* all values below must be even */
45#define I40E_ITR_50K 20
46#define I40E_ITR_20K 50
47#define I40E_ITR_18K 60
48#define I40E_ITR_8K 122
49#define I40E_MAX_ITR 8160 /* maximum value as per datasheet */
50#define ITR_TO_REG(setting) ((setting) & ~I40E_ITR_DYNAMIC)
51#define ITR_REG_ALIGN(setting) __ALIGN_MASK(setting, ~I40E_ITR_MASK)
52#define ITR_IS_DYNAMIC(setting) (!!((setting) & I40E_ITR_DYNAMIC))
53
54#define I40E_ITR_RX_DEF (I40E_ITR_20K | I40E_ITR_DYNAMIC)
55#define I40E_ITR_TX_DEF (I40E_ITR_20K | I40E_ITR_DYNAMIC)
56
54/* 0x40 is the enable bit for interrupt rate limiting, and must be set if 57/* 0x40 is the enable bit for interrupt rate limiting, and must be set if
55 * the value of the rate limit is non-zero 58 * the value of the rate limit is non-zero
56 */ 59 */
57#define INTRL_ENA BIT(6) 60#define INTRL_ENA BIT(6)
61#define I40E_MAX_INTRL 0x3B /* reg uses 4 usec resolution */
58#define INTRL_REG_TO_USEC(intrl) ((intrl & ~INTRL_ENA) << 2) 62#define INTRL_REG_TO_USEC(intrl) ((intrl & ~INTRL_ENA) << 2)
63
59/** 64/**
60 * i40e_intrl_usec_to_reg - convert interrupt rate limit to register 65 * i40e_intrl_usec_to_reg - convert interrupt rate limit to register
61 * @intrl: interrupt rate limit to convert 66 * @intrl: interrupt rate limit to convert
@@ -382,8 +387,7 @@ struct i40e_ring {
382 * these values always store the USER setting, and must be converted 387 * these values always store the USER setting, and must be converted
383 * before programming to a register. 388 * before programming to a register.
384 */ 389 */
385 u16 rx_itr_setting; 390 u16 itr_setting;
386 u16 tx_itr_setting;
387 391
388 u16 count; /* Number of descriptors */ 392 u16 count; /* Number of descriptors */
389 u16 reg_idx; /* HW register index of the ring */ 393 u16 reg_idx; /* HW register index of the ring */
@@ -459,21 +463,21 @@ static inline void set_ring_xdp(struct i40e_ring *ring)
459 ring->flags |= I40E_TXR_FLAGS_XDP; 463 ring->flags |= I40E_TXR_FLAGS_XDP;
460} 464}
461 465
462enum i40e_latency_range { 466#define I40E_ITR_ADAPTIVE_MIN_INC 0x0002
463 I40E_LOWEST_LATENCY = 0, 467#define I40E_ITR_ADAPTIVE_MIN_USECS 0x0002
464 I40E_LOW_LATENCY = 1, 468#define I40E_ITR_ADAPTIVE_MAX_USECS 0x007e
465 I40E_BULK_LATENCY = 2, 469#define I40E_ITR_ADAPTIVE_LATENCY 0x8000
466}; 470#define I40E_ITR_ADAPTIVE_BULK 0x0000
471#define ITR_IS_BULK(x) (!((x) & I40E_ITR_ADAPTIVE_LATENCY))
467 472
468struct i40e_ring_container { 473struct i40e_ring_container {
469 /* array of pointers to rings */ 474 struct i40e_ring *ring; /* pointer to linked list of ring(s) */
470 struct i40e_ring *ring; 475 unsigned long next_update; /* jiffies value of next update */
471 unsigned int total_bytes; /* total bytes processed this int */ 476 unsigned int total_bytes; /* total bytes processed this int */
472 unsigned int total_packets; /* total packets processed this int */ 477 unsigned int total_packets; /* total packets processed this int */
473 unsigned long last_itr_update; /* jiffies of last ITR update */
474 u16 count; 478 u16 count;
475 enum i40e_latency_range latency_range; 479 u16 target_itr; /* target ITR setting for ring(s) */
476 u16 itr; 480 u16 current_itr; /* current ITR setting for ring(s) */
477}; 481};
478 482
479/* iterator for handling rings in ring container */ 483/* iterator for handling rings in ring container */
@@ -501,7 +505,7 @@ void i40e_free_tx_resources(struct i40e_ring *tx_ring);
501void i40e_free_rx_resources(struct i40e_ring *rx_ring); 505void i40e_free_rx_resources(struct i40e_ring *rx_ring);
502int i40e_napi_poll(struct napi_struct *napi, int budget); 506int i40e_napi_poll(struct napi_struct *napi, int budget);
503void i40e_force_wb(struct i40e_vsi *vsi, struct i40e_q_vector *q_vector); 507void i40e_force_wb(struct i40e_vsi *vsi, struct i40e_q_vector *q_vector);
504u32 i40e_get_tx_pending(struct i40e_ring *ring); 508u32 i40e_get_tx_pending(struct i40e_ring *ring, bool in_sw);
505void i40e_detect_recover_hung(struct i40e_vsi *vsi); 509void i40e_detect_recover_hung(struct i40e_vsi *vsi);
506int __i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size); 510int __i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size);
507bool __i40e_chk_linearize(struct sk_buff *skb); 511bool __i40e_chk_linearize(struct sk_buff *skb);
diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h b/drivers/net/ethernet/intel/i40e/i40e_type.h
index cd294e6a8587..69ea15892a5b 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_type.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_type.h
@@ -39,7 +39,7 @@
39#define I40E_MASK(mask, shift) ((u32)(mask) << (shift)) 39#define I40E_MASK(mask, shift) ((u32)(mask) << (shift))
40 40
41#define I40E_MAX_VSI_QP 16 41#define I40E_MAX_VSI_QP 16
42#define I40E_MAX_VF_VSI 3 42#define I40E_MAX_VF_VSI 4
43#define I40E_MAX_CHAINED_RX_BUFFERS 5 43#define I40E_MAX_CHAINED_RX_BUFFERS 5
44#define I40E_MAX_PF_UDP_OFFLOAD_PORTS 16 44#define I40E_MAX_PF_UDP_OFFLOAD_PORTS 16
45 45
@@ -1336,6 +1336,9 @@ struct i40e_hw_port_stats {
1336#define I40E_SR_PCIE_ALT_MODULE_MAX_SIZE 1024 1336#define I40E_SR_PCIE_ALT_MODULE_MAX_SIZE 1024
1337#define I40E_SR_CONTROL_WORD_1_SHIFT 0x06 1337#define I40E_SR_CONTROL_WORD_1_SHIFT 0x06
1338#define I40E_SR_CONTROL_WORD_1_MASK (0x03 << I40E_SR_CONTROL_WORD_1_SHIFT) 1338#define I40E_SR_CONTROL_WORD_1_MASK (0x03 << I40E_SR_CONTROL_WORD_1_SHIFT)
1339#define I40E_PTR_TYPE BIT(15)
1340#define I40E_SR_OCP_CFG_WORD0 0x2B
1341#define I40E_SR_OCP_ENABLED BIT(15)
1339 1342
1340/* Shadow RAM related */ 1343/* Shadow RAM related */
1341#define I40E_SR_SECTOR_SIZE_IN_WORDS 0x800 1344#define I40E_SR_SECTOR_SIZE_IN_WORDS 0x800
diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
index e9309fb9084b..321ab4badb68 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
@@ -258,6 +258,38 @@ static u16 i40e_vc_get_pf_queue_id(struct i40e_vf *vf, u16 vsi_id,
258} 258}
259 259
260/** 260/**
261 * i40e_get_real_pf_qid
262 * @vf: pointer to the VF info
263 * @vsi_id: vsi id
264 * @queue_id: queue number
265 *
266 * wrapper function to get pf_queue_id handling ADq code as well
267 **/
268static u16 i40e_get_real_pf_qid(struct i40e_vf *vf, u16 vsi_id, u16 queue_id)
269{
270 int i;
271
272 if (vf->adq_enabled) {
273 /* Although VF considers all the queues(can be 1 to 16) as its
274 * own but they may actually belong to different VSIs(up to 4).
275 * We need to find which queues belongs to which VSI.
276 */
277 for (i = 0; i < vf->num_tc; i++) {
278 if (queue_id < vf->ch[i].num_qps) {
279 vsi_id = vf->ch[i].vsi_id;
280 break;
281 }
282 /* find right queue id which is relative to a
283 * given VSI.
284 */
285 queue_id -= vf->ch[i].num_qps;
286 }
287 }
288
289 return i40e_vc_get_pf_queue_id(vf, vsi_id, queue_id);
290}
291
292/**
261 * i40e_config_irq_link_list 293 * i40e_config_irq_link_list
262 * @vf: pointer to the VF info 294 * @vf: pointer to the VF info
263 * @vsi_id: id of VSI as given by the FW 295 * @vsi_id: id of VSI as given by the FW
@@ -310,7 +342,7 @@ static void i40e_config_irq_link_list(struct i40e_vf *vf, u16 vsi_id,
310 342
311 vsi_queue_id = next_q / I40E_VIRTCHNL_SUPPORTED_QTYPES; 343 vsi_queue_id = next_q / I40E_VIRTCHNL_SUPPORTED_QTYPES;
312 qtype = next_q % I40E_VIRTCHNL_SUPPORTED_QTYPES; 344 qtype = next_q % I40E_VIRTCHNL_SUPPORTED_QTYPES;
313 pf_queue_id = i40e_vc_get_pf_queue_id(vf, vsi_id, vsi_queue_id); 345 pf_queue_id = i40e_get_real_pf_qid(vf, vsi_id, vsi_queue_id);
314 reg = ((qtype << I40E_VPINT_LNKLSTN_FIRSTQ_TYPE_SHIFT) | pf_queue_id); 346 reg = ((qtype << I40E_VPINT_LNKLSTN_FIRSTQ_TYPE_SHIFT) | pf_queue_id);
315 347
316 wr32(hw, reg_idx, reg); 348 wr32(hw, reg_idx, reg);
@@ -333,8 +365,9 @@ static void i40e_config_irq_link_list(struct i40e_vf *vf, u16 vsi_id,
333 if (next_q < size) { 365 if (next_q < size) {
334 vsi_queue_id = next_q / I40E_VIRTCHNL_SUPPORTED_QTYPES; 366 vsi_queue_id = next_q / I40E_VIRTCHNL_SUPPORTED_QTYPES;
335 qtype = next_q % I40E_VIRTCHNL_SUPPORTED_QTYPES; 367 qtype = next_q % I40E_VIRTCHNL_SUPPORTED_QTYPES;
336 pf_queue_id = i40e_vc_get_pf_queue_id(vf, vsi_id, 368 pf_queue_id = i40e_get_real_pf_qid(vf,
337 vsi_queue_id); 369 vsi_id,
370 vsi_queue_id);
338 } else { 371 } else {
339 pf_queue_id = I40E_QUEUE_END_OF_LIST; 372 pf_queue_id = I40E_QUEUE_END_OF_LIST;
340 qtype = 0; 373 qtype = 0;
@@ -669,18 +702,20 @@ error_param:
669/** 702/**
670 * i40e_alloc_vsi_res 703 * i40e_alloc_vsi_res
671 * @vf: pointer to the VF info 704 * @vf: pointer to the VF info
672 * @type: type of VSI to allocate 705 * @idx: VSI index, applies only for ADq mode, zero otherwise
673 * 706 *
674 * alloc VF vsi context & resources 707 * alloc VF vsi context & resources
675 **/ 708 **/
676static int i40e_alloc_vsi_res(struct i40e_vf *vf, enum i40e_vsi_type type) 709static int i40e_alloc_vsi_res(struct i40e_vf *vf, u8 idx)
677{ 710{
678 struct i40e_mac_filter *f = NULL; 711 struct i40e_mac_filter *f = NULL;
679 struct i40e_pf *pf = vf->pf; 712 struct i40e_pf *pf = vf->pf;
680 struct i40e_vsi *vsi; 713 struct i40e_vsi *vsi;
714 u64 max_tx_rate = 0;
681 int ret = 0; 715 int ret = 0;
682 716
683 vsi = i40e_vsi_setup(pf, type, pf->vsi[pf->lan_vsi]->seid, vf->vf_id); 717 vsi = i40e_vsi_setup(pf, I40E_VSI_SRIOV, pf->vsi[pf->lan_vsi]->seid,
718 vf->vf_id);
684 719
685 if (!vsi) { 720 if (!vsi) {
686 dev_err(&pf->pdev->dev, 721 dev_err(&pf->pdev->dev,
@@ -689,7 +724,8 @@ static int i40e_alloc_vsi_res(struct i40e_vf *vf, enum i40e_vsi_type type)
689 ret = -ENOENT; 724 ret = -ENOENT;
690 goto error_alloc_vsi_res; 725 goto error_alloc_vsi_res;
691 } 726 }
692 if (type == I40E_VSI_SRIOV) { 727
728 if (!idx) {
693 u64 hena = i40e_pf_get_default_rss_hena(pf); 729 u64 hena = i40e_pf_get_default_rss_hena(pf);
694 u8 broadcast[ETH_ALEN]; 730 u8 broadcast[ETH_ALEN];
695 731
@@ -721,17 +757,29 @@ static int i40e_alloc_vsi_res(struct i40e_vf *vf, enum i40e_vsi_type type)
721 spin_unlock_bh(&vsi->mac_filter_hash_lock); 757 spin_unlock_bh(&vsi->mac_filter_hash_lock);
722 wr32(&pf->hw, I40E_VFQF_HENA1(0, vf->vf_id), (u32)hena); 758 wr32(&pf->hw, I40E_VFQF_HENA1(0, vf->vf_id), (u32)hena);
723 wr32(&pf->hw, I40E_VFQF_HENA1(1, vf->vf_id), (u32)(hena >> 32)); 759 wr32(&pf->hw, I40E_VFQF_HENA1(1, vf->vf_id), (u32)(hena >> 32));
760 /* program mac filter only for VF VSI */
761 ret = i40e_sync_vsi_filters(vsi);
762 if (ret)
763 dev_err(&pf->pdev->dev, "Unable to program ucast filters\n");
724 } 764 }
725 765
726 /* program mac filter */ 766 /* storing VSI index and id for ADq and don't apply the mac filter */
727 ret = i40e_sync_vsi_filters(vsi); 767 if (vf->adq_enabled) {
728 if (ret) 768 vf->ch[idx].vsi_idx = vsi->idx;
729 dev_err(&pf->pdev->dev, "Unable to program ucast filters\n"); 769 vf->ch[idx].vsi_id = vsi->id;
770 }
730 771
731 /* Set VF bandwidth if specified */ 772 /* Set VF bandwidth if specified */
732 if (vf->tx_rate) { 773 if (vf->tx_rate) {
774 max_tx_rate = vf->tx_rate;
775 } else if (vf->ch[idx].max_tx_rate) {
776 max_tx_rate = vf->ch[idx].max_tx_rate;
777 }
778
779 if (max_tx_rate) {
780 max_tx_rate = div_u64(max_tx_rate, I40E_BW_CREDIT_DIVISOR);
733 ret = i40e_aq_config_vsi_bw_limit(&pf->hw, vsi->seid, 781 ret = i40e_aq_config_vsi_bw_limit(&pf->hw, vsi->seid,
734 vf->tx_rate / 50, 0, NULL); 782 max_tx_rate, 0, NULL);
735 if (ret) 783 if (ret)
736 dev_err(&pf->pdev->dev, "Unable to set tx rate, VF %d, error code %d.\n", 784 dev_err(&pf->pdev->dev, "Unable to set tx rate, VF %d, error code %d.\n",
737 vf->vf_id, ret); 785 vf->vf_id, ret);
@@ -742,6 +790,92 @@ error_alloc_vsi_res:
742} 790}
743 791
744/** 792/**
793 * i40e_map_pf_queues_to_vsi
794 * @vf: pointer to the VF info
795 *
796 * PF maps LQPs to a VF by programming VSILAN_QTABLE & VPLAN_QTABLE. This
797 * function takes care of first part VSILAN_QTABLE, mapping pf queues to VSI.
798 **/
799static void i40e_map_pf_queues_to_vsi(struct i40e_vf *vf)
800{
801 struct i40e_pf *pf = vf->pf;
802 struct i40e_hw *hw = &pf->hw;
803 u32 reg, num_tc = 1; /* VF has at least one traffic class */
804 u16 vsi_id, qps;
805 int i, j;
806
807 if (vf->adq_enabled)
808 num_tc = vf->num_tc;
809
810 for (i = 0; i < num_tc; i++) {
811 if (vf->adq_enabled) {
812 qps = vf->ch[i].num_qps;
813 vsi_id = vf->ch[i].vsi_id;
814 } else {
815 qps = pf->vsi[vf->lan_vsi_idx]->alloc_queue_pairs;
816 vsi_id = vf->lan_vsi_id;
817 }
818
819 for (j = 0; j < 7; j++) {
820 if (j * 2 >= qps) {
821 /* end of list */
822 reg = 0x07FF07FF;
823 } else {
824 u16 qid = i40e_vc_get_pf_queue_id(vf,
825 vsi_id,
826 j * 2);
827 reg = qid;
828 qid = i40e_vc_get_pf_queue_id(vf, vsi_id,
829 (j * 2) + 1);
830 reg |= qid << 16;
831 }
832 i40e_write_rx_ctl(hw,
833 I40E_VSILAN_QTABLE(j, vsi_id),
834 reg);
835 }
836 }
837}
838
839/**
840 * i40e_map_pf_to_vf_queues
841 * @vf: pointer to the VF info
842 *
843 * PF maps LQPs to a VF by programming VSILAN_QTABLE & VPLAN_QTABLE. This
844 * function takes care of the second part VPLAN_QTABLE & completes VF mappings.
845 **/
846static void i40e_map_pf_to_vf_queues(struct i40e_vf *vf)
847{
848 struct i40e_pf *pf = vf->pf;
849 struct i40e_hw *hw = &pf->hw;
850 u32 reg, total_qps = 0;
851 u32 qps, num_tc = 1; /* VF has at least one traffic class */
852 u16 vsi_id, qid;
853 int i, j;
854
855 if (vf->adq_enabled)
856 num_tc = vf->num_tc;
857
858 for (i = 0; i < num_tc; i++) {
859 if (vf->adq_enabled) {
860 qps = vf->ch[i].num_qps;
861 vsi_id = vf->ch[i].vsi_id;
862 } else {
863 qps = pf->vsi[vf->lan_vsi_idx]->alloc_queue_pairs;
864 vsi_id = vf->lan_vsi_id;
865 }
866
867 for (j = 0; j < qps; j++) {
868 qid = i40e_vc_get_pf_queue_id(vf, vsi_id, j);
869
870 reg = (qid & I40E_VPLAN_QTABLE_QINDEX_MASK);
871 wr32(hw, I40E_VPLAN_QTABLE(total_qps, vf->vf_id),
872 reg);
873 total_qps++;
874 }
875 }
876}
877
878/**
745 * i40e_enable_vf_mappings 879 * i40e_enable_vf_mappings
746 * @vf: pointer to the VF info 880 * @vf: pointer to the VF info
747 * 881 *
@@ -751,8 +885,7 @@ static void i40e_enable_vf_mappings(struct i40e_vf *vf)
751{ 885{
752 struct i40e_pf *pf = vf->pf; 886 struct i40e_pf *pf = vf->pf;
753 struct i40e_hw *hw = &pf->hw; 887 struct i40e_hw *hw = &pf->hw;
754 u32 reg, total_queue_pairs = 0; 888 u32 reg;
755 int j;
756 889
757 /* Tell the hardware we're using noncontiguous mapping. HW requires 890 /* Tell the hardware we're using noncontiguous mapping. HW requires
758 * that VF queues be mapped using this method, even when they are 891 * that VF queues be mapped using this method, even when they are
@@ -765,30 +898,8 @@ static void i40e_enable_vf_mappings(struct i40e_vf *vf)
765 reg = I40E_VPLAN_MAPENA_TXRX_ENA_MASK; 898 reg = I40E_VPLAN_MAPENA_TXRX_ENA_MASK;
766 wr32(hw, I40E_VPLAN_MAPENA(vf->vf_id), reg); 899 wr32(hw, I40E_VPLAN_MAPENA(vf->vf_id), reg);
767 900
768 /* map PF queues to VF queues */ 901 i40e_map_pf_to_vf_queues(vf);
769 for (j = 0; j < pf->vsi[vf->lan_vsi_idx]->alloc_queue_pairs; j++) { 902 i40e_map_pf_queues_to_vsi(vf);
770 u16 qid = i40e_vc_get_pf_queue_id(vf, vf->lan_vsi_id, j);
771
772 reg = (qid & I40E_VPLAN_QTABLE_QINDEX_MASK);
773 wr32(hw, I40E_VPLAN_QTABLE(total_queue_pairs, vf->vf_id), reg);
774 total_queue_pairs++;
775 }
776
777 /* map PF queues to VSI */
778 for (j = 0; j < 7; j++) {
779 if (j * 2 >= pf->vsi[vf->lan_vsi_idx]->alloc_queue_pairs) {
780 reg = 0x07FF07FF; /* unused */
781 } else {
782 u16 qid = i40e_vc_get_pf_queue_id(vf, vf->lan_vsi_id,
783 j * 2);
784 reg = qid;
785 qid = i40e_vc_get_pf_queue_id(vf, vf->lan_vsi_id,
786 (j * 2) + 1);
787 reg |= qid << 16;
788 }
789 i40e_write_rx_ctl(hw, I40E_VSILAN_QTABLE(j, vf->lan_vsi_id),
790 reg);
791 }
792 903
793 i40e_flush(hw); 904 i40e_flush(hw);
794} 905}
@@ -824,7 +935,7 @@ static void i40e_free_vf_res(struct i40e_vf *vf)
824 struct i40e_pf *pf = vf->pf; 935 struct i40e_pf *pf = vf->pf;
825 struct i40e_hw *hw = &pf->hw; 936 struct i40e_hw *hw = &pf->hw;
826 u32 reg_idx, reg; 937 u32 reg_idx, reg;
827 int i, msix_vf; 938 int i, j, msix_vf;
828 939
829 /* Start by disabling VF's configuration API to prevent the OS from 940 /* Start by disabling VF's configuration API to prevent the OS from
830 * accessing the VF's VSI after it's freed / invalidated. 941 * accessing the VF's VSI after it's freed / invalidated.
@@ -846,6 +957,20 @@ static void i40e_free_vf_res(struct i40e_vf *vf)
846 vf->lan_vsi_id = 0; 957 vf->lan_vsi_id = 0;
847 vf->num_mac = 0; 958 vf->num_mac = 0;
848 } 959 }
960
961 /* do the accounting and remove additional ADq VSI's */
962 if (vf->adq_enabled && vf->ch[0].vsi_idx) {
963 for (j = 0; j < vf->num_tc; j++) {
964 /* At this point VSI0 is already released so don't
965 * release it again and only clear their values in
966 * structure variables
967 */
968 if (j)
969 i40e_vsi_release(pf->vsi[vf->ch[j].vsi_idx]);
970 vf->ch[j].vsi_idx = 0;
971 vf->ch[j].vsi_id = 0;
972 }
973 }
849 msix_vf = pf->hw.func_caps.num_msix_vectors_vf; 974 msix_vf = pf->hw.func_caps.num_msix_vectors_vf;
850 975
851 /* disable interrupts so the VF starts in a known state */ 976 /* disable interrupts so the VF starts in a known state */
@@ -891,7 +1016,7 @@ static int i40e_alloc_vf_res(struct i40e_vf *vf)
891{ 1016{
892 struct i40e_pf *pf = vf->pf; 1017 struct i40e_pf *pf = vf->pf;
893 int total_queue_pairs = 0; 1018 int total_queue_pairs = 0;
894 int ret; 1019 int ret, idx;
895 1020
896 if (vf->num_req_queues && 1021 if (vf->num_req_queues &&
897 vf->num_req_queues <= pf->queues_left + I40E_DEFAULT_QUEUES_PER_VF) 1022 vf->num_req_queues <= pf->queues_left + I40E_DEFAULT_QUEUES_PER_VF)
@@ -900,11 +1025,30 @@ static int i40e_alloc_vf_res(struct i40e_vf *vf)
900 pf->num_vf_qps = I40E_DEFAULT_QUEUES_PER_VF; 1025 pf->num_vf_qps = I40E_DEFAULT_QUEUES_PER_VF;
901 1026
902 /* allocate hw vsi context & associated resources */ 1027 /* allocate hw vsi context & associated resources */
903 ret = i40e_alloc_vsi_res(vf, I40E_VSI_SRIOV); 1028 ret = i40e_alloc_vsi_res(vf, 0);
904 if (ret) 1029 if (ret)
905 goto error_alloc; 1030 goto error_alloc;
906 total_queue_pairs += pf->vsi[vf->lan_vsi_idx]->alloc_queue_pairs; 1031 total_queue_pairs += pf->vsi[vf->lan_vsi_idx]->alloc_queue_pairs;
907 1032
1033 /* allocate additional VSIs based on tc information for ADq */
1034 if (vf->adq_enabled) {
1035 if (pf->queues_left >=
1036 (I40E_MAX_VF_QUEUES - I40E_DEFAULT_QUEUES_PER_VF)) {
1037 /* TC 0 always belongs to VF VSI */
1038 for (idx = 1; idx < vf->num_tc; idx++) {
1039 ret = i40e_alloc_vsi_res(vf, idx);
1040 if (ret)
1041 goto error_alloc;
1042 }
1043 /* send correct number of queues */
1044 total_queue_pairs = I40E_MAX_VF_QUEUES;
1045 } else {
1046 dev_info(&pf->pdev->dev, "VF %d: Not enough queues to allocate, disabling ADq\n",
1047 vf->vf_id);
1048 vf->adq_enabled = false;
1049 }
1050 }
1051
908 /* We account for each VF to get a default number of queue pairs. If 1052 /* We account for each VF to get a default number of queue pairs. If
909 * the VF has now requested more, we need to account for that to make 1053 * the VF has now requested more, we need to account for that to make
910 * certain we never request more queues than we actually have left in 1054 * certain we never request more queues than we actually have left in
@@ -1537,6 +1681,27 @@ static int i40e_vc_get_version_msg(struct i40e_vf *vf, u8 *msg)
1537} 1681}
1538 1682
1539/** 1683/**
1684 * i40e_del_qch - delete all the additional VSIs created as a part of ADq
1685 * @vf: pointer to VF structure
1686 **/
1687static void i40e_del_qch(struct i40e_vf *vf)
1688{
1689 struct i40e_pf *pf = vf->pf;
1690 int i;
1691
1692 /* first element in the array belongs to primary VF VSI and we shouldn't
1693 * delete it. We should however delete the rest of the VSIs created
1694 */
1695 for (i = 1; i < vf->num_tc; i++) {
1696 if (vf->ch[i].vsi_idx) {
1697 i40e_vsi_release(pf->vsi[vf->ch[i].vsi_idx]);
1698 vf->ch[i].vsi_idx = 0;
1699 vf->ch[i].vsi_id = 0;
1700 }
1701 }
1702}
1703
1704/**
1540 * i40e_vc_get_vf_resources_msg 1705 * i40e_vc_get_vf_resources_msg
1541 * @vf: pointer to the VF info 1706 * @vf: pointer to the VF info
1542 * @msg: pointer to the msg buffer 1707 * @msg: pointer to the msg buffer
@@ -1631,6 +1796,9 @@ static int i40e_vc_get_vf_resources_msg(struct i40e_vf *vf, u8 *msg)
1631 if (vf->driver_caps & VIRTCHNL_VF_OFFLOAD_REQ_QUEUES) 1796 if (vf->driver_caps & VIRTCHNL_VF_OFFLOAD_REQ_QUEUES)
1632 vfres->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_REQ_QUEUES; 1797 vfres->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_REQ_QUEUES;
1633 1798
1799 if (vf->driver_caps & VIRTCHNL_VF_OFFLOAD_ADQ)
1800 vfres->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_ADQ;
1801
1634 vfres->num_vsis = num_vsis; 1802 vfres->num_vsis = num_vsis;
1635 vfres->num_queue_pairs = vf->num_queue_pairs; 1803 vfres->num_queue_pairs = vf->num_queue_pairs;
1636 vfres->max_vectors = pf->hw.func_caps.num_msix_vectors_vf; 1804 vfres->max_vectors = pf->hw.func_caps.num_msix_vectors_vf;
@@ -1855,27 +2023,37 @@ static int i40e_vc_config_queues_msg(struct i40e_vf *vf, u8 *msg, u16 msglen)
1855 (struct virtchnl_vsi_queue_config_info *)msg; 2023 (struct virtchnl_vsi_queue_config_info *)msg;
1856 struct virtchnl_queue_pair_info *qpi; 2024 struct virtchnl_queue_pair_info *qpi;
1857 struct i40e_pf *pf = vf->pf; 2025 struct i40e_pf *pf = vf->pf;
1858 u16 vsi_id, vsi_queue_id; 2026 u16 vsi_id, vsi_queue_id = 0;
1859 i40e_status aq_ret = 0; 2027 i40e_status aq_ret = 0;
1860 int i; 2028 int i, j = 0, idx = 0;
2029
2030 vsi_id = qci->vsi_id;
1861 2031
1862 if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { 2032 if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) {
1863 aq_ret = I40E_ERR_PARAM; 2033 aq_ret = I40E_ERR_PARAM;
1864 goto error_param; 2034 goto error_param;
1865 } 2035 }
1866 2036
1867 vsi_id = qci->vsi_id;
1868 if (!i40e_vc_isvalid_vsi_id(vf, vsi_id)) { 2037 if (!i40e_vc_isvalid_vsi_id(vf, vsi_id)) {
1869 aq_ret = I40E_ERR_PARAM; 2038 aq_ret = I40E_ERR_PARAM;
1870 goto error_param; 2039 goto error_param;
1871 } 2040 }
2041
1872 for (i = 0; i < qci->num_queue_pairs; i++) { 2042 for (i = 0; i < qci->num_queue_pairs; i++) {
1873 qpi = &qci->qpair[i]; 2043 qpi = &qci->qpair[i];
1874 vsi_queue_id = qpi->txq.queue_id; 2044
1875 if ((qpi->txq.vsi_id != vsi_id) || 2045 if (!vf->adq_enabled) {
1876 (qpi->rxq.vsi_id != vsi_id) || 2046 vsi_queue_id = qpi->txq.queue_id;
1877 (qpi->rxq.queue_id != vsi_queue_id) || 2047
1878 !i40e_vc_isvalid_queue_id(vf, vsi_id, vsi_queue_id)) { 2048 if (qpi->txq.vsi_id != qci->vsi_id ||
2049 qpi->rxq.vsi_id != qci->vsi_id ||
2050 qpi->rxq.queue_id != vsi_queue_id) {
2051 aq_ret = I40E_ERR_PARAM;
2052 goto error_param;
2053 }
2054 }
2055
2056 if (!i40e_vc_isvalid_queue_id(vf, vsi_id, vsi_queue_id)) {
1879 aq_ret = I40E_ERR_PARAM; 2057 aq_ret = I40E_ERR_PARAM;
1880 goto error_param; 2058 goto error_param;
1881 } 2059 }
@@ -1887,9 +2065,33 @@ static int i40e_vc_config_queues_msg(struct i40e_vf *vf, u8 *msg, u16 msglen)
1887 aq_ret = I40E_ERR_PARAM; 2065 aq_ret = I40E_ERR_PARAM;
1888 goto error_param; 2066 goto error_param;
1889 } 2067 }
2068
2069 /* For ADq there can be up to 4 VSIs with max 4 queues each.
2070 * VF does not know about these additional VSIs and all
2071 * it cares is about its own queues. PF configures these queues
2072 * to its appropriate VSIs based on TC mapping
2073 **/
2074 if (vf->adq_enabled) {
2075 if (j == (vf->ch[idx].num_qps - 1)) {
2076 idx++;
2077 j = 0; /* resetting the queue count */
2078 vsi_queue_id = 0;
2079 } else {
2080 j++;
2081 vsi_queue_id++;
2082 }
2083 vsi_id = vf->ch[idx].vsi_id;
2084 }
1890 } 2085 }
1891 /* set vsi num_queue_pairs in use to num configured by VF */ 2086 /* set vsi num_queue_pairs in use to num configured by VF */
1892 pf->vsi[vf->lan_vsi_idx]->num_queue_pairs = qci->num_queue_pairs; 2087 if (!vf->adq_enabled) {
2088 pf->vsi[vf->lan_vsi_idx]->num_queue_pairs =
2089 qci->num_queue_pairs;
2090 } else {
2091 for (i = 0; i < vf->num_tc; i++)
2092 pf->vsi[vf->ch[i].vsi_idx]->num_queue_pairs =
2093 vf->ch[i].num_qps;
2094 }
1893 2095
1894error_param: 2096error_param:
1895 /* send the response to the VF */ 2097 /* send the response to the VF */
@@ -1898,6 +2100,33 @@ error_param:
1898} 2100}
1899 2101
1900/** 2102/**
2103 * i40e_validate_queue_map
2104 * @vsi_id: vsi id
2105 * @queuemap: Tx or Rx queue map
2106 *
2107 * check if Tx or Rx queue map is valid
2108 **/
2109static int i40e_validate_queue_map(struct i40e_vf *vf, u16 vsi_id,
2110 unsigned long queuemap)
2111{
2112 u16 vsi_queue_id, queue_id;
2113
2114 for_each_set_bit(vsi_queue_id, &queuemap, I40E_MAX_VSI_QP) {
2115 if (vf->adq_enabled) {
2116 vsi_id = vf->ch[vsi_queue_id / I40E_MAX_VF_VSI].vsi_id;
2117 queue_id = (vsi_queue_id % I40E_DEFAULT_QUEUES_PER_VF);
2118 } else {
2119 queue_id = vsi_queue_id;
2120 }
2121
2122 if (!i40e_vc_isvalid_queue_id(vf, vsi_id, queue_id))
2123 return -EINVAL;
2124 }
2125
2126 return 0;
2127}
2128
2129/**
1901 * i40e_vc_config_irq_map_msg 2130 * i40e_vc_config_irq_map_msg
1902 * @vf: pointer to the VF info 2131 * @vf: pointer to the VF info
1903 * @msg: pointer to the msg buffer 2132 * @msg: pointer to the msg buffer
@@ -1911,9 +2140,8 @@ static int i40e_vc_config_irq_map_msg(struct i40e_vf *vf, u8 *msg, u16 msglen)
1911 struct virtchnl_irq_map_info *irqmap_info = 2140 struct virtchnl_irq_map_info *irqmap_info =
1912 (struct virtchnl_irq_map_info *)msg; 2141 (struct virtchnl_irq_map_info *)msg;
1913 struct virtchnl_vector_map *map; 2142 struct virtchnl_vector_map *map;
1914 u16 vsi_id, vsi_queue_id, vector_id; 2143 u16 vsi_id, vector_id;
1915 i40e_status aq_ret = 0; 2144 i40e_status aq_ret = 0;
1916 unsigned long tempmap;
1917 int i; 2145 int i;
1918 2146
1919 if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { 2147 if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) {
@@ -1923,7 +2151,6 @@ static int i40e_vc_config_irq_map_msg(struct i40e_vf *vf, u8 *msg, u16 msglen)
1923 2151
1924 for (i = 0; i < irqmap_info->num_vectors; i++) { 2152 for (i = 0; i < irqmap_info->num_vectors; i++) {
1925 map = &irqmap_info->vecmap[i]; 2153 map = &irqmap_info->vecmap[i];
1926
1927 vector_id = map->vector_id; 2154 vector_id = map->vector_id;
1928 vsi_id = map->vsi_id; 2155 vsi_id = map->vsi_id;
1929 /* validate msg params */ 2156 /* validate msg params */
@@ -1933,23 +2160,14 @@ static int i40e_vc_config_irq_map_msg(struct i40e_vf *vf, u8 *msg, u16 msglen)
1933 goto error_param; 2160 goto error_param;
1934 } 2161 }
1935 2162
1936 /* lookout for the invalid queue index */ 2163 if (i40e_validate_queue_map(vf, vsi_id, map->rxq_map)) {
1937 tempmap = map->rxq_map; 2164 aq_ret = I40E_ERR_PARAM;
1938 for_each_set_bit(vsi_queue_id, &tempmap, I40E_MAX_VSI_QP) { 2165 goto error_param;
1939 if (!i40e_vc_isvalid_queue_id(vf, vsi_id,
1940 vsi_queue_id)) {
1941 aq_ret = I40E_ERR_PARAM;
1942 goto error_param;
1943 }
1944 } 2166 }
1945 2167
1946 tempmap = map->txq_map; 2168 if (i40e_validate_queue_map(vf, vsi_id, map->txq_map)) {
1947 for_each_set_bit(vsi_queue_id, &tempmap, I40E_MAX_VSI_QP) { 2169 aq_ret = I40E_ERR_PARAM;
1948 if (!i40e_vc_isvalid_queue_id(vf, vsi_id, 2170 goto error_param;
1949 vsi_queue_id)) {
1950 aq_ret = I40E_ERR_PARAM;
1951 goto error_param;
1952 }
1953 } 2171 }
1954 2172
1955 i40e_config_irq_link_list(vf, vsi_id, map); 2173 i40e_config_irq_link_list(vf, vsi_id, map);
@@ -1975,6 +2193,7 @@ static int i40e_vc_enable_queues_msg(struct i40e_vf *vf, u8 *msg, u16 msglen)
1975 struct i40e_pf *pf = vf->pf; 2193 struct i40e_pf *pf = vf->pf;
1976 u16 vsi_id = vqs->vsi_id; 2194 u16 vsi_id = vqs->vsi_id;
1977 i40e_status aq_ret = 0; 2195 i40e_status aq_ret = 0;
2196 int i;
1978 2197
1979 if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { 2198 if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) {
1980 aq_ret = I40E_ERR_PARAM; 2199 aq_ret = I40E_ERR_PARAM;
@@ -1993,6 +2212,16 @@ static int i40e_vc_enable_queues_msg(struct i40e_vf *vf, u8 *msg, u16 msglen)
1993 2212
1994 if (i40e_vsi_start_rings(pf->vsi[vf->lan_vsi_idx])) 2213 if (i40e_vsi_start_rings(pf->vsi[vf->lan_vsi_idx]))
1995 aq_ret = I40E_ERR_TIMEOUT; 2214 aq_ret = I40E_ERR_TIMEOUT;
2215
2216 /* need to start the rings for additional ADq VSI's as well */
2217 if (vf->adq_enabled) {
2218 /* zero belongs to LAN VSI */
2219 for (i = 1; i < vf->num_tc; i++) {
2220 if (i40e_vsi_start_rings(pf->vsi[vf->ch[i].vsi_idx]))
2221 aq_ret = I40E_ERR_TIMEOUT;
2222 }
2223 }
2224
1996error_param: 2225error_param:
1997 /* send the response to the VF */ 2226 /* send the response to the VF */
1998 return i40e_vc_send_resp_to_vf(vf, VIRTCHNL_OP_ENABLE_QUEUES, 2227 return i40e_vc_send_resp_to_vf(vf, VIRTCHNL_OP_ENABLE_QUEUES,
@@ -2139,25 +2368,47 @@ error_param:
2139/** 2368/**
2140 * i40e_check_vf_permission 2369 * i40e_check_vf_permission
2141 * @vf: pointer to the VF info 2370 * @vf: pointer to the VF info
2142 * @macaddr: pointer to the MAC Address being checked 2371 * @al: MAC address list from virtchnl
2143 * 2372 *
2144 * Check if the VF has permission to add or delete unicast MAC address 2373 * Check that the given list of MAC addresses is allowed. Will return -EPERM
2145 * filters and return error code -EPERM if not. Then check if the 2374 * if any address in the list is not valid. Checks the following conditions:
2146 * address filter requested is broadcast or zero and if so return 2375 *
2147 * an invalid MAC address error code. 2376 * 1) broadcast and zero addresses are never valid
2377 * 2) unicast addresses are not allowed if the VMM has administratively set
2378 * the VF MAC address, unless the VF is marked as privileged.
2379 * 3) There is enough space to add all the addresses.
2380 *
2381 * Note that to guarantee consistency, it is expected this function be called
2382 * while holding the mac_filter_hash_lock, as otherwise the current number of
2383 * addresses might not be accurate.
2148 **/ 2384 **/
2149static inline int i40e_check_vf_permission(struct i40e_vf *vf, u8 *macaddr) 2385static inline int i40e_check_vf_permission(struct i40e_vf *vf,
2386 struct virtchnl_ether_addr_list *al)
2150{ 2387{
2151 struct i40e_pf *pf = vf->pf; 2388 struct i40e_pf *pf = vf->pf;
2152 int ret = 0; 2389 int i;
2390
2391 /* If this VF is not privileged, then we can't add more than a limited
2392 * number of addresses. Check to make sure that the additions do not
2393 * push us over the limit.
2394 */
2395 if (!test_bit(I40E_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps) &&
2396 (vf->num_mac + al->num_elements) > I40E_VC_MAX_MAC_ADDR_PER_VF) {
2397 dev_err(&pf->pdev->dev,
2398 "Cannot add more MAC addresses, VF is not trusted, switch the VF to trusted to add more functionality\n");
2399 return -EPERM;
2400 }
2401
2402 for (i = 0; i < al->num_elements; i++) {
2403 u8 *addr = al->list[i].addr;
2404
2405 if (is_broadcast_ether_addr(addr) ||
2406 is_zero_ether_addr(addr)) {
2407 dev_err(&pf->pdev->dev, "invalid VF MAC addr %pM\n",
2408 addr);
2409 return I40E_ERR_INVALID_MAC_ADDR;
2410 }
2153 2411
2154 if (is_broadcast_ether_addr(macaddr) ||
2155 is_zero_ether_addr(macaddr)) {
2156 dev_err(&pf->pdev->dev, "invalid VF MAC addr %pM\n", macaddr);
2157 ret = I40E_ERR_INVALID_MAC_ADDR;
2158 } else if (vf->pf_set_mac && !is_multicast_ether_addr(macaddr) &&
2159 !test_bit(I40E_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps) &&
2160 !ether_addr_equal(macaddr, vf->default_lan_addr.addr)) {
2161 /* If the host VMM administrator has set the VF MAC address 2412 /* If the host VMM administrator has set the VF MAC address
2162 * administratively via the ndo_set_vf_mac command then deny 2413 * administratively via the ndo_set_vf_mac command then deny
2163 * permission to the VF to add or delete unicast MAC addresses. 2414 * permission to the VF to add or delete unicast MAC addresses.
@@ -2165,16 +2416,16 @@ static inline int i40e_check_vf_permission(struct i40e_vf *vf, u8 *macaddr)
2165 * The VF may request to set the MAC address filter already 2416 * The VF may request to set the MAC address filter already
2166 * assigned to it so do not return an error in that case. 2417 * assigned to it so do not return an error in that case.
2167 */ 2418 */
2168 dev_err(&pf->pdev->dev, 2419 if (!test_bit(I40E_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps) &&
2169 "VF attempting to override administratively set MAC address, reload the VF driver to resume normal operation\n"); 2420 !is_multicast_ether_addr(addr) && vf->pf_set_mac &&
2170 ret = -EPERM; 2421 !ether_addr_equal(addr, vf->default_lan_addr.addr)) {
2171 } else if ((vf->num_mac >= I40E_VC_MAX_MAC_ADDR_PER_VF) && 2422 dev_err(&pf->pdev->dev,
2172 !test_bit(I40E_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps)) { 2423 "VF attempting to override administratively set MAC address, reload the VF driver to resume normal operation\n");
2173 dev_err(&pf->pdev->dev, 2424 return -EPERM;
2174 "VF is not trusted, switch the VF to trusted to add more functionality\n"); 2425 }
2175 ret = -EPERM;
2176 } 2426 }
2177 return ret; 2427
2428 return 0;
2178} 2429}
2179 2430
2180/** 2431/**
@@ -2201,11 +2452,6 @@ static int i40e_vc_add_mac_addr_msg(struct i40e_vf *vf, u8 *msg, u16 msglen)
2201 goto error_param; 2452 goto error_param;
2202 } 2453 }
2203 2454
2204 for (i = 0; i < al->num_elements; i++) {
2205 ret = i40e_check_vf_permission(vf, al->list[i].addr);
2206 if (ret)
2207 goto error_param;
2208 }
2209 vsi = pf->vsi[vf->lan_vsi_idx]; 2455 vsi = pf->vsi[vf->lan_vsi_idx];
2210 2456
2211 /* Lock once, because all function inside for loop accesses VSI's 2457 /* Lock once, because all function inside for loop accesses VSI's
@@ -2213,6 +2459,12 @@ static int i40e_vc_add_mac_addr_msg(struct i40e_vf *vf, u8 *msg, u16 msglen)
2213 */ 2459 */
2214 spin_lock_bh(&vsi->mac_filter_hash_lock); 2460 spin_lock_bh(&vsi->mac_filter_hash_lock);
2215 2461
2462 ret = i40e_check_vf_permission(vf, al);
2463 if (ret) {
2464 spin_unlock_bh(&vsi->mac_filter_hash_lock);
2465 goto error_param;
2466 }
2467
2216 /* add new addresses to the list */ 2468 /* add new addresses to the list */
2217 for (i = 0; i < al->num_elements; i++) { 2469 for (i = 0; i < al->num_elements; i++) {
2218 struct i40e_mac_filter *f; 2470 struct i40e_mac_filter *f;
@@ -2688,6 +2940,618 @@ err:
2688} 2940}
2689 2941
2690/** 2942/**
2943 * i40e_validate_cloud_filter
2944 * @mask: mask for TC filter
2945 * @data: data for TC filter
2946 *
2947 * This function validates cloud filter programmed as TC filter for ADq
2948 **/
2949static int i40e_validate_cloud_filter(struct i40e_vf *vf,
2950 struct virtchnl_filter *tc_filter)
2951{
2952 struct virtchnl_l4_spec mask = tc_filter->mask.tcp_spec;
2953 struct virtchnl_l4_spec data = tc_filter->data.tcp_spec;
2954 struct i40e_pf *pf = vf->pf;
2955 struct i40e_vsi *vsi = NULL;
2956 struct i40e_mac_filter *f;
2957 struct hlist_node *h;
2958 bool found = false;
2959 int bkt;
2960
2961 if (!tc_filter->action) {
2962 dev_info(&pf->pdev->dev,
2963 "VF %d: Currently ADq doesn't support Drop Action\n",
2964 vf->vf_id);
2965 goto err;
2966 }
2967
2968 /* action_meta is TC number here to which the filter is applied */
2969 if (!tc_filter->action_meta ||
2970 tc_filter->action_meta > I40E_MAX_VF_VSI) {
2971 dev_info(&pf->pdev->dev, "VF %d: Invalid TC number %u\n",
2972 vf->vf_id, tc_filter->action_meta);
2973 goto err;
2974 }
2975
2976 /* Check filter if it's programmed for advanced mode or basic mode.
2977 * There are two ADq modes (for VF only),
2978 * 1. Basic mode: intended to allow as many filter options as possible
2979 * to be added to a VF in Non-trusted mode. Main goal is
2980 * to add filters to its own MAC and VLAN id.
2981 * 2. Advanced mode: is for allowing filters to be applied other than
2982 * its own MAC or VLAN. This mode requires the VF to be
2983 * Trusted.
2984 */
2985 if (mask.dst_mac[0] && !mask.dst_ip[0]) {
2986 vsi = pf->vsi[vf->lan_vsi_idx];
2987 f = i40e_find_mac(vsi, data.dst_mac);
2988
2989 if (!f) {
2990 dev_info(&pf->pdev->dev,
2991 "Destination MAC %pM doesn't belong to VF %d\n",
2992 data.dst_mac, vf->vf_id);
2993 goto err;
2994 }
2995
2996 if (mask.vlan_id) {
2997 hash_for_each_safe(vsi->mac_filter_hash, bkt, h, f,
2998 hlist) {
2999 if (f->vlan == ntohs(data.vlan_id)) {
3000 found = true;
3001 break;
3002 }
3003 }
3004 if (!found) {
3005 dev_info(&pf->pdev->dev,
3006 "VF %d doesn't have any VLAN id %u\n",
3007 vf->vf_id, ntohs(data.vlan_id));
3008 goto err;
3009 }
3010 }
3011 } else {
3012 /* Check if VF is trusted */
3013 if (!test_bit(I40E_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps)) {
3014 dev_err(&pf->pdev->dev,
3015 "VF %d not trusted, make VF trusted to add advanced mode ADq cloud filters\n",
3016 vf->vf_id);
3017 return I40E_ERR_CONFIG;
3018 }
3019 }
3020
3021 if (mask.dst_mac[0] & data.dst_mac[0]) {
3022 if (is_broadcast_ether_addr(data.dst_mac) ||
3023 is_zero_ether_addr(data.dst_mac)) {
3024 dev_info(&pf->pdev->dev, "VF %d: Invalid Dest MAC addr %pM\n",
3025 vf->vf_id, data.dst_mac);
3026 goto err;
3027 }
3028 }
3029
3030 if (mask.src_mac[0] & data.src_mac[0]) {
3031 if (is_broadcast_ether_addr(data.src_mac) ||
3032 is_zero_ether_addr(data.src_mac)) {
3033 dev_info(&pf->pdev->dev, "VF %d: Invalid Source MAC addr %pM\n",
3034 vf->vf_id, data.src_mac);
3035 goto err;
3036 }
3037 }
3038
3039 if (mask.dst_port & data.dst_port) {
3040 if (!data.dst_port || be16_to_cpu(data.dst_port) > 0xFFFF) {
3041 dev_info(&pf->pdev->dev, "VF %d: Invalid Dest port\n",
3042 vf->vf_id);
3043 goto err;
3044 }
3045 }
3046
3047 if (mask.src_port & data.src_port) {
3048 if (!data.src_port || be16_to_cpu(data.src_port) > 0xFFFF) {
3049 dev_info(&pf->pdev->dev, "VF %d: Invalid Source port\n",
3050 vf->vf_id);
3051 goto err;
3052 }
3053 }
3054
3055 if (tc_filter->flow_type != VIRTCHNL_TCP_V6_FLOW &&
3056 tc_filter->flow_type != VIRTCHNL_TCP_V4_FLOW) {
3057 dev_info(&pf->pdev->dev, "VF %d: Invalid Flow type\n",
3058 vf->vf_id);
3059 goto err;
3060 }
3061
3062 if (mask.vlan_id & data.vlan_id) {
3063 if (ntohs(data.vlan_id) > I40E_MAX_VLANID) {
3064 dev_info(&pf->pdev->dev, "VF %d: invalid VLAN ID\n",
3065 vf->vf_id);
3066 goto err;
3067 }
3068 }
3069
3070 return I40E_SUCCESS;
3071err:
3072 return I40E_ERR_CONFIG;
3073}
3074
3075/**
3076 * i40e_find_vsi_from_seid - searches for the vsi with the given seid
3077 * @vf: pointer to the VF info
3078 * @seid - seid of the vsi it is searching for
3079 **/
3080static struct i40e_vsi *i40e_find_vsi_from_seid(struct i40e_vf *vf, u16 seid)
3081{
3082 struct i40e_pf *pf = vf->pf;
3083 struct i40e_vsi *vsi = NULL;
3084 int i;
3085
3086 for (i = 0; i < vf->num_tc ; i++) {
3087 vsi = i40e_find_vsi_from_id(pf, vf->ch[i].vsi_id);
3088 if (vsi && vsi->seid == seid)
3089 return vsi;
3090 }
3091 return NULL;
3092}
3093
3094/**
3095 * i40e_del_all_cloud_filters
3096 * @vf: pointer to the VF info
3097 *
3098 * This function deletes all cloud filters
3099 **/
3100static void i40e_del_all_cloud_filters(struct i40e_vf *vf)
3101{
3102 struct i40e_cloud_filter *cfilter = NULL;
3103 struct i40e_pf *pf = vf->pf;
3104 struct i40e_vsi *vsi = NULL;
3105 struct hlist_node *node;
3106 int ret;
3107
3108 hlist_for_each_entry_safe(cfilter, node,
3109 &vf->cloud_filter_list, cloud_node) {
3110 vsi = i40e_find_vsi_from_seid(vf, cfilter->seid);
3111
3112 if (!vsi) {
3113 dev_err(&pf->pdev->dev, "VF %d: no VSI found for matching %u seid, can't delete cloud filter\n",
3114 vf->vf_id, cfilter->seid);
3115 continue;
3116 }
3117
3118 if (cfilter->dst_port)
3119 ret = i40e_add_del_cloud_filter_big_buf(vsi, cfilter,
3120 false);
3121 else
3122 ret = i40e_add_del_cloud_filter(vsi, cfilter, false);
3123 if (ret)
3124 dev_err(&pf->pdev->dev,
3125 "VF %d: Failed to delete cloud filter, err %s aq_err %s\n",
3126 vf->vf_id, i40e_stat_str(&pf->hw, ret),
3127 i40e_aq_str(&pf->hw,
3128 pf->hw.aq.asq_last_status));
3129
3130 hlist_del(&cfilter->cloud_node);
3131 kfree(cfilter);
3132 vf->num_cloud_filters--;
3133 }
3134}
3135
3136/**
3137 * i40e_vc_del_cloud_filter
3138 * @vf: pointer to the VF info
3139 * @msg: pointer to the msg buffer
3140 *
3141 * This function deletes a cloud filter programmed as TC filter for ADq
3142 **/
3143static int i40e_vc_del_cloud_filter(struct i40e_vf *vf, u8 *msg)
3144{
3145 struct virtchnl_filter *vcf = (struct virtchnl_filter *)msg;
3146 struct virtchnl_l4_spec mask = vcf->mask.tcp_spec;
3147 struct virtchnl_l4_spec tcf = vcf->data.tcp_spec;
3148 struct i40e_cloud_filter cfilter, *cf = NULL;
3149 struct i40e_pf *pf = vf->pf;
3150 struct i40e_vsi *vsi = NULL;
3151 struct hlist_node *node;
3152 i40e_status aq_ret = 0;
3153 int i, ret;
3154
3155 if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) {
3156 aq_ret = I40E_ERR_PARAM;
3157 goto err;
3158 }
3159
3160 if (!vf->adq_enabled) {
3161 dev_info(&pf->pdev->dev,
3162 "VF %d: ADq not enabled, can't apply cloud filter\n",
3163 vf->vf_id);
3164 aq_ret = I40E_ERR_PARAM;
3165 goto err;
3166 }
3167
3168 if (i40e_validate_cloud_filter(vf, vcf)) {
3169 dev_info(&pf->pdev->dev,
3170 "VF %d: Invalid input, can't apply cloud filter\n",
3171 vf->vf_id);
3172 aq_ret = I40E_ERR_PARAM;
3173 goto err;
3174 }
3175
3176 memset(&cfilter, 0, sizeof(cfilter));
3177 /* parse destination mac address */
3178 for (i = 0; i < ETH_ALEN; i++)
3179 cfilter.dst_mac[i] = mask.dst_mac[i] & tcf.dst_mac[i];
3180
3181 /* parse source mac address */
3182 for (i = 0; i < ETH_ALEN; i++)
3183 cfilter.src_mac[i] = mask.src_mac[i] & tcf.src_mac[i];
3184
3185 cfilter.vlan_id = mask.vlan_id & tcf.vlan_id;
3186 cfilter.dst_port = mask.dst_port & tcf.dst_port;
3187 cfilter.src_port = mask.src_port & tcf.src_port;
3188
3189 switch (vcf->flow_type) {
3190 case VIRTCHNL_TCP_V4_FLOW:
3191 cfilter.n_proto = ETH_P_IP;
3192 if (mask.dst_ip[0] & tcf.dst_ip[0])
3193 memcpy(&cfilter.ip.v4.dst_ip, tcf.dst_ip,
3194 ARRAY_SIZE(tcf.dst_ip));
3195 else if (mask.src_ip[0] & tcf.dst_ip[0])
3196 memcpy(&cfilter.ip.v4.src_ip, tcf.src_ip,
3197 ARRAY_SIZE(tcf.dst_ip));
3198 break;
3199 case VIRTCHNL_TCP_V6_FLOW:
3200 cfilter.n_proto = ETH_P_IPV6;
3201 if (mask.dst_ip[3] & tcf.dst_ip[3])
3202 memcpy(&cfilter.ip.v6.dst_ip6, tcf.dst_ip,
3203 sizeof(cfilter.ip.v6.dst_ip6));
3204 if (mask.src_ip[3] & tcf.src_ip[3])
3205 memcpy(&cfilter.ip.v6.src_ip6, tcf.src_ip,
3206 sizeof(cfilter.ip.v6.src_ip6));
3207 break;
3208 default:
3209 /* TC filter can be configured based on different combinations
3210 * and in this case IP is not a part of filter config
3211 */
3212 dev_info(&pf->pdev->dev, "VF %d: Flow type not configured\n",
3213 vf->vf_id);
3214 }
3215
3216 /* get the vsi to which the tc belongs to */
3217 vsi = pf->vsi[vf->ch[vcf->action_meta].vsi_idx];
3218 cfilter.seid = vsi->seid;
3219 cfilter.flags = vcf->field_flags;
3220
3221 /* Deleting TC filter */
3222 if (tcf.dst_port)
3223 ret = i40e_add_del_cloud_filter_big_buf(vsi, &cfilter, false);
3224 else
3225 ret = i40e_add_del_cloud_filter(vsi, &cfilter, false);
3226 if (ret) {
3227 dev_err(&pf->pdev->dev,
3228 "VF %d: Failed to delete cloud filter, err %s aq_err %s\n",
3229 vf->vf_id, i40e_stat_str(&pf->hw, ret),
3230 i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
3231 goto err;
3232 }
3233
3234 hlist_for_each_entry_safe(cf, node,
3235 &vf->cloud_filter_list, cloud_node) {
3236 if (cf->seid != cfilter.seid)
3237 continue;
3238 if (mask.dst_port)
3239 if (cfilter.dst_port != cf->dst_port)
3240 continue;
3241 if (mask.dst_mac[0])
3242 if (!ether_addr_equal(cf->src_mac, cfilter.src_mac))
3243 continue;
3244 /* for ipv4 data to be valid, only first byte of mask is set */
3245 if (cfilter.n_proto == ETH_P_IP && mask.dst_ip[0])
3246 if (memcmp(&cfilter.ip.v4.dst_ip, &cf->ip.v4.dst_ip,
3247 ARRAY_SIZE(tcf.dst_ip)))
3248 continue;
3249 /* for ipv6, mask is set for all sixteen bytes (4 words) */
3250 if (cfilter.n_proto == ETH_P_IPV6 && mask.dst_ip[3])
3251 if (memcmp(&cfilter.ip.v6.dst_ip6, &cf->ip.v6.dst_ip6,
3252 sizeof(cfilter.ip.v6.src_ip6)))
3253 continue;
3254 if (mask.vlan_id)
3255 if (cfilter.vlan_id != cf->vlan_id)
3256 continue;
3257
3258 hlist_del(&cf->cloud_node);
3259 kfree(cf);
3260 vf->num_cloud_filters--;
3261 }
3262
3263err:
3264 return i40e_vc_send_resp_to_vf(vf, VIRTCHNL_OP_DEL_CLOUD_FILTER,
3265 aq_ret);
3266}
3267
3268/**
3269 * i40e_vc_add_cloud_filter
3270 * @vf: pointer to the VF info
3271 * @msg: pointer to the msg buffer
3272 *
3273 * This function adds a cloud filter programmed as TC filter for ADq
3274 **/
3275static int i40e_vc_add_cloud_filter(struct i40e_vf *vf, u8 *msg)
3276{
3277 struct virtchnl_filter *vcf = (struct virtchnl_filter *)msg;
3278 struct virtchnl_l4_spec mask = vcf->mask.tcp_spec;
3279 struct virtchnl_l4_spec tcf = vcf->data.tcp_spec;
3280 struct i40e_cloud_filter *cfilter = NULL;
3281 struct i40e_pf *pf = vf->pf;
3282 struct i40e_vsi *vsi = NULL;
3283 i40e_status aq_ret = 0;
3284 int i, ret;
3285
3286 if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) {
3287 aq_ret = I40E_ERR_PARAM;
3288 goto err;
3289 }
3290
3291 if (!vf->adq_enabled) {
3292 dev_info(&pf->pdev->dev,
3293 "VF %d: ADq is not enabled, can't apply cloud filter\n",
3294 vf->vf_id);
3295 aq_ret = I40E_ERR_PARAM;
3296 goto err;
3297 }
3298
3299 if (i40e_validate_cloud_filter(vf, vcf)) {
3300 dev_info(&pf->pdev->dev,
3301 "VF %d: Invalid input/s, can't apply cloud filter\n",
3302 vf->vf_id);
3303 aq_ret = I40E_ERR_PARAM;
3304 goto err;
3305 }
3306
3307 cfilter = kzalloc(sizeof(*cfilter), GFP_KERNEL);
3308 if (!cfilter)
3309 return -ENOMEM;
3310
3311 /* parse destination mac address */
3312 for (i = 0; i < ETH_ALEN; i++)
3313 cfilter->dst_mac[i] = mask.dst_mac[i] & tcf.dst_mac[i];
3314
3315 /* parse source mac address */
3316 for (i = 0; i < ETH_ALEN; i++)
3317 cfilter->src_mac[i] = mask.src_mac[i] & tcf.src_mac[i];
3318
3319 cfilter->vlan_id = mask.vlan_id & tcf.vlan_id;
3320 cfilter->dst_port = mask.dst_port & tcf.dst_port;
3321 cfilter->src_port = mask.src_port & tcf.src_port;
3322
3323 switch (vcf->flow_type) {
3324 case VIRTCHNL_TCP_V4_FLOW:
3325 cfilter->n_proto = ETH_P_IP;
3326 if (mask.dst_ip[0] & tcf.dst_ip[0])
3327 memcpy(&cfilter->ip.v4.dst_ip, tcf.dst_ip,
3328 ARRAY_SIZE(tcf.dst_ip));
3329 else if (mask.src_ip[0] & tcf.dst_ip[0])
3330 memcpy(&cfilter->ip.v4.src_ip, tcf.src_ip,
3331 ARRAY_SIZE(tcf.dst_ip));
3332 break;
3333 case VIRTCHNL_TCP_V6_FLOW:
3334 cfilter->n_proto = ETH_P_IPV6;
3335 if (mask.dst_ip[3] & tcf.dst_ip[3])
3336 memcpy(&cfilter->ip.v6.dst_ip6, tcf.dst_ip,
3337 sizeof(cfilter->ip.v6.dst_ip6));
3338 if (mask.src_ip[3] & tcf.src_ip[3])
3339 memcpy(&cfilter->ip.v6.src_ip6, tcf.src_ip,
3340 sizeof(cfilter->ip.v6.src_ip6));
3341 break;
3342 default:
3343 /* TC filter can be configured based on different combinations
3344 * and in this case IP is not a part of filter config
3345 */
3346 dev_info(&pf->pdev->dev, "VF %d: Flow type not configured\n",
3347 vf->vf_id);
3348 }
3349
3350 /* get the VSI to which the TC belongs to */
3351 vsi = pf->vsi[vf->ch[vcf->action_meta].vsi_idx];
3352 cfilter->seid = vsi->seid;
3353 cfilter->flags = vcf->field_flags;
3354
3355 /* Adding cloud filter programmed as TC filter */
3356 if (tcf.dst_port)
3357 ret = i40e_add_del_cloud_filter_big_buf(vsi, cfilter, true);
3358 else
3359 ret = i40e_add_del_cloud_filter(vsi, cfilter, true);
3360 if (ret) {
3361 dev_err(&pf->pdev->dev,
3362 "VF %d: Failed to add cloud filter, err %s aq_err %s\n",
3363 vf->vf_id, i40e_stat_str(&pf->hw, ret),
3364 i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
3365 goto err;
3366 }
3367
3368 INIT_HLIST_NODE(&cfilter->cloud_node);
3369 hlist_add_head(&cfilter->cloud_node, &vf->cloud_filter_list);
3370 vf->num_cloud_filters++;
3371err:
3372 return i40e_vc_send_resp_to_vf(vf, VIRTCHNL_OP_ADD_CLOUD_FILTER,
3373 aq_ret);
3374}
3375
3376/**
3377 * i40e_vc_add_qch_msg: Add queue channel and enable ADq
3378 * @vf: pointer to the VF info
3379 * @msg: pointer to the msg buffer
3380 **/
3381static int i40e_vc_add_qch_msg(struct i40e_vf *vf, u8 *msg)
3382{
3383 struct virtchnl_tc_info *tci =
3384 (struct virtchnl_tc_info *)msg;
3385 struct i40e_pf *pf = vf->pf;
3386 struct i40e_link_status *ls = &pf->hw.phy.link_info;
3387 int i, adq_request_qps = 0, speed = 0;
3388 i40e_status aq_ret = 0;
3389
3390 if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) {
3391 aq_ret = I40E_ERR_PARAM;
3392 goto err;
3393 }
3394
3395 /* ADq cannot be applied if spoof check is ON */
3396 if (vf->spoofchk) {
3397 dev_err(&pf->pdev->dev,
3398 "Spoof check is ON, turn it OFF to enable ADq\n");
3399 aq_ret = I40E_ERR_PARAM;
3400 goto err;
3401 }
3402
3403 if (!(vf->driver_caps & VIRTCHNL_VF_OFFLOAD_ADQ)) {
3404 dev_err(&pf->pdev->dev,
3405 "VF %d attempting to enable ADq, but hasn't properly negotiated that capability\n",
3406 vf->vf_id);
3407 aq_ret = I40E_ERR_PARAM;
3408 goto err;
3409 }
3410
3411 /* max number of traffic classes for VF currently capped at 4 */
3412 if (!tci->num_tc || tci->num_tc > I40E_MAX_VF_VSI) {
3413 dev_err(&pf->pdev->dev,
3414 "VF %d trying to set %u TCs, valid range 1-4 TCs per VF\n",
3415 vf->vf_id, tci->num_tc);
3416 aq_ret = I40E_ERR_PARAM;
3417 goto err;
3418 }
3419
3420 /* validate queues for each TC */
3421 for (i = 0; i < tci->num_tc; i++)
3422 if (!tci->list[i].count ||
3423 tci->list[i].count > I40E_DEFAULT_QUEUES_PER_VF) {
3424 dev_err(&pf->pdev->dev,
3425 "VF %d: TC %d trying to set %u queues, valid range 1-4 queues per TC\n",
3426 vf->vf_id, i, tci->list[i].count);
3427 aq_ret = I40E_ERR_PARAM;
3428 goto err;
3429 }
3430
3431 /* need Max VF queues but already have default number of queues */
3432 adq_request_qps = I40E_MAX_VF_QUEUES - I40E_DEFAULT_QUEUES_PER_VF;
3433
3434 if (pf->queues_left < adq_request_qps) {
3435 dev_err(&pf->pdev->dev,
3436 "No queues left to allocate to VF %d\n",
3437 vf->vf_id);
3438 aq_ret = I40E_ERR_PARAM;
3439 goto err;
3440 } else {
3441 /* we need to allocate max VF queues to enable ADq so as to
3442 * make sure ADq enabled VF always gets back queues when it
3443 * goes through a reset.
3444 */
3445 vf->num_queue_pairs = I40E_MAX_VF_QUEUES;
3446 }
3447
3448 /* get link speed in MB to validate rate limit */
3449 switch (ls->link_speed) {
3450 case VIRTCHNL_LINK_SPEED_100MB:
3451 speed = SPEED_100;
3452 break;
3453 case VIRTCHNL_LINK_SPEED_1GB:
3454 speed = SPEED_1000;
3455 break;
3456 case VIRTCHNL_LINK_SPEED_10GB:
3457 speed = SPEED_10000;
3458 break;
3459 case VIRTCHNL_LINK_SPEED_20GB:
3460 speed = SPEED_20000;
3461 break;
3462 case VIRTCHNL_LINK_SPEED_25GB:
3463 speed = SPEED_25000;
3464 break;
3465 case VIRTCHNL_LINK_SPEED_40GB:
3466 speed = SPEED_40000;
3467 break;
3468 default:
3469 dev_err(&pf->pdev->dev,
3470 "Cannot detect link speed\n");
3471 aq_ret = I40E_ERR_PARAM;
3472 goto err;
3473 }
3474
3475 /* parse data from the queue channel info */
3476 vf->num_tc = tci->num_tc;
3477 for (i = 0; i < vf->num_tc; i++) {
3478 if (tci->list[i].max_tx_rate) {
3479 if (tci->list[i].max_tx_rate > speed) {
3480 dev_err(&pf->pdev->dev,
3481 "Invalid max tx rate %llu specified for VF %d.",
3482 tci->list[i].max_tx_rate,
3483 vf->vf_id);
3484 aq_ret = I40E_ERR_PARAM;
3485 goto err;
3486 } else {
3487 vf->ch[i].max_tx_rate =
3488 tci->list[i].max_tx_rate;
3489 }
3490 }
3491 vf->ch[i].num_qps = tci->list[i].count;
3492 }
3493
3494 /* set this flag only after making sure all inputs are sane */
3495 vf->adq_enabled = true;
3496 /* num_req_queues is set when user changes number of queues via ethtool
3497 * and this causes issue for default VSI(which depends on this variable)
3498 * when ADq is enabled, hence reset it.
3499 */
3500 vf->num_req_queues = 0;
3501
3502 /* reset the VF in order to allocate resources */
3503 i40e_vc_notify_vf_reset(vf);
3504 i40e_reset_vf(vf, false);
3505
3506 return I40E_SUCCESS;
3507
3508 /* send the response to the VF */
3509err:
3510 return i40e_vc_send_resp_to_vf(vf, VIRTCHNL_OP_ENABLE_CHANNELS,
3511 aq_ret);
3512}
3513
3514/**
3515 * i40e_vc_del_qch_msg
3516 * @vf: pointer to the VF info
3517 * @msg: pointer to the msg buffer
3518 **/
3519static int i40e_vc_del_qch_msg(struct i40e_vf *vf, u8 *msg)
3520{
3521 struct i40e_pf *pf = vf->pf;
3522 i40e_status aq_ret = 0;
3523
3524 if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) {
3525 aq_ret = I40E_ERR_PARAM;
3526 goto err;
3527 }
3528
3529 if (vf->adq_enabled) {
3530 i40e_del_all_cloud_filters(vf);
3531 i40e_del_qch(vf);
3532 vf->adq_enabled = false;
3533 vf->num_tc = 0;
3534 dev_info(&pf->pdev->dev,
3535 "Deleting Queue Channels and cloud filters for ADq on VF %d\n",
3536 vf->vf_id);
3537 } else {
3538 dev_info(&pf->pdev->dev, "VF %d trying to delete queue channels but ADq isn't enabled\n",
3539 vf->vf_id);
3540 aq_ret = I40E_ERR_PARAM;
3541 }
3542
3543 /* reset the VF in order to allocate resources */
3544 i40e_vc_notify_vf_reset(vf);
3545 i40e_reset_vf(vf, false);
3546
3547 return I40E_SUCCESS;
3548
3549err:
3550 return i40e_vc_send_resp_to_vf(vf, VIRTCHNL_OP_DISABLE_CHANNELS,
3551 aq_ret);
3552}
3553
3554/**
2691 * i40e_vc_process_vf_msg 3555 * i40e_vc_process_vf_msg
2692 * @pf: pointer to the PF structure 3556 * @pf: pointer to the PF structure
2693 * @vf_id: source VF id 3557 * @vf_id: source VF id
@@ -2816,7 +3680,18 @@ int i40e_vc_process_vf_msg(struct i40e_pf *pf, s16 vf_id, u32 v_opcode,
2816 case VIRTCHNL_OP_REQUEST_QUEUES: 3680 case VIRTCHNL_OP_REQUEST_QUEUES:
2817 ret = i40e_vc_request_queues_msg(vf, msg, msglen); 3681 ret = i40e_vc_request_queues_msg(vf, msg, msglen);
2818 break; 3682 break;
2819 3683 case VIRTCHNL_OP_ENABLE_CHANNELS:
3684 ret = i40e_vc_add_qch_msg(vf, msg);
3685 break;
3686 case VIRTCHNL_OP_DISABLE_CHANNELS:
3687 ret = i40e_vc_del_qch_msg(vf, msg);
3688 break;
3689 case VIRTCHNL_OP_ADD_CLOUD_FILTER:
3690 ret = i40e_vc_add_cloud_filter(vf, msg);
3691 break;
3692 case VIRTCHNL_OP_DEL_CLOUD_FILTER:
3693 ret = i40e_vc_del_cloud_filter(vf, msg);
3694 break;
2820 case VIRTCHNL_OP_UNKNOWN: 3695 case VIRTCHNL_OP_UNKNOWN:
2821 default: 3696 default:
2822 dev_err(&pf->pdev->dev, "Unsupported opcode %d from VF %d\n", 3697 dev_err(&pf->pdev->dev, "Unsupported opcode %d from VF %d\n",
@@ -2889,6 +3764,7 @@ int i40e_ndo_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac)
2889 int ret = 0; 3764 int ret = 0;
2890 struct hlist_node *h; 3765 struct hlist_node *h;
2891 int bkt; 3766 int bkt;
3767 u8 i;
2892 3768
2893 /* validate the request */ 3769 /* validate the request */
2894 if (vf_id >= pf->num_alloc_vfs) { 3770 if (vf_id >= pf->num_alloc_vfs) {
@@ -2900,6 +3776,16 @@ int i40e_ndo_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac)
2900 3776
2901 vf = &(pf->vf[vf_id]); 3777 vf = &(pf->vf[vf_id]);
2902 vsi = pf->vsi[vf->lan_vsi_idx]; 3778 vsi = pf->vsi[vf->lan_vsi_idx];
3779
3780 /* When the VF is resetting wait until it is done.
3781 * It can take up to 200 milliseconds,
3782 * but wait for up to 300 milliseconds to be safe.
3783 */
3784 for (i = 0; i < 15; i++) {
3785 if (test_bit(I40E_VF_STATE_INIT, &vf->vf_states))
3786 break;
3787 msleep(20);
3788 }
2903 if (!test_bit(I40E_VF_STATE_INIT, &vf->vf_states)) { 3789 if (!test_bit(I40E_VF_STATE_INIT, &vf->vf_states)) {
2904 dev_err(&pf->pdev->dev, "VF %d still in reset. Try again.\n", 3790 dev_err(&pf->pdev->dev, "VF %d still in reset. Try again.\n",
2905 vf_id); 3791 vf_id);
@@ -3382,6 +4268,16 @@ int i40e_ndo_set_vf_trust(struct net_device *netdev, int vf_id, bool setting)
3382 i40e_vc_disable_vf(vf); 4268 i40e_vc_disable_vf(vf);
3383 dev_info(&pf->pdev->dev, "VF %u is now %strusted\n", 4269 dev_info(&pf->pdev->dev, "VF %u is now %strusted\n",
3384 vf_id, setting ? "" : "un"); 4270 vf_id, setting ? "" : "un");
4271
4272 if (vf->adq_enabled) {
4273 if (!vf->trusted) {
4274 dev_info(&pf->pdev->dev,
4275 "VF %u no longer Trusted, deleting all cloud filters\n",
4276 vf_id);
4277 i40e_del_all_cloud_filters(vf);
4278 }
4279 }
4280
3385out: 4281out:
3386 return ret; 4282 return ret;
3387} 4283}
diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
index 5efc4f92bb37..6852599b2379 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
@@ -69,6 +69,19 @@ enum i40e_vf_capabilities {
69 I40E_VIRTCHNL_VF_CAP_IWARP, 69 I40E_VIRTCHNL_VF_CAP_IWARP,
70}; 70};
71 71
72/* In ADq, max 4 VSI's can be allocated per VF including primary VF VSI.
73 * These variables are used to store indices, id's and number of queues
74 * for each VSI including that of primary VF VSI. Each Traffic class is
75 * termed as channel and each channel can in-turn have 4 queues which
76 * means max 16 queues overall per VF.
77 */
78struct i40evf_channel {
79 u16 vsi_idx; /* index in PF struct for all channel VSIs */
80 u16 vsi_id; /* VSI ID used by firmware */
81 u16 num_qps; /* number of queue pairs requested by user */
82 u64 max_tx_rate; /* bandwidth rate allocation for VSIs */
83};
84
72/* VF information structure */ 85/* VF information structure */
73struct i40e_vf { 86struct i40e_vf {
74 struct i40e_pf *pf; 87 struct i40e_pf *pf;
@@ -111,6 +124,13 @@ struct i40e_vf {
111 u16 num_mac; 124 u16 num_mac;
112 u16 num_vlan; 125 u16 num_vlan;
113 126
127 /* ADq related variables */
128 bool adq_enabled; /* flag to enable adq */
129 u8 num_tc;
130 struct i40evf_channel ch[I40E_MAX_VF_VSI];
131 struct hlist_head cloud_filter_list;
132 u16 num_cloud_filters;
133
114 /* RDMA Client */ 134 /* RDMA Client */
115 struct virtchnl_iwarp_qvlist_info *qvlist_info; 135 struct virtchnl_iwarp_qvlist_info *qvlist_info;
116}; 136};
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
index 357d6051281f..e088d23eb083 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
@@ -196,7 +196,7 @@ void i40evf_detect_recover_hung(struct i40e_vsi *vsi)
196 */ 196 */
197 smp_rmb(); 197 smp_rmb();
198 tx_ring->tx_stats.prev_pkt_ctr = 198 tx_ring->tx_stats.prev_pkt_ctr =
199 i40evf_get_tx_pending(tx_ring, false) ? packets : -1; 199 i40evf_get_tx_pending(tx_ring, true) ? packets : -1;
200 } 200 }
201 } 201 }
202} 202}
@@ -392,99 +392,241 @@ void i40evf_force_wb(struct i40e_vsi *vsi, struct i40e_q_vector *q_vector)
392 val); 392 val);
393} 393}
394 394
395static inline bool i40e_container_is_rx(struct i40e_q_vector *q_vector,
396 struct i40e_ring_container *rc)
397{
398 return &q_vector->rx == rc;
399}
400
401static inline unsigned int i40e_itr_divisor(struct i40e_q_vector *q_vector)
402{
403 unsigned int divisor;
404
405 switch (q_vector->adapter->link_speed) {
406 case I40E_LINK_SPEED_40GB:
407 divisor = I40E_ITR_ADAPTIVE_MIN_INC * 1024;
408 break;
409 case I40E_LINK_SPEED_25GB:
410 case I40E_LINK_SPEED_20GB:
411 divisor = I40E_ITR_ADAPTIVE_MIN_INC * 512;
412 break;
413 default:
414 case I40E_LINK_SPEED_10GB:
415 divisor = I40E_ITR_ADAPTIVE_MIN_INC * 256;
416 break;
417 case I40E_LINK_SPEED_1GB:
418 case I40E_LINK_SPEED_100MB:
419 divisor = I40E_ITR_ADAPTIVE_MIN_INC * 32;
420 break;
421 }
422
423 return divisor;
424}
425
395/** 426/**
396 * i40e_set_new_dynamic_itr - Find new ITR level 427 * i40e_update_itr - update the dynamic ITR value based on statistics
428 * @q_vector: structure containing interrupt and ring information
397 * @rc: structure containing ring performance data 429 * @rc: structure containing ring performance data
398 * 430 *
399 * Returns true if ITR changed, false if not 431 * Stores a new ITR value based on packets and byte
400 * 432 * counts during the last interrupt. The advantage of per interrupt
401 * Stores a new ITR value based on packets and byte counts during 433 * computation is faster updates and more accurate ITR for the current
402 * the last interrupt. The advantage of per interrupt computation 434 * traffic pattern. Constants in this function were computed
403 * is faster updates and more accurate ITR for the current traffic 435 * based on theoretical maximum wire speed and thresholds were set based
404 * pattern. Constants in this function were computed based on 436 * on testing data as well as attempting to minimize response time
405 * theoretical maximum wire speed and thresholds were set based on
406 * testing data as well as attempting to minimize response time
407 * while increasing bulk throughput. 437 * while increasing bulk throughput.
408 **/ 438 **/
409static bool i40e_set_new_dynamic_itr(struct i40e_ring_container *rc) 439static void i40e_update_itr(struct i40e_q_vector *q_vector,
440 struct i40e_ring_container *rc)
410{ 441{
411 enum i40e_latency_range new_latency_range = rc->latency_range; 442 unsigned int avg_wire_size, packets, bytes, itr;
412 u32 new_itr = rc->itr; 443 unsigned long next_update = jiffies;
413 int bytes_per_usec;
414 unsigned int usecs, estimated_usecs;
415 444
416 if (rc->total_packets == 0 || !rc->itr) 445 /* If we don't have any rings just leave ourselves set for maximum
417 return false; 446 * possible latency so we take ourselves out of the equation.
447 */
448 if (!rc->ring || !ITR_IS_DYNAMIC(rc->ring->itr_setting))
449 return;
450
451 /* For Rx we want to push the delay up and default to low latency.
452 * for Tx we want to pull the delay down and default to high latency.
453 */
454 itr = i40e_container_is_rx(q_vector, rc) ?
455 I40E_ITR_ADAPTIVE_MIN_USECS | I40E_ITR_ADAPTIVE_LATENCY :
456 I40E_ITR_ADAPTIVE_MAX_USECS | I40E_ITR_ADAPTIVE_LATENCY;
457
458 /* If we didn't update within up to 1 - 2 jiffies we can assume
459 * that either packets are coming in so slow there hasn't been
460 * any work, or that there is so much work that NAPI is dealing
461 * with interrupt moderation and we don't need to do anything.
462 */
463 if (time_after(next_update, rc->next_update))
464 goto clear_counts;
465
466 /* If itr_countdown is set it means we programmed an ITR within
467 * the last 4 interrupt cycles. This has a side effect of us
468 * potentially firing an early interrupt. In order to work around
469 * this we need to throw out any data received for a few
470 * interrupts following the update.
471 */
472 if (q_vector->itr_countdown) {
473 itr = rc->target_itr;
474 goto clear_counts;
475 }
476
477 packets = rc->total_packets;
478 bytes = rc->total_bytes;
418 479
419 usecs = (rc->itr << 1) * ITR_COUNTDOWN_START; 480 if (i40e_container_is_rx(q_vector, rc)) {
420 bytes_per_usec = rc->total_bytes / usecs; 481 /* If Rx there are 1 to 4 packets and bytes are less than
482 * 9000 assume insufficient data to use bulk rate limiting
483 * approach unless Tx is already in bulk rate limiting. We
484 * are likely latency driven.
485 */
486 if (packets && packets < 4 && bytes < 9000 &&
487 (q_vector->tx.target_itr & I40E_ITR_ADAPTIVE_LATENCY)) {
488 itr = I40E_ITR_ADAPTIVE_LATENCY;
489 goto adjust_by_size;
490 }
491 } else if (packets < 4) {
492 /* If we have Tx and Rx ITR maxed and Tx ITR is running in
493 * bulk mode and we are receiving 4 or fewer packets just
494 * reset the ITR_ADAPTIVE_LATENCY bit for latency mode so
495 * that the Rx can relax.
496 */
497 if (rc->target_itr == I40E_ITR_ADAPTIVE_MAX_USECS &&
498 (q_vector->rx.target_itr & I40E_ITR_MASK) ==
499 I40E_ITR_ADAPTIVE_MAX_USECS)
500 goto clear_counts;
501 } else if (packets > 32) {
502 /* If we have processed over 32 packets in a single interrupt
503 * for Tx assume we need to switch over to "bulk" mode.
504 */
505 rc->target_itr &= ~I40E_ITR_ADAPTIVE_LATENCY;
506 }
421 507
422 /* The calculations in this algorithm depend on interrupts actually 508 /* We have no packets to actually measure against. This means
423 * firing at the ITR rate. This may not happen if the packet rate is 509 * either one of the other queues on this vector is active or
424 * really low, or if we've been napi polling. Check to make sure 510 * we are a Tx queue doing TSO with too high of an interrupt rate.
425 * that's not the case before we continue. 511 *
512 * Between 4 and 56 we can assume that our current interrupt delay
513 * is only slightly too low. As such we should increase it by a small
514 * fixed amount.
426 */ 515 */
427 estimated_usecs = jiffies_to_usecs(jiffies - rc->last_itr_update); 516 if (packets < 56) {
428 if (estimated_usecs > usecs) { 517 itr = rc->target_itr + I40E_ITR_ADAPTIVE_MIN_INC;
429 new_latency_range = I40E_LOW_LATENCY; 518 if ((itr & I40E_ITR_MASK) > I40E_ITR_ADAPTIVE_MAX_USECS) {
430 goto reset_latency; 519 itr &= I40E_ITR_ADAPTIVE_LATENCY;
520 itr += I40E_ITR_ADAPTIVE_MAX_USECS;
521 }
522 goto clear_counts;
523 }
524
525 if (packets <= 256) {
526 itr = min(q_vector->tx.current_itr, q_vector->rx.current_itr);
527 itr &= I40E_ITR_MASK;
528
529 /* Between 56 and 112 is our "goldilocks" zone where we are
530 * working out "just right". Just report that our current
531 * ITR is good for us.
532 */
533 if (packets <= 112)
534 goto clear_counts;
535
536 /* If packet count is 128 or greater we are likely looking
537 * at a slight overrun of the delay we want. Try halving
538 * our delay to see if that will cut the number of packets
539 * in half per interrupt.
540 */
541 itr /= 2;
542 itr &= I40E_ITR_MASK;
543 if (itr < I40E_ITR_ADAPTIVE_MIN_USECS)
544 itr = I40E_ITR_ADAPTIVE_MIN_USECS;
545
546 goto clear_counts;
431 } 547 }
432 548
433 /* simple throttlerate management 549 /* The paths below assume we are dealing with a bulk ITR since
434 * 0-10MB/s lowest (50000 ints/s) 550 * number of packets is greater than 256. We are just going to have
435 * 10-20MB/s low (20000 ints/s) 551 * to compute a value and try to bring the count under control,
436 * 20-1249MB/s bulk (18000 ints/s) 552 * though for smaller packet sizes there isn't much we can do as
553 * NAPI polling will likely be kicking in sooner rather than later.
554 */
555 itr = I40E_ITR_ADAPTIVE_BULK;
556
557adjust_by_size:
558 /* If packet counts are 256 or greater we can assume we have a gross
559 * overestimation of what the rate should be. Instead of trying to fine
560 * tune it just use the formula below to try and dial in an exact value
561 * give the current packet size of the frame.
562 */
563 avg_wire_size = bytes / packets;
564
565 /* The following is a crude approximation of:
566 * wmem_default / (size + overhead) = desired_pkts_per_int
567 * rate / bits_per_byte / (size + ethernet overhead) = pkt_rate
568 * (desired_pkt_rate / pkt_rate) * usecs_per_sec = ITR value
437 * 569 *
438 * The math works out because the divisor is in 10^(-6) which 570 * Assuming wmem_default is 212992 and overhead is 640 bytes per
439 * turns the bytes/us input value into MB/s values, but 571 * packet, (256 skb, 64 headroom, 320 shared info), we can reduce the
440 * make sure to use usecs, as the register values written 572 * formula down to
441 * are in 2 usec increments in the ITR registers, and make sure 573 *
442 * to use the smoothed values that the countdown timer gives us. 574 * (170 * (size + 24)) / (size + 640) = ITR
575 *
576 * We first do some math on the packet size and then finally bitshift
577 * by 8 after rounding up. We also have to account for PCIe link speed
578 * difference as ITR scales based on this.
443 */ 579 */
444 switch (new_latency_range) { 580 if (avg_wire_size <= 60) {
445 case I40E_LOWEST_LATENCY: 581 /* Start at 250k ints/sec */
446 if (bytes_per_usec > 10) 582 avg_wire_size = 4096;
447 new_latency_range = I40E_LOW_LATENCY; 583 } else if (avg_wire_size <= 380) {
448 break; 584 /* 250K ints/sec to 60K ints/sec */
449 case I40E_LOW_LATENCY: 585 avg_wire_size *= 40;
450 if (bytes_per_usec > 20) 586 avg_wire_size += 1696;
451 new_latency_range = I40E_BULK_LATENCY; 587 } else if (avg_wire_size <= 1084) {
452 else if (bytes_per_usec <= 10) 588 /* 60K ints/sec to 36K ints/sec */
453 new_latency_range = I40E_LOWEST_LATENCY; 589 avg_wire_size *= 15;
454 break; 590 avg_wire_size += 11452;
455 case I40E_BULK_LATENCY: 591 } else if (avg_wire_size <= 1980) {
456 default: 592 /* 36K ints/sec to 30K ints/sec */
457 if (bytes_per_usec <= 20) 593 avg_wire_size *= 5;
458 new_latency_range = I40E_LOW_LATENCY; 594 avg_wire_size += 22420;
459 break; 595 } else {
596 /* plateau at a limit of 30K ints/sec */
597 avg_wire_size = 32256;
460 } 598 }
461 599
462reset_latency: 600 /* If we are in low latency mode halve our delay which doubles the
463 rc->latency_range = new_latency_range; 601 * rate to somewhere between 100K to 16K ints/sec
602 */
603 if (itr & I40E_ITR_ADAPTIVE_LATENCY)
604 avg_wire_size /= 2;
464 605
465 switch (new_latency_range) { 606 /* Resultant value is 256 times larger than it needs to be. This
466 case I40E_LOWEST_LATENCY: 607 * gives us room to adjust the value as needed to either increase
467 new_itr = I40E_ITR_50K; 608 * or decrease the value based on link speeds of 10G, 2.5G, 1G, etc.
468 break; 609 *
469 case I40E_LOW_LATENCY: 610 * Use addition as we have already recorded the new latency flag
470 new_itr = I40E_ITR_20K; 611 * for the ITR value.
471 break; 612 */
472 case I40E_BULK_LATENCY: 613 itr += DIV_ROUND_UP(avg_wire_size, i40e_itr_divisor(q_vector)) *
473 new_itr = I40E_ITR_18K; 614 I40E_ITR_ADAPTIVE_MIN_INC;
474 break; 615
475 default: 616 if ((itr & I40E_ITR_MASK) > I40E_ITR_ADAPTIVE_MAX_USECS) {
476 break; 617 itr &= I40E_ITR_ADAPTIVE_LATENCY;
618 itr += I40E_ITR_ADAPTIVE_MAX_USECS;
477 } 619 }
478 620
621clear_counts:
622 /* write back value */
623 rc->target_itr = itr;
624
625 /* next update should occur within next jiffy */
626 rc->next_update = next_update + 1;
627
479 rc->total_bytes = 0; 628 rc->total_bytes = 0;
480 rc->total_packets = 0; 629 rc->total_packets = 0;
481 rc->last_itr_update = jiffies;
482
483 if (new_itr != rc->itr) {
484 rc->itr = new_itr;
485 return true;
486 }
487 return false;
488} 630}
489 631
490/** 632/**
@@ -1273,7 +1415,7 @@ static struct sk_buff *i40e_build_skb(struct i40e_ring *rx_ring,
1273 * @rx_buffer: rx buffer to pull data from 1415 * @rx_buffer: rx buffer to pull data from
1274 * 1416 *
1275 * This function will clean up the contents of the rx_buffer. It will 1417 * This function will clean up the contents of the rx_buffer. It will
1276 * either recycle the bufer or unmap it and free the associated resources. 1418 * either recycle the buffer or unmap it and free the associated resources.
1277 */ 1419 */
1278static void i40e_put_rx_buffer(struct i40e_ring *rx_ring, 1420static void i40e_put_rx_buffer(struct i40e_ring *rx_ring,
1279 struct i40e_rx_buffer *rx_buffer) 1421 struct i40e_rx_buffer *rx_buffer)
@@ -1457,33 +1599,45 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget)
1457 return failure ? budget : (int)total_rx_packets; 1599 return failure ? budget : (int)total_rx_packets;
1458} 1600}
1459 1601
1460static u32 i40e_buildreg_itr(const int type, const u16 itr) 1602static inline u32 i40e_buildreg_itr(const int type, u16 itr)
1461{ 1603{
1462 u32 val; 1604 u32 val;
1463 1605
1606 /* We don't bother with setting the CLEARPBA bit as the data sheet
1607 * points out doing so is "meaningless since it was already
1608 * auto-cleared". The auto-clearing happens when the interrupt is
1609 * asserted.
1610 *
1611 * Hardware errata 28 for also indicates that writing to a
1612 * xxINT_DYN_CTLx CSR with INTENA_MSK (bit 31) set to 0 will clear
1613 * an event in the PBA anyway so we need to rely on the automask
1614 * to hold pending events for us until the interrupt is re-enabled
1615 *
1616 * The itr value is reported in microseconds, and the register
1617 * value is recorded in 2 microsecond units. For this reason we
1618 * only need to shift by the interval shift - 1 instead of the
1619 * full value.
1620 */
1621 itr &= I40E_ITR_MASK;
1622
1464 val = I40E_VFINT_DYN_CTLN1_INTENA_MASK | 1623 val = I40E_VFINT_DYN_CTLN1_INTENA_MASK |
1465 I40E_VFINT_DYN_CTLN1_CLEARPBA_MASK |
1466 (type << I40E_VFINT_DYN_CTLN1_ITR_INDX_SHIFT) | 1624 (type << I40E_VFINT_DYN_CTLN1_ITR_INDX_SHIFT) |
1467 (itr << I40E_VFINT_DYN_CTLN1_INTERVAL_SHIFT); 1625 (itr << (I40E_VFINT_DYN_CTLN1_INTERVAL_SHIFT - 1));
1468 1626
1469 return val; 1627 return val;
1470} 1628}
1471 1629
1472/* a small macro to shorten up some long lines */ 1630/* a small macro to shorten up some long lines */
1473#define INTREG I40E_VFINT_DYN_CTLN1 1631#define INTREG I40E_VFINT_DYN_CTLN1
1474static inline int get_rx_itr(struct i40e_vsi *vsi, int idx)
1475{
1476 struct i40evf_adapter *adapter = vsi->back;
1477 1632
1478 return adapter->rx_rings[idx].rx_itr_setting; 1633/* The act of updating the ITR will cause it to immediately trigger. In order
1479} 1634 * to prevent this from throwing off adaptive update statistics we defer the
1480 1635 * update so that it can only happen so often. So after either Tx or Rx are
1481static inline int get_tx_itr(struct i40e_vsi *vsi, int idx) 1636 * updated we make the adaptive scheme wait until either the ITR completely
1482{ 1637 * expires via the next_update expiration or we have been through at least
1483 struct i40evf_adapter *adapter = vsi->back; 1638 * 3 interrupts.
1484 1639 */
1485 return adapter->tx_rings[idx].tx_itr_setting; 1640#define ITR_COUNTDOWN_START 3
1486}
1487 1641
1488/** 1642/**
1489 * i40e_update_enable_itr - Update itr and re-enable MSIX interrupt 1643 * i40e_update_enable_itr - Update itr and re-enable MSIX interrupt
@@ -1495,70 +1649,51 @@ static inline void i40e_update_enable_itr(struct i40e_vsi *vsi,
1495 struct i40e_q_vector *q_vector) 1649 struct i40e_q_vector *q_vector)
1496{ 1650{
1497 struct i40e_hw *hw = &vsi->back->hw; 1651 struct i40e_hw *hw = &vsi->back->hw;
1498 bool rx = false, tx = false; 1652 u32 intval;
1499 u32 rxval, txval;
1500 int idx = q_vector->v_idx;
1501 int rx_itr_setting, tx_itr_setting;
1502
1503 /* avoid dynamic calculation if in countdown mode OR if
1504 * all dynamic is disabled
1505 */
1506 rxval = txval = i40e_buildreg_itr(I40E_ITR_NONE, 0);
1507
1508 rx_itr_setting = get_rx_itr(vsi, idx);
1509 tx_itr_setting = get_tx_itr(vsi, idx);
1510 1653
1511 if (q_vector->itr_countdown > 0 || 1654 /* These will do nothing if dynamic updates are not enabled */
1512 (!ITR_IS_DYNAMIC(rx_itr_setting) && 1655 i40e_update_itr(q_vector, &q_vector->tx);
1513 !ITR_IS_DYNAMIC(tx_itr_setting))) { 1656 i40e_update_itr(q_vector, &q_vector->rx);
1514 goto enable_int;
1515 }
1516
1517 if (ITR_IS_DYNAMIC(rx_itr_setting)) {
1518 rx = i40e_set_new_dynamic_itr(&q_vector->rx);
1519 rxval = i40e_buildreg_itr(I40E_RX_ITR, q_vector->rx.itr);
1520 }
1521 1657
1522 if (ITR_IS_DYNAMIC(tx_itr_setting)) { 1658 /* This block of logic allows us to get away with only updating
1523 tx = i40e_set_new_dynamic_itr(&q_vector->tx); 1659 * one ITR value with each interrupt. The idea is to perform a
1524 txval = i40e_buildreg_itr(I40E_TX_ITR, q_vector->tx.itr); 1660 * pseudo-lazy update with the following criteria.
1525 } 1661 *
1526 1662 * 1. Rx is given higher priority than Tx if both are in same state
1527 if (rx || tx) { 1663 * 2. If we must reduce an ITR that is given highest priority.
1528 /* get the higher of the two ITR adjustments and 1664 * 3. We then give priority to increasing ITR based on amount.
1529 * use the same value for both ITR registers
1530 * when in adaptive mode (Rx and/or Tx)
1531 */
1532 u16 itr = max(q_vector->tx.itr, q_vector->rx.itr);
1533
1534 q_vector->tx.itr = q_vector->rx.itr = itr;
1535 txval = i40e_buildreg_itr(I40E_TX_ITR, itr);
1536 tx = true;
1537 rxval = i40e_buildreg_itr(I40E_RX_ITR, itr);
1538 rx = true;
1539 }
1540
1541 /* only need to enable the interrupt once, but need
1542 * to possibly update both ITR values
1543 */ 1665 */
1544 if (rx) { 1666 if (q_vector->rx.target_itr < q_vector->rx.current_itr) {
1545 /* set the INTENA_MSK_MASK so that this first write 1667 /* Rx ITR needs to be reduced, this is highest priority */
1546 * won't actually enable the interrupt, instead just 1668 intval = i40e_buildreg_itr(I40E_RX_ITR,
1547 * updating the ITR (it's bit 31 PF and VF) 1669 q_vector->rx.target_itr);
1670 q_vector->rx.current_itr = q_vector->rx.target_itr;
1671 q_vector->itr_countdown = ITR_COUNTDOWN_START;
1672 } else if ((q_vector->tx.target_itr < q_vector->tx.current_itr) ||
1673 ((q_vector->rx.target_itr - q_vector->rx.current_itr) <
1674 (q_vector->tx.target_itr - q_vector->tx.current_itr))) {
1675 /* Tx ITR needs to be reduced, this is second priority
1676 * Tx ITR needs to be increased more than Rx, fourth priority
1548 */ 1677 */
1549 rxval |= BIT(31); 1678 intval = i40e_buildreg_itr(I40E_TX_ITR,
1550 /* don't check _DOWN because interrupt isn't being enabled */ 1679 q_vector->tx.target_itr);
1551 wr32(hw, INTREG(q_vector->reg_idx), rxval); 1680 q_vector->tx.current_itr = q_vector->tx.target_itr;
1681 q_vector->itr_countdown = ITR_COUNTDOWN_START;
1682 } else if (q_vector->rx.current_itr != q_vector->rx.target_itr) {
1683 /* Rx ITR needs to be increased, third priority */
1684 intval = i40e_buildreg_itr(I40E_RX_ITR,
1685 q_vector->rx.target_itr);
1686 q_vector->rx.current_itr = q_vector->rx.target_itr;
1687 q_vector->itr_countdown = ITR_COUNTDOWN_START;
1688 } else {
1689 /* No ITR update, lowest priority */
1690 intval = i40e_buildreg_itr(I40E_ITR_NONE, 0);
1691 if (q_vector->itr_countdown)
1692 q_vector->itr_countdown--;
1552 } 1693 }
1553 1694
1554enable_int:
1555 if (!test_bit(__I40E_VSI_DOWN, vsi->state)) 1695 if (!test_bit(__I40E_VSI_DOWN, vsi->state))
1556 wr32(hw, INTREG(q_vector->reg_idx), txval); 1696 wr32(hw, INTREG(q_vector->reg_idx), intval);
1557
1558 if (q_vector->itr_countdown)
1559 q_vector->itr_countdown--;
1560 else
1561 q_vector->itr_countdown = ITR_COUNTDOWN_START;
1562} 1697}
1563 1698
1564/** 1699/**
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.h b/drivers/net/ethernet/intel/i40evf/i40e_txrx.h
index 7798a6645c3f..9129447d079b 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.h
+++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.h
@@ -28,31 +28,35 @@
28#define _I40E_TXRX_H_ 28#define _I40E_TXRX_H_
29 29
30/* Interrupt Throttling and Rate Limiting Goodies */ 30/* Interrupt Throttling and Rate Limiting Goodies */
31
32#define I40E_MAX_ITR 0x0FF0 /* reg uses 2 usec resolution */
33#define I40E_MIN_ITR 0x0001 /* reg uses 2 usec resolution */
34#define I40E_ITR_100K 0x0005
35#define I40E_ITR_50K 0x000A
36#define I40E_ITR_20K 0x0019
37#define I40E_ITR_18K 0x001B
38#define I40E_ITR_8K 0x003E
39#define I40E_ITR_4K 0x007A
40#define I40E_MAX_INTRL 0x3B /* reg uses 4 usec resolution */
41#define I40E_ITR_RX_DEF (ITR_REG_TO_USEC(I40E_ITR_20K) | \
42 I40E_ITR_DYNAMIC)
43#define I40E_ITR_TX_DEF (ITR_REG_TO_USEC(I40E_ITR_20K) | \
44 I40E_ITR_DYNAMIC)
45#define I40E_ITR_DYNAMIC 0x8000 /* use top bit as a flag */
46#define I40E_MIN_INT_RATE 250 /* ~= 1000000 / (I40E_MAX_ITR * 2) */
47#define I40E_MAX_INT_RATE 500000 /* == 1000000 / (I40E_MIN_ITR * 2) */
48#define I40E_DEFAULT_IRQ_WORK 256 31#define I40E_DEFAULT_IRQ_WORK 256
49#define ITR_TO_REG(setting) ((setting & ~I40E_ITR_DYNAMIC) >> 1) 32
50#define ITR_IS_DYNAMIC(setting) (!!(setting & I40E_ITR_DYNAMIC)) 33/* The datasheet for the X710 and XL710 indicate that the maximum value for
51#define ITR_REG_TO_USEC(itr_reg) (itr_reg << 1) 34 * the ITR is 8160usec which is then called out as 0xFF0 with a 2usec
35 * resolution. 8160 is 0x1FE0 when written out in hex. So instead of storing
36 * the register value which is divided by 2 lets use the actual values and
37 * avoid an excessive amount of translation.
38 */
39#define I40E_ITR_DYNAMIC 0x8000 /* use top bit as a flag */
40#define I40E_ITR_MASK 0x1FFE /* mask for ITR register value */
41#define I40E_MIN_ITR 2 /* reg uses 2 usec resolution */
42#define I40E_ITR_100K 10 /* all values below must be even */
43#define I40E_ITR_50K 20
44#define I40E_ITR_20K 50
45#define I40E_ITR_18K 60
46#define I40E_ITR_8K 122
47#define I40E_MAX_ITR 8160 /* maximum value as per datasheet */
48#define ITR_TO_REG(setting) ((setting) & ~I40E_ITR_DYNAMIC)
49#define ITR_REG_ALIGN(setting) __ALIGN_MASK(setting, ~I40E_ITR_MASK)
50#define ITR_IS_DYNAMIC(setting) (!!((setting) & I40E_ITR_DYNAMIC))
51
52#define I40E_ITR_RX_DEF (I40E_ITR_20K | I40E_ITR_DYNAMIC)
53#define I40E_ITR_TX_DEF (I40E_ITR_20K | I40E_ITR_DYNAMIC)
54
52/* 0x40 is the enable bit for interrupt rate limiting, and must be set if 55/* 0x40 is the enable bit for interrupt rate limiting, and must be set if
53 * the value of the rate limit is non-zero 56 * the value of the rate limit is non-zero
54 */ 57 */
55#define INTRL_ENA BIT(6) 58#define INTRL_ENA BIT(6)
59#define I40E_MAX_INTRL 0x3B /* reg uses 4 usec resolution */
56#define INTRL_REG_TO_USEC(intrl) ((intrl & ~INTRL_ENA) << 2) 60#define INTRL_REG_TO_USEC(intrl) ((intrl & ~INTRL_ENA) << 2)
57#define INTRL_USEC_TO_REG(set) ((set) ? ((set) >> 2) | INTRL_ENA : 0) 61#define INTRL_USEC_TO_REG(set) ((set) ? ((set) >> 2) | INTRL_ENA : 0)
58#define I40E_INTRL_8K 125 /* 8000 ints/sec */ 62#define I40E_INTRL_8K 125 /* 8000 ints/sec */
@@ -362,8 +366,7 @@ struct i40e_ring {
362 * these values always store the USER setting, and must be converted 366 * these values always store the USER setting, and must be converted
363 * before programming to a register. 367 * before programming to a register.
364 */ 368 */
365 u16 rx_itr_setting; 369 u16 itr_setting;
366 u16 tx_itr_setting;
367 370
368 u16 count; /* Number of descriptors */ 371 u16 count; /* Number of descriptors */
369 u16 reg_idx; /* HW register index of the ring */ 372 u16 reg_idx; /* HW register index of the ring */
@@ -425,21 +428,21 @@ static inline void clear_ring_build_skb_enabled(struct i40e_ring *ring)
425 ring->flags &= ~I40E_RXR_FLAGS_BUILD_SKB_ENABLED; 428 ring->flags &= ~I40E_RXR_FLAGS_BUILD_SKB_ENABLED;
426} 429}
427 430
428enum i40e_latency_range { 431#define I40E_ITR_ADAPTIVE_MIN_INC 0x0002
429 I40E_LOWEST_LATENCY = 0, 432#define I40E_ITR_ADAPTIVE_MIN_USECS 0x0002
430 I40E_LOW_LATENCY = 1, 433#define I40E_ITR_ADAPTIVE_MAX_USECS 0x007e
431 I40E_BULK_LATENCY = 2, 434#define I40E_ITR_ADAPTIVE_LATENCY 0x8000
432}; 435#define I40E_ITR_ADAPTIVE_BULK 0x0000
436#define ITR_IS_BULK(x) (!((x) & I40E_ITR_ADAPTIVE_LATENCY))
433 437
434struct i40e_ring_container { 438struct i40e_ring_container {
435 /* array of pointers to rings */ 439 struct i40e_ring *ring; /* pointer to linked list of ring(s) */
436 struct i40e_ring *ring; 440 unsigned long next_update; /* jiffies value of next update */
437 unsigned int total_bytes; /* total bytes processed this int */ 441 unsigned int total_bytes; /* total bytes processed this int */
438 unsigned int total_packets; /* total packets processed this int */ 442 unsigned int total_packets; /* total packets processed this int */
439 unsigned long last_itr_update; /* jiffies of last ITR update */
440 u16 count; 443 u16 count;
441 enum i40e_latency_range latency_range; 444 u16 target_itr; /* target ITR setting for ring(s) */
442 u16 itr; 445 u16 current_itr; /* current ITR setting for ring(s) */
443}; 446};
444 447
445/* iterator for handling rings in ring container */ 448/* iterator for handling rings in ring container */
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf.h b/drivers/net/ethernet/intel/i40evf/i40evf.h
index 9690c1ea019e..279dced87e47 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf.h
+++ b/drivers/net/ethernet/intel/i40evf/i40evf.h
@@ -52,7 +52,10 @@
52#include <linux/socket.h> 52#include <linux/socket.h>
53#include <linux/jiffies.h> 53#include <linux/jiffies.h>
54#include <net/ip6_checksum.h> 54#include <net/ip6_checksum.h>
55#include <net/pkt_cls.h>
55#include <net/udp.h> 56#include <net/udp.h>
57#include <net/tc_act/tc_gact.h>
58#include <net/tc_act/tc_mirred.h>
56 59
57#include "i40e_type.h" 60#include "i40e_type.h"
58#include <linux/avf/virtchnl.h> 61#include <linux/avf/virtchnl.h>
@@ -106,6 +109,7 @@ struct i40e_vsi {
106 109
107#define I40EVF_HKEY_ARRAY_SIZE ((I40E_VFQF_HKEY_MAX_INDEX + 1) * 4) 110#define I40EVF_HKEY_ARRAY_SIZE ((I40E_VFQF_HKEY_MAX_INDEX + 1) * 4)
108#define I40EVF_HLUT_ARRAY_SIZE ((I40E_VFQF_HLUT_MAX_INDEX + 1) * 4) 111#define I40EVF_HLUT_ARRAY_SIZE ((I40E_VFQF_HLUT_MAX_INDEX + 1) * 4)
112#define I40EVF_MBPS_DIVISOR 125000 /* divisor to convert to Mbps */
109 113
110/* MAX_MSIX_Q_VECTORS of these are allocated, 114/* MAX_MSIX_Q_VECTORS of these are allocated,
111 * but we only use one per queue-specific vector. 115 * but we only use one per queue-specific vector.
@@ -117,9 +121,8 @@ struct i40e_q_vector {
117 struct i40e_ring_container rx; 121 struct i40e_ring_container rx;
118 struct i40e_ring_container tx; 122 struct i40e_ring_container tx;
119 u32 ring_mask; 123 u32 ring_mask;
124 u8 itr_countdown; /* when 0 should adjust adaptive ITR */
120 u8 num_ringpairs; /* total number of ring pairs in vector */ 125 u8 num_ringpairs; /* total number of ring pairs in vector */
121#define ITR_COUNTDOWN_START 100
122 u8 itr_countdown; /* when 0 or 1 update ITR */
123 u16 v_idx; /* index in the vsi->q_vector array. */ 126 u16 v_idx; /* index in the vsi->q_vector array. */
124 u16 reg_idx; /* register index of the interrupt */ 127 u16 reg_idx; /* register index of the interrupt */
125 char name[IFNAMSIZ + 15]; 128 char name[IFNAMSIZ + 15];
@@ -169,6 +172,28 @@ struct i40evf_vlan_filter {
169 bool add; /* filter needs to be added */ 172 bool add; /* filter needs to be added */
170}; 173};
171 174
175#define I40EVF_MAX_TRAFFIC_CLASS 4
176/* State of traffic class creation */
177enum i40evf_tc_state_t {
178 __I40EVF_TC_INVALID, /* no traffic class, default state */
179 __I40EVF_TC_RUNNING, /* traffic classes have been created */
180};
181
182/* channel info */
183struct i40evf_channel_config {
184 struct virtchnl_channel_info ch_info[I40EVF_MAX_TRAFFIC_CLASS];
185 enum i40evf_tc_state_t state;
186 u8 total_qps;
187};
188
189/* State of cloud filter */
190enum i40evf_cloud_filter_state_t {
191 __I40EVF_CF_INVALID, /* cloud filter not added */
192 __I40EVF_CF_ADD_PENDING, /* cloud filter pending add by the PF */
193 __I40EVF_CF_DEL_PENDING, /* cloud filter pending del by the PF */
194 __I40EVF_CF_ACTIVE, /* cloud filter is active */
195};
196
172/* Driver state. The order of these is important! */ 197/* Driver state. The order of these is important! */
173enum i40evf_state_t { 198enum i40evf_state_t {
174 __I40EVF_STARTUP, /* driver loaded, probe complete */ 199 __I40EVF_STARTUP, /* driver loaded, probe complete */
@@ -190,6 +215,36 @@ enum i40evf_critical_section_t {
190 __I40EVF_IN_REMOVE_TASK, /* device being removed */ 215 __I40EVF_IN_REMOVE_TASK, /* device being removed */
191}; 216};
192 217
218#define I40EVF_CLOUD_FIELD_OMAC 0x01
219#define I40EVF_CLOUD_FIELD_IMAC 0x02
220#define I40EVF_CLOUD_FIELD_IVLAN 0x04
221#define I40EVF_CLOUD_FIELD_TEN_ID 0x08
222#define I40EVF_CLOUD_FIELD_IIP 0x10
223
224#define I40EVF_CF_FLAGS_OMAC I40EVF_CLOUD_FIELD_OMAC
225#define I40EVF_CF_FLAGS_IMAC I40EVF_CLOUD_FIELD_IMAC
226#define I40EVF_CF_FLAGS_IMAC_IVLAN (I40EVF_CLOUD_FIELD_IMAC |\
227 I40EVF_CLOUD_FIELD_IVLAN)
228#define I40EVF_CF_FLAGS_IMAC_TEN_ID (I40EVF_CLOUD_FIELD_IMAC |\
229 I40EVF_CLOUD_FIELD_TEN_ID)
230#define I40EVF_CF_FLAGS_OMAC_TEN_ID_IMAC (I40EVF_CLOUD_FIELD_OMAC |\
231 I40EVF_CLOUD_FIELD_IMAC |\
232 I40EVF_CLOUD_FIELD_TEN_ID)
233#define I40EVF_CF_FLAGS_IMAC_IVLAN_TEN_ID (I40EVF_CLOUD_FIELD_IMAC |\
234 I40EVF_CLOUD_FIELD_IVLAN |\
235 I40EVF_CLOUD_FIELD_TEN_ID)
236#define I40EVF_CF_FLAGS_IIP I40E_CLOUD_FIELD_IIP
237
238/* bookkeeping of cloud filters */
239struct i40evf_cloud_filter {
240 enum i40evf_cloud_filter_state_t state;
241 struct list_head list;
242 struct virtchnl_filter f;
243 unsigned long cookie;
244 bool del; /* filter needs to be deleted */
245 bool add; /* filter needs to be added */
246};
247
193/* board specific private data structure */ 248/* board specific private data structure */
194struct i40evf_adapter { 249struct i40evf_adapter {
195 struct timer_list watchdog_timer; 250 struct timer_list watchdog_timer;
@@ -225,13 +280,10 @@ struct i40evf_adapter {
225 280
226 u32 flags; 281 u32 flags;
227#define I40EVF_FLAG_RX_CSUM_ENABLED BIT(0) 282#define I40EVF_FLAG_RX_CSUM_ENABLED BIT(0)
228#define I40EVF_FLAG_IMIR_ENABLED BIT(1)
229#define I40EVF_FLAG_MQ_CAPABLE BIT(2)
230#define I40EVF_FLAG_PF_COMMS_FAILED BIT(3) 283#define I40EVF_FLAG_PF_COMMS_FAILED BIT(3)
231#define I40EVF_FLAG_RESET_PENDING BIT(4) 284#define I40EVF_FLAG_RESET_PENDING BIT(4)
232#define I40EVF_FLAG_RESET_NEEDED BIT(5) 285#define I40EVF_FLAG_RESET_NEEDED BIT(5)
233#define I40EVF_FLAG_WB_ON_ITR_CAPABLE BIT(6) 286#define I40EVF_FLAG_WB_ON_ITR_CAPABLE BIT(6)
234#define I40EVF_FLAG_OUTER_UDP_CSUM_CAPABLE BIT(7)
235#define I40EVF_FLAG_ADDR_SET_BY_PF BIT(8) 287#define I40EVF_FLAG_ADDR_SET_BY_PF BIT(8)
236#define I40EVF_FLAG_SERVICE_CLIENT_REQUESTED BIT(9) 288#define I40EVF_FLAG_SERVICE_CLIENT_REQUESTED BIT(9)
237#define I40EVF_FLAG_CLIENT_NEEDS_OPEN BIT(10) 289#define I40EVF_FLAG_CLIENT_NEEDS_OPEN BIT(10)
@@ -241,6 +293,7 @@ struct i40evf_adapter {
241#define I40EVF_FLAG_ALLMULTI_ON BIT(14) 293#define I40EVF_FLAG_ALLMULTI_ON BIT(14)
242#define I40EVF_FLAG_LEGACY_RX BIT(15) 294#define I40EVF_FLAG_LEGACY_RX BIT(15)
243#define I40EVF_FLAG_REINIT_ITR_NEEDED BIT(16) 295#define I40EVF_FLAG_REINIT_ITR_NEEDED BIT(16)
296#define I40EVF_FLAG_QUEUES_DISABLED BIT(17)
244/* duplicates for common code */ 297/* duplicates for common code */
245#define I40E_FLAG_DCB_ENABLED 0 298#define I40E_FLAG_DCB_ENABLED 0
246#define I40E_FLAG_RX_CSUM_ENABLED I40EVF_FLAG_RX_CSUM_ENABLED 299#define I40E_FLAG_RX_CSUM_ENABLED I40EVF_FLAG_RX_CSUM_ENABLED
@@ -269,6 +322,10 @@ struct i40evf_adapter {
269#define I40EVF_FLAG_AQ_RELEASE_ALLMULTI BIT(18) 322#define I40EVF_FLAG_AQ_RELEASE_ALLMULTI BIT(18)
270#define I40EVF_FLAG_AQ_ENABLE_VLAN_STRIPPING BIT(19) 323#define I40EVF_FLAG_AQ_ENABLE_VLAN_STRIPPING BIT(19)
271#define I40EVF_FLAG_AQ_DISABLE_VLAN_STRIPPING BIT(20) 324#define I40EVF_FLAG_AQ_DISABLE_VLAN_STRIPPING BIT(20)
325#define I40EVF_FLAG_AQ_ENABLE_CHANNELS BIT(21)
326#define I40EVF_FLAG_AQ_DISABLE_CHANNELS BIT(22)
327#define I40EVF_FLAG_AQ_ADD_CLOUD_FILTER BIT(23)
328#define I40EVF_FLAG_AQ_DEL_CLOUD_FILTER BIT(24)
272 329
273 /* OS defined structs */ 330 /* OS defined structs */
274 struct net_device *netdev; 331 struct net_device *netdev;
@@ -314,6 +371,13 @@ struct i40evf_adapter {
314 u16 rss_lut_size; 371 u16 rss_lut_size;
315 u8 *rss_key; 372 u8 *rss_key;
316 u8 *rss_lut; 373 u8 *rss_lut;
374 /* ADQ related members */
375 struct i40evf_channel_config ch_config;
376 u8 num_tc;
377 struct list_head cloud_filter_list;
378 /* lock to protest access to the cloud filter list */
379 spinlock_t cloud_filter_list_lock;
380 u16 num_cloud_filters;
317}; 381};
318 382
319 383
@@ -380,4 +444,8 @@ void i40evf_notify_client_message(struct i40e_vsi *vsi, u8 *msg, u16 len);
380void i40evf_notify_client_l2_params(struct i40e_vsi *vsi); 444void i40evf_notify_client_l2_params(struct i40e_vsi *vsi);
381void i40evf_notify_client_open(struct i40e_vsi *vsi); 445void i40evf_notify_client_open(struct i40e_vsi *vsi);
382void i40evf_notify_client_close(struct i40e_vsi *vsi, bool reset); 446void i40evf_notify_client_close(struct i40e_vsi *vsi, bool reset);
447void i40evf_enable_channels(struct i40evf_adapter *adapter);
448void i40evf_disable_channels(struct i40evf_adapter *adapter);
449void i40evf_add_cloud_filter(struct i40evf_adapter *adapter);
450void i40evf_del_cloud_filter(struct i40evf_adapter *adapter);
383#endif /* _I40EVF_H_ */ 451#endif /* _I40EVF_H_ */
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
index e2d8aa19d205..e6793255de0b 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
@@ -457,14 +457,14 @@ static int __i40evf_get_coalesce(struct net_device *netdev,
457 rx_ring = &adapter->rx_rings[queue]; 457 rx_ring = &adapter->rx_rings[queue];
458 tx_ring = &adapter->tx_rings[queue]; 458 tx_ring = &adapter->tx_rings[queue];
459 459
460 if (ITR_IS_DYNAMIC(rx_ring->rx_itr_setting)) 460 if (ITR_IS_DYNAMIC(rx_ring->itr_setting))
461 ec->use_adaptive_rx_coalesce = 1; 461 ec->use_adaptive_rx_coalesce = 1;
462 462
463 if (ITR_IS_DYNAMIC(tx_ring->tx_itr_setting)) 463 if (ITR_IS_DYNAMIC(tx_ring->itr_setting))
464 ec->use_adaptive_tx_coalesce = 1; 464 ec->use_adaptive_tx_coalesce = 1;
465 465
466 ec->rx_coalesce_usecs = rx_ring->rx_itr_setting & ~I40E_ITR_DYNAMIC; 466 ec->rx_coalesce_usecs = rx_ring->itr_setting & ~I40E_ITR_DYNAMIC;
467 ec->tx_coalesce_usecs = tx_ring->tx_itr_setting & ~I40E_ITR_DYNAMIC; 467 ec->tx_coalesce_usecs = tx_ring->itr_setting & ~I40E_ITR_DYNAMIC;
468 468
469 return 0; 469 return 0;
470} 470}
@@ -502,7 +502,7 @@ static int i40evf_get_per_queue_coalesce(struct net_device *netdev,
502 502
503/** 503/**
504 * i40evf_set_itr_per_queue - set ITR values for specific queue 504 * i40evf_set_itr_per_queue - set ITR values for specific queue
505 * @vsi: the VSI to set values for 505 * @adapter: the VF adapter struct to set values for
506 * @ec: coalesce settings from ethtool 506 * @ec: coalesce settings from ethtool
507 * @queue: the queue to modify 507 * @queue: the queue to modify
508 * 508 *
@@ -514,33 +514,29 @@ static void i40evf_set_itr_per_queue(struct i40evf_adapter *adapter,
514{ 514{
515 struct i40e_ring *rx_ring = &adapter->rx_rings[queue]; 515 struct i40e_ring *rx_ring = &adapter->rx_rings[queue];
516 struct i40e_ring *tx_ring = &adapter->tx_rings[queue]; 516 struct i40e_ring *tx_ring = &adapter->tx_rings[queue];
517 struct i40e_vsi *vsi = &adapter->vsi;
518 struct i40e_hw *hw = &adapter->hw;
519 struct i40e_q_vector *q_vector; 517 struct i40e_q_vector *q_vector;
520 u16 vector;
521 518
522 rx_ring->rx_itr_setting = ec->rx_coalesce_usecs; 519 rx_ring->itr_setting = ITR_REG_ALIGN(ec->rx_coalesce_usecs);
523 tx_ring->tx_itr_setting = ec->tx_coalesce_usecs; 520 tx_ring->itr_setting = ITR_REG_ALIGN(ec->tx_coalesce_usecs);
524 521
525 rx_ring->rx_itr_setting |= I40E_ITR_DYNAMIC; 522 rx_ring->itr_setting |= I40E_ITR_DYNAMIC;
526 if (!ec->use_adaptive_rx_coalesce) 523 if (!ec->use_adaptive_rx_coalesce)
527 rx_ring->rx_itr_setting ^= I40E_ITR_DYNAMIC; 524 rx_ring->itr_setting ^= I40E_ITR_DYNAMIC;
528 525
529 tx_ring->tx_itr_setting |= I40E_ITR_DYNAMIC; 526 tx_ring->itr_setting |= I40E_ITR_DYNAMIC;
530 if (!ec->use_adaptive_tx_coalesce) 527 if (!ec->use_adaptive_tx_coalesce)
531 tx_ring->tx_itr_setting ^= I40E_ITR_DYNAMIC; 528 tx_ring->itr_setting ^= I40E_ITR_DYNAMIC;
532 529
533 q_vector = rx_ring->q_vector; 530 q_vector = rx_ring->q_vector;
534 q_vector->rx.itr = ITR_TO_REG(rx_ring->rx_itr_setting); 531 q_vector->rx.target_itr = ITR_TO_REG(rx_ring->itr_setting);
535 vector = vsi->base_vector + q_vector->v_idx;
536 wr32(hw, I40E_VFINT_ITRN1(I40E_RX_ITR, vector - 1), q_vector->rx.itr);
537 532
538 q_vector = tx_ring->q_vector; 533 q_vector = tx_ring->q_vector;
539 q_vector->tx.itr = ITR_TO_REG(tx_ring->tx_itr_setting); 534 q_vector->tx.target_itr = ITR_TO_REG(tx_ring->itr_setting);
540 vector = vsi->base_vector + q_vector->v_idx;
541 wr32(hw, I40E_VFINT_ITRN1(I40E_TX_ITR, vector - 1), q_vector->tx.itr);
542 535
543 i40e_flush(hw); 536 /* The interrupt handler itself will take care of programming
537 * the Tx and Rx ITR values based on the values we have entered
538 * into the q_vector, no need to write the values now.
539 */
544} 540}
545 541
546/** 542/**
@@ -565,8 +561,8 @@ static int __i40evf_set_coalesce(struct net_device *netdev,
565 if (ec->rx_coalesce_usecs == 0) { 561 if (ec->rx_coalesce_usecs == 0) {
566 if (ec->use_adaptive_rx_coalesce) 562 if (ec->use_adaptive_rx_coalesce)
567 netif_info(adapter, drv, netdev, "rx-usecs=0, need to disable adaptive-rx for a complete disable\n"); 563 netif_info(adapter, drv, netdev, "rx-usecs=0, need to disable adaptive-rx for a complete disable\n");
568 } else if ((ec->rx_coalesce_usecs < (I40E_MIN_ITR << 1)) || 564 } else if ((ec->rx_coalesce_usecs < I40E_MIN_ITR) ||
569 (ec->rx_coalesce_usecs > (I40E_MAX_ITR << 1))) { 565 (ec->rx_coalesce_usecs > I40E_MAX_ITR)) {
570 netif_info(adapter, drv, netdev, "Invalid value, rx-usecs range is 0-8160\n"); 566 netif_info(adapter, drv, netdev, "Invalid value, rx-usecs range is 0-8160\n");
571 return -EINVAL; 567 return -EINVAL;
572 } 568 }
@@ -575,8 +571,8 @@ static int __i40evf_set_coalesce(struct net_device *netdev,
575 if (ec->tx_coalesce_usecs == 0) { 571 if (ec->tx_coalesce_usecs == 0) {
576 if (ec->use_adaptive_tx_coalesce) 572 if (ec->use_adaptive_tx_coalesce)
577 netif_info(adapter, drv, netdev, "tx-usecs=0, need to disable adaptive-tx for a complete disable\n"); 573 netif_info(adapter, drv, netdev, "tx-usecs=0, need to disable adaptive-tx for a complete disable\n");
578 } else if ((ec->tx_coalesce_usecs < (I40E_MIN_ITR << 1)) || 574 } else if ((ec->tx_coalesce_usecs < I40E_MIN_ITR) ||
579 (ec->tx_coalesce_usecs > (I40E_MAX_ITR << 1))) { 575 (ec->tx_coalesce_usecs > I40E_MAX_ITR)) {
580 netif_info(adapter, drv, netdev, "Invalid value, tx-usecs range is 0-8160\n"); 576 netif_info(adapter, drv, netdev, "Invalid value, tx-usecs range is 0-8160\n");
581 return -EINVAL; 577 return -EINVAL;
582 } 578 }
@@ -699,6 +695,12 @@ static int i40evf_set_channels(struct net_device *netdev,
699 return -EINVAL; 695 return -EINVAL;
700 } 696 }
701 697
698 if ((adapter->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_ADQ) &&
699 adapter->num_tc) {
700 dev_info(&adapter->pdev->dev, "Cannot set channels since ADq is enabled.\n");
701 return -EINVAL;
702 }
703
702 /* All of these should have already been checked by ethtool before this 704 /* All of these should have already been checked by ethtool before this
703 * even gets to us, but just to be sure. 705 * even gets to us, but just to be sure.
704 */ 706 */
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
index 16989ad2ca90..7e7cd80abaf4 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
@@ -353,11 +353,12 @@ i40evf_map_vector_to_rxq(struct i40evf_adapter *adapter, int v_idx, int r_idx)
353 rx_ring->vsi = &adapter->vsi; 353 rx_ring->vsi = &adapter->vsi;
354 q_vector->rx.ring = rx_ring; 354 q_vector->rx.ring = rx_ring;
355 q_vector->rx.count++; 355 q_vector->rx.count++;
356 q_vector->rx.latency_range = I40E_LOW_LATENCY; 356 q_vector->rx.next_update = jiffies + 1;
357 q_vector->rx.itr = ITR_TO_REG(rx_ring->rx_itr_setting); 357 q_vector->rx.target_itr = ITR_TO_REG(rx_ring->itr_setting);
358 q_vector->ring_mask |= BIT(r_idx); 358 q_vector->ring_mask |= BIT(r_idx);
359 q_vector->itr_countdown = ITR_COUNTDOWN_START; 359 wr32(hw, I40E_VFINT_ITRN1(I40E_RX_ITR, q_vector->reg_idx),
360 wr32(hw, I40E_VFINT_ITRN1(I40E_RX_ITR, v_idx - 1), q_vector->rx.itr); 360 q_vector->rx.current_itr);
361 q_vector->rx.current_itr = q_vector->rx.target_itr;
361} 362}
362 363
363/** 364/**
@@ -378,11 +379,12 @@ i40evf_map_vector_to_txq(struct i40evf_adapter *adapter, int v_idx, int t_idx)
378 tx_ring->vsi = &adapter->vsi; 379 tx_ring->vsi = &adapter->vsi;
379 q_vector->tx.ring = tx_ring; 380 q_vector->tx.ring = tx_ring;
380 q_vector->tx.count++; 381 q_vector->tx.count++;
381 q_vector->tx.latency_range = I40E_LOW_LATENCY; 382 q_vector->tx.next_update = jiffies + 1;
382 q_vector->tx.itr = ITR_TO_REG(tx_ring->tx_itr_setting); 383 q_vector->tx.target_itr = ITR_TO_REG(tx_ring->itr_setting);
383 q_vector->itr_countdown = ITR_COUNTDOWN_START;
384 q_vector->num_ringpairs++; 384 q_vector->num_ringpairs++;
385 wr32(hw, I40E_VFINT_ITRN1(I40E_TX_ITR, v_idx - 1), q_vector->tx.itr); 385 wr32(hw, I40E_VFINT_ITRN1(I40E_TX_ITR, q_vector->reg_idx),
386 q_vector->tx.target_itr);
387 q_vector->tx.current_itr = q_vector->tx.target_itr;
386} 388}
387 389
388/** 390/**
@@ -783,7 +785,7 @@ static int i40evf_vlan_rx_kill_vid(struct net_device *netdev,
783 **/ 785 **/
784static struct 786static struct
785i40evf_mac_filter *i40evf_find_filter(struct i40evf_adapter *adapter, 787i40evf_mac_filter *i40evf_find_filter(struct i40evf_adapter *adapter,
786 u8 *macaddr) 788 const u8 *macaddr)
787{ 789{
788 struct i40evf_mac_filter *f; 790 struct i40evf_mac_filter *f;
789 791
@@ -806,20 +808,18 @@ i40evf_mac_filter *i40evf_find_filter(struct i40evf_adapter *adapter,
806 **/ 808 **/
807static struct 809static struct
808i40evf_mac_filter *i40evf_add_filter(struct i40evf_adapter *adapter, 810i40evf_mac_filter *i40evf_add_filter(struct i40evf_adapter *adapter,
809 u8 *macaddr) 811 const u8 *macaddr)
810{ 812{
811 struct i40evf_mac_filter *f; 813 struct i40evf_mac_filter *f;
812 814
813 if (!macaddr) 815 if (!macaddr)
814 return NULL; 816 return NULL;
815 817
816 spin_lock_bh(&adapter->mac_vlan_list_lock);
817
818 f = i40evf_find_filter(adapter, macaddr); 818 f = i40evf_find_filter(adapter, macaddr);
819 if (!f) { 819 if (!f) {
820 f = kzalloc(sizeof(*f), GFP_ATOMIC); 820 f = kzalloc(sizeof(*f), GFP_ATOMIC);
821 if (!f) 821 if (!f)
822 goto clearout; 822 return f;
823 823
824 ether_addr_copy(f->macaddr, macaddr); 824 ether_addr_copy(f->macaddr, macaddr);
825 825
@@ -830,8 +830,6 @@ i40evf_mac_filter *i40evf_add_filter(struct i40evf_adapter *adapter,
830 f->remove = false; 830 f->remove = false;
831 } 831 }
832 832
833clearout:
834 spin_unlock_bh(&adapter->mac_vlan_list_lock);
835 return f; 833 return f;
836} 834}
837 835
@@ -866,9 +864,10 @@ static int i40evf_set_mac(struct net_device *netdev, void *p)
866 adapter->aq_required |= I40EVF_FLAG_AQ_DEL_MAC_FILTER; 864 adapter->aq_required |= I40EVF_FLAG_AQ_DEL_MAC_FILTER;
867 } 865 }
868 866
867 f = i40evf_add_filter(adapter, addr->sa_data);
868
869 spin_unlock_bh(&adapter->mac_vlan_list_lock); 869 spin_unlock_bh(&adapter->mac_vlan_list_lock);
870 870
871 f = i40evf_add_filter(adapter, addr->sa_data);
872 if (f) { 871 if (f) {
873 ether_addr_copy(hw->mac.addr, addr->sa_data); 872 ether_addr_copy(hw->mac.addr, addr->sa_data);
874 ether_addr_copy(netdev->dev_addr, adapter->hw.mac.addr); 873 ether_addr_copy(netdev->dev_addr, adapter->hw.mac.addr);
@@ -878,50 +877,64 @@ static int i40evf_set_mac(struct net_device *netdev, void *p)
878} 877}
879 878
880/** 879/**
881 * i40evf_set_rx_mode - NDO callback to set the netdev filters 880 * i40evf_addr_sync - Callback for dev_(mc|uc)_sync to add address
882 * @netdev: network interface device structure 881 * @netdev: the netdevice
883 **/ 882 * @addr: address to add
884static void i40evf_set_rx_mode(struct net_device *netdev) 883 *
884 * Called by __dev_(mc|uc)_sync when an address needs to be added. We call
885 * __dev_(uc|mc)_sync from .set_rx_mode and guarantee to hold the hash lock.
886 */
887static int i40evf_addr_sync(struct net_device *netdev, const u8 *addr)
885{ 888{
886 struct i40evf_adapter *adapter = netdev_priv(netdev); 889 struct i40evf_adapter *adapter = netdev_priv(netdev);
887 struct i40evf_mac_filter *f, *ftmp;
888 struct netdev_hw_addr *uca;
889 struct netdev_hw_addr *mca;
890 struct netdev_hw_addr *ha;
891
892 /* add addr if not already in the filter list */
893 netdev_for_each_uc_addr(uca, netdev) {
894 i40evf_add_filter(adapter, uca->addr);
895 }
896 netdev_for_each_mc_addr(mca, netdev) {
897 i40evf_add_filter(adapter, mca->addr);
898 }
899 890
900 spin_lock_bh(&adapter->mac_vlan_list_lock); 891 if (i40evf_add_filter(adapter, addr))
901 892 return 0;
902 list_for_each_entry_safe(f, ftmp, &adapter->mac_filter_list, list) { 893 else
903 netdev_for_each_mc_addr(mca, netdev) 894 return -ENOMEM;
904 if (ether_addr_equal(mca->addr, f->macaddr)) 895}
905 goto bottom_of_search_loop;
906
907 netdev_for_each_uc_addr(uca, netdev)
908 if (ether_addr_equal(uca->addr, f->macaddr))
909 goto bottom_of_search_loop;
910 896
911 for_each_dev_addr(netdev, ha) 897/**
912 if (ether_addr_equal(ha->addr, f->macaddr)) 898 * i40evf_addr_unsync - Callback for dev_(mc|uc)_sync to remove address
913 goto bottom_of_search_loop; 899 * @netdev: the netdevice
900 * @addr: address to add
901 *
902 * Called by __dev_(mc|uc)_sync when an address needs to be removed. We call
903 * __dev_(uc|mc)_sync from .set_rx_mode and guarantee to hold the hash lock.
904 */
905static int i40evf_addr_unsync(struct net_device *netdev, const u8 *addr)
906{
907 struct i40evf_adapter *adapter = netdev_priv(netdev);
908 struct i40evf_mac_filter *f;
914 909
915 if (ether_addr_equal(f->macaddr, adapter->hw.mac.addr)) 910 /* Under some circumstances, we might receive a request to delete
916 goto bottom_of_search_loop; 911 * our own device address from our uc list. Because we store the
912 * device address in the VSI's MAC/VLAN filter list, we need to ignore
913 * such requests and not delete our device address from this list.
914 */
915 if (ether_addr_equal(addr, netdev->dev_addr))
916 return 0;
917 917
918 /* f->macaddr wasn't found in uc, mc, or ha list so delete it */ 918 f = i40evf_find_filter(adapter, addr);
919 if (f) {
919 f->remove = true; 920 f->remove = true;
920 adapter->aq_required |= I40EVF_FLAG_AQ_DEL_MAC_FILTER; 921 adapter->aq_required |= I40EVF_FLAG_AQ_DEL_MAC_FILTER;
921
922bottom_of_search_loop:
923 continue;
924 } 922 }
923 return 0;
924}
925
926/**
927 * i40evf_set_rx_mode - NDO callback to set the netdev filters
928 * @netdev: network interface device structure
929 **/
930static void i40evf_set_rx_mode(struct net_device *netdev)
931{
932 struct i40evf_adapter *adapter = netdev_priv(netdev);
933
934 spin_lock_bh(&adapter->mac_vlan_list_lock);
935 __dev_uc_sync(netdev, i40evf_addr_sync, i40evf_addr_unsync);
936 __dev_mc_sync(netdev, i40evf_addr_sync, i40evf_addr_unsync);
937 spin_unlock_bh(&adapter->mac_vlan_list_lock);
925 938
926 if (netdev->flags & IFF_PROMISC && 939 if (netdev->flags & IFF_PROMISC &&
927 !(adapter->flags & I40EVF_FLAG_PROMISC_ON)) 940 !(adapter->flags & I40EVF_FLAG_PROMISC_ON))
@@ -936,8 +949,6 @@ bottom_of_search_loop:
936 else if (!(netdev->flags & IFF_ALLMULTI) && 949 else if (!(netdev->flags & IFF_ALLMULTI) &&
937 adapter->flags & I40EVF_FLAG_ALLMULTI_ON) 950 adapter->flags & I40EVF_FLAG_ALLMULTI_ON)
938 adapter->aq_required |= I40EVF_FLAG_AQ_RELEASE_ALLMULTI; 951 adapter->aq_required |= I40EVF_FLAG_AQ_RELEASE_ALLMULTI;
939
940 spin_unlock_bh(&adapter->mac_vlan_list_lock);
941} 952}
942 953
943/** 954/**
@@ -1025,7 +1036,9 @@ static void i40evf_up_complete(struct i40evf_adapter *adapter)
1025void i40evf_down(struct i40evf_adapter *adapter) 1036void i40evf_down(struct i40evf_adapter *adapter)
1026{ 1037{
1027 struct net_device *netdev = adapter->netdev; 1038 struct net_device *netdev = adapter->netdev;
1039 struct i40evf_vlan_filter *vlf;
1028 struct i40evf_mac_filter *f; 1040 struct i40evf_mac_filter *f;
1041 struct i40evf_cloud_filter *cf;
1029 1042
1030 if (adapter->state <= __I40EVF_DOWN_PENDING) 1043 if (adapter->state <= __I40EVF_DOWN_PENDING)
1031 return; 1044 return;
@@ -1038,17 +1051,29 @@ void i40evf_down(struct i40evf_adapter *adapter)
1038 1051
1039 spin_lock_bh(&adapter->mac_vlan_list_lock); 1052 spin_lock_bh(&adapter->mac_vlan_list_lock);
1040 1053
1054 /* clear the sync flag on all filters */
1055 __dev_uc_unsync(adapter->netdev, NULL);
1056 __dev_mc_unsync(adapter->netdev, NULL);
1057
1041 /* remove all MAC filters */ 1058 /* remove all MAC filters */
1042 list_for_each_entry(f, &adapter->mac_filter_list, list) { 1059 list_for_each_entry(f, &adapter->mac_filter_list, list) {
1043 f->remove = true; 1060 f->remove = true;
1044 } 1061 }
1062
1045 /* remove all VLAN filters */ 1063 /* remove all VLAN filters */
1046 list_for_each_entry(f, &adapter->vlan_filter_list, list) { 1064 list_for_each_entry(vlf, &adapter->vlan_filter_list, list) {
1047 f->remove = true; 1065 vlf->remove = true;
1048 } 1066 }
1049 1067
1050 spin_unlock_bh(&adapter->mac_vlan_list_lock); 1068 spin_unlock_bh(&adapter->mac_vlan_list_lock);
1051 1069
1070 /* remove all cloud filters */
1071 spin_lock_bh(&adapter->cloud_filter_list_lock);
1072 list_for_each_entry(cf, &adapter->cloud_filter_list, list) {
1073 cf->del = true;
1074 }
1075 spin_unlock_bh(&adapter->cloud_filter_list_lock);
1076
1052 if (!(adapter->flags & I40EVF_FLAG_PF_COMMS_FAILED) && 1077 if (!(adapter->flags & I40EVF_FLAG_PF_COMMS_FAILED) &&
1053 adapter->state != __I40EVF_RESETTING) { 1078 adapter->state != __I40EVF_RESETTING) {
1054 /* cancel any current operation */ 1079 /* cancel any current operation */
@@ -1059,6 +1084,7 @@ void i40evf_down(struct i40evf_adapter *adapter)
1059 */ 1084 */
1060 adapter->aq_required = I40EVF_FLAG_AQ_DEL_MAC_FILTER; 1085 adapter->aq_required = I40EVF_FLAG_AQ_DEL_MAC_FILTER;
1061 adapter->aq_required |= I40EVF_FLAG_AQ_DEL_VLAN_FILTER; 1086 adapter->aq_required |= I40EVF_FLAG_AQ_DEL_VLAN_FILTER;
1087 adapter->aq_required |= I40EVF_FLAG_AQ_DEL_CLOUD_FILTER;
1062 adapter->aq_required |= I40EVF_FLAG_AQ_DISABLE_QUEUES; 1088 adapter->aq_required |= I40EVF_FLAG_AQ_DISABLE_QUEUES;
1063 } 1089 }
1064 1090
@@ -1144,6 +1170,9 @@ static int i40evf_alloc_queues(struct i40evf_adapter *adapter)
1144 */ 1170 */
1145 if (adapter->num_req_queues) 1171 if (adapter->num_req_queues)
1146 num_active_queues = adapter->num_req_queues; 1172 num_active_queues = adapter->num_req_queues;
1173 else if ((adapter->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_ADQ) &&
1174 adapter->num_tc)
1175 num_active_queues = adapter->ch_config.total_qps;
1147 else 1176 else
1148 num_active_queues = min_t(int, 1177 num_active_queues = min_t(int,
1149 adapter->vsi_res->num_queue_pairs, 1178 adapter->vsi_res->num_queue_pairs,
@@ -1169,7 +1198,7 @@ static int i40evf_alloc_queues(struct i40evf_adapter *adapter)
1169 tx_ring->netdev = adapter->netdev; 1198 tx_ring->netdev = adapter->netdev;
1170 tx_ring->dev = &adapter->pdev->dev; 1199 tx_ring->dev = &adapter->pdev->dev;
1171 tx_ring->count = adapter->tx_desc_count; 1200 tx_ring->count = adapter->tx_desc_count;
1172 tx_ring->tx_itr_setting = I40E_ITR_TX_DEF; 1201 tx_ring->itr_setting = I40E_ITR_TX_DEF;
1173 if (adapter->flags & I40EVF_FLAG_WB_ON_ITR_CAPABLE) 1202 if (adapter->flags & I40EVF_FLAG_WB_ON_ITR_CAPABLE)
1174 tx_ring->flags |= I40E_TXR_FLAGS_WB_ON_ITR; 1203 tx_ring->flags |= I40E_TXR_FLAGS_WB_ON_ITR;
1175 1204
@@ -1178,7 +1207,7 @@ static int i40evf_alloc_queues(struct i40evf_adapter *adapter)
1178 rx_ring->netdev = adapter->netdev; 1207 rx_ring->netdev = adapter->netdev;
1179 rx_ring->dev = &adapter->pdev->dev; 1208 rx_ring->dev = &adapter->pdev->dev;
1180 rx_ring->count = adapter->rx_desc_count; 1209 rx_ring->count = adapter->rx_desc_count;
1181 rx_ring->rx_itr_setting = I40E_ITR_RX_DEF; 1210 rx_ring->itr_setting = I40E_ITR_RX_DEF;
1182 } 1211 }
1183 1212
1184 adapter->num_active_queues = num_active_queues; 1213 adapter->num_active_queues = num_active_queues;
@@ -1471,6 +1500,16 @@ int i40evf_init_interrupt_scheme(struct i40evf_adapter *adapter)
1471 goto err_alloc_q_vectors; 1500 goto err_alloc_q_vectors;
1472 } 1501 }
1473 1502
1503 /* If we've made it so far while ADq flag being ON, then we haven't
1504 * bailed out anywhere in middle. And ADq isn't just enabled but actual
1505 * resources have been allocated in the reset path.
1506 * Now we can truly claim that ADq is enabled.
1507 */
1508 if ((adapter->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_ADQ) &&
1509 adapter->num_tc)
1510 dev_info(&adapter->pdev->dev, "ADq Enabled, %u TCs created",
1511 adapter->num_tc);
1512
1474 dev_info(&adapter->pdev->dev, "Multiqueue %s: Queue pair count = %u", 1513 dev_info(&adapter->pdev->dev, "Multiqueue %s: Queue pair count = %u",
1475 (adapter->num_active_queues > 1) ? "Enabled" : "Disabled", 1514 (adapter->num_active_queues > 1) ? "Enabled" : "Disabled",
1476 adapter->num_active_queues); 1515 adapter->num_active_queues);
@@ -1712,6 +1751,27 @@ static void i40evf_watchdog_task(struct work_struct *work)
1712 i40evf_set_promiscuous(adapter, 0); 1751 i40evf_set_promiscuous(adapter, 0);
1713 goto watchdog_done; 1752 goto watchdog_done;
1714 } 1753 }
1754
1755 if (adapter->aq_required & I40EVF_FLAG_AQ_ENABLE_CHANNELS) {
1756 i40evf_enable_channels(adapter);
1757 goto watchdog_done;
1758 }
1759
1760 if (adapter->aq_required & I40EVF_FLAG_AQ_DISABLE_CHANNELS) {
1761 i40evf_disable_channels(adapter);
1762 goto watchdog_done;
1763 }
1764
1765 if (adapter->aq_required & I40EVF_FLAG_AQ_ADD_CLOUD_FILTER) {
1766 i40evf_add_cloud_filter(adapter);
1767 goto watchdog_done;
1768 }
1769
1770 if (adapter->aq_required & I40EVF_FLAG_AQ_DEL_CLOUD_FILTER) {
1771 i40evf_del_cloud_filter(adapter);
1772 goto watchdog_done;
1773 }
1774
1715 schedule_delayed_work(&adapter->client_task, msecs_to_jiffies(5)); 1775 schedule_delayed_work(&adapter->client_task, msecs_to_jiffies(5));
1716 1776
1717 if (adapter->state == __I40EVF_RUNNING) 1777 if (adapter->state == __I40EVF_RUNNING)
@@ -1735,6 +1795,7 @@ static void i40evf_disable_vf(struct i40evf_adapter *adapter)
1735{ 1795{
1736 struct i40evf_mac_filter *f, *ftmp; 1796 struct i40evf_mac_filter *f, *ftmp;
1737 struct i40evf_vlan_filter *fv, *fvtmp; 1797 struct i40evf_vlan_filter *fv, *fvtmp;
1798 struct i40evf_cloud_filter *cf, *cftmp;
1738 1799
1739 adapter->flags |= I40EVF_FLAG_PF_COMMS_FAILED; 1800 adapter->flags |= I40EVF_FLAG_PF_COMMS_FAILED;
1740 1801
@@ -1756,7 +1817,7 @@ static void i40evf_disable_vf(struct i40evf_adapter *adapter)
1756 1817
1757 spin_lock_bh(&adapter->mac_vlan_list_lock); 1818 spin_lock_bh(&adapter->mac_vlan_list_lock);
1758 1819
1759 /* Delete all of the filters, both MAC and VLAN. */ 1820 /* Delete all of the filters */
1760 list_for_each_entry_safe(f, ftmp, &adapter->mac_filter_list, list) { 1821 list_for_each_entry_safe(f, ftmp, &adapter->mac_filter_list, list) {
1761 list_del(&f->list); 1822 list_del(&f->list);
1762 kfree(f); 1823 kfree(f);
@@ -1769,6 +1830,14 @@ static void i40evf_disable_vf(struct i40evf_adapter *adapter)
1769 1830
1770 spin_unlock_bh(&adapter->mac_vlan_list_lock); 1831 spin_unlock_bh(&adapter->mac_vlan_list_lock);
1771 1832
1833 spin_lock_bh(&adapter->cloud_filter_list_lock);
1834 list_for_each_entry_safe(cf, cftmp, &adapter->cloud_filter_list, list) {
1835 list_del(&cf->list);
1836 kfree(cf);
1837 adapter->num_cloud_filters--;
1838 }
1839 spin_unlock_bh(&adapter->cloud_filter_list_lock);
1840
1772 i40evf_free_misc_irq(adapter); 1841 i40evf_free_misc_irq(adapter);
1773 i40evf_reset_interrupt_capability(adapter); 1842 i40evf_reset_interrupt_capability(adapter);
1774 i40evf_free_queues(adapter); 1843 i40evf_free_queues(adapter);
@@ -1798,9 +1867,11 @@ static void i40evf_reset_task(struct work_struct *work)
1798 struct i40evf_adapter *adapter = container_of(work, 1867 struct i40evf_adapter *adapter = container_of(work,
1799 struct i40evf_adapter, 1868 struct i40evf_adapter,
1800 reset_task); 1869 reset_task);
1870 struct virtchnl_vf_resource *vfres = adapter->vf_res;
1801 struct net_device *netdev = adapter->netdev; 1871 struct net_device *netdev = adapter->netdev;
1802 struct i40e_hw *hw = &adapter->hw; 1872 struct i40e_hw *hw = &adapter->hw;
1803 struct i40evf_vlan_filter *vlf; 1873 struct i40evf_vlan_filter *vlf;
1874 struct i40evf_cloud_filter *cf;
1804 struct i40evf_mac_filter *f; 1875 struct i40evf_mac_filter *f;
1805 u32 reg_val; 1876 u32 reg_val;
1806 int i = 0, err; 1877 int i = 0, err;
@@ -1893,6 +1964,7 @@ continue_reset:
1893 i40evf_free_all_rx_resources(adapter); 1964 i40evf_free_all_rx_resources(adapter);
1894 i40evf_free_all_tx_resources(adapter); 1965 i40evf_free_all_tx_resources(adapter);
1895 1966
1967 adapter->flags |= I40EVF_FLAG_QUEUES_DISABLED;
1896 /* kill and reinit the admin queue */ 1968 /* kill and reinit the admin queue */
1897 i40evf_shutdown_adminq(hw); 1969 i40evf_shutdown_adminq(hw);
1898 adapter->current_op = VIRTCHNL_OP_UNKNOWN; 1970 adapter->current_op = VIRTCHNL_OP_UNKNOWN;
@@ -1924,8 +1996,19 @@ continue_reset:
1924 1996
1925 spin_unlock_bh(&adapter->mac_vlan_list_lock); 1997 spin_unlock_bh(&adapter->mac_vlan_list_lock);
1926 1998
1999 /* check if TCs are running and re-add all cloud filters */
2000 spin_lock_bh(&adapter->cloud_filter_list_lock);
2001 if ((vfres->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_ADQ) &&
2002 adapter->num_tc) {
2003 list_for_each_entry(cf, &adapter->cloud_filter_list, list) {
2004 cf->add = true;
2005 }
2006 }
2007 spin_unlock_bh(&adapter->cloud_filter_list_lock);
2008
1927 adapter->aq_required |= I40EVF_FLAG_AQ_ADD_MAC_FILTER; 2009 adapter->aq_required |= I40EVF_FLAG_AQ_ADD_MAC_FILTER;
1928 adapter->aq_required |= I40EVF_FLAG_AQ_ADD_VLAN_FILTER; 2010 adapter->aq_required |= I40EVF_FLAG_AQ_ADD_VLAN_FILTER;
2011 adapter->aq_required |= I40EVF_FLAG_AQ_ADD_CLOUD_FILTER;
1929 i40evf_misc_irq_enable(adapter); 2012 i40evf_misc_irq_enable(adapter);
1930 2013
1931 mod_timer(&adapter->watchdog_timer, jiffies + 2); 2014 mod_timer(&adapter->watchdog_timer, jiffies + 2);
@@ -2191,6 +2274,712 @@ void i40evf_free_all_rx_resources(struct i40evf_adapter *adapter)
2191} 2274}
2192 2275
2193/** 2276/**
2277 * i40evf_validate_tx_bandwidth - validate the max Tx bandwidth
2278 * @adapter: board private structure
2279 * @max_tx_rate: max Tx bw for a tc
2280 **/
2281static int i40evf_validate_tx_bandwidth(struct i40evf_adapter *adapter,
2282 u64 max_tx_rate)
2283{
2284 int speed = 0, ret = 0;
2285
2286 switch (adapter->link_speed) {
2287 case I40E_LINK_SPEED_40GB:
2288 speed = 40000;
2289 break;
2290 case I40E_LINK_SPEED_25GB:
2291 speed = 25000;
2292 break;
2293 case I40E_LINK_SPEED_20GB:
2294 speed = 20000;
2295 break;
2296 case I40E_LINK_SPEED_10GB:
2297 speed = 10000;
2298 break;
2299 case I40E_LINK_SPEED_1GB:
2300 speed = 1000;
2301 break;
2302 case I40E_LINK_SPEED_100MB:
2303 speed = 100;
2304 break;
2305 default:
2306 break;
2307 }
2308
2309 if (max_tx_rate > speed) {
2310 dev_err(&adapter->pdev->dev,
2311 "Invalid tx rate specified\n");
2312 ret = -EINVAL;
2313 }
2314
2315 return ret;
2316}
2317
2318/**
2319 * i40evf_validate_channel_config - validate queue mapping info
2320 * @adapter: board private structure
2321 * @mqprio_qopt: queue parameters
2322 *
2323 * This function validates if the config provided by the user to
2324 * configure queue channels is valid or not. Returns 0 on a valid
2325 * config.
2326 **/
2327static int i40evf_validate_ch_config(struct i40evf_adapter *adapter,
2328 struct tc_mqprio_qopt_offload *mqprio_qopt)
2329{
2330 u64 total_max_rate = 0;
2331 int i, num_qps = 0;
2332 u64 tx_rate = 0;
2333 int ret = 0;
2334
2335 if (mqprio_qopt->qopt.num_tc > I40EVF_MAX_TRAFFIC_CLASS ||
2336 mqprio_qopt->qopt.num_tc < 1)
2337 return -EINVAL;
2338
2339 for (i = 0; i <= mqprio_qopt->qopt.num_tc - 1; i++) {
2340 if (!mqprio_qopt->qopt.count[i] ||
2341 mqprio_qopt->qopt.offset[i] != num_qps)
2342 return -EINVAL;
2343 if (mqprio_qopt->min_rate[i]) {
2344 dev_err(&adapter->pdev->dev,
2345 "Invalid min tx rate (greater than 0) specified\n");
2346 return -EINVAL;
2347 }
2348 /*convert to Mbps */
2349 tx_rate = div_u64(mqprio_qopt->max_rate[i],
2350 I40EVF_MBPS_DIVISOR);
2351 total_max_rate += tx_rate;
2352 num_qps += mqprio_qopt->qopt.count[i];
2353 }
2354 if (num_qps > MAX_QUEUES)
2355 return -EINVAL;
2356
2357 ret = i40evf_validate_tx_bandwidth(adapter, total_max_rate);
2358 return ret;
2359}
2360
2361/**
2362 * i40evf_del_all_cloud_filters - delete all cloud filters
2363 * on the traffic classes
2364 **/
2365static void i40evf_del_all_cloud_filters(struct i40evf_adapter *adapter)
2366{
2367 struct i40evf_cloud_filter *cf, *cftmp;
2368
2369 spin_lock_bh(&adapter->cloud_filter_list_lock);
2370 list_for_each_entry_safe(cf, cftmp, &adapter->cloud_filter_list,
2371 list) {
2372 list_del(&cf->list);
2373 kfree(cf);
2374 adapter->num_cloud_filters--;
2375 }
2376 spin_unlock_bh(&adapter->cloud_filter_list_lock);
2377}
2378
2379/**
2380 * __i40evf_setup_tc - configure multiple traffic classes
2381 * @netdev: network interface device structure
2382 * @type_date: tc offload data
2383 *
2384 * This function processes the config information provided by the
2385 * user to configure traffic classes/queue channels and packages the
2386 * information to request the PF to setup traffic classes.
2387 *
2388 * Returns 0 on success.
2389 **/
2390static int __i40evf_setup_tc(struct net_device *netdev, void *type_data)
2391{
2392 struct tc_mqprio_qopt_offload *mqprio_qopt = type_data;
2393 struct i40evf_adapter *adapter = netdev_priv(netdev);
2394 struct virtchnl_vf_resource *vfres = adapter->vf_res;
2395 u8 num_tc = 0, total_qps = 0;
2396 int ret = 0, netdev_tc = 0;
2397 u64 max_tx_rate;
2398 u16 mode;
2399 int i;
2400
2401 num_tc = mqprio_qopt->qopt.num_tc;
2402 mode = mqprio_qopt->mode;
2403
2404 /* delete queue_channel */
2405 if (!mqprio_qopt->qopt.hw) {
2406 if (adapter->ch_config.state == __I40EVF_TC_RUNNING) {
2407 /* reset the tc configuration */
2408 netdev_reset_tc(netdev);
2409 adapter->num_tc = 0;
2410 netif_tx_stop_all_queues(netdev);
2411 netif_tx_disable(netdev);
2412 i40evf_del_all_cloud_filters(adapter);
2413 adapter->aq_required = I40EVF_FLAG_AQ_DISABLE_CHANNELS;
2414 goto exit;
2415 } else {
2416 return -EINVAL;
2417 }
2418 }
2419
2420 /* add queue channel */
2421 if (mode == TC_MQPRIO_MODE_CHANNEL) {
2422 if (!(vfres->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_ADQ)) {
2423 dev_err(&adapter->pdev->dev, "ADq not supported\n");
2424 return -EOPNOTSUPP;
2425 }
2426 if (adapter->ch_config.state != __I40EVF_TC_INVALID) {
2427 dev_err(&adapter->pdev->dev, "TC configuration already exists\n");
2428 return -EINVAL;
2429 }
2430
2431 ret = i40evf_validate_ch_config(adapter, mqprio_qopt);
2432 if (ret)
2433 return ret;
2434 /* Return if same TC config is requested */
2435 if (adapter->num_tc == num_tc)
2436 return 0;
2437 adapter->num_tc = num_tc;
2438
2439 for (i = 0; i < I40EVF_MAX_TRAFFIC_CLASS; i++) {
2440 if (i < num_tc) {
2441 adapter->ch_config.ch_info[i].count =
2442 mqprio_qopt->qopt.count[i];
2443 adapter->ch_config.ch_info[i].offset =
2444 mqprio_qopt->qopt.offset[i];
2445 total_qps += mqprio_qopt->qopt.count[i];
2446 max_tx_rate = mqprio_qopt->max_rate[i];
2447 /* convert to Mbps */
2448 max_tx_rate = div_u64(max_tx_rate,
2449 I40EVF_MBPS_DIVISOR);
2450 adapter->ch_config.ch_info[i].max_tx_rate =
2451 max_tx_rate;
2452 } else {
2453 adapter->ch_config.ch_info[i].count = 1;
2454 adapter->ch_config.ch_info[i].offset = 0;
2455 }
2456 }
2457 adapter->ch_config.total_qps = total_qps;
2458 netif_tx_stop_all_queues(netdev);
2459 netif_tx_disable(netdev);
2460 adapter->aq_required |= I40EVF_FLAG_AQ_ENABLE_CHANNELS;
2461 netdev_reset_tc(netdev);
2462 /* Report the tc mapping up the stack */
2463 netdev_set_num_tc(adapter->netdev, num_tc);
2464 for (i = 0; i < I40EVF_MAX_TRAFFIC_CLASS; i++) {
2465 u16 qcount = mqprio_qopt->qopt.count[i];
2466 u16 qoffset = mqprio_qopt->qopt.offset[i];
2467
2468 if (i < num_tc)
2469 netdev_set_tc_queue(netdev, netdev_tc++, qcount,
2470 qoffset);
2471 }
2472 }
2473exit:
2474 return ret;
2475}
2476
2477/**
2478 * i40evf_parse_cls_flower - Parse tc flower filters provided by kernel
2479 * @adapter: board private structure
2480 * @cls_flower: pointer to struct tc_cls_flower_offload
2481 * @filter: pointer to cloud filter structure
2482 */
2483static int i40evf_parse_cls_flower(struct i40evf_adapter *adapter,
2484 struct tc_cls_flower_offload *f,
2485 struct i40evf_cloud_filter *filter)
2486{
2487 u16 n_proto_mask = 0;
2488 u16 n_proto_key = 0;
2489 u8 field_flags = 0;
2490 u16 addr_type = 0;
2491 u16 n_proto = 0;
2492 int i = 0;
2493 struct virtchnl_filter *vf = &filter->f;
2494
2495 if (f->dissector->used_keys &
2496 ~(BIT(FLOW_DISSECTOR_KEY_CONTROL) |
2497 BIT(FLOW_DISSECTOR_KEY_BASIC) |
2498 BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS) |
2499 BIT(FLOW_DISSECTOR_KEY_VLAN) |
2500 BIT(FLOW_DISSECTOR_KEY_IPV4_ADDRS) |
2501 BIT(FLOW_DISSECTOR_KEY_IPV6_ADDRS) |
2502 BIT(FLOW_DISSECTOR_KEY_PORTS) |
2503 BIT(FLOW_DISSECTOR_KEY_ENC_KEYID))) {
2504 dev_err(&adapter->pdev->dev, "Unsupported key used: 0x%x\n",
2505 f->dissector->used_keys);
2506 return -EOPNOTSUPP;
2507 }
2508
2509 if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_ENC_KEYID)) {
2510 struct flow_dissector_key_keyid *mask =
2511 skb_flow_dissector_target(f->dissector,
2512 FLOW_DISSECTOR_KEY_ENC_KEYID,
2513 f->mask);
2514
2515 if (mask->keyid != 0)
2516 field_flags |= I40EVF_CLOUD_FIELD_TEN_ID;
2517 }
2518
2519 if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_BASIC)) {
2520 struct flow_dissector_key_basic *key =
2521 skb_flow_dissector_target(f->dissector,
2522 FLOW_DISSECTOR_KEY_BASIC,
2523 f->key);
2524
2525 struct flow_dissector_key_basic *mask =
2526 skb_flow_dissector_target(f->dissector,
2527 FLOW_DISSECTOR_KEY_BASIC,
2528 f->mask);
2529 n_proto_key = ntohs(key->n_proto);
2530 n_proto_mask = ntohs(mask->n_proto);
2531
2532 if (n_proto_key == ETH_P_ALL) {
2533 n_proto_key = 0;
2534 n_proto_mask = 0;
2535 }
2536 n_proto = n_proto_key & n_proto_mask;
2537 if (n_proto != ETH_P_IP && n_proto != ETH_P_IPV6)
2538 return -EINVAL;
2539 if (n_proto == ETH_P_IPV6) {
2540 /* specify flow type as TCP IPv6 */
2541 vf->flow_type = VIRTCHNL_TCP_V6_FLOW;
2542 }
2543
2544 if (key->ip_proto != IPPROTO_TCP) {
2545 dev_info(&adapter->pdev->dev, "Only TCP transport is supported\n");
2546 return -EINVAL;
2547 }
2548 }
2549
2550 if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
2551 struct flow_dissector_key_eth_addrs *key =
2552 skb_flow_dissector_target(f->dissector,
2553 FLOW_DISSECTOR_KEY_ETH_ADDRS,
2554 f->key);
2555
2556 struct flow_dissector_key_eth_addrs *mask =
2557 skb_flow_dissector_target(f->dissector,
2558 FLOW_DISSECTOR_KEY_ETH_ADDRS,
2559 f->mask);
2560 /* use is_broadcast and is_zero to check for all 0xf or 0 */
2561 if (!is_zero_ether_addr(mask->dst)) {
2562 if (is_broadcast_ether_addr(mask->dst)) {
2563 field_flags |= I40EVF_CLOUD_FIELD_OMAC;
2564 } else {
2565 dev_err(&adapter->pdev->dev, "Bad ether dest mask %pM\n",
2566 mask->dst);
2567 return I40E_ERR_CONFIG;
2568 }
2569 }
2570
2571 if (!is_zero_ether_addr(mask->src)) {
2572 if (is_broadcast_ether_addr(mask->src)) {
2573 field_flags |= I40EVF_CLOUD_FIELD_IMAC;
2574 } else {
2575 dev_err(&adapter->pdev->dev, "Bad ether src mask %pM\n",
2576 mask->src);
2577 return I40E_ERR_CONFIG;
2578 }
2579 }
2580
2581 if (!is_zero_ether_addr(key->dst))
2582 if (is_valid_ether_addr(key->dst) ||
2583 is_multicast_ether_addr(key->dst)) {
2584 /* set the mask if a valid dst_mac address */
2585 for (i = 0; i < ETH_ALEN; i++)
2586 vf->mask.tcp_spec.dst_mac[i] |= 0xff;
2587 ether_addr_copy(vf->data.tcp_spec.dst_mac,
2588 key->dst);
2589 }
2590
2591 if (!is_zero_ether_addr(key->src))
2592 if (is_valid_ether_addr(key->src) ||
2593 is_multicast_ether_addr(key->src)) {
2594 /* set the mask if a valid dst_mac address */
2595 for (i = 0; i < ETH_ALEN; i++)
2596 vf->mask.tcp_spec.src_mac[i] |= 0xff;
2597 ether_addr_copy(vf->data.tcp_spec.src_mac,
2598 key->src);
2599 }
2600 }
2601
2602 if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_VLAN)) {
2603 struct flow_dissector_key_vlan *key =
2604 skb_flow_dissector_target(f->dissector,
2605 FLOW_DISSECTOR_KEY_VLAN,
2606 f->key);
2607 struct flow_dissector_key_vlan *mask =
2608 skb_flow_dissector_target(f->dissector,
2609 FLOW_DISSECTOR_KEY_VLAN,
2610 f->mask);
2611
2612 if (mask->vlan_id) {
2613 if (mask->vlan_id == VLAN_VID_MASK) {
2614 field_flags |= I40EVF_CLOUD_FIELD_IVLAN;
2615 } else {
2616 dev_err(&adapter->pdev->dev, "Bad vlan mask %u\n",
2617 mask->vlan_id);
2618 return I40E_ERR_CONFIG;
2619 }
2620 }
2621 vf->mask.tcp_spec.vlan_id |= cpu_to_be16(0xffff);
2622 vf->data.tcp_spec.vlan_id = cpu_to_be16(key->vlan_id);
2623 }
2624
2625 if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_CONTROL)) {
2626 struct flow_dissector_key_control *key =
2627 skb_flow_dissector_target(f->dissector,
2628 FLOW_DISSECTOR_KEY_CONTROL,
2629 f->key);
2630
2631 addr_type = key->addr_type;
2632 }
2633
2634 if (addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) {
2635 struct flow_dissector_key_ipv4_addrs *key =
2636 skb_flow_dissector_target(f->dissector,
2637 FLOW_DISSECTOR_KEY_IPV4_ADDRS,
2638 f->key);
2639 struct flow_dissector_key_ipv4_addrs *mask =
2640 skb_flow_dissector_target(f->dissector,
2641 FLOW_DISSECTOR_KEY_IPV4_ADDRS,
2642 f->mask);
2643
2644 if (mask->dst) {
2645 if (mask->dst == cpu_to_be32(0xffffffff)) {
2646 field_flags |= I40EVF_CLOUD_FIELD_IIP;
2647 } else {
2648 dev_err(&adapter->pdev->dev, "Bad ip dst mask 0x%08x\n",
2649 be32_to_cpu(mask->dst));
2650 return I40E_ERR_CONFIG;
2651 }
2652 }
2653
2654 if (mask->src) {
2655 if (mask->src == cpu_to_be32(0xffffffff)) {
2656 field_flags |= I40EVF_CLOUD_FIELD_IIP;
2657 } else {
2658 dev_err(&adapter->pdev->dev, "Bad ip src mask 0x%08x\n",
2659 be32_to_cpu(mask->dst));
2660 return I40E_ERR_CONFIG;
2661 }
2662 }
2663
2664 if (field_flags & I40EVF_CLOUD_FIELD_TEN_ID) {
2665 dev_info(&adapter->pdev->dev, "Tenant id not allowed for ip filter\n");
2666 return I40E_ERR_CONFIG;
2667 }
2668 if (key->dst) {
2669 vf->mask.tcp_spec.dst_ip[0] |= cpu_to_be32(0xffffffff);
2670 vf->data.tcp_spec.dst_ip[0] = key->dst;
2671 }
2672 if (key->src) {
2673 vf->mask.tcp_spec.src_ip[0] |= cpu_to_be32(0xffffffff);
2674 vf->data.tcp_spec.src_ip[0] = key->src;
2675 }
2676 }
2677
2678 if (addr_type == FLOW_DISSECTOR_KEY_IPV6_ADDRS) {
2679 struct flow_dissector_key_ipv6_addrs *key =
2680 skb_flow_dissector_target(f->dissector,
2681 FLOW_DISSECTOR_KEY_IPV6_ADDRS,
2682 f->key);
2683 struct flow_dissector_key_ipv6_addrs *mask =
2684 skb_flow_dissector_target(f->dissector,
2685 FLOW_DISSECTOR_KEY_IPV6_ADDRS,
2686 f->mask);
2687
2688 /* validate mask, make sure it is not IPV6_ADDR_ANY */
2689 if (ipv6_addr_any(&mask->dst)) {
2690 dev_err(&adapter->pdev->dev, "Bad ipv6 dst mask 0x%02x\n",
2691 IPV6_ADDR_ANY);
2692 return I40E_ERR_CONFIG;
2693 }
2694
2695 /* src and dest IPv6 address should not be LOOPBACK
2696 * (0:0:0:0:0:0:0:1) which can be represented as ::1
2697 */
2698 if (ipv6_addr_loopback(&key->dst) ||
2699 ipv6_addr_loopback(&key->src)) {
2700 dev_err(&adapter->pdev->dev,
2701 "ipv6 addr should not be loopback\n");
2702 return I40E_ERR_CONFIG;
2703 }
2704 if (!ipv6_addr_any(&mask->dst) || !ipv6_addr_any(&mask->src))
2705 field_flags |= I40EVF_CLOUD_FIELD_IIP;
2706
2707 for (i = 0; i < 4; i++)
2708 vf->mask.tcp_spec.dst_ip[i] |= cpu_to_be32(0xffffffff);
2709 memcpy(&vf->data.tcp_spec.dst_ip, &key->dst.s6_addr32,
2710 sizeof(vf->data.tcp_spec.dst_ip));
2711 for (i = 0; i < 4; i++)
2712 vf->mask.tcp_spec.src_ip[i] |= cpu_to_be32(0xffffffff);
2713 memcpy(&vf->data.tcp_spec.src_ip, &key->src.s6_addr32,
2714 sizeof(vf->data.tcp_spec.src_ip));
2715 }
2716 if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_PORTS)) {
2717 struct flow_dissector_key_ports *key =
2718 skb_flow_dissector_target(f->dissector,
2719 FLOW_DISSECTOR_KEY_PORTS,
2720 f->key);
2721 struct flow_dissector_key_ports *mask =
2722 skb_flow_dissector_target(f->dissector,
2723 FLOW_DISSECTOR_KEY_PORTS,
2724 f->mask);
2725
2726 if (mask->src) {
2727 if (mask->src == cpu_to_be16(0xffff)) {
2728 field_flags |= I40EVF_CLOUD_FIELD_IIP;
2729 } else {
2730 dev_err(&adapter->pdev->dev, "Bad src port mask %u\n",
2731 be16_to_cpu(mask->src));
2732 return I40E_ERR_CONFIG;
2733 }
2734 }
2735
2736 if (mask->dst) {
2737 if (mask->dst == cpu_to_be16(0xffff)) {
2738 field_flags |= I40EVF_CLOUD_FIELD_IIP;
2739 } else {
2740 dev_err(&adapter->pdev->dev, "Bad dst port mask %u\n",
2741 be16_to_cpu(mask->dst));
2742 return I40E_ERR_CONFIG;
2743 }
2744 }
2745 if (key->dst) {
2746 vf->mask.tcp_spec.dst_port |= cpu_to_be16(0xffff);
2747 vf->data.tcp_spec.dst_port = key->dst;
2748 }
2749
2750 if (key->src) {
2751 vf->mask.tcp_spec.src_port |= cpu_to_be16(0xffff);
2752 vf->data.tcp_spec.src_port = key->src;
2753 }
2754 }
2755 vf->field_flags = field_flags;
2756
2757 return 0;
2758}
2759
2760/**
2761 * i40evf_handle_tclass - Forward to a traffic class on the device
2762 * @adapter: board private structure
2763 * @tc: traffic class index on the device
2764 * @filter: pointer to cloud filter structure
2765 */
2766static int i40evf_handle_tclass(struct i40evf_adapter *adapter, u32 tc,
2767 struct i40evf_cloud_filter *filter)
2768{
2769 if (tc == 0)
2770 return 0;
2771 if (tc < adapter->num_tc) {
2772 if (!filter->f.data.tcp_spec.dst_port) {
2773 dev_err(&adapter->pdev->dev,
2774 "Specify destination port to redirect to traffic class other than TC0\n");
2775 return -EINVAL;
2776 }
2777 }
2778 /* redirect to a traffic class on the same device */
2779 filter->f.action = VIRTCHNL_ACTION_TC_REDIRECT;
2780 filter->f.action_meta = tc;
2781 return 0;
2782}
2783
2784/**
2785 * i40evf_configure_clsflower - Add tc flower filters
2786 * @adapter: board private structure
2787 * @cls_flower: Pointer to struct tc_cls_flower_offload
2788 */
2789static int i40evf_configure_clsflower(struct i40evf_adapter *adapter,
2790 struct tc_cls_flower_offload *cls_flower)
2791{
2792 int tc = tc_classid_to_hwtc(adapter->netdev, cls_flower->classid);
2793 struct i40evf_cloud_filter *filter = NULL;
2794 int err = -EINVAL, count = 50;
2795
2796 if (tc < 0) {
2797 dev_err(&adapter->pdev->dev, "Invalid traffic class\n");
2798 return -EINVAL;
2799 }
2800
2801 filter = kzalloc(sizeof(*filter), GFP_KERNEL);
2802 if (!filter)
2803 return -ENOMEM;
2804
2805 while (test_and_set_bit(__I40EVF_IN_CRITICAL_TASK,
2806 &adapter->crit_section)) {
2807 if (--count == 0)
2808 goto err;
2809 udelay(1);
2810 }
2811
2812 filter->cookie = cls_flower->cookie;
2813
2814 /* set the mask to all zeroes to begin with */
2815 memset(&filter->f.mask.tcp_spec, 0, sizeof(struct virtchnl_l4_spec));
2816 /* start out with flow type and eth type IPv4 to begin with */
2817 filter->f.flow_type = VIRTCHNL_TCP_V4_FLOW;
2818 err = i40evf_parse_cls_flower(adapter, cls_flower, filter);
2819 if (err < 0)
2820 goto err;
2821
2822 err = i40evf_handle_tclass(adapter, tc, filter);
2823 if (err < 0)
2824 goto err;
2825
2826 /* add filter to the list */
2827 spin_lock_bh(&adapter->cloud_filter_list_lock);
2828 list_add_tail(&filter->list, &adapter->cloud_filter_list);
2829 adapter->num_cloud_filters++;
2830 filter->add = true;
2831 adapter->aq_required |= I40EVF_FLAG_AQ_ADD_CLOUD_FILTER;
2832 spin_unlock_bh(&adapter->cloud_filter_list_lock);
2833err:
2834 if (err)
2835 kfree(filter);
2836
2837 clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section);
2838 return err;
2839}
2840
2841/* i40evf_find_cf - Find the cloud filter in the list
2842 * @adapter: Board private structure
2843 * @cookie: filter specific cookie
2844 *
2845 * Returns ptr to the filter object or NULL. Must be called while holding the
2846 * cloud_filter_list_lock.
2847 */
2848static struct i40evf_cloud_filter *i40evf_find_cf(struct i40evf_adapter *adapter,
2849 unsigned long *cookie)
2850{
2851 struct i40evf_cloud_filter *filter = NULL;
2852
2853 if (!cookie)
2854 return NULL;
2855
2856 list_for_each_entry(filter, &adapter->cloud_filter_list, list) {
2857 if (!memcmp(cookie, &filter->cookie, sizeof(filter->cookie)))
2858 return filter;
2859 }
2860 return NULL;
2861}
2862
2863/**
2864 * i40evf_delete_clsflower - Remove tc flower filters
2865 * @adapter: board private structure
2866 * @cls_flower: Pointer to struct tc_cls_flower_offload
2867 */
2868static int i40evf_delete_clsflower(struct i40evf_adapter *adapter,
2869 struct tc_cls_flower_offload *cls_flower)
2870{
2871 struct i40evf_cloud_filter *filter = NULL;
2872 int err = 0;
2873
2874 spin_lock_bh(&adapter->cloud_filter_list_lock);
2875 filter = i40evf_find_cf(adapter, &cls_flower->cookie);
2876 if (filter) {
2877 filter->del = true;
2878 adapter->aq_required |= I40EVF_FLAG_AQ_DEL_CLOUD_FILTER;
2879 } else {
2880 err = -EINVAL;
2881 }
2882 spin_unlock_bh(&adapter->cloud_filter_list_lock);
2883
2884 return err;
2885}
2886
2887/**
2888 * i40evf_setup_tc_cls_flower - flower classifier offloads
2889 * @netdev: net device to configure
2890 * @type_data: offload data
2891 */
2892static int i40evf_setup_tc_cls_flower(struct i40evf_adapter *adapter,
2893 struct tc_cls_flower_offload *cls_flower)
2894{
2895 if (cls_flower->common.chain_index)
2896 return -EOPNOTSUPP;
2897
2898 switch (cls_flower->command) {
2899 case TC_CLSFLOWER_REPLACE:
2900 return i40evf_configure_clsflower(adapter, cls_flower);
2901 case TC_CLSFLOWER_DESTROY:
2902 return i40evf_delete_clsflower(adapter, cls_flower);
2903 case TC_CLSFLOWER_STATS:
2904 return -EOPNOTSUPP;
2905 default:
2906 return -EINVAL;
2907 }
2908}
2909
2910/**
2911 * i40evf_setup_tc_block_cb - block callback for tc
2912 * @type: type of offload
2913 * @type_data: offload data
2914 * @cb_priv:
2915 *
2916 * This function is the block callback for traffic classes
2917 **/
2918static int i40evf_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
2919 void *cb_priv)
2920{
2921 switch (type) {
2922 case TC_SETUP_CLSFLOWER:
2923 return i40evf_setup_tc_cls_flower(cb_priv, type_data);
2924 default:
2925 return -EOPNOTSUPP;
2926 }
2927}
2928
2929/**
2930 * i40evf_setup_tc_block - register callbacks for tc
2931 * @netdev: network interface device structure
2932 * @f: tc offload data
2933 *
2934 * This function registers block callbacks for tc
2935 * offloads
2936 **/
2937static int i40evf_setup_tc_block(struct net_device *dev,
2938 struct tc_block_offload *f)
2939{
2940 struct i40evf_adapter *adapter = netdev_priv(dev);
2941
2942 if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
2943 return -EOPNOTSUPP;
2944
2945 switch (f->command) {
2946 case TC_BLOCK_BIND:
2947 return tcf_block_cb_register(f->block, i40evf_setup_tc_block_cb,
2948 adapter, adapter);
2949 case TC_BLOCK_UNBIND:
2950 tcf_block_cb_unregister(f->block, i40evf_setup_tc_block_cb,
2951 adapter);
2952 return 0;
2953 default:
2954 return -EOPNOTSUPP;
2955 }
2956}
2957
2958/**
2959 * i40evf_setup_tc - configure multiple traffic classes
2960 * @netdev: network interface device structure
2961 * @type: type of offload
2962 * @type_date: tc offload data
2963 *
2964 * This function is the callback to ndo_setup_tc in the
2965 * netdev_ops.
2966 *
2967 * Returns 0 on success
2968 **/
2969static int i40evf_setup_tc(struct net_device *netdev, enum tc_setup_type type,
2970 void *type_data)
2971{
2972 switch (type) {
2973 case TC_SETUP_QDISC_MQPRIO:
2974 return __i40evf_setup_tc(netdev, type_data);
2975 case TC_SETUP_BLOCK:
2976 return i40evf_setup_tc_block(netdev, type_data);
2977 default:
2978 return -EOPNOTSUPP;
2979 }
2980}
2981
2982/**
2194 * i40evf_open - Called when a network interface is made active 2983 * i40evf_open - Called when a network interface is made active
2195 * @netdev: network interface device structure 2984 * @netdev: network interface device structure
2196 * 2985 *
@@ -2236,7 +3025,12 @@ static int i40evf_open(struct net_device *netdev)
2236 if (err) 3025 if (err)
2237 goto err_req_irq; 3026 goto err_req_irq;
2238 3027
3028 spin_lock_bh(&adapter->mac_vlan_list_lock);
3029
2239 i40evf_add_filter(adapter, adapter->hw.mac.addr); 3030 i40evf_add_filter(adapter, adapter->hw.mac.addr);
3031
3032 spin_unlock_bh(&adapter->mac_vlan_list_lock);
3033
2240 i40evf_configure(adapter); 3034 i40evf_configure(adapter);
2241 3035
2242 i40evf_up_complete(adapter); 3036 i40evf_up_complete(adapter);
@@ -2457,6 +3251,7 @@ static const struct net_device_ops i40evf_netdev_ops = {
2457#ifdef CONFIG_NET_POLL_CONTROLLER 3251#ifdef CONFIG_NET_POLL_CONTROLLER
2458 .ndo_poll_controller = i40evf_netpoll, 3252 .ndo_poll_controller = i40evf_netpoll,
2459#endif 3253#endif
3254 .ndo_setup_tc = i40evf_setup_tc,
2460}; 3255};
2461 3256
2462/** 3257/**
@@ -2571,6 +3366,9 @@ int i40evf_process_config(struct i40evf_adapter *adapter)
2571 if (vfres->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN) 3366 if (vfres->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN)
2572 hw_features |= (NETIF_F_HW_VLAN_CTAG_TX | 3367 hw_features |= (NETIF_F_HW_VLAN_CTAG_TX |
2573 NETIF_F_HW_VLAN_CTAG_RX); 3368 NETIF_F_HW_VLAN_CTAG_RX);
3369 /* Enable cloud filter if ADQ is supported */
3370 if (vfres->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_ADQ)
3371 hw_features |= NETIF_F_HW_TC;
2574 3372
2575 netdev->hw_features |= hw_features; 3373 netdev->hw_features |= hw_features;
2576 3374
@@ -2938,9 +3736,11 @@ static int i40evf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
2938 mutex_init(&hw->aq.arq_mutex); 3736 mutex_init(&hw->aq.arq_mutex);
2939 3737
2940 spin_lock_init(&adapter->mac_vlan_list_lock); 3738 spin_lock_init(&adapter->mac_vlan_list_lock);
3739 spin_lock_init(&adapter->cloud_filter_list_lock);
2941 3740
2942 INIT_LIST_HEAD(&adapter->mac_filter_list); 3741 INIT_LIST_HEAD(&adapter->mac_filter_list);
2943 INIT_LIST_HEAD(&adapter->vlan_filter_list); 3742 INIT_LIST_HEAD(&adapter->vlan_filter_list);
3743 INIT_LIST_HEAD(&adapter->cloud_filter_list);
2944 3744
2945 INIT_WORK(&adapter->reset_task, i40evf_reset_task); 3745 INIT_WORK(&adapter->reset_task, i40evf_reset_task);
2946 INIT_WORK(&adapter->adminq_task, i40evf_adminq_task); 3746 INIT_WORK(&adapter->adminq_task, i40evf_adminq_task);
@@ -3065,7 +3865,9 @@ static void i40evf_remove(struct pci_dev *pdev)
3065{ 3865{
3066 struct net_device *netdev = pci_get_drvdata(pdev); 3866 struct net_device *netdev = pci_get_drvdata(pdev);
3067 struct i40evf_adapter *adapter = netdev_priv(netdev); 3867 struct i40evf_adapter *adapter = netdev_priv(netdev);
3868 struct i40evf_vlan_filter *vlf, *vlftmp;
3068 struct i40evf_mac_filter *f, *ftmp; 3869 struct i40evf_mac_filter *f, *ftmp;
3870 struct i40evf_cloud_filter *cf, *cftmp;
3069 struct i40e_hw *hw = &adapter->hw; 3871 struct i40e_hw *hw = &adapter->hw;
3070 int err; 3872 int err;
3071 /* Indicate we are in remove and not to run reset_task */ 3873 /* Indicate we are in remove and not to run reset_task */
@@ -3087,6 +3889,7 @@ static void i40evf_remove(struct pci_dev *pdev)
3087 /* Shut down all the garbage mashers on the detention level */ 3889 /* Shut down all the garbage mashers on the detention level */
3088 adapter->state = __I40EVF_REMOVE; 3890 adapter->state = __I40EVF_REMOVE;
3089 adapter->aq_required = 0; 3891 adapter->aq_required = 0;
3892 adapter->flags &= ~I40EVF_FLAG_REINIT_ITR_NEEDED;
3090 i40evf_request_reset(adapter); 3893 i40evf_request_reset(adapter);
3091 msleep(50); 3894 msleep(50);
3092 /* If the FW isn't responding, kick it once, but only once. */ 3895 /* If the FW isn't responding, kick it once, but only once. */
@@ -3127,13 +3930,21 @@ static void i40evf_remove(struct pci_dev *pdev)
3127 list_del(&f->list); 3930 list_del(&f->list);
3128 kfree(f); 3931 kfree(f);
3129 } 3932 }
3130 list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) { 3933 list_for_each_entry_safe(vlf, vlftmp, &adapter->vlan_filter_list,
3131 list_del(&f->list); 3934 list) {
3132 kfree(f); 3935 list_del(&vlf->list);
3936 kfree(vlf);
3133 } 3937 }
3134 3938
3135 spin_unlock_bh(&adapter->mac_vlan_list_lock); 3939 spin_unlock_bh(&adapter->mac_vlan_list_lock);
3136 3940
3941 spin_lock_bh(&adapter->cloud_filter_list_lock);
3942 list_for_each_entry_safe(cf, cftmp, &adapter->cloud_filter_list, list) {
3943 list_del(&cf->list);
3944 kfree(cf);
3945 }
3946 spin_unlock_bh(&adapter->cloud_filter_list_lock);
3947
3137 free_netdev(netdev); 3948 free_netdev(netdev);
3138 3949
3139 pci_disable_pcie_error_reporting(pdev); 3950 pci_disable_pcie_error_reporting(pdev);
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c b/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c
index 50ce0d6c09ef..3c76c817ca1a 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c
@@ -161,7 +161,8 @@ int i40evf_send_vf_config_msg(struct i40evf_adapter *adapter)
161 VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2 | 161 VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2 |
162 VIRTCHNL_VF_OFFLOAD_ENCAP | 162 VIRTCHNL_VF_OFFLOAD_ENCAP |
163 VIRTCHNL_VF_OFFLOAD_ENCAP_CSUM | 163 VIRTCHNL_VF_OFFLOAD_ENCAP_CSUM |
164 VIRTCHNL_VF_OFFLOAD_REQ_QUEUES; 164 VIRTCHNL_VF_OFFLOAD_REQ_QUEUES |
165 VIRTCHNL_VF_OFFLOAD_ADQ;
165 166
166 adapter->current_op = VIRTCHNL_OP_GET_VF_RESOURCES; 167 adapter->current_op = VIRTCHNL_OP_GET_VF_RESOURCES;
167 adapter->aq_required &= ~I40EVF_FLAG_AQ_GET_CONFIG; 168 adapter->aq_required &= ~I40EVF_FLAG_AQ_GET_CONFIG;
@@ -344,6 +345,7 @@ void i40evf_disable_queues(struct i40evf_adapter *adapter)
344void i40evf_map_queues(struct i40evf_adapter *adapter) 345void i40evf_map_queues(struct i40evf_adapter *adapter)
345{ 346{
346 struct virtchnl_irq_map_info *vimi; 347 struct virtchnl_irq_map_info *vimi;
348 struct virtchnl_vector_map *vecmap;
347 int v_idx, q_vectors, len; 349 int v_idx, q_vectors, len;
348 struct i40e_q_vector *q_vector; 350 struct i40e_q_vector *q_vector;
349 351
@@ -367,17 +369,22 @@ void i40evf_map_queues(struct i40evf_adapter *adapter)
367 vimi->num_vectors = adapter->num_msix_vectors; 369 vimi->num_vectors = adapter->num_msix_vectors;
368 /* Queue vectors first */ 370 /* Queue vectors first */
369 for (v_idx = 0; v_idx < q_vectors; v_idx++) { 371 for (v_idx = 0; v_idx < q_vectors; v_idx++) {
370 q_vector = adapter->q_vectors + v_idx; 372 q_vector = &adapter->q_vectors[v_idx];
371 vimi->vecmap[v_idx].vsi_id = adapter->vsi_res->vsi_id; 373 vecmap = &vimi->vecmap[v_idx];
372 vimi->vecmap[v_idx].vector_id = v_idx + NONQ_VECS; 374
373 vimi->vecmap[v_idx].txq_map = q_vector->ring_mask; 375 vecmap->vsi_id = adapter->vsi_res->vsi_id;
374 vimi->vecmap[v_idx].rxq_map = q_vector->ring_mask; 376 vecmap->vector_id = v_idx + NONQ_VECS;
377 vecmap->txq_map = q_vector->ring_mask;
378 vecmap->rxq_map = q_vector->ring_mask;
379 vecmap->rxitr_idx = I40E_RX_ITR;
380 vecmap->txitr_idx = I40E_TX_ITR;
375 } 381 }
376 /* Misc vector last - this is only for AdminQ messages */ 382 /* Misc vector last - this is only for AdminQ messages */
377 vimi->vecmap[v_idx].vsi_id = adapter->vsi_res->vsi_id; 383 vecmap = &vimi->vecmap[v_idx];
378 vimi->vecmap[v_idx].vector_id = 0; 384 vecmap->vsi_id = adapter->vsi_res->vsi_id;
379 vimi->vecmap[v_idx].txq_map = 0; 385 vecmap->vector_id = 0;
380 vimi->vecmap[v_idx].rxq_map = 0; 386 vecmap->txq_map = 0;
387 vecmap->rxq_map = 0;
381 388
382 adapter->aq_required &= ~I40EVF_FLAG_AQ_MAP_VECTORS; 389 adapter->aq_required &= ~I40EVF_FLAG_AQ_MAP_VECTORS;
383 i40evf_send_pf_msg(adapter, VIRTCHNL_OP_CONFIG_IRQ_MAP, 390 i40evf_send_pf_msg(adapter, VIRTCHNL_OP_CONFIG_IRQ_MAP,
@@ -459,7 +466,7 @@ void i40evf_add_ether_addrs(struct i40evf_adapter *adapter)
459 more = true; 466 more = true;
460 } 467 }
461 468
462 veal = kzalloc(len, GFP_KERNEL); 469 veal = kzalloc(len, GFP_ATOMIC);
463 if (!veal) { 470 if (!veal) {
464 spin_unlock_bh(&adapter->mac_vlan_list_lock); 471 spin_unlock_bh(&adapter->mac_vlan_list_lock);
465 return; 472 return;
@@ -532,7 +539,7 @@ void i40evf_del_ether_addrs(struct i40evf_adapter *adapter)
532 (count * sizeof(struct virtchnl_ether_addr)); 539 (count * sizeof(struct virtchnl_ether_addr));
533 more = true; 540 more = true;
534 } 541 }
535 veal = kzalloc(len, GFP_KERNEL); 542 veal = kzalloc(len, GFP_ATOMIC);
536 if (!veal) { 543 if (!veal) {
537 spin_unlock_bh(&adapter->mac_vlan_list_lock); 544 spin_unlock_bh(&adapter->mac_vlan_list_lock);
538 return; 545 return;
@@ -606,7 +613,7 @@ void i40evf_add_vlans(struct i40evf_adapter *adapter)
606 (count * sizeof(u16)); 613 (count * sizeof(u16));
607 more = true; 614 more = true;
608 } 615 }
609 vvfl = kzalloc(len, GFP_KERNEL); 616 vvfl = kzalloc(len, GFP_ATOMIC);
610 if (!vvfl) { 617 if (!vvfl) {
611 spin_unlock_bh(&adapter->mac_vlan_list_lock); 618 spin_unlock_bh(&adapter->mac_vlan_list_lock);
612 return; 619 return;
@@ -678,7 +685,7 @@ void i40evf_del_vlans(struct i40evf_adapter *adapter)
678 (count * sizeof(u16)); 685 (count * sizeof(u16));
679 more = true; 686 more = true;
680 } 687 }
681 vvfl = kzalloc(len, GFP_KERNEL); 688 vvfl = kzalloc(len, GFP_ATOMIC);
682 if (!vvfl) { 689 if (!vvfl) {
683 spin_unlock_bh(&adapter->mac_vlan_list_lock); 690 spin_unlock_bh(&adapter->mac_vlan_list_lock);
684 return; 691 return;
@@ -967,6 +974,205 @@ static void i40evf_print_link_message(struct i40evf_adapter *adapter)
967} 974}
968 975
969/** 976/**
977 * i40evf_enable_channel
978 * @adapter: adapter structure
979 *
980 * Request that the PF enable channels as specified by
981 * the user via tc tool.
982 **/
983void i40evf_enable_channels(struct i40evf_adapter *adapter)
984{
985 struct virtchnl_tc_info *vti = NULL;
986 u16 len;
987 int i;
988
989 if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
990 /* bail because we already have a command pending */
991 dev_err(&adapter->pdev->dev, "Cannot configure mqprio, command %d pending\n",
992 adapter->current_op);
993 return;
994 }
995
996 len = (adapter->num_tc * sizeof(struct virtchnl_channel_info)) +
997 sizeof(struct virtchnl_tc_info);
998
999 vti = kzalloc(len, GFP_KERNEL);
1000 if (!vti)
1001 return;
1002 vti->num_tc = adapter->num_tc;
1003 for (i = 0; i < vti->num_tc; i++) {
1004 vti->list[i].count = adapter->ch_config.ch_info[i].count;
1005 vti->list[i].offset = adapter->ch_config.ch_info[i].offset;
1006 vti->list[i].pad = 0;
1007 vti->list[i].max_tx_rate =
1008 adapter->ch_config.ch_info[i].max_tx_rate;
1009 }
1010
1011 adapter->ch_config.state = __I40EVF_TC_RUNNING;
1012 adapter->flags |= I40EVF_FLAG_REINIT_ITR_NEEDED;
1013 adapter->current_op = VIRTCHNL_OP_ENABLE_CHANNELS;
1014 adapter->aq_required &= ~I40EVF_FLAG_AQ_ENABLE_CHANNELS;
1015 i40evf_send_pf_msg(adapter, VIRTCHNL_OP_ENABLE_CHANNELS,
1016 (u8 *)vti, len);
1017 kfree(vti);
1018}
1019
1020/**
1021 * i40evf_disable_channel
1022 * @adapter: adapter structure
1023 *
1024 * Request that the PF disable channels that are configured
1025 **/
1026void i40evf_disable_channels(struct i40evf_adapter *adapter)
1027{
1028 if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
1029 /* bail because we already have a command pending */
1030 dev_err(&adapter->pdev->dev, "Cannot configure mqprio, command %d pending\n",
1031 adapter->current_op);
1032 return;
1033 }
1034
1035 adapter->ch_config.state = __I40EVF_TC_INVALID;
1036 adapter->flags |= I40EVF_FLAG_REINIT_ITR_NEEDED;
1037 adapter->current_op = VIRTCHNL_OP_DISABLE_CHANNELS;
1038 adapter->aq_required &= ~I40EVF_FLAG_AQ_DISABLE_CHANNELS;
1039 i40evf_send_pf_msg(adapter, VIRTCHNL_OP_DISABLE_CHANNELS,
1040 NULL, 0);
1041}
1042
1043/**
1044 * i40evf_print_cloud_filter
1045 * @adapter: adapter structure
1046 * @f: cloud filter to print
1047 *
1048 * Print the cloud filter
1049 **/
1050static void i40evf_print_cloud_filter(struct i40evf_adapter *adapter,
1051 struct virtchnl_filter *f)
1052{
1053 switch (f->flow_type) {
1054 case VIRTCHNL_TCP_V4_FLOW:
1055 dev_info(&adapter->pdev->dev, "dst_mac: %pM src_mac: %pM vlan_id: %hu dst_ip: %pI4 src_ip %pI4 dst_port %hu src_port %hu\n",
1056 &f->data.tcp_spec.dst_mac,
1057 &f->data.tcp_spec.src_mac,
1058 ntohs(f->data.tcp_spec.vlan_id),
1059 &f->data.tcp_spec.dst_ip[0],
1060 &f->data.tcp_spec.src_ip[0],
1061 ntohs(f->data.tcp_spec.dst_port),
1062 ntohs(f->data.tcp_spec.src_port));
1063 break;
1064 case VIRTCHNL_TCP_V6_FLOW:
1065 dev_info(&adapter->pdev->dev, "dst_mac: %pM src_mac: %pM vlan_id: %hu dst_ip: %pI6 src_ip %pI6 dst_port %hu src_port %hu\n",
1066 &f->data.tcp_spec.dst_mac,
1067 &f->data.tcp_spec.src_mac,
1068 ntohs(f->data.tcp_spec.vlan_id),
1069 &f->data.tcp_spec.dst_ip,
1070 &f->data.tcp_spec.src_ip,
1071 ntohs(f->data.tcp_spec.dst_port),
1072 ntohs(f->data.tcp_spec.src_port));
1073 break;
1074 }
1075}
1076
1077/**
1078 * i40evf_add_cloud_filter
1079 * @adapter: adapter structure
1080 *
1081 * Request that the PF add cloud filters as specified
1082 * by the user via tc tool.
1083 **/
1084void i40evf_add_cloud_filter(struct i40evf_adapter *adapter)
1085{
1086 struct i40evf_cloud_filter *cf;
1087 struct virtchnl_filter *f;
1088 int len = 0, count = 0;
1089
1090 if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
1091 /* bail because we already have a command pending */
1092 dev_err(&adapter->pdev->dev, "Cannot add cloud filter, command %d pending\n",
1093 adapter->current_op);
1094 return;
1095 }
1096 list_for_each_entry(cf, &adapter->cloud_filter_list, list) {
1097 if (cf->add) {
1098 count++;
1099 break;
1100 }
1101 }
1102 if (!count) {
1103 adapter->aq_required &= ~I40EVF_FLAG_AQ_ADD_CLOUD_FILTER;
1104 return;
1105 }
1106 adapter->current_op = VIRTCHNL_OP_ADD_CLOUD_FILTER;
1107
1108 len = sizeof(struct virtchnl_filter);
1109 f = kzalloc(len, GFP_KERNEL);
1110 if (!f)
1111 return;
1112
1113 list_for_each_entry(cf, &adapter->cloud_filter_list, list) {
1114 if (cf->add) {
1115 memcpy(f, &cf->f, sizeof(struct virtchnl_filter));
1116 cf->add = false;
1117 cf->state = __I40EVF_CF_ADD_PENDING;
1118 i40evf_send_pf_msg(adapter,
1119 VIRTCHNL_OP_ADD_CLOUD_FILTER,
1120 (u8 *)f, len);
1121 }
1122 }
1123 kfree(f);
1124}
1125
1126/**
1127 * i40evf_del_cloud_filter
1128 * @adapter: adapter structure
1129 *
1130 * Request that the PF delete cloud filters as specified
1131 * by the user via tc tool.
1132 **/
1133void i40evf_del_cloud_filter(struct i40evf_adapter *adapter)
1134{
1135 struct i40evf_cloud_filter *cf, *cftmp;
1136 struct virtchnl_filter *f;
1137 int len = 0, count = 0;
1138
1139 if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
1140 /* bail because we already have a command pending */
1141 dev_err(&adapter->pdev->dev, "Cannot remove cloud filter, command %d pending\n",
1142 adapter->current_op);
1143 return;
1144 }
1145 list_for_each_entry(cf, &adapter->cloud_filter_list, list) {
1146 if (cf->del) {
1147 count++;
1148 break;
1149 }
1150 }
1151 if (!count) {
1152 adapter->aq_required &= ~I40EVF_FLAG_AQ_DEL_CLOUD_FILTER;
1153 return;
1154 }
1155 adapter->current_op = VIRTCHNL_OP_DEL_CLOUD_FILTER;
1156
1157 len = sizeof(struct virtchnl_filter);
1158 f = kzalloc(len, GFP_KERNEL);
1159 if (!f)
1160 return;
1161
1162 list_for_each_entry_safe(cf, cftmp, &adapter->cloud_filter_list, list) {
1163 if (cf->del) {
1164 memcpy(f, &cf->f, sizeof(struct virtchnl_filter));
1165 cf->del = false;
1166 cf->state = __I40EVF_CF_DEL_PENDING;
1167 i40evf_send_pf_msg(adapter,
1168 VIRTCHNL_OP_DEL_CLOUD_FILTER,
1169 (u8 *)f, len);
1170 }
1171 }
1172 kfree(f);
1173}
1174
1175/**
970 * i40evf_request_reset 1176 * i40evf_request_reset
971 * @adapter: adapter structure 1177 * @adapter: adapter structure
972 * 1178 *
@@ -1011,14 +1217,25 @@ void i40evf_virtchnl_completion(struct i40evf_adapter *adapter,
1011 if (adapter->link_up == link_up) 1217 if (adapter->link_up == link_up)
1012 break; 1218 break;
1013 1219
1014 /* If we get link up message and start queues before 1220 if (link_up) {
1015 * our queues are configured it will trigger a TX hang. 1221 /* If we get link up message and start queues
1016 * In that case, just ignore the link status message, 1222 * before our queues are configured it will
1017 * we'll get another one after we enable queues and 1223 * trigger a TX hang. In that case, just ignore
1018 * actually prepared to send traffic. 1224 * the link status message,we'll get another one
1019 */ 1225 * after we enable queues and actually prepared
1020 if (link_up && adapter->state != __I40EVF_RUNNING) 1226 * to send traffic.
1021 break; 1227 */
1228 if (adapter->state != __I40EVF_RUNNING)
1229 break;
1230
1231 /* For ADq enabled VF, we reconfigure VSIs and
1232 * re-allocate queues. Hence wait till all
1233 * queues are enabled.
1234 */
1235 if (adapter->flags &
1236 I40EVF_FLAG_QUEUES_DISABLED)
1237 break;
1238 }
1022 1239
1023 adapter->link_up = link_up; 1240 adapter->link_up = link_up;
1024 if (link_up) { 1241 if (link_up) {
@@ -1031,7 +1248,7 @@ void i40evf_virtchnl_completion(struct i40evf_adapter *adapter,
1031 i40evf_print_link_message(adapter); 1248 i40evf_print_link_message(adapter);
1032 break; 1249 break;
1033 case VIRTCHNL_EVENT_RESET_IMPENDING: 1250 case VIRTCHNL_EVENT_RESET_IMPENDING:
1034 dev_info(&adapter->pdev->dev, "PF reset warning received\n"); 1251 dev_info(&adapter->pdev->dev, "Reset warning received from the PF\n");
1035 if (!(adapter->flags & I40EVF_FLAG_RESET_PENDING)) { 1252 if (!(adapter->flags & I40EVF_FLAG_RESET_PENDING)) {
1036 adapter->flags |= I40EVF_FLAG_RESET_PENDING; 1253 adapter->flags |= I40EVF_FLAG_RESET_PENDING;
1037 dev_info(&adapter->pdev->dev, "Scheduling reset task\n"); 1254 dev_info(&adapter->pdev->dev, "Scheduling reset task\n");
@@ -1063,6 +1280,57 @@ void i40evf_virtchnl_completion(struct i40evf_adapter *adapter,
1063 dev_err(&adapter->pdev->dev, "Failed to delete MAC filter, error %s\n", 1280 dev_err(&adapter->pdev->dev, "Failed to delete MAC filter, error %s\n",
1064 i40evf_stat_str(&adapter->hw, v_retval)); 1281 i40evf_stat_str(&adapter->hw, v_retval));
1065 break; 1282 break;
1283 case VIRTCHNL_OP_ENABLE_CHANNELS:
1284 dev_err(&adapter->pdev->dev, "Failed to configure queue channels, error %s\n",
1285 i40evf_stat_str(&adapter->hw, v_retval));
1286 adapter->flags &= ~I40EVF_FLAG_REINIT_ITR_NEEDED;
1287 adapter->ch_config.state = __I40EVF_TC_INVALID;
1288 netdev_reset_tc(netdev);
1289 netif_tx_start_all_queues(netdev);
1290 break;
1291 case VIRTCHNL_OP_DISABLE_CHANNELS:
1292 dev_err(&adapter->pdev->dev, "Failed to disable queue channels, error %s\n",
1293 i40evf_stat_str(&adapter->hw, v_retval));
1294 adapter->flags &= ~I40EVF_FLAG_REINIT_ITR_NEEDED;
1295 adapter->ch_config.state = __I40EVF_TC_RUNNING;
1296 netif_tx_start_all_queues(netdev);
1297 break;
1298 case VIRTCHNL_OP_ADD_CLOUD_FILTER: {
1299 struct i40evf_cloud_filter *cf, *cftmp;
1300
1301 list_for_each_entry_safe(cf, cftmp,
1302 &adapter->cloud_filter_list,
1303 list) {
1304 if (cf->state == __I40EVF_CF_ADD_PENDING) {
1305 cf->state = __I40EVF_CF_INVALID;
1306 dev_info(&adapter->pdev->dev, "Failed to add cloud filter, error %s\n",
1307 i40evf_stat_str(&adapter->hw,
1308 v_retval));
1309 i40evf_print_cloud_filter(adapter,
1310 &cf->f);
1311 list_del(&cf->list);
1312 kfree(cf);
1313 adapter->num_cloud_filters--;
1314 }
1315 }
1316 }
1317 break;
1318 case VIRTCHNL_OP_DEL_CLOUD_FILTER: {
1319 struct i40evf_cloud_filter *cf;
1320
1321 list_for_each_entry(cf, &adapter->cloud_filter_list,
1322 list) {
1323 if (cf->state == __I40EVF_CF_DEL_PENDING) {
1324 cf->state = __I40EVF_CF_ACTIVE;
1325 dev_info(&adapter->pdev->dev, "Failed to del cloud filter, error %s\n",
1326 i40evf_stat_str(&adapter->hw,
1327 v_retval));
1328 i40evf_print_cloud_filter(adapter,
1329 &cf->f);
1330 }
1331 }
1332 }
1333 break;
1066 default: 1334 default:
1067 dev_err(&adapter->pdev->dev, "PF returned error %d (%s) to our request %d\n", 1335 dev_err(&adapter->pdev->dev, "PF returned error %d (%s) to our request %d\n",
1068 v_retval, 1336 v_retval,
@@ -1102,6 +1370,7 @@ void i40evf_virtchnl_completion(struct i40evf_adapter *adapter,
1102 case VIRTCHNL_OP_ENABLE_QUEUES: 1370 case VIRTCHNL_OP_ENABLE_QUEUES:
1103 /* enable transmits */ 1371 /* enable transmits */
1104 i40evf_irq_enable(adapter, true); 1372 i40evf_irq_enable(adapter, true);
1373 adapter->flags &= ~I40EVF_FLAG_QUEUES_DISABLED;
1105 break; 1374 break;
1106 case VIRTCHNL_OP_DISABLE_QUEUES: 1375 case VIRTCHNL_OP_DISABLE_QUEUES:
1107 i40evf_free_all_tx_resources(adapter); 1376 i40evf_free_all_tx_resources(adapter);
@@ -1156,6 +1425,29 @@ void i40evf_virtchnl_completion(struct i40evf_adapter *adapter,
1156 } 1425 }
1157 } 1426 }
1158 break; 1427 break;
1428 case VIRTCHNL_OP_ADD_CLOUD_FILTER: {
1429 struct i40evf_cloud_filter *cf;
1430
1431 list_for_each_entry(cf, &adapter->cloud_filter_list, list) {
1432 if (cf->state == __I40EVF_CF_ADD_PENDING)
1433 cf->state = __I40EVF_CF_ACTIVE;
1434 }
1435 }
1436 break;
1437 case VIRTCHNL_OP_DEL_CLOUD_FILTER: {
1438 struct i40evf_cloud_filter *cf, *cftmp;
1439
1440 list_for_each_entry_safe(cf, cftmp, &adapter->cloud_filter_list,
1441 list) {
1442 if (cf->state == __I40EVF_CF_DEL_PENDING) {
1443 cf->state = __I40EVF_CF_INVALID;
1444 list_del(&cf->list);
1445 kfree(cf);
1446 adapter->num_cloud_filters--;
1447 }
1448 }
1449 }
1450 break;
1159 default: 1451 default:
1160 if (adapter->current_op && (v_opcode != adapter->current_op)) 1452 if (adapter->current_op && (v_opcode != adapter->current_op))
1161 dev_warn(&adapter->pdev->dev, "Expected response %d from PF, received %d\n", 1453 dev_warn(&adapter->pdev->dev, "Expected response %d from PF, received %d\n",
diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h
index 1c6b8d9176a8..55d6f17d5799 100644
--- a/drivers/net/ethernet/intel/igb/igb.h
+++ b/drivers/net/ethernet/intel/igb/igb.h
@@ -109,6 +109,7 @@ struct vf_data_storage {
109 u16 pf_qos; 109 u16 pf_qos;
110 u16 tx_rate; 110 u16 tx_rate;
111 bool spoofchk_enabled; 111 bool spoofchk_enabled;
112 bool trusted;
112}; 113};
113 114
114/* Number of unicast MAC filters reserved for the PF in the RAR registers */ 115/* Number of unicast MAC filters reserved for the PF in the RAR registers */
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index b88fae785369..715bb32e6901 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -190,6 +190,8 @@ static int igb_ndo_set_vf_vlan(struct net_device *netdev,
190static int igb_ndo_set_vf_bw(struct net_device *, int, int, int); 190static int igb_ndo_set_vf_bw(struct net_device *, int, int, int);
191static int igb_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, 191static int igb_ndo_set_vf_spoofchk(struct net_device *netdev, int vf,
192 bool setting); 192 bool setting);
193static int igb_ndo_set_vf_trust(struct net_device *netdev, int vf,
194 bool setting);
193static int igb_ndo_get_vf_config(struct net_device *netdev, int vf, 195static int igb_ndo_get_vf_config(struct net_device *netdev, int vf,
194 struct ifla_vf_info *ivi); 196 struct ifla_vf_info *ivi);
195static void igb_check_vf_rate_limit(struct igb_adapter *); 197static void igb_check_vf_rate_limit(struct igb_adapter *);
@@ -774,8 +776,7 @@ u32 igb_rd32(struct e1000_hw *hw, u32 reg)
774 if (!(~value) && (!reg || !(~readl(hw_addr)))) { 776 if (!(~value) && (!reg || !(~readl(hw_addr)))) {
775 struct net_device *netdev = igb->netdev; 777 struct net_device *netdev = igb->netdev;
776 hw->hw_addr = NULL; 778 hw->hw_addr = NULL;
777 netif_device_detach(netdev); 779 netdev_err(netdev, "PCIe link lost\n");
778 netdev_err(netdev, "PCIe link lost, device now detached\n");
779 } 780 }
780 781
781 return value; 782 return value;
@@ -2527,6 +2528,7 @@ static const struct net_device_ops igb_netdev_ops = {
2527 .ndo_set_vf_vlan = igb_ndo_set_vf_vlan, 2528 .ndo_set_vf_vlan = igb_ndo_set_vf_vlan,
2528 .ndo_set_vf_rate = igb_ndo_set_vf_bw, 2529 .ndo_set_vf_rate = igb_ndo_set_vf_bw,
2529 .ndo_set_vf_spoofchk = igb_ndo_set_vf_spoofchk, 2530 .ndo_set_vf_spoofchk = igb_ndo_set_vf_spoofchk,
2531 .ndo_set_vf_trust = igb_ndo_set_vf_trust,
2530 .ndo_get_vf_config = igb_ndo_get_vf_config, 2532 .ndo_get_vf_config = igb_ndo_get_vf_config,
2531#ifdef CONFIG_NET_POLL_CONTROLLER 2533#ifdef CONFIG_NET_POLL_CONTROLLER
2532 .ndo_poll_controller = igb_netpoll, 2534 .ndo_poll_controller = igb_netpoll,
@@ -5747,7 +5749,7 @@ netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb,
5747 if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { 5749 if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
5748 struct igb_adapter *adapter = netdev_priv(tx_ring->netdev); 5750 struct igb_adapter *adapter = netdev_priv(tx_ring->netdev);
5749 5751
5750 if (adapter->tstamp_config.tx_type & HWTSTAMP_TX_ON && 5752 if (adapter->tstamp_config.tx_type == HWTSTAMP_TX_ON &&
5751 !test_and_set_bit_lock(__IGB_PTP_TX_IN_PROGRESS, 5753 !test_and_set_bit_lock(__IGB_PTP_TX_IN_PROGRESS,
5752 &adapter->state)) { 5754 &adapter->state)) {
5753 skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; 5755 skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
@@ -6383,6 +6385,9 @@ static int igb_vf_configure(struct igb_adapter *adapter, int vf)
6383 /* By default spoof check is enabled for all VFs */ 6385 /* By default spoof check is enabled for all VFs */
6384 adapter->vf_data[vf].spoofchk_enabled = true; 6386 adapter->vf_data[vf].spoofchk_enabled = true;
6385 6387
6388 /* By default VFs are not trusted */
6389 adapter->vf_data[vf].trusted = false;
6390
6386 return 0; 6391 return 0;
6387} 6392}
6388 6393
@@ -6940,13 +6945,13 @@ static int igb_set_vf_mac_filter(struct igb_adapter *adapter, const int vf,
6940 } 6945 }
6941 break; 6946 break;
6942 case E1000_VF_MAC_FILTER_ADD: 6947 case E1000_VF_MAC_FILTER_ADD:
6943 if (vf_data->flags & IGB_VF_FLAG_PF_SET_MAC) { 6948 if ((vf_data->flags & IGB_VF_FLAG_PF_SET_MAC) &&
6949 !vf_data->trusted) {
6944 dev_warn(&pdev->dev, 6950 dev_warn(&pdev->dev,
6945 "VF %d requested MAC filter but is administratively denied\n", 6951 "VF %d requested MAC filter but is administratively denied\n",
6946 vf); 6952 vf);
6947 return -EINVAL; 6953 return -EINVAL;
6948 } 6954 }
6949
6950 if (!is_valid_ether_addr(addr)) { 6955 if (!is_valid_ether_addr(addr)) {
6951 dev_warn(&pdev->dev, 6956 dev_warn(&pdev->dev,
6952 "VF %d attempted to set invalid MAC filter\n", 6957 "VF %d attempted to set invalid MAC filter\n",
@@ -6998,7 +7003,8 @@ static int igb_set_vf_mac_addr(struct igb_adapter *adapter, u32 *msg, int vf)
6998 int ret = 0; 7003 int ret = 0;
6999 7004
7000 if (!info) { 7005 if (!info) {
7001 if (vf_data->flags & IGB_VF_FLAG_PF_SET_MAC) { 7006 if ((vf_data->flags & IGB_VF_FLAG_PF_SET_MAC) &&
7007 !vf_data->trusted) {
7002 dev_warn(&pdev->dev, 7008 dev_warn(&pdev->dev,
7003 "VF %d attempted to override administratively set MAC address\nReload the VF driver to resume operations\n", 7009 "VF %d attempted to override administratively set MAC address\nReload the VF driver to resume operations\n",
7004 vf); 7010 vf);
@@ -8934,6 +8940,22 @@ static int igb_ndo_set_vf_spoofchk(struct net_device *netdev, int vf,
8934 return 0; 8940 return 0;
8935} 8941}
8936 8942
8943static int igb_ndo_set_vf_trust(struct net_device *netdev, int vf, bool setting)
8944{
8945 struct igb_adapter *adapter = netdev_priv(netdev);
8946
8947 if (vf >= adapter->vfs_allocated_count)
8948 return -EINVAL;
8949 if (adapter->vf_data[vf].trusted == setting)
8950 return 0;
8951
8952 adapter->vf_data[vf].trusted = setting;
8953
8954 dev_info(&adapter->pdev->dev, "VF %u is %strusted\n",
8955 vf, setting ? "" : "not ");
8956 return 0;
8957}
8958
8937static int igb_ndo_get_vf_config(struct net_device *netdev, 8959static int igb_ndo_get_vf_config(struct net_device *netdev,
8938 int vf, struct ifla_vf_info *ivi) 8960 int vf, struct ifla_vf_info *ivi)
8939{ 8961{
@@ -8947,6 +8969,7 @@ static int igb_ndo_get_vf_config(struct net_device *netdev,
8947 ivi->vlan = adapter->vf_data[vf].pf_vlan; 8969 ivi->vlan = adapter->vf_data[vf].pf_vlan;
8948 ivi->qos = adapter->vf_data[vf].pf_qos; 8970 ivi->qos = adapter->vf_data[vf].pf_qos;
8949 ivi->spoofchk = adapter->vf_data[vf].spoofchk_enabled; 8971 ivi->spoofchk = adapter->vf_data[vf].spoofchk_enabled;
8972 ivi->trusted = adapter->vf_data[vf].trusted;
8950 return 0; 8973 return 0;
8951} 8974}
8952 8975
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
index 221f15803480..c0e6ab42e0e1 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
@@ -97,6 +97,7 @@ static const struct ixgbe_stats ixgbe_gstrings_stats[] = {
97 {"tx_heartbeat_errors", IXGBE_NETDEV_STAT(tx_heartbeat_errors)}, 97 {"tx_heartbeat_errors", IXGBE_NETDEV_STAT(tx_heartbeat_errors)},
98 {"tx_timeout_count", IXGBE_STAT(tx_timeout_count)}, 98 {"tx_timeout_count", IXGBE_STAT(tx_timeout_count)},
99 {"tx_restart_queue", IXGBE_STAT(restart_queue)}, 99 {"tx_restart_queue", IXGBE_STAT(restart_queue)},
100 {"rx_length_errors", IXGBE_STAT(stats.rlec)},
100 {"rx_long_length_errors", IXGBE_STAT(stats.roc)}, 101 {"rx_long_length_errors", IXGBE_STAT(stats.roc)},
101 {"rx_short_length_errors", IXGBE_STAT(stats.ruc)}, 102 {"rx_short_length_errors", IXGBE_STAT(stats.ruc)},
102 {"tx_flow_control_xon", IXGBE_STAT(stats.lxontxc)}, 103 {"tx_flow_control_xon", IXGBE_STAT(stats.lxontxc)},
@@ -3059,6 +3060,8 @@ static int ixgbe_set_rxfh(struct net_device *netdev, const u32 *indir,
3059 3060
3060 for (i = 0; i < reta_entries; i++) 3061 for (i = 0; i < reta_entries; i++)
3061 adapter->rss_indir_tbl[i] = indir[i]; 3062 adapter->rss_indir_tbl[i] = indir[i];
3063
3064 ixgbe_store_reta(adapter);
3062 } 3065 }
3063 3066
3064 /* Fill out the rss hash key */ 3067 /* Fill out the rss hash key */
@@ -3067,8 +3070,6 @@ static int ixgbe_set_rxfh(struct net_device *netdev, const u32 *indir,
3067 ixgbe_store_key(adapter); 3070 ixgbe_store_key(adapter);
3068 } 3071 }
3069 3072
3070 ixgbe_store_reta(adapter);
3071
3072 return 0; 3073 return 0;
3073} 3074}
3074 3075
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
index 93eacddb6704..f2254528dcfc 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
@@ -423,15 +423,21 @@ static int ixgbe_ipsec_parse_proto_keys(struct xfrm_state *xs,
423 const char aes_gcm_name[] = "rfc4106(gcm(aes))"; 423 const char aes_gcm_name[] = "rfc4106(gcm(aes))";
424 int key_len; 424 int key_len;
425 425
426 if (xs->aead) { 426 if (!xs->aead) {
427 key_data = &xs->aead->alg_key[0];
428 key_len = xs->aead->alg_key_len;
429 alg_name = xs->aead->alg_name;
430 } else {
431 netdev_err(dev, "Unsupported IPsec algorithm\n"); 427 netdev_err(dev, "Unsupported IPsec algorithm\n");
432 return -EINVAL; 428 return -EINVAL;
433 } 429 }
434 430
431 if (xs->aead->alg_icv_len != IXGBE_IPSEC_AUTH_BITS) {
432 netdev_err(dev, "IPsec offload requires %d bit authentication\n",
433 IXGBE_IPSEC_AUTH_BITS);
434 return -EINVAL;
435 }
436
437 key_data = &xs->aead->alg_key[0];
438 key_len = xs->aead->alg_key_len;
439 alg_name = xs->aead->alg_name;
440
435 if (strcmp(alg_name, aes_gcm_name)) { 441 if (strcmp(alg_name, aes_gcm_name)) {
436 netdev_err(dev, "Unsupported IPsec algorithm - please use %s\n", 442 netdev_err(dev, "Unsupported IPsec algorithm - please use %s\n",
437 aes_gcm_name); 443 aes_gcm_name);
@@ -718,23 +724,10 @@ static bool ixgbe_ipsec_offload_ok(struct sk_buff *skb, struct xfrm_state *xs)
718 return true; 724 return true;
719} 725}
720 726
721/**
722 * ixgbe_ipsec_free - called by xfrm garbage collections
723 * @xs: pointer to transformer state struct
724 *
725 * We don't have any garbage to collect, so we shouldn't bother
726 * implementing this function, but the XFRM code doesn't check for
727 * existence before calling the API callback.
728 **/
729static void ixgbe_ipsec_free(struct xfrm_state *xs)
730{
731}
732
733static const struct xfrmdev_ops ixgbe_xfrmdev_ops = { 727static const struct xfrmdev_ops ixgbe_xfrmdev_ops = {
734 .xdo_dev_state_add = ixgbe_ipsec_add_sa, 728 .xdo_dev_state_add = ixgbe_ipsec_add_sa,
735 .xdo_dev_state_delete = ixgbe_ipsec_del_sa, 729 .xdo_dev_state_delete = ixgbe_ipsec_del_sa,
736 .xdo_dev_offload_ok = ixgbe_ipsec_offload_ok, 730 .xdo_dev_offload_ok = ixgbe_ipsec_offload_ok,
737 .xdo_dev_state_free = ixgbe_ipsec_free,
738}; 731};
739 732
740/** 733/**
@@ -783,11 +776,33 @@ int ixgbe_ipsec_tx(struct ixgbe_ring *tx_ring,
783 776
784 itd->flags = 0; 777 itd->flags = 0;
785 if (xs->id.proto == IPPROTO_ESP) { 778 if (xs->id.proto == IPPROTO_ESP) {
779 struct sk_buff *skb = first->skb;
780 int ret, authlen, trailerlen;
781 u8 padlen;
782
786 itd->flags |= IXGBE_ADVTXD_TUCMD_IPSEC_TYPE_ESP | 783 itd->flags |= IXGBE_ADVTXD_TUCMD_IPSEC_TYPE_ESP |
787 IXGBE_ADVTXD_TUCMD_L4T_TCP; 784 IXGBE_ADVTXD_TUCMD_L4T_TCP;
788 if (first->protocol == htons(ETH_P_IP)) 785 if (first->protocol == htons(ETH_P_IP))
789 itd->flags |= IXGBE_ADVTXD_TUCMD_IPV4; 786 itd->flags |= IXGBE_ADVTXD_TUCMD_IPV4;
790 itd->trailer_len = xs->props.trailer_len; 787
788 /* The actual trailer length is authlen (16 bytes) plus
789 * 2 bytes for the proto and the padlen values, plus
790 * padlen bytes of padding. This ends up not the same
791 * as the static value found in xs->props.trailer_len (21).
792 *
793 * The "correct" way to get the auth length would be to use
794 * authlen = crypto_aead_authsize(xs->data);
795 * but since we know we only have one size to worry about
796 * we can let the compiler use the constant and save us a
797 * few CPU cycles.
798 */
799 authlen = IXGBE_IPSEC_AUTH_BITS / 8;
800
801 ret = skb_copy_bits(skb, skb->len - (authlen + 2), &padlen, 1);
802 if (unlikely(ret))
803 return 0;
804 trailerlen = authlen + 2 + padlen;
805 itd->trailer_len = trailerlen;
791 } 806 }
792 if (tsa->encrypt) 807 if (tsa->encrypt)
793 itd->flags |= IXGBE_ADVTXD_TUCMD_IPSEC_ENCRYPT_EN; 808 itd->flags |= IXGBE_ADVTXD_TUCMD_IPSEC_ENCRYPT_EN;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h
index da3ce7849e85..87d2800b94ab 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h
@@ -32,6 +32,7 @@
32#define IXGBE_IPSEC_MAX_RX_IP_COUNT 128 32#define IXGBE_IPSEC_MAX_RX_IP_COUNT 128
33#define IXGBE_IPSEC_BASE_RX_INDEX 0 33#define IXGBE_IPSEC_BASE_RX_INDEX 0
34#define IXGBE_IPSEC_BASE_TX_INDEX IXGBE_IPSEC_MAX_SA_COUNT 34#define IXGBE_IPSEC_BASE_TX_INDEX IXGBE_IPSEC_MAX_SA_COUNT
35#define IXGBE_IPSEC_AUTH_BITS 128
35 36
36#define IXGBE_RXTXIDX_IPS_EN 0x00000001 37#define IXGBE_RXTXIDX_IPS_EN 0x00000001
37#define IXGBE_RXIDX_TBL_SHIFT 1 38#define IXGBE_RXIDX_TBL_SHIFT 1
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
index 4242f0213e46..ed4cbe94c355 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
@@ -58,7 +58,6 @@ static bool ixgbe_cache_ring_dcb_sriov(struct ixgbe_adapter *adapter)
58 return false; 58 return false;
59 59
60 /* start at VMDq register offset for SR-IOV enabled setups */ 60 /* start at VMDq register offset for SR-IOV enabled setups */
61 pool = 0;
62 reg_idx = vmdq->offset * __ALIGN_MASK(1, ~vmdq->mask); 61 reg_idx = vmdq->offset * __ALIGN_MASK(1, ~vmdq->mask);
63 for (i = 0, pool = 0; i < adapter->num_rx_queues; i++, reg_idx++) { 62 for (i = 0, pool = 0; i < adapter->num_rx_queues; i++, reg_idx++) {
64 /* If we are greater than indices move to next pool */ 63 /* If we are greater than indices move to next pool */
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 9fc063af233c..85369423452d 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -7711,7 +7711,8 @@ static void ixgbe_service_task(struct work_struct *work)
7711 7711
7712 if (test_bit(__IXGBE_PTP_RUNNING, &adapter->state)) { 7712 if (test_bit(__IXGBE_PTP_RUNNING, &adapter->state)) {
7713 ixgbe_ptp_overflow_check(adapter); 7713 ixgbe_ptp_overflow_check(adapter);
7714 ixgbe_ptp_rx_hang(adapter); 7714 if (adapter->flags & IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER)
7715 ixgbe_ptp_rx_hang(adapter);
7715 ixgbe_ptp_tx_hang(adapter); 7716 ixgbe_ptp_tx_hang(adapter);
7716 } 7717 }
7717 7718
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
index 27a70a52f3c9..008aa073a679 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
@@ -831,7 +831,11 @@ static int ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf)
831 IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset), reg); 831 IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset), reg);
832 832
833 /* force drop enable for all VF Rx queues */ 833 /* force drop enable for all VF Rx queues */
834 ixgbe_write_qde(adapter, vf, IXGBE_QDE_ENABLE); 834 reg = IXGBE_QDE_ENABLE;
835 if (adapter->vfinfo[vf].pf_vlan)
836 reg |= IXGBE_QDE_HIDE_VLAN;
837
838 ixgbe_write_qde(adapter, vf, reg);
835 839
836 /* enable receive for vf */ 840 /* enable receive for vf */
837 reg = IXGBE_READ_REG(hw, IXGBE_VFRE(reg_offset)); 841 reg = IXGBE_READ_REG(hw, IXGBE_VFRE(reg_offset));
diff --git a/drivers/net/ethernet/intel/ixgbevf/ethtool.c b/drivers/net/ethernet/intel/ixgbevf/ethtool.c
index 4400e49090b4..e7623fed42da 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ethtool.c
@@ -94,6 +94,13 @@ static const char ixgbe_gstrings_test[][ETH_GSTRING_LEN] = {
94 94
95#define IXGBEVF_TEST_LEN (sizeof(ixgbe_gstrings_test) / ETH_GSTRING_LEN) 95#define IXGBEVF_TEST_LEN (sizeof(ixgbe_gstrings_test) / ETH_GSTRING_LEN)
96 96
97static const char ixgbevf_priv_flags_strings[][ETH_GSTRING_LEN] = {
98#define IXGBEVF_PRIV_FLAGS_LEGACY_RX BIT(0)
99 "legacy-rx",
100};
101
102#define IXGBEVF_PRIV_FLAGS_STR_LEN ARRAY_SIZE(ixgbevf_priv_flags_strings)
103
97static int ixgbevf_get_link_ksettings(struct net_device *netdev, 104static int ixgbevf_get_link_ksettings(struct net_device *netdev,
98 struct ethtool_link_ksettings *cmd) 105 struct ethtool_link_ksettings *cmd)
99{ 106{
@@ -241,6 +248,8 @@ static void ixgbevf_get_drvinfo(struct net_device *netdev,
241 sizeof(drvinfo->version)); 248 sizeof(drvinfo->version));
242 strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), 249 strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
243 sizeof(drvinfo->bus_info)); 250 sizeof(drvinfo->bus_info));
251
252 drvinfo->n_priv_flags = IXGBEVF_PRIV_FLAGS_STR_LEN;
244} 253}
245 254
246static void ixgbevf_get_ringparam(struct net_device *netdev, 255static void ixgbevf_get_ringparam(struct net_device *netdev,
@@ -392,6 +401,8 @@ static int ixgbevf_get_sset_count(struct net_device *netdev, int stringset)
392 return IXGBEVF_TEST_LEN; 401 return IXGBEVF_TEST_LEN;
393 case ETH_SS_STATS: 402 case ETH_SS_STATS:
394 return IXGBEVF_STATS_LEN; 403 return IXGBEVF_STATS_LEN;
404 case ETH_SS_PRIV_FLAGS:
405 return IXGBEVF_PRIV_FLAGS_STR_LEN;
395 default: 406 default:
396 return -EINVAL; 407 return -EINVAL;
397 } 408 }
@@ -496,6 +507,10 @@ static void ixgbevf_get_strings(struct net_device *netdev, u32 stringset,
496 p += ETH_GSTRING_LEN; 507 p += ETH_GSTRING_LEN;
497 } 508 }
498 break; 509 break;
510 case ETH_SS_PRIV_FLAGS:
511 memcpy(data, ixgbevf_priv_flags_strings,
512 IXGBEVF_PRIV_FLAGS_STR_LEN * ETH_GSTRING_LEN);
513 break;
499 } 514 }
500} 515}
501 516
@@ -888,6 +903,37 @@ static int ixgbevf_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
888 return err; 903 return err;
889} 904}
890 905
906static u32 ixgbevf_get_priv_flags(struct net_device *netdev)
907{
908 struct ixgbevf_adapter *adapter = netdev_priv(netdev);
909 u32 priv_flags = 0;
910
911 if (adapter->flags & IXGBEVF_FLAGS_LEGACY_RX)
912 priv_flags |= IXGBEVF_PRIV_FLAGS_LEGACY_RX;
913
914 return priv_flags;
915}
916
917static int ixgbevf_set_priv_flags(struct net_device *netdev, u32 priv_flags)
918{
919 struct ixgbevf_adapter *adapter = netdev_priv(netdev);
920 unsigned int flags = adapter->flags;
921
922 flags &= ~IXGBEVF_FLAGS_LEGACY_RX;
923 if (priv_flags & IXGBEVF_PRIV_FLAGS_LEGACY_RX)
924 flags |= IXGBEVF_FLAGS_LEGACY_RX;
925
926 if (flags != adapter->flags) {
927 adapter->flags = flags;
928
929 /* reset interface to repopulate queues */
930 if (netif_running(netdev))
931 ixgbevf_reinit_locked(adapter);
932 }
933
934 return 0;
935}
936
891static const struct ethtool_ops ixgbevf_ethtool_ops = { 937static const struct ethtool_ops ixgbevf_ethtool_ops = {
892 .get_drvinfo = ixgbevf_get_drvinfo, 938 .get_drvinfo = ixgbevf_get_drvinfo,
893 .get_regs_len = ixgbevf_get_regs_len, 939 .get_regs_len = ixgbevf_get_regs_len,
@@ -909,6 +955,8 @@ static const struct ethtool_ops ixgbevf_ethtool_ops = {
909 .get_rxfh_key_size = ixgbevf_get_rxfh_key_size, 955 .get_rxfh_key_size = ixgbevf_get_rxfh_key_size,
910 .get_rxfh = ixgbevf_get_rxfh, 956 .get_rxfh = ixgbevf_get_rxfh,
911 .get_link_ksettings = ixgbevf_get_link_ksettings, 957 .get_link_ksettings = ixgbevf_get_link_ksettings,
958 .get_priv_flags = ixgbevf_get_priv_flags,
959 .set_priv_flags = ixgbevf_set_priv_flags,
912}; 960};
913 961
914void ixgbevf_set_ethtool_ops(struct net_device *netdev) 962void ixgbevf_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
index f6952425c87d..f65ca156af2d 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
@@ -89,19 +89,15 @@ struct ixgbevf_rx_queue_stats {
89}; 89};
90 90
91enum ixgbevf_ring_state_t { 91enum ixgbevf_ring_state_t {
92 __IXGBEVF_RX_3K_BUFFER,
93 __IXGBEVF_RX_BUILD_SKB_ENABLED,
92 __IXGBEVF_TX_DETECT_HANG, 94 __IXGBEVF_TX_DETECT_HANG,
93 __IXGBEVF_HANG_CHECK_ARMED, 95 __IXGBEVF_HANG_CHECK_ARMED,
94}; 96};
95 97
96#define check_for_tx_hang(ring) \
97 test_bit(__IXGBEVF_TX_DETECT_HANG, &(ring)->state)
98#define set_check_for_tx_hang(ring) \
99 set_bit(__IXGBEVF_TX_DETECT_HANG, &(ring)->state)
100#define clear_check_for_tx_hang(ring) \
101 clear_bit(__IXGBEVF_TX_DETECT_HANG, &(ring)->state)
102
103struct ixgbevf_ring { 98struct ixgbevf_ring {
104 struct ixgbevf_ring *next; 99 struct ixgbevf_ring *next;
100 struct ixgbevf_q_vector *q_vector; /* backpointer to q_vector */
105 struct net_device *netdev; 101 struct net_device *netdev;
106 struct device *dev; 102 struct device *dev;
107 void *desc; /* descriptor ring memory */ 103 void *desc; /* descriptor ring memory */
@@ -133,7 +129,7 @@ struct ixgbevf_ring {
133 */ 129 */
134 u16 reg_idx; 130 u16 reg_idx;
135 int queue_index; /* needed for multiqueue queue management */ 131 int queue_index; /* needed for multiqueue queue management */
136}; 132} ____cacheline_internodealigned_in_smp;
137 133
138/* How many Rx Buffers do we bundle into one write to the hardware ? */ 134/* How many Rx Buffers do we bundle into one write to the hardware ? */
139#define IXGBEVF_RX_BUFFER_WRITE 16 /* Must be power of 2 */ 135#define IXGBEVF_RX_BUFFER_WRITE 16 /* Must be power of 2 */
@@ -156,12 +152,20 @@ struct ixgbevf_ring {
156/* Supported Rx Buffer Sizes */ 152/* Supported Rx Buffer Sizes */
157#define IXGBEVF_RXBUFFER_256 256 /* Used for packet split */ 153#define IXGBEVF_RXBUFFER_256 256 /* Used for packet split */
158#define IXGBEVF_RXBUFFER_2048 2048 154#define IXGBEVF_RXBUFFER_2048 2048
155#define IXGBEVF_RXBUFFER_3072 3072
159 156
160#define IXGBEVF_RX_HDR_SIZE IXGBEVF_RXBUFFER_256 157#define IXGBEVF_RX_HDR_SIZE IXGBEVF_RXBUFFER_256
161#define IXGBEVF_RX_BUFSZ IXGBEVF_RXBUFFER_2048
162 158
163#define MAXIMUM_ETHERNET_VLAN_SIZE (VLAN_ETH_FRAME_LEN + ETH_FCS_LEN) 159#define MAXIMUM_ETHERNET_VLAN_SIZE (VLAN_ETH_FRAME_LEN + ETH_FCS_LEN)
164 160
161#define IXGBEVF_SKB_PAD (NET_SKB_PAD + NET_IP_ALIGN)
162#if (PAGE_SIZE < 8192)
163#define IXGBEVF_MAX_FRAME_BUILD_SKB \
164 (SKB_WITH_OVERHEAD(IXGBEVF_RXBUFFER_2048) - IXGBEVF_SKB_PAD)
165#else
166#define IXGBEVF_MAX_FRAME_BUILD_SKB IXGBEVF_RXBUFFER_2048
167#endif
168
165#define IXGBE_TX_FLAGS_CSUM BIT(0) 169#define IXGBE_TX_FLAGS_CSUM BIT(0)
166#define IXGBE_TX_FLAGS_VLAN BIT(1) 170#define IXGBE_TX_FLAGS_VLAN BIT(1)
167#define IXGBE_TX_FLAGS_TSO BIT(2) 171#define IXGBE_TX_FLAGS_TSO BIT(2)
@@ -170,6 +174,50 @@ struct ixgbevf_ring {
170#define IXGBE_TX_FLAGS_VLAN_PRIO_MASK 0x0000e000 174#define IXGBE_TX_FLAGS_VLAN_PRIO_MASK 0x0000e000
171#define IXGBE_TX_FLAGS_VLAN_SHIFT 16 175#define IXGBE_TX_FLAGS_VLAN_SHIFT 16
172 176
177#define ring_uses_large_buffer(ring) \
178 test_bit(__IXGBEVF_RX_3K_BUFFER, &(ring)->state)
179#define set_ring_uses_large_buffer(ring) \
180 set_bit(__IXGBEVF_RX_3K_BUFFER, &(ring)->state)
181#define clear_ring_uses_large_buffer(ring) \
182 clear_bit(__IXGBEVF_RX_3K_BUFFER, &(ring)->state)
183
184#define ring_uses_build_skb(ring) \
185 test_bit(__IXGBEVF_RX_BUILD_SKB_ENABLED, &(ring)->state)
186#define set_ring_build_skb_enabled(ring) \
187 set_bit(__IXGBEVF_RX_BUILD_SKB_ENABLED, &(ring)->state)
188#define clear_ring_build_skb_enabled(ring) \
189 clear_bit(__IXGBEVF_RX_BUILD_SKB_ENABLED, &(ring)->state)
190
191static inline unsigned int ixgbevf_rx_bufsz(struct ixgbevf_ring *ring)
192{
193#if (PAGE_SIZE < 8192)
194 if (ring_uses_large_buffer(ring))
195 return IXGBEVF_RXBUFFER_3072;
196
197 if (ring_uses_build_skb(ring))
198 return IXGBEVF_MAX_FRAME_BUILD_SKB;
199#endif
200 return IXGBEVF_RXBUFFER_2048;
201}
202
203static inline unsigned int ixgbevf_rx_pg_order(struct ixgbevf_ring *ring)
204{
205#if (PAGE_SIZE < 8192)
206 if (ring_uses_large_buffer(ring))
207 return 1;
208#endif
209 return 0;
210}
211
212#define ixgbevf_rx_pg_size(_ring) (PAGE_SIZE << ixgbevf_rx_pg_order(_ring))
213
214#define check_for_tx_hang(ring) \
215 test_bit(__IXGBEVF_TX_DETECT_HANG, &(ring)->state)
216#define set_check_for_tx_hang(ring) \
217 set_bit(__IXGBEVF_TX_DETECT_HANG, &(ring)->state)
218#define clear_check_for_tx_hang(ring) \
219 clear_bit(__IXGBEVF_TX_DETECT_HANG, &(ring)->state)
220
173struct ixgbevf_ring_container { 221struct ixgbevf_ring_container {
174 struct ixgbevf_ring *ring; /* pointer to linked list of rings */ 222 struct ixgbevf_ring *ring; /* pointer to linked list of rings */
175 unsigned int total_bytes; /* total bytes processed this int */ 223 unsigned int total_bytes; /* total bytes processed this int */
@@ -194,7 +242,11 @@ struct ixgbevf_q_vector {
194 u16 itr; /* Interrupt throttle rate written to EITR */ 242 u16 itr; /* Interrupt throttle rate written to EITR */
195 struct napi_struct napi; 243 struct napi_struct napi;
196 struct ixgbevf_ring_container rx, tx; 244 struct ixgbevf_ring_container rx, tx;
245 struct rcu_head rcu; /* to avoid race with update stats on free */
197 char name[IFNAMSIZ + 9]; 246 char name[IFNAMSIZ + 9];
247
248 /* for dynamic allocation of rings associated with this q_vector */
249 struct ixgbevf_ring ring[0] ____cacheline_internodealigned_in_smp;
198#ifdef CONFIG_NET_RX_BUSY_POLL 250#ifdef CONFIG_NET_RX_BUSY_POLL
199 unsigned int state; 251 unsigned int state;
200#define IXGBEVF_QV_STATE_IDLE 0 252#define IXGBEVF_QV_STATE_IDLE 0
@@ -331,6 +383,8 @@ struct ixgbevf_adapter {
331 383
332 u32 *rss_key; 384 u32 *rss_key;
333 u8 rss_indir_tbl[IXGBEVF_X550_VFRETA_SIZE]; 385 u8 rss_indir_tbl[IXGBEVF_X550_VFRETA_SIZE];
386 u32 flags;
387#define IXGBEVF_FLAGS_LEGACY_RX BIT(1)
334}; 388};
335 389
336enum ixbgevf_state_t { 390enum ixbgevf_state_t {
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 9b3d43d28106..4da449e0a4ba 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -130,6 +130,9 @@ static void ixgbevf_service_event_complete(struct ixgbevf_adapter *adapter)
130static void ixgbevf_queue_reset_subtask(struct ixgbevf_adapter *adapter); 130static void ixgbevf_queue_reset_subtask(struct ixgbevf_adapter *adapter);
131static void ixgbevf_set_itr(struct ixgbevf_q_vector *q_vector); 131static void ixgbevf_set_itr(struct ixgbevf_q_vector *q_vector);
132static void ixgbevf_free_all_rx_resources(struct ixgbevf_adapter *adapter); 132static void ixgbevf_free_all_rx_resources(struct ixgbevf_adapter *adapter);
133static bool ixgbevf_can_reuse_rx_page(struct ixgbevf_rx_buffer *rx_buffer);
134static void ixgbevf_reuse_rx_page(struct ixgbevf_ring *rx_ring,
135 struct ixgbevf_rx_buffer *old_buff);
133 136
134static void ixgbevf_remove_adapter(struct ixgbe_hw *hw) 137static void ixgbevf_remove_adapter(struct ixgbe_hw *hw)
135{ 138{
@@ -527,6 +530,49 @@ static void ixgbevf_process_skb_fields(struct ixgbevf_ring *rx_ring,
527 skb->protocol = eth_type_trans(skb, rx_ring->netdev); 530 skb->protocol = eth_type_trans(skb, rx_ring->netdev);
528} 531}
529 532
533static
534struct ixgbevf_rx_buffer *ixgbevf_get_rx_buffer(struct ixgbevf_ring *rx_ring,
535 const unsigned int size)
536{
537 struct ixgbevf_rx_buffer *rx_buffer;
538
539 rx_buffer = &rx_ring->rx_buffer_info[rx_ring->next_to_clean];
540 prefetchw(rx_buffer->page);
541
542 /* we are reusing so sync this buffer for CPU use */
543 dma_sync_single_range_for_cpu(rx_ring->dev,
544 rx_buffer->dma,
545 rx_buffer->page_offset,
546 size,
547 DMA_FROM_DEVICE);
548
549 rx_buffer->pagecnt_bias--;
550
551 return rx_buffer;
552}
553
554static void ixgbevf_put_rx_buffer(struct ixgbevf_ring *rx_ring,
555 struct ixgbevf_rx_buffer *rx_buffer)
556{
557 if (ixgbevf_can_reuse_rx_page(rx_buffer)) {
558 /* hand second half of page back to the ring */
559 ixgbevf_reuse_rx_page(rx_ring, rx_buffer);
560 } else {
561 /* We are not reusing the buffer so unmap it and free
562 * any references we are holding to it
563 */
564 dma_unmap_page_attrs(rx_ring->dev, rx_buffer->dma,
565 ixgbevf_rx_pg_size(rx_ring),
566 DMA_FROM_DEVICE,
567 IXGBEVF_RX_DMA_ATTR);
568 __page_frag_cache_drain(rx_buffer->page,
569 rx_buffer->pagecnt_bias);
570 }
571
572 /* clear contents of rx_buffer */
573 rx_buffer->page = NULL;
574}
575
530/** 576/**
531 * ixgbevf_is_non_eop - process handling of non-EOP buffers 577 * ixgbevf_is_non_eop - process handling of non-EOP buffers
532 * @rx_ring: Rx ring being processed 578 * @rx_ring: Rx ring being processed
@@ -554,32 +600,38 @@ static bool ixgbevf_is_non_eop(struct ixgbevf_ring *rx_ring,
554 return true; 600 return true;
555} 601}
556 602
603static inline unsigned int ixgbevf_rx_offset(struct ixgbevf_ring *rx_ring)
604{
605 return ring_uses_build_skb(rx_ring) ? IXGBEVF_SKB_PAD : 0;
606}
607
557static bool ixgbevf_alloc_mapped_page(struct ixgbevf_ring *rx_ring, 608static bool ixgbevf_alloc_mapped_page(struct ixgbevf_ring *rx_ring,
558 struct ixgbevf_rx_buffer *bi) 609 struct ixgbevf_rx_buffer *bi)
559{ 610{
560 struct page *page = bi->page; 611 struct page *page = bi->page;
561 dma_addr_t dma = bi->dma; 612 dma_addr_t dma;
562 613
563 /* since we are recycling buffers we should seldom need to alloc */ 614 /* since we are recycling buffers we should seldom need to alloc */
564 if (likely(page)) 615 if (likely(page))
565 return true; 616 return true;
566 617
567 /* alloc new page for storage */ 618 /* alloc new page for storage */
568 page = dev_alloc_page(); 619 page = dev_alloc_pages(ixgbevf_rx_pg_order(rx_ring));
569 if (unlikely(!page)) { 620 if (unlikely(!page)) {
570 rx_ring->rx_stats.alloc_rx_page_failed++; 621 rx_ring->rx_stats.alloc_rx_page_failed++;
571 return false; 622 return false;
572 } 623 }
573 624
574 /* map page for use */ 625 /* map page for use */
575 dma = dma_map_page_attrs(rx_ring->dev, page, 0, PAGE_SIZE, 626 dma = dma_map_page_attrs(rx_ring->dev, page, 0,
627 ixgbevf_rx_pg_size(rx_ring),
576 DMA_FROM_DEVICE, IXGBEVF_RX_DMA_ATTR); 628 DMA_FROM_DEVICE, IXGBEVF_RX_DMA_ATTR);
577 629
578 /* if mapping failed free memory back to system since 630 /* if mapping failed free memory back to system since
579 * there isn't much point in holding memory we can't use 631 * there isn't much point in holding memory we can't use
580 */ 632 */
581 if (dma_mapping_error(rx_ring->dev, dma)) { 633 if (dma_mapping_error(rx_ring->dev, dma)) {
582 __free_page(page); 634 __free_pages(page, ixgbevf_rx_pg_order(rx_ring));
583 635
584 rx_ring->rx_stats.alloc_rx_page_failed++; 636 rx_ring->rx_stats.alloc_rx_page_failed++;
585 return false; 637 return false;
@@ -587,7 +639,7 @@ static bool ixgbevf_alloc_mapped_page(struct ixgbevf_ring *rx_ring,
587 639
588 bi->dma = dma; 640 bi->dma = dma;
589 bi->page = page; 641 bi->page = page;
590 bi->page_offset = 0; 642 bi->page_offset = ixgbevf_rx_offset(rx_ring);
591 bi->pagecnt_bias = 1; 643 bi->pagecnt_bias = 1;
592 rx_ring->rx_stats.alloc_rx_page++; 644 rx_ring->rx_stats.alloc_rx_page++;
593 645
@@ -621,7 +673,7 @@ static void ixgbevf_alloc_rx_buffers(struct ixgbevf_ring *rx_ring,
621 /* sync the buffer for use by the device */ 673 /* sync the buffer for use by the device */
622 dma_sync_single_range_for_device(rx_ring->dev, bi->dma, 674 dma_sync_single_range_for_device(rx_ring->dev, bi->dma,
623 bi->page_offset, 675 bi->page_offset,
624 IXGBEVF_RX_BUFSZ, 676 ixgbevf_rx_bufsz(rx_ring),
625 DMA_FROM_DEVICE); 677 DMA_FROM_DEVICE);
626 678
627 /* Refresh the desc even if pkt_addr didn't change 679 /* Refresh the desc even if pkt_addr didn't change
@@ -734,11 +786,10 @@ static inline bool ixgbevf_page_is_reserved(struct page *page)
734 return (page_to_nid(page) != numa_mem_id()) || page_is_pfmemalloc(page); 786 return (page_to_nid(page) != numa_mem_id()) || page_is_pfmemalloc(page);
735} 787}
736 788
737static bool ixgbevf_can_reuse_rx_page(struct ixgbevf_rx_buffer *rx_buffer, 789static bool ixgbevf_can_reuse_rx_page(struct ixgbevf_rx_buffer *rx_buffer)
738 struct page *page,
739 const unsigned int truesize)
740{ 790{
741 unsigned int pagecnt_bias = rx_buffer->pagecnt_bias--; 791 unsigned int pagecnt_bias = rx_buffer->pagecnt_bias;
792 struct page *page = rx_buffer->page;
742 793
743 /* avoid re-using remote pages */ 794 /* avoid re-using remote pages */
744 if (unlikely(ixgbevf_page_is_reserved(page))) 795 if (unlikely(ixgbevf_page_is_reserved(page)))
@@ -746,17 +797,13 @@ static bool ixgbevf_can_reuse_rx_page(struct ixgbevf_rx_buffer *rx_buffer,
746 797
747#if (PAGE_SIZE < 8192) 798#if (PAGE_SIZE < 8192)
748 /* if we are only owner of page we can reuse it */ 799 /* if we are only owner of page we can reuse it */
749 if (unlikely(page_ref_count(page) != pagecnt_bias)) 800 if (unlikely((page_ref_count(page) - pagecnt_bias) > 1))
750 return false; 801 return false;
751
752 /* flip page offset to other buffer */
753 rx_buffer->page_offset ^= IXGBEVF_RX_BUFSZ;
754
755#else 802#else
756 /* move offset up to the next cache line */ 803#define IXGBEVF_LAST_OFFSET \
757 rx_buffer->page_offset += truesize; 804 (SKB_WITH_OVERHEAD(PAGE_SIZE) - IXGBEVF_RXBUFFER_2048)
758 805
759 if (rx_buffer->page_offset > (PAGE_SIZE - IXGBEVF_RX_BUFSZ)) 806 if (rx_buffer->page_offset > IXGBEVF_LAST_OFFSET)
760 return false; 807 return false;
761 808
762#endif 809#endif
@@ -765,7 +812,7 @@ static bool ixgbevf_can_reuse_rx_page(struct ixgbevf_rx_buffer *rx_buffer,
765 * the pagecnt_bias and page count so that we fully restock the 812 * the pagecnt_bias and page count so that we fully restock the
766 * number of references the driver holds. 813 * number of references the driver holds.
767 */ 814 */
768 if (unlikely(pagecnt_bias == 1)) { 815 if (unlikely(!pagecnt_bias)) {
769 page_ref_add(page, USHRT_MAX); 816 page_ref_add(page, USHRT_MAX);
770 rx_buffer->pagecnt_bias = USHRT_MAX; 817 rx_buffer->pagecnt_bias = USHRT_MAX;
771 } 818 }
@@ -777,127 +824,81 @@ static bool ixgbevf_can_reuse_rx_page(struct ixgbevf_rx_buffer *rx_buffer,
777 * ixgbevf_add_rx_frag - Add contents of Rx buffer to sk_buff 824 * ixgbevf_add_rx_frag - Add contents of Rx buffer to sk_buff
778 * @rx_ring: rx descriptor ring to transact packets on 825 * @rx_ring: rx descriptor ring to transact packets on
779 * @rx_buffer: buffer containing page to add 826 * @rx_buffer: buffer containing page to add
780 * @rx_desc: descriptor containing length of buffer written by hardware
781 * @skb: sk_buff to place the data into 827 * @skb: sk_buff to place the data into
828 * @size: size of buffer to be added
782 * 829 *
783 * This function will add the data contained in rx_buffer->page to the skb. 830 * This function will add the data contained in rx_buffer->page to the skb.
784 * This is done either through a direct copy if the data in the buffer is
785 * less than the skb header size, otherwise it will just attach the page as
786 * a frag to the skb.
787 *
788 * The function will then update the page offset if necessary and return
789 * true if the buffer can be reused by the adapter.
790 **/ 831 **/
791static bool ixgbevf_add_rx_frag(struct ixgbevf_ring *rx_ring, 832static void ixgbevf_add_rx_frag(struct ixgbevf_ring *rx_ring,
792 struct ixgbevf_rx_buffer *rx_buffer, 833 struct ixgbevf_rx_buffer *rx_buffer,
793 u16 size, 834 struct sk_buff *skb,
794 union ixgbe_adv_rx_desc *rx_desc, 835 unsigned int size)
795 struct sk_buff *skb)
796{ 836{
797 struct page *page = rx_buffer->page;
798 unsigned char *va = page_address(page) + rx_buffer->page_offset;
799#if (PAGE_SIZE < 8192) 837#if (PAGE_SIZE < 8192)
800 unsigned int truesize = IXGBEVF_RX_BUFSZ; 838 unsigned int truesize = ixgbevf_rx_pg_size(rx_ring) / 2;
801#else 839#else
802 unsigned int truesize = ALIGN(size, L1_CACHE_BYTES); 840 unsigned int truesize = ring_uses_build_skb(rx_ring) ?
841 SKB_DATA_ALIGN(IXGBEVF_SKB_PAD + size) :
842 SKB_DATA_ALIGN(size);
843#endif
844 skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, rx_buffer->page,
845 rx_buffer->page_offset, size, truesize);
846#if (PAGE_SIZE < 8192)
847 rx_buffer->page_offset ^= truesize;
848#else
849 rx_buffer->page_offset += truesize;
803#endif 850#endif
804 unsigned int pull_len;
805
806 if (unlikely(skb_is_nonlinear(skb)))
807 goto add_tail_frag;
808
809 if (likely(size <= IXGBEVF_RX_HDR_SIZE)) {
810 memcpy(__skb_put(skb, size), va, ALIGN(size, sizeof(long)));
811
812 /* page is not reserved, we can reuse buffer as is */
813 if (likely(!ixgbevf_page_is_reserved(page)))
814 return true;
815
816 /* this page cannot be reused so discard it */
817 return false;
818 }
819
820 /* we need the header to contain the greater of either ETH_HLEN or
821 * 60 bytes if the skb->len is less than 60 for skb_pad.
822 */
823 pull_len = eth_get_headlen(va, IXGBEVF_RX_HDR_SIZE);
824
825 /* align pull length to size of long to optimize memcpy performance */
826 memcpy(__skb_put(skb, pull_len), va, ALIGN(pull_len, sizeof(long)));
827
828 /* update all of the pointers */
829 va += pull_len;
830 size -= pull_len;
831
832add_tail_frag:
833 skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
834 (unsigned long)va & ~PAGE_MASK, size, truesize);
835
836 return ixgbevf_can_reuse_rx_page(rx_buffer, page, truesize);
837} 851}
838 852
839static struct sk_buff *ixgbevf_fetch_rx_buffer(struct ixgbevf_ring *rx_ring, 853static
840 union ixgbe_adv_rx_desc *rx_desc, 854struct sk_buff *ixgbevf_construct_skb(struct ixgbevf_ring *rx_ring,
841 struct sk_buff *skb) 855 struct ixgbevf_rx_buffer *rx_buffer,
856 union ixgbe_adv_rx_desc *rx_desc,
857 unsigned int size)
842{ 858{
843 struct ixgbevf_rx_buffer *rx_buffer; 859 void *va = page_address(rx_buffer->page) + rx_buffer->page_offset;
844 struct page *page; 860#if (PAGE_SIZE < 8192)
845 u16 size = le16_to_cpu(rx_desc->wb.upper.length); 861 unsigned int truesize = ixgbevf_rx_pg_size(rx_ring) / 2;
846 862#else
847 rx_buffer = &rx_ring->rx_buffer_info[rx_ring->next_to_clean]; 863 unsigned int truesize = SKB_DATA_ALIGN(size);
848 page = rx_buffer->page; 864#endif
849 prefetchw(page); 865 unsigned int headlen;
850 866 struct sk_buff *skb;
851 /* we are reusing so sync this buffer for CPU use */
852 dma_sync_single_range_for_cpu(rx_ring->dev,
853 rx_buffer->dma,
854 rx_buffer->page_offset,
855 size,
856 DMA_FROM_DEVICE);
857
858 if (likely(!skb)) {
859 void *page_addr = page_address(page) +
860 rx_buffer->page_offset;
861 867
862 /* prefetch first cache line of first page */ 868 /* prefetch first cache line of first page */
863 prefetch(page_addr); 869 prefetch(va);
864#if L1_CACHE_BYTES < 128 870#if L1_CACHE_BYTES < 128
865 prefetch(page_addr + L1_CACHE_BYTES); 871 prefetch(va + L1_CACHE_BYTES);
866#endif 872#endif
867 873
868 /* allocate a skb to store the frags */ 874 /* allocate a skb to store the frags */
869 skb = netdev_alloc_skb_ip_align(rx_ring->netdev, 875 skb = napi_alloc_skb(&rx_ring->q_vector->napi, IXGBEVF_RX_HDR_SIZE);
870 IXGBEVF_RX_HDR_SIZE); 876 if (unlikely(!skb))
871 if (unlikely(!skb)) { 877 return NULL;
872 rx_ring->rx_stats.alloc_rx_buff_failed++;
873 return NULL;
874 }
875 878
876 /* we will be copying header into skb->data in 879 /* Determine available headroom for copy */
877 * pskb_may_pull so it is in our interest to prefetch 880 headlen = size;
878 * it now to avoid a possible cache miss 881 if (headlen > IXGBEVF_RX_HDR_SIZE)
879 */ 882 headlen = eth_get_headlen(va, IXGBEVF_RX_HDR_SIZE);
880 prefetchw(skb->data);
881 }
882 883
883 /* pull page into skb */ 884 /* align pull length to size of long to optimize memcpy performance */
884 if (ixgbevf_add_rx_frag(rx_ring, rx_buffer, size, rx_desc, skb)) { 885 memcpy(__skb_put(skb, headlen), va, ALIGN(headlen, sizeof(long)));
885 /* hand second half of page back to the ring */ 886
886 ixgbevf_reuse_rx_page(rx_ring, rx_buffer); 887 /* update all of the pointers */
888 size -= headlen;
889 if (size) {
890 skb_add_rx_frag(skb, 0, rx_buffer->page,
891 (va + headlen) - page_address(rx_buffer->page),
892 size, truesize);
893#if (PAGE_SIZE < 8192)
894 rx_buffer->page_offset ^= truesize;
895#else
896 rx_buffer->page_offset += truesize;
897#endif
887 } else { 898 } else {
888 /* We are not reusing the buffer so unmap it and free 899 rx_buffer->pagecnt_bias++;
889 * any references we are holding to it
890 */
891 dma_unmap_page_attrs(rx_ring->dev, rx_buffer->dma,
892 PAGE_SIZE, DMA_FROM_DEVICE,
893 IXGBEVF_RX_DMA_ATTR);
894 __page_frag_cache_drain(page, rx_buffer->pagecnt_bias);
895 } 900 }
896 901
897 /* clear contents of buffer_info */
898 rx_buffer->dma = 0;
899 rx_buffer->page = NULL;
900
901 return skb; 902 return skb;
902} 903}
903 904
@@ -909,6 +910,44 @@ static inline void ixgbevf_irq_enable_queues(struct ixgbevf_adapter *adapter,
909 IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, qmask); 910 IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, qmask);
910} 911}
911 912
913static struct sk_buff *ixgbevf_build_skb(struct ixgbevf_ring *rx_ring,
914 struct ixgbevf_rx_buffer *rx_buffer,
915 union ixgbe_adv_rx_desc *rx_desc,
916 unsigned int size)
917{
918 void *va = page_address(rx_buffer->page) + rx_buffer->page_offset;
919#if (PAGE_SIZE < 8192)
920 unsigned int truesize = ixgbevf_rx_pg_size(rx_ring) / 2;
921#else
922 unsigned int truesize = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) +
923 SKB_DATA_ALIGN(IXGBEVF_SKB_PAD + size);
924#endif
925 struct sk_buff *skb;
926
927 /* prefetch first cache line of first page */
928 prefetch(va);
929#if L1_CACHE_BYTES < 128
930 prefetch(va + L1_CACHE_BYTES);
931#endif
932
933 /* build an skb to around the page buffer */
934 skb = build_skb(va - IXGBEVF_SKB_PAD, truesize);
935 if (unlikely(!skb))
936 return NULL;
937
938 /* update pointers within the skb to store the data */
939 skb_reserve(skb, IXGBEVF_SKB_PAD);
940 __skb_put(skb, size);
941
942 /* update buffer offset */
943#if (PAGE_SIZE < 8192)
944 rx_buffer->page_offset ^= truesize;
945#else
946 rx_buffer->page_offset += truesize;
947#endif
948
949 return skb;
950}
912static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, 951static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector,
913 struct ixgbevf_ring *rx_ring, 952 struct ixgbevf_ring *rx_ring,
914 int budget) 953 int budget)
@@ -919,6 +958,8 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector,
919 958
920 while (likely(total_rx_packets < budget)) { 959 while (likely(total_rx_packets < budget)) {
921 union ixgbe_adv_rx_desc *rx_desc; 960 union ixgbe_adv_rx_desc *rx_desc;
961 struct ixgbevf_rx_buffer *rx_buffer;
962 unsigned int size;
922 963
923 /* return some buffers to hardware, one at a time is too slow */ 964 /* return some buffers to hardware, one at a time is too slow */
924 if (cleaned_count >= IXGBEVF_RX_BUFFER_WRITE) { 965 if (cleaned_count >= IXGBEVF_RX_BUFFER_WRITE) {
@@ -927,8 +968,8 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector,
927 } 968 }
928 969
929 rx_desc = IXGBEVF_RX_DESC(rx_ring, rx_ring->next_to_clean); 970 rx_desc = IXGBEVF_RX_DESC(rx_ring, rx_ring->next_to_clean);
930 971 size = le16_to_cpu(rx_desc->wb.upper.length);
931 if (!rx_desc->wb.upper.length) 972 if (!size)
932 break; 973 break;
933 974
934 /* This memory barrier is needed to keep us from reading 975 /* This memory barrier is needed to keep us from reading
@@ -937,15 +978,26 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector,
937 */ 978 */
938 rmb(); 979 rmb();
939 980
981 rx_buffer = ixgbevf_get_rx_buffer(rx_ring, size);
982
940 /* retrieve a buffer from the ring */ 983 /* retrieve a buffer from the ring */
941 skb = ixgbevf_fetch_rx_buffer(rx_ring, rx_desc, skb); 984 if (skb)
985 ixgbevf_add_rx_frag(rx_ring, rx_buffer, skb, size);
986 else if (ring_uses_build_skb(rx_ring))
987 skb = ixgbevf_build_skb(rx_ring, rx_buffer,
988 rx_desc, size);
989 else
990 skb = ixgbevf_construct_skb(rx_ring, rx_buffer,
991 rx_desc, size);
942 992
943 /* exit if we failed to retrieve a buffer */ 993 /* exit if we failed to retrieve a buffer */
944 if (!skb) { 994 if (!skb) {
945 rx_ring->rx_stats.alloc_rx_buff_failed++; 995 rx_ring->rx_stats.alloc_rx_buff_failed++;
996 rx_buffer->pagecnt_bias++;
946 break; 997 break;
947 } 998 }
948 999
1000 ixgbevf_put_rx_buffer(rx_ring, rx_buffer);
949 cleaned_count++; 1001 cleaned_count++;
950 1002
951 /* fetch next buffer in frame if non-eop */ 1003 /* fetch next buffer in frame if non-eop */
@@ -1260,85 +1312,6 @@ static irqreturn_t ixgbevf_msix_clean_rings(int irq, void *data)
1260 return IRQ_HANDLED; 1312 return IRQ_HANDLED;
1261} 1313}
1262 1314
1263static inline void map_vector_to_rxq(struct ixgbevf_adapter *a, int v_idx,
1264 int r_idx)
1265{
1266 struct ixgbevf_q_vector *q_vector = a->q_vector[v_idx];
1267
1268 a->rx_ring[r_idx]->next = q_vector->rx.ring;
1269 q_vector->rx.ring = a->rx_ring[r_idx];
1270 q_vector->rx.count++;
1271}
1272
1273static inline void map_vector_to_txq(struct ixgbevf_adapter *a, int v_idx,
1274 int t_idx)
1275{
1276 struct ixgbevf_q_vector *q_vector = a->q_vector[v_idx];
1277
1278 a->tx_ring[t_idx]->next = q_vector->tx.ring;
1279 q_vector->tx.ring = a->tx_ring[t_idx];
1280 q_vector->tx.count++;
1281}
1282
1283/**
1284 * ixgbevf_map_rings_to_vectors - Maps descriptor rings to vectors
1285 * @adapter: board private structure to initialize
1286 *
1287 * This function maps descriptor rings to the queue-specific vectors
1288 * we were allotted through the MSI-X enabling code. Ideally, we'd have
1289 * one vector per ring/queue, but on a constrained vector budget, we
1290 * group the rings as "efficiently" as possible. You would add new
1291 * mapping configurations in here.
1292 **/
1293static int ixgbevf_map_rings_to_vectors(struct ixgbevf_adapter *adapter)
1294{
1295 int q_vectors;
1296 int v_start = 0;
1297 int rxr_idx = 0, txr_idx = 0;
1298 int rxr_remaining = adapter->num_rx_queues;
1299 int txr_remaining = adapter->num_tx_queues;
1300 int i, j;
1301 int rqpv, tqpv;
1302
1303 q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
1304
1305 /* The ideal configuration...
1306 * We have enough vectors to map one per queue.
1307 */
1308 if (q_vectors == adapter->num_rx_queues + adapter->num_tx_queues) {
1309 for (; rxr_idx < rxr_remaining; v_start++, rxr_idx++)
1310 map_vector_to_rxq(adapter, v_start, rxr_idx);
1311
1312 for (; txr_idx < txr_remaining; v_start++, txr_idx++)
1313 map_vector_to_txq(adapter, v_start, txr_idx);
1314 return 0;
1315 }
1316
1317 /* If we don't have enough vectors for a 1-to-1
1318 * mapping, we'll have to group them so there are
1319 * multiple queues per vector.
1320 */
1321 /* Re-adjusting *qpv takes care of the remainder. */
1322 for (i = v_start; i < q_vectors; i++) {
1323 rqpv = DIV_ROUND_UP(rxr_remaining, q_vectors - i);
1324 for (j = 0; j < rqpv; j++) {
1325 map_vector_to_rxq(adapter, i, rxr_idx);
1326 rxr_idx++;
1327 rxr_remaining--;
1328 }
1329 }
1330 for (i = v_start; i < q_vectors; i++) {
1331 tqpv = DIV_ROUND_UP(txr_remaining, q_vectors - i);
1332 for (j = 0; j < tqpv; j++) {
1333 map_vector_to_txq(adapter, i, txr_idx);
1334 txr_idx++;
1335 txr_remaining--;
1336 }
1337 }
1338
1339 return 0;
1340}
1341
1342/** 1315/**
1343 * ixgbevf_request_msix_irqs - Initialize MSI-X interrupts 1316 * ixgbevf_request_msix_irqs - Initialize MSI-X interrupts
1344 * @adapter: board private structure 1317 * @adapter: board private structure
@@ -1411,20 +1384,6 @@ free_queue_irqs:
1411 return err; 1384 return err;
1412} 1385}
1413 1386
1414static inline void ixgbevf_reset_q_vectors(struct ixgbevf_adapter *adapter)
1415{
1416 int i, q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
1417
1418 for (i = 0; i < q_vectors; i++) {
1419 struct ixgbevf_q_vector *q_vector = adapter->q_vector[i];
1420
1421 q_vector->rx.ring = NULL;
1422 q_vector->tx.ring = NULL;
1423 q_vector->rx.count = 0;
1424 q_vector->tx.count = 0;
1425 }
1426}
1427
1428/** 1387/**
1429 * ixgbevf_request_irq - initialize interrupts 1388 * ixgbevf_request_irq - initialize interrupts
1430 * @adapter: board private structure 1389 * @adapter: board private structure
@@ -1464,8 +1423,6 @@ static void ixgbevf_free_irq(struct ixgbevf_adapter *adapter)
1464 free_irq(adapter->msix_entries[i].vector, 1423 free_irq(adapter->msix_entries[i].vector,
1465 adapter->q_vector[i]); 1424 adapter->q_vector[i]);
1466 } 1425 }
1467
1468 ixgbevf_reset_q_vectors(adapter);
1469} 1426}
1470 1427
1471/** 1428/**
@@ -1587,7 +1544,8 @@ static void ixgbevf_configure_tx(struct ixgbevf_adapter *adapter)
1587 1544
1588#define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT 2 1545#define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT 2
1589 1546
1590static void ixgbevf_configure_srrctl(struct ixgbevf_adapter *adapter, int index) 1547static void ixgbevf_configure_srrctl(struct ixgbevf_adapter *adapter,
1548 struct ixgbevf_ring *ring, int index)
1591{ 1549{
1592 struct ixgbe_hw *hw = &adapter->hw; 1550 struct ixgbe_hw *hw = &adapter->hw;
1593 u32 srrctl; 1551 u32 srrctl;
@@ -1595,7 +1553,10 @@ static void ixgbevf_configure_srrctl(struct ixgbevf_adapter *adapter, int index)
1595 srrctl = IXGBE_SRRCTL_DROP_EN; 1553 srrctl = IXGBE_SRRCTL_DROP_EN;
1596 1554
1597 srrctl |= IXGBEVF_RX_HDR_SIZE << IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT; 1555 srrctl |= IXGBEVF_RX_HDR_SIZE << IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT;
1598 srrctl |= IXGBEVF_RX_BUFSZ >> IXGBE_SRRCTL_BSIZEPKT_SHIFT; 1556 if (ring_uses_large_buffer(ring))
1557 srrctl |= IXGBEVF_RXBUFFER_3072 >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
1558 else
1559 srrctl |= IXGBEVF_RXBUFFER_2048 >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
1599 srrctl |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF; 1560 srrctl |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF;
1600 1561
1601 IXGBE_WRITE_REG(hw, IXGBE_VFSRRCTL(index), srrctl); 1562 IXGBE_WRITE_REG(hw, IXGBE_VFSRRCTL(index), srrctl);
@@ -1767,10 +1728,21 @@ static void ixgbevf_configure_rx_ring(struct ixgbevf_adapter *adapter,
1767 ring->next_to_use = 0; 1728 ring->next_to_use = 0;
1768 ring->next_to_alloc = 0; 1729 ring->next_to_alloc = 0;
1769 1730
1770 ixgbevf_configure_srrctl(adapter, reg_idx); 1731 ixgbevf_configure_srrctl(adapter, ring, reg_idx);
1771 1732
1772 /* allow any size packet since we can handle overflow */ 1733 /* RXDCTL.RLPML does not work on 82599 */
1773 rxdctl &= ~IXGBE_RXDCTL_RLPML_EN; 1734 if (adapter->hw.mac.type != ixgbe_mac_82599_vf) {
1735 rxdctl &= ~(IXGBE_RXDCTL_RLPMLMASK |
1736 IXGBE_RXDCTL_RLPML_EN);
1737
1738#if (PAGE_SIZE < 8192)
1739 /* Limit the maximum frame size so we don't overrun the skb */
1740 if (ring_uses_build_skb(ring) &&
1741 !ring_uses_large_buffer(ring))
1742 rxdctl |= IXGBEVF_MAX_FRAME_BUILD_SKB |
1743 IXGBE_RXDCTL_RLPML_EN;
1744#endif
1745 }
1774 1746
1775 rxdctl |= IXGBE_RXDCTL_ENABLE | IXGBE_RXDCTL_VME; 1747 rxdctl |= IXGBE_RXDCTL_ENABLE | IXGBE_RXDCTL_VME;
1776 IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(reg_idx), rxdctl); 1748 IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(reg_idx), rxdctl);
@@ -1779,6 +1751,29 @@ static void ixgbevf_configure_rx_ring(struct ixgbevf_adapter *adapter,
1779 ixgbevf_alloc_rx_buffers(ring, ixgbevf_desc_unused(ring)); 1751 ixgbevf_alloc_rx_buffers(ring, ixgbevf_desc_unused(ring));
1780} 1752}
1781 1753
1754static void ixgbevf_set_rx_buffer_len(struct ixgbevf_adapter *adapter,
1755 struct ixgbevf_ring *rx_ring)
1756{
1757 struct net_device *netdev = adapter->netdev;
1758 unsigned int max_frame = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
1759
1760 /* set build_skb and buffer size flags */
1761 clear_ring_build_skb_enabled(rx_ring);
1762 clear_ring_uses_large_buffer(rx_ring);
1763
1764 if (adapter->flags & IXGBEVF_FLAGS_LEGACY_RX)
1765 return;
1766
1767 set_ring_build_skb_enabled(rx_ring);
1768
1769 if (PAGE_SIZE < 8192) {
1770 if (max_frame <= IXGBEVF_MAX_FRAME_BUILD_SKB)
1771 return;
1772
1773 set_ring_uses_large_buffer(rx_ring);
1774 }
1775}
1776
1782/** 1777/**
1783 * ixgbevf_configure_rx - Configure 82599 VF Receive Unit after Reset 1778 * ixgbevf_configure_rx - Configure 82599 VF Receive Unit after Reset
1784 * @adapter: board private structure 1779 * @adapter: board private structure
@@ -1806,8 +1801,12 @@ static void ixgbevf_configure_rx(struct ixgbevf_adapter *adapter)
1806 /* Setup the HW Rx Head and Tail Descriptor Pointers and 1801 /* Setup the HW Rx Head and Tail Descriptor Pointers and
1807 * the Base and Length of the Rx Descriptor Ring 1802 * the Base and Length of the Rx Descriptor Ring
1808 */ 1803 */
1809 for (i = 0; i < adapter->num_rx_queues; i++) 1804 for (i = 0; i < adapter->num_rx_queues; i++) {
1810 ixgbevf_configure_rx_ring(adapter, adapter->rx_ring[i]); 1805 struct ixgbevf_ring *rx_ring = adapter->rx_ring[i];
1806
1807 ixgbevf_set_rx_buffer_len(adapter, rx_ring);
1808 ixgbevf_configure_rx_ring(adapter, rx_ring);
1809 }
1811} 1810}
1812 1811
1813static int ixgbevf_vlan_rx_add_vid(struct net_device *netdev, 1812static int ixgbevf_vlan_rx_add_vid(struct net_device *netdev,
@@ -2136,13 +2135,13 @@ static void ixgbevf_clean_rx_ring(struct ixgbevf_ring *rx_ring)
2136 dma_sync_single_range_for_cpu(rx_ring->dev, 2135 dma_sync_single_range_for_cpu(rx_ring->dev,
2137 rx_buffer->dma, 2136 rx_buffer->dma,
2138 rx_buffer->page_offset, 2137 rx_buffer->page_offset,
2139 IXGBEVF_RX_BUFSZ, 2138 ixgbevf_rx_bufsz(rx_ring),
2140 DMA_FROM_DEVICE); 2139 DMA_FROM_DEVICE);
2141 2140
2142 /* free resources associated with mapping */ 2141 /* free resources associated with mapping */
2143 dma_unmap_page_attrs(rx_ring->dev, 2142 dma_unmap_page_attrs(rx_ring->dev,
2144 rx_buffer->dma, 2143 rx_buffer->dma,
2145 PAGE_SIZE, 2144 ixgbevf_rx_pg_size(rx_ring),
2146 DMA_FROM_DEVICE, 2145 DMA_FROM_DEVICE,
2147 IXGBEVF_RX_DMA_ATTR); 2146 IXGBEVF_RX_DMA_ATTR);
2148 2147
@@ -2405,105 +2404,171 @@ static void ixgbevf_set_num_queues(struct ixgbevf_adapter *adapter)
2405} 2404}
2406 2405
2407/** 2406/**
2408 * ixgbevf_alloc_queues - Allocate memory for all rings 2407 * ixgbevf_set_interrupt_capability - set MSI-X or FAIL if not supported
2408 * @adapter: board private structure to initialize
2409 *
2410 * Attempt to configure the interrupts using the best available
2411 * capabilities of the hardware and the kernel.
2412 **/
2413static int ixgbevf_set_interrupt_capability(struct ixgbevf_adapter *adapter)
2414{
2415 int vector, v_budget;
2416
2417 /* It's easy to be greedy for MSI-X vectors, but it really
2418 * doesn't do us much good if we have a lot more vectors
2419 * than CPU's. So let's be conservative and only ask for
2420 * (roughly) the same number of vectors as there are CPU's.
2421 * The default is to use pairs of vectors.
2422 */
2423 v_budget = max(adapter->num_rx_queues, adapter->num_tx_queues);
2424 v_budget = min_t(int, v_budget, num_online_cpus());
2425 v_budget += NON_Q_VECTORS;
2426
2427 adapter->msix_entries = kcalloc(v_budget,
2428 sizeof(struct msix_entry), GFP_KERNEL);
2429 if (!adapter->msix_entries)
2430 return -ENOMEM;
2431
2432 for (vector = 0; vector < v_budget; vector++)
2433 adapter->msix_entries[vector].entry = vector;
2434
2435 /* A failure in MSI-X entry allocation isn't fatal, but the VF driver
2436 * does not support any other modes, so we will simply fail here. Note
2437 * that we clean up the msix_entries pointer else-where.
2438 */
2439 return ixgbevf_acquire_msix_vectors(adapter, v_budget);
2440}
2441
2442static void ixgbevf_add_ring(struct ixgbevf_ring *ring,
2443 struct ixgbevf_ring_container *head)
2444{
2445 ring->next = head->ring;
2446 head->ring = ring;
2447 head->count++;
2448}
2449
2450/**
2451 * ixgbevf_alloc_q_vector - Allocate memory for a single interrupt vector
2409 * @adapter: board private structure to initialize 2452 * @adapter: board private structure to initialize
2453 * @v_idx: index of vector in adapter struct
2454 * @txr_count: number of Tx rings for q vector
2455 * @txr_idx: index of first Tx ring to assign
2456 * @rxr_count: number of Rx rings for q vector
2457 * @rxr_idx: index of first Rx ring to assign
2410 * 2458 *
2411 * We allocate one ring per queue at run-time since we don't know the 2459 * We allocate one q_vector. If allocation fails we return -ENOMEM.
2412 * number of queues at compile-time. The polling_netdev array is
2413 * intended for Multiqueue, but should work fine with a single queue.
2414 **/ 2460 **/
2415static int ixgbevf_alloc_queues(struct ixgbevf_adapter *adapter) 2461static int ixgbevf_alloc_q_vector(struct ixgbevf_adapter *adapter, int v_idx,
2462 int txr_count, int txr_idx,
2463 int rxr_count, int rxr_idx)
2416{ 2464{
2465 struct ixgbevf_q_vector *q_vector;
2417 struct ixgbevf_ring *ring; 2466 struct ixgbevf_ring *ring;
2418 int rx = 0, tx = 0; 2467 int ring_count, size;
2419 2468
2420 for (; tx < adapter->num_tx_queues; tx++) { 2469 ring_count = txr_count + rxr_count;
2421 ring = kzalloc(sizeof(*ring), GFP_KERNEL); 2470 size = sizeof(*q_vector) + (sizeof(*ring) * ring_count);
2422 if (!ring)
2423 goto err_allocation;
2424 2471
2472 /* allocate q_vector and rings */
2473 q_vector = kzalloc(size, GFP_KERNEL);
2474 if (!q_vector)
2475 return -ENOMEM;
2476
2477 /* initialize NAPI */
2478 netif_napi_add(adapter->netdev, &q_vector->napi, ixgbevf_poll, 64);
2479
2480 /* tie q_vector and adapter together */
2481 adapter->q_vector[v_idx] = q_vector;
2482 q_vector->adapter = adapter;
2483 q_vector->v_idx = v_idx;
2484
2485 /* initialize pointer to rings */
2486 ring = q_vector->ring;
2487
2488 while (txr_count) {
2489 /* assign generic ring traits */
2425 ring->dev = &adapter->pdev->dev; 2490 ring->dev = &adapter->pdev->dev;
2426 ring->netdev = adapter->netdev; 2491 ring->netdev = adapter->netdev;
2492
2493 /* configure backlink on ring */
2494 ring->q_vector = q_vector;
2495
2496 /* update q_vector Tx values */
2497 ixgbevf_add_ring(ring, &q_vector->tx);
2498
2499 /* apply Tx specific ring traits */
2427 ring->count = adapter->tx_ring_count; 2500 ring->count = adapter->tx_ring_count;
2428 ring->queue_index = tx; 2501 ring->queue_index = txr_idx;
2429 ring->reg_idx = tx; 2502 ring->reg_idx = txr_idx;
2430 2503
2431 adapter->tx_ring[tx] = ring; 2504 /* assign ring to adapter */
2432 } 2505 adapter->tx_ring[txr_idx] = ring;
2433 2506
2434 for (; rx < adapter->num_rx_queues; rx++) { 2507 /* update count and index */
2435 ring = kzalloc(sizeof(*ring), GFP_KERNEL); 2508 txr_count--;
2436 if (!ring) 2509 txr_idx++;
2437 goto err_allocation;
2438 2510
2511 /* push pointer to next ring */
2512 ring++;
2513 }
2514
2515 while (rxr_count) {
2516 /* assign generic ring traits */
2439 ring->dev = &adapter->pdev->dev; 2517 ring->dev = &adapter->pdev->dev;
2440 ring->netdev = adapter->netdev; 2518 ring->netdev = adapter->netdev;
2441 2519
2520 /* configure backlink on ring */
2521 ring->q_vector = q_vector;
2522
2523 /* update q_vector Rx values */
2524 ixgbevf_add_ring(ring, &q_vector->rx);
2525
2526 /* apply Rx specific ring traits */
2442 ring->count = adapter->rx_ring_count; 2527 ring->count = adapter->rx_ring_count;
2443 ring->queue_index = rx; 2528 ring->queue_index = rxr_idx;
2444 ring->reg_idx = rx; 2529 ring->reg_idx = rxr_idx;
2445 2530
2446 adapter->rx_ring[rx] = ring; 2531 /* assign ring to adapter */
2447 } 2532 adapter->rx_ring[rxr_idx] = ring;
2448 2533
2449 return 0; 2534 /* update count and index */
2535 rxr_count--;
2536 rxr_idx++;
2450 2537
2451err_allocation: 2538 /* push pointer to next ring */
2452 while (tx) { 2539 ring++;
2453 kfree(adapter->tx_ring[--tx]);
2454 adapter->tx_ring[tx] = NULL;
2455 } 2540 }
2456 2541
2457 while (rx) { 2542 return 0;
2458 kfree(adapter->rx_ring[--rx]);
2459 adapter->rx_ring[rx] = NULL;
2460 }
2461 return -ENOMEM;
2462} 2543}
2463 2544
2464/** 2545/**
2465 * ixgbevf_set_interrupt_capability - set MSI-X or FAIL if not supported 2546 * ixgbevf_free_q_vector - Free memory allocated for specific interrupt vector
2466 * @adapter: board private structure to initialize 2547 * @adapter: board private structure to initialize
2548 * @v_idx: index of vector in adapter struct
2467 * 2549 *
2468 * Attempt to configure the interrupts using the best available 2550 * This function frees the memory allocated to the q_vector. In addition if
2469 * capabilities of the hardware and the kernel. 2551 * NAPI is enabled it will delete any references to the NAPI struct prior
2552 * to freeing the q_vector.
2470 **/ 2553 **/
2471static int ixgbevf_set_interrupt_capability(struct ixgbevf_adapter *adapter) 2554static void ixgbevf_free_q_vector(struct ixgbevf_adapter *adapter, int v_idx)
2472{ 2555{
2473 struct net_device *netdev = adapter->netdev; 2556 struct ixgbevf_q_vector *q_vector = adapter->q_vector[v_idx];
2474 int err; 2557 struct ixgbevf_ring *ring;
2475 int vector, v_budget;
2476
2477 /* It's easy to be greedy for MSI-X vectors, but it really
2478 * doesn't do us much good if we have a lot more vectors
2479 * than CPU's. So let's be conservative and only ask for
2480 * (roughly) the same number of vectors as there are CPU's.
2481 * The default is to use pairs of vectors.
2482 */
2483 v_budget = max(adapter->num_rx_queues, adapter->num_tx_queues);
2484 v_budget = min_t(int, v_budget, num_online_cpus());
2485 v_budget += NON_Q_VECTORS;
2486 2558
2487 /* A failure in MSI-X entry allocation isn't fatal, but it does 2559 ixgbevf_for_each_ring(ring, q_vector->tx)
2488 * mean we disable MSI-X capabilities of the adapter. 2560 adapter->tx_ring[ring->queue_index] = NULL;
2489 */
2490 adapter->msix_entries = kcalloc(v_budget,
2491 sizeof(struct msix_entry), GFP_KERNEL);
2492 if (!adapter->msix_entries)
2493 return -ENOMEM;
2494 2561
2495 for (vector = 0; vector < v_budget; vector++) 2562 ixgbevf_for_each_ring(ring, q_vector->rx)
2496 adapter->msix_entries[vector].entry = vector; 2563 adapter->rx_ring[ring->queue_index] = NULL;
2497 2564
2498 err = ixgbevf_acquire_msix_vectors(adapter, v_budget); 2565 adapter->q_vector[v_idx] = NULL;
2499 if (err) 2566 netif_napi_del(&q_vector->napi);
2500 return err;
2501 2567
2502 err = netif_set_real_num_tx_queues(netdev, adapter->num_tx_queues); 2568 /* ixgbevf_get_stats() might access the rings on this vector,
2503 if (err) 2569 * we must wait a grace period before freeing it.
2504 return err; 2570 */
2505 2571 kfree_rcu(q_vector, rcu);
2506 return netif_set_real_num_rx_queues(netdev, adapter->num_rx_queues);
2507} 2572}
2508 2573
2509/** 2574/**
@@ -2515,35 +2580,53 @@ static int ixgbevf_set_interrupt_capability(struct ixgbevf_adapter *adapter)
2515 **/ 2580 **/
2516static int ixgbevf_alloc_q_vectors(struct ixgbevf_adapter *adapter) 2581static int ixgbevf_alloc_q_vectors(struct ixgbevf_adapter *adapter)
2517{ 2582{
2518 int q_idx, num_q_vectors; 2583 int q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
2519 struct ixgbevf_q_vector *q_vector; 2584 int rxr_remaining = adapter->num_rx_queues;
2585 int txr_remaining = adapter->num_tx_queues;
2586 int rxr_idx = 0, txr_idx = 0, v_idx = 0;
2587 int err;
2588
2589 if (q_vectors >= (rxr_remaining + txr_remaining)) {
2590 for (; rxr_remaining; v_idx++, q_vectors--) {
2591 int rqpv = DIV_ROUND_UP(rxr_remaining, q_vectors);
2592
2593 err = ixgbevf_alloc_q_vector(adapter, v_idx,
2594 0, 0, rqpv, rxr_idx);
2595 if (err)
2596 goto err_out;
2597
2598 /* update counts and index */
2599 rxr_remaining -= rqpv;
2600 rxr_idx += rqpv;
2601 }
2602 }
2603
2604 for (; q_vectors; v_idx++, q_vectors--) {
2605 int rqpv = DIV_ROUND_UP(rxr_remaining, q_vectors);
2606 int tqpv = DIV_ROUND_UP(txr_remaining, q_vectors);
2520 2607
2521 num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; 2608 err = ixgbevf_alloc_q_vector(adapter, v_idx,
2609 tqpv, txr_idx,
2610 rqpv, rxr_idx);
2522 2611
2523 for (q_idx = 0; q_idx < num_q_vectors; q_idx++) { 2612 if (err)
2524 q_vector = kzalloc(sizeof(struct ixgbevf_q_vector), GFP_KERNEL);
2525 if (!q_vector)
2526 goto err_out; 2613 goto err_out;
2527 q_vector->adapter = adapter; 2614
2528 q_vector->v_idx = q_idx; 2615 /* update counts and index */
2529 netif_napi_add(adapter->netdev, &q_vector->napi, 2616 rxr_remaining -= rqpv;
2530 ixgbevf_poll, 64); 2617 rxr_idx += rqpv;
2531 adapter->q_vector[q_idx] = q_vector; 2618 txr_remaining -= tqpv;
2619 txr_idx += tqpv;
2532 } 2620 }
2533 2621
2534 return 0; 2622 return 0;
2535 2623
2536err_out: 2624err_out:
2537 while (q_idx) { 2625 while (v_idx) {
2538 q_idx--; 2626 v_idx--;
2539 q_vector = adapter->q_vector[q_idx]; 2627 ixgbevf_free_q_vector(adapter, v_idx);
2540#ifdef CONFIG_NET_RX_BUSY_POLL
2541 napi_hash_del(&q_vector->napi);
2542#endif
2543 netif_napi_del(&q_vector->napi);
2544 kfree(q_vector);
2545 adapter->q_vector[q_idx] = NULL;
2546 } 2628 }
2629
2547 return -ENOMEM; 2630 return -ENOMEM;
2548} 2631}
2549 2632
@@ -2557,17 +2640,11 @@ err_out:
2557 **/ 2640 **/
2558static void ixgbevf_free_q_vectors(struct ixgbevf_adapter *adapter) 2641static void ixgbevf_free_q_vectors(struct ixgbevf_adapter *adapter)
2559{ 2642{
2560 int q_idx, num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; 2643 int q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
2561
2562 for (q_idx = 0; q_idx < num_q_vectors; q_idx++) {
2563 struct ixgbevf_q_vector *q_vector = adapter->q_vector[q_idx];
2564 2644
2565 adapter->q_vector[q_idx] = NULL; 2645 while (q_vectors) {
2566#ifdef CONFIG_NET_RX_BUSY_POLL 2646 q_vectors--;
2567 napi_hash_del(&q_vector->napi); 2647 ixgbevf_free_q_vector(adapter, q_vectors);
2568#endif
2569 netif_napi_del(&q_vector->napi);
2570 kfree(q_vector);
2571 } 2648 }
2572} 2649}
2573 2650
@@ -2611,12 +2688,6 @@ static int ixgbevf_init_interrupt_scheme(struct ixgbevf_adapter *adapter)
2611 goto err_alloc_q_vectors; 2688 goto err_alloc_q_vectors;
2612 } 2689 }
2613 2690
2614 err = ixgbevf_alloc_queues(adapter);
2615 if (err) {
2616 pr_err("Unable to allocate memory for queues\n");
2617 goto err_alloc_queues;
2618 }
2619
2620 hw_dbg(&adapter->hw, "Multiqueue %s: Rx Queue count = %u, Tx Queue count = %u\n", 2691 hw_dbg(&adapter->hw, "Multiqueue %s: Rx Queue count = %u, Tx Queue count = %u\n",
2621 (adapter->num_rx_queues > 1) ? "Enabled" : 2692 (adapter->num_rx_queues > 1) ? "Enabled" :
2622 "Disabled", adapter->num_rx_queues, adapter->num_tx_queues); 2693 "Disabled", adapter->num_rx_queues, adapter->num_tx_queues);
@@ -2624,8 +2695,6 @@ static int ixgbevf_init_interrupt_scheme(struct ixgbevf_adapter *adapter)
2624 set_bit(__IXGBEVF_DOWN, &adapter->state); 2695 set_bit(__IXGBEVF_DOWN, &adapter->state);
2625 2696
2626 return 0; 2697 return 0;
2627err_alloc_queues:
2628 ixgbevf_free_q_vectors(adapter);
2629err_alloc_q_vectors: 2698err_alloc_q_vectors:
2630 ixgbevf_reset_interrupt_capability(adapter); 2699 ixgbevf_reset_interrupt_capability(adapter);
2631err_set_interrupt: 2700err_set_interrupt:
@@ -2641,17 +2710,6 @@ err_set_interrupt:
2641 **/ 2710 **/
2642static void ixgbevf_clear_interrupt_scheme(struct ixgbevf_adapter *adapter) 2711static void ixgbevf_clear_interrupt_scheme(struct ixgbevf_adapter *adapter)
2643{ 2712{
2644 int i;
2645
2646 for (i = 0; i < adapter->num_tx_queues; i++) {
2647 kfree(adapter->tx_ring[i]);
2648 adapter->tx_ring[i] = NULL;
2649 }
2650 for (i = 0; i < adapter->num_rx_queues; i++) {
2651 kfree(adapter->rx_ring[i]);
2652 adapter->rx_ring[i] = NULL;
2653 }
2654
2655 adapter->num_tx_queues = 0; 2713 adapter->num_tx_queues = 0;
2656 adapter->num_rx_queues = 0; 2714 adapter->num_rx_queues = 0;
2657 2715
@@ -3088,9 +3146,14 @@ static int ixgbevf_setup_all_tx_resources(struct ixgbevf_adapter *adapter)
3088 if (!err) 3146 if (!err)
3089 continue; 3147 continue;
3090 hw_dbg(&adapter->hw, "Allocation for Tx Queue %u failed\n", i); 3148 hw_dbg(&adapter->hw, "Allocation for Tx Queue %u failed\n", i);
3091 break; 3149 goto err_setup_tx;
3092 } 3150 }
3093 3151
3152 return 0;
3153err_setup_tx:
3154 /* rewind the index freeing the rings as we go */
3155 while (i--)
3156 ixgbevf_free_tx_resources(adapter->tx_ring[i]);
3094 return err; 3157 return err;
3095} 3158}
3096 3159
@@ -3148,8 +3211,14 @@ static int ixgbevf_setup_all_rx_resources(struct ixgbevf_adapter *adapter)
3148 if (!err) 3211 if (!err)
3149 continue; 3212 continue;
3150 hw_dbg(&adapter->hw, "Allocation for Rx Queue %u failed\n", i); 3213 hw_dbg(&adapter->hw, "Allocation for Rx Queue %u failed\n", i);
3151 break; 3214 goto err_setup_rx;
3152 } 3215 }
3216
3217 return 0;
3218err_setup_rx:
3219 /* rewind the index freeing the rings as we go */
3220 while (i--)
3221 ixgbevf_free_rx_resources(adapter->rx_ring[i]);
3153 return err; 3222 return err;
3154} 3223}
3155 3224
@@ -3244,28 +3313,31 @@ int ixgbevf_open(struct net_device *netdev)
3244 3313
3245 ixgbevf_configure(adapter); 3314 ixgbevf_configure(adapter);
3246 3315
3247 /* Map the Tx/Rx rings to the vectors we were allotted.
3248 * if request_irq will be called in this function map_rings
3249 * must be called *before* up_complete
3250 */
3251 ixgbevf_map_rings_to_vectors(adapter);
3252
3253 err = ixgbevf_request_irq(adapter); 3316 err = ixgbevf_request_irq(adapter);
3254 if (err) 3317 if (err)
3255 goto err_req_irq; 3318 goto err_req_irq;
3256 3319
3320 /* Notify the stack of the actual queue counts. */
3321 err = netif_set_real_num_tx_queues(netdev, adapter->num_tx_queues);
3322 if (err)
3323 goto err_set_queues;
3324
3325 err = netif_set_real_num_rx_queues(netdev, adapter->num_rx_queues);
3326 if (err)
3327 goto err_set_queues;
3328
3257 ixgbevf_up_complete(adapter); 3329 ixgbevf_up_complete(adapter);
3258 3330
3259 return 0; 3331 return 0;
3260 3332
3333err_set_queues:
3334 ixgbevf_free_irq(adapter);
3261err_req_irq: 3335err_req_irq:
3262 ixgbevf_down(adapter);
3263err_setup_rx:
3264 ixgbevf_free_all_rx_resources(adapter); 3336 ixgbevf_free_all_rx_resources(adapter);
3265err_setup_tx: 3337err_setup_rx:
3266 ixgbevf_free_all_tx_resources(adapter); 3338 ixgbevf_free_all_tx_resources(adapter);
3339err_setup_tx:
3267 ixgbevf_reset(adapter); 3340 ixgbevf_reset(adapter);
3268
3269err_setup_reset: 3341err_setup_reset:
3270 3342
3271 return err; 3343 return err;
@@ -3707,11 +3779,10 @@ static int ixgbevf_maybe_stop_tx(struct ixgbevf_ring *tx_ring, int size)
3707 return __ixgbevf_maybe_stop_tx(tx_ring, size); 3779 return __ixgbevf_maybe_stop_tx(tx_ring, size);
3708} 3780}
3709 3781
3710static int ixgbevf_xmit_frame(struct sk_buff *skb, struct net_device *netdev) 3782static int ixgbevf_xmit_frame_ring(struct sk_buff *skb,
3783 struct ixgbevf_ring *tx_ring)
3711{ 3784{
3712 struct ixgbevf_adapter *adapter = netdev_priv(netdev);
3713 struct ixgbevf_tx_buffer *first; 3785 struct ixgbevf_tx_buffer *first;
3714 struct ixgbevf_ring *tx_ring;
3715 int tso; 3786 int tso;
3716 u32 tx_flags = 0; 3787 u32 tx_flags = 0;
3717 u16 count = TXD_USE_COUNT(skb_headlen(skb)); 3788 u16 count = TXD_USE_COUNT(skb_headlen(skb));
@@ -3726,8 +3797,6 @@ static int ixgbevf_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
3726 return NETDEV_TX_OK; 3797 return NETDEV_TX_OK;
3727 } 3798 }
3728 3799
3729 tx_ring = adapter->tx_ring[skb->queue_mapping];
3730
3731 /* need: 1 descriptor per page * PAGE_SIZE/IXGBE_MAX_DATA_PER_TXD, 3800 /* need: 1 descriptor per page * PAGE_SIZE/IXGBE_MAX_DATA_PER_TXD,
3732 * + 1 desc for skb_headlen/IXGBE_MAX_DATA_PER_TXD, 3801 * + 1 desc for skb_headlen/IXGBE_MAX_DATA_PER_TXD,
3733 * + 2 desc gap to keep tail from touching head, 3802 * + 2 desc gap to keep tail from touching head,
@@ -3780,6 +3849,29 @@ out_drop:
3780 return NETDEV_TX_OK; 3849 return NETDEV_TX_OK;
3781} 3850}
3782 3851
3852static int ixgbevf_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
3853{
3854 struct ixgbevf_adapter *adapter = netdev_priv(netdev);
3855 struct ixgbevf_ring *tx_ring;
3856
3857 if (skb->len <= 0) {
3858 dev_kfree_skb_any(skb);
3859 return NETDEV_TX_OK;
3860 }
3861
3862 /* The minimum packet size for olinfo paylen is 17 so pad the skb
3863 * in order to meet this minimum size requirement.
3864 */
3865 if (skb->len < 17) {
3866 if (skb_padto(skb, 17))
3867 return NETDEV_TX_OK;
3868 skb->len = 17;
3869 }
3870
3871 tx_ring = adapter->tx_ring[skb->queue_mapping];
3872 return ixgbevf_xmit_frame_ring(skb, tx_ring);
3873}
3874
3783/** 3875/**
3784 * ixgbevf_set_mac - Change the Ethernet Address of the NIC 3876 * ixgbevf_set_mac - Change the Ethernet Address of the NIC
3785 * @netdev: network interface device structure 3877 * @netdev: network interface device structure
@@ -3839,6 +3931,9 @@ static int ixgbevf_change_mtu(struct net_device *netdev, int new_mtu)
3839 /* must set new MTU before calling down or up */ 3931 /* must set new MTU before calling down or up */
3840 netdev->mtu = new_mtu; 3932 netdev->mtu = new_mtu;
3841 3933
3934 if (netif_running(netdev))
3935 ixgbevf_reinit_locked(adapter);
3936
3842 return 0; 3937 return 0;
3843} 3938}
3844 3939
@@ -3917,17 +4012,11 @@ static int ixgbevf_resume(struct pci_dev *pdev)
3917 4012
3918 rtnl_lock(); 4013 rtnl_lock();
3919 err = ixgbevf_init_interrupt_scheme(adapter); 4014 err = ixgbevf_init_interrupt_scheme(adapter);
4015 if (!err && netif_running(netdev))
4016 err = ixgbevf_open(netdev);
3920 rtnl_unlock(); 4017 rtnl_unlock();
3921 if (err) { 4018 if (err)
3922 dev_err(&pdev->dev, "Cannot initialize interrupts\n");
3923 return err; 4019 return err;
3924 }
3925
3926 if (netif_running(netdev)) {
3927 err = ixgbevf_open(netdev);
3928 if (err)
3929 return err;
3930 }
3931 4020
3932 netif_device_attach(netdev); 4021 netif_device_attach(netdev);
3933 4022
@@ -3953,6 +4042,7 @@ static void ixgbevf_get_stats(struct net_device *netdev,
3953 4042
3954 stats->multicast = adapter->stats.vfmprc - adapter->stats.base_vfmprc; 4043 stats->multicast = adapter->stats.vfmprc - adapter->stats.base_vfmprc;
3955 4044
4045 rcu_read_lock();
3956 for (i = 0; i < adapter->num_rx_queues; i++) { 4046 for (i = 0; i < adapter->num_rx_queues; i++) {
3957 ring = adapter->rx_ring[i]; 4047 ring = adapter->rx_ring[i];
3958 do { 4048 do {
@@ -3974,6 +4064,7 @@ static void ixgbevf_get_stats(struct net_device *netdev,
3974 stats->tx_bytes += bytes; 4064 stats->tx_bytes += bytes;
3975 stats->tx_packets += packets; 4065 stats->tx_packets += packets;
3976 } 4066 }
4067 rcu_read_unlock();
3977} 4068}
3978 4069
3979#define IXGBEVF_MAX_MAC_HDR_LEN 127 4070#define IXGBEVF_MAX_MAC_HDR_LEN 127
diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c
index 5a1668cdb461..f8bc3d4a39ff 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -44,6 +44,7 @@
44#define MVPP2_RX_ATTR_FIFO_SIZE_REG(port) (0x20 + 4 * (port)) 44#define MVPP2_RX_ATTR_FIFO_SIZE_REG(port) (0x20 + 4 * (port))
45#define MVPP2_RX_MIN_PKT_SIZE_REG 0x60 45#define MVPP2_RX_MIN_PKT_SIZE_REG 0x60
46#define MVPP2_RX_FIFO_INIT_REG 0x64 46#define MVPP2_RX_FIFO_INIT_REG 0x64
47#define MVPP22_TX_FIFO_THRESH_REG(port) (0x8840 + 4 * (port))
47#define MVPP22_TX_FIFO_SIZE_REG(port) (0x8860 + 4 * (port)) 48#define MVPP22_TX_FIFO_SIZE_REG(port) (0x8860 + 4 * (port))
48 49
49/* RX DMA Top Registers */ 50/* RX DMA Top Registers */
@@ -65,6 +66,10 @@
65#define MVPP2_RXQ_PACKET_OFFSET_MASK 0x70000000 66#define MVPP2_RXQ_PACKET_OFFSET_MASK 0x70000000
66#define MVPP2_RXQ_DISABLE_MASK BIT(31) 67#define MVPP2_RXQ_DISABLE_MASK BIT(31)
67 68
69/* Top Registers */
70#define MVPP2_MH_REG(port) (0x5040 + 4 * (port))
71#define MVPP2_DSA_EXTENDED BIT(5)
72
68/* Parser Registers */ 73/* Parser Registers */
69#define MVPP2_PRS_INIT_LOOKUP_REG 0x1000 74#define MVPP2_PRS_INIT_LOOKUP_REG 0x1000
70#define MVPP2_PRS_PORT_LU_MAX 0xf 75#define MVPP2_PRS_PORT_LU_MAX 0xf
@@ -254,6 +259,7 @@
254#define MVPP2_BM_BPPI_READ_PTR_REG(pool) (0x6100 + ((pool) * 4)) 259#define MVPP2_BM_BPPI_READ_PTR_REG(pool) (0x6100 + ((pool) * 4))
255#define MVPP2_BM_BPPI_PTRS_NUM_REG(pool) (0x6140 + ((pool) * 4)) 260#define MVPP2_BM_BPPI_PTRS_NUM_REG(pool) (0x6140 + ((pool) * 4))
256#define MVPP2_BM_BPPI_PTR_NUM_MASK 0x7ff 261#define MVPP2_BM_BPPI_PTR_NUM_MASK 0x7ff
262#define MVPP22_BM_POOL_PTRS_NUM_MASK 0xfff8
257#define MVPP2_BM_BPPI_PREFETCH_FULL_MASK BIT(16) 263#define MVPP2_BM_BPPI_PREFETCH_FULL_MASK BIT(16)
258#define MVPP2_BM_POOL_CTRL_REG(pool) (0x6200 + ((pool) * 4)) 264#define MVPP2_BM_POOL_CTRL_REG(pool) (0x6200 + ((pool) * 4))
259#define MVPP2_BM_START_MASK BIT(0) 265#define MVPP2_BM_START_MASK BIT(0)
@@ -473,6 +479,7 @@
473#define MVPP2_ETH_TYPE_LEN 2 479#define MVPP2_ETH_TYPE_LEN 2
474#define MVPP2_PPPOE_HDR_SIZE 8 480#define MVPP2_PPPOE_HDR_SIZE 8
475#define MVPP2_VLAN_TAG_LEN 4 481#define MVPP2_VLAN_TAG_LEN 4
482#define MVPP2_VLAN_TAG_EDSA_LEN 8
476 483
477/* Lbtd 802.3 type */ 484/* Lbtd 802.3 type */
478#define MVPP2_IP_LBDT_TYPE 0xfffa 485#define MVPP2_IP_LBDT_TYPE 0xfffa
@@ -536,6 +543,11 @@
536/* TX FIFO constants */ 543/* TX FIFO constants */
537#define MVPP22_TX_FIFO_DATA_SIZE_10KB 0xa 544#define MVPP22_TX_FIFO_DATA_SIZE_10KB 0xa
538#define MVPP22_TX_FIFO_DATA_SIZE_3KB 0x3 545#define MVPP22_TX_FIFO_DATA_SIZE_3KB 0x3
546#define MVPP2_TX_FIFO_THRESHOLD_MIN 256
547#define MVPP2_TX_FIFO_THRESHOLD_10KB \
548 (MVPP22_TX_FIFO_DATA_SIZE_10KB * 1024 - MVPP2_TX_FIFO_THRESHOLD_MIN)
549#define MVPP2_TX_FIFO_THRESHOLD_3KB \
550 (MVPP22_TX_FIFO_DATA_SIZE_3KB * 1024 - MVPP2_TX_FIFO_THRESHOLD_MIN)
539 551
540/* RX buffer constants */ 552/* RX buffer constants */
541#define MVPP2_SKB_SHINFO_SIZE \ 553#define MVPP2_SKB_SHINFO_SIZE \
@@ -589,6 +601,9 @@ enum mvpp2_tag_type {
589#define MVPP2_PRS_TCAM_PROTO_MASK 0xff 601#define MVPP2_PRS_TCAM_PROTO_MASK 0xff
590#define MVPP2_PRS_TCAM_PROTO_MASK_L 0x3f 602#define MVPP2_PRS_TCAM_PROTO_MASK_L 0x3f
591#define MVPP2_PRS_DBL_VLANS_MAX 100 603#define MVPP2_PRS_DBL_VLANS_MAX 100
604#define MVPP2_PRS_CAST_MASK BIT(0)
605#define MVPP2_PRS_MCAST_VAL BIT(0)
606#define MVPP2_PRS_UCAST_VAL 0x0
592 607
593/* Tcam structure: 608/* Tcam structure:
594 * - lookup ID - 4 bits 609 * - lookup ID - 4 bits
@@ -609,35 +624,81 @@ enum mvpp2_tag_type {
609#define MVPP2_PRS_TCAM_LU_BYTE 20 624#define MVPP2_PRS_TCAM_LU_BYTE 20
610#define MVPP2_PRS_TCAM_EN_OFFS(offs) ((offs) + 2) 625#define MVPP2_PRS_TCAM_EN_OFFS(offs) ((offs) + 2)
611#define MVPP2_PRS_TCAM_INV_WORD 5 626#define MVPP2_PRS_TCAM_INV_WORD 5
627
628#define MVPP2_PRS_VID_TCAM_BYTE 2
629
630/* TCAM range for unicast and multicast filtering. We have 25 entries per port,
631 * with 4 dedicated to UC filtering and the rest to multicast filtering.
632 * Additionnally we reserve one entry for the broadcast address, and one for
633 * each port's own address.
634 */
635#define MVPP2_PRS_MAC_UC_MC_FILT_MAX 25
636#define MVPP2_PRS_MAC_RANGE_SIZE 80
637
638/* Number of entries per port dedicated to UC and MC filtering */
639#define MVPP2_PRS_MAC_UC_FILT_MAX 4
640#define MVPP2_PRS_MAC_MC_FILT_MAX (MVPP2_PRS_MAC_UC_MC_FILT_MAX - \
641 MVPP2_PRS_MAC_UC_FILT_MAX)
642
643/* There is a TCAM range reserved for VLAN filtering entries, range size is 33
644 * 10 VLAN ID filter entries per port
645 * 1 default VLAN filter entry per port
646 * It is assumed that there are 3 ports for filter, not including loopback port
647 */
648#define MVPP2_PRS_VLAN_FILT_MAX 11
649#define MVPP2_PRS_VLAN_FILT_RANGE_SIZE 33
650
651#define MVPP2_PRS_VLAN_FILT_MAX_ENTRY (MVPP2_PRS_VLAN_FILT_MAX - 2)
652#define MVPP2_PRS_VLAN_FILT_DFLT_ENTRY (MVPP2_PRS_VLAN_FILT_MAX - 1)
653
612/* Tcam entries ID */ 654/* Tcam entries ID */
613#define MVPP2_PE_DROP_ALL 0 655#define MVPP2_PE_DROP_ALL 0
614#define MVPP2_PE_FIRST_FREE_TID 1 656#define MVPP2_PE_FIRST_FREE_TID 1
615#define MVPP2_PE_LAST_FREE_TID (MVPP2_PRS_TCAM_SRAM_SIZE - 31) 657
658/* MAC filtering range */
659#define MVPP2_PE_MAC_RANGE_END (MVPP2_PE_VID_FILT_RANGE_START - 1)
660#define MVPP2_PE_MAC_RANGE_START (MVPP2_PE_MAC_RANGE_END - \
661 MVPP2_PRS_MAC_RANGE_SIZE + 1)
662/* VLAN filtering range */
663#define MVPP2_PE_VID_FILT_RANGE_END (MVPP2_PRS_TCAM_SRAM_SIZE - 31)
664#define MVPP2_PE_VID_FILT_RANGE_START (MVPP2_PE_VID_FILT_RANGE_END - \
665 MVPP2_PRS_VLAN_FILT_RANGE_SIZE + 1)
666#define MVPP2_PE_LAST_FREE_TID (MVPP2_PE_VID_FILT_RANGE_START - 1)
616#define MVPP2_PE_IP6_EXT_PROTO_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 30) 667#define MVPP2_PE_IP6_EXT_PROTO_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 30)
617#define MVPP2_PE_MAC_MC_IP6 (MVPP2_PRS_TCAM_SRAM_SIZE - 29) 668#define MVPP2_PE_IP6_ADDR_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 29)
618#define MVPP2_PE_IP6_ADDR_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 28) 669#define MVPP2_PE_IP4_ADDR_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 28)
619#define MVPP2_PE_IP4_ADDR_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 27) 670#define MVPP2_PE_LAST_DEFAULT_FLOW (MVPP2_PRS_TCAM_SRAM_SIZE - 27)
620#define MVPP2_PE_LAST_DEFAULT_FLOW (MVPP2_PRS_TCAM_SRAM_SIZE - 26) 671#define MVPP2_PE_FIRST_DEFAULT_FLOW (MVPP2_PRS_TCAM_SRAM_SIZE - 22)
621#define MVPP2_PE_FIRST_DEFAULT_FLOW (MVPP2_PRS_TCAM_SRAM_SIZE - 19) 672#define MVPP2_PE_EDSA_TAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 21)
622#define MVPP2_PE_EDSA_TAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 18) 673#define MVPP2_PE_EDSA_UNTAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 20)
623#define MVPP2_PE_EDSA_UNTAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 17) 674#define MVPP2_PE_DSA_TAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 19)
624#define MVPP2_PE_DSA_TAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 16) 675#define MVPP2_PE_DSA_UNTAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 18)
625#define MVPP2_PE_DSA_UNTAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 15) 676#define MVPP2_PE_ETYPE_EDSA_TAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 17)
626#define MVPP2_PE_ETYPE_EDSA_TAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 14) 677#define MVPP2_PE_ETYPE_EDSA_UNTAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 16)
627#define MVPP2_PE_ETYPE_EDSA_UNTAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 13) 678#define MVPP2_PE_ETYPE_DSA_TAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 15)
628#define MVPP2_PE_ETYPE_DSA_TAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 12) 679#define MVPP2_PE_ETYPE_DSA_UNTAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 14)
629#define MVPP2_PE_ETYPE_DSA_UNTAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 11) 680#define MVPP2_PE_MH_DEFAULT (MVPP2_PRS_TCAM_SRAM_SIZE - 13)
630#define MVPP2_PE_MH_DEFAULT (MVPP2_PRS_TCAM_SRAM_SIZE - 10) 681#define MVPP2_PE_DSA_DEFAULT (MVPP2_PRS_TCAM_SRAM_SIZE - 12)
631#define MVPP2_PE_DSA_DEFAULT (MVPP2_PRS_TCAM_SRAM_SIZE - 9) 682#define MVPP2_PE_IP6_PROTO_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 11)
632#define MVPP2_PE_IP6_PROTO_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 8) 683#define MVPP2_PE_IP4_PROTO_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 10)
633#define MVPP2_PE_IP4_PROTO_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 7) 684#define MVPP2_PE_ETH_TYPE_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 9)
634#define MVPP2_PE_ETH_TYPE_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 6) 685#define MVPP2_PE_VID_FLTR_DEFAULT (MVPP2_PRS_TCAM_SRAM_SIZE - 8)
635#define MVPP2_PE_VLAN_DBL (MVPP2_PRS_TCAM_SRAM_SIZE - 5) 686#define MVPP2_PE_VID_EDSA_FLTR_DEFAULT (MVPP2_PRS_TCAM_SRAM_SIZE - 7)
636#define MVPP2_PE_VLAN_NONE (MVPP2_PRS_TCAM_SRAM_SIZE - 4) 687#define MVPP2_PE_VLAN_DBL (MVPP2_PRS_TCAM_SRAM_SIZE - 6)
637#define MVPP2_PE_MAC_MC_ALL (MVPP2_PRS_TCAM_SRAM_SIZE - 3) 688#define MVPP2_PE_VLAN_NONE (MVPP2_PRS_TCAM_SRAM_SIZE - 5)
638#define MVPP2_PE_MAC_PROMISCUOUS (MVPP2_PRS_TCAM_SRAM_SIZE - 2) 689/* reserved */
690#define MVPP2_PE_MAC_MC_PROMISCUOUS (MVPP2_PRS_TCAM_SRAM_SIZE - 3)
691#define MVPP2_PE_MAC_UC_PROMISCUOUS (MVPP2_PRS_TCAM_SRAM_SIZE - 2)
639#define MVPP2_PE_MAC_NON_PROMISCUOUS (MVPP2_PRS_TCAM_SRAM_SIZE - 1) 692#define MVPP2_PE_MAC_NON_PROMISCUOUS (MVPP2_PRS_TCAM_SRAM_SIZE - 1)
640 693
694#define MVPP2_PRS_VID_PORT_FIRST(port) (MVPP2_PE_VID_FILT_RANGE_START + \
695 ((port) * MVPP2_PRS_VLAN_FILT_MAX))
696#define MVPP2_PRS_VID_PORT_LAST(port) (MVPP2_PRS_VID_PORT_FIRST(port) \
697 + MVPP2_PRS_VLAN_FILT_MAX_ENTRY)
698/* Index of default vid filter for given port */
699#define MVPP2_PRS_VID_PORT_DFLT(port) (MVPP2_PRS_VID_PORT_FIRST(port) \
700 + MVPP2_PRS_VLAN_FILT_DFLT_ENTRY)
701
641/* Sram structure 702/* Sram structure
642 * The fields are represented by MVPP2_PRS_TCAM_DATA_REG(3)->(0). 703 * The fields are represented by MVPP2_PRS_TCAM_DATA_REG(3)->(0).
643 */ 704 */
@@ -725,6 +786,7 @@ enum mvpp2_tag_type {
725#define MVPP2_PRS_IPV6_EXT_AH_L4_AI_BIT BIT(4) 786#define MVPP2_PRS_IPV6_EXT_AH_L4_AI_BIT BIT(4)
726#define MVPP2_PRS_SINGLE_VLAN_AI 0 787#define MVPP2_PRS_SINGLE_VLAN_AI 0
727#define MVPP2_PRS_DBL_VLAN_AI_BIT BIT(7) 788#define MVPP2_PRS_DBL_VLAN_AI_BIT BIT(7)
789#define MVPP2_PRS_EDSA_VID_AI_BIT BIT(0)
728 790
729/* DSA/EDSA type */ 791/* DSA/EDSA type */
730#define MVPP2_PRS_TAGGED true 792#define MVPP2_PRS_TAGGED true
@@ -747,6 +809,7 @@ enum mvpp2_prs_lookup {
747 MVPP2_PRS_LU_MAC, 809 MVPP2_PRS_LU_MAC,
748 MVPP2_PRS_LU_DSA, 810 MVPP2_PRS_LU_DSA,
749 MVPP2_PRS_LU_VLAN, 811 MVPP2_PRS_LU_VLAN,
812 MVPP2_PRS_LU_VID,
750 MVPP2_PRS_LU_L2, 813 MVPP2_PRS_LU_L2,
751 MVPP2_PRS_LU_PPPOE, 814 MVPP2_PRS_LU_PPPOE,
752 MVPP2_PRS_LU_IP4, 815 MVPP2_PRS_LU_IP4,
@@ -755,6 +818,12 @@ enum mvpp2_prs_lookup {
755 MVPP2_PRS_LU_LAST, 818 MVPP2_PRS_LU_LAST,
756}; 819};
757 820
821/* L2 cast enum */
822enum mvpp2_prs_l2_cast {
823 MVPP2_PRS_L2_UNI_CAST,
824 MVPP2_PRS_L2_MULTI_CAST,
825};
826
758/* L3 cast enum */ 827/* L3 cast enum */
759enum mvpp2_prs_l3_cast { 828enum mvpp2_prs_l3_cast {
760 MVPP2_PRS_L3_UNI_CAST, 829 MVPP2_PRS_L3_UNI_CAST,
@@ -772,23 +841,26 @@ enum mvpp2_prs_l3_cast {
772#define MVPP22_RSS_TABLE_ENTRIES 32 841#define MVPP22_RSS_TABLE_ENTRIES 32
773 842
774/* BM constants */ 843/* BM constants */
775#define MVPP2_BM_POOLS_NUM 8 844#define MVPP2_BM_JUMBO_BUF_NUM 512
776#define MVPP2_BM_LONG_BUF_NUM 1024 845#define MVPP2_BM_LONG_BUF_NUM 1024
777#define MVPP2_BM_SHORT_BUF_NUM 2048 846#define MVPP2_BM_SHORT_BUF_NUM 2048
778#define MVPP2_BM_POOL_SIZE_MAX (16*1024 - MVPP2_BM_POOL_PTR_ALIGN/4) 847#define MVPP2_BM_POOL_SIZE_MAX (16*1024 - MVPP2_BM_POOL_PTR_ALIGN/4)
779#define MVPP2_BM_POOL_PTR_ALIGN 128 848#define MVPP2_BM_POOL_PTR_ALIGN 128
780#define MVPP2_BM_SWF_LONG_POOL(port) ((port > 2) ? 2 : port)
781#define MVPP2_BM_SWF_SHORT_POOL 3
782 849
783/* BM cookie (32 bits) definition */ 850/* BM cookie (32 bits) definition */
784#define MVPP2_BM_COOKIE_POOL_OFFS 8 851#define MVPP2_BM_COOKIE_POOL_OFFS 8
785#define MVPP2_BM_COOKIE_CPU_OFFS 24 852#define MVPP2_BM_COOKIE_CPU_OFFS 24
786 853
854#define MVPP2_BM_SHORT_FRAME_SIZE 512
855#define MVPP2_BM_LONG_FRAME_SIZE 2048
856#define MVPP2_BM_JUMBO_FRAME_SIZE 10240
787/* BM short pool packet size 857/* BM short pool packet size
788 * These value assure that for SWF the total number 858 * These value assure that for SWF the total number
789 * of bytes allocated for each buffer will be 512 859 * of bytes allocated for each buffer will be 512
790 */ 860 */
791#define MVPP2_BM_SHORT_PKT_SIZE MVPP2_RX_MAX_PKT_SIZE(512) 861#define MVPP2_BM_SHORT_PKT_SIZE MVPP2_RX_MAX_PKT_SIZE(MVPP2_BM_SHORT_FRAME_SIZE)
862#define MVPP2_BM_LONG_PKT_SIZE MVPP2_RX_MAX_PKT_SIZE(MVPP2_BM_LONG_FRAME_SIZE)
863#define MVPP2_BM_JUMBO_PKT_SIZE MVPP2_RX_MAX_PKT_SIZE(MVPP2_BM_JUMBO_FRAME_SIZE)
792 864
793#define MVPP21_ADDR_SPACE_SZ 0 865#define MVPP21_ADDR_SPACE_SZ 0
794#define MVPP22_ADDR_SPACE_SZ SZ_64K 866#define MVPP22_ADDR_SPACE_SZ SZ_64K
@@ -796,12 +868,18 @@ enum mvpp2_prs_l3_cast {
796#define MVPP2_MAX_THREADS 8 868#define MVPP2_MAX_THREADS 8
797#define MVPP2_MAX_QVECS MVPP2_MAX_THREADS 869#define MVPP2_MAX_QVECS MVPP2_MAX_THREADS
798 870
799enum mvpp2_bm_type { 871enum mvpp2_bm_pool_log_num {
800 MVPP2_BM_FREE, 872 MVPP2_BM_SHORT,
801 MVPP2_BM_SWF_LONG, 873 MVPP2_BM_LONG,
802 MVPP2_BM_SWF_SHORT 874 MVPP2_BM_JUMBO,
875 MVPP2_BM_POOLS_NUM
803}; 876};
804 877
878static struct {
879 int pkt_size;
880 int buf_num;
881} mvpp2_pools[MVPP2_BM_POOLS_NUM];
882
805/* GMAC MIB Counters register definitions */ 883/* GMAC MIB Counters register definitions */
806#define MVPP21_MIB_COUNTERS_OFFSET 0x1000 884#define MVPP21_MIB_COUNTERS_OFFSET 0x1000
807#define MVPP21_MIB_COUNTERS_PORT_SZ 0x400 885#define MVPP21_MIB_COUNTERS_PORT_SZ 0x400
@@ -1230,7 +1308,6 @@ struct mvpp2_cls_lookup_entry {
1230struct mvpp2_bm_pool { 1308struct mvpp2_bm_pool {
1231 /* Pool number in the range 0-7 */ 1309 /* Pool number in the range 0-7 */
1232 int id; 1310 int id;
1233 enum mvpp2_bm_type type;
1234 1311
1235 /* Buffer Pointers Pool External (BPPE) size */ 1312 /* Buffer Pointers Pool External (BPPE) size */
1236 int size; 1313 int size;
@@ -1662,6 +1739,14 @@ static void mvpp2_prs_match_etype(struct mvpp2_prs_entry *pe, int offset,
1662 mvpp2_prs_tcam_data_byte_set(pe, offset + 1, ethertype & 0xff, 0xff); 1739 mvpp2_prs_tcam_data_byte_set(pe, offset + 1, ethertype & 0xff, 0xff);
1663} 1740}
1664 1741
1742/* Set vid in tcam sw entry */
1743static void mvpp2_prs_match_vid(struct mvpp2_prs_entry *pe, int offset,
1744 unsigned short vid)
1745{
1746 mvpp2_prs_tcam_data_byte_set(pe, offset + 0, (vid & 0xf00) >> 8, 0xf);
1747 mvpp2_prs_tcam_data_byte_set(pe, offset + 1, vid & 0xff, 0xff);
1748}
1749
1665/* Set bits in sram sw entry */ 1750/* Set bits in sram sw entry */
1666static void mvpp2_prs_sram_bits_set(struct mvpp2_prs_entry *pe, int bit_num, 1751static void mvpp2_prs_sram_bits_set(struct mvpp2_prs_entry *pe, int bit_num,
1667 int val) 1752 int val)
@@ -1914,78 +1999,43 @@ static void mvpp2_prs_mac_drop_all_set(struct mvpp2 *priv, int port, bool add)
1914 mvpp2_prs_hw_write(priv, &pe); 1999 mvpp2_prs_hw_write(priv, &pe);
1915} 2000}
1916 2001
1917/* Set port to promiscuous mode */ 2002/* Set port to unicast or multicast promiscuous mode */
1918static void mvpp2_prs_mac_promisc_set(struct mvpp2 *priv, int port, bool add) 2003static void mvpp2_prs_mac_promisc_set(struct mvpp2 *priv, int port,
2004 enum mvpp2_prs_l2_cast l2_cast, bool add)
1919{ 2005{
1920 struct mvpp2_prs_entry pe; 2006 struct mvpp2_prs_entry pe;
2007 unsigned char cast_match;
2008 unsigned int ri;
2009 int tid;
1921 2010
1922 /* Promiscuous mode - Accept unknown packets */ 2011 if (l2_cast == MVPP2_PRS_L2_UNI_CAST) {
1923 2012 cast_match = MVPP2_PRS_UCAST_VAL;
1924 if (priv->prs_shadow[MVPP2_PE_MAC_PROMISCUOUS].valid) { 2013 tid = MVPP2_PE_MAC_UC_PROMISCUOUS;
1925 /* Entry exist - update port only */ 2014 ri = MVPP2_PRS_RI_L2_UCAST;
1926 pe.index = MVPP2_PE_MAC_PROMISCUOUS;
1927 mvpp2_prs_hw_read(priv, &pe);
1928 } else { 2015 } else {
1929 /* Entry doesn't exist - create new */ 2016 cast_match = MVPP2_PRS_MCAST_VAL;
1930 memset(&pe, 0, sizeof(pe)); 2017 tid = MVPP2_PE_MAC_MC_PROMISCUOUS;
1931 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MAC); 2018 ri = MVPP2_PRS_RI_L2_MCAST;
1932 pe.index = MVPP2_PE_MAC_PROMISCUOUS;
1933
1934 /* Continue - set next lookup */
1935 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_DSA);
1936
1937 /* Set result info bits */
1938 mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L2_UCAST,
1939 MVPP2_PRS_RI_L2_CAST_MASK);
1940
1941 /* Shift to ethertype */
1942 mvpp2_prs_sram_shift_set(&pe, 2 * ETH_ALEN,
1943 MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
1944
1945 /* Mask all ports */
1946 mvpp2_prs_tcam_port_map_set(&pe, 0);
1947
1948 /* Update shadow table */
1949 mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_MAC);
1950 } 2019 }
1951 2020
1952 /* Update port mask */ 2021 /* promiscuous mode - Accept unknown unicast or multicast packets */
1953 mvpp2_prs_tcam_port_set(&pe, port, add); 2022 if (priv->prs_shadow[tid].valid) {
1954 2023 pe.index = tid;
1955 mvpp2_prs_hw_write(priv, &pe);
1956}
1957
1958/* Accept multicast */
1959static void mvpp2_prs_mac_multi_set(struct mvpp2 *priv, int port, int index,
1960 bool add)
1961{
1962 struct mvpp2_prs_entry pe;
1963 unsigned char da_mc;
1964
1965 /* Ethernet multicast address first byte is
1966 * 0x01 for IPv4 and 0x33 for IPv6
1967 */
1968 da_mc = (index == MVPP2_PE_MAC_MC_ALL) ? 0x01 : 0x33;
1969
1970 if (priv->prs_shadow[index].valid) {
1971 /* Entry exist - update port only */
1972 pe.index = index;
1973 mvpp2_prs_hw_read(priv, &pe); 2024 mvpp2_prs_hw_read(priv, &pe);
1974 } else { 2025 } else {
1975 /* Entry doesn't exist - create new */
1976 memset(&pe, 0, sizeof(pe)); 2026 memset(&pe, 0, sizeof(pe));
1977 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MAC); 2027 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MAC);
1978 pe.index = index; 2028 pe.index = tid;
1979 2029
1980 /* Continue - set next lookup */ 2030 /* Continue - set next lookup */
1981 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_DSA); 2031 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_DSA);
1982 2032
1983 /* Set result info bits */ 2033 /* Set result info bits */
1984 mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L2_MCAST, 2034 mvpp2_prs_sram_ri_update(&pe, ri, MVPP2_PRS_RI_L2_CAST_MASK);
1985 MVPP2_PRS_RI_L2_CAST_MASK);
1986 2035
1987 /* Update tcam entry data first byte */ 2036 /* Match UC or MC addresses */
1988 mvpp2_prs_tcam_data_byte_set(&pe, 0, da_mc, 0xff); 2037 mvpp2_prs_tcam_data_byte_set(&pe, 0, cast_match,
2038 MVPP2_PRS_CAST_MASK);
1989 2039
1990 /* Shift to ethertype */ 2040 /* Shift to ethertype */
1991 mvpp2_prs_sram_shift_set(&pe, 2 * ETH_ALEN, 2041 mvpp2_prs_sram_shift_set(&pe, 2 * ETH_ALEN,
@@ -2029,24 +2079,30 @@ static void mvpp2_prs_dsa_tag_set(struct mvpp2 *priv, int port, bool add,
2029 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_DSA); 2079 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_DSA);
2030 pe.index = tid; 2080 pe.index = tid;
2031 2081
2032 /* Shift 4 bytes if DSA tag or 8 bytes in case of EDSA tag*/
2033 mvpp2_prs_sram_shift_set(&pe, shift,
2034 MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
2035
2036 /* Update shadow table */ 2082 /* Update shadow table */
2037 mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_DSA); 2083 mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_DSA);
2038 2084
2039 if (tagged) { 2085 if (tagged) {
2040 /* Set tagged bit in DSA tag */ 2086 /* Set tagged bit in DSA tag */
2041 mvpp2_prs_tcam_data_byte_set(&pe, 0, 2087 mvpp2_prs_tcam_data_byte_set(&pe, 0,
2042 MVPP2_PRS_TCAM_DSA_TAGGED_BIT, 2088 MVPP2_PRS_TCAM_DSA_TAGGED_BIT,
2043 MVPP2_PRS_TCAM_DSA_TAGGED_BIT); 2089 MVPP2_PRS_TCAM_DSA_TAGGED_BIT);
2044 /* Clear all ai bits for next iteration */ 2090
2045 mvpp2_prs_sram_ai_update(&pe, 0, 2091 /* Set ai bits for next iteration */
2046 MVPP2_PRS_SRAM_AI_MASK); 2092 if (extend)
2047 /* If packet is tagged continue check vlans */ 2093 mvpp2_prs_sram_ai_update(&pe, 1,
2048 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_VLAN); 2094 MVPP2_PRS_SRAM_AI_MASK);
2095 else
2096 mvpp2_prs_sram_ai_update(&pe, 0,
2097 MVPP2_PRS_SRAM_AI_MASK);
2098
2099 /* If packet is tagged continue check vid filtering */
2100 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_VID);
2049 } else { 2101 } else {
2102 /* Shift 4 bytes for DSA tag or 8 bytes for EDSA tag*/
2103 mvpp2_prs_sram_shift_set(&pe, shift,
2104 MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
2105
2050 /* Set result info bits to 'no vlans' */ 2106 /* Set result info bits to 'no vlans' */
2051 mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_VLAN_NONE, 2107 mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_VLAN_NONE,
2052 MVPP2_PRS_RI_VLAN_MASK); 2108 MVPP2_PRS_RI_VLAN_MASK);
@@ -2231,10 +2287,9 @@ static int mvpp2_prs_vlan_add(struct mvpp2 *priv, unsigned short tpid, int ai,
2231 2287
2232 mvpp2_prs_match_etype(pe, 0, tpid); 2288 mvpp2_prs_match_etype(pe, 0, tpid);
2233 2289
2234 mvpp2_prs_sram_next_lu_set(pe, MVPP2_PRS_LU_L2); 2290 /* VLAN tag detected, proceed with VID filtering */
2235 /* Shift 4 bytes - skip 1 vlan tag */ 2291 mvpp2_prs_sram_next_lu_set(pe, MVPP2_PRS_LU_VID);
2236 mvpp2_prs_sram_shift_set(pe, MVPP2_VLAN_TAG_LEN, 2292
2237 MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
2238 /* Clear all ai bits for next iteration */ 2293 /* Clear all ai bits for next iteration */
2239 mvpp2_prs_sram_ai_update(pe, 0, MVPP2_PRS_SRAM_AI_MASK); 2294 mvpp2_prs_sram_ai_update(pe, 0, MVPP2_PRS_SRAM_AI_MASK);
2240 2295
@@ -2375,8 +2430,8 @@ static int mvpp2_prs_double_vlan_add(struct mvpp2 *priv, unsigned short tpid1,
2375 mvpp2_prs_match_etype(pe, 4, tpid2); 2430 mvpp2_prs_match_etype(pe, 4, tpid2);
2376 2431
2377 mvpp2_prs_sram_next_lu_set(pe, MVPP2_PRS_LU_VLAN); 2432 mvpp2_prs_sram_next_lu_set(pe, MVPP2_PRS_LU_VLAN);
2378 /* Shift 8 bytes - skip 2 vlan tags */ 2433 /* Shift 4 bytes - skip outer vlan tag */
2379 mvpp2_prs_sram_shift_set(pe, 2 * MVPP2_VLAN_TAG_LEN, 2434 mvpp2_prs_sram_shift_set(pe, MVPP2_VLAN_TAG_LEN,
2380 MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD); 2435 MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
2381 mvpp2_prs_sram_ri_update(pe, MVPP2_PRS_RI_VLAN_DOUBLE, 2436 mvpp2_prs_sram_ri_update(pe, MVPP2_PRS_RI_VLAN_DOUBLE,
2382 MVPP2_PRS_RI_VLAN_MASK); 2437 MVPP2_PRS_RI_VLAN_MASK);
@@ -2694,11 +2749,10 @@ static void mvpp2_prs_mac_init(struct mvpp2 *priv)
2694 mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_MAC); 2749 mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_MAC);
2695 mvpp2_prs_hw_write(priv, &pe); 2750 mvpp2_prs_hw_write(priv, &pe);
2696 2751
2697 /* place holders only - no ports */ 2752 /* Create dummy entries for drop all and promiscuous modes */
2698 mvpp2_prs_mac_drop_all_set(priv, 0, false); 2753 mvpp2_prs_mac_drop_all_set(priv, 0, false);
2699 mvpp2_prs_mac_promisc_set(priv, 0, false); 2754 mvpp2_prs_mac_promisc_set(priv, 0, MVPP2_PRS_L2_UNI_CAST, false);
2700 mvpp2_prs_mac_multi_set(priv, 0, MVPP2_PE_MAC_MC_ALL, false); 2755 mvpp2_prs_mac_promisc_set(priv, 0, MVPP2_PRS_L2_MULTI_CAST, false);
2701 mvpp2_prs_mac_multi_set(priv, 0, MVPP2_PE_MAC_MC_IP6, false);
2702} 2756}
2703 2757
2704/* Set default entries for various types of dsa packets */ 2758/* Set default entries for various types of dsa packets */
@@ -2755,6 +2809,62 @@ static void mvpp2_prs_dsa_init(struct mvpp2 *priv)
2755 mvpp2_prs_hw_write(priv, &pe); 2809 mvpp2_prs_hw_write(priv, &pe);
2756} 2810}
2757 2811
2812/* Initialize parser entries for VID filtering */
2813static void mvpp2_prs_vid_init(struct mvpp2 *priv)
2814{
2815 struct mvpp2_prs_entry pe;
2816
2817 memset(&pe, 0, sizeof(pe));
2818
2819 /* Set default vid entry */
2820 pe.index = MVPP2_PE_VID_FLTR_DEFAULT;
2821 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_VID);
2822
2823 mvpp2_prs_tcam_ai_update(&pe, 0, MVPP2_PRS_EDSA_VID_AI_BIT);
2824
2825 /* Skip VLAN header - Set offset to 4 bytes */
2826 mvpp2_prs_sram_shift_set(&pe, MVPP2_VLAN_TAG_LEN,
2827 MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
2828
2829 /* Clear all ai bits for next iteration */
2830 mvpp2_prs_sram_ai_update(&pe, 0, MVPP2_PRS_SRAM_AI_MASK);
2831
2832 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_L2);
2833
2834 /* Unmask all ports */
2835 mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);
2836
2837 /* Update shadow table and hw entry */
2838 mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_VID);
2839 mvpp2_prs_hw_write(priv, &pe);
2840
2841 /* Set default vid entry for extended DSA*/
2842 memset(&pe, 0, sizeof(pe));
2843
2844 /* Set default vid entry */
2845 pe.index = MVPP2_PE_VID_EDSA_FLTR_DEFAULT;
2846 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_VID);
2847
2848 mvpp2_prs_tcam_ai_update(&pe, MVPP2_PRS_EDSA_VID_AI_BIT,
2849 MVPP2_PRS_EDSA_VID_AI_BIT);
2850
2851 /* Skip VLAN header - Set offset to 8 bytes */
2852 mvpp2_prs_sram_shift_set(&pe, MVPP2_VLAN_TAG_EDSA_LEN,
2853 MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
2854
2855 /* Clear all ai bits for next iteration */
2856 mvpp2_prs_sram_ai_update(&pe, 0, MVPP2_PRS_SRAM_AI_MASK);
2857
2858 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_L2);
2859
2860 /* Unmask all ports */
2861 mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);
2862
2863 /* Update shadow table and hw entry */
2864 mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_VID);
2865 mvpp2_prs_hw_write(priv, &pe);
2866}
2867
2758/* Match basic ethertypes */ 2868/* Match basic ethertypes */
2759static int mvpp2_prs_etype_init(struct mvpp2 *priv) 2869static int mvpp2_prs_etype_init(struct mvpp2 *priv)
2760{ 2870{
@@ -3023,7 +3133,8 @@ static int mvpp2_prs_vlan_init(struct platform_device *pdev, struct mvpp2 *priv)
3023 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_VLAN); 3133 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_VLAN);
3024 pe.index = MVPP2_PE_VLAN_DBL; 3134 pe.index = MVPP2_PE_VLAN_DBL;
3025 3135
3026 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_L2); 3136 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_VID);
3137
3027 /* Clear ai for next iterations */ 3138 /* Clear ai for next iterations */
3028 mvpp2_prs_sram_ai_update(&pe, 0, MVPP2_PRS_SRAM_AI_MASK); 3139 mvpp2_prs_sram_ai_update(&pe, 0, MVPP2_PRS_SRAM_AI_MASK);
3029 mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_VLAN_DOUBLE, 3140 mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_VLAN_DOUBLE,
@@ -3386,6 +3497,192 @@ static int mvpp2_prs_ip6_init(struct mvpp2 *priv)
3386 return 0; 3497 return 0;
3387} 3498}
3388 3499
3500/* Find tcam entry with matched pair <vid,port> */
3501static int mvpp2_prs_vid_range_find(struct mvpp2 *priv, int pmap, u16 vid,
3502 u16 mask)
3503{
3504 unsigned char byte[2], enable[2];
3505 struct mvpp2_prs_entry pe;
3506 u16 rvid, rmask;
3507 int tid;
3508
3509 /* Go through the all entries with MVPP2_PRS_LU_VID */
3510 for (tid = MVPP2_PE_VID_FILT_RANGE_START;
3511 tid <= MVPP2_PE_VID_FILT_RANGE_END; tid++) {
3512 if (!priv->prs_shadow[tid].valid ||
3513 priv->prs_shadow[tid].lu != MVPP2_PRS_LU_VID)
3514 continue;
3515
3516 pe.index = tid;
3517
3518 mvpp2_prs_hw_read(priv, &pe);
3519 mvpp2_prs_tcam_data_byte_get(&pe, 2, &byte[0], &enable[0]);
3520 mvpp2_prs_tcam_data_byte_get(&pe, 3, &byte[1], &enable[1]);
3521
3522 rvid = ((byte[0] & 0xf) << 8) + byte[1];
3523 rmask = ((enable[0] & 0xf) << 8) + enable[1];
3524
3525 if (rvid != vid || rmask != mask)
3526 continue;
3527
3528 return tid;
3529 }
3530
3531 return 0;
3532}
3533
3534/* Write parser entry for VID filtering */
3535static int mvpp2_prs_vid_entry_add(struct mvpp2_port *port, u16 vid)
3536{
3537 unsigned int vid_start = MVPP2_PE_VID_FILT_RANGE_START +
3538 port->id * MVPP2_PRS_VLAN_FILT_MAX;
3539 unsigned int mask = 0xfff, reg_val, shift;
3540 struct mvpp2 *priv = port->priv;
3541 struct mvpp2_prs_entry pe;
3542 int tid;
3543
3544 /* Scan TCAM and see if entry with this <vid,port> already exist */
3545 tid = mvpp2_prs_vid_range_find(priv, (1 << port->id), vid, mask);
3546
3547 reg_val = mvpp2_read(priv, MVPP2_MH_REG(port->id));
3548 if (reg_val & MVPP2_DSA_EXTENDED)
3549 shift = MVPP2_VLAN_TAG_EDSA_LEN;
3550 else
3551 shift = MVPP2_VLAN_TAG_LEN;
3552
3553 /* No such entry */
3554 if (!tid) {
3555 memset(&pe, 0, sizeof(pe));
3556
3557 /* Go through all entries from first to last in vlan range */
3558 tid = mvpp2_prs_tcam_first_free(priv, vid_start,
3559 vid_start +
3560 MVPP2_PRS_VLAN_FILT_MAX_ENTRY);
3561
3562 /* There isn't room for a new VID filter */
3563 if (tid < 0)
3564 return tid;
3565
3566 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_VID);
3567 pe.index = tid;
3568
3569 /* Mask all ports */
3570 mvpp2_prs_tcam_port_map_set(&pe, 0);
3571 } else {
3572 mvpp2_prs_hw_read(priv, &pe);
3573 }
3574
3575 /* Enable the current port */
3576 mvpp2_prs_tcam_port_set(&pe, port->id, true);
3577
3578 /* Continue - set next lookup */
3579 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_L2);
3580
3581 /* Skip VLAN header - Set offset to 4 or 8 bytes */
3582 mvpp2_prs_sram_shift_set(&pe, shift, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
3583
3584 /* Set match on VID */
3585 mvpp2_prs_match_vid(&pe, MVPP2_PRS_VID_TCAM_BYTE, vid);
3586
3587 /* Clear all ai bits for next iteration */
3588 mvpp2_prs_sram_ai_update(&pe, 0, MVPP2_PRS_SRAM_AI_MASK);
3589
3590 /* Update shadow table */
3591 mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_VID);
3592 mvpp2_prs_hw_write(priv, &pe);
3593
3594 return 0;
3595}
3596
3597/* Write parser entry for VID filtering */
3598static void mvpp2_prs_vid_entry_remove(struct mvpp2_port *port, u16 vid)
3599{
3600 struct mvpp2 *priv = port->priv;
3601 int tid;
3602
3603 /* Scan TCAM and see if entry with this <vid,port> already exist */
3604 tid = mvpp2_prs_vid_range_find(priv, (1 << port->id), vid, 0xfff);
3605
3606 /* No such entry */
3607 if (tid)
3608 return;
3609
3610 mvpp2_prs_hw_inv(priv, tid);
3611 priv->prs_shadow[tid].valid = false;
3612}
3613
3614/* Remove all existing VID filters on this port */
3615static void mvpp2_prs_vid_remove_all(struct mvpp2_port *port)
3616{
3617 struct mvpp2 *priv = port->priv;
3618 int tid;
3619
3620 for (tid = MVPP2_PRS_VID_PORT_FIRST(port->id);
3621 tid <= MVPP2_PRS_VID_PORT_LAST(port->id); tid++) {
3622 if (priv->prs_shadow[tid].valid)
3623 mvpp2_prs_vid_entry_remove(port, tid);
3624 }
3625}
3626
3627/* Remove VID filering entry for this port */
3628static void mvpp2_prs_vid_disable_filtering(struct mvpp2_port *port)
3629{
3630 unsigned int tid = MVPP2_PRS_VID_PORT_DFLT(port->id);
3631 struct mvpp2 *priv = port->priv;
3632
3633 /* Invalidate the guard entry */
3634 mvpp2_prs_hw_inv(priv, tid);
3635
3636 priv->prs_shadow[tid].valid = false;
3637}
3638
3639/* Add guard entry that drops packets when no VID is matched on this port */
3640static void mvpp2_prs_vid_enable_filtering(struct mvpp2_port *port)
3641{
3642 unsigned int tid = MVPP2_PRS_VID_PORT_DFLT(port->id);
3643 struct mvpp2 *priv = port->priv;
3644 unsigned int reg_val, shift;
3645 struct mvpp2_prs_entry pe;
3646
3647 if (priv->prs_shadow[tid].valid)
3648 return;
3649
3650 memset(&pe, 0, sizeof(pe));
3651
3652 pe.index = tid;
3653
3654 reg_val = mvpp2_read(priv, MVPP2_MH_REG(port->id));
3655 if (reg_val & MVPP2_DSA_EXTENDED)
3656 shift = MVPP2_VLAN_TAG_EDSA_LEN;
3657 else
3658 shift = MVPP2_VLAN_TAG_LEN;
3659
3660 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_VID);
3661
3662 /* Mask all ports */
3663 mvpp2_prs_tcam_port_map_set(&pe, 0);
3664
3665 /* Update port mask */
3666 mvpp2_prs_tcam_port_set(&pe, port->id, true);
3667
3668 /* Continue - set next lookup */
3669 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_L2);
3670
3671 /* Skip VLAN header - Set offset to 4 or 8 bytes */
3672 mvpp2_prs_sram_shift_set(&pe, shift, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
3673
3674 /* Drop VLAN packets that don't belong to any VIDs on this port */
3675 mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_DROP_MASK,
3676 MVPP2_PRS_RI_DROP_MASK);
3677
3678 /* Clear all ai bits for next iteration */
3679 mvpp2_prs_sram_ai_update(&pe, 0, MVPP2_PRS_SRAM_AI_MASK);
3680
3681 /* Update shadow table */
3682 mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_VID);
3683 mvpp2_prs_hw_write(priv, &pe);
3684}
3685
3389/* Parser default initialization */ 3686/* Parser default initialization */
3390static int mvpp2_prs_default_init(struct platform_device *pdev, 3687static int mvpp2_prs_default_init(struct platform_device *pdev,
3391 struct mvpp2 *priv) 3688 struct mvpp2 *priv)
@@ -3429,6 +3726,8 @@ static int mvpp2_prs_default_init(struct platform_device *pdev,
3429 3726
3430 mvpp2_prs_dsa_init(priv); 3727 mvpp2_prs_dsa_init(priv);
3431 3728
3729 mvpp2_prs_vid_init(priv);
3730
3432 err = mvpp2_prs_etype_init(priv); 3731 err = mvpp2_prs_etype_init(priv);
3433 if (err) 3732 if (err)
3434 return err; 3733 return err;
@@ -3485,8 +3784,8 @@ mvpp2_prs_mac_da_range_find(struct mvpp2 *priv, int pmap, const u8 *da,
3485 mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_MAC); 3784 mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_MAC);
3486 3785
3487 /* Go through the all entires with MVPP2_PRS_LU_MAC */ 3786 /* Go through the all entires with MVPP2_PRS_LU_MAC */
3488 for (tid = MVPP2_PE_FIRST_FREE_TID; 3787 for (tid = MVPP2_PE_MAC_RANGE_START;
3489 tid <= MVPP2_PE_LAST_FREE_TID; tid++) { 3788 tid <= MVPP2_PE_MAC_RANGE_END; tid++) {
3490 unsigned int entry_pmap; 3789 unsigned int entry_pmap;
3491 3790
3492 if (!priv->prs_shadow[tid].valid || 3791 if (!priv->prs_shadow[tid].valid ||
@@ -3508,16 +3807,17 @@ mvpp2_prs_mac_da_range_find(struct mvpp2 *priv, int pmap, const u8 *da,
3508} 3807}
3509 3808
3510/* Update parser's mac da entry */ 3809/* Update parser's mac da entry */
3511static int mvpp2_prs_mac_da_accept(struct mvpp2 *priv, int port, 3810static int mvpp2_prs_mac_da_accept(struct mvpp2_port *port, const u8 *da,
3512 const u8 *da, bool add) 3811 bool add)
3513{ 3812{
3514 struct mvpp2_prs_entry *pe;
3515 unsigned int pmap, len, ri;
3516 unsigned char mask[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 3813 unsigned char mask[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
3814 struct mvpp2 *priv = port->priv;
3815 unsigned int pmap, len, ri;
3816 struct mvpp2_prs_entry *pe;
3517 int tid; 3817 int tid;
3518 3818
3519 /* Scan TCAM and see if entry with this <MAC DA, port> already exist */ 3819 /* Scan TCAM and see if entry with this <MAC DA, port> already exist */
3520 pe = mvpp2_prs_mac_da_range_find(priv, (1 << port), da, mask, 3820 pe = mvpp2_prs_mac_da_range_find(priv, BIT(port->id), da, mask,
3521 MVPP2_PRS_UDF_MAC_DEF); 3821 MVPP2_PRS_UDF_MAC_DEF);
3522 3822
3523 /* No such entry */ 3823 /* No such entry */
@@ -3526,18 +3826,10 @@ static int mvpp2_prs_mac_da_accept(struct mvpp2 *priv, int port,
3526 return 0; 3826 return 0;
3527 3827
3528 /* Create new TCAM entry */ 3828 /* Create new TCAM entry */
3529 /* Find first range mac entry*/
3530 for (tid = MVPP2_PE_FIRST_FREE_TID;
3531 tid <= MVPP2_PE_LAST_FREE_TID; tid++)
3532 if (priv->prs_shadow[tid].valid &&
3533 (priv->prs_shadow[tid].lu == MVPP2_PRS_LU_MAC) &&
3534 (priv->prs_shadow[tid].udf ==
3535 MVPP2_PRS_UDF_MAC_RANGE))
3536 break;
3537
3538 /* Go through the all entries from first to last */ 3829 /* Go through the all entries from first to last */
3539 tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID, 3830 tid = mvpp2_prs_tcam_first_free(priv,
3540 tid - 1); 3831 MVPP2_PE_MAC_RANGE_START,
3832 MVPP2_PE_MAC_RANGE_END);
3541 if (tid < 0) 3833 if (tid < 0)
3542 return tid; 3834 return tid;
3543 3835
@@ -3552,7 +3844,7 @@ static int mvpp2_prs_mac_da_accept(struct mvpp2 *priv, int port,
3552 } 3844 }
3553 3845
3554 /* Update port mask */ 3846 /* Update port mask */
3555 mvpp2_prs_tcam_port_set(pe, port, add); 3847 mvpp2_prs_tcam_port_set(pe, port->id, add);
3556 3848
3557 /* Invalidate the entry if no ports are left enabled */ 3849 /* Invalidate the entry if no ports are left enabled */
3558 pmap = mvpp2_prs_tcam_port_map_get(pe); 3850 pmap = mvpp2_prs_tcam_port_map_get(pe);
@@ -3576,12 +3868,16 @@ static int mvpp2_prs_mac_da_accept(struct mvpp2 *priv, int port,
3576 mvpp2_prs_tcam_data_byte_set(pe, len, da[len], 0xff); 3868 mvpp2_prs_tcam_data_byte_set(pe, len, da[len], 0xff);
3577 3869
3578 /* Set result info bits */ 3870 /* Set result info bits */
3579 if (is_broadcast_ether_addr(da)) 3871 if (is_broadcast_ether_addr(da)) {
3580 ri = MVPP2_PRS_RI_L2_BCAST; 3872 ri = MVPP2_PRS_RI_L2_BCAST;
3581 else if (is_multicast_ether_addr(da)) 3873 } else if (is_multicast_ether_addr(da)) {
3582 ri = MVPP2_PRS_RI_L2_MCAST; 3874 ri = MVPP2_PRS_RI_L2_MCAST;
3583 else 3875 } else {
3584 ri = MVPP2_PRS_RI_L2_UCAST | MVPP2_PRS_RI_MAC_ME_MASK; 3876 ri = MVPP2_PRS_RI_L2_UCAST;
3877
3878 if (ether_addr_equal(da, port->dev->dev_addr))
3879 ri |= MVPP2_PRS_RI_MAC_ME_MASK;
3880 }
3585 3881
3586 mvpp2_prs_sram_ri_update(pe, ri, MVPP2_PRS_RI_L2_CAST_MASK | 3882 mvpp2_prs_sram_ri_update(pe, ri, MVPP2_PRS_RI_L2_CAST_MASK |
3587 MVPP2_PRS_RI_MAC_ME_MASK); 3883 MVPP2_PRS_RI_MAC_ME_MASK);
@@ -3608,13 +3904,12 @@ static int mvpp2_prs_update_mac_da(struct net_device *dev, const u8 *da)
3608 int err; 3904 int err;
3609 3905
3610 /* Remove old parser entry */ 3906 /* Remove old parser entry */
3611 err = mvpp2_prs_mac_da_accept(port->priv, port->id, dev->dev_addr, 3907 err = mvpp2_prs_mac_da_accept(port, dev->dev_addr, false);
3612 false);
3613 if (err) 3908 if (err)
3614 return err; 3909 return err;
3615 3910
3616 /* Add new parser entry */ 3911 /* Add new parser entry */
3617 err = mvpp2_prs_mac_da_accept(port->priv, port->id, da, true); 3912 err = mvpp2_prs_mac_da_accept(port, da, true);
3618 if (err) 3913 if (err)
3619 return err; 3914 return err;
3620 3915
@@ -3624,14 +3919,15 @@ static int mvpp2_prs_update_mac_da(struct net_device *dev, const u8 *da)
3624 return 0; 3919 return 0;
3625} 3920}
3626 3921
3627/* Delete all port's multicast simple (not range) entries */ 3922static void mvpp2_prs_mac_del_all(struct mvpp2_port *port)
3628static void mvpp2_prs_mcast_del_all(struct mvpp2 *priv, int port)
3629{ 3923{
3924 struct mvpp2 *priv = port->priv;
3630 struct mvpp2_prs_entry pe; 3925 struct mvpp2_prs_entry pe;
3926 unsigned long pmap;
3631 int index, tid; 3927 int index, tid;
3632 3928
3633 for (tid = MVPP2_PE_FIRST_FREE_TID; 3929 for (tid = MVPP2_PE_MAC_RANGE_START;
3634 tid <= MVPP2_PE_LAST_FREE_TID; tid++) { 3930 tid <= MVPP2_PE_MAC_RANGE_END; tid++) {
3635 unsigned char da[ETH_ALEN], da_mask[ETH_ALEN]; 3931 unsigned char da[ETH_ALEN], da_mask[ETH_ALEN];
3636 3932
3637 if (!priv->prs_shadow[tid].valid || 3933 if (!priv->prs_shadow[tid].valid ||
@@ -3639,18 +3935,29 @@ static void mvpp2_prs_mcast_del_all(struct mvpp2 *priv, int port)
3639 (priv->prs_shadow[tid].udf != MVPP2_PRS_UDF_MAC_DEF)) 3935 (priv->prs_shadow[tid].udf != MVPP2_PRS_UDF_MAC_DEF))
3640 continue; 3936 continue;
3641 3937
3642 /* Only simple mac entries */
3643 pe.index = tid; 3938 pe.index = tid;
3644 mvpp2_prs_hw_read(priv, &pe); 3939 mvpp2_prs_hw_read(priv, &pe);
3645 3940
3941 pmap = mvpp2_prs_tcam_port_map_get(&pe);
3942
3943 /* We only want entries active on this port */
3944 if (!test_bit(port->id, &pmap))
3945 continue;
3946
3646 /* Read mac addr from entry */ 3947 /* Read mac addr from entry */
3647 for (index = 0; index < ETH_ALEN; index++) 3948 for (index = 0; index < ETH_ALEN; index++)
3648 mvpp2_prs_tcam_data_byte_get(&pe, index, &da[index], 3949 mvpp2_prs_tcam_data_byte_get(&pe, index, &da[index],
3649 &da_mask[index]); 3950 &da_mask[index]);
3650 3951
3651 if (is_multicast_ether_addr(da) && !is_broadcast_ether_addr(da)) 3952 /* Special cases : Don't remove broadcast and port's own
3652 /* Delete this entry */ 3953 * address
3653 mvpp2_prs_mac_da_accept(priv, port, da, false); 3954 */
3955 if (is_broadcast_ether_addr(da) ||
3956 ether_addr_equal(da, port->dev->dev_addr))
3957 continue;
3958
3959 /* Remove entry from TCAM */
3960 mvpp2_prs_mac_da_accept(port, da, false);
3654 } 3961 }
3655} 3962}
3656 3963
@@ -3901,7 +4208,6 @@ static int mvpp2_bm_pool_create(struct platform_device *pdev,
3901 val |= MVPP2_BM_START_MASK; 4208 val |= MVPP2_BM_START_MASK;
3902 mvpp2_write(priv, MVPP2_BM_POOL_CTRL_REG(bm_pool->id), val); 4209 mvpp2_write(priv, MVPP2_BM_POOL_CTRL_REG(bm_pool->id), val);
3903 4210
3904 bm_pool->type = MVPP2_BM_FREE;
3905 bm_pool->size = size; 4211 bm_pool->size = size;
3906 bm_pool->pkt_size = 0; 4212 bm_pool->pkt_size = 0;
3907 bm_pool->buf_num = 0; 4213 bm_pool->buf_num = 0;
@@ -3954,11 +4260,17 @@ static void mvpp2_bm_bufs_get_addrs(struct device *dev, struct mvpp2 *priv,
3954 4260
3955/* Free all buffers from the pool */ 4261/* Free all buffers from the pool */
3956static void mvpp2_bm_bufs_free(struct device *dev, struct mvpp2 *priv, 4262static void mvpp2_bm_bufs_free(struct device *dev, struct mvpp2 *priv,
3957 struct mvpp2_bm_pool *bm_pool) 4263 struct mvpp2_bm_pool *bm_pool, int buf_num)
3958{ 4264{
3959 int i; 4265 int i;
3960 4266
3961 for (i = 0; i < bm_pool->buf_num; i++) { 4267 if (buf_num > bm_pool->buf_num) {
4268 WARN(1, "Pool does not have so many bufs pool(%d) bufs(%d)\n",
4269 bm_pool->id, buf_num);
4270 buf_num = bm_pool->buf_num;
4271 }
4272
4273 for (i = 0; i < buf_num; i++) {
3962 dma_addr_t buf_dma_addr; 4274 dma_addr_t buf_dma_addr;
3963 phys_addr_t buf_phys_addr; 4275 phys_addr_t buf_phys_addr;
3964 void *data; 4276 void *data;
@@ -3980,16 +4292,39 @@ static void mvpp2_bm_bufs_free(struct device *dev, struct mvpp2 *priv,
3980 bm_pool->buf_num -= i; 4292 bm_pool->buf_num -= i;
3981} 4293}
3982 4294
4295/* Check number of buffers in BM pool */
4296static int mvpp2_check_hw_buf_num(struct mvpp2 *priv, struct mvpp2_bm_pool *bm_pool)
4297{
4298 int buf_num = 0;
4299
4300 buf_num += mvpp2_read(priv, MVPP2_BM_POOL_PTRS_NUM_REG(bm_pool->id)) &
4301 MVPP22_BM_POOL_PTRS_NUM_MASK;
4302 buf_num += mvpp2_read(priv, MVPP2_BM_BPPI_PTRS_NUM_REG(bm_pool->id)) &
4303 MVPP2_BM_BPPI_PTR_NUM_MASK;
4304
4305 /* HW has one buffer ready which is not reflected in the counters */
4306 if (buf_num)
4307 buf_num += 1;
4308
4309 return buf_num;
4310}
4311
3983/* Cleanup pool */ 4312/* Cleanup pool */
3984static int mvpp2_bm_pool_destroy(struct platform_device *pdev, 4313static int mvpp2_bm_pool_destroy(struct platform_device *pdev,
3985 struct mvpp2 *priv, 4314 struct mvpp2 *priv,
3986 struct mvpp2_bm_pool *bm_pool) 4315 struct mvpp2_bm_pool *bm_pool)
3987{ 4316{
4317 int buf_num;
3988 u32 val; 4318 u32 val;
3989 4319
3990 mvpp2_bm_bufs_free(&pdev->dev, priv, bm_pool); 4320 buf_num = mvpp2_check_hw_buf_num(priv, bm_pool);
3991 if (bm_pool->buf_num) { 4321 mvpp2_bm_bufs_free(&pdev->dev, priv, bm_pool, buf_num);
3992 WARN(1, "cannot free all buffers in pool %d\n", bm_pool->id); 4322
4323 /* Check buffer counters after free */
4324 buf_num = mvpp2_check_hw_buf_num(priv, bm_pool);
4325 if (buf_num) {
4326 WARN(1, "cannot free all buffers in pool %d, buf_num left %d\n",
4327 bm_pool->id, bm_pool->buf_num);
3993 return 0; 4328 return 0;
3994 } 4329 }
3995 4330
@@ -4051,6 +4386,21 @@ static int mvpp2_bm_init(struct platform_device *pdev, struct mvpp2 *priv)
4051 return 0; 4386 return 0;
4052} 4387}
4053 4388
4389static void mvpp2_setup_bm_pool(void)
4390{
4391 /* Short pool */
4392 mvpp2_pools[MVPP2_BM_SHORT].buf_num = MVPP2_BM_SHORT_BUF_NUM;
4393 mvpp2_pools[MVPP2_BM_SHORT].pkt_size = MVPP2_BM_SHORT_PKT_SIZE;
4394
4395 /* Long pool */
4396 mvpp2_pools[MVPP2_BM_LONG].buf_num = MVPP2_BM_LONG_BUF_NUM;
4397 mvpp2_pools[MVPP2_BM_LONG].pkt_size = MVPP2_BM_LONG_PKT_SIZE;
4398
4399 /* Jumbo pool */
4400 mvpp2_pools[MVPP2_BM_JUMBO].buf_num = MVPP2_BM_JUMBO_BUF_NUM;
4401 mvpp2_pools[MVPP2_BM_JUMBO].pkt_size = MVPP2_BM_JUMBO_PKT_SIZE;
4402}
4403
4054/* Attach long pool to rxq */ 4404/* Attach long pool to rxq */
4055static void mvpp2_rxq_long_pool_set(struct mvpp2_port *port, 4405static void mvpp2_rxq_long_pool_set(struct mvpp2_port *port,
4056 int lrxq, int long_pool) 4406 int lrxq, int long_pool)
@@ -4189,13 +4539,11 @@ static int mvpp2_bm_bufs_add(struct mvpp2_port *port,
4189 bm_pool->buf_num += i; 4539 bm_pool->buf_num += i;
4190 4540
4191 netdev_dbg(port->dev, 4541 netdev_dbg(port->dev,
4192 "%s pool %d: pkt_size=%4d, buf_size=%4d, total_size=%4d\n", 4542 "pool %d: pkt_size=%4d, buf_size=%4d, total_size=%4d\n",
4193 bm_pool->type == MVPP2_BM_SWF_SHORT ? "short" : " long",
4194 bm_pool->id, bm_pool->pkt_size, buf_size, total_size); 4543 bm_pool->id, bm_pool->pkt_size, buf_size, total_size);
4195 4544
4196 netdev_dbg(port->dev, 4545 netdev_dbg(port->dev,
4197 "%s pool %d: %d of %d buffers added\n", 4546 "pool %d: %d of %d buffers added\n",
4198 bm_pool->type == MVPP2_BM_SWF_SHORT ? "short" : " long",
4199 bm_pool->id, i, buf_num); 4547 bm_pool->id, i, buf_num);
4200 return i; 4548 return i;
4201} 4549}
@@ -4204,25 +4552,20 @@ static int mvpp2_bm_bufs_add(struct mvpp2_port *port,
4204 * pool pointer on success 4552 * pool pointer on success
4205 */ 4553 */
4206static struct mvpp2_bm_pool * 4554static struct mvpp2_bm_pool *
4207mvpp2_bm_pool_use(struct mvpp2_port *port, int pool, enum mvpp2_bm_type type, 4555mvpp2_bm_pool_use(struct mvpp2_port *port, unsigned pool, int pkt_size)
4208 int pkt_size)
4209{ 4556{
4210 struct mvpp2_bm_pool *new_pool = &port->priv->bm_pools[pool]; 4557 struct mvpp2_bm_pool *new_pool = &port->priv->bm_pools[pool];
4211 int num; 4558 int num;
4212 4559
4213 if (new_pool->type != MVPP2_BM_FREE && new_pool->type != type) { 4560 if (pool >= MVPP2_BM_POOLS_NUM) {
4214 netdev_err(port->dev, "mixing pool types is forbidden\n"); 4561 netdev_err(port->dev, "Invalid pool %d\n", pool);
4215 return NULL; 4562 return NULL;
4216 } 4563 }
4217 4564
4218 if (new_pool->type == MVPP2_BM_FREE)
4219 new_pool->type = type;
4220
4221 /* Allocate buffers in case BM pool is used as long pool, but packet 4565 /* Allocate buffers in case BM pool is used as long pool, but packet
4222 * size doesn't match MTU or BM pool hasn't being used yet 4566 * size doesn't match MTU or BM pool hasn't being used yet
4223 */ 4567 */
4224 if (((type == MVPP2_BM_SWF_LONG) && (pkt_size > new_pool->pkt_size)) || 4568 if (new_pool->pkt_size == 0) {
4225 (new_pool->pkt_size == 0)) {
4226 int pkts_num; 4569 int pkts_num;
4227 4570
4228 /* Set default buffer number or free all the buffers in case 4571 /* Set default buffer number or free all the buffers in case
@@ -4230,12 +4573,10 @@ mvpp2_bm_pool_use(struct mvpp2_port *port, int pool, enum mvpp2_bm_type type,
4230 */ 4573 */
4231 pkts_num = new_pool->buf_num; 4574 pkts_num = new_pool->buf_num;
4232 if (pkts_num == 0) 4575 if (pkts_num == 0)
4233 pkts_num = type == MVPP2_BM_SWF_LONG ? 4576 pkts_num = mvpp2_pools[pool].buf_num;
4234 MVPP2_BM_LONG_BUF_NUM :
4235 MVPP2_BM_SHORT_BUF_NUM;
4236 else 4577 else
4237 mvpp2_bm_bufs_free(port->dev->dev.parent, 4578 mvpp2_bm_bufs_free(port->dev->dev.parent,
4238 port->priv, new_pool); 4579 port->priv, new_pool, pkts_num);
4239 4580
4240 new_pool->pkt_size = pkt_size; 4581 new_pool->pkt_size = pkt_size;
4241 new_pool->frag_size = 4582 new_pool->frag_size =
@@ -4261,16 +4602,28 @@ mvpp2_bm_pool_use(struct mvpp2_port *port, int pool, enum mvpp2_bm_type type,
4261static int mvpp2_swf_bm_pool_init(struct mvpp2_port *port) 4602static int mvpp2_swf_bm_pool_init(struct mvpp2_port *port)
4262{ 4603{
4263 int rxq; 4604 int rxq;
4605 enum mvpp2_bm_pool_log_num long_log_pool, short_log_pool;
4606
4607 /* If port pkt_size is higher than 1518B:
4608 * HW Long pool - SW Jumbo pool, HW Short pool - SW Long pool
4609 * else: HW Long pool - SW Long pool, HW Short pool - SW Short pool
4610 */
4611 if (port->pkt_size > MVPP2_BM_LONG_PKT_SIZE) {
4612 long_log_pool = MVPP2_BM_JUMBO;
4613 short_log_pool = MVPP2_BM_LONG;
4614 } else {
4615 long_log_pool = MVPP2_BM_LONG;
4616 short_log_pool = MVPP2_BM_SHORT;
4617 }
4264 4618
4265 if (!port->pool_long) { 4619 if (!port->pool_long) {
4266 port->pool_long = 4620 port->pool_long =
4267 mvpp2_bm_pool_use(port, MVPP2_BM_SWF_LONG_POOL(port->id), 4621 mvpp2_bm_pool_use(port, long_log_pool,
4268 MVPP2_BM_SWF_LONG, 4622 mvpp2_pools[long_log_pool].pkt_size);
4269 port->pkt_size);
4270 if (!port->pool_long) 4623 if (!port->pool_long)
4271 return -ENOMEM; 4624 return -ENOMEM;
4272 4625
4273 port->pool_long->port_map |= (1 << port->id); 4626 port->pool_long->port_map |= BIT(port->id);
4274 4627
4275 for (rxq = 0; rxq < port->nrxqs; rxq++) 4628 for (rxq = 0; rxq < port->nrxqs; rxq++)
4276 mvpp2_rxq_long_pool_set(port, rxq, port->pool_long->id); 4629 mvpp2_rxq_long_pool_set(port, rxq, port->pool_long->id);
@@ -4278,13 +4631,12 @@ static int mvpp2_swf_bm_pool_init(struct mvpp2_port *port)
4278 4631
4279 if (!port->pool_short) { 4632 if (!port->pool_short) {
4280 port->pool_short = 4633 port->pool_short =
4281 mvpp2_bm_pool_use(port, MVPP2_BM_SWF_SHORT_POOL, 4634 mvpp2_bm_pool_use(port, short_log_pool,
4282 MVPP2_BM_SWF_SHORT, 4635 mvpp2_pools[short_log_pool].pkt_size);
4283 MVPP2_BM_SHORT_PKT_SIZE);
4284 if (!port->pool_short) 4636 if (!port->pool_short)
4285 return -ENOMEM; 4637 return -ENOMEM;
4286 4638
4287 port->pool_short->port_map |= (1 << port->id); 4639 port->pool_short->port_map |= BIT(port->id);
4288 4640
4289 for (rxq = 0; rxq < port->nrxqs; rxq++) 4641 for (rxq = 0; rxq < port->nrxqs; rxq++)
4290 mvpp2_rxq_short_pool_set(port, rxq, 4642 mvpp2_rxq_short_pool_set(port, rxq,
@@ -4297,30 +4649,49 @@ static int mvpp2_swf_bm_pool_init(struct mvpp2_port *port)
4297static int mvpp2_bm_update_mtu(struct net_device *dev, int mtu) 4649static int mvpp2_bm_update_mtu(struct net_device *dev, int mtu)
4298{ 4650{
4299 struct mvpp2_port *port = netdev_priv(dev); 4651 struct mvpp2_port *port = netdev_priv(dev);
4300 struct mvpp2_bm_pool *port_pool = port->pool_long; 4652 enum mvpp2_bm_pool_log_num new_long_pool;
4301 int num, pkts_num = port_pool->buf_num;
4302 int pkt_size = MVPP2_RX_PKT_SIZE(mtu); 4653 int pkt_size = MVPP2_RX_PKT_SIZE(mtu);
4303 4654
4304 /* Update BM pool with new buffer size */ 4655 /* If port MTU is higher than 1518B:
4305 mvpp2_bm_bufs_free(dev->dev.parent, port->priv, port_pool); 4656 * HW Long pool - SW Jumbo pool, HW Short pool - SW Long pool
4306 if (port_pool->buf_num) { 4657 * else: HW Long pool - SW Long pool, HW Short pool - SW Short pool
4307 WARN(1, "cannot free all buffers in pool %d\n", port_pool->id); 4658 */
4308 return -EIO; 4659 if (pkt_size > MVPP2_BM_LONG_PKT_SIZE)
4309 } 4660 new_long_pool = MVPP2_BM_JUMBO;
4310 4661 else
4311 port_pool->pkt_size = pkt_size; 4662 new_long_pool = MVPP2_BM_LONG;
4312 port_pool->frag_size = SKB_DATA_ALIGN(MVPP2_RX_BUF_SIZE(pkt_size)) + 4663
4313 MVPP2_SKB_SHINFO_SIZE; 4664 if (new_long_pool != port->pool_long->id) {
4314 num = mvpp2_bm_bufs_add(port, port_pool, pkts_num); 4665 /* Remove port from old short & long pool */
4315 if (num != pkts_num) { 4666 port->pool_long = mvpp2_bm_pool_use(port, port->pool_long->id,
4316 WARN(1, "pool %d: %d of %d allocated\n", 4667 port->pool_long->pkt_size);
4317 port_pool->id, num, pkts_num); 4668 port->pool_long->port_map &= ~BIT(port->id);
4318 return -EIO; 4669 port->pool_long = NULL;
4670
4671 port->pool_short = mvpp2_bm_pool_use(port, port->pool_short->id,
4672 port->pool_short->pkt_size);
4673 port->pool_short->port_map &= ~BIT(port->id);
4674 port->pool_short = NULL;
4675
4676 port->pkt_size = pkt_size;
4677
4678 /* Add port to new short & long pool */
4679 mvpp2_swf_bm_pool_init(port);
4680
4681 /* Update L4 checksum when jumbo enable/disable on port */
4682 if (new_long_pool == MVPP2_BM_JUMBO && port->id != 0) {
4683 dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
4684 dev->hw_features &= ~(NETIF_F_IP_CSUM |
4685 NETIF_F_IPV6_CSUM);
4686 } else {
4687 dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
4688 dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
4689 }
4319 } 4690 }
4320 4691
4321 mvpp2_bm_pool_bufsize_set(port->priv, port_pool,
4322 MVPP2_RX_BUF_SIZE(port_pool->pkt_size));
4323 dev->mtu = mtu; 4692 dev->mtu = mtu;
4693 dev->wanted_features = dev->features;
4694
4324 netdev_update_features(dev); 4695 netdev_update_features(dev);
4325 return 0; 4696 return 0;
4326} 4697}
@@ -7007,15 +7378,14 @@ static int mvpp2_open(struct net_device *dev)
7007 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 7378 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
7008 int err; 7379 int err;
7009 7380
7010 err = mvpp2_prs_mac_da_accept(port->priv, port->id, mac_bcast, true); 7381 err = mvpp2_prs_mac_da_accept(port, mac_bcast, true);
7011 if (err) { 7382 if (err) {
7012 netdev_err(dev, "mvpp2_prs_mac_da_accept BC failed\n"); 7383 netdev_err(dev, "mvpp2_prs_mac_da_accept BC failed\n");
7013 return err; 7384 return err;
7014 } 7385 }
7015 err = mvpp2_prs_mac_da_accept(port->priv, port->id, 7386 err = mvpp2_prs_mac_da_accept(port, dev->dev_addr, true);
7016 dev->dev_addr, true);
7017 if (err) { 7387 if (err) {
7018 netdev_err(dev, "mvpp2_prs_mac_da_accept MC failed\n"); 7388 netdev_err(dev, "mvpp2_prs_mac_da_accept own addr failed\n");
7019 return err; 7389 return err;
7020 } 7390 }
7021 err = mvpp2_prs_tag_mode_set(port->priv, port->id, MVPP2_TAG_TYPE_MH); 7391 err = mvpp2_prs_tag_mode_set(port->priv, port->id, MVPP2_TAG_TYPE_MH);
@@ -7129,30 +7499,64 @@ static int mvpp2_stop(struct net_device *dev)
7129 return 0; 7499 return 0;
7130} 7500}
7131 7501
7502static int mvpp2_prs_mac_da_accept_list(struct mvpp2_port *port,
7503 struct netdev_hw_addr_list *list)
7504{
7505 struct netdev_hw_addr *ha;
7506 int ret;
7507
7508 netdev_hw_addr_list_for_each(ha, list) {
7509 ret = mvpp2_prs_mac_da_accept(port, ha->addr, true);
7510 if (ret)
7511 return ret;
7512 }
7513
7514 return 0;
7515}
7516
7517static void mvpp2_set_rx_promisc(struct mvpp2_port *port, bool enable)
7518{
7519 if (!enable && (port->dev->features & NETIF_F_HW_VLAN_CTAG_FILTER))
7520 mvpp2_prs_vid_enable_filtering(port);
7521 else
7522 mvpp2_prs_vid_disable_filtering(port);
7523
7524 mvpp2_prs_mac_promisc_set(port->priv, port->id,
7525 MVPP2_PRS_L2_UNI_CAST, enable);
7526
7527 mvpp2_prs_mac_promisc_set(port->priv, port->id,
7528 MVPP2_PRS_L2_MULTI_CAST, enable);
7529}
7530
7132static void mvpp2_set_rx_mode(struct net_device *dev) 7531static void mvpp2_set_rx_mode(struct net_device *dev)
7133{ 7532{
7134 struct mvpp2_port *port = netdev_priv(dev); 7533 struct mvpp2_port *port = netdev_priv(dev);
7135 struct mvpp2 *priv = port->priv; 7534
7136 struct netdev_hw_addr *ha; 7535 /* Clear the whole UC and MC list */
7137 int id = port->id; 7536 mvpp2_prs_mac_del_all(port);
7138 bool allmulti = dev->flags & IFF_ALLMULTI; 7537
7139 7538 if (dev->flags & IFF_PROMISC) {
7140retry: 7539 mvpp2_set_rx_promisc(port, true);
7141 mvpp2_prs_mac_promisc_set(priv, id, dev->flags & IFF_PROMISC); 7540 return;
7142 mvpp2_prs_mac_multi_set(priv, id, MVPP2_PE_MAC_MC_ALL, allmulti); 7541 }
7143 mvpp2_prs_mac_multi_set(priv, id, MVPP2_PE_MAC_MC_IP6, allmulti); 7542
7144 7543 mvpp2_set_rx_promisc(port, false);
7145 /* Remove all port->id's mcast enries */ 7544
7146 mvpp2_prs_mcast_del_all(priv, id); 7545 if (netdev_uc_count(dev) > MVPP2_PRS_MAC_UC_FILT_MAX ||
7147 7546 mvpp2_prs_mac_da_accept_list(port, &dev->uc))
7148 if (!allmulti) { 7547 mvpp2_prs_mac_promisc_set(port->priv, port->id,
7149 netdev_for_each_mc_addr(ha, dev) { 7548 MVPP2_PRS_L2_UNI_CAST, true);
7150 if (mvpp2_prs_mac_da_accept(priv, id, ha->addr, true)) { 7549
7151 allmulti = true; 7550 if (dev->flags & IFF_ALLMULTI) {
7152 goto retry; 7551 mvpp2_prs_mac_promisc_set(port->priv, port->id,
7153 } 7552 MVPP2_PRS_L2_MULTI_CAST, true);
7154 } 7553 return;
7155 } 7554 }
7555
7556 if (netdev_mc_count(dev) > MVPP2_PRS_MAC_MC_FILT_MAX ||
7557 mvpp2_prs_mac_da_accept_list(port, &dev->mc))
7558 mvpp2_prs_mac_promisc_set(port->priv, port->id,
7559 MVPP2_PRS_L2_MULTI_CAST, true);
7156} 7560}
7157 7561
7158static int mvpp2_set_mac_address(struct net_device *dev, void *p) 7562static int mvpp2_set_mac_address(struct net_device *dev, void *p)
@@ -7292,6 +7696,48 @@ static int mvpp2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
7292 return ret; 7696 return ret;
7293} 7697}
7294 7698
7699static int mvpp2_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid)
7700{
7701 struct mvpp2_port *port = netdev_priv(dev);
7702 int ret;
7703
7704 ret = mvpp2_prs_vid_entry_add(port, vid);
7705 if (ret)
7706 netdev_err(dev, "rx-vlan-filter offloading cannot accept more than %d VIDs per port\n",
7707 MVPP2_PRS_VLAN_FILT_MAX - 1);
7708 return ret;
7709}
7710
7711static int mvpp2_vlan_rx_kill_vid(struct net_device *dev, __be16 proto, u16 vid)
7712{
7713 struct mvpp2_port *port = netdev_priv(dev);
7714
7715 mvpp2_prs_vid_entry_remove(port, vid);
7716 return 0;
7717}
7718
7719static int mvpp2_set_features(struct net_device *dev,
7720 netdev_features_t features)
7721{
7722 netdev_features_t changed = dev->features ^ features;
7723 struct mvpp2_port *port = netdev_priv(dev);
7724
7725 if (changed & NETIF_F_HW_VLAN_CTAG_FILTER) {
7726 if (features & NETIF_F_HW_VLAN_CTAG_FILTER) {
7727 mvpp2_prs_vid_enable_filtering(port);
7728 } else {
7729 /* Invalidate all registered VID filters for this
7730 * port
7731 */
7732 mvpp2_prs_vid_remove_all(port);
7733
7734 mvpp2_prs_vid_disable_filtering(port);
7735 }
7736 }
7737
7738 return 0;
7739}
7740
7295/* Ethtool methods */ 7741/* Ethtool methods */
7296 7742
7297/* Set interrupt coalescing for ethtools */ 7743/* Set interrupt coalescing for ethtools */
@@ -7433,6 +7879,9 @@ static const struct net_device_ops mvpp2_netdev_ops = {
7433 .ndo_change_mtu = mvpp2_change_mtu, 7879 .ndo_change_mtu = mvpp2_change_mtu,
7434 .ndo_get_stats64 = mvpp2_get_stats64, 7880 .ndo_get_stats64 = mvpp2_get_stats64,
7435 .ndo_do_ioctl = mvpp2_ioctl, 7881 .ndo_do_ioctl = mvpp2_ioctl,
7882 .ndo_vlan_rx_add_vid = mvpp2_vlan_rx_add_vid,
7883 .ndo_vlan_rx_kill_vid = mvpp2_vlan_rx_kill_vid,
7884 .ndo_set_features = mvpp2_set_features,
7436}; 7885};
7437 7886
7438static const struct ethtool_ops mvpp2_eth_tool_ops = { 7887static const struct ethtool_ops mvpp2_eth_tool_ops = {
@@ -7943,16 +8392,25 @@ static int mvpp2_port_probe(struct platform_device *pdev,
7943 } 8392 }
7944 } 8393 }
7945 8394
7946 features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO; 8395 features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
8396 NETIF_F_TSO;
7947 dev->features = features | NETIF_F_RXCSUM; 8397 dev->features = features | NETIF_F_RXCSUM;
7948 dev->hw_features |= features | NETIF_F_RXCSUM | NETIF_F_GRO; 8398 dev->hw_features |= features | NETIF_F_RXCSUM | NETIF_F_GRO |
8399 NETIF_F_HW_VLAN_CTAG_FILTER;
8400
8401 if (port->pool_long->id == MVPP2_BM_JUMBO && port->id != 0) {
8402 dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
8403 dev->hw_features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
8404 }
8405
7949 dev->vlan_features |= features; 8406 dev->vlan_features |= features;
7950 dev->gso_max_segs = MVPP2_MAX_TSO_SEGS; 8407 dev->gso_max_segs = MVPP2_MAX_TSO_SEGS;
8408 dev->priv_flags |= IFF_UNICAST_FLT;
7951 8409
7952 /* MTU range: 68 - 9676 */ 8410 /* MTU range: 68 - 9704 */
7953 dev->min_mtu = ETH_MIN_MTU; 8411 dev->min_mtu = ETH_MIN_MTU;
7954 /* 9676 == 9700 - 20 and rounding to 8 */ 8412 /* 9704 == 9728 - 20 and rounding to 8 */
7955 dev->max_mtu = 9676; 8413 dev->max_mtu = MVPP2_BM_JUMBO_PKT_SIZE;
7956 8414
7957 err = register_netdev(dev); 8415 err = register_netdev(dev);
7958 if (err < 0) { 8416 if (err < 0) {
@@ -8083,14 +8541,25 @@ static void mvpp22_rx_fifo_init(struct mvpp2 *priv)
8083 mvpp2_write(priv, MVPP2_RX_FIFO_INIT_REG, 0x1); 8541 mvpp2_write(priv, MVPP2_RX_FIFO_INIT_REG, 0x1);
8084} 8542}
8085 8543
8086/* Initialize Tx FIFO's */ 8544/* Initialize Tx FIFO's: the total FIFO size is 19kB on PPv2.2 and 10G
8545 * interfaces must have a Tx FIFO size of 10kB. As only port 0 can do 10G,
8546 * configure its Tx FIFO size to 10kB and the others ports Tx FIFO size to 3kB.
8547 */
8087static void mvpp22_tx_fifo_init(struct mvpp2 *priv) 8548static void mvpp22_tx_fifo_init(struct mvpp2 *priv)
8088{ 8549{
8089 int port; 8550 int port, size, thrs;
8090 8551
8091 for (port = 0; port < MVPP2_MAX_PORTS; port++) 8552 for (port = 0; port < MVPP2_MAX_PORTS; port++) {
8092 mvpp2_write(priv, MVPP22_TX_FIFO_SIZE_REG(port), 8553 if (port == 0) {
8093 MVPP22_TX_FIFO_DATA_SIZE_3KB); 8554 size = MVPP22_TX_FIFO_DATA_SIZE_10KB;
8555 thrs = MVPP2_TX_FIFO_THRESHOLD_10KB;
8556 } else {
8557 size = MVPP22_TX_FIFO_DATA_SIZE_3KB;
8558 thrs = MVPP2_TX_FIFO_THRESHOLD_3KB;
8559 }
8560 mvpp2_write(priv, MVPP22_TX_FIFO_SIZE_REG(port), size);
8561 mvpp2_write(priv, MVPP22_TX_FIFO_THRESH_REG(port), thrs);
8562 }
8094} 8563}
8095 8564
8096static void mvpp2_axi_init(struct mvpp2 *priv) 8565static void mvpp2_axi_init(struct mvpp2 *priv)
@@ -8284,6 +8753,8 @@ static int mvpp2_probe(struct platform_device *pdev)
8284 priv->sysctrl_base = NULL; 8753 priv->sysctrl_base = NULL;
8285 } 8754 }
8286 8755
8756 mvpp2_setup_bm_pool();
8757
8287 for (i = 0; i < MVPP2_MAX_THREADS; i++) { 8758 for (i = 0; i < MVPP2_MAX_THREADS; i++) {
8288 u32 addr_space_sz; 8759 u32 addr_space_sz;
8289 8760
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
index ebc1f566a4d9..9a7a2f05ab35 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
@@ -199,6 +199,10 @@ static const char main_strings[][ETH_GSTRING_LEN] = {
199 "rx_xdp_drop", 199 "rx_xdp_drop",
200 "rx_xdp_tx", 200 "rx_xdp_tx",
201 "rx_xdp_tx_full", 201 "rx_xdp_tx_full",
202
203 /* phy statistics */
204 "rx_packets_phy", "rx_bytes_phy",
205 "tx_packets_phy", "tx_bytes_phy",
202}; 206};
203 207
204static const char mlx4_en_test_names[][ETH_GSTRING_LEN]= { 208static const char mlx4_en_test_names[][ETH_GSTRING_LEN]= {
@@ -411,6 +415,10 @@ static void mlx4_en_get_ethtool_stats(struct net_device *dev,
411 if (bitmap_iterator_test(&it)) 415 if (bitmap_iterator_test(&it))
412 data[index++] = ((unsigned long *)&priv->xdp_stats)[i]; 416 data[index++] = ((unsigned long *)&priv->xdp_stats)[i];
413 417
418 for (i = 0; i < NUM_PHY_STATS; i++, bitmap_iterator_inc(&it))
419 if (bitmap_iterator_test(&it))
420 data[index++] = ((unsigned long *)&priv->phy_stats)[i];
421
414 for (i = 0; i < priv->tx_ring_num[TX]; i++) { 422 for (i = 0; i < priv->tx_ring_num[TX]; i++) {
415 data[index++] = priv->tx_ring[TX][i]->packets; 423 data[index++] = priv->tx_ring[TX][i]->packets;
416 data[index++] = priv->tx_ring[TX][i]->bytes; 424 data[index++] = priv->tx_ring[TX][i]->bytes;
@@ -490,6 +498,12 @@ static void mlx4_en_get_strings(struct net_device *dev,
490 strcpy(data + (index++) * ETH_GSTRING_LEN, 498 strcpy(data + (index++) * ETH_GSTRING_LEN,
491 main_strings[strings]); 499 main_strings[strings]);
492 500
501 for (i = 0; i < NUM_PHY_STATS; i++, strings++,
502 bitmap_iterator_inc(&it))
503 if (bitmap_iterator_test(&it))
504 strcpy(data + (index++) * ETH_GSTRING_LEN,
505 main_strings[strings]);
506
493 for (i = 0; i < priv->tx_ring_num[TX]; i++) { 507 for (i = 0; i < priv->tx_ring_num[TX]; i++) {
494 sprintf(data + (index++) * ETH_GSTRING_LEN, 508 sprintf(data + (index++) * ETH_GSTRING_LEN,
495 "tx%d_packets", i); 509 "tx%d_packets", i);
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index 8fc51bc29003..e0adac4a9a19 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -3256,6 +3256,10 @@ void mlx4_en_set_stats_bitmap(struct mlx4_dev *dev,
3256 3256
3257 bitmap_set(stats_bitmap->bitmap, last_i, NUM_XDP_STATS); 3257 bitmap_set(stats_bitmap->bitmap, last_i, NUM_XDP_STATS);
3258 last_i += NUM_XDP_STATS; 3258 last_i += NUM_XDP_STATS;
3259
3260 if (!mlx4_is_slave(dev))
3261 bitmap_set(stats_bitmap->bitmap, last_i, NUM_PHY_STATS);
3262 last_i += NUM_PHY_STATS;
3259} 3263}
3260 3264
3261int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, 3265int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
@@ -3630,10 +3634,6 @@ int mlx4_en_reset_config(struct net_device *dev,
3630 mlx4_en_stop_port(dev, 1); 3634 mlx4_en_stop_port(dev, 1);
3631 } 3635 }
3632 3636
3633 en_warn(priv, "Changing device configuration rx filter(%x) rx vlan(%x)\n",
3634 ts_config.rx_filter,
3635 !!(features & NETIF_F_HW_VLAN_CTAG_RX));
3636
3637 mlx4_en_safe_replace_resources(priv, tmp); 3637 mlx4_en_safe_replace_resources(priv, tmp);
3638 3638
3639 if (DEV_FEATURE_CHANGED(dev, features, NETIF_F_HW_VLAN_CTAG_RX)) { 3639 if (DEV_FEATURE_CHANGED(dev, features, NETIF_F_HW_VLAN_CTAG_RX)) {
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_port.c b/drivers/net/ethernet/mellanox/mlx4/en_port.c
index 1fa4849a6f56..0158b88bea5b 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_port.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_port.c
@@ -275,19 +275,31 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset)
275 priv->port_stats.xmit_more += READ_ONCE(ring->xmit_more); 275 priv->port_stats.xmit_more += READ_ONCE(ring->xmit_more);
276 } 276 }
277 277
278 if (mlx4_is_master(mdev->dev)) { 278 if (!mlx4_is_slave(mdev->dev)) {
279 stats->rx_packets = en_stats_adder(&mlx4_en_stats->RTOT_prio_0, 279 struct mlx4_en_phy_stats *p_stats = &priv->phy_stats;
280 &mlx4_en_stats->RTOT_prio_1, 280
281 NUM_PRIORITIES); 281 p_stats->rx_packets_phy =
282 stats->tx_packets = en_stats_adder(&mlx4_en_stats->TTOT_prio_0, 282 en_stats_adder(&mlx4_en_stats->RTOT_prio_0,
283 &mlx4_en_stats->TTOT_prio_1, 283 &mlx4_en_stats->RTOT_prio_1,
284 NUM_PRIORITIES); 284 NUM_PRIORITIES);
285 stats->rx_bytes = en_stats_adder(&mlx4_en_stats->ROCT_prio_0, 285 p_stats->tx_packets_phy =
286 &mlx4_en_stats->ROCT_prio_1, 286 en_stats_adder(&mlx4_en_stats->TTOT_prio_0,
287 NUM_PRIORITIES); 287 &mlx4_en_stats->TTOT_prio_1,
288 stats->tx_bytes = en_stats_adder(&mlx4_en_stats->TOCT_prio_0, 288 NUM_PRIORITIES);
289 &mlx4_en_stats->TOCT_prio_1, 289 p_stats->rx_bytes_phy =
290 NUM_PRIORITIES); 290 en_stats_adder(&mlx4_en_stats->ROCT_prio_0,
291 &mlx4_en_stats->ROCT_prio_1,
292 NUM_PRIORITIES);
293 p_stats->tx_bytes_phy =
294 en_stats_adder(&mlx4_en_stats->TOCT_prio_0,
295 &mlx4_en_stats->TOCT_prio_1,
296 NUM_PRIORITIES);
297 if (mlx4_is_master(mdev->dev)) {
298 stats->rx_packets = p_stats->rx_packets_phy;
299 stats->tx_packets = p_stats->tx_packets_phy;
300 stats->rx_bytes = p_stats->rx_bytes_phy;
301 stats->tx_bytes = p_stats->tx_bytes_phy;
302 }
291 } 303 }
292 304
293 /* net device stats */ 305 /* net device stats */
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
index b4d144e67514..05787efef492 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
@@ -291,13 +291,10 @@ int mlx4_en_create_rx_ring(struct mlx4_en_priv *priv,
291 291
292 tmp = size * roundup_pow_of_two(MLX4_EN_MAX_RX_FRAGS * 292 tmp = size * roundup_pow_of_two(MLX4_EN_MAX_RX_FRAGS *
293 sizeof(struct mlx4_en_rx_alloc)); 293 sizeof(struct mlx4_en_rx_alloc));
294 ring->rx_info = vzalloc_node(tmp, node); 294 ring->rx_info = kvzalloc_node(tmp, GFP_KERNEL, node);
295 if (!ring->rx_info) { 295 if (!ring->rx_info) {
296 ring->rx_info = vzalloc(tmp); 296 err = -ENOMEM;
297 if (!ring->rx_info) { 297 goto err_xdp_info;
298 err = -ENOMEM;
299 goto err_xdp_info;
300 }
301 } 298 }
302 299
303 en_dbg(DRV, priv, "Allocated rx_info ring at addr:%p size:%d\n", 300 en_dbg(DRV, priv, "Allocated rx_info ring at addr:%p size:%d\n",
@@ -318,7 +315,7 @@ int mlx4_en_create_rx_ring(struct mlx4_en_priv *priv,
318 return 0; 315 return 0;
319 316
320err_info: 317err_info:
321 vfree(ring->rx_info); 318 kvfree(ring->rx_info);
322 ring->rx_info = NULL; 319 ring->rx_info = NULL;
323err_xdp_info: 320err_xdp_info:
324 xdp_rxq_info_unreg(&ring->xdp_rxq); 321 xdp_rxq_info_unreg(&ring->xdp_rxq);
@@ -447,7 +444,7 @@ void mlx4_en_destroy_rx_ring(struct mlx4_en_priv *priv,
447 bpf_prog_put(old_prog); 444 bpf_prog_put(old_prog);
448 xdp_rxq_info_unreg(&ring->xdp_rxq); 445 xdp_rxq_info_unreg(&ring->xdp_rxq);
449 mlx4_free_hwq_res(mdev->dev, &ring->wqres, size * stride + TXBB_SIZE); 446 mlx4_free_hwq_res(mdev->dev, &ring->wqres, size * stride + TXBB_SIZE);
450 vfree(ring->rx_info); 447 kvfree(ring->rx_info);
451 ring->rx_info = NULL; 448 ring->rx_info = NULL;
452 kfree(ring); 449 kfree(ring);
453 *pring = NULL; 450 *pring = NULL;
@@ -649,6 +646,12 @@ static int check_csum(struct mlx4_cqe *cqe, struct sk_buff *skb, void *va,
649 return get_fixed_ipv4_csum(hw_checksum, skb, hdr); 646 return get_fixed_ipv4_csum(hw_checksum, skb, hdr);
650} 647}
651 648
649#if IS_ENABLED(CONFIG_IPV6)
650#define MLX4_CQE_STATUS_IP_ANY (MLX4_CQE_STATUS_IPV4 | MLX4_CQE_STATUS_IPV6)
651#else
652#define MLX4_CQE_STATUS_IP_ANY (MLX4_CQE_STATUS_IPV4)
653#endif
654
652int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int budget) 655int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int budget)
653{ 656{
654 struct mlx4_en_priv *priv = netdev_priv(dev); 657 struct mlx4_en_priv *priv = netdev_priv(dev);
@@ -662,12 +665,9 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
662 int polled = 0; 665 int polled = 0;
663 int index; 666 int index;
664 667
665 if (unlikely(!priv->port_up)) 668 if (unlikely(!priv->port_up || budget <= 0))
666 return 0; 669 return 0;
667 670
668 if (unlikely(budget <= 0))
669 return polled;
670
671 ring = priv->rx_ring[cq_ring]; 671 ring = priv->rx_ring[cq_ring];
672 672
673 /* Protect accesses to: ring->xdp_prog, priv->mac_hash list */ 673 /* Protect accesses to: ring->xdp_prog, priv->mac_hash list */
@@ -838,12 +838,7 @@ xdp_drop_no_cnt:
838 ring->csum_ok++; 838 ring->csum_ok++;
839 } else { 839 } else {
840 if (!(priv->flags & MLX4_EN_FLAG_RX_CSUM_NON_TCP_UDP && 840 if (!(priv->flags & MLX4_EN_FLAG_RX_CSUM_NON_TCP_UDP &&
841 (cqe->status & cpu_to_be16(MLX4_CQE_STATUS_IPV4 | 841 (cqe->status & cpu_to_be16(MLX4_CQE_STATUS_IP_ANY))))
842#if IS_ENABLED(CONFIG_IPV6)
843 MLX4_CQE_STATUS_IPV6))))
844#else
845 0))))
846#endif
847 goto csum_none; 842 goto csum_none;
848 if (check_csum(cqe, skb, va, dev->features)) 843 if (check_csum(cqe, skb, va, dev->features))
849 goto csum_none; 844 goto csum_none;
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
index f470ae37d937..f7c81133594f 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
@@ -608,6 +608,7 @@ struct mlx4_en_priv {
608 struct mlx4_en_flow_stats_tx tx_flowstats; 608 struct mlx4_en_flow_stats_tx tx_flowstats;
609 struct mlx4_en_port_stats port_stats; 609 struct mlx4_en_port_stats port_stats;
610 struct mlx4_en_xdp_stats xdp_stats; 610 struct mlx4_en_xdp_stats xdp_stats;
611 struct mlx4_en_phy_stats phy_stats;
611 struct mlx4_en_stats_bitmap stats_bitmap; 612 struct mlx4_en_stats_bitmap stats_bitmap;
612 struct list_head mc_list; 613 struct list_head mc_list;
613 struct list_head curr_list; 614 struct list_head curr_list;
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_stats.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_stats.h
index aab28eb27a30..86b6051da8ec 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_stats.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_stats.h
@@ -63,6 +63,14 @@ struct mlx4_en_xdp_stats {
63#define NUM_XDP_STATS 3 63#define NUM_XDP_STATS 3
64}; 64};
65 65
66struct mlx4_en_phy_stats {
67 unsigned long rx_packets_phy;
68 unsigned long rx_bytes_phy;
69 unsigned long tx_packets_phy;
70 unsigned long tx_bytes_phy;
71#define NUM_PHY_STATS 4
72};
73
66#define NUM_MAIN_STATS 21 74#define NUM_MAIN_STATS 21
67 75
68#define MLX4_NUM_PRIORITIES 8 76#define MLX4_NUM_PRIORITIES 8
@@ -116,7 +124,7 @@ enum {
116 124
117#define NUM_ALL_STATS (NUM_MAIN_STATS + NUM_PORT_STATS + NUM_PKT_STATS + \ 125#define NUM_ALL_STATS (NUM_MAIN_STATS + NUM_PORT_STATS + NUM_PKT_STATS + \
118 NUM_FLOW_STATS + NUM_PERF_STATS + NUM_PF_STATS + \ 126 NUM_FLOW_STATS + NUM_PERF_STATS + NUM_PF_STATS + \
119 NUM_XDP_STATS) 127 NUM_XDP_STATS + NUM_PHY_STATS)
120 128
121#define MLX4_FIND_NETDEV_STAT(n) (offsetof(struct net_device_stats, n) / \ 129#define MLX4_FIND_NETDEV_STAT(n) (offsetof(struct net_device_stats, n) / \
122 sizeof(((struct net_device_stats *)0)->n)) 130 sizeof(((struct net_device_stats *)0)->n))
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.c
index 53e69edaedde..9f1b1939716a 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.c
@@ -37,24 +37,11 @@
37#include "mlx5_core.h" 37#include "mlx5_core.h"
38#include "fpga/ipsec.h" 38#include "fpga/ipsec.h"
39 39
40void *mlx5_accel_ipsec_sa_cmd_exec(struct mlx5_core_dev *mdev,
41 struct mlx5_accel_ipsec_sa *cmd)
42{
43 if (!MLX5_IPSEC_DEV(mdev))
44 return ERR_PTR(-EOPNOTSUPP);
45
46 return mlx5_fpga_ipsec_sa_cmd_exec(mdev, cmd);
47}
48
49int mlx5_accel_ipsec_sa_cmd_wait(void *ctx)
50{
51 return mlx5_fpga_ipsec_sa_cmd_wait(ctx);
52}
53
54u32 mlx5_accel_ipsec_device_caps(struct mlx5_core_dev *mdev) 40u32 mlx5_accel_ipsec_device_caps(struct mlx5_core_dev *mdev)
55{ 41{
56 return mlx5_fpga_ipsec_device_caps(mdev); 42 return mlx5_fpga_ipsec_device_caps(mdev);
57} 43}
44EXPORT_SYMBOL_GPL(mlx5_accel_ipsec_device_caps);
58 45
59unsigned int mlx5_accel_ipsec_counters_count(struct mlx5_core_dev *mdev) 46unsigned int mlx5_accel_ipsec_counters_count(struct mlx5_core_dev *mdev)
60{ 47{
@@ -67,6 +54,21 @@ int mlx5_accel_ipsec_counters_read(struct mlx5_core_dev *mdev, u64 *counters,
67 return mlx5_fpga_ipsec_counters_read(mdev, counters, count); 54 return mlx5_fpga_ipsec_counters_read(mdev, counters, count);
68} 55}
69 56
57void *mlx5_accel_esp_create_hw_context(struct mlx5_core_dev *mdev,
58 struct mlx5_accel_esp_xfrm *xfrm,
59 const __be32 saddr[4],
60 const __be32 daddr[4],
61 const __be32 spi, bool is_ipv6)
62{
63 return mlx5_fpga_ipsec_create_sa_ctx(mdev, xfrm, saddr, daddr,
64 spi, is_ipv6);
65}
66
67void mlx5_accel_esp_free_hw_context(void *context)
68{
69 mlx5_fpga_ipsec_delete_sa_ctx(context);
70}
71
70int mlx5_accel_ipsec_init(struct mlx5_core_dev *mdev) 72int mlx5_accel_ipsec_init(struct mlx5_core_dev *mdev)
71{ 73{
72 return mlx5_fpga_ipsec_init(mdev); 74 return mlx5_fpga_ipsec_init(mdev);
@@ -76,3 +78,32 @@ void mlx5_accel_ipsec_cleanup(struct mlx5_core_dev *mdev)
76{ 78{
77 mlx5_fpga_ipsec_cleanup(mdev); 79 mlx5_fpga_ipsec_cleanup(mdev);
78} 80}
81
82struct mlx5_accel_esp_xfrm *
83mlx5_accel_esp_create_xfrm(struct mlx5_core_dev *mdev,
84 const struct mlx5_accel_esp_xfrm_attrs *attrs,
85 u32 flags)
86{
87 struct mlx5_accel_esp_xfrm *xfrm;
88
89 xfrm = mlx5_fpga_esp_create_xfrm(mdev, attrs, flags);
90 if (IS_ERR(xfrm))
91 return xfrm;
92
93 xfrm->mdev = mdev;
94 return xfrm;
95}
96EXPORT_SYMBOL_GPL(mlx5_accel_esp_create_xfrm);
97
98void mlx5_accel_esp_destroy_xfrm(struct mlx5_accel_esp_xfrm *xfrm)
99{
100 mlx5_fpga_esp_destroy_xfrm(xfrm);
101}
102EXPORT_SYMBOL_GPL(mlx5_accel_esp_destroy_xfrm);
103
104int mlx5_accel_esp_modify_xfrm(struct mlx5_accel_esp_xfrm *xfrm,
105 const struct mlx5_accel_esp_xfrm_attrs *attrs)
106{
107 return mlx5_fpga_esp_modify_xfrm(xfrm, attrs);
108}
109EXPORT_SYMBOL_GPL(mlx5_accel_esp_modify_xfrm);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.h b/drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.h
index d6e20fea9554..024dbd22a89b 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.h
@@ -34,89 +34,25 @@
34#ifndef __MLX5_ACCEL_IPSEC_H__ 34#ifndef __MLX5_ACCEL_IPSEC_H__
35#define __MLX5_ACCEL_IPSEC_H__ 35#define __MLX5_ACCEL_IPSEC_H__
36 36
37#ifdef CONFIG_MLX5_ACCEL
38
39#include <linux/mlx5/driver.h> 37#include <linux/mlx5/driver.h>
38#include <linux/mlx5/accel.h>
40 39
41enum { 40#ifdef CONFIG_MLX5_ACCEL
42 MLX5_ACCEL_IPSEC_DEVICE = BIT(1),
43 MLX5_ACCEL_IPSEC_IPV6 = BIT(2),
44 MLX5_ACCEL_IPSEC_ESP = BIT(3),
45 MLX5_ACCEL_IPSEC_LSO = BIT(4),
46};
47
48#define MLX5_IPSEC_SADB_IP_AH BIT(7)
49#define MLX5_IPSEC_SADB_IP_ESP BIT(6)
50#define MLX5_IPSEC_SADB_SA_VALID BIT(5)
51#define MLX5_IPSEC_SADB_SPI_EN BIT(4)
52#define MLX5_IPSEC_SADB_DIR_SX BIT(3)
53#define MLX5_IPSEC_SADB_IPV6 BIT(2)
54
55enum {
56 MLX5_IPSEC_CMD_ADD_SA = 0,
57 MLX5_IPSEC_CMD_DEL_SA = 1,
58};
59
60enum mlx5_accel_ipsec_enc_mode {
61 MLX5_IPSEC_SADB_MODE_NONE = 0,
62 MLX5_IPSEC_SADB_MODE_AES_GCM_128_AUTH_128 = 1,
63 MLX5_IPSEC_SADB_MODE_AES_GCM_256_AUTH_128 = 3,
64};
65 41
66#define MLX5_IPSEC_DEV(mdev) (mlx5_accel_ipsec_device_caps(mdev) & \ 42#define MLX5_IPSEC_DEV(mdev) (mlx5_accel_ipsec_device_caps(mdev) & \
67 MLX5_ACCEL_IPSEC_DEVICE) 43 MLX5_ACCEL_IPSEC_CAP_DEVICE)
68
69struct mlx5_accel_ipsec_sa {
70 __be32 cmd;
71 u8 key_enc[32];
72 u8 key_auth[32];
73 __be32 sip[4];
74 __be32 dip[4];
75 union {
76 struct {
77 __be32 reserved;
78 u8 salt_iv[8];
79 __be32 salt;
80 } __packed gcm;
81 struct {
82 u8 salt[16];
83 } __packed cbc;
84 };
85 __be32 spi;
86 __be32 sw_sa_handle;
87 __be16 tfclen;
88 u8 enc_mode;
89 u8 sip_masklen;
90 u8 dip_masklen;
91 u8 flags;
92 u8 reserved[2];
93} __packed;
94
95/**
96 * mlx5_accel_ipsec_sa_cmd_exec - Execute an IPSec SADB command
97 * @mdev: mlx5 device
98 * @cmd: command to execute
99 * May be called from atomic context. Returns context pointer, or error
100 * Caller must eventually call mlx5_accel_ipsec_sa_cmd_wait from non-atomic
101 * context, to cleanup the context pointer
102 */
103void *mlx5_accel_ipsec_sa_cmd_exec(struct mlx5_core_dev *mdev,
104 struct mlx5_accel_ipsec_sa *cmd);
105
106/**
107 * mlx5_accel_ipsec_sa_cmd_wait - Wait for command execution completion
108 * @context: Context pointer returned from call to mlx5_accel_ipsec_sa_cmd_exec
109 * Sleeps (killable) until command execution is complete.
110 * Returns the command result, or -EINTR if killed
111 */
112int mlx5_accel_ipsec_sa_cmd_wait(void *context);
113
114u32 mlx5_accel_ipsec_device_caps(struct mlx5_core_dev *mdev);
115 44
116unsigned int mlx5_accel_ipsec_counters_count(struct mlx5_core_dev *mdev); 45unsigned int mlx5_accel_ipsec_counters_count(struct mlx5_core_dev *mdev);
117int mlx5_accel_ipsec_counters_read(struct mlx5_core_dev *mdev, u64 *counters, 46int mlx5_accel_ipsec_counters_read(struct mlx5_core_dev *mdev, u64 *counters,
118 unsigned int count); 47 unsigned int count);
119 48
49void *mlx5_accel_esp_create_hw_context(struct mlx5_core_dev *mdev,
50 struct mlx5_accel_esp_xfrm *xfrm,
51 const __be32 saddr[4],
52 const __be32 daddr[4],
53 const __be32 spi, bool is_ipv6);
54void mlx5_accel_esp_free_hw_context(void *context);
55
120int mlx5_accel_ipsec_init(struct mlx5_core_dev *mdev); 56int mlx5_accel_ipsec_init(struct mlx5_core_dev *mdev);
121void mlx5_accel_ipsec_cleanup(struct mlx5_core_dev *mdev); 57void mlx5_accel_ipsec_cleanup(struct mlx5_core_dev *mdev);
122 58
@@ -124,6 +60,20 @@ void mlx5_accel_ipsec_cleanup(struct mlx5_core_dev *mdev);
124 60
125#define MLX5_IPSEC_DEV(mdev) false 61#define MLX5_IPSEC_DEV(mdev) false
126 62
63static inline void *
64mlx5_accel_esp_create_hw_context(struct mlx5_core_dev *mdev,
65 struct mlx5_accel_esp_xfrm *xfrm,
66 const __be32 saddr[4],
67 const __be32 daddr[4],
68 const __be32 spi, bool is_ipv6)
69{
70 return NULL;
71}
72
73static inline void mlx5_accel_esp_free_hw_context(void *context)
74{
75}
76
127static inline int mlx5_accel_ipsec_init(struct mlx5_core_dev *mdev) 77static inline int mlx5_accel_ipsec_init(struct mlx5_core_dev *mdev)
128{ 78{
129 return 0; 79 return 0;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/alloc.c b/drivers/net/ethernet/mellanox/mlx5/core/alloc.c
index 47239bf7bf43..323ffe8bf7e4 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/alloc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/alloc.c
@@ -71,19 +71,24 @@ static void *mlx5_dma_zalloc_coherent_node(struct mlx5_core_dev *dev,
71} 71}
72 72
73int mlx5_buf_alloc_node(struct mlx5_core_dev *dev, int size, 73int mlx5_buf_alloc_node(struct mlx5_core_dev *dev, int size,
74 struct mlx5_buf *buf, int node) 74 struct mlx5_frag_buf *buf, int node)
75{ 75{
76 dma_addr_t t; 76 dma_addr_t t;
77 77
78 buf->size = size; 78 buf->size = size;
79 buf->npages = 1; 79 buf->npages = 1;
80 buf->page_shift = (u8)get_order(size) + PAGE_SHIFT; 80 buf->page_shift = (u8)get_order(size) + PAGE_SHIFT;
81 buf->direct.buf = mlx5_dma_zalloc_coherent_node(dev, size, 81
82 &t, node); 82 buf->frags = kzalloc(sizeof(*buf->frags), GFP_KERNEL);
83 if (!buf->direct.buf) 83 if (!buf->frags)
84 return -ENOMEM; 84 return -ENOMEM;
85 85
86 buf->direct.map = t; 86 buf->frags->buf = mlx5_dma_zalloc_coherent_node(dev, size,
87 &t, node);
88 if (!buf->frags->buf)
89 goto err_out;
90
91 buf->frags->map = t;
87 92
88 while (t & ((1 << buf->page_shift) - 1)) { 93 while (t & ((1 << buf->page_shift) - 1)) {
89 --buf->page_shift; 94 --buf->page_shift;
@@ -91,18 +96,24 @@ int mlx5_buf_alloc_node(struct mlx5_core_dev *dev, int size,
91 } 96 }
92 97
93 return 0; 98 return 0;
99err_out:
100 kfree(buf->frags);
101 return -ENOMEM;
94} 102}
95 103
96int mlx5_buf_alloc(struct mlx5_core_dev *dev, int size, struct mlx5_buf *buf) 104int mlx5_buf_alloc(struct mlx5_core_dev *dev,
105 int size, struct mlx5_frag_buf *buf)
97{ 106{
98 return mlx5_buf_alloc_node(dev, size, buf, dev->priv.numa_node); 107 return mlx5_buf_alloc_node(dev, size, buf, dev->priv.numa_node);
99} 108}
100EXPORT_SYMBOL_GPL(mlx5_buf_alloc); 109EXPORT_SYMBOL(mlx5_buf_alloc);
101 110
102void mlx5_buf_free(struct mlx5_core_dev *dev, struct mlx5_buf *buf) 111void mlx5_buf_free(struct mlx5_core_dev *dev, struct mlx5_frag_buf *buf)
103{ 112{
104 dma_free_coherent(&dev->pdev->dev, buf->size, buf->direct.buf, 113 dma_free_coherent(&dev->pdev->dev, buf->size, buf->frags->buf,
105 buf->direct.map); 114 buf->frags->map);
115
116 kfree(buf->frags);
106} 117}
107EXPORT_SYMBOL_GPL(mlx5_buf_free); 118EXPORT_SYMBOL_GPL(mlx5_buf_free);
108 119
@@ -147,6 +158,7 @@ err_free_buf:
147err_out: 158err_out:
148 return -ENOMEM; 159 return -ENOMEM;
149} 160}
161EXPORT_SYMBOL_GPL(mlx5_frag_buf_alloc_node);
150 162
151void mlx5_frag_buf_free(struct mlx5_core_dev *dev, struct mlx5_frag_buf *buf) 163void mlx5_frag_buf_free(struct mlx5_core_dev *dev, struct mlx5_frag_buf *buf)
152{ 164{
@@ -162,6 +174,7 @@ void mlx5_frag_buf_free(struct mlx5_core_dev *dev, struct mlx5_frag_buf *buf)
162 } 174 }
163 kfree(buf->frags); 175 kfree(buf->frags);
164} 176}
177EXPORT_SYMBOL_GPL(mlx5_frag_buf_free);
165 178
166static struct mlx5_db_pgdir *mlx5_alloc_db_pgdir(struct mlx5_core_dev *dev, 179static struct mlx5_db_pgdir *mlx5_alloc_db_pgdir(struct mlx5_core_dev *dev,
167 int node) 180 int node)
@@ -275,13 +288,13 @@ void mlx5_db_free(struct mlx5_core_dev *dev, struct mlx5_db *db)
275} 288}
276EXPORT_SYMBOL_GPL(mlx5_db_free); 289EXPORT_SYMBOL_GPL(mlx5_db_free);
277 290
278void mlx5_fill_page_array(struct mlx5_buf *buf, __be64 *pas) 291void mlx5_fill_page_array(struct mlx5_frag_buf *buf, __be64 *pas)
279{ 292{
280 u64 addr; 293 u64 addr;
281 int i; 294 int i;
282 295
283 for (i = 0; i < buf->npages; i++) { 296 for (i = 0; i < buf->npages; i++) {
284 addr = buf->direct.map + (i << buf->page_shift); 297 addr = buf->frags->map + (i << buf->page_shift);
285 298
286 pas[i] = cpu_to_be64(addr); 299 pas[i] = cpu_to_be64(addr);
287 } 300 }
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cq.c b/drivers/net/ethernet/mellanox/mlx5/core/cq.c
index 1016e05c7ec7..a4179122a279 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/cq.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/cq.c
@@ -58,8 +58,7 @@ void mlx5_cq_tasklet_cb(unsigned long data)
58 tasklet_ctx.list) { 58 tasklet_ctx.list) {
59 list_del_init(&mcq->tasklet_ctx.list); 59 list_del_init(&mcq->tasklet_ctx.list);
60 mcq->tasklet_ctx.comp(mcq); 60 mcq->tasklet_ctx.comp(mcq);
61 if (refcount_dec_and_test(&mcq->refcount)) 61 mlx5_cq_put(mcq);
62 complete(&mcq->free);
63 if (time_after(jiffies, end)) 62 if (time_after(jiffies, end))
64 break; 63 break;
65 } 64 }
@@ -80,69 +79,19 @@ static void mlx5_add_cq_to_tasklet(struct mlx5_core_cq *cq)
80 * still arrive. 79 * still arrive.
81 */ 80 */
82 if (list_empty_careful(&cq->tasklet_ctx.list)) { 81 if (list_empty_careful(&cq->tasklet_ctx.list)) {
83 refcount_inc(&cq->refcount); 82 mlx5_cq_hold(cq);
84 list_add_tail(&cq->tasklet_ctx.list, &tasklet_ctx->list); 83 list_add_tail(&cq->tasklet_ctx.list, &tasklet_ctx->list);
85 } 84 }
86 spin_unlock_irqrestore(&tasklet_ctx->lock, flags); 85 spin_unlock_irqrestore(&tasklet_ctx->lock, flags);
87} 86}
88 87
89void mlx5_cq_completion(struct mlx5_core_dev *dev, u32 cqn)
90{
91 struct mlx5_core_cq *cq;
92 struct mlx5_cq_table *table = &dev->priv.cq_table;
93
94 spin_lock(&table->lock);
95 cq = radix_tree_lookup(&table->tree, cqn);
96 if (likely(cq))
97 refcount_inc(&cq->refcount);
98 spin_unlock(&table->lock);
99
100 if (!cq) {
101 mlx5_core_warn(dev, "Completion event for bogus CQ 0x%x\n", cqn);
102 return;
103 }
104
105 ++cq->arm_sn;
106
107 cq->comp(cq);
108
109 if (refcount_dec_and_test(&cq->refcount))
110 complete(&cq->free);
111}
112
113void mlx5_cq_event(struct mlx5_core_dev *dev, u32 cqn, int event_type)
114{
115 struct mlx5_cq_table *table = &dev->priv.cq_table;
116 struct mlx5_core_cq *cq;
117
118 spin_lock(&table->lock);
119
120 cq = radix_tree_lookup(&table->tree, cqn);
121 if (cq)
122 refcount_inc(&cq->refcount);
123
124 spin_unlock(&table->lock);
125
126 if (!cq) {
127 mlx5_core_warn(dev, "Async event for bogus CQ 0x%x\n", cqn);
128 return;
129 }
130
131 cq->event(cq, event_type);
132
133 if (refcount_dec_and_test(&cq->refcount))
134 complete(&cq->free);
135}
136
137int mlx5_core_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq, 88int mlx5_core_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
138 u32 *in, int inlen) 89 u32 *in, int inlen)
139{ 90{
140 struct mlx5_cq_table *table = &dev->priv.cq_table; 91 int eqn = MLX5_GET(cqc, MLX5_ADDR_OF(create_cq_in, in, cq_context), c_eqn);
92 u32 dout[MLX5_ST_SZ_DW(destroy_cq_out)];
141 u32 out[MLX5_ST_SZ_DW(create_cq_out)]; 93 u32 out[MLX5_ST_SZ_DW(create_cq_out)];
142 u32 din[MLX5_ST_SZ_DW(destroy_cq_in)]; 94 u32 din[MLX5_ST_SZ_DW(destroy_cq_in)];
143 u32 dout[MLX5_ST_SZ_DW(destroy_cq_out)];
144 int eqn = MLX5_GET(cqc, MLX5_ADDR_OF(create_cq_in, in, cq_context),
145 c_eqn);
146 struct mlx5_eq *eq; 95 struct mlx5_eq *eq;
147 int err; 96 int err;
148 97
@@ -159,6 +108,7 @@ int mlx5_core_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
159 cq->cqn = MLX5_GET(create_cq_out, out, cqn); 108 cq->cqn = MLX5_GET(create_cq_out, out, cqn);
160 cq->cons_index = 0; 109 cq->cons_index = 0;
161 cq->arm_sn = 0; 110 cq->arm_sn = 0;
111 cq->eq = eq;
162 refcount_set(&cq->refcount, 1); 112 refcount_set(&cq->refcount, 1);
163 init_completion(&cq->free); 113 init_completion(&cq->free);
164 if (!cq->comp) 114 if (!cq->comp)
@@ -167,12 +117,16 @@ int mlx5_core_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
167 cq->tasklet_ctx.priv = &eq->tasklet_ctx; 117 cq->tasklet_ctx.priv = &eq->tasklet_ctx;
168 INIT_LIST_HEAD(&cq->tasklet_ctx.list); 118 INIT_LIST_HEAD(&cq->tasklet_ctx.list);
169 119
170 spin_lock_irq(&table->lock); 120 /* Add to comp EQ CQ tree to recv comp events */
171 err = radix_tree_insert(&table->tree, cq->cqn, cq); 121 err = mlx5_eq_add_cq(eq, cq);
172 spin_unlock_irq(&table->lock);
173 if (err) 122 if (err)
174 goto err_cmd; 123 goto err_cmd;
175 124
125 /* Add to async EQ CQ tree to recv async events */
126 err = mlx5_eq_add_cq(&dev->priv.eq_table.async_eq, cq);
127 if (err)
128 goto err_cq_add;
129
176 cq->pid = current->pid; 130 cq->pid = current->pid;
177 err = mlx5_debug_cq_add(dev, cq); 131 err = mlx5_debug_cq_add(dev, cq);
178 if (err) 132 if (err)
@@ -183,6 +137,8 @@ int mlx5_core_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
183 137
184 return 0; 138 return 0;
185 139
140err_cq_add:
141 mlx5_eq_del_cq(eq, cq);
186err_cmd: 142err_cmd:
187 memset(din, 0, sizeof(din)); 143 memset(din, 0, sizeof(din));
188 memset(dout, 0, sizeof(dout)); 144 memset(dout, 0, sizeof(dout));
@@ -195,23 +151,17 @@ EXPORT_SYMBOL(mlx5_core_create_cq);
195 151
196int mlx5_core_destroy_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq) 152int mlx5_core_destroy_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq)
197{ 153{
198 struct mlx5_cq_table *table = &dev->priv.cq_table;
199 u32 out[MLX5_ST_SZ_DW(destroy_cq_out)] = {0}; 154 u32 out[MLX5_ST_SZ_DW(destroy_cq_out)] = {0};
200 u32 in[MLX5_ST_SZ_DW(destroy_cq_in)] = {0}; 155 u32 in[MLX5_ST_SZ_DW(destroy_cq_in)] = {0};
201 struct mlx5_core_cq *tmp;
202 int err; 156 int err;
203 157
204 spin_lock_irq(&table->lock); 158 err = mlx5_eq_del_cq(&dev->priv.eq_table.async_eq, cq);
205 tmp = radix_tree_delete(&table->tree, cq->cqn); 159 if (err)
206 spin_unlock_irq(&table->lock); 160 return err;
207 if (!tmp) { 161
208 mlx5_core_warn(dev, "cq 0x%x not found in tree\n", cq->cqn); 162 err = mlx5_eq_del_cq(cq->eq, cq);
209 return -EINVAL; 163 if (err)
210 } 164 return err;
211 if (tmp != cq) {
212 mlx5_core_warn(dev, "corruption on srqn 0x%x\n", cq->cqn);
213 return -EINVAL;
214 }
215 165
216 MLX5_SET(destroy_cq_in, in, opcode, MLX5_CMD_OP_DESTROY_CQ); 166 MLX5_SET(destroy_cq_in, in, opcode, MLX5_CMD_OP_DESTROY_CQ);
217 MLX5_SET(destroy_cq_in, in, cqn, cq->cqn); 167 MLX5_SET(destroy_cq_in, in, cqn, cq->cqn);
@@ -222,8 +172,7 @@ int mlx5_core_destroy_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq)
222 synchronize_irq(cq->irqn); 172 synchronize_irq(cq->irqn);
223 173
224 mlx5_debug_cq_remove(dev, cq); 174 mlx5_debug_cq_remove(dev, cq);
225 if (refcount_dec_and_test(&cq->refcount)) 175 mlx5_cq_put(cq);
226 complete(&cq->free);
227 wait_for_completion(&cq->free); 176 wait_for_completion(&cq->free);
228 177
229 return 0; 178 return 0;
@@ -270,21 +219,3 @@ int mlx5_core_modify_cq_moderation(struct mlx5_core_dev *dev,
270 return mlx5_core_modify_cq(dev, cq, in, sizeof(in)); 219 return mlx5_core_modify_cq(dev, cq, in, sizeof(in));
271} 220}
272EXPORT_SYMBOL(mlx5_core_modify_cq_moderation); 221EXPORT_SYMBOL(mlx5_core_modify_cq_moderation);
273
274int mlx5_init_cq_table(struct mlx5_core_dev *dev)
275{
276 struct mlx5_cq_table *table = &dev->priv.cq_table;
277 int err;
278
279 memset(table, 0, sizeof(*table));
280 spin_lock_init(&table->lock);
281 INIT_RADIX_TREE(&table->tree, GFP_ATOMIC);
282 err = mlx5_cq_debugfs_init(dev);
283
284 return err;
285}
286
287void mlx5_cleanup_cq_table(struct mlx5_core_dev *dev)
288{
289 mlx5_cq_debugfs_cleanup(dev);
290}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/dev.c b/drivers/net/ethernet/mellanox/mlx5/core/dev.c
index 17b723218b0c..b994b80d5714 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/dev.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/dev.c
@@ -337,6 +337,14 @@ void mlx5_unregister_interface(struct mlx5_interface *intf)
337} 337}
338EXPORT_SYMBOL(mlx5_unregister_interface); 338EXPORT_SYMBOL(mlx5_unregister_interface);
339 339
340void mlx5_reload_interface(struct mlx5_core_dev *mdev, int protocol)
341{
342 mutex_lock(&mlx5_intf_mutex);
343 mlx5_remove_dev_by_protocol(mdev, protocol);
344 mlx5_add_dev_by_protocol(mdev, protocol);
345 mutex_unlock(&mlx5_intf_mutex);
346}
347
340void *mlx5_get_protocol_dev(struct mlx5_core_dev *mdev, int protocol) 348void *mlx5_get_protocol_dev(struct mlx5_core_dev *mdev, int protocol)
341{ 349{
342 struct mlx5_priv *priv = &mdev->priv; 350 struct mlx5_priv *priv = &mdev->priv;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fs_tracepoint.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fs_tracepoint.c
index fd509160c8f6..d93ff567b40d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fs_tracepoint.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fs_tracepoint.c
@@ -246,6 +246,9 @@ const char *parse_fs_dst(struct trace_seq *p,
246 case MLX5_FLOW_DESTINATION_TYPE_COUNTER: 246 case MLX5_FLOW_DESTINATION_TYPE_COUNTER:
247 trace_seq_printf(p, "counter_id=%u\n", counter_id); 247 trace_seq_printf(p, "counter_id=%u\n", counter_id);
248 break; 248 break;
249 case MLX5_FLOW_DESTINATION_TYPE_PORT:
250 trace_seq_printf(p, "port\n");
251 break;
249 } 252 }
250 253
251 trace_seq_putc(p, 0); 254 trace_seq_putc(p, 0);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fs_tracepoint.h b/drivers/net/ethernet/mellanox/mlx5/core/diag/fs_tracepoint.h
index 80eef4163f52..a6ba57fbb414 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fs_tracepoint.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fs_tracepoint.h
@@ -163,9 +163,9 @@ TRACE_EVENT(mlx5_fs_set_fte,
163 fs_get_obj(__entry->fg, fte->node.parent); 163 fs_get_obj(__entry->fg, fte->node.parent);
164 __entry->group_index = __entry->fg->id; 164 __entry->group_index = __entry->fg->id;
165 __entry->index = fte->index; 165 __entry->index = fte->index;
166 __entry->action = fte->action; 166 __entry->action = fte->action.action;
167 __entry->mask_enable = __entry->fg->mask.match_criteria_enable; 167 __entry->mask_enable = __entry->fg->mask.match_criteria_enable;
168 __entry->flow_tag = fte->flow_tag; 168 __entry->flow_tag = fte->action.flow_tag;
169 memcpy(__entry->mask_outer, 169 memcpy(__entry->mask_outer,
170 MLX5_ADDR_OF(fte_match_param, 170 MLX5_ADDR_OF(fte_match_param,
171 &__entry->fg->mask.match_criteria, 171 &__entry->fg->mask.match_criteria,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
index bac5103efad3..cf58c9637904 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
@@ -38,17 +38,24 @@
38#include <linux/module.h> 38#include <linux/module.h>
39 39
40#include "en.h" 40#include "en.h"
41#include "accel/ipsec.h"
42#include "en_accel/ipsec.h" 41#include "en_accel/ipsec.h"
43#include "en_accel/ipsec_rxtx.h" 42#include "en_accel/ipsec_rxtx.h"
44 43
45struct mlx5e_ipsec_sa_entry { 44
46 struct hlist_node hlist; /* Item in SADB_RX hashtable */ 45static struct mlx5e_ipsec_sa_entry *to_ipsec_sa_entry(struct xfrm_state *x)
47 unsigned int handle; /* Handle in SADB_RX */ 46{
48 struct xfrm_state *x; 47 struct mlx5e_ipsec_sa_entry *sa;
49 struct mlx5e_ipsec *ipsec; 48
50 void *context; 49 if (!x)
51}; 50 return NULL;
51
52 sa = (struct mlx5e_ipsec_sa_entry *)x->xso.offload_handle;
53 if (!sa)
54 return NULL;
55
56 WARN_ON(sa->x != x);
57 return sa;
58}
52 59
53struct xfrm_state *mlx5e_ipsec_sadb_rx_lookup(struct mlx5e_ipsec *ipsec, 60struct xfrm_state *mlx5e_ipsec_sadb_rx_lookup(struct mlx5e_ipsec *ipsec,
54 unsigned int handle) 61 unsigned int handle)
@@ -74,18 +81,16 @@ static int mlx5e_ipsec_sadb_rx_add(struct mlx5e_ipsec_sa_entry *sa_entry)
74 unsigned long flags; 81 unsigned long flags;
75 int ret; 82 int ret;
76 83
77 spin_lock_irqsave(&ipsec->sadb_rx_lock, flags);
78 ret = ida_simple_get(&ipsec->halloc, 1, 0, GFP_KERNEL); 84 ret = ida_simple_get(&ipsec->halloc, 1, 0, GFP_KERNEL);
79 if (ret < 0) 85 if (ret < 0)
80 goto out; 86 return ret;
81 87
88 spin_lock_irqsave(&ipsec->sadb_rx_lock, flags);
82 sa_entry->handle = ret; 89 sa_entry->handle = ret;
83 hash_add_rcu(ipsec->sadb_rx, &sa_entry->hlist, sa_entry->handle); 90 hash_add_rcu(ipsec->sadb_rx, &sa_entry->hlist, sa_entry->handle);
84 ret = 0;
85
86out:
87 spin_unlock_irqrestore(&ipsec->sadb_rx_lock, flags); 91 spin_unlock_irqrestore(&ipsec->sadb_rx_lock, flags);
88 return ret; 92
93 return 0;
89} 94}
90 95
91static void mlx5e_ipsec_sadb_rx_del(struct mlx5e_ipsec_sa_entry *sa_entry) 96static void mlx5e_ipsec_sadb_rx_del(struct mlx5e_ipsec_sa_entry *sa_entry)
@@ -101,87 +106,99 @@ static void mlx5e_ipsec_sadb_rx_del(struct mlx5e_ipsec_sa_entry *sa_entry)
101static void mlx5e_ipsec_sadb_rx_free(struct mlx5e_ipsec_sa_entry *sa_entry) 106static void mlx5e_ipsec_sadb_rx_free(struct mlx5e_ipsec_sa_entry *sa_entry)
102{ 107{
103 struct mlx5e_ipsec *ipsec = sa_entry->ipsec; 108 struct mlx5e_ipsec *ipsec = sa_entry->ipsec;
104 unsigned long flags;
105 109
106 /* Wait for the hash_del_rcu call in sadb_rx_del to affect data path */ 110 /* xfrm already doing sync rcu between del and free callbacks */
107 synchronize_rcu(); 111
108 spin_lock_irqsave(&ipsec->sadb_rx_lock, flags);
109 ida_simple_remove(&ipsec->halloc, sa_entry->handle); 112 ida_simple_remove(&ipsec->halloc, sa_entry->handle);
110 spin_unlock_irqrestore(&ipsec->sadb_rx_lock, flags);
111} 113}
112 114
113static enum mlx5_accel_ipsec_enc_mode mlx5e_ipsec_enc_mode(struct xfrm_state *x) 115static bool mlx5e_ipsec_update_esn_state(struct mlx5e_ipsec_sa_entry *sa_entry)
114{ 116{
115 unsigned int key_len = (x->aead->alg_key_len + 7) / 8 - 4; 117 struct xfrm_replay_state_esn *replay_esn;
116 118 u32 seq_bottom;
117 switch (key_len) { 119 u8 overlap;
118 case 16: 120 u32 *esn;
119 return MLX5_IPSEC_SADB_MODE_AES_GCM_128_AUTH_128; 121
120 case 32: 122 if (!(sa_entry->x->props.flags & XFRM_STATE_ESN)) {
121 return MLX5_IPSEC_SADB_MODE_AES_GCM_256_AUTH_128; 123 sa_entry->esn_state.trigger = 0;
122 default: 124 return false;
123 netdev_warn(x->xso.dev, "Bad key len: %d for alg %s\n", 125 }
124 key_len, x->aead->alg_name); 126
125 return -1; 127 replay_esn = sa_entry->x->replay_esn;
128 seq_bottom = replay_esn->seq - replay_esn->replay_window + 1;
129 overlap = sa_entry->esn_state.overlap;
130
131 sa_entry->esn_state.esn = xfrm_replay_seqhi(sa_entry->x,
132 htonl(seq_bottom));
133 esn = &sa_entry->esn_state.esn;
134
135 sa_entry->esn_state.trigger = 1;
136 if (unlikely(overlap && seq_bottom < MLX5E_IPSEC_ESN_SCOPE_MID)) {
137 ++(*esn);
138 sa_entry->esn_state.overlap = 0;
139 return true;
140 } else if (unlikely(!overlap &&
141 (seq_bottom >= MLX5E_IPSEC_ESN_SCOPE_MID))) {
142 sa_entry->esn_state.overlap = 1;
143 return true;
126 } 144 }
145
146 return false;
127} 147}
128 148
129static void mlx5e_ipsec_build_hw_sa(u32 op, struct mlx5e_ipsec_sa_entry *sa_entry, 149static void
130 struct mlx5_accel_ipsec_sa *hw_sa) 150mlx5e_ipsec_build_accel_xfrm_attrs(struct mlx5e_ipsec_sa_entry *sa_entry,
151 struct mlx5_accel_esp_xfrm_attrs *attrs)
131{ 152{
132 struct xfrm_state *x = sa_entry->x; 153 struct xfrm_state *x = sa_entry->x;
154 struct aes_gcm_keymat *aes_gcm = &attrs->keymat.aes_gcm;
133 struct aead_geniv_ctx *geniv_ctx; 155 struct aead_geniv_ctx *geniv_ctx;
134 unsigned int crypto_data_len;
135 struct crypto_aead *aead; 156 struct crypto_aead *aead;
136 unsigned int key_len; 157 unsigned int crypto_data_len, key_len;
137 int ivsize; 158 int ivsize;
138 159
139 memset(hw_sa, 0, sizeof(*hw_sa)); 160 memset(attrs, 0, sizeof(*attrs));
140
141 if (op == MLX5_IPSEC_CMD_ADD_SA) {
142 crypto_data_len = (x->aead->alg_key_len + 7) / 8;
143 key_len = crypto_data_len - 4; /* 4 bytes salt at end */
144 aead = x->data;
145 geniv_ctx = crypto_aead_ctx(aead);
146 ivsize = crypto_aead_ivsize(aead);
147
148 memcpy(&hw_sa->key_enc, x->aead->alg_key, key_len);
149 /* Duplicate 128 bit key twice according to HW layout */
150 if (key_len == 16)
151 memcpy(&hw_sa->key_enc[16], x->aead->alg_key, key_len);
152 memcpy(&hw_sa->gcm.salt_iv, geniv_ctx->salt, ivsize);
153 hw_sa->gcm.salt = *((__be32 *)(x->aead->alg_key + key_len));
154 }
155 161
156 hw_sa->cmd = htonl(op); 162 /* key */
157 hw_sa->flags |= MLX5_IPSEC_SADB_SA_VALID | MLX5_IPSEC_SADB_SPI_EN; 163 crypto_data_len = (x->aead->alg_key_len + 7) / 8;
158 if (x->props.family == AF_INET) { 164 key_len = crypto_data_len - 4; /* 4 bytes salt at end */
159 hw_sa->sip[3] = x->props.saddr.a4; 165
160 hw_sa->dip[3] = x->id.daddr.a4; 166 memcpy(aes_gcm->aes_key, x->aead->alg_key, key_len);
161 hw_sa->sip_masklen = 32; 167 aes_gcm->key_len = key_len * 8;
162 hw_sa->dip_masklen = 32; 168
163 } else { 169 /* salt and seq_iv */
164 memcpy(hw_sa->sip, x->props.saddr.a6, sizeof(hw_sa->sip)); 170 aead = x->data;
165 memcpy(hw_sa->dip, x->id.daddr.a6, sizeof(hw_sa->dip)); 171 geniv_ctx = crypto_aead_ctx(aead);
166 hw_sa->sip_masklen = 128; 172 ivsize = crypto_aead_ivsize(aead);
167 hw_sa->dip_masklen = 128; 173 memcpy(&aes_gcm->seq_iv, &geniv_ctx->salt, ivsize);
168 hw_sa->flags |= MLX5_IPSEC_SADB_IPV6; 174 memcpy(&aes_gcm->salt, x->aead->alg_key + key_len,
169 } 175 sizeof(aes_gcm->salt));
170 hw_sa->spi = x->id.spi; 176
171 hw_sa->sw_sa_handle = htonl(sa_entry->handle); 177 /* iv len */
172 switch (x->id.proto) { 178 aes_gcm->icv_len = x->aead->alg_icv_len;
173 case IPPROTO_ESP: 179
174 hw_sa->flags |= MLX5_IPSEC_SADB_IP_ESP; 180 /* esn */
175 break; 181 if (sa_entry->esn_state.trigger) {
176 case IPPROTO_AH: 182 attrs->flags |= MLX5_ACCEL_ESP_FLAGS_ESN_TRIGGERED;
177 hw_sa->flags |= MLX5_IPSEC_SADB_IP_AH; 183 attrs->esn = sa_entry->esn_state.esn;
178 break; 184 if (sa_entry->esn_state.overlap)
179 default: 185 attrs->flags |= MLX5_ACCEL_ESP_FLAGS_ESN_STATE_OVERLAP;
180 break;
181 } 186 }
182 hw_sa->enc_mode = mlx5e_ipsec_enc_mode(x); 187
183 if (!(x->xso.flags & XFRM_OFFLOAD_INBOUND)) 188 /* rx handle */
184 hw_sa->flags |= MLX5_IPSEC_SADB_DIR_SX; 189 attrs->sa_handle = sa_entry->handle;
190
191 /* algo type */
192 attrs->keymat_type = MLX5_ACCEL_ESP_KEYMAT_AES_GCM;
193
194 /* action */
195 attrs->action = (!(x->xso.flags & XFRM_OFFLOAD_INBOUND)) ?
196 MLX5_ACCEL_ESP_ACTION_ENCRYPT :
197 MLX5_ACCEL_ESP_ACTION_DECRYPT;
198 /* flags */
199 attrs->flags |= (x->props.mode == XFRM_MODE_TRANSPORT) ?
200 MLX5_ACCEL_ESP_FLAGS_TRANSPORT :
201 MLX5_ACCEL_ESP_FLAGS_TUNNEL;
185} 202}
186 203
187static inline int mlx5e_xfrm_validate_state(struct xfrm_state *x) 204static inline int mlx5e_xfrm_validate_state(struct xfrm_state *x)
@@ -203,7 +220,9 @@ static inline int mlx5e_xfrm_validate_state(struct xfrm_state *x)
203 netdev_info(netdev, "Cannot offload compressed xfrm states\n"); 220 netdev_info(netdev, "Cannot offload compressed xfrm states\n");
204 return -EINVAL; 221 return -EINVAL;
205 } 222 }
206 if (x->props.flags & XFRM_STATE_ESN) { 223 if (x->props.flags & XFRM_STATE_ESN &&
224 !(mlx5_accel_ipsec_device_caps(priv->mdev) &
225 MLX5_ACCEL_IPSEC_CAP_ESN)) {
207 netdev_info(netdev, "Cannot offload ESN xfrm states\n"); 226 netdev_info(netdev, "Cannot offload ESN xfrm states\n");
208 return -EINVAL; 227 return -EINVAL;
209 } 228 }
@@ -251,7 +270,8 @@ static inline int mlx5e_xfrm_validate_state(struct xfrm_state *x)
251 return -EINVAL; 270 return -EINVAL;
252 } 271 }
253 if (x->props.family == AF_INET6 && 272 if (x->props.family == AF_INET6 &&
254 !(mlx5_accel_ipsec_device_caps(priv->mdev) & MLX5_ACCEL_IPSEC_IPV6)) { 273 !(mlx5_accel_ipsec_device_caps(priv->mdev) &
274 MLX5_ACCEL_IPSEC_CAP_IPV6)) {
255 netdev_info(netdev, "IPv6 xfrm state offload is not supported by this device\n"); 275 netdev_info(netdev, "IPv6 xfrm state offload is not supported by this device\n");
256 return -EINVAL; 276 return -EINVAL;
257 } 277 }
@@ -262,9 +282,10 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x)
262{ 282{
263 struct mlx5e_ipsec_sa_entry *sa_entry = NULL; 283 struct mlx5e_ipsec_sa_entry *sa_entry = NULL;
264 struct net_device *netdev = x->xso.dev; 284 struct net_device *netdev = x->xso.dev;
265 struct mlx5_accel_ipsec_sa hw_sa; 285 struct mlx5_accel_esp_xfrm_attrs attrs;
266 struct mlx5e_priv *priv; 286 struct mlx5e_priv *priv;
267 void *context; 287 __be32 saddr[4] = {0}, daddr[4] = {0}, spi;
288 bool is_ipv6 = false;
268 int err; 289 int err;
269 290
270 priv = netdev_priv(netdev); 291 priv = netdev_priv(netdev);
@@ -291,22 +312,49 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x)
291 netdev_info(netdev, "Failed adding to SADB_RX: %d\n", err); 312 netdev_info(netdev, "Failed adding to SADB_RX: %d\n", err);
292 goto err_entry; 313 goto err_entry;
293 } 314 }
315 } else {
316 sa_entry->set_iv_op = (x->props.flags & XFRM_STATE_ESN) ?
317 mlx5e_ipsec_set_iv_esn : mlx5e_ipsec_set_iv;
294 } 318 }
295 319
296 mlx5e_ipsec_build_hw_sa(MLX5_IPSEC_CMD_ADD_SA, sa_entry, &hw_sa); 320 /* check esn */
297 context = mlx5_accel_ipsec_sa_cmd_exec(sa_entry->ipsec->en_priv->mdev, &hw_sa); 321 mlx5e_ipsec_update_esn_state(sa_entry);
298 if (IS_ERR(context)) { 322
299 err = PTR_ERR(context); 323 /* create xfrm */
324 mlx5e_ipsec_build_accel_xfrm_attrs(sa_entry, &attrs);
325 sa_entry->xfrm =
326 mlx5_accel_esp_create_xfrm(priv->mdev, &attrs,
327 MLX5_ACCEL_XFRM_FLAG_REQUIRE_METADATA);
328 if (IS_ERR(sa_entry->xfrm)) {
329 err = PTR_ERR(sa_entry->xfrm);
300 goto err_sadb_rx; 330 goto err_sadb_rx;
301 } 331 }
302 332
303 err = mlx5_accel_ipsec_sa_cmd_wait(context); 333 /* create hw context */
304 if (err) 334 if (x->props.family == AF_INET) {
305 goto err_sadb_rx; 335 saddr[3] = x->props.saddr.a4;
336 daddr[3] = x->id.daddr.a4;
337 } else {
338 memcpy(saddr, x->props.saddr.a6, sizeof(saddr));
339 memcpy(daddr, x->id.daddr.a6, sizeof(daddr));
340 is_ipv6 = true;
341 }
342 spi = x->id.spi;
343 sa_entry->hw_context =
344 mlx5_accel_esp_create_hw_context(priv->mdev,
345 sa_entry->xfrm,
346 saddr, daddr, spi,
347 is_ipv6);
348 if (IS_ERR(sa_entry->hw_context)) {
349 err = PTR_ERR(sa_entry->hw_context);
350 goto err_xfrm;
351 }
306 352
307 x->xso.offload_handle = (unsigned long)sa_entry; 353 x->xso.offload_handle = (unsigned long)sa_entry;
308 goto out; 354 goto out;
309 355
356err_xfrm:
357 mlx5_accel_esp_destroy_xfrm(sa_entry->xfrm);
310err_sadb_rx: 358err_sadb_rx:
311 if (x->xso.flags & XFRM_OFFLOAD_INBOUND) { 359 if (x->xso.flags & XFRM_OFFLOAD_INBOUND) {
312 mlx5e_ipsec_sadb_rx_del(sa_entry); 360 mlx5e_ipsec_sadb_rx_del(sa_entry);
@@ -320,43 +368,26 @@ out:
320 368
321static void mlx5e_xfrm_del_state(struct xfrm_state *x) 369static void mlx5e_xfrm_del_state(struct xfrm_state *x)
322{ 370{
323 struct mlx5e_ipsec_sa_entry *sa_entry; 371 struct mlx5e_ipsec_sa_entry *sa_entry = to_ipsec_sa_entry(x);
324 struct mlx5_accel_ipsec_sa hw_sa;
325 void *context;
326 372
327 if (!x->xso.offload_handle) 373 if (!sa_entry)
328 return; 374 return;
329 375
330 sa_entry = (struct mlx5e_ipsec_sa_entry *)x->xso.offload_handle;
331 WARN_ON(sa_entry->x != x);
332
333 if (x->xso.flags & XFRM_OFFLOAD_INBOUND) 376 if (x->xso.flags & XFRM_OFFLOAD_INBOUND)
334 mlx5e_ipsec_sadb_rx_del(sa_entry); 377 mlx5e_ipsec_sadb_rx_del(sa_entry);
335
336 mlx5e_ipsec_build_hw_sa(MLX5_IPSEC_CMD_DEL_SA, sa_entry, &hw_sa);
337 context = mlx5_accel_ipsec_sa_cmd_exec(sa_entry->ipsec->en_priv->mdev, &hw_sa);
338 if (IS_ERR(context))
339 return;
340
341 sa_entry->context = context;
342} 378}
343 379
344static void mlx5e_xfrm_free_state(struct xfrm_state *x) 380static void mlx5e_xfrm_free_state(struct xfrm_state *x)
345{ 381{
346 struct mlx5e_ipsec_sa_entry *sa_entry; 382 struct mlx5e_ipsec_sa_entry *sa_entry = to_ipsec_sa_entry(x);
347 int res;
348 383
349 if (!x->xso.offload_handle) 384 if (!sa_entry)
350 return; 385 return;
351 386
352 sa_entry = (struct mlx5e_ipsec_sa_entry *)x->xso.offload_handle; 387 if (sa_entry->hw_context) {
353 WARN_ON(sa_entry->x != x); 388 flush_workqueue(sa_entry->ipsec->wq);
354 389 mlx5_accel_esp_free_hw_context(sa_entry->hw_context);
355 res = mlx5_accel_ipsec_sa_cmd_wait(sa_entry->context); 390 mlx5_accel_esp_destroy_xfrm(sa_entry->xfrm);
356 sa_entry->context = NULL;
357 if (res) {
358 /* Leftover object will leak */
359 return;
360 } 391 }
361 392
362 if (x->xso.flags & XFRM_OFFLOAD_INBOUND) 393 if (x->xso.flags & XFRM_OFFLOAD_INBOUND)
@@ -383,6 +414,14 @@ int mlx5e_ipsec_init(struct mlx5e_priv *priv)
383 ida_init(&ipsec->halloc); 414 ida_init(&ipsec->halloc);
384 ipsec->en_priv = priv; 415 ipsec->en_priv = priv;
385 ipsec->en_priv->ipsec = ipsec; 416 ipsec->en_priv->ipsec = ipsec;
417 ipsec->no_trailer = !!(mlx5_accel_ipsec_device_caps(priv->mdev) &
418 MLX5_ACCEL_IPSEC_CAP_RX_NO_TRAILER);
419 ipsec->wq = alloc_ordered_workqueue("mlx5e_ipsec: %s", 0,
420 priv->netdev->name);
421 if (!ipsec->wq) {
422 kfree(ipsec);
423 return -ENOMEM;
424 }
386 netdev_dbg(priv->netdev, "IPSec attached to netdevice\n"); 425 netdev_dbg(priv->netdev, "IPSec attached to netdevice\n");
387 return 0; 426 return 0;
388} 427}
@@ -394,6 +433,9 @@ void mlx5e_ipsec_cleanup(struct mlx5e_priv *priv)
394 if (!ipsec) 433 if (!ipsec)
395 return; 434 return;
396 435
436 drain_workqueue(ipsec->wq);
437 destroy_workqueue(ipsec->wq);
438
397 ida_destroy(&ipsec->halloc); 439 ida_destroy(&ipsec->halloc);
398 kfree(ipsec); 440 kfree(ipsec);
399 priv->ipsec = NULL; 441 priv->ipsec = NULL;
@@ -414,11 +456,58 @@ static bool mlx5e_ipsec_offload_ok(struct sk_buff *skb, struct xfrm_state *x)
414 return true; 456 return true;
415} 457}
416 458
459struct mlx5e_ipsec_modify_state_work {
460 struct work_struct work;
461 struct mlx5_accel_esp_xfrm_attrs attrs;
462 struct mlx5e_ipsec_sa_entry *sa_entry;
463};
464
465static void _update_xfrm_state(struct work_struct *work)
466{
467 int ret;
468 struct mlx5e_ipsec_modify_state_work *modify_work =
469 container_of(work, struct mlx5e_ipsec_modify_state_work, work);
470 struct mlx5e_ipsec_sa_entry *sa_entry = modify_work->sa_entry;
471
472 ret = mlx5_accel_esp_modify_xfrm(sa_entry->xfrm,
473 &modify_work->attrs);
474 if (ret)
475 netdev_warn(sa_entry->ipsec->en_priv->netdev,
476 "Not an IPSec offload device\n");
477
478 kfree(modify_work);
479}
480
481static void mlx5e_xfrm_advance_esn_state(struct xfrm_state *x)
482{
483 struct mlx5e_ipsec_sa_entry *sa_entry = to_ipsec_sa_entry(x);
484 struct mlx5e_ipsec_modify_state_work *modify_work;
485 bool need_update;
486
487 if (!sa_entry)
488 return;
489
490 need_update = mlx5e_ipsec_update_esn_state(sa_entry);
491 if (!need_update)
492 return;
493
494 modify_work = kzalloc(sizeof(*modify_work), GFP_ATOMIC);
495 if (!modify_work)
496 return;
497
498 mlx5e_ipsec_build_accel_xfrm_attrs(sa_entry, &modify_work->attrs);
499 modify_work->sa_entry = sa_entry;
500
501 INIT_WORK(&modify_work->work, _update_xfrm_state);
502 WARN_ON(!queue_work(sa_entry->ipsec->wq, &modify_work->work));
503}
504
417static const struct xfrmdev_ops mlx5e_ipsec_xfrmdev_ops = { 505static const struct xfrmdev_ops mlx5e_ipsec_xfrmdev_ops = {
418 .xdo_dev_state_add = mlx5e_xfrm_add_state, 506 .xdo_dev_state_add = mlx5e_xfrm_add_state,
419 .xdo_dev_state_delete = mlx5e_xfrm_del_state, 507 .xdo_dev_state_delete = mlx5e_xfrm_del_state,
420 .xdo_dev_state_free = mlx5e_xfrm_free_state, 508 .xdo_dev_state_free = mlx5e_xfrm_free_state,
421 .xdo_dev_offload_ok = mlx5e_ipsec_offload_ok, 509 .xdo_dev_offload_ok = mlx5e_ipsec_offload_ok,
510 .xdo_dev_state_advance_esn = mlx5e_xfrm_advance_esn_state,
422}; 511};
423 512
424void mlx5e_ipsec_build_netdev(struct mlx5e_priv *priv) 513void mlx5e_ipsec_build_netdev(struct mlx5e_priv *priv)
@@ -429,7 +518,7 @@ void mlx5e_ipsec_build_netdev(struct mlx5e_priv *priv)
429 if (!priv->ipsec) 518 if (!priv->ipsec)
430 return; 519 return;
431 520
432 if (!(mlx5_accel_ipsec_device_caps(mdev) & MLX5_ACCEL_IPSEC_ESP) || 521 if (!(mlx5_accel_ipsec_device_caps(mdev) & MLX5_ACCEL_IPSEC_CAP_ESP) ||
433 !MLX5_CAP_ETH(mdev, swp)) { 522 !MLX5_CAP_ETH(mdev, swp)) {
434 mlx5_core_dbg(mdev, "mlx5e: ESP and SWP offload not supported\n"); 523 mlx5_core_dbg(mdev, "mlx5e: ESP and SWP offload not supported\n");
435 return; 524 return;
@@ -448,7 +537,7 @@ void mlx5e_ipsec_build_netdev(struct mlx5e_priv *priv)
448 netdev->features |= NETIF_F_HW_ESP_TX_CSUM; 537 netdev->features |= NETIF_F_HW_ESP_TX_CSUM;
449 netdev->hw_enc_features |= NETIF_F_HW_ESP_TX_CSUM; 538 netdev->hw_enc_features |= NETIF_F_HW_ESP_TX_CSUM;
450 539
451 if (!(mlx5_accel_ipsec_device_caps(mdev) & MLX5_ACCEL_IPSEC_LSO) || 540 if (!(mlx5_accel_ipsec_device_caps(mdev) & MLX5_ACCEL_IPSEC_CAP_LSO) ||
452 !MLX5_CAP_ETH(mdev, swp_lso)) { 541 !MLX5_CAP_ETH(mdev, swp_lso)) {
453 mlx5_core_dbg(mdev, "mlx5e: ESP LSO not supported\n"); 542 mlx5_core_dbg(mdev, "mlx5e: ESP LSO not supported\n");
454 return; 543 return;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h
index 56e00baf16cc..1198fc1eba4c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h
@@ -40,7 +40,11 @@
40#include <net/xfrm.h> 40#include <net/xfrm.h>
41#include <linux/idr.h> 41#include <linux/idr.h>
42 42
43#include "accel/ipsec.h"
44
43#define MLX5E_IPSEC_SADB_RX_BITS 10 45#define MLX5E_IPSEC_SADB_RX_BITS 10
46#define MLX5E_IPSEC_ESN_SCOPE_MID 0x80000000L
47
44#define MLX5E_METADATA_ETHER_TYPE (0x8CE4) 48#define MLX5E_METADATA_ETHER_TYPE (0x8CE4)
45#define MLX5E_METADATA_ETHER_LEN 8 49#define MLX5E_METADATA_ETHER_LEN 8
46 50
@@ -77,10 +81,30 @@ struct mlx5e_ipsec_stats {
77struct mlx5e_ipsec { 81struct mlx5e_ipsec {
78 struct mlx5e_priv *en_priv; 82 struct mlx5e_priv *en_priv;
79 DECLARE_HASHTABLE(sadb_rx, MLX5E_IPSEC_SADB_RX_BITS); 83 DECLARE_HASHTABLE(sadb_rx, MLX5E_IPSEC_SADB_RX_BITS);
84 bool no_trailer;
80 spinlock_t sadb_rx_lock; /* Protects sadb_rx and halloc */ 85 spinlock_t sadb_rx_lock; /* Protects sadb_rx and halloc */
81 struct ida halloc; 86 struct ida halloc;
82 struct mlx5e_ipsec_sw_stats sw_stats; 87 struct mlx5e_ipsec_sw_stats sw_stats;
83 struct mlx5e_ipsec_stats stats; 88 struct mlx5e_ipsec_stats stats;
89 struct workqueue_struct *wq;
90};
91
92struct mlx5e_ipsec_esn_state {
93 u32 esn;
94 u8 trigger: 1;
95 u8 overlap: 1;
96};
97
98struct mlx5e_ipsec_sa_entry {
99 struct hlist_node hlist; /* Item in SADB_RX hashtable */
100 struct mlx5e_ipsec_esn_state esn_state;
101 unsigned int handle; /* Handle in SADB_RX */
102 struct xfrm_state *x;
103 struct mlx5e_ipsec *ipsec;
104 struct mlx5_accel_esp_xfrm *xfrm;
105 void *hw_context;
106 void (*set_iv_op)(struct sk_buff *skb, struct xfrm_state *x,
107 struct xfrm_offload *xo);
84}; 108};
85 109
86void mlx5e_ipsec_build_inverse_table(void); 110void mlx5e_ipsec_build_inverse_table(void);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c
index 6a7c8b04447e..c245d8e78509 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c
@@ -42,10 +42,11 @@
42enum { 42enum {
43 MLX5E_IPSEC_RX_SYNDROME_DECRYPTED = 0x11, 43 MLX5E_IPSEC_RX_SYNDROME_DECRYPTED = 0x11,
44 MLX5E_IPSEC_RX_SYNDROME_AUTH_FAILED = 0x12, 44 MLX5E_IPSEC_RX_SYNDROME_AUTH_FAILED = 0x12,
45 MLX5E_IPSEC_RX_SYNDROME_BAD_PROTO = 0x17,
45}; 46};
46 47
47struct mlx5e_ipsec_rx_metadata { 48struct mlx5e_ipsec_rx_metadata {
48 unsigned char reserved; 49 unsigned char nexthdr;
49 __be32 sa_handle; 50 __be32 sa_handle;
50} __packed; 51} __packed;
51 52
@@ -175,7 +176,30 @@ static void mlx5e_ipsec_set_swp(struct sk_buff *skb,
175 } 176 }
176} 177}
177 178
178static void mlx5e_ipsec_set_iv(struct sk_buff *skb, struct xfrm_offload *xo) 179void mlx5e_ipsec_set_iv_esn(struct sk_buff *skb, struct xfrm_state *x,
180 struct xfrm_offload *xo)
181{
182 struct xfrm_replay_state_esn *replay_esn = x->replay_esn;
183 __u32 oseq = replay_esn->oseq;
184 int iv_offset;
185 __be64 seqno;
186 u32 seq_hi;
187
188 if (unlikely(skb_is_gso(skb) && oseq < MLX5E_IPSEC_ESN_SCOPE_MID &&
189 MLX5E_IPSEC_ESN_SCOPE_MID < (oseq - skb_shinfo(skb)->gso_segs))) {
190 seq_hi = xo->seq.hi - 1;
191 } else {
192 seq_hi = xo->seq.hi;
193 }
194
195 /* Place the SN in the IV field */
196 seqno = cpu_to_be64(xo->seq.low + ((u64)seq_hi << 32));
197 iv_offset = skb_transport_offset(skb) + sizeof(struct ip_esp_hdr);
198 skb_store_bits(skb, iv_offset, &seqno, 8);
199}
200
201void mlx5e_ipsec_set_iv(struct sk_buff *skb, struct xfrm_state *x,
202 struct xfrm_offload *xo)
179{ 203{
180 int iv_offset; 204 int iv_offset;
181 __be64 seqno; 205 __be64 seqno;
@@ -227,6 +251,7 @@ struct sk_buff *mlx5e_ipsec_handle_tx_skb(struct net_device *netdev,
227 struct mlx5e_priv *priv = netdev_priv(netdev); 251 struct mlx5e_priv *priv = netdev_priv(netdev);
228 struct xfrm_offload *xo = xfrm_offload(skb); 252 struct xfrm_offload *xo = xfrm_offload(skb);
229 struct mlx5e_ipsec_metadata *mdata; 253 struct mlx5e_ipsec_metadata *mdata;
254 struct mlx5e_ipsec_sa_entry *sa_entry;
230 struct xfrm_state *x; 255 struct xfrm_state *x;
231 256
232 if (!xo) 257 if (!xo)
@@ -261,7 +286,8 @@ struct sk_buff *mlx5e_ipsec_handle_tx_skb(struct net_device *netdev,
261 goto drop; 286 goto drop;
262 } 287 }
263 mlx5e_ipsec_set_swp(skb, &wqe->eth, x->props.mode, xo); 288 mlx5e_ipsec_set_swp(skb, &wqe->eth, x->props.mode, xo);
264 mlx5e_ipsec_set_iv(skb, xo); 289 sa_entry = (struct mlx5e_ipsec_sa_entry *)x->xso.offload_handle;
290 sa_entry->set_iv_op(skb, x, xo);
265 mlx5e_ipsec_set_metadata(skb, mdata, xo); 291 mlx5e_ipsec_set_metadata(skb, mdata, xo);
266 292
267 return skb; 293 return skb;
@@ -301,10 +327,17 @@ mlx5e_ipsec_build_sp(struct net_device *netdev, struct sk_buff *skb,
301 switch (mdata->syndrome) { 327 switch (mdata->syndrome) {
302 case MLX5E_IPSEC_RX_SYNDROME_DECRYPTED: 328 case MLX5E_IPSEC_RX_SYNDROME_DECRYPTED:
303 xo->status = CRYPTO_SUCCESS; 329 xo->status = CRYPTO_SUCCESS;
330 if (likely(priv->ipsec->no_trailer)) {
331 xo->flags |= XFRM_ESP_NO_TRAILER;
332 xo->proto = mdata->content.rx.nexthdr;
333 }
304 break; 334 break;
305 case MLX5E_IPSEC_RX_SYNDROME_AUTH_FAILED: 335 case MLX5E_IPSEC_RX_SYNDROME_AUTH_FAILED:
306 xo->status = CRYPTO_TUNNEL_ESP_AUTH_FAILED; 336 xo->status = CRYPTO_TUNNEL_ESP_AUTH_FAILED;
307 break; 337 break;
338 case MLX5E_IPSEC_RX_SYNDROME_BAD_PROTO:
339 xo->status = CRYPTO_INVALID_PROTOCOL;
340 break;
308 default: 341 default:
309 atomic64_inc(&priv->ipsec->sw_stats.ipsec_rx_drop_syndrome); 342 atomic64_inc(&priv->ipsec->sw_stats.ipsec_rx_drop_syndrome);
310 return NULL; 343 return NULL;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.h
index e37ae2598dbb..2bfbbef1b054 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.h
@@ -37,6 +37,7 @@
37#ifdef CONFIG_MLX5_EN_IPSEC 37#ifdef CONFIG_MLX5_EN_IPSEC
38 38
39#include <linux/skbuff.h> 39#include <linux/skbuff.h>
40#include <net/xfrm.h>
40#include "en.h" 41#include "en.h"
41 42
42struct sk_buff *mlx5e_ipsec_handle_rx_skb(struct net_device *netdev, 43struct sk_buff *mlx5e_ipsec_handle_rx_skb(struct net_device *netdev,
@@ -46,6 +47,10 @@ void mlx5e_ipsec_handle_rx_cqe(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe);
46void mlx5e_ipsec_inverse_table_init(void); 47void mlx5e_ipsec_inverse_table_init(void);
47bool mlx5e_ipsec_feature_check(struct sk_buff *skb, struct net_device *netdev, 48bool mlx5e_ipsec_feature_check(struct sk_buff *skb, struct net_device *netdev,
48 netdev_features_t features); 49 netdev_features_t features);
50void mlx5e_ipsec_set_iv_esn(struct sk_buff *skb, struct xfrm_state *x,
51 struct xfrm_offload *xo);
52void mlx5e_ipsec_set_iv(struct sk_buff *skb, struct xfrm_state *x,
53 struct xfrm_offload *xo);
49struct sk_buff *mlx5e_ipsec_handle_tx_skb(struct net_device *netdev, 54struct sk_buff *mlx5e_ipsec_handle_tx_skb(struct net_device *netdev,
50 struct mlx5e_tx_wqe *wqe, 55 struct mlx5e_tx_wqe *wqe,
51 struct sk_buff *skb); 56 struct sk_buff *skb);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
index 363d8dcb7f17..ea4b255380a2 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
@@ -1156,6 +1156,15 @@ mlx5e_vport_rep_unload(struct mlx5_eswitch_rep *rep)
1156 kfree(ppriv); /* mlx5e_rep_priv */ 1156 kfree(ppriv); /* mlx5e_rep_priv */
1157} 1157}
1158 1158
1159static void *mlx5e_vport_rep_get_proto_dev(struct mlx5_eswitch_rep *rep)
1160{
1161 struct mlx5e_rep_priv *rpriv;
1162
1163 rpriv = mlx5e_rep_to_rep_priv(rep);
1164
1165 return rpriv->netdev;
1166}
1167
1159static void mlx5e_rep_register_vf_vports(struct mlx5e_priv *priv) 1168static void mlx5e_rep_register_vf_vports(struct mlx5e_priv *priv)
1160{ 1169{
1161 struct mlx5_core_dev *mdev = priv->mdev; 1170 struct mlx5_core_dev *mdev = priv->mdev;
@@ -1168,6 +1177,7 @@ static void mlx5e_rep_register_vf_vports(struct mlx5e_priv *priv)
1168 1177
1169 rep_if.load = mlx5e_vport_rep_load; 1178 rep_if.load = mlx5e_vport_rep_load;
1170 rep_if.unload = mlx5e_vport_rep_unload; 1179 rep_if.unload = mlx5e_vport_rep_unload;
1180 rep_if.get_proto_dev = mlx5e_vport_rep_get_proto_dev;
1171 mlx5_eswitch_register_vport_rep(esw, vport, &rep_if, REP_ETH); 1181 mlx5_eswitch_register_vport_rep(esw, vport, &rep_if, REP_ETH);
1172 } 1182 }
1173} 1183}
@@ -1195,6 +1205,7 @@ void mlx5e_register_vport_reps(struct mlx5e_priv *priv)
1195 1205
1196 rep_if.load = mlx5e_nic_rep_load; 1206 rep_if.load = mlx5e_nic_rep_load;
1197 rep_if.unload = mlx5e_nic_rep_unload; 1207 rep_if.unload = mlx5e_nic_rep_unload;
1208 rep_if.get_proto_dev = mlx5e_vport_rep_get_proto_dev;
1198 rep_if.priv = rpriv; 1209 rep_if.priv = rpriv;
1199 INIT_LIST_HEAD(&rpriv->vport_sqs_list); 1210 INIT_LIST_HEAD(&rpriv->vport_sqs_list);
1200 mlx5_eswitch_register_vport_rep(esw, 0, &rep_if, REP_ETH); /* UPLINK PF vport*/ 1211 mlx5_eswitch_register_vport_rep(esw, 0, &rep_if, REP_ETH); /* UPLINK PF vport*/
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
index e5c3ab46a24a..8cce90dc461d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
@@ -53,7 +53,7 @@ static inline bool mlx5e_rx_hw_stamp(struct hwtstamp_config *config)
53static inline void mlx5e_read_cqe_slot(struct mlx5e_cq *cq, u32 cqcc, 53static inline void mlx5e_read_cqe_slot(struct mlx5e_cq *cq, u32 cqcc,
54 void *data) 54 void *data)
55{ 55{
56 u32 ci = cqcc & cq->wq.sz_m1; 56 u32 ci = cqcc & cq->wq.fbc.sz_m1;
57 57
58 memcpy(data, mlx5_cqwq_get_wqe(&cq->wq, ci), sizeof(struct mlx5_cqe64)); 58 memcpy(data, mlx5_cqwq_get_wqe(&cq->wq, ci), sizeof(struct mlx5_cqe64));
59} 59}
@@ -75,9 +75,10 @@ static inline void mlx5e_read_mini_arr_slot(struct mlx5e_cq *cq, u32 cqcc)
75 75
76static inline void mlx5e_cqes_update_owner(struct mlx5e_cq *cq, u32 cqcc, int n) 76static inline void mlx5e_cqes_update_owner(struct mlx5e_cq *cq, u32 cqcc, int n)
77{ 77{
78 u8 op_own = (cqcc >> cq->wq.log_sz) & 1; 78 struct mlx5_frag_buf_ctrl *fbc = &cq->wq.fbc;
79 u32 wq_sz = 1 << cq->wq.log_sz; 79 u8 op_own = (cqcc >> fbc->log_sz) & 1;
80 u32 ci = cqcc & cq->wq.sz_m1; 80 u32 wq_sz = 1 << fbc->log_sz;
81 u32 ci = cqcc & fbc->sz_m1;
81 u32 ci_top = min_t(u32, wq_sz, ci + n); 82 u32 ci_top = min_t(u32, wq_sz, ci + n);
82 83
83 for (; ci < ci_top; ci++, n--) { 84 for (; ci < ci_top; ci++, n--) {
@@ -102,7 +103,7 @@ static inline void mlx5e_decompress_cqe(struct mlx5e_rq *rq,
102 cq->title.byte_cnt = cq->mini_arr[cq->mini_arr_idx].byte_cnt; 103 cq->title.byte_cnt = cq->mini_arr[cq->mini_arr_idx].byte_cnt;
103 cq->title.check_sum = cq->mini_arr[cq->mini_arr_idx].checksum; 104 cq->title.check_sum = cq->mini_arr[cq->mini_arr_idx].checksum;
104 cq->title.op_own &= 0xf0; 105 cq->title.op_own &= 0xf0;
105 cq->title.op_own |= 0x01 & (cqcc >> cq->wq.log_sz); 106 cq->title.op_own |= 0x01 & (cqcc >> cq->wq.fbc.log_sz);
106 cq->title.wqe_counter = cpu_to_be16(cq->decmprs_wqe_counter); 107 cq->title.wqe_counter = cpu_to_be16(cq->decmprs_wqe_counter);
107 108
108 if (rq->wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) 109 if (rq->wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
index fa86a1466718..7c33df2034f0 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -675,6 +675,7 @@ mlx5e_tc_add_nic_flow(struct mlx5e_priv *priv,
675 struct mlx5_flow_destination dest[2] = {}; 675 struct mlx5_flow_destination dest[2] = {};
676 struct mlx5_flow_act flow_act = { 676 struct mlx5_flow_act flow_act = {
677 .action = attr->action, 677 .action = attr->action,
678 .has_flow_tag = true,
678 .flow_tag = attr->flow_tag, 679 .flow_tag = attr->flow_tag,
679 .encap_id = 0, 680 .encap_id = 0,
680 }; 681 };
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eq.c b/drivers/net/ethernet/mellanox/mlx5/core/eq.c
index 25106e996a96..c1c94974e16b 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eq.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eq.c
@@ -393,6 +393,51 @@ static void general_event_handler(struct mlx5_core_dev *dev,
393 } 393 }
394} 394}
395 395
396/* caller must eventually call mlx5_cq_put on the returned cq */
397static struct mlx5_core_cq *mlx5_eq_cq_get(struct mlx5_eq *eq, u32 cqn)
398{
399 struct mlx5_cq_table *table = &eq->cq_table;
400 struct mlx5_core_cq *cq = NULL;
401
402 spin_lock(&table->lock);
403 cq = radix_tree_lookup(&table->tree, cqn);
404 if (likely(cq))
405 mlx5_cq_hold(cq);
406 spin_unlock(&table->lock);
407
408 return cq;
409}
410
411static void mlx5_eq_cq_completion(struct mlx5_eq *eq, u32 cqn)
412{
413 struct mlx5_core_cq *cq = mlx5_eq_cq_get(eq, cqn);
414
415 if (unlikely(!cq)) {
416 mlx5_core_warn(eq->dev, "Completion event for bogus CQ 0x%x\n", cqn);
417 return;
418 }
419
420 ++cq->arm_sn;
421
422 cq->comp(cq);
423
424 mlx5_cq_put(cq);
425}
426
427static void mlx5_eq_cq_event(struct mlx5_eq *eq, u32 cqn, int event_type)
428{
429 struct mlx5_core_cq *cq = mlx5_eq_cq_get(eq, cqn);
430
431 if (unlikely(!cq)) {
432 mlx5_core_warn(eq->dev, "Async event for bogus CQ 0x%x\n", cqn);
433 return;
434 }
435
436 cq->event(cq, event_type);
437
438 mlx5_cq_put(cq);
439}
440
396static irqreturn_t mlx5_eq_int(int irq, void *eq_ptr) 441static irqreturn_t mlx5_eq_int(int irq, void *eq_ptr)
397{ 442{
398 struct mlx5_eq *eq = eq_ptr; 443 struct mlx5_eq *eq = eq_ptr;
@@ -415,7 +460,7 @@ static irqreturn_t mlx5_eq_int(int irq, void *eq_ptr)
415 switch (eqe->type) { 460 switch (eqe->type) {
416 case MLX5_EVENT_TYPE_COMP: 461 case MLX5_EVENT_TYPE_COMP:
417 cqn = be32_to_cpu(eqe->data.comp.cqn) & 0xffffff; 462 cqn = be32_to_cpu(eqe->data.comp.cqn) & 0xffffff;
418 mlx5_cq_completion(dev, cqn); 463 mlx5_eq_cq_completion(eq, cqn);
419 break; 464 break;
420 case MLX5_EVENT_TYPE_DCT_DRAINED: 465 case MLX5_EVENT_TYPE_DCT_DRAINED:
421 rsn = be32_to_cpu(eqe->data.dct.dctn) & 0xffffff; 466 rsn = be32_to_cpu(eqe->data.dct.dctn) & 0xffffff;
@@ -472,7 +517,7 @@ static irqreturn_t mlx5_eq_int(int irq, void *eq_ptr)
472 cqn = be32_to_cpu(eqe->data.cq_err.cqn) & 0xffffff; 517 cqn = be32_to_cpu(eqe->data.cq_err.cqn) & 0xffffff;
473 mlx5_core_warn(dev, "CQ error on CQN 0x%x, syndrome 0x%x\n", 518 mlx5_core_warn(dev, "CQ error on CQN 0x%x, syndrome 0x%x\n",
474 cqn, eqe->data.cq_err.syndrome); 519 cqn, eqe->data.cq_err.syndrome);
475 mlx5_cq_event(dev, cqn, eqe->type); 520 mlx5_eq_cq_event(eq, cqn, eqe->type);
476 break; 521 break;
477 522
478 case MLX5_EVENT_TYPE_PAGE_REQUEST: 523 case MLX5_EVENT_TYPE_PAGE_REQUEST:
@@ -567,6 +612,7 @@ int mlx5_create_map_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq, u8 vecidx,
567 int nent, u64 mask, const char *name, 612 int nent, u64 mask, const char *name,
568 enum mlx5_eq_type type) 613 enum mlx5_eq_type type)
569{ 614{
615 struct mlx5_cq_table *cq_table = &eq->cq_table;
570 u32 out[MLX5_ST_SZ_DW(create_eq_out)] = {0}; 616 u32 out[MLX5_ST_SZ_DW(create_eq_out)] = {0};
571 struct mlx5_priv *priv = &dev->priv; 617 struct mlx5_priv *priv = &dev->priv;
572 irq_handler_t handler; 618 irq_handler_t handler;
@@ -576,6 +622,11 @@ int mlx5_create_map_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq, u8 vecidx,
576 u32 *in; 622 u32 *in;
577 int err; 623 int err;
578 624
625 /* Init CQ table */
626 memset(cq_table, 0, sizeof(*cq_table));
627 spin_lock_init(&cq_table->lock);
628 INIT_RADIX_TREE(&cq_table->tree, GFP_ATOMIC);
629
579 eq->type = type; 630 eq->type = type;
580 eq->nent = roundup_pow_of_two(nent + MLX5_NUM_SPARE_EQE); 631 eq->nent = roundup_pow_of_two(nent + MLX5_NUM_SPARE_EQE);
581 eq->cons_index = 0; 632 eq->cons_index = 0;
@@ -669,7 +720,6 @@ err_buf:
669 mlx5_buf_free(dev, &eq->buf); 720 mlx5_buf_free(dev, &eq->buf);
670 return err; 721 return err;
671} 722}
672EXPORT_SYMBOL_GPL(mlx5_create_map_eq);
673 723
674int mlx5_destroy_unmap_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq) 724int mlx5_destroy_unmap_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq)
675{ 725{
@@ -696,7 +746,40 @@ int mlx5_destroy_unmap_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq)
696 746
697 return err; 747 return err;
698} 748}
699EXPORT_SYMBOL_GPL(mlx5_destroy_unmap_eq); 749
750int mlx5_eq_add_cq(struct mlx5_eq *eq, struct mlx5_core_cq *cq)
751{
752 struct mlx5_cq_table *table = &eq->cq_table;
753 int err;
754
755 spin_lock_irq(&table->lock);
756 err = radix_tree_insert(&table->tree, cq->cqn, cq);
757 spin_unlock_irq(&table->lock);
758
759 return err;
760}
761
762int mlx5_eq_del_cq(struct mlx5_eq *eq, struct mlx5_core_cq *cq)
763{
764 struct mlx5_cq_table *table = &eq->cq_table;
765 struct mlx5_core_cq *tmp;
766
767 spin_lock_irq(&table->lock);
768 tmp = radix_tree_delete(&table->tree, cq->cqn);
769 spin_unlock_irq(&table->lock);
770
771 if (!tmp) {
772 mlx5_core_warn(eq->dev, "cq 0x%x not found in eq 0x%x tree\n", eq->eqn, cq->cqn);
773 return -ENOENT;
774 }
775
776 if (tmp != cq) {
777 mlx5_core_warn(eq->dev, "corruption on cqn 0x%x in eq 0x%x\n", eq->eqn, cq->cqn);
778 return -EINVAL;
779 }
780
781 return 0;
782}
700 783
701int mlx5_eq_init(struct mlx5_core_dev *dev) 784int mlx5_eq_init(struct mlx5_core_dev *dev)
702{ 785{
@@ -840,4 +923,3 @@ int mlx5_core_eq_query(struct mlx5_core_dev *dev, struct mlx5_eq *eq,
840 MLX5_SET(query_eq_in, in, eq_number, eq->eqn); 923 MLX5_SET(query_eq_in, in, eq_number, eq->eqn);
841 return mlx5_cmd_exec(dev, in, sizeof(in), out, outlen); 924 return mlx5_cmd_exec(dev, in, sizeof(in), out, outlen);
842} 925}
843EXPORT_SYMBOL_GPL(mlx5_core_eq_query);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
index c2b1d7d351fc..77b7272eaaa8 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
@@ -1619,10 +1619,14 @@ int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs, int mode)
1619 esw_info(esw->dev, "E-Switch enable SRIOV: nvfs(%d) mode (%d)\n", nvfs, mode); 1619 esw_info(esw->dev, "E-Switch enable SRIOV: nvfs(%d) mode (%d)\n", nvfs, mode);
1620 esw->mode = mode; 1620 esw->mode = mode;
1621 1621
1622 if (mode == SRIOV_LEGACY) 1622 if (mode == SRIOV_LEGACY) {
1623 err = esw_create_legacy_fdb_table(esw, nvfs + 1); 1623 err = esw_create_legacy_fdb_table(esw, nvfs + 1);
1624 else 1624 } else {
1625 mlx5_reload_interface(esw->dev, MLX5_INTERFACE_PROTOCOL_IB);
1626
1625 err = esw_offloads_init(esw, nvfs + 1); 1627 err = esw_offloads_init(esw, nvfs + 1);
1628 }
1629
1626 if (err) 1630 if (err)
1627 goto abort; 1631 goto abort;
1628 1632
@@ -1644,12 +1648,17 @@ int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs, int mode)
1644 1648
1645abort: 1649abort:
1646 esw->mode = SRIOV_NONE; 1650 esw->mode = SRIOV_NONE;
1651
1652 if (mode == SRIOV_OFFLOADS)
1653 mlx5_reload_interface(esw->dev, MLX5_INTERFACE_PROTOCOL_IB);
1654
1647 return err; 1655 return err;
1648} 1656}
1649 1657
1650void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw) 1658void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw)
1651{ 1659{
1652 struct esw_mc_addr *mc_promisc; 1660 struct esw_mc_addr *mc_promisc;
1661 int old_mode;
1653 int nvports; 1662 int nvports;
1654 int i; 1663 int i;
1655 1664
@@ -1675,7 +1684,11 @@ void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw)
1675 else if (esw->mode == SRIOV_OFFLOADS) 1684 else if (esw->mode == SRIOV_OFFLOADS)
1676 esw_offloads_cleanup(esw, nvports); 1685 esw_offloads_cleanup(esw, nvports);
1677 1686
1687 old_mode = esw->mode;
1678 esw->mode = SRIOV_NONE; 1688 esw->mode = SRIOV_NONE;
1689
1690 if (old_mode == SRIOV_OFFLOADS)
1691 mlx5_reload_interface(esw->dev, MLX5_INTERFACE_PROTOCOL_IB);
1679} 1692}
1680 1693
1681int mlx5_eswitch_init(struct mlx5_core_dev *dev) 1694int mlx5_eswitch_init(struct mlx5_core_dev *dev)
@@ -2175,3 +2188,9 @@ free_out:
2175 kvfree(out); 2188 kvfree(out);
2176 return err; 2189 return err;
2177} 2190}
2191
2192u8 mlx5_eswitch_mode(struct mlx5_eswitch *esw)
2193{
2194 return esw->mode;
2195}
2196EXPORT_SYMBOL_GPL(mlx5_eswitch_mode);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
index 2fa037066b2f..98d2177d0806 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
@@ -37,19 +37,9 @@
37#include <linux/if_link.h> 37#include <linux/if_link.h>
38#include <net/devlink.h> 38#include <net/devlink.h>
39#include <linux/mlx5/device.h> 39#include <linux/mlx5/device.h>
40#include <linux/mlx5/eswitch.h>
40#include "lib/mpfs.h" 41#include "lib/mpfs.h"
41 42
42enum {
43 SRIOV_NONE,
44 SRIOV_LEGACY,
45 SRIOV_OFFLOADS
46};
47
48enum {
49 REP_ETH,
50 NUM_REP_TYPES,
51};
52
53#ifdef CONFIG_MLX5_ESWITCH 43#ifdef CONFIG_MLX5_ESWITCH
54 44
55#define MLX5_MAX_UC_PER_VPORT(dev) \ 45#define MLX5_MAX_UC_PER_VPORT(dev) \
@@ -139,29 +129,13 @@ struct mlx5_eswitch_fdb {
139 struct mlx5_flow_table *fdb; 129 struct mlx5_flow_table *fdb;
140 struct mlx5_flow_group *send_to_vport_grp; 130 struct mlx5_flow_group *send_to_vport_grp;
141 struct mlx5_flow_group *miss_grp; 131 struct mlx5_flow_group *miss_grp;
142 struct mlx5_flow_handle *miss_rule; 132 struct mlx5_flow_handle *miss_rule_uni;
133 struct mlx5_flow_handle *miss_rule_multi;
143 int vlan_push_pop_refcount; 134 int vlan_push_pop_refcount;
144 } offloads; 135 } offloads;
145 }; 136 };
146}; 137};
147 138
148struct mlx5_eswitch_rep;
149struct mlx5_eswitch_rep_if {
150 int (*load)(struct mlx5_core_dev *dev,
151 struct mlx5_eswitch_rep *rep);
152 void (*unload)(struct mlx5_eswitch_rep *rep);
153 void *priv;
154 bool valid;
155};
156
157struct mlx5_eswitch_rep {
158 struct mlx5_eswitch_rep_if rep_if[NUM_REP_TYPES];
159 u16 vport;
160 u8 hw_id[ETH_ALEN];
161 u16 vlan;
162 u32 vlan_refcount;
163};
164
165struct mlx5_esw_offload { 139struct mlx5_esw_offload {
166 struct mlx5_flow_table *ft_offloads; 140 struct mlx5_flow_table *ft_offloads;
167 struct mlx5_flow_group *vport_rx_group; 141 struct mlx5_flow_group *vport_rx_group;
@@ -231,9 +205,6 @@ int mlx5_eswitch_get_vport_config(struct mlx5_eswitch *esw,
231int mlx5_eswitch_get_vport_stats(struct mlx5_eswitch *esw, 205int mlx5_eswitch_get_vport_stats(struct mlx5_eswitch *esw,
232 int vport, 206 int vport,
233 struct ifla_vf_stats *vf_stats); 207 struct ifla_vf_stats *vf_stats);
234struct mlx5_flow_handle *
235mlx5_eswitch_add_send_to_vport_rule(struct mlx5_eswitch *esw, int vport,
236 u32 sqn);
237void mlx5_eswitch_del_send_to_vport_rule(struct mlx5_flow_handle *rule); 208void mlx5_eswitch_del_send_to_vport_rule(struct mlx5_flow_handle *rule);
238 209
239struct mlx5_flow_spec; 210struct mlx5_flow_spec;
@@ -278,13 +249,6 @@ int mlx5_devlink_eswitch_inline_mode_get(struct devlink *devlink, u8 *mode);
278int mlx5_eswitch_inline_mode_get(struct mlx5_eswitch *esw, int nvfs, u8 *mode); 249int mlx5_eswitch_inline_mode_get(struct mlx5_eswitch *esw, int nvfs, u8 *mode);
279int mlx5_devlink_eswitch_encap_mode_set(struct devlink *devlink, u8 encap); 250int mlx5_devlink_eswitch_encap_mode_set(struct devlink *devlink, u8 encap);
280int mlx5_devlink_eswitch_encap_mode_get(struct devlink *devlink, u8 *encap); 251int mlx5_devlink_eswitch_encap_mode_get(struct devlink *devlink, u8 *encap);
281void mlx5_eswitch_register_vport_rep(struct mlx5_eswitch *esw,
282 int vport_index,
283 struct mlx5_eswitch_rep_if *rep_if,
284 u8 rep_type);
285void mlx5_eswitch_unregister_vport_rep(struct mlx5_eswitch *esw,
286 int vport_index,
287 u8 rep_type);
288void *mlx5_eswitch_get_uplink_priv(struct mlx5_eswitch *esw, u8 rep_type); 252void *mlx5_eswitch_get_uplink_priv(struct mlx5_eswitch *esw, u8 rep_type);
289 253
290int mlx5_eswitch_add_vlan_action(struct mlx5_eswitch *esw, 254int mlx5_eswitch_add_vlan_action(struct mlx5_eswitch *esw,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
index 99f583a15cc3..0a8303c1b52f 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
@@ -338,6 +338,7 @@ out:
338 kvfree(spec); 338 kvfree(spec);
339 return flow_rule; 339 return flow_rule;
340} 340}
341EXPORT_SYMBOL(mlx5_eswitch_add_send_to_vport_rule);
341 342
342void mlx5_eswitch_del_send_to_vport_rule(struct mlx5_flow_handle *rule) 343void mlx5_eswitch_del_send_to_vport_rule(struct mlx5_flow_handle *rule)
343{ 344{
@@ -350,7 +351,11 @@ static int esw_add_fdb_miss_rule(struct mlx5_eswitch *esw)
350 struct mlx5_flow_destination dest = {}; 351 struct mlx5_flow_destination dest = {};
351 struct mlx5_flow_handle *flow_rule = NULL; 352 struct mlx5_flow_handle *flow_rule = NULL;
352 struct mlx5_flow_spec *spec; 353 struct mlx5_flow_spec *spec;
354 void *headers_c;
355 void *headers_v;
353 int err = 0; 356 int err = 0;
357 u8 *dmac_c;
358 u8 *dmac_v;
354 359
355 spec = kvzalloc(sizeof(*spec), GFP_KERNEL); 360 spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
356 if (!spec) { 361 if (!spec) {
@@ -358,6 +363,13 @@ static int esw_add_fdb_miss_rule(struct mlx5_eswitch *esw)
358 goto out; 363 goto out;
359 } 364 }
360 365
366 spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
367 headers_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
368 outer_headers);
369 dmac_c = MLX5_ADDR_OF(fte_match_param, headers_c,
370 outer_headers.dmac_47_16);
371 dmac_c[0] = 0x01;
372
361 dest.type = MLX5_FLOW_DESTINATION_TYPE_VPORT; 373 dest.type = MLX5_FLOW_DESTINATION_TYPE_VPORT;
362 dest.vport_num = 0; 374 dest.vport_num = 0;
363 flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST; 375 flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
@@ -366,11 +378,28 @@ static int esw_add_fdb_miss_rule(struct mlx5_eswitch *esw)
366 &flow_act, &dest, 1); 378 &flow_act, &dest, 1);
367 if (IS_ERR(flow_rule)) { 379 if (IS_ERR(flow_rule)) {
368 err = PTR_ERR(flow_rule); 380 err = PTR_ERR(flow_rule);
369 esw_warn(esw->dev, "FDB: Failed to add miss flow rule err %d\n", err); 381 esw_warn(esw->dev, "FDB: Failed to add unicast miss flow rule err %d\n", err);
370 goto out; 382 goto out;
371 } 383 }
372 384
373 esw->fdb_table.offloads.miss_rule = flow_rule; 385 esw->fdb_table.offloads.miss_rule_uni = flow_rule;
386
387 headers_v = MLX5_ADDR_OF(fte_match_param, spec->match_value,
388 outer_headers);
389 dmac_v = MLX5_ADDR_OF(fte_match_param, headers_v,
390 outer_headers.dmac_47_16);
391 dmac_v[0] = 0x01;
392 flow_rule = mlx5_add_flow_rules(esw->fdb_table.offloads.fdb, spec,
393 &flow_act, &dest, 1);
394 if (IS_ERR(flow_rule)) {
395 err = PTR_ERR(flow_rule);
396 esw_warn(esw->dev, "FDB: Failed to add multicast miss flow rule err %d\n", err);
397 mlx5_del_flow_rules(esw->fdb_table.offloads.miss_rule_uni);
398 goto out;
399 }
400
401 esw->fdb_table.offloads.miss_rule_multi = flow_rule;
402
374out: 403out:
375 kvfree(spec); 404 kvfree(spec);
376 return err; 405 return err;
@@ -426,6 +455,7 @@ static void esw_destroy_offloads_fast_fdb_table(struct mlx5_eswitch *esw)
426} 455}
427 456
428#define MAX_PF_SQ 256 457#define MAX_PF_SQ 256
458#define MAX_SQ_NVPORTS 32
429 459
430static int esw_create_offloads_fdb_tables(struct mlx5_eswitch *esw, int nvports) 460static int esw_create_offloads_fdb_tables(struct mlx5_eswitch *esw, int nvports)
431{ 461{
@@ -438,6 +468,7 @@ static int esw_create_offloads_fdb_tables(struct mlx5_eswitch *esw, int nvports)
438 struct mlx5_flow_group *g; 468 struct mlx5_flow_group *g;
439 void *match_criteria; 469 void *match_criteria;
440 u32 *flow_group_in; 470 u32 *flow_group_in;
471 u8 *dmac;
441 472
442 esw_debug(esw->dev, "Create offloads FDB Tables\n"); 473 esw_debug(esw->dev, "Create offloads FDB Tables\n");
443 flow_group_in = kvzalloc(inlen, GFP_KERNEL); 474 flow_group_in = kvzalloc(inlen, GFP_KERNEL);
@@ -455,7 +486,7 @@ static int esw_create_offloads_fdb_tables(struct mlx5_eswitch *esw, int nvports)
455 if (err) 486 if (err)
456 goto fast_fdb_err; 487 goto fast_fdb_err;
457 488
458 table_size = nvports + MAX_PF_SQ + 1; 489 table_size = nvports * MAX_SQ_NVPORTS + MAX_PF_SQ + 2;
459 490
460 ft_attr.max_fte = table_size; 491 ft_attr.max_fte = table_size;
461 ft_attr.prio = FDB_SLOW_PATH; 492 ft_attr.prio = FDB_SLOW_PATH;
@@ -478,7 +509,7 @@ static int esw_create_offloads_fdb_tables(struct mlx5_eswitch *esw, int nvports)
478 MLX5_SET_TO_ONES(fte_match_param, match_criteria, misc_parameters.source_sqn); 509 MLX5_SET_TO_ONES(fte_match_param, match_criteria, misc_parameters.source_sqn);
479 MLX5_SET_TO_ONES(fte_match_param, match_criteria, misc_parameters.source_port); 510 MLX5_SET_TO_ONES(fte_match_param, match_criteria, misc_parameters.source_port);
480 511
481 ix = nvports + MAX_PF_SQ; 512 ix = nvports * MAX_SQ_NVPORTS + MAX_PF_SQ;
482 MLX5_SET(create_flow_group_in, flow_group_in, start_flow_index, 0); 513 MLX5_SET(create_flow_group_in, flow_group_in, start_flow_index, 0);
483 MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, ix - 1); 514 MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, ix - 1);
484 515
@@ -492,10 +523,16 @@ static int esw_create_offloads_fdb_tables(struct mlx5_eswitch *esw, int nvports)
492 523
493 /* create miss group */ 524 /* create miss group */
494 memset(flow_group_in, 0, inlen); 525 memset(flow_group_in, 0, inlen);
495 MLX5_SET(create_flow_group_in, flow_group_in, match_criteria_enable, 0); 526 MLX5_SET(create_flow_group_in, flow_group_in, match_criteria_enable,
527 MLX5_MATCH_OUTER_HEADERS);
528 match_criteria = MLX5_ADDR_OF(create_flow_group_in, flow_group_in,
529 match_criteria);
530 dmac = MLX5_ADDR_OF(fte_match_param, match_criteria,
531 outer_headers.dmac_47_16);
532 dmac[0] = 0x01;
496 533
497 MLX5_SET(create_flow_group_in, flow_group_in, start_flow_index, ix); 534 MLX5_SET(create_flow_group_in, flow_group_in, start_flow_index, ix);
498 MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, ix + 1); 535 MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, ix + 2);
499 536
500 g = mlx5_create_flow_group(fdb, flow_group_in); 537 g = mlx5_create_flow_group(fdb, flow_group_in);
501 if (IS_ERR(g)) { 538 if (IS_ERR(g)) {
@@ -531,7 +568,8 @@ static void esw_destroy_offloads_fdb_tables(struct mlx5_eswitch *esw)
531 return; 568 return;
532 569
533 esw_debug(esw->dev, "Destroy offloads FDB Tables\n"); 570 esw_debug(esw->dev, "Destroy offloads FDB Tables\n");
534 mlx5_del_flow_rules(esw->fdb_table.offloads.miss_rule); 571 mlx5_del_flow_rules(esw->fdb_table.offloads.miss_rule_multi);
572 mlx5_del_flow_rules(esw->fdb_table.offloads.miss_rule_uni);
535 mlx5_destroy_flow_group(esw->fdb_table.offloads.send_to_vport_grp); 573 mlx5_destroy_flow_group(esw->fdb_table.offloads.send_to_vport_grp);
536 mlx5_destroy_flow_group(esw->fdb_table.offloads.miss_grp); 574 mlx5_destroy_flow_group(esw->fdb_table.offloads.miss_grp);
537 575
@@ -789,14 +827,9 @@ int esw_offloads_init(struct mlx5_eswitch *esw, int nvports)
789{ 827{
790 int err; 828 int err;
791 829
792 /* disable PF RoCE so missed packets don't go through RoCE steering */
793 mlx5_dev_list_lock();
794 mlx5_remove_dev_by_protocol(esw->dev, MLX5_INTERFACE_PROTOCOL_IB);
795 mlx5_dev_list_unlock();
796
797 err = esw_create_offloads_fdb_tables(esw, nvports); 830 err = esw_create_offloads_fdb_tables(esw, nvports);
798 if (err) 831 if (err)
799 goto create_fdb_err; 832 return err;
800 833
801 err = esw_create_offloads_table(esw); 834 err = esw_create_offloads_table(esw);
802 if (err) 835 if (err)
@@ -821,12 +854,6 @@ create_fg_err:
821create_ft_err: 854create_ft_err:
822 esw_destroy_offloads_fdb_tables(esw); 855 esw_destroy_offloads_fdb_tables(esw);
823 856
824create_fdb_err:
825 /* enable back PF RoCE */
826 mlx5_dev_list_lock();
827 mlx5_add_dev_by_protocol(esw->dev, MLX5_INTERFACE_PROTOCOL_IB);
828 mlx5_dev_list_unlock();
829
830 return err; 857 return err;
831} 858}
832 859
@@ -844,9 +871,7 @@ static int esw_offloads_stop(struct mlx5_eswitch *esw)
844 } 871 }
845 872
846 /* enable back PF RoCE */ 873 /* enable back PF RoCE */
847 mlx5_dev_list_lock(); 874 mlx5_reload_interface(esw->dev, MLX5_INTERFACE_PROTOCOL_IB);
848 mlx5_add_dev_by_protocol(esw->dev, MLX5_INTERFACE_PROTOCOL_IB);
849 mlx5_dev_list_unlock();
850 875
851 return err; 876 return err;
852} 877}
@@ -1160,10 +1185,12 @@ void mlx5_eswitch_register_vport_rep(struct mlx5_eswitch *esw,
1160 1185
1161 rep_if->load = __rep_if->load; 1186 rep_if->load = __rep_if->load;
1162 rep_if->unload = __rep_if->unload; 1187 rep_if->unload = __rep_if->unload;
1188 rep_if->get_proto_dev = __rep_if->get_proto_dev;
1163 rep_if->priv = __rep_if->priv; 1189 rep_if->priv = __rep_if->priv;
1164 1190
1165 rep_if->valid = true; 1191 rep_if->valid = true;
1166} 1192}
1193EXPORT_SYMBOL(mlx5_eswitch_register_vport_rep);
1167 1194
1168void mlx5_eswitch_unregister_vport_rep(struct mlx5_eswitch *esw, 1195void mlx5_eswitch_unregister_vport_rep(struct mlx5_eswitch *esw,
1169 int vport_index, u8 rep_type) 1196 int vport_index, u8 rep_type)
@@ -1178,6 +1205,7 @@ void mlx5_eswitch_unregister_vport_rep(struct mlx5_eswitch *esw,
1178 1205
1179 rep->rep_if[rep_type].valid = false; 1206 rep->rep_if[rep_type].valid = false;
1180} 1207}
1208EXPORT_SYMBOL(mlx5_eswitch_unregister_vport_rep);
1181 1209
1182void *mlx5_eswitch_get_uplink_priv(struct mlx5_eswitch *esw, u8 rep_type) 1210void *mlx5_eswitch_get_uplink_priv(struct mlx5_eswitch *esw, u8 rep_type)
1183{ 1211{
@@ -1188,3 +1216,35 @@ void *mlx5_eswitch_get_uplink_priv(struct mlx5_eswitch *esw, u8 rep_type)
1188 rep = &offloads->vport_reps[UPLINK_REP_INDEX]; 1216 rep = &offloads->vport_reps[UPLINK_REP_INDEX];
1189 return rep->rep_if[rep_type].priv; 1217 return rep->rep_if[rep_type].priv;
1190} 1218}
1219
1220void *mlx5_eswitch_get_proto_dev(struct mlx5_eswitch *esw,
1221 int vport,
1222 u8 rep_type)
1223{
1224 struct mlx5_esw_offload *offloads = &esw->offloads;
1225 struct mlx5_eswitch_rep *rep;
1226
1227 if (vport == FDB_UPLINK_VPORT)
1228 vport = UPLINK_REP_INDEX;
1229
1230 rep = &offloads->vport_reps[vport];
1231
1232 if (rep->rep_if[rep_type].valid &&
1233 rep->rep_if[rep_type].get_proto_dev)
1234 return rep->rep_if[rep_type].get_proto_dev(rep);
1235 return NULL;
1236}
1237EXPORT_SYMBOL(mlx5_eswitch_get_proto_dev);
1238
1239void *mlx5_eswitch_uplink_get_proto_dev(struct mlx5_eswitch *esw, u8 rep_type)
1240{
1241 return mlx5_eswitch_get_proto_dev(esw, UPLINK_REP_INDEX, rep_type);
1242}
1243EXPORT_SYMBOL(mlx5_eswitch_uplink_get_proto_dev);
1244
1245struct mlx5_eswitch_rep *mlx5_eswitch_vport_rep(struct mlx5_eswitch *esw,
1246 int vport)
1247{
1248 return &esw->offloads.vport_reps[vport];
1249}
1250EXPORT_SYMBOL(mlx5_eswitch_vport_rep);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c
index 35d0e33381ca..4f1568528738 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c
@@ -31,49 +31,91 @@
31 * 31 *
32 */ 32 */
33 33
34#include <linux/rhashtable.h>
34#include <linux/mlx5/driver.h> 35#include <linux/mlx5/driver.h>
36#include <linux/mlx5/fs_helpers.h>
37#include <linux/mlx5/fs.h>
38#include <linux/rbtree.h>
35 39
36#include "mlx5_core.h" 40#include "mlx5_core.h"
41#include "fs_cmd.h"
37#include "fpga/ipsec.h" 42#include "fpga/ipsec.h"
38#include "fpga/sdk.h" 43#include "fpga/sdk.h"
39#include "fpga/core.h" 44#include "fpga/core.h"
40 45
41#define SBU_QP_QUEUE_SIZE 8 46#define SBU_QP_QUEUE_SIZE 8
47#define MLX5_FPGA_IPSEC_CMD_TIMEOUT_MSEC (60 * 1000)
42 48
43enum mlx5_ipsec_response_syndrome { 49enum mlx5_fpga_ipsec_cmd_status {
44 MLX5_IPSEC_RESPONSE_SUCCESS = 0, 50 MLX5_FPGA_IPSEC_CMD_PENDING,
45 MLX5_IPSEC_RESPONSE_ILLEGAL_REQUEST = 1, 51 MLX5_FPGA_IPSEC_CMD_SEND_FAIL,
46 MLX5_IPSEC_RESPONSE_SADB_ISSUE = 2, 52 MLX5_FPGA_IPSEC_CMD_COMPLETE,
47 MLX5_IPSEC_RESPONSE_WRITE_RESPONSE_ISSUE = 3,
48}; 53};
49 54
50enum mlx5_fpga_ipsec_sacmd_status { 55struct mlx5_fpga_ipsec_cmd_context {
51 MLX5_FPGA_IPSEC_SACMD_PENDING,
52 MLX5_FPGA_IPSEC_SACMD_SEND_FAIL,
53 MLX5_FPGA_IPSEC_SACMD_COMPLETE,
54};
55
56struct mlx5_ipsec_command_context {
57 struct mlx5_fpga_dma_buf buf; 56 struct mlx5_fpga_dma_buf buf;
58 struct mlx5_accel_ipsec_sa sa; 57 enum mlx5_fpga_ipsec_cmd_status status;
59 enum mlx5_fpga_ipsec_sacmd_status status; 58 struct mlx5_ifc_fpga_ipsec_cmd_resp resp;
60 int status_code; 59 int status_code;
61 struct completion complete; 60 struct completion complete;
62 struct mlx5_fpga_device *dev; 61 struct mlx5_fpga_device *dev;
63 struct list_head list; /* Item in pending_cmds */ 62 struct list_head list; /* Item in pending_cmds */
63 u8 command[0];
64};
65
66struct mlx5_fpga_esp_xfrm;
67
68struct mlx5_fpga_ipsec_sa_ctx {
69 struct rhash_head hash;
70 struct mlx5_ifc_fpga_ipsec_sa hw_sa;
71 struct mlx5_core_dev *dev;
72 struct mlx5_fpga_esp_xfrm *fpga_xfrm;
73};
74
75struct mlx5_fpga_esp_xfrm {
76 unsigned int num_rules;
77 struct mlx5_fpga_ipsec_sa_ctx *sa_ctx;
78 struct mutex lock; /* xfrm lock */
79 struct mlx5_accel_esp_xfrm accel_xfrm;
80};
81
82struct mlx5_fpga_ipsec_rule {
83 struct rb_node node;
84 struct fs_fte *fte;
85 struct mlx5_fpga_ipsec_sa_ctx *ctx;
64}; 86};
65 87
66struct mlx5_ipsec_sadb_resp { 88static const struct rhashtable_params rhash_sa = {
67 __be32 syndrome; 89 .key_len = FIELD_SIZEOF(struct mlx5_fpga_ipsec_sa_ctx, hw_sa),
68 __be32 sw_sa_handle; 90 .key_offset = offsetof(struct mlx5_fpga_ipsec_sa_ctx, hw_sa),
69 u8 reserved[24]; 91 .head_offset = offsetof(struct mlx5_fpga_ipsec_sa_ctx, hash),
70} __packed; 92 .automatic_shrinking = true,
93 .min_size = 1,
94};
71 95
72struct mlx5_fpga_ipsec { 96struct mlx5_fpga_ipsec {
97 struct mlx5_fpga_device *fdev;
73 struct list_head pending_cmds; 98 struct list_head pending_cmds;
74 spinlock_t pending_cmds_lock; /* Protects pending_cmds */ 99 spinlock_t pending_cmds_lock; /* Protects pending_cmds */
75 u32 caps[MLX5_ST_SZ_DW(ipsec_extended_cap)]; 100 u32 caps[MLX5_ST_SZ_DW(ipsec_extended_cap)];
76 struct mlx5_fpga_conn *conn; 101 struct mlx5_fpga_conn *conn;
102
103 struct notifier_block fs_notifier_ingress_bypass;
104 struct notifier_block fs_notifier_egress;
105
106 /* Map hardware SA --> SA context
107 * (mlx5_fpga_ipsec_sa) (mlx5_fpga_ipsec_sa_ctx)
108 * We will use this hash to avoid SAs duplication in fpga which
109 * aren't allowed
110 */
111 struct rhashtable sa_hash; /* hw_sa -> mlx5_fpga_ipsec_sa_ctx */
112 struct mutex sa_hash_lock;
113
114 /* Tree holding all rules for this fpga device
115 * Key for searching a rule (mlx5_fpga_ipsec_rule) is (ft, id)
116 */
117 struct rb_root rules_rb;
118 struct mutex rules_rb_lock; /* rules lock */
77}; 119};
78 120
79static bool mlx5_fpga_is_ipsec_device(struct mlx5_core_dev *mdev) 121static bool mlx5_fpga_is_ipsec_device(struct mlx5_core_dev *mdev)
@@ -97,28 +139,29 @@ static void mlx5_fpga_ipsec_send_complete(struct mlx5_fpga_conn *conn,
97 struct mlx5_fpga_dma_buf *buf, 139 struct mlx5_fpga_dma_buf *buf,
98 u8 status) 140 u8 status)
99{ 141{
100 struct mlx5_ipsec_command_context *context; 142 struct mlx5_fpga_ipsec_cmd_context *context;
101 143
102 if (status) { 144 if (status) {
103 context = container_of(buf, struct mlx5_ipsec_command_context, 145 context = container_of(buf, struct mlx5_fpga_ipsec_cmd_context,
104 buf); 146 buf);
105 mlx5_fpga_warn(fdev, "IPSec command send failed with status %u\n", 147 mlx5_fpga_warn(fdev, "IPSec command send failed with status %u\n",
106 status); 148 status);
107 context->status = MLX5_FPGA_IPSEC_SACMD_SEND_FAIL; 149 context->status = MLX5_FPGA_IPSEC_CMD_SEND_FAIL;
108 complete(&context->complete); 150 complete(&context->complete);
109 } 151 }
110} 152}
111 153
112static inline int syndrome_to_errno(enum mlx5_ipsec_response_syndrome syndrome) 154static inline
155int syndrome_to_errno(enum mlx5_ifc_fpga_ipsec_response_syndrome syndrome)
113{ 156{
114 switch (syndrome) { 157 switch (syndrome) {
115 case MLX5_IPSEC_RESPONSE_SUCCESS: 158 case MLX5_FPGA_IPSEC_RESPONSE_SUCCESS:
116 return 0; 159 return 0;
117 case MLX5_IPSEC_RESPONSE_SADB_ISSUE: 160 case MLX5_FPGA_IPSEC_RESPONSE_SADB_ISSUE:
118 return -EEXIST; 161 return -EEXIST;
119 case MLX5_IPSEC_RESPONSE_ILLEGAL_REQUEST: 162 case MLX5_FPGA_IPSEC_RESPONSE_ILLEGAL_REQUEST:
120 return -EINVAL; 163 return -EINVAL;
121 case MLX5_IPSEC_RESPONSE_WRITE_RESPONSE_ISSUE: 164 case MLX5_FPGA_IPSEC_RESPONSE_WRITE_RESPONSE_ISSUE:
122 return -EIO; 165 return -EIO;
123 } 166 }
124 return -EIO; 167 return -EIO;
@@ -126,9 +169,9 @@ static inline int syndrome_to_errno(enum mlx5_ipsec_response_syndrome syndrome)
126 169
127static void mlx5_fpga_ipsec_recv(void *cb_arg, struct mlx5_fpga_dma_buf *buf) 170static void mlx5_fpga_ipsec_recv(void *cb_arg, struct mlx5_fpga_dma_buf *buf)
128{ 171{
129 struct mlx5_ipsec_sadb_resp *resp = buf->sg[0].data; 172 struct mlx5_ifc_fpga_ipsec_cmd_resp *resp = buf->sg[0].data;
130 struct mlx5_ipsec_command_context *context; 173 struct mlx5_fpga_ipsec_cmd_context *context;
131 enum mlx5_ipsec_response_syndrome syndrome; 174 enum mlx5_ifc_fpga_ipsec_response_syndrome syndrome;
132 struct mlx5_fpga_device *fdev = cb_arg; 175 struct mlx5_fpga_device *fdev = cb_arg;
133 unsigned long flags; 176 unsigned long flags;
134 177
@@ -138,12 +181,12 @@ static void mlx5_fpga_ipsec_recv(void *cb_arg, struct mlx5_fpga_dma_buf *buf)
138 return; 181 return;
139 } 182 }
140 183
141 mlx5_fpga_dbg(fdev, "mlx5_ipsec recv_cb syndrome %08x sa_id %x\n", 184 mlx5_fpga_dbg(fdev, "mlx5_ipsec recv_cb syndrome %08x\n",
142 ntohl(resp->syndrome), ntohl(resp->sw_sa_handle)); 185 ntohl(resp->syndrome));
143 186
144 spin_lock_irqsave(&fdev->ipsec->pending_cmds_lock, flags); 187 spin_lock_irqsave(&fdev->ipsec->pending_cmds_lock, flags);
145 context = list_first_entry_or_null(&fdev->ipsec->pending_cmds, 188 context = list_first_entry_or_null(&fdev->ipsec->pending_cmds,
146 struct mlx5_ipsec_command_context, 189 struct mlx5_fpga_ipsec_cmd_context,
147 list); 190 list);
148 if (context) 191 if (context)
149 list_del(&context->list); 192 list_del(&context->list);
@@ -155,51 +198,48 @@ static void mlx5_fpga_ipsec_recv(void *cb_arg, struct mlx5_fpga_dma_buf *buf)
155 } 198 }
156 mlx5_fpga_dbg(fdev, "Handling response for %p\n", context); 199 mlx5_fpga_dbg(fdev, "Handling response for %p\n", context);
157 200
158 if (context->sa.sw_sa_handle != resp->sw_sa_handle) {
159 mlx5_fpga_err(fdev, "mismatch SA handle. cmd 0x%08x vs resp 0x%08x\n",
160 ntohl(context->sa.sw_sa_handle),
161 ntohl(resp->sw_sa_handle));
162 return;
163 }
164
165 syndrome = ntohl(resp->syndrome); 201 syndrome = ntohl(resp->syndrome);
166 context->status_code = syndrome_to_errno(syndrome); 202 context->status_code = syndrome_to_errno(syndrome);
167 context->status = MLX5_FPGA_IPSEC_SACMD_COMPLETE; 203 context->status = MLX5_FPGA_IPSEC_CMD_COMPLETE;
204 memcpy(&context->resp, resp, sizeof(*resp));
168 205
169 if (context->status_code) 206 if (context->status_code)
170 mlx5_fpga_warn(fdev, "IPSec SADB command failed with syndrome %08x\n", 207 mlx5_fpga_warn(fdev, "IPSec command failed with syndrome %08x\n",
171 syndrome); 208 syndrome);
209
172 complete(&context->complete); 210 complete(&context->complete);
173} 211}
174 212
175void *mlx5_fpga_ipsec_sa_cmd_exec(struct mlx5_core_dev *mdev, 213static void *mlx5_fpga_ipsec_cmd_exec(struct mlx5_core_dev *mdev,
176 struct mlx5_accel_ipsec_sa *cmd) 214 const void *cmd, int cmd_size)
177{ 215{
178 struct mlx5_ipsec_command_context *context; 216 struct mlx5_fpga_ipsec_cmd_context *context;
179 struct mlx5_fpga_device *fdev = mdev->fpga; 217 struct mlx5_fpga_device *fdev = mdev->fpga;
180 unsigned long flags; 218 unsigned long flags;
181 int res = 0; 219 int res;
182 220
183 BUILD_BUG_ON((sizeof(struct mlx5_accel_ipsec_sa) & 3) != 0);
184 if (!fdev || !fdev->ipsec) 221 if (!fdev || !fdev->ipsec)
185 return ERR_PTR(-EOPNOTSUPP); 222 return ERR_PTR(-EOPNOTSUPP);
186 223
187 context = kzalloc(sizeof(*context), GFP_ATOMIC); 224 if (cmd_size & 3)
225 return ERR_PTR(-EINVAL);
226
227 context = kzalloc(sizeof(*context) + cmd_size, GFP_ATOMIC);
188 if (!context) 228 if (!context)
189 return ERR_PTR(-ENOMEM); 229 return ERR_PTR(-ENOMEM);
190 230
191 memcpy(&context->sa, cmd, sizeof(*cmd)); 231 context->status = MLX5_FPGA_IPSEC_CMD_PENDING;
232 context->dev = fdev;
192 context->buf.complete = mlx5_fpga_ipsec_send_complete; 233 context->buf.complete = mlx5_fpga_ipsec_send_complete;
193 context->buf.sg[0].size = sizeof(context->sa);
194 context->buf.sg[0].data = &context->sa;
195 init_completion(&context->complete); 234 init_completion(&context->complete);
196 context->dev = fdev; 235 memcpy(&context->command, cmd, cmd_size);
236 context->buf.sg[0].size = cmd_size;
237 context->buf.sg[0].data = &context->command;
238
197 spin_lock_irqsave(&fdev->ipsec->pending_cmds_lock, flags); 239 spin_lock_irqsave(&fdev->ipsec->pending_cmds_lock, flags);
198 list_add_tail(&context->list, &fdev->ipsec->pending_cmds); 240 list_add_tail(&context->list, &fdev->ipsec->pending_cmds);
199 spin_unlock_irqrestore(&fdev->ipsec->pending_cmds_lock, flags); 241 spin_unlock_irqrestore(&fdev->ipsec->pending_cmds_lock, flags);
200 242
201 context->status = MLX5_FPGA_IPSEC_SACMD_PENDING;
202
203 res = mlx5_fpga_sbu_conn_sendmsg(fdev->ipsec->conn, &context->buf); 243 res = mlx5_fpga_sbu_conn_sendmsg(fdev->ipsec->conn, &context->buf);
204 if (res) { 244 if (res) {
205 mlx5_fpga_warn(fdev, "Failure sending IPSec command: %d\n", 245 mlx5_fpga_warn(fdev, "Failure sending IPSec command: %d\n",
@@ -214,47 +254,103 @@ void *mlx5_fpga_ipsec_sa_cmd_exec(struct mlx5_core_dev *mdev,
214 return context; 254 return context;
215} 255}
216 256
217int mlx5_fpga_ipsec_sa_cmd_wait(void *ctx) 257static int mlx5_fpga_ipsec_cmd_wait(void *ctx)
218{ 258{
219 struct mlx5_ipsec_command_context *context = ctx; 259 struct mlx5_fpga_ipsec_cmd_context *context = ctx;
260 unsigned long timeout =
261 msecs_to_jiffies(MLX5_FPGA_IPSEC_CMD_TIMEOUT_MSEC);
220 int res; 262 int res;
221 263
222 res = wait_for_completion_killable(&context->complete); 264 res = wait_for_completion_timeout(&context->complete, timeout);
223 if (res) { 265 if (!res) {
224 mlx5_fpga_warn(context->dev, "Failure waiting for IPSec command response\n"); 266 mlx5_fpga_warn(context->dev, "Failure waiting for IPSec command response\n");
225 return -EINTR; 267 return -ETIMEDOUT;
226 } 268 }
227 269
228 if (context->status == MLX5_FPGA_IPSEC_SACMD_COMPLETE) 270 if (context->status == MLX5_FPGA_IPSEC_CMD_COMPLETE)
229 res = context->status_code; 271 res = context->status_code;
230 else 272 else
231 res = -EIO; 273 res = -EIO;
232 274
233 kfree(context);
234 return res; 275 return res;
235} 276}
236 277
278static inline bool is_v2_sadb_supported(struct mlx5_fpga_ipsec *fipsec)
279{
280 if (MLX5_GET(ipsec_extended_cap, fipsec->caps, v2_command))
281 return true;
282 return false;
283}
284
285static int mlx5_fpga_ipsec_update_hw_sa(struct mlx5_fpga_device *fdev,
286 struct mlx5_ifc_fpga_ipsec_sa *hw_sa,
287 int opcode)
288{
289 struct mlx5_core_dev *dev = fdev->mdev;
290 struct mlx5_ifc_fpga_ipsec_sa *sa;
291 struct mlx5_fpga_ipsec_cmd_context *cmd_context;
292 size_t sa_cmd_size;
293 int err;
294
295 hw_sa->ipsec_sa_v1.cmd = htonl(opcode);
296 if (is_v2_sadb_supported(fdev->ipsec))
297 sa_cmd_size = sizeof(*hw_sa);
298 else
299 sa_cmd_size = sizeof(hw_sa->ipsec_sa_v1);
300
301 cmd_context = (struct mlx5_fpga_ipsec_cmd_context *)
302 mlx5_fpga_ipsec_cmd_exec(dev, hw_sa, sa_cmd_size);
303 if (IS_ERR(cmd_context))
304 return PTR_ERR(cmd_context);
305
306 err = mlx5_fpga_ipsec_cmd_wait(cmd_context);
307 if (err)
308 goto out;
309
310 sa = (struct mlx5_ifc_fpga_ipsec_sa *)&cmd_context->command;
311 if (sa->ipsec_sa_v1.sw_sa_handle != cmd_context->resp.sw_sa_handle) {
312 mlx5_fpga_err(fdev, "mismatch SA handle. cmd 0x%08x vs resp 0x%08x\n",
313 ntohl(sa->ipsec_sa_v1.sw_sa_handle),
314 ntohl(cmd_context->resp.sw_sa_handle));
315 err = -EIO;
316 }
317
318out:
319 kfree(cmd_context);
320 return err;
321}
322
237u32 mlx5_fpga_ipsec_device_caps(struct mlx5_core_dev *mdev) 323u32 mlx5_fpga_ipsec_device_caps(struct mlx5_core_dev *mdev)
238{ 324{
239 struct mlx5_fpga_device *fdev = mdev->fpga; 325 struct mlx5_fpga_device *fdev = mdev->fpga;
240 u32 ret = 0; 326 u32 ret = 0;
241 327
242 if (mlx5_fpga_is_ipsec_device(mdev)) 328 if (mlx5_fpga_is_ipsec_device(mdev)) {
243 ret |= MLX5_ACCEL_IPSEC_DEVICE; 329 ret |= MLX5_ACCEL_IPSEC_CAP_DEVICE;
244 else 330 ret |= MLX5_ACCEL_IPSEC_CAP_REQUIRED_METADATA;
331 } else {
245 return ret; 332 return ret;
333 }
246 334
247 if (!fdev->ipsec) 335 if (!fdev->ipsec)
248 return ret; 336 return ret;
249 337
250 if (MLX5_GET(ipsec_extended_cap, fdev->ipsec->caps, esp)) 338 if (MLX5_GET(ipsec_extended_cap, fdev->ipsec->caps, esp))
251 ret |= MLX5_ACCEL_IPSEC_ESP; 339 ret |= MLX5_ACCEL_IPSEC_CAP_ESP;
252 340
253 if (MLX5_GET(ipsec_extended_cap, fdev->ipsec->caps, ipv6)) 341 if (MLX5_GET(ipsec_extended_cap, fdev->ipsec->caps, ipv6))
254 ret |= MLX5_ACCEL_IPSEC_IPV6; 342 ret |= MLX5_ACCEL_IPSEC_CAP_IPV6;
255 343
256 if (MLX5_GET(ipsec_extended_cap, fdev->ipsec->caps, lso)) 344 if (MLX5_GET(ipsec_extended_cap, fdev->ipsec->caps, lso))
257 ret |= MLX5_ACCEL_IPSEC_LSO; 345 ret |= MLX5_ACCEL_IPSEC_CAP_LSO;
346
347 if (MLX5_GET(ipsec_extended_cap, fdev->ipsec->caps, rx_no_trailer))
348 ret |= MLX5_ACCEL_IPSEC_CAP_RX_NO_TRAILER;
349
350 if (MLX5_GET(ipsec_extended_cap, fdev->ipsec->caps, esn)) {
351 ret |= MLX5_ACCEL_IPSEC_CAP_ESN;
352 ret |= MLX5_ACCEL_IPSEC_CAP_TX_IV_IS_ESN;
353 }
258 354
259 return ret; 355 return ret;
260} 356}
@@ -318,6 +414,828 @@ out:
318 return ret; 414 return ret;
319} 415}
320 416
417static int mlx5_fpga_ipsec_set_caps(struct mlx5_core_dev *mdev, u32 flags)
418{
419 struct mlx5_fpga_ipsec_cmd_context *context;
420 struct mlx5_ifc_fpga_ipsec_cmd_cap cmd = {0};
421 int err;
422
423 cmd.cmd = htonl(MLX5_FPGA_IPSEC_CMD_OP_SET_CAP);
424 cmd.flags = htonl(flags);
425 context = mlx5_fpga_ipsec_cmd_exec(mdev, &cmd, sizeof(cmd));
426 if (IS_ERR(context)) {
427 err = PTR_ERR(context);
428 goto out;
429 }
430
431 err = mlx5_fpga_ipsec_cmd_wait(context);
432 if (err)
433 goto out;
434
435 if ((context->resp.flags & cmd.flags) != cmd.flags) {
436 mlx5_fpga_err(context->dev, "Failed to set capabilities. cmd 0x%08x vs resp 0x%08x\n",
437 cmd.flags,
438 context->resp.flags);
439 err = -EIO;
440 }
441
442out:
443 return err;
444}
445
446static int mlx5_fpga_ipsec_enable_supported_caps(struct mlx5_core_dev *mdev)
447{
448 u32 dev_caps = mlx5_fpga_ipsec_device_caps(mdev);
449 u32 flags = 0;
450
451 if (dev_caps & MLX5_ACCEL_IPSEC_CAP_RX_NO_TRAILER)
452 flags |= MLX5_FPGA_IPSEC_CAP_NO_TRAILER;
453
454 return mlx5_fpga_ipsec_set_caps(mdev, flags);
455}
456
457static void
458mlx5_fpga_ipsec_build_hw_xfrm(struct mlx5_core_dev *mdev,
459 const struct mlx5_accel_esp_xfrm_attrs *xfrm_attrs,
460 struct mlx5_ifc_fpga_ipsec_sa *hw_sa)
461{
462 const struct aes_gcm_keymat *aes_gcm = &xfrm_attrs->keymat.aes_gcm;
463
464 /* key */
465 memcpy(&hw_sa->ipsec_sa_v1.key_enc, aes_gcm->aes_key,
466 aes_gcm->key_len / 8);
467 /* Duplicate 128 bit key twice according to HW layout */
468 if (aes_gcm->key_len == 128)
469 memcpy(&hw_sa->ipsec_sa_v1.key_enc[16],
470 aes_gcm->aes_key, aes_gcm->key_len / 8);
471
472 /* salt and seq_iv */
473 memcpy(&hw_sa->ipsec_sa_v1.gcm.salt_iv, &aes_gcm->seq_iv,
474 sizeof(aes_gcm->seq_iv));
475 memcpy(&hw_sa->ipsec_sa_v1.gcm.salt, &aes_gcm->salt,
476 sizeof(aes_gcm->salt));
477
478 /* esn */
479 if (xfrm_attrs->flags & MLX5_ACCEL_ESP_FLAGS_ESN_TRIGGERED) {
480 hw_sa->ipsec_sa_v1.flags |= MLX5_FPGA_IPSEC_SA_ESN_EN;
481 hw_sa->ipsec_sa_v1.flags |=
482 (xfrm_attrs->flags &
483 MLX5_ACCEL_ESP_FLAGS_ESN_STATE_OVERLAP) ?
484 MLX5_FPGA_IPSEC_SA_ESN_OVERLAP : 0;
485 hw_sa->esn = htonl(xfrm_attrs->esn);
486 } else {
487 hw_sa->ipsec_sa_v1.flags &= ~MLX5_FPGA_IPSEC_SA_ESN_EN;
488 hw_sa->ipsec_sa_v1.flags &=
489 ~(xfrm_attrs->flags &
490 MLX5_ACCEL_ESP_FLAGS_ESN_STATE_OVERLAP) ?
491 MLX5_FPGA_IPSEC_SA_ESN_OVERLAP : 0;
492 hw_sa->esn = 0;
493 }
494
495 /* rx handle */
496 hw_sa->ipsec_sa_v1.sw_sa_handle = htonl(xfrm_attrs->sa_handle);
497
498 /* enc mode */
499 switch (aes_gcm->key_len) {
500 case 128:
501 hw_sa->ipsec_sa_v1.enc_mode =
502 MLX5_FPGA_IPSEC_SA_ENC_MODE_AES_GCM_128_AUTH_128;
503 break;
504 case 256:
505 hw_sa->ipsec_sa_v1.enc_mode =
506 MLX5_FPGA_IPSEC_SA_ENC_MODE_AES_GCM_256_AUTH_128;
507 break;
508 }
509
510 /* flags */
511 hw_sa->ipsec_sa_v1.flags |= MLX5_FPGA_IPSEC_SA_SA_VALID |
512 MLX5_FPGA_IPSEC_SA_SPI_EN |
513 MLX5_FPGA_IPSEC_SA_IP_ESP;
514
515 if (xfrm_attrs->action & MLX5_ACCEL_ESP_ACTION_ENCRYPT)
516 hw_sa->ipsec_sa_v1.flags |= MLX5_FPGA_IPSEC_SA_DIR_SX;
517 else
518 hw_sa->ipsec_sa_v1.flags &= ~MLX5_FPGA_IPSEC_SA_DIR_SX;
519}
520
521static void
522mlx5_fpga_ipsec_build_hw_sa(struct mlx5_core_dev *mdev,
523 struct mlx5_accel_esp_xfrm_attrs *xfrm_attrs,
524 const __be32 saddr[4],
525 const __be32 daddr[4],
526 const __be32 spi, bool is_ipv6,
527 struct mlx5_ifc_fpga_ipsec_sa *hw_sa)
528{
529 mlx5_fpga_ipsec_build_hw_xfrm(mdev, xfrm_attrs, hw_sa);
530
531 /* IPs */
532 memcpy(hw_sa->ipsec_sa_v1.sip, saddr, sizeof(hw_sa->ipsec_sa_v1.sip));
533 memcpy(hw_sa->ipsec_sa_v1.dip, daddr, sizeof(hw_sa->ipsec_sa_v1.dip));
534
535 /* SPI */
536 hw_sa->ipsec_sa_v1.spi = spi;
537
538 /* flags */
539 if (is_ipv6)
540 hw_sa->ipsec_sa_v1.flags |= MLX5_FPGA_IPSEC_SA_IPV6;
541}
542
543static bool is_full_mask(const void *p, size_t len)
544{
545 WARN_ON(len % 4);
546
547 return !memchr_inv(p, 0xff, len);
548}
549
550static bool validate_fpga_full_mask(struct mlx5_core_dev *dev,
551 const u32 *match_c,
552 const u32 *match_v)
553{
554 const void *misc_params_c = MLX5_ADDR_OF(fte_match_param,
555 match_c,
556 misc_parameters);
557 const void *headers_c = MLX5_ADDR_OF(fte_match_param,
558 match_c,
559 outer_headers);
560 const void *headers_v = MLX5_ADDR_OF(fte_match_param,
561 match_v,
562 outer_headers);
563
564 if (mlx5_fs_is_outer_ipv4_flow(dev, headers_c, headers_v)) {
565 const void *s_ipv4_c = MLX5_ADDR_OF(fte_match_set_lyr_2_4,
566 headers_c,
567 src_ipv4_src_ipv6.ipv4_layout.ipv4);
568 const void *d_ipv4_c = MLX5_ADDR_OF(fte_match_set_lyr_2_4,
569 headers_c,
570 dst_ipv4_dst_ipv6.ipv4_layout.ipv4);
571
572 if (!is_full_mask(s_ipv4_c, MLX5_FLD_SZ_BYTES(ipv4_layout,
573 ipv4)) ||
574 !is_full_mask(d_ipv4_c, MLX5_FLD_SZ_BYTES(ipv4_layout,
575 ipv4)))
576 return false;
577 } else {
578 const void *s_ipv6_c = MLX5_ADDR_OF(fte_match_set_lyr_2_4,
579 headers_c,
580 src_ipv4_src_ipv6.ipv6_layout.ipv6);
581 const void *d_ipv6_c = MLX5_ADDR_OF(fte_match_set_lyr_2_4,
582 headers_c,
583 dst_ipv4_dst_ipv6.ipv6_layout.ipv6);
584
585 if (!is_full_mask(s_ipv6_c, MLX5_FLD_SZ_BYTES(ipv6_layout,
586 ipv6)) ||
587 !is_full_mask(d_ipv6_c, MLX5_FLD_SZ_BYTES(ipv6_layout,
588 ipv6)))
589 return false;
590 }
591
592 if (!is_full_mask(MLX5_ADDR_OF(fte_match_set_misc, misc_params_c,
593 outer_esp_spi),
594 MLX5_FLD_SZ_BYTES(fte_match_set_misc, outer_esp_spi)))
595 return false;
596
597 return true;
598}
599
600static bool mlx5_is_fpga_ipsec_rule(struct mlx5_core_dev *dev,
601 u8 match_criteria_enable,
602 const u32 *match_c,
603 const u32 *match_v)
604{
605 u32 ipsec_dev_caps = mlx5_accel_ipsec_device_caps(dev);
606 bool ipv6_flow;
607
608 ipv6_flow = mlx5_fs_is_outer_ipv6_flow(dev, match_c, match_v);
609
610 if (!(match_criteria_enable & MLX5_MATCH_OUTER_HEADERS) ||
611 mlx5_fs_is_outer_udp_flow(match_c, match_v) ||
612 mlx5_fs_is_outer_tcp_flow(match_c, match_v) ||
613 mlx5_fs_is_vxlan_flow(match_c) ||
614 !(mlx5_fs_is_outer_ipv4_flow(dev, match_c, match_v) ||
615 ipv6_flow))
616 return false;
617
618 if (!(ipsec_dev_caps & MLX5_ACCEL_IPSEC_CAP_DEVICE))
619 return false;
620
621 if (!(ipsec_dev_caps & MLX5_ACCEL_IPSEC_CAP_ESP) &&
622 mlx5_fs_is_outer_ipsec_flow(match_c))
623 return false;
624
625 if (!(ipsec_dev_caps & MLX5_ACCEL_IPSEC_CAP_IPV6) &&
626 ipv6_flow)
627 return false;
628
629 if (!validate_fpga_full_mask(dev, match_c, match_v))
630 return false;
631
632 return true;
633}
634
635static bool mlx5_is_fpga_egress_ipsec_rule(struct mlx5_core_dev *dev,
636 u8 match_criteria_enable,
637 const u32 *match_c,
638 const u32 *match_v,
639 struct mlx5_flow_act *flow_act)
640{
641 const void *outer_c = MLX5_ADDR_OF(fte_match_param, match_c,
642 outer_headers);
643 bool is_dmac = MLX5_GET(fte_match_set_lyr_2_4, outer_c, dmac_47_16) ||
644 MLX5_GET(fte_match_set_lyr_2_4, outer_c, dmac_15_0);
645 bool is_smac = MLX5_GET(fte_match_set_lyr_2_4, outer_c, smac_47_16) ||
646 MLX5_GET(fte_match_set_lyr_2_4, outer_c, smac_15_0);
647 int ret;
648
649 ret = mlx5_is_fpga_ipsec_rule(dev, match_criteria_enable, match_c,
650 match_v);
651 if (!ret)
652 return ret;
653
654 if (is_dmac || is_smac ||
655 (match_criteria_enable &
656 ~(MLX5_MATCH_OUTER_HEADERS | MLX5_MATCH_MISC_PARAMETERS)) ||
657 (flow_act->action & ~(MLX5_FLOW_CONTEXT_ACTION_ENCRYPT | MLX5_FLOW_CONTEXT_ACTION_ALLOW)) ||
658 flow_act->has_flow_tag)
659 return false;
660
661 return true;
662}
663
664void *mlx5_fpga_ipsec_create_sa_ctx(struct mlx5_core_dev *mdev,
665 struct mlx5_accel_esp_xfrm *accel_xfrm,
666 const __be32 saddr[4],
667 const __be32 daddr[4],
668 const __be32 spi, bool is_ipv6)
669{
670 struct mlx5_fpga_ipsec_sa_ctx *sa_ctx;
671 struct mlx5_fpga_esp_xfrm *fpga_xfrm =
672 container_of(accel_xfrm, typeof(*fpga_xfrm),
673 accel_xfrm);
674 struct mlx5_fpga_device *fdev = mdev->fpga;
675 struct mlx5_fpga_ipsec *fipsec = fdev->ipsec;
676 int opcode, err;
677 void *context;
678
679 /* alloc SA */
680 sa_ctx = kzalloc(sizeof(*sa_ctx), GFP_KERNEL);
681 if (!sa_ctx)
682 return ERR_PTR(-ENOMEM);
683
684 sa_ctx->dev = mdev;
685
686 /* build candidate SA */
687 mlx5_fpga_ipsec_build_hw_sa(mdev, &accel_xfrm->attrs,
688 saddr, daddr, spi, is_ipv6,
689 &sa_ctx->hw_sa);
690
691 mutex_lock(&fpga_xfrm->lock);
692
693 if (fpga_xfrm->sa_ctx) { /* multiple rules for same accel_xfrm */
694 /* all rules must be with same IPs and SPI */
695 if (memcmp(&sa_ctx->hw_sa, &fpga_xfrm->sa_ctx->hw_sa,
696 sizeof(sa_ctx->hw_sa))) {
697 context = ERR_PTR(-EINVAL);
698 goto exists;
699 }
700
701 ++fpga_xfrm->num_rules;
702 context = fpga_xfrm->sa_ctx;
703 goto exists;
704 }
705
706 /* This is unbounded fpga_xfrm, try to add to hash */
707 mutex_lock(&fipsec->sa_hash_lock);
708
709 err = rhashtable_lookup_insert_fast(&fipsec->sa_hash, &sa_ctx->hash,
710 rhash_sa);
711 if (err) {
712 /* Can't bound different accel_xfrm to already existing sa_ctx.
713 * This is because we can't support multiple ketmats for
714 * same IPs and SPI
715 */
716 context = ERR_PTR(-EEXIST);
717 goto unlock_hash;
718 }
719
720 /* Bound accel_xfrm to sa_ctx */
721 opcode = is_v2_sadb_supported(fdev->ipsec) ?
722 MLX5_FPGA_IPSEC_CMD_OP_ADD_SA_V2 :
723 MLX5_FPGA_IPSEC_CMD_OP_ADD_SA;
724 err = mlx5_fpga_ipsec_update_hw_sa(fdev, &sa_ctx->hw_sa, opcode);
725 sa_ctx->hw_sa.ipsec_sa_v1.cmd = 0;
726 if (err) {
727 context = ERR_PTR(err);
728 goto delete_hash;
729 }
730
731 mutex_unlock(&fipsec->sa_hash_lock);
732
733 ++fpga_xfrm->num_rules;
734 fpga_xfrm->sa_ctx = sa_ctx;
735 sa_ctx->fpga_xfrm = fpga_xfrm;
736
737 mutex_unlock(&fpga_xfrm->lock);
738
739 return sa_ctx;
740
741delete_hash:
742 WARN_ON(rhashtable_remove_fast(&fipsec->sa_hash, &sa_ctx->hash,
743 rhash_sa));
744unlock_hash:
745 mutex_unlock(&fipsec->sa_hash_lock);
746
747exists:
748 mutex_unlock(&fpga_xfrm->lock);
749 kfree(sa_ctx);
750 return context;
751}
752
753static void *
754mlx5_fpga_ipsec_fs_create_sa_ctx(struct mlx5_core_dev *mdev,
755 struct fs_fte *fte,
756 bool is_egress)
757{
758 struct mlx5_accel_esp_xfrm *accel_xfrm;
759 __be32 saddr[4], daddr[4], spi;
760 struct mlx5_flow_group *fg;
761 bool is_ipv6 = false;
762
763 fs_get_obj(fg, fte->node.parent);
764 /* validate */
765 if (is_egress &&
766 !mlx5_is_fpga_egress_ipsec_rule(mdev,
767 fg->mask.match_criteria_enable,
768 fg->mask.match_criteria,
769 fte->val,
770 &fte->action))
771 return ERR_PTR(-EINVAL);
772 else if (!mlx5_is_fpga_ipsec_rule(mdev,
773 fg->mask.match_criteria_enable,
774 fg->mask.match_criteria,
775 fte->val))
776 return ERR_PTR(-EINVAL);
777
778 /* get xfrm context */
779 accel_xfrm =
780 (struct mlx5_accel_esp_xfrm *)fte->action.esp_id;
781
782 /* IPs */
783 if (mlx5_fs_is_outer_ipv4_flow(mdev, fg->mask.match_criteria,
784 fte->val)) {
785 memcpy(&saddr[3],
786 MLX5_ADDR_OF(fte_match_set_lyr_2_4,
787 fte->val,
788 src_ipv4_src_ipv6.ipv4_layout.ipv4),
789 sizeof(saddr[3]));
790 memcpy(&daddr[3],
791 MLX5_ADDR_OF(fte_match_set_lyr_2_4,
792 fte->val,
793 dst_ipv4_dst_ipv6.ipv4_layout.ipv4),
794 sizeof(daddr[3]));
795 } else {
796 memcpy(saddr,
797 MLX5_ADDR_OF(fte_match_param,
798 fte->val,
799 outer_headers.src_ipv4_src_ipv6.ipv6_layout.ipv6),
800 sizeof(saddr));
801 memcpy(daddr,
802 MLX5_ADDR_OF(fte_match_param,
803 fte->val,
804 outer_headers.dst_ipv4_dst_ipv6.ipv6_layout.ipv6),
805 sizeof(daddr));
806 is_ipv6 = true;
807 }
808
809 /* SPI */
810 spi = MLX5_GET_BE(typeof(spi),
811 fte_match_param, fte->val,
812 misc_parameters.outer_esp_spi);
813
814 /* create */
815 return mlx5_fpga_ipsec_create_sa_ctx(mdev, accel_xfrm,
816 saddr, daddr,
817 spi, is_ipv6);
818}
819
820static void
821mlx5_fpga_ipsec_release_sa_ctx(struct mlx5_fpga_ipsec_sa_ctx *sa_ctx)
822{
823 struct mlx5_fpga_device *fdev = sa_ctx->dev->fpga;
824 struct mlx5_fpga_ipsec *fipsec = fdev->ipsec;
825 int opcode = is_v2_sadb_supported(fdev->ipsec) ?
826 MLX5_FPGA_IPSEC_CMD_OP_DEL_SA_V2 :
827 MLX5_FPGA_IPSEC_CMD_OP_DEL_SA;
828 int err;
829
830 err = mlx5_fpga_ipsec_update_hw_sa(fdev, &sa_ctx->hw_sa, opcode);
831 sa_ctx->hw_sa.ipsec_sa_v1.cmd = 0;
832 if (err) {
833 WARN_ON(err);
834 return;
835 }
836
837 mutex_lock(&fipsec->sa_hash_lock);
838 WARN_ON(rhashtable_remove_fast(&fipsec->sa_hash, &sa_ctx->hash,
839 rhash_sa));
840 mutex_unlock(&fipsec->sa_hash_lock);
841}
842
843void mlx5_fpga_ipsec_delete_sa_ctx(void *context)
844{
845 struct mlx5_fpga_esp_xfrm *fpga_xfrm =
846 ((struct mlx5_fpga_ipsec_sa_ctx *)context)->fpga_xfrm;
847
848 mutex_lock(&fpga_xfrm->lock);
849 if (!--fpga_xfrm->num_rules) {
850 mlx5_fpga_ipsec_release_sa_ctx(fpga_xfrm->sa_ctx);
851 fpga_xfrm->sa_ctx = NULL;
852 }
853 mutex_unlock(&fpga_xfrm->lock);
854}
855
856static inline struct mlx5_fpga_ipsec_rule *
857_rule_search(struct rb_root *root, struct fs_fte *fte)
858{
859 struct rb_node *node = root->rb_node;
860
861 while (node) {
862 struct mlx5_fpga_ipsec_rule *rule =
863 container_of(node, struct mlx5_fpga_ipsec_rule,
864 node);
865
866 if (rule->fte < fte)
867 node = node->rb_left;
868 else if (rule->fte > fte)
869 node = node->rb_right;
870 else
871 return rule;
872 }
873 return NULL;
874}
875
876static struct mlx5_fpga_ipsec_rule *
877rule_search(struct mlx5_fpga_ipsec *ipsec_dev, struct fs_fte *fte)
878{
879 struct mlx5_fpga_ipsec_rule *rule;
880
881 mutex_lock(&ipsec_dev->rules_rb_lock);
882 rule = _rule_search(&ipsec_dev->rules_rb, fte);
883 mutex_unlock(&ipsec_dev->rules_rb_lock);
884
885 return rule;
886}
887
888static inline int _rule_insert(struct rb_root *root,
889 struct mlx5_fpga_ipsec_rule *rule)
890{
891 struct rb_node **new = &root->rb_node, *parent = NULL;
892
893 /* Figure out where to put new node */
894 while (*new) {
895 struct mlx5_fpga_ipsec_rule *this =
896 container_of(*new, struct mlx5_fpga_ipsec_rule,
897 node);
898
899 parent = *new;
900 if (rule->fte < this->fte)
901 new = &((*new)->rb_left);
902 else if (rule->fte > this->fte)
903 new = &((*new)->rb_right);
904 else
905 return -EEXIST;
906 }
907
908 /* Add new node and rebalance tree. */
909 rb_link_node(&rule->node, parent, new);
910 rb_insert_color(&rule->node, root);
911
912 return 0;
913}
914
915static int rule_insert(struct mlx5_fpga_ipsec *ipsec_dev,
916 struct mlx5_fpga_ipsec_rule *rule)
917{
918 int ret;
919
920 mutex_lock(&ipsec_dev->rules_rb_lock);
921 ret = _rule_insert(&ipsec_dev->rules_rb, rule);
922 mutex_unlock(&ipsec_dev->rules_rb_lock);
923
924 return ret;
925}
926
927static inline void _rule_delete(struct mlx5_fpga_ipsec *ipsec_dev,
928 struct mlx5_fpga_ipsec_rule *rule)
929{
930 struct rb_root *root = &ipsec_dev->rules_rb;
931
932 mutex_lock(&ipsec_dev->rules_rb_lock);
933 rb_erase(&rule->node, root);
934 mutex_unlock(&ipsec_dev->rules_rb_lock);
935}
936
937static void rule_delete(struct mlx5_fpga_ipsec *ipsec_dev,
938 struct mlx5_fpga_ipsec_rule *rule)
939{
940 _rule_delete(ipsec_dev, rule);
941 kfree(rule);
942}
943
944struct mailbox_mod {
945 uintptr_t saved_esp_id;
946 u32 saved_action;
947 u32 saved_outer_esp_spi_value;
948};
949
950static void restore_spec_mailbox(struct fs_fte *fte,
951 struct mailbox_mod *mbox_mod)
952{
953 char *misc_params_v = MLX5_ADDR_OF(fte_match_param,
954 fte->val,
955 misc_parameters);
956
957 MLX5_SET(fte_match_set_misc, misc_params_v, outer_esp_spi,
958 mbox_mod->saved_outer_esp_spi_value);
959 fte->action.action |= mbox_mod->saved_action;
960 fte->action.esp_id = (uintptr_t)mbox_mod->saved_esp_id;
961}
962
963static void modify_spec_mailbox(struct mlx5_core_dev *mdev,
964 struct fs_fte *fte,
965 struct mailbox_mod *mbox_mod)
966{
967 char *misc_params_v = MLX5_ADDR_OF(fte_match_param,
968 fte->val,
969 misc_parameters);
970
971 mbox_mod->saved_esp_id = fte->action.esp_id;
972 mbox_mod->saved_action = fte->action.action &
973 (MLX5_FLOW_CONTEXT_ACTION_ENCRYPT |
974 MLX5_FLOW_CONTEXT_ACTION_DECRYPT);
975 mbox_mod->saved_outer_esp_spi_value =
976 MLX5_GET(fte_match_set_misc, misc_params_v,
977 outer_esp_spi);
978
979 fte->action.esp_id = 0;
980 fte->action.action &= ~(MLX5_FLOW_CONTEXT_ACTION_ENCRYPT |
981 MLX5_FLOW_CONTEXT_ACTION_DECRYPT);
982 if (!MLX5_CAP_FLOWTABLE(mdev,
983 flow_table_properties_nic_receive.ft_field_support.outer_esp_spi))
984 MLX5_SET(fte_match_set_misc, misc_params_v, outer_esp_spi, 0);
985}
986
987static enum fs_flow_table_type egress_to_fs_ft(bool egress)
988{
989 return egress ? FS_FT_NIC_TX : FS_FT_NIC_RX;
990}
991
992static int fpga_ipsec_fs_create_flow_group(struct mlx5_core_dev *dev,
993 struct mlx5_flow_table *ft,
994 u32 *in,
995 unsigned int *group_id,
996 bool is_egress)
997{
998 int (*create_flow_group)(struct mlx5_core_dev *dev,
999 struct mlx5_flow_table *ft, u32 *in,
1000 unsigned int *group_id) =
1001 mlx5_fs_cmd_get_default(egress_to_fs_ft(is_egress))->create_flow_group;
1002 char *misc_params_c = MLX5_ADDR_OF(create_flow_group_in, in,
1003 match_criteria.misc_parameters);
1004 u32 saved_outer_esp_spi_mask;
1005 u8 match_criteria_enable;
1006 int ret;
1007
1008 if (MLX5_CAP_FLOWTABLE(dev,
1009 flow_table_properties_nic_receive.ft_field_support.outer_esp_spi))
1010 return create_flow_group(dev, ft, in, group_id);
1011
1012 match_criteria_enable =
1013 MLX5_GET(create_flow_group_in, in, match_criteria_enable);
1014 saved_outer_esp_spi_mask =
1015 MLX5_GET(fte_match_set_misc, misc_params_c, outer_esp_spi);
1016 if (!match_criteria_enable || !saved_outer_esp_spi_mask)
1017 return create_flow_group(dev, ft, in, group_id);
1018
1019 MLX5_SET(fte_match_set_misc, misc_params_c, outer_esp_spi, 0);
1020
1021 if (!(*misc_params_c) &&
1022 !memcmp(misc_params_c, misc_params_c + 1, MLX5_ST_SZ_BYTES(fte_match_set_misc) - 1))
1023 MLX5_SET(create_flow_group_in, in, match_criteria_enable,
1024 match_criteria_enable & ~MLX5_MATCH_MISC_PARAMETERS);
1025
1026 ret = create_flow_group(dev, ft, in, group_id);
1027
1028 MLX5_SET(fte_match_set_misc, misc_params_c, outer_esp_spi, saved_outer_esp_spi_mask);
1029 MLX5_SET(create_flow_group_in, in, match_criteria_enable, match_criteria_enable);
1030
1031 return ret;
1032}
1033
1034static int fpga_ipsec_fs_create_fte(struct mlx5_core_dev *dev,
1035 struct mlx5_flow_table *ft,
1036 struct mlx5_flow_group *fg,
1037 struct fs_fte *fte,
1038 bool is_egress)
1039{
1040 int (*create_fte)(struct mlx5_core_dev *dev,
1041 struct mlx5_flow_table *ft,
1042 struct mlx5_flow_group *fg,
1043 struct fs_fte *fte) =
1044 mlx5_fs_cmd_get_default(egress_to_fs_ft(is_egress))->create_fte;
1045 struct mlx5_fpga_device *fdev = dev->fpga;
1046 struct mlx5_fpga_ipsec *fipsec = fdev->ipsec;
1047 struct mlx5_fpga_ipsec_rule *rule;
1048 bool is_esp = fte->action.esp_id;
1049 struct mailbox_mod mbox_mod;
1050 int ret;
1051
1052 if (!is_esp ||
1053 !(fte->action.action &
1054 (MLX5_FLOW_CONTEXT_ACTION_ENCRYPT |
1055 MLX5_FLOW_CONTEXT_ACTION_DECRYPT)))
1056 return create_fte(dev, ft, fg, fte);
1057
1058 rule = kzalloc(sizeof(*rule), GFP_KERNEL);
1059 if (!rule)
1060 return -ENOMEM;
1061
1062 rule->ctx = mlx5_fpga_ipsec_fs_create_sa_ctx(dev, fte, is_egress);
1063 if (IS_ERR(rule->ctx)) {
1064 kfree(rule);
1065 return PTR_ERR(rule->ctx);
1066 }
1067
1068 rule->fte = fte;
1069 WARN_ON(rule_insert(fipsec, rule));
1070
1071 modify_spec_mailbox(dev, fte, &mbox_mod);
1072 ret = create_fte(dev, ft, fg, fte);
1073 restore_spec_mailbox(fte, &mbox_mod);
1074 if (ret) {
1075 _rule_delete(fipsec, rule);
1076 mlx5_fpga_ipsec_delete_sa_ctx(rule->ctx);
1077 kfree(rule);
1078 }
1079
1080 return ret;
1081}
1082
1083static int fpga_ipsec_fs_update_fte(struct mlx5_core_dev *dev,
1084 struct mlx5_flow_table *ft,
1085 unsigned int group_id,
1086 int modify_mask,
1087 struct fs_fte *fte,
1088 bool is_egress)
1089{
1090 int (*update_fte)(struct mlx5_core_dev *dev,
1091 struct mlx5_flow_table *ft,
1092 unsigned int group_id,
1093 int modify_mask,
1094 struct fs_fte *fte) =
1095 mlx5_fs_cmd_get_default(egress_to_fs_ft(is_egress))->update_fte;
1096 bool is_esp = fte->action.esp_id;
1097 struct mailbox_mod mbox_mod;
1098 int ret;
1099
1100 if (!is_esp ||
1101 !(fte->action.action &
1102 (MLX5_FLOW_CONTEXT_ACTION_ENCRYPT |
1103 MLX5_FLOW_CONTEXT_ACTION_DECRYPT)))
1104 return update_fte(dev, ft, group_id, modify_mask, fte);
1105
1106 modify_spec_mailbox(dev, fte, &mbox_mod);
1107 ret = update_fte(dev, ft, group_id, modify_mask, fte);
1108 restore_spec_mailbox(fte, &mbox_mod);
1109
1110 return ret;
1111}
1112
1113static int fpga_ipsec_fs_delete_fte(struct mlx5_core_dev *dev,
1114 struct mlx5_flow_table *ft,
1115 struct fs_fte *fte,
1116 bool is_egress)
1117{
1118 int (*delete_fte)(struct mlx5_core_dev *dev,
1119 struct mlx5_flow_table *ft,
1120 struct fs_fte *fte) =
1121 mlx5_fs_cmd_get_default(egress_to_fs_ft(is_egress))->delete_fte;
1122 struct mlx5_fpga_device *fdev = dev->fpga;
1123 struct mlx5_fpga_ipsec *fipsec = fdev->ipsec;
1124 struct mlx5_fpga_ipsec_rule *rule;
1125 bool is_esp = fte->action.esp_id;
1126 struct mailbox_mod mbox_mod;
1127 int ret;
1128
1129 if (!is_esp ||
1130 !(fte->action.action &
1131 (MLX5_FLOW_CONTEXT_ACTION_ENCRYPT |
1132 MLX5_FLOW_CONTEXT_ACTION_DECRYPT)))
1133 return delete_fte(dev, ft, fte);
1134
1135 rule = rule_search(fipsec, fte);
1136 if (!rule)
1137 return -ENOENT;
1138
1139 mlx5_fpga_ipsec_delete_sa_ctx(rule->ctx);
1140 rule_delete(fipsec, rule);
1141
1142 modify_spec_mailbox(dev, fte, &mbox_mod);
1143 ret = delete_fte(dev, ft, fte);
1144 restore_spec_mailbox(fte, &mbox_mod);
1145
1146 return ret;
1147}
1148
1149static int
1150mlx5_fpga_ipsec_fs_create_flow_group_egress(struct mlx5_core_dev *dev,
1151 struct mlx5_flow_table *ft,
1152 u32 *in,
1153 unsigned int *group_id)
1154{
1155 return fpga_ipsec_fs_create_flow_group(dev, ft, in, group_id, true);
1156}
1157
1158static int
1159mlx5_fpga_ipsec_fs_create_fte_egress(struct mlx5_core_dev *dev,
1160 struct mlx5_flow_table *ft,
1161 struct mlx5_flow_group *fg,
1162 struct fs_fte *fte)
1163{
1164 return fpga_ipsec_fs_create_fte(dev, ft, fg, fte, true);
1165}
1166
1167static int
1168mlx5_fpga_ipsec_fs_update_fte_egress(struct mlx5_core_dev *dev,
1169 struct mlx5_flow_table *ft,
1170 unsigned int group_id,
1171 int modify_mask,
1172 struct fs_fte *fte)
1173{
1174 return fpga_ipsec_fs_update_fte(dev, ft, group_id, modify_mask, fte,
1175 true);
1176}
1177
1178static int
1179mlx5_fpga_ipsec_fs_delete_fte_egress(struct mlx5_core_dev *dev,
1180 struct mlx5_flow_table *ft,
1181 struct fs_fte *fte)
1182{
1183 return fpga_ipsec_fs_delete_fte(dev, ft, fte, true);
1184}
1185
1186static int
1187mlx5_fpga_ipsec_fs_create_flow_group_ingress(struct mlx5_core_dev *dev,
1188 struct mlx5_flow_table *ft,
1189 u32 *in,
1190 unsigned int *group_id)
1191{
1192 return fpga_ipsec_fs_create_flow_group(dev, ft, in, group_id, false);
1193}
1194
1195static int
1196mlx5_fpga_ipsec_fs_create_fte_ingress(struct mlx5_core_dev *dev,
1197 struct mlx5_flow_table *ft,
1198 struct mlx5_flow_group *fg,
1199 struct fs_fte *fte)
1200{
1201 return fpga_ipsec_fs_create_fte(dev, ft, fg, fte, false);
1202}
1203
1204static int
1205mlx5_fpga_ipsec_fs_update_fte_ingress(struct mlx5_core_dev *dev,
1206 struct mlx5_flow_table *ft,
1207 unsigned int group_id,
1208 int modify_mask,
1209 struct fs_fte *fte)
1210{
1211 return fpga_ipsec_fs_update_fte(dev, ft, group_id, modify_mask, fte,
1212 false);
1213}
1214
1215static int
1216mlx5_fpga_ipsec_fs_delete_fte_ingress(struct mlx5_core_dev *dev,
1217 struct mlx5_flow_table *ft,
1218 struct fs_fte *fte)
1219{
1220 return fpga_ipsec_fs_delete_fte(dev, ft, fte, false);
1221}
1222
1223static struct mlx5_flow_cmds fpga_ipsec_ingress;
1224static struct mlx5_flow_cmds fpga_ipsec_egress;
1225
1226const struct mlx5_flow_cmds *mlx5_fs_cmd_get_default_ipsec_fpga_cmds(enum fs_flow_table_type type)
1227{
1228 switch (type) {
1229 case FS_FT_NIC_RX:
1230 return &fpga_ipsec_ingress;
1231 case FS_FT_NIC_TX:
1232 return &fpga_ipsec_egress;
1233 default:
1234 WARN_ON(true);
1235 return NULL;
1236 }
1237}
1238
321int mlx5_fpga_ipsec_init(struct mlx5_core_dev *mdev) 1239int mlx5_fpga_ipsec_init(struct mlx5_core_dev *mdev)
322{ 1240{
323 struct mlx5_fpga_conn_attr init_attr = {0}; 1241 struct mlx5_fpga_conn_attr init_attr = {0};
@@ -332,6 +1250,8 @@ int mlx5_fpga_ipsec_init(struct mlx5_core_dev *mdev)
332 if (!fdev->ipsec) 1250 if (!fdev->ipsec)
333 return -ENOMEM; 1251 return -ENOMEM;
334 1252
1253 fdev->ipsec->fdev = fdev;
1254
335 err = mlx5_fpga_get_sbu_caps(fdev, sizeof(fdev->ipsec->caps), 1255 err = mlx5_fpga_get_sbu_caps(fdev, sizeof(fdev->ipsec->caps),
336 fdev->ipsec->caps); 1256 fdev->ipsec->caps);
337 if (err) { 1257 if (err) {
@@ -355,14 +1275,47 @@ int mlx5_fpga_ipsec_init(struct mlx5_core_dev *mdev)
355 goto error; 1275 goto error;
356 } 1276 }
357 fdev->ipsec->conn = conn; 1277 fdev->ipsec->conn = conn;
1278
1279 err = rhashtable_init(&fdev->ipsec->sa_hash, &rhash_sa);
1280 if (err)
1281 goto err_destroy_conn;
1282 mutex_init(&fdev->ipsec->sa_hash_lock);
1283
1284 fdev->ipsec->rules_rb = RB_ROOT;
1285 mutex_init(&fdev->ipsec->rules_rb_lock);
1286
1287 err = mlx5_fpga_ipsec_enable_supported_caps(mdev);
1288 if (err) {
1289 mlx5_fpga_err(fdev, "Failed to enable IPSec extended capabilities: %d\n",
1290 err);
1291 goto err_destroy_hash;
1292 }
1293
358 return 0; 1294 return 0;
359 1295
1296err_destroy_hash:
1297 rhashtable_destroy(&fdev->ipsec->sa_hash);
1298
1299err_destroy_conn:
1300 mlx5_fpga_sbu_conn_destroy(conn);
1301
360error: 1302error:
361 kfree(fdev->ipsec); 1303 kfree(fdev->ipsec);
362 fdev->ipsec = NULL; 1304 fdev->ipsec = NULL;
363 return err; 1305 return err;
364} 1306}
365 1307
1308static void destroy_rules_rb(struct rb_root *root)
1309{
1310 struct mlx5_fpga_ipsec_rule *r, *tmp;
1311
1312 rbtree_postorder_for_each_entry_safe(r, tmp, root, node) {
1313 rb_erase(&r->node, root);
1314 mlx5_fpga_ipsec_delete_sa_ctx(r->ctx);
1315 kfree(r);
1316 }
1317}
1318
366void mlx5_fpga_ipsec_cleanup(struct mlx5_core_dev *mdev) 1319void mlx5_fpga_ipsec_cleanup(struct mlx5_core_dev *mdev)
367{ 1320{
368 struct mlx5_fpga_device *fdev = mdev->fpga; 1321 struct mlx5_fpga_device *fdev = mdev->fpga;
@@ -370,7 +1323,209 @@ void mlx5_fpga_ipsec_cleanup(struct mlx5_core_dev *mdev)
370 if (!mlx5_fpga_is_ipsec_device(mdev)) 1323 if (!mlx5_fpga_is_ipsec_device(mdev))
371 return; 1324 return;
372 1325
1326 destroy_rules_rb(&fdev->ipsec->rules_rb);
1327 rhashtable_destroy(&fdev->ipsec->sa_hash);
1328
373 mlx5_fpga_sbu_conn_destroy(fdev->ipsec->conn); 1329 mlx5_fpga_sbu_conn_destroy(fdev->ipsec->conn);
374 kfree(fdev->ipsec); 1330 kfree(fdev->ipsec);
375 fdev->ipsec = NULL; 1331 fdev->ipsec = NULL;
376} 1332}
1333
1334void mlx5_fpga_ipsec_build_fs_cmds(void)
1335{
1336 /* ingress */
1337 fpga_ipsec_ingress.create_flow_table =
1338 mlx5_fs_cmd_get_default(egress_to_fs_ft(false))->create_flow_table;
1339 fpga_ipsec_ingress.destroy_flow_table =
1340 mlx5_fs_cmd_get_default(egress_to_fs_ft(false))->destroy_flow_table;
1341 fpga_ipsec_ingress.modify_flow_table =
1342 mlx5_fs_cmd_get_default(egress_to_fs_ft(false))->modify_flow_table;
1343 fpga_ipsec_ingress.create_flow_group =
1344 mlx5_fpga_ipsec_fs_create_flow_group_ingress;
1345 fpga_ipsec_ingress.destroy_flow_group =
1346 mlx5_fs_cmd_get_default(egress_to_fs_ft(false))->destroy_flow_group;
1347 fpga_ipsec_ingress.create_fte =
1348 mlx5_fpga_ipsec_fs_create_fte_ingress;
1349 fpga_ipsec_ingress.update_fte =
1350 mlx5_fpga_ipsec_fs_update_fte_ingress;
1351 fpga_ipsec_ingress.delete_fte =
1352 mlx5_fpga_ipsec_fs_delete_fte_ingress;
1353 fpga_ipsec_ingress.update_root_ft =
1354 mlx5_fs_cmd_get_default(egress_to_fs_ft(false))->update_root_ft;
1355
1356 /* egress */
1357 fpga_ipsec_egress.create_flow_table =
1358 mlx5_fs_cmd_get_default(egress_to_fs_ft(true))->create_flow_table;
1359 fpga_ipsec_egress.destroy_flow_table =
1360 mlx5_fs_cmd_get_default(egress_to_fs_ft(true))->destroy_flow_table;
1361 fpga_ipsec_egress.modify_flow_table =
1362 mlx5_fs_cmd_get_default(egress_to_fs_ft(true))->modify_flow_table;
1363 fpga_ipsec_egress.create_flow_group =
1364 mlx5_fpga_ipsec_fs_create_flow_group_egress;
1365 fpga_ipsec_egress.destroy_flow_group =
1366 mlx5_fs_cmd_get_default(egress_to_fs_ft(true))->destroy_flow_group;
1367 fpga_ipsec_egress.create_fte =
1368 mlx5_fpga_ipsec_fs_create_fte_egress;
1369 fpga_ipsec_egress.update_fte =
1370 mlx5_fpga_ipsec_fs_update_fte_egress;
1371 fpga_ipsec_egress.delete_fte =
1372 mlx5_fpga_ipsec_fs_delete_fte_egress;
1373 fpga_ipsec_egress.update_root_ft =
1374 mlx5_fs_cmd_get_default(egress_to_fs_ft(true))->update_root_ft;
1375}
1376
1377static int
1378mlx5_fpga_esp_validate_xfrm_attrs(struct mlx5_core_dev *mdev,
1379 const struct mlx5_accel_esp_xfrm_attrs *attrs)
1380{
1381 if (attrs->tfc_pad) {
1382 mlx5_core_err(mdev, "Cannot offload xfrm states with tfc padding\n");
1383 return -EOPNOTSUPP;
1384 }
1385
1386 if (attrs->replay_type != MLX5_ACCEL_ESP_REPLAY_NONE) {
1387 mlx5_core_err(mdev, "Cannot offload xfrm states with anti replay\n");
1388 return -EOPNOTSUPP;
1389 }
1390
1391 if (attrs->keymat_type != MLX5_ACCEL_ESP_KEYMAT_AES_GCM) {
1392 mlx5_core_err(mdev, "Only aes gcm keymat is supported\n");
1393 return -EOPNOTSUPP;
1394 }
1395
1396 if (attrs->keymat.aes_gcm.iv_algo !=
1397 MLX5_ACCEL_ESP_AES_GCM_IV_ALGO_SEQ) {
1398 mlx5_core_err(mdev, "Only iv sequence algo is supported\n");
1399 return -EOPNOTSUPP;
1400 }
1401
1402 if (attrs->keymat.aes_gcm.icv_len != 128) {
1403 mlx5_core_err(mdev, "Cannot offload xfrm states with AEAD ICV length other than 128bit\n");
1404 return -EOPNOTSUPP;
1405 }
1406
1407 if (attrs->keymat.aes_gcm.key_len != 128 &&
1408 attrs->keymat.aes_gcm.key_len != 256) {
1409 mlx5_core_err(mdev, "Cannot offload xfrm states with AEAD key length other than 128/256 bit\n");
1410 return -EOPNOTSUPP;
1411 }
1412
1413 if ((attrs->flags & MLX5_ACCEL_ESP_FLAGS_ESN_TRIGGERED) &&
1414 (!MLX5_GET(ipsec_extended_cap, mdev->fpga->ipsec->caps,
1415 v2_command))) {
1416 mlx5_core_err(mdev, "Cannot offload xfrm states with AEAD key length other than 128/256 bit\n");
1417 return -EOPNOTSUPP;
1418 }
1419
1420 return 0;
1421}
1422
1423struct mlx5_accel_esp_xfrm *
1424mlx5_fpga_esp_create_xfrm(struct mlx5_core_dev *mdev,
1425 const struct mlx5_accel_esp_xfrm_attrs *attrs,
1426 u32 flags)
1427{
1428 struct mlx5_fpga_esp_xfrm *fpga_xfrm;
1429
1430 if (!(flags & MLX5_ACCEL_XFRM_FLAG_REQUIRE_METADATA)) {
1431 mlx5_core_warn(mdev, "Tried to create an esp action without metadata\n");
1432 return ERR_PTR(-EINVAL);
1433 }
1434
1435 if (mlx5_fpga_esp_validate_xfrm_attrs(mdev, attrs)) {
1436 mlx5_core_warn(mdev, "Tried to create an esp with unsupported attrs\n");
1437 return ERR_PTR(-EOPNOTSUPP);
1438 }
1439
1440 fpga_xfrm = kzalloc(sizeof(*fpga_xfrm), GFP_KERNEL);
1441 if (!fpga_xfrm)
1442 return ERR_PTR(-ENOMEM);
1443
1444 mutex_init(&fpga_xfrm->lock);
1445 memcpy(&fpga_xfrm->accel_xfrm.attrs, attrs,
1446 sizeof(fpga_xfrm->accel_xfrm.attrs));
1447
1448 return &fpga_xfrm->accel_xfrm;
1449}
1450
1451void mlx5_fpga_esp_destroy_xfrm(struct mlx5_accel_esp_xfrm *xfrm)
1452{
1453 struct mlx5_fpga_esp_xfrm *fpga_xfrm =
1454 container_of(xfrm, struct mlx5_fpga_esp_xfrm,
1455 accel_xfrm);
1456 /* assuming no sa_ctx are connected to this xfrm_ctx */
1457 kfree(fpga_xfrm);
1458}
1459
1460int mlx5_fpga_esp_modify_xfrm(struct mlx5_accel_esp_xfrm *xfrm,
1461 const struct mlx5_accel_esp_xfrm_attrs *attrs)
1462{
1463 struct mlx5_core_dev *mdev = xfrm->mdev;
1464 struct mlx5_fpga_device *fdev = mdev->fpga;
1465 struct mlx5_fpga_ipsec *fipsec = fdev->ipsec;
1466 struct mlx5_fpga_esp_xfrm *fpga_xfrm;
1467 struct mlx5_ifc_fpga_ipsec_sa org_hw_sa;
1468
1469 int err = 0;
1470
1471 if (!memcmp(&xfrm->attrs, attrs, sizeof(xfrm->attrs)))
1472 return 0;
1473
1474 if (!mlx5_fpga_esp_validate_xfrm_attrs(mdev, attrs)) {
1475 mlx5_core_warn(mdev, "Tried to create an esp with unsupported attrs\n");
1476 return -EOPNOTSUPP;
1477 }
1478
1479 if (is_v2_sadb_supported(fipsec)) {
1480 mlx5_core_warn(mdev, "Modify esp is not supported\n");
1481 return -EOPNOTSUPP;
1482 }
1483
1484 fpga_xfrm = container_of(xfrm, struct mlx5_fpga_esp_xfrm, accel_xfrm);
1485
1486 mutex_lock(&fpga_xfrm->lock);
1487
1488 if (!fpga_xfrm->sa_ctx)
1489 /* Unbounded xfrm, chane only sw attrs */
1490 goto change_sw_xfrm_attrs;
1491
1492 /* copy original hw sa */
1493 memcpy(&org_hw_sa, &fpga_xfrm->sa_ctx->hw_sa, sizeof(org_hw_sa));
1494 mutex_lock(&fipsec->sa_hash_lock);
1495 /* remove original hw sa from hash */
1496 WARN_ON(rhashtable_remove_fast(&fipsec->sa_hash,
1497 &fpga_xfrm->sa_ctx->hash, rhash_sa));
1498 /* update hw_sa with new xfrm attrs*/
1499 mlx5_fpga_ipsec_build_hw_xfrm(xfrm->mdev, attrs,
1500 &fpga_xfrm->sa_ctx->hw_sa);
1501 /* try to insert new hw_sa to hash */
1502 err = rhashtable_insert_fast(&fipsec->sa_hash,
1503 &fpga_xfrm->sa_ctx->hash, rhash_sa);
1504 if (err)
1505 goto rollback_sa;
1506
1507 /* modify device with new hw_sa */
1508 err = mlx5_fpga_ipsec_update_hw_sa(fdev, &fpga_xfrm->sa_ctx->hw_sa,
1509 MLX5_FPGA_IPSEC_CMD_OP_MOD_SA_V2);
1510 fpga_xfrm->sa_ctx->hw_sa.ipsec_sa_v1.cmd = 0;
1511 if (err)
1512 WARN_ON(rhashtable_remove_fast(&fipsec->sa_hash,
1513 &fpga_xfrm->sa_ctx->hash,
1514 rhash_sa));
1515rollback_sa:
1516 if (err) {
1517 /* return original hw_sa to hash */
1518 memcpy(&fpga_xfrm->sa_ctx->hw_sa, &org_hw_sa,
1519 sizeof(org_hw_sa));
1520 WARN_ON(rhashtable_insert_fast(&fipsec->sa_hash,
1521 &fpga_xfrm->sa_ctx->hash,
1522 rhash_sa));
1523 }
1524 mutex_unlock(&fipsec->sa_hash_lock);
1525
1526change_sw_xfrm_attrs:
1527 if (!err)
1528 memcpy(&xfrm->attrs, attrs, sizeof(xfrm->attrs));
1529 mutex_unlock(&fpga_xfrm->lock);
1530 return err;
1531}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.h b/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.h
index 26a3e4b56972..2b5e63b0d4d6 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.h
@@ -35,33 +35,38 @@
35#define __MLX5_FPGA_IPSEC_H__ 35#define __MLX5_FPGA_IPSEC_H__
36 36
37#include "accel/ipsec.h" 37#include "accel/ipsec.h"
38#include "fs_cmd.h"
38 39
39#ifdef CONFIG_MLX5_FPGA 40#ifdef CONFIG_MLX5_FPGA
40 41
41void *mlx5_fpga_ipsec_sa_cmd_exec(struct mlx5_core_dev *mdev,
42 struct mlx5_accel_ipsec_sa *cmd);
43int mlx5_fpga_ipsec_sa_cmd_wait(void *context);
44
45u32 mlx5_fpga_ipsec_device_caps(struct mlx5_core_dev *mdev); 42u32 mlx5_fpga_ipsec_device_caps(struct mlx5_core_dev *mdev);
46unsigned int mlx5_fpga_ipsec_counters_count(struct mlx5_core_dev *mdev); 43unsigned int mlx5_fpga_ipsec_counters_count(struct mlx5_core_dev *mdev);
47int mlx5_fpga_ipsec_counters_read(struct mlx5_core_dev *mdev, u64 *counters, 44int mlx5_fpga_ipsec_counters_read(struct mlx5_core_dev *mdev, u64 *counters,
48 unsigned int counters_count); 45 unsigned int counters_count);
49 46
47void *mlx5_fpga_ipsec_create_sa_ctx(struct mlx5_core_dev *mdev,
48 struct mlx5_accel_esp_xfrm *accel_xfrm,
49 const __be32 saddr[4],
50 const __be32 daddr[4],
51 const __be32 spi, bool is_ipv6);
52void mlx5_fpga_ipsec_delete_sa_ctx(void *context);
53
50int mlx5_fpga_ipsec_init(struct mlx5_core_dev *mdev); 54int mlx5_fpga_ipsec_init(struct mlx5_core_dev *mdev);
51void mlx5_fpga_ipsec_cleanup(struct mlx5_core_dev *mdev); 55void mlx5_fpga_ipsec_cleanup(struct mlx5_core_dev *mdev);
56void mlx5_fpga_ipsec_build_fs_cmds(void);
52 57
53#else 58struct mlx5_accel_esp_xfrm *
59mlx5_fpga_esp_create_xfrm(struct mlx5_core_dev *mdev,
60 const struct mlx5_accel_esp_xfrm_attrs *attrs,
61 u32 flags);
62void mlx5_fpga_esp_destroy_xfrm(struct mlx5_accel_esp_xfrm *xfrm);
63int mlx5_fpga_esp_modify_xfrm(struct mlx5_accel_esp_xfrm *xfrm,
64 const struct mlx5_accel_esp_xfrm_attrs *attrs);
54 65
55static inline void *mlx5_fpga_ipsec_sa_cmd_exec(struct mlx5_core_dev *mdev, 66const struct mlx5_flow_cmds *
56 struct mlx5_accel_ipsec_sa *cmd) 67mlx5_fs_cmd_get_default_ipsec_fpga_cmds(enum fs_flow_table_type type);
57{
58 return ERR_PTR(-EOPNOTSUPP);
59}
60 68
61static inline int mlx5_fpga_ipsec_sa_cmd_wait(void *context) 69#else
62{
63 return -EOPNOTSUPP;
64}
65 70
66static inline u32 mlx5_fpga_ipsec_device_caps(struct mlx5_core_dev *mdev) 71static inline u32 mlx5_fpga_ipsec_device_caps(struct mlx5_core_dev *mdev)
67{ 72{
@@ -80,6 +85,20 @@ static inline int mlx5_fpga_ipsec_counters_read(struct mlx5_core_dev *mdev,
80 return 0; 85 return 0;
81} 86}
82 87
88static inline void *
89mlx5_fpga_ipsec_create_sa_ctx(struct mlx5_core_dev *mdev,
90 struct mlx5_accel_esp_xfrm *accel_xfrm,
91 const __be32 saddr[4],
92 const __be32 daddr[4],
93 const __be32 spi, bool is_ipv6)
94{
95 return NULL;
96}
97
98static inline void mlx5_fpga_ipsec_delete_sa_ctx(void *context)
99{
100}
101
83static inline int mlx5_fpga_ipsec_init(struct mlx5_core_dev *mdev) 102static inline int mlx5_fpga_ipsec_init(struct mlx5_core_dev *mdev)
84{ 103{
85 return 0; 104 return 0;
@@ -89,6 +108,35 @@ static inline void mlx5_fpga_ipsec_cleanup(struct mlx5_core_dev *mdev)
89{ 108{
90} 109}
91 110
111static inline void mlx5_fpga_ipsec_build_fs_cmds(void)
112{
113}
114
115static inline struct mlx5_accel_esp_xfrm *
116mlx5_fpga_esp_create_xfrm(struct mlx5_core_dev *mdev,
117 const struct mlx5_accel_esp_xfrm_attrs *attrs,
118 u32 flags)
119{
120 return ERR_PTR(-EOPNOTSUPP);
121}
122
123static inline void mlx5_fpga_esp_destroy_xfrm(struct mlx5_accel_esp_xfrm *xfrm)
124{
125}
126
127static inline int
128mlx5_fpga_esp_modify_xfrm(struct mlx5_accel_esp_xfrm *xfrm,
129 const struct mlx5_accel_esp_xfrm_attrs *attrs)
130{
131 return -EOPNOTSUPP;
132}
133
134static inline const struct mlx5_flow_cmds *
135mlx5_fs_cmd_get_default_ipsec_fpga_cmds(enum fs_flow_table_type type)
136{
137 return mlx5_fs_cmd_get_default(type);
138}
139
92#endif /* CONFIG_MLX5_FPGA */ 140#endif /* CONFIG_MLX5_FPGA */
93 141
94#endif /* __MLX5_FPGA_SADB_H__ */ 142#endif /* __MLX5_FPGA_SADB_H__ */
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c
index 881e2e55840c..645f83cac34d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c
@@ -39,9 +39,81 @@
39#include "mlx5_core.h" 39#include "mlx5_core.h"
40#include "eswitch.h" 40#include "eswitch.h"
41 41
42int mlx5_cmd_update_root_ft(struct mlx5_core_dev *dev, 42static int mlx5_cmd_stub_update_root_ft(struct mlx5_core_dev *dev,
43 struct mlx5_flow_table *ft, u32 underlay_qpn, 43 struct mlx5_flow_table *ft,
44 bool disconnect) 44 u32 underlay_qpn,
45 bool disconnect)
46{
47 return 0;
48}
49
50static int mlx5_cmd_stub_create_flow_table(struct mlx5_core_dev *dev,
51 u16 vport,
52 enum fs_flow_table_op_mod op_mod,
53 enum fs_flow_table_type type,
54 unsigned int level,
55 unsigned int log_size,
56 struct mlx5_flow_table *next_ft,
57 unsigned int *table_id, u32 flags)
58{
59 return 0;
60}
61
62static int mlx5_cmd_stub_destroy_flow_table(struct mlx5_core_dev *dev,
63 struct mlx5_flow_table *ft)
64{
65 return 0;
66}
67
68static int mlx5_cmd_stub_modify_flow_table(struct mlx5_core_dev *dev,
69 struct mlx5_flow_table *ft,
70 struct mlx5_flow_table *next_ft)
71{
72 return 0;
73}
74
75static int mlx5_cmd_stub_create_flow_group(struct mlx5_core_dev *dev,
76 struct mlx5_flow_table *ft,
77 u32 *in,
78 unsigned int *group_id)
79{
80 return 0;
81}
82
83static int mlx5_cmd_stub_destroy_flow_group(struct mlx5_core_dev *dev,
84 struct mlx5_flow_table *ft,
85 unsigned int group_id)
86{
87 return 0;
88}
89
90static int mlx5_cmd_stub_create_fte(struct mlx5_core_dev *dev,
91 struct mlx5_flow_table *ft,
92 struct mlx5_flow_group *group,
93 struct fs_fte *fte)
94{
95 return 0;
96}
97
98static int mlx5_cmd_stub_update_fte(struct mlx5_core_dev *dev,
99 struct mlx5_flow_table *ft,
100 unsigned int group_id,
101 int modify_mask,
102 struct fs_fte *fte)
103{
104 return -EOPNOTSUPP;
105}
106
107static int mlx5_cmd_stub_delete_fte(struct mlx5_core_dev *dev,
108 struct mlx5_flow_table *ft,
109 struct fs_fte *fte)
110{
111 return 0;
112}
113
114static int mlx5_cmd_update_root_ft(struct mlx5_core_dev *dev,
115 struct mlx5_flow_table *ft, u32 underlay_qpn,
116 bool disconnect)
45{ 117{
46 u32 in[MLX5_ST_SZ_DW(set_flow_table_root_in)] = {0}; 118 u32 in[MLX5_ST_SZ_DW(set_flow_table_root_in)] = {0};
47 u32 out[MLX5_ST_SZ_DW(set_flow_table_root_out)] = {0}; 119 u32 out[MLX5_ST_SZ_DW(set_flow_table_root_out)] = {0};
@@ -71,12 +143,14 @@ int mlx5_cmd_update_root_ft(struct mlx5_core_dev *dev,
71 return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); 143 return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
72} 144}
73 145
74int mlx5_cmd_create_flow_table(struct mlx5_core_dev *dev, 146static int mlx5_cmd_create_flow_table(struct mlx5_core_dev *dev,
75 u16 vport, 147 u16 vport,
76 enum fs_flow_table_op_mod op_mod, 148 enum fs_flow_table_op_mod op_mod,
77 enum fs_flow_table_type type, unsigned int level, 149 enum fs_flow_table_type type,
78 unsigned int log_size, struct mlx5_flow_table 150 unsigned int level,
79 *next_ft, unsigned int *table_id, u32 flags) 151 unsigned int log_size,
152 struct mlx5_flow_table *next_ft,
153 unsigned int *table_id, u32 flags)
80{ 154{
81 int en_encap_decap = !!(flags & MLX5_FLOW_TABLE_TUNNEL_EN); 155 int en_encap_decap = !!(flags & MLX5_FLOW_TABLE_TUNNEL_EN);
82 u32 out[MLX5_ST_SZ_DW(create_flow_table_out)] = {0}; 156 u32 out[MLX5_ST_SZ_DW(create_flow_table_out)] = {0};
@@ -125,8 +199,8 @@ int mlx5_cmd_create_flow_table(struct mlx5_core_dev *dev,
125 return err; 199 return err;
126} 200}
127 201
128int mlx5_cmd_destroy_flow_table(struct mlx5_core_dev *dev, 202static int mlx5_cmd_destroy_flow_table(struct mlx5_core_dev *dev,
129 struct mlx5_flow_table *ft) 203 struct mlx5_flow_table *ft)
130{ 204{
131 u32 in[MLX5_ST_SZ_DW(destroy_flow_table_in)] = {0}; 205 u32 in[MLX5_ST_SZ_DW(destroy_flow_table_in)] = {0};
132 u32 out[MLX5_ST_SZ_DW(destroy_flow_table_out)] = {0}; 206 u32 out[MLX5_ST_SZ_DW(destroy_flow_table_out)] = {0};
@@ -143,9 +217,9 @@ int mlx5_cmd_destroy_flow_table(struct mlx5_core_dev *dev,
143 return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); 217 return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
144} 218}
145 219
146int mlx5_cmd_modify_flow_table(struct mlx5_core_dev *dev, 220static int mlx5_cmd_modify_flow_table(struct mlx5_core_dev *dev,
147 struct mlx5_flow_table *ft, 221 struct mlx5_flow_table *ft,
148 struct mlx5_flow_table *next_ft) 222 struct mlx5_flow_table *next_ft)
149{ 223{
150 u32 in[MLX5_ST_SZ_DW(modify_flow_table_in)] = {0}; 224 u32 in[MLX5_ST_SZ_DW(modify_flow_table_in)] = {0};
151 u32 out[MLX5_ST_SZ_DW(modify_flow_table_out)] = {0}; 225 u32 out[MLX5_ST_SZ_DW(modify_flow_table_out)] = {0};
@@ -188,10 +262,10 @@ int mlx5_cmd_modify_flow_table(struct mlx5_core_dev *dev,
188 return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); 262 return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
189} 263}
190 264
191int mlx5_cmd_create_flow_group(struct mlx5_core_dev *dev, 265static int mlx5_cmd_create_flow_group(struct mlx5_core_dev *dev,
192 struct mlx5_flow_table *ft, 266 struct mlx5_flow_table *ft,
193 u32 *in, 267 u32 *in,
194 unsigned int *group_id) 268 unsigned int *group_id)
195{ 269{
196 u32 out[MLX5_ST_SZ_DW(create_flow_group_out)] = {0}; 270 u32 out[MLX5_ST_SZ_DW(create_flow_group_out)] = {0};
197 int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in); 271 int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
@@ -213,9 +287,9 @@ int mlx5_cmd_create_flow_group(struct mlx5_core_dev *dev,
213 return err; 287 return err;
214} 288}
215 289
216int mlx5_cmd_destroy_flow_group(struct mlx5_core_dev *dev, 290static int mlx5_cmd_destroy_flow_group(struct mlx5_core_dev *dev,
217 struct mlx5_flow_table *ft, 291 struct mlx5_flow_table *ft,
218 unsigned int group_id) 292 unsigned int group_id)
219{ 293{
220 u32 out[MLX5_ST_SZ_DW(destroy_flow_group_out)] = {0}; 294 u32 out[MLX5_ST_SZ_DW(destroy_flow_group_out)] = {0};
221 u32 in[MLX5_ST_SZ_DW(destroy_flow_group_in)] = {0}; 295 u32 in[MLX5_ST_SZ_DW(destroy_flow_group_in)] = {0};
@@ -266,16 +340,17 @@ static int mlx5_cmd_set_fte(struct mlx5_core_dev *dev,
266 340
267 in_flow_context = MLX5_ADDR_OF(set_fte_in, in, flow_context); 341 in_flow_context = MLX5_ADDR_OF(set_fte_in, in, flow_context);
268 MLX5_SET(flow_context, in_flow_context, group_id, group_id); 342 MLX5_SET(flow_context, in_flow_context, group_id, group_id);
269 MLX5_SET(flow_context, in_flow_context, flow_tag, fte->flow_tag); 343 MLX5_SET(flow_context, in_flow_context, flow_tag, fte->action.flow_tag);
270 MLX5_SET(flow_context, in_flow_context, action, fte->action); 344 MLX5_SET(flow_context, in_flow_context, action, fte->action.action);
271 MLX5_SET(flow_context, in_flow_context, encap_id, fte->encap_id); 345 MLX5_SET(flow_context, in_flow_context, encap_id, fte->action.encap_id);
272 MLX5_SET(flow_context, in_flow_context, modify_header_id, fte->modify_id); 346 MLX5_SET(flow_context, in_flow_context, modify_header_id,
347 fte->action.modify_id);
273 in_match_value = MLX5_ADDR_OF(flow_context, in_flow_context, 348 in_match_value = MLX5_ADDR_OF(flow_context, in_flow_context,
274 match_value); 349 match_value);
275 memcpy(in_match_value, &fte->val, sizeof(fte->val)); 350 memcpy(in_match_value, &fte->val, sizeof(fte->val));
276 351
277 in_dests = MLX5_ADDR_OF(flow_context, in_flow_context, destination); 352 in_dests = MLX5_ADDR_OF(flow_context, in_flow_context, destination);
278 if (fte->action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) { 353 if (fte->action.action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) {
279 int list_size = 0; 354 int list_size = 0;
280 355
281 list_for_each_entry(dst, &fte->node.children, node.list) { 356 list_for_each_entry(dst, &fte->node.children, node.list) {
@@ -301,7 +376,7 @@ static int mlx5_cmd_set_fte(struct mlx5_core_dev *dev,
301 list_size); 376 list_size);
302 } 377 }
303 378
304 if (fte->action & MLX5_FLOW_CONTEXT_ACTION_COUNT) { 379 if (fte->action.action & MLX5_FLOW_CONTEXT_ACTION_COUNT) {
305 int max_list_size = BIT(MLX5_CAP_FLOWTABLE_TYPE(dev, 380 int max_list_size = BIT(MLX5_CAP_FLOWTABLE_TYPE(dev,
306 log_max_flow_counter, 381 log_max_flow_counter,
307 ft->type)); 382 ft->type));
@@ -332,19 +407,21 @@ err_out:
332 return err; 407 return err;
333} 408}
334 409
335int mlx5_cmd_create_fte(struct mlx5_core_dev *dev, 410static int mlx5_cmd_create_fte(struct mlx5_core_dev *dev,
336 struct mlx5_flow_table *ft, 411 struct mlx5_flow_table *ft,
337 unsigned group_id, 412 struct mlx5_flow_group *group,
338 struct fs_fte *fte) 413 struct fs_fte *fte)
339{ 414{
415 unsigned int group_id = group->id;
416
340 return mlx5_cmd_set_fte(dev, 0, 0, ft, group_id, fte); 417 return mlx5_cmd_set_fte(dev, 0, 0, ft, group_id, fte);
341} 418}
342 419
343int mlx5_cmd_update_fte(struct mlx5_core_dev *dev, 420static int mlx5_cmd_update_fte(struct mlx5_core_dev *dev,
344 struct mlx5_flow_table *ft, 421 struct mlx5_flow_table *ft,
345 unsigned group_id, 422 unsigned int group_id,
346 int modify_mask, 423 int modify_mask,
347 struct fs_fte *fte) 424 struct fs_fte *fte)
348{ 425{
349 int opmod; 426 int opmod;
350 int atomic_mod_cap = MLX5_CAP_FLOWTABLE(dev, 427 int atomic_mod_cap = MLX5_CAP_FLOWTABLE(dev,
@@ -357,9 +434,9 @@ int mlx5_cmd_update_fte(struct mlx5_core_dev *dev,
357 return mlx5_cmd_set_fte(dev, opmod, modify_mask, ft, group_id, fte); 434 return mlx5_cmd_set_fte(dev, opmod, modify_mask, ft, group_id, fte);
358} 435}
359 436
360int mlx5_cmd_delete_fte(struct mlx5_core_dev *dev, 437static int mlx5_cmd_delete_fte(struct mlx5_core_dev *dev,
361 struct mlx5_flow_table *ft, 438 struct mlx5_flow_table *ft,
362 unsigned int index) 439 struct fs_fte *fte)
363{ 440{
364 u32 out[MLX5_ST_SZ_DW(delete_fte_out)] = {0}; 441 u32 out[MLX5_ST_SZ_DW(delete_fte_out)] = {0};
365 u32 in[MLX5_ST_SZ_DW(delete_fte_in)] = {0}; 442 u32 in[MLX5_ST_SZ_DW(delete_fte_in)] = {0};
@@ -367,7 +444,7 @@ int mlx5_cmd_delete_fte(struct mlx5_core_dev *dev,
367 MLX5_SET(delete_fte_in, in, opcode, MLX5_CMD_OP_DELETE_FLOW_TABLE_ENTRY); 444 MLX5_SET(delete_fte_in, in, opcode, MLX5_CMD_OP_DELETE_FLOW_TABLE_ENTRY);
368 MLX5_SET(delete_fte_in, in, table_type, ft->type); 445 MLX5_SET(delete_fte_in, in, table_type, ft->type);
369 MLX5_SET(delete_fte_in, in, table_id, ft->id); 446 MLX5_SET(delete_fte_in, in, table_id, ft->id);
370 MLX5_SET(delete_fte_in, in, flow_index, index); 447 MLX5_SET(delete_fte_in, in, flow_index, fte->index);
371 if (ft->vport) { 448 if (ft->vport) {
372 MLX5_SET(delete_fte_in, in, vport_number, ft->vport); 449 MLX5_SET(delete_fte_in, in, vport_number, ft->vport);
373 MLX5_SET(delete_fte_in, in, other_vport, 1); 450 MLX5_SET(delete_fte_in, in, other_vport, 1);
@@ -610,3 +687,53 @@ void mlx5_modify_header_dealloc(struct mlx5_core_dev *dev, u32 modify_header_id)
610 687
611 mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); 688 mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
612} 689}
690
691static const struct mlx5_flow_cmds mlx5_flow_cmds = {
692 .create_flow_table = mlx5_cmd_create_flow_table,
693 .destroy_flow_table = mlx5_cmd_destroy_flow_table,
694 .modify_flow_table = mlx5_cmd_modify_flow_table,
695 .create_flow_group = mlx5_cmd_create_flow_group,
696 .destroy_flow_group = mlx5_cmd_destroy_flow_group,
697 .create_fte = mlx5_cmd_create_fte,
698 .update_fte = mlx5_cmd_update_fte,
699 .delete_fte = mlx5_cmd_delete_fte,
700 .update_root_ft = mlx5_cmd_update_root_ft,
701};
702
703static const struct mlx5_flow_cmds mlx5_flow_cmd_stubs = {
704 .create_flow_table = mlx5_cmd_stub_create_flow_table,
705 .destroy_flow_table = mlx5_cmd_stub_destroy_flow_table,
706 .modify_flow_table = mlx5_cmd_stub_modify_flow_table,
707 .create_flow_group = mlx5_cmd_stub_create_flow_group,
708 .destroy_flow_group = mlx5_cmd_stub_destroy_flow_group,
709 .create_fte = mlx5_cmd_stub_create_fte,
710 .update_fte = mlx5_cmd_stub_update_fte,
711 .delete_fte = mlx5_cmd_stub_delete_fte,
712 .update_root_ft = mlx5_cmd_stub_update_root_ft,
713};
714
715static const struct mlx5_flow_cmds *mlx5_fs_cmd_get_fw_cmds(void)
716{
717 return &mlx5_flow_cmds;
718}
719
720static const struct mlx5_flow_cmds *mlx5_fs_cmd_get_stub_cmds(void)
721{
722 return &mlx5_flow_cmd_stubs;
723}
724
725const struct mlx5_flow_cmds *mlx5_fs_cmd_get_default(enum fs_flow_table_type type)
726{
727 switch (type) {
728 case FS_FT_NIC_RX:
729 case FS_FT_ESW_EGRESS_ACL:
730 case FS_FT_ESW_INGRESS_ACL:
731 case FS_FT_FDB:
732 case FS_FT_SNIFFER_RX:
733 case FS_FT_SNIFFER_TX:
734 return mlx5_fs_cmd_get_fw_cmds();
735 case FS_FT_NIC_TX:
736 default:
737 return mlx5_fs_cmd_get_stub_cmds();
738 }
739}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.h b/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.h
index 71e2d0f37ad9..6228ba7bfa1a 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.h
@@ -33,46 +33,52 @@
33#ifndef _MLX5_FS_CMD_ 33#ifndef _MLX5_FS_CMD_
34#define _MLX5_FS_CMD_ 34#define _MLX5_FS_CMD_
35 35
36int mlx5_cmd_create_flow_table(struct mlx5_core_dev *dev, 36#include "fs_core.h"
37 u16 vport,
38 enum fs_flow_table_op_mod op_mod,
39 enum fs_flow_table_type type, unsigned int level,
40 unsigned int log_size, struct mlx5_flow_table
41 *next_ft, unsigned int *table_id, u32 flags);
42 37
43int mlx5_cmd_destroy_flow_table(struct mlx5_core_dev *dev, 38struct mlx5_flow_cmds {
44 struct mlx5_flow_table *ft); 39 int (*create_flow_table)(struct mlx5_core_dev *dev,
40 u16 vport,
41 enum fs_flow_table_op_mod op_mod,
42 enum fs_flow_table_type type,
43 unsigned int level, unsigned int log_size,
44 struct mlx5_flow_table *next_ft,
45 unsigned int *table_id, u32 flags);
46 int (*destroy_flow_table)(struct mlx5_core_dev *dev,
47 struct mlx5_flow_table *ft);
45 48
46int mlx5_cmd_modify_flow_table(struct mlx5_core_dev *dev, 49 int (*modify_flow_table)(struct mlx5_core_dev *dev,
47 struct mlx5_flow_table *ft, 50 struct mlx5_flow_table *ft,
48 struct mlx5_flow_table *next_ft); 51 struct mlx5_flow_table *next_ft);
49 52
50int mlx5_cmd_create_flow_group(struct mlx5_core_dev *dev, 53 int (*create_flow_group)(struct mlx5_core_dev *dev,
51 struct mlx5_flow_table *ft, 54 struct mlx5_flow_table *ft,
52 u32 *in, unsigned int *group_id); 55 u32 *in,
56 unsigned int *group_id);
53 57
54int mlx5_cmd_destroy_flow_group(struct mlx5_core_dev *dev, 58 int (*destroy_flow_group)(struct mlx5_core_dev *dev,
55 struct mlx5_flow_table *ft, 59 struct mlx5_flow_table *ft,
56 unsigned int group_id); 60 unsigned int group_id);
57 61
58int mlx5_cmd_create_fte(struct mlx5_core_dev *dev, 62 int (*create_fte)(struct mlx5_core_dev *dev,
59 struct mlx5_flow_table *ft, 63 struct mlx5_flow_table *ft,
60 unsigned group_id, 64 struct mlx5_flow_group *fg,
61 struct fs_fte *fte); 65 struct fs_fte *fte);
62 66
63int mlx5_cmd_update_fte(struct mlx5_core_dev *dev, 67 int (*update_fte)(struct mlx5_core_dev *dev,
64 struct mlx5_flow_table *ft, 68 struct mlx5_flow_table *ft,
65 unsigned group_id, 69 unsigned int group_id,
66 int modify_mask, 70 int modify_mask,
67 struct fs_fte *fte); 71 struct fs_fte *fte);
68 72
69int mlx5_cmd_delete_fte(struct mlx5_core_dev *dev, 73 int (*delete_fte)(struct mlx5_core_dev *dev,
70 struct mlx5_flow_table *ft, 74 struct mlx5_flow_table *ft,
71 unsigned int index); 75 struct fs_fte *fte);
72 76
73int mlx5_cmd_update_root_ft(struct mlx5_core_dev *dev, 77 int (*update_root_ft)(struct mlx5_core_dev *dev,
74 struct mlx5_flow_table *ft, u32 underlay_qpn, 78 struct mlx5_flow_table *ft,
75 bool disconnect); 79 u32 underlay_qpn,
80 bool disconnect);
81};
76 82
77int mlx5_cmd_fc_alloc(struct mlx5_core_dev *dev, u32 *id); 83int mlx5_cmd_fc_alloc(struct mlx5_core_dev *dev, u32 *id);
78int mlx5_cmd_fc_free(struct mlx5_core_dev *dev, u32 id); 84int mlx5_cmd_fc_free(struct mlx5_core_dev *dev, u32 id);
@@ -90,4 +96,6 @@ void mlx5_cmd_fc_bulk_get(struct mlx5_core_dev *dev,
90 struct mlx5_cmd_fc_bulk *b, u32 id, 96 struct mlx5_cmd_fc_bulk *b, u32 id,
91 u64 *packets, u64 *bytes); 97 u64 *packets, u64 *bytes);
92 98
99const struct mlx5_flow_cmds *mlx5_fs_cmd_get_default(enum fs_flow_table_type type);
100
93#endif 101#endif
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
index 31fc2cfac3b3..3ba07c7096ef 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
@@ -37,6 +37,8 @@
37#include "fs_core.h" 37#include "fs_core.h"
38#include "fs_cmd.h" 38#include "fs_cmd.h"
39#include "diag/fs_tracepoint.h" 39#include "diag/fs_tracepoint.h"
40#include "accel/ipsec.h"
41#include "fpga/ipsec.h"
40 42
41#define INIT_TREE_NODE_ARRAY_SIZE(...) (sizeof((struct init_tree_node[]){__VA_ARGS__}) /\ 43#define INIT_TREE_NODE_ARRAY_SIZE(...) (sizeof((struct init_tree_node[]){__VA_ARGS__}) /\
42 sizeof(struct init_tree_node)) 44 sizeof(struct init_tree_node))
@@ -425,15 +427,17 @@ static void del_sw_prio(struct fs_node *node)
425 427
426static void del_hw_flow_table(struct fs_node *node) 428static void del_hw_flow_table(struct fs_node *node)
427{ 429{
430 struct mlx5_flow_root_namespace *root;
428 struct mlx5_flow_table *ft; 431 struct mlx5_flow_table *ft;
429 struct mlx5_core_dev *dev; 432 struct mlx5_core_dev *dev;
430 int err; 433 int err;
431 434
432 fs_get_obj(ft, node); 435 fs_get_obj(ft, node);
433 dev = get_dev(&ft->node); 436 dev = get_dev(&ft->node);
437 root = find_root(&ft->node);
434 438
435 if (node->active) { 439 if (node->active) {
436 err = mlx5_cmd_destroy_flow_table(dev, ft); 440 err = root->cmds->destroy_flow_table(dev, ft);
437 if (err) 441 if (err)
438 mlx5_core_warn(dev, "flow steering can't destroy ft\n"); 442 mlx5_core_warn(dev, "flow steering can't destroy ft\n");
439 } 443 }
@@ -454,6 +458,7 @@ static void del_sw_flow_table(struct fs_node *node)
454 458
455static void del_sw_hw_rule(struct fs_node *node) 459static void del_sw_hw_rule(struct fs_node *node)
456{ 460{
461 struct mlx5_flow_root_namespace *root;
457 struct mlx5_flow_rule *rule; 462 struct mlx5_flow_rule *rule;
458 struct mlx5_flow_table *ft; 463 struct mlx5_flow_table *ft;
459 struct mlx5_flow_group *fg; 464 struct mlx5_flow_group *fg;
@@ -477,19 +482,20 @@ static void del_sw_hw_rule(struct fs_node *node)
477 if (rule->dest_attr.type == MLX5_FLOW_DESTINATION_TYPE_COUNTER && 482 if (rule->dest_attr.type == MLX5_FLOW_DESTINATION_TYPE_COUNTER &&
478 --fte->dests_size) { 483 --fte->dests_size) {
479 modify_mask = BIT(MLX5_SET_FTE_MODIFY_ENABLE_MASK_ACTION); 484 modify_mask = BIT(MLX5_SET_FTE_MODIFY_ENABLE_MASK_ACTION);
480 fte->action &= ~MLX5_FLOW_CONTEXT_ACTION_COUNT; 485 fte->action.action &= ~MLX5_FLOW_CONTEXT_ACTION_COUNT;
481 update_fte = true; 486 update_fte = true;
482 goto out; 487 goto out;
483 } 488 }
484 489
485 if ((fte->action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) && 490 if ((fte->action.action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) &&
486 --fte->dests_size) { 491 --fte->dests_size) {
487 modify_mask = BIT(MLX5_SET_FTE_MODIFY_ENABLE_MASK_DESTINATION_LIST), 492 modify_mask = BIT(MLX5_SET_FTE_MODIFY_ENABLE_MASK_DESTINATION_LIST),
488 update_fte = true; 493 update_fte = true;
489 } 494 }
490out: 495out:
496 root = find_root(&ft->node);
491 if (update_fte && fte->dests_size) { 497 if (update_fte && fte->dests_size) {
492 err = mlx5_cmd_update_fte(dev, ft, fg->id, modify_mask, fte); 498 err = root->cmds->update_fte(dev, ft, fg->id, modify_mask, fte);
493 if (err) 499 if (err)
494 mlx5_core_warn(dev, 500 mlx5_core_warn(dev,
495 "%s can't del rule fg id=%d fte_index=%d\n", 501 "%s can't del rule fg id=%d fte_index=%d\n",
@@ -500,6 +506,7 @@ out:
500 506
501static void del_hw_fte(struct fs_node *node) 507static void del_hw_fte(struct fs_node *node)
502{ 508{
509 struct mlx5_flow_root_namespace *root;
503 struct mlx5_flow_table *ft; 510 struct mlx5_flow_table *ft;
504 struct mlx5_flow_group *fg; 511 struct mlx5_flow_group *fg;
505 struct mlx5_core_dev *dev; 512 struct mlx5_core_dev *dev;
@@ -512,9 +519,9 @@ static void del_hw_fte(struct fs_node *node)
512 519
513 trace_mlx5_fs_del_fte(fte); 520 trace_mlx5_fs_del_fte(fte);
514 dev = get_dev(&ft->node); 521 dev = get_dev(&ft->node);
522 root = find_root(&ft->node);
515 if (node->active) { 523 if (node->active) {
516 err = mlx5_cmd_delete_fte(dev, ft, 524 err = root->cmds->delete_fte(dev, ft, fte);
517 fte->index);
518 if (err) 525 if (err)
519 mlx5_core_warn(dev, 526 mlx5_core_warn(dev,
520 "flow steering can't delete fte in index %d of flow group id %d\n", 527 "flow steering can't delete fte in index %d of flow group id %d\n",
@@ -542,6 +549,7 @@ static void del_sw_fte(struct fs_node *node)
542 549
543static void del_hw_flow_group(struct fs_node *node) 550static void del_hw_flow_group(struct fs_node *node)
544{ 551{
552 struct mlx5_flow_root_namespace *root;
545 struct mlx5_flow_group *fg; 553 struct mlx5_flow_group *fg;
546 struct mlx5_flow_table *ft; 554 struct mlx5_flow_table *ft;
547 struct mlx5_core_dev *dev; 555 struct mlx5_core_dev *dev;
@@ -551,7 +559,8 @@ static void del_hw_flow_group(struct fs_node *node)
551 dev = get_dev(&ft->node); 559 dev = get_dev(&ft->node);
552 trace_mlx5_fs_del_fg(fg); 560 trace_mlx5_fs_del_fg(fg);
553 561
554 if (fg->node.active && mlx5_cmd_destroy_flow_group(dev, ft, fg->id)) 562 root = find_root(&ft->node);
563 if (fg->node.active && root->cmds->destroy_flow_group(dev, ft, fg->id))
555 mlx5_core_warn(dev, "flow steering can't destroy fg %d of ft %d\n", 564 mlx5_core_warn(dev, "flow steering can't destroy fg %d of ft %d\n",
556 fg->id, ft->id); 565 fg->id, ft->id);
557} 566}
@@ -615,10 +624,7 @@ static struct fs_fte *alloc_fte(struct mlx5_flow_table *ft,
615 624
616 memcpy(fte->val, match_value, sizeof(fte->val)); 625 memcpy(fte->val, match_value, sizeof(fte->val));
617 fte->node.type = FS_TYPE_FLOW_ENTRY; 626 fte->node.type = FS_TYPE_FLOW_ENTRY;
618 fte->flow_tag = flow_act->flow_tag; 627 fte->action = *flow_act;
619 fte->action = flow_act->action;
620 fte->encap_id = flow_act->encap_id;
621 fte->modify_id = flow_act->modify_id;
622 628
623 tree_init_node(&fte->node, del_hw_fte, del_sw_fte); 629 tree_init_node(&fte->node, del_hw_fte, del_sw_fte);
624 630
@@ -797,15 +803,14 @@ static int connect_fts_in_prio(struct mlx5_core_dev *dev,
797 struct fs_prio *prio, 803 struct fs_prio *prio,
798 struct mlx5_flow_table *ft) 804 struct mlx5_flow_table *ft)
799{ 805{
806 struct mlx5_flow_root_namespace *root = find_root(&prio->node);
800 struct mlx5_flow_table *iter; 807 struct mlx5_flow_table *iter;
801 int i = 0; 808 int i = 0;
802 int err; 809 int err;
803 810
804 fs_for_each_ft(iter, prio) { 811 fs_for_each_ft(iter, prio) {
805 i++; 812 i++;
806 err = mlx5_cmd_modify_flow_table(dev, 813 err = root->cmds->modify_flow_table(dev, iter, ft);
807 iter,
808 ft);
809 if (err) { 814 if (err) {
810 mlx5_core_warn(dev, "Failed to modify flow table %d\n", 815 mlx5_core_warn(dev, "Failed to modify flow table %d\n",
811 iter->id); 816 iter->id);
@@ -853,12 +858,12 @@ static int update_root_ft_create(struct mlx5_flow_table *ft, struct fs_prio
853 if (list_empty(&root->underlay_qpns)) { 858 if (list_empty(&root->underlay_qpns)) {
854 /* Don't set any QPN (zero) in case QPN list is empty */ 859 /* Don't set any QPN (zero) in case QPN list is empty */
855 qpn = 0; 860 qpn = 0;
856 err = mlx5_cmd_update_root_ft(root->dev, ft, qpn, false); 861 err = root->cmds->update_root_ft(root->dev, ft, qpn, false);
857 } else { 862 } else {
858 list_for_each_entry(uqp, &root->underlay_qpns, list) { 863 list_for_each_entry(uqp, &root->underlay_qpns, list) {
859 qpn = uqp->qpn; 864 qpn = uqp->qpn;
860 err = mlx5_cmd_update_root_ft(root->dev, ft, qpn, 865 err = root->cmds->update_root_ft(root->dev, ft,
861 false); 866 qpn, false);
862 if (err) 867 if (err)
863 break; 868 break;
864 } 869 }
@@ -877,6 +882,7 @@ static int update_root_ft_create(struct mlx5_flow_table *ft, struct fs_prio
877static int _mlx5_modify_rule_destination(struct mlx5_flow_rule *rule, 882static int _mlx5_modify_rule_destination(struct mlx5_flow_rule *rule,
878 struct mlx5_flow_destination *dest) 883 struct mlx5_flow_destination *dest)
879{ 884{
885 struct mlx5_flow_root_namespace *root;
880 struct mlx5_flow_table *ft; 886 struct mlx5_flow_table *ft;
881 struct mlx5_flow_group *fg; 887 struct mlx5_flow_group *fg;
882 struct fs_fte *fte; 888 struct fs_fte *fte;
@@ -884,17 +890,16 @@ static int _mlx5_modify_rule_destination(struct mlx5_flow_rule *rule,
884 int err = 0; 890 int err = 0;
885 891
886 fs_get_obj(fte, rule->node.parent); 892 fs_get_obj(fte, rule->node.parent);
887 if (!(fte->action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST)) 893 if (!(fte->action.action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST))
888 return -EINVAL; 894 return -EINVAL;
889 down_write_ref_node(&fte->node); 895 down_write_ref_node(&fte->node);
890 fs_get_obj(fg, fte->node.parent); 896 fs_get_obj(fg, fte->node.parent);
891 fs_get_obj(ft, fg->node.parent); 897 fs_get_obj(ft, fg->node.parent);
892 898
893 memcpy(&rule->dest_attr, dest, sizeof(*dest)); 899 memcpy(&rule->dest_attr, dest, sizeof(*dest));
894 err = mlx5_cmd_update_fte(get_dev(&ft->node), 900 root = find_root(&ft->node);
895 ft, fg->id, 901 err = root->cmds->update_fte(get_dev(&ft->node), ft, fg->id,
896 modify_mask, 902 modify_mask, fte);
897 fte);
898 up_write_ref_node(&fte->node); 903 up_write_ref_node(&fte->node);
899 904
900 return err; 905 return err;
@@ -1035,9 +1040,9 @@ static struct mlx5_flow_table *__mlx5_create_flow_table(struct mlx5_flow_namespa
1035 tree_init_node(&ft->node, del_hw_flow_table, del_sw_flow_table); 1040 tree_init_node(&ft->node, del_hw_flow_table, del_sw_flow_table);
1036 log_table_sz = ft->max_fte ? ilog2(ft->max_fte) : 0; 1041 log_table_sz = ft->max_fte ? ilog2(ft->max_fte) : 0;
1037 next_ft = find_next_chained_ft(fs_prio); 1042 next_ft = find_next_chained_ft(fs_prio);
1038 err = mlx5_cmd_create_flow_table(root->dev, ft->vport, ft->op_mod, ft->type, 1043 err = root->cmds->create_flow_table(root->dev, ft->vport, ft->op_mod,
1039 ft->level, log_table_sz, next_ft, &ft->id, 1044 ft->type, ft->level, log_table_sz,
1040 ft->flags); 1045 next_ft, &ft->id, ft->flags);
1041 if (err) 1046 if (err)
1042 goto free_ft; 1047 goto free_ft;
1043 1048
@@ -1053,7 +1058,7 @@ static struct mlx5_flow_table *__mlx5_create_flow_table(struct mlx5_flow_namespa
1053 mutex_unlock(&root->chain_lock); 1058 mutex_unlock(&root->chain_lock);
1054 return ft; 1059 return ft;
1055destroy_ft: 1060destroy_ft:
1056 mlx5_cmd_destroy_flow_table(root->dev, ft); 1061 root->cmds->destroy_flow_table(root->dev, ft);
1057free_ft: 1062free_ft:
1058 kfree(ft); 1063 kfree(ft);
1059unlock_root: 1064unlock_root:
@@ -1125,6 +1130,7 @@ EXPORT_SYMBOL(mlx5_create_auto_grouped_flow_table);
1125struct mlx5_flow_group *mlx5_create_flow_group(struct mlx5_flow_table *ft, 1130struct mlx5_flow_group *mlx5_create_flow_group(struct mlx5_flow_table *ft,
1126 u32 *fg_in) 1131 u32 *fg_in)
1127{ 1132{
1133 struct mlx5_flow_root_namespace *root = find_root(&ft->node);
1128 void *match_criteria = MLX5_ADDR_OF(create_flow_group_in, 1134 void *match_criteria = MLX5_ADDR_OF(create_flow_group_in,
1129 fg_in, match_criteria); 1135 fg_in, match_criteria);
1130 u8 match_criteria_enable = MLX5_GET(create_flow_group_in, 1136 u8 match_criteria_enable = MLX5_GET(create_flow_group_in,
@@ -1152,7 +1158,7 @@ struct mlx5_flow_group *mlx5_create_flow_group(struct mlx5_flow_table *ft,
1152 if (IS_ERR(fg)) 1158 if (IS_ERR(fg))
1153 return fg; 1159 return fg;
1154 1160
1155 err = mlx5_cmd_create_flow_group(dev, ft, fg_in, &fg->id); 1161 err = root->cmds->create_flow_group(dev, ft, fg_in, &fg->id);
1156 if (err) { 1162 if (err) {
1157 tree_put_node(&fg->node); 1163 tree_put_node(&fg->node);
1158 return ERR_PTR(err); 1164 return ERR_PTR(err);
@@ -1275,6 +1281,7 @@ add_rule_fte(struct fs_fte *fte,
1275 int dest_num, 1281 int dest_num,
1276 bool update_action) 1282 bool update_action)
1277{ 1283{
1284 struct mlx5_flow_root_namespace *root;
1278 struct mlx5_flow_handle *handle; 1285 struct mlx5_flow_handle *handle;
1279 struct mlx5_flow_table *ft; 1286 struct mlx5_flow_table *ft;
1280 int modify_mask = 0; 1287 int modify_mask = 0;
@@ -1290,12 +1297,13 @@ add_rule_fte(struct fs_fte *fte,
1290 modify_mask |= BIT(MLX5_SET_FTE_MODIFY_ENABLE_MASK_ACTION); 1297 modify_mask |= BIT(MLX5_SET_FTE_MODIFY_ENABLE_MASK_ACTION);
1291 1298
1292 fs_get_obj(ft, fg->node.parent); 1299 fs_get_obj(ft, fg->node.parent);
1300 root = find_root(&fg->node);
1293 if (!(fte->status & FS_FTE_STATUS_EXISTING)) 1301 if (!(fte->status & FS_FTE_STATUS_EXISTING))
1294 err = mlx5_cmd_create_fte(get_dev(&ft->node), 1302 err = root->cmds->create_fte(get_dev(&ft->node),
1295 ft, fg->id, fte); 1303 ft, fg, fte);
1296 else 1304 else
1297 err = mlx5_cmd_update_fte(get_dev(&ft->node), 1305 err = root->cmds->update_fte(get_dev(&ft->node), ft, fg->id,
1298 ft, fg->id, modify_mask, fte); 1306 modify_mask, fte);
1299 if (err) 1307 if (err)
1300 goto free_handle; 1308 goto free_handle;
1301 1309
@@ -1360,6 +1368,7 @@ out:
1360static int create_auto_flow_group(struct mlx5_flow_table *ft, 1368static int create_auto_flow_group(struct mlx5_flow_table *ft,
1361 struct mlx5_flow_group *fg) 1369 struct mlx5_flow_group *fg)
1362{ 1370{
1371 struct mlx5_flow_root_namespace *root = find_root(&ft->node);
1363 struct mlx5_core_dev *dev = get_dev(&ft->node); 1372 struct mlx5_core_dev *dev = get_dev(&ft->node);
1364 int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in); 1373 int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
1365 void *match_criteria_addr; 1374 void *match_criteria_addr;
@@ -1380,7 +1389,7 @@ static int create_auto_flow_group(struct mlx5_flow_table *ft,
1380 memcpy(match_criteria_addr, fg->mask.match_criteria, 1389 memcpy(match_criteria_addr, fg->mask.match_criteria,
1381 sizeof(fg->mask.match_criteria)); 1390 sizeof(fg->mask.match_criteria));
1382 1391
1383 err = mlx5_cmd_create_flow_group(dev, ft, in, &fg->id); 1392 err = root->cmds->create_flow_group(dev, ft, in, &fg->id);
1384 if (!err) { 1393 if (!err) {
1385 fg->node.active = true; 1394 fg->node.active = true;
1386 trace_mlx5_fs_add_fg(fg); 1395 trace_mlx5_fs_add_fg(fg);
@@ -1438,16 +1447,17 @@ static bool check_conflicting_actions(u32 action1, u32 action2)
1438 1447
1439static int check_conflicting_ftes(struct fs_fte *fte, const struct mlx5_flow_act *flow_act) 1448static int check_conflicting_ftes(struct fs_fte *fte, const struct mlx5_flow_act *flow_act)
1440{ 1449{
1441 if (check_conflicting_actions(flow_act->action, fte->action)) { 1450 if (check_conflicting_actions(flow_act->action, fte->action.action)) {
1442 mlx5_core_warn(get_dev(&fte->node), 1451 mlx5_core_warn(get_dev(&fte->node),
1443 "Found two FTEs with conflicting actions\n"); 1452 "Found two FTEs with conflicting actions\n");
1444 return -EEXIST; 1453 return -EEXIST;
1445 } 1454 }
1446 1455
1447 if (fte->flow_tag != flow_act->flow_tag) { 1456 if (flow_act->has_flow_tag &&
1457 fte->action.flow_tag != flow_act->flow_tag) {
1448 mlx5_core_warn(get_dev(&fte->node), 1458 mlx5_core_warn(get_dev(&fte->node),
1449 "FTE flow tag %u already exists with different flow tag %u\n", 1459 "FTE flow tag %u already exists with different flow tag %u\n",
1450 fte->flow_tag, 1460 fte->action.flow_tag,
1451 flow_act->flow_tag); 1461 flow_act->flow_tag);
1452 return -EEXIST; 1462 return -EEXIST;
1453 } 1463 }
@@ -1471,12 +1481,12 @@ static struct mlx5_flow_handle *add_rule_fg(struct mlx5_flow_group *fg,
1471 if (ret) 1481 if (ret)
1472 return ERR_PTR(ret); 1482 return ERR_PTR(ret);
1473 1483
1474 old_action = fte->action; 1484 old_action = fte->action.action;
1475 fte->action |= flow_act->action; 1485 fte->action.action |= flow_act->action;
1476 handle = add_rule_fte(fte, fg, dest, dest_num, 1486 handle = add_rule_fte(fte, fg, dest, dest_num,
1477 old_action != flow_act->action); 1487 old_action != flow_act->action);
1478 if (IS_ERR(handle)) { 1488 if (IS_ERR(handle)) {
1479 fte->action = old_action; 1489 fte->action.action = old_action;
1480 return handle; 1490 return handle;
1481 } 1491 }
1482 trace_mlx5_fs_set_fte(fte, false); 1492 trace_mlx5_fs_set_fte(fte, false);
@@ -1637,7 +1647,6 @@ try_add_to_existing_fg(struct mlx5_flow_table *ft,
1637 1647
1638 list_for_each_entry(iter, match_head, list) { 1648 list_for_each_entry(iter, match_head, list) {
1639 nested_down_read_ref_node(&iter->g->node, FS_LOCK_PARENT); 1649 nested_down_read_ref_node(&iter->g->node, FS_LOCK_PARENT);
1640 ida_pre_get(&iter->g->fte_allocator, GFP_KERNEL);
1641 } 1650 }
1642 1651
1643search_again_locked: 1652search_again_locked:
@@ -1919,7 +1928,6 @@ static int update_root_ft_destroy(struct mlx5_flow_table *ft)
1919 return 0; 1928 return 0;
1920 1929
1921 new_root_ft = find_next_ft(ft); 1930 new_root_ft = find_next_ft(ft);
1922
1923 if (!new_root_ft) { 1931 if (!new_root_ft) {
1924 root->root_ft = NULL; 1932 root->root_ft = NULL;
1925 return 0; 1933 return 0;
@@ -1928,13 +1936,14 @@ static int update_root_ft_destroy(struct mlx5_flow_table *ft)
1928 if (list_empty(&root->underlay_qpns)) { 1936 if (list_empty(&root->underlay_qpns)) {
1929 /* Don't set any QPN (zero) in case QPN list is empty */ 1937 /* Don't set any QPN (zero) in case QPN list is empty */
1930 qpn = 0; 1938 qpn = 0;
1931 err = mlx5_cmd_update_root_ft(root->dev, new_root_ft, qpn, 1939 err = root->cmds->update_root_ft(root->dev, new_root_ft,
1932 false); 1940 qpn, false);
1933 } else { 1941 } else {
1934 list_for_each_entry(uqp, &root->underlay_qpns, list) { 1942 list_for_each_entry(uqp, &root->underlay_qpns, list) {
1935 qpn = uqp->qpn; 1943 qpn = uqp->qpn;
1936 err = mlx5_cmd_update_root_ft(root->dev, new_root_ft, 1944 err = root->cmds->update_root_ft(root->dev,
1937 qpn, false); 1945 new_root_ft, qpn,
1946 false);
1938 if (err) 1947 if (err)
1939 break; 1948 break;
1940 } 1949 }
@@ -2046,6 +2055,11 @@ struct mlx5_flow_namespace *mlx5_get_flow_namespace(struct mlx5_core_dev *dev,
2046 return &steering->sniffer_tx_root_ns->ns; 2055 return &steering->sniffer_tx_root_ns->ns;
2047 else 2056 else
2048 return NULL; 2057 return NULL;
2058 case MLX5_FLOW_NAMESPACE_EGRESS:
2059 if (steering->egress_root_ns)
2060 return &steering->egress_root_ns->ns;
2061 else
2062 return NULL;
2049 default: 2063 default:
2050 return NULL; 2064 return NULL;
2051 } 2065 }
@@ -2236,13 +2250,18 @@ static int init_root_tree(struct mlx5_flow_steering *steering,
2236 return 0; 2250 return 0;
2237} 2251}
2238 2252
2239static struct mlx5_flow_root_namespace *create_root_ns(struct mlx5_flow_steering *steering, 2253static struct mlx5_flow_root_namespace
2240 enum fs_flow_table_type 2254*create_root_ns(struct mlx5_flow_steering *steering,
2241 table_type) 2255 enum fs_flow_table_type table_type)
2242{ 2256{
2257 const struct mlx5_flow_cmds *cmds = mlx5_fs_cmd_get_default(table_type);
2243 struct mlx5_flow_root_namespace *root_ns; 2258 struct mlx5_flow_root_namespace *root_ns;
2244 struct mlx5_flow_namespace *ns; 2259 struct mlx5_flow_namespace *ns;
2245 2260
2261 if (mlx5_accel_ipsec_device_caps(steering->dev) & MLX5_ACCEL_IPSEC_CAP_DEVICE &&
2262 (table_type == FS_FT_NIC_RX || table_type == FS_FT_NIC_TX))
2263 cmds = mlx5_fs_cmd_get_default_ipsec_fpga_cmds(table_type);
2264
2246 /* Create the root namespace */ 2265 /* Create the root namespace */
2247 root_ns = kvzalloc(sizeof(*root_ns), GFP_KERNEL); 2266 root_ns = kvzalloc(sizeof(*root_ns), GFP_KERNEL);
2248 if (!root_ns) 2267 if (!root_ns)
@@ -2250,6 +2269,7 @@ static struct mlx5_flow_root_namespace *create_root_ns(struct mlx5_flow_steering
2250 2269
2251 root_ns->dev = steering->dev; 2270 root_ns->dev = steering->dev;
2252 root_ns->table_type = table_type; 2271 root_ns->table_type = table_type;
2272 root_ns->cmds = cmds;
2253 2273
2254 INIT_LIST_HEAD(&root_ns->underlay_qpns); 2274 INIT_LIST_HEAD(&root_ns->underlay_qpns);
2255 2275
@@ -2408,6 +2428,7 @@ void mlx5_cleanup_fs(struct mlx5_core_dev *dev)
2408 cleanup_root_ns(steering->fdb_root_ns); 2428 cleanup_root_ns(steering->fdb_root_ns);
2409 cleanup_root_ns(steering->sniffer_rx_root_ns); 2429 cleanup_root_ns(steering->sniffer_rx_root_ns);
2410 cleanup_root_ns(steering->sniffer_tx_root_ns); 2430 cleanup_root_ns(steering->sniffer_tx_root_ns);
2431 cleanup_root_ns(steering->egress_root_ns);
2411 mlx5_cleanup_fc_stats(dev); 2432 mlx5_cleanup_fc_stats(dev);
2412 kmem_cache_destroy(steering->ftes_cache); 2433 kmem_cache_destroy(steering->ftes_cache);
2413 kmem_cache_destroy(steering->fgs_cache); 2434 kmem_cache_destroy(steering->fgs_cache);
@@ -2553,6 +2574,20 @@ cleanup_root_ns:
2553 return err; 2574 return err;
2554} 2575}
2555 2576
2577static int init_egress_root_ns(struct mlx5_flow_steering *steering)
2578{
2579 struct fs_prio *prio;
2580
2581 steering->egress_root_ns = create_root_ns(steering,
2582 FS_FT_NIC_TX);
2583 if (!steering->egress_root_ns)
2584 return -ENOMEM;
2585
2586 /* create 1 prio*/
2587 prio = fs_create_prio(&steering->egress_root_ns->ns, 0, 1);
2588 return PTR_ERR_OR_ZERO(prio);
2589}
2590
2556int mlx5_init_fs(struct mlx5_core_dev *dev) 2591int mlx5_init_fs(struct mlx5_core_dev *dev)
2557{ 2592{
2558 struct mlx5_flow_steering *steering; 2593 struct mlx5_flow_steering *steering;
@@ -2618,6 +2653,12 @@ int mlx5_init_fs(struct mlx5_core_dev *dev)
2618 goto err; 2653 goto err;
2619 } 2654 }
2620 2655
2656 if (MLX5_IPSEC_DEV(dev)) {
2657 err = init_egress_root_ns(steering);
2658 if (err)
2659 goto err;
2660 }
2661
2621 return 0; 2662 return 0;
2622err: 2663err:
2623 mlx5_cleanup_fs(dev); 2664 mlx5_cleanup_fs(dev);
@@ -2641,7 +2682,8 @@ int mlx5_fs_add_rx_underlay_qpn(struct mlx5_core_dev *dev, u32 underlay_qpn)
2641 goto update_ft_fail; 2682 goto update_ft_fail;
2642 } 2683 }
2643 2684
2644 err = mlx5_cmd_update_root_ft(dev, root->root_ft, underlay_qpn, false); 2685 err = root->cmds->update_root_ft(dev, root->root_ft, underlay_qpn,
2686 false);
2645 if (err) { 2687 if (err) {
2646 mlx5_core_warn(dev, "Failed adding underlay QPN (%u) to root FT err(%d)\n", 2688 mlx5_core_warn(dev, "Failed adding underlay QPN (%u) to root FT err(%d)\n",
2647 underlay_qpn, err); 2689 underlay_qpn, err);
@@ -2684,7 +2726,8 @@ int mlx5_fs_remove_rx_underlay_qpn(struct mlx5_core_dev *dev, u32 underlay_qpn)
2684 goto out; 2726 goto out;
2685 } 2727 }
2686 2728
2687 err = mlx5_cmd_update_root_ft(dev, root->root_ft, underlay_qpn, true); 2729 err = root->cmds->update_root_ft(dev, root->root_ft, underlay_qpn,
2730 true);
2688 if (err) 2731 if (err)
2689 mlx5_core_warn(dev, "Failed removing underlay QPN (%u) from root FT err(%d)\n", 2732 mlx5_core_warn(dev, "Failed removing underlay QPN (%u) from root FT err(%d)\n",
2690 underlay_qpn, err); 2733 underlay_qpn, err);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.h b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.h
index 05262708f14b..e26d3e9d5f9f 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.h
@@ -48,6 +48,7 @@ enum fs_node_type {
48 48
49enum fs_flow_table_type { 49enum fs_flow_table_type {
50 FS_FT_NIC_RX = 0x0, 50 FS_FT_NIC_RX = 0x0,
51 FS_FT_NIC_TX = 0x1,
51 FS_FT_ESW_EGRESS_ACL = 0x2, 52 FS_FT_ESW_EGRESS_ACL = 0x2,
52 FS_FT_ESW_INGRESS_ACL = 0x3, 53 FS_FT_ESW_INGRESS_ACL = 0x3,
53 FS_FT_FDB = 0X4, 54 FS_FT_FDB = 0X4,
@@ -75,6 +76,7 @@ struct mlx5_flow_steering {
75 struct mlx5_flow_root_namespace **esw_ingress_root_ns; 76 struct mlx5_flow_root_namespace **esw_ingress_root_ns;
76 struct mlx5_flow_root_namespace *sniffer_tx_root_ns; 77 struct mlx5_flow_root_namespace *sniffer_tx_root_ns;
77 struct mlx5_flow_root_namespace *sniffer_rx_root_ns; 78 struct mlx5_flow_root_namespace *sniffer_rx_root_ns;
79 struct mlx5_flow_root_namespace *egress_root_ns;
78}; 80};
79 81
80struct fs_node { 82struct fs_node {
@@ -174,11 +176,8 @@ struct fs_fte {
174 struct fs_node node; 176 struct fs_node node;
175 u32 val[MLX5_ST_SZ_DW_MATCH_PARAM]; 177 u32 val[MLX5_ST_SZ_DW_MATCH_PARAM];
176 u32 dests_size; 178 u32 dests_size;
177 u32 flow_tag;
178 u32 index; 179 u32 index;
179 u32 action; 180 struct mlx5_flow_act action;
180 u32 encap_id;
181 u32 modify_id;
182 enum fs_fte_status status; 181 enum fs_fte_status status;
183 struct mlx5_fc *counter; 182 struct mlx5_fc *counter;
184 struct rhash_head hash; 183 struct rhash_head hash;
@@ -224,6 +223,7 @@ struct mlx5_flow_root_namespace {
224 /* Should be held when chaining flow tables */ 223 /* Should be held when chaining flow tables */
225 struct mutex chain_lock; 224 struct mutex chain_lock;
226 struct list_head underlay_qpns; 225 struct list_head underlay_qpns;
226 const struct mlx5_flow_cmds *cmds;
227}; 227};
228 228
229int mlx5_init_fc_stats(struct mlx5_core_dev *dev); 229int mlx5_init_fc_stats(struct mlx5_core_dev *dev);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
index ae391e4b7070..13b6f66310c9 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
@@ -58,6 +58,7 @@
58#include "eswitch.h" 58#include "eswitch.h"
59#include "lib/mlx5.h" 59#include "lib/mlx5.h"
60#include "fpga/core.h" 60#include "fpga/core.h"
61#include "fpga/ipsec.h"
61#include "accel/ipsec.h" 62#include "accel/ipsec.h"
62#include "lib/clock.h" 63#include "lib/clock.h"
63 64
@@ -942,9 +943,9 @@ static int mlx5_init_once(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
942 goto out; 943 goto out;
943 } 944 }
944 945
945 err = mlx5_init_cq_table(dev); 946 err = mlx5_cq_debugfs_init(dev);
946 if (err) { 947 if (err) {
947 dev_err(&pdev->dev, "failed to initialize cq table\n"); 948 dev_err(&pdev->dev, "failed to initialize cq debugfs\n");
948 goto err_eq_cleanup; 949 goto err_eq_cleanup;
949 } 950 }
950 951
@@ -1002,7 +1003,7 @@ err_tables_cleanup:
1002 mlx5_cleanup_mkey_table(dev); 1003 mlx5_cleanup_mkey_table(dev);
1003 mlx5_cleanup_srq_table(dev); 1004 mlx5_cleanup_srq_table(dev);
1004 mlx5_cleanup_qp_table(dev); 1005 mlx5_cleanup_qp_table(dev);
1005 mlx5_cleanup_cq_table(dev); 1006 mlx5_cq_debugfs_cleanup(dev);
1006 1007
1007err_eq_cleanup: 1008err_eq_cleanup:
1008 mlx5_eq_cleanup(dev); 1009 mlx5_eq_cleanup(dev);
@@ -1023,7 +1024,7 @@ static void mlx5_cleanup_once(struct mlx5_core_dev *dev)
1023 mlx5_cleanup_mkey_table(dev); 1024 mlx5_cleanup_mkey_table(dev);
1024 mlx5_cleanup_srq_table(dev); 1025 mlx5_cleanup_srq_table(dev);
1025 mlx5_cleanup_qp_table(dev); 1026 mlx5_cleanup_qp_table(dev);
1026 mlx5_cleanup_cq_table(dev); 1027 mlx5_cq_debugfs_cleanup(dev);
1027 mlx5_eq_cleanup(dev); 1028 mlx5_eq_cleanup(dev);
1028} 1029}
1029 1030
@@ -1173,6 +1174,18 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
1173 goto err_affinity_hints; 1174 goto err_affinity_hints;
1174 } 1175 }
1175 1176
1177 err = mlx5_fpga_device_start(dev);
1178 if (err) {
1179 dev_err(&pdev->dev, "fpga device start failed %d\n", err);
1180 goto err_fpga_start;
1181 }
1182
1183 err = mlx5_accel_ipsec_init(dev);
1184 if (err) {
1185 dev_err(&pdev->dev, "IPSec device start failed %d\n", err);
1186 goto err_ipsec_start;
1187 }
1188
1176 err = mlx5_init_fs(dev); 1189 err = mlx5_init_fs(dev);
1177 if (err) { 1190 if (err) {
1178 dev_err(&pdev->dev, "Failed to init flow steering\n"); 1191 dev_err(&pdev->dev, "Failed to init flow steering\n");
@@ -1191,17 +1204,6 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
1191 goto err_sriov; 1204 goto err_sriov;
1192 } 1205 }
1193 1206
1194 err = mlx5_fpga_device_start(dev);
1195 if (err) {
1196 dev_err(&pdev->dev, "fpga device start failed %d\n", err);
1197 goto err_fpga_start;
1198 }
1199 err = mlx5_accel_ipsec_init(dev);
1200 if (err) {
1201 dev_err(&pdev->dev, "IPSec device start failed %d\n", err);
1202 goto err_ipsec_start;
1203 }
1204
1205 if (mlx5_device_registered(dev)) { 1207 if (mlx5_device_registered(dev)) {
1206 mlx5_attach_device(dev); 1208 mlx5_attach_device(dev);
1207 } else { 1209 } else {
@@ -1219,17 +1221,18 @@ out:
1219 return 0; 1221 return 0;
1220 1222
1221err_reg_dev: 1223err_reg_dev:
1222 mlx5_accel_ipsec_cleanup(dev);
1223err_ipsec_start:
1224 mlx5_fpga_device_stop(dev);
1225
1226err_fpga_start:
1227 mlx5_sriov_detach(dev); 1224 mlx5_sriov_detach(dev);
1228 1225
1229err_sriov: 1226err_sriov:
1230 mlx5_cleanup_fs(dev); 1227 mlx5_cleanup_fs(dev);
1231 1228
1232err_fs: 1229err_fs:
1230 mlx5_accel_ipsec_cleanup(dev);
1231
1232err_ipsec_start:
1233 mlx5_fpga_device_stop(dev);
1234
1235err_fpga_start:
1233 mlx5_irq_clear_affinity_hints(dev); 1236 mlx5_irq_clear_affinity_hints(dev);
1234 1237
1235err_affinity_hints: 1238err_affinity_hints:
@@ -1296,11 +1299,10 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
1296 if (mlx5_device_registered(dev)) 1299 if (mlx5_device_registered(dev))
1297 mlx5_detach_device(dev); 1300 mlx5_detach_device(dev);
1298 1301
1299 mlx5_accel_ipsec_cleanup(dev);
1300 mlx5_fpga_device_stop(dev);
1301
1302 mlx5_sriov_detach(dev); 1302 mlx5_sriov_detach(dev);
1303 mlx5_cleanup_fs(dev); 1303 mlx5_cleanup_fs(dev);
1304 mlx5_accel_ipsec_cleanup(dev);
1305 mlx5_fpga_device_stop(dev);
1304 mlx5_irq_clear_affinity_hints(dev); 1306 mlx5_irq_clear_affinity_hints(dev);
1305 free_comp_eqs(dev); 1307 free_comp_eqs(dev);
1306 mlx5_stop_eqs(dev); 1308 mlx5_stop_eqs(dev);
@@ -1657,6 +1659,7 @@ static int __init init(void)
1657 get_random_bytes(&sw_owner_id, sizeof(sw_owner_id)); 1659 get_random_bytes(&sw_owner_id, sizeof(sw_owner_id));
1658 1660
1659 mlx5_core_verify_params(); 1661 mlx5_core_verify_params();
1662 mlx5_fpga_ipsec_build_fs_cmds();
1660 mlx5_register_debugfs(); 1663 mlx5_register_debugfs();
1661 1664
1662 err = pci_register_driver(&mlx5_core_driver); 1665 err = pci_register_driver(&mlx5_core_driver);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
index 394552f36fcf..4e25f2b2e0bc 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
@@ -38,16 +38,11 @@
38#include <linux/sched.h> 38#include <linux/sched.h>
39#include <linux/if_link.h> 39#include <linux/if_link.h>
40#include <linux/firmware.h> 40#include <linux/firmware.h>
41#include <linux/mlx5/cq.h>
41 42
42#define DRIVER_NAME "mlx5_core" 43#define DRIVER_NAME "mlx5_core"
43#define DRIVER_VERSION "5.0-0" 44#define DRIVER_VERSION "5.0-0"
44 45
45#define MLX5_TOTAL_VPORTS(mdev) (1 + pci_sriov_get_totalvfs(mdev->pdev))
46#define MLX5_VPORT_MANAGER(mdev) \
47 (MLX5_CAP_GEN(mdev, vport_group_manager) && \
48 (MLX5_CAP_GEN(mdev, port_type) == MLX5_CAP_PORT_TYPE_ETH) && \
49 mlx5_core_is_pf(mdev))
50
51extern uint mlx5_core_debug_mask; 46extern uint mlx5_core_debug_mask;
52 47
53#define mlx5_core_dbg(__dev, format, ...) \ 48#define mlx5_core_dbg(__dev, format, ...) \
@@ -115,9 +110,29 @@ int mlx5_destroy_scheduling_element_cmd(struct mlx5_core_dev *dev, u8 hierarchy,
115 u32 element_id); 110 u32 element_id);
116int mlx5_wait_for_vf_pages(struct mlx5_core_dev *dev); 111int mlx5_wait_for_vf_pages(struct mlx5_core_dev *dev);
117u64 mlx5_read_internal_timer(struct mlx5_core_dev *dev); 112u64 mlx5_read_internal_timer(struct mlx5_core_dev *dev);
113
114int mlx5_eq_init(struct mlx5_core_dev *dev);
115void mlx5_eq_cleanup(struct mlx5_core_dev *dev);
116int mlx5_create_map_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq, u8 vecidx,
117 int nent, u64 mask, const char *name,
118 enum mlx5_eq_type type);
119int mlx5_destroy_unmap_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq);
120int mlx5_eq_add_cq(struct mlx5_eq *eq, struct mlx5_core_cq *cq);
121int mlx5_eq_del_cq(struct mlx5_eq *eq, struct mlx5_core_cq *cq);
122int mlx5_core_eq_query(struct mlx5_core_dev *dev, struct mlx5_eq *eq,
123 u32 *out, int outlen);
124int mlx5_start_eqs(struct mlx5_core_dev *dev);
125void mlx5_stop_eqs(struct mlx5_core_dev *dev);
118struct mlx5_eq *mlx5_eqn2eq(struct mlx5_core_dev *dev, int eqn); 126struct mlx5_eq *mlx5_eqn2eq(struct mlx5_core_dev *dev, int eqn);
119u32 mlx5_eq_poll_irq_disabled(struct mlx5_eq *eq); 127u32 mlx5_eq_poll_irq_disabled(struct mlx5_eq *eq);
120void mlx5_cq_tasklet_cb(unsigned long data); 128void mlx5_cq_tasklet_cb(unsigned long data);
129void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool forced);
130int mlx5_debug_eq_add(struct mlx5_core_dev *dev, struct mlx5_eq *eq);
131void mlx5_debug_eq_remove(struct mlx5_core_dev *dev, struct mlx5_eq *eq);
132int mlx5_eq_debugfs_init(struct mlx5_core_dev *dev);
133void mlx5_eq_debugfs_cleanup(struct mlx5_core_dev *dev);
134int mlx5_cq_debugfs_init(struct mlx5_core_dev *dev);
135void mlx5_cq_debugfs_cleanup(struct mlx5_core_dev *dev);
121 136
122int mlx5_query_pcam_reg(struct mlx5_core_dev *dev, u32 *pcam, u8 feature_group, 137int mlx5_query_pcam_reg(struct mlx5_core_dev *dev, u32 *pcam, u8 feature_group,
123 u8 access_reg_group); 138 u8 access_reg_group);
@@ -186,4 +201,5 @@ static inline int mlx5_lag_is_lacp_owner(struct mlx5_core_dev *dev)
186int mlx5_lag_allow(struct mlx5_core_dev *dev); 201int mlx5_lag_allow(struct mlx5_core_dev *dev);
187int mlx5_lag_forbid(struct mlx5_core_dev *dev); 202int mlx5_lag_forbid(struct mlx5_core_dev *dev);
188 203
204void mlx5_reload_interface(struct mlx5_core_dev *mdev, int protocol);
189#endif /* __MLX5_CORE_H__ */ 205#endif /* __MLX5_CORE_H__ */
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/wq.c b/drivers/net/ethernet/mellanox/mlx5/core/wq.c
index 6bcfc25350f5..ea66448ba365 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/wq.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/wq.c
@@ -41,7 +41,7 @@ u32 mlx5_wq_cyc_get_size(struct mlx5_wq_cyc *wq)
41 41
42u32 mlx5_cqwq_get_size(struct mlx5_cqwq *wq) 42u32 mlx5_cqwq_get_size(struct mlx5_cqwq *wq)
43{ 43{
44 return wq->sz_m1 + 1; 44 return wq->fbc.sz_m1 + 1;
45} 45}
46 46
47u32 mlx5_wq_ll_get_size(struct mlx5_wq_ll *wq) 47u32 mlx5_wq_ll_get_size(struct mlx5_wq_ll *wq)
@@ -62,7 +62,7 @@ static u32 mlx5_wq_qp_get_byte_size(struct mlx5_wq_qp *wq)
62 62
63static u32 mlx5_cqwq_get_byte_size(struct mlx5_cqwq *wq) 63static u32 mlx5_cqwq_get_byte_size(struct mlx5_cqwq *wq)
64{ 64{
65 return mlx5_cqwq_get_size(wq) << wq->log_stride; 65 return mlx5_cqwq_get_size(wq) << wq->fbc.log_stride;
66} 66}
67 67
68static u32 mlx5_wq_ll_get_byte_size(struct mlx5_wq_ll *wq) 68static u32 mlx5_wq_ll_get_byte_size(struct mlx5_wq_ll *wq)
@@ -92,7 +92,7 @@ int mlx5_wq_cyc_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,
92 goto err_db_free; 92 goto err_db_free;
93 } 93 }
94 94
95 wq->buf = wq_ctrl->buf.direct.buf; 95 wq->buf = wq_ctrl->buf.frags->buf;
96 wq->db = wq_ctrl->db.db; 96 wq->db = wq_ctrl->db.db;
97 97
98 wq_ctrl->mdev = mdev; 98 wq_ctrl->mdev = mdev;
@@ -130,7 +130,7 @@ int mlx5_wq_qp_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,
130 goto err_db_free; 130 goto err_db_free;
131 } 131 }
132 132
133 wq->rq.buf = wq_ctrl->buf.direct.buf; 133 wq->rq.buf = wq_ctrl->buf.frags->buf;
134 wq->sq.buf = wq->rq.buf + mlx5_wq_cyc_get_byte_size(&wq->rq); 134 wq->sq.buf = wq->rq.buf + mlx5_wq_cyc_get_byte_size(&wq->rq);
135 wq->rq.db = &wq_ctrl->db.db[MLX5_RCV_DBR]; 135 wq->rq.db = &wq_ctrl->db.db[MLX5_RCV_DBR];
136 wq->sq.db = &wq_ctrl->db.db[MLX5_SND_DBR]; 136 wq->sq.db = &wq_ctrl->db.db[MLX5_SND_DBR];
@@ -151,11 +151,7 @@ int mlx5_cqwq_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,
151{ 151{
152 int err; 152 int err;
153 153
154 wq->log_stride = 6 + MLX5_GET(cqc, cqc, cqe_sz); 154 mlx5_core_init_cq_frag_buf(&wq->fbc, cqc);
155 wq->log_sz = MLX5_GET(cqc, cqc, log_cq_size);
156 wq->sz_m1 = (1 << wq->log_sz) - 1;
157 wq->log_frag_strides = PAGE_SHIFT - wq->log_stride;
158 wq->frag_sz_m1 = (1 << wq->log_frag_strides) - 1;
159 155
160 err = mlx5_db_alloc_node(mdev, &wq_ctrl->db, param->db_numa_node); 156 err = mlx5_db_alloc_node(mdev, &wq_ctrl->db, param->db_numa_node);
161 if (err) { 157 if (err) {
@@ -172,7 +168,7 @@ int mlx5_cqwq_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,
172 goto err_db_free; 168 goto err_db_free;
173 } 169 }
174 170
175 wq->frag_buf = wq_ctrl->frag_buf; 171 wq->fbc.frag_buf = wq_ctrl->frag_buf;
176 wq->db = wq_ctrl->db.db; 172 wq->db = wq_ctrl->db.db;
177 173
178 wq_ctrl->mdev = mdev; 174 wq_ctrl->mdev = mdev;
@@ -209,7 +205,7 @@ int mlx5_wq_ll_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,
209 goto err_db_free; 205 goto err_db_free;
210 } 206 }
211 207
212 wq->buf = wq_ctrl->buf.direct.buf; 208 wq->buf = wq_ctrl->buf.frags->buf;
213 wq->db = wq_ctrl->db.db; 209 wq->db = wq_ctrl->db.db;
214 210
215 for (i = 0; i < wq->sz_m1; i++) { 211 for (i = 0; i < wq->sz_m1; i++) {
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/wq.h b/drivers/net/ethernet/mellanox/mlx5/core/wq.h
index 718589d0cec2..fca90b94596d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/wq.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/wq.h
@@ -45,7 +45,7 @@ struct mlx5_wq_param {
45 45
46struct mlx5_wq_ctrl { 46struct mlx5_wq_ctrl {
47 struct mlx5_core_dev *mdev; 47 struct mlx5_core_dev *mdev;
48 struct mlx5_buf buf; 48 struct mlx5_frag_buf buf;
49 struct mlx5_db db; 49 struct mlx5_db db;
50}; 50};
51 51
@@ -68,14 +68,9 @@ struct mlx5_wq_qp {
68}; 68};
69 69
70struct mlx5_cqwq { 70struct mlx5_cqwq {
71 struct mlx5_frag_buf frag_buf; 71 struct mlx5_frag_buf_ctrl fbc;
72 __be32 *db; 72 __be32 *db;
73 u32 sz_m1; 73 u32 cc; /* consumer counter */
74 u32 frag_sz_m1;
75 u32 cc; /* consumer counter */
76 u8 log_sz;
77 u8 log_stride;
78 u8 log_frag_strides;
79}; 74};
80 75
81struct mlx5_wq_ll { 76struct mlx5_wq_ll {
@@ -131,20 +126,17 @@ static inline int mlx5_wq_cyc_cc_bigger(u16 cc1, u16 cc2)
131 126
132static inline u32 mlx5_cqwq_get_ci(struct mlx5_cqwq *wq) 127static inline u32 mlx5_cqwq_get_ci(struct mlx5_cqwq *wq)
133{ 128{
134 return wq->cc & wq->sz_m1; 129 return wq->cc & wq->fbc.sz_m1;
135} 130}
136 131
137static inline void *mlx5_cqwq_get_wqe(struct mlx5_cqwq *wq, u32 ix) 132static inline void *mlx5_cqwq_get_wqe(struct mlx5_cqwq *wq, u32 ix)
138{ 133{
139 unsigned int frag = (ix >> wq->log_frag_strides); 134 return mlx5_frag_buf_get_wqe(&wq->fbc, ix);
140
141 return wq->frag_buf.frags[frag].buf +
142 ((wq->frag_sz_m1 & ix) << wq->log_stride);
143} 135}
144 136
145static inline u32 mlx5_cqwq_get_wrap_cnt(struct mlx5_cqwq *wq) 137static inline u32 mlx5_cqwq_get_wrap_cnt(struct mlx5_cqwq *wq)
146{ 138{
147 return wq->cc >> wq->log_sz; 139 return wq->cc >> wq->fbc.log_sz;
148} 140}
149 141
150static inline void mlx5_cqwq_pop(struct mlx5_cqwq *wq) 142static inline void mlx5_cqwq_pop(struct mlx5_cqwq *wq)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/Kconfig b/drivers/net/ethernet/mellanox/mlxsw/Kconfig
index d56eea310509..f4d9c9975ac3 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/Kconfig
+++ b/drivers/net/ethernet/mellanox/mlxsw/Kconfig
@@ -76,6 +76,8 @@ config MLXSW_SPECTRUM
76 depends on PSAMPLE || PSAMPLE=n 76 depends on PSAMPLE || PSAMPLE=n
77 depends on BRIDGE || BRIDGE=n 77 depends on BRIDGE || BRIDGE=n
78 depends on IPV6 || IPV6=n 78 depends on IPV6 || IPV6=n
79 depends on NET_IPGRE || NET_IPGRE=n
80 depends on IPV6_GRE || IPV6_GRE=n
79 select PARMAN 81 select PARMAN
80 select MLXFW 82 select MLXFW
81 default m 83 default m
diff --git a/drivers/net/ethernet/mellanox/mlxsw/Makefile b/drivers/net/ethernet/mellanox/mlxsw/Makefile
index 9463c3fa254f..0cadcabfe86f 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/Makefile
+++ b/drivers/net/ethernet/mellanox/mlxsw/Makefile
@@ -20,7 +20,7 @@ mlxsw_spectrum-objs := spectrum.o spectrum_buffers.o \
20 spectrum_cnt.o spectrum_fid.o \ 20 spectrum_cnt.o spectrum_fid.o \
21 spectrum_ipip.o spectrum_acl_flex_actions.o \ 21 spectrum_ipip.o spectrum_acl_flex_actions.o \
22 spectrum_mr.o spectrum_mr_tcam.o \ 22 spectrum_mr.o spectrum_mr_tcam.o \
23 spectrum_qdisc.o 23 spectrum_qdisc.o spectrum_span.o
24mlxsw_spectrum-$(CONFIG_MLXSW_SPECTRUM_DCB) += spectrum_dcb.o 24mlxsw_spectrum-$(CONFIG_MLXSW_SPECTRUM_DCB) += spectrum_dcb.o
25mlxsw_spectrum-$(CONFIG_NET_DEVLINK) += spectrum_dpipe.o 25mlxsw_spectrum-$(CONFIG_NET_DEVLINK) += spectrum_dpipe.o
26obj-$(CONFIG_MLXSW_MINIMAL) += mlxsw_minimal.o 26obj-$(CONFIG_MLXSW_MINIMAL) += mlxsw_minimal.o
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c b/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c
index 996dc099cd58..3c0d882ba183 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c 2 * drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c
3 * Copyright (c) 2017 Mellanox Technologies. All rights reserved. 3 * Copyright (c) 2017, 2018 Mellanox Technologies. All rights reserved.
4 * Copyright (c) 2017 Jiri Pirko <jiri@mellanox.com> 4 * Copyright (c) 2017 Jiri Pirko <jiri@mellanox.com>
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
@@ -849,7 +849,6 @@ struct mlxsw_afa_mirror {
849 struct mlxsw_afa_resource resource; 849 struct mlxsw_afa_resource resource;
850 int span_id; 850 int span_id;
851 u8 local_in_port; 851 u8 local_in_port;
852 u8 local_out_port;
853 bool ingress; 852 bool ingress;
854}; 853};
855 854
@@ -859,7 +858,7 @@ mlxsw_afa_mirror_destroy(struct mlxsw_afa_block *block,
859{ 858{
860 block->afa->ops->mirror_del(block->afa->ops_priv, 859 block->afa->ops->mirror_del(block->afa->ops_priv,
861 mirror->local_in_port, 860 mirror->local_in_port,
862 mirror->local_out_port, 861 mirror->span_id,
863 mirror->ingress); 862 mirror->ingress);
864 kfree(mirror); 863 kfree(mirror);
865} 864}
@@ -875,9 +874,8 @@ mlxsw_afa_mirror_destructor(struct mlxsw_afa_block *block,
875} 874}
876 875
877static struct mlxsw_afa_mirror * 876static struct mlxsw_afa_mirror *
878mlxsw_afa_mirror_create(struct mlxsw_afa_block *block, 877mlxsw_afa_mirror_create(struct mlxsw_afa_block *block, u8 local_in_port,
879 u8 local_in_port, u8 local_out_port, 878 const struct net_device *out_dev, bool ingress)
880 bool ingress)
881{ 879{
882 struct mlxsw_afa_mirror *mirror; 880 struct mlxsw_afa_mirror *mirror;
883 int err; 881 int err;
@@ -887,13 +885,12 @@ mlxsw_afa_mirror_create(struct mlxsw_afa_block *block,
887 return ERR_PTR(-ENOMEM); 885 return ERR_PTR(-ENOMEM);
888 886
889 err = block->afa->ops->mirror_add(block->afa->ops_priv, 887 err = block->afa->ops->mirror_add(block->afa->ops_priv,
890 local_in_port, local_out_port, 888 local_in_port, out_dev,
891 ingress, &mirror->span_id); 889 ingress, &mirror->span_id);
892 if (err) 890 if (err)
893 goto err_mirror_add; 891 goto err_mirror_add;
894 892
895 mirror->ingress = ingress; 893 mirror->ingress = ingress;
896 mirror->local_out_port = local_out_port;
897 mirror->local_in_port = local_in_port; 894 mirror->local_in_port = local_in_port;
898 mirror->resource.destructor = mlxsw_afa_mirror_destructor; 895 mirror->resource.destructor = mlxsw_afa_mirror_destructor;
899 mlxsw_afa_resource_add(block, &mirror->resource); 896 mlxsw_afa_resource_add(block, &mirror->resource);
@@ -920,13 +917,13 @@ mlxsw_afa_block_append_allocated_mirror(struct mlxsw_afa_block *block,
920} 917}
921 918
922int 919int
923mlxsw_afa_block_append_mirror(struct mlxsw_afa_block *block, 920mlxsw_afa_block_append_mirror(struct mlxsw_afa_block *block, u8 local_in_port,
924 u8 local_in_port, u8 local_out_port, bool ingress) 921 const struct net_device *out_dev, bool ingress)
925{ 922{
926 struct mlxsw_afa_mirror *mirror; 923 struct mlxsw_afa_mirror *mirror;
927 int err; 924 int err;
928 925
929 mirror = mlxsw_afa_mirror_create(block, local_in_port, local_out_port, 926 mirror = mlxsw_afa_mirror_create(block, local_in_port, out_dev,
930 ingress); 927 ingress);
931 if (IS_ERR(mirror)) 928 if (IS_ERR(mirror))
932 return PTR_ERR(mirror); 929 return PTR_ERR(mirror);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.h b/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.h
index b91f2b0829b0..3a155d104384 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.h
@@ -36,6 +36,7 @@
36#define _MLXSW_CORE_ACL_FLEX_ACTIONS_H 36#define _MLXSW_CORE_ACL_FLEX_ACTIONS_H
37 37
38#include <linux/types.h> 38#include <linux/types.h>
39#include <linux/netdevice.h>
39 40
40struct mlxsw_afa; 41struct mlxsw_afa;
41struct mlxsw_afa_block; 42struct mlxsw_afa_block;
@@ -48,9 +49,10 @@ struct mlxsw_afa_ops {
48 void (*kvdl_fwd_entry_del)(void *priv, u32 kvdl_index); 49 void (*kvdl_fwd_entry_del)(void *priv, u32 kvdl_index);
49 int (*counter_index_get)(void *priv, unsigned int *p_counter_index); 50 int (*counter_index_get)(void *priv, unsigned int *p_counter_index);
50 void (*counter_index_put)(void *priv, unsigned int counter_index); 51 void (*counter_index_put)(void *priv, unsigned int counter_index);
51 int (*mirror_add)(void *priv, u8 locol_in_port, u8 local_out_port, 52 int (*mirror_add)(void *priv, u8 local_in_port,
53 const struct net_device *out_dev,
52 bool ingress, int *p_span_id); 54 bool ingress, int *p_span_id);
53 void (*mirror_del)(void *priv, u8 locol_in_port, u8 local_out_port, 55 void (*mirror_del)(void *priv, u8 local_in_port, int span_id,
54 bool ingress); 56 bool ingress);
55}; 57};
56 58
@@ -71,7 +73,8 @@ int mlxsw_afa_block_append_trap(struct mlxsw_afa_block *block, u16 trap_id);
71int mlxsw_afa_block_append_trap_and_forward(struct mlxsw_afa_block *block, 73int mlxsw_afa_block_append_trap_and_forward(struct mlxsw_afa_block *block,
72 u16 trap_id); 74 u16 trap_id);
73int mlxsw_afa_block_append_mirror(struct mlxsw_afa_block *block, 75int mlxsw_afa_block_append_mirror(struct mlxsw_afa_block *block,
74 u8 local_in_port, u8 local_out_port, 76 u8 local_in_port,
77 const struct net_device *out_dev,
75 bool ingress); 78 bool ingress);
76int mlxsw_afa_block_append_fwd(struct mlxsw_afa_block *block, 79int mlxsw_afa_block_append_fwd(struct mlxsw_afa_block *block,
77 u8 local_port, bool in_port); 80 u8 local_port, bool in_port);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci.c b/drivers/net/ethernet/mellanox/mlxsw/pci.c
index 85faa87bf42d..e30c6ce3dcb4 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/pci.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/pci.c
@@ -1519,8 +1519,7 @@ static int mlxsw_pci_cmd_exec(void *bus_priv, u16 opcode, u8 opcode_mod,
1519 u8 *p_status) 1519 u8 *p_status)
1520{ 1520{
1521 struct mlxsw_pci *mlxsw_pci = bus_priv; 1521 struct mlxsw_pci *mlxsw_pci = bus_priv;
1522 dma_addr_t in_mapaddr = mlxsw_pci->cmd.in_mbox.mapaddr; 1522 dma_addr_t in_mapaddr = 0, out_mapaddr = 0;
1523 dma_addr_t out_mapaddr = mlxsw_pci->cmd.out_mbox.mapaddr;
1524 bool evreq = mlxsw_pci->cmd.nopoll; 1523 bool evreq = mlxsw_pci->cmd.nopoll;
1525 unsigned long timeout = msecs_to_jiffies(MLXSW_PCI_CIR_TIMEOUT_MSECS); 1524 unsigned long timeout = msecs_to_jiffies(MLXSW_PCI_CIR_TIMEOUT_MSECS);
1526 bool *p_wait_done = &mlxsw_pci->cmd.wait_done; 1525 bool *p_wait_done = &mlxsw_pci->cmd.wait_done;
@@ -1532,11 +1531,15 @@ static int mlxsw_pci_cmd_exec(void *bus_priv, u16 opcode, u8 opcode_mod,
1532 if (err) 1531 if (err)
1533 return err; 1532 return err;
1534 1533
1535 if (in_mbox) 1534 if (in_mbox) {
1536 memcpy(mlxsw_pci->cmd.in_mbox.buf, in_mbox, in_mbox_size); 1535 memcpy(mlxsw_pci->cmd.in_mbox.buf, in_mbox, in_mbox_size);
1536 in_mapaddr = mlxsw_pci->cmd.in_mbox.mapaddr;
1537 }
1537 mlxsw_pci_write32(mlxsw_pci, CIR_IN_PARAM_HI, upper_32_bits(in_mapaddr)); 1538 mlxsw_pci_write32(mlxsw_pci, CIR_IN_PARAM_HI, upper_32_bits(in_mapaddr));
1538 mlxsw_pci_write32(mlxsw_pci, CIR_IN_PARAM_LO, lower_32_bits(in_mapaddr)); 1539 mlxsw_pci_write32(mlxsw_pci, CIR_IN_PARAM_LO, lower_32_bits(in_mapaddr));
1539 1540
1541 if (out_mbox)
1542 out_mapaddr = mlxsw_pci->cmd.out_mbox.mapaddr;
1540 mlxsw_pci_write32(mlxsw_pci, CIR_OUT_PARAM_HI, upper_32_bits(out_mapaddr)); 1543 mlxsw_pci_write32(mlxsw_pci, CIR_OUT_PARAM_HI, upper_32_bits(out_mapaddr));
1541 mlxsw_pci_write32(mlxsw_pci, CIR_OUT_PARAM_LO, lower_32_bits(out_mapaddr)); 1544 mlxsw_pci_write32(mlxsw_pci, CIR_OUT_PARAM_LO, lower_32_bits(out_mapaddr));
1542 1545
diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
index 0e08be41c8e0..e002398364c8 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
@@ -1,11 +1,11 @@
1/* 1/*
2 * drivers/net/ethernet/mellanox/mlxsw/reg.h 2 * drivers/net/ethernet/mellanox/mlxsw/reg.h
3 * Copyright (c) 2015-2017 Mellanox Technologies. All rights reserved. 3 * Copyright (c) 2015-2018 Mellanox Technologies. All rights reserved.
4 * Copyright (c) 2015-2016 Ido Schimmel <idosch@mellanox.com> 4 * Copyright (c) 2015-2016 Ido Schimmel <idosch@mellanox.com>
5 * Copyright (c) 2015 Elad Raz <eladr@mellanox.com> 5 * Copyright (c) 2015 Elad Raz <eladr@mellanox.com>
6 * Copyright (c) 2015-2017 Jiri Pirko <jiri@mellanox.com> 6 * Copyright (c) 2015-2017 Jiri Pirko <jiri@mellanox.com>
7 * Copyright (c) 2016 Yotam Gigi <yotamg@mellanox.com> 7 * Copyright (c) 2016 Yotam Gigi <yotamg@mellanox.com>
8 * Copyright (c) 2017 Petr Machata <petrm@mellanox.com> 8 * Copyright (c) 2017-2018 Petr Machata <petrm@mellanox.com>
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are met: 11 * modification, are permitted provided that the following conditions are met:
@@ -2872,6 +2872,14 @@ static inline void mlxsw_reg_pmtu_pack(char *payload, u8 local_port,
2872 2872
2873MLXSW_REG_DEFINE(ptys, MLXSW_REG_PTYS_ID, MLXSW_REG_PTYS_LEN); 2873MLXSW_REG_DEFINE(ptys, MLXSW_REG_PTYS_ID, MLXSW_REG_PTYS_LEN);
2874 2874
2875/* an_disable_admin
2876 * Auto negotiation disable administrative configuration
2877 * 0 - Device doesn't support AN disable.
2878 * 1 - Device supports AN disable.
2879 * Access: RW
2880 */
2881MLXSW_ITEM32(reg, ptys, an_disable_admin, 0x00, 30, 1);
2882
2875/* reg_ptys_local_port 2883/* reg_ptys_local_port
2876 * Local port number. 2884 * Local port number.
2877 * Access: Index 2885 * Access: Index
@@ -3000,12 +3008,13 @@ MLXSW_ITEM32(reg, ptys, ib_proto_oper, 0x28, 0, 16);
3000MLXSW_ITEM32(reg, ptys, eth_proto_lp_advertise, 0x30, 0, 32); 3008MLXSW_ITEM32(reg, ptys, eth_proto_lp_advertise, 0x30, 0, 32);
3001 3009
3002static inline void mlxsw_reg_ptys_eth_pack(char *payload, u8 local_port, 3010static inline void mlxsw_reg_ptys_eth_pack(char *payload, u8 local_port,
3003 u32 proto_admin) 3011 u32 proto_admin, bool autoneg)
3004{ 3012{
3005 MLXSW_REG_ZERO(ptys, payload); 3013 MLXSW_REG_ZERO(ptys, payload);
3006 mlxsw_reg_ptys_local_port_set(payload, local_port); 3014 mlxsw_reg_ptys_local_port_set(payload, local_port);
3007 mlxsw_reg_ptys_proto_mask_set(payload, MLXSW_REG_PTYS_PROTO_MASK_ETH); 3015 mlxsw_reg_ptys_proto_mask_set(payload, MLXSW_REG_PTYS_PROTO_MASK_ETH);
3008 mlxsw_reg_ptys_eth_proto_admin_set(payload, proto_admin); 3016 mlxsw_reg_ptys_eth_proto_admin_set(payload, proto_admin);
3017 mlxsw_reg_ptys_an_disable_admin_set(payload, !autoneg);
3009} 3018}
3010 3019
3011static inline void mlxsw_reg_ptys_eth_unpack(char *payload, 3020static inline void mlxsw_reg_ptys_eth_unpack(char *payload,
@@ -6772,8 +6781,104 @@ MLXSW_ITEM32(reg, mpat, qos, 0x04, 26, 1);
6772 */ 6781 */
6773MLXSW_ITEM32(reg, mpat, be, 0x04, 25, 1); 6782MLXSW_ITEM32(reg, mpat, be, 0x04, 25, 1);
6774 6783
6784enum mlxsw_reg_mpat_span_type {
6785 /* Local SPAN Ethernet.
6786 * The original packet is not encapsulated.
6787 */
6788 MLXSW_REG_MPAT_SPAN_TYPE_LOCAL_ETH = 0x0,
6789
6790 /* Encapsulated Remote SPAN Ethernet L3 GRE.
6791 * The packet is encapsulated with GRE header.
6792 */
6793 MLXSW_REG_MPAT_SPAN_TYPE_REMOTE_ETH_L3 = 0x3,
6794};
6795
6796/* reg_mpat_span_type
6797 * SPAN type.
6798 * Access: RW
6799 */
6800MLXSW_ITEM32(reg, mpat, span_type, 0x04, 0, 4);
6801
6802/* Remote SPAN - Ethernet VLAN
6803 * - - - - - - - - - - - - - -
6804 */
6805
6806/* reg_mpat_eth_rspan_vid
6807 * Encapsulation header VLAN ID.
6808 * Access: RW
6809 */
6810MLXSW_ITEM32(reg, mpat, eth_rspan_vid, 0x18, 0, 12);
6811
6812/* Encapsulated Remote SPAN - Ethernet L2
6813 * - - - - - - - - - - - - - - - - - - -
6814 */
6815
6816enum mlxsw_reg_mpat_eth_rspan_version {
6817 MLXSW_REG_MPAT_ETH_RSPAN_VERSION_NO_HEADER = 15,
6818};
6819
6820/* reg_mpat_eth_rspan_version
6821 * RSPAN mirror header version.
6822 * Access: RW
6823 */
6824MLXSW_ITEM32(reg, mpat, eth_rspan_version, 0x10, 18, 4);
6825
6826/* reg_mpat_eth_rspan_mac
6827 * Destination MAC address.
6828 * Access: RW
6829 */
6830MLXSW_ITEM_BUF(reg, mpat, eth_rspan_mac, 0x12, 6);
6831
6832/* reg_mpat_eth_rspan_tp
6833 * Tag Packet. Indicates whether the mirroring header should be VLAN tagged.
6834 * Access: RW
6835 */
6836MLXSW_ITEM32(reg, mpat, eth_rspan_tp, 0x18, 16, 1);
6837
6838/* Encapsulated Remote SPAN - Ethernet L3
6839 * - - - - - - - - - - - - - - - - - - -
6840 */
6841
6842enum mlxsw_reg_mpat_eth_rspan_protocol {
6843 MLXSW_REG_MPAT_ETH_RSPAN_PROTOCOL_IPV4,
6844 MLXSW_REG_MPAT_ETH_RSPAN_PROTOCOL_IPV6,
6845};
6846
6847/* reg_mpat_eth_rspan_protocol
6848 * SPAN encapsulation protocol.
6849 * Access: RW
6850 */
6851MLXSW_ITEM32(reg, mpat, eth_rspan_protocol, 0x18, 24, 4);
6852
6853/* reg_mpat_eth_rspan_ttl
6854 * Encapsulation header Time-to-Live/HopLimit.
6855 * Access: RW
6856 */
6857MLXSW_ITEM32(reg, mpat, eth_rspan_ttl, 0x1C, 4, 8);
6858
6859/* reg_mpat_eth_rspan_smac
6860 * Source MAC address
6861 * Access: RW
6862 */
6863MLXSW_ITEM_BUF(reg, mpat, eth_rspan_smac, 0x22, 6);
6864
6865/* reg_mpat_eth_rspan_dip*
6866 * Destination IP address. The IP version is configured by protocol.
6867 * Access: RW
6868 */
6869MLXSW_ITEM32(reg, mpat, eth_rspan_dip4, 0x4C, 0, 32);
6870MLXSW_ITEM_BUF(reg, mpat, eth_rspan_dip6, 0x40, 16);
6871
6872/* reg_mpat_eth_rspan_sip*
6873 * Source IP address. The IP version is configured by protocol.
6874 * Access: RW
6875 */
6876MLXSW_ITEM32(reg, mpat, eth_rspan_sip4, 0x5C, 0, 32);
6877MLXSW_ITEM_BUF(reg, mpat, eth_rspan_sip6, 0x50, 16);
6878
6775static inline void mlxsw_reg_mpat_pack(char *payload, u8 pa_id, 6879static inline void mlxsw_reg_mpat_pack(char *payload, u8 pa_id,
6776 u16 system_port, bool e) 6880 u16 system_port, bool e,
6881 enum mlxsw_reg_mpat_span_type span_type)
6777{ 6882{
6778 MLXSW_REG_ZERO(mpat, payload); 6883 MLXSW_REG_ZERO(mpat, payload);
6779 mlxsw_reg_mpat_pa_id_set(payload, pa_id); 6884 mlxsw_reg_mpat_pa_id_set(payload, pa_id);
@@ -6781,6 +6886,49 @@ static inline void mlxsw_reg_mpat_pack(char *payload, u8 pa_id,
6781 mlxsw_reg_mpat_e_set(payload, e); 6886 mlxsw_reg_mpat_e_set(payload, e);
6782 mlxsw_reg_mpat_qos_set(payload, 1); 6887 mlxsw_reg_mpat_qos_set(payload, 1);
6783 mlxsw_reg_mpat_be_set(payload, 1); 6888 mlxsw_reg_mpat_be_set(payload, 1);
6889 mlxsw_reg_mpat_span_type_set(payload, span_type);
6890}
6891
6892static inline void mlxsw_reg_mpat_eth_rspan_pack(char *payload, u16 vid)
6893{
6894 mlxsw_reg_mpat_eth_rspan_vid_set(payload, vid);
6895}
6896
6897static inline void
6898mlxsw_reg_mpat_eth_rspan_l2_pack(char *payload,
6899 enum mlxsw_reg_mpat_eth_rspan_version version,
6900 const char *mac,
6901 bool tp)
6902{
6903 mlxsw_reg_mpat_eth_rspan_version_set(payload, version);
6904 mlxsw_reg_mpat_eth_rspan_mac_memcpy_to(payload, mac);
6905 mlxsw_reg_mpat_eth_rspan_tp_set(payload, tp);
6906}
6907
6908static inline void
6909mlxsw_reg_mpat_eth_rspan_l3_ipv4_pack(char *payload, u8 ttl,
6910 const char *smac,
6911 u32 sip, u32 dip)
6912{
6913 mlxsw_reg_mpat_eth_rspan_ttl_set(payload, ttl);
6914 mlxsw_reg_mpat_eth_rspan_smac_memcpy_to(payload, smac);
6915 mlxsw_reg_mpat_eth_rspan_protocol_set(payload,
6916 MLXSW_REG_MPAT_ETH_RSPAN_PROTOCOL_IPV4);
6917 mlxsw_reg_mpat_eth_rspan_sip4_set(payload, sip);
6918 mlxsw_reg_mpat_eth_rspan_dip4_set(payload, dip);
6919}
6920
6921static inline void
6922mlxsw_reg_mpat_eth_rspan_l3_ipv6_pack(char *payload, u8 ttl,
6923 const char *smac,
6924 struct in6_addr sip, struct in6_addr dip)
6925{
6926 mlxsw_reg_mpat_eth_rspan_ttl_set(payload, ttl);
6927 mlxsw_reg_mpat_eth_rspan_smac_memcpy_to(payload, smac);
6928 mlxsw_reg_mpat_eth_rspan_protocol_set(payload,
6929 MLXSW_REG_MPAT_ETH_RSPAN_PROTOCOL_IPV6);
6930 mlxsw_reg_mpat_eth_rspan_sip6_memcpy_to(payload, (void *)&sip);
6931 mlxsw_reg_mpat_eth_rspan_dip6_memcpy_to(payload, (void *)&dip);
6784} 6932}
6785 6933
6786/* MPAR - Monitoring Port Analyzer Register 6934/* MPAR - Monitoring Port Analyzer Register
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index bf400c75fcc8..7885fc475f7e 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * drivers/net/ethernet/mellanox/mlxsw/spectrum.c 2 * drivers/net/ethernet/mellanox/mlxsw/spectrum.c
3 * Copyright (c) 2015-2017 Mellanox Technologies. All rights reserved. 3 * Copyright (c) 2015-2018 Mellanox Technologies. All rights reserved.
4 * Copyright (c) 2015-2017 Jiri Pirko <jiri@mellanox.com> 4 * Copyright (c) 2015-2017 Jiri Pirko <jiri@mellanox.com>
5 * Copyright (c) 2015 Ido Schimmel <idosch@mellanox.com> 5 * Copyright (c) 2015 Ido Schimmel <idosch@mellanox.com>
6 * Copyright (c) 2015 Elad Raz <eladr@mellanox.com> 6 * Copyright (c) 2015 Elad Raz <eladr@mellanox.com>
@@ -71,11 +71,12 @@
71#include "spectrum_cnt.h" 71#include "spectrum_cnt.h"
72#include "spectrum_dpipe.h" 72#include "spectrum_dpipe.h"
73#include "spectrum_acl_flex_actions.h" 73#include "spectrum_acl_flex_actions.h"
74#include "spectrum_span.h"
74#include "../mlxfw/mlxfw.h" 75#include "../mlxfw/mlxfw.h"
75 76
76#define MLXSW_FWREV_MAJOR 13 77#define MLXSW_FWREV_MAJOR 13
77#define MLXSW_FWREV_MINOR 1530 78#define MLXSW_FWREV_MINOR 1620
78#define MLXSW_FWREV_SUBMINOR 152 79#define MLXSW_FWREV_SUBMINOR 192
79#define MLXSW_FWREV_MINOR_TO_BRANCH(minor) ((minor) / 100) 80#define MLXSW_FWREV_MINOR_TO_BRANCH(minor) ((minor) / 100)
80 81
81#define MLXSW_SP_FW_FILENAME \ 82#define MLXSW_SP_FW_FILENAME \
@@ -487,347 +488,6 @@ static int mlxsw_sp_base_mac_get(struct mlxsw_sp *mlxsw_sp)
487 return 0; 488 return 0;
488} 489}
489 490
490static int mlxsw_sp_span_init(struct mlxsw_sp *mlxsw_sp)
491{
492 int i;
493
494 if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_SPAN))
495 return -EIO;
496
497 mlxsw_sp->span.entries_count = MLXSW_CORE_RES_GET(mlxsw_sp->core,
498 MAX_SPAN);
499 mlxsw_sp->span.entries = kcalloc(mlxsw_sp->span.entries_count,
500 sizeof(struct mlxsw_sp_span_entry),
501 GFP_KERNEL);
502 if (!mlxsw_sp->span.entries)
503 return -ENOMEM;
504
505 for (i = 0; i < mlxsw_sp->span.entries_count; i++)
506 INIT_LIST_HEAD(&mlxsw_sp->span.entries[i].bound_ports_list);
507
508 return 0;
509}
510
511static void mlxsw_sp_span_fini(struct mlxsw_sp *mlxsw_sp)
512{
513 int i;
514
515 for (i = 0; i < mlxsw_sp->span.entries_count; i++) {
516 struct mlxsw_sp_span_entry *curr = &mlxsw_sp->span.entries[i];
517
518 WARN_ON_ONCE(!list_empty(&curr->bound_ports_list));
519 }
520 kfree(mlxsw_sp->span.entries);
521}
522
523static struct mlxsw_sp_span_entry *
524mlxsw_sp_span_entry_create(struct mlxsw_sp_port *port)
525{
526 struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
527 struct mlxsw_sp_span_entry *span_entry;
528 char mpat_pl[MLXSW_REG_MPAT_LEN];
529 u8 local_port = port->local_port;
530 int index;
531 int i;
532 int err;
533
534 /* find a free entry to use */
535 index = -1;
536 for (i = 0; i < mlxsw_sp->span.entries_count; i++) {
537 if (!mlxsw_sp->span.entries[i].used) {
538 index = i;
539 span_entry = &mlxsw_sp->span.entries[i];
540 break;
541 }
542 }
543 if (index < 0)
544 return NULL;
545
546 /* create a new port analayzer entry for local_port */
547 mlxsw_reg_mpat_pack(mpat_pl, index, local_port, true);
548 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpat), mpat_pl);
549 if (err)
550 return NULL;
551
552 span_entry->used = true;
553 span_entry->id = index;
554 span_entry->ref_count = 1;
555 span_entry->local_port = local_port;
556 return span_entry;
557}
558
559static void mlxsw_sp_span_entry_destroy(struct mlxsw_sp *mlxsw_sp,
560 struct mlxsw_sp_span_entry *span_entry)
561{
562 u8 local_port = span_entry->local_port;
563 char mpat_pl[MLXSW_REG_MPAT_LEN];
564 int pa_id = span_entry->id;
565
566 mlxsw_reg_mpat_pack(mpat_pl, pa_id, local_port, false);
567 mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpat), mpat_pl);
568 span_entry->used = false;
569}
570
571struct mlxsw_sp_span_entry *
572mlxsw_sp_span_entry_find(struct mlxsw_sp *mlxsw_sp, u8 local_port)
573{
574 int i;
575
576 for (i = 0; i < mlxsw_sp->span.entries_count; i++) {
577 struct mlxsw_sp_span_entry *curr = &mlxsw_sp->span.entries[i];
578
579 if (curr->used && curr->local_port == local_port)
580 return curr;
581 }
582 return NULL;
583}
584
585static struct mlxsw_sp_span_entry
586*mlxsw_sp_span_entry_get(struct mlxsw_sp_port *port)
587{
588 struct mlxsw_sp_span_entry *span_entry;
589
590 span_entry = mlxsw_sp_span_entry_find(port->mlxsw_sp,
591 port->local_port);
592 if (span_entry) {
593 /* Already exists, just take a reference */
594 span_entry->ref_count++;
595 return span_entry;
596 }
597
598 return mlxsw_sp_span_entry_create(port);
599}
600
601static int mlxsw_sp_span_entry_put(struct mlxsw_sp *mlxsw_sp,
602 struct mlxsw_sp_span_entry *span_entry)
603{
604 WARN_ON(!span_entry->ref_count);
605 if (--span_entry->ref_count == 0)
606 mlxsw_sp_span_entry_destroy(mlxsw_sp, span_entry);
607 return 0;
608}
609
610static bool mlxsw_sp_span_is_egress_mirror(struct mlxsw_sp_port *port)
611{
612 struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
613 struct mlxsw_sp_span_inspected_port *p;
614 int i;
615
616 for (i = 0; i < mlxsw_sp->span.entries_count; i++) {
617 struct mlxsw_sp_span_entry *curr = &mlxsw_sp->span.entries[i];
618
619 list_for_each_entry(p, &curr->bound_ports_list, list)
620 if (p->local_port == port->local_port &&
621 p->type == MLXSW_SP_SPAN_EGRESS)
622 return true;
623 }
624
625 return false;
626}
627
628static int mlxsw_sp_span_mtu_to_buffsize(const struct mlxsw_sp *mlxsw_sp,
629 int mtu)
630{
631 return mlxsw_sp_bytes_cells(mlxsw_sp, mtu * 5 / 2) + 1;
632}
633
634static int mlxsw_sp_span_port_mtu_update(struct mlxsw_sp_port *port, u16 mtu)
635{
636 struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
637 char sbib_pl[MLXSW_REG_SBIB_LEN];
638 int err;
639
640 /* If port is egress mirrored, the shared buffer size should be
641 * updated according to the mtu value
642 */
643 if (mlxsw_sp_span_is_egress_mirror(port)) {
644 u32 buffsize = mlxsw_sp_span_mtu_to_buffsize(mlxsw_sp, mtu);
645
646 mlxsw_reg_sbib_pack(sbib_pl, port->local_port, buffsize);
647 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl);
648 if (err) {
649 netdev_err(port->dev, "Could not update shared buffer for mirroring\n");
650 return err;
651 }
652 }
653
654 return 0;
655}
656
657static struct mlxsw_sp_span_inspected_port *
658mlxsw_sp_span_entry_bound_port_find(struct mlxsw_sp_span_entry *span_entry,
659 enum mlxsw_sp_span_type type,
660 struct mlxsw_sp_port *port,
661 bool bind)
662{
663 struct mlxsw_sp_span_inspected_port *p;
664
665 list_for_each_entry(p, &span_entry->bound_ports_list, list)
666 if (type == p->type &&
667 port->local_port == p->local_port &&
668 bind == p->bound)
669 return p;
670 return NULL;
671}
672
673static int
674mlxsw_sp_span_inspected_port_bind(struct mlxsw_sp_port *port,
675 struct mlxsw_sp_span_entry *span_entry,
676 enum mlxsw_sp_span_type type,
677 bool bind)
678{
679 struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
680 char mpar_pl[MLXSW_REG_MPAR_LEN];
681 int pa_id = span_entry->id;
682
683 /* bind the port to the SPAN entry */
684 mlxsw_reg_mpar_pack(mpar_pl, port->local_port,
685 (enum mlxsw_reg_mpar_i_e) type, bind, pa_id);
686 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpar), mpar_pl);
687}
688
689static int
690mlxsw_sp_span_inspected_port_add(struct mlxsw_sp_port *port,
691 struct mlxsw_sp_span_entry *span_entry,
692 enum mlxsw_sp_span_type type,
693 bool bind)
694{
695 struct mlxsw_sp_span_inspected_port *inspected_port;
696 struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
697 char sbib_pl[MLXSW_REG_SBIB_LEN];
698 int i;
699 int err;
700
701 /* A given (source port, direction) can only be bound to one analyzer,
702 * so if a binding is requested, check for conflicts.
703 */
704 if (bind)
705 for (i = 0; i < mlxsw_sp->span.entries_count; i++) {
706 struct mlxsw_sp_span_entry *curr =
707 &mlxsw_sp->span.entries[i];
708
709 if (mlxsw_sp_span_entry_bound_port_find(curr, type,
710 port, bind))
711 return -EEXIST;
712 }
713
714 /* if it is an egress SPAN, bind a shared buffer to it */
715 if (type == MLXSW_SP_SPAN_EGRESS) {
716 u32 buffsize = mlxsw_sp_span_mtu_to_buffsize(mlxsw_sp,
717 port->dev->mtu);
718
719 mlxsw_reg_sbib_pack(sbib_pl, port->local_port, buffsize);
720 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl);
721 if (err) {
722 netdev_err(port->dev, "Could not create shared buffer for mirroring\n");
723 return err;
724 }
725 }
726
727 if (bind) {
728 err = mlxsw_sp_span_inspected_port_bind(port, span_entry, type,
729 true);
730 if (err)
731 goto err_port_bind;
732 }
733
734 inspected_port = kzalloc(sizeof(*inspected_port), GFP_KERNEL);
735 if (!inspected_port) {
736 err = -ENOMEM;
737 goto err_inspected_port_alloc;
738 }
739 inspected_port->local_port = port->local_port;
740 inspected_port->type = type;
741 inspected_port->bound = bind;
742 list_add_tail(&inspected_port->list, &span_entry->bound_ports_list);
743
744 return 0;
745
746err_inspected_port_alloc:
747 if (bind)
748 mlxsw_sp_span_inspected_port_bind(port, span_entry, type,
749 false);
750err_port_bind:
751 if (type == MLXSW_SP_SPAN_EGRESS) {
752 mlxsw_reg_sbib_pack(sbib_pl, port->local_port, 0);
753 mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl);
754 }
755 return err;
756}
757
758static void
759mlxsw_sp_span_inspected_port_del(struct mlxsw_sp_port *port,
760 struct mlxsw_sp_span_entry *span_entry,
761 enum mlxsw_sp_span_type type,
762 bool bind)
763{
764 struct mlxsw_sp_span_inspected_port *inspected_port;
765 struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
766 char sbib_pl[MLXSW_REG_SBIB_LEN];
767
768 inspected_port = mlxsw_sp_span_entry_bound_port_find(span_entry, type,
769 port, bind);
770 if (!inspected_port)
771 return;
772
773 if (bind)
774 mlxsw_sp_span_inspected_port_bind(port, span_entry, type,
775 false);
776 /* remove the SBIB buffer if it was egress SPAN */
777 if (type == MLXSW_SP_SPAN_EGRESS) {
778 mlxsw_reg_sbib_pack(sbib_pl, port->local_port, 0);
779 mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl);
780 }
781
782 mlxsw_sp_span_entry_put(mlxsw_sp, span_entry);
783
784 list_del(&inspected_port->list);
785 kfree(inspected_port);
786}
787
788int mlxsw_sp_span_mirror_add(struct mlxsw_sp_port *from,
789 struct mlxsw_sp_port *to,
790 enum mlxsw_sp_span_type type, bool bind)
791{
792 struct mlxsw_sp *mlxsw_sp = from->mlxsw_sp;
793 struct mlxsw_sp_span_entry *span_entry;
794 int err;
795
796 span_entry = mlxsw_sp_span_entry_get(to);
797 if (!span_entry)
798 return -ENOENT;
799
800 netdev_dbg(from->dev, "Adding inspected port to SPAN entry %d\n",
801 span_entry->id);
802
803 err = mlxsw_sp_span_inspected_port_add(from, span_entry, type, bind);
804 if (err)
805 goto err_port_bind;
806
807 return 0;
808
809err_port_bind:
810 mlxsw_sp_span_entry_put(mlxsw_sp, span_entry);
811 return err;
812}
813
814void mlxsw_sp_span_mirror_del(struct mlxsw_sp_port *from, u8 destination_port,
815 enum mlxsw_sp_span_type type, bool bind)
816{
817 struct mlxsw_sp_span_entry *span_entry;
818
819 span_entry = mlxsw_sp_span_entry_find(from->mlxsw_sp,
820 destination_port);
821 if (!span_entry) {
822 netdev_err(from->dev, "no span entry found\n");
823 return;
824 }
825
826 netdev_dbg(from->dev, "removing inspected port from SPAN entry %d\n",
827 span_entry->id);
828 mlxsw_sp_span_inspected_port_del(from, span_entry, type, bind);
829}
830
831static int mlxsw_sp_port_sample_set(struct mlxsw_sp_port *mlxsw_sp_port, 491static int mlxsw_sp_port_sample_set(struct mlxsw_sp_port *mlxsw_sp_port,
832 bool enable, u32 rate) 492 bool enable, u32 rate)
833{ 493{
@@ -1380,6 +1040,16 @@ mlxsw_sp_port_get_hw_xstats(struct net_device *dev,
1380 xstats->tail_drop[i] = 1040 xstats->tail_drop[i] =
1381 mlxsw_reg_ppcnt_tc_no_buffer_discard_uc_get(ppcnt_pl); 1041 mlxsw_reg_ppcnt_tc_no_buffer_discard_uc_get(ppcnt_pl);
1382 } 1042 }
1043
1044 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
1045 err = mlxsw_sp_port_get_stats_raw(dev, MLXSW_REG_PPCNT_PRIO_CNT,
1046 i, ppcnt_pl);
1047 if (err)
1048 continue;
1049
1050 xstats->tx_packets[i] = mlxsw_reg_ppcnt_tx_frames_get(ppcnt_pl);
1051 xstats->tx_bytes[i] = mlxsw_reg_ppcnt_tx_octets_get(ppcnt_pl);
1052 }
1383} 1053}
1384 1054
1385static void update_stats_cache(struct work_struct *work) 1055static void update_stats_cache(struct work_struct *work)
@@ -1604,7 +1274,6 @@ mlxsw_sp_port_add_cls_matchall_mirror(struct mlxsw_sp_port *mlxsw_sp_port,
1604 bool ingress) 1274 bool ingress)
1605{ 1275{
1606 enum mlxsw_sp_span_type span_type; 1276 enum mlxsw_sp_span_type span_type;
1607 struct mlxsw_sp_port *to_port;
1608 struct net_device *to_dev; 1277 struct net_device *to_dev;
1609 1278
1610 to_dev = tcf_mirred_dev(a); 1279 to_dev = tcf_mirred_dev(a);
@@ -1613,17 +1282,10 @@ mlxsw_sp_port_add_cls_matchall_mirror(struct mlxsw_sp_port *mlxsw_sp_port,
1613 return -EINVAL; 1282 return -EINVAL;
1614 } 1283 }
1615 1284
1616 if (!mlxsw_sp_port_dev_check(to_dev)) {
1617 netdev_err(mlxsw_sp_port->dev, "Cannot mirror to a non-spectrum port");
1618 return -EOPNOTSUPP;
1619 }
1620 to_port = netdev_priv(to_dev);
1621
1622 mirror->to_local_port = to_port->local_port;
1623 mirror->ingress = ingress; 1285 mirror->ingress = ingress;
1624 span_type = ingress ? MLXSW_SP_SPAN_INGRESS : MLXSW_SP_SPAN_EGRESS; 1286 span_type = ingress ? MLXSW_SP_SPAN_INGRESS : MLXSW_SP_SPAN_EGRESS;
1625 return mlxsw_sp_span_mirror_add(mlxsw_sp_port, to_port, span_type, 1287 return mlxsw_sp_span_mirror_add(mlxsw_sp_port, to_dev, span_type,
1626 true); 1288 true, &mirror->span_id);
1627} 1289}
1628 1290
1629static void 1291static void
@@ -1634,7 +1296,7 @@ mlxsw_sp_port_del_cls_matchall_mirror(struct mlxsw_sp_port *mlxsw_sp_port,
1634 1296
1635 span_type = mirror->ingress ? 1297 span_type = mirror->ingress ?
1636 MLXSW_SP_SPAN_INGRESS : MLXSW_SP_SPAN_EGRESS; 1298 MLXSW_SP_SPAN_INGRESS : MLXSW_SP_SPAN_EGRESS;
1637 mlxsw_sp_span_mirror_del(mlxsw_sp_port, mirror->to_local_port, 1299 mlxsw_sp_span_mirror_del(mlxsw_sp_port, mirror->span_id,
1638 span_type, true); 1300 span_type, true);
1639} 1301}
1640 1302
@@ -2728,7 +2390,7 @@ static int mlxsw_sp_port_get_link_ksettings(struct net_device *dev,
2728 int err; 2390 int err;
2729 2391
2730 autoneg = mlxsw_sp_port->link.autoneg; 2392 autoneg = mlxsw_sp_port->link.autoneg;
2731 mlxsw_reg_ptys_eth_pack(ptys_pl, mlxsw_sp_port->local_port, 0); 2393 mlxsw_reg_ptys_eth_pack(ptys_pl, mlxsw_sp_port->local_port, 0, false);
2732 err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl); 2394 err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl);
2733 if (err) 2395 if (err)
2734 return err; 2396 return err;
@@ -2762,7 +2424,7 @@ mlxsw_sp_port_set_link_ksettings(struct net_device *dev,
2762 bool autoneg; 2424 bool autoneg;
2763 int err; 2425 int err;
2764 2426
2765 mlxsw_reg_ptys_eth_pack(ptys_pl, mlxsw_sp_port->local_port, 0); 2427 mlxsw_reg_ptys_eth_pack(ptys_pl, mlxsw_sp_port->local_port, 0, false);
2766 err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl); 2428 err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl);
2767 if (err) 2429 if (err)
2768 return err; 2430 return err;
@@ -2780,7 +2442,7 @@ mlxsw_sp_port_set_link_ksettings(struct net_device *dev,
2780 } 2442 }
2781 2443
2782 mlxsw_reg_ptys_eth_pack(ptys_pl, mlxsw_sp_port->local_port, 2444 mlxsw_reg_ptys_eth_pack(ptys_pl, mlxsw_sp_port->local_port,
2783 eth_proto_new); 2445 eth_proto_new, autoneg);
2784 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl); 2446 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl);
2785 if (err) 2447 if (err)
2786 return err; 2448 return err;
@@ -2991,7 +2653,7 @@ mlxsw_sp_port_speed_by_width_set(struct mlxsw_sp_port *mlxsw_sp_port, u8 width)
2991 2653
2992 eth_proto_admin = mlxsw_sp_to_ptys_upper_speed(upper_speed); 2654 eth_proto_admin = mlxsw_sp_to_ptys_upper_speed(upper_speed);
2993 mlxsw_reg_ptys_eth_pack(ptys_pl, mlxsw_sp_port->local_port, 2655 mlxsw_reg_ptys_eth_pack(ptys_pl, mlxsw_sp_port->local_port,
2994 eth_proto_admin); 2656 eth_proto_admin, mlxsw_sp_port->link.autoneg);
2995 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl); 2657 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl);
2996} 2658}
2997 2659
@@ -4021,14 +3683,24 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
4021 goto err_afa_init; 3683 goto err_afa_init;
4022 } 3684 }
4023 3685
3686 err = mlxsw_sp_span_init(mlxsw_sp);
3687 if (err) {
3688 dev_err(mlxsw_sp->bus_info->dev, "Failed to init span system\n");
3689 goto err_span_init;
3690 }
3691
3692 /* Initialize router after SPAN is initialized, so that the FIB and
3693 * neighbor event handlers can issue SPAN respin.
3694 */
4024 err = mlxsw_sp_router_init(mlxsw_sp); 3695 err = mlxsw_sp_router_init(mlxsw_sp);
4025 if (err) { 3696 if (err) {
4026 dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize router\n"); 3697 dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize router\n");
4027 goto err_router_init; 3698 goto err_router_init;
4028 } 3699 }
4029 3700
4030 /* Initialize netdevice notifier after router is initialized, so that 3701 /* Initialize netdevice notifier after router and SPAN is initialized,
4031 * the event handler can use router structures. 3702 * so that the event handler can use router structures and call SPAN
3703 * respin.
4032 */ 3704 */
4033 mlxsw_sp->netdevice_nb.notifier_call = mlxsw_sp_netdevice_event; 3705 mlxsw_sp->netdevice_nb.notifier_call = mlxsw_sp_netdevice_event;
4034 err = register_netdevice_notifier(&mlxsw_sp->netdevice_nb); 3706 err = register_netdevice_notifier(&mlxsw_sp->netdevice_nb);
@@ -4037,12 +3709,6 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
4037 goto err_netdev_notifier; 3709 goto err_netdev_notifier;
4038 } 3710 }
4039 3711
4040 err = mlxsw_sp_span_init(mlxsw_sp);
4041 if (err) {
4042 dev_err(mlxsw_sp->bus_info->dev, "Failed to init span system\n");
4043 goto err_span_init;
4044 }
4045
4046 err = mlxsw_sp_acl_init(mlxsw_sp); 3712 err = mlxsw_sp_acl_init(mlxsw_sp);
4047 if (err) { 3713 if (err) {
4048 dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize ACL\n"); 3714 dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize ACL\n");
@@ -4068,12 +3734,12 @@ err_ports_create:
4068err_dpipe_init: 3734err_dpipe_init:
4069 mlxsw_sp_acl_fini(mlxsw_sp); 3735 mlxsw_sp_acl_fini(mlxsw_sp);
4070err_acl_init: 3736err_acl_init:
4071 mlxsw_sp_span_fini(mlxsw_sp);
4072err_span_init:
4073 unregister_netdevice_notifier(&mlxsw_sp->netdevice_nb); 3737 unregister_netdevice_notifier(&mlxsw_sp->netdevice_nb);
4074err_netdev_notifier: 3738err_netdev_notifier:
4075 mlxsw_sp_router_fini(mlxsw_sp); 3739 mlxsw_sp_router_fini(mlxsw_sp);
4076err_router_init: 3740err_router_init:
3741 mlxsw_sp_span_fini(mlxsw_sp);
3742err_span_init:
4077 mlxsw_sp_afa_fini(mlxsw_sp); 3743 mlxsw_sp_afa_fini(mlxsw_sp);
4078err_afa_init: 3744err_afa_init:
4079 mlxsw_sp_counter_pool_fini(mlxsw_sp); 3745 mlxsw_sp_counter_pool_fini(mlxsw_sp);
@@ -4099,9 +3765,9 @@ static void mlxsw_sp_fini(struct mlxsw_core *mlxsw_core)
4099 mlxsw_sp_ports_remove(mlxsw_sp); 3765 mlxsw_sp_ports_remove(mlxsw_sp);
4100 mlxsw_sp_dpipe_fini(mlxsw_sp); 3766 mlxsw_sp_dpipe_fini(mlxsw_sp);
4101 mlxsw_sp_acl_fini(mlxsw_sp); 3767 mlxsw_sp_acl_fini(mlxsw_sp);
4102 mlxsw_sp_span_fini(mlxsw_sp);
4103 unregister_netdevice_notifier(&mlxsw_sp->netdevice_nb); 3768 unregister_netdevice_notifier(&mlxsw_sp->netdevice_nb);
4104 mlxsw_sp_router_fini(mlxsw_sp); 3769 mlxsw_sp_router_fini(mlxsw_sp);
3770 mlxsw_sp_span_fini(mlxsw_sp);
4105 mlxsw_sp_afa_fini(mlxsw_sp); 3771 mlxsw_sp_afa_fini(mlxsw_sp);
4106 mlxsw_sp_counter_pool_fini(mlxsw_sp); 3772 mlxsw_sp_counter_pool_fini(mlxsw_sp);
4107 mlxsw_sp_switchdev_fini(mlxsw_sp); 3773 mlxsw_sp_switchdev_fini(mlxsw_sp);
@@ -4113,12 +3779,8 @@ static void mlxsw_sp_fini(struct mlxsw_core *mlxsw_core)
4113} 3779}
4114 3780
4115static const struct mlxsw_config_profile mlxsw_sp_config_profile = { 3781static const struct mlxsw_config_profile mlxsw_sp_config_profile = {
4116 .used_max_vepa_channels = 1,
4117 .max_vepa_channels = 0,
4118 .used_max_mid = 1, 3782 .used_max_mid = 1,
4119 .max_mid = MLXSW_SP_MID_MAX, 3783 .max_mid = MLXSW_SP_MID_MAX,
4120 .used_max_pgt = 1,
4121 .max_pgt = 0,
4122 .used_flood_tables = 1, 3784 .used_flood_tables = 1,
4123 .used_flood_mode = 1, 3785 .used_flood_mode = 1,
4124 .flood_mode = 3, 3786 .flood_mode = 3,
@@ -4144,70 +3806,6 @@ static const struct mlxsw_config_profile mlxsw_sp_config_profile = {
4144 .resource_query_enable = 1, 3806 .resource_query_enable = 1,
4145}; 3807};
4146 3808
4147static bool
4148mlxsw_sp_resource_kvd_granularity_validate(struct netlink_ext_ack *extack,
4149 u64 size)
4150{
4151 const struct mlxsw_config_profile *profile;
4152
4153 profile = &mlxsw_sp_config_profile;
4154 if (size % profile->kvd_hash_granularity) {
4155 NL_SET_ERR_MSG_MOD(extack, "resource set with wrong granularity");
4156 return false;
4157 }
4158 return true;
4159}
4160
4161static int
4162mlxsw_sp_resource_kvd_size_validate(struct devlink *devlink, u64 size,
4163 struct netlink_ext_ack *extack)
4164{
4165 NL_SET_ERR_MSG_MOD(extack, "kvd size cannot be changed");
4166 return -EINVAL;
4167}
4168
4169static int
4170mlxsw_sp_resource_kvd_linear_size_validate(struct devlink *devlink, u64 size,
4171 struct netlink_ext_ack *extack)
4172{
4173 if (!mlxsw_sp_resource_kvd_granularity_validate(extack, size))
4174 return -EINVAL;
4175
4176 return 0;
4177}
4178
4179static int
4180mlxsw_sp_resource_kvd_hash_single_size_validate(struct devlink *devlink, u64 size,
4181 struct netlink_ext_ack *extack)
4182{
4183 struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
4184
4185 if (!mlxsw_sp_resource_kvd_granularity_validate(extack, size))
4186 return -EINVAL;
4187
4188 if (size < MLXSW_CORE_RES_GET(mlxsw_core, KVD_SINGLE_MIN_SIZE)) {
4189 NL_SET_ERR_MSG_MOD(extack, "hash single size is smaller than minimum");
4190 return -EINVAL;
4191 }
4192 return 0;
4193}
4194
4195static int
4196mlxsw_sp_resource_kvd_hash_double_size_validate(struct devlink *devlink, u64 size,
4197 struct netlink_ext_ack *extack)
4198{
4199 struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
4200
4201 if (!mlxsw_sp_resource_kvd_granularity_validate(extack, size))
4202 return -EINVAL;
4203
4204 if (size < MLXSW_CORE_RES_GET(mlxsw_core, KVD_DOUBLE_MIN_SIZE)) {
4205 NL_SET_ERR_MSG_MOD(extack, "hash double size is smaller than minimum");
4206 return -EINVAL;
4207 }
4208 return 0;
4209}
4210
4211static u64 mlxsw_sp_resource_kvd_linear_occ_get(struct devlink *devlink) 3809static u64 mlxsw_sp_resource_kvd_linear_occ_get(struct devlink *devlink)
4212{ 3810{
4213 struct mlxsw_core *mlxsw_core = devlink_priv(devlink); 3811 struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
@@ -4216,23 +3814,10 @@ static u64 mlxsw_sp_resource_kvd_linear_occ_get(struct devlink *devlink)
4216 return mlxsw_sp_kvdl_occ_get(mlxsw_sp); 3814 return mlxsw_sp_kvdl_occ_get(mlxsw_sp);
4217} 3815}
4218 3816
4219static struct devlink_resource_ops mlxsw_sp_resource_kvd_ops = {
4220 .size_validate = mlxsw_sp_resource_kvd_size_validate,
4221};
4222
4223static struct devlink_resource_ops mlxsw_sp_resource_kvd_linear_ops = { 3817static struct devlink_resource_ops mlxsw_sp_resource_kvd_linear_ops = {
4224 .size_validate = mlxsw_sp_resource_kvd_linear_size_validate,
4225 .occ_get = mlxsw_sp_resource_kvd_linear_occ_get, 3818 .occ_get = mlxsw_sp_resource_kvd_linear_occ_get,
4226}; 3819};
4227 3820
4228static struct devlink_resource_ops mlxsw_sp_resource_kvd_hash_single_ops = {
4229 .size_validate = mlxsw_sp_resource_kvd_hash_single_size_validate,
4230};
4231
4232static struct devlink_resource_ops mlxsw_sp_resource_kvd_hash_double_ops = {
4233 .size_validate = mlxsw_sp_resource_kvd_hash_double_size_validate,
4234};
4235
4236static void 3821static void
4237mlxsw_sp_resource_size_params_prepare(struct mlxsw_core *mlxsw_core, 3822mlxsw_sp_resource_size_params_prepare(struct mlxsw_core *mlxsw_core,
4238 struct devlink_resource_size_params *kvd_size_params, 3823 struct devlink_resource_size_params *kvd_size_params,
@@ -4291,17 +3876,16 @@ static int mlxsw_sp_resources_register(struct mlxsw_core *mlxsw_core)
4291 3876
4292 kvd_size = MLXSW_CORE_RES_GET(mlxsw_core, KVD_SIZE); 3877 kvd_size = MLXSW_CORE_RES_GET(mlxsw_core, KVD_SIZE);
4293 err = devlink_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_KVD, 3878 err = devlink_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_KVD,
4294 true, kvd_size, 3879 kvd_size, MLXSW_SP_RESOURCE_KVD,
4295 MLXSW_SP_RESOURCE_KVD,
4296 DEVLINK_RESOURCE_ID_PARENT_TOP, 3880 DEVLINK_RESOURCE_ID_PARENT_TOP,
4297 &kvd_size_params, 3881 &kvd_size_params,
4298 &mlxsw_sp_resource_kvd_ops); 3882 NULL);
4299 if (err) 3883 if (err)
4300 return err; 3884 return err;
4301 3885
4302 linear_size = profile->kvd_linear_size; 3886 linear_size = profile->kvd_linear_size;
4303 err = devlink_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_KVD_LINEAR, 3887 err = devlink_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_KVD_LINEAR,
4304 false, linear_size, 3888 linear_size,
4305 MLXSW_SP_RESOURCE_KVD_LINEAR, 3889 MLXSW_SP_RESOURCE_KVD_LINEAR,
4306 MLXSW_SP_RESOURCE_KVD, 3890 MLXSW_SP_RESOURCE_KVD,
4307 &linear_size_params, 3891 &linear_size_params,
@@ -4309,27 +3893,31 @@ static int mlxsw_sp_resources_register(struct mlxsw_core *mlxsw_core)
4309 if (err) 3893 if (err)
4310 return err; 3894 return err;
4311 3895
3896 err = mlxsw_sp_kvdl_resources_register(devlink);
3897 if (err)
3898 return err;
3899
4312 double_size = kvd_size - linear_size; 3900 double_size = kvd_size - linear_size;
4313 double_size *= profile->kvd_hash_double_parts; 3901 double_size *= profile->kvd_hash_double_parts;
4314 double_size /= profile->kvd_hash_double_parts + 3902 double_size /= profile->kvd_hash_double_parts +
4315 profile->kvd_hash_single_parts; 3903 profile->kvd_hash_single_parts;
4316 double_size = rounddown(double_size, profile->kvd_hash_granularity); 3904 double_size = rounddown(double_size, profile->kvd_hash_granularity);
4317 err = devlink_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_KVD_HASH_DOUBLE, 3905 err = devlink_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_KVD_HASH_DOUBLE,
4318 false, double_size, 3906 double_size,
4319 MLXSW_SP_RESOURCE_KVD_HASH_DOUBLE, 3907 MLXSW_SP_RESOURCE_KVD_HASH_DOUBLE,
4320 MLXSW_SP_RESOURCE_KVD, 3908 MLXSW_SP_RESOURCE_KVD,
4321 &hash_double_size_params, 3909 &hash_double_size_params,
4322 &mlxsw_sp_resource_kvd_hash_double_ops); 3910 NULL);
4323 if (err) 3911 if (err)
4324 return err; 3912 return err;
4325 3913
4326 single_size = kvd_size - double_size - linear_size; 3914 single_size = kvd_size - double_size - linear_size;
4327 err = devlink_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_KVD_HASH_SINGLE, 3915 err = devlink_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_KVD_HASH_SINGLE,
4328 false, single_size, 3916 single_size,
4329 MLXSW_SP_RESOURCE_KVD_HASH_SINGLE, 3917 MLXSW_SP_RESOURCE_KVD_HASH_SINGLE,
4330 MLXSW_SP_RESOURCE_KVD, 3918 MLXSW_SP_RESOURCE_KVD,
4331 &hash_single_size_params, 3919 &hash_single_size_params,
4332 &mlxsw_sp_resource_kvd_hash_single_ops); 3920 NULL);
4333 if (err) 3921 if (err)
4334 return err; 3922 return err;
4335 3923
@@ -4583,13 +4171,11 @@ mlxsw_sp_master_lag_check(struct mlxsw_sp *mlxsw_sp,
4583 u16 lag_id; 4171 u16 lag_id;
4584 4172
4585 if (mlxsw_sp_lag_index_get(mlxsw_sp, lag_dev, &lag_id) != 0) { 4173 if (mlxsw_sp_lag_index_get(mlxsw_sp, lag_dev, &lag_id) != 0) {
4586 NL_SET_ERR_MSG(extack, 4174 NL_SET_ERR_MSG_MOD(extack, "Exceeded number of supported LAG devices");
4587 "spectrum: Exceeded number of supported LAG devices");
4588 return false; 4175 return false;
4589 } 4176 }
4590 if (lag_upper_info->tx_type != NETDEV_LAG_TX_TYPE_HASH) { 4177 if (lag_upper_info->tx_type != NETDEV_LAG_TX_TYPE_HASH) {
4591 NL_SET_ERR_MSG(extack, 4178 NL_SET_ERR_MSG_MOD(extack, "LAG device using unsupported Tx type");
4592 "spectrum: LAG device using unsupported Tx type");
4593 return false; 4179 return false;
4594 } 4180 }
4595 return true; 4181 return true;
@@ -4831,8 +4417,7 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *lower_dev,
4831 !netif_is_lag_master(upper_dev) && 4417 !netif_is_lag_master(upper_dev) &&
4832 !netif_is_bridge_master(upper_dev) && 4418 !netif_is_bridge_master(upper_dev) &&
4833 !netif_is_ovs_master(upper_dev)) { 4419 !netif_is_ovs_master(upper_dev)) {
4834 NL_SET_ERR_MSG(extack, 4420 NL_SET_ERR_MSG_MOD(extack, "Unknown upper device type");
4835 "spectrum: Unknown upper device type");
4836 return -EINVAL; 4421 return -EINVAL;
4837 } 4422 }
4838 if (!info->linking) 4423 if (!info->linking)
@@ -4841,8 +4426,7 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *lower_dev,
4841 (!netif_is_bridge_master(upper_dev) || 4426 (!netif_is_bridge_master(upper_dev) ||
4842 !mlxsw_sp_bridge_device_is_offloaded(mlxsw_sp, 4427 !mlxsw_sp_bridge_device_is_offloaded(mlxsw_sp,
4843 upper_dev))) { 4428 upper_dev))) {
4844 NL_SET_ERR_MSG(extack, 4429 NL_SET_ERR_MSG_MOD(extack, "Enslaving a port to a device that already has an upper device is not supported");
4845 "spectrum: Enslaving a port to a device that already has an upper device is not supported");
4846 return -EINVAL; 4430 return -EINVAL;
4847 } 4431 }
4848 if (netif_is_lag_master(upper_dev) && 4432 if (netif_is_lag_master(upper_dev) &&
@@ -4850,24 +4434,20 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *lower_dev,
4850 info->upper_info, extack)) 4434 info->upper_info, extack))
4851 return -EINVAL; 4435 return -EINVAL;
4852 if (netif_is_lag_master(upper_dev) && vlan_uses_dev(dev)) { 4436 if (netif_is_lag_master(upper_dev) && vlan_uses_dev(dev)) {
4853 NL_SET_ERR_MSG(extack, 4437 NL_SET_ERR_MSG_MOD(extack, "Master device is a LAG master and this device has a VLAN");
4854 "spectrum: Master device is a LAG master and this device has a VLAN");
4855 return -EINVAL; 4438 return -EINVAL;
4856 } 4439 }
4857 if (netif_is_lag_port(dev) && is_vlan_dev(upper_dev) && 4440 if (netif_is_lag_port(dev) && is_vlan_dev(upper_dev) &&
4858 !netif_is_lag_master(vlan_dev_real_dev(upper_dev))) { 4441 !netif_is_lag_master(vlan_dev_real_dev(upper_dev))) {
4859 NL_SET_ERR_MSG(extack, 4442 NL_SET_ERR_MSG_MOD(extack, "Can not put a VLAN on a LAG port");
4860 "spectrum: Can not put a VLAN on a LAG port");
4861 return -EINVAL; 4443 return -EINVAL;
4862 } 4444 }
4863 if (netif_is_ovs_master(upper_dev) && vlan_uses_dev(dev)) { 4445 if (netif_is_ovs_master(upper_dev) && vlan_uses_dev(dev)) {
4864 NL_SET_ERR_MSG(extack, 4446 NL_SET_ERR_MSG_MOD(extack, "Master device is an OVS master and this device has a VLAN");
4865 "spectrum: Master device is an OVS master and this device has a VLAN");
4866 return -EINVAL; 4447 return -EINVAL;
4867 } 4448 }
4868 if (netif_is_ovs_port(dev) && is_vlan_dev(upper_dev)) { 4449 if (netif_is_ovs_port(dev) && is_vlan_dev(upper_dev)) {
4869 NL_SET_ERR_MSG(extack, 4450 NL_SET_ERR_MSG_MOD(extack, "Can not put a VLAN on an OVS port");
4870 "spectrum: Can not put a VLAN on an OVS port");
4871 return -EINVAL; 4451 return -EINVAL;
4872 } 4452 }
4873 break; 4453 break;
@@ -4980,7 +4560,7 @@ static int mlxsw_sp_netdevice_port_vlan_event(struct net_device *vlan_dev,
4980 case NETDEV_PRECHANGEUPPER: 4560 case NETDEV_PRECHANGEUPPER:
4981 upper_dev = info->upper_dev; 4561 upper_dev = info->upper_dev;
4982 if (!netif_is_bridge_master(upper_dev)) { 4562 if (!netif_is_bridge_master(upper_dev)) {
4983 NL_SET_ERR_MSG(extack, "spectrum: VLAN devices only support bridge and VRF uppers"); 4563 NL_SET_ERR_MSG_MOD(extack, "VLAN devices only support bridge and VRF uppers");
4984 return -EINVAL; 4564 return -EINVAL;
4985 } 4565 }
4986 if (!info->linking) 4566 if (!info->linking)
@@ -4989,7 +4569,7 @@ static int mlxsw_sp_netdevice_port_vlan_event(struct net_device *vlan_dev,
4989 (!netif_is_bridge_master(upper_dev) || 4569 (!netif_is_bridge_master(upper_dev) ||
4990 !mlxsw_sp_bridge_device_is_offloaded(mlxsw_sp, 4570 !mlxsw_sp_bridge_device_is_offloaded(mlxsw_sp,
4991 upper_dev))) { 4571 upper_dev))) {
4992 NL_SET_ERR_MSG(extack, "spectrum: Enslaving a port to a device that already has an upper device is not supported"); 4572 NL_SET_ERR_MSG_MOD(extack, "Enslaving a port to a device that already has an upper device is not supported");
4993 return -EINVAL; 4573 return -EINVAL;
4994 } 4574 }
4995 break; 4575 break;
@@ -5067,10 +4647,18 @@ static int mlxsw_sp_netdevice_event(struct notifier_block *nb,
5067 unsigned long event, void *ptr) 4647 unsigned long event, void *ptr)
5068{ 4648{
5069 struct net_device *dev = netdev_notifier_info_to_dev(ptr); 4649 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
4650 struct mlxsw_sp_span_entry *span_entry;
5070 struct mlxsw_sp *mlxsw_sp; 4651 struct mlxsw_sp *mlxsw_sp;
5071 int err = 0; 4652 int err = 0;
5072 4653
5073 mlxsw_sp = container_of(nb, struct mlxsw_sp, netdevice_nb); 4654 mlxsw_sp = container_of(nb, struct mlxsw_sp, netdevice_nb);
4655 if (event == NETDEV_UNREGISTER) {
4656 span_entry = mlxsw_sp_span_entry_find_by_port(mlxsw_sp, dev);
4657 if (span_entry)
4658 mlxsw_sp_span_entry_invalidate(mlxsw_sp, span_entry);
4659 }
4660 mlxsw_sp_span_respin(mlxsw_sp);
4661
5074 if (mlxsw_sp_netdev_is_ipip_ol(mlxsw_sp, dev)) 4662 if (mlxsw_sp_netdev_is_ipip_ol(mlxsw_sp, dev))
5075 err = mlxsw_sp_netdevice_ipip_ol_event(mlxsw_sp, dev, 4663 err = mlxsw_sp_netdevice_ipip_ol_event(mlxsw_sp, dev,
5076 event, ptr); 4664 event, ptr);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
index 92064db2ae44..21bee8f19894 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
@@ -70,16 +70,23 @@
70#define MLXSW_SP_RESOURCE_NAME_KVD_LINEAR "linear" 70#define MLXSW_SP_RESOURCE_NAME_KVD_LINEAR "linear"
71#define MLXSW_SP_RESOURCE_NAME_KVD_HASH_SINGLE "hash_single" 71#define MLXSW_SP_RESOURCE_NAME_KVD_HASH_SINGLE "hash_single"
72#define MLXSW_SP_RESOURCE_NAME_KVD_HASH_DOUBLE "hash_double" 72#define MLXSW_SP_RESOURCE_NAME_KVD_HASH_DOUBLE "hash_double"
73#define MLXSW_SP_RESOURCE_NAME_KVD_LINEAR_SINGLES "singles"
74#define MLXSW_SP_RESOURCE_NAME_KVD_LINEAR_CHUNKS "chunks"
75#define MLXSW_SP_RESOURCE_NAME_KVD_LINEAR_LARGE_CHUNKS "large_chunks"
73 76
74enum mlxsw_sp_resource_id { 77enum mlxsw_sp_resource_id {
75 MLXSW_SP_RESOURCE_KVD, 78 MLXSW_SP_RESOURCE_KVD,
76 MLXSW_SP_RESOURCE_KVD_LINEAR, 79 MLXSW_SP_RESOURCE_KVD_LINEAR,
77 MLXSW_SP_RESOURCE_KVD_HASH_SINGLE, 80 MLXSW_SP_RESOURCE_KVD_HASH_SINGLE,
78 MLXSW_SP_RESOURCE_KVD_HASH_DOUBLE, 81 MLXSW_SP_RESOURCE_KVD_HASH_DOUBLE,
82 MLXSW_SP_RESOURCE_KVD_LINEAR_SINGLE,
83 MLXSW_SP_RESOURCE_KVD_LINEAR_CHUNKS,
84 MLXSW_SP_RESOURCE_KVD_LINEAR_LARGE_CHUNKS,
79}; 85};
80 86
81struct mlxsw_sp_port; 87struct mlxsw_sp_port;
82struct mlxsw_sp_rif; 88struct mlxsw_sp_rif;
89struct mlxsw_sp_span_entry;
83 90
84struct mlxsw_sp_upper { 91struct mlxsw_sp_upper {
85 struct net_device *dev; 92 struct net_device *dev;
@@ -111,35 +118,13 @@ struct mlxsw_sp_mid {
111 unsigned long *ports_in_mid; /* bits array */ 118 unsigned long *ports_in_mid; /* bits array */
112}; 119};
113 120
114enum mlxsw_sp_span_type {
115 MLXSW_SP_SPAN_EGRESS,
116 MLXSW_SP_SPAN_INGRESS
117};
118
119struct mlxsw_sp_span_inspected_port {
120 struct list_head list;
121 enum mlxsw_sp_span_type type;
122 u8 local_port;
123
124 /* Whether this is a directly bound mirror (port-to-port) or an ACL. */
125 bool bound;
126};
127
128struct mlxsw_sp_span_entry {
129 u8 local_port;
130 bool used;
131 struct list_head bound_ports_list;
132 int ref_count;
133 int id;
134};
135
136enum mlxsw_sp_port_mall_action_type { 121enum mlxsw_sp_port_mall_action_type {
137 MLXSW_SP_PORT_MALL_MIRROR, 122 MLXSW_SP_PORT_MALL_MIRROR,
138 MLXSW_SP_PORT_MALL_SAMPLE, 123 MLXSW_SP_PORT_MALL_SAMPLE,
139}; 124};
140 125
141struct mlxsw_sp_port_mall_mirror_tc_entry { 126struct mlxsw_sp_port_mall_mirror_tc_entry {
142 u8 to_local_port; 127 int span_id;
143 bool ingress; 128 bool ingress;
144}; 129};
145 130
@@ -226,6 +211,8 @@ struct mlxsw_sp_port_xstats {
226 u64 wred_drop[TC_MAX_QUEUE]; 211 u64 wred_drop[TC_MAX_QUEUE];
227 u64 tail_drop[TC_MAX_QUEUE]; 212 u64 tail_drop[TC_MAX_QUEUE];
228 u64 backlog[TC_MAX_QUEUE]; 213 u64 backlog[TC_MAX_QUEUE];
214 u64 tx_bytes[IEEE_8021QAZ_MAX_TCS];
215 u64 tx_packets[IEEE_8021QAZ_MAX_TCS];
229}; 216};
230 217
231struct mlxsw_sp_port { 218struct mlxsw_sp_port {
@@ -263,6 +250,7 @@ struct mlxsw_sp_port {
263 struct mlxsw_sp_port_sample *sample; 250 struct mlxsw_sp_port_sample *sample;
264 struct list_head vlans_list; 251 struct list_head vlans_list;
265 struct mlxsw_sp_qdisc *root_qdisc; 252 struct mlxsw_sp_qdisc *root_qdisc;
253 struct mlxsw_sp_qdisc *tclass_qdiscs;
266 unsigned acl_rule_count; 254 unsigned acl_rule_count;
267 struct mlxsw_sp_acl_block *ing_acl_block; 255 struct mlxsw_sp_acl_block *ing_acl_block;
268 struct mlxsw_sp_acl_block *eg_acl_block; 256 struct mlxsw_sp_acl_block *eg_acl_block;
@@ -400,16 +388,6 @@ struct mlxsw_sp_port *mlxsw_sp_port_dev_lower_find(struct net_device *dev);
400struct mlxsw_sp_port *mlxsw_sp_port_lower_dev_hold(struct net_device *dev); 388struct mlxsw_sp_port *mlxsw_sp_port_lower_dev_hold(struct net_device *dev);
401void mlxsw_sp_port_dev_put(struct mlxsw_sp_port *mlxsw_sp_port); 389void mlxsw_sp_port_dev_put(struct mlxsw_sp_port *mlxsw_sp_port);
402struct mlxsw_sp_port *mlxsw_sp_port_dev_lower_find_rcu(struct net_device *dev); 390struct mlxsw_sp_port *mlxsw_sp_port_dev_lower_find_rcu(struct net_device *dev);
403int mlxsw_sp_span_mirror_add(struct mlxsw_sp_port *from,
404 struct mlxsw_sp_port *to,
405 enum mlxsw_sp_span_type type,
406 bool bind);
407void mlxsw_sp_span_mirror_del(struct mlxsw_sp_port *from,
408 u8 destination_port,
409 enum mlxsw_sp_span_type type,
410 bool bind);
411struct mlxsw_sp_span_entry *
412mlxsw_sp_span_entry_find(struct mlxsw_sp *mlxsw_sp, u8 local_port);
413 391
414/* spectrum_dcb.c */ 392/* spectrum_dcb.c */
415#ifdef CONFIG_MLXSW_SPECTRUM_DCB 393#ifdef CONFIG_MLXSW_SPECTRUM_DCB
@@ -465,6 +443,7 @@ int mlxsw_sp_kvdl_alloc_size_query(struct mlxsw_sp *mlxsw_sp,
465 unsigned int entry_count, 443 unsigned int entry_count,
466 unsigned int *p_alloc_size); 444 unsigned int *p_alloc_size);
467u64 mlxsw_sp_kvdl_occ_get(const struct mlxsw_sp *mlxsw_sp); 445u64 mlxsw_sp_kvdl_occ_get(const struct mlxsw_sp *mlxsw_sp);
446int mlxsw_sp_kvdl_resources_register(struct devlink *devlink);
468 447
469struct mlxsw_sp_acl_rule_info { 448struct mlxsw_sp_acl_rule_info {
470 unsigned int priority; 449 unsigned int priority;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c
index 92d90ed7207e..79b1fa27a9a4 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c
@@ -160,6 +160,13 @@ bool mlxsw_sp_acl_block_disabled(struct mlxsw_sp_acl_block *block)
160 return block->disable_count; 160 return block->disable_count;
161} 161}
162 162
163static bool
164mlxsw_sp_acl_ruleset_is_singular(const struct mlxsw_sp_acl_ruleset *ruleset)
165{
166 /* We hold a reference on ruleset ourselves */
167 return ruleset->ref_count == 2;
168}
169
163static int 170static int
164mlxsw_sp_acl_ruleset_bind(struct mlxsw_sp *mlxsw_sp, 171mlxsw_sp_acl_ruleset_bind(struct mlxsw_sp *mlxsw_sp,
165 struct mlxsw_sp_acl_block *block, 172 struct mlxsw_sp_acl_block *block,
@@ -341,21 +348,8 @@ mlxsw_sp_acl_ruleset_create(struct mlxsw_sp *mlxsw_sp,
341 if (err) 348 if (err)
342 goto err_ht_insert; 349 goto err_ht_insert;
343 350
344 if (!chain_index) {
345 /* We only need ruleset with chain index 0, the implicit one,
346 * to be directly bound to device. The rest of the rulesets
347 * are bound by "Goto action set".
348 */
349 err = mlxsw_sp_acl_ruleset_block_bind(mlxsw_sp, ruleset, block);
350 if (err)
351 goto err_ruleset_bind;
352 }
353
354 return ruleset; 351 return ruleset;
355 352
356err_ruleset_bind:
357 rhashtable_remove_fast(&acl->ruleset_ht, &ruleset->ht_node,
358 mlxsw_sp_acl_ruleset_ht_params);
359err_ht_insert: 353err_ht_insert:
360 ops->ruleset_del(mlxsw_sp, ruleset->priv); 354 ops->ruleset_del(mlxsw_sp, ruleset->priv);
361err_ops_ruleset_add: 355err_ops_ruleset_add:
@@ -369,12 +363,8 @@ static void mlxsw_sp_acl_ruleset_destroy(struct mlxsw_sp *mlxsw_sp,
369 struct mlxsw_sp_acl_ruleset *ruleset) 363 struct mlxsw_sp_acl_ruleset *ruleset)
370{ 364{
371 const struct mlxsw_sp_acl_profile_ops *ops = ruleset->ht_key.ops; 365 const struct mlxsw_sp_acl_profile_ops *ops = ruleset->ht_key.ops;
372 struct mlxsw_sp_acl_block *block = ruleset->ht_key.block;
373 u32 chain_index = ruleset->ht_key.chain_index;
374 struct mlxsw_sp_acl *acl = mlxsw_sp->acl; 366 struct mlxsw_sp_acl *acl = mlxsw_sp->acl;
375 367
376 if (!chain_index)
377 mlxsw_sp_acl_ruleset_block_unbind(mlxsw_sp, ruleset, block);
378 rhashtable_remove_fast(&acl->ruleset_ht, &ruleset->ht_node, 368 rhashtable_remove_fast(&acl->ruleset_ht, &ruleset->ht_node,
379 mlxsw_sp_acl_ruleset_ht_params); 369 mlxsw_sp_acl_ruleset_ht_params);
380 ops->ruleset_del(mlxsw_sp, ruleset->priv); 370 ops->ruleset_del(mlxsw_sp, ruleset->priv);
@@ -577,7 +567,6 @@ int mlxsw_sp_acl_rulei_act_mirror(struct mlxsw_sp *mlxsw_sp,
577 struct net_device *out_dev) 567 struct net_device *out_dev)
578{ 568{
579 struct mlxsw_sp_acl_block_binding *binding; 569 struct mlxsw_sp_acl_block_binding *binding;
580 struct mlxsw_sp_port *out_port;
581 struct mlxsw_sp_port *in_port; 570 struct mlxsw_sp_port *in_port;
582 571
583 if (!list_is_singular(&block->binding_list)) 572 if (!list_is_singular(&block->binding_list))
@@ -586,16 +575,10 @@ int mlxsw_sp_acl_rulei_act_mirror(struct mlxsw_sp *mlxsw_sp,
586 binding = list_first_entry(&block->binding_list, 575 binding = list_first_entry(&block->binding_list,
587 struct mlxsw_sp_acl_block_binding, list); 576 struct mlxsw_sp_acl_block_binding, list);
588 in_port = binding->mlxsw_sp_port; 577 in_port = binding->mlxsw_sp_port;
589 if (!mlxsw_sp_port_dev_check(out_dev))
590 return -EINVAL;
591
592 out_port = netdev_priv(out_dev);
593 if (out_port->mlxsw_sp != mlxsw_sp)
594 return -EINVAL;
595 578
596 return mlxsw_afa_block_append_mirror(rulei->act_block, 579 return mlxsw_afa_block_append_mirror(rulei->act_block,
597 in_port->local_port, 580 in_port->local_port,
598 out_port->local_port, 581 out_dev,
599 binding->ingress); 582 binding->ingress);
600} 583}
601 584
@@ -700,10 +683,25 @@ int mlxsw_sp_acl_rule_add(struct mlxsw_sp *mlxsw_sp,
700 if (err) 683 if (err)
701 goto err_rhashtable_insert; 684 goto err_rhashtable_insert;
702 685
686 if (!ruleset->ht_key.chain_index &&
687 mlxsw_sp_acl_ruleset_is_singular(ruleset)) {
688 /* We only need ruleset with chain index 0, the implicit
689 * one, to be directly bound to device. The rest of the
690 * rulesets are bound by "Goto action set".
691 */
692 err = mlxsw_sp_acl_ruleset_block_bind(mlxsw_sp, ruleset,
693 ruleset->ht_key.block);
694 if (err)
695 goto err_ruleset_block_bind;
696 }
697
703 list_add_tail(&rule->list, &mlxsw_sp->acl->rules); 698 list_add_tail(&rule->list, &mlxsw_sp->acl->rules);
704 ruleset->ht_key.block->rule_count++; 699 ruleset->ht_key.block->rule_count++;
705 return 0; 700 return 0;
706 701
702err_ruleset_block_bind:
703 rhashtable_remove_fast(&ruleset->rule_ht, &rule->ht_node,
704 mlxsw_sp_acl_rule_ht_params);
707err_rhashtable_insert: 705err_rhashtable_insert:
708 ops->rule_del(mlxsw_sp, rule->priv); 706 ops->rule_del(mlxsw_sp, rule->priv);
709 return err; 707 return err;
@@ -717,6 +715,10 @@ void mlxsw_sp_acl_rule_del(struct mlxsw_sp *mlxsw_sp,
717 715
718 ruleset->ht_key.block->rule_count--; 716 ruleset->ht_key.block->rule_count--;
719 list_del(&rule->list); 717 list_del(&rule->list);
718 if (!ruleset->ht_key.chain_index &&
719 mlxsw_sp_acl_ruleset_is_singular(ruleset))
720 mlxsw_sp_acl_ruleset_block_unbind(mlxsw_sp, ruleset,
721 ruleset->ht_key.block);
720 rhashtable_remove_fast(&ruleset->rule_ht, &rule->ht_node, 722 rhashtable_remove_fast(&ruleset->rule_ht, &rule->ht_node,
721 mlxsw_sp_acl_rule_ht_params); 723 mlxsw_sp_acl_rule_ht_params);
722 ops->rule_del(mlxsw_sp, rule->priv); 724 ops->rule_del(mlxsw_sp, rule->priv);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_actions.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_actions.c
index 6ca6894125f0..510ce48d87f7 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_actions.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_actions.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_actions.c 2 * drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_actions.c
3 * Copyright (c) 2017 Mellanox Technologies. All rights reserved. 3 * Copyright (c) 2017, 2018 Mellanox Technologies. All rights reserved.
4 * Copyright (c) 2017 Jiri Pirko <jiri@mellanox.com> 4 * Copyright (c) 2017 Jiri Pirko <jiri@mellanox.com>
5 * Copyright (c) 2017 Yotam Gigi <yotamg@mellanox.com> 5 * Copyright (c) 2017 Yotam Gigi <yotamg@mellanox.com>
6 * 6 *
@@ -35,6 +35,7 @@
35 35
36#include "spectrum_acl_flex_actions.h" 36#include "spectrum_acl_flex_actions.h"
37#include "core_acl_flex_actions.h" 37#include "core_acl_flex_actions.h"
38#include "spectrum_span.h"
38 39
39#define MLXSW_SP_KVDL_ACT_EXT_SIZE 1 40#define MLXSW_SP_KVDL_ACT_EXT_SIZE 1
40 41
@@ -125,40 +126,23 @@ mlxsw_sp_act_counter_index_put(void *priv, unsigned int counter_index)
125} 126}
126 127
127static int 128static int
128mlxsw_sp_act_mirror_add(void *priv, u8 local_in_port, u8 local_out_port, 129mlxsw_sp_act_mirror_add(void *priv, u8 local_in_port,
130 const struct net_device *out_dev,
129 bool ingress, int *p_span_id) 131 bool ingress, int *p_span_id)
130{ 132{
131 struct mlxsw_sp_port *in_port, *out_port; 133 struct mlxsw_sp_port *in_port;
132 struct mlxsw_sp_span_entry *span_entry;
133 struct mlxsw_sp *mlxsw_sp = priv; 134 struct mlxsw_sp *mlxsw_sp = priv;
134 enum mlxsw_sp_span_type type; 135 enum mlxsw_sp_span_type type;
135 int err;
136 136
137 type = ingress ? MLXSW_SP_SPAN_INGRESS : MLXSW_SP_SPAN_EGRESS; 137 type = ingress ? MLXSW_SP_SPAN_INGRESS : MLXSW_SP_SPAN_EGRESS;
138 out_port = mlxsw_sp->ports[local_out_port];
139 in_port = mlxsw_sp->ports[local_in_port]; 138 in_port = mlxsw_sp->ports[local_in_port];
140 139
141 err = mlxsw_sp_span_mirror_add(in_port, out_port, type, false); 140 return mlxsw_sp_span_mirror_add(in_port, out_dev, type,
142 if (err) 141 false, p_span_id);
143 return err;
144
145 span_entry = mlxsw_sp_span_entry_find(mlxsw_sp, local_out_port);
146 if (!span_entry) {
147 err = -ENOENT;
148 goto err_span_entry_find;
149 }
150
151 *p_span_id = span_entry->id;
152 return 0;
153
154err_span_entry_find:
155 mlxsw_sp_span_mirror_del(in_port, local_out_port, type, false);
156 return err;
157} 142}
158 143
159static void 144static void
160mlxsw_sp_act_mirror_del(void *priv, u8 local_in_port, u8 local_out_port, 145mlxsw_sp_act_mirror_del(void *priv, u8 local_in_port, int span_id, bool ingress)
161 bool ingress)
162{ 146{
163 struct mlxsw_sp *mlxsw_sp = priv; 147 struct mlxsw_sp *mlxsw_sp = priv;
164 struct mlxsw_sp_port *in_port; 148 struct mlxsw_sp_port *in_port;
@@ -167,7 +151,7 @@ mlxsw_sp_act_mirror_del(void *priv, u8 local_in_port, u8 local_out_port,
167 type = ingress ? MLXSW_SP_SPAN_INGRESS : MLXSW_SP_SPAN_EGRESS; 151 type = ingress ? MLXSW_SP_SPAN_INGRESS : MLXSW_SP_SPAN_EGRESS;
168 in_port = mlxsw_sp->ports[local_in_port]; 152 in_port = mlxsw_sp->ports[local_in_port];
169 153
170 mlxsw_sp_span_mirror_del(in_port, local_out_port, type, false); 154 mlxsw_sp_span_mirror_del(in_port, span_id, type, false);
171} 155}
172 156
173static const struct mlxsw_afa_ops mlxsw_sp_act_afa_ops = { 157static const struct mlxsw_afa_ops mlxsw_sp_act_afa_ops = {
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
index c6e180c2be1e..ad1b548e3cac 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
@@ -228,10 +228,6 @@ mlxsw_sp_acl_tcam_group_add(struct mlxsw_sp *mlxsw_sp,
228 if (err) 228 if (err)
229 return err; 229 return err;
230 230
231 err = mlxsw_sp_acl_tcam_group_update(mlxsw_sp, group);
232 if (err)
233 goto err_group_update;
234
235 err = rhashtable_init(&group->chunk_ht, 231 err = rhashtable_init(&group->chunk_ht,
236 &mlxsw_sp_acl_tcam_chunk_ht_params); 232 &mlxsw_sp_acl_tcam_chunk_ht_params);
237 if (err) 233 if (err)
@@ -240,7 +236,6 @@ mlxsw_sp_acl_tcam_group_add(struct mlxsw_sp *mlxsw_sp,
240 return 0; 236 return 0;
241 237
242err_rhashtable_init: 238err_rhashtable_init:
243err_group_update:
244 mlxsw_sp_acl_tcam_group_id_put(tcam, group->id); 239 mlxsw_sp_acl_tcam_group_id_put(tcam, group->id);
245 return err; 240 return err;
246} 241}
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.c
index 7502e53447bd..98d896c14b87 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.c 2 * drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.c
3 * Copyright (c) 2017 Mellanox Technologies. All rights reserved. 3 * Copyright (c) 2017-2018 Mellanox Technologies. All rights reserved.
4 * Copyright (c) 2017 Petr Machata <petrm@mellanox.com> 4 * Copyright (c) 2017-2018 Petr Machata <petrm@mellanox.com>
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met: 7 * modification, are permitted provided that the following conditions are met:
@@ -33,126 +33,125 @@
33 */ 33 */
34 34
35#include <net/ip_tunnels.h> 35#include <net/ip_tunnels.h>
36#include <net/ip6_tunnel.h>
36 37
37#include "spectrum_ipip.h" 38#include "spectrum_ipip.h"
38 39
39struct ip_tunnel_parm 40struct ip_tunnel_parm
40mlxsw_sp_ipip_netdev_parms(const struct net_device *ol_dev) 41mlxsw_sp_ipip_netdev_parms4(const struct net_device *ol_dev)
41{ 42{
42 struct ip_tunnel *tun = netdev_priv(ol_dev); 43 struct ip_tunnel *tun = netdev_priv(ol_dev);
43 44
44 return tun->parms; 45 return tun->parms;
45} 46}
46 47
47static bool mlxsw_sp_ipip_parms_has_ikey(struct ip_tunnel_parm parms) 48struct __ip6_tnl_parm
49mlxsw_sp_ipip_netdev_parms6(const struct net_device *ol_dev)
50{
51 struct ip6_tnl *tun = netdev_priv(ol_dev);
52
53 return tun->parms;
54}
55
56static bool mlxsw_sp_ipip_parms4_has_ikey(struct ip_tunnel_parm parms)
48{ 57{
49 return !!(parms.i_flags & TUNNEL_KEY); 58 return !!(parms.i_flags & TUNNEL_KEY);
50} 59}
51 60
52static bool mlxsw_sp_ipip_parms_has_okey(struct ip_tunnel_parm parms) 61static bool mlxsw_sp_ipip_parms4_has_okey(struct ip_tunnel_parm parms)
53{ 62{
54 return !!(parms.o_flags & TUNNEL_KEY); 63 return !!(parms.o_flags & TUNNEL_KEY);
55} 64}
56 65
57static u32 mlxsw_sp_ipip_parms_ikey(struct ip_tunnel_parm parms) 66static u32 mlxsw_sp_ipip_parms4_ikey(struct ip_tunnel_parm parms)
58{ 67{
59 return mlxsw_sp_ipip_parms_has_ikey(parms) ? 68 return mlxsw_sp_ipip_parms4_has_ikey(parms) ?
60 be32_to_cpu(parms.i_key) : 0; 69 be32_to_cpu(parms.i_key) : 0;
61} 70}
62 71
63static u32 mlxsw_sp_ipip_parms_okey(struct ip_tunnel_parm parms) 72static u32 mlxsw_sp_ipip_parms4_okey(struct ip_tunnel_parm parms)
64{ 73{
65 return mlxsw_sp_ipip_parms_has_okey(parms) ? 74 return mlxsw_sp_ipip_parms4_has_okey(parms) ?
66 be32_to_cpu(parms.o_key) : 0; 75 be32_to_cpu(parms.o_key) : 0;
67} 76}
68 77
69static __be32 mlxsw_sp_ipip_parms_saddr4(struct ip_tunnel_parm parms) 78static union mlxsw_sp_l3addr
79mlxsw_sp_ipip_parms4_saddr(struct ip_tunnel_parm parms)
70{ 80{
71 return parms.iph.saddr; 81 return (union mlxsw_sp_l3addr) { .addr4 = parms.iph.saddr };
72} 82}
73 83
74static union mlxsw_sp_l3addr 84static union mlxsw_sp_l3addr
75mlxsw_sp_ipip_parms_saddr(enum mlxsw_sp_l3proto proto, 85mlxsw_sp_ipip_parms6_saddr(struct __ip6_tnl_parm parms)
76 struct ip_tunnel_parm parms)
77{ 86{
78 switch (proto) { 87 return (union mlxsw_sp_l3addr) { .addr6 = parms.laddr };
79 case MLXSW_SP_L3_PROTO_IPV4:
80 return (union mlxsw_sp_l3addr) {
81 .addr4 = mlxsw_sp_ipip_parms_saddr4(parms),
82 };
83 case MLXSW_SP_L3_PROTO_IPV6:
84 break;
85 }
86
87 WARN_ON(1);
88 return (union mlxsw_sp_l3addr) {
89 .addr4 = 0,
90 };
91} 88}
92 89
93static __be32 mlxsw_sp_ipip_parms_daddr4(struct ip_tunnel_parm parms) 90static union mlxsw_sp_l3addr
91mlxsw_sp_ipip_parms4_daddr(struct ip_tunnel_parm parms)
94{ 92{
95 return parms.iph.daddr; 93 return (union mlxsw_sp_l3addr) { .addr4 = parms.iph.daddr };
96} 94}
97 95
98static union mlxsw_sp_l3addr 96static union mlxsw_sp_l3addr
99mlxsw_sp_ipip_parms_daddr(enum mlxsw_sp_l3proto proto, 97mlxsw_sp_ipip_parms6_daddr(struct __ip6_tnl_parm parms)
100 struct ip_tunnel_parm parms) 98{
99 return (union mlxsw_sp_l3addr) { .addr6 = parms.raddr };
100}
101
102union mlxsw_sp_l3addr
103mlxsw_sp_ipip_netdev_saddr(enum mlxsw_sp_l3proto proto,
104 const struct net_device *ol_dev)
101{ 105{
106 struct ip_tunnel_parm parms4;
107 struct __ip6_tnl_parm parms6;
108
102 switch (proto) { 109 switch (proto) {
103 case MLXSW_SP_L3_PROTO_IPV4: 110 case MLXSW_SP_L3_PROTO_IPV4:
104 return (union mlxsw_sp_l3addr) { 111 parms4 = mlxsw_sp_ipip_netdev_parms4(ol_dev);
105 .addr4 = mlxsw_sp_ipip_parms_daddr4(parms), 112 return mlxsw_sp_ipip_parms4_saddr(parms4);
106 };
107 case MLXSW_SP_L3_PROTO_IPV6: 113 case MLXSW_SP_L3_PROTO_IPV6:
108 break; 114 parms6 = mlxsw_sp_ipip_netdev_parms6(ol_dev);
115 return mlxsw_sp_ipip_parms6_saddr(parms6);
109 } 116 }
110 117
111 WARN_ON(1); 118 WARN_ON(1);
112 return (union mlxsw_sp_l3addr) { 119 return (union mlxsw_sp_l3addr) {0};
113 .addr4 = 0,
114 };
115}
116
117static bool mlxsw_sp_ipip_netdev_has_ikey(const struct net_device *ol_dev)
118{
119 return mlxsw_sp_ipip_parms_has_ikey(mlxsw_sp_ipip_netdev_parms(ol_dev));
120} 120}
121 121
122static bool mlxsw_sp_ipip_netdev_has_okey(const struct net_device *ol_dev) 122static __be32 mlxsw_sp_ipip_netdev_daddr4(const struct net_device *ol_dev)
123{ 123{
124 return mlxsw_sp_ipip_parms_has_okey(mlxsw_sp_ipip_netdev_parms(ol_dev));
125}
126 124
127static u32 mlxsw_sp_ipip_netdev_ikey(const struct net_device *ol_dev) 125 struct ip_tunnel_parm parms4 = mlxsw_sp_ipip_netdev_parms4(ol_dev);
128{
129 return mlxsw_sp_ipip_parms_ikey(mlxsw_sp_ipip_netdev_parms(ol_dev));
130}
131 126
132static u32 mlxsw_sp_ipip_netdev_okey(const struct net_device *ol_dev) 127 return mlxsw_sp_ipip_parms4_daddr(parms4).addr4;
133{
134 return mlxsw_sp_ipip_parms_okey(mlxsw_sp_ipip_netdev_parms(ol_dev));
135} 128}
136 129
137union mlxsw_sp_l3addr 130static union mlxsw_sp_l3addr
138mlxsw_sp_ipip_netdev_saddr(enum mlxsw_sp_l3proto proto, 131mlxsw_sp_ipip_netdev_daddr(enum mlxsw_sp_l3proto proto,
139 const struct net_device *ol_dev) 132 const struct net_device *ol_dev)
140{ 133{
141 return mlxsw_sp_ipip_parms_saddr(proto, 134 struct ip_tunnel_parm parms4;
142 mlxsw_sp_ipip_netdev_parms(ol_dev)); 135 struct __ip6_tnl_parm parms6;
143}
144 136
145static __be32 mlxsw_sp_ipip_netdev_daddr4(const struct net_device *ol_dev) 137 switch (proto) {
146{ 138 case MLXSW_SP_L3_PROTO_IPV4:
147 return mlxsw_sp_ipip_parms_daddr4(mlxsw_sp_ipip_netdev_parms(ol_dev)); 139 parms4 = mlxsw_sp_ipip_netdev_parms4(ol_dev);
140 return mlxsw_sp_ipip_parms4_daddr(parms4);
141 case MLXSW_SP_L3_PROTO_IPV6:
142 parms6 = mlxsw_sp_ipip_netdev_parms6(ol_dev);
143 return mlxsw_sp_ipip_parms6_daddr(parms6);
144 }
145
146 WARN_ON(1);
147 return (union mlxsw_sp_l3addr) {0};
148} 148}
149 149
150static union mlxsw_sp_l3addr 150bool mlxsw_sp_l3addr_is_zero(union mlxsw_sp_l3addr addr)
151mlxsw_sp_ipip_netdev_daddr(enum mlxsw_sp_l3proto proto,
152 const struct net_device *ol_dev)
153{ 151{
154 return mlxsw_sp_ipip_parms_daddr(proto, 152 union mlxsw_sp_l3addr naddr = {0};
155 mlxsw_sp_ipip_netdev_parms(ol_dev)); 153
154 return !memcmp(&addr, &naddr, sizeof(naddr));
156} 155}
157 156
158static int 157static int
@@ -176,12 +175,17 @@ mlxsw_sp_ipip_fib_entry_op_gre4_rtdp(struct mlxsw_sp *mlxsw_sp,
176 u32 tunnel_index, 175 u32 tunnel_index,
177 struct mlxsw_sp_ipip_entry *ipip_entry) 176 struct mlxsw_sp_ipip_entry *ipip_entry)
178{ 177{
179 bool has_ikey = mlxsw_sp_ipip_netdev_has_ikey(ipip_entry->ol_dev);
180 u16 rif_index = mlxsw_sp_ipip_lb_rif_index(ipip_entry->ol_lb); 178 u16 rif_index = mlxsw_sp_ipip_lb_rif_index(ipip_entry->ol_lb);
181 u32 ikey = mlxsw_sp_ipip_netdev_ikey(ipip_entry->ol_dev);
182 char rtdp_pl[MLXSW_REG_RTDP_LEN]; 179 char rtdp_pl[MLXSW_REG_RTDP_LEN];
180 struct ip_tunnel_parm parms;
183 unsigned int type_check; 181 unsigned int type_check;
182 bool has_ikey;
184 u32 daddr4; 183 u32 daddr4;
184 u32 ikey;
185
186 parms = mlxsw_sp_ipip_netdev_parms4(ipip_entry->ol_dev);
187 has_ikey = mlxsw_sp_ipip_parms4_has_ikey(parms);
188 ikey = mlxsw_sp_ipip_parms4_ikey(parms);
185 189
186 mlxsw_reg_rtdp_pack(rtdp_pl, MLXSW_REG_RTDP_TYPE_IPIP, tunnel_index); 190 mlxsw_reg_rtdp_pack(rtdp_pl, MLXSW_REG_RTDP_TYPE_IPIP, tunnel_index);
187 191
@@ -243,15 +247,14 @@ static bool mlxsw_sp_ipip_tunnel_complete(enum mlxsw_sp_l3proto proto,
243{ 247{
244 union mlxsw_sp_l3addr saddr = mlxsw_sp_ipip_netdev_saddr(proto, ol_dev); 248 union mlxsw_sp_l3addr saddr = mlxsw_sp_ipip_netdev_saddr(proto, ol_dev);
245 union mlxsw_sp_l3addr daddr = mlxsw_sp_ipip_netdev_daddr(proto, ol_dev); 249 union mlxsw_sp_l3addr daddr = mlxsw_sp_ipip_netdev_daddr(proto, ol_dev);
246 union mlxsw_sp_l3addr naddr = {0};
247 250
248 /* Tunnels with unset local or remote address are valid in Linux and 251 /* Tunnels with unset local or remote address are valid in Linux and
249 * used for lightweight tunnels (LWT) and Non-Broadcast Multi-Access 252 * used for lightweight tunnels (LWT) and Non-Broadcast Multi-Access
250 * (NBMA) tunnels. In principle these can be offloaded, but the driver 253 * (NBMA) tunnels. In principle these can be offloaded, but the driver
251 * currently doesn't support this. So punt. 254 * currently doesn't support this. So punt.
252 */ 255 */
253 return memcmp(&saddr, &naddr, sizeof(naddr)) && 256 return !mlxsw_sp_l3addr_is_zero(saddr) &&
254 memcmp(&daddr, &naddr, sizeof(naddr)); 257 !mlxsw_sp_l3addr_is_zero(daddr);
255} 258}
256 259
257static bool mlxsw_sp_ipip_can_offload_gre4(const struct mlxsw_sp *mlxsw_sp, 260static bool mlxsw_sp_ipip_can_offload_gre4(const struct mlxsw_sp *mlxsw_sp,
@@ -273,14 +276,15 @@ static struct mlxsw_sp_rif_ipip_lb_config
273mlxsw_sp_ipip_ol_loopback_config_gre4(struct mlxsw_sp *mlxsw_sp, 276mlxsw_sp_ipip_ol_loopback_config_gre4(struct mlxsw_sp *mlxsw_sp,
274 const struct net_device *ol_dev) 277 const struct net_device *ol_dev)
275{ 278{
279 struct ip_tunnel_parm parms = mlxsw_sp_ipip_netdev_parms4(ol_dev);
276 enum mlxsw_reg_ritr_loopback_ipip_type lb_ipipt; 280 enum mlxsw_reg_ritr_loopback_ipip_type lb_ipipt;
277 281
278 lb_ipipt = mlxsw_sp_ipip_netdev_has_okey(ol_dev) ? 282 lb_ipipt = mlxsw_sp_ipip_parms4_has_okey(parms) ?
279 MLXSW_REG_RITR_LOOPBACK_IPIP_TYPE_IP_IN_GRE_KEY_IN_IP : 283 MLXSW_REG_RITR_LOOPBACK_IPIP_TYPE_IP_IN_GRE_KEY_IN_IP :
280 MLXSW_REG_RITR_LOOPBACK_IPIP_TYPE_IP_IN_GRE_IN_IP; 284 MLXSW_REG_RITR_LOOPBACK_IPIP_TYPE_IP_IN_GRE_IN_IP;
281 return (struct mlxsw_sp_rif_ipip_lb_config){ 285 return (struct mlxsw_sp_rif_ipip_lb_config){
282 .lb_ipipt = lb_ipipt, 286 .lb_ipipt = lb_ipipt,
283 .okey = mlxsw_sp_ipip_netdev_okey(ol_dev), 287 .okey = mlxsw_sp_ipip_parms4_okey(parms),
284 .ul_protocol = MLXSW_SP_L3_PROTO_IPV4, 288 .ul_protocol = MLXSW_SP_L3_PROTO_IPV4,
285 .saddr = mlxsw_sp_ipip_netdev_saddr(MLXSW_SP_L3_PROTO_IPV4, 289 .saddr = mlxsw_sp_ipip_netdev_saddr(MLXSW_SP_L3_PROTO_IPV4,
286 ol_dev), 290 ol_dev),
@@ -300,16 +304,12 @@ mlxsw_sp_ipip_ol_netdev_change_gre4(struct mlxsw_sp *mlxsw_sp,
300 bool update_nhs = false; 304 bool update_nhs = false;
301 int err = 0; 305 int err = 0;
302 306
303 new_parms = mlxsw_sp_ipip_netdev_parms(ipip_entry->ol_dev); 307 new_parms = mlxsw_sp_ipip_netdev_parms4(ipip_entry->ol_dev);
304 308
305 new_saddr = mlxsw_sp_ipip_parms_saddr(MLXSW_SP_L3_PROTO_IPV4, 309 new_saddr = mlxsw_sp_ipip_parms4_saddr(new_parms);
306 new_parms); 310 old_saddr = mlxsw_sp_ipip_parms4_saddr(ipip_entry->parms4);
307 old_saddr = mlxsw_sp_ipip_parms_saddr(MLXSW_SP_L3_PROTO_IPV4, 311 new_daddr = mlxsw_sp_ipip_parms4_daddr(new_parms);
308 ipip_entry->parms); 312 old_daddr = mlxsw_sp_ipip_parms4_daddr(ipip_entry->parms4);
309 new_daddr = mlxsw_sp_ipip_parms_daddr(MLXSW_SP_L3_PROTO_IPV4,
310 new_parms);
311 old_daddr = mlxsw_sp_ipip_parms_daddr(MLXSW_SP_L3_PROTO_IPV4,
312 ipip_entry->parms);
313 313
314 if (!mlxsw_sp_l3addr_eq(&new_saddr, &old_saddr)) { 314 if (!mlxsw_sp_l3addr_eq(&new_saddr, &old_saddr)) {
315 u16 ul_tb_id = mlxsw_sp_ipip_dev_ul_tb_id(ipip_entry->ol_dev); 315 u16 ul_tb_id = mlxsw_sp_ipip_dev_ul_tb_id(ipip_entry->ol_dev);
@@ -326,14 +326,14 @@ mlxsw_sp_ipip_ol_netdev_change_gre4(struct mlxsw_sp *mlxsw_sp,
326 } 326 }
327 327
328 update_tunnel = true; 328 update_tunnel = true;
329 } else if ((mlxsw_sp_ipip_parms_okey(ipip_entry->parms) != 329 } else if ((mlxsw_sp_ipip_parms4_okey(ipip_entry->parms4) !=
330 mlxsw_sp_ipip_parms_okey(new_parms)) || 330 mlxsw_sp_ipip_parms4_okey(new_parms)) ||
331 ipip_entry->parms.link != new_parms.link) { 331 ipip_entry->parms4.link != new_parms.link) {
332 update_tunnel = true; 332 update_tunnel = true;
333 } else if (!mlxsw_sp_l3addr_eq(&new_daddr, &old_daddr)) { 333 } else if (!mlxsw_sp_l3addr_eq(&new_daddr, &old_daddr)) {
334 update_nhs = true; 334 update_nhs = true;
335 } else if (mlxsw_sp_ipip_parms_ikey(ipip_entry->parms) != 335 } else if (mlxsw_sp_ipip_parms4_ikey(ipip_entry->parms4) !=
336 mlxsw_sp_ipip_parms_ikey(new_parms)) { 336 mlxsw_sp_ipip_parms4_ikey(new_parms)) {
337 update_decap = true; 337 update_decap = true;
338 } 338 }
339 339
@@ -350,7 +350,7 @@ mlxsw_sp_ipip_ol_netdev_change_gre4(struct mlxsw_sp *mlxsw_sp,
350 false, false, false, 350 false, false, false,
351 extack); 351 extack);
352 352
353 ipip_entry->parms = new_parms; 353 ipip_entry->parms4 = new_parms;
354 return err; 354 return err;
355} 355}
356 356
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.h
index 04b08d9d76e9..6909d867bb59 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.h 2 * drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.h
3 * Copyright (c) 2017 Mellanox Technologies. All rights reserved. 3 * Copyright (c) 2017-2018 Mellanox Technologies. All rights reserved.
4 * Copyright (c) 2017 Petr Machata <petrm@mellanox.com> 4 * Copyright (c) 2017-2018 Petr Machata <petrm@mellanox.com>
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met: 7 * modification, are permitted provided that the following conditions are met:
@@ -37,14 +37,19 @@
37 37
38#include "spectrum_router.h" 38#include "spectrum_router.h"
39#include <net/ip_fib.h> 39#include <net/ip_fib.h>
40#include <linux/if_tunnel.h>
40 41
41struct ip_tunnel_parm 42struct ip_tunnel_parm
42mlxsw_sp_ipip_netdev_parms(const struct net_device *ol_dev); 43mlxsw_sp_ipip_netdev_parms4(const struct net_device *ol_dev);
44struct __ip6_tnl_parm
45mlxsw_sp_ipip_netdev_parms6(const struct net_device *ol_dev);
43 46
44union mlxsw_sp_l3addr 47union mlxsw_sp_l3addr
45mlxsw_sp_ipip_netdev_saddr(enum mlxsw_sp_l3proto proto, 48mlxsw_sp_ipip_netdev_saddr(enum mlxsw_sp_l3proto proto,
46 const struct net_device *ol_dev); 49 const struct net_device *ol_dev);
47 50
51bool mlxsw_sp_l3addr_is_zero(union mlxsw_sp_l3addr addr);
52
48enum mlxsw_sp_ipip_type { 53enum mlxsw_sp_ipip_type {
49 MLXSW_SP_IPIP_TYPE_GRE4, 54 MLXSW_SP_IPIP_TYPE_GRE4,
50 MLXSW_SP_IPIP_TYPE_MAX, 55 MLXSW_SP_IPIP_TYPE_MAX,
@@ -56,7 +61,9 @@ struct mlxsw_sp_ipip_entry {
56 struct mlxsw_sp_rif_ipip_lb *ol_lb; 61 struct mlxsw_sp_rif_ipip_lb *ol_lb;
57 struct mlxsw_sp_fib_entry *decap_fib_entry; 62 struct mlxsw_sp_fib_entry *decap_fib_entry;
58 struct list_head ipip_list_node; 63 struct list_head ipip_list_node;
59 struct ip_tunnel_parm parms; 64 union {
65 struct ip_tunnel_parm parms4;
66 };
60}; 67};
61 68
62struct mlxsw_sp_ipip_ops { 69struct mlxsw_sp_ipip_ops {
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_kvdl.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_kvdl.c
index 55f9d2d70f9e..85503e93b93f 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_kvdl.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_kvdl.c
@@ -67,7 +67,7 @@ struct mlxsw_sp_kvdl_part_info {
67 67
68struct mlxsw_sp_kvdl_part { 68struct mlxsw_sp_kvdl_part {
69 struct list_head list; 69 struct list_head list;
70 const struct mlxsw_sp_kvdl_part_info *info; 70 struct mlxsw_sp_kvdl_part_info *info;
71 unsigned long usage[0]; /* Entries */ 71 unsigned long usage[0]; /* Entries */
72}; 72};
73 73
@@ -188,21 +188,27 @@ int mlxsw_sp_kvdl_alloc_size_query(struct mlxsw_sp *mlxsw_sp,
188 return 0; 188 return 0;
189} 189}
190 190
191enum mlxsw_sp_kvdl_part_id {
192 MLXSW_SP_KVDL_PART_SINGLE,
193 MLXSW_SP_KVDL_PART_CHUNKS,
194 MLXSW_SP_KVDL_PART_LARGE_CHUNKS,
195};
196
191static const struct mlxsw_sp_kvdl_part_info kvdl_parts_info[] = { 197static const struct mlxsw_sp_kvdl_part_info kvdl_parts_info[] = {
192 { 198 {
193 .part_index = 0, 199 .part_index = MLXSW_SP_KVDL_PART_SINGLE,
194 .start_index = MLXSW_SP_KVDL_SINGLE_BASE, 200 .start_index = MLXSW_SP_KVDL_SINGLE_BASE,
195 .end_index = MLXSW_SP_KVDL_SINGLE_END, 201 .end_index = MLXSW_SP_KVDL_SINGLE_END,
196 .alloc_size = 1, 202 .alloc_size = 1,
197 }, 203 },
198 { 204 {
199 .part_index = 1, 205 .part_index = MLXSW_SP_KVDL_PART_CHUNKS,
200 .start_index = MLXSW_SP_KVDL_CHUNKS_BASE, 206 .start_index = MLXSW_SP_KVDL_CHUNKS_BASE,
201 .end_index = MLXSW_SP_KVDL_CHUNKS_END, 207 .end_index = MLXSW_SP_KVDL_CHUNKS_END,
202 .alloc_size = MLXSW_SP_CHUNK_MAX, 208 .alloc_size = MLXSW_SP_CHUNK_MAX,
203 }, 209 },
204 { 210 {
205 .part_index = 2, 211 .part_index = MLXSW_SP_KVDL_PART_LARGE_CHUNKS,
206 .start_index = MLXSW_SP_KVDL_LARGE_CHUNKS_BASE, 212 .start_index = MLXSW_SP_KVDL_LARGE_CHUNKS_BASE,
207 .end_index = MLXSW_SP_KVDL_LARGE_CHUNKS_END, 213 .end_index = MLXSW_SP_KVDL_LARGE_CHUNKS_END,
208 .alloc_size = MLXSW_SP_LARGE_CHUNK_MAX, 214 .alloc_size = MLXSW_SP_LARGE_CHUNK_MAX,
@@ -222,27 +228,76 @@ mlxsw_sp_kvdl_part_find(struct mlxsw_sp *mlxsw_sp, unsigned int part_index)
222 return NULL; 228 return NULL;
223} 229}
224 230
231static void
232mlxsw_sp_kvdl_part_update(struct mlxsw_sp *mlxsw_sp,
233 struct mlxsw_sp_kvdl_part *part, unsigned int size)
234{
235 struct mlxsw_sp_kvdl_part_info *info = part->info;
236
237 if (list_is_last(&part->list, &mlxsw_sp->kvdl->parts_list)) {
238 info->end_index = size - 1;
239 } else {
240 struct mlxsw_sp_kvdl_part *last_part;
241
242 last_part = list_next_entry(part, list);
243 info->start_index = last_part->info->end_index + 1;
244 info->end_index = info->start_index + size - 1;
245 }
246}
247
225static int mlxsw_sp_kvdl_part_init(struct mlxsw_sp *mlxsw_sp, 248static int mlxsw_sp_kvdl_part_init(struct mlxsw_sp *mlxsw_sp,
226 unsigned int part_index) 249 unsigned int part_index)
227{ 250{
251 struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
228 const struct mlxsw_sp_kvdl_part_info *info; 252 const struct mlxsw_sp_kvdl_part_info *info;
253 enum mlxsw_sp_resource_id resource_id;
229 struct mlxsw_sp_kvdl_part *part; 254 struct mlxsw_sp_kvdl_part *part;
255 bool need_update = true;
230 unsigned int nr_entries; 256 unsigned int nr_entries;
231 size_t usage_size; 257 size_t usage_size;
258 u64 resource_size;
259 int err;
232 260
233 info = &kvdl_parts_info[part_index]; 261 info = &kvdl_parts_info[part_index];
234 262
235 nr_entries = (info->end_index - info->start_index + 1) / 263 switch (part_index) {
236 info->alloc_size; 264 case MLXSW_SP_KVDL_PART_SINGLE:
265 resource_id = MLXSW_SP_RESOURCE_KVD_LINEAR_SINGLE;
266 break;
267 case MLXSW_SP_KVDL_PART_CHUNKS:
268 resource_id = MLXSW_SP_RESOURCE_KVD_LINEAR_CHUNKS;
269 break;
270 case MLXSW_SP_KVDL_PART_LARGE_CHUNKS:
271 resource_id = MLXSW_SP_RESOURCE_KVD_LINEAR_LARGE_CHUNKS;
272 break;
273 default:
274 return -EINVAL;
275 }
276
277 err = devlink_resource_size_get(devlink, resource_id, &resource_size);
278 if (err) {
279 need_update = false;
280 resource_size = info->end_index - info->start_index + 1;
281 }
282
283 nr_entries = div_u64(resource_size, info->alloc_size);
237 usage_size = BITS_TO_LONGS(nr_entries) * sizeof(unsigned long); 284 usage_size = BITS_TO_LONGS(nr_entries) * sizeof(unsigned long);
238 part = kzalloc(sizeof(*part) + usage_size, GFP_KERNEL); 285 part = kzalloc(sizeof(*part) + usage_size, GFP_KERNEL);
239 if (!part) 286 if (!part)
240 return -ENOMEM; 287 return -ENOMEM;
241 288
242 part->info = info; 289 part->info = kmemdup(info, sizeof(*part->info), GFP_KERNEL);
243 list_add(&part->list, &mlxsw_sp->kvdl->parts_list); 290 if (!part->info)
291 goto err_part_info_alloc;
244 292
293 list_add(&part->list, &mlxsw_sp->kvdl->parts_list);
294 if (need_update)
295 mlxsw_sp_kvdl_part_update(mlxsw_sp, part, resource_size);
245 return 0; 296 return 0;
297
298err_part_info_alloc:
299 kfree(part);
300 return -ENOMEM;
246} 301}
247 302
248static void mlxsw_sp_kvdl_part_fini(struct mlxsw_sp *mlxsw_sp, 303static void mlxsw_sp_kvdl_part_fini(struct mlxsw_sp *mlxsw_sp,
@@ -255,6 +310,7 @@ static void mlxsw_sp_kvdl_part_fini(struct mlxsw_sp *mlxsw_sp,
255 return; 310 return;
256 311
257 list_del(&part->list); 312 list_del(&part->list);
313 kfree(part->info);
258 kfree(part); 314 kfree(part);
259} 315}
260 316
@@ -312,6 +368,123 @@ u64 mlxsw_sp_kvdl_occ_get(const struct mlxsw_sp *mlxsw_sp)
312 return occ; 368 return occ;
313} 369}
314 370
371static u64 mlxsw_sp_kvdl_single_occ_get(struct devlink *devlink)
372{
373 struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
374 struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
375 struct mlxsw_sp_kvdl_part *part;
376
377 part = mlxsw_sp_kvdl_part_find(mlxsw_sp, MLXSW_SP_KVDL_PART_SINGLE);
378 if (!part)
379 return -EINVAL;
380
381 return mlxsw_sp_kvdl_part_occ(part);
382}
383
384static u64 mlxsw_sp_kvdl_chunks_occ_get(struct devlink *devlink)
385{
386 struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
387 struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
388 struct mlxsw_sp_kvdl_part *part;
389
390 part = mlxsw_sp_kvdl_part_find(mlxsw_sp, MLXSW_SP_KVDL_PART_CHUNKS);
391 if (!part)
392 return -EINVAL;
393
394 return mlxsw_sp_kvdl_part_occ(part);
395}
396
397static u64 mlxsw_sp_kvdl_large_chunks_occ_get(struct devlink *devlink)
398{
399 struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
400 struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
401 struct mlxsw_sp_kvdl_part *part;
402
403 part = mlxsw_sp_kvdl_part_find(mlxsw_sp,
404 MLXSW_SP_KVDL_PART_LARGE_CHUNKS);
405 if (!part)
406 return -EINVAL;
407
408 return mlxsw_sp_kvdl_part_occ(part);
409}
410
411static struct devlink_resource_ops mlxsw_sp_kvdl_single_ops = {
412 .occ_get = mlxsw_sp_kvdl_single_occ_get,
413};
414
415static struct devlink_resource_ops mlxsw_sp_kvdl_chunks_ops = {
416 .occ_get = mlxsw_sp_kvdl_chunks_occ_get,
417};
418
419static struct devlink_resource_ops mlxsw_sp_kvdl_chunks_large_ops = {
420 .occ_get = mlxsw_sp_kvdl_large_chunks_occ_get,
421};
422
423static struct devlink_resource_size_params mlxsw_sp_kvdl_single_size_params = {
424 .size_min = 0,
425 .size_granularity = 1,
426 .unit = DEVLINK_RESOURCE_UNIT_ENTRY,
427};
428
429static struct devlink_resource_size_params mlxsw_sp_kvdl_chunks_size_params = {
430 .size_min = 0,
431 .size_granularity = MLXSW_SP_CHUNK_MAX,
432 .unit = DEVLINK_RESOURCE_UNIT_ENTRY,
433};
434
435static struct devlink_resource_size_params mlxsw_sp_kvdl_large_chunks_size_params = {
436 .size_min = 0,
437 .size_granularity = MLXSW_SP_LARGE_CHUNK_MAX,
438 .unit = DEVLINK_RESOURCE_UNIT_ENTRY,
439};
440
441static void
442mlxsw_sp_kvdl_resource_size_params_prepare(struct devlink *devlink)
443{
444 struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
445 u32 kvdl_max_size;
446
447 kvdl_max_size = MLXSW_CORE_RES_GET(mlxsw_core, KVD_SIZE) -
448 MLXSW_CORE_RES_GET(mlxsw_core, KVD_SINGLE_MIN_SIZE) -
449 MLXSW_CORE_RES_GET(mlxsw_core, KVD_DOUBLE_MIN_SIZE);
450
451 mlxsw_sp_kvdl_single_size_params.size_max = kvdl_max_size;
452 mlxsw_sp_kvdl_chunks_size_params.size_max = kvdl_max_size;
453 mlxsw_sp_kvdl_large_chunks_size_params.size_max = kvdl_max_size;
454}
455
456int mlxsw_sp_kvdl_resources_register(struct devlink *devlink)
457{
458 int err;
459
460 mlxsw_sp_kvdl_resource_size_params_prepare(devlink);
461 err = devlink_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_KVD_LINEAR_SINGLES,
462 MLXSW_SP_KVDL_SINGLE_SIZE,
463 MLXSW_SP_RESOURCE_KVD_LINEAR_SINGLE,
464 MLXSW_SP_RESOURCE_KVD_LINEAR,
465 &mlxsw_sp_kvdl_single_size_params,
466 &mlxsw_sp_kvdl_single_ops);
467 if (err)
468 return err;
469
470 err = devlink_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_KVD_LINEAR_CHUNKS,
471 MLXSW_SP_KVDL_CHUNKS_SIZE,
472 MLXSW_SP_RESOURCE_KVD_LINEAR_CHUNKS,
473 MLXSW_SP_RESOURCE_KVD_LINEAR,
474 &mlxsw_sp_kvdl_chunks_size_params,
475 &mlxsw_sp_kvdl_chunks_ops);
476 if (err)
477 return err;
478
479 err = devlink_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_KVD_LINEAR_LARGE_CHUNKS,
480 MLXSW_SP_KVDL_LARGE_CHUNKS_SIZE,
481 MLXSW_SP_RESOURCE_KVD_LINEAR_LARGE_CHUNKS,
482 MLXSW_SP_RESOURCE_KVD_LINEAR,
483 &mlxsw_sp_kvdl_large_chunks_size_params,
484 &mlxsw_sp_kvdl_chunks_large_ops);
485 return err;
486}
487
315int mlxsw_sp_kvdl_init(struct mlxsw_sp *mlxsw_sp) 488int mlxsw_sp_kvdl_init(struct mlxsw_sp *mlxsw_sp)
316{ 489{
317 struct mlxsw_sp_kvdl *kvdl; 490 struct mlxsw_sp_kvdl *kvdl;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c
index d20b143de3b4..978a3c70653a 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c
@@ -126,8 +126,8 @@ mlxsw_sp_mr_route_ivif_in_evifs(const struct mlxsw_sp_mr_route *mr_route)
126 126
127 switch (mr_route->mr_table->proto) { 127 switch (mr_route->mr_table->proto) {
128 case MLXSW_SP_L3_PROTO_IPV4: 128 case MLXSW_SP_L3_PROTO_IPV4:
129 ivif = mr_route->mfc4->mfc_parent; 129 ivif = mr_route->mfc4->_c.mfc_parent;
130 return mr_route->mfc4->mfc_un.res.ttls[ivif] != 255; 130 return mr_route->mfc4->_c.mfc_un.res.ttls[ivif] != 255;
131 case MLXSW_SP_L3_PROTO_IPV6: 131 case MLXSW_SP_L3_PROTO_IPV6:
132 /* fall through */ 132 /* fall through */
133 default: 133 default:
@@ -364,7 +364,7 @@ mlxsw_sp_mr_route4_create(struct mlxsw_sp_mr_table *mr_table,
364 mr_route->mfc4 = mfc; 364 mr_route->mfc4 = mfc;
365 mr_route->mr_table = mr_table; 365 mr_route->mr_table = mr_table;
366 for (i = 0; i < MAXVIFS; i++) { 366 for (i = 0; i < MAXVIFS; i++) {
367 if (mfc->mfc_un.res.ttls[i] != 255) { 367 if (mfc->_c.mfc_un.res.ttls[i] != 255) {
368 err = mlxsw_sp_mr_route_evif_link(mr_route, 368 err = mlxsw_sp_mr_route_evif_link(mr_route,
369 &mr_table->vifs[i]); 369 &mr_table->vifs[i]);
370 if (err) 370 if (err)
@@ -374,7 +374,8 @@ mlxsw_sp_mr_route4_create(struct mlxsw_sp_mr_table *mr_table,
374 mr_route->min_mtu = mr_table->vifs[i].dev->mtu; 374 mr_route->min_mtu = mr_table->vifs[i].dev->mtu;
375 } 375 }
376 } 376 }
377 mlxsw_sp_mr_route_ivif_link(mr_route, &mr_table->vifs[mfc->mfc_parent]); 377 mlxsw_sp_mr_route_ivif_link(mr_route,
378 &mr_table->vifs[mfc->_c.mfc_parent]);
378 379
379 mr_route->route_action = mlxsw_sp_mr_route_action(mr_route); 380 mr_route->route_action = mlxsw_sp_mr_route_action(mr_route);
380 return mr_route; 381 return mr_route;
@@ -418,9 +419,9 @@ static void mlxsw_sp_mr_mfc_offload_set(struct mlxsw_sp_mr_route *mr_route,
418 switch (mr_route->mr_table->proto) { 419 switch (mr_route->mr_table->proto) {
419 case MLXSW_SP_L3_PROTO_IPV4: 420 case MLXSW_SP_L3_PROTO_IPV4:
420 if (offload) 421 if (offload)
421 mr_route->mfc4->mfc_flags |= MFC_OFFLOAD; 422 mr_route->mfc4->_c.mfc_flags |= MFC_OFFLOAD;
422 else 423 else
423 mr_route->mfc4->mfc_flags &= ~MFC_OFFLOAD; 424 mr_route->mfc4->_c.mfc_flags &= ~MFC_OFFLOAD;
424 break; 425 break;
425 case MLXSW_SP_L3_PROTO_IPV6: 426 case MLXSW_SP_L3_PROTO_IPV6:
426 /* fall through */ 427 /* fall through */
@@ -943,10 +944,10 @@ static void mlxsw_sp_mr_route_stats_update(struct mlxsw_sp *mlxsw_sp,
943 944
944 switch (mr_route->mr_table->proto) { 945 switch (mr_route->mr_table->proto) {
945 case MLXSW_SP_L3_PROTO_IPV4: 946 case MLXSW_SP_L3_PROTO_IPV4:
946 if (mr_route->mfc4->mfc_un.res.pkt != packets) 947 if (mr_route->mfc4->_c.mfc_un.res.pkt != packets)
947 mr_route->mfc4->mfc_un.res.lastuse = jiffies; 948 mr_route->mfc4->_c.mfc_un.res.lastuse = jiffies;
948 mr_route->mfc4->mfc_un.res.pkt = packets; 949 mr_route->mfc4->_c.mfc_un.res.pkt = packets;
949 mr_route->mfc4->mfc_un.res.bytes = bytes; 950 mr_route->mfc4->_c.mfc_un.res.bytes = bytes;
950 break; 951 break;
951 case MLXSW_SP_L3_PROTO_IPV6: 952 case MLXSW_SP_L3_PROTO_IPV6:
952 /* fall through */ 953 /* fall through */
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_qdisc.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_qdisc.c
index 0b7670459051..91262b0573e3 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_qdisc.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_qdisc.c
@@ -42,6 +42,8 @@
42#include "reg.h" 42#include "reg.h"
43 43
44#define MLXSW_SP_PRIO_BAND_TO_TCLASS(band) (IEEE_8021QAZ_MAX_TCS - band - 1) 44#define MLXSW_SP_PRIO_BAND_TO_TCLASS(band) (IEEE_8021QAZ_MAX_TCS - band - 1)
45#define MLXSW_SP_PRIO_CHILD_TO_TCLASS(child) \
46 MLXSW_SP_PRIO_BAND_TO_TCLASS((child - 1))
45 47
46enum mlxsw_sp_qdisc_type { 48enum mlxsw_sp_qdisc_type {
47 MLXSW_SP_QDISC_NO_QDISC, 49 MLXSW_SP_QDISC_NO_QDISC,
@@ -76,6 +78,7 @@ struct mlxsw_sp_qdisc_ops {
76struct mlxsw_sp_qdisc { 78struct mlxsw_sp_qdisc {
77 u32 handle; 79 u32 handle;
78 u8 tclass_num; 80 u8 tclass_num;
81 u8 prio_bitmap;
79 union { 82 union {
80 struct red_stats red; 83 struct red_stats red;
81 } xstats_base; 84 } xstats_base;
@@ -99,6 +102,44 @@ mlxsw_sp_qdisc_compare(struct mlxsw_sp_qdisc *mlxsw_sp_qdisc, u32 handle,
99 mlxsw_sp_qdisc->handle == handle; 102 mlxsw_sp_qdisc->handle == handle;
100} 103}
101 104
105static struct mlxsw_sp_qdisc *
106mlxsw_sp_qdisc_find(struct mlxsw_sp_port *mlxsw_sp_port, u32 parent,
107 bool root_only)
108{
109 int tclass, child_index;
110
111 if (parent == TC_H_ROOT)
112 return mlxsw_sp_port->root_qdisc;
113
114 if (root_only || !mlxsw_sp_port->root_qdisc ||
115 !mlxsw_sp_port->root_qdisc->ops ||
116 TC_H_MAJ(parent) != mlxsw_sp_port->root_qdisc->handle ||
117 TC_H_MIN(parent) > IEEE_8021QAZ_MAX_TCS)
118 return NULL;
119
120 child_index = TC_H_MIN(parent);
121 tclass = MLXSW_SP_PRIO_CHILD_TO_TCLASS(child_index);
122 return &mlxsw_sp_port->tclass_qdiscs[tclass];
123}
124
125static struct mlxsw_sp_qdisc *
126mlxsw_sp_qdisc_find_by_handle(struct mlxsw_sp_port *mlxsw_sp_port, u32 handle)
127{
128 int i;
129
130 if (mlxsw_sp_port->root_qdisc->handle == handle)
131 return mlxsw_sp_port->root_qdisc;
132
133 if (mlxsw_sp_port->root_qdisc->handle == TC_H_UNSPEC)
134 return NULL;
135
136 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
137 if (mlxsw_sp_port->tclass_qdiscs[i].handle == handle)
138 return &mlxsw_sp_port->tclass_qdiscs[i];
139
140 return NULL;
141}
142
102static int 143static int
103mlxsw_sp_qdisc_destroy(struct mlxsw_sp_port *mlxsw_sp_port, 144mlxsw_sp_qdisc_destroy(struct mlxsw_sp_port *mlxsw_sp_port,
104 struct mlxsw_sp_qdisc *mlxsw_sp_qdisc) 145 struct mlxsw_sp_qdisc *mlxsw_sp_qdisc)
@@ -185,6 +226,23 @@ mlxsw_sp_qdisc_get_xstats(struct mlxsw_sp_port *mlxsw_sp_port,
185 return -EOPNOTSUPP; 226 return -EOPNOTSUPP;
186} 227}
187 228
229static void
230mlxsw_sp_qdisc_bstats_per_priority_get(struct mlxsw_sp_port_xstats *xstats,
231 u8 prio_bitmap, u64 *tx_packets,
232 u64 *tx_bytes)
233{
234 int i;
235
236 *tx_packets = 0;
237 *tx_bytes = 0;
238 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
239 if (prio_bitmap & BIT(i)) {
240 *tx_packets += xstats->tx_packets[i];
241 *tx_bytes += xstats->tx_bytes[i];
242 }
243 }
244}
245
188static int 246static int
189mlxsw_sp_tclass_congestion_enable(struct mlxsw_sp_port *mlxsw_sp_port, 247mlxsw_sp_tclass_congestion_enable(struct mlxsw_sp_port *mlxsw_sp_port,
190 int tclass_num, u32 min, u32 max, 248 int tclass_num, u32 min, u32 max,
@@ -230,17 +288,16 @@ mlxsw_sp_setup_tc_qdisc_red_clean_stats(struct mlxsw_sp_port *mlxsw_sp_port,
230 u8 tclass_num = mlxsw_sp_qdisc->tclass_num; 288 u8 tclass_num = mlxsw_sp_qdisc->tclass_num;
231 struct mlxsw_sp_qdisc_stats *stats_base; 289 struct mlxsw_sp_qdisc_stats *stats_base;
232 struct mlxsw_sp_port_xstats *xstats; 290 struct mlxsw_sp_port_xstats *xstats;
233 struct rtnl_link_stats64 *stats;
234 struct red_stats *red_base; 291 struct red_stats *red_base;
235 292
236 xstats = &mlxsw_sp_port->periodic_hw_stats.xstats; 293 xstats = &mlxsw_sp_port->periodic_hw_stats.xstats;
237 stats = &mlxsw_sp_port->periodic_hw_stats.stats;
238 stats_base = &mlxsw_sp_qdisc->stats_base; 294 stats_base = &mlxsw_sp_qdisc->stats_base;
239 red_base = &mlxsw_sp_qdisc->xstats_base.red; 295 red_base = &mlxsw_sp_qdisc->xstats_base.red;
240 296
241 stats_base->tx_packets = stats->tx_packets; 297 mlxsw_sp_qdisc_bstats_per_priority_get(xstats,
242 stats_base->tx_bytes = stats->tx_bytes; 298 mlxsw_sp_qdisc->prio_bitmap,
243 299 &stats_base->tx_packets,
300 &stats_base->tx_bytes);
244 red_base->prob_mark = xstats->ecn; 301 red_base->prob_mark = xstats->ecn;
245 red_base->prob_drop = xstats->wred_drop[tclass_num]; 302 red_base->prob_drop = xstats->wred_drop[tclass_num];
246 red_base->pdrop = xstats->tail_drop[tclass_num]; 303 red_base->pdrop = xstats->tail_drop[tclass_num];
@@ -255,6 +312,12 @@ static int
255mlxsw_sp_qdisc_red_destroy(struct mlxsw_sp_port *mlxsw_sp_port, 312mlxsw_sp_qdisc_red_destroy(struct mlxsw_sp_port *mlxsw_sp_port,
256 struct mlxsw_sp_qdisc *mlxsw_sp_qdisc) 313 struct mlxsw_sp_qdisc *mlxsw_sp_qdisc)
257{ 314{
315 struct mlxsw_sp_qdisc *root_qdisc = mlxsw_sp_port->root_qdisc;
316
317 if (root_qdisc != mlxsw_sp_qdisc)
318 root_qdisc->stats_base.backlog -=
319 mlxsw_sp_qdisc->stats_base.backlog;
320
258 return mlxsw_sp_tclass_congestion_disable(mlxsw_sp_port, 321 return mlxsw_sp_tclass_congestion_disable(mlxsw_sp_port,
259 mlxsw_sp_qdisc->tclass_num); 322 mlxsw_sp_qdisc->tclass_num);
260} 323}
@@ -319,6 +382,7 @@ mlxsw_sp_qdisc_red_unoffload(struct mlxsw_sp_port *mlxsw_sp_port,
319 backlog = mlxsw_sp_cells_bytes(mlxsw_sp_port->mlxsw_sp, 382 backlog = mlxsw_sp_cells_bytes(mlxsw_sp_port->mlxsw_sp,
320 mlxsw_sp_qdisc->stats_base.backlog); 383 mlxsw_sp_qdisc->stats_base.backlog);
321 p->qstats->backlog -= backlog; 384 p->qstats->backlog -= backlog;
385 mlxsw_sp_qdisc->stats_base.backlog = 0;
322} 386}
323 387
324static int 388static int
@@ -357,14 +421,16 @@ mlxsw_sp_qdisc_get_red_stats(struct mlxsw_sp_port *mlxsw_sp_port,
357 u8 tclass_num = mlxsw_sp_qdisc->tclass_num; 421 u8 tclass_num = mlxsw_sp_qdisc->tclass_num;
358 struct mlxsw_sp_qdisc_stats *stats_base; 422 struct mlxsw_sp_qdisc_stats *stats_base;
359 struct mlxsw_sp_port_xstats *xstats; 423 struct mlxsw_sp_port_xstats *xstats;
360 struct rtnl_link_stats64 *stats;
361 424
362 xstats = &mlxsw_sp_port->periodic_hw_stats.xstats; 425 xstats = &mlxsw_sp_port->periodic_hw_stats.xstats;
363 stats = &mlxsw_sp_port->periodic_hw_stats.stats;
364 stats_base = &mlxsw_sp_qdisc->stats_base; 426 stats_base = &mlxsw_sp_qdisc->stats_base;
365 427
366 tx_bytes = stats->tx_bytes - stats_base->tx_bytes; 428 mlxsw_sp_qdisc_bstats_per_priority_get(xstats,
367 tx_packets = stats->tx_packets - stats_base->tx_packets; 429 mlxsw_sp_qdisc->prio_bitmap,
430 &tx_packets, &tx_bytes);
431 tx_bytes = tx_bytes - stats_base->tx_bytes;
432 tx_packets = tx_packets - stats_base->tx_packets;
433
368 overlimits = xstats->wred_drop[tclass_num] + xstats->ecn - 434 overlimits = xstats->wred_drop[tclass_num] + xstats->ecn -
369 stats_base->overlimits; 435 stats_base->overlimits;
370 drops = xstats->wred_drop[tclass_num] + xstats->tail_drop[tclass_num] - 436 drops = xstats->wred_drop[tclass_num] + xstats->tail_drop[tclass_num] -
@@ -406,11 +472,10 @@ int mlxsw_sp_setup_tc_red(struct mlxsw_sp_port *mlxsw_sp_port,
406{ 472{
407 struct mlxsw_sp_qdisc *mlxsw_sp_qdisc; 473 struct mlxsw_sp_qdisc *mlxsw_sp_qdisc;
408 474
409 if (p->parent != TC_H_ROOT) 475 mlxsw_sp_qdisc = mlxsw_sp_qdisc_find(mlxsw_sp_port, p->parent, false);
476 if (!mlxsw_sp_qdisc)
410 return -EOPNOTSUPP; 477 return -EOPNOTSUPP;
411 478
412 mlxsw_sp_qdisc = mlxsw_sp_port->root_qdisc;
413
414 if (p->command == TC_RED_REPLACE) 479 if (p->command == TC_RED_REPLACE)
415 return mlxsw_sp_qdisc_replace(mlxsw_sp_port, p->handle, 480 return mlxsw_sp_qdisc_replace(mlxsw_sp_port, p->handle,
416 mlxsw_sp_qdisc, 481 mlxsw_sp_qdisc,
@@ -441,9 +506,13 @@ mlxsw_sp_qdisc_prio_destroy(struct mlxsw_sp_port *mlxsw_sp_port,
441{ 506{
442 int i; 507 int i;
443 508
444 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) 509 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
445 mlxsw_sp_port_prio_tc_set(mlxsw_sp_port, i, 510 mlxsw_sp_port_prio_tc_set(mlxsw_sp_port, i,
446 MLXSW_SP_PORT_DEFAULT_TCLASS); 511 MLXSW_SP_PORT_DEFAULT_TCLASS);
512 mlxsw_sp_qdisc_destroy(mlxsw_sp_port,
513 &mlxsw_sp_port->tclass_qdiscs[i]);
514 mlxsw_sp_port->tclass_qdiscs[i].prio_bitmap = 0;
515 }
447 516
448 return 0; 517 return 0;
449} 518}
@@ -467,16 +536,41 @@ mlxsw_sp_qdisc_prio_replace(struct mlxsw_sp_port *mlxsw_sp_port,
467 void *params) 536 void *params)
468{ 537{
469 struct tc_prio_qopt_offload_params *p = params; 538 struct tc_prio_qopt_offload_params *p = params;
470 int tclass, i; 539 struct mlxsw_sp_qdisc *child_qdisc;
540 int tclass, i, band, backlog;
541 u8 old_priomap;
471 int err; 542 int err;
472 543
473 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { 544 for (band = 0; band < p->bands; band++) {
474 tclass = MLXSW_SP_PRIO_BAND_TO_TCLASS(p->priomap[i]); 545 tclass = MLXSW_SP_PRIO_BAND_TO_TCLASS(band);
475 err = mlxsw_sp_port_prio_tc_set(mlxsw_sp_port, i, tclass); 546 child_qdisc = &mlxsw_sp_port->tclass_qdiscs[tclass];
476 if (err) 547 old_priomap = child_qdisc->prio_bitmap;
477 return err; 548 child_qdisc->prio_bitmap = 0;
549 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
550 if (p->priomap[i] == band) {
551 child_qdisc->prio_bitmap |= BIT(i);
552 if (BIT(i) & old_priomap)
553 continue;
554 err = mlxsw_sp_port_prio_tc_set(mlxsw_sp_port,
555 i, tclass);
556 if (err)
557 return err;
558 }
559 }
560 if (old_priomap != child_qdisc->prio_bitmap &&
561 child_qdisc->ops && child_qdisc->ops->clean_stats) {
562 backlog = child_qdisc->stats_base.backlog;
563 child_qdisc->ops->clean_stats(mlxsw_sp_port,
564 child_qdisc);
565 child_qdisc->stats_base.backlog = backlog;
566 }
567 }
568 for (; band < IEEE_8021QAZ_MAX_TCS; band++) {
569 tclass = MLXSW_SP_PRIO_BAND_TO_TCLASS(band);
570 child_qdisc = &mlxsw_sp_port->tclass_qdiscs[tclass];
571 child_qdisc->prio_bitmap = 0;
572 mlxsw_sp_qdisc_destroy(mlxsw_sp_port, child_qdisc);
478 } 573 }
479
480 return 0; 574 return 0;
481} 575}
482 576
@@ -513,6 +607,7 @@ mlxsw_sp_qdisc_get_prio_stats(struct mlxsw_sp_port *mlxsw_sp_port,
513 607
514 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { 608 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
515 drops += xstats->tail_drop[i]; 609 drops += xstats->tail_drop[i];
610 drops += xstats->wred_drop[i];
516 backlog += xstats->backlog[i]; 611 backlog += xstats->backlog[i];
517 } 612 }
518 drops = drops - stats_base->drops; 613 drops = drops - stats_base->drops;
@@ -548,8 +643,10 @@ mlxsw_sp_setup_tc_qdisc_prio_clean_stats(struct mlxsw_sp_port *mlxsw_sp_port,
548 stats_base->tx_bytes = stats->tx_bytes; 643 stats_base->tx_bytes = stats->tx_bytes;
549 644
550 stats_base->drops = 0; 645 stats_base->drops = 0;
551 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) 646 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
552 stats_base->drops += xstats->tail_drop[i]; 647 stats_base->drops += xstats->tail_drop[i];
648 stats_base->drops += xstats->wred_drop[i];
649 }
553 650
554 mlxsw_sp_qdisc->stats_base.backlog = 0; 651 mlxsw_sp_qdisc->stats_base.backlog = 0;
555} 652}
@@ -564,15 +661,48 @@ static struct mlxsw_sp_qdisc_ops mlxsw_sp_qdisc_ops_prio = {
564 .clean_stats = mlxsw_sp_setup_tc_qdisc_prio_clean_stats, 661 .clean_stats = mlxsw_sp_setup_tc_qdisc_prio_clean_stats,
565}; 662};
566 663
664/* Grafting is not supported in mlxsw. It will result in un-offloading of the
665 * grafted qdisc as well as the qdisc in the qdisc new location.
666 * (However, if the graft is to the location where the qdisc is already at, it
667 * will be ignored completely and won't cause un-offloading).
668 */
669static int
670mlxsw_sp_qdisc_prio_graft(struct mlxsw_sp_port *mlxsw_sp_port,
671 struct mlxsw_sp_qdisc *mlxsw_sp_qdisc,
672 struct tc_prio_qopt_offload_graft_params *p)
673{
674 int tclass_num = MLXSW_SP_PRIO_BAND_TO_TCLASS(p->band);
675 struct mlxsw_sp_qdisc *old_qdisc;
676
677 /* Check if the grafted qdisc is already in its "new" location. If so -
678 * nothing needs to be done.
679 */
680 if (p->band < IEEE_8021QAZ_MAX_TCS &&
681 mlxsw_sp_port->tclass_qdiscs[tclass_num].handle == p->child_handle)
682 return 0;
683
684 /* See if the grafted qdisc is already offloaded on any tclass. If so,
685 * unoffload it.
686 */
687 old_qdisc = mlxsw_sp_qdisc_find_by_handle(mlxsw_sp_port,
688 p->child_handle);
689 if (old_qdisc)
690 mlxsw_sp_qdisc_destroy(mlxsw_sp_port, old_qdisc);
691
692 mlxsw_sp_qdisc_destroy(mlxsw_sp_port,
693 &mlxsw_sp_port->tclass_qdiscs[tclass_num]);
694 return -EOPNOTSUPP;
695}
696
567int mlxsw_sp_setup_tc_prio(struct mlxsw_sp_port *mlxsw_sp_port, 697int mlxsw_sp_setup_tc_prio(struct mlxsw_sp_port *mlxsw_sp_port,
568 struct tc_prio_qopt_offload *p) 698 struct tc_prio_qopt_offload *p)
569{ 699{
570 struct mlxsw_sp_qdisc *mlxsw_sp_qdisc; 700 struct mlxsw_sp_qdisc *mlxsw_sp_qdisc;
571 701
572 if (p->parent != TC_H_ROOT) 702 mlxsw_sp_qdisc = mlxsw_sp_qdisc_find(mlxsw_sp_port, p->parent, true);
703 if (!mlxsw_sp_qdisc)
573 return -EOPNOTSUPP; 704 return -EOPNOTSUPP;
574 705
575 mlxsw_sp_qdisc = mlxsw_sp_port->root_qdisc;
576 if (p->command == TC_PRIO_REPLACE) 706 if (p->command == TC_PRIO_REPLACE)
577 return mlxsw_sp_qdisc_replace(mlxsw_sp_port, p->handle, 707 return mlxsw_sp_qdisc_replace(mlxsw_sp_port, p->handle,
578 mlxsw_sp_qdisc, 708 mlxsw_sp_qdisc,
@@ -589,6 +719,9 @@ int mlxsw_sp_setup_tc_prio(struct mlxsw_sp_port *mlxsw_sp_port,
589 case TC_PRIO_STATS: 719 case TC_PRIO_STATS:
590 return mlxsw_sp_qdisc_get_stats(mlxsw_sp_port, mlxsw_sp_qdisc, 720 return mlxsw_sp_qdisc_get_stats(mlxsw_sp_port, mlxsw_sp_qdisc,
591 &p->stats); 721 &p->stats);
722 case TC_PRIO_GRAFT:
723 return mlxsw_sp_qdisc_prio_graft(mlxsw_sp_port, mlxsw_sp_qdisc,
724 &p->graft_params);
592 default: 725 default:
593 return -EOPNOTSUPP; 726 return -EOPNOTSUPP;
594 } 727 }
@@ -596,17 +729,36 @@ int mlxsw_sp_setup_tc_prio(struct mlxsw_sp_port *mlxsw_sp_port,
596 729
597int mlxsw_sp_tc_qdisc_init(struct mlxsw_sp_port *mlxsw_sp_port) 730int mlxsw_sp_tc_qdisc_init(struct mlxsw_sp_port *mlxsw_sp_port)
598{ 731{
599 mlxsw_sp_port->root_qdisc = kzalloc(sizeof(*mlxsw_sp_port->root_qdisc), 732 struct mlxsw_sp_qdisc *mlxsw_sp_qdisc;
600 GFP_KERNEL); 733 int i;
601 if (!mlxsw_sp_port->root_qdisc)
602 return -ENOMEM;
603 734
735 mlxsw_sp_qdisc = kzalloc(sizeof(*mlxsw_sp_qdisc), GFP_KERNEL);
736 if (!mlxsw_sp_qdisc)
737 goto err_root_qdisc_init;
738
739 mlxsw_sp_port->root_qdisc = mlxsw_sp_qdisc;
740 mlxsw_sp_port->root_qdisc->prio_bitmap = 0xff;
604 mlxsw_sp_port->root_qdisc->tclass_num = MLXSW_SP_PORT_DEFAULT_TCLASS; 741 mlxsw_sp_port->root_qdisc->tclass_num = MLXSW_SP_PORT_DEFAULT_TCLASS;
605 742
743 mlxsw_sp_qdisc = kzalloc(sizeof(*mlxsw_sp_qdisc) * IEEE_8021QAZ_MAX_TCS,
744 GFP_KERNEL);
745 if (!mlxsw_sp_qdisc)
746 goto err_tclass_qdiscs_init;
747
748 mlxsw_sp_port->tclass_qdiscs = mlxsw_sp_qdisc;
749 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
750 mlxsw_sp_port->tclass_qdiscs[i].tclass_num = i;
751
606 return 0; 752 return 0;
753
754err_tclass_qdiscs_init:
755 kfree(mlxsw_sp_port->root_qdisc);
756err_root_qdisc_init:
757 return -ENOMEM;
607} 758}
608 759
609void mlxsw_sp_tc_qdisc_fini(struct mlxsw_sp_port *mlxsw_sp_port) 760void mlxsw_sp_tc_qdisc_fini(struct mlxsw_sp_port *mlxsw_sp_port)
610{ 761{
762 kfree(mlxsw_sp_port->tclass_qdiscs);
611 kfree(mlxsw_sp_port->root_qdisc); 763 kfree(mlxsw_sp_port->root_qdisc);
612} 764}
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index f7948e983637..921bd1075edf 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -1,10 +1,10 @@
1/* 1/*
2 * drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c 2 * drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
3 * Copyright (c) 2016-2017 Mellanox Technologies. All rights reserved. 3 * Copyright (c) 2016-2018 Mellanox Technologies. All rights reserved.
4 * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com> 4 * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com>
5 * Copyright (c) 2016 Ido Schimmel <idosch@mellanox.com> 5 * Copyright (c) 2016 Ido Schimmel <idosch@mellanox.com>
6 * Copyright (c) 2016 Yotam Gigi <yotamg@mellanox.com> 6 * Copyright (c) 2016 Yotam Gigi <yotamg@mellanox.com>
7 * Copyright (c) 2017 Petr Machata <petrm@mellanox.com> 7 * Copyright (c) 2017-2018 Petr Machata <petrm@mellanox.com>
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met: 10 * modification, are permitted provided that the following conditions are met:
@@ -70,6 +70,7 @@
70#include "spectrum_mr.h" 70#include "spectrum_mr.h"
71#include "spectrum_mr_tcam.h" 71#include "spectrum_mr_tcam.h"
72#include "spectrum_router.h" 72#include "spectrum_router.h"
73#include "spectrum_span.h"
73 74
74struct mlxsw_sp_fib; 75struct mlxsw_sp_fib;
75struct mlxsw_sp_vr; 76struct mlxsw_sp_vr;
@@ -796,7 +797,7 @@ static struct mlxsw_sp_vr *mlxsw_sp_vr_create(struct mlxsw_sp *mlxsw_sp,
796 797
797 vr = mlxsw_sp_vr_find_unused(mlxsw_sp); 798 vr = mlxsw_sp_vr_find_unused(mlxsw_sp);
798 if (!vr) { 799 if (!vr) {
799 NL_SET_ERR_MSG(extack, "spectrum: Exceeded number of supported virtual routers"); 800 NL_SET_ERR_MSG_MOD(extack, "Exceeded number of supported virtual routers");
800 return ERR_PTR(-EBUSY); 801 return ERR_PTR(-EBUSY);
801 } 802 }
802 fib4 = mlxsw_sp_fib_create(mlxsw_sp, vr, MLXSW_SP_L3_PROTO_IPV4); 803 fib4 = mlxsw_sp_fib_create(mlxsw_sp, vr, MLXSW_SP_L3_PROTO_IPV4);
@@ -1024,9 +1025,11 @@ mlxsw_sp_ipip_entry_alloc(struct mlxsw_sp *mlxsw_sp,
1024 enum mlxsw_sp_ipip_type ipipt, 1025 enum mlxsw_sp_ipip_type ipipt,
1025 struct net_device *ol_dev) 1026 struct net_device *ol_dev)
1026{ 1027{
1028 const struct mlxsw_sp_ipip_ops *ipip_ops;
1027 struct mlxsw_sp_ipip_entry *ipip_entry; 1029 struct mlxsw_sp_ipip_entry *ipip_entry;
1028 struct mlxsw_sp_ipip_entry *ret = NULL; 1030 struct mlxsw_sp_ipip_entry *ret = NULL;
1029 1031
1032 ipip_ops = mlxsw_sp->router->ipip_ops_arr[ipipt];
1030 ipip_entry = kzalloc(sizeof(*ipip_entry), GFP_KERNEL); 1033 ipip_entry = kzalloc(sizeof(*ipip_entry), GFP_KERNEL);
1031 if (!ipip_entry) 1034 if (!ipip_entry)
1032 return ERR_PTR(-ENOMEM); 1035 return ERR_PTR(-ENOMEM);
@@ -1040,7 +1043,15 @@ mlxsw_sp_ipip_entry_alloc(struct mlxsw_sp *mlxsw_sp,
1040 1043
1041 ipip_entry->ipipt = ipipt; 1044 ipip_entry->ipipt = ipipt;
1042 ipip_entry->ol_dev = ol_dev; 1045 ipip_entry->ol_dev = ol_dev;
1043 ipip_entry->parms = mlxsw_sp_ipip_netdev_parms(ol_dev); 1046
1047 switch (ipip_ops->ul_proto) {
1048 case MLXSW_SP_L3_PROTO_IPV4:
1049 ipip_entry->parms4 = mlxsw_sp_ipip_netdev_parms4(ol_dev);
1050 break;
1051 case MLXSW_SP_L3_PROTO_IPV6:
1052 WARN_ON(1);
1053 break;
1054 }
1044 1055
1045 return ipip_entry; 1056 return ipip_entry;
1046 1057
@@ -2320,6 +2331,8 @@ static void mlxsw_sp_router_neigh_event_work(struct work_struct *work)
2320 read_unlock_bh(&n->lock); 2331 read_unlock_bh(&n->lock);
2321 2332
2322 rtnl_lock(); 2333 rtnl_lock();
2334 mlxsw_sp_span_respin(mlxsw_sp);
2335
2323 entry_connected = nud_state & NUD_VALID && !dead; 2336 entry_connected = nud_state & NUD_VALID && !dead;
2324 neigh_entry = mlxsw_sp_neigh_entry_lookup(mlxsw_sp, n); 2337 neigh_entry = mlxsw_sp_neigh_entry_lookup(mlxsw_sp, n);
2325 if (!entry_connected && !neigh_entry) 2338 if (!entry_connected && !neigh_entry)
@@ -2417,7 +2430,8 @@ static int mlxsw_sp_router_netevent_event(struct notifier_block *nb,
2417 mlxsw_core_schedule_work(&net_work->work); 2430 mlxsw_core_schedule_work(&net_work->work);
2418 mlxsw_sp_port_dev_put(mlxsw_sp_port); 2431 mlxsw_sp_port_dev_put(mlxsw_sp_port);
2419 break; 2432 break;
2420 case NETEVENT_MULTIPATH_HASH_UPDATE: 2433 case NETEVENT_IPV4_MPATH_HASH_UPDATE:
2434 case NETEVENT_IPV6_MPATH_HASH_UPDATE:
2421 net = ptr; 2435 net = ptr;
2422 2436
2423 if (!net_eq(net, &init_net)) 2437 if (!net_eq(net, &init_net))
@@ -5579,6 +5593,8 @@ static void mlxsw_sp_router_fib4_event_work(struct work_struct *work)
5579 5593
5580 /* Protect internal structures from changes */ 5594 /* Protect internal structures from changes */
5581 rtnl_lock(); 5595 rtnl_lock();
5596 mlxsw_sp_span_respin(mlxsw_sp);
5597
5582 switch (fib_work->event) { 5598 switch (fib_work->event) {
5583 case FIB_EVENT_ENTRY_REPLACE: /* fall through */ 5599 case FIB_EVENT_ENTRY_REPLACE: /* fall through */
5584 case FIB_EVENT_ENTRY_APPEND: /* fall through */ 5600 case FIB_EVENT_ENTRY_APPEND: /* fall through */
@@ -5621,6 +5637,8 @@ static void mlxsw_sp_router_fib6_event_work(struct work_struct *work)
5621 int err; 5637 int err;
5622 5638
5623 rtnl_lock(); 5639 rtnl_lock();
5640 mlxsw_sp_span_respin(mlxsw_sp);
5641
5624 switch (fib_work->event) { 5642 switch (fib_work->event) {
5625 case FIB_EVENT_ENTRY_REPLACE: /* fall through */ 5643 case FIB_EVENT_ENTRY_REPLACE: /* fall through */
5626 case FIB_EVENT_ENTRY_ADD: 5644 case FIB_EVENT_ENTRY_ADD:
@@ -5793,7 +5811,7 @@ static int mlxsw_sp_router_fib_rule_event(unsigned long event,
5793 } 5811 }
5794 5812
5795 if (err < 0) 5813 if (err < 0)
5796 NL_SET_ERR_MSG(extack, "spectrum: FIB rules not supported. Aborting offload"); 5814 NL_SET_ERR_MSG_MOD(extack, "FIB rules not supported. Aborting offload");
5797 5815
5798 return err; 5816 return err;
5799} 5817}
@@ -6032,7 +6050,7 @@ mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp,
6032 6050
6033 err = mlxsw_sp_rif_index_alloc(mlxsw_sp, &rif_index); 6051 err = mlxsw_sp_rif_index_alloc(mlxsw_sp, &rif_index);
6034 if (err) { 6052 if (err) {
6035 NL_SET_ERR_MSG(extack, "spectrum: Exceeded number of supported router interfaces"); 6053 NL_SET_ERR_MSG_MOD(extack, "Exceeded number of supported router interfaces");
6036 goto err_rif_index_alloc; 6054 goto err_rif_index_alloc;
6037 } 6055 }
6038 6056
@@ -7013,13 +7031,25 @@ static void mlxsw_sp_mp4_hash_init(char *recr2_pl)
7013 7031
7014static void mlxsw_sp_mp6_hash_init(char *recr2_pl) 7032static void mlxsw_sp_mp6_hash_init(char *recr2_pl)
7015{ 7033{
7034 bool only_l3 = !ip6_multipath_hash_policy(&init_net);
7035
7016 mlxsw_sp_mp_hash_header_set(recr2_pl, 7036 mlxsw_sp_mp_hash_header_set(recr2_pl,
7017 MLXSW_REG_RECR2_IPV6_EN_NOT_TCP_NOT_UDP); 7037 MLXSW_REG_RECR2_IPV6_EN_NOT_TCP_NOT_UDP);
7018 mlxsw_sp_mp_hash_header_set(recr2_pl, MLXSW_REG_RECR2_IPV6_EN_TCP_UDP); 7038 mlxsw_sp_mp_hash_header_set(recr2_pl, MLXSW_REG_RECR2_IPV6_EN_TCP_UDP);
7019 mlxsw_reg_recr2_ipv6_sip_enable(recr2_pl); 7039 mlxsw_reg_recr2_ipv6_sip_enable(recr2_pl);
7020 mlxsw_reg_recr2_ipv6_dip_enable(recr2_pl); 7040 mlxsw_reg_recr2_ipv6_dip_enable(recr2_pl);
7021 mlxsw_sp_mp_hash_field_set(recr2_pl, MLXSW_REG_RECR2_IPV6_FLOW_LABEL);
7022 mlxsw_sp_mp_hash_field_set(recr2_pl, MLXSW_REG_RECR2_IPV6_NEXT_HEADER); 7041 mlxsw_sp_mp_hash_field_set(recr2_pl, MLXSW_REG_RECR2_IPV6_NEXT_HEADER);
7042 if (only_l3) {
7043 mlxsw_sp_mp_hash_field_set(recr2_pl,
7044 MLXSW_REG_RECR2_IPV6_FLOW_LABEL);
7045 } else {
7046 mlxsw_sp_mp_hash_header_set(recr2_pl,
7047 MLXSW_REG_RECR2_TCP_UDP_EN_IPV6);
7048 mlxsw_sp_mp_hash_field_set(recr2_pl,
7049 MLXSW_REG_RECR2_TCP_UDP_SPORT);
7050 mlxsw_sp_mp_hash_field_set(recr2_pl,
7051 MLXSW_REG_RECR2_TCP_UDP_DPORT);
7052 }
7023} 7053}
7024 7054
7025static int mlxsw_sp_mp_hash_init(struct mlxsw_sp *mlxsw_sp) 7055static int mlxsw_sp_mp_hash_init(struct mlxsw_sp *mlxsw_sp)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
new file mode 100644
index 000000000000..ae22a3daffbf
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
@@ -0,0 +1,804 @@
1/*
2 * drivers/net/ethernet/mellanox/mlxsw/mlxsw_span.c
3 * Copyright (c) 2018 Mellanox Technologies. All rights reserved.
4 * Copyright (c) 2018 Petr Machata <petrm@mellanox.com>
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the names of the copyright holders nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * Alternatively, this software may be distributed under the terms of the
19 * GNU General Public License ("GPL") version 2 as published by the Free
20 * Software Foundation.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 */
34
35#include <linux/list.h>
36#include <net/arp.h>
37#include <net/gre.h>
38#include <net/ndisc.h>
39#include <net/ip6_tunnel.h>
40
41#include "spectrum.h"
42#include "spectrum_span.h"
43#include "spectrum_ipip.h"
44
45int mlxsw_sp_span_init(struct mlxsw_sp *mlxsw_sp)
46{
47 int i;
48
49 if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_SPAN))
50 return -EIO;
51
52 mlxsw_sp->span.entries_count = MLXSW_CORE_RES_GET(mlxsw_sp->core,
53 MAX_SPAN);
54 mlxsw_sp->span.entries = kcalloc(mlxsw_sp->span.entries_count,
55 sizeof(struct mlxsw_sp_span_entry),
56 GFP_KERNEL);
57 if (!mlxsw_sp->span.entries)
58 return -ENOMEM;
59
60 for (i = 0; i < mlxsw_sp->span.entries_count; i++) {
61 struct mlxsw_sp_span_entry *curr = &mlxsw_sp->span.entries[i];
62
63 INIT_LIST_HEAD(&curr->bound_ports_list);
64 curr->id = i;
65 }
66
67 return 0;
68}
69
70void mlxsw_sp_span_fini(struct mlxsw_sp *mlxsw_sp)
71{
72 int i;
73
74 for (i = 0; i < mlxsw_sp->span.entries_count; i++) {
75 struct mlxsw_sp_span_entry *curr = &mlxsw_sp->span.entries[i];
76
77 WARN_ON_ONCE(!list_empty(&curr->bound_ports_list));
78 }
79 kfree(mlxsw_sp->span.entries);
80}
81
82static int
83mlxsw_sp_span_entry_phys_parms(const struct net_device *to_dev,
84 struct mlxsw_sp_span_parms *sparmsp)
85{
86 sparmsp->dest_port = netdev_priv(to_dev);
87 return 0;
88}
89
90static int
91mlxsw_sp_span_entry_phys_configure(struct mlxsw_sp_span_entry *span_entry,
92 struct mlxsw_sp_span_parms sparms)
93{
94 struct mlxsw_sp_port *dest_port = sparms.dest_port;
95 struct mlxsw_sp *mlxsw_sp = dest_port->mlxsw_sp;
96 u8 local_port = dest_port->local_port;
97 char mpat_pl[MLXSW_REG_MPAT_LEN];
98 int pa_id = span_entry->id;
99
100 /* Create a new port analayzer entry for local_port. */
101 mlxsw_reg_mpat_pack(mpat_pl, pa_id, local_port, true,
102 MLXSW_REG_MPAT_SPAN_TYPE_LOCAL_ETH);
103
104 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpat), mpat_pl);
105}
106
107static void
108mlxsw_sp_span_entry_deconfigure_common(struct mlxsw_sp_span_entry *span_entry,
109 enum mlxsw_reg_mpat_span_type span_type)
110{
111 struct mlxsw_sp_port *dest_port = span_entry->parms.dest_port;
112 struct mlxsw_sp *mlxsw_sp = dest_port->mlxsw_sp;
113 u8 local_port = dest_port->local_port;
114 char mpat_pl[MLXSW_REG_MPAT_LEN];
115 int pa_id = span_entry->id;
116
117 mlxsw_reg_mpat_pack(mpat_pl, pa_id, local_port, false, span_type);
118 mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpat), mpat_pl);
119}
120
121static void
122mlxsw_sp_span_entry_phys_deconfigure(struct mlxsw_sp_span_entry *span_entry)
123{
124 mlxsw_sp_span_entry_deconfigure_common(span_entry,
125 MLXSW_REG_MPAT_SPAN_TYPE_LOCAL_ETH);
126}
127
128static const
129struct mlxsw_sp_span_entry_ops mlxsw_sp_span_entry_ops_phys = {
130 .can_handle = mlxsw_sp_port_dev_check,
131 .parms = mlxsw_sp_span_entry_phys_parms,
132 .configure = mlxsw_sp_span_entry_phys_configure,
133 .deconfigure = mlxsw_sp_span_entry_phys_deconfigure,
134};
135
136static int mlxsw_sp_span_dmac(struct neigh_table *tbl,
137 const void *pkey,
138 struct net_device *l3edev,
139 unsigned char dmac[ETH_ALEN])
140{
141 struct neighbour *neigh = neigh_lookup(tbl, pkey, l3edev);
142 int err = 0;
143
144 if (!neigh) {
145 neigh = neigh_create(tbl, pkey, l3edev);
146 if (IS_ERR(neigh))
147 return PTR_ERR(neigh);
148 }
149
150 neigh_event_send(neigh, NULL);
151
152 read_lock_bh(&neigh->lock);
153 if ((neigh->nud_state & NUD_VALID) && !neigh->dead)
154 memcpy(dmac, neigh->ha, ETH_ALEN);
155 else
156 err = -ENOENT;
157 read_unlock_bh(&neigh->lock);
158
159 neigh_release(neigh);
160 return err;
161}
162
163static int
164mlxsw_sp_span_entry_unoffloadable(struct mlxsw_sp_span_parms *sparmsp)
165{
166 sparmsp->dest_port = NULL;
167 return 0;
168}
169
170static __maybe_unused int
171mlxsw_sp_span_entry_tunnel_parms_common(struct net_device *l3edev,
172 union mlxsw_sp_l3addr saddr,
173 union mlxsw_sp_l3addr daddr,
174 union mlxsw_sp_l3addr gw,
175 __u8 ttl,
176 struct neigh_table *tbl,
177 struct mlxsw_sp_span_parms *sparmsp)
178{
179 unsigned char dmac[ETH_ALEN];
180
181 if (mlxsw_sp_l3addr_is_zero(gw))
182 gw = daddr;
183
184 if (!l3edev || !mlxsw_sp_port_dev_check(l3edev) ||
185 mlxsw_sp_span_dmac(tbl, &gw, l3edev, dmac))
186 return mlxsw_sp_span_entry_unoffloadable(sparmsp);
187
188 sparmsp->dest_port = netdev_priv(l3edev);
189 sparmsp->ttl = ttl;
190 memcpy(sparmsp->dmac, dmac, ETH_ALEN);
191 memcpy(sparmsp->smac, l3edev->dev_addr, ETH_ALEN);
192 sparmsp->saddr = saddr;
193 sparmsp->daddr = daddr;
194 return 0;
195}
196
197#if IS_ENABLED(CONFIG_NET_IPGRE)
198static struct net_device *
199mlxsw_sp_span_gretap4_route(const struct net_device *to_dev,
200 __be32 *saddrp, __be32 *daddrp)
201{
202 struct ip_tunnel *tun = netdev_priv(to_dev);
203 struct net_device *dev = NULL;
204 struct ip_tunnel_parm parms;
205 struct rtable *rt = NULL;
206 struct flowi4 fl4;
207
208 /* We assume "dev" stays valid after rt is put. */
209 ASSERT_RTNL();
210
211 parms = mlxsw_sp_ipip_netdev_parms4(to_dev);
212 ip_tunnel_init_flow(&fl4, parms.iph.protocol, *daddrp, *saddrp,
213 0, 0, parms.link, tun->fwmark);
214
215 rt = ip_route_output_key(tun->net, &fl4);
216 if (IS_ERR(rt))
217 return NULL;
218
219 if (rt->rt_type != RTN_UNICAST)
220 goto out;
221
222 dev = rt->dst.dev;
223 *saddrp = fl4.saddr;
224 *daddrp = rt->rt_gateway;
225
226out:
227 ip_rt_put(rt);
228 return dev;
229}
230
231static int
232mlxsw_sp_span_entry_gretap4_parms(const struct net_device *to_dev,
233 struct mlxsw_sp_span_parms *sparmsp)
234{
235 struct ip_tunnel_parm tparm = mlxsw_sp_ipip_netdev_parms4(to_dev);
236 union mlxsw_sp_l3addr saddr = { .addr4 = tparm.iph.saddr };
237 union mlxsw_sp_l3addr daddr = { .addr4 = tparm.iph.daddr };
238 bool inherit_tos = tparm.iph.tos & 0x1;
239 bool inherit_ttl = !tparm.iph.ttl;
240 union mlxsw_sp_l3addr gw = daddr;
241 struct net_device *l3edev;
242
243 if (!(to_dev->flags & IFF_UP) ||
244 /* Reject tunnels with GRE keys, checksums, etc. */
245 tparm.i_flags || tparm.o_flags ||
246 /* Require a fixed TTL and a TOS copied from the mirrored packet. */
247 inherit_ttl || !inherit_tos ||
248 /* A destination address may not be "any". */
249 mlxsw_sp_l3addr_is_zero(daddr))
250 return mlxsw_sp_span_entry_unoffloadable(sparmsp);
251
252 l3edev = mlxsw_sp_span_gretap4_route(to_dev, &saddr.addr4, &gw.addr4);
253 return mlxsw_sp_span_entry_tunnel_parms_common(l3edev, saddr, daddr, gw,
254 tparm.iph.ttl,
255 &arp_tbl, sparmsp);
256}
257
258static int
259mlxsw_sp_span_entry_gretap4_configure(struct mlxsw_sp_span_entry *span_entry,
260 struct mlxsw_sp_span_parms sparms)
261{
262 struct mlxsw_sp_port *dest_port = sparms.dest_port;
263 struct mlxsw_sp *mlxsw_sp = dest_port->mlxsw_sp;
264 u8 local_port = dest_port->local_port;
265 char mpat_pl[MLXSW_REG_MPAT_LEN];
266 int pa_id = span_entry->id;
267
268 /* Create a new port analayzer entry for local_port. */
269 mlxsw_reg_mpat_pack(mpat_pl, pa_id, local_port, true,
270 MLXSW_REG_MPAT_SPAN_TYPE_REMOTE_ETH_L3);
271 mlxsw_reg_mpat_eth_rspan_l2_pack(mpat_pl,
272 MLXSW_REG_MPAT_ETH_RSPAN_VERSION_NO_HEADER,
273 sparms.dmac, false);
274 mlxsw_reg_mpat_eth_rspan_l3_ipv4_pack(mpat_pl,
275 sparms.ttl, sparms.smac,
276 be32_to_cpu(sparms.saddr.addr4),
277 be32_to_cpu(sparms.daddr.addr4));
278
279 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpat), mpat_pl);
280}
281
282static void
283mlxsw_sp_span_entry_gretap4_deconfigure(struct mlxsw_sp_span_entry *span_entry)
284{
285 mlxsw_sp_span_entry_deconfigure_common(span_entry,
286 MLXSW_REG_MPAT_SPAN_TYPE_REMOTE_ETH_L3);
287}
288
289static const struct mlxsw_sp_span_entry_ops mlxsw_sp_span_entry_ops_gretap4 = {
290 .can_handle = is_gretap_dev,
291 .parms = mlxsw_sp_span_entry_gretap4_parms,
292 .configure = mlxsw_sp_span_entry_gretap4_configure,
293 .deconfigure = mlxsw_sp_span_entry_gretap4_deconfigure,
294};
295#endif
296
297#if IS_ENABLED(CONFIG_IPV6_GRE)
298static struct net_device *
299mlxsw_sp_span_gretap6_route(const struct net_device *to_dev,
300 struct in6_addr *saddrp,
301 struct in6_addr *daddrp)
302{
303 struct ip6_tnl *t = netdev_priv(to_dev);
304 struct flowi6 fl6 = t->fl.u.ip6;
305 struct net_device *dev = NULL;
306 struct dst_entry *dst;
307 struct rt6_info *rt6;
308
309 /* We assume "dev" stays valid after dst is released. */
310 ASSERT_RTNL();
311
312 fl6.flowi6_mark = t->parms.fwmark;
313 if (!ip6_tnl_xmit_ctl(t, &fl6.saddr, &fl6.daddr))
314 return NULL;
315
316 dst = ip6_route_output(t->net, NULL, &fl6);
317 if (!dst || dst->error)
318 goto out;
319
320 rt6 = container_of(dst, struct rt6_info, dst);
321
322 dev = dst->dev;
323 *saddrp = fl6.saddr;
324 *daddrp = rt6->rt6i_gateway;
325
326out:
327 dst_release(dst);
328 return dev;
329}
330
331static int
332mlxsw_sp_span_entry_gretap6_parms(const struct net_device *to_dev,
333 struct mlxsw_sp_span_parms *sparmsp)
334{
335 struct __ip6_tnl_parm tparm = mlxsw_sp_ipip_netdev_parms6(to_dev);
336 bool inherit_tos = tparm.flags & IP6_TNL_F_USE_ORIG_TCLASS;
337 union mlxsw_sp_l3addr saddr = { .addr6 = tparm.laddr };
338 union mlxsw_sp_l3addr daddr = { .addr6 = tparm.raddr };
339 bool inherit_ttl = !tparm.hop_limit;
340 union mlxsw_sp_l3addr gw = daddr;
341 struct net_device *l3edev;
342
343 if (!(to_dev->flags & IFF_UP) ||
344 /* Reject tunnels with GRE keys, checksums, etc. */
345 tparm.i_flags || tparm.o_flags ||
346 /* Require a fixed TTL and a TOS copied from the mirrored packet. */
347 inherit_ttl || !inherit_tos ||
348 /* A destination address may not be "any". */
349 mlxsw_sp_l3addr_is_zero(daddr))
350 return mlxsw_sp_span_entry_unoffloadable(sparmsp);
351
352 l3edev = mlxsw_sp_span_gretap6_route(to_dev, &saddr.addr6, &gw.addr6);
353 return mlxsw_sp_span_entry_tunnel_parms_common(l3edev, saddr, daddr, gw,
354 tparm.hop_limit,
355 &nd_tbl, sparmsp);
356}
357
358static int
359mlxsw_sp_span_entry_gretap6_configure(struct mlxsw_sp_span_entry *span_entry,
360 struct mlxsw_sp_span_parms sparms)
361{
362 struct mlxsw_sp_port *dest_port = sparms.dest_port;
363 struct mlxsw_sp *mlxsw_sp = dest_port->mlxsw_sp;
364 u8 local_port = dest_port->local_port;
365 char mpat_pl[MLXSW_REG_MPAT_LEN];
366 int pa_id = span_entry->id;
367
368 /* Create a new port analayzer entry for local_port. */
369 mlxsw_reg_mpat_pack(mpat_pl, pa_id, local_port, true,
370 MLXSW_REG_MPAT_SPAN_TYPE_REMOTE_ETH_L3);
371 mlxsw_reg_mpat_eth_rspan_l2_pack(mpat_pl,
372 MLXSW_REG_MPAT_ETH_RSPAN_VERSION_NO_HEADER,
373 sparms.dmac, false);
374 mlxsw_reg_mpat_eth_rspan_l3_ipv6_pack(mpat_pl, sparms.ttl, sparms.smac,
375 sparms.saddr.addr6,
376 sparms.daddr.addr6);
377
378 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpat), mpat_pl);
379}
380
381static void
382mlxsw_sp_span_entry_gretap6_deconfigure(struct mlxsw_sp_span_entry *span_entry)
383{
384 mlxsw_sp_span_entry_deconfigure_common(span_entry,
385 MLXSW_REG_MPAT_SPAN_TYPE_REMOTE_ETH_L3);
386}
387
388static const
389struct mlxsw_sp_span_entry_ops mlxsw_sp_span_entry_ops_gretap6 = {
390 .can_handle = is_ip6gretap_dev,
391 .parms = mlxsw_sp_span_entry_gretap6_parms,
392 .configure = mlxsw_sp_span_entry_gretap6_configure,
393 .deconfigure = mlxsw_sp_span_entry_gretap6_deconfigure,
394};
395#endif
396
397static const
398struct mlxsw_sp_span_entry_ops *const mlxsw_sp_span_entry_types[] = {
399 &mlxsw_sp_span_entry_ops_phys,
400#if IS_ENABLED(CONFIG_NET_IPGRE)
401 &mlxsw_sp_span_entry_ops_gretap4,
402#endif
403#if IS_ENABLED(CONFIG_IPV6_GRE)
404 &mlxsw_sp_span_entry_ops_gretap6,
405#endif
406};
407
408static int
409mlxsw_sp_span_entry_nop_parms(const struct net_device *to_dev,
410 struct mlxsw_sp_span_parms *sparmsp)
411{
412 return mlxsw_sp_span_entry_unoffloadable(sparmsp);
413}
414
415static int
416mlxsw_sp_span_entry_nop_configure(struct mlxsw_sp_span_entry *span_entry,
417 struct mlxsw_sp_span_parms sparms)
418{
419 return 0;
420}
421
422static void
423mlxsw_sp_span_entry_nop_deconfigure(struct mlxsw_sp_span_entry *span_entry)
424{
425}
426
427static const struct mlxsw_sp_span_entry_ops mlxsw_sp_span_entry_ops_nop = {
428 .parms = mlxsw_sp_span_entry_nop_parms,
429 .configure = mlxsw_sp_span_entry_nop_configure,
430 .deconfigure = mlxsw_sp_span_entry_nop_deconfigure,
431};
432
433static void
434mlxsw_sp_span_entry_configure(struct mlxsw_sp *mlxsw_sp,
435 struct mlxsw_sp_span_entry *span_entry,
436 struct mlxsw_sp_span_parms sparms)
437{
438 if (sparms.dest_port) {
439 if (sparms.dest_port->mlxsw_sp != mlxsw_sp) {
440 netdev_err(span_entry->to_dev, "Cannot mirror to %s, which belongs to a different mlxsw instance",
441 sparms.dest_port->dev->name);
442 sparms.dest_port = NULL;
443 } else if (span_entry->ops->configure(span_entry, sparms)) {
444 netdev_err(span_entry->to_dev, "Failed to offload mirror to %s",
445 sparms.dest_port->dev->name);
446 sparms.dest_port = NULL;
447 }
448 }
449
450 span_entry->parms = sparms;
451}
452
453static void
454mlxsw_sp_span_entry_deconfigure(struct mlxsw_sp_span_entry *span_entry)
455{
456 if (span_entry->parms.dest_port)
457 span_entry->ops->deconfigure(span_entry);
458}
459
460static struct mlxsw_sp_span_entry *
461mlxsw_sp_span_entry_create(struct mlxsw_sp *mlxsw_sp,
462 const struct net_device *to_dev,
463 const struct mlxsw_sp_span_entry_ops *ops,
464 struct mlxsw_sp_span_parms sparms)
465{
466 struct mlxsw_sp_span_entry *span_entry = NULL;
467 int i;
468
469 /* find a free entry to use */
470 for (i = 0; i < mlxsw_sp->span.entries_count; i++) {
471 if (!mlxsw_sp->span.entries[i].ref_count) {
472 span_entry = &mlxsw_sp->span.entries[i];
473 break;
474 }
475 }
476 if (!span_entry)
477 return NULL;
478
479 span_entry->ops = ops;
480 span_entry->ref_count = 1;
481 span_entry->to_dev = to_dev;
482 mlxsw_sp_span_entry_configure(mlxsw_sp, span_entry, sparms);
483
484 return span_entry;
485}
486
487static void mlxsw_sp_span_entry_destroy(struct mlxsw_sp_span_entry *span_entry)
488{
489 mlxsw_sp_span_entry_deconfigure(span_entry);
490}
491
492struct mlxsw_sp_span_entry *
493mlxsw_sp_span_entry_find_by_port(struct mlxsw_sp *mlxsw_sp,
494 const struct net_device *to_dev)
495{
496 int i;
497
498 for (i = 0; i < mlxsw_sp->span.entries_count; i++) {
499 struct mlxsw_sp_span_entry *curr = &mlxsw_sp->span.entries[i];
500
501 if (curr->ref_count && curr->to_dev == to_dev)
502 return curr;
503 }
504 return NULL;
505}
506
507void mlxsw_sp_span_entry_invalidate(struct mlxsw_sp *mlxsw_sp,
508 struct mlxsw_sp_span_entry *span_entry)
509{
510 mlxsw_sp_span_entry_deconfigure(span_entry);
511 span_entry->ops = &mlxsw_sp_span_entry_ops_nop;
512}
513
514static struct mlxsw_sp_span_entry *
515mlxsw_sp_span_entry_find_by_id(struct mlxsw_sp *mlxsw_sp, int span_id)
516{
517 int i;
518
519 for (i = 0; i < mlxsw_sp->span.entries_count; i++) {
520 struct mlxsw_sp_span_entry *curr = &mlxsw_sp->span.entries[i];
521
522 if (curr->ref_count && curr->id == span_id)
523 return curr;
524 }
525 return NULL;
526}
527
528static struct mlxsw_sp_span_entry *
529mlxsw_sp_span_entry_get(struct mlxsw_sp *mlxsw_sp,
530 const struct net_device *to_dev,
531 const struct mlxsw_sp_span_entry_ops *ops,
532 struct mlxsw_sp_span_parms sparms)
533{
534 struct mlxsw_sp_span_entry *span_entry;
535
536 span_entry = mlxsw_sp_span_entry_find_by_port(mlxsw_sp, to_dev);
537 if (span_entry) {
538 /* Already exists, just take a reference */
539 span_entry->ref_count++;
540 return span_entry;
541 }
542
543 return mlxsw_sp_span_entry_create(mlxsw_sp, to_dev, ops, sparms);
544}
545
546static int mlxsw_sp_span_entry_put(struct mlxsw_sp *mlxsw_sp,
547 struct mlxsw_sp_span_entry *span_entry)
548{
549 WARN_ON(!span_entry->ref_count);
550 if (--span_entry->ref_count == 0)
551 mlxsw_sp_span_entry_destroy(span_entry);
552 return 0;
553}
554
555static bool mlxsw_sp_span_is_egress_mirror(struct mlxsw_sp_port *port)
556{
557 struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
558 struct mlxsw_sp_span_inspected_port *p;
559 int i;
560
561 for (i = 0; i < mlxsw_sp->span.entries_count; i++) {
562 struct mlxsw_sp_span_entry *curr = &mlxsw_sp->span.entries[i];
563
564 list_for_each_entry(p, &curr->bound_ports_list, list)
565 if (p->local_port == port->local_port &&
566 p->type == MLXSW_SP_SPAN_EGRESS)
567 return true;
568 }
569
570 return false;
571}
572
573static int mlxsw_sp_span_mtu_to_buffsize(const struct mlxsw_sp *mlxsw_sp,
574 int mtu)
575{
576 return mlxsw_sp_bytes_cells(mlxsw_sp, mtu * 5 / 2) + 1;
577}
578
579int mlxsw_sp_span_port_mtu_update(struct mlxsw_sp_port *port, u16 mtu)
580{
581 struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
582 char sbib_pl[MLXSW_REG_SBIB_LEN];
583 int err;
584
585 /* If port is egress mirrored, the shared buffer size should be
586 * updated according to the mtu value
587 */
588 if (mlxsw_sp_span_is_egress_mirror(port)) {
589 u32 buffsize = mlxsw_sp_span_mtu_to_buffsize(mlxsw_sp, mtu);
590
591 mlxsw_reg_sbib_pack(sbib_pl, port->local_port, buffsize);
592 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl);
593 if (err) {
594 netdev_err(port->dev, "Could not update shared buffer for mirroring\n");
595 return err;
596 }
597 }
598
599 return 0;
600}
601
602static struct mlxsw_sp_span_inspected_port *
603mlxsw_sp_span_entry_bound_port_find(struct mlxsw_sp_port *port,
604 struct mlxsw_sp_span_entry *span_entry)
605{
606 struct mlxsw_sp_span_inspected_port *p;
607
608 list_for_each_entry(p, &span_entry->bound_ports_list, list)
609 if (port->local_port == p->local_port)
610 return p;
611 return NULL;
612}
613
614static int
615mlxsw_sp_span_inspected_port_bind(struct mlxsw_sp_port *port,
616 struct mlxsw_sp_span_entry *span_entry,
617 enum mlxsw_sp_span_type type,
618 bool bind)
619{
620 struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
621 char mpar_pl[MLXSW_REG_MPAR_LEN];
622 int pa_id = span_entry->id;
623
624 /* bind the port to the SPAN entry */
625 mlxsw_reg_mpar_pack(mpar_pl, port->local_port,
626 (enum mlxsw_reg_mpar_i_e)type, bind, pa_id);
627 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpar), mpar_pl);
628}
629
630static int
631mlxsw_sp_span_inspected_port_add(struct mlxsw_sp_port *port,
632 struct mlxsw_sp_span_entry *span_entry,
633 enum mlxsw_sp_span_type type,
634 bool bind)
635{
636 struct mlxsw_sp_span_inspected_port *inspected_port;
637 struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
638 char sbib_pl[MLXSW_REG_SBIB_LEN];
639 int err;
640
641 /* if it is an egress SPAN, bind a shared buffer to it */
642 if (type == MLXSW_SP_SPAN_EGRESS) {
643 u32 buffsize = mlxsw_sp_span_mtu_to_buffsize(mlxsw_sp,
644 port->dev->mtu);
645
646 mlxsw_reg_sbib_pack(sbib_pl, port->local_port, buffsize);
647 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl);
648 if (err) {
649 netdev_err(port->dev, "Could not create shared buffer for mirroring\n");
650 return err;
651 }
652 }
653
654 if (bind) {
655 err = mlxsw_sp_span_inspected_port_bind(port, span_entry, type,
656 true);
657 if (err)
658 goto err_port_bind;
659 }
660
661 inspected_port = kzalloc(sizeof(*inspected_port), GFP_KERNEL);
662 if (!inspected_port) {
663 err = -ENOMEM;
664 goto err_inspected_port_alloc;
665 }
666 inspected_port->local_port = port->local_port;
667 inspected_port->type = type;
668 list_add_tail(&inspected_port->list, &span_entry->bound_ports_list);
669
670 return 0;
671
672err_inspected_port_alloc:
673 if (bind)
674 mlxsw_sp_span_inspected_port_bind(port, span_entry, type,
675 false);
676err_port_bind:
677 if (type == MLXSW_SP_SPAN_EGRESS) {
678 mlxsw_reg_sbib_pack(sbib_pl, port->local_port, 0);
679 mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl);
680 }
681 return err;
682}
683
684static void
685mlxsw_sp_span_inspected_port_del(struct mlxsw_sp_port *port,
686 struct mlxsw_sp_span_entry *span_entry,
687 enum mlxsw_sp_span_type type,
688 bool bind)
689{
690 struct mlxsw_sp_span_inspected_port *inspected_port;
691 struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
692 char sbib_pl[MLXSW_REG_SBIB_LEN];
693
694 inspected_port = mlxsw_sp_span_entry_bound_port_find(port, span_entry);
695 if (!inspected_port)
696 return;
697
698 if (bind)
699 mlxsw_sp_span_inspected_port_bind(port, span_entry, type,
700 false);
701 /* remove the SBIB buffer if it was egress SPAN */
702 if (type == MLXSW_SP_SPAN_EGRESS) {
703 mlxsw_reg_sbib_pack(sbib_pl, port->local_port, 0);
704 mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl);
705 }
706
707 mlxsw_sp_span_entry_put(mlxsw_sp, span_entry);
708
709 list_del(&inspected_port->list);
710 kfree(inspected_port);
711}
712
713static const struct mlxsw_sp_span_entry_ops *
714mlxsw_sp_span_entry_ops(struct mlxsw_sp *mlxsw_sp,
715 const struct net_device *to_dev)
716{
717 size_t i;
718
719 for (i = 0; i < ARRAY_SIZE(mlxsw_sp_span_entry_types); ++i)
720 if (mlxsw_sp_span_entry_types[i]->can_handle(to_dev))
721 return mlxsw_sp_span_entry_types[i];
722
723 return NULL;
724}
725
726int mlxsw_sp_span_mirror_add(struct mlxsw_sp_port *from,
727 const struct net_device *to_dev,
728 enum mlxsw_sp_span_type type, bool bind,
729 int *p_span_id)
730{
731 struct mlxsw_sp *mlxsw_sp = from->mlxsw_sp;
732 const struct mlxsw_sp_span_entry_ops *ops;
733 struct mlxsw_sp_span_parms sparms = {0};
734 struct mlxsw_sp_span_entry *span_entry;
735 int err;
736
737 ops = mlxsw_sp_span_entry_ops(mlxsw_sp, to_dev);
738 if (!ops) {
739 netdev_err(to_dev, "Cannot mirror to %s", to_dev->name);
740 return -EOPNOTSUPP;
741 }
742
743 err = ops->parms(to_dev, &sparms);
744 if (err)
745 return err;
746
747 span_entry = mlxsw_sp_span_entry_get(mlxsw_sp, to_dev, ops, sparms);
748 if (!span_entry)
749 return -ENOENT;
750
751 netdev_dbg(from->dev, "Adding inspected port to SPAN entry %d\n",
752 span_entry->id);
753
754 err = mlxsw_sp_span_inspected_port_add(from, span_entry, type, bind);
755 if (err)
756 goto err_port_bind;
757
758 *p_span_id = span_entry->id;
759 return 0;
760
761err_port_bind:
762 mlxsw_sp_span_entry_put(mlxsw_sp, span_entry);
763 return err;
764}
765
766void mlxsw_sp_span_mirror_del(struct mlxsw_sp_port *from, int span_id,
767 enum mlxsw_sp_span_type type, bool bind)
768{
769 struct mlxsw_sp_span_entry *span_entry;
770
771 span_entry = mlxsw_sp_span_entry_find_by_id(from->mlxsw_sp, span_id);
772 if (!span_entry) {
773 netdev_err(from->dev, "no span entry found\n");
774 return;
775 }
776
777 netdev_dbg(from->dev, "removing inspected port from SPAN entry %d\n",
778 span_entry->id);
779 mlxsw_sp_span_inspected_port_del(from, span_entry, type, bind);
780}
781
782void mlxsw_sp_span_respin(struct mlxsw_sp *mlxsw_sp)
783{
784 int i;
785 int err;
786
787 ASSERT_RTNL();
788 for (i = 0; i < mlxsw_sp->span.entries_count; i++) {
789 struct mlxsw_sp_span_entry *curr = &mlxsw_sp->span.entries[i];
790 struct mlxsw_sp_span_parms sparms = {0};
791
792 if (!curr->ref_count)
793 continue;
794
795 err = curr->ops->parms(curr->to_dev, &sparms);
796 if (err)
797 continue;
798
799 if (memcmp(&sparms, &curr->parms, sizeof(sparms))) {
800 mlxsw_sp_span_entry_deconfigure(curr);
801 mlxsw_sp_span_entry_configure(mlxsw_sp, curr, sparms);
802 }
803 }
804}
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h
new file mode 100644
index 000000000000..4b87ec20e658
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h
@@ -0,0 +1,107 @@
1/*
2 * drivers/net/ethernet/mellanox/mlxsw/mlxsw_span.h
3 * Copyright (c) 2018 Mellanox Technologies. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the names of the copyright holders nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * Alternatively, this software may be distributed under the terms of the
18 * GNU General Public License ("GPL") version 2 as published by the Free
19 * Software Foundation.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#ifndef _MLXSW_SPECTRUM_SPAN_H
35#define _MLXSW_SPECTRUM_SPAN_H
36
37#include <linux/types.h>
38#include <linux/if_ether.h>
39
40#include "spectrum_router.h"
41
42struct mlxsw_sp;
43struct mlxsw_sp_port;
44
45enum mlxsw_sp_span_type {
46 MLXSW_SP_SPAN_EGRESS,
47 MLXSW_SP_SPAN_INGRESS
48};
49
50struct mlxsw_sp_span_inspected_port {
51 struct list_head list;
52 enum mlxsw_sp_span_type type;
53 u8 local_port;
54
55 /* Whether this is a directly bound mirror (port-to-port) or an ACL. */
56 bool bound;
57};
58
59struct mlxsw_sp_span_parms {
60 struct mlxsw_sp_port *dest_port; /* NULL for unoffloaded SPAN. */
61 unsigned int ttl;
62 unsigned char dmac[ETH_ALEN];
63 unsigned char smac[ETH_ALEN];
64 union mlxsw_sp_l3addr daddr;
65 union mlxsw_sp_l3addr saddr;
66};
67
68struct mlxsw_sp_span_entry_ops;
69
70struct mlxsw_sp_span_entry {
71 const struct net_device *to_dev;
72 const struct mlxsw_sp_span_entry_ops *ops;
73 struct mlxsw_sp_span_parms parms;
74 struct list_head bound_ports_list;
75 int ref_count;
76 int id;
77};
78
79struct mlxsw_sp_span_entry_ops {
80 bool (*can_handle)(const struct net_device *to_dev);
81 int (*parms)(const struct net_device *to_dev,
82 struct mlxsw_sp_span_parms *sparmsp);
83 int (*configure)(struct mlxsw_sp_span_entry *span_entry,
84 struct mlxsw_sp_span_parms sparms);
85 void (*deconfigure)(struct mlxsw_sp_span_entry *span_entry);
86};
87
88int mlxsw_sp_span_init(struct mlxsw_sp *mlxsw_sp);
89void mlxsw_sp_span_fini(struct mlxsw_sp *mlxsw_sp);
90void mlxsw_sp_span_respin(struct mlxsw_sp *mlxsw_sp);
91
92int mlxsw_sp_span_mirror_add(struct mlxsw_sp_port *from,
93 const struct net_device *to_dev,
94 enum mlxsw_sp_span_type type,
95 bool bind, int *p_span_id);
96void mlxsw_sp_span_mirror_del(struct mlxsw_sp_port *from, int span_id,
97 enum mlxsw_sp_span_type type, bool bind);
98struct mlxsw_sp_span_entry *
99mlxsw_sp_span_entry_find_by_port(struct mlxsw_sp *mlxsw_sp,
100 const struct net_device *to_dev);
101
102void mlxsw_sp_span_entry_invalidate(struct mlxsw_sp *mlxsw_sp,
103 struct mlxsw_sp_span_entry *span_entry);
104
105int mlxsw_sp_span_port_mtu_update(struct mlxsw_sp_port *port, u16 mtu);
106
107#endif
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
index 161bcdc012f0..c11c9a635866 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -1844,7 +1844,7 @@ mlxsw_sp_bridge_8021q_port_join(struct mlxsw_sp_bridge_device *bridge_device,
1844 struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan; 1844 struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
1845 1845
1846 if (is_vlan_dev(bridge_port->dev)) { 1846 if (is_vlan_dev(bridge_port->dev)) {
1847 NL_SET_ERR_MSG(extack, "spectrum: Can not enslave a VLAN device to a VLAN-aware bridge"); 1847 NL_SET_ERR_MSG_MOD(extack, "Can not enslave a VLAN device to a VLAN-aware bridge");
1848 return -EINVAL; 1848 return -EINVAL;
1849 } 1849 }
1850 1850
@@ -1907,20 +1907,16 @@ mlxsw_sp_bridge_8021d_port_join(struct mlxsw_sp_bridge_device *bridge_device,
1907 struct netlink_ext_ack *extack) 1907 struct netlink_ext_ack *extack)
1908{ 1908{
1909 struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan; 1909 struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
1910 struct net_device *dev = bridge_port->dev;
1910 u16 vid; 1911 u16 vid;
1911 1912
1912 if (!is_vlan_dev(bridge_port->dev)) { 1913 vid = is_vlan_dev(dev) ? vlan_dev_vlan_id(dev) : 1;
1913 NL_SET_ERR_MSG(extack, "spectrum: Only VLAN devices can be enslaved to a VLAN-unaware bridge");
1914 return -EINVAL;
1915 }
1916 vid = vlan_dev_vlan_id(bridge_port->dev);
1917
1918 mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_vid(mlxsw_sp_port, vid); 1914 mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_vid(mlxsw_sp_port, vid);
1919 if (WARN_ON(!mlxsw_sp_port_vlan)) 1915 if (WARN_ON(!mlxsw_sp_port_vlan))
1920 return -EINVAL; 1916 return -EINVAL;
1921 1917
1922 if (mlxsw_sp_port_is_br_member(mlxsw_sp_port, bridge_device->dev)) { 1918 if (mlxsw_sp_port_is_br_member(mlxsw_sp_port, bridge_device->dev)) {
1923 NL_SET_ERR_MSG(extack, "spectrum: Can not bridge VLAN uppers of the same port"); 1919 NL_SET_ERR_MSG_MOD(extack, "Can not bridge VLAN uppers of the same port");
1924 return -EINVAL; 1920 return -EINVAL;
1925 } 1921 }
1926 1922
@@ -1937,8 +1933,10 @@ mlxsw_sp_bridge_8021d_port_leave(struct mlxsw_sp_bridge_device *bridge_device,
1937 struct mlxsw_sp_port *mlxsw_sp_port) 1933 struct mlxsw_sp_port *mlxsw_sp_port)
1938{ 1934{
1939 struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan; 1935 struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
1940 u16 vid = vlan_dev_vlan_id(bridge_port->dev); 1936 struct net_device *dev = bridge_port->dev;
1937 u16 vid;
1941 1938
1939 vid = is_vlan_dev(dev) ? vlan_dev_vlan_id(dev) : 1;
1942 mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_vid(mlxsw_sp_port, vid); 1940 mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_vid(mlxsw_sp_port, vid);
1943 if (WARN_ON(!mlxsw_sp_port_vlan)) 1941 if (WARN_ON(!mlxsw_sp_port_vlan))
1944 return; 1942 return;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/switchx2.c b/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
index f3c29bbf07e2..c87b0934a405 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
@@ -789,7 +789,7 @@ mlxsw_sx_port_get_link_ksettings(struct net_device *dev,
789 u32 supported, advertising, lp_advertising; 789 u32 supported, advertising, lp_advertising;
790 int err; 790 int err;
791 791
792 mlxsw_reg_ptys_eth_pack(ptys_pl, mlxsw_sx_port->local_port, 0); 792 mlxsw_reg_ptys_eth_pack(ptys_pl, mlxsw_sx_port->local_port, 0, false);
793 err = mlxsw_reg_query(mlxsw_sx->core, MLXSW_REG(ptys), ptys_pl); 793 err = mlxsw_reg_query(mlxsw_sx->core, MLXSW_REG(ptys), ptys_pl);
794 if (err) { 794 if (err) {
795 netdev_err(dev, "Failed to get proto"); 795 netdev_err(dev, "Failed to get proto");
@@ -879,7 +879,7 @@ mlxsw_sx_port_set_link_ksettings(struct net_device *dev,
879 mlxsw_sx_to_ptys_advert_link(advertising) : 879 mlxsw_sx_to_ptys_advert_link(advertising) :
880 mlxsw_sx_to_ptys_speed(speed); 880 mlxsw_sx_to_ptys_speed(speed);
881 881
882 mlxsw_reg_ptys_eth_pack(ptys_pl, mlxsw_sx_port->local_port, 0); 882 mlxsw_reg_ptys_eth_pack(ptys_pl, mlxsw_sx_port->local_port, 0, false);
883 err = mlxsw_reg_query(mlxsw_sx->core, MLXSW_REG(ptys), ptys_pl); 883 err = mlxsw_reg_query(mlxsw_sx->core, MLXSW_REG(ptys), ptys_pl);
884 if (err) { 884 if (err) {
885 netdev_err(dev, "Failed to get proto"); 885 netdev_err(dev, "Failed to get proto");
@@ -897,7 +897,7 @@ mlxsw_sx_port_set_link_ksettings(struct net_device *dev,
897 return 0; 897 return 0;
898 898
899 mlxsw_reg_ptys_eth_pack(ptys_pl, mlxsw_sx_port->local_port, 899 mlxsw_reg_ptys_eth_pack(ptys_pl, mlxsw_sx_port->local_port,
900 eth_proto_new); 900 eth_proto_new, true);
901 err = mlxsw_reg_write(mlxsw_sx->core, MLXSW_REG(ptys), ptys_pl); 901 err = mlxsw_reg_write(mlxsw_sx->core, MLXSW_REG(ptys), ptys_pl);
902 if (err) { 902 if (err) {
903 netdev_err(dev, "Failed to set proto admin"); 903 netdev_err(dev, "Failed to set proto admin");
@@ -1029,7 +1029,7 @@ mlxsw_sx_port_speed_by_width_set(struct mlxsw_sx_port *mlxsw_sx_port, u8 width)
1029 1029
1030 eth_proto_admin = mlxsw_sx_to_ptys_upper_speed(upper_speed); 1030 eth_proto_admin = mlxsw_sx_to_ptys_upper_speed(upper_speed);
1031 mlxsw_reg_ptys_eth_pack(ptys_pl, mlxsw_sx_port->local_port, 1031 mlxsw_reg_ptys_eth_pack(ptys_pl, mlxsw_sx_port->local_port,
1032 eth_proto_admin); 1032 eth_proto_admin, true);
1033 return mlxsw_reg_write(mlxsw_sx->core, MLXSW_REG(ptys), ptys_pl); 1033 return mlxsw_reg_write(mlxsw_sx->core, MLXSW_REG(ptys), ptys_pl);
1034} 1034}
1035 1035
diff --git a/drivers/net/ethernet/microchip/Kconfig b/drivers/net/ethernet/microchip/Kconfig
index 36a09d94b368..71dca8bd51ac 100644
--- a/drivers/net/ethernet/microchip/Kconfig
+++ b/drivers/net/ethernet/microchip/Kconfig
@@ -42,4 +42,14 @@ config ENCX24J600
42 To compile this driver as a module, choose M here. The module will be 42 To compile this driver as a module, choose M here. The module will be
43 called encx24j600. 43 called encx24j600.
44 44
45config LAN743X
46 tristate "LAN743x support"
47 depends on PCI
48 select PHYLIB
49 ---help---
50 Support for the Microchip LAN743x PCI Express Gigabit Ethernet chip
51
52 To compile this driver as a module, choose M here. The module will be
53 called lan743x.
54
45endif # NET_VENDOR_MICROCHIP 55endif # NET_VENDOR_MICROCHIP
diff --git a/drivers/net/ethernet/microchip/Makefile b/drivers/net/ethernet/microchip/Makefile
index ff78f621b59a..2e982cc249fb 100644
--- a/drivers/net/ethernet/microchip/Makefile
+++ b/drivers/net/ethernet/microchip/Makefile
@@ -4,3 +4,6 @@
4 4
5obj-$(CONFIG_ENC28J60) += enc28j60.o 5obj-$(CONFIG_ENC28J60) += enc28j60.o
6obj-$(CONFIG_ENCX24J600) += encx24j600.o encx24j600-regmap.o 6obj-$(CONFIG_ENCX24J600) += encx24j600.o encx24j600-regmap.o
7obj-$(CONFIG_LAN743X) += lan743x.o
8
9lan743x-objs := lan743x_main.o
diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c
new file mode 100644
index 000000000000..dd947e4dd3ce
--- /dev/null
+++ b/drivers/net/ethernet/microchip/lan743x_main.c
@@ -0,0 +1,2771 @@
1/* SPDX-License-Identifier: GPL-2.0+ */
2/* Copyright (C) 2018 Microchip Technology Inc. */
3
4#include <linux/module.h>
5#include <linux/pci.h>
6#include <linux/netdevice.h>
7#include <linux/etherdevice.h>
8#include <linux/crc32.h>
9#include <linux/microchipphy.h>
10#include <linux/net_tstamp.h>
11#include <linux/phy.h>
12#include <linux/rtnetlink.h>
13#include <linux/iopoll.h>
14#include "lan743x_main.h"
15
16static void lan743x_pci_cleanup(struct lan743x_adapter *adapter)
17{
18 pci_release_selected_regions(adapter->pdev,
19 pci_select_bars(adapter->pdev,
20 IORESOURCE_MEM));
21 pci_disable_device(adapter->pdev);
22}
23
24static int lan743x_pci_init(struct lan743x_adapter *adapter,
25 struct pci_dev *pdev)
26{
27 unsigned long bars = 0;
28 int ret;
29
30 adapter->pdev = pdev;
31 ret = pci_enable_device_mem(pdev);
32 if (ret)
33 goto return_error;
34
35 netif_info(adapter, probe, adapter->netdev,
36 "PCI: Vendor ID = 0x%04X, Device ID = 0x%04X\n",
37 pdev->vendor, pdev->device);
38 bars = pci_select_bars(pdev, IORESOURCE_MEM);
39 if (!test_bit(0, &bars))
40 goto disable_device;
41
42 ret = pci_request_selected_regions(pdev, bars, DRIVER_NAME);
43 if (ret)
44 goto disable_device;
45
46 pci_set_master(pdev);
47 return 0;
48
49disable_device:
50 pci_disable_device(adapter->pdev);
51
52return_error:
53 return ret;
54}
55
56static u32 lan743x_csr_read(struct lan743x_adapter *adapter, int offset)
57{
58 return ioread32(&adapter->csr.csr_address[offset]);
59}
60
61static void lan743x_csr_write(struct lan743x_adapter *adapter, int offset,
62 u32 data)
63{
64 iowrite32(data, &adapter->csr.csr_address[offset]);
65}
66
67#define LAN743X_CSR_READ_OP(offset) lan743x_csr_read(adapter, offset)
68
69static int lan743x_csr_light_reset(struct lan743x_adapter *adapter)
70{
71 u32 data;
72
73 data = lan743x_csr_read(adapter, HW_CFG);
74 data |= HW_CFG_LRST_;
75 lan743x_csr_write(adapter, HW_CFG, data);
76
77 return readx_poll_timeout(LAN743X_CSR_READ_OP, HW_CFG, data,
78 !(data & HW_CFG_LRST_), 100000, 10000000);
79}
80
81static int lan743x_csr_wait_for_bit(struct lan743x_adapter *adapter,
82 int offset, u32 bit_mask,
83 int target_value, int usleep_min,
84 int usleep_max, int count)
85{
86 u32 data;
87
88 return readx_poll_timeout(LAN743X_CSR_READ_OP, offset, data,
89 target_value == ((data & bit_mask) ? 1 : 0),
90 usleep_max, usleep_min * count);
91}
92
93static int lan743x_csr_init(struct lan743x_adapter *adapter)
94{
95 struct lan743x_csr *csr = &adapter->csr;
96 resource_size_t bar_start, bar_length;
97 int result;
98
99 bar_start = pci_resource_start(adapter->pdev, 0);
100 bar_length = pci_resource_len(adapter->pdev, 0);
101 csr->csr_address = devm_ioremap(&adapter->pdev->dev,
102 bar_start, bar_length);
103 if (!csr->csr_address) {
104 result = -ENOMEM;
105 goto clean_up;
106 }
107
108 csr->id_rev = lan743x_csr_read(adapter, ID_REV);
109 csr->fpga_rev = lan743x_csr_read(adapter, FPGA_REV);
110 netif_info(adapter, probe, adapter->netdev,
111 "ID_REV = 0x%08X, FPGA_REV = %d.%d\n",
112 csr->id_rev, FPGA_REV_GET_MAJOR_(csr->fpga_rev),
113 FPGA_REV_GET_MINOR_(csr->fpga_rev));
114 if (!ID_REV_IS_VALID_CHIP_ID_(csr->id_rev)) {
115 result = -ENODEV;
116 goto clean_up;
117 }
118
119 csr->flags = LAN743X_CSR_FLAG_SUPPORTS_INTR_AUTO_SET_CLR;
120 switch (csr->id_rev & ID_REV_CHIP_REV_MASK_) {
121 case ID_REV_CHIP_REV_A0_:
122 csr->flags |= LAN743X_CSR_FLAG_IS_A0;
123 csr->flags &= ~LAN743X_CSR_FLAG_SUPPORTS_INTR_AUTO_SET_CLR;
124 break;
125 case ID_REV_CHIP_REV_B0_:
126 csr->flags |= LAN743X_CSR_FLAG_IS_B0;
127 break;
128 }
129
130 result = lan743x_csr_light_reset(adapter);
131 if (result)
132 goto clean_up;
133 return 0;
134clean_up:
135 return result;
136}
137
138static void lan743x_intr_software_isr(void *context)
139{
140 struct lan743x_adapter *adapter = context;
141 struct lan743x_intr *intr = &adapter->intr;
142 u32 int_sts;
143
144 int_sts = lan743x_csr_read(adapter, INT_STS);
145 if (int_sts & INT_BIT_SW_GP_) {
146 lan743x_csr_write(adapter, INT_STS, INT_BIT_SW_GP_);
147 intr->software_isr_flag = 1;
148 }
149}
150
151static void lan743x_tx_isr(void *context, u32 int_sts, u32 flags)
152{
153 struct lan743x_tx *tx = context;
154 struct lan743x_adapter *adapter = tx->adapter;
155 bool enable_flag = true;
156 u32 int_en = 0;
157
158 int_en = lan743x_csr_read(adapter, INT_EN_SET);
159 if (flags & LAN743X_VECTOR_FLAG_SOURCE_ENABLE_CLEAR) {
160 lan743x_csr_write(adapter, INT_EN_CLR,
161 INT_BIT_DMA_TX_(tx->channel_number));
162 }
163
164 if (int_sts & INT_BIT_DMA_TX_(tx->channel_number)) {
165 u32 ioc_bit = DMAC_INT_BIT_TX_IOC_(tx->channel_number);
166 u32 dmac_int_sts;
167 u32 dmac_int_en;
168
169 if (flags & LAN743X_VECTOR_FLAG_SOURCE_STATUS_READ)
170 dmac_int_sts = lan743x_csr_read(adapter, DMAC_INT_STS);
171 else
172 dmac_int_sts = ioc_bit;
173 if (flags & LAN743X_VECTOR_FLAG_SOURCE_ENABLE_CHECK)
174 dmac_int_en = lan743x_csr_read(adapter,
175 DMAC_INT_EN_SET);
176 else
177 dmac_int_en = ioc_bit;
178
179 dmac_int_en &= ioc_bit;
180 dmac_int_sts &= dmac_int_en;
181 if (dmac_int_sts & ioc_bit) {
182 napi_schedule(&tx->napi);
183 enable_flag = false;/* poll func will enable later */
184 }
185 }
186
187 if (enable_flag)
188 /* enable isr */
189 lan743x_csr_write(adapter, INT_EN_SET,
190 INT_BIT_DMA_TX_(tx->channel_number));
191}
192
193static void lan743x_rx_isr(void *context, u32 int_sts, u32 flags)
194{
195 struct lan743x_rx *rx = context;
196 struct lan743x_adapter *adapter = rx->adapter;
197 bool enable_flag = true;
198
199 if (flags & LAN743X_VECTOR_FLAG_SOURCE_ENABLE_CLEAR) {
200 lan743x_csr_write(adapter, INT_EN_CLR,
201 INT_BIT_DMA_RX_(rx->channel_number));
202 }
203
204 if (int_sts & INT_BIT_DMA_RX_(rx->channel_number)) {
205 u32 rx_frame_bit = DMAC_INT_BIT_RXFRM_(rx->channel_number);
206 u32 dmac_int_sts;
207 u32 dmac_int_en;
208
209 if (flags & LAN743X_VECTOR_FLAG_SOURCE_STATUS_READ)
210 dmac_int_sts = lan743x_csr_read(adapter, DMAC_INT_STS);
211 else
212 dmac_int_sts = rx_frame_bit;
213 if (flags & LAN743X_VECTOR_FLAG_SOURCE_ENABLE_CHECK)
214 dmac_int_en = lan743x_csr_read(adapter,
215 DMAC_INT_EN_SET);
216 else
217 dmac_int_en = rx_frame_bit;
218
219 dmac_int_en &= rx_frame_bit;
220 dmac_int_sts &= dmac_int_en;
221 if (dmac_int_sts & rx_frame_bit) {
222 napi_schedule(&rx->napi);
223 enable_flag = false;/* poll funct will enable later */
224 }
225 }
226
227 if (enable_flag) {
228 /* enable isr */
229 lan743x_csr_write(adapter, INT_EN_SET,
230 INT_BIT_DMA_RX_(rx->channel_number));
231 }
232}
233
234static void lan743x_intr_shared_isr(void *context, u32 int_sts, u32 flags)
235{
236 struct lan743x_adapter *adapter = context;
237 unsigned int channel;
238
239 if (int_sts & INT_BIT_ALL_RX_) {
240 for (channel = 0; channel < LAN743X_USED_RX_CHANNELS;
241 channel++) {
242 u32 int_bit = INT_BIT_DMA_RX_(channel);
243
244 if (int_sts & int_bit) {
245 lan743x_rx_isr(&adapter->rx[channel],
246 int_bit, flags);
247 int_sts &= ~int_bit;
248 }
249 }
250 }
251 if (int_sts & INT_BIT_ALL_TX_) {
252 for (channel = 0; channel < LAN743X_USED_TX_CHANNELS;
253 channel++) {
254 u32 int_bit = INT_BIT_DMA_TX_(channel);
255
256 if (int_sts & int_bit) {
257 lan743x_tx_isr(&adapter->tx[channel],
258 int_bit, flags);
259 int_sts &= ~int_bit;
260 }
261 }
262 }
263 if (int_sts & INT_BIT_ALL_OTHER_) {
264 if (int_sts & INT_BIT_SW_GP_) {
265 lan743x_intr_software_isr(adapter);
266 int_sts &= ~INT_BIT_SW_GP_;
267 }
268 }
269 if (int_sts)
270 lan743x_csr_write(adapter, INT_EN_CLR, int_sts);
271}
272
273static irqreturn_t lan743x_intr_entry_isr(int irq, void *ptr)
274{
275 struct lan743x_vector *vector = ptr;
276 struct lan743x_adapter *adapter = vector->adapter;
277 irqreturn_t result = IRQ_NONE;
278 u32 int_enables;
279 u32 int_sts;
280
281 if (vector->flags & LAN743X_VECTOR_FLAG_SOURCE_STATUS_READ) {
282 int_sts = lan743x_csr_read(adapter, INT_STS);
283 } else if (vector->flags &
284 (LAN743X_VECTOR_FLAG_SOURCE_STATUS_R2C |
285 LAN743X_VECTOR_FLAG_SOURCE_ENABLE_R2C)) {
286 int_sts = lan743x_csr_read(adapter, INT_STS_R2C);
287 } else {
288 /* use mask as implied status */
289 int_sts = vector->int_mask | INT_BIT_MAS_;
290 }
291
292 if (!(int_sts & INT_BIT_MAS_))
293 goto irq_done;
294
295 if (vector->flags & LAN743X_VECTOR_FLAG_VECTOR_ENABLE_ISR_CLEAR)
296 /* disable vector interrupt */
297 lan743x_csr_write(adapter,
298 INT_VEC_EN_CLR,
299 INT_VEC_EN_(vector->vector_index));
300
301 if (vector->flags & LAN743X_VECTOR_FLAG_MASTER_ENABLE_CLEAR)
302 /* disable master interrupt */
303 lan743x_csr_write(adapter, INT_EN_CLR, INT_BIT_MAS_);
304
305 if (vector->flags & LAN743X_VECTOR_FLAG_SOURCE_ENABLE_CHECK) {
306 int_enables = lan743x_csr_read(adapter, INT_EN_SET);
307 } else {
308 /* use vector mask as implied enable mask */
309 int_enables = vector->int_mask;
310 }
311
312 int_sts &= int_enables;
313 int_sts &= vector->int_mask;
314 if (int_sts) {
315 if (vector->handler) {
316 vector->handler(vector->context,
317 int_sts, vector->flags);
318 } else {
319 /* disable interrupts on this vector */
320 lan743x_csr_write(adapter, INT_EN_CLR,
321 vector->int_mask);
322 }
323 result = IRQ_HANDLED;
324 }
325
326 if (vector->flags & LAN743X_VECTOR_FLAG_MASTER_ENABLE_SET)
327 /* enable master interrupt */
328 lan743x_csr_write(adapter, INT_EN_SET, INT_BIT_MAS_);
329
330 if (vector->flags & LAN743X_VECTOR_FLAG_VECTOR_ENABLE_ISR_SET)
331 /* enable vector interrupt */
332 lan743x_csr_write(adapter,
333 INT_VEC_EN_SET,
334 INT_VEC_EN_(vector->vector_index));
335irq_done:
336 return result;
337}
338
339static int lan743x_intr_test_isr(struct lan743x_adapter *adapter)
340{
341 struct lan743x_intr *intr = &adapter->intr;
342 int result = -ENODEV;
343 int timeout = 10;
344
345 intr->software_isr_flag = 0;
346
347 /* enable interrupt */
348 lan743x_csr_write(adapter, INT_EN_SET, INT_BIT_SW_GP_);
349
350 /* activate interrupt here */
351 lan743x_csr_write(adapter, INT_SET, INT_BIT_SW_GP_);
352 while ((timeout > 0) && (!(intr->software_isr_flag))) {
353 usleep_range(1000, 20000);
354 timeout--;
355 }
356
357 if (intr->software_isr_flag)
358 result = 0;
359
360 /* disable interrupts */
361 lan743x_csr_write(adapter, INT_EN_CLR, INT_BIT_SW_GP_);
362 return result;
363}
364
365static int lan743x_intr_register_isr(struct lan743x_adapter *adapter,
366 int vector_index, u32 flags,
367 u32 int_mask,
368 lan743x_vector_handler handler,
369 void *context)
370{
371 struct lan743x_vector *vector = &adapter->intr.vector_list
372 [vector_index];
373 int ret;
374
375 vector->adapter = adapter;
376 vector->flags = flags;
377 vector->vector_index = vector_index;
378 vector->int_mask = int_mask;
379 vector->handler = handler;
380 vector->context = context;
381
382 ret = request_irq(vector->irq,
383 lan743x_intr_entry_isr,
384 (flags & LAN743X_VECTOR_FLAG_IRQ_SHARED) ?
385 IRQF_SHARED : 0, DRIVER_NAME, vector);
386 if (ret) {
387 vector->handler = NULL;
388 vector->context = NULL;
389 vector->int_mask = 0;
390 vector->flags = 0;
391 }
392 return ret;
393}
394
395static void lan743x_intr_unregister_isr(struct lan743x_adapter *adapter,
396 int vector_index)
397{
398 struct lan743x_vector *vector = &adapter->intr.vector_list
399 [vector_index];
400
401 free_irq(vector->irq, vector);
402 vector->handler = NULL;
403 vector->context = NULL;
404 vector->int_mask = 0;
405 vector->flags = 0;
406}
407
408static u32 lan743x_intr_get_vector_flags(struct lan743x_adapter *adapter,
409 u32 int_mask)
410{
411 int index;
412
413 for (index = 0; index < LAN743X_MAX_VECTOR_COUNT; index++) {
414 if (adapter->intr.vector_list[index].int_mask & int_mask)
415 return adapter->intr.vector_list[index].flags;
416 }
417 return 0;
418}
419
420static void lan743x_intr_close(struct lan743x_adapter *adapter)
421{
422 struct lan743x_intr *intr = &adapter->intr;
423 int index = 0;
424
425 lan743x_csr_write(adapter, INT_EN_CLR, INT_BIT_MAS_);
426 lan743x_csr_write(adapter, INT_VEC_EN_CLR, 0x000000FF);
427
428 for (index = 0; index < LAN743X_MAX_VECTOR_COUNT; index++) {
429 if (intr->flags & INTR_FLAG_IRQ_REQUESTED(index)) {
430 lan743x_intr_unregister_isr(adapter, index);
431 intr->flags &= ~INTR_FLAG_IRQ_REQUESTED(index);
432 }
433 }
434
435 if (intr->flags & INTR_FLAG_MSI_ENABLED) {
436 pci_disable_msi(adapter->pdev);
437 intr->flags &= ~INTR_FLAG_MSI_ENABLED;
438 }
439
440 if (intr->flags & INTR_FLAG_MSIX_ENABLED) {
441 pci_disable_msix(adapter->pdev);
442 intr->flags &= ~INTR_FLAG_MSIX_ENABLED;
443 }
444}
445
446static int lan743x_intr_open(struct lan743x_adapter *adapter)
447{
448 struct msix_entry msix_entries[LAN743X_MAX_VECTOR_COUNT];
449 struct lan743x_intr *intr = &adapter->intr;
450 u32 int_vec_en_auto_clr = 0;
451 u32 int_vec_map0 = 0;
452 u32 int_vec_map1 = 0;
453 int ret = -ENODEV;
454 int index = 0;
455 u32 flags = 0;
456
457 intr->number_of_vectors = 0;
458
459 /* Try to set up MSIX interrupts */
460 memset(&msix_entries[0], 0,
461 sizeof(struct msix_entry) * LAN743X_MAX_VECTOR_COUNT);
462 for (index = 0; index < LAN743X_MAX_VECTOR_COUNT; index++)
463 msix_entries[index].entry = index;
464 ret = pci_enable_msix_range(adapter->pdev,
465 msix_entries, 1,
466 1 + LAN743X_USED_TX_CHANNELS +
467 LAN743X_USED_RX_CHANNELS);
468
469 if (ret > 0) {
470 intr->flags |= INTR_FLAG_MSIX_ENABLED;
471 intr->number_of_vectors = ret;
472 intr->using_vectors = true;
473 for (index = 0; index < intr->number_of_vectors; index++)
474 intr->vector_list[index].irq = msix_entries
475 [index].vector;
476 netif_info(adapter, ifup, adapter->netdev,
477 "using MSIX interrupts, number of vectors = %d\n",
478 intr->number_of_vectors);
479 }
480
481 /* If MSIX failed try to setup using MSI interrupts */
482 if (!intr->number_of_vectors) {
483 if (!(adapter->csr.flags & LAN743X_CSR_FLAG_IS_A0)) {
484 if (!pci_enable_msi(adapter->pdev)) {
485 intr->flags |= INTR_FLAG_MSI_ENABLED;
486 intr->number_of_vectors = 1;
487 intr->using_vectors = true;
488 intr->vector_list[0].irq =
489 adapter->pdev->irq;
490 netif_info(adapter, ifup, adapter->netdev,
491 "using MSI interrupts, number of vectors = %d\n",
492 intr->number_of_vectors);
493 }
494 }
495 }
496
497 /* If MSIX, and MSI failed, setup using legacy interrupt */
498 if (!intr->number_of_vectors) {
499 intr->number_of_vectors = 1;
500 intr->using_vectors = false;
501 intr->vector_list[0].irq = intr->irq;
502 netif_info(adapter, ifup, adapter->netdev,
503 "using legacy interrupts\n");
504 }
505
506 /* At this point we must have at least one irq */
507 lan743x_csr_write(adapter, INT_VEC_EN_CLR, 0xFFFFFFFF);
508
509 /* map all interrupts to vector 0 */
510 lan743x_csr_write(adapter, INT_VEC_MAP0, 0x00000000);
511 lan743x_csr_write(adapter, INT_VEC_MAP1, 0x00000000);
512 lan743x_csr_write(adapter, INT_VEC_MAP2, 0x00000000);
513 flags = LAN743X_VECTOR_FLAG_SOURCE_STATUS_READ |
514 LAN743X_VECTOR_FLAG_SOURCE_STATUS_W2C |
515 LAN743X_VECTOR_FLAG_SOURCE_ENABLE_CHECK |
516 LAN743X_VECTOR_FLAG_SOURCE_ENABLE_CLEAR;
517
518 if (intr->using_vectors) {
519 flags |= LAN743X_VECTOR_FLAG_VECTOR_ENABLE_ISR_CLEAR |
520 LAN743X_VECTOR_FLAG_VECTOR_ENABLE_ISR_SET;
521 } else {
522 flags |= LAN743X_VECTOR_FLAG_MASTER_ENABLE_CLEAR |
523 LAN743X_VECTOR_FLAG_MASTER_ENABLE_SET |
524 LAN743X_VECTOR_FLAG_IRQ_SHARED;
525 }
526
527 if (adapter->csr.flags & LAN743X_CSR_FLAG_SUPPORTS_INTR_AUTO_SET_CLR) {
528 flags &= ~LAN743X_VECTOR_FLAG_SOURCE_STATUS_READ;
529 flags &= ~LAN743X_VECTOR_FLAG_SOURCE_STATUS_W2C;
530 flags &= ~LAN743X_VECTOR_FLAG_SOURCE_ENABLE_CLEAR;
531 flags &= ~LAN743X_VECTOR_FLAG_SOURCE_ENABLE_CHECK;
532 flags |= LAN743X_VECTOR_FLAG_SOURCE_STATUS_R2C;
533 flags |= LAN743X_VECTOR_FLAG_SOURCE_ENABLE_R2C;
534 }
535
536 ret = lan743x_intr_register_isr(adapter, 0, flags,
537 INT_BIT_ALL_RX_ | INT_BIT_ALL_TX_ |
538 INT_BIT_ALL_OTHER_,
539 lan743x_intr_shared_isr, adapter);
540 if (ret)
541 goto clean_up;
542 intr->flags |= INTR_FLAG_IRQ_REQUESTED(0);
543
544 if (intr->using_vectors)
545 lan743x_csr_write(adapter, INT_VEC_EN_SET,
546 INT_VEC_EN_(0));
547
548 if (!(adapter->csr.flags & LAN743X_CSR_FLAG_IS_A0)) {
549 lan743x_csr_write(adapter, INT_MOD_CFG0, LAN743X_INT_MOD);
550 lan743x_csr_write(adapter, INT_MOD_CFG1, LAN743X_INT_MOD);
551 lan743x_csr_write(adapter, INT_MOD_CFG2, LAN743X_INT_MOD);
552 lan743x_csr_write(adapter, INT_MOD_CFG3, LAN743X_INT_MOD);
553 lan743x_csr_write(adapter, INT_MOD_CFG4, LAN743X_INT_MOD);
554 lan743x_csr_write(adapter, INT_MOD_CFG5, LAN743X_INT_MOD);
555 lan743x_csr_write(adapter, INT_MOD_CFG6, LAN743X_INT_MOD);
556 lan743x_csr_write(adapter, INT_MOD_CFG7, LAN743X_INT_MOD);
557 lan743x_csr_write(adapter, INT_MOD_MAP0, 0x00005432);
558 lan743x_csr_write(adapter, INT_MOD_MAP1, 0x00000001);
559 lan743x_csr_write(adapter, INT_MOD_MAP2, 0x00FFFFFF);
560 }
561
562 /* enable interrupts */
563 lan743x_csr_write(adapter, INT_EN_SET, INT_BIT_MAS_);
564 ret = lan743x_intr_test_isr(adapter);
565 if (ret)
566 goto clean_up;
567
568 if (intr->number_of_vectors > 1) {
569 int number_of_tx_vectors = intr->number_of_vectors - 1;
570
571 if (number_of_tx_vectors > LAN743X_USED_TX_CHANNELS)
572 number_of_tx_vectors = LAN743X_USED_TX_CHANNELS;
573 flags = LAN743X_VECTOR_FLAG_SOURCE_STATUS_READ |
574 LAN743X_VECTOR_FLAG_SOURCE_STATUS_W2C |
575 LAN743X_VECTOR_FLAG_SOURCE_ENABLE_CHECK |
576 LAN743X_VECTOR_FLAG_SOURCE_ENABLE_CLEAR |
577 LAN743X_VECTOR_FLAG_VECTOR_ENABLE_ISR_CLEAR |
578 LAN743X_VECTOR_FLAG_VECTOR_ENABLE_ISR_SET;
579
580 if (adapter->csr.flags &
581 LAN743X_CSR_FLAG_SUPPORTS_INTR_AUTO_SET_CLR) {
582 flags = LAN743X_VECTOR_FLAG_VECTOR_ENABLE_AUTO_CLEAR |
583 LAN743X_VECTOR_FLAG_VECTOR_ENABLE_AUTO_SET |
584 LAN743X_VECTOR_FLAG_SOURCE_ENABLE_AUTO_SET |
585 LAN743X_VECTOR_FLAG_SOURCE_ENABLE_AUTO_CLEAR |
586 LAN743X_VECTOR_FLAG_SOURCE_STATUS_AUTO_CLEAR;
587 }
588
589 for (index = 0; index < number_of_tx_vectors; index++) {
590 u32 int_bit = INT_BIT_DMA_TX_(index);
591 int vector = index + 1;
592
593 /* map TX interrupt to vector */
594 int_vec_map1 |= INT_VEC_MAP1_TX_VEC_(index, vector);
595 lan743x_csr_write(adapter, INT_VEC_MAP1, int_vec_map1);
596 if (flags &
597 LAN743X_VECTOR_FLAG_VECTOR_ENABLE_AUTO_CLEAR) {
598 int_vec_en_auto_clr |= INT_VEC_EN_(vector);
599 lan743x_csr_write(adapter, INT_VEC_EN_AUTO_CLR,
600 int_vec_en_auto_clr);
601 }
602
603 /* Remove TX interrupt from shared mask */
604 intr->vector_list[0].int_mask &= ~int_bit;
605 ret = lan743x_intr_register_isr(adapter, vector, flags,
606 int_bit, lan743x_tx_isr,
607 &adapter->tx[index]);
608 if (ret)
609 goto clean_up;
610 intr->flags |= INTR_FLAG_IRQ_REQUESTED(vector);
611 if (!(flags &
612 LAN743X_VECTOR_FLAG_VECTOR_ENABLE_AUTO_SET))
613 lan743x_csr_write(adapter, INT_VEC_EN_SET,
614 INT_VEC_EN_(vector));
615 }
616 }
617 if ((intr->number_of_vectors - LAN743X_USED_TX_CHANNELS) > 1) {
618 int number_of_rx_vectors = intr->number_of_vectors -
619 LAN743X_USED_TX_CHANNELS - 1;
620
621 if (number_of_rx_vectors > LAN743X_USED_RX_CHANNELS)
622 number_of_rx_vectors = LAN743X_USED_RX_CHANNELS;
623
624 flags = LAN743X_VECTOR_FLAG_SOURCE_STATUS_READ |
625 LAN743X_VECTOR_FLAG_SOURCE_STATUS_W2C |
626 LAN743X_VECTOR_FLAG_SOURCE_ENABLE_CHECK |
627 LAN743X_VECTOR_FLAG_SOURCE_ENABLE_CLEAR |
628 LAN743X_VECTOR_FLAG_VECTOR_ENABLE_ISR_CLEAR |
629 LAN743X_VECTOR_FLAG_VECTOR_ENABLE_ISR_SET;
630
631 if (adapter->csr.flags &
632 LAN743X_CSR_FLAG_SUPPORTS_INTR_AUTO_SET_CLR) {
633 flags = LAN743X_VECTOR_FLAG_VECTOR_ENABLE_AUTO_CLEAR |
634 LAN743X_VECTOR_FLAG_VECTOR_ENABLE_AUTO_SET |
635 LAN743X_VECTOR_FLAG_SOURCE_ENABLE_AUTO_SET |
636 LAN743X_VECTOR_FLAG_SOURCE_ENABLE_AUTO_CLEAR |
637 LAN743X_VECTOR_FLAG_SOURCE_STATUS_AUTO_CLEAR;
638 }
639 for (index = 0; index < number_of_rx_vectors; index++) {
640 int vector = index + 1 + LAN743X_USED_TX_CHANNELS;
641 u32 int_bit = INT_BIT_DMA_RX_(index);
642
643 /* map RX interrupt to vector */
644 int_vec_map0 |= INT_VEC_MAP0_RX_VEC_(index, vector);
645 lan743x_csr_write(adapter, INT_VEC_MAP0, int_vec_map0);
646 if (flags &
647 LAN743X_VECTOR_FLAG_VECTOR_ENABLE_AUTO_CLEAR) {
648 int_vec_en_auto_clr |= INT_VEC_EN_(vector);
649 lan743x_csr_write(adapter, INT_VEC_EN_AUTO_CLR,
650 int_vec_en_auto_clr);
651 }
652
653 /* Remove RX interrupt from shared mask */
654 intr->vector_list[0].int_mask &= ~int_bit;
655 ret = lan743x_intr_register_isr(adapter, vector, flags,
656 int_bit, lan743x_rx_isr,
657 &adapter->rx[index]);
658 if (ret)
659 goto clean_up;
660 intr->flags |= INTR_FLAG_IRQ_REQUESTED(vector);
661
662 lan743x_csr_write(adapter, INT_VEC_EN_SET,
663 INT_VEC_EN_(vector));
664 }
665 }
666 return 0;
667
668clean_up:
669 lan743x_intr_close(adapter);
670 return ret;
671}
672
673static int lan743x_dp_write(struct lan743x_adapter *adapter,
674 u32 select, u32 addr, u32 length, u32 *buf)
675{
676 int ret = -EIO;
677 u32 dp_sel;
678 int i;
679
680 mutex_lock(&adapter->dp_lock);
681 if (lan743x_csr_wait_for_bit(adapter, DP_SEL, DP_SEL_DPRDY_,
682 1, 40, 100, 100))
683 goto unlock;
684 dp_sel = lan743x_csr_read(adapter, DP_SEL);
685 dp_sel &= ~DP_SEL_MASK_;
686 dp_sel |= select;
687 lan743x_csr_write(adapter, DP_SEL, dp_sel);
688
689 for (i = 0; i < length; i++) {
690 lan743x_csr_write(adapter, DP_ADDR, addr + i);
691 lan743x_csr_write(adapter, DP_DATA_0, buf[i]);
692 lan743x_csr_write(adapter, DP_CMD, DP_CMD_WRITE_);
693 if (lan743x_csr_wait_for_bit(adapter, DP_SEL, DP_SEL_DPRDY_,
694 1, 40, 100, 100))
695 goto unlock;
696 }
697 ret = 0;
698
699unlock:
700 mutex_unlock(&adapter->dp_lock);
701 return ret;
702}
703
704static u32 lan743x_mac_mii_access(u16 id, u16 index, int read)
705{
706 u32 ret;
707
708 ret = (id << MAC_MII_ACC_PHY_ADDR_SHIFT_) &
709 MAC_MII_ACC_PHY_ADDR_MASK_;
710 ret |= (index << MAC_MII_ACC_MIIRINDA_SHIFT_) &
711 MAC_MII_ACC_MIIRINDA_MASK_;
712
713 if (read)
714 ret |= MAC_MII_ACC_MII_READ_;
715 else
716 ret |= MAC_MII_ACC_MII_WRITE_;
717 ret |= MAC_MII_ACC_MII_BUSY_;
718
719 return ret;
720}
721
722static int lan743x_mac_mii_wait_till_not_busy(struct lan743x_adapter *adapter)
723{
724 u32 data;
725
726 return readx_poll_timeout(LAN743X_CSR_READ_OP, MAC_MII_ACC, data,
727 !(data & MAC_MII_ACC_MII_BUSY_), 0, 1000000);
728}
729
730static int lan743x_mdiobus_read(struct mii_bus *bus, int phy_id, int index)
731{
732 struct lan743x_adapter *adapter = bus->priv;
733 u32 val, mii_access;
734 int ret;
735
736 /* comfirm MII not busy */
737 ret = lan743x_mac_mii_wait_till_not_busy(adapter);
738 if (ret < 0)
739 return ret;
740
741 /* set the address, index & direction (read from PHY) */
742 mii_access = lan743x_mac_mii_access(phy_id, index, MAC_MII_READ);
743 lan743x_csr_write(adapter, MAC_MII_ACC, mii_access);
744 ret = lan743x_mac_mii_wait_till_not_busy(adapter);
745 if (ret < 0)
746 return ret;
747
748 val = lan743x_csr_read(adapter, MAC_MII_DATA);
749 return (int)(val & 0xFFFF);
750}
751
752static int lan743x_mdiobus_write(struct mii_bus *bus,
753 int phy_id, int index, u16 regval)
754{
755 struct lan743x_adapter *adapter = bus->priv;
756 u32 val, mii_access;
757 int ret;
758
759 /* confirm MII not busy */
760 ret = lan743x_mac_mii_wait_till_not_busy(adapter);
761 if (ret < 0)
762 return ret;
763 val = (u32)regval;
764 lan743x_csr_write(adapter, MAC_MII_DATA, val);
765
766 /* set the address, index & direction (write to PHY) */
767 mii_access = lan743x_mac_mii_access(phy_id, index, MAC_MII_WRITE);
768 lan743x_csr_write(adapter, MAC_MII_ACC, mii_access);
769 ret = lan743x_mac_mii_wait_till_not_busy(adapter);
770 return ret;
771}
772
773static void lan743x_mac_set_address(struct lan743x_adapter *adapter,
774 u8 *addr)
775{
776 u32 addr_lo, addr_hi;
777
778 addr_lo = addr[0] |
779 addr[1] << 8 |
780 addr[2] << 16 |
781 addr[3] << 24;
782 addr_hi = addr[4] |
783 addr[5] << 8;
784 lan743x_csr_write(adapter, MAC_RX_ADDRL, addr_lo);
785 lan743x_csr_write(adapter, MAC_RX_ADDRH, addr_hi);
786
787 ether_addr_copy(adapter->mac_address, addr);
788 netif_info(adapter, drv, adapter->netdev,
789 "MAC address set to %pM\n", addr);
790}
791
792static int lan743x_mac_init(struct lan743x_adapter *adapter)
793{
794 bool mac_address_valid = true;
795 struct net_device *netdev;
796 u32 mac_addr_hi = 0;
797 u32 mac_addr_lo = 0;
798 u32 data;
799 int ret;
800
801 netdev = adapter->netdev;
802 lan743x_csr_write(adapter, MAC_CR, MAC_CR_RST_);
803 ret = lan743x_csr_wait_for_bit(adapter, MAC_CR, MAC_CR_RST_,
804 0, 1000, 20000, 100);
805 if (ret)
806 return ret;
807
808 /* setup auto duplex, and speed detection */
809 data = lan743x_csr_read(adapter, MAC_CR);
810 data |= MAC_CR_ADD_ | MAC_CR_ASD_;
811 data |= MAC_CR_CNTR_RST_;
812 lan743x_csr_write(adapter, MAC_CR, data);
813
814 mac_addr_hi = lan743x_csr_read(adapter, MAC_RX_ADDRH);
815 mac_addr_lo = lan743x_csr_read(adapter, MAC_RX_ADDRL);
816 adapter->mac_address[0] = mac_addr_lo & 0xFF;
817 adapter->mac_address[1] = (mac_addr_lo >> 8) & 0xFF;
818 adapter->mac_address[2] = (mac_addr_lo >> 16) & 0xFF;
819 adapter->mac_address[3] = (mac_addr_lo >> 24) & 0xFF;
820 adapter->mac_address[4] = mac_addr_hi & 0xFF;
821 adapter->mac_address[5] = (mac_addr_hi >> 8) & 0xFF;
822
823 if (((mac_addr_hi & 0x0000FFFF) == 0x0000FFFF) &&
824 mac_addr_lo == 0xFFFFFFFF) {
825 mac_address_valid = false;
826 } else if (!is_valid_ether_addr(adapter->mac_address)) {
827 mac_address_valid = false;
828 }
829
830 if (!mac_address_valid)
831 random_ether_addr(adapter->mac_address);
832 lan743x_mac_set_address(adapter, adapter->mac_address);
833 ether_addr_copy(netdev->dev_addr, adapter->mac_address);
834 return 0;
835}
836
837static int lan743x_mac_open(struct lan743x_adapter *adapter)
838{
839 int ret = 0;
840 u32 temp;
841
842 temp = lan743x_csr_read(adapter, MAC_RX);
843 lan743x_csr_write(adapter, MAC_RX, temp | MAC_RX_RXEN_);
844 temp = lan743x_csr_read(adapter, MAC_TX);
845 lan743x_csr_write(adapter, MAC_TX, temp | MAC_TX_TXEN_);
846 return ret;
847}
848
849static void lan743x_mac_close(struct lan743x_adapter *adapter)
850{
851 u32 temp;
852
853 temp = lan743x_csr_read(adapter, MAC_TX);
854 temp &= ~MAC_TX_TXEN_;
855 lan743x_csr_write(adapter, MAC_TX, temp);
856 lan743x_csr_wait_for_bit(adapter, MAC_TX, MAC_TX_TXD_,
857 1, 1000, 20000, 100);
858
859 temp = lan743x_csr_read(adapter, MAC_RX);
860 temp &= ~MAC_RX_RXEN_;
861 lan743x_csr_write(adapter, MAC_RX, temp);
862 lan743x_csr_wait_for_bit(adapter, MAC_RX, MAC_RX_RXD_,
863 1, 1000, 20000, 100);
864}
865
866static void lan743x_mac_flow_ctrl_set_enables(struct lan743x_adapter *adapter,
867 bool tx_enable, bool rx_enable)
868{
869 u32 flow_setting = 0;
870
871 /* set maximum pause time because when fifo space frees
872 * up a zero value pause frame will be sent to release the pause
873 */
874 flow_setting = MAC_FLOW_CR_FCPT_MASK_;
875 if (tx_enable)
876 flow_setting |= MAC_FLOW_CR_TX_FCEN_;
877 if (rx_enable)
878 flow_setting |= MAC_FLOW_CR_RX_FCEN_;
879 lan743x_csr_write(adapter, MAC_FLOW, flow_setting);
880}
881
882static int lan743x_mac_set_mtu(struct lan743x_adapter *adapter, int new_mtu)
883{
884 int enabled = 0;
885 u32 mac_rx = 0;
886
887 mac_rx = lan743x_csr_read(adapter, MAC_RX);
888 if (mac_rx & MAC_RX_RXEN_) {
889 enabled = 1;
890 if (mac_rx & MAC_RX_RXD_) {
891 lan743x_csr_write(adapter, MAC_RX, mac_rx);
892 mac_rx &= ~MAC_RX_RXD_;
893 }
894 mac_rx &= ~MAC_RX_RXEN_;
895 lan743x_csr_write(adapter, MAC_RX, mac_rx);
896 lan743x_csr_wait_for_bit(adapter, MAC_RX, MAC_RX_RXD_,
897 1, 1000, 20000, 100);
898 lan743x_csr_write(adapter, MAC_RX, mac_rx | MAC_RX_RXD_);
899 }
900
901 mac_rx &= ~(MAC_RX_MAX_SIZE_MASK_);
902 mac_rx |= (((new_mtu + ETH_HLEN + 4) << MAC_RX_MAX_SIZE_SHIFT_) &
903 MAC_RX_MAX_SIZE_MASK_);
904 lan743x_csr_write(adapter, MAC_RX, mac_rx);
905
906 if (enabled) {
907 mac_rx |= MAC_RX_RXEN_;
908 lan743x_csr_write(adapter, MAC_RX, mac_rx);
909 }
910 return 0;
911}
912
913/* PHY */
914static int lan743x_phy_reset(struct lan743x_adapter *adapter)
915{
916 u32 data;
917
918 /* Only called with in probe, and before mdiobus_register */
919
920 data = lan743x_csr_read(adapter, PMT_CTL);
921 data |= PMT_CTL_ETH_PHY_RST_;
922 lan743x_csr_write(adapter, PMT_CTL, data);
923
924 return readx_poll_timeout(LAN743X_CSR_READ_OP, PMT_CTL, data,
925 (!(data & PMT_CTL_ETH_PHY_RST_) &&
926 (data & PMT_CTL_READY_)),
927 50000, 1000000);
928}
929
930static void lan743x_phy_update_flowcontrol(struct lan743x_adapter *adapter,
931 u8 duplex, u16 local_adv,
932 u16 remote_adv)
933{
934 struct lan743x_phy *phy = &adapter->phy;
935 u8 cap;
936
937 if (phy->fc_autoneg)
938 cap = mii_resolve_flowctrl_fdx(local_adv, remote_adv);
939 else
940 cap = phy->fc_request_control;
941
942 lan743x_mac_flow_ctrl_set_enables(adapter,
943 cap & FLOW_CTRL_TX,
944 cap & FLOW_CTRL_RX);
945}
946
947static int lan743x_phy_init(struct lan743x_adapter *adapter)
948{
949 return lan743x_phy_reset(adapter);
950}
951
952static void lan743x_phy_link_status_change(struct net_device *netdev)
953{
954 struct lan743x_adapter *adapter = netdev_priv(netdev);
955 struct phy_device *phydev = netdev->phydev;
956
957 phy_print_status(phydev);
958 if (phydev->state == PHY_RUNNING) {
959 struct ethtool_link_ksettings ksettings;
960 int remote_advertisement = 0;
961 int local_advertisement = 0;
962
963 memset(&ksettings, 0, sizeof(ksettings));
964 phy_ethtool_get_link_ksettings(netdev, &ksettings);
965 local_advertisement = phy_read(phydev, MII_ADVERTISE);
966 if (local_advertisement < 0)
967 return;
968
969 remote_advertisement = phy_read(phydev, MII_LPA);
970 if (remote_advertisement < 0)
971 return;
972
973 lan743x_phy_update_flowcontrol(adapter,
974 ksettings.base.duplex,
975 local_advertisement,
976 remote_advertisement);
977 }
978}
979
980static void lan743x_phy_close(struct lan743x_adapter *adapter)
981{
982 struct net_device *netdev = adapter->netdev;
983
984 phy_stop(netdev->phydev);
985 phy_disconnect(netdev->phydev);
986 netdev->phydev = NULL;
987}
988
989static int lan743x_phy_open(struct lan743x_adapter *adapter)
990{
991 struct lan743x_phy *phy = &adapter->phy;
992 struct phy_device *phydev;
993 struct net_device *netdev;
994 int ret = -EIO;
995 u32 mii_adv;
996
997 netdev = adapter->netdev;
998 phydev = phy_find_first(adapter->mdiobus);
999 if (!phydev)
1000 goto return_error;
1001
1002 ret = phy_connect_direct(netdev, phydev,
1003 lan743x_phy_link_status_change,
1004 PHY_INTERFACE_MODE_GMII);
1005 if (ret)
1006 goto return_error;
1007
1008 /* MAC doesn't support 1000T Half */
1009 phydev->supported &= ~SUPPORTED_1000baseT_Half;
1010
1011 /* support both flow controls */
1012 phy->fc_request_control = (FLOW_CTRL_RX | FLOW_CTRL_TX);
1013 phydev->advertising &= ~(ADVERTISED_Pause | ADVERTISED_Asym_Pause);
1014 mii_adv = (u32)mii_advertise_flowctrl(phy->fc_request_control);
1015 phydev->advertising |= mii_adv_to_ethtool_adv_t(mii_adv);
1016 phy->fc_autoneg = phydev->autoneg;
1017
1018 phy_start(phydev);
1019 phy_start_aneg(phydev);
1020 return 0;
1021
1022return_error:
1023 return ret;
1024}
1025
1026static void lan743x_rfe_update_mac_address(struct lan743x_adapter *adapter)
1027{
1028 u8 *mac_addr;
1029 u32 mac_addr_hi = 0;
1030 u32 mac_addr_lo = 0;
1031
1032 /* Add mac address to perfect Filter */
1033 mac_addr = adapter->mac_address;
1034 mac_addr_lo = ((((u32)(mac_addr[0])) << 0) |
1035 (((u32)(mac_addr[1])) << 8) |
1036 (((u32)(mac_addr[2])) << 16) |
1037 (((u32)(mac_addr[3])) << 24));
1038 mac_addr_hi = ((((u32)(mac_addr[4])) << 0) |
1039 (((u32)(mac_addr[5])) << 8));
1040
1041 lan743x_csr_write(adapter, RFE_ADDR_FILT_LO(0), mac_addr_lo);
1042 lan743x_csr_write(adapter, RFE_ADDR_FILT_HI(0),
1043 mac_addr_hi | RFE_ADDR_FILT_HI_VALID_);
1044}
1045
1046static void lan743x_rfe_set_multicast(struct lan743x_adapter *adapter)
1047{
1048 struct net_device *netdev = adapter->netdev;
1049 u32 hash_table[DP_SEL_VHF_HASH_LEN];
1050 u32 rfctl;
1051 u32 data;
1052
1053 rfctl = lan743x_csr_read(adapter, RFE_CTL);
1054 rfctl &= ~(RFE_CTL_AU_ | RFE_CTL_AM_ |
1055 RFE_CTL_DA_PERFECT_ | RFE_CTL_MCAST_HASH_);
1056 rfctl |= RFE_CTL_AB_;
1057 if (netdev->flags & IFF_PROMISC) {
1058 rfctl |= RFE_CTL_AM_ | RFE_CTL_AU_;
1059 } else {
1060 if (netdev->flags & IFF_ALLMULTI)
1061 rfctl |= RFE_CTL_AM_;
1062 }
1063
1064 memset(hash_table, 0, DP_SEL_VHF_HASH_LEN * sizeof(u32));
1065 if (netdev_mc_count(netdev)) {
1066 struct netdev_hw_addr *ha;
1067 int i;
1068
1069 rfctl |= RFE_CTL_DA_PERFECT_;
1070 i = 1;
1071 netdev_for_each_mc_addr(ha, netdev) {
1072 /* set first 32 into Perfect Filter */
1073 if (i < 33) {
1074 lan743x_csr_write(adapter,
1075 RFE_ADDR_FILT_HI(i), 0);
1076 data = ha->addr[3];
1077 data = ha->addr[2] | (data << 8);
1078 data = ha->addr[1] | (data << 8);
1079 data = ha->addr[0] | (data << 8);
1080 lan743x_csr_write(adapter,
1081 RFE_ADDR_FILT_LO(i), data);
1082 data = ha->addr[5];
1083 data = ha->addr[4] | (data << 8);
1084 data |= RFE_ADDR_FILT_HI_VALID_;
1085 lan743x_csr_write(adapter,
1086 RFE_ADDR_FILT_HI(i), data);
1087 } else {
1088 u32 bitnum = (ether_crc(ETH_ALEN, ha->addr) >>
1089 23) & 0x1FF;
1090 hash_table[bitnum / 32] |= (1 << (bitnum % 32));
1091 rfctl |= RFE_CTL_MCAST_HASH_;
1092 }
1093 i++;
1094 }
1095 }
1096
1097 lan743x_dp_write(adapter, DP_SEL_RFE_RAM,
1098 DP_SEL_VHF_VLAN_LEN,
1099 DP_SEL_VHF_HASH_LEN, hash_table);
1100 lan743x_csr_write(adapter, RFE_CTL, rfctl);
1101}
1102
1103static int lan743x_dmac_init(struct lan743x_adapter *adapter)
1104{
1105 u32 data = 0;
1106
1107 lan743x_csr_write(adapter, DMAC_CMD, DMAC_CMD_SWR_);
1108 lan743x_csr_wait_for_bit(adapter, DMAC_CMD, DMAC_CMD_SWR_,
1109 0, 1000, 20000, 100);
1110 switch (DEFAULT_DMA_DESCRIPTOR_SPACING) {
1111 case DMA_DESCRIPTOR_SPACING_16:
1112 data = DMAC_CFG_MAX_DSPACE_16_;
1113 break;
1114 case DMA_DESCRIPTOR_SPACING_32:
1115 data = DMAC_CFG_MAX_DSPACE_32_;
1116 break;
1117 case DMA_DESCRIPTOR_SPACING_64:
1118 data = DMAC_CFG_MAX_DSPACE_64_;
1119 break;
1120 case DMA_DESCRIPTOR_SPACING_128:
1121 data = DMAC_CFG_MAX_DSPACE_128_;
1122 break;
1123 default:
1124 return -EPERM;
1125 }
1126 if (!(adapter->csr.flags & LAN743X_CSR_FLAG_IS_A0))
1127 data |= DMAC_CFG_COAL_EN_;
1128 data |= DMAC_CFG_CH_ARB_SEL_RX_HIGH_;
1129 data |= DMAC_CFG_MAX_READ_REQ_SET_(6);
1130 lan743x_csr_write(adapter, DMAC_CFG, data);
1131 data = DMAC_COAL_CFG_TIMER_LIMIT_SET_(1);
1132 data |= DMAC_COAL_CFG_TIMER_TX_START_;
1133 data |= DMAC_COAL_CFG_FLUSH_INTS_;
1134 data |= DMAC_COAL_CFG_INT_EXIT_COAL_;
1135 data |= DMAC_COAL_CFG_CSR_EXIT_COAL_;
1136 data |= DMAC_COAL_CFG_TX_THRES_SET_(0x0A);
1137 data |= DMAC_COAL_CFG_RX_THRES_SET_(0x0C);
1138 lan743x_csr_write(adapter, DMAC_COAL_CFG, data);
1139 data = DMAC_OBFF_TX_THRES_SET_(0x08);
1140 data |= DMAC_OBFF_RX_THRES_SET_(0x0A);
1141 lan743x_csr_write(adapter, DMAC_OBFF_CFG, data);
1142 return 0;
1143}
1144
1145static int lan743x_dmac_tx_get_state(struct lan743x_adapter *adapter,
1146 int tx_channel)
1147{
1148 u32 dmac_cmd = 0;
1149
1150 dmac_cmd = lan743x_csr_read(adapter, DMAC_CMD);
1151 return DMAC_CHANNEL_STATE_SET((dmac_cmd &
1152 DMAC_CMD_START_T_(tx_channel)),
1153 (dmac_cmd &
1154 DMAC_CMD_STOP_T_(tx_channel)));
1155}
1156
1157static int lan743x_dmac_tx_wait_till_stopped(struct lan743x_adapter *adapter,
1158 int tx_channel)
1159{
1160 int timeout = 100;
1161 int result = 0;
1162
1163 while (timeout &&
1164 ((result = lan743x_dmac_tx_get_state(adapter, tx_channel)) ==
1165 DMAC_CHANNEL_STATE_STOP_PENDING)) {
1166 usleep_range(1000, 20000);
1167 timeout--;
1168 }
1169 if (result == DMAC_CHANNEL_STATE_STOP_PENDING)
1170 result = -ENODEV;
1171 return result;
1172}
1173
1174static int lan743x_dmac_rx_get_state(struct lan743x_adapter *adapter,
1175 int rx_channel)
1176{
1177 u32 dmac_cmd = 0;
1178
1179 dmac_cmd = lan743x_csr_read(adapter, DMAC_CMD);
1180 return DMAC_CHANNEL_STATE_SET((dmac_cmd &
1181 DMAC_CMD_START_R_(rx_channel)),
1182 (dmac_cmd &
1183 DMAC_CMD_STOP_R_(rx_channel)));
1184}
1185
1186static int lan743x_dmac_rx_wait_till_stopped(struct lan743x_adapter *adapter,
1187 int rx_channel)
1188{
1189 int timeout = 100;
1190 int result = 0;
1191
1192 while (timeout &&
1193 ((result = lan743x_dmac_rx_get_state(adapter, rx_channel)) ==
1194 DMAC_CHANNEL_STATE_STOP_PENDING)) {
1195 usleep_range(1000, 20000);
1196 timeout--;
1197 }
1198 if (result == DMAC_CHANNEL_STATE_STOP_PENDING)
1199 result = -ENODEV;
1200 return result;
1201}
1202
1203static void lan743x_tx_release_desc(struct lan743x_tx *tx,
1204 int descriptor_index, bool cleanup)
1205{
1206 struct lan743x_tx_buffer_info *buffer_info = NULL;
1207 struct lan743x_tx_descriptor *descriptor = NULL;
1208 u32 descriptor_type = 0;
1209
1210 descriptor = &tx->ring_cpu_ptr[descriptor_index];
1211 buffer_info = &tx->buffer_info[descriptor_index];
1212 if (!(buffer_info->flags & TX_BUFFER_INFO_FLAG_ACTIVE))
1213 goto done;
1214
1215 descriptor_type = (descriptor->data0) &
1216 TX_DESC_DATA0_DTYPE_MASK_;
1217 if (descriptor_type == TX_DESC_DATA0_DTYPE_DATA_)
1218 goto clean_up_data_descriptor;
1219 else
1220 goto clear_active;
1221
1222clean_up_data_descriptor:
1223 if (buffer_info->dma_ptr) {
1224 if (buffer_info->flags &
1225 TX_BUFFER_INFO_FLAG_SKB_FRAGMENT) {
1226 dma_unmap_page(&tx->adapter->pdev->dev,
1227 buffer_info->dma_ptr,
1228 buffer_info->buffer_length,
1229 DMA_TO_DEVICE);
1230 } else {
1231 dma_unmap_single(&tx->adapter->pdev->dev,
1232 buffer_info->dma_ptr,
1233 buffer_info->buffer_length,
1234 DMA_TO_DEVICE);
1235 }
1236 buffer_info->dma_ptr = 0;
1237 buffer_info->buffer_length = 0;
1238 }
1239 if (buffer_info->skb) {
1240 dev_kfree_skb(buffer_info->skb);
1241 buffer_info->skb = NULL;
1242 }
1243
1244clear_active:
1245 buffer_info->flags &= ~TX_BUFFER_INFO_FLAG_ACTIVE;
1246
1247done:
1248 memset(buffer_info, 0, sizeof(*buffer_info));
1249 memset(descriptor, 0, sizeof(*descriptor));
1250}
1251
1252static int lan743x_tx_next_index(struct lan743x_tx *tx, int index)
1253{
1254 return ((++index) % tx->ring_size);
1255}
1256
1257static void lan743x_tx_release_completed_descriptors(struct lan743x_tx *tx)
1258{
1259 while ((*tx->head_cpu_ptr) != (tx->last_head)) {
1260 lan743x_tx_release_desc(tx, tx->last_head, false);
1261 tx->last_head = lan743x_tx_next_index(tx, tx->last_head);
1262 }
1263}
1264
1265static void lan743x_tx_release_all_descriptors(struct lan743x_tx *tx)
1266{
1267 u32 original_head = 0;
1268
1269 original_head = tx->last_head;
1270 do {
1271 lan743x_tx_release_desc(tx, tx->last_head, true);
1272 tx->last_head = lan743x_tx_next_index(tx, tx->last_head);
1273 } while (tx->last_head != original_head);
1274 memset(tx->ring_cpu_ptr, 0,
1275 sizeof(*tx->ring_cpu_ptr) * (tx->ring_size));
1276 memset(tx->buffer_info, 0,
1277 sizeof(*tx->buffer_info) * (tx->ring_size));
1278}
1279
1280static int lan743x_tx_get_desc_cnt(struct lan743x_tx *tx,
1281 struct sk_buff *skb)
1282{
1283 int result = 1; /* 1 for the main skb buffer */
1284 int nr_frags = 0;
1285
1286 if (skb_is_gso(skb))
1287 result++; /* requires an extension descriptor */
1288 nr_frags = skb_shinfo(skb)->nr_frags;
1289 result += nr_frags; /* 1 for each fragment buffer */
1290 return result;
1291}
1292
1293static int lan743x_tx_get_avail_desc(struct lan743x_tx *tx)
1294{
1295 int last_head = tx->last_head;
1296 int last_tail = tx->last_tail;
1297
1298 if (last_tail >= last_head)
1299 return tx->ring_size - last_tail + last_head - 1;
1300 else
1301 return last_head - last_tail - 1;
1302}
1303
1304static int lan743x_tx_frame_start(struct lan743x_tx *tx,
1305 unsigned char *first_buffer,
1306 unsigned int first_buffer_length,
1307 unsigned int frame_length,
1308 bool check_sum)
1309{
1310 /* called only from within lan743x_tx_xmit_frame.
1311 * assuming tx->ring_lock has already been acquired.
1312 */
1313 struct lan743x_tx_descriptor *tx_descriptor = NULL;
1314 struct lan743x_tx_buffer_info *buffer_info = NULL;
1315 struct lan743x_adapter *adapter = tx->adapter;
1316 struct device *dev = &adapter->pdev->dev;
1317 dma_addr_t dma_ptr;
1318
1319 tx->frame_flags |= TX_FRAME_FLAG_IN_PROGRESS;
1320 tx->frame_first = tx->last_tail;
1321 tx->frame_tail = tx->frame_first;
1322
1323 tx_descriptor = &tx->ring_cpu_ptr[tx->frame_tail];
1324 buffer_info = &tx->buffer_info[tx->frame_tail];
1325 dma_ptr = dma_map_single(dev, first_buffer, first_buffer_length,
1326 DMA_TO_DEVICE);
1327 if (dma_mapping_error(dev, dma_ptr))
1328 return -ENOMEM;
1329
1330 tx_descriptor->data1 = DMA_ADDR_LOW32(dma_ptr);
1331 tx_descriptor->data2 = DMA_ADDR_HIGH32(dma_ptr);
1332 tx_descriptor->data3 = (frame_length << 16) &
1333 TX_DESC_DATA3_FRAME_LENGTH_MSS_MASK_;
1334
1335 buffer_info->skb = NULL;
1336 buffer_info->dma_ptr = dma_ptr;
1337 buffer_info->buffer_length = first_buffer_length;
1338 buffer_info->flags |= TX_BUFFER_INFO_FLAG_ACTIVE;
1339
1340 tx->frame_data0 = (first_buffer_length &
1341 TX_DESC_DATA0_BUF_LENGTH_MASK_) |
1342 TX_DESC_DATA0_DTYPE_DATA_ |
1343 TX_DESC_DATA0_FS_ |
1344 TX_DESC_DATA0_FCS_;
1345
1346 if (check_sum)
1347 tx->frame_data0 |= TX_DESC_DATA0_ICE_ |
1348 TX_DESC_DATA0_IPE_ |
1349 TX_DESC_DATA0_TPE_;
1350
1351 /* data0 will be programmed in one of other frame assembler functions */
1352 return 0;
1353}
1354
1355static void lan743x_tx_frame_add_lso(struct lan743x_tx *tx,
1356 unsigned int frame_length)
1357{
1358 /* called only from within lan743x_tx_xmit_frame.
1359 * assuming tx->ring_lock has already been acquired.
1360 */
1361 struct lan743x_tx_descriptor *tx_descriptor = NULL;
1362 struct lan743x_tx_buffer_info *buffer_info = NULL;
1363
1364 /* wrap up previous descriptor */
1365 tx->frame_data0 |= TX_DESC_DATA0_EXT_;
1366 tx_descriptor = &tx->ring_cpu_ptr[tx->frame_tail];
1367 tx_descriptor->data0 = tx->frame_data0;
1368
1369 /* move to next descriptor */
1370 tx->frame_tail = lan743x_tx_next_index(tx, tx->frame_tail);
1371 tx_descriptor = &tx->ring_cpu_ptr[tx->frame_tail];
1372 buffer_info = &tx->buffer_info[tx->frame_tail];
1373
1374 /* add extension descriptor */
1375 tx_descriptor->data1 = 0;
1376 tx_descriptor->data2 = 0;
1377 tx_descriptor->data3 = 0;
1378
1379 buffer_info->skb = NULL;
1380 buffer_info->dma_ptr = 0;
1381 buffer_info->buffer_length = 0;
1382 buffer_info->flags |= TX_BUFFER_INFO_FLAG_ACTIVE;
1383
1384 tx->frame_data0 = (frame_length & TX_DESC_DATA0_EXT_PAY_LENGTH_MASK_) |
1385 TX_DESC_DATA0_DTYPE_EXT_ |
1386 TX_DESC_DATA0_EXT_LSO_;
1387
1388 /* data0 will be programmed in one of other frame assembler functions */
1389}
1390
1391static int lan743x_tx_frame_add_fragment(struct lan743x_tx *tx,
1392 const struct skb_frag_struct *fragment,
1393 unsigned int frame_length)
1394{
1395 /* called only from within lan743x_tx_xmit_frame
1396 * assuming tx->ring_lock has already been acquired
1397 */
1398 struct lan743x_tx_descriptor *tx_descriptor = NULL;
1399 struct lan743x_tx_buffer_info *buffer_info = NULL;
1400 struct lan743x_adapter *adapter = tx->adapter;
1401 struct device *dev = &adapter->pdev->dev;
1402 unsigned int fragment_length = 0;
1403 dma_addr_t dma_ptr;
1404
1405 fragment_length = skb_frag_size(fragment);
1406 if (!fragment_length)
1407 return 0;
1408
1409 /* wrap up previous descriptor */
1410 tx_descriptor = &tx->ring_cpu_ptr[tx->frame_tail];
1411 tx_descriptor->data0 = tx->frame_data0;
1412
1413 /* move to next descriptor */
1414 tx->frame_tail = lan743x_tx_next_index(tx, tx->frame_tail);
1415 tx_descriptor = &tx->ring_cpu_ptr[tx->frame_tail];
1416 buffer_info = &tx->buffer_info[tx->frame_tail];
1417 dma_ptr = skb_frag_dma_map(dev, fragment,
1418 0, fragment_length,
1419 DMA_TO_DEVICE);
1420 if (dma_mapping_error(dev, dma_ptr)) {
1421 int desc_index;
1422
1423 /* cleanup all previously setup descriptors */
1424 desc_index = tx->frame_first;
1425 while (desc_index != tx->frame_tail) {
1426 lan743x_tx_release_desc(tx, desc_index, true);
1427 desc_index = lan743x_tx_next_index(tx, desc_index);
1428 }
1429 dma_wmb();
1430 tx->frame_flags &= ~TX_FRAME_FLAG_IN_PROGRESS;
1431 tx->frame_first = 0;
1432 tx->frame_data0 = 0;
1433 tx->frame_tail = 0;
1434 return -ENOMEM;
1435 }
1436
1437 tx_descriptor->data1 = DMA_ADDR_LOW32(dma_ptr);
1438 tx_descriptor->data2 = DMA_ADDR_HIGH32(dma_ptr);
1439 tx_descriptor->data3 = (frame_length << 16) &
1440 TX_DESC_DATA3_FRAME_LENGTH_MSS_MASK_;
1441
1442 buffer_info->skb = NULL;
1443 buffer_info->dma_ptr = dma_ptr;
1444 buffer_info->buffer_length = fragment_length;
1445 buffer_info->flags |= TX_BUFFER_INFO_FLAG_ACTIVE;
1446 buffer_info->flags |= TX_BUFFER_INFO_FLAG_SKB_FRAGMENT;
1447
1448 tx->frame_data0 = (fragment_length & TX_DESC_DATA0_BUF_LENGTH_MASK_) |
1449 TX_DESC_DATA0_DTYPE_DATA_ |
1450 TX_DESC_DATA0_FCS_;
1451
1452 /* data0 will be programmed in one of other frame assembler functions */
1453 return 0;
1454}
1455
1456static void lan743x_tx_frame_end(struct lan743x_tx *tx,
1457 struct sk_buff *skb,
1458 bool ignore_sync)
1459{
1460 /* called only from within lan743x_tx_xmit_frame
1461 * assuming tx->ring_lock has already been acquired
1462 */
1463 struct lan743x_tx_descriptor *tx_descriptor = NULL;
1464 struct lan743x_tx_buffer_info *buffer_info = NULL;
1465 struct lan743x_adapter *adapter = tx->adapter;
1466 u32 tx_tail_flags = 0;
1467
1468 /* wrap up previous descriptor */
1469 tx->frame_data0 |= TX_DESC_DATA0_LS_;
1470 tx->frame_data0 |= TX_DESC_DATA0_IOC_;
1471
1472 tx_descriptor = &tx->ring_cpu_ptr[tx->frame_tail];
1473 buffer_info = &tx->buffer_info[tx->frame_tail];
1474 buffer_info->skb = skb;
1475 if (ignore_sync)
1476 buffer_info->flags |= TX_BUFFER_INFO_FLAG_IGNORE_SYNC;
1477
1478 tx_descriptor->data0 = tx->frame_data0;
1479 tx->frame_tail = lan743x_tx_next_index(tx, tx->frame_tail);
1480 tx->last_tail = tx->frame_tail;
1481
1482 dma_wmb();
1483
1484 if (tx->vector_flags & LAN743X_VECTOR_FLAG_VECTOR_ENABLE_AUTO_SET)
1485 tx_tail_flags |= TX_TAIL_SET_TOP_INT_VEC_EN_;
1486 if (tx->vector_flags & LAN743X_VECTOR_FLAG_SOURCE_ENABLE_AUTO_SET)
1487 tx_tail_flags |= TX_TAIL_SET_DMAC_INT_EN_ |
1488 TX_TAIL_SET_TOP_INT_EN_;
1489
1490 lan743x_csr_write(adapter, TX_TAIL(tx->channel_number),
1491 tx_tail_flags | tx->frame_tail);
1492 tx->frame_flags &= ~TX_FRAME_FLAG_IN_PROGRESS;
1493}
1494
1495static netdev_tx_t lan743x_tx_xmit_frame(struct lan743x_tx *tx,
1496 struct sk_buff *skb)
1497{
1498 int required_number_of_descriptors = 0;
1499 unsigned int start_frame_length = 0;
1500 unsigned int frame_length = 0;
1501 unsigned int head_length = 0;
1502 unsigned long irq_flags = 0;
1503 bool ignore_sync = false;
1504 int nr_frags = 0;
1505 bool gso = false;
1506 int j;
1507
1508 required_number_of_descriptors = lan743x_tx_get_desc_cnt(tx, skb);
1509
1510 spin_lock_irqsave(&tx->ring_lock, irq_flags);
1511 if (required_number_of_descriptors >
1512 lan743x_tx_get_avail_desc(tx)) {
1513 if (required_number_of_descriptors > (tx->ring_size - 1)) {
1514 dev_kfree_skb(skb);
1515 } else {
1516 /* save to overflow buffer */
1517 tx->overflow_skb = skb;
1518 netif_stop_queue(tx->adapter->netdev);
1519 }
1520 goto unlock;
1521 }
1522
1523 /* space available, transmit skb */
1524 head_length = skb_headlen(skb);
1525 frame_length = skb_pagelen(skb);
1526 nr_frags = skb_shinfo(skb)->nr_frags;
1527 start_frame_length = frame_length;
1528 gso = skb_is_gso(skb);
1529 if (gso) {
1530 start_frame_length = max(skb_shinfo(skb)->gso_size,
1531 (unsigned short)8);
1532 }
1533
1534 if (lan743x_tx_frame_start(tx,
1535 skb->data, head_length,
1536 start_frame_length,
1537 skb->ip_summed == CHECKSUM_PARTIAL)) {
1538 dev_kfree_skb(skb);
1539 goto unlock;
1540 }
1541
1542 if (gso)
1543 lan743x_tx_frame_add_lso(tx, frame_length);
1544
1545 if (nr_frags <= 0)
1546 goto finish;
1547
1548 for (j = 0; j < nr_frags; j++) {
1549 const struct skb_frag_struct *frag;
1550
1551 frag = &(skb_shinfo(skb)->frags[j]);
1552 if (lan743x_tx_frame_add_fragment(tx, frag, frame_length)) {
1553 /* upon error no need to call
1554 * lan743x_tx_frame_end
1555 * frame assembler clean up was performed inside
1556 * lan743x_tx_frame_add_fragment
1557 */
1558 dev_kfree_skb(skb);
1559 goto unlock;
1560 }
1561 }
1562
1563finish:
1564 lan743x_tx_frame_end(tx, skb, ignore_sync);
1565
1566unlock:
1567 spin_unlock_irqrestore(&tx->ring_lock, irq_flags);
1568 return NETDEV_TX_OK;
1569}
1570
1571static int lan743x_tx_napi_poll(struct napi_struct *napi, int weight)
1572{
1573 struct lan743x_tx *tx = container_of(napi, struct lan743x_tx, napi);
1574 struct lan743x_adapter *adapter = tx->adapter;
1575 bool start_transmitter = false;
1576 unsigned long irq_flags = 0;
1577 u32 ioc_bit = 0;
1578 u32 int_sts = 0;
1579
1580 ioc_bit = DMAC_INT_BIT_TX_IOC_(tx->channel_number);
1581 int_sts = lan743x_csr_read(adapter, DMAC_INT_STS);
1582 if (tx->vector_flags & LAN743X_VECTOR_FLAG_SOURCE_STATUS_W2C)
1583 lan743x_csr_write(adapter, DMAC_INT_STS, ioc_bit);
1584 spin_lock_irqsave(&tx->ring_lock, irq_flags);
1585
1586 /* clean up tx ring */
1587 lan743x_tx_release_completed_descriptors(tx);
1588 if (netif_queue_stopped(adapter->netdev)) {
1589 if (tx->overflow_skb) {
1590 if (lan743x_tx_get_desc_cnt(tx, tx->overflow_skb) <=
1591 lan743x_tx_get_avail_desc(tx))
1592 start_transmitter = true;
1593 } else {
1594 netif_wake_queue(adapter->netdev);
1595 }
1596 }
1597 spin_unlock_irqrestore(&tx->ring_lock, irq_flags);
1598
1599 if (start_transmitter) {
1600 /* space is now available, transmit overflow skb */
1601 lan743x_tx_xmit_frame(tx, tx->overflow_skb);
1602 tx->overflow_skb = NULL;
1603 netif_wake_queue(adapter->netdev);
1604 }
1605
1606 if (!napi_complete_done(napi, weight))
1607 goto done;
1608
1609 /* enable isr */
1610 lan743x_csr_write(adapter, INT_EN_SET,
1611 INT_BIT_DMA_TX_(tx->channel_number));
1612 lan743x_csr_read(adapter, INT_STS);
1613
1614done:
1615 return weight;
1616}
1617
1618static void lan743x_tx_ring_cleanup(struct lan743x_tx *tx)
1619{
1620 if (tx->head_cpu_ptr) {
1621 pci_free_consistent(tx->adapter->pdev,
1622 sizeof(*tx->head_cpu_ptr),
1623 (void *)(tx->head_cpu_ptr),
1624 tx->head_dma_ptr);
1625 tx->head_cpu_ptr = NULL;
1626 tx->head_dma_ptr = 0;
1627 }
1628 kfree(tx->buffer_info);
1629 tx->buffer_info = NULL;
1630
1631 if (tx->ring_cpu_ptr) {
1632 pci_free_consistent(tx->adapter->pdev,
1633 tx->ring_allocation_size,
1634 tx->ring_cpu_ptr,
1635 tx->ring_dma_ptr);
1636 tx->ring_allocation_size = 0;
1637 tx->ring_cpu_ptr = NULL;
1638 tx->ring_dma_ptr = 0;
1639 }
1640 tx->ring_size = 0;
1641}
1642
1643static int lan743x_tx_ring_init(struct lan743x_tx *tx)
1644{
1645 size_t ring_allocation_size = 0;
1646 void *cpu_ptr = NULL;
1647 dma_addr_t dma_ptr;
1648 int ret = -ENOMEM;
1649
1650 tx->ring_size = LAN743X_TX_RING_SIZE;
1651 if (tx->ring_size & ~TX_CFG_B_TX_RING_LEN_MASK_) {
1652 ret = -EINVAL;
1653 goto cleanup;
1654 }
1655 ring_allocation_size = ALIGN(tx->ring_size *
1656 sizeof(struct lan743x_tx_descriptor),
1657 PAGE_SIZE);
1658 dma_ptr = 0;
1659 cpu_ptr = pci_zalloc_consistent(tx->adapter->pdev,
1660 ring_allocation_size, &dma_ptr);
1661 if (!cpu_ptr) {
1662 ret = -ENOMEM;
1663 goto cleanup;
1664 }
1665
1666 tx->ring_allocation_size = ring_allocation_size;
1667 tx->ring_cpu_ptr = (struct lan743x_tx_descriptor *)cpu_ptr;
1668 tx->ring_dma_ptr = dma_ptr;
1669
1670 cpu_ptr = kcalloc(tx->ring_size, sizeof(*tx->buffer_info), GFP_KERNEL);
1671 if (!cpu_ptr) {
1672 ret = -ENOMEM;
1673 goto cleanup;
1674 }
1675 tx->buffer_info = (struct lan743x_tx_buffer_info *)cpu_ptr;
1676 dma_ptr = 0;
1677 cpu_ptr = pci_zalloc_consistent(tx->adapter->pdev,
1678 sizeof(*tx->head_cpu_ptr), &dma_ptr);
1679 if (!cpu_ptr) {
1680 ret = -ENOMEM;
1681 goto cleanup;
1682 }
1683
1684 tx->head_cpu_ptr = cpu_ptr;
1685 tx->head_dma_ptr = dma_ptr;
1686 if (tx->head_dma_ptr & 0x3) {
1687 ret = -ENOMEM;
1688 goto cleanup;
1689 }
1690
1691 return 0;
1692
1693cleanup:
1694 lan743x_tx_ring_cleanup(tx);
1695 return ret;
1696}
1697
1698static void lan743x_tx_close(struct lan743x_tx *tx)
1699{
1700 struct lan743x_adapter *adapter = tx->adapter;
1701
1702 lan743x_csr_write(adapter,
1703 DMAC_CMD,
1704 DMAC_CMD_STOP_T_(tx->channel_number));
1705 lan743x_dmac_tx_wait_till_stopped(adapter, tx->channel_number);
1706
1707 lan743x_csr_write(adapter,
1708 DMAC_INT_EN_CLR,
1709 DMAC_INT_BIT_TX_IOC_(tx->channel_number));
1710 lan743x_csr_write(adapter, INT_EN_CLR,
1711 INT_BIT_DMA_TX_(tx->channel_number));
1712 napi_disable(&tx->napi);
1713 netif_napi_del(&tx->napi);
1714
1715 lan743x_csr_write(adapter, FCT_TX_CTL,
1716 FCT_TX_CTL_DIS_(tx->channel_number));
1717 lan743x_csr_wait_for_bit(adapter, FCT_TX_CTL,
1718 FCT_TX_CTL_EN_(tx->channel_number),
1719 0, 1000, 20000, 100);
1720
1721 lan743x_tx_release_all_descriptors(tx);
1722
1723 if (tx->overflow_skb) {
1724 dev_kfree_skb(tx->overflow_skb);
1725 tx->overflow_skb = NULL;
1726 }
1727
1728 lan743x_tx_ring_cleanup(tx);
1729}
1730
1731static int lan743x_tx_open(struct lan743x_tx *tx)
1732{
1733 struct lan743x_adapter *adapter = NULL;
1734 u32 data = 0;
1735 int ret;
1736
1737 adapter = tx->adapter;
1738 ret = lan743x_tx_ring_init(tx);
1739 if (ret)
1740 return ret;
1741
1742 /* initialize fifo */
1743 lan743x_csr_write(adapter, FCT_TX_CTL,
1744 FCT_TX_CTL_RESET_(tx->channel_number));
1745 lan743x_csr_wait_for_bit(adapter, FCT_TX_CTL,
1746 FCT_TX_CTL_RESET_(tx->channel_number),
1747 0, 1000, 20000, 100);
1748
1749 /* enable fifo */
1750 lan743x_csr_write(adapter, FCT_TX_CTL,
1751 FCT_TX_CTL_EN_(tx->channel_number));
1752
1753 /* reset tx channel */
1754 lan743x_csr_write(adapter, DMAC_CMD,
1755 DMAC_CMD_TX_SWR_(tx->channel_number));
1756 lan743x_csr_wait_for_bit(adapter, DMAC_CMD,
1757 DMAC_CMD_TX_SWR_(tx->channel_number),
1758 0, 1000, 20000, 100);
1759
1760 /* Write TX_BASE_ADDR */
1761 lan743x_csr_write(adapter,
1762 TX_BASE_ADDRH(tx->channel_number),
1763 DMA_ADDR_HIGH32(tx->ring_dma_ptr));
1764 lan743x_csr_write(adapter,
1765 TX_BASE_ADDRL(tx->channel_number),
1766 DMA_ADDR_LOW32(tx->ring_dma_ptr));
1767
1768 /* Write TX_CFG_B */
1769 data = lan743x_csr_read(adapter, TX_CFG_B(tx->channel_number));
1770 data &= ~TX_CFG_B_TX_RING_LEN_MASK_;
1771 data |= ((tx->ring_size) & TX_CFG_B_TX_RING_LEN_MASK_);
1772 if (!(adapter->csr.flags & LAN743X_CSR_FLAG_IS_A0))
1773 data |= TX_CFG_B_TDMABL_512_;
1774 lan743x_csr_write(adapter, TX_CFG_B(tx->channel_number), data);
1775
1776 /* Write TX_CFG_A */
1777 data = TX_CFG_A_TX_TMR_HPWB_SEL_IOC_ | TX_CFG_A_TX_HP_WB_EN_;
1778 if (!(adapter->csr.flags & LAN743X_CSR_FLAG_IS_A0)) {
1779 data |= TX_CFG_A_TX_HP_WB_ON_INT_TMR_;
1780 data |= TX_CFG_A_TX_PF_THRES_SET_(0x10);
1781 data |= TX_CFG_A_TX_PF_PRI_THRES_SET_(0x04);
1782 data |= TX_CFG_A_TX_HP_WB_THRES_SET_(0x07);
1783 }
1784 lan743x_csr_write(adapter, TX_CFG_A(tx->channel_number), data);
1785
1786 /* Write TX_HEAD_WRITEBACK_ADDR */
1787 lan743x_csr_write(adapter,
1788 TX_HEAD_WRITEBACK_ADDRH(tx->channel_number),
1789 DMA_ADDR_HIGH32(tx->head_dma_ptr));
1790 lan743x_csr_write(adapter,
1791 TX_HEAD_WRITEBACK_ADDRL(tx->channel_number),
1792 DMA_ADDR_LOW32(tx->head_dma_ptr));
1793
1794 /* set last head */
1795 tx->last_head = lan743x_csr_read(adapter, TX_HEAD(tx->channel_number));
1796
1797 /* write TX_TAIL */
1798 tx->last_tail = 0;
1799 lan743x_csr_write(adapter, TX_TAIL(tx->channel_number),
1800 (u32)(tx->last_tail));
1801 tx->vector_flags = lan743x_intr_get_vector_flags(adapter,
1802 INT_BIT_DMA_TX_
1803 (tx->channel_number));
1804 netif_napi_add(adapter->netdev,
1805 &tx->napi, lan743x_tx_napi_poll,
1806 tx->ring_size - 1);
1807 napi_enable(&tx->napi);
1808
1809 data = 0;
1810 if (tx->vector_flags & LAN743X_VECTOR_FLAG_SOURCE_ENABLE_AUTO_CLEAR)
1811 data |= TX_CFG_C_TX_TOP_INT_EN_AUTO_CLR_;
1812 if (tx->vector_flags & LAN743X_VECTOR_FLAG_SOURCE_STATUS_AUTO_CLEAR)
1813 data |= TX_CFG_C_TX_DMA_INT_STS_AUTO_CLR_;
1814 if (tx->vector_flags & LAN743X_VECTOR_FLAG_SOURCE_STATUS_R2C)
1815 data |= TX_CFG_C_TX_INT_STS_R2C_MODE_MASK_;
1816 if (tx->vector_flags & LAN743X_VECTOR_FLAG_SOURCE_ENABLE_R2C)
1817 data |= TX_CFG_C_TX_INT_EN_R2C_;
1818 lan743x_csr_write(adapter, TX_CFG_C(tx->channel_number), data);
1819
1820 if (!(tx->vector_flags & LAN743X_VECTOR_FLAG_SOURCE_ENABLE_AUTO_SET))
1821 lan743x_csr_write(adapter, INT_EN_SET,
1822 INT_BIT_DMA_TX_(tx->channel_number));
1823 lan743x_csr_write(adapter, DMAC_INT_EN_SET,
1824 DMAC_INT_BIT_TX_IOC_(tx->channel_number));
1825
1826 /* start dmac channel */
1827 lan743x_csr_write(adapter, DMAC_CMD,
1828 DMAC_CMD_START_T_(tx->channel_number));
1829 return 0;
1830}
1831
1832static int lan743x_rx_next_index(struct lan743x_rx *rx, int index)
1833{
1834 return ((++index) % rx->ring_size);
1835}
1836
1837static int lan743x_rx_allocate_ring_element(struct lan743x_rx *rx, int index)
1838{
1839 struct lan743x_rx_buffer_info *buffer_info;
1840 struct lan743x_rx_descriptor *descriptor;
1841 int length = 0;
1842
1843 length = (LAN743X_MAX_FRAME_SIZE + ETH_HLEN + 4 + RX_HEAD_PADDING);
1844 descriptor = &rx->ring_cpu_ptr[index];
1845 buffer_info = &rx->buffer_info[index];
1846 buffer_info->skb = __netdev_alloc_skb(rx->adapter->netdev,
1847 length,
1848 GFP_ATOMIC | GFP_DMA);
1849 if (!(buffer_info->skb))
1850 return -ENOMEM;
1851 buffer_info->dma_ptr = dma_map_single(&rx->adapter->pdev->dev,
1852 buffer_info->skb->data,
1853 length,
1854 DMA_FROM_DEVICE);
1855 if (dma_mapping_error(&rx->adapter->pdev->dev,
1856 buffer_info->dma_ptr)) {
1857 buffer_info->dma_ptr = 0;
1858 return -ENOMEM;
1859 }
1860
1861 buffer_info->buffer_length = length;
1862 descriptor->data1 = DMA_ADDR_LOW32(buffer_info->dma_ptr);
1863 descriptor->data2 = DMA_ADDR_HIGH32(buffer_info->dma_ptr);
1864 descriptor->data3 = 0;
1865 descriptor->data0 = (RX_DESC_DATA0_OWN_ |
1866 (length & RX_DESC_DATA0_BUF_LENGTH_MASK_));
1867 skb_reserve(buffer_info->skb, RX_HEAD_PADDING);
1868
1869 return 0;
1870}
1871
1872static void lan743x_rx_reuse_ring_element(struct lan743x_rx *rx, int index)
1873{
1874 struct lan743x_rx_buffer_info *buffer_info;
1875 struct lan743x_rx_descriptor *descriptor;
1876
1877 descriptor = &rx->ring_cpu_ptr[index];
1878 buffer_info = &rx->buffer_info[index];
1879
1880 descriptor->data1 = DMA_ADDR_LOW32(buffer_info->dma_ptr);
1881 descriptor->data2 = DMA_ADDR_HIGH32(buffer_info->dma_ptr);
1882 descriptor->data3 = 0;
1883 descriptor->data0 = (RX_DESC_DATA0_OWN_ |
1884 ((buffer_info->buffer_length) &
1885 RX_DESC_DATA0_BUF_LENGTH_MASK_));
1886}
1887
1888static void lan743x_rx_release_ring_element(struct lan743x_rx *rx, int index)
1889{
1890 struct lan743x_rx_buffer_info *buffer_info;
1891 struct lan743x_rx_descriptor *descriptor;
1892
1893 descriptor = &rx->ring_cpu_ptr[index];
1894 buffer_info = &rx->buffer_info[index];
1895
1896 memset(descriptor, 0, sizeof(*descriptor));
1897
1898 if (buffer_info->dma_ptr) {
1899 dma_unmap_single(&rx->adapter->pdev->dev,
1900 buffer_info->dma_ptr,
1901 buffer_info->buffer_length,
1902 DMA_FROM_DEVICE);
1903 buffer_info->dma_ptr = 0;
1904 }
1905
1906 if (buffer_info->skb) {
1907 dev_kfree_skb(buffer_info->skb);
1908 buffer_info->skb = NULL;
1909 }
1910
1911 memset(buffer_info, 0, sizeof(*buffer_info));
1912}
1913
1914static int lan743x_rx_process_packet(struct lan743x_rx *rx)
1915{
1916 struct skb_shared_hwtstamps *hwtstamps = NULL;
1917 int result = RX_PROCESS_RESULT_NOTHING_TO_DO;
1918 struct lan743x_rx_buffer_info *buffer_info;
1919 struct lan743x_rx_descriptor *descriptor;
1920 int current_head_index = -1;
1921 int extension_index = -1;
1922 int first_index = -1;
1923 int last_index = -1;
1924
1925 current_head_index = *rx->head_cpu_ptr;
1926 if (current_head_index < 0 || current_head_index >= rx->ring_size)
1927 goto done;
1928
1929 if (rx->last_head < 0 || rx->last_head >= rx->ring_size)
1930 goto done;
1931
1932 if (rx->last_head != current_head_index) {
1933 descriptor = &rx->ring_cpu_ptr[rx->last_head];
1934 if (descriptor->data0 & RX_DESC_DATA0_OWN_)
1935 goto done;
1936
1937 if (!(descriptor->data0 & RX_DESC_DATA0_FS_))
1938 goto done;
1939
1940 first_index = rx->last_head;
1941 if (descriptor->data0 & RX_DESC_DATA0_LS_) {
1942 last_index = rx->last_head;
1943 } else {
1944 int index;
1945
1946 index = lan743x_rx_next_index(rx, first_index);
1947 while (index != current_head_index) {
1948 descriptor = &rx->ring_cpu_ptr[index];
1949 if (descriptor->data0 & RX_DESC_DATA0_OWN_)
1950 goto done;
1951
1952 if (descriptor->data0 & RX_DESC_DATA0_LS_) {
1953 last_index = index;
1954 break;
1955 }
1956 index = lan743x_rx_next_index(rx, index);
1957 }
1958 }
1959 if (last_index >= 0) {
1960 descriptor = &rx->ring_cpu_ptr[last_index];
1961 if (descriptor->data0 & RX_DESC_DATA0_EXT_) {
1962 /* extension is expected to follow */
1963 int index = lan743x_rx_next_index(rx,
1964 last_index);
1965 if (index != current_head_index) {
1966 descriptor = &rx->ring_cpu_ptr[index];
1967 if (descriptor->data0 &
1968 RX_DESC_DATA0_OWN_) {
1969 goto done;
1970 }
1971 if (descriptor->data0 &
1972 RX_DESC_DATA0_EXT_) {
1973 extension_index = index;
1974 } else {
1975 goto done;
1976 }
1977 } else {
1978 /* extension is not yet available */
1979 /* prevent processing of this packet */
1980 first_index = -1;
1981 last_index = -1;
1982 }
1983 }
1984 }
1985 }
1986 if (first_index >= 0 && last_index >= 0) {
1987 int real_last_index = last_index;
1988 struct sk_buff *skb = NULL;
1989 u32 ts_sec = 0;
1990 u32 ts_nsec = 0;
1991
1992 /* packet is available */
1993 if (first_index == last_index) {
1994 /* single buffer packet */
1995 int packet_length;
1996
1997 buffer_info = &rx->buffer_info[first_index];
1998 skb = buffer_info->skb;
1999 descriptor = &rx->ring_cpu_ptr[first_index];
2000
2001 /* unmap from dma */
2002 if (buffer_info->dma_ptr) {
2003 dma_unmap_single(&rx->adapter->pdev->dev,
2004 buffer_info->dma_ptr,
2005 buffer_info->buffer_length,
2006 DMA_FROM_DEVICE);
2007 buffer_info->dma_ptr = 0;
2008 buffer_info->buffer_length = 0;
2009 }
2010 buffer_info->skb = NULL;
2011 packet_length = RX_DESC_DATA0_FRAME_LENGTH_GET_
2012 (descriptor->data0);
2013 skb_put(skb, packet_length - 4);
2014 skb->protocol = eth_type_trans(skb,
2015 rx->adapter->netdev);
2016 lan743x_rx_allocate_ring_element(rx, first_index);
2017 } else {
2018 int index = first_index;
2019
2020 /* multi buffer packet not supported */
2021 /* this should not happen since
2022 * buffers are allocated to be at least jumbo size
2023 */
2024
2025 /* clean up buffers */
2026 if (first_index <= last_index) {
2027 while ((index >= first_index) &&
2028 (index <= last_index)) {
2029 lan743x_rx_release_ring_element(rx,
2030 index);
2031 lan743x_rx_allocate_ring_element(rx,
2032 index);
2033 index = lan743x_rx_next_index(rx,
2034 index);
2035 }
2036 } else {
2037 while ((index >= first_index) ||
2038 (index <= last_index)) {
2039 lan743x_rx_release_ring_element(rx,
2040 index);
2041 lan743x_rx_allocate_ring_element(rx,
2042 index);
2043 index = lan743x_rx_next_index(rx,
2044 index);
2045 }
2046 }
2047 }
2048
2049 if (extension_index >= 0) {
2050 descriptor = &rx->ring_cpu_ptr[extension_index];
2051 buffer_info = &rx->buffer_info[extension_index];
2052
2053 ts_sec = descriptor->data1;
2054 ts_nsec = (descriptor->data2 &
2055 RX_DESC_DATA2_TS_NS_MASK_);
2056 lan743x_rx_reuse_ring_element(rx, extension_index);
2057 real_last_index = extension_index;
2058 }
2059
2060 if (!skb) {
2061 result = RX_PROCESS_RESULT_PACKET_DROPPED;
2062 goto move_forward;
2063 }
2064
2065 if (extension_index < 0)
2066 goto pass_packet_to_os;
2067 hwtstamps = skb_hwtstamps(skb);
2068 if (hwtstamps)
2069 hwtstamps->hwtstamp = ktime_set(ts_sec, ts_nsec);
2070
2071pass_packet_to_os:
2072 /* pass packet to OS */
2073 napi_gro_receive(&rx->napi, skb);
2074 result = RX_PROCESS_RESULT_PACKET_RECEIVED;
2075
2076move_forward:
2077 /* push tail and head forward */
2078 rx->last_tail = real_last_index;
2079 rx->last_head = lan743x_rx_next_index(rx, real_last_index);
2080 }
2081done:
2082 return result;
2083}
2084
2085static int lan743x_rx_napi_poll(struct napi_struct *napi, int weight)
2086{
2087 struct lan743x_rx *rx = container_of(napi, struct lan743x_rx, napi);
2088 struct lan743x_adapter *adapter = rx->adapter;
2089 u32 rx_tail_flags = 0;
2090 int count;
2091
2092 if (rx->vector_flags & LAN743X_VECTOR_FLAG_SOURCE_STATUS_W2C) {
2093 /* clear int status bit before reading packet */
2094 lan743x_csr_write(adapter, DMAC_INT_STS,
2095 DMAC_INT_BIT_RXFRM_(rx->channel_number));
2096 }
2097 count = 0;
2098 while (count < weight) {
2099 int rx_process_result = -1;
2100
2101 rx_process_result = lan743x_rx_process_packet(rx);
2102 if (rx_process_result == RX_PROCESS_RESULT_PACKET_RECEIVED) {
2103 count++;
2104 } else if (rx_process_result ==
2105 RX_PROCESS_RESULT_NOTHING_TO_DO) {
2106 break;
2107 } else if (rx_process_result ==
2108 RX_PROCESS_RESULT_PACKET_DROPPED) {
2109 continue;
2110 }
2111 }
2112 rx->frame_count += count;
2113 if (count == weight)
2114 goto done;
2115
2116 if (!napi_complete_done(napi, count))
2117 goto done;
2118
2119 if (rx->vector_flags & LAN743X_VECTOR_FLAG_VECTOR_ENABLE_AUTO_SET)
2120 rx_tail_flags |= RX_TAIL_SET_TOP_INT_VEC_EN_;
2121 if (rx->vector_flags & LAN743X_VECTOR_FLAG_SOURCE_ENABLE_AUTO_SET) {
2122 rx_tail_flags |= RX_TAIL_SET_TOP_INT_EN_;
2123 } else {
2124 lan743x_csr_write(adapter, INT_EN_SET,
2125 INT_BIT_DMA_RX_(rx->channel_number));
2126 }
2127
2128 /* update RX_TAIL */
2129 lan743x_csr_write(adapter, RX_TAIL(rx->channel_number),
2130 rx_tail_flags | rx->last_tail);
2131done:
2132 return count;
2133}
2134
2135static void lan743x_rx_ring_cleanup(struct lan743x_rx *rx)
2136{
2137 if (rx->buffer_info && rx->ring_cpu_ptr) {
2138 int index;
2139
2140 for (index = 0; index < rx->ring_size; index++)
2141 lan743x_rx_release_ring_element(rx, index);
2142 }
2143
2144 if (rx->head_cpu_ptr) {
2145 pci_free_consistent(rx->adapter->pdev,
2146 sizeof(*rx->head_cpu_ptr),
2147 rx->head_cpu_ptr,
2148 rx->head_dma_ptr);
2149 rx->head_cpu_ptr = NULL;
2150 rx->head_dma_ptr = 0;
2151 }
2152
2153 kfree(rx->buffer_info);
2154 rx->buffer_info = NULL;
2155
2156 if (rx->ring_cpu_ptr) {
2157 pci_free_consistent(rx->adapter->pdev,
2158 rx->ring_allocation_size,
2159 rx->ring_cpu_ptr,
2160 rx->ring_dma_ptr);
2161 rx->ring_allocation_size = 0;
2162 rx->ring_cpu_ptr = NULL;
2163 rx->ring_dma_ptr = 0;
2164 }
2165
2166 rx->ring_size = 0;
2167 rx->last_head = 0;
2168}
2169
2170static int lan743x_rx_ring_init(struct lan743x_rx *rx)
2171{
2172 size_t ring_allocation_size = 0;
2173 dma_addr_t dma_ptr = 0;
2174 void *cpu_ptr = NULL;
2175 int ret = -ENOMEM;
2176 int index = 0;
2177
2178 rx->ring_size = LAN743X_RX_RING_SIZE;
2179 if (rx->ring_size <= 1) {
2180 ret = -EINVAL;
2181 goto cleanup;
2182 }
2183 if (rx->ring_size & ~RX_CFG_B_RX_RING_LEN_MASK_) {
2184 ret = -EINVAL;
2185 goto cleanup;
2186 }
2187 ring_allocation_size = ALIGN(rx->ring_size *
2188 sizeof(struct lan743x_rx_descriptor),
2189 PAGE_SIZE);
2190 dma_ptr = 0;
2191 cpu_ptr = pci_zalloc_consistent(rx->adapter->pdev,
2192 ring_allocation_size, &dma_ptr);
2193 if (!cpu_ptr) {
2194 ret = -ENOMEM;
2195 goto cleanup;
2196 }
2197 rx->ring_allocation_size = ring_allocation_size;
2198 rx->ring_cpu_ptr = (struct lan743x_rx_descriptor *)cpu_ptr;
2199 rx->ring_dma_ptr = dma_ptr;
2200
2201 cpu_ptr = kcalloc(rx->ring_size, sizeof(*rx->buffer_info),
2202 GFP_KERNEL);
2203 if (!cpu_ptr) {
2204 ret = -ENOMEM;
2205 goto cleanup;
2206 }
2207 rx->buffer_info = (struct lan743x_rx_buffer_info *)cpu_ptr;
2208 dma_ptr = 0;
2209 cpu_ptr = pci_zalloc_consistent(rx->adapter->pdev,
2210 sizeof(*rx->head_cpu_ptr), &dma_ptr);
2211 if (!cpu_ptr) {
2212 ret = -ENOMEM;
2213 goto cleanup;
2214 }
2215
2216 rx->head_cpu_ptr = cpu_ptr;
2217 rx->head_dma_ptr = dma_ptr;
2218 if (rx->head_dma_ptr & 0x3) {
2219 ret = -ENOMEM;
2220 goto cleanup;
2221 }
2222
2223 rx->last_head = 0;
2224 for (index = 0; index < rx->ring_size; index++) {
2225 ret = lan743x_rx_allocate_ring_element(rx, index);
2226 if (ret)
2227 goto cleanup;
2228 }
2229 return 0;
2230
2231cleanup:
2232 lan743x_rx_ring_cleanup(rx);
2233 return ret;
2234}
2235
2236static void lan743x_rx_close(struct lan743x_rx *rx)
2237{
2238 struct lan743x_adapter *adapter = rx->adapter;
2239
2240 lan743x_csr_write(adapter, FCT_RX_CTL,
2241 FCT_RX_CTL_DIS_(rx->channel_number));
2242 lan743x_csr_wait_for_bit(adapter, FCT_RX_CTL,
2243 FCT_RX_CTL_EN_(rx->channel_number),
2244 0, 1000, 20000, 100);
2245
2246 lan743x_csr_write(adapter, DMAC_CMD,
2247 DMAC_CMD_STOP_R_(rx->channel_number));
2248 lan743x_dmac_rx_wait_till_stopped(adapter, rx->channel_number);
2249
2250 lan743x_csr_write(adapter, DMAC_INT_EN_CLR,
2251 DMAC_INT_BIT_RXFRM_(rx->channel_number));
2252 lan743x_csr_write(adapter, INT_EN_CLR,
2253 INT_BIT_DMA_RX_(rx->channel_number));
2254 napi_disable(&rx->napi);
2255
2256 netif_napi_del(&rx->napi);
2257
2258 lan743x_rx_ring_cleanup(rx);
2259}
2260
2261static int lan743x_rx_open(struct lan743x_rx *rx)
2262{
2263 struct lan743x_adapter *adapter = rx->adapter;
2264 u32 data = 0;
2265 int ret;
2266
2267 rx->frame_count = 0;
2268 ret = lan743x_rx_ring_init(rx);
2269 if (ret)
2270 goto return_error;
2271
2272 netif_napi_add(adapter->netdev,
2273 &rx->napi, lan743x_rx_napi_poll,
2274 rx->ring_size - 1);
2275
2276 lan743x_csr_write(adapter, DMAC_CMD,
2277 DMAC_CMD_RX_SWR_(rx->channel_number));
2278 lan743x_csr_wait_for_bit(adapter, DMAC_CMD,
2279 DMAC_CMD_RX_SWR_(rx->channel_number),
2280 0, 1000, 20000, 100);
2281
2282 /* set ring base address */
2283 lan743x_csr_write(adapter,
2284 RX_BASE_ADDRH(rx->channel_number),
2285 DMA_ADDR_HIGH32(rx->ring_dma_ptr));
2286 lan743x_csr_write(adapter,
2287 RX_BASE_ADDRL(rx->channel_number),
2288 DMA_ADDR_LOW32(rx->ring_dma_ptr));
2289
2290 /* set rx write back address */
2291 lan743x_csr_write(adapter,
2292 RX_HEAD_WRITEBACK_ADDRH(rx->channel_number),
2293 DMA_ADDR_HIGH32(rx->head_dma_ptr));
2294 lan743x_csr_write(adapter,
2295 RX_HEAD_WRITEBACK_ADDRL(rx->channel_number),
2296 DMA_ADDR_LOW32(rx->head_dma_ptr));
2297 data = RX_CFG_A_RX_HP_WB_EN_;
2298 if (!(adapter->csr.flags & LAN743X_CSR_FLAG_IS_A0)) {
2299 data |= (RX_CFG_A_RX_WB_ON_INT_TMR_ |
2300 RX_CFG_A_RX_WB_THRES_SET_(0x7) |
2301 RX_CFG_A_RX_PF_THRES_SET_(16) |
2302 RX_CFG_A_RX_PF_PRI_THRES_SET_(4));
2303 }
2304
2305 /* set RX_CFG_A */
2306 lan743x_csr_write(adapter,
2307 RX_CFG_A(rx->channel_number), data);
2308
2309 /* set RX_CFG_B */
2310 data = lan743x_csr_read(adapter, RX_CFG_B(rx->channel_number));
2311 data &= ~RX_CFG_B_RX_PAD_MASK_;
2312 if (!RX_HEAD_PADDING)
2313 data |= RX_CFG_B_RX_PAD_0_;
2314 else
2315 data |= RX_CFG_B_RX_PAD_2_;
2316 data &= ~RX_CFG_B_RX_RING_LEN_MASK_;
2317 data |= ((rx->ring_size) & RX_CFG_B_RX_RING_LEN_MASK_);
2318 data |= RX_CFG_B_TS_ALL_RX_;
2319 if (!(adapter->csr.flags & LAN743X_CSR_FLAG_IS_A0))
2320 data |= RX_CFG_B_RDMABL_512_;
2321
2322 lan743x_csr_write(adapter, RX_CFG_B(rx->channel_number), data);
2323 rx->vector_flags = lan743x_intr_get_vector_flags(adapter,
2324 INT_BIT_DMA_RX_
2325 (rx->channel_number));
2326
2327 /* set RX_CFG_C */
2328 data = 0;
2329 if (rx->vector_flags & LAN743X_VECTOR_FLAG_SOURCE_ENABLE_AUTO_CLEAR)
2330 data |= RX_CFG_C_RX_TOP_INT_EN_AUTO_CLR_;
2331 if (rx->vector_flags & LAN743X_VECTOR_FLAG_SOURCE_STATUS_AUTO_CLEAR)
2332 data |= RX_CFG_C_RX_DMA_INT_STS_AUTO_CLR_;
2333 if (rx->vector_flags & LAN743X_VECTOR_FLAG_SOURCE_STATUS_R2C)
2334 data |= RX_CFG_C_RX_INT_STS_R2C_MODE_MASK_;
2335 if (rx->vector_flags & LAN743X_VECTOR_FLAG_SOURCE_ENABLE_R2C)
2336 data |= RX_CFG_C_RX_INT_EN_R2C_;
2337 lan743x_csr_write(adapter, RX_CFG_C(rx->channel_number), data);
2338
2339 rx->last_tail = ((u32)(rx->ring_size - 1));
2340 lan743x_csr_write(adapter, RX_TAIL(rx->channel_number),
2341 rx->last_tail);
2342 rx->last_head = lan743x_csr_read(adapter, RX_HEAD(rx->channel_number));
2343 if (rx->last_head) {
2344 ret = -EIO;
2345 goto napi_delete;
2346 }
2347
2348 napi_enable(&rx->napi);
2349
2350 lan743x_csr_write(adapter, INT_EN_SET,
2351 INT_BIT_DMA_RX_(rx->channel_number));
2352 lan743x_csr_write(adapter, DMAC_INT_STS,
2353 DMAC_INT_BIT_RXFRM_(rx->channel_number));
2354 lan743x_csr_write(adapter, DMAC_INT_EN_SET,
2355 DMAC_INT_BIT_RXFRM_(rx->channel_number));
2356 lan743x_csr_write(adapter, DMAC_CMD,
2357 DMAC_CMD_START_R_(rx->channel_number));
2358
2359 /* initialize fifo */
2360 lan743x_csr_write(adapter, FCT_RX_CTL,
2361 FCT_RX_CTL_RESET_(rx->channel_number));
2362 lan743x_csr_wait_for_bit(adapter, FCT_RX_CTL,
2363 FCT_RX_CTL_RESET_(rx->channel_number),
2364 0, 1000, 20000, 100);
2365 lan743x_csr_write(adapter, FCT_FLOW(rx->channel_number),
2366 FCT_FLOW_CTL_REQ_EN_ |
2367 FCT_FLOW_CTL_ON_THRESHOLD_SET_(0x2A) |
2368 FCT_FLOW_CTL_OFF_THRESHOLD_SET_(0xA));
2369
2370 /* enable fifo */
2371 lan743x_csr_write(adapter, FCT_RX_CTL,
2372 FCT_RX_CTL_EN_(rx->channel_number));
2373 return 0;
2374
2375napi_delete:
2376 netif_napi_del(&rx->napi);
2377 lan743x_rx_ring_cleanup(rx);
2378
2379return_error:
2380 return ret;
2381}
2382
2383static int lan743x_netdev_close(struct net_device *netdev)
2384{
2385 struct lan743x_adapter *adapter = netdev_priv(netdev);
2386 int index;
2387
2388 lan743x_tx_close(&adapter->tx[0]);
2389
2390 for (index = 0; index < LAN743X_USED_RX_CHANNELS; index++)
2391 lan743x_rx_close(&adapter->rx[index]);
2392
2393 lan743x_phy_close(adapter);
2394
2395 lan743x_mac_close(adapter);
2396
2397 lan743x_intr_close(adapter);
2398
2399 return 0;
2400}
2401
2402static int lan743x_netdev_open(struct net_device *netdev)
2403{
2404 struct lan743x_adapter *adapter = netdev_priv(netdev);
2405 int index;
2406 int ret;
2407
2408 ret = lan743x_intr_open(adapter);
2409 if (ret)
2410 goto return_error;
2411
2412 ret = lan743x_mac_open(adapter);
2413 if (ret)
2414 goto close_intr;
2415
2416 ret = lan743x_phy_open(adapter);
2417 if (ret)
2418 goto close_mac;
2419
2420 for (index = 0; index < LAN743X_USED_RX_CHANNELS; index++) {
2421 ret = lan743x_rx_open(&adapter->rx[index]);
2422 if (ret)
2423 goto close_rx;
2424 }
2425
2426 ret = lan743x_tx_open(&adapter->tx[0]);
2427 if (ret)
2428 goto close_rx;
2429
2430 return 0;
2431
2432close_rx:
2433 for (index = 0; index < LAN743X_USED_RX_CHANNELS; index++) {
2434 if (adapter->rx[index].ring_cpu_ptr)
2435 lan743x_rx_close(&adapter->rx[index]);
2436 }
2437 lan743x_phy_close(adapter);
2438
2439close_mac:
2440 lan743x_mac_close(adapter);
2441
2442close_intr:
2443 lan743x_intr_close(adapter);
2444
2445return_error:
2446 netif_warn(adapter, ifup, adapter->netdev,
2447 "Error opening LAN743x\n");
2448 return ret;
2449}
2450
2451static netdev_tx_t lan743x_netdev_xmit_frame(struct sk_buff *skb,
2452 struct net_device *netdev)
2453{
2454 struct lan743x_adapter *adapter = netdev_priv(netdev);
2455
2456 return lan743x_tx_xmit_frame(&adapter->tx[0], skb);
2457}
2458
2459static int lan743x_netdev_ioctl(struct net_device *netdev,
2460 struct ifreq *ifr, int cmd)
2461{
2462 if (!netif_running(netdev))
2463 return -EINVAL;
2464 return phy_mii_ioctl(netdev->phydev, ifr, cmd);
2465}
2466
2467static void lan743x_netdev_set_multicast(struct net_device *netdev)
2468{
2469 struct lan743x_adapter *adapter = netdev_priv(netdev);
2470
2471 lan743x_rfe_set_multicast(adapter);
2472}
2473
2474static int lan743x_netdev_change_mtu(struct net_device *netdev, int new_mtu)
2475{
2476 struct lan743x_adapter *adapter = netdev_priv(netdev);
2477 int ret = 0;
2478
2479 ret = lan743x_mac_set_mtu(adapter, new_mtu);
2480 if (!ret)
2481 netdev->mtu = new_mtu;
2482 return ret;
2483}
2484
2485static void lan743x_netdev_get_stats64(struct net_device *netdev,
2486 struct rtnl_link_stats64 *stats)
2487{
2488 struct lan743x_adapter *adapter = netdev_priv(netdev);
2489
2490 stats->rx_packets = lan743x_csr_read(adapter, STAT_RX_TOTAL_FRAMES);
2491 stats->tx_packets = lan743x_csr_read(adapter, STAT_TX_TOTAL_FRAMES);
2492 stats->rx_bytes = lan743x_csr_read(adapter,
2493 STAT_RX_UNICAST_BYTE_COUNT) +
2494 lan743x_csr_read(adapter,
2495 STAT_RX_BROADCAST_BYTE_COUNT) +
2496 lan743x_csr_read(adapter,
2497 STAT_RX_MULTICAST_BYTE_COUNT);
2498 stats->tx_bytes = lan743x_csr_read(adapter,
2499 STAT_TX_UNICAST_BYTE_COUNT) +
2500 lan743x_csr_read(adapter,
2501 STAT_TX_BROADCAST_BYTE_COUNT) +
2502 lan743x_csr_read(adapter,
2503 STAT_TX_MULTICAST_BYTE_COUNT);
2504 stats->rx_errors = lan743x_csr_read(adapter, STAT_RX_FCS_ERRORS) +
2505 lan743x_csr_read(adapter,
2506 STAT_RX_ALIGNMENT_ERRORS) +
2507 lan743x_csr_read(adapter, STAT_RX_JABBER_ERRORS) +
2508 lan743x_csr_read(adapter,
2509 STAT_RX_UNDERSIZE_FRAME_ERRORS) +
2510 lan743x_csr_read(adapter,
2511 STAT_RX_OVERSIZE_FRAME_ERRORS);
2512 stats->tx_errors = lan743x_csr_read(adapter, STAT_TX_FCS_ERRORS) +
2513 lan743x_csr_read(adapter,
2514 STAT_TX_EXCESS_DEFERRAL_ERRORS) +
2515 lan743x_csr_read(adapter, STAT_TX_CARRIER_ERRORS);
2516 stats->rx_dropped = lan743x_csr_read(adapter,
2517 STAT_RX_DROPPED_FRAMES);
2518 stats->tx_dropped = lan743x_csr_read(adapter,
2519 STAT_TX_EXCESSIVE_COLLISION);
2520 stats->multicast = lan743x_csr_read(adapter,
2521 STAT_RX_MULTICAST_FRAMES) +
2522 lan743x_csr_read(adapter,
2523 STAT_TX_MULTICAST_FRAMES);
2524 stats->collisions = lan743x_csr_read(adapter,
2525 STAT_TX_SINGLE_COLLISIONS) +
2526 lan743x_csr_read(adapter,
2527 STAT_TX_MULTIPLE_COLLISIONS) +
2528 lan743x_csr_read(adapter,
2529 STAT_TX_LATE_COLLISIONS);
2530}
2531
2532static int lan743x_netdev_set_mac_address(struct net_device *netdev,
2533 void *addr)
2534{
2535 struct lan743x_adapter *adapter = netdev_priv(netdev);
2536 struct sockaddr *sock_addr = addr;
2537 int ret;
2538
2539 ret = eth_prepare_mac_addr_change(netdev, sock_addr);
2540 if (ret)
2541 return ret;
2542 ether_addr_copy(netdev->dev_addr, sock_addr->sa_data);
2543 lan743x_mac_set_address(adapter, sock_addr->sa_data);
2544 lan743x_rfe_update_mac_address(adapter);
2545 return 0;
2546}
2547
2548static const struct net_device_ops lan743x_netdev_ops = {
2549 .ndo_open = lan743x_netdev_open,
2550 .ndo_stop = lan743x_netdev_close,
2551 .ndo_start_xmit = lan743x_netdev_xmit_frame,
2552 .ndo_do_ioctl = lan743x_netdev_ioctl,
2553 .ndo_set_rx_mode = lan743x_netdev_set_multicast,
2554 .ndo_change_mtu = lan743x_netdev_change_mtu,
2555 .ndo_get_stats64 = lan743x_netdev_get_stats64,
2556 .ndo_set_mac_address = lan743x_netdev_set_mac_address,
2557};
2558
2559static void lan743x_hardware_cleanup(struct lan743x_adapter *adapter)
2560{
2561 lan743x_csr_write(adapter, INT_EN_CLR, 0xFFFFFFFF);
2562}
2563
2564static void lan743x_mdiobus_cleanup(struct lan743x_adapter *adapter)
2565{
2566 mdiobus_unregister(adapter->mdiobus);
2567}
2568
2569static void lan743x_full_cleanup(struct lan743x_adapter *adapter)
2570{
2571 unregister_netdev(adapter->netdev);
2572
2573 lan743x_mdiobus_cleanup(adapter);
2574 lan743x_hardware_cleanup(adapter);
2575 lan743x_pci_cleanup(adapter);
2576}
2577
2578static int lan743x_hardware_init(struct lan743x_adapter *adapter,
2579 struct pci_dev *pdev)
2580{
2581 struct lan743x_tx *tx;
2582 int index;
2583 int ret;
2584
2585 adapter->intr.irq = adapter->pdev->irq;
2586 lan743x_csr_write(adapter, INT_EN_CLR, 0xFFFFFFFF);
2587 mutex_init(&adapter->dp_lock);
2588 ret = lan743x_mac_init(adapter);
2589 if (ret)
2590 return ret;
2591
2592 ret = lan743x_phy_init(adapter);
2593 if (ret)
2594 return ret;
2595
2596 lan743x_rfe_update_mac_address(adapter);
2597
2598 ret = lan743x_dmac_init(adapter);
2599 if (ret)
2600 return ret;
2601
2602 for (index = 0; index < LAN743X_USED_RX_CHANNELS; index++) {
2603 adapter->rx[index].adapter = adapter;
2604 adapter->rx[index].channel_number = index;
2605 }
2606
2607 tx = &adapter->tx[0];
2608 tx->adapter = adapter;
2609 tx->channel_number = 0;
2610 spin_lock_init(&tx->ring_lock);
2611 return 0;
2612}
2613
2614static int lan743x_mdiobus_init(struct lan743x_adapter *adapter)
2615{
2616 int ret;
2617
2618 adapter->mdiobus = devm_mdiobus_alloc(&adapter->pdev->dev);
2619 if (!(adapter->mdiobus)) {
2620 ret = -ENOMEM;
2621 goto return_error;
2622 }
2623
2624 adapter->mdiobus->priv = (void *)adapter;
2625 adapter->mdiobus->read = lan743x_mdiobus_read;
2626 adapter->mdiobus->write = lan743x_mdiobus_write;
2627 adapter->mdiobus->name = "lan743x-mdiobus";
2628 snprintf(adapter->mdiobus->id, MII_BUS_ID_SIZE,
2629 "pci-%s", pci_name(adapter->pdev));
2630
2631 /* set to internal PHY id */
2632 adapter->mdiobus->phy_mask = ~(u32)BIT(1);
2633
2634 /* register mdiobus */
2635 ret = mdiobus_register(adapter->mdiobus);
2636 if (ret < 0)
2637 goto return_error;
2638 return 0;
2639
2640return_error:
2641 return ret;
2642}
2643
2644/* lan743x_pcidev_probe - Device Initialization Routine
2645 * @pdev: PCI device information struct
2646 * @id: entry in lan743x_pci_tbl
2647 *
2648 * Returns 0 on success, negative on failure
2649 *
2650 * initializes an adapter identified by a pci_dev structure.
2651 * The OS initialization, configuring of the adapter private structure,
2652 * and a hardware reset occur.
2653 **/
2654static int lan743x_pcidev_probe(struct pci_dev *pdev,
2655 const struct pci_device_id *id)
2656{
2657 struct lan743x_adapter *adapter = NULL;
2658 struct net_device *netdev = NULL;
2659 int ret = -ENODEV;
2660
2661 netdev = devm_alloc_etherdev(&pdev->dev,
2662 sizeof(struct lan743x_adapter));
2663 if (!netdev)
2664 goto return_error;
2665
2666 SET_NETDEV_DEV(netdev, &pdev->dev);
2667 pci_set_drvdata(pdev, netdev);
2668 adapter = netdev_priv(netdev);
2669 adapter->netdev = netdev;
2670 adapter->msg_enable = NETIF_MSG_DRV | NETIF_MSG_PROBE |
2671 NETIF_MSG_LINK | NETIF_MSG_IFUP |
2672 NETIF_MSG_IFDOWN | NETIF_MSG_TX_QUEUED;
2673 netdev->max_mtu = LAN743X_MAX_FRAME_SIZE;
2674
2675 ret = lan743x_pci_init(adapter, pdev);
2676 if (ret)
2677 goto return_error;
2678
2679 ret = lan743x_csr_init(adapter);
2680 if (ret)
2681 goto cleanup_pci;
2682
2683 ret = lan743x_hardware_init(adapter, pdev);
2684 if (ret)
2685 goto cleanup_pci;
2686
2687 ret = lan743x_mdiobus_init(adapter);
2688 if (ret)
2689 goto cleanup_hardware;
2690
2691 adapter->netdev->netdev_ops = &lan743x_netdev_ops;
2692 adapter->netdev->features = NETIF_F_SG | NETIF_F_TSO | NETIF_F_HW_CSUM;
2693 adapter->netdev->hw_features = adapter->netdev->features;
2694
2695 /* carrier off reporting is important to ethtool even BEFORE open */
2696 netif_carrier_off(netdev);
2697
2698 ret = register_netdev(adapter->netdev);
2699 if (ret < 0)
2700 goto cleanup_mdiobus;
2701 return 0;
2702
2703cleanup_mdiobus:
2704 lan743x_mdiobus_cleanup(adapter);
2705
2706cleanup_hardware:
2707 lan743x_hardware_cleanup(adapter);
2708
2709cleanup_pci:
2710 lan743x_pci_cleanup(adapter);
2711
2712return_error:
2713 pr_warn("Initialization failed\n");
2714 return ret;
2715}
2716
2717/**
2718 * lan743x_pcidev_remove - Device Removal Routine
2719 * @pdev: PCI device information struct
2720 *
2721 * this is called by the PCI subsystem to alert the driver
2722 * that it should release a PCI device. This could be caused by a
2723 * Hot-Plug event, or because the driver is going to be removed from
2724 * memory.
2725 **/
2726static void lan743x_pcidev_remove(struct pci_dev *pdev)
2727{
2728 struct net_device *netdev = pci_get_drvdata(pdev);
2729 struct lan743x_adapter *adapter = netdev_priv(netdev);
2730
2731 lan743x_full_cleanup(adapter);
2732}
2733
2734static void lan743x_pcidev_shutdown(struct pci_dev *pdev)
2735{
2736 struct net_device *netdev = pci_get_drvdata(pdev);
2737 struct lan743x_adapter *adapter = netdev_priv(netdev);
2738
2739 rtnl_lock();
2740 netif_device_detach(netdev);
2741
2742 /* close netdev when netdev is at running state.
2743 * For instance, it is true when system goes to sleep by pm-suspend
2744 * However, it is false when system goes to sleep by suspend GUI menu
2745 */
2746 if (netif_running(netdev))
2747 lan743x_netdev_close(netdev);
2748 rtnl_unlock();
2749
2750 /* clean up lan743x portion */
2751 lan743x_hardware_cleanup(adapter);
2752}
2753
2754static const struct pci_device_id lan743x_pcidev_tbl[] = {
2755 { PCI_DEVICE(PCI_VENDOR_ID_SMSC, PCI_DEVICE_ID_SMSC_LAN7430) },
2756 { 0, }
2757};
2758
2759static struct pci_driver lan743x_pcidev_driver = {
2760 .name = DRIVER_NAME,
2761 .id_table = lan743x_pcidev_tbl,
2762 .probe = lan743x_pcidev_probe,
2763 .remove = lan743x_pcidev_remove,
2764 .shutdown = lan743x_pcidev_shutdown,
2765};
2766
2767module_pci_driver(lan743x_pcidev_driver);
2768
2769MODULE_AUTHOR(DRIVER_AUTHOR);
2770MODULE_DESCRIPTION(DRIVER_DESC);
2771MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/microchip/lan743x_main.h b/drivers/net/ethernet/microchip/lan743x_main.h
new file mode 100644
index 000000000000..73b463a9df61
--- /dev/null
+++ b/drivers/net/ethernet/microchip/lan743x_main.h
@@ -0,0 +1,597 @@
1/* SPDX-License-Identifier: GPL-2.0+ */
2/* Copyright (C) 2018 Microchip Technology Inc. */
3
4#ifndef _LAN743X_H
5#define _LAN743X_H
6
7#define DRIVER_AUTHOR "Bryan Whitehead <Bryan.Whitehead@microchip.com>"
8#define DRIVER_DESC "LAN743x PCIe Gigabit Ethernet Driver"
9#define DRIVER_NAME "lan743x"
10
11/* Register Definitions */
12#define ID_REV (0x00)
13#define ID_REV_IS_VALID_CHIP_ID_(id_rev) \
14 (((id_rev) & 0xFFF00000) == 0x74300000)
15#define ID_REV_CHIP_REV_MASK_ (0x0000FFFF)
16#define ID_REV_CHIP_REV_A0_ (0x00000000)
17#define ID_REV_CHIP_REV_B0_ (0x00000010)
18
19#define FPGA_REV (0x04)
20#define FPGA_REV_GET_MINOR_(fpga_rev) (((fpga_rev) >> 8) & 0x000000FF)
21#define FPGA_REV_GET_MAJOR_(fpga_rev) ((fpga_rev) & 0x000000FF)
22
23#define HW_CFG (0x010)
24#define HW_CFG_LRST_ BIT(1)
25
26#define PMT_CTL (0x014)
27#define PMT_CTL_READY_ BIT(7)
28#define PMT_CTL_ETH_PHY_RST_ BIT(4)
29
30#define DP_SEL (0x024)
31#define DP_SEL_DPRDY_ BIT(31)
32#define DP_SEL_MASK_ (0x0000001F)
33#define DP_SEL_RFE_RAM (0x00000001)
34
35#define DP_SEL_VHF_HASH_LEN (16)
36#define DP_SEL_VHF_VLAN_LEN (128)
37
38#define DP_CMD (0x028)
39#define DP_CMD_WRITE_ (0x00000001)
40
41#define DP_ADDR (0x02C)
42
43#define DP_DATA_0 (0x030)
44
45#define FCT_RX_CTL (0xAC)
46#define FCT_RX_CTL_EN_(channel) BIT(28 + (channel))
47#define FCT_RX_CTL_DIS_(channel) BIT(24 + (channel))
48#define FCT_RX_CTL_RESET_(channel) BIT(20 + (channel))
49
50#define FCT_TX_CTL (0xC4)
51#define FCT_TX_CTL_EN_(channel) BIT(28 + (channel))
52#define FCT_TX_CTL_DIS_(channel) BIT(24 + (channel))
53#define FCT_TX_CTL_RESET_(channel) BIT(20 + (channel))
54
55#define FCT_FLOW(rx_channel) (0xE0 + ((rx_channel) << 2))
56#define FCT_FLOW_CTL_OFF_THRESHOLD_ (0x00007F00)
57#define FCT_FLOW_CTL_OFF_THRESHOLD_SET_(value) \
58 ((value << 8) & FCT_FLOW_CTL_OFF_THRESHOLD_)
59#define FCT_FLOW_CTL_REQ_EN_ BIT(7)
60#define FCT_FLOW_CTL_ON_THRESHOLD_ (0x0000007F)
61#define FCT_FLOW_CTL_ON_THRESHOLD_SET_(value) \
62 ((value << 0) & FCT_FLOW_CTL_ON_THRESHOLD_)
63
64#define MAC_CR (0x100)
65#define MAC_CR_ADD_ BIT(12)
66#define MAC_CR_ASD_ BIT(11)
67#define MAC_CR_CNTR_RST_ BIT(5)
68#define MAC_CR_RST_ BIT(0)
69
70#define MAC_RX (0x104)
71#define MAC_RX_MAX_SIZE_SHIFT_ (16)
72#define MAC_RX_MAX_SIZE_MASK_ (0x3FFF0000)
73#define MAC_RX_RXD_ BIT(1)
74#define MAC_RX_RXEN_ BIT(0)
75
76#define MAC_TX (0x108)
77#define MAC_TX_TXD_ BIT(1)
78#define MAC_TX_TXEN_ BIT(0)
79
80#define MAC_FLOW (0x10C)
81#define MAC_FLOW_CR_TX_FCEN_ BIT(30)
82#define MAC_FLOW_CR_RX_FCEN_ BIT(29)
83#define MAC_FLOW_CR_FCPT_MASK_ (0x0000FFFF)
84
85#define MAC_RX_ADDRH (0x118)
86
87#define MAC_RX_ADDRL (0x11C)
88
89#define MAC_MII_ACC (0x120)
90#define MAC_MII_ACC_PHY_ADDR_SHIFT_ (11)
91#define MAC_MII_ACC_PHY_ADDR_MASK_ (0x0000F800)
92#define MAC_MII_ACC_MIIRINDA_SHIFT_ (6)
93#define MAC_MII_ACC_MIIRINDA_MASK_ (0x000007C0)
94#define MAC_MII_ACC_MII_READ_ (0x00000000)
95#define MAC_MII_ACC_MII_WRITE_ (0x00000002)
96#define MAC_MII_ACC_MII_BUSY_ BIT(0)
97
98#define MAC_MII_DATA (0x124)
99
100/* offset 0x400 - 0x500, x may range from 0 to 32, for a total of 33 entries */
101#define RFE_ADDR_FILT_HI(x) (0x400 + (8 * (x)))
102#define RFE_ADDR_FILT_HI_VALID_ BIT(31)
103
104/* offset 0x404 - 0x504, x may range from 0 to 32, for a total of 33 entries */
105#define RFE_ADDR_FILT_LO(x) (0x404 + (8 * (x)))
106
107#define RFE_CTL (0x508)
108#define RFE_CTL_AB_ BIT(10)
109#define RFE_CTL_AM_ BIT(9)
110#define RFE_CTL_AU_ BIT(8)
111#define RFE_CTL_MCAST_HASH_ BIT(3)
112#define RFE_CTL_DA_PERFECT_ BIT(1)
113
114#define INT_STS (0x780)
115#define INT_BIT_DMA_RX_(channel) BIT(24 + (channel))
116#define INT_BIT_ALL_RX_ (0x0F000000)
117#define INT_BIT_DMA_TX_(channel) BIT(16 + (channel))
118#define INT_BIT_ALL_TX_ (0x000F0000)
119#define INT_BIT_SW_GP_ BIT(9)
120#define INT_BIT_ALL_OTHER_ (0x00000280)
121#define INT_BIT_MAS_ BIT(0)
122
123#define INT_SET (0x784)
124
125#define INT_EN_SET (0x788)
126
127#define INT_EN_CLR (0x78C)
128
129#define INT_STS_R2C (0x790)
130
131#define INT_VEC_EN_SET (0x794)
132#define INT_VEC_EN_CLR (0x798)
133#define INT_VEC_EN_AUTO_CLR (0x79C)
134#define INT_VEC_EN_(vector_index) BIT(0 + vector_index)
135
136#define INT_VEC_MAP0 (0x7A0)
137#define INT_VEC_MAP0_RX_VEC_(channel, vector) \
138 (((u32)(vector)) << ((channel) << 2))
139
140#define INT_VEC_MAP1 (0x7A4)
141#define INT_VEC_MAP1_TX_VEC_(channel, vector) \
142 (((u32)(vector)) << ((channel) << 2))
143
144#define INT_VEC_MAP2 (0x7A8)
145
146#define INT_MOD_MAP0 (0x7B0)
147
148#define INT_MOD_MAP1 (0x7B4)
149
150#define INT_MOD_MAP2 (0x7B8)
151
152#define INT_MOD_CFG0 (0x7C0)
153#define INT_MOD_CFG1 (0x7C4)
154#define INT_MOD_CFG2 (0x7C8)
155#define INT_MOD_CFG3 (0x7CC)
156#define INT_MOD_CFG4 (0x7D0)
157#define INT_MOD_CFG5 (0x7D4)
158#define INT_MOD_CFG6 (0x7D8)
159#define INT_MOD_CFG7 (0x7DC)
160
161#define DMAC_CFG (0xC00)
162#define DMAC_CFG_COAL_EN_ BIT(16)
163#define DMAC_CFG_CH_ARB_SEL_RX_HIGH_ (0x00000000)
164#define DMAC_CFG_MAX_READ_REQ_MASK_ (0x00000070)
165#define DMAC_CFG_MAX_READ_REQ_SET_(val) \
166 ((((u32)(val)) << 4) & DMAC_CFG_MAX_READ_REQ_MASK_)
167#define DMAC_CFG_MAX_DSPACE_16_ (0x00000000)
168#define DMAC_CFG_MAX_DSPACE_32_ (0x00000001)
169#define DMAC_CFG_MAX_DSPACE_64_ BIT(1)
170#define DMAC_CFG_MAX_DSPACE_128_ (0x00000003)
171
172#define DMAC_COAL_CFG (0xC04)
173#define DMAC_COAL_CFG_TIMER_LIMIT_MASK_ (0xFFF00000)
174#define DMAC_COAL_CFG_TIMER_LIMIT_SET_(val) \
175 ((((u32)(val)) << 20) & DMAC_COAL_CFG_TIMER_LIMIT_MASK_)
176#define DMAC_COAL_CFG_TIMER_TX_START_ BIT(19)
177#define DMAC_COAL_CFG_FLUSH_INTS_ BIT(18)
178#define DMAC_COAL_CFG_INT_EXIT_COAL_ BIT(17)
179#define DMAC_COAL_CFG_CSR_EXIT_COAL_ BIT(16)
180#define DMAC_COAL_CFG_TX_THRES_MASK_ (0x0000FF00)
181#define DMAC_COAL_CFG_TX_THRES_SET_(val) \
182 ((((u32)(val)) << 8) & DMAC_COAL_CFG_TX_THRES_MASK_)
183#define DMAC_COAL_CFG_RX_THRES_MASK_ (0x000000FF)
184#define DMAC_COAL_CFG_RX_THRES_SET_(val) \
185 (((u32)(val)) & DMAC_COAL_CFG_RX_THRES_MASK_)
186
187#define DMAC_OBFF_CFG (0xC08)
188#define DMAC_OBFF_TX_THRES_MASK_ (0x0000FF00)
189#define DMAC_OBFF_TX_THRES_SET_(val) \
190 ((((u32)(val)) << 8) & DMAC_OBFF_TX_THRES_MASK_)
191#define DMAC_OBFF_RX_THRES_MASK_ (0x000000FF)
192#define DMAC_OBFF_RX_THRES_SET_(val) \
193 (((u32)(val)) & DMAC_OBFF_RX_THRES_MASK_)
194
195#define DMAC_CMD (0xC0C)
196#define DMAC_CMD_SWR_ BIT(31)
197#define DMAC_CMD_TX_SWR_(channel) BIT(24 + (channel))
198#define DMAC_CMD_START_T_(channel) BIT(20 + (channel))
199#define DMAC_CMD_STOP_T_(channel) BIT(16 + (channel))
200#define DMAC_CMD_RX_SWR_(channel) BIT(8 + (channel))
201#define DMAC_CMD_START_R_(channel) BIT(4 + (channel))
202#define DMAC_CMD_STOP_R_(channel) BIT(0 + (channel))
203
204#define DMAC_INT_STS (0xC10)
205#define DMAC_INT_EN_SET (0xC14)
206#define DMAC_INT_EN_CLR (0xC18)
207#define DMAC_INT_BIT_RXFRM_(channel) BIT(16 + (channel))
208#define DMAC_INT_BIT_TX_IOC_(channel) BIT(0 + (channel))
209
210#define RX_CFG_A(channel) (0xC40 + ((channel) << 6))
211#define RX_CFG_A_RX_WB_ON_INT_TMR_ BIT(30)
212#define RX_CFG_A_RX_WB_THRES_MASK_ (0x1F000000)
213#define RX_CFG_A_RX_WB_THRES_SET_(val) \
214 ((((u32)(val)) << 24) & RX_CFG_A_RX_WB_THRES_MASK_)
215#define RX_CFG_A_RX_PF_THRES_MASK_ (0x001F0000)
216#define RX_CFG_A_RX_PF_THRES_SET_(val) \
217 ((((u32)(val)) << 16) & RX_CFG_A_RX_PF_THRES_MASK_)
218#define RX_CFG_A_RX_PF_PRI_THRES_MASK_ (0x00001F00)
219#define RX_CFG_A_RX_PF_PRI_THRES_SET_(val) \
220 ((((u32)(val)) << 8) & RX_CFG_A_RX_PF_PRI_THRES_MASK_)
221#define RX_CFG_A_RX_HP_WB_EN_ BIT(5)
222
223#define RX_CFG_B(channel) (0xC44 + ((channel) << 6))
224#define RX_CFG_B_TS_ALL_RX_ BIT(29)
225#define RX_CFG_B_RX_PAD_MASK_ (0x03000000)
226#define RX_CFG_B_RX_PAD_0_ (0x00000000)
227#define RX_CFG_B_RX_PAD_2_ (0x02000000)
228#define RX_CFG_B_RDMABL_512_ (0x00040000)
229#define RX_CFG_B_RX_RING_LEN_MASK_ (0x0000FFFF)
230
231#define RX_BASE_ADDRH(channel) (0xC48 + ((channel) << 6))
232
233#define RX_BASE_ADDRL(channel) (0xC4C + ((channel) << 6))
234
235#define RX_HEAD_WRITEBACK_ADDRH(channel) (0xC50 + ((channel) << 6))
236
237#define RX_HEAD_WRITEBACK_ADDRL(channel) (0xC54 + ((channel) << 6))
238
239#define RX_HEAD(channel) (0xC58 + ((channel) << 6))
240
241#define RX_TAIL(channel) (0xC5C + ((channel) << 6))
242#define RX_TAIL_SET_TOP_INT_EN_ BIT(30)
243#define RX_TAIL_SET_TOP_INT_VEC_EN_ BIT(29)
244
245#define RX_CFG_C(channel) (0xC64 + ((channel) << 6))
246#define RX_CFG_C_RX_TOP_INT_EN_AUTO_CLR_ BIT(6)
247#define RX_CFG_C_RX_INT_EN_R2C_ BIT(4)
248#define RX_CFG_C_RX_DMA_INT_STS_AUTO_CLR_ BIT(3)
249#define RX_CFG_C_RX_INT_STS_R2C_MODE_MASK_ (0x00000007)
250
251#define TX_CFG_A(channel) (0xD40 + ((channel) << 6))
252#define TX_CFG_A_TX_HP_WB_ON_INT_TMR_ BIT(30)
253#define TX_CFG_A_TX_TMR_HPWB_SEL_IOC_ (0x10000000)
254#define TX_CFG_A_TX_PF_THRES_MASK_ (0x001F0000)
255#define TX_CFG_A_TX_PF_THRES_SET_(value) \
256 ((((u32)(value)) << 16) & TX_CFG_A_TX_PF_THRES_MASK_)
257#define TX_CFG_A_TX_PF_PRI_THRES_MASK_ (0x00001F00)
258#define TX_CFG_A_TX_PF_PRI_THRES_SET_(value) \
259 ((((u32)(value)) << 8) & TX_CFG_A_TX_PF_PRI_THRES_MASK_)
260#define TX_CFG_A_TX_HP_WB_EN_ BIT(5)
261#define TX_CFG_A_TX_HP_WB_THRES_MASK_ (0x0000000F)
262#define TX_CFG_A_TX_HP_WB_THRES_SET_(value) \
263 (((u32)(value)) & TX_CFG_A_TX_HP_WB_THRES_MASK_)
264
265#define TX_CFG_B(channel) (0xD44 + ((channel) << 6))
266#define TX_CFG_B_TDMABL_512_ (0x00040000)
267#define TX_CFG_B_TX_RING_LEN_MASK_ (0x0000FFFF)
268
269#define TX_BASE_ADDRH(channel) (0xD48 + ((channel) << 6))
270
271#define TX_BASE_ADDRL(channel) (0xD4C + ((channel) << 6))
272
273#define TX_HEAD_WRITEBACK_ADDRH(channel) (0xD50 + ((channel) << 6))
274
275#define TX_HEAD_WRITEBACK_ADDRL(channel) (0xD54 + ((channel) << 6))
276
277#define TX_HEAD(channel) (0xD58 + ((channel) << 6))
278
279#define TX_TAIL(channel) (0xD5C + ((channel) << 6))
280#define TX_TAIL_SET_DMAC_INT_EN_ BIT(31)
281#define TX_TAIL_SET_TOP_INT_EN_ BIT(30)
282#define TX_TAIL_SET_TOP_INT_VEC_EN_ BIT(29)
283
284#define TX_CFG_C(channel) (0xD64 + ((channel) << 6))
285#define TX_CFG_C_TX_TOP_INT_EN_AUTO_CLR_ BIT(6)
286#define TX_CFG_C_TX_DMA_INT_EN_AUTO_CLR_ BIT(5)
287#define TX_CFG_C_TX_INT_EN_R2C_ BIT(4)
288#define TX_CFG_C_TX_DMA_INT_STS_AUTO_CLR_ BIT(3)
289#define TX_CFG_C_TX_INT_STS_R2C_MODE_MASK_ (0x00000007)
290
291/* MAC statistics registers */
292#define STAT_RX_FCS_ERRORS (0x1200)
293#define STAT_RX_ALIGNMENT_ERRORS (0x1204)
294#define STAT_RX_JABBER_ERRORS (0x120C)
295#define STAT_RX_UNDERSIZE_FRAME_ERRORS (0x1210)
296#define STAT_RX_OVERSIZE_FRAME_ERRORS (0x1214)
297#define STAT_RX_DROPPED_FRAMES (0x1218)
298#define STAT_RX_UNICAST_BYTE_COUNT (0x121C)
299#define STAT_RX_BROADCAST_BYTE_COUNT (0x1220)
300#define STAT_RX_MULTICAST_BYTE_COUNT (0x1224)
301#define STAT_RX_MULTICAST_FRAMES (0x1230)
302#define STAT_RX_TOTAL_FRAMES (0x1254)
303
304#define STAT_TX_FCS_ERRORS (0x1280)
305#define STAT_TX_EXCESS_DEFERRAL_ERRORS (0x1284)
306#define STAT_TX_CARRIER_ERRORS (0x1288)
307#define STAT_TX_SINGLE_COLLISIONS (0x1290)
308#define STAT_TX_MULTIPLE_COLLISIONS (0x1294)
309#define STAT_TX_EXCESSIVE_COLLISION (0x1298)
310#define STAT_TX_LATE_COLLISIONS (0x129C)
311#define STAT_TX_UNICAST_BYTE_COUNT (0x12A0)
312#define STAT_TX_BROADCAST_BYTE_COUNT (0x12A4)
313#define STAT_TX_MULTICAST_BYTE_COUNT (0x12A8)
314#define STAT_TX_MULTICAST_FRAMES (0x12B4)
315#define STAT_TX_TOTAL_FRAMES (0x12D8)
316
317/* End of Register definitions */
318
319#define LAN743X_MAX_RX_CHANNELS (4)
320#define LAN743X_MAX_TX_CHANNELS (1)
321struct lan743x_adapter;
322
323#define LAN743X_USED_RX_CHANNELS (4)
324#define LAN743X_USED_TX_CHANNELS (1)
325#define LAN743X_INT_MOD (400)
326
327#if (LAN743X_USED_RX_CHANNELS > LAN743X_MAX_RX_CHANNELS)
328#error Invalid LAN743X_USED_RX_CHANNELS
329#endif
330#if (LAN743X_USED_TX_CHANNELS > LAN743X_MAX_TX_CHANNELS)
331#error Invalid LAN743X_USED_TX_CHANNELS
332#endif
333
334/* PCI */
335/* SMSC acquired EFAR late 1990's, MCHP acquired SMSC 2012 */
336#define PCI_VENDOR_ID_SMSC PCI_VENDOR_ID_EFAR
337#define PCI_DEVICE_ID_SMSC_LAN7430 (0x7430)
338
339#define PCI_CONFIG_LENGTH (0x1000)
340
341/* CSR */
342#define CSR_LENGTH (0x2000)
343
344#define LAN743X_CSR_FLAG_IS_A0 BIT(0)
345#define LAN743X_CSR_FLAG_IS_B0 BIT(1)
346#define LAN743X_CSR_FLAG_SUPPORTS_INTR_AUTO_SET_CLR BIT(8)
347
348struct lan743x_csr {
349 u32 flags;
350 u8 __iomem *csr_address;
351 u32 id_rev;
352 u32 fpga_rev;
353};
354
355/* INTERRUPTS */
356typedef void(*lan743x_vector_handler)(void *context, u32 int_sts, u32 flags);
357
358#define LAN743X_VECTOR_FLAG_IRQ_SHARED BIT(0)
359#define LAN743X_VECTOR_FLAG_SOURCE_STATUS_READ BIT(1)
360#define LAN743X_VECTOR_FLAG_SOURCE_STATUS_R2C BIT(2)
361#define LAN743X_VECTOR_FLAG_SOURCE_STATUS_W2C BIT(3)
362#define LAN743X_VECTOR_FLAG_SOURCE_ENABLE_CHECK BIT(4)
363#define LAN743X_VECTOR_FLAG_SOURCE_ENABLE_CLEAR BIT(5)
364#define LAN743X_VECTOR_FLAG_SOURCE_ENABLE_R2C BIT(6)
365#define LAN743X_VECTOR_FLAG_MASTER_ENABLE_CLEAR BIT(7)
366#define LAN743X_VECTOR_FLAG_MASTER_ENABLE_SET BIT(8)
367#define LAN743X_VECTOR_FLAG_VECTOR_ENABLE_ISR_CLEAR BIT(9)
368#define LAN743X_VECTOR_FLAG_VECTOR_ENABLE_ISR_SET BIT(10)
369#define LAN743X_VECTOR_FLAG_VECTOR_ENABLE_AUTO_CLEAR BIT(11)
370#define LAN743X_VECTOR_FLAG_VECTOR_ENABLE_AUTO_SET BIT(12)
371#define LAN743X_VECTOR_FLAG_SOURCE_ENABLE_AUTO_CLEAR BIT(13)
372#define LAN743X_VECTOR_FLAG_SOURCE_ENABLE_AUTO_SET BIT(14)
373#define LAN743X_VECTOR_FLAG_SOURCE_STATUS_AUTO_CLEAR BIT(15)
374
375struct lan743x_vector {
376 int irq;
377 u32 flags;
378 struct lan743x_adapter *adapter;
379 int vector_index;
380 u32 int_mask;
381 lan743x_vector_handler handler;
382 void *context;
383};
384
385#define LAN743X_MAX_VECTOR_COUNT (8)
386
387struct lan743x_intr {
388 int flags;
389
390 unsigned int irq;
391
392 struct lan743x_vector vector_list[LAN743X_MAX_VECTOR_COUNT];
393 int number_of_vectors;
394 bool using_vectors;
395
396 int software_isr_flag;
397};
398
399#define LAN743X_MAX_FRAME_SIZE (9 * 1024)
400
401/* PHY */
402struct lan743x_phy {
403 bool fc_autoneg;
404 u8 fc_request_control;
405};
406
407/* TX */
408struct lan743x_tx_descriptor;
409struct lan743x_tx_buffer_info;
410
411#define GPIO_QUEUE_STARTED (0)
412#define GPIO_TX_FUNCTION (1)
413#define GPIO_TX_COMPLETION (2)
414#define GPIO_TX_FRAGMENT (3)
415
416#define TX_FRAME_FLAG_IN_PROGRESS BIT(0)
417
418struct lan743x_tx {
419 struct lan743x_adapter *adapter;
420 u32 vector_flags;
421 int channel_number;
422
423 int ring_size;
424 size_t ring_allocation_size;
425 struct lan743x_tx_descriptor *ring_cpu_ptr;
426 dma_addr_t ring_dma_ptr;
427 /* ring_lock: used to prevent concurrent access to tx ring */
428 spinlock_t ring_lock;
429 u32 frame_flags;
430 u32 frame_first;
431 u32 frame_data0;
432 u32 frame_tail;
433
434 struct lan743x_tx_buffer_info *buffer_info;
435
436 u32 *head_cpu_ptr;
437 dma_addr_t head_dma_ptr;
438 int last_head;
439 int last_tail;
440
441 struct napi_struct napi;
442
443 struct sk_buff *overflow_skb;
444};
445
446/* RX */
447struct lan743x_rx_descriptor;
448struct lan743x_rx_buffer_info;
449
450struct lan743x_rx {
451 struct lan743x_adapter *adapter;
452 u32 vector_flags;
453 int channel_number;
454
455 int ring_size;
456 size_t ring_allocation_size;
457 struct lan743x_rx_descriptor *ring_cpu_ptr;
458 dma_addr_t ring_dma_ptr;
459
460 struct lan743x_rx_buffer_info *buffer_info;
461
462 u32 *head_cpu_ptr;
463 dma_addr_t head_dma_ptr;
464 u32 last_head;
465 u32 last_tail;
466
467 struct napi_struct napi;
468
469 u32 frame_count;
470};
471
472struct lan743x_adapter {
473 struct net_device *netdev;
474 struct mii_bus *mdiobus;
475 int msg_enable;
476 struct pci_dev *pdev;
477 struct lan743x_csr csr;
478 struct lan743x_intr intr;
479
480 /* lock, used to prevent concurrent access to data port */
481 struct mutex dp_lock;
482
483 u8 mac_address[ETH_ALEN];
484
485 struct lan743x_phy phy;
486 struct lan743x_tx tx[LAN743X_MAX_TX_CHANNELS];
487 struct lan743x_rx rx[LAN743X_MAX_RX_CHANNELS];
488};
489
490#define LAN743X_COMPONENT_FLAG_RX(channel) BIT(20 + (channel))
491
492#define INTR_FLAG_IRQ_REQUESTED(vector_index) BIT(0 + vector_index)
493#define INTR_FLAG_MSI_ENABLED BIT(8)
494#define INTR_FLAG_MSIX_ENABLED BIT(9)
495
496#define MAC_MII_READ 1
497#define MAC_MII_WRITE 0
498
499#define PHY_FLAG_OPENED BIT(0)
500#define PHY_FLAG_ATTACHED BIT(1)
501
502#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
503#define DMA_ADDR_HIGH32(dma_addr) ((u32)(((dma_addr) >> 32) & 0xFFFFFFFF))
504#else
505#define DMA_ADDR_HIGH32(dma_addr) ((u32)(0))
506#endif
507#define DMA_ADDR_LOW32(dma_addr) ((u32)((dma_addr) & 0xFFFFFFFF))
508#define DMA_DESCRIPTOR_SPACING_16 (16)
509#define DMA_DESCRIPTOR_SPACING_32 (32)
510#define DMA_DESCRIPTOR_SPACING_64 (64)
511#define DMA_DESCRIPTOR_SPACING_128 (128)
512#define DEFAULT_DMA_DESCRIPTOR_SPACING (L1_CACHE_BYTES)
513
514#define DMAC_CHANNEL_STATE_SET(start_bit, stop_bit) \
515 (((start_bit) ? 2 : 0) | ((stop_bit) ? 1 : 0))
516#define DMAC_CHANNEL_STATE_INITIAL DMAC_CHANNEL_STATE_SET(0, 0)
517#define DMAC_CHANNEL_STATE_STARTED DMAC_CHANNEL_STATE_SET(1, 0)
518#define DMAC_CHANNEL_STATE_STOP_PENDING DMAC_CHANNEL_STATE_SET(1, 1)
519#define DMAC_CHANNEL_STATE_STOPPED DMAC_CHANNEL_STATE_SET(0, 1)
520
521/* TX Descriptor bits */
522#define TX_DESC_DATA0_DTYPE_MASK_ (0xC0000000)
523#define TX_DESC_DATA0_DTYPE_DATA_ (0x00000000)
524#define TX_DESC_DATA0_DTYPE_EXT_ (0x40000000)
525#define TX_DESC_DATA0_FS_ (0x20000000)
526#define TX_DESC_DATA0_LS_ (0x10000000)
527#define TX_DESC_DATA0_EXT_ (0x08000000)
528#define TX_DESC_DATA0_IOC_ (0x04000000)
529#define TX_DESC_DATA0_ICE_ (0x00400000)
530#define TX_DESC_DATA0_IPE_ (0x00200000)
531#define TX_DESC_DATA0_TPE_ (0x00100000)
532#define TX_DESC_DATA0_FCS_ (0x00020000)
533#define TX_DESC_DATA0_BUF_LENGTH_MASK_ (0x0000FFFF)
534#define TX_DESC_DATA0_EXT_LSO_ (0x00200000)
535#define TX_DESC_DATA0_EXT_PAY_LENGTH_MASK_ (0x000FFFFF)
536#define TX_DESC_DATA3_FRAME_LENGTH_MSS_MASK_ (0x3FFF0000)
537
538struct lan743x_tx_descriptor {
539 u32 data0;
540 u32 data1;
541 u32 data2;
542 u32 data3;
543} __aligned(DEFAULT_DMA_DESCRIPTOR_SPACING);
544
545#define TX_BUFFER_INFO_FLAG_ACTIVE BIT(0)
546#define TX_BUFFER_INFO_FLAG_IGNORE_SYNC BIT(2)
547#define TX_BUFFER_INFO_FLAG_SKB_FRAGMENT BIT(3)
548struct lan743x_tx_buffer_info {
549 int flags;
550 struct sk_buff *skb;
551 dma_addr_t dma_ptr;
552 unsigned int buffer_length;
553};
554
555#define LAN743X_TX_RING_SIZE (50)
556
557/* OWN bit is set. ie, Descs are owned by RX DMAC */
558#define RX_DESC_DATA0_OWN_ (0x00008000)
559/* OWN bit is clear. ie, Descs are owned by host */
560#define RX_DESC_DATA0_FS_ (0x80000000)
561#define RX_DESC_DATA0_LS_ (0x40000000)
562#define RX_DESC_DATA0_FRAME_LENGTH_MASK_ (0x3FFF0000)
563#define RX_DESC_DATA0_FRAME_LENGTH_GET_(data0) \
564 (((data0) & RX_DESC_DATA0_FRAME_LENGTH_MASK_) >> 16)
565#define RX_DESC_DATA0_EXT_ (0x00004000)
566#define RX_DESC_DATA0_BUF_LENGTH_MASK_ (0x00003FFF)
567#define RX_DESC_DATA2_TS_NS_MASK_ (0x3FFFFFFF)
568
569#if ((NET_IP_ALIGN != 0) && (NET_IP_ALIGN != 2))
570#error NET_IP_ALIGN must be 0 or 2
571#endif
572
573#define RX_HEAD_PADDING NET_IP_ALIGN
574
575struct lan743x_rx_descriptor {
576 u32 data0;
577 u32 data1;
578 u32 data2;
579 u32 data3;
580} __aligned(DEFAULT_DMA_DESCRIPTOR_SPACING);
581
582#define RX_BUFFER_INFO_FLAG_ACTIVE BIT(0)
583struct lan743x_rx_buffer_info {
584 int flags;
585 struct sk_buff *skb;
586
587 dma_addr_t dma_ptr;
588 unsigned int buffer_length;
589};
590
591#define LAN743X_RX_RING_SIZE (65)
592
593#define RX_PROCESS_RESULT_NOTHING_TO_DO (0)
594#define RX_PROCESS_RESULT_PACKET_RECEIVED (1)
595#define RX_PROCESS_RESULT_PACKET_DROPPED (2)
596
597#endif /* _LAN743X_H */
diff --git a/drivers/net/ethernet/natsemi/jazzsonic.c b/drivers/net/ethernet/natsemi/jazzsonic.c
index d5b28884e21e..51fa82b429a3 100644
--- a/drivers/net/ethernet/natsemi/jazzsonic.c
+++ b/drivers/net/ethernet/natsemi/jazzsonic.c
@@ -60,14 +60,6 @@ do { \
60 *((volatile unsigned int *)dev->base_addr+(reg)) = (val); \ 60 *((volatile unsigned int *)dev->base_addr+(reg)) = (val); \
61} while (0) 61} while (0)
62 62
63
64/* use 0 for production, 1 for verification, >1 for debug */
65#ifdef SONIC_DEBUG
66static unsigned int sonic_debug = SONIC_DEBUG;
67#else
68static unsigned int sonic_debug = 1;
69#endif
70
71/* 63/*
72 * We cannot use station (ethernet) address prefixes to detect the 64 * We cannot use station (ethernet) address prefixes to detect the
73 * sonic controller since these are board manufacturer depended. 65 * sonic controller since these are board manufacturer depended.
@@ -117,7 +109,6 @@ static const struct net_device_ops sonic_netdev_ops = {
117 109
118static int sonic_probe1(struct net_device *dev) 110static int sonic_probe1(struct net_device *dev)
119{ 111{
120 static unsigned version_printed;
121 unsigned int silicon_revision; 112 unsigned int silicon_revision;
122 unsigned int val; 113 unsigned int val;
123 struct sonic_local *lp = netdev_priv(dev); 114 struct sonic_local *lp = netdev_priv(dev);
@@ -133,26 +124,17 @@ static int sonic_probe1(struct net_device *dev)
133 * the expected location. 124 * the expected location.
134 */ 125 */
135 silicon_revision = SONIC_READ(SONIC_SR); 126 silicon_revision = SONIC_READ(SONIC_SR);
136 if (sonic_debug > 1)
137 printk("SONIC Silicon Revision = 0x%04x\n",silicon_revision);
138
139 i = 0; 127 i = 0;
140 while (known_revisions[i] != 0xffff && 128 while (known_revisions[i] != 0xffff &&
141 known_revisions[i] != silicon_revision) 129 known_revisions[i] != silicon_revision)
142 i++; 130 i++;
143 131
144 if (known_revisions[i] == 0xffff) { 132 if (known_revisions[i] == 0xffff) {
145 printk("SONIC ethernet controller not found (0x%4x)\n", 133 pr_info("SONIC ethernet controller not found (0x%4x)\n",
146 silicon_revision); 134 silicon_revision);
147 goto out; 135 goto out;
148 } 136 }
149 137
150 if (sonic_debug && version_printed++ == 0)
151 printk(version);
152
153 printk(KERN_INFO "%s: Sonic ethernet found at 0x%08lx, ",
154 dev_name(lp->device), dev->base_addr);
155
156 /* 138 /*
157 * Put the sonic into software reset, then 139 * Put the sonic into software reset, then
158 * retrieve and print the ethernet address. 140 * retrieve and print the ethernet address.
@@ -245,12 +227,16 @@ static int jazz_sonic_probe(struct platform_device *pdev)
245 err = sonic_probe1(dev); 227 err = sonic_probe1(dev);
246 if (err) 228 if (err)
247 goto out; 229 goto out;
230
231 pr_info("SONIC ethernet @%08lx, MAC %pM, IRQ %d\n",
232 dev->base_addr, dev->dev_addr, dev->irq);
233
234 sonic_msg_init(dev);
235
248 err = register_netdev(dev); 236 err = register_netdev(dev);
249 if (err) 237 if (err)
250 goto out1; 238 goto out1;
251 239
252 printk("%s: MAC %pM IRQ %d\n", dev->name, dev->dev_addr, dev->irq);
253
254 return 0; 240 return 0;
255 241
256out1: 242out1:
@@ -262,8 +248,6 @@ out:
262} 248}
263 249
264MODULE_DESCRIPTION("Jazz SONIC ethernet driver"); 250MODULE_DESCRIPTION("Jazz SONIC ethernet driver");
265module_param(sonic_debug, int, 0);
266MODULE_PARM_DESC(sonic_debug, "jazzsonic debug level (1-4)");
267MODULE_ALIAS("platform:jazzsonic"); 251MODULE_ALIAS("platform:jazzsonic");
268 252
269#include "sonic.c" 253#include "sonic.c"
diff --git a/drivers/net/ethernet/natsemi/macsonic.c b/drivers/net/ethernet/natsemi/macsonic.c
index b922ab5cedea..0937fc2a928e 100644
--- a/drivers/net/ethernet/natsemi/macsonic.c
+++ b/drivers/net/ethernet/natsemi/macsonic.c
@@ -60,8 +60,6 @@
60#include <asm/macints.h> 60#include <asm/macints.h>
61#include <asm/mac_via.h> 61#include <asm/mac_via.h>
62 62
63static char mac_sonic_string[] = "macsonic";
64
65#include "sonic.h" 63#include "sonic.h"
66 64
67/* These should basically be bus-size and endian independent (since 65/* These should basically be bus-size and endian independent (since
@@ -72,15 +70,6 @@ static char mac_sonic_string[] = "macsonic";
72#define SONIC_WRITE(reg,val) (nubus_writew(val, dev->base_addr + (reg * 4) \ 70#define SONIC_WRITE(reg,val) (nubus_writew(val, dev->base_addr + (reg * 4) \
73 + lp->reg_offset)) 71 + lp->reg_offset))
74 72
75/* use 0 for production, 1 for verification, >1 for debug */
76#ifdef SONIC_DEBUG
77static unsigned int sonic_debug = SONIC_DEBUG;
78#else
79static unsigned int sonic_debug = 1;
80#endif
81
82static int sonic_version_printed;
83
84/* For onboard SONIC */ 73/* For onboard SONIC */
85#define ONBOARD_SONIC_REGISTERS 0x50F0A000 74#define ONBOARD_SONIC_REGISTERS 0x50F0A000
86#define ONBOARD_SONIC_PROM_BASE 0x50f08000 75#define ONBOARD_SONIC_PROM_BASE 0x50f08000
@@ -313,11 +302,6 @@ static int mac_onboard_sonic_probe(struct net_device *dev)
313 int sr; 302 int sr;
314 bool commslot = macintosh_config->expansion_type == MAC_EXP_PDS_COMM; 303 bool commslot = macintosh_config->expansion_type == MAC_EXP_PDS_COMM;
315 304
316 if (!MACH_IS_MAC)
317 return -ENODEV;
318
319 printk(KERN_INFO "Checking for internal Macintosh ethernet (SONIC).. ");
320
321 /* Bogus probing, on the models which may or may not have 305 /* Bogus probing, on the models which may or may not have
322 Ethernet (BTW, the Ethernet *is* always at the same 306 Ethernet (BTW, the Ethernet *is* always at the same
323 address, and nothing else lives there, at least if Apple's 307 address, and nothing else lives there, at least if Apple's
@@ -327,13 +311,11 @@ static int mac_onboard_sonic_probe(struct net_device *dev)
327 311
328 card_present = hwreg_present((void*)ONBOARD_SONIC_REGISTERS); 312 card_present = hwreg_present((void*)ONBOARD_SONIC_REGISTERS);
329 if (!card_present) { 313 if (!card_present) {
330 printk("none.\n"); 314 pr_info("Onboard/comm-slot SONIC not found\n");
331 return -ENODEV; 315 return -ENODEV;
332 } 316 }
333 } 317 }
334 318
335 printk("yes\n");
336
337 /* Danger! My arms are flailing wildly! You *must* set lp->reg_offset 319 /* Danger! My arms are flailing wildly! You *must* set lp->reg_offset
338 * and dev->base_addr before using SONIC_READ() or SONIC_WRITE() */ 320 * and dev->base_addr before using SONIC_READ() or SONIC_WRITE() */
339 dev->base_addr = ONBOARD_SONIC_REGISTERS; 321 dev->base_addr = ONBOARD_SONIC_REGISTERS;
@@ -342,18 +324,10 @@ static int mac_onboard_sonic_probe(struct net_device *dev)
342 else 324 else
343 dev->irq = IRQ_NUBUS_9; 325 dev->irq = IRQ_NUBUS_9;
344 326
345 if (!sonic_version_printed) {
346 printk(KERN_INFO "%s", version);
347 sonic_version_printed = 1;
348 }
349 printk(KERN_INFO "%s: onboard / comm-slot SONIC at 0x%08lx\n",
350 dev_name(lp->device), dev->base_addr);
351
352 /* The PowerBook's SONIC is 16 bit always. */ 327 /* The PowerBook's SONIC is 16 bit always. */
353 if (macintosh_config->ident == MAC_MODEL_PB520) { 328 if (macintosh_config->ident == MAC_MODEL_PB520) {
354 lp->reg_offset = 0; 329 lp->reg_offset = 0;
355 lp->dma_bitmode = SONIC_BITMODE16; 330 lp->dma_bitmode = SONIC_BITMODE16;
356 sr = SONIC_READ(SONIC_SR);
357 } else if (commslot) { 331 } else if (commslot) {
358 /* Some of the comm-slot cards are 16 bit. But some 332 /* Some of the comm-slot cards are 16 bit. But some
359 of them are not. The 32-bit cards use offset 2 and 333 of them are not. The 32-bit cards use offset 2 and
@@ -370,22 +344,21 @@ static int mac_onboard_sonic_probe(struct net_device *dev)
370 else { 344 else {
371 lp->dma_bitmode = SONIC_BITMODE16; 345 lp->dma_bitmode = SONIC_BITMODE16;
372 lp->reg_offset = 0; 346 lp->reg_offset = 0;
373 sr = SONIC_READ(SONIC_SR);
374 } 347 }
375 } else { 348 } else {
376 /* All onboard cards are at offset 2 with 32 bit DMA. */ 349 /* All onboard cards are at offset 2 with 32 bit DMA. */
377 lp->reg_offset = 2; 350 lp->reg_offset = 2;
378 lp->dma_bitmode = SONIC_BITMODE32; 351 lp->dma_bitmode = SONIC_BITMODE32;
379 sr = SONIC_READ(SONIC_SR);
380 } 352 }
381 printk(KERN_INFO
382 "%s: revision 0x%04x, using %d bit DMA and register offset %d\n",
383 dev_name(lp->device), sr, lp->dma_bitmode?32:16, lp->reg_offset);
384 353
385#if 0 /* This is sometimes useful to find out how MacOS configured the card. */ 354 pr_info("Onboard/comm-slot SONIC, revision 0x%04x, %d bit DMA, register offset %d\n",
386 printk(KERN_INFO "%s: DCR: 0x%04x, DCR2: 0x%04x\n", dev_name(lp->device), 355 SONIC_READ(SONIC_SR), lp->dma_bitmode ? 32 : 16,
387 SONIC_READ(SONIC_DCR) & 0xffff, SONIC_READ(SONIC_DCR2) & 0xffff); 356 lp->reg_offset);
388#endif 357
358 /* This is sometimes useful to find out how MacOS configured the card */
359 pr_debug("%s: DCR=0x%04x, DCR2=0x%04x\n", __func__,
360 SONIC_READ(SONIC_DCR) & 0xffff,
361 SONIC_READ(SONIC_DCR2) & 0xffff);
389 362
390 /* Software reset, then initialize control registers. */ 363 /* Software reset, then initialize control registers. */
391 SONIC_WRITE(SONIC_CMD, SONIC_CR_RST); 364 SONIC_WRITE(SONIC_CMD, SONIC_CR_RST);
@@ -406,11 +379,14 @@ static int mac_onboard_sonic_probe(struct net_device *dev)
406 /* Now look for the MAC address. */ 379 /* Now look for the MAC address. */
407 mac_onboard_sonic_ethernet_addr(dev); 380 mac_onboard_sonic_ethernet_addr(dev);
408 381
382 pr_info("SONIC ethernet @%08lx, MAC %pM, IRQ %d\n",
383 dev->base_addr, dev->dev_addr, dev->irq);
384
409 /* Shared init code */ 385 /* Shared init code */
410 return macsonic_init(dev); 386 return macsonic_init(dev);
411} 387}
412 388
413static int mac_nubus_sonic_ethernet_addr(struct net_device *dev, 389static int mac_sonic_nubus_ethernet_addr(struct net_device *dev,
414 unsigned long prom_addr, int id) 390 unsigned long prom_addr, int id)
415{ 391{
416 int i; 392 int i;
@@ -449,70 +425,49 @@ static int macsonic_ident(struct nubus_rsrc *fres)
449 return -1; 425 return -1;
450} 426}
451 427
452static int mac_nubus_sonic_probe(struct net_device *dev) 428static int mac_sonic_nubus_probe_board(struct nubus_board *board, int id,
429 struct net_device *dev)
453{ 430{
454 static int slots;
455 struct nubus_rsrc *ndev = NULL;
456 struct sonic_local* lp = netdev_priv(dev); 431 struct sonic_local* lp = netdev_priv(dev);
457 unsigned long base_addr, prom_addr; 432 unsigned long base_addr, prom_addr;
458 u16 sonic_dcr; 433 u16 sonic_dcr;
459 int id = -1;
460 int reg_offset, dma_bitmode; 434 int reg_offset, dma_bitmode;
461 435
462 /* Find the first SONIC that hasn't been initialized already */
463 for_each_func_rsrc(ndev) {
464 if (ndev->category != NUBUS_CAT_NETWORK ||
465 ndev->type != NUBUS_TYPE_ETHERNET)
466 continue;
467
468 /* Have we seen it already? */
469 if (slots & (1<<ndev->board->slot))
470 continue;
471 slots |= 1<<ndev->board->slot;
472
473 /* Is it one of ours? */
474 if ((id = macsonic_ident(ndev)) != -1)
475 break;
476 }
477
478 if (ndev == NULL)
479 return -ENODEV;
480
481 switch (id) { 436 switch (id) {
482 case MACSONIC_DUODOCK: 437 case MACSONIC_DUODOCK:
483 base_addr = ndev->board->slot_addr + DUODOCK_SONIC_REGISTERS; 438 base_addr = board->slot_addr + DUODOCK_SONIC_REGISTERS;
484 prom_addr = ndev->board->slot_addr + DUODOCK_SONIC_PROM_BASE; 439 prom_addr = board->slot_addr + DUODOCK_SONIC_PROM_BASE;
485 sonic_dcr = SONIC_DCR_EXBUS | SONIC_DCR_RFT0 | SONIC_DCR_RFT1 | 440 sonic_dcr = SONIC_DCR_EXBUS | SONIC_DCR_RFT0 | SONIC_DCR_RFT1 |
486 SONIC_DCR_TFT0; 441 SONIC_DCR_TFT0;
487 reg_offset = 2; 442 reg_offset = 2;
488 dma_bitmode = SONIC_BITMODE32; 443 dma_bitmode = SONIC_BITMODE32;
489 break; 444 break;
490 case MACSONIC_APPLE: 445 case MACSONIC_APPLE:
491 base_addr = ndev->board->slot_addr + APPLE_SONIC_REGISTERS; 446 base_addr = board->slot_addr + APPLE_SONIC_REGISTERS;
492 prom_addr = ndev->board->slot_addr + APPLE_SONIC_PROM_BASE; 447 prom_addr = board->slot_addr + APPLE_SONIC_PROM_BASE;
493 sonic_dcr = SONIC_DCR_BMS | SONIC_DCR_RFT1 | SONIC_DCR_TFT0; 448 sonic_dcr = SONIC_DCR_BMS | SONIC_DCR_RFT1 | SONIC_DCR_TFT0;
494 reg_offset = 0; 449 reg_offset = 0;
495 dma_bitmode = SONIC_BITMODE32; 450 dma_bitmode = SONIC_BITMODE32;
496 break; 451 break;
497 case MACSONIC_APPLE16: 452 case MACSONIC_APPLE16:
498 base_addr = ndev->board->slot_addr + APPLE_SONIC_REGISTERS; 453 base_addr = board->slot_addr + APPLE_SONIC_REGISTERS;
499 prom_addr = ndev->board->slot_addr + APPLE_SONIC_PROM_BASE; 454 prom_addr = board->slot_addr + APPLE_SONIC_PROM_BASE;
500 sonic_dcr = SONIC_DCR_EXBUS | SONIC_DCR_RFT1 | SONIC_DCR_TFT0 | 455 sonic_dcr = SONIC_DCR_EXBUS | SONIC_DCR_RFT1 | SONIC_DCR_TFT0 |
501 SONIC_DCR_PO1 | SONIC_DCR_BMS; 456 SONIC_DCR_PO1 | SONIC_DCR_BMS;
502 reg_offset = 0; 457 reg_offset = 0;
503 dma_bitmode = SONIC_BITMODE16; 458 dma_bitmode = SONIC_BITMODE16;
504 break; 459 break;
505 case MACSONIC_DAYNALINK: 460 case MACSONIC_DAYNALINK:
506 base_addr = ndev->board->slot_addr + APPLE_SONIC_REGISTERS; 461 base_addr = board->slot_addr + APPLE_SONIC_REGISTERS;
507 prom_addr = ndev->board->slot_addr + DAYNALINK_PROM_BASE; 462 prom_addr = board->slot_addr + DAYNALINK_PROM_BASE;
508 sonic_dcr = SONIC_DCR_RFT1 | SONIC_DCR_TFT0 | 463 sonic_dcr = SONIC_DCR_RFT1 | SONIC_DCR_TFT0 |
509 SONIC_DCR_PO1 | SONIC_DCR_BMS; 464 SONIC_DCR_PO1 | SONIC_DCR_BMS;
510 reg_offset = 0; 465 reg_offset = 0;
511 dma_bitmode = SONIC_BITMODE16; 466 dma_bitmode = SONIC_BITMODE16;
512 break; 467 break;
513 case MACSONIC_DAYNA: 468 case MACSONIC_DAYNA:
514 base_addr = ndev->board->slot_addr + DAYNA_SONIC_REGISTERS; 469 base_addr = board->slot_addr + DAYNA_SONIC_REGISTERS;
515 prom_addr = ndev->board->slot_addr + DAYNA_SONIC_MAC_ADDR; 470 prom_addr = board->slot_addr + DAYNA_SONIC_MAC_ADDR;
516 sonic_dcr = SONIC_DCR_BMS | 471 sonic_dcr = SONIC_DCR_BMS |
517 SONIC_DCR_RFT1 | SONIC_DCR_TFT0 | SONIC_DCR_PO1; 472 SONIC_DCR_RFT1 | SONIC_DCR_TFT0 | SONIC_DCR_PO1;
518 reg_offset = 0; 473 reg_offset = 0;
@@ -528,21 +483,16 @@ static int mac_nubus_sonic_probe(struct net_device *dev)
528 dev->base_addr = base_addr; 483 dev->base_addr = base_addr;
529 lp->reg_offset = reg_offset; 484 lp->reg_offset = reg_offset;
530 lp->dma_bitmode = dma_bitmode; 485 lp->dma_bitmode = dma_bitmode;
531 dev->irq = SLOT2IRQ(ndev->board->slot); 486 dev->irq = SLOT2IRQ(board->slot);
532 487
533 if (!sonic_version_printed) { 488 dev_info(&board->dev, "%s, revision 0x%04x, %d bit DMA, register offset %d\n",
534 printk(KERN_INFO "%s", version); 489 board->name, SONIC_READ(SONIC_SR),
535 sonic_version_printed = 1; 490 lp->dma_bitmode ? 32 : 16, lp->reg_offset);
536 }
537 printk(KERN_INFO "%s: %s in slot %X\n",
538 dev_name(lp->device), ndev->board->name, ndev->board->slot);
539 printk(KERN_INFO "%s: revision 0x%04x, using %d bit DMA and register offset %d\n",
540 dev_name(lp->device), SONIC_READ(SONIC_SR), dma_bitmode?32:16, reg_offset);
541 491
542#if 0 /* This is sometimes useful to find out how MacOS configured the card. */ 492 /* This is sometimes useful to find out how MacOS configured the card */
543 printk(KERN_INFO "%s: DCR: 0x%04x, DCR2: 0x%04x\n", dev_name(lp->device), 493 dev_dbg(&board->dev, "%s: DCR=0x%04x, DCR2=0x%04x\n", __func__,
544 SONIC_READ(SONIC_DCR) & 0xffff, SONIC_READ(SONIC_DCR2) & 0xffff); 494 SONIC_READ(SONIC_DCR) & 0xffff,
545#endif 495 SONIC_READ(SONIC_DCR2) & 0xffff);
546 496
547 /* Software reset, then initialize control registers. */ 497 /* Software reset, then initialize control registers. */
548 SONIC_WRITE(SONIC_CMD, SONIC_CR_RST); 498 SONIC_WRITE(SONIC_CMD, SONIC_CR_RST);
@@ -557,14 +507,17 @@ static int mac_nubus_sonic_probe(struct net_device *dev)
557 SONIC_WRITE(SONIC_ISR, 0x7fff); 507 SONIC_WRITE(SONIC_ISR, 0x7fff);
558 508
559 /* Now look for the MAC address. */ 509 /* Now look for the MAC address. */
560 if (mac_nubus_sonic_ethernet_addr(dev, prom_addr, id) != 0) 510 if (mac_sonic_nubus_ethernet_addr(dev, prom_addr, id) != 0)
561 return -ENODEV; 511 return -ENODEV;
562 512
513 dev_info(&board->dev, "SONIC ethernet @%08lx, MAC %pM, IRQ %d\n",
514 dev->base_addr, dev->dev_addr, dev->irq);
515
563 /* Shared init code */ 516 /* Shared init code */
564 return macsonic_init(dev); 517 return macsonic_init(dev);
565} 518}
566 519
567static int mac_sonic_probe(struct platform_device *pdev) 520static int mac_sonic_platform_probe(struct platform_device *pdev)
568{ 521{
569 struct net_device *dev; 522 struct net_device *dev;
570 struct sonic_local *lp; 523 struct sonic_local *lp;
@@ -579,22 +532,16 @@ static int mac_sonic_probe(struct platform_device *pdev)
579 SET_NETDEV_DEV(dev, &pdev->dev); 532 SET_NETDEV_DEV(dev, &pdev->dev);
580 platform_set_drvdata(pdev, dev); 533 platform_set_drvdata(pdev, dev);
581 534
582 /* This will catch fatal stuff like -ENOMEM as well as success */
583 err = mac_onboard_sonic_probe(dev); 535 err = mac_onboard_sonic_probe(dev);
584 if (err == 0)
585 goto found;
586 if (err != -ENODEV)
587 goto out;
588 err = mac_nubus_sonic_probe(dev);
589 if (err) 536 if (err)
590 goto out; 537 goto out;
591found: 538
539 sonic_msg_init(dev);
540
592 err = register_netdev(dev); 541 err = register_netdev(dev);
593 if (err) 542 if (err)
594 goto out; 543 goto out;
595 544
596 printk("%s: MAC %pM IRQ %d\n", dev->name, dev->dev_addr, dev->irq);
597
598 return 0; 545 return 0;
599 546
600out: 547out:
@@ -604,13 +551,11 @@ out:
604} 551}
605 552
606MODULE_DESCRIPTION("Macintosh SONIC ethernet driver"); 553MODULE_DESCRIPTION("Macintosh SONIC ethernet driver");
607module_param(sonic_debug, int, 0);
608MODULE_PARM_DESC(sonic_debug, "macsonic debug level (1-4)");
609MODULE_ALIAS("platform:macsonic"); 554MODULE_ALIAS("platform:macsonic");
610 555
611#include "sonic.c" 556#include "sonic.c"
612 557
613static int mac_sonic_device_remove(struct platform_device *pdev) 558static int mac_sonic_platform_remove(struct platform_device *pdev)
614{ 559{
615 struct net_device *dev = platform_get_drvdata(pdev); 560 struct net_device *dev = platform_get_drvdata(pdev);
616 struct sonic_local* lp = netdev_priv(dev); 561 struct sonic_local* lp = netdev_priv(dev);
@@ -623,12 +568,105 @@ static int mac_sonic_device_remove(struct platform_device *pdev)
623 return 0; 568 return 0;
624} 569}
625 570
626static struct platform_driver mac_sonic_driver = { 571static struct platform_driver mac_sonic_platform_driver = {
627 .probe = mac_sonic_probe, 572 .probe = mac_sonic_platform_probe,
628 .remove = mac_sonic_device_remove, 573 .remove = mac_sonic_platform_remove,
629 .driver = { 574 .driver = {
630 .name = mac_sonic_string, 575 .name = "macsonic",
576 },
577};
578
579static int mac_sonic_nubus_probe(struct nubus_board *board)
580{
581 struct net_device *ndev;
582 struct sonic_local *lp;
583 struct nubus_rsrc *fres;
584 int id = -1;
585 int err;
586
587 /* The platform driver will handle a PDS or Comm Slot card (even if
588 * it has a pseudoslot declaration ROM).
589 */
590 if (macintosh_config->expansion_type == MAC_EXP_PDS_COMM)
591 return -ENODEV;
592
593 for_each_board_func_rsrc(board, fres) {
594 if (fres->category != NUBUS_CAT_NETWORK ||
595 fres->type != NUBUS_TYPE_ETHERNET)
596 continue;
597
598 id = macsonic_ident(fres);
599 if (id != -1)
600 break;
601 }
602 if (!fres)
603 return -ENODEV;
604
605 ndev = alloc_etherdev(sizeof(struct sonic_local));
606 if (!ndev)
607 return -ENOMEM;
608
609 lp = netdev_priv(ndev);
610 lp->device = &board->dev;
611 SET_NETDEV_DEV(ndev, &board->dev);
612
613 err = mac_sonic_nubus_probe_board(board, id, ndev);
614 if (err)
615 goto out;
616
617 sonic_msg_init(ndev);
618
619 err = register_netdev(ndev);
620 if (err)
621 goto out;
622
623 nubus_set_drvdata(board, ndev);
624
625 return 0;
626
627out:
628 free_netdev(ndev);
629 return err;
630}
631
632static int mac_sonic_nubus_remove(struct nubus_board *board)
633{
634 struct net_device *ndev = nubus_get_drvdata(board);
635 struct sonic_local *lp = netdev_priv(ndev);
636
637 unregister_netdev(ndev);
638 dma_free_coherent(lp->device,
639 SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode),
640 lp->descriptors, lp->descriptors_laddr);
641 free_netdev(ndev);
642
643 return 0;
644}
645
646static struct nubus_driver mac_sonic_nubus_driver = {
647 .probe = mac_sonic_nubus_probe,
648 .remove = mac_sonic_nubus_remove,
649 .driver = {
650 .name = "macsonic-nubus",
651 .owner = THIS_MODULE,
631 }, 652 },
632}; 653};
633 654
634module_platform_driver(mac_sonic_driver); 655static int perr, nerr;
656
657static int __init mac_sonic_init(void)
658{
659 perr = platform_driver_register(&mac_sonic_platform_driver);
660 nerr = nubus_driver_register(&mac_sonic_nubus_driver);
661 return 0;
662}
663module_init(mac_sonic_init);
664
665static void __exit mac_sonic_exit(void)
666{
667 if (!perr)
668 platform_driver_unregister(&mac_sonic_platform_driver);
669 if (!nerr)
670 nubus_driver_unregister(&mac_sonic_nubus_driver);
671}
672module_exit(mac_sonic_exit);
diff --git a/drivers/net/ethernet/natsemi/sonic.c b/drivers/net/ethernet/natsemi/sonic.c
index 612c7a44b26c..7ed08486ae23 100644
--- a/drivers/net/ethernet/natsemi/sonic.c
+++ b/drivers/net/ethernet/natsemi/sonic.c
@@ -33,7 +33,21 @@
33 * the NetBSD file "sys/arch/mac68k/dev/if_sn.c". 33 * the NetBSD file "sys/arch/mac68k/dev/if_sn.c".
34 */ 34 */
35 35
36static unsigned int version_printed;
36 37
38static int sonic_debug = -1;
39module_param(sonic_debug, int, 0);
40MODULE_PARM_DESC(sonic_debug, "debug message level");
41
42static void sonic_msg_init(struct net_device *dev)
43{
44 struct sonic_local *lp = netdev_priv(dev);
45
46 lp->msg_enable = netif_msg_init(sonic_debug, 0);
47
48 if (version_printed++ == 0)
49 netif_dbg(lp, drv, dev, "%s", version);
50}
37 51
38/* 52/*
39 * Open/initialize the SONIC controller. 53 * Open/initialize the SONIC controller.
@@ -47,8 +61,7 @@ static int sonic_open(struct net_device *dev)
47 struct sonic_local *lp = netdev_priv(dev); 61 struct sonic_local *lp = netdev_priv(dev);
48 int i; 62 int i;
49 63
50 if (sonic_debug > 2) 64 netif_dbg(lp, ifup, dev, "%s: initializing sonic driver\n", __func__);
51 printk("sonic_open: initializing sonic driver.\n");
52 65
53 for (i = 0; i < SONIC_NUM_RRS; i++) { 66 for (i = 0; i < SONIC_NUM_RRS; i++) {
54 struct sk_buff *skb = netdev_alloc_skb(dev, SONIC_RBSIZE + 2); 67 struct sk_buff *skb = netdev_alloc_skb(dev, SONIC_RBSIZE + 2);
@@ -95,8 +108,7 @@ static int sonic_open(struct net_device *dev)
95 108
96 netif_start_queue(dev); 109 netif_start_queue(dev);
97 110
98 if (sonic_debug > 2) 111 netif_dbg(lp, ifup, dev, "%s: Initialization done\n", __func__);
99 printk("sonic_open: Initialization done.\n");
100 112
101 return 0; 113 return 0;
102} 114}
@@ -110,8 +122,7 @@ static int sonic_close(struct net_device *dev)
110 struct sonic_local *lp = netdev_priv(dev); 122 struct sonic_local *lp = netdev_priv(dev);
111 int i; 123 int i;
112 124
113 if (sonic_debug > 2) 125 netif_dbg(lp, ifdown, dev, "%s\n", __func__);
114 printk("sonic_close\n");
115 126
116 netif_stop_queue(dev); 127 netif_stop_queue(dev);
117 128
@@ -205,8 +216,7 @@ static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev)
205 int length; 216 int length;
206 int entry = lp->next_tx; 217 int entry = lp->next_tx;
207 218
208 if (sonic_debug > 2) 219 netif_dbg(lp, tx_queued, dev, "%s: skb=%p\n", __func__, skb);
209 printk("sonic_send_packet: skb=%p, dev=%p\n", skb, dev);
210 220
211 length = skb->len; 221 length = skb->len;
212 if (length < ETH_ZLEN) { 222 if (length < ETH_ZLEN) {
@@ -252,14 +262,12 @@ static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev)
252 lp->next_tx = (entry + 1) & SONIC_TDS_MASK; 262 lp->next_tx = (entry + 1) & SONIC_TDS_MASK;
253 if (lp->tx_skb[lp->next_tx] != NULL) { 263 if (lp->tx_skb[lp->next_tx] != NULL) {
254 /* The ring is full, the ISR has yet to process the next TD. */ 264 /* The ring is full, the ISR has yet to process the next TD. */
255 if (sonic_debug > 3) 265 netif_dbg(lp, tx_queued, dev, "%s: stopping queue\n", __func__);
256 printk("%s: stopping queue\n", dev->name);
257 netif_stop_queue(dev); 266 netif_stop_queue(dev);
258 /* after this packet, wait for ISR to free up some TDAs */ 267 /* after this packet, wait for ISR to free up some TDAs */
259 } else netif_start_queue(dev); 268 } else netif_start_queue(dev);
260 269
261 if (sonic_debug > 2) 270 netif_dbg(lp, tx_queued, dev, "%s: issuing Tx command\n", __func__);
262 printk("sonic_send_packet: issuing Tx command\n");
263 271
264 SONIC_WRITE(SONIC_CMD, SONIC_CR_TXP); 272 SONIC_WRITE(SONIC_CMD, SONIC_CR_TXP);
265 273
@@ -281,8 +289,7 @@ static irqreturn_t sonic_interrupt(int irq, void *dev_id)
281 289
282 do { 290 do {
283 if (status & SONIC_INT_PKTRX) { 291 if (status & SONIC_INT_PKTRX) {
284 if (sonic_debug > 2) 292 netif_dbg(lp, intr, dev, "%s: packet rx\n", __func__);
285 printk("%s: packet rx\n", dev->name);
286 sonic_rx(dev); /* got packet(s) */ 293 sonic_rx(dev); /* got packet(s) */
287 SONIC_WRITE(SONIC_ISR, SONIC_INT_PKTRX); /* clear the interrupt */ 294 SONIC_WRITE(SONIC_ISR, SONIC_INT_PKTRX); /* clear the interrupt */
288 } 295 }
@@ -299,8 +306,7 @@ static irqreturn_t sonic_interrupt(int irq, void *dev_id)
299 * still being allocated by sonic_send_packet (status clear & tx_skb[entry] clear) 306 * still being allocated by sonic_send_packet (status clear & tx_skb[entry] clear)
300 */ 307 */
301 308
302 if (sonic_debug > 2) 309 netif_dbg(lp, intr, dev, "%s: tx done\n", __func__);
303 printk("%s: tx done\n", dev->name);
304 310
305 while (lp->tx_skb[entry] != NULL) { 311 while (lp->tx_skb[entry] != NULL) {
306 if ((td_status = sonic_tda_get(dev, entry, SONIC_TD_STATUS)) == 0) 312 if ((td_status = sonic_tda_get(dev, entry, SONIC_TD_STATUS)) == 0)
@@ -346,20 +352,20 @@ static irqreturn_t sonic_interrupt(int irq, void *dev_id)
346 * check error conditions 352 * check error conditions
347 */ 353 */
348 if (status & SONIC_INT_RFO) { 354 if (status & SONIC_INT_RFO) {
349 if (sonic_debug > 1) 355 netif_dbg(lp, rx_err, dev, "%s: rx fifo overrun\n",
350 printk("%s: rx fifo overrun\n", dev->name); 356 __func__);
351 lp->stats.rx_fifo_errors++; 357 lp->stats.rx_fifo_errors++;
352 SONIC_WRITE(SONIC_ISR, SONIC_INT_RFO); /* clear the interrupt */ 358 SONIC_WRITE(SONIC_ISR, SONIC_INT_RFO); /* clear the interrupt */
353 } 359 }
354 if (status & SONIC_INT_RDE) { 360 if (status & SONIC_INT_RDE) {
355 if (sonic_debug > 1) 361 netif_dbg(lp, rx_err, dev, "%s: rx descriptors exhausted\n",
356 printk("%s: rx descriptors exhausted\n", dev->name); 362 __func__);
357 lp->stats.rx_dropped++; 363 lp->stats.rx_dropped++;
358 SONIC_WRITE(SONIC_ISR, SONIC_INT_RDE); /* clear the interrupt */ 364 SONIC_WRITE(SONIC_ISR, SONIC_INT_RDE); /* clear the interrupt */
359 } 365 }
360 if (status & SONIC_INT_RBAE) { 366 if (status & SONIC_INT_RBAE) {
361 if (sonic_debug > 1) 367 netif_dbg(lp, rx_err, dev, "%s: rx buffer area exceeded\n",
362 printk("%s: rx buffer area exceeded\n", dev->name); 368 __func__);
363 lp->stats.rx_dropped++; 369 lp->stats.rx_dropped++;
364 SONIC_WRITE(SONIC_ISR, SONIC_INT_RBAE); /* clear the interrupt */ 370 SONIC_WRITE(SONIC_ISR, SONIC_INT_RBAE); /* clear the interrupt */
365 } 371 }
@@ -380,8 +386,9 @@ static irqreturn_t sonic_interrupt(int irq, void *dev_id)
380 386
381 /* transmit error */ 387 /* transmit error */
382 if (status & SONIC_INT_TXER) { 388 if (status & SONIC_INT_TXER) {
383 if ((SONIC_READ(SONIC_TCR) & SONIC_TCR_FU) && (sonic_debug > 2)) 389 if (SONIC_READ(SONIC_TCR) & SONIC_TCR_FU)
384 printk(KERN_ERR "%s: tx fifo underrun\n", dev->name); 390 netif_dbg(lp, tx_err, dev, "%s: tx fifo underrun\n",
391 __func__);
385 SONIC_WRITE(SONIC_ISR, SONIC_INT_TXER); /* clear the interrupt */ 392 SONIC_WRITE(SONIC_ISR, SONIC_INT_TXER); /* clear the interrupt */
386 } 393 }
387 394
@@ -475,8 +482,8 @@ static void sonic_rx(struct net_device *dev)
475 if (lp->cur_rwp >= lp->rra_end) lp->cur_rwp = lp->rra_laddr & 0xffff; 482 if (lp->cur_rwp >= lp->rra_end) lp->cur_rwp = lp->rra_laddr & 0xffff;
476 SONIC_WRITE(SONIC_RWP, lp->cur_rwp); 483 SONIC_WRITE(SONIC_RWP, lp->cur_rwp);
477 if (SONIC_READ(SONIC_ISR) & SONIC_INT_RBE) { 484 if (SONIC_READ(SONIC_ISR) & SONIC_INT_RBE) {
478 if (sonic_debug > 2) 485 netif_dbg(lp, rx_err, dev, "%s: rx buffer exhausted\n",
479 printk("%s: rx buffer exhausted\n", dev->name); 486 __func__);
480 SONIC_WRITE(SONIC_ISR, SONIC_INT_RBE); /* clear the flag */ 487 SONIC_WRITE(SONIC_ISR, SONIC_INT_RBE); /* clear the flag */
481 } 488 }
482 } else 489 } else
@@ -542,9 +549,8 @@ static void sonic_multicast_list(struct net_device *dev)
542 (netdev_mc_count(dev) > 15)) { 549 (netdev_mc_count(dev) > 15)) {
543 rcr |= SONIC_RCR_AMC; 550 rcr |= SONIC_RCR_AMC;
544 } else { 551 } else {
545 if (sonic_debug > 2) 552 netif_dbg(lp, ifup, dev, "%s: mc_count %d\n", __func__,
546 printk("sonic_multicast_list: mc_count %d\n", 553 netdev_mc_count(dev));
547 netdev_mc_count(dev));
548 sonic_set_cam_enable(dev, 1); /* always enable our own address */ 554 sonic_set_cam_enable(dev, 1); /* always enable our own address */
549 i = 1; 555 i = 1;
550 netdev_for_each_mc_addr(ha, dev) { 556 netdev_for_each_mc_addr(ha, dev) {
@@ -562,8 +568,7 @@ static void sonic_multicast_list(struct net_device *dev)
562 } 568 }
563 } 569 }
564 570
565 if (sonic_debug > 2) 571 netif_dbg(lp, ifup, dev, "%s: setting RCR=%x\n", __func__, rcr);
566 printk("sonic_multicast_list: setting RCR=%x\n", rcr);
567 572
568 SONIC_WRITE(SONIC_RCR, rcr); 573 SONIC_WRITE(SONIC_RCR, rcr);
569} 574}
@@ -596,8 +601,8 @@ static int sonic_init(struct net_device *dev)
596 /* 601 /*
597 * initialize the receive resource area 602 * initialize the receive resource area
598 */ 603 */
599 if (sonic_debug > 2) 604 netif_dbg(lp, ifup, dev, "%s: initialize receive resource area\n",
600 printk("sonic_init: initialize receive resource area\n"); 605 __func__);
601 606
602 for (i = 0; i < SONIC_NUM_RRS; i++) { 607 for (i = 0; i < SONIC_NUM_RRS; i++) {
603 u16 bufadr_l = (unsigned long)lp->rx_laddr[i] & 0xffff; 608 u16 bufadr_l = (unsigned long)lp->rx_laddr[i] & 0xffff;
@@ -622,8 +627,7 @@ static int sonic_init(struct net_device *dev)
622 SONIC_WRITE(SONIC_EOBC, (SONIC_RBSIZE >> 1) - (lp->dma_bitmode ? 2 : 1)); 627 SONIC_WRITE(SONIC_EOBC, (SONIC_RBSIZE >> 1) - (lp->dma_bitmode ? 2 : 1));
623 628
624 /* load the resource pointers */ 629 /* load the resource pointers */
625 if (sonic_debug > 3) 630 netif_dbg(lp, ifup, dev, "%s: issuing RRRA command\n", __func__);
626 printk("sonic_init: issuing RRRA command\n");
627 631
628 SONIC_WRITE(SONIC_CMD, SONIC_CR_RRRA); 632 SONIC_WRITE(SONIC_CMD, SONIC_CR_RRRA);
629 i = 0; 633 i = 0;
@@ -632,16 +636,17 @@ static int sonic_init(struct net_device *dev)
632 break; 636 break;
633 } 637 }
634 638
635 if (sonic_debug > 2) 639 netif_dbg(lp, ifup, dev, "%s: status=%x, i=%d\n", __func__,
636 printk("sonic_init: status=%x i=%d\n", SONIC_READ(SONIC_CMD), i); 640 SONIC_READ(SONIC_CMD), i);
637 641
638 /* 642 /*
639 * Initialize the receive descriptors so that they 643 * Initialize the receive descriptors so that they
640 * become a circular linked list, ie. let the last 644 * become a circular linked list, ie. let the last
641 * descriptor point to the first again. 645 * descriptor point to the first again.
642 */ 646 */
643 if (sonic_debug > 2) 647 netif_dbg(lp, ifup, dev, "%s: initialize receive descriptors\n",
644 printk("sonic_init: initialize receive descriptors\n"); 648 __func__);
649
645 for (i=0; i<SONIC_NUM_RDS; i++) { 650 for (i=0; i<SONIC_NUM_RDS; i++) {
646 sonic_rda_put(dev, i, SONIC_RD_STATUS, 0); 651 sonic_rda_put(dev, i, SONIC_RD_STATUS, 0);
647 sonic_rda_put(dev, i, SONIC_RD_PKTLEN, 0); 652 sonic_rda_put(dev, i, SONIC_RD_PKTLEN, 0);
@@ -664,8 +669,9 @@ static int sonic_init(struct net_device *dev)
664 /* 669 /*
665 * initialize transmit descriptors 670 * initialize transmit descriptors
666 */ 671 */
667 if (sonic_debug > 2) 672 netif_dbg(lp, ifup, dev, "%s: initialize transmit descriptors\n",
668 printk("sonic_init: initialize transmit descriptors\n"); 673 __func__);
674
669 for (i = 0; i < SONIC_NUM_TDS; i++) { 675 for (i = 0; i < SONIC_NUM_TDS; i++) {
670 sonic_tda_put(dev, i, SONIC_TD_STATUS, 0); 676 sonic_tda_put(dev, i, SONIC_TD_STATUS, 0);
671 sonic_tda_put(dev, i, SONIC_TD_CONFIG, 0); 677 sonic_tda_put(dev, i, SONIC_TD_CONFIG, 0);
@@ -712,10 +718,8 @@ static int sonic_init(struct net_device *dev)
712 if (SONIC_READ(SONIC_ISR) & SONIC_INT_LCD) 718 if (SONIC_READ(SONIC_ISR) & SONIC_INT_LCD)
713 break; 719 break;
714 } 720 }
715 if (sonic_debug > 2) { 721 netif_dbg(lp, ifup, dev, "%s: CMD=%x, ISR=%x, i=%d\n", __func__,
716 printk("sonic_init: CMD=%x, ISR=%x\n, i=%d", 722 SONIC_READ(SONIC_CMD), SONIC_READ(SONIC_ISR), i);
717 SONIC_READ(SONIC_CMD), SONIC_READ(SONIC_ISR), i);
718 }
719 723
720 /* 724 /*
721 * enable receiver, disable loopback 725 * enable receiver, disable loopback
@@ -731,9 +735,8 @@ static int sonic_init(struct net_device *dev)
731 if ((cmd & SONIC_CR_RXEN) == 0 || (cmd & SONIC_CR_STP) == 0) 735 if ((cmd & SONIC_CR_RXEN) == 0 || (cmd & SONIC_CR_STP) == 0)
732 printk(KERN_ERR "sonic_init: failed, status=%x\n", cmd); 736 printk(KERN_ERR "sonic_init: failed, status=%x\n", cmd);
733 737
734 if (sonic_debug > 2) 738 netif_dbg(lp, ifup, dev, "%s: new status=%x\n", __func__,
735 printk("sonic_init: new status=%x\n", 739 SONIC_READ(SONIC_CMD));
736 SONIC_READ(SONIC_CMD));
737 740
738 return 0; 741 return 0;
739} 742}
diff --git a/drivers/net/ethernet/natsemi/sonic.h b/drivers/net/ethernet/natsemi/sonic.h
index 421b1a283fed..2b27f7049acb 100644
--- a/drivers/net/ethernet/natsemi/sonic.h
+++ b/drivers/net/ethernet/natsemi/sonic.h
@@ -319,6 +319,7 @@ struct sonic_local {
319 unsigned int eol_rx; 319 unsigned int eol_rx;
320 unsigned int eol_tx; /* last unacked transmit packet */ 320 unsigned int eol_tx; /* last unacked transmit packet */
321 unsigned int next_tx; /* next free TD */ 321 unsigned int next_tx; /* next free TD */
322 int msg_enable;
322 struct device *device; /* generic device */ 323 struct device *device; /* generic device */
323 struct net_device_stats stats; 324 struct net_device_stats stats;
324}; 325};
@@ -336,6 +337,7 @@ static struct net_device_stats *sonic_get_stats(struct net_device *dev);
336static void sonic_multicast_list(struct net_device *dev); 337static void sonic_multicast_list(struct net_device *dev);
337static int sonic_init(struct net_device *dev); 338static int sonic_init(struct net_device *dev);
338static void sonic_tx_timeout(struct net_device *dev); 339static void sonic_tx_timeout(struct net_device *dev);
340static void sonic_msg_init(struct net_device *dev);
339 341
340/* Internal inlines for reading/writing DMA buffers. Note that bus 342/* Internal inlines for reading/writing DMA buffers. Note that bus
341 size and endianness matter here, whereas they don't for registers, 343 size and endianness matter here, whereas they don't for registers,
diff --git a/drivers/net/ethernet/natsemi/xtsonic.c b/drivers/net/ethernet/natsemi/xtsonic.c
index 1817deea98a4..e1b886e87a76 100644
--- a/drivers/net/ethernet/natsemi/xtsonic.c
+++ b/drivers/net/ethernet/natsemi/xtsonic.c
@@ -73,14 +73,6 @@ extern void xtboard_get_ether_addr(unsigned char *buf);
73#define SONIC_WRITE(reg,val) \ 73#define SONIC_WRITE(reg,val) \
74 *((volatile unsigned int *)dev->base_addr+reg) = val 74 *((volatile unsigned int *)dev->base_addr+reg) = val
75 75
76
77/* Use 0 for production, 1 for verification, and >2 for debug */
78#ifdef SONIC_DEBUG
79static unsigned int sonic_debug = SONIC_DEBUG;
80#else
81static unsigned int sonic_debug = 1;
82#endif
83
84/* 76/*
85 * We cannot use station (ethernet) address prefixes to detect the 77 * We cannot use station (ethernet) address prefixes to detect the
86 * sonic controller since these are board manufacturer depended. 78 * sonic controller since these are board manufacturer depended.
@@ -130,7 +122,6 @@ static const struct net_device_ops xtsonic_netdev_ops = {
130 122
131static int __init sonic_probe1(struct net_device *dev) 123static int __init sonic_probe1(struct net_device *dev)
132{ 124{
133 static unsigned version_printed = 0;
134 unsigned int silicon_revision; 125 unsigned int silicon_revision;
135 struct sonic_local *lp = netdev_priv(dev); 126 struct sonic_local *lp = netdev_priv(dev);
136 unsigned int base_addr = dev->base_addr; 127 unsigned int base_addr = dev->base_addr;
@@ -146,23 +137,17 @@ static int __init sonic_probe1(struct net_device *dev)
146 * the expected location. 137 * the expected location.
147 */ 138 */
148 silicon_revision = SONIC_READ(SONIC_SR); 139 silicon_revision = SONIC_READ(SONIC_SR);
149 if (sonic_debug > 1)
150 printk("SONIC Silicon Revision = 0x%04x\n",silicon_revision);
151
152 i = 0; 140 i = 0;
153 while ((known_revisions[i] != 0xffff) && 141 while ((known_revisions[i] != 0xffff) &&
154 (known_revisions[i] != silicon_revision)) 142 (known_revisions[i] != silicon_revision))
155 i++; 143 i++;
156 144
157 if (known_revisions[i] == 0xffff) { 145 if (known_revisions[i] == 0xffff) {
158 printk("SONIC ethernet controller not found (0x%4x)\n", 146 pr_info("SONIC ethernet controller not found (0x%4x)\n",
159 silicon_revision); 147 silicon_revision);
160 return -ENODEV; 148 return -ENODEV;
161 } 149 }
162 150
163 if (sonic_debug && version_printed++ == 0)
164 printk(version);
165
166 /* 151 /*
167 * Put the sonic into software reset, then retrieve ethernet address. 152 * Put the sonic into software reset, then retrieve ethernet address.
168 * Note: we are assuming that the boot-loader has initialized the cam. 153 * Note: we are assuming that the boot-loader has initialized the cam.
@@ -273,12 +258,15 @@ int xtsonic_probe(struct platform_device *pdev)
273 258
274 if ((err = sonic_probe1(dev))) 259 if ((err = sonic_probe1(dev)))
275 goto out; 260 goto out;
261
262 pr_info("SONIC ethernet @%08lx, MAC %pM, IRQ %d\n",
263 dev->base_addr, dev->dev_addr, dev->irq);
264
265 sonic_msg_init(dev);
266
276 if ((err = register_netdev(dev))) 267 if ((err = register_netdev(dev)))
277 goto out1; 268 goto out1;
278 269
279 printk("%s: SONIC ethernet @%08lx, MAC %pM, IRQ %d\n", dev->name,
280 dev->base_addr, dev->dev_addr, dev->irq);
281
282 return 0; 270 return 0;
283 271
284out1: 272out1:
@@ -290,8 +278,6 @@ out:
290} 278}
291 279
292MODULE_DESCRIPTION("Xtensa XT2000 SONIC ethernet driver"); 280MODULE_DESCRIPTION("Xtensa XT2000 SONIC ethernet driver");
293module_param(sonic_debug, int, 0);
294MODULE_PARM_DESC(sonic_debug, "xtsonic debug level (1-4)");
295 281
296#include "sonic.c" 282#include "sonic.c"
297 283
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/Makefile b/drivers/net/ethernet/netronome/nfp/bpf/Makefile
new file mode 100644
index 000000000000..805fa28f391a
--- /dev/null
+++ b/drivers/net/ethernet/netronome/nfp/bpf/Makefile
@@ -0,0 +1,2 @@
1# SPDX-License-Identifier: GPL-2.0
2# kbuild requires Makefile in a directory to build individual objects
diff --git a/drivers/net/ethernet/netronome/nfp/flower/Makefile b/drivers/net/ethernet/netronome/nfp/flower/Makefile
new file mode 100644
index 000000000000..805fa28f391a
--- /dev/null
+++ b/drivers/net/ethernet/netronome/nfp/flower/Makefile
@@ -0,0 +1,2 @@
1# SPDX-License-Identifier: GPL-2.0
2# kbuild requires Makefile in a directory to build individual objects
diff --git a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h
index adfe474c2cf0..28c1cd5b823b 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h
+++ b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h
@@ -61,6 +61,13 @@
61#define NFP_FLOWER_MASK_MPLS_BOS BIT(8) 61#define NFP_FLOWER_MASK_MPLS_BOS BIT(8)
62#define NFP_FLOWER_MASK_MPLS_Q BIT(0) 62#define NFP_FLOWER_MASK_MPLS_Q BIT(0)
63 63
64/* Compressed HW representation of TCP Flags */
65#define NFP_FL_TCP_FLAG_URG BIT(4)
66#define NFP_FL_TCP_FLAG_PSH BIT(3)
67#define NFP_FL_TCP_FLAG_RST BIT(2)
68#define NFP_FL_TCP_FLAG_SYN BIT(1)
69#define NFP_FL_TCP_FLAG_FIN BIT(0)
70
64#define NFP_FL_SC_ACT_DROP 0x80000000 71#define NFP_FL_SC_ACT_DROP 0x80000000
65#define NFP_FL_SC_ACT_USER 0x7D000000 72#define NFP_FL_SC_ACT_USER 0x7D000000
66#define NFP_FL_SC_ACT_POPV 0x6A000000 73#define NFP_FL_SC_ACT_POPV 0x6A000000
@@ -257,7 +264,7 @@ struct nfp_flower_tp_ports {
257 * 3 2 1 264 * 3 2 1
258 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 265 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
259 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 266 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
260 * | DSCP |ECN| protocol | reserved | 267 * | DSCP |ECN| protocol | ttl | flags |
261 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 268 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
262 * | ipv4_addr_src | 269 * | ipv4_addr_src |
263 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 270 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -268,7 +275,7 @@ struct nfp_flower_ipv4 {
268 u8 tos; 275 u8 tos;
269 u8 proto; 276 u8 proto;
270 u8 ttl; 277 u8 ttl;
271 u8 reserved; 278 u8 flags;
272 __be32 ipv4_src; 279 __be32 ipv4_src;
273 __be32 ipv4_dst; 280 __be32 ipv4_dst;
274}; 281};
diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.h b/drivers/net/ethernet/netronome/nfp/flower/main.h
index 332ff0fdc038..c5cebf6fb1d3 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/main.h
+++ b/drivers/net/ethernet/netronome/nfp/flower/main.h
@@ -41,6 +41,7 @@
41#include <linux/time64.h> 41#include <linux/time64.h>
42#include <linux/types.h> 42#include <linux/types.h>
43#include <net/pkt_cls.h> 43#include <net/pkt_cls.h>
44#include <net/tcp.h>
44#include <linux/workqueue.h> 45#include <linux/workqueue.h>
45 46
46struct net_device; 47struct net_device;
diff --git a/drivers/net/ethernet/netronome/nfp/flower/match.c b/drivers/net/ethernet/netronome/nfp/flower/match.c
index 37c2ecae2a7a..b3bc8279d4fb 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/match.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/match.c
@@ -181,6 +181,26 @@ nfp_flower_compile_ipv4(struct nfp_flower_ipv4 *frame,
181 frame->tos = flow_ip->tos; 181 frame->tos = flow_ip->tos;
182 frame->ttl = flow_ip->ttl; 182 frame->ttl = flow_ip->ttl;
183 } 183 }
184
185 if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_TCP)) {
186 struct flow_dissector_key_tcp *tcp;
187 u32 tcp_flags;
188
189 tcp = skb_flow_dissector_target(flow->dissector,
190 FLOW_DISSECTOR_KEY_TCP, target);
191 tcp_flags = be16_to_cpu(tcp->flags);
192
193 if (tcp_flags & TCPHDR_FIN)
194 frame->flags |= NFP_FL_TCP_FLAG_FIN;
195 if (tcp_flags & TCPHDR_SYN)
196 frame->flags |= NFP_FL_TCP_FLAG_SYN;
197 if (tcp_flags & TCPHDR_RST)
198 frame->flags |= NFP_FL_TCP_FLAG_RST;
199 if (tcp_flags & TCPHDR_PSH)
200 frame->flags |= NFP_FL_TCP_FLAG_PSH;
201 if (tcp_flags & TCPHDR_URG)
202 frame->flags |= NFP_FL_TCP_FLAG_URG;
203 }
184} 204}
185 205
186static void 206static void
diff --git a/drivers/net/ethernet/netronome/nfp/flower/offload.c b/drivers/net/ethernet/netronome/nfp/flower/offload.c
index eb5c13dea8f5..f3586c519805 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/offload.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/offload.c
@@ -44,11 +44,16 @@
44#include "../nfp_net.h" 44#include "../nfp_net.h"
45#include "../nfp_port.h" 45#include "../nfp_port.h"
46 46
47#define NFP_FLOWER_SUPPORTED_TCPFLAGS \
48 (TCPHDR_FIN | TCPHDR_SYN | TCPHDR_RST | \
49 TCPHDR_PSH | TCPHDR_URG)
50
47#define NFP_FLOWER_WHITELIST_DISSECTOR \ 51#define NFP_FLOWER_WHITELIST_DISSECTOR \
48 (BIT(FLOW_DISSECTOR_KEY_CONTROL) | \ 52 (BIT(FLOW_DISSECTOR_KEY_CONTROL) | \
49 BIT(FLOW_DISSECTOR_KEY_BASIC) | \ 53 BIT(FLOW_DISSECTOR_KEY_BASIC) | \
50 BIT(FLOW_DISSECTOR_KEY_IPV4_ADDRS) | \ 54 BIT(FLOW_DISSECTOR_KEY_IPV4_ADDRS) | \
51 BIT(FLOW_DISSECTOR_KEY_IPV6_ADDRS) | \ 55 BIT(FLOW_DISSECTOR_KEY_IPV6_ADDRS) | \
56 BIT(FLOW_DISSECTOR_KEY_TCP) | \
52 BIT(FLOW_DISSECTOR_KEY_PORTS) | \ 57 BIT(FLOW_DISSECTOR_KEY_PORTS) | \
53 BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS) | \ 58 BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS) | \
54 BIT(FLOW_DISSECTOR_KEY_VLAN) | \ 59 BIT(FLOW_DISSECTOR_KEY_VLAN) | \
@@ -288,6 +293,35 @@ nfp_flower_calculate_key_layers(struct nfp_app *app,
288 } 293 }
289 } 294 }
290 295
296 if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_TCP)) {
297 struct flow_dissector_key_tcp *tcp;
298 u32 tcp_flags;
299
300 tcp = skb_flow_dissector_target(flow->dissector,
301 FLOW_DISSECTOR_KEY_TCP,
302 flow->key);
303 tcp_flags = be16_to_cpu(tcp->flags);
304
305 if (tcp_flags & ~NFP_FLOWER_SUPPORTED_TCPFLAGS)
306 return -EOPNOTSUPP;
307
308 /* We only support PSH and URG flags when either
309 * FIN, SYN or RST is present as well.
310 */
311 if ((tcp_flags & (TCPHDR_PSH | TCPHDR_URG)) &&
312 !(tcp_flags & (TCPHDR_FIN | TCPHDR_SYN | TCPHDR_RST)))
313 return -EOPNOTSUPP;
314
315 /* We need to store TCP flags in the IPv4 key space, thus
316 * we need to ensure we include a IPv4 key layer if we have
317 * not done so already.
318 */
319 if (!(key_layer & NFP_FLOWER_LAYER_IPV4)) {
320 key_layer |= NFP_FLOWER_LAYER_IPV4;
321 key_size += sizeof(struct nfp_flower_ipv4);
322 }
323 }
324
291 ret_key_ls->key_layer = key_layer; 325 ret_key_ls->key_layer = key_layer;
292 ret_key_ls->key_layer_two = key_layer_two; 326 ret_key_ls->key_layer_two = key_layer_two;
293 ret_key_ls->key_size = key_size; 327 ret_key_ls->key_size = key_size;
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_main.c b/drivers/net/ethernet/netronome/nfp/nfp_main.c
index ab301d56430b..c4b1f344b4da 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_main.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_main.c
@@ -645,6 +645,7 @@ MODULE_FIRMWARE("netronome/nic_AMDA0097-0001_4x10_1x40.nffw");
645MODULE_FIRMWARE("netronome/nic_AMDA0097-0001_8x10.nffw"); 645MODULE_FIRMWARE("netronome/nic_AMDA0097-0001_8x10.nffw");
646MODULE_FIRMWARE("netronome/nic_AMDA0099-0001_2x10.nffw"); 646MODULE_FIRMWARE("netronome/nic_AMDA0099-0001_2x10.nffw");
647MODULE_FIRMWARE("netronome/nic_AMDA0099-0001_2x25.nffw"); 647MODULE_FIRMWARE("netronome/nic_AMDA0099-0001_2x25.nffw");
648MODULE_FIRMWARE("netronome/nic_AMDA0099-0001_1x10_1x25.nffw");
648 649
649MODULE_AUTHOR("Netronome Systems <oss-drivers@netronome.com>"); 650MODULE_AUTHOR("Netronome Systems <oss-drivers@netronome.com>");
650MODULE_LICENSE("GPL"); 651MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h b/drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h
index 4499a7333078..bb63c115537d 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2015-2017 Netronome Systems, Inc. 2 * Copyright (C) 2015-2018 Netronome Systems, Inc.
3 * 3 *
4 * This software is dual licensed under the GNU General License Version 2, 4 * This software is dual licensed under the GNU General License Version 2,
5 * June 1991 as shown in the file COPYING in the top-level directory of this 5 * June 1991 as shown in the file COPYING in the top-level directory of this
@@ -51,12 +51,12 @@
51 * The configuration BAR is 8K in size, but due to 51 * The configuration BAR is 8K in size, but due to
52 * THB-350, 32k needs to be reserved. 52 * THB-350, 32k needs to be reserved.
53 */ 53 */
54#define NFP_NET_CFG_BAR_SZ (32 * 1024) 54#define NFP_NET_CFG_BAR_SZ (32 * 1024)
55 55
56/** 56/**
57 * Offset in Freelist buffer where packet starts on RX 57 * Offset in Freelist buffer where packet starts on RX
58 */ 58 */
59#define NFP_NET_RX_OFFSET 32 59#define NFP_NET_RX_OFFSET 32
60 60
61/** 61/**
62 * LSO parameters 62 * LSO parameters
@@ -75,65 +75,65 @@
75#define NFP_NET_META_PORTID 5 75#define NFP_NET_META_PORTID 5
76#define NFP_NET_META_CSUM 6 /* checksum complete type */ 76#define NFP_NET_META_CSUM 6 /* checksum complete type */
77 77
78#define NFP_META_PORT_ID_CTRL ~0U 78#define NFP_META_PORT_ID_CTRL ~0U
79 79
80/** 80/**
81 * Hash type pre-pended when a RSS hash was computed 81 * Hash type pre-pended when a RSS hash was computed
82 */ 82 */
83#define NFP_NET_RSS_NONE 0 83#define NFP_NET_RSS_NONE 0
84#define NFP_NET_RSS_IPV4 1 84#define NFP_NET_RSS_IPV4 1
85#define NFP_NET_RSS_IPV6 2 85#define NFP_NET_RSS_IPV6 2
86#define NFP_NET_RSS_IPV6_EX 3 86#define NFP_NET_RSS_IPV6_EX 3
87#define NFP_NET_RSS_IPV4_TCP 4 87#define NFP_NET_RSS_IPV4_TCP 4
88#define NFP_NET_RSS_IPV6_TCP 5 88#define NFP_NET_RSS_IPV6_TCP 5
89#define NFP_NET_RSS_IPV6_EX_TCP 6 89#define NFP_NET_RSS_IPV6_EX_TCP 6
90#define NFP_NET_RSS_IPV4_UDP 7 90#define NFP_NET_RSS_IPV4_UDP 7
91#define NFP_NET_RSS_IPV6_UDP 8 91#define NFP_NET_RSS_IPV6_UDP 8
92#define NFP_NET_RSS_IPV6_EX_UDP 9 92#define NFP_NET_RSS_IPV6_EX_UDP 9
93 93
94/** 94/**
95 * Ring counts 95 * Ring counts
96 * %NFP_NET_TXR_MAX: Maximum number of TX rings 96 * %NFP_NET_TXR_MAX: Maximum number of TX rings
97 * %NFP_NET_RXR_MAX: Maximum number of RX rings 97 * %NFP_NET_RXR_MAX: Maximum number of RX rings
98 */ 98 */
99#define NFP_NET_TXR_MAX 64 99#define NFP_NET_TXR_MAX 64
100#define NFP_NET_RXR_MAX 64 100#define NFP_NET_RXR_MAX 64
101 101
102/** 102/**
103 * Read/Write config words (0x0000 - 0x002c) 103 * Read/Write config words (0x0000 - 0x002c)
104 * %NFP_NET_CFG_CTRL: Global control 104 * %NFP_NET_CFG_CTRL: Global control
105 * %NFP_NET_CFG_UPDATE: Indicate which fields are updated 105 * %NFP_NET_CFG_UPDATE: Indicate which fields are updated
106 * %NFP_NET_CFG_TXRS_ENABLE: Bitmask of enabled TX rings 106 * %NFP_NET_CFG_TXRS_ENABLE: Bitmask of enabled TX rings
107 * %NFP_NET_CFG_RXRS_ENABLE: Bitmask of enabled RX rings 107 * %NFP_NET_CFG_RXRS_ENABLE: Bitmask of enabled RX rings
108 * %NFP_NET_CFG_MTU: Set MTU size 108 * %NFP_NET_CFG_MTU: Set MTU size
109 * %NFP_NET_CFG_FLBUFSZ: Set freelist buffer size (must be larger than MTU) 109 * %NFP_NET_CFG_FLBUFSZ: Set freelist buffer size (must be larger than MTU)
110 * %NFP_NET_CFG_EXN: MSI-X table entry for exceptions 110 * %NFP_NET_CFG_EXN: MSI-X table entry for exceptions
111 * %NFP_NET_CFG_LSC: MSI-X table entry for link state changes 111 * %NFP_NET_CFG_LSC: MSI-X table entry for link state changes
112 * %NFP_NET_CFG_MACADDR: MAC address 112 * %NFP_NET_CFG_MACADDR: MAC address
113 * 113 *
114 * TODO: 114 * TODO:
115 * - define Error details in UPDATE 115 * - define Error details in UPDATE
116 */ 116 */
117#define NFP_NET_CFG_CTRL 0x0000 117#define NFP_NET_CFG_CTRL 0x0000
118#define NFP_NET_CFG_CTRL_ENABLE (0x1 << 0) /* Global enable */ 118#define NFP_NET_CFG_CTRL_ENABLE (0x1 << 0) /* Global enable */
119#define NFP_NET_CFG_CTRL_PROMISC (0x1 << 1) /* Enable Promisc mode */ 119#define NFP_NET_CFG_CTRL_PROMISC (0x1 << 1) /* Enable Promisc mode */
120#define NFP_NET_CFG_CTRL_L2BC (0x1 << 2) /* Allow L2 Broadcast */ 120#define NFP_NET_CFG_CTRL_L2BC (0x1 << 2) /* Allow L2 Broadcast */
121#define NFP_NET_CFG_CTRL_L2MC (0x1 << 3) /* Allow L2 Multicast */ 121#define NFP_NET_CFG_CTRL_L2MC (0x1 << 3) /* Allow L2 Multicast */
122#define NFP_NET_CFG_CTRL_RXCSUM (0x1 << 4) /* Enable RX Checksum */ 122#define NFP_NET_CFG_CTRL_RXCSUM (0x1 << 4) /* Enable RX Checksum */
123#define NFP_NET_CFG_CTRL_TXCSUM (0x1 << 5) /* Enable TX Checksum */ 123#define NFP_NET_CFG_CTRL_TXCSUM (0x1 << 5) /* Enable TX Checksum */
124#define NFP_NET_CFG_CTRL_RXVLAN (0x1 << 6) /* Enable VLAN strip */ 124#define NFP_NET_CFG_CTRL_RXVLAN (0x1 << 6) /* Enable VLAN strip */
125#define NFP_NET_CFG_CTRL_TXVLAN (0x1 << 7) /* Enable VLAN insert */ 125#define NFP_NET_CFG_CTRL_TXVLAN (0x1 << 7) /* Enable VLAN insert */
126#define NFP_NET_CFG_CTRL_SCATTER (0x1 << 8) /* Scatter DMA */ 126#define NFP_NET_CFG_CTRL_SCATTER (0x1 << 8) /* Scatter DMA */
127#define NFP_NET_CFG_CTRL_GATHER (0x1 << 9) /* Gather DMA */ 127#define NFP_NET_CFG_CTRL_GATHER (0x1 << 9) /* Gather DMA */
128#define NFP_NET_CFG_CTRL_LSO (0x1 << 10) /* LSO/TSO (version 1) */ 128#define NFP_NET_CFG_CTRL_LSO (0x1 << 10) /* LSO/TSO (version 1) */
129#define NFP_NET_CFG_CTRL_CTAG_FILTER (0x1 << 11) /* VLAN CTAG filtering */ 129#define NFP_NET_CFG_CTRL_CTAG_FILTER (0x1 << 11) /* VLAN CTAG filtering */
130#define NFP_NET_CFG_CTRL_RINGCFG (0x1 << 16) /* Ring runtime changes */ 130#define NFP_NET_CFG_CTRL_RINGCFG (0x1 << 16) /* Ring runtime changes */
131#define NFP_NET_CFG_CTRL_RSS (0x1 << 17) /* RSS (version 1) */ 131#define NFP_NET_CFG_CTRL_RSS (0x1 << 17) /* RSS (version 1) */
132#define NFP_NET_CFG_CTRL_IRQMOD (0x1 << 18) /* Interrupt moderation */ 132#define NFP_NET_CFG_CTRL_IRQMOD (0x1 << 18) /* Interrupt moderation */
133#define NFP_NET_CFG_CTRL_RINGPRIO (0x1 << 19) /* Ring priorities */ 133#define NFP_NET_CFG_CTRL_RINGPRIO (0x1 << 19) /* Ring priorities */
134#define NFP_NET_CFG_CTRL_MSIXAUTO (0x1 << 20) /* MSI-X auto-masking */ 134#define NFP_NET_CFG_CTRL_MSIXAUTO (0x1 << 20) /* MSI-X auto-masking */
135#define NFP_NET_CFG_CTRL_TXRWB (0x1 << 21) /* Write-back of TX ring*/ 135#define NFP_NET_CFG_CTRL_TXRWB (0x1 << 21) /* Write-back of TX ring*/
136#define NFP_NET_CFG_CTRL_L2SWITCH (0x1 << 22) /* L2 Switch */ 136#define NFP_NET_CFG_CTRL_L2SWITCH (0x1 << 22) /* L2 Switch */
137#define NFP_NET_CFG_CTRL_L2SWITCH_LOCAL (0x1 << 23) /* Switch to local */ 137#define NFP_NET_CFG_CTRL_L2SWITCH_LOCAL (0x1 << 23) /* Switch to local */
138#define NFP_NET_CFG_CTRL_VXLAN (0x1 << 24) /* VXLAN tunnel support */ 138#define NFP_NET_CFG_CTRL_VXLAN (0x1 << 24) /* VXLAN tunnel support */
139#define NFP_NET_CFG_CTRL_NVGRE (0x1 << 25) /* NVGRE tunnel support */ 139#define NFP_NET_CFG_CTRL_NVGRE (0x1 << 25) /* NVGRE tunnel support */
@@ -152,35 +152,35 @@
152#define NFP_NET_CFG_CTRL_CHAIN_META (NFP_NET_CFG_CTRL_RSS2 | \ 152#define NFP_NET_CFG_CTRL_CHAIN_META (NFP_NET_CFG_CTRL_RSS2 | \
153 NFP_NET_CFG_CTRL_CSUM_COMPLETE) 153 NFP_NET_CFG_CTRL_CSUM_COMPLETE)
154 154
155#define NFP_NET_CFG_UPDATE 0x0004 155#define NFP_NET_CFG_UPDATE 0x0004
156#define NFP_NET_CFG_UPDATE_GEN (0x1 << 0) /* General update */ 156#define NFP_NET_CFG_UPDATE_GEN (0x1 << 0) /* General update */
157#define NFP_NET_CFG_UPDATE_RING (0x1 << 1) /* Ring config change */ 157#define NFP_NET_CFG_UPDATE_RING (0x1 << 1) /* Ring config change */
158#define NFP_NET_CFG_UPDATE_RSS (0x1 << 2) /* RSS config change */ 158#define NFP_NET_CFG_UPDATE_RSS (0x1 << 2) /* RSS config change */
159#define NFP_NET_CFG_UPDATE_TXRPRIO (0x1 << 3) /* TX Ring prio change */ 159#define NFP_NET_CFG_UPDATE_TXRPRIO (0x1 << 3) /* TX Ring prio change */
160#define NFP_NET_CFG_UPDATE_RXRPRIO (0x1 << 4) /* RX Ring prio change */ 160#define NFP_NET_CFG_UPDATE_RXRPRIO (0x1 << 4) /* RX Ring prio change */
161#define NFP_NET_CFG_UPDATE_MSIX (0x1 << 5) /* MSI-X change */ 161#define NFP_NET_CFG_UPDATE_MSIX (0x1 << 5) /* MSI-X change */
162#define NFP_NET_CFG_UPDATE_L2SWITCH (0x1 << 6) /* Switch changes */ 162#define NFP_NET_CFG_UPDATE_L2SWITCH (0x1 << 6) /* Switch changes */
163#define NFP_NET_CFG_UPDATE_RESET (0x1 << 7) /* Update due to FLR */ 163#define NFP_NET_CFG_UPDATE_RESET (0x1 << 7) /* Update due to FLR */
164#define NFP_NET_CFG_UPDATE_IRQMOD (0x1 << 8) /* IRQ mod change */ 164#define NFP_NET_CFG_UPDATE_IRQMOD (0x1 << 8) /* IRQ mod change */
165#define NFP_NET_CFG_UPDATE_VXLAN (0x1 << 9) /* VXLAN port change */ 165#define NFP_NET_CFG_UPDATE_VXLAN (0x1 << 9) /* VXLAN port change */
166#define NFP_NET_CFG_UPDATE_BPF (0x1 << 10) /* BPF program load */ 166#define NFP_NET_CFG_UPDATE_BPF (0x1 << 10) /* BPF program load */
167#define NFP_NET_CFG_UPDATE_MACADDR (0x1 << 11) /* MAC address change */ 167#define NFP_NET_CFG_UPDATE_MACADDR (0x1 << 11) /* MAC address change */
168#define NFP_NET_CFG_UPDATE_MBOX (0x1 << 12) /* Mailbox update */ 168#define NFP_NET_CFG_UPDATE_MBOX (0x1 << 12) /* Mailbox update */
169#define NFP_NET_CFG_UPDATE_VF (0x1 << 13) /* VF settings change */ 169#define NFP_NET_CFG_UPDATE_VF (0x1 << 13) /* VF settings change */
170#define NFP_NET_CFG_UPDATE_ERR (0x1 << 31) /* A error occurred */ 170#define NFP_NET_CFG_UPDATE_ERR (0x1 << 31) /* A error occurred */
171#define NFP_NET_CFG_TXRS_ENABLE 0x0008 171#define NFP_NET_CFG_TXRS_ENABLE 0x0008
172#define NFP_NET_CFG_RXRS_ENABLE 0x0010 172#define NFP_NET_CFG_RXRS_ENABLE 0x0010
173#define NFP_NET_CFG_MTU 0x0018 173#define NFP_NET_CFG_MTU 0x0018
174#define NFP_NET_CFG_FLBUFSZ 0x001c 174#define NFP_NET_CFG_FLBUFSZ 0x001c
175#define NFP_NET_CFG_EXN 0x001f 175#define NFP_NET_CFG_EXN 0x001f
176#define NFP_NET_CFG_LSC 0x0020 176#define NFP_NET_CFG_LSC 0x0020
177#define NFP_NET_CFG_MACADDR 0x0024 177#define NFP_NET_CFG_MACADDR 0x0024
178 178
179/** 179/**
180 * Read-only words (0x0030 - 0x0050): 180 * Read-only words (0x0030 - 0x0050):
181 * %NFP_NET_CFG_VERSION: Firmware version number 181 * %NFP_NET_CFG_VERSION: Firmware version number
182 * %NFP_NET_CFG_STS: Status 182 * %NFP_NET_CFG_STS: Status
183 * %NFP_NET_CFG_CAP: Capabilities (same bits as %NFP_NET_CFG_CTRL) 183 * %NFP_NET_CFG_CAP: Capabilities (same bits as %NFP_NET_CFG_CTRL)
184 * %NFP_NET_CFG_MAX_TXRINGS: Maximum number of TX rings 184 * %NFP_NET_CFG_MAX_TXRINGS: Maximum number of TX rings
185 * %NFP_NET_CFG_MAX_RXRINGS: Maximum number of RX rings 185 * %NFP_NET_CFG_MAX_RXRINGS: Maximum number of RX rings
186 * %NFP_NET_CFG_MAX_MTU: Maximum support MTU 186 * %NFP_NET_CFG_MAX_MTU: Maximum support MTU
@@ -190,37 +190,37 @@
190 * TODO: 190 * TODO:
191 * - define more STS bits 191 * - define more STS bits
192 */ 192 */
193#define NFP_NET_CFG_VERSION 0x0030 193#define NFP_NET_CFG_VERSION 0x0030
194#define NFP_NET_CFG_VERSION_RESERVED_MASK (0xff << 24) 194#define NFP_NET_CFG_VERSION_RESERVED_MASK (0xff << 24)
195#define NFP_NET_CFG_VERSION_CLASS_MASK (0xff << 16) 195#define NFP_NET_CFG_VERSION_CLASS_MASK (0xff << 16)
196#define NFP_NET_CFG_VERSION_CLASS(x) (((x) & 0xff) << 16) 196#define NFP_NET_CFG_VERSION_CLASS(x) (((x) & 0xff) << 16)
197#define NFP_NET_CFG_VERSION_CLASS_GENERIC 0 197#define NFP_NET_CFG_VERSION_CLASS_GENERIC 0
198#define NFP_NET_CFG_VERSION_MAJOR_MASK (0xff << 8) 198#define NFP_NET_CFG_VERSION_MAJOR_MASK (0xff << 8)
199#define NFP_NET_CFG_VERSION_MAJOR(x) (((x) & 0xff) << 8) 199#define NFP_NET_CFG_VERSION_MAJOR(x) (((x) & 0xff) << 8)
200#define NFP_NET_CFG_VERSION_MINOR_MASK (0xff << 0) 200#define NFP_NET_CFG_VERSION_MINOR_MASK (0xff << 0)
201#define NFP_NET_CFG_VERSION_MINOR(x) (((x) & 0xff) << 0) 201#define NFP_NET_CFG_VERSION_MINOR(x) (((x) & 0xff) << 0)
202#define NFP_NET_CFG_STS 0x0034 202#define NFP_NET_CFG_STS 0x0034
203#define NFP_NET_CFG_STS_LINK (0x1 << 0) /* Link up or down */ 203#define NFP_NET_CFG_STS_LINK (0x1 << 0) /* Link up or down */
204/* Link rate */ 204/* Link rate */
205#define NFP_NET_CFG_STS_LINK_RATE_SHIFT 1 205#define NFP_NET_CFG_STS_LINK_RATE_SHIFT 1
206#define NFP_NET_CFG_STS_LINK_RATE_MASK 0xF 206#define NFP_NET_CFG_STS_LINK_RATE_MASK 0xF
207#define NFP_NET_CFG_STS_LINK_RATE \ 207#define NFP_NET_CFG_STS_LINK_RATE \
208 (NFP_NET_CFG_STS_LINK_RATE_MASK << NFP_NET_CFG_STS_LINK_RATE_SHIFT) 208 (NFP_NET_CFG_STS_LINK_RATE_MASK << NFP_NET_CFG_STS_LINK_RATE_SHIFT)
209#define NFP_NET_CFG_STS_LINK_RATE_UNSUPPORTED 0 209#define NFP_NET_CFG_STS_LINK_RATE_UNSUPPORTED 0
210#define NFP_NET_CFG_STS_LINK_RATE_UNKNOWN 1 210#define NFP_NET_CFG_STS_LINK_RATE_UNKNOWN 1
211#define NFP_NET_CFG_STS_LINK_RATE_1G 2 211#define NFP_NET_CFG_STS_LINK_RATE_1G 2
212#define NFP_NET_CFG_STS_LINK_RATE_10G 3 212#define NFP_NET_CFG_STS_LINK_RATE_10G 3
213#define NFP_NET_CFG_STS_LINK_RATE_25G 4 213#define NFP_NET_CFG_STS_LINK_RATE_25G 4
214#define NFP_NET_CFG_STS_LINK_RATE_40G 5 214#define NFP_NET_CFG_STS_LINK_RATE_40G 5
215#define NFP_NET_CFG_STS_LINK_RATE_50G 6 215#define NFP_NET_CFG_STS_LINK_RATE_50G 6
216#define NFP_NET_CFG_STS_LINK_RATE_100G 7 216#define NFP_NET_CFG_STS_LINK_RATE_100G 7
217#define NFP_NET_CFG_CAP 0x0038 217#define NFP_NET_CFG_CAP 0x0038
218#define NFP_NET_CFG_MAX_TXRINGS 0x003c 218#define NFP_NET_CFG_MAX_TXRINGS 0x003c
219#define NFP_NET_CFG_MAX_RXRINGS 0x0040 219#define NFP_NET_CFG_MAX_RXRINGS 0x0040
220#define NFP_NET_CFG_MAX_MTU 0x0044 220#define NFP_NET_CFG_MAX_MTU 0x0044
221/* Next two words are being used by VFs for solving THB350 issue */ 221/* Next two words are being used by VFs for solving THB350 issue */
222#define NFP_NET_CFG_START_TXQ 0x0048 222#define NFP_NET_CFG_START_TXQ 0x0048
223#define NFP_NET_CFG_START_RXQ 0x004c 223#define NFP_NET_CFG_START_RXQ 0x004c
224 224
225/** 225/**
226 * Prepend configuration 226 * Prepend configuration
@@ -280,8 +280,8 @@
280/** 280/**
281 * 40B reserved for future use (0x0098 - 0x00c0) 281 * 40B reserved for future use (0x0098 - 0x00c0)
282 */ 282 */
283#define NFP_NET_CFG_RESERVED 0x0098 283#define NFP_NET_CFG_RESERVED 0x0098
284#define NFP_NET_CFG_RESERVED_SZ 0x0028 284#define NFP_NET_CFG_RESERVED_SZ 0x0028
285 285
286/** 286/**
287 * RSS configuration (0x0100 - 0x01ac): 287 * RSS configuration (0x0100 - 0x01ac):
@@ -290,26 +290,26 @@
290 * %NFP_NET_CFG_RSS_KEY: RSS "secret" key 290 * %NFP_NET_CFG_RSS_KEY: RSS "secret" key
291 * %NFP_NET_CFG_RSS_ITBL: RSS indirection table 291 * %NFP_NET_CFG_RSS_ITBL: RSS indirection table
292 */ 292 */
293#define NFP_NET_CFG_RSS_BASE 0x0100 293#define NFP_NET_CFG_RSS_BASE 0x0100
294#define NFP_NET_CFG_RSS_CTRL NFP_NET_CFG_RSS_BASE 294#define NFP_NET_CFG_RSS_CTRL NFP_NET_CFG_RSS_BASE
295#define NFP_NET_CFG_RSS_MASK (0x7f) 295#define NFP_NET_CFG_RSS_MASK (0x7f)
296#define NFP_NET_CFG_RSS_MASK_of(_x) ((_x) & 0x7f) 296#define NFP_NET_CFG_RSS_MASK_of(_x) ((_x) & 0x7f)
297#define NFP_NET_CFG_RSS_IPV4 (1 << 8) /* RSS for IPv4 */ 297#define NFP_NET_CFG_RSS_IPV4 (1 << 8) /* RSS for IPv4 */
298#define NFP_NET_CFG_RSS_IPV6 (1 << 9) /* RSS for IPv6 */ 298#define NFP_NET_CFG_RSS_IPV6 (1 << 9) /* RSS for IPv6 */
299#define NFP_NET_CFG_RSS_IPV4_TCP (1 << 10) /* RSS for IPv4/TCP */ 299#define NFP_NET_CFG_RSS_IPV4_TCP (1 << 10) /* RSS for IPv4/TCP */
300#define NFP_NET_CFG_RSS_IPV4_UDP (1 << 11) /* RSS for IPv4/UDP */ 300#define NFP_NET_CFG_RSS_IPV4_UDP (1 << 11) /* RSS for IPv4/UDP */
301#define NFP_NET_CFG_RSS_IPV6_TCP (1 << 12) /* RSS for IPv6/TCP */ 301#define NFP_NET_CFG_RSS_IPV6_TCP (1 << 12) /* RSS for IPv6/TCP */
302#define NFP_NET_CFG_RSS_IPV6_UDP (1 << 13) /* RSS for IPv6/UDP */ 302#define NFP_NET_CFG_RSS_IPV6_UDP (1 << 13) /* RSS for IPv6/UDP */
303#define NFP_NET_CFG_RSS_HFUNC 0xff000000 303#define NFP_NET_CFG_RSS_HFUNC 0xff000000
304#define NFP_NET_CFG_RSS_TOEPLITZ (1 << 24) /* Use Toeplitz hash */ 304#define NFP_NET_CFG_RSS_TOEPLITZ (1 << 24) /* Use Toeplitz hash */
305#define NFP_NET_CFG_RSS_XOR (1 << 25) /* Use XOR as hash */ 305#define NFP_NET_CFG_RSS_XOR (1 << 25) /* Use XOR as hash */
306#define NFP_NET_CFG_RSS_CRC32 (1 << 26) /* Use CRC32 as hash */ 306#define NFP_NET_CFG_RSS_CRC32 (1 << 26) /* Use CRC32 as hash */
307#define NFP_NET_CFG_RSS_HFUNCS 3 307#define NFP_NET_CFG_RSS_HFUNCS 3
308#define NFP_NET_CFG_RSS_KEY (NFP_NET_CFG_RSS_BASE + 0x4) 308#define NFP_NET_CFG_RSS_KEY (NFP_NET_CFG_RSS_BASE + 0x4)
309#define NFP_NET_CFG_RSS_KEY_SZ 0x28 309#define NFP_NET_CFG_RSS_KEY_SZ 0x28
310#define NFP_NET_CFG_RSS_ITBL (NFP_NET_CFG_RSS_BASE + 0x4 + \ 310#define NFP_NET_CFG_RSS_ITBL (NFP_NET_CFG_RSS_BASE + 0x4 + \
311 NFP_NET_CFG_RSS_KEY_SZ) 311 NFP_NET_CFG_RSS_KEY_SZ)
312#define NFP_NET_CFG_RSS_ITBL_SZ 0x80 312#define NFP_NET_CFG_RSS_ITBL_SZ 0x80
313 313
314/** 314/**
315 * TX ring configuration (0x200 - 0x800) 315 * TX ring configuration (0x200 - 0x800)
@@ -321,13 +321,13 @@
321 * %NFP_NET_CFG_TXR_PRIO: Per TX ring priority (1B entries) 321 * %NFP_NET_CFG_TXR_PRIO: Per TX ring priority (1B entries)
322 * %NFP_NET_CFG_TXR_IRQ_MOD: Per TX ring interrupt moderation packet 322 * %NFP_NET_CFG_TXR_IRQ_MOD: Per TX ring interrupt moderation packet
323 */ 323 */
324#define NFP_NET_CFG_TXR_BASE 0x0200 324#define NFP_NET_CFG_TXR_BASE 0x0200
325#define NFP_NET_CFG_TXR_ADDR(_x) (NFP_NET_CFG_TXR_BASE + ((_x) * 0x8)) 325#define NFP_NET_CFG_TXR_ADDR(_x) (NFP_NET_CFG_TXR_BASE + ((_x) * 0x8))
326#define NFP_NET_CFG_TXR_WB_ADDR(_x) (NFP_NET_CFG_TXR_BASE + 0x200 + \ 326#define NFP_NET_CFG_TXR_WB_ADDR(_x) (NFP_NET_CFG_TXR_BASE + 0x200 + \
327 ((_x) * 0x8)) 327 ((_x) * 0x8))
328#define NFP_NET_CFG_TXR_SZ(_x) (NFP_NET_CFG_TXR_BASE + 0x400 + (_x)) 328#define NFP_NET_CFG_TXR_SZ(_x) (NFP_NET_CFG_TXR_BASE + 0x400 + (_x))
329#define NFP_NET_CFG_TXR_VEC(_x) (NFP_NET_CFG_TXR_BASE + 0x440 + (_x)) 329#define NFP_NET_CFG_TXR_VEC(_x) (NFP_NET_CFG_TXR_BASE + 0x440 + (_x))
330#define NFP_NET_CFG_TXR_PRIO(_x) (NFP_NET_CFG_TXR_BASE + 0x480 + (_x)) 330#define NFP_NET_CFG_TXR_PRIO(_x) (NFP_NET_CFG_TXR_BASE + 0x480 + (_x))
331#define NFP_NET_CFG_TXR_IRQ_MOD(_x) (NFP_NET_CFG_TXR_BASE + 0x500 + \ 331#define NFP_NET_CFG_TXR_IRQ_MOD(_x) (NFP_NET_CFG_TXR_BASE + 0x500 + \
332 ((_x) * 0x4)) 332 ((_x) * 0x4))
333 333
@@ -340,11 +340,11 @@
340 * %NFP_NET_CFG_RXR_PRIO: Per RX ring priority (1B entries) 340 * %NFP_NET_CFG_RXR_PRIO: Per RX ring priority (1B entries)
341 * %NFP_NET_CFG_RXR_IRQ_MOD: Per RX ring interrupt moderation (4B entries) 341 * %NFP_NET_CFG_RXR_IRQ_MOD: Per RX ring interrupt moderation (4B entries)
342 */ 342 */
343#define NFP_NET_CFG_RXR_BASE 0x0800 343#define NFP_NET_CFG_RXR_BASE 0x0800
344#define NFP_NET_CFG_RXR_ADDR(_x) (NFP_NET_CFG_RXR_BASE + ((_x) * 0x8)) 344#define NFP_NET_CFG_RXR_ADDR(_x) (NFP_NET_CFG_RXR_BASE + ((_x) * 0x8))
345#define NFP_NET_CFG_RXR_SZ(_x) (NFP_NET_CFG_RXR_BASE + 0x200 + (_x)) 345#define NFP_NET_CFG_RXR_SZ(_x) (NFP_NET_CFG_RXR_BASE + 0x200 + (_x))
346#define NFP_NET_CFG_RXR_VEC(_x) (NFP_NET_CFG_RXR_BASE + 0x240 + (_x)) 346#define NFP_NET_CFG_RXR_VEC(_x) (NFP_NET_CFG_RXR_BASE + 0x240 + (_x))
347#define NFP_NET_CFG_RXR_PRIO(_x) (NFP_NET_CFG_RXR_BASE + 0x280 + (_x)) 347#define NFP_NET_CFG_RXR_PRIO(_x) (NFP_NET_CFG_RXR_BASE + 0x280 + (_x))
348#define NFP_NET_CFG_RXR_IRQ_MOD(_x) (NFP_NET_CFG_RXR_BASE + 0x300 + \ 348#define NFP_NET_CFG_RXR_IRQ_MOD(_x) (NFP_NET_CFG_RXR_BASE + 0x300 + \
349 ((_x) * 0x4)) 349 ((_x) * 0x4))
350 350
@@ -358,36 +358,36 @@
358 * the MSI-X entry and the host driver must clear the register to 358 * the MSI-X entry and the host driver must clear the register to
359 * re-enable the interrupt. 359 * re-enable the interrupt.
360 */ 360 */
361#define NFP_NET_CFG_ICR_BASE 0x0c00 361#define NFP_NET_CFG_ICR_BASE 0x0c00
362#define NFP_NET_CFG_ICR(_x) (NFP_NET_CFG_ICR_BASE + (_x)) 362#define NFP_NET_CFG_ICR(_x) (NFP_NET_CFG_ICR_BASE + (_x))
363#define NFP_NET_CFG_ICR_UNMASKED 0x0 363#define NFP_NET_CFG_ICR_UNMASKED 0x0
364#define NFP_NET_CFG_ICR_RXTX 0x1 364#define NFP_NET_CFG_ICR_RXTX 0x1
365#define NFP_NET_CFG_ICR_LSC 0x2 365#define NFP_NET_CFG_ICR_LSC 0x2
366 366
367/** 367/**
368 * General device stats (0x0d00 - 0x0d90) 368 * General device stats (0x0d00 - 0x0d90)
369 * all counters are 64bit. 369 * all counters are 64bit.
370 */ 370 */
371#define NFP_NET_CFG_STATS_BASE 0x0d00 371#define NFP_NET_CFG_STATS_BASE 0x0d00
372#define NFP_NET_CFG_STATS_RX_DISCARDS (NFP_NET_CFG_STATS_BASE + 0x00) 372#define NFP_NET_CFG_STATS_RX_DISCARDS (NFP_NET_CFG_STATS_BASE + 0x00)
373#define NFP_NET_CFG_STATS_RX_ERRORS (NFP_NET_CFG_STATS_BASE + 0x08) 373#define NFP_NET_CFG_STATS_RX_ERRORS (NFP_NET_CFG_STATS_BASE + 0x08)
374#define NFP_NET_CFG_STATS_RX_OCTETS (NFP_NET_CFG_STATS_BASE + 0x10) 374#define NFP_NET_CFG_STATS_RX_OCTETS (NFP_NET_CFG_STATS_BASE + 0x10)
375#define NFP_NET_CFG_STATS_RX_UC_OCTETS (NFP_NET_CFG_STATS_BASE + 0x18) 375#define NFP_NET_CFG_STATS_RX_UC_OCTETS (NFP_NET_CFG_STATS_BASE + 0x18)
376#define NFP_NET_CFG_STATS_RX_MC_OCTETS (NFP_NET_CFG_STATS_BASE + 0x20) 376#define NFP_NET_CFG_STATS_RX_MC_OCTETS (NFP_NET_CFG_STATS_BASE + 0x20)
377#define NFP_NET_CFG_STATS_RX_BC_OCTETS (NFP_NET_CFG_STATS_BASE + 0x28) 377#define NFP_NET_CFG_STATS_RX_BC_OCTETS (NFP_NET_CFG_STATS_BASE + 0x28)
378#define NFP_NET_CFG_STATS_RX_FRAMES (NFP_NET_CFG_STATS_BASE + 0x30) 378#define NFP_NET_CFG_STATS_RX_FRAMES (NFP_NET_CFG_STATS_BASE + 0x30)
379#define NFP_NET_CFG_STATS_RX_MC_FRAMES (NFP_NET_CFG_STATS_BASE + 0x38) 379#define NFP_NET_CFG_STATS_RX_MC_FRAMES (NFP_NET_CFG_STATS_BASE + 0x38)
380#define NFP_NET_CFG_STATS_RX_BC_FRAMES (NFP_NET_CFG_STATS_BASE + 0x40) 380#define NFP_NET_CFG_STATS_RX_BC_FRAMES (NFP_NET_CFG_STATS_BASE + 0x40)
381 381
382#define NFP_NET_CFG_STATS_TX_DISCARDS (NFP_NET_CFG_STATS_BASE + 0x48) 382#define NFP_NET_CFG_STATS_TX_DISCARDS (NFP_NET_CFG_STATS_BASE + 0x48)
383#define NFP_NET_CFG_STATS_TX_ERRORS (NFP_NET_CFG_STATS_BASE + 0x50) 383#define NFP_NET_CFG_STATS_TX_ERRORS (NFP_NET_CFG_STATS_BASE + 0x50)
384#define NFP_NET_CFG_STATS_TX_OCTETS (NFP_NET_CFG_STATS_BASE + 0x58) 384#define NFP_NET_CFG_STATS_TX_OCTETS (NFP_NET_CFG_STATS_BASE + 0x58)
385#define NFP_NET_CFG_STATS_TX_UC_OCTETS (NFP_NET_CFG_STATS_BASE + 0x60) 385#define NFP_NET_CFG_STATS_TX_UC_OCTETS (NFP_NET_CFG_STATS_BASE + 0x60)
386#define NFP_NET_CFG_STATS_TX_MC_OCTETS (NFP_NET_CFG_STATS_BASE + 0x68) 386#define NFP_NET_CFG_STATS_TX_MC_OCTETS (NFP_NET_CFG_STATS_BASE + 0x68)
387#define NFP_NET_CFG_STATS_TX_BC_OCTETS (NFP_NET_CFG_STATS_BASE + 0x70) 387#define NFP_NET_CFG_STATS_TX_BC_OCTETS (NFP_NET_CFG_STATS_BASE + 0x70)
388#define NFP_NET_CFG_STATS_TX_FRAMES (NFP_NET_CFG_STATS_BASE + 0x78) 388#define NFP_NET_CFG_STATS_TX_FRAMES (NFP_NET_CFG_STATS_BASE + 0x78)
389#define NFP_NET_CFG_STATS_TX_MC_FRAMES (NFP_NET_CFG_STATS_BASE + 0x80) 389#define NFP_NET_CFG_STATS_TX_MC_FRAMES (NFP_NET_CFG_STATS_BASE + 0x80)
390#define NFP_NET_CFG_STATS_TX_BC_FRAMES (NFP_NET_CFG_STATS_BASE + 0x88) 390#define NFP_NET_CFG_STATS_TX_BC_FRAMES (NFP_NET_CFG_STATS_BASE + 0x88)
391 391
392#define NFP_NET_CFG_STATS_APP0_FRAMES (NFP_NET_CFG_STATS_BASE + 0x90) 392#define NFP_NET_CFG_STATS_APP0_FRAMES (NFP_NET_CFG_STATS_BASE + 0x90)
393#define NFP_NET_CFG_STATS_APP0_BYTES (NFP_NET_CFG_STATS_BASE + 0x98) 393#define NFP_NET_CFG_STATS_APP0_BYTES (NFP_NET_CFG_STATS_BASE + 0x98)
@@ -404,11 +404,11 @@
404 * %NFP_NET_CFG_TXR_STATS: TX ring statistics (Packet and Byte count) 404 * %NFP_NET_CFG_TXR_STATS: TX ring statistics (Packet and Byte count)
405 * %NFP_NET_CFG_RXR_STATS: RX ring statistics (Packet and Byte count) 405 * %NFP_NET_CFG_RXR_STATS: RX ring statistics (Packet and Byte count)
406 */ 406 */
407#define NFP_NET_CFG_TXR_STATS_BASE 0x1000 407#define NFP_NET_CFG_TXR_STATS_BASE 0x1000
408#define NFP_NET_CFG_TXR_STATS(_x) (NFP_NET_CFG_TXR_STATS_BASE + \ 408#define NFP_NET_CFG_TXR_STATS(_x) (NFP_NET_CFG_TXR_STATS_BASE + \
409 ((_x) * 0x10)) 409 ((_x) * 0x10))
410#define NFP_NET_CFG_RXR_STATS_BASE 0x1400 410#define NFP_NET_CFG_RXR_STATS_BASE 0x1400
411#define NFP_NET_CFG_RXR_STATS(_x) (NFP_NET_CFG_RXR_STATS_BASE + \ 411#define NFP_NET_CFG_RXR_STATS(_x) (NFP_NET_CFG_RXR_STATS_BASE + \
412 ((_x) * 0x10)) 412 ((_x) * 0x10))
413 413
414/** 414/**
@@ -444,7 +444,7 @@
444 * %NFP_NET_CFG_TLV_TYPE: Offset of type within the TLV 444 * %NFP_NET_CFG_TLV_TYPE: Offset of type within the TLV
445 * %NFP_NET_CFG_TLV_TYPE_REQUIRED: Driver must be able to parse the TLV 445 * %NFP_NET_CFG_TLV_TYPE_REQUIRED: Driver must be able to parse the TLV
446 * %NFP_NET_CFG_TLV_LENGTH: Offset of length within the TLV 446 * %NFP_NET_CFG_TLV_LENGTH: Offset of length within the TLV
447 * %NFP_NET_CFG_TLV_LENGTH_INC: TLV length increments 447 * %NFP_NET_CFG_TLV_LENGTH_INC: TLV length increments
448 * %NFP_NET_CFG_TLV_VALUE: Offset of value with the TLV 448 * %NFP_NET_CFG_TLV_VALUE: Offset of value with the TLV
449 * 449 *
450 * List of simple TLV structures, first one starts at %NFP_NET_CFG_TLV_BASE. 450 * List of simple TLV structures, first one starts at %NFP_NET_CFG_TLV_BASE.
@@ -457,12 +457,12 @@
457 * Note that the 4 byte TLV header is not counted in %NFP_NET_CFG_TLV_LENGTH. 457 * Note that the 4 byte TLV header is not counted in %NFP_NET_CFG_TLV_LENGTH.
458 */ 458 */
459#define NFP_NET_CFG_TLV_TYPE 0x00 459#define NFP_NET_CFG_TLV_TYPE 0x00
460#define NFP_NET_CFG_TLV_TYPE_REQUIRED 0x8000 460#define NFP_NET_CFG_TLV_TYPE_REQUIRED 0x8000
461#define NFP_NET_CFG_TLV_LENGTH 0x02 461#define NFP_NET_CFG_TLV_LENGTH 0x02
462#define NFP_NET_CFG_TLV_LENGTH_INC 4 462#define NFP_NET_CFG_TLV_LENGTH_INC 4
463#define NFP_NET_CFG_TLV_VALUE 0x04 463#define NFP_NET_CFG_TLV_VALUE 0x04
464 464
465#define NFP_NET_CFG_TLV_HEADER_REQUIRED 0x80000000 465#define NFP_NET_CFG_TLV_HEADER_REQUIRED 0x80000000
466#define NFP_NET_CFG_TLV_HEADER_TYPE 0x7fff0000 466#define NFP_NET_CFG_TLV_HEADER_TYPE 0x7fff0000
467#define NFP_NET_CFG_TLV_HEADER_LENGTH 0x0000ffff 467#define NFP_NET_CFG_TLV_HEADER_LENGTH 0x0000ffff
468 468
diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/Makefile b/drivers/net/ethernet/netronome/nfp/nfpcore/Makefile
new file mode 100644
index 000000000000..805fa28f391a
--- /dev/null
+++ b/drivers/net/ethernet/netronome/nfp/nfpcore/Makefile
@@ -0,0 +1,2 @@
1# SPDX-License-Identifier: GPL-2.0
2# kbuild requires Makefile in a directory to build individual objects
diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000/Makefile b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000/Makefile
new file mode 100644
index 000000000000..805fa28f391a
--- /dev/null
+++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000/Makefile
@@ -0,0 +1,2 @@
1# SPDX-License-Identifier: GPL-2.0
2# kbuild requires Makefile in a directory to build individual objects
diff --git a/drivers/net/ethernet/netronome/nfp/nic/Makefile b/drivers/net/ethernet/netronome/nfp/nic/Makefile
new file mode 100644
index 000000000000..805fa28f391a
--- /dev/null
+++ b/drivers/net/ethernet/netronome/nfp/nic/Makefile
@@ -0,0 +1,2 @@
1# SPDX-License-Identifier: GPL-2.0
2# kbuild requires Makefile in a directory to build individual objects
diff --git a/drivers/net/ethernet/qlogic/qed/qed_iwarp.c b/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
index d5d02be72947..69051e98aff9 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
@@ -1799,7 +1799,7 @@ enum qed_iwarp_mpa_pkt_type {
1799/* fpdu can be fragmented over maximum 3 bds: header, partial mpa, unaligned */ 1799/* fpdu can be fragmented over maximum 3 bds: header, partial mpa, unaligned */
1800#define QED_IWARP_MAX_BDS_PER_FPDU 3 1800#define QED_IWARP_MAX_BDS_PER_FPDU 3
1801 1801
1802char *pkt_type_str[] = { 1802static const char * const pkt_type_str[] = {
1803 "QED_IWARP_MPA_PKT_PACKED", 1803 "QED_IWARP_MPA_PKT_PACKED",
1804 "QED_IWARP_MPA_PKT_PARTIAL", 1804 "QED_IWARP_MPA_PKT_PARTIAL",
1805 "QED_IWARP_MPA_PKT_UNALIGNED" 1805 "QED_IWARP_MPA_PKT_UNALIGNED"
diff --git a/drivers/net/ethernet/qualcomm/qca_spi.c b/drivers/net/ethernet/qualcomm/qca_spi.c
index 9c236298fe21..5803cd6db406 100644
--- a/drivers/net/ethernet/qualcomm/qca_spi.c
+++ b/drivers/net/ethernet/qualcomm/qca_spi.c
@@ -705,7 +705,6 @@ qcaspi_netdev_xmit(struct sk_buff *skb, struct net_device *dev)
705 tskb = skb_copy_expand(skb, QCAFRM_HEADER_LEN, 705 tskb = skb_copy_expand(skb, QCAFRM_HEADER_LEN,
706 QCAFRM_FOOTER_LEN + pad_len, GFP_ATOMIC); 706 QCAFRM_FOOTER_LEN + pad_len, GFP_ATOMIC);
707 if (!tskb) { 707 if (!tskb) {
708 netdev_dbg(qca->net_dev, "could not allocate tx_buff\n");
709 qca->stats.out_of_mem++; 708 qca->stats.out_of_mem++;
710 return NETDEV_TX_BUSY; 709 return NETDEV_TX_BUSY;
711 } 710 }
diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
index c4949183eef3..38d9356ebcc4 100644
--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
+++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
@@ -1,4 +1,4 @@
1/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. 1/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
2 * 2 *
3 * This program is free software; you can redistribute it and/or modify 3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and 4 * it under the terms of the GNU General Public License version 2 and
@@ -43,6 +43,11 @@
43 43
44/* Local Definitions and Declarations */ 44/* Local Definitions and Declarations */
45 45
46static const struct nla_policy rmnet_policy[IFLA_RMNET_MAX + 1] = {
47 [IFLA_RMNET_MUX_ID] = { .type = NLA_U16 },
48 [IFLA_RMNET_FLAGS] = { .len = sizeof(struct ifla_rmnet_flags) },
49};
50
46static int rmnet_is_real_dev_registered(const struct net_device *real_dev) 51static int rmnet_is_real_dev_registered(const struct net_device *real_dev)
47{ 52{
48 return rcu_access_pointer(real_dev->rx_handler) == rmnet_rx_handler; 53 return rcu_access_pointer(real_dev->rx_handler) == rmnet_rx_handler;
@@ -131,7 +136,7 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev,
131 struct nlattr *tb[], struct nlattr *data[], 136 struct nlattr *tb[], struct nlattr *data[],
132 struct netlink_ext_ack *extack) 137 struct netlink_ext_ack *extack)
133{ 138{
134 u32 data_format = RMNET_INGRESS_FORMAT_DEAGGREGATION; 139 u32 data_format = RMNET_FLAGS_INGRESS_DEAGGREGATION;
135 struct net_device *real_dev; 140 struct net_device *real_dev;
136 int mode = RMNET_EPMODE_VND; 141 int mode = RMNET_EPMODE_VND;
137 struct rmnet_endpoint *ep; 142 struct rmnet_endpoint *ep;
@@ -143,14 +148,14 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev,
143 if (!real_dev || !dev) 148 if (!real_dev || !dev)
144 return -ENODEV; 149 return -ENODEV;
145 150
146 if (!data[IFLA_VLAN_ID]) 151 if (!data[IFLA_RMNET_MUX_ID])
147 return -EINVAL; 152 return -EINVAL;
148 153
149 ep = kzalloc(sizeof(*ep), GFP_ATOMIC); 154 ep = kzalloc(sizeof(*ep), GFP_ATOMIC);
150 if (!ep) 155 if (!ep)
151 return -ENOMEM; 156 return -ENOMEM;
152 157
153 mux_id = nla_get_u16(data[IFLA_VLAN_ID]); 158 mux_id = nla_get_u16(data[IFLA_RMNET_MUX_ID]);
154 159
155 err = rmnet_register_real_device(real_dev); 160 err = rmnet_register_real_device(real_dev);
156 if (err) 161 if (err)
@@ -165,10 +170,10 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev,
165 170
166 hlist_add_head_rcu(&ep->hlnode, &port->muxed_ep[mux_id]); 171 hlist_add_head_rcu(&ep->hlnode, &port->muxed_ep[mux_id]);
167 172
168 if (data[IFLA_VLAN_FLAGS]) { 173 if (data[IFLA_RMNET_FLAGS]) {
169 struct ifla_vlan_flags *flags; 174 struct ifla_rmnet_flags *flags;
170 175
171 flags = nla_data(data[IFLA_VLAN_FLAGS]); 176 flags = nla_data(data[IFLA_RMNET_FLAGS]);
172 data_format = flags->flags & flags->mask; 177 data_format = flags->flags & flags->mask;
173 } 178 }
174 179
@@ -276,10 +281,10 @@ static int rmnet_rtnl_validate(struct nlattr *tb[], struct nlattr *data[],
276{ 281{
277 u16 mux_id; 282 u16 mux_id;
278 283
279 if (!data || !data[IFLA_VLAN_ID]) 284 if (!data || !data[IFLA_RMNET_MUX_ID])
280 return -EINVAL; 285 return -EINVAL;
281 286
282 mux_id = nla_get_u16(data[IFLA_VLAN_ID]); 287 mux_id = nla_get_u16(data[IFLA_RMNET_MUX_ID]);
283 if (mux_id > (RMNET_MAX_LOGICAL_EP - 1)) 288 if (mux_id > (RMNET_MAX_LOGICAL_EP - 1))
284 return -ERANGE; 289 return -ERANGE;
285 290
@@ -304,8 +309,8 @@ static int rmnet_changelink(struct net_device *dev, struct nlattr *tb[],
304 309
305 port = rmnet_get_port_rtnl(real_dev); 310 port = rmnet_get_port_rtnl(real_dev);
306 311
307 if (data[IFLA_VLAN_ID]) { 312 if (data[IFLA_RMNET_MUX_ID]) {
308 mux_id = nla_get_u16(data[IFLA_VLAN_ID]); 313 mux_id = nla_get_u16(data[IFLA_RMNET_MUX_ID]);
309 ep = rmnet_get_endpoint(port, priv->mux_id); 314 ep = rmnet_get_endpoint(port, priv->mux_id);
310 315
311 hlist_del_init_rcu(&ep->hlnode); 316 hlist_del_init_rcu(&ep->hlnode);
@@ -315,10 +320,10 @@ static int rmnet_changelink(struct net_device *dev, struct nlattr *tb[],
315 priv->mux_id = mux_id; 320 priv->mux_id = mux_id;
316 } 321 }
317 322
318 if (data[IFLA_VLAN_FLAGS]) { 323 if (data[IFLA_RMNET_FLAGS]) {
319 struct ifla_vlan_flags *flags; 324 struct ifla_rmnet_flags *flags;
320 325
321 flags = nla_data(data[IFLA_VLAN_FLAGS]); 326 flags = nla_data(data[IFLA_RMNET_FLAGS]);
322 port->data_format = flags->flags & flags->mask; 327 port->data_format = flags->flags & flags->mask;
323 } 328 }
324 329
@@ -327,13 +332,45 @@ static int rmnet_changelink(struct net_device *dev, struct nlattr *tb[],
327 332
328static size_t rmnet_get_size(const struct net_device *dev) 333static size_t rmnet_get_size(const struct net_device *dev)
329{ 334{
330 return nla_total_size(2) /* IFLA_VLAN_ID */ + 335 return
331 nla_total_size(sizeof(struct ifla_vlan_flags)); /* IFLA_VLAN_FLAGS */ 336 /* IFLA_RMNET_MUX_ID */
337 nla_total_size(2) +
338 /* IFLA_RMNET_FLAGS */
339 nla_total_size(sizeof(struct ifla_rmnet_flags));
340}
341
342static int rmnet_fill_info(struct sk_buff *skb, const struct net_device *dev)
343{
344 struct rmnet_priv *priv = netdev_priv(dev);
345 struct net_device *real_dev;
346 struct ifla_rmnet_flags f;
347 struct rmnet_port *port;
348
349 real_dev = priv->real_dev;
350
351 if (!rmnet_is_real_dev_registered(real_dev))
352 return -ENODEV;
353
354 if (nla_put_u16(skb, IFLA_RMNET_MUX_ID, priv->mux_id))
355 goto nla_put_failure;
356
357 port = rmnet_get_port_rtnl(real_dev);
358
359 f.flags = port->data_format;
360 f.mask = ~0;
361
362 if (nla_put(skb, IFLA_RMNET_FLAGS, sizeof(f), &f))
363 goto nla_put_failure;
364
365 return 0;
366
367nla_put_failure:
368 return -EMSGSIZE;
332} 369}
333 370
334struct rtnl_link_ops rmnet_link_ops __read_mostly = { 371struct rtnl_link_ops rmnet_link_ops __read_mostly = {
335 .kind = "rmnet", 372 .kind = "rmnet",
336 .maxtype = __IFLA_VLAN_MAX, 373 .maxtype = __IFLA_RMNET_MAX,
337 .priv_size = sizeof(struct rmnet_priv), 374 .priv_size = sizeof(struct rmnet_priv),
338 .setup = rmnet_vnd_setup, 375 .setup = rmnet_vnd_setup,
339 .validate = rmnet_rtnl_validate, 376 .validate = rmnet_rtnl_validate,
@@ -341,6 +378,8 @@ struct rtnl_link_ops rmnet_link_ops __read_mostly = {
341 .dellink = rmnet_dellink, 378 .dellink = rmnet_dellink,
342 .get_size = rmnet_get_size, 379 .get_size = rmnet_get_size,
343 .changelink = rmnet_changelink, 380 .changelink = rmnet_changelink,
381 .policy = rmnet_policy,
382 .fill_info = rmnet_fill_info,
344}; 383};
345 384
346/* Needs either rcu_read_lock() or rtnl lock */ 385/* Needs either rcu_read_lock() or rtnl lock */
diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h
index 00e4634100d3..0b5b5da80198 100644
--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h
+++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h
@@ -1,4 +1,4 @@
1/* Copyright (c) 2013-2014, 2016-2017 The Linux Foundation. All rights reserved. 1/* Copyright (c) 2013-2014, 2016-2018 The Linux Foundation. All rights reserved.
2 * 2 *
3 * This program is free software; you can redistribute it and/or modify 3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and 4 * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c
index 601edec28c5f..6fcd586e9804 100644
--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c
+++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c
@@ -1,4 +1,4 @@
1/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. 1/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
2 * 2 *
3 * This program is free software; you can redistribute it and/or modify 3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and 4 * it under the terms of the GNU General Public License version 2 and
@@ -70,7 +70,7 @@ __rmnet_map_ingress_handler(struct sk_buff *skb,
70 u8 mux_id; 70 u8 mux_id;
71 71
72 if (RMNET_MAP_GET_CD_BIT(skb)) { 72 if (RMNET_MAP_GET_CD_BIT(skb)) {
73 if (port->data_format & RMNET_INGRESS_FORMAT_MAP_COMMANDS) 73 if (port->data_format & RMNET_FLAGS_INGRESS_MAP_COMMANDS)
74 return rmnet_map_command(skb, port); 74 return rmnet_map_command(skb, port);
75 75
76 goto free_skb; 76 goto free_skb;
@@ -93,7 +93,7 @@ __rmnet_map_ingress_handler(struct sk_buff *skb,
93 skb_pull(skb, sizeof(struct rmnet_map_header)); 93 skb_pull(skb, sizeof(struct rmnet_map_header));
94 rmnet_set_skb_proto(skb); 94 rmnet_set_skb_proto(skb);
95 95
96 if (port->data_format & RMNET_INGRESS_FORMAT_MAP_CKSUMV4) { 96 if (port->data_format & RMNET_FLAGS_INGRESS_MAP_CKSUMV4) {
97 if (!rmnet_map_checksum_downlink_packet(skb, len + pad)) 97 if (!rmnet_map_checksum_downlink_packet(skb, len + pad))
98 skb->ip_summed = CHECKSUM_UNNECESSARY; 98 skb->ip_summed = CHECKSUM_UNNECESSARY;
99 } 99 }
@@ -121,7 +121,7 @@ rmnet_map_ingress_handler(struct sk_buff *skb,
121 skb_push(skb, ETH_HLEN); 121 skb_push(skb, ETH_HLEN);
122 } 122 }
123 123
124 if (port->data_format & RMNET_INGRESS_FORMAT_DEAGGREGATION) { 124 if (port->data_format & RMNET_FLAGS_INGRESS_DEAGGREGATION) {
125 while ((skbn = rmnet_map_deaggregate(skb, port)) != NULL) 125 while ((skbn = rmnet_map_deaggregate(skb, port)) != NULL)
126 __rmnet_map_ingress_handler(skbn, port); 126 __rmnet_map_ingress_handler(skbn, port);
127 127
@@ -141,7 +141,7 @@ static int rmnet_map_egress_handler(struct sk_buff *skb,
141 additional_header_len = 0; 141 additional_header_len = 0;
142 required_headroom = sizeof(struct rmnet_map_header); 142 required_headroom = sizeof(struct rmnet_map_header);
143 143
144 if (port->data_format & RMNET_EGRESS_FORMAT_MAP_CKSUMV4) { 144 if (port->data_format & RMNET_FLAGS_EGRESS_MAP_CKSUMV4) {
145 additional_header_len = sizeof(struct rmnet_map_ul_csum_header); 145 additional_header_len = sizeof(struct rmnet_map_ul_csum_header);
146 required_headroom += additional_header_len; 146 required_headroom += additional_header_len;
147 } 147 }
@@ -151,7 +151,7 @@ static int rmnet_map_egress_handler(struct sk_buff *skb,
151 goto fail; 151 goto fail;
152 } 152 }
153 153
154 if (port->data_format & RMNET_EGRESS_FORMAT_MAP_CKSUMV4) 154 if (port->data_format & RMNET_FLAGS_EGRESS_MAP_CKSUMV4)
155 rmnet_map_checksum_uplink_packet(skb, orig_dev); 155 rmnet_map_checksum_uplink_packet(skb, orig_dev);
156 156
157 map_header = rmnet_map_add_map_header(skb, additional_header_len, 0); 157 map_header = rmnet_map_add_map_header(skb, additional_header_len, 0);
diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h
index 6ce31e29136d..884f1f52dcc2 100644
--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h
+++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h
@@ -1,4 +1,4 @@
1/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. 1/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
2 * 2 *
3 * This program is free software; you can redistribute it and/or modify 3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and 4 * it under the terms of the GNU General Public License version 2 and
@@ -23,8 +23,8 @@ struct rmnet_map_control_command {
23 struct { 23 struct {
24 u16 ip_family:2; 24 u16 ip_family:2;
25 u16 reserved:14; 25 u16 reserved:14;
26 u16 flow_control_seq_num; 26 __be16 flow_control_seq_num;
27 u32 qos_id; 27 __be32 qos_id;
28 } flow_control; 28 } flow_control;
29 u8 data[0]; 29 u8 data[0];
30 }; 30 };
@@ -44,7 +44,7 @@ struct rmnet_map_header {
44 u8 reserved_bit:1; 44 u8 reserved_bit:1;
45 u8 cd_bit:1; 45 u8 cd_bit:1;
46 u8 mux_id; 46 u8 mux_id;
47 u16 pkt_len; 47 __be16 pkt_len;
48} __aligned(1); 48} __aligned(1);
49 49
50struct rmnet_map_dl_csum_trailer { 50struct rmnet_map_dl_csum_trailer {
diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_command.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_command.c
index b0dbca070c00..78fdad0c6f76 100644
--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_command.c
+++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_command.c
@@ -1,4 +1,4 @@
1/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. 1/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
2 * 2 *
3 * This program is free software; you can redistribute it and/or modify 3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and 4 * it under the terms of the GNU General Public License version 2 and
@@ -69,7 +69,7 @@ static void rmnet_map_send_ack(struct sk_buff *skb,
69 struct rmnet_map_control_command *cmd; 69 struct rmnet_map_control_command *cmd;
70 int xmit_status; 70 int xmit_status;
71 71
72 if (port->data_format & RMNET_INGRESS_FORMAT_MAP_CKSUMV4) { 72 if (port->data_format & RMNET_FLAGS_INGRESS_MAP_CKSUMV4) {
73 if (skb->len < sizeof(struct rmnet_map_header) + 73 if (skb->len < sizeof(struct rmnet_map_header) +
74 RMNET_MAP_GET_LENGTH(skb) + 74 RMNET_MAP_GET_LENGTH(skb) +
75 sizeof(struct rmnet_map_dl_csum_trailer)) { 75 sizeof(struct rmnet_map_dl_csum_trailer)) {
diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c
index c74a6c56d315..a6ea09416f8d 100644
--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c
+++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c
@@ -1,4 +1,4 @@
1/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. 1/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
2 * 2 *
3 * This program is free software; you can redistribute it and/or modify 3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and 4 * it under the terms of the GNU General Public License version 2 and
@@ -309,7 +309,7 @@ struct sk_buff *rmnet_map_deaggregate(struct sk_buff *skb,
309 maph = (struct rmnet_map_header *)skb->data; 309 maph = (struct rmnet_map_header *)skb->data;
310 packet_len = ntohs(maph->pkt_len) + sizeof(struct rmnet_map_header); 310 packet_len = ntohs(maph->pkt_len) + sizeof(struct rmnet_map_header);
311 311
312 if (port->data_format & RMNET_INGRESS_FORMAT_MAP_CKSUMV4) 312 if (port->data_format & RMNET_FLAGS_INGRESS_MAP_CKSUMV4)
313 packet_len += sizeof(struct rmnet_map_dl_csum_trailer); 313 packet_len += sizeof(struct rmnet_map_dl_csum_trailer);
314 314
315 if (((int)skb->len - (int)packet_len) < 0) 315 if (((int)skb->len - (int)packet_len) < 0)
@@ -323,7 +323,6 @@ struct sk_buff *rmnet_map_deaggregate(struct sk_buff *skb,
323 if (!skbn) 323 if (!skbn)
324 return NULL; 324 return NULL;
325 325
326 skbn->dev = skb->dev;
327 skb_reserve(skbn, RMNET_MAP_DEAGGR_HEADROOM); 326 skb_reserve(skbn, RMNET_MAP_DEAGGR_HEADROOM);
328 skb_put(skbn, packet_len); 327 skb_put(skbn, packet_len);
329 memcpy(skbn->data, skb->data, packet_len); 328 memcpy(skbn->data, skb->data, packet_len);
diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_private.h b/drivers/net/ethernet/qualcomm/rmnet/rmnet_private.h
index de0143eaa05a..b9cc4f85f229 100644
--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_private.h
+++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_private.h
@@ -1,4 +1,4 @@
1/* Copyright (c) 2013-2014, 2016-2017 The Linux Foundation. All rights reserved. 1/* Copyright (c) 2013-2014, 2016-2018 The Linux Foundation. All rights reserved.
2 * 2 *
3 * This program is free software; you can redistribute it and/or modify 3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and 4 * it under the terms of the GNU General Public License version 2 and
@@ -18,12 +18,6 @@
18#define RMNET_NEEDED_HEADROOM 16 18#define RMNET_NEEDED_HEADROOM 16
19#define RMNET_TX_QUEUE_LEN 1000 19#define RMNET_TX_QUEUE_LEN 1000
20 20
21/* Constants */
22#define RMNET_INGRESS_FORMAT_DEAGGREGATION BIT(0)
23#define RMNET_INGRESS_FORMAT_MAP_COMMANDS BIT(1)
24#define RMNET_INGRESS_FORMAT_MAP_CKSUMV4 BIT(2)
25#define RMNET_EGRESS_FORMAT_MAP_CKSUMV4 BIT(3)
26
27/* Replace skb->dev to a virtual rmnet device and pass up the stack */ 21/* Replace skb->dev to a virtual rmnet device and pass up the stack */
28#define RMNET_EPMODE_VND (1) 22#define RMNET_EPMODE_VND (1)
29/* Pass the frame directly to another device with dev_queue_xmit() */ 23/* Pass the frame directly to another device with dev_queue_xmit() */
diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c
index 346d310914df..2ea16a088de8 100644
--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c
+++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c
@@ -1,4 +1,4 @@
1/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. 1/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
2 * 2 *
3 * This program is free software; you can redistribute it and/or modify 3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and 4 * it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index 0bf7d1759250..630409e0337f 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -99,12 +99,12 @@ static const int multicast_filter_limit = 32;
99#define RTL8169_PHY_TIMEOUT (10*HZ) 99#define RTL8169_PHY_TIMEOUT (10*HZ)
100 100
101/* write/read MMIO register */ 101/* write/read MMIO register */
102#define RTL_W8(reg, val8) writeb ((val8), ioaddr + (reg)) 102#define RTL_W8(tp, reg, val8) writeb((val8), tp->mmio_addr + (reg))
103#define RTL_W16(reg, val16) writew ((val16), ioaddr + (reg)) 103#define RTL_W16(tp, reg, val16) writew((val16), tp->mmio_addr + (reg))
104#define RTL_W32(reg, val32) writel ((val32), ioaddr + (reg)) 104#define RTL_W32(tp, reg, val32) writel((val32), tp->mmio_addr + (reg))
105#define RTL_R8(reg) readb (ioaddr + (reg)) 105#define RTL_R8(tp, reg) readb(tp->mmio_addr + (reg))
106#define RTL_R16(reg) readw (ioaddr + (reg)) 106#define RTL_R16(tp, reg) readw(tp->mmio_addr + (reg))
107#define RTL_R32(reg) readl (ioaddr + (reg)) 107#define RTL_R32(tp, reg) readl(tp->mmio_addr + (reg))
108 108
109enum mac_version { 109enum mac_version {
110 RTL_GIGA_MAC_VER_01 = 0, 110 RTL_GIGA_MAC_VER_01 = 0,
@@ -735,12 +735,6 @@ struct ring_info {
735 u8 __pad[sizeof(void *) - sizeof(u32)]; 735 u8 __pad[sizeof(void *) - sizeof(u32)];
736}; 736};
737 737
738enum features {
739 RTL_FEATURE_WOL = (1 << 0),
740 RTL_FEATURE_MSI = (1 << 1),
741 RTL_FEATURE_GMII = (1 << 2),
742};
743
744struct rtl8169_counters { 738struct rtl8169_counters {
745 __le64 tx_packets; 739 __le64 tx_packets;
746 __le64 rx_packets; 740 __le64 rx_packets;
@@ -829,7 +823,7 @@ struct rtl8169_private {
829 void (*phy_reset_enable)(struct rtl8169_private *tp); 823 void (*phy_reset_enable)(struct rtl8169_private *tp);
830 void (*hw_start)(struct net_device *); 824 void (*hw_start)(struct net_device *);
831 unsigned int (*phy_reset_pending)(struct rtl8169_private *tp); 825 unsigned int (*phy_reset_pending)(struct rtl8169_private *tp);
832 unsigned int (*link_ok)(void __iomem *); 826 unsigned int (*link_ok)(struct rtl8169_private *tp);
833 int (*do_ioctl)(struct rtl8169_private *tp, struct mii_ioctl_data *data, int cmd); 827 int (*do_ioctl)(struct rtl8169_private *tp, struct mii_ioctl_data *data, int cmd);
834 bool (*tso_csum)(struct rtl8169_private *, struct sk_buff *, u32 *); 828 bool (*tso_csum)(struct rtl8169_private *, struct sk_buff *, u32 *);
835 829
@@ -893,6 +887,11 @@ MODULE_FIRMWARE(FIRMWARE_8168H_2);
893MODULE_FIRMWARE(FIRMWARE_8107E_1); 887MODULE_FIRMWARE(FIRMWARE_8107E_1);
894MODULE_FIRMWARE(FIRMWARE_8107E_2); 888MODULE_FIRMWARE(FIRMWARE_8107E_2);
895 889
890static inline struct device *tp_to_dev(struct rtl8169_private *tp)
891{
892 return &tp->pci_dev->dev;
893}
894
896static void rtl_lock_work(struct rtl8169_private *tp) 895static void rtl_lock_work(struct rtl8169_private *tp)
897{ 896{
898 mutex_lock(&tp->wk.mutex); 897 mutex_lock(&tp->wk.mutex);
@@ -903,9 +902,9 @@ static void rtl_unlock_work(struct rtl8169_private *tp)
903 mutex_unlock(&tp->wk.mutex); 902 mutex_unlock(&tp->wk.mutex);
904} 903}
905 904
906static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force) 905static void rtl_tx_performance_tweak(struct rtl8169_private *tp, u16 force)
907{ 906{
908 pcie_capability_clear_and_set_word(pdev, PCI_EXP_DEVCTL, 907 pcie_capability_clear_and_set_word(tp->pci_dev, PCI_EXP_DEVCTL,
909 PCI_EXP_DEVCTL_READRQ, force); 908 PCI_EXP_DEVCTL_READRQ, force);
910} 909}
911 910
@@ -984,56 +983,46 @@ static bool rtl_ocp_reg_failure(struct rtl8169_private *tp, u32 reg)
984 983
985DECLARE_RTL_COND(rtl_ocp_gphy_cond) 984DECLARE_RTL_COND(rtl_ocp_gphy_cond)
986{ 985{
987 void __iomem *ioaddr = tp->mmio_addr; 986 return RTL_R32(tp, GPHY_OCP) & OCPAR_FLAG;
988
989 return RTL_R32(GPHY_OCP) & OCPAR_FLAG;
990} 987}
991 988
992static void r8168_phy_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data) 989static void r8168_phy_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data)
993{ 990{
994 void __iomem *ioaddr = tp->mmio_addr;
995
996 if (rtl_ocp_reg_failure(tp, reg)) 991 if (rtl_ocp_reg_failure(tp, reg))
997 return; 992 return;
998 993
999 RTL_W32(GPHY_OCP, OCPAR_FLAG | (reg << 15) | data); 994 RTL_W32(tp, GPHY_OCP, OCPAR_FLAG | (reg << 15) | data);
1000 995
1001 rtl_udelay_loop_wait_low(tp, &rtl_ocp_gphy_cond, 25, 10); 996 rtl_udelay_loop_wait_low(tp, &rtl_ocp_gphy_cond, 25, 10);
1002} 997}
1003 998
1004static u16 r8168_phy_ocp_read(struct rtl8169_private *tp, u32 reg) 999static u16 r8168_phy_ocp_read(struct rtl8169_private *tp, u32 reg)
1005{ 1000{
1006 void __iomem *ioaddr = tp->mmio_addr;
1007
1008 if (rtl_ocp_reg_failure(tp, reg)) 1001 if (rtl_ocp_reg_failure(tp, reg))
1009 return 0; 1002 return 0;
1010 1003
1011 RTL_W32(GPHY_OCP, reg << 15); 1004 RTL_W32(tp, GPHY_OCP, reg << 15);
1012 1005
1013 return rtl_udelay_loop_wait_high(tp, &rtl_ocp_gphy_cond, 25, 10) ? 1006 return rtl_udelay_loop_wait_high(tp, &rtl_ocp_gphy_cond, 25, 10) ?
1014 (RTL_R32(GPHY_OCP) & 0xffff) : ~0; 1007 (RTL_R32(tp, GPHY_OCP) & 0xffff) : ~0;
1015} 1008}
1016 1009
1017static void r8168_mac_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data) 1010static void r8168_mac_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data)
1018{ 1011{
1019 void __iomem *ioaddr = tp->mmio_addr;
1020
1021 if (rtl_ocp_reg_failure(tp, reg)) 1012 if (rtl_ocp_reg_failure(tp, reg))
1022 return; 1013 return;
1023 1014
1024 RTL_W32(OCPDR, OCPAR_FLAG | (reg << 15) | data); 1015 RTL_W32(tp, OCPDR, OCPAR_FLAG | (reg << 15) | data);
1025} 1016}
1026 1017
1027static u16 r8168_mac_ocp_read(struct rtl8169_private *tp, u32 reg) 1018static u16 r8168_mac_ocp_read(struct rtl8169_private *tp, u32 reg)
1028{ 1019{
1029 void __iomem *ioaddr = tp->mmio_addr;
1030
1031 if (rtl_ocp_reg_failure(tp, reg)) 1020 if (rtl_ocp_reg_failure(tp, reg))
1032 return 0; 1021 return 0;
1033 1022
1034 RTL_W32(OCPDR, reg << 15); 1023 RTL_W32(tp, OCPDR, reg << 15);
1035 1024
1036 return RTL_R32(OCPDR); 1025 return RTL_R32(tp, OCPDR);
1037} 1026}
1038 1027
1039#define OCP_STD_PHY_BASE 0xa400 1028#define OCP_STD_PHY_BASE 0xa400
@@ -1076,16 +1065,12 @@ static int mac_mcu_read(struct rtl8169_private *tp, int reg)
1076 1065
1077DECLARE_RTL_COND(rtl_phyar_cond) 1066DECLARE_RTL_COND(rtl_phyar_cond)
1078{ 1067{
1079 void __iomem *ioaddr = tp->mmio_addr; 1068 return RTL_R32(tp, PHYAR) & 0x80000000;
1080
1081 return RTL_R32(PHYAR) & 0x80000000;
1082} 1069}
1083 1070
1084static void r8169_mdio_write(struct rtl8169_private *tp, int reg, int value) 1071static void r8169_mdio_write(struct rtl8169_private *tp, int reg, int value)
1085{ 1072{
1086 void __iomem *ioaddr = tp->mmio_addr; 1073 RTL_W32(tp, PHYAR, 0x80000000 | (reg & 0x1f) << 16 | (value & 0xffff));
1087
1088 RTL_W32(PHYAR, 0x80000000 | (reg & 0x1f) << 16 | (value & 0xffff));
1089 1074
1090 rtl_udelay_loop_wait_low(tp, &rtl_phyar_cond, 25, 20); 1075 rtl_udelay_loop_wait_low(tp, &rtl_phyar_cond, 25, 20);
1091 /* 1076 /*
@@ -1097,13 +1082,12 @@ static void r8169_mdio_write(struct rtl8169_private *tp, int reg, int value)
1097 1082
1098static int r8169_mdio_read(struct rtl8169_private *tp, int reg) 1083static int r8169_mdio_read(struct rtl8169_private *tp, int reg)
1099{ 1084{
1100 void __iomem *ioaddr = tp->mmio_addr;
1101 int value; 1085 int value;
1102 1086
1103 RTL_W32(PHYAR, 0x0 | (reg & 0x1f) << 16); 1087 RTL_W32(tp, PHYAR, 0x0 | (reg & 0x1f) << 16);
1104 1088
1105 value = rtl_udelay_loop_wait_high(tp, &rtl_phyar_cond, 25, 20) ? 1089 value = rtl_udelay_loop_wait_high(tp, &rtl_phyar_cond, 25, 20) ?
1106 RTL_R32(PHYAR) & 0xffff : ~0; 1090 RTL_R32(tp, PHYAR) & 0xffff : ~0;
1107 1091
1108 /* 1092 /*
1109 * According to hardware specs a 20us delay is required after read 1093 * According to hardware specs a 20us delay is required after read
@@ -1116,18 +1100,14 @@ static int r8169_mdio_read(struct rtl8169_private *tp, int reg)
1116 1100
1117DECLARE_RTL_COND(rtl_ocpar_cond) 1101DECLARE_RTL_COND(rtl_ocpar_cond)
1118{ 1102{
1119 void __iomem *ioaddr = tp->mmio_addr; 1103 return RTL_R32(tp, OCPAR) & OCPAR_FLAG;
1120
1121 return RTL_R32(OCPAR) & OCPAR_FLAG;
1122} 1104}
1123 1105
1124static void r8168dp_1_mdio_access(struct rtl8169_private *tp, int reg, u32 data) 1106static void r8168dp_1_mdio_access(struct rtl8169_private *tp, int reg, u32 data)
1125{ 1107{
1126 void __iomem *ioaddr = tp->mmio_addr; 1108 RTL_W32(tp, OCPDR, data | ((reg & OCPDR_REG_MASK) << OCPDR_GPHY_REG_SHIFT));
1127 1109 RTL_W32(tp, OCPAR, OCPAR_GPHY_WRITE_CMD);
1128 RTL_W32(OCPDR, data | ((reg & OCPDR_REG_MASK) << OCPDR_GPHY_REG_SHIFT)); 1110 RTL_W32(tp, EPHY_RXER_NUM, 0);
1129 RTL_W32(OCPAR, OCPAR_GPHY_WRITE_CMD);
1130 RTL_W32(EPHY_RXER_NUM, 0);
1131 1111
1132 rtl_udelay_loop_wait_low(tp, &rtl_ocpar_cond, 1000, 100); 1112 rtl_udelay_loop_wait_low(tp, &rtl_ocpar_cond, 1000, 100);
1133} 1113}
@@ -1140,51 +1120,46 @@ static void r8168dp_1_mdio_write(struct rtl8169_private *tp, int reg, int value)
1140 1120
1141static int r8168dp_1_mdio_read(struct rtl8169_private *tp, int reg) 1121static int r8168dp_1_mdio_read(struct rtl8169_private *tp, int reg)
1142{ 1122{
1143 void __iomem *ioaddr = tp->mmio_addr;
1144
1145 r8168dp_1_mdio_access(tp, reg, OCPDR_READ_CMD); 1123 r8168dp_1_mdio_access(tp, reg, OCPDR_READ_CMD);
1146 1124
1147 mdelay(1); 1125 mdelay(1);
1148 RTL_W32(OCPAR, OCPAR_GPHY_READ_CMD); 1126 RTL_W32(tp, OCPAR, OCPAR_GPHY_READ_CMD);
1149 RTL_W32(EPHY_RXER_NUM, 0); 1127 RTL_W32(tp, EPHY_RXER_NUM, 0);
1150 1128
1151 return rtl_udelay_loop_wait_high(tp, &rtl_ocpar_cond, 1000, 100) ? 1129 return rtl_udelay_loop_wait_high(tp, &rtl_ocpar_cond, 1000, 100) ?
1152 RTL_R32(OCPDR) & OCPDR_DATA_MASK : ~0; 1130 RTL_R32(tp, OCPDR) & OCPDR_DATA_MASK : ~0;
1153} 1131}
1154 1132
1155#define R8168DP_1_MDIO_ACCESS_BIT 0x00020000 1133#define R8168DP_1_MDIO_ACCESS_BIT 0x00020000
1156 1134
1157static void r8168dp_2_mdio_start(void __iomem *ioaddr) 1135static void r8168dp_2_mdio_start(struct rtl8169_private *tp)
1158{ 1136{
1159 RTL_W32(0xd0, RTL_R32(0xd0) & ~R8168DP_1_MDIO_ACCESS_BIT); 1137 RTL_W32(tp, 0xd0, RTL_R32(tp, 0xd0) & ~R8168DP_1_MDIO_ACCESS_BIT);
1160} 1138}
1161 1139
1162static void r8168dp_2_mdio_stop(void __iomem *ioaddr) 1140static void r8168dp_2_mdio_stop(struct rtl8169_private *tp)
1163{ 1141{
1164 RTL_W32(0xd0, RTL_R32(0xd0) | R8168DP_1_MDIO_ACCESS_BIT); 1142 RTL_W32(tp, 0xd0, RTL_R32(tp, 0xd0) | R8168DP_1_MDIO_ACCESS_BIT);
1165} 1143}
1166 1144
1167static void r8168dp_2_mdio_write(struct rtl8169_private *tp, int reg, int value) 1145static void r8168dp_2_mdio_write(struct rtl8169_private *tp, int reg, int value)
1168{ 1146{
1169 void __iomem *ioaddr = tp->mmio_addr; 1147 r8168dp_2_mdio_start(tp);
1170
1171 r8168dp_2_mdio_start(ioaddr);
1172 1148
1173 r8169_mdio_write(tp, reg, value); 1149 r8169_mdio_write(tp, reg, value);
1174 1150
1175 r8168dp_2_mdio_stop(ioaddr); 1151 r8168dp_2_mdio_stop(tp);
1176} 1152}
1177 1153
1178static int r8168dp_2_mdio_read(struct rtl8169_private *tp, int reg) 1154static int r8168dp_2_mdio_read(struct rtl8169_private *tp, int reg)
1179{ 1155{
1180 void __iomem *ioaddr = tp->mmio_addr;
1181 int value; 1156 int value;
1182 1157
1183 r8168dp_2_mdio_start(ioaddr); 1158 r8168dp_2_mdio_start(tp);
1184 1159
1185 value = r8169_mdio_read(tp, reg); 1160 value = r8169_mdio_read(tp, reg);
1186 1161
1187 r8168dp_2_mdio_stop(ioaddr); 1162 r8168dp_2_mdio_stop(tp);
1188 1163
1189 return value; 1164 return value;
1190} 1165}
@@ -1229,16 +1204,12 @@ static int rtl_mdio_read(struct net_device *dev, int phy_id, int location)
1229 1204
1230DECLARE_RTL_COND(rtl_ephyar_cond) 1205DECLARE_RTL_COND(rtl_ephyar_cond)
1231{ 1206{
1232 void __iomem *ioaddr = tp->mmio_addr; 1207 return RTL_R32(tp, EPHYAR) & EPHYAR_FLAG;
1233
1234 return RTL_R32(EPHYAR) & EPHYAR_FLAG;
1235} 1208}
1236 1209
1237static void rtl_ephy_write(struct rtl8169_private *tp, int reg_addr, int value) 1210static void rtl_ephy_write(struct rtl8169_private *tp, int reg_addr, int value)
1238{ 1211{
1239 void __iomem *ioaddr = tp->mmio_addr; 1212 RTL_W32(tp, EPHYAR, EPHYAR_WRITE_CMD | (value & EPHYAR_DATA_MASK) |
1240
1241 RTL_W32(EPHYAR, EPHYAR_WRITE_CMD | (value & EPHYAR_DATA_MASK) |
1242 (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT); 1213 (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT);
1243 1214
1244 rtl_udelay_loop_wait_low(tp, &rtl_ephyar_cond, 10, 100); 1215 rtl_udelay_loop_wait_low(tp, &rtl_ephyar_cond, 10, 100);
@@ -1248,41 +1219,33 @@ static void rtl_ephy_write(struct rtl8169_private *tp, int reg_addr, int value)
1248 1219
1249static u16 rtl_ephy_read(struct rtl8169_private *tp, int reg_addr) 1220static u16 rtl_ephy_read(struct rtl8169_private *tp, int reg_addr)
1250{ 1221{
1251 void __iomem *ioaddr = tp->mmio_addr; 1222 RTL_W32(tp, EPHYAR, (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT);
1252
1253 RTL_W32(EPHYAR, (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT);
1254 1223
1255 return rtl_udelay_loop_wait_high(tp, &rtl_ephyar_cond, 10, 100) ? 1224 return rtl_udelay_loop_wait_high(tp, &rtl_ephyar_cond, 10, 100) ?
1256 RTL_R32(EPHYAR) & EPHYAR_DATA_MASK : ~0; 1225 RTL_R32(tp, EPHYAR) & EPHYAR_DATA_MASK : ~0;
1257} 1226}
1258 1227
1259DECLARE_RTL_COND(rtl_eriar_cond) 1228DECLARE_RTL_COND(rtl_eriar_cond)
1260{ 1229{
1261 void __iomem *ioaddr = tp->mmio_addr; 1230 return RTL_R32(tp, ERIAR) & ERIAR_FLAG;
1262
1263 return RTL_R32(ERIAR) & ERIAR_FLAG;
1264} 1231}
1265 1232
1266static void rtl_eri_write(struct rtl8169_private *tp, int addr, u32 mask, 1233static void rtl_eri_write(struct rtl8169_private *tp, int addr, u32 mask,
1267 u32 val, int type) 1234 u32 val, int type)
1268{ 1235{
1269 void __iomem *ioaddr = tp->mmio_addr;
1270
1271 BUG_ON((addr & 3) || (mask == 0)); 1236 BUG_ON((addr & 3) || (mask == 0));
1272 RTL_W32(ERIDR, val); 1237 RTL_W32(tp, ERIDR, val);
1273 RTL_W32(ERIAR, ERIAR_WRITE_CMD | type | mask | addr); 1238 RTL_W32(tp, ERIAR, ERIAR_WRITE_CMD | type | mask | addr);
1274 1239
1275 rtl_udelay_loop_wait_low(tp, &rtl_eriar_cond, 100, 100); 1240 rtl_udelay_loop_wait_low(tp, &rtl_eriar_cond, 100, 100);
1276} 1241}
1277 1242
1278static u32 rtl_eri_read(struct rtl8169_private *tp, int addr, int type) 1243static u32 rtl_eri_read(struct rtl8169_private *tp, int addr, int type)
1279{ 1244{
1280 void __iomem *ioaddr = tp->mmio_addr; 1245 RTL_W32(tp, ERIAR, ERIAR_READ_CMD | type | ERIAR_MASK_1111 | addr);
1281
1282 RTL_W32(ERIAR, ERIAR_READ_CMD | type | ERIAR_MASK_1111 | addr);
1283 1246
1284 return rtl_udelay_loop_wait_high(tp, &rtl_eriar_cond, 100, 100) ? 1247 return rtl_udelay_loop_wait_high(tp, &rtl_eriar_cond, 100, 100) ?
1285 RTL_R32(ERIDR) : ~0; 1248 RTL_R32(tp, ERIDR) : ~0;
1286} 1249}
1287 1250
1288static void rtl_w0w1_eri(struct rtl8169_private *tp, int addr, u32 mask, u32 p, 1251static void rtl_w0w1_eri(struct rtl8169_private *tp, int addr, u32 mask, u32 p,
@@ -1296,11 +1259,9 @@ static void rtl_w0w1_eri(struct rtl8169_private *tp, int addr, u32 mask, u32 p,
1296 1259
1297static u32 r8168dp_ocp_read(struct rtl8169_private *tp, u8 mask, u16 reg) 1260static u32 r8168dp_ocp_read(struct rtl8169_private *tp, u8 mask, u16 reg)
1298{ 1261{
1299 void __iomem *ioaddr = tp->mmio_addr; 1262 RTL_W32(tp, OCPAR, ((u32)mask & 0x0f) << 12 | (reg & 0x0fff));
1300
1301 RTL_W32(OCPAR, ((u32)mask & 0x0f) << 12 | (reg & 0x0fff));
1302 return rtl_udelay_loop_wait_high(tp, &rtl_ocpar_cond, 100, 20) ? 1263 return rtl_udelay_loop_wait_high(tp, &rtl_ocpar_cond, 100, 20) ?
1303 RTL_R32(OCPDR) : ~0; 1264 RTL_R32(tp, OCPDR) : ~0;
1304} 1265}
1305 1266
1306static u32 r8168ep_ocp_read(struct rtl8169_private *tp, u8 mask, u16 reg) 1267static u32 r8168ep_ocp_read(struct rtl8169_private *tp, u8 mask, u16 reg)
@@ -1328,10 +1289,8 @@ static u32 ocp_read(struct rtl8169_private *tp, u8 mask, u16 reg)
1328static void r8168dp_ocp_write(struct rtl8169_private *tp, u8 mask, u16 reg, 1289static void r8168dp_ocp_write(struct rtl8169_private *tp, u8 mask, u16 reg,
1329 u32 data) 1290 u32 data)
1330{ 1291{
1331 void __iomem *ioaddr = tp->mmio_addr; 1292 RTL_W32(tp, OCPDR, data);
1332 1293 RTL_W32(tp, OCPAR, OCPAR_FLAG | ((u32)mask & 0x0f) << 12 | (reg & 0x0fff));
1333 RTL_W32(OCPDR, data);
1334 RTL_W32(OCPAR, OCPAR_FLAG | ((u32)mask & 0x0f) << 12 | (reg & 0x0fff));
1335 rtl_udelay_loop_wait_low(tp, &rtl_ocpar_cond, 100, 20); 1294 rtl_udelay_loop_wait_low(tp, &rtl_ocpar_cond, 100, 20);
1336} 1295}
1337 1296
@@ -1393,19 +1352,15 @@ DECLARE_RTL_COND(rtl_ep_ocp_read_cond)
1393 1352
1394DECLARE_RTL_COND(rtl_ocp_tx_cond) 1353DECLARE_RTL_COND(rtl_ocp_tx_cond)
1395{ 1354{
1396 void __iomem *ioaddr = tp->mmio_addr; 1355 return RTL_R8(tp, IBISR0) & 0x20;
1397
1398 return RTL_R8(IBISR0) & 0x20;
1399} 1356}
1400 1357
1401static void rtl8168ep_stop_cmac(struct rtl8169_private *tp) 1358static void rtl8168ep_stop_cmac(struct rtl8169_private *tp)
1402{ 1359{
1403 void __iomem *ioaddr = tp->mmio_addr; 1360 RTL_W8(tp, IBCR2, RTL_R8(tp, IBCR2) & ~0x01);
1404
1405 RTL_W8(IBCR2, RTL_R8(IBCR2) & ~0x01);
1406 rtl_msleep_loop_wait_high(tp, &rtl_ocp_tx_cond, 50, 2000); 1361 rtl_msleep_loop_wait_high(tp, &rtl_ocp_tx_cond, 50, 2000);
1407 RTL_W8(IBISR0, RTL_R8(IBISR0) | 0x20); 1362 RTL_W8(tp, IBISR0, RTL_R8(tp, IBISR0) | 0x20);
1408 RTL_W8(IBCR0, RTL_R8(IBCR0) & ~0x01); 1363 RTL_W8(tp, IBCR0, RTL_R8(tp, IBCR0) & ~0x01);
1409} 1364}
1410 1365
1411static void rtl8168dp_driver_start(struct rtl8169_private *tp) 1366static void rtl8168dp_driver_start(struct rtl8169_private *tp)
@@ -1473,19 +1428,19 @@ static void rtl8168_driver_stop(struct rtl8169_private *tp)
1473 } 1428 }
1474} 1429}
1475 1430
1476static int r8168dp_check_dash(struct rtl8169_private *tp) 1431static bool r8168dp_check_dash(struct rtl8169_private *tp)
1477{ 1432{
1478 u16 reg = rtl8168_get_ocp_reg(tp); 1433 u16 reg = rtl8168_get_ocp_reg(tp);
1479 1434
1480 return (ocp_read(tp, 0x0f, reg) & 0x00008000) ? 1 : 0; 1435 return !!(ocp_read(tp, 0x0f, reg) & 0x00008000);
1481} 1436}
1482 1437
1483static int r8168ep_check_dash(struct rtl8169_private *tp) 1438static bool r8168ep_check_dash(struct rtl8169_private *tp)
1484{ 1439{
1485 return (ocp_read(tp, 0x0f, 0x128) & 0x00000001) ? 1 : 0; 1440 return !!(ocp_read(tp, 0x0f, 0x128) & 0x00000001);
1486} 1441}
1487 1442
1488static int r8168_check_dash(struct rtl8169_private *tp) 1443static bool r8168_check_dash(struct rtl8169_private *tp)
1489{ 1444{
1490 switch (tp->mac_version) { 1445 switch (tp->mac_version) {
1491 case RTL_GIGA_MAC_VER_27: 1446 case RTL_GIGA_MAC_VER_27:
@@ -1497,7 +1452,7 @@ static int r8168_check_dash(struct rtl8169_private *tp)
1497 case RTL_GIGA_MAC_VER_51: 1452 case RTL_GIGA_MAC_VER_51:
1498 return r8168ep_check_dash(tp); 1453 return r8168ep_check_dash(tp);
1499 default: 1454 default:
1500 return 0; 1455 return false;
1501 } 1456 }
1502} 1457}
1503 1458
@@ -1518,49 +1473,37 @@ static void rtl_write_exgmac_batch(struct rtl8169_private *tp,
1518 1473
1519DECLARE_RTL_COND(rtl_efusear_cond) 1474DECLARE_RTL_COND(rtl_efusear_cond)
1520{ 1475{
1521 void __iomem *ioaddr = tp->mmio_addr; 1476 return RTL_R32(tp, EFUSEAR) & EFUSEAR_FLAG;
1522
1523 return RTL_R32(EFUSEAR) & EFUSEAR_FLAG;
1524} 1477}
1525 1478
1526static u8 rtl8168d_efuse_read(struct rtl8169_private *tp, int reg_addr) 1479static u8 rtl8168d_efuse_read(struct rtl8169_private *tp, int reg_addr)
1527{ 1480{
1528 void __iomem *ioaddr = tp->mmio_addr; 1481 RTL_W32(tp, EFUSEAR, (reg_addr & EFUSEAR_REG_MASK) << EFUSEAR_REG_SHIFT);
1529
1530 RTL_W32(EFUSEAR, (reg_addr & EFUSEAR_REG_MASK) << EFUSEAR_REG_SHIFT);
1531 1482
1532 return rtl_udelay_loop_wait_high(tp, &rtl_efusear_cond, 100, 300) ? 1483 return rtl_udelay_loop_wait_high(tp, &rtl_efusear_cond, 100, 300) ?
1533 RTL_R32(EFUSEAR) & EFUSEAR_DATA_MASK : ~0; 1484 RTL_R32(tp, EFUSEAR) & EFUSEAR_DATA_MASK : ~0;
1534} 1485}
1535 1486
1536static u16 rtl_get_events(struct rtl8169_private *tp) 1487static u16 rtl_get_events(struct rtl8169_private *tp)
1537{ 1488{
1538 void __iomem *ioaddr = tp->mmio_addr; 1489 return RTL_R16(tp, IntrStatus);
1539
1540 return RTL_R16(IntrStatus);
1541} 1490}
1542 1491
1543static void rtl_ack_events(struct rtl8169_private *tp, u16 bits) 1492static void rtl_ack_events(struct rtl8169_private *tp, u16 bits)
1544{ 1493{
1545 void __iomem *ioaddr = tp->mmio_addr; 1494 RTL_W16(tp, IntrStatus, bits);
1546
1547 RTL_W16(IntrStatus, bits);
1548 mmiowb(); 1495 mmiowb();
1549} 1496}
1550 1497
1551static void rtl_irq_disable(struct rtl8169_private *tp) 1498static void rtl_irq_disable(struct rtl8169_private *tp)
1552{ 1499{
1553 void __iomem *ioaddr = tp->mmio_addr; 1500 RTL_W16(tp, IntrMask, 0);
1554
1555 RTL_W16(IntrMask, 0);
1556 mmiowb(); 1501 mmiowb();
1557} 1502}
1558 1503
1559static void rtl_irq_enable(struct rtl8169_private *tp, u16 bits) 1504static void rtl_irq_enable(struct rtl8169_private *tp, u16 bits)
1560{ 1505{
1561 void __iomem *ioaddr = tp->mmio_addr; 1506 RTL_W16(tp, IntrMask, bits);
1562
1563 RTL_W16(IntrMask, bits);
1564} 1507}
1565 1508
1566#define RTL_EVENT_NAPI_RX (RxOK | RxErr) 1509#define RTL_EVENT_NAPI_RX (RxOK | RxErr)
@@ -1574,18 +1517,14 @@ static void rtl_irq_enable_all(struct rtl8169_private *tp)
1574 1517
1575static void rtl8169_irq_mask_and_ack(struct rtl8169_private *tp) 1518static void rtl8169_irq_mask_and_ack(struct rtl8169_private *tp)
1576{ 1519{
1577 void __iomem *ioaddr = tp->mmio_addr;
1578
1579 rtl_irq_disable(tp); 1520 rtl_irq_disable(tp);
1580 rtl_ack_events(tp, RTL_EVENT_NAPI | tp->event_slow); 1521 rtl_ack_events(tp, RTL_EVENT_NAPI | tp->event_slow);
1581 RTL_R8(ChipCmd); 1522 RTL_R8(tp, ChipCmd);
1582} 1523}
1583 1524
1584static unsigned int rtl8169_tbi_reset_pending(struct rtl8169_private *tp) 1525static unsigned int rtl8169_tbi_reset_pending(struct rtl8169_private *tp)
1585{ 1526{
1586 void __iomem *ioaddr = tp->mmio_addr; 1527 return RTL_R32(tp, TBICSR) & TBIReset;
1587
1588 return RTL_R32(TBICSR) & TBIReset;
1589} 1528}
1590 1529
1591static unsigned int rtl8169_xmii_reset_pending(struct rtl8169_private *tp) 1530static unsigned int rtl8169_xmii_reset_pending(struct rtl8169_private *tp)
@@ -1593,21 +1532,19 @@ static unsigned int rtl8169_xmii_reset_pending(struct rtl8169_private *tp)
1593 return rtl_readphy(tp, MII_BMCR) & BMCR_RESET; 1532 return rtl_readphy(tp, MII_BMCR) & BMCR_RESET;
1594} 1533}
1595 1534
1596static unsigned int rtl8169_tbi_link_ok(void __iomem *ioaddr) 1535static unsigned int rtl8169_tbi_link_ok(struct rtl8169_private *tp)
1597{ 1536{
1598 return RTL_R32(TBICSR) & TBILinkOk; 1537 return RTL_R32(tp, TBICSR) & TBILinkOk;
1599} 1538}
1600 1539
1601static unsigned int rtl8169_xmii_link_ok(void __iomem *ioaddr) 1540static unsigned int rtl8169_xmii_link_ok(struct rtl8169_private *tp)
1602{ 1541{
1603 return RTL_R8(PHYstatus) & LinkStatus; 1542 return RTL_R8(tp, PHYstatus) & LinkStatus;
1604} 1543}
1605 1544
1606static void rtl8169_tbi_reset_enable(struct rtl8169_private *tp) 1545static void rtl8169_tbi_reset_enable(struct rtl8169_private *tp)
1607{ 1546{
1608 void __iomem *ioaddr = tp->mmio_addr; 1547 RTL_W32(tp, TBICSR, RTL_R32(tp, TBICSR) | TBIReset);
1609
1610 RTL_W32(TBICSR, RTL_R32(TBICSR) | TBIReset);
1611} 1548}
1612 1549
1613static void rtl8169_xmii_reset_enable(struct rtl8169_private *tp) 1550static void rtl8169_xmii_reset_enable(struct rtl8169_private *tp)
@@ -1620,7 +1557,6 @@ static void rtl8169_xmii_reset_enable(struct rtl8169_private *tp)
1620 1557
1621static void rtl_link_chg_patch(struct rtl8169_private *tp) 1558static void rtl_link_chg_patch(struct rtl8169_private *tp)
1622{ 1559{
1623 void __iomem *ioaddr = tp->mmio_addr;
1624 struct net_device *dev = tp->dev; 1560 struct net_device *dev = tp->dev;
1625 1561
1626 if (!netif_running(dev)) 1562 if (!netif_running(dev))
@@ -1628,12 +1564,12 @@ static void rtl_link_chg_patch(struct rtl8169_private *tp)
1628 1564
1629 if (tp->mac_version == RTL_GIGA_MAC_VER_34 || 1565 if (tp->mac_version == RTL_GIGA_MAC_VER_34 ||
1630 tp->mac_version == RTL_GIGA_MAC_VER_38) { 1566 tp->mac_version == RTL_GIGA_MAC_VER_38) {
1631 if (RTL_R8(PHYstatus) & _1000bpsF) { 1567 if (RTL_R8(tp, PHYstatus) & _1000bpsF) {
1632 rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x00000011, 1568 rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x00000011,
1633 ERIAR_EXGMAC); 1569 ERIAR_EXGMAC);
1634 rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x00000005, 1570 rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x00000005,
1635 ERIAR_EXGMAC); 1571 ERIAR_EXGMAC);
1636 } else if (RTL_R8(PHYstatus) & _100bps) { 1572 } else if (RTL_R8(tp, PHYstatus) & _100bps) {
1637 rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x0000001f, 1573 rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x0000001f,
1638 ERIAR_EXGMAC); 1574 ERIAR_EXGMAC);
1639 rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x00000005, 1575 rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x00000005,
@@ -1651,7 +1587,7 @@ static void rtl_link_chg_patch(struct rtl8169_private *tp)
1651 ERIAR_EXGMAC); 1587 ERIAR_EXGMAC);
1652 } else if (tp->mac_version == RTL_GIGA_MAC_VER_35 || 1588 } else if (tp->mac_version == RTL_GIGA_MAC_VER_35 ||
1653 tp->mac_version == RTL_GIGA_MAC_VER_36) { 1589 tp->mac_version == RTL_GIGA_MAC_VER_36) {
1654 if (RTL_R8(PHYstatus) & _1000bpsF) { 1590 if (RTL_R8(tp, PHYstatus) & _1000bpsF) {
1655 rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x00000011, 1591 rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x00000011,
1656 ERIAR_EXGMAC); 1592 ERIAR_EXGMAC);
1657 rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x00000005, 1593 rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x00000005,
@@ -1663,7 +1599,7 @@ static void rtl_link_chg_patch(struct rtl8169_private *tp)
1663 ERIAR_EXGMAC); 1599 ERIAR_EXGMAC);
1664 } 1600 }
1665 } else if (tp->mac_version == RTL_GIGA_MAC_VER_37) { 1601 } else if (tp->mac_version == RTL_GIGA_MAC_VER_37) {
1666 if (RTL_R8(PHYstatus) & _10bps) { 1602 if (RTL_R8(tp, PHYstatus) & _10bps) {
1667 rtl_eri_write(tp, 0x1d0, ERIAR_MASK_0011, 0x4d02, 1603 rtl_eri_write(tp, 0x1d0, ERIAR_MASK_0011, 0x4d02,
1668 ERIAR_EXGMAC); 1604 ERIAR_EXGMAC);
1669 rtl_eri_write(tp, 0x1dc, ERIAR_MASK_0011, 0x0060, 1605 rtl_eri_write(tp, 0x1dc, ERIAR_MASK_0011, 0x0060,
@@ -1676,20 +1612,21 @@ static void rtl_link_chg_patch(struct rtl8169_private *tp)
1676} 1612}
1677 1613
1678static void rtl8169_check_link_status(struct net_device *dev, 1614static void rtl8169_check_link_status(struct net_device *dev,
1679 struct rtl8169_private *tp, 1615 struct rtl8169_private *tp)
1680 void __iomem *ioaddr)
1681{ 1616{
1682 if (tp->link_ok(ioaddr)) { 1617 struct device *d = tp_to_dev(tp);
1618
1619 if (tp->link_ok(tp)) {
1683 rtl_link_chg_patch(tp); 1620 rtl_link_chg_patch(tp);
1684 /* This is to cancel a scheduled suspend if there's one. */ 1621 /* This is to cancel a scheduled suspend if there's one. */
1685 pm_request_resume(&tp->pci_dev->dev); 1622 pm_request_resume(d);
1686 netif_carrier_on(dev); 1623 netif_carrier_on(dev);
1687 if (net_ratelimit()) 1624 if (net_ratelimit())
1688 netif_info(tp, ifup, dev, "link up\n"); 1625 netif_info(tp, ifup, dev, "link up\n");
1689 } else { 1626 } else {
1690 netif_carrier_off(dev); 1627 netif_carrier_off(dev);
1691 netif_info(tp, ifdown, dev, "link down\n"); 1628 netif_info(tp, ifdown, dev, "link down\n");
1692 pm_runtime_idle(&tp->pci_dev->dev); 1629 pm_runtime_idle(d);
1693 } 1630 }
1694} 1631}
1695 1632
@@ -1697,15 +1634,14 @@ static void rtl8169_check_link_status(struct net_device *dev,
1697 1634
1698static u32 __rtl8169_get_wol(struct rtl8169_private *tp) 1635static u32 __rtl8169_get_wol(struct rtl8169_private *tp)
1699{ 1636{
1700 void __iomem *ioaddr = tp->mmio_addr;
1701 u8 options; 1637 u8 options;
1702 u32 wolopts = 0; 1638 u32 wolopts = 0;
1703 1639
1704 options = RTL_R8(Config1); 1640 options = RTL_R8(tp, Config1);
1705 if (!(options & PMEnable)) 1641 if (!(options & PMEnable))
1706 return 0; 1642 return 0;
1707 1643
1708 options = RTL_R8(Config3); 1644 options = RTL_R8(tp, Config3);
1709 if (options & LinkUp) 1645 if (options & LinkUp)
1710 wolopts |= WAKE_PHY; 1646 wolopts |= WAKE_PHY;
1711 switch (tp->mac_version) { 1647 switch (tp->mac_version) {
@@ -1735,7 +1671,7 @@ static u32 __rtl8169_get_wol(struct rtl8169_private *tp)
1735 break; 1671 break;
1736 } 1672 }
1737 1673
1738 options = RTL_R8(Config5); 1674 options = RTL_R8(tp, Config5);
1739 if (options & UWF) 1675 if (options & UWF)
1740 wolopts |= WAKE_UCAST; 1676 wolopts |= WAKE_UCAST;
1741 if (options & BWF) 1677 if (options & BWF)
@@ -1749,7 +1685,7 @@ static u32 __rtl8169_get_wol(struct rtl8169_private *tp)
1749static void rtl8169_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) 1685static void rtl8169_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
1750{ 1686{
1751 struct rtl8169_private *tp = netdev_priv(dev); 1687 struct rtl8169_private *tp = netdev_priv(dev);
1752 struct device *d = &tp->pci_dev->dev; 1688 struct device *d = tp_to_dev(tp);
1753 1689
1754 pm_runtime_get_noresume(d); 1690 pm_runtime_get_noresume(d);
1755 1691
@@ -1768,7 +1704,6 @@ static void rtl8169_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
1768 1704
1769static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts) 1705static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts)
1770{ 1706{
1771 void __iomem *ioaddr = tp->mmio_addr;
1772 unsigned int i, tmp; 1707 unsigned int i, tmp;
1773 static const struct { 1708 static const struct {
1774 u32 opt; 1709 u32 opt;
@@ -1784,7 +1719,7 @@ static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts)
1784 }; 1719 };
1785 u8 options; 1720 u8 options;
1786 1721
1787 RTL_W8(Cfg9346, Cfg9346_Unlock); 1722 RTL_W8(tp, Cfg9346, Cfg9346_Unlock);
1788 1723
1789 switch (tp->mac_version) { 1724 switch (tp->mac_version) {
1790 case RTL_GIGA_MAC_VER_34: 1725 case RTL_GIGA_MAC_VER_34:
@@ -1826,43 +1761,39 @@ static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts)
1826 } 1761 }
1827 1762
1828 for (i = 0; i < tmp; i++) { 1763 for (i = 0; i < tmp; i++) {
1829 options = RTL_R8(cfg[i].reg) & ~cfg[i].mask; 1764 options = RTL_R8(tp, cfg[i].reg) & ~cfg[i].mask;
1830 if (wolopts & cfg[i].opt) 1765 if (wolopts & cfg[i].opt)
1831 options |= cfg[i].mask; 1766 options |= cfg[i].mask;
1832 RTL_W8(cfg[i].reg, options); 1767 RTL_W8(tp, cfg[i].reg, options);
1833 } 1768 }
1834 1769
1835 switch (tp->mac_version) { 1770 switch (tp->mac_version) {
1836 case RTL_GIGA_MAC_VER_01 ... RTL_GIGA_MAC_VER_17: 1771 case RTL_GIGA_MAC_VER_01 ... RTL_GIGA_MAC_VER_17:
1837 options = RTL_R8(Config1) & ~PMEnable; 1772 options = RTL_R8(tp, Config1) & ~PMEnable;
1838 if (wolopts) 1773 if (wolopts)
1839 options |= PMEnable; 1774 options |= PMEnable;
1840 RTL_W8(Config1, options); 1775 RTL_W8(tp, Config1, options);
1841 break; 1776 break;
1842 default: 1777 default:
1843 options = RTL_R8(Config2) & ~PME_SIGNAL; 1778 options = RTL_R8(tp, Config2) & ~PME_SIGNAL;
1844 if (wolopts) 1779 if (wolopts)
1845 options |= PME_SIGNAL; 1780 options |= PME_SIGNAL;
1846 RTL_W8(Config2, options); 1781 RTL_W8(tp, Config2, options);
1847 break; 1782 break;
1848 } 1783 }
1849 1784
1850 RTL_W8(Cfg9346, Cfg9346_Lock); 1785 RTL_W8(tp, Cfg9346, Cfg9346_Lock);
1851} 1786}
1852 1787
1853static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) 1788static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
1854{ 1789{
1855 struct rtl8169_private *tp = netdev_priv(dev); 1790 struct rtl8169_private *tp = netdev_priv(dev);
1856 struct device *d = &tp->pci_dev->dev; 1791 struct device *d = tp_to_dev(tp);
1857 1792
1858 pm_runtime_get_noresume(d); 1793 pm_runtime_get_noresume(d);
1859 1794
1860 rtl_lock_work(tp); 1795 rtl_lock_work(tp);
1861 1796
1862 if (wol->wolopts)
1863 tp->features |= RTL_FEATURE_WOL;
1864 else
1865 tp->features &= ~RTL_FEATURE_WOL;
1866 if (pm_runtime_active(d)) 1797 if (pm_runtime_active(d))
1867 __rtl8169_set_wol(tp, wol->wolopts); 1798 __rtl8169_set_wol(tp, wol->wolopts);
1868 else 1799 else
@@ -1870,7 +1801,7 @@ static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
1870 1801
1871 rtl_unlock_work(tp); 1802 rtl_unlock_work(tp);
1872 1803
1873 device_set_wakeup_enable(&tp->pci_dev->dev, wol->wolopts); 1804 device_set_wakeup_enable(d, wol->wolopts);
1874 1805
1875 pm_runtime_put_noidle(d); 1806 pm_runtime_put_noidle(d);
1876 1807
@@ -1906,16 +1837,15 @@ static int rtl8169_set_speed_tbi(struct net_device *dev,
1906 u8 autoneg, u16 speed, u8 duplex, u32 ignored) 1837 u8 autoneg, u16 speed, u8 duplex, u32 ignored)
1907{ 1838{
1908 struct rtl8169_private *tp = netdev_priv(dev); 1839 struct rtl8169_private *tp = netdev_priv(dev);
1909 void __iomem *ioaddr = tp->mmio_addr;
1910 int ret = 0; 1840 int ret = 0;
1911 u32 reg; 1841 u32 reg;
1912 1842
1913 reg = RTL_R32(TBICSR); 1843 reg = RTL_R32(tp, TBICSR);
1914 if ((autoneg == AUTONEG_DISABLE) && (speed == SPEED_1000) && 1844 if ((autoneg == AUTONEG_DISABLE) && (speed == SPEED_1000) &&
1915 (duplex == DUPLEX_FULL)) { 1845 (duplex == DUPLEX_FULL)) {
1916 RTL_W32(TBICSR, reg & ~(TBINwEnable | TBINwRestart)); 1846 RTL_W32(tp, TBICSR, reg & ~(TBINwEnable | TBINwRestart));
1917 } else if (autoneg == AUTONEG_ENABLE) 1847 } else if (autoneg == AUTONEG_ENABLE)
1918 RTL_W32(TBICSR, reg | TBINwEnable | TBINwRestart); 1848 RTL_W32(tp, TBICSR, reg | TBINwEnable | TBINwRestart);
1919 else { 1849 else {
1920 netif_warn(tp, link, dev, 1850 netif_warn(tp, link, dev,
1921 "incorrect speed setting refused in TBI mode\n"); 1851 "incorrect speed setting refused in TBI mode\n");
@@ -2040,16 +1970,15 @@ static void __rtl8169_set_features(struct net_device *dev,
2040 netdev_features_t features) 1970 netdev_features_t features)
2041{ 1971{
2042 struct rtl8169_private *tp = netdev_priv(dev); 1972 struct rtl8169_private *tp = netdev_priv(dev);
2043 void __iomem *ioaddr = tp->mmio_addr;
2044 u32 rx_config; 1973 u32 rx_config;
2045 1974
2046 rx_config = RTL_R32(RxConfig); 1975 rx_config = RTL_R32(tp, RxConfig);
2047 if (features & NETIF_F_RXALL) 1976 if (features & NETIF_F_RXALL)
2048 rx_config |= (AcceptErr | AcceptRunt); 1977 rx_config |= (AcceptErr | AcceptRunt);
2049 else 1978 else
2050 rx_config &= ~(AcceptErr | AcceptRunt); 1979 rx_config &= ~(AcceptErr | AcceptRunt);
2051 1980
2052 RTL_W32(RxConfig, rx_config); 1981 RTL_W32(tp, RxConfig, rx_config);
2053 1982
2054 if (features & NETIF_F_RXCSUM) 1983 if (features & NETIF_F_RXCSUM)
2055 tp->cp_cmd |= RxChkSum; 1984 tp->cp_cmd |= RxChkSum;
@@ -2061,10 +1990,10 @@ static void __rtl8169_set_features(struct net_device *dev,
2061 else 1990 else
2062 tp->cp_cmd &= ~RxVlan; 1991 tp->cp_cmd &= ~RxVlan;
2063 1992
2064 tp->cp_cmd |= RTL_R16(CPlusCmd) & ~(RxVlan | RxChkSum); 1993 tp->cp_cmd |= RTL_R16(tp, CPlusCmd) & ~(RxVlan | RxChkSum);
2065 1994
2066 RTL_W16(CPlusCmd, tp->cp_cmd); 1995 RTL_W16(tp, CPlusCmd, tp->cp_cmd);
2067 RTL_R16(CPlusCmd); 1996 RTL_R16(tp, CPlusCmd);
2068} 1997}
2069 1998
2070static int rtl8169_set_features(struct net_device *dev, 1999static int rtl8169_set_features(struct net_device *dev,
@@ -2101,7 +2030,6 @@ static int rtl8169_get_link_ksettings_tbi(struct net_device *dev,
2101 struct ethtool_link_ksettings *cmd) 2030 struct ethtool_link_ksettings *cmd)
2102{ 2031{
2103 struct rtl8169_private *tp = netdev_priv(dev); 2032 struct rtl8169_private *tp = netdev_priv(dev);
2104 void __iomem *ioaddr = tp->mmio_addr;
2105 u32 status; 2033 u32 status;
2106 u32 supported, advertising; 2034 u32 supported, advertising;
2107 2035
@@ -2109,7 +2037,7 @@ static int rtl8169_get_link_ksettings_tbi(struct net_device *dev,
2109 SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_FIBRE; 2037 SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_FIBRE;
2110 cmd->base.port = PORT_FIBRE; 2038 cmd->base.port = PORT_FIBRE;
2111 2039
2112 status = RTL_R32(TBICSR); 2040 status = RTL_R32(tp, TBICSR);
2113 advertising = (status & TBINwEnable) ? ADVERTISED_Autoneg : 0; 2041 advertising = (status & TBINwEnable) ? ADVERTISED_Autoneg : 0;
2114 cmd->base.autoneg = !!(status & TBINwEnable); 2042 cmd->base.autoneg = !!(status & TBINwEnable);
2115 2043
@@ -2224,23 +2152,20 @@ static int rtl8169_get_sset_count(struct net_device *dev, int sset)
2224 2152
2225DECLARE_RTL_COND(rtl_counters_cond) 2153DECLARE_RTL_COND(rtl_counters_cond)
2226{ 2154{
2227 void __iomem *ioaddr = tp->mmio_addr; 2155 return RTL_R32(tp, CounterAddrLow) & (CounterReset | CounterDump);
2228
2229 return RTL_R32(CounterAddrLow) & (CounterReset | CounterDump);
2230} 2156}
2231 2157
2232static bool rtl8169_do_counters(struct net_device *dev, u32 counter_cmd) 2158static bool rtl8169_do_counters(struct net_device *dev, u32 counter_cmd)
2233{ 2159{
2234 struct rtl8169_private *tp = netdev_priv(dev); 2160 struct rtl8169_private *tp = netdev_priv(dev);
2235 void __iomem *ioaddr = tp->mmio_addr;
2236 dma_addr_t paddr = tp->counters_phys_addr; 2161 dma_addr_t paddr = tp->counters_phys_addr;
2237 u32 cmd; 2162 u32 cmd;
2238 2163
2239 RTL_W32(CounterAddrHigh, (u64)paddr >> 32); 2164 RTL_W32(tp, CounterAddrHigh, (u64)paddr >> 32);
2240 RTL_R32(CounterAddrHigh); 2165 RTL_R32(tp, CounterAddrHigh);
2241 cmd = (u64)paddr & DMA_BIT_MASK(32); 2166 cmd = (u64)paddr & DMA_BIT_MASK(32);
2242 RTL_W32(CounterAddrLow, cmd); 2167 RTL_W32(tp, CounterAddrLow, cmd);
2243 RTL_W32(CounterAddrLow, cmd | counter_cmd); 2168 RTL_W32(tp, CounterAddrLow, cmd | counter_cmd);
2244 2169
2245 return rtl_udelay_loop_wait_low(tp, &rtl_counters_cond, 10, 1000); 2170 return rtl_udelay_loop_wait_low(tp, &rtl_counters_cond, 10, 1000);
2246} 2171}
@@ -2262,13 +2187,12 @@ static bool rtl8169_reset_counters(struct net_device *dev)
2262static bool rtl8169_update_counters(struct net_device *dev) 2187static bool rtl8169_update_counters(struct net_device *dev)
2263{ 2188{
2264 struct rtl8169_private *tp = netdev_priv(dev); 2189 struct rtl8169_private *tp = netdev_priv(dev);
2265 void __iomem *ioaddr = tp->mmio_addr;
2266 2190
2267 /* 2191 /*
2268 * Some chips are unable to dump tally counters when the receiver 2192 * Some chips are unable to dump tally counters when the receiver
2269 * is disabled. 2193 * is disabled.
2270 */ 2194 */
2271 if ((RTL_R8(ChipCmd) & CmdRxEnb) == 0) 2195 if ((RTL_R8(tp, ChipCmd) & CmdRxEnb) == 0)
2272 return true; 2196 return true;
2273 2197
2274 return rtl8169_do_counters(dev, CounterDump); 2198 return rtl8169_do_counters(dev, CounterDump);
@@ -2317,7 +2241,7 @@ static void rtl8169_get_ethtool_stats(struct net_device *dev,
2317 struct ethtool_stats *stats, u64 *data) 2241 struct ethtool_stats *stats, u64 *data)
2318{ 2242{
2319 struct rtl8169_private *tp = netdev_priv(dev); 2243 struct rtl8169_private *tp = netdev_priv(dev);
2320 struct device *d = &tp->pci_dev->dev; 2244 struct device *d = tp_to_dev(tp);
2321 struct rtl8169_counters *counters = tp->counters; 2245 struct rtl8169_counters *counters = tp->counters;
2322 2246
2323 ASSERT_RTNL(); 2247 ASSERT_RTNL();
@@ -2448,7 +2372,6 @@ static const struct rtl_coalesce_info *rtl_coalesce_info(struct net_device *dev)
2448static int rtl_get_coalesce(struct net_device *dev, struct ethtool_coalesce *ec) 2372static int rtl_get_coalesce(struct net_device *dev, struct ethtool_coalesce *ec)
2449{ 2373{
2450 struct rtl8169_private *tp = netdev_priv(dev); 2374 struct rtl8169_private *tp = netdev_priv(dev);
2451 void __iomem *ioaddr = tp->mmio_addr;
2452 const struct rtl_coalesce_info *ci; 2375 const struct rtl_coalesce_info *ci;
2453 const struct rtl_coalesce_scale *scale; 2376 const struct rtl_coalesce_scale *scale;
2454 struct { 2377 struct {
@@ -2468,10 +2391,10 @@ static int rtl_get_coalesce(struct net_device *dev, struct ethtool_coalesce *ec)
2468 if (IS_ERR(ci)) 2391 if (IS_ERR(ci))
2469 return PTR_ERR(ci); 2392 return PTR_ERR(ci);
2470 2393
2471 scale = &ci->scalev[RTL_R16(CPlusCmd) & 3]; 2394 scale = &ci->scalev[RTL_R16(tp, CPlusCmd) & 3];
2472 2395
2473 /* read IntrMitigate and adjust according to scale */ 2396 /* read IntrMitigate and adjust according to scale */
2474 for (w = RTL_R16(IntrMitigate); w; w >>= RTL_COALESCE_SHIFT, p++) { 2397 for (w = RTL_R16(tp, IntrMitigate); w; w >>= RTL_COALESCE_SHIFT, p++) {
2475 *p->max_frames = (w & RTL_COALESCE_MASK) << 2; 2398 *p->max_frames = (w & RTL_COALESCE_MASK) << 2;
2476 w >>= RTL_COALESCE_SHIFT; 2399 w >>= RTL_COALESCE_SHIFT;
2477 *p->usecs = w & RTL_COALESCE_MASK; 2400 *p->usecs = w & RTL_COALESCE_MASK;
@@ -2518,7 +2441,6 @@ static const struct rtl_coalesce_scale *rtl_coalesce_choose_scale(
2518static int rtl_set_coalesce(struct net_device *dev, struct ethtool_coalesce *ec) 2441static int rtl_set_coalesce(struct net_device *dev, struct ethtool_coalesce *ec)
2519{ 2442{
2520 struct rtl8169_private *tp = netdev_priv(dev); 2443 struct rtl8169_private *tp = netdev_priv(dev);
2521 void __iomem *ioaddr = tp->mmio_addr;
2522 const struct rtl_coalesce_scale *scale; 2444 const struct rtl_coalesce_scale *scale;
2523 struct { 2445 struct {
2524 u32 frames; 2446 u32 frames;
@@ -2566,11 +2488,11 @@ static int rtl_set_coalesce(struct net_device *dev, struct ethtool_coalesce *ec)
2566 2488
2567 rtl_lock_work(tp); 2489 rtl_lock_work(tp);
2568 2490
2569 RTL_W16(IntrMitigate, swab16(w)); 2491 RTL_W16(tp, IntrMitigate, swab16(w));
2570 2492
2571 tp->cp_cmd = (tp->cp_cmd & ~3) | cp01; 2493 tp->cp_cmd = (tp->cp_cmd & ~3) | cp01;
2572 RTL_W16(CPlusCmd, tp->cp_cmd); 2494 RTL_W16(tp, CPlusCmd, tp->cp_cmd);
2573 RTL_R16(CPlusCmd); 2495 RTL_R16(tp, CPlusCmd);
2574 2496
2575 rtl_unlock_work(tp); 2497 rtl_unlock_work(tp);
2576 2498
@@ -2600,17 +2522,16 @@ static const struct ethtool_ops rtl8169_ethtool_ops = {
2600static void rtl8169_get_mac_version(struct rtl8169_private *tp, 2522static void rtl8169_get_mac_version(struct rtl8169_private *tp,
2601 struct net_device *dev, u8 default_version) 2523 struct net_device *dev, u8 default_version)
2602{ 2524{
2603 void __iomem *ioaddr = tp->mmio_addr;
2604 /* 2525 /*
2605 * The driver currently handles the 8168Bf and the 8168Be identically 2526 * The driver currently handles the 8168Bf and the 8168Be identically
2606 * but they can be identified more specifically through the test below 2527 * but they can be identified more specifically through the test below
2607 * if needed: 2528 * if needed:
2608 * 2529 *
2609 * (RTL_R32(TxConfig) & 0x700000) == 0x500000 ? 8168Bf : 8168Be 2530 * (RTL_R32(tp, TxConfig) & 0x700000) == 0x500000 ? 8168Bf : 8168Be
2610 * 2531 *
2611 * Same thing for the 8101Eb and the 8101Ec: 2532 * Same thing for the 8101Eb and the 8101Ec:
2612 * 2533 *
2613 * (RTL_R32(TxConfig) & 0x700000) == 0x200000 ? 8101Eb : 8101Ec 2534 * (RTL_R32(tp, TxConfig) & 0x700000) == 0x200000 ? 8101Eb : 8101Ec
2614 */ 2535 */
2615 static const struct rtl_mac_info { 2536 static const struct rtl_mac_info {
2616 u32 mask; 2537 u32 mask;
@@ -2708,7 +2629,7 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
2708 const struct rtl_mac_info *p = mac_info; 2629 const struct rtl_mac_info *p = mac_info;
2709 u32 reg; 2630 u32 reg;
2710 2631
2711 reg = RTL_R32(TxConfig); 2632 reg = RTL_R32(tp, TxConfig);
2712 while ((reg & p->mask) != p->val) 2633 while ((reg & p->mask) != p->val)
2713 p++; 2634 p++;
2714 tp->mac_version = p->mac_version; 2635 tp->mac_version = p->mac_version;
@@ -3805,8 +3726,6 @@ static void rtl8168e_2_hw_phy_config(struct rtl8169_private *tp)
3805 rtl_writephy(tp, 0x1f, 0x0005); 3726 rtl_writephy(tp, 0x1f, 0x0005);
3806 rtl_w0w1_phy(tp, 0x01, 0x0100, 0x0000); 3727 rtl_w0w1_phy(tp, 0x01, 0x0100, 0x0000);
3807 rtl_writephy(tp, 0x1f, 0x0000); 3728 rtl_writephy(tp, 0x1f, 0x0000);
3808 /* soft-reset phy */
3809 rtl_writephy(tp, MII_BMCR, BMCR_RESET | BMCR_ANENABLE | BMCR_ANRESTART);
3810 3729
3811 /* Broken BIOS workaround: feed GigaMAC registers with MAC address. */ 3730 /* Broken BIOS workaround: feed GigaMAC registers with MAC address. */
3812 rtl_rar_exgmac_set(tp, tp->dev->dev_addr); 3731 rtl_rar_exgmac_set(tp, tp->dev->dev_addr);
@@ -4591,7 +4510,6 @@ static void rtl_hw_phy_config(struct net_device *dev)
4591static void rtl_phy_work(struct rtl8169_private *tp) 4510static void rtl_phy_work(struct rtl8169_private *tp)
4592{ 4511{
4593 struct timer_list *timer = &tp->timer; 4512 struct timer_list *timer = &tp->timer;
4594 void __iomem *ioaddr = tp->mmio_addr;
4595 unsigned long timeout = RTL8169_PHY_TIMEOUT; 4513 unsigned long timeout = RTL8169_PHY_TIMEOUT;
4596 4514
4597 assert(tp->mac_version > RTL_GIGA_MAC_VER_01); 4515 assert(tp->mac_version > RTL_GIGA_MAC_VER_01);
@@ -4605,7 +4523,7 @@ static void rtl_phy_work(struct rtl8169_private *tp)
4605 goto out_mod_timer; 4523 goto out_mod_timer;
4606 } 4524 }
4607 4525
4608 if (tp->link_ok(ioaddr)) 4526 if (tp->link_ok(tp))
4609 return; 4527 return;
4610 4528
4611 netif_dbg(tp, link, tp->dev, "PHY reset until link up\n"); 4529 netif_dbg(tp, link, tp->dev, "PHY reset until link up\n");
@@ -4643,21 +4561,17 @@ static void rtl8169_phy_reset(struct net_device *dev,
4643 4561
4644static bool rtl_tbi_enabled(struct rtl8169_private *tp) 4562static bool rtl_tbi_enabled(struct rtl8169_private *tp)
4645{ 4563{
4646 void __iomem *ioaddr = tp->mmio_addr;
4647
4648 return (tp->mac_version == RTL_GIGA_MAC_VER_01) && 4564 return (tp->mac_version == RTL_GIGA_MAC_VER_01) &&
4649 (RTL_R8(PHYstatus) & TBI_Enable); 4565 (RTL_R8(tp, PHYstatus) & TBI_Enable);
4650} 4566}
4651 4567
4652static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp) 4568static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp)
4653{ 4569{
4654 void __iomem *ioaddr = tp->mmio_addr;
4655
4656 rtl_hw_phy_config(dev); 4570 rtl_hw_phy_config(dev);
4657 4571
4658 if (tp->mac_version <= RTL_GIGA_MAC_VER_06) { 4572 if (tp->mac_version <= RTL_GIGA_MAC_VER_06) {
4659 dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n"); 4573 dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
4660 RTL_W8(0x82, 0x01); 4574 RTL_W8(tp, 0x82, 0x01);
4661 } 4575 }
4662 4576
4663 pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40); 4577 pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40);
@@ -4667,7 +4581,7 @@ static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp)
4667 4581
4668 if (tp->mac_version == RTL_GIGA_MAC_VER_02) { 4582 if (tp->mac_version == RTL_GIGA_MAC_VER_02) {
4669 dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n"); 4583 dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
4670 RTL_W8(0x82, 0x01); 4584 RTL_W8(tp, 0x82, 0x01);
4671 dprintk("Set PHY Reg 0x0bh = 0x00h\n"); 4585 dprintk("Set PHY Reg 0x0bh = 0x00h\n");
4672 rtl_writephy(tp, 0x0b, 0x0000); //w 0x0b 15 0 0 4586 rtl_writephy(tp, 0x0b, 0x0000); //w 0x0b 15 0 0
4673 } 4587 }
@@ -4687,22 +4601,20 @@ static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp)
4687 4601
4688static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr) 4602static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr)
4689{ 4603{
4690 void __iomem *ioaddr = tp->mmio_addr;
4691
4692 rtl_lock_work(tp); 4604 rtl_lock_work(tp);
4693 4605
4694 RTL_W8(Cfg9346, Cfg9346_Unlock); 4606 RTL_W8(tp, Cfg9346, Cfg9346_Unlock);
4695 4607
4696 RTL_W32(MAC4, addr[4] | addr[5] << 8); 4608 RTL_W32(tp, MAC4, addr[4] | addr[5] << 8);
4697 RTL_R32(MAC4); 4609 RTL_R32(tp, MAC4);
4698 4610
4699 RTL_W32(MAC0, addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24); 4611 RTL_W32(tp, MAC0, addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24);
4700 RTL_R32(MAC0); 4612 RTL_R32(tp, MAC0);
4701 4613
4702 if (tp->mac_version == RTL_GIGA_MAC_VER_34) 4614 if (tp->mac_version == RTL_GIGA_MAC_VER_34)
4703 rtl_rar_exgmac_set(tp, addr); 4615 rtl_rar_exgmac_set(tp, addr);
4704 4616
4705 RTL_W8(Cfg9346, Cfg9346_Lock); 4617 RTL_W8(tp, Cfg9346, Cfg9346_Lock);
4706 4618
4707 rtl_unlock_work(tp); 4619 rtl_unlock_work(tp);
4708} 4620}
@@ -4710,13 +4622,12 @@ static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr)
4710static int rtl_set_mac_address(struct net_device *dev, void *p) 4622static int rtl_set_mac_address(struct net_device *dev, void *p)
4711{ 4623{
4712 struct rtl8169_private *tp = netdev_priv(dev); 4624 struct rtl8169_private *tp = netdev_priv(dev);
4713 struct device *d = &tp->pci_dev->dev; 4625 struct device *d = tp_to_dev(tp);
4714 struct sockaddr *addr = p; 4626 int ret;
4715
4716 if (!is_valid_ether_addr(addr->sa_data))
4717 return -EADDRNOTAVAIL;
4718 4627
4719 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); 4628 ret = eth_mac_addr(dev, p);
4629 if (ret)
4630 return ret;
4720 4631
4721 pm_runtime_get_noresume(d); 4632 pm_runtime_get_noresume(d);
4722 4633
@@ -4822,8 +4733,6 @@ static void rtl_speed_down(struct rtl8169_private *tp)
4822 4733
4823static void rtl_wol_suspend_quirk(struct rtl8169_private *tp) 4734static void rtl_wol_suspend_quirk(struct rtl8169_private *tp)
4824{ 4735{
4825 void __iomem *ioaddr = tp->mmio_addr;
4826
4827 switch (tp->mac_version) { 4736 switch (tp->mac_version) {
4828 case RTL_GIGA_MAC_VER_25: 4737 case RTL_GIGA_MAC_VER_25:
4829 case RTL_GIGA_MAC_VER_26: 4738 case RTL_GIGA_MAC_VER_26:
@@ -4847,7 +4756,7 @@ static void rtl_wol_suspend_quirk(struct rtl8169_private *tp)
4847 case RTL_GIGA_MAC_VER_49: 4756 case RTL_GIGA_MAC_VER_49:
4848 case RTL_GIGA_MAC_VER_50: 4757 case RTL_GIGA_MAC_VER_50:
4849 case RTL_GIGA_MAC_VER_51: 4758 case RTL_GIGA_MAC_VER_51:
4850 RTL_W32(RxConfig, RTL_R32(RxConfig) | 4759 RTL_W32(tp, RxConfig, RTL_R32(tp, RxConfig) |
4851 AcceptBroadcast | AcceptMulticast | AcceptMyPhys); 4760 AcceptBroadcast | AcceptMulticast | AcceptMyPhys);
4852 break; 4761 break;
4853 default: 4762 default:
@@ -4880,8 +4789,6 @@ static void r810x_phy_power_up(struct rtl8169_private *tp)
4880 4789
4881static void r810x_pll_power_down(struct rtl8169_private *tp) 4790static void r810x_pll_power_down(struct rtl8169_private *tp)
4882{ 4791{
4883 void __iomem *ioaddr = tp->mmio_addr;
4884
4885 if (rtl_wol_pll_power_down(tp)) 4792 if (rtl_wol_pll_power_down(tp))
4886 return; 4793 return;
4887 4794
@@ -4896,15 +4803,13 @@ static void r810x_pll_power_down(struct rtl8169_private *tp)
4896 case RTL_GIGA_MAC_VER_16: 4803 case RTL_GIGA_MAC_VER_16:
4897 break; 4804 break;
4898 default: 4805 default:
4899 RTL_W8(PMCH, RTL_R8(PMCH) & ~0x80); 4806 RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) & ~0x80);
4900 break; 4807 break;
4901 } 4808 }
4902} 4809}
4903 4810
4904static void r810x_pll_power_up(struct rtl8169_private *tp) 4811static void r810x_pll_power_up(struct rtl8169_private *tp)
4905{ 4812{
4906 void __iomem *ioaddr = tp->mmio_addr;
4907
4908 r810x_phy_power_up(tp); 4813 r810x_phy_power_up(tp);
4909 4814
4910 switch (tp->mac_version) { 4815 switch (tp->mac_version) {
@@ -4917,10 +4822,10 @@ static void r810x_pll_power_up(struct rtl8169_private *tp)
4917 break; 4822 break;
4918 case RTL_GIGA_MAC_VER_47: 4823 case RTL_GIGA_MAC_VER_47:
4919 case RTL_GIGA_MAC_VER_48: 4824 case RTL_GIGA_MAC_VER_48:
4920 RTL_W8(PMCH, RTL_R8(PMCH) | 0xc0); 4825 RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) | 0xc0);
4921 break; 4826 break;
4922 default: 4827 default:
4923 RTL_W8(PMCH, RTL_R8(PMCH) | 0x80); 4828 RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) | 0x80);
4924 break; 4829 break;
4925 } 4830 }
4926} 4831}
@@ -4987,21 +4892,12 @@ static void r8168_phy_power_down(struct rtl8169_private *tp)
4987 4892
4988static void r8168_pll_power_down(struct rtl8169_private *tp) 4893static void r8168_pll_power_down(struct rtl8169_private *tp)
4989{ 4894{
4990 void __iomem *ioaddr = tp->mmio_addr; 4895 if (r8168_check_dash(tp))
4991
4992 if ((tp->mac_version == RTL_GIGA_MAC_VER_27 ||
4993 tp->mac_version == RTL_GIGA_MAC_VER_28 ||
4994 tp->mac_version == RTL_GIGA_MAC_VER_31 ||
4995 tp->mac_version == RTL_GIGA_MAC_VER_49 ||
4996 tp->mac_version == RTL_GIGA_MAC_VER_50 ||
4997 tp->mac_version == RTL_GIGA_MAC_VER_51) &&
4998 r8168_check_dash(tp)) {
4999 return; 4896 return;
5000 }
5001 4897
5002 if ((tp->mac_version == RTL_GIGA_MAC_VER_23 || 4898 if ((tp->mac_version == RTL_GIGA_MAC_VER_23 ||
5003 tp->mac_version == RTL_GIGA_MAC_VER_24) && 4899 tp->mac_version == RTL_GIGA_MAC_VER_24) &&
5004 (RTL_R16(CPlusCmd) & ASF)) { 4900 (RTL_R16(tp, CPlusCmd) & ASF)) {
5005 return; 4901 return;
5006 } 4902 }
5007 4903
@@ -5027,22 +4923,20 @@ static void r8168_pll_power_down(struct rtl8169_private *tp)
5027 case RTL_GIGA_MAC_VER_46: 4923 case RTL_GIGA_MAC_VER_46:
5028 case RTL_GIGA_MAC_VER_50: 4924 case RTL_GIGA_MAC_VER_50:
5029 case RTL_GIGA_MAC_VER_51: 4925 case RTL_GIGA_MAC_VER_51:
5030 RTL_W8(PMCH, RTL_R8(PMCH) & ~0x80); 4926 RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) & ~0x80);
5031 break; 4927 break;
5032 case RTL_GIGA_MAC_VER_40: 4928 case RTL_GIGA_MAC_VER_40:
5033 case RTL_GIGA_MAC_VER_41: 4929 case RTL_GIGA_MAC_VER_41:
5034 case RTL_GIGA_MAC_VER_49: 4930 case RTL_GIGA_MAC_VER_49:
5035 rtl_w0w1_eri(tp, 0x1a8, ERIAR_MASK_1111, 0x00000000, 4931 rtl_w0w1_eri(tp, 0x1a8, ERIAR_MASK_1111, 0x00000000,
5036 0xfc000000, ERIAR_EXGMAC); 4932 0xfc000000, ERIAR_EXGMAC);
5037 RTL_W8(PMCH, RTL_R8(PMCH) & ~0x80); 4933 RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) & ~0x80);
5038 break; 4934 break;
5039 } 4935 }
5040} 4936}
5041 4937
5042static void r8168_pll_power_up(struct rtl8169_private *tp) 4938static void r8168_pll_power_up(struct rtl8169_private *tp)
5043{ 4939{
5044 void __iomem *ioaddr = tp->mmio_addr;
5045
5046 switch (tp->mac_version) { 4940 switch (tp->mac_version) {
5047 case RTL_GIGA_MAC_VER_25: 4941 case RTL_GIGA_MAC_VER_25:
5048 case RTL_GIGA_MAC_VER_26: 4942 case RTL_GIGA_MAC_VER_26:
@@ -5051,19 +4945,19 @@ static void r8168_pll_power_up(struct rtl8169_private *tp)
5051 case RTL_GIGA_MAC_VER_31: 4945 case RTL_GIGA_MAC_VER_31:
5052 case RTL_GIGA_MAC_VER_32: 4946 case RTL_GIGA_MAC_VER_32:
5053 case RTL_GIGA_MAC_VER_33: 4947 case RTL_GIGA_MAC_VER_33:
5054 RTL_W8(PMCH, RTL_R8(PMCH) | 0x80); 4948 RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) | 0x80);
5055 break; 4949 break;
5056 case RTL_GIGA_MAC_VER_44: 4950 case RTL_GIGA_MAC_VER_44:
5057 case RTL_GIGA_MAC_VER_45: 4951 case RTL_GIGA_MAC_VER_45:
5058 case RTL_GIGA_MAC_VER_46: 4952 case RTL_GIGA_MAC_VER_46:
5059 case RTL_GIGA_MAC_VER_50: 4953 case RTL_GIGA_MAC_VER_50:
5060 case RTL_GIGA_MAC_VER_51: 4954 case RTL_GIGA_MAC_VER_51:
5061 RTL_W8(PMCH, RTL_R8(PMCH) | 0xc0); 4955 RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) | 0xc0);
5062 break; 4956 break;
5063 case RTL_GIGA_MAC_VER_40: 4957 case RTL_GIGA_MAC_VER_40:
5064 case RTL_GIGA_MAC_VER_41: 4958 case RTL_GIGA_MAC_VER_41:
5065 case RTL_GIGA_MAC_VER_49: 4959 case RTL_GIGA_MAC_VER_49:
5066 RTL_W8(PMCH, RTL_R8(PMCH) | 0xc0); 4960 RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) | 0xc0);
5067 rtl_w0w1_eri(tp, 0x1a8, ERIAR_MASK_1111, 0xfc000000, 4961 rtl_w0w1_eri(tp, 0x1a8, ERIAR_MASK_1111, 0xfc000000,
5068 0x00000000, ERIAR_EXGMAC); 4962 0x00000000, ERIAR_EXGMAC);
5069 break; 4963 break;
@@ -5153,8 +5047,6 @@ static void rtl_init_pll_power_ops(struct rtl8169_private *tp)
5153 5047
5154static void rtl_init_rxcfg(struct rtl8169_private *tp) 5048static void rtl_init_rxcfg(struct rtl8169_private *tp)
5155{ 5049{
5156 void __iomem *ioaddr = tp->mmio_addr;
5157
5158 switch (tp->mac_version) { 5050 switch (tp->mac_version) {
5159 case RTL_GIGA_MAC_VER_01: 5051 case RTL_GIGA_MAC_VER_01:
5160 case RTL_GIGA_MAC_VER_02: 5052 case RTL_GIGA_MAC_VER_02:
@@ -5170,7 +5062,7 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp)
5170 case RTL_GIGA_MAC_VER_15: 5062 case RTL_GIGA_MAC_VER_15:
5171 case RTL_GIGA_MAC_VER_16: 5063 case RTL_GIGA_MAC_VER_16:
5172 case RTL_GIGA_MAC_VER_17: 5064 case RTL_GIGA_MAC_VER_17:
5173 RTL_W32(RxConfig, RX_FIFO_THRESH | RX_DMA_BURST); 5065 RTL_W32(tp, RxConfig, RX_FIFO_THRESH | RX_DMA_BURST);
5174 break; 5066 break;
5175 case RTL_GIGA_MAC_VER_18: 5067 case RTL_GIGA_MAC_VER_18:
5176 case RTL_GIGA_MAC_VER_19: 5068 case RTL_GIGA_MAC_VER_19:
@@ -5181,7 +5073,7 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp)
5181 case RTL_GIGA_MAC_VER_24: 5073 case RTL_GIGA_MAC_VER_24:
5182 case RTL_GIGA_MAC_VER_34: 5074 case RTL_GIGA_MAC_VER_34:
5183 case RTL_GIGA_MAC_VER_35: 5075 case RTL_GIGA_MAC_VER_35:
5184 RTL_W32(RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST); 5076 RTL_W32(tp, RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST);
5185 break; 5077 break;
5186 case RTL_GIGA_MAC_VER_40: 5078 case RTL_GIGA_MAC_VER_40:
5187 case RTL_GIGA_MAC_VER_41: 5079 case RTL_GIGA_MAC_VER_41:
@@ -5195,10 +5087,10 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp)
5195 case RTL_GIGA_MAC_VER_49: 5087 case RTL_GIGA_MAC_VER_49:
5196 case RTL_GIGA_MAC_VER_50: 5088 case RTL_GIGA_MAC_VER_50:
5197 case RTL_GIGA_MAC_VER_51: 5089 case RTL_GIGA_MAC_VER_51:
5198 RTL_W32(RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST | RX_EARLY_OFF); 5090 RTL_W32(tp, RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST | RX_EARLY_OFF);
5199 break; 5091 break;
5200 default: 5092 default:
5201 RTL_W32(RxConfig, RX128_INT_EN | RX_DMA_BURST); 5093 RTL_W32(tp, RxConfig, RX128_INT_EN | RX_DMA_BURST);
5202 break; 5094 break;
5203 } 5095 }
5204} 5096}
@@ -5210,102 +5102,82 @@ static void rtl8169_init_ring_indexes(struct rtl8169_private *tp)
5210 5102
5211static void rtl_hw_jumbo_enable(struct rtl8169_private *tp) 5103static void rtl_hw_jumbo_enable(struct rtl8169_private *tp)
5212{ 5104{
5213 void __iomem *ioaddr = tp->mmio_addr; 5105 RTL_W8(tp, Cfg9346, Cfg9346_Unlock);
5214
5215 RTL_W8(Cfg9346, Cfg9346_Unlock);
5216 rtl_generic_op(tp, tp->jumbo_ops.enable); 5106 rtl_generic_op(tp, tp->jumbo_ops.enable);
5217 RTL_W8(Cfg9346, Cfg9346_Lock); 5107 RTL_W8(tp, Cfg9346, Cfg9346_Lock);
5218} 5108}
5219 5109
5220static void rtl_hw_jumbo_disable(struct rtl8169_private *tp) 5110static void rtl_hw_jumbo_disable(struct rtl8169_private *tp)
5221{ 5111{
5222 void __iomem *ioaddr = tp->mmio_addr; 5112 RTL_W8(tp, Cfg9346, Cfg9346_Unlock);
5223
5224 RTL_W8(Cfg9346, Cfg9346_Unlock);
5225 rtl_generic_op(tp, tp->jumbo_ops.disable); 5113 rtl_generic_op(tp, tp->jumbo_ops.disable);
5226 RTL_W8(Cfg9346, Cfg9346_Lock); 5114 RTL_W8(tp, Cfg9346, Cfg9346_Lock);
5227} 5115}
5228 5116
5229static void r8168c_hw_jumbo_enable(struct rtl8169_private *tp) 5117static void r8168c_hw_jumbo_enable(struct rtl8169_private *tp)
5230{ 5118{
5231 void __iomem *ioaddr = tp->mmio_addr; 5119 RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0);
5232 5120 RTL_W8(tp, Config4, RTL_R8(tp, Config4) | Jumbo_En1);
5233 RTL_W8(Config3, RTL_R8(Config3) | Jumbo_En0); 5121 rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_512B);
5234 RTL_W8(Config4, RTL_R8(Config4) | Jumbo_En1);
5235 rtl_tx_performance_tweak(tp->pci_dev, PCI_EXP_DEVCTL_READRQ_512B);
5236} 5122}
5237 5123
5238static void r8168c_hw_jumbo_disable(struct rtl8169_private *tp) 5124static void r8168c_hw_jumbo_disable(struct rtl8169_private *tp)
5239{ 5125{
5240 void __iomem *ioaddr = tp->mmio_addr; 5126 RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Jumbo_En0);
5241 5127 RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~Jumbo_En1);
5242 RTL_W8(Config3, RTL_R8(Config3) & ~Jumbo_En0); 5128 rtl_tx_performance_tweak(tp, 0x5 << MAX_READ_REQUEST_SHIFT);
5243 RTL_W8(Config4, RTL_R8(Config4) & ~Jumbo_En1);
5244 rtl_tx_performance_tweak(tp->pci_dev, 0x5 << MAX_READ_REQUEST_SHIFT);
5245} 5129}
5246 5130
5247static void r8168dp_hw_jumbo_enable(struct rtl8169_private *tp) 5131static void r8168dp_hw_jumbo_enable(struct rtl8169_private *tp)
5248{ 5132{
5249 void __iomem *ioaddr = tp->mmio_addr; 5133 RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0);
5250
5251 RTL_W8(Config3, RTL_R8(Config3) | Jumbo_En0);
5252} 5134}
5253 5135
5254static void r8168dp_hw_jumbo_disable(struct rtl8169_private *tp) 5136static void r8168dp_hw_jumbo_disable(struct rtl8169_private *tp)
5255{ 5137{
5256 void __iomem *ioaddr = tp->mmio_addr; 5138 RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Jumbo_En0);
5257
5258 RTL_W8(Config3, RTL_R8(Config3) & ~Jumbo_En0);
5259} 5139}
5260 5140
5261static void r8168e_hw_jumbo_enable(struct rtl8169_private *tp) 5141static void r8168e_hw_jumbo_enable(struct rtl8169_private *tp)
5262{ 5142{
5263 void __iomem *ioaddr = tp->mmio_addr; 5143 RTL_W8(tp, MaxTxPacketSize, 0x3f);
5264 5144 RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0);
5265 RTL_W8(MaxTxPacketSize, 0x3f); 5145 RTL_W8(tp, Config4, RTL_R8(tp, Config4) | 0x01);
5266 RTL_W8(Config3, RTL_R8(Config3) | Jumbo_En0); 5146 rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_512B);
5267 RTL_W8(Config4, RTL_R8(Config4) | 0x01);
5268 rtl_tx_performance_tweak(tp->pci_dev, PCI_EXP_DEVCTL_READRQ_512B);
5269} 5147}
5270 5148
5271static void r8168e_hw_jumbo_disable(struct rtl8169_private *tp) 5149static void r8168e_hw_jumbo_disable(struct rtl8169_private *tp)
5272{ 5150{
5273 void __iomem *ioaddr = tp->mmio_addr; 5151 RTL_W8(tp, MaxTxPacketSize, 0x0c);
5274 5152 RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Jumbo_En0);
5275 RTL_W8(MaxTxPacketSize, 0x0c); 5153 RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~0x01);
5276 RTL_W8(Config3, RTL_R8(Config3) & ~Jumbo_En0); 5154 rtl_tx_performance_tweak(tp, 0x5 << MAX_READ_REQUEST_SHIFT);
5277 RTL_W8(Config4, RTL_R8(Config4) & ~0x01);
5278 rtl_tx_performance_tweak(tp->pci_dev, 0x5 << MAX_READ_REQUEST_SHIFT);
5279} 5155}
5280 5156
5281static void r8168b_0_hw_jumbo_enable(struct rtl8169_private *tp) 5157static void r8168b_0_hw_jumbo_enable(struct rtl8169_private *tp)
5282{ 5158{
5283 rtl_tx_performance_tweak(tp->pci_dev, 5159 rtl_tx_performance_tweak(tp,
5284 PCI_EXP_DEVCTL_READRQ_512B | PCI_EXP_DEVCTL_NOSNOOP_EN); 5160 PCI_EXP_DEVCTL_READRQ_512B | PCI_EXP_DEVCTL_NOSNOOP_EN);
5285} 5161}
5286 5162
5287static void r8168b_0_hw_jumbo_disable(struct rtl8169_private *tp) 5163static void r8168b_0_hw_jumbo_disable(struct rtl8169_private *tp)
5288{ 5164{
5289 rtl_tx_performance_tweak(tp->pci_dev, 5165 rtl_tx_performance_tweak(tp,
5290 (0x5 << MAX_READ_REQUEST_SHIFT) | PCI_EXP_DEVCTL_NOSNOOP_EN); 5166 (0x5 << MAX_READ_REQUEST_SHIFT) | PCI_EXP_DEVCTL_NOSNOOP_EN);
5291} 5167}
5292 5168
5293static void r8168b_1_hw_jumbo_enable(struct rtl8169_private *tp) 5169static void r8168b_1_hw_jumbo_enable(struct rtl8169_private *tp)
5294{ 5170{
5295 void __iomem *ioaddr = tp->mmio_addr;
5296
5297 r8168b_0_hw_jumbo_enable(tp); 5171 r8168b_0_hw_jumbo_enable(tp);
5298 5172
5299 RTL_W8(Config4, RTL_R8(Config4) | (1 << 0)); 5173 RTL_W8(tp, Config4, RTL_R8(tp, Config4) | (1 << 0));
5300} 5174}
5301 5175
5302static void r8168b_1_hw_jumbo_disable(struct rtl8169_private *tp) 5176static void r8168b_1_hw_jumbo_disable(struct rtl8169_private *tp)
5303{ 5177{
5304 void __iomem *ioaddr = tp->mmio_addr;
5305
5306 r8168b_0_hw_jumbo_disable(tp); 5178 r8168b_0_hw_jumbo_disable(tp);
5307 5179
5308 RTL_W8(Config4, RTL_R8(Config4) & ~(1 << 0)); 5180 RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~(1 << 0));
5309} 5181}
5310 5182
5311static void rtl_init_jumbo_ops(struct rtl8169_private *tp) 5183static void rtl_init_jumbo_ops(struct rtl8169_private *tp)
@@ -5372,16 +5244,12 @@ static void rtl_init_jumbo_ops(struct rtl8169_private *tp)
5372 5244
5373DECLARE_RTL_COND(rtl_chipcmd_cond) 5245DECLARE_RTL_COND(rtl_chipcmd_cond)
5374{ 5246{
5375 void __iomem *ioaddr = tp->mmio_addr; 5247 return RTL_R8(tp, ChipCmd) & CmdReset;
5376
5377 return RTL_R8(ChipCmd) & CmdReset;
5378} 5248}
5379 5249
5380static void rtl_hw_reset(struct rtl8169_private *tp) 5250static void rtl_hw_reset(struct rtl8169_private *tp)
5381{ 5251{
5382 void __iomem *ioaddr = tp->mmio_addr; 5252 RTL_W8(tp, ChipCmd, CmdReset);
5383
5384 RTL_W8(ChipCmd, CmdReset);
5385 5253
5386 rtl_udelay_loop_wait_low(tp, &rtl_chipcmd_cond, 100, 100); 5254 rtl_udelay_loop_wait_low(tp, &rtl_chipcmd_cond, 100, 100);
5387} 5255}
@@ -5400,7 +5268,7 @@ static void rtl_request_uncached_firmware(struct rtl8169_private *tp)
5400 if (!rtl_fw) 5268 if (!rtl_fw)
5401 goto err_warn; 5269 goto err_warn;
5402 5270
5403 rc = request_firmware(&rtl_fw->fw, name, &tp->pci_dev->dev); 5271 rc = request_firmware(&rtl_fw->fw, name, tp_to_dev(tp));
5404 if (rc < 0) 5272 if (rc < 0)
5405 goto err_free; 5273 goto err_free;
5406 5274
@@ -5432,29 +5300,21 @@ static void rtl_request_firmware(struct rtl8169_private *tp)
5432 5300
5433static void rtl_rx_close(struct rtl8169_private *tp) 5301static void rtl_rx_close(struct rtl8169_private *tp)
5434{ 5302{
5435 void __iomem *ioaddr = tp->mmio_addr; 5303 RTL_W32(tp, RxConfig, RTL_R32(tp, RxConfig) & ~RX_CONFIG_ACCEPT_MASK);
5436
5437 RTL_W32(RxConfig, RTL_R32(RxConfig) & ~RX_CONFIG_ACCEPT_MASK);
5438} 5304}
5439 5305
5440DECLARE_RTL_COND(rtl_npq_cond) 5306DECLARE_RTL_COND(rtl_npq_cond)
5441{ 5307{
5442 void __iomem *ioaddr = tp->mmio_addr; 5308 return RTL_R8(tp, TxPoll) & NPQ;
5443
5444 return RTL_R8(TxPoll) & NPQ;
5445} 5309}
5446 5310
5447DECLARE_RTL_COND(rtl_txcfg_empty_cond) 5311DECLARE_RTL_COND(rtl_txcfg_empty_cond)
5448{ 5312{
5449 void __iomem *ioaddr = tp->mmio_addr; 5313 return RTL_R32(tp, TxConfig) & TXCFG_EMPTY;
5450
5451 return RTL_R32(TxConfig) & TXCFG_EMPTY;
5452} 5314}
5453 5315
5454static void rtl8169_hw_reset(struct rtl8169_private *tp) 5316static void rtl8169_hw_reset(struct rtl8169_private *tp)
5455{ 5317{
5456 void __iomem *ioaddr = tp->mmio_addr;
5457
5458 /* Disable interrupts */ 5318 /* Disable interrupts */
5459 rtl8169_irq_mask_and_ack(tp); 5319 rtl8169_irq_mask_and_ack(tp);
5460 5320
@@ -5481,10 +5341,10 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp)
5481 tp->mac_version == RTL_GIGA_MAC_VER_49 || 5341 tp->mac_version == RTL_GIGA_MAC_VER_49 ||
5482 tp->mac_version == RTL_GIGA_MAC_VER_50 || 5342 tp->mac_version == RTL_GIGA_MAC_VER_50 ||
5483 tp->mac_version == RTL_GIGA_MAC_VER_51) { 5343 tp->mac_version == RTL_GIGA_MAC_VER_51) {
5484 RTL_W8(ChipCmd, RTL_R8(ChipCmd) | StopReq); 5344 RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq);
5485 rtl_udelay_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 666); 5345 rtl_udelay_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 666);
5486 } else { 5346 } else {
5487 RTL_W8(ChipCmd, RTL_R8(ChipCmd) | StopReq); 5347 RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq);
5488 udelay(100); 5348 udelay(100);
5489 } 5349 }
5490 5350
@@ -5493,10 +5353,8 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp)
5493 5353
5494static void rtl_set_rx_tx_config_registers(struct rtl8169_private *tp) 5354static void rtl_set_rx_tx_config_registers(struct rtl8169_private *tp)
5495{ 5355{
5496 void __iomem *ioaddr = tp->mmio_addr;
5497
5498 /* Set DMA burst size and Interframe Gap Time */ 5356 /* Set DMA burst size and Interframe Gap Time */
5499 RTL_W32(TxConfig, (TX_DMA_BURST << TxDMAShift) | 5357 RTL_W32(tp, TxConfig, (TX_DMA_BURST << TxDMAShift) |
5500 (InterFrameGap << TxInterFrameGapShift)); 5358 (InterFrameGap << TxInterFrameGapShift));
5501} 5359}
5502 5360
@@ -5509,36 +5367,35 @@ static void rtl_hw_start(struct net_device *dev)
5509 rtl_irq_enable_all(tp); 5367 rtl_irq_enable_all(tp);
5510} 5368}
5511 5369
5512static void rtl_set_rx_tx_desc_registers(struct rtl8169_private *tp, 5370static void rtl_set_rx_tx_desc_registers(struct rtl8169_private *tp)
5513 void __iomem *ioaddr)
5514{ 5371{
5515 /* 5372 /*
5516 * Magic spell: some iop3xx ARM board needs the TxDescAddrHigh 5373 * Magic spell: some iop3xx ARM board needs the TxDescAddrHigh
5517 * register to be written before TxDescAddrLow to work. 5374 * register to be written before TxDescAddrLow to work.
5518 * Switching from MMIO to I/O access fixes the issue as well. 5375 * Switching from MMIO to I/O access fixes the issue as well.
5519 */ 5376 */
5520 RTL_W32(TxDescStartAddrHigh, ((u64) tp->TxPhyAddr) >> 32); 5377 RTL_W32(tp, TxDescStartAddrHigh, ((u64) tp->TxPhyAddr) >> 32);
5521 RTL_W32(TxDescStartAddrLow, ((u64) tp->TxPhyAddr) & DMA_BIT_MASK(32)); 5378 RTL_W32(tp, TxDescStartAddrLow, ((u64) tp->TxPhyAddr) & DMA_BIT_MASK(32));
5522 RTL_W32(RxDescAddrHigh, ((u64) tp->RxPhyAddr) >> 32); 5379 RTL_W32(tp, RxDescAddrHigh, ((u64) tp->RxPhyAddr) >> 32);
5523 RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr) & DMA_BIT_MASK(32)); 5380 RTL_W32(tp, RxDescAddrLow, ((u64) tp->RxPhyAddr) & DMA_BIT_MASK(32));
5524} 5381}
5525 5382
5526static u16 rtl_rw_cpluscmd(void __iomem *ioaddr) 5383static u16 rtl_rw_cpluscmd(struct rtl8169_private *tp)
5527{ 5384{
5528 u16 cmd; 5385 u16 cmd;
5529 5386
5530 cmd = RTL_R16(CPlusCmd); 5387 cmd = RTL_R16(tp, CPlusCmd);
5531 RTL_W16(CPlusCmd, cmd); 5388 RTL_W16(tp, CPlusCmd, cmd);
5532 return cmd; 5389 return cmd;
5533} 5390}
5534 5391
5535static void rtl_set_rx_max_size(void __iomem *ioaddr, unsigned int rx_buf_sz) 5392static void rtl_set_rx_max_size(struct rtl8169_private *tp, unsigned int rx_buf_sz)
5536{ 5393{
5537 /* Low hurts. Let's disable the filtering. */ 5394 /* Low hurts. Let's disable the filtering. */
5538 RTL_W16(RxMaxSize, rx_buf_sz + 1); 5395 RTL_W16(tp, RxMaxSize, rx_buf_sz + 1);
5539} 5396}
5540 5397
5541static void rtl8169_set_magic_reg(void __iomem *ioaddr, unsigned mac_version) 5398static void rtl8169_set_magic_reg(struct rtl8169_private *tp, unsigned mac_version)
5542{ 5399{
5543 static const struct rtl_cfg2_info { 5400 static const struct rtl_cfg2_info {
5544 u32 mac_version; 5401 u32 mac_version;
@@ -5554,10 +5411,10 @@ static void rtl8169_set_magic_reg(void __iomem *ioaddr, unsigned mac_version)
5554 unsigned int i; 5411 unsigned int i;
5555 u32 clk; 5412 u32 clk;
5556 5413
5557 clk = RTL_R8(Config2) & PCI_Clock_66MHz; 5414 clk = RTL_R8(tp, Config2) & PCI_Clock_66MHz;
5558 for (i = 0; i < ARRAY_SIZE(cfg2_info); i++, p++) { 5415 for (i = 0; i < ARRAY_SIZE(cfg2_info); i++, p++) {
5559 if ((p->mac_version == mac_version) && (p->clk == clk)) { 5416 if ((p->mac_version == mac_version) && (p->clk == clk)) {
5560 RTL_W32(0x7c, p->val); 5417 RTL_W32(tp, 0x7c, p->val);
5561 break; 5418 break;
5562 } 5419 }
5563 } 5420 }
@@ -5566,7 +5423,6 @@ static void rtl8169_set_magic_reg(void __iomem *ioaddr, unsigned mac_version)
5566static void rtl_set_rx_mode(struct net_device *dev) 5423static void rtl_set_rx_mode(struct net_device *dev)
5567{ 5424{
5568 struct rtl8169_private *tp = netdev_priv(dev); 5425 struct rtl8169_private *tp = netdev_priv(dev);
5569 void __iomem *ioaddr = tp->mmio_addr;
5570 u32 mc_filter[2]; /* Multicast hash filter */ 5426 u32 mc_filter[2]; /* Multicast hash filter */
5571 int rx_mode; 5427 int rx_mode;
5572 u32 tmp = 0; 5428 u32 tmp = 0;
@@ -5598,7 +5454,7 @@ static void rtl_set_rx_mode(struct net_device *dev)
5598 if (dev->features & NETIF_F_RXALL) 5454 if (dev->features & NETIF_F_RXALL)
5599 rx_mode |= (AcceptErr | AcceptRunt); 5455 rx_mode |= (AcceptErr | AcceptRunt);
5600 5456
5601 tmp = (RTL_R32(RxConfig) & ~RX_CONFIG_ACCEPT_MASK) | rx_mode; 5457 tmp = (RTL_R32(tp, RxConfig) & ~RX_CONFIG_ACCEPT_MASK) | rx_mode;
5602 5458
5603 if (tp->mac_version > RTL_GIGA_MAC_VER_06) { 5459 if (tp->mac_version > RTL_GIGA_MAC_VER_06) {
5604 u32 data = mc_filter[0]; 5460 u32 data = mc_filter[0];
@@ -5610,35 +5466,34 @@ static void rtl_set_rx_mode(struct net_device *dev)
5610 if (tp->mac_version == RTL_GIGA_MAC_VER_35) 5466 if (tp->mac_version == RTL_GIGA_MAC_VER_35)
5611 mc_filter[1] = mc_filter[0] = 0xffffffff; 5467 mc_filter[1] = mc_filter[0] = 0xffffffff;
5612 5468
5613 RTL_W32(MAR0 + 4, mc_filter[1]); 5469 RTL_W32(tp, MAR0 + 4, mc_filter[1]);
5614 RTL_W32(MAR0 + 0, mc_filter[0]); 5470 RTL_W32(tp, MAR0 + 0, mc_filter[0]);
5615 5471
5616 RTL_W32(RxConfig, tmp); 5472 RTL_W32(tp, RxConfig, tmp);
5617} 5473}
5618 5474
5619static void rtl_hw_start_8169(struct net_device *dev) 5475static void rtl_hw_start_8169(struct net_device *dev)
5620{ 5476{
5621 struct rtl8169_private *tp = netdev_priv(dev); 5477 struct rtl8169_private *tp = netdev_priv(dev);
5622 void __iomem *ioaddr = tp->mmio_addr;
5623 struct pci_dev *pdev = tp->pci_dev; 5478 struct pci_dev *pdev = tp->pci_dev;
5624 5479
5625 if (tp->mac_version == RTL_GIGA_MAC_VER_05) { 5480 if (tp->mac_version == RTL_GIGA_MAC_VER_05) {
5626 RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) | PCIMulRW); 5481 RTL_W16(tp, CPlusCmd, RTL_R16(tp, CPlusCmd) | PCIMulRW);
5627 pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 0x08); 5482 pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 0x08);
5628 } 5483 }
5629 5484
5630 RTL_W8(Cfg9346, Cfg9346_Unlock); 5485 RTL_W8(tp, Cfg9346, Cfg9346_Unlock);
5631 if (tp->mac_version == RTL_GIGA_MAC_VER_01 || 5486 if (tp->mac_version == RTL_GIGA_MAC_VER_01 ||
5632 tp->mac_version == RTL_GIGA_MAC_VER_02 || 5487 tp->mac_version == RTL_GIGA_MAC_VER_02 ||
5633 tp->mac_version == RTL_GIGA_MAC_VER_03 || 5488 tp->mac_version == RTL_GIGA_MAC_VER_03 ||
5634 tp->mac_version == RTL_GIGA_MAC_VER_04) 5489 tp->mac_version == RTL_GIGA_MAC_VER_04)
5635 RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); 5490 RTL_W8(tp, ChipCmd, CmdTxEnb | CmdRxEnb);
5636 5491
5637 rtl_init_rxcfg(tp); 5492 rtl_init_rxcfg(tp);
5638 5493
5639 RTL_W8(EarlyTxThres, NoEarlyTx); 5494 RTL_W8(tp, EarlyTxThres, NoEarlyTx);
5640 5495
5641 rtl_set_rx_max_size(ioaddr, rx_buf_sz); 5496 rtl_set_rx_max_size(tp, rx_buf_sz);
5642 5497
5643 if (tp->mac_version == RTL_GIGA_MAC_VER_01 || 5498 if (tp->mac_version == RTL_GIGA_MAC_VER_01 ||
5644 tp->mac_version == RTL_GIGA_MAC_VER_02 || 5499 tp->mac_version == RTL_GIGA_MAC_VER_02 ||
@@ -5646,7 +5501,7 @@ static void rtl_hw_start_8169(struct net_device *dev)
5646 tp->mac_version == RTL_GIGA_MAC_VER_04) 5501 tp->mac_version == RTL_GIGA_MAC_VER_04)
5647 rtl_set_rx_tx_config_registers(tp); 5502 rtl_set_rx_tx_config_registers(tp);
5648 5503
5649 tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW; 5504 tp->cp_cmd |= rtl_rw_cpluscmd(tp) | PCIMulRW;
5650 5505
5651 if (tp->mac_version == RTL_GIGA_MAC_VER_02 || 5506 if (tp->mac_version == RTL_GIGA_MAC_VER_02 ||
5652 tp->mac_version == RTL_GIGA_MAC_VER_03) { 5507 tp->mac_version == RTL_GIGA_MAC_VER_03) {
@@ -5655,37 +5510,37 @@ static void rtl_hw_start_8169(struct net_device *dev)
5655 tp->cp_cmd |= (1 << 14); 5510 tp->cp_cmd |= (1 << 14);
5656 } 5511 }
5657 5512
5658 RTL_W16(CPlusCmd, tp->cp_cmd); 5513 RTL_W16(tp, CPlusCmd, tp->cp_cmd);
5659 5514
5660 rtl8169_set_magic_reg(ioaddr, tp->mac_version); 5515 rtl8169_set_magic_reg(tp, tp->mac_version);
5661 5516
5662 /* 5517 /*
5663 * Undocumented corner. Supposedly: 5518 * Undocumented corner. Supposedly:
5664 * (TxTimer << 12) | (TxPackets << 8) | (RxTimer << 4) | RxPackets 5519 * (TxTimer << 12) | (TxPackets << 8) | (RxTimer << 4) | RxPackets
5665 */ 5520 */
5666 RTL_W16(IntrMitigate, 0x0000); 5521 RTL_W16(tp, IntrMitigate, 0x0000);
5667 5522
5668 rtl_set_rx_tx_desc_registers(tp, ioaddr); 5523 rtl_set_rx_tx_desc_registers(tp);
5669 5524
5670 if (tp->mac_version != RTL_GIGA_MAC_VER_01 && 5525 if (tp->mac_version != RTL_GIGA_MAC_VER_01 &&
5671 tp->mac_version != RTL_GIGA_MAC_VER_02 && 5526 tp->mac_version != RTL_GIGA_MAC_VER_02 &&
5672 tp->mac_version != RTL_GIGA_MAC_VER_03 && 5527 tp->mac_version != RTL_GIGA_MAC_VER_03 &&
5673 tp->mac_version != RTL_GIGA_MAC_VER_04) { 5528 tp->mac_version != RTL_GIGA_MAC_VER_04) {
5674 RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); 5529 RTL_W8(tp, ChipCmd, CmdTxEnb | CmdRxEnb);
5675 rtl_set_rx_tx_config_registers(tp); 5530 rtl_set_rx_tx_config_registers(tp);
5676 } 5531 }
5677 5532
5678 RTL_W8(Cfg9346, Cfg9346_Lock); 5533 RTL_W8(tp, Cfg9346, Cfg9346_Lock);
5679 5534
5680 /* Initially a 10 us delay. Turned it into a PCI commit. - FR */ 5535 /* Initially a 10 us delay. Turned it into a PCI commit. - FR */
5681 RTL_R8(IntrMask); 5536 RTL_R8(tp, IntrMask);
5682 5537
5683 RTL_W32(RxMissed, 0); 5538 RTL_W32(tp, RxMissed, 0);
5684 5539
5685 rtl_set_rx_mode(dev); 5540 rtl_set_rx_mode(dev);
5686 5541
5687 /* no early-rx interrupts */ 5542 /* no early-rx interrupts */
5688 RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xf000); 5543 RTL_W16(tp, MultiIntr, RTL_R16(tp, MultiIntr) & 0xf000);
5689} 5544}
5690 5545
5691static void rtl_csi_write(struct rtl8169_private *tp, int addr, int value) 5546static void rtl_csi_write(struct rtl8169_private *tp, int addr, int value)
@@ -5719,17 +5574,13 @@ static void rtl_csi_access_enable_2(struct rtl8169_private *tp)
5719 5574
5720DECLARE_RTL_COND(rtl_csiar_cond) 5575DECLARE_RTL_COND(rtl_csiar_cond)
5721{ 5576{
5722 void __iomem *ioaddr = tp->mmio_addr; 5577 return RTL_R32(tp, CSIAR) & CSIAR_FLAG;
5723
5724 return RTL_R32(CSIAR) & CSIAR_FLAG;
5725} 5578}
5726 5579
5727static void r8169_csi_write(struct rtl8169_private *tp, int addr, int value) 5580static void r8169_csi_write(struct rtl8169_private *tp, int addr, int value)
5728{ 5581{
5729 void __iomem *ioaddr = tp->mmio_addr; 5582 RTL_W32(tp, CSIDR, value);
5730 5583 RTL_W32(tp, CSIAR, CSIAR_WRITE_CMD | (addr & CSIAR_ADDR_MASK) |
5731 RTL_W32(CSIDR, value);
5732 RTL_W32(CSIAR, CSIAR_WRITE_CMD | (addr & CSIAR_ADDR_MASK) |
5733 CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT); 5584 CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT);
5734 5585
5735 rtl_udelay_loop_wait_low(tp, &rtl_csiar_cond, 10, 100); 5586 rtl_udelay_loop_wait_low(tp, &rtl_csiar_cond, 10, 100);
@@ -5737,21 +5588,17 @@ static void r8169_csi_write(struct rtl8169_private *tp, int addr, int value)
5737 5588
5738static u32 r8169_csi_read(struct rtl8169_private *tp, int addr) 5589static u32 r8169_csi_read(struct rtl8169_private *tp, int addr)
5739{ 5590{
5740 void __iomem *ioaddr = tp->mmio_addr; 5591 RTL_W32(tp, CSIAR, (addr & CSIAR_ADDR_MASK) |
5741
5742 RTL_W32(CSIAR, (addr & CSIAR_ADDR_MASK) |
5743 CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT); 5592 CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT);
5744 5593
5745 return rtl_udelay_loop_wait_high(tp, &rtl_csiar_cond, 10, 100) ? 5594 return rtl_udelay_loop_wait_high(tp, &rtl_csiar_cond, 10, 100) ?
5746 RTL_R32(CSIDR) : ~0; 5595 RTL_R32(tp, CSIDR) : ~0;
5747} 5596}
5748 5597
5749static void r8402_csi_write(struct rtl8169_private *tp, int addr, int value) 5598static void r8402_csi_write(struct rtl8169_private *tp, int addr, int value)
5750{ 5599{
5751 void __iomem *ioaddr = tp->mmio_addr; 5600 RTL_W32(tp, CSIDR, value);
5752 5601 RTL_W32(tp, CSIAR, CSIAR_WRITE_CMD | (addr & CSIAR_ADDR_MASK) |
5753 RTL_W32(CSIDR, value);
5754 RTL_W32(CSIAR, CSIAR_WRITE_CMD | (addr & CSIAR_ADDR_MASK) |
5755 CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT | 5602 CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT |
5756 CSIAR_FUNC_NIC); 5603 CSIAR_FUNC_NIC);
5757 5604
@@ -5760,21 +5607,17 @@ static void r8402_csi_write(struct rtl8169_private *tp, int addr, int value)
5760 5607
5761static u32 r8402_csi_read(struct rtl8169_private *tp, int addr) 5608static u32 r8402_csi_read(struct rtl8169_private *tp, int addr)
5762{ 5609{
5763 void __iomem *ioaddr = tp->mmio_addr; 5610 RTL_W32(tp, CSIAR, (addr & CSIAR_ADDR_MASK) | CSIAR_FUNC_NIC |
5764
5765 RTL_W32(CSIAR, (addr & CSIAR_ADDR_MASK) | CSIAR_FUNC_NIC |
5766 CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT); 5611 CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT);
5767 5612
5768 return rtl_udelay_loop_wait_high(tp, &rtl_csiar_cond, 10, 100) ? 5613 return rtl_udelay_loop_wait_high(tp, &rtl_csiar_cond, 10, 100) ?
5769 RTL_R32(CSIDR) : ~0; 5614 RTL_R32(tp, CSIDR) : ~0;
5770} 5615}
5771 5616
5772static void r8411_csi_write(struct rtl8169_private *tp, int addr, int value) 5617static void r8411_csi_write(struct rtl8169_private *tp, int addr, int value)
5773{ 5618{
5774 void __iomem *ioaddr = tp->mmio_addr; 5619 RTL_W32(tp, CSIDR, value);
5775 5620 RTL_W32(tp, CSIAR, CSIAR_WRITE_CMD | (addr & CSIAR_ADDR_MASK) |
5776 RTL_W32(CSIDR, value);
5777 RTL_W32(CSIAR, CSIAR_WRITE_CMD | (addr & CSIAR_ADDR_MASK) |
5778 CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT | 5621 CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT |
5779 CSIAR_FUNC_NIC2); 5622 CSIAR_FUNC_NIC2);
5780 5623
@@ -5783,13 +5626,11 @@ static void r8411_csi_write(struct rtl8169_private *tp, int addr, int value)
5783 5626
5784static u32 r8411_csi_read(struct rtl8169_private *tp, int addr) 5627static u32 r8411_csi_read(struct rtl8169_private *tp, int addr)
5785{ 5628{
5786 void __iomem *ioaddr = tp->mmio_addr; 5629 RTL_W32(tp, CSIAR, (addr & CSIAR_ADDR_MASK) | CSIAR_FUNC_NIC2 |
5787
5788 RTL_W32(CSIAR, (addr & CSIAR_ADDR_MASK) | CSIAR_FUNC_NIC2 |
5789 CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT); 5630 CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT);
5790 5631
5791 return rtl_udelay_loop_wait_high(tp, &rtl_csiar_cond, 10, 100) ? 5632 return rtl_udelay_loop_wait_high(tp, &rtl_csiar_cond, 10, 100) ?
5792 RTL_R32(CSIDR) : ~0; 5633 RTL_R32(tp, CSIDR) : ~0;
5793} 5634}
5794 5635
5795static void rtl_init_csi_ops(struct rtl8169_private *tp) 5636static void rtl_init_csi_ops(struct rtl8169_private *tp)
@@ -5851,31 +5692,30 @@ static void rtl_ephy_init(struct rtl8169_private *tp, const struct ephy_info *e,
5851 } 5692 }
5852} 5693}
5853 5694
5854static void rtl_disable_clock_request(struct pci_dev *pdev) 5695static void rtl_disable_clock_request(struct rtl8169_private *tp)
5855{ 5696{
5856 pcie_capability_clear_word(pdev, PCI_EXP_LNKCTL, 5697 pcie_capability_clear_word(tp->pci_dev, PCI_EXP_LNKCTL,
5857 PCI_EXP_LNKCTL_CLKREQ_EN); 5698 PCI_EXP_LNKCTL_CLKREQ_EN);
5858} 5699}
5859 5700
5860static void rtl_enable_clock_request(struct pci_dev *pdev) 5701static void rtl_enable_clock_request(struct rtl8169_private *tp)
5861{ 5702{
5862 pcie_capability_set_word(pdev, PCI_EXP_LNKCTL, 5703 pcie_capability_set_word(tp->pci_dev, PCI_EXP_LNKCTL,
5863 PCI_EXP_LNKCTL_CLKREQ_EN); 5704 PCI_EXP_LNKCTL_CLKREQ_EN);
5864} 5705}
5865 5706
5866static void rtl_pcie_state_l2l3_enable(struct rtl8169_private *tp, bool enable) 5707static void rtl_pcie_state_l2l3_enable(struct rtl8169_private *tp, bool enable)
5867{ 5708{
5868 void __iomem *ioaddr = tp->mmio_addr;
5869 u8 data; 5709 u8 data;
5870 5710
5871 data = RTL_R8(Config3); 5711 data = RTL_R8(tp, Config3);
5872 5712
5873 if (enable) 5713 if (enable)
5874 data |= Rdy_to_L23; 5714 data |= Rdy_to_L23;
5875 else 5715 else
5876 data &= ~Rdy_to_L23; 5716 data &= ~Rdy_to_L23;
5877 5717
5878 RTL_W8(Config3, data); 5718 RTL_W8(tp, Config3, data);
5879} 5719}
5880 5720
5881#define R8168_CPCMD_QUIRK_MASK (\ 5721#define R8168_CPCMD_QUIRK_MASK (\
@@ -5891,45 +5731,37 @@ static void rtl_pcie_state_l2l3_enable(struct rtl8169_private *tp, bool enable)
5891 5731
5892static void rtl_hw_start_8168bb(struct rtl8169_private *tp) 5732static void rtl_hw_start_8168bb(struct rtl8169_private *tp)
5893{ 5733{
5894 void __iomem *ioaddr = tp->mmio_addr; 5734 RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en);
5895 struct pci_dev *pdev = tp->pci_dev;
5896 5735
5897 RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); 5736 RTL_W16(tp, CPlusCmd, RTL_R16(tp, CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
5898
5899 RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
5900 5737
5901 if (tp->dev->mtu <= ETH_DATA_LEN) { 5738 if (tp->dev->mtu <= ETH_DATA_LEN) {
5902 rtl_tx_performance_tweak(pdev, (0x5 << MAX_READ_REQUEST_SHIFT) | 5739 rtl_tx_performance_tweak(tp, (0x5 << MAX_READ_REQUEST_SHIFT) |
5903 PCI_EXP_DEVCTL_NOSNOOP_EN); 5740 PCI_EXP_DEVCTL_NOSNOOP_EN);
5904 } 5741 }
5905} 5742}
5906 5743
5907static void rtl_hw_start_8168bef(struct rtl8169_private *tp) 5744static void rtl_hw_start_8168bef(struct rtl8169_private *tp)
5908{ 5745{
5909 void __iomem *ioaddr = tp->mmio_addr;
5910
5911 rtl_hw_start_8168bb(tp); 5746 rtl_hw_start_8168bb(tp);
5912 5747
5913 RTL_W8(MaxTxPacketSize, TxPacketMax); 5748 RTL_W8(tp, MaxTxPacketSize, TxPacketMax);
5914 5749
5915 RTL_W8(Config4, RTL_R8(Config4) & ~(1 << 0)); 5750 RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~(1 << 0));
5916} 5751}
5917 5752
5918static void __rtl_hw_start_8168cp(struct rtl8169_private *tp) 5753static void __rtl_hw_start_8168cp(struct rtl8169_private *tp)
5919{ 5754{
5920 void __iomem *ioaddr = tp->mmio_addr; 5755 RTL_W8(tp, Config1, RTL_R8(tp, Config1) | Speed_down);
5921 struct pci_dev *pdev = tp->pci_dev;
5922 5756
5923 RTL_W8(Config1, RTL_R8(Config1) | Speed_down); 5757 RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en);
5924
5925 RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en);
5926 5758
5927 if (tp->dev->mtu <= ETH_DATA_LEN) 5759 if (tp->dev->mtu <= ETH_DATA_LEN)
5928 rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); 5760 rtl_tx_performance_tweak(tp, 0x5 << MAX_READ_REQUEST_SHIFT);
5929 5761
5930 rtl_disable_clock_request(pdev); 5762 rtl_disable_clock_request(tp);
5931 5763
5932 RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK); 5764 RTL_W16(tp, CPlusCmd, RTL_R16(tp, CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
5933} 5765}
5934 5766
5935static void rtl_hw_start_8168cp_1(struct rtl8169_private *tp) 5767static void rtl_hw_start_8168cp_1(struct rtl8169_private *tp)
@@ -5951,42 +5783,35 @@ static void rtl_hw_start_8168cp_1(struct rtl8169_private *tp)
5951 5783
5952static void rtl_hw_start_8168cp_2(struct rtl8169_private *tp) 5784static void rtl_hw_start_8168cp_2(struct rtl8169_private *tp)
5953{ 5785{
5954 void __iomem *ioaddr = tp->mmio_addr;
5955 struct pci_dev *pdev = tp->pci_dev;
5956
5957 rtl_csi_access_enable_2(tp); 5786 rtl_csi_access_enable_2(tp);
5958 5787
5959 RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); 5788 RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en);
5960 5789
5961 if (tp->dev->mtu <= ETH_DATA_LEN) 5790 if (tp->dev->mtu <= ETH_DATA_LEN)
5962 rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); 5791 rtl_tx_performance_tweak(tp, 0x5 << MAX_READ_REQUEST_SHIFT);
5963 5792
5964 RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK); 5793 RTL_W16(tp, CPlusCmd, RTL_R16(tp, CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
5965} 5794}
5966 5795
5967static void rtl_hw_start_8168cp_3(struct rtl8169_private *tp) 5796static void rtl_hw_start_8168cp_3(struct rtl8169_private *tp)
5968{ 5797{
5969 void __iomem *ioaddr = tp->mmio_addr;
5970 struct pci_dev *pdev = tp->pci_dev;
5971
5972 rtl_csi_access_enable_2(tp); 5798 rtl_csi_access_enable_2(tp);
5973 5799
5974 RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); 5800 RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en);
5975 5801
5976 /* Magic. */ 5802 /* Magic. */
5977 RTL_W8(DBG_REG, 0x20); 5803 RTL_W8(tp, DBG_REG, 0x20);
5978 5804
5979 RTL_W8(MaxTxPacketSize, TxPacketMax); 5805 RTL_W8(tp, MaxTxPacketSize, TxPacketMax);
5980 5806
5981 if (tp->dev->mtu <= ETH_DATA_LEN) 5807 if (tp->dev->mtu <= ETH_DATA_LEN)
5982 rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); 5808 rtl_tx_performance_tweak(tp, 0x5 << MAX_READ_REQUEST_SHIFT);
5983 5809
5984 RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK); 5810 RTL_W16(tp, CPlusCmd, RTL_R16(tp, CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
5985} 5811}
5986 5812
5987static void rtl_hw_start_8168c_1(struct rtl8169_private *tp) 5813static void rtl_hw_start_8168c_1(struct rtl8169_private *tp)
5988{ 5814{
5989 void __iomem *ioaddr = tp->mmio_addr;
5990 static const struct ephy_info e_info_8168c_1[] = { 5815 static const struct ephy_info e_info_8168c_1[] = {
5991 { 0x02, 0x0800, 0x1000 }, 5816 { 0x02, 0x0800, 0x1000 },
5992 { 0x03, 0, 0x0002 }, 5817 { 0x03, 0, 0x0002 },
@@ -5995,7 +5820,7 @@ static void rtl_hw_start_8168c_1(struct rtl8169_private *tp)
5995 5820
5996 rtl_csi_access_enable_2(tp); 5821 rtl_csi_access_enable_2(tp);
5997 5822
5998 RTL_W8(DBG_REG, 0x06 | FIX_NAK_1 | FIX_NAK_2); 5823 RTL_W8(tp, DBG_REG, 0x06 | FIX_NAK_1 | FIX_NAK_2);
5999 5824
6000 rtl_ephy_init(tp, e_info_8168c_1, ARRAY_SIZE(e_info_8168c_1)); 5825 rtl_ephy_init(tp, e_info_8168c_1, ARRAY_SIZE(e_info_8168c_1));
6001 5826
@@ -6030,40 +5855,32 @@ static void rtl_hw_start_8168c_4(struct rtl8169_private *tp)
6030 5855
6031static void rtl_hw_start_8168d(struct rtl8169_private *tp) 5856static void rtl_hw_start_8168d(struct rtl8169_private *tp)
6032{ 5857{
6033 void __iomem *ioaddr = tp->mmio_addr;
6034 struct pci_dev *pdev = tp->pci_dev;
6035
6036 rtl_csi_access_enable_2(tp); 5858 rtl_csi_access_enable_2(tp);
6037 5859
6038 rtl_disable_clock_request(pdev); 5860 rtl_disable_clock_request(tp);
6039 5861
6040 RTL_W8(MaxTxPacketSize, TxPacketMax); 5862 RTL_W8(tp, MaxTxPacketSize, TxPacketMax);
6041 5863
6042 if (tp->dev->mtu <= ETH_DATA_LEN) 5864 if (tp->dev->mtu <= ETH_DATA_LEN)
6043 rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); 5865 rtl_tx_performance_tweak(tp, 0x5 << MAX_READ_REQUEST_SHIFT);
6044 5866
6045 RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK); 5867 RTL_W16(tp, CPlusCmd, RTL_R16(tp, CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
6046} 5868}
6047 5869
6048static void rtl_hw_start_8168dp(struct rtl8169_private *tp) 5870static void rtl_hw_start_8168dp(struct rtl8169_private *tp)
6049{ 5871{
6050 void __iomem *ioaddr = tp->mmio_addr;
6051 struct pci_dev *pdev = tp->pci_dev;
6052
6053 rtl_csi_access_enable_1(tp); 5872 rtl_csi_access_enable_1(tp);
6054 5873
6055 if (tp->dev->mtu <= ETH_DATA_LEN) 5874 if (tp->dev->mtu <= ETH_DATA_LEN)
6056 rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); 5875 rtl_tx_performance_tweak(tp, 0x5 << MAX_READ_REQUEST_SHIFT);
6057 5876
6058 RTL_W8(MaxTxPacketSize, TxPacketMax); 5877 RTL_W8(tp, MaxTxPacketSize, TxPacketMax);
6059 5878
6060 rtl_disable_clock_request(pdev); 5879 rtl_disable_clock_request(tp);
6061} 5880}
6062 5881
6063static void rtl_hw_start_8168d_4(struct rtl8169_private *tp) 5882static void rtl_hw_start_8168d_4(struct rtl8169_private *tp)
6064{ 5883{
6065 void __iomem *ioaddr = tp->mmio_addr;
6066 struct pci_dev *pdev = tp->pci_dev;
6067 static const struct ephy_info e_info_8168d_4[] = { 5884 static const struct ephy_info e_info_8168d_4[] = {
6068 { 0x0b, 0x0000, 0x0048 }, 5885 { 0x0b, 0x0000, 0x0048 },
6069 { 0x19, 0x0020, 0x0050 }, 5886 { 0x19, 0x0020, 0x0050 },
@@ -6072,19 +5889,17 @@ static void rtl_hw_start_8168d_4(struct rtl8169_private *tp)
6072 5889
6073 rtl_csi_access_enable_1(tp); 5890 rtl_csi_access_enable_1(tp);
6074 5891
6075 rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); 5892 rtl_tx_performance_tweak(tp, 0x5 << MAX_READ_REQUEST_SHIFT);
6076 5893
6077 RTL_W8(MaxTxPacketSize, TxPacketMax); 5894 RTL_W8(tp, MaxTxPacketSize, TxPacketMax);
6078 5895
6079 rtl_ephy_init(tp, e_info_8168d_4, ARRAY_SIZE(e_info_8168d_4)); 5896 rtl_ephy_init(tp, e_info_8168d_4, ARRAY_SIZE(e_info_8168d_4));
6080 5897
6081 rtl_enable_clock_request(pdev); 5898 rtl_enable_clock_request(tp);
6082} 5899}
6083 5900
6084static void rtl_hw_start_8168e_1(struct rtl8169_private *tp) 5901static void rtl_hw_start_8168e_1(struct rtl8169_private *tp)
6085{ 5902{
6086 void __iomem *ioaddr = tp->mmio_addr;
6087 struct pci_dev *pdev = tp->pci_dev;
6088 static const struct ephy_info e_info_8168e_1[] = { 5903 static const struct ephy_info e_info_8168e_1[] = {
6089 { 0x00, 0x0200, 0x0100 }, 5904 { 0x00, 0x0200, 0x0100 },
6090 { 0x00, 0x0000, 0x0004 }, 5905 { 0x00, 0x0000, 0x0004 },
@@ -6106,23 +5921,21 @@ static void rtl_hw_start_8168e_1(struct rtl8169_private *tp)
6106 rtl_ephy_init(tp, e_info_8168e_1, ARRAY_SIZE(e_info_8168e_1)); 5921 rtl_ephy_init(tp, e_info_8168e_1, ARRAY_SIZE(e_info_8168e_1));
6107 5922
6108 if (tp->dev->mtu <= ETH_DATA_LEN) 5923 if (tp->dev->mtu <= ETH_DATA_LEN)
6109 rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); 5924 rtl_tx_performance_tweak(tp, 0x5 << MAX_READ_REQUEST_SHIFT);
6110 5925
6111 RTL_W8(MaxTxPacketSize, TxPacketMax); 5926 RTL_W8(tp, MaxTxPacketSize, TxPacketMax);
6112 5927
6113 rtl_disable_clock_request(pdev); 5928 rtl_disable_clock_request(tp);
6114 5929
6115 /* Reset tx FIFO pointer */ 5930 /* Reset tx FIFO pointer */
6116 RTL_W32(MISC, RTL_R32(MISC) | TXPLA_RST); 5931 RTL_W32(tp, MISC, RTL_R32(tp, MISC) | TXPLA_RST);
6117 RTL_W32(MISC, RTL_R32(MISC) & ~TXPLA_RST); 5932 RTL_W32(tp, MISC, RTL_R32(tp, MISC) & ~TXPLA_RST);
6118 5933
6119 RTL_W8(Config5, RTL_R8(Config5) & ~Spi_en); 5934 RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~Spi_en);
6120} 5935}
6121 5936
6122static void rtl_hw_start_8168e_2(struct rtl8169_private *tp) 5937static void rtl_hw_start_8168e_2(struct rtl8169_private *tp)
6123{ 5938{
6124 void __iomem *ioaddr = tp->mmio_addr;
6125 struct pci_dev *pdev = tp->pci_dev;
6126 static const struct ephy_info e_info_8168e_2[] = { 5939 static const struct ephy_info e_info_8168e_2[] = {
6127 { 0x09, 0x0000, 0x0080 }, 5940 { 0x09, 0x0000, 0x0080 },
6128 { 0x19, 0x0000, 0x0224 } 5941 { 0x19, 0x0000, 0x0224 }
@@ -6133,7 +5946,7 @@ static void rtl_hw_start_8168e_2(struct rtl8169_private *tp)
6133 rtl_ephy_init(tp, e_info_8168e_2, ARRAY_SIZE(e_info_8168e_2)); 5946 rtl_ephy_init(tp, e_info_8168e_2, ARRAY_SIZE(e_info_8168e_2));
6134 5947
6135 if (tp->dev->mtu <= ETH_DATA_LEN) 5948 if (tp->dev->mtu <= ETH_DATA_LEN)
6136 rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); 5949 rtl_tx_performance_tweak(tp, 0x5 << MAX_READ_REQUEST_SHIFT);
6137 5950
6138 rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); 5951 rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
6139 rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); 5952 rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
@@ -6144,29 +5957,26 @@ static void rtl_hw_start_8168e_2(struct rtl8169_private *tp)
6144 rtl_w0w1_eri(tp, 0x1b0, ERIAR_MASK_0001, 0x10, 0x00, ERIAR_EXGMAC); 5957 rtl_w0w1_eri(tp, 0x1b0, ERIAR_MASK_0001, 0x10, 0x00, ERIAR_EXGMAC);
6145 rtl_w0w1_eri(tp, 0x0d4, ERIAR_MASK_0011, 0x0c00, 0xff00, ERIAR_EXGMAC); 5958 rtl_w0w1_eri(tp, 0x0d4, ERIAR_MASK_0011, 0x0c00, 0xff00, ERIAR_EXGMAC);
6146 5959
6147 RTL_W8(MaxTxPacketSize, EarlySize); 5960 RTL_W8(tp, MaxTxPacketSize, EarlySize);
6148 5961
6149 rtl_disable_clock_request(pdev); 5962 rtl_disable_clock_request(tp);
6150 5963
6151 RTL_W32(TxConfig, RTL_R32(TxConfig) | TXCFG_AUTO_FIFO); 5964 RTL_W32(tp, TxConfig, RTL_R32(tp, TxConfig) | TXCFG_AUTO_FIFO);
6152 RTL_W8(MCU, RTL_R8(MCU) & ~NOW_IS_OOB); 5965 RTL_W8(tp, MCU, RTL_R8(tp, MCU) & ~NOW_IS_OOB);
6153 5966
6154 /* Adjust EEE LED frequency */ 5967 /* Adjust EEE LED frequency */
6155 RTL_W8(EEE_LED, RTL_R8(EEE_LED) & ~0x07); 5968 RTL_W8(tp, EEE_LED, RTL_R8(tp, EEE_LED) & ~0x07);
6156 5969
6157 RTL_W8(DLLPR, RTL_R8(DLLPR) | PFM_EN); 5970 RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) | PFM_EN);
6158 RTL_W32(MISC, RTL_R32(MISC) | PWM_EN); 5971 RTL_W32(tp, MISC, RTL_R32(tp, MISC) | PWM_EN);
6159 RTL_W8(Config5, RTL_R8(Config5) & ~Spi_en); 5972 RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~Spi_en);
6160} 5973}
6161 5974
6162static void rtl_hw_start_8168f(struct rtl8169_private *tp) 5975static void rtl_hw_start_8168f(struct rtl8169_private *tp)
6163{ 5976{
6164 void __iomem *ioaddr = tp->mmio_addr;
6165 struct pci_dev *pdev = tp->pci_dev;
6166
6167 rtl_csi_access_enable_2(tp); 5977 rtl_csi_access_enable_2(tp);
6168 5978
6169 rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); 5979 rtl_tx_performance_tweak(tp, 0x5 << MAX_READ_REQUEST_SHIFT);
6170 5980
6171 rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); 5981 rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
6172 rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); 5982 rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
@@ -6179,20 +5989,19 @@ static void rtl_hw_start_8168f(struct rtl8169_private *tp)
6179 rtl_eri_write(tp, 0xcc, ERIAR_MASK_1111, 0x00000050, ERIAR_EXGMAC); 5989 rtl_eri_write(tp, 0xcc, ERIAR_MASK_1111, 0x00000050, ERIAR_EXGMAC);
6180 rtl_eri_write(tp, 0xd0, ERIAR_MASK_1111, 0x00000060, ERIAR_EXGMAC); 5990 rtl_eri_write(tp, 0xd0, ERIAR_MASK_1111, 0x00000060, ERIAR_EXGMAC);
6181 5991
6182 RTL_W8(MaxTxPacketSize, EarlySize); 5992 RTL_W8(tp, MaxTxPacketSize, EarlySize);
6183 5993
6184 rtl_disable_clock_request(pdev); 5994 rtl_disable_clock_request(tp);
6185 5995
6186 RTL_W32(TxConfig, RTL_R32(TxConfig) | TXCFG_AUTO_FIFO); 5996 RTL_W32(tp, TxConfig, RTL_R32(tp, TxConfig) | TXCFG_AUTO_FIFO);
6187 RTL_W8(MCU, RTL_R8(MCU) & ~NOW_IS_OOB); 5997 RTL_W8(tp, MCU, RTL_R8(tp, MCU) & ~NOW_IS_OOB);
6188 RTL_W8(DLLPR, RTL_R8(DLLPR) | PFM_EN); 5998 RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) | PFM_EN);
6189 RTL_W32(MISC, RTL_R32(MISC) | PWM_EN); 5999 RTL_W32(tp, MISC, RTL_R32(tp, MISC) | PWM_EN);
6190 RTL_W8(Config5, RTL_R8(Config5) & ~Spi_en); 6000 RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~Spi_en);
6191} 6001}
6192 6002
6193static void rtl_hw_start_8168f_1(struct rtl8169_private *tp) 6003static void rtl_hw_start_8168f_1(struct rtl8169_private *tp)
6194{ 6004{
6195 void __iomem *ioaddr = tp->mmio_addr;
6196 static const struct ephy_info e_info_8168f_1[] = { 6005 static const struct ephy_info e_info_8168f_1[] = {
6197 { 0x06, 0x00c0, 0x0020 }, 6006 { 0x06, 0x00c0, 0x0020 },
6198 { 0x08, 0x0001, 0x0002 }, 6007 { 0x08, 0x0001, 0x0002 },
@@ -6207,7 +6016,7 @@ static void rtl_hw_start_8168f_1(struct rtl8169_private *tp)
6207 rtl_w0w1_eri(tp, 0x0d4, ERIAR_MASK_0011, 0x0c00, 0xff00, ERIAR_EXGMAC); 6016 rtl_w0w1_eri(tp, 0x0d4, ERIAR_MASK_0011, 0x0c00, 0xff00, ERIAR_EXGMAC);
6208 6017
6209 /* Adjust EEE LED frequency */ 6018 /* Adjust EEE LED frequency */
6210 RTL_W8(EEE_LED, RTL_R8(EEE_LED) & ~0x07); 6019 RTL_W8(tp, EEE_LED, RTL_R8(tp, EEE_LED) & ~0x07);
6211} 6020}
6212 6021
6213static void rtl_hw_start_8411(struct rtl8169_private *tp) 6022static void rtl_hw_start_8411(struct rtl8169_private *tp)
@@ -6229,10 +6038,7 @@ static void rtl_hw_start_8411(struct rtl8169_private *tp)
6229 6038
6230static void rtl_hw_start_8168g(struct rtl8169_private *tp) 6039static void rtl_hw_start_8168g(struct rtl8169_private *tp)
6231{ 6040{
6232 void __iomem *ioaddr = tp->mmio_addr; 6041 RTL_W32(tp, TxConfig, RTL_R32(tp, TxConfig) | TXCFG_AUTO_FIFO);
6233 struct pci_dev *pdev = tp->pci_dev;
6234
6235 RTL_W32(TxConfig, RTL_R32(TxConfig) | TXCFG_AUTO_FIFO);
6236 6042
6237 rtl_eri_write(tp, 0xc8, ERIAR_MASK_0101, 0x080002, ERIAR_EXGMAC); 6043 rtl_eri_write(tp, 0xc8, ERIAR_MASK_0101, 0x080002, ERIAR_EXGMAC);
6238 rtl_eri_write(tp, 0xcc, ERIAR_MASK_0001, 0x38, ERIAR_EXGMAC); 6044 rtl_eri_write(tp, 0xcc, ERIAR_MASK_0001, 0x38, ERIAR_EXGMAC);
@@ -6241,20 +6047,20 @@ static void rtl_hw_start_8168g(struct rtl8169_private *tp)
6241 6047
6242 rtl_csi_access_enable_1(tp); 6048 rtl_csi_access_enable_1(tp);
6243 6049
6244 rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); 6050 rtl_tx_performance_tweak(tp, 0x5 << MAX_READ_REQUEST_SHIFT);
6245 6051
6246 rtl_w0w1_eri(tp, 0xdc, ERIAR_MASK_0001, 0x00, 0x01, ERIAR_EXGMAC); 6052 rtl_w0w1_eri(tp, 0xdc, ERIAR_MASK_0001, 0x00, 0x01, ERIAR_EXGMAC);
6247 rtl_w0w1_eri(tp, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, ERIAR_EXGMAC); 6053 rtl_w0w1_eri(tp, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, ERIAR_EXGMAC);
6248 rtl_eri_write(tp, 0x2f8, ERIAR_MASK_0011, 0x1d8f, ERIAR_EXGMAC); 6054 rtl_eri_write(tp, 0x2f8, ERIAR_MASK_0011, 0x1d8f, ERIAR_EXGMAC);
6249 6055
6250 RTL_W32(MISC, RTL_R32(MISC) & ~RXDV_GATED_EN); 6056 RTL_W32(tp, MISC, RTL_R32(tp, MISC) & ~RXDV_GATED_EN);
6251 RTL_W8(MaxTxPacketSize, EarlySize); 6057 RTL_W8(tp, MaxTxPacketSize, EarlySize);
6252 6058
6253 rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); 6059 rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
6254 rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); 6060 rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
6255 6061
6256 /* Adjust EEE LED frequency */ 6062 /* Adjust EEE LED frequency */
6257 RTL_W8(EEE_LED, RTL_R8(EEE_LED) & ~0x07); 6063 RTL_W8(tp, EEE_LED, RTL_R8(tp, EEE_LED) & ~0x07);
6258 6064
6259 rtl_w0w1_eri(tp, 0x2fc, ERIAR_MASK_0001, 0x01, 0x06, ERIAR_EXGMAC); 6065 rtl_w0w1_eri(tp, 0x2fc, ERIAR_MASK_0001, 0x01, 0x06, ERIAR_EXGMAC);
6260 rtl_w0w1_eri(tp, 0x1b0, ERIAR_MASK_0011, 0x0000, 0x1000, ERIAR_EXGMAC); 6066 rtl_w0w1_eri(tp, 0x1b0, ERIAR_MASK_0011, 0x0000, 0x1000, ERIAR_EXGMAC);
@@ -6264,7 +6070,6 @@ static void rtl_hw_start_8168g(struct rtl8169_private *tp)
6264 6070
6265static void rtl_hw_start_8168g_1(struct rtl8169_private *tp) 6071static void rtl_hw_start_8168g_1(struct rtl8169_private *tp)
6266{ 6072{
6267 void __iomem *ioaddr = tp->mmio_addr;
6268 static const struct ephy_info e_info_8168g_1[] = { 6073 static const struct ephy_info e_info_8168g_1[] = {
6269 { 0x00, 0x0000, 0x0008 }, 6074 { 0x00, 0x0000, 0x0008 },
6270 { 0x0c, 0x37d0, 0x0820 }, 6075 { 0x0c, 0x37d0, 0x0820 },
@@ -6275,14 +6080,13 @@ static void rtl_hw_start_8168g_1(struct rtl8169_private *tp)
6275 rtl_hw_start_8168g(tp); 6080 rtl_hw_start_8168g(tp);
6276 6081
6277 /* disable aspm and clock request before access ephy */ 6082 /* disable aspm and clock request before access ephy */
6278 RTL_W8(Config2, RTL_R8(Config2) & ~ClkReqEn); 6083 RTL_W8(tp, Config2, RTL_R8(tp, Config2) & ~ClkReqEn);
6279 RTL_W8(Config5, RTL_R8(Config5) & ~ASPM_en); 6084 RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~ASPM_en);
6280 rtl_ephy_init(tp, e_info_8168g_1, ARRAY_SIZE(e_info_8168g_1)); 6085 rtl_ephy_init(tp, e_info_8168g_1, ARRAY_SIZE(e_info_8168g_1));
6281} 6086}
6282 6087
6283static void rtl_hw_start_8168g_2(struct rtl8169_private *tp) 6088static void rtl_hw_start_8168g_2(struct rtl8169_private *tp)
6284{ 6089{
6285 void __iomem *ioaddr = tp->mmio_addr;
6286 static const struct ephy_info e_info_8168g_2[] = { 6090 static const struct ephy_info e_info_8168g_2[] = {
6287 { 0x00, 0x0000, 0x0008 }, 6091 { 0x00, 0x0000, 0x0008 },
6288 { 0x0c, 0x3df0, 0x0200 }, 6092 { 0x0c, 0x3df0, 0x0200 },
@@ -6293,14 +6097,13 @@ static void rtl_hw_start_8168g_2(struct rtl8169_private *tp)
6293 rtl_hw_start_8168g(tp); 6097 rtl_hw_start_8168g(tp);
6294 6098
6295 /* disable aspm and clock request before access ephy */ 6099 /* disable aspm and clock request before access ephy */
6296 RTL_W8(Config2, RTL_R8(Config2) & ~ClkReqEn); 6100 RTL_W8(tp, Config2, RTL_R8(tp, Config2) & ~ClkReqEn);
6297 RTL_W8(Config5, RTL_R8(Config5) & ~ASPM_en); 6101 RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~ASPM_en);
6298 rtl_ephy_init(tp, e_info_8168g_2, ARRAY_SIZE(e_info_8168g_2)); 6102 rtl_ephy_init(tp, e_info_8168g_2, ARRAY_SIZE(e_info_8168g_2));
6299} 6103}
6300 6104
6301static void rtl_hw_start_8411_2(struct rtl8169_private *tp) 6105static void rtl_hw_start_8411_2(struct rtl8169_private *tp)
6302{ 6106{
6303 void __iomem *ioaddr = tp->mmio_addr;
6304 static const struct ephy_info e_info_8411_2[] = { 6107 static const struct ephy_info e_info_8411_2[] = {
6305 { 0x00, 0x0000, 0x0008 }, 6108 { 0x00, 0x0000, 0x0008 },
6306 { 0x0c, 0x3df0, 0x0200 }, 6109 { 0x0c, 0x3df0, 0x0200 },
@@ -6312,15 +6115,13 @@ static void rtl_hw_start_8411_2(struct rtl8169_private *tp)
6312 rtl_hw_start_8168g(tp); 6115 rtl_hw_start_8168g(tp);
6313 6116
6314 /* disable aspm and clock request before access ephy */ 6117 /* disable aspm and clock request before access ephy */
6315 RTL_W8(Config2, RTL_R8(Config2) & ~ClkReqEn); 6118 RTL_W8(tp, Config2, RTL_R8(tp, Config2) & ~ClkReqEn);
6316 RTL_W8(Config5, RTL_R8(Config5) & ~ASPM_en); 6119 RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~ASPM_en);
6317 rtl_ephy_init(tp, e_info_8411_2, ARRAY_SIZE(e_info_8411_2)); 6120 rtl_ephy_init(tp, e_info_8411_2, ARRAY_SIZE(e_info_8411_2));
6318} 6121}
6319 6122
6320static void rtl_hw_start_8168h_1(struct rtl8169_private *tp) 6123static void rtl_hw_start_8168h_1(struct rtl8169_private *tp)
6321{ 6124{
6322 void __iomem *ioaddr = tp->mmio_addr;
6323 struct pci_dev *pdev = tp->pci_dev;
6324 int rg_saw_cnt; 6125 int rg_saw_cnt;
6325 u32 data; 6126 u32 data;
6326 static const struct ephy_info e_info_8168h_1[] = { 6127 static const struct ephy_info e_info_8168h_1[] = {
@@ -6333,11 +6134,11 @@ static void rtl_hw_start_8168h_1(struct rtl8169_private *tp)
6333 }; 6134 };
6334 6135
6335 /* disable aspm and clock request before access ephy */ 6136 /* disable aspm and clock request before access ephy */
6336 RTL_W8(Config2, RTL_R8(Config2) & ~ClkReqEn); 6137 RTL_W8(tp, Config2, RTL_R8(tp, Config2) & ~ClkReqEn);
6337 RTL_W8(Config5, RTL_R8(Config5) & ~ASPM_en); 6138 RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~ASPM_en);
6338 rtl_ephy_init(tp, e_info_8168h_1, ARRAY_SIZE(e_info_8168h_1)); 6139 rtl_ephy_init(tp, e_info_8168h_1, ARRAY_SIZE(e_info_8168h_1));
6339 6140
6340 RTL_W32(TxConfig, RTL_R32(TxConfig) | TXCFG_AUTO_FIFO); 6141 RTL_W32(tp, TxConfig, RTL_R32(tp, TxConfig) | TXCFG_AUTO_FIFO);
6341 6142
6342 rtl_eri_write(tp, 0xc8, ERIAR_MASK_0101, 0x00080002, ERIAR_EXGMAC); 6143 rtl_eri_write(tp, 0xc8, ERIAR_MASK_0101, 0x00080002, ERIAR_EXGMAC);
6343 rtl_eri_write(tp, 0xcc, ERIAR_MASK_0001, 0x38, ERIAR_EXGMAC); 6144 rtl_eri_write(tp, 0xcc, ERIAR_MASK_0001, 0x38, ERIAR_EXGMAC);
@@ -6346,7 +6147,7 @@ static void rtl_hw_start_8168h_1(struct rtl8169_private *tp)
6346 6147
6347 rtl_csi_access_enable_1(tp); 6148 rtl_csi_access_enable_1(tp);
6348 6149
6349 rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); 6150 rtl_tx_performance_tweak(tp, 0x5 << MAX_READ_REQUEST_SHIFT);
6350 6151
6351 rtl_w0w1_eri(tp, 0xdc, ERIAR_MASK_0001, 0x00, 0x01, ERIAR_EXGMAC); 6152 rtl_w0w1_eri(tp, 0xdc, ERIAR_MASK_0001, 0x00, 0x01, ERIAR_EXGMAC);
6352 rtl_w0w1_eri(tp, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, ERIAR_EXGMAC); 6153 rtl_w0w1_eri(tp, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, ERIAR_EXGMAC);
@@ -6357,19 +6158,19 @@ static void rtl_hw_start_8168h_1(struct rtl8169_private *tp)
6357 6158
6358 rtl_eri_write(tp, 0x5f0, ERIAR_MASK_0011, 0x4f87, ERIAR_EXGMAC); 6159 rtl_eri_write(tp, 0x5f0, ERIAR_MASK_0011, 0x4f87, ERIAR_EXGMAC);
6359 6160
6360 RTL_W32(MISC, RTL_R32(MISC) & ~RXDV_GATED_EN); 6161 RTL_W32(tp, MISC, RTL_R32(tp, MISC) & ~RXDV_GATED_EN);
6361 RTL_W8(MaxTxPacketSize, EarlySize); 6162 RTL_W8(tp, MaxTxPacketSize, EarlySize);
6362 6163
6363 rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); 6164 rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
6364 rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); 6165 rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
6365 6166
6366 /* Adjust EEE LED frequency */ 6167 /* Adjust EEE LED frequency */
6367 RTL_W8(EEE_LED, RTL_R8(EEE_LED) & ~0x07); 6168 RTL_W8(tp, EEE_LED, RTL_R8(tp, EEE_LED) & ~0x07);
6368 6169
6369 RTL_W8(DLLPR, RTL_R8(DLLPR) & ~PFM_EN); 6170 RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~PFM_EN);
6370 RTL_W8(MISC_1, RTL_R8(MISC_1) & ~PFM_D3COLD_EN); 6171 RTL_W8(tp, MISC_1, RTL_R8(tp, MISC_1) & ~PFM_D3COLD_EN);
6371 6172
6372 RTL_W8(DLLPR, RTL_R8(DLLPR) & ~TX_10M_PS_EN); 6173 RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~TX_10M_PS_EN);
6373 6174
6374 rtl_w0w1_eri(tp, 0x1b0, ERIAR_MASK_0011, 0x0000, 0x1000, ERIAR_EXGMAC); 6175 rtl_w0w1_eri(tp, 0x1b0, ERIAR_MASK_0011, 0x0000, 0x1000, ERIAR_EXGMAC);
6375 6176
@@ -6417,12 +6218,9 @@ static void rtl_hw_start_8168h_1(struct rtl8169_private *tp)
6417 6218
6418static void rtl_hw_start_8168ep(struct rtl8169_private *tp) 6219static void rtl_hw_start_8168ep(struct rtl8169_private *tp)
6419{ 6220{
6420 void __iomem *ioaddr = tp->mmio_addr;
6421 struct pci_dev *pdev = tp->pci_dev;
6422
6423 rtl8168ep_stop_cmac(tp); 6221 rtl8168ep_stop_cmac(tp);
6424 6222
6425 RTL_W32(TxConfig, RTL_R32(TxConfig) | TXCFG_AUTO_FIFO); 6223 RTL_W32(tp, TxConfig, RTL_R32(tp, TxConfig) | TXCFG_AUTO_FIFO);
6426 6224
6427 rtl_eri_write(tp, 0xc8, ERIAR_MASK_0101, 0x00080002, ERIAR_EXGMAC); 6225 rtl_eri_write(tp, 0xc8, ERIAR_MASK_0101, 0x00080002, ERIAR_EXGMAC);
6428 rtl_eri_write(tp, 0xcc, ERIAR_MASK_0001, 0x2f, ERIAR_EXGMAC); 6226 rtl_eri_write(tp, 0xcc, ERIAR_MASK_0001, 0x2f, ERIAR_EXGMAC);
@@ -6431,7 +6229,7 @@ static void rtl_hw_start_8168ep(struct rtl8169_private *tp)
6431 6229
6432 rtl_csi_access_enable_1(tp); 6230 rtl_csi_access_enable_1(tp);
6433 6231
6434 rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); 6232 rtl_tx_performance_tweak(tp, 0x5 << MAX_READ_REQUEST_SHIFT);
6435 6233
6436 rtl_w0w1_eri(tp, 0xdc, ERIAR_MASK_0001, 0x00, 0x01, ERIAR_EXGMAC); 6234 rtl_w0w1_eri(tp, 0xdc, ERIAR_MASK_0001, 0x00, 0x01, ERIAR_EXGMAC);
6437 rtl_w0w1_eri(tp, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, ERIAR_EXGMAC); 6235 rtl_w0w1_eri(tp, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, ERIAR_EXGMAC);
@@ -6440,25 +6238,24 @@ static void rtl_hw_start_8168ep(struct rtl8169_private *tp)
6440 6238
6441 rtl_eri_write(tp, 0x5f0, ERIAR_MASK_0011, 0x4f87, ERIAR_EXGMAC); 6239 rtl_eri_write(tp, 0x5f0, ERIAR_MASK_0011, 0x4f87, ERIAR_EXGMAC);
6442 6240
6443 RTL_W32(MISC, RTL_R32(MISC) & ~RXDV_GATED_EN); 6241 RTL_W32(tp, MISC, RTL_R32(tp, MISC) & ~RXDV_GATED_EN);
6444 RTL_W8(MaxTxPacketSize, EarlySize); 6242 RTL_W8(tp, MaxTxPacketSize, EarlySize);
6445 6243
6446 rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); 6244 rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
6447 rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); 6245 rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
6448 6246
6449 /* Adjust EEE LED frequency */ 6247 /* Adjust EEE LED frequency */
6450 RTL_W8(EEE_LED, RTL_R8(EEE_LED) & ~0x07); 6248 RTL_W8(tp, EEE_LED, RTL_R8(tp, EEE_LED) & ~0x07);
6451 6249
6452 rtl_w0w1_eri(tp, 0x2fc, ERIAR_MASK_0001, 0x01, 0x06, ERIAR_EXGMAC); 6250 rtl_w0w1_eri(tp, 0x2fc, ERIAR_MASK_0001, 0x01, 0x06, ERIAR_EXGMAC);
6453 6251
6454 RTL_W8(DLLPR, RTL_R8(DLLPR) & ~TX_10M_PS_EN); 6252 RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~TX_10M_PS_EN);
6455 6253
6456 rtl_pcie_state_l2l3_enable(tp, false); 6254 rtl_pcie_state_l2l3_enable(tp, false);
6457} 6255}
6458 6256
6459static void rtl_hw_start_8168ep_1(struct rtl8169_private *tp) 6257static void rtl_hw_start_8168ep_1(struct rtl8169_private *tp)
6460{ 6258{
6461 void __iomem *ioaddr = tp->mmio_addr;
6462 static const struct ephy_info e_info_8168ep_1[] = { 6259 static const struct ephy_info e_info_8168ep_1[] = {
6463 { 0x00, 0xffff, 0x10ab }, 6260 { 0x00, 0xffff, 0x10ab },
6464 { 0x06, 0xffff, 0xf030 }, 6261 { 0x06, 0xffff, 0xf030 },
@@ -6468,8 +6265,8 @@ static void rtl_hw_start_8168ep_1(struct rtl8169_private *tp)
6468 }; 6265 };
6469 6266
6470 /* disable aspm and clock request before access ephy */ 6267 /* disable aspm and clock request before access ephy */
6471 RTL_W8(Config2, RTL_R8(Config2) & ~ClkReqEn); 6268 RTL_W8(tp, Config2, RTL_R8(tp, Config2) & ~ClkReqEn);
6472 RTL_W8(Config5, RTL_R8(Config5) & ~ASPM_en); 6269 RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~ASPM_en);
6473 rtl_ephy_init(tp, e_info_8168ep_1, ARRAY_SIZE(e_info_8168ep_1)); 6270 rtl_ephy_init(tp, e_info_8168ep_1, ARRAY_SIZE(e_info_8168ep_1));
6474 6271
6475 rtl_hw_start_8168ep(tp); 6272 rtl_hw_start_8168ep(tp);
@@ -6477,7 +6274,6 @@ static void rtl_hw_start_8168ep_1(struct rtl8169_private *tp)
6477 6274
6478static void rtl_hw_start_8168ep_2(struct rtl8169_private *tp) 6275static void rtl_hw_start_8168ep_2(struct rtl8169_private *tp)
6479{ 6276{
6480 void __iomem *ioaddr = tp->mmio_addr;
6481 static const struct ephy_info e_info_8168ep_2[] = { 6277 static const struct ephy_info e_info_8168ep_2[] = {
6482 { 0x00, 0xffff, 0x10a3 }, 6278 { 0x00, 0xffff, 0x10a3 },
6483 { 0x19, 0xffff, 0xfc00 }, 6279 { 0x19, 0xffff, 0xfc00 },
@@ -6485,19 +6281,18 @@ static void rtl_hw_start_8168ep_2(struct rtl8169_private *tp)
6485 }; 6281 };
6486 6282
6487 /* disable aspm and clock request before access ephy */ 6283 /* disable aspm and clock request before access ephy */
6488 RTL_W8(Config2, RTL_R8(Config2) & ~ClkReqEn); 6284 RTL_W8(tp, Config2, RTL_R8(tp, Config2) & ~ClkReqEn);
6489 RTL_W8(Config5, RTL_R8(Config5) & ~ASPM_en); 6285 RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~ASPM_en);
6490 rtl_ephy_init(tp, e_info_8168ep_2, ARRAY_SIZE(e_info_8168ep_2)); 6286 rtl_ephy_init(tp, e_info_8168ep_2, ARRAY_SIZE(e_info_8168ep_2));
6491 6287
6492 rtl_hw_start_8168ep(tp); 6288 rtl_hw_start_8168ep(tp);
6493 6289
6494 RTL_W8(DLLPR, RTL_R8(DLLPR) & ~PFM_EN); 6290 RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~PFM_EN);
6495 RTL_W8(MISC_1, RTL_R8(MISC_1) & ~PFM_D3COLD_EN); 6291 RTL_W8(tp, MISC_1, RTL_R8(tp, MISC_1) & ~PFM_D3COLD_EN);
6496} 6292}
6497 6293
6498static void rtl_hw_start_8168ep_3(struct rtl8169_private *tp) 6294static void rtl_hw_start_8168ep_3(struct rtl8169_private *tp)
6499{ 6295{
6500 void __iomem *ioaddr = tp->mmio_addr;
6501 u32 data; 6296 u32 data;
6502 static const struct ephy_info e_info_8168ep_3[] = { 6297 static const struct ephy_info e_info_8168ep_3[] = {
6503 { 0x00, 0xffff, 0x10a3 }, 6298 { 0x00, 0xffff, 0x10a3 },
@@ -6507,14 +6302,14 @@ static void rtl_hw_start_8168ep_3(struct rtl8169_private *tp)
6507 }; 6302 };
6508 6303
6509 /* disable aspm and clock request before access ephy */ 6304 /* disable aspm and clock request before access ephy */
6510 RTL_W8(Config2, RTL_R8(Config2) & ~ClkReqEn); 6305 RTL_W8(tp, Config2, RTL_R8(tp, Config2) & ~ClkReqEn);
6511 RTL_W8(Config5, RTL_R8(Config5) & ~ASPM_en); 6306 RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~ASPM_en);
6512 rtl_ephy_init(tp, e_info_8168ep_3, ARRAY_SIZE(e_info_8168ep_3)); 6307 rtl_ephy_init(tp, e_info_8168ep_3, ARRAY_SIZE(e_info_8168ep_3));
6513 6308
6514 rtl_hw_start_8168ep(tp); 6309 rtl_hw_start_8168ep(tp);
6515 6310
6516 RTL_W8(DLLPR, RTL_R8(DLLPR) & ~PFM_EN); 6311 RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~PFM_EN);
6517 RTL_W8(MISC_1, RTL_R8(MISC_1) & ~PFM_D3COLD_EN); 6312 RTL_W8(tp, MISC_1, RTL_R8(tp, MISC_1) & ~PFM_D3COLD_EN);
6518 6313
6519 data = r8168_mac_ocp_read(tp, 0xd3e2); 6314 data = r8168_mac_ocp_read(tp, 0xd3e2);
6520 data &= 0xf000; 6315 data &= 0xf000;
@@ -6533,19 +6328,18 @@ static void rtl_hw_start_8168ep_3(struct rtl8169_private *tp)
6533static void rtl_hw_start_8168(struct net_device *dev) 6328static void rtl_hw_start_8168(struct net_device *dev)
6534{ 6329{
6535 struct rtl8169_private *tp = netdev_priv(dev); 6330 struct rtl8169_private *tp = netdev_priv(dev);
6536 void __iomem *ioaddr = tp->mmio_addr;
6537 6331
6538 RTL_W8(Cfg9346, Cfg9346_Unlock); 6332 RTL_W8(tp, Cfg9346, Cfg9346_Unlock);
6539 6333
6540 RTL_W8(MaxTxPacketSize, TxPacketMax); 6334 RTL_W8(tp, MaxTxPacketSize, TxPacketMax);
6541 6335
6542 rtl_set_rx_max_size(ioaddr, rx_buf_sz); 6336 rtl_set_rx_max_size(tp, rx_buf_sz);
6543 6337
6544 tp->cp_cmd |= RTL_R16(CPlusCmd) | PktCntrDisable | INTT_1; 6338 tp->cp_cmd |= RTL_R16(tp, CPlusCmd) | PktCntrDisable | INTT_1;
6545 6339
6546 RTL_W16(CPlusCmd, tp->cp_cmd); 6340 RTL_W16(tp, CPlusCmd, tp->cp_cmd);
6547 6341
6548 RTL_W16(IntrMitigate, 0x5151); 6342 RTL_W16(tp, IntrMitigate, 0x5151);
6549 6343
6550 /* Work around for RxFIFO overflow. */ 6344 /* Work around for RxFIFO overflow. */
6551 if (tp->mac_version == RTL_GIGA_MAC_VER_11) { 6345 if (tp->mac_version == RTL_GIGA_MAC_VER_11) {
@@ -6553,11 +6347,11 @@ static void rtl_hw_start_8168(struct net_device *dev)
6553 tp->event_slow &= ~RxOverflow; 6347 tp->event_slow &= ~RxOverflow;
6554 } 6348 }
6555 6349
6556 rtl_set_rx_tx_desc_registers(tp, ioaddr); 6350 rtl_set_rx_tx_desc_registers(tp);
6557 6351
6558 rtl_set_rx_tx_config_registers(tp); 6352 rtl_set_rx_tx_config_registers(tp);
6559 6353
6560 RTL_R8(IntrMask); 6354 RTL_R8(tp, IntrMask);
6561 6355
6562 switch (tp->mac_version) { 6356 switch (tp->mac_version) {
6563 case RTL_GIGA_MAC_VER_11: 6357 case RTL_GIGA_MAC_VER_11:
@@ -6663,13 +6457,13 @@ static void rtl_hw_start_8168(struct net_device *dev)
6663 break; 6457 break;
6664 } 6458 }
6665 6459
6666 RTL_W8(Cfg9346, Cfg9346_Lock); 6460 RTL_W8(tp, Cfg9346, Cfg9346_Lock);
6667 6461
6668 RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); 6462 RTL_W8(tp, ChipCmd, CmdTxEnb | CmdRxEnb);
6669 6463
6670 rtl_set_rx_mode(dev); 6464 rtl_set_rx_mode(dev);
6671 6465
6672 RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xf000); 6466 RTL_W16(tp, MultiIntr, RTL_R16(tp, MultiIntr) & 0xf000);
6673} 6467}
6674 6468
6675#define R810X_CPCMD_QUIRK_MASK (\ 6469#define R810X_CPCMD_QUIRK_MASK (\
@@ -6685,8 +6479,6 @@ static void rtl_hw_start_8168(struct net_device *dev)
6685 6479
6686static void rtl_hw_start_8102e_1(struct rtl8169_private *tp) 6480static void rtl_hw_start_8102e_1(struct rtl8169_private *tp)
6687{ 6481{
6688 void __iomem *ioaddr = tp->mmio_addr;
6689 struct pci_dev *pdev = tp->pci_dev;
6690 static const struct ephy_info e_info_8102e_1[] = { 6482 static const struct ephy_info e_info_8102e_1[] = {
6691 { 0x01, 0, 0x6e65 }, 6483 { 0x01, 0, 0x6e65 },
6692 { 0x02, 0, 0x091f }, 6484 { 0x02, 0, 0x091f },
@@ -6701,32 +6493,29 @@ static void rtl_hw_start_8102e_1(struct rtl8169_private *tp)
6701 6493
6702 rtl_csi_access_enable_2(tp); 6494 rtl_csi_access_enable_2(tp);
6703 6495
6704 RTL_W8(DBG_REG, FIX_NAK_1); 6496 RTL_W8(tp, DBG_REG, FIX_NAK_1);
6705 6497
6706 rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); 6498 rtl_tx_performance_tweak(tp, 0x5 << MAX_READ_REQUEST_SHIFT);
6707 6499
6708 RTL_W8(Config1, 6500 RTL_W8(tp, Config1,
6709 LEDS1 | LEDS0 | Speed_down | MEMMAP | IOMAP | VPD | PMEnable); 6501 LEDS1 | LEDS0 | Speed_down | MEMMAP | IOMAP | VPD | PMEnable);
6710 RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); 6502 RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en);
6711 6503
6712 cfg1 = RTL_R8(Config1); 6504 cfg1 = RTL_R8(tp, Config1);
6713 if ((cfg1 & LEDS0) && (cfg1 & LEDS1)) 6505 if ((cfg1 & LEDS0) && (cfg1 & LEDS1))
6714 RTL_W8(Config1, cfg1 & ~LEDS0); 6506 RTL_W8(tp, Config1, cfg1 & ~LEDS0);
6715 6507
6716 rtl_ephy_init(tp, e_info_8102e_1, ARRAY_SIZE(e_info_8102e_1)); 6508 rtl_ephy_init(tp, e_info_8102e_1, ARRAY_SIZE(e_info_8102e_1));
6717} 6509}
6718 6510
6719static void rtl_hw_start_8102e_2(struct rtl8169_private *tp) 6511static void rtl_hw_start_8102e_2(struct rtl8169_private *tp)
6720{ 6512{
6721 void __iomem *ioaddr = tp->mmio_addr;
6722 struct pci_dev *pdev = tp->pci_dev;
6723
6724 rtl_csi_access_enable_2(tp); 6513 rtl_csi_access_enable_2(tp);
6725 6514
6726 rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); 6515 rtl_tx_performance_tweak(tp, 0x5 << MAX_READ_REQUEST_SHIFT);
6727 6516
6728 RTL_W8(Config1, MEMMAP | IOMAP | VPD | PMEnable); 6517 RTL_W8(tp, Config1, MEMMAP | IOMAP | VPD | PMEnable);
6729 RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); 6518 RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en);
6730} 6519}
6731 6520
6732static void rtl_hw_start_8102e_3(struct rtl8169_private *tp) 6521static void rtl_hw_start_8102e_3(struct rtl8169_private *tp)
@@ -6738,7 +6527,6 @@ static void rtl_hw_start_8102e_3(struct rtl8169_private *tp)
6738 6527
6739static void rtl_hw_start_8105e_1(struct rtl8169_private *tp) 6528static void rtl_hw_start_8105e_1(struct rtl8169_private *tp)
6740{ 6529{
6741 void __iomem *ioaddr = tp->mmio_addr;
6742 static const struct ephy_info e_info_8105e_1[] = { 6530 static const struct ephy_info e_info_8105e_1[] = {
6743 { 0x07, 0, 0x4000 }, 6531 { 0x07, 0, 0x4000 },
6744 { 0x19, 0, 0x0200 }, 6532 { 0x19, 0, 0x0200 },
@@ -6751,13 +6539,13 @@ static void rtl_hw_start_8105e_1(struct rtl8169_private *tp)
6751 }; 6539 };
6752 6540
6753 /* Force LAN exit from ASPM if Rx/Tx are not idle */ 6541 /* Force LAN exit from ASPM if Rx/Tx are not idle */
6754 RTL_W32(FuncEvent, RTL_R32(FuncEvent) | 0x002800); 6542 RTL_W32(tp, FuncEvent, RTL_R32(tp, FuncEvent) | 0x002800);
6755 6543
6756 /* Disable Early Tally Counter */ 6544 /* Disable Early Tally Counter */
6757 RTL_W32(FuncEvent, RTL_R32(FuncEvent) & ~0x010000); 6545 RTL_W32(tp, FuncEvent, RTL_R32(tp, FuncEvent) & ~0x010000);
6758 6546
6759 RTL_W8(MCU, RTL_R8(MCU) | EN_NDP | EN_OOB_RESET); 6547 RTL_W8(tp, MCU, RTL_R8(tp, MCU) | EN_NDP | EN_OOB_RESET);
6760 RTL_W8(DLLPR, RTL_R8(DLLPR) | PFM_EN); 6548 RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) | PFM_EN);
6761 6549
6762 rtl_ephy_init(tp, e_info_8105e_1, ARRAY_SIZE(e_info_8105e_1)); 6550 rtl_ephy_init(tp, e_info_8105e_1, ARRAY_SIZE(e_info_8105e_1));
6763 6551
@@ -6772,7 +6560,6 @@ static void rtl_hw_start_8105e_2(struct rtl8169_private *tp)
6772 6560
6773static void rtl_hw_start_8402(struct rtl8169_private *tp) 6561static void rtl_hw_start_8402(struct rtl8169_private *tp)
6774{ 6562{
6775 void __iomem *ioaddr = tp->mmio_addr;
6776 static const struct ephy_info e_info_8402[] = { 6563 static const struct ephy_info e_info_8402[] = {
6777 { 0x19, 0xffff, 0xff64 }, 6564 { 0x19, 0xffff, 0xff64 },
6778 { 0x1e, 0, 0x4000 } 6565 { 0x1e, 0, 0x4000 }
@@ -6781,14 +6568,14 @@ static void rtl_hw_start_8402(struct rtl8169_private *tp)
6781 rtl_csi_access_enable_2(tp); 6568 rtl_csi_access_enable_2(tp);
6782 6569
6783 /* Force LAN exit from ASPM if Rx/Tx are not idle */ 6570 /* Force LAN exit from ASPM if Rx/Tx are not idle */
6784 RTL_W32(FuncEvent, RTL_R32(FuncEvent) | 0x002800); 6571 RTL_W32(tp, FuncEvent, RTL_R32(tp, FuncEvent) | 0x002800);
6785 6572
6786 RTL_W32(TxConfig, RTL_R32(TxConfig) | TXCFG_AUTO_FIFO); 6573 RTL_W32(tp, TxConfig, RTL_R32(tp, TxConfig) | TXCFG_AUTO_FIFO);
6787 RTL_W8(MCU, RTL_R8(MCU) & ~NOW_IS_OOB); 6574 RTL_W8(tp, MCU, RTL_R8(tp, MCU) & ~NOW_IS_OOB);
6788 6575
6789 rtl_ephy_init(tp, e_info_8402, ARRAY_SIZE(e_info_8402)); 6576 rtl_ephy_init(tp, e_info_8402, ARRAY_SIZE(e_info_8402));
6790 6577
6791 rtl_tx_performance_tweak(tp->pci_dev, 0x5 << MAX_READ_REQUEST_SHIFT); 6578 rtl_tx_performance_tweak(tp, 0x5 << MAX_READ_REQUEST_SHIFT);
6792 6579
6793 rtl_eri_write(tp, 0xc8, ERIAR_MASK_1111, 0x00000002, ERIAR_EXGMAC); 6580 rtl_eri_write(tp, 0xc8, ERIAR_MASK_1111, 0x00000002, ERIAR_EXGMAC);
6794 rtl_eri_write(tp, 0xe8, ERIAR_MASK_1111, 0x00000006, ERIAR_EXGMAC); 6581 rtl_eri_write(tp, 0xe8, ERIAR_MASK_1111, 0x00000006, ERIAR_EXGMAC);
@@ -6803,14 +6590,12 @@ static void rtl_hw_start_8402(struct rtl8169_private *tp)
6803 6590
6804static void rtl_hw_start_8106(struct rtl8169_private *tp) 6591static void rtl_hw_start_8106(struct rtl8169_private *tp)
6805{ 6592{
6806 void __iomem *ioaddr = tp->mmio_addr;
6807
6808 /* Force LAN exit from ASPM if Rx/Tx are not idle */ 6593 /* Force LAN exit from ASPM if Rx/Tx are not idle */
6809 RTL_W32(FuncEvent, RTL_R32(FuncEvent) | 0x002800); 6594 RTL_W32(tp, FuncEvent, RTL_R32(tp, FuncEvent) | 0x002800);
6810 6595
6811 RTL_W32(MISC, (RTL_R32(MISC) | DISABLE_LAN_EN) & ~EARLY_TALLY_EN); 6596 RTL_W32(tp, MISC, (RTL_R32(tp, MISC) | DISABLE_LAN_EN) & ~EARLY_TALLY_EN);
6812 RTL_W8(MCU, RTL_R8(MCU) | EN_NDP | EN_OOB_RESET); 6597 RTL_W8(tp, MCU, RTL_R8(tp, MCU) | EN_NDP | EN_OOB_RESET);
6813 RTL_W8(DLLPR, RTL_R8(DLLPR) & ~PFM_EN); 6598 RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~PFM_EN);
6814 6599
6815 rtl_pcie_state_l2l3_enable(tp, false); 6600 rtl_pcie_state_l2l3_enable(tp, false);
6816} 6601}
@@ -6818,7 +6603,6 @@ static void rtl_hw_start_8106(struct rtl8169_private *tp)
6818static void rtl_hw_start_8101(struct net_device *dev) 6603static void rtl_hw_start_8101(struct net_device *dev)
6819{ 6604{
6820 struct rtl8169_private *tp = netdev_priv(dev); 6605 struct rtl8169_private *tp = netdev_priv(dev);
6821 void __iomem *ioaddr = tp->mmio_addr;
6822 struct pci_dev *pdev = tp->pci_dev; 6606 struct pci_dev *pdev = tp->pci_dev;
6823 6607
6824 if (tp->mac_version >= RTL_GIGA_MAC_VER_30) 6608 if (tp->mac_version >= RTL_GIGA_MAC_VER_30)
@@ -6829,16 +6613,16 @@ static void rtl_hw_start_8101(struct net_device *dev)
6829 pcie_capability_set_word(pdev, PCI_EXP_DEVCTL, 6613 pcie_capability_set_word(pdev, PCI_EXP_DEVCTL,
6830 PCI_EXP_DEVCTL_NOSNOOP_EN); 6614 PCI_EXP_DEVCTL_NOSNOOP_EN);
6831 6615
6832 RTL_W8(Cfg9346, Cfg9346_Unlock); 6616 RTL_W8(tp, Cfg9346, Cfg9346_Unlock);
6833 6617
6834 RTL_W8(MaxTxPacketSize, TxPacketMax); 6618 RTL_W8(tp, MaxTxPacketSize, TxPacketMax);
6835 6619
6836 rtl_set_rx_max_size(ioaddr, rx_buf_sz); 6620 rtl_set_rx_max_size(tp, rx_buf_sz);
6837 6621
6838 tp->cp_cmd &= ~R810X_CPCMD_QUIRK_MASK; 6622 tp->cp_cmd &= ~R810X_CPCMD_QUIRK_MASK;
6839 RTL_W16(CPlusCmd, tp->cp_cmd); 6623 RTL_W16(tp, CPlusCmd, tp->cp_cmd);
6840 6624
6841 rtl_set_rx_tx_desc_registers(tp, ioaddr); 6625 rtl_set_rx_tx_desc_registers(tp);
6842 6626
6843 rtl_set_rx_tx_config_registers(tp); 6627 rtl_set_rx_tx_config_registers(tp);
6844 6628
@@ -6878,17 +6662,17 @@ static void rtl_hw_start_8101(struct net_device *dev)
6878 break; 6662 break;
6879 } 6663 }
6880 6664
6881 RTL_W8(Cfg9346, Cfg9346_Lock); 6665 RTL_W8(tp, Cfg9346, Cfg9346_Lock);
6882 6666
6883 RTL_W16(IntrMitigate, 0x0000); 6667 RTL_W16(tp, IntrMitigate, 0x0000);
6884 6668
6885 RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); 6669 RTL_W8(tp, ChipCmd, CmdTxEnb | CmdRxEnb);
6886 6670
6887 rtl_set_rx_mode(dev); 6671 rtl_set_rx_mode(dev);
6888 6672
6889 RTL_R8(IntrMask); 6673 RTL_R8(tp, IntrMask);
6890 6674
6891 RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xf000); 6675 RTL_W16(tp, MultiIntr, RTL_R16(tp, MultiIntr) & 0xf000);
6892} 6676}
6893 6677
6894static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) 6678static int rtl8169_change_mtu(struct net_device *dev, int new_mtu)
@@ -6915,7 +6699,7 @@ static inline void rtl8169_make_unusable_by_asic(struct RxDesc *desc)
6915static void rtl8169_free_rx_databuff(struct rtl8169_private *tp, 6699static void rtl8169_free_rx_databuff(struct rtl8169_private *tp,
6916 void **data_buff, struct RxDesc *desc) 6700 void **data_buff, struct RxDesc *desc)
6917{ 6701{
6918 dma_unmap_single(&tp->pci_dev->dev, le64_to_cpu(desc->addr), rx_buf_sz, 6702 dma_unmap_single(tp_to_dev(tp), le64_to_cpu(desc->addr), rx_buf_sz,
6919 DMA_FROM_DEVICE); 6703 DMA_FROM_DEVICE);
6920 6704
6921 kfree(*data_buff); 6705 kfree(*data_buff);
@@ -6950,7 +6734,7 @@ static struct sk_buff *rtl8169_alloc_rx_data(struct rtl8169_private *tp,
6950{ 6734{
6951 void *data; 6735 void *data;
6952 dma_addr_t mapping; 6736 dma_addr_t mapping;
6953 struct device *d = &tp->pci_dev->dev; 6737 struct device *d = tp_to_dev(tp);
6954 struct net_device *dev = tp->dev; 6738 struct net_device *dev = tp->dev;
6955 int node = dev->dev.parent ? dev_to_node(dev->dev.parent) : -1; 6739 int node = dev->dev.parent ? dev_to_node(dev->dev.parent) : -1;
6956 6740
@@ -7062,7 +6846,7 @@ static void rtl8169_tx_clear_range(struct rtl8169_private *tp, u32 start,
7062 if (len) { 6846 if (len) {
7063 struct sk_buff *skb = tx_skb->skb; 6847 struct sk_buff *skb = tx_skb->skb;
7064 6848
7065 rtl8169_unmap_tx_skb(&tp->pci_dev->dev, tx_skb, 6849 rtl8169_unmap_tx_skb(tp_to_dev(tp), tx_skb,
7066 tp->TxDescArray + entry); 6850 tp->TxDescArray + entry);
7067 if (skb) { 6851 if (skb) {
7068 dev_consume_skb_any(skb); 6852 dev_consume_skb_any(skb);
@@ -7098,7 +6882,7 @@ static void rtl_reset_work(struct rtl8169_private *tp)
7098 napi_enable(&tp->napi); 6882 napi_enable(&tp->napi);
7099 rtl_hw_start(dev); 6883 rtl_hw_start(dev);
7100 netif_wake_queue(dev); 6884 netif_wake_queue(dev);
7101 rtl8169_check_link_status(dev, tp, tp->mmio_addr); 6885 rtl8169_check_link_status(dev, tp);
7102} 6886}
7103 6887
7104static void rtl8169_tx_timeout(struct net_device *dev) 6888static void rtl8169_tx_timeout(struct net_device *dev)
@@ -7114,7 +6898,7 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb,
7114 struct skb_shared_info *info = skb_shinfo(skb); 6898 struct skb_shared_info *info = skb_shinfo(skb);
7115 unsigned int cur_frag, entry; 6899 unsigned int cur_frag, entry;
7116 struct TxDesc *uninitialized_var(txd); 6900 struct TxDesc *uninitialized_var(txd);
7117 struct device *d = &tp->pci_dev->dev; 6901 struct device *d = tp_to_dev(tp);
7118 6902
7119 entry = tp->cur_tx; 6903 entry = tp->cur_tx;
7120 for (cur_frag = 0; cur_frag < info->nr_frags; cur_frag++) { 6904 for (cur_frag = 0; cur_frag < info->nr_frags; cur_frag++) {
@@ -7346,8 +7130,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
7346 struct rtl8169_private *tp = netdev_priv(dev); 7130 struct rtl8169_private *tp = netdev_priv(dev);
7347 unsigned int entry = tp->cur_tx % NUM_TX_DESC; 7131 unsigned int entry = tp->cur_tx % NUM_TX_DESC;
7348 struct TxDesc *txd = tp->TxDescArray + entry; 7132 struct TxDesc *txd = tp->TxDescArray + entry;
7349 void __iomem *ioaddr = tp->mmio_addr; 7133 struct device *d = tp_to_dev(tp);
7350 struct device *d = &tp->pci_dev->dev;
7351 dma_addr_t mapping; 7134 dma_addr_t mapping;
7352 u32 status, len; 7135 u32 status, len;
7353 u32 opts[2]; 7136 u32 opts[2];
@@ -7406,7 +7189,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
7406 7189
7407 tp->cur_tx += frags + 1; 7190 tp->cur_tx += frags + 1;
7408 7191
7409 RTL_W8(TxPoll, NPQ); 7192 RTL_W8(tp, TxPoll, NPQ);
7410 7193
7411 mmiowb(); 7194 mmiowb();
7412 7195
@@ -7477,11 +7260,9 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev)
7477 7260
7478 /* The infamous DAC f*ckup only happens at boot time */ 7261 /* The infamous DAC f*ckup only happens at boot time */
7479 if ((tp->cp_cmd & PCIDAC) && !tp->cur_rx) { 7262 if ((tp->cp_cmd & PCIDAC) && !tp->cur_rx) {
7480 void __iomem *ioaddr = tp->mmio_addr;
7481
7482 netif_info(tp, intr, dev, "disabling PCI DAC\n"); 7263 netif_info(tp, intr, dev, "disabling PCI DAC\n");
7483 tp->cp_cmd &= ~PCIDAC; 7264 tp->cp_cmd &= ~PCIDAC;
7484 RTL_W16(CPlusCmd, tp->cp_cmd); 7265 RTL_W16(tp, CPlusCmd, tp->cp_cmd);
7485 dev->features &= ~NETIF_F_HIGHDMA; 7266 dev->features &= ~NETIF_F_HIGHDMA;
7486 } 7267 }
7487 7268
@@ -7513,7 +7294,7 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp)
7513 */ 7294 */
7514 dma_rmb(); 7295 dma_rmb();
7515 7296
7516 rtl8169_unmap_tx_skb(&tp->pci_dev->dev, tx_skb, 7297 rtl8169_unmap_tx_skb(tp_to_dev(tp), tx_skb,
7517 tp->TxDescArray + entry); 7298 tp->TxDescArray + entry);
7518 if (status & LastFrag) { 7299 if (status & LastFrag) {
7519 u64_stats_update_begin(&tp->tx_stats.syncp); 7300 u64_stats_update_begin(&tp->tx_stats.syncp);
@@ -7547,11 +7328,8 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp)
7547 * of start_xmit activity is detected (if it is not detected, 7328 * of start_xmit activity is detected (if it is not detected,
7548 * it is slow enough). -- FR 7329 * it is slow enough). -- FR
7549 */ 7330 */
7550 if (tp->cur_tx != dirty_tx) { 7331 if (tp->cur_tx != dirty_tx)
7551 void __iomem *ioaddr = tp->mmio_addr; 7332 RTL_W8(tp, TxPoll, NPQ);
7552
7553 RTL_W8(TxPoll, NPQ);
7554 }
7555 } 7333 }
7556} 7334}
7557 7335
@@ -7577,7 +7355,7 @@ static struct sk_buff *rtl8169_try_rx_copy(void *data,
7577 dma_addr_t addr) 7355 dma_addr_t addr)
7578{ 7356{
7579 struct sk_buff *skb; 7357 struct sk_buff *skb;
7580 struct device *d = &tp->pci_dev->dev; 7358 struct device *d = tp_to_dev(tp);
7581 7359
7582 data = rtl8169_align(data); 7360 data = rtl8169_align(data);
7583 dma_sync_single_for_cpu(d, addr, pkt_size, DMA_FROM_DEVICE); 7361 dma_sync_single_for_cpu(d, addr, pkt_size, DMA_FROM_DEVICE);
@@ -7732,7 +7510,7 @@ static void rtl_slow_event_work(struct rtl8169_private *tp)
7732 rtl8169_pcierr_interrupt(dev); 7510 rtl8169_pcierr_interrupt(dev);
7733 7511
7734 if (status & LinkChg) 7512 if (status & LinkChg)
7735 rtl8169_check_link_status(dev, tp, tp->mmio_addr); 7513 rtl8169_check_link_status(dev, tp);
7736 7514
7737 rtl_irq_enable_all(tp); 7515 rtl_irq_enable_all(tp);
7738} 7516}
@@ -7804,21 +7582,20 @@ static int rtl8169_poll(struct napi_struct *napi, int budget)
7804 return work_done; 7582 return work_done;
7805} 7583}
7806 7584
7807static void rtl8169_rx_missed(struct net_device *dev, void __iomem *ioaddr) 7585static void rtl8169_rx_missed(struct net_device *dev)
7808{ 7586{
7809 struct rtl8169_private *tp = netdev_priv(dev); 7587 struct rtl8169_private *tp = netdev_priv(dev);
7810 7588
7811 if (tp->mac_version > RTL_GIGA_MAC_VER_06) 7589 if (tp->mac_version > RTL_GIGA_MAC_VER_06)
7812 return; 7590 return;
7813 7591
7814 dev->stats.rx_missed_errors += (RTL_R32(RxMissed) & 0xffffff); 7592 dev->stats.rx_missed_errors += RTL_R32(tp, RxMissed) & 0xffffff;
7815 RTL_W32(RxMissed, 0); 7593 RTL_W32(tp, RxMissed, 0);
7816} 7594}
7817 7595
7818static void rtl8169_down(struct net_device *dev) 7596static void rtl8169_down(struct net_device *dev)
7819{ 7597{
7820 struct rtl8169_private *tp = netdev_priv(dev); 7598 struct rtl8169_private *tp = netdev_priv(dev);
7821 void __iomem *ioaddr = tp->mmio_addr;
7822 7599
7823 del_timer_sync(&tp->timer); 7600 del_timer_sync(&tp->timer);
7824 7601
@@ -7831,7 +7608,7 @@ static void rtl8169_down(struct net_device *dev)
7831 * as netif_running is not true (rtl8169_interrupt, rtl8169_reset_task) 7608 * as netif_running is not true (rtl8169_interrupt, rtl8169_reset_task)
7832 * and napi is disabled (rtl8169_poll). 7609 * and napi is disabled (rtl8169_poll).
7833 */ 7610 */
7834 rtl8169_rx_missed(dev, ioaddr); 7611 rtl8169_rx_missed(dev);
7835 7612
7836 /* Give a racing hard_start_xmit a few cycles to complete. */ 7613 /* Give a racing hard_start_xmit a few cycles to complete. */
7837 synchronize_sched(); 7614 synchronize_sched();
@@ -7861,7 +7638,7 @@ static int rtl8169_close(struct net_device *dev)
7861 7638
7862 cancel_work_sync(&tp->wk.work); 7639 cancel_work_sync(&tp->wk.work);
7863 7640
7864 free_irq(pdev->irq, dev); 7641 pci_free_irq(pdev, 0, dev);
7865 7642
7866 dma_free_coherent(&pdev->dev, R8169_RX_RING_BYTES, tp->RxDescArray, 7643 dma_free_coherent(&pdev->dev, R8169_RX_RING_BYTES, tp->RxDescArray,
7867 tp->RxPhyAddr); 7644 tp->RxPhyAddr);
@@ -7880,14 +7657,13 @@ static void rtl8169_netpoll(struct net_device *dev)
7880{ 7657{
7881 struct rtl8169_private *tp = netdev_priv(dev); 7658 struct rtl8169_private *tp = netdev_priv(dev);
7882 7659
7883 rtl8169_interrupt(tp->pci_dev->irq, dev); 7660 rtl8169_interrupt(pci_irq_vector(tp->pci_dev, 0), dev);
7884} 7661}
7885#endif 7662#endif
7886 7663
7887static int rtl_open(struct net_device *dev) 7664static int rtl_open(struct net_device *dev)
7888{ 7665{
7889 struct rtl8169_private *tp = netdev_priv(dev); 7666 struct rtl8169_private *tp = netdev_priv(dev);
7890 void __iomem *ioaddr = tp->mmio_addr;
7891 struct pci_dev *pdev = tp->pci_dev; 7667 struct pci_dev *pdev = tp->pci_dev;
7892 int retval = -ENOMEM; 7668 int retval = -ENOMEM;
7893 7669
@@ -7917,9 +7693,8 @@ static int rtl_open(struct net_device *dev)
7917 7693
7918 rtl_request_firmware(tp); 7694 rtl_request_firmware(tp);
7919 7695
7920 retval = request_irq(pdev->irq, rtl8169_interrupt, 7696 retval = pci_request_irq(pdev, 0, rtl8169_interrupt, NULL, dev,
7921 (tp->features & RTL_FEATURE_MSI) ? 0 : IRQF_SHARED, 7697 dev->name);
7922 dev->name, dev);
7923 if (retval < 0) 7698 if (retval < 0)
7924 goto err_release_fw_2; 7699 goto err_release_fw_2;
7925 7700
@@ -7947,7 +7722,7 @@ static int rtl_open(struct net_device *dev)
7947 tp->saved_wolopts = 0; 7722 tp->saved_wolopts = 0;
7948 pm_runtime_put_sync(&pdev->dev); 7723 pm_runtime_put_sync(&pdev->dev);
7949 7724
7950 rtl8169_check_link_status(dev, tp, ioaddr); 7725 rtl8169_check_link_status(dev, tp);
7951out: 7726out:
7952 return retval; 7727 return retval;
7953 7728
@@ -7971,7 +7746,6 @@ static void
7971rtl8169_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) 7746rtl8169_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
7972{ 7747{
7973 struct rtl8169_private *tp = netdev_priv(dev); 7748 struct rtl8169_private *tp = netdev_priv(dev);
7974 void __iomem *ioaddr = tp->mmio_addr;
7975 struct pci_dev *pdev = tp->pci_dev; 7749 struct pci_dev *pdev = tp->pci_dev;
7976 struct rtl8169_counters *counters = tp->counters; 7750 struct rtl8169_counters *counters = tp->counters;
7977 unsigned int start; 7751 unsigned int start;
@@ -7979,7 +7753,7 @@ rtl8169_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
7979 pm_runtime_get_noresume(&pdev->dev); 7753 pm_runtime_get_noresume(&pdev->dev);
7980 7754
7981 if (netif_running(dev) && pm_runtime_active(&pdev->dev)) 7755 if (netif_running(dev) && pm_runtime_active(&pdev->dev))
7982 rtl8169_rx_missed(dev, ioaddr); 7756 rtl8169_rx_missed(dev);
7983 7757
7984 do { 7758 do {
7985 start = u64_stats_fetch_begin_irq(&tp->rx_stats.syncp); 7759 start = u64_stats_fetch_begin_irq(&tp->rx_stats.syncp);
@@ -8102,7 +7876,7 @@ static int rtl8169_runtime_suspend(struct device *device)
8102 rtl8169_net_suspend(dev); 7876 rtl8169_net_suspend(dev);
8103 7877
8104 /* Update counters before going runtime suspend */ 7878 /* Update counters before going runtime suspend */
8105 rtl8169_rx_missed(dev, tp->mmio_addr); 7879 rtl8169_rx_missed(dev);
8106 rtl8169_update_counters(dev); 7880 rtl8169_update_counters(dev);
8107 7881
8108 return 0; 7882 return 0;
@@ -8163,8 +7937,6 @@ static const struct dev_pm_ops rtl8169_pm_ops = {
8163 7937
8164static void rtl_wol_shutdown_quirk(struct rtl8169_private *tp) 7938static void rtl_wol_shutdown_quirk(struct rtl8169_private *tp)
8165{ 7939{
8166 void __iomem *ioaddr = tp->mmio_addr;
8167
8168 /* WoL fails with 8168b when the receiver is disabled. */ 7940 /* WoL fails with 8168b when the receiver is disabled. */
8169 switch (tp->mac_version) { 7941 switch (tp->mac_version) {
8170 case RTL_GIGA_MAC_VER_11: 7942 case RTL_GIGA_MAC_VER_11:
@@ -8172,9 +7944,9 @@ static void rtl_wol_shutdown_quirk(struct rtl8169_private *tp)
8172 case RTL_GIGA_MAC_VER_17: 7944 case RTL_GIGA_MAC_VER_17:
8173 pci_clear_master(tp->pci_dev); 7945 pci_clear_master(tp->pci_dev);
8174 7946
8175 RTL_W8(ChipCmd, CmdRxEnb); 7947 RTL_W8(tp, ChipCmd, CmdRxEnb);
8176 /* PCI commit */ 7948 /* PCI commit */
8177 RTL_R8(ChipCmd); 7949 RTL_R8(tp, ChipCmd);
8178 break; 7950 break;
8179 default: 7951 default:
8180 break; 7952 break;
@@ -8209,15 +7981,8 @@ static void rtl_remove_one(struct pci_dev *pdev)
8209 struct net_device *dev = pci_get_drvdata(pdev); 7981 struct net_device *dev = pci_get_drvdata(pdev);
8210 struct rtl8169_private *tp = netdev_priv(dev); 7982 struct rtl8169_private *tp = netdev_priv(dev);
8211 7983
8212 if ((tp->mac_version == RTL_GIGA_MAC_VER_27 || 7984 if (r8168_check_dash(tp))
8213 tp->mac_version == RTL_GIGA_MAC_VER_28 ||
8214 tp->mac_version == RTL_GIGA_MAC_VER_31 ||
8215 tp->mac_version == RTL_GIGA_MAC_VER_49 ||
8216 tp->mac_version == RTL_GIGA_MAC_VER_50 ||
8217 tp->mac_version == RTL_GIGA_MAC_VER_51) &&
8218 r8168_check_dash(tp)) {
8219 rtl8168_driver_stop(tp); 7985 rtl8168_driver_stop(tp);
8220 }
8221 7986
8222 netif_napi_del(&tp->napi); 7987 netif_napi_del(&tp->napi);
8223 7988
@@ -8256,7 +8021,7 @@ static const struct rtl_cfg_info {
8256 unsigned int region; 8021 unsigned int region;
8257 unsigned int align; 8022 unsigned int align;
8258 u16 event_slow; 8023 u16 event_slow;
8259 unsigned features; 8024 unsigned int has_gmii:1;
8260 const struct rtl_coalesce_info *coalesce_info; 8025 const struct rtl_coalesce_info *coalesce_info;
8261 u8 default_ver; 8026 u8 default_ver;
8262} rtl_cfg_infos [] = { 8027} rtl_cfg_infos [] = {
@@ -8265,7 +8030,7 @@ static const struct rtl_cfg_info {
8265 .region = 1, 8030 .region = 1,
8266 .align = 0, 8031 .align = 0,
8267 .event_slow = SYSErr | LinkChg | RxOverflow | RxFIFOOver, 8032 .event_slow = SYSErr | LinkChg | RxOverflow | RxFIFOOver,
8268 .features = RTL_FEATURE_GMII, 8033 .has_gmii = 1,
8269 .coalesce_info = rtl_coalesce_info_8169, 8034 .coalesce_info = rtl_coalesce_info_8169,
8270 .default_ver = RTL_GIGA_MAC_VER_01, 8035 .default_ver = RTL_GIGA_MAC_VER_01,
8271 }, 8036 },
@@ -8274,7 +8039,7 @@ static const struct rtl_cfg_info {
8274 .region = 2, 8039 .region = 2,
8275 .align = 8, 8040 .align = 8,
8276 .event_slow = SYSErr | LinkChg | RxOverflow, 8041 .event_slow = SYSErr | LinkChg | RxOverflow,
8277 .features = RTL_FEATURE_GMII | RTL_FEATURE_MSI, 8042 .has_gmii = 1,
8278 .coalesce_info = rtl_coalesce_info_8168_8136, 8043 .coalesce_info = rtl_coalesce_info_8168_8136,
8279 .default_ver = RTL_GIGA_MAC_VER_11, 8044 .default_ver = RTL_GIGA_MAC_VER_11,
8280 }, 8045 },
@@ -8284,56 +8049,44 @@ static const struct rtl_cfg_info {
8284 .align = 8, 8049 .align = 8,
8285 .event_slow = SYSErr | LinkChg | RxOverflow | RxFIFOOver | 8050 .event_slow = SYSErr | LinkChg | RxOverflow | RxFIFOOver |
8286 PCSTimeout, 8051 PCSTimeout,
8287 .features = RTL_FEATURE_MSI,
8288 .coalesce_info = rtl_coalesce_info_8168_8136, 8052 .coalesce_info = rtl_coalesce_info_8168_8136,
8289 .default_ver = RTL_GIGA_MAC_VER_13, 8053 .default_ver = RTL_GIGA_MAC_VER_13,
8290 } 8054 }
8291}; 8055};
8292 8056
8293/* Cfg9346_Unlock assumed. */ 8057static int rtl_alloc_irq(struct rtl8169_private *tp)
8294static unsigned rtl_try_msi(struct rtl8169_private *tp,
8295 const struct rtl_cfg_info *cfg)
8296{ 8058{
8297 void __iomem *ioaddr = tp->mmio_addr; 8059 unsigned int flags;
8298 unsigned msi = 0;
8299 u8 cfg2;
8300 8060
8301 cfg2 = RTL_R8(Config2) & ~MSIEnable; 8061 if (tp->mac_version <= RTL_GIGA_MAC_VER_06) {
8302 if (cfg->features & RTL_FEATURE_MSI) { 8062 RTL_W8(tp, Cfg9346, Cfg9346_Unlock);
8303 if (pci_enable_msi(tp->pci_dev)) { 8063 RTL_W8(tp, Config2, RTL_R8(tp, Config2) & ~MSIEnable);
8304 netif_info(tp, hw, tp->dev, "no MSI. Back to INTx.\n"); 8064 RTL_W8(tp, Cfg9346, Cfg9346_Lock);
8305 } else { 8065 flags = PCI_IRQ_LEGACY;
8306 cfg2 |= MSIEnable; 8066 } else {
8307 msi = RTL_FEATURE_MSI; 8067 flags = PCI_IRQ_ALL_TYPES;
8308 }
8309 } 8068 }
8310 if (tp->mac_version <= RTL_GIGA_MAC_VER_06) 8069
8311 RTL_W8(Config2, cfg2); 8070 return pci_alloc_irq_vectors(tp->pci_dev, 1, 1, flags);
8312 return msi;
8313} 8071}
8314 8072
8315DECLARE_RTL_COND(rtl_link_list_ready_cond) 8073DECLARE_RTL_COND(rtl_link_list_ready_cond)
8316{ 8074{
8317 void __iomem *ioaddr = tp->mmio_addr; 8075 return RTL_R8(tp, MCU) & LINK_LIST_RDY;
8318
8319 return RTL_R8(MCU) & LINK_LIST_RDY;
8320} 8076}
8321 8077
8322DECLARE_RTL_COND(rtl_rxtx_empty_cond) 8078DECLARE_RTL_COND(rtl_rxtx_empty_cond)
8323{ 8079{
8324 void __iomem *ioaddr = tp->mmio_addr; 8080 return (RTL_R8(tp, MCU) & RXTX_EMPTY) == RXTX_EMPTY;
8325
8326 return (RTL_R8(MCU) & RXTX_EMPTY) == RXTX_EMPTY;
8327} 8081}
8328 8082
8329static void rtl_hw_init_8168g(struct rtl8169_private *tp) 8083static void rtl_hw_init_8168g(struct rtl8169_private *tp)
8330{ 8084{
8331 void __iomem *ioaddr = tp->mmio_addr;
8332 u32 data; 8085 u32 data;
8333 8086
8334 tp->ocp_base = OCP_STD_PHY_BASE; 8087 tp->ocp_base = OCP_STD_PHY_BASE;
8335 8088
8336 RTL_W32(MISC, RTL_R32(MISC) | RXDV_GATED_EN); 8089 RTL_W32(tp, MISC, RTL_R32(tp, MISC) | RXDV_GATED_EN);
8337 8090
8338 if (!rtl_udelay_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 42)) 8091 if (!rtl_udelay_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 42))
8339 return; 8092 return;
@@ -8341,9 +8094,9 @@ static void rtl_hw_init_8168g(struct rtl8169_private *tp)
8341 if (!rtl_udelay_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42)) 8094 if (!rtl_udelay_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42))
8342 return; 8095 return;
8343 8096
8344 RTL_W8(ChipCmd, RTL_R8(ChipCmd) & ~(CmdTxEnb | CmdRxEnb)); 8097 RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) & ~(CmdTxEnb | CmdRxEnb));
8345 msleep(1); 8098 msleep(1);
8346 RTL_W8(MCU, RTL_R8(MCU) & ~NOW_IS_OOB); 8099 RTL_W8(tp, MCU, RTL_R8(tp, MCU) & ~NOW_IS_OOB);
8347 8100
8348 data = r8168_mac_ocp_read(tp, 0xe8de); 8101 data = r8168_mac_ocp_read(tp, 0xe8de);
8349 data &= ~(1 << 14); 8102 data &= ~(1 << 14);
@@ -8397,7 +8150,6 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
8397 struct rtl8169_private *tp; 8150 struct rtl8169_private *tp;
8398 struct mii_if_info *mii; 8151 struct mii_if_info *mii;
8399 struct net_device *dev; 8152 struct net_device *dev;
8400 void __iomem *ioaddr;
8401 int chipset, i; 8153 int chipset, i;
8402 int rc; 8154 int rc;
8403 8155
@@ -8423,7 +8175,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
8423 mii->mdio_write = rtl_mdio_write; 8175 mii->mdio_write = rtl_mdio_write;
8424 mii->phy_id_mask = 0x1f; 8176 mii->phy_id_mask = 0x1f;
8425 mii->reg_num_mask = 0x1f; 8177 mii->reg_num_mask = 0x1f;
8426 mii->supports_gmii = !!(cfg->features & RTL_FEATURE_GMII); 8178 mii->supports_gmii = cfg->has_gmii;
8427 8179
8428 /* disable ASPM completely as that cause random device stop working 8180 /* disable ASPM completely as that cause random device stop working
8429 * problems as well as full system hangs for some PCIe devices users */ 8181 * problems as well as full system hangs for some PCIe devices users */
@@ -8455,20 +8207,13 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
8455 return -ENODEV; 8207 return -ENODEV;
8456 } 8208 }
8457 8209
8458 rc = pci_request_regions(pdev, MODULENAME); 8210 rc = pcim_iomap_regions(pdev, BIT(region), MODULENAME);
8459 if (rc < 0) { 8211 if (rc < 0) {
8460 netif_err(tp, probe, dev, "could not request regions\n"); 8212 netif_err(tp, probe, dev, "cannot remap MMIO, aborting\n");
8461 return rc; 8213 return rc;
8462 } 8214 }
8463 8215
8464 /* ioremap MMIO region */ 8216 tp->mmio_addr = pcim_iomap_table(pdev)[region];
8465 ioaddr = devm_ioremap(&pdev->dev, pci_resource_start(pdev, region),
8466 R8169_REGS_SIZE);
8467 if (!ioaddr) {
8468 netif_err(tp, probe, dev, "cannot remap MMIO, aborting\n");
8469 return -EIO;
8470 }
8471 tp->mmio_addr = ioaddr;
8472 8217
8473 if (!pci_is_pcie(pdev)) 8218 if (!pci_is_pcie(pdev))
8474 netif_info(tp, probe, dev, "not PCI Express\n"); 8219 netif_info(tp, probe, dev, "not PCI Express\n");
@@ -8518,41 +8263,14 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
8518 chipset = tp->mac_version; 8263 chipset = tp->mac_version;
8519 tp->txd_version = rtl_chip_infos[chipset].txd_version; 8264 tp->txd_version = rtl_chip_infos[chipset].txd_version;
8520 8265
8521 RTL_W8(Cfg9346, Cfg9346_Unlock); 8266 rc = rtl_alloc_irq(tp);
8522 RTL_W8(Config1, RTL_R8(Config1) | PMEnable); 8267 if (rc < 0) {
8523 RTL_W8(Config5, RTL_R8(Config5) & (BWF | MWF | UWF | LanWake | PMEStatus)); 8268 netif_err(tp, probe, dev, "Can't allocate interrupt\n");
8524 switch (tp->mac_version) { 8269 return rc;
8525 case RTL_GIGA_MAC_VER_34:
8526 case RTL_GIGA_MAC_VER_35:
8527 case RTL_GIGA_MAC_VER_36:
8528 case RTL_GIGA_MAC_VER_37:
8529 case RTL_GIGA_MAC_VER_38:
8530 case RTL_GIGA_MAC_VER_40:
8531 case RTL_GIGA_MAC_VER_41:
8532 case RTL_GIGA_MAC_VER_42:
8533 case RTL_GIGA_MAC_VER_43:
8534 case RTL_GIGA_MAC_VER_44:
8535 case RTL_GIGA_MAC_VER_45:
8536 case RTL_GIGA_MAC_VER_46:
8537 case RTL_GIGA_MAC_VER_47:
8538 case RTL_GIGA_MAC_VER_48:
8539 case RTL_GIGA_MAC_VER_49:
8540 case RTL_GIGA_MAC_VER_50:
8541 case RTL_GIGA_MAC_VER_51:
8542 if (rtl_eri_read(tp, 0xdc, ERIAR_EXGMAC) & MagicPacket_v2)
8543 tp->features |= RTL_FEATURE_WOL;
8544 if ((RTL_R8(Config3) & LinkUp) != 0)
8545 tp->features |= RTL_FEATURE_WOL;
8546 break;
8547 default:
8548 if ((RTL_R8(Config3) & (LinkUp | MagicPacket)) != 0)
8549 tp->features |= RTL_FEATURE_WOL;
8550 break;
8551 } 8270 }
8552 if ((RTL_R8(Config5) & (UWF | BWF | MWF)) != 0) 8271
8553 tp->features |= RTL_FEATURE_WOL; 8272 /* override BIOS settings, use userspace tools to enable WOL */
8554 tp->features |= rtl_try_msi(tp, cfg); 8273 __rtl8169_set_wol(tp, 0);
8555 RTL_W8(Cfg9346, Cfg9346_Lock);
8556 8274
8557 if (rtl_tbi_enabled(tp)) { 8275 if (rtl_tbi_enabled(tp)) {
8558 tp->set_speed = rtl8169_set_speed_tbi; 8276 tp->set_speed = rtl8169_set_speed_tbi;
@@ -8600,7 +8318,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
8600 rtl_rar_set(tp, (u8 *)mac_addr); 8318 rtl_rar_set(tp, (u8 *)mac_addr);
8601 } 8319 }
8602 for (i = 0; i < ETH_ALEN; i++) 8320 for (i = 0; i < ETH_ALEN; i++)
8603 dev->dev_addr[i] = RTL_R8(MAC0 + i); 8321 dev->dev_addr[i] = RTL_R8(tp, MAC0 + i);
8604 8322
8605 dev->ethtool_ops = &rtl8169_ethtool_ops; 8323 dev->ethtool_ops = &rtl8169_ethtool_ops;
8606 dev->watchdog_timeo = RTL8169_TX_TIMEOUT; 8324 dev->watchdog_timeo = RTL8169_TX_TIMEOUT;
@@ -8667,8 +8385,9 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
8667 pci_set_drvdata(pdev, dev); 8385 pci_set_drvdata(pdev, dev);
8668 8386
8669 netif_info(tp, probe, dev, "%s at 0x%p, %pM, XID %08x IRQ %d\n", 8387 netif_info(tp, probe, dev, "%s at 0x%p, %pM, XID %08x IRQ %d\n",
8670 rtl_chip_infos[chipset].name, ioaddr, dev->dev_addr, 8388 rtl_chip_infos[chipset].name, tp->mmio_addr, dev->dev_addr,
8671 (u32)(RTL_R32(TxConfig) & 0x9cf0f8ff), pdev->irq); 8389 (u32)(RTL_R32(tp, TxConfig) & 0x9cf0f8ff),
8390 pci_irq_vector(pdev, 0));
8672 if (rtl_chip_infos[chipset].jumbo_max != JUMBO_1K) { 8391 if (rtl_chip_infos[chipset].jumbo_max != JUMBO_1K) {
8673 netif_info(tp, probe, dev, "jumbo features [frames: %d bytes, " 8392 netif_info(tp, probe, dev, "jumbo features [frames: %d bytes, "
8674 "tx checksumming: %s]\n", 8393 "tx checksumming: %s]\n",
@@ -8676,15 +8395,8 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
8676 rtl_chip_infos[chipset].jumbo_tx_csum ? "ok" : "ko"); 8395 rtl_chip_infos[chipset].jumbo_tx_csum ? "ok" : "ko");
8677 } 8396 }
8678 8397
8679 if ((tp->mac_version == RTL_GIGA_MAC_VER_27 || 8398 if (r8168_check_dash(tp))
8680 tp->mac_version == RTL_GIGA_MAC_VER_28 ||
8681 tp->mac_version == RTL_GIGA_MAC_VER_31 ||
8682 tp->mac_version == RTL_GIGA_MAC_VER_49 ||
8683 tp->mac_version == RTL_GIGA_MAC_VER_50 ||
8684 tp->mac_version == RTL_GIGA_MAC_VER_51) &&
8685 r8168_check_dash(tp)) {
8686 rtl8168_driver_start(tp); 8399 rtl8168_driver_start(tp);
8687 }
8688 8400
8689 netif_carrier_off(dev); 8401 netif_carrier_off(dev);
8690 8402
diff --git a/drivers/net/ethernet/renesas/ravb.h b/drivers/net/ethernet/renesas/ravb.h
index 96a27b00c90e..b81f4faf7b10 100644
--- a/drivers/net/ethernet/renesas/ravb.h
+++ b/drivers/net/ethernet/renesas/ravb.h
@@ -1018,6 +1018,7 @@ struct ravb_private {
1018 u32 dirty_rx[NUM_RX_QUEUE]; /* Producer ring indices */ 1018 u32 dirty_rx[NUM_RX_QUEUE]; /* Producer ring indices */
1019 u32 cur_tx[NUM_TX_QUEUE]; 1019 u32 cur_tx[NUM_TX_QUEUE];
1020 u32 dirty_tx[NUM_TX_QUEUE]; 1020 u32 dirty_tx[NUM_TX_QUEUE];
1021 u32 rx_buf_sz; /* Based on MTU+slack. */
1021 struct napi_struct napi[NUM_RX_QUEUE]; 1022 struct napi_struct napi[NUM_RX_QUEUE];
1022 struct work_struct work; 1023 struct work_struct work;
1023 /* MII transceiver section. */ 1024 /* MII transceiver section. */
diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
index a95fbd5510d9..68f122140966 100644
--- a/drivers/net/ethernet/renesas/ravb_main.c
+++ b/drivers/net/ethernet/renesas/ravb_main.c
@@ -238,7 +238,7 @@ static void ravb_ring_free(struct net_device *ndev, int q)
238 le32_to_cpu(desc->dptr))) 238 le32_to_cpu(desc->dptr)))
239 dma_unmap_single(ndev->dev.parent, 239 dma_unmap_single(ndev->dev.parent,
240 le32_to_cpu(desc->dptr), 240 le32_to_cpu(desc->dptr),
241 PKT_BUF_SZ, 241 priv->rx_buf_sz,
242 DMA_FROM_DEVICE); 242 DMA_FROM_DEVICE);
243 } 243 }
244 ring_size = sizeof(struct ravb_ex_rx_desc) * 244 ring_size = sizeof(struct ravb_ex_rx_desc) *
@@ -300,9 +300,9 @@ static void ravb_ring_format(struct net_device *ndev, int q)
300 for (i = 0; i < priv->num_rx_ring[q]; i++) { 300 for (i = 0; i < priv->num_rx_ring[q]; i++) {
301 /* RX descriptor */ 301 /* RX descriptor */
302 rx_desc = &priv->rx_ring[q][i]; 302 rx_desc = &priv->rx_ring[q][i];
303 rx_desc->ds_cc = cpu_to_le16(PKT_BUF_SZ); 303 rx_desc->ds_cc = cpu_to_le16(priv->rx_buf_sz);
304 dma_addr = dma_map_single(ndev->dev.parent, priv->rx_skb[q][i]->data, 304 dma_addr = dma_map_single(ndev->dev.parent, priv->rx_skb[q][i]->data,
305 PKT_BUF_SZ, 305 priv->rx_buf_sz,
306 DMA_FROM_DEVICE); 306 DMA_FROM_DEVICE);
307 /* We just set the data size to 0 for a failed mapping which 307 /* We just set the data size to 0 for a failed mapping which
308 * should prevent DMA from happening... 308 * should prevent DMA from happening...
@@ -346,6 +346,9 @@ static int ravb_ring_init(struct net_device *ndev, int q)
346 int ring_size; 346 int ring_size;
347 int i; 347 int i;
348 348
349 priv->rx_buf_sz = (ndev->mtu <= 1492 ? PKT_BUF_SZ : ndev->mtu) +
350 ETH_HLEN + VLAN_HLEN;
351
349 /* Allocate RX and TX skb rings */ 352 /* Allocate RX and TX skb rings */
350 priv->rx_skb[q] = kcalloc(priv->num_rx_ring[q], 353 priv->rx_skb[q] = kcalloc(priv->num_rx_ring[q],
351 sizeof(*priv->rx_skb[q]), GFP_KERNEL); 354 sizeof(*priv->rx_skb[q]), GFP_KERNEL);
@@ -355,7 +358,7 @@ static int ravb_ring_init(struct net_device *ndev, int q)
355 goto error; 358 goto error;
356 359
357 for (i = 0; i < priv->num_rx_ring[q]; i++) { 360 for (i = 0; i < priv->num_rx_ring[q]; i++) {
358 skb = netdev_alloc_skb(ndev, PKT_BUF_SZ + RAVB_ALIGN - 1); 361 skb = netdev_alloc_skb(ndev, priv->rx_buf_sz + RAVB_ALIGN - 1);
359 if (!skb) 362 if (!skb)
360 goto error; 363 goto error;
361 ravb_set_buffer_align(skb); 364 ravb_set_buffer_align(skb);
@@ -586,7 +589,7 @@ static bool ravb_rx(struct net_device *ndev, int *quota, int q)
586 skb = priv->rx_skb[q][entry]; 589 skb = priv->rx_skb[q][entry];
587 priv->rx_skb[q][entry] = NULL; 590 priv->rx_skb[q][entry] = NULL;
588 dma_unmap_single(ndev->dev.parent, le32_to_cpu(desc->dptr), 591 dma_unmap_single(ndev->dev.parent, le32_to_cpu(desc->dptr),
589 PKT_BUF_SZ, 592 priv->rx_buf_sz,
590 DMA_FROM_DEVICE); 593 DMA_FROM_DEVICE);
591 get_ts &= (q == RAVB_NC) ? 594 get_ts &= (q == RAVB_NC) ?
592 RAVB_RXTSTAMP_TYPE_V2_L2_EVENT : 595 RAVB_RXTSTAMP_TYPE_V2_L2_EVENT :
@@ -619,11 +622,12 @@ static bool ravb_rx(struct net_device *ndev, int *quota, int q)
619 for (; priv->cur_rx[q] - priv->dirty_rx[q] > 0; priv->dirty_rx[q]++) { 622 for (; priv->cur_rx[q] - priv->dirty_rx[q] > 0; priv->dirty_rx[q]++) {
620 entry = priv->dirty_rx[q] % priv->num_rx_ring[q]; 623 entry = priv->dirty_rx[q] % priv->num_rx_ring[q];
621 desc = &priv->rx_ring[q][entry]; 624 desc = &priv->rx_ring[q][entry];
622 desc->ds_cc = cpu_to_le16(PKT_BUF_SZ); 625 desc->ds_cc = cpu_to_le16(priv->rx_buf_sz);
623 626
624 if (!priv->rx_skb[q][entry]) { 627 if (!priv->rx_skb[q][entry]) {
625 skb = netdev_alloc_skb(ndev, 628 skb = netdev_alloc_skb(ndev,
626 PKT_BUF_SZ + RAVB_ALIGN - 1); 629 priv->rx_buf_sz +
630 RAVB_ALIGN - 1);
627 if (!skb) 631 if (!skb)
628 break; /* Better luck next round. */ 632 break; /* Better luck next round. */
629 ravb_set_buffer_align(skb); 633 ravb_set_buffer_align(skb);
@@ -1854,6 +1858,17 @@ static int ravb_do_ioctl(struct net_device *ndev, struct ifreq *req, int cmd)
1854 return phy_mii_ioctl(phydev, req, cmd); 1858 return phy_mii_ioctl(phydev, req, cmd);
1855} 1859}
1856 1860
1861static int ravb_change_mtu(struct net_device *ndev, int new_mtu)
1862{
1863 if (netif_running(ndev))
1864 return -EBUSY;
1865
1866 ndev->mtu = new_mtu;
1867 netdev_update_features(ndev);
1868
1869 return 0;
1870}
1871
1857static void ravb_set_rx_csum(struct net_device *ndev, bool enable) 1872static void ravb_set_rx_csum(struct net_device *ndev, bool enable)
1858{ 1873{
1859 struct ravb_private *priv = netdev_priv(ndev); 1874 struct ravb_private *priv = netdev_priv(ndev);
@@ -1895,6 +1910,7 @@ static const struct net_device_ops ravb_netdev_ops = {
1895 .ndo_set_rx_mode = ravb_set_rx_mode, 1910 .ndo_set_rx_mode = ravb_set_rx_mode,
1896 .ndo_tx_timeout = ravb_tx_timeout, 1911 .ndo_tx_timeout = ravb_tx_timeout,
1897 .ndo_do_ioctl = ravb_do_ioctl, 1912 .ndo_do_ioctl = ravb_do_ioctl,
1913 .ndo_change_mtu = ravb_change_mtu,
1898 .ndo_validate_addr = eth_validate_addr, 1914 .ndo_validate_addr = eth_validate_addr,
1899 .ndo_set_mac_address = eth_mac_addr, 1915 .ndo_set_mac_address = eth_mac_addr,
1900 .ndo_set_features = ravb_set_features, 1916 .ndo_set_features = ravb_set_features,
@@ -2117,6 +2133,9 @@ static int ravb_probe(struct platform_device *pdev)
2117 goto out_release; 2133 goto out_release;
2118 } 2134 }
2119 2135
2136 ndev->max_mtu = 2048 - (ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN);
2137 ndev->min_mtu = ETH_MIN_MTU;
2138
2120 /* Set function */ 2139 /* Set function */
2121 ndev->netdev_ops = &ravb_netdev_ops; 2140 ndev->netdev_ops = &ravb_netdev_ops;
2122 ndev->ethtool_ops = &ravb_ethtool_ops; 2141 ndev->ethtool_ops = &ravb_ethtool_ops;
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index 14c839bb09e7..3557fe3f2bb5 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -123,8 +123,8 @@ static const u16 sh_eth_offset_gigabit[SH_ETH_MAX_REGISTER_OFFSET] = {
123 [TSU_FWSL0] = 0x0030, 123 [TSU_FWSL0] = 0x0030,
124 [TSU_FWSL1] = 0x0034, 124 [TSU_FWSL1] = 0x0034,
125 [TSU_FWSLC] = 0x0038, 125 [TSU_FWSLC] = 0x0038,
126 [TSU_QTAG0] = 0x0040, 126 [TSU_QTAGM0] = 0x0040,
127 [TSU_QTAG1] = 0x0044, 127 [TSU_QTAGM1] = 0x0044,
128 [TSU_FWSR] = 0x0050, 128 [TSU_FWSR] = 0x0050,
129 [TSU_FWINMK] = 0x0054, 129 [TSU_FWINMK] = 0x0054,
130 [TSU_ADQT0] = 0x0048, 130 [TSU_ADQT0] = 0x0048,
@@ -763,6 +763,7 @@ static struct sh_eth_cpu_data sh7757_data = {
763 .rpadir = 1, 763 .rpadir = 1,
764 .rpadir_value = 2 << 16, 764 .rpadir_value = 2 << 16,
765 .rtrate = 1, 765 .rtrate = 1,
766 .dual_port = 1,
766}; 767};
767 768
768#define SH_GIGA_ETH_BASE 0xfee00000UL 769#define SH_GIGA_ETH_BASE 0xfee00000UL
@@ -841,6 +842,7 @@ static struct sh_eth_cpu_data sh7757_data_giga = {
841 .no_trimd = 1, 842 .no_trimd = 1,
842 .no_ade = 1, 843 .no_ade = 1,
843 .tsu = 1, 844 .tsu = 1,
845 .dual_port = 1,
844}; 846};
845 847
846/* SH7734 */ 848/* SH7734 */
@@ -911,6 +913,7 @@ static struct sh_eth_cpu_data sh7763_data = {
911 .tsu = 1, 913 .tsu = 1,
912 .irq_flags = IRQF_SHARED, 914 .irq_flags = IRQF_SHARED,
913 .magic = 1, 915 .magic = 1,
916 .dual_port = 1,
914}; 917};
915 918
916static struct sh_eth_cpu_data sh7619_data = { 919static struct sh_eth_cpu_data sh7619_data = {
@@ -943,6 +946,7 @@ static struct sh_eth_cpu_data sh771x_data = {
943 EESIPR_RRFIP | EESIPR_RTLFIP | EESIPR_RTSFIP | 946 EESIPR_RRFIP | EESIPR_RTLFIP | EESIPR_RTSFIP |
944 EESIPR_PREIP | EESIPR_CERFIP, 947 EESIPR_PREIP | EESIPR_CERFIP,
945 .tsu = 1, 948 .tsu = 1,
949 .dual_port = 1,
946}; 950};
947 951
948static void sh_eth_set_default_cpu_data(struct sh_eth_cpu_data *cd) 952static void sh_eth_set_default_cpu_data(struct sh_eth_cpu_data *cd)
@@ -972,20 +976,16 @@ static void sh_eth_set_default_cpu_data(struct sh_eth_cpu_data *cd)
972 976
973static int sh_eth_check_reset(struct net_device *ndev) 977static int sh_eth_check_reset(struct net_device *ndev)
974{ 978{
975 int ret = 0; 979 int cnt;
976 int cnt = 100;
977 980
978 while (cnt > 0) { 981 for (cnt = 100; cnt > 0; cnt--) {
979 if (!(sh_eth_read(ndev, EDMR) & EDMR_SRST_GETHER)) 982 if (!(sh_eth_read(ndev, EDMR) & EDMR_SRST_GETHER))
980 break; 983 return 0;
981 mdelay(1); 984 mdelay(1);
982 cnt--;
983 }
984 if (cnt <= 0) {
985 netdev_err(ndev, "Device reset failed\n");
986 ret = -ETIMEDOUT;
987 } 985 }
988 return ret; 986
987 netdev_err(ndev, "Device reset failed\n");
988 return -ETIMEDOUT;
989} 989}
990 990
991static int sh_eth_reset(struct net_device *ndev) 991static int sh_eth_reset(struct net_device *ndev)
@@ -2112,8 +2112,6 @@ static size_t __sh_eth_get_regs(struct net_device *ndev, u32 *buf)
2112 add_tsu_reg(TSU_FWSL0); 2112 add_tsu_reg(TSU_FWSL0);
2113 add_tsu_reg(TSU_FWSL1); 2113 add_tsu_reg(TSU_FWSL1);
2114 add_tsu_reg(TSU_FWSLC); 2114 add_tsu_reg(TSU_FWSLC);
2115 add_tsu_reg(TSU_QTAG0);
2116 add_tsu_reg(TSU_QTAG1);
2117 add_tsu_reg(TSU_QTAGM0); 2115 add_tsu_reg(TSU_QTAGM0);
2118 add_tsu_reg(TSU_QTAGM1); 2116 add_tsu_reg(TSU_QTAGM1);
2119 add_tsu_reg(TSU_FWSR); 2117 add_tsu_reg(TSU_FWSR);
@@ -2932,7 +2930,7 @@ static int sh_eth_vlan_rx_kill_vid(struct net_device *ndev,
2932/* SuperH's TSU register init function */ 2930/* SuperH's TSU register init function */
2933static void sh_eth_tsu_init(struct sh_eth_private *mdp) 2931static void sh_eth_tsu_init(struct sh_eth_private *mdp)
2934{ 2932{
2935 if (sh_eth_is_rz_fast_ether(mdp)) { 2933 if (!mdp->cd->dual_port) {
2936 sh_eth_tsu_write(mdp, 0, TSU_TEN); /* Disable all CAM entry */ 2934 sh_eth_tsu_write(mdp, 0, TSU_TEN); /* Disable all CAM entry */
2937 sh_eth_tsu_write(mdp, TSU_FWSLC_POSTENU | TSU_FWSLC_POSTENL, 2935 sh_eth_tsu_write(mdp, TSU_FWSLC_POSTENU | TSU_FWSLC_POSTENL,
2938 TSU_FWSLC); /* Enable POST registers */ 2936 TSU_FWSLC); /* Enable POST registers */
@@ -2949,13 +2947,8 @@ static void sh_eth_tsu_init(struct sh_eth_private *mdp)
2949 sh_eth_tsu_write(mdp, 0, TSU_FWSL0); 2947 sh_eth_tsu_write(mdp, 0, TSU_FWSL0);
2950 sh_eth_tsu_write(mdp, 0, TSU_FWSL1); 2948 sh_eth_tsu_write(mdp, 0, TSU_FWSL1);
2951 sh_eth_tsu_write(mdp, TSU_FWSLC_POSTENU | TSU_FWSLC_POSTENL, TSU_FWSLC); 2949 sh_eth_tsu_write(mdp, TSU_FWSLC_POSTENU | TSU_FWSLC_POSTENL, TSU_FWSLC);
2952 if (sh_eth_is_gether(mdp)) { 2950 sh_eth_tsu_write(mdp, 0, TSU_QTAGM0); /* Disable QTAG(0->1) */
2953 sh_eth_tsu_write(mdp, 0, TSU_QTAG0); /* Disable QTAG(0->1) */ 2951 sh_eth_tsu_write(mdp, 0, TSU_QTAGM1); /* Disable QTAG(1->0) */
2954 sh_eth_tsu_write(mdp, 0, TSU_QTAG1); /* Disable QTAG(1->0) */
2955 } else {
2956 sh_eth_tsu_write(mdp, 0, TSU_QTAGM0); /* Disable QTAG(0->1) */
2957 sh_eth_tsu_write(mdp, 0, TSU_QTAGM1); /* Disable QTAG(1->0) */
2958 }
2959 sh_eth_tsu_write(mdp, 0, TSU_FWSR); /* all interrupt status clear */ 2952 sh_eth_tsu_write(mdp, 0, TSU_FWSR); /* all interrupt status clear */
2960 sh_eth_tsu_write(mdp, 0, TSU_FWINMK); /* Disable all interrupt */ 2953 sh_eth_tsu_write(mdp, 0, TSU_FWINMK); /* Disable all interrupt */
2961 sh_eth_tsu_write(mdp, 0, TSU_TEN); /* Disable all CAM entry */ 2954 sh_eth_tsu_write(mdp, 0, TSU_TEN); /* Disable all CAM entry */
diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h
index e5fe70134690..21047d58a93f 100644
--- a/drivers/net/ethernet/renesas/sh_eth.h
+++ b/drivers/net/ethernet/renesas/sh_eth.h
@@ -118,8 +118,8 @@ enum {
118 TSU_FWSL0, 118 TSU_FWSL0,
119 TSU_FWSL1, 119 TSU_FWSL1,
120 TSU_FWSLC, 120 TSU_FWSLC,
121 TSU_QTAG0, 121 TSU_QTAG0, /* Same as TSU_QTAGM0 */
122 TSU_QTAG1, 122 TSU_QTAG1, /* Same as TSU_QTAGM1 */
123 TSU_QTAGM0, 123 TSU_QTAGM0,
124 TSU_QTAGM1, 124 TSU_QTAGM1,
125 TSU_FWSR, 125 TSU_FWSR,
@@ -509,6 +509,7 @@ struct sh_eth_cpu_data {
509 unsigned rmiimode:1; /* EtherC has RMIIMODE register */ 509 unsigned rmiimode:1; /* EtherC has RMIIMODE register */
510 unsigned rtrate:1; /* EtherC has RTRATE register */ 510 unsigned rtrate:1; /* EtherC has RTRATE register */
511 unsigned magic:1; /* EtherC has ECMR.MPDE and ECSR.MPD */ 511 unsigned magic:1; /* EtherC has ECMR.MPDE and ECSR.MPD */
512 unsigned dual_port:1; /* Dual EtherC/E-DMAC */
512}; 513};
513 514
514struct sh_eth_private { 515struct sh_eth_private {
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c
index 75fbf58e421c..e100273b623d 100644
--- a/drivers/net/ethernet/sfc/ef10.c
+++ b/drivers/net/ethernet/sfc/ef10.c
@@ -28,9 +28,6 @@ enum {
28 EFX_EF10_TEST = 1, 28 EFX_EF10_TEST = 1,
29 EFX_EF10_REFILL, 29 EFX_EF10_REFILL,
30}; 30};
31
32/* The reserved RSS context value */
33#define EFX_EF10_RSS_CONTEXT_INVALID 0xffffffff
34/* The maximum size of a shared RSS context */ 31/* The maximum size of a shared RSS context */
35/* TODO: this should really be from the mcdi protocol export */ 32/* TODO: this should really be from the mcdi protocol export */
36#define EFX_EF10_MAX_SHARED_RSS_CONTEXT_SIZE 64UL 33#define EFX_EF10_MAX_SHARED_RSS_CONTEXT_SIZE 64UL
@@ -697,7 +694,7 @@ static int efx_ef10_probe(struct efx_nic *efx)
697 } 694 }
698 nic_data->warm_boot_count = rc; 695 nic_data->warm_boot_count = rc;
699 696
700 nic_data->rx_rss_context = EFX_EF10_RSS_CONTEXT_INVALID; 697 efx->rss_context.context_id = EFX_EF10_RSS_CONTEXT_INVALID;
701 698
702 nic_data->vport_id = EVB_PORT_ID_ASSIGNED; 699 nic_data->vport_id = EVB_PORT_ID_ASSIGNED;
703 700
@@ -1489,8 +1486,8 @@ static int efx_ef10_init_nic(struct efx_nic *efx)
1489 } 1486 }
1490 1487
1491 /* don't fail init if RSS setup doesn't work */ 1488 /* don't fail init if RSS setup doesn't work */
1492 rc = efx->type->rx_push_rss_config(efx, false, efx->rx_indir_table, NULL); 1489 rc = efx->type->rx_push_rss_config(efx, false,
1493 efx->rss_active = (rc == 0); 1490 efx->rss_context.rx_indir_table, NULL);
1494 1491
1495 return 0; 1492 return 0;
1496} 1493}
@@ -1507,7 +1504,7 @@ static void efx_ef10_reset_mc_allocations(struct efx_nic *efx)
1507 nic_data->must_restore_filters = true; 1504 nic_data->must_restore_filters = true;
1508 nic_data->must_restore_piobufs = true; 1505 nic_data->must_restore_piobufs = true;
1509 efx_ef10_forget_old_piobufs(efx); 1506 efx_ef10_forget_old_piobufs(efx);
1510 nic_data->rx_rss_context = EFX_EF10_RSS_CONTEXT_INVALID; 1507 efx->rss_context.context_id = EFX_EF10_RSS_CONTEXT_INVALID;
1511 1508
1512 /* Driver-created vswitches and vports must be re-created */ 1509 /* Driver-created vswitches and vports must be re-created */
1513 nic_data->must_probe_vswitching = true; 1510 nic_data->must_probe_vswitching = true;
@@ -2703,27 +2700,30 @@ static int efx_ef10_get_rss_flags(struct efx_nic *efx, u32 context, u32 *flags)
2703 * Defaults are 4-tuple for TCP and 2-tuple for UDP and other-IP, so we 2700 * Defaults are 4-tuple for TCP and 2-tuple for UDP and other-IP, so we
2704 * just need to set the UDP ports flags (for both IP versions). 2701 * just need to set the UDP ports flags (for both IP versions).
2705 */ 2702 */
2706static void efx_ef10_set_rss_flags(struct efx_nic *efx, u32 context) 2703static void efx_ef10_set_rss_flags(struct efx_nic *efx,
2704 struct efx_rss_context *ctx)
2707{ 2705{
2708 MCDI_DECLARE_BUF(inbuf, MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_LEN); 2706 MCDI_DECLARE_BUF(inbuf, MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_LEN);
2709 u32 flags; 2707 u32 flags;
2710 2708
2711 BUILD_BUG_ON(MC_CMD_RSS_CONTEXT_SET_FLAGS_OUT_LEN != 0); 2709 BUILD_BUG_ON(MC_CMD_RSS_CONTEXT_SET_FLAGS_OUT_LEN != 0);
2712 2710
2713 if (efx_ef10_get_rss_flags(efx, context, &flags) != 0) 2711 if (efx_ef10_get_rss_flags(efx, ctx->context_id, &flags) != 0)
2714 return; 2712 return;
2715 MCDI_SET_DWORD(inbuf, RSS_CONTEXT_SET_FLAGS_IN_RSS_CONTEXT_ID, context); 2713 MCDI_SET_DWORD(inbuf, RSS_CONTEXT_SET_FLAGS_IN_RSS_CONTEXT_ID,
2714 ctx->context_id);
2716 flags |= RSS_MODE_HASH_PORTS << MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_UDP_IPV4_RSS_MODE_LBN; 2715 flags |= RSS_MODE_HASH_PORTS << MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_UDP_IPV4_RSS_MODE_LBN;
2717 flags |= RSS_MODE_HASH_PORTS << MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_UDP_IPV6_RSS_MODE_LBN; 2716 flags |= RSS_MODE_HASH_PORTS << MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_UDP_IPV6_RSS_MODE_LBN;
2718 MCDI_SET_DWORD(inbuf, RSS_CONTEXT_SET_FLAGS_IN_FLAGS, flags); 2717 MCDI_SET_DWORD(inbuf, RSS_CONTEXT_SET_FLAGS_IN_FLAGS, flags);
2719 if (!efx_mcdi_rpc(efx, MC_CMD_RSS_CONTEXT_SET_FLAGS, inbuf, sizeof(inbuf), 2718 if (!efx_mcdi_rpc(efx, MC_CMD_RSS_CONTEXT_SET_FLAGS, inbuf, sizeof(inbuf),
2720 NULL, 0, NULL)) 2719 NULL, 0, NULL))
2721 /* Succeeded, so UDP 4-tuple is now enabled */ 2720 /* Succeeded, so UDP 4-tuple is now enabled */
2722 efx->rx_hash_udp_4tuple = true; 2721 ctx->rx_hash_udp_4tuple = true;
2723} 2722}
2724 2723
2725static int efx_ef10_alloc_rss_context(struct efx_nic *efx, u32 *context, 2724static int efx_ef10_alloc_rss_context(struct efx_nic *efx, bool exclusive,
2726 bool exclusive, unsigned *context_size) 2725 struct efx_rss_context *ctx,
2726 unsigned *context_size)
2727{ 2727{
2728 MCDI_DECLARE_BUF(inbuf, MC_CMD_RSS_CONTEXT_ALLOC_IN_LEN); 2728 MCDI_DECLARE_BUF(inbuf, MC_CMD_RSS_CONTEXT_ALLOC_IN_LEN);
2729 MCDI_DECLARE_BUF(outbuf, MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN); 2729 MCDI_DECLARE_BUF(outbuf, MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN);
@@ -2739,7 +2739,7 @@ static int efx_ef10_alloc_rss_context(struct efx_nic *efx, u32 *context,
2739 EFX_EF10_MAX_SHARED_RSS_CONTEXT_SIZE); 2739 EFX_EF10_MAX_SHARED_RSS_CONTEXT_SIZE);
2740 2740
2741 if (!exclusive && rss_spread == 1) { 2741 if (!exclusive && rss_spread == 1) {
2742 *context = EFX_EF10_RSS_CONTEXT_INVALID; 2742 ctx->context_id = EFX_EF10_RSS_CONTEXT_INVALID;
2743 if (context_size) 2743 if (context_size)
2744 *context_size = 1; 2744 *context_size = 1;
2745 return 0; 2745 return 0;
@@ -2762,29 +2762,26 @@ static int efx_ef10_alloc_rss_context(struct efx_nic *efx, u32 *context,
2762 if (outlen < MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN) 2762 if (outlen < MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN)
2763 return -EIO; 2763 return -EIO;
2764 2764
2765 *context = MCDI_DWORD(outbuf, RSS_CONTEXT_ALLOC_OUT_RSS_CONTEXT_ID); 2765 ctx->context_id = MCDI_DWORD(outbuf, RSS_CONTEXT_ALLOC_OUT_RSS_CONTEXT_ID);
2766 2766
2767 if (context_size) 2767 if (context_size)
2768 *context_size = rss_spread; 2768 *context_size = rss_spread;
2769 2769
2770 if (nic_data->datapath_caps & 2770 if (nic_data->datapath_caps &
2771 1 << MC_CMD_GET_CAPABILITIES_OUT_ADDITIONAL_RSS_MODES_LBN) 2771 1 << MC_CMD_GET_CAPABILITIES_OUT_ADDITIONAL_RSS_MODES_LBN)
2772 efx_ef10_set_rss_flags(efx, *context); 2772 efx_ef10_set_rss_flags(efx, ctx);
2773 2773
2774 return 0; 2774 return 0;
2775} 2775}
2776 2776
2777static void efx_ef10_free_rss_context(struct efx_nic *efx, u32 context) 2777static int efx_ef10_free_rss_context(struct efx_nic *efx, u32 context)
2778{ 2778{
2779 MCDI_DECLARE_BUF(inbuf, MC_CMD_RSS_CONTEXT_FREE_IN_LEN); 2779 MCDI_DECLARE_BUF(inbuf, MC_CMD_RSS_CONTEXT_FREE_IN_LEN);
2780 int rc;
2781 2780
2782 MCDI_SET_DWORD(inbuf, RSS_CONTEXT_FREE_IN_RSS_CONTEXT_ID, 2781 MCDI_SET_DWORD(inbuf, RSS_CONTEXT_FREE_IN_RSS_CONTEXT_ID,
2783 context); 2782 context);
2784 2783 return efx_mcdi_rpc(efx, MC_CMD_RSS_CONTEXT_FREE, inbuf, sizeof(inbuf),
2785 rc = efx_mcdi_rpc(efx, MC_CMD_RSS_CONTEXT_FREE, inbuf, sizeof(inbuf),
2786 NULL, 0, NULL); 2784 NULL, 0, NULL);
2787 WARN_ON(rc != 0);
2788} 2785}
2789 2786
2790static int efx_ef10_populate_rss_table(struct efx_nic *efx, u32 context, 2787static int efx_ef10_populate_rss_table(struct efx_nic *efx, u32 context,
@@ -2796,15 +2793,15 @@ static int efx_ef10_populate_rss_table(struct efx_nic *efx, u32 context,
2796 2793
2797 MCDI_SET_DWORD(tablebuf, RSS_CONTEXT_SET_TABLE_IN_RSS_CONTEXT_ID, 2794 MCDI_SET_DWORD(tablebuf, RSS_CONTEXT_SET_TABLE_IN_RSS_CONTEXT_ID,
2798 context); 2795 context);
2799 BUILD_BUG_ON(ARRAY_SIZE(efx->rx_indir_table) != 2796 BUILD_BUG_ON(ARRAY_SIZE(efx->rss_context.rx_indir_table) !=
2800 MC_CMD_RSS_CONTEXT_SET_TABLE_IN_INDIRECTION_TABLE_LEN); 2797 MC_CMD_RSS_CONTEXT_SET_TABLE_IN_INDIRECTION_TABLE_LEN);
2801 2798
2802 /* This iterates over the length of efx->rx_indir_table, but copies 2799 /* This iterates over the length of efx->rss_context.rx_indir_table, but
2803 * bytes from rx_indir_table. That's because the latter is a pointer 2800 * copies bytes from rx_indir_table. That's because the latter is a
2804 * rather than an array, but should have the same length. 2801 * pointer rather than an array, but should have the same length.
2805 * The efx->rx_hash_key loop below is similar. 2802 * The efx->rss_context.rx_hash_key loop below is similar.
2806 */ 2803 */
2807 for (i = 0; i < ARRAY_SIZE(efx->rx_indir_table); ++i) 2804 for (i = 0; i < ARRAY_SIZE(efx->rss_context.rx_indir_table); ++i)
2808 MCDI_PTR(tablebuf, 2805 MCDI_PTR(tablebuf,
2809 RSS_CONTEXT_SET_TABLE_IN_INDIRECTION_TABLE)[i] = 2806 RSS_CONTEXT_SET_TABLE_IN_INDIRECTION_TABLE)[i] =
2810 (u8) rx_indir_table[i]; 2807 (u8) rx_indir_table[i];
@@ -2816,9 +2813,9 @@ static int efx_ef10_populate_rss_table(struct efx_nic *efx, u32 context,
2816 2813
2817 MCDI_SET_DWORD(keybuf, RSS_CONTEXT_SET_KEY_IN_RSS_CONTEXT_ID, 2814 MCDI_SET_DWORD(keybuf, RSS_CONTEXT_SET_KEY_IN_RSS_CONTEXT_ID,
2818 context); 2815 context);
2819 BUILD_BUG_ON(ARRAY_SIZE(efx->rx_hash_key) != 2816 BUILD_BUG_ON(ARRAY_SIZE(efx->rss_context.rx_hash_key) !=
2820 MC_CMD_RSS_CONTEXT_SET_KEY_IN_TOEPLITZ_KEY_LEN); 2817 MC_CMD_RSS_CONTEXT_SET_KEY_IN_TOEPLITZ_KEY_LEN);
2821 for (i = 0; i < ARRAY_SIZE(efx->rx_hash_key); ++i) 2818 for (i = 0; i < ARRAY_SIZE(efx->rss_context.rx_hash_key); ++i)
2822 MCDI_PTR(keybuf, RSS_CONTEXT_SET_KEY_IN_TOEPLITZ_KEY)[i] = key[i]; 2819 MCDI_PTR(keybuf, RSS_CONTEXT_SET_KEY_IN_TOEPLITZ_KEY)[i] = key[i];
2823 2820
2824 return efx_mcdi_rpc(efx, MC_CMD_RSS_CONTEXT_SET_KEY, keybuf, 2821 return efx_mcdi_rpc(efx, MC_CMD_RSS_CONTEXT_SET_KEY, keybuf,
@@ -2827,27 +2824,27 @@ static int efx_ef10_populate_rss_table(struct efx_nic *efx, u32 context,
2827 2824
2828static void efx_ef10_rx_free_indir_table(struct efx_nic *efx) 2825static void efx_ef10_rx_free_indir_table(struct efx_nic *efx)
2829{ 2826{
2830 struct efx_ef10_nic_data *nic_data = efx->nic_data; 2827 int rc;
2831 2828
2832 if (nic_data->rx_rss_context != EFX_EF10_RSS_CONTEXT_INVALID) 2829 if (efx->rss_context.context_id != EFX_EF10_RSS_CONTEXT_INVALID) {
2833 efx_ef10_free_rss_context(efx, nic_data->rx_rss_context); 2830 rc = efx_ef10_free_rss_context(efx, efx->rss_context.context_id);
2834 nic_data->rx_rss_context = EFX_EF10_RSS_CONTEXT_INVALID; 2831 WARN_ON(rc != 0);
2832 }
2833 efx->rss_context.context_id = EFX_EF10_RSS_CONTEXT_INVALID;
2835} 2834}
2836 2835
2837static int efx_ef10_rx_push_shared_rss_config(struct efx_nic *efx, 2836static int efx_ef10_rx_push_shared_rss_config(struct efx_nic *efx,
2838 unsigned *context_size) 2837 unsigned *context_size)
2839{ 2838{
2840 u32 new_rx_rss_context;
2841 struct efx_ef10_nic_data *nic_data = efx->nic_data; 2839 struct efx_ef10_nic_data *nic_data = efx->nic_data;
2842 int rc = efx_ef10_alloc_rss_context(efx, &new_rx_rss_context, 2840 int rc = efx_ef10_alloc_rss_context(efx, false, &efx->rss_context,
2843 false, context_size); 2841 context_size);
2844 2842
2845 if (rc != 0) 2843 if (rc != 0)
2846 return rc; 2844 return rc;
2847 2845
2848 nic_data->rx_rss_context = new_rx_rss_context;
2849 nic_data->rx_rss_context_exclusive = false; 2846 nic_data->rx_rss_context_exclusive = false;
2850 efx_set_default_rx_indir_table(efx); 2847 efx_set_default_rx_indir_table(efx, &efx->rss_context);
2851 return 0; 2848 return 0;
2852} 2849}
2853 2850
@@ -2855,50 +2852,79 @@ static int efx_ef10_rx_push_exclusive_rss_config(struct efx_nic *efx,
2855 const u32 *rx_indir_table, 2852 const u32 *rx_indir_table,
2856 const u8 *key) 2853 const u8 *key)
2857{ 2854{
2855 u32 old_rx_rss_context = efx->rss_context.context_id;
2858 struct efx_ef10_nic_data *nic_data = efx->nic_data; 2856 struct efx_ef10_nic_data *nic_data = efx->nic_data;
2859 int rc; 2857 int rc;
2860 u32 new_rx_rss_context;
2861 2858
2862 if (nic_data->rx_rss_context == EFX_EF10_RSS_CONTEXT_INVALID || 2859 if (efx->rss_context.context_id == EFX_EF10_RSS_CONTEXT_INVALID ||
2863 !nic_data->rx_rss_context_exclusive) { 2860 !nic_data->rx_rss_context_exclusive) {
2864 rc = efx_ef10_alloc_rss_context(efx, &new_rx_rss_context, 2861 rc = efx_ef10_alloc_rss_context(efx, true, &efx->rss_context,
2865 true, NULL); 2862 NULL);
2866 if (rc == -EOPNOTSUPP) 2863 if (rc == -EOPNOTSUPP)
2867 return rc; 2864 return rc;
2868 else if (rc != 0) 2865 else if (rc != 0)
2869 goto fail1; 2866 goto fail1;
2870 } else {
2871 new_rx_rss_context = nic_data->rx_rss_context;
2872 } 2867 }
2873 2868
2874 rc = efx_ef10_populate_rss_table(efx, new_rx_rss_context, 2869 rc = efx_ef10_populate_rss_table(efx, efx->rss_context.context_id,
2875 rx_indir_table, key); 2870 rx_indir_table, key);
2876 if (rc != 0) 2871 if (rc != 0)
2877 goto fail2; 2872 goto fail2;
2878 2873
2879 if (nic_data->rx_rss_context != new_rx_rss_context) 2874 if (efx->rss_context.context_id != old_rx_rss_context &&
2880 efx_ef10_rx_free_indir_table(efx); 2875 old_rx_rss_context != EFX_EF10_RSS_CONTEXT_INVALID)
2881 nic_data->rx_rss_context = new_rx_rss_context; 2876 WARN_ON(efx_ef10_free_rss_context(efx, old_rx_rss_context) != 0);
2882 nic_data->rx_rss_context_exclusive = true; 2877 nic_data->rx_rss_context_exclusive = true;
2883 if (rx_indir_table != efx->rx_indir_table) 2878 if (rx_indir_table != efx->rss_context.rx_indir_table)
2884 memcpy(efx->rx_indir_table, rx_indir_table, 2879 memcpy(efx->rss_context.rx_indir_table, rx_indir_table,
2885 sizeof(efx->rx_indir_table)); 2880 sizeof(efx->rss_context.rx_indir_table));
2886 if (key != efx->rx_hash_key) 2881 if (key != efx->rss_context.rx_hash_key)
2887 memcpy(efx->rx_hash_key, key, efx->type->rx_hash_key_size); 2882 memcpy(efx->rss_context.rx_hash_key, key,
2883 efx->type->rx_hash_key_size);
2888 2884
2889 return 0; 2885 return 0;
2890 2886
2891fail2: 2887fail2:
2892 if (new_rx_rss_context != nic_data->rx_rss_context) 2888 if (old_rx_rss_context != efx->rss_context.context_id) {
2893 efx_ef10_free_rss_context(efx, new_rx_rss_context); 2889 WARN_ON(efx_ef10_free_rss_context(efx, efx->rss_context.context_id) != 0);
2890 efx->rss_context.context_id = old_rx_rss_context;
2891 }
2894fail1: 2892fail1:
2895 netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc); 2893 netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
2896 return rc; 2894 return rc;
2897} 2895}
2898 2896
2899static int efx_ef10_rx_pull_rss_config(struct efx_nic *efx) 2897static int efx_ef10_rx_push_rss_context_config(struct efx_nic *efx,
2898 struct efx_rss_context *ctx,
2899 const u32 *rx_indir_table,
2900 const u8 *key)
2901{
2902 int rc;
2903
2904 if (ctx->context_id == EFX_EF10_RSS_CONTEXT_INVALID) {
2905 rc = efx_ef10_alloc_rss_context(efx, true, ctx, NULL);
2906 if (rc)
2907 return rc;
2908 }
2909
2910 if (!rx_indir_table) /* Delete this context */
2911 return efx_ef10_free_rss_context(efx, ctx->context_id);
2912
2913 rc = efx_ef10_populate_rss_table(efx, ctx->context_id,
2914 rx_indir_table, key);
2915 if (rc)
2916 return rc;
2917
2918 memcpy(ctx->rx_indir_table, rx_indir_table,
2919 sizeof(efx->rss_context.rx_indir_table));
2920 memcpy(ctx->rx_hash_key, key, efx->type->rx_hash_key_size);
2921
2922 return 0;
2923}
2924
2925static int efx_ef10_rx_pull_rss_context_config(struct efx_nic *efx,
2926 struct efx_rss_context *ctx)
2900{ 2927{
2901 struct efx_ef10_nic_data *nic_data = efx->nic_data;
2902 MCDI_DECLARE_BUF(inbuf, MC_CMD_RSS_CONTEXT_GET_TABLE_IN_LEN); 2928 MCDI_DECLARE_BUF(inbuf, MC_CMD_RSS_CONTEXT_GET_TABLE_IN_LEN);
2903 MCDI_DECLARE_BUF(tablebuf, MC_CMD_RSS_CONTEXT_GET_TABLE_OUT_LEN); 2929 MCDI_DECLARE_BUF(tablebuf, MC_CMD_RSS_CONTEXT_GET_TABLE_OUT_LEN);
2904 MCDI_DECLARE_BUF(keybuf, MC_CMD_RSS_CONTEXT_GET_KEY_OUT_LEN); 2930 MCDI_DECLARE_BUF(keybuf, MC_CMD_RSS_CONTEXT_GET_KEY_OUT_LEN);
@@ -2908,12 +2934,12 @@ static int efx_ef10_rx_pull_rss_config(struct efx_nic *efx)
2908 BUILD_BUG_ON(MC_CMD_RSS_CONTEXT_GET_TABLE_IN_LEN != 2934 BUILD_BUG_ON(MC_CMD_RSS_CONTEXT_GET_TABLE_IN_LEN !=
2909 MC_CMD_RSS_CONTEXT_GET_KEY_IN_LEN); 2935 MC_CMD_RSS_CONTEXT_GET_KEY_IN_LEN);
2910 2936
2911 if (nic_data->rx_rss_context == EFX_EF10_RSS_CONTEXT_INVALID) 2937 if (ctx->context_id == EFX_EF10_RSS_CONTEXT_INVALID)
2912 return -ENOENT; 2938 return -ENOENT;
2913 2939
2914 MCDI_SET_DWORD(inbuf, RSS_CONTEXT_GET_TABLE_IN_RSS_CONTEXT_ID, 2940 MCDI_SET_DWORD(inbuf, RSS_CONTEXT_GET_TABLE_IN_RSS_CONTEXT_ID,
2915 nic_data->rx_rss_context); 2941 ctx->context_id);
2916 BUILD_BUG_ON(ARRAY_SIZE(efx->rx_indir_table) != 2942 BUILD_BUG_ON(ARRAY_SIZE(ctx->rx_indir_table) !=
2917 MC_CMD_RSS_CONTEXT_GET_TABLE_OUT_INDIRECTION_TABLE_LEN); 2943 MC_CMD_RSS_CONTEXT_GET_TABLE_OUT_INDIRECTION_TABLE_LEN);
2918 rc = efx_mcdi_rpc(efx, MC_CMD_RSS_CONTEXT_GET_TABLE, inbuf, sizeof(inbuf), 2944 rc = efx_mcdi_rpc(efx, MC_CMD_RSS_CONTEXT_GET_TABLE, inbuf, sizeof(inbuf),
2919 tablebuf, sizeof(tablebuf), &outlen); 2945 tablebuf, sizeof(tablebuf), &outlen);
@@ -2923,13 +2949,13 @@ static int efx_ef10_rx_pull_rss_config(struct efx_nic *efx)
2923 if (WARN_ON(outlen != MC_CMD_RSS_CONTEXT_GET_TABLE_OUT_LEN)) 2949 if (WARN_ON(outlen != MC_CMD_RSS_CONTEXT_GET_TABLE_OUT_LEN))
2924 return -EIO; 2950 return -EIO;
2925 2951
2926 for (i = 0; i < ARRAY_SIZE(efx->rx_indir_table); i++) 2952 for (i = 0; i < ARRAY_SIZE(ctx->rx_indir_table); i++)
2927 efx->rx_indir_table[i] = MCDI_PTR(tablebuf, 2953 ctx->rx_indir_table[i] = MCDI_PTR(tablebuf,
2928 RSS_CONTEXT_GET_TABLE_OUT_INDIRECTION_TABLE)[i]; 2954 RSS_CONTEXT_GET_TABLE_OUT_INDIRECTION_TABLE)[i];
2929 2955
2930 MCDI_SET_DWORD(inbuf, RSS_CONTEXT_GET_KEY_IN_RSS_CONTEXT_ID, 2956 MCDI_SET_DWORD(inbuf, RSS_CONTEXT_GET_KEY_IN_RSS_CONTEXT_ID,
2931 nic_data->rx_rss_context); 2957 ctx->context_id);
2932 BUILD_BUG_ON(ARRAY_SIZE(efx->rx_hash_key) != 2958 BUILD_BUG_ON(ARRAY_SIZE(ctx->rx_hash_key) !=
2933 MC_CMD_RSS_CONTEXT_SET_KEY_IN_TOEPLITZ_KEY_LEN); 2959 MC_CMD_RSS_CONTEXT_SET_KEY_IN_TOEPLITZ_KEY_LEN);
2934 rc = efx_mcdi_rpc(efx, MC_CMD_RSS_CONTEXT_GET_KEY, inbuf, sizeof(inbuf), 2960 rc = efx_mcdi_rpc(efx, MC_CMD_RSS_CONTEXT_GET_KEY, inbuf, sizeof(inbuf),
2935 keybuf, sizeof(keybuf), &outlen); 2961 keybuf, sizeof(keybuf), &outlen);
@@ -2939,13 +2965,38 @@ static int efx_ef10_rx_pull_rss_config(struct efx_nic *efx)
2939 if (WARN_ON(outlen != MC_CMD_RSS_CONTEXT_GET_KEY_OUT_LEN)) 2965 if (WARN_ON(outlen != MC_CMD_RSS_CONTEXT_GET_KEY_OUT_LEN))
2940 return -EIO; 2966 return -EIO;
2941 2967
2942 for (i = 0; i < ARRAY_SIZE(efx->rx_hash_key); ++i) 2968 for (i = 0; i < ARRAY_SIZE(ctx->rx_hash_key); ++i)
2943 efx->rx_hash_key[i] = MCDI_PTR( 2969 ctx->rx_hash_key[i] = MCDI_PTR(
2944 keybuf, RSS_CONTEXT_GET_KEY_OUT_TOEPLITZ_KEY)[i]; 2970 keybuf, RSS_CONTEXT_GET_KEY_OUT_TOEPLITZ_KEY)[i];
2945 2971
2946 return 0; 2972 return 0;
2947} 2973}
2948 2974
2975static int efx_ef10_rx_pull_rss_config(struct efx_nic *efx)
2976{
2977 return efx_ef10_rx_pull_rss_context_config(efx, &efx->rss_context);
2978}
2979
2980static void efx_ef10_rx_restore_rss_contexts(struct efx_nic *efx)
2981{
2982 struct efx_rss_context *ctx;
2983 int rc;
2984
2985 list_for_each_entry(ctx, &efx->rss_context.list, list) {
2986 /* previous NIC RSS context is gone */
2987 ctx->context_id = EFX_EF10_RSS_CONTEXT_INVALID;
2988 /* so try to allocate a new one */
2989 rc = efx_ef10_rx_push_rss_context_config(efx, ctx,
2990 ctx->rx_indir_table,
2991 ctx->rx_hash_key);
2992 if (rc)
2993 netif_warn(efx, probe, efx->net_dev,
2994 "failed to restore RSS context %u, rc=%d"
2995 "; RSS filters may fail to be applied\n",
2996 ctx->user_id, rc);
2997 }
2998}
2999
2949static int efx_ef10_pf_rx_push_rss_config(struct efx_nic *efx, bool user, 3000static int efx_ef10_pf_rx_push_rss_config(struct efx_nic *efx, bool user,
2950 const u32 *rx_indir_table, 3001 const u32 *rx_indir_table,
2951 const u8 *key) 3002 const u8 *key)
@@ -2956,7 +3007,7 @@ static int efx_ef10_pf_rx_push_rss_config(struct efx_nic *efx, bool user,
2956 return 0; 3007 return 0;
2957 3008
2958 if (!key) 3009 if (!key)
2959 key = efx->rx_hash_key; 3010 key = efx->rss_context.rx_hash_key;
2960 3011
2961 rc = efx_ef10_rx_push_exclusive_rss_config(efx, rx_indir_table, key); 3012 rc = efx_ef10_rx_push_exclusive_rss_config(efx, rx_indir_table, key);
2962 3013
@@ -2965,7 +3016,8 @@ static int efx_ef10_pf_rx_push_rss_config(struct efx_nic *efx, bool user,
2965 bool mismatch = false; 3016 bool mismatch = false;
2966 size_t i; 3017 size_t i;
2967 3018
2968 for (i = 0; i < ARRAY_SIZE(efx->rx_indir_table) && !mismatch; 3019 for (i = 0;
3020 i < ARRAY_SIZE(efx->rss_context.rx_indir_table) && !mismatch;
2969 i++) 3021 i++)
2970 mismatch = rx_indir_table[i] != 3022 mismatch = rx_indir_table[i] !=
2971 ethtool_rxfh_indir_default(i, efx->rss_spread); 3023 ethtool_rxfh_indir_default(i, efx->rss_spread);
@@ -3000,11 +3052,9 @@ static int efx_ef10_vf_rx_push_rss_config(struct efx_nic *efx, bool user,
3000 const u8 *key 3052 const u8 *key
3001 __attribute__ ((unused))) 3053 __attribute__ ((unused)))
3002{ 3054{
3003 struct efx_ef10_nic_data *nic_data = efx->nic_data;
3004
3005 if (user) 3055 if (user)
3006 return -EOPNOTSUPP; 3056 return -EOPNOTSUPP;
3007 if (nic_data->rx_rss_context != EFX_EF10_RSS_CONTEXT_INVALID) 3057 if (efx->rss_context.context_id != EFX_EF10_RSS_CONTEXT_INVALID)
3008 return 0; 3058 return 0;
3009 return efx_ef10_rx_push_shared_rss_config(efx, NULL); 3059 return efx_ef10_rx_push_shared_rss_config(efx, NULL);
3010} 3060}
@@ -4109,6 +4159,7 @@ efx_ef10_filter_push_prep_set_match_fields(struct efx_nic *efx,
4109static void efx_ef10_filter_push_prep(struct efx_nic *efx, 4159static void efx_ef10_filter_push_prep(struct efx_nic *efx,
4110 const struct efx_filter_spec *spec, 4160 const struct efx_filter_spec *spec,
4111 efx_dword_t *inbuf, u64 handle, 4161 efx_dword_t *inbuf, u64 handle,
4162 struct efx_rss_context *ctx,
4112 bool replacing) 4163 bool replacing)
4113{ 4164{
4114 struct efx_ef10_nic_data *nic_data = efx->nic_data; 4165 struct efx_ef10_nic_data *nic_data = efx->nic_data;
@@ -4116,11 +4167,16 @@ static void efx_ef10_filter_push_prep(struct efx_nic *efx,
4116 4167
4117 memset(inbuf, 0, MC_CMD_FILTER_OP_EXT_IN_LEN); 4168 memset(inbuf, 0, MC_CMD_FILTER_OP_EXT_IN_LEN);
4118 4169
4119 /* Remove RSS flag if we don't have an RSS context. */ 4170 /* If RSS filter, caller better have given us an RSS context */
4120 if (flags & EFX_FILTER_FLAG_RX_RSS && 4171 if (flags & EFX_FILTER_FLAG_RX_RSS) {
4121 spec->rss_context == EFX_FILTER_RSS_CONTEXT_DEFAULT && 4172 /* We don't have the ability to return an error, so we'll just
4122 nic_data->rx_rss_context == EFX_EF10_RSS_CONTEXT_INVALID) 4173 * log a warning and disable RSS for the filter.
4123 flags &= ~EFX_FILTER_FLAG_RX_RSS; 4174 */
4175 if (WARN_ON_ONCE(!ctx))
4176 flags &= ~EFX_FILTER_FLAG_RX_RSS;
4177 else if (WARN_ON_ONCE(ctx->context_id == EFX_EF10_RSS_CONTEXT_INVALID))
4178 flags &= ~EFX_FILTER_FLAG_RX_RSS;
4179 }
4124 4180
4125 if (replacing) { 4181 if (replacing) {
4126 MCDI_SET_DWORD(inbuf, FILTER_OP_IN_OP, 4182 MCDI_SET_DWORD(inbuf, FILTER_OP_IN_OP,
@@ -4146,21 +4202,18 @@ static void efx_ef10_filter_push_prep(struct efx_nic *efx,
4146 MC_CMD_FILTER_OP_IN_RX_MODE_RSS : 4202 MC_CMD_FILTER_OP_IN_RX_MODE_RSS :
4147 MC_CMD_FILTER_OP_IN_RX_MODE_SIMPLE); 4203 MC_CMD_FILTER_OP_IN_RX_MODE_SIMPLE);
4148 if (flags & EFX_FILTER_FLAG_RX_RSS) 4204 if (flags & EFX_FILTER_FLAG_RX_RSS)
4149 MCDI_SET_DWORD(inbuf, FILTER_OP_IN_RX_CONTEXT, 4205 MCDI_SET_DWORD(inbuf, FILTER_OP_IN_RX_CONTEXT, ctx->context_id);
4150 spec->rss_context !=
4151 EFX_FILTER_RSS_CONTEXT_DEFAULT ?
4152 spec->rss_context : nic_data->rx_rss_context);
4153} 4206}
4154 4207
4155static int efx_ef10_filter_push(struct efx_nic *efx, 4208static int efx_ef10_filter_push(struct efx_nic *efx,
4156 const struct efx_filter_spec *spec, 4209 const struct efx_filter_spec *spec, u64 *handle,
4157 u64 *handle, bool replacing) 4210 struct efx_rss_context *ctx, bool replacing)
4158{ 4211{
4159 MCDI_DECLARE_BUF(inbuf, MC_CMD_FILTER_OP_EXT_IN_LEN); 4212 MCDI_DECLARE_BUF(inbuf, MC_CMD_FILTER_OP_EXT_IN_LEN);
4160 MCDI_DECLARE_BUF(outbuf, MC_CMD_FILTER_OP_EXT_OUT_LEN); 4213 MCDI_DECLARE_BUF(outbuf, MC_CMD_FILTER_OP_EXT_OUT_LEN);
4161 int rc; 4214 int rc;
4162 4215
4163 efx_ef10_filter_push_prep(efx, spec, inbuf, *handle, replacing); 4216 efx_ef10_filter_push_prep(efx, spec, inbuf, *handle, ctx, replacing);
4164 rc = efx_mcdi_rpc(efx, MC_CMD_FILTER_OP, inbuf, sizeof(inbuf), 4217 rc = efx_mcdi_rpc(efx, MC_CMD_FILTER_OP, inbuf, sizeof(inbuf),
4165 outbuf, sizeof(outbuf), NULL); 4218 outbuf, sizeof(outbuf), NULL);
4166 if (rc == 0) 4219 if (rc == 0)
@@ -4252,6 +4305,7 @@ static s32 efx_ef10_filter_insert(struct efx_nic *efx,
4252 struct efx_ef10_filter_table *table = efx->filter_state; 4305 struct efx_ef10_filter_table *table = efx->filter_state;
4253 DECLARE_BITMAP(mc_rem_map, EFX_EF10_FILTER_SEARCH_LIMIT); 4306 DECLARE_BITMAP(mc_rem_map, EFX_EF10_FILTER_SEARCH_LIMIT);
4254 struct efx_filter_spec *saved_spec; 4307 struct efx_filter_spec *saved_spec;
4308 struct efx_rss_context *ctx = NULL;
4255 unsigned int match_pri, hash; 4309 unsigned int match_pri, hash;
4256 unsigned int priv_flags; 4310 unsigned int priv_flags;
4257 bool replacing = false; 4311 bool replacing = false;
@@ -4275,6 +4329,18 @@ static s32 efx_ef10_filter_insert(struct efx_nic *efx,
4275 if (is_mc_recip) 4329 if (is_mc_recip)
4276 bitmap_zero(mc_rem_map, EFX_EF10_FILTER_SEARCH_LIMIT); 4330 bitmap_zero(mc_rem_map, EFX_EF10_FILTER_SEARCH_LIMIT);
4277 4331
4332 if (spec->flags & EFX_FILTER_FLAG_RX_RSS) {
4333 if (spec->rss_context)
4334 ctx = efx_find_rss_context_entry(spec->rss_context,
4335 &efx->rss_context.list);
4336 else
4337 ctx = &efx->rss_context;
4338 if (!ctx)
4339 return -ENOENT;
4340 if (ctx->context_id == EFX_EF10_RSS_CONTEXT_INVALID)
4341 return -EOPNOTSUPP;
4342 }
4343
4278 /* Find any existing filters with the same match tuple or 4344 /* Find any existing filters with the same match tuple or
4279 * else a free slot to insert at. If any of them are busy, 4345 * else a free slot to insert at. If any of them are busy,
4280 * we have to wait and retry. 4346 * we have to wait and retry.
@@ -4390,7 +4456,7 @@ found:
4390 spin_unlock_bh(&efx->filter_lock); 4456 spin_unlock_bh(&efx->filter_lock);
4391 4457
4392 rc = efx_ef10_filter_push(efx, spec, &table->entry[ins_index].handle, 4458 rc = efx_ef10_filter_push(efx, spec, &table->entry[ins_index].handle,
4393 replacing); 4459 ctx, replacing);
4394 4460
4395 /* Finalise the software table entry */ 4461 /* Finalise the software table entry */
4396 spin_lock_bh(&efx->filter_lock); 4462 spin_lock_bh(&efx->filter_lock);
@@ -4534,12 +4600,13 @@ static int efx_ef10_filter_remove_internal(struct efx_nic *efx,
4534 4600
4535 new_spec.priority = EFX_FILTER_PRI_AUTO; 4601 new_spec.priority = EFX_FILTER_PRI_AUTO;
4536 new_spec.flags = (EFX_FILTER_FLAG_RX | 4602 new_spec.flags = (EFX_FILTER_FLAG_RX |
4537 (efx_rss_enabled(efx) ? 4603 (efx_rss_active(&efx->rss_context) ?
4538 EFX_FILTER_FLAG_RX_RSS : 0)); 4604 EFX_FILTER_FLAG_RX_RSS : 0));
4539 new_spec.dmaq_id = 0; 4605 new_spec.dmaq_id = 0;
4540 new_spec.rss_context = EFX_FILTER_RSS_CONTEXT_DEFAULT; 4606 new_spec.rss_context = 0;
4541 rc = efx_ef10_filter_push(efx, &new_spec, 4607 rc = efx_ef10_filter_push(efx, &new_spec,
4542 &table->entry[filter_idx].handle, 4608 &table->entry[filter_idx].handle,
4609 &efx->rss_context,
4543 true); 4610 true);
4544 4611
4545 spin_lock_bh(&efx->filter_lock); 4612 spin_lock_bh(&efx->filter_lock);
@@ -4783,7 +4850,8 @@ static s32 efx_ef10_filter_rfs_insert(struct efx_nic *efx,
4783 cookie = replacing << 31 | ins_index << 16 | spec->dmaq_id; 4850 cookie = replacing << 31 | ins_index << 16 | spec->dmaq_id;
4784 4851
4785 efx_ef10_filter_push_prep(efx, spec, inbuf, 4852 efx_ef10_filter_push_prep(efx, spec, inbuf,
4786 table->entry[ins_index].handle, replacing); 4853 table->entry[ins_index].handle, NULL,
4854 replacing);
4787 efx_mcdi_rpc_async(efx, MC_CMD_FILTER_OP, inbuf, sizeof(inbuf), 4855 efx_mcdi_rpc_async(efx, MC_CMD_FILTER_OP, inbuf, sizeof(inbuf),
4788 MC_CMD_FILTER_OP_OUT_LEN, 4856 MC_CMD_FILTER_OP_OUT_LEN,
4789 efx_ef10_filter_rfs_insert_complete, cookie); 4857 efx_ef10_filter_rfs_insert_complete, cookie);
@@ -5104,6 +5172,7 @@ static void efx_ef10_filter_table_restore(struct efx_nic *efx)
5104 unsigned int invalid_filters = 0, failed = 0; 5172 unsigned int invalid_filters = 0, failed = 0;
5105 struct efx_ef10_filter_vlan *vlan; 5173 struct efx_ef10_filter_vlan *vlan;
5106 struct efx_filter_spec *spec; 5174 struct efx_filter_spec *spec;
5175 struct efx_rss_context *ctx;
5107 unsigned int filter_idx; 5176 unsigned int filter_idx;
5108 u32 mcdi_flags; 5177 u32 mcdi_flags;
5109 int match_pri; 5178 int match_pri;
@@ -5133,17 +5202,34 @@ static void efx_ef10_filter_table_restore(struct efx_nic *efx)
5133 invalid_filters++; 5202 invalid_filters++;
5134 goto not_restored; 5203 goto not_restored;
5135 } 5204 }
5136 if (spec->rss_context != EFX_FILTER_RSS_CONTEXT_DEFAULT && 5205 if (spec->rss_context)
5137 spec->rss_context != nic_data->rx_rss_context) 5206 ctx = efx_find_rss_context_entry(spec->rss_context,
5138 netif_warn(efx, drv, efx->net_dev, 5207 &efx->rss_context.list);
5139 "Warning: unable to restore a filter with specific RSS context.\n"); 5208 else
5209 ctx = &efx->rss_context;
5210 if (spec->flags & EFX_FILTER_FLAG_RX_RSS) {
5211 if (!ctx) {
5212 netif_warn(efx, drv, efx->net_dev,
5213 "Warning: unable to restore a filter with nonexistent RSS context %u.\n",
5214 spec->rss_context);
5215 invalid_filters++;
5216 goto not_restored;
5217 }
5218 if (ctx->context_id == EFX_EF10_RSS_CONTEXT_INVALID) {
5219 netif_warn(efx, drv, efx->net_dev,
5220 "Warning: unable to restore a filter with RSS context %u as it was not created.\n",
5221 spec->rss_context);
5222 invalid_filters++;
5223 goto not_restored;
5224 }
5225 }
5140 5226
5141 table->entry[filter_idx].spec |= EFX_EF10_FILTER_FLAG_BUSY; 5227 table->entry[filter_idx].spec |= EFX_EF10_FILTER_FLAG_BUSY;
5142 spin_unlock_bh(&efx->filter_lock); 5228 spin_unlock_bh(&efx->filter_lock);
5143 5229
5144 rc = efx_ef10_filter_push(efx, spec, 5230 rc = efx_ef10_filter_push(efx, spec,
5145 &table->entry[filter_idx].handle, 5231 &table->entry[filter_idx].handle,
5146 false); 5232 ctx, false);
5147 if (rc) 5233 if (rc)
5148 failed++; 5234 failed++;
5149 spin_lock_bh(&efx->filter_lock); 5235 spin_lock_bh(&efx->filter_lock);
@@ -6784,6 +6870,9 @@ const struct efx_nic_type efx_hunt_a0_nic_type = {
6784 .tx_limit_len = efx_ef10_tx_limit_len, 6870 .tx_limit_len = efx_ef10_tx_limit_len,
6785 .rx_push_rss_config = efx_ef10_pf_rx_push_rss_config, 6871 .rx_push_rss_config = efx_ef10_pf_rx_push_rss_config,
6786 .rx_pull_rss_config = efx_ef10_rx_pull_rss_config, 6872 .rx_pull_rss_config = efx_ef10_rx_pull_rss_config,
6873 .rx_push_rss_context_config = efx_ef10_rx_push_rss_context_config,
6874 .rx_pull_rss_context_config = efx_ef10_rx_pull_rss_context_config,
6875 .rx_restore_rss_contexts = efx_ef10_rx_restore_rss_contexts,
6787 .rx_probe = efx_ef10_rx_probe, 6876 .rx_probe = efx_ef10_rx_probe,
6788 .rx_init = efx_ef10_rx_init, 6877 .rx_init = efx_ef10_rx_init,
6789 .rx_remove = efx_ef10_rx_remove, 6878 .rx_remove = efx_ef10_rx_remove,
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 16757cfc5b29..7321a4cf6f4d 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -1353,12 +1353,13 @@ static void efx_fini_io(struct efx_nic *efx)
1353 pci_disable_device(efx->pci_dev); 1353 pci_disable_device(efx->pci_dev);
1354} 1354}
1355 1355
1356void efx_set_default_rx_indir_table(struct efx_nic *efx) 1356void efx_set_default_rx_indir_table(struct efx_nic *efx,
1357 struct efx_rss_context *ctx)
1357{ 1358{
1358 size_t i; 1359 size_t i;
1359 1360
1360 for (i = 0; i < ARRAY_SIZE(efx->rx_indir_table); i++) 1361 for (i = 0; i < ARRAY_SIZE(ctx->rx_indir_table); i++)
1361 efx->rx_indir_table[i] = 1362 ctx->rx_indir_table[i] =
1362 ethtool_rxfh_indir_default(i, efx->rss_spread); 1363 ethtool_rxfh_indir_default(i, efx->rss_spread);
1363} 1364}
1364 1365
@@ -1739,9 +1740,9 @@ static int efx_probe_nic(struct efx_nic *efx)
1739 } while (rc == -EAGAIN); 1740 } while (rc == -EAGAIN);
1740 1741
1741 if (efx->n_channels > 1) 1742 if (efx->n_channels > 1)
1742 netdev_rss_key_fill(&efx->rx_hash_key, 1743 netdev_rss_key_fill(efx->rss_context.rx_hash_key,
1743 sizeof(efx->rx_hash_key)); 1744 sizeof(efx->rss_context.rx_hash_key));
1744 efx_set_default_rx_indir_table(efx); 1745 efx_set_default_rx_indir_table(efx, &efx->rss_context);
1745 1746
1746 netif_set_real_num_tx_queues(efx->net_dev, efx->n_tx_channels); 1747 netif_set_real_num_tx_queues(efx->net_dev, efx->n_tx_channels);
1747 netif_set_real_num_rx_queues(efx->net_dev, efx->n_rx_channels); 1748 netif_set_real_num_rx_queues(efx->net_dev, efx->n_rx_channels);
@@ -2700,6 +2701,8 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok)
2700 " VFs may not function\n", rc); 2701 " VFs may not function\n", rc);
2701#endif 2702#endif
2702 2703
2704 if (efx->type->rx_restore_rss_contexts)
2705 efx->type->rx_restore_rss_contexts(efx);
2703 down_read(&efx->filter_sem); 2706 down_read(&efx->filter_sem);
2704 efx_restore_filters(efx); 2707 efx_restore_filters(efx);
2705 up_read(&efx->filter_sem); 2708 up_read(&efx->filter_sem);
@@ -3003,6 +3006,7 @@ static int efx_init_struct(struct efx_nic *efx,
3003 efx->type->rx_hash_offset - efx->type->rx_prefix_size; 3006 efx->type->rx_hash_offset - efx->type->rx_prefix_size;
3004 efx->rx_packet_ts_offset = 3007 efx->rx_packet_ts_offset =
3005 efx->type->rx_ts_offset - efx->type->rx_prefix_size; 3008 efx->type->rx_ts_offset - efx->type->rx_prefix_size;
3009 INIT_LIST_HEAD(&efx->rss_context.list);
3006 spin_lock_init(&efx->stats_lock); 3010 spin_lock_init(&efx->stats_lock);
3007 efx->vi_stride = EFX_DEFAULT_VI_STRIDE; 3011 efx->vi_stride = EFX_DEFAULT_VI_STRIDE;
3008 efx->num_mac_stats = MC_CMD_MAC_NSTATS; 3012 efx->num_mac_stats = MC_CMD_MAC_NSTATS;
@@ -3072,6 +3076,55 @@ void efx_update_sw_stats(struct efx_nic *efx, u64 *stats)
3072 stats[GENERIC_STAT_rx_noskb_drops] = atomic_read(&efx->n_rx_noskb_drops); 3076 stats[GENERIC_STAT_rx_noskb_drops] = atomic_read(&efx->n_rx_noskb_drops);
3073} 3077}
3074 3078
3079/* RSS contexts. We're using linked lists and crappy O(n) algorithms, because
3080 * (a) this is an infrequent control-plane operation and (b) n is small (max 64)
3081 */
3082struct efx_rss_context *efx_alloc_rss_context_entry(struct list_head *head)
3083{
3084 struct efx_rss_context *ctx, *new;
3085 u32 id = 1; /* Don't use zero, that refers to the master RSS context */
3086
3087 /* Search for first gap in the numbering */
3088 list_for_each_entry(ctx, head, list) {
3089 if (ctx->user_id != id)
3090 break;
3091 id++;
3092 /* Check for wrap. If this happens, we have nearly 2^32
3093 * allocated RSS contexts, which seems unlikely.
3094 */
3095 if (WARN_ON_ONCE(!id))
3096 return NULL;
3097 }
3098
3099 /* Create the new entry */
3100 new = kmalloc(sizeof(struct efx_rss_context), GFP_KERNEL);
3101 if (!new)
3102 return NULL;
3103 new->context_id = EFX_EF10_RSS_CONTEXT_INVALID;
3104 new->rx_hash_udp_4tuple = false;
3105
3106 /* Insert the new entry into the gap */
3107 new->user_id = id;
3108 list_add_tail(&new->list, &ctx->list);
3109 return new;
3110}
3111
3112struct efx_rss_context *efx_find_rss_context_entry(u32 id, struct list_head *head)
3113{
3114 struct efx_rss_context *ctx;
3115
3116 list_for_each_entry(ctx, head, list)
3117 if (ctx->user_id == id)
3118 return ctx;
3119 return NULL;
3120}
3121
3122void efx_free_rss_context_entry(struct efx_rss_context *ctx)
3123{
3124 list_del(&ctx->list);
3125 kfree(ctx);
3126}
3127
3075/************************************************************************** 3128/**************************************************************************
3076 * 3129 *
3077 * PCI interface 3130 * PCI interface
diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h
index 0cddc5ad77b1..3429ae3f3b08 100644
--- a/drivers/net/ethernet/sfc/efx.h
+++ b/drivers/net/ethernet/sfc/efx.h
@@ -34,7 +34,8 @@ extern unsigned int efx_piobuf_size;
34extern bool efx_separate_tx_channels; 34extern bool efx_separate_tx_channels;
35 35
36/* RX */ 36/* RX */
37void efx_set_default_rx_indir_table(struct efx_nic *efx); 37void efx_set_default_rx_indir_table(struct efx_nic *efx,
38 struct efx_rss_context *ctx);
38void efx_rx_config_page_split(struct efx_nic *efx); 39void efx_rx_config_page_split(struct efx_nic *efx);
39int efx_probe_rx_queue(struct efx_rx_queue *rx_queue); 40int efx_probe_rx_queue(struct efx_rx_queue *rx_queue);
40void efx_remove_rx_queue(struct efx_rx_queue *rx_queue); 41void efx_remove_rx_queue(struct efx_rx_queue *rx_queue);
@@ -182,6 +183,15 @@ static inline void efx_filter_rfs_expire(struct efx_channel *channel) {}
182#endif 183#endif
183bool efx_filter_is_mc_recipient(const struct efx_filter_spec *spec); 184bool efx_filter_is_mc_recipient(const struct efx_filter_spec *spec);
184 185
186/* RSS contexts */
187struct efx_rss_context *efx_alloc_rss_context_entry(struct list_head *list);
188struct efx_rss_context *efx_find_rss_context_entry(u32 id, struct list_head *list);
189void efx_free_rss_context_entry(struct efx_rss_context *ctx);
190static inline bool efx_rss_active(struct efx_rss_context *ctx)
191{
192 return ctx->context_id != EFX_EF10_RSS_CONTEXT_INVALID;
193}
194
185/* Channels */ 195/* Channels */
186int efx_channel_dummy_op_int(struct efx_channel *channel); 196int efx_channel_dummy_op_int(struct efx_channel *channel);
187void efx_channel_dummy_op_void(struct efx_channel *channel); 197void efx_channel_dummy_op_void(struct efx_channel *channel);
diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c
index 4db2dc2bf52f..bb1c80d48d12 100644
--- a/drivers/net/ethernet/sfc/ethtool.c
+++ b/drivers/net/ethernet/sfc/ethtool.c
@@ -808,7 +808,8 @@ static inline void ip6_fill_mask(__be32 *mask)
808} 808}
809 809
810static int efx_ethtool_get_class_rule(struct efx_nic *efx, 810static int efx_ethtool_get_class_rule(struct efx_nic *efx,
811 struct ethtool_rx_flow_spec *rule) 811 struct ethtool_rx_flow_spec *rule,
812 u32 *rss_context)
812{ 813{
813 struct ethtool_tcpip4_spec *ip_entry = &rule->h_u.tcp_ip4_spec; 814 struct ethtool_tcpip4_spec *ip_entry = &rule->h_u.tcp_ip4_spec;
814 struct ethtool_tcpip4_spec *ip_mask = &rule->m_u.tcp_ip4_spec; 815 struct ethtool_tcpip4_spec *ip_mask = &rule->m_u.tcp_ip4_spec;
@@ -964,6 +965,11 @@ static int efx_ethtool_get_class_rule(struct efx_nic *efx,
964 rule->m_ext.vlan_tci = htons(0xfff); 965 rule->m_ext.vlan_tci = htons(0xfff);
965 } 966 }
966 967
968 if (spec.flags & EFX_FILTER_FLAG_RX_RSS) {
969 rule->flow_type |= FLOW_RSS;
970 *rss_context = spec.rss_context;
971 }
972
967 return rc; 973 return rc;
968} 974}
969 975
@@ -972,6 +978,8 @@ efx_ethtool_get_rxnfc(struct net_device *net_dev,
972 struct ethtool_rxnfc *info, u32 *rule_locs) 978 struct ethtool_rxnfc *info, u32 *rule_locs)
973{ 979{
974 struct efx_nic *efx = netdev_priv(net_dev); 980 struct efx_nic *efx = netdev_priv(net_dev);
981 u32 rss_context = 0;
982 s32 rc;
975 983
976 switch (info->cmd) { 984 switch (info->cmd) {
977 case ETHTOOL_GRXRINGS: 985 case ETHTOOL_GRXRINGS:
@@ -979,12 +987,20 @@ efx_ethtool_get_rxnfc(struct net_device *net_dev,
979 return 0; 987 return 0;
980 988
981 case ETHTOOL_GRXFH: { 989 case ETHTOOL_GRXFH: {
990 struct efx_rss_context *ctx = &efx->rss_context;
991
992 if (info->flow_type & FLOW_RSS && info->rss_context) {
993 ctx = efx_find_rss_context_entry(info->rss_context,
994 &efx->rss_context.list);
995 if (!ctx)
996 return -ENOENT;
997 }
982 info->data = 0; 998 info->data = 0;
983 if (!efx->rss_active) /* No RSS */ 999 if (!efx_rss_active(ctx)) /* No RSS */
984 return 0; 1000 return 0;
985 switch (info->flow_type) { 1001 switch (info->flow_type & ~FLOW_RSS) {
986 case UDP_V4_FLOW: 1002 case UDP_V4_FLOW:
987 if (efx->rx_hash_udp_4tuple) 1003 if (ctx->rx_hash_udp_4tuple)
988 /* fall through */ 1004 /* fall through */
989 case TCP_V4_FLOW: 1005 case TCP_V4_FLOW:
990 info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; 1006 info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
@@ -995,7 +1011,7 @@ efx_ethtool_get_rxnfc(struct net_device *net_dev,
995 info->data |= RXH_IP_SRC | RXH_IP_DST; 1011 info->data |= RXH_IP_SRC | RXH_IP_DST;
996 break; 1012 break;
997 case UDP_V6_FLOW: 1013 case UDP_V6_FLOW:
998 if (efx->rx_hash_udp_4tuple) 1014 if (ctx->rx_hash_udp_4tuple)
999 /* fall through */ 1015 /* fall through */
1000 case TCP_V6_FLOW: 1016 case TCP_V6_FLOW:
1001 info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; 1017 info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
@@ -1023,10 +1039,14 @@ efx_ethtool_get_rxnfc(struct net_device *net_dev,
1023 case ETHTOOL_GRXCLSRULE: 1039 case ETHTOOL_GRXCLSRULE:
1024 if (efx_filter_get_rx_id_limit(efx) == 0) 1040 if (efx_filter_get_rx_id_limit(efx) == 0)
1025 return -EOPNOTSUPP; 1041 return -EOPNOTSUPP;
1026 return efx_ethtool_get_class_rule(efx, &info->fs); 1042 rc = efx_ethtool_get_class_rule(efx, &info->fs, &rss_context);
1043 if (rc < 0)
1044 return rc;
1045 if (info->fs.flow_type & FLOW_RSS)
1046 info->rss_context = rss_context;
1047 return 0;
1027 1048
1028 case ETHTOOL_GRXCLSRLALL: { 1049 case ETHTOOL_GRXCLSRLALL:
1029 s32 rc;
1030 info->data = efx_filter_get_rx_id_limit(efx); 1050 info->data = efx_filter_get_rx_id_limit(efx);
1031 if (info->data == 0) 1051 if (info->data == 0)
1032 return -EOPNOTSUPP; 1052 return -EOPNOTSUPP;
@@ -1036,7 +1056,6 @@ efx_ethtool_get_rxnfc(struct net_device *net_dev,
1036 return rc; 1056 return rc;
1037 info->rule_cnt = rc; 1057 info->rule_cnt = rc;
1038 return 0; 1058 return 0;
1039 }
1040 1059
1041 default: 1060 default:
1042 return -EOPNOTSUPP; 1061 return -EOPNOTSUPP;
@@ -1054,7 +1073,8 @@ static inline bool ip6_mask_is_empty(__be32 mask[4])
1054} 1073}
1055 1074
1056static int efx_ethtool_set_class_rule(struct efx_nic *efx, 1075static int efx_ethtool_set_class_rule(struct efx_nic *efx,
1057 struct ethtool_rx_flow_spec *rule) 1076 struct ethtool_rx_flow_spec *rule,
1077 u32 rss_context)
1058{ 1078{
1059 struct ethtool_tcpip4_spec *ip_entry = &rule->h_u.tcp_ip4_spec; 1079 struct ethtool_tcpip4_spec *ip_entry = &rule->h_u.tcp_ip4_spec;
1060 struct ethtool_tcpip4_spec *ip_mask = &rule->m_u.tcp_ip4_spec; 1080 struct ethtool_tcpip4_spec *ip_mask = &rule->m_u.tcp_ip4_spec;
@@ -1066,6 +1086,7 @@ static int efx_ethtool_set_class_rule(struct efx_nic *efx,
1066 struct ethtool_usrip6_spec *uip6_mask = &rule->m_u.usr_ip6_spec; 1086 struct ethtool_usrip6_spec *uip6_mask = &rule->m_u.usr_ip6_spec;
1067 struct ethhdr *mac_entry = &rule->h_u.ether_spec; 1087 struct ethhdr *mac_entry = &rule->h_u.ether_spec;
1068 struct ethhdr *mac_mask = &rule->m_u.ether_spec; 1088 struct ethhdr *mac_mask = &rule->m_u.ether_spec;
1089 enum efx_filter_flags flags = 0;
1069 struct efx_filter_spec spec; 1090 struct efx_filter_spec spec;
1070 int rc; 1091 int rc;
1071 1092
@@ -1084,12 +1105,19 @@ static int efx_ethtool_set_class_rule(struct efx_nic *efx,
1084 rule->m_ext.data[1])) 1105 rule->m_ext.data[1]))
1085 return -EINVAL; 1106 return -EINVAL;
1086 1107
1087 efx_filter_init_rx(&spec, EFX_FILTER_PRI_MANUAL, 1108 if (efx->rx_scatter)
1088 efx->rx_scatter ? EFX_FILTER_FLAG_RX_SCATTER : 0, 1109 flags |= EFX_FILTER_FLAG_RX_SCATTER;
1110 if (rule->flow_type & FLOW_RSS)
1111 flags |= EFX_FILTER_FLAG_RX_RSS;
1112
1113 efx_filter_init_rx(&spec, EFX_FILTER_PRI_MANUAL, flags,
1089 (rule->ring_cookie == RX_CLS_FLOW_DISC) ? 1114 (rule->ring_cookie == RX_CLS_FLOW_DISC) ?
1090 EFX_FILTER_RX_DMAQ_ID_DROP : rule->ring_cookie); 1115 EFX_FILTER_RX_DMAQ_ID_DROP : rule->ring_cookie);
1091 1116
1092 switch (rule->flow_type & ~FLOW_EXT) { 1117 if (rule->flow_type & FLOW_RSS)
1118 spec.rss_context = rss_context;
1119
1120 switch (rule->flow_type & ~(FLOW_EXT | FLOW_RSS)) {
1093 case TCP_V4_FLOW: 1121 case TCP_V4_FLOW:
1094 case UDP_V4_FLOW: 1122 case UDP_V4_FLOW:
1095 spec.match_flags = (EFX_FILTER_MATCH_ETHER_TYPE | 1123 spec.match_flags = (EFX_FILTER_MATCH_ETHER_TYPE |
@@ -1265,7 +1293,8 @@ static int efx_ethtool_set_rxnfc(struct net_device *net_dev,
1265 1293
1266 switch (info->cmd) { 1294 switch (info->cmd) {
1267 case ETHTOOL_SRXCLSRLINS: 1295 case ETHTOOL_SRXCLSRLINS:
1268 return efx_ethtool_set_class_rule(efx, &info->fs); 1296 return efx_ethtool_set_class_rule(efx, &info->fs,
1297 info->rss_context);
1269 1298
1270 case ETHTOOL_SRXCLSRLDEL: 1299 case ETHTOOL_SRXCLSRLDEL:
1271 return efx_filter_remove_id_safe(efx, EFX_FILTER_PRI_MANUAL, 1300 return efx_filter_remove_id_safe(efx, EFX_FILTER_PRI_MANUAL,
@@ -1280,7 +1309,9 @@ static u32 efx_ethtool_get_rxfh_indir_size(struct net_device *net_dev)
1280{ 1309{
1281 struct efx_nic *efx = netdev_priv(net_dev); 1310 struct efx_nic *efx = netdev_priv(net_dev);
1282 1311
1283 return (efx->n_rx_channels == 1) ? 0 : ARRAY_SIZE(efx->rx_indir_table); 1312 if (efx->n_rx_channels == 1)
1313 return 0;
1314 return ARRAY_SIZE(efx->rss_context.rx_indir_table);
1284} 1315}
1285 1316
1286static u32 efx_ethtool_get_rxfh_key_size(struct net_device *net_dev) 1317static u32 efx_ethtool_get_rxfh_key_size(struct net_device *net_dev)
@@ -1303,9 +1334,11 @@ static int efx_ethtool_get_rxfh(struct net_device *net_dev, u32 *indir, u8 *key,
1303 if (hfunc) 1334 if (hfunc)
1304 *hfunc = ETH_RSS_HASH_TOP; 1335 *hfunc = ETH_RSS_HASH_TOP;
1305 if (indir) 1336 if (indir)
1306 memcpy(indir, efx->rx_indir_table, sizeof(efx->rx_indir_table)); 1337 memcpy(indir, efx->rss_context.rx_indir_table,
1338 sizeof(efx->rss_context.rx_indir_table));
1307 if (key) 1339 if (key)
1308 memcpy(key, efx->rx_hash_key, efx->type->rx_hash_key_size); 1340 memcpy(key, efx->rss_context.rx_hash_key,
1341 efx->type->rx_hash_key_size);
1309 return 0; 1342 return 0;
1310} 1343}
1311 1344
@@ -1321,13 +1354,93 @@ static int efx_ethtool_set_rxfh(struct net_device *net_dev, const u32 *indir,
1321 return 0; 1354 return 0;
1322 1355
1323 if (!key) 1356 if (!key)
1324 key = efx->rx_hash_key; 1357 key = efx->rss_context.rx_hash_key;
1325 if (!indir) 1358 if (!indir)
1326 indir = efx->rx_indir_table; 1359 indir = efx->rss_context.rx_indir_table;
1327 1360
1328 return efx->type->rx_push_rss_config(efx, true, indir, key); 1361 return efx->type->rx_push_rss_config(efx, true, indir, key);
1329} 1362}
1330 1363
1364static int efx_ethtool_get_rxfh_context(struct net_device *net_dev, u32 *indir,
1365 u8 *key, u8 *hfunc, u32 rss_context)
1366{
1367 struct efx_nic *efx = netdev_priv(net_dev);
1368 struct efx_rss_context *ctx;
1369 int rc;
1370
1371 if (!efx->type->rx_pull_rss_context_config)
1372 return -EOPNOTSUPP;
1373 ctx = efx_find_rss_context_entry(rss_context, &efx->rss_context.list);
1374 if (!ctx)
1375 return -ENOENT;
1376 rc = efx->type->rx_pull_rss_context_config(efx, ctx);
1377 if (rc)
1378 return rc;
1379
1380 if (hfunc)
1381 *hfunc = ETH_RSS_HASH_TOP;
1382 if (indir)
1383 memcpy(indir, ctx->rx_indir_table, sizeof(ctx->rx_indir_table));
1384 if (key)
1385 memcpy(key, ctx->rx_hash_key, efx->type->rx_hash_key_size);
1386 return 0;
1387}
1388
1389static int efx_ethtool_set_rxfh_context(struct net_device *net_dev,
1390 const u32 *indir, const u8 *key,
1391 const u8 hfunc, u32 *rss_context,
1392 bool delete)
1393{
1394 struct efx_nic *efx = netdev_priv(net_dev);
1395 struct efx_rss_context *ctx;
1396 bool allocated = false;
1397 int rc;
1398
1399 if (!efx->type->rx_push_rss_context_config)
1400 return -EOPNOTSUPP;
1401 /* Hash function is Toeplitz, cannot be changed */
1402 if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
1403 return -EOPNOTSUPP;
1404 if (*rss_context == ETH_RXFH_CONTEXT_ALLOC) {
1405 if (delete)
1406 /* alloc + delete == Nothing to do */
1407 return -EINVAL;
1408 ctx = efx_alloc_rss_context_entry(&efx->rss_context.list);
1409 if (!ctx)
1410 return -ENOMEM;
1411 ctx->context_id = EFX_EF10_RSS_CONTEXT_INVALID;
1412 /* Initialise indir table and key to defaults */
1413 efx_set_default_rx_indir_table(efx, ctx);
1414 netdev_rss_key_fill(ctx->rx_hash_key, sizeof(ctx->rx_hash_key));
1415 allocated = true;
1416 } else {
1417 ctx = efx_find_rss_context_entry(*rss_context,
1418 &efx->rss_context.list);
1419 if (!ctx)
1420 return -ENOENT;
1421 }
1422
1423 if (delete) {
1424 /* delete this context */
1425 rc = efx->type->rx_push_rss_context_config(efx, ctx, NULL, NULL);
1426 if (!rc)
1427 efx_free_rss_context_entry(ctx);
1428 return rc;
1429 }
1430
1431 if (!key)
1432 key = ctx->rx_hash_key;
1433 if (!indir)
1434 indir = ctx->rx_indir_table;
1435
1436 rc = efx->type->rx_push_rss_context_config(efx, ctx, indir, key);
1437 if (rc && allocated)
1438 efx_free_rss_context_entry(ctx);
1439 else
1440 *rss_context = ctx->user_id;
1441 return rc;
1442}
1443
1331static int efx_ethtool_get_ts_info(struct net_device *net_dev, 1444static int efx_ethtool_get_ts_info(struct net_device *net_dev,
1332 struct ethtool_ts_info *ts_info) 1445 struct ethtool_ts_info *ts_info)
1333{ 1446{
@@ -1375,6 +1488,36 @@ static int efx_ethtool_get_module_info(struct net_device *net_dev,
1375 return ret; 1488 return ret;
1376} 1489}
1377 1490
1491static int efx_ethtool_get_fecparam(struct net_device *net_dev,
1492 struct ethtool_fecparam *fecparam)
1493{
1494 struct efx_nic *efx = netdev_priv(net_dev);
1495 int rc;
1496
1497 if (!efx->phy_op || !efx->phy_op->get_fecparam)
1498 return -EOPNOTSUPP;
1499 mutex_lock(&efx->mac_lock);
1500 rc = efx->phy_op->get_fecparam(efx, fecparam);
1501 mutex_unlock(&efx->mac_lock);
1502
1503 return rc;
1504}
1505
1506static int efx_ethtool_set_fecparam(struct net_device *net_dev,
1507 struct ethtool_fecparam *fecparam)
1508{
1509 struct efx_nic *efx = netdev_priv(net_dev);
1510 int rc;
1511
1512 if (!efx->phy_op || !efx->phy_op->get_fecparam)
1513 return -EOPNOTSUPP;
1514 mutex_lock(&efx->mac_lock);
1515 rc = efx->phy_op->set_fecparam(efx, fecparam);
1516 mutex_unlock(&efx->mac_lock);
1517
1518 return rc;
1519}
1520
1378const struct ethtool_ops efx_ethtool_ops = { 1521const struct ethtool_ops efx_ethtool_ops = {
1379 .get_drvinfo = efx_ethtool_get_drvinfo, 1522 .get_drvinfo = efx_ethtool_get_drvinfo,
1380 .get_regs_len = efx_ethtool_get_regs_len, 1523 .get_regs_len = efx_ethtool_get_regs_len,
@@ -1403,9 +1546,13 @@ const struct ethtool_ops efx_ethtool_ops = {
1403 .get_rxfh_key_size = efx_ethtool_get_rxfh_key_size, 1546 .get_rxfh_key_size = efx_ethtool_get_rxfh_key_size,
1404 .get_rxfh = efx_ethtool_get_rxfh, 1547 .get_rxfh = efx_ethtool_get_rxfh,
1405 .set_rxfh = efx_ethtool_set_rxfh, 1548 .set_rxfh = efx_ethtool_set_rxfh,
1549 .get_rxfh_context = efx_ethtool_get_rxfh_context,
1550 .set_rxfh_context = efx_ethtool_set_rxfh_context,
1406 .get_ts_info = efx_ethtool_get_ts_info, 1551 .get_ts_info = efx_ethtool_get_ts_info,
1407 .get_module_info = efx_ethtool_get_module_info, 1552 .get_module_info = efx_ethtool_get_module_info,
1408 .get_module_eeprom = efx_ethtool_get_module_eeprom, 1553 .get_module_eeprom = efx_ethtool_get_module_eeprom,
1409 .get_link_ksettings = efx_ethtool_get_link_ksettings, 1554 .get_link_ksettings = efx_ethtool_get_link_ksettings,
1410 .set_link_ksettings = efx_ethtool_set_link_ksettings, 1555 .set_link_ksettings = efx_ethtool_set_link_ksettings,
1556 .get_fecparam = efx_ethtool_get_fecparam,
1557 .set_fecparam = efx_ethtool_set_fecparam,
1411}; 1558};
diff --git a/drivers/net/ethernet/sfc/falcon/enum.h b/drivers/net/ethernet/sfc/falcon/enum.h
index 30a1136fc909..4824fcf5c3d4 100644
--- a/drivers/net/ethernet/sfc/falcon/enum.h
+++ b/drivers/net/ethernet/sfc/falcon/enum.h
@@ -81,7 +81,6 @@ enum ef4_loopback_mode {
81 (1 << LOOPBACK_XAUI) | \ 81 (1 << LOOPBACK_XAUI) | \
82 (1 << LOOPBACK_GMII) | \ 82 (1 << LOOPBACK_GMII) | \
83 (1 << LOOPBACK_SGMII) | \ 83 (1 << LOOPBACK_SGMII) | \
84 (1 << LOOPBACK_SGMII) | \
85 (1 << LOOPBACK_XGBR) | \ 84 (1 << LOOPBACK_XGBR) | \
86 (1 << LOOPBACK_XFI) | \ 85 (1 << LOOPBACK_XFI) | \
87 (1 << LOOPBACK_XAUI_FAR) | \ 86 (1 << LOOPBACK_XAUI_FAR) | \
diff --git a/drivers/net/ethernet/sfc/farch.c b/drivers/net/ethernet/sfc/farch.c
index 266b9bee1f3a..ad001e77d554 100644
--- a/drivers/net/ethernet/sfc/farch.c
+++ b/drivers/net/ethernet/sfc/farch.c
@@ -1630,12 +1630,12 @@ void efx_farch_rx_push_indir_table(struct efx_nic *efx)
1630 size_t i = 0; 1630 size_t i = 0;
1631 efx_dword_t dword; 1631 efx_dword_t dword;
1632 1632
1633 BUILD_BUG_ON(ARRAY_SIZE(efx->rx_indir_table) != 1633 BUILD_BUG_ON(ARRAY_SIZE(efx->rss_context.rx_indir_table) !=
1634 FR_BZ_RX_INDIRECTION_TBL_ROWS); 1634 FR_BZ_RX_INDIRECTION_TBL_ROWS);
1635 1635
1636 for (i = 0; i < FR_BZ_RX_INDIRECTION_TBL_ROWS; i++) { 1636 for (i = 0; i < FR_BZ_RX_INDIRECTION_TBL_ROWS; i++) {
1637 EFX_POPULATE_DWORD_1(dword, FRF_BZ_IT_QUEUE, 1637 EFX_POPULATE_DWORD_1(dword, FRF_BZ_IT_QUEUE,
1638 efx->rx_indir_table[i]); 1638 efx->rss_context.rx_indir_table[i]);
1639 efx_writed(efx, &dword, 1639 efx_writed(efx, &dword,
1640 FR_BZ_RX_INDIRECTION_TBL + 1640 FR_BZ_RX_INDIRECTION_TBL +
1641 FR_BZ_RX_INDIRECTION_TBL_STEP * i); 1641 FR_BZ_RX_INDIRECTION_TBL_STEP * i);
@@ -1647,14 +1647,14 @@ void efx_farch_rx_pull_indir_table(struct efx_nic *efx)
1647 size_t i = 0; 1647 size_t i = 0;
1648 efx_dword_t dword; 1648 efx_dword_t dword;
1649 1649
1650 BUILD_BUG_ON(ARRAY_SIZE(efx->rx_indir_table) != 1650 BUILD_BUG_ON(ARRAY_SIZE(efx->rss_context.rx_indir_table) !=
1651 FR_BZ_RX_INDIRECTION_TBL_ROWS); 1651 FR_BZ_RX_INDIRECTION_TBL_ROWS);
1652 1652
1653 for (i = 0; i < FR_BZ_RX_INDIRECTION_TBL_ROWS; i++) { 1653 for (i = 0; i < FR_BZ_RX_INDIRECTION_TBL_ROWS; i++) {
1654 efx_readd(efx, &dword, 1654 efx_readd(efx, &dword,
1655 FR_BZ_RX_INDIRECTION_TBL + 1655 FR_BZ_RX_INDIRECTION_TBL +
1656 FR_BZ_RX_INDIRECTION_TBL_STEP * i); 1656 FR_BZ_RX_INDIRECTION_TBL_STEP * i);
1657 efx->rx_indir_table[i] = EFX_DWORD_FIELD(dword, FRF_BZ_IT_QUEUE); 1657 efx->rss_context.rx_indir_table[i] = EFX_DWORD_FIELD(dword, FRF_BZ_IT_QUEUE);
1658 } 1658 }
1659} 1659}
1660 1660
@@ -2032,8 +2032,7 @@ efx_farch_filter_from_gen_spec(struct efx_farch_filter_spec *spec,
2032{ 2032{
2033 bool is_full = false; 2033 bool is_full = false;
2034 2034
2035 if ((gen_spec->flags & EFX_FILTER_FLAG_RX_RSS) && 2035 if ((gen_spec->flags & EFX_FILTER_FLAG_RX_RSS) && gen_spec->rss_context)
2036 gen_spec->rss_context != EFX_FILTER_RSS_CONTEXT_DEFAULT)
2037 return -EINVAL; 2036 return -EINVAL;
2038 2037
2039 spec->priority = gen_spec->priority; 2038 spec->priority = gen_spec->priority;
diff --git a/drivers/net/ethernet/sfc/filter.h b/drivers/net/ethernet/sfc/filter.h
index 8189a1cd973f..59021ad6d98d 100644
--- a/drivers/net/ethernet/sfc/filter.h
+++ b/drivers/net/ethernet/sfc/filter.h
@@ -125,7 +125,9 @@ enum efx_encap_type {
125 * @match_flags: Match type flags, from &enum efx_filter_match_flags 125 * @match_flags: Match type flags, from &enum efx_filter_match_flags
126 * @priority: Priority of the filter, from &enum efx_filter_priority 126 * @priority: Priority of the filter, from &enum efx_filter_priority
127 * @flags: Miscellaneous flags, from &enum efx_filter_flags 127 * @flags: Miscellaneous flags, from &enum efx_filter_flags
128 * @rss_context: RSS context to use, if %EFX_FILTER_FLAG_RX_RSS is set 128 * @rss_context: RSS context to use, if %EFX_FILTER_FLAG_RX_RSS is set. This
129 * is a user_id (with 0 meaning the driver/default RSS context), not an
130 * MCFW context_id.
129 * @dmaq_id: Source/target queue index, or %EFX_FILTER_RX_DMAQ_ID_DROP for 131 * @dmaq_id: Source/target queue index, or %EFX_FILTER_RX_DMAQ_ID_DROP for
130 * an RX drop filter 132 * an RX drop filter
131 * @outer_vid: Outer VLAN ID to match, if %EFX_FILTER_MATCH_OUTER_VID is set 133 * @outer_vid: Outer VLAN ID to match, if %EFX_FILTER_MATCH_OUTER_VID is set
@@ -173,7 +175,6 @@ struct efx_filter_spec {
173}; 175};
174 176
175enum { 177enum {
176 EFX_FILTER_RSS_CONTEXT_DEFAULT = 0xffffffff,
177 EFX_FILTER_RX_DMAQ_ID_DROP = 0xfff 178 EFX_FILTER_RX_DMAQ_ID_DROP = 0xfff
178}; 179};
179 180
@@ -185,7 +186,7 @@ static inline void efx_filter_init_rx(struct efx_filter_spec *spec,
185 memset(spec, 0, sizeof(*spec)); 186 memset(spec, 0, sizeof(*spec));
186 spec->priority = priority; 187 spec->priority = priority;
187 spec->flags = EFX_FILTER_FLAG_RX | flags; 188 spec->flags = EFX_FILTER_FLAG_RX | flags;
188 spec->rss_context = EFX_FILTER_RSS_CONTEXT_DEFAULT; 189 spec->rss_context = 0;
189 spec->dmaq_id = rxq_id; 190 spec->dmaq_id = rxq_id;
190} 191}
191 192
diff --git a/drivers/net/ethernet/sfc/mcdi_pcol.h b/drivers/net/ethernet/sfc/mcdi_pcol.h
index 869d76f8f589..3839eec783ea 100644
--- a/drivers/net/ethernet/sfc/mcdi_pcol.h
+++ b/drivers/net/ethernet/sfc/mcdi_pcol.h
@@ -273,7 +273,8 @@
273#define MC_CMD_ERR_NO_PRIVILEGE 0x1013 273#define MC_CMD_ERR_NO_PRIVILEGE 0x1013
274/* Workaround 26807 could not be turned on/off because some functions 274/* Workaround 26807 could not be turned on/off because some functions
275 * have already installed filters. See the comment at 275 * have already installed filters. See the comment at
276 * MC_CMD_WORKAROUND_BUG26807. */ 276 * MC_CMD_WORKAROUND_BUG26807.
277 * May also returned for other operations such as sub-variant switching. */
277#define MC_CMD_ERR_FILTERS_PRESENT 0x1014 278#define MC_CMD_ERR_FILTERS_PRESENT 0x1014
278/* The clock whose frequency you've attempted to set set 279/* The clock whose frequency you've attempted to set set
279 * doesn't exist on this NIC */ 280 * doesn't exist on this NIC */
@@ -292,6 +293,10 @@
292 * away. This is distinct from MC_CMD_ERR_DATAPATH_DISABLED in that the 293 * away. This is distinct from MC_CMD_ERR_DATAPATH_DISABLED in that the
293 * datapath absence may be temporary*/ 294 * datapath absence may be temporary*/
294#define MC_CMD_ERR_NO_DATAPATH 0x1019 295#define MC_CMD_ERR_NO_DATAPATH 0x1019
296/* The operation could not complete because some VIs are allocated */
297#define MC_CMD_ERR_VIS_PRESENT 0x101a
298/* The operation could not complete because some PIO buffers are allocated */
299#define MC_CMD_ERR_PIOBUFS_PRESENT 0x101b
295 300
296#define MC_CMD_ERR_CODE_OFST 0 301#define MC_CMD_ERR_CODE_OFST 0
297 302
@@ -312,10 +317,17 @@
312#define SIENA_MC_BOOTROM_COPYCODE_VEC (0x800 - 3 * 0x4) 317#define SIENA_MC_BOOTROM_COPYCODE_VEC (0x800 - 3 * 0x4)
313#define HUNT_MC_BOOTROM_COPYCODE_VEC (0x8000 - 3 * 0x4) 318#define HUNT_MC_BOOTROM_COPYCODE_VEC (0x8000 - 3 * 0x4)
314#define MEDFORD_MC_BOOTROM_COPYCODE_VEC (0x10000 - 3 * 0x4) 319#define MEDFORD_MC_BOOTROM_COPYCODE_VEC (0x10000 - 3 * 0x4)
315/* Points to the recovery mode entry point. */ 320/* Points to the recovery mode entry point. Misnamed but kept for compatibility. */
316#define SIENA_MC_BOOTROM_NOFLASH_VEC (0x800 - 2 * 0x4) 321#define SIENA_MC_BOOTROM_NOFLASH_VEC (0x800 - 2 * 0x4)
317#define HUNT_MC_BOOTROM_NOFLASH_VEC (0x8000 - 2 * 0x4) 322#define HUNT_MC_BOOTROM_NOFLASH_VEC (0x8000 - 2 * 0x4)
318#define MEDFORD_MC_BOOTROM_NOFLASH_VEC (0x10000 - 2 * 0x4) 323#define MEDFORD_MC_BOOTROM_NOFLASH_VEC (0x10000 - 2 * 0x4)
324/* Points to the recovery mode entry point. Same as above, but the right name. */
325#define SIENA_MC_BOOTROM_RECOVERY_VEC (0x800 - 2 * 0x4)
326#define HUNT_MC_BOOTROM_RECOVERY_VEC (0x8000 - 2 * 0x4)
327#define MEDFORD_MC_BOOTROM_RECOVERY_VEC (0x10000 - 2 * 0x4)
328
329/* Points to noflash mode entry point. */
330#define MEDFORD_MC_BOOTROM_REAL_NOFLASH_VEC (0x10000 - 4 * 0x4)
319 331
320/* The command set exported by the boot ROM (MCDI v0) */ 332/* The command set exported by the boot ROM (MCDI v0) */
321#define MC_CMD_GET_VERSION_V0_SUPPORTED_FUNCS { \ 333#define MC_CMD_GET_VERSION_V0_SUPPORTED_FUNCS { \
@@ -365,7 +377,7 @@
365#define MCDI_EVENT_LEVEL_LBN 33 377#define MCDI_EVENT_LEVEL_LBN 33
366#define MCDI_EVENT_LEVEL_WIDTH 3 378#define MCDI_EVENT_LEVEL_WIDTH 3
367/* enum: Info. */ 379/* enum: Info. */
368#define MCDI_EVENT_LEVEL_INFO 0x0 380#define MCDI_EVENT_LEVEL_INFO 0x0
369/* enum: Warning. */ 381/* enum: Warning. */
370#define MCDI_EVENT_LEVEL_WARN 0x1 382#define MCDI_EVENT_LEVEL_WARN 0x1
371/* enum: Error. */ 383/* enum: Error. */
@@ -385,21 +397,21 @@
385#define MCDI_EVENT_LINKCHANGE_SPEED_LBN 16 397#define MCDI_EVENT_LINKCHANGE_SPEED_LBN 16
386#define MCDI_EVENT_LINKCHANGE_SPEED_WIDTH 4 398#define MCDI_EVENT_LINKCHANGE_SPEED_WIDTH 4
387/* enum: Link is down or link speed could not be determined */ 399/* enum: Link is down or link speed could not be determined */
388#define MCDI_EVENT_LINKCHANGE_SPEED_UNKNOWN 0x0 400#define MCDI_EVENT_LINKCHANGE_SPEED_UNKNOWN 0x0
389/* enum: 100Mbs */ 401/* enum: 100Mbs */
390#define MCDI_EVENT_LINKCHANGE_SPEED_100M 0x1 402#define MCDI_EVENT_LINKCHANGE_SPEED_100M 0x1
391/* enum: 1Gbs */ 403/* enum: 1Gbs */
392#define MCDI_EVENT_LINKCHANGE_SPEED_1G 0x2 404#define MCDI_EVENT_LINKCHANGE_SPEED_1G 0x2
393/* enum: 10Gbs */ 405/* enum: 10Gbs */
394#define MCDI_EVENT_LINKCHANGE_SPEED_10G 0x3 406#define MCDI_EVENT_LINKCHANGE_SPEED_10G 0x3
395/* enum: 40Gbs */ 407/* enum: 40Gbs */
396#define MCDI_EVENT_LINKCHANGE_SPEED_40G 0x4 408#define MCDI_EVENT_LINKCHANGE_SPEED_40G 0x4
397/* enum: 25Gbs */ 409/* enum: 25Gbs */
398#define MCDI_EVENT_LINKCHANGE_SPEED_25G 0x5 410#define MCDI_EVENT_LINKCHANGE_SPEED_25G 0x5
399/* enum: 50Gbs */ 411/* enum: 50Gbs */
400#define MCDI_EVENT_LINKCHANGE_SPEED_50G 0x6 412#define MCDI_EVENT_LINKCHANGE_SPEED_50G 0x6
401/* enum: 100Gbs */ 413/* enum: 100Gbs */
402#define MCDI_EVENT_LINKCHANGE_SPEED_100G 0x7 414#define MCDI_EVENT_LINKCHANGE_SPEED_100G 0x7
403#define MCDI_EVENT_LINKCHANGE_FCNTL_LBN 20 415#define MCDI_EVENT_LINKCHANGE_FCNTL_LBN 20
404#define MCDI_EVENT_LINKCHANGE_FCNTL_WIDTH 4 416#define MCDI_EVENT_LINKCHANGE_FCNTL_WIDTH 4
405#define MCDI_EVENT_LINKCHANGE_LINK_FLAGS_LBN 24 417#define MCDI_EVENT_LINKCHANGE_LINK_FLAGS_LBN 24
@@ -606,23 +618,23 @@
606/* enum: Transmit error */ 618/* enum: Transmit error */
607#define MCDI_EVENT_CODE_TX_ERR 0xb 619#define MCDI_EVENT_CODE_TX_ERR 0xb
608/* enum: Tx flush has completed */ 620/* enum: Tx flush has completed */
609#define MCDI_EVENT_CODE_TX_FLUSH 0xc 621#define MCDI_EVENT_CODE_TX_FLUSH 0xc
610/* enum: PTP packet received timestamp */ 622/* enum: PTP packet received timestamp */
611#define MCDI_EVENT_CODE_PTP_RX 0xd 623#define MCDI_EVENT_CODE_PTP_RX 0xd
612/* enum: PTP NIC failure */ 624/* enum: PTP NIC failure */
613#define MCDI_EVENT_CODE_PTP_FAULT 0xe 625#define MCDI_EVENT_CODE_PTP_FAULT 0xe
614/* enum: PTP PPS event */ 626/* enum: PTP PPS event */
615#define MCDI_EVENT_CODE_PTP_PPS 0xf 627#define MCDI_EVENT_CODE_PTP_PPS 0xf
616/* enum: Rx flush has completed */ 628/* enum: Rx flush has completed */
617#define MCDI_EVENT_CODE_RX_FLUSH 0x10 629#define MCDI_EVENT_CODE_RX_FLUSH 0x10
618/* enum: Receive error */ 630/* enum: Receive error */
619#define MCDI_EVENT_CODE_RX_ERR 0x11 631#define MCDI_EVENT_CODE_RX_ERR 0x11
620/* enum: AOE fault */ 632/* enum: AOE fault */
621#define MCDI_EVENT_CODE_AOE 0x12 633#define MCDI_EVENT_CODE_AOE 0x12
622/* enum: Network port calibration failed (VCAL). */ 634/* enum: Network port calibration failed (VCAL). */
623#define MCDI_EVENT_CODE_VCAL_FAIL 0x13 635#define MCDI_EVENT_CODE_VCAL_FAIL 0x13
624/* enum: HW PPS event */ 636/* enum: HW PPS event */
625#define MCDI_EVENT_CODE_HW_PPS 0x14 637#define MCDI_EVENT_CODE_HW_PPS 0x14
626/* enum: The MC has rebooted (huntington and later, siena uses CODE_REBOOT and 638/* enum: The MC has rebooted (huntington and later, siena uses CODE_REBOOT and
627 * a different format) 639 * a different format)
628 */ 640 */
@@ -654,7 +666,7 @@
654/* enum: Artificial event generated by host and posted via MC for test 666/* enum: Artificial event generated by host and posted via MC for test
655 * purposes. 667 * purposes.
656 */ 668 */
657#define MCDI_EVENT_CODE_TESTGEN 0xfa 669#define MCDI_EVENT_CODE_TESTGEN 0xfa
658#define MCDI_EVENT_CMDDONE_DATA_OFST 0 670#define MCDI_EVENT_CMDDONE_DATA_OFST 0
659#define MCDI_EVENT_CMDDONE_DATA_LEN 4 671#define MCDI_EVENT_CMDDONE_DATA_LEN 4
660#define MCDI_EVENT_CMDDONE_DATA_LBN 0 672#define MCDI_EVENT_CMDDONE_DATA_LBN 0
@@ -784,7 +796,7 @@
784#define FCDI_EVENT_LEVEL_LBN 33 796#define FCDI_EVENT_LEVEL_LBN 33
785#define FCDI_EVENT_LEVEL_WIDTH 3 797#define FCDI_EVENT_LEVEL_WIDTH 3
786/* enum: Info. */ 798/* enum: Info. */
787#define FCDI_EVENT_LEVEL_INFO 0x0 799#define FCDI_EVENT_LEVEL_INFO 0x0
788/* enum: Warning. */ 800/* enum: Warning. */
789#define FCDI_EVENT_LEVEL_WARN 0x1 801#define FCDI_EVENT_LEVEL_WARN 0x1
790/* enum: Error. */ 802/* enum: Error. */
@@ -916,7 +928,7 @@
916#define MUM_EVENT_LEVEL_LBN 33 928#define MUM_EVENT_LEVEL_LBN 33
917#define MUM_EVENT_LEVEL_WIDTH 3 929#define MUM_EVENT_LEVEL_WIDTH 3
918/* enum: Info. */ 930/* enum: Info. */
919#define MUM_EVENT_LEVEL_INFO 0x0 931#define MUM_EVENT_LEVEL_INFO 0x0
920/* enum: Warning. */ 932/* enum: Warning. */
921#define MUM_EVENT_LEVEL_WARN 0x1 933#define MUM_EVENT_LEVEL_WARN 0x1
922/* enum: Error. */ 934/* enum: Error. */
@@ -1002,7 +1014,9 @@
1002 1014
1003/***********************************/ 1015/***********************************/
1004/* MC_CMD_READ32 1016/* MC_CMD_READ32
1005 * Read multiple 32byte words from MC memory. 1017 * Read multiple 32byte words from MC memory. Note - this command really
1018 * belongs to INSECURE category but is required by shmboot. The command handler
1019 * has additional checks to reject insecure calls.
1006 */ 1020 */
1007#define MC_CMD_READ32 0x1 1021#define MC_CMD_READ32 0x1
1008 1022
@@ -1050,7 +1064,9 @@
1050 1064
1051/***********************************/ 1065/***********************************/
1052/* MC_CMD_COPYCODE 1066/* MC_CMD_COPYCODE
1053 * Copy MC code between two locations and jump. 1067 * Copy MC code between two locations and jump. Note - this command really
1068 * belongs to INSECURE category but is required by shmboot. The command handler
1069 * has additional checks to reject insecure calls.
1054 */ 1070 */
1055#define MC_CMD_COPYCODE 0x3 1071#define MC_CMD_COPYCODE 0x3
1056 1072
@@ -1139,7 +1155,7 @@
1139#define MC_CMD_GET_BOOT_STATUS_OUT_BOOT_OFFSET_OFST 0 1155#define MC_CMD_GET_BOOT_STATUS_OUT_BOOT_OFFSET_OFST 0
1140#define MC_CMD_GET_BOOT_STATUS_OUT_BOOT_OFFSET_LEN 4 1156#define MC_CMD_GET_BOOT_STATUS_OUT_BOOT_OFFSET_LEN 4
1141/* enum: indicates that the MC wasn't flash booted */ 1157/* enum: indicates that the MC wasn't flash booted */
1142#define MC_CMD_GET_BOOT_STATUS_OUT_BOOT_OFFSET_NULL 0xdeadbeef 1158#define MC_CMD_GET_BOOT_STATUS_OUT_BOOT_OFFSET_NULL 0xdeadbeef
1143#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_OFST 4 1159#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_OFST 4
1144#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_LEN 4 1160#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_LEN 4
1145#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_WATCHDOG_LBN 0 1161#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_WATCHDOG_LBN 0
@@ -1555,11 +1571,10 @@
1555#define MC_CMD_PTP_IN_MANFTEST_PACKET_TEST_ENABLE_OFST 8 1571#define MC_CMD_PTP_IN_MANFTEST_PACKET_TEST_ENABLE_OFST 8
1556#define MC_CMD_PTP_IN_MANFTEST_PACKET_TEST_ENABLE_LEN 4 1572#define MC_CMD_PTP_IN_MANFTEST_PACKET_TEST_ENABLE_LEN 4
1557 1573
1558/* MC_CMD_PTP_IN_RESET_STATS msgrequest */ 1574/* MC_CMD_PTP_IN_RESET_STATS msgrequest: Reset PTP statistics */
1559#define MC_CMD_PTP_IN_RESET_STATS_LEN 8 1575#define MC_CMD_PTP_IN_RESET_STATS_LEN 8
1560/* MC_CMD_PTP_IN_CMD_OFST 0 */ 1576/* MC_CMD_PTP_IN_CMD_OFST 0 */
1561/* MC_CMD_PTP_IN_CMD_LEN 4 */ 1577/* MC_CMD_PTP_IN_CMD_LEN 4 */
1562/* Reset PTP statistics */
1563/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ 1578/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
1564/* MC_CMD_PTP_IN_PERIPH_ID_LEN 4 */ 1579/* MC_CMD_PTP_IN_PERIPH_ID_LEN 4 */
1565 1580
@@ -1710,11 +1725,10 @@
1710/* enum: External. */ 1725/* enum: External. */
1711#define MC_CMD_PTP_CLK_SRC_EXTERNAL 0x1 1726#define MC_CMD_PTP_CLK_SRC_EXTERNAL 0x1
1712 1727
1713/* MC_CMD_PTP_IN_RST_CLK msgrequest */ 1728/* MC_CMD_PTP_IN_RST_CLK msgrequest: Reset value of Timer Reg. */
1714#define MC_CMD_PTP_IN_RST_CLK_LEN 8 1729#define MC_CMD_PTP_IN_RST_CLK_LEN 8
1715/* MC_CMD_PTP_IN_CMD_OFST 0 */ 1730/* MC_CMD_PTP_IN_CMD_OFST 0 */
1716/* MC_CMD_PTP_IN_CMD_LEN 4 */ 1731/* MC_CMD_PTP_IN_CMD_LEN 4 */
1717/* Reset value of Timer Reg. */
1718/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ 1732/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
1719/* MC_CMD_PTP_IN_PERIPH_ID_LEN 4 */ 1733/* MC_CMD_PTP_IN_PERIPH_ID_LEN 4 */
1720 1734
@@ -2687,8 +2701,16 @@
2687#define MC_CMD_DRV_ATTACH_IN_NEW_STATE_LEN 4 2701#define MC_CMD_DRV_ATTACH_IN_NEW_STATE_LEN 4
2688#define MC_CMD_DRV_ATTACH_LBN 0 2702#define MC_CMD_DRV_ATTACH_LBN 0
2689#define MC_CMD_DRV_ATTACH_WIDTH 1 2703#define MC_CMD_DRV_ATTACH_WIDTH 1
2704#define MC_CMD_DRV_ATTACH_IN_ATTACH_LBN 0
2705#define MC_CMD_DRV_ATTACH_IN_ATTACH_WIDTH 1
2690#define MC_CMD_DRV_PREBOOT_LBN 1 2706#define MC_CMD_DRV_PREBOOT_LBN 1
2691#define MC_CMD_DRV_PREBOOT_WIDTH 1 2707#define MC_CMD_DRV_PREBOOT_WIDTH 1
2708#define MC_CMD_DRV_ATTACH_IN_PREBOOT_LBN 1
2709#define MC_CMD_DRV_ATTACH_IN_PREBOOT_WIDTH 1
2710#define MC_CMD_DRV_ATTACH_IN_SUBVARIANT_AWARE_LBN 2
2711#define MC_CMD_DRV_ATTACH_IN_SUBVARIANT_AWARE_WIDTH 1
2712#define MC_CMD_DRV_ATTACH_IN_WANT_VI_SPREADING_LBN 3
2713#define MC_CMD_DRV_ATTACH_IN_WANT_VI_SPREADING_WIDTH 1
2692/* 1 to set new state, or 0 to just report the existing state */ 2714/* 1 to set new state, or 0 to just report the existing state */
2693#define MC_CMD_DRV_ATTACH_IN_UPDATE_OFST 4 2715#define MC_CMD_DRV_ATTACH_IN_UPDATE_OFST 4
2694#define MC_CMD_DRV_ATTACH_IN_UPDATE_LEN 4 2716#define MC_CMD_DRV_ATTACH_IN_UPDATE_LEN 4
@@ -2711,8 +2733,14 @@
2711 * support 2733 * support
2712 */ 2734 */
2713#define MC_CMD_FW_RULES_ENGINE 0x5 2735#define MC_CMD_FW_RULES_ENGINE 0x5
2736/* enum: Prefer to use firmware with additional DPDK support */
2737#define MC_CMD_FW_DPDK 0x6
2738/* enum: Prefer to use "l3xudp" custom datapath firmware (see SF-119495-PD and
2739 * bug69716)
2740 */
2741#define MC_CMD_FW_L3XUDP 0x7
2714/* enum: Only this option is allowed for non-admin functions */ 2742/* enum: Only this option is allowed for non-admin functions */
2715#define MC_CMD_FW_DONT_CARE 0xffffffff 2743#define MC_CMD_FW_DONT_CARE 0xffffffff
2716 2744
2717/* MC_CMD_DRV_ATTACH_OUT msgresponse */ 2745/* MC_CMD_DRV_ATTACH_OUT msgresponse */
2718#define MC_CMD_DRV_ATTACH_OUT_LEN 4 2746#define MC_CMD_DRV_ATTACH_OUT_LEN 4
@@ -2740,6 +2768,11 @@
2740 * refers to the Sorrento external FPGA port. 2768 * refers to the Sorrento external FPGA port.
2741 */ 2769 */
2742#define MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_NO_ACTIVE_PORT 0x3 2770#define MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_NO_ACTIVE_PORT 0x3
2771/* enum: If set, indicates that VI spreading is currently enabled. Will always
2772 * indicate the current state, regardless of the value in the WANT_VI_SPREADING
2773 * input.
2774 */
2775#define MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_VI_SPREADING_ENABLED 0x4
2743 2776
2744 2777
2745/***********************************/ 2778/***********************************/
@@ -3294,83 +3327,83 @@
3294#define MC_CMD_GET_LOOPBACK_MODES_OUT_100M_LO_OFST 0 3327#define MC_CMD_GET_LOOPBACK_MODES_OUT_100M_LO_OFST 0
3295#define MC_CMD_GET_LOOPBACK_MODES_OUT_100M_HI_OFST 4 3328#define MC_CMD_GET_LOOPBACK_MODES_OUT_100M_HI_OFST 4
3296/* enum: None. */ 3329/* enum: None. */
3297#define MC_CMD_LOOPBACK_NONE 0x0 3330#define MC_CMD_LOOPBACK_NONE 0x0
3298/* enum: Data. */ 3331/* enum: Data. */
3299#define MC_CMD_LOOPBACK_DATA 0x1 3332#define MC_CMD_LOOPBACK_DATA 0x1
3300/* enum: GMAC. */ 3333/* enum: GMAC. */
3301#define MC_CMD_LOOPBACK_GMAC 0x2 3334#define MC_CMD_LOOPBACK_GMAC 0x2
3302/* enum: XGMII. */ 3335/* enum: XGMII. */
3303#define MC_CMD_LOOPBACK_XGMII 0x3 3336#define MC_CMD_LOOPBACK_XGMII 0x3
3304/* enum: XGXS. */ 3337/* enum: XGXS. */
3305#define MC_CMD_LOOPBACK_XGXS 0x4 3338#define MC_CMD_LOOPBACK_XGXS 0x4
3306/* enum: XAUI. */ 3339/* enum: XAUI. */
3307#define MC_CMD_LOOPBACK_XAUI 0x5 3340#define MC_CMD_LOOPBACK_XAUI 0x5
3308/* enum: GMII. */ 3341/* enum: GMII. */
3309#define MC_CMD_LOOPBACK_GMII 0x6 3342#define MC_CMD_LOOPBACK_GMII 0x6
3310/* enum: SGMII. */ 3343/* enum: SGMII. */
3311#define MC_CMD_LOOPBACK_SGMII 0x7 3344#define MC_CMD_LOOPBACK_SGMII 0x7
3312/* enum: XGBR. */ 3345/* enum: XGBR. */
3313#define MC_CMD_LOOPBACK_XGBR 0x8 3346#define MC_CMD_LOOPBACK_XGBR 0x8
3314/* enum: XFI. */ 3347/* enum: XFI. */
3315#define MC_CMD_LOOPBACK_XFI 0x9 3348#define MC_CMD_LOOPBACK_XFI 0x9
3316/* enum: XAUI Far. */ 3349/* enum: XAUI Far. */
3317#define MC_CMD_LOOPBACK_XAUI_FAR 0xa 3350#define MC_CMD_LOOPBACK_XAUI_FAR 0xa
3318/* enum: GMII Far. */ 3351/* enum: GMII Far. */
3319#define MC_CMD_LOOPBACK_GMII_FAR 0xb 3352#define MC_CMD_LOOPBACK_GMII_FAR 0xb
3320/* enum: SGMII Far. */ 3353/* enum: SGMII Far. */
3321#define MC_CMD_LOOPBACK_SGMII_FAR 0xc 3354#define MC_CMD_LOOPBACK_SGMII_FAR 0xc
3322/* enum: XFI Far. */ 3355/* enum: XFI Far. */
3323#define MC_CMD_LOOPBACK_XFI_FAR 0xd 3356#define MC_CMD_LOOPBACK_XFI_FAR 0xd
3324/* enum: GPhy. */ 3357/* enum: GPhy. */
3325#define MC_CMD_LOOPBACK_GPHY 0xe 3358#define MC_CMD_LOOPBACK_GPHY 0xe
3326/* enum: PhyXS. */ 3359/* enum: PhyXS. */
3327#define MC_CMD_LOOPBACK_PHYXS 0xf 3360#define MC_CMD_LOOPBACK_PHYXS 0xf
3328/* enum: PCS. */ 3361/* enum: PCS. */
3329#define MC_CMD_LOOPBACK_PCS 0x10 3362#define MC_CMD_LOOPBACK_PCS 0x10
3330/* enum: PMA-PMD. */ 3363/* enum: PMA-PMD. */
3331#define MC_CMD_LOOPBACK_PMAPMD 0x11 3364#define MC_CMD_LOOPBACK_PMAPMD 0x11
3332/* enum: Cross-Port. */ 3365/* enum: Cross-Port. */
3333#define MC_CMD_LOOPBACK_XPORT 0x12 3366#define MC_CMD_LOOPBACK_XPORT 0x12
3334/* enum: XGMII-Wireside. */ 3367/* enum: XGMII-Wireside. */
3335#define MC_CMD_LOOPBACK_XGMII_WS 0x13 3368#define MC_CMD_LOOPBACK_XGMII_WS 0x13
3336/* enum: XAUI Wireside. */ 3369/* enum: XAUI Wireside. */
3337#define MC_CMD_LOOPBACK_XAUI_WS 0x14 3370#define MC_CMD_LOOPBACK_XAUI_WS 0x14
3338/* enum: XAUI Wireside Far. */ 3371/* enum: XAUI Wireside Far. */
3339#define MC_CMD_LOOPBACK_XAUI_WS_FAR 0x15 3372#define MC_CMD_LOOPBACK_XAUI_WS_FAR 0x15
3340/* enum: XAUI Wireside near. */ 3373/* enum: XAUI Wireside near. */
3341#define MC_CMD_LOOPBACK_XAUI_WS_NEAR 0x16 3374#define MC_CMD_LOOPBACK_XAUI_WS_NEAR 0x16
3342/* enum: GMII Wireside. */ 3375/* enum: GMII Wireside. */
3343#define MC_CMD_LOOPBACK_GMII_WS 0x17 3376#define MC_CMD_LOOPBACK_GMII_WS 0x17
3344/* enum: XFI Wireside. */ 3377/* enum: XFI Wireside. */
3345#define MC_CMD_LOOPBACK_XFI_WS 0x18 3378#define MC_CMD_LOOPBACK_XFI_WS 0x18
3346/* enum: XFI Wireside Far. */ 3379/* enum: XFI Wireside Far. */
3347#define MC_CMD_LOOPBACK_XFI_WS_FAR 0x19 3380#define MC_CMD_LOOPBACK_XFI_WS_FAR 0x19
3348/* enum: PhyXS Wireside. */ 3381/* enum: PhyXS Wireside. */
3349#define MC_CMD_LOOPBACK_PHYXS_WS 0x1a 3382#define MC_CMD_LOOPBACK_PHYXS_WS 0x1a
3350/* enum: PMA lanes MAC-Serdes. */ 3383/* enum: PMA lanes MAC-Serdes. */
3351#define MC_CMD_LOOPBACK_PMA_INT 0x1b 3384#define MC_CMD_LOOPBACK_PMA_INT 0x1b
3352/* enum: KR Serdes Parallel (Encoder). */ 3385/* enum: KR Serdes Parallel (Encoder). */
3353#define MC_CMD_LOOPBACK_SD_NEAR 0x1c 3386#define MC_CMD_LOOPBACK_SD_NEAR 0x1c
3354/* enum: KR Serdes Serial. */ 3387/* enum: KR Serdes Serial. */
3355#define MC_CMD_LOOPBACK_SD_FAR 0x1d 3388#define MC_CMD_LOOPBACK_SD_FAR 0x1d
3356/* enum: PMA lanes MAC-Serdes Wireside. */ 3389/* enum: PMA lanes MAC-Serdes Wireside. */
3357#define MC_CMD_LOOPBACK_PMA_INT_WS 0x1e 3390#define MC_CMD_LOOPBACK_PMA_INT_WS 0x1e
3358/* enum: KR Serdes Parallel Wireside (Full PCS). */ 3391/* enum: KR Serdes Parallel Wireside (Full PCS). */
3359#define MC_CMD_LOOPBACK_SD_FEP2_WS 0x1f 3392#define MC_CMD_LOOPBACK_SD_FEP2_WS 0x1f
3360/* enum: KR Serdes Parallel Wireside (Sym Aligner to TX). */ 3393/* enum: KR Serdes Parallel Wireside (Sym Aligner to TX). */
3361#define MC_CMD_LOOPBACK_SD_FEP1_5_WS 0x20 3394#define MC_CMD_LOOPBACK_SD_FEP1_5_WS 0x20
3362/* enum: KR Serdes Parallel Wireside (Deserializer to Serializer). */ 3395/* enum: KR Serdes Parallel Wireside (Deserializer to Serializer). */
3363#define MC_CMD_LOOPBACK_SD_FEP_WS 0x21 3396#define MC_CMD_LOOPBACK_SD_FEP_WS 0x21
3364/* enum: KR Serdes Serial Wireside. */ 3397/* enum: KR Serdes Serial Wireside. */
3365#define MC_CMD_LOOPBACK_SD_FES_WS 0x22 3398#define MC_CMD_LOOPBACK_SD_FES_WS 0x22
3366/* enum: Near side of AOE Siena side port */ 3399/* enum: Near side of AOE Siena side port */
3367#define MC_CMD_LOOPBACK_AOE_INT_NEAR 0x23 3400#define MC_CMD_LOOPBACK_AOE_INT_NEAR 0x23
3368/* enum: Medford Wireside datapath loopback */ 3401/* enum: Medford Wireside datapath loopback */
3369#define MC_CMD_LOOPBACK_DATA_WS 0x24 3402#define MC_CMD_LOOPBACK_DATA_WS 0x24
3370/* enum: Force link up without setting up any physical loopback (snapper use 3403/* enum: Force link up without setting up any physical loopback (snapper use
3371 * only) 3404 * only)
3372 */ 3405 */
3373#define MC_CMD_LOOPBACK_FORCE_EXT_LINK 0x25 3406#define MC_CMD_LOOPBACK_FORCE_EXT_LINK 0x25
3374/* Supported loopbacks. */ 3407/* Supported loopbacks. */
3375#define MC_CMD_GET_LOOPBACK_MODES_OUT_1G_OFST 8 3408#define MC_CMD_GET_LOOPBACK_MODES_OUT_1G_OFST 8
3376#define MC_CMD_GET_LOOPBACK_MODES_OUT_1G_LEN 8 3409#define MC_CMD_GET_LOOPBACK_MODES_OUT_1G_LEN 8
@@ -3410,83 +3443,83 @@
3410#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_100M_LO_OFST 0 3443#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_100M_LO_OFST 0
3411#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_100M_HI_OFST 4 3444#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_100M_HI_OFST 4
3412/* enum: None. */ 3445/* enum: None. */
3413/* MC_CMD_LOOPBACK_NONE 0x0 */ 3446/* MC_CMD_LOOPBACK_NONE 0x0 */
3414/* enum: Data. */ 3447/* enum: Data. */
3415/* MC_CMD_LOOPBACK_DATA 0x1 */ 3448/* MC_CMD_LOOPBACK_DATA 0x1 */
3416/* enum: GMAC. */ 3449/* enum: GMAC. */
3417/* MC_CMD_LOOPBACK_GMAC 0x2 */ 3450/* MC_CMD_LOOPBACK_GMAC 0x2 */
3418/* enum: XGMII. */ 3451/* enum: XGMII. */
3419/* MC_CMD_LOOPBACK_XGMII 0x3 */ 3452/* MC_CMD_LOOPBACK_XGMII 0x3 */
3420/* enum: XGXS. */ 3453/* enum: XGXS. */
3421/* MC_CMD_LOOPBACK_XGXS 0x4 */ 3454/* MC_CMD_LOOPBACK_XGXS 0x4 */
3422/* enum: XAUI. */ 3455/* enum: XAUI. */
3423/* MC_CMD_LOOPBACK_XAUI 0x5 */ 3456/* MC_CMD_LOOPBACK_XAUI 0x5 */
3424/* enum: GMII. */ 3457/* enum: GMII. */
3425/* MC_CMD_LOOPBACK_GMII 0x6 */ 3458/* MC_CMD_LOOPBACK_GMII 0x6 */
3426/* enum: SGMII. */ 3459/* enum: SGMII. */
3427/* MC_CMD_LOOPBACK_SGMII 0x7 */ 3460/* MC_CMD_LOOPBACK_SGMII 0x7 */
3428/* enum: XGBR. */ 3461/* enum: XGBR. */
3429/* MC_CMD_LOOPBACK_XGBR 0x8 */ 3462/* MC_CMD_LOOPBACK_XGBR 0x8 */
3430/* enum: XFI. */ 3463/* enum: XFI. */
3431/* MC_CMD_LOOPBACK_XFI 0x9 */ 3464/* MC_CMD_LOOPBACK_XFI 0x9 */
3432/* enum: XAUI Far. */ 3465/* enum: XAUI Far. */
3433/* MC_CMD_LOOPBACK_XAUI_FAR 0xa */ 3466/* MC_CMD_LOOPBACK_XAUI_FAR 0xa */
3434/* enum: GMII Far. */ 3467/* enum: GMII Far. */
3435/* MC_CMD_LOOPBACK_GMII_FAR 0xb */ 3468/* MC_CMD_LOOPBACK_GMII_FAR 0xb */
3436/* enum: SGMII Far. */ 3469/* enum: SGMII Far. */
3437/* MC_CMD_LOOPBACK_SGMII_FAR 0xc */ 3470/* MC_CMD_LOOPBACK_SGMII_FAR 0xc */
3438/* enum: XFI Far. */ 3471/* enum: XFI Far. */
3439/* MC_CMD_LOOPBACK_XFI_FAR 0xd */ 3472/* MC_CMD_LOOPBACK_XFI_FAR 0xd */
3440/* enum: GPhy. */ 3473/* enum: GPhy. */
3441/* MC_CMD_LOOPBACK_GPHY 0xe */ 3474/* MC_CMD_LOOPBACK_GPHY 0xe */
3442/* enum: PhyXS. */ 3475/* enum: PhyXS. */
3443/* MC_CMD_LOOPBACK_PHYXS 0xf */ 3476/* MC_CMD_LOOPBACK_PHYXS 0xf */
3444/* enum: PCS. */ 3477/* enum: PCS. */
3445/* MC_CMD_LOOPBACK_PCS 0x10 */ 3478/* MC_CMD_LOOPBACK_PCS 0x10 */
3446/* enum: PMA-PMD. */ 3479/* enum: PMA-PMD. */
3447/* MC_CMD_LOOPBACK_PMAPMD 0x11 */ 3480/* MC_CMD_LOOPBACK_PMAPMD 0x11 */
3448/* enum: Cross-Port. */ 3481/* enum: Cross-Port. */
3449/* MC_CMD_LOOPBACK_XPORT 0x12 */ 3482/* MC_CMD_LOOPBACK_XPORT 0x12 */
3450/* enum: XGMII-Wireside. */ 3483/* enum: XGMII-Wireside. */
3451/* MC_CMD_LOOPBACK_XGMII_WS 0x13 */ 3484/* MC_CMD_LOOPBACK_XGMII_WS 0x13 */
3452/* enum: XAUI Wireside. */ 3485/* enum: XAUI Wireside. */
3453/* MC_CMD_LOOPBACK_XAUI_WS 0x14 */ 3486/* MC_CMD_LOOPBACK_XAUI_WS 0x14 */
3454/* enum: XAUI Wireside Far. */ 3487/* enum: XAUI Wireside Far. */
3455/* MC_CMD_LOOPBACK_XAUI_WS_FAR 0x15 */ 3488/* MC_CMD_LOOPBACK_XAUI_WS_FAR 0x15 */
3456/* enum: XAUI Wireside near. */ 3489/* enum: XAUI Wireside near. */
3457/* MC_CMD_LOOPBACK_XAUI_WS_NEAR 0x16 */ 3490/* MC_CMD_LOOPBACK_XAUI_WS_NEAR 0x16 */
3458/* enum: GMII Wireside. */ 3491/* enum: GMII Wireside. */
3459/* MC_CMD_LOOPBACK_GMII_WS 0x17 */ 3492/* MC_CMD_LOOPBACK_GMII_WS 0x17 */
3460/* enum: XFI Wireside. */ 3493/* enum: XFI Wireside. */
3461/* MC_CMD_LOOPBACK_XFI_WS 0x18 */ 3494/* MC_CMD_LOOPBACK_XFI_WS 0x18 */
3462/* enum: XFI Wireside Far. */ 3495/* enum: XFI Wireside Far. */
3463/* MC_CMD_LOOPBACK_XFI_WS_FAR 0x19 */ 3496/* MC_CMD_LOOPBACK_XFI_WS_FAR 0x19 */
3464/* enum: PhyXS Wireside. */ 3497/* enum: PhyXS Wireside. */
3465/* MC_CMD_LOOPBACK_PHYXS_WS 0x1a */ 3498/* MC_CMD_LOOPBACK_PHYXS_WS 0x1a */
3466/* enum: PMA lanes MAC-Serdes. */ 3499/* enum: PMA lanes MAC-Serdes. */
3467/* MC_CMD_LOOPBACK_PMA_INT 0x1b */ 3500/* MC_CMD_LOOPBACK_PMA_INT 0x1b */
3468/* enum: KR Serdes Parallel (Encoder). */ 3501/* enum: KR Serdes Parallel (Encoder). */
3469/* MC_CMD_LOOPBACK_SD_NEAR 0x1c */ 3502/* MC_CMD_LOOPBACK_SD_NEAR 0x1c */
3470/* enum: KR Serdes Serial. */ 3503/* enum: KR Serdes Serial. */
3471/* MC_CMD_LOOPBACK_SD_FAR 0x1d */ 3504/* MC_CMD_LOOPBACK_SD_FAR 0x1d */
3472/* enum: PMA lanes MAC-Serdes Wireside. */ 3505/* enum: PMA lanes MAC-Serdes Wireside. */
3473/* MC_CMD_LOOPBACK_PMA_INT_WS 0x1e */ 3506/* MC_CMD_LOOPBACK_PMA_INT_WS 0x1e */
3474/* enum: KR Serdes Parallel Wireside (Full PCS). */ 3507/* enum: KR Serdes Parallel Wireside (Full PCS). */
3475/* MC_CMD_LOOPBACK_SD_FEP2_WS 0x1f */ 3508/* MC_CMD_LOOPBACK_SD_FEP2_WS 0x1f */
3476/* enum: KR Serdes Parallel Wireside (Sym Aligner to TX). */ 3509/* enum: KR Serdes Parallel Wireside (Sym Aligner to TX). */
3477/* MC_CMD_LOOPBACK_SD_FEP1_5_WS 0x20 */ 3510/* MC_CMD_LOOPBACK_SD_FEP1_5_WS 0x20 */
3478/* enum: KR Serdes Parallel Wireside (Deserializer to Serializer). */ 3511/* enum: KR Serdes Parallel Wireside (Deserializer to Serializer). */
3479/* MC_CMD_LOOPBACK_SD_FEP_WS 0x21 */ 3512/* MC_CMD_LOOPBACK_SD_FEP_WS 0x21 */
3480/* enum: KR Serdes Serial Wireside. */ 3513/* enum: KR Serdes Serial Wireside. */
3481/* MC_CMD_LOOPBACK_SD_FES_WS 0x22 */ 3514/* MC_CMD_LOOPBACK_SD_FES_WS 0x22 */
3482/* enum: Near side of AOE Siena side port */ 3515/* enum: Near side of AOE Siena side port */
3483/* MC_CMD_LOOPBACK_AOE_INT_NEAR 0x23 */ 3516/* MC_CMD_LOOPBACK_AOE_INT_NEAR 0x23 */
3484/* enum: Medford Wireside datapath loopback */ 3517/* enum: Medford Wireside datapath loopback */
3485/* MC_CMD_LOOPBACK_DATA_WS 0x24 */ 3518/* MC_CMD_LOOPBACK_DATA_WS 0x24 */
3486/* enum: Force link up without setting up any physical loopback (snapper use 3519/* enum: Force link up without setting up any physical loopback (snapper use
3487 * only) 3520 * only)
3488 */ 3521 */
3489/* MC_CMD_LOOPBACK_FORCE_EXT_LINK 0x25 */ 3522/* MC_CMD_LOOPBACK_FORCE_EXT_LINK 0x25 */
3490/* Supported loopbacks. */ 3523/* Supported loopbacks. */
3491#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_1G_OFST 8 3524#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_1G_OFST 8
3492#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_1G_LEN 8 3525#define MC_CMD_GET_LOOPBACK_MODES_OUT_V2_1G_LEN 8
@@ -3537,6 +3570,37 @@
3537/* Enum values, see field(s): */ 3570/* Enum values, see field(s): */
3538/* 100M */ 3571/* 100M */
3539 3572
3573/* AN_TYPE structuredef: Auto-negotiation types defined in IEEE802.3 */
3574#define AN_TYPE_LEN 4
3575#define AN_TYPE_TYPE_OFST 0
3576#define AN_TYPE_TYPE_LEN 4
3577/* enum: None, AN disabled or not supported */
3578#define MC_CMD_AN_NONE 0x0
3579/* enum: Clause 28 - BASE-T */
3580#define MC_CMD_AN_CLAUSE28 0x1
3581/* enum: Clause 37 - BASE-X */
3582#define MC_CMD_AN_CLAUSE37 0x2
3583/* enum: Clause 73 - BASE-R startup protocol for backplane and copper cable
3584 * assemblies. Includes Clause 72/Clause 92 link-training.
3585 */
3586#define MC_CMD_AN_CLAUSE73 0x3
3587#define AN_TYPE_TYPE_LBN 0
3588#define AN_TYPE_TYPE_WIDTH 32
3589
3590/* FEC_TYPE structuredef: Forward error correction types defined in IEEE802.3
3591 */
3592#define FEC_TYPE_LEN 4
3593#define FEC_TYPE_TYPE_OFST 0
3594#define FEC_TYPE_TYPE_LEN 4
3595/* enum: No FEC */
3596#define MC_CMD_FEC_NONE 0x0
3597/* enum: Clause 74 BASE-R FEC (a.k.a Firecode) */
3598#define MC_CMD_FEC_BASER 0x1
3599/* enum: Clause 91/Clause 108 Reed-Solomon FEC */
3600#define MC_CMD_FEC_RS 0x2
3601#define FEC_TYPE_TYPE_LBN 0
3602#define FEC_TYPE_TYPE_WIDTH 32
3603
3540 3604
3541/***********************************/ 3605/***********************************/
3542/* MC_CMD_GET_LINK 3606/* MC_CMD_GET_LINK
@@ -3552,10 +3616,14 @@
3552 3616
3553/* MC_CMD_GET_LINK_OUT msgresponse */ 3617/* MC_CMD_GET_LINK_OUT msgresponse */
3554#define MC_CMD_GET_LINK_OUT_LEN 28 3618#define MC_CMD_GET_LINK_OUT_LEN 28
3555/* near-side advertised capabilities */ 3619/* Near-side advertised capabilities. Refer to
3620 * MC_CMD_GET_PHY_CFG_OUT/SUPPORTED_CAP for bit definitions.
3621 */
3556#define MC_CMD_GET_LINK_OUT_CAP_OFST 0 3622#define MC_CMD_GET_LINK_OUT_CAP_OFST 0
3557#define MC_CMD_GET_LINK_OUT_CAP_LEN 4 3623#define MC_CMD_GET_LINK_OUT_CAP_LEN 4
3558/* link-partner advertised capabilities */ 3624/* Link-partner advertised capabilities. Refer to
3625 * MC_CMD_GET_PHY_CFG_OUT/SUPPORTED_CAP for bit definitions.
3626 */
3559#define MC_CMD_GET_LINK_OUT_LP_CAP_OFST 4 3627#define MC_CMD_GET_LINK_OUT_LP_CAP_OFST 4
3560#define MC_CMD_GET_LINK_OUT_LP_CAP_LEN 4 3628#define MC_CMD_GET_LINK_OUT_LP_CAP_LEN 4
3561/* Autonegotiated speed in mbit/s. The link may still be down even if this 3629/* Autonegotiated speed in mbit/s. The link may still be down even if this
@@ -3598,6 +3666,97 @@
3598#define MC_CMD_MAC_FAULT_PENDING_RECONFIG_LBN 3 3666#define MC_CMD_MAC_FAULT_PENDING_RECONFIG_LBN 3
3599#define MC_CMD_MAC_FAULT_PENDING_RECONFIG_WIDTH 1 3667#define MC_CMD_MAC_FAULT_PENDING_RECONFIG_WIDTH 1
3600 3668
3669/* MC_CMD_GET_LINK_OUT_V2 msgresponse: Extended link state information */
3670#define MC_CMD_GET_LINK_OUT_V2_LEN 44
3671/* Near-side advertised capabilities. Refer to
3672 * MC_CMD_GET_PHY_CFG_OUT/SUPPORTED_CAP for bit definitions.
3673 */
3674#define MC_CMD_GET_LINK_OUT_V2_CAP_OFST 0
3675#define MC_CMD_GET_LINK_OUT_V2_CAP_LEN 4
3676/* Link-partner advertised capabilities. Refer to
3677 * MC_CMD_GET_PHY_CFG_OUT/SUPPORTED_CAP for bit definitions.
3678 */
3679#define MC_CMD_GET_LINK_OUT_V2_LP_CAP_OFST 4
3680#define MC_CMD_GET_LINK_OUT_V2_LP_CAP_LEN 4
3681/* Autonegotiated speed in mbit/s. The link may still be down even if this
3682 * reads non-zero.
3683 */
3684#define MC_CMD_GET_LINK_OUT_V2_LINK_SPEED_OFST 8
3685#define MC_CMD_GET_LINK_OUT_V2_LINK_SPEED_LEN 4
3686/* Current loopback setting. */
3687#define MC_CMD_GET_LINK_OUT_V2_LOOPBACK_MODE_OFST 12
3688#define MC_CMD_GET_LINK_OUT_V2_LOOPBACK_MODE_LEN 4
3689/* Enum values, see field(s): */
3690/* MC_CMD_GET_LOOPBACK_MODES/MC_CMD_GET_LOOPBACK_MODES_OUT/100M */
3691#define MC_CMD_GET_LINK_OUT_V2_FLAGS_OFST 16
3692#define MC_CMD_GET_LINK_OUT_V2_FLAGS_LEN 4
3693#define MC_CMD_GET_LINK_OUT_V2_LINK_UP_LBN 0
3694#define MC_CMD_GET_LINK_OUT_V2_LINK_UP_WIDTH 1
3695#define MC_CMD_GET_LINK_OUT_V2_FULL_DUPLEX_LBN 1
3696#define MC_CMD_GET_LINK_OUT_V2_FULL_DUPLEX_WIDTH 1
3697#define MC_CMD_GET_LINK_OUT_V2_BPX_LINK_LBN 2
3698#define MC_CMD_GET_LINK_OUT_V2_BPX_LINK_WIDTH 1
3699#define MC_CMD_GET_LINK_OUT_V2_PHY_LINK_LBN 3
3700#define MC_CMD_GET_LINK_OUT_V2_PHY_LINK_WIDTH 1
3701#define MC_CMD_GET_LINK_OUT_V2_LINK_FAULT_RX_LBN 6
3702#define MC_CMD_GET_LINK_OUT_V2_LINK_FAULT_RX_WIDTH 1
3703#define MC_CMD_GET_LINK_OUT_V2_LINK_FAULT_TX_LBN 7
3704#define MC_CMD_GET_LINK_OUT_V2_LINK_FAULT_TX_WIDTH 1
3705/* This returns the negotiated flow control value. */
3706#define MC_CMD_GET_LINK_OUT_V2_FCNTL_OFST 20
3707#define MC_CMD_GET_LINK_OUT_V2_FCNTL_LEN 4
3708/* Enum values, see field(s): */
3709/* MC_CMD_SET_MAC/MC_CMD_SET_MAC_IN/FCNTL */
3710#define MC_CMD_GET_LINK_OUT_V2_MAC_FAULT_OFST 24
3711#define MC_CMD_GET_LINK_OUT_V2_MAC_FAULT_LEN 4
3712/* MC_CMD_MAC_FAULT_XGMII_LOCAL_LBN 0 */
3713/* MC_CMD_MAC_FAULT_XGMII_LOCAL_WIDTH 1 */
3714/* MC_CMD_MAC_FAULT_XGMII_REMOTE_LBN 1 */
3715/* MC_CMD_MAC_FAULT_XGMII_REMOTE_WIDTH 1 */
3716/* MC_CMD_MAC_FAULT_SGMII_REMOTE_LBN 2 */
3717/* MC_CMD_MAC_FAULT_SGMII_REMOTE_WIDTH 1 */
3718/* MC_CMD_MAC_FAULT_PENDING_RECONFIG_LBN 3 */
3719/* MC_CMD_MAC_FAULT_PENDING_RECONFIG_WIDTH 1 */
3720/* True local device capabilities (taking into account currently used PMD/MDI,
3721 * e.g. plugged-in module). In general, subset of
3722 * MC_CMD_GET_PHY_CFG_OUT/SUPPORTED_CAP, but may include extra _FEC_REQUEST
3723 * bits, if the PMD requires FEC. 0 if unknown (e.g. module unplugged). Equal
3724 * to SUPPORTED_CAP for non-pluggable PMDs. Refer to
3725 * MC_CMD_GET_PHY_CFG_OUT/SUPPORTED_CAP for bit definitions.
3726 */
3727#define MC_CMD_GET_LINK_OUT_V2_LD_CAP_OFST 28
3728#define MC_CMD_GET_LINK_OUT_V2_LD_CAP_LEN 4
3729/* Auto-negotiation type used on the link */
3730#define MC_CMD_GET_LINK_OUT_V2_AN_TYPE_OFST 32
3731#define MC_CMD_GET_LINK_OUT_V2_AN_TYPE_LEN 4
3732/* Enum values, see field(s): */
3733/* AN_TYPE/TYPE */
3734/* Forward error correction used on the link */
3735#define MC_CMD_GET_LINK_OUT_V2_FEC_TYPE_OFST 36
3736#define MC_CMD_GET_LINK_OUT_V2_FEC_TYPE_LEN 4
3737/* Enum values, see field(s): */
3738/* FEC_TYPE/TYPE */
3739#define MC_CMD_GET_LINK_OUT_V2_EXT_FLAGS_OFST 40
3740#define MC_CMD_GET_LINK_OUT_V2_EXT_FLAGS_LEN 4
3741#define MC_CMD_GET_LINK_OUT_V2_PMD_MDI_CONNECTED_LBN 0
3742#define MC_CMD_GET_LINK_OUT_V2_PMD_MDI_CONNECTED_WIDTH 1
3743#define MC_CMD_GET_LINK_OUT_V2_PMD_READY_LBN 1
3744#define MC_CMD_GET_LINK_OUT_V2_PMD_READY_WIDTH 1
3745#define MC_CMD_GET_LINK_OUT_V2_PMD_LINK_UP_LBN 2
3746#define MC_CMD_GET_LINK_OUT_V2_PMD_LINK_UP_WIDTH 1
3747#define MC_CMD_GET_LINK_OUT_V2_PMA_LINK_UP_LBN 3
3748#define MC_CMD_GET_LINK_OUT_V2_PMA_LINK_UP_WIDTH 1
3749#define MC_CMD_GET_LINK_OUT_V2_PCS_LOCK_LBN 4
3750#define MC_CMD_GET_LINK_OUT_V2_PCS_LOCK_WIDTH 1
3751#define MC_CMD_GET_LINK_OUT_V2_ALIGN_LOCK_LBN 5
3752#define MC_CMD_GET_LINK_OUT_V2_ALIGN_LOCK_WIDTH 1
3753#define MC_CMD_GET_LINK_OUT_V2_HI_BER_LBN 6
3754#define MC_CMD_GET_LINK_OUT_V2_HI_BER_WIDTH 1
3755#define MC_CMD_GET_LINK_OUT_V2_FEC_LOCK_LBN 7
3756#define MC_CMD_GET_LINK_OUT_V2_FEC_LOCK_WIDTH 1
3757#define MC_CMD_GET_LINK_OUT_V2_AN_DONE_LBN 8
3758#define MC_CMD_GET_LINK_OUT_V2_AN_DONE_WIDTH 1
3759
3601 3760
3602/***********************************/ 3761/***********************************/
3603/* MC_CMD_SET_LINK 3762/* MC_CMD_SET_LINK
@@ -3610,7 +3769,9 @@
3610 3769
3611/* MC_CMD_SET_LINK_IN msgrequest */ 3770/* MC_CMD_SET_LINK_IN msgrequest */
3612#define MC_CMD_SET_LINK_IN_LEN 16 3771#define MC_CMD_SET_LINK_IN_LEN 16
3613/* ??? */ 3772/* Near-side advertised capabilities. Refer to
3773 * MC_CMD_GET_PHY_CFG_OUT/SUPPORTED_CAP for bit definitions.
3774 */
3614#define MC_CMD_SET_LINK_IN_CAP_OFST 0 3775#define MC_CMD_SET_LINK_IN_CAP_OFST 0
3615#define MC_CMD_SET_LINK_IN_CAP_LEN 4 3776#define MC_CMD_SET_LINK_IN_CAP_LEN 4
3616/* Flags */ 3777/* Flags */
@@ -3650,9 +3811,9 @@
3650/* Set LED state. */ 3811/* Set LED state. */
3651#define MC_CMD_SET_ID_LED_IN_STATE_OFST 0 3812#define MC_CMD_SET_ID_LED_IN_STATE_OFST 0
3652#define MC_CMD_SET_ID_LED_IN_STATE_LEN 4 3813#define MC_CMD_SET_ID_LED_IN_STATE_LEN 4
3653#define MC_CMD_LED_OFF 0x0 /* enum */ 3814#define MC_CMD_LED_OFF 0x0 /* enum */
3654#define MC_CMD_LED_ON 0x1 /* enum */ 3815#define MC_CMD_LED_ON 0x1 /* enum */
3655#define MC_CMD_LED_DEFAULT 0x2 /* enum */ 3816#define MC_CMD_LED_DEFAULT 0x2 /* enum */
3656 3817
3657/* MC_CMD_SET_ID_LED_OUT msgresponse */ 3818/* MC_CMD_SET_ID_LED_OUT msgresponse */
3658#define MC_CMD_SET_ID_LED_OUT_LEN 0 3819#define MC_CMD_SET_ID_LED_OUT_LEN 0
@@ -3802,53 +3963,53 @@
3802#define MC_CMD_PHY_STATS_OUT_NO_DMA_STATISTICS_LEN 4 3963#define MC_CMD_PHY_STATS_OUT_NO_DMA_STATISTICS_LEN 4
3803#define MC_CMD_PHY_STATS_OUT_NO_DMA_STATISTICS_NUM MC_CMD_PHY_NSTATS 3964#define MC_CMD_PHY_STATS_OUT_NO_DMA_STATISTICS_NUM MC_CMD_PHY_NSTATS
3804/* enum: OUI. */ 3965/* enum: OUI. */
3805#define MC_CMD_OUI 0x0 3966#define MC_CMD_OUI 0x0
3806/* enum: PMA-PMD Link Up. */ 3967/* enum: PMA-PMD Link Up. */
3807#define MC_CMD_PMA_PMD_LINK_UP 0x1 3968#define MC_CMD_PMA_PMD_LINK_UP 0x1
3808/* enum: PMA-PMD RX Fault. */ 3969/* enum: PMA-PMD RX Fault. */
3809#define MC_CMD_PMA_PMD_RX_FAULT 0x2 3970#define MC_CMD_PMA_PMD_RX_FAULT 0x2
3810/* enum: PMA-PMD TX Fault. */ 3971/* enum: PMA-PMD TX Fault. */
3811#define MC_CMD_PMA_PMD_TX_FAULT 0x3 3972#define MC_CMD_PMA_PMD_TX_FAULT 0x3
3812/* enum: PMA-PMD Signal */ 3973/* enum: PMA-PMD Signal */
3813#define MC_CMD_PMA_PMD_SIGNAL 0x4 3974#define MC_CMD_PMA_PMD_SIGNAL 0x4
3814/* enum: PMA-PMD SNR A. */ 3975/* enum: PMA-PMD SNR A. */
3815#define MC_CMD_PMA_PMD_SNR_A 0x5 3976#define MC_CMD_PMA_PMD_SNR_A 0x5
3816/* enum: PMA-PMD SNR B. */ 3977/* enum: PMA-PMD SNR B. */
3817#define MC_CMD_PMA_PMD_SNR_B 0x6 3978#define MC_CMD_PMA_PMD_SNR_B 0x6
3818/* enum: PMA-PMD SNR C. */ 3979/* enum: PMA-PMD SNR C. */
3819#define MC_CMD_PMA_PMD_SNR_C 0x7 3980#define MC_CMD_PMA_PMD_SNR_C 0x7
3820/* enum: PMA-PMD SNR D. */ 3981/* enum: PMA-PMD SNR D. */
3821#define MC_CMD_PMA_PMD_SNR_D 0x8 3982#define MC_CMD_PMA_PMD_SNR_D 0x8
3822/* enum: PCS Link Up. */ 3983/* enum: PCS Link Up. */
3823#define MC_CMD_PCS_LINK_UP 0x9 3984#define MC_CMD_PCS_LINK_UP 0x9
3824/* enum: PCS RX Fault. */ 3985/* enum: PCS RX Fault. */
3825#define MC_CMD_PCS_RX_FAULT 0xa 3986#define MC_CMD_PCS_RX_FAULT 0xa
3826/* enum: PCS TX Fault. */ 3987/* enum: PCS TX Fault. */
3827#define MC_CMD_PCS_TX_FAULT 0xb 3988#define MC_CMD_PCS_TX_FAULT 0xb
3828/* enum: PCS BER. */ 3989/* enum: PCS BER. */
3829#define MC_CMD_PCS_BER 0xc 3990#define MC_CMD_PCS_BER 0xc
3830/* enum: PCS Block Errors. */ 3991/* enum: PCS Block Errors. */
3831#define MC_CMD_PCS_BLOCK_ERRORS 0xd 3992#define MC_CMD_PCS_BLOCK_ERRORS 0xd
3832/* enum: PhyXS Link Up. */ 3993/* enum: PhyXS Link Up. */
3833#define MC_CMD_PHYXS_LINK_UP 0xe 3994#define MC_CMD_PHYXS_LINK_UP 0xe
3834/* enum: PhyXS RX Fault. */ 3995/* enum: PhyXS RX Fault. */
3835#define MC_CMD_PHYXS_RX_FAULT 0xf 3996#define MC_CMD_PHYXS_RX_FAULT 0xf
3836/* enum: PhyXS TX Fault. */ 3997/* enum: PhyXS TX Fault. */
3837#define MC_CMD_PHYXS_TX_FAULT 0x10 3998#define MC_CMD_PHYXS_TX_FAULT 0x10
3838/* enum: PhyXS Align. */ 3999/* enum: PhyXS Align. */
3839#define MC_CMD_PHYXS_ALIGN 0x11 4000#define MC_CMD_PHYXS_ALIGN 0x11
3840/* enum: PhyXS Sync. */ 4001/* enum: PhyXS Sync. */
3841#define MC_CMD_PHYXS_SYNC 0x12 4002#define MC_CMD_PHYXS_SYNC 0x12
3842/* enum: AN link-up. */ 4003/* enum: AN link-up. */
3843#define MC_CMD_AN_LINK_UP 0x13 4004#define MC_CMD_AN_LINK_UP 0x13
3844/* enum: AN Complete. */ 4005/* enum: AN Complete. */
3845#define MC_CMD_AN_COMPLETE 0x14 4006#define MC_CMD_AN_COMPLETE 0x14
3846/* enum: AN 10GBaseT Status. */ 4007/* enum: AN 10GBaseT Status. */
3847#define MC_CMD_AN_10GBT_STATUS 0x15 4008#define MC_CMD_AN_10GBT_STATUS 0x15
3848/* enum: Clause 22 Link-Up. */ 4009/* enum: Clause 22 Link-Up. */
3849#define MC_CMD_CL22_LINK_UP 0x16 4010#define MC_CMD_CL22_LINK_UP 0x16
3850/* enum: (Last entry) */ 4011/* enum: (Last entry) */
3851#define MC_CMD_PHY_NSTATS 0x17 4012#define MC_CMD_PHY_NSTATS 0x17
3852 4013
3853 4014
3854/***********************************/ 4015/***********************************/
@@ -3910,139 +4071,139 @@
3910#define MC_CMD_MAC_STATS_OUT_NO_DMA_STATISTICS_LO_OFST 0 4071#define MC_CMD_MAC_STATS_OUT_NO_DMA_STATISTICS_LO_OFST 0
3911#define MC_CMD_MAC_STATS_OUT_NO_DMA_STATISTICS_HI_OFST 4 4072#define MC_CMD_MAC_STATS_OUT_NO_DMA_STATISTICS_HI_OFST 4
3912#define MC_CMD_MAC_STATS_OUT_NO_DMA_STATISTICS_NUM MC_CMD_MAC_NSTATS 4073#define MC_CMD_MAC_STATS_OUT_NO_DMA_STATISTICS_NUM MC_CMD_MAC_NSTATS
3913#define MC_CMD_MAC_GENERATION_START 0x0 /* enum */ 4074#define MC_CMD_MAC_GENERATION_START 0x0 /* enum */
3914#define MC_CMD_MAC_DMABUF_START 0x1 /* enum */ 4075#define MC_CMD_MAC_DMABUF_START 0x1 /* enum */
3915#define MC_CMD_MAC_TX_PKTS 0x1 /* enum */ 4076#define MC_CMD_MAC_TX_PKTS 0x1 /* enum */
3916#define MC_CMD_MAC_TX_PAUSE_PKTS 0x2 /* enum */ 4077#define MC_CMD_MAC_TX_PAUSE_PKTS 0x2 /* enum */
3917#define MC_CMD_MAC_TX_CONTROL_PKTS 0x3 /* enum */ 4078#define MC_CMD_MAC_TX_CONTROL_PKTS 0x3 /* enum */
3918#define MC_CMD_MAC_TX_UNICAST_PKTS 0x4 /* enum */ 4079#define MC_CMD_MAC_TX_UNICAST_PKTS 0x4 /* enum */
3919#define MC_CMD_MAC_TX_MULTICAST_PKTS 0x5 /* enum */ 4080#define MC_CMD_MAC_TX_MULTICAST_PKTS 0x5 /* enum */
3920#define MC_CMD_MAC_TX_BROADCAST_PKTS 0x6 /* enum */ 4081#define MC_CMD_MAC_TX_BROADCAST_PKTS 0x6 /* enum */
3921#define MC_CMD_MAC_TX_BYTES 0x7 /* enum */ 4082#define MC_CMD_MAC_TX_BYTES 0x7 /* enum */
3922#define MC_CMD_MAC_TX_BAD_BYTES 0x8 /* enum */ 4083#define MC_CMD_MAC_TX_BAD_BYTES 0x8 /* enum */
3923#define MC_CMD_MAC_TX_LT64_PKTS 0x9 /* enum */ 4084#define MC_CMD_MAC_TX_LT64_PKTS 0x9 /* enum */
3924#define MC_CMD_MAC_TX_64_PKTS 0xa /* enum */ 4085#define MC_CMD_MAC_TX_64_PKTS 0xa /* enum */
3925#define MC_CMD_MAC_TX_65_TO_127_PKTS 0xb /* enum */ 4086#define MC_CMD_MAC_TX_65_TO_127_PKTS 0xb /* enum */
3926#define MC_CMD_MAC_TX_128_TO_255_PKTS 0xc /* enum */ 4087#define MC_CMD_MAC_TX_128_TO_255_PKTS 0xc /* enum */
3927#define MC_CMD_MAC_TX_256_TO_511_PKTS 0xd /* enum */ 4088#define MC_CMD_MAC_TX_256_TO_511_PKTS 0xd /* enum */
3928#define MC_CMD_MAC_TX_512_TO_1023_PKTS 0xe /* enum */ 4089#define MC_CMD_MAC_TX_512_TO_1023_PKTS 0xe /* enum */
3929#define MC_CMD_MAC_TX_1024_TO_15XX_PKTS 0xf /* enum */ 4090#define MC_CMD_MAC_TX_1024_TO_15XX_PKTS 0xf /* enum */
3930#define MC_CMD_MAC_TX_15XX_TO_JUMBO_PKTS 0x10 /* enum */ 4091#define MC_CMD_MAC_TX_15XX_TO_JUMBO_PKTS 0x10 /* enum */
3931#define MC_CMD_MAC_TX_GTJUMBO_PKTS 0x11 /* enum */ 4092#define MC_CMD_MAC_TX_GTJUMBO_PKTS 0x11 /* enum */
3932#define MC_CMD_MAC_TX_BAD_FCS_PKTS 0x12 /* enum */ 4093#define MC_CMD_MAC_TX_BAD_FCS_PKTS 0x12 /* enum */
3933#define MC_CMD_MAC_TX_SINGLE_COLLISION_PKTS 0x13 /* enum */ 4094#define MC_CMD_MAC_TX_SINGLE_COLLISION_PKTS 0x13 /* enum */
3934#define MC_CMD_MAC_TX_MULTIPLE_COLLISION_PKTS 0x14 /* enum */ 4095#define MC_CMD_MAC_TX_MULTIPLE_COLLISION_PKTS 0x14 /* enum */
3935#define MC_CMD_MAC_TX_EXCESSIVE_COLLISION_PKTS 0x15 /* enum */ 4096#define MC_CMD_MAC_TX_EXCESSIVE_COLLISION_PKTS 0x15 /* enum */
3936#define MC_CMD_MAC_TX_LATE_COLLISION_PKTS 0x16 /* enum */ 4097#define MC_CMD_MAC_TX_LATE_COLLISION_PKTS 0x16 /* enum */
3937#define MC_CMD_MAC_TX_DEFERRED_PKTS 0x17 /* enum */ 4098#define MC_CMD_MAC_TX_DEFERRED_PKTS 0x17 /* enum */
3938#define MC_CMD_MAC_TX_EXCESSIVE_DEFERRED_PKTS 0x18 /* enum */ 4099#define MC_CMD_MAC_TX_EXCESSIVE_DEFERRED_PKTS 0x18 /* enum */
3939#define MC_CMD_MAC_TX_NON_TCPUDP_PKTS 0x19 /* enum */ 4100#define MC_CMD_MAC_TX_NON_TCPUDP_PKTS 0x19 /* enum */
3940#define MC_CMD_MAC_TX_MAC_SRC_ERR_PKTS 0x1a /* enum */ 4101#define MC_CMD_MAC_TX_MAC_SRC_ERR_PKTS 0x1a /* enum */
3941#define MC_CMD_MAC_TX_IP_SRC_ERR_PKTS 0x1b /* enum */ 4102#define MC_CMD_MAC_TX_IP_SRC_ERR_PKTS 0x1b /* enum */
3942#define MC_CMD_MAC_RX_PKTS 0x1c /* enum */ 4103#define MC_CMD_MAC_RX_PKTS 0x1c /* enum */
3943#define MC_CMD_MAC_RX_PAUSE_PKTS 0x1d /* enum */ 4104#define MC_CMD_MAC_RX_PAUSE_PKTS 0x1d /* enum */
3944#define MC_CMD_MAC_RX_GOOD_PKTS 0x1e /* enum */ 4105#define MC_CMD_MAC_RX_GOOD_PKTS 0x1e /* enum */
3945#define MC_CMD_MAC_RX_CONTROL_PKTS 0x1f /* enum */ 4106#define MC_CMD_MAC_RX_CONTROL_PKTS 0x1f /* enum */
3946#define MC_CMD_MAC_RX_UNICAST_PKTS 0x20 /* enum */ 4107#define MC_CMD_MAC_RX_UNICAST_PKTS 0x20 /* enum */
3947#define MC_CMD_MAC_RX_MULTICAST_PKTS 0x21 /* enum */ 4108#define MC_CMD_MAC_RX_MULTICAST_PKTS 0x21 /* enum */
3948#define MC_CMD_MAC_RX_BROADCAST_PKTS 0x22 /* enum */ 4109#define MC_CMD_MAC_RX_BROADCAST_PKTS 0x22 /* enum */
3949#define MC_CMD_MAC_RX_BYTES 0x23 /* enum */ 4110#define MC_CMD_MAC_RX_BYTES 0x23 /* enum */
3950#define MC_CMD_MAC_RX_BAD_BYTES 0x24 /* enum */ 4111#define MC_CMD_MAC_RX_BAD_BYTES 0x24 /* enum */
3951#define MC_CMD_MAC_RX_64_PKTS 0x25 /* enum */ 4112#define MC_CMD_MAC_RX_64_PKTS 0x25 /* enum */
3952#define MC_CMD_MAC_RX_65_TO_127_PKTS 0x26 /* enum */ 4113#define MC_CMD_MAC_RX_65_TO_127_PKTS 0x26 /* enum */
3953#define MC_CMD_MAC_RX_128_TO_255_PKTS 0x27 /* enum */ 4114#define MC_CMD_MAC_RX_128_TO_255_PKTS 0x27 /* enum */
3954#define MC_CMD_MAC_RX_256_TO_511_PKTS 0x28 /* enum */ 4115#define MC_CMD_MAC_RX_256_TO_511_PKTS 0x28 /* enum */
3955#define MC_CMD_MAC_RX_512_TO_1023_PKTS 0x29 /* enum */ 4116#define MC_CMD_MAC_RX_512_TO_1023_PKTS 0x29 /* enum */
3956#define MC_CMD_MAC_RX_1024_TO_15XX_PKTS 0x2a /* enum */ 4117#define MC_CMD_MAC_RX_1024_TO_15XX_PKTS 0x2a /* enum */
3957#define MC_CMD_MAC_RX_15XX_TO_JUMBO_PKTS 0x2b /* enum */ 4118#define MC_CMD_MAC_RX_15XX_TO_JUMBO_PKTS 0x2b /* enum */
3958#define MC_CMD_MAC_RX_GTJUMBO_PKTS 0x2c /* enum */ 4119#define MC_CMD_MAC_RX_GTJUMBO_PKTS 0x2c /* enum */
3959#define MC_CMD_MAC_RX_UNDERSIZE_PKTS 0x2d /* enum */ 4120#define MC_CMD_MAC_RX_UNDERSIZE_PKTS 0x2d /* enum */
3960#define MC_CMD_MAC_RX_BAD_FCS_PKTS 0x2e /* enum */ 4121#define MC_CMD_MAC_RX_BAD_FCS_PKTS 0x2e /* enum */
3961#define MC_CMD_MAC_RX_OVERFLOW_PKTS 0x2f /* enum */ 4122#define MC_CMD_MAC_RX_OVERFLOW_PKTS 0x2f /* enum */
3962#define MC_CMD_MAC_RX_FALSE_CARRIER_PKTS 0x30 /* enum */ 4123#define MC_CMD_MAC_RX_FALSE_CARRIER_PKTS 0x30 /* enum */
3963#define MC_CMD_MAC_RX_SYMBOL_ERROR_PKTS 0x31 /* enum */ 4124#define MC_CMD_MAC_RX_SYMBOL_ERROR_PKTS 0x31 /* enum */
3964#define MC_CMD_MAC_RX_ALIGN_ERROR_PKTS 0x32 /* enum */ 4125#define MC_CMD_MAC_RX_ALIGN_ERROR_PKTS 0x32 /* enum */
3965#define MC_CMD_MAC_RX_LENGTH_ERROR_PKTS 0x33 /* enum */ 4126#define MC_CMD_MAC_RX_LENGTH_ERROR_PKTS 0x33 /* enum */
3966#define MC_CMD_MAC_RX_INTERNAL_ERROR_PKTS 0x34 /* enum */ 4127#define MC_CMD_MAC_RX_INTERNAL_ERROR_PKTS 0x34 /* enum */
3967#define MC_CMD_MAC_RX_JABBER_PKTS 0x35 /* enum */ 4128#define MC_CMD_MAC_RX_JABBER_PKTS 0x35 /* enum */
3968#define MC_CMD_MAC_RX_NODESC_DROPS 0x36 /* enum */ 4129#define MC_CMD_MAC_RX_NODESC_DROPS 0x36 /* enum */
3969#define MC_CMD_MAC_RX_LANES01_CHAR_ERR 0x37 /* enum */ 4130#define MC_CMD_MAC_RX_LANES01_CHAR_ERR 0x37 /* enum */
3970#define MC_CMD_MAC_RX_LANES23_CHAR_ERR 0x38 /* enum */ 4131#define MC_CMD_MAC_RX_LANES23_CHAR_ERR 0x38 /* enum */
3971#define MC_CMD_MAC_RX_LANES01_DISP_ERR 0x39 /* enum */ 4132#define MC_CMD_MAC_RX_LANES01_DISP_ERR 0x39 /* enum */
3972#define MC_CMD_MAC_RX_LANES23_DISP_ERR 0x3a /* enum */ 4133#define MC_CMD_MAC_RX_LANES23_DISP_ERR 0x3a /* enum */
3973#define MC_CMD_MAC_RX_MATCH_FAULT 0x3b /* enum */ 4134#define MC_CMD_MAC_RX_MATCH_FAULT 0x3b /* enum */
3974/* enum: PM trunc_bb_overflow counter. Valid for EF10 with PM_AND_RXDP_COUNTERS 4135/* enum: PM trunc_bb_overflow counter. Valid for EF10 with PM_AND_RXDP_COUNTERS
3975 * capability only. 4136 * capability only.
3976 */ 4137 */
3977#define MC_CMD_MAC_PM_TRUNC_BB_OVERFLOW 0x3c 4138#define MC_CMD_MAC_PM_TRUNC_BB_OVERFLOW 0x3c
3978/* enum: PM discard_bb_overflow counter. Valid for EF10 with 4139/* enum: PM discard_bb_overflow counter. Valid for EF10 with
3979 * PM_AND_RXDP_COUNTERS capability only. 4140 * PM_AND_RXDP_COUNTERS capability only.
3980 */ 4141 */
3981#define MC_CMD_MAC_PM_DISCARD_BB_OVERFLOW 0x3d 4142#define MC_CMD_MAC_PM_DISCARD_BB_OVERFLOW 0x3d
3982/* enum: PM trunc_vfifo_full counter. Valid for EF10 with PM_AND_RXDP_COUNTERS 4143/* enum: PM trunc_vfifo_full counter. Valid for EF10 with PM_AND_RXDP_COUNTERS
3983 * capability only. 4144 * capability only.
3984 */ 4145 */
3985#define MC_CMD_MAC_PM_TRUNC_VFIFO_FULL 0x3e 4146#define MC_CMD_MAC_PM_TRUNC_VFIFO_FULL 0x3e
3986/* enum: PM discard_vfifo_full counter. Valid for EF10 with 4147/* enum: PM discard_vfifo_full counter. Valid for EF10 with
3987 * PM_AND_RXDP_COUNTERS capability only. 4148 * PM_AND_RXDP_COUNTERS capability only.
3988 */ 4149 */
3989#define MC_CMD_MAC_PM_DISCARD_VFIFO_FULL 0x3f 4150#define MC_CMD_MAC_PM_DISCARD_VFIFO_FULL 0x3f
3990/* enum: PM trunc_qbb counter. Valid for EF10 with PM_AND_RXDP_COUNTERS 4151/* enum: PM trunc_qbb counter. Valid for EF10 with PM_AND_RXDP_COUNTERS
3991 * capability only. 4152 * capability only.
3992 */ 4153 */
3993#define MC_CMD_MAC_PM_TRUNC_QBB 0x40 4154#define MC_CMD_MAC_PM_TRUNC_QBB 0x40
3994/* enum: PM discard_qbb counter. Valid for EF10 with PM_AND_RXDP_COUNTERS 4155/* enum: PM discard_qbb counter. Valid for EF10 with PM_AND_RXDP_COUNTERS
3995 * capability only. 4156 * capability only.
3996 */ 4157 */
3997#define MC_CMD_MAC_PM_DISCARD_QBB 0x41 4158#define MC_CMD_MAC_PM_DISCARD_QBB 0x41
3998/* enum: PM discard_mapping counter. Valid for EF10 with PM_AND_RXDP_COUNTERS 4159/* enum: PM discard_mapping counter. Valid for EF10 with PM_AND_RXDP_COUNTERS
3999 * capability only. 4160 * capability only.
4000 */ 4161 */
4001#define MC_CMD_MAC_PM_DISCARD_MAPPING 0x42 4162#define MC_CMD_MAC_PM_DISCARD_MAPPING 0x42
4002/* enum: RXDP counter: Number of packets dropped due to the queue being 4163/* enum: RXDP counter: Number of packets dropped due to the queue being
4003 * disabled. Valid for EF10 with PM_AND_RXDP_COUNTERS capability only. 4164 * disabled. Valid for EF10 with PM_AND_RXDP_COUNTERS capability only.
4004 */ 4165 */
4005#define MC_CMD_MAC_RXDP_Q_DISABLED_PKTS 0x43 4166#define MC_CMD_MAC_RXDP_Q_DISABLED_PKTS 0x43
4006/* enum: RXDP counter: Number of packets dropped by the DICPU. Valid for EF10 4167/* enum: RXDP counter: Number of packets dropped by the DICPU. Valid for EF10
4007 * with PM_AND_RXDP_COUNTERS capability only. 4168 * with PM_AND_RXDP_COUNTERS capability only.
4008 */ 4169 */
4009#define MC_CMD_MAC_RXDP_DI_DROPPED_PKTS 0x45 4170#define MC_CMD_MAC_RXDP_DI_DROPPED_PKTS 0x45
4010/* enum: RXDP counter: Number of non-host packets. Valid for EF10 with 4171/* enum: RXDP counter: Number of non-host packets. Valid for EF10 with
4011 * PM_AND_RXDP_COUNTERS capability only. 4172 * PM_AND_RXDP_COUNTERS capability only.
4012 */ 4173 */
4013#define MC_CMD_MAC_RXDP_STREAMING_PKTS 0x46 4174#define MC_CMD_MAC_RXDP_STREAMING_PKTS 0x46
4014/* enum: RXDP counter: Number of times an hlb descriptor fetch was performed. 4175/* enum: RXDP counter: Number of times an hlb descriptor fetch was performed.
4015 * Valid for EF10 with PM_AND_RXDP_COUNTERS capability only. 4176 * Valid for EF10 with PM_AND_RXDP_COUNTERS capability only.
4016 */ 4177 */
4017#define MC_CMD_MAC_RXDP_HLB_FETCH_CONDITIONS 0x47 4178#define MC_CMD_MAC_RXDP_HLB_FETCH_CONDITIONS 0x47
4018/* enum: RXDP counter: Number of times the DPCPU waited for an existing 4179/* enum: RXDP counter: Number of times the DPCPU waited for an existing
4019 * descriptor fetch. Valid for EF10 with PM_AND_RXDP_COUNTERS capability only. 4180 * descriptor fetch. Valid for EF10 with PM_AND_RXDP_COUNTERS capability only.
4020 */ 4181 */
4021#define MC_CMD_MAC_RXDP_HLB_WAIT_CONDITIONS 0x48 4182#define MC_CMD_MAC_RXDP_HLB_WAIT_CONDITIONS 0x48
4022#define MC_CMD_MAC_VADAPTER_RX_DMABUF_START 0x4c /* enum */ 4183#define MC_CMD_MAC_VADAPTER_RX_DMABUF_START 0x4c /* enum */
4023#define MC_CMD_MAC_VADAPTER_RX_UNICAST_PACKETS 0x4c /* enum */ 4184#define MC_CMD_MAC_VADAPTER_RX_UNICAST_PACKETS 0x4c /* enum */
4024#define MC_CMD_MAC_VADAPTER_RX_UNICAST_BYTES 0x4d /* enum */ 4185#define MC_CMD_MAC_VADAPTER_RX_UNICAST_BYTES 0x4d /* enum */
4025#define MC_CMD_MAC_VADAPTER_RX_MULTICAST_PACKETS 0x4e /* enum */ 4186#define MC_CMD_MAC_VADAPTER_RX_MULTICAST_PACKETS 0x4e /* enum */
4026#define MC_CMD_MAC_VADAPTER_RX_MULTICAST_BYTES 0x4f /* enum */ 4187#define MC_CMD_MAC_VADAPTER_RX_MULTICAST_BYTES 0x4f /* enum */
4027#define MC_CMD_MAC_VADAPTER_RX_BROADCAST_PACKETS 0x50 /* enum */ 4188#define MC_CMD_MAC_VADAPTER_RX_BROADCAST_PACKETS 0x50 /* enum */
4028#define MC_CMD_MAC_VADAPTER_RX_BROADCAST_BYTES 0x51 /* enum */ 4189#define MC_CMD_MAC_VADAPTER_RX_BROADCAST_BYTES 0x51 /* enum */
4029#define MC_CMD_MAC_VADAPTER_RX_BAD_PACKETS 0x52 /* enum */ 4190#define MC_CMD_MAC_VADAPTER_RX_BAD_PACKETS 0x52 /* enum */
4030#define MC_CMD_MAC_VADAPTER_RX_BAD_BYTES 0x53 /* enum */ 4191#define MC_CMD_MAC_VADAPTER_RX_BAD_BYTES 0x53 /* enum */
4031#define MC_CMD_MAC_VADAPTER_RX_OVERFLOW 0x54 /* enum */ 4192#define MC_CMD_MAC_VADAPTER_RX_OVERFLOW 0x54 /* enum */
4032#define MC_CMD_MAC_VADAPTER_TX_DMABUF_START 0x57 /* enum */ 4193#define MC_CMD_MAC_VADAPTER_TX_DMABUF_START 0x57 /* enum */
4033#define MC_CMD_MAC_VADAPTER_TX_UNICAST_PACKETS 0x57 /* enum */ 4194#define MC_CMD_MAC_VADAPTER_TX_UNICAST_PACKETS 0x57 /* enum */
4034#define MC_CMD_MAC_VADAPTER_TX_UNICAST_BYTES 0x58 /* enum */ 4195#define MC_CMD_MAC_VADAPTER_TX_UNICAST_BYTES 0x58 /* enum */
4035#define MC_CMD_MAC_VADAPTER_TX_MULTICAST_PACKETS 0x59 /* enum */ 4196#define MC_CMD_MAC_VADAPTER_TX_MULTICAST_PACKETS 0x59 /* enum */
4036#define MC_CMD_MAC_VADAPTER_TX_MULTICAST_BYTES 0x5a /* enum */ 4197#define MC_CMD_MAC_VADAPTER_TX_MULTICAST_BYTES 0x5a /* enum */
4037#define MC_CMD_MAC_VADAPTER_TX_BROADCAST_PACKETS 0x5b /* enum */ 4198#define MC_CMD_MAC_VADAPTER_TX_BROADCAST_PACKETS 0x5b /* enum */
4038#define MC_CMD_MAC_VADAPTER_TX_BROADCAST_BYTES 0x5c /* enum */ 4199#define MC_CMD_MAC_VADAPTER_TX_BROADCAST_BYTES 0x5c /* enum */
4039#define MC_CMD_MAC_VADAPTER_TX_BAD_PACKETS 0x5d /* enum */ 4200#define MC_CMD_MAC_VADAPTER_TX_BAD_PACKETS 0x5d /* enum */
4040#define MC_CMD_MAC_VADAPTER_TX_BAD_BYTES 0x5e /* enum */ 4201#define MC_CMD_MAC_VADAPTER_TX_BAD_BYTES 0x5e /* enum */
4041#define MC_CMD_MAC_VADAPTER_TX_OVERFLOW 0x5f /* enum */ 4202#define MC_CMD_MAC_VADAPTER_TX_OVERFLOW 0x5f /* enum */
4042/* enum: Start of GMAC stats buffer space, for Siena only. */ 4203/* enum: Start of GMAC stats buffer space, for Siena only. */
4043#define MC_CMD_GMAC_DMABUF_START 0x40 4204#define MC_CMD_GMAC_DMABUF_START 0x40
4044/* enum: End of GMAC stats buffer space, for Siena only. */ 4205/* enum: End of GMAC stats buffer space, for Siena only. */
4045#define MC_CMD_GMAC_DMABUF_END 0x5f 4206#define MC_CMD_GMAC_DMABUF_END 0x5f
4046/* enum: GENERATION_END value, used together with GENERATION_START to verify 4207/* enum: GENERATION_END value, used together with GENERATION_START to verify
4047 * consistency of DMAd data. For legacy firmware / drivers without extended 4208 * consistency of DMAd data. For legacy firmware / drivers without extended
4048 * stats (more precisely, when DMA_LEN == MC_CMD_MAC_NSTATS * 4209 * stats (more precisely, when DMA_LEN == MC_CMD_MAC_NSTATS *
@@ -4054,7 +4215,7 @@
4054 * sizeof(uint64_t). See SF-109306-TC, Section 9.2 for details. 4215 * sizeof(uint64_t). See SF-109306-TC, Section 9.2 for details.
4055 */ 4216 */
4056#define MC_CMD_MAC_GENERATION_END 0x60 4217#define MC_CMD_MAC_GENERATION_END 0x60
4057#define MC_CMD_MAC_NSTATS 0x61 /* enum */ 4218#define MC_CMD_MAC_NSTATS 0x61 /* enum */
4058 4219
4059/* MC_CMD_MAC_STATS_V2_OUT_DMA msgresponse */ 4220/* MC_CMD_MAC_STATS_V2_OUT_DMA msgresponse */
4060#define MC_CMD_MAC_STATS_V2_OUT_DMA_LEN 0 4221#define MC_CMD_MAC_STATS_V2_OUT_DMA_LEN 0
@@ -4067,25 +4228,25 @@
4067#define MC_CMD_MAC_STATS_V2_OUT_NO_DMA_STATISTICS_HI_OFST 4 4228#define MC_CMD_MAC_STATS_V2_OUT_NO_DMA_STATISTICS_HI_OFST 4
4068#define MC_CMD_MAC_STATS_V2_OUT_NO_DMA_STATISTICS_NUM MC_CMD_MAC_NSTATS_V2 4229#define MC_CMD_MAC_STATS_V2_OUT_NO_DMA_STATISTICS_NUM MC_CMD_MAC_NSTATS_V2
4069/* enum: Start of FEC stats buffer space, Medford2 and up */ 4230/* enum: Start of FEC stats buffer space, Medford2 and up */
4070#define MC_CMD_MAC_FEC_DMABUF_START 0x61 4231#define MC_CMD_MAC_FEC_DMABUF_START 0x61
4071/* enum: Number of uncorrected FEC codewords on link (RS-FEC only for Medford2) 4232/* enum: Number of uncorrected FEC codewords on link (RS-FEC only for Medford2)
4072 */ 4233 */
4073#define MC_CMD_MAC_FEC_UNCORRECTED_ERRORS 0x61 4234#define MC_CMD_MAC_FEC_UNCORRECTED_ERRORS 0x61
4074/* enum: Number of corrected FEC codewords on link (RS-FEC only for Medford2) 4235/* enum: Number of corrected FEC codewords on link (RS-FEC only for Medford2)
4075 */ 4236 */
4076#define MC_CMD_MAC_FEC_CORRECTED_ERRORS 0x62 4237#define MC_CMD_MAC_FEC_CORRECTED_ERRORS 0x62
4077/* enum: Number of corrected 10-bit symbol errors, lane 0 (RS-FEC only) */ 4238/* enum: Number of corrected 10-bit symbol errors, lane 0 (RS-FEC only) */
4078#define MC_CMD_MAC_FEC_CORRECTED_SYMBOLS_LANE0 0x63 4239#define MC_CMD_MAC_FEC_CORRECTED_SYMBOLS_LANE0 0x63
4079/* enum: Number of corrected 10-bit symbol errors, lane 1 (RS-FEC only) */ 4240/* enum: Number of corrected 10-bit symbol errors, lane 1 (RS-FEC only) */
4080#define MC_CMD_MAC_FEC_CORRECTED_SYMBOLS_LANE1 0x64 4241#define MC_CMD_MAC_FEC_CORRECTED_SYMBOLS_LANE1 0x64
4081/* enum: Number of corrected 10-bit symbol errors, lane 2 (RS-FEC only) */ 4242/* enum: Number of corrected 10-bit symbol errors, lane 2 (RS-FEC only) */
4082#define MC_CMD_MAC_FEC_CORRECTED_SYMBOLS_LANE2 0x65 4243#define MC_CMD_MAC_FEC_CORRECTED_SYMBOLS_LANE2 0x65
4083/* enum: Number of corrected 10-bit symbol errors, lane 3 (RS-FEC only) */ 4244/* enum: Number of corrected 10-bit symbol errors, lane 3 (RS-FEC only) */
4084#define MC_CMD_MAC_FEC_CORRECTED_SYMBOLS_LANE3 0x66 4245#define MC_CMD_MAC_FEC_CORRECTED_SYMBOLS_LANE3 0x66
4085/* enum: This includes the space at offset 103 which is the final 4246/* enum: This includes the space at offset 103 which is the final
4086 * GENERATION_END in a MAC_STATS_V2 response and otherwise unused. 4247 * GENERATION_END in a MAC_STATS_V2 response and otherwise unused.
4087 */ 4248 */
4088#define MC_CMD_MAC_NSTATS_V2 0x68 4249#define MC_CMD_MAC_NSTATS_V2 0x68
4089/* Other enum values, see field(s): */ 4250/* Other enum values, see field(s): */
4090/* MC_CMD_MAC_STATS_OUT_NO_DMA/STATISTICS */ 4251/* MC_CMD_MAC_STATS_OUT_NO_DMA/STATISTICS */
4091 4252
@@ -4100,66 +4261,66 @@
4100#define MC_CMD_MAC_STATS_V3_OUT_NO_DMA_STATISTICS_HI_OFST 4 4261#define MC_CMD_MAC_STATS_V3_OUT_NO_DMA_STATISTICS_HI_OFST 4
4101#define MC_CMD_MAC_STATS_V3_OUT_NO_DMA_STATISTICS_NUM MC_CMD_MAC_NSTATS_V3 4262#define MC_CMD_MAC_STATS_V3_OUT_NO_DMA_STATISTICS_NUM MC_CMD_MAC_NSTATS_V3
4102/* enum: Start of CTPIO stats buffer space, Medford2 and up */ 4263/* enum: Start of CTPIO stats buffer space, Medford2 and up */
4103#define MC_CMD_MAC_CTPIO_DMABUF_START 0x68 4264#define MC_CMD_MAC_CTPIO_DMABUF_START 0x68
4104/* enum: Number of CTPIO fallbacks because a DMA packet was in progress on the 4265/* enum: Number of CTPIO fallbacks because a DMA packet was in progress on the
4105 * target VI 4266 * target VI
4106 */ 4267 */
4107#define MC_CMD_MAC_CTPIO_VI_BUSY_FALLBACK 0x68 4268#define MC_CMD_MAC_CTPIO_VI_BUSY_FALLBACK 0x68
4108/* enum: Number of times a CTPIO send wrote beyond frame end (informational 4269/* enum: Number of times a CTPIO send wrote beyond frame end (informational
4109 * only) 4270 * only)
4110 */ 4271 */
4111#define MC_CMD_MAC_CTPIO_LONG_WRITE_SUCCESS 0x69 4272#define MC_CMD_MAC_CTPIO_LONG_WRITE_SUCCESS 0x69
4112/* enum: Number of CTPIO failures because the TX doorbell was written before 4273/* enum: Number of CTPIO failures because the TX doorbell was written before
4113 * the end of the frame data 4274 * the end of the frame data
4114 */ 4275 */
4115#define MC_CMD_MAC_CTPIO_MISSING_DBELL_FAIL 0x6a 4276#define MC_CMD_MAC_CTPIO_MISSING_DBELL_FAIL 0x6a
4116/* enum: Number of CTPIO failures because the internal FIFO overflowed */ 4277/* enum: Number of CTPIO failures because the internal FIFO overflowed */
4117#define MC_CMD_MAC_CTPIO_OVERFLOW_FAIL 0x6b 4278#define MC_CMD_MAC_CTPIO_OVERFLOW_FAIL 0x6b
4118/* enum: Number of CTPIO failures because the host did not deliver data fast 4279/* enum: Number of CTPIO failures because the host did not deliver data fast
4119 * enough to avoid MAC underflow 4280 * enough to avoid MAC underflow
4120 */ 4281 */
4121#define MC_CMD_MAC_CTPIO_UNDERFLOW_FAIL 0x6c 4282#define MC_CMD_MAC_CTPIO_UNDERFLOW_FAIL 0x6c
4122/* enum: Number of CTPIO failures because the host did not deliver all the 4283/* enum: Number of CTPIO failures because the host did not deliver all the
4123 * frame data within the timeout 4284 * frame data within the timeout
4124 */ 4285 */
4125#define MC_CMD_MAC_CTPIO_TIMEOUT_FAIL 0x6d 4286#define MC_CMD_MAC_CTPIO_TIMEOUT_FAIL 0x6d
4126/* enum: Number of CTPIO failures because the frame data arrived out of order 4287/* enum: Number of CTPIO failures because the frame data arrived out of order
4127 * or with gaps 4288 * or with gaps
4128 */ 4289 */
4129#define MC_CMD_MAC_CTPIO_NONCONTIG_WR_FAIL 0x6e 4290#define MC_CMD_MAC_CTPIO_NONCONTIG_WR_FAIL 0x6e
4130/* enum: Number of CTPIO failures because the host started a new frame before 4291/* enum: Number of CTPIO failures because the host started a new frame before
4131 * completing the previous one 4292 * completing the previous one
4132 */ 4293 */
4133#define MC_CMD_MAC_CTPIO_FRM_CLOBBER_FAIL 0x6f 4294#define MC_CMD_MAC_CTPIO_FRM_CLOBBER_FAIL 0x6f
4134/* enum: Number of CTPIO failures because a write was not a multiple of 32 bits 4295/* enum: Number of CTPIO failures because a write was not a multiple of 32 bits
4135 * or not 32-bit aligned 4296 * or not 32-bit aligned
4136 */ 4297 */
4137#define MC_CMD_MAC_CTPIO_INVALID_WR_FAIL 0x70 4298#define MC_CMD_MAC_CTPIO_INVALID_WR_FAIL 0x70
4138/* enum: Number of CTPIO fallbacks because another VI on the same port was 4299/* enum: Number of CTPIO fallbacks because another VI on the same port was
4139 * sending a CTPIO frame 4300 * sending a CTPIO frame
4140 */ 4301 */
4141#define MC_CMD_MAC_CTPIO_VI_CLOBBER_FALLBACK 0x71 4302#define MC_CMD_MAC_CTPIO_VI_CLOBBER_FALLBACK 0x71
4142/* enum: Number of CTPIO fallbacks because target VI did not have CTPIO enabled 4303/* enum: Number of CTPIO fallbacks because target VI did not have CTPIO enabled
4143 */ 4304 */
4144#define MC_CMD_MAC_CTPIO_UNQUALIFIED_FALLBACK 0x72 4305#define MC_CMD_MAC_CTPIO_UNQUALIFIED_FALLBACK 0x72
4145/* enum: Number of CTPIO fallbacks because length in header was less than 29 4306/* enum: Number of CTPIO fallbacks because length in header was less than 29
4146 * bytes 4307 * bytes
4147 */ 4308 */
4148#define MC_CMD_MAC_CTPIO_RUNT_FALLBACK 0x73 4309#define MC_CMD_MAC_CTPIO_RUNT_FALLBACK 0x73
4149/* enum: Total number of successful CTPIO sends on this port */ 4310/* enum: Total number of successful CTPIO sends on this port */
4150#define MC_CMD_MAC_CTPIO_SUCCESS 0x74 4311#define MC_CMD_MAC_CTPIO_SUCCESS 0x74
4151/* enum: Total number of CTPIO fallbacks on this port */ 4312/* enum: Total number of CTPIO fallbacks on this port */
4152#define MC_CMD_MAC_CTPIO_FALLBACK 0x75 4313#define MC_CMD_MAC_CTPIO_FALLBACK 0x75
4153/* enum: Total number of CTPIO poisoned frames on this port, whether erased or 4314/* enum: Total number of CTPIO poisoned frames on this port, whether erased or
4154 * not 4315 * not
4155 */ 4316 */
4156#define MC_CMD_MAC_CTPIO_POISON 0x76 4317#define MC_CMD_MAC_CTPIO_POISON 0x76
4157/* enum: Total number of CTPIO erased frames on this port */ 4318/* enum: Total number of CTPIO erased frames on this port */
4158#define MC_CMD_MAC_CTPIO_ERASE 0x77 4319#define MC_CMD_MAC_CTPIO_ERASE 0x77
4159/* enum: This includes the space at offset 120 which is the final 4320/* enum: This includes the space at offset 120 which is the final
4160 * GENERATION_END in a MAC_STATS_V3 response and otherwise unused. 4321 * GENERATION_END in a MAC_STATS_V3 response and otherwise unused.
4161 */ 4322 */
4162#define MC_CMD_MAC_NSTATS_V3 0x79 4323#define MC_CMD_MAC_NSTATS_V3 0x79
4163/* Other enum values, see field(s): */ 4324/* Other enum values, see field(s): */
4164/* MC_CMD_MAC_STATS_V2_OUT_NO_DMA/STATISTICS */ 4325/* MC_CMD_MAC_STATS_V2_OUT_NO_DMA/STATISTICS */
4165 4326
@@ -4268,25 +4429,25 @@
4268#define MC_CMD_WOL_FILTER_SET_IN_LEN 192 4429#define MC_CMD_WOL_FILTER_SET_IN_LEN 192
4269#define MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0 4430#define MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0
4270#define MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_LEN 4 4431#define MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_LEN 4
4271#define MC_CMD_FILTER_MODE_SIMPLE 0x0 /* enum */ 4432#define MC_CMD_FILTER_MODE_SIMPLE 0x0 /* enum */
4272#define MC_CMD_FILTER_MODE_STRUCTURED 0xffffffff /* enum */ 4433#define MC_CMD_FILTER_MODE_STRUCTURED 0xffffffff /* enum */
4273/* A type value of 1 is unused. */ 4434/* A type value of 1 is unused. */
4274#define MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4 4435#define MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4
4275#define MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_LEN 4 4436#define MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_LEN 4
4276/* enum: Magic */ 4437/* enum: Magic */
4277#define MC_CMD_WOL_TYPE_MAGIC 0x0 4438#define MC_CMD_WOL_TYPE_MAGIC 0x0
4278/* enum: MS Windows Magic */ 4439/* enum: MS Windows Magic */
4279#define MC_CMD_WOL_TYPE_WIN_MAGIC 0x2 4440#define MC_CMD_WOL_TYPE_WIN_MAGIC 0x2
4280/* enum: IPv4 Syn */ 4441/* enum: IPv4 Syn */
4281#define MC_CMD_WOL_TYPE_IPV4_SYN 0x3 4442#define MC_CMD_WOL_TYPE_IPV4_SYN 0x3
4282/* enum: IPv6 Syn */ 4443/* enum: IPv6 Syn */
4283#define MC_CMD_WOL_TYPE_IPV6_SYN 0x4 4444#define MC_CMD_WOL_TYPE_IPV6_SYN 0x4
4284/* enum: Bitmap */ 4445/* enum: Bitmap */
4285#define MC_CMD_WOL_TYPE_BITMAP 0x5 4446#define MC_CMD_WOL_TYPE_BITMAP 0x5
4286/* enum: Link */ 4447/* enum: Link */
4287#define MC_CMD_WOL_TYPE_LINK 0x6 4448#define MC_CMD_WOL_TYPE_LINK 0x6
4288/* enum: (Above this for future use) */ 4449/* enum: (Above this for future use) */
4289#define MC_CMD_WOL_TYPE_MAX 0x7 4450#define MC_CMD_WOL_TYPE_MAX 0x7
4290#define MC_CMD_WOL_FILTER_SET_IN_DATA_OFST 8 4451#define MC_CMD_WOL_FILTER_SET_IN_DATA_OFST 8
4291#define MC_CMD_WOL_FILTER_SET_IN_DATA_LEN 4 4452#define MC_CMD_WOL_FILTER_SET_IN_DATA_LEN 4
4292#define MC_CMD_WOL_FILTER_SET_IN_DATA_NUM 46 4453#define MC_CMD_WOL_FILTER_SET_IN_DATA_NUM 46
@@ -4515,6 +4676,8 @@
4515#define MC_CMD_NVRAM_INFO_OUT_PROTECTED_WIDTH 1 4676#define MC_CMD_NVRAM_INFO_OUT_PROTECTED_WIDTH 1
4516#define MC_CMD_NVRAM_INFO_OUT_TLV_LBN 1 4677#define MC_CMD_NVRAM_INFO_OUT_TLV_LBN 1
4517#define MC_CMD_NVRAM_INFO_OUT_TLV_WIDTH 1 4678#define MC_CMD_NVRAM_INFO_OUT_TLV_WIDTH 1
4679#define MC_CMD_NVRAM_INFO_OUT_READ_ONLY_IF_TSA_BOUND_LBN 2
4680#define MC_CMD_NVRAM_INFO_OUT_READ_ONLY_IF_TSA_BOUND_WIDTH 1
4518#define MC_CMD_NVRAM_INFO_OUT_READ_ONLY_LBN 5 4681#define MC_CMD_NVRAM_INFO_OUT_READ_ONLY_LBN 5
4519#define MC_CMD_NVRAM_INFO_OUT_READ_ONLY_WIDTH 1 4682#define MC_CMD_NVRAM_INFO_OUT_READ_ONLY_WIDTH 1
4520#define MC_CMD_NVRAM_INFO_OUT_CMAC_LBN 6 4683#define MC_CMD_NVRAM_INFO_OUT_CMAC_LBN 6
@@ -4542,6 +4705,8 @@
4542#define MC_CMD_NVRAM_INFO_V2_OUT_PROTECTED_WIDTH 1 4705#define MC_CMD_NVRAM_INFO_V2_OUT_PROTECTED_WIDTH 1
4543#define MC_CMD_NVRAM_INFO_V2_OUT_TLV_LBN 1 4706#define MC_CMD_NVRAM_INFO_V2_OUT_TLV_LBN 1
4544#define MC_CMD_NVRAM_INFO_V2_OUT_TLV_WIDTH 1 4707#define MC_CMD_NVRAM_INFO_V2_OUT_TLV_WIDTH 1
4708#define MC_CMD_NVRAM_INFO_V2_OUT_READ_ONLY_IF_TSA_BOUND_LBN 2
4709#define MC_CMD_NVRAM_INFO_V2_OUT_READ_ONLY_IF_TSA_BOUND_WIDTH 1
4545#define MC_CMD_NVRAM_INFO_V2_OUT_READ_ONLY_LBN 5 4710#define MC_CMD_NVRAM_INFO_V2_OUT_READ_ONLY_LBN 5
4546#define MC_CMD_NVRAM_INFO_V2_OUT_READ_ONLY_WIDTH 1 4711#define MC_CMD_NVRAM_INFO_V2_OUT_READ_ONLY_WIDTH 1
4547#define MC_CMD_NVRAM_INFO_V2_OUT_A_B_LBN 7 4712#define MC_CMD_NVRAM_INFO_V2_OUT_A_B_LBN 7
@@ -4560,7 +4725,11 @@
4560/* MC_CMD_NVRAM_UPDATE_START 4725/* MC_CMD_NVRAM_UPDATE_START
4561 * Start a group of update operations on a virtual NVRAM partition. Locks 4726 * Start a group of update operations on a virtual NVRAM partition. Locks
4562 * required: PHY_LOCK if type==*PHY*. Returns: 0, EINVAL (bad type), EACCES (if 4727 * required: PHY_LOCK if type==*PHY*. Returns: 0, EINVAL (bad type), EACCES (if
4563 * PHY_LOCK required and not held). 4728 * PHY_LOCK required and not held). In an adapter bound to a TSA controller,
4729 * MC_CMD_NVRAM_UPDATE_START can only be used on a subset of partition types
4730 * i.e. static config, dynamic config and expansion ROM config. Attempting to
4731 * perform this operation on a restricted partition will return the error
4732 * EPERM.
4564 */ 4733 */
4565#define MC_CMD_NVRAM_UPDATE_START 0x38 4734#define MC_CMD_NVRAM_UPDATE_START 0x38
4566 4735
@@ -4720,8 +4889,12 @@
4720/***********************************/ 4889/***********************************/
4721/* MC_CMD_NVRAM_UPDATE_FINISH 4890/* MC_CMD_NVRAM_UPDATE_FINISH
4722 * Finish a group of update operations on a virtual NVRAM partition. Locks 4891 * Finish a group of update operations on a virtual NVRAM partition. Locks
4723 * required: PHY_LOCK if type==*PHY*. Returns: 0, EINVAL (bad 4892 * required: PHY_LOCK if type==*PHY*. Returns: 0, EINVAL (bad type/offset/
4724 * type/offset/length), EACCES (if PHY_LOCK required and not held) 4893 * length), EACCES (if PHY_LOCK required and not held). In an adapter bound to
4894 * a TSA controller, MC_CMD_NVRAM_UPDATE_FINISH can only be used on a subset of
4895 * partition types i.e. static config, dynamic config and expansion ROM config.
4896 * Attempting to perform this operation on a restricted partition will return
4897 * the error EPERM.
4725 */ 4898 */
4726#define MC_CMD_NVRAM_UPDATE_FINISH 0x3c 4899#define MC_CMD_NVRAM_UPDATE_FINISH 0x3c
4727 4900
@@ -4958,181 +5131,181 @@
4958#define MC_CMD_SENSOR_INFO_OUT_MASK_OFST 0 5131#define MC_CMD_SENSOR_INFO_OUT_MASK_OFST 0
4959#define MC_CMD_SENSOR_INFO_OUT_MASK_LEN 4 5132#define MC_CMD_SENSOR_INFO_OUT_MASK_LEN 4
4960/* enum: Controller temperature: degC */ 5133/* enum: Controller temperature: degC */
4961#define MC_CMD_SENSOR_CONTROLLER_TEMP 0x0 5134#define MC_CMD_SENSOR_CONTROLLER_TEMP 0x0
4962/* enum: Phy common temperature: degC */ 5135/* enum: Phy common temperature: degC */
4963#define MC_CMD_SENSOR_PHY_COMMON_TEMP 0x1 5136#define MC_CMD_SENSOR_PHY_COMMON_TEMP 0x1
4964/* enum: Controller cooling: bool */ 5137/* enum: Controller cooling: bool */
4965#define MC_CMD_SENSOR_CONTROLLER_COOLING 0x2 5138#define MC_CMD_SENSOR_CONTROLLER_COOLING 0x2
4966/* enum: Phy 0 temperature: degC */ 5139/* enum: Phy 0 temperature: degC */
4967#define MC_CMD_SENSOR_PHY0_TEMP 0x3 5140#define MC_CMD_SENSOR_PHY0_TEMP 0x3
4968/* enum: Phy 0 cooling: bool */ 5141/* enum: Phy 0 cooling: bool */
4969#define MC_CMD_SENSOR_PHY0_COOLING 0x4 5142#define MC_CMD_SENSOR_PHY0_COOLING 0x4
4970/* enum: Phy 1 temperature: degC */ 5143/* enum: Phy 1 temperature: degC */
4971#define MC_CMD_SENSOR_PHY1_TEMP 0x5 5144#define MC_CMD_SENSOR_PHY1_TEMP 0x5
4972/* enum: Phy 1 cooling: bool */ 5145/* enum: Phy 1 cooling: bool */
4973#define MC_CMD_SENSOR_PHY1_COOLING 0x6 5146#define MC_CMD_SENSOR_PHY1_COOLING 0x6
4974/* enum: 1.0v power: mV */ 5147/* enum: 1.0v power: mV */
4975#define MC_CMD_SENSOR_IN_1V0 0x7 5148#define MC_CMD_SENSOR_IN_1V0 0x7
4976/* enum: 1.2v power: mV */ 5149/* enum: 1.2v power: mV */
4977#define MC_CMD_SENSOR_IN_1V2 0x8 5150#define MC_CMD_SENSOR_IN_1V2 0x8
4978/* enum: 1.8v power: mV */ 5151/* enum: 1.8v power: mV */
4979#define MC_CMD_SENSOR_IN_1V8 0x9 5152#define MC_CMD_SENSOR_IN_1V8 0x9
4980/* enum: 2.5v power: mV */ 5153/* enum: 2.5v power: mV */
4981#define MC_CMD_SENSOR_IN_2V5 0xa 5154#define MC_CMD_SENSOR_IN_2V5 0xa
4982/* enum: 3.3v power: mV */ 5155/* enum: 3.3v power: mV */
4983#define MC_CMD_SENSOR_IN_3V3 0xb 5156#define MC_CMD_SENSOR_IN_3V3 0xb
4984/* enum: 12v power: mV */ 5157/* enum: 12v power: mV */
4985#define MC_CMD_SENSOR_IN_12V0 0xc 5158#define MC_CMD_SENSOR_IN_12V0 0xc
4986/* enum: 1.2v analogue power: mV */ 5159/* enum: 1.2v analogue power: mV */
4987#define MC_CMD_SENSOR_IN_1V2A 0xd 5160#define MC_CMD_SENSOR_IN_1V2A 0xd
4988/* enum: reference voltage: mV */ 5161/* enum: reference voltage: mV */
4989#define MC_CMD_SENSOR_IN_VREF 0xe 5162#define MC_CMD_SENSOR_IN_VREF 0xe
4990/* enum: AOE FPGA power: mV */ 5163/* enum: AOE FPGA power: mV */
4991#define MC_CMD_SENSOR_OUT_VAOE 0xf 5164#define MC_CMD_SENSOR_OUT_VAOE 0xf
4992/* enum: AOE FPGA temperature: degC */ 5165/* enum: AOE FPGA temperature: degC */
4993#define MC_CMD_SENSOR_AOE_TEMP 0x10 5166#define MC_CMD_SENSOR_AOE_TEMP 0x10
4994/* enum: AOE FPGA PSU temperature: degC */ 5167/* enum: AOE FPGA PSU temperature: degC */
4995#define MC_CMD_SENSOR_PSU_AOE_TEMP 0x11 5168#define MC_CMD_SENSOR_PSU_AOE_TEMP 0x11
4996/* enum: AOE PSU temperature: degC */ 5169/* enum: AOE PSU temperature: degC */
4997#define MC_CMD_SENSOR_PSU_TEMP 0x12 5170#define MC_CMD_SENSOR_PSU_TEMP 0x12
4998/* enum: Fan 0 speed: RPM */ 5171/* enum: Fan 0 speed: RPM */
4999#define MC_CMD_SENSOR_FAN_0 0x13 5172#define MC_CMD_SENSOR_FAN_0 0x13
5000/* enum: Fan 1 speed: RPM */ 5173/* enum: Fan 1 speed: RPM */
5001#define MC_CMD_SENSOR_FAN_1 0x14 5174#define MC_CMD_SENSOR_FAN_1 0x14
5002/* enum: Fan 2 speed: RPM */ 5175/* enum: Fan 2 speed: RPM */
5003#define MC_CMD_SENSOR_FAN_2 0x15 5176#define MC_CMD_SENSOR_FAN_2 0x15
5004/* enum: Fan 3 speed: RPM */ 5177/* enum: Fan 3 speed: RPM */
5005#define MC_CMD_SENSOR_FAN_3 0x16 5178#define MC_CMD_SENSOR_FAN_3 0x16
5006/* enum: Fan 4 speed: RPM */ 5179/* enum: Fan 4 speed: RPM */
5007#define MC_CMD_SENSOR_FAN_4 0x17 5180#define MC_CMD_SENSOR_FAN_4 0x17
5008/* enum: AOE FPGA input power: mV */ 5181/* enum: AOE FPGA input power: mV */
5009#define MC_CMD_SENSOR_IN_VAOE 0x18 5182#define MC_CMD_SENSOR_IN_VAOE 0x18
5010/* enum: AOE FPGA current: mA */ 5183/* enum: AOE FPGA current: mA */
5011#define MC_CMD_SENSOR_OUT_IAOE 0x19 5184#define MC_CMD_SENSOR_OUT_IAOE 0x19
5012/* enum: AOE FPGA input current: mA */ 5185/* enum: AOE FPGA input current: mA */
5013#define MC_CMD_SENSOR_IN_IAOE 0x1a 5186#define MC_CMD_SENSOR_IN_IAOE 0x1a
5014/* enum: NIC power consumption: W */ 5187/* enum: NIC power consumption: W */
5015#define MC_CMD_SENSOR_NIC_POWER 0x1b 5188#define MC_CMD_SENSOR_NIC_POWER 0x1b
5016/* enum: 0.9v power voltage: mV */ 5189/* enum: 0.9v power voltage: mV */
5017#define MC_CMD_SENSOR_IN_0V9 0x1c 5190#define MC_CMD_SENSOR_IN_0V9 0x1c
5018/* enum: 0.9v power current: mA */ 5191/* enum: 0.9v power current: mA */
5019#define MC_CMD_SENSOR_IN_I0V9 0x1d 5192#define MC_CMD_SENSOR_IN_I0V9 0x1d
5020/* enum: 1.2v power current: mA */ 5193/* enum: 1.2v power current: mA */
5021#define MC_CMD_SENSOR_IN_I1V2 0x1e 5194#define MC_CMD_SENSOR_IN_I1V2 0x1e
5022/* enum: Not a sensor: reserved for the next page flag */ 5195/* enum: Not a sensor: reserved for the next page flag */
5023#define MC_CMD_SENSOR_PAGE0_NEXT 0x1f 5196#define MC_CMD_SENSOR_PAGE0_NEXT 0x1f
5024/* enum: 0.9v power voltage (at ADC): mV */ 5197/* enum: 0.9v power voltage (at ADC): mV */
5025#define MC_CMD_SENSOR_IN_0V9_ADC 0x20 5198#define MC_CMD_SENSOR_IN_0V9_ADC 0x20
5026/* enum: Controller temperature 2: degC */ 5199/* enum: Controller temperature 2: degC */
5027#define MC_CMD_SENSOR_CONTROLLER_2_TEMP 0x21 5200#define MC_CMD_SENSOR_CONTROLLER_2_TEMP 0x21
5028/* enum: Voltage regulator internal temperature: degC */ 5201/* enum: Voltage regulator internal temperature: degC */
5029#define MC_CMD_SENSOR_VREG_INTERNAL_TEMP 0x22 5202#define MC_CMD_SENSOR_VREG_INTERNAL_TEMP 0x22
5030/* enum: 0.9V voltage regulator temperature: degC */ 5203/* enum: 0.9V voltage regulator temperature: degC */
5031#define MC_CMD_SENSOR_VREG_0V9_TEMP 0x23 5204#define MC_CMD_SENSOR_VREG_0V9_TEMP 0x23
5032/* enum: 1.2V voltage regulator temperature: degC */ 5205/* enum: 1.2V voltage regulator temperature: degC */
5033#define MC_CMD_SENSOR_VREG_1V2_TEMP 0x24 5206#define MC_CMD_SENSOR_VREG_1V2_TEMP 0x24
5034/* enum: controller internal temperature sensor voltage (internal ADC): mV */ 5207/* enum: controller internal temperature sensor voltage (internal ADC): mV */
5035#define MC_CMD_SENSOR_CONTROLLER_VPTAT 0x25 5208#define MC_CMD_SENSOR_CONTROLLER_VPTAT 0x25
5036/* enum: controller internal temperature (internal ADC): degC */ 5209/* enum: controller internal temperature (internal ADC): degC */
5037#define MC_CMD_SENSOR_CONTROLLER_INTERNAL_TEMP 0x26 5210#define MC_CMD_SENSOR_CONTROLLER_INTERNAL_TEMP 0x26
5038/* enum: controller internal temperature sensor voltage (external ADC): mV */ 5211/* enum: controller internal temperature sensor voltage (external ADC): mV */
5039#define MC_CMD_SENSOR_CONTROLLER_VPTAT_EXTADC 0x27 5212#define MC_CMD_SENSOR_CONTROLLER_VPTAT_EXTADC 0x27
5040/* enum: controller internal temperature (external ADC): degC */ 5213/* enum: controller internal temperature (external ADC): degC */
5041#define MC_CMD_SENSOR_CONTROLLER_INTERNAL_TEMP_EXTADC 0x28 5214#define MC_CMD_SENSOR_CONTROLLER_INTERNAL_TEMP_EXTADC 0x28
5042/* enum: ambient temperature: degC */ 5215/* enum: ambient temperature: degC */
5043#define MC_CMD_SENSOR_AMBIENT_TEMP 0x29 5216#define MC_CMD_SENSOR_AMBIENT_TEMP 0x29
5044/* enum: air flow: bool */ 5217/* enum: air flow: bool */
5045#define MC_CMD_SENSOR_AIRFLOW 0x2a 5218#define MC_CMD_SENSOR_AIRFLOW 0x2a
5046/* enum: voltage between VSS08D and VSS08D at CSR: mV */ 5219/* enum: voltage between VSS08D and VSS08D at CSR: mV */
5047#define MC_CMD_SENSOR_VDD08D_VSS08D_CSR 0x2b 5220#define MC_CMD_SENSOR_VDD08D_VSS08D_CSR 0x2b
5048/* enum: voltage between VSS08D and VSS08D at CSR (external ADC): mV */ 5221/* enum: voltage between VSS08D and VSS08D at CSR (external ADC): mV */
5049#define MC_CMD_SENSOR_VDD08D_VSS08D_CSR_EXTADC 0x2c 5222#define MC_CMD_SENSOR_VDD08D_VSS08D_CSR_EXTADC 0x2c
5050/* enum: Hotpoint temperature: degC */ 5223/* enum: Hotpoint temperature: degC */
5051#define MC_CMD_SENSOR_HOTPOINT_TEMP 0x2d 5224#define MC_CMD_SENSOR_HOTPOINT_TEMP 0x2d
5052/* enum: Port 0 PHY power switch over-current: bool */ 5225/* enum: Port 0 PHY power switch over-current: bool */
5053#define MC_CMD_SENSOR_PHY_POWER_PORT0 0x2e 5226#define MC_CMD_SENSOR_PHY_POWER_PORT0 0x2e
5054/* enum: Port 1 PHY power switch over-current: bool */ 5227/* enum: Port 1 PHY power switch over-current: bool */
5055#define MC_CMD_SENSOR_PHY_POWER_PORT1 0x2f 5228#define MC_CMD_SENSOR_PHY_POWER_PORT1 0x2f
5056/* enum: Mop-up microcontroller reference voltage (millivolts) */ 5229/* enum: Mop-up microcontroller reference voltage: mV */
5057#define MC_CMD_SENSOR_MUM_VCC 0x30 5230#define MC_CMD_SENSOR_MUM_VCC 0x30
5058/* enum: 0.9v power phase A voltage: mV */ 5231/* enum: 0.9v power phase A voltage: mV */
5059#define MC_CMD_SENSOR_IN_0V9_A 0x31 5232#define MC_CMD_SENSOR_IN_0V9_A 0x31
5060/* enum: 0.9v power phase A current: mA */ 5233/* enum: 0.9v power phase A current: mA */
5061#define MC_CMD_SENSOR_IN_I0V9_A 0x32 5234#define MC_CMD_SENSOR_IN_I0V9_A 0x32
5062/* enum: 0.9V voltage regulator phase A temperature: degC */ 5235/* enum: 0.9V voltage regulator phase A temperature: degC */
5063#define MC_CMD_SENSOR_VREG_0V9_A_TEMP 0x33 5236#define MC_CMD_SENSOR_VREG_0V9_A_TEMP 0x33
5064/* enum: 0.9v power phase B voltage: mV */ 5237/* enum: 0.9v power phase B voltage: mV */
5065#define MC_CMD_SENSOR_IN_0V9_B 0x34 5238#define MC_CMD_SENSOR_IN_0V9_B 0x34
5066/* enum: 0.9v power phase B current: mA */ 5239/* enum: 0.9v power phase B current: mA */
5067#define MC_CMD_SENSOR_IN_I0V9_B 0x35 5240#define MC_CMD_SENSOR_IN_I0V9_B 0x35
5068/* enum: 0.9V voltage regulator phase B temperature: degC */ 5241/* enum: 0.9V voltage regulator phase B temperature: degC */
5069#define MC_CMD_SENSOR_VREG_0V9_B_TEMP 0x36 5242#define MC_CMD_SENSOR_VREG_0V9_B_TEMP 0x36
5070/* enum: CCOM AVREG 1v2 supply (interval ADC): mV */ 5243/* enum: CCOM AVREG 1v2 supply (interval ADC): mV */
5071#define MC_CMD_SENSOR_CCOM_AVREG_1V2_SUPPLY 0x37 5244#define MC_CMD_SENSOR_CCOM_AVREG_1V2_SUPPLY 0x37
5072/* enum: CCOM AVREG 1v2 supply (external ADC): mV */ 5245/* enum: CCOM AVREG 1v2 supply (external ADC): mV */
5073#define MC_CMD_SENSOR_CCOM_AVREG_1V2_SUPPLY_EXTADC 0x38 5246#define MC_CMD_SENSOR_CCOM_AVREG_1V2_SUPPLY_EXTADC 0x38
5074/* enum: CCOM AVREG 1v8 supply (interval ADC): mV */ 5247/* enum: CCOM AVREG 1v8 supply (interval ADC): mV */
5075#define MC_CMD_SENSOR_CCOM_AVREG_1V8_SUPPLY 0x39 5248#define MC_CMD_SENSOR_CCOM_AVREG_1V8_SUPPLY 0x39
5076/* enum: CCOM AVREG 1v8 supply (external ADC): mV */ 5249/* enum: CCOM AVREG 1v8 supply (external ADC): mV */
5077#define MC_CMD_SENSOR_CCOM_AVREG_1V8_SUPPLY_EXTADC 0x3a 5250#define MC_CMD_SENSOR_CCOM_AVREG_1V8_SUPPLY_EXTADC 0x3a
5078/* enum: CCOM RTS temperature: degC */ 5251/* enum: CCOM RTS temperature: degC */
5079#define MC_CMD_SENSOR_CONTROLLER_RTS 0x3b 5252#define MC_CMD_SENSOR_CONTROLLER_RTS 0x3b
5080/* enum: Not a sensor: reserved for the next page flag */ 5253/* enum: Not a sensor: reserved for the next page flag */
5081#define MC_CMD_SENSOR_PAGE1_NEXT 0x3f 5254#define MC_CMD_SENSOR_PAGE1_NEXT 0x3f
5082/* enum: controller internal temperature sensor voltage on master core 5255/* enum: controller internal temperature sensor voltage on master core
5083 * (internal ADC): mV 5256 * (internal ADC): mV
5084 */ 5257 */
5085#define MC_CMD_SENSOR_CONTROLLER_MASTER_VPTAT 0x40 5258#define MC_CMD_SENSOR_CONTROLLER_MASTER_VPTAT 0x40
5086/* enum: controller internal temperature on master core (internal ADC): degC */ 5259/* enum: controller internal temperature on master core (internal ADC): degC */
5087#define MC_CMD_SENSOR_CONTROLLER_MASTER_INTERNAL_TEMP 0x41 5260#define MC_CMD_SENSOR_CONTROLLER_MASTER_INTERNAL_TEMP 0x41
5088/* enum: controller internal temperature sensor voltage on master core 5261/* enum: controller internal temperature sensor voltage on master core
5089 * (external ADC): mV 5262 * (external ADC): mV
5090 */ 5263 */
5091#define MC_CMD_SENSOR_CONTROLLER_MASTER_VPTAT_EXTADC 0x42 5264#define MC_CMD_SENSOR_CONTROLLER_MASTER_VPTAT_EXTADC 0x42
5092/* enum: controller internal temperature on master core (external ADC): degC */ 5265/* enum: controller internal temperature on master core (external ADC): degC */
5093#define MC_CMD_SENSOR_CONTROLLER_MASTER_INTERNAL_TEMP_EXTADC 0x43 5266#define MC_CMD_SENSOR_CONTROLLER_MASTER_INTERNAL_TEMP_EXTADC 0x43
5094/* enum: controller internal temperature on slave core sensor voltage (internal 5267/* enum: controller internal temperature on slave core sensor voltage (internal
5095 * ADC): mV 5268 * ADC): mV
5096 */ 5269 */
5097#define MC_CMD_SENSOR_CONTROLLER_SLAVE_VPTAT 0x44 5270#define MC_CMD_SENSOR_CONTROLLER_SLAVE_VPTAT 0x44
5098/* enum: controller internal temperature on slave core (internal ADC): degC */ 5271/* enum: controller internal temperature on slave core (internal ADC): degC */
5099#define MC_CMD_SENSOR_CONTROLLER_SLAVE_INTERNAL_TEMP 0x45 5272#define MC_CMD_SENSOR_CONTROLLER_SLAVE_INTERNAL_TEMP 0x45
5100/* enum: controller internal temperature on slave core sensor voltage (external 5273/* enum: controller internal temperature on slave core sensor voltage (external
5101 * ADC): mV 5274 * ADC): mV
5102 */ 5275 */
5103#define MC_CMD_SENSOR_CONTROLLER_SLAVE_VPTAT_EXTADC 0x46 5276#define MC_CMD_SENSOR_CONTROLLER_SLAVE_VPTAT_EXTADC 0x46
5104/* enum: controller internal temperature on slave core (external ADC): degC */ 5277/* enum: controller internal temperature on slave core (external ADC): degC */
5105#define MC_CMD_SENSOR_CONTROLLER_SLAVE_INTERNAL_TEMP_EXTADC 0x47 5278#define MC_CMD_SENSOR_CONTROLLER_SLAVE_INTERNAL_TEMP_EXTADC 0x47
5106/* enum: Voltage supplied to the SODIMMs from their power supply: mV */ 5279/* enum: Voltage supplied to the SODIMMs from their power supply: mV */
5107#define MC_CMD_SENSOR_SODIMM_VOUT 0x49 5280#define MC_CMD_SENSOR_SODIMM_VOUT 0x49
5108/* enum: Temperature of SODIMM 0 (if installed): degC */ 5281/* enum: Temperature of SODIMM 0 (if installed): degC */
5109#define MC_CMD_SENSOR_SODIMM_0_TEMP 0x4a 5282#define MC_CMD_SENSOR_SODIMM_0_TEMP 0x4a
5110/* enum: Temperature of SODIMM 1 (if installed): degC */ 5283/* enum: Temperature of SODIMM 1 (if installed): degC */
5111#define MC_CMD_SENSOR_SODIMM_1_TEMP 0x4b 5284#define MC_CMD_SENSOR_SODIMM_1_TEMP 0x4b
5112/* enum: Voltage supplied to the QSFP #0 from their power supply: mV */ 5285/* enum: Voltage supplied to the QSFP #0 from their power supply: mV */
5113#define MC_CMD_SENSOR_PHY0_VCC 0x4c 5286#define MC_CMD_SENSOR_PHY0_VCC 0x4c
5114/* enum: Voltage supplied to the QSFP #1 from their power supply: mV */ 5287/* enum: Voltage supplied to the QSFP #1 from their power supply: mV */
5115#define MC_CMD_SENSOR_PHY1_VCC 0x4d 5288#define MC_CMD_SENSOR_PHY1_VCC 0x4d
5116/* enum: Controller die temperature (TDIODE): degC */ 5289/* enum: Controller die temperature (TDIODE): degC */
5117#define MC_CMD_SENSOR_CONTROLLER_TDIODE_TEMP 0x4e 5290#define MC_CMD_SENSOR_CONTROLLER_TDIODE_TEMP 0x4e
5118/* enum: Board temperature (front): degC */ 5291/* enum: Board temperature (front): degC */
5119#define MC_CMD_SENSOR_BOARD_FRONT_TEMP 0x4f 5292#define MC_CMD_SENSOR_BOARD_FRONT_TEMP 0x4f
5120/* enum: Board temperature (back): degC */ 5293/* enum: Board temperature (back): degC */
5121#define MC_CMD_SENSOR_BOARD_BACK_TEMP 0x50 5294#define MC_CMD_SENSOR_BOARD_BACK_TEMP 0x50
5122/* enum: 1.8v power current: mA */ 5295/* enum: 1.8v power current: mA */
5123#define MC_CMD_SENSOR_IN_I1V8 0x51 5296#define MC_CMD_SENSOR_IN_I1V8 0x51
5124/* enum: 2.5v power current: mA */ 5297/* enum: 2.5v power current: mA */
5125#define MC_CMD_SENSOR_IN_I2V5 0x52 5298#define MC_CMD_SENSOR_IN_I2V5 0x52
5126/* enum: 3.3v power current: mA */ 5299/* enum: 3.3v power current: mA */
5127#define MC_CMD_SENSOR_IN_I3V3 0x53 5300#define MC_CMD_SENSOR_IN_I3V3 0x53
5128/* enum: 12v power current: mA */ 5301/* enum: 12v power current: mA */
5129#define MC_CMD_SENSOR_IN_I12V0 0x54 5302#define MC_CMD_SENSOR_IN_I12V0 0x54
5130/* enum: 1.3v power: mV */ 5303/* enum: 1.3v power: mV */
5131#define MC_CMD_SENSOR_IN_1V3 0x55 5304#define MC_CMD_SENSOR_IN_1V3 0x55
5132/* enum: 1.3v power current: mA */ 5305/* enum: 1.3v power current: mA */
5133#define MC_CMD_SENSOR_IN_I1V3 0x56 5306#define MC_CMD_SENSOR_IN_I1V3 0x56
5134/* enum: Not a sensor: reserved for the next page flag */ 5307/* enum: Not a sensor: reserved for the next page flag */
5135#define MC_CMD_SENSOR_PAGE2_NEXT 0x5f 5308#define MC_CMD_SENSOR_PAGE2_NEXT 0x5f
5136/* MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF */ 5309/* MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF */
5137#define MC_CMD_SENSOR_ENTRY_OFST 4 5310#define MC_CMD_SENSOR_ENTRY_OFST 4
5138#define MC_CMD_SENSOR_ENTRY_LEN 8 5311#define MC_CMD_SENSOR_ENTRY_LEN 8
@@ -5234,17 +5407,17 @@
5234#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE_OFST 2 5407#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE_OFST 2
5235#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE_LEN 1 5408#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE_LEN 1
5236/* enum: Ok. */ 5409/* enum: Ok. */
5237#define MC_CMD_SENSOR_STATE_OK 0x0 5410#define MC_CMD_SENSOR_STATE_OK 0x0
5238/* enum: Breached warning threshold. */ 5411/* enum: Breached warning threshold. */
5239#define MC_CMD_SENSOR_STATE_WARNING 0x1 5412#define MC_CMD_SENSOR_STATE_WARNING 0x1
5240/* enum: Breached fatal threshold. */ 5413/* enum: Breached fatal threshold. */
5241#define MC_CMD_SENSOR_STATE_FATAL 0x2 5414#define MC_CMD_SENSOR_STATE_FATAL 0x2
5242/* enum: Fault with sensor. */ 5415/* enum: Fault with sensor. */
5243#define MC_CMD_SENSOR_STATE_BROKEN 0x3 5416#define MC_CMD_SENSOR_STATE_BROKEN 0x3
5244/* enum: Sensor is working but does not currently have a reading. */ 5417/* enum: Sensor is working but does not currently have a reading. */
5245#define MC_CMD_SENSOR_STATE_NO_READING 0x4 5418#define MC_CMD_SENSOR_STATE_NO_READING 0x4
5246/* enum: Sensor initialisation failed. */ 5419/* enum: Sensor initialisation failed. */
5247#define MC_CMD_SENSOR_STATE_INIT_FAILED 0x5 5420#define MC_CMD_SENSOR_STATE_INIT_FAILED 0x5
5248#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE_LBN 16 5421#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE_LBN 16
5249#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE_WIDTH 8 5422#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE_WIDTH 8
5250#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_TYPE_OFST 3 5423#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_TYPE_OFST 3
@@ -5327,7 +5500,7 @@
5327#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_OFST 0 5500#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_OFST 0
5328#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_LEN 4 5501#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_LEN 4
5329#define MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_ARP 0x1 /* enum */ 5502#define MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_ARP 0x1 /* enum */
5330#define MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_NS 0x2 /* enum */ 5503#define MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_NS 0x2 /* enum */
5331#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_DATA_OFST 4 5504#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_DATA_OFST 4
5332#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_DATA_LEN 4 5505#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_DATA_LEN 4
5333#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_DATA_MINNUM 1 5506#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_DATA_MINNUM 1
@@ -5416,17 +5589,17 @@
5416/* enum: Assert using the FAIL_ASSERTION_WITH_USEFUL_VALUES macro. Unless 5589/* enum: Assert using the FAIL_ASSERTION_WITH_USEFUL_VALUES macro. Unless
5417 * you're testing firmware, this is what you want. 5590 * you're testing firmware, this is what you want.
5418 */ 5591 */
5419#define MC_CMD_TESTASSERT_V2_IN_FAIL_ASSERTION_WITH_USEFUL_VALUES 0x0 5592#define MC_CMD_TESTASSERT_V2_IN_FAIL_ASSERTION_WITH_USEFUL_VALUES 0x0
5420/* enum: Assert using assert(0); */ 5593/* enum: Assert using assert(0); */
5421#define MC_CMD_TESTASSERT_V2_IN_ASSERT_FALSE 0x1 5594#define MC_CMD_TESTASSERT_V2_IN_ASSERT_FALSE 0x1
5422/* enum: Deliberately trigger a watchdog */ 5595/* enum: Deliberately trigger a watchdog */
5423#define MC_CMD_TESTASSERT_V2_IN_WATCHDOG 0x2 5596#define MC_CMD_TESTASSERT_V2_IN_WATCHDOG 0x2
5424/* enum: Deliberately trigger a trap by loading from an invalid address */ 5597/* enum: Deliberately trigger a trap by loading from an invalid address */
5425#define MC_CMD_TESTASSERT_V2_IN_LOAD_TRAP 0x3 5598#define MC_CMD_TESTASSERT_V2_IN_LOAD_TRAP 0x3
5426/* enum: Deliberately trigger a trap by storing to an invalid address */ 5599/* enum: Deliberately trigger a trap by storing to an invalid address */
5427#define MC_CMD_TESTASSERT_V2_IN_STORE_TRAP 0x4 5600#define MC_CMD_TESTASSERT_V2_IN_STORE_TRAP 0x4
5428/* enum: Jump to an invalid address */ 5601/* enum: Jump to an invalid address */
5429#define MC_CMD_TESTASSERT_V2_IN_JUMP_TRAP 0x5 5602#define MC_CMD_TESTASSERT_V2_IN_JUMP_TRAP 0x5
5430 5603
5431/* MC_CMD_TESTASSERT_V2_OUT msgresponse */ 5604/* MC_CMD_TESTASSERT_V2_OUT msgresponse */
5432#define MC_CMD_TESTASSERT_V2_OUT_LEN 0 5605#define MC_CMD_TESTASSERT_V2_OUT_LEN 0
@@ -5969,7 +6142,7 @@
5969/* MC_CMD_MUM_IN_CMD_LEN 4 */ 6142/* MC_CMD_MUM_IN_CMD_LEN 4 */
5970#define MC_CMD_MUM_IN_LOG_OP_OFST 4 6143#define MC_CMD_MUM_IN_LOG_OP_OFST 4
5971#define MC_CMD_MUM_IN_LOG_OP_LEN 4 6144#define MC_CMD_MUM_IN_LOG_OP_LEN 4
5972#define MC_CMD_MUM_IN_LOG_OP_UART 0x1 /* enum */ 6145#define MC_CMD_MUM_IN_LOG_OP_UART 0x1 /* enum */
5973 6146
5974/* MC_CMD_MUM_IN_LOG_OP_UART msgrequest */ 6147/* MC_CMD_MUM_IN_LOG_OP_UART msgrequest */
5975#define MC_CMD_MUM_IN_LOG_OP_UART_LEN 12 6148#define MC_CMD_MUM_IN_LOG_OP_UART_LEN 12
@@ -6464,17 +6637,17 @@
6464#define EVB_PORT_ID_PORT_ID_OFST 0 6637#define EVB_PORT_ID_PORT_ID_OFST 0
6465#define EVB_PORT_ID_PORT_ID_LEN 4 6638#define EVB_PORT_ID_PORT_ID_LEN 4
6466/* enum: An invalid port handle. */ 6639/* enum: An invalid port handle. */
6467#define EVB_PORT_ID_NULL 0x0 6640#define EVB_PORT_ID_NULL 0x0
6468/* enum: The port assigned to this function.. */ 6641/* enum: The port assigned to this function.. */
6469#define EVB_PORT_ID_ASSIGNED 0x1000000 6642#define EVB_PORT_ID_ASSIGNED 0x1000000
6470/* enum: External network port 0 */ 6643/* enum: External network port 0 */
6471#define EVB_PORT_ID_MAC0 0x2000000 6644#define EVB_PORT_ID_MAC0 0x2000000
6472/* enum: External network port 1 */ 6645/* enum: External network port 1 */
6473#define EVB_PORT_ID_MAC1 0x2000001 6646#define EVB_PORT_ID_MAC1 0x2000001
6474/* enum: External network port 2 */ 6647/* enum: External network port 2 */
6475#define EVB_PORT_ID_MAC2 0x2000002 6648#define EVB_PORT_ID_MAC2 0x2000002
6476/* enum: External network port 3 */ 6649/* enum: External network port 3 */
6477#define EVB_PORT_ID_MAC3 0x2000003 6650#define EVB_PORT_ID_MAC3 0x2000003
6478#define EVB_PORT_ID_PORT_ID_LBN 0 6651#define EVB_PORT_ID_PORT_ID_LBN 0
6479#define EVB_PORT_ID_PORT_ID_WIDTH 32 6652#define EVB_PORT_ID_PORT_ID_WIDTH 32
6480 6653
@@ -6486,7 +6659,7 @@
6486#define EVB_VLAN_TAG_MODE_LBN 12 6659#define EVB_VLAN_TAG_MODE_LBN 12
6487#define EVB_VLAN_TAG_MODE_WIDTH 4 6660#define EVB_VLAN_TAG_MODE_WIDTH 4
6488/* enum: Insert the VLAN. */ 6661/* enum: Insert the VLAN. */
6489#define EVB_VLAN_TAG_INSERT 0x0 6662#define EVB_VLAN_TAG_INSERT 0x0
6490/* enum: Replace the VLAN if already present. */ 6663/* enum: Replace the VLAN if already present. */
6491#define EVB_VLAN_TAG_REPLACE 0x1 6664#define EVB_VLAN_TAG_REPLACE 0x1
6492 6665
@@ -6515,110 +6688,110 @@
6515#define NVRAM_PARTITION_TYPE_ID_OFST 0 6688#define NVRAM_PARTITION_TYPE_ID_OFST 0
6516#define NVRAM_PARTITION_TYPE_ID_LEN 2 6689#define NVRAM_PARTITION_TYPE_ID_LEN 2
6517/* enum: Primary MC firmware partition */ 6690/* enum: Primary MC firmware partition */
6518#define NVRAM_PARTITION_TYPE_MC_FIRMWARE 0x100 6691#define NVRAM_PARTITION_TYPE_MC_FIRMWARE 0x100
6519/* enum: Secondary MC firmware partition */ 6692/* enum: Secondary MC firmware partition */
6520#define NVRAM_PARTITION_TYPE_MC_FIRMWARE_BACKUP 0x200 6693#define NVRAM_PARTITION_TYPE_MC_FIRMWARE_BACKUP 0x200
6521/* enum: Expansion ROM partition */ 6694/* enum: Expansion ROM partition */
6522#define NVRAM_PARTITION_TYPE_EXPANSION_ROM 0x300 6695#define NVRAM_PARTITION_TYPE_EXPANSION_ROM 0x300
6523/* enum: Static configuration TLV partition */ 6696/* enum: Static configuration TLV partition */
6524#define NVRAM_PARTITION_TYPE_STATIC_CONFIG 0x400 6697#define NVRAM_PARTITION_TYPE_STATIC_CONFIG 0x400
6525/* enum: Dynamic configuration TLV partition */ 6698/* enum: Dynamic configuration TLV partition */
6526#define NVRAM_PARTITION_TYPE_DYNAMIC_CONFIG 0x500 6699#define NVRAM_PARTITION_TYPE_DYNAMIC_CONFIG 0x500
6527/* enum: Expansion ROM configuration data for port 0 */ 6700/* enum: Expansion ROM configuration data for port 0 */
6528#define NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT0 0x600 6701#define NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT0 0x600
6529/* enum: Synonym for EXPROM_CONFIG_PORT0 as used in pmap files */ 6702/* enum: Synonym for EXPROM_CONFIG_PORT0 as used in pmap files */
6530#define NVRAM_PARTITION_TYPE_EXPROM_CONFIG 0x600 6703#define NVRAM_PARTITION_TYPE_EXPROM_CONFIG 0x600
6531/* enum: Expansion ROM configuration data for port 1 */ 6704/* enum: Expansion ROM configuration data for port 1 */
6532#define NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT1 0x601 6705#define NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT1 0x601
6533/* enum: Expansion ROM configuration data for port 2 */ 6706/* enum: Expansion ROM configuration data for port 2 */
6534#define NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT2 0x602 6707#define NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT2 0x602
6535/* enum: Expansion ROM configuration data for port 3 */ 6708/* enum: Expansion ROM configuration data for port 3 */
6536#define NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT3 0x603 6709#define NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT3 0x603
6537/* enum: Non-volatile log output partition */ 6710/* enum: Non-volatile log output partition */
6538#define NVRAM_PARTITION_TYPE_LOG 0x700 6711#define NVRAM_PARTITION_TYPE_LOG 0x700
6539/* enum: Non-volatile log output of second core on dual-core device */ 6712/* enum: Non-volatile log output of second core on dual-core device */
6540#define NVRAM_PARTITION_TYPE_LOG_SLAVE 0x701 6713#define NVRAM_PARTITION_TYPE_LOG_SLAVE 0x701
6541/* enum: Device state dump output partition */ 6714/* enum: Device state dump output partition */
6542#define NVRAM_PARTITION_TYPE_DUMP 0x800 6715#define NVRAM_PARTITION_TYPE_DUMP 0x800
6543/* enum: Application license key storage partition */ 6716/* enum: Application license key storage partition */
6544#define NVRAM_PARTITION_TYPE_LICENSE 0x900 6717#define NVRAM_PARTITION_TYPE_LICENSE 0x900
6545/* enum: Start of range used for PHY partitions (low 8 bits are the PHY ID) */ 6718/* enum: Start of range used for PHY partitions (low 8 bits are the PHY ID) */
6546#define NVRAM_PARTITION_TYPE_PHY_MIN 0xa00 6719#define NVRAM_PARTITION_TYPE_PHY_MIN 0xa00
6547/* enum: End of range used for PHY partitions (low 8 bits are the PHY ID) */ 6720/* enum: End of range used for PHY partitions (low 8 bits are the PHY ID) */
6548#define NVRAM_PARTITION_TYPE_PHY_MAX 0xaff 6721#define NVRAM_PARTITION_TYPE_PHY_MAX 0xaff
6549/* enum: Primary FPGA partition */ 6722/* enum: Primary FPGA partition */
6550#define NVRAM_PARTITION_TYPE_FPGA 0xb00 6723#define NVRAM_PARTITION_TYPE_FPGA 0xb00
6551/* enum: Secondary FPGA partition */ 6724/* enum: Secondary FPGA partition */
6552#define NVRAM_PARTITION_TYPE_FPGA_BACKUP 0xb01 6725#define NVRAM_PARTITION_TYPE_FPGA_BACKUP 0xb01
6553/* enum: FC firmware partition */ 6726/* enum: FC firmware partition */
6554#define NVRAM_PARTITION_TYPE_FC_FIRMWARE 0xb02 6727#define NVRAM_PARTITION_TYPE_FC_FIRMWARE 0xb02
6555/* enum: FC License partition */ 6728/* enum: FC License partition */
6556#define NVRAM_PARTITION_TYPE_FC_LICENSE 0xb03 6729#define NVRAM_PARTITION_TYPE_FC_LICENSE 0xb03
6557/* enum: Non-volatile log output partition for FC */ 6730/* enum: Non-volatile log output partition for FC */
6558#define NVRAM_PARTITION_TYPE_FC_LOG 0xb04 6731#define NVRAM_PARTITION_TYPE_FC_LOG 0xb04
6559/* enum: MUM firmware partition */ 6732/* enum: MUM firmware partition */
6560#define NVRAM_PARTITION_TYPE_MUM_FIRMWARE 0xc00 6733#define NVRAM_PARTITION_TYPE_MUM_FIRMWARE 0xc00
6561/* enum: SUC firmware partition (this is intentionally an alias of 6734/* enum: SUC firmware partition (this is intentionally an alias of
6562 * MUM_FIRMWARE) 6735 * MUM_FIRMWARE)
6563 */ 6736 */
6564#define NVRAM_PARTITION_TYPE_SUC_FIRMWARE 0xc00 6737#define NVRAM_PARTITION_TYPE_SUC_FIRMWARE 0xc00
6565/* enum: MUM Non-volatile log output partition. */ 6738/* enum: MUM Non-volatile log output partition. */
6566#define NVRAM_PARTITION_TYPE_MUM_LOG 0xc01 6739#define NVRAM_PARTITION_TYPE_MUM_LOG 0xc01
6567/* enum: MUM Application table partition. */ 6740/* enum: MUM Application table partition. */
6568#define NVRAM_PARTITION_TYPE_MUM_APPTABLE 0xc02 6741#define NVRAM_PARTITION_TYPE_MUM_APPTABLE 0xc02
6569/* enum: MUM boot rom partition. */ 6742/* enum: MUM boot rom partition. */
6570#define NVRAM_PARTITION_TYPE_MUM_BOOT_ROM 0xc03 6743#define NVRAM_PARTITION_TYPE_MUM_BOOT_ROM 0xc03
6571/* enum: MUM production signatures & calibration rom partition. */ 6744/* enum: MUM production signatures & calibration rom partition. */
6572#define NVRAM_PARTITION_TYPE_MUM_PROD_ROM 0xc04 6745#define NVRAM_PARTITION_TYPE_MUM_PROD_ROM 0xc04
6573/* enum: MUM user signatures & calibration rom partition. */ 6746/* enum: MUM user signatures & calibration rom partition. */
6574#define NVRAM_PARTITION_TYPE_MUM_USER_ROM 0xc05 6747#define NVRAM_PARTITION_TYPE_MUM_USER_ROM 0xc05
6575/* enum: MUM fuses and lockbits partition. */ 6748/* enum: MUM fuses and lockbits partition. */
6576#define NVRAM_PARTITION_TYPE_MUM_FUSELOCK 0xc06 6749#define NVRAM_PARTITION_TYPE_MUM_FUSELOCK 0xc06
6577/* enum: UEFI expansion ROM if separate from PXE */ 6750/* enum: UEFI expansion ROM if separate from PXE */
6578#define NVRAM_PARTITION_TYPE_EXPANSION_UEFI 0xd00 6751#define NVRAM_PARTITION_TYPE_EXPANSION_UEFI 0xd00
6579/* enum: Used by the expansion ROM for logging */ 6752/* enum: Used by the expansion ROM for logging */
6580#define NVRAM_PARTITION_TYPE_PXE_LOG 0x1000 6753#define NVRAM_PARTITION_TYPE_PXE_LOG 0x1000
6581/* enum: Used for XIP code of shmbooted images */ 6754/* enum: Used for XIP code of shmbooted images */
6582#define NVRAM_PARTITION_TYPE_XIP_SCRATCH 0x1100 6755#define NVRAM_PARTITION_TYPE_XIP_SCRATCH 0x1100
6583/* enum: Spare partition 2 */ 6756/* enum: Spare partition 2 */
6584#define NVRAM_PARTITION_TYPE_SPARE_2 0x1200 6757#define NVRAM_PARTITION_TYPE_SPARE_2 0x1200
6585/* enum: Manufacturing partition. Used during manufacture to pass information 6758/* enum: Manufacturing partition. Used during manufacture to pass information
6586 * between XJTAG and Manftest. 6759 * between XJTAG and Manftest.
6587 */ 6760 */
6588#define NVRAM_PARTITION_TYPE_MANUFACTURING 0x1300 6761#define NVRAM_PARTITION_TYPE_MANUFACTURING 0x1300
6589/* enum: Spare partition 4 */ 6762/* enum: Spare partition 4 */
6590#define NVRAM_PARTITION_TYPE_SPARE_4 0x1400 6763#define NVRAM_PARTITION_TYPE_SPARE_4 0x1400
6591/* enum: Spare partition 5 */ 6764/* enum: Spare partition 5 */
6592#define NVRAM_PARTITION_TYPE_SPARE_5 0x1500 6765#define NVRAM_PARTITION_TYPE_SPARE_5 0x1500
6593/* enum: Partition for reporting MC status. See mc_flash_layout.h 6766/* enum: Partition for reporting MC status. See mc_flash_layout.h
6594 * medford_mc_status_hdr_t for layout on Medford. 6767 * medford_mc_status_hdr_t for layout on Medford.
6595 */ 6768 */
6596#define NVRAM_PARTITION_TYPE_STATUS 0x1600 6769#define NVRAM_PARTITION_TYPE_STATUS 0x1600
6597/* enum: Spare partition 13 */ 6770/* enum: Spare partition 13 */
6598#define NVRAM_PARTITION_TYPE_SPARE_13 0x1700 6771#define NVRAM_PARTITION_TYPE_SPARE_13 0x1700
6599/* enum: Spare partition 14 */ 6772/* enum: Spare partition 14 */
6600#define NVRAM_PARTITION_TYPE_SPARE_14 0x1800 6773#define NVRAM_PARTITION_TYPE_SPARE_14 0x1800
6601/* enum: Spare partition 15 */ 6774/* enum: Spare partition 15 */
6602#define NVRAM_PARTITION_TYPE_SPARE_15 0x1900 6775#define NVRAM_PARTITION_TYPE_SPARE_15 0x1900
6603/* enum: Spare partition 16 */ 6776/* enum: Spare partition 16 */
6604#define NVRAM_PARTITION_TYPE_SPARE_16 0x1a00 6777#define NVRAM_PARTITION_TYPE_SPARE_16 0x1a00
6605/* enum: Factory defaults for dynamic configuration */ 6778/* enum: Factory defaults for dynamic configuration */
6606#define NVRAM_PARTITION_TYPE_DYNCONFIG_DEFAULTS 0x1b00 6779#define NVRAM_PARTITION_TYPE_DYNCONFIG_DEFAULTS 0x1b00
6607/* enum: Factory defaults for expansion ROM configuration */ 6780/* enum: Factory defaults for expansion ROM configuration */
6608#define NVRAM_PARTITION_TYPE_ROMCONFIG_DEFAULTS 0x1c00 6781#define NVRAM_PARTITION_TYPE_ROMCONFIG_DEFAULTS 0x1c00
6609/* enum: Field Replaceable Unit inventory information for use on IPMI 6782/* enum: Field Replaceable Unit inventory information for use on IPMI
6610 * platforms. See SF-119124-PS. The STATIC_CONFIG partition may contain a 6783 * platforms. See SF-119124-PS. The STATIC_CONFIG partition may contain a
6611 * subset of the information stored in this partition. 6784 * subset of the information stored in this partition.
6612 */ 6785 */
6613#define NVRAM_PARTITION_TYPE_FRU_INFORMATION 0x1d00 6786#define NVRAM_PARTITION_TYPE_FRU_INFORMATION 0x1d00
6614/* enum: Start of reserved value range (firmware may use for any purpose) */ 6787/* enum: Start of reserved value range (firmware may use for any purpose) */
6615#define NVRAM_PARTITION_TYPE_RESERVED_VALUES_MIN 0xff00 6788#define NVRAM_PARTITION_TYPE_RESERVED_VALUES_MIN 0xff00
6616/* enum: End of reserved value range (firmware may use for any purpose) */ 6789/* enum: End of reserved value range (firmware may use for any purpose) */
6617#define NVRAM_PARTITION_TYPE_RESERVED_VALUES_MAX 0xfffd 6790#define NVRAM_PARTITION_TYPE_RESERVED_VALUES_MAX 0xfffd
6618/* enum: Recovery partition map (provided if real map is missing or corrupt) */ 6791/* enum: Recovery partition map (provided if real map is missing or corrupt) */
6619#define NVRAM_PARTITION_TYPE_RECOVERY_MAP 0xfffe 6792#define NVRAM_PARTITION_TYPE_RECOVERY_MAP 0xfffe
6620/* enum: Partition map (real map as stored in flash) */ 6793/* enum: Partition map (real map as stored in flash) */
6621#define NVRAM_PARTITION_TYPE_PARTITION_MAP 0xffff 6794#define NVRAM_PARTITION_TYPE_PARTITION_MAP 0xffff
6622#define NVRAM_PARTITION_TYPE_ID_LBN 0 6795#define NVRAM_PARTITION_TYPE_ID_LBN 0
6623#define NVRAM_PARTITION_TYPE_ID_WIDTH 16 6796#define NVRAM_PARTITION_TYPE_ID_WIDTH 16
6624 6797
@@ -6627,37 +6800,37 @@
6627#define LICENSED_APP_ID_ID_OFST 0 6800#define LICENSED_APP_ID_ID_OFST 0
6628#define LICENSED_APP_ID_ID_LEN 4 6801#define LICENSED_APP_ID_ID_LEN 4
6629/* enum: OpenOnload */ 6802/* enum: OpenOnload */
6630#define LICENSED_APP_ID_ONLOAD 0x1 6803#define LICENSED_APP_ID_ONLOAD 0x1
6631/* enum: PTP timestamping */ 6804/* enum: PTP timestamping */
6632#define LICENSED_APP_ID_PTP 0x2 6805#define LICENSED_APP_ID_PTP 0x2
6633/* enum: SolarCapture Pro */ 6806/* enum: SolarCapture Pro */
6634#define LICENSED_APP_ID_SOLARCAPTURE_PRO 0x4 6807#define LICENSED_APP_ID_SOLARCAPTURE_PRO 0x4
6635/* enum: SolarSecure filter engine */ 6808/* enum: SolarSecure filter engine */
6636#define LICENSED_APP_ID_SOLARSECURE 0x8 6809#define LICENSED_APP_ID_SOLARSECURE 0x8
6637/* enum: Performance monitor */ 6810/* enum: Performance monitor */
6638#define LICENSED_APP_ID_PERF_MONITOR 0x10 6811#define LICENSED_APP_ID_PERF_MONITOR 0x10
6639/* enum: SolarCapture Live */ 6812/* enum: SolarCapture Live */
6640#define LICENSED_APP_ID_SOLARCAPTURE_LIVE 0x20 6813#define LICENSED_APP_ID_SOLARCAPTURE_LIVE 0x20
6641/* enum: Capture SolarSystem */ 6814/* enum: Capture SolarSystem */
6642#define LICENSED_APP_ID_CAPTURE_SOLARSYSTEM 0x40 6815#define LICENSED_APP_ID_CAPTURE_SOLARSYSTEM 0x40
6643/* enum: Network Access Control */ 6816/* enum: Network Access Control */
6644#define LICENSED_APP_ID_NETWORK_ACCESS_CONTROL 0x80 6817#define LICENSED_APP_ID_NETWORK_ACCESS_CONTROL 0x80
6645/* enum: TCP Direct */ 6818/* enum: TCP Direct */
6646#define LICENSED_APP_ID_TCP_DIRECT 0x100 6819#define LICENSED_APP_ID_TCP_DIRECT 0x100
6647/* enum: Low Latency */ 6820/* enum: Low Latency */
6648#define LICENSED_APP_ID_LOW_LATENCY 0x200 6821#define LICENSED_APP_ID_LOW_LATENCY 0x200
6649/* enum: SolarCapture Tap */ 6822/* enum: SolarCapture Tap */
6650#define LICENSED_APP_ID_SOLARCAPTURE_TAP 0x400 6823#define LICENSED_APP_ID_SOLARCAPTURE_TAP 0x400
6651/* enum: Capture SolarSystem 40G */ 6824/* enum: Capture SolarSystem 40G */
6652#define LICENSED_APP_ID_CAPTURE_SOLARSYSTEM_40G 0x800 6825#define LICENSED_APP_ID_CAPTURE_SOLARSYSTEM_40G 0x800
6653/* enum: Capture SolarSystem 1G */ 6826/* enum: Capture SolarSystem 1G */
6654#define LICENSED_APP_ID_CAPTURE_SOLARSYSTEM_1G 0x1000 6827#define LICENSED_APP_ID_CAPTURE_SOLARSYSTEM_1G 0x1000
6655/* enum: ScaleOut Onload */ 6828/* enum: ScaleOut Onload */
6656#define LICENSED_APP_ID_SCALEOUT_ONLOAD 0x2000 6829#define LICENSED_APP_ID_SCALEOUT_ONLOAD 0x2000
6657/* enum: SCS Network Analytics Dashboard */ 6830/* enum: SCS Network Analytics Dashboard */
6658#define LICENSED_APP_ID_DSHBRD 0x4000 6831#define LICENSED_APP_ID_DSHBRD 0x4000
6659/* enum: SolarCapture Trading Analytics */ 6832/* enum: SolarCapture Trading Analytics */
6660#define LICENSED_APP_ID_SCATRD 0x8000 6833#define LICENSED_APP_ID_SCATRD 0x8000
6661#define LICENSED_APP_ID_ID_LBN 0 6834#define LICENSED_APP_ID_ID_LBN 0
6662#define LICENSED_APP_ID_ID_WIDTH 32 6835#define LICENSED_APP_ID_ID_WIDTH 32
6663 6836
@@ -6775,23 +6948,23 @@
6775#define TX_TIMESTAMP_EVENT_TX_EV_TYPE_OFST 3 6948#define TX_TIMESTAMP_EVENT_TX_EV_TYPE_OFST 3
6776#define TX_TIMESTAMP_EVENT_TX_EV_TYPE_LEN 1 6949#define TX_TIMESTAMP_EVENT_TX_EV_TYPE_LEN 1
6777/* enum: This is a TX completion event, not a timestamp */ 6950/* enum: This is a TX completion event, not a timestamp */
6778#define TX_TIMESTAMP_EVENT_TX_EV_COMPLETION 0x0 6951#define TX_TIMESTAMP_EVENT_TX_EV_COMPLETION 0x0
6779/* enum: This is a TX completion event for a CTPIO transmit. The event format 6952/* enum: This is a TX completion event for a CTPIO transmit. The event format
6780 * is the same as for TX_EV_COMPLETION. 6953 * is the same as for TX_EV_COMPLETION.
6781 */ 6954 */
6782#define TX_TIMESTAMP_EVENT_TX_EV_CTPIO_COMPLETION 0x11 6955#define TX_TIMESTAMP_EVENT_TX_EV_CTPIO_COMPLETION 0x11
6783/* enum: This is the low part of a TX timestamp for a CTPIO transmission. The 6956/* enum: This is the low part of a TX timestamp for a CTPIO transmission. The
6784 * event format is the same as for TX_EV_TSTAMP_LO 6957 * event format is the same as for TX_EV_TSTAMP_LO
6785 */ 6958 */
6786#define TX_TIMESTAMP_EVENT_TX_EV_CTPIO_TS_LO 0x12 6959#define TX_TIMESTAMP_EVENT_TX_EV_CTPIO_TS_LO 0x12
6787/* enum: This is the high part of a TX timestamp for a CTPIO transmission. The 6960/* enum: This is the high part of a TX timestamp for a CTPIO transmission. The
6788 * event format is the same as for TX_EV_TSTAMP_HI 6961 * event format is the same as for TX_EV_TSTAMP_HI
6789 */ 6962 */
6790#define TX_TIMESTAMP_EVENT_TX_EV_CTPIO_TS_HI 0x13 6963#define TX_TIMESTAMP_EVENT_TX_EV_CTPIO_TS_HI 0x13
6791/* enum: This is the low part of a TX timestamp event */ 6964/* enum: This is the low part of a TX timestamp event */
6792#define TX_TIMESTAMP_EVENT_TX_EV_TSTAMP_LO 0x51 6965#define TX_TIMESTAMP_EVENT_TX_EV_TSTAMP_LO 0x51
6793/* enum: This is the high part of a TX timestamp event */ 6966/* enum: This is the high part of a TX timestamp event */
6794#define TX_TIMESTAMP_EVENT_TX_EV_TSTAMP_HI 0x52 6967#define TX_TIMESTAMP_EVENT_TX_EV_TSTAMP_HI 0x52
6795#define TX_TIMESTAMP_EVENT_TX_EV_TYPE_LBN 24 6968#define TX_TIMESTAMP_EVENT_TX_EV_TYPE_LBN 24
6796#define TX_TIMESTAMP_EVENT_TX_EV_TYPE_WIDTH 8 6969#define TX_TIMESTAMP_EVENT_TX_EV_TYPE_WIDTH 8
6797/* upper 16 bits of timestamp data */ 6970/* upper 16 bits of timestamp data */
@@ -7071,17 +7244,17 @@
7071#define QUEUE_CRC_MODE_MODE_LBN 0 7244#define QUEUE_CRC_MODE_MODE_LBN 0
7072#define QUEUE_CRC_MODE_MODE_WIDTH 4 7245#define QUEUE_CRC_MODE_MODE_WIDTH 4
7073/* enum: No CRC. */ 7246/* enum: No CRC. */
7074#define QUEUE_CRC_MODE_NONE 0x0 7247#define QUEUE_CRC_MODE_NONE 0x0
7075/* enum: CRC Fiber channel over ethernet. */ 7248/* enum: CRC Fiber channel over ethernet. */
7076#define QUEUE_CRC_MODE_FCOE 0x1 7249#define QUEUE_CRC_MODE_FCOE 0x1
7077/* enum: CRC (digest) iSCSI header only. */ 7250/* enum: CRC (digest) iSCSI header only. */
7078#define QUEUE_CRC_MODE_ISCSI_HDR 0x2 7251#define QUEUE_CRC_MODE_ISCSI_HDR 0x2
7079/* enum: CRC (digest) iSCSI header and payload. */ 7252/* enum: CRC (digest) iSCSI header and payload. */
7080#define QUEUE_CRC_MODE_ISCSI 0x3 7253#define QUEUE_CRC_MODE_ISCSI 0x3
7081/* enum: CRC Fiber channel over IP over ethernet. */ 7254/* enum: CRC Fiber channel over IP over ethernet. */
7082#define QUEUE_CRC_MODE_FCOIPOE 0x4 7255#define QUEUE_CRC_MODE_FCOIPOE 0x4
7083/* enum: CRC MPA. */ 7256/* enum: CRC MPA. */
7084#define QUEUE_CRC_MODE_MPA 0x5 7257#define QUEUE_CRC_MODE_MPA 0x5
7085#define QUEUE_CRC_MODE_SPARE_LBN 4 7258#define QUEUE_CRC_MODE_SPARE_LBN 4
7086#define QUEUE_CRC_MODE_SPARE_WIDTH 4 7259#define QUEUE_CRC_MODE_SPARE_WIDTH 4
7087 7260
@@ -7157,11 +7330,15 @@
7157/* Size, in entries */ 7330/* Size, in entries */
7158#define MC_CMD_INIT_RXQ_EXT_IN_SIZE_OFST 0 7331#define MC_CMD_INIT_RXQ_EXT_IN_SIZE_OFST 0
7159#define MC_CMD_INIT_RXQ_EXT_IN_SIZE_LEN 4 7332#define MC_CMD_INIT_RXQ_EXT_IN_SIZE_LEN 4
7160/* The EVQ to send events to. This is an index originally specified to INIT_EVQ 7333/* The EVQ to send events to. This is an index originally specified to
7334 * INIT_EVQ. If DMA_MODE == PACKED_STREAM this must be equal to INSTANCE.
7161 */ 7335 */
7162#define MC_CMD_INIT_RXQ_EXT_IN_TARGET_EVQ_OFST 4 7336#define MC_CMD_INIT_RXQ_EXT_IN_TARGET_EVQ_OFST 4
7163#define MC_CMD_INIT_RXQ_EXT_IN_TARGET_EVQ_LEN 4 7337#define MC_CMD_INIT_RXQ_EXT_IN_TARGET_EVQ_LEN 4
7164/* The value to put in the event data. Check hardware spec. for valid range. */ 7338/* The value to put in the event data. Check hardware spec. for valid range.
7339 * This field is ignored if DMA_MODE == EQUAL_STRIDE_PACKED_STREAM or DMA_MODE
7340 * == PACKED_STREAM.
7341 */
7165#define MC_CMD_INIT_RXQ_EXT_IN_LABEL_OFST 8 7342#define MC_CMD_INIT_RXQ_EXT_IN_LABEL_OFST 8
7166#define MC_CMD_INIT_RXQ_EXT_IN_LABEL_LEN 4 7343#define MC_CMD_INIT_RXQ_EXT_IN_LABEL_LEN 4
7167/* Desired instance. Must be set to a specific instance, which is a function 7344/* Desired instance. Must be set to a specific instance, which is a function
@@ -7189,18 +7366,25 @@
7189#define MC_CMD_INIT_RXQ_EXT_IN_DMA_MODE_LBN 10 7366#define MC_CMD_INIT_RXQ_EXT_IN_DMA_MODE_LBN 10
7190#define MC_CMD_INIT_RXQ_EXT_IN_DMA_MODE_WIDTH 4 7367#define MC_CMD_INIT_RXQ_EXT_IN_DMA_MODE_WIDTH 4
7191/* enum: One packet per descriptor (for normal networking) */ 7368/* enum: One packet per descriptor (for normal networking) */
7192#define MC_CMD_INIT_RXQ_EXT_IN_SINGLE_PACKET 0x0 7369#define MC_CMD_INIT_RXQ_EXT_IN_SINGLE_PACKET 0x0
7193/* enum: Pack multiple packets into large descriptors (for SolarCapture) */ 7370/* enum: Pack multiple packets into large descriptors (for SolarCapture) */
7194#define MC_CMD_INIT_RXQ_EXT_IN_PACKED_STREAM 0x1 7371#define MC_CMD_INIT_RXQ_EXT_IN_PACKED_STREAM 0x1
7372/* enum: Pack multiple packets into large descriptors using the format designed
7373 * to maximise packet rate. This mode uses 1 "bucket" per descriptor with
7374 * multiple fixed-size packet buffers within each bucket. For a full
7375 * description see SF-119419-TC. This mode is only supported by "dpdk" datapath
7376 * firmware.
7377 */
7378#define MC_CMD_INIT_RXQ_EXT_IN_EQUAL_STRIDE_PACKED_STREAM 0x2
7195#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_SNAPSHOT_MODE_LBN 14 7379#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_SNAPSHOT_MODE_LBN 14
7196#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_SNAPSHOT_MODE_WIDTH 1 7380#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_SNAPSHOT_MODE_WIDTH 1
7197#define MC_CMD_INIT_RXQ_EXT_IN_PACKED_STREAM_BUFF_SIZE_LBN 15 7381#define MC_CMD_INIT_RXQ_EXT_IN_PACKED_STREAM_BUFF_SIZE_LBN 15
7198#define MC_CMD_INIT_RXQ_EXT_IN_PACKED_STREAM_BUFF_SIZE_WIDTH 3 7382#define MC_CMD_INIT_RXQ_EXT_IN_PACKED_STREAM_BUFF_SIZE_WIDTH 3
7199#define MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_1M 0x0 /* enum */ 7383#define MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_1M 0x0 /* enum */
7200#define MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_512K 0x1 /* enum */ 7384#define MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_512K 0x1 /* enum */
7201#define MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_256K 0x2 /* enum */ 7385#define MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_256K 0x2 /* enum */
7202#define MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_128K 0x3 /* enum */ 7386#define MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_128K 0x3 /* enum */
7203#define MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_64K 0x4 /* enum */ 7387#define MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_64K 0x4 /* enum */
7204#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_WANT_OUTER_CLASSES_LBN 18 7388#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_WANT_OUTER_CLASSES_LBN 18
7205#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_WANT_OUTER_CLASSES_WIDTH 1 7389#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_WANT_OUTER_CLASSES_WIDTH 1
7206#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_FORCE_EV_MERGING_LBN 19 7390#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_FORCE_EV_MERGING_LBN 19
@@ -7221,12 +7405,122 @@
7221#define MC_CMD_INIT_RXQ_EXT_IN_SNAPSHOT_LENGTH_OFST 540 7405#define MC_CMD_INIT_RXQ_EXT_IN_SNAPSHOT_LENGTH_OFST 540
7222#define MC_CMD_INIT_RXQ_EXT_IN_SNAPSHOT_LENGTH_LEN 4 7406#define MC_CMD_INIT_RXQ_EXT_IN_SNAPSHOT_LENGTH_LEN 4
7223 7407
7408/* MC_CMD_INIT_RXQ_V3_IN msgrequest */
7409#define MC_CMD_INIT_RXQ_V3_IN_LEN 560
7410/* Size, in entries */
7411#define MC_CMD_INIT_RXQ_V3_IN_SIZE_OFST 0
7412#define MC_CMD_INIT_RXQ_V3_IN_SIZE_LEN 4
7413/* The EVQ to send events to. This is an index originally specified to
7414 * INIT_EVQ. If DMA_MODE == PACKED_STREAM this must be equal to INSTANCE.
7415 */
7416#define MC_CMD_INIT_RXQ_V3_IN_TARGET_EVQ_OFST 4
7417#define MC_CMD_INIT_RXQ_V3_IN_TARGET_EVQ_LEN 4
7418/* The value to put in the event data. Check hardware spec. for valid range.
7419 * This field is ignored if DMA_MODE == EQUAL_STRIDE_PACKED_STREAM or DMA_MODE
7420 * == PACKED_STREAM.
7421 */
7422#define MC_CMD_INIT_RXQ_V3_IN_LABEL_OFST 8
7423#define MC_CMD_INIT_RXQ_V3_IN_LABEL_LEN 4
7424/* Desired instance. Must be set to a specific instance, which is a function
7425 * local queue index.
7426 */
7427#define MC_CMD_INIT_RXQ_V3_IN_INSTANCE_OFST 12
7428#define MC_CMD_INIT_RXQ_V3_IN_INSTANCE_LEN 4
7429/* There will be more flags here. */
7430#define MC_CMD_INIT_RXQ_V3_IN_FLAGS_OFST 16
7431#define MC_CMD_INIT_RXQ_V3_IN_FLAGS_LEN 4
7432#define MC_CMD_INIT_RXQ_V3_IN_FLAG_BUFF_MODE_LBN 0
7433#define MC_CMD_INIT_RXQ_V3_IN_FLAG_BUFF_MODE_WIDTH 1
7434#define MC_CMD_INIT_RXQ_V3_IN_FLAG_HDR_SPLIT_LBN 1
7435#define MC_CMD_INIT_RXQ_V3_IN_FLAG_HDR_SPLIT_WIDTH 1
7436#define MC_CMD_INIT_RXQ_V3_IN_FLAG_TIMESTAMP_LBN 2
7437#define MC_CMD_INIT_RXQ_V3_IN_FLAG_TIMESTAMP_WIDTH 1
7438#define MC_CMD_INIT_RXQ_V3_IN_CRC_MODE_LBN 3
7439#define MC_CMD_INIT_RXQ_V3_IN_CRC_MODE_WIDTH 4
7440#define MC_CMD_INIT_RXQ_V3_IN_FLAG_CHAIN_LBN 7
7441#define MC_CMD_INIT_RXQ_V3_IN_FLAG_CHAIN_WIDTH 1
7442#define MC_CMD_INIT_RXQ_V3_IN_FLAG_PREFIX_LBN 8
7443#define MC_CMD_INIT_RXQ_V3_IN_FLAG_PREFIX_WIDTH 1
7444#define MC_CMD_INIT_RXQ_V3_IN_FLAG_DISABLE_SCATTER_LBN 9
7445#define MC_CMD_INIT_RXQ_V3_IN_FLAG_DISABLE_SCATTER_WIDTH 1
7446#define MC_CMD_INIT_RXQ_V3_IN_DMA_MODE_LBN 10
7447#define MC_CMD_INIT_RXQ_V3_IN_DMA_MODE_WIDTH 4
7448/* enum: One packet per descriptor (for normal networking) */
7449#define MC_CMD_INIT_RXQ_V3_IN_SINGLE_PACKET 0x0
7450/* enum: Pack multiple packets into large descriptors (for SolarCapture) */
7451#define MC_CMD_INIT_RXQ_V3_IN_PACKED_STREAM 0x1
7452/* enum: Pack multiple packets into large descriptors using the format designed
7453 * to maximise packet rate. This mode uses 1 "bucket" per descriptor with
7454 * multiple fixed-size packet buffers within each bucket. For a full
7455 * description see SF-119419-TC. This mode is only supported by "dpdk" datapath
7456 * firmware.
7457 */
7458#define MC_CMD_INIT_RXQ_V3_IN_EQUAL_STRIDE_PACKED_STREAM 0x2
7459#define MC_CMD_INIT_RXQ_V3_IN_FLAG_SNAPSHOT_MODE_LBN 14
7460#define MC_CMD_INIT_RXQ_V3_IN_FLAG_SNAPSHOT_MODE_WIDTH 1
7461#define MC_CMD_INIT_RXQ_V3_IN_PACKED_STREAM_BUFF_SIZE_LBN 15
7462#define MC_CMD_INIT_RXQ_V3_IN_PACKED_STREAM_BUFF_SIZE_WIDTH 3
7463#define MC_CMD_INIT_RXQ_V3_IN_PS_BUFF_1M 0x0 /* enum */
7464#define MC_CMD_INIT_RXQ_V3_IN_PS_BUFF_512K 0x1 /* enum */
7465#define MC_CMD_INIT_RXQ_V3_IN_PS_BUFF_256K 0x2 /* enum */
7466#define MC_CMD_INIT_RXQ_V3_IN_PS_BUFF_128K 0x3 /* enum */
7467#define MC_CMD_INIT_RXQ_V3_IN_PS_BUFF_64K 0x4 /* enum */
7468#define MC_CMD_INIT_RXQ_V3_IN_FLAG_WANT_OUTER_CLASSES_LBN 18
7469#define MC_CMD_INIT_RXQ_V3_IN_FLAG_WANT_OUTER_CLASSES_WIDTH 1
7470#define MC_CMD_INIT_RXQ_V3_IN_FLAG_FORCE_EV_MERGING_LBN 19
7471#define MC_CMD_INIT_RXQ_V3_IN_FLAG_FORCE_EV_MERGING_WIDTH 1
7472/* Owner ID to use if in buffer mode (zero if physical) */
7473#define MC_CMD_INIT_RXQ_V3_IN_OWNER_ID_OFST 20
7474#define MC_CMD_INIT_RXQ_V3_IN_OWNER_ID_LEN 4
7475/* The port ID associated with the v-adaptor which should contain this DMAQ. */
7476#define MC_CMD_INIT_RXQ_V3_IN_PORT_ID_OFST 24
7477#define MC_CMD_INIT_RXQ_V3_IN_PORT_ID_LEN 4
7478/* 64-bit address of 4k of 4k-aligned host memory buffer */
7479#define MC_CMD_INIT_RXQ_V3_IN_DMA_ADDR_OFST 28
7480#define MC_CMD_INIT_RXQ_V3_IN_DMA_ADDR_LEN 8
7481#define MC_CMD_INIT_RXQ_V3_IN_DMA_ADDR_LO_OFST 28
7482#define MC_CMD_INIT_RXQ_V3_IN_DMA_ADDR_HI_OFST 32
7483#define MC_CMD_INIT_RXQ_V3_IN_DMA_ADDR_NUM 64
7484/* Maximum length of packet to receive, if SNAPSHOT_MODE flag is set */
7485#define MC_CMD_INIT_RXQ_V3_IN_SNAPSHOT_LENGTH_OFST 540
7486#define MC_CMD_INIT_RXQ_V3_IN_SNAPSHOT_LENGTH_LEN 4
7487/* The number of packet buffers that will be contained within each
7488 * EQUAL_STRIDE_PACKED_STREAM format bucket supplied by the driver. This field
7489 * is ignored unless DMA_MODE == EQUAL_STRIDE_PACKED_STREAM.
7490 */
7491#define MC_CMD_INIT_RXQ_V3_IN_ES_PACKET_BUFFERS_PER_BUCKET_OFST 544
7492#define MC_CMD_INIT_RXQ_V3_IN_ES_PACKET_BUFFERS_PER_BUCKET_LEN 4
7493/* The length in bytes of the area in each packet buffer that can be written to
7494 * by the adapter. This is used to store the packet prefix and the packet
7495 * payload. This length does not include any end padding added by the driver.
7496 * This field is ignored unless DMA_MODE == EQUAL_STRIDE_PACKED_STREAM.
7497 */
7498#define MC_CMD_INIT_RXQ_V3_IN_ES_MAX_DMA_LEN_OFST 548
7499#define MC_CMD_INIT_RXQ_V3_IN_ES_MAX_DMA_LEN_LEN 4
7500/* The length in bytes of a single packet buffer within a
7501 * EQUAL_STRIDE_PACKED_STREAM format bucket. This field is ignored unless
7502 * DMA_MODE == EQUAL_STRIDE_PACKED_STREAM.
7503 */
7504#define MC_CMD_INIT_RXQ_V3_IN_ES_PACKET_STRIDE_OFST 552
7505#define MC_CMD_INIT_RXQ_V3_IN_ES_PACKET_STRIDE_LEN 4
7506/* The maximum time in nanoseconds that the datapath will be backpressured if
7507 * there are no RX descriptors available. If the timeout is reached and there
7508 * are still no descriptors then the packet will be dropped. A timeout of 0
7509 * means the datapath will never be blocked. This field is ignored unless
7510 * DMA_MODE == EQUAL_STRIDE_PACKED_STREAM.
7511 */
7512#define MC_CMD_INIT_RXQ_V3_IN_ES_HEAD_OF_LINE_BLOCK_TIMEOUT_OFST 556
7513#define MC_CMD_INIT_RXQ_V3_IN_ES_HEAD_OF_LINE_BLOCK_TIMEOUT_LEN 4
7514
7224/* MC_CMD_INIT_RXQ_OUT msgresponse */ 7515/* MC_CMD_INIT_RXQ_OUT msgresponse */
7225#define MC_CMD_INIT_RXQ_OUT_LEN 0 7516#define MC_CMD_INIT_RXQ_OUT_LEN 0
7226 7517
7227/* MC_CMD_INIT_RXQ_EXT_OUT msgresponse */ 7518/* MC_CMD_INIT_RXQ_EXT_OUT msgresponse */
7228#define MC_CMD_INIT_RXQ_EXT_OUT_LEN 0 7519#define MC_CMD_INIT_RXQ_EXT_OUT_LEN 0
7229 7520
7521/* MC_CMD_INIT_RXQ_V3_OUT msgresponse */
7522#define MC_CMD_INIT_RXQ_V3_OUT_LEN 0
7523
7230 7524
7231/***********************************/ 7525/***********************************/
7232/* MC_CMD_INIT_TXQ 7526/* MC_CMD_INIT_TXQ
@@ -7466,7 +7760,7 @@
7466#define MC_CMD_PROXY_CMD_IN_TARGET_PF_WIDTH 16 7760#define MC_CMD_PROXY_CMD_IN_TARGET_PF_WIDTH 16
7467#define MC_CMD_PROXY_CMD_IN_TARGET_VF_LBN 16 7761#define MC_CMD_PROXY_CMD_IN_TARGET_VF_LBN 16
7468#define MC_CMD_PROXY_CMD_IN_TARGET_VF_WIDTH 16 7762#define MC_CMD_PROXY_CMD_IN_TARGET_VF_WIDTH 16
7469#define MC_CMD_PROXY_CMD_IN_VF_NULL 0xffff /* enum */ 7763#define MC_CMD_PROXY_CMD_IN_VF_NULL 0xffff /* enum */
7470 7764
7471/* MC_CMD_PROXY_CMD_OUT msgresponse */ 7765/* MC_CMD_PROXY_CMD_OUT msgresponse */
7472#define MC_CMD_PROXY_CMD_OUT_LEN 0 7766#define MC_CMD_PROXY_CMD_OUT_LEN 0
@@ -7479,7 +7773,7 @@
7479#define MC_PROXY_STATUS_BUFFER_HANDLE_OFST 0 7773#define MC_PROXY_STATUS_BUFFER_HANDLE_OFST 0
7480#define MC_PROXY_STATUS_BUFFER_HANDLE_LEN 4 7774#define MC_PROXY_STATUS_BUFFER_HANDLE_LEN 4
7481/* enum: An invalid handle. */ 7775/* enum: An invalid handle. */
7482#define MC_PROXY_STATUS_BUFFER_HANDLE_INVALID 0x0 7776#define MC_PROXY_STATUS_BUFFER_HANDLE_INVALID 0x0
7483#define MC_PROXY_STATUS_BUFFER_HANDLE_LBN 0 7777#define MC_PROXY_STATUS_BUFFER_HANDLE_LBN 0
7484#define MC_PROXY_STATUS_BUFFER_HANDLE_WIDTH 32 7778#define MC_PROXY_STATUS_BUFFER_HANDLE_WIDTH 32
7485/* The requesting physical function number */ 7779/* The requesting physical function number */
@@ -7748,17 +8042,17 @@
7748#define MC_CMD_FILTER_OP_IN_OP_OFST 0 8042#define MC_CMD_FILTER_OP_IN_OP_OFST 0
7749#define MC_CMD_FILTER_OP_IN_OP_LEN 4 8043#define MC_CMD_FILTER_OP_IN_OP_LEN 4
7750/* enum: single-recipient filter insert */ 8044/* enum: single-recipient filter insert */
7751#define MC_CMD_FILTER_OP_IN_OP_INSERT 0x0 8045#define MC_CMD_FILTER_OP_IN_OP_INSERT 0x0
7752/* enum: single-recipient filter remove */ 8046/* enum: single-recipient filter remove */
7753#define MC_CMD_FILTER_OP_IN_OP_REMOVE 0x1 8047#define MC_CMD_FILTER_OP_IN_OP_REMOVE 0x1
7754/* enum: multi-recipient filter subscribe */ 8048/* enum: multi-recipient filter subscribe */
7755#define MC_CMD_FILTER_OP_IN_OP_SUBSCRIBE 0x2 8049#define MC_CMD_FILTER_OP_IN_OP_SUBSCRIBE 0x2
7756/* enum: multi-recipient filter unsubscribe */ 8050/* enum: multi-recipient filter unsubscribe */
7757#define MC_CMD_FILTER_OP_IN_OP_UNSUBSCRIBE 0x3 8051#define MC_CMD_FILTER_OP_IN_OP_UNSUBSCRIBE 0x3
7758/* enum: replace one recipient with another (warning - the filter handle may 8052/* enum: replace one recipient with another (warning - the filter handle may
7759 * change) 8053 * change)
7760 */ 8054 */
7761#define MC_CMD_FILTER_OP_IN_OP_REPLACE 0x4 8055#define MC_CMD_FILTER_OP_IN_OP_REPLACE 0x4
7762/* filter handle (for remove / unsubscribe operations) */ 8056/* filter handle (for remove / unsubscribe operations) */
7763#define MC_CMD_FILTER_OP_IN_HANDLE_OFST 4 8057#define MC_CMD_FILTER_OP_IN_HANDLE_OFST 4
7764#define MC_CMD_FILTER_OP_IN_HANDLE_LEN 8 8058#define MC_CMD_FILTER_OP_IN_HANDLE_LEN 8
@@ -7803,15 +8097,15 @@
7803#define MC_CMD_FILTER_OP_IN_RX_DEST_OFST 20 8097#define MC_CMD_FILTER_OP_IN_RX_DEST_OFST 20
7804#define MC_CMD_FILTER_OP_IN_RX_DEST_LEN 4 8098#define MC_CMD_FILTER_OP_IN_RX_DEST_LEN 4
7805/* enum: drop packets */ 8099/* enum: drop packets */
7806#define MC_CMD_FILTER_OP_IN_RX_DEST_DROP 0x0 8100#define MC_CMD_FILTER_OP_IN_RX_DEST_DROP 0x0
7807/* enum: receive to host */ 8101/* enum: receive to host */
7808#define MC_CMD_FILTER_OP_IN_RX_DEST_HOST 0x1 8102#define MC_CMD_FILTER_OP_IN_RX_DEST_HOST 0x1
7809/* enum: receive to MC */ 8103/* enum: receive to MC */
7810#define MC_CMD_FILTER_OP_IN_RX_DEST_MC 0x2 8104#define MC_CMD_FILTER_OP_IN_RX_DEST_MC 0x2
7811/* enum: loop back to TXDP 0 */ 8105/* enum: loop back to TXDP 0 */
7812#define MC_CMD_FILTER_OP_IN_RX_DEST_TX0 0x3 8106#define MC_CMD_FILTER_OP_IN_RX_DEST_TX0 0x3
7813/* enum: loop back to TXDP 1 */ 8107/* enum: loop back to TXDP 1 */
7814#define MC_CMD_FILTER_OP_IN_RX_DEST_TX1 0x4 8108#define MC_CMD_FILTER_OP_IN_RX_DEST_TX1 0x4
7815/* receive queue handle (for multiple queue modes, this is the base queue) */ 8109/* receive queue handle (for multiple queue modes, this is the base queue) */
7816#define MC_CMD_FILTER_OP_IN_RX_QUEUE_OFST 24 8110#define MC_CMD_FILTER_OP_IN_RX_QUEUE_OFST 24
7817#define MC_CMD_FILTER_OP_IN_RX_QUEUE_LEN 4 8111#define MC_CMD_FILTER_OP_IN_RX_QUEUE_LEN 4
@@ -7819,14 +8113,14 @@
7819#define MC_CMD_FILTER_OP_IN_RX_MODE_OFST 28 8113#define MC_CMD_FILTER_OP_IN_RX_MODE_OFST 28
7820#define MC_CMD_FILTER_OP_IN_RX_MODE_LEN 4 8114#define MC_CMD_FILTER_OP_IN_RX_MODE_LEN 4
7821/* enum: receive to just the specified queue */ 8115/* enum: receive to just the specified queue */
7822#define MC_CMD_FILTER_OP_IN_RX_MODE_SIMPLE 0x0 8116#define MC_CMD_FILTER_OP_IN_RX_MODE_SIMPLE 0x0
7823/* enum: receive to multiple queues using RSS context */ 8117/* enum: receive to multiple queues using RSS context */
7824#define MC_CMD_FILTER_OP_IN_RX_MODE_RSS 0x1 8118#define MC_CMD_FILTER_OP_IN_RX_MODE_RSS 0x1
7825/* enum: receive to multiple queues using .1p mapping */ 8119/* enum: receive to multiple queues using .1p mapping */
7826#define MC_CMD_FILTER_OP_IN_RX_MODE_DOT1P_MAPPING 0x2 8120#define MC_CMD_FILTER_OP_IN_RX_MODE_DOT1P_MAPPING 0x2
7827/* enum: install a filter entry that will never match; for test purposes only 8121/* enum: install a filter entry that will never match; for test purposes only
7828 */ 8122 */
7829#define MC_CMD_FILTER_OP_IN_RX_MODE_TEST_NEVER_MATCH 0x80000000 8123#define MC_CMD_FILTER_OP_IN_RX_MODE_TEST_NEVER_MATCH 0x80000000
7830/* RSS context (for RX_MODE_RSS) or .1p mapping handle (for 8124/* RSS context (for RX_MODE_RSS) or .1p mapping handle (for
7831 * RX_MODE_DOT1P_MAPPING), as returned by MC_CMD_RSS_CONTEXT_ALLOC or 8125 * RX_MODE_DOT1P_MAPPING), as returned by MC_CMD_RSS_CONTEXT_ALLOC or
7832 * MC_CMD_DOT1P_MAPPING_ALLOC. 8126 * MC_CMD_DOT1P_MAPPING_ALLOC.
@@ -7843,7 +8137,7 @@
7843#define MC_CMD_FILTER_OP_IN_TX_DEST_OFST 40 8137#define MC_CMD_FILTER_OP_IN_TX_DEST_OFST 40
7844#define MC_CMD_FILTER_OP_IN_TX_DEST_LEN 4 8138#define MC_CMD_FILTER_OP_IN_TX_DEST_LEN 4
7845/* enum: request default behaviour (based on filter type) */ 8139/* enum: request default behaviour (based on filter type) */
7846#define MC_CMD_FILTER_OP_IN_TX_DEST_DEFAULT 0xffffffff 8140#define MC_CMD_FILTER_OP_IN_TX_DEST_DEFAULT 0xffffffff
7847#define MC_CMD_FILTER_OP_IN_TX_DEST_MAC_LBN 0 8141#define MC_CMD_FILTER_OP_IN_TX_DEST_MAC_LBN 0
7848#define MC_CMD_FILTER_OP_IN_TX_DEST_MAC_WIDTH 1 8142#define MC_CMD_FILTER_OP_IN_TX_DEST_MAC_WIDTH 1
7849#define MC_CMD_FILTER_OP_IN_TX_DEST_PM_LBN 1 8143#define MC_CMD_FILTER_OP_IN_TX_DEST_PM_LBN 1
@@ -7971,15 +8265,15 @@
7971#define MC_CMD_FILTER_OP_EXT_IN_RX_DEST_OFST 20 8265#define MC_CMD_FILTER_OP_EXT_IN_RX_DEST_OFST 20
7972#define MC_CMD_FILTER_OP_EXT_IN_RX_DEST_LEN 4 8266#define MC_CMD_FILTER_OP_EXT_IN_RX_DEST_LEN 4
7973/* enum: drop packets */ 8267/* enum: drop packets */
7974#define MC_CMD_FILTER_OP_EXT_IN_RX_DEST_DROP 0x0 8268#define MC_CMD_FILTER_OP_EXT_IN_RX_DEST_DROP 0x0
7975/* enum: receive to host */ 8269/* enum: receive to host */
7976#define MC_CMD_FILTER_OP_EXT_IN_RX_DEST_HOST 0x1 8270#define MC_CMD_FILTER_OP_EXT_IN_RX_DEST_HOST 0x1
7977/* enum: receive to MC */ 8271/* enum: receive to MC */
7978#define MC_CMD_FILTER_OP_EXT_IN_RX_DEST_MC 0x2 8272#define MC_CMD_FILTER_OP_EXT_IN_RX_DEST_MC 0x2
7979/* enum: loop back to TXDP 0 */ 8273/* enum: loop back to TXDP 0 */
7980#define MC_CMD_FILTER_OP_EXT_IN_RX_DEST_TX0 0x3 8274#define MC_CMD_FILTER_OP_EXT_IN_RX_DEST_TX0 0x3
7981/* enum: loop back to TXDP 1 */ 8275/* enum: loop back to TXDP 1 */
7982#define MC_CMD_FILTER_OP_EXT_IN_RX_DEST_TX1 0x4 8276#define MC_CMD_FILTER_OP_EXT_IN_RX_DEST_TX1 0x4
7983/* receive queue handle (for multiple queue modes, this is the base queue) */ 8277/* receive queue handle (for multiple queue modes, this is the base queue) */
7984#define MC_CMD_FILTER_OP_EXT_IN_RX_QUEUE_OFST 24 8278#define MC_CMD_FILTER_OP_EXT_IN_RX_QUEUE_OFST 24
7985#define MC_CMD_FILTER_OP_EXT_IN_RX_QUEUE_LEN 4 8279#define MC_CMD_FILTER_OP_EXT_IN_RX_QUEUE_LEN 4
@@ -7987,14 +8281,14 @@
7987#define MC_CMD_FILTER_OP_EXT_IN_RX_MODE_OFST 28 8281#define MC_CMD_FILTER_OP_EXT_IN_RX_MODE_OFST 28
7988#define MC_CMD_FILTER_OP_EXT_IN_RX_MODE_LEN 4 8282#define MC_CMD_FILTER_OP_EXT_IN_RX_MODE_LEN 4
7989/* enum: receive to just the specified queue */ 8283/* enum: receive to just the specified queue */
7990#define MC_CMD_FILTER_OP_EXT_IN_RX_MODE_SIMPLE 0x0 8284#define MC_CMD_FILTER_OP_EXT_IN_RX_MODE_SIMPLE 0x0
7991/* enum: receive to multiple queues using RSS context */ 8285/* enum: receive to multiple queues using RSS context */
7992#define MC_CMD_FILTER_OP_EXT_IN_RX_MODE_RSS 0x1 8286#define MC_CMD_FILTER_OP_EXT_IN_RX_MODE_RSS 0x1
7993/* enum: receive to multiple queues using .1p mapping */ 8287/* enum: receive to multiple queues using .1p mapping */
7994#define MC_CMD_FILTER_OP_EXT_IN_RX_MODE_DOT1P_MAPPING 0x2 8288#define MC_CMD_FILTER_OP_EXT_IN_RX_MODE_DOT1P_MAPPING 0x2
7995/* enum: install a filter entry that will never match; for test purposes only 8289/* enum: install a filter entry that will never match; for test purposes only
7996 */ 8290 */
7997#define MC_CMD_FILTER_OP_EXT_IN_RX_MODE_TEST_NEVER_MATCH 0x80000000 8291#define MC_CMD_FILTER_OP_EXT_IN_RX_MODE_TEST_NEVER_MATCH 0x80000000
7998/* RSS context (for RX_MODE_RSS) or .1p mapping handle (for 8292/* RSS context (for RX_MODE_RSS) or .1p mapping handle (for
7999 * RX_MODE_DOT1P_MAPPING), as returned by MC_CMD_RSS_CONTEXT_ALLOC or 8293 * RX_MODE_DOT1P_MAPPING), as returned by MC_CMD_RSS_CONTEXT_ALLOC or
8000 * MC_CMD_DOT1P_MAPPING_ALLOC. 8294 * MC_CMD_DOT1P_MAPPING_ALLOC.
@@ -8011,7 +8305,7 @@
8011#define MC_CMD_FILTER_OP_EXT_IN_TX_DEST_OFST 40 8305#define MC_CMD_FILTER_OP_EXT_IN_TX_DEST_OFST 40
8012#define MC_CMD_FILTER_OP_EXT_IN_TX_DEST_LEN 4 8306#define MC_CMD_FILTER_OP_EXT_IN_TX_DEST_LEN 4
8013/* enum: request default behaviour (based on filter type) */ 8307/* enum: request default behaviour (based on filter type) */
8014#define MC_CMD_FILTER_OP_EXT_IN_TX_DEST_DEFAULT 0xffffffff 8308#define MC_CMD_FILTER_OP_EXT_IN_TX_DEST_DEFAULT 0xffffffff
8015#define MC_CMD_FILTER_OP_EXT_IN_TX_DEST_MAC_LBN 0 8309#define MC_CMD_FILTER_OP_EXT_IN_TX_DEST_MAC_LBN 0
8016#define MC_CMD_FILTER_OP_EXT_IN_TX_DEST_MAC_WIDTH 1 8310#define MC_CMD_FILTER_OP_EXT_IN_TX_DEST_MAC_WIDTH 1
8017#define MC_CMD_FILTER_OP_EXT_IN_TX_DEST_PM_LBN 1 8311#define MC_CMD_FILTER_OP_EXT_IN_TX_DEST_PM_LBN 1
@@ -8054,17 +8348,17 @@
8054#define MC_CMD_FILTER_OP_EXT_IN_VNI_TYPE_LBN 24 8348#define MC_CMD_FILTER_OP_EXT_IN_VNI_TYPE_LBN 24
8055#define MC_CMD_FILTER_OP_EXT_IN_VNI_TYPE_WIDTH 8 8349#define MC_CMD_FILTER_OP_EXT_IN_VNI_TYPE_WIDTH 8
8056/* enum: Match VXLAN traffic with this VNI */ 8350/* enum: Match VXLAN traffic with this VNI */
8057#define MC_CMD_FILTER_OP_EXT_IN_VNI_TYPE_VXLAN 0x0 8351#define MC_CMD_FILTER_OP_EXT_IN_VNI_TYPE_VXLAN 0x0
8058/* enum: Match Geneve traffic with this VNI */ 8352/* enum: Match Geneve traffic with this VNI */
8059#define MC_CMD_FILTER_OP_EXT_IN_VNI_TYPE_GENEVE 0x1 8353#define MC_CMD_FILTER_OP_EXT_IN_VNI_TYPE_GENEVE 0x1
8060/* enum: Reserved for experimental development use */ 8354/* enum: Reserved for experimental development use */
8061#define MC_CMD_FILTER_OP_EXT_IN_VNI_TYPE_EXPERIMENTAL 0xfe 8355#define MC_CMD_FILTER_OP_EXT_IN_VNI_TYPE_EXPERIMENTAL 0xfe
8062#define MC_CMD_FILTER_OP_EXT_IN_VSID_VALUE_LBN 0 8356#define MC_CMD_FILTER_OP_EXT_IN_VSID_VALUE_LBN 0
8063#define MC_CMD_FILTER_OP_EXT_IN_VSID_VALUE_WIDTH 24 8357#define MC_CMD_FILTER_OP_EXT_IN_VSID_VALUE_WIDTH 24
8064#define MC_CMD_FILTER_OP_EXT_IN_VSID_TYPE_LBN 24 8358#define MC_CMD_FILTER_OP_EXT_IN_VSID_TYPE_LBN 24
8065#define MC_CMD_FILTER_OP_EXT_IN_VSID_TYPE_WIDTH 8 8359#define MC_CMD_FILTER_OP_EXT_IN_VSID_TYPE_WIDTH 8
8066/* enum: Match NVGRE traffic with this VSID */ 8360/* enum: Match NVGRE traffic with this VSID */
8067#define MC_CMD_FILTER_OP_EXT_IN_VSID_TYPE_NVGRE 0x0 8361#define MC_CMD_FILTER_OP_EXT_IN_VSID_TYPE_NVGRE 0x0
8068/* source IP address to match (as bytes in network order; set last 12 bytes to 8362/* source IP address to match (as bytes in network order; set last 12 bytes to
8069 * 0 for IPv4 address) 8363 * 0 for IPv4 address)
8070 */ 8364 */
@@ -8131,6 +8425,273 @@
8131#define MC_CMD_FILTER_OP_EXT_IN_IFRM_DST_IP_OFST 156 8425#define MC_CMD_FILTER_OP_EXT_IN_IFRM_DST_IP_OFST 156
8132#define MC_CMD_FILTER_OP_EXT_IN_IFRM_DST_IP_LEN 16 8426#define MC_CMD_FILTER_OP_EXT_IN_IFRM_DST_IP_LEN 16
8133 8427
8428/* MC_CMD_FILTER_OP_V3_IN msgrequest: FILTER_OP extension to support additional
8429 * filter actions for Intel's DPDK (Data Plane Development Kit, dpdk.org) via
8430 * its rte_flow API. This extension is only useful with the sfc_efx driver
8431 * included as part of DPDK, used in conjunction with the dpdk datapath
8432 * firmware variant.
8433 */
8434#define MC_CMD_FILTER_OP_V3_IN_LEN 180
8435/* identifies the type of operation requested */
8436#define MC_CMD_FILTER_OP_V3_IN_OP_OFST 0
8437#define MC_CMD_FILTER_OP_V3_IN_OP_LEN 4
8438/* Enum values, see field(s): */
8439/* MC_CMD_FILTER_OP_IN/OP */
8440/* filter handle (for remove / unsubscribe operations) */
8441#define MC_CMD_FILTER_OP_V3_IN_HANDLE_OFST 4
8442#define MC_CMD_FILTER_OP_V3_IN_HANDLE_LEN 8
8443#define MC_CMD_FILTER_OP_V3_IN_HANDLE_LO_OFST 4
8444#define MC_CMD_FILTER_OP_V3_IN_HANDLE_HI_OFST 8
8445/* The port ID associated with the v-adaptor which should contain this filter.
8446 */
8447#define MC_CMD_FILTER_OP_V3_IN_PORT_ID_OFST 12
8448#define MC_CMD_FILTER_OP_V3_IN_PORT_ID_LEN 4
8449/* fields to include in match criteria */
8450#define MC_CMD_FILTER_OP_V3_IN_MATCH_FIELDS_OFST 16
8451#define MC_CMD_FILTER_OP_V3_IN_MATCH_FIELDS_LEN 4
8452#define MC_CMD_FILTER_OP_V3_IN_MATCH_SRC_IP_LBN 0
8453#define MC_CMD_FILTER_OP_V3_IN_MATCH_SRC_IP_WIDTH 1
8454#define MC_CMD_FILTER_OP_V3_IN_MATCH_DST_IP_LBN 1
8455#define MC_CMD_FILTER_OP_V3_IN_MATCH_DST_IP_WIDTH 1
8456#define MC_CMD_FILTER_OP_V3_IN_MATCH_SRC_MAC_LBN 2
8457#define MC_CMD_FILTER_OP_V3_IN_MATCH_SRC_MAC_WIDTH 1
8458#define MC_CMD_FILTER_OP_V3_IN_MATCH_SRC_PORT_LBN 3
8459#define MC_CMD_FILTER_OP_V3_IN_MATCH_SRC_PORT_WIDTH 1
8460#define MC_CMD_FILTER_OP_V3_IN_MATCH_DST_MAC_LBN 4
8461#define MC_CMD_FILTER_OP_V3_IN_MATCH_DST_MAC_WIDTH 1
8462#define MC_CMD_FILTER_OP_V3_IN_MATCH_DST_PORT_LBN 5
8463#define MC_CMD_FILTER_OP_V3_IN_MATCH_DST_PORT_WIDTH 1
8464#define MC_CMD_FILTER_OP_V3_IN_MATCH_ETHER_TYPE_LBN 6
8465#define MC_CMD_FILTER_OP_V3_IN_MATCH_ETHER_TYPE_WIDTH 1
8466#define MC_CMD_FILTER_OP_V3_IN_MATCH_INNER_VLAN_LBN 7
8467#define MC_CMD_FILTER_OP_V3_IN_MATCH_INNER_VLAN_WIDTH 1
8468#define MC_CMD_FILTER_OP_V3_IN_MATCH_OUTER_VLAN_LBN 8
8469#define MC_CMD_FILTER_OP_V3_IN_MATCH_OUTER_VLAN_WIDTH 1
8470#define MC_CMD_FILTER_OP_V3_IN_MATCH_IP_PROTO_LBN 9
8471#define MC_CMD_FILTER_OP_V3_IN_MATCH_IP_PROTO_WIDTH 1
8472#define MC_CMD_FILTER_OP_V3_IN_MATCH_FWDEF0_LBN 10
8473#define MC_CMD_FILTER_OP_V3_IN_MATCH_FWDEF0_WIDTH 1
8474#define MC_CMD_FILTER_OP_V3_IN_MATCH_VNI_OR_VSID_LBN 11
8475#define MC_CMD_FILTER_OP_V3_IN_MATCH_VNI_OR_VSID_WIDTH 1
8476#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_SRC_IP_LBN 12
8477#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_SRC_IP_WIDTH 1
8478#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_DST_IP_LBN 13
8479#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_DST_IP_WIDTH 1
8480#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_SRC_MAC_LBN 14
8481#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_SRC_MAC_WIDTH 1
8482#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_SRC_PORT_LBN 15
8483#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_SRC_PORT_WIDTH 1
8484#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_DST_MAC_LBN 16
8485#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_DST_MAC_WIDTH 1
8486#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_DST_PORT_LBN 17
8487#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_DST_PORT_WIDTH 1
8488#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_ETHER_TYPE_LBN 18
8489#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_ETHER_TYPE_WIDTH 1
8490#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_INNER_VLAN_LBN 19
8491#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_INNER_VLAN_WIDTH 1
8492#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_OUTER_VLAN_LBN 20
8493#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_OUTER_VLAN_WIDTH 1
8494#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_IP_PROTO_LBN 21
8495#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_IP_PROTO_WIDTH 1
8496#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_FWDEF0_LBN 22
8497#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_FWDEF0_WIDTH 1
8498#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_FWDEF1_LBN 23
8499#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_FWDEF1_WIDTH 1
8500#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_UNKNOWN_MCAST_DST_LBN 24
8501#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_UNKNOWN_MCAST_DST_WIDTH 1
8502#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_UNKNOWN_UCAST_DST_LBN 25
8503#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_UNKNOWN_UCAST_DST_WIDTH 1
8504#define MC_CMD_FILTER_OP_V3_IN_MATCH_UNKNOWN_MCAST_DST_LBN 30
8505#define MC_CMD_FILTER_OP_V3_IN_MATCH_UNKNOWN_MCAST_DST_WIDTH 1
8506#define MC_CMD_FILTER_OP_V3_IN_MATCH_UNKNOWN_UCAST_DST_LBN 31
8507#define MC_CMD_FILTER_OP_V3_IN_MATCH_UNKNOWN_UCAST_DST_WIDTH 1
8508/* receive destination */
8509#define MC_CMD_FILTER_OP_V3_IN_RX_DEST_OFST 20
8510#define MC_CMD_FILTER_OP_V3_IN_RX_DEST_LEN 4
8511/* enum: drop packets */
8512#define MC_CMD_FILTER_OP_V3_IN_RX_DEST_DROP 0x0
8513/* enum: receive to host */
8514#define MC_CMD_FILTER_OP_V3_IN_RX_DEST_HOST 0x1
8515/* enum: receive to MC */
8516#define MC_CMD_FILTER_OP_V3_IN_RX_DEST_MC 0x2
8517/* enum: loop back to TXDP 0 */
8518#define MC_CMD_FILTER_OP_V3_IN_RX_DEST_TX0 0x3
8519/* enum: loop back to TXDP 1 */
8520#define MC_CMD_FILTER_OP_V3_IN_RX_DEST_TX1 0x4
8521/* receive queue handle (for multiple queue modes, this is the base queue) */
8522#define MC_CMD_FILTER_OP_V3_IN_RX_QUEUE_OFST 24
8523#define MC_CMD_FILTER_OP_V3_IN_RX_QUEUE_LEN 4
8524/* receive mode */
8525#define MC_CMD_FILTER_OP_V3_IN_RX_MODE_OFST 28
8526#define MC_CMD_FILTER_OP_V3_IN_RX_MODE_LEN 4
8527/* enum: receive to just the specified queue */
8528#define MC_CMD_FILTER_OP_V3_IN_RX_MODE_SIMPLE 0x0
8529/* enum: receive to multiple queues using RSS context */
8530#define MC_CMD_FILTER_OP_V3_IN_RX_MODE_RSS 0x1
8531/* enum: receive to multiple queues using .1p mapping */
8532#define MC_CMD_FILTER_OP_V3_IN_RX_MODE_DOT1P_MAPPING 0x2
8533/* enum: install a filter entry that will never match; for test purposes only
8534 */
8535#define MC_CMD_FILTER_OP_V3_IN_RX_MODE_TEST_NEVER_MATCH 0x80000000
8536/* RSS context (for RX_MODE_RSS) or .1p mapping handle (for
8537 * RX_MODE_DOT1P_MAPPING), as returned by MC_CMD_RSS_CONTEXT_ALLOC or
8538 * MC_CMD_DOT1P_MAPPING_ALLOC.
8539 */
8540#define MC_CMD_FILTER_OP_V3_IN_RX_CONTEXT_OFST 32
8541#define MC_CMD_FILTER_OP_V3_IN_RX_CONTEXT_LEN 4
8542/* transmit domain (reserved; set to 0) */
8543#define MC_CMD_FILTER_OP_V3_IN_TX_DOMAIN_OFST 36
8544#define MC_CMD_FILTER_OP_V3_IN_TX_DOMAIN_LEN 4
8545/* transmit destination (either set the MAC and/or PM bits for explicit
8546 * control, or set this field to TX_DEST_DEFAULT for sensible default
8547 * behaviour)
8548 */
8549#define MC_CMD_FILTER_OP_V3_IN_TX_DEST_OFST 40
8550#define MC_CMD_FILTER_OP_V3_IN_TX_DEST_LEN 4
8551/* enum: request default behaviour (based on filter type) */
8552#define MC_CMD_FILTER_OP_V3_IN_TX_DEST_DEFAULT 0xffffffff
8553#define MC_CMD_FILTER_OP_V3_IN_TX_DEST_MAC_LBN 0
8554#define MC_CMD_FILTER_OP_V3_IN_TX_DEST_MAC_WIDTH 1
8555#define MC_CMD_FILTER_OP_V3_IN_TX_DEST_PM_LBN 1
8556#define MC_CMD_FILTER_OP_V3_IN_TX_DEST_PM_WIDTH 1
8557/* source MAC address to match (as bytes in network order) */
8558#define MC_CMD_FILTER_OP_V3_IN_SRC_MAC_OFST 44
8559#define MC_CMD_FILTER_OP_V3_IN_SRC_MAC_LEN 6
8560/* source port to match (as bytes in network order) */
8561#define MC_CMD_FILTER_OP_V3_IN_SRC_PORT_OFST 50
8562#define MC_CMD_FILTER_OP_V3_IN_SRC_PORT_LEN 2
8563/* destination MAC address to match (as bytes in network order) */
8564#define MC_CMD_FILTER_OP_V3_IN_DST_MAC_OFST 52
8565#define MC_CMD_FILTER_OP_V3_IN_DST_MAC_LEN 6
8566/* destination port to match (as bytes in network order) */
8567#define MC_CMD_FILTER_OP_V3_IN_DST_PORT_OFST 58
8568#define MC_CMD_FILTER_OP_V3_IN_DST_PORT_LEN 2
8569/* Ethernet type to match (as bytes in network order) */
8570#define MC_CMD_FILTER_OP_V3_IN_ETHER_TYPE_OFST 60
8571#define MC_CMD_FILTER_OP_V3_IN_ETHER_TYPE_LEN 2
8572/* Inner VLAN tag to match (as bytes in network order) */
8573#define MC_CMD_FILTER_OP_V3_IN_INNER_VLAN_OFST 62
8574#define MC_CMD_FILTER_OP_V3_IN_INNER_VLAN_LEN 2
8575/* Outer VLAN tag to match (as bytes in network order) */
8576#define MC_CMD_FILTER_OP_V3_IN_OUTER_VLAN_OFST 64
8577#define MC_CMD_FILTER_OP_V3_IN_OUTER_VLAN_LEN 2
8578/* IP protocol to match (in low byte; set high byte to 0) */
8579#define MC_CMD_FILTER_OP_V3_IN_IP_PROTO_OFST 66
8580#define MC_CMD_FILTER_OP_V3_IN_IP_PROTO_LEN 2
8581/* Firmware defined register 0 to match (reserved; set to 0) */
8582#define MC_CMD_FILTER_OP_V3_IN_FWDEF0_OFST 68
8583#define MC_CMD_FILTER_OP_V3_IN_FWDEF0_LEN 4
8584/* VNI (for VXLAN/Geneve, when IP protocol is UDP) or VSID (for NVGRE, when IP
8585 * protocol is GRE) to match (as bytes in network order; set last byte to 0 for
8586 * VXLAN/NVGRE, or 1 for Geneve)
8587 */
8588#define MC_CMD_FILTER_OP_V3_IN_VNI_OR_VSID_OFST 72
8589#define MC_CMD_FILTER_OP_V3_IN_VNI_OR_VSID_LEN 4
8590#define MC_CMD_FILTER_OP_V3_IN_VNI_VALUE_LBN 0
8591#define MC_CMD_FILTER_OP_V3_IN_VNI_VALUE_WIDTH 24
8592#define MC_CMD_FILTER_OP_V3_IN_VNI_TYPE_LBN 24
8593#define MC_CMD_FILTER_OP_V3_IN_VNI_TYPE_WIDTH 8
8594/* enum: Match VXLAN traffic with this VNI */
8595#define MC_CMD_FILTER_OP_V3_IN_VNI_TYPE_VXLAN 0x0
8596/* enum: Match Geneve traffic with this VNI */
8597#define MC_CMD_FILTER_OP_V3_IN_VNI_TYPE_GENEVE 0x1
8598/* enum: Reserved for experimental development use */
8599#define MC_CMD_FILTER_OP_V3_IN_VNI_TYPE_EXPERIMENTAL 0xfe
8600#define MC_CMD_FILTER_OP_V3_IN_VSID_VALUE_LBN 0
8601#define MC_CMD_FILTER_OP_V3_IN_VSID_VALUE_WIDTH 24
8602#define MC_CMD_FILTER_OP_V3_IN_VSID_TYPE_LBN 24
8603#define MC_CMD_FILTER_OP_V3_IN_VSID_TYPE_WIDTH 8
8604/* enum: Match NVGRE traffic with this VSID */
8605#define MC_CMD_FILTER_OP_V3_IN_VSID_TYPE_NVGRE 0x0
8606/* source IP address to match (as bytes in network order; set last 12 bytes to
8607 * 0 for IPv4 address)
8608 */
8609#define MC_CMD_FILTER_OP_V3_IN_SRC_IP_OFST 76
8610#define MC_CMD_FILTER_OP_V3_IN_SRC_IP_LEN 16
8611/* destination IP address to match (as bytes in network order; set last 12
8612 * bytes to 0 for IPv4 address)
8613 */
8614#define MC_CMD_FILTER_OP_V3_IN_DST_IP_OFST 92
8615#define MC_CMD_FILTER_OP_V3_IN_DST_IP_LEN 16
8616/* VXLAN/NVGRE inner frame source MAC address to match (as bytes in network
8617 * order)
8618 */
8619#define MC_CMD_FILTER_OP_V3_IN_IFRM_SRC_MAC_OFST 108
8620#define MC_CMD_FILTER_OP_V3_IN_IFRM_SRC_MAC_LEN 6
8621/* VXLAN/NVGRE inner frame source port to match (as bytes in network order) */
8622#define MC_CMD_FILTER_OP_V3_IN_IFRM_SRC_PORT_OFST 114
8623#define MC_CMD_FILTER_OP_V3_IN_IFRM_SRC_PORT_LEN 2
8624/* VXLAN/NVGRE inner frame destination MAC address to match (as bytes in
8625 * network order)
8626 */
8627#define MC_CMD_FILTER_OP_V3_IN_IFRM_DST_MAC_OFST 116
8628#define MC_CMD_FILTER_OP_V3_IN_IFRM_DST_MAC_LEN 6
8629/* VXLAN/NVGRE inner frame destination port to match (as bytes in network
8630 * order)
8631 */
8632#define MC_CMD_FILTER_OP_V3_IN_IFRM_DST_PORT_OFST 122
8633#define MC_CMD_FILTER_OP_V3_IN_IFRM_DST_PORT_LEN 2
8634/* VXLAN/NVGRE inner frame Ethernet type to match (as bytes in network order)
8635 */
8636#define MC_CMD_FILTER_OP_V3_IN_IFRM_ETHER_TYPE_OFST 124
8637#define MC_CMD_FILTER_OP_V3_IN_IFRM_ETHER_TYPE_LEN 2
8638/* VXLAN/NVGRE inner frame Inner VLAN tag to match (as bytes in network order)
8639 */
8640#define MC_CMD_FILTER_OP_V3_IN_IFRM_INNER_VLAN_OFST 126
8641#define MC_CMD_FILTER_OP_V3_IN_IFRM_INNER_VLAN_LEN 2
8642/* VXLAN/NVGRE inner frame Outer VLAN tag to match (as bytes in network order)
8643 */
8644#define MC_CMD_FILTER_OP_V3_IN_IFRM_OUTER_VLAN_OFST 128
8645#define MC_CMD_FILTER_OP_V3_IN_IFRM_OUTER_VLAN_LEN 2
8646/* VXLAN/NVGRE inner frame IP protocol to match (in low byte; set high byte to
8647 * 0)
8648 */
8649#define MC_CMD_FILTER_OP_V3_IN_IFRM_IP_PROTO_OFST 130
8650#define MC_CMD_FILTER_OP_V3_IN_IFRM_IP_PROTO_LEN 2
8651/* VXLAN/NVGRE inner frame Firmware defined register 0 to match (reserved; set
8652 * to 0)
8653 */
8654#define MC_CMD_FILTER_OP_V3_IN_IFRM_FWDEF0_OFST 132
8655#define MC_CMD_FILTER_OP_V3_IN_IFRM_FWDEF0_LEN 4
8656/* VXLAN/NVGRE inner frame Firmware defined register 1 to match (reserved; set
8657 * to 0)
8658 */
8659#define MC_CMD_FILTER_OP_V3_IN_IFRM_FWDEF1_OFST 136
8660#define MC_CMD_FILTER_OP_V3_IN_IFRM_FWDEF1_LEN 4
8661/* VXLAN/NVGRE inner frame source IP address to match (as bytes in network
8662 * order; set last 12 bytes to 0 for IPv4 address)
8663 */
8664#define MC_CMD_FILTER_OP_V3_IN_IFRM_SRC_IP_OFST 140
8665#define MC_CMD_FILTER_OP_V3_IN_IFRM_SRC_IP_LEN 16
8666/* VXLAN/NVGRE inner frame destination IP address to match (as bytes in network
8667 * order; set last 12 bytes to 0 for IPv4 address)
8668 */
8669#define MC_CMD_FILTER_OP_V3_IN_IFRM_DST_IP_OFST 156
8670#define MC_CMD_FILTER_OP_V3_IN_IFRM_DST_IP_LEN 16
8671/* Set an action for all packets matching this filter. The DPDK driver and dpdk
8672 * f/w variant use their own specific delivery structures, which are documented
8673 * in the DPDK Firmware Driver Interface (SF-119419-TC). Requesting anything
8674 * other than MATCH_ACTION_NONE when the NIC is running another f/w variant
8675 * will cause the filter insertion to fail with ENOTSUP.
8676 */
8677#define MC_CMD_FILTER_OP_V3_IN_MATCH_ACTION_OFST 172
8678#define MC_CMD_FILTER_OP_V3_IN_MATCH_ACTION_LEN 4
8679/* enum: do nothing extra */
8680#define MC_CMD_FILTER_OP_V3_IN_MATCH_ACTION_NONE 0x0
8681/* enum: Set the match flag in the packet prefix for packets matching the
8682 * filter (only with dpdk firmware, otherwise fails with ENOTSUP). Used to
8683 * support the DPDK rte_flow "FLAG" action.
8684 */
8685#define MC_CMD_FILTER_OP_V3_IN_MATCH_ACTION_FLAG 0x1
8686/* enum: Insert MATCH_MARK_VALUE into the packet prefix for packets matching
8687 * the filter (only with dpdk firmware, otherwise fails with ENOTSUP). Used to
8688 * support the DPDK rte_flow "MARK" action.
8689 */
8690#define MC_CMD_FILTER_OP_V3_IN_MATCH_ACTION_MARK 0x2
8691/* the mark value for MATCH_ACTION_MARK */
8692#define MC_CMD_FILTER_OP_V3_IN_MATCH_MARK_VALUE_OFST 176
8693#define MC_CMD_FILTER_OP_V3_IN_MATCH_MARK_VALUE_LEN 4
8694
8134/* MC_CMD_FILTER_OP_OUT msgresponse */ 8695/* MC_CMD_FILTER_OP_OUT msgresponse */
8135#define MC_CMD_FILTER_OP_OUT_LEN 12 8696#define MC_CMD_FILTER_OP_OUT_LEN 12
8136/* identifies the type of operation requested */ 8697/* identifies the type of operation requested */
@@ -8147,9 +8708,9 @@
8147#define MC_CMD_FILTER_OP_OUT_HANDLE_LO_OFST 4 8708#define MC_CMD_FILTER_OP_OUT_HANDLE_LO_OFST 4
8148#define MC_CMD_FILTER_OP_OUT_HANDLE_HI_OFST 8 8709#define MC_CMD_FILTER_OP_OUT_HANDLE_HI_OFST 8
8149/* enum: guaranteed invalid filter handle (low 32 bits) */ 8710/* enum: guaranteed invalid filter handle (low 32 bits) */
8150#define MC_CMD_FILTER_OP_OUT_HANDLE_LO_INVALID 0xffffffff 8711#define MC_CMD_FILTER_OP_OUT_HANDLE_LO_INVALID 0xffffffff
8151/* enum: guaranteed invalid filter handle (high 32 bits) */ 8712/* enum: guaranteed invalid filter handle (high 32 bits) */
8152#define MC_CMD_FILTER_OP_OUT_HANDLE_HI_INVALID 0xffffffff 8713#define MC_CMD_FILTER_OP_OUT_HANDLE_HI_INVALID 0xffffffff
8153 8714
8154/* MC_CMD_FILTER_OP_EXT_OUT msgresponse */ 8715/* MC_CMD_FILTER_OP_EXT_OUT msgresponse */
8155#define MC_CMD_FILTER_OP_EXT_OUT_LEN 12 8716#define MC_CMD_FILTER_OP_EXT_OUT_LEN 12
@@ -8184,20 +8745,20 @@
8184#define MC_CMD_GET_PARSER_DISP_INFO_IN_OP_OFST 0 8745#define MC_CMD_GET_PARSER_DISP_INFO_IN_OP_OFST 0
8185#define MC_CMD_GET_PARSER_DISP_INFO_IN_OP_LEN 4 8746#define MC_CMD_GET_PARSER_DISP_INFO_IN_OP_LEN 4
8186/* enum: read the list of supported RX filter matches */ 8747/* enum: read the list of supported RX filter matches */
8187#define MC_CMD_GET_PARSER_DISP_INFO_IN_OP_GET_SUPPORTED_RX_MATCHES 0x1 8748#define MC_CMD_GET_PARSER_DISP_INFO_IN_OP_GET_SUPPORTED_RX_MATCHES 0x1
8188/* enum: read flags indicating restrictions on filter insertion for the calling 8749/* enum: read flags indicating restrictions on filter insertion for the calling
8189 * client 8750 * client
8190 */ 8751 */
8191#define MC_CMD_GET_PARSER_DISP_INFO_IN_OP_GET_RESTRICTIONS 0x2 8752#define MC_CMD_GET_PARSER_DISP_INFO_IN_OP_GET_RESTRICTIONS 0x2
8192/* enum: read properties relating to security rules (Medford-only; for use by 8753/* enum: read properties relating to security rules (Medford-only; for use by
8193 * SolarSecure apps, not directly by drivers. See SF-114946-SW.) 8754 * SolarSecure apps, not directly by drivers. See SF-114946-SW.)
8194 */ 8755 */
8195#define MC_CMD_GET_PARSER_DISP_INFO_IN_OP_GET_SECURITY_RULE_INFO 0x3 8756#define MC_CMD_GET_PARSER_DISP_INFO_IN_OP_GET_SECURITY_RULE_INFO 0x3
8196/* enum: read the list of supported RX filter matches for VXLAN/NVGRE 8757/* enum: read the list of supported RX filter matches for VXLAN/NVGRE
8197 * encapsulated frames, which follow a different match sequence to normal 8758 * encapsulated frames, which follow a different match sequence to normal
8198 * frames (Medford only) 8759 * frames (Medford only)
8199 */ 8760 */
8200#define MC_CMD_GET_PARSER_DISP_INFO_IN_OP_GET_SUPPORTED_ENCAP_RX_MATCHES 0x4 8761#define MC_CMD_GET_PARSER_DISP_INFO_IN_OP_GET_SUPPORTED_ENCAP_RX_MATCHES 0x4
8201 8762
8202/* MC_CMD_GET_PARSER_DISP_INFO_OUT msgresponse */ 8763/* MC_CMD_GET_PARSER_DISP_INFO_OUT msgresponse */
8203#define MC_CMD_GET_PARSER_DISP_INFO_OUT_LENMIN 8 8764#define MC_CMD_GET_PARSER_DISP_INFO_OUT_LENMIN 8
@@ -8238,7 +8799,9 @@
8238 * Direct read/write of parser-dispatcher state (DICPUs and LUE) for debugging. 8799 * Direct read/write of parser-dispatcher state (DICPUs and LUE) for debugging.
8239 * Please note that this interface is only of use to debug tools which have 8800 * Please note that this interface is only of use to debug tools which have
8240 * knowledge of firmware and hardware data structures; nothing here is intended 8801 * knowledge of firmware and hardware data structures; nothing here is intended
8241 * for use by normal driver code. 8802 * for use by normal driver code. Note that although this command is in the
8803 * Admin privilege group, in tamperproof adapters, only read operations are
8804 * permitted.
8242 */ 8805 */
8243#define MC_CMD_PARSER_DISP_RW 0xe5 8806#define MC_CMD_PARSER_DISP_RW 0xe5
8244 8807
@@ -8250,32 +8813,36 @@
8250#define MC_CMD_PARSER_DISP_RW_IN_TARGET_OFST 0 8813#define MC_CMD_PARSER_DISP_RW_IN_TARGET_OFST 0
8251#define MC_CMD_PARSER_DISP_RW_IN_TARGET_LEN 4 8814#define MC_CMD_PARSER_DISP_RW_IN_TARGET_LEN 4
8252/* enum: RX dispatcher CPU */ 8815/* enum: RX dispatcher CPU */
8253#define MC_CMD_PARSER_DISP_RW_IN_RX_DICPU 0x0 8816#define MC_CMD_PARSER_DISP_RW_IN_RX_DICPU 0x0
8254/* enum: TX dispatcher CPU */ 8817/* enum: TX dispatcher CPU */
8255#define MC_CMD_PARSER_DISP_RW_IN_TX_DICPU 0x1 8818#define MC_CMD_PARSER_DISP_RW_IN_TX_DICPU 0x1
8256/* enum: Lookup engine (with original metadata format). Deprecated; used only 8819/* enum: Lookup engine (with original metadata format). Deprecated; used only
8257 * by cmdclient as a fallback for very old Huntington firmware, and not 8820 * by cmdclient as a fallback for very old Huntington firmware, and not
8258 * supported in firmware beyond v6.4.0.1005. Use LUE_VERSIONED_METADATA 8821 * supported in firmware beyond v6.4.0.1005. Use LUE_VERSIONED_METADATA
8259 * instead. 8822 * instead.
8260 */ 8823 */
8261#define MC_CMD_PARSER_DISP_RW_IN_LUE 0x2 8824#define MC_CMD_PARSER_DISP_RW_IN_LUE 0x2
8262/* enum: Lookup engine (with requested metadata format) */ 8825/* enum: Lookup engine (with requested metadata format) */
8263#define MC_CMD_PARSER_DISP_RW_IN_LUE_VERSIONED_METADATA 0x3 8826#define MC_CMD_PARSER_DISP_RW_IN_LUE_VERSIONED_METADATA 0x3
8264/* enum: RX0 dispatcher CPU (alias for RX_DICPU; Medford has 2 RX DICPUs) */ 8827/* enum: RX0 dispatcher CPU (alias for RX_DICPU; Medford has 2 RX DICPUs) */
8265#define MC_CMD_PARSER_DISP_RW_IN_RX0_DICPU 0x0 8828#define MC_CMD_PARSER_DISP_RW_IN_RX0_DICPU 0x0
8266/* enum: RX1 dispatcher CPU (only valid for Medford) */ 8829/* enum: RX1 dispatcher CPU (only valid for Medford) */
8267#define MC_CMD_PARSER_DISP_RW_IN_RX1_DICPU 0x4 8830#define MC_CMD_PARSER_DISP_RW_IN_RX1_DICPU 0x4
8268/* enum: Miscellaneous other state (only valid for Medford) */ 8831/* enum: Miscellaneous other state (only valid for Medford) */
8269#define MC_CMD_PARSER_DISP_RW_IN_MISC_STATE 0x5 8832#define MC_CMD_PARSER_DISP_RW_IN_MISC_STATE 0x5
8270/* identifies the type of operation requested */ 8833/* identifies the type of operation requested */
8271#define MC_CMD_PARSER_DISP_RW_IN_OP_OFST 4 8834#define MC_CMD_PARSER_DISP_RW_IN_OP_OFST 4
8272#define MC_CMD_PARSER_DISP_RW_IN_OP_LEN 4 8835#define MC_CMD_PARSER_DISP_RW_IN_OP_LEN 4
8273/* enum: Read a word of DICPU DMEM or a LUE entry */ 8836/* enum: Read a word of DICPU DMEM or a LUE entry */
8274#define MC_CMD_PARSER_DISP_RW_IN_READ 0x0 8837#define MC_CMD_PARSER_DISP_RW_IN_READ 0x0
8275/* enum: Write a word of DICPU DMEM or a LUE entry. */ 8838/* enum: Write a word of DICPU DMEM or a LUE entry. Not permitted on
8276#define MC_CMD_PARSER_DISP_RW_IN_WRITE 0x1 8839 * tamperproof adapters.
8277/* enum: Read-modify-write a word of DICPU DMEM (not valid for LUE). */ 8840 */
8278#define MC_CMD_PARSER_DISP_RW_IN_RMW 0x2 8841#define MC_CMD_PARSER_DISP_RW_IN_WRITE 0x1
8842/* enum: Read-modify-write a word of DICPU DMEM (not valid for LUE). Not
8843 * permitted on tamperproof adapters.
8844 */
8845#define MC_CMD_PARSER_DISP_RW_IN_RMW 0x2
8279/* data memory address (DICPU targets) or LUE index (LUE targets) */ 8846/* data memory address (DICPU targets) or LUE index (LUE targets) */
8280#define MC_CMD_PARSER_DISP_RW_IN_ADDRESS_OFST 8 8847#define MC_CMD_PARSER_DISP_RW_IN_ADDRESS_OFST 8
8281#define MC_CMD_PARSER_DISP_RW_IN_ADDRESS_LEN 4 8848#define MC_CMD_PARSER_DISP_RW_IN_ADDRESS_LEN 4
@@ -8283,7 +8850,7 @@
8283#define MC_CMD_PARSER_DISP_RW_IN_SELECTOR_OFST 8 8850#define MC_CMD_PARSER_DISP_RW_IN_SELECTOR_OFST 8
8284#define MC_CMD_PARSER_DISP_RW_IN_SELECTOR_LEN 4 8851#define MC_CMD_PARSER_DISP_RW_IN_SELECTOR_LEN 4
8285/* enum: Port to datapath mapping */ 8852/* enum: Port to datapath mapping */
8286#define MC_CMD_PARSER_DISP_RW_IN_PORT_DP_MAPPING 0x1 8853#define MC_CMD_PARSER_DISP_RW_IN_PORT_DP_MAPPING 0x1
8287/* value to write (for DMEM writes) */ 8854/* value to write (for DMEM writes) */
8288#define MC_CMD_PARSER_DISP_RW_IN_DMEM_WRITE_VALUE_OFST 12 8855#define MC_CMD_PARSER_DISP_RW_IN_DMEM_WRITE_VALUE_OFST 12
8289#define MC_CMD_PARSER_DISP_RW_IN_DMEM_WRITE_VALUE_LEN 4 8856#define MC_CMD_PARSER_DISP_RW_IN_DMEM_WRITE_VALUE_LEN 4
@@ -8317,8 +8884,8 @@
8317#define MC_CMD_PARSER_DISP_RW_OUT_PORT_DP_MAPPING_OFST 0 8884#define MC_CMD_PARSER_DISP_RW_OUT_PORT_DP_MAPPING_OFST 0
8318#define MC_CMD_PARSER_DISP_RW_OUT_PORT_DP_MAPPING_LEN 4 8885#define MC_CMD_PARSER_DISP_RW_OUT_PORT_DP_MAPPING_LEN 4
8319#define MC_CMD_PARSER_DISP_RW_OUT_PORT_DP_MAPPING_NUM 4 8886#define MC_CMD_PARSER_DISP_RW_OUT_PORT_DP_MAPPING_NUM 4
8320#define MC_CMD_PARSER_DISP_RW_OUT_DP0 0x1 /* enum */ 8887#define MC_CMD_PARSER_DISP_RW_OUT_DP0 0x1 /* enum */
8321#define MC_CMD_PARSER_DISP_RW_OUT_DP1 0x2 /* enum */ 8888#define MC_CMD_PARSER_DISP_RW_OUT_DP1 0x2 /* enum */
8322 8889
8323 8890
8324/***********************************/ 8891/***********************************/
@@ -8783,13 +9350,13 @@
8783#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN_TLP_GLOBAL_CATEGORY_OFST 0 9350#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN_TLP_GLOBAL_CATEGORY_OFST 0
8784#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN_TLP_GLOBAL_CATEGORY_LEN 4 9351#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN_TLP_GLOBAL_CATEGORY_LEN 4
8785/* enum: MISC. */ 9352/* enum: MISC. */
8786#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN_TLP_GLOBAL_CATEGORY_MISC 0x0 9353#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN_TLP_GLOBAL_CATEGORY_MISC 0x0
8787/* enum: IDO. */ 9354/* enum: IDO. */
8788#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN_TLP_GLOBAL_CATEGORY_IDO 0x1 9355#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN_TLP_GLOBAL_CATEGORY_IDO 0x1
8789/* enum: RO. */ 9356/* enum: RO. */
8790#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN_TLP_GLOBAL_CATEGORY_RO 0x2 9357#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN_TLP_GLOBAL_CATEGORY_RO 0x2
8791/* enum: TPH Type. */ 9358/* enum: TPH Type. */
8792#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN_TLP_GLOBAL_CATEGORY_TPH_TYPE 0x3 9359#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN_TLP_GLOBAL_CATEGORY_TPH_TYPE 0x3
8793 9360
8794/* MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT msgresponse */ 9361/* MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT msgresponse */
8795#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_LEN 8 9362#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_LEN 8
@@ -8920,57 +9487,57 @@
8920 */ 9487 */
8921#define MC_CMD_SATELLITE_DOWNLOAD_IN_PHASE_OFST 0 9488#define MC_CMD_SATELLITE_DOWNLOAD_IN_PHASE_OFST 0
8922#define MC_CMD_SATELLITE_DOWNLOAD_IN_PHASE_LEN 4 9489#define MC_CMD_SATELLITE_DOWNLOAD_IN_PHASE_LEN 4
8923#define MC_CMD_SATELLITE_DOWNLOAD_IN_PHASE_IDLE 0x0 /* enum */ 9490#define MC_CMD_SATELLITE_DOWNLOAD_IN_PHASE_IDLE 0x0 /* enum */
8924#define MC_CMD_SATELLITE_DOWNLOAD_IN_PHASE_RESET 0x1 /* enum */ 9491#define MC_CMD_SATELLITE_DOWNLOAD_IN_PHASE_RESET 0x1 /* enum */
8925#define MC_CMD_SATELLITE_DOWNLOAD_IN_PHASE_IMEMS 0x2 /* enum */ 9492#define MC_CMD_SATELLITE_DOWNLOAD_IN_PHASE_IMEMS 0x2 /* enum */
8926#define MC_CMD_SATELLITE_DOWNLOAD_IN_PHASE_VECTORS 0x3 /* enum */ 9493#define MC_CMD_SATELLITE_DOWNLOAD_IN_PHASE_VECTORS 0x3 /* enum */
8927#define MC_CMD_SATELLITE_DOWNLOAD_IN_PHASE_READY 0x4 /* enum */ 9494#define MC_CMD_SATELLITE_DOWNLOAD_IN_PHASE_READY 0x4 /* enum */
8928/* Target for download. (These match the blob numbers defined in 9495/* Target for download. (These match the blob numbers defined in
8929 * mc_flash_layout.h.) 9496 * mc_flash_layout.h.)
8930 */ 9497 */
8931#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_OFST 4 9498#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_OFST 4
8932#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_LEN 4 9499#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_LEN 4
8933/* enum: Valid in phase 2 (PHASE_IMEMS) only */ 9500/* enum: Valid in phase 2 (PHASE_IMEMS) only */
8934#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_TXDI_TEXT 0x0 9501#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_TXDI_TEXT 0x0
8935/* enum: Valid in phase 2 (PHASE_IMEMS) only */ 9502/* enum: Valid in phase 2 (PHASE_IMEMS) only */
8936#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_RXDI_TEXT 0x1 9503#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_RXDI_TEXT 0x1
8937/* enum: Valid in phase 2 (PHASE_IMEMS) only */ 9504/* enum: Valid in phase 2 (PHASE_IMEMS) only */
8938#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_TXDP_TEXT 0x2 9505#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_TXDP_TEXT 0x2
8939/* enum: Valid in phase 2 (PHASE_IMEMS) only */ 9506/* enum: Valid in phase 2 (PHASE_IMEMS) only */
8940#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_RXDP_TEXT 0x3 9507#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_RXDP_TEXT 0x3
8941/* enum: Valid in phase 2 (PHASE_IMEMS) only */ 9508/* enum: Valid in phase 2 (PHASE_IMEMS) only */
8942#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_RXHRSL_HR_LUT 0x4 9509#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_RXHRSL_HR_LUT 0x4
8943/* enum: Valid in phase 2 (PHASE_IMEMS) only */ 9510/* enum: Valid in phase 2 (PHASE_IMEMS) only */
8944#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_RXHRSL_HR_LUT_CFG 0x5 9511#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_RXHRSL_HR_LUT_CFG 0x5
8945/* enum: Valid in phase 2 (PHASE_IMEMS) only */ 9512/* enum: Valid in phase 2 (PHASE_IMEMS) only */
8946#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_TXHRSL_HR_LUT 0x6 9513#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_TXHRSL_HR_LUT 0x6
8947/* enum: Valid in phase 2 (PHASE_IMEMS) only */ 9514/* enum: Valid in phase 2 (PHASE_IMEMS) only */
8948#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_TXHRSL_HR_LUT_CFG 0x7 9515#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_TXHRSL_HR_LUT_CFG 0x7
8949/* enum: Valid in phase 2 (PHASE_IMEMS) only */ 9516/* enum: Valid in phase 2 (PHASE_IMEMS) only */
8950#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_RXHRSL_HR_PGM 0x8 9517#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_RXHRSL_HR_PGM 0x8
8951/* enum: Valid in phase 2 (PHASE_IMEMS) only */ 9518/* enum: Valid in phase 2 (PHASE_IMEMS) only */
8952#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_RXHRSL_SL_PGM 0x9 9519#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_RXHRSL_SL_PGM 0x9
8953/* enum: Valid in phase 2 (PHASE_IMEMS) only */ 9520/* enum: Valid in phase 2 (PHASE_IMEMS) only */
8954#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_TXHRSL_HR_PGM 0xa 9521#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_TXHRSL_HR_PGM 0xa
8955/* enum: Valid in phase 2 (PHASE_IMEMS) only */ 9522/* enum: Valid in phase 2 (PHASE_IMEMS) only */
8956#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_TXHRSL_SL_PGM 0xb 9523#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_TXHRSL_SL_PGM 0xb
8957/* enum: Valid in phase 3 (PHASE_VECTORS) only */ 9524/* enum: Valid in phase 3 (PHASE_VECTORS) only */
8958#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_RXDI_VTBL0 0xc 9525#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_RXDI_VTBL0 0xc
8959/* enum: Valid in phase 3 (PHASE_VECTORS) only */ 9526/* enum: Valid in phase 3 (PHASE_VECTORS) only */
8960#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_TXDI_VTBL0 0xd 9527#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_TXDI_VTBL0 0xd
8961/* enum: Valid in phase 3 (PHASE_VECTORS) only */ 9528/* enum: Valid in phase 3 (PHASE_VECTORS) only */
8962#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_RXDI_VTBL1 0xe 9529#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_RXDI_VTBL1 0xe
8963/* enum: Valid in phase 3 (PHASE_VECTORS) only */ 9530/* enum: Valid in phase 3 (PHASE_VECTORS) only */
8964#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_TXDI_VTBL1 0xf 9531#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_TXDI_VTBL1 0xf
8965/* enum: Valid in phases 1 (PHASE_RESET) and 4 (PHASE_READY) only */ 9532/* enum: Valid in phases 1 (PHASE_RESET) and 4 (PHASE_READY) only */
8966#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_ALL 0xffffffff 9533#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_ALL 0xffffffff
8967/* Chunk ID, or CHUNK_ID_LAST or CHUNK_ID_ABORT */ 9534/* Chunk ID, or CHUNK_ID_LAST or CHUNK_ID_ABORT */
8968#define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_ID_OFST 8 9535#define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_ID_OFST 8
8969#define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_ID_LEN 4 9536#define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_ID_LEN 4
8970/* enum: Last chunk, containing checksum rather than data */ 9537/* enum: Last chunk, containing checksum rather than data */
8971#define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_ID_LAST 0xffffffff 9538#define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_ID_LAST 0xffffffff
8972/* enum: Abort download of this item */ 9539/* enum: Abort download of this item */
8973#define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_ID_ABORT 0xfffffffe 9540#define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_ID_ABORT 0xfffffffe
8974/* Length of this chunk in bytes */ 9541/* Length of this chunk in bytes */
8975#define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_LEN_OFST 12 9542#define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_LEN_OFST 12
8976#define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_LEN_LEN 4 9543#define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_LEN_LEN 4
@@ -8989,21 +9556,21 @@
8989#define MC_CMD_SATELLITE_DOWNLOAD_OUT_INFO_OFST 4 9556#define MC_CMD_SATELLITE_DOWNLOAD_OUT_INFO_OFST 4
8990#define MC_CMD_SATELLITE_DOWNLOAD_OUT_INFO_LEN 4 9557#define MC_CMD_SATELLITE_DOWNLOAD_OUT_INFO_LEN 4
8991/* enum: Code download OK, completed. */ 9558/* enum: Code download OK, completed. */
8992#define MC_CMD_SATELLITE_DOWNLOAD_OUT_OK_COMPLETE 0x0 9559#define MC_CMD_SATELLITE_DOWNLOAD_OUT_OK_COMPLETE 0x0
8993/* enum: Code download aborted as requested. */ 9560/* enum: Code download aborted as requested. */
8994#define MC_CMD_SATELLITE_DOWNLOAD_OUT_OK_ABORTED 0x1 9561#define MC_CMD_SATELLITE_DOWNLOAD_OUT_OK_ABORTED 0x1
8995/* enum: Code download OK so far, send next chunk. */ 9562/* enum: Code download OK so far, send next chunk. */
8996#define MC_CMD_SATELLITE_DOWNLOAD_OUT_OK_NEXT_CHUNK 0x2 9563#define MC_CMD_SATELLITE_DOWNLOAD_OUT_OK_NEXT_CHUNK 0x2
8997/* enum: Download phases out of sequence */ 9564/* enum: Download phases out of sequence */
8998#define MC_CMD_SATELLITE_DOWNLOAD_OUT_ERR_BAD_PHASE 0x100 9565#define MC_CMD_SATELLITE_DOWNLOAD_OUT_ERR_BAD_PHASE 0x100
8999/* enum: Bad target for this phase */ 9566/* enum: Bad target for this phase */
9000#define MC_CMD_SATELLITE_DOWNLOAD_OUT_ERR_BAD_TARGET 0x101 9567#define MC_CMD_SATELLITE_DOWNLOAD_OUT_ERR_BAD_TARGET 0x101
9001/* enum: Chunk ID out of sequence */ 9568/* enum: Chunk ID out of sequence */
9002#define MC_CMD_SATELLITE_DOWNLOAD_OUT_ERR_BAD_CHUNK_ID 0x200 9569#define MC_CMD_SATELLITE_DOWNLOAD_OUT_ERR_BAD_CHUNK_ID 0x200
9003/* enum: Chunk length zero or too large */ 9570/* enum: Chunk length zero or too large */
9004#define MC_CMD_SATELLITE_DOWNLOAD_OUT_ERR_BAD_CHUNK_LEN 0x201 9571#define MC_CMD_SATELLITE_DOWNLOAD_OUT_ERR_BAD_CHUNK_LEN 0x201
9005/* enum: Checksum was incorrect */ 9572/* enum: Checksum was incorrect */
9006#define MC_CMD_SATELLITE_DOWNLOAD_OUT_ERR_BAD_CHECKSUM 0x300 9573#define MC_CMD_SATELLITE_DOWNLOAD_OUT_ERR_BAD_CHECKSUM 0x300
9007 9574
9008 9575
9009/***********************************/ 9576/***********************************/
@@ -9087,54 +9654,58 @@
9087#define MC_CMD_GET_CAPABILITIES_OUT_RX_DPCPU_FW_ID_OFST 4 9654#define MC_CMD_GET_CAPABILITIES_OUT_RX_DPCPU_FW_ID_OFST 4
9088#define MC_CMD_GET_CAPABILITIES_OUT_RX_DPCPU_FW_ID_LEN 2 9655#define MC_CMD_GET_CAPABILITIES_OUT_RX_DPCPU_FW_ID_LEN 2
9089/* enum: Standard RXDP firmware */ 9656/* enum: Standard RXDP firmware */
9090#define MC_CMD_GET_CAPABILITIES_OUT_RXDP 0x0 9657#define MC_CMD_GET_CAPABILITIES_OUT_RXDP 0x0
9091/* enum: Low latency RXDP firmware */ 9658/* enum: Low latency RXDP firmware */
9092#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_LOW_LATENCY 0x1 9659#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_LOW_LATENCY 0x1
9093/* enum: Packed stream RXDP firmware */ 9660/* enum: Packed stream RXDP firmware */
9094#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_PACKED_STREAM 0x2 9661#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_PACKED_STREAM 0x2
9095/* enum: Rules engine RXDP firmware */ 9662/* enum: Rules engine RXDP firmware */
9096#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_RULES_ENGINE 0x5 9663#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_RULES_ENGINE 0x5
9664/* enum: DPDK RXDP firmware */
9665#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_DPDK 0x6
9097/* enum: BIST RXDP firmware */ 9666/* enum: BIST RXDP firmware */
9098#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_BIST 0x10a 9667#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_BIST 0x10a
9099/* enum: RXDP Test firmware image 1 */ 9668/* enum: RXDP Test firmware image 1 */
9100#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_FW_TO_MC_CUT_THROUGH 0x101 9669#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_FW_TO_MC_CUT_THROUGH 0x101
9101/* enum: RXDP Test firmware image 2 */ 9670/* enum: RXDP Test firmware image 2 */
9102#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_FW_TO_MC_STORE_FORWARD 0x102 9671#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_FW_TO_MC_STORE_FORWARD 0x102
9103/* enum: RXDP Test firmware image 3 */ 9672/* enum: RXDP Test firmware image 3 */
9104#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_FW_TO_MC_STORE_FORWARD_FIRST 0x103 9673#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_FW_TO_MC_STORE_FORWARD_FIRST 0x103
9105/* enum: RXDP Test firmware image 4 */ 9674/* enum: RXDP Test firmware image 4 */
9106#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_EVERY_EVENT_BATCHABLE 0x104 9675#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_EVERY_EVENT_BATCHABLE 0x104
9107/* enum: RXDP Test firmware image 5 */ 9676/* enum: RXDP Test firmware image 5 */
9108#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_BACKPRESSURE 0x105 9677#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_BACKPRESSURE 0x105
9109/* enum: RXDP Test firmware image 6 */ 9678/* enum: RXDP Test firmware image 6 */
9110#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_FW_PACKET_EDITS 0x106 9679#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_FW_PACKET_EDITS 0x106
9111/* enum: RXDP Test firmware image 7 */ 9680/* enum: RXDP Test firmware image 7 */
9112#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_FW_RX_HDR_SPLIT 0x107 9681#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_FW_RX_HDR_SPLIT 0x107
9113/* enum: RXDP Test firmware image 8 */ 9682/* enum: RXDP Test firmware image 8 */
9114#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_FW_DISABLE_DL 0x108 9683#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_FW_DISABLE_DL 0x108
9115/* enum: RXDP Test firmware image 9 */ 9684/* enum: RXDP Test firmware image 9 */
9116#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_FW_DOORBELL_DELAY 0x10b 9685#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_FW_DOORBELL_DELAY 0x10b
9117/* enum: RXDP Test firmware image 10 */ 9686/* enum: RXDP Test firmware image 10 */
9118#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_FW_SLOW 0x10c 9687#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_FW_SLOW 0x10c
9119/* TxDPCPU firmware id. */ 9688/* TxDPCPU firmware id. */
9120#define MC_CMD_GET_CAPABILITIES_OUT_TX_DPCPU_FW_ID_OFST 6 9689#define MC_CMD_GET_CAPABILITIES_OUT_TX_DPCPU_FW_ID_OFST 6
9121#define MC_CMD_GET_CAPABILITIES_OUT_TX_DPCPU_FW_ID_LEN 2 9690#define MC_CMD_GET_CAPABILITIES_OUT_TX_DPCPU_FW_ID_LEN 2
9122/* enum: Standard TXDP firmware */ 9691/* enum: Standard TXDP firmware */
9123#define MC_CMD_GET_CAPABILITIES_OUT_TXDP 0x0 9692#define MC_CMD_GET_CAPABILITIES_OUT_TXDP 0x0
9124/* enum: Low latency TXDP firmware */ 9693/* enum: Low latency TXDP firmware */
9125#define MC_CMD_GET_CAPABILITIES_OUT_TXDP_LOW_LATENCY 0x1 9694#define MC_CMD_GET_CAPABILITIES_OUT_TXDP_LOW_LATENCY 0x1
9126/* enum: High packet rate TXDP firmware */ 9695/* enum: High packet rate TXDP firmware */
9127#define MC_CMD_GET_CAPABILITIES_OUT_TXDP_HIGH_PACKET_RATE 0x3 9696#define MC_CMD_GET_CAPABILITIES_OUT_TXDP_HIGH_PACKET_RATE 0x3
9128/* enum: Rules engine TXDP firmware */ 9697/* enum: Rules engine TXDP firmware */
9129#define MC_CMD_GET_CAPABILITIES_OUT_TXDP_RULES_ENGINE 0x5 9698#define MC_CMD_GET_CAPABILITIES_OUT_TXDP_RULES_ENGINE 0x5
9699/* enum: DPDK TXDP firmware */
9700#define MC_CMD_GET_CAPABILITIES_OUT_TXDP_DPDK 0x6
9130/* enum: BIST TXDP firmware */ 9701/* enum: BIST TXDP firmware */
9131#define MC_CMD_GET_CAPABILITIES_OUT_TXDP_BIST 0x12d 9702#define MC_CMD_GET_CAPABILITIES_OUT_TXDP_BIST 0x12d
9132/* enum: TXDP Test firmware image 1 */ 9703/* enum: TXDP Test firmware image 1 */
9133#define MC_CMD_GET_CAPABILITIES_OUT_TXDP_TEST_FW_TSO_EDIT 0x101 9704#define MC_CMD_GET_CAPABILITIES_OUT_TXDP_TEST_FW_TSO_EDIT 0x101
9134/* enum: TXDP Test firmware image 2 */ 9705/* enum: TXDP Test firmware image 2 */
9135#define MC_CMD_GET_CAPABILITIES_OUT_TXDP_TEST_FW_PACKET_EDITS 0x102 9706#define MC_CMD_GET_CAPABILITIES_OUT_TXDP_TEST_FW_PACKET_EDITS 0x102
9136/* enum: TXDP CSR bus test firmware */ 9707/* enum: TXDP CSR bus test firmware */
9137#define MC_CMD_GET_CAPABILITIES_OUT_TXDP_TEST_FW_CSR 0x103 9708#define MC_CMD_GET_CAPABILITIES_OUT_TXDP_TEST_FW_CSR 0x103
9138#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_VERSION_OFST 8 9709#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_VERSION_OFST 8
9139#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_VERSION_LEN 2 9710#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_VERSION_LEN 2
9140#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_VERSION_REV_LBN 0 9711#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_VERSION_REV_LBN 0
@@ -9144,41 +9715,43 @@
9144/* enum: reserved value - do not use (may indicate alternative interpretation 9715/* enum: reserved value - do not use (may indicate alternative interpretation
9145 * of REV field in future) 9716 * of REV field in future)
9146 */ 9717 */
9147#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_RESERVED 0x0 9718#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_RESERVED 0x0
9148/* enum: Trivial RX PD firmware for early Huntington development (Huntington 9719/* enum: Trivial RX PD firmware for early Huntington development (Huntington
9149 * development only) 9720 * development only)
9150 */ 9721 */
9151#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_FIRST_PKT 0x1 9722#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_FIRST_PKT 0x1
9152/* enum: RX PD firmware with approximately Siena-compatible behaviour 9723/* enum: RX PD firmware with approximately Siena-compatible behaviour
9153 * (Huntington development only) 9724 * (Huntington development only)
9154 */ 9725 */
9155#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_SIENA_COMPAT 0x2 9726#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_SIENA_COMPAT 0x2
9156/* enum: Full featured RX PD production firmware */ 9727/* enum: Full featured RX PD production firmware */
9157#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_FULL_FEATURED 0x3 9728#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_FULL_FEATURED 0x3
9158/* enum: (deprecated original name for the FULL_FEATURED variant) */ 9729/* enum: (deprecated original name for the FULL_FEATURED variant) */
9159#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_VSWITCH 0x3 9730#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_VSWITCH 0x3
9160/* enum: siena_compat variant RX PD firmware using PM rather than MAC 9731/* enum: siena_compat variant RX PD firmware using PM rather than MAC
9161 * (Huntington development only) 9732 * (Huntington development only)
9162 */ 9733 */
9163#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_SIENA_COMPAT_PM 0x4 9734#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_SIENA_COMPAT_PM 0x4
9164/* enum: Low latency RX PD production firmware */ 9735/* enum: Low latency RX PD production firmware */
9165#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_LOW_LATENCY 0x5 9736#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_LOW_LATENCY 0x5
9166/* enum: Packed stream RX PD production firmware */ 9737/* enum: Packed stream RX PD production firmware */
9167#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_PACKED_STREAM 0x6 9738#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_PACKED_STREAM 0x6
9168/* enum: RX PD firmware handling layer 2 only for high packet rate performance 9739/* enum: RX PD firmware handling layer 2 only for high packet rate performance
9169 * tests (Medford development only) 9740 * tests (Medford development only)
9170 */ 9741 */
9171#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_LAYER2_PERF 0x7 9742#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_LAYER2_PERF 0x7
9172/* enum: Rules engine RX PD production firmware */ 9743/* enum: Rules engine RX PD production firmware */
9173#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_RULES_ENGINE 0x8 9744#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_RULES_ENGINE 0x8
9174/* enum: reserved value - do not use (bug69716) */ 9745/* enum: Custom firmware variant (see SF-119495-PD and bug69716) */
9175#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_RESERVED_9 0x9 9746#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_L3XUDP 0x9
9747/* enum: DPDK RX PD production firmware */
9748#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_DPDK 0xa
9176/* enum: RX PD firmware for GUE parsing prototype (Medford development only) */ 9749/* enum: RX PD firmware for GUE parsing prototype (Medford development only) */
9177#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe 9750#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe
9178/* enum: RX PD firmware parsing but not filtering network overlay tunnel 9751/* enum: RX PD firmware parsing but not filtering network overlay tunnel
9179 * encapsulations (Medford development only) 9752 * encapsulations (Medford development only)
9180 */ 9753 */
9181#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_TESTFW_ENCAP_PARSING_ONLY 0xf 9754#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_TESTFW_ENCAP_PARSING_ONLY 0xf
9182#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_VERSION_OFST 10 9755#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_VERSION_OFST 10
9183#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_VERSION_LEN 2 9756#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_VERSION_LEN 2
9184#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_VERSION_REV_LBN 0 9757#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_VERSION_REV_LBN 0
@@ -9188,34 +9761,36 @@
9188/* enum: reserved value - do not use (may indicate alternative interpretation 9761/* enum: reserved value - do not use (may indicate alternative interpretation
9189 * of REV field in future) 9762 * of REV field in future)
9190 */ 9763 */
9191#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_RESERVED 0x0 9764#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_RESERVED 0x0
9192/* enum: Trivial TX PD firmware for early Huntington development (Huntington 9765/* enum: Trivial TX PD firmware for early Huntington development (Huntington
9193 * development only) 9766 * development only)
9194 */ 9767 */
9195#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_FIRST_PKT 0x1 9768#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_FIRST_PKT 0x1
9196/* enum: TX PD firmware with approximately Siena-compatible behaviour 9769/* enum: TX PD firmware with approximately Siena-compatible behaviour
9197 * (Huntington development only) 9770 * (Huntington development only)
9198 */ 9771 */
9199#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_SIENA_COMPAT 0x2 9772#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_SIENA_COMPAT 0x2
9200/* enum: Full featured TX PD production firmware */ 9773/* enum: Full featured TX PD production firmware */
9201#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_FULL_FEATURED 0x3 9774#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_FULL_FEATURED 0x3
9202/* enum: (deprecated original name for the FULL_FEATURED variant) */ 9775/* enum: (deprecated original name for the FULL_FEATURED variant) */
9203#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_VSWITCH 0x3 9776#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_VSWITCH 0x3
9204/* enum: siena_compat variant TX PD firmware using PM rather than MAC 9777/* enum: siena_compat variant TX PD firmware using PM rather than MAC
9205 * (Huntington development only) 9778 * (Huntington development only)
9206 */ 9779 */
9207#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_SIENA_COMPAT_PM 0x4 9780#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_SIENA_COMPAT_PM 0x4
9208#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_LOW_LATENCY 0x5 /* enum */ 9781#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_LOW_LATENCY 0x5 /* enum */
9209/* enum: TX PD firmware handling layer 2 only for high packet rate performance 9782/* enum: TX PD firmware handling layer 2 only for high packet rate performance
9210 * tests (Medford development only) 9783 * tests (Medford development only)
9211 */ 9784 */
9212#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_LAYER2_PERF 0x7 9785#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_LAYER2_PERF 0x7
9213/* enum: Rules engine TX PD production firmware */ 9786/* enum: Rules engine TX PD production firmware */
9214#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_RULES_ENGINE 0x8 9787#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_RULES_ENGINE 0x8
9215/* enum: reserved value - do not use (bug69716) */ 9788/* enum: Custom firmware variant (see SF-119495-PD and bug69716) */
9216#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_RESERVED_9 0x9 9789#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_L3XUDP 0x9
9790/* enum: DPDK TX PD production firmware */
9791#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_DPDK 0xa
9217/* enum: RX PD firmware for GUE parsing prototype (Medford development only) */ 9792/* enum: RX PD firmware for GUE parsing prototype (Medford development only) */
9218#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe 9793#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe
9219/* Hardware capabilities of NIC */ 9794/* Hardware capabilities of NIC */
9220#define MC_CMD_GET_CAPABILITIES_OUT_HW_CAPABILITIES_OFST 12 9795#define MC_CMD_GET_CAPABILITIES_OUT_HW_CAPABILITIES_OFST 12
9221#define MC_CMD_GET_CAPABILITIES_OUT_HW_CAPABILITIES_LEN 4 9796#define MC_CMD_GET_CAPABILITIES_OUT_HW_CAPABILITIES_LEN 4
@@ -9293,54 +9868,58 @@
9293#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_DPCPU_FW_ID_OFST 4 9868#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_DPCPU_FW_ID_OFST 4
9294#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_DPCPU_FW_ID_LEN 2 9869#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_DPCPU_FW_ID_LEN 2
9295/* enum: Standard RXDP firmware */ 9870/* enum: Standard RXDP firmware */
9296#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP 0x0 9871#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP 0x0
9297/* enum: Low latency RXDP firmware */ 9872/* enum: Low latency RXDP firmware */
9298#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_LOW_LATENCY 0x1 9873#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_LOW_LATENCY 0x1
9299/* enum: Packed stream RXDP firmware */ 9874/* enum: Packed stream RXDP firmware */
9300#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_PACKED_STREAM 0x2 9875#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_PACKED_STREAM 0x2
9301/* enum: Rules engine RXDP firmware */ 9876/* enum: Rules engine RXDP firmware */
9302#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_RULES_ENGINE 0x5 9877#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_RULES_ENGINE 0x5
9878/* enum: DPDK RXDP firmware */
9879#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_DPDK 0x6
9303/* enum: BIST RXDP firmware */ 9880/* enum: BIST RXDP firmware */
9304#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_BIST 0x10a 9881#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_BIST 0x10a
9305/* enum: RXDP Test firmware image 1 */ 9882/* enum: RXDP Test firmware image 1 */
9306#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_TEST_FW_TO_MC_CUT_THROUGH 0x101 9883#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_TEST_FW_TO_MC_CUT_THROUGH 0x101
9307/* enum: RXDP Test firmware image 2 */ 9884/* enum: RXDP Test firmware image 2 */
9308#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_TEST_FW_TO_MC_STORE_FORWARD 0x102 9885#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_TEST_FW_TO_MC_STORE_FORWARD 0x102
9309/* enum: RXDP Test firmware image 3 */ 9886/* enum: RXDP Test firmware image 3 */
9310#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_TEST_FW_TO_MC_STORE_FORWARD_FIRST 0x103 9887#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_TEST_FW_TO_MC_STORE_FORWARD_FIRST 0x103
9311/* enum: RXDP Test firmware image 4 */ 9888/* enum: RXDP Test firmware image 4 */
9312#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_TEST_EVERY_EVENT_BATCHABLE 0x104 9889#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_TEST_EVERY_EVENT_BATCHABLE 0x104
9313/* enum: RXDP Test firmware image 5 */ 9890/* enum: RXDP Test firmware image 5 */
9314#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_TEST_BACKPRESSURE 0x105 9891#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_TEST_BACKPRESSURE 0x105
9315/* enum: RXDP Test firmware image 6 */ 9892/* enum: RXDP Test firmware image 6 */
9316#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_TEST_FW_PACKET_EDITS 0x106 9893#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_TEST_FW_PACKET_EDITS 0x106
9317/* enum: RXDP Test firmware image 7 */ 9894/* enum: RXDP Test firmware image 7 */
9318#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_TEST_FW_RX_HDR_SPLIT 0x107 9895#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_TEST_FW_RX_HDR_SPLIT 0x107
9319/* enum: RXDP Test firmware image 8 */ 9896/* enum: RXDP Test firmware image 8 */
9320#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_TEST_FW_DISABLE_DL 0x108 9897#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_TEST_FW_DISABLE_DL 0x108
9321/* enum: RXDP Test firmware image 9 */ 9898/* enum: RXDP Test firmware image 9 */
9322#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_TEST_FW_DOORBELL_DELAY 0x10b 9899#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_TEST_FW_DOORBELL_DELAY 0x10b
9323/* enum: RXDP Test firmware image 10 */ 9900/* enum: RXDP Test firmware image 10 */
9324#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_TEST_FW_SLOW 0x10c 9901#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_TEST_FW_SLOW 0x10c
9325/* TxDPCPU firmware id. */ 9902/* TxDPCPU firmware id. */
9326#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_DPCPU_FW_ID_OFST 6 9903#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_DPCPU_FW_ID_OFST 6
9327#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_DPCPU_FW_ID_LEN 2 9904#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_DPCPU_FW_ID_LEN 2
9328/* enum: Standard TXDP firmware */ 9905/* enum: Standard TXDP firmware */
9329#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXDP 0x0 9906#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXDP 0x0
9330/* enum: Low latency TXDP firmware */ 9907/* enum: Low latency TXDP firmware */
9331#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXDP_LOW_LATENCY 0x1 9908#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXDP_LOW_LATENCY 0x1
9332/* enum: High packet rate TXDP firmware */ 9909/* enum: High packet rate TXDP firmware */
9333#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXDP_HIGH_PACKET_RATE 0x3 9910#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXDP_HIGH_PACKET_RATE 0x3
9334/* enum: Rules engine TXDP firmware */ 9911/* enum: Rules engine TXDP firmware */
9335#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXDP_RULES_ENGINE 0x5 9912#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXDP_RULES_ENGINE 0x5
9913/* enum: DPDK TXDP firmware */
9914#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXDP_DPDK 0x6
9336/* enum: BIST TXDP firmware */ 9915/* enum: BIST TXDP firmware */
9337#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXDP_BIST 0x12d 9916#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXDP_BIST 0x12d
9338/* enum: TXDP Test firmware image 1 */ 9917/* enum: TXDP Test firmware image 1 */
9339#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXDP_TEST_FW_TSO_EDIT 0x101 9918#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXDP_TEST_FW_TSO_EDIT 0x101
9340/* enum: TXDP Test firmware image 2 */ 9919/* enum: TXDP Test firmware image 2 */
9341#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXDP_TEST_FW_PACKET_EDITS 0x102 9920#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXDP_TEST_FW_PACKET_EDITS 0x102
9342/* enum: TXDP CSR bus test firmware */ 9921/* enum: TXDP CSR bus test firmware */
9343#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXDP_TEST_FW_CSR 0x103 9922#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXDP_TEST_FW_CSR 0x103
9344#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_VERSION_OFST 8 9923#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_VERSION_OFST 8
9345#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_VERSION_LEN 2 9924#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_VERSION_LEN 2
9346#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_VERSION_REV_LBN 0 9925#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_VERSION_REV_LBN 0
@@ -9350,41 +9929,43 @@
9350/* enum: reserved value - do not use (may indicate alternative interpretation 9929/* enum: reserved value - do not use (may indicate alternative interpretation
9351 * of REV field in future) 9930 * of REV field in future)
9352 */ 9931 */
9353#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_RESERVED 0x0 9932#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_RESERVED 0x0
9354/* enum: Trivial RX PD firmware for early Huntington development (Huntington 9933/* enum: Trivial RX PD firmware for early Huntington development (Huntington
9355 * development only) 9934 * development only)
9356 */ 9935 */
9357#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_FIRST_PKT 0x1 9936#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_FIRST_PKT 0x1
9358/* enum: RX PD firmware with approximately Siena-compatible behaviour 9937/* enum: RX PD firmware with approximately Siena-compatible behaviour
9359 * (Huntington development only) 9938 * (Huntington development only)
9360 */ 9939 */
9361#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_SIENA_COMPAT 0x2 9940#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_SIENA_COMPAT 0x2
9362/* enum: Full featured RX PD production firmware */ 9941/* enum: Full featured RX PD production firmware */
9363#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_FULL_FEATURED 0x3 9942#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_FULL_FEATURED 0x3
9364/* enum: (deprecated original name for the FULL_FEATURED variant) */ 9943/* enum: (deprecated original name for the FULL_FEATURED variant) */
9365#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_VSWITCH 0x3 9944#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_VSWITCH 0x3
9366/* enum: siena_compat variant RX PD firmware using PM rather than MAC 9945/* enum: siena_compat variant RX PD firmware using PM rather than MAC
9367 * (Huntington development only) 9946 * (Huntington development only)
9368 */ 9947 */
9369#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_SIENA_COMPAT_PM 0x4 9948#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_SIENA_COMPAT_PM 0x4
9370/* enum: Low latency RX PD production firmware */ 9949/* enum: Low latency RX PD production firmware */
9371#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_LOW_LATENCY 0x5 9950#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_LOW_LATENCY 0x5
9372/* enum: Packed stream RX PD production firmware */ 9951/* enum: Packed stream RX PD production firmware */
9373#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_PACKED_STREAM 0x6 9952#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_PACKED_STREAM 0x6
9374/* enum: RX PD firmware handling layer 2 only for high packet rate performance 9953/* enum: RX PD firmware handling layer 2 only for high packet rate performance
9375 * tests (Medford development only) 9954 * tests (Medford development only)
9376 */ 9955 */
9377#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_LAYER2_PERF 0x7 9956#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_LAYER2_PERF 0x7
9378/* enum: Rules engine RX PD production firmware */ 9957/* enum: Rules engine RX PD production firmware */
9379#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_RULES_ENGINE 0x8 9958#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_RULES_ENGINE 0x8
9380/* enum: reserved value - do not use (bug69716) */ 9959/* enum: Custom firmware variant (see SF-119495-PD and bug69716) */
9381#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_RESERVED_9 0x9 9960#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_L3XUDP 0x9
9961/* enum: DPDK RX PD production firmware */
9962#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_DPDK 0xa
9382/* enum: RX PD firmware for GUE parsing prototype (Medford development only) */ 9963/* enum: RX PD firmware for GUE parsing prototype (Medford development only) */
9383#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe 9964#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe
9384/* enum: RX PD firmware parsing but not filtering network overlay tunnel 9965/* enum: RX PD firmware parsing but not filtering network overlay tunnel
9385 * encapsulations (Medford development only) 9966 * encapsulations (Medford development only)
9386 */ 9967 */
9387#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_TESTFW_ENCAP_PARSING_ONLY 0xf 9968#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_TESTFW_ENCAP_PARSING_ONLY 0xf
9388#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_VERSION_OFST 10 9969#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_VERSION_OFST 10
9389#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_VERSION_LEN 2 9970#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_VERSION_LEN 2
9390#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_VERSION_REV_LBN 0 9971#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_VERSION_REV_LBN 0
@@ -9394,34 +9975,36 @@
9394/* enum: reserved value - do not use (may indicate alternative interpretation 9975/* enum: reserved value - do not use (may indicate alternative interpretation
9395 * of REV field in future) 9976 * of REV field in future)
9396 */ 9977 */
9397#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_TYPE_RESERVED 0x0 9978#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_TYPE_RESERVED 0x0
9398/* enum: Trivial TX PD firmware for early Huntington development (Huntington 9979/* enum: Trivial TX PD firmware for early Huntington development (Huntington
9399 * development only) 9980 * development only)
9400 */ 9981 */
9401#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_TYPE_FIRST_PKT 0x1 9982#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_TYPE_FIRST_PKT 0x1
9402/* enum: TX PD firmware with approximately Siena-compatible behaviour 9983/* enum: TX PD firmware with approximately Siena-compatible behaviour
9403 * (Huntington development only) 9984 * (Huntington development only)
9404 */ 9985 */
9405#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_TYPE_SIENA_COMPAT 0x2 9986#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_TYPE_SIENA_COMPAT 0x2
9406/* enum: Full featured TX PD production firmware */ 9987/* enum: Full featured TX PD production firmware */
9407#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_TYPE_FULL_FEATURED 0x3 9988#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_TYPE_FULL_FEATURED 0x3
9408/* enum: (deprecated original name for the FULL_FEATURED variant) */ 9989/* enum: (deprecated original name for the FULL_FEATURED variant) */
9409#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_TYPE_VSWITCH 0x3 9990#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_TYPE_VSWITCH 0x3
9410/* enum: siena_compat variant TX PD firmware using PM rather than MAC 9991/* enum: siena_compat variant TX PD firmware using PM rather than MAC
9411 * (Huntington development only) 9992 * (Huntington development only)
9412 */ 9993 */
9413#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_TYPE_SIENA_COMPAT_PM 0x4 9994#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_TYPE_SIENA_COMPAT_PM 0x4
9414#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_TYPE_LOW_LATENCY 0x5 /* enum */ 9995#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_TYPE_LOW_LATENCY 0x5 /* enum */
9415/* enum: TX PD firmware handling layer 2 only for high packet rate performance 9996/* enum: TX PD firmware handling layer 2 only for high packet rate performance
9416 * tests (Medford development only) 9997 * tests (Medford development only)
9417 */ 9998 */
9418#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_TYPE_LAYER2_PERF 0x7 9999#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_TYPE_LAYER2_PERF 0x7
9419/* enum: Rules engine TX PD production firmware */ 10000/* enum: Rules engine TX PD production firmware */
9420#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_TYPE_RULES_ENGINE 0x8 10001#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_TYPE_RULES_ENGINE 0x8
9421/* enum: reserved value - do not use (bug69716) */ 10002/* enum: Custom firmware variant (see SF-119495-PD and bug69716) */
9422#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_TYPE_RESERVED_9 0x9 10003#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_TYPE_L3XUDP 0x9
10004/* enum: DPDK TX PD production firmware */
10005#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_TYPE_DPDK 0xa
9423/* enum: RX PD firmware for GUE parsing prototype (Medford development only) */ 10006/* enum: RX PD firmware for GUE parsing prototype (Medford development only) */
9424#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe 10007#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe
9425/* Hardware capabilities of NIC */ 10008/* Hardware capabilities of NIC */
9426#define MC_CMD_GET_CAPABILITIES_V2_OUT_HW_CAPABILITIES_OFST 12 10009#define MC_CMD_GET_CAPABILITIES_V2_OUT_HW_CAPABILITIES_OFST 12
9427#define MC_CMD_GET_CAPABILITIES_V2_OUT_HW_CAPABILITIES_LEN 4 10010#define MC_CMD_GET_CAPABILITIES_V2_OUT_HW_CAPABILITIES_LEN 4
@@ -9469,6 +10052,18 @@
9469#define MC_CMD_GET_CAPABILITIES_V2_OUT_TSA_BOUND_WIDTH 1 10052#define MC_CMD_GET_CAPABILITIES_V2_OUT_TSA_BOUND_WIDTH 1
9470#define MC_CMD_GET_CAPABILITIES_V2_OUT_SF_ADAPTER_AUTHENTICATION_LBN 18 10053#define MC_CMD_GET_CAPABILITIES_V2_OUT_SF_ADAPTER_AUTHENTICATION_LBN 18
9471#define MC_CMD_GET_CAPABILITIES_V2_OUT_SF_ADAPTER_AUTHENTICATION_WIDTH 1 10054#define MC_CMD_GET_CAPABILITIES_V2_OUT_SF_ADAPTER_AUTHENTICATION_WIDTH 1
10055#define MC_CMD_GET_CAPABILITIES_V2_OUT_FILTER_ACTION_FLAG_LBN 19
10056#define MC_CMD_GET_CAPABILITIES_V2_OUT_FILTER_ACTION_FLAG_WIDTH 1
10057#define MC_CMD_GET_CAPABILITIES_V2_OUT_FILTER_ACTION_MARK_LBN 20
10058#define MC_CMD_GET_CAPABILITIES_V2_OUT_FILTER_ACTION_MARK_WIDTH 1
10059#define MC_CMD_GET_CAPABILITIES_V2_OUT_EQUAL_STRIDE_PACKED_STREAM_LBN 21
10060#define MC_CMD_GET_CAPABILITIES_V2_OUT_EQUAL_STRIDE_PACKED_STREAM_WIDTH 1
10061#define MC_CMD_GET_CAPABILITIES_V2_OUT_L3XUDP_SUPPORT_LBN 22
10062#define MC_CMD_GET_CAPABILITIES_V2_OUT_L3XUDP_SUPPORT_WIDTH 1
10063#define MC_CMD_GET_CAPABILITIES_V2_OUT_FW_SUBVARIANT_NO_TX_CSUM_LBN 23
10064#define MC_CMD_GET_CAPABILITIES_V2_OUT_FW_SUBVARIANT_NO_TX_CSUM_WIDTH 1
10065#define MC_CMD_GET_CAPABILITIES_V2_OUT_VI_SPREADING_LBN 24
10066#define MC_CMD_GET_CAPABILITIES_V2_OUT_VI_SPREADING_WIDTH 1
9472/* Number of FATSOv2 contexts per datapath supported by this NIC. Not present 10067/* Number of FATSOv2 contexts per datapath supported by this NIC. Not present
9473 * on older firmware (check the length). 10068 * on older firmware (check the length).
9474 */ 10069 */
@@ -9482,18 +10077,18 @@
9482#define MC_CMD_GET_CAPABILITIES_V2_OUT_PFS_TO_PORTS_ASSIGNMENT_LEN 1 10077#define MC_CMD_GET_CAPABILITIES_V2_OUT_PFS_TO_PORTS_ASSIGNMENT_LEN 1
9483#define MC_CMD_GET_CAPABILITIES_V2_OUT_PFS_TO_PORTS_ASSIGNMENT_NUM 16 10078#define MC_CMD_GET_CAPABILITIES_V2_OUT_PFS_TO_PORTS_ASSIGNMENT_NUM 16
9484/* enum: The caller is not permitted to access information on this PF. */ 10079/* enum: The caller is not permitted to access information on this PF. */
9485#define MC_CMD_GET_CAPABILITIES_V2_OUT_ACCESS_NOT_PERMITTED 0xff 10080#define MC_CMD_GET_CAPABILITIES_V2_OUT_ACCESS_NOT_PERMITTED 0xff
9486/* enum: PF does not exist. */ 10081/* enum: PF does not exist. */
9487#define MC_CMD_GET_CAPABILITIES_V2_OUT_PF_NOT_PRESENT 0xfe 10082#define MC_CMD_GET_CAPABILITIES_V2_OUT_PF_NOT_PRESENT 0xfe
9488/* enum: PF does exist but is not assigned to any external port. */ 10083/* enum: PF does exist but is not assigned to any external port. */
9489#define MC_CMD_GET_CAPABILITIES_V2_OUT_PF_NOT_ASSIGNED 0xfd 10084#define MC_CMD_GET_CAPABILITIES_V2_OUT_PF_NOT_ASSIGNED 0xfd
9490/* enum: This value indicates that PF is assigned, but it cannot be expressed 10085/* enum: This value indicates that PF is assigned, but it cannot be expressed
9491 * in this field. It is intended for a possible future situation where a more 10086 * in this field. It is intended for a possible future situation where a more
9492 * complex scheme of PFs to ports mapping is being used. The future driver 10087 * complex scheme of PFs to ports mapping is being used. The future driver
9493 * should look for a new field supporting the new scheme. The current/old 10088 * should look for a new field supporting the new scheme. The current/old
9494 * driver should treat this value as PF_NOT_ASSIGNED. 10089 * driver should treat this value as PF_NOT_ASSIGNED.
9495 */ 10090 */
9496#define MC_CMD_GET_CAPABILITIES_V2_OUT_INCOMPATIBLE_ASSIGNMENT 0xfc 10091#define MC_CMD_GET_CAPABILITIES_V2_OUT_INCOMPATIBLE_ASSIGNMENT 0xfc
9497/* One byte per PF containing the number of its VFs, indexed by PF number. A 10092/* One byte per PF containing the number of its VFs, indexed by PF number. A
9498 * special value indicates that a PF is not present. 10093 * special value indicates that a PF is not present.
9499 */ 10094 */
@@ -9501,9 +10096,9 @@
9501#define MC_CMD_GET_CAPABILITIES_V2_OUT_NUM_VFS_PER_PF_LEN 1 10096#define MC_CMD_GET_CAPABILITIES_V2_OUT_NUM_VFS_PER_PF_LEN 1
9502#define MC_CMD_GET_CAPABILITIES_V2_OUT_NUM_VFS_PER_PF_NUM 16 10097#define MC_CMD_GET_CAPABILITIES_V2_OUT_NUM_VFS_PER_PF_NUM 16
9503/* enum: The caller is not permitted to access information on this PF. */ 10098/* enum: The caller is not permitted to access information on this PF. */
9504/* MC_CMD_GET_CAPABILITIES_V2_OUT_ACCESS_NOT_PERMITTED 0xff */ 10099/* MC_CMD_GET_CAPABILITIES_V2_OUT_ACCESS_NOT_PERMITTED 0xff */
9505/* enum: PF does not exist. */ 10100/* enum: PF does not exist. */
9506/* MC_CMD_GET_CAPABILITIES_V2_OUT_PF_NOT_PRESENT 0xfe */ 10101/* MC_CMD_GET_CAPABILITIES_V2_OUT_PF_NOT_PRESENT 0xfe */
9507/* Number of VIs available for each external port */ 10102/* Number of VIs available for each external port */
9508#define MC_CMD_GET_CAPABILITIES_V2_OUT_NUM_VIS_PER_PORT_OFST 58 10103#define MC_CMD_GET_CAPABILITIES_V2_OUT_NUM_VIS_PER_PORT_OFST 58
9509#define MC_CMD_GET_CAPABILITIES_V2_OUT_NUM_VIS_PER_PORT_LEN 2 10104#define MC_CMD_GET_CAPABILITIES_V2_OUT_NUM_VIS_PER_PORT_LEN 2
@@ -9592,54 +10187,58 @@
9592#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_DPCPU_FW_ID_OFST 4 10187#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_DPCPU_FW_ID_OFST 4
9593#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_DPCPU_FW_ID_LEN 2 10188#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_DPCPU_FW_ID_LEN 2
9594/* enum: Standard RXDP firmware */ 10189/* enum: Standard RXDP firmware */
9595#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP 0x0 10190#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP 0x0
9596/* enum: Low latency RXDP firmware */ 10191/* enum: Low latency RXDP firmware */
9597#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_LOW_LATENCY 0x1 10192#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_LOW_LATENCY 0x1
9598/* enum: Packed stream RXDP firmware */ 10193/* enum: Packed stream RXDP firmware */
9599#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_PACKED_STREAM 0x2 10194#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_PACKED_STREAM 0x2
9600/* enum: Rules engine RXDP firmware */ 10195/* enum: Rules engine RXDP firmware */
9601#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_RULES_ENGINE 0x5 10196#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_RULES_ENGINE 0x5
10197/* enum: DPDK RXDP firmware */
10198#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_DPDK 0x6
9602/* enum: BIST RXDP firmware */ 10199/* enum: BIST RXDP firmware */
9603#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_BIST 0x10a 10200#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_BIST 0x10a
9604/* enum: RXDP Test firmware image 1 */ 10201/* enum: RXDP Test firmware image 1 */
9605#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_TEST_FW_TO_MC_CUT_THROUGH 0x101 10202#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_TEST_FW_TO_MC_CUT_THROUGH 0x101
9606/* enum: RXDP Test firmware image 2 */ 10203/* enum: RXDP Test firmware image 2 */
9607#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_TEST_FW_TO_MC_STORE_FORWARD 0x102 10204#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_TEST_FW_TO_MC_STORE_FORWARD 0x102
9608/* enum: RXDP Test firmware image 3 */ 10205/* enum: RXDP Test firmware image 3 */
9609#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_TEST_FW_TO_MC_STORE_FORWARD_FIRST 0x103 10206#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_TEST_FW_TO_MC_STORE_FORWARD_FIRST 0x103
9610/* enum: RXDP Test firmware image 4 */ 10207/* enum: RXDP Test firmware image 4 */
9611#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_TEST_EVERY_EVENT_BATCHABLE 0x104 10208#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_TEST_EVERY_EVENT_BATCHABLE 0x104
9612/* enum: RXDP Test firmware image 5 */ 10209/* enum: RXDP Test firmware image 5 */
9613#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_TEST_BACKPRESSURE 0x105 10210#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_TEST_BACKPRESSURE 0x105
9614/* enum: RXDP Test firmware image 6 */ 10211/* enum: RXDP Test firmware image 6 */
9615#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_TEST_FW_PACKET_EDITS 0x106 10212#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_TEST_FW_PACKET_EDITS 0x106
9616/* enum: RXDP Test firmware image 7 */ 10213/* enum: RXDP Test firmware image 7 */
9617#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_TEST_FW_RX_HDR_SPLIT 0x107 10214#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_TEST_FW_RX_HDR_SPLIT 0x107
9618/* enum: RXDP Test firmware image 8 */ 10215/* enum: RXDP Test firmware image 8 */
9619#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_TEST_FW_DISABLE_DL 0x108 10216#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_TEST_FW_DISABLE_DL 0x108
9620/* enum: RXDP Test firmware image 9 */ 10217/* enum: RXDP Test firmware image 9 */
9621#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_TEST_FW_DOORBELL_DELAY 0x10b 10218#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_TEST_FW_DOORBELL_DELAY 0x10b
9622/* enum: RXDP Test firmware image 10 */ 10219/* enum: RXDP Test firmware image 10 */
9623#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_TEST_FW_SLOW 0x10c 10220#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_TEST_FW_SLOW 0x10c
9624/* TxDPCPU firmware id. */ 10221/* TxDPCPU firmware id. */
9625#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_DPCPU_FW_ID_OFST 6 10222#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_DPCPU_FW_ID_OFST 6
9626#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_DPCPU_FW_ID_LEN 2 10223#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_DPCPU_FW_ID_LEN 2
9627/* enum: Standard TXDP firmware */ 10224/* enum: Standard TXDP firmware */
9628#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXDP 0x0 10225#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXDP 0x0
9629/* enum: Low latency TXDP firmware */ 10226/* enum: Low latency TXDP firmware */
9630#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXDP_LOW_LATENCY 0x1 10227#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXDP_LOW_LATENCY 0x1
9631/* enum: High packet rate TXDP firmware */ 10228/* enum: High packet rate TXDP firmware */
9632#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXDP_HIGH_PACKET_RATE 0x3 10229#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXDP_HIGH_PACKET_RATE 0x3
9633/* enum: Rules engine TXDP firmware */ 10230/* enum: Rules engine TXDP firmware */
9634#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXDP_RULES_ENGINE 0x5 10231#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXDP_RULES_ENGINE 0x5
10232/* enum: DPDK TXDP firmware */
10233#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXDP_DPDK 0x6
9635/* enum: BIST TXDP firmware */ 10234/* enum: BIST TXDP firmware */
9636#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXDP_BIST 0x12d 10235#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXDP_BIST 0x12d
9637/* enum: TXDP Test firmware image 1 */ 10236/* enum: TXDP Test firmware image 1 */
9638#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXDP_TEST_FW_TSO_EDIT 0x101 10237#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXDP_TEST_FW_TSO_EDIT 0x101
9639/* enum: TXDP Test firmware image 2 */ 10238/* enum: TXDP Test firmware image 2 */
9640#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXDP_TEST_FW_PACKET_EDITS 0x102 10239#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXDP_TEST_FW_PACKET_EDITS 0x102
9641/* enum: TXDP CSR bus test firmware */ 10240/* enum: TXDP CSR bus test firmware */
9642#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXDP_TEST_FW_CSR 0x103 10241#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXDP_TEST_FW_CSR 0x103
9643#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_VERSION_OFST 8 10242#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_VERSION_OFST 8
9644#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_VERSION_LEN 2 10243#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_VERSION_LEN 2
9645#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_VERSION_REV_LBN 0 10244#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_VERSION_REV_LBN 0
@@ -9649,41 +10248,43 @@
9649/* enum: reserved value - do not use (may indicate alternative interpretation 10248/* enum: reserved value - do not use (may indicate alternative interpretation
9650 * of REV field in future) 10249 * of REV field in future)
9651 */ 10250 */
9652#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_RESERVED 0x0 10251#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_RESERVED 0x0
9653/* enum: Trivial RX PD firmware for early Huntington development (Huntington 10252/* enum: Trivial RX PD firmware for early Huntington development (Huntington
9654 * development only) 10253 * development only)
9655 */ 10254 */
9656#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_FIRST_PKT 0x1 10255#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_FIRST_PKT 0x1
9657/* enum: RX PD firmware with approximately Siena-compatible behaviour 10256/* enum: RX PD firmware with approximately Siena-compatible behaviour
9658 * (Huntington development only) 10257 * (Huntington development only)
9659 */ 10258 */
9660#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_SIENA_COMPAT 0x2 10259#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_SIENA_COMPAT 0x2
9661/* enum: Full featured RX PD production firmware */ 10260/* enum: Full featured RX PD production firmware */
9662#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_FULL_FEATURED 0x3 10261#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_FULL_FEATURED 0x3
9663/* enum: (deprecated original name for the FULL_FEATURED variant) */ 10262/* enum: (deprecated original name for the FULL_FEATURED variant) */
9664#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_VSWITCH 0x3 10263#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_VSWITCH 0x3
9665/* enum: siena_compat variant RX PD firmware using PM rather than MAC 10264/* enum: siena_compat variant RX PD firmware using PM rather than MAC
9666 * (Huntington development only) 10265 * (Huntington development only)
9667 */ 10266 */
9668#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_SIENA_COMPAT_PM 0x4 10267#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_SIENA_COMPAT_PM 0x4
9669/* enum: Low latency RX PD production firmware */ 10268/* enum: Low latency RX PD production firmware */
9670#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_LOW_LATENCY 0x5 10269#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_LOW_LATENCY 0x5
9671/* enum: Packed stream RX PD production firmware */ 10270/* enum: Packed stream RX PD production firmware */
9672#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_PACKED_STREAM 0x6 10271#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_PACKED_STREAM 0x6
9673/* enum: RX PD firmware handling layer 2 only for high packet rate performance 10272/* enum: RX PD firmware handling layer 2 only for high packet rate performance
9674 * tests (Medford development only) 10273 * tests (Medford development only)
9675 */ 10274 */
9676#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_LAYER2_PERF 0x7 10275#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_LAYER2_PERF 0x7
9677/* enum: Rules engine RX PD production firmware */ 10276/* enum: Rules engine RX PD production firmware */
9678#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_RULES_ENGINE 0x8 10277#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_RULES_ENGINE 0x8
9679/* enum: reserved value - do not use (bug69716) */ 10278/* enum: Custom firmware variant (see SF-119495-PD and bug69716) */
9680#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_RESERVED_9 0x9 10279#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_L3XUDP 0x9
10280/* enum: DPDK RX PD production firmware */
10281#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_DPDK 0xa
9681/* enum: RX PD firmware for GUE parsing prototype (Medford development only) */ 10282/* enum: RX PD firmware for GUE parsing prototype (Medford development only) */
9682#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe 10283#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe
9683/* enum: RX PD firmware parsing but not filtering network overlay tunnel 10284/* enum: RX PD firmware parsing but not filtering network overlay tunnel
9684 * encapsulations (Medford development only) 10285 * encapsulations (Medford development only)
9685 */ 10286 */
9686#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_TESTFW_ENCAP_PARSING_ONLY 0xf 10287#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_TESTFW_ENCAP_PARSING_ONLY 0xf
9687#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_VERSION_OFST 10 10288#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_VERSION_OFST 10
9688#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_VERSION_LEN 2 10289#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_VERSION_LEN 2
9689#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_VERSION_REV_LBN 0 10290#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_VERSION_REV_LBN 0
@@ -9693,34 +10294,36 @@
9693/* enum: reserved value - do not use (may indicate alternative interpretation 10294/* enum: reserved value - do not use (may indicate alternative interpretation
9694 * of REV field in future) 10295 * of REV field in future)
9695 */ 10296 */
9696#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_TYPE_RESERVED 0x0 10297#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_TYPE_RESERVED 0x0
9697/* enum: Trivial TX PD firmware for early Huntington development (Huntington 10298/* enum: Trivial TX PD firmware for early Huntington development (Huntington
9698 * development only) 10299 * development only)
9699 */ 10300 */
9700#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_TYPE_FIRST_PKT 0x1 10301#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_TYPE_FIRST_PKT 0x1
9701/* enum: TX PD firmware with approximately Siena-compatible behaviour 10302/* enum: TX PD firmware with approximately Siena-compatible behaviour
9702 * (Huntington development only) 10303 * (Huntington development only)
9703 */ 10304 */
9704#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_TYPE_SIENA_COMPAT 0x2 10305#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_TYPE_SIENA_COMPAT 0x2
9705/* enum: Full featured TX PD production firmware */ 10306/* enum: Full featured TX PD production firmware */
9706#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_TYPE_FULL_FEATURED 0x3 10307#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_TYPE_FULL_FEATURED 0x3
9707/* enum: (deprecated original name for the FULL_FEATURED variant) */ 10308/* enum: (deprecated original name for the FULL_FEATURED variant) */
9708#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_TYPE_VSWITCH 0x3 10309#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_TYPE_VSWITCH 0x3
9709/* enum: siena_compat variant TX PD firmware using PM rather than MAC 10310/* enum: siena_compat variant TX PD firmware using PM rather than MAC
9710 * (Huntington development only) 10311 * (Huntington development only)
9711 */ 10312 */
9712#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_TYPE_SIENA_COMPAT_PM 0x4 10313#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_TYPE_SIENA_COMPAT_PM 0x4
9713#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_TYPE_LOW_LATENCY 0x5 /* enum */ 10314#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_TYPE_LOW_LATENCY 0x5 /* enum */
9714/* enum: TX PD firmware handling layer 2 only for high packet rate performance 10315/* enum: TX PD firmware handling layer 2 only for high packet rate performance
9715 * tests (Medford development only) 10316 * tests (Medford development only)
9716 */ 10317 */
9717#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_TYPE_LAYER2_PERF 0x7 10318#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_TYPE_LAYER2_PERF 0x7
9718/* enum: Rules engine TX PD production firmware */ 10319/* enum: Rules engine TX PD production firmware */
9719#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_TYPE_RULES_ENGINE 0x8 10320#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_TYPE_RULES_ENGINE 0x8
9720/* enum: reserved value - do not use (bug69716) */ 10321/* enum: Custom firmware variant (see SF-119495-PD and bug69716) */
9721#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_TYPE_RESERVED_9 0x9 10322#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_TYPE_L3XUDP 0x9
10323/* enum: DPDK TX PD production firmware */
10324#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_TYPE_DPDK 0xa
9722/* enum: RX PD firmware for GUE parsing prototype (Medford development only) */ 10325/* enum: RX PD firmware for GUE parsing prototype (Medford development only) */
9723#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe 10326#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe
9724/* Hardware capabilities of NIC */ 10327/* Hardware capabilities of NIC */
9725#define MC_CMD_GET_CAPABILITIES_V3_OUT_HW_CAPABILITIES_OFST 12 10328#define MC_CMD_GET_CAPABILITIES_V3_OUT_HW_CAPABILITIES_OFST 12
9726#define MC_CMD_GET_CAPABILITIES_V3_OUT_HW_CAPABILITIES_LEN 4 10329#define MC_CMD_GET_CAPABILITIES_V3_OUT_HW_CAPABILITIES_LEN 4
@@ -9768,6 +10371,18 @@
9768#define MC_CMD_GET_CAPABILITIES_V3_OUT_TSA_BOUND_WIDTH 1 10371#define MC_CMD_GET_CAPABILITIES_V3_OUT_TSA_BOUND_WIDTH 1
9769#define MC_CMD_GET_CAPABILITIES_V3_OUT_SF_ADAPTER_AUTHENTICATION_LBN 18 10372#define MC_CMD_GET_CAPABILITIES_V3_OUT_SF_ADAPTER_AUTHENTICATION_LBN 18
9770#define MC_CMD_GET_CAPABILITIES_V3_OUT_SF_ADAPTER_AUTHENTICATION_WIDTH 1 10373#define MC_CMD_GET_CAPABILITIES_V3_OUT_SF_ADAPTER_AUTHENTICATION_WIDTH 1
10374#define MC_CMD_GET_CAPABILITIES_V3_OUT_FILTER_ACTION_FLAG_LBN 19
10375#define MC_CMD_GET_CAPABILITIES_V3_OUT_FILTER_ACTION_FLAG_WIDTH 1
10376#define MC_CMD_GET_CAPABILITIES_V3_OUT_FILTER_ACTION_MARK_LBN 20
10377#define MC_CMD_GET_CAPABILITIES_V3_OUT_FILTER_ACTION_MARK_WIDTH 1
10378#define MC_CMD_GET_CAPABILITIES_V3_OUT_EQUAL_STRIDE_PACKED_STREAM_LBN 21
10379#define MC_CMD_GET_CAPABILITIES_V3_OUT_EQUAL_STRIDE_PACKED_STREAM_WIDTH 1
10380#define MC_CMD_GET_CAPABILITIES_V3_OUT_L3XUDP_SUPPORT_LBN 22
10381#define MC_CMD_GET_CAPABILITIES_V3_OUT_L3XUDP_SUPPORT_WIDTH 1
10382#define MC_CMD_GET_CAPABILITIES_V3_OUT_FW_SUBVARIANT_NO_TX_CSUM_LBN 23
10383#define MC_CMD_GET_CAPABILITIES_V3_OUT_FW_SUBVARIANT_NO_TX_CSUM_WIDTH 1
10384#define MC_CMD_GET_CAPABILITIES_V3_OUT_VI_SPREADING_LBN 24
10385#define MC_CMD_GET_CAPABILITIES_V3_OUT_VI_SPREADING_WIDTH 1
9771/* Number of FATSOv2 contexts per datapath supported by this NIC. Not present 10386/* Number of FATSOv2 contexts per datapath supported by this NIC. Not present
9772 * on older firmware (check the length). 10387 * on older firmware (check the length).
9773 */ 10388 */
@@ -9781,18 +10396,18 @@
9781#define MC_CMD_GET_CAPABILITIES_V3_OUT_PFS_TO_PORTS_ASSIGNMENT_LEN 1 10396#define MC_CMD_GET_CAPABILITIES_V3_OUT_PFS_TO_PORTS_ASSIGNMENT_LEN 1
9782#define MC_CMD_GET_CAPABILITIES_V3_OUT_PFS_TO_PORTS_ASSIGNMENT_NUM 16 10397#define MC_CMD_GET_CAPABILITIES_V3_OUT_PFS_TO_PORTS_ASSIGNMENT_NUM 16
9783/* enum: The caller is not permitted to access information on this PF. */ 10398/* enum: The caller is not permitted to access information on this PF. */
9784#define MC_CMD_GET_CAPABILITIES_V3_OUT_ACCESS_NOT_PERMITTED 0xff 10399#define MC_CMD_GET_CAPABILITIES_V3_OUT_ACCESS_NOT_PERMITTED 0xff
9785/* enum: PF does not exist. */ 10400/* enum: PF does not exist. */
9786#define MC_CMD_GET_CAPABILITIES_V3_OUT_PF_NOT_PRESENT 0xfe 10401#define MC_CMD_GET_CAPABILITIES_V3_OUT_PF_NOT_PRESENT 0xfe
9787/* enum: PF does exist but is not assigned to any external port. */ 10402/* enum: PF does exist but is not assigned to any external port. */
9788#define MC_CMD_GET_CAPABILITIES_V3_OUT_PF_NOT_ASSIGNED 0xfd 10403#define MC_CMD_GET_CAPABILITIES_V3_OUT_PF_NOT_ASSIGNED 0xfd
9789/* enum: This value indicates that PF is assigned, but it cannot be expressed 10404/* enum: This value indicates that PF is assigned, but it cannot be expressed
9790 * in this field. It is intended for a possible future situation where a more 10405 * in this field. It is intended for a possible future situation where a more
9791 * complex scheme of PFs to ports mapping is being used. The future driver 10406 * complex scheme of PFs to ports mapping is being used. The future driver
9792 * should look for a new field supporting the new scheme. The current/old 10407 * should look for a new field supporting the new scheme. The current/old
9793 * driver should treat this value as PF_NOT_ASSIGNED. 10408 * driver should treat this value as PF_NOT_ASSIGNED.
9794 */ 10409 */
9795#define MC_CMD_GET_CAPABILITIES_V3_OUT_INCOMPATIBLE_ASSIGNMENT 0xfc 10410#define MC_CMD_GET_CAPABILITIES_V3_OUT_INCOMPATIBLE_ASSIGNMENT 0xfc
9796/* One byte per PF containing the number of its VFs, indexed by PF number. A 10411/* One byte per PF containing the number of its VFs, indexed by PF number. A
9797 * special value indicates that a PF is not present. 10412 * special value indicates that a PF is not present.
9798 */ 10413 */
@@ -9800,9 +10415,9 @@
9800#define MC_CMD_GET_CAPABILITIES_V3_OUT_NUM_VFS_PER_PF_LEN 1 10415#define MC_CMD_GET_CAPABILITIES_V3_OUT_NUM_VFS_PER_PF_LEN 1
9801#define MC_CMD_GET_CAPABILITIES_V3_OUT_NUM_VFS_PER_PF_NUM 16 10416#define MC_CMD_GET_CAPABILITIES_V3_OUT_NUM_VFS_PER_PF_NUM 16
9802/* enum: The caller is not permitted to access information on this PF. */ 10417/* enum: The caller is not permitted to access information on this PF. */
9803/* MC_CMD_GET_CAPABILITIES_V3_OUT_ACCESS_NOT_PERMITTED 0xff */ 10418/* MC_CMD_GET_CAPABILITIES_V3_OUT_ACCESS_NOT_PERMITTED 0xff */
9804/* enum: PF does not exist. */ 10419/* enum: PF does not exist. */
9805/* MC_CMD_GET_CAPABILITIES_V3_OUT_PF_NOT_PRESENT 0xfe */ 10420/* MC_CMD_GET_CAPABILITIES_V3_OUT_PF_NOT_PRESENT 0xfe */
9806/* Number of VIs available for each external port */ 10421/* Number of VIs available for each external port */
9807#define MC_CMD_GET_CAPABILITIES_V3_OUT_NUM_VIS_PER_PORT_OFST 58 10422#define MC_CMD_GET_CAPABILITIES_V3_OUT_NUM_VIS_PER_PORT_OFST 58
9808#define MC_CMD_GET_CAPABILITIES_V3_OUT_NUM_VIS_PER_PORT_LEN 2 10423#define MC_CMD_GET_CAPABILITIES_V3_OUT_NUM_VIS_PER_PORT_LEN 2
@@ -9833,11 +10448,11 @@
9833/* enum: Each VI occupies 8k as on Huntington and Medford. PIO is at offset 4k. 10448/* enum: Each VI occupies 8k as on Huntington and Medford. PIO is at offset 4k.
9834 * CTPIO is not mapped. 10449 * CTPIO is not mapped.
9835 */ 10450 */
9836#define MC_CMD_GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE_8K 0x0 10451#define MC_CMD_GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE_8K 0x0
9837/* enum: Each VI occupies 16k. PIO is at offset 4k. CTPIO is at offset 12k. */ 10452/* enum: Each VI occupies 16k. PIO is at offset 4k. CTPIO is at offset 12k. */
9838#define MC_CMD_GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE_16K 0x1 10453#define MC_CMD_GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE_16K 0x1
9839/* enum: Each VI occupies 64k. PIO is at offset 4k. CTPIO is at offset 12k. */ 10454/* enum: Each VI occupies 64k. PIO is at offset 4k. CTPIO is at offset 12k. */
9840#define MC_CMD_GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE_64K 0x2 10455#define MC_CMD_GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE_64K 0x2
9841/* Number of vFIFOs per adapter that can be used for VFIFO Stuffing 10456/* Number of vFIFOs per adapter that can be used for VFIFO Stuffing
9842 * (SF-115995-SW) in the present configuration of firmware and port mode. 10457 * (SF-115995-SW) in the present configuration of firmware and port mode.
9843 */ 10458 */
@@ -9916,54 +10531,58 @@
9916#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_DPCPU_FW_ID_OFST 4 10531#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_DPCPU_FW_ID_OFST 4
9917#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_DPCPU_FW_ID_LEN 2 10532#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_DPCPU_FW_ID_LEN 2
9918/* enum: Standard RXDP firmware */ 10533/* enum: Standard RXDP firmware */
9919#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP 0x0 10534#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP 0x0
9920/* enum: Low latency RXDP firmware */ 10535/* enum: Low latency RXDP firmware */
9921#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_LOW_LATENCY 0x1 10536#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_LOW_LATENCY 0x1
9922/* enum: Packed stream RXDP firmware */ 10537/* enum: Packed stream RXDP firmware */
9923#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_PACKED_STREAM 0x2 10538#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_PACKED_STREAM 0x2
9924/* enum: Rules engine RXDP firmware */ 10539/* enum: Rules engine RXDP firmware */
9925#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_RULES_ENGINE 0x5 10540#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_RULES_ENGINE 0x5
10541/* enum: DPDK RXDP firmware */
10542#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_DPDK 0x6
9926/* enum: BIST RXDP firmware */ 10543/* enum: BIST RXDP firmware */
9927#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_BIST 0x10a 10544#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_BIST 0x10a
9928/* enum: RXDP Test firmware image 1 */ 10545/* enum: RXDP Test firmware image 1 */
9929#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_TEST_FW_TO_MC_CUT_THROUGH 0x101 10546#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_TEST_FW_TO_MC_CUT_THROUGH 0x101
9930/* enum: RXDP Test firmware image 2 */ 10547/* enum: RXDP Test firmware image 2 */
9931#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_TEST_FW_TO_MC_STORE_FORWARD 0x102 10548#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_TEST_FW_TO_MC_STORE_FORWARD 0x102
9932/* enum: RXDP Test firmware image 3 */ 10549/* enum: RXDP Test firmware image 3 */
9933#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_TEST_FW_TO_MC_STORE_FORWARD_FIRST 0x103 10550#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_TEST_FW_TO_MC_STORE_FORWARD_FIRST 0x103
9934/* enum: RXDP Test firmware image 4 */ 10551/* enum: RXDP Test firmware image 4 */
9935#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_TEST_EVERY_EVENT_BATCHABLE 0x104 10552#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_TEST_EVERY_EVENT_BATCHABLE 0x104
9936/* enum: RXDP Test firmware image 5 */ 10553/* enum: RXDP Test firmware image 5 */
9937#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_TEST_BACKPRESSURE 0x105 10554#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_TEST_BACKPRESSURE 0x105
9938/* enum: RXDP Test firmware image 6 */ 10555/* enum: RXDP Test firmware image 6 */
9939#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_TEST_FW_PACKET_EDITS 0x106 10556#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_TEST_FW_PACKET_EDITS 0x106
9940/* enum: RXDP Test firmware image 7 */ 10557/* enum: RXDP Test firmware image 7 */
9941#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_TEST_FW_RX_HDR_SPLIT 0x107 10558#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_TEST_FW_RX_HDR_SPLIT 0x107
9942/* enum: RXDP Test firmware image 8 */ 10559/* enum: RXDP Test firmware image 8 */
9943#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_TEST_FW_DISABLE_DL 0x108 10560#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_TEST_FW_DISABLE_DL 0x108
9944/* enum: RXDP Test firmware image 9 */ 10561/* enum: RXDP Test firmware image 9 */
9945#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_TEST_FW_DOORBELL_DELAY 0x10b 10562#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_TEST_FW_DOORBELL_DELAY 0x10b
9946/* enum: RXDP Test firmware image 10 */ 10563/* enum: RXDP Test firmware image 10 */
9947#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_TEST_FW_SLOW 0x10c 10564#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_TEST_FW_SLOW 0x10c
9948/* TxDPCPU firmware id. */ 10565/* TxDPCPU firmware id. */
9949#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_DPCPU_FW_ID_OFST 6 10566#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_DPCPU_FW_ID_OFST 6
9950#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_DPCPU_FW_ID_LEN 2 10567#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_DPCPU_FW_ID_LEN 2
9951/* enum: Standard TXDP firmware */ 10568/* enum: Standard TXDP firmware */
9952#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXDP 0x0 10569#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXDP 0x0
9953/* enum: Low latency TXDP firmware */ 10570/* enum: Low latency TXDP firmware */
9954#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXDP_LOW_LATENCY 0x1 10571#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXDP_LOW_LATENCY 0x1
9955/* enum: High packet rate TXDP firmware */ 10572/* enum: High packet rate TXDP firmware */
9956#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXDP_HIGH_PACKET_RATE 0x3 10573#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXDP_HIGH_PACKET_RATE 0x3
9957/* enum: Rules engine TXDP firmware */ 10574/* enum: Rules engine TXDP firmware */
9958#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXDP_RULES_ENGINE 0x5 10575#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXDP_RULES_ENGINE 0x5
10576/* enum: DPDK TXDP firmware */
10577#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXDP_DPDK 0x6
9959/* enum: BIST TXDP firmware */ 10578/* enum: BIST TXDP firmware */
9960#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXDP_BIST 0x12d 10579#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXDP_BIST 0x12d
9961/* enum: TXDP Test firmware image 1 */ 10580/* enum: TXDP Test firmware image 1 */
9962#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXDP_TEST_FW_TSO_EDIT 0x101 10581#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXDP_TEST_FW_TSO_EDIT 0x101
9963/* enum: TXDP Test firmware image 2 */ 10582/* enum: TXDP Test firmware image 2 */
9964#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXDP_TEST_FW_PACKET_EDITS 0x102 10583#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXDP_TEST_FW_PACKET_EDITS 0x102
9965/* enum: TXDP CSR bus test firmware */ 10584/* enum: TXDP CSR bus test firmware */
9966#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXDP_TEST_FW_CSR 0x103 10585#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXDP_TEST_FW_CSR 0x103
9967#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_VERSION_OFST 8 10586#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_VERSION_OFST 8
9968#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_VERSION_LEN 2 10587#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_VERSION_LEN 2
9969#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_VERSION_REV_LBN 0 10588#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_VERSION_REV_LBN 0
@@ -9973,41 +10592,43 @@
9973/* enum: reserved value - do not use (may indicate alternative interpretation 10592/* enum: reserved value - do not use (may indicate alternative interpretation
9974 * of REV field in future) 10593 * of REV field in future)
9975 */ 10594 */
9976#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_RESERVED 0x0 10595#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_RESERVED 0x0
9977/* enum: Trivial RX PD firmware for early Huntington development (Huntington 10596/* enum: Trivial RX PD firmware for early Huntington development (Huntington
9978 * development only) 10597 * development only)
9979 */ 10598 */
9980#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_FIRST_PKT 0x1 10599#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_FIRST_PKT 0x1
9981/* enum: RX PD firmware with approximately Siena-compatible behaviour 10600/* enum: RX PD firmware with approximately Siena-compatible behaviour
9982 * (Huntington development only) 10601 * (Huntington development only)
9983 */ 10602 */
9984#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_SIENA_COMPAT 0x2 10603#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_SIENA_COMPAT 0x2
9985/* enum: Full featured RX PD production firmware */ 10604/* enum: Full featured RX PD production firmware */
9986#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_FULL_FEATURED 0x3 10605#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_FULL_FEATURED 0x3
9987/* enum: (deprecated original name for the FULL_FEATURED variant) */ 10606/* enum: (deprecated original name for the FULL_FEATURED variant) */
9988#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_VSWITCH 0x3 10607#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_VSWITCH 0x3
9989/* enum: siena_compat variant RX PD firmware using PM rather than MAC 10608/* enum: siena_compat variant RX PD firmware using PM rather than MAC
9990 * (Huntington development only) 10609 * (Huntington development only)
9991 */ 10610 */
9992#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_SIENA_COMPAT_PM 0x4 10611#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_SIENA_COMPAT_PM 0x4
9993/* enum: Low latency RX PD production firmware */ 10612/* enum: Low latency RX PD production firmware */
9994#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_LOW_LATENCY 0x5 10613#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_LOW_LATENCY 0x5
9995/* enum: Packed stream RX PD production firmware */ 10614/* enum: Packed stream RX PD production firmware */
9996#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_PACKED_STREAM 0x6 10615#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_PACKED_STREAM 0x6
9997/* enum: RX PD firmware handling layer 2 only for high packet rate performance 10616/* enum: RX PD firmware handling layer 2 only for high packet rate performance
9998 * tests (Medford development only) 10617 * tests (Medford development only)
9999 */ 10618 */
10000#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_LAYER2_PERF 0x7 10619#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_LAYER2_PERF 0x7
10001/* enum: Rules engine RX PD production firmware */ 10620/* enum: Rules engine RX PD production firmware */
10002#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_RULES_ENGINE 0x8 10621#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_RULES_ENGINE 0x8
10003/* enum: reserved value - do not use (bug69716) */ 10622/* enum: Custom firmware variant (see SF-119495-PD and bug69716) */
10004#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_RESERVED_9 0x9 10623#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_L3XUDP 0x9
10624/* enum: DPDK RX PD production firmware */
10625#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_DPDK 0xa
10005/* enum: RX PD firmware for GUE parsing prototype (Medford development only) */ 10626/* enum: RX PD firmware for GUE parsing prototype (Medford development only) */
10006#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe 10627#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe
10007/* enum: RX PD firmware parsing but not filtering network overlay tunnel 10628/* enum: RX PD firmware parsing but not filtering network overlay tunnel
10008 * encapsulations (Medford development only) 10629 * encapsulations (Medford development only)
10009 */ 10630 */
10010#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_TESTFW_ENCAP_PARSING_ONLY 0xf 10631#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_TESTFW_ENCAP_PARSING_ONLY 0xf
10011#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_VERSION_OFST 10 10632#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_VERSION_OFST 10
10012#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_VERSION_LEN 2 10633#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_VERSION_LEN 2
10013#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_VERSION_REV_LBN 0 10634#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_VERSION_REV_LBN 0
@@ -10017,34 +10638,36 @@
10017/* enum: reserved value - do not use (may indicate alternative interpretation 10638/* enum: reserved value - do not use (may indicate alternative interpretation
10018 * of REV field in future) 10639 * of REV field in future)
10019 */ 10640 */
10020#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_TYPE_RESERVED 0x0 10641#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_TYPE_RESERVED 0x0
10021/* enum: Trivial TX PD firmware for early Huntington development (Huntington 10642/* enum: Trivial TX PD firmware for early Huntington development (Huntington
10022 * development only) 10643 * development only)
10023 */ 10644 */
10024#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_TYPE_FIRST_PKT 0x1 10645#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_TYPE_FIRST_PKT 0x1
10025/* enum: TX PD firmware with approximately Siena-compatible behaviour 10646/* enum: TX PD firmware with approximately Siena-compatible behaviour
10026 * (Huntington development only) 10647 * (Huntington development only)
10027 */ 10648 */
10028#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_TYPE_SIENA_COMPAT 0x2 10649#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_TYPE_SIENA_COMPAT 0x2
10029/* enum: Full featured TX PD production firmware */ 10650/* enum: Full featured TX PD production firmware */
10030#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_TYPE_FULL_FEATURED 0x3 10651#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_TYPE_FULL_FEATURED 0x3
10031/* enum: (deprecated original name for the FULL_FEATURED variant) */ 10652/* enum: (deprecated original name for the FULL_FEATURED variant) */
10032#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_TYPE_VSWITCH 0x3 10653#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_TYPE_VSWITCH 0x3
10033/* enum: siena_compat variant TX PD firmware using PM rather than MAC 10654/* enum: siena_compat variant TX PD firmware using PM rather than MAC
10034 * (Huntington development only) 10655 * (Huntington development only)
10035 */ 10656 */
10036#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_TYPE_SIENA_COMPAT_PM 0x4 10657#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_TYPE_SIENA_COMPAT_PM 0x4
10037#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_TYPE_LOW_LATENCY 0x5 /* enum */ 10658#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_TYPE_LOW_LATENCY 0x5 /* enum */
10038/* enum: TX PD firmware handling layer 2 only for high packet rate performance 10659/* enum: TX PD firmware handling layer 2 only for high packet rate performance
10039 * tests (Medford development only) 10660 * tests (Medford development only)
10040 */ 10661 */
10041#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_TYPE_LAYER2_PERF 0x7 10662#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_TYPE_LAYER2_PERF 0x7
10042/* enum: Rules engine TX PD production firmware */ 10663/* enum: Rules engine TX PD production firmware */
10043#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_TYPE_RULES_ENGINE 0x8 10664#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_TYPE_RULES_ENGINE 0x8
10044/* enum: reserved value - do not use (bug69716) */ 10665/* enum: Custom firmware variant (see SF-119495-PD and bug69716) */
10045#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_TYPE_RESERVED_9 0x9 10666#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_TYPE_L3XUDP 0x9
10667/* enum: DPDK TX PD production firmware */
10668#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_TYPE_DPDK 0xa
10046/* enum: RX PD firmware for GUE parsing prototype (Medford development only) */ 10669/* enum: RX PD firmware for GUE parsing prototype (Medford development only) */
10047#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe 10670#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe
10048/* Hardware capabilities of NIC */ 10671/* Hardware capabilities of NIC */
10049#define MC_CMD_GET_CAPABILITIES_V4_OUT_HW_CAPABILITIES_OFST 12 10672#define MC_CMD_GET_CAPABILITIES_V4_OUT_HW_CAPABILITIES_OFST 12
10050#define MC_CMD_GET_CAPABILITIES_V4_OUT_HW_CAPABILITIES_LEN 4 10673#define MC_CMD_GET_CAPABILITIES_V4_OUT_HW_CAPABILITIES_LEN 4
@@ -10092,6 +10715,18 @@
10092#define MC_CMD_GET_CAPABILITIES_V4_OUT_TSA_BOUND_WIDTH 1 10715#define MC_CMD_GET_CAPABILITIES_V4_OUT_TSA_BOUND_WIDTH 1
10093#define MC_CMD_GET_CAPABILITIES_V4_OUT_SF_ADAPTER_AUTHENTICATION_LBN 18 10716#define MC_CMD_GET_CAPABILITIES_V4_OUT_SF_ADAPTER_AUTHENTICATION_LBN 18
10094#define MC_CMD_GET_CAPABILITIES_V4_OUT_SF_ADAPTER_AUTHENTICATION_WIDTH 1 10717#define MC_CMD_GET_CAPABILITIES_V4_OUT_SF_ADAPTER_AUTHENTICATION_WIDTH 1
10718#define MC_CMD_GET_CAPABILITIES_V4_OUT_FILTER_ACTION_FLAG_LBN 19
10719#define MC_CMD_GET_CAPABILITIES_V4_OUT_FILTER_ACTION_FLAG_WIDTH 1
10720#define MC_CMD_GET_CAPABILITIES_V4_OUT_FILTER_ACTION_MARK_LBN 20
10721#define MC_CMD_GET_CAPABILITIES_V4_OUT_FILTER_ACTION_MARK_WIDTH 1
10722#define MC_CMD_GET_CAPABILITIES_V4_OUT_EQUAL_STRIDE_PACKED_STREAM_LBN 21
10723#define MC_CMD_GET_CAPABILITIES_V4_OUT_EQUAL_STRIDE_PACKED_STREAM_WIDTH 1
10724#define MC_CMD_GET_CAPABILITIES_V4_OUT_L3XUDP_SUPPORT_LBN 22
10725#define MC_CMD_GET_CAPABILITIES_V4_OUT_L3XUDP_SUPPORT_WIDTH 1
10726#define MC_CMD_GET_CAPABILITIES_V4_OUT_FW_SUBVARIANT_NO_TX_CSUM_LBN 23
10727#define MC_CMD_GET_CAPABILITIES_V4_OUT_FW_SUBVARIANT_NO_TX_CSUM_WIDTH 1
10728#define MC_CMD_GET_CAPABILITIES_V4_OUT_VI_SPREADING_LBN 24
10729#define MC_CMD_GET_CAPABILITIES_V4_OUT_VI_SPREADING_WIDTH 1
10095/* Number of FATSOv2 contexts per datapath supported by this NIC. Not present 10730/* Number of FATSOv2 contexts per datapath supported by this NIC. Not present
10096 * on older firmware (check the length). 10731 * on older firmware (check the length).
10097 */ 10732 */
@@ -10105,18 +10740,18 @@
10105#define MC_CMD_GET_CAPABILITIES_V4_OUT_PFS_TO_PORTS_ASSIGNMENT_LEN 1 10740#define MC_CMD_GET_CAPABILITIES_V4_OUT_PFS_TO_PORTS_ASSIGNMENT_LEN 1
10106#define MC_CMD_GET_CAPABILITIES_V4_OUT_PFS_TO_PORTS_ASSIGNMENT_NUM 16 10741#define MC_CMD_GET_CAPABILITIES_V4_OUT_PFS_TO_PORTS_ASSIGNMENT_NUM 16
10107/* enum: The caller is not permitted to access information on this PF. */ 10742/* enum: The caller is not permitted to access information on this PF. */
10108#define MC_CMD_GET_CAPABILITIES_V4_OUT_ACCESS_NOT_PERMITTED 0xff 10743#define MC_CMD_GET_CAPABILITIES_V4_OUT_ACCESS_NOT_PERMITTED 0xff
10109/* enum: PF does not exist. */ 10744/* enum: PF does not exist. */
10110#define MC_CMD_GET_CAPABILITIES_V4_OUT_PF_NOT_PRESENT 0xfe 10745#define MC_CMD_GET_CAPABILITIES_V4_OUT_PF_NOT_PRESENT 0xfe
10111/* enum: PF does exist but is not assigned to any external port. */ 10746/* enum: PF does exist but is not assigned to any external port. */
10112#define MC_CMD_GET_CAPABILITIES_V4_OUT_PF_NOT_ASSIGNED 0xfd 10747#define MC_CMD_GET_CAPABILITIES_V4_OUT_PF_NOT_ASSIGNED 0xfd
10113/* enum: This value indicates that PF is assigned, but it cannot be expressed 10748/* enum: This value indicates that PF is assigned, but it cannot be expressed
10114 * in this field. It is intended for a possible future situation where a more 10749 * in this field. It is intended for a possible future situation where a more
10115 * complex scheme of PFs to ports mapping is being used. The future driver 10750 * complex scheme of PFs to ports mapping is being used. The future driver
10116 * should look for a new field supporting the new scheme. The current/old 10751 * should look for a new field supporting the new scheme. The current/old
10117 * driver should treat this value as PF_NOT_ASSIGNED. 10752 * driver should treat this value as PF_NOT_ASSIGNED.
10118 */ 10753 */
10119#define MC_CMD_GET_CAPABILITIES_V4_OUT_INCOMPATIBLE_ASSIGNMENT 0xfc 10754#define MC_CMD_GET_CAPABILITIES_V4_OUT_INCOMPATIBLE_ASSIGNMENT 0xfc
10120/* One byte per PF containing the number of its VFs, indexed by PF number. A 10755/* One byte per PF containing the number of its VFs, indexed by PF number. A
10121 * special value indicates that a PF is not present. 10756 * special value indicates that a PF is not present.
10122 */ 10757 */
@@ -10124,9 +10759,9 @@
10124#define MC_CMD_GET_CAPABILITIES_V4_OUT_NUM_VFS_PER_PF_LEN 1 10759#define MC_CMD_GET_CAPABILITIES_V4_OUT_NUM_VFS_PER_PF_LEN 1
10125#define MC_CMD_GET_CAPABILITIES_V4_OUT_NUM_VFS_PER_PF_NUM 16 10760#define MC_CMD_GET_CAPABILITIES_V4_OUT_NUM_VFS_PER_PF_NUM 16
10126/* enum: The caller is not permitted to access information on this PF. */ 10761/* enum: The caller is not permitted to access information on this PF. */
10127/* MC_CMD_GET_CAPABILITIES_V4_OUT_ACCESS_NOT_PERMITTED 0xff */ 10762/* MC_CMD_GET_CAPABILITIES_V4_OUT_ACCESS_NOT_PERMITTED 0xff */
10128/* enum: PF does not exist. */ 10763/* enum: PF does not exist. */
10129/* MC_CMD_GET_CAPABILITIES_V4_OUT_PF_NOT_PRESENT 0xfe */ 10764/* MC_CMD_GET_CAPABILITIES_V4_OUT_PF_NOT_PRESENT 0xfe */
10130/* Number of VIs available for each external port */ 10765/* Number of VIs available for each external port */
10131#define MC_CMD_GET_CAPABILITIES_V4_OUT_NUM_VIS_PER_PORT_OFST 58 10766#define MC_CMD_GET_CAPABILITIES_V4_OUT_NUM_VIS_PER_PORT_OFST 58
10132#define MC_CMD_GET_CAPABILITIES_V4_OUT_NUM_VIS_PER_PORT_LEN 2 10767#define MC_CMD_GET_CAPABILITIES_V4_OUT_NUM_VIS_PER_PORT_LEN 2
@@ -10157,11 +10792,11 @@
10157/* enum: Each VI occupies 8k as on Huntington and Medford. PIO is at offset 4k. 10792/* enum: Each VI occupies 8k as on Huntington and Medford. PIO is at offset 4k.
10158 * CTPIO is not mapped. 10793 * CTPIO is not mapped.
10159 */ 10794 */
10160#define MC_CMD_GET_CAPABILITIES_V4_OUT_VI_WINDOW_MODE_8K 0x0 10795#define MC_CMD_GET_CAPABILITIES_V4_OUT_VI_WINDOW_MODE_8K 0x0
10161/* enum: Each VI occupies 16k. PIO is at offset 4k. CTPIO is at offset 12k. */ 10796/* enum: Each VI occupies 16k. PIO is at offset 4k. CTPIO is at offset 12k. */
10162#define MC_CMD_GET_CAPABILITIES_V4_OUT_VI_WINDOW_MODE_16K 0x1 10797#define MC_CMD_GET_CAPABILITIES_V4_OUT_VI_WINDOW_MODE_16K 0x1
10163/* enum: Each VI occupies 64k. PIO is at offset 4k. CTPIO is at offset 12k. */ 10798/* enum: Each VI occupies 64k. PIO is at offset 4k. CTPIO is at offset 12k. */
10164#define MC_CMD_GET_CAPABILITIES_V4_OUT_VI_WINDOW_MODE_64K 0x2 10799#define MC_CMD_GET_CAPABILITIES_V4_OUT_VI_WINDOW_MODE_64K 0x2
10165/* Number of vFIFOs per adapter that can be used for VFIFO Stuffing 10800/* Number of vFIFOs per adapter that can be used for VFIFO Stuffing
10166 * (SF-115995-SW) in the present configuration of firmware and port mode. 10801 * (SF-115995-SW) in the present configuration of firmware and port mode.
10167 */ 10802 */
@@ -10201,7 +10836,16 @@
10201#define MC_CMD_V2_EXTN_IN_ACTUAL_LEN_LBN 16 10836#define MC_CMD_V2_EXTN_IN_ACTUAL_LEN_LBN 16
10202#define MC_CMD_V2_EXTN_IN_ACTUAL_LEN_WIDTH 10 10837#define MC_CMD_V2_EXTN_IN_ACTUAL_LEN_WIDTH 10
10203#define MC_CMD_V2_EXTN_IN_UNUSED2_LBN 26 10838#define MC_CMD_V2_EXTN_IN_UNUSED2_LBN 26
10204#define MC_CMD_V2_EXTN_IN_UNUSED2_WIDTH 6 10839#define MC_CMD_V2_EXTN_IN_UNUSED2_WIDTH 2
10840/* Type of command/response */
10841#define MC_CMD_V2_EXTN_IN_MESSAGE_TYPE_LBN 28
10842#define MC_CMD_V2_EXTN_IN_MESSAGE_TYPE_WIDTH 4
10843/* enum: MCDI command directed to or response originating from the MC. */
10844#define MC_CMD_V2_EXTN_IN_MCDI_MESSAGE_TYPE_MC 0x0
10845/* enum: MCDI command directed to a TSA controller. MCDI responses of this type
10846 * are not defined.
10847 */
10848#define MC_CMD_V2_EXTN_IN_MCDI_MESSAGE_TYPE_TSA 0x1
10205 10849
10206 10850
10207/***********************************/ 10851/***********************************/
@@ -10412,15 +11056,15 @@
10412#define MC_CMD_VSWITCH_ALLOC_IN_TYPE_OFST 4 11056#define MC_CMD_VSWITCH_ALLOC_IN_TYPE_OFST 4
10413#define MC_CMD_VSWITCH_ALLOC_IN_TYPE_LEN 4 11057#define MC_CMD_VSWITCH_ALLOC_IN_TYPE_LEN 4
10414/* enum: VLAN */ 11058/* enum: VLAN */
10415#define MC_CMD_VSWITCH_ALLOC_IN_VSWITCH_TYPE_VLAN 0x1 11059#define MC_CMD_VSWITCH_ALLOC_IN_VSWITCH_TYPE_VLAN 0x1
10416/* enum: VEB */ 11060/* enum: VEB */
10417#define MC_CMD_VSWITCH_ALLOC_IN_VSWITCH_TYPE_VEB 0x2 11061#define MC_CMD_VSWITCH_ALLOC_IN_VSWITCH_TYPE_VEB 0x2
10418/* enum: VEPA (obsolete) */ 11062/* enum: VEPA (obsolete) */
10419#define MC_CMD_VSWITCH_ALLOC_IN_VSWITCH_TYPE_VEPA 0x3 11063#define MC_CMD_VSWITCH_ALLOC_IN_VSWITCH_TYPE_VEPA 0x3
10420/* enum: MUX */ 11064/* enum: MUX */
10421#define MC_CMD_VSWITCH_ALLOC_IN_VSWITCH_TYPE_MUX 0x4 11065#define MC_CMD_VSWITCH_ALLOC_IN_VSWITCH_TYPE_MUX 0x4
10422/* enum: Snapper specific; semantics TBD */ 11066/* enum: Snapper specific; semantics TBD */
10423#define MC_CMD_VSWITCH_ALLOC_IN_VSWITCH_TYPE_TEST 0x5 11067#define MC_CMD_VSWITCH_ALLOC_IN_VSWITCH_TYPE_TEST 0x5
10424/* Flags controlling v-port creation */ 11068/* Flags controlling v-port creation */
10425#define MC_CMD_VSWITCH_ALLOC_IN_FLAGS_OFST 8 11069#define MC_CMD_VSWITCH_ALLOC_IN_FLAGS_OFST 8
10426#define MC_CMD_VSWITCH_ALLOC_IN_FLAGS_LEN 4 11070#define MC_CMD_VSWITCH_ALLOC_IN_FLAGS_LEN 4
@@ -10495,23 +11139,23 @@
10495#define MC_CMD_VPORT_ALLOC_IN_TYPE_OFST 4 11139#define MC_CMD_VPORT_ALLOC_IN_TYPE_OFST 4
10496#define MC_CMD_VPORT_ALLOC_IN_TYPE_LEN 4 11140#define MC_CMD_VPORT_ALLOC_IN_TYPE_LEN 4
10497/* enum: VLAN (obsolete) */ 11141/* enum: VLAN (obsolete) */
10498#define MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_VLAN 0x1 11142#define MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_VLAN 0x1
10499/* enum: VEB (obsolete) */ 11143/* enum: VEB (obsolete) */
10500#define MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_VEB 0x2 11144#define MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_VEB 0x2
10501/* enum: VEPA (obsolete) */ 11145/* enum: VEPA (obsolete) */
10502#define MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_VEPA 0x3 11146#define MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_VEPA 0x3
10503/* enum: A normal v-port receives packets which match a specified MAC and/or 11147/* enum: A normal v-port receives packets which match a specified MAC and/or
10504 * VLAN. 11148 * VLAN.
10505 */ 11149 */
10506#define MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_NORMAL 0x4 11150#define MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_NORMAL 0x4
10507/* enum: An expansion v-port packets traffic which don't match any other 11151/* enum: An expansion v-port packets traffic which don't match any other
10508 * v-port. 11152 * v-port.
10509 */ 11153 */
10510#define MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_EXPANSION 0x5 11154#define MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_EXPANSION 0x5
10511/* enum: An test v-port receives packets which match any filters installed by 11155/* enum: An test v-port receives packets which match any filters installed by
10512 * its downstream components. 11156 * its downstream components.
10513 */ 11157 */
10514#define MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_TEST 0x6 11158#define MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_TEST 0x6
10515/* Flags controlling v-port creation */ 11159/* Flags controlling v-port creation */
10516#define MC_CMD_VPORT_ALLOC_IN_FLAGS_OFST 8 11160#define MC_CMD_VPORT_ALLOC_IN_FLAGS_OFST 8
10517#define MC_CMD_VPORT_ALLOC_IN_FLAGS_LEN 4 11161#define MC_CMD_VPORT_ALLOC_IN_FLAGS_LEN 4
@@ -10595,7 +11239,7 @@
10595#define MC_CMD_VADAPTOR_ALLOC_IN_MACADDR_OFST 24 11239#define MC_CMD_VADAPTOR_ALLOC_IN_MACADDR_OFST 24
10596#define MC_CMD_VADAPTOR_ALLOC_IN_MACADDR_LEN 6 11240#define MC_CMD_VADAPTOR_ALLOC_IN_MACADDR_LEN 6
10597/* enum: Derive the MAC address from the upstream port */ 11241/* enum: Derive the MAC address from the upstream port */
10598#define MC_CMD_VADAPTOR_ALLOC_IN_AUTO_MAC 0x0 11242#define MC_CMD_VADAPTOR_ALLOC_IN_AUTO_MAC 0x0
10599 11243
10600/* MC_CMD_VADAPTOR_ALLOC_OUT msgresponse */ 11244/* MC_CMD_VADAPTOR_ALLOC_OUT msgresponse */
10601#define MC_CMD_VADAPTOR_ALLOC_OUT_LEN 0 11245#define MC_CMD_VADAPTOR_ALLOC_OUT_LEN 0
@@ -10809,12 +11453,12 @@
10809/* enum: Allocate a context for exclusive use. The key and indirection table 11453/* enum: Allocate a context for exclusive use. The key and indirection table
10810 * must be explicitly configured. 11454 * must be explicitly configured.
10811 */ 11455 */
10812#define MC_CMD_RSS_CONTEXT_ALLOC_IN_TYPE_EXCLUSIVE 0x0 11456#define MC_CMD_RSS_CONTEXT_ALLOC_IN_TYPE_EXCLUSIVE 0x0
10813/* enum: Allocate a context for shared use; this will spread across a range of 11457/* enum: Allocate a context for shared use; this will spread across a range of
10814 * queues, but the key and indirection table are pre-configured and may not be 11458 * queues, but the key and indirection table are pre-configured and may not be
10815 * changed. For this mode, NUM_QUEUES must 2, 4, 8, 16, 32 or 64. 11459 * changed. For this mode, NUM_QUEUES must 2, 4, 8, 16, 32 or 64.
10816 */ 11460 */
10817#define MC_CMD_RSS_CONTEXT_ALLOC_IN_TYPE_SHARED 0x1 11461#define MC_CMD_RSS_CONTEXT_ALLOC_IN_TYPE_SHARED 0x1
10818/* Number of queues spanned by this context, in the range 1-64; valid offsets 11462/* Number of queues spanned by this context, in the range 1-64; valid offsets
10819 * in the indirection table will be in the range 0 to NUM_QUEUES-1. 11463 * in the indirection table will be in the range 0 to NUM_QUEUES-1.
10820 */ 11464 */
@@ -10830,7 +11474,7 @@
10830#define MC_CMD_RSS_CONTEXT_ALLOC_OUT_RSS_CONTEXT_ID_OFST 0 11474#define MC_CMD_RSS_CONTEXT_ALLOC_OUT_RSS_CONTEXT_ID_OFST 0
10831#define MC_CMD_RSS_CONTEXT_ALLOC_OUT_RSS_CONTEXT_ID_LEN 4 11475#define MC_CMD_RSS_CONTEXT_ALLOC_OUT_RSS_CONTEXT_ID_LEN 4
10832/* enum: guaranteed invalid RSS context handle value */ 11476/* enum: guaranteed invalid RSS context handle value */
10833#define MC_CMD_RSS_CONTEXT_ALLOC_OUT_RSS_CONTEXT_ID_INVALID 0xffffffff 11477#define MC_CMD_RSS_CONTEXT_ALLOC_OUT_RSS_CONTEXT_ID_INVALID 0xffffffff
10834 11478
10835 11479
10836/***********************************/ 11480/***********************************/
@@ -11073,7 +11717,7 @@
11073#define MC_CMD_DOT1P_MAPPING_ALLOC_OUT_DOT1P_MAPPING_ID_OFST 0 11717#define MC_CMD_DOT1P_MAPPING_ALLOC_OUT_DOT1P_MAPPING_ID_OFST 0
11074#define MC_CMD_DOT1P_MAPPING_ALLOC_OUT_DOT1P_MAPPING_ID_LEN 4 11718#define MC_CMD_DOT1P_MAPPING_ALLOC_OUT_DOT1P_MAPPING_ID_LEN 4
11075/* enum: guaranteed invalid .1p mapping handle value */ 11719/* enum: guaranteed invalid .1p mapping handle value */
11076#define MC_CMD_DOT1P_MAPPING_ALLOC_OUT_DOT1P_MAPPING_ID_INVALID 0xffffffff 11720#define MC_CMD_DOT1P_MAPPING_ALLOC_OUT_DOT1P_MAPPING_ID_INVALID 0xffffffff
11077 11721
11078 11722
11079/***********************************/ 11723/***********************************/
@@ -11385,11 +12029,11 @@
11385#define MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_LEN_LBN 1 12029#define MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_LEN_LBN 1
11386#define MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_LEN_WIDTH 2 12030#define MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_LEN_WIDTH 2
11387/* enum: pad to 64 bytes */ 12031/* enum: pad to 64 bytes */
11388#define MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_64 0x0 12032#define MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_64 0x0
11389/* enum: pad to 128 bytes (Medford only) */ 12033/* enum: pad to 128 bytes (Medford only) */
11390#define MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_128 0x1 12034#define MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_128 0x1
11391/* enum: pad to 256 bytes (Medford only) */ 12035/* enum: pad to 256 bytes (Medford only) */
11392#define MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_256 0x2 12036#define MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_256 0x2
11393 12037
11394/* MC_CMD_SET_RXDP_CONFIG_OUT msgresponse */ 12038/* MC_CMD_SET_RXDP_CONFIG_OUT msgresponse */
11395#define MC_CMD_SET_RXDP_CONFIG_OUT_LEN 0 12039#define MC_CMD_SET_RXDP_CONFIG_OUT_LEN 0
@@ -11453,37 +12097,37 @@
11453#define MC_CMD_SET_CLOCK_IN_SYS_FREQ_OFST 0 12097#define MC_CMD_SET_CLOCK_IN_SYS_FREQ_OFST 0
11454#define MC_CMD_SET_CLOCK_IN_SYS_FREQ_LEN 4 12098#define MC_CMD_SET_CLOCK_IN_SYS_FREQ_LEN 4
11455/* enum: Leave the system clock domain frequency unchanged */ 12099/* enum: Leave the system clock domain frequency unchanged */
11456#define MC_CMD_SET_CLOCK_IN_SYS_DOMAIN_DONT_CHANGE 0x0 12100#define MC_CMD_SET_CLOCK_IN_SYS_DOMAIN_DONT_CHANGE 0x0
11457/* Requested frequency in MHz for inter-core clock domain */ 12101/* Requested frequency in MHz for inter-core clock domain */
11458#define MC_CMD_SET_CLOCK_IN_ICORE_FREQ_OFST 4 12102#define MC_CMD_SET_CLOCK_IN_ICORE_FREQ_OFST 4
11459#define MC_CMD_SET_CLOCK_IN_ICORE_FREQ_LEN 4 12103#define MC_CMD_SET_CLOCK_IN_ICORE_FREQ_LEN 4
11460/* enum: Leave the inter-core clock domain frequency unchanged */ 12104/* enum: Leave the inter-core clock domain frequency unchanged */
11461#define MC_CMD_SET_CLOCK_IN_ICORE_DOMAIN_DONT_CHANGE 0x0 12105#define MC_CMD_SET_CLOCK_IN_ICORE_DOMAIN_DONT_CHANGE 0x0
11462/* Requested frequency in MHz for DPCPU clock domain */ 12106/* Requested frequency in MHz for DPCPU clock domain */
11463#define MC_CMD_SET_CLOCK_IN_DPCPU_FREQ_OFST 8 12107#define MC_CMD_SET_CLOCK_IN_DPCPU_FREQ_OFST 8
11464#define MC_CMD_SET_CLOCK_IN_DPCPU_FREQ_LEN 4 12108#define MC_CMD_SET_CLOCK_IN_DPCPU_FREQ_LEN 4
11465/* enum: Leave the DPCPU clock domain frequency unchanged */ 12109/* enum: Leave the DPCPU clock domain frequency unchanged */
11466#define MC_CMD_SET_CLOCK_IN_DPCPU_DOMAIN_DONT_CHANGE 0x0 12110#define MC_CMD_SET_CLOCK_IN_DPCPU_DOMAIN_DONT_CHANGE 0x0
11467/* Requested frequency in MHz for PCS clock domain */ 12111/* Requested frequency in MHz for PCS clock domain */
11468#define MC_CMD_SET_CLOCK_IN_PCS_FREQ_OFST 12 12112#define MC_CMD_SET_CLOCK_IN_PCS_FREQ_OFST 12
11469#define MC_CMD_SET_CLOCK_IN_PCS_FREQ_LEN 4 12113#define MC_CMD_SET_CLOCK_IN_PCS_FREQ_LEN 4
11470/* enum: Leave the PCS clock domain frequency unchanged */ 12114/* enum: Leave the PCS clock domain frequency unchanged */
11471#define MC_CMD_SET_CLOCK_IN_PCS_DOMAIN_DONT_CHANGE 0x0 12115#define MC_CMD_SET_CLOCK_IN_PCS_DOMAIN_DONT_CHANGE 0x0
11472/* Requested frequency in MHz for MC clock domain */ 12116/* Requested frequency in MHz for MC clock domain */
11473#define MC_CMD_SET_CLOCK_IN_MC_FREQ_OFST 16 12117#define MC_CMD_SET_CLOCK_IN_MC_FREQ_OFST 16
11474#define MC_CMD_SET_CLOCK_IN_MC_FREQ_LEN 4 12118#define MC_CMD_SET_CLOCK_IN_MC_FREQ_LEN 4
11475/* enum: Leave the MC clock domain frequency unchanged */ 12119/* enum: Leave the MC clock domain frequency unchanged */
11476#define MC_CMD_SET_CLOCK_IN_MC_DOMAIN_DONT_CHANGE 0x0 12120#define MC_CMD_SET_CLOCK_IN_MC_DOMAIN_DONT_CHANGE 0x0
11477/* Requested frequency in MHz for rmon clock domain */ 12121/* Requested frequency in MHz for rmon clock domain */
11478#define MC_CMD_SET_CLOCK_IN_RMON_FREQ_OFST 20 12122#define MC_CMD_SET_CLOCK_IN_RMON_FREQ_OFST 20
11479#define MC_CMD_SET_CLOCK_IN_RMON_FREQ_LEN 4 12123#define MC_CMD_SET_CLOCK_IN_RMON_FREQ_LEN 4
11480/* enum: Leave the rmon clock domain frequency unchanged */ 12124/* enum: Leave the rmon clock domain frequency unchanged */
11481#define MC_CMD_SET_CLOCK_IN_RMON_DOMAIN_DONT_CHANGE 0x0 12125#define MC_CMD_SET_CLOCK_IN_RMON_DOMAIN_DONT_CHANGE 0x0
11482/* Requested frequency in MHz for vswitch clock domain */ 12126/* Requested frequency in MHz for vswitch clock domain */
11483#define MC_CMD_SET_CLOCK_IN_VSWITCH_FREQ_OFST 24 12127#define MC_CMD_SET_CLOCK_IN_VSWITCH_FREQ_OFST 24
11484#define MC_CMD_SET_CLOCK_IN_VSWITCH_FREQ_LEN 4 12128#define MC_CMD_SET_CLOCK_IN_VSWITCH_FREQ_LEN 4
11485/* enum: Leave the vswitch clock domain frequency unchanged */ 12129/* enum: Leave the vswitch clock domain frequency unchanged */
11486#define MC_CMD_SET_CLOCK_IN_VSWITCH_DOMAIN_DONT_CHANGE 0x0 12130#define MC_CMD_SET_CLOCK_IN_VSWITCH_DOMAIN_DONT_CHANGE 0x0
11487 12131
11488/* MC_CMD_SET_CLOCK_OUT msgresponse */ 12132/* MC_CMD_SET_CLOCK_OUT msgresponse */
11489#define MC_CMD_SET_CLOCK_OUT_LEN 28 12133#define MC_CMD_SET_CLOCK_OUT_LEN 28
@@ -11491,37 +12135,37 @@
11491#define MC_CMD_SET_CLOCK_OUT_SYS_FREQ_OFST 0 12135#define MC_CMD_SET_CLOCK_OUT_SYS_FREQ_OFST 0
11492#define MC_CMD_SET_CLOCK_OUT_SYS_FREQ_LEN 4 12136#define MC_CMD_SET_CLOCK_OUT_SYS_FREQ_LEN 4
11493/* enum: The system clock domain doesn't exist */ 12137/* enum: The system clock domain doesn't exist */
11494#define MC_CMD_SET_CLOCK_OUT_SYS_DOMAIN_UNSUPPORTED 0x0 12138#define MC_CMD_SET_CLOCK_OUT_SYS_DOMAIN_UNSUPPORTED 0x0
11495/* Resulting inter-core frequency in MHz */ 12139/* Resulting inter-core frequency in MHz */
11496#define MC_CMD_SET_CLOCK_OUT_ICORE_FREQ_OFST 4 12140#define MC_CMD_SET_CLOCK_OUT_ICORE_FREQ_OFST 4
11497#define MC_CMD_SET_CLOCK_OUT_ICORE_FREQ_LEN 4 12141#define MC_CMD_SET_CLOCK_OUT_ICORE_FREQ_LEN 4
11498/* enum: The inter-core clock domain doesn't exist / isn't used */ 12142/* enum: The inter-core clock domain doesn't exist / isn't used */
11499#define MC_CMD_SET_CLOCK_OUT_ICORE_DOMAIN_UNSUPPORTED 0x0 12143#define MC_CMD_SET_CLOCK_OUT_ICORE_DOMAIN_UNSUPPORTED 0x0
11500/* Resulting DPCPU frequency in MHz */ 12144/* Resulting DPCPU frequency in MHz */
11501#define MC_CMD_SET_CLOCK_OUT_DPCPU_FREQ_OFST 8 12145#define MC_CMD_SET_CLOCK_OUT_DPCPU_FREQ_OFST 8
11502#define MC_CMD_SET_CLOCK_OUT_DPCPU_FREQ_LEN 4 12146#define MC_CMD_SET_CLOCK_OUT_DPCPU_FREQ_LEN 4
11503/* enum: The dpcpu clock domain doesn't exist */ 12147/* enum: The dpcpu clock domain doesn't exist */
11504#define MC_CMD_SET_CLOCK_OUT_DPCPU_DOMAIN_UNSUPPORTED 0x0 12148#define MC_CMD_SET_CLOCK_OUT_DPCPU_DOMAIN_UNSUPPORTED 0x0
11505/* Resulting PCS frequency in MHz */ 12149/* Resulting PCS frequency in MHz */
11506#define MC_CMD_SET_CLOCK_OUT_PCS_FREQ_OFST 12 12150#define MC_CMD_SET_CLOCK_OUT_PCS_FREQ_OFST 12
11507#define MC_CMD_SET_CLOCK_OUT_PCS_FREQ_LEN 4 12151#define MC_CMD_SET_CLOCK_OUT_PCS_FREQ_LEN 4
11508/* enum: The PCS clock domain doesn't exist / isn't controlled */ 12152/* enum: The PCS clock domain doesn't exist / isn't controlled */
11509#define MC_CMD_SET_CLOCK_OUT_PCS_DOMAIN_UNSUPPORTED 0x0 12153#define MC_CMD_SET_CLOCK_OUT_PCS_DOMAIN_UNSUPPORTED 0x0
11510/* Resulting MC frequency in MHz */ 12154/* Resulting MC frequency in MHz */
11511#define MC_CMD_SET_CLOCK_OUT_MC_FREQ_OFST 16 12155#define MC_CMD_SET_CLOCK_OUT_MC_FREQ_OFST 16
11512#define MC_CMD_SET_CLOCK_OUT_MC_FREQ_LEN 4 12156#define MC_CMD_SET_CLOCK_OUT_MC_FREQ_LEN 4
11513/* enum: The MC clock domain doesn't exist / isn't controlled */ 12157/* enum: The MC clock domain doesn't exist / isn't controlled */
11514#define MC_CMD_SET_CLOCK_OUT_MC_DOMAIN_UNSUPPORTED 0x0 12158#define MC_CMD_SET_CLOCK_OUT_MC_DOMAIN_UNSUPPORTED 0x0
11515/* Resulting rmon frequency in MHz */ 12159/* Resulting rmon frequency in MHz */
11516#define MC_CMD_SET_CLOCK_OUT_RMON_FREQ_OFST 20 12160#define MC_CMD_SET_CLOCK_OUT_RMON_FREQ_OFST 20
11517#define MC_CMD_SET_CLOCK_OUT_RMON_FREQ_LEN 4 12161#define MC_CMD_SET_CLOCK_OUT_RMON_FREQ_LEN 4
11518/* enum: The rmon clock domain doesn't exist / isn't controlled */ 12162/* enum: The rmon clock domain doesn't exist / isn't controlled */
11519#define MC_CMD_SET_CLOCK_OUT_RMON_DOMAIN_UNSUPPORTED 0x0 12163#define MC_CMD_SET_CLOCK_OUT_RMON_DOMAIN_UNSUPPORTED 0x0
11520/* Resulting vswitch frequency in MHz */ 12164/* Resulting vswitch frequency in MHz */
11521#define MC_CMD_SET_CLOCK_OUT_VSWITCH_FREQ_OFST 24 12165#define MC_CMD_SET_CLOCK_OUT_VSWITCH_FREQ_OFST 24
11522#define MC_CMD_SET_CLOCK_OUT_VSWITCH_FREQ_LEN 4 12166#define MC_CMD_SET_CLOCK_OUT_VSWITCH_FREQ_LEN 4
11523/* enum: The vswitch clock domain doesn't exist / isn't controlled */ 12167/* enum: The vswitch clock domain doesn't exist / isn't controlled */
11524#define MC_CMD_SET_CLOCK_OUT_VSWITCH_DOMAIN_UNSUPPORTED 0x0 12168#define MC_CMD_SET_CLOCK_OUT_VSWITCH_DOMAIN_UNSUPPORTED 0x0
11525 12169
11526 12170
11527/***********************************/ 12171/***********************************/
@@ -11537,21 +12181,21 @@
11537#define MC_CMD_DPCPU_RPC_IN_CPU_OFST 0 12181#define MC_CMD_DPCPU_RPC_IN_CPU_OFST 0
11538#define MC_CMD_DPCPU_RPC_IN_CPU_LEN 4 12182#define MC_CMD_DPCPU_RPC_IN_CPU_LEN 4
11539/* enum: RxDPCPU0 */ 12183/* enum: RxDPCPU0 */
11540#define MC_CMD_DPCPU_RPC_IN_DPCPU_RX0 0x0 12184#define MC_CMD_DPCPU_RPC_IN_DPCPU_RX0 0x0
11541/* enum: TxDPCPU0 */ 12185/* enum: TxDPCPU0 */
11542#define MC_CMD_DPCPU_RPC_IN_DPCPU_TX0 0x1 12186#define MC_CMD_DPCPU_RPC_IN_DPCPU_TX0 0x1
11543/* enum: TxDPCPU1 */ 12187/* enum: TxDPCPU1 */
11544#define MC_CMD_DPCPU_RPC_IN_DPCPU_TX1 0x2 12188#define MC_CMD_DPCPU_RPC_IN_DPCPU_TX1 0x2
11545/* enum: RxDPCPU1 (Medford only) */ 12189/* enum: RxDPCPU1 (Medford only) */
11546#define MC_CMD_DPCPU_RPC_IN_DPCPU_RX1 0x3 12190#define MC_CMD_DPCPU_RPC_IN_DPCPU_RX1 0x3
11547/* enum: RxDPCPU (will be for the calling function; for now, just an alias of 12191/* enum: RxDPCPU (will be for the calling function; for now, just an alias of
11548 * DPCPU_RX0) 12192 * DPCPU_RX0)
11549 */ 12193 */
11550#define MC_CMD_DPCPU_RPC_IN_DPCPU_RX 0x80 12194#define MC_CMD_DPCPU_RPC_IN_DPCPU_RX 0x80
11551/* enum: TxDPCPU (will be for the calling function; for now, just an alias of 12195/* enum: TxDPCPU (will be for the calling function; for now, just an alias of
11552 * DPCPU_TX0) 12196 * DPCPU_TX0)
11553 */ 12197 */
11554#define MC_CMD_DPCPU_RPC_IN_DPCPU_TX 0x81 12198#define MC_CMD_DPCPU_RPC_IN_DPCPU_TX 0x81
11555/* First 8 bits [39:32] of DATA are consumed by MC-DPCPU protocol and must be 12199/* First 8 bits [39:32] of DATA are consumed by MC-DPCPU protocol and must be
11556 * initialised to zero 12200 * initialised to zero
11557 */ 12201 */
@@ -11559,15 +12203,15 @@
11559#define MC_CMD_DPCPU_RPC_IN_DATA_LEN 32 12203#define MC_CMD_DPCPU_RPC_IN_DATA_LEN 32
11560#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_CMDNUM_LBN 8 12204#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_CMDNUM_LBN 8
11561#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_CMDNUM_WIDTH 8 12205#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_CMDNUM_WIDTH 8
11562#define MC_CMD_DPCPU_RPC_IN_CMDNUM_TXDPCPU_READ 0x6 /* enum */ 12206#define MC_CMD_DPCPU_RPC_IN_CMDNUM_TXDPCPU_READ 0x6 /* enum */
11563#define MC_CMD_DPCPU_RPC_IN_CMDNUM_TXDPCPU_WRITE 0x7 /* enum */ 12207#define MC_CMD_DPCPU_RPC_IN_CMDNUM_TXDPCPU_WRITE 0x7 /* enum */
11564#define MC_CMD_DPCPU_RPC_IN_CMDNUM_TXDPCPU_SELF_TEST 0xc /* enum */ 12208#define MC_CMD_DPCPU_RPC_IN_CMDNUM_TXDPCPU_SELF_TEST 0xc /* enum */
11565#define MC_CMD_DPCPU_RPC_IN_CMDNUM_TXDPCPU_CSR_ACCESS 0xe /* enum */ 12209#define MC_CMD_DPCPU_RPC_IN_CMDNUM_TXDPCPU_CSR_ACCESS 0xe /* enum */
11566#define MC_CMD_DPCPU_RPC_IN_CMDNUM_RXDPCPU_READ 0x46 /* enum */ 12210#define MC_CMD_DPCPU_RPC_IN_CMDNUM_RXDPCPU_READ 0x46 /* enum */
11567#define MC_CMD_DPCPU_RPC_IN_CMDNUM_RXDPCPU_WRITE 0x47 /* enum */ 12211#define MC_CMD_DPCPU_RPC_IN_CMDNUM_RXDPCPU_WRITE 0x47 /* enum */
11568#define MC_CMD_DPCPU_RPC_IN_CMDNUM_RXDPCPU_SELF_TEST 0x4a /* enum */ 12212#define MC_CMD_DPCPU_RPC_IN_CMDNUM_RXDPCPU_SELF_TEST 0x4a /* enum */
11569#define MC_CMD_DPCPU_RPC_IN_CMDNUM_RXDPCPU_CSR_ACCESS 0x4c /* enum */ 12213#define MC_CMD_DPCPU_RPC_IN_CMDNUM_RXDPCPU_CSR_ACCESS 0x4c /* enum */
11570#define MC_CMD_DPCPU_RPC_IN_CMDNUM_RXDPCPU_SET_MC_REPLAY_CNTXT 0x4d /* enum */ 12214#define MC_CMD_DPCPU_RPC_IN_CMDNUM_RXDPCPU_SET_MC_REPLAY_CNTXT 0x4d /* enum */
11571#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_REQ_OBJID_LBN 16 12215#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_REQ_OBJID_LBN 16
11572#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_REQ_OBJID_WIDTH 16 12216#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_REQ_OBJID_WIDTH 16
11573#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_REQ_ADDR_LBN 16 12217#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_REQ_ADDR_LBN 16
@@ -11578,11 +12222,11 @@
11578#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_INFO_WIDTH 240 12222#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_INFO_WIDTH 240
11579#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_CMD_LBN 16 12223#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_CMD_LBN 16
11580#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_CMD_WIDTH 16 12224#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_CMD_WIDTH 16
11581#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_CMD_STOP_RETURN_RESULT 0x0 /* enum */ 12225#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_CMD_STOP_RETURN_RESULT 0x0 /* enum */
11582#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_CMD_START_READ 0x1 /* enum */ 12226#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_CMD_START_READ 0x1 /* enum */
11583#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_CMD_START_WRITE 0x2 /* enum */ 12227#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_CMD_START_WRITE 0x2 /* enum */
11584#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_CMD_START_WRITE_READ 0x3 /* enum */ 12228#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_CMD_START_WRITE_READ 0x3 /* enum */
11585#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_CMD_START_PIPELINED_READ 0x4 /* enum */ 12229#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_CMD_START_PIPELINED_READ 0x4 /* enum */
11586#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_START_DELAY_LBN 48 12230#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_START_DELAY_LBN 48
11587#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_START_DELAY_WIDTH 16 12231#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_START_DELAY_WIDTH 16
11588#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_RPT_COUNT_LBN 64 12232#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_RPT_COUNT_LBN 64
@@ -11591,9 +12235,9 @@
11591#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_GAP_DELAY_WIDTH 16 12235#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_GAP_DELAY_WIDTH 16
11592#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_MODE_LBN 16 12236#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_MODE_LBN 16
11593#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_MODE_WIDTH 16 12237#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_MODE_WIDTH 16
11594#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_MODE_CUT_THROUGH 0x1 /* enum */ 12238#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_MODE_CUT_THROUGH 0x1 /* enum */
11595#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_MODE_STORE_FORWARD 0x2 /* enum */ 12239#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_MODE_STORE_FORWARD 0x2 /* enum */
11596#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_MODE_STORE_FORWARD_FIRST 0x3 /* enum */ 12240#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_MODE_STORE_FORWARD_FIRST 0x3 /* enum */
11597#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_CNTXT_LBN 64 12241#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_CNTXT_LBN 64
11598#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_CNTXT_WIDTH 16 12242#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_CNTXT_WIDTH 16
11599#define MC_CMD_DPCPU_RPC_IN_WDATA_OFST 12 12243#define MC_CMD_DPCPU_RPC_IN_WDATA_OFST 12
@@ -11660,7 +12304,7 @@
11660#define MC_CMD_SHMBOOT_OP_IN_SHMBOOT_OP_OFST 0 12304#define MC_CMD_SHMBOOT_OP_IN_SHMBOOT_OP_OFST 0
11661#define MC_CMD_SHMBOOT_OP_IN_SHMBOOT_OP_LEN 4 12305#define MC_CMD_SHMBOOT_OP_IN_SHMBOOT_OP_LEN 4
11662/* enum: Copy slave_data section to the slave core. (Greenport only) */ 12306/* enum: Copy slave_data section to the slave core. (Greenport only) */
11663#define MC_CMD_SHMBOOT_OP_IN_PUSH_SLAVE_DATA 0x0 12307#define MC_CMD_SHMBOOT_OP_IN_PUSH_SLAVE_DATA 0x0
11664 12308
11665/* MC_CMD_SHMBOOT_OP_OUT msgresponse */ 12309/* MC_CMD_SHMBOOT_OP_OUT msgresponse */
11666#define MC_CMD_SHMBOOT_OP_OUT_LEN 0 12310#define MC_CMD_SHMBOOT_OP_OUT_LEN 0
@@ -11709,14 +12353,14 @@
11709#define MC_CMD_DUMP_DO_IN_PADDING_LEN 4 12353#define MC_CMD_DUMP_DO_IN_PADDING_LEN 4
11710#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_OFST 4 12354#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_OFST 4
11711#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_LEN 4 12355#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_LEN 4
11712#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM 0x0 /* enum */ 12356#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM 0x0 /* enum */
11713#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_DEFAULT 0x1 /* enum */ 12357#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_DEFAULT 0x1 /* enum */
11714#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_TYPE_OFST 8 12358#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_TYPE_OFST 8
11715#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_TYPE_LEN 4 12359#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_TYPE_LEN 4
11716#define MC_CMD_DUMP_DO_IN_DUMP_LOCATION_NVRAM 0x1 /* enum */ 12360#define MC_CMD_DUMP_DO_IN_DUMP_LOCATION_NVRAM 0x1 /* enum */
11717#define MC_CMD_DUMP_DO_IN_DUMP_LOCATION_HOST_MEMORY 0x2 /* enum */ 12361#define MC_CMD_DUMP_DO_IN_DUMP_LOCATION_HOST_MEMORY 0x2 /* enum */
11718#define MC_CMD_DUMP_DO_IN_DUMP_LOCATION_HOST_MEMORY_MLI 0x3 /* enum */ 12362#define MC_CMD_DUMP_DO_IN_DUMP_LOCATION_HOST_MEMORY_MLI 0x3 /* enum */
11719#define MC_CMD_DUMP_DO_IN_DUMP_LOCATION_UART 0x4 /* enum */ 12363#define MC_CMD_DUMP_DO_IN_DUMP_LOCATION_UART 0x4 /* enum */
11720#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_NVRAM_PARTITION_TYPE_ID_OFST 12 12364#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_NVRAM_PARTITION_TYPE_ID_OFST 12
11721#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_NVRAM_PARTITION_TYPE_ID_LEN 4 12365#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_NVRAM_PARTITION_TYPE_ID_LEN 4
11722#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_NVRAM_OFFSET_OFST 16 12366#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_NVRAM_OFFSET_OFST 16
@@ -11727,24 +12371,24 @@
11727#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_ADDR_HI_LEN 4 12371#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_ADDR_HI_LEN 4
11728#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_LO_OFST 12 12372#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_LO_OFST 12
11729#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_LO_LEN 4 12373#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_LO_LEN 4
11730#define MC_CMD_DUMP_DO_IN_HOST_MEMORY_MLI_PAGE_SIZE 0x1000 /* enum */ 12374#define MC_CMD_DUMP_DO_IN_HOST_MEMORY_MLI_PAGE_SIZE 0x1000 /* enum */
11731#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_HI_OFST 16 12375#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_HI_OFST 16
11732#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_HI_LEN 4 12376#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_HI_LEN 4
11733#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_DEPTH_OFST 20 12377#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_DEPTH_OFST 20
11734#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_DEPTH_LEN 4 12378#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_DEPTH_LEN 4
11735#define MC_CMD_DUMP_DO_IN_HOST_MEMORY_MLI_MAX_DEPTH 0x2 /* enum */ 12379#define MC_CMD_DUMP_DO_IN_HOST_MEMORY_MLI_MAX_DEPTH 0x2 /* enum */
11736#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_UART_PORT_OFST 12 12380#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_UART_PORT_OFST 12
11737#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_UART_PORT_LEN 4 12381#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_UART_PORT_LEN 4
11738/* enum: The uart port this command was received over (if using a uart 12382/* enum: The uart port this command was received over (if using a uart
11739 * transport) 12383 * transport)
11740 */ 12384 */
11741#define MC_CMD_DUMP_DO_IN_UART_PORT_SRC 0xff 12385#define MC_CMD_DUMP_DO_IN_UART_PORT_SRC 0xff
11742#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_SIZE_OFST 24 12386#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_SIZE_OFST 24
11743#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_SIZE_LEN 4 12387#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_SIZE_LEN 4
11744#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_OFST 28 12388#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_OFST 28
11745#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_LEN 4 12389#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_LEN 4
11746#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM 0x0 /* enum */ 12390#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM 0x0 /* enum */
11747#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_NVRAM_DUMP_PARTITION 0x1 /* enum */ 12391#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_NVRAM_DUMP_PARTITION 0x1 /* enum */
11748#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_TYPE_OFST 32 12392#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_TYPE_OFST 32
11749#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_TYPE_LEN 4 12393#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_TYPE_LEN 4
11750/* Enum values, see field(s): */ 12394/* Enum values, see field(s): */
@@ -11854,11 +12498,11 @@
11854#define MC_CMD_SET_PSU_IN_LEN 12 12498#define MC_CMD_SET_PSU_IN_LEN 12
11855#define MC_CMD_SET_PSU_IN_PARAM_OFST 0 12499#define MC_CMD_SET_PSU_IN_PARAM_OFST 0
11856#define MC_CMD_SET_PSU_IN_PARAM_LEN 4 12500#define MC_CMD_SET_PSU_IN_PARAM_LEN 4
11857#define MC_CMD_SET_PSU_IN_PARAM_SUPPLY_VOLTAGE 0x0 /* enum */ 12501#define MC_CMD_SET_PSU_IN_PARAM_SUPPLY_VOLTAGE 0x0 /* enum */
11858#define MC_CMD_SET_PSU_IN_RAIL_OFST 4 12502#define MC_CMD_SET_PSU_IN_RAIL_OFST 4
11859#define MC_CMD_SET_PSU_IN_RAIL_LEN 4 12503#define MC_CMD_SET_PSU_IN_RAIL_LEN 4
11860#define MC_CMD_SET_PSU_IN_RAIL_0V9 0x0 /* enum */ 12504#define MC_CMD_SET_PSU_IN_RAIL_0V9 0x0 /* enum */
11861#define MC_CMD_SET_PSU_IN_RAIL_1V2 0x1 /* enum */ 12505#define MC_CMD_SET_PSU_IN_RAIL_1V2 0x1 /* enum */
11862/* desired value, eg voltage in mV */ 12506/* desired value, eg voltage in mV */
11863#define MC_CMD_SET_PSU_IN_VALUE_OFST 8 12507#define MC_CMD_SET_PSU_IN_VALUE_OFST 8
11864#define MC_CMD_SET_PSU_IN_VALUE_LEN 4 12508#define MC_CMD_SET_PSU_IN_VALUE_LEN 4
@@ -12031,26 +12675,30 @@
12031#define MC_CMD_KR_TUNE_IN_KR_TUNE_OP_OFST 0 12675#define MC_CMD_KR_TUNE_IN_KR_TUNE_OP_OFST 0
12032#define MC_CMD_KR_TUNE_IN_KR_TUNE_OP_LEN 1 12676#define MC_CMD_KR_TUNE_IN_KR_TUNE_OP_LEN 1
12033/* enum: Get current RXEQ settings */ 12677/* enum: Get current RXEQ settings */
12034#define MC_CMD_KR_TUNE_IN_RXEQ_GET 0x0 12678#define MC_CMD_KR_TUNE_IN_RXEQ_GET 0x0
12035/* enum: Override RXEQ settings */ 12679/* enum: Override RXEQ settings */
12036#define MC_CMD_KR_TUNE_IN_RXEQ_SET 0x1 12680#define MC_CMD_KR_TUNE_IN_RXEQ_SET 0x1
12037/* enum: Get current TX Driver settings */ 12681/* enum: Get current TX Driver settings */
12038#define MC_CMD_KR_TUNE_IN_TXEQ_GET 0x2 12682#define MC_CMD_KR_TUNE_IN_TXEQ_GET 0x2
12039/* enum: Override TX Driver settings */ 12683/* enum: Override TX Driver settings */
12040#define MC_CMD_KR_TUNE_IN_TXEQ_SET 0x3 12684#define MC_CMD_KR_TUNE_IN_TXEQ_SET 0x3
12041/* enum: Force KR Serdes reset / recalibration */ 12685/* enum: Force KR Serdes reset / recalibration */
12042#define MC_CMD_KR_TUNE_IN_RECAL 0x4 12686#define MC_CMD_KR_TUNE_IN_RECAL 0x4
12043/* enum: Start KR Serdes Eye diagram plot on a given lane. Lane must have valid 12687/* enum: Start KR Serdes Eye diagram plot on a given lane. Lane must have valid
12044 * signal. 12688 * signal.
12045 */ 12689 */
12046#define MC_CMD_KR_TUNE_IN_START_EYE_PLOT 0x5 12690#define MC_CMD_KR_TUNE_IN_START_EYE_PLOT 0x5
12047/* enum: Poll KR Serdes Eye diagram plot. Returns one row of BER data. The 12691/* enum: Poll KR Serdes Eye diagram plot. Returns one row of BER data. The
12048 * caller should call this command repeatedly after starting eye plot, until no 12692 * caller should call this command repeatedly after starting eye plot, until no
12049 * more data is returned. 12693 * more data is returned.
12050 */ 12694 */
12051#define MC_CMD_KR_TUNE_IN_POLL_EYE_PLOT 0x6 12695#define MC_CMD_KR_TUNE_IN_POLL_EYE_PLOT 0x6
12052/* enum: Read Figure Of Merit (eye quality, higher is better). */ 12696/* enum: Read Figure Of Merit (eye quality, higher is better). */
12053#define MC_CMD_KR_TUNE_IN_READ_FOM 0x7 12697#define MC_CMD_KR_TUNE_IN_READ_FOM 0x7
12698/* enum: Start/stop link training frames */
12699#define MC_CMD_KR_TUNE_IN_LINK_TRAIN_RUN 0x8
12700/* enum: Issue KR link training command (control training coefficients) */
12701#define MC_CMD_KR_TUNE_IN_LINK_TRAIN_CMD 0x9
12054/* Align the arguments to 32 bits */ 12702/* Align the arguments to 32 bits */
12055#define MC_CMD_KR_TUNE_IN_KR_TUNE_RSVD_OFST 1 12703#define MC_CMD_KR_TUNE_IN_KR_TUNE_RSVD_OFST 1
12056#define MC_CMD_KR_TUNE_IN_KR_TUNE_RSVD_LEN 3 12704#define MC_CMD_KR_TUNE_IN_KR_TUNE_RSVD_LEN 3
@@ -12084,98 +12732,98 @@
12084#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_ID_LBN 0 12732#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_ID_LBN 0
12085#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_ID_WIDTH 8 12733#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_ID_WIDTH 8
12086/* enum: Attenuation (0-15, Huntington) */ 12734/* enum: Attenuation (0-15, Huntington) */
12087#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_ATT 0x0 12735#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_ATT 0x0
12088/* enum: CTLE Boost (0-15, Huntington) */ 12736/* enum: CTLE Boost (0-15, Huntington) */
12089#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_BOOST 0x1 12737#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_BOOST 0x1
12090/* enum: Edge DFE Tap1 (Huntington - 0 - max negative, 64 - zero, 127 - max 12738/* enum: Edge DFE Tap1 (Huntington - 0 - max negative, 64 - zero, 127 - max
12091 * positive, Medford - 0-31) 12739 * positive, Medford - 0-31)
12092 */ 12740 */
12093#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_EDFE_TAP1 0x2 12741#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_EDFE_TAP1 0x2
12094/* enum: Edge DFE Tap2 (Huntington - 0 - max negative, 32 - zero, 63 - max 12742/* enum: Edge DFE Tap2 (Huntington - 0 - max negative, 32 - zero, 63 - max
12095 * positive, Medford - 0-31) 12743 * positive, Medford - 0-31)
12096 */ 12744 */
12097#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_EDFE_TAP2 0x3 12745#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_EDFE_TAP2 0x3
12098/* enum: Edge DFE Tap3 (Huntington - 0 - max negative, 32 - zero, 63 - max 12746/* enum: Edge DFE Tap3 (Huntington - 0 - max negative, 32 - zero, 63 - max
12099 * positive, Medford - 0-16) 12747 * positive, Medford - 0-16)
12100 */ 12748 */
12101#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_EDFE_TAP3 0x4 12749#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_EDFE_TAP3 0x4
12102/* enum: Edge DFE Tap4 (Huntington - 0 - max negative, 32 - zero, 63 - max 12750/* enum: Edge DFE Tap4 (Huntington - 0 - max negative, 32 - zero, 63 - max
12103 * positive, Medford - 0-16) 12751 * positive, Medford - 0-16)
12104 */ 12752 */
12105#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_EDFE_TAP4 0x5 12753#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_EDFE_TAP4 0x5
12106/* enum: Edge DFE Tap5 (Huntington - 0 - max negative, 32 - zero, 63 - max 12754/* enum: Edge DFE Tap5 (Huntington - 0 - max negative, 32 - zero, 63 - max
12107 * positive, Medford - 0-16) 12755 * positive, Medford - 0-16)
12108 */ 12756 */
12109#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_EDFE_TAP5 0x6 12757#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_EDFE_TAP5 0x6
12110/* enum: Edge DFE DLEV (0-128 for Medford) */ 12758/* enum: Edge DFE DLEV (0-128 for Medford) */
12111#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_EDFE_DLEV 0x7 12759#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_EDFE_DLEV 0x7
12112/* enum: Variable Gain Amplifier (0-15, Medford) */ 12760/* enum: Variable Gain Amplifier (0-15, Medford) */
12113#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_VGA 0x8 12761#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_VGA 0x8
12114/* enum: CTLE EQ Capacitor (0-15, Medford) */ 12762/* enum: CTLE EQ Capacitor (0-15, Medford) */
12115#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_CTLE_EQC 0x9 12763#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_CTLE_EQC 0x9
12116/* enum: CTLE EQ Resistor (0-7, Medford) */ 12764/* enum: CTLE EQ Resistor (0-7, Medford) */
12117#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_CTLE_EQRES 0xa 12765#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_CTLE_EQRES 0xa
12118/* enum: CTLE gain (0-31, Medford2) */ 12766/* enum: CTLE gain (0-31, Medford2) */
12119#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_CTLE_GAIN 0xb 12767#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_CTLE_GAIN 0xb
12120/* enum: CTLE pole (0-31, Medford2) */ 12768/* enum: CTLE pole (0-31, Medford2) */
12121#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_CTLE_POLE 0xc 12769#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_CTLE_POLE 0xc
12122/* enum: CTLE peaking (0-31, Medford2) */ 12770/* enum: CTLE peaking (0-31, Medford2) */
12123#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_CTLE_PEAK 0xd 12771#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_CTLE_PEAK 0xd
12124/* enum: DFE Tap1 - even path (Medford2 - 6 bit signed (-29 - +29)) */ 12772/* enum: DFE Tap1 - even path (Medford2 - 6 bit signed (-29 - +29)) */
12125#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP1_EVEN 0xe 12773#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP1_EVEN 0xe
12126/* enum: DFE Tap1 - odd path (Medford2 - 6 bit signed (-29 - +29)) */ 12774/* enum: DFE Tap1 - odd path (Medford2 - 6 bit signed (-29 - +29)) */
12127#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP1_ODD 0xf 12775#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP1_ODD 0xf
12128/* enum: DFE Tap2 (Medford2 - 6 bit signed (-20 - +20)) */ 12776/* enum: DFE Tap2 (Medford2 - 6 bit signed (-20 - +20)) */
12129#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP2 0x10 12777#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP2 0x10
12130/* enum: DFE Tap3 (Medford2 - 6 bit signed (-20 - +20)) */ 12778/* enum: DFE Tap3 (Medford2 - 6 bit signed (-20 - +20)) */
12131#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP3 0x11 12779#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP3 0x11
12132/* enum: DFE Tap4 (Medford2 - 6 bit signed (-20 - +20)) */ 12780/* enum: DFE Tap4 (Medford2 - 6 bit signed (-20 - +20)) */
12133#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP4 0x12 12781#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP4 0x12
12134/* enum: DFE Tap5 (Medford2 - 6 bit signed (-24 - +24)) */ 12782/* enum: DFE Tap5 (Medford2 - 6 bit signed (-24 - +24)) */
12135#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP5 0x13 12783#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP5 0x13
12136/* enum: DFE Tap6 (Medford2 - 6 bit signed (-24 - +24)) */ 12784/* enum: DFE Tap6 (Medford2 - 6 bit signed (-24 - +24)) */
12137#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP6 0x14 12785#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP6 0x14
12138/* enum: DFE Tap7 (Medford2 - 6 bit signed (-24 - +24)) */ 12786/* enum: DFE Tap7 (Medford2 - 6 bit signed (-24 - +24)) */
12139#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP7 0x15 12787#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP7 0x15
12140/* enum: DFE Tap8 (Medford2 - 6 bit signed (-24 - +24)) */ 12788/* enum: DFE Tap8 (Medford2 - 6 bit signed (-24 - +24)) */
12141#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP8 0x16 12789#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP8 0x16
12142/* enum: DFE Tap9 (Medford2 - 6 bit signed (-24 - +24)) */ 12790/* enum: DFE Tap9 (Medford2 - 6 bit signed (-24 - +24)) */
12143#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP9 0x17 12791#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP9 0x17
12144/* enum: DFE Tap10 (Medford2 - 6 bit signed (-24 - +24)) */ 12792/* enum: DFE Tap10 (Medford2 - 6 bit signed (-24 - +24)) */
12145#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP10 0x18 12793#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP10 0x18
12146/* enum: DFE Tap11 (Medford2 - 6 bit signed (-24 - +24)) */ 12794/* enum: DFE Tap11 (Medford2 - 6 bit signed (-24 - +24)) */
12147#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP11 0x19 12795#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP11 0x19
12148/* enum: DFE Tap12 (Medford2 - 6 bit signed (-24 - +24)) */ 12796/* enum: DFE Tap12 (Medford2 - 6 bit signed (-24 - +24)) */
12149#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP12 0x1a 12797#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP12 0x1a
12150/* enum: I/Q clk offset (Medford2 - 4 bit signed (-5 - +5))) */ 12798/* enum: I/Q clk offset (Medford2 - 4 bit signed (-5 - +5))) */
12151#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_IQ_OFF 0x1b 12799#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_IQ_OFF 0x1b
12152/* enum: Negative h1 polarity data sampler offset calibration code, even path 12800/* enum: Negative h1 polarity data sampler offset calibration code, even path
12153 * (Medford2 - 6 bit signed (-29 - +29))) 12801 * (Medford2 - 6 bit signed (-29 - +29)))
12154 */ 12802 */
12155#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_H1N_OFF_EVEN 0x1c 12803#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_H1N_OFF_EVEN 0x1c
12156/* enum: Negative h1 polarity data sampler offset calibration code, odd path 12804/* enum: Negative h1 polarity data sampler offset calibration code, odd path
12157 * (Medford2 - 6 bit signed (-29 - +29))) 12805 * (Medford2 - 6 bit signed (-29 - +29)))
12158 */ 12806 */
12159#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_H1N_OFF_ODD 0x1d 12807#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_H1N_OFF_ODD 0x1d
12160/* enum: Positive h1 polarity data sampler offset calibration code, even path 12808/* enum: Positive h1 polarity data sampler offset calibration code, even path
12161 * (Medford2 - 6 bit signed (-29 - +29))) 12809 * (Medford2 - 6 bit signed (-29 - +29)))
12162 */ 12810 */
12163#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_H1P_OFF_EVEN 0x1e 12811#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_H1P_OFF_EVEN 0x1e
12164/* enum: Positive h1 polarity data sampler offset calibration code, odd path 12812/* enum: Positive h1 polarity data sampler offset calibration code, odd path
12165 * (Medford2 - 6 bit signed (-29 - +29))) 12813 * (Medford2 - 6 bit signed (-29 - +29)))
12166 */ 12814 */
12167#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_H1P_OFF_ODD 0x1f 12815#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_H1P_OFF_ODD 0x1f
12168/* enum: CDR calibration loop code (Medford2) */ 12816/* enum: CDR calibration loop code (Medford2) */
12169#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_CDR_PVT 0x20 12817#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_CDR_PVT 0x20
12170/* enum: CDR integral loop code (Medford2) */ 12818/* enum: CDR integral loop code (Medford2) */
12171#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_CDR_INTEG 0x21 12819#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_CDR_INTEG 0x21
12172#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_LANE_LBN 8 12820#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_LANE_LBN 8
12173#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_LANE_WIDTH 3 12821#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_LANE_WIDTH 3
12174#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_LANE_0 0x0 /* enum */ 12822#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_LANE_0 0x0 /* enum */
12175#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_LANE_1 0x1 /* enum */ 12823#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_LANE_1 0x1 /* enum */
12176#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_LANE_2 0x2 /* enum */ 12824#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_LANE_2 0x2 /* enum */
12177#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_LANE_3 0x3 /* enum */ 12825#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_LANE_3 0x3 /* enum */
12178#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_LANE_ALL 0x4 /* enum */ 12826#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_LANE_ALL 0x4 /* enum */
12179#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_AUTOCAL_LBN 11 12827#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_AUTOCAL_LBN 11
12180#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_AUTOCAL_WIDTH 1 12828#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_AUTOCAL_WIDTH 1
12181#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_RESERVED_LBN 12 12829#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_RESERVED_LBN 12
@@ -12241,38 +12889,38 @@
12241#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_ID_LBN 0 12889#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_ID_LBN 0
12242#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_ID_WIDTH 8 12890#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_ID_WIDTH 8
12243/* enum: TX Amplitude (Huntington, Medford, Medford2) */ 12891/* enum: TX Amplitude (Huntington, Medford, Medford2) */
12244#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_LEV 0x0 12892#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_LEV 0x0
12245/* enum: De-Emphasis Tap1 Magnitude (0-7) (Huntington) */ 12893/* enum: De-Emphasis Tap1 Magnitude (0-7) (Huntington) */
12246#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_MODE 0x1 12894#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_MODE 0x1
12247/* enum: De-Emphasis Tap1 Fine */ 12895/* enum: De-Emphasis Tap1 Fine */
12248#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_DTLEV 0x2 12896#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_DTLEV 0x2
12249/* enum: De-Emphasis Tap2 Magnitude (0-6) (Huntington) */ 12897/* enum: De-Emphasis Tap2 Magnitude (0-6) (Huntington) */
12250#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_D2 0x3 12898#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_D2 0x3
12251/* enum: De-Emphasis Tap2 Fine (Huntington) */ 12899/* enum: De-Emphasis Tap2 Fine (Huntington) */
12252#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_D2TLEV 0x4 12900#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_D2TLEV 0x4
12253/* enum: Pre-Emphasis Magnitude (Huntington) */ 12901/* enum: Pre-Emphasis Magnitude (Huntington) */
12254#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_E 0x5 12902#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_E 0x5
12255/* enum: Pre-Emphasis Fine (Huntington) */ 12903/* enum: Pre-Emphasis Fine (Huntington) */
12256#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_ETLEV 0x6 12904#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_ETLEV 0x6
12257/* enum: TX Slew Rate Coarse control (Huntington) */ 12905/* enum: TX Slew Rate Coarse control (Huntington) */
12258#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_PREDRV_DLY 0x7 12906#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_PREDRV_DLY 0x7
12259/* enum: TX Slew Rate Fine control (Huntington) */ 12907/* enum: TX Slew Rate Fine control (Huntington) */
12260#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_SR_SET 0x8 12908#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_SR_SET 0x8
12261/* enum: TX Termination Impedance control (Huntington) */ 12909/* enum: TX Termination Impedance control (Huntington) */
12262#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_RT_SET 0x9 12910#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_RT_SET 0x9
12263/* enum: TX Amplitude Fine control (Medford) */ 12911/* enum: TX Amplitude Fine control (Medford) */
12264#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_LEV_FINE 0xa 12912#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_LEV_FINE 0xa
12265/* enum: Pre-shoot Tap (Medford, Medford2) */ 12913/* enum: Pre-shoot Tap (Medford, Medford2) */
12266#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TAP_ADV 0xb 12914#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TAP_ADV 0xb
12267/* enum: De-emphasis Tap (Medford, Medford2) */ 12915/* enum: De-emphasis Tap (Medford, Medford2) */
12268#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TAP_DLY 0xc 12916#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TAP_DLY 0xc
12269#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_LANE_LBN 8 12917#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_LANE_LBN 8
12270#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_LANE_WIDTH 3 12918#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_LANE_WIDTH 3
12271#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LANE_0 0x0 /* enum */ 12919#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LANE_0 0x0 /* enum */
12272#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LANE_1 0x1 /* enum */ 12920#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LANE_1 0x1 /* enum */
12273#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LANE_2 0x2 /* enum */ 12921#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LANE_2 0x2 /* enum */
12274#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LANE_3 0x3 /* enum */ 12922#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LANE_3 0x3 /* enum */
12275#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LANE_ALL 0x4 /* enum */ 12923#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LANE_ALL 0x4 /* enum */
12276#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_RESERVED_LBN 11 12924#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_RESERVED_LBN 11
12277#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_RESERVED_WIDTH 5 12925#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_RESERVED_WIDTH 5
12278#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_INITIAL_LBN 16 12926#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_INITIAL_LBN 16
@@ -12345,9 +12993,12 @@
12345/* Align the arguments to 32 bits */ 12993/* Align the arguments to 32 bits */
12346#define MC_CMD_KR_TUNE_START_EYE_PLOT_V2_IN_KR_TUNE_RSVD_OFST 1 12994#define MC_CMD_KR_TUNE_START_EYE_PLOT_V2_IN_KR_TUNE_RSVD_OFST 1
12347#define MC_CMD_KR_TUNE_START_EYE_PLOT_V2_IN_KR_TUNE_RSVD_LEN 3 12995#define MC_CMD_KR_TUNE_START_EYE_PLOT_V2_IN_KR_TUNE_RSVD_LEN 3
12348/* Port-relative lane to scan eye on */
12349#define MC_CMD_KR_TUNE_START_EYE_PLOT_V2_IN_LANE_OFST 4 12996#define MC_CMD_KR_TUNE_START_EYE_PLOT_V2_IN_LANE_OFST 4
12350#define MC_CMD_KR_TUNE_START_EYE_PLOT_V2_IN_LANE_LEN 4 12997#define MC_CMD_KR_TUNE_START_EYE_PLOT_V2_IN_LANE_LEN 4
12998#define MC_CMD_KR_TUNE_START_EYE_PLOT_V2_IN_LANE_NUM_LBN 0
12999#define MC_CMD_KR_TUNE_START_EYE_PLOT_V2_IN_LANE_NUM_WIDTH 8
13000#define MC_CMD_KR_TUNE_START_EYE_PLOT_V2_IN_LANE_ABS_REL_LBN 31
13001#define MC_CMD_KR_TUNE_START_EYE_PLOT_V2_IN_LANE_ABS_REL_WIDTH 1
12351/* Scan duration / cycle count */ 13002/* Scan duration / cycle count */
12352#define MC_CMD_KR_TUNE_START_EYE_PLOT_V2_IN_BER_OFST 8 13003#define MC_CMD_KR_TUNE_START_EYE_PLOT_V2_IN_BER_OFST 8
12353#define MC_CMD_KR_TUNE_START_EYE_PLOT_V2_IN_BER_LEN 4 13004#define MC_CMD_KR_TUNE_START_EYE_PLOT_V2_IN_BER_LEN 4
@@ -12383,12 +13034,91 @@
12383#define MC_CMD_KR_TUNE_READ_FOM_IN_KR_TUNE_RSVD_LEN 3 13034#define MC_CMD_KR_TUNE_READ_FOM_IN_KR_TUNE_RSVD_LEN 3
12384#define MC_CMD_KR_TUNE_READ_FOM_IN_LANE_OFST 4 13035#define MC_CMD_KR_TUNE_READ_FOM_IN_LANE_OFST 4
12385#define MC_CMD_KR_TUNE_READ_FOM_IN_LANE_LEN 4 13036#define MC_CMD_KR_TUNE_READ_FOM_IN_LANE_LEN 4
13037#define MC_CMD_KR_TUNE_READ_FOM_IN_LANE_NUM_LBN 0
13038#define MC_CMD_KR_TUNE_READ_FOM_IN_LANE_NUM_WIDTH 8
13039#define MC_CMD_KR_TUNE_READ_FOM_IN_LANE_ABS_REL_LBN 31
13040#define MC_CMD_KR_TUNE_READ_FOM_IN_LANE_ABS_REL_WIDTH 1
12386 13041
12387/* MC_CMD_KR_TUNE_READ_FOM_OUT msgresponse */ 13042/* MC_CMD_KR_TUNE_READ_FOM_OUT msgresponse */
12388#define MC_CMD_KR_TUNE_READ_FOM_OUT_LEN 4 13043#define MC_CMD_KR_TUNE_READ_FOM_OUT_LEN 4
12389#define MC_CMD_KR_TUNE_READ_FOM_OUT_FOM_OFST 0 13044#define MC_CMD_KR_TUNE_READ_FOM_OUT_FOM_OFST 0
12390#define MC_CMD_KR_TUNE_READ_FOM_OUT_FOM_LEN 4 13045#define MC_CMD_KR_TUNE_READ_FOM_OUT_FOM_LEN 4
12391 13046
13047/* MC_CMD_KR_TUNE_LINK_TRAIN_RUN_IN msgrequest */
13048#define MC_CMD_KR_TUNE_LINK_TRAIN_RUN_IN_LEN 8
13049/* Requested operation */
13050#define MC_CMD_KR_TUNE_LINK_TRAIN_RUN_IN_KR_TUNE_OP_OFST 0
13051#define MC_CMD_KR_TUNE_LINK_TRAIN_RUN_IN_KR_TUNE_OP_LEN 1
13052/* Align the arguments to 32 bits */
13053#define MC_CMD_KR_TUNE_LINK_TRAIN_RUN_IN_KR_TUNE_RSVD_OFST 1
13054#define MC_CMD_KR_TUNE_LINK_TRAIN_RUN_IN_KR_TUNE_RSVD_LEN 3
13055#define MC_CMD_KR_TUNE_LINK_TRAIN_RUN_IN_RUN_OFST 4
13056#define MC_CMD_KR_TUNE_LINK_TRAIN_RUN_IN_RUN_LEN 4
13057#define MC_CMD_KR_TUNE_LINK_TRAIN_RUN_IN_STOP 0x0 /* enum */
13058#define MC_CMD_KR_TUNE_LINK_TRAIN_RUN_IN_START 0x1 /* enum */
13059
13060/* MC_CMD_KR_TUNE_LINK_TRAIN_CMD_IN msgrequest */
13061#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_IN_LEN 28
13062/* Requested operation */
13063#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_IN_KR_TUNE_OP_OFST 0
13064#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_IN_KR_TUNE_OP_LEN 1
13065/* Align the arguments to 32 bits */
13066#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_IN_KR_TUNE_RSVD_OFST 1
13067#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_IN_KR_TUNE_RSVD_LEN 3
13068#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_IN_LANE_OFST 4
13069#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_IN_LANE_LEN 4
13070/* Set INITIALIZE state */
13071#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_IN_INITIALIZE_OFST 8
13072#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_IN_INITIALIZE_LEN 4
13073/* Set PRESET state */
13074#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_IN_PRESET_OFST 12
13075#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_IN_PRESET_LEN 4
13076/* C(-1) request */
13077#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_IN_CM1_OFST 16
13078#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_IN_CM1_LEN 4
13079#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_IN_REQ_HOLD 0x0 /* enum */
13080#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_IN_REQ_INCREMENT 0x1 /* enum */
13081#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_IN_REQ_DECREMENT 0x2 /* enum */
13082/* C(0) request */
13083#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_IN_C0_OFST 20
13084#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_IN_C0_LEN 4
13085/* Enum values, see field(s): */
13086/* MC_CMD_KR_TUNE_LINK_TRAIN_CMD_IN/CM1 */
13087/* C(+1) request */
13088#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_IN_CP1_OFST 24
13089#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_IN_CP1_LEN 4
13090/* Enum values, see field(s): */
13091/* MC_CMD_KR_TUNE_LINK_TRAIN_CMD_IN/CM1 */
13092
13093/* MC_CMD_KR_TUNE_LINK_TRAIN_CMD_OUT msgresponse */
13094#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_OUT_LEN 24
13095/* C(-1) status */
13096#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_OUT_CM1_STATUS_OFST 0
13097#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_OUT_CM1_STATUS_LEN 4
13098#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_OUT_STATUS_NOT_UPDATED 0x0 /* enum */
13099#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_OUT_STATUS_UPDATED 0x1 /* enum */
13100#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_OUT_STATUS_MINIMUM 0x2 /* enum */
13101#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_OUT_STATUS_MAXIMUM 0x3 /* enum */
13102/* C(0) status */
13103#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_OUT_C0_STATUS_OFST 4
13104#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_OUT_C0_STATUS_LEN 4
13105/* Enum values, see field(s): */
13106/* MC_CMD_KR_TUNE_LINK_TRAIN_CMD_IN/CM1 */
13107/* C(+1) status */
13108#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_OUT_CP1_STATUS_OFST 8
13109#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_OUT_CP1_STATUS_LEN 4
13110/* Enum values, see field(s): */
13111/* MC_CMD_KR_TUNE_LINK_TRAIN_CMD_IN/CM1 */
13112/* C(-1) value */
13113#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_OUT_CM1_VALUE_OFST 12
13114#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_OUT_CM1_VALUE_LEN 4
13115/* C(0) value */
13116#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_OUT_C0_VALUE_OFST 16
13117#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_OUT_C0_VALUE_LEN 4
13118/* C(+1) status */
13119#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_OUT_CP1_VALUE_OFST 20
13120#define MC_CMD_KR_TUNE_LINK_TRAIN_CMD_OUT_CP1_VALUE_LEN 4
13121
12392 13122
12393/***********************************/ 13123/***********************************/
12394/* MC_CMD_PCIE_TUNE 13124/* MC_CMD_PCIE_TUNE
@@ -12406,22 +13136,22 @@
12406#define MC_CMD_PCIE_TUNE_IN_PCIE_TUNE_OP_OFST 0 13136#define MC_CMD_PCIE_TUNE_IN_PCIE_TUNE_OP_OFST 0
12407#define MC_CMD_PCIE_TUNE_IN_PCIE_TUNE_OP_LEN 1 13137#define MC_CMD_PCIE_TUNE_IN_PCIE_TUNE_OP_LEN 1
12408/* enum: Get current RXEQ settings */ 13138/* enum: Get current RXEQ settings */
12409#define MC_CMD_PCIE_TUNE_IN_RXEQ_GET 0x0 13139#define MC_CMD_PCIE_TUNE_IN_RXEQ_GET 0x0
12410/* enum: Override RXEQ settings */ 13140/* enum: Override RXEQ settings */
12411#define MC_CMD_PCIE_TUNE_IN_RXEQ_SET 0x1 13141#define MC_CMD_PCIE_TUNE_IN_RXEQ_SET 0x1
12412/* enum: Get current TX Driver settings */ 13142/* enum: Get current TX Driver settings */
12413#define MC_CMD_PCIE_TUNE_IN_TXEQ_GET 0x2 13143#define MC_CMD_PCIE_TUNE_IN_TXEQ_GET 0x2
12414/* enum: Override TX Driver settings */ 13144/* enum: Override TX Driver settings */
12415#define MC_CMD_PCIE_TUNE_IN_TXEQ_SET 0x3 13145#define MC_CMD_PCIE_TUNE_IN_TXEQ_SET 0x3
12416/* enum: Start PCIe Serdes Eye diagram plot on a given lane. */ 13146/* enum: Start PCIe Serdes Eye diagram plot on a given lane. */
12417#define MC_CMD_PCIE_TUNE_IN_START_EYE_PLOT 0x5 13147#define MC_CMD_PCIE_TUNE_IN_START_EYE_PLOT 0x5
12418/* enum: Poll PCIe Serdes Eye diagram plot. Returns one row of BER data. The 13148/* enum: Poll PCIe Serdes Eye diagram plot. Returns one row of BER data. The
12419 * caller should call this command repeatedly after starting eye plot, until no 13149 * caller should call this command repeatedly after starting eye plot, until no
12420 * more data is returned. 13150 * more data is returned.
12421 */ 13151 */
12422#define MC_CMD_PCIE_TUNE_IN_POLL_EYE_PLOT 0x6 13152#define MC_CMD_PCIE_TUNE_IN_POLL_EYE_PLOT 0x6
12423/* enum: Enable the SERDES BIST and set it to generate a 200MHz square wave */ 13153/* enum: Enable the SERDES BIST and set it to generate a 200MHz square wave */
12424#define MC_CMD_PCIE_TUNE_IN_BIST_SQUARE_WAVE 0x7 13154#define MC_CMD_PCIE_TUNE_IN_BIST_SQUARE_WAVE 0x7
12425/* Align the arguments to 32 bits */ 13155/* Align the arguments to 32 bits */
12426#define MC_CMD_PCIE_TUNE_IN_PCIE_TUNE_RSVD_OFST 1 13156#define MC_CMD_PCIE_TUNE_IN_PCIE_TUNE_RSVD_OFST 1
12427#define MC_CMD_PCIE_TUNE_IN_PCIE_TUNE_RSVD_LEN 3 13157#define MC_CMD_PCIE_TUNE_IN_PCIE_TUNE_RSVD_LEN 3
@@ -12455,46 +13185,46 @@
12455#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_ID_LBN 0 13185#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_ID_LBN 0
12456#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_ID_WIDTH 8 13186#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_ID_WIDTH 8
12457/* enum: Attenuation (0-15) */ 13187/* enum: Attenuation (0-15) */
12458#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_ATT 0x0 13188#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_ATT 0x0
12459/* enum: CTLE Boost (0-15) */ 13189/* enum: CTLE Boost (0-15) */
12460#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_BOOST 0x1 13190#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_BOOST 0x1
12461/* enum: DFE Tap1 (0 - max negative, 64 - zero, 127 - max positive) */ 13191/* enum: DFE Tap1 (0 - max negative, 64 - zero, 127 - max positive) */
12462#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_DFE_TAP1 0x2 13192#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_DFE_TAP1 0x2
12463/* enum: DFE Tap2 (0 - max negative, 32 - zero, 63 - max positive) */ 13193/* enum: DFE Tap2 (0 - max negative, 32 - zero, 63 - max positive) */
12464#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_DFE_TAP2 0x3 13194#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_DFE_TAP2 0x3
12465/* enum: DFE Tap3 (0 - max negative, 32 - zero, 63 - max positive) */ 13195/* enum: DFE Tap3 (0 - max negative, 32 - zero, 63 - max positive) */
12466#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_DFE_TAP3 0x4 13196#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_DFE_TAP3 0x4
12467/* enum: DFE Tap4 (0 - max negative, 32 - zero, 63 - max positive) */ 13197/* enum: DFE Tap4 (0 - max negative, 32 - zero, 63 - max positive) */
12468#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_DFE_TAP4 0x5 13198#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_DFE_TAP4 0x5
12469/* enum: DFE Tap5 (0 - max negative, 32 - zero, 63 - max positive) */ 13199/* enum: DFE Tap5 (0 - max negative, 32 - zero, 63 - max positive) */
12470#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_DFE_TAP5 0x6 13200#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_DFE_TAP5 0x6
12471/* enum: DFE DLev */ 13201/* enum: DFE DLev */
12472#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_DFE_DLEV 0x7 13202#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_DFE_DLEV 0x7
12473/* enum: Figure of Merit */ 13203/* enum: Figure of Merit */
12474#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_FOM 0x8 13204#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_FOM 0x8
12475/* enum: CTLE EQ Capacitor (HF Gain) */ 13205/* enum: CTLE EQ Capacitor (HF Gain) */
12476#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_CTLE_EQC 0x9 13206#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_CTLE_EQC 0x9
12477/* enum: CTLE EQ Resistor (DC Gain) */ 13207/* enum: CTLE EQ Resistor (DC Gain) */
12478#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_CTLE_EQRES 0xa 13208#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_CTLE_EQRES 0xa
12479#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_LANE_LBN 8 13209#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_LANE_LBN 8
12480#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_LANE_WIDTH 5 13210#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_LANE_WIDTH 5
12481#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_0 0x0 /* enum */ 13211#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_0 0x0 /* enum */
12482#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_1 0x1 /* enum */ 13212#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_1 0x1 /* enum */
12483#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_2 0x2 /* enum */ 13213#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_2 0x2 /* enum */
12484#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_3 0x3 /* enum */ 13214#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_3 0x3 /* enum */
12485#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_4 0x4 /* enum */ 13215#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_4 0x4 /* enum */
12486#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_5 0x5 /* enum */ 13216#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_5 0x5 /* enum */
12487#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_6 0x6 /* enum */ 13217#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_6 0x6 /* enum */
12488#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_7 0x7 /* enum */ 13218#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_7 0x7 /* enum */
12489#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_8 0x8 /* enum */ 13219#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_8 0x8 /* enum */
12490#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_9 0x9 /* enum */ 13220#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_9 0x9 /* enum */
12491#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_10 0xa /* enum */ 13221#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_10 0xa /* enum */
12492#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_11 0xb /* enum */ 13222#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_11 0xb /* enum */
12493#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_12 0xc /* enum */ 13223#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_12 0xc /* enum */
12494#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_13 0xd /* enum */ 13224#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_13 0xd /* enum */
12495#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_14 0xe /* enum */ 13225#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_14 0xe /* enum */
12496#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_15 0xf /* enum */ 13226#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_15 0xf /* enum */
12497#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_ALL 0x10 /* enum */ 13227#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_ALL 0x10 /* enum */
12498#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_AUTOCAL_LBN 13 13228#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_AUTOCAL_LBN 13
12499#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_AUTOCAL_WIDTH 1 13229#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_AUTOCAL_WIDTH 1
12500#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_RESERVED_LBN 14 13230#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_RESERVED_LBN 14
@@ -12558,15 +13288,15 @@
12558#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_ID_LBN 0 13288#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_ID_LBN 0
12559#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_ID_WIDTH 8 13289#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_ID_WIDTH 8
12560/* enum: TxMargin (PIPE) */ 13290/* enum: TxMargin (PIPE) */
12561#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_TXMARGIN 0x0 13291#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_TXMARGIN 0x0
12562/* enum: TxSwing (PIPE) */ 13292/* enum: TxSwing (PIPE) */
12563#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_TXSWING 0x1 13293#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_TXSWING 0x1
12564/* enum: De-emphasis coefficient C(-1) (PIPE) */ 13294/* enum: De-emphasis coefficient C(-1) (PIPE) */
12565#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_CM1 0x2 13295#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_CM1 0x2
12566/* enum: De-emphasis coefficient C(0) (PIPE) */ 13296/* enum: De-emphasis coefficient C(0) (PIPE) */
12567#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_C0 0x3 13297#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_C0 0x3
12568/* enum: De-emphasis coefficient C(+1) (PIPE) */ 13298/* enum: De-emphasis coefficient C(+1) (PIPE) */
12569#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_CP1 0x4 13299#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_CP1 0x4
12570#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_LANE_LBN 8 13300#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_LANE_LBN 8
12571#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_LANE_WIDTH 4 13301#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_LANE_WIDTH 4
12572/* Enum values, see field(s): */ 13302/* Enum values, see field(s): */
@@ -12632,9 +13362,9 @@
12632/* enum: re-read and apply licenses after a license key partition update; note 13362/* enum: re-read and apply licenses after a license key partition update; note
12633 * that this operation returns a zero-length response 13363 * that this operation returns a zero-length response
12634 */ 13364 */
12635#define MC_CMD_LICENSING_IN_OP_UPDATE_LICENSE 0x0 13365#define MC_CMD_LICENSING_IN_OP_UPDATE_LICENSE 0x0
12636/* enum: report counts of installed licenses */ 13366/* enum: report counts of installed licenses */
12637#define MC_CMD_LICENSING_IN_OP_GET_KEY_STATS 0x1 13367#define MC_CMD_LICENSING_IN_OP_GET_KEY_STATS 0x1
12638 13368
12639/* MC_CMD_LICENSING_OUT msgresponse */ 13369/* MC_CMD_LICENSING_OUT msgresponse */
12640#define MC_CMD_LICENSING_OUT_LEN 28 13370#define MC_CMD_LICENSING_OUT_LEN 28
@@ -12665,9 +13395,9 @@
12665#define MC_CMD_LICENSING_OUT_LICENSING_SELF_TEST_OFST 24 13395#define MC_CMD_LICENSING_OUT_LICENSING_SELF_TEST_OFST 24
12666#define MC_CMD_LICENSING_OUT_LICENSING_SELF_TEST_LEN 4 13396#define MC_CMD_LICENSING_OUT_LICENSING_SELF_TEST_LEN 4
12667/* enum: licensing subsystem self-test failed */ 13397/* enum: licensing subsystem self-test failed */
12668#define MC_CMD_LICENSING_OUT_SELF_TEST_FAIL 0x0 13398#define MC_CMD_LICENSING_OUT_SELF_TEST_FAIL 0x0
12669/* enum: licensing subsystem self-test passed */ 13399/* enum: licensing subsystem self-test passed */
12670#define MC_CMD_LICENSING_OUT_SELF_TEST_PASS 0x1 13400#define MC_CMD_LICENSING_OUT_SELF_TEST_PASS 0x1
12671 13401
12672 13402
12673/***********************************/ 13403/***********************************/
@@ -12687,11 +13417,11 @@
12687/* enum: re-read and apply licenses after a license key partition update; note 13417/* enum: re-read and apply licenses after a license key partition update; note
12688 * that this operation returns a zero-length response 13418 * that this operation returns a zero-length response
12689 */ 13419 */
12690#define MC_CMD_LICENSING_V3_IN_OP_UPDATE_LICENSE 0x0 13420#define MC_CMD_LICENSING_V3_IN_OP_UPDATE_LICENSE 0x0
12691/* enum: report counts of installed licenses Returns EAGAIN if license 13421/* enum: report counts of installed licenses Returns EAGAIN if license
12692 * processing (updating) has been started but not yet completed. 13422 * processing (updating) has been started but not yet completed.
12693 */ 13423 */
12694#define MC_CMD_LICENSING_V3_IN_OP_REPORT_LICENSE 0x1 13424#define MC_CMD_LICENSING_V3_IN_OP_REPORT_LICENSE 0x1
12695 13425
12696/* MC_CMD_LICENSING_V3_OUT msgresponse */ 13426/* MC_CMD_LICENSING_V3_OUT msgresponse */
12697#define MC_CMD_LICENSING_V3_OUT_LEN 88 13427#define MC_CMD_LICENSING_V3_OUT_LEN 88
@@ -12718,9 +13448,9 @@
12718#define MC_CMD_LICENSING_V3_OUT_LICENSING_SELF_TEST_OFST 20 13448#define MC_CMD_LICENSING_V3_OUT_LICENSING_SELF_TEST_OFST 20
12719#define MC_CMD_LICENSING_V3_OUT_LICENSING_SELF_TEST_LEN 4 13449#define MC_CMD_LICENSING_V3_OUT_LICENSING_SELF_TEST_LEN 4
12720/* enum: licensing subsystem self-test failed */ 13450/* enum: licensing subsystem self-test failed */
12721#define MC_CMD_LICENSING_V3_OUT_SELF_TEST_FAIL 0x0 13451#define MC_CMD_LICENSING_V3_OUT_SELF_TEST_FAIL 0x0
12722/* enum: licensing subsystem self-test passed */ 13452/* enum: licensing subsystem self-test passed */
12723#define MC_CMD_LICENSING_V3_OUT_SELF_TEST_PASS 0x1 13453#define MC_CMD_LICENSING_V3_OUT_SELF_TEST_PASS 0x1
12724/* bitmask of licensed applications */ 13454/* bitmask of licensed applications */
12725#define MC_CMD_LICENSING_V3_OUT_LICENSED_APPS_OFST 24 13455#define MC_CMD_LICENSING_V3_OUT_LICENSED_APPS_OFST 24
12726#define MC_CMD_LICENSING_V3_OUT_LICENSED_APPS_LEN 8 13456#define MC_CMD_LICENSING_V3_OUT_LICENSED_APPS_LEN 8
@@ -12806,9 +13536,9 @@
12806#define MC_CMD_GET_LICENSED_APP_STATE_OUT_STATE_OFST 0 13536#define MC_CMD_GET_LICENSED_APP_STATE_OUT_STATE_OFST 0
12807#define MC_CMD_GET_LICENSED_APP_STATE_OUT_STATE_LEN 4 13537#define MC_CMD_GET_LICENSED_APP_STATE_OUT_STATE_LEN 4
12808/* enum: no (or invalid) license is present for the application */ 13538/* enum: no (or invalid) license is present for the application */
12809#define MC_CMD_GET_LICENSED_APP_STATE_OUT_NOT_LICENSED 0x0 13539#define MC_CMD_GET_LICENSED_APP_STATE_OUT_NOT_LICENSED 0x0
12810/* enum: a valid license is present for the application */ 13540/* enum: a valid license is present for the application */
12811#define MC_CMD_GET_LICENSED_APP_STATE_OUT_LICENSED 0x1 13541#define MC_CMD_GET_LICENSED_APP_STATE_OUT_LICENSED 0x1
12812 13542
12813 13543
12814/***********************************/ 13544/***********************************/
@@ -12837,9 +13567,9 @@
12837#define MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_STATE_OFST 0 13567#define MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_STATE_OFST 0
12838#define MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_STATE_LEN 4 13568#define MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_STATE_LEN 4
12839/* enum: no (or invalid) license is present for the application */ 13569/* enum: no (or invalid) license is present for the application */
12840#define MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_NOT_LICENSED 0x0 13570#define MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_NOT_LICENSED 0x0
12841/* enum: a valid license is present for the application */ 13571/* enum: a valid license is present for the application */
12842#define MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LICENSED 0x1 13572#define MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LICENSED 0x1
12843 13573
12844 13574
12845/***********************************/ 13575/***********************************/
@@ -12891,9 +13621,9 @@
12891#define MC_CMD_LICENSED_APP_OP_IN_OP_OFST 4 13621#define MC_CMD_LICENSED_APP_OP_IN_OP_OFST 4
12892#define MC_CMD_LICENSED_APP_OP_IN_OP_LEN 4 13622#define MC_CMD_LICENSED_APP_OP_IN_OP_LEN 4
12893/* enum: validate application */ 13623/* enum: validate application */
12894#define MC_CMD_LICENSED_APP_OP_IN_OP_VALIDATE 0x0 13624#define MC_CMD_LICENSED_APP_OP_IN_OP_VALIDATE 0x0
12895/* enum: mask application */ 13625/* enum: mask application */
12896#define MC_CMD_LICENSED_APP_OP_IN_OP_MASK 0x1 13626#define MC_CMD_LICENSED_APP_OP_IN_OP_MASK 0x1
12897/* arguments specific to this particular operation */ 13627/* arguments specific to this particular operation */
12898#define MC_CMD_LICENSED_APP_OP_IN_ARGS_OFST 8 13628#define MC_CMD_LICENSED_APP_OP_IN_ARGS_OFST 8
12899#define MC_CMD_LICENSED_APP_OP_IN_ARGS_LEN 4 13629#define MC_CMD_LICENSED_APP_OP_IN_ARGS_LEN 4
@@ -12984,9 +13714,9 @@
12984#define MC_CMD_LICENSED_V3_VALIDATE_APP_OUT_EXPIRY_UNITS_OFST 100 13714#define MC_CMD_LICENSED_V3_VALIDATE_APP_OUT_EXPIRY_UNITS_OFST 100
12985#define MC_CMD_LICENSED_V3_VALIDATE_APP_OUT_EXPIRY_UNITS_LEN 4 13715#define MC_CMD_LICENSED_V3_VALIDATE_APP_OUT_EXPIRY_UNITS_LEN 4
12986/* enum: expiry units are accounting units */ 13716/* enum: expiry units are accounting units */
12987#define MC_CMD_LICENSED_V3_VALIDATE_APP_OUT_EXPIRY_UNIT_ACC 0x0 13717#define MC_CMD_LICENSED_V3_VALIDATE_APP_OUT_EXPIRY_UNIT_ACC 0x0
12988/* enum: expiry units are calendar days */ 13718/* enum: expiry units are calendar days */
12989#define MC_CMD_LICENSED_V3_VALIDATE_APP_OUT_EXPIRY_UNIT_DAYS 0x1 13719#define MC_CMD_LICENSED_V3_VALIDATE_APP_OUT_EXPIRY_UNIT_DAYS 0x1
12990/* base MAC address of the NIC stored in NVRAM (note that this is a constant 13720/* base MAC address of the NIC stored in NVRAM (note that this is a constant
12991 * value for a given NIC regardless which function is calling, effectively this 13721 * value for a given NIC regardless which function is calling, effectively this
12992 * is PF0 base MAC address) 13722 * is PF0 base MAC address)
@@ -13019,9 +13749,9 @@
13019#define MC_CMD_LICENSED_V3_MASK_FEATURES_IN_FLAG_OFST 8 13749#define MC_CMD_LICENSED_V3_MASK_FEATURES_IN_FLAG_OFST 8
13020#define MC_CMD_LICENSED_V3_MASK_FEATURES_IN_FLAG_LEN 4 13750#define MC_CMD_LICENSED_V3_MASK_FEATURES_IN_FLAG_LEN 4
13021/* enum: turn the features off */ 13751/* enum: turn the features off */
13022#define MC_CMD_LICENSED_V3_MASK_FEATURES_IN_OFF 0x0 13752#define MC_CMD_LICENSED_V3_MASK_FEATURES_IN_OFF 0x0
13023/* enum: turn the features back on */ 13753/* enum: turn the features back on */
13024#define MC_CMD_LICENSED_V3_MASK_FEATURES_IN_ON 0x1 13754#define MC_CMD_LICENSED_V3_MASK_FEATURES_IN_ON 0x1
13025 13755
13026/* MC_CMD_LICENSED_V3_MASK_FEATURES_OUT msgresponse */ 13756/* MC_CMD_LICENSED_V3_MASK_FEATURES_OUT msgresponse */
13027#define MC_CMD_LICENSED_V3_MASK_FEATURES_OUT_LEN 0 13757#define MC_CMD_LICENSED_V3_MASK_FEATURES_OUT_LEN 0
@@ -13048,15 +13778,15 @@
13048 * This is an asynchronous operation owing to the time taken to validate an 13778 * This is an asynchronous operation owing to the time taken to validate an
13049 * ECDSA license 13779 * ECDSA license
13050 */ 13780 */
13051#define MC_CMD_LICENSING_V3_TEMPORARY_SET 0x0 13781#define MC_CMD_LICENSING_V3_TEMPORARY_SET 0x0
13052/* enum: clear the license immediately rather than waiting for the next power 13782/* enum: clear the license immediately rather than waiting for the next power
13053 * cycle 13783 * cycle
13054 */ 13784 */
13055#define MC_CMD_LICENSING_V3_TEMPORARY_CLEAR 0x1 13785#define MC_CMD_LICENSING_V3_TEMPORARY_CLEAR 0x1
13056/* enum: get the status of the asynchronous MC_CMD_LICENSING_V3_TEMPORARY_SET 13786/* enum: get the status of the asynchronous MC_CMD_LICENSING_V3_TEMPORARY_SET
13057 * operation 13787 * operation
13058 */ 13788 */
13059#define MC_CMD_LICENSING_V3_TEMPORARY_STATUS 0x2 13789#define MC_CMD_LICENSING_V3_TEMPORARY_STATUS 0x2
13060 13790
13061/* MC_CMD_LICENSING_V3_TEMPORARY_IN_SET msgrequest */ 13791/* MC_CMD_LICENSING_V3_TEMPORARY_IN_SET msgrequest */
13062#define MC_CMD_LICENSING_V3_TEMPORARY_IN_SET_LEN 164 13792#define MC_CMD_LICENSING_V3_TEMPORARY_IN_SET_LEN 164
@@ -13082,13 +13812,13 @@
13082#define MC_CMD_LICENSING_V3_TEMPORARY_OUT_STATUS_STATUS_OFST 0 13812#define MC_CMD_LICENSING_V3_TEMPORARY_OUT_STATUS_STATUS_OFST 0
13083#define MC_CMD_LICENSING_V3_TEMPORARY_OUT_STATUS_STATUS_LEN 4 13813#define MC_CMD_LICENSING_V3_TEMPORARY_OUT_STATUS_STATUS_LEN 4
13084/* enum: finished validating and installing license */ 13814/* enum: finished validating and installing license */
13085#define MC_CMD_LICENSING_V3_TEMPORARY_STATUS_OK 0x0 13815#define MC_CMD_LICENSING_V3_TEMPORARY_STATUS_OK 0x0
13086/* enum: license validation and installation in progress */ 13816/* enum: license validation and installation in progress */
13087#define MC_CMD_LICENSING_V3_TEMPORARY_STATUS_IN_PROGRESS 0x1 13817#define MC_CMD_LICENSING_V3_TEMPORARY_STATUS_IN_PROGRESS 0x1
13088/* enum: licensing error. More specific error messages are not provided to 13818/* enum: licensing error. More specific error messages are not provided to
13089 * avoid exposing details of the licensing system to the client 13819 * avoid exposing details of the licensing system to the client
13090 */ 13820 */
13091#define MC_CMD_LICENSING_V3_TEMPORARY_STATUS_ERROR 0x2 13821#define MC_CMD_LICENSING_V3_TEMPORARY_STATUS_ERROR 0x2
13092/* bitmask of licensed features */ 13822/* bitmask of licensed features */
13093#define MC_CMD_LICENSING_V3_TEMPORARY_OUT_STATUS_LICENSED_FEATURES_OFST 4 13823#define MC_CMD_LICENSING_V3_TEMPORARY_OUT_STATUS_LICENSED_FEATURES_OFST 4
13094#define MC_CMD_LICENSING_V3_TEMPORARY_OUT_STATUS_LICENSED_FEATURES_LEN 8 13824#define MC_CMD_LICENSING_V3_TEMPORARY_OUT_STATUS_LICENSED_FEATURES_LEN 8
@@ -13124,9 +13854,9 @@
13124#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_RX_MODE_OFST 8 13854#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_RX_MODE_OFST 8
13125#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_RX_MODE_LEN 4 13855#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_RX_MODE_LEN 4
13126/* enum: receive to just the specified queue */ 13856/* enum: receive to just the specified queue */
13127#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_RX_MODE_SIMPLE 0x0 13857#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_RX_MODE_SIMPLE 0x0
13128/* enum: receive to multiple queues using RSS context */ 13858/* enum: receive to multiple queues using RSS context */
13129#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_RX_MODE_RSS 0x1 13859#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_RX_MODE_RSS 0x1
13130/* RSS context (for RX_MODE_RSS) as returned by MC_CMD_RSS_CONTEXT_ALLOC. Note 13860/* RSS context (for RX_MODE_RSS) as returned by MC_CMD_RSS_CONTEXT_ALLOC. Note
13131 * that these handles should be considered opaque to the host, although a value 13861 * that these handles should be considered opaque to the host, although a value
13132 * of 0xFFFFFFFF is guaranteed never to be a valid handle. 13862 * of 0xFFFFFFFF is guaranteed never to be a valid handle.
@@ -13146,7 +13876,7 @@
13146 */ 13876 */
13147#define MC_CMD_GET_PORT_SNIFF_CONFIG 0xf8 13877#define MC_CMD_GET_PORT_SNIFF_CONFIG 0xf8
13148 13878
13149#define MC_CMD_0xf8_PRIVILEGE_CTG SRIOV_CTG_ADMIN 13879#define MC_CMD_0xf8_PRIVILEGE_CTG SRIOV_CTG_GENERAL
13150 13880
13151/* MC_CMD_GET_PORT_SNIFF_CONFIG_IN msgrequest */ 13881/* MC_CMD_GET_PORT_SNIFF_CONFIG_IN msgrequest */
13152#define MC_CMD_GET_PORT_SNIFF_CONFIG_IN_LEN 0 13882#define MC_CMD_GET_PORT_SNIFF_CONFIG_IN_LEN 0
@@ -13167,9 +13897,9 @@
13167#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_RX_MODE_OFST 8 13897#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_RX_MODE_OFST 8
13168#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_RX_MODE_LEN 4 13898#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_RX_MODE_LEN 4
13169/* enum: receiving to just the specified queue */ 13899/* enum: receiving to just the specified queue */
13170#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_RX_MODE_SIMPLE 0x0 13900#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_RX_MODE_SIMPLE 0x0
13171/* enum: receiving to multiple queues using RSS context */ 13901/* enum: receiving to multiple queues using RSS context */
13172#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_RX_MODE_RSS 0x1 13902#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_RX_MODE_RSS 0x1
13173/* RSS context (for RX_MODE_RSS) */ 13903/* RSS context (for RX_MODE_RSS) */
13174#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_RX_CONTEXT_OFST 12 13904#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_RX_CONTEXT_OFST 12
13175#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_RX_CONTEXT_LEN 4 13905#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_RX_CONTEXT_LEN 4
@@ -13193,12 +13923,12 @@
13193/* enum: Per-TXQ enable for multicast UDP destination lookup for possible 13923/* enum: Per-TXQ enable for multicast UDP destination lookup for possible
13194 * internal loopback. (ENTITY is a queue handle, VALUE is a single boolean.) 13924 * internal loopback. (ENTITY is a queue handle, VALUE is a single boolean.)
13195 */ 13925 */
13196#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_TXQ_MCAST_UDP_DST_LOOKUP_EN 0x0 13926#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_TXQ_MCAST_UDP_DST_LOOKUP_EN 0x0
13197/* enum: Per-v-adaptor enable for suppression of self-transmissions on the 13927/* enum: Per-v-adaptor enable for suppression of self-transmissions on the
13198 * internal loopback path. (ENTITY is an EVB_PORT_ID, VALUE is a single 13928 * internal loopback path. (ENTITY is an EVB_PORT_ID, VALUE is a single
13199 * boolean.) 13929 * boolean.)
13200 */ 13930 */
13201#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_VADAPTOR_SUPPRESS_SELF_TX 0x1 13931#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_VADAPTOR_SUPPRESS_SELF_TX 0x1
13202/* handle for the entity to update: queue handle, EVB port ID, etc. depending 13932/* handle for the entity to update: queue handle, EVB port ID, etc. depending
13203 * on the type of configuration setting being changed 13933 * on the type of configuration setting being changed
13204 */ 13934 */
@@ -13278,9 +14008,9 @@
13278#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_RX_MODE_OFST 8 14008#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_RX_MODE_OFST 8
13279#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_RX_MODE_LEN 4 14009#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_RX_MODE_LEN 4
13280/* enum: receive to just the specified queue */ 14010/* enum: receive to just the specified queue */
13281#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_RX_MODE_SIMPLE 0x0 14011#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_RX_MODE_SIMPLE 0x0
13282/* enum: receive to multiple queues using RSS context */ 14012/* enum: receive to multiple queues using RSS context */
13283#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_RX_MODE_RSS 0x1 14013#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_RX_MODE_RSS 0x1
13284/* RSS context (for RX_MODE_RSS) as returned by MC_CMD_RSS_CONTEXT_ALLOC. Note 14014/* RSS context (for RX_MODE_RSS) as returned by MC_CMD_RSS_CONTEXT_ALLOC. Note
13285 * that these handles should be considered opaque to the host, although a value 14015 * that these handles should be considered opaque to the host, although a value
13286 * of 0xFFFFFFFF is guaranteed never to be a valid handle. 14016 * of 0xFFFFFFFF is guaranteed never to be a valid handle.
@@ -13300,7 +14030,7 @@
13300 */ 14030 */
13301#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG 0xfc 14031#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG 0xfc
13302 14032
13303#define MC_CMD_0xfc_PRIVILEGE_CTG SRIOV_CTG_ADMIN 14033#define MC_CMD_0xfc_PRIVILEGE_CTG SRIOV_CTG_GENERAL
13304 14034
13305/* MC_CMD_GET_TX_PORT_SNIFF_CONFIG_IN msgrequest */ 14035/* MC_CMD_GET_TX_PORT_SNIFF_CONFIG_IN msgrequest */
13306#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_IN_LEN 0 14036#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_IN_LEN 0
@@ -13319,9 +14049,9 @@
13319#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_RX_MODE_OFST 8 14049#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_RX_MODE_OFST 8
13320#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_RX_MODE_LEN 4 14050#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_RX_MODE_LEN 4
13321/* enum: receiving to just the specified queue */ 14051/* enum: receiving to just the specified queue */
13322#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_RX_MODE_SIMPLE 0x0 14052#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_RX_MODE_SIMPLE 0x0
13323/* enum: receiving to multiple queues using RSS context */ 14053/* enum: receiving to multiple queues using RSS context */
13324#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_RX_MODE_RSS 0x1 14054#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_RX_MODE_RSS 0x1
13325/* RSS context (for RX_MODE_RSS) */ 14055/* RSS context (for RX_MODE_RSS) */
13326#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_RX_CONTEXT_OFST 12 14056#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_RX_CONTEXT_OFST 12
13327#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_RX_CONTEXT_LEN 4 14057#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_RX_CONTEXT_LEN 4
@@ -13431,9 +14161,9 @@
13431#define MC_CMD_READ_ATB_IN_LEN 16 14161#define MC_CMD_READ_ATB_IN_LEN 16
13432#define MC_CMD_READ_ATB_IN_SIGNAL_BUS_OFST 0 14162#define MC_CMD_READ_ATB_IN_SIGNAL_BUS_OFST 0
13433#define MC_CMD_READ_ATB_IN_SIGNAL_BUS_LEN 4 14163#define MC_CMD_READ_ATB_IN_SIGNAL_BUS_LEN 4
13434#define MC_CMD_READ_ATB_IN_BUS_CCOM 0x0 /* enum */ 14164#define MC_CMD_READ_ATB_IN_BUS_CCOM 0x0 /* enum */
13435#define MC_CMD_READ_ATB_IN_BUS_CKR 0x1 /* enum */ 14165#define MC_CMD_READ_ATB_IN_BUS_CKR 0x1 /* enum */
13436#define MC_CMD_READ_ATB_IN_BUS_CPCIE 0x8 /* enum */ 14166#define MC_CMD_READ_ATB_IN_BUS_CPCIE 0x8 /* enum */
13437#define MC_CMD_READ_ATB_IN_SIGNAL_EN_BITNO_OFST 4 14167#define MC_CMD_READ_ATB_IN_SIGNAL_EN_BITNO_OFST 4
13438#define MC_CMD_READ_ATB_IN_SIGNAL_EN_BITNO_LEN 4 14168#define MC_CMD_READ_ATB_IN_SIGNAL_EN_BITNO_LEN 4
13439#define MC_CMD_READ_ATB_IN_SIGNAL_SEL_OFST 8 14169#define MC_CMD_READ_ATB_IN_SIGNAL_SEL_OFST 8
@@ -13503,46 +14233,46 @@
13503#define MC_CMD_PRIVILEGE_MASK_IN_FUNCTION_PF_WIDTH 16 14233#define MC_CMD_PRIVILEGE_MASK_IN_FUNCTION_PF_WIDTH 16
13504#define MC_CMD_PRIVILEGE_MASK_IN_FUNCTION_VF_LBN 16 14234#define MC_CMD_PRIVILEGE_MASK_IN_FUNCTION_VF_LBN 16
13505#define MC_CMD_PRIVILEGE_MASK_IN_FUNCTION_VF_WIDTH 16 14235#define MC_CMD_PRIVILEGE_MASK_IN_FUNCTION_VF_WIDTH 16
13506#define MC_CMD_PRIVILEGE_MASK_IN_VF_NULL 0xffff /* enum */ 14236#define MC_CMD_PRIVILEGE_MASK_IN_VF_NULL 0xffff /* enum */
13507/* New privilege mask to be set. The mask will only be changed if the MSB is 14237/* New privilege mask to be set. The mask will only be changed if the MSB is
13508 * set to 1. 14238 * set to 1.
13509 */ 14239 */
13510#define MC_CMD_PRIVILEGE_MASK_IN_NEW_MASK_OFST 4 14240#define MC_CMD_PRIVILEGE_MASK_IN_NEW_MASK_OFST 4
13511#define MC_CMD_PRIVILEGE_MASK_IN_NEW_MASK_LEN 4 14241#define MC_CMD_PRIVILEGE_MASK_IN_NEW_MASK_LEN 4
13512#define MC_CMD_PRIVILEGE_MASK_IN_GRP_ADMIN 0x1 /* enum */ 14242#define MC_CMD_PRIVILEGE_MASK_IN_GRP_ADMIN 0x1 /* enum */
13513#define MC_CMD_PRIVILEGE_MASK_IN_GRP_LINK 0x2 /* enum */ 14243#define MC_CMD_PRIVILEGE_MASK_IN_GRP_LINK 0x2 /* enum */
13514#define MC_CMD_PRIVILEGE_MASK_IN_GRP_ONLOAD 0x4 /* enum */ 14244#define MC_CMD_PRIVILEGE_MASK_IN_GRP_ONLOAD 0x4 /* enum */
13515#define MC_CMD_PRIVILEGE_MASK_IN_GRP_PTP 0x8 /* enum */ 14245#define MC_CMD_PRIVILEGE_MASK_IN_GRP_PTP 0x8 /* enum */
13516#define MC_CMD_PRIVILEGE_MASK_IN_GRP_INSECURE_FILTERS 0x10 /* enum */ 14246#define MC_CMD_PRIVILEGE_MASK_IN_GRP_INSECURE_FILTERS 0x10 /* enum */
13517/* enum: Deprecated. Equivalent to MAC_SPOOFING_TX combined with CHANGE_MAC. */ 14247/* enum: Deprecated. Equivalent to MAC_SPOOFING_TX combined with CHANGE_MAC. */
13518#define MC_CMD_PRIVILEGE_MASK_IN_GRP_MAC_SPOOFING 0x20 14248#define MC_CMD_PRIVILEGE_MASK_IN_GRP_MAC_SPOOFING 0x20
13519#define MC_CMD_PRIVILEGE_MASK_IN_GRP_UNICAST 0x40 /* enum */ 14249#define MC_CMD_PRIVILEGE_MASK_IN_GRP_UNICAST 0x40 /* enum */
13520#define MC_CMD_PRIVILEGE_MASK_IN_GRP_MULTICAST 0x80 /* enum */ 14250#define MC_CMD_PRIVILEGE_MASK_IN_GRP_MULTICAST 0x80 /* enum */
13521#define MC_CMD_PRIVILEGE_MASK_IN_GRP_BROADCAST 0x100 /* enum */ 14251#define MC_CMD_PRIVILEGE_MASK_IN_GRP_BROADCAST 0x100 /* enum */
13522#define MC_CMD_PRIVILEGE_MASK_IN_GRP_ALL_MULTICAST 0x200 /* enum */ 14252#define MC_CMD_PRIVILEGE_MASK_IN_GRP_ALL_MULTICAST 0x200 /* enum */
13523#define MC_CMD_PRIVILEGE_MASK_IN_GRP_PROMISCUOUS 0x400 /* enum */ 14253#define MC_CMD_PRIVILEGE_MASK_IN_GRP_PROMISCUOUS 0x400 /* enum */
13524/* enum: Allows to set the TX packets' source MAC address to any arbitrary MAC 14254/* enum: Allows to set the TX packets' source MAC address to any arbitrary MAC
13525 * adress. 14255 * adress.
13526 */ 14256 */
13527#define MC_CMD_PRIVILEGE_MASK_IN_GRP_MAC_SPOOFING_TX 0x800 14257#define MC_CMD_PRIVILEGE_MASK_IN_GRP_MAC_SPOOFING_TX 0x800
13528/* enum: Privilege that allows a Function to change the MAC address configured 14258/* enum: Privilege that allows a Function to change the MAC address configured
13529 * in its associated vAdapter/vPort. 14259 * in its associated vAdapter/vPort.
13530 */ 14260 */
13531#define MC_CMD_PRIVILEGE_MASK_IN_GRP_CHANGE_MAC 0x1000 14261#define MC_CMD_PRIVILEGE_MASK_IN_GRP_CHANGE_MAC 0x1000
13532/* enum: Privilege that allows a Function to install filters that specify VLANs 14262/* enum: Privilege that allows a Function to install filters that specify VLANs
13533 * that are not in the permit list for the associated vPort. This privilege is 14263 * that are not in the permit list for the associated vPort. This privilege is
13534 * primarily to support ESX where vPorts are created that restrict traffic to 14264 * primarily to support ESX where vPorts are created that restrict traffic to
13535 * only a set of permitted VLANs. See the vPort flag FLAG_VLAN_RESTRICT. 14265 * only a set of permitted VLANs. See the vPort flag FLAG_VLAN_RESTRICT.
13536 */ 14266 */
13537#define MC_CMD_PRIVILEGE_MASK_IN_GRP_UNRESTRICTED_VLAN 0x2000 14267#define MC_CMD_PRIVILEGE_MASK_IN_GRP_UNRESTRICTED_VLAN 0x2000
13538/* enum: Privilege for insecure commands. Commands that belong to this group 14268/* enum: Privilege for insecure commands. Commands that belong to this group
13539 * are not permitted on secure adapters regardless of the privilege mask. 14269 * are not permitted on secure adapters regardless of the privilege mask.
13540 */ 14270 */
13541#define MC_CMD_PRIVILEGE_MASK_IN_GRP_INSECURE 0x4000 14271#define MC_CMD_PRIVILEGE_MASK_IN_GRP_INSECURE 0x4000
13542/* enum: Set this bit to indicate that a new privilege mask is to be set, 14272/* enum: Set this bit to indicate that a new privilege mask is to be set,
13543 * otherwise the command will only read the existing mask. 14273 * otherwise the command will only read the existing mask.
13544 */ 14274 */
13545#define MC_CMD_PRIVILEGE_MASK_IN_DO_CHANGE 0x80000000 14275#define MC_CMD_PRIVILEGE_MASK_IN_DO_CHANGE 0x80000000
13546 14276
13547/* MC_CMD_PRIVILEGE_MASK_OUT msgresponse */ 14277/* MC_CMD_PRIVILEGE_MASK_OUT msgresponse */
13548#define MC_CMD_PRIVILEGE_MASK_OUT_LEN 4 14278#define MC_CMD_PRIVILEGE_MASK_OUT_LEN 4
@@ -13573,12 +14303,12 @@
13573/* New link state mode to be set */ 14303/* New link state mode to be set */
13574#define MC_CMD_LINK_STATE_MODE_IN_NEW_MODE_OFST 4 14304#define MC_CMD_LINK_STATE_MODE_IN_NEW_MODE_OFST 4
13575#define MC_CMD_LINK_STATE_MODE_IN_NEW_MODE_LEN 4 14305#define MC_CMD_LINK_STATE_MODE_IN_NEW_MODE_LEN 4
13576#define MC_CMD_LINK_STATE_MODE_IN_LINK_STATE_AUTO 0x0 /* enum */ 14306#define MC_CMD_LINK_STATE_MODE_IN_LINK_STATE_AUTO 0x0 /* enum */
13577#define MC_CMD_LINK_STATE_MODE_IN_LINK_STATE_UP 0x1 /* enum */ 14307#define MC_CMD_LINK_STATE_MODE_IN_LINK_STATE_UP 0x1 /* enum */
13578#define MC_CMD_LINK_STATE_MODE_IN_LINK_STATE_DOWN 0x2 /* enum */ 14308#define MC_CMD_LINK_STATE_MODE_IN_LINK_STATE_DOWN 0x2 /* enum */
13579/* enum: Use this value to just read the existing setting without modifying it. 14309/* enum: Use this value to just read the existing setting without modifying it.
13580 */ 14310 */
13581#define MC_CMD_LINK_STATE_MODE_IN_DO_NOT_CHANGE 0xffffffff 14311#define MC_CMD_LINK_STATE_MODE_IN_DO_NOT_CHANGE 0xffffffff
13582 14312
13583/* MC_CMD_LINK_STATE_MODE_OUT msgresponse */ 14313/* MC_CMD_LINK_STATE_MODE_OUT msgresponse */
13584#define MC_CMD_LINK_STATE_MODE_OUT_LEN 4 14314#define MC_CMD_LINK_STATE_MODE_OUT_LEN 4
@@ -13674,12 +14404,12 @@
13674/* The groups of functions to have their privilege masks modified. */ 14404/* The groups of functions to have their privilege masks modified. */
13675#define MC_CMD_PRIVILEGE_MODIFY_IN_FN_GROUP_OFST 0 14405#define MC_CMD_PRIVILEGE_MODIFY_IN_FN_GROUP_OFST 0
13676#define MC_CMD_PRIVILEGE_MODIFY_IN_FN_GROUP_LEN 4 14406#define MC_CMD_PRIVILEGE_MODIFY_IN_FN_GROUP_LEN 4
13677#define MC_CMD_PRIVILEGE_MODIFY_IN_NONE 0x0 /* enum */ 14407#define MC_CMD_PRIVILEGE_MODIFY_IN_NONE 0x0 /* enum */
13678#define MC_CMD_PRIVILEGE_MODIFY_IN_ALL 0x1 /* enum */ 14408#define MC_CMD_PRIVILEGE_MODIFY_IN_ALL 0x1 /* enum */
13679#define MC_CMD_PRIVILEGE_MODIFY_IN_PFS_ONLY 0x2 /* enum */ 14409#define MC_CMD_PRIVILEGE_MODIFY_IN_PFS_ONLY 0x2 /* enum */
13680#define MC_CMD_PRIVILEGE_MODIFY_IN_VFS_ONLY 0x3 /* enum */ 14410#define MC_CMD_PRIVILEGE_MODIFY_IN_VFS_ONLY 0x3 /* enum */
13681#define MC_CMD_PRIVILEGE_MODIFY_IN_VFS_OF_PF 0x4 /* enum */ 14411#define MC_CMD_PRIVILEGE_MODIFY_IN_VFS_OF_PF 0x4 /* enum */
13682#define MC_CMD_PRIVILEGE_MODIFY_IN_ONE 0x5 /* enum */ 14412#define MC_CMD_PRIVILEGE_MODIFY_IN_ONE 0x5 /* enum */
13683/* For VFS_OF_PF specify the PF, for ONE specify the target function */ 14413/* For VFS_OF_PF specify the PF, for ONE specify the target function */
13684#define MC_CMD_PRIVILEGE_MODIFY_IN_FUNCTION_OFST 4 14414#define MC_CMD_PRIVILEGE_MODIFY_IN_FUNCTION_OFST 4
13685#define MC_CMD_PRIVILEGE_MODIFY_IN_FUNCTION_LEN 4 14415#define MC_CMD_PRIVILEGE_MODIFY_IN_FUNCTION_LEN 4
@@ -13782,11 +14512,11 @@
13782/* Sector type */ 14512/* Sector type */
13783#define MC_CMD_XPM_READ_SECTOR_OUT_TYPE_OFST 0 14513#define MC_CMD_XPM_READ_SECTOR_OUT_TYPE_OFST 0
13784#define MC_CMD_XPM_READ_SECTOR_OUT_TYPE_LEN 4 14514#define MC_CMD_XPM_READ_SECTOR_OUT_TYPE_LEN 4
13785#define MC_CMD_XPM_READ_SECTOR_OUT_BLANK 0x0 /* enum */ 14515#define MC_CMD_XPM_READ_SECTOR_OUT_BLANK 0x0 /* enum */
13786#define MC_CMD_XPM_READ_SECTOR_OUT_CRYPTO_KEY_128 0x1 /* enum */ 14516#define MC_CMD_XPM_READ_SECTOR_OUT_CRYPTO_KEY_128 0x1 /* enum */
13787#define MC_CMD_XPM_READ_SECTOR_OUT_CRYPTO_KEY_256 0x2 /* enum */ 14517#define MC_CMD_XPM_READ_SECTOR_OUT_CRYPTO_KEY_256 0x2 /* enum */
13788#define MC_CMD_XPM_READ_SECTOR_OUT_CRYPTO_DATA 0x3 /* enum */ 14518#define MC_CMD_XPM_READ_SECTOR_OUT_CRYPTO_DATA 0x3 /* enum */
13789#define MC_CMD_XPM_READ_SECTOR_OUT_INVALID 0xff /* enum */ 14519#define MC_CMD_XPM_READ_SECTOR_OUT_INVALID 0xff /* enum */
13790/* Sector data */ 14520/* Sector data */
13791#define MC_CMD_XPM_READ_SECTOR_OUT_DATA_OFST 4 14521#define MC_CMD_XPM_READ_SECTOR_OUT_DATA_OFST 4
13792#define MC_CMD_XPM_READ_SECTOR_OUT_DATA_LEN 1 14522#define MC_CMD_XPM_READ_SECTOR_OUT_DATA_LEN 1
@@ -14001,18 +14731,18 @@
14001#define TUNNEL_ENCAP_UDP_PORT_ENTRY_UDP_PORT_OFST 0 14731#define TUNNEL_ENCAP_UDP_PORT_ENTRY_UDP_PORT_OFST 0
14002#define TUNNEL_ENCAP_UDP_PORT_ENTRY_UDP_PORT_LEN 2 14732#define TUNNEL_ENCAP_UDP_PORT_ENTRY_UDP_PORT_LEN 2
14003/* enum: the IANA allocated UDP port for VXLAN */ 14733/* enum: the IANA allocated UDP port for VXLAN */
14004#define TUNNEL_ENCAP_UDP_PORT_ENTRY_IANA_VXLAN_UDP_PORT 0x12b5 14734#define TUNNEL_ENCAP_UDP_PORT_ENTRY_IANA_VXLAN_UDP_PORT 0x12b5
14005/* enum: the IANA allocated UDP port for Geneve */ 14735/* enum: the IANA allocated UDP port for Geneve */
14006#define TUNNEL_ENCAP_UDP_PORT_ENTRY_IANA_GENEVE_UDP_PORT 0x17c1 14736#define TUNNEL_ENCAP_UDP_PORT_ENTRY_IANA_GENEVE_UDP_PORT 0x17c1
14007#define TUNNEL_ENCAP_UDP_PORT_ENTRY_UDP_PORT_LBN 0 14737#define TUNNEL_ENCAP_UDP_PORT_ENTRY_UDP_PORT_LBN 0
14008#define TUNNEL_ENCAP_UDP_PORT_ENTRY_UDP_PORT_WIDTH 16 14738#define TUNNEL_ENCAP_UDP_PORT_ENTRY_UDP_PORT_WIDTH 16
14009/* tunnel encapsulation protocol (only those named below are supported) */ 14739/* tunnel encapsulation protocol (only those named below are supported) */
14010#define TUNNEL_ENCAP_UDP_PORT_ENTRY_PROTOCOL_OFST 2 14740#define TUNNEL_ENCAP_UDP_PORT_ENTRY_PROTOCOL_OFST 2
14011#define TUNNEL_ENCAP_UDP_PORT_ENTRY_PROTOCOL_LEN 2 14741#define TUNNEL_ENCAP_UDP_PORT_ENTRY_PROTOCOL_LEN 2
14012/* enum: This port will be used for VXLAN on both IPv4 and IPv6 */ 14742/* enum: This port will be used for VXLAN on both IPv4 and IPv6 */
14013#define TUNNEL_ENCAP_UDP_PORT_ENTRY_VXLAN 0x0 14743#define TUNNEL_ENCAP_UDP_PORT_ENTRY_VXLAN 0x0
14014/* enum: This port will be used for Geneve on both IPv4 and IPv6 */ 14744/* enum: This port will be used for Geneve on both IPv4 and IPv6 */
14015#define TUNNEL_ENCAP_UDP_PORT_ENTRY_GENEVE 0x1 14745#define TUNNEL_ENCAP_UDP_PORT_ENTRY_GENEVE 0x1
14016#define TUNNEL_ENCAP_UDP_PORT_ENTRY_PROTOCOL_LBN 16 14746#define TUNNEL_ENCAP_UDP_PORT_ENTRY_PROTOCOL_LBN 16
14017#define TUNNEL_ENCAP_UDP_PORT_ENTRY_PROTOCOL_WIDTH 16 14747#define TUNNEL_ENCAP_UDP_PORT_ENTRY_PROTOCOL_WIDTH 16
14018 14748
@@ -14180,10 +14910,10 @@
14180/* Timer mode. Meanings as per EVQ_TMR_REG.TC_TIMER_VAL */ 14910/* Timer mode. Meanings as per EVQ_TMR_REG.TC_TIMER_VAL */
14181#define MC_CMD_SET_EVQ_TMR_IN_TMR_MODE_OFST 12 14911#define MC_CMD_SET_EVQ_TMR_IN_TMR_MODE_OFST 12
14182#define MC_CMD_SET_EVQ_TMR_IN_TMR_MODE_LEN 4 14912#define MC_CMD_SET_EVQ_TMR_IN_TMR_MODE_LEN 4
14183#define MC_CMD_SET_EVQ_TMR_IN_TIMER_MODE_DIS 0x0 /* enum */ 14913#define MC_CMD_SET_EVQ_TMR_IN_TIMER_MODE_DIS 0x0 /* enum */
14184#define MC_CMD_SET_EVQ_TMR_IN_TIMER_MODE_IMMED_START 0x1 /* enum */ 14914#define MC_CMD_SET_EVQ_TMR_IN_TIMER_MODE_IMMED_START 0x1 /* enum */
14185#define MC_CMD_SET_EVQ_TMR_IN_TIMER_MODE_TRIG_START 0x2 /* enum */ 14915#define MC_CMD_SET_EVQ_TMR_IN_TIMER_MODE_TRIG_START 0x2 /* enum */
14186#define MC_CMD_SET_EVQ_TMR_IN_TIMER_MODE_INT_HLDOFF 0x3 /* enum */ 14916#define MC_CMD_SET_EVQ_TMR_IN_TIMER_MODE_INT_HLDOFF 0x3 /* enum */
14187 14917
14188/* MC_CMD_SET_EVQ_TMR_OUT msgresponse */ 14918/* MC_CMD_SET_EVQ_TMR_OUT msgresponse */
14189#define MC_CMD_SET_EVQ_TMR_OUT_LEN 8 14919#define MC_CMD_SET_EVQ_TMR_OUT_LEN 8
@@ -14269,7 +14999,7 @@
14269 */ 14999 */
14270#define MC_CMD_ALLOCATE_TX_VFIFO_CP 0x11d 15000#define MC_CMD_ALLOCATE_TX_VFIFO_CP 0x11d
14271 15001
14272#define MC_CMD_0x11d_PRIVILEGE_CTG SRIOV_CTG_ADMIN 15002#define MC_CMD_0x11d_PRIVILEGE_CTG SRIOV_CTG_GENERAL
14273 15003
14274/* MC_CMD_ALLOCATE_TX_VFIFO_CP_IN msgrequest */ 15004/* MC_CMD_ALLOCATE_TX_VFIFO_CP_IN msgrequest */
14275#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_LEN 20 15005#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_LEN 20
@@ -14281,9 +15011,9 @@
14281/* Will the common pool be used as TX_vFIFO_ULL (1) */ 15011/* Will the common pool be used as TX_vFIFO_ULL (1) */
14282#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_MODE_OFST 4 15012#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_MODE_OFST 4
14283#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_MODE_LEN 4 15013#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_MODE_LEN 4
14284#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_ENABLED 0x1 /* enum */ 15014#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_ENABLED 0x1 /* enum */
14285/* enum: Using this interface without TX_vFIFO_ULL is not supported for now */ 15015/* enum: Using this interface without TX_vFIFO_ULL is not supported for now */
14286#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_DISABLED 0x0 15016#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_DISABLED 0x0
14287/* Number of buffers to reserve for the common pool */ 15017/* Number of buffers to reserve for the common pool */
14288#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_SIZE_OFST 8 15018#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_SIZE_OFST 8
14289#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_SIZE_LEN 4 15019#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_SIZE_LEN 4
@@ -14291,20 +15021,20 @@
14291#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_INGRESS_OFST 12 15021#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_INGRESS_OFST 12
14292#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_INGRESS_LEN 4 15022#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_INGRESS_LEN 4
14293/* enum: Extracts information from function */ 15023/* enum: Extracts information from function */
14294#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_USE_FUNCTION_VALUE -0x1 15024#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_USE_FUNCTION_VALUE -0x1
14295/* Network port or RX Engine to which the common pool connects. */ 15025/* Network port or RX Engine to which the common pool connects. */
14296#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_EGRESS_OFST 16 15026#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_EGRESS_OFST 16
14297#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_EGRESS_LEN 4 15027#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_EGRESS_LEN 4
14298/* enum: Extracts information from function */ 15028/* enum: Extracts information from function */
14299/* MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_USE_FUNCTION_VALUE -0x1 */ 15029/* MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_USE_FUNCTION_VALUE -0x1 */
14300#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_PORT0 0x0 /* enum */ 15030#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_PORT0 0x0 /* enum */
14301#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_PORT1 0x1 /* enum */ 15031#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_PORT1 0x1 /* enum */
14302#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_PORT2 0x2 /* enum */ 15032#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_PORT2 0x2 /* enum */
14303#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_PORT3 0x3 /* enum */ 15033#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_PORT3 0x3 /* enum */
14304/* enum: To enable Switch loopback with Rx engine 0 */ 15034/* enum: To enable Switch loopback with Rx engine 0 */
14305#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_RX_ENGINE0 0x4 15035#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_RX_ENGINE0 0x4
14306/* enum: To enable Switch loopback with Rx engine 1 */ 15036/* enum: To enable Switch loopback with Rx engine 1 */
14307#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_RX_ENGINE1 0x5 15037#define MC_CMD_ALLOCATE_TX_VFIFO_CP_IN_RX_ENGINE1 0x5
14308 15038
14309/* MC_CMD_ALLOCATE_TX_VFIFO_CP_OUT msgresponse */ 15039/* MC_CMD_ALLOCATE_TX_VFIFO_CP_OUT msgresponse */
14310#define MC_CMD_ALLOCATE_TX_VFIFO_CP_OUT_LEN 4 15040#define MC_CMD_ALLOCATE_TX_VFIFO_CP_OUT_LEN 4
@@ -14320,7 +15050,7 @@
14320 */ 15050 */
14321#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO 0x11e 15051#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO 0x11e
14322 15052
14323#define MC_CMD_0x11e_PRIVILEGE_CTG SRIOV_CTG_ADMIN 15053#define MC_CMD_0x11e_PRIVILEGE_CTG SRIOV_CTG_GENERAL
14324 15054
14325/* MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN msgrequest */ 15055/* MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN msgrequest */
14326#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_LEN 20 15056#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_LEN 20
@@ -14332,20 +15062,20 @@
14332#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_EGRESS_OFST 4 15062#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_EGRESS_OFST 4
14333#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_EGRESS_LEN 4 15063#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_EGRESS_LEN 4
14334/* enum: Extracts information from common pool */ 15064/* enum: Extracts information from common pool */
14335#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_USE_CP_VALUE -0x1 15065#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_USE_CP_VALUE -0x1
14336#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_PORT0 0x0 /* enum */ 15066#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_PORT0 0x0 /* enum */
14337#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_PORT1 0x1 /* enum */ 15067#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_PORT1 0x1 /* enum */
14338#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_PORT2 0x2 /* enum */ 15068#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_PORT2 0x2 /* enum */
14339#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_PORT3 0x3 /* enum */ 15069#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_PORT3 0x3 /* enum */
14340/* enum: To enable Switch loopback with Rx engine 0 */ 15070/* enum: To enable Switch loopback with Rx engine 0 */
14341#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_RX_ENGINE0 0x4 15071#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_RX_ENGINE0 0x4
14342/* enum: To enable Switch loopback with Rx engine 1 */ 15072/* enum: To enable Switch loopback with Rx engine 1 */
14343#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_RX_ENGINE1 0x5 15073#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_RX_ENGINE1 0x5
14344/* Minimum number of buffers that the pool must have */ 15074/* Minimum number of buffers that the pool must have */
14345#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_SIZE_OFST 8 15075#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_SIZE_OFST 8
14346#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_SIZE_LEN 4 15076#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_SIZE_LEN 4
14347/* enum: Do not check the space available */ 15077/* enum: Do not check the space available */
14348#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_NO_MINIMUM 0x0 15078#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_NO_MINIMUM 0x0
14349/* Will the vFIFO be used as TX_vFIFO_ULL */ 15079/* Will the vFIFO be used as TX_vFIFO_ULL */
14350#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_MODE_OFST 12 15080#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_MODE_OFST 12
14351#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_MODE_LEN 4 15081#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_MODE_LEN 4
@@ -14353,7 +15083,7 @@
14353#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_PRIORITY_OFST 16 15083#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_PRIORITY_OFST 16
14354#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_PRIORITY_LEN 4 15084#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_PRIORITY_LEN 4
14355/* enum: Search for the lowest unused priority */ 15085/* enum: Search for the lowest unused priority */
14356#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_LOWEST_AVAILABLE -0x1 15086#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_IN_LOWEST_AVAILABLE -0x1
14357 15087
14358/* MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_OUT msgresponse */ 15088/* MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_OUT msgresponse */
14359#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_OUT_LEN 8 15089#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO_OUT_LEN 8
@@ -14372,7 +15102,7 @@
14372 */ 15102 */
14373#define MC_CMD_TEARDOWN_TX_VFIFO_VF 0x11f 15103#define MC_CMD_TEARDOWN_TX_VFIFO_VF 0x11f
14374 15104
14375#define MC_CMD_0x11f_PRIVILEGE_CTG SRIOV_CTG_ADMIN 15105#define MC_CMD_0x11f_PRIVILEGE_CTG SRIOV_CTG_GENERAL
14376 15106
14377/* MC_CMD_TEARDOWN_TX_VFIFO_VF_IN msgrequest */ 15107/* MC_CMD_TEARDOWN_TX_VFIFO_VF_IN msgrequest */
14378#define MC_CMD_TEARDOWN_TX_VFIFO_VF_IN_LEN 4 15108#define MC_CMD_TEARDOWN_TX_VFIFO_VF_IN_LEN 4
@@ -14391,7 +15121,7 @@
14391 */ 15121 */
14392#define MC_CMD_DEALLOCATE_TX_VFIFO_CP 0x121 15122#define MC_CMD_DEALLOCATE_TX_VFIFO_CP 0x121
14393 15123
14394#define MC_CMD_0x121_PRIVILEGE_CTG SRIOV_CTG_ADMIN 15124#define MC_CMD_0x121_PRIVILEGE_CTG SRIOV_CTG_GENERAL
14395 15125
14396/* MC_CMD_DEALLOCATE_TX_VFIFO_CP_IN msgrequest */ 15126/* MC_CMD_DEALLOCATE_TX_VFIFO_CP_IN msgrequest */
14397#define MC_CMD_DEALLOCATE_TX_VFIFO_CP_IN_LEN 4 15127#define MC_CMD_DEALLOCATE_TX_VFIFO_CP_IN_LEN 4
@@ -14410,7 +15140,7 @@
14410 */ 15140 */
14411#define MC_CMD_SWITCH_GET_UNASSIGNED_BUFFERS 0x124 15141#define MC_CMD_SWITCH_GET_UNASSIGNED_BUFFERS 0x124
14412 15142
14413#define MC_CMD_0x124_PRIVILEGE_CTG SRIOV_CTG_ADMIN 15143#define MC_CMD_0x124_PRIVILEGE_CTG SRIOV_CTG_GENERAL
14414 15144
14415/* MC_CMD_SWITCH_GET_UNASSIGNED_BUFFERS_IN msgrequest */ 15145/* MC_CMD_SWITCH_GET_UNASSIGNED_BUFFERS_IN msgrequest */
14416#define MC_CMD_SWITCH_GET_UNASSIGNED_BUFFERS_IN_LEN 0 15146#define MC_CMD_SWITCH_GET_UNASSIGNED_BUFFERS_IN_LEN 0
diff --git a/drivers/net/ethernet/sfc/mcdi_port.c b/drivers/net/ethernet/sfc/mcdi_port.c
index ce8aabf9091e..9382bb0b4d5a 100644
--- a/drivers/net/ethernet/sfc/mcdi_port.c
+++ b/drivers/net/ethernet/sfc/mcdi_port.c
@@ -352,6 +352,64 @@ static void efx_mcdi_phy_decode_link(struct efx_nic *efx,
352 link_state->speed = speed; 352 link_state->speed = speed;
353} 353}
354 354
355/* The semantics of the ethtool FEC mode bitmask are not well defined,
356 * particularly the meaning of combinations of bits. Which means we get to
357 * define our own semantics, as follows:
358 * OFF overrides any other bits, and means "disable all FEC" (with the
359 * exception of 25G KR4/CR4, where it is not possible to reject it if AN
360 * partner requests it).
361 * AUTO on its own means use cable requirements and link partner autoneg with
362 * fw-default preferences for the cable type.
363 * AUTO and either RS or BASER means use the specified FEC type if cable and
364 * link partner support it, otherwise autoneg/fw-default.
365 * RS or BASER alone means use the specified FEC type if cable and link partner
366 * support it and either requests it, otherwise no FEC.
367 * Both RS and BASER (whether AUTO or not) means use FEC if cable and link
368 * partner support it, preferring RS to BASER.
369 */
370static u32 ethtool_fec_caps_to_mcdi(u32 ethtool_cap)
371{
372 u32 ret = 0;
373
374 if (ethtool_cap & ETHTOOL_FEC_OFF)
375 return 0;
376
377 if (ethtool_cap & ETHTOOL_FEC_AUTO)
378 ret |= (1 << MC_CMD_PHY_CAP_BASER_FEC_LBN) |
379 (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_LBN) |
380 (1 << MC_CMD_PHY_CAP_RS_FEC_LBN);
381 if (ethtool_cap & ETHTOOL_FEC_RS)
382 ret |= (1 << MC_CMD_PHY_CAP_RS_FEC_LBN) |
383 (1 << MC_CMD_PHY_CAP_RS_FEC_REQUESTED_LBN);
384 if (ethtool_cap & ETHTOOL_FEC_BASER)
385 ret |= (1 << MC_CMD_PHY_CAP_BASER_FEC_LBN) |
386 (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_LBN) |
387 (1 << MC_CMD_PHY_CAP_BASER_FEC_REQUESTED_LBN) |
388 (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_REQUESTED_LBN);
389 return ret;
390}
391
392/* Invert ethtool_fec_caps_to_mcdi. There are two combinations that function
393 * can never produce, (baser xor rs) and neither req; the implementation below
394 * maps both of those to AUTO. This should never matter, and it's not clear
395 * what a better mapping would be anyway.
396 */
397static u32 mcdi_fec_caps_to_ethtool(u32 caps, bool is_25g)
398{
399 bool rs = caps & (1 << MC_CMD_PHY_CAP_RS_FEC_LBN),
400 rs_req = caps & (1 << MC_CMD_PHY_CAP_RS_FEC_REQUESTED_LBN),
401 baser = is_25g ? caps & (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_LBN)
402 : caps & (1 << MC_CMD_PHY_CAP_BASER_FEC_LBN),
403 baser_req = is_25g ? caps & (1 << MC_CMD_PHY_CAP_25G_BASER_FEC_REQUESTED_LBN)
404 : caps & (1 << MC_CMD_PHY_CAP_BASER_FEC_REQUESTED_LBN);
405
406 if (!baser && !rs)
407 return ETHTOOL_FEC_OFF;
408 return (rs_req ? ETHTOOL_FEC_RS : 0) |
409 (baser_req ? ETHTOOL_FEC_BASER : 0) |
410 (baser == baser_req && rs == rs_req ? 0 : ETHTOOL_FEC_AUTO);
411}
412
355static int efx_mcdi_phy_probe(struct efx_nic *efx) 413static int efx_mcdi_phy_probe(struct efx_nic *efx)
356{ 414{
357 struct efx_mcdi_phy_data *phy_data; 415 struct efx_mcdi_phy_data *phy_data;
@@ -438,6 +496,13 @@ static int efx_mcdi_phy_probe(struct efx_nic *efx)
438 MCDI_DWORD(outbuf, GET_LINK_OUT_FLAGS), 496 MCDI_DWORD(outbuf, GET_LINK_OUT_FLAGS),
439 MCDI_DWORD(outbuf, GET_LINK_OUT_FCNTL)); 497 MCDI_DWORD(outbuf, GET_LINK_OUT_FCNTL));
440 498
499 /* Record the initial FEC configuration (or nearest approximation
500 * representable in the ethtool configuration space)
501 */
502 efx->fec_config = mcdi_fec_caps_to_ethtool(caps,
503 efx->link_state.speed == 25000 ||
504 efx->link_state.speed == 50000);
505
441 /* Default to Autonegotiated flow control if the PHY supports it */ 506 /* Default to Autonegotiated flow control if the PHY supports it */
442 efx->wanted_fc = EFX_FC_RX | EFX_FC_TX; 507 efx->wanted_fc = EFX_FC_RX | EFX_FC_TX;
443 if (phy_data->supported_cap & (1 << MC_CMD_PHY_CAP_AN_LBN)) 508 if (phy_data->supported_cap & (1 << MC_CMD_PHY_CAP_AN_LBN))
@@ -458,6 +523,8 @@ int efx_mcdi_port_reconfigure(struct efx_nic *efx)
458 ethtool_linkset_to_mcdi_cap(efx->link_advertising) : 523 ethtool_linkset_to_mcdi_cap(efx->link_advertising) :
459 phy_cfg->forced_cap); 524 phy_cfg->forced_cap);
460 525
526 caps |= ethtool_fec_caps_to_mcdi(efx->fec_config);
527
461 return efx_mcdi_set_link(efx, caps, efx_get_mcdi_phy_flags(efx), 528 return efx_mcdi_set_link(efx, caps, efx_get_mcdi_phy_flags(efx),
462 efx->loopback_mode, 0); 529 efx->loopback_mode, 0);
463} 530}
@@ -584,6 +651,8 @@ efx_mcdi_phy_set_link_ksettings(struct efx_nic *efx,
584 } 651 }
585 } 652 }
586 653
654 caps |= ethtool_fec_caps_to_mcdi(efx->fec_config);
655
587 rc = efx_mcdi_set_link(efx, caps, efx_get_mcdi_phy_flags(efx), 656 rc = efx_mcdi_set_link(efx, caps, efx_get_mcdi_phy_flags(efx),
588 efx->loopback_mode, 0); 657 efx->loopback_mode, 0);
589 if (rc) 658 if (rc)
@@ -599,6 +668,85 @@ efx_mcdi_phy_set_link_ksettings(struct efx_nic *efx,
599 return 0; 668 return 0;
600} 669}
601 670
671static int efx_mcdi_phy_get_fecparam(struct efx_nic *efx,
672 struct ethtool_fecparam *fec)
673{
674 MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_V2_LEN);
675 u32 caps, active, speed; /* MCDI format */
676 bool is_25g = false;
677 size_t outlen;
678 int rc;
679
680 BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
681 rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
682 outbuf, sizeof(outbuf), &outlen);
683 if (rc)
684 return rc;
685 if (outlen < MC_CMD_GET_LINK_OUT_V2_LEN)
686 return -EOPNOTSUPP;
687
688 /* behaviour for 25G/50G links depends on 25G BASER bit */
689 speed = MCDI_DWORD(outbuf, GET_LINK_OUT_V2_LINK_SPEED);
690 is_25g = speed == 25000 || speed == 50000;
691
692 caps = MCDI_DWORD(outbuf, GET_LINK_OUT_V2_CAP);
693 fec->fec = mcdi_fec_caps_to_ethtool(caps, is_25g);
694 /* BASER is never supported on 100G */
695 if (speed == 100000)
696 fec->fec &= ~ETHTOOL_FEC_BASER;
697
698 active = MCDI_DWORD(outbuf, GET_LINK_OUT_V2_FEC_TYPE);
699 switch (active) {
700 case MC_CMD_FEC_NONE:
701 fec->active_fec = ETHTOOL_FEC_OFF;
702 break;
703 case MC_CMD_FEC_BASER:
704 fec->active_fec = ETHTOOL_FEC_BASER;
705 break;
706 case MC_CMD_FEC_RS:
707 fec->active_fec = ETHTOOL_FEC_RS;
708 break;
709 default:
710 netif_warn(efx, hw, efx->net_dev,
711 "Firmware reports unrecognised FEC_TYPE %u\n",
712 active);
713 /* We don't know what firmware has picked. AUTO is as good a
714 * "can't happen" value as any other.
715 */
716 fec->active_fec = ETHTOOL_FEC_AUTO;
717 break;
718 }
719
720 return 0;
721}
722
723static int efx_mcdi_phy_set_fecparam(struct efx_nic *efx,
724 const struct ethtool_fecparam *fec)
725{
726 struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
727 u32 caps;
728 int rc;
729
730 /* Work out what efx_mcdi_phy_set_link_ksettings() would produce from
731 * saved advertising bits
732 */
733 if (test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, efx->link_advertising))
734 caps = (ethtool_linkset_to_mcdi_cap(efx->link_advertising) |
735 1 << MC_CMD_PHY_CAP_AN_LBN);
736 else
737 caps = phy_cfg->forced_cap;
738
739 caps |= ethtool_fec_caps_to_mcdi(fec->fec);
740 rc = efx_mcdi_set_link(efx, caps, efx_get_mcdi_phy_flags(efx),
741 efx->loopback_mode, 0);
742 if (rc)
743 return rc;
744
745 /* Record the new FEC setting for subsequent set_link calls */
746 efx->fec_config = fec->fec;
747 return 0;
748}
749
602static int efx_mcdi_phy_test_alive(struct efx_nic *efx) 750static int efx_mcdi_phy_test_alive(struct efx_nic *efx)
603{ 751{
604 MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PHY_STATE_OUT_LEN); 752 MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PHY_STATE_OUT_LEN);
@@ -977,6 +1125,8 @@ static const struct efx_phy_operations efx_mcdi_phy_ops = {
977 .remove = efx_mcdi_phy_remove, 1125 .remove = efx_mcdi_phy_remove,
978 .get_link_ksettings = efx_mcdi_phy_get_link_ksettings, 1126 .get_link_ksettings = efx_mcdi_phy_get_link_ksettings,
979 .set_link_ksettings = efx_mcdi_phy_set_link_ksettings, 1127 .set_link_ksettings = efx_mcdi_phy_set_link_ksettings,
1128 .get_fecparam = efx_mcdi_phy_get_fecparam,
1129 .set_fecparam = efx_mcdi_phy_set_fecparam,
980 .test_alive = efx_mcdi_phy_test_alive, 1130 .test_alive = efx_mcdi_phy_test_alive,
981 .run_tests = efx_mcdi_phy_run_tests, 1131 .run_tests = efx_mcdi_phy_run_tests,
982 .test_name = efx_mcdi_phy_test_name, 1132 .test_name = efx_mcdi_phy_test_name,
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index d20a8660ee48..2453f3849e72 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -627,6 +627,8 @@ static inline bool efx_link_state_equal(const struct efx_link_state *left,
627 * Serialised by the mac_lock. 627 * Serialised by the mac_lock.
628 * @get_link_ksettings: Get ethtool settings. Serialised by the mac_lock. 628 * @get_link_ksettings: Get ethtool settings. Serialised by the mac_lock.
629 * @set_link_ksettings: Set ethtool settings. Serialised by the mac_lock. 629 * @set_link_ksettings: Set ethtool settings. Serialised by the mac_lock.
630 * @get_fecparam: Get Forward Error Correction settings. Serialised by mac_lock.
631 * @set_fecparam: Set Forward Error Correction settings. Serialised by mac_lock.
630 * @set_npage_adv: Set abilities advertised in (Extended) Next Page 632 * @set_npage_adv: Set abilities advertised in (Extended) Next Page
631 * (only needed where AN bit is set in mmds) 633 * (only needed where AN bit is set in mmds)
632 * @test_alive: Test that PHY is 'alive' (online) 634 * @test_alive: Test that PHY is 'alive' (online)
@@ -645,6 +647,9 @@ struct efx_phy_operations {
645 struct ethtool_link_ksettings *cmd); 647 struct ethtool_link_ksettings *cmd);
646 int (*set_link_ksettings)(struct efx_nic *efx, 648 int (*set_link_ksettings)(struct efx_nic *efx,
647 const struct ethtool_link_ksettings *cmd); 649 const struct ethtool_link_ksettings *cmd);
650 int (*get_fecparam)(struct efx_nic *efx, struct ethtool_fecparam *fec);
651 int (*set_fecparam)(struct efx_nic *efx,
652 const struct ethtool_fecparam *fec);
648 void (*set_npage_adv) (struct efx_nic *efx, u32); 653 void (*set_npage_adv) (struct efx_nic *efx, u32);
649 int (*test_alive) (struct efx_nic *efx); 654 int (*test_alive) (struct efx_nic *efx);
650 const char *(*test_name) (struct efx_nic *efx, unsigned int index); 655 const char *(*test_name) (struct efx_nic *efx, unsigned int index);
@@ -704,6 +709,28 @@ union efx_multicast_hash {
704 709
705struct vfdi_status; 710struct vfdi_status;
706 711
712/* The reserved RSS context value */
713#define EFX_EF10_RSS_CONTEXT_INVALID 0xffffffff
714/**
715 * struct efx_rss_context - A user-defined RSS context for filtering
716 * @list: node of linked list on which this struct is stored
717 * @context_id: the RSS_CONTEXT_ID returned by MC firmware, or
718 * %EFX_EF10_RSS_CONTEXT_INVALID if this context is not present on the NIC.
719 * For Siena, 0 if RSS is active, else %EFX_EF10_RSS_CONTEXT_INVALID.
720 * @user_id: the rss_context ID exposed to userspace over ethtool.
721 * @rx_hash_udp_4tuple: UDP 4-tuple hashing enabled
722 * @rx_hash_key: Toeplitz hash key for this RSS context
723 * @indir_table: Indirection table for this RSS context
724 */
725struct efx_rss_context {
726 struct list_head list;
727 u32 context_id;
728 u32 user_id;
729 bool rx_hash_udp_4tuple;
730 u8 rx_hash_key[40];
731 u32 rx_indir_table[128];
732};
733
707/** 734/**
708 * struct efx_nic - an Efx NIC 735 * struct efx_nic - an Efx NIC
709 * @name: Device name (net device name or bus id before net device registered) 736 * @name: Device name (net device name or bus id before net device registered)
@@ -764,11 +791,9 @@ struct vfdi_status;
764 * (valid only for NICs that set %EFX_RX_PKT_PREFIX_LEN; always negative) 791 * (valid only for NICs that set %EFX_RX_PKT_PREFIX_LEN; always negative)
765 * @rx_packet_ts_offset: Offset of timestamp from start of packet data 792 * @rx_packet_ts_offset: Offset of timestamp from start of packet data
766 * (valid only if channel->sync_timestamps_enabled; always negative) 793 * (valid only if channel->sync_timestamps_enabled; always negative)
767 * @rx_hash_key: Toeplitz hash key for RSS
768 * @rx_indir_table: Indirection table for RSS
769 * @rx_scatter: Scatter mode enabled for receives 794 * @rx_scatter: Scatter mode enabled for receives
770 * @rss_active: RSS enabled on hardware 795 * @rss_context: Main RSS context. Its @list member is the head of the list of
771 * @rx_hash_udp_4tuple: UDP 4-tuple hashing enabled 796 * RSS contexts created by user requests
772 * @int_error_count: Number of internal errors seen recently 797 * @int_error_count: Number of internal errors seen recently
773 * @int_error_expire: Time at which error count will be expired 798 * @int_error_expire: Time at which error count will be expired
774 * @irq_soft_enabled: Are IRQs soft-enabled? If not, IRQ handler will 799 * @irq_soft_enabled: Are IRQs soft-enabled? If not, IRQ handler will
@@ -800,6 +825,8 @@ struct vfdi_status;
800 * @mdio_bus: PHY MDIO bus ID (only used by Siena) 825 * @mdio_bus: PHY MDIO bus ID (only used by Siena)
801 * @phy_mode: PHY operating mode. Serialised by @mac_lock. 826 * @phy_mode: PHY operating mode. Serialised by @mac_lock.
802 * @link_advertising: Autonegotiation advertising flags 827 * @link_advertising: Autonegotiation advertising flags
828 * @fec_config: Forward Error Correction configuration flags. For bit positions
829 * see &enum ethtool_fec_config_bits.
803 * @link_state: Current state of the link 830 * @link_state: Current state of the link
804 * @n_link_state_changes: Number of times the link has changed state 831 * @n_link_state_changes: Number of times the link has changed state
805 * @unicast_filter: Flag for Falcon-arch simple unicast filter. 832 * @unicast_filter: Flag for Falcon-arch simple unicast filter.
@@ -909,11 +936,8 @@ struct efx_nic {
909 int rx_packet_hash_offset; 936 int rx_packet_hash_offset;
910 int rx_packet_len_offset; 937 int rx_packet_len_offset;
911 int rx_packet_ts_offset; 938 int rx_packet_ts_offset;
912 u8 rx_hash_key[40];
913 u32 rx_indir_table[128];
914 bool rx_scatter; 939 bool rx_scatter;
915 bool rss_active; 940 struct efx_rss_context rss_context;
916 bool rx_hash_udp_4tuple;
917 941
918 unsigned int_error_count; 942 unsigned int_error_count;
919 unsigned long int_error_expire; 943 unsigned long int_error_expire;
@@ -955,6 +979,7 @@ struct efx_nic {
955 enum efx_phy_mode phy_mode; 979 enum efx_phy_mode phy_mode;
956 980
957 __ETHTOOL_DECLARE_LINK_MODE_MASK(link_advertising); 981 __ETHTOOL_DECLARE_LINK_MODE_MASK(link_advertising);
982 u32 fec_config;
958 struct efx_link_state link_state; 983 struct efx_link_state link_state;
959 unsigned int n_link_state_changes; 984 unsigned int n_link_state_changes;
960 985
@@ -1099,6 +1124,10 @@ struct efx_udp_tunnel {
1099 * @tx_write: Write TX descriptors and doorbell 1124 * @tx_write: Write TX descriptors and doorbell
1100 * @rx_push_rss_config: Write RSS hash key and indirection table to the NIC 1125 * @rx_push_rss_config: Write RSS hash key and indirection table to the NIC
1101 * @rx_pull_rss_config: Read RSS hash key and indirection table back from the NIC 1126 * @rx_pull_rss_config: Read RSS hash key and indirection table back from the NIC
1127 * @rx_push_rss_context_config: Write RSS hash key and indirection table for
1128 * user RSS context to the NIC
1129 * @rx_pull_rss_context_config: Read RSS hash key and indirection table for user
1130 * RSS context back from the NIC
1102 * @rx_probe: Allocate resources for RX queue 1131 * @rx_probe: Allocate resources for RX queue
1103 * @rx_init: Initialise RX queue on the NIC 1132 * @rx_init: Initialise RX queue on the NIC
1104 * @rx_remove: Free resources for RX queue 1133 * @rx_remove: Free resources for RX queue
@@ -1237,6 +1266,13 @@ struct efx_nic_type {
1237 int (*rx_push_rss_config)(struct efx_nic *efx, bool user, 1266 int (*rx_push_rss_config)(struct efx_nic *efx, bool user,
1238 const u32 *rx_indir_table, const u8 *key); 1267 const u32 *rx_indir_table, const u8 *key);
1239 int (*rx_pull_rss_config)(struct efx_nic *efx); 1268 int (*rx_pull_rss_config)(struct efx_nic *efx);
1269 int (*rx_push_rss_context_config)(struct efx_nic *efx,
1270 struct efx_rss_context *ctx,
1271 const u32 *rx_indir_table,
1272 const u8 *key);
1273 int (*rx_pull_rss_context_config)(struct efx_nic *efx,
1274 struct efx_rss_context *ctx);
1275 void (*rx_restore_rss_contexts)(struct efx_nic *efx);
1240 int (*rx_probe)(struct efx_rx_queue *rx_queue); 1276 int (*rx_probe)(struct efx_rx_queue *rx_queue);
1241 void (*rx_init)(struct efx_rx_queue *rx_queue); 1277 void (*rx_init)(struct efx_rx_queue *rx_queue);
1242 void (*rx_remove)(struct efx_rx_queue *rx_queue); 1278 void (*rx_remove)(struct efx_rx_queue *rx_queue);
diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h
index 6549fc685a48..d080a414e8f2 100644
--- a/drivers/net/ethernet/sfc/nic.h
+++ b/drivers/net/ethernet/sfc/nic.h
@@ -374,7 +374,6 @@ enum {
374 * @piobuf_size: size of a single PIO buffer 374 * @piobuf_size: size of a single PIO buffer
375 * @must_restore_piobufs: Flag: PIO buffers have yet to be restored after MC 375 * @must_restore_piobufs: Flag: PIO buffers have yet to be restored after MC
376 * reboot 376 * reboot
377 * @rx_rss_context: Firmware handle for our RSS context
378 * @rx_rss_context_exclusive: Whether our RSS context is exclusive or shared 377 * @rx_rss_context_exclusive: Whether our RSS context is exclusive or shared
379 * @stats: Hardware statistics 378 * @stats: Hardware statistics
380 * @workaround_35388: Flag: firmware supports workaround for bug 35388 379 * @workaround_35388: Flag: firmware supports workaround for bug 35388
@@ -415,7 +414,6 @@ struct efx_ef10_nic_data {
415 unsigned int piobuf_handle[EF10_TX_PIOBUF_COUNT]; 414 unsigned int piobuf_handle[EF10_TX_PIOBUF_COUNT];
416 u16 piobuf_size; 415 u16 piobuf_size;
417 bool must_restore_piobufs; 416 bool must_restore_piobufs;
418 u32 rx_rss_context;
419 bool rx_rss_context_exclusive; 417 bool rx_rss_context_exclusive;
420 u64 stats[EF10_STAT_COUNT]; 418 u64 stats[EF10_STAT_COUNT];
421 bool workaround_35388; 419 bool workaround_35388;
diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c
index ae8645ae4492..18aab25234ba 100644
--- a/drivers/net/ethernet/sfc/siena.c
+++ b/drivers/net/ethernet/sfc/siena.c
@@ -350,11 +350,11 @@ static int siena_rx_pull_rss_config(struct efx_nic *efx)
350 * siena_rx_push_rss_config, below) 350 * siena_rx_push_rss_config, below)
351 */ 351 */
352 efx_reado(efx, &temp, FR_CZ_RX_RSS_IPV6_REG1); 352 efx_reado(efx, &temp, FR_CZ_RX_RSS_IPV6_REG1);
353 memcpy(efx->rx_hash_key, &temp, sizeof(temp)); 353 memcpy(efx->rss_context.rx_hash_key, &temp, sizeof(temp));
354 efx_reado(efx, &temp, FR_CZ_RX_RSS_IPV6_REG2); 354 efx_reado(efx, &temp, FR_CZ_RX_RSS_IPV6_REG2);
355 memcpy(efx->rx_hash_key + sizeof(temp), &temp, sizeof(temp)); 355 memcpy(efx->rss_context.rx_hash_key + sizeof(temp), &temp, sizeof(temp));
356 efx_reado(efx, &temp, FR_CZ_RX_RSS_IPV6_REG3); 356 efx_reado(efx, &temp, FR_CZ_RX_RSS_IPV6_REG3);
357 memcpy(efx->rx_hash_key + 2 * sizeof(temp), &temp, 357 memcpy(efx->rss_context.rx_hash_key + 2 * sizeof(temp), &temp,
358 FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH / 8); 358 FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH / 8);
359 efx_farch_rx_pull_indir_table(efx); 359 efx_farch_rx_pull_indir_table(efx);
360 return 0; 360 return 0;
@@ -367,26 +367,26 @@ static int siena_rx_push_rss_config(struct efx_nic *efx, bool user,
367 367
368 /* Set hash key for IPv4 */ 368 /* Set hash key for IPv4 */
369 if (key) 369 if (key)
370 memcpy(efx->rx_hash_key, key, sizeof(temp)); 370 memcpy(efx->rss_context.rx_hash_key, key, sizeof(temp));
371 memcpy(&temp, efx->rx_hash_key, sizeof(temp)); 371 memcpy(&temp, efx->rss_context.rx_hash_key, sizeof(temp));
372 efx_writeo(efx, &temp, FR_BZ_RX_RSS_TKEY); 372 efx_writeo(efx, &temp, FR_BZ_RX_RSS_TKEY);
373 373
374 /* Enable IPv6 RSS */ 374 /* Enable IPv6 RSS */
375 BUILD_BUG_ON(sizeof(efx->rx_hash_key) < 375 BUILD_BUG_ON(sizeof(efx->rss_context.rx_hash_key) <
376 2 * sizeof(temp) + FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH / 8 || 376 2 * sizeof(temp) + FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH / 8 ||
377 FRF_CZ_RX_RSS_IPV6_TKEY_HI_LBN != 0); 377 FRF_CZ_RX_RSS_IPV6_TKEY_HI_LBN != 0);
378 memcpy(&temp, efx->rx_hash_key, sizeof(temp)); 378 memcpy(&temp, efx->rss_context.rx_hash_key, sizeof(temp));
379 efx_writeo(efx, &temp, FR_CZ_RX_RSS_IPV6_REG1); 379 efx_writeo(efx, &temp, FR_CZ_RX_RSS_IPV6_REG1);
380 memcpy(&temp, efx->rx_hash_key + sizeof(temp), sizeof(temp)); 380 memcpy(&temp, efx->rss_context.rx_hash_key + sizeof(temp), sizeof(temp));
381 efx_writeo(efx, &temp, FR_CZ_RX_RSS_IPV6_REG2); 381 efx_writeo(efx, &temp, FR_CZ_RX_RSS_IPV6_REG2);
382 EFX_POPULATE_OWORD_2(temp, FRF_CZ_RX_RSS_IPV6_THASH_ENABLE, 1, 382 EFX_POPULATE_OWORD_2(temp, FRF_CZ_RX_RSS_IPV6_THASH_ENABLE, 1,
383 FRF_CZ_RX_RSS_IPV6_IP_THASH_ENABLE, 1); 383 FRF_CZ_RX_RSS_IPV6_IP_THASH_ENABLE, 1);
384 memcpy(&temp, efx->rx_hash_key + 2 * sizeof(temp), 384 memcpy(&temp, efx->rss_context.rx_hash_key + 2 * sizeof(temp),
385 FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH / 8); 385 FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH / 8);
386 efx_writeo(efx, &temp, FR_CZ_RX_RSS_IPV6_REG3); 386 efx_writeo(efx, &temp, FR_CZ_RX_RSS_IPV6_REG3);
387 387
388 memcpy(efx->rx_indir_table, rx_indir_table, 388 memcpy(efx->rss_context.rx_indir_table, rx_indir_table,
389 sizeof(efx->rx_indir_table)); 389 sizeof(efx->rss_context.rx_indir_table));
390 efx_farch_rx_push_indir_table(efx); 390 efx_farch_rx_push_indir_table(efx);
391 391
392 return 0; 392 return 0;
@@ -432,8 +432,8 @@ static int siena_init_nic(struct efx_nic *efx)
432 EFX_RX_USR_BUF_SIZE >> 5); 432 EFX_RX_USR_BUF_SIZE >> 5);
433 efx_writeo(efx, &temp, FR_AZ_RX_CFG); 433 efx_writeo(efx, &temp, FR_AZ_RX_CFG);
434 434
435 siena_rx_push_rss_config(efx, false, efx->rx_indir_table, NULL); 435 siena_rx_push_rss_config(efx, false, efx->rss_context.rx_indir_table, NULL);
436 efx->rss_active = true; 436 efx->rss_context.context_id = 0; /* indicates RSS is active */
437 437
438 /* Enable event logging */ 438 /* Enable event logging */
439 rc = efx_mcdi_log_ctrl(efx, true, false, 0); 439 rc = efx_mcdi_log_ctrl(efx, true, false, 0);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
index 5270d26f0bc6..2d5d4aea3bcb 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
@@ -48,26 +48,18 @@
48#define MUX_CLK_NUM_PARENTS 2 48#define MUX_CLK_NUM_PARENTS 2
49 49
50struct meson8b_dwmac { 50struct meson8b_dwmac {
51 struct platform_device *pdev; 51 struct device *dev;
52
53 void __iomem *regs; 52 void __iomem *regs;
54
55 phy_interface_t phy_mode; 53 phy_interface_t phy_mode;
54 struct clk *rgmii_tx_clk;
55 u32 tx_delay_ns;
56};
56 57
58struct meson8b_dwmac_clk_configs {
57 struct clk_mux m250_mux; 59 struct clk_mux m250_mux;
58 struct clk *m250_mux_clk;
59 struct clk *m250_mux_parent[MUX_CLK_NUM_PARENTS];
60
61 struct clk_divider m250_div; 60 struct clk_divider m250_div;
62 struct clk *m250_div_clk;
63
64 struct clk_fixed_factor fixed_div2; 61 struct clk_fixed_factor fixed_div2;
65 struct clk *fixed_div2_clk;
66
67 struct clk_gate rgmii_tx_en; 62 struct clk_gate rgmii_tx_en;
68 struct clk *rgmii_tx_en_clk;
69
70 u32 tx_delay_ns;
71}; 63};
72 64
73static void meson8b_dwmac_mask_bits(struct meson8b_dwmac *dwmac, u32 reg, 65static void meson8b_dwmac_mask_bits(struct meson8b_dwmac *dwmac, u32 reg,
@@ -82,106 +74,99 @@ static void meson8b_dwmac_mask_bits(struct meson8b_dwmac *dwmac, u32 reg,
82 writel(data, dwmac->regs + reg); 74 writel(data, dwmac->regs + reg);
83} 75}
84 76
85static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac *dwmac) 77static struct clk *meson8b_dwmac_register_clk(struct meson8b_dwmac *dwmac,
78 const char *name_suffix,
79 const char **parent_names,
80 int num_parents,
81 const struct clk_ops *ops,
82 struct clk_hw *hw)
86{ 83{
87 struct clk_init_data init; 84 struct clk_init_data init;
88 int i, ret;
89 struct device *dev = &dwmac->pdev->dev;
90 char clk_name[32]; 85 char clk_name[32];
91 const char *clk_div_parents[1]; 86
92 const char *mux_parent_names[MUX_CLK_NUM_PARENTS]; 87 snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(dwmac->dev),
88 name_suffix);
89
90 init.name = clk_name;
91 init.ops = ops;
92 init.flags = CLK_SET_RATE_PARENT;
93 init.parent_names = parent_names;
94 init.num_parents = num_parents;
95
96 hw->init = &init;
97
98 return devm_clk_register(dwmac->dev, hw);
99}
100
101static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac *dwmac)
102{
103 int i, ret;
104 struct clk *clk;
105 struct device *dev = dwmac->dev;
106 const char *parent_name, *mux_parent_names[MUX_CLK_NUM_PARENTS];
107 struct meson8b_dwmac_clk_configs *clk_configs;
108
109 clk_configs = devm_kzalloc(dev, sizeof(*clk_configs), GFP_KERNEL);
110 if (!clk_configs)
111 return -ENOMEM;
93 112
94 /* get the mux parents from DT */ 113 /* get the mux parents from DT */
95 for (i = 0; i < MUX_CLK_NUM_PARENTS; i++) { 114 for (i = 0; i < MUX_CLK_NUM_PARENTS; i++) {
96 char name[16]; 115 char name[16];
97 116
98 snprintf(name, sizeof(name), "clkin%d", i); 117 snprintf(name, sizeof(name), "clkin%d", i);
99 dwmac->m250_mux_parent[i] = devm_clk_get(dev, name); 118 clk = devm_clk_get(dev, name);
100 if (IS_ERR(dwmac->m250_mux_parent[i])) { 119 if (IS_ERR(clk)) {
101 ret = PTR_ERR(dwmac->m250_mux_parent[i]); 120 ret = PTR_ERR(clk);
102 if (ret != -EPROBE_DEFER) 121 if (ret != -EPROBE_DEFER)
103 dev_err(dev, "Missing clock %s\n", name); 122 dev_err(dev, "Missing clock %s\n", name);
104 return ret; 123 return ret;
105 } 124 }
106 125
107 mux_parent_names[i] = 126 mux_parent_names[i] = __clk_get_name(clk);
108 __clk_get_name(dwmac->m250_mux_parent[i]);
109 } 127 }
110 128
111 /* create the m250_mux */ 129 clk_configs->m250_mux.reg = dwmac->regs + PRG_ETH0;
112 snprintf(clk_name, sizeof(clk_name), "%s#m250_sel", dev_name(dev)); 130 clk_configs->m250_mux.shift = PRG_ETH0_CLK_M250_SEL_SHIFT;
113 init.name = clk_name; 131 clk_configs->m250_mux.mask = PRG_ETH0_CLK_M250_SEL_MASK;
114 init.ops = &clk_mux_ops; 132 clk = meson8b_dwmac_register_clk(dwmac, "m250_sel", mux_parent_names,
115 init.flags = CLK_SET_RATE_PARENT; 133 MUX_CLK_NUM_PARENTS, &clk_mux_ops,
116 init.parent_names = mux_parent_names; 134 &clk_configs->m250_mux.hw);
117 init.num_parents = MUX_CLK_NUM_PARENTS; 135 if (WARN_ON(IS_ERR(clk)))
118 136 return PTR_ERR(clk);
119 dwmac->m250_mux.reg = dwmac->regs + PRG_ETH0; 137
120 dwmac->m250_mux.shift = PRG_ETH0_CLK_M250_SEL_SHIFT; 138 parent_name = __clk_get_name(clk);
121 dwmac->m250_mux.mask = PRG_ETH0_CLK_M250_SEL_MASK; 139 clk_configs->m250_div.reg = dwmac->regs + PRG_ETH0;
122 dwmac->m250_mux.flags = 0; 140 clk_configs->m250_div.shift = PRG_ETH0_CLK_M250_DIV_SHIFT;
123 dwmac->m250_mux.table = NULL; 141 clk_configs->m250_div.width = PRG_ETH0_CLK_M250_DIV_WIDTH;
124 dwmac->m250_mux.hw.init = &init; 142 clk_configs->m250_div.flags = CLK_DIVIDER_ONE_BASED |
125
126 dwmac->m250_mux_clk = devm_clk_register(dev, &dwmac->m250_mux.hw);
127 if (WARN_ON(IS_ERR(dwmac->m250_mux_clk)))
128 return PTR_ERR(dwmac->m250_mux_clk);
129
130 /* create the m250_div */
131 snprintf(clk_name, sizeof(clk_name), "%s#m250_div", dev_name(dev));
132 init.name = devm_kstrdup(dev, clk_name, GFP_KERNEL);
133 init.ops = &clk_divider_ops;
134 init.flags = CLK_SET_RATE_PARENT;
135 clk_div_parents[0] = __clk_get_name(dwmac->m250_mux_clk);
136 init.parent_names = clk_div_parents;
137 init.num_parents = ARRAY_SIZE(clk_div_parents);
138
139 dwmac->m250_div.reg = dwmac->regs + PRG_ETH0;
140 dwmac->m250_div.shift = PRG_ETH0_CLK_M250_DIV_SHIFT;
141 dwmac->m250_div.width = PRG_ETH0_CLK_M250_DIV_WIDTH;
142 dwmac->m250_div.hw.init = &init;
143 dwmac->m250_div.flags = CLK_DIVIDER_ONE_BASED |
144 CLK_DIVIDER_ALLOW_ZERO | 143 CLK_DIVIDER_ALLOW_ZERO |
145 CLK_DIVIDER_ROUND_CLOSEST; 144 CLK_DIVIDER_ROUND_CLOSEST;
146 145 clk = meson8b_dwmac_register_clk(dwmac, "m250_div", &parent_name, 1,
147 dwmac->m250_div_clk = devm_clk_register(dev, &dwmac->m250_div.hw); 146 &clk_divider_ops,
148 if (WARN_ON(IS_ERR(dwmac->m250_div_clk))) 147 &clk_configs->m250_div.hw);
149 return PTR_ERR(dwmac->m250_div_clk); 148 if (WARN_ON(IS_ERR(clk)))
150 149 return PTR_ERR(clk);
151 /* create the fixed_div2 */ 150
152 snprintf(clk_name, sizeof(clk_name), "%s#fixed_div2", dev_name(dev)); 151 parent_name = __clk_get_name(clk);
153 init.name = devm_kstrdup(dev, clk_name, GFP_KERNEL); 152 clk_configs->fixed_div2.mult = 1;
154 init.ops = &clk_fixed_factor_ops; 153 clk_configs->fixed_div2.div = 2;
155 init.flags = CLK_SET_RATE_PARENT; 154 clk = meson8b_dwmac_register_clk(dwmac, "fixed_div2", &parent_name, 1,
156 clk_div_parents[0] = __clk_get_name(dwmac->m250_div_clk); 155 &clk_fixed_factor_ops,
157 init.parent_names = clk_div_parents; 156 &clk_configs->fixed_div2.hw);
158 init.num_parents = ARRAY_SIZE(clk_div_parents); 157 if (WARN_ON(IS_ERR(clk)))
159 158 return PTR_ERR(clk);
160 dwmac->fixed_div2.mult = 1; 159
161 dwmac->fixed_div2.div = 2; 160 parent_name = __clk_get_name(clk);
162 dwmac->fixed_div2.hw.init = &init; 161 clk_configs->rgmii_tx_en.reg = dwmac->regs + PRG_ETH0;
163 162 clk_configs->rgmii_tx_en.bit_idx = PRG_ETH0_RGMII_TX_CLK_EN;
164 dwmac->fixed_div2_clk = devm_clk_register(dev, &dwmac->fixed_div2.hw); 163 clk = meson8b_dwmac_register_clk(dwmac, "rgmii_tx_en", &parent_name, 1,
165 if (WARN_ON(IS_ERR(dwmac->fixed_div2_clk))) 164 &clk_gate_ops,
166 return PTR_ERR(dwmac->fixed_div2_clk); 165 &clk_configs->rgmii_tx_en.hw);
167 166 if (WARN_ON(IS_ERR(clk)))
168 /* create the rgmii_tx_en */ 167 return PTR_ERR(clk);
169 init.name = devm_kasprintf(dev, GFP_KERNEL, "%s#rgmii_tx_en", 168
170 dev_name(dev)); 169 dwmac->rgmii_tx_clk = clk;
171 init.ops = &clk_gate_ops;
172 init.flags = CLK_SET_RATE_PARENT;
173 clk_div_parents[0] = __clk_get_name(dwmac->fixed_div2_clk);
174 init.parent_names = clk_div_parents;
175 init.num_parents = ARRAY_SIZE(clk_div_parents);
176
177 dwmac->rgmii_tx_en.reg = dwmac->regs + PRG_ETH0;
178 dwmac->rgmii_tx_en.bit_idx = PRG_ETH0_RGMII_TX_CLK_EN;
179 dwmac->rgmii_tx_en.hw.init = &init;
180
181 dwmac->rgmii_tx_en_clk = devm_clk_register(dev,
182 &dwmac->rgmii_tx_en.hw);
183 if (WARN_ON(IS_ERR(dwmac->rgmii_tx_en_clk)))
184 return PTR_ERR(dwmac->rgmii_tx_en_clk);
185 170
186 return 0; 171 return 0;
187} 172}
@@ -219,19 +204,23 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac *dwmac)
219 * a register) based on the line-speed (125MHz for Gbit speeds, 204 * a register) based on the line-speed (125MHz for Gbit speeds,
220 * 25MHz for 100Mbit/s and 2.5MHz for 10Mbit/s). 205 * 25MHz for 100Mbit/s and 2.5MHz for 10Mbit/s).
221 */ 206 */
222 ret = clk_set_rate(dwmac->rgmii_tx_en_clk, 125 * 1000 * 1000); 207 ret = clk_set_rate(dwmac->rgmii_tx_clk, 125 * 1000 * 1000);
223 if (ret) { 208 if (ret) {
224 dev_err(&dwmac->pdev->dev, 209 dev_err(dwmac->dev,
225 "failed to set RGMII TX clock\n"); 210 "failed to set RGMII TX clock\n");
226 return ret; 211 return ret;
227 } 212 }
228 213
229 ret = clk_prepare_enable(dwmac->rgmii_tx_en_clk); 214 ret = clk_prepare_enable(dwmac->rgmii_tx_clk);
230 if (ret) { 215 if (ret) {
231 dev_err(&dwmac->pdev->dev, 216 dev_err(dwmac->dev,
232 "failed to enable the RGMII TX clock\n"); 217 "failed to enable the RGMII TX clock\n");
233 return ret; 218 return ret;
234 } 219 }
220
221 devm_add_action_or_reset(dwmac->dev,
222 (void(*)(void *))clk_disable_unprepare,
223 dwmac->rgmii_tx_clk);
235 break; 224 break;
236 225
237 case PHY_INTERFACE_MODE_RMII: 226 case PHY_INTERFACE_MODE_RMII:
@@ -251,7 +240,7 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac *dwmac)
251 break; 240 break;
252 241
253 default: 242 default:
254 dev_err(&dwmac->pdev->dev, "unsupported phy-mode %s\n", 243 dev_err(dwmac->dev, "unsupported phy-mode %s\n",
255 phy_modes(dwmac->phy_mode)); 244 phy_modes(dwmac->phy_mode));
256 return -EINVAL; 245 return -EINVAL;
257 } 246 }
@@ -292,7 +281,7 @@ static int meson8b_dwmac_probe(struct platform_device *pdev)
292 goto err_remove_config_dt; 281 goto err_remove_config_dt;
293 } 282 }
294 283
295 dwmac->pdev = pdev; 284 dwmac->dev = &pdev->dev;
296 dwmac->phy_mode = of_get_phy_mode(pdev->dev.of_node); 285 dwmac->phy_mode = of_get_phy_mode(pdev->dev.of_node);
297 if (dwmac->phy_mode < 0) { 286 if (dwmac->phy_mode < 0) {
298 dev_err(&pdev->dev, "missing phy-mode property\n"); 287 dev_err(&pdev->dev, "missing phy-mode property\n");
@@ -317,29 +306,16 @@ static int meson8b_dwmac_probe(struct platform_device *pdev)
317 306
318 ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); 307 ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
319 if (ret) 308 if (ret)
320 goto err_clk_disable; 309 goto err_remove_config_dt;
321 310
322 return 0; 311 return 0;
323 312
324err_clk_disable:
325 if (phy_interface_mode_is_rgmii(dwmac->phy_mode))
326 clk_disable_unprepare(dwmac->rgmii_tx_en_clk);
327err_remove_config_dt: 313err_remove_config_dt:
328 stmmac_remove_config_dt(pdev, plat_dat); 314 stmmac_remove_config_dt(pdev, plat_dat);
329 315
330 return ret; 316 return ret;
331} 317}
332 318
333static int meson8b_dwmac_remove(struct platform_device *pdev)
334{
335 struct meson8b_dwmac *dwmac = get_stmmac_bsp_priv(&pdev->dev);
336
337 if (phy_interface_mode_is_rgmii(dwmac->phy_mode))
338 clk_disable_unprepare(dwmac->rgmii_tx_en_clk);
339
340 return stmmac_pltfr_remove(pdev);
341}
342
343static const struct of_device_id meson8b_dwmac_match[] = { 319static const struct of_device_id meson8b_dwmac_match[] = {
344 { .compatible = "amlogic,meson8b-dwmac" }, 320 { .compatible = "amlogic,meson8b-dwmac" },
345 { .compatible = "amlogic,meson-gxbb-dwmac" }, 321 { .compatible = "amlogic,meson-gxbb-dwmac" },
@@ -349,7 +325,7 @@ MODULE_DEVICE_TABLE(of, meson8b_dwmac_match);
349 325
350static struct platform_driver meson8b_dwmac_driver = { 326static struct platform_driver meson8b_dwmac_driver = {
351 .probe = meson8b_dwmac_probe, 327 .probe = meson8b_dwmac_probe,
352 .remove = meson8b_dwmac_remove, 328 .remove = stmmac_pltfr_remove,
353 .driver = { 329 .driver = {
354 .name = "meson8b-dwmac", 330 .name = "meson8b-dwmac",
355 .pm = &stmmac_pltfr_pm_ops, 331 .pm = &stmmac_pltfr_pm_ops,
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
index 63795ecafc8d..46b9ae20ff6c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
@@ -120,7 +120,7 @@ static void dwmac4_tx_queue_priority(struct mac_device_info *hw,
120 writel(value, ioaddr + base_register); 120 writel(value, ioaddr + base_register);
121} 121}
122 122
123static void dwmac4_tx_queue_routing(struct mac_device_info *hw, 123static void dwmac4_rx_queue_routing(struct mac_device_info *hw,
124 u8 packet, u32 queue) 124 u8 packet, u32 queue)
125{ 125{
126 void __iomem *ioaddr = hw->pcsr; 126 void __iomem *ioaddr = hw->pcsr;
@@ -713,7 +713,7 @@ static const struct stmmac_ops dwmac4_ops = {
713 .rx_queue_enable = dwmac4_rx_queue_enable, 713 .rx_queue_enable = dwmac4_rx_queue_enable,
714 .rx_queue_prio = dwmac4_rx_queue_priority, 714 .rx_queue_prio = dwmac4_rx_queue_priority,
715 .tx_queue_prio = dwmac4_tx_queue_priority, 715 .tx_queue_prio = dwmac4_tx_queue_priority,
716 .rx_queue_routing = dwmac4_tx_queue_routing, 716 .rx_queue_routing = dwmac4_rx_queue_routing,
717 .prog_mtl_rx_algorithms = dwmac4_prog_mtl_rx_algorithms, 717 .prog_mtl_rx_algorithms = dwmac4_prog_mtl_rx_algorithms,
718 .prog_mtl_tx_algorithms = dwmac4_prog_mtl_tx_algorithms, 718 .prog_mtl_tx_algorithms = dwmac4_prog_mtl_tx_algorithms,
719 .set_mtl_tx_queue_weight = dwmac4_set_mtl_tx_queue_weight, 719 .set_mtl_tx_queue_weight = dwmac4_set_mtl_tx_queue_weight,
@@ -744,7 +744,7 @@ static const struct stmmac_ops dwmac410_ops = {
744 .rx_queue_enable = dwmac4_rx_queue_enable, 744 .rx_queue_enable = dwmac4_rx_queue_enable,
745 .rx_queue_prio = dwmac4_rx_queue_priority, 745 .rx_queue_prio = dwmac4_rx_queue_priority,
746 .tx_queue_prio = dwmac4_tx_queue_priority, 746 .tx_queue_prio = dwmac4_tx_queue_priority,
747 .rx_queue_routing = dwmac4_tx_queue_routing, 747 .rx_queue_routing = dwmac4_rx_queue_routing,
748 .prog_mtl_rx_algorithms = dwmac4_prog_mtl_rx_algorithms, 748 .prog_mtl_rx_algorithms = dwmac4_prog_mtl_rx_algorithms,
749 .prog_mtl_tx_algorithms = dwmac4_prog_mtl_tx_algorithms, 749 .prog_mtl_tx_algorithms = dwmac4_prog_mtl_tx_algorithms,
750 .set_mtl_tx_queue_weight = dwmac4_set_mtl_tx_queue_weight, 750 .set_mtl_tx_queue_weight = dwmac4_set_mtl_tx_queue_weight,
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
index c728ffa095de..2a6521d33e43 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
@@ -389,6 +389,8 @@ static void dwmac4_rd_prepare_tso_tx_desc(struct dma_desc *p, int is_fs,
389 389
390static void dwmac4_release_tx_desc(struct dma_desc *p, int mode) 390static void dwmac4_release_tx_desc(struct dma_desc *p, int mode)
391{ 391{
392 p->des0 = 0;
393 p->des1 = 0;
392 p->des2 = 0; 394 p->des2 = 0;
393 p->des3 = 0; 395 p->des3 = 0;
394} 396}
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index a916e13624eb..75161e1b7e55 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -58,6 +58,7 @@ struct stmmac_tx_queue {
58 unsigned int dirty_tx; 58 unsigned int dirty_tx;
59 dma_addr_t dma_tx_phy; 59 dma_addr_t dma_tx_phy;
60 u32 tx_tail_addr; 60 u32 tx_tail_addr;
61 u32 mss;
61}; 62};
62 63
63struct stmmac_rx_queue { 64struct stmmac_rx_queue {
@@ -138,7 +139,6 @@ struct stmmac_priv {
138 spinlock_t ptp_lock; 139 spinlock_t ptp_lock;
139 void __iomem *mmcaddr; 140 void __iomem *mmcaddr;
140 void __iomem *ptpaddr; 141 void __iomem *ptpaddr;
141 u32 mss;
142 142
143#ifdef CONFIG_DEBUG_FS 143#ifdef CONFIG_DEBUG_FS
144 struct dentry *dbgfs_dir; 144 struct dentry *dbgfs_dir;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 7ad841434ec8..a9856a8bf8ad 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1355,6 +1355,7 @@ static int init_dma_tx_desc_rings(struct net_device *dev)
1355 1355
1356 tx_q->dirty_tx = 0; 1356 tx_q->dirty_tx = 0;
1357 tx_q->cur_tx = 0; 1357 tx_q->cur_tx = 0;
1358 tx_q->mss = 0;
1358 1359
1359 netdev_tx_reset_queue(netdev_get_tx_queue(priv->dev, queue)); 1360 netdev_tx_reset_queue(netdev_get_tx_queue(priv->dev, queue));
1360 } 1361 }
@@ -1843,6 +1844,11 @@ static void stmmac_tx_clean(struct stmmac_priv *priv, u32 queue)
1843 if (unlikely(status & tx_dma_own)) 1844 if (unlikely(status & tx_dma_own))
1844 break; 1845 break;
1845 1846
1847 /* Make sure descriptor fields are read after reading
1848 * the own bit.
1849 */
1850 dma_rmb();
1851
1846 /* Just consider the last segment and ...*/ 1852 /* Just consider the last segment and ...*/
1847 if (likely(!(status & tx_not_ls))) { 1853 if (likely(!(status & tx_not_ls))) {
1848 /* ... verify the status error condition */ 1854 /* ... verify the status error condition */
@@ -1946,6 +1952,7 @@ static void stmmac_tx_err(struct stmmac_priv *priv, u32 chan)
1946 (i == DMA_TX_SIZE - 1)); 1952 (i == DMA_TX_SIZE - 1));
1947 tx_q->dirty_tx = 0; 1953 tx_q->dirty_tx = 0;
1948 tx_q->cur_tx = 0; 1954 tx_q->cur_tx = 0;
1955 tx_q->mss = 0;
1949 netdev_tx_reset_queue(netdev_get_tx_queue(priv->dev, chan)); 1956 netdev_tx_reset_queue(netdev_get_tx_queue(priv->dev, chan));
1950 stmmac_start_tx_dma(priv, chan); 1957 stmmac_start_tx_dma(priv, chan);
1951 1958
@@ -2430,7 +2437,7 @@ static void stmmac_mac_config_rx_queues_routing(struct stmmac_priv *priv)
2430 continue; 2437 continue;
2431 2438
2432 packet = priv->plat->rx_queues_cfg[queue].pkt_route; 2439 packet = priv->plat->rx_queues_cfg[queue].pkt_route;
2433 priv->hw->mac->rx_queue_prio(priv->hw, packet, queue); 2440 priv->hw->mac->rx_queue_routing(priv->hw, packet, queue);
2434 } 2441 }
2435} 2442}
2436 2443
@@ -2632,7 +2639,6 @@ static int stmmac_open(struct net_device *dev)
2632 2639
2633 priv->dma_buf_sz = STMMAC_ALIGN(buf_sz); 2640 priv->dma_buf_sz = STMMAC_ALIGN(buf_sz);
2634 priv->rx_copybreak = STMMAC_RX_COPYBREAK; 2641 priv->rx_copybreak = STMMAC_RX_COPYBREAK;
2635 priv->mss = 0;
2636 2642
2637 ret = alloc_dma_desc_resources(priv); 2643 ret = alloc_dma_desc_resources(priv);
2638 if (ret < 0) { 2644 if (ret < 0) {
@@ -2793,6 +2799,7 @@ static void stmmac_tso_allocator(struct stmmac_priv *priv, unsigned int des,
2793 2799
2794 while (tmp_len > 0) { 2800 while (tmp_len > 0) {
2795 tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, DMA_TX_SIZE); 2801 tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, DMA_TX_SIZE);
2802 WARN_ON(tx_q->tx_skbuff[tx_q->cur_tx]);
2796 desc = tx_q->dma_tx + tx_q->cur_tx; 2803 desc = tx_q->dma_tx + tx_q->cur_tx;
2797 2804
2798 desc->des0 = cpu_to_le32(des + (total_len - tmp_len)); 2805 desc->des0 = cpu_to_le32(des + (total_len - tmp_len));
@@ -2872,11 +2879,12 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
2872 mss = skb_shinfo(skb)->gso_size; 2879 mss = skb_shinfo(skb)->gso_size;
2873 2880
2874 /* set new MSS value if needed */ 2881 /* set new MSS value if needed */
2875 if (mss != priv->mss) { 2882 if (mss != tx_q->mss) {
2876 mss_desc = tx_q->dma_tx + tx_q->cur_tx; 2883 mss_desc = tx_q->dma_tx + tx_q->cur_tx;
2877 priv->hw->desc->set_mss(mss_desc, mss); 2884 priv->hw->desc->set_mss(mss_desc, mss);
2878 priv->mss = mss; 2885 tx_q->mss = mss;
2879 tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, DMA_TX_SIZE); 2886 tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, DMA_TX_SIZE);
2887 WARN_ON(tx_q->tx_skbuff[tx_q->cur_tx]);
2880 } 2888 }
2881 2889
2882 if (netif_msg_tx_queued(priv)) { 2890 if (netif_msg_tx_queued(priv)) {
@@ -2887,6 +2895,7 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
2887 } 2895 }
2888 2896
2889 first_entry = tx_q->cur_tx; 2897 first_entry = tx_q->cur_tx;
2898 WARN_ON(tx_q->tx_skbuff[first_entry]);
2890 2899
2891 desc = tx_q->dma_tx + first_entry; 2900 desc = tx_q->dma_tx + first_entry;
2892 first = desc; 2901 first = desc;
@@ -2926,7 +2935,6 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
2926 2935
2927 tx_q->tx_skbuff_dma[tx_q->cur_tx].buf = des; 2936 tx_q->tx_skbuff_dma[tx_q->cur_tx].buf = des;
2928 tx_q->tx_skbuff_dma[tx_q->cur_tx].len = skb_frag_size(frag); 2937 tx_q->tx_skbuff_dma[tx_q->cur_tx].len = skb_frag_size(frag);
2929 tx_q->tx_skbuff[tx_q->cur_tx] = NULL;
2930 tx_q->tx_skbuff_dma[tx_q->cur_tx].map_as_page = true; 2938 tx_q->tx_skbuff_dma[tx_q->cur_tx].map_as_page = true;
2931 } 2939 }
2932 2940
@@ -2980,14 +2988,21 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
2980 tcp_hdrlen(skb) / 4, (skb->len - proto_hdr_len)); 2988 tcp_hdrlen(skb) / 4, (skb->len - proto_hdr_len));
2981 2989
2982 /* If context desc is used to change MSS */ 2990 /* If context desc is used to change MSS */
2983 if (mss_desc) 2991 if (mss_desc) {
2992 /* Make sure that first descriptor has been completely
2993 * written, including its own bit. This is because MSS is
2994 * actually before first descriptor, so we need to make
2995 * sure that MSS's own bit is the last thing written.
2996 */
2997 dma_wmb();
2984 priv->hw->desc->set_tx_owner(mss_desc); 2998 priv->hw->desc->set_tx_owner(mss_desc);
2999 }
2985 3000
2986 /* The own bit must be the latest setting done when prepare the 3001 /* The own bit must be the latest setting done when prepare the
2987 * descriptor and then barrier is needed to make sure that 3002 * descriptor and then barrier is needed to make sure that
2988 * all is coherent before granting the DMA engine. 3003 * all is coherent before granting the DMA engine.
2989 */ 3004 */
2990 dma_wmb(); 3005 wmb();
2991 3006
2992 if (netif_msg_pktdata(priv)) { 3007 if (netif_msg_pktdata(priv)) {
2993 pr_info("%s: curr=%d dirty=%d f=%d, e=%d, f_p=%p, nfrags %d\n", 3008 pr_info("%s: curr=%d dirty=%d f=%d, e=%d, f_p=%p, nfrags %d\n",
@@ -3062,6 +3077,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
3062 3077
3063 entry = tx_q->cur_tx; 3078 entry = tx_q->cur_tx;
3064 first_entry = entry; 3079 first_entry = entry;
3080 WARN_ON(tx_q->tx_skbuff[first_entry]);
3065 3081
3066 csum_insertion = (skb->ip_summed == CHECKSUM_PARTIAL); 3082 csum_insertion = (skb->ip_summed == CHECKSUM_PARTIAL);
3067 3083
@@ -3090,6 +3106,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
3090 bool last_segment = (i == (nfrags - 1)); 3106 bool last_segment = (i == (nfrags - 1));
3091 3107
3092 entry = STMMAC_GET_ENTRY(entry, DMA_TX_SIZE); 3108 entry = STMMAC_GET_ENTRY(entry, DMA_TX_SIZE);
3109 WARN_ON(tx_q->tx_skbuff[entry]);
3093 3110
3094 if (likely(priv->extend_desc)) 3111 if (likely(priv->extend_desc))
3095 desc = (struct dma_desc *)(tx_q->dma_etx + entry); 3112 desc = (struct dma_desc *)(tx_q->dma_etx + entry);
@@ -3101,8 +3118,6 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
3101 if (dma_mapping_error(priv->device, des)) 3118 if (dma_mapping_error(priv->device, des))
3102 goto dma_map_err; /* should reuse desc w/o issues */ 3119 goto dma_map_err; /* should reuse desc w/o issues */
3103 3120
3104 tx_q->tx_skbuff[entry] = NULL;
3105
3106 tx_q->tx_skbuff_dma[entry].buf = des; 3121 tx_q->tx_skbuff_dma[entry].buf = des;
3107 if (unlikely(priv->synopsys_id >= DWMAC_CORE_4_00)) 3122 if (unlikely(priv->synopsys_id >= DWMAC_CORE_4_00))
3108 desc->des0 = cpu_to_le32(des); 3123 desc->des0 = cpu_to_le32(des);
@@ -3211,7 +3226,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
3211 * descriptor and then barrier is needed to make sure that 3226 * descriptor and then barrier is needed to make sure that
3212 * all is coherent before granting the DMA engine. 3227 * all is coherent before granting the DMA engine.
3213 */ 3228 */
3214 dma_wmb(); 3229 wmb();
3215 } 3230 }
3216 3231
3217 netdev_tx_sent_queue(netdev_get_tx_queue(dev, queue), skb->len); 3232 netdev_tx_sent_queue(netdev_get_tx_queue(dev, queue), skb->len);
@@ -4436,6 +4451,7 @@ static void stmmac_reset_queues_param(struct stmmac_priv *priv)
4436 4451
4437 tx_q->cur_tx = 0; 4452 tx_q->cur_tx = 0;
4438 tx_q->dirty_tx = 0; 4453 tx_q->dirty_tx = 0;
4454 tx_q->mss = 0;
4439 } 4455 }
4440} 4456}
4441 4457
@@ -4481,11 +4497,6 @@ int stmmac_resume(struct device *dev)
4481 4497
4482 stmmac_reset_queues_param(priv); 4498 stmmac_reset_queues_param(priv);
4483 4499
4484 /* reset private mss value to force mss context settings at
4485 * next tso xmit (only used for gmac4).
4486 */
4487 priv->mss = 0;
4488
4489 stmmac_clear_descriptors(priv); 4500 stmmac_clear_descriptors(priv);
4490 4501
4491 stmmac_hw_setup(ndev, false); 4502 stmmac_hw_setup(ndev, false);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 05f122b8424a..ebd3e5ffa73c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -135,13 +135,14 @@ static struct stmmac_axi *stmmac_axi_setup(struct platform_device *pdev)
135 * stmmac_mtl_setup - parse DT parameters for multiple queues configuration 135 * stmmac_mtl_setup - parse DT parameters for multiple queues configuration
136 * @pdev: platform device 136 * @pdev: platform device
137 */ 137 */
138static void stmmac_mtl_setup(struct platform_device *pdev, 138static int stmmac_mtl_setup(struct platform_device *pdev,
139 struct plat_stmmacenet_data *plat) 139 struct plat_stmmacenet_data *plat)
140{ 140{
141 struct device_node *q_node; 141 struct device_node *q_node;
142 struct device_node *rx_node; 142 struct device_node *rx_node;
143 struct device_node *tx_node; 143 struct device_node *tx_node;
144 u8 queue = 0; 144 u8 queue = 0;
145 int ret = 0;
145 146
146 /* For backwards-compatibility with device trees that don't have any 147 /* For backwards-compatibility with device trees that don't have any
147 * snps,mtl-rx-config or snps,mtl-tx-config properties, we fall back 148 * snps,mtl-rx-config or snps,mtl-tx-config properties, we fall back
@@ -159,12 +160,12 @@ static void stmmac_mtl_setup(struct platform_device *pdev,
159 160
160 rx_node = of_parse_phandle(pdev->dev.of_node, "snps,mtl-rx-config", 0); 161 rx_node = of_parse_phandle(pdev->dev.of_node, "snps,mtl-rx-config", 0);
161 if (!rx_node) 162 if (!rx_node)
162 return; 163 return ret;
163 164
164 tx_node = of_parse_phandle(pdev->dev.of_node, "snps,mtl-tx-config", 0); 165 tx_node = of_parse_phandle(pdev->dev.of_node, "snps,mtl-tx-config", 0);
165 if (!tx_node) { 166 if (!tx_node) {
166 of_node_put(rx_node); 167 of_node_put(rx_node);
167 return; 168 return ret;
168 } 169 }
169 170
170 /* Processing RX queues common config */ 171 /* Processing RX queues common config */
@@ -220,6 +221,11 @@ static void stmmac_mtl_setup(struct platform_device *pdev,
220 221
221 queue++; 222 queue++;
222 } 223 }
224 if (queue != plat->rx_queues_to_use) {
225 ret = -EINVAL;
226 dev_err(&pdev->dev, "Not all RX queues were configured\n");
227 goto out;
228 }
223 229
224 /* Processing TX queues common config */ 230 /* Processing TX queues common config */
225 if (of_property_read_u32(tx_node, "snps,tx-queues-to-use", 231 if (of_property_read_u32(tx_node, "snps,tx-queues-to-use",
@@ -281,10 +287,18 @@ static void stmmac_mtl_setup(struct platform_device *pdev,
281 287
282 queue++; 288 queue++;
283 } 289 }
290 if (queue != plat->tx_queues_to_use) {
291 ret = -EINVAL;
292 dev_err(&pdev->dev, "Not all TX queues were configured\n");
293 goto out;
294 }
284 295
296out:
285 of_node_put(rx_node); 297 of_node_put(rx_node);
286 of_node_put(tx_node); 298 of_node_put(tx_node);
287 of_node_put(q_node); 299 of_node_put(q_node);
300
301 return ret;
288} 302}
289 303
290/** 304/**
@@ -376,6 +390,7 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
376 struct device_node *np = pdev->dev.of_node; 390 struct device_node *np = pdev->dev.of_node;
377 struct plat_stmmacenet_data *plat; 391 struct plat_stmmacenet_data *plat;
378 struct stmmac_dma_cfg *dma_cfg; 392 struct stmmac_dma_cfg *dma_cfg;
393 int rc;
379 394
380 plat = devm_kzalloc(&pdev->dev, sizeof(*plat), GFP_KERNEL); 395 plat = devm_kzalloc(&pdev->dev, sizeof(*plat), GFP_KERNEL);
381 if (!plat) 396 if (!plat)
@@ -402,8 +417,9 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
402 dev_warn(&pdev->dev, "snps,phy-addr property is deprecated\n"); 417 dev_warn(&pdev->dev, "snps,phy-addr property is deprecated\n");
403 418
404 /* To Configure PHY by using all device-tree supported properties */ 419 /* To Configure PHY by using all device-tree supported properties */
405 if (stmmac_dt_phy(plat, np, &pdev->dev)) 420 rc = stmmac_dt_phy(plat, np, &pdev->dev);
406 return ERR_PTR(-ENODEV); 421 if (rc)
422 return ERR_PTR(rc);
407 423
408 of_property_read_u32(np, "tx-fifo-depth", &plat->tx_fifo_size); 424 of_property_read_u32(np, "tx-fifo-depth", &plat->tx_fifo_size);
409 425
@@ -499,7 +515,11 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
499 515
500 plat->axi = stmmac_axi_setup(pdev); 516 plat->axi = stmmac_axi_setup(pdev);
501 517
502 stmmac_mtl_setup(pdev, plat); 518 rc = stmmac_mtl_setup(pdev, plat);
519 if (rc) {
520 stmmac_remove_config_dt(pdev, plat);
521 return ERR_PTR(rc);
522 }
503 523
504 /* clock setup */ 524 /* clock setup */
505 plat->stmmac_clk = devm_clk_get(&pdev->dev, 525 plat->stmmac_clk = devm_clk_get(&pdev->dev,
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index b2b30c9df037..1b4af54a4968 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -120,14 +120,18 @@ do { \
120#define CPDMA_RXCP 0x60 120#define CPDMA_RXCP 0x60
121 121
122#define CPSW_POLL_WEIGHT 64 122#define CPSW_POLL_WEIGHT 64
123#define CPSW_RX_VLAN_ENCAP_HDR_SIZE 4
123#define CPSW_MIN_PACKET_SIZE (VLAN_ETH_ZLEN) 124#define CPSW_MIN_PACKET_SIZE (VLAN_ETH_ZLEN)
124#define CPSW_MAX_PACKET_SIZE (VLAN_ETH_FRAME_LEN + ETH_FCS_LEN) 125#define CPSW_MAX_PACKET_SIZE (VLAN_ETH_FRAME_LEN +\
126 ETH_FCS_LEN +\
127 CPSW_RX_VLAN_ENCAP_HDR_SIZE)
125 128
126#define RX_PRIORITY_MAPPING 0x76543210 129#define RX_PRIORITY_MAPPING 0x76543210
127#define TX_PRIORITY_MAPPING 0x33221100 130#define TX_PRIORITY_MAPPING 0x33221100
128#define CPDMA_TX_PRIORITY_MAP 0x01234567 131#define CPDMA_TX_PRIORITY_MAP 0x01234567
129 132
130#define CPSW_VLAN_AWARE BIT(1) 133#define CPSW_VLAN_AWARE BIT(1)
134#define CPSW_RX_VLAN_ENCAP BIT(2)
131#define CPSW_ALE_VLAN_AWARE 1 135#define CPSW_ALE_VLAN_AWARE 1
132 136
133#define CPSW_FIFO_NORMAL_MODE (0 << 16) 137#define CPSW_FIFO_NORMAL_MODE (0 << 16)
@@ -148,6 +152,18 @@ do { \
148#define CPSW_MAX_QUEUES 8 152#define CPSW_MAX_QUEUES 8
149#define CPSW_CPDMA_DESCS_POOL_SIZE_DEFAULT 256 153#define CPSW_CPDMA_DESCS_POOL_SIZE_DEFAULT 256
150 154
155#define CPSW_RX_VLAN_ENCAP_HDR_PRIO_SHIFT 29
156#define CPSW_RX_VLAN_ENCAP_HDR_PRIO_MSK GENMASK(2, 0)
157#define CPSW_RX_VLAN_ENCAP_HDR_VID_SHIFT 16
158#define CPSW_RX_VLAN_ENCAP_HDR_PKT_TYPE_SHIFT 8
159#define CPSW_RX_VLAN_ENCAP_HDR_PKT_TYPE_MSK GENMASK(1, 0)
160enum {
161 CPSW_RX_VLAN_ENCAP_HDR_PKT_VLAN_TAG = 0,
162 CPSW_RX_VLAN_ENCAP_HDR_PKT_RESERV,
163 CPSW_RX_VLAN_ENCAP_HDR_PKT_PRIO_TAG,
164 CPSW_RX_VLAN_ENCAP_HDR_PKT_UNTAG,
165};
166
151static int debug_level; 167static int debug_level;
152module_param(debug_level, int, 0); 168module_param(debug_level, int, 0);
153MODULE_PARM_DESC(debug_level, "cpsw debug level (NETIF_MSG bits)"); 169MODULE_PARM_DESC(debug_level, "cpsw debug level (NETIF_MSG bits)");
@@ -718,6 +734,49 @@ static void cpsw_tx_handler(void *token, int len, int status)
718 dev_kfree_skb_any(skb); 734 dev_kfree_skb_any(skb);
719} 735}
720 736
737static void cpsw_rx_vlan_encap(struct sk_buff *skb)
738{
739 struct cpsw_priv *priv = netdev_priv(skb->dev);
740 struct cpsw_common *cpsw = priv->cpsw;
741 u32 rx_vlan_encap_hdr = *((u32 *)skb->data);
742 u16 vtag, vid, prio, pkt_type;
743
744 /* Remove VLAN header encapsulation word */
745 skb_pull(skb, CPSW_RX_VLAN_ENCAP_HDR_SIZE);
746
747 pkt_type = (rx_vlan_encap_hdr >>
748 CPSW_RX_VLAN_ENCAP_HDR_PKT_TYPE_SHIFT) &
749 CPSW_RX_VLAN_ENCAP_HDR_PKT_TYPE_MSK;
750 /* Ignore unknown & Priority-tagged packets*/
751 if (pkt_type == CPSW_RX_VLAN_ENCAP_HDR_PKT_RESERV ||
752 pkt_type == CPSW_RX_VLAN_ENCAP_HDR_PKT_PRIO_TAG)
753 return;
754
755 vid = (rx_vlan_encap_hdr >>
756 CPSW_RX_VLAN_ENCAP_HDR_VID_SHIFT) &
757 VLAN_VID_MASK;
758 /* Ignore vid 0 and pass packet as is */
759 if (!vid)
760 return;
761 /* Ignore default vlans in dual mac mode */
762 if (cpsw->data.dual_emac &&
763 vid == cpsw->slaves[priv->emac_port].port_vlan)
764 return;
765
766 prio = (rx_vlan_encap_hdr >>
767 CPSW_RX_VLAN_ENCAP_HDR_PRIO_SHIFT) &
768 CPSW_RX_VLAN_ENCAP_HDR_PRIO_MSK;
769
770 vtag = (prio << VLAN_PRIO_SHIFT) | vid;
771 __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vtag);
772
773 /* strip vlan tag for VLAN-tagged packet */
774 if (pkt_type == CPSW_RX_VLAN_ENCAP_HDR_PKT_VLAN_TAG) {
775 memmove(skb->data + VLAN_HLEN, skb->data, 2 * ETH_ALEN);
776 skb_pull(skb, VLAN_HLEN);
777 }
778}
779
721static void cpsw_rx_handler(void *token, int len, int status) 780static void cpsw_rx_handler(void *token, int len, int status)
722{ 781{
723 struct cpdma_chan *ch; 782 struct cpdma_chan *ch;
@@ -752,6 +811,8 @@ static void cpsw_rx_handler(void *token, int len, int status)
752 if (new_skb) { 811 if (new_skb) {
753 skb_copy_queue_mapping(new_skb, skb); 812 skb_copy_queue_mapping(new_skb, skb);
754 skb_put(skb, len); 813 skb_put(skb, len);
814 if (status & CPDMA_RX_VLAN_ENCAP)
815 cpsw_rx_vlan_encap(skb);
755 cpts_rx_timestamp(cpsw->cpts, skb); 816 cpts_rx_timestamp(cpsw->cpts, skb);
756 skb->protocol = eth_type_trans(skb, ndev); 817 skb->protocol = eth_type_trans(skb, ndev);
757 netif_receive_skb(skb); 818 netif_receive_skb(skb);
@@ -1407,7 +1468,7 @@ static void cpsw_init_host_port(struct cpsw_priv *priv)
1407 cpsw_ale_control_set(cpsw->ale, HOST_PORT_NUM, ALE_VLAN_AWARE, 1468 cpsw_ale_control_set(cpsw->ale, HOST_PORT_NUM, ALE_VLAN_AWARE,
1408 CPSW_ALE_VLAN_AWARE); 1469 CPSW_ALE_VLAN_AWARE);
1409 control_reg = readl(&cpsw->regs->control); 1470 control_reg = readl(&cpsw->regs->control);
1410 control_reg |= CPSW_VLAN_AWARE; 1471 control_reg |= CPSW_VLAN_AWARE | CPSW_RX_VLAN_ENCAP;
1411 writel(control_reg, &cpsw->regs->control); 1472 writel(control_reg, &cpsw->regs->control);
1412 fifo_mode = (cpsw->data.dual_emac) ? CPSW_FIFO_DUAL_MAC_MODE : 1473 fifo_mode = (cpsw->data.dual_emac) ? CPSW_FIFO_DUAL_MAC_MODE :
1413 CPSW_FIFO_NORMAL_MODE; 1474 CPSW_FIFO_NORMAL_MODE;
@@ -3123,7 +3184,7 @@ static int cpsw_probe(struct platform_device *pdev)
3123 cpsw->quirk_irq = true; 3184 cpsw->quirk_irq = true;
3124 } 3185 }
3125 3186
3126 ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER; 3187 ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_CTAG_RX;
3127 3188
3128 ndev->netdev_ops = &cpsw_netdev_ops; 3189 ndev->netdev_ops = &cpsw_netdev_ops;
3129 ndev->ethtool_ops = &cpsw_ethtool_ops; 3190 ndev->ethtool_ops = &cpsw_ethtool_ops;
diff --git a/drivers/net/ethernet/ti/davinci_cpdma.c b/drivers/net/ethernet/ti/davinci_cpdma.c
index 6f9173ff9414..31ae04117f0a 100644
--- a/drivers/net/ethernet/ti/davinci_cpdma.c
+++ b/drivers/net/ethernet/ti/davinci_cpdma.c
@@ -1164,7 +1164,7 @@ static int __cpdma_chan_process(struct cpdma_chan *chan)
1164 outlen -= CPDMA_DESC_CRC_LEN; 1164 outlen -= CPDMA_DESC_CRC_LEN;
1165 1165
1166 status = status & (CPDMA_DESC_EOQ | CPDMA_DESC_TD_COMPLETE | 1166 status = status & (CPDMA_DESC_EOQ | CPDMA_DESC_TD_COMPLETE |
1167 CPDMA_DESC_PORT_MASK); 1167 CPDMA_DESC_PORT_MASK | CPDMA_RX_VLAN_ENCAP);
1168 1168
1169 chan->head = desc_from_phys(pool, desc_read(desc, hw_next)); 1169 chan->head = desc_from_phys(pool, desc_read(desc, hw_next));
1170 chan_write(chan, cp, desc_dma); 1170 chan_write(chan, cp, desc_dma);
diff --git a/drivers/net/ethernet/ti/davinci_cpdma.h b/drivers/net/ethernet/ti/davinci_cpdma.h
index fd65ce2b83de..d399af5389b8 100644
--- a/drivers/net/ethernet/ti/davinci_cpdma.h
+++ b/drivers/net/ethernet/ti/davinci_cpdma.h
@@ -19,6 +19,8 @@
19 19
20#define CPDMA_RX_SOURCE_PORT(__status__) ((__status__ >> 16) & 0x7) 20#define CPDMA_RX_SOURCE_PORT(__status__) ((__status__ >> 16) & 0x7)
21 21
22#define CPDMA_RX_VLAN_ENCAP BIT(19)
23
22#define CPDMA_EOI_RX_THRESH 0x0 24#define CPDMA_EOI_RX_THRESH 0x0
23#define CPDMA_EOI_RX 0x1 25#define CPDMA_EOI_RX 0x1
24#define CPDMA_EOI_TX 0x2 26#define CPDMA_EOI_TX 0x2
diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
index b919e89a9b93..516dd59249d7 100644
--- a/drivers/net/geneve.c
+++ b/drivers/net/geneve.c
@@ -1694,6 +1694,7 @@ static struct pernet_operations geneve_net_ops = {
1694 .exit_batch = geneve_exit_batch_net, 1694 .exit_batch = geneve_exit_batch_net,
1695 .id = &geneve_net_id, 1695 .id = &geneve_net_id,
1696 .size = sizeof(struct geneve_net), 1696 .size = sizeof(struct geneve_net),
1697 .async = true,
1697}; 1698};
1698 1699
1699static int __init geneve_init_module(void) 1700static int __init geneve_init_module(void)
diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
index f38e32a7ec9c..127edd23018f 100644
--- a/drivers/net/gtp.c
+++ b/drivers/net/gtp.c
@@ -1325,6 +1325,7 @@ static struct pernet_operations gtp_net_ops = {
1325 .exit = gtp_net_exit, 1325 .exit = gtp_net_exit,
1326 .id = &gtp_net_id, 1326 .id = &gtp_net_id,
1327 .size = sizeof(struct gtp_net), 1327 .size = sizeof(struct gtp_net),
1328 .async = true,
1328}; 1329};
1329 1330
1330static int __init gtp_init(void) 1331static int __init gtp_init(void)
diff --git a/drivers/net/hyperv/Makefile b/drivers/net/hyperv/Makefile
index c8a66827100c..3f25b9c8ea59 100644
--- a/drivers/net/hyperv/Makefile
+++ b/drivers/net/hyperv/Makefile
@@ -1,3 +1,3 @@
1obj-$(CONFIG_HYPERV_NET) += hv_netvsc.o 1obj-$(CONFIG_HYPERV_NET) += hv_netvsc.o
2 2
3hv_netvsc-y := netvsc_drv.o netvsc.o rndis_filter.o 3hv_netvsc-y := netvsc_drv.o netvsc.o rndis_filter.o netvsc_trace.o
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 7472172823f3..4123d081b1c7 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -36,6 +36,7 @@
36#include <asm/sync_bitops.h> 36#include <asm/sync_bitops.h>
37 37
38#include "hyperv_net.h" 38#include "hyperv_net.h"
39#include "netvsc_trace.h"
39 40
40/* 41/*
41 * Switch the data path from the synthetic interface to the VF 42 * Switch the data path from the synthetic interface to the VF
@@ -57,6 +58,8 @@ void netvsc_switch_datapath(struct net_device *ndev, bool vf)
57 init_pkt->msg.v4_msg.active_dp.active_datapath = 58 init_pkt->msg.v4_msg.active_dp.active_datapath =
58 NVSP_DATAPATH_SYNTHETIC; 59 NVSP_DATAPATH_SYNTHETIC;
59 60
61 trace_nvsp_send(ndev, init_pkt);
62
60 vmbus_sendpacket(dev->channel, init_pkt, 63 vmbus_sendpacket(dev->channel, init_pkt,
61 sizeof(struct nvsp_message), 64 sizeof(struct nvsp_message),
62 (unsigned long)init_pkt, 65 (unsigned long)init_pkt,
@@ -129,6 +132,8 @@ static void netvsc_revoke_buf(struct hv_device *device,
129 revoke_packet->msg.v1_msg. 132 revoke_packet->msg.v1_msg.
130 revoke_recv_buf.id = NETVSC_RECEIVE_BUFFER_ID; 133 revoke_recv_buf.id = NETVSC_RECEIVE_BUFFER_ID;
131 134
135 trace_nvsp_send(ndev, revoke_packet);
136
132 ret = vmbus_sendpacket(device->channel, 137 ret = vmbus_sendpacket(device->channel,
133 revoke_packet, 138 revoke_packet,
134 sizeof(struct nvsp_message), 139 sizeof(struct nvsp_message),
@@ -169,6 +174,8 @@ static void netvsc_revoke_buf(struct hv_device *device,
169 revoke_packet->msg.v1_msg.revoke_send_buf.id = 174 revoke_packet->msg.v1_msg.revoke_send_buf.id =
170 NETVSC_SEND_BUFFER_ID; 175 NETVSC_SEND_BUFFER_ID;
171 176
177 trace_nvsp_send(ndev, revoke_packet);
178
172 ret = vmbus_sendpacket(device->channel, 179 ret = vmbus_sendpacket(device->channel,
173 revoke_packet, 180 revoke_packet,
174 sizeof(struct nvsp_message), 181 sizeof(struct nvsp_message),
@@ -298,6 +305,8 @@ static int netvsc_init_buf(struct hv_device *device,
298 init_packet->msg.v1_msg. 305 init_packet->msg.v1_msg.
299 send_recv_buf.id = NETVSC_RECEIVE_BUFFER_ID; 306 send_recv_buf.id = NETVSC_RECEIVE_BUFFER_ID;
300 307
308 trace_nvsp_send(ndev, init_packet);
309
301 /* Send the gpadl notification request */ 310 /* Send the gpadl notification request */
302 ret = vmbus_sendpacket(device->channel, init_packet, 311 ret = vmbus_sendpacket(device->channel, init_packet,
303 sizeof(struct nvsp_message), 312 sizeof(struct nvsp_message),
@@ -377,6 +386,8 @@ static int netvsc_init_buf(struct hv_device *device,
377 net_device->send_buf_gpadl_handle; 386 net_device->send_buf_gpadl_handle;
378 init_packet->msg.v1_msg.send_send_buf.id = NETVSC_SEND_BUFFER_ID; 387 init_packet->msg.v1_msg.send_send_buf.id = NETVSC_SEND_BUFFER_ID;
379 388
389 trace_nvsp_send(ndev, init_packet);
390
380 /* Send the gpadl notification request */ 391 /* Send the gpadl notification request */
381 ret = vmbus_sendpacket(device->channel, init_packet, 392 ret = vmbus_sendpacket(device->channel, init_packet,
382 sizeof(struct nvsp_message), 393 sizeof(struct nvsp_message),
@@ -445,6 +456,8 @@ static int negotiate_nvsp_ver(struct hv_device *device,
445 init_packet->msg.init_msg.init.min_protocol_ver = nvsp_ver; 456 init_packet->msg.init_msg.init.min_protocol_ver = nvsp_ver;
446 init_packet->msg.init_msg.init.max_protocol_ver = nvsp_ver; 457 init_packet->msg.init_msg.init.max_protocol_ver = nvsp_ver;
447 458
459 trace_nvsp_send(ndev, init_packet);
460
448 /* Send the init request */ 461 /* Send the init request */
449 ret = vmbus_sendpacket(device->channel, init_packet, 462 ret = vmbus_sendpacket(device->channel, init_packet,
450 sizeof(struct nvsp_message), 463 sizeof(struct nvsp_message),
@@ -477,6 +490,8 @@ static int negotiate_nvsp_ver(struct hv_device *device,
477 init_packet->msg.v2_msg.send_ndis_config.capability.teaming = 1; 490 init_packet->msg.v2_msg.send_ndis_config.capability.teaming = 1;
478 } 491 }
479 492
493 trace_nvsp_send(ndev, init_packet);
494
480 ret = vmbus_sendpacket(device->channel, init_packet, 495 ret = vmbus_sendpacket(device->channel, init_packet,
481 sizeof(struct nvsp_message), 496 sizeof(struct nvsp_message),
482 (unsigned long)init_packet, 497 (unsigned long)init_packet,
@@ -489,6 +504,7 @@ static int netvsc_connect_vsp(struct hv_device *device,
489 struct netvsc_device *net_device, 504 struct netvsc_device *net_device,
490 const struct netvsc_device_info *device_info) 505 const struct netvsc_device_info *device_info)
491{ 506{
507 struct net_device *ndev = hv_get_drvdata(device);
492 static const u32 ver_list[] = { 508 static const u32 ver_list[] = {
493 NVSP_PROTOCOL_VERSION_1, NVSP_PROTOCOL_VERSION_2, 509 NVSP_PROTOCOL_VERSION_1, NVSP_PROTOCOL_VERSION_2,
494 NVSP_PROTOCOL_VERSION_4, NVSP_PROTOCOL_VERSION_5 510 NVSP_PROTOCOL_VERSION_4, NVSP_PROTOCOL_VERSION_5
@@ -529,6 +545,8 @@ static int netvsc_connect_vsp(struct hv_device *device,
529 send_ndis_ver.ndis_minor_ver = 545 send_ndis_ver.ndis_minor_ver =
530 ndis_version & 0xFFFF; 546 ndis_version & 0xFFFF;
531 547
548 trace_nvsp_send(ndev, init_packet);
549
532 /* Send the init request */ 550 /* Send the init request */
533 ret = vmbus_sendpacket(device->channel, init_packet, 551 ret = vmbus_sendpacket(device->channel, init_packet,
534 sizeof(struct nvsp_message), 552 sizeof(struct nvsp_message),
@@ -747,7 +765,7 @@ static inline int netvsc_send_pkt(
747 struct sk_buff *skb) 765 struct sk_buff *skb)
748{ 766{
749 struct nvsp_message nvmsg; 767 struct nvsp_message nvmsg;
750 struct nvsp_1_message_send_rndis_packet * const rpkt = 768 struct nvsp_1_message_send_rndis_packet *rpkt =
751 &nvmsg.msg.v1_msg.send_rndis_pkt; 769 &nvmsg.msg.v1_msg.send_rndis_pkt;
752 struct netvsc_channel * const nvchan = 770 struct netvsc_channel * const nvchan =
753 &net_device->chan_table[packet->q_idx]; 771 &net_device->chan_table[packet->q_idx];
@@ -776,6 +794,8 @@ static inline int netvsc_send_pkt(
776 if (out_channel->rescind) 794 if (out_channel->rescind)
777 return -ENODEV; 795 return -ENODEV;
778 796
797 trace_nvsp_send_pkt(ndev, out_channel, rpkt);
798
779 if (packet->page_buf_cnt) { 799 if (packet->page_buf_cnt) {
780 if (packet->cp_partial) 800 if (packet->cp_partial)
781 pb += packet->rmsg_pgcnt; 801 pb += packet->rmsg_pgcnt;
@@ -1079,6 +1099,8 @@ static int netvsc_receive(struct net_device *ndev,
1079 + vmxferpage_packet->ranges[i].byte_offset; 1099 + vmxferpage_packet->ranges[i].byte_offset;
1080 u32 buflen = vmxferpage_packet->ranges[i].byte_count; 1100 u32 buflen = vmxferpage_packet->ranges[i].byte_count;
1081 1101
1102 trace_rndis_recv(ndev, q_idx, data);
1103
1082 /* Pass it to the upper layer */ 1104 /* Pass it to the upper layer */
1083 status = rndis_filter_receive(ndev, net_device, 1105 status = rndis_filter_receive(ndev, net_device,
1084 channel, data, buflen); 1106 channel, data, buflen);
@@ -1143,6 +1165,8 @@ static int netvsc_process_raw_pkt(struct hv_device *device,
1143 struct net_device_context *net_device_ctx = netdev_priv(ndev); 1165 struct net_device_context *net_device_ctx = netdev_priv(ndev);
1144 struct nvsp_message *nvmsg = hv_pkt_data(desc); 1166 struct nvsp_message *nvmsg = hv_pkt_data(desc);
1145 1167
1168 trace_nvsp_recv(ndev, channel, nvmsg);
1169
1146 switch (desc->type) { 1170 switch (desc->type) {
1147 case VM_PKT_COMP: 1171 case VM_PKT_COMP:
1148 netvsc_send_completion(net_device, channel, device, 1172 netvsc_send_completion(net_device, channel, device,
diff --git a/drivers/net/hyperv/netvsc_trace.c b/drivers/net/hyperv/netvsc_trace.c
new file mode 100644
index 000000000000..bb0ce5a2bcd5
--- /dev/null
+++ b/drivers/net/hyperv/netvsc_trace.c
@@ -0,0 +1,7 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#include <linux/netdevice.h>
3
4#include "hyperv_net.h"
5
6#define CREATE_TRACE_POINTS
7#include "netvsc_trace.h"
diff --git a/drivers/net/hyperv/netvsc_trace.h b/drivers/net/hyperv/netvsc_trace.h
new file mode 100644
index 000000000000..f7585563dea5
--- /dev/null
+++ b/drivers/net/hyperv/netvsc_trace.h
@@ -0,0 +1,182 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2
3#if !defined(_NETVSC_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
4#define _NETVSC_TRACE_H
5
6#include <linux/tracepoint.h>
7
8#undef TRACE_SYSTEM
9#define TRACE_SYSTEM netvsc
10#define TRACE_INCLUDE_FILE netvsc_trace
11
12TRACE_DEFINE_ENUM(RNDIS_MSG_PACKET);
13TRACE_DEFINE_ENUM(RNDIS_MSG_INDICATE);
14TRACE_DEFINE_ENUM(RNDIS_MSG_INIT);
15TRACE_DEFINE_ENUM(RNDIS_MSG_INIT_C);
16TRACE_DEFINE_ENUM(RNDIS_MSG_HALT);
17TRACE_DEFINE_ENUM(RNDIS_MSG_QUERY);
18TRACE_DEFINE_ENUM(RNDIS_MSG_QUERY_C);
19TRACE_DEFINE_ENUM(RNDIS_MSG_SET);
20TRACE_DEFINE_ENUM(RNDIS_MSG_SET_C);
21TRACE_DEFINE_ENUM(RNDIS_MSG_RESET);
22TRACE_DEFINE_ENUM(RNDIS_MSG_RESET_C);
23TRACE_DEFINE_ENUM(RNDIS_MSG_KEEPALIVE);
24TRACE_DEFINE_ENUM(RNDIS_MSG_KEEPALIVE_C);
25
26#define show_rndis_type(type) \
27 __print_symbolic(type, \
28 { RNDIS_MSG_PACKET, "PACKET" }, \
29 { RNDIS_MSG_INDICATE, "INDICATE", }, \
30 { RNDIS_MSG_INIT, "INIT", }, \
31 { RNDIS_MSG_INIT_C, "INIT_C", }, \
32 { RNDIS_MSG_HALT, "HALT", }, \
33 { RNDIS_MSG_QUERY, "QUERY", }, \
34 { RNDIS_MSG_QUERY_C, "QUERY_C", }, \
35 { RNDIS_MSG_SET, "SET", }, \
36 { RNDIS_MSG_SET_C, "SET_C", }, \
37 { RNDIS_MSG_RESET, "RESET", }, \
38 { RNDIS_MSG_RESET_C, "RESET_C", }, \
39 { RNDIS_MSG_KEEPALIVE, "KEEPALIVE", }, \
40 { RNDIS_MSG_KEEPALIVE_C, "KEEPALIVE_C", })
41
42DECLARE_EVENT_CLASS(rndis_msg_class,
43 TP_PROTO(const struct net_device *ndev, u16 q,
44 const struct rndis_message *msg),
45 TP_ARGS(ndev, q, msg),
46 TP_STRUCT__entry(
47 __string( name, ndev->name )
48 __field( u16, queue )
49 __field( u32, req_id )
50 __field( u32, msg_type )
51 __field( u32, msg_len )
52 ),
53 TP_fast_assign(
54 __assign_str(name, ndev->name);
55 __entry->queue = q;
56 __entry->req_id = msg->msg.init_req.req_id;
57 __entry->msg_type = msg->ndis_msg_type;
58 __entry->msg_len = msg->msg_len;
59 ),
60 TP_printk("dev=%s q=%u req=%#x type=%s msg_len=%u",
61 __get_str(name), __entry->queue, __entry->req_id,
62 show_rndis_type(__entry->msg_type), __entry->msg_len)
63);
64
65DEFINE_EVENT(rndis_msg_class, rndis_send,
66 TP_PROTO(const struct net_device *ndev, u16 q,
67 const struct rndis_message *msg),
68 TP_ARGS(ndev, q, msg)
69);
70
71DEFINE_EVENT(rndis_msg_class, rndis_recv,
72 TP_PROTO(const struct net_device *ndev, u16 q,
73 const struct rndis_message *msg),
74 TP_ARGS(ndev, q, msg)
75);
76
77TRACE_DEFINE_ENUM(NVSP_MSG_TYPE_INIT);
78TRACE_DEFINE_ENUM(NVSP_MSG_TYPE_INIT_COMPLETE);
79TRACE_DEFINE_ENUM(NVSP_MSG1_TYPE_SEND_NDIS_VER);
80TRACE_DEFINE_ENUM(NVSP_MSG1_TYPE_SEND_RECV_BUF);
81TRACE_DEFINE_ENUM(NVSP_MSG1_TYPE_SEND_RECV_BUF_COMPLETE);
82TRACE_DEFINE_ENUM(NVSP_MSG1_TYPE_REVOKE_RECV_BUF);
83TRACE_DEFINE_ENUM(NVSP_MSG1_TYPE_SEND_SEND_BUF);
84TRACE_DEFINE_ENUM(NVSP_MSG1_TYPE_SEND_SEND_BUF_COMPLETE);
85TRACE_DEFINE_ENUM(NVSP_MSG1_TYPE_REVOKE_SEND_BUF);
86TRACE_DEFINE_ENUM(NVSP_MSG1_TYPE_SEND_RNDIS_PKT);
87TRACE_DEFINE_ENUM(NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE);
88TRACE_DEFINE_ENUM(NVSP_MSG2_TYPE_SEND_NDIS_CONFIG);
89
90TRACE_DEFINE_ENUM(NVSP_MSG4_TYPE_SEND_VF_ASSOCIATION);
91TRACE_DEFINE_ENUM(NVSP_MSG4_TYPE_SWITCH_DATA_PATH);
92
93TRACE_DEFINE_ENUM(NVSP_MSG5_TYPE_SUBCHANNEL);
94TRACE_DEFINE_ENUM(NVSP_MSG5_TYPE_SEND_INDIRECTION_TABLE);
95
96#define show_nvsp_type(type) \
97 __print_symbolic(type, \
98 { NVSP_MSG_TYPE_INIT, "INIT" }, \
99 { NVSP_MSG_TYPE_INIT_COMPLETE, "INIT_COMPLETE" }, \
100 { NVSP_MSG1_TYPE_SEND_NDIS_VER, "SEND_NDIS_VER" }, \
101 { NVSP_MSG1_TYPE_SEND_RECV_BUF, "SEND_RECV_BUF" }, \
102 { NVSP_MSG1_TYPE_SEND_RECV_BUF_COMPLETE, "SEND_RECV_BUF_COMPLETE" }, \
103 { NVSP_MSG1_TYPE_REVOKE_RECV_BUF, "REVOKE_RECV_BUF" }, \
104 { NVSP_MSG1_TYPE_SEND_SEND_BUF, "SEND_SEND_BUF" }, \
105 { NVSP_MSG1_TYPE_SEND_SEND_BUF_COMPLETE, "SEND_SEND_BUF_COMPLETE" }, \
106 { NVSP_MSG1_TYPE_REVOKE_SEND_BUF, "REVOKE_SEND_BUF" }, \
107 { NVSP_MSG1_TYPE_SEND_RNDIS_PKT, "SEND_RNDIS_PKT" }, \
108 { NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE, "SEND_RNDIS_PKT_COMPLETE" },\
109 { NVSP_MSG2_TYPE_SEND_NDIS_CONFIG, "SEND_NDIS_CONFIG" }, \
110 { NVSP_MSG4_TYPE_SEND_VF_ASSOCIATION, "SEND_VF_ASSOCIATION" }, \
111 { NVSP_MSG4_TYPE_SWITCH_DATA_PATH, "SWITCH_DATA_PATH" }, \
112 { NVSP_MSG5_TYPE_SUBCHANNEL, "SUBCHANNEL" }, \
113 { NVSP_MSG5_TYPE_SEND_INDIRECTION_TABLE, "SEND_INDIRECTION_TABLE" })
114
115TRACE_EVENT(nvsp_send,
116 TP_PROTO(const struct net_device *ndev,
117 const struct nvsp_message *msg),
118 TP_ARGS(ndev, msg),
119 TP_STRUCT__entry(
120 __string( name, ndev->name )
121 __field( u32, msg_type )
122 ),
123 TP_fast_assign(
124 __assign_str(name, ndev->name);
125 __entry->msg_type = msg->hdr.msg_type;
126 ),
127 TP_printk("dev=%s type=%s",
128 __get_str(name),
129 show_nvsp_type(__entry->msg_type))
130);
131
132TRACE_EVENT(nvsp_send_pkt,
133 TP_PROTO(const struct net_device *ndev,
134 const struct vmbus_channel *chan,
135 const struct nvsp_1_message_send_rndis_packet *rpkt),
136 TP_ARGS(ndev, chan, rpkt),
137 TP_STRUCT__entry(
138 __string( name, ndev->name )
139 __field( u16, qid )
140 __field( u32, channel_type )
141 __field( u32, section_index )
142 __field( u32, section_size )
143 ),
144 TP_fast_assign(
145 __assign_str(name, ndev->name);
146 __entry->qid = chan->offermsg.offer.sub_channel_index;
147 __entry->channel_type = rpkt->channel_type;
148 __entry->section_index = rpkt->send_buf_section_index;
149 __entry->section_size = rpkt->send_buf_section_size;
150 ),
151 TP_printk("dev=%s qid=%u type=%s section=%u size=%d",
152 __get_str(name), __entry->qid,
153 __entry->channel_type ? "CONTROL" : "DATA",
154 __entry->section_index, __entry->section_size)
155);
156
157TRACE_EVENT(nvsp_recv,
158 TP_PROTO(const struct net_device *ndev,
159 const struct vmbus_channel *chan,
160 const struct nvsp_message *msg),
161 TP_ARGS(ndev, chan, msg),
162 TP_STRUCT__entry(
163 __string( name, ndev->name )
164 __field( u16, qid )
165 __field( u32, msg_type )
166 ),
167 TP_fast_assign(
168 __assign_str(name, ndev->name);
169 __entry->qid = chan->offermsg.offer.sub_channel_index;
170 __entry->msg_type = msg->hdr.msg_type;
171 ),
172 TP_printk("dev=%s qid=%u type=%s",
173 __get_str(name), __entry->qid,
174 show_nvsp_type(__entry->msg_type))
175);
176
177#endif /* _NETVSC_TRACE_H */
178
179/* This part must be outside protection */
180#undef TRACE_INCLUDE_PATH
181#define TRACE_INCLUDE_PATH ../../drivers/net/hyperv
182#include <trace/define_trace.h>
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index a6ec41c399d6..020f8bc54386 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -31,6 +31,7 @@
31#include <linux/rtnetlink.h> 31#include <linux/rtnetlink.h>
32 32
33#include "hyperv_net.h" 33#include "hyperv_net.h"
34#include "netvsc_trace.h"
34 35
35static void rndis_set_multicast(struct work_struct *w); 36static void rndis_set_multicast(struct work_struct *w);
36 37
@@ -241,6 +242,8 @@ static int rndis_filter_send_request(struct rndis_device *dev,
241 pb[0].len; 242 pb[0].len;
242 } 243 }
243 244
245 trace_rndis_send(dev->ndev, 0, &req->request_msg);
246
244 rcu_read_lock_bh(); 247 rcu_read_lock_bh();
245 ret = netvsc_send(dev->ndev, packet, NULL, pb, NULL); 248 ret = netvsc_send(dev->ndev, packet, NULL, pb, NULL);
246 rcu_read_unlock_bh(); 249 rcu_read_unlock_bh();
@@ -942,12 +945,11 @@ static bool netvsc_device_idle(const struct netvsc_device *nvdev)
942 return true; 945 return true;
943} 946}
944 947
945static void rndis_filter_halt_device(struct rndis_device *dev) 948static void rndis_filter_halt_device(struct netvsc_device *nvdev,
949 struct rndis_device *dev)
946{ 950{
947 struct rndis_request *request; 951 struct rndis_request *request;
948 struct rndis_halt_request *halt; 952 struct rndis_halt_request *halt;
949 struct net_device_context *net_device_ctx = netdev_priv(dev->ndev);
950 struct netvsc_device *nvdev = rtnl_dereference(net_device_ctx->nvdev);
951 953
952 /* Attempt to do a rndis device halt */ 954 /* Attempt to do a rndis device halt */
953 request = get_rndis_request(dev, RNDIS_MSG_HALT, 955 request = get_rndis_request(dev, RNDIS_MSG_HALT,
@@ -1086,6 +1088,8 @@ void rndis_set_subchannel(struct work_struct *w)
1086 init_packet->msg.v5_msg.subchn_req.op = NVSP_SUBCHANNEL_ALLOCATE; 1088 init_packet->msg.v5_msg.subchn_req.op = NVSP_SUBCHANNEL_ALLOCATE;
1087 init_packet->msg.v5_msg.subchn_req.num_subchannels = 1089 init_packet->msg.v5_msg.subchn_req.num_subchannels =
1088 nvdev->num_chn - 1; 1090 nvdev->num_chn - 1;
1091 trace_nvsp_send(ndev, init_packet);
1092
1089 ret = vmbus_sendpacket(hv_dev->channel, init_packet, 1093 ret = vmbus_sendpacket(hv_dev->channel, init_packet,
1090 sizeof(struct nvsp_message), 1094 sizeof(struct nvsp_message),
1091 (unsigned long)init_packet, 1095 (unsigned long)init_packet,
@@ -1350,7 +1354,7 @@ void rndis_filter_device_remove(struct hv_device *dev,
1350 struct rndis_device *rndis_dev = net_dev->extension; 1354 struct rndis_device *rndis_dev = net_dev->extension;
1351 1355
1352 /* Halt and release the rndis device */ 1356 /* Halt and release the rndis device */
1353 rndis_filter_halt_device(rndis_dev); 1357 rndis_filter_halt_device(net_dev, rndis_dev);
1354 1358
1355 net_dev->extension = NULL; 1359 net_dev->extension = NULL;
1356 1360
diff --git a/drivers/net/ieee802154/Kconfig b/drivers/net/ieee802154/Kconfig
index 303ba4133920..8782f5655e3f 100644
--- a/drivers/net/ieee802154/Kconfig
+++ b/drivers/net/ieee802154/Kconfig
@@ -104,3 +104,14 @@ config IEEE802154_CA8210_DEBUGFS
104 exposes a debugfs node for each CA8210 instance which allows 104 exposes a debugfs node for each CA8210 instance which allows
105 direct use of the Cascoda API, exposing the 802.15.4 MAC 105 direct use of the Cascoda API, exposing the 802.15.4 MAC
106 management entities. 106 management entities.
107
108config IEEE802154_MCR20A
109 tristate "MCR20A transceiver driver"
110 depends on IEEE802154_DRIVERS && MAC802154
111 depends on SPI
112 ---help---
113 Say Y here to enable the MCR20A SPI 802.15.4 wireless
114 controller.
115
116 This driver can also be built as a module. To do so, say M here.
117 the module will be called 'mcr20a'.
diff --git a/drivers/net/ieee802154/Makefile b/drivers/net/ieee802154/Makefile
index bea1de5e726c..104744d5a668 100644
--- a/drivers/net/ieee802154/Makefile
+++ b/drivers/net/ieee802154/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_IEEE802154_CC2520) += cc2520.o
6obj-$(CONFIG_IEEE802154_ATUSB) += atusb.o 6obj-$(CONFIG_IEEE802154_ATUSB) += atusb.o
7obj-$(CONFIG_IEEE802154_ADF7242) += adf7242.o 7obj-$(CONFIG_IEEE802154_ADF7242) += adf7242.o
8obj-$(CONFIG_IEEE802154_CA8210) += ca8210.o 8obj-$(CONFIG_IEEE802154_CA8210) += ca8210.o
9obj-$(CONFIG_IEEE802154_MCR20A) += mcr20a.o
diff --git a/drivers/net/ieee802154/mcr20a.c b/drivers/net/ieee802154/mcr20a.c
new file mode 100644
index 000000000000..d9eb22a52551
--- /dev/null
+++ b/drivers/net/ieee802154/mcr20a.c
@@ -0,0 +1,1413 @@
1/*
2 * Driver for NXP MCR20A 802.15.4 Wireless-PAN Networking controller
3 *
4 * Copyright (C) 2018 Xue Liu <liuxuenetmail@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2
8 * as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/gpio.h>
19#include <linux/spi/spi.h>
20#include <linux/workqueue.h>
21#include <linux/interrupt.h>
22#include <linux/skbuff.h>
23#include <linux/of_gpio.h>
24#include <linux/regmap.h>
25#include <linux/ieee802154.h>
26#include <linux/debugfs.h>
27
28#include <net/mac802154.h>
29#include <net/cfg802154.h>
30
31#include <linux/device.h>
32
33#include "mcr20a.h"
34
35#define SPI_COMMAND_BUFFER 3
36
37#define REGISTER_READ BIT(7)
38#define REGISTER_WRITE (0 << 7)
39#define REGISTER_ACCESS (0 << 6)
40#define PACKET_BUFF_BURST_ACCESS BIT(6)
41#define PACKET_BUFF_BYTE_ACCESS BIT(5)
42
43#define MCR20A_WRITE_REG(x) (x)
44#define MCR20A_READ_REG(x) (REGISTER_READ | (x))
45#define MCR20A_BURST_READ_PACKET_BUF (0xC0)
46#define MCR20A_BURST_WRITE_PACKET_BUF (0x40)
47
48#define MCR20A_CMD_REG 0x80
49#define MCR20A_CMD_REG_MASK 0x3f
50#define MCR20A_CMD_WRITE 0x40
51#define MCR20A_CMD_FB 0x20
52
53/* Number of Interrupt Request Status Register */
54#define MCR20A_IRQSTS_NUM 2 /* only IRQ_STS1 and IRQ_STS2 */
55
56/* MCR20A CCA Type */
57enum {
58 MCR20A_CCA_ED, // energy detect - CCA bit not active,
59 // not to be used for T and CCCA sequences
60 MCR20A_CCA_MODE1, // energy detect - CCA bit ACTIVE
61 MCR20A_CCA_MODE2, // 802.15.4 compliant signal detect - CCA bit ACTIVE
62 MCR20A_CCA_MODE3
63};
64
65enum {
66 MCR20A_XCVSEQ_IDLE = 0x00,
67 MCR20A_XCVSEQ_RX = 0x01,
68 MCR20A_XCVSEQ_TX = 0x02,
69 MCR20A_XCVSEQ_CCA = 0x03,
70 MCR20A_XCVSEQ_TR = 0x04,
71 MCR20A_XCVSEQ_CCCA = 0x05,
72};
73
74/* IEEE-802.15.4 defined constants (2.4 GHz logical channels) */
75#define MCR20A_MIN_CHANNEL (11)
76#define MCR20A_MAX_CHANNEL (26)
77#define MCR20A_CHANNEL_SPACING (5)
78
79/* MCR20A CCA Threshold constans */
80#define MCR20A_MIN_CCA_THRESHOLD (0x6EU)
81#define MCR20A_MAX_CCA_THRESHOLD (0x00U)
82
83/* version 0C */
84#define MCR20A_OVERWRITE_VERSION (0x0C)
85
86/* MCR20A PLL configurations */
87static const u8 PLL_INT[16] = {
88 /* 2405 */ 0x0B, /* 2410 */ 0x0B, /* 2415 */ 0x0B,
89 /* 2420 */ 0x0B, /* 2425 */ 0x0B, /* 2430 */ 0x0B,
90 /* 2435 */ 0x0C, /* 2440 */ 0x0C, /* 2445 */ 0x0C,
91 /* 2450 */ 0x0C, /* 2455 */ 0x0C, /* 2460 */ 0x0C,
92 /* 2465 */ 0x0D, /* 2470 */ 0x0D, /* 2475 */ 0x0D,
93 /* 2480 */ 0x0D
94};
95
96static const u8 PLL_FRAC[16] = {
97 /* 2405 */ 0x28, /* 2410 */ 0x50, /* 2415 */ 0x78,
98 /* 2420 */ 0xA0, /* 2425 */ 0xC8, /* 2430 */ 0xF0,
99 /* 2435 */ 0x18, /* 2440 */ 0x40, /* 2445 */ 0x68,
100 /* 2450 */ 0x90, /* 2455 */ 0xB8, /* 2460 */ 0xE0,
101 /* 2465 */ 0x08, /* 2470 */ 0x30, /* 2475 */ 0x58,
102 /* 2480 */ 0x80
103};
104
105static const struct reg_sequence mar20a_iar_overwrites[] = {
106 { IAR_MISC_PAD_CTRL, 0x02 },
107 { IAR_VCO_CTRL1, 0xB3 },
108 { IAR_VCO_CTRL2, 0x07 },
109 { IAR_PA_TUNING, 0x71 },
110 { IAR_CHF_IBUF, 0x2F },
111 { IAR_CHF_QBUF, 0x2F },
112 { IAR_CHF_IRIN, 0x24 },
113 { IAR_CHF_QRIN, 0x24 },
114 { IAR_CHF_IL, 0x24 },
115 { IAR_CHF_QL, 0x24 },
116 { IAR_CHF_CC1, 0x32 },
117 { IAR_CHF_CCL, 0x1D },
118 { IAR_CHF_CC2, 0x2D },
119 { IAR_CHF_IROUT, 0x24 },
120 { IAR_CHF_QROUT, 0x24 },
121 { IAR_PA_CAL, 0x28 },
122 { IAR_AGC_THR1, 0x55 },
123 { IAR_AGC_THR2, 0x2D },
124 { IAR_ATT_RSSI1, 0x5F },
125 { IAR_ATT_RSSI2, 0x8F },
126 { IAR_RSSI_OFFSET, 0x61 },
127 { IAR_CHF_PMA_GAIN, 0x03 },
128 { IAR_CCA1_THRESH, 0x50 },
129 { IAR_CORR_NVAL, 0x13 },
130 { IAR_ACKDELAY, 0x3D },
131};
132
133#define MCR20A_VALID_CHANNELS (0x07FFF800)
134
135struct mcr20a_platform_data {
136 int rst_gpio;
137};
138
139#define MCR20A_MAX_BUF (127)
140
141#define printdev(X) (&X->spi->dev)
142
143/* regmap information for Direct Access Register (DAR) access */
144#define MCR20A_DAR_WRITE 0x01
145#define MCR20A_DAR_READ 0x00
146#define MCR20A_DAR_NUMREGS 0x3F
147
148/* regmap information for Indirect Access Register (IAR) access */
149#define MCR20A_IAR_ACCESS 0x80
150#define MCR20A_IAR_NUMREGS 0xBEFF
151
152/* Read/Write SPI Commands for DAR and IAR registers. */
153#define MCR20A_READSHORT(reg) ((reg) << 1)
154#define MCR20A_WRITESHORT(reg) ((reg) << 1 | 1)
155#define MCR20A_READLONG(reg) (1 << 15 | (reg) << 5)
156#define MCR20A_WRITELONG(reg) (1 << 15 | (reg) << 5 | 1 << 4)
157
158/* Type definitions for link configuration of instantiable layers */
159#define MCR20A_PHY_INDIRECT_QUEUE_SIZE (12)
160
161static bool
162mcr20a_dar_writeable(struct device *dev, unsigned int reg)
163{
164 switch (reg) {
165 case DAR_IRQ_STS1:
166 case DAR_IRQ_STS2:
167 case DAR_IRQ_STS3:
168 case DAR_PHY_CTRL1:
169 case DAR_PHY_CTRL2:
170 case DAR_PHY_CTRL3:
171 case DAR_PHY_CTRL4:
172 case DAR_SRC_CTRL:
173 case DAR_SRC_ADDRS_SUM_LSB:
174 case DAR_SRC_ADDRS_SUM_MSB:
175 case DAR_T3CMP_LSB:
176 case DAR_T3CMP_MSB:
177 case DAR_T3CMP_USB:
178 case DAR_T2PRIMECMP_LSB:
179 case DAR_T2PRIMECMP_MSB:
180 case DAR_T1CMP_LSB:
181 case DAR_T1CMP_MSB:
182 case DAR_T1CMP_USB:
183 case DAR_T2CMP_LSB:
184 case DAR_T2CMP_MSB:
185 case DAR_T2CMP_USB:
186 case DAR_T4CMP_LSB:
187 case DAR_T4CMP_MSB:
188 case DAR_T4CMP_USB:
189 case DAR_PLL_INT0:
190 case DAR_PLL_FRAC0_LSB:
191 case DAR_PLL_FRAC0_MSB:
192 case DAR_PA_PWR:
193 /* no DAR_ACM */
194 case DAR_OVERWRITE_VER:
195 case DAR_CLK_OUT_CTRL:
196 case DAR_PWR_MODES:
197 return true;
198 default:
199 return false;
200 }
201}
202
203static bool
204mcr20a_dar_readable(struct device *dev, unsigned int reg)
205{
206 bool rc;
207
208 /* all writeable are also readable */
209 rc = mcr20a_dar_writeable(dev, reg);
210 if (rc)
211 return rc;
212
213 /* readonly regs */
214 switch (reg) {
215 case DAR_RX_FRM_LEN:
216 case DAR_CCA1_ED_FNL:
217 case DAR_EVENT_TMR_LSB:
218 case DAR_EVENT_TMR_MSB:
219 case DAR_EVENT_TMR_USB:
220 case DAR_TIMESTAMP_LSB:
221 case DAR_TIMESTAMP_MSB:
222 case DAR_TIMESTAMP_USB:
223 case DAR_SEQ_STATE:
224 case DAR_LQI_VALUE:
225 case DAR_RSSI_CCA_CONT:
226 return true;
227 default:
228 return false;
229 }
230}
231
232static bool
233mcr20a_dar_volatile(struct device *dev, unsigned int reg)
234{
235 /* can be changed during runtime */
236 switch (reg) {
237 case DAR_IRQ_STS1:
238 case DAR_IRQ_STS2:
239 case DAR_IRQ_STS3:
240 /* use them in spi_async and regmap so it's volatile */
241 return true;
242 default:
243 return false;
244 }
245}
246
247static bool
248mcr20a_dar_precious(struct device *dev, unsigned int reg)
249{
250 /* don't clear irq line on read */
251 switch (reg) {
252 case DAR_IRQ_STS1:
253 case DAR_IRQ_STS2:
254 case DAR_IRQ_STS3:
255 return true;
256 default:
257 return false;
258 }
259}
260
261static const struct regmap_config mcr20a_dar_regmap = {
262 .name = "mcr20a_dar",
263 .reg_bits = 8,
264 .val_bits = 8,
265 .write_flag_mask = REGISTER_ACCESS | REGISTER_WRITE,
266 .read_flag_mask = REGISTER_ACCESS | REGISTER_READ,
267 .cache_type = REGCACHE_RBTREE,
268 .writeable_reg = mcr20a_dar_writeable,
269 .readable_reg = mcr20a_dar_readable,
270 .volatile_reg = mcr20a_dar_volatile,
271 .precious_reg = mcr20a_dar_precious,
272 .fast_io = true,
273 .can_multi_write = true,
274};
275
276static bool
277mcr20a_iar_writeable(struct device *dev, unsigned int reg)
278{
279 switch (reg) {
280 case IAR_XTAL_TRIM:
281 case IAR_PMC_LP_TRIM:
282 case IAR_MACPANID0_LSB:
283 case IAR_MACPANID0_MSB:
284 case IAR_MACSHORTADDRS0_LSB:
285 case IAR_MACSHORTADDRS0_MSB:
286 case IAR_MACLONGADDRS0_0:
287 case IAR_MACLONGADDRS0_8:
288 case IAR_MACLONGADDRS0_16:
289 case IAR_MACLONGADDRS0_24:
290 case IAR_MACLONGADDRS0_32:
291 case IAR_MACLONGADDRS0_40:
292 case IAR_MACLONGADDRS0_48:
293 case IAR_MACLONGADDRS0_56:
294 case IAR_RX_FRAME_FILTER:
295 case IAR_PLL_INT1:
296 case IAR_PLL_FRAC1_LSB:
297 case IAR_PLL_FRAC1_MSB:
298 case IAR_MACPANID1_LSB:
299 case IAR_MACPANID1_MSB:
300 case IAR_MACSHORTADDRS1_LSB:
301 case IAR_MACSHORTADDRS1_MSB:
302 case IAR_MACLONGADDRS1_0:
303 case IAR_MACLONGADDRS1_8:
304 case IAR_MACLONGADDRS1_16:
305 case IAR_MACLONGADDRS1_24:
306 case IAR_MACLONGADDRS1_32:
307 case IAR_MACLONGADDRS1_40:
308 case IAR_MACLONGADDRS1_48:
309 case IAR_MACLONGADDRS1_56:
310 case IAR_DUAL_PAN_CTRL:
311 case IAR_DUAL_PAN_DWELL:
312 case IAR_CCA1_THRESH:
313 case IAR_CCA1_ED_OFFSET_COMP:
314 case IAR_LQI_OFFSET_COMP:
315 case IAR_CCA_CTRL:
316 case IAR_CCA2_CORR_PEAKS:
317 case IAR_CCA2_CORR_THRESH:
318 case IAR_TMR_PRESCALE:
319 case IAR_ANT_PAD_CTRL:
320 case IAR_MISC_PAD_CTRL:
321 case IAR_BSM_CTRL:
322 case IAR_RNG:
323 case IAR_RX_WTR_MARK:
324 case IAR_SOFT_RESET:
325 case IAR_TXDELAY:
326 case IAR_ACKDELAY:
327 case IAR_CORR_NVAL:
328 case IAR_ANT_AGC_CTRL:
329 case IAR_AGC_THR1:
330 case IAR_AGC_THR2:
331 case IAR_PA_CAL:
332 case IAR_ATT_RSSI1:
333 case IAR_ATT_RSSI2:
334 case IAR_RSSI_OFFSET:
335 case IAR_XTAL_CTRL:
336 case IAR_CHF_PMA_GAIN:
337 case IAR_CHF_IBUF:
338 case IAR_CHF_QBUF:
339 case IAR_CHF_IRIN:
340 case IAR_CHF_QRIN:
341 case IAR_CHF_IL:
342 case IAR_CHF_QL:
343 case IAR_CHF_CC1:
344 case IAR_CHF_CCL:
345 case IAR_CHF_CC2:
346 case IAR_CHF_IROUT:
347 case IAR_CHF_QROUT:
348 case IAR_PA_TUNING:
349 case IAR_VCO_CTRL1:
350 case IAR_VCO_CTRL2:
351 return true;
352 default:
353 return false;
354 }
355}
356
357static bool
358mcr20a_iar_readable(struct device *dev, unsigned int reg)
359{
360 bool rc;
361
362 /* all writeable are also readable */
363 rc = mcr20a_iar_writeable(dev, reg);
364 if (rc)
365 return rc;
366
367 /* readonly regs */
368 switch (reg) {
369 case IAR_PART_ID:
370 case IAR_DUAL_PAN_STS:
371 case IAR_RX_BYTE_COUNT:
372 case IAR_FILTERFAIL_CODE1:
373 case IAR_FILTERFAIL_CODE2:
374 case IAR_RSSI:
375 return true;
376 default:
377 return false;
378 }
379}
380
381static bool
382mcr20a_iar_volatile(struct device *dev, unsigned int reg)
383{
384/* can be changed during runtime */
385 switch (reg) {
386 case IAR_DUAL_PAN_STS:
387 case IAR_RX_BYTE_COUNT:
388 case IAR_FILTERFAIL_CODE1:
389 case IAR_FILTERFAIL_CODE2:
390 case IAR_RSSI:
391 return true;
392 default:
393 return false;
394 }
395}
396
397static const struct regmap_config mcr20a_iar_regmap = {
398 .name = "mcr20a_iar",
399 .reg_bits = 16,
400 .val_bits = 8,
401 .write_flag_mask = REGISTER_ACCESS | REGISTER_WRITE | IAR_INDEX,
402 .read_flag_mask = REGISTER_ACCESS | REGISTER_READ | IAR_INDEX,
403 .cache_type = REGCACHE_RBTREE,
404 .writeable_reg = mcr20a_iar_writeable,
405 .readable_reg = mcr20a_iar_readable,
406 .volatile_reg = mcr20a_iar_volatile,
407 .fast_io = true,
408};
409
410struct mcr20a_local {
411 struct spi_device *spi;
412
413 struct ieee802154_hw *hw;
414 struct mcr20a_platform_data *pdata;
415 struct regmap *regmap_dar;
416 struct regmap *regmap_iar;
417
418 u8 *buf;
419
420 bool is_tx;
421
422 /* for writing tx buffer */
423 struct spi_message tx_buf_msg;
424 u8 tx_header[1];
425 /* burst buffer write command */
426 struct spi_transfer tx_xfer_header;
427 u8 tx_len[1];
428 /* len of tx packet */
429 struct spi_transfer tx_xfer_len;
430 /* data of tx packet */
431 struct spi_transfer tx_xfer_buf;
432 struct sk_buff *tx_skb;
433
434 /* for read length rxfifo */
435 struct spi_message reg_msg;
436 u8 reg_cmd[1];
437 u8 reg_data[MCR20A_IRQSTS_NUM];
438 struct spi_transfer reg_xfer_cmd;
439 struct spi_transfer reg_xfer_data;
440
441 /* receive handling */
442 struct spi_message rx_buf_msg;
443 u8 rx_header[1];
444 struct spi_transfer rx_xfer_header;
445 u8 rx_lqi[1];
446 struct spi_transfer rx_xfer_lqi;
447 u8 rx_buf[MCR20A_MAX_BUF];
448 struct spi_transfer rx_xfer_buf;
449
450 /* isr handling for reading intstat */
451 struct spi_message irq_msg;
452 u8 irq_header[1];
453 u8 irq_data[MCR20A_IRQSTS_NUM];
454 struct spi_transfer irq_xfer_data;
455 struct spi_transfer irq_xfer_header;
456};
457
458static void
459mcr20a_write_tx_buf_complete(void *context)
460{
461 struct mcr20a_local *lp = context;
462 int ret;
463
464 dev_dbg(printdev(lp), "%s\n", __func__);
465
466 lp->reg_msg.complete = NULL;
467 lp->reg_cmd[0] = MCR20A_WRITE_REG(DAR_PHY_CTRL1);
468 lp->reg_data[0] = MCR20A_XCVSEQ_TX;
469 lp->reg_xfer_data.len = 1;
470
471 ret = spi_async(lp->spi, &lp->reg_msg);
472 if (ret)
473 dev_err(printdev(lp), "failed to set SEQ TX\n");
474}
475
476static int
477mcr20a_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
478{
479 struct mcr20a_local *lp = hw->priv;
480
481 dev_dbg(printdev(lp), "%s\n", __func__);
482
483 lp->tx_skb = skb;
484
485 print_hex_dump_debug("mcr20a tx: ", DUMP_PREFIX_OFFSET, 16, 1,
486 skb->data, skb->len, 0);
487
488 lp->is_tx = 1;
489
490 lp->reg_msg.complete = NULL;
491 lp->reg_cmd[0] = MCR20A_WRITE_REG(DAR_PHY_CTRL1);
492 lp->reg_data[0] = MCR20A_XCVSEQ_IDLE;
493 lp->reg_xfer_data.len = 1;
494
495 return spi_async(lp->spi, &lp->reg_msg);
496}
497
498static int
499mcr20a_ed(struct ieee802154_hw *hw, u8 *level)
500{
501 WARN_ON(!level);
502 *level = 0xbe;
503 return 0;
504}
505
506static int
507mcr20a_set_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
508{
509 struct mcr20a_local *lp = hw->priv;
510 int ret;
511
512 dev_dbg(printdev(lp), "%s\n", __func__);
513
514 /* freqency = ((PLL_INT+64) + (PLL_FRAC/65536)) * 32 MHz */
515 ret = regmap_write(lp->regmap_dar, DAR_PLL_INT0, PLL_INT[channel - 11]);
516 if (ret)
517 return ret;
518 ret = regmap_write(lp->regmap_dar, DAR_PLL_FRAC0_LSB, 0x00);
519 if (ret)
520 return ret;
521 ret = regmap_write(lp->regmap_dar, DAR_PLL_FRAC0_MSB,
522 PLL_FRAC[channel - 11]);
523 if (ret)
524 return ret;
525
526 return 0;
527}
528
529static int
530mcr20a_start(struct ieee802154_hw *hw)
531{
532 struct mcr20a_local *lp = hw->priv;
533 int ret;
534
535 dev_dbg(printdev(lp), "%s\n", __func__);
536
537 /* No slotted operation */
538 dev_dbg(printdev(lp), "no slotted operation\n");
539 ret = regmap_update_bits(lp->regmap_dar, DAR_PHY_CTRL1,
540 DAR_PHY_CTRL1_SLOTTED, 0x0);
541
542 /* enable irq */
543 enable_irq(lp->spi->irq);
544
545 /* Unmask SEQ interrupt */
546 ret = regmap_update_bits(lp->regmap_dar, DAR_PHY_CTRL2,
547 DAR_PHY_CTRL2_SEQMSK, 0x0);
548
549 /* Start the RX sequence */
550 dev_dbg(printdev(lp), "start the RX sequence\n");
551 ret = regmap_update_bits(lp->regmap_dar, DAR_PHY_CTRL1,
552 DAR_PHY_CTRL1_XCVSEQ_MASK, MCR20A_XCVSEQ_RX);
553
554 return 0;
555}
556
557static void
558mcr20a_stop(struct ieee802154_hw *hw)
559{
560 struct mcr20a_local *lp = hw->priv;
561
562 dev_dbg(printdev(lp), "%s\n", __func__);
563
564 /* stop all running sequence */
565 regmap_update_bits(lp->regmap_dar, DAR_PHY_CTRL1,
566 DAR_PHY_CTRL1_XCVSEQ_MASK, MCR20A_XCVSEQ_IDLE);
567
568 /* disable irq */
569 disable_irq(lp->spi->irq);
570}
571
572static int
573mcr20a_set_hw_addr_filt(struct ieee802154_hw *hw,
574 struct ieee802154_hw_addr_filt *filt,
575 unsigned long changed)
576{
577 struct mcr20a_local *lp = hw->priv;
578
579 dev_dbg(printdev(lp), "%s\n", __func__);
580
581 if (changed & IEEE802154_AFILT_SADDR_CHANGED) {
582 u16 addr = le16_to_cpu(filt->short_addr);
583
584 regmap_write(lp->regmap_iar, IAR_MACSHORTADDRS0_LSB, addr);
585 regmap_write(lp->regmap_iar, IAR_MACSHORTADDRS0_MSB, addr >> 8);
586 }
587
588 if (changed & IEEE802154_AFILT_PANID_CHANGED) {
589 u16 pan = le16_to_cpu(filt->pan_id);
590
591 regmap_write(lp->regmap_iar, IAR_MACPANID0_LSB, pan);
592 regmap_write(lp->regmap_iar, IAR_MACPANID0_MSB, pan >> 8);
593 }
594
595 if (changed & IEEE802154_AFILT_IEEEADDR_CHANGED) {
596 u8 addr[8], i;
597
598 memcpy(addr, &filt->ieee_addr, 8);
599 for (i = 0; i < 8; i++)
600 regmap_write(lp->regmap_iar,
601 IAR_MACLONGADDRS0_0 + i, addr[i]);
602 }
603
604 if (changed & IEEE802154_AFILT_PANC_CHANGED) {
605 if (filt->pan_coord) {
606 regmap_update_bits(lp->regmap_dar, DAR_PHY_CTRL4,
607 DAR_PHY_CTRL4_PANCORDNTR0, 0x10);
608 } else {
609 regmap_update_bits(lp->regmap_dar, DAR_PHY_CTRL4,
610 DAR_PHY_CTRL4_PANCORDNTR0, 0x00);
611 }
612 }
613
614 return 0;
615}
616
617/* -30 dBm to 10 dBm */
618#define MCR20A_MAX_TX_POWERS 0x14
619static const s32 mcr20a_powers[MCR20A_MAX_TX_POWERS + 1] = {
620 -3000, -2800, -2600, -2400, -2200, -2000, -1800, -1600, -1400,
621 -1200, -1000, -800, -600, -400, -200, 0, 200, 400, 600, 800, 1000
622};
623
624static int
625mcr20a_set_txpower(struct ieee802154_hw *hw, s32 mbm)
626{
627 struct mcr20a_local *lp = hw->priv;
628 u32 i;
629
630 dev_dbg(printdev(lp), "%s(%d)\n", __func__, mbm);
631
632 for (i = 0; i < lp->hw->phy->supported.tx_powers_size; i++) {
633 if (lp->hw->phy->supported.tx_powers[i] == mbm)
634 return regmap_write(lp->regmap_dar, DAR_PA_PWR,
635 ((i + 8) & 0x1F));
636 }
637
638 return -EINVAL;
639}
640
641#define MCR20A_MAX_ED_LEVELS MCR20A_MIN_CCA_THRESHOLD
642static s32 mcr20a_ed_levels[MCR20A_MAX_ED_LEVELS + 1];
643
644static int
645mcr20a_set_cca_mode(struct ieee802154_hw *hw,
646 const struct wpan_phy_cca *cca)
647{
648 struct mcr20a_local *lp = hw->priv;
649 unsigned int cca_mode = 0xff;
650 bool cca_mode_and = false;
651 int ret;
652
653 dev_dbg(printdev(lp), "%s\n", __func__);
654
655 /* mapping 802.15.4 to driver spec */
656 switch (cca->mode) {
657 case NL802154_CCA_ENERGY:
658 cca_mode = MCR20A_CCA_MODE1;
659 break;
660 case NL802154_CCA_CARRIER:
661 cca_mode = MCR20A_CCA_MODE2;
662 break;
663 case NL802154_CCA_ENERGY_CARRIER:
664 switch (cca->opt) {
665 case NL802154_CCA_OPT_ENERGY_CARRIER_AND:
666 cca_mode = MCR20A_CCA_MODE3;
667 cca_mode_and = true;
668 break;
669 case NL802154_CCA_OPT_ENERGY_CARRIER_OR:
670 cca_mode = MCR20A_CCA_MODE3;
671 cca_mode_and = false;
672 break;
673 default:
674 return -EINVAL;
675 }
676 break;
677 default:
678 return -EINVAL;
679 }
680 ret = regmap_update_bits(lp->regmap_dar, DAR_PHY_CTRL4,
681 DAR_PHY_CTRL4_CCATYPE_MASK,
682 cca_mode << DAR_PHY_CTRL4_CCATYPE_SHIFT);
683 if (ret < 0)
684 return ret;
685
686 if (cca_mode == MCR20A_CCA_MODE3) {
687 if (cca_mode_and) {
688 ret = regmap_update_bits(lp->regmap_iar, IAR_CCA_CTRL,
689 IAR_CCA_CTRL_CCA3_AND_NOT_OR,
690 0x08);
691 } else {
692 ret = regmap_update_bits(lp->regmap_iar,
693 IAR_CCA_CTRL,
694 IAR_CCA_CTRL_CCA3_AND_NOT_OR,
695 0x00);
696 }
697 if (ret < 0)
698 return ret;
699 }
700
701 return ret;
702}
703
704static int
705mcr20a_set_cca_ed_level(struct ieee802154_hw *hw, s32 mbm)
706{
707 struct mcr20a_local *lp = hw->priv;
708 u32 i;
709
710 dev_dbg(printdev(lp), "%s\n", __func__);
711
712 for (i = 0; i < hw->phy->supported.cca_ed_levels_size; i++) {
713 if (hw->phy->supported.cca_ed_levels[i] == mbm)
714 return regmap_write(lp->regmap_iar, IAR_CCA1_THRESH, i);
715 }
716
717 return 0;
718}
719
720static int
721mcr20a_set_promiscuous_mode(struct ieee802154_hw *hw, const bool on)
722{
723 struct mcr20a_local *lp = hw->priv;
724 int ret;
725 u8 rx_frame_filter_reg = 0x0;
726 u8 val;
727
728 dev_dbg(printdev(lp), "%s(%d)\n", __func__, on);
729
730 if (on) {
731 /* All frame types accepted*/
732 val |= DAR_PHY_CTRL4_PROMISCUOUS;
733 rx_frame_filter_reg &= ~(IAR_RX_FRAME_FLT_FRM_VER);
734 rx_frame_filter_reg |= (IAR_RX_FRAME_FLT_ACK_FT |
735 IAR_RX_FRAME_FLT_NS_FT);
736
737 ret = regmap_update_bits(lp->regmap_dar, DAR_PHY_CTRL4,
738 DAR_PHY_CTRL4_PROMISCUOUS,
739 DAR_PHY_CTRL4_PROMISCUOUS);
740 if (ret < 0)
741 return ret;
742
743 ret = regmap_write(lp->regmap_iar, IAR_RX_FRAME_FILTER,
744 rx_frame_filter_reg);
745 if (ret < 0)
746 return ret;
747 } else {
748 ret = regmap_update_bits(lp->regmap_dar, DAR_PHY_CTRL4,
749 DAR_PHY_CTRL4_PROMISCUOUS, 0x0);
750 if (ret < 0)
751 return ret;
752
753 ret = regmap_write(lp->regmap_iar, IAR_RX_FRAME_FILTER,
754 IAR_RX_FRAME_FLT_FRM_VER |
755 IAR_RX_FRAME_FLT_BEACON_FT |
756 IAR_RX_FRAME_FLT_DATA_FT |
757 IAR_RX_FRAME_FLT_CMD_FT);
758 if (ret < 0)
759 return ret;
760 }
761
762 return 0;
763}
764
765static const struct ieee802154_ops mcr20a_hw_ops = {
766 .owner = THIS_MODULE,
767 .xmit_async = mcr20a_xmit,
768 .ed = mcr20a_ed,
769 .set_channel = mcr20a_set_channel,
770 .start = mcr20a_start,
771 .stop = mcr20a_stop,
772 .set_hw_addr_filt = mcr20a_set_hw_addr_filt,
773 .set_txpower = mcr20a_set_txpower,
774 .set_cca_mode = mcr20a_set_cca_mode,
775 .set_cca_ed_level = mcr20a_set_cca_ed_level,
776 .set_promiscuous_mode = mcr20a_set_promiscuous_mode,
777};
778
779static int
780mcr20a_request_rx(struct mcr20a_local *lp)
781{
782 dev_dbg(printdev(lp), "%s\n", __func__);
783
784 /* Start the RX sequence */
785 regmap_update_bits_async(lp->regmap_dar, DAR_PHY_CTRL1,
786 DAR_PHY_CTRL1_XCVSEQ_MASK, MCR20A_XCVSEQ_RX);
787
788 return 0;
789}
790
791static void
792mcr20a_handle_rx_read_buf_complete(void *context)
793{
794 struct mcr20a_local *lp = context;
795 u8 len = lp->reg_data[0] & DAR_RX_FRAME_LENGTH_MASK;
796 struct sk_buff *skb;
797
798 dev_dbg(printdev(lp), "%s\n", __func__);
799
800 dev_dbg(printdev(lp), "RX is done\n");
801
802 if (!ieee802154_is_valid_psdu_len(len)) {
803 dev_vdbg(&lp->spi->dev, "corrupted frame received\n");
804 len = IEEE802154_MTU;
805 }
806
807 len = len - 2; /* get rid of frame check field */
808
809 skb = dev_alloc_skb(len);
810 if (!skb)
811 return;
812
813 memcpy(skb_put(skb, len), lp->rx_buf, len);
814 ieee802154_rx_irqsafe(lp->hw, skb, lp->rx_lqi[0]);
815
816 print_hex_dump_debug("mcr20a rx: ", DUMP_PREFIX_OFFSET, 16, 1,
817 lp->rx_buf, len, 0);
818 pr_debug("mcr20a rx: lqi: %02hhx\n", lp->rx_lqi[0]);
819
820 /* start RX sequence */
821 mcr20a_request_rx(lp);
822}
823
824static void
825mcr20a_handle_rx_read_len_complete(void *context)
826{
827 struct mcr20a_local *lp = context;
828 u8 len;
829 int ret;
830
831 dev_dbg(printdev(lp), "%s\n", __func__);
832
833 /* get the length of received frame */
834 len = lp->reg_data[0] & DAR_RX_FRAME_LENGTH_MASK;
835 dev_dbg(printdev(lp), "frame len : %d\n", len);
836
837 /* prepare to read the rx buf */
838 lp->rx_buf_msg.complete = mcr20a_handle_rx_read_buf_complete;
839 lp->rx_header[0] = MCR20A_BURST_READ_PACKET_BUF;
840 lp->rx_xfer_buf.len = len;
841
842 ret = spi_async(lp->spi, &lp->rx_buf_msg);
843 if (ret)
844 dev_err(printdev(lp), "failed to read rx buffer length\n");
845}
846
847static int
848mcr20a_handle_rx(struct mcr20a_local *lp)
849{
850 dev_dbg(printdev(lp), "%s\n", __func__);
851 lp->reg_msg.complete = mcr20a_handle_rx_read_len_complete;
852 lp->reg_cmd[0] = MCR20A_READ_REG(DAR_RX_FRM_LEN);
853 lp->reg_xfer_data.len = 1;
854
855 return spi_async(lp->spi, &lp->reg_msg);
856}
857
858static int
859mcr20a_handle_tx_complete(struct mcr20a_local *lp)
860{
861 dev_dbg(printdev(lp), "%s\n", __func__);
862
863 ieee802154_xmit_complete(lp->hw, lp->tx_skb, false);
864
865 return mcr20a_request_rx(lp);
866}
867
868static int
869mcr20a_handle_tx(struct mcr20a_local *lp)
870{
871 int ret;
872
873 dev_dbg(printdev(lp), "%s\n", __func__);
874
875 /* write tx buffer */
876 lp->tx_header[0] = MCR20A_BURST_WRITE_PACKET_BUF;
877 /* add 2 bytes of FCS */
878 lp->tx_len[0] = lp->tx_skb->len + 2;
879 lp->tx_xfer_buf.tx_buf = lp->tx_skb->data;
880 /* add 1 byte psduLength */
881 lp->tx_xfer_buf.len = lp->tx_skb->len + 1;
882
883 ret = spi_async(lp->spi, &lp->tx_buf_msg);
884 if (ret) {
885 dev_err(printdev(lp), "SPI write Failed for TX buf\n");
886 return ret;
887 }
888
889 return 0;
890}
891
892static void
893mcr20a_irq_clean_complete(void *context)
894{
895 struct mcr20a_local *lp = context;
896 u8 seq_state = lp->irq_data[DAR_IRQ_STS1] & DAR_PHY_CTRL1_XCVSEQ_MASK;
897
898 dev_dbg(printdev(lp), "%s\n", __func__);
899
900 enable_irq(lp->spi->irq);
901
902 dev_dbg(printdev(lp), "IRQ STA1 (%02x) STA2 (%02x)\n",
903 lp->irq_data[DAR_IRQ_STS1], lp->irq_data[DAR_IRQ_STS2]);
904
905 switch (seq_state) {
906 /* TX IRQ, RX IRQ and SEQ IRQ */
907 case (0x03):
908 if (lp->is_tx) {
909 lp->is_tx = 0;
910 dev_dbg(printdev(lp), "TX is done. No ACK\n");
911 mcr20a_handle_tx_complete(lp);
912 }
913 break;
914 case (0x05):
915 /* rx is starting */
916 dev_dbg(printdev(lp), "RX is starting\n");
917 mcr20a_handle_rx(lp);
918 break;
919 case (0x07):
920 if (lp->is_tx) {
921 /* tx is done */
922 lp->is_tx = 0;
923 dev_dbg(printdev(lp), "TX is done. Get ACK\n");
924 mcr20a_handle_tx_complete(lp);
925 } else {
926 /* rx is starting */
927 dev_dbg(printdev(lp), "RX is starting\n");
928 mcr20a_handle_rx(lp);
929 }
930 break;
931 case (0x01):
932 if (lp->is_tx) {
933 dev_dbg(printdev(lp), "TX is starting\n");
934 mcr20a_handle_tx(lp);
935 } else {
936 dev_dbg(printdev(lp), "MCR20A is stop\n");
937 }
938 break;
939 }
940}
941
942static void mcr20a_irq_status_complete(void *context)
943{
944 int ret;
945 struct mcr20a_local *lp = context;
946
947 dev_dbg(printdev(lp), "%s\n", __func__);
948 regmap_update_bits_async(lp->regmap_dar, DAR_PHY_CTRL1,
949 DAR_PHY_CTRL1_XCVSEQ_MASK, MCR20A_XCVSEQ_IDLE);
950
951 lp->reg_msg.complete = mcr20a_irq_clean_complete;
952 lp->reg_cmd[0] = MCR20A_WRITE_REG(DAR_IRQ_STS1);
953 memcpy(lp->reg_data, lp->irq_data, MCR20A_IRQSTS_NUM);
954 lp->reg_xfer_data.len = MCR20A_IRQSTS_NUM;
955
956 ret = spi_async(lp->spi, &lp->reg_msg);
957
958 if (ret)
959 dev_err(printdev(lp), "failed to clean irq status\n");
960}
961
962static irqreturn_t mcr20a_irq_isr(int irq, void *data)
963{
964 struct mcr20a_local *lp = data;
965 int ret;
966
967 disable_irq_nosync(irq);
968
969 lp->irq_header[0] = MCR20A_READ_REG(DAR_IRQ_STS1);
970 /* read IRQSTSx */
971 ret = spi_async(lp->spi, &lp->irq_msg);
972 if (ret) {
973 enable_irq(irq);
974 return IRQ_NONE;
975 }
976
977 return IRQ_HANDLED;
978}
979
980static int mcr20a_get_platform_data(struct spi_device *spi,
981 struct mcr20a_platform_data *pdata)
982{
983 int ret = 0;
984
985 if (!spi->dev.of_node)
986 return -EINVAL;
987
988 pdata->rst_gpio = of_get_named_gpio(spi->dev.of_node, "rst_b-gpio", 0);
989 dev_dbg(&spi->dev, "rst_b-gpio: %d\n", pdata->rst_gpio);
990
991 return ret;
992}
993
994static void mcr20a_hw_setup(struct mcr20a_local *lp)
995{
996 u8 i;
997 struct ieee802154_hw *hw = lp->hw;
998 struct wpan_phy *phy = lp->hw->phy;
999
1000 dev_dbg(printdev(lp), "%s\n", __func__);
1001
1002 phy->symbol_duration = 16;
1003 phy->lifs_period = 40;
1004 phy->sifs_period = 12;
1005
1006 hw->flags = IEEE802154_HW_TX_OMIT_CKSUM |
1007 IEEE802154_HW_AFILT |
1008 IEEE802154_HW_PROMISCUOUS;
1009
1010 phy->flags = WPAN_PHY_FLAG_TXPOWER | WPAN_PHY_FLAG_CCA_ED_LEVEL |
1011 WPAN_PHY_FLAG_CCA_MODE;
1012
1013 phy->supported.cca_modes = BIT(NL802154_CCA_ENERGY) |
1014 BIT(NL802154_CCA_CARRIER) | BIT(NL802154_CCA_ENERGY_CARRIER);
1015 phy->supported.cca_opts = BIT(NL802154_CCA_OPT_ENERGY_CARRIER_AND) |
1016 BIT(NL802154_CCA_OPT_ENERGY_CARRIER_OR);
1017
1018 /* initiating cca_ed_levels */
1019 for (i = MCR20A_MAX_CCA_THRESHOLD; i < MCR20A_MIN_CCA_THRESHOLD + 1;
1020 ++i) {
1021 mcr20a_ed_levels[i] = -i * 100;
1022 }
1023
1024 phy->supported.cca_ed_levels = mcr20a_ed_levels;
1025 phy->supported.cca_ed_levels_size = ARRAY_SIZE(mcr20a_ed_levels);
1026
1027 phy->cca.mode = NL802154_CCA_ENERGY;
1028
1029 phy->supported.channels[0] = MCR20A_VALID_CHANNELS;
1030 phy->current_page = 0;
1031 /* MCR20A default reset value */
1032 phy->current_channel = 20;
1033 phy->symbol_duration = 16;
1034 phy->supported.tx_powers = mcr20a_powers;
1035 phy->supported.tx_powers_size = ARRAY_SIZE(mcr20a_powers);
1036 phy->cca_ed_level = phy->supported.cca_ed_levels[75];
1037 phy->transmit_power = phy->supported.tx_powers[0x0F];
1038}
1039
1040static void
1041mcr20a_setup_tx_spi_messages(struct mcr20a_local *lp)
1042{
1043 spi_message_init(&lp->tx_buf_msg);
1044 lp->tx_buf_msg.context = lp;
1045 lp->tx_buf_msg.complete = mcr20a_write_tx_buf_complete;
1046
1047 lp->tx_xfer_header.len = 1;
1048 lp->tx_xfer_header.tx_buf = lp->tx_header;
1049
1050 lp->tx_xfer_len.len = 1;
1051 lp->tx_xfer_len.tx_buf = lp->tx_len;
1052
1053 spi_message_add_tail(&lp->tx_xfer_header, &lp->tx_buf_msg);
1054 spi_message_add_tail(&lp->tx_xfer_len, &lp->tx_buf_msg);
1055 spi_message_add_tail(&lp->tx_xfer_buf, &lp->tx_buf_msg);
1056}
1057
1058static void
1059mcr20a_setup_rx_spi_messages(struct mcr20a_local *lp)
1060{
1061 spi_message_init(&lp->reg_msg);
1062 lp->reg_msg.context = lp;
1063
1064 lp->reg_xfer_cmd.len = 1;
1065 lp->reg_xfer_cmd.tx_buf = lp->reg_cmd;
1066 lp->reg_xfer_cmd.rx_buf = lp->reg_cmd;
1067
1068 lp->reg_xfer_data.rx_buf = lp->reg_data;
1069 lp->reg_xfer_data.tx_buf = lp->reg_data;
1070
1071 spi_message_add_tail(&lp->reg_xfer_cmd, &lp->reg_msg);
1072 spi_message_add_tail(&lp->reg_xfer_data, &lp->reg_msg);
1073
1074 spi_message_init(&lp->rx_buf_msg);
1075 lp->rx_buf_msg.context = lp;
1076 lp->rx_buf_msg.complete = mcr20a_handle_rx_read_buf_complete;
1077 lp->rx_xfer_header.len = 1;
1078 lp->rx_xfer_header.tx_buf = lp->rx_header;
1079 lp->rx_xfer_header.rx_buf = lp->rx_header;
1080
1081 lp->rx_xfer_buf.rx_buf = lp->rx_buf;
1082
1083 lp->rx_xfer_lqi.len = 1;
1084 lp->rx_xfer_lqi.rx_buf = lp->rx_lqi;
1085
1086 spi_message_add_tail(&lp->rx_xfer_header, &lp->rx_buf_msg);
1087 spi_message_add_tail(&lp->rx_xfer_buf, &lp->rx_buf_msg);
1088 spi_message_add_tail(&lp->rx_xfer_lqi, &lp->rx_buf_msg);
1089}
1090
1091static void
1092mcr20a_setup_irq_spi_messages(struct mcr20a_local *lp)
1093{
1094 spi_message_init(&lp->irq_msg);
1095 lp->irq_msg.context = lp;
1096 lp->irq_msg.complete = mcr20a_irq_status_complete;
1097 lp->irq_xfer_header.len = 1;
1098 lp->irq_xfer_header.tx_buf = lp->irq_header;
1099 lp->irq_xfer_header.rx_buf = lp->irq_header;
1100
1101 lp->irq_xfer_data.len = MCR20A_IRQSTS_NUM;
1102 lp->irq_xfer_data.rx_buf = lp->irq_data;
1103
1104 spi_message_add_tail(&lp->irq_xfer_header, &lp->irq_msg);
1105 spi_message_add_tail(&lp->irq_xfer_data, &lp->irq_msg);
1106}
1107
1108static int
1109mcr20a_phy_init(struct mcr20a_local *lp)
1110{
1111 u8 index;
1112 unsigned int phy_reg = 0;
1113 int ret;
1114
1115 dev_dbg(printdev(lp), "%s\n", __func__);
1116
1117 /* Disable Tristate on COCO MISO for SPI reads */
1118 ret = regmap_write(lp->regmap_iar, IAR_MISC_PAD_CTRL, 0x02);
1119 if (ret)
1120 goto err_ret;
1121
1122 /* Clear all PP IRQ bits in IRQSTS1 to avoid unexpected interrupts
1123 * immediately after init
1124 */
1125 ret = regmap_write(lp->regmap_dar, DAR_IRQ_STS1, 0xEF);
1126 if (ret)
1127 goto err_ret;
1128
1129 /* Clear all PP IRQ bits in IRQSTS2 */
1130 ret = regmap_write(lp->regmap_dar, DAR_IRQ_STS2,
1131 DAR_IRQSTS2_ASM_IRQ | DAR_IRQSTS2_PB_ERR_IRQ |
1132 DAR_IRQSTS2_WAKE_IRQ);
1133 if (ret)
1134 goto err_ret;
1135
1136 /* Disable all timer interrupts */
1137 ret = regmap_write(lp->regmap_dar, DAR_IRQ_STS3, 0xFF);
1138 if (ret)
1139 goto err_ret;
1140
1141 /* PHY_CTRL1 : default HW settings + AUTOACK enabled */
1142 ret = regmap_update_bits(lp->regmap_dar, DAR_PHY_CTRL1,
1143 DAR_PHY_CTRL1_AUTOACK, DAR_PHY_CTRL1_AUTOACK);
1144
1145 /* PHY_CTRL2 : disable all interrupts */
1146 ret = regmap_write(lp->regmap_dar, DAR_PHY_CTRL2, 0xFF);
1147 if (ret)
1148 goto err_ret;
1149
1150 /* PHY_CTRL3 : disable all timers and remaining interrupts */
1151 ret = regmap_write(lp->regmap_dar, DAR_PHY_CTRL3,
1152 DAR_PHY_CTRL3_ASM_MSK | DAR_PHY_CTRL3_PB_ERR_MSK |
1153 DAR_PHY_CTRL3_WAKE_MSK);
1154 if (ret)
1155 goto err_ret;
1156
1157 /* SRC_CTRL : enable Acknowledge Frame Pending and
1158 * Source Address Matching Enable
1159 */
1160 ret = regmap_write(lp->regmap_dar, DAR_SRC_CTRL,
1161 DAR_SRC_CTRL_ACK_FRM_PND |
1162 (DAR_SRC_CTRL_INDEX << DAR_SRC_CTRL_INDEX_SHIFT));
1163 if (ret)
1164 goto err_ret;
1165
1166 /* RX_FRAME_FILTER */
1167 /* FRM_VER[1:0] = b11. Accept FrameVersion 0 and 1 packets */
1168 ret = regmap_write(lp->regmap_iar, IAR_RX_FRAME_FILTER,
1169 IAR_RX_FRAME_FLT_FRM_VER |
1170 IAR_RX_FRAME_FLT_BEACON_FT |
1171 IAR_RX_FRAME_FLT_DATA_FT |
1172 IAR_RX_FRAME_FLT_CMD_FT);
1173 if (ret)
1174 goto err_ret;
1175
1176 dev_info(printdev(lp), "MCR20A DAR overwrites version: 0x%02x\n",
1177 MCR20A_OVERWRITE_VERSION);
1178
1179 /* Overwrites direct registers */
1180 ret = regmap_write(lp->regmap_dar, DAR_OVERWRITE_VER,
1181 MCR20A_OVERWRITE_VERSION);
1182 if (ret)
1183 goto err_ret;
1184
1185 /* Overwrites indirect registers */
1186 ret = regmap_multi_reg_write(lp->regmap_iar, mar20a_iar_overwrites,
1187 ARRAY_SIZE(mar20a_iar_overwrites));
1188 if (ret)
1189 goto err_ret;
1190
1191 /* Clear HW indirect queue */
1192 dev_dbg(printdev(lp), "clear HW indirect queue\n");
1193 for (index = 0; index < MCR20A_PHY_INDIRECT_QUEUE_SIZE; index++) {
1194 phy_reg = (u8)(((index & DAR_SRC_CTRL_INDEX) <<
1195 DAR_SRC_CTRL_INDEX_SHIFT)
1196 | (DAR_SRC_CTRL_SRCADDR_EN)
1197 | (DAR_SRC_CTRL_INDEX_DISABLE));
1198 ret = regmap_write(lp->regmap_dar, DAR_SRC_CTRL, phy_reg);
1199 if (ret)
1200 goto err_ret;
1201 phy_reg = 0;
1202 }
1203
1204 /* Assign HW Indirect hash table to PAN0 */
1205 ret = regmap_read(lp->regmap_iar, IAR_DUAL_PAN_CTRL, &phy_reg);
1206 if (ret)
1207 goto err_ret;
1208
1209 /* Clear current lvl */
1210 phy_reg &= ~IAR_DUAL_PAN_CTRL_DUAL_PAN_SAM_LVL_MSK;
1211
1212 /* Set new lvl */
1213 phy_reg |= MCR20A_PHY_INDIRECT_QUEUE_SIZE <<
1214 IAR_DUAL_PAN_CTRL_DUAL_PAN_SAM_LVL_SHIFT;
1215 ret = regmap_write(lp->regmap_iar, IAR_DUAL_PAN_CTRL, phy_reg);
1216 if (ret)
1217 goto err_ret;
1218
1219 /* Set CCA threshold to -75 dBm */
1220 ret = regmap_write(lp->regmap_iar, IAR_CCA1_THRESH, 0x4B);
1221 if (ret)
1222 goto err_ret;
1223
1224 /* Set prescaller to obtain 1 symbol (16us) timebase */
1225 ret = regmap_write(lp->regmap_iar, IAR_TMR_PRESCALE, 0x05);
1226 if (ret)
1227 goto err_ret;
1228
1229 /* Enable autodoze mode. */
1230 ret = regmap_update_bits(lp->regmap_dar, DAR_PWR_MODES,
1231 DAR_PWR_MODES_AUTODOZE,
1232 DAR_PWR_MODES_AUTODOZE);
1233 if (ret)
1234 goto err_ret;
1235
1236 /* Disable clk_out */
1237 ret = regmap_update_bits(lp->regmap_dar, DAR_CLK_OUT_CTRL,
1238 DAR_CLK_OUT_CTRL_EN, 0x0);
1239 if (ret)
1240 goto err_ret;
1241
1242 return 0;
1243
1244err_ret:
1245 return ret;
1246}
1247
1248static int
1249mcr20a_probe(struct spi_device *spi)
1250{
1251 struct ieee802154_hw *hw;
1252 struct mcr20a_local *lp;
1253 struct mcr20a_platform_data *pdata;
1254 int irq_type;
1255 int ret = -ENOMEM;
1256
1257 dev_dbg(&spi->dev, "%s\n", __func__);
1258
1259 if (!spi->irq) {
1260 dev_err(&spi->dev, "no IRQ specified\n");
1261 return -EINVAL;
1262 }
1263
1264 pdata = kmalloc(sizeof(*pdata), GFP_KERNEL);
1265 if (!pdata)
1266 return -ENOMEM;
1267
1268 /* set mcr20a platform data */
1269 ret = mcr20a_get_platform_data(spi, pdata);
1270 if (ret < 0) {
1271 dev_crit(&spi->dev, "mcr20a_get_platform_data failed.\n");
1272 return ret;
1273 }
1274
1275 /* init reset gpio */
1276 if (gpio_is_valid(pdata->rst_gpio)) {
1277 ret = devm_gpio_request_one(&spi->dev, pdata->rst_gpio,
1278 GPIOF_OUT_INIT_HIGH, "reset");
1279 if (ret)
1280 return ret;
1281 }
1282
1283 /* reset mcr20a */
1284 if (gpio_is_valid(pdata->rst_gpio)) {
1285 usleep_range(10, 20);
1286 gpio_set_value_cansleep(pdata->rst_gpio, 0);
1287 usleep_range(10, 20);
1288 gpio_set_value_cansleep(pdata->rst_gpio, 1);
1289 usleep_range(120, 240);
1290 }
1291
1292 /* allocate ieee802154_hw and private data */
1293 hw = ieee802154_alloc_hw(sizeof(*lp), &mcr20a_hw_ops);
1294 if (!hw) {
1295 dev_crit(&spi->dev, "ieee802154_alloc_hw failed\n");
1296 return -ENOMEM;
1297 }
1298
1299 /* init mcr20a local data */
1300 lp = hw->priv;
1301 lp->hw = hw;
1302 lp->spi = spi;
1303 lp->spi->dev.platform_data = pdata;
1304 lp->pdata = pdata;
1305
1306 /* init ieee802154_hw */
1307 hw->parent = &spi->dev;
1308 ieee802154_random_extended_addr(&hw->phy->perm_extended_addr);
1309
1310 /* init buf */
1311 lp->buf = devm_kzalloc(&spi->dev, SPI_COMMAND_BUFFER, GFP_KERNEL);
1312
1313 if (!lp->buf)
1314 return -ENOMEM;
1315
1316 mcr20a_setup_tx_spi_messages(lp);
1317 mcr20a_setup_rx_spi_messages(lp);
1318 mcr20a_setup_irq_spi_messages(lp);
1319
1320 /* setup regmap */
1321 lp->regmap_dar = devm_regmap_init_spi(spi, &mcr20a_dar_regmap);
1322 if (IS_ERR(lp->regmap_dar)) {
1323 ret = PTR_ERR(lp->regmap_dar);
1324 dev_err(&spi->dev, "Failed to allocate dar map: %d\n",
1325 ret);
1326 goto free_dev;
1327 }
1328
1329 lp->regmap_iar = devm_regmap_init_spi(spi, &mcr20a_iar_regmap);
1330 if (IS_ERR(lp->regmap_iar)) {
1331 ret = PTR_ERR(lp->regmap_iar);
1332 dev_err(&spi->dev, "Failed to allocate iar map: %d\n", ret);
1333 goto free_dev;
1334 }
1335
1336 mcr20a_hw_setup(lp);
1337
1338 spi_set_drvdata(spi, lp);
1339
1340 ret = mcr20a_phy_init(lp);
1341 if (ret < 0) {
1342 dev_crit(&spi->dev, "mcr20a_phy_init failed\n");
1343 goto free_dev;
1344 }
1345
1346 irq_type = irq_get_trigger_type(spi->irq);
1347 if (!irq_type)
1348 irq_type = IRQF_TRIGGER_FALLING;
1349
1350 ret = devm_request_irq(&spi->dev, spi->irq, mcr20a_irq_isr,
1351 irq_type, dev_name(&spi->dev), lp);
1352 if (ret) {
1353 dev_err(&spi->dev, "could not request_irq for mcr20a\n");
1354 ret = -ENODEV;
1355 goto free_dev;
1356 }
1357
1358 /* disable_irq by default and wait for starting hardware */
1359 disable_irq(spi->irq);
1360
1361 ret = ieee802154_register_hw(hw);
1362 if (ret) {
1363 dev_crit(&spi->dev, "ieee802154_register_hw failed\n");
1364 goto free_dev;
1365 }
1366
1367 return ret;
1368
1369free_dev:
1370 ieee802154_free_hw(lp->hw);
1371
1372 return ret;
1373}
1374
1375static int mcr20a_remove(struct spi_device *spi)
1376{
1377 struct mcr20a_local *lp = spi_get_drvdata(spi);
1378
1379 dev_dbg(&spi->dev, "%s\n", __func__);
1380
1381 ieee802154_unregister_hw(lp->hw);
1382 ieee802154_free_hw(lp->hw);
1383
1384 return 0;
1385}
1386
1387static const struct of_device_id mcr20a_of_match[] = {
1388 { .compatible = "nxp,mcr20a", },
1389 { },
1390};
1391MODULE_DEVICE_TABLE(of, mcr20a_of_match);
1392
1393static const struct spi_device_id mcr20a_device_id[] = {
1394 { .name = "mcr20a", },
1395 { },
1396};
1397MODULE_DEVICE_TABLE(spi, mcr20a_device_id);
1398
1399static struct spi_driver mcr20a_driver = {
1400 .id_table = mcr20a_device_id,
1401 .driver = {
1402 .of_match_table = of_match_ptr(mcr20a_of_match),
1403 .name = "mcr20a",
1404 },
1405 .probe = mcr20a_probe,
1406 .remove = mcr20a_remove,
1407};
1408
1409module_spi_driver(mcr20a_driver);
1410
1411MODULE_DESCRIPTION("MCR20A Transceiver Driver");
1412MODULE_LICENSE("GPL v2");
1413MODULE_AUTHOR("Xue Liu <liuxuenetmail@gmail>");
diff --git a/drivers/net/ieee802154/mcr20a.h b/drivers/net/ieee802154/mcr20a.h
new file mode 100644
index 000000000000..6da4fd00b3c5
--- /dev/null
+++ b/drivers/net/ieee802154/mcr20a.h
@@ -0,0 +1,498 @@
1/*
2 * Driver for NXP MCR20A 802.15.4 Wireless-PAN Networking controller
3 *
4 * Copyright (C) 2018 Xue Liu <liuxuenetmail@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2
8 * as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16#ifndef _MCR20A_H
17#define _MCR20A_H
18
19/* Direct Accress Register */
20#define DAR_IRQ_STS1 0x00
21#define DAR_IRQ_STS2 0x01
22#define DAR_IRQ_STS3 0x02
23#define DAR_PHY_CTRL1 0x03
24#define DAR_PHY_CTRL2 0x04
25#define DAR_PHY_CTRL3 0x05
26#define DAR_RX_FRM_LEN 0x06
27#define DAR_PHY_CTRL4 0x07
28#define DAR_SRC_CTRL 0x08
29#define DAR_SRC_ADDRS_SUM_LSB 0x09
30#define DAR_SRC_ADDRS_SUM_MSB 0x0A
31#define DAR_CCA1_ED_FNL 0x0B
32#define DAR_EVENT_TMR_LSB 0x0C
33#define DAR_EVENT_TMR_MSB 0x0D
34#define DAR_EVENT_TMR_USB 0x0E
35#define DAR_TIMESTAMP_LSB 0x0F
36#define DAR_TIMESTAMP_MSB 0x10
37#define DAR_TIMESTAMP_USB 0x11
38#define DAR_T3CMP_LSB 0x12
39#define DAR_T3CMP_MSB 0x13
40#define DAR_T3CMP_USB 0x14
41#define DAR_T2PRIMECMP_LSB 0x15
42#define DAR_T2PRIMECMP_MSB 0x16
43#define DAR_T1CMP_LSB 0x17
44#define DAR_T1CMP_MSB 0x18
45#define DAR_T1CMP_USB 0x19
46#define DAR_T2CMP_LSB 0x1A
47#define DAR_T2CMP_MSB 0x1B
48#define DAR_T2CMP_USB 0x1C
49#define DAR_T4CMP_LSB 0x1D
50#define DAR_T4CMP_MSB 0x1E
51#define DAR_T4CMP_USB 0x1F
52#define DAR_PLL_INT0 0x20
53#define DAR_PLL_FRAC0_LSB 0x21
54#define DAR_PLL_FRAC0_MSB 0x22
55#define DAR_PA_PWR 0x23
56#define DAR_SEQ_STATE 0x24
57#define DAR_LQI_VALUE 0x25
58#define DAR_RSSI_CCA_CONT 0x26
59/*------------------ 0x27 */
60#define DAR_ASM_CTRL1 0x28
61#define DAR_ASM_CTRL2 0x29
62#define DAR_ASM_DATA_0 0x2A
63#define DAR_ASM_DATA_1 0x2B
64#define DAR_ASM_DATA_2 0x2C
65#define DAR_ASM_DATA_3 0x2D
66#define DAR_ASM_DATA_4 0x2E
67#define DAR_ASM_DATA_5 0x2F
68#define DAR_ASM_DATA_6 0x30
69#define DAR_ASM_DATA_7 0x31
70#define DAR_ASM_DATA_8 0x32
71#define DAR_ASM_DATA_9 0x33
72#define DAR_ASM_DATA_A 0x34
73#define DAR_ASM_DATA_B 0x35
74#define DAR_ASM_DATA_C 0x36
75#define DAR_ASM_DATA_D 0x37
76#define DAR_ASM_DATA_E 0x38
77#define DAR_ASM_DATA_F 0x39
78/*----------------------- 0x3A */
79#define DAR_OVERWRITE_VER 0x3B
80#define DAR_CLK_OUT_CTRL 0x3C
81#define DAR_PWR_MODES 0x3D
82#define IAR_INDEX 0x3E
83#define IAR_DATA 0x3F
84
85/* Indirect Resgister Memory */
86#define IAR_PART_ID 0x00
87#define IAR_XTAL_TRIM 0x01
88#define IAR_PMC_LP_TRIM 0x02
89#define IAR_MACPANID0_LSB 0x03
90#define IAR_MACPANID0_MSB 0x04
91#define IAR_MACSHORTADDRS0_LSB 0x05
92#define IAR_MACSHORTADDRS0_MSB 0x06
93#define IAR_MACLONGADDRS0_0 0x07
94#define IAR_MACLONGADDRS0_8 0x08
95#define IAR_MACLONGADDRS0_16 0x09
96#define IAR_MACLONGADDRS0_24 0x0A
97#define IAR_MACLONGADDRS0_32 0x0B
98#define IAR_MACLONGADDRS0_40 0x0C
99#define IAR_MACLONGADDRS0_48 0x0D
100#define IAR_MACLONGADDRS0_56 0x0E
101#define IAR_RX_FRAME_FILTER 0x0F
102#define IAR_PLL_INT1 0x10
103#define IAR_PLL_FRAC1_LSB 0x11
104#define IAR_PLL_FRAC1_MSB 0x12
105#define IAR_MACPANID1_LSB 0x13
106#define IAR_MACPANID1_MSB 0x14
107#define IAR_MACSHORTADDRS1_LSB 0x15
108#define IAR_MACSHORTADDRS1_MSB 0x16
109#define IAR_MACLONGADDRS1_0 0x17
110#define IAR_MACLONGADDRS1_8 0x18
111#define IAR_MACLONGADDRS1_16 0x19
112#define IAR_MACLONGADDRS1_24 0x1A
113#define IAR_MACLONGADDRS1_32 0x1B
114#define IAR_MACLONGADDRS1_40 0x1C
115#define IAR_MACLONGADDRS1_48 0x1D
116#define IAR_MACLONGADDRS1_56 0x1E
117#define IAR_DUAL_PAN_CTRL 0x1F
118#define IAR_DUAL_PAN_DWELL 0x20
119#define IAR_DUAL_PAN_STS 0x21
120#define IAR_CCA1_THRESH 0x22
121#define IAR_CCA1_ED_OFFSET_COMP 0x23
122#define IAR_LQI_OFFSET_COMP 0x24
123#define IAR_CCA_CTRL 0x25
124#define IAR_CCA2_CORR_PEAKS 0x26
125#define IAR_CCA2_CORR_THRESH 0x27
126#define IAR_TMR_PRESCALE 0x28
127/*-------------------- 0x29 */
128#define IAR_GPIO_DATA 0x2A
129#define IAR_GPIO_DIR 0x2B
130#define IAR_GPIO_PUL_EN 0x2C
131#define IAR_GPIO_PUL_SEL 0x2D
132#define IAR_GPIO_DS 0x2E
133/*------------------ 0x2F */
134#define IAR_ANT_PAD_CTRL 0x30
135#define IAR_MISC_PAD_CTRL 0x31
136#define IAR_BSM_CTRL 0x32
137/*------------------- 0x33 */
138#define IAR_RNG 0x34
139#define IAR_RX_BYTE_COUNT 0x35
140#define IAR_RX_WTR_MARK 0x36
141#define IAR_SOFT_RESET 0x37
142#define IAR_TXDELAY 0x38
143#define IAR_ACKDELAY 0x39
144#define IAR_SEQ_MGR_CTRL 0x3A
145#define IAR_SEQ_MGR_STS 0x3B
146#define IAR_SEQ_T_STS 0x3C
147#define IAR_ABORT_STS 0x3D
148#define IAR_CCCA_BUSY_CNT 0x3E
149#define IAR_SRC_ADDR_CHECKSUM1 0x3F
150#define IAR_SRC_ADDR_CHECKSUM2 0x40
151#define IAR_SRC_TBL_VALID1 0x41
152#define IAR_SRC_TBL_VALID2 0x42
153#define IAR_FILTERFAIL_CODE1 0x43
154#define IAR_FILTERFAIL_CODE2 0x44
155#define IAR_SLOT_PRELOAD 0x45
156/*-------------------- 0x46 */
157#define IAR_CORR_VT 0x47
158#define IAR_SYNC_CTRL 0x48
159#define IAR_PN_LSB_0 0x49
160#define IAR_PN_LSB_1 0x4A
161#define IAR_PN_MSB_0 0x4B
162#define IAR_PN_MSB_1 0x4C
163#define IAR_CORR_NVAL 0x4D
164#define IAR_TX_MODE_CTRL 0x4E
165#define IAR_SNF_THR 0x4F
166#define IAR_FAD_THR 0x50
167#define IAR_ANT_AGC_CTRL 0x51
168#define IAR_AGC_THR1 0x52
169#define IAR_AGC_THR2 0x53
170#define IAR_AGC_HYS 0x54
171#define IAR_AFC 0x55
172/*------------------- 0x56 */
173/*------------------- 0x57 */
174#define IAR_PHY_STS 0x58
175#define IAR_RX_MAX_CORR 0x59
176#define IAR_RX_MAX_PREAMBLE 0x5A
177#define IAR_RSSI 0x5B
178/*------------------- 0x5C */
179/*------------------- 0x5D */
180#define IAR_PLL_DIG_CTRL 0x5E
181#define IAR_VCO_CAL 0x5F
182#define IAR_VCO_BEST_DIFF 0x60
183#define IAR_VCO_BIAS 0x61
184#define IAR_KMOD_CTRL 0x62
185#define IAR_KMOD_CAL 0x63
186#define IAR_PA_CAL 0x64
187#define IAR_PA_PWRCAL 0x65
188#define IAR_ATT_RSSI1 0x66
189#define IAR_ATT_RSSI2 0x67
190#define IAR_RSSI_OFFSET 0x68
191#define IAR_RSSI_SLOPE 0x69
192#define IAR_RSSI_CAL1 0x6A
193#define IAR_RSSI_CAL2 0x6B
194/*------------------- 0x6C */
195/*------------------- 0x6D */
196#define IAR_XTAL_CTRL 0x6E
197#define IAR_XTAL_COMP_MIN 0x6F
198#define IAR_XTAL_COMP_MAX 0x70
199#define IAR_XTAL_GM 0x71
200/*------------------- 0x72 */
201/*------------------- 0x73 */
202#define IAR_LNA_TUNE 0x74
203#define IAR_LNA_AGCGAIN 0x75
204/*------------------- 0x76 */
205/*------------------- 0x77 */
206#define IAR_CHF_PMA_GAIN 0x78
207#define IAR_CHF_IBUF 0x79
208#define IAR_CHF_QBUF 0x7A
209#define IAR_CHF_IRIN 0x7B
210#define IAR_CHF_QRIN 0x7C
211#define IAR_CHF_IL 0x7D
212#define IAR_CHF_QL 0x7E
213#define IAR_CHF_CC1 0x7F
214#define IAR_CHF_CCL 0x80
215#define IAR_CHF_CC2 0x81
216#define IAR_CHF_IROUT 0x82
217#define IAR_CHF_QROUT 0x83
218/*------------------- 0x84 */
219/*------------------- 0x85 */
220#define IAR_RSSI_CTRL 0x86
221/*------------------- 0x87 */
222/*------------------- 0x88 */
223#define IAR_PA_BIAS 0x89
224#define IAR_PA_TUNING 0x8A
225/*------------------- 0x8B */
226/*------------------- 0x8C */
227#define IAR_PMC_HP_TRIM 0x8D
228#define IAR_VREGA_TRIM 0x8E
229/*------------------- 0x8F */
230/*------------------- 0x90 */
231#define IAR_VCO_CTRL1 0x91
232#define IAR_VCO_CTRL2 0x92
233/*------------------- 0x93 */
234/*------------------- 0x94 */
235#define IAR_ANA_SPARE_OUT1 0x95
236#define IAR_ANA_SPARE_OUT2 0x96
237#define IAR_ANA_SPARE_IN 0x97
238#define IAR_MISCELLANEOUS 0x98
239/*------------------- 0x99 */
240#define IAR_SEQ_MGR_OVRD0 0x9A
241#define IAR_SEQ_MGR_OVRD1 0x9B
242#define IAR_SEQ_MGR_OVRD2 0x9C
243#define IAR_SEQ_MGR_OVRD3 0x9D
244#define IAR_SEQ_MGR_OVRD4 0x9E
245#define IAR_SEQ_MGR_OVRD5 0x9F
246#define IAR_SEQ_MGR_OVRD6 0xA0
247#define IAR_SEQ_MGR_OVRD7 0xA1
248/*------------------- 0xA2 */
249#define IAR_TESTMODE_CTRL 0xA3
250#define IAR_DTM_CTRL1 0xA4
251#define IAR_DTM_CTRL2 0xA5
252#define IAR_ATM_CTRL1 0xA6
253#define IAR_ATM_CTRL2 0xA7
254#define IAR_ATM_CTRL3 0xA8
255/*------------------- 0xA9 */
256#define IAR_LIM_FE_TEST_CTRL 0xAA
257#define IAR_CHF_TEST_CTRL 0xAB
258#define IAR_VCO_TEST_CTRL 0xAC
259#define IAR_PLL_TEST_CTRL 0xAD
260#define IAR_PA_TEST_CTRL 0xAE
261#define IAR_PMC_TEST_CTRL 0xAF
262#define IAR_SCAN_DTM_PROTECT_1 0xFE
263#define IAR_SCAN_DTM_PROTECT_0 0xFF
264
265/* IRQSTS1 bits */
266#define DAR_IRQSTS1_RX_FRM_PEND BIT(7)
267#define DAR_IRQSTS1_PLL_UNLOCK_IRQ BIT(6)
268#define DAR_IRQSTS1_FILTERFAIL_IRQ BIT(5)
269#define DAR_IRQSTS1_RXWTRMRKIRQ BIT(4)
270#define DAR_IRQSTS1_CCAIRQ BIT(3)
271#define DAR_IRQSTS1_RXIRQ BIT(2)
272#define DAR_IRQSTS1_TXIRQ BIT(1)
273#define DAR_IRQSTS1_SEQIRQ BIT(0)
274
275/* IRQSTS2 bits */
276#define DAR_IRQSTS2_CRCVALID BIT(7)
277#define DAR_IRQSTS2_CCA BIT(6)
278#define DAR_IRQSTS2_SRCADDR BIT(5)
279#define DAR_IRQSTS2_PI BIT(4)
280#define DAR_IRQSTS2_TMRSTATUS BIT(3)
281#define DAR_IRQSTS2_ASM_IRQ BIT(2)
282#define DAR_IRQSTS2_PB_ERR_IRQ BIT(1)
283#define DAR_IRQSTS2_WAKE_IRQ BIT(0)
284
285/* IRQSTS3 bits */
286#define DAR_IRQSTS3_TMR4MSK BIT(7)
287#define DAR_IRQSTS3_TMR3MSK BIT(6)
288#define DAR_IRQSTS3_TMR2MSK BIT(5)
289#define DAR_IRQSTS3_TMR1MSK BIT(4)
290#define DAR_IRQSTS3_TMR4IRQ BIT(3)
291#define DAR_IRQSTS3_TMR3IRQ BIT(2)
292#define DAR_IRQSTS3_TMR2IRQ BIT(1)
293#define DAR_IRQSTS3_TMR1IRQ BIT(0)
294
295/* PHY_CTRL1 bits */
296#define DAR_PHY_CTRL1_TMRTRIGEN BIT(7)
297#define DAR_PHY_CTRL1_SLOTTED BIT(6)
298#define DAR_PHY_CTRL1_CCABFRTX BIT(5)
299#define DAR_PHY_CTRL1_CCABFRTX_SHIFT 5
300#define DAR_PHY_CTRL1_RXACKRQD BIT(4)
301#define DAR_PHY_CTRL1_AUTOACK BIT(3)
302#define DAR_PHY_CTRL1_XCVSEQ_MASK 0x07
303
304/* PHY_CTRL2 bits */
305#define DAR_PHY_CTRL2_CRC_MSK BIT(7)
306#define DAR_PHY_CTRL2_PLL_UNLOCK_MSK BIT(6)
307#define DAR_PHY_CTRL2_FILTERFAIL_MSK BIT(5)
308#define DAR_PHY_CTRL2_RX_WMRK_MSK BIT(4)
309#define DAR_PHY_CTRL2_CCAMSK BIT(3)
310#define DAR_PHY_CTRL2_RXMSK BIT(2)
311#define DAR_PHY_CTRL2_TXMSK BIT(1)
312#define DAR_PHY_CTRL2_SEQMSK BIT(0)
313
314/* PHY_CTRL3 bits */
315#define DAR_PHY_CTRL3_TMR4CMP_EN BIT(7)
316#define DAR_PHY_CTRL3_TMR3CMP_EN BIT(6)
317#define DAR_PHY_CTRL3_TMR2CMP_EN BIT(5)
318#define DAR_PHY_CTRL3_TMR1CMP_EN BIT(4)
319#define DAR_PHY_CTRL3_ASM_MSK BIT(2)
320#define DAR_PHY_CTRL3_PB_ERR_MSK BIT(1)
321#define DAR_PHY_CTRL3_WAKE_MSK BIT(0)
322
323/* RX_FRM_LEN bits */
324#define DAR_RX_FRAME_LENGTH_MASK (0x7F)
325
326/* PHY_CTRL4 bits */
327#define DAR_PHY_CTRL4_TRCV_MSK BIT(7)
328#define DAR_PHY_CTRL4_TC3TMOUT BIT(6)
329#define DAR_PHY_CTRL4_PANCORDNTR0 BIT(5)
330#define DAR_PHY_CTRL4_CCATYPE (3)
331#define DAR_PHY_CTRL4_CCATYPE_SHIFT (3)
332#define DAR_PHY_CTRL4_CCATYPE_MASK (0x18)
333#define DAR_PHY_CTRL4_TMRLOAD BIT(2)
334#define DAR_PHY_CTRL4_PROMISCUOUS BIT(1)
335#define DAR_PHY_CTRL4_TC2PRIME_EN BIT(0)
336
337/* SRC_CTRL bits */
338#define DAR_SRC_CTRL_INDEX (0x0F)
339#define DAR_SRC_CTRL_INDEX_SHIFT (4)
340#define DAR_SRC_CTRL_ACK_FRM_PND BIT(3)
341#define DAR_SRC_CTRL_SRCADDR_EN BIT(2)
342#define DAR_SRC_CTRL_INDEX_EN BIT(1)
343#define DAR_SRC_CTRL_INDEX_DISABLE BIT(0)
344
345/* DAR_ASM_CTRL1 bits */
346#define DAR_ASM_CTRL1_CLEAR BIT(7)
347#define DAR_ASM_CTRL1_START BIT(6)
348#define DAR_ASM_CTRL1_SELFTST BIT(5)
349#define DAR_ASM_CTRL1_CTR BIT(4)
350#define DAR_ASM_CTRL1_CBC BIT(3)
351#define DAR_ASM_CTRL1_AES BIT(2)
352#define DAR_ASM_CTRL1_LOAD_MAC BIT(1)
353
354/* DAR_ASM_CTRL2 bits */
355#define DAR_ASM_CTRL2_DATA_REG_TYPE_SEL (7)
356#define DAR_ASM_CTRL2_DATA_REG_TYPE_SEL_SHIFT (5)
357#define DAR_ASM_CTRL2_TSTPAS BIT(1)
358
359/* DAR_CLK_OUT_CTRL bits */
360#define DAR_CLK_OUT_CTRL_EXTEND BIT(7)
361#define DAR_CLK_OUT_CTRL_HIZ BIT(6)
362#define DAR_CLK_OUT_CTRL_SR BIT(5)
363#define DAR_CLK_OUT_CTRL_DS BIT(4)
364#define DAR_CLK_OUT_CTRL_EN BIT(3)
365#define DAR_CLK_OUT_CTRL_DIV (7)
366
367/* DAR_PWR_MODES bits */
368#define DAR_PWR_MODES_XTAL_READY BIT(5)
369#define DAR_PWR_MODES_XTALEN BIT(4)
370#define DAR_PWR_MODES_ASM_CLK_EN BIT(3)
371#define DAR_PWR_MODES_AUTODOZE BIT(1)
372#define DAR_PWR_MODES_PMC_MODE BIT(0)
373
374/* RX_FRAME_FILTER bits */
375#define IAR_RX_FRAME_FLT_FRM_VER (0xC0)
376#define IAR_RX_FRAME_FLT_FRM_VER_SHIFT (6)
377#define IAR_RX_FRAME_FLT_ACTIVE_PROMISCUOUS BIT(5)
378#define IAR_RX_FRAME_FLT_NS_FT BIT(4)
379#define IAR_RX_FRAME_FLT_CMD_FT BIT(3)
380#define IAR_RX_FRAME_FLT_ACK_FT BIT(2)
381#define IAR_RX_FRAME_FLT_DATA_FT BIT(1)
382#define IAR_RX_FRAME_FLT_BEACON_FT BIT(0)
383
384/* DUAL_PAN_CTRL bits */
385#define IAR_DUAL_PAN_CTRL_DUAL_PAN_SAM_LVL_MSK (0xF0)
386#define IAR_DUAL_PAN_CTRL_DUAL_PAN_SAM_LVL_SHIFT (4)
387#define IAR_DUAL_PAN_CTRL_CURRENT_NETWORK BIT(3)
388#define IAR_DUAL_PAN_CTRL_PANCORDNTR1 BIT(2)
389#define IAR_DUAL_PAN_CTRL_DUAL_PAN_AUTO BIT(1)
390#define IAR_DUAL_PAN_CTRL_ACTIVE_NETWORK BIT(0)
391
392/* DUAL_PAN_STS bits */
393#define IAR_DUAL_PAN_STS_RECD_ON_PAN1 BIT(7)
394#define IAR_DUAL_PAN_STS_RECD_ON_PAN0 BIT(6)
395#define IAR_DUAL_PAN_STS_DUAL_PAN_REMAIN (0x3F)
396
397/* CCA_CTRL bits */
398#define IAR_CCA_CTRL_AGC_FRZ_EN BIT(6)
399#define IAR_CCA_CTRL_CONT_RSSI_EN BIT(5)
400#define IAR_CCA_CTRL_LQI_RSSI_NOT_CORR BIT(4)
401#define IAR_CCA_CTRL_CCA3_AND_NOT_OR BIT(3)
402#define IAR_CCA_CTRL_POWER_COMP_EN_LQI BIT(2)
403#define IAR_CCA_CTRL_POWER_COMP_EN_ED BIT(1)
404#define IAR_CCA_CTRL_POWER_COMP_EN_CCA1 BIT(0)
405
406/* ANT_PAD_CTRL bits */
407#define IAR_ANT_PAD_CTRL_ANTX_POL (0x0F)
408#define IAR_ANT_PAD_CTRL_ANTX_POL_SHIFT (4)
409#define IAR_ANT_PAD_CTRL_ANTX_CTRLMODE BIT(3)
410#define IAR_ANT_PAD_CTRL_ANTX_HZ BIT(2)
411#define IAR_ANT_PAD_CTRL_ANTX_EN (3)
412
413/* MISC_PAD_CTRL bits */
414#define IAR_MISC_PAD_CTRL_MISO_HIZ_EN BIT(3)
415#define IAR_MISC_PAD_CTRL_IRQ_B_OD BIT(2)
416#define IAR_MISC_PAD_CTRL_NON_GPIO_DS BIT(1)
417#define IAR_MISC_PAD_CTRL_ANTX_CURR (1)
418
419/* ANT_AGC_CTRL bits */
420#define IAR_ANT_AGC_CTRL_FAD_EN_SHIFT (0)
421#define IAR_ANT_AGC_CTRL_FAD_EN_MASK (1)
422#define IAR_ANT_AGC_CTRL_ANTX_SHIFT (1)
423#define IAR_ANT_AGC_CTRL_ANTX_MASK BIT(AR_ANT_AGC_CTRL_ANTX_SHIFT)
424
425/* BSM_CTRL bits */
426#define BSM_CTRL_BSM_EN (1)
427
428/* SOFT_RESET bits */
429#define IAR_SOFT_RESET_SOG_RST BIT(7)
430#define IAR_SOFT_RESET_REGS_RST BIT(4)
431#define IAR_SOFT_RESET_PLL_RST BIT(3)
432#define IAR_SOFT_RESET_TX_RST BIT(2)
433#define IAR_SOFT_RESET_RX_RST BIT(1)
434#define IAR_SOFT_RESET_SEQ_MGR_RST BIT(0)
435
436/* SEQ_MGR_CTRL bits */
437#define IAR_SEQ_MGR_CTRL_SEQ_STATE_CTRL (3)
438#define IAR_SEQ_MGR_CTRL_SEQ_STATE_CTRL_SHIFT (6)
439#define IAR_SEQ_MGR_CTRL_NO_RX_RECYCLE BIT(5)
440#define IAR_SEQ_MGR_CTRL_LATCH_PREAMBLE BIT(4)
441#define IAR_SEQ_MGR_CTRL_EVENT_TMR_DO_NOT_LATCH BIT(3)
442#define IAR_SEQ_MGR_CTRL_CLR_NEW_SEQ_INHIBIT BIT(2)
443#define IAR_SEQ_MGR_CTRL_PSM_LOCK_DIS BIT(1)
444#define IAR_SEQ_MGR_CTRL_PLL_ABORT_OVRD BIT(0)
445
446/* SEQ_MGR_STS bits */
447#define IAR_SEQ_MGR_STS_TMR2_SEQ_TRIG_ARMED BIT(7)
448#define IAR_SEQ_MGR_STS_RX_MODE BIT(6)
449#define IAR_SEQ_MGR_STS_RX_TIMEOUT_PENDING BIT(5)
450#define IAR_SEQ_MGR_STS_NEW_SEQ_INHIBIT BIT(4)
451#define IAR_SEQ_MGR_STS_SEQ_IDLE BIT(3)
452#define IAR_SEQ_MGR_STS_XCVSEQ_ACTUAL (7)
453
454/* ABORT_STS bits */
455#define IAR_ABORT_STS_PLL_ABORTED BIT(2)
456#define IAR_ABORT_STS_TC3_ABORTED BIT(1)
457#define IAR_ABORT_STS_SW_ABORTED BIT(0)
458
459/* IAR_FILTERFAIL_CODE2 bits */
460#define IAR_FILTERFAIL_CODE2_PAN_SEL BIT(7)
461#define IAR_FILTERFAIL_CODE2_9_8 (3)
462
463/* PHY_STS bits */
464#define IAR_PHY_STS_PLL_UNLOCK BIT(7)
465#define IAR_PHY_STS_PLL_LOCK_ERR BIT(6)
466#define IAR_PHY_STS_PLL_LOCK BIT(5)
467#define IAR_PHY_STS_CRCVALID BIT(3)
468#define IAR_PHY_STS_FILTERFAIL_FLAG_SEL BIT(2)
469#define IAR_PHY_STS_SFD_DET BIT(1)
470#define IAR_PHY_STS_PREAMBLE_DET BIT(0)
471
472/* TESTMODE_CTRL bits */
473#define IAR_TEST_MODE_CTRL_HOT_ANT BIT(4)
474#define IAR_TEST_MODE_CTRL_IDEAL_RSSI_EN BIT(3)
475#define IAR_TEST_MODE_CTRL_IDEAL_PFC_EN BIT(2)
476#define IAR_TEST_MODE_CTRL_CONTINUOUS_EN BIT(1)
477#define IAR_TEST_MODE_CTRL_FPGA_EN BIT(0)
478
479/* DTM_CTRL1 bits */
480#define IAR_DTM_CTRL1_ATM_LOCKED BIT(7)
481#define IAR_DTM_CTRL1_DTM_EN BIT(6)
482#define IAR_DTM_CTRL1_PAGE5 BIT(5)
483#define IAR_DTM_CTRL1_PAGE4 BIT(4)
484#define IAR_DTM_CTRL1_PAGE3 BIT(3)
485#define IAR_DTM_CTRL1_PAGE2 BIT(2)
486#define IAR_DTM_CTRL1_PAGE1 BIT(1)
487#define IAR_DTM_CTRL1_PAGE0 BIT(0)
488
489/* TX_MODE_CTRL */
490#define IAR_TX_MODE_CTRL_TX_INV BIT(4)
491#define IAR_TX_MODE_CTRL_BT_EN BIT(3)
492#define IAR_TX_MODE_CTRL_DTS2 BIT(2)
493#define IAR_TX_MODE_CTRL_DTS1 BIT(1)
494#define IAR_TX_MODE_CTRL_DTS0 BIT(0)
495
496#define TX_MODE_CTRL_DTS_MASK (7)
497
498#endif /* _MCR20A_H */
diff --git a/drivers/net/ipvlan/ipvlan.h b/drivers/net/ipvlan/ipvlan.h
index 5166575a164d..adb826f55e60 100644
--- a/drivers/net/ipvlan/ipvlan.h
+++ b/drivers/net/ipvlan/ipvlan.h
@@ -74,6 +74,7 @@ struct ipvl_dev {
74 DECLARE_BITMAP(mac_filters, IPVLAN_MAC_FILTER_SIZE); 74 DECLARE_BITMAP(mac_filters, IPVLAN_MAC_FILTER_SIZE);
75 netdev_features_t sfeatures; 75 netdev_features_t sfeatures;
76 u32 msg_enable; 76 u32 msg_enable;
77 spinlock_t addrs_lock;
77}; 78};
78 79
79struct ipvl_addr { 80struct ipvl_addr {
@@ -176,4 +177,10 @@ int ipvlan_link_new(struct net *src_net, struct net_device *dev,
176void ipvlan_link_delete(struct net_device *dev, struct list_head *head); 177void ipvlan_link_delete(struct net_device *dev, struct list_head *head);
177void ipvlan_link_setup(struct net_device *dev); 178void ipvlan_link_setup(struct net_device *dev);
178int ipvlan_link_register(struct rtnl_link_ops *ops); 179int ipvlan_link_register(struct rtnl_link_ops *ops);
180
181static inline bool netif_is_ipvlan_port(const struct net_device *dev)
182{
183 return rcu_access_pointer(dev->rx_handler) == ipvlan_handle_frame;
184}
185
179#endif /* __IPVLAN_H */ 186#endif /* __IPVLAN_H */
diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c
index c1f008fe4e1d..1a8132eb2a3e 100644
--- a/drivers/net/ipvlan/ipvlan_core.c
+++ b/drivers/net/ipvlan/ipvlan_core.c
@@ -35,6 +35,7 @@ void ipvlan_count_rx(const struct ipvl_dev *ipvlan,
35} 35}
36EXPORT_SYMBOL_GPL(ipvlan_count_rx); 36EXPORT_SYMBOL_GPL(ipvlan_count_rx);
37 37
38#if IS_ENABLED(CONFIG_IPV6)
38static u8 ipvlan_get_v6_hash(const void *iaddr) 39static u8 ipvlan_get_v6_hash(const void *iaddr)
39{ 40{
40 const struct in6_addr *ip6_addr = iaddr; 41 const struct in6_addr *ip6_addr = iaddr;
@@ -42,6 +43,12 @@ static u8 ipvlan_get_v6_hash(const void *iaddr)
42 return __ipv6_addr_jhash(ip6_addr, ipvlan_jhash_secret) & 43 return __ipv6_addr_jhash(ip6_addr, ipvlan_jhash_secret) &
43 IPVLAN_HASH_MASK; 44 IPVLAN_HASH_MASK;
44} 45}
46#else
47static u8 ipvlan_get_v6_hash(const void *iaddr)
48{
49 return 0;
50}
51#endif
45 52
46static u8 ipvlan_get_v4_hash(const void *iaddr) 53static u8 ipvlan_get_v4_hash(const void *iaddr)
47{ 54{
@@ -51,6 +58,23 @@ static u8 ipvlan_get_v4_hash(const void *iaddr)
51 IPVLAN_HASH_MASK; 58 IPVLAN_HASH_MASK;
52} 59}
53 60
61static bool addr_equal(bool is_v6, struct ipvl_addr *addr, const void *iaddr)
62{
63 if (!is_v6 && addr->atype == IPVL_IPV4) {
64 struct in_addr *i4addr = (struct in_addr *)iaddr;
65
66 return addr->ip4addr.s_addr == i4addr->s_addr;
67#if IS_ENABLED(CONFIG_IPV6)
68 } else if (is_v6 && addr->atype == IPVL_IPV6) {
69 struct in6_addr *i6addr = (struct in6_addr *)iaddr;
70
71 return ipv6_addr_equal(&addr->ip6addr, i6addr);
72#endif
73 }
74
75 return false;
76}
77
54static struct ipvl_addr *ipvlan_ht_addr_lookup(const struct ipvl_port *port, 78static struct ipvl_addr *ipvlan_ht_addr_lookup(const struct ipvl_port *port,
55 const void *iaddr, bool is_v6) 79 const void *iaddr, bool is_v6)
56{ 80{
@@ -59,15 +83,9 @@ static struct ipvl_addr *ipvlan_ht_addr_lookup(const struct ipvl_port *port,
59 83
60 hash = is_v6 ? ipvlan_get_v6_hash(iaddr) : 84 hash = is_v6 ? ipvlan_get_v6_hash(iaddr) :
61 ipvlan_get_v4_hash(iaddr); 85 ipvlan_get_v4_hash(iaddr);
62 hlist_for_each_entry_rcu(addr, &port->hlhead[hash], hlnode) { 86 hlist_for_each_entry_rcu(addr, &port->hlhead[hash], hlnode)
63 if (is_v6 && addr->atype == IPVL_IPV6 && 87 if (addr_equal(is_v6, addr, iaddr))
64 ipv6_addr_equal(&addr->ip6addr, iaddr))
65 return addr;
66 else if (!is_v6 && addr->atype == IPVL_IPV4 &&
67 addr->ip4addr.s_addr ==
68 ((struct in_addr *)iaddr)->s_addr)
69 return addr; 88 return addr;
70 }
71 return NULL; 89 return NULL;
72} 90}
73 91
@@ -91,29 +109,33 @@ void ipvlan_ht_addr_del(struct ipvl_addr *addr)
91struct ipvl_addr *ipvlan_find_addr(const struct ipvl_dev *ipvlan, 109struct ipvl_addr *ipvlan_find_addr(const struct ipvl_dev *ipvlan,
92 const void *iaddr, bool is_v6) 110 const void *iaddr, bool is_v6)
93{ 111{
94 struct ipvl_addr *addr; 112 struct ipvl_addr *addr, *ret = NULL;
95 113
96 list_for_each_entry(addr, &ipvlan->addrs, anode) { 114 rcu_read_lock();
97 if ((is_v6 && addr->atype == IPVL_IPV6 && 115 list_for_each_entry_rcu(addr, &ipvlan->addrs, anode) {
98 ipv6_addr_equal(&addr->ip6addr, iaddr)) || 116 if (addr_equal(is_v6, addr, iaddr)) {
99 (!is_v6 && addr->atype == IPVL_IPV4 && 117 ret = addr;
100 addr->ip4addr.s_addr == ((struct in_addr *)iaddr)->s_addr)) 118 break;
101 return addr; 119 }
102 } 120 }
103 return NULL; 121 rcu_read_unlock();
122 return ret;
104} 123}
105 124
106bool ipvlan_addr_busy(struct ipvl_port *port, void *iaddr, bool is_v6) 125bool ipvlan_addr_busy(struct ipvl_port *port, void *iaddr, bool is_v6)
107{ 126{
108 struct ipvl_dev *ipvlan; 127 struct ipvl_dev *ipvlan;
128 bool ret = false;
109 129
110 ASSERT_RTNL(); 130 rcu_read_lock();
111 131 list_for_each_entry_rcu(ipvlan, &port->ipvlans, pnode) {
112 list_for_each_entry(ipvlan, &port->ipvlans, pnode) { 132 if (ipvlan_find_addr(ipvlan, iaddr, is_v6)) {
113 if (ipvlan_find_addr(ipvlan, iaddr, is_v6)) 133 ret = true;
114 return true; 134 break;
135 }
115 } 136 }
116 return false; 137 rcu_read_unlock();
138 return ret;
117} 139}
118 140
119static void *ipvlan_get_L3_hdr(struct ipvl_port *port, struct sk_buff *skb, int *type) 141static void *ipvlan_get_L3_hdr(struct ipvl_port *port, struct sk_buff *skb, int *type)
@@ -150,6 +172,7 @@ static void *ipvlan_get_L3_hdr(struct ipvl_port *port, struct sk_buff *skb, int
150 lyr3h = ip4h; 172 lyr3h = ip4h;
151 break; 173 break;
152 } 174 }
175#if IS_ENABLED(CONFIG_IPV6)
153 case htons(ETH_P_IPV6): { 176 case htons(ETH_P_IPV6): {
154 struct ipv6hdr *ip6h; 177 struct ipv6hdr *ip6h;
155 178
@@ -188,6 +211,7 @@ static void *ipvlan_get_L3_hdr(struct ipvl_port *port, struct sk_buff *skb, int
188 } 211 }
189 break; 212 break;
190 } 213 }
214#endif
191 default: 215 default:
192 return NULL; 216 return NULL;
193 } 217 }
@@ -337,14 +361,18 @@ static struct ipvl_addr *ipvlan_addr_lookup(struct ipvl_port *port,
337{ 361{
338 struct ipvl_addr *addr = NULL; 362 struct ipvl_addr *addr = NULL;
339 363
340 if (addr_type == IPVL_IPV6) { 364 switch (addr_type) {
365#if IS_ENABLED(CONFIG_IPV6)
366 case IPVL_IPV6: {
341 struct ipv6hdr *ip6h; 367 struct ipv6hdr *ip6h;
342 struct in6_addr *i6addr; 368 struct in6_addr *i6addr;
343 369
344 ip6h = (struct ipv6hdr *)lyr3h; 370 ip6h = (struct ipv6hdr *)lyr3h;
345 i6addr = use_dest ? &ip6h->daddr : &ip6h->saddr; 371 i6addr = use_dest ? &ip6h->daddr : &ip6h->saddr;
346 addr = ipvlan_ht_addr_lookup(port, i6addr, true); 372 addr = ipvlan_ht_addr_lookup(port, i6addr, true);
347 } else if (addr_type == IPVL_ICMPV6) { 373 break;
374 }
375 case IPVL_ICMPV6: {
348 struct nd_msg *ndmh; 376 struct nd_msg *ndmh;
349 struct in6_addr *i6addr; 377 struct in6_addr *i6addr;
350 378
@@ -356,14 +384,19 @@ static struct ipvl_addr *ipvlan_addr_lookup(struct ipvl_port *port,
356 i6addr = &ndmh->target; 384 i6addr = &ndmh->target;
357 addr = ipvlan_ht_addr_lookup(port, i6addr, true); 385 addr = ipvlan_ht_addr_lookup(port, i6addr, true);
358 } 386 }
359 } else if (addr_type == IPVL_IPV4) { 387 break;
388 }
389#endif
390 case IPVL_IPV4: {
360 struct iphdr *ip4h; 391 struct iphdr *ip4h;
361 __be32 *i4addr; 392 __be32 *i4addr;
362 393
363 ip4h = (struct iphdr *)lyr3h; 394 ip4h = (struct iphdr *)lyr3h;
364 i4addr = use_dest ? &ip4h->daddr : &ip4h->saddr; 395 i4addr = use_dest ? &ip4h->daddr : &ip4h->saddr;
365 addr = ipvlan_ht_addr_lookup(port, i4addr, false); 396 addr = ipvlan_ht_addr_lookup(port, i4addr, false);
366 } else if (addr_type == IPVL_ARP) { 397 break;
398 }
399 case IPVL_ARP: {
367 struct arphdr *arph; 400 struct arphdr *arph;
368 unsigned char *arp_ptr; 401 unsigned char *arp_ptr;
369 __be32 dip; 402 __be32 dip;
@@ -377,6 +410,8 @@ static struct ipvl_addr *ipvlan_addr_lookup(struct ipvl_port *port,
377 410
378 memcpy(&dip, arp_ptr, 4); 411 memcpy(&dip, arp_ptr, 4);
379 addr = ipvlan_ht_addr_lookup(port, &dip, false); 412 addr = ipvlan_ht_addr_lookup(port, &dip, false);
413 break;
414 }
380 } 415 }
381 416
382 return addr; 417 return addr;
@@ -420,6 +455,7 @@ out:
420 return ret; 455 return ret;
421} 456}
422 457
458#if IS_ENABLED(CONFIG_IPV6)
423static int ipvlan_process_v6_outbound(struct sk_buff *skb) 459static int ipvlan_process_v6_outbound(struct sk_buff *skb)
424{ 460{
425 const struct ipv6hdr *ip6h = ipv6_hdr(skb); 461 const struct ipv6hdr *ip6h = ipv6_hdr(skb);
@@ -456,6 +492,12 @@ err:
456out: 492out:
457 return ret; 493 return ret;
458} 494}
495#else
496static int ipvlan_process_v6_outbound(struct sk_buff *skb)
497{
498 return NET_XMIT_DROP;
499}
500#endif
459 501
460static int ipvlan_process_outbound(struct sk_buff *skb) 502static int ipvlan_process_outbound(struct sk_buff *skb)
461{ 503{
@@ -464,8 +506,8 @@ static int ipvlan_process_outbound(struct sk_buff *skb)
464 506
465 /* In this mode we dont care about multicast and broadcast traffic */ 507 /* In this mode we dont care about multicast and broadcast traffic */
466 if (is_multicast_ether_addr(ethh->h_dest)) { 508 if (is_multicast_ether_addr(ethh->h_dest)) {
467 pr_warn_ratelimited("Dropped {multi|broad}cast of type= [%x]\n", 509 pr_debug_ratelimited("Dropped {multi|broad}cast of type=[%x]\n",
468 ntohs(skb->protocol)); 510 ntohs(skb->protocol));
469 kfree_skb(skb); 511 kfree_skb(skb);
470 goto out; 512 goto out;
471 } 513 }
@@ -759,6 +801,7 @@ struct sk_buff *ipvlan_l3_rcv(struct net_device *dev, struct sk_buff *skb,
759 goto out; 801 goto out;
760 break; 802 break;
761 } 803 }
804#if IS_ENABLED(CONFIG_IPV6)
762 case AF_INET6: 805 case AF_INET6:
763 { 806 {
764 struct dst_entry *dst; 807 struct dst_entry *dst;
@@ -774,10 +817,12 @@ struct sk_buff *ipvlan_l3_rcv(struct net_device *dev, struct sk_buff *skb,
774 }; 817 };
775 818
776 skb_dst_drop(skb); 819 skb_dst_drop(skb);
777 dst = ip6_route_input_lookup(dev_net(sdev), sdev, &fl6, flags); 820 dst = ip6_route_input_lookup(dev_net(sdev), sdev, &fl6,
821 skb, flags);
778 skb_dst_set(skb, dst); 822 skb_dst_set(skb, dst);
779 break; 823 break;
780 } 824 }
825#endif
781 default: 826 default:
782 break; 827 break;
783 } 828 }
diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c
index 2469df118fbf..743d37fb034a 100644
--- a/drivers/net/ipvlan/ipvlan_main.c
+++ b/drivers/net/ipvlan/ipvlan_main.c
@@ -22,12 +22,14 @@ static const struct nf_hook_ops ipvl_nfops[] = {
22 .hooknum = NF_INET_LOCAL_IN, 22 .hooknum = NF_INET_LOCAL_IN,
23 .priority = INT_MAX, 23 .priority = INT_MAX,
24 }, 24 },
25#if IS_ENABLED(CONFIG_IPV6)
25 { 26 {
26 .hook = ipvlan_nf_input, 27 .hook = ipvlan_nf_input,
27 .pf = NFPROTO_IPV6, 28 .pf = NFPROTO_IPV6,
28 .hooknum = NF_INET_LOCAL_IN, 29 .hooknum = NF_INET_LOCAL_IN,
29 .priority = INT_MAX, 30 .priority = INT_MAX,
30 }, 31 },
32#endif
31}; 33};
32 34
33static const struct l3mdev_ops ipvl_l3mdev_ops = { 35static const struct l3mdev_ops ipvl_l3mdev_ops = {
@@ -127,7 +129,6 @@ static int ipvlan_port_create(struct net_device *dev)
127 if (err) 129 if (err)
128 goto err; 130 goto err;
129 131
130 dev->priv_flags |= IFF_IPVLAN_MASTER;
131 return 0; 132 return 0;
132 133
133err: 134err:
@@ -140,7 +141,6 @@ static void ipvlan_port_destroy(struct net_device *dev)
140 struct ipvl_port *port = ipvlan_port_get_rtnl(dev); 141 struct ipvl_port *port = ipvlan_port_get_rtnl(dev);
141 struct sk_buff *skb; 142 struct sk_buff *skb;
142 143
143 dev->priv_flags &= ~IFF_IPVLAN_MASTER;
144 if (port->mode == IPVLAN_MODE_L3S) { 144 if (port->mode == IPVLAN_MODE_L3S) {
145 dev->priv_flags &= ~IFF_L3MDEV_MASTER; 145 dev->priv_flags &= ~IFF_L3MDEV_MASTER;
146 ipvlan_unregister_nf_hook(dev_net(dev)); 146 ipvlan_unregister_nf_hook(dev_net(dev));
@@ -176,7 +176,7 @@ static int ipvlan_init(struct net_device *dev)
176 dev->state = (dev->state & ~IPVLAN_STATE_MASK) | 176 dev->state = (dev->state & ~IPVLAN_STATE_MASK) |
177 (phy_dev->state & IPVLAN_STATE_MASK); 177 (phy_dev->state & IPVLAN_STATE_MASK);
178 dev->features = phy_dev->features & IPVLAN_FEATURES; 178 dev->features = phy_dev->features & IPVLAN_FEATURES;
179 dev->features |= NETIF_F_LLTX; 179 dev->features |= NETIF_F_LLTX | NETIF_F_VLAN_CHALLENGED;
180 dev->gso_max_size = phy_dev->gso_max_size; 180 dev->gso_max_size = phy_dev->gso_max_size;
181 dev->gso_max_segs = phy_dev->gso_max_segs; 181 dev->gso_max_segs = phy_dev->gso_max_segs;
182 dev->hard_header_len = phy_dev->hard_header_len; 182 dev->hard_header_len = phy_dev->hard_header_len;
@@ -225,8 +225,10 @@ static int ipvlan_open(struct net_device *dev)
225 else 225 else
226 dev->flags &= ~IFF_NOARP; 226 dev->flags &= ~IFF_NOARP;
227 227
228 list_for_each_entry(addr, &ipvlan->addrs, anode) 228 rcu_read_lock();
229 list_for_each_entry_rcu(addr, &ipvlan->addrs, anode)
229 ipvlan_ht_addr_add(ipvlan, addr); 230 ipvlan_ht_addr_add(ipvlan, addr);
231 rcu_read_unlock();
230 232
231 return dev_uc_add(phy_dev, phy_dev->dev_addr); 233 return dev_uc_add(phy_dev, phy_dev->dev_addr);
232} 234}
@@ -242,8 +244,10 @@ static int ipvlan_stop(struct net_device *dev)
242 244
243 dev_uc_del(phy_dev, phy_dev->dev_addr); 245 dev_uc_del(phy_dev, phy_dev->dev_addr);
244 246
245 list_for_each_entry(addr, &ipvlan->addrs, anode) 247 rcu_read_lock();
248 list_for_each_entry_rcu(addr, &ipvlan->addrs, anode)
246 ipvlan_ht_addr_del(addr); 249 ipvlan_ht_addr_del(addr);
250 rcu_read_unlock();
247 251
248 return 0; 252 return 0;
249} 253}
@@ -417,6 +421,12 @@ static const struct header_ops ipvlan_header_ops = {
417 .cache_update = eth_header_cache_update, 421 .cache_update = eth_header_cache_update,
418}; 422};
419 423
424static bool netif_is_ipvlan(const struct net_device *dev)
425{
426 /* both ipvlan and ipvtap devices use the same netdev_ops */
427 return dev->netdev_ops == &ipvlan_netdev_ops;
428}
429
420static int ipvlan_ethtool_get_link_ksettings(struct net_device *dev, 430static int ipvlan_ethtool_get_link_ksettings(struct net_device *dev,
421 struct ethtool_link_ksettings *cmd) 431 struct ethtool_link_ksettings *cmd)
422{ 432{
@@ -586,6 +596,7 @@ int ipvlan_link_new(struct net *src_net, struct net_device *dev,
586 ipvlan->sfeatures = IPVLAN_FEATURES; 596 ipvlan->sfeatures = IPVLAN_FEATURES;
587 ipvlan_adjust_mtu(ipvlan, phy_dev); 597 ipvlan_adjust_mtu(ipvlan, phy_dev);
588 INIT_LIST_HEAD(&ipvlan->addrs); 598 INIT_LIST_HEAD(&ipvlan->addrs);
599 spin_lock_init(&ipvlan->addrs_lock);
589 600
590 /* TODO Probably put random address here to be presented to the 601 /* TODO Probably put random address here to be presented to the
591 * world but keep using the physical-dev address for the outgoing 602 * world but keep using the physical-dev address for the outgoing
@@ -593,7 +604,7 @@ int ipvlan_link_new(struct net *src_net, struct net_device *dev,
593 */ 604 */
594 memcpy(dev->dev_addr, phy_dev->dev_addr, ETH_ALEN); 605 memcpy(dev->dev_addr, phy_dev->dev_addr, ETH_ALEN);
595 606
596 dev->priv_flags |= IFF_IPVLAN_SLAVE; 607 dev->priv_flags |= IFF_NO_RX_HANDLER;
597 608
598 err = register_netdevice(dev); 609 err = register_netdevice(dev);
599 if (err < 0) 610 if (err < 0)
@@ -663,11 +674,13 @@ void ipvlan_link_delete(struct net_device *dev, struct list_head *head)
663 struct ipvl_dev *ipvlan = netdev_priv(dev); 674 struct ipvl_dev *ipvlan = netdev_priv(dev);
664 struct ipvl_addr *addr, *next; 675 struct ipvl_addr *addr, *next;
665 676
677 spin_lock_bh(&ipvlan->addrs_lock);
666 list_for_each_entry_safe(addr, next, &ipvlan->addrs, anode) { 678 list_for_each_entry_safe(addr, next, &ipvlan->addrs, anode) {
667 ipvlan_ht_addr_del(addr); 679 ipvlan_ht_addr_del(addr);
668 list_del(&addr->anode); 680 list_del_rcu(&addr->anode);
669 kfree_rcu(addr, rcu); 681 kfree_rcu(addr, rcu);
670 } 682 }
683 spin_unlock_bh(&ipvlan->addrs_lock);
671 684
672 ida_simple_remove(&ipvlan->port->ida, dev->dev_id); 685 ida_simple_remove(&ipvlan->port->ida, dev->dev_id);
673 list_del_rcu(&ipvlan->pnode); 686 list_del_rcu(&ipvlan->pnode);
@@ -758,8 +771,7 @@ static int ipvlan_device_event(struct notifier_block *unused,
758 if (dev->reg_state != NETREG_UNREGISTERING) 771 if (dev->reg_state != NETREG_UNREGISTERING)
759 break; 772 break;
760 773
761 list_for_each_entry_safe(ipvlan, next, &port->ipvlans, 774 list_for_each_entry_safe(ipvlan, next, &port->ipvlans, pnode)
762 pnode)
763 ipvlan->dev->rtnl_link_ops->dellink(ipvlan->dev, 775 ipvlan->dev->rtnl_link_ops->dellink(ipvlan->dev,
764 &lst_kill); 776 &lst_kill);
765 unregister_netdevice_many(&lst_kill); 777 unregister_netdevice_many(&lst_kill);
@@ -791,6 +803,7 @@ static int ipvlan_device_event(struct notifier_block *unused,
791 return NOTIFY_DONE; 803 return NOTIFY_DONE;
792} 804}
793 805
806/* the caller must held the addrs lock */
794static int ipvlan_add_addr(struct ipvl_dev *ipvlan, void *iaddr, bool is_v6) 807static int ipvlan_add_addr(struct ipvl_dev *ipvlan, void *iaddr, bool is_v6)
795{ 808{
796 struct ipvl_addr *addr; 809 struct ipvl_addr *addr;
@@ -800,14 +813,17 @@ static int ipvlan_add_addr(struct ipvl_dev *ipvlan, void *iaddr, bool is_v6)
800 return -ENOMEM; 813 return -ENOMEM;
801 814
802 addr->master = ipvlan; 815 addr->master = ipvlan;
803 if (is_v6) { 816 if (!is_v6) {
804 memcpy(&addr->ip6addr, iaddr, sizeof(struct in6_addr));
805 addr->atype = IPVL_IPV6;
806 } else {
807 memcpy(&addr->ip4addr, iaddr, sizeof(struct in_addr)); 817 memcpy(&addr->ip4addr, iaddr, sizeof(struct in_addr));
808 addr->atype = IPVL_IPV4; 818 addr->atype = IPVL_IPV4;
819#if IS_ENABLED(CONFIG_IPV6)
820 } else {
821 memcpy(&addr->ip6addr, iaddr, sizeof(struct in6_addr));
822 addr->atype = IPVL_IPV6;
823#endif
809 } 824 }
810 list_add_tail(&addr->anode, &ipvlan->addrs); 825
826 list_add_tail_rcu(&addr->anode, &ipvlan->addrs);
811 827
812 /* If the interface is not up, the address will be added to the hash 828 /* If the interface is not up, the address will be added to the hash
813 * list by ipvlan_open. 829 * list by ipvlan_open.
@@ -822,32 +838,17 @@ static void ipvlan_del_addr(struct ipvl_dev *ipvlan, void *iaddr, bool is_v6)
822{ 838{
823 struct ipvl_addr *addr; 839 struct ipvl_addr *addr;
824 840
841 spin_lock_bh(&ipvlan->addrs_lock);
825 addr = ipvlan_find_addr(ipvlan, iaddr, is_v6); 842 addr = ipvlan_find_addr(ipvlan, iaddr, is_v6);
826 if (!addr) 843 if (!addr) {
844 spin_unlock_bh(&ipvlan->addrs_lock);
827 return; 845 return;
846 }
828 847
829 ipvlan_ht_addr_del(addr); 848 ipvlan_ht_addr_del(addr);
830 list_del(&addr->anode); 849 list_del_rcu(&addr->anode);
850 spin_unlock_bh(&ipvlan->addrs_lock);
831 kfree_rcu(addr, rcu); 851 kfree_rcu(addr, rcu);
832
833 return;
834}
835
836static int ipvlan_add_addr6(struct ipvl_dev *ipvlan, struct in6_addr *ip6_addr)
837{
838 if (ipvlan_addr_busy(ipvlan->port, ip6_addr, true)) {
839 netif_err(ipvlan, ifup, ipvlan->dev,
840 "Failed to add IPv6=%pI6c addr for %s intf\n",
841 ip6_addr, ipvlan->dev->name);
842 return -EINVAL;
843 }
844
845 return ipvlan_add_addr(ipvlan, ip6_addr, true);
846}
847
848static void ipvlan_del_addr6(struct ipvl_dev *ipvlan, struct in6_addr *ip6_addr)
849{
850 return ipvlan_del_addr(ipvlan, ip6_addr, true);
851} 852}
852 853
853static bool ipvlan_is_valid_dev(const struct net_device *dev) 854static bool ipvlan_is_valid_dev(const struct net_device *dev)
@@ -863,6 +864,27 @@ static bool ipvlan_is_valid_dev(const struct net_device *dev)
863 return true; 864 return true;
864} 865}
865 866
867#if IS_ENABLED(CONFIG_IPV6)
868static int ipvlan_add_addr6(struct ipvl_dev *ipvlan, struct in6_addr *ip6_addr)
869{
870 int ret = -EINVAL;
871
872 spin_lock_bh(&ipvlan->addrs_lock);
873 if (ipvlan_addr_busy(ipvlan->port, ip6_addr, true))
874 netif_err(ipvlan, ifup, ipvlan->dev,
875 "Failed to add IPv6=%pI6c addr for %s intf\n",
876 ip6_addr, ipvlan->dev->name);
877 else
878 ret = ipvlan_add_addr(ipvlan, ip6_addr, true);
879 spin_unlock_bh(&ipvlan->addrs_lock);
880 return ret;
881}
882
883static void ipvlan_del_addr6(struct ipvl_dev *ipvlan, struct in6_addr *ip6_addr)
884{
885 return ipvlan_del_addr(ipvlan, ip6_addr, true);
886}
887
866static int ipvlan_addr6_event(struct notifier_block *unused, 888static int ipvlan_addr6_event(struct notifier_block *unused,
867 unsigned long event, void *ptr) 889 unsigned long event, void *ptr)
868{ 890{
@@ -894,10 +916,6 @@ static int ipvlan_addr6_validator_event(struct notifier_block *unused,
894 struct net_device *dev = (struct net_device *)i6vi->i6vi_dev->dev; 916 struct net_device *dev = (struct net_device *)i6vi->i6vi_dev->dev;
895 struct ipvl_dev *ipvlan = netdev_priv(dev); 917 struct ipvl_dev *ipvlan = netdev_priv(dev);
896 918
897 /* FIXME IPv6 autoconf calls us from bh without RTNL */
898 if (in_softirq())
899 return NOTIFY_DONE;
900
901 if (!ipvlan_is_valid_dev(dev)) 919 if (!ipvlan_is_valid_dev(dev))
902 return NOTIFY_DONE; 920 return NOTIFY_DONE;
903 921
@@ -913,17 +931,21 @@ static int ipvlan_addr6_validator_event(struct notifier_block *unused,
913 931
914 return NOTIFY_OK; 932 return NOTIFY_OK;
915} 933}
934#endif
916 935
917static int ipvlan_add_addr4(struct ipvl_dev *ipvlan, struct in_addr *ip4_addr) 936static int ipvlan_add_addr4(struct ipvl_dev *ipvlan, struct in_addr *ip4_addr)
918{ 937{
919 if (ipvlan_addr_busy(ipvlan->port, ip4_addr, false)) { 938 int ret = -EINVAL;
939
940 spin_lock_bh(&ipvlan->addrs_lock);
941 if (ipvlan_addr_busy(ipvlan->port, ip4_addr, false))
920 netif_err(ipvlan, ifup, ipvlan->dev, 942 netif_err(ipvlan, ifup, ipvlan->dev,
921 "Failed to add IPv4=%pI4 on %s intf.\n", 943 "Failed to add IPv4=%pI4 on %s intf.\n",
922 ip4_addr, ipvlan->dev->name); 944 ip4_addr, ipvlan->dev->name);
923 return -EINVAL; 945 else
924 } 946 ret = ipvlan_add_addr(ipvlan, ip4_addr, false);
925 947 spin_unlock_bh(&ipvlan->addrs_lock);
926 return ipvlan_add_addr(ipvlan, ip4_addr, false); 948 return ret;
927} 949}
928 950
929static void ipvlan_del_addr4(struct ipvl_dev *ipvlan, struct in_addr *ip4_addr) 951static void ipvlan_del_addr4(struct ipvl_dev *ipvlan, struct in_addr *ip4_addr)
@@ -993,6 +1015,7 @@ static struct notifier_block ipvlan_notifier_block __read_mostly = {
993 .notifier_call = ipvlan_device_event, 1015 .notifier_call = ipvlan_device_event,
994}; 1016};
995 1017
1018#if IS_ENABLED(CONFIG_IPV6)
996static struct notifier_block ipvlan_addr6_notifier_block __read_mostly = { 1019static struct notifier_block ipvlan_addr6_notifier_block __read_mostly = {
997 .notifier_call = ipvlan_addr6_event, 1020 .notifier_call = ipvlan_addr6_event,
998}; 1021};
@@ -1000,6 +1023,7 @@ static struct notifier_block ipvlan_addr6_notifier_block __read_mostly = {
1000static struct notifier_block ipvlan_addr6_vtor_notifier_block __read_mostly = { 1023static struct notifier_block ipvlan_addr6_vtor_notifier_block __read_mostly = {
1001 .notifier_call = ipvlan_addr6_validator_event, 1024 .notifier_call = ipvlan_addr6_validator_event,
1002}; 1025};
1026#endif
1003 1027
1004static void ipvlan_ns_exit(struct net *net) 1028static void ipvlan_ns_exit(struct net *net)
1005{ 1029{
@@ -1016,6 +1040,7 @@ static struct pernet_operations ipvlan_net_ops = {
1016 .id = &ipvlan_netid, 1040 .id = &ipvlan_netid,
1017 .size = sizeof(struct ipvlan_netns), 1041 .size = sizeof(struct ipvlan_netns),
1018 .exit = ipvlan_ns_exit, 1042 .exit = ipvlan_ns_exit,
1043 .async = true,
1019}; 1044};
1020 1045
1021static int __init ipvlan_init_module(void) 1046static int __init ipvlan_init_module(void)
@@ -1024,9 +1049,11 @@ static int __init ipvlan_init_module(void)
1024 1049
1025 ipvlan_init_secret(); 1050 ipvlan_init_secret();
1026 register_netdevice_notifier(&ipvlan_notifier_block); 1051 register_netdevice_notifier(&ipvlan_notifier_block);
1052#if IS_ENABLED(CONFIG_IPV6)
1027 register_inet6addr_notifier(&ipvlan_addr6_notifier_block); 1053 register_inet6addr_notifier(&ipvlan_addr6_notifier_block);
1028 register_inet6addr_validator_notifier( 1054 register_inet6addr_validator_notifier(
1029 &ipvlan_addr6_vtor_notifier_block); 1055 &ipvlan_addr6_vtor_notifier_block);
1056#endif
1030 register_inetaddr_notifier(&ipvlan_addr4_notifier_block); 1057 register_inetaddr_notifier(&ipvlan_addr4_notifier_block);
1031 register_inetaddr_validator_notifier(&ipvlan_addr4_vtor_notifier_block); 1058 register_inetaddr_validator_notifier(&ipvlan_addr4_vtor_notifier_block);
1032 1059
@@ -1045,9 +1072,11 @@ error:
1045 unregister_inetaddr_notifier(&ipvlan_addr4_notifier_block); 1072 unregister_inetaddr_notifier(&ipvlan_addr4_notifier_block);
1046 unregister_inetaddr_validator_notifier( 1073 unregister_inetaddr_validator_notifier(
1047 &ipvlan_addr4_vtor_notifier_block); 1074 &ipvlan_addr4_vtor_notifier_block);
1075#if IS_ENABLED(CONFIG_IPV6)
1048 unregister_inet6addr_notifier(&ipvlan_addr6_notifier_block); 1076 unregister_inet6addr_notifier(&ipvlan_addr6_notifier_block);
1049 unregister_inet6addr_validator_notifier( 1077 unregister_inet6addr_validator_notifier(
1050 &ipvlan_addr6_vtor_notifier_block); 1078 &ipvlan_addr6_vtor_notifier_block);
1079#endif
1051 unregister_netdevice_notifier(&ipvlan_notifier_block); 1080 unregister_netdevice_notifier(&ipvlan_notifier_block);
1052 return err; 1081 return err;
1053} 1082}
@@ -1060,9 +1089,11 @@ static void __exit ipvlan_cleanup_module(void)
1060 unregister_inetaddr_notifier(&ipvlan_addr4_notifier_block); 1089 unregister_inetaddr_notifier(&ipvlan_addr4_notifier_block);
1061 unregister_inetaddr_validator_notifier( 1090 unregister_inetaddr_validator_notifier(
1062 &ipvlan_addr4_vtor_notifier_block); 1091 &ipvlan_addr4_vtor_notifier_block);
1092#if IS_ENABLED(CONFIG_IPV6)
1063 unregister_inet6addr_notifier(&ipvlan_addr6_notifier_block); 1093 unregister_inet6addr_notifier(&ipvlan_addr6_notifier_block);
1064 unregister_inet6addr_validator_notifier( 1094 unregister_inet6addr_validator_notifier(
1065 &ipvlan_addr6_vtor_notifier_block); 1095 &ipvlan_addr6_vtor_notifier_block);
1096#endif
1066} 1097}
1067 1098
1068module_init(ipvlan_init_module); 1099module_init(ipvlan_init_module);
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
index 30612497643c..b97a907ea5aa 100644
--- a/drivers/net/loopback.c
+++ b/drivers/net/loopback.c
@@ -230,4 +230,5 @@ out:
230/* Registered in net/core/dev.c */ 230/* Registered in net/core/dev.c */
231struct pernet_operations __net_initdata loopback_net_ops = { 231struct pernet_operations __net_initdata loopback_net_ops = {
232 .init = loopback_net_init, 232 .init = loopback_net_init,
233 .async = true,
233}; 234};
diff --git a/drivers/net/phy/aquantia.c b/drivers/net/phy/aquantia.c
index e8ae50e1255e..319edc9c8ec7 100644
--- a/drivers/net/phy/aquantia.c
+++ b/drivers/net/phy/aquantia.c
@@ -38,14 +38,6 @@ static int aquantia_config_aneg(struct phy_device *phydev)
38 return 0; 38 return 0;
39} 39}
40 40
41static int aquantia_aneg_done(struct phy_device *phydev)
42{
43 int reg;
44
45 reg = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1);
46 return (reg < 0) ? reg : (reg & BMSR_ANEGCOMPLETE);
47}
48
49static int aquantia_config_intr(struct phy_device *phydev) 41static int aquantia_config_intr(struct phy_device *phydev)
50{ 42{
51 int err; 43 int err;
@@ -125,7 +117,7 @@ static struct phy_driver aquantia_driver[] = {
125 .name = "Aquantia AQ1202", 117 .name = "Aquantia AQ1202",
126 .features = PHY_AQUANTIA_FEATURES, 118 .features = PHY_AQUANTIA_FEATURES,
127 .flags = PHY_HAS_INTERRUPT, 119 .flags = PHY_HAS_INTERRUPT,
128 .aneg_done = aquantia_aneg_done, 120 .aneg_done = genphy_c45_aneg_done,
129 .config_aneg = aquantia_config_aneg, 121 .config_aneg = aquantia_config_aneg,
130 .config_intr = aquantia_config_intr, 122 .config_intr = aquantia_config_intr,
131 .ack_interrupt = aquantia_ack_interrupt, 123 .ack_interrupt = aquantia_ack_interrupt,
@@ -137,7 +129,7 @@ static struct phy_driver aquantia_driver[] = {
137 .name = "Aquantia AQ2104", 129 .name = "Aquantia AQ2104",
138 .features = PHY_AQUANTIA_FEATURES, 130 .features = PHY_AQUANTIA_FEATURES,
139 .flags = PHY_HAS_INTERRUPT, 131 .flags = PHY_HAS_INTERRUPT,
140 .aneg_done = aquantia_aneg_done, 132 .aneg_done = genphy_c45_aneg_done,
141 .config_aneg = aquantia_config_aneg, 133 .config_aneg = aquantia_config_aneg,
142 .config_intr = aquantia_config_intr, 134 .config_intr = aquantia_config_intr,
143 .ack_interrupt = aquantia_ack_interrupt, 135 .ack_interrupt = aquantia_ack_interrupt,
@@ -149,7 +141,7 @@ static struct phy_driver aquantia_driver[] = {
149 .name = "Aquantia AQR105", 141 .name = "Aquantia AQR105",
150 .features = PHY_AQUANTIA_FEATURES, 142 .features = PHY_AQUANTIA_FEATURES,
151 .flags = PHY_HAS_INTERRUPT, 143 .flags = PHY_HAS_INTERRUPT,
152 .aneg_done = aquantia_aneg_done, 144 .aneg_done = genphy_c45_aneg_done,
153 .config_aneg = aquantia_config_aneg, 145 .config_aneg = aquantia_config_aneg,
154 .config_intr = aquantia_config_intr, 146 .config_intr = aquantia_config_intr,
155 .ack_interrupt = aquantia_ack_interrupt, 147 .ack_interrupt = aquantia_ack_interrupt,
@@ -161,7 +153,7 @@ static struct phy_driver aquantia_driver[] = {
161 .name = "Aquantia AQR106", 153 .name = "Aquantia AQR106",
162 .features = PHY_AQUANTIA_FEATURES, 154 .features = PHY_AQUANTIA_FEATURES,
163 .flags = PHY_HAS_INTERRUPT, 155 .flags = PHY_HAS_INTERRUPT,
164 .aneg_done = aquantia_aneg_done, 156 .aneg_done = genphy_c45_aneg_done,
165 .config_aneg = aquantia_config_aneg, 157 .config_aneg = aquantia_config_aneg,
166 .config_intr = aquantia_config_intr, 158 .config_intr = aquantia_config_intr,
167 .ack_interrupt = aquantia_ack_interrupt, 159 .ack_interrupt = aquantia_ack_interrupt,
@@ -173,7 +165,7 @@ static struct phy_driver aquantia_driver[] = {
173 .name = "Aquantia AQR107", 165 .name = "Aquantia AQR107",
174 .features = PHY_AQUANTIA_FEATURES, 166 .features = PHY_AQUANTIA_FEATURES,
175 .flags = PHY_HAS_INTERRUPT, 167 .flags = PHY_HAS_INTERRUPT,
176 .aneg_done = aquantia_aneg_done, 168 .aneg_done = genphy_c45_aneg_done,
177 .config_aneg = aquantia_config_aneg, 169 .config_aneg = aquantia_config_aneg,
178 .config_intr = aquantia_config_intr, 170 .config_intr = aquantia_config_intr,
179 .ack_interrupt = aquantia_ack_interrupt, 171 .ack_interrupt = aquantia_ack_interrupt,
@@ -185,7 +177,7 @@ static struct phy_driver aquantia_driver[] = {
185 .name = "Aquantia AQR405", 177 .name = "Aquantia AQR405",
186 .features = PHY_AQUANTIA_FEATURES, 178 .features = PHY_AQUANTIA_FEATURES,
187 .flags = PHY_HAS_INTERRUPT, 179 .flags = PHY_HAS_INTERRUPT,
188 .aneg_done = aquantia_aneg_done, 180 .aneg_done = genphy_c45_aneg_done,
189 .config_aneg = aquantia_config_aneg, 181 .config_aneg = aquantia_config_aneg,
190 .config_intr = aquantia_config_intr, 182 .config_intr = aquantia_config_intr,
191 .ack_interrupt = aquantia_ack_interrupt, 183 .ack_interrupt = aquantia_ack_interrupt,
diff --git a/drivers/net/phy/bcm7xxx.c b/drivers/net/phy/bcm7xxx.c
index 421feb8f92fe..29b1c88b55cc 100644
--- a/drivers/net/phy/bcm7xxx.c
+++ b/drivers/net/phy/bcm7xxx.c
@@ -565,7 +565,7 @@ static int bcm7xxx_28nm_set_tunable(struct phy_device *phydev,
565 if (ret) 565 if (ret)
566 return ret; 566 return ret;
567 567
568 /* Disable EEE advertisment since this prevents the PHY 568 /* Disable EEE advertisement since this prevents the PHY
569 * from successfully linking up, trigger auto-negotiation restart 569 * from successfully linking up, trigger auto-negotiation restart
570 * to let the MAC decide what to do. 570 * to let the MAC decide what to do.
571 */ 571 */
diff --git a/drivers/net/phy/cortina.c b/drivers/net/phy/cortina.c
index 9442db221834..8022cd317f62 100644
--- a/drivers/net/phy/cortina.c
+++ b/drivers/net/phy/cortina.c
@@ -30,14 +30,6 @@ static int cortina_read_reg(struct phy_device *phydev, u16 regnum)
30 MII_ADDR_C45 | regnum); 30 MII_ADDR_C45 | regnum);
31} 31}
32 32
33static int cortina_config_aneg(struct phy_device *phydev)
34{
35 phydev->supported = SUPPORTED_10000baseT_Full;
36 phydev->advertising = SUPPORTED_10000baseT_Full;
37
38 return 0;
39}
40
41static int cortina_read_status(struct phy_device *phydev) 33static int cortina_read_status(struct phy_device *phydev)
42{ 34{
43 int gpio_int_status, ret = 0; 35 int gpio_int_status, ret = 0;
@@ -61,11 +53,6 @@ err:
61 return ret; 53 return ret;
62} 54}
63 55
64static int cortina_soft_reset(struct phy_device *phydev)
65{
66 return 0;
67}
68
69static int cortina_probe(struct phy_device *phydev) 56static int cortina_probe(struct phy_device *phydev)
70{ 57{
71 u32 phy_id = 0; 58 u32 phy_id = 0;
@@ -101,9 +88,10 @@ static struct phy_driver cortina_driver[] = {
101 .phy_id = PHY_ID_CS4340, 88 .phy_id = PHY_ID_CS4340,
102 .phy_id_mask = 0xffffffff, 89 .phy_id_mask = 0xffffffff,
103 .name = "Cortina CS4340", 90 .name = "Cortina CS4340",
104 .config_aneg = cortina_config_aneg, 91 .config_init = gen10g_config_init,
92 .config_aneg = gen10g_config_aneg,
105 .read_status = cortina_read_status, 93 .read_status = cortina_read_status,
106 .soft_reset = cortina_soft_reset, 94 .soft_reset = gen10g_no_soft_reset,
107 .probe = cortina_probe, 95 .probe = cortina_probe,
108}, 96},
109}; 97};
diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c
index ab58224f897f..b3935778b19f 100644
--- a/drivers/net/phy/dp83867.c
+++ b/drivers/net/phy/dp83867.c
@@ -75,6 +75,8 @@
75 75
76#define DP83867_IO_MUX_CFG_IO_IMPEDANCE_MAX 0x0 76#define DP83867_IO_MUX_CFG_IO_IMPEDANCE_MAX 0x0
77#define DP83867_IO_MUX_CFG_IO_IMPEDANCE_MIN 0x1f 77#define DP83867_IO_MUX_CFG_IO_IMPEDANCE_MIN 0x1f
78#define DP83867_IO_MUX_CFG_CLK_O_SEL_MASK (0x1f << 8)
79#define DP83867_IO_MUX_CFG_CLK_O_SEL_SHIFT 8
78 80
79/* CFG4 bits */ 81/* CFG4 bits */
80#define DP83867_CFG4_PORT_MIRROR_EN BIT(0) 82#define DP83867_CFG4_PORT_MIRROR_EN BIT(0)
@@ -92,6 +94,7 @@ struct dp83867_private {
92 int io_impedance; 94 int io_impedance;
93 int port_mirroring; 95 int port_mirroring;
94 bool rxctrl_strap_quirk; 96 bool rxctrl_strap_quirk;
97 int clk_output_sel;
95}; 98};
96 99
97static int dp83867_ack_interrupt(struct phy_device *phydev) 100static int dp83867_ack_interrupt(struct phy_device *phydev)
@@ -160,6 +163,14 @@ static int dp83867_of_init(struct phy_device *phydev)
160 dp83867->io_impedance = -EINVAL; 163 dp83867->io_impedance = -EINVAL;
161 164
162 /* Optional configuration */ 165 /* Optional configuration */
166 ret = of_property_read_u32(of_node, "ti,clk-output-sel",
167 &dp83867->clk_output_sel);
168 if (ret || dp83867->clk_output_sel > DP83867_CLK_O_SEL_REF_CLK)
169 /* Keep the default value if ti,clk-output-sel is not set
170 * or too high
171 */
172 dp83867->clk_output_sel = DP83867_CLK_O_SEL_REF_CLK;
173
163 if (of_property_read_bool(of_node, "ti,max-output-impedance")) 174 if (of_property_read_bool(of_node, "ti,max-output-impedance"))
164 dp83867->io_impedance = DP83867_IO_MUX_CFG_IO_IMPEDANCE_MAX; 175 dp83867->io_impedance = DP83867_IO_MUX_CFG_IO_IMPEDANCE_MAX;
165 else if (of_property_read_bool(of_node, "ti,min-output-impedance")) 176 else if (of_property_read_bool(of_node, "ti,min-output-impedance"))
@@ -295,6 +306,14 @@ static int dp83867_config_init(struct phy_device *phydev)
295 if (dp83867->port_mirroring != DP83867_PORT_MIRROING_KEEP) 306 if (dp83867->port_mirroring != DP83867_PORT_MIRROING_KEEP)
296 dp83867_config_port_mirroring(phydev); 307 dp83867_config_port_mirroring(phydev);
297 308
309 /* Clock output selection if muxing property is set */
310 if (dp83867->clk_output_sel != DP83867_CLK_O_SEL_REF_CLK) {
311 val = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_IO_MUX_CFG);
312 val &= ~DP83867_IO_MUX_CFG_CLK_O_SEL_MASK;
313 val |= (dp83867->clk_output_sel << DP83867_IO_MUX_CFG_CLK_O_SEL_SHIFT);
314 phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_IO_MUX_CFG, val);
315 }
316
298 return 0; 317 return 0;
299} 318}
300 319
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index 0e0978d8a0eb..a75c511950c3 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -860,7 +860,7 @@ static int m88e1510_config_init(struct phy_device *phydev)
860 return err; 860 return err;
861 861
862 /* There appears to be a bug in the 88e1512 when used in 862 /* There appears to be a bug in the 88e1512 when used in
863 * SGMII to copper mode, where the AN advertisment register 863 * SGMII to copper mode, where the AN advertisement register
864 * clears the pause bits each time a negotiation occurs. 864 * clears the pause bits each time a negotiation occurs.
865 * This means we can never be truely sure what was advertised, 865 * This means we can never be truely sure what was advertised,
866 * so disable Pause support. 866 * so disable Pause support.
diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c
index 8a0bd98fdec7..9564916d2d7b 100644
--- a/drivers/net/phy/marvell10g.c
+++ b/drivers/net/phy/marvell10g.c
@@ -71,15 +71,6 @@ static int mv3310_probe(struct phy_device *phydev)
71 return 0; 71 return 0;
72} 72}
73 73
74/*
75 * Resetting the MV88X3310 causes it to become non-responsive. Avoid
76 * setting the reset bit(s).
77 */
78static int mv3310_soft_reset(struct phy_device *phydev)
79{
80 return 0;
81}
82
83static int mv3310_config_init(struct phy_device *phydev) 74static int mv3310_config_init(struct phy_device *phydev)
84{ 75{
85 __ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, }; 76 __ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, };
@@ -317,7 +308,7 @@ static int mv3310_read_status(struct phy_device *phydev)
317 if (val < 0) 308 if (val < 0)
318 return val; 309 return val;
319 310
320 /* Read the link partner's 1G advertisment */ 311 /* Read the link partner's 1G advertisement */
321 val = phy_read_mmd(phydev, MDIO_MMD_AN, MV_AN_STAT1000); 312 val = phy_read_mmd(phydev, MDIO_MMD_AN, MV_AN_STAT1000);
322 if (val < 0) 313 if (val < 0)
323 return val; 314 return val;
@@ -377,7 +368,7 @@ static struct phy_driver mv3310_drivers[] = {
377 SUPPORTED_10000baseT_Full | 368 SUPPORTED_10000baseT_Full |
378 SUPPORTED_Backplane, 369 SUPPORTED_Backplane,
379 .probe = mv3310_probe, 370 .probe = mv3310_probe,
380 .soft_reset = mv3310_soft_reset, 371 .soft_reset = gen10g_no_soft_reset,
381 .config_init = mv3310_config_init, 372 .config_init = mv3310_config_init,
382 .config_aneg = mv3310_config_aneg, 373 .config_aneg = mv3310_config_aneg,
383 .aneg_done = mv3310_aneg_done, 374 .aneg_done = mv3310_aneg_done,
diff --git a/drivers/net/phy/mdio-mux-mmioreg.c b/drivers/net/phy/mdio-mux-mmioreg.c
index 2573ab012f16..70f6115530af 100644
--- a/drivers/net/phy/mdio-mux-mmioreg.c
+++ b/drivers/net/phy/mdio-mux-mmioreg.c
@@ -163,8 +163,9 @@ static int mdio_mux_mmioreg_probe(struct platform_device *pdev)
163 mdio_mux_mmioreg_switch_fn, 163 mdio_mux_mmioreg_switch_fn,
164 &s->mux_handle, s, NULL); 164 &s->mux_handle, s, NULL);
165 if (ret) { 165 if (ret) {
166 dev_err(&pdev->dev, "failed to register mdio-mux bus %pOF\n", 166 if (ret != -EPROBE_DEFER)
167 np); 167 dev_err(&pdev->dev,
168 "failed to register mdio-mux bus %pOF\n", np);
168 return ret; 169 return ret;
169 } 170 }
170 171
diff --git a/drivers/net/phy/phy-c45.c b/drivers/net/phy/phy-c45.c
index a4576859afae..e1225545362d 100644
--- a/drivers/net/phy/phy-c45.c
+++ b/drivers/net/phy/phy-c45.c
@@ -163,11 +163,11 @@ int genphy_c45_read_link(struct phy_device *phydev, u32 mmd_mask)
163EXPORT_SYMBOL_GPL(genphy_c45_read_link); 163EXPORT_SYMBOL_GPL(genphy_c45_read_link);
164 164
165/** 165/**
166 * genphy_c45_read_lpa - read the link partner advertisment and pause 166 * genphy_c45_read_lpa - read the link partner advertisement and pause
167 * @phydev: target phy_device struct 167 * @phydev: target phy_device struct
168 * 168 *
169 * Read the Clause 45 defined base (7.19) and 10G (7.33) status registers, 169 * Read the Clause 45 defined base (7.19) and 10G (7.33) status registers,
170 * filling in the link partner advertisment, pause and asym_pause members 170 * filling in the link partner advertisement, pause and asym_pause members
171 * in @phydev. This assumes that the auto-negotiation MMD is present, and 171 * in @phydev. This assumes that the auto-negotiation MMD is present, and
172 * the backplane bit (7.48.0) is clear. Clause 45 PHY drivers are expected 172 * the backplane bit (7.48.0) is clear. Clause 45 PHY drivers are expected
173 * to fill in the remainder of the link partner advert from vendor registers. 173 * to fill in the remainder of the link partner advert from vendor registers.
@@ -176,7 +176,7 @@ int genphy_c45_read_lpa(struct phy_device *phydev)
176{ 176{
177 int val; 177 int val;
178 178
179 /* Read the link partner's base page advertisment */ 179 /* Read the link partner's base page advertisement */
180 val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_LPA); 180 val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_LPA);
181 if (val < 0) 181 if (val < 0)
182 return val; 182 return val;
@@ -185,7 +185,7 @@ int genphy_c45_read_lpa(struct phy_device *phydev)
185 phydev->pause = val & LPA_PAUSE_CAP ? 1 : 0; 185 phydev->pause = val & LPA_PAUSE_CAP ? 1 : 0;
186 phydev->asym_pause = val & LPA_PAUSE_ASYM ? 1 : 0; 186 phydev->asym_pause = val & LPA_PAUSE_ASYM ? 1 : 0;
187 187
188 /* Read the link partner's 10G advertisment */ 188 /* Read the link partner's 10G advertisement */
189 val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_STAT); 189 val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_STAT);
190 if (val < 0) 190 if (val < 0)
191 return val; 191 return val;
@@ -268,12 +268,13 @@ EXPORT_SYMBOL_GPL(genphy_c45_read_mdix);
268 268
269/* The gen10g_* functions are the old Clause 45 stub */ 269/* The gen10g_* functions are the old Clause 45 stub */
270 270
271static int gen10g_config_aneg(struct phy_device *phydev) 271int gen10g_config_aneg(struct phy_device *phydev)
272{ 272{
273 return 0; 273 return 0;
274} 274}
275EXPORT_SYMBOL_GPL(gen10g_config_aneg);
275 276
276static int gen10g_read_status(struct phy_device *phydev) 277int gen10g_read_status(struct phy_device *phydev)
277{ 278{
278 u32 mmd_mask = phydev->c45_ids.devices_in_package; 279 u32 mmd_mask = phydev->c45_ids.devices_in_package;
279 int ret; 280 int ret;
@@ -291,14 +292,16 @@ static int gen10g_read_status(struct phy_device *phydev)
291 292
292 return 0; 293 return 0;
293} 294}
295EXPORT_SYMBOL_GPL(gen10g_read_status);
294 296
295static int gen10g_soft_reset(struct phy_device *phydev) 297int gen10g_no_soft_reset(struct phy_device *phydev)
296{ 298{
297 /* Do nothing for now */ 299 /* Do nothing for now */
298 return 0; 300 return 0;
299} 301}
302EXPORT_SYMBOL_GPL(gen10g_no_soft_reset);
300 303
301static int gen10g_config_init(struct phy_device *phydev) 304int gen10g_config_init(struct phy_device *phydev)
302{ 305{
303 /* Temporarily just say we support everything */ 306 /* Temporarily just say we support everything */
304 phydev->supported = SUPPORTED_10000baseT_Full; 307 phydev->supported = SUPPORTED_10000baseT_Full;
@@ -306,22 +309,25 @@ static int gen10g_config_init(struct phy_device *phydev)
306 309
307 return 0; 310 return 0;
308} 311}
312EXPORT_SYMBOL_GPL(gen10g_config_init);
309 313
310static int gen10g_suspend(struct phy_device *phydev) 314int gen10g_suspend(struct phy_device *phydev)
311{ 315{
312 return 0; 316 return 0;
313} 317}
318EXPORT_SYMBOL_GPL(gen10g_suspend);
314 319
315static int gen10g_resume(struct phy_device *phydev) 320int gen10g_resume(struct phy_device *phydev)
316{ 321{
317 return 0; 322 return 0;
318} 323}
324EXPORT_SYMBOL_GPL(gen10g_resume);
319 325
320struct phy_driver genphy_10g_driver = { 326struct phy_driver genphy_10g_driver = {
321 .phy_id = 0xffffffff, 327 .phy_id = 0xffffffff,
322 .phy_id_mask = 0xffffffff, 328 .phy_id_mask = 0xffffffff,
323 .name = "Generic 10G PHY", 329 .name = "Generic 10G PHY",
324 .soft_reset = gen10g_soft_reset, 330 .soft_reset = gen10g_no_soft_reset,
325 .config_init = gen10g_config_init, 331 .config_init = gen10g_config_init,
326 .features = 0, 332 .features = 0,
327 .config_aneg = gen10g_config_aneg, 333 .config_aneg = gen10g_config_aneg,
diff --git a/drivers/net/phy/phy-core.c b/drivers/net/phy/phy-core.c
index 4083f00c97a5..c7da4cbb1103 100644
--- a/drivers/net/phy/phy-core.c
+++ b/drivers/net/phy/phy-core.c
@@ -190,10 +190,10 @@ size_t phy_speeds(unsigned int *speeds, size_t size,
190} 190}
191 191
192/** 192/**
193 * phy_resolve_aneg_linkmode - resolve the advertisments into phy settings 193 * phy_resolve_aneg_linkmode - resolve the advertisements into phy settings
194 * @phydev: The phy_device struct 194 * @phydev: The phy_device struct
195 * 195 *
196 * Resolve our and the link partner advertisments into their corresponding 196 * Resolve our and the link partner advertisements into their corresponding
197 * speed and duplex. If full duplex was negotiated, extract the pause mode 197 * speed and duplex. If full duplex was negotiated, extract the pause mode
198 * from the link partner mask. 198 * from the link partner mask.
199 */ 199 */
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 9aabfa1a455a..05c1e8ef15e6 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -628,19 +628,10 @@ static int phy_disable_interrupts(struct phy_device *phydev)
628 /* Disable PHY interrupts */ 628 /* Disable PHY interrupts */
629 err = phy_config_interrupt(phydev, PHY_INTERRUPT_DISABLED); 629 err = phy_config_interrupt(phydev, PHY_INTERRUPT_DISABLED);
630 if (err) 630 if (err)
631 goto phy_err; 631 return err;
632 632
633 /* Clear the interrupt */ 633 /* Clear the interrupt */
634 err = phy_clear_interrupt(phydev); 634 return phy_clear_interrupt(phydev);
635 if (err)
636 goto phy_err;
637
638 return 0;
639
640phy_err:
641 phy_error(phydev);
642
643 return err;
644} 635}
645 636
646/** 637/**
@@ -773,13 +764,8 @@ void phy_stop(struct phy_device *phydev)
773 if (PHY_HALTED == phydev->state) 764 if (PHY_HALTED == phydev->state)
774 goto out_unlock; 765 goto out_unlock;
775 766
776 if (phy_interrupt_is_valid(phydev)) { 767 if (phy_interrupt_is_valid(phydev))
777 /* Disable PHY Interrupts */ 768 phy_disable_interrupts(phydev);
778 phy_config_interrupt(phydev, PHY_INTERRUPT_DISABLED);
779
780 /* Clear any pending interrupts */
781 phy_clear_interrupt(phydev);
782 }
783 769
784 phydev->state = PHY_HALTED; 770 phydev->state = PHY_HALTED;
785 771
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 74664a6c0cdc..ac23322a32e1 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -374,7 +374,7 @@ struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id,
374 dev->duplex = -1; 374 dev->duplex = -1;
375 dev->pause = 0; 375 dev->pause = 0;
376 dev->asym_pause = 0; 376 dev->asym_pause = 0;
377 dev->link = 1; 377 dev->link = 0;
378 dev->interface = PHY_INTERFACE_MODE_GMII; 378 dev->interface = PHY_INTERFACE_MODE_GMII;
379 379
380 dev->autoneg = AUTONEG_ENABLE; 380 dev->autoneg = AUTONEG_ENABLE;
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 6ac8b29b2dc3..51a011a349fe 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -364,7 +364,7 @@ static void phylink_get_fixed_state(struct phylink *pl, struct phylink_link_stat
364} 364}
365 365
366/* Flow control is resolved according to our and the link partners 366/* Flow control is resolved according to our and the link partners
367 * advertisments using the following drawn from the 802.3 specs: 367 * advertisements using the following drawn from the 802.3 specs:
368 * Local device Link partner 368 * Local device Link partner
369 * Pause AsymDir Pause AsymDir Result 369 * Pause AsymDir Pause AsymDir Result
370 * 1 X 1 X TX+RX 370 * 1 X 1 X TX+RX
@@ -679,12 +679,11 @@ static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy)
679 679
680 mutex_lock(&phy->lock); 680 mutex_lock(&phy->lock);
681 mutex_lock(&pl->state_mutex); 681 mutex_lock(&pl->state_mutex);
682 pl->netdev->phydev = phy;
683 pl->phydev = phy; 682 pl->phydev = phy;
684 linkmode_copy(pl->supported, supported); 683 linkmode_copy(pl->supported, supported);
685 linkmode_copy(pl->link_config.advertising, config.advertising); 684 linkmode_copy(pl->link_config.advertising, config.advertising);
686 685
687 /* Restrict the phy advertisment according to the MAC support. */ 686 /* Restrict the phy advertisement according to the MAC support. */
688 ethtool_convert_link_mode_to_legacy_u32(&advertising, config.advertising); 687 ethtool_convert_link_mode_to_legacy_u32(&advertising, config.advertising);
689 phy->advertising = advertising; 688 phy->advertising = advertising;
690 mutex_unlock(&pl->state_mutex); 689 mutex_unlock(&pl->state_mutex);
@@ -817,7 +816,6 @@ void phylink_disconnect_phy(struct phylink *pl)
817 if (phy) { 816 if (phy) {
818 mutex_lock(&phy->lock); 817 mutex_lock(&phy->lock);
819 mutex_lock(&pl->state_mutex); 818 mutex_lock(&pl->state_mutex);
820 pl->netdev->phydev = NULL;
821 pl->phydev = NULL; 819 pl->phydev = NULL;
822 mutex_unlock(&pl->state_mutex); 820 mutex_unlock(&pl->state_mutex);
823 mutex_unlock(&phy->lock); 821 mutex_unlock(&phy->lock);
@@ -889,7 +887,7 @@ void phylink_start(struct phylink *pl)
889 887
890 /* Apply the link configuration to the MAC when starting. This allows 888 /* Apply the link configuration to the MAC when starting. This allows
891 * a fixed-link to start with the correct parameters, and also 889 * a fixed-link to start with the correct parameters, and also
892 * ensures that we set the appropriate advertisment for Serdes links. 890 * ensures that we set the appropriate advertisement for Serdes links.
893 */ 891 */
894 phylink_resolve_flow(pl, &pl->link_config); 892 phylink_resolve_flow(pl, &pl->link_config);
895 phylink_mac_config(pl, &pl->link_config); 893 phylink_mac_config(pl, &pl->link_config);
@@ -1076,7 +1074,7 @@ int phylink_ethtool_ksettings_set(struct phylink *pl,
1076 1074
1077 config = pl->link_config; 1075 config = pl->link_config;
1078 1076
1079 /* Mask out unsupported advertisments */ 1077 /* Mask out unsupported advertisements */
1080 linkmode_and(config.advertising, kset->link_modes.advertising, 1078 linkmode_and(config.advertising, kset->link_modes.advertising,
1081 pl->supported); 1079 pl->supported);
1082 1080
@@ -1121,7 +1119,7 @@ int phylink_ethtool_ksettings_set(struct phylink *pl,
1121 if (phylink_validate(pl, pl->supported, &config)) 1119 if (phylink_validate(pl, pl->supported, &config))
1122 return -EINVAL; 1120 return -EINVAL;
1123 1121
1124 /* If autonegotiation is enabled, we must have an advertisment */ 1122 /* If autonegotiation is enabled, we must have an advertisement */
1125 if (config.an_enabled && phylink_is_empty_linkmode(config.advertising)) 1123 if (config.an_enabled && phylink_is_empty_linkmode(config.advertising))
1126 return -EINVAL; 1124 return -EINVAL;
1127 1125
@@ -1584,25 +1582,14 @@ static int phylink_sfp_module_insert(void *upstream,
1584 bool changed; 1582 bool changed;
1585 u8 port; 1583 u8 port;
1586 1584
1587 sfp_parse_support(pl->sfp_bus, id, support);
1588 port = sfp_parse_port(pl->sfp_bus, id, support);
1589 iface = sfp_parse_interface(pl->sfp_bus, id);
1590
1591 ASSERT_RTNL(); 1585 ASSERT_RTNL();
1592 1586
1593 switch (iface) { 1587 sfp_parse_support(pl->sfp_bus, id, support);
1594 case PHY_INTERFACE_MODE_SGMII: 1588 port = sfp_parse_port(pl->sfp_bus, id, support);
1595 case PHY_INTERFACE_MODE_1000BASEX:
1596 case PHY_INTERFACE_MODE_2500BASEX:
1597 case PHY_INTERFACE_MODE_10GKR:
1598 break;
1599 default:
1600 return -EINVAL;
1601 }
1602 1589
1603 memset(&config, 0, sizeof(config)); 1590 memset(&config, 0, sizeof(config));
1604 linkmode_copy(config.advertising, support); 1591 linkmode_copy(config.advertising, support);
1605 config.interface = iface; 1592 config.interface = PHY_INTERFACE_MODE_NA;
1606 config.speed = SPEED_UNKNOWN; 1593 config.speed = SPEED_UNKNOWN;
1607 config.duplex = DUPLEX_UNKNOWN; 1594 config.duplex = DUPLEX_UNKNOWN;
1608 config.pause = MLO_PAUSE_AN; 1595 config.pause = MLO_PAUSE_AN;
@@ -1611,6 +1598,22 @@ static int phylink_sfp_module_insert(void *upstream,
1611 /* Ignore errors if we're expecting a PHY to attach later */ 1598 /* Ignore errors if we're expecting a PHY to attach later */
1612 ret = phylink_validate(pl, support, &config); 1599 ret = phylink_validate(pl, support, &config);
1613 if (ret) { 1600 if (ret) {
1601 netdev_err(pl->netdev, "validation with support %*pb failed: %d\n",
1602 __ETHTOOL_LINK_MODE_MASK_NBITS, support, ret);
1603 return ret;
1604 }
1605
1606 iface = sfp_select_interface(pl->sfp_bus, id, config.advertising);
1607 if (iface == PHY_INTERFACE_MODE_NA) {
1608 netdev_err(pl->netdev,
1609 "selection of interface failed, advertisement %*pb\n",
1610 __ETHTOOL_LINK_MODE_MASK_NBITS, config.advertising);
1611 return -EINVAL;
1612 }
1613
1614 config.interface = iface;
1615 ret = phylink_validate(pl, support, &config);
1616 if (ret) {
1614 netdev_err(pl->netdev, "validation of %s/%s with support %*pb failed: %d\n", 1617 netdev_err(pl->netdev, "validation of %s/%s with support %*pb failed: %d\n",
1615 phylink_an_mode_str(MLO_AN_INBAND), 1618 phylink_an_mode_str(MLO_AN_INBAND),
1616 phy_modes(config.interface), 1619 phy_modes(config.interface),
diff --git a/drivers/net/phy/sfp-bus.c b/drivers/net/phy/sfp-bus.c
index 8961209ee949..3d4ff5d0d2a6 100644
--- a/drivers/net/phy/sfp-bus.c
+++ b/drivers/net/phy/sfp-bus.c
@@ -106,68 +106,6 @@ int sfp_parse_port(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
106EXPORT_SYMBOL_GPL(sfp_parse_port); 106EXPORT_SYMBOL_GPL(sfp_parse_port);
107 107
108/** 108/**
109 * sfp_parse_interface() - Parse the phy_interface_t
110 * @bus: a pointer to the &struct sfp_bus structure for the sfp module
111 * @id: a pointer to the module's &struct sfp_eeprom_id
112 *
113 * Derive the phy_interface_t mode for the information found in the
114 * module's identifying EEPROM. There is no standard or defined way
115 * to derive this information, so we use some heuristics.
116 *
117 * If the encoding is 64b66b, then the module must be >= 10G, so
118 * return %PHY_INTERFACE_MODE_10GKR.
119 *
120 * If it's 8b10b, then it's 1G or slower. If it's definitely a fibre
121 * module, return %PHY_INTERFACE_MODE_1000BASEX mode, otherwise return
122 * %PHY_INTERFACE_MODE_SGMII mode.
123 *
124 * If the encoding is not known, return %PHY_INTERFACE_MODE_NA.
125 */
126phy_interface_t sfp_parse_interface(struct sfp_bus *bus,
127 const struct sfp_eeprom_id *id)
128{
129 phy_interface_t iface;
130
131 /* Setting the serdes link mode is guesswork: there's no field in
132 * the EEPROM which indicates what mode should be used.
133 *
134 * If the module wants 64b66b, then it must be >= 10G.
135 *
136 * If it's a gigabit-only fiber module, it probably does not have
137 * a PHY, so switch to 802.3z negotiation mode. Otherwise, switch
138 * to SGMII mode (which is required to support non-gigabit speeds).
139 */
140 switch (id->base.encoding) {
141 case SFP_ENCODING_8472_64B66B:
142 iface = PHY_INTERFACE_MODE_10GKR;
143 break;
144
145 case SFP_ENCODING_8B10B:
146 if (!id->base.e1000_base_t &&
147 !id->base.e100_base_lx &&
148 !id->base.e100_base_fx)
149 iface = PHY_INTERFACE_MODE_1000BASEX;
150 else
151 iface = PHY_INTERFACE_MODE_SGMII;
152 break;
153
154 default:
155 if (id->base.e1000_base_cx) {
156 iface = PHY_INTERFACE_MODE_1000BASEX;
157 break;
158 }
159
160 iface = PHY_INTERFACE_MODE_NA;
161 dev_err(bus->sfp_dev,
162 "SFP module encoding does not support 8b10b nor 64b66b\n");
163 break;
164 }
165
166 return iface;
167}
168EXPORT_SYMBOL_GPL(sfp_parse_interface);
169
170/**
171 * sfp_parse_support() - Parse the eeprom id for supported link modes 109 * sfp_parse_support() - Parse the eeprom id for supported link modes
172 * @bus: a pointer to the &struct sfp_bus structure for the sfp module 110 * @bus: a pointer to the &struct sfp_bus structure for the sfp module
173 * @id: a pointer to the module's &struct sfp_eeprom_id 111 * @id: a pointer to the module's &struct sfp_eeprom_id
@@ -180,10 +118,7 @@ void sfp_parse_support(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
180 unsigned long *support) 118 unsigned long *support)
181{ 119{
182 unsigned int br_min, br_nom, br_max; 120 unsigned int br_min, br_nom, br_max;
183 121 __ETHTOOL_DECLARE_LINK_MODE_MASK(modes) = { 0, };
184 phylink_set(support, Autoneg);
185 phylink_set(support, Pause);
186 phylink_set(support, Asym_Pause);
187 122
188 /* Decode the bitrate information to MBd */ 123 /* Decode the bitrate information to MBd */
189 br_min = br_nom = br_max = 0; 124 br_min = br_nom = br_max = 0;
@@ -201,20 +136,20 @@ void sfp_parse_support(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
201 136
202 /* Set ethtool support from the compliance fields. */ 137 /* Set ethtool support from the compliance fields. */
203 if (id->base.e10g_base_sr) 138 if (id->base.e10g_base_sr)
204 phylink_set(support, 10000baseSR_Full); 139 phylink_set(modes, 10000baseSR_Full);
205 if (id->base.e10g_base_lr) 140 if (id->base.e10g_base_lr)
206 phylink_set(support, 10000baseLR_Full); 141 phylink_set(modes, 10000baseLR_Full);
207 if (id->base.e10g_base_lrm) 142 if (id->base.e10g_base_lrm)
208 phylink_set(support, 10000baseLRM_Full); 143 phylink_set(modes, 10000baseLRM_Full);
209 if (id->base.e10g_base_er) 144 if (id->base.e10g_base_er)
210 phylink_set(support, 10000baseER_Full); 145 phylink_set(modes, 10000baseER_Full);
211 if (id->base.e1000_base_sx || 146 if (id->base.e1000_base_sx ||
212 id->base.e1000_base_lx || 147 id->base.e1000_base_lx ||
213 id->base.e1000_base_cx) 148 id->base.e1000_base_cx)
214 phylink_set(support, 1000baseX_Full); 149 phylink_set(modes, 1000baseX_Full);
215 if (id->base.e1000_base_t) { 150 if (id->base.e1000_base_t) {
216 phylink_set(support, 1000baseT_Half); 151 phylink_set(modes, 1000baseT_Half);
217 phylink_set(support, 1000baseT_Full); 152 phylink_set(modes, 1000baseT_Full);
218 } 153 }
219 154
220 /* 1000Base-PX or 1000Base-BX10 */ 155 /* 1000Base-PX or 1000Base-BX10 */
@@ -228,20 +163,20 @@ void sfp_parse_support(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
228 if ((id->base.sfp_ct_passive || id->base.sfp_ct_active) && br_nom) { 163 if ((id->base.sfp_ct_passive || id->base.sfp_ct_active) && br_nom) {
229 /* This may look odd, but some manufacturers use 12000MBd */ 164 /* This may look odd, but some manufacturers use 12000MBd */
230 if (br_min <= 12000 && br_max >= 10300) 165 if (br_min <= 12000 && br_max >= 10300)
231 phylink_set(support, 10000baseCR_Full); 166 phylink_set(modes, 10000baseCR_Full);
232 if (br_min <= 3200 && br_max >= 3100) 167 if (br_min <= 3200 && br_max >= 3100)
233 phylink_set(support, 2500baseX_Full); 168 phylink_set(modes, 2500baseX_Full);
234 if (br_min <= 1300 && br_max >= 1200) 169 if (br_min <= 1300 && br_max >= 1200)
235 phylink_set(support, 1000baseX_Full); 170 phylink_set(modes, 1000baseX_Full);
236 } 171 }
237 if (id->base.sfp_ct_passive) { 172 if (id->base.sfp_ct_passive) {
238 if (id->base.passive.sff8431_app_e) 173 if (id->base.passive.sff8431_app_e)
239 phylink_set(support, 10000baseCR_Full); 174 phylink_set(modes, 10000baseCR_Full);
240 } 175 }
241 if (id->base.sfp_ct_active) { 176 if (id->base.sfp_ct_active) {
242 if (id->base.active.sff8431_app_e || 177 if (id->base.active.sff8431_app_e ||
243 id->base.active.sff8431_lim) { 178 id->base.active.sff8431_lim) {
244 phylink_set(support, 10000baseCR_Full); 179 phylink_set(modes, 10000baseCR_Full);
245 } 180 }
246 } 181 }
247 182
@@ -249,18 +184,18 @@ void sfp_parse_support(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
249 case 0x00: /* Unspecified */ 184 case 0x00: /* Unspecified */
250 break; 185 break;
251 case 0x02: /* 100Gbase-SR4 or 25Gbase-SR */ 186 case 0x02: /* 100Gbase-SR4 or 25Gbase-SR */
252 phylink_set(support, 100000baseSR4_Full); 187 phylink_set(modes, 100000baseSR4_Full);
253 phylink_set(support, 25000baseSR_Full); 188 phylink_set(modes, 25000baseSR_Full);
254 break; 189 break;
255 case 0x03: /* 100Gbase-LR4 or 25Gbase-LR */ 190 case 0x03: /* 100Gbase-LR4 or 25Gbase-LR */
256 case 0x04: /* 100Gbase-ER4 or 25Gbase-ER */ 191 case 0x04: /* 100Gbase-ER4 or 25Gbase-ER */
257 phylink_set(support, 100000baseLR4_ER4_Full); 192 phylink_set(modes, 100000baseLR4_ER4_Full);
258 break; 193 break;
259 case 0x0b: /* 100Gbase-CR4 or 25Gbase-CR CA-L */ 194 case 0x0b: /* 100Gbase-CR4 or 25Gbase-CR CA-L */
260 case 0x0c: /* 25Gbase-CR CA-S */ 195 case 0x0c: /* 25Gbase-CR CA-S */
261 case 0x0d: /* 25Gbase-CR CA-N */ 196 case 0x0d: /* 25Gbase-CR CA-N */
262 phylink_set(support, 100000baseCR4_Full); 197 phylink_set(modes, 100000baseCR4_Full);
263 phylink_set(support, 25000baseCR_Full); 198 phylink_set(modes, 25000baseCR_Full);
264 break; 199 break;
265 default: 200 default:
266 dev_warn(bus->sfp_dev, 201 dev_warn(bus->sfp_dev,
@@ -274,13 +209,70 @@ void sfp_parse_support(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
274 id->base.fc_speed_200 || 209 id->base.fc_speed_200 ||
275 id->base.fc_speed_400) { 210 id->base.fc_speed_400) {
276 if (id->base.br_nominal >= 31) 211 if (id->base.br_nominal >= 31)
277 phylink_set(support, 2500baseX_Full); 212 phylink_set(modes, 2500baseX_Full);
278 if (id->base.br_nominal >= 12) 213 if (id->base.br_nominal >= 12)
279 phylink_set(support, 1000baseX_Full); 214 phylink_set(modes, 1000baseX_Full);
280 } 215 }
216
217 /* If we haven't discovered any modes that this module supports, try
218 * the encoding and bitrate to determine supported modes. Some BiDi
219 * modules (eg, 1310nm/1550nm) are not 1000BASE-BX compliant due to
220 * the differing wavelengths, so do not set any transceiver bits.
221 */
222 if (bitmap_empty(modes, __ETHTOOL_LINK_MODE_MASK_NBITS)) {
223 /* If the encoding and bit rate allows 1000baseX */
224 if (id->base.encoding == SFP_ENCODING_8B10B && br_nom &&
225 br_min <= 1300 && br_max >= 1200)
226 phylink_set(modes, 1000baseX_Full);
227 }
228
229 bitmap_or(support, support, modes, __ETHTOOL_LINK_MODE_MASK_NBITS);
230
231 phylink_set(support, Autoneg);
232 phylink_set(support, Pause);
233 phylink_set(support, Asym_Pause);
281} 234}
282EXPORT_SYMBOL_GPL(sfp_parse_support); 235EXPORT_SYMBOL_GPL(sfp_parse_support);
283 236
237/**
238 * sfp_select_interface() - Select appropriate phy_interface_t mode
239 * @bus: a pointer to the &struct sfp_bus structure for the sfp module
240 * @id: a pointer to the module's &struct sfp_eeprom_id
241 * @link_modes: ethtool link modes mask
242 *
243 * Derive the phy_interface_t mode for the information found in the
244 * module's identifying EEPROM and the link modes mask. There is no
245 * standard or defined way to derive this information, so we decide
246 * based upon the link mode mask.
247 */
248phy_interface_t sfp_select_interface(struct sfp_bus *bus,
249 const struct sfp_eeprom_id *id,
250 unsigned long *link_modes)
251{
252 if (phylink_test(link_modes, 10000baseCR_Full) ||
253 phylink_test(link_modes, 10000baseSR_Full) ||
254 phylink_test(link_modes, 10000baseLR_Full) ||
255 phylink_test(link_modes, 10000baseLRM_Full) ||
256 phylink_test(link_modes, 10000baseER_Full))
257 return PHY_INTERFACE_MODE_10GKR;
258
259 if (phylink_test(link_modes, 2500baseX_Full))
260 return PHY_INTERFACE_MODE_2500BASEX;
261
262 if (id->base.e1000_base_t ||
263 id->base.e100_base_lx ||
264 id->base.e100_base_fx)
265 return PHY_INTERFACE_MODE_SGMII;
266
267 if (phylink_test(link_modes, 1000baseX_Full))
268 return PHY_INTERFACE_MODE_1000BASEX;
269
270 dev_warn(bus->sfp_dev, "Unable to ascertain link mode\n");
271
272 return PHY_INTERFACE_MODE_NA;
273}
274EXPORT_SYMBOL_GPL(sfp_select_interface);
275
284static LIST_HEAD(sfp_buses); 276static LIST_HEAD(sfp_buses);
285static DEFINE_MUTEX(sfp_mutex); 277static DEFINE_MUTEX(sfp_mutex);
286 278
diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c
index 6c7d9289078d..83bf4959b043 100644
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -42,6 +42,7 @@ enum {
42 42
43 SFP_MOD_EMPTY = 0, 43 SFP_MOD_EMPTY = 0,
44 SFP_MOD_PROBE, 44 SFP_MOD_PROBE,
45 SFP_MOD_HPOWER,
45 SFP_MOD_PRESENT, 46 SFP_MOD_PRESENT,
46 SFP_MOD_ERROR, 47 SFP_MOD_ERROR,
47 48
@@ -86,6 +87,7 @@ static const enum gpiod_flags gpio_flags[] = {
86 * access the I2C EEPROM. However, Avago modules require 300ms. 87 * access the I2C EEPROM. However, Avago modules require 300ms.
87 */ 88 */
88#define T_PROBE_INIT msecs_to_jiffies(300) 89#define T_PROBE_INIT msecs_to_jiffies(300)
90#define T_HPOWER_LEVEL msecs_to_jiffies(300)
89#define T_PROBE_RETRY msecs_to_jiffies(100) 91#define T_PROBE_RETRY msecs_to_jiffies(100)
90 92
91/* SFP modules appear to always have their PHY configured for bus address 93/* SFP modules appear to always have their PHY configured for bus address
@@ -110,10 +112,12 @@ struct sfp {
110 struct sfp_bus *sfp_bus; 112 struct sfp_bus *sfp_bus;
111 struct phy_device *mod_phy; 113 struct phy_device *mod_phy;
112 const struct sff_data *type; 114 const struct sff_data *type;
115 u32 max_power_mW;
113 116
114 unsigned int (*get_state)(struct sfp *); 117 unsigned int (*get_state)(struct sfp *);
115 void (*set_state)(struct sfp *, unsigned int); 118 void (*set_state)(struct sfp *, unsigned int);
116 int (*read)(struct sfp *, bool, u8, void *, size_t); 119 int (*read)(struct sfp *, bool, u8, void *, size_t);
120 int (*write)(struct sfp *, bool, u8, void *, size_t);
117 121
118 struct gpio_desc *gpio[GPIO_MAX]; 122 struct gpio_desc *gpio[GPIO_MAX];
119 123
@@ -201,10 +205,11 @@ static void sfp_gpio_set_state(struct sfp *sfp, unsigned int state)
201 } 205 }
202} 206}
203 207
204static int sfp__i2c_read(struct i2c_adapter *i2c, u8 bus_addr, u8 dev_addr, 208static int sfp_i2c_read(struct sfp *sfp, bool a2, u8 dev_addr, void *buf,
205 void *buf, size_t len) 209 size_t len)
206{ 210{
207 struct i2c_msg msgs[2]; 211 struct i2c_msg msgs[2];
212 u8 bus_addr = a2 ? 0x51 : 0x50;
208 int ret; 213 int ret;
209 214
210 msgs[0].addr = bus_addr; 215 msgs[0].addr = bus_addr;
@@ -216,17 +221,38 @@ static int sfp__i2c_read(struct i2c_adapter *i2c, u8 bus_addr, u8 dev_addr,
216 msgs[1].len = len; 221 msgs[1].len = len;
217 msgs[1].buf = buf; 222 msgs[1].buf = buf;
218 223
219 ret = i2c_transfer(i2c, msgs, ARRAY_SIZE(msgs)); 224 ret = i2c_transfer(sfp->i2c, msgs, ARRAY_SIZE(msgs));
220 if (ret < 0) 225 if (ret < 0)
221 return ret; 226 return ret;
222 227
223 return ret == ARRAY_SIZE(msgs) ? len : 0; 228 return ret == ARRAY_SIZE(msgs) ? len : 0;
224} 229}
225 230
226static int sfp_i2c_read(struct sfp *sfp, bool a2, u8 addr, void *buf, 231static int sfp_i2c_write(struct sfp *sfp, bool a2, u8 dev_addr, void *buf,
227 size_t len) 232 size_t len)
228{ 233{
229 return sfp__i2c_read(sfp->i2c, a2 ? 0x51 : 0x50, addr, buf, len); 234 struct i2c_msg msgs[1];
235 u8 bus_addr = a2 ? 0x51 : 0x50;
236 int ret;
237
238 msgs[0].addr = bus_addr;
239 msgs[0].flags = 0;
240 msgs[0].len = 1 + len;
241 msgs[0].buf = kmalloc(1 + len, GFP_KERNEL);
242 if (!msgs[0].buf)
243 return -ENOMEM;
244
245 msgs[0].buf[0] = dev_addr;
246 memcpy(&msgs[0].buf[1], buf, len);
247
248 ret = i2c_transfer(sfp->i2c, msgs, ARRAY_SIZE(msgs));
249
250 kfree(msgs[0].buf);
251
252 if (ret < 0)
253 return ret;
254
255 return ret == ARRAY_SIZE(msgs) ? len : 0;
230} 256}
231 257
232static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c) 258static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c)
@@ -239,6 +265,7 @@ static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c)
239 265
240 sfp->i2c = i2c; 266 sfp->i2c = i2c;
241 sfp->read = sfp_i2c_read; 267 sfp->read = sfp_i2c_read;
268 sfp->write = sfp_i2c_write;
242 269
243 i2c_mii = mdio_i2c_alloc(sfp->dev, i2c); 270 i2c_mii = mdio_i2c_alloc(sfp->dev, i2c);
244 if (IS_ERR(i2c_mii)) 271 if (IS_ERR(i2c_mii))
@@ -274,6 +301,11 @@ static int sfp_read(struct sfp *sfp, bool a2, u8 addr, void *buf, size_t len)
274 return sfp->read(sfp, a2, addr, buf, len); 301 return sfp->read(sfp, a2, addr, buf, len);
275} 302}
276 303
304static int sfp_write(struct sfp *sfp, bool a2, u8 addr, void *buf, size_t len)
305{
306 return sfp->write(sfp, a2, addr, buf, len);
307}
308
277static unsigned int sfp_check(void *buf, size_t len) 309static unsigned int sfp_check(void *buf, size_t len)
278{ 310{
279 u8 *p, check; 311 u8 *p, check;
@@ -462,21 +494,83 @@ static void sfp_sm_mod_init(struct sfp *sfp)
462 sfp_sm_probe_phy(sfp); 494 sfp_sm_probe_phy(sfp);
463} 495}
464 496
497static int sfp_sm_mod_hpower(struct sfp *sfp)
498{
499 u32 power;
500 u8 val;
501 int err;
502
503 power = 1000;
504 if (sfp->id.ext.options & cpu_to_be16(SFP_OPTIONS_POWER_DECL))
505 power = 1500;
506 if (sfp->id.ext.options & cpu_to_be16(SFP_OPTIONS_HIGH_POWER_LEVEL))
507 power = 2000;
508
509 if (sfp->id.ext.sff8472_compliance == SFP_SFF8472_COMPLIANCE_NONE &&
510 (sfp->id.ext.diagmon & (SFP_DIAGMON_DDM | SFP_DIAGMON_ADDRMODE)) !=
511 SFP_DIAGMON_DDM) {
512 /* The module appears not to implement bus address 0xa2,
513 * or requires an address change sequence, so assume that
514 * the module powers up in the indicated power mode.
515 */
516 if (power > sfp->max_power_mW) {
517 dev_err(sfp->dev,
518 "Host does not support %u.%uW modules\n",
519 power / 1000, (power / 100) % 10);
520 return -EINVAL;
521 }
522 return 0;
523 }
524
525 if (power > sfp->max_power_mW) {
526 dev_warn(sfp->dev,
527 "Host does not support %u.%uW modules, module left in power mode 1\n",
528 power / 1000, (power / 100) % 10);
529 return 0;
530 }
531
532 if (power <= 1000)
533 return 0;
534
535 err = sfp_read(sfp, true, SFP_EXT_STATUS, &val, sizeof(val));
536 if (err != sizeof(val)) {
537 dev_err(sfp->dev, "Failed to read EEPROM: %d\n", err);
538 err = -EAGAIN;
539 goto err;
540 }
541
542 val |= BIT(0);
543
544 err = sfp_write(sfp, true, SFP_EXT_STATUS, &val, sizeof(val));
545 if (err != sizeof(val)) {
546 dev_err(sfp->dev, "Failed to write EEPROM: %d\n", err);
547 err = -EAGAIN;
548 goto err;
549 }
550
551 dev_info(sfp->dev, "Module switched to %u.%uW power level\n",
552 power / 1000, (power / 100) % 10);
553 return T_HPOWER_LEVEL;
554
555err:
556 return err;
557}
558
465static int sfp_sm_mod_probe(struct sfp *sfp) 559static int sfp_sm_mod_probe(struct sfp *sfp)
466{ 560{
467 /* SFP module inserted - read I2C data */ 561 /* SFP module inserted - read I2C data */
468 struct sfp_eeprom_id id; 562 struct sfp_eeprom_id id;
469 u8 check; 563 u8 check;
470 int err; 564 int ret;
471 565
472 err = sfp_read(sfp, false, 0, &id, sizeof(id)); 566 ret = sfp_read(sfp, false, 0, &id, sizeof(id));
473 if (err < 0) { 567 if (ret < 0) {
474 dev_err(sfp->dev, "failed to read EEPROM: %d\n", err); 568 dev_err(sfp->dev, "failed to read EEPROM: %d\n", ret);
475 return -EAGAIN; 569 return -EAGAIN;
476 } 570 }
477 571
478 if (err != sizeof(id)) { 572 if (ret != sizeof(id)) {
479 dev_err(sfp->dev, "EEPROM short read: %d\n", err); 573 dev_err(sfp->dev, "EEPROM short read: %d\n", ret);
480 return -EAGAIN; 574 return -EAGAIN;
481 } 575 }
482 576
@@ -521,7 +615,11 @@ static int sfp_sm_mod_probe(struct sfp *sfp)
521 dev_warn(sfp->dev, 615 dev_warn(sfp->dev,
522 "module address swap to access page 0xA2 is not supported.\n"); 616 "module address swap to access page 0xA2 is not supported.\n");
523 617
524 return sfp_module_insert(sfp->sfp_bus, &sfp->id); 618 ret = sfp_module_insert(sfp->sfp_bus, &sfp->id);
619 if (ret < 0)
620 return ret;
621
622 return sfp_sm_mod_hpower(sfp);
525} 623}
526 624
527static void sfp_sm_mod_remove(struct sfp *sfp) 625static void sfp_sm_mod_remove(struct sfp *sfp)
@@ -560,17 +658,25 @@ static void sfp_sm_event(struct sfp *sfp, unsigned int event)
560 if (event == SFP_E_REMOVE) { 658 if (event == SFP_E_REMOVE) {
561 sfp_sm_ins_next(sfp, SFP_MOD_EMPTY, 0); 659 sfp_sm_ins_next(sfp, SFP_MOD_EMPTY, 0);
562 } else if (event == SFP_E_TIMEOUT) { 660 } else if (event == SFP_E_TIMEOUT) {
563 int err = sfp_sm_mod_probe(sfp); 661 int val = sfp_sm_mod_probe(sfp);
564 662
565 if (err == 0) 663 if (val == 0)
566 sfp_sm_ins_next(sfp, SFP_MOD_PRESENT, 0); 664 sfp_sm_ins_next(sfp, SFP_MOD_PRESENT, 0);
567 else if (err == -EAGAIN) 665 else if (val > 0)
568 sfp_sm_set_timer(sfp, T_PROBE_RETRY); 666 sfp_sm_ins_next(sfp, SFP_MOD_HPOWER, val);
569 else 667 else if (val != -EAGAIN)
570 sfp_sm_ins_next(sfp, SFP_MOD_ERROR, 0); 668 sfp_sm_ins_next(sfp, SFP_MOD_ERROR, 0);
669 else
670 sfp_sm_set_timer(sfp, T_PROBE_RETRY);
571 } 671 }
572 break; 672 break;
573 673
674 case SFP_MOD_HPOWER:
675 if (event == SFP_E_TIMEOUT) {
676 sfp_sm_ins_next(sfp, SFP_MOD_PRESENT, 0);
677 break;
678 }
679 /* fallthrough */
574 case SFP_MOD_PRESENT: 680 case SFP_MOD_PRESENT:
575 case SFP_MOD_ERROR: 681 case SFP_MOD_ERROR:
576 if (event == SFP_E_REMOVE) { 682 if (event == SFP_E_REMOVE) {
@@ -889,6 +995,14 @@ static int sfp_probe(struct platform_device *pdev)
889 if (!(sfp->gpio[GPIO_MODDEF0])) 995 if (!(sfp->gpio[GPIO_MODDEF0]))
890 sfp->get_state = sff_gpio_get_state; 996 sfp->get_state = sff_gpio_get_state;
891 997
998 device_property_read_u32(&pdev->dev, "maximum-power-milliwatt",
999 &sfp->max_power_mW);
1000 if (!sfp->max_power_mW)
1001 sfp->max_power_mW = 1000;
1002
1003 dev_info(sfp->dev, "Host maximum power %u.%uW\n",
1004 sfp->max_power_mW / 1000, (sfp->max_power_mW / 100) % 10);
1005
892 sfp->sfp_bus = sfp_register_socket(sfp->dev, sfp, &sfp_module_ops); 1006 sfp->sfp_bus = sfp_register_socket(sfp->dev, sfp, &sfp_module_ops);
893 if (!sfp->sfp_bus) 1007 if (!sfp->sfp_bus)
894 return -ENOMEM; 1008 return -ENOMEM;
diff --git a/drivers/net/phy/teranetics.c b/drivers/net/phy/teranetics.c
index fb2cef764e9a..22f3bdd8206c 100644
--- a/drivers/net/phy/teranetics.c
+++ b/drivers/net/phy/teranetics.c
@@ -34,39 +34,17 @@ MODULE_LICENSE("GPL v2");
34 MDIO_PHYXS_LNSTAT_SYNC3 | \ 34 MDIO_PHYXS_LNSTAT_SYNC3 | \
35 MDIO_PHYXS_LNSTAT_ALIGN) 35 MDIO_PHYXS_LNSTAT_ALIGN)
36 36
37static int teranetics_config_init(struct phy_device *phydev)
38{
39 phydev->supported = SUPPORTED_10000baseT_Full;
40 phydev->advertising = SUPPORTED_10000baseT_Full;
41
42 return 0;
43}
44
45static int teranetics_soft_reset(struct phy_device *phydev)
46{
47 return 0;
48}
49
50static int teranetics_aneg_done(struct phy_device *phydev) 37static int teranetics_aneg_done(struct phy_device *phydev)
51{ 38{
52 int reg;
53
54 /* auto negotiation state can only be checked when using copper 39 /* auto negotiation state can only be checked when using copper
55 * port, if using fiber port, just lie it's done. 40 * port, if using fiber port, just lie it's done.
56 */ 41 */
57 if (!phy_read_mmd(phydev, MDIO_MMD_VEND1, 93)) { 42 if (!phy_read_mmd(phydev, MDIO_MMD_VEND1, 93))
58 reg = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1); 43 return genphy_c45_aneg_done(phydev);
59 return (reg < 0) ? reg : (reg & BMSR_ANEGCOMPLETE);
60 }
61 44
62 return 1; 45 return 1;
63} 46}
64 47
65static int teranetics_config_aneg(struct phy_device *phydev)
66{
67 return 0;
68}
69
70static int teranetics_read_status(struct phy_device *phydev) 48static int teranetics_read_status(struct phy_device *phydev)
71{ 49{
72 int reg; 50 int reg;
@@ -102,10 +80,10 @@ static struct phy_driver teranetics_driver[] = {
102 .phy_id = PHY_ID_TN2020, 80 .phy_id = PHY_ID_TN2020,
103 .phy_id_mask = 0xffffffff, 81 .phy_id_mask = 0xffffffff,
104 .name = "Teranetics TN2020", 82 .name = "Teranetics TN2020",
105 .soft_reset = teranetics_soft_reset, 83 .soft_reset = gen10g_no_soft_reset,
106 .aneg_done = teranetics_aneg_done, 84 .aneg_done = teranetics_aneg_done,
107 .config_init = teranetics_config_init, 85 .config_init = gen10g_config_init,
108 .config_aneg = teranetics_config_aneg, 86 .config_aneg = gen10g_config_aneg,
109 .read_status = teranetics_read_status, 87 .read_status = teranetics_read_status,
110 .match_phy_device = teranetics_match_phy_device, 88 .match_phy_device = teranetics_match_phy_device,
111}, 89},
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
index da1937832c99..926c2c322d43 100644
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -970,6 +970,7 @@ static struct pernet_operations ppp_net_ops = {
970 .exit = ppp_exit_net, 970 .exit = ppp_exit_net,
971 .id = &ppp_net_id, 971 .id = &ppp_net_id,
972 .size = sizeof(struct ppp_net), 972 .size = sizeof(struct ppp_net),
973 .async = true,
973}; 974};
974 975
975static int ppp_unit_register(struct ppp *ppp, int unit, bool ifname_is_set) 976static int ppp_unit_register(struct ppp *ppp, int unit, bool ifname_is_set)
diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c
index 5aa59f41bf8c..c10e6181a2f0 100644
--- a/drivers/net/ppp/pppoe.c
+++ b/drivers/net/ppp/pppoe.c
@@ -714,7 +714,7 @@ err_put:
714} 714}
715 715
716static int pppoe_getname(struct socket *sock, struct sockaddr *uaddr, 716static int pppoe_getname(struct socket *sock, struct sockaddr *uaddr,
717 int *usockaddr_len, int peer) 717 int peer)
718{ 718{
719 int len = sizeof(struct sockaddr_pppox); 719 int len = sizeof(struct sockaddr_pppox);
720 struct sockaddr_pppox sp; 720 struct sockaddr_pppox sp;
@@ -726,9 +726,7 @@ static int pppoe_getname(struct socket *sock, struct sockaddr *uaddr,
726 726
727 memcpy(uaddr, &sp, len); 727 memcpy(uaddr, &sp, len);
728 728
729 *usockaddr_len = len; 729 return len;
730
731 return 0;
732} 730}
733 731
734static int pppoe_ioctl(struct socket *sock, unsigned int cmd, 732static int pppoe_ioctl(struct socket *sock, unsigned int cmd,
@@ -1163,6 +1161,7 @@ static struct pernet_operations pppoe_net_ops = {
1163 .exit = pppoe_exit_net, 1161 .exit = pppoe_exit_net,
1164 .id = &pppoe_net_id, 1162 .id = &pppoe_net_id,
1165 .size = sizeof(struct pppoe_net), 1163 .size = sizeof(struct pppoe_net),
1164 .async = true,
1166}; 1165};
1167 1166
1168static int __init pppoe_init(void) 1167static int __init pppoe_init(void)
diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c
index 6dde9a0cfe76..8249d46a7844 100644
--- a/drivers/net/ppp/pptp.c
+++ b/drivers/net/ppp/pptp.c
@@ -483,7 +483,7 @@ static int pptp_connect(struct socket *sock, struct sockaddr *uservaddr,
483} 483}
484 484
485static int pptp_getname(struct socket *sock, struct sockaddr *uaddr, 485static int pptp_getname(struct socket *sock, struct sockaddr *uaddr,
486 int *usockaddr_len, int peer) 486 int peer)
487{ 487{
488 int len = sizeof(struct sockaddr_pppox); 488 int len = sizeof(struct sockaddr_pppox);
489 struct sockaddr_pppox sp; 489 struct sockaddr_pppox sp;
@@ -496,9 +496,7 @@ static int pptp_getname(struct socket *sock, struct sockaddr *uaddr,
496 496
497 memcpy(uaddr, &sp, len); 497 memcpy(uaddr, &sp, len);
498 498
499 *usockaddr_len = len; 499 return len;
500
501 return 0;
502} 500}
503 501
504static int pptp_release(struct socket *sock) 502static int pptp_release(struct socket *sock)
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index 56c701b73c12..222093e878a8 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -1105,14 +1105,15 @@ static void team_port_disable_netpoll(struct team_port *port)
1105} 1105}
1106#endif 1106#endif
1107 1107
1108static int team_upper_dev_link(struct team *team, struct team_port *port) 1108static int team_upper_dev_link(struct team *team, struct team_port *port,
1109 struct netlink_ext_ack *extack)
1109{ 1110{
1110 struct netdev_lag_upper_info lag_upper_info; 1111 struct netdev_lag_upper_info lag_upper_info;
1111 int err; 1112 int err;
1112 1113
1113 lag_upper_info.tx_type = team->mode->lag_tx_type; 1114 lag_upper_info.tx_type = team->mode->lag_tx_type;
1114 err = netdev_master_upper_dev_link(port->dev, team->dev, NULL, 1115 err = netdev_master_upper_dev_link(port->dev, team->dev, NULL,
1115 &lag_upper_info, NULL); 1116 &lag_upper_info, extack);
1116 if (err) 1117 if (err)
1117 return err; 1118 return err;
1118 port->dev->priv_flags |= IFF_TEAM_PORT; 1119 port->dev->priv_flags |= IFF_TEAM_PORT;
@@ -1129,7 +1130,8 @@ static void __team_port_change_port_added(struct team_port *port, bool linkup);
1129static int team_dev_type_check_change(struct net_device *dev, 1130static int team_dev_type_check_change(struct net_device *dev,
1130 struct net_device *port_dev); 1131 struct net_device *port_dev);
1131 1132
1132static int team_port_add(struct team *team, struct net_device *port_dev) 1133static int team_port_add(struct team *team, struct net_device *port_dev,
1134 struct netlink_ext_ack *extack)
1133{ 1135{
1134 struct net_device *dev = team->dev; 1136 struct net_device *dev = team->dev;
1135 struct team_port *port; 1137 struct team_port *port;
@@ -1137,12 +1139,14 @@ static int team_port_add(struct team *team, struct net_device *port_dev)
1137 int err; 1139 int err;
1138 1140
1139 if (port_dev->flags & IFF_LOOPBACK) { 1141 if (port_dev->flags & IFF_LOOPBACK) {
1142 NL_SET_ERR_MSG(extack, "Loopback device can't be added as a team port");
1140 netdev_err(dev, "Device %s is loopback device. Loopback devices can't be added as a team port\n", 1143 netdev_err(dev, "Device %s is loopback device. Loopback devices can't be added as a team port\n",
1141 portname); 1144 portname);
1142 return -EINVAL; 1145 return -EINVAL;
1143 } 1146 }
1144 1147
1145 if (team_port_exists(port_dev)) { 1148 if (team_port_exists(port_dev)) {
1149 NL_SET_ERR_MSG(extack, "Device is already a port of a team device");
1146 netdev_err(dev, "Device %s is already a port " 1150 netdev_err(dev, "Device %s is already a port "
1147 "of a team device\n", portname); 1151 "of a team device\n", portname);
1148 return -EBUSY; 1152 return -EBUSY;
@@ -1150,6 +1154,7 @@ static int team_port_add(struct team *team, struct net_device *port_dev)
1150 1154
1151 if (port_dev->features & NETIF_F_VLAN_CHALLENGED && 1155 if (port_dev->features & NETIF_F_VLAN_CHALLENGED &&
1152 vlan_uses_dev(dev)) { 1156 vlan_uses_dev(dev)) {
1157 NL_SET_ERR_MSG(extack, "Device is VLAN challenged and team device has VLAN set up");
1153 netdev_err(dev, "Device %s is VLAN challenged and team device has VLAN set up\n", 1158 netdev_err(dev, "Device %s is VLAN challenged and team device has VLAN set up\n",
1154 portname); 1159 portname);
1155 return -EPERM; 1160 return -EPERM;
@@ -1160,6 +1165,7 @@ static int team_port_add(struct team *team, struct net_device *port_dev)
1160 return err; 1165 return err;
1161 1166
1162 if (port_dev->flags & IFF_UP) { 1167 if (port_dev->flags & IFF_UP) {
1168 NL_SET_ERR_MSG(extack, "Device is up. Set it down before adding it as a team port");
1163 netdev_err(dev, "Device %s is up. Set it down before adding it as a team port\n", 1169 netdev_err(dev, "Device %s is up. Set it down before adding it as a team port\n",
1164 portname); 1170 portname);
1165 return -EBUSY; 1171 return -EBUSY;
@@ -1227,7 +1233,7 @@ static int team_port_add(struct team *team, struct net_device *port_dev)
1227 goto err_handler_register; 1233 goto err_handler_register;
1228 } 1234 }
1229 1235
1230 err = team_upper_dev_link(team, port); 1236 err = team_upper_dev_link(team, port, extack);
1231 if (err) { 1237 if (err) {
1232 netdev_err(dev, "Device %s failed to set upper link\n", 1238 netdev_err(dev, "Device %s failed to set upper link\n",
1233 portname); 1239 portname);
@@ -1921,7 +1927,7 @@ static int team_add_slave(struct net_device *dev, struct net_device *port_dev,
1921 int err; 1927 int err;
1922 1928
1923 mutex_lock(&team->lock); 1929 mutex_lock(&team->lock);
1924 err = team_port_add(team, port_dev); 1930 err = team_port_add(team, port_dev, extack);
1925 mutex_unlock(&team->lock); 1931 mutex_unlock(&team->lock);
1926 1932
1927 if (!err) 1933 if (!err)
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 28cfa642e39a..a1ba262f40ad 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -78,6 +78,7 @@
78#include <linux/mutex.h> 78#include <linux/mutex.h>
79 79
80#include <linux/uaccess.h> 80#include <linux/uaccess.h>
81#include <linux/proc_fs.h>
81 82
82/* Uncomment to enable debugging */ 83/* Uncomment to enable debugging */
83/* #define TUN_DEBUG 1 */ 84/* #define TUN_DEBUG 1 */
@@ -1613,7 +1614,6 @@ static struct sk_buff *tun_build_skb(struct tun_struct *tun,
1613 unsigned int delta = 0; 1614 unsigned int delta = 0;
1614 char *buf; 1615 char *buf;
1615 size_t copied; 1616 size_t copied;
1616 bool xdp_xmit = false;
1617 int err, pad = TUN_RX_PAD; 1617 int err, pad = TUN_RX_PAD;
1618 1618
1619 rcu_read_lock(); 1619 rcu_read_lock();
@@ -1671,8 +1671,14 @@ static struct sk_buff *tun_build_skb(struct tun_struct *tun,
1671 preempt_enable(); 1671 preempt_enable();
1672 return NULL; 1672 return NULL;
1673 case XDP_TX: 1673 case XDP_TX:
1674 xdp_xmit = true; 1674 get_page(alloc_frag->page);
1675 /* fall through */ 1675 alloc_frag->offset += buflen;
1676 if (tun_xdp_xmit(tun->dev, &xdp))
1677 goto err_redirect;
1678 tun_xdp_flush(tun->dev);
1679 rcu_read_unlock();
1680 preempt_enable();
1681 return NULL;
1676 case XDP_PASS: 1682 case XDP_PASS:
1677 delta = orig_data - xdp.data; 1683 delta = orig_data - xdp.data;
1678 break; 1684 break;
@@ -1699,14 +1705,6 @@ static struct sk_buff *tun_build_skb(struct tun_struct *tun,
1699 get_page(alloc_frag->page); 1705 get_page(alloc_frag->page);
1700 alloc_frag->offset += buflen; 1706 alloc_frag->offset += buflen;
1701 1707
1702 if (xdp_xmit) {
1703 skb->dev = tun->dev;
1704 generic_xdp_tx(skb, xdp_prog);
1705 rcu_read_unlock();
1706 preempt_enable();
1707 return NULL;
1708 }
1709
1710 rcu_read_unlock(); 1708 rcu_read_unlock();
1711 preempt_enable(); 1709 preempt_enable();
1712 1710
@@ -2287,11 +2285,67 @@ static int tun_validate(struct nlattr *tb[], struct nlattr *data[],
2287 return -EINVAL; 2285 return -EINVAL;
2288} 2286}
2289 2287
2288static size_t tun_get_size(const struct net_device *dev)
2289{
2290 BUILD_BUG_ON(sizeof(u32) != sizeof(uid_t));
2291 BUILD_BUG_ON(sizeof(u32) != sizeof(gid_t));
2292
2293 return nla_total_size(sizeof(uid_t)) + /* OWNER */
2294 nla_total_size(sizeof(gid_t)) + /* GROUP */
2295 nla_total_size(sizeof(u8)) + /* TYPE */
2296 nla_total_size(sizeof(u8)) + /* PI */
2297 nla_total_size(sizeof(u8)) + /* VNET_HDR */
2298 nla_total_size(sizeof(u8)) + /* PERSIST */
2299 nla_total_size(sizeof(u8)) + /* MULTI_QUEUE */
2300 nla_total_size(sizeof(u32)) + /* NUM_QUEUES */
2301 nla_total_size(sizeof(u32)) + /* NUM_DISABLED_QUEUES */
2302 0;
2303}
2304
2305static int tun_fill_info(struct sk_buff *skb, const struct net_device *dev)
2306{
2307 struct tun_struct *tun = netdev_priv(dev);
2308
2309 if (nla_put_u8(skb, IFLA_TUN_TYPE, tun->flags & TUN_TYPE_MASK))
2310 goto nla_put_failure;
2311 if (uid_valid(tun->owner) &&
2312 nla_put_u32(skb, IFLA_TUN_OWNER,
2313 from_kuid_munged(current_user_ns(), tun->owner)))
2314 goto nla_put_failure;
2315 if (gid_valid(tun->group) &&
2316 nla_put_u32(skb, IFLA_TUN_GROUP,
2317 from_kgid_munged(current_user_ns(), tun->group)))
2318 goto nla_put_failure;
2319 if (nla_put_u8(skb, IFLA_TUN_PI, !(tun->flags & IFF_NO_PI)))
2320 goto nla_put_failure;
2321 if (nla_put_u8(skb, IFLA_TUN_VNET_HDR, !!(tun->flags & IFF_VNET_HDR)))
2322 goto nla_put_failure;
2323 if (nla_put_u8(skb, IFLA_TUN_PERSIST, !!(tun->flags & IFF_PERSIST)))
2324 goto nla_put_failure;
2325 if (nla_put_u8(skb, IFLA_TUN_MULTI_QUEUE,
2326 !!(tun->flags & IFF_MULTI_QUEUE)))
2327 goto nla_put_failure;
2328 if (tun->flags & IFF_MULTI_QUEUE) {
2329 if (nla_put_u32(skb, IFLA_TUN_NUM_QUEUES, tun->numqueues))
2330 goto nla_put_failure;
2331 if (nla_put_u32(skb, IFLA_TUN_NUM_DISABLED_QUEUES,
2332 tun->numdisabled))
2333 goto nla_put_failure;
2334 }
2335
2336 return 0;
2337
2338nla_put_failure:
2339 return -EMSGSIZE;
2340}
2341
2290static struct rtnl_link_ops tun_link_ops __read_mostly = { 2342static struct rtnl_link_ops tun_link_ops __read_mostly = {
2291 .kind = DRV_NAME, 2343 .kind = DRV_NAME,
2292 .priv_size = sizeof(struct tun_struct), 2344 .priv_size = sizeof(struct tun_struct),
2293 .setup = tun_setup, 2345 .setup = tun_setup,
2294 .validate = tun_validate, 2346 .validate = tun_validate,
2347 .get_size = tun_get_size,
2348 .fill_info = tun_fill_info,
2295}; 2349};
2296 2350
2297static void tun_sock_write_space(struct sock *sk) 2351static void tun_sock_write_space(struct sock *sk)
@@ -2783,6 +2837,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
2783 struct tun_struct *tun; 2837 struct tun_struct *tun;
2784 void __user* argp = (void __user*)arg; 2838 void __user* argp = (void __user*)arg;
2785 struct ifreq ifr; 2839 struct ifreq ifr;
2840 struct net *net;
2786 kuid_t owner; 2841 kuid_t owner;
2787 kgid_t group; 2842 kgid_t group;
2788 int sndbuf; 2843 int sndbuf;
@@ -2791,7 +2846,8 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
2791 int le; 2846 int le;
2792 int ret; 2847 int ret;
2793 2848
2794 if (cmd == TUNSETIFF || cmd == TUNSETQUEUE || _IOC_TYPE(cmd) == SOCK_IOC_TYPE) { 2849 if (cmd == TUNSETIFF || cmd == TUNSETQUEUE ||
2850 (_IOC_TYPE(cmd) == SOCK_IOC_TYPE && cmd != SIOCGSKNS)) {
2795 if (copy_from_user(&ifr, argp, ifreq_len)) 2851 if (copy_from_user(&ifr, argp, ifreq_len))
2796 return -EFAULT; 2852 return -EFAULT;
2797 } else { 2853 } else {
@@ -2811,6 +2867,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
2811 rtnl_lock(); 2867 rtnl_lock();
2812 2868
2813 tun = tun_get(tfile); 2869 tun = tun_get(tfile);
2870 net = sock_net(&tfile->sk);
2814 if (cmd == TUNSETIFF) { 2871 if (cmd == TUNSETIFF) {
2815 ret = -EEXIST; 2872 ret = -EEXIST;
2816 if (tun) 2873 if (tun)
@@ -2818,7 +2875,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
2818 2875
2819 ifr.ifr_name[IFNAMSIZ-1] = '\0'; 2876 ifr.ifr_name[IFNAMSIZ-1] = '\0';
2820 2877
2821 ret = tun_set_iff(sock_net(&tfile->sk), file, &ifr); 2878 ret = tun_set_iff(net, file, &ifr);
2822 2879
2823 if (ret) 2880 if (ret)
2824 goto unlock; 2881 goto unlock;
@@ -2840,6 +2897,14 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
2840 tfile->ifindex = ifindex; 2897 tfile->ifindex = ifindex;
2841 goto unlock; 2898 goto unlock;
2842 } 2899 }
2900 if (cmd == SIOCGSKNS) {
2901 ret = -EPERM;
2902 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
2903 goto unlock;
2904
2905 ret = open_related_ns(&net->ns, get_net_ns);
2906 goto unlock;
2907 }
2843 2908
2844 ret = -EBADFD; 2909 ret = -EBADFD;
2845 if (!tun) 2910 if (!tun)
diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c
index f32261ecd215..fb1b78d4b9ef 100644
--- a/drivers/net/usb/ax88179_178a.c
+++ b/drivers/net/usb/ax88179_178a.c
@@ -1223,7 +1223,7 @@ static int ax88179_led_setting(struct usbnet *dev)
1223 return 0; 1223 return 0;
1224} 1224}
1225 1225
1226static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf) 1226static int ax88179_link_bind_or_reset(struct usbnet *dev, bool do_reset)
1227{ 1227{
1228 u8 buf[5]; 1228 u8 buf[5];
1229 u16 *tmp16; 1229 u16 *tmp16;
@@ -1231,12 +1231,11 @@ static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf)
1231 struct ax88179_data *ax179_data = (struct ax88179_data *)dev->data; 1231 struct ax88179_data *ax179_data = (struct ax88179_data *)dev->data;
1232 struct ethtool_eee eee_data; 1232 struct ethtool_eee eee_data;
1233 1233
1234 usbnet_get_endpoints(dev, intf);
1235
1236 tmp16 = (u16 *)buf; 1234 tmp16 = (u16 *)buf;
1237 tmp = (u8 *)buf; 1235 tmp = (u8 *)buf;
1238 1236
1239 memset(ax179_data, 0, sizeof(*ax179_data)); 1237 if (!do_reset)
1238 memset(ax179_data, 0, sizeof(*ax179_data));
1240 1239
1241 /* Power up ethernet PHY */ 1240 /* Power up ethernet PHY */
1242 *tmp16 = 0; 1241 *tmp16 = 0;
@@ -1249,9 +1248,13 @@ static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf)
1249 ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, tmp); 1248 ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, tmp);
1250 msleep(100); 1249 msleep(100);
1251 1250
1251 if (do_reset)
1252 ax88179_auto_detach(dev, 0);
1253
1252 ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN, 1254 ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN,
1253 ETH_ALEN, dev->net->dev_addr); 1255 ETH_ALEN, dev->net->dev_addr);
1254 memcpy(dev->net->perm_addr, dev->net->dev_addr, ETH_ALEN); 1256 if (!do_reset)
1257 memcpy(dev->net->perm_addr, dev->net->dev_addr, ETH_ALEN);
1255 1258
1256 /* RX bulk configuration */ 1259 /* RX bulk configuration */
1257 memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5); 1260 memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5);
@@ -1266,19 +1269,21 @@ static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf)
1266 ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_HIGH, 1269 ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_HIGH,
1267 1, 1, tmp); 1270 1, 1, tmp);
1268 1271
1269 dev->net->netdev_ops = &ax88179_netdev_ops; 1272 if (!do_reset) {
1270 dev->net->ethtool_ops = &ax88179_ethtool_ops; 1273 dev->net->netdev_ops = &ax88179_netdev_ops;
1271 dev->net->needed_headroom = 8; 1274 dev->net->ethtool_ops = &ax88179_ethtool_ops;
1272 dev->net->max_mtu = 4088; 1275 dev->net->needed_headroom = 8;
1273 1276 dev->net->max_mtu = 4088;
1274 /* Initialize MII structure */ 1277
1275 dev->mii.dev = dev->net; 1278 /* Initialize MII structure */
1276 dev->mii.mdio_read = ax88179_mdio_read; 1279 dev->mii.dev = dev->net;
1277 dev->mii.mdio_write = ax88179_mdio_write; 1280 dev->mii.mdio_read = ax88179_mdio_read;
1278 dev->mii.phy_id_mask = 0xff; 1281 dev->mii.mdio_write = ax88179_mdio_write;
1279 dev->mii.reg_num_mask = 0xff; 1282 dev->mii.phy_id_mask = 0xff;
1280 dev->mii.phy_id = 0x03; 1283 dev->mii.reg_num_mask = 0xff;
1281 dev->mii.supports_gmii = 1; 1284 dev->mii.phy_id = 0x03;
1285 dev->mii.supports_gmii = 1;
1286 }
1282 1287
1283 dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | 1288 dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
1284 NETIF_F_RXCSUM; 1289 NETIF_F_RXCSUM;
@@ -1330,6 +1335,13 @@ static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf)
1330 return 0; 1335 return 0;
1331} 1336}
1332 1337
1338static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf)
1339{
1340 usbnet_get_endpoints(dev, intf);
1341
1342 return ax88179_link_bind_or_reset(dev, false);
1343}
1344
1333static void ax88179_unbind(struct usbnet *dev, struct usb_interface *intf) 1345static void ax88179_unbind(struct usbnet *dev, struct usb_interface *intf)
1334{ 1346{
1335 u16 tmp16; 1347 u16 tmp16;
@@ -1458,74 +1470,7 @@ ax88179_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
1458 1470
1459static int ax88179_link_reset(struct usbnet *dev) 1471static int ax88179_link_reset(struct usbnet *dev)
1460{ 1472{
1461 struct ax88179_data *ax179_data = (struct ax88179_data *)dev->data; 1473 return ax88179_link_bind_or_reset(dev, true);
1462 u8 tmp[5], link_sts;
1463 u16 mode, tmp16, delay = HZ / 10;
1464 u32 tmp32 = 0x40000000;
1465 unsigned long jtimeout;
1466
1467 jtimeout = jiffies + delay;
1468 while (tmp32 & 0x40000000) {
1469 mode = 0;
1470 ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &mode);
1471 ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2,
1472 &ax179_data->rxctl);
1473
1474 /*link up, check the usb device control TX FIFO full or empty*/
1475 ax88179_read_cmd(dev, 0x81, 0x8c, 0, 4, &tmp32);
1476
1477 if (time_after(jiffies, jtimeout))
1478 return 0;
1479 }
1480
1481 mode = AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_TXFLOW_CTRLEN |
1482 AX_MEDIUM_RXFLOW_CTRLEN;
1483
1484 ax88179_read_cmd(dev, AX_ACCESS_MAC, PHYSICAL_LINK_STATUS,
1485 1, 1, &link_sts);
1486
1487 ax88179_read_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
1488 GMII_PHY_PHYSR, 2, &tmp16);
1489
1490 if (!(tmp16 & GMII_PHY_PHYSR_LINK)) {
1491 return 0;
1492 } else if (GMII_PHY_PHYSR_GIGA == (tmp16 & GMII_PHY_PHYSR_SMASK)) {
1493 mode |= AX_MEDIUM_GIGAMODE | AX_MEDIUM_EN_125MHZ;
1494 if (dev->net->mtu > 1500)
1495 mode |= AX_MEDIUM_JUMBO_EN;
1496
1497 if (link_sts & AX_USB_SS)
1498 memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5);
1499 else if (link_sts & AX_USB_HS)
1500 memcpy(tmp, &AX88179_BULKIN_SIZE[1], 5);
1501 else
1502 memcpy(tmp, &AX88179_BULKIN_SIZE[3], 5);
1503 } else if (GMII_PHY_PHYSR_100 == (tmp16 & GMII_PHY_PHYSR_SMASK)) {
1504 mode |= AX_MEDIUM_PS;
1505
1506 if (link_sts & (AX_USB_SS | AX_USB_HS))
1507 memcpy(tmp, &AX88179_BULKIN_SIZE[2], 5);
1508 else
1509 memcpy(tmp, &AX88179_BULKIN_SIZE[3], 5);
1510 } else {
1511 memcpy(tmp, &AX88179_BULKIN_SIZE[3], 5);
1512 }
1513
1514 /* RX bulk configuration */
1515 ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_BULKIN_QCTRL, 5, 5, tmp);
1516
1517 dev->rx_urb_size = (1024 * (tmp[3] + 2));
1518
1519 if (tmp16 & GMII_PHY_PHYSR_FULL)
1520 mode |= AX_MEDIUM_FULL_DUPLEX;
1521 ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
1522 2, 2, &mode);
1523
1524 ax179_data->eee_enabled = ax88179_chk_eee(dev);
1525
1526 netif_carrier_on(dev->net);
1527
1528 return 0;
1529} 1474}
1530 1475
1531static int ax88179_reset(struct usbnet *dev) 1476static int ax88179_reset(struct usbnet *dev)
@@ -1556,7 +1501,6 @@ static int ax88179_reset(struct usbnet *dev)
1556 1501
1557 ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN, ETH_ALEN, 1502 ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN, ETH_ALEN,
1558 dev->net->dev_addr); 1503 dev->net->dev_addr);
1559 memcpy(dev->net->perm_addr, dev->net->dev_addr, ETH_ALEN);
1560 1504
1561 /* RX bulk configuration */ 1505 /* RX bulk configuration */
1562 memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5); 1506 memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5);
diff --git a/drivers/net/usb/cdc_eem.c b/drivers/net/usb/cdc_eem.c
index f7180f8db39e..61ea4eaace5d 100644
--- a/drivers/net/usb/cdc_eem.c
+++ b/drivers/net/usb/cdc_eem.c
@@ -83,11 +83,8 @@ static int eem_bind(struct usbnet *dev, struct usb_interface *intf)
83 int status = 0; 83 int status = 0;
84 84
85 status = usbnet_get_endpoints(dev, intf); 85 status = usbnet_get_endpoints(dev, intf);
86 if (status < 0) { 86 if (status < 0)
87 usb_set_intfdata(intf, NULL);
88 usb_driver_release_interface(driver_of(intf), intf);
89 return status; 87 return status;
90 }
91 88
92 /* no jumbogram (16K) support for now */ 89 /* no jumbogram (16K) support for now */
93 90
diff --git a/drivers/net/usb/kalmia.c b/drivers/net/usb/kalmia.c
index ce0b0b4e3a57..bd2ba3659028 100644
--- a/drivers/net/usb/kalmia.c
+++ b/drivers/net/usb/kalmia.c
@@ -114,14 +114,14 @@ kalmia_init_and_get_ethernet_addr(struct usbnet *dev, u8 *ethernet_addr)
114 return -ENOMEM; 114 return -ENOMEM;
115 115
116 memcpy(usb_buf, init_msg_1, 12); 116 memcpy(usb_buf, init_msg_1, 12);
117 status = kalmia_send_init_packet(dev, usb_buf, sizeof(init_msg_1) 117 status = kalmia_send_init_packet(dev, usb_buf, ARRAY_SIZE(init_msg_1),
118 / sizeof(init_msg_1[0]), usb_buf, 24); 118 usb_buf, 24);
119 if (status != 0) 119 if (status != 0)
120 return status; 120 return status;
121 121
122 memcpy(usb_buf, init_msg_2, 12); 122 memcpy(usb_buf, init_msg_2, 12);
123 status = kalmia_send_init_packet(dev, usb_buf, sizeof(init_msg_2) 123 status = kalmia_send_init_packet(dev, usb_buf, ARRAY_SIZE(init_msg_2),
124 / sizeof(init_msg_2[0]), usb_buf, 28); 124 usb_buf, 28);
125 if (status != 0) 125 if (status != 0)
126 return status; 126 return status;
127 127
@@ -150,12 +150,8 @@ kalmia_bind(struct usbnet *dev, struct usb_interface *intf)
150 dev->rx_urb_size = dev->hard_mtu * 10; // Found as optimal after testing 150 dev->rx_urb_size = dev->hard_mtu * 10; // Found as optimal after testing
151 151
152 status = kalmia_init_and_get_ethernet_addr(dev, ethernet_addr); 152 status = kalmia_init_and_get_ethernet_addr(dev, ethernet_addr);
153 153 if (status)
154 if (status) {
155 usb_set_intfdata(intf, NULL);
156 usb_driver_release_interface(driver_of(intf), intf);
157 return status; 154 return status;
158 }
159 155
160 memcpy(dev->net->dev_addr, ethernet_addr, ETH_ALEN); 156 memcpy(dev->net->dev_addr, ethernet_addr, ETH_ALEN);
161 157
diff --git a/drivers/net/usb/lg-vl600.c b/drivers/net/usb/lg-vl600.c
index dbabd7ca5268..257916f172cd 100644
--- a/drivers/net/usb/lg-vl600.c
+++ b/drivers/net/usb/lg-vl600.c
@@ -157,12 +157,8 @@ static int vl600_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
157 157
158 s->current_rx_buf = skb_copy_expand(skb, 0, 158 s->current_rx_buf = skb_copy_expand(skb, 0,
159 le32_to_cpup(&frame->len), GFP_ATOMIC); 159 le32_to_cpup(&frame->len), GFP_ATOMIC);
160 if (!s->current_rx_buf) { 160 if (!s->current_rx_buf)
161 netif_err(dev, ifup, dev->net, "Reserving %i bytes "
162 "for packet assembly failed.\n",
163 le32_to_cpup(&frame->len));
164 dev->net->stats.rx_errors++; 161 dev->net->stats.rx_errors++;
165 }
166 162
167 return 0; 163 return 0;
168 } 164 }
diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
index 139c61c8244a..c6be49d3a9eb 100644
--- a/drivers/net/vrf.c
+++ b/drivers/net/vrf.c
@@ -736,7 +736,6 @@ static int vrf_rtable_create(struct net_device *dev)
736 return -ENOMEM; 736 return -ENOMEM;
737 737
738 rth->dst.output = vrf_output; 738 rth->dst.output = vrf_output;
739 rth->rt_table_id = vrf->tb_id;
740 739
741 rcu_assign_pointer(vrf->rth, rth); 740 rcu_assign_pointer(vrf->rth, rth);
742 741
@@ -942,6 +941,7 @@ static struct rt6_info *vrf_ip6_route_lookup(struct net *net,
942 const struct net_device *dev, 941 const struct net_device *dev,
943 struct flowi6 *fl6, 942 struct flowi6 *fl6,
944 int ifindex, 943 int ifindex,
944 const struct sk_buff *skb,
945 int flags) 945 int flags)
946{ 946{
947 struct net_vrf *vrf = netdev_priv(dev); 947 struct net_vrf *vrf = netdev_priv(dev);
@@ -960,7 +960,7 @@ static struct rt6_info *vrf_ip6_route_lookup(struct net *net,
960 if (!table) 960 if (!table)
961 return NULL; 961 return NULL;
962 962
963 return ip6_pol_route(net, table, ifindex, fl6, flags); 963 return ip6_pol_route(net, table, ifindex, fl6, skb, flags);
964} 964}
965 965
966static void vrf_ip6_input_dst(struct sk_buff *skb, struct net_device *vrf_dev, 966static void vrf_ip6_input_dst(struct sk_buff *skb, struct net_device *vrf_dev,
@@ -978,7 +978,7 @@ static void vrf_ip6_input_dst(struct sk_buff *skb, struct net_device *vrf_dev,
978 struct net *net = dev_net(vrf_dev); 978 struct net *net = dev_net(vrf_dev);
979 struct rt6_info *rt6; 979 struct rt6_info *rt6;
980 980
981 rt6 = vrf_ip6_route_lookup(net, vrf_dev, &fl6, ifindex, 981 rt6 = vrf_ip6_route_lookup(net, vrf_dev, &fl6, ifindex, skb,
982 RT6_LOOKUP_F_HAS_SADDR | RT6_LOOKUP_F_IFACE); 982 RT6_LOOKUP_F_HAS_SADDR | RT6_LOOKUP_F_IFACE);
983 if (unlikely(!rt6)) 983 if (unlikely(!rt6))
984 return; 984 return;
@@ -1111,7 +1111,7 @@ static struct dst_entry *vrf_link_scope_lookup(const struct net_device *dev,
1111 if (!ipv6_addr_any(&fl6->saddr)) 1111 if (!ipv6_addr_any(&fl6->saddr))
1112 flags |= RT6_LOOKUP_F_HAS_SADDR; 1112 flags |= RT6_LOOKUP_F_HAS_SADDR;
1113 1113
1114 rt = vrf_ip6_route_lookup(net, dev, fl6, fl6->flowi6_oif, flags); 1114 rt = vrf_ip6_route_lookup(net, dev, fl6, fl6->flowi6_oif, NULL, flags);
1115 if (rt) 1115 if (rt)
1116 dst = &rt->dst; 1116 dst = &rt->dst;
1117 1117
@@ -1146,6 +1146,7 @@ static inline size_t vrf_fib_rule_nl_size(void)
1146 sz = NLMSG_ALIGN(sizeof(struct fib_rule_hdr)); 1146 sz = NLMSG_ALIGN(sizeof(struct fib_rule_hdr));
1147 sz += nla_total_size(sizeof(u8)); /* FRA_L3MDEV */ 1147 sz += nla_total_size(sizeof(u8)); /* FRA_L3MDEV */
1148 sz += nla_total_size(sizeof(u32)); /* FRA_PRIORITY */ 1148 sz += nla_total_size(sizeof(u32)); /* FRA_PRIORITY */
1149 sz += nla_total_size(sizeof(u8)); /* FRA_PROTOCOL */
1149 1150
1150 return sz; 1151 return sz;
1151} 1152}
@@ -1176,6 +1177,9 @@ static int vrf_fib_rule(const struct net_device *dev, __u8 family, bool add_it)
1176 frh->family = family; 1177 frh->family = family;
1177 frh->action = FR_ACT_TO_TBL; 1178 frh->action = FR_ACT_TO_TBL;
1178 1179
1180 if (nla_put_u8(skb, FRA_PROTOCOL, RTPROT_KERNEL))
1181 goto nla_put_failure;
1182
1179 if (nla_put_u8(skb, FRA_L3MDEV, 1)) 1183 if (nla_put_u8(skb, FRA_L3MDEV, 1))
1180 goto nla_put_failure; 1184 goto nla_put_failure;
1181 1185
@@ -1431,6 +1435,7 @@ static struct pernet_operations vrf_net_ops __net_initdata = {
1431 .init = vrf_netns_init, 1435 .init = vrf_netns_init,
1432 .id = &vrf_net_id, 1436 .id = &vrf_net_id,
1433 .size = sizeof(bool), 1437 .size = sizeof(bool),
1438 .async = true,
1434}; 1439};
1435 1440
1436static int __init vrf_init_module(void) 1441static int __init vrf_init_module(void)
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index fab7a4db249e..aa5f034d6ad1 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -3752,6 +3752,7 @@ static struct pernet_operations vxlan_net_ops = {
3752 .exit_batch = vxlan_exit_batch_net, 3752 .exit_batch = vxlan_exit_batch_net,
3753 .id = &vxlan_net_id, 3753 .id = &vxlan_net_id,
3754 .size = sizeof(struct vxlan_net), 3754 .size = sizeof(struct vxlan_net),
3755 .async = true,
3755}; 3756};
3756 3757
3757static int __init vxlan_init_module(void) 3758static int __init vxlan_init_module(void)
diff --git a/drivers/net/wimax/i2400m/usb-rx.c b/drivers/net/wimax/i2400m/usb-rx.c
index b78ee676e102..5b64bda7d9e7 100644
--- a/drivers/net/wimax/i2400m/usb-rx.c
+++ b/drivers/net/wimax/i2400m/usb-rx.c
@@ -263,9 +263,6 @@ retry:
263 new_skb = skb_copy_expand(rx_skb, 0, rx_size - rx_skb->len, 263 new_skb = skb_copy_expand(rx_skb, 0, rx_size - rx_skb->len,
264 GFP_KERNEL); 264 GFP_KERNEL);
265 if (new_skb == NULL) { 265 if (new_skb == NULL) {
266 if (printk_ratelimit())
267 dev_err(dev, "RX: Can't reallocate skb to %d; "
268 "RX dropped\n", rx_size);
269 kfree_skb(rx_skb); 266 kfree_skb(rx_skb);
270 rx_skb = NULL; 267 rx_skb = NULL;
271 goto out; /* drop it...*/ 268 goto out; /* drop it...*/
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index 768f63f38341..b799a5384abb 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -1599,7 +1599,8 @@ static void wil_probe_client_handle(struct wil6210_priv *wil,
1599 */ 1599 */
1600 bool alive = (sta->status == wil_sta_connected); 1600 bool alive = (sta->status == wil_sta_connected);
1601 1601
1602 cfg80211_probe_status(ndev, sta->addr, req->cookie, alive, GFP_KERNEL); 1602 cfg80211_probe_status(ndev, sta->addr, req->cookie, alive,
1603 0, false, GFP_KERNEL);
1603} 1604}
1604 1605
1605static struct list_head *next_probe_client(struct wil6210_priv *wil) 1606static struct list_head *next_probe_client(struct wil6210_priv *wil)
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 35b21f8152bb..100cf42db65d 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -253,7 +253,7 @@ static inline void hwsim_clear_chanctx_magic(struct ieee80211_chanctx_conf *c)
253 253
254static unsigned int hwsim_net_id; 254static unsigned int hwsim_net_id;
255 255
256static int hwsim_netgroup; 256static struct ida hwsim_netgroup_ida = IDA_INIT;
257 257
258struct hwsim_net { 258struct hwsim_net {
259 int netgroup; 259 int netgroup;
@@ -267,11 +267,13 @@ static inline int hwsim_net_get_netgroup(struct net *net)
267 return hwsim_net->netgroup; 267 return hwsim_net->netgroup;
268} 268}
269 269
270static inline void hwsim_net_set_netgroup(struct net *net) 270static inline int hwsim_net_set_netgroup(struct net *net)
271{ 271{
272 struct hwsim_net *hwsim_net = net_generic(net, hwsim_net_id); 272 struct hwsim_net *hwsim_net = net_generic(net, hwsim_net_id);
273 273
274 hwsim_net->netgroup = hwsim_netgroup++; 274 hwsim_net->netgroup = ida_simple_get(&hwsim_netgroup_ida,
275 0, 0, GFP_KERNEL);
276 return hwsim_net->netgroup >= 0 ? 0 : -ENOMEM;
275} 277}
276 278
277static inline u32 hwsim_net_get_wmediumd(struct net *net) 279static inline u32 hwsim_net_get_wmediumd(struct net *net)
@@ -493,6 +495,7 @@ static LIST_HEAD(hwsim_radios);
493static struct workqueue_struct *hwsim_wq; 495static struct workqueue_struct *hwsim_wq;
494static struct rhashtable hwsim_radios_rht; 496static struct rhashtable hwsim_radios_rht;
495static int hwsim_radio_idx; 497static int hwsim_radio_idx;
498static int hwsim_radios_generation = 1;
496 499
497static struct platform_driver mac80211_hwsim_driver = { 500static struct platform_driver mac80211_hwsim_driver = {
498 .driver = { 501 .driver = {
@@ -637,6 +640,7 @@ static const struct nla_policy hwsim_genl_policy[HWSIM_ATTR_MAX + 1] = {
637 [HWSIM_ATTR_RADIO_NAME] = { .type = NLA_STRING }, 640 [HWSIM_ATTR_RADIO_NAME] = { .type = NLA_STRING },
638 [HWSIM_ATTR_NO_VIF] = { .type = NLA_FLAG }, 641 [HWSIM_ATTR_NO_VIF] = { .type = NLA_FLAG },
639 [HWSIM_ATTR_FREQ] = { .type = NLA_U32 }, 642 [HWSIM_ATTR_FREQ] = { .type = NLA_U32 },
643 [HWSIM_ATTR_PERM_ADDR] = { .type = NLA_UNSPEC, .len = ETH_ALEN },
640}; 644};
641 645
642static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, 646static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
@@ -2408,6 +2412,7 @@ struct hwsim_new_radio_params {
2408 bool destroy_on_close; 2412 bool destroy_on_close;
2409 const char *hwname; 2413 const char *hwname;
2410 bool no_vif; 2414 bool no_vif;
2415 const u8 *perm_addr;
2411}; 2416};
2412 2417
2413static void hwsim_mcast_config_msg(struct sk_buff *mcast_skb, 2418static void hwsim_mcast_config_msg(struct sk_buff *mcast_skb,
@@ -2572,15 +2577,25 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
2572 skb_queue_head_init(&data->pending); 2577 skb_queue_head_init(&data->pending);
2573 2578
2574 SET_IEEE80211_DEV(hw, data->dev); 2579 SET_IEEE80211_DEV(hw, data->dev);
2575 eth_zero_addr(addr); 2580 if (!param->perm_addr) {
2576 addr[0] = 0x02; 2581 eth_zero_addr(addr);
2577 addr[3] = idx >> 8; 2582 addr[0] = 0x02;
2578 addr[4] = idx; 2583 addr[3] = idx >> 8;
2579 memcpy(data->addresses[0].addr, addr, ETH_ALEN); 2584 addr[4] = idx;
2580 memcpy(data->addresses[1].addr, addr, ETH_ALEN); 2585 memcpy(data->addresses[0].addr, addr, ETH_ALEN);
2581 data->addresses[1].addr[0] |= 0x40; 2586 /* Why need here second address ? */
2582 hw->wiphy->n_addresses = 2; 2587 data->addresses[1].addr[0] |= 0x40;
2583 hw->wiphy->addresses = data->addresses; 2588 memcpy(data->addresses[1].addr, addr, ETH_ALEN);
2589 hw->wiphy->n_addresses = 2;
2590 hw->wiphy->addresses = data->addresses;
2591 /* possible address clash is checked at hash table insertion */
2592 } else {
2593 memcpy(data->addresses[0].addr, param->perm_addr, ETH_ALEN);
2594 /* compatibility with automatically generated mac addr */
2595 memcpy(data->addresses[1].addr, param->perm_addr, ETH_ALEN);
2596 hw->wiphy->n_addresses = 2;
2597 hw->wiphy->addresses = data->addresses;
2598 }
2584 2599
2585 data->channels = param->channels; 2600 data->channels = param->channels;
2586 data->use_chanctx = param->use_chanctx; 2601 data->use_chanctx = param->use_chanctx;
@@ -2786,13 +2801,17 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
2786 err = rhashtable_insert_fast(&hwsim_radios_rht, &data->rht, 2801 err = rhashtable_insert_fast(&hwsim_radios_rht, &data->rht,
2787 hwsim_rht_params); 2802 hwsim_rht_params);
2788 if (err < 0) { 2803 if (err < 0) {
2789 pr_debug("mac80211_hwsim: radio index %d already present\n", 2804 if (info) {
2790 idx); 2805 GENL_SET_ERR_MSG(info, "perm addr already present");
2806 NL_SET_BAD_ATTR(info->extack,
2807 info->attrs[HWSIM_ATTR_PERM_ADDR]);
2808 }
2791 spin_unlock_bh(&hwsim_radio_lock); 2809 spin_unlock_bh(&hwsim_radio_lock);
2792 goto failed_final_insert; 2810 goto failed_final_insert;
2793 } 2811 }
2794 2812
2795 list_add_tail(&data->list, &hwsim_radios); 2813 list_add_tail(&data->list, &hwsim_radios);
2814 hwsim_radios_generation++;
2796 spin_unlock_bh(&hwsim_radio_lock); 2815 spin_unlock_bh(&hwsim_radio_lock);
2797 2816
2798 if (idx > 0) 2817 if (idx > 0)
@@ -3211,6 +3230,19 @@ static int hwsim_new_radio_nl(struct sk_buff *msg, struct genl_info *info)
3211 param.regd = hwsim_world_regdom_custom[idx]; 3230 param.regd = hwsim_world_regdom_custom[idx];
3212 } 3231 }
3213 3232
3233 if (info->attrs[HWSIM_ATTR_PERM_ADDR]) {
3234 if (!is_valid_ether_addr(
3235 nla_data(info->attrs[HWSIM_ATTR_PERM_ADDR]))) {
3236 GENL_SET_ERR_MSG(info,"MAC is no valid source addr");
3237 NL_SET_BAD_ATTR(info->extack,
3238 info->attrs[HWSIM_ATTR_PERM_ADDR]);
3239 return -EINVAL;
3240 }
3241
3242
3243 param.perm_addr = nla_data(info->attrs[HWSIM_ATTR_PERM_ADDR]);
3244 }
3245
3214 ret = mac80211_hwsim_new_radio(info, &param); 3246 ret = mac80211_hwsim_new_radio(info, &param);
3215 kfree(hwname); 3247 kfree(hwname);
3216 return ret; 3248 return ret;
@@ -3250,6 +3282,7 @@ static int hwsim_del_radio_nl(struct sk_buff *msg, struct genl_info *info)
3250 list_del(&data->list); 3282 list_del(&data->list);
3251 rhashtable_remove_fast(&hwsim_radios_rht, &data->rht, 3283 rhashtable_remove_fast(&hwsim_radios_rht, &data->rht,
3252 hwsim_rht_params); 3284 hwsim_rht_params);
3285 hwsim_radios_generation++;
3253 spin_unlock_bh(&hwsim_radio_lock); 3286 spin_unlock_bh(&hwsim_radio_lock);
3254 mac80211_hwsim_del_radio(data, wiphy_name(data->hw->wiphy), 3287 mac80211_hwsim_del_radio(data, wiphy_name(data->hw->wiphy),
3255 info); 3288 info);
@@ -3306,17 +3339,19 @@ out_err:
3306static int hwsim_dump_radio_nl(struct sk_buff *skb, 3339static int hwsim_dump_radio_nl(struct sk_buff *skb,
3307 struct netlink_callback *cb) 3340 struct netlink_callback *cb)
3308{ 3341{
3309 int idx = cb->args[0]; 3342 int last_idx = cb->args[0];
3310 struct mac80211_hwsim_data *data = NULL; 3343 struct mac80211_hwsim_data *data = NULL;
3311 int res; 3344 int res = 0;
3345 void *hdr;
3312 3346
3313 spin_lock_bh(&hwsim_radio_lock); 3347 spin_lock_bh(&hwsim_radio_lock);
3348 cb->seq = hwsim_radios_generation;
3314 3349
3315 if (idx == hwsim_radio_idx) 3350 if (last_idx >= hwsim_radio_idx-1)
3316 goto done; 3351 goto done;
3317 3352
3318 list_for_each_entry(data, &hwsim_radios, list) { 3353 list_for_each_entry(data, &hwsim_radios, list) {
3319 if (data->idx < idx) 3354 if (data->idx <= last_idx)
3320 continue; 3355 continue;
3321 3356
3322 if (!net_eq(wiphy_net(data->hw->wiphy), sock_net(skb->sk))) 3357 if (!net_eq(wiphy_net(data->hw->wiphy), sock_net(skb->sk)))
@@ -3329,14 +3364,25 @@ static int hwsim_dump_radio_nl(struct sk_buff *skb,
3329 if (res < 0) 3364 if (res < 0)
3330 break; 3365 break;
3331 3366
3332 idx = data->idx + 1; 3367 last_idx = data->idx;
3333 } 3368 }
3334 3369
3335 cb->args[0] = idx; 3370 cb->args[0] = last_idx;
3371
3372 /* list changed, but no new element sent, set interrupted flag */
3373 if (skb->len == 0 && cb->prev_seq && cb->seq != cb->prev_seq) {
3374 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
3375 cb->nlh->nlmsg_seq, &hwsim_genl_family,
3376 NLM_F_MULTI, HWSIM_CMD_GET_RADIO);
3377 if (!hdr)
3378 res = -EMSGSIZE;
3379 genl_dump_check_consistent(cb, hdr);
3380 genlmsg_end(skb, hdr);
3381 }
3336 3382
3337done: 3383done:
3338 spin_unlock_bh(&hwsim_radio_lock); 3384 spin_unlock_bh(&hwsim_radio_lock);
3339 return skb->len; 3385 return res ?: skb->len;
3340} 3386}
3341 3387
3342/* Generic Netlink operations array */ 3388/* Generic Netlink operations array */
@@ -3394,6 +3440,7 @@ static void destroy_radio(struct work_struct *work)
3394 struct mac80211_hwsim_data *data = 3440 struct mac80211_hwsim_data *data =
3395 container_of(work, struct mac80211_hwsim_data, destroy_work); 3441 container_of(work, struct mac80211_hwsim_data, destroy_work);
3396 3442
3443 hwsim_radios_generation++;
3397 mac80211_hwsim_del_radio(data, wiphy_name(data->hw->wiphy), NULL); 3444 mac80211_hwsim_del_radio(data, wiphy_name(data->hw->wiphy), NULL);
3398} 3445}
3399 3446
@@ -3463,9 +3510,7 @@ failure:
3463 3510
3464static __net_init int hwsim_init_net(struct net *net) 3511static __net_init int hwsim_init_net(struct net *net)
3465{ 3512{
3466 hwsim_net_set_netgroup(net); 3513 return hwsim_net_set_netgroup(net);
3467
3468 return 0;
3469} 3514}
3470 3515
3471static void __net_exit hwsim_exit_net(struct net *net) 3516static void __net_exit hwsim_exit_net(struct net *net)
@@ -3488,6 +3533,8 @@ static void __net_exit hwsim_exit_net(struct net *net)
3488 queue_work(hwsim_wq, &data->destroy_work); 3533 queue_work(hwsim_wq, &data->destroy_work);
3489 } 3534 }
3490 spin_unlock_bh(&hwsim_radio_lock); 3535 spin_unlock_bh(&hwsim_radio_lock);
3536
3537 ida_simple_remove(&hwsim_netgroup_ida, hwsim_net_get_netgroup(net));
3491} 3538}
3492 3539
3493static struct pernet_operations hwsim_net_ops = { 3540static struct pernet_operations hwsim_net_ops = {
@@ -3495,6 +3542,7 @@ static struct pernet_operations hwsim_net_ops = {
3495 .exit = hwsim_exit_net, 3542 .exit = hwsim_exit_net,
3496 .id = &hwsim_net_id, 3543 .id = &hwsim_net_id,
3497 .size = sizeof(struct hwsim_net), 3544 .size = sizeof(struct hwsim_net),
3545 .async = true,
3498}; 3546};
3499 3547
3500static void hwsim_exit_netlink(void) 3548static void hwsim_exit_netlink(void)
diff --git a/drivers/net/wireless/mac80211_hwsim.h b/drivers/net/wireless/mac80211_hwsim.h
index a96a79c1eff5..0fe3199f8c72 100644
--- a/drivers/net/wireless/mac80211_hwsim.h
+++ b/drivers/net/wireless/mac80211_hwsim.h
@@ -68,7 +68,12 @@ enum hwsim_tx_control_flags {
68 * %HWSIM_ATTR_SIGNAL, %HWSIM_ATTR_COOKIE 68 * %HWSIM_ATTR_SIGNAL, %HWSIM_ATTR_COOKIE
69 * @HWSIM_CMD_NEW_RADIO: create a new radio with the given parameters, 69 * @HWSIM_CMD_NEW_RADIO: create a new radio with the given parameters,
70 * returns the radio ID (>= 0) or negative on errors, if successful 70 * returns the radio ID (>= 0) or negative on errors, if successful
71 * then multicast the result 71 * then multicast the result, uses optional parameter:
72 * %HWSIM_ATTR_REG_STRICT_REG, %HWSIM_ATTR_SUPPORT_P2P_DEVICE,
73 * %HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE, %HWSIM_ATTR_CHANNELS,
74 * %HWSIM_ATTR_NO_VIF, %HWSIM_ATTR_RADIO_NAME, %HWSIM_ATTR_USE_CHANCTX,
75 * %HWSIM_ATTR_REG_HINT_ALPHA2, %HWSIM_ATTR_REG_CUSTOM_REG,
76 * %HWSIM_ATTR_PERM_ADDR
72 * @HWSIM_CMD_DEL_RADIO: destroy a radio, reply is multicasted 77 * @HWSIM_CMD_DEL_RADIO: destroy a radio, reply is multicasted
73 * @HWSIM_CMD_GET_RADIO: fetch information about existing radios, uses: 78 * @HWSIM_CMD_GET_RADIO: fetch information about existing radios, uses:
74 * %HWSIM_ATTR_RADIO_ID 79 * %HWSIM_ATTR_RADIO_ID
@@ -126,6 +131,7 @@ enum {
126 * @HWSIM_ATTR_FREQ: Frequency at which packet is transmitted or received. 131 * @HWSIM_ATTR_FREQ: Frequency at which packet is transmitted or received.
127 * @HWSIM_ATTR_TX_INFO_FLAGS: additional flags for corresponding 132 * @HWSIM_ATTR_TX_INFO_FLAGS: additional flags for corresponding
128 * rates of %HWSIM_ATTR_TX_INFO 133 * rates of %HWSIM_ATTR_TX_INFO
134 * @HWSIM_ATTR_PERM_ADDR: permanent mac address of new radio
129 * @__HWSIM_ATTR_MAX: enum limit 135 * @__HWSIM_ATTR_MAX: enum limit
130 */ 136 */
131 137
@@ -153,6 +159,7 @@ enum {
153 HWSIM_ATTR_FREQ, 159 HWSIM_ATTR_FREQ,
154 HWSIM_ATTR_PAD, 160 HWSIM_ATTR_PAD,
155 HWSIM_ATTR_TX_INFO_FLAGS, 161 HWSIM_ATTR_TX_INFO_FLAGS,
162 HWSIM_ATTR_PERM_ADDR,
156 __HWSIM_ATTR_MAX, 163 __HWSIM_ATTR_MAX,
157}; 164};
158#define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1) 165#define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1)
diff --git a/drivers/net/wireless/ti/wl1251/tx.c b/drivers/net/wireless/ti/wl1251/tx.c
index de2fa6705574..12ed14ebc307 100644
--- a/drivers/net/wireless/ti/wl1251/tx.c
+++ b/drivers/net/wireless/ti/wl1251/tx.c
@@ -221,10 +221,8 @@ static int wl1251_tx_send_packet(struct wl1251 *wl, struct sk_buff *skb,
221 struct sk_buff *newskb = skb_copy_expand(skb, 0, 3, 221 struct sk_buff *newskb = skb_copy_expand(skb, 0, 3,
222 GFP_KERNEL); 222 GFP_KERNEL);
223 223
224 if (unlikely(newskb == NULL)) { 224 if (unlikely(newskb == NULL))
225 wl1251_error("Can't allocate skb!");
226 return -EINVAL; 225 return -EINVAL;
227 }
228 226
229 tx_hdr = (struct tx_double_buffer_desc *) newskb->data; 227 tx_hdr = (struct tx_double_buffer_desc *) newskb->data;
230 228
diff --git a/drivers/net/xen-netback/rx.c b/drivers/net/xen-netback/rx.c
index b1cf7c6f407a..ef5887037b22 100644
--- a/drivers/net/xen-netback/rx.c
+++ b/drivers/net/xen-netback/rx.c
@@ -419,7 +419,7 @@ static void xenvif_rx_extra_slot(struct xenvif_queue *queue,
419 BUG(); 419 BUG();
420} 420}
421 421
422void xenvif_rx_skb(struct xenvif_queue *queue) 422static void xenvif_rx_skb(struct xenvif_queue *queue)
423{ 423{
424 struct xenvif_pkt_state pkt; 424 struct xenvif_pkt_state pkt;
425 425
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index 959c65cf75d9..4326715dc13e 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -233,8 +233,6 @@ static inline int qeth_is_ipa_enabled(struct qeth_ipa_info *ipa,
233#define QETH_IDX_FUNC_LEVEL_OSD 0x0101 233#define QETH_IDX_FUNC_LEVEL_OSD 0x0101
234#define QETH_IDX_FUNC_LEVEL_IQD 0x4108 234#define QETH_IDX_FUNC_LEVEL_IQD 0x4108
235 235
236#define QETH_REAL_CARD 1
237#define QETH_VLAN_CARD 2
238#define QETH_BUFSIZE 4096 236#define QETH_BUFSIZE 4096
239 237
240/** 238/**
@@ -556,12 +554,6 @@ enum qeth_prot_versions {
556 QETH_PROT_IPV6 = 0x0006, 554 QETH_PROT_IPV6 = 0x0006,
557}; 555};
558 556
559enum qeth_ip_types {
560 QETH_IP_TYPE_NORMAL,
561 QETH_IP_TYPE_VIPA,
562 QETH_IP_TYPE_RXIP,
563};
564
565enum qeth_cmd_buffer_state { 557enum qeth_cmd_buffer_state {
566 BUF_STATE_FREE, 558 BUF_STATE_FREE,
567 BUF_STATE_LOCKED, 559 BUF_STATE_LOCKED,
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 3653bea38470..19203340f879 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -718,11 +718,8 @@ static int qeth_check_idx_response(struct qeth_card *card,
718 718
719 QETH_DBF_HEX(CTRL, 2, buffer, QETH_DBF_CTRL_LEN); 719 QETH_DBF_HEX(CTRL, 2, buffer, QETH_DBF_CTRL_LEN);
720 if ((buffer[2] & 0xc0) == 0xc0) { 720 if ((buffer[2] & 0xc0) == 0xc0) {
721 QETH_DBF_MESSAGE(2, "received an IDX TERMINATE " 721 QETH_DBF_MESSAGE(2, "received an IDX TERMINATE with cause code %#02x\n",
722 "with cause code 0x%02x%s\n", 722 buffer[4]);
723 buffer[4],
724 ((buffer[4] == 0x22) ?
725 " -- try another portname" : ""));
726 QETH_CARD_TEXT(card, 2, "ckidxres"); 723 QETH_CARD_TEXT(card, 2, "ckidxres");
727 QETH_CARD_TEXT(card, 2, " idxterm"); 724 QETH_CARD_TEXT(card, 2, " idxterm");
728 QETH_CARD_TEXT_(card, 2, " rc%d", -EIO); 725 QETH_CARD_TEXT_(card, 2, " rc%d", -EIO);
@@ -2849,7 +2846,8 @@ static int qeth_init_input_buffer(struct qeth_card *card,
2849 int i; 2846 int i;
2850 2847
2851 if ((card->options.cq == QETH_CQ_ENABLED) && (!buf->rx_skb)) { 2848 if ((card->options.cq == QETH_CQ_ENABLED) && (!buf->rx_skb)) {
2852 buf->rx_skb = dev_alloc_skb(QETH_RX_PULL_LEN + ETH_HLEN); 2849 buf->rx_skb = netdev_alloc_skb(card->dev,
2850 QETH_RX_PULL_LEN + ETH_HLEN);
2853 if (!buf->rx_skb) 2851 if (!buf->rx_skb)
2854 return 1; 2852 return 1;
2855 } 2853 }
@@ -2886,8 +2884,8 @@ int qeth_init_qdio_queues(struct qeth_card *card)
2886 QETH_DBF_TEXT(SETUP, 2, "initqdqs"); 2884 QETH_DBF_TEXT(SETUP, 2, "initqdqs");
2887 2885
2888 /* inbound queue */ 2886 /* inbound queue */
2889 qdio_reset_buffers(card->qdio.in_q->qdio_bufs, 2887 qdio_reset_buffers(card->qdio.in_q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q);
2890 QDIO_MAX_BUFFERS_PER_Q); 2888 memset(&card->rx, 0, sizeof(struct qeth_rx));
2891 qeth_initialize_working_pool_list(card); 2889 qeth_initialize_working_pool_list(card);
2892 /*give only as many buffers to hardware as we have buffer pool entries*/ 2890 /*give only as many buffers to hardware as we have buffer pool entries*/
2893 for (i = 0; i < card->qdio.in_buf_pool.buf_count - 1; ++i) 2891 for (i = 0; i < card->qdio.in_buf_pool.buf_count - 1; ++i)
@@ -2962,12 +2960,10 @@ struct qeth_cmd_buffer *qeth_get_ipacmd_buffer(struct qeth_card *card,
2962 enum qeth_ipa_cmds ipacmd, enum qeth_prot_versions prot) 2960 enum qeth_ipa_cmds ipacmd, enum qeth_prot_versions prot)
2963{ 2961{
2964 struct qeth_cmd_buffer *iob; 2962 struct qeth_cmd_buffer *iob;
2965 struct qeth_ipa_cmd *cmd;
2966 2963
2967 iob = qeth_get_buffer(&card->write); 2964 iob = qeth_get_buffer(&card->write);
2968 if (iob) { 2965 if (iob) {
2969 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); 2966 qeth_fill_ipacmd_header(card, __ipa_cmd(iob), ipacmd, prot);
2970 qeth_fill_ipacmd_header(card, cmd, ipacmd, prot);
2971 } else { 2967 } else {
2972 dev_warn(&card->gdev->dev, 2968 dev_warn(&card->gdev->dev,
2973 "The qeth driver ran out of channel command buffers\n"); 2969 "The qeth driver ran out of channel command buffers\n");
@@ -3078,7 +3074,7 @@ static struct qeth_cmd_buffer *qeth_get_adapter_cmd(struct qeth_card *card,
3078 iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETADAPTERPARMS, 3074 iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETADAPTERPARMS,
3079 QETH_PROT_IPV4); 3075 QETH_PROT_IPV4);
3080 if (iob) { 3076 if (iob) {
3081 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); 3077 cmd = __ipa_cmd(iob);
3082 cmd->data.setadapterparms.hdr.cmdlength = cmdlen; 3078 cmd->data.setadapterparms.hdr.cmdlength = cmdlen;
3083 cmd->data.setadapterparms.hdr.command_code = command; 3079 cmd->data.setadapterparms.hdr.command_code = command;
3084 cmd->data.setadapterparms.hdr.used_total = 1; 3080 cmd->data.setadapterparms.hdr.used_total = 1;
@@ -3220,7 +3216,7 @@ static int qeth_query_setdiagass(struct qeth_card *card)
3220 iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0); 3216 iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0);
3221 if (!iob) 3217 if (!iob)
3222 return -ENOMEM; 3218 return -ENOMEM;
3223 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); 3219 cmd = __ipa_cmd(iob);
3224 cmd->data.diagass.subcmd_len = 16; 3220 cmd->data.diagass.subcmd_len = 16;
3225 cmd->data.diagass.subcmd = QETH_DIAGS_CMD_QUERY; 3221 cmd->data.diagass.subcmd = QETH_DIAGS_CMD_QUERY;
3226 return qeth_send_ipa_cmd(card, iob, qeth_query_setdiagass_cb, NULL); 3222 return qeth_send_ipa_cmd(card, iob, qeth_query_setdiagass_cb, NULL);
@@ -3273,7 +3269,7 @@ int qeth_hw_trap(struct qeth_card *card, enum qeth_diags_trap_action action)
3273 iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0); 3269 iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0);
3274 if (!iob) 3270 if (!iob)
3275 return -ENOMEM; 3271 return -ENOMEM;
3276 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); 3272 cmd = __ipa_cmd(iob);
3277 cmd->data.diagass.subcmd_len = 80; 3273 cmd->data.diagass.subcmd_len = 80;
3278 cmd->data.diagass.subcmd = QETH_DIAGS_CMD_TRAP; 3274 cmd->data.diagass.subcmd = QETH_DIAGS_CMD_TRAP;
3279 cmd->data.diagass.type = 1; 3275 cmd->data.diagass.type = 1;
@@ -4251,7 +4247,7 @@ void qeth_setadp_promisc_mode(struct qeth_card *card)
4251 sizeof(struct qeth_ipacmd_setadpparms_hdr) + 8); 4247 sizeof(struct qeth_ipacmd_setadpparms_hdr) + 8);
4252 if (!iob) 4248 if (!iob)
4253 return; 4249 return;
4254 cmd = (struct qeth_ipa_cmd *)(iob->data + IPA_PDU_HEADER_SIZE); 4250 cmd = __ipa_cmd(iob);
4255 cmd->data.setadapterparms.data.mode = mode; 4251 cmd->data.setadapterparms.data.mode = mode;
4256 qeth_send_ipa_cmd(card, iob, qeth_setadp_promisc_mode_cb, NULL); 4252 qeth_send_ipa_cmd(card, iob, qeth_setadp_promisc_mode_cb, NULL);
4257} 4253}
@@ -4318,7 +4314,7 @@ int qeth_setadpparms_change_macaddr(struct qeth_card *card)
4318 sizeof(struct qeth_change_addr)); 4314 sizeof(struct qeth_change_addr));
4319 if (!iob) 4315 if (!iob)
4320 return -ENOMEM; 4316 return -ENOMEM;
4321 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); 4317 cmd = __ipa_cmd(iob);
4322 cmd->data.setadapterparms.data.change_addr.cmd = CHANGE_ADDR_READ_MAC; 4318 cmd->data.setadapterparms.data.change_addr.cmd = CHANGE_ADDR_READ_MAC;
4323 cmd->data.setadapterparms.data.change_addr.addr_size = ETH_ALEN; 4319 cmd->data.setadapterparms.data.change_addr.addr_size = ETH_ALEN;
4324 ether_addr_copy(cmd->data.setadapterparms.data.change_addr.addr, 4320 ether_addr_copy(cmd->data.setadapterparms.data.change_addr.addr,
@@ -4433,7 +4429,7 @@ static int qeth_setadpparms_set_access_ctrl(struct qeth_card *card,
4433 sizeof(struct qeth_set_access_ctrl)); 4429 sizeof(struct qeth_set_access_ctrl));
4434 if (!iob) 4430 if (!iob)
4435 return -ENOMEM; 4431 return -ENOMEM;
4436 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); 4432 cmd = __ipa_cmd(iob);
4437 access_ctrl_req = &cmd->data.setadapterparms.data.set_access_ctrl; 4433 access_ctrl_req = &cmd->data.setadapterparms.data.set_access_ctrl;
4438 access_ctrl_req->subcmd_code = isolation; 4434 access_ctrl_req->subcmd_code = isolation;
4439 4435
@@ -4679,7 +4675,7 @@ static int qeth_snmp_command(struct qeth_card *card, char __user *udata)
4679 rc = -ENOMEM; 4675 rc = -ENOMEM;
4680 goto out; 4676 goto out;
4681 } 4677 }
4682 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); 4678 cmd = __ipa_cmd(iob);
4683 memcpy(&cmd->data.setadapterparms.data.snmp, &ureq->cmd, req_len); 4679 memcpy(&cmd->data.setadapterparms.data.snmp, &ureq->cmd, req_len);
4684 rc = qeth_send_ipa_snmp_cmd(card, iob, QETH_SETADP_BASE_LEN + req_len, 4680 rc = qeth_send_ipa_snmp_cmd(card, iob, QETH_SETADP_BASE_LEN + req_len,
4685 qeth_snmp_command_cb, (void *)&qinfo); 4681 qeth_snmp_command_cb, (void *)&qinfo);
@@ -4764,7 +4760,7 @@ static int qeth_query_oat_command(struct qeth_card *card, char __user *udata)
4764 rc = -ENOMEM; 4760 rc = -ENOMEM;
4765 goto out_free; 4761 goto out_free;
4766 } 4762 }
4767 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); 4763 cmd = __ipa_cmd(iob);
4768 oat_req = &cmd->data.setadapterparms.data.query_oat; 4764 oat_req = &cmd->data.setadapterparms.data.query_oat;
4769 oat_req->subcmd_code = oat_data.command; 4765 oat_req->subcmd_code = oat_data.command;
4770 4766
@@ -5339,7 +5335,7 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *card,
5339 } else { 5335 } else {
5340 unsigned int linear = (use_rx_sg) ? QETH_RX_PULL_LEN : skb_len; 5336 unsigned int linear = (use_rx_sg) ? QETH_RX_PULL_LEN : skb_len;
5341 5337
5342 skb = dev_alloc_skb(linear + headroom); 5338 skb = napi_alloc_skb(&card->napi, linear + headroom);
5343 } 5339 }
5344 if (!skb) 5340 if (!skb)
5345 goto no_mem; 5341 goto no_mem;
@@ -5503,7 +5499,7 @@ struct qeth_cmd_buffer *qeth_get_setassparms_cmd(struct qeth_card *card,
5503 iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETASSPARMS, prot); 5499 iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETASSPARMS, prot);
5504 5500
5505 if (iob) { 5501 if (iob) {
5506 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); 5502 cmd = __ipa_cmd(iob);
5507 cmd->data.setassparms.hdr.assist_no = ipa_func; 5503 cmd->data.setassparms.hdr.assist_no = ipa_func;
5508 cmd->data.setassparms.hdr.length = 8 + len; 5504 cmd->data.setassparms.hdr.length = 8 + len;
5509 cmd->data.setassparms.hdr.command_code = cmd_code; 5505 cmd->data.setassparms.hdr.command_code = cmd_code;
@@ -5526,7 +5522,7 @@ int qeth_send_setassparms(struct qeth_card *card,
5526 5522
5527 QETH_CARD_TEXT(card, 4, "sendassp"); 5523 QETH_CARD_TEXT(card, 4, "sendassp");
5528 5524
5529 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); 5525 cmd = __ipa_cmd(iob);
5530 if (len <= sizeof(__u32)) 5526 if (len <= sizeof(__u32))
5531 cmd->data.setassparms.data.flags_32bit = (__u32) data; 5527 cmd->data.setassparms.data.flags_32bit = (__u32) data;
5532 else /* (len > sizeof(__u32)) */ 5528 else /* (len > sizeof(__u32)) */
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 5ef4c978ad19..50a313806dde 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -108,7 +108,7 @@ static int qeth_l2_send_setdelmac(struct qeth_card *card, __u8 *mac,
108 iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4); 108 iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4);
109 if (!iob) 109 if (!iob)
110 return -ENOMEM; 110 return -ENOMEM;
111 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); 111 cmd = __ipa_cmd(iob);
112 cmd->data.setdelmac.mac_length = ETH_ALEN; 112 cmd->data.setdelmac.mac_length = ETH_ALEN;
113 ether_addr_copy(cmd->data.setdelmac.mac, mac); 113 ether_addr_copy(cmd->data.setdelmac.mac, mac);
114 return qeth_setdelmac_makerc(card, qeth_send_ipa_cmd(card, iob, 114 return qeth_setdelmac_makerc(card, qeth_send_ipa_cmd(card, iob,
@@ -305,7 +305,7 @@ static int qeth_l2_send_setdelvlan(struct qeth_card *card, __u16 i,
305 iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4); 305 iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4);
306 if (!iob) 306 if (!iob)
307 return -ENOMEM; 307 return -ENOMEM;
308 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); 308 cmd = __ipa_cmd(iob);
309 cmd->data.setdelvlan.vlan_id = i; 309 cmd->data.setdelvlan.vlan_id = i;
310 return qeth_setdelvlan_makerc(card, qeth_send_ipa_cmd(card, iob, 310 return qeth_setdelvlan_makerc(card, qeth_send_ipa_cmd(card, iob,
311 qeth_l2_send_setdelvlan_cb, NULL)); 311 qeth_l2_send_setdelvlan_cb, NULL));
@@ -437,10 +437,8 @@ static int qeth_l2_process_inbound_buffer(struct qeth_card *card,
437 *done = 1; 437 *done = 1;
438 break; 438 break;
439 } 439 }
440 skb->dev = card->dev;
441 switch (hdr->hdr.l2.id) { 440 switch (hdr->hdr.l2.id) {
442 case QETH_HEADER_TYPE_LAYER2: 441 case QETH_HEADER_TYPE_LAYER2:
443 skb->pkt_type = PACKET_HOST;
444 skb->protocol = eth_type_trans(skb, skb->dev); 442 skb->protocol = eth_type_trans(skb, skb->dev);
445 if ((card->dev->features & NETIF_F_RXCSUM) 443 if ((card->dev->features & NETIF_F_RXCSUM)
446 && ((hdr->hdr.l2.flags[1] & 444 && ((hdr->hdr.l2.flags[1] &
@@ -975,6 +973,7 @@ static int qeth_l2_setup_netdev(struct qeth_card *card)
975 return -ENODEV; 973 return -ENODEV;
976 974
977 card->dev->ml_priv = card; 975 card->dev->ml_priv = card;
976 card->dev->priv_flags |= IFF_UNICAST_FLT;
978 card->dev->watchdog_timeo = QETH_TX_TIMEOUT; 977 card->dev->watchdog_timeo = QETH_TX_TIMEOUT;
979 card->dev->mtu = card->info.initial_mtu; 978 card->dev->mtu = card->info.initial_mtu;
980 card->dev->min_mtu = 64; 979 card->dev->min_mtu = 64;
@@ -991,9 +990,16 @@ static int qeth_l2_setup_netdev(struct qeth_card *card)
991 card->dev->features |= NETIF_F_VLAN_CHALLENGED; 990 card->dev->features |= NETIF_F_VLAN_CHALLENGED;
992 else 991 else
993 card->dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER; 992 card->dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
993
994 if (card->info.type != QETH_CARD_TYPE_OSN &&
995 card->info.type != QETH_CARD_TYPE_IQD) {
996 card->dev->priv_flags &= ~IFF_TX_SKB_SHARING;
997 card->dev->needed_headroom = sizeof(struct qeth_hdr);
998 card->dev->hw_features |= NETIF_F_SG;
999 card->dev->vlan_features |= NETIF_F_SG;
1000 }
1001
994 if (card->info.type == QETH_CARD_TYPE_OSD && !card->info.guestlan) { 1002 if (card->info.type == QETH_CARD_TYPE_OSD && !card->info.guestlan) {
995 card->dev->hw_features = NETIF_F_SG;
996 card->dev->vlan_features = NETIF_F_SG;
997 card->dev->features |= NETIF_F_SG; 1003 card->dev->features |= NETIF_F_SG;
998 /* OSA 3S and earlier has no RX/TX support */ 1004 /* OSA 3S and earlier has no RX/TX support */
999 if (qeth_is_supported(card, IPA_OUTBOUND_CHECKSUM)) { 1005 if (qeth_is_supported(card, IPA_OUTBOUND_CHECKSUM)) {
@@ -1005,11 +1011,6 @@ static int qeth_l2_setup_netdev(struct qeth_card *card)
1005 card->dev->vlan_features |= NETIF_F_RXCSUM; 1011 card->dev->vlan_features |= NETIF_F_RXCSUM;
1006 } 1012 }
1007 } 1013 }
1008 if (card->info.type != QETH_CARD_TYPE_OSN &&
1009 card->info.type != QETH_CARD_TYPE_IQD) {
1010 card->dev->priv_flags &= ~IFF_TX_SKB_SHARING;
1011 card->dev->needed_headroom = sizeof(struct qeth_hdr);
1012 }
1013 1014
1014 card->info.broadcast_capable = 1; 1015 card->info.broadcast_capable = 1;
1015 qeth_l2_request_initial_mac(card); 1016 qeth_l2_request_initial_mac(card);
@@ -1086,7 +1087,6 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
1086 qeth_l2_setup_bridgeport_attrs(card); 1087 qeth_l2_setup_bridgeport_attrs(card);
1087 1088
1088 card->state = CARD_STATE_HARDSETUP; 1089 card->state = CARD_STATE_HARDSETUP;
1089 memset(&card->rx, 0, sizeof(struct qeth_rx));
1090 qeth_print_status_message(card); 1090 qeth_print_status_message(card);
1091 1091
1092 /* softsetup */ 1092 /* softsetup */
@@ -1374,7 +1374,6 @@ int qeth_osn_assist(struct net_device *dev, void *data, int data_len)
1374{ 1374{
1375 struct qeth_cmd_buffer *iob; 1375 struct qeth_cmd_buffer *iob;
1376 struct qeth_card *card; 1376 struct qeth_card *card;
1377 int rc;
1378 1377
1379 if (!dev) 1378 if (!dev)
1380 return -ENODEV; 1379 return -ENODEV;
@@ -1385,9 +1384,8 @@ int qeth_osn_assist(struct net_device *dev, void *data, int data_len)
1385 if (!qeth_card_hw_is_reachable(card)) 1384 if (!qeth_card_hw_is_reachable(card))
1386 return -ENODEV; 1385 return -ENODEV;
1387 iob = qeth_wait_for_buffer(&card->write); 1386 iob = qeth_wait_for_buffer(&card->write);
1388 memcpy(iob->data+IPA_PDU_HEADER_SIZE, data, data_len); 1387 memcpy(__ipa_cmd(iob), data, data_len);
1389 rc = qeth_osn_send_ipa_cmd(card, iob, data_len); 1388 return qeth_osn_send_ipa_cmd(card, iob, data_len);
1390 return rc;
1391} 1389}
1392EXPORT_SYMBOL(qeth_osn_assist); 1390EXPORT_SYMBOL(qeth_osn_assist);
1393 1391
@@ -1764,7 +1762,7 @@ static struct qeth_cmd_buffer *qeth_sbp_build_cmd(struct qeth_card *card,
1764 iob = qeth_get_ipacmd_buffer(card, ipa_cmd, 0); 1762 iob = qeth_get_ipacmd_buffer(card, ipa_cmd, 0);
1765 if (!iob) 1763 if (!iob)
1766 return iob; 1764 return iob;
1767 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); 1765 cmd = __ipa_cmd(iob);
1768 cmd->data.sbp.hdr.cmdlength = sizeof(struct qeth_ipacmd_sbp_hdr) + 1766 cmd->data.sbp.hdr.cmdlength = sizeof(struct qeth_ipacmd_sbp_hdr) +
1769 cmd_length; 1767 cmd_length;
1770 cmd->data.sbp.hdr.command_code = sbp_cmd; 1768 cmd->data.sbp.hdr.command_code = sbp_cmd;
@@ -2129,7 +2127,7 @@ static int qeth_l2_vnicc_request(struct qeth_card *card,
2129 return -ENOMEM; 2127 return -ENOMEM;
2130 2128
2131 /* create header for request */ 2129 /* create header for request */
2132 cmd = (struct qeth_ipa_cmd *)(iob->data + IPA_PDU_HEADER_SIZE); 2130 cmd = __ipa_cmd(iob);
2133 req = &cmd->data.vnicc; 2131 req = &cmd->data.vnicc;
2134 2132
2135 /* create sub command header for request */ 2133 /* create sub command header for request */
diff --git a/drivers/s390/net/qeth_l3.h b/drivers/s390/net/qeth_l3.h
index 498fe9af2cdb..87659cfc9066 100644
--- a/drivers/s390/net/qeth_l3.h
+++ b/drivers/s390/net/qeth_l3.h
@@ -15,21 +15,26 @@
15 15
16#define QETH_SNIFF_AVAIL 0x0008 16#define QETH_SNIFF_AVAIL 0x0008
17 17
18enum qeth_ip_types {
19 QETH_IP_TYPE_NORMAL,
20 QETH_IP_TYPE_VIPA,
21 QETH_IP_TYPE_RXIP,
22};
23
18struct qeth_ipaddr { 24struct qeth_ipaddr {
19 struct hlist_node hnode; 25 struct hlist_node hnode;
20 enum qeth_ip_types type; 26 enum qeth_ip_types type;
21 enum qeth_ipa_setdelip_flags set_flags; 27 unsigned char mac[ETH_ALEN];
22 enum qeth_ipa_setdelip_flags del_flags;
23 u8 is_multicast:1; 28 u8 is_multicast:1;
24 u8 in_progress:1; 29 u8 in_progress:1;
25 u8 disp_flag:2; 30 u8 disp_flag:2;
31 u8 ipato:1; /* ucast only */
26 32
27 /* is changed only for normal ip addresses 33 /* is changed only for normal ip addresses
28 * for non-normal addresses it always is 1 34 * for non-normal addresses it always is 1
29 */ 35 */
30 int ref_counter; 36 int ref_counter;
31 enum qeth_prot_versions proto; 37 enum qeth_prot_versions proto;
32 unsigned char mac[ETH_ALEN];
33 union { 38 union {
34 struct { 39 struct {
35 unsigned int addr; 40 unsigned int addr;
@@ -42,6 +47,16 @@ struct qeth_ipaddr {
42 } u; 47 } u;
43}; 48};
44 49
50static inline void qeth_l3_init_ipaddr(struct qeth_ipaddr *addr,
51 enum qeth_ip_types type,
52 enum qeth_prot_versions proto)
53{
54 memset(addr, 0, sizeof(*addr));
55 addr->type = type;
56 addr->proto = proto;
57 addr->disp_flag = QETH_DISP_ADDR_DO_NOTHING;
58}
59
45static inline bool qeth_l3_addr_match_ip(struct qeth_ipaddr *a1, 60static inline bool qeth_l3_addr_match_ip(struct qeth_ipaddr *a1,
46 struct qeth_ipaddr *a2) 61 struct qeth_ipaddr *a2)
47{ 62{
@@ -109,15 +124,10 @@ int qeth_l3_add_ipato_entry(struct qeth_card *, struct qeth_ipato_entry *);
109int qeth_l3_del_ipato_entry(struct qeth_card *card, 124int qeth_l3_del_ipato_entry(struct qeth_card *card,
110 enum qeth_prot_versions proto, u8 *addr, 125 enum qeth_prot_versions proto, u8 *addr,
111 int mask_bits); 126 int mask_bits);
112int qeth_l3_add_vipa(struct qeth_card *, enum qeth_prot_versions, const u8 *);
113int qeth_l3_del_vipa(struct qeth_card *card, enum qeth_prot_versions proto,
114 const u8 *addr);
115int qeth_l3_add_rxip(struct qeth_card *, enum qeth_prot_versions, const u8 *);
116int qeth_l3_del_rxip(struct qeth_card *card, enum qeth_prot_versions proto,
117 const u8 *addr);
118void qeth_l3_update_ipato(struct qeth_card *card); 127void qeth_l3_update_ipato(struct qeth_card *card);
119struct qeth_ipaddr *qeth_l3_get_addr_buffer(enum qeth_prot_versions); 128int qeth_l3_modify_hsuid(struct qeth_card *card, bool add);
120int qeth_l3_add_ip(struct qeth_card *, struct qeth_ipaddr *); 129int qeth_l3_modify_rxip_vipa(struct qeth_card *card, bool add, const u8 *ip,
121int qeth_l3_delete_ip(struct qeth_card *, struct qeth_ipaddr *); 130 enum qeth_ip_types type,
131 enum qeth_prot_versions proto);
122 132
123#endif /* __QETH_L3_H__ */ 133#endif /* __QETH_L3_H__ */
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index b6b12220da71..c1a16a74aa83 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -67,6 +67,15 @@ void qeth_l3_ipaddr_to_string(enum qeth_prot_versions proto, const __u8 *addr,
67 qeth_l3_ipaddr6_to_string(addr, buf); 67 qeth_l3_ipaddr6_to_string(addr, buf);
68} 68}
69 69
70static struct qeth_ipaddr *qeth_l3_get_addr_buffer(enum qeth_prot_versions prot)
71{
72 struct qeth_ipaddr *addr = kmalloc(sizeof(*addr), GFP_ATOMIC);
73
74 if (addr)
75 qeth_l3_init_ipaddr(addr, QETH_IP_TYPE_NORMAL, prot);
76 return addr;
77}
78
70static struct qeth_ipaddr *qeth_l3_find_addr_by_ip(struct qeth_card *card, 79static struct qeth_ipaddr *qeth_l3_find_addr_by_ip(struct qeth_card *card,
71 struct qeth_ipaddr *query) 80 struct qeth_ipaddr *query)
72{ 81{
@@ -138,12 +147,18 @@ static bool qeth_l3_is_addr_covered_by_ipato(struct qeth_card *card,
138 return rc; 147 return rc;
139} 148}
140 149
141int qeth_l3_delete_ip(struct qeth_card *card, struct qeth_ipaddr *tmp_addr) 150static int qeth_l3_delete_ip(struct qeth_card *card,
151 struct qeth_ipaddr *tmp_addr)
142{ 152{
143 int rc = 0; 153 int rc = 0;
144 struct qeth_ipaddr *addr; 154 struct qeth_ipaddr *addr;
145 155
146 QETH_CARD_TEXT(card, 4, "delip"); 156 if (tmp_addr->type == QETH_IP_TYPE_RXIP)
157 QETH_CARD_TEXT(card, 2, "delrxip");
158 else if (tmp_addr->type == QETH_IP_TYPE_VIPA)
159 QETH_CARD_TEXT(card, 2, "delvipa");
160 else
161 QETH_CARD_TEXT(card, 2, "delip");
147 162
148 if (tmp_addr->proto == QETH_PROT_IPV4) 163 if (tmp_addr->proto == QETH_PROT_IPV4)
149 QETH_CARD_HEX(card, 4, &tmp_addr->u.a4.addr, 4); 164 QETH_CARD_HEX(card, 4, &tmp_addr->u.a4.addr, 4);
@@ -171,13 +186,18 @@ int qeth_l3_delete_ip(struct qeth_card *card, struct qeth_ipaddr *tmp_addr)
171 return rc; 186 return rc;
172} 187}
173 188
174int qeth_l3_add_ip(struct qeth_card *card, struct qeth_ipaddr *tmp_addr) 189static int qeth_l3_add_ip(struct qeth_card *card, struct qeth_ipaddr *tmp_addr)
175{ 190{
176 int rc = 0; 191 int rc = 0;
177 struct qeth_ipaddr *addr; 192 struct qeth_ipaddr *addr;
178 char buf[40]; 193 char buf[40];
179 194
180 QETH_CARD_TEXT(card, 4, "addip"); 195 if (tmp_addr->type == QETH_IP_TYPE_RXIP)
196 QETH_CARD_TEXT(card, 2, "addrxip");
197 else if (tmp_addr->type == QETH_IP_TYPE_VIPA)
198 QETH_CARD_TEXT(card, 2, "addvipa");
199 else
200 QETH_CARD_TEXT(card, 2, "addip");
181 201
182 if (tmp_addr->proto == QETH_PROT_IPV4) 202 if (tmp_addr->proto == QETH_PROT_IPV4)
183 QETH_CARD_HEX(card, 4, &tmp_addr->u.a4.addr, 4); 203 QETH_CARD_HEX(card, 4, &tmp_addr->u.a4.addr, 4);
@@ -209,7 +229,7 @@ int qeth_l3_add_ip(struct qeth_card *card, struct qeth_ipaddr *tmp_addr)
209 229
210 if (qeth_l3_is_addr_covered_by_ipato(card, addr)) { 230 if (qeth_l3_is_addr_covered_by_ipato(card, addr)) {
211 QETH_CARD_TEXT(card, 2, "tkovaddr"); 231 QETH_CARD_TEXT(card, 2, "tkovaddr");
212 addr->set_flags |= QETH_IPA_SETIP_TAKEOVER_FLAG; 232 addr->ipato = 1;
213 } 233 }
214 hash_add(card->ip_htable, &addr->hnode, 234 hash_add(card->ip_htable, &addr->hnode,
215 qeth_l3_ipaddr_hash(addr)); 235 qeth_l3_ipaddr_hash(addr));
@@ -251,23 +271,6 @@ int qeth_l3_add_ip(struct qeth_card *card, struct qeth_ipaddr *tmp_addr)
251 return rc; 271 return rc;
252} 272}
253 273
254
255struct qeth_ipaddr *qeth_l3_get_addr_buffer(
256 enum qeth_prot_versions prot)
257{
258 struct qeth_ipaddr *addr;
259
260 addr = kzalloc(sizeof(struct qeth_ipaddr), GFP_ATOMIC);
261 if (!addr)
262 return NULL;
263
264 addr->type = QETH_IP_TYPE_NORMAL;
265 addr->disp_flag = QETH_DISP_ADDR_DO_NOTHING;
266 addr->proto = prot;
267
268 return addr;
269}
270
271static void qeth_l3_clear_ip_htable(struct qeth_card *card, int recover) 274static void qeth_l3_clear_ip_htable(struct qeth_card *card, int recover)
272{ 275{
273 struct qeth_ipaddr *addr; 276 struct qeth_ipaddr *addr;
@@ -352,7 +355,7 @@ static int qeth_l3_send_setdelmc(struct qeth_card *card,
352 iob = qeth_get_ipacmd_buffer(card, ipacmd, addr->proto); 355 iob = qeth_get_ipacmd_buffer(card, ipacmd, addr->proto);
353 if (!iob) 356 if (!iob)
354 return -ENOMEM; 357 return -ENOMEM;
355 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); 358 cmd = __ipa_cmd(iob);
356 ether_addr_copy(cmd->data.setdelipm.mac, addr->mac); 359 ether_addr_copy(cmd->data.setdelipm.mac, addr->mac);
357 if (addr->proto == QETH_PROT_IPV6) 360 if (addr->proto == QETH_PROT_IPV6)
358 memcpy(cmd->data.setdelipm.ip6, &addr->u.a6.addr, 361 memcpy(cmd->data.setdelipm.ip6, &addr->u.a6.addr,
@@ -379,21 +382,38 @@ static void qeth_l3_fill_netmask(u8 *netmask, unsigned int len)
379 } 382 }
380} 383}
381 384
385static u32 qeth_l3_get_setdelip_flags(struct qeth_ipaddr *addr, bool set)
386{
387 switch (addr->type) {
388 case QETH_IP_TYPE_RXIP:
389 return (set) ? QETH_IPA_SETIP_TAKEOVER_FLAG : 0;
390 case QETH_IP_TYPE_VIPA:
391 return (set) ? QETH_IPA_SETIP_VIPA_FLAG :
392 QETH_IPA_DELIP_VIPA_FLAG;
393 default:
394 return (set && addr->ipato) ? QETH_IPA_SETIP_TAKEOVER_FLAG : 0;
395 }
396}
397
382static int qeth_l3_send_setdelip(struct qeth_card *card, 398static int qeth_l3_send_setdelip(struct qeth_card *card,
383 struct qeth_ipaddr *addr, int ipacmd, unsigned int flags) 399 struct qeth_ipaddr *addr,
400 enum qeth_ipa_cmds ipacmd)
384{ 401{
385 int rc;
386 struct qeth_cmd_buffer *iob; 402 struct qeth_cmd_buffer *iob;
387 struct qeth_ipa_cmd *cmd; 403 struct qeth_ipa_cmd *cmd;
388 __u8 netmask[16]; 404 __u8 netmask[16];
405 u32 flags;
389 406
390 QETH_CARD_TEXT(card, 4, "setdelip"); 407 QETH_CARD_TEXT(card, 4, "setdelip");
391 QETH_CARD_TEXT_(card, 4, "flags%02X", flags);
392 408
393 iob = qeth_get_ipacmd_buffer(card, ipacmd, addr->proto); 409 iob = qeth_get_ipacmd_buffer(card, ipacmd, addr->proto);
394 if (!iob) 410 if (!iob)
395 return -ENOMEM; 411 return -ENOMEM;
396 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); 412 cmd = __ipa_cmd(iob);
413
414 flags = qeth_l3_get_setdelip_flags(addr, ipacmd == IPA_CMD_SETIP);
415 QETH_CARD_TEXT_(card, 4, "flags%02X", flags);
416
397 if (addr->proto == QETH_PROT_IPV6) { 417 if (addr->proto == QETH_PROT_IPV6) {
398 memcpy(cmd->data.setdelip6.ip_addr, &addr->u.a6.addr, 418 memcpy(cmd->data.setdelip6.ip_addr, &addr->u.a6.addr,
399 sizeof(struct in6_addr)); 419 sizeof(struct in6_addr));
@@ -407,9 +427,7 @@ static int qeth_l3_send_setdelip(struct qeth_card *card,
407 cmd->data.setdelip4.flags = flags; 427 cmd->data.setdelip4.flags = flags;
408 } 428 }
409 429
410 rc = qeth_send_ipa_cmd(card, iob, NULL, NULL); 430 return qeth_send_ipa_cmd(card, iob, NULL, NULL);
411
412 return rc;
413} 431}
414 432
415static int qeth_l3_send_setrouting(struct qeth_card *card, 433static int qeth_l3_send_setrouting(struct qeth_card *card,
@@ -423,7 +441,7 @@ static int qeth_l3_send_setrouting(struct qeth_card *card,
423 iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETRTG, prot); 441 iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETRTG, prot);
424 if (!iob) 442 if (!iob)
425 return -ENOMEM; 443 return -ENOMEM;
426 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); 444 cmd = __ipa_cmd(iob);
427 cmd->data.setrtg.type = (type); 445 cmd->data.setrtg.type = (type);
428 rc = qeth_send_ipa_cmd(card, iob, NULL, NULL); 446 rc = qeth_send_ipa_cmd(card, iob, NULL, NULL);
429 447
@@ -525,10 +543,7 @@ void qeth_l3_update_ipato(struct qeth_card *card)
525 hash_for_each(card->ip_htable, i, addr, hnode) { 543 hash_for_each(card->ip_htable, i, addr, hnode) {
526 if (addr->type != QETH_IP_TYPE_NORMAL) 544 if (addr->type != QETH_IP_TYPE_NORMAL)
527 continue; 545 continue;
528 if (qeth_l3_is_addr_covered_by_ipato(card, addr)) 546 addr->ipato = qeth_l3_is_addr_covered_by_ipato(card, addr);
529 addr->set_flags |= QETH_IPA_SETIP_TAKEOVER_FLAG;
530 else
531 addr->set_flags &= ~QETH_IPA_SETIP_TAKEOVER_FLAG;
532 } 547 }
533} 548}
534 549
@@ -606,132 +621,39 @@ int qeth_l3_del_ipato_entry(struct qeth_card *card,
606 return rc; 621 return rc;
607} 622}
608 623
609/* 624int qeth_l3_modify_rxip_vipa(struct qeth_card *card, bool add, const u8 *ip,
610 * VIPA related functions 625 enum qeth_ip_types type,
611 */ 626 enum qeth_prot_versions proto)
612int qeth_l3_add_vipa(struct qeth_card *card, enum qeth_prot_versions proto,
613 const u8 *addr)
614{
615 struct qeth_ipaddr *ipaddr;
616 int rc;
617
618 ipaddr = qeth_l3_get_addr_buffer(proto);
619 if (ipaddr) {
620 if (proto == QETH_PROT_IPV4) {
621 QETH_CARD_TEXT(card, 2, "addvipa4");
622 memcpy(&ipaddr->u.a4.addr, addr, 4);
623 ipaddr->u.a4.mask = 0;
624 } else if (proto == QETH_PROT_IPV6) {
625 QETH_CARD_TEXT(card, 2, "addvipa6");
626 memcpy(&ipaddr->u.a6.addr, addr, 16);
627 ipaddr->u.a6.pfxlen = 0;
628 }
629 ipaddr->type = QETH_IP_TYPE_VIPA;
630 ipaddr->set_flags = QETH_IPA_SETIP_VIPA_FLAG;
631 ipaddr->del_flags = QETH_IPA_DELIP_VIPA_FLAG;
632 } else
633 return -ENOMEM;
634
635 spin_lock_bh(&card->ip_lock);
636 rc = qeth_l3_add_ip(card, ipaddr);
637 spin_unlock_bh(&card->ip_lock);
638
639 kfree(ipaddr);
640
641 return rc;
642}
643
644int qeth_l3_del_vipa(struct qeth_card *card, enum qeth_prot_versions proto,
645 const u8 *addr)
646{
647 struct qeth_ipaddr *ipaddr;
648 int rc;
649
650 ipaddr = qeth_l3_get_addr_buffer(proto);
651 if (ipaddr) {
652 if (proto == QETH_PROT_IPV4) {
653 QETH_CARD_TEXT(card, 2, "delvipa4");
654 memcpy(&ipaddr->u.a4.addr, addr, 4);
655 ipaddr->u.a4.mask = 0;
656 } else if (proto == QETH_PROT_IPV6) {
657 QETH_CARD_TEXT(card, 2, "delvipa6");
658 memcpy(&ipaddr->u.a6.addr, addr, 16);
659 ipaddr->u.a6.pfxlen = 0;
660 }
661 ipaddr->type = QETH_IP_TYPE_VIPA;
662 } else
663 return -ENOMEM;
664
665 spin_lock_bh(&card->ip_lock);
666 rc = qeth_l3_delete_ip(card, ipaddr);
667 spin_unlock_bh(&card->ip_lock);
668
669 kfree(ipaddr);
670 return rc;
671}
672
673/*
674 * proxy ARP related functions
675 */
676int qeth_l3_add_rxip(struct qeth_card *card, enum qeth_prot_versions proto,
677 const u8 *addr)
678{ 627{
679 struct qeth_ipaddr *ipaddr; 628 struct qeth_ipaddr addr;
680 int rc; 629 int rc;
681 630
682 ipaddr = qeth_l3_get_addr_buffer(proto); 631 qeth_l3_init_ipaddr(&addr, type, proto);
683 if (ipaddr) { 632 if (proto == QETH_PROT_IPV4)
684 if (proto == QETH_PROT_IPV4) { 633 memcpy(&addr.u.a4.addr, ip, 4);
685 QETH_CARD_TEXT(card, 2, "addrxip4"); 634 else
686 memcpy(&ipaddr->u.a4.addr, addr, 4); 635 memcpy(&addr.u.a6.addr, ip, 16);
687 ipaddr->u.a4.mask = 0;
688 } else if (proto == QETH_PROT_IPV6) {
689 QETH_CARD_TEXT(card, 2, "addrxip6");
690 memcpy(&ipaddr->u.a6.addr, addr, 16);
691 ipaddr->u.a6.pfxlen = 0;
692 }
693
694 ipaddr->type = QETH_IP_TYPE_RXIP;
695 ipaddr->set_flags = QETH_IPA_SETIP_TAKEOVER_FLAG;
696 ipaddr->del_flags = 0;
697 } else
698 return -ENOMEM;
699 636
700 spin_lock_bh(&card->ip_lock); 637 spin_lock_bh(&card->ip_lock);
701 rc = qeth_l3_add_ip(card, ipaddr); 638 rc = add ? qeth_l3_add_ip(card, &addr) : qeth_l3_delete_ip(card, &addr);
702 spin_unlock_bh(&card->ip_lock); 639 spin_unlock_bh(&card->ip_lock);
703
704 kfree(ipaddr);
705
706 return rc; 640 return rc;
707} 641}
708 642
709int qeth_l3_del_rxip(struct qeth_card *card, enum qeth_prot_versions proto, 643int qeth_l3_modify_hsuid(struct qeth_card *card, bool add)
710 const u8 *addr)
711{ 644{
712 struct qeth_ipaddr *ipaddr; 645 struct qeth_ipaddr addr;
713 int rc; 646 int rc, i;
714 647
715 ipaddr = qeth_l3_get_addr_buffer(proto); 648 qeth_l3_init_ipaddr(&addr, QETH_IP_TYPE_NORMAL, QETH_PROT_IPV6);
716 if (ipaddr) { 649 addr.u.a6.addr.s6_addr[0] = 0xfe;
717 if (proto == QETH_PROT_IPV4) { 650 addr.u.a6.addr.s6_addr[1] = 0x80;
718 QETH_CARD_TEXT(card, 2, "delrxip4"); 651 for (i = 0; i < 8; i++)
719 memcpy(&ipaddr->u.a4.addr, addr, 4); 652 addr.u.a6.addr.s6_addr[8+i] = card->options.hsuid[i];
720 ipaddr->u.a4.mask = 0;
721 } else if (proto == QETH_PROT_IPV6) {
722 QETH_CARD_TEXT(card, 2, "delrxip6");
723 memcpy(&ipaddr->u.a6.addr, addr, 16);
724 ipaddr->u.a6.pfxlen = 0;
725 }
726 ipaddr->type = QETH_IP_TYPE_RXIP;
727 } else
728 return -ENOMEM;
729 653
730 spin_lock_bh(&card->ip_lock); 654 spin_lock_bh(&card->ip_lock);
731 rc = qeth_l3_delete_ip(card, ipaddr); 655 rc = add ? qeth_l3_add_ip(card, &addr) : qeth_l3_delete_ip(card, &addr);
732 spin_unlock_bh(&card->ip_lock); 656 spin_unlock_bh(&card->ip_lock);
733
734 kfree(ipaddr);
735 return rc; 657 return rc;
736} 658}
737 659
@@ -758,8 +680,7 @@ static int qeth_l3_register_addr_entry(struct qeth_card *card,
758 if (addr->is_multicast) 680 if (addr->is_multicast)
759 rc = qeth_l3_send_setdelmc(card, addr, IPA_CMD_SETIPM); 681 rc = qeth_l3_send_setdelmc(card, addr, IPA_CMD_SETIPM);
760 else 682 else
761 rc = qeth_l3_send_setdelip(card, addr, IPA_CMD_SETIP, 683 rc = qeth_l3_send_setdelip(card, addr, IPA_CMD_SETIP);
762 addr->set_flags);
763 if (rc) 684 if (rc)
764 QETH_CARD_TEXT(card, 2, "failed"); 685 QETH_CARD_TEXT(card, 2, "failed");
765 } while ((--cnt > 0) && rc); 686 } while ((--cnt > 0) && rc);
@@ -791,8 +712,7 @@ static int qeth_l3_deregister_addr_entry(struct qeth_card *card,
791 if (addr->is_multicast) 712 if (addr->is_multicast)
792 rc = qeth_l3_send_setdelmc(card, addr, IPA_CMD_DELIPM); 713 rc = qeth_l3_send_setdelmc(card, addr, IPA_CMD_DELIPM);
793 else 714 else
794 rc = qeth_l3_send_setdelip(card, addr, IPA_CMD_DELIP, 715 rc = qeth_l3_send_setdelip(card, addr, IPA_CMD_DELIP);
795 addr->del_flags);
796 if (rc) 716 if (rc)
797 QETH_CARD_TEXT(card, 2, "failed"); 717 QETH_CARD_TEXT(card, 2, "failed");
798 718
@@ -1072,7 +992,7 @@ static int qeth_l3_iqd_read_initial_mac(struct qeth_card *card)
1072 QETH_PROT_IPV6); 992 QETH_PROT_IPV6);
1073 if (!iob) 993 if (!iob)
1074 return -ENOMEM; 994 return -ENOMEM;
1075 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); 995 cmd = __ipa_cmd(iob);
1076 *((__u16 *) &cmd->data.create_destroy_addr.unique_id[6]) = 996 *((__u16 *) &cmd->data.create_destroy_addr.unique_id[6]) =
1077 card->info.unique_id; 997 card->info.unique_id;
1078 998
@@ -1117,7 +1037,7 @@ static int qeth_l3_get_unique_id(struct qeth_card *card)
1117 QETH_PROT_IPV6); 1037 QETH_PROT_IPV6);
1118 if (!iob) 1038 if (!iob)
1119 return -ENOMEM; 1039 return -ENOMEM;
1120 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); 1040 cmd = __ipa_cmd(iob);
1121 *((__u16 *) &cmd->data.create_destroy_addr.unique_id[6]) = 1041 *((__u16 *) &cmd->data.create_destroy_addr.unique_id[6]) =
1122 card->info.unique_id; 1042 card->info.unique_id;
1123 1043
@@ -1193,7 +1113,7 @@ qeth_diags_trace(struct qeth_card *card, enum qeth_diags_trace_cmds diags_cmd)
1193 iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0); 1113 iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0);
1194 if (!iob) 1114 if (!iob)
1195 return -ENOMEM; 1115 return -ENOMEM;
1196 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); 1116 cmd = __ipa_cmd(iob);
1197 cmd->data.diagass.subcmd_len = 16; 1117 cmd->data.diagass.subcmd_len = 16;
1198 cmd->data.diagass.subcmd = QETH_DIAGS_CMD_TRACE; 1118 cmd->data.diagass.subcmd = QETH_DIAGS_CMD_TRACE;
1199 cmd->data.diagass.type = QETH_DIAGS_TYPE_HIPERSOCKET; 1119 cmd->data.diagass.type = QETH_DIAGS_TYPE_HIPERSOCKET;
@@ -1502,30 +1422,24 @@ static void qeth_l3_rebuild_skb(struct qeth_card *card, struct sk_buff *skb,
1502 ipv6_eth_mc_map(&ipv6_hdr(skb)->daddr, tg_addr); 1422 ipv6_eth_mc_map(&ipv6_hdr(skb)->daddr, tg_addr);
1503 1423
1504 card->stats.multicast++; 1424 card->stats.multicast++;
1505 skb->pkt_type = PACKET_MULTICAST;
1506 break; 1425 break;
1507 case QETH_CAST_BROADCAST: 1426 case QETH_CAST_BROADCAST:
1508 ether_addr_copy(tg_addr, card->dev->broadcast); 1427 ether_addr_copy(tg_addr, card->dev->broadcast);
1509 card->stats.multicast++; 1428 card->stats.multicast++;
1510 skb->pkt_type = PACKET_BROADCAST;
1511 break; 1429 break;
1512 case QETH_CAST_UNICAST:
1513 case QETH_CAST_ANYCAST:
1514 case QETH_CAST_NOCAST:
1515 default: 1430 default:
1516 if (card->options.sniffer) 1431 if (card->options.sniffer)
1517 skb->pkt_type = PACKET_OTHERHOST; 1432 skb->pkt_type = PACKET_OTHERHOST;
1518 else
1519 skb->pkt_type = PACKET_HOST;
1520 ether_addr_copy(tg_addr, card->dev->dev_addr); 1433 ether_addr_copy(tg_addr, card->dev->dev_addr);
1521 } 1434 }
1435
1522 if (hdr->hdr.l3.ext_flags & QETH_HDR_EXT_SRC_MAC_ADDR) 1436 if (hdr->hdr.l3.ext_flags & QETH_HDR_EXT_SRC_MAC_ADDR)
1523 card->dev->header_ops->create(skb, card->dev, prot, 1437 card->dev->header_ops->create(skb, card->dev, prot,
1524 tg_addr, &hdr->hdr.l3.next_hop.rx.src_mac, 1438 tg_addr, &hdr->hdr.l3.next_hop.rx.src_mac,
1525 card->dev->addr_len); 1439 skb->len);
1526 else 1440 else
1527 card->dev->header_ops->create(skb, card->dev, prot, 1441 card->dev->header_ops->create(skb, card->dev, prot,
1528 tg_addr, "FAKELL", card->dev->addr_len); 1442 tg_addr, "FAKELL", skb->len);
1529 } 1443 }
1530 1444
1531 skb->protocol = eth_type_trans(skb, card->dev); 1445 skb->protocol = eth_type_trans(skb, card->dev);
@@ -1572,20 +1486,16 @@ static int qeth_l3_process_inbound_buffer(struct qeth_card *card,
1572 *done = 1; 1486 *done = 1;
1573 break; 1487 break;
1574 } 1488 }
1575 skb->dev = card->dev;
1576 switch (hdr->hdr.l3.id) { 1489 switch (hdr->hdr.l3.id) {
1577 case QETH_HEADER_TYPE_LAYER3: 1490 case QETH_HEADER_TYPE_LAYER3:
1578 magic = *(__u16 *)skb->data; 1491 magic = *(__u16 *)skb->data;
1579 if ((card->info.type == QETH_CARD_TYPE_IQD) && 1492 if ((card->info.type == QETH_CARD_TYPE_IQD) &&
1580 (magic == ETH_P_AF_IUCV)) { 1493 (magic == ETH_P_AF_IUCV)) {
1581 skb->protocol = cpu_to_be16(ETH_P_AF_IUCV); 1494 skb->protocol = cpu_to_be16(ETH_P_AF_IUCV);
1582 skb->pkt_type = PACKET_HOST;
1583 skb->mac_header = NET_SKB_PAD;
1584 skb->dev = card->dev;
1585 len = skb->len; 1495 len = skb->len;
1586 card->dev->header_ops->create(skb, card->dev, 0, 1496 card->dev->header_ops->create(skb, card->dev, 0,
1587 card->dev->dev_addr, "FAKELL", 1497 card->dev->dev_addr, "FAKELL", len);
1588 card->dev->addr_len); 1498 skb_reset_mac_header(skb);
1589 netif_receive_skb(skb); 1499 netif_receive_skb(skb);
1590 } else { 1500 } else {
1591 qeth_l3_rebuild_skb(card, skb, hdr); 1501 qeth_l3_rebuild_skb(card, skb, hdr);
@@ -1594,7 +1504,6 @@ static int qeth_l3_process_inbound_buffer(struct qeth_card *card,
1594 } 1504 }
1595 break; 1505 break;
1596 case QETH_HEADER_TYPE_LAYER2: /* for HiperSockets sniffer */ 1506 case QETH_HEADER_TYPE_LAYER2: /* for HiperSockets sniffer */
1597 skb->pkt_type = PACKET_HOST;
1598 skb->protocol = eth_type_trans(skb, skb->dev); 1507 skb->protocol = eth_type_trans(skb, skb->dev);
1599 len = skb->len; 1508 len = skb->len;
1600 netif_receive_skb(skb); 1509 netif_receive_skb(skb);
@@ -1613,69 +1522,6 @@ static int qeth_l3_process_inbound_buffer(struct qeth_card *card,
1613 return work_done; 1522 return work_done;
1614} 1523}
1615 1524
1616static int qeth_l3_verify_vlan_dev(struct net_device *dev,
1617 struct qeth_card *card)
1618{
1619 int rc = 0;
1620 u16 vid;
1621
1622 for_each_set_bit(vid, card->active_vlans, VLAN_N_VID) {
1623 struct net_device *netdev;
1624
1625 rcu_read_lock();
1626 netdev = __vlan_find_dev_deep_rcu(card->dev, htons(ETH_P_8021Q),
1627 vid);
1628 rcu_read_unlock();
1629 if (netdev == dev) {
1630 rc = QETH_VLAN_CARD;
1631 break;
1632 }
1633 }
1634
1635 if (rc && !(vlan_dev_real_dev(dev)->ml_priv == (void *)card))
1636 return 0;
1637
1638 return rc;
1639}
1640
1641static int qeth_l3_verify_dev(struct net_device *dev)
1642{
1643 struct qeth_card *card;
1644 int rc = 0;
1645 unsigned long flags;
1646
1647 read_lock_irqsave(&qeth_core_card_list.rwlock, flags);
1648 list_for_each_entry(card, &qeth_core_card_list.list, list) {
1649 if (card->dev == dev) {
1650 rc = QETH_REAL_CARD;
1651 break;
1652 }
1653 rc = qeth_l3_verify_vlan_dev(dev, card);
1654 if (rc)
1655 break;
1656 }
1657 read_unlock_irqrestore(&qeth_core_card_list.rwlock, flags);
1658
1659 return rc;
1660}
1661
1662static struct qeth_card *qeth_l3_get_card_from_dev(struct net_device *dev)
1663{
1664 struct qeth_card *card = NULL;
1665 int rc;
1666
1667 rc = qeth_l3_verify_dev(dev);
1668 if (rc == QETH_REAL_CARD)
1669 card = dev->ml_priv;
1670 else if (rc == QETH_VLAN_CARD)
1671 card = vlan_dev_real_dev(dev)->ml_priv;
1672 if (card && card->options.layer2)
1673 card = NULL;
1674 if (card)
1675 QETH_CARD_TEXT_(card, 4, "%d", rc);
1676 return card ;
1677}
1678
1679static void qeth_l3_stop_card(struct qeth_card *card, int recovery_mode) 1525static void qeth_l3_stop_card(struct qeth_card *card, int recovery_mode)
1680{ 1526{
1681 QETH_DBF_TEXT(SETUP, 2, "stopcard"); 1527 QETH_DBF_TEXT(SETUP, 2, "stopcard");
@@ -2004,7 +1850,7 @@ static int qeth_l3_query_arp_cache_info(struct qeth_card *card,
2004 prot); 1850 prot);
2005 if (!iob) 1851 if (!iob)
2006 return -ENOMEM; 1852 return -ENOMEM;
2007 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); 1853 cmd = __ipa_cmd(iob);
2008 cmd->data.setassparms.data.query_arp.request_bits = 0x000F; 1854 cmd->data.setassparms.data.query_arp.request_bits = 0x000F;
2009 cmd->data.setassparms.data.query_arp.reply_bits = 0; 1855 cmd->data.setassparms.data.query_arp.reply_bits = 0;
2010 cmd->data.setassparms.data.query_arp.no_entries = 0; 1856 cmd->data.setassparms.data.query_arp.no_entries = 0;
@@ -2785,14 +2631,16 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
2785 if (!(card->info.unique_id & UNIQUE_ID_NOT_BY_CARD)) 2631 if (!(card->info.unique_id & UNIQUE_ID_NOT_BY_CARD))
2786 card->dev->dev_id = card->info.unique_id & 2632 card->dev->dev_id = card->info.unique_id &
2787 0xffff; 2633 0xffff;
2634
2635 card->dev->hw_features |= NETIF_F_SG;
2636 card->dev->vlan_features |= NETIF_F_SG;
2637
2788 if (!card->info.guestlan) { 2638 if (!card->info.guestlan) {
2789 card->dev->hw_features = NETIF_F_SG |
2790 NETIF_F_RXCSUM | NETIF_F_IP_CSUM |
2791 NETIF_F_TSO;
2792 card->dev->vlan_features = NETIF_F_SG |
2793 NETIF_F_RXCSUM | NETIF_F_IP_CSUM |
2794 NETIF_F_TSO;
2795 card->dev->features |= NETIF_F_SG; 2639 card->dev->features |= NETIF_F_SG;
2640 card->dev->hw_features |= NETIF_F_TSO |
2641 NETIF_F_RXCSUM | NETIF_F_IP_CSUM;
2642 card->dev->vlan_features |= NETIF_F_TSO |
2643 NETIF_F_RXCSUM | NETIF_F_IP_CSUM;
2796 } 2644 }
2797 } 2645 }
2798 } else if (card->info.type == QETH_CARD_TYPE_IQD) { 2646 } else if (card->info.type == QETH_CARD_TYPE_IQD) {
@@ -2907,7 +2755,6 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
2907 card->info.hwtrap = 0; 2755 card->info.hwtrap = 0;
2908 2756
2909 card->state = CARD_STATE_HARDSETUP; 2757 card->state = CARD_STATE_HARDSETUP;
2910 memset(&card->rx, 0, sizeof(struct qeth_rx));
2911 qeth_print_status_message(card); 2758 qeth_print_status_message(card);
2912 2759
2913 /* softsetup */ 2760 /* softsetup */
@@ -3130,13 +2977,43 @@ struct qeth_discipline qeth_l3_discipline = {
3130}; 2977};
3131EXPORT_SYMBOL_GPL(qeth_l3_discipline); 2978EXPORT_SYMBOL_GPL(qeth_l3_discipline);
3132 2979
2980static int qeth_l3_handle_ip_event(struct qeth_card *card,
2981 struct qeth_ipaddr *addr,
2982 unsigned long event)
2983{
2984 switch (event) {
2985 case NETDEV_UP:
2986 spin_lock_bh(&card->ip_lock);
2987 qeth_l3_add_ip(card, addr);
2988 spin_unlock_bh(&card->ip_lock);
2989 return NOTIFY_OK;
2990 case NETDEV_DOWN:
2991 spin_lock_bh(&card->ip_lock);
2992 qeth_l3_delete_ip(card, addr);
2993 spin_unlock_bh(&card->ip_lock);
2994 return NOTIFY_OK;
2995 default:
2996 return NOTIFY_DONE;
2997 }
2998}
2999
3000static struct qeth_card *qeth_l3_get_card_from_dev(struct net_device *dev)
3001{
3002 if (is_vlan_dev(dev))
3003 dev = vlan_dev_real_dev(dev);
3004 if (dev->netdev_ops == &qeth_l3_osa_netdev_ops ||
3005 dev->netdev_ops == &qeth_l3_netdev_ops)
3006 return (struct qeth_card *) dev->ml_priv;
3007 return NULL;
3008}
3009
3133static int qeth_l3_ip_event(struct notifier_block *this, 3010static int qeth_l3_ip_event(struct notifier_block *this,
3134 unsigned long event, void *ptr) 3011 unsigned long event, void *ptr)
3135{ 3012{
3136 3013
3137 struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; 3014 struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
3138 struct net_device *dev = (struct net_device *)ifa->ifa_dev->dev; 3015 struct net_device *dev = ifa->ifa_dev->dev;
3139 struct qeth_ipaddr *addr; 3016 struct qeth_ipaddr addr;
3140 struct qeth_card *card; 3017 struct qeth_card *card;
3141 3018
3142 if (dev_net(dev) != &init_net) 3019 if (dev_net(dev) != &init_net)
@@ -3147,29 +3024,11 @@ static int qeth_l3_ip_event(struct notifier_block *this,
3147 return NOTIFY_DONE; 3024 return NOTIFY_DONE;
3148 QETH_CARD_TEXT(card, 3, "ipevent"); 3025 QETH_CARD_TEXT(card, 3, "ipevent");
3149 3026
3150 addr = qeth_l3_get_addr_buffer(QETH_PROT_IPV4); 3027 qeth_l3_init_ipaddr(&addr, QETH_IP_TYPE_NORMAL, QETH_PROT_IPV4);
3151 if (addr) { 3028 addr.u.a4.addr = be32_to_cpu(ifa->ifa_address);
3152 addr->u.a4.addr = be32_to_cpu(ifa->ifa_address); 3029 addr.u.a4.mask = be32_to_cpu(ifa->ifa_mask);
3153 addr->u.a4.mask = be32_to_cpu(ifa->ifa_mask);
3154 addr->type = QETH_IP_TYPE_NORMAL;
3155 } else
3156 return NOTIFY_DONE;
3157
3158 switch (event) {
3159 case NETDEV_UP:
3160 spin_lock_bh(&card->ip_lock);
3161 qeth_l3_add_ip(card, addr);
3162 spin_unlock_bh(&card->ip_lock);
3163 break;
3164 case NETDEV_DOWN:
3165 spin_lock_bh(&card->ip_lock);
3166 qeth_l3_delete_ip(card, addr);
3167 spin_unlock_bh(&card->ip_lock);
3168 break;
3169 }
3170 3030
3171 kfree(addr); 3031 return qeth_l3_handle_ip_event(card, &addr, event);
3172 return NOTIFY_DONE;
3173} 3032}
3174 3033
3175static struct notifier_block qeth_l3_ip_notifier = { 3034static struct notifier_block qeth_l3_ip_notifier = {
@@ -3181,8 +3040,8 @@ static int qeth_l3_ip6_event(struct notifier_block *this,
3181 unsigned long event, void *ptr) 3040 unsigned long event, void *ptr)
3182{ 3041{
3183 struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr; 3042 struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr;
3184 struct net_device *dev = (struct net_device *)ifa->idev->dev; 3043 struct net_device *dev = ifa->idev->dev;
3185 struct qeth_ipaddr *addr; 3044 struct qeth_ipaddr addr;
3186 struct qeth_card *card; 3045 struct qeth_card *card;
3187 3046
3188 card = qeth_l3_get_card_from_dev(dev); 3047 card = qeth_l3_get_card_from_dev(dev);
@@ -3192,29 +3051,11 @@ static int qeth_l3_ip6_event(struct notifier_block *this,
3192 if (!qeth_is_supported(card, IPA_IPV6)) 3051 if (!qeth_is_supported(card, IPA_IPV6))
3193 return NOTIFY_DONE; 3052 return NOTIFY_DONE;
3194 3053
3195 addr = qeth_l3_get_addr_buffer(QETH_PROT_IPV6); 3054 qeth_l3_init_ipaddr(&addr, QETH_IP_TYPE_NORMAL, QETH_PROT_IPV6);
3196 if (addr) { 3055 addr.u.a6.addr = ifa->addr;
3197 memcpy(&addr->u.a6.addr, &ifa->addr, sizeof(struct in6_addr)); 3056 addr.u.a6.pfxlen = ifa->prefix_len;
3198 addr->u.a6.pfxlen = ifa->prefix_len;
3199 addr->type = QETH_IP_TYPE_NORMAL;
3200 } else
3201 return NOTIFY_DONE;
3202
3203 switch (event) {
3204 case NETDEV_UP:
3205 spin_lock_bh(&card->ip_lock);
3206 qeth_l3_add_ip(card, addr);
3207 spin_unlock_bh(&card->ip_lock);
3208 break;
3209 case NETDEV_DOWN:
3210 spin_lock_bh(&card->ip_lock);
3211 qeth_l3_delete_ip(card, addr);
3212 spin_unlock_bh(&card->ip_lock);
3213 break;
3214 }
3215 3057
3216 kfree(addr); 3058 return qeth_l3_handle_ip_event(card, &addr, event);
3217 return NOTIFY_DONE;
3218} 3059}
3219 3060
3220static struct notifier_block qeth_l3_ip6_notifier = { 3061static struct notifier_block qeth_l3_ip6_notifier = {
diff --git a/drivers/s390/net/qeth_l3_sys.c b/drivers/s390/net/qeth_l3_sys.c
index a645cfe66ddf..f61192a048f4 100644
--- a/drivers/s390/net/qeth_l3_sys.c
+++ b/drivers/s390/net/qeth_l3_sys.c
@@ -272,9 +272,8 @@ static ssize_t qeth_l3_dev_hsuid_store(struct device *dev,
272 struct device_attribute *attr, const char *buf, size_t count) 272 struct device_attribute *attr, const char *buf, size_t count)
273{ 273{
274 struct qeth_card *card = dev_get_drvdata(dev); 274 struct qeth_card *card = dev_get_drvdata(dev);
275 struct qeth_ipaddr *addr;
276 char *tmp; 275 char *tmp;
277 int rc, i; 276 int rc;
278 277
279 if (!card) 278 if (!card)
280 return -EINVAL; 279 return -EINVAL;
@@ -293,25 +292,9 @@ static ssize_t qeth_l3_dev_hsuid_store(struct device *dev,
293 if (strlen(tmp) > 8) 292 if (strlen(tmp) > 8)
294 return -EINVAL; 293 return -EINVAL;
295 294
296 if (card->options.hsuid[0]) { 295 if (card->options.hsuid[0])
297 /* delete old ip address */ 296 /* delete old ip address */
298 addr = qeth_l3_get_addr_buffer(QETH_PROT_IPV6); 297 qeth_l3_modify_hsuid(card, false);
299 if (!addr)
300 return -ENOMEM;
301
302 addr->u.a6.addr.s6_addr32[0] = cpu_to_be32(0xfe800000);
303 addr->u.a6.addr.s6_addr32[1] = 0x00000000;
304 for (i = 8; i < 16; i++)
305 addr->u.a6.addr.s6_addr[i] =
306 card->options.hsuid[i - 8];
307 addr->u.a6.pfxlen = 0;
308 addr->type = QETH_IP_TYPE_NORMAL;
309
310 spin_lock_bh(&card->ip_lock);
311 qeth_l3_delete_ip(card, addr);
312 spin_unlock_bh(&card->ip_lock);
313 kfree(addr);
314 }
315 298
316 if (strlen(tmp) == 0) { 299 if (strlen(tmp) == 0) {
317 /* delete ip address only */ 300 /* delete ip address only */
@@ -331,21 +314,7 @@ static ssize_t qeth_l3_dev_hsuid_store(struct device *dev,
331 if (card->dev) 314 if (card->dev)
332 memcpy(card->dev->perm_addr, card->options.hsuid, 9); 315 memcpy(card->dev->perm_addr, card->options.hsuid, 9);
333 316
334 addr = qeth_l3_get_addr_buffer(QETH_PROT_IPV6); 317 rc = qeth_l3_modify_hsuid(card, true);
335 if (addr != NULL) {
336 addr->u.a6.addr.s6_addr32[0] = cpu_to_be32(0xfe800000);
337 addr->u.a6.addr.s6_addr32[1] = 0x00000000;
338 for (i = 8; i < 16; i++)
339 addr->u.a6.addr.s6_addr[i] = card->options.hsuid[i - 8];
340 addr->u.a6.pfxlen = 0;
341 addr->type = QETH_IP_TYPE_NORMAL;
342 } else
343 return -ENOMEM;
344
345 spin_lock_bh(&card->ip_lock);
346 rc = qeth_l3_add_ip(card, addr);
347 spin_unlock_bh(&card->ip_lock);
348 kfree(addr);
349 318
350 return rc ? rc : count; 319 return rc ? rc : count;
351} 320}
@@ -767,7 +736,8 @@ static ssize_t qeth_l3_dev_vipa_add_store(const char *buf, size_t count,
767 mutex_lock(&card->conf_mutex); 736 mutex_lock(&card->conf_mutex);
768 rc = qeth_l3_parse_vipae(buf, proto, addr); 737 rc = qeth_l3_parse_vipae(buf, proto, addr);
769 if (!rc) 738 if (!rc)
770 rc = qeth_l3_add_vipa(card, proto, addr); 739 rc = qeth_l3_modify_rxip_vipa(card, true, addr,
740 QETH_IP_TYPE_VIPA, proto);
771 mutex_unlock(&card->conf_mutex); 741 mutex_unlock(&card->conf_mutex);
772 return rc ? rc : count; 742 return rc ? rc : count;
773} 743}
@@ -796,7 +766,8 @@ static ssize_t qeth_l3_dev_vipa_del_store(const char *buf, size_t count,
796 mutex_lock(&card->conf_mutex); 766 mutex_lock(&card->conf_mutex);
797 rc = qeth_l3_parse_vipae(buf, proto, addr); 767 rc = qeth_l3_parse_vipae(buf, proto, addr);
798 if (!rc) 768 if (!rc)
799 rc = qeth_l3_del_vipa(card, proto, addr); 769 rc = qeth_l3_modify_rxip_vipa(card, false, addr,
770 QETH_IP_TYPE_VIPA, proto);
800 mutex_unlock(&card->conf_mutex); 771 mutex_unlock(&card->conf_mutex);
801 return rc ? rc : count; 772 return rc ? rc : count;
802} 773}
@@ -908,7 +879,8 @@ static ssize_t qeth_l3_dev_rxip_add_store(const char *buf, size_t count,
908 mutex_lock(&card->conf_mutex); 879 mutex_lock(&card->conf_mutex);
909 rc = qeth_l3_parse_rxipe(buf, proto, addr); 880 rc = qeth_l3_parse_rxipe(buf, proto, addr);
910 if (!rc) 881 if (!rc)
911 rc = qeth_l3_add_rxip(card, proto, addr); 882 rc = qeth_l3_modify_rxip_vipa(card, true, addr,
883 QETH_IP_TYPE_RXIP, proto);
912 mutex_unlock(&card->conf_mutex); 884 mutex_unlock(&card->conf_mutex);
913 return rc ? rc : count; 885 return rc ? rc : count;
914} 886}
@@ -937,7 +909,8 @@ static ssize_t qeth_l3_dev_rxip_del_store(const char *buf, size_t count,
937 mutex_lock(&card->conf_mutex); 909 mutex_lock(&card->conf_mutex);
938 rc = qeth_l3_parse_rxipe(buf, proto, addr); 910 rc = qeth_l3_parse_rxipe(buf, proto, addr);
939 if (!rc) 911 if (!rc)
940 rc = qeth_l3_del_rxip(card, proto, addr); 912 rc = qeth_l3_modify_rxip_vipa(card, false, addr,
913 QETH_IP_TYPE_RXIP, proto);
941 mutex_unlock(&card->conf_mutex); 914 mutex_unlock(&card->conf_mutex);
942 return rc ? rc : count; 915 return rc ? rc : count;
943} 916}
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 6198559abbd8..0ad00dbf912d 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -732,7 +732,7 @@ static int iscsi_sw_tcp_conn_get_param(struct iscsi_cls_conn *cls_conn,
732 struct iscsi_tcp_conn *tcp_conn = conn->dd_data; 732 struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
733 struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data; 733 struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
734 struct sockaddr_in6 addr; 734 struct sockaddr_in6 addr;
735 int rc, len; 735 int rc;
736 736
737 switch(param) { 737 switch(param) {
738 case ISCSI_PARAM_CONN_PORT: 738 case ISCSI_PARAM_CONN_PORT:
@@ -745,12 +745,12 @@ static int iscsi_sw_tcp_conn_get_param(struct iscsi_cls_conn *cls_conn,
745 } 745 }
746 if (param == ISCSI_PARAM_LOCAL_PORT) 746 if (param == ISCSI_PARAM_LOCAL_PORT)
747 rc = kernel_getsockname(tcp_sw_conn->sock, 747 rc = kernel_getsockname(tcp_sw_conn->sock,
748 (struct sockaddr *)&addr, &len); 748 (struct sockaddr *)&addr);
749 else 749 else
750 rc = kernel_getpeername(tcp_sw_conn->sock, 750 rc = kernel_getpeername(tcp_sw_conn->sock,
751 (struct sockaddr *)&addr, &len); 751 (struct sockaddr *)&addr);
752 spin_unlock_bh(&conn->session->frwd_lock); 752 spin_unlock_bh(&conn->session->frwd_lock);
753 if (rc) 753 if (rc < 0)
754 return rc; 754 return rc;
755 755
756 return iscsi_conn_get_addr_param((struct sockaddr_storage *) 756 return iscsi_conn_get_addr_param((struct sockaddr_storage *)
@@ -771,7 +771,7 @@ static int iscsi_sw_tcp_host_get_param(struct Scsi_Host *shost,
771 struct iscsi_tcp_conn *tcp_conn; 771 struct iscsi_tcp_conn *tcp_conn;
772 struct iscsi_sw_tcp_conn *tcp_sw_conn; 772 struct iscsi_sw_tcp_conn *tcp_sw_conn;
773 struct sockaddr_in6 addr; 773 struct sockaddr_in6 addr;
774 int rc, len; 774 int rc;
775 775
776 switch (param) { 776 switch (param) {
777 case ISCSI_HOST_PARAM_IPADDRESS: 777 case ISCSI_HOST_PARAM_IPADDRESS:
@@ -793,9 +793,9 @@ static int iscsi_sw_tcp_host_get_param(struct Scsi_Host *shost,
793 } 793 }
794 794
795 rc = kernel_getsockname(tcp_sw_conn->sock, 795 rc = kernel_getsockname(tcp_sw_conn->sock,
796 (struct sockaddr *)&addr, &len); 796 (struct sockaddr *)&addr);
797 spin_unlock_bh(&session->frwd_lock); 797 spin_unlock_bh(&session->frwd_lock);
798 if (rc) 798 if (rc < 0)
799 return rc; 799 return rc;
800 800
801 return iscsi_conn_get_addr_param((struct sockaddr_storage *) 801 return iscsi_conn_get_addr_param((struct sockaddr_storage *)
diff --git a/drivers/soc/qcom/qmi_interface.c b/drivers/soc/qcom/qmi_interface.c
index 877611d5c42b..321982277697 100644
--- a/drivers/soc/qcom/qmi_interface.c
+++ b/drivers/soc/qcom/qmi_interface.c
@@ -586,7 +586,6 @@ static struct socket *qmi_sock_create(struct qmi_handle *qmi,
586 struct sockaddr_qrtr *sq) 586 struct sockaddr_qrtr *sq)
587{ 587{
588 struct socket *sock; 588 struct socket *sock;
589 int sl = sizeof(*sq);
590 int ret; 589 int ret;
591 590
592 ret = sock_create_kern(&init_net, AF_QIPCRTR, SOCK_DGRAM, 591 ret = sock_create_kern(&init_net, AF_QIPCRTR, SOCK_DGRAM,
@@ -594,7 +593,7 @@ static struct socket *qmi_sock_create(struct qmi_handle *qmi,
594 if (ret < 0) 593 if (ret < 0)
595 return ERR_PTR(ret); 594 return ERR_PTR(ret);
596 595
597 ret = kernel_getsockname(sock, (struct sockaddr *)sq, &sl); 596 ret = kernel_getsockname(sock, (struct sockaddr *)sq);
598 if (ret < 0) { 597 if (ret < 0) {
599 sock_release(sock); 598 sock_release(sock);
600 return ERR_PTR(ret); 599 return ERR_PTR(ret);
diff --git a/drivers/staging/ipx/af_ipx.c b/drivers/staging/ipx/af_ipx.c
index d21a9d128d3e..5703dd176787 100644
--- a/drivers/staging/ipx/af_ipx.c
+++ b/drivers/staging/ipx/af_ipx.c
@@ -1577,7 +1577,7 @@ out:
1577 1577
1578 1578
1579static int ipx_getname(struct socket *sock, struct sockaddr *uaddr, 1579static int ipx_getname(struct socket *sock, struct sockaddr *uaddr,
1580 int *uaddr_len, int peer) 1580 int peer)
1581{ 1581{
1582 struct ipx_address *addr; 1582 struct ipx_address *addr;
1583 struct sockaddr_ipx sipx; 1583 struct sockaddr_ipx sipx;
@@ -1585,8 +1585,6 @@ static int ipx_getname(struct socket *sock, struct sockaddr *uaddr,
1585 struct ipx_sock *ipxs = ipx_sk(sk); 1585 struct ipx_sock *ipxs = ipx_sk(sk);
1586 int rc; 1586 int rc;
1587 1587
1588 *uaddr_len = sizeof(struct sockaddr_ipx);
1589
1590 lock_sock(sk); 1588 lock_sock(sk);
1591 if (peer) { 1589 if (peer) {
1592 rc = -ENOTCONN; 1590 rc = -ENOTCONN;
@@ -1620,7 +1618,7 @@ static int ipx_getname(struct socket *sock, struct sockaddr *uaddr,
1620 sipx.sipx_zero = 0; 1618 sipx.sipx_zero = 0;
1621 memcpy(uaddr, &sipx, sizeof(sipx)); 1619 memcpy(uaddr, &sipx, sizeof(sipx));
1622 1620
1623 rc = 0; 1621 rc = sizeof(struct sockaddr_ipx);
1624out: 1622out:
1625 release_sock(sk); 1623 release_sock(sk);
1626 return rc; 1624 return rc;
diff --git a/drivers/staging/irda/net/af_irda.c b/drivers/staging/irda/net/af_irda.c
index 2f1e9ab3d6d0..c13553a9ee11 100644
--- a/drivers/staging/irda/net/af_irda.c
+++ b/drivers/staging/irda/net/af_irda.c
@@ -697,7 +697,7 @@ static int irda_discover_daddr_and_lsap_sel(struct irda_sock *self, char *name)
697 * 697 *
698 */ 698 */
699static int irda_getname(struct socket *sock, struct sockaddr *uaddr, 699static int irda_getname(struct socket *sock, struct sockaddr *uaddr,
700 int *uaddr_len, int peer) 700 int peer)
701{ 701{
702 struct sockaddr_irda saddr; 702 struct sockaddr_irda saddr;
703 struct sock *sk = sock->sk; 703 struct sock *sk = sock->sk;
@@ -720,11 +720,9 @@ static int irda_getname(struct socket *sock, struct sockaddr *uaddr,
720 pr_debug("%s(), tsap_sel = %#x\n", __func__, saddr.sir_lsap_sel); 720 pr_debug("%s(), tsap_sel = %#x\n", __func__, saddr.sir_lsap_sel);
721 pr_debug("%s(), addr = %08x\n", __func__, saddr.sir_addr); 721 pr_debug("%s(), addr = %08x\n", __func__, saddr.sir_addr);
722 722
723 /* uaddr_len come to us uninitialised */ 723 memcpy(uaddr, &saddr, sizeof (struct sockaddr_irda));
724 *uaddr_len = sizeof (struct sockaddr_irda);
725 memcpy(uaddr, &saddr, *uaddr_len);
726 724
727 return 0; 725 return sizeof (struct sockaddr_irda);
728} 726}
729 727
730/* 728/*
diff --git a/drivers/staging/lustre/lnet/lnet/lib-socket.c b/drivers/staging/lustre/lnet/lnet/lib-socket.c
index ce93806eefca..1bee667802b0 100644
--- a/drivers/staging/lustre/lnet/lnet/lib-socket.c
+++ b/drivers/staging/lustre/lnet/lnet/lib-socket.c
@@ -448,14 +448,13 @@ int
448lnet_sock_getaddr(struct socket *sock, bool remote, __u32 *ip, int *port) 448lnet_sock_getaddr(struct socket *sock, bool remote, __u32 *ip, int *port)
449{ 449{
450 struct sockaddr_in sin; 450 struct sockaddr_in sin;
451 int len = sizeof(sin);
452 int rc; 451 int rc;
453 452
454 if (remote) 453 if (remote)
455 rc = kernel_getpeername(sock, (struct sockaddr *)&sin, &len); 454 rc = kernel_getpeername(sock, (struct sockaddr *)&sin);
456 else 455 else
457 rc = kernel_getsockname(sock, (struct sockaddr *)&sin, &len); 456 rc = kernel_getsockname(sock, (struct sockaddr *)&sin);
458 if (rc) { 457 if (rc < 0) {
459 CERROR("Error %d getting sock %s IP/port\n", 458 CERROR("Error %d getting sock %s IP/port\n",
460 rc, remote ? "peer" : "local"); 459 rc, remote ? "peer" : "local");
461 return rc; 460 return rc;
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c
index 64c5a57b92e4..99501785cdc1 100644
--- a/drivers/target/iscsi/iscsi_target_login.c
+++ b/drivers/target/iscsi/iscsi_target_login.c
@@ -1020,7 +1020,7 @@ int iscsit_accept_np(struct iscsi_np *np, struct iscsi_conn *conn)
1020 struct socket *new_sock, *sock = np->np_socket; 1020 struct socket *new_sock, *sock = np->np_socket;
1021 struct sockaddr_in sock_in; 1021 struct sockaddr_in sock_in;
1022 struct sockaddr_in6 sock_in6; 1022 struct sockaddr_in6 sock_in6;
1023 int rc, err; 1023 int rc;
1024 1024
1025 rc = kernel_accept(sock, &new_sock, 0); 1025 rc = kernel_accept(sock, &new_sock, 0);
1026 if (rc < 0) 1026 if (rc < 0)
@@ -1033,8 +1033,8 @@ int iscsit_accept_np(struct iscsi_np *np, struct iscsi_conn *conn)
1033 memset(&sock_in6, 0, sizeof(struct sockaddr_in6)); 1033 memset(&sock_in6, 0, sizeof(struct sockaddr_in6));
1034 1034
1035 rc = conn->sock->ops->getname(conn->sock, 1035 rc = conn->sock->ops->getname(conn->sock,
1036 (struct sockaddr *)&sock_in6, &err, 1); 1036 (struct sockaddr *)&sock_in6, 1);
1037 if (!rc) { 1037 if (rc >= 0) {
1038 if (!ipv6_addr_v4mapped(&sock_in6.sin6_addr)) { 1038 if (!ipv6_addr_v4mapped(&sock_in6.sin6_addr)) {
1039 memcpy(&conn->login_sockaddr, &sock_in6, sizeof(sock_in6)); 1039 memcpy(&conn->login_sockaddr, &sock_in6, sizeof(sock_in6));
1040 } else { 1040 } else {
@@ -1047,8 +1047,8 @@ int iscsit_accept_np(struct iscsi_np *np, struct iscsi_conn *conn)
1047 } 1047 }
1048 1048
1049 rc = conn->sock->ops->getname(conn->sock, 1049 rc = conn->sock->ops->getname(conn->sock,
1050 (struct sockaddr *)&sock_in6, &err, 0); 1050 (struct sockaddr *)&sock_in6, 0);
1051 if (!rc) { 1051 if (rc >= 0) {
1052 if (!ipv6_addr_v4mapped(&sock_in6.sin6_addr)) { 1052 if (!ipv6_addr_v4mapped(&sock_in6.sin6_addr)) {
1053 memcpy(&conn->local_sockaddr, &sock_in6, sizeof(sock_in6)); 1053 memcpy(&conn->local_sockaddr, &sock_in6, sizeof(sock_in6));
1054 } else { 1054 } else {
@@ -1063,13 +1063,13 @@ int iscsit_accept_np(struct iscsi_np *np, struct iscsi_conn *conn)
1063 memset(&sock_in, 0, sizeof(struct sockaddr_in)); 1063 memset(&sock_in, 0, sizeof(struct sockaddr_in));
1064 1064
1065 rc = conn->sock->ops->getname(conn->sock, 1065 rc = conn->sock->ops->getname(conn->sock,
1066 (struct sockaddr *)&sock_in, &err, 1); 1066 (struct sockaddr *)&sock_in, 1);
1067 if (!rc) 1067 if (rc >= 0)
1068 memcpy(&conn->login_sockaddr, &sock_in, sizeof(sock_in)); 1068 memcpy(&conn->login_sockaddr, &sock_in, sizeof(sock_in));
1069 1069
1070 rc = conn->sock->ops->getname(conn->sock, 1070 rc = conn->sock->ops->getname(conn->sock,
1071 (struct sockaddr *)&sock_in, &err, 0); 1071 (struct sockaddr *)&sock_in, 0);
1072 if (!rc) 1072 if (rc >= 0)
1073 memcpy(&conn->local_sockaddr, &sock_in, sizeof(sock_in)); 1073 memcpy(&conn->local_sockaddr, &sock_in, sizeof(sock_in));
1074 } 1074 }
1075 1075
diff --git a/drivers/usb/gadget/function/f_eem.c b/drivers/usb/gadget/function/f_eem.c
index 37557651b600..c13befa31110 100644
--- a/drivers/usb/gadget/function/f_eem.c
+++ b/drivers/usb/gadget/function/f_eem.c
@@ -507,7 +507,6 @@ static int eem_unwrap(struct gether *port,
507 0, 507 0,
508 GFP_ATOMIC); 508 GFP_ATOMIC);
509 if (unlikely(!skb3)) { 509 if (unlikely(!skb3)) {
510 DBG(cdev, "unable to realign EEM packet\n");
511 dev_kfree_skb_any(skb2); 510 dev_kfree_skb_any(skb2);
512 continue; 511 continue;
513 } 512 }
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 8139bc70ad7d..a31d9b240af8 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -1040,7 +1040,7 @@ static struct socket *get_raw_socket(int fd)
1040 struct sockaddr_ll sa; 1040 struct sockaddr_ll sa;
1041 char buf[MAX_ADDR_LEN]; 1041 char buf[MAX_ADDR_LEN];
1042 } uaddr; 1042 } uaddr;
1043 int uaddr_len = sizeof uaddr, r; 1043 int r;
1044 struct socket *sock = sockfd_lookup(fd, &r); 1044 struct socket *sock = sockfd_lookup(fd, &r);
1045 1045
1046 if (!sock) 1046 if (!sock)
@@ -1052,9 +1052,8 @@ static struct socket *get_raw_socket(int fd)
1052 goto err; 1052 goto err;
1053 } 1053 }
1054 1054
1055 r = sock->ops->getname(sock, (struct sockaddr *)&uaddr.sa, 1055 r = sock->ops->getname(sock, (struct sockaddr *)&uaddr.sa, 0);
1056 &uaddr_len, 0); 1056 if (r < 0)
1057 if (r)
1058 goto err; 1057 goto err;
1059 1058
1060 if (uaddr.sa.sll_family != AF_PACKET) { 1059 if (uaddr.sa.sll_family != AF_PACKET) {
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index 0d14e2ff19f1..0898dbdbf955 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -61,9 +61,9 @@ static struct vhost_vsock *__vhost_vsock_get(u32 guest_cid)
61 if (other_cid == 0) 61 if (other_cid == 0)
62 continue; 62 continue;
63 63
64 if (other_cid == guest_cid) { 64 if (other_cid == guest_cid)
65 return vsock; 65 return vsock;
66 } 66
67 } 67 }
68 68
69 return NULL; 69 return NULL;
diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
index cff79ea0c01d..5243989a60cc 100644
--- a/fs/dlm/lowcomms.c
+++ b/fs/dlm/lowcomms.c
@@ -482,7 +482,6 @@ static void lowcomms_error_report(struct sock *sk)
482{ 482{
483 struct connection *con; 483 struct connection *con;
484 struct sockaddr_storage saddr; 484 struct sockaddr_storage saddr;
485 int buflen;
486 void (*orig_report)(struct sock *) = NULL; 485 void (*orig_report)(struct sock *) = NULL;
487 486
488 read_lock_bh(&sk->sk_callback_lock); 487 read_lock_bh(&sk->sk_callback_lock);
@@ -492,7 +491,7 @@ static void lowcomms_error_report(struct sock *sk)
492 491
493 orig_report = listen_sock.sk_error_report; 492 orig_report = listen_sock.sk_error_report;
494 if (con->sock == NULL || 493 if (con->sock == NULL ||
495 kernel_getpeername(con->sock, (struct sockaddr *)&saddr, &buflen)) { 494 kernel_getpeername(con->sock, (struct sockaddr *)&saddr) < 0) {
496 printk_ratelimited(KERN_ERR "dlm: node %d: socket error " 495 printk_ratelimited(KERN_ERR "dlm: node %d: socket error "
497 "sending to node %d, port %d, " 496 "sending to node %d, port %d, "
498 "sk_err=%d/%d\n", dlm_our_nodeid(), 497 "sk_err=%d/%d\n", dlm_our_nodeid(),
@@ -757,8 +756,8 @@ static int tcp_accept_from_sock(struct connection *con)
757 756
758 /* Get the connected socket's peer */ 757 /* Get the connected socket's peer */
759 memset(&peeraddr, 0, sizeof(peeraddr)); 758 memset(&peeraddr, 0, sizeof(peeraddr));
760 if (newsock->ops->getname(newsock, (struct sockaddr *)&peeraddr, 759 len = newsock->ops->getname(newsock, (struct sockaddr *)&peeraddr, 2);
761 &len, 2)) { 760 if (len < 0) {
762 result = -ECONNABORTED; 761 result = -ECONNABORTED;
763 goto accept_err; 762 goto accept_err;
764 } 763 }
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index 9c36d614bf89..2dee4e03ff1c 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -709,6 +709,7 @@ static struct pernet_operations lockd_net_ops = {
709 .exit = lockd_exit_net, 709 .exit = lockd_exit_net,
710 .id = &lockd_net_id, 710 .id = &lockd_net_id,
711 .size = sizeof(struct lockd_net), 711 .size = sizeof(struct lockd_net),
712 .async = true,
712}; 713};
713 714
714 715
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 7d893543cf3b..6c3083c992e5 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -2122,6 +2122,7 @@ static struct pernet_operations nfs_net_ops = {
2122 .exit = nfs_net_exit, 2122 .exit = nfs_net_exit,
2123 .id = &nfs_net_id, 2123 .id = &nfs_net_id,
2124 .size = sizeof(struct nfs_net), 2124 .size = sizeof(struct nfs_net),
2125 .async = true,
2125}; 2126};
2126 2127
2127/* 2128/*
diff --git a/fs/nfs_common/grace.c b/fs/nfs_common/grace.c
index 5be08f02a76b..8c743a405df6 100644
--- a/fs/nfs_common/grace.c
+++ b/fs/nfs_common/grace.c
@@ -118,6 +118,7 @@ static struct pernet_operations grace_net_ops = {
118 .exit = grace_exit_net, 118 .exit = grace_exit_net,
119 .id = &grace_net_id, 119 .id = &grace_net_id,
120 .size = sizeof(struct list_head), 120 .size = sizeof(struct list_head),
121 .async = true,
121}; 122};
122 123
123static int __init 124static int __init
diff --git a/fs/nsfs.c b/fs/nsfs.c
index 36b0772701a0..60702d677bd4 100644
--- a/fs/nsfs.c
+++ b/fs/nsfs.c
@@ -184,6 +184,7 @@ int open_related_ns(struct ns_common *ns,
184 184
185 return fd; 185 return fd;
186} 186}
187EXPORT_SYMBOL_GPL(open_related_ns);
187 188
188static long ns_ioctl(struct file *filp, unsigned int ioctl, 189static long ns_ioctl(struct file *filp, unsigned int ioctl,
189 unsigned long arg) 190 unsigned long arg)
diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c
index eac5140aac47..e5076185cc1e 100644
--- a/fs/ocfs2/cluster/tcp.c
+++ b/fs/ocfs2/cluster/tcp.c
@@ -1819,7 +1819,7 @@ int o2net_register_hb_callbacks(void)
1819 1819
1820static int o2net_accept_one(struct socket *sock, int *more) 1820static int o2net_accept_one(struct socket *sock, int *more)
1821{ 1821{
1822 int ret, slen; 1822 int ret;
1823 struct sockaddr_in sin; 1823 struct sockaddr_in sin;
1824 struct socket *new_sock = NULL; 1824 struct socket *new_sock = NULL;
1825 struct o2nm_node *node = NULL; 1825 struct o2nm_node *node = NULL;
@@ -1864,9 +1864,7 @@ static int o2net_accept_one(struct socket *sock, int *more)
1864 goto out; 1864 goto out;
1865 } 1865 }
1866 1866
1867 slen = sizeof(sin); 1867 ret = new_sock->ops->getname(new_sock, (struct sockaddr *) &sin, 1);
1868 ret = new_sock->ops->getname(new_sock, (struct sockaddr *) &sin,
1869 &slen, 1);
1870 if (ret < 0) 1868 if (ret < 0)
1871 goto out; 1869 goto out;
1872 1870
diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c
index 68c06ae7888c..da6f8733c9c5 100644
--- a/fs/proc/proc_net.c
+++ b/fs/proc/proc_net.c
@@ -237,6 +237,7 @@ static __net_exit void proc_net_ns_exit(struct net *net)
237static struct pernet_operations __net_initdata proc_net_ns_ops = { 237static struct pernet_operations __net_initdata proc_net_ns_ops = {
238 .init = proc_net_ns_init, 238 .init = proc_net_ns_init,
239 .exit = proc_net_ns_exit, 239 .exit = proc_net_ns_exit,
240 .async = true,
240}; 241};
241 242
242int __init proc_net_init(void) 243int __init proc_net_init(void)
diff --git a/include/dt-bindings/net/ti-dp83867.h b/include/dt-bindings/net/ti-dp83867.h
index 172744a72eb7..7b1656427cbe 100644
--- a/include/dt-bindings/net/ti-dp83867.h
+++ b/include/dt-bindings/net/ti-dp83867.h
@@ -42,4 +42,18 @@
42#define DP83867_RGMIIDCTL_3_75_NS 0xe 42#define DP83867_RGMIIDCTL_3_75_NS 0xe
43#define DP83867_RGMIIDCTL_4_00_NS 0xf 43#define DP83867_RGMIIDCTL_4_00_NS 0xf
44 44
45/* IO_MUX_CFG - Clock output selection */
46#define DP83867_CLK_O_SEL_CHN_A_RCLK 0x0
47#define DP83867_CLK_O_SEL_CHN_B_RCLK 0x1
48#define DP83867_CLK_O_SEL_CHN_C_RCLK 0x2
49#define DP83867_CLK_O_SEL_CHN_D_RCLK 0x3
50#define DP83867_CLK_O_SEL_CHN_A_RCLK_DIV5 0x4
51#define DP83867_CLK_O_SEL_CHN_B_RCLK_DIV5 0x5
52#define DP83867_CLK_O_SEL_CHN_C_RCLK_DIV5 0x6
53#define DP83867_CLK_O_SEL_CHN_D_RCLK_DIV5 0x7
54#define DP83867_CLK_O_SEL_CHN_A_TCLK 0x8
55#define DP83867_CLK_O_SEL_CHN_B_TCLK 0x9
56#define DP83867_CLK_O_SEL_CHN_C_TCLK 0xA
57#define DP83867_CLK_O_SEL_CHN_D_TCLK 0xB
58#define DP83867_CLK_O_SEL_REF_CLK 0xC
45#endif 59#endif
diff --git a/include/linux/atalk.h b/include/linux/atalk.h
index 4d356e168692..40373920ea58 100644
--- a/include/linux/atalk.h
+++ b/include/linux/atalk.h
@@ -113,10 +113,12 @@ extern void aarp_proto_init(void);
113/* Inter module exports */ 113/* Inter module exports */
114 114
115/* Give a device find its atif control structure */ 115/* Give a device find its atif control structure */
116#if IS_ENABLED(CONFIG_IRDA) || IS_ENABLED(CONFIG_ATALK)
116static inline struct atalk_iface *atalk_find_dev(struct net_device *dev) 117static inline struct atalk_iface *atalk_find_dev(struct net_device *dev)
117{ 118{
118 return dev->atalk_ptr; 119 return dev->atalk_ptr;
119} 120}
121#endif
120 122
121extern struct atalk_addr *atalk_find_dev_addr(struct net_device *dev); 123extern struct atalk_addr *atalk_find_dev_addr(struct net_device *dev);
122extern struct net_device *atrtr_get_dev(struct atalk_addr *sa); 124extern struct net_device *atrtr_get_dev(struct atalk_addr *sa);
diff --git a/include/linux/avf/virtchnl.h b/include/linux/avf/virtchnl.h
index 3ce61342fa31..b0a7f315bfbe 100644
--- a/include/linux/avf/virtchnl.h
+++ b/include/linux/avf/virtchnl.h
@@ -136,15 +136,21 @@ enum virtchnl_ops {
136 VIRTCHNL_OP_ENABLE_VLAN_STRIPPING = 27, 136 VIRTCHNL_OP_ENABLE_VLAN_STRIPPING = 27,
137 VIRTCHNL_OP_DISABLE_VLAN_STRIPPING = 28, 137 VIRTCHNL_OP_DISABLE_VLAN_STRIPPING = 28,
138 VIRTCHNL_OP_REQUEST_QUEUES = 29, 138 VIRTCHNL_OP_REQUEST_QUEUES = 29,
139 VIRTCHNL_OP_ENABLE_CHANNELS = 30,
140 VIRTCHNL_OP_DISABLE_CHANNELS = 31,
141 VIRTCHNL_OP_ADD_CLOUD_FILTER = 32,
142 VIRTCHNL_OP_DEL_CLOUD_FILTER = 33,
139}; 143};
140 144
141/* This macro is used to generate a compilation error if a structure 145/* These macros are used to generate compilation errors if a structure/union
142 * is not exactly the correct length. It gives a divide by zero error if the 146 * is not exactly the correct length. It gives a divide by zero error if the
143 * structure is not of the correct size, otherwise it creates an enum that is 147 * structure/union is not of the correct size, otherwise it creates an enum
144 * never used. 148 * that is never used.
145 */ 149 */
146#define VIRTCHNL_CHECK_STRUCT_LEN(n, X) enum virtchnl_static_assert_enum_##X \ 150#define VIRTCHNL_CHECK_STRUCT_LEN(n, X) enum virtchnl_static_assert_enum_##X \
147 { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) } 151 { virtchnl_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
152#define VIRTCHNL_CHECK_UNION_LEN(n, X) enum virtchnl_static_asset_enum_##X \
153 { virtchnl_static_assert_##X = (n)/((sizeof(union X) == (n)) ? 1 : 0) }
148 154
149/* Virtual channel message descriptor. This overlays the admin queue 155/* Virtual channel message descriptor. This overlays the admin queue
150 * descriptor. All other data is passed in external buffers. 156 * descriptor. All other data is passed in external buffers.
@@ -244,6 +250,7 @@ VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_vsi_resource);
244#define VIRTCHNL_VF_OFFLOAD_ENCAP 0X00100000 250#define VIRTCHNL_VF_OFFLOAD_ENCAP 0X00100000
245#define VIRTCHNL_VF_OFFLOAD_ENCAP_CSUM 0X00200000 251#define VIRTCHNL_VF_OFFLOAD_ENCAP_CSUM 0X00200000
246#define VIRTCHNL_VF_OFFLOAD_RX_ENCAP_CSUM 0X00400000 252#define VIRTCHNL_VF_OFFLOAD_RX_ENCAP_CSUM 0X00400000
253#define VIRTCHNL_VF_OFFLOAD_ADQ 0X00800000
247 254
248#define VF_BASE_MODE_OFFLOADS (VIRTCHNL_VF_OFFLOAD_L2 | \ 255#define VF_BASE_MODE_OFFLOADS (VIRTCHNL_VF_OFFLOAD_L2 | \
249 VIRTCHNL_VF_OFFLOAD_VLAN | \ 256 VIRTCHNL_VF_OFFLOAD_VLAN | \
@@ -496,6 +503,81 @@ struct virtchnl_rss_hena {
496 503
497VIRTCHNL_CHECK_STRUCT_LEN(8, virtchnl_rss_hena); 504VIRTCHNL_CHECK_STRUCT_LEN(8, virtchnl_rss_hena);
498 505
506/* VIRTCHNL_OP_ENABLE_CHANNELS
507 * VIRTCHNL_OP_DISABLE_CHANNELS
508 * VF sends these messages to enable or disable channels based on
509 * the user specified queue count and queue offset for each traffic class.
510 * This struct encompasses all the information that the PF needs from
511 * VF to create a channel.
512 */
513struct virtchnl_channel_info {
514 u16 count; /* number of queues in a channel */
515 u16 offset; /* queues in a channel start from 'offset' */
516 u32 pad;
517 u64 max_tx_rate;
518};
519
520VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_channel_info);
521
522struct virtchnl_tc_info {
523 u32 num_tc;
524 u32 pad;
525 struct virtchnl_channel_info list[1];
526};
527
528VIRTCHNL_CHECK_STRUCT_LEN(24, virtchnl_tc_info);
529
530/* VIRTCHNL_ADD_CLOUD_FILTER
531 * VIRTCHNL_DEL_CLOUD_FILTER
532 * VF sends these messages to add or delete a cloud filter based on the
533 * user specified match and action filters. These structures encompass
534 * all the information that the PF needs from the VF to add/delete a
535 * cloud filter.
536 */
537
538struct virtchnl_l4_spec {
539 u8 src_mac[ETH_ALEN];
540 u8 dst_mac[ETH_ALEN];
541 __be16 vlan_id;
542 __be16 pad; /* reserved for future use */
543 __be32 src_ip[4];
544 __be32 dst_ip[4];
545 __be16 src_port;
546 __be16 dst_port;
547};
548
549VIRTCHNL_CHECK_STRUCT_LEN(52, virtchnl_l4_spec);
550
551union virtchnl_flow_spec {
552 struct virtchnl_l4_spec tcp_spec;
553 u8 buffer[128]; /* reserved for future use */
554};
555
556VIRTCHNL_CHECK_UNION_LEN(128, virtchnl_flow_spec);
557
558enum virtchnl_action {
559 /* action types */
560 VIRTCHNL_ACTION_DROP = 0,
561 VIRTCHNL_ACTION_TC_REDIRECT,
562};
563
564enum virtchnl_flow_type {
565 /* flow types */
566 VIRTCHNL_TCP_V4_FLOW = 0,
567 VIRTCHNL_TCP_V6_FLOW,
568};
569
570struct virtchnl_filter {
571 union virtchnl_flow_spec data;
572 union virtchnl_flow_spec mask;
573 enum virtchnl_flow_type flow_type;
574 enum virtchnl_action action;
575 u32 action_meta;
576 __u8 field_flags;
577};
578
579VIRTCHNL_CHECK_STRUCT_LEN(272, virtchnl_filter);
580
499/* VIRTCHNL_OP_EVENT 581/* VIRTCHNL_OP_EVENT
500 * PF sends this message to inform the VF driver of events that may affect it. 582 * PF sends this message to inform the VF driver of events that may affect it.
501 * No direct response is expected from the VF, though it may generate other 583 * No direct response is expected from the VF, though it may generate other
@@ -711,6 +793,25 @@ virtchnl_vc_validate_vf_msg(struct virtchnl_version_info *ver, u32 v_opcode,
711 case VIRTCHNL_OP_REQUEST_QUEUES: 793 case VIRTCHNL_OP_REQUEST_QUEUES:
712 valid_len = sizeof(struct virtchnl_vf_res_request); 794 valid_len = sizeof(struct virtchnl_vf_res_request);
713 break; 795 break;
796 case VIRTCHNL_OP_ENABLE_CHANNELS:
797 valid_len = sizeof(struct virtchnl_tc_info);
798 if (msglen >= valid_len) {
799 struct virtchnl_tc_info *vti =
800 (struct virtchnl_tc_info *)msg;
801 valid_len += vti->num_tc *
802 sizeof(struct virtchnl_channel_info);
803 if (vti->num_tc == 0)
804 err_msg_format = true;
805 }
806 break;
807 case VIRTCHNL_OP_DISABLE_CHANNELS:
808 break;
809 case VIRTCHNL_OP_ADD_CLOUD_FILTER:
810 valid_len = sizeof(struct virtchnl_filter);
811 break;
812 case VIRTCHNL_OP_DEL_CLOUD_FILTER:
813 valid_len = sizeof(struct virtchnl_filter);
814 break;
714 /* These are always errors coming from the VF. */ 815 /* These are always errors coming from the VF. */
715 case VIRTCHNL_OP_EVENT: 816 case VIRTCHNL_OP_EVENT:
716 case VIRTCHNL_OP_UNKNOWN: 817 case VIRTCHNL_OP_UNKNOWN:
diff --git a/include/linux/bpf-cgroup.h b/include/linux/bpf-cgroup.h
index a7f16e0f8d68..8a4566691c8f 100644
--- a/include/linux/bpf-cgroup.h
+++ b/include/linux/bpf-cgroup.h
@@ -96,7 +96,7 @@ int __cgroup_bpf_check_dev_permission(short dev_type, u32 major, u32 minor,
96#define BPF_CGROUP_RUN_PROG_INET_SOCK(sk) \ 96#define BPF_CGROUP_RUN_PROG_INET_SOCK(sk) \
97({ \ 97({ \
98 int __ret = 0; \ 98 int __ret = 0; \
99 if (cgroup_bpf_enabled && sk) { \ 99 if (cgroup_bpf_enabled) { \
100 __ret = __cgroup_bpf_run_filter_sk(sk, \ 100 __ret = __cgroup_bpf_run_filter_sk(sk, \
101 BPF_CGROUP_INET_SOCK_CREATE); \ 101 BPF_CGROUP_INET_SOCK_CREATE); \
102 } \ 102 } \
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 66df387106de..819229c80eca 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -21,6 +21,7 @@ struct bpf_verifier_env;
21struct perf_event; 21struct perf_event;
22struct bpf_prog; 22struct bpf_prog;
23struct bpf_map; 23struct bpf_map;
24struct sock;
24 25
25/* map is generic key/value storage optionally accesible by eBPF programs */ 26/* map is generic key/value storage optionally accesible by eBPF programs */
26struct bpf_map_ops { 27struct bpf_map_ops {
diff --git a/include/linux/bpf_types.h b/include/linux/bpf_types.h
index 19b8349a3809..5e2e8a49fb21 100644
--- a/include/linux/bpf_types.h
+++ b/include/linux/bpf_types.h
@@ -13,6 +13,7 @@ BPF_PROG_TYPE(BPF_PROG_TYPE_LWT_OUT, lwt_inout)
13BPF_PROG_TYPE(BPF_PROG_TYPE_LWT_XMIT, lwt_xmit) 13BPF_PROG_TYPE(BPF_PROG_TYPE_LWT_XMIT, lwt_xmit)
14BPF_PROG_TYPE(BPF_PROG_TYPE_SOCK_OPS, sock_ops) 14BPF_PROG_TYPE(BPF_PROG_TYPE_SOCK_OPS, sock_ops)
15BPF_PROG_TYPE(BPF_PROG_TYPE_SK_SKB, sk_skb) 15BPF_PROG_TYPE(BPF_PROG_TYPE_SK_SKB, sk_skb)
16BPF_PROG_TYPE(BPF_PROG_TYPE_SK_MSG, sk_msg)
16#endif 17#endif
17#ifdef CONFIG_BPF_EVENTS 18#ifdef CONFIG_BPF_EVENTS
18BPF_PROG_TYPE(BPF_PROG_TYPE_KPROBE, kprobe) 19BPF_PROG_TYPE(BPF_PROG_TYPE_KPROBE, kprobe)
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 2ec41a7eb54f..ebe41811ed34 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -371,6 +371,11 @@ struct ethtool_ops {
371 u8 *hfunc); 371 u8 *hfunc);
372 int (*set_rxfh)(struct net_device *, const u32 *indir, 372 int (*set_rxfh)(struct net_device *, const u32 *indir,
373 const u8 *key, const u8 hfunc); 373 const u8 *key, const u8 hfunc);
374 int (*get_rxfh_context)(struct net_device *, u32 *indir, u8 *key,
375 u8 *hfunc, u32 rss_context);
376 int (*set_rxfh_context)(struct net_device *, const u32 *indir,
377 const u8 *key, const u8 hfunc,
378 u32 *rss_context, bool delete);
374 void (*get_channels)(struct net_device *, struct ethtool_channels *); 379 void (*get_channels)(struct net_device *, struct ethtool_channels *);
375 int (*set_channels)(struct net_device *, struct ethtool_channels *); 380 int (*set_channels)(struct net_device *, struct ethtool_channels *);
376 int (*get_dump_flag)(struct net_device *, struct ethtool_dump *); 381 int (*get_dump_flag)(struct net_device *, struct ethtool_dump *);
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 276932d75975..109d05ccea9a 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -20,7 +20,6 @@
20#include <linux/set_memory.h> 20#include <linux/set_memory.h>
21#include <linux/kallsyms.h> 21#include <linux/kallsyms.h>
22 22
23#include <net/xdp.h>
24#include <net/sch_generic.h> 23#include <net/sch_generic.h>
25 24
26#include <uapi/linux/filter.h> 25#include <uapi/linux/filter.h>
@@ -30,6 +29,7 @@ struct sk_buff;
30struct sock; 29struct sock;
31struct seccomp_data; 30struct seccomp_data;
32struct bpf_prog_aux; 31struct bpf_prog_aux;
32struct xdp_rxq_info;
33 33
34/* ArgX, context and stack frame pointer register positions. Note, 34/* ArgX, context and stack frame pointer register positions. Note,
35 * Arg1, Arg2, Arg3, etc are used as argument mappings of function 35 * Arg1, Arg2, Arg3, etc are used as argument mappings of function
@@ -507,6 +507,22 @@ struct xdp_buff {
507 struct xdp_rxq_info *rxq; 507 struct xdp_rxq_info *rxq;
508}; 508};
509 509
510struct sk_msg_buff {
511 void *data;
512 void *data_end;
513 __u32 apply_bytes;
514 __u32 cork_bytes;
515 int sg_copybreak;
516 int sg_start;
517 int sg_curr;
518 int sg_end;
519 struct scatterlist sg_data[MAX_SKB_FRAGS];
520 bool sg_copy[MAX_SKB_FRAGS];
521 __u32 key;
522 __u32 flags;
523 struct bpf_map *map;
524};
525
510/* Compute the linear packet data range [data, data_end) which 526/* Compute the linear packet data range [data, data_end) which
511 * will be accessed by various program types (cls_bpf, act_bpf, 527 * will be accessed by various program types (cls_bpf, act_bpf,
512 * lwt, ...). Subsystems allowing direct data access must (!) 528 * lwt, ...). Subsystems allowing direct data access must (!)
@@ -771,6 +787,7 @@ xdp_data_meta_unsupported(const struct xdp_buff *xdp)
771void bpf_warn_invalid_xdp_action(u32 act); 787void bpf_warn_invalid_xdp_action(u32 act);
772 788
773struct sock *do_sk_redirect_map(struct sk_buff *skb); 789struct sock *do_sk_redirect_map(struct sk_buff *skb);
790struct sock *do_msg_redirect_map(struct sk_msg_buff *md);
774 791
775#ifdef CONFIG_BPF_JIT 792#ifdef CONFIG_BPF_JIT
776extern int bpf_jit_enable; 793extern int bpf_jit_enable;
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index ee6657a0ed69..8fe7e4306816 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -8,6 +8,7 @@
8 * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net> 8 * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
9 * Copyright (c) 2013 - 2014 Intel Mobile Communications GmbH 9 * Copyright (c) 2013 - 2014 Intel Mobile Communications GmbH
10 * Copyright (c) 2016 - 2017 Intel Deutschland GmbH 10 * Copyright (c) 2016 - 2017 Intel Deutschland GmbH
11 * Copyright (c) 2018 Intel Corporation
11 * 12 *
12 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as 14 * it under the terms of the GNU General Public License version 2 as
@@ -2111,7 +2112,7 @@ enum ieee80211_key_len {
2111#define FILS_ERP_MAX_REALM_LEN 253 2112#define FILS_ERP_MAX_REALM_LEN 253
2112#define FILS_ERP_MAX_RRK_LEN 64 2113#define FILS_ERP_MAX_RRK_LEN 64
2113 2114
2114#define PMK_MAX_LEN 48 2115#define PMK_MAX_LEN 64
2115 2116
2116/* Public action codes (IEEE Std 802.11-2016, 9.6.8.1, Table 9-307) */ 2117/* Public action codes (IEEE Std 802.11-2016, 9.6.8.1, Table 9-307) */
2117enum ieee80211_pub_actioncode { 2118enum ieee80211_pub_actioncode {
@@ -2502,6 +2503,17 @@ static inline u8 *ieee80211_get_qos_ctl(struct ieee80211_hdr *hdr)
2502} 2503}
2503 2504
2504/** 2505/**
2506 * ieee80211_get_tid - get qos TID
2507 * @hdr: the frame
2508 */
2509static inline u8 ieee80211_get_tid(struct ieee80211_hdr *hdr)
2510{
2511 u8 *qc = ieee80211_get_qos_ctl(hdr);
2512
2513 return qc[0] & IEEE80211_QOS_CTL_TID_MASK;
2514}
2515
2516/**
2505 * ieee80211_get_SA - get pointer to SA 2517 * ieee80211_get_SA - get pointer to SA
2506 * @hdr: the frame 2518 * @hdr: the frame
2507 * 2519 *
diff --git a/include/linux/mlx5/accel.h b/include/linux/mlx5/accel.h
new file mode 100644
index 000000000000..70e7e5673ce9
--- /dev/null
+++ b/include/linux/mlx5/accel.h
@@ -0,0 +1,144 @@
1/*
2 * Copyright (c) 2018 Mellanox Technologies. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 *
32 */
33
34#ifndef __MLX5_ACCEL_H__
35#define __MLX5_ACCEL_H__
36
37#include <linux/mlx5/driver.h>
38
39enum mlx5_accel_esp_aes_gcm_keymat_iv_algo {
40 MLX5_ACCEL_ESP_AES_GCM_IV_ALGO_SEQ,
41};
42
43enum mlx5_accel_esp_flags {
44 MLX5_ACCEL_ESP_FLAGS_TUNNEL = 0, /* Default */
45 MLX5_ACCEL_ESP_FLAGS_TRANSPORT = 1UL << 0,
46 MLX5_ACCEL_ESP_FLAGS_ESN_TRIGGERED = 1UL << 1,
47 MLX5_ACCEL_ESP_FLAGS_ESN_STATE_OVERLAP = 1UL << 2,
48};
49
50enum mlx5_accel_esp_action {
51 MLX5_ACCEL_ESP_ACTION_DECRYPT,
52 MLX5_ACCEL_ESP_ACTION_ENCRYPT,
53};
54
55enum mlx5_accel_esp_keymats {
56 MLX5_ACCEL_ESP_KEYMAT_AES_NONE,
57 MLX5_ACCEL_ESP_KEYMAT_AES_GCM,
58};
59
60enum mlx5_accel_esp_replay {
61 MLX5_ACCEL_ESP_REPLAY_NONE,
62 MLX5_ACCEL_ESP_REPLAY_BMP,
63};
64
65struct aes_gcm_keymat {
66 u64 seq_iv;
67 enum mlx5_accel_esp_aes_gcm_keymat_iv_algo iv_algo;
68
69 u32 salt;
70 u32 icv_len;
71
72 u32 key_len;
73 u32 aes_key[256 / 32];
74};
75
76struct mlx5_accel_esp_xfrm_attrs {
77 enum mlx5_accel_esp_action action;
78 u32 esn;
79 u32 spi;
80 u32 seq;
81 u32 tfc_pad;
82 u32 flags;
83 u32 sa_handle;
84 enum mlx5_accel_esp_replay replay_type;
85 union {
86 struct {
87 u32 size;
88
89 } bmp;
90 } replay;
91 enum mlx5_accel_esp_keymats keymat_type;
92 union {
93 struct aes_gcm_keymat aes_gcm;
94 } keymat;
95};
96
97struct mlx5_accel_esp_xfrm {
98 struct mlx5_core_dev *mdev;
99 struct mlx5_accel_esp_xfrm_attrs attrs;
100};
101
102enum {
103 MLX5_ACCEL_XFRM_FLAG_REQUIRE_METADATA = 1UL << 0,
104};
105
106enum mlx5_accel_ipsec_cap {
107 MLX5_ACCEL_IPSEC_CAP_DEVICE = 1 << 0,
108 MLX5_ACCEL_IPSEC_CAP_REQUIRED_METADATA = 1 << 1,
109 MLX5_ACCEL_IPSEC_CAP_ESP = 1 << 2,
110 MLX5_ACCEL_IPSEC_CAP_IPV6 = 1 << 3,
111 MLX5_ACCEL_IPSEC_CAP_LSO = 1 << 4,
112 MLX5_ACCEL_IPSEC_CAP_RX_NO_TRAILER = 1 << 5,
113 MLX5_ACCEL_IPSEC_CAP_ESN = 1 << 6,
114 MLX5_ACCEL_IPSEC_CAP_TX_IV_IS_ESN = 1 << 7,
115};
116
117#ifdef CONFIG_MLX5_ACCEL
118
119u32 mlx5_accel_ipsec_device_caps(struct mlx5_core_dev *mdev);
120
121struct mlx5_accel_esp_xfrm *
122mlx5_accel_esp_create_xfrm(struct mlx5_core_dev *mdev,
123 const struct mlx5_accel_esp_xfrm_attrs *attrs,
124 u32 flags);
125void mlx5_accel_esp_destroy_xfrm(struct mlx5_accel_esp_xfrm *xfrm);
126int mlx5_accel_esp_modify_xfrm(struct mlx5_accel_esp_xfrm *xfrm,
127 const struct mlx5_accel_esp_xfrm_attrs *attrs);
128
129#else
130
131static inline u32 mlx5_accel_ipsec_device_caps(struct mlx5_core_dev *mdev) { return 0; }
132
133static inline struct mlx5_accel_esp_xfrm *
134mlx5_accel_esp_create_xfrm(struct mlx5_core_dev *mdev,
135 const struct mlx5_accel_esp_xfrm_attrs *attrs,
136 u32 flags) { return ERR_PTR(-EOPNOTSUPP); }
137static inline void
138mlx5_accel_esp_destroy_xfrm(struct mlx5_accel_esp_xfrm *xfrm) {}
139static inline int
140mlx5_accel_esp_modify_xfrm(struct mlx5_accel_esp_xfrm *xfrm,
141 const struct mlx5_accel_esp_xfrm_attrs *attrs) { return -EOPNOTSUPP; }
142
143#endif
144#endif
diff --git a/include/linux/mlx5/cq.h b/include/linux/mlx5/cq.h
index 48c181a2acc9..445ad194e0fe 100644
--- a/include/linux/mlx5/cq.h
+++ b/include/linux/mlx5/cq.h
@@ -60,6 +60,7 @@ struct mlx5_core_cq {
60 } tasklet_ctx; 60 } tasklet_ctx;
61 int reset_notify_added; 61 int reset_notify_added;
62 struct list_head reset_notify; 62 struct list_head reset_notify;
63 struct mlx5_eq *eq;
63}; 64};
64 65
65 66
@@ -171,8 +172,17 @@ static inline void mlx5_cq_arm(struct mlx5_core_cq *cq, u32 cmd,
171 mlx5_write64(doorbell, uar_page + MLX5_CQ_DOORBELL, NULL); 172 mlx5_write64(doorbell, uar_page + MLX5_CQ_DOORBELL, NULL);
172} 173}
173 174
174int mlx5_init_cq_table(struct mlx5_core_dev *dev); 175static inline void mlx5_cq_hold(struct mlx5_core_cq *cq)
175void mlx5_cleanup_cq_table(struct mlx5_core_dev *dev); 176{
177 refcount_inc(&cq->refcount);
178}
179
180static inline void mlx5_cq_put(struct mlx5_core_cq *cq)
181{
182 if (refcount_dec_and_test(&cq->refcount))
183 complete(&cq->free);
184}
185
176int mlx5_core_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq, 186int mlx5_core_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
177 u32 *in, int inlen); 187 u32 *in, int inlen);
178int mlx5_core_destroy_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq); 188int mlx5_core_destroy_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq);
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
index 9d3a03364e6e..cded85ab6fe4 100644
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@ -345,13 +345,6 @@ struct mlx5_buf_list {
345 dma_addr_t map; 345 dma_addr_t map;
346}; 346};
347 347
348struct mlx5_buf {
349 struct mlx5_buf_list direct;
350 int npages;
351 int size;
352 u8 page_shift;
353};
354
355struct mlx5_frag_buf { 348struct mlx5_frag_buf {
356 struct mlx5_buf_list *frags; 349 struct mlx5_buf_list *frags;
357 int npages; 350 int npages;
@@ -359,6 +352,15 @@ struct mlx5_frag_buf {
359 u8 page_shift; 352 u8 page_shift;
360}; 353};
361 354
355struct mlx5_frag_buf_ctrl {
356 struct mlx5_frag_buf frag_buf;
357 u32 sz_m1;
358 u32 frag_sz_m1;
359 u8 log_sz;
360 u8 log_stride;
361 u8 log_frag_strides;
362};
363
362struct mlx5_eq_tasklet { 364struct mlx5_eq_tasklet {
363 struct list_head list; 365 struct list_head list;
364 struct list_head process_list; 366 struct list_head process_list;
@@ -375,11 +377,18 @@ struct mlx5_eq_pagefault {
375 mempool_t *pool; 377 mempool_t *pool;
376}; 378};
377 379
380struct mlx5_cq_table {
381 /* protect radix tree */
382 spinlock_t lock;
383 struct radix_tree_root tree;
384};
385
378struct mlx5_eq { 386struct mlx5_eq {
379 struct mlx5_core_dev *dev; 387 struct mlx5_core_dev *dev;
388 struct mlx5_cq_table cq_table;
380 __be32 __iomem *doorbell; 389 __be32 __iomem *doorbell;
381 u32 cons_index; 390 u32 cons_index;
382 struct mlx5_buf buf; 391 struct mlx5_frag_buf buf;
383 int size; 392 int size;
384 unsigned int irqn; 393 unsigned int irqn;
385 u8 eqn; 394 u8 eqn;
@@ -526,13 +535,6 @@ struct mlx5_core_health {
526 struct delayed_work recover_work; 535 struct delayed_work recover_work;
527}; 536};
528 537
529struct mlx5_cq_table {
530 /* protect radix tree
531 */
532 spinlock_t lock;
533 struct radix_tree_root tree;
534};
535
536struct mlx5_qp_table { 538struct mlx5_qp_table {
537 /* protect radix tree 539 /* protect radix tree
538 */ 540 */
@@ -654,10 +656,6 @@ struct mlx5_priv {
654 struct dentry *cmdif_debugfs; 656 struct dentry *cmdif_debugfs;
655 /* end: qp staff */ 657 /* end: qp staff */
656 658
657 /* start: cq staff */
658 struct mlx5_cq_table cq_table;
659 /* end: cq staff */
660
661 /* start: mkey staff */ 659 /* start: mkey staff */
662 struct mlx5_mkey_table mkey_table; 660 struct mlx5_mkey_table mkey_table;
663 /* end: mkey staff */ 661 /* end: mkey staff */
@@ -936,9 +934,9 @@ struct mlx5_hca_vport_context {
936 bool grh_required; 934 bool grh_required;
937}; 935};
938 936
939static inline void *mlx5_buf_offset(struct mlx5_buf *buf, int offset) 937static inline void *mlx5_buf_offset(struct mlx5_frag_buf *buf, int offset)
940{ 938{
941 return buf->direct.buf + offset; 939 return buf->frags->buf + offset;
942} 940}
943 941
944#define STRUCT_FIELD(header, field) \ 942#define STRUCT_FIELD(header, field) \
@@ -977,6 +975,25 @@ static inline u32 mlx5_base_mkey(const u32 key)
977 return key & 0xffffff00u; 975 return key & 0xffffff00u;
978} 976}
979 977
978static inline void mlx5_core_init_cq_frag_buf(struct mlx5_frag_buf_ctrl *fbc,
979 void *cqc)
980{
981 fbc->log_stride = 6 + MLX5_GET(cqc, cqc, cqe_sz);
982 fbc->log_sz = MLX5_GET(cqc, cqc, log_cq_size);
983 fbc->sz_m1 = (1 << fbc->log_sz) - 1;
984 fbc->log_frag_strides = PAGE_SHIFT - fbc->log_stride;
985 fbc->frag_sz_m1 = (1 << fbc->log_frag_strides) - 1;
986}
987
988static inline void *mlx5_frag_buf_get_wqe(struct mlx5_frag_buf_ctrl *fbc,
989 u32 ix)
990{
991 unsigned int frag = (ix >> fbc->log_frag_strides);
992
993 return fbc->frag_buf.frags[frag].buf +
994 ((fbc->frag_sz_m1 & ix) << fbc->log_stride);
995}
996
980int mlx5_cmd_init(struct mlx5_core_dev *dev); 997int mlx5_cmd_init(struct mlx5_core_dev *dev);
981void mlx5_cmd_cleanup(struct mlx5_core_dev *dev); 998void mlx5_cmd_cleanup(struct mlx5_core_dev *dev);
982void mlx5_cmd_use_events(struct mlx5_core_dev *dev); 999void mlx5_cmd_use_events(struct mlx5_core_dev *dev);
@@ -1002,9 +1019,10 @@ void mlx5_drain_health_wq(struct mlx5_core_dev *dev);
1002void mlx5_trigger_health_work(struct mlx5_core_dev *dev); 1019void mlx5_trigger_health_work(struct mlx5_core_dev *dev);
1003void mlx5_drain_health_recovery(struct mlx5_core_dev *dev); 1020void mlx5_drain_health_recovery(struct mlx5_core_dev *dev);
1004int mlx5_buf_alloc_node(struct mlx5_core_dev *dev, int size, 1021int mlx5_buf_alloc_node(struct mlx5_core_dev *dev, int size,
1005 struct mlx5_buf *buf, int node); 1022 struct mlx5_frag_buf *buf, int node);
1006int mlx5_buf_alloc(struct mlx5_core_dev *dev, int size, struct mlx5_buf *buf); 1023int mlx5_buf_alloc(struct mlx5_core_dev *dev,
1007void mlx5_buf_free(struct mlx5_core_dev *dev, struct mlx5_buf *buf); 1024 int size, struct mlx5_frag_buf *buf);
1025void mlx5_buf_free(struct mlx5_core_dev *dev, struct mlx5_frag_buf *buf);
1008int mlx5_frag_buf_alloc_node(struct mlx5_core_dev *dev, int size, 1026int mlx5_frag_buf_alloc_node(struct mlx5_core_dev *dev, int size,
1009 struct mlx5_frag_buf *buf, int node); 1027 struct mlx5_frag_buf *buf, int node);
1010void mlx5_frag_buf_free(struct mlx5_core_dev *dev, struct mlx5_frag_buf *buf); 1028void mlx5_frag_buf_free(struct mlx5_core_dev *dev, struct mlx5_frag_buf *buf);
@@ -1049,22 +1067,12 @@ int mlx5_satisfy_startup_pages(struct mlx5_core_dev *dev, int boot);
1049int mlx5_reclaim_startup_pages(struct mlx5_core_dev *dev); 1067int mlx5_reclaim_startup_pages(struct mlx5_core_dev *dev);
1050void mlx5_register_debugfs(void); 1068void mlx5_register_debugfs(void);
1051void mlx5_unregister_debugfs(void); 1069void mlx5_unregister_debugfs(void);
1052int mlx5_eq_init(struct mlx5_core_dev *dev); 1070
1053void mlx5_eq_cleanup(struct mlx5_core_dev *dev); 1071void mlx5_fill_page_array(struct mlx5_frag_buf *buf, __be64 *pas);
1054void mlx5_fill_page_array(struct mlx5_buf *buf, __be64 *pas);
1055void mlx5_fill_page_frag_array(struct mlx5_frag_buf *frag_buf, __be64 *pas); 1072void mlx5_fill_page_frag_array(struct mlx5_frag_buf *frag_buf, __be64 *pas);
1056void mlx5_cq_completion(struct mlx5_core_dev *dev, u32 cqn);
1057void mlx5_rsc_event(struct mlx5_core_dev *dev, u32 rsn, int event_type); 1073void mlx5_rsc_event(struct mlx5_core_dev *dev, u32 rsn, int event_type);
1058void mlx5_srq_event(struct mlx5_core_dev *dev, u32 srqn, int event_type); 1074void mlx5_srq_event(struct mlx5_core_dev *dev, u32 srqn, int event_type);
1059struct mlx5_core_srq *mlx5_core_get_srq(struct mlx5_core_dev *dev, u32 srqn); 1075struct mlx5_core_srq *mlx5_core_get_srq(struct mlx5_core_dev *dev, u32 srqn);
1060void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool forced);
1061void mlx5_cq_event(struct mlx5_core_dev *dev, u32 cqn, int event_type);
1062int mlx5_create_map_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq, u8 vecidx,
1063 int nent, u64 mask, const char *name,
1064 enum mlx5_eq_type type);
1065int mlx5_destroy_unmap_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq);
1066int mlx5_start_eqs(struct mlx5_core_dev *dev);
1067void mlx5_stop_eqs(struct mlx5_core_dev *dev);
1068int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn, 1076int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn,
1069 unsigned int *irqn); 1077 unsigned int *irqn);
1070int mlx5_core_attach_mcg(struct mlx5_core_dev *dev, union ib_gid *mgid, u32 qpn); 1078int mlx5_core_attach_mcg(struct mlx5_core_dev *dev, union ib_gid *mgid, u32 qpn);
@@ -1076,14 +1084,6 @@ int mlx5_core_access_reg(struct mlx5_core_dev *dev, void *data_in,
1076 int size_in, void *data_out, int size_out, 1084 int size_in, void *data_out, int size_out,
1077 u16 reg_num, int arg, int write); 1085 u16 reg_num, int arg, int write);
1078 1086
1079int mlx5_debug_eq_add(struct mlx5_core_dev *dev, struct mlx5_eq *eq);
1080void mlx5_debug_eq_remove(struct mlx5_core_dev *dev, struct mlx5_eq *eq);
1081int mlx5_core_eq_query(struct mlx5_core_dev *dev, struct mlx5_eq *eq,
1082 u32 *out, int outlen);
1083int mlx5_eq_debugfs_init(struct mlx5_core_dev *dev);
1084void mlx5_eq_debugfs_cleanup(struct mlx5_core_dev *dev);
1085int mlx5_cq_debugfs_init(struct mlx5_core_dev *dev);
1086void mlx5_cq_debugfs_cleanup(struct mlx5_core_dev *dev);
1087int mlx5_db_alloc(struct mlx5_core_dev *dev, struct mlx5_db *db); 1087int mlx5_db_alloc(struct mlx5_core_dev *dev, struct mlx5_db *db);
1088int mlx5_db_alloc_node(struct mlx5_core_dev *dev, struct mlx5_db *db, 1088int mlx5_db_alloc_node(struct mlx5_core_dev *dev, struct mlx5_db *db,
1089 int node); 1089 int node);
@@ -1224,6 +1224,12 @@ static inline int mlx5_core_is_pf(struct mlx5_core_dev *dev)
1224 return !(dev->priv.pci_dev_data & MLX5_PCI_DEV_IS_VF); 1224 return !(dev->priv.pci_dev_data & MLX5_PCI_DEV_IS_VF);
1225} 1225}
1226 1226
1227#define MLX5_TOTAL_VPORTS(mdev) (1 + pci_sriov_get_totalvfs((mdev)->pdev))
1228#define MLX5_VPORT_MANAGER(mdev) \
1229 (MLX5_CAP_GEN(mdev, vport_group_manager) && \
1230 (MLX5_CAP_GEN(mdev, port_type) == MLX5_CAP_PORT_TYPE_ETH) && \
1231 mlx5_core_is_pf(mdev))
1232
1227static inline int mlx5_get_gid_table_len(u16 param) 1233static inline int mlx5_get_gid_table_len(u16 param)
1228{ 1234{
1229 if (param > 4) { 1235 if (param > 4) {
diff --git a/include/linux/mlx5/eswitch.h b/include/linux/mlx5/eswitch.h
new file mode 100644
index 000000000000..d3c9db492b30
--- /dev/null
+++ b/include/linux/mlx5/eswitch.h
@@ -0,0 +1,58 @@
1/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
2/*
3 * Copyright (c) 2018 Mellanox Technologies. All rights reserved.
4 */
5
6#ifndef _MLX5_ESWITCH_
7#define _MLX5_ESWITCH_
8
9#include <linux/mlx5/driver.h>
10
11enum {
12 SRIOV_NONE,
13 SRIOV_LEGACY,
14 SRIOV_OFFLOADS
15};
16
17enum {
18 REP_ETH,
19 REP_IB,
20 NUM_REP_TYPES,
21};
22
23struct mlx5_eswitch_rep;
24struct mlx5_eswitch_rep_if {
25 int (*load)(struct mlx5_core_dev *dev,
26 struct mlx5_eswitch_rep *rep);
27 void (*unload)(struct mlx5_eswitch_rep *rep);
28 void *(*get_proto_dev)(struct mlx5_eswitch_rep *rep);
29 void *priv;
30 bool valid;
31};
32
33struct mlx5_eswitch_rep {
34 struct mlx5_eswitch_rep_if rep_if[NUM_REP_TYPES];
35 u16 vport;
36 u8 hw_id[ETH_ALEN];
37 u16 vlan;
38 u32 vlan_refcount;
39};
40
41void mlx5_eswitch_register_vport_rep(struct mlx5_eswitch *esw,
42 int vport_index,
43 struct mlx5_eswitch_rep_if *rep_if,
44 u8 rep_type);
45void mlx5_eswitch_unregister_vport_rep(struct mlx5_eswitch *esw,
46 int vport_index,
47 u8 rep_type);
48void *mlx5_eswitch_get_proto_dev(struct mlx5_eswitch *esw,
49 int vport,
50 u8 rep_type);
51struct mlx5_eswitch_rep *mlx5_eswitch_vport_rep(struct mlx5_eswitch *esw,
52 int vport);
53void *mlx5_eswitch_uplink_get_proto_dev(struct mlx5_eswitch *esw, u8 rep_type);
54u8 mlx5_eswitch_mode(struct mlx5_eswitch *esw);
55struct mlx5_flow_handle *
56mlx5_eswitch_add_send_to_vport_rule(struct mlx5_eswitch *esw,
57 int vport, u32 sqn);
58#endif
diff --git a/include/linux/mlx5/fs.h b/include/linux/mlx5/fs.h
index a0b48afcb422..b957e52434f8 100644
--- a/include/linux/mlx5/fs.h
+++ b/include/linux/mlx5/fs.h
@@ -40,6 +40,8 @@
40 40
41enum { 41enum {
42 MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO = 1 << 16, 42 MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO = 1 << 16,
43 MLX5_FLOW_CONTEXT_ACTION_ENCRYPT = 1 << 17,
44 MLX5_FLOW_CONTEXT_ACTION_DECRYPT = 1 << 18,
43}; 45};
44 46
45enum { 47enum {
@@ -69,6 +71,7 @@ enum mlx5_flow_namespace_type {
69 MLX5_FLOW_NAMESPACE_ESW_INGRESS, 71 MLX5_FLOW_NAMESPACE_ESW_INGRESS,
70 MLX5_FLOW_NAMESPACE_SNIFFER_RX, 72 MLX5_FLOW_NAMESPACE_SNIFFER_RX,
71 MLX5_FLOW_NAMESPACE_SNIFFER_TX, 73 MLX5_FLOW_NAMESPACE_SNIFFER_TX,
74 MLX5_FLOW_NAMESPACE_EGRESS,
72}; 75};
73 76
74struct mlx5_flow_table; 77struct mlx5_flow_table;
@@ -141,9 +144,11 @@ void mlx5_destroy_flow_group(struct mlx5_flow_group *fg);
141 144
142struct mlx5_flow_act { 145struct mlx5_flow_act {
143 u32 action; 146 u32 action;
147 bool has_flow_tag;
144 u32 flow_tag; 148 u32 flow_tag;
145 u32 encap_id; 149 u32 encap_id;
146 u32 modify_id; 150 u32 modify_id;
151 uintptr_t esp_id;
147}; 152};
148 153
149#define MLX5_DECLARE_FLOW_ACT(name) \ 154#define MLX5_DECLARE_FLOW_ACT(name) \
diff --git a/include/linux/mlx5/fs_helpers.h b/include/linux/mlx5/fs_helpers.h
new file mode 100644
index 000000000000..7b476bbae731
--- /dev/null
+++ b/include/linux/mlx5/fs_helpers.h
@@ -0,0 +1,134 @@
1/*
2 * Copyright (c) 2018, Mellanox Technologies. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 */
32
33#ifndef _MLX5_FS_HELPERS_
34#define _MLX5_FS_HELPERS_
35
36#include <linux/mlx5/mlx5_ifc.h>
37
38#define MLX5_FS_IPV4_VERSION 4
39#define MLX5_FS_IPV6_VERSION 6
40
41static inline bool _mlx5_fs_is_outer_ipproto_flow(const u32 *match_c,
42 const u32 *match_v, u8 match)
43{
44 const void *headers_c = MLX5_ADDR_OF(fte_match_param, match_c,
45 outer_headers);
46 const void *headers_v = MLX5_ADDR_OF(fte_match_param, match_v,
47 outer_headers);
48
49 return MLX5_GET(fte_match_set_lyr_2_4, headers_c, ip_protocol) == 0xff &&
50 MLX5_GET(fte_match_set_lyr_2_4, headers_v, ip_protocol) == match;
51}
52
53static inline bool mlx5_fs_is_outer_tcp_flow(const u32 *match_c,
54 const u32 *match_v)
55{
56 return _mlx5_fs_is_outer_ipproto_flow(match_c, match_v, IPPROTO_TCP);
57}
58
59static inline bool mlx5_fs_is_outer_udp_flow(const u32 *match_c,
60 const u32 *match_v)
61{
62 return _mlx5_fs_is_outer_ipproto_flow(match_c, match_v, IPPROTO_UDP);
63}
64
65static inline bool mlx5_fs_is_vxlan_flow(const u32 *match_c)
66{
67 void *misc_params_c = MLX5_ADDR_OF(fte_match_param, match_c,
68 misc_parameters);
69
70 return MLX5_GET(fte_match_set_misc, misc_params_c, vxlan_vni);
71}
72
73static inline bool _mlx5_fs_is_outer_ipv_flow(struct mlx5_core_dev *mdev,
74 const u32 *match_c,
75 const u32 *match_v, int version)
76{
77 int match_ipv = MLX5_CAP_FLOWTABLE_NIC_RX(mdev,
78 ft_field_support.outer_ip_version);
79 const void *headers_c = MLX5_ADDR_OF(fte_match_param, match_c,
80 outer_headers);
81 const void *headers_v = MLX5_ADDR_OF(fte_match_param, match_v,
82 outer_headers);
83
84 if (!match_ipv) {
85 u16 ethertype;
86
87 switch (version) {
88 case MLX5_FS_IPV4_VERSION:
89 ethertype = ETH_P_IP;
90 break;
91 case MLX5_FS_IPV6_VERSION:
92 ethertype = ETH_P_IPV6;
93 break;
94 default:
95 return false;
96 }
97
98 return MLX5_GET(fte_match_set_lyr_2_4, headers_c,
99 ethertype) == 0xffff &&
100 MLX5_GET(fte_match_set_lyr_2_4, headers_v,
101 ethertype) == ethertype;
102 }
103
104 return MLX5_GET(fte_match_set_lyr_2_4, headers_c,
105 ip_version) == 0xf &&
106 MLX5_GET(fte_match_set_lyr_2_4, headers_v,
107 ip_version) == version;
108}
109
110static inline bool
111mlx5_fs_is_outer_ipv4_flow(struct mlx5_core_dev *mdev, const u32 *match_c,
112 const u32 *match_v)
113{
114 return _mlx5_fs_is_outer_ipv_flow(mdev, match_c, match_v,
115 MLX5_FS_IPV4_VERSION);
116}
117
118static inline bool
119mlx5_fs_is_outer_ipv6_flow(struct mlx5_core_dev *mdev, const u32 *match_c,
120 const u32 *match_v)
121{
122 return _mlx5_fs_is_outer_ipv_flow(mdev, match_c, match_v,
123 MLX5_FS_IPV6_VERSION);
124}
125
126static inline bool mlx5_fs_is_outer_ipsec_flow(const u32 *match_c)
127{
128 void *misc_params_c =
129 MLX5_ADDR_OF(fte_match_param, match_c, misc_parameters);
130
131 return MLX5_GET(fte_match_set_misc, misc_params_c, outer_esp_spi);
132}
133
134#endif
diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
index f4e417686f62..14ad84afe8ba 100644
--- a/include/linux/mlx5/mlx5_ifc.h
+++ b/include/linux/mlx5/mlx5_ifc.h
@@ -295,7 +295,9 @@ struct mlx5_ifc_flow_table_fields_supported_bits {
295 u8 inner_tcp_dport[0x1]; 295 u8 inner_tcp_dport[0x1];
296 u8 inner_tcp_flags[0x1]; 296 u8 inner_tcp_flags[0x1];
297 u8 reserved_at_37[0x9]; 297 u8 reserved_at_37[0x9];
298 u8 reserved_at_40[0x1a]; 298 u8 reserved_at_40[0x17];
299 u8 outer_esp_spi[0x1];
300 u8 reserved_at_58[0x2];
299 u8 bth_dst_qp[0x1]; 301 u8 bth_dst_qp[0x1];
300 302
301 u8 reserved_at_5b[0x25]; 303 u8 reserved_at_5b[0x25];
@@ -437,7 +439,9 @@ struct mlx5_ifc_fte_match_set_misc_bits {
437 439
438 u8 reserved_at_120[0x28]; 440 u8 reserved_at_120[0x28];
439 u8 bth_dst_qp[0x18]; 441 u8 bth_dst_qp[0x18];
440 u8 reserved_at_160[0xa0]; 442 u8 reserved_at_160[0x20];
443 u8 outer_esp_spi[0x20];
444 u8 reserved_at_1a0[0x60];
441}; 445};
442 446
443struct mlx5_ifc_cmd_pas_bits { 447struct mlx5_ifc_cmd_pas_bits {
@@ -1091,6 +1095,7 @@ enum mlx5_flow_destination_type {
1091 MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE = 0x1, 1095 MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE = 0x1,
1092 MLX5_FLOW_DESTINATION_TYPE_TIR = 0x2, 1096 MLX5_FLOW_DESTINATION_TYPE_TIR = 0x2,
1093 1097
1098 MLX5_FLOW_DESTINATION_TYPE_PORT = 0x99,
1094 MLX5_FLOW_DESTINATION_TYPE_COUNTER = 0x100, 1099 MLX5_FLOW_DESTINATION_TYPE_COUNTER = 0x100,
1095}; 1100};
1096 1101
diff --git a/include/linux/mlx5/mlx5_ifc_fpga.h b/include/linux/mlx5/mlx5_ifc_fpga.h
index 255a88d08078..ec052491ba3d 100644
--- a/include/linux/mlx5/mlx5_ifc_fpga.h
+++ b/include/linux/mlx5/mlx5_ifc_fpga.h
@@ -373,7 +373,10 @@ struct mlx5_ifc_fpga_destroy_qp_out_bits {
373struct mlx5_ifc_ipsec_extended_cap_bits { 373struct mlx5_ifc_ipsec_extended_cap_bits {
374 u8 encapsulation[0x20]; 374 u8 encapsulation[0x20];
375 375
376 u8 reserved_0[0x15]; 376 u8 reserved_0[0x12];
377 u8 v2_command[0x1];
378 u8 udp_encap[0x1];
379 u8 rx_no_trailer[0x1];
377 u8 ipv4_fragment[0x1]; 380 u8 ipv4_fragment[0x1];
378 u8 ipv6[0x1]; 381 u8 ipv6[0x1];
379 u8 esn[0x1]; 382 u8 esn[0x1];
@@ -429,4 +432,91 @@ struct mlx5_ifc_ipsec_counters_bits {
429 u8 dropped_cmd[0x40]; 432 u8 dropped_cmd[0x40];
430}; 433};
431 434
435enum mlx5_ifc_fpga_ipsec_response_syndrome {
436 MLX5_FPGA_IPSEC_RESPONSE_SUCCESS = 0,
437 MLX5_FPGA_IPSEC_RESPONSE_ILLEGAL_REQUEST = 1,
438 MLX5_FPGA_IPSEC_RESPONSE_SADB_ISSUE = 2,
439 MLX5_FPGA_IPSEC_RESPONSE_WRITE_RESPONSE_ISSUE = 3,
440};
441
442struct mlx5_ifc_fpga_ipsec_cmd_resp {
443 __be32 syndrome;
444 union {
445 __be32 sw_sa_handle;
446 __be32 flags;
447 };
448 u8 reserved[24];
449} __packed;
450
451enum mlx5_ifc_fpga_ipsec_cmd_opcode {
452 MLX5_FPGA_IPSEC_CMD_OP_ADD_SA = 0,
453 MLX5_FPGA_IPSEC_CMD_OP_DEL_SA = 1,
454 MLX5_FPGA_IPSEC_CMD_OP_ADD_SA_V2 = 2,
455 MLX5_FPGA_IPSEC_CMD_OP_DEL_SA_V2 = 3,
456 MLX5_FPGA_IPSEC_CMD_OP_MOD_SA_V2 = 4,
457 MLX5_FPGA_IPSEC_CMD_OP_SET_CAP = 5,
458};
459
460enum mlx5_ifc_fpga_ipsec_cap {
461 MLX5_FPGA_IPSEC_CAP_NO_TRAILER = BIT(0),
462};
463
464struct mlx5_ifc_fpga_ipsec_cmd_cap {
465 __be32 cmd;
466 __be32 flags;
467 u8 reserved[24];
468} __packed;
469
470enum mlx5_ifc_fpga_ipsec_sa_flags {
471 MLX5_FPGA_IPSEC_SA_ESN_EN = BIT(0),
472 MLX5_FPGA_IPSEC_SA_ESN_OVERLAP = BIT(1),
473 MLX5_FPGA_IPSEC_SA_IPV6 = BIT(2),
474 MLX5_FPGA_IPSEC_SA_DIR_SX = BIT(3),
475 MLX5_FPGA_IPSEC_SA_SPI_EN = BIT(4),
476 MLX5_FPGA_IPSEC_SA_SA_VALID = BIT(5),
477 MLX5_FPGA_IPSEC_SA_IP_ESP = BIT(6),
478 MLX5_FPGA_IPSEC_SA_IP_AH = BIT(7),
479};
480
481enum mlx5_ifc_fpga_ipsec_sa_enc_mode {
482 MLX5_FPGA_IPSEC_SA_ENC_MODE_NONE = 0,
483 MLX5_FPGA_IPSEC_SA_ENC_MODE_AES_GCM_128_AUTH_128 = 1,
484 MLX5_FPGA_IPSEC_SA_ENC_MODE_AES_GCM_256_AUTH_128 = 3,
485};
486
487struct mlx5_ifc_fpga_ipsec_sa_v1 {
488 __be32 cmd;
489 u8 key_enc[32];
490 u8 key_auth[32];
491 __be32 sip[4];
492 __be32 dip[4];
493 union {
494 struct {
495 __be32 reserved;
496 u8 salt_iv[8];
497 __be32 salt;
498 } __packed gcm;
499 struct {
500 u8 salt[16];
501 } __packed cbc;
502 };
503 __be32 spi;
504 __be32 sw_sa_handle;
505 __be16 tfclen;
506 u8 enc_mode;
507 u8 reserved1[2];
508 u8 flags;
509 u8 reserved2[2];
510};
511
512struct mlx5_ifc_fpga_ipsec_sa {
513 struct mlx5_ifc_fpga_ipsec_sa_v1 ipsec_sa_v1;
514 __be16 udp_sp;
515 __be16 udp_dp;
516 u8 reserved1[4];
517 __be32 esn;
518 __be16 vid; /* only 12 bits, rest is reserved */
519 __be16 reserved2;
520} __packed;
521
432#endif /* MLX5_IFC_FPGA_H */ 522#endif /* MLX5_IFC_FPGA_H */
diff --git a/include/linux/mroute.h b/include/linux/mroute.h
index 5396521a776a..7ed82e4f11b3 100644
--- a/include/linux/mroute.h
+++ b/include/linux/mroute.h
@@ -4,11 +4,10 @@
4 4
5#include <linux/in.h> 5#include <linux/in.h>
6#include <linux/pim.h> 6#include <linux/pim.h>
7#include <linux/rhashtable.h>
8#include <net/sock.h>
9#include <net/fib_rules.h> 7#include <net/fib_rules.h>
10#include <net/fib_notifier.h> 8#include <net/fib_notifier.h>
11#include <uapi/linux/mroute.h> 9#include <uapi/linux/mroute.h>
10#include <linux/mroute_base.h>
12 11
13#ifdef CONFIG_IP_MROUTE 12#ifdef CONFIG_IP_MROUTE
14static inline int ip_mroute_opt(int opt) 13static inline int ip_mroute_opt(int opt)
@@ -56,18 +55,6 @@ static inline bool ipmr_rule_default(const struct fib_rule *rule)
56} 55}
57#endif 56#endif
58 57
59struct vif_device {
60 struct net_device *dev; /* Device we are using */
61 struct netdev_phys_item_id dev_parent_id; /* Device parent ID */
62 unsigned long bytes_in,bytes_out;
63 unsigned long pkt_in,pkt_out; /* Statistics */
64 unsigned long rate_limit; /* Traffic shaping (NI) */
65 unsigned char threshold; /* TTL threshold */
66 unsigned short flags; /* Control flags */
67 __be32 local,remote; /* Addresses(remote for tunnels)*/
68 int link; /* Physical interface index */
69};
70
71struct vif_entry_notifier_info { 58struct vif_entry_notifier_info {
72 struct fib_notifier_info info; 59 struct fib_notifier_info info;
73 struct net_device *dev; 60 struct net_device *dev;
@@ -78,34 +65,6 @@ struct vif_entry_notifier_info {
78 65
79#define VIFF_STATIC 0x8000 66#define VIFF_STATIC 0x8000
80 67
81#define VIF_EXISTS(_mrt, _idx) ((_mrt)->vif_table[_idx].dev != NULL)
82
83struct mr_table {
84 struct list_head list;
85 possible_net_t net;
86 u32 id;
87 struct sock __rcu *mroute_sk;
88 struct timer_list ipmr_expire_timer;
89 struct list_head mfc_unres_queue;
90 struct vif_device vif_table[MAXVIFS];
91 struct rhltable mfc_hash;
92 struct list_head mfc_cache_list;
93 int maxvif;
94 atomic_t cache_resolve_queue_len;
95 bool mroute_do_assert;
96 bool mroute_do_pim;
97 int mroute_reg_vif_num;
98};
99
100/* mfc_flags:
101 * MFC_STATIC - the entry was added statically (not by a routing daemon)
102 * MFC_OFFLOAD - the entry was offloaded to the hardware
103 */
104enum {
105 MFC_STATIC = BIT(0),
106 MFC_OFFLOAD = BIT(1),
107};
108
109struct mfc_cache_cmp_arg { 68struct mfc_cache_cmp_arg {
110 __be32 mfc_mcastgrp; 69 __be32 mfc_mcastgrp;
111 __be32 mfc_origin; 70 __be32 mfc_origin;
@@ -113,28 +72,13 @@ struct mfc_cache_cmp_arg {
113 72
114/** 73/**
115 * struct mfc_cache - multicast routing entries 74 * struct mfc_cache - multicast routing entries
116 * @mnode: rhashtable list 75 * @_c: Common multicast routing information; has to be first [for casting]
117 * @mfc_mcastgrp: destination multicast group address 76 * @mfc_mcastgrp: destination multicast group address
118 * @mfc_origin: source address 77 * @mfc_origin: source address
119 * @cmparg: used for rhashtable comparisons 78 * @cmparg: used for rhashtable comparisons
120 * @mfc_parent: source interface (iif)
121 * @mfc_flags: entry flags
122 * @expires: unresolved entry expire time
123 * @unresolved: unresolved cached skbs
124 * @last_assert: time of last assert
125 * @minvif: minimum VIF id
126 * @maxvif: maximum VIF id
127 * @bytes: bytes that have passed for this entry
128 * @pkt: packets that have passed for this entry
129 * @wrong_if: number of wrong source interface hits
130 * @lastuse: time of last use of the group (traffic or update)
131 * @ttls: OIF TTL threshold array
132 * @refcount: reference count for this entry
133 * @list: global entry list
134 * @rcu: used for entry destruction
135 */ 79 */
136struct mfc_cache { 80struct mfc_cache {
137 struct rhlist_head mnode; 81 struct mr_mfc _c;
138 union { 82 union {
139 struct { 83 struct {
140 __be32 mfc_mcastgrp; 84 __be32 mfc_mcastgrp;
@@ -142,28 +86,6 @@ struct mfc_cache {
142 }; 86 };
143 struct mfc_cache_cmp_arg cmparg; 87 struct mfc_cache_cmp_arg cmparg;
144 }; 88 };
145 vifi_t mfc_parent;
146 int mfc_flags;
147
148 union {
149 struct {
150 unsigned long expires;
151 struct sk_buff_head unresolved;
152 } unres;
153 struct {
154 unsigned long last_assert;
155 int minvif;
156 int maxvif;
157 unsigned long bytes;
158 unsigned long pkt;
159 unsigned long wrong_if;
160 unsigned long lastuse;
161 unsigned char ttls[MAXVIFS];
162 refcount_t refcount;
163 } res;
164 } mfc_un;
165 struct list_head list;
166 struct rcu_head rcu;
167}; 89};
168 90
169struct mfc_entry_notifier_info { 91struct mfc_entry_notifier_info {
@@ -187,12 +109,12 @@ static inline void ipmr_cache_free(struct mfc_cache *mfc_cache)
187 109
188static inline void ipmr_cache_put(struct mfc_cache *c) 110static inline void ipmr_cache_put(struct mfc_cache *c)
189{ 111{
190 if (refcount_dec_and_test(&c->mfc_un.res.refcount)) 112 if (refcount_dec_and_test(&c->_c.mfc_un.res.refcount))
191 ipmr_cache_free(c); 113 ipmr_cache_free(c);
192} 114}
193static inline void ipmr_cache_hold(struct mfc_cache *c) 115static inline void ipmr_cache_hold(struct mfc_cache *c)
194{ 116{
195 refcount_inc(&c->mfc_un.res.refcount); 117 refcount_inc(&c->_c.mfc_un.res.refcount);
196} 118}
197 119
198#endif 120#endif
diff --git a/include/linux/mroute6.h b/include/linux/mroute6.h
index 3014c52bfd86..1ac38e6819f5 100644
--- a/include/linux/mroute6.h
+++ b/include/linux/mroute6.h
@@ -7,6 +7,7 @@
7#include <linux/skbuff.h> /* for struct sk_buff_head */ 7#include <linux/skbuff.h> /* for struct sk_buff_head */
8#include <net/net_namespace.h> 8#include <net/net_namespace.h>
9#include <uapi/linux/mroute6.h> 9#include <uapi/linux/mroute6.h>
10#include <linux/mroute_base.h>
10 11
11#ifdef CONFIG_IPV6_MROUTE 12#ifdef CONFIG_IPV6_MROUTE
12static inline int ip6_mroute_opt(int opt) 13static inline int ip6_mroute_opt(int opt)
@@ -62,57 +63,24 @@ static inline void ip6_mr_cleanup(void)
62} 63}
63#endif 64#endif
64 65
65struct mif_device {
66 struct net_device *dev; /* Device we are using */
67 unsigned long bytes_in,bytes_out;
68 unsigned long pkt_in,pkt_out; /* Statistics */
69 unsigned long rate_limit; /* Traffic shaping (NI) */
70 unsigned char threshold; /* TTL threshold */
71 unsigned short flags; /* Control flags */
72 int link; /* Physical interface index */
73};
74
75#define VIFF_STATIC 0x8000 66#define VIFF_STATIC 0x8000
76 67
77struct mfc6_cache { 68struct mfc6_cache_cmp_arg {
78 struct list_head list; 69 struct in6_addr mf6c_mcastgrp;
79 struct in6_addr mf6c_mcastgrp; /* Group the entry belongs to */ 70 struct in6_addr mf6c_origin;
80 struct in6_addr mf6c_origin; /* Source of packet */ 71};
81 mifi_t mf6c_parent; /* Source interface */
82 int mfc_flags; /* Flags on line */
83 72
73struct mfc6_cache {
74 struct mr_mfc _c;
84 union { 75 union {
85 struct { 76 struct {
86 unsigned long expires; 77 struct in6_addr mf6c_mcastgrp;
87 struct sk_buff_head unresolved; /* Unresolved buffers */ 78 struct in6_addr mf6c_origin;
88 } unres; 79 };
89 struct { 80 struct mfc6_cache_cmp_arg cmparg;
90 unsigned long last_assert; 81 };
91 int minvif;
92 int maxvif;
93 unsigned long bytes;
94 unsigned long pkt;
95 unsigned long wrong_if;
96 unsigned long lastuse;
97 unsigned char ttls[MAXMIFS]; /* TTL thresholds */
98 } res;
99 } mfc_un;
100}; 82};
101 83
102#define MFC_STATIC 1
103#define MFC_NOTIFY 2
104
105#define MFC6_LINES 64
106
107#define MFC6_HASH(a, g) (((__force u32)(a)->s6_addr32[0] ^ \
108 (__force u32)(a)->s6_addr32[1] ^ \
109 (__force u32)(a)->s6_addr32[2] ^ \
110 (__force u32)(a)->s6_addr32[3] ^ \
111 (__force u32)(g)->s6_addr32[0] ^ \
112 (__force u32)(g)->s6_addr32[1] ^ \
113 (__force u32)(g)->s6_addr32[2] ^ \
114 (__force u32)(g)->s6_addr32[3]) % MFC6_LINES)
115
116#define MFC_ASSERT_THRESH (3*HZ) /* Maximal freq. of asserts */ 84#define MFC_ASSERT_THRESH (3*HZ) /* Maximal freq. of asserts */
117 85
118struct rtmsg; 86struct rtmsg;
@@ -120,12 +88,12 @@ extern int ip6mr_get_route(struct net *net, struct sk_buff *skb,
120 struct rtmsg *rtm, u32 portid); 88 struct rtmsg *rtm, u32 portid);
121 89
122#ifdef CONFIG_IPV6_MROUTE 90#ifdef CONFIG_IPV6_MROUTE
123extern struct sock *mroute6_socket(struct net *net, struct sk_buff *skb); 91bool mroute6_is_socket(struct net *net, struct sk_buff *skb);
124extern int ip6mr_sk_done(struct sock *sk); 92extern int ip6mr_sk_done(struct sock *sk);
125#else 93#else
126static inline struct sock *mroute6_socket(struct net *net, struct sk_buff *skb) 94static inline bool mroute6_is_socket(struct net *net, struct sk_buff *skb)
127{ 95{
128 return NULL; 96 return false;
129} 97}
130static inline int ip6mr_sk_done(struct sock *sk) 98static inline int ip6mr_sk_done(struct sock *sk)
131{ 99{
diff --git a/include/linux/mroute_base.h b/include/linux/mroute_base.h
new file mode 100644
index 000000000000..c2560cb50f1d
--- /dev/null
+++ b/include/linux/mroute_base.h
@@ -0,0 +1,346 @@
1#ifndef __LINUX_MROUTE_BASE_H
2#define __LINUX_MROUTE_BASE_H
3
4#include <linux/netdevice.h>
5#include <linux/rhashtable.h>
6#include <linux/spinlock.h>
7#include <net/net_namespace.h>
8#include <net/sock.h>
9
10/**
11 * struct vif_device - interface representor for multicast routing
12 * @dev: network device being used
13 * @bytes_in: statistic; bytes ingressing
14 * @bytes_out: statistic; bytes egresing
15 * @pkt_in: statistic; packets ingressing
16 * @pkt_out: statistic; packets egressing
17 * @rate_limit: Traffic shaping (NI)
18 * @threshold: TTL threshold
19 * @flags: Control flags
20 * @link: Physical interface index
21 * @dev_parent_id: device parent id
22 * @local: Local address
23 * @remote: Remote address for tunnels
24 */
25struct vif_device {
26 struct net_device *dev;
27 unsigned long bytes_in, bytes_out;
28 unsigned long pkt_in, pkt_out;
29 unsigned long rate_limit;
30 unsigned char threshold;
31 unsigned short flags;
32 int link;
33
34 /* Currently only used by ipmr */
35 struct netdev_phys_item_id dev_parent_id;
36 __be32 local, remote;
37};
38
39#ifndef MAXVIFS
40/* This one is nasty; value is defined in uapi using different symbols for
41 * mroute and morute6 but both map into same 32.
42 */
43#define MAXVIFS 32
44#endif
45
46#define VIF_EXISTS(_mrt, _idx) (!!((_mrt)->vif_table[_idx].dev))
47
48/* mfc_flags:
49 * MFC_STATIC - the entry was added statically (not by a routing daemon)
50 * MFC_OFFLOAD - the entry was offloaded to the hardware
51 */
52enum {
53 MFC_STATIC = BIT(0),
54 MFC_OFFLOAD = BIT(1),
55};
56
57/**
58 * struct mr_mfc - common multicast routing entries
59 * @mnode: rhashtable list
60 * @mfc_parent: source interface (iif)
61 * @mfc_flags: entry flags
62 * @expires: unresolved entry expire time
63 * @unresolved: unresolved cached skbs
64 * @last_assert: time of last assert
65 * @minvif: minimum VIF id
66 * @maxvif: maximum VIF id
67 * @bytes: bytes that have passed for this entry
68 * @pkt: packets that have passed for this entry
69 * @wrong_if: number of wrong source interface hits
70 * @lastuse: time of last use of the group (traffic or update)
71 * @ttls: OIF TTL threshold array
72 * @refcount: reference count for this entry
73 * @list: global entry list
74 * @rcu: used for entry destruction
75 */
76struct mr_mfc {
77 struct rhlist_head mnode;
78 unsigned short mfc_parent;
79 int mfc_flags;
80
81 union {
82 struct {
83 unsigned long expires;
84 struct sk_buff_head unresolved;
85 } unres;
86 struct {
87 unsigned long last_assert;
88 int minvif;
89 int maxvif;
90 unsigned long bytes;
91 unsigned long pkt;
92 unsigned long wrong_if;
93 unsigned long lastuse;
94 unsigned char ttls[MAXVIFS];
95 refcount_t refcount;
96 } res;
97 } mfc_un;
98 struct list_head list;
99 struct rcu_head rcu;
100};
101
102struct mr_table;
103
104/**
105 * struct mr_table_ops - callbacks and info for protocol-specific ops
106 * @rht_params: parameters for accessing the MFC hash
107 * @cmparg_any: a hash key to be used for matching on (*,*) routes
108 */
109struct mr_table_ops {
110 const struct rhashtable_params *rht_params;
111 void *cmparg_any;
112};
113
114/**
115 * struct mr_table - a multicast routing table
116 * @list: entry within a list of multicast routing tables
117 * @net: net where this table belongs
118 * @ops: protocol specific operations
119 * @id: identifier of the table
120 * @mroute_sk: socket associated with the table
121 * @ipmr_expire_timer: timer for handling unresolved routes
122 * @mfc_unres_queue: list of unresolved MFC entries
123 * @vif_table: array containing all possible vifs
124 * @mfc_hash: Hash table of all resolved routes for easy lookup
125 * @mfc_cache_list: list of resovled routes for possible traversal
126 * @maxvif: Identifier of highest value vif currently in use
127 * @cache_resolve_queue_len: current size of unresolved queue
128 * @mroute_do_assert: Whether to inform userspace on wrong ingress
129 * @mroute_do_pim: Whether to receive IGMP PIMv1
130 * @mroute_reg_vif_num: PIM-device vif index
131 */
132struct mr_table {
133 struct list_head list;
134 possible_net_t net;
135 struct mr_table_ops ops;
136 u32 id;
137 struct sock __rcu *mroute_sk;
138 struct timer_list ipmr_expire_timer;
139 struct list_head mfc_unres_queue;
140 struct vif_device vif_table[MAXVIFS];
141 struct rhltable mfc_hash;
142 struct list_head mfc_cache_list;
143 int maxvif;
144 atomic_t cache_resolve_queue_len;
145 bool mroute_do_assert;
146 bool mroute_do_pim;
147 int mroute_reg_vif_num;
148};
149
150#ifdef CONFIG_IP_MROUTE_COMMON
151void vif_device_init(struct vif_device *v,
152 struct net_device *dev,
153 unsigned long rate_limit,
154 unsigned char threshold,
155 unsigned short flags,
156 unsigned short get_iflink_mask);
157
158struct mr_table *
159mr_table_alloc(struct net *net, u32 id,
160 struct mr_table_ops *ops,
161 void (*expire_func)(struct timer_list *t),
162 void (*table_set)(struct mr_table *mrt,
163 struct net *net));
164
165/* These actually return 'struct mr_mfc *', but to avoid need for explicit
166 * castings they simply return void.
167 */
168void *mr_mfc_find_parent(struct mr_table *mrt,
169 void *hasharg, int parent);
170void *mr_mfc_find_any_parent(struct mr_table *mrt, int vifi);
171void *mr_mfc_find_any(struct mr_table *mrt, int vifi, void *hasharg);
172
173int mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
174 struct mr_mfc *c, struct rtmsg *rtm);
175int mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb,
176 struct mr_table *(*iter)(struct net *net,
177 struct mr_table *mrt),
178 int (*fill)(struct mr_table *mrt,
179 struct sk_buff *skb,
180 u32 portid, u32 seq, struct mr_mfc *c,
181 int cmd, int flags),
182 spinlock_t *lock);
183#else
184static inline void vif_device_init(struct vif_device *v,
185 struct net_device *dev,
186 unsigned long rate_limit,
187 unsigned char threshold,
188 unsigned short flags,
189 unsigned short get_iflink_mask)
190{
191}
192
193static inline void *
194mr_table_alloc(struct net *net, u32 id,
195 struct mr_table_ops *ops,
196 void (*expire_func)(struct timer_list *t),
197 void (*table_set)(struct mr_table *mrt,
198 struct net *net))
199{
200 return NULL;
201}
202
203static inline void *mr_mfc_find_parent(struct mr_table *mrt,
204 void *hasharg, int parent)
205{
206 return NULL;
207}
208
209static inline void *mr_mfc_find_any_parent(struct mr_table *mrt,
210 int vifi)
211{
212 return NULL;
213}
214
215static inline struct mr_mfc *mr_mfc_find_any(struct mr_table *mrt,
216 int vifi, void *hasharg)
217{
218 return NULL;
219}
220
221static inline int mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
222 struct mr_mfc *c, struct rtmsg *rtm)
223{
224 return -EINVAL;
225}
226
227static inline int
228mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb,
229 struct mr_table *(*iter)(struct net *net,
230 struct mr_table *mrt),
231 int (*fill)(struct mr_table *mrt,
232 struct sk_buff *skb,
233 u32 portid, u32 seq, struct mr_mfc *c,
234 int cmd, int flags),
235 spinlock_t *lock)
236{
237 return -EINVAL;
238}
239#endif
240
241static inline void *mr_mfc_find(struct mr_table *mrt, void *hasharg)
242{
243 return mr_mfc_find_parent(mrt, hasharg, -1);
244}
245
246#ifdef CONFIG_PROC_FS
247struct mr_vif_iter {
248 struct seq_net_private p;
249 struct mr_table *mrt;
250 int ct;
251};
252
253struct mr_mfc_iter {
254 struct seq_net_private p;
255 struct mr_table *mrt;
256 struct list_head *cache;
257
258 /* Lock protecting the mr_table's unresolved queue */
259 spinlock_t *lock;
260};
261
262#ifdef CONFIG_IP_MROUTE_COMMON
263void *mr_vif_seq_idx(struct net *net, struct mr_vif_iter *iter, loff_t pos);
264void *mr_vif_seq_next(struct seq_file *seq, void *v, loff_t *pos);
265
266static inline void *mr_vif_seq_start(struct seq_file *seq, loff_t *pos)
267{
268 return *pos ? mr_vif_seq_idx(seq_file_net(seq),
269 seq->private, *pos - 1)
270 : SEQ_START_TOKEN;
271}
272
273/* These actually return 'struct mr_mfc *', but to avoid need for explicit
274 * castings they simply return void.
275 */
276void *mr_mfc_seq_idx(struct net *net,
277 struct mr_mfc_iter *it, loff_t pos);
278void *mr_mfc_seq_next(struct seq_file *seq, void *v,
279 loff_t *pos);
280
281static inline void *mr_mfc_seq_start(struct seq_file *seq, loff_t *pos,
282 struct mr_table *mrt, spinlock_t *lock)
283{
284 struct mr_mfc_iter *it = seq->private;
285
286 it->mrt = mrt;
287 it->cache = NULL;
288 it->lock = lock;
289
290 return *pos ? mr_mfc_seq_idx(seq_file_net(seq),
291 seq->private, *pos - 1)
292 : SEQ_START_TOKEN;
293}
294
295static inline void mr_mfc_seq_stop(struct seq_file *seq, void *v)
296{
297 struct mr_mfc_iter *it = seq->private;
298 struct mr_table *mrt = it->mrt;
299
300 if (it->cache == &mrt->mfc_unres_queue)
301 spin_unlock_bh(it->lock);
302 else if (it->cache == &mrt->mfc_cache_list)
303 rcu_read_unlock();
304}
305#else
306static inline void *mr_vif_seq_idx(struct net *net, struct mr_vif_iter *iter,
307 loff_t pos)
308{
309 return NULL;
310}
311
312static inline void *mr_vif_seq_next(struct seq_file *seq,
313 void *v, loff_t *pos)
314{
315 return NULL;
316}
317
318static inline void *mr_vif_seq_start(struct seq_file *seq, loff_t *pos)
319{
320 return NULL;
321}
322
323static inline void *mr_mfc_seq_idx(struct net *net,
324 struct mr_mfc_iter *it, loff_t pos)
325{
326 return NULL;
327}
328
329static inline void *mr_mfc_seq_next(struct seq_file *seq, void *v,
330 loff_t *pos)
331{
332 return NULL;
333}
334
335static inline void *mr_mfc_seq_start(struct seq_file *seq, loff_t *pos,
336 struct mr_table *mrt, spinlock_t *lock)
337{
338 return NULL;
339}
340
341static inline void mr_mfc_seq_stop(struct seq_file *seq, void *v)
342{
343}
344#endif
345#endif
346#endif
diff --git a/include/linux/net.h b/include/linux/net.h
index 2a0391eea05c..2248a052061d 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -146,7 +146,7 @@ struct proto_ops {
146 struct socket *newsock, int flags, bool kern); 146 struct socket *newsock, int flags, bool kern);
147 int (*getname) (struct socket *sock, 147 int (*getname) (struct socket *sock,
148 struct sockaddr *addr, 148 struct sockaddr *addr,
149 int *sockaddr_len, int peer); 149 int peer);
150 __poll_t (*poll) (struct file *file, struct socket *sock, 150 __poll_t (*poll) (struct file *file, struct socket *sock,
151 struct poll_table_struct *wait); 151 struct poll_table_struct *wait);
152 int (*ioctl) (struct socket *sock, unsigned int cmd, 152 int (*ioctl) (struct socket *sock, unsigned int cmd,
@@ -295,10 +295,8 @@ int kernel_listen(struct socket *sock, int backlog);
295int kernel_accept(struct socket *sock, struct socket **newsock, int flags); 295int kernel_accept(struct socket *sock, struct socket **newsock, int flags);
296int kernel_connect(struct socket *sock, struct sockaddr *addr, int addrlen, 296int kernel_connect(struct socket *sock, struct sockaddr *addr, int addrlen,
297 int flags); 297 int flags);
298int kernel_getsockname(struct socket *sock, struct sockaddr *addr, 298int kernel_getsockname(struct socket *sock, struct sockaddr *addr);
299 int *addrlen); 299int kernel_getpeername(struct socket *sock, struct sockaddr *addr);
300int kernel_getpeername(struct socket *sock, struct sockaddr *addr,
301 int *addrlen);
302int kernel_getsockopt(struct socket *sock, int level, int optname, char *optval, 300int kernel_getsockopt(struct socket *sock, int level, int optname, char *optval,
303 int *optlen); 301 int *optlen);
304int kernel_setsockopt(struct socket *sock, int level, int optname, char *optval, 302int kernel_setsockopt(struct socket *sock, int level, int optname, char *optval,
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 5eef6c8e2741..913b1cc882cf 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -585,6 +585,15 @@ struct netdev_queue {
585#endif 585#endif
586} ____cacheline_aligned_in_smp; 586} ____cacheline_aligned_in_smp;
587 587
588extern int sysctl_fb_tunnels_only_for_init_net;
589
590static inline bool net_has_fallback_tunnels(const struct net *net)
591{
592 return net == &init_net ||
593 !IS_ENABLED(CONFIG_SYSCTL) ||
594 !sysctl_fb_tunnels_only_for_init_net;
595}
596
588static inline int netdev_queue_numa_node_read(const struct netdev_queue *q) 597static inline int netdev_queue_numa_node_read(const struct netdev_queue *q)
589{ 598{
590#if defined(CONFIG_XPS) && defined(CONFIG_NUMA) 599#if defined(CONFIG_XPS) && defined(CONFIG_NUMA)
@@ -1381,8 +1390,6 @@ struct net_device_ops {
1381 * @IFF_MACVLAN: Macvlan device 1390 * @IFF_MACVLAN: Macvlan device
1382 * @IFF_XMIT_DST_RELEASE_PERM: IFF_XMIT_DST_RELEASE not taking into account 1391 * @IFF_XMIT_DST_RELEASE_PERM: IFF_XMIT_DST_RELEASE not taking into account
1383 * underlying stacked devices 1392 * underlying stacked devices
1384 * @IFF_IPVLAN_MASTER: IPvlan master device
1385 * @IFF_IPVLAN_SLAVE: IPvlan slave device
1386 * @IFF_L3MDEV_MASTER: device is an L3 master device 1393 * @IFF_L3MDEV_MASTER: device is an L3 master device
1387 * @IFF_NO_QUEUE: device can run without qdisc attached 1394 * @IFF_NO_QUEUE: device can run without qdisc attached
1388 * @IFF_OPENVSWITCH: device is a Open vSwitch master 1395 * @IFF_OPENVSWITCH: device is a Open vSwitch master
@@ -1392,6 +1399,7 @@ struct net_device_ops {
1392 * @IFF_PHONY_HEADROOM: the headroom value is controlled by an external 1399 * @IFF_PHONY_HEADROOM: the headroom value is controlled by an external
1393 * entity (i.e. the master device for bridged veth) 1400 * entity (i.e. the master device for bridged veth)
1394 * @IFF_MACSEC: device is a MACsec device 1401 * @IFF_MACSEC: device is a MACsec device
1402 * @IFF_NO_RX_HANDLER: device doesn't support the rx_handler hook
1395 */ 1403 */
1396enum netdev_priv_flags { 1404enum netdev_priv_flags {
1397 IFF_802_1Q_VLAN = 1<<0, 1405 IFF_802_1Q_VLAN = 1<<0,
@@ -1412,16 +1420,15 @@ enum netdev_priv_flags {
1412 IFF_LIVE_ADDR_CHANGE = 1<<15, 1420 IFF_LIVE_ADDR_CHANGE = 1<<15,
1413 IFF_MACVLAN = 1<<16, 1421 IFF_MACVLAN = 1<<16,
1414 IFF_XMIT_DST_RELEASE_PERM = 1<<17, 1422 IFF_XMIT_DST_RELEASE_PERM = 1<<17,
1415 IFF_IPVLAN_MASTER = 1<<18, 1423 IFF_L3MDEV_MASTER = 1<<18,
1416 IFF_IPVLAN_SLAVE = 1<<19, 1424 IFF_NO_QUEUE = 1<<19,
1417 IFF_L3MDEV_MASTER = 1<<20, 1425 IFF_OPENVSWITCH = 1<<20,
1418 IFF_NO_QUEUE = 1<<21, 1426 IFF_L3MDEV_SLAVE = 1<<21,
1419 IFF_OPENVSWITCH = 1<<22, 1427 IFF_TEAM = 1<<22,
1420 IFF_L3MDEV_SLAVE = 1<<23, 1428 IFF_RXFH_CONFIGURED = 1<<23,
1421 IFF_TEAM = 1<<24, 1429 IFF_PHONY_HEADROOM = 1<<24,
1422 IFF_RXFH_CONFIGURED = 1<<25, 1430 IFF_MACSEC = 1<<25,
1423 IFF_PHONY_HEADROOM = 1<<26, 1431 IFF_NO_RX_HANDLER = 1<<26,
1424 IFF_MACSEC = 1<<27,
1425}; 1432};
1426 1433
1427#define IFF_802_1Q_VLAN IFF_802_1Q_VLAN 1434#define IFF_802_1Q_VLAN IFF_802_1Q_VLAN
@@ -1442,8 +1449,6 @@ enum netdev_priv_flags {
1442#define IFF_LIVE_ADDR_CHANGE IFF_LIVE_ADDR_CHANGE 1449#define IFF_LIVE_ADDR_CHANGE IFF_LIVE_ADDR_CHANGE
1443#define IFF_MACVLAN IFF_MACVLAN 1450#define IFF_MACVLAN IFF_MACVLAN
1444#define IFF_XMIT_DST_RELEASE_PERM IFF_XMIT_DST_RELEASE_PERM 1451#define IFF_XMIT_DST_RELEASE_PERM IFF_XMIT_DST_RELEASE_PERM
1445#define IFF_IPVLAN_MASTER IFF_IPVLAN_MASTER
1446#define IFF_IPVLAN_SLAVE IFF_IPVLAN_SLAVE
1447#define IFF_L3MDEV_MASTER IFF_L3MDEV_MASTER 1452#define IFF_L3MDEV_MASTER IFF_L3MDEV_MASTER
1448#define IFF_NO_QUEUE IFF_NO_QUEUE 1453#define IFF_NO_QUEUE IFF_NO_QUEUE
1449#define IFF_OPENVSWITCH IFF_OPENVSWITCH 1454#define IFF_OPENVSWITCH IFF_OPENVSWITCH
@@ -1451,6 +1456,7 @@ enum netdev_priv_flags {
1451#define IFF_TEAM IFF_TEAM 1456#define IFF_TEAM IFF_TEAM
1452#define IFF_RXFH_CONFIGURED IFF_RXFH_CONFIGURED 1457#define IFF_RXFH_CONFIGURED IFF_RXFH_CONFIGURED
1453#define IFF_MACSEC IFF_MACSEC 1458#define IFF_MACSEC IFF_MACSEC
1459#define IFF_NO_RX_HANDLER IFF_NO_RX_HANDLER
1454 1460
1455/** 1461/**
1456 * struct net_device - The DEVICE structure. 1462 * struct net_device - The DEVICE structure.
@@ -1798,11 +1804,17 @@ struct net_device {
1798#if IS_ENABLED(CONFIG_TIPC) 1804#if IS_ENABLED(CONFIG_TIPC)
1799 struct tipc_bearer __rcu *tipc_ptr; 1805 struct tipc_bearer __rcu *tipc_ptr;
1800#endif 1806#endif
1807#if IS_ENABLED(CONFIG_IRDA) || IS_ENABLED(CONFIG_ATALK)
1801 void *atalk_ptr; 1808 void *atalk_ptr;
1809#endif
1802 struct in_device __rcu *ip_ptr; 1810 struct in_device __rcu *ip_ptr;
1811#if IS_ENABLED(CONFIG_DECNET)
1803 struct dn_dev __rcu *dn_ptr; 1812 struct dn_dev __rcu *dn_ptr;
1813#endif
1804 struct inet6_dev __rcu *ip6_ptr; 1814 struct inet6_dev __rcu *ip6_ptr;
1815#if IS_ENABLED(CONFIG_AX25)
1805 void *ax25_ptr; 1816 void *ax25_ptr;
1817#endif
1806 struct wireless_dev *ieee80211_ptr; 1818 struct wireless_dev *ieee80211_ptr;
1807 struct wpan_dev *ieee802154_ptr; 1819 struct wpan_dev *ieee802154_ptr;
1808#if IS_ENABLED(CONFIG_MPLS_ROUTING) 1820#if IS_ENABLED(CONFIG_MPLS_ROUTING)
@@ -4217,16 +4229,6 @@ static inline bool netif_is_macvlan_port(const struct net_device *dev)
4217 return dev->priv_flags & IFF_MACVLAN_PORT; 4229 return dev->priv_flags & IFF_MACVLAN_PORT;
4218} 4230}
4219 4231
4220static inline bool netif_is_ipvlan(const struct net_device *dev)
4221{
4222 return dev->priv_flags & IFF_IPVLAN_SLAVE;
4223}
4224
4225static inline bool netif_is_ipvlan_port(const struct net_device *dev)
4226{
4227 return dev->priv_flags & IFF_IPVLAN_MASTER;
4228}
4229
4230static inline bool netif_is_bond_master(const struct net_device *dev) 4232static inline bool netif_is_bond_master(const struct net_device *dev)
4231{ 4233{
4232 return dev->flags & IFF_MASTER && dev->priv_flags & IFF_BONDING; 4234 return dev->flags & IFF_MASTER && dev->priv_flags & IFF_BONDING;
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 7c4c2379e010..f0b5870a6d40 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -999,6 +999,14 @@ int genphy_c45_pma_setup_forced(struct phy_device *phydev);
999int genphy_c45_an_disable_aneg(struct phy_device *phydev); 999int genphy_c45_an_disable_aneg(struct phy_device *phydev);
1000int genphy_c45_read_mdix(struct phy_device *phydev); 1000int genphy_c45_read_mdix(struct phy_device *phydev);
1001 1001
1002/* The gen10g_* functions are the old Clause 45 stub */
1003int gen10g_config_aneg(struct phy_device *phydev);
1004int gen10g_read_status(struct phy_device *phydev);
1005int gen10g_no_soft_reset(struct phy_device *phydev);
1006int gen10g_config_init(struct phy_device *phydev);
1007int gen10g_suspend(struct phy_device *phydev);
1008int gen10g_resume(struct phy_device *phydev);
1009
1002static inline int phy_read_status(struct phy_device *phydev) 1010static inline int phy_read_status(struct phy_device *phydev)
1003{ 1011{
1004 if (!phydev->drv) 1012 if (!phydev->drv)
diff --git a/include/linux/ptp_classify.h b/include/linux/ptp_classify.h
index a079656b614c..059242030631 100644
--- a/include/linux/ptp_classify.h
+++ b/include/linux/ptp_classify.h
@@ -75,5 +75,9 @@ void __init ptp_classifier_init(void);
75static inline void ptp_classifier_init(void) 75static inline void ptp_classifier_init(void)
76{ 76{
77} 77}
78static inline unsigned int ptp_classify_raw(struct sk_buff *skb)
79{
80 return PTP_CLASS_NONE;
81}
78#endif 82#endif
79#endif /* _PTP_CLASSIFY_H_ */ 83#endif /* _PTP_CLASSIFY_H_ */
diff --git a/include/linux/ptr_ring.h b/include/linux/ptr_ring.h
index e6335227b844..6894976b54e3 100644
--- a/include/linux/ptr_ring.h
+++ b/include/linux/ptr_ring.h
@@ -296,13 +296,14 @@ static inline void *__ptr_ring_consume(struct ptr_ring *r)
296{ 296{
297 void *ptr; 297 void *ptr;
298 298
299 /* The READ_ONCE in __ptr_ring_peek guarantees that anyone
300 * accessing data through the pointer is up to date. Pairs
301 * with smp_wmb in __ptr_ring_produce.
302 */
299 ptr = __ptr_ring_peek(r); 303 ptr = __ptr_ring_peek(r);
300 if (ptr) 304 if (ptr)
301 __ptr_ring_discard_one(r); 305 __ptr_ring_discard_one(r);
302 306
303 /* Make sure anyone accessing data through the pointer is up to date. */
304 /* Pairs with smp_wmb in __ptr_ring_produce. */
305 smp_read_barrier_depends();
306 return ptr; 307 return ptr;
307} 308}
308 309
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index 1fdcde96eb65..562a175c35a9 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -33,9 +33,10 @@ extern void rtnl_lock(void);
33extern void rtnl_unlock(void); 33extern void rtnl_unlock(void);
34extern int rtnl_trylock(void); 34extern int rtnl_trylock(void);
35extern int rtnl_is_locked(void); 35extern int rtnl_is_locked(void);
36extern int rtnl_lock_killable(void);
36 37
37extern wait_queue_head_t netdev_unregistering_wq; 38extern wait_queue_head_t netdev_unregistering_wq;
38extern struct mutex net_mutex; 39extern struct rw_semaphore net_sem;
39 40
40#ifdef CONFIG_PROVE_LOCKING 41#ifdef CONFIG_PROVE_LOCKING
41extern bool lockdep_rtnl_is_held(void); 42extern bool lockdep_rtnl_is_held(void);
diff --git a/include/linux/sfp.h b/include/linux/sfp.h
index e724d5a3dd80..ebce9e24906a 100644
--- a/include/linux/sfp.h
+++ b/include/linux/sfp.h
@@ -422,10 +422,11 @@ struct sfp_upstream_ops {
422#if IS_ENABLED(CONFIG_SFP) 422#if IS_ENABLED(CONFIG_SFP)
423int sfp_parse_port(struct sfp_bus *bus, const struct sfp_eeprom_id *id, 423int sfp_parse_port(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
424 unsigned long *support); 424 unsigned long *support);
425phy_interface_t sfp_parse_interface(struct sfp_bus *bus,
426 const struct sfp_eeprom_id *id);
427void sfp_parse_support(struct sfp_bus *bus, const struct sfp_eeprom_id *id, 425void sfp_parse_support(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
428 unsigned long *support); 426 unsigned long *support);
427phy_interface_t sfp_select_interface(struct sfp_bus *bus,
428 const struct sfp_eeprom_id *id,
429 unsigned long *link_modes);
429 430
430int sfp_get_module_info(struct sfp_bus *bus, struct ethtool_modinfo *modinfo); 431int sfp_get_module_info(struct sfp_bus *bus, struct ethtool_modinfo *modinfo);
431int sfp_get_module_eeprom(struct sfp_bus *bus, struct ethtool_eeprom *ee, 432int sfp_get_module_eeprom(struct sfp_bus *bus, struct ethtool_eeprom *ee,
@@ -444,18 +445,19 @@ static inline int sfp_parse_port(struct sfp_bus *bus,
444 return PORT_OTHER; 445 return PORT_OTHER;
445} 446}
446 447
447static inline phy_interface_t sfp_parse_interface(struct sfp_bus *bus,
448 const struct sfp_eeprom_id *id)
449{
450 return PHY_INTERFACE_MODE_NA;
451}
452
453static inline void sfp_parse_support(struct sfp_bus *bus, 448static inline void sfp_parse_support(struct sfp_bus *bus,
454 const struct sfp_eeprom_id *id, 449 const struct sfp_eeprom_id *id,
455 unsigned long *support) 450 unsigned long *support)
456{ 451{
457} 452}
458 453
454static inline phy_interface_t sfp_select_interface(struct sfp_bus *bus,
455 const struct sfp_eeprom_id *id,
456 unsigned long *link_modes)
457{
458 return PHY_INTERFACE_MODE_NA;
459}
460
459static inline int sfp_get_module_info(struct sfp_bus *bus, 461static inline int sfp_get_module_info(struct sfp_bus *bus,
460 struct ethtool_modinfo *modinfo) 462 struct ethtool_modinfo *modinfo)
461{ 463{
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 99df17109e1b..47082f54ec1f 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -466,6 +466,9 @@ struct ubuf_info {
466 466
467#define skb_uarg(SKB) ((struct ubuf_info *)(skb_shinfo(SKB)->destructor_arg)) 467#define skb_uarg(SKB) ((struct ubuf_info *)(skb_shinfo(SKB)->destructor_arg))
468 468
469int mm_account_pinned_pages(struct mmpin *mmp, size_t size);
470void mm_unaccount_pinned_pages(struct mmpin *mmp);
471
469struct ubuf_info *sock_zerocopy_alloc(struct sock *sk, size_t size); 472struct ubuf_info *sock_zerocopy_alloc(struct sock *sk, size_t size);
470struct ubuf_info *sock_zerocopy_realloc(struct sock *sk, size_t size, 473struct ubuf_info *sock_zerocopy_realloc(struct sock *sk, size_t size,
471 struct ubuf_info *uarg); 474 struct ubuf_info *uarg);
diff --git a/include/linux/socket.h b/include/linux/socket.h
index 9286a5a8c60c..60e01482a9c4 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -287,6 +287,7 @@ struct ucred {
287#define MSG_SENDPAGE_NOTLAST 0x20000 /* sendpage() internal : not the last page */ 287#define MSG_SENDPAGE_NOTLAST 0x20000 /* sendpage() internal : not the last page */
288#define MSG_BATCH 0x40000 /* sendmmsg(): more messages coming */ 288#define MSG_BATCH 0x40000 /* sendmmsg(): more messages coming */
289#define MSG_EOF MSG_FIN 289#define MSG_EOF MSG_FIN
290#define MSG_NO_SHARED_FRAGS 0x80000 /* sendpage() internal : page frags are not shared */
290 291
291#define MSG_ZEROCOPY 0x4000000 /* Use user data in kernel path */ 292#define MSG_ZEROCOPY 0x4000000 /* Use user data in kernel path */
292#define MSG_FASTOPEN 0x20000000 /* Send data in TCP SYN */ 293#define MSG_FASTOPEN 0x20000000 /* Send data in TCP SYN */
@@ -353,4 +354,6 @@ extern int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen
353 unsigned int flags, struct timespec *timeout); 354 unsigned int flags, struct timespec *timeout);
354extern int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, 355extern int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg,
355 unsigned int vlen, unsigned int flags); 356 unsigned int vlen, unsigned int flags);
357
358extern struct ns_common *get_net_ns(struct ns_common *ns);
356#endif /* _LINUX_SOCKET_H */ 359#endif /* _LINUX_SOCKET_H */
diff --git a/include/net/Space.h b/include/net/Space.h
index 27fb5c937c4f..9cce0d80d37a 100644
--- a/include/net/Space.h
+++ b/include/net/Space.h
@@ -20,8 +20,6 @@ struct net_device *cs89x0_probe(int unit);
20struct net_device *mvme147lance_probe(int unit); 20struct net_device *mvme147lance_probe(int unit);
21struct net_device *tc515_probe(int unit); 21struct net_device *tc515_probe(int unit);
22struct net_device *lance_probe(int unit); 22struct net_device *lance_probe(int unit);
23struct net_device *mac8390_probe(int unit);
24struct net_device *mac89x0_probe(int unit);
25struct net_device *cops_probe(int unit); 23struct net_device *cops_probe(int unit);
26struct net_device *ltpc_probe(void); 24struct net_device *ltpc_probe(void);
27 25
diff --git a/include/net/act_api.h b/include/net/act_api.h
index 6ed9692f20bd..e0a9c2003b24 100644
--- a/include/net/act_api.h
+++ b/include/net/act_api.h
@@ -87,13 +87,17 @@ struct tc_action_ops {
87 struct tcf_result *); 87 struct tcf_result *);
88 int (*dump)(struct sk_buff *, struct tc_action *, int, int); 88 int (*dump)(struct sk_buff *, struct tc_action *, int, int);
89 void (*cleanup)(struct tc_action *); 89 void (*cleanup)(struct tc_action *);
90 int (*lookup)(struct net *, struct tc_action **, u32); 90 int (*lookup)(struct net *net, struct tc_action **a, u32 index,
91 struct netlink_ext_ack *extack);
91 int (*init)(struct net *net, struct nlattr *nla, 92 int (*init)(struct net *net, struct nlattr *nla,
92 struct nlattr *est, struct tc_action **act, int ovr, 93 struct nlattr *est, struct tc_action **act, int ovr,
93 int bind); 94 int bind, struct netlink_ext_ack *extack);
94 int (*walk)(struct net *, struct sk_buff *, 95 int (*walk)(struct net *, struct sk_buff *,
95 struct netlink_callback *, int, const struct tc_action_ops *); 96 struct netlink_callback *, int,
97 const struct tc_action_ops *,
98 struct netlink_ext_ack *);
96 void (*stats_update)(struct tc_action *, u64, u32, u64); 99 void (*stats_update)(struct tc_action *, u64, u32, u64);
100 size_t (*get_fill_size)(const struct tc_action *act);
97 struct net_device *(*get_dev)(const struct tc_action *a); 101 struct net_device *(*get_dev)(const struct tc_action *a);
98}; 102};
99 103
@@ -137,7 +141,8 @@ static inline void tc_action_net_exit(struct list_head *net_list,
137 141
138int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb, 142int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb,
139 struct netlink_callback *cb, int type, 143 struct netlink_callback *cb, int type,
140 const struct tc_action_ops *ops); 144 const struct tc_action_ops *ops,
145 struct netlink_ext_ack *extack);
141int tcf_idr_search(struct tc_action_net *tn, struct tc_action **a, u32 index); 146int tcf_idr_search(struct tc_action_net *tn, struct tc_action **a, u32 index);
142bool tcf_idr_check(struct tc_action_net *tn, u32 index, struct tc_action **a, 147bool tcf_idr_check(struct tc_action_net *tn, u32 index, struct tc_action **a,
143 int bind); 148 int bind);
@@ -162,10 +167,12 @@ int tcf_action_exec(struct sk_buff *skb, struct tc_action **actions,
162 int nr_actions, struct tcf_result *res); 167 int nr_actions, struct tcf_result *res);
163int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla, 168int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
164 struct nlattr *est, char *name, int ovr, int bind, 169 struct nlattr *est, char *name, int ovr, int bind,
165 struct list_head *actions); 170 struct list_head *actions, size_t *attr_size,
171 struct netlink_ext_ack *extack);
166struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp, 172struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
167 struct nlattr *nla, struct nlattr *est, 173 struct nlattr *nla, struct nlattr *est,
168 char *name, int ovr, int bind); 174 char *name, int ovr, int bind,
175 struct netlink_ext_ack *extack);
169int tcf_action_dump(struct sk_buff *skb, struct list_head *, int, int); 176int tcf_action_dump(struct sk_buff *skb, struct list_head *, int, int);
170int tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int, int); 177int tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int, int);
171int tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int, int); 178int tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int, int);
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index c4185a7b0e90..132e5b95167a 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -69,8 +69,8 @@ int addrconf_set_dstaddr(struct net *net, void __user *arg);
69int ipv6_chk_addr(struct net *net, const struct in6_addr *addr, 69int ipv6_chk_addr(struct net *net, const struct in6_addr *addr,
70 const struct net_device *dev, int strict); 70 const struct net_device *dev, int strict);
71int ipv6_chk_addr_and_flags(struct net *net, const struct in6_addr *addr, 71int ipv6_chk_addr_and_flags(struct net *net, const struct in6_addr *addr,
72 const struct net_device *dev, int strict, 72 const struct net_device *dev, bool skip_dev_check,
73 u32 banned_flags); 73 int strict, u32 banned_flags);
74 74
75#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) 75#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
76int ipv6_chk_home_addr(struct net *net, const struct in6_addr *addr); 76int ipv6_chk_home_addr(struct net *net, const struct in6_addr *addr);
diff --git a/include/net/ax25.h b/include/net/ax25.h
index 76fb39c272a7..c91bc87931c7 100644
--- a/include/net/ax25.h
+++ b/include/net/ax25.h
@@ -318,10 +318,12 @@ void ax25_digi_invert(const ax25_digi *, ax25_digi *);
318extern ax25_dev *ax25_dev_list; 318extern ax25_dev *ax25_dev_list;
319extern spinlock_t ax25_dev_lock; 319extern spinlock_t ax25_dev_lock;
320 320
321#if IS_ENABLED(CONFIG_AX25)
321static inline ax25_dev *ax25_dev_ax25dev(struct net_device *dev) 322static inline ax25_dev *ax25_dev_ax25dev(struct net_device *dev)
322{ 323{
323 return dev->ax25_ptr; 324 return dev->ax25_ptr;
324} 325}
326#endif
325 327
326ax25_dev *ax25_addr_ax25dev(ax25_address *); 328ax25_dev *ax25_addr_ax25dev(ax25_address *);
327void ax25_dev_device_up(struct net_device *); 329void ax25_dev_device_up(struct net_device *);
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 81174f9b8d14..fc40843baed3 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1147,6 +1147,7 @@ struct cfg80211_tid_stats {
1147 * @rx_duration: aggregate PPDU duration(usecs) for all the frames from a peer 1147 * @rx_duration: aggregate PPDU duration(usecs) for all the frames from a peer
1148 * @pertid: per-TID statistics, see &struct cfg80211_tid_stats, using the last 1148 * @pertid: per-TID statistics, see &struct cfg80211_tid_stats, using the last
1149 * (IEEE80211_NUM_TIDS) index for MSDUs not encapsulated in QoS-MPDUs. 1149 * (IEEE80211_NUM_TIDS) index for MSDUs not encapsulated in QoS-MPDUs.
1150 * @ack_signal: signal strength (in dBm) of the last ACK frame.
1150 */ 1151 */
1151struct station_info { 1152struct station_info {
1152 u64 filled; 1153 u64 filled;
@@ -1191,6 +1192,7 @@ struct station_info {
1191 u64 rx_duration; 1192 u64 rx_duration;
1192 u8 rx_beacon_signal_avg; 1193 u8 rx_beacon_signal_avg;
1193 struct cfg80211_tid_stats pertid[IEEE80211_NUM_TIDS + 1]; 1194 struct cfg80211_tid_stats pertid[IEEE80211_NUM_TIDS + 1];
1195 s8 ack_signal;
1194}; 1196};
1195 1197
1196#if IS_ENABLED(CONFIG_CFG80211) 1198#if IS_ENABLED(CONFIG_CFG80211)
@@ -1905,11 +1907,16 @@ struct cfg80211_auth_request {
1905 * @ASSOC_REQ_DISABLE_HT: Disable HT (802.11n) 1907 * @ASSOC_REQ_DISABLE_HT: Disable HT (802.11n)
1906 * @ASSOC_REQ_DISABLE_VHT: Disable VHT 1908 * @ASSOC_REQ_DISABLE_VHT: Disable VHT
1907 * @ASSOC_REQ_USE_RRM: Declare RRM capability in this association 1909 * @ASSOC_REQ_USE_RRM: Declare RRM capability in this association
1910 * @CONNECT_REQ_EXTERNAL_AUTH_SUPPORT: User space indicates external
1911 * authentication capability. Drivers can offload authentication to
1912 * userspace if this flag is set. Only applicable for cfg80211_connect()
1913 * request (connect callback).
1908 */ 1914 */
1909enum cfg80211_assoc_req_flags { 1915enum cfg80211_assoc_req_flags {
1910 ASSOC_REQ_DISABLE_HT = BIT(0), 1916 ASSOC_REQ_DISABLE_HT = BIT(0),
1911 ASSOC_REQ_DISABLE_VHT = BIT(1), 1917 ASSOC_REQ_DISABLE_VHT = BIT(1),
1912 ASSOC_REQ_USE_RRM = BIT(2), 1918 ASSOC_REQ_USE_RRM = BIT(2),
1919 CONNECT_REQ_EXTERNAL_AUTH_SUPPORT = BIT(3),
1913}; 1920};
1914 1921
1915/** 1922/**
@@ -2601,6 +2608,33 @@ struct cfg80211_pmk_conf {
2601}; 2608};
2602 2609
2603/** 2610/**
2611 * struct cfg80211_external_auth_params - Trigger External authentication.
2612 *
2613 * Commonly used across the external auth request and event interfaces.
2614 *
2615 * @action: action type / trigger for external authentication. Only significant
2616 * for the authentication request event interface (driver to user space).
2617 * @bssid: BSSID of the peer with which the authentication has
2618 * to happen. Used by both the authentication request event and
2619 * authentication response command interface.
2620 * @ssid: SSID of the AP. Used by both the authentication request event and
2621 * authentication response command interface.
2622 * @key_mgmt_suite: AKM suite of the respective authentication. Used by the
2623 * authentication request event interface.
2624 * @status: status code, %WLAN_STATUS_SUCCESS for successful authentication,
2625 * use %WLAN_STATUS_UNSPECIFIED_FAILURE if user space cannot give you
2626 * the real status code for failures. Used only for the authentication
2627 * response command interface (user space to driver).
2628 */
2629struct cfg80211_external_auth_params {
2630 enum nl80211_external_auth_action action;
2631 u8 bssid[ETH_ALEN] __aligned(2);
2632 struct cfg80211_ssid ssid;
2633 unsigned int key_mgmt_suite;
2634 u16 status;
2635};
2636
2637/**
2604 * struct cfg80211_ops - backend description for wireless configuration 2638 * struct cfg80211_ops - backend description for wireless configuration
2605 * 2639 *
2606 * This struct is registered by fullmac card drivers and/or wireless stacks 2640 * This struct is registered by fullmac card drivers and/or wireless stacks
@@ -2923,6 +2957,9 @@ struct cfg80211_pmk_conf {
2923 * (invoked with the wireless_dev mutex held) 2957 * (invoked with the wireless_dev mutex held)
2924 * @del_pmk: delete the previously configured PMK for the given authenticator. 2958 * @del_pmk: delete the previously configured PMK for the given authenticator.
2925 * (invoked with the wireless_dev mutex held) 2959 * (invoked with the wireless_dev mutex held)
2960 *
2961 * @external_auth: indicates result of offloaded authentication processing from
2962 * user space
2926 */ 2963 */
2927struct cfg80211_ops { 2964struct cfg80211_ops {
2928 int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); 2965 int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -3216,6 +3253,8 @@ struct cfg80211_ops {
3216 const struct cfg80211_pmk_conf *conf); 3253 const struct cfg80211_pmk_conf *conf);
3217 int (*del_pmk)(struct wiphy *wiphy, struct net_device *dev, 3254 int (*del_pmk)(struct wiphy *wiphy, struct net_device *dev,
3218 const u8 *aa); 3255 const u8 *aa);
3256 int (*external_auth)(struct wiphy *wiphy, struct net_device *dev,
3257 struct cfg80211_external_auth_params *params);
3219}; 3258};
3220 3259
3221/* 3260/*
@@ -3517,6 +3556,35 @@ enum wiphy_vendor_command_flags {
3517}; 3556};
3518 3557
3519/** 3558/**
3559 * enum wiphy_opmode_flag - Station's ht/vht operation mode information flags
3560 *
3561 * @STA_OPMODE_MAX_BW_CHANGED: Max Bandwidth changed
3562 * @STA_OPMODE_SMPS_MODE_CHANGED: SMPS mode changed
3563 * @STA_OPMODE_N_SS_CHANGED: max N_SS (number of spatial streams) changed
3564 *
3565 */
3566enum wiphy_opmode_flag {
3567 STA_OPMODE_MAX_BW_CHANGED = BIT(0),
3568 STA_OPMODE_SMPS_MODE_CHANGED = BIT(1),
3569 STA_OPMODE_N_SS_CHANGED = BIT(2),
3570};
3571
3572/**
3573 * struct sta_opmode_info - Station's ht/vht operation mode information
3574 * @changed: contains value from &enum wiphy_opmode_flag
3575 * @smps_mode: New SMPS mode of a station
3576 * @bw: new max bandwidth value of a station
3577 * @rx_nss: new rx_nss value of a station
3578 */
3579
3580struct sta_opmode_info {
3581 u32 changed;
3582 u8 smps_mode;
3583 u8 bw;
3584 u8 rx_nss;
3585};
3586
3587/**
3520 * struct wiphy_vendor_command - vendor command definition 3588 * struct wiphy_vendor_command - vendor command definition
3521 * @info: vendor command identifying information, as used in nl80211 3589 * @info: vendor command identifying information, as used in nl80211
3522 * @flags: flags, see &enum wiphy_vendor_command_flags 3590 * @flags: flags, see &enum wiphy_vendor_command_flags
@@ -4342,10 +4410,12 @@ unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr);
4342 * of it being pushed into the SKB 4410 * of it being pushed into the SKB
4343 * @addr: the device MAC address 4411 * @addr: the device MAC address
4344 * @iftype: the virtual interface type 4412 * @iftype: the virtual interface type
4413 * @data_offset: offset of payload after the 802.11 header
4345 * Return: 0 on success. Non-zero on error. 4414 * Return: 0 on success. Non-zero on error.
4346 */ 4415 */
4347int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr, 4416int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr,
4348 const u8 *addr, enum nl80211_iftype iftype); 4417 const u8 *addr, enum nl80211_iftype iftype,
4418 u8 data_offset);
4349 4419
4350/** 4420/**
4351 * ieee80211_data_to_8023 - convert an 802.11 data frame to 802.3 4421 * ieee80211_data_to_8023 - convert an 802.11 data frame to 802.3
@@ -4357,7 +4427,7 @@ int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr,
4357static inline int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, 4427static inline int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
4358 enum nl80211_iftype iftype) 4428 enum nl80211_iftype iftype)
4359{ 4429{
4360 return ieee80211_data_to_8023_exthdr(skb, NULL, addr, iftype); 4430 return ieee80211_data_to_8023_exthdr(skb, NULL, addr, iftype, 0);
4361} 4431}
4362 4432
4363/** 4433/**
@@ -5685,6 +5755,20 @@ void cfg80211_radar_event(struct wiphy *wiphy,
5685 struct cfg80211_chan_def *chandef, gfp_t gfp); 5755 struct cfg80211_chan_def *chandef, gfp_t gfp);
5686 5756
5687/** 5757/**
5758 * cfg80211_sta_opmode_change_notify - STA's ht/vht operation mode change event
5759 * @dev: network device
5760 * @mac: MAC address of a station which opmode got modified
5761 * @sta_opmode: station's current opmode value
5762 * @gfp: context flags
5763 *
5764 * Driver should call this function when station's opmode modified via action
5765 * frame.
5766 */
5767void cfg80211_sta_opmode_change_notify(struct net_device *dev, const u8 *mac,
5768 struct sta_opmode_info *sta_opmode,
5769 gfp_t gfp);
5770
5771/**
5688 * cfg80211_cac_event - Channel availability check (CAC) event 5772 * cfg80211_cac_event - Channel availability check (CAC) event
5689 * @netdev: network device 5773 * @netdev: network device
5690 * @chandef: chandef for the current channel 5774 * @chandef: chandef for the current channel
@@ -5758,10 +5842,13 @@ bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev,
5758 * @addr: the address of the peer 5842 * @addr: the address of the peer
5759 * @cookie: the cookie filled in @probe_client previously 5843 * @cookie: the cookie filled in @probe_client previously
5760 * @acked: indicates whether probe was acked or not 5844 * @acked: indicates whether probe was acked or not
5845 * @ack_signal: signal strength (in dBm) of the ACK frame.
5846 * @is_valid_ack_signal: indicates the ack_signal is valid or not.
5761 * @gfp: allocation flags 5847 * @gfp: allocation flags
5762 */ 5848 */
5763void cfg80211_probe_status(struct net_device *dev, const u8 *addr, 5849void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
5764 u64 cookie, bool acked, gfp_t gfp); 5850 u64 cookie, bool acked, s32 ack_signal,
5851 bool is_valid_ack_signal, gfp_t gfp);
5765 5852
5766/** 5853/**
5767 * cfg80211_report_obss_beacon - report beacon from other APs 5854 * cfg80211_report_obss_beacon - report beacon from other APs
@@ -6202,6 +6289,17 @@ void cfg80211_nan_func_terminated(struct wireless_dev *wdev,
6202/* ethtool helper */ 6289/* ethtool helper */
6203void cfg80211_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info); 6290void cfg80211_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info);
6204 6291
6292/**
6293 * cfg80211_external_auth_request - userspace request for authentication
6294 * @netdev: network device
6295 * @params: External authentication parameters
6296 * @gfp: allocation flags
6297 * Returns: 0 on success, < 0 on error
6298 */
6299int cfg80211_external_auth_request(struct net_device *netdev,
6300 struct cfg80211_external_auth_params *params,
6301 gfp_t gfp);
6302
6205/* Logging, debugging and troubleshooting/diagnostic helpers. */ 6303/* Logging, debugging and troubleshooting/diagnostic helpers. */
6206 6304
6207/* wiphy_printk helpers, similar to dev_printk */ 6305/* wiphy_printk helpers, similar to dev_printk */
diff --git a/include/net/devlink.h b/include/net/devlink.h
index 4de35ed12bcc..d5b707375e48 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -234,13 +234,9 @@ struct devlink_dpipe_headers {
234/** 234/**
235 * struct devlink_resource_ops - resource ops 235 * struct devlink_resource_ops - resource ops
236 * @occ_get: get the occupied size 236 * @occ_get: get the occupied size
237 * @size_validate: validate the size of the resource before update, reload
238 * is needed for changes to take place
239 */ 237 */
240struct devlink_resource_ops { 238struct devlink_resource_ops {
241 u64 (*occ_get)(struct devlink *devlink); 239 u64 (*occ_get)(struct devlink *devlink);
242 int (*size_validate)(struct devlink *devlink, u64 size,
243 struct netlink_ext_ack *extack);
244}; 240};
245 241
246/** 242/**
@@ -410,7 +406,6 @@ extern struct devlink_dpipe_header devlink_dpipe_header_ipv6;
410 406
411int devlink_resource_register(struct devlink *devlink, 407int devlink_resource_register(struct devlink *devlink,
412 const char *resource_name, 408 const char *resource_name,
413 bool top_hierarchy,
414 u64 resource_size, 409 u64 resource_size,
415 u64 resource_id, 410 u64 resource_id,
416 u64 parent_resource_id, 411 u64 parent_resource_id,
diff --git a/include/net/dsa.h b/include/net/dsa.h
index 6cb602dd970c..60fb4ec8ba61 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -19,6 +19,7 @@
19#include <linux/workqueue.h> 19#include <linux/workqueue.h>
20#include <linux/of.h> 20#include <linux/of.h>
21#include <linux/ethtool.h> 21#include <linux/ethtool.h>
22#include <linux/net_tstamp.h>
22#include <net/devlink.h> 23#include <net/devlink.h>
23#include <net/switchdev.h> 24#include <net/switchdev.h>
24 25
@@ -101,6 +102,7 @@ struct dsa_platform_data {
101}; 102};
102 103
103struct packet_type; 104struct packet_type;
105struct dsa_switch;
104 106
105struct dsa_device_ops { 107struct dsa_device_ops {
106 struct sk_buff *(*xmit)(struct sk_buff *skb, struct net_device *dev); 108 struct sk_buff *(*xmit)(struct sk_buff *skb, struct net_device *dev);
@@ -357,7 +359,7 @@ struct dsa_switch_ops {
357 void (*get_strings)(struct dsa_switch *ds, int port, uint8_t *data); 359 void (*get_strings)(struct dsa_switch *ds, int port, uint8_t *data);
358 void (*get_ethtool_stats)(struct dsa_switch *ds, 360 void (*get_ethtool_stats)(struct dsa_switch *ds,
359 int port, uint64_t *data); 361 int port, uint64_t *data);
360 int (*get_sset_count)(struct dsa_switch *ds); 362 int (*get_sset_count)(struct dsa_switch *ds, int port);
361 363
362 /* 364 /*
363 * ethtool Wake-on-LAN 365 * ethtool Wake-on-LAN
@@ -368,6 +370,12 @@ struct dsa_switch_ops {
368 struct ethtool_wolinfo *w); 370 struct ethtool_wolinfo *w);
369 371
370 /* 372 /*
373 * ethtool timestamp info
374 */
375 int (*get_ts_info)(struct dsa_switch *ds, int port,
376 struct ethtool_ts_info *ts);
377
378 /*
371 * Suspend and resume 379 * Suspend and resume
372 */ 380 */
373 int (*suspend)(struct dsa_switch *ds); 381 int (*suspend)(struct dsa_switch *ds);
@@ -469,6 +477,18 @@ struct dsa_switch_ops {
469 int port, struct net_device *br); 477 int port, struct net_device *br);
470 void (*crosschip_bridge_leave)(struct dsa_switch *ds, int sw_index, 478 void (*crosschip_bridge_leave)(struct dsa_switch *ds, int sw_index,
471 int port, struct net_device *br); 479 int port, struct net_device *br);
480
481 /*
482 * PTP functionality
483 */
484 int (*port_hwtstamp_get)(struct dsa_switch *ds, int port,
485 struct ifreq *ifr);
486 int (*port_hwtstamp_set)(struct dsa_switch *ds, int port,
487 struct ifreq *ifr);
488 bool (*port_txtstamp)(struct dsa_switch *ds, int port,
489 struct sk_buff *clone, unsigned int type);
490 bool (*port_rxtstamp)(struct dsa_switch *ds, int port,
491 struct sk_buff *skb, unsigned int type);
472}; 492};
473 493
474struct dsa_switch_driver { 494struct dsa_switch_driver {
diff --git a/include/net/dst.h b/include/net/dst.h
index c63d2c37f6e9..b3219cd8a5a1 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -356,6 +356,7 @@ static inline void __skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev,
356 * skb_tunnel_rx - prepare skb for rx reinsert 356 * skb_tunnel_rx - prepare skb for rx reinsert
357 * @skb: buffer 357 * @skb: buffer
358 * @dev: tunnel device 358 * @dev: tunnel device
359 * @net: netns for packet i/o
359 * 360 *
360 * After decapsulation, packet is going to re-enter (netif_rx()) our stack, 361 * After decapsulation, packet is going to re-enter (netif_rx()) our stack,
361 * so make some cleanups, and perform accounting. 362 * so make some cleanups, and perform accounting.
diff --git a/include/net/dst_cache.h b/include/net/dst_cache.h
index 72fd5067c353..67634675e919 100644
--- a/include/net/dst_cache.h
+++ b/include/net/dst_cache.h
@@ -54,7 +54,7 @@ void dst_cache_set_ip4(struct dst_cache *dst_cache, struct dst_entry *dst,
54 * local BH must be disabled. 54 * local BH must be disabled.
55 */ 55 */
56void dst_cache_set_ip6(struct dst_cache *dst_cache, struct dst_entry *dst, 56void dst_cache_set_ip6(struct dst_cache *dst_cache, struct dst_entry *dst,
57 const struct in6_addr *addr); 57 const struct in6_addr *saddr);
58 58
59/** 59/**
60 * dst_cache_get_ip6 - perform cache lookup and fetch ipv6 source address 60 * dst_cache_get_ip6 - perform cache lookup and fetch ipv6 source address
@@ -71,7 +71,7 @@ struct dst_entry *dst_cache_get_ip6(struct dst_cache *dst_cache,
71 * dst_cache_reset - invalidate the cache contents 71 * dst_cache_reset - invalidate the cache contents
72 * @dst_cache: the cache 72 * @dst_cache: the cache
73 * 73 *
74 * This do not free the cached dst to avoid races and contentions. 74 * This does not free the cached dst to avoid races and contentions.
75 * the dst will be freed on later cache lookup. 75 * the dst will be freed on later cache lookup.
76 */ 76 */
77static inline void dst_cache_reset(struct dst_cache *dst_cache) 77static inline void dst_cache_reset(struct dst_cache *dst_cache)
diff --git a/include/net/ethoc.h b/include/net/ethoc.h
index bb7f467da7fc..29ba069a1d93 100644
--- a/include/net/ethoc.h
+++ b/include/net/ethoc.h
@@ -21,4 +21,3 @@ struct ethoc_platform_data {
21}; 21};
22 22
23#endif /* !LINUX_NET_ETHOC_H */ 23#endif /* !LINUX_NET_ETHOC_H */
24
diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h
index 648caf90ec07..e5cfcfc7dd93 100644
--- a/include/net/fib_rules.h
+++ b/include/net/fib_rules.h
@@ -26,7 +26,8 @@ struct fib_rule {
26 u32 table; 26 u32 table;
27 u8 action; 27 u8 action;
28 u8 l3mdev; 28 u8 l3mdev;
29 /* 2 bytes hole, try to use */ 29 u8 proto;
30 u8 ip_proto;
30 u32 target; 31 u32 target;
31 __be64 tun_id; 32 __be64 tun_id;
32 struct fib_rule __rcu *ctarget; 33 struct fib_rule __rcu *ctarget;
@@ -39,11 +40,14 @@ struct fib_rule {
39 char iifname[IFNAMSIZ]; 40 char iifname[IFNAMSIZ];
40 char oifname[IFNAMSIZ]; 41 char oifname[IFNAMSIZ];
41 struct fib_kuid_range uid_range; 42 struct fib_kuid_range uid_range;
43 struct fib_rule_port_range sport_range;
44 struct fib_rule_port_range dport_range;
42 struct rcu_head rcu; 45 struct rcu_head rcu;
43}; 46};
44 47
45struct fib_lookup_arg { 48struct fib_lookup_arg {
46 void *lookup_ptr; 49 void *lookup_ptr;
50 const void *lookup_data;
47 void *result; 51 void *result;
48 struct fib_rule *rule; 52 struct fib_rule *rule;
49 u32 table; 53 u32 table;
@@ -108,7 +112,12 @@ struct fib_rule_notifier_info {
108 [FRA_SUPPRESS_IFGROUP] = { .type = NLA_U32 }, \ 112 [FRA_SUPPRESS_IFGROUP] = { .type = NLA_U32 }, \
109 [FRA_GOTO] = { .type = NLA_U32 }, \ 113 [FRA_GOTO] = { .type = NLA_U32 }, \
110 [FRA_L3MDEV] = { .type = NLA_U8 }, \ 114 [FRA_L3MDEV] = { .type = NLA_U8 }, \
111 [FRA_UID_RANGE] = { .len = sizeof(struct fib_rule_uid_range) } 115 [FRA_UID_RANGE] = { .len = sizeof(struct fib_rule_uid_range) }, \
116 [FRA_PROTOCOL] = { .type = NLA_U8 }, \
117 [FRA_IP_PROTO] = { .type = NLA_U8 }, \
118 [FRA_SPORT_RANGE] = { .len = sizeof(struct fib_rule_port_range) }, \
119 [FRA_DPORT_RANGE] = { .len = sizeof(struct fib_rule_port_range) }
120
112 121
113static inline void fib_rule_get(struct fib_rule *rule) 122static inline void fib_rule_get(struct fib_rule *rule)
114{ 123{
@@ -142,6 +151,38 @@ static inline u32 frh_get_table(struct fib_rule_hdr *frh, struct nlattr **nla)
142 return frh->table; 151 return frh->table;
143} 152}
144 153
154static inline bool fib_rule_port_range_set(const struct fib_rule_port_range *range)
155{
156 return range->start != 0 && range->end != 0;
157}
158
159static inline bool fib_rule_port_inrange(const struct fib_rule_port_range *a,
160 __be16 port)
161{
162 return ntohs(port) >= a->start &&
163 ntohs(port) <= a->end;
164}
165
166static inline bool fib_rule_port_range_valid(const struct fib_rule_port_range *a)
167{
168 return a->start != 0 && a->end != 0 && a->end < 0xffff &&
169 a->start <= a->end;
170}
171
172static inline bool fib_rule_port_range_compare(struct fib_rule_port_range *a,
173 struct fib_rule_port_range *b)
174{
175 return a->start == b->start &&
176 a->end == b->end;
177}
178
179static inline bool fib_rule_requires_fldissect(struct fib_rule *rule)
180{
181 return rule->ip_proto ||
182 fib_rule_port_range_set(&rule->sport_range) ||
183 fib_rule_port_range_set(&rule->dport_range);
184}
185
145struct fib_rules_ops *fib_rules_register(const struct fib_rules_ops *, 186struct fib_rules_ops *fib_rules_register(const struct fib_rules_ops *,
146 struct net *); 187 struct net *);
147void fib_rules_unregister(struct fib_rules_ops *); 188void fib_rules_unregister(struct fib_rules_ops *);
diff --git a/include/net/flow.h b/include/net/flow.h
index f1624fd5b1d0..8ce21793094e 100644
--- a/include/net/flow.h
+++ b/include/net/flow.h
@@ -125,7 +125,7 @@ static inline void flowi4_update_output(struct flowi4 *fl4, int oif, __u8 tos,
125 fl4->daddr = daddr; 125 fl4->daddr = daddr;
126 fl4->saddr = saddr; 126 fl4->saddr = saddr;
127} 127}
128 128
129 129
130struct flowi6 { 130struct flowi6 {
131 struct flowi_common __fl_common; 131 struct flowi_common __fl_common;
@@ -222,20 +222,4 @@ static inline unsigned int flow_key_size(u16 family)
222 222
223__u32 __get_hash_from_flowi6(const struct flowi6 *fl6, struct flow_keys *keys); 223__u32 __get_hash_from_flowi6(const struct flowi6 *fl6, struct flow_keys *keys);
224 224
225static inline __u32 get_hash_from_flowi6(const struct flowi6 *fl6)
226{
227 struct flow_keys keys;
228
229 return __get_hash_from_flowi6(fl6, &keys);
230}
231
232__u32 __get_hash_from_flowi4(const struct flowi4 *fl4, struct flow_keys *keys);
233
234static inline __u32 get_hash_from_flowi4(const struct flowi4 *fl4)
235{
236 struct flow_keys keys;
237
238 return __get_hash_from_flowi4(fl4, &keys);
239}
240
241#endif 225#endif
diff --git a/include/net/gre.h b/include/net/gre.h
index f90585decbce..797142eee9cd 100644
--- a/include/net/gre.h
+++ b/include/net/gre.h
@@ -37,6 +37,9 @@ struct net_device *gretap_fb_dev_create(struct net *net, const char *name,
37int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi, 37int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi,
38 bool *csum_err, __be16 proto, int nhs); 38 bool *csum_err, __be16 proto, int nhs);
39 39
40bool is_gretap_dev(const struct net_device *dev);
41bool is_ip6gretap_dev(const struct net_device *dev);
42
40static inline int gre_calc_hlen(__be16 o_flags) 43static inline int gre_calc_hlen(__be16 o_flags)
41{ 44{
42 int addend = 4; 45 int addend = 4;
diff --git a/include/net/ieee80211_radiotap.h b/include/net/ieee80211_radiotap.h
index d91f9e7f4d71..960236fb1681 100644
--- a/include/net/ieee80211_radiotap.h
+++ b/include/net/ieee80211_radiotap.h
@@ -149,6 +149,8 @@ enum ieee80211_radiotap_ampdu_flags {
149 IEEE80211_RADIOTAP_AMPDU_IS_LAST = 0x0008, 149 IEEE80211_RADIOTAP_AMPDU_IS_LAST = 0x0008,
150 IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR = 0x0010, 150 IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR = 0x0010,
151 IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN = 0x0020, 151 IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN = 0x0020,
152 IEEE80211_RADIOTAP_AMPDU_EOF = 0x0040,
153 IEEE80211_RADIOTAP_AMPDU_EOF_KNOWN = 0x0080,
152}; 154};
153 155
154/* for IEEE80211_RADIOTAP_VHT */ 156/* for IEEE80211_RADIOTAP_VHT */
diff --git a/include/net/inet_common.h b/include/net/inet_common.h
index 5a54c9570977..500f81375200 100644
--- a/include/net/inet_common.h
+++ b/include/net/inet_common.h
@@ -32,7 +32,7 @@ int inet_shutdown(struct socket *sock, int how);
32int inet_listen(struct socket *sock, int backlog); 32int inet_listen(struct socket *sock, int backlog);
33void inet_sock_destruct(struct sock *sk); 33void inet_sock_destruct(struct sock *sk);
34int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len); 34int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len);
35int inet_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, 35int inet_getname(struct socket *sock, struct sockaddr *uaddr,
36 int peer); 36 int peer);
37int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); 37int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
38int inet_ctl_sock_create(struct sock **sk, unsigned short family, 38int inet_ctl_sock_create(struct sock **sk, unsigned short family,
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h
index c1a93ce35e62..b68fea022a82 100644
--- a/include/net/inet_connection_sock.h
+++ b/include/net/inet_connection_sock.h
@@ -49,9 +49,9 @@ struct inet_connection_sock_af_ops {
49 u16 net_header_len; 49 u16 net_header_len;
50 u16 net_frag_header_len; 50 u16 net_frag_header_len;
51 u16 sockaddr_len; 51 u16 sockaddr_len;
52 int (*setsockopt)(struct sock *sk, int level, int optname, 52 int (*setsockopt)(struct sock *sk, int level, int optname,
53 char __user *optval, unsigned int optlen); 53 char __user *optval, unsigned int optlen);
54 int (*getsockopt)(struct sock *sk, int level, int optname, 54 int (*getsockopt)(struct sock *sk, int level, int optname,
55 char __user *optval, int __user *optlen); 55 char __user *optval, int __user *optlen);
56#ifdef CONFIG_COMPAT 56#ifdef CONFIG_COMPAT
57 int (*compat_setsockopt)(struct sock *sk, 57 int (*compat_setsockopt)(struct sock *sk,
@@ -67,7 +67,7 @@ struct inet_connection_sock_af_ops {
67 67
68/** inet_connection_sock - INET connection oriented sock 68/** inet_connection_sock - INET connection oriented sock
69 * 69 *
70 * @icsk_accept_queue: FIFO of established children 70 * @icsk_accept_queue: FIFO of established children
71 * @icsk_bind_hash: Bind node 71 * @icsk_bind_hash: Bind node
72 * @icsk_timeout: Timeout 72 * @icsk_timeout: Timeout
73 * @icsk_retransmit_timer: Resend (no ack) 73 * @icsk_retransmit_timer: Resend (no ack)
@@ -122,7 +122,7 @@ struct inet_connection_sock {
122 unsigned long timeout; /* Currently scheduled timeout */ 122 unsigned long timeout; /* Currently scheduled timeout */
123 __u32 lrcvtime; /* timestamp of last received data packet */ 123 __u32 lrcvtime; /* timestamp of last received data packet */
124 __u16 last_seg_size; /* Size of last incoming segment */ 124 __u16 last_seg_size; /* Size of last incoming segment */
125 __u16 rcv_mss; /* MSS used for delayed ACK decisions */ 125 __u16 rcv_mss; /* MSS used for delayed ACK decisions */
126 } icsk_ack; 126 } icsk_ack;
127 struct { 127 struct {
128 int enabled; 128 int enabled;
@@ -201,7 +201,7 @@ extern const char inet_csk_timer_bug_msg[];
201static inline void inet_csk_clear_xmit_timer(struct sock *sk, const int what) 201static inline void inet_csk_clear_xmit_timer(struct sock *sk, const int what)
202{ 202{
203 struct inet_connection_sock *icsk = inet_csk(sk); 203 struct inet_connection_sock *icsk = inet_csk(sk);
204 204
205 if (what == ICSK_TIME_RETRANS || what == ICSK_TIME_PROBE0) { 205 if (what == ICSK_TIME_RETRANS || what == ICSK_TIME_PROBE0) {
206 icsk->icsk_pending = 0; 206 icsk->icsk_pending = 0;
207#ifdef INET_CSK_CLEAR_TIMERS 207#ifdef INET_CSK_CLEAR_TIMERS
diff --git a/include/net/ip.h b/include/net/ip.h
index f49b3a576bec..36f8f7811093 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -91,6 +91,17 @@ static inline int inet_sdif(struct sk_buff *skb)
91 return 0; 91 return 0;
92} 92}
93 93
94/* Special input handler for packets caught by router alert option.
95 They are selected only by protocol field, and then processed likely
96 local ones; but only if someone wants them! Otherwise, router
97 not running rsvpd will kill RSVP.
98
99 It is user level problem, what it will make with them.
100 I have no idea, how it will masquearde or NAT them (it is joke, joke :-)),
101 but receiver should be enough clever f.e. to forward mtrace requests,
102 sent to multicast group to reach destination designated router.
103 */
104
94struct ip_ra_chain { 105struct ip_ra_chain {
95 struct ip_ra_chain __rcu *next; 106 struct ip_ra_chain __rcu *next;
96 struct sock *sk; 107 struct sock *sk;
@@ -101,8 +112,6 @@ struct ip_ra_chain {
101 struct rcu_head rcu; 112 struct rcu_head rcu;
102}; 113};
103 114
104extern struct ip_ra_chain __rcu *ip_ra_chain;
105
106/* IP flags. */ 115/* IP flags. */
107#define IP_CE 0x8000 /* Flag: "Congestion" */ 116#define IP_CE 0x8000 /* Flag: "Congestion" */
108#define IP_DF 0x4000 /* Flag: "Don't Fragment" */ 117#define IP_DF 0x4000 /* Flag: "Don't Fragment" */
@@ -186,15 +195,15 @@ int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len);
186void ip4_datagram_release_cb(struct sock *sk); 195void ip4_datagram_release_cb(struct sock *sk);
187 196
188struct ip_reply_arg { 197struct ip_reply_arg {
189 struct kvec iov[1]; 198 struct kvec iov[1];
190 int flags; 199 int flags;
191 __wsum csum; 200 __wsum csum;
192 int csumoffset; /* u16 offset of csum in iov[0].iov_base */ 201 int csumoffset; /* u16 offset of csum in iov[0].iov_base */
193 /* -1 if not needed */ 202 /* -1 if not needed */
194 int bound_dev_if; 203 int bound_dev_if;
195 u8 tos; 204 u8 tos;
196 kuid_t uid; 205 kuid_t uid;
197}; 206};
198 207
199#define IP_REPLY_ARG_NOSRCCHECK 1 208#define IP_REPLY_ARG_NOSRCCHECK 1
200 209
@@ -584,13 +593,13 @@ int ip_frag_mem(struct net *net);
584/* 593/*
585 * Functions provided by ip_forward.c 594 * Functions provided by ip_forward.c
586 */ 595 */
587 596
588int ip_forward(struct sk_buff *skb); 597int ip_forward(struct sk_buff *skb);
589 598
590/* 599/*
591 * Functions provided by ip_options.c 600 * Functions provided by ip_options.c
592 */ 601 */
593 602
594void ip_options_build(struct sk_buff *skb, struct ip_options *opt, 603void ip_options_build(struct sk_buff *skb, struct ip_options *opt,
595 __be32 daddr, struct rtable *rt, int is_frag); 604 __be32 daddr, struct rtable *rt, int is_frag);
596 605
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index 34ec321d6a03..5e86fd9dc857 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -350,7 +350,8 @@ struct fib6_table {
350 350
351typedef struct rt6_info *(*pol_lookup_t)(struct net *, 351typedef struct rt6_info *(*pol_lookup_t)(struct net *,
352 struct fib6_table *, 352 struct fib6_table *,
353 struct flowi6 *, int); 353 struct flowi6 *,
354 const struct sk_buff *, int);
354 355
355struct fib6_entry_notifier_info { 356struct fib6_entry_notifier_info {
356 struct fib_notifier_info info; /* must be first */ 357 struct fib_notifier_info info; /* must be first */
@@ -364,6 +365,7 @@ struct fib6_entry_notifier_info {
364struct fib6_table *fib6_get_table(struct net *net, u32 id); 365struct fib6_table *fib6_get_table(struct net *net, u32 id);
365struct fib6_table *fib6_new_table(struct net *net, u32 id); 366struct fib6_table *fib6_new_table(struct net *net, u32 id);
366struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6, 367struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
368 const struct sk_buff *skb,
367 int flags, pol_lookup_t lookup); 369 int flags, pol_lookup_t lookup);
368 370
369struct fib6_node *fib6_lookup(struct fib6_node *root, 371struct fib6_node *fib6_lookup(struct fib6_node *root,
@@ -415,6 +417,24 @@ void fib6_rules_cleanup(void);
415bool fib6_rule_default(const struct fib_rule *rule); 417bool fib6_rule_default(const struct fib_rule *rule);
416int fib6_rules_dump(struct net *net, struct notifier_block *nb); 418int fib6_rules_dump(struct net *net, struct notifier_block *nb);
417unsigned int fib6_rules_seq_read(struct net *net); 419unsigned int fib6_rules_seq_read(struct net *net);
420
421static inline bool fib6_rules_early_flow_dissect(struct net *net,
422 struct sk_buff *skb,
423 struct flowi6 *fl6,
424 struct flow_keys *flkeys)
425{
426 unsigned int flag = FLOW_DISSECTOR_F_STOP_AT_ENCAP;
427
428 if (!net->ipv6.fib6_rules_require_fldissect)
429 return false;
430
431 skb_flow_dissect_flow_keys(skb, flkeys, flag);
432 fl6->fl6_sport = flkeys->ports.src;
433 fl6->fl6_dport = flkeys->ports.dst;
434 fl6->flowi6_proto = flkeys->basic.ip_proto;
435
436 return true;
437}
418#else 438#else
419static inline int fib6_rules_init(void) 439static inline int fib6_rules_init(void)
420{ 440{
@@ -436,5 +456,12 @@ static inline unsigned int fib6_rules_seq_read(struct net *net)
436{ 456{
437 return 0; 457 return 0;
438} 458}
459static inline bool fib6_rules_early_flow_dissect(struct net *net,
460 struct sk_buff *skb,
461 struct flowi6 *fl6,
462 struct flow_keys *flkeys)
463{
464 return false;
465}
439#endif 466#endif
440#endif 467#endif
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index ac0866bb9e93..0084013d6bed 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -75,7 +75,8 @@ static inline bool rt6_qualify_for_ecmp(const struct rt6_info *rt)
75void ip6_route_input(struct sk_buff *skb); 75void ip6_route_input(struct sk_buff *skb);
76struct dst_entry *ip6_route_input_lookup(struct net *net, 76struct dst_entry *ip6_route_input_lookup(struct net *net,
77 struct net_device *dev, 77 struct net_device *dev,
78 struct flowi6 *fl6, int flags); 78 struct flowi6 *fl6,
79 const struct sk_buff *skb, int flags);
79 80
80struct dst_entry *ip6_route_output_flags(struct net *net, const struct sock *sk, 81struct dst_entry *ip6_route_output_flags(struct net *net, const struct sock *sk,
81 struct flowi6 *fl6, int flags); 82 struct flowi6 *fl6, int flags);
@@ -88,9 +89,10 @@ static inline struct dst_entry *ip6_route_output(struct net *net,
88} 89}
89 90
90struct dst_entry *ip6_route_lookup(struct net *net, struct flowi6 *fl6, 91struct dst_entry *ip6_route_lookup(struct net *net, struct flowi6 *fl6,
91 int flags); 92 const struct sk_buff *skb, int flags);
92struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table, 93struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table,
93 int ifindex, struct flowi6 *fl6, int flags); 94 int ifindex, struct flowi6 *fl6,
95 const struct sk_buff *skb, int flags);
94 96
95void ip6_route_init_special_entries(void); 97void ip6_route_init_special_entries(void);
96int ip6_route_init(void); 98int ip6_route_init(void);
@@ -126,8 +128,10 @@ static inline int ip6_route_get_saddr(struct net *net, struct rt6_info *rt,
126} 128}
127 129
128struct rt6_info *rt6_lookup(struct net *net, const struct in6_addr *daddr, 130struct rt6_info *rt6_lookup(struct net *net, const struct in6_addr *daddr,
129 const struct in6_addr *saddr, int oif, int flags); 131 const struct in6_addr *saddr, int oif,
130u32 rt6_multipath_hash(const struct flowi6 *fl6, const struct sk_buff *skb); 132 const struct sk_buff *skb, int flags);
133u32 rt6_multipath_hash(const struct net *net, const struct flowi6 *fl6,
134 const struct sk_buff *skb, struct flow_keys *hkeys);
131 135
132struct dst_entry *icmp6_dst_alloc(struct net_device *dev, struct flowi6 *fl6); 136struct dst_entry *icmp6_dst_alloc(struct net_device *dev, struct flowi6 *fl6);
133 137
@@ -269,4 +273,5 @@ static inline bool rt6_duplicate_nexthop(struct rt6_info *a, struct rt6_info *b)
269 ipv6_addr_equal(&a->rt6i_gateway, &b->rt6i_gateway) && 273 ipv6_addr_equal(&a->rt6i_gateway, &b->rt6i_gateway) &&
270 !lwtunnel_cmp_encap(a->dst.lwtstate, b->dst.lwtstate); 274 !lwtunnel_cmp_encap(a->dst.lwtstate, b->dst.lwtstate);
271} 275}
276
272#endif 277#endif
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index 77d0a78cf7d2..81d0f2107ff1 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -158,7 +158,7 @@ struct fib_result_nl {
158 unsigned char nh_sel; 158 unsigned char nh_sel;
159 unsigned char type; 159 unsigned char type;
160 unsigned char scope; 160 unsigned char scope;
161 int err; 161 int err;
162}; 162};
163 163
164#ifdef CONFIG_IP_ROUTE_MULTIPATH 164#ifdef CONFIG_IP_ROUTE_MULTIPATH
@@ -294,6 +294,13 @@ static inline unsigned int fib4_rules_seq_read(struct net *net)
294 return 0; 294 return 0;
295} 295}
296 296
297static inline bool fib4_rules_early_flow_dissect(struct net *net,
298 struct sk_buff *skb,
299 struct flowi4 *fl4,
300 struct flow_keys *flkeys)
301{
302 return false;
303}
297#else /* CONFIG_IP_MULTIPLE_TABLES */ 304#else /* CONFIG_IP_MULTIPLE_TABLES */
298int __net_init fib4_rules_init(struct net *net); 305int __net_init fib4_rules_init(struct net *net);
299void __net_exit fib4_rules_exit(struct net *net); 306void __net_exit fib4_rules_exit(struct net *net);
@@ -342,6 +349,24 @@ bool fib4_rule_default(const struct fib_rule *rule);
342int fib4_rules_dump(struct net *net, struct notifier_block *nb); 349int fib4_rules_dump(struct net *net, struct notifier_block *nb);
343unsigned int fib4_rules_seq_read(struct net *net); 350unsigned int fib4_rules_seq_read(struct net *net);
344 351
352static inline bool fib4_rules_early_flow_dissect(struct net *net,
353 struct sk_buff *skb,
354 struct flowi4 *fl4,
355 struct flow_keys *flkeys)
356{
357 unsigned int flag = FLOW_DISSECTOR_F_STOP_AT_ENCAP;
358
359 if (!net->ipv4.fib_rules_require_fldissect)
360 return false;
361
362 skb_flow_dissect_flow_keys(skb, flkeys, flag);
363 fl4->fl4_sport = flkeys->ports.src;
364 fl4->fl4_dport = flkeys->ports.dst;
365 fl4->flowi4_proto = flkeys->basic.ip_proto;
366
367 return true;
368}
369
345#endif /* CONFIG_IP_MULTIPLE_TABLES */ 370#endif /* CONFIG_IP_MULTIPLE_TABLES */
346 371
347/* Exported by fib_frontend.c */ 372/* Exported by fib_frontend.c */
@@ -371,8 +396,8 @@ int fib_sync_down_addr(struct net_device *dev, __be32 local);
371int fib_sync_up(struct net_device *dev, unsigned int nh_flags); 396int fib_sync_up(struct net_device *dev, unsigned int nh_flags);
372 397
373#ifdef CONFIG_IP_ROUTE_MULTIPATH 398#ifdef CONFIG_IP_ROUTE_MULTIPATH
374int fib_multipath_hash(const struct fib_info *fi, const struct flowi4 *fl4, 399int fib_multipath_hash(const struct net *net, const struct flowi4 *fl4,
375 const struct sk_buff *skb); 400 const struct sk_buff *skb, struct flow_keys *flkeys);
376#endif 401#endif
377void fib_select_multipath(struct fib_result *res, int hash); 402void fib_select_multipath(struct fib_result *res, int hash);
378void fib_select_path(struct net *net, struct fib_result *res, 403void fib_select_path(struct net *net, struct fib_result *res,
diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h
index 1f16773cfd76..540a4b4417bf 100644
--- a/include/net/ip_tunnels.h
+++ b/include/net/ip_tunnels.h
@@ -180,8 +180,10 @@ struct tnl_ptk_info {
180 180
181struct ip_tunnel_net { 181struct ip_tunnel_net {
182 struct net_device *fb_tunnel_dev; 182 struct net_device *fb_tunnel_dev;
183 struct rtnl_link_ops *rtnl_link_ops;
183 struct hlist_head tunnels[IP_TNL_HASH_SIZE]; 184 struct hlist_head tunnels[IP_TNL_HASH_SIZE];
184 struct ip_tunnel __rcu *collect_md_tun; 185 struct ip_tunnel __rcu *collect_md_tun;
186 int type;
185}; 187};
186 188
187static inline void ip_tunnel_key_init(struct ip_tunnel_key *key, 189static inline void ip_tunnel_key_init(struct ip_tunnel_key *key,
@@ -254,6 +256,22 @@ static inline __be32 tunnel_id_to_key32(__be64 tun_id)
254 256
255#ifdef CONFIG_INET 257#ifdef CONFIG_INET
256 258
259static inline void ip_tunnel_init_flow(struct flowi4 *fl4,
260 int proto,
261 __be32 daddr, __be32 saddr,
262 __be32 key, __u8 tos, int oif,
263 __u32 mark)
264{
265 memset(fl4, 0, sizeof(*fl4));
266 fl4->flowi4_oif = oif;
267 fl4->daddr = daddr;
268 fl4->saddr = saddr;
269 fl4->flowi4_tos = tos;
270 fl4->flowi4_proto = proto;
271 fl4->fl4_gre_key = key;
272 fl4->flowi4_mark = mark;
273}
274
257int ip_tunnel_init(struct net_device *dev); 275int ip_tunnel_init(struct net_device *dev);
258void ip_tunnel_uninit(struct net_device *dev); 276void ip_tunnel_uninit(struct net_device *dev);
259void ip_tunnel_dellink(struct net_device *dev, struct list_head *head); 277void ip_tunnel_dellink(struct net_device *dev, struct list_head *head);
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 8606c9113d3f..50a6f0ddb878 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -105,8 +105,8 @@
105 105
106#define IPV6_ADDR_ANY 0x0000U 106#define IPV6_ADDR_ANY 0x0000U
107 107
108#define IPV6_ADDR_UNICAST 0x0001U 108#define IPV6_ADDR_UNICAST 0x0001U
109#define IPV6_ADDR_MULTICAST 0x0002U 109#define IPV6_ADDR_MULTICAST 0x0002U
110 110
111#define IPV6_ADDR_LOOPBACK 0x0010U 111#define IPV6_ADDR_LOOPBACK 0x0010U
112#define IPV6_ADDR_LINKLOCAL 0x0020U 112#define IPV6_ADDR_LINKLOCAL 0x0020U
@@ -447,7 +447,7 @@ ipv6_masked_addr_cmp(const struct in6_addr *a1, const struct in6_addr *m,
447#endif 447#endif
448} 448}
449 449
450static inline void ipv6_addr_prefix(struct in6_addr *pfx, 450static inline void ipv6_addr_prefix(struct in6_addr *pfx,
451 const struct in6_addr *addr, 451 const struct in6_addr *addr,
452 int plen) 452 int plen)
453{ 453{
@@ -496,7 +496,7 @@ static inline void __ipv6_addr_set_half(__be32 *addr,
496 addr[1] = wl; 496 addr[1] = wl;
497} 497}
498 498
499static inline void ipv6_addr_set(struct in6_addr *addr, 499static inline void ipv6_addr_set(struct in6_addr *addr,
500 __be32 w1, __be32 w2, 500 __be32 w1, __be32 w2,
501 __be32 w3, __be32 w4) 501 __be32 w3, __be32 w4)
502{ 502{
@@ -732,7 +732,7 @@ static inline int __ipv6_addr_diff32(const void *token1, const void *token2, int
732 } 732 }
733 733
734 /* 734 /*
735 * we should *never* get to this point since that 735 * we should *never* get to this point since that
736 * would mean the addrs are equal 736 * would mean the addrs are equal
737 * 737 *
738 * However, we do get to it 8) And exacly, when 738 * However, we do get to it 8) And exacly, when
@@ -888,6 +888,17 @@ static inline int ip6_default_np_autolabel(struct net *net)
888} 888}
889#endif 889#endif
890 890
891#if IS_ENABLED(CONFIG_IPV6)
892static inline int ip6_multipath_hash_policy(const struct net *net)
893{
894 return net->ipv6.sysctl.multipath_hash_policy;
895}
896#else
897static inline int ip6_multipath_hash_policy(const struct net *net)
898{
899 return 0;
900}
901#endif
891 902
892/* 903/*
893 * Header manipulation 904 * Header manipulation
@@ -1056,7 +1067,7 @@ void ipv6_local_rxpmtu(struct sock *sk, struct flowi6 *fl6, u32 mtu);
1056 1067
1057int inet6_release(struct socket *sock); 1068int inet6_release(struct socket *sock);
1058int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len); 1069int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len);
1059int inet6_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, 1070int inet6_getname(struct socket *sock, struct sockaddr *uaddr,
1060 int peer); 1071 int peer);
1061int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); 1072int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
1062 1073
diff --git a/include/net/lwtunnel.h b/include/net/lwtunnel.h
index d747ef975cd8..33fd9ba7e0e5 100644
--- a/include/net/lwtunnel.h
+++ b/include/net/lwtunnel.h
@@ -127,6 +127,17 @@ int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb);
127int lwtunnel_input(struct sk_buff *skb); 127int lwtunnel_input(struct sk_buff *skb);
128int lwtunnel_xmit(struct sk_buff *skb); 128int lwtunnel_xmit(struct sk_buff *skb);
129 129
130static inline void lwtunnel_set_redirect(struct dst_entry *dst)
131{
132 if (lwtunnel_output_redirect(dst->lwtstate)) {
133 dst->lwtstate->orig_output = dst->output;
134 dst->output = lwtunnel_output;
135 }
136 if (lwtunnel_input_redirect(dst->lwtstate)) {
137 dst->lwtstate->orig_input = dst->input;
138 dst->input = lwtunnel_input;
139 }
140}
130#else 141#else
131 142
132static inline void lwtstate_free(struct lwtunnel_state *lws) 143static inline void lwtstate_free(struct lwtunnel_state *lws)
@@ -158,6 +169,10 @@ static inline bool lwtunnel_xmit_redirect(struct lwtunnel_state *lwtstate)
158 return false; 169 return false;
159} 170}
160 171
172static inline void lwtunnel_set_redirect(struct dst_entry *dst)
173{
174}
175
161static inline unsigned int lwtunnel_headroom(struct lwtunnel_state *lwtstate, 176static inline unsigned int lwtunnel_headroom(struct lwtunnel_state *lwtstate,
162 unsigned int mtu) 177 unsigned int mtu)
163{ 178{
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 2b581bd93812..2449982daf75 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -6,6 +6,7 @@
6 * Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net> 6 * Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net>
7 * Copyright 2013-2014 Intel Mobile Communications GmbH 7 * Copyright 2013-2014 Intel Mobile Communications GmbH
8 * Copyright (C) 2015 - 2017 Intel Deutschland GmbH 8 * Copyright (C) 2015 - 2017 Intel Deutschland GmbH
9 * Copyright (C) 2018 Intel Corporation
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as 12 * it under the terms of the GNU General Public License version 2 as
@@ -934,6 +935,7 @@ struct ieee80211_tx_info {
934 u8 ampdu_len; 935 u8 ampdu_len;
935 u8 antenna; 936 u8 antenna;
936 u16 tx_time; 937 u16 tx_time;
938 bool is_valid_ack_signal;
937 void *status_driver_data[19 / sizeof(void *)]; 939 void *status_driver_data[19 / sizeof(void *)];
938 } status; 940 } status;
939 struct { 941 struct {
@@ -1098,6 +1100,9 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
1098 * the first subframe. 1100 * the first subframe.
1099 * @RX_FLAG_ICV_STRIPPED: The ICV is stripped from this frame. CRC checking must 1101 * @RX_FLAG_ICV_STRIPPED: The ICV is stripped from this frame. CRC checking must
1100 * be done in the hardware. 1102 * be done in the hardware.
1103 * @RX_FLAG_AMPDU_EOF_BIT: Value of the EOF bit in the A-MPDU delimiter for this
1104 * frame
1105 * @RX_FLAG_AMPDU_EOF_BIT_KNOWN: The EOF value is known
1101 */ 1106 */
1102enum mac80211_rx_flags { 1107enum mac80211_rx_flags {
1103 RX_FLAG_MMIC_ERROR = BIT(0), 1108 RX_FLAG_MMIC_ERROR = BIT(0),
@@ -1124,6 +1129,8 @@ enum mac80211_rx_flags {
1124 RX_FLAG_MIC_STRIPPED = BIT(21), 1129 RX_FLAG_MIC_STRIPPED = BIT(21),
1125 RX_FLAG_ALLOW_SAME_PN = BIT(22), 1130 RX_FLAG_ALLOW_SAME_PN = BIT(22),
1126 RX_FLAG_ICV_STRIPPED = BIT(23), 1131 RX_FLAG_ICV_STRIPPED = BIT(23),
1132 RX_FLAG_AMPDU_EOF_BIT = BIT(24),
1133 RX_FLAG_AMPDU_EOF_BIT_KNOWN = BIT(25),
1127}; 1134};
1128 1135
1129/** 1136/**
@@ -2063,6 +2070,14 @@ struct ieee80211_txq {
2063 * @IEEE80211_HW_SUPPORTS_TDLS_BUFFER_STA: Hardware supports buffer STA on 2070 * @IEEE80211_HW_SUPPORTS_TDLS_BUFFER_STA: Hardware supports buffer STA on
2064 * TDLS links. 2071 * TDLS links.
2065 * 2072 *
2073 * @IEEE80211_HW_DEAUTH_NEED_MGD_TX_PREP: The driver requires the
2074 * mgd_prepare_tx() callback to be called before transmission of a
2075 * deauthentication frame in case the association was completed but no
2076 * beacon was heard. This is required in multi-channel scenarios, where the
2077 * virtual interface might not be given air time for the transmission of
2078 * the frame, as it is not synced with the AP/P2P GO yet, and thus the
2079 * deauthentication frame might not be transmitted.
2080 >
2066 * @IEEE80211_HW_DOESNT_SUPPORT_QOS_NDP: The driver (or firmware) doesn't 2081 * @IEEE80211_HW_DOESNT_SUPPORT_QOS_NDP: The driver (or firmware) doesn't
2067 * support QoS NDP for AP probing - that's most likely a driver bug. 2082 * support QoS NDP for AP probing - that's most likely a driver bug.
2068 * 2083 *
@@ -2109,6 +2124,7 @@ enum ieee80211_hw_flags {
2109 IEEE80211_HW_REPORTS_LOW_ACK, 2124 IEEE80211_HW_REPORTS_LOW_ACK,
2110 IEEE80211_HW_SUPPORTS_TX_FRAG, 2125 IEEE80211_HW_SUPPORTS_TX_FRAG,
2111 IEEE80211_HW_SUPPORTS_TDLS_BUFFER_STA, 2126 IEEE80211_HW_SUPPORTS_TDLS_BUFFER_STA,
2127 IEEE80211_HW_DEAUTH_NEED_MGD_TX_PREP,
2112 IEEE80211_HW_DOESNT_SUPPORT_QOS_NDP, 2128 IEEE80211_HW_DOESNT_SUPPORT_QOS_NDP,
2113 2129
2114 /* keep last, obviously */ 2130 /* keep last, obviously */
@@ -3354,6 +3370,9 @@ enum ieee80211_reconfig_type {
3354 * management frame prior to having successfully associated to allow the 3370 * management frame prior to having successfully associated to allow the
3355 * driver to give it channel time for the transmission, to get a response 3371 * driver to give it channel time for the transmission, to get a response
3356 * and to be able to synchronize with the GO. 3372 * and to be able to synchronize with the GO.
3373 * For drivers that set %IEEE80211_HW_DEAUTH_NEED_MGD_TX_PREP, mac80211
3374 * would also call this function before transmitting a deauthentication
3375 * frame in case that no beacon was heard from the AP/P2P GO.
3357 * The callback will be called before each transmission and upon return 3376 * The callback will be called before each transmission and upon return
3358 * mac80211 will transmit the frame right away. 3377 * mac80211 will transmit the frame right away.
3359 * The callback is optional and can (should!) sleep. 3378 * The callback is optional and can (should!) sleep.
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index f306b2aa15a4..09e30bdc7876 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -40,7 +40,7 @@ struct net_device;
40struct sock; 40struct sock;
41struct ctl_table_header; 41struct ctl_table_header;
42struct net_generic; 42struct net_generic;
43struct sock; 43struct uevent_sock;
44struct netns_ipvs; 44struct netns_ipvs;
45 45
46 46
@@ -59,8 +59,12 @@ struct net {
59 atomic64_t cookie_gen; 59 atomic64_t cookie_gen;
60 60
61 struct list_head list; /* list of network namespaces */ 61 struct list_head list; /* list of network namespaces */
62 struct list_head cleanup_list; /* namespaces on death row */ 62 struct list_head exit_list; /* To linked to call pernet exit
63 struct list_head exit_list; /* Use only net_mutex */ 63 * methods on dead net (net_sem
64 * read locked), or to unregister
65 * pernet ops (net_sem wr locked).
66 */
67 struct llist_node cleanup_list; /* namespaces on death row */
64 68
65 struct user_namespace *user_ns; /* Owning user namespace */ 69 struct user_namespace *user_ns; /* Owning user namespace */
66 struct ucounts *ucounts; 70 struct ucounts *ucounts;
@@ -79,6 +83,8 @@ struct net {
79 struct sock *rtnl; /* rtnetlink socket */ 83 struct sock *rtnl; /* rtnetlink socket */
80 struct sock *genl_sock; 84 struct sock *genl_sock;
81 85
86 struct uevent_sock *uevent_sock; /* uevent socket */
87
82 struct list_head dev_base_head; 88 struct list_head dev_base_head;
83 struct hlist_head *dev_name_head; 89 struct hlist_head *dev_name_head;
84 struct hlist_head *dev_index_head; 90 struct hlist_head *dev_index_head;
@@ -89,7 +95,7 @@ struct net {
89 /* core fib_rules */ 95 /* core fib_rules */
90 struct list_head rules_ops; 96 struct list_head rules_ops;
91 97
92 struct list_head fib_notifier_ops; /* protected by net_mutex */ 98 struct list_head fib_notifier_ops; /* protected by net_sem */
93 99
94 struct net_device *loopback_dev; /* The loopback */ 100 struct net_device *loopback_dev; /* The loopback */
95 struct netns_core core; 101 struct netns_core core;
@@ -308,11 +314,31 @@ struct net *get_net_ns_by_id(struct net *net, int id);
308 314
309struct pernet_operations { 315struct pernet_operations {
310 struct list_head list; 316 struct list_head list;
317 /*
318 * Below methods are called without any exclusive locks.
319 * More than one net may be constructed and destructed
320 * in parallel on several cpus. Every pernet_operations
321 * have to keep in mind all other pernet_operations and
322 * to introduce a locking, if they share common resources.
323 *
324 * Exit methods using blocking RCU primitives, such as
325 * synchronize_rcu(), should be implemented via exit_batch.
326 * Then, destruction of a group of net requires single
327 * synchronize_rcu() related to these pernet_operations,
328 * instead of separate synchronize_rcu() for every net.
329 * Please, avoid synchronize_rcu() at all, where it's possible.
330 */
311 int (*init)(struct net *net); 331 int (*init)(struct net *net);
312 void (*exit)(struct net *net); 332 void (*exit)(struct net *net);
313 void (*exit_batch)(struct list_head *net_exit_list); 333 void (*exit_batch)(struct list_head *net_exit_list);
314 unsigned int *id; 334 unsigned int *id;
315 size_t size; 335 size_t size;
336 /*
337 * Indicates above methods are allowed to be executed in parallel
338 * with methods of any other pernet_operations, i.e. they are not
339 * need write locked net_sem.
340 */
341 bool async;
316}; 342};
317 343
318/* 344/*
diff --git a/include/net/netevent.h b/include/net/netevent.h
index 40e7bab68490..d9918261701c 100644
--- a/include/net/netevent.h
+++ b/include/net/netevent.h
@@ -26,7 +26,8 @@ enum netevent_notif_type {
26 NETEVENT_NEIGH_UPDATE = 1, /* arg is struct neighbour ptr */ 26 NETEVENT_NEIGH_UPDATE = 1, /* arg is struct neighbour ptr */
27 NETEVENT_REDIRECT, /* arg is struct netevent_redirect ptr */ 27 NETEVENT_REDIRECT, /* arg is struct netevent_redirect ptr */
28 NETEVENT_DELAY_PROBE_TIME_UPDATE, /* arg is struct neigh_parms ptr */ 28 NETEVENT_DELAY_PROBE_TIME_UPDATE, /* arg is struct neigh_parms ptr */
29 NETEVENT_MULTIPATH_HASH_UPDATE, /* arg is struct net ptr */ 29 NETEVENT_IPV4_MPATH_HASH_UPDATE, /* arg is struct net ptr */
30 NETEVENT_IPV6_MPATH_HASH_UPDATE, /* arg is struct net ptr */
30}; 31};
31 32
32int register_netevent_notifier(struct notifier_block *nb); 33int register_netevent_notifier(struct notifier_block *nb);
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
index 44668c29701a..8491bc9c86b1 100644
--- a/include/net/netns/ipv4.h
+++ b/include/net/netns/ipv4.h
@@ -49,9 +49,12 @@ struct netns_ipv4 {
49#endif 49#endif
50 struct ipv4_devconf *devconf_all; 50 struct ipv4_devconf *devconf_all;
51 struct ipv4_devconf *devconf_dflt; 51 struct ipv4_devconf *devconf_dflt;
52 struct ip_ra_chain __rcu *ra_chain;
53 struct mutex ra_mutex;
52#ifdef CONFIG_IP_MULTIPLE_TABLES 54#ifdef CONFIG_IP_MULTIPLE_TABLES
53 struct fib_rules_ops *rules_ops; 55 struct fib_rules_ops *rules_ops;
54 bool fib_has_custom_rules; 56 bool fib_has_custom_rules;
57 unsigned int fib_rules_require_fldissect;
55 struct fib_table __rcu *fib_main; 58 struct fib_table __rcu *fib_main;
56 struct fib_table __rcu *fib_default; 59 struct fib_table __rcu *fib_default;
57#endif 60#endif
@@ -167,6 +170,9 @@ struct netns_ipv4 {
167 atomic_t tfo_active_disable_times; 170 atomic_t tfo_active_disable_times;
168 unsigned long tfo_active_disable_stamp; 171 unsigned long tfo_active_disable_stamp;
169 172
173 int sysctl_udp_wmem_min;
174 int sysctl_udp_rmem_min;
175
170#ifdef CONFIG_NET_L3_MASTER_DEV 176#ifdef CONFIG_NET_L3_MASTER_DEV
171 int sysctl_udp_l3mdev_accept; 177 int sysctl_udp_l3mdev_accept;
172#endif 178#endif
diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h
index 987cc4569cb8..5b51110435fc 100644
--- a/include/net/netns/ipv6.h
+++ b/include/net/netns/ipv6.h
@@ -28,6 +28,7 @@ struct netns_sysctl_ipv6 {
28 int ip6_rt_gc_elasticity; 28 int ip6_rt_gc_elasticity;
29 int ip6_rt_mtu_expires; 29 int ip6_rt_mtu_expires;
30 int ip6_rt_min_advmss; 30 int ip6_rt_min_advmss;
31 int multipath_hash_policy;
31 int flowlabel_consistency; 32 int flowlabel_consistency;
32 int auto_flowlabels; 33 int auto_flowlabels;
33 int icmpv6_time; 34 int icmpv6_time;
@@ -71,7 +72,8 @@ struct netns_ipv6 {
71 unsigned int ip6_rt_gc_expire; 72 unsigned int ip6_rt_gc_expire;
72 unsigned long ip6_rt_last_gc; 73 unsigned long ip6_rt_last_gc;
73#ifdef CONFIG_IPV6_MULTIPLE_TABLES 74#ifdef CONFIG_IPV6_MULTIPLE_TABLES
74 bool fib6_has_custom_rules; 75 unsigned int fib6_rules_require_fldissect;
76 bool fib6_has_custom_rules;
75 struct rt6_info *ip6_prohibit_entry; 77 struct rt6_info *ip6_prohibit_entry;
76 struct rt6_info *ip6_blk_hole_entry; 78 struct rt6_info *ip6_blk_hole_entry;
77 struct fib6_table *fib6_local_tbl; 79 struct fib6_table *fib6_local_tbl;
@@ -84,7 +86,7 @@ struct netns_ipv6 {
84 struct sock *mc_autojoin_sk; 86 struct sock *mc_autojoin_sk;
85#ifdef CONFIG_IPV6_MROUTE 87#ifdef CONFIG_IPV6_MROUTE
86#ifndef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES 88#ifndef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES
87 struct mr6_table *mrt6; 89 struct mr_table *mrt6;
88#else 90#else
89 struct list_head mr6_tables; 91 struct list_head mr6_tables;
90 struct fib_rules_ops *mr6_rules_ops; 92 struct fib_rules_ops *mr6_rules_ops;
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index 87406252f0a3..e828d31be5da 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -806,6 +806,7 @@ enum tc_prio_command {
806 TC_PRIO_REPLACE, 806 TC_PRIO_REPLACE,
807 TC_PRIO_DESTROY, 807 TC_PRIO_DESTROY,
808 TC_PRIO_STATS, 808 TC_PRIO_STATS,
809 TC_PRIO_GRAFT,
809}; 810};
810 811
811struct tc_prio_qopt_offload_params { 812struct tc_prio_qopt_offload_params {
@@ -818,6 +819,11 @@ struct tc_prio_qopt_offload_params {
818 struct gnet_stats_queue *qstats; 819 struct gnet_stats_queue *qstats;
819}; 820};
820 821
822struct tc_prio_qopt_offload_graft_params {
823 u8 band;
824 u32 child_handle;
825};
826
821struct tc_prio_qopt_offload { 827struct tc_prio_qopt_offload {
822 enum tc_prio_command command; 828 enum tc_prio_command command;
823 u32 handle; 829 u32 handle;
@@ -825,6 +831,8 @@ struct tc_prio_qopt_offload {
825 union { 831 union {
826 struct tc_prio_qopt_offload_params replace_params; 832 struct tc_prio_qopt_offload_params replace_params;
827 struct tc_qopt_offload_stats stats; 833 struct tc_qopt_offload_stats stats;
834 struct tc_prio_qopt_offload_graft_params graft_params;
828 }; 835 };
829}; 836};
837
830#endif 838#endif
diff --git a/include/net/route.h b/include/net/route.h
index 20a92ca9e115..dbb032d5921b 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -66,8 +66,6 @@ struct rtable {
66 u32 rt_mtu_locked:1, 66 u32 rt_mtu_locked:1,
67 rt_pmtu:31; 67 rt_pmtu:31;
68 68
69 u32 rt_table_id;
70
71 struct list_head rt_uncached; 69 struct list_head rt_uncached;
72 struct uncached_list *rt_uncached_list; 70 struct uncached_list *rt_uncached_list;
73}; 71};
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 2092d33194dd..493e311bbe93 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -540,7 +540,7 @@ static inline bool skb_skip_tc_classify(struct sk_buff *skb)
540 return false; 540 return false;
541} 541}
542 542
543/* Reset all TX qdiscs greater then index of a device. */ 543/* Reset all TX qdiscs greater than index of a device. */
544static inline void qdisc_reset_all_tx_gt(struct net_device *dev, unsigned int i) 544static inline void qdisc_reset_all_tx_gt(struct net_device *dev, unsigned int i)
545{ 545{
546 struct Qdisc *qdisc; 546 struct Qdisc *qdisc;
diff --git a/include/net/sctp/auth.h b/include/net/sctp/auth.h
index e5c57d0a082d..687e7f80037d 100644
--- a/include/net/sctp/auth.h
+++ b/include/net/sctp/auth.h
@@ -62,8 +62,10 @@ struct sctp_auth_bytes {
62/* Definition for a shared key, weather endpoint or association */ 62/* Definition for a shared key, weather endpoint or association */
63struct sctp_shared_key { 63struct sctp_shared_key {
64 struct list_head key_list; 64 struct list_head key_list;
65 __u16 key_id;
66 struct sctp_auth_bytes *key; 65 struct sctp_auth_bytes *key;
66 refcount_t refcnt;
67 __u16 key_id;
68 __u8 deactivated;
67}; 69};
68 70
69#define key_for_each(__key, __list_head) \ 71#define key_for_each(__key, __list_head) \
@@ -103,21 +105,22 @@ int sctp_auth_send_cid(enum sctp_cid chunk,
103int sctp_auth_recv_cid(enum sctp_cid chunk, 105int sctp_auth_recv_cid(enum sctp_cid chunk,
104 const struct sctp_association *asoc); 106 const struct sctp_association *asoc);
105void sctp_auth_calculate_hmac(const struct sctp_association *asoc, 107void sctp_auth_calculate_hmac(const struct sctp_association *asoc,
106 struct sk_buff *skb, 108 struct sk_buff *skb, struct sctp_auth_chunk *auth,
107 struct sctp_auth_chunk *auth, gfp_t gfp); 109 struct sctp_shared_key *ep_key, gfp_t gfp);
110void sctp_auth_shkey_release(struct sctp_shared_key *sh_key);
111void sctp_auth_shkey_hold(struct sctp_shared_key *sh_key);
108 112
109/* API Helpers */ 113/* API Helpers */
110int sctp_auth_ep_add_chunkid(struct sctp_endpoint *ep, __u8 chunk_id); 114int sctp_auth_ep_add_chunkid(struct sctp_endpoint *ep, __u8 chunk_id);
111int sctp_auth_ep_set_hmacs(struct sctp_endpoint *ep, 115int sctp_auth_ep_set_hmacs(struct sctp_endpoint *ep,
112 struct sctp_hmacalgo *hmacs); 116 struct sctp_hmacalgo *hmacs);
113int sctp_auth_set_key(struct sctp_endpoint *ep, 117int sctp_auth_set_key(struct sctp_endpoint *ep, struct sctp_association *asoc,
114 struct sctp_association *asoc,
115 struct sctp_authkey *auth_key); 118 struct sctp_authkey *auth_key);
116int sctp_auth_set_active_key(struct sctp_endpoint *ep, 119int sctp_auth_set_active_key(struct sctp_endpoint *ep,
117 struct sctp_association *asoc, 120 struct sctp_association *asoc, __u16 key_id);
118 __u16 key_id);
119int sctp_auth_del_key_id(struct sctp_endpoint *ep, 121int sctp_auth_del_key_id(struct sctp_endpoint *ep,
120 struct sctp_association *asoc, 122 struct sctp_association *asoc, __u16 key_id);
121 __u16 key_id); 123int sctp_auth_deact_key_id(struct sctp_endpoint *ep,
124 struct sctp_association *asoc, __u16 key_id);
122 125
123#endif 126#endif
diff --git a/include/net/sctp/command.h b/include/net/sctp/command.h
index b55c6a48a206..6640f84fe536 100644
--- a/include/net/sctp/command.h
+++ b/include/net/sctp/command.h
@@ -100,6 +100,7 @@ enum sctp_verb {
100 SCTP_CMD_SET_SK_ERR, /* Set sk_err */ 100 SCTP_CMD_SET_SK_ERR, /* Set sk_err */
101 SCTP_CMD_ASSOC_CHANGE, /* generate and send assoc_change event */ 101 SCTP_CMD_ASSOC_CHANGE, /* generate and send assoc_change event */
102 SCTP_CMD_ADAPTATION_IND, /* generate and send adaptation event */ 102 SCTP_CMD_ADAPTATION_IND, /* generate and send adaptation event */
103 SCTP_CMD_PEER_NO_AUTH, /* generate and send authentication event */
103 SCTP_CMD_ASSOC_SHKEY, /* generate the association shared keys */ 104 SCTP_CMD_ASSOC_SHKEY, /* generate the association shared keys */
104 SCTP_CMD_T1_RETRAN, /* Mark for retransmission after T1 timeout */ 105 SCTP_CMD_T1_RETRAN, /* Mark for retransmission after T1 timeout */
105 SCTP_CMD_UPDATE_INITTAG, /* Update peer inittag */ 106 SCTP_CMD_UPDATE_INITTAG, /* Update peer inittag */
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index f7ae6b0a21d0..72c5b8fc3232 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -180,14 +180,7 @@ struct sctp_transport *sctp_epaddr_lookup_transport(
180/* 180/*
181 * sctp/proc.c 181 * sctp/proc.c
182 */ 182 */
183int sctp_snmp_proc_init(struct net *net); 183int __net_init sctp_proc_init(struct net *net);
184void sctp_snmp_proc_exit(struct net *net);
185int sctp_eps_proc_init(struct net *net);
186void sctp_eps_proc_exit(struct net *net);
187int sctp_assocs_proc_init(struct net *net);
188void sctp_assocs_proc_exit(struct net *net);
189int sctp_remaddr_proc_init(struct net *net);
190void sctp_remaddr_proc_exit(struct net *net);
191 184
192/* 185/*
193 * sctp/offload.c 186 * sctp/offload.c
@@ -318,7 +311,6 @@ atomic_t sctp_dbg_objcnt_## name = ATOMIC_INIT(0)
318{.label= #name, .counter= &sctp_dbg_objcnt_## name} 311{.label= #name, .counter= &sctp_dbg_objcnt_## name}
319 312
320void sctp_dbg_objcnt_init(struct net *); 313void sctp_dbg_objcnt_init(struct net *);
321void sctp_dbg_objcnt_exit(struct net *);
322 314
323#else 315#else
324 316
@@ -326,7 +318,6 @@ void sctp_dbg_objcnt_exit(struct net *);
326#define SCTP_DBG_OBJCNT_DEC(name) 318#define SCTP_DBG_OBJCNT_DEC(name)
327 319
328static inline void sctp_dbg_objcnt_init(struct net *net) { return; } 320static inline void sctp_dbg_objcnt_init(struct net *net) { return; }
329static inline void sctp_dbg_objcnt_exit(struct net *net) { return; }
330 321
331#endif /* CONFIG_SCTP_DBG_OBJCOUNT */ 322#endif /* CONFIG_SCTP_DBG_OBJCOUNT */
332 323
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index 2883c43c5258..2d0e782c9055 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -263,7 +263,8 @@ int sctp_process_asconf_ack(struct sctp_association *asoc,
263struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc, 263struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc,
264 __u32 new_cum_tsn, size_t nstreams, 264 __u32 new_cum_tsn, size_t nstreams,
265 struct sctp_fwdtsn_skip *skiplist); 265 struct sctp_fwdtsn_skip *skiplist);
266struct sctp_chunk *sctp_make_auth(const struct sctp_association *asoc); 266struct sctp_chunk *sctp_make_auth(const struct sctp_association *asoc,
267 __u16 key_id);
267struct sctp_chunk *sctp_make_strreset_req(const struct sctp_association *asoc, 268struct sctp_chunk *sctp_make_strreset_req(const struct sctp_association *asoc,
268 __u16 stream_num, __be16 *stream_list, 269 __u16 stream_num, __be16 *stream_list,
269 bool out, bool in); 270 bool out, bool in);
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 03e92dda1813..012fb3e2f4cf 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -577,8 +577,12 @@ struct sctp_chunk {
577 /* This points to the sk_buff containing the actual data. */ 577 /* This points to the sk_buff containing the actual data. */
578 struct sk_buff *skb; 578 struct sk_buff *skb;
579 579
580 /* In case of GSO packets, this will store the head one */ 580 union {
581 struct sk_buff *head_skb; 581 /* In case of GSO packets, this will store the head one */
582 struct sk_buff *head_skb;
583 /* In case of auth enabled, this will point to the shkey */
584 struct sctp_shared_key *shkey;
585 };
582 586
583 /* These are the SCTP headers by reverse order in a packet. 587 /* These are the SCTP headers by reverse order in a packet.
584 * Note that some of these may happen more than once. In that 588 * Note that some of these may happen more than once. In that
@@ -1995,6 +1999,7 @@ struct sctp_association {
1995 * The current generated assocaition shared key (secret) 1999 * The current generated assocaition shared key (secret)
1996 */ 2000 */
1997 struct sctp_auth_bytes *asoc_shared_key; 2001 struct sctp_auth_bytes *asoc_shared_key;
2002 struct sctp_shared_key *shkey;
1998 2003
1999 /* SCTP AUTH: hmac id of the first peer requested algorithm 2004 /* SCTP AUTH: hmac id of the first peer requested algorithm
2000 * that we support. 2005 * that we support.
@@ -2112,6 +2117,9 @@ struct sctp_cmsgs {
2112 struct sctp_initmsg *init; 2117 struct sctp_initmsg *init;
2113 struct sctp_sndrcvinfo *srinfo; 2118 struct sctp_sndrcvinfo *srinfo;
2114 struct sctp_sndinfo *sinfo; 2119 struct sctp_sndinfo *sinfo;
2120 struct sctp_prinfo *prinfo;
2121 struct sctp_authinfo *authinfo;
2122 struct msghdr *addrs_msg;
2115}; 2123};
2116 2124
2117/* Structure for tracking memory objects */ 2125/* Structure for tracking memory objects */
diff --git a/include/net/sock.h b/include/net/sock.h
index ae23f3b389ca..709311132d4c 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -417,6 +417,7 @@ struct sock {
417 struct page_frag sk_frag; 417 struct page_frag sk_frag;
418 netdev_features_t sk_route_caps; 418 netdev_features_t sk_route_caps;
419 netdev_features_t sk_route_nocaps; 419 netdev_features_t sk_route_nocaps;
420 netdev_features_t sk_route_forced_caps;
420 int sk_gso_type; 421 int sk_gso_type;
421 unsigned int sk_gso_max_size; 422 unsigned int sk_gso_max_size;
422 gfp_t sk_allocation; 423 gfp_t sk_allocation;
@@ -1585,7 +1586,7 @@ int sock_no_bind(struct socket *, struct sockaddr *, int);
1585int sock_no_connect(struct socket *, struct sockaddr *, int, int); 1586int sock_no_connect(struct socket *, struct sockaddr *, int, int);
1586int sock_no_socketpair(struct socket *, struct socket *); 1587int sock_no_socketpair(struct socket *, struct socket *);
1587int sock_no_accept(struct socket *, struct socket *, int, bool); 1588int sock_no_accept(struct socket *, struct socket *, int, bool);
1588int sock_no_getname(struct socket *, struct sockaddr *, int *, int); 1589int sock_no_getname(struct socket *, struct sockaddr *, int);
1589__poll_t sock_no_poll(struct file *, struct socket *, 1590__poll_t sock_no_poll(struct file *, struct socket *,
1590 struct poll_table_struct *); 1591 struct poll_table_struct *);
1591int sock_no_ioctl(struct socket *, unsigned int, unsigned long); 1592int sock_no_ioctl(struct socket *, unsigned int, unsigned long);
@@ -1863,15 +1864,6 @@ static inline void sk_nocaps_add(struct sock *sk, netdev_features_t flags)
1863 sk->sk_route_caps &= ~flags; 1864 sk->sk_route_caps &= ~flags;
1864} 1865}
1865 1866
1866static inline bool sk_check_csum_caps(struct sock *sk)
1867{
1868 return (sk->sk_route_caps & NETIF_F_HW_CSUM) ||
1869 (sk->sk_family == PF_INET &&
1870 (sk->sk_route_caps & NETIF_F_IP_CSUM)) ||
1871 (sk->sk_family == PF_INET6 &&
1872 (sk->sk_route_caps & NETIF_F_IPV6_CSUM));
1873}
1874
1875static inline int skb_do_copy_data_nocache(struct sock *sk, struct sk_buff *skb, 1867static inline int skb_do_copy_data_nocache(struct sock *sk, struct sk_buff *skb,
1876 struct iov_iter *from, char *to, 1868 struct iov_iter *from, char *to,
1877 int copy, int offset) 1869 int copy, int offset)
@@ -2150,6 +2142,10 @@ static inline struct page_frag *sk_page_frag(struct sock *sk)
2150 2142
2151bool sk_page_frag_refill(struct sock *sk, struct page_frag *pfrag); 2143bool sk_page_frag_refill(struct sock *sk, struct page_frag *pfrag);
2152 2144
2145int sk_alloc_sg(struct sock *sk, int len, struct scatterlist *sg,
2146 int sg_start, int *sg_curr, unsigned int *sg_size,
2147 int first_coalesce);
2148
2153/* 2149/*
2154 * Default write policy as shown to user space via poll/select/SIGIO 2150 * Default write policy as shown to user space via poll/select/SIGIO
2155 */ 2151 */
diff --git a/include/net/tcp.h b/include/net/tcp.h
index e3fc667f9ac2..9c9b3768b350 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -374,7 +374,8 @@ enum tcp_tw_status tcp_timewait_state_process(struct inet_timewait_sock *tw,
374 struct sk_buff *skb, 374 struct sk_buff *skb,
375 const struct tcphdr *th); 375 const struct tcphdr *th);
376struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, 376struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
377 struct request_sock *req, bool fastopen); 377 struct request_sock *req, bool fastopen,
378 bool *lost_race);
378int tcp_child_process(struct sock *parent, struct sock *child, 379int tcp_child_process(struct sock *parent, struct sock *child,
379 struct sk_buff *skb); 380 struct sk_buff *skb);
380void tcp_enter_loss(struct sock *sk); 381void tcp_enter_loss(struct sock *sk);
@@ -510,8 +511,6 @@ __u32 cookie_v6_init_sequence(const struct sk_buff *skb, __u16 *mss);
510#endif 511#endif
511/* tcp_output.c */ 512/* tcp_output.c */
512 513
513u32 tcp_tso_autosize(const struct sock *sk, unsigned int mss_now,
514 int min_tso_segs);
515void __tcp_push_pending_frames(struct sock *sk, unsigned int cur_mss, 514void __tcp_push_pending_frames(struct sock *sk, unsigned int cur_mss,
516 int nonagle); 515 int nonagle);
517int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs); 516int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs);
@@ -980,8 +979,8 @@ struct tcp_congestion_ops {
980 u32 (*undo_cwnd)(struct sock *sk); 979 u32 (*undo_cwnd)(struct sock *sk);
981 /* hook for packet ack accounting (optional) */ 980 /* hook for packet ack accounting (optional) */
982 void (*pkts_acked)(struct sock *sk, const struct ack_sample *sample); 981 void (*pkts_acked)(struct sock *sk, const struct ack_sample *sample);
983 /* suggest number of segments for each skb to transmit (optional) */ 982 /* override sysctl_tcp_min_tso_segs */
984 u32 (*tso_segs_goal)(struct sock *sk); 983 u32 (*min_tso_segs)(struct sock *sk);
985 /* returns the multiplier used in tcp_sndbuf_expand (optional) */ 984 /* returns the multiplier used in tcp_sndbuf_expand (optional) */
986 u32 (*sndbuf_expand)(struct sock *sk); 985 u32 (*sndbuf_expand)(struct sock *sk);
987 /* call when packets are delivered to update cwnd and pacing rate, 986 /* call when packets are delivered to update cwnd and pacing rate,
diff --git a/include/net/tcp_states.h b/include/net/tcp_states.h
index 50e78a74d0df..2875e169d744 100644
--- a/include/net/tcp_states.h
+++ b/include/net/tcp_states.h
@@ -32,21 +32,21 @@ enum {
32 32
33#define TCP_STATE_MASK 0xF 33#define TCP_STATE_MASK 0xF
34 34
35#define TCP_ACTION_FIN (1 << 7) 35#define TCP_ACTION_FIN (1 << TCP_CLOSE)
36 36
37enum { 37enum {
38 TCPF_ESTABLISHED = (1 << 1), 38 TCPF_ESTABLISHED = (1 << TCP_ESTABLISHED),
39 TCPF_SYN_SENT = (1 << 2), 39 TCPF_SYN_SENT = (1 << TCP_SYN_SENT),
40 TCPF_SYN_RECV = (1 << 3), 40 TCPF_SYN_RECV = (1 << TCP_SYN_RECV),
41 TCPF_FIN_WAIT1 = (1 << 4), 41 TCPF_FIN_WAIT1 = (1 << TCP_FIN_WAIT1),
42 TCPF_FIN_WAIT2 = (1 << 5), 42 TCPF_FIN_WAIT2 = (1 << TCP_FIN_WAIT2),
43 TCPF_TIME_WAIT = (1 << 6), 43 TCPF_TIME_WAIT = (1 << TCP_TIME_WAIT),
44 TCPF_CLOSE = (1 << 7), 44 TCPF_CLOSE = (1 << TCP_CLOSE),
45 TCPF_CLOSE_WAIT = (1 << 8), 45 TCPF_CLOSE_WAIT = (1 << TCP_CLOSE_WAIT),
46 TCPF_LAST_ACK = (1 << 9), 46 TCPF_LAST_ACK = (1 << TCP_LAST_ACK),
47 TCPF_LISTEN = (1 << 10), 47 TCPF_LISTEN = (1 << TCP_LISTEN),
48 TCPF_CLOSING = (1 << 11), 48 TCPF_CLOSING = (1 << TCP_CLOSING),
49 TCPF_NEW_SYN_RECV = (1 << 12), 49 TCPF_NEW_SYN_RECV = (1 << TCP_NEW_SYN_RECV),
50}; 50};
51 51
52#endif /* _LINUX_TCP_STATES_H */ 52#endif /* _LINUX_TCP_STATES_H */
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 7d2077665c0b..aa027ba1d032 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1267,12 +1267,12 @@ static inline void xfrm_sk_free_policy(struct sock *sk)
1267 1267
1268static inline void xfrm_sk_free_policy(struct sock *sk) {} 1268static inline void xfrm_sk_free_policy(struct sock *sk) {}
1269static inline int xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk) { return 0; } 1269static inline int xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk) { return 0; }
1270static inline int xfrm6_route_forward(struct sk_buff *skb) { return 1; } 1270static inline int xfrm6_route_forward(struct sk_buff *skb) { return 1; }
1271static inline int xfrm4_route_forward(struct sk_buff *skb) { return 1; } 1271static inline int xfrm4_route_forward(struct sk_buff *skb) { return 1; }
1272static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb) 1272static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
1273{ 1273{
1274 return 1; 1274 return 1;
1275} 1275}
1276static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb) 1276static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
1277{ 1277{
1278 return 1; 1278 return 1;
@@ -1356,7 +1356,7 @@ __xfrm6_state_addr_check(const struct xfrm_state *x,
1356{ 1356{
1357 if (ipv6_addr_equal((struct in6_addr *)daddr, (struct in6_addr *)&x->id.daddr) && 1357 if (ipv6_addr_equal((struct in6_addr *)daddr, (struct in6_addr *)&x->id.daddr) &&
1358 (ipv6_addr_equal((struct in6_addr *)saddr, (struct in6_addr *)&x->props.saddr) || 1358 (ipv6_addr_equal((struct in6_addr *)saddr, (struct in6_addr *)&x->props.saddr) ||
1359 ipv6_addr_any((struct in6_addr *)saddr) || 1359 ipv6_addr_any((struct in6_addr *)saddr) ||
1360 ipv6_addr_any((struct in6_addr *)&x->props.saddr))) 1360 ipv6_addr_any((struct in6_addr *)&x->props.saddr)))
1361 return 1; 1361 return 1;
1362 return 0; 1362 return 0;
@@ -1666,7 +1666,7 @@ int xfrm_user_policy(struct sock *sk, int optname,
1666static inline int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen) 1666static inline int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen)
1667{ 1667{
1668 return -ENOPROTOOPT; 1668 return -ENOPROTOOPT;
1669} 1669}
1670 1670
1671static inline int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb) 1671static inline int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
1672{ 1672{
diff --git a/include/uapi/linux/batadv_packet.h b/include/uapi/linux/batadv_packet.h
index 5cb360be2a11..894d8d2f713d 100644
--- a/include/uapi/linux/batadv_packet.h
+++ b/include/uapi/linux/batadv_packet.h
@@ -1,5 +1,5 @@
1/* SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) */ 1/* SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) */
2/* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2007-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner, Simon Wunderlich 4 * Marek Lindner, Simon Wunderlich
5 * 5 *
@@ -196,8 +196,6 @@ struct batadv_bla_claim_dst {
196 __be16 group; /* group id */ 196 __be16 group; /* group id */
197}; 197};
198 198
199#pragma pack()
200
201/** 199/**
202 * struct batadv_ogm_packet - ogm (routing protocol) packet 200 * struct batadv_ogm_packet - ogm (routing protocol) packet
203 * @packet_type: batman-adv packet type, part of the general header 201 * @packet_type: batman-adv packet type, part of the general header
@@ -222,9 +220,6 @@ struct batadv_ogm_packet {
222 __u8 reserved; 220 __u8 reserved;
223 __u8 tq; 221 __u8 tq;
224 __be16 tvlv_len; 222 __be16 tvlv_len;
225 /* __packed is not needed as the struct size is divisible by 4,
226 * and the largest data type in this struct has a size of 4.
227 */
228}; 223};
229 224
230#define BATADV_OGM_HLEN sizeof(struct batadv_ogm_packet) 225#define BATADV_OGM_HLEN sizeof(struct batadv_ogm_packet)
@@ -249,9 +244,6 @@ struct batadv_ogm2_packet {
249 __u8 orig[ETH_ALEN]; 244 __u8 orig[ETH_ALEN];
250 __be16 tvlv_len; 245 __be16 tvlv_len;
251 __be32 throughput; 246 __be32 throughput;
252 /* __packed is not needed as the struct size is divisible by 4,
253 * and the largest data type in this struct has a size of 4.
254 */
255}; 247};
256 248
257#define BATADV_OGM2_HLEN sizeof(struct batadv_ogm2_packet) 249#define BATADV_OGM2_HLEN sizeof(struct batadv_ogm2_packet)
@@ -405,7 +397,6 @@ struct batadv_icmp_packet_rr {
405 * misalignment of the payload after the ethernet header. It may also lead to 397 * misalignment of the payload after the ethernet header. It may also lead to
406 * leakage of information when the padding it not initialized before sending. 398 * leakage of information when the padding it not initialized before sending.
407 */ 399 */
408#pragma pack(2)
409 400
410/** 401/**
411 * struct batadv_unicast_packet - unicast packet for network payload 402 * struct batadv_unicast_packet - unicast packet for network payload
@@ -533,8 +524,6 @@ struct batadv_coded_packet {
533 __be16 coded_len; 524 __be16 coded_len;
534}; 525};
535 526
536#pragma pack()
537
538/** 527/**
539 * struct batadv_unicast_tvlv_packet - generic unicast packet with tvlv payload 528 * struct batadv_unicast_tvlv_packet - generic unicast packet with tvlv payload
540 * @packet_type: batman-adv packet type, part of the general header 529 * @packet_type: batman-adv packet type, part of the general header
@@ -641,4 +630,6 @@ struct batadv_tvlv_mcast_data {
641 __u8 reserved[3]; 630 __u8 reserved[3];
642}; 631};
643 632
633#pragma pack()
634
644#endif /* _UAPI_LINUX_BATADV_PACKET_H_ */ 635#endif /* _UAPI_LINUX_BATADV_PACKET_H_ */
diff --git a/include/uapi/linux/batman_adv.h b/include/uapi/linux/batman_adv.h
index ae00c99cbed0..324a0e1143e7 100644
--- a/include/uapi/linux/batman_adv.h
+++ b/include/uapi/linux/batman_adv.h
@@ -1,5 +1,5 @@
1/* SPDX-License-Identifier: MIT */ 1/* SPDX-License-Identifier: MIT */
2/* Copyright (C) 2016-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2016-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Matthias Schiffer 4 * Matthias Schiffer
5 * 5 *
@@ -92,6 +92,53 @@ enum batadv_tt_client_flags {
92}; 92};
93 93
94/** 94/**
95 * enum batadv_mcast_flags_priv - Private, own multicast flags
96 *
97 * These are internal, multicast related flags. Currently they describe certain
98 * multicast related attributes of the segment this originator bridges into the
99 * mesh.
100 *
101 * Those attributes are used to determine the public multicast flags this
102 * originator is going to announce via TT.
103 *
104 * For netlink, if BATADV_MCAST_FLAGS_BRIDGED is unset then all querier
105 * related flags are undefined.
106 */
107enum batadv_mcast_flags_priv {
108 /**
109 * @BATADV_MCAST_FLAGS_BRIDGED: There is a bridge on top of the mesh
110 * interface.
111 */
112 BATADV_MCAST_FLAGS_BRIDGED = (1 << 0),
113
114 /**
115 * @BATADV_MCAST_FLAGS_QUERIER_IPV4_EXISTS: Whether an IGMP querier
116 * exists in the mesh
117 */
118 BATADV_MCAST_FLAGS_QUERIER_IPV4_EXISTS = (1 << 1),
119
120 /**
121 * @BATADV_MCAST_FLAGS_QUERIER_IPV6_EXISTS: Whether an MLD querier
122 * exists in the mesh
123 */
124 BATADV_MCAST_FLAGS_QUERIER_IPV6_EXISTS = (1 << 2),
125
126 /**
127 * @BATADV_MCAST_FLAGS_QUERIER_IPV4_SHADOWING: If an IGMP querier
128 * exists, whether it is potentially shadowing multicast listeners
129 * (i.e. querier is behind our own bridge segment)
130 */
131 BATADV_MCAST_FLAGS_QUERIER_IPV4_SHADOWING = (1 << 3),
132
133 /**
134 * @BATADV_MCAST_FLAGS_QUERIER_IPV6_SHADOWING: If an MLD querier
135 * exists, whether it is potentially shadowing multicast listeners
136 * (i.e. querier is behind our own bridge segment)
137 */
138 BATADV_MCAST_FLAGS_QUERIER_IPV6_SHADOWING = (1 << 4),
139};
140
141/**
95 * enum batadv_nl_attrs - batman-adv netlink attributes 142 * enum batadv_nl_attrs - batman-adv netlink attributes
96 */ 143 */
97enum batadv_nl_attrs { 144enum batadv_nl_attrs {
@@ -272,6 +319,31 @@ enum batadv_nl_attrs {
272 */ 319 */
273 BATADV_ATTR_BLA_CRC, 320 BATADV_ATTR_BLA_CRC,
274 321
322 /**
323 * @BATADV_ATTR_DAT_CACHE_IP4ADDRESS: Client IPv4 address
324 */
325 BATADV_ATTR_DAT_CACHE_IP4ADDRESS,
326
327 /**
328 * @BATADV_ATTR_DAT_CACHE_HWADDRESS: Client MAC address
329 */
330 BATADV_ATTR_DAT_CACHE_HWADDRESS,
331
332 /**
333 * @BATADV_ATTR_DAT_CACHE_VID: VLAN ID
334 */
335 BATADV_ATTR_DAT_CACHE_VID,
336
337 /**
338 * @BATADV_ATTR_MCAST_FLAGS: Per originator multicast flags
339 */
340 BATADV_ATTR_MCAST_FLAGS,
341
342 /**
343 * @BATADV_ATTR_MCAST_FLAGS_PRIV: Private, own multicast flags
344 */
345 BATADV_ATTR_MCAST_FLAGS_PRIV,
346
275 /* add attributes above here, update the policy in netlink.c */ 347 /* add attributes above here, update the policy in netlink.c */
276 348
277 /** 349 /**
@@ -361,6 +433,16 @@ enum batadv_nl_commands {
361 */ 433 */
362 BATADV_CMD_GET_BLA_BACKBONE, 434 BATADV_CMD_GET_BLA_BACKBONE,
363 435
436 /**
437 * @BATADV_CMD_GET_DAT_CACHE: Query list of DAT cache entries
438 */
439 BATADV_CMD_GET_DAT_CACHE,
440
441 /**
442 * @BATADV_CMD_GET_MCAST_FLAGS: Query list of multicast flags
443 */
444 BATADV_CMD_GET_MCAST_FLAGS,
445
364 /* add new commands above here */ 446 /* add new commands above here */
365 447
366 /** 448 /**
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index db6bdc375126..18b7c510c511 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -133,6 +133,7 @@ enum bpf_prog_type {
133 BPF_PROG_TYPE_SOCK_OPS, 133 BPF_PROG_TYPE_SOCK_OPS,
134 BPF_PROG_TYPE_SK_SKB, 134 BPF_PROG_TYPE_SK_SKB,
135 BPF_PROG_TYPE_CGROUP_DEVICE, 135 BPF_PROG_TYPE_CGROUP_DEVICE,
136 BPF_PROG_TYPE_SK_MSG,
136}; 137};
137 138
138enum bpf_attach_type { 139enum bpf_attach_type {
@@ -143,6 +144,7 @@ enum bpf_attach_type {
143 BPF_SK_SKB_STREAM_PARSER, 144 BPF_SK_SKB_STREAM_PARSER,
144 BPF_SK_SKB_STREAM_VERDICT, 145 BPF_SK_SKB_STREAM_VERDICT,
145 BPF_CGROUP_DEVICE, 146 BPF_CGROUP_DEVICE,
147 BPF_SK_MSG_VERDICT,
146 __MAX_BPF_ATTACH_TYPE 148 __MAX_BPF_ATTACH_TYPE
147}; 149};
148 150
@@ -231,6 +233,28 @@ enum bpf_attach_type {
231#define BPF_F_RDONLY (1U << 3) 233#define BPF_F_RDONLY (1U << 3)
232#define BPF_F_WRONLY (1U << 4) 234#define BPF_F_WRONLY (1U << 4)
233 235
236/* Flag for stack_map, store build_id+offset instead of pointer */
237#define BPF_F_STACK_BUILD_ID (1U << 5)
238
239enum bpf_stack_build_id_status {
240 /* user space need an empty entry to identify end of a trace */
241 BPF_STACK_BUILD_ID_EMPTY = 0,
242 /* with valid build_id and offset */
243 BPF_STACK_BUILD_ID_VALID = 1,
244 /* couldn't get build_id, fallback to ip */
245 BPF_STACK_BUILD_ID_IP = 2,
246};
247
248#define BPF_BUILD_ID_SIZE 20
249struct bpf_stack_build_id {
250 __s32 status;
251 unsigned char build_id[BPF_BUILD_ID_SIZE];
252 union {
253 __u64 offset;
254 __u64 ip;
255 };
256};
257
234union bpf_attr { 258union bpf_attr {
235 struct { /* anonymous struct used by BPF_MAP_CREATE command */ 259 struct { /* anonymous struct used by BPF_MAP_CREATE command */
236 __u32 map_type; /* one of enum bpf_map_type */ 260 __u32 map_type; /* one of enum bpf_map_type */
@@ -696,6 +720,15 @@ union bpf_attr {
696 * int bpf_override_return(pt_regs, rc) 720 * int bpf_override_return(pt_regs, rc)
697 * @pt_regs: pointer to struct pt_regs 721 * @pt_regs: pointer to struct pt_regs
698 * @rc: the return value to set 722 * @rc: the return value to set
723 *
724 * int bpf_msg_redirect_map(map, key, flags)
725 * Redirect msg to a sock in map using key as a lookup key for the
726 * sock in map.
727 * @map: pointer to sockmap
728 * @key: key to lookup sock in map
729 * @flags: reserved for future use
730 * Return: SK_PASS
731 *
699 */ 732 */
700#define __BPF_FUNC_MAPPER(FN) \ 733#define __BPF_FUNC_MAPPER(FN) \
701 FN(unspec), \ 734 FN(unspec), \
@@ -757,7 +790,11 @@ union bpf_attr {
757 FN(perf_prog_read_value), \ 790 FN(perf_prog_read_value), \
758 FN(getsockopt), \ 791 FN(getsockopt), \
759 FN(override_return), \ 792 FN(override_return), \
760 FN(sock_ops_cb_flags_set), 793 FN(sock_ops_cb_flags_set), \
794 FN(msg_redirect_map), \
795 FN(msg_apply_bytes), \
796 FN(msg_cork_bytes), \
797 FN(msg_pull_data),
761 798
762/* integer value in 'imm' field of BPF_CALL instruction selects which helper 799/* integer value in 'imm' field of BPF_CALL instruction selects which helper
763 * function eBPF program intends to call 800 * function eBPF program intends to call
@@ -800,6 +837,7 @@ enum bpf_func_id {
800/* BPF_FUNC_skb_set_tunnel_key flags. */ 837/* BPF_FUNC_skb_set_tunnel_key flags. */
801#define BPF_F_ZERO_CSUM_TX (1ULL << 1) 838#define BPF_F_ZERO_CSUM_TX (1ULL << 1)
802#define BPF_F_DONT_FRAGMENT (1ULL << 2) 839#define BPF_F_DONT_FRAGMENT (1ULL << 2)
840#define BPF_F_SEQ_NUMBER (1ULL << 3)
803 841
804/* BPF_FUNC_perf_event_output, BPF_FUNC_perf_event_read and 842/* BPF_FUNC_perf_event_output, BPF_FUNC_perf_event_read and
805 * BPF_FUNC_perf_event_read_value flags. 843 * BPF_FUNC_perf_event_read_value flags.
@@ -919,6 +957,14 @@ enum sk_action {
919 SK_PASS, 957 SK_PASS,
920}; 958};
921 959
960/* user accessible metadata for SK_MSG packet hook, new fields must
961 * be added to the end of this structure
962 */
963struct sk_msg_md {
964 void *data;
965 void *data_end;
966};
967
922#define BPF_TAG_SIZE 8 968#define BPF_TAG_SIZE 8
923 969
924struct bpf_prog_info { 970struct bpf_prog_info {
diff --git a/include/uapi/linux/bpf_perf_event.h b/include/uapi/linux/bpf_perf_event.h
index 8f95303f9d80..eb1b9d21250c 100644
--- a/include/uapi/linux/bpf_perf_event.h
+++ b/include/uapi/linux/bpf_perf_event.h
@@ -13,6 +13,7 @@
13struct bpf_perf_event_data { 13struct bpf_perf_event_data {
14 bpf_user_pt_regs_t regs; 14 bpf_user_pt_regs_t regs;
15 __u64 sample_period; 15 __u64 sample_period;
16 __u64 addr;
16}; 17};
17 18
18#endif /* _UAPI__LINUX_BPF_PERF_EVENT_H__ */ 19#endif /* _UAPI__LINUX_BPF_PERF_EVENT_H__ */
diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
index 44a0b675a6bc..20da156aaf64 100644
--- a/include/uapi/linux/ethtool.h
+++ b/include/uapi/linux/ethtool.h
@@ -914,12 +914,15 @@ static inline __u64 ethtool_get_flow_spec_ring_vf(__u64 ring_cookie)
914 * @flow_type: Type of flow to be affected, e.g. %TCP_V4_FLOW 914 * @flow_type: Type of flow to be affected, e.g. %TCP_V4_FLOW
915 * @data: Command-dependent value 915 * @data: Command-dependent value
916 * @fs: Flow classification rule 916 * @fs: Flow classification rule
917 * @rss_context: RSS context to be affected
917 * @rule_cnt: Number of rules to be affected 918 * @rule_cnt: Number of rules to be affected
918 * @rule_locs: Array of used rule locations 919 * @rule_locs: Array of used rule locations
919 * 920 *
920 * For %ETHTOOL_GRXFH and %ETHTOOL_SRXFH, @data is a bitmask indicating 921 * For %ETHTOOL_GRXFH and %ETHTOOL_SRXFH, @data is a bitmask indicating
921 * the fields included in the flow hash, e.g. %RXH_IP_SRC. The following 922 * the fields included in the flow hash, e.g. %RXH_IP_SRC. The following
922 * structure fields must not be used. 923 * structure fields must not be used, except that if @flow_type includes
924 * the %FLOW_RSS flag, then @rss_context determines which RSS context to
925 * act on.
923 * 926 *
924 * For %ETHTOOL_GRXRINGS, @data is set to the number of RX rings/queues 927 * For %ETHTOOL_GRXRINGS, @data is set to the number of RX rings/queues
925 * on return. 928 * on return.
@@ -931,7 +934,9 @@ static inline __u64 ethtool_get_flow_spec_ring_vf(__u64 ring_cookie)
931 * set in @data then special location values should not be used. 934 * set in @data then special location values should not be used.
932 * 935 *
933 * For %ETHTOOL_GRXCLSRULE, @fs.@location specifies the location of an 936 * For %ETHTOOL_GRXCLSRULE, @fs.@location specifies the location of an
934 * existing rule on entry and @fs contains the rule on return. 937 * existing rule on entry and @fs contains the rule on return; if
938 * @fs.@flow_type includes the %FLOW_RSS flag, then @rss_context is
939 * filled with the RSS context ID associated with the rule.
935 * 940 *
936 * For %ETHTOOL_GRXCLSRLALL, @rule_cnt specifies the array size of the 941 * For %ETHTOOL_GRXCLSRLALL, @rule_cnt specifies the array size of the
937 * user buffer for @rule_locs on entry. On return, @data is the size 942 * user buffer for @rule_locs on entry. On return, @data is the size
@@ -942,7 +947,11 @@ static inline __u64 ethtool_get_flow_spec_ring_vf(__u64 ring_cookie)
942 * For %ETHTOOL_SRXCLSRLINS, @fs specifies the rule to add or update. 947 * For %ETHTOOL_SRXCLSRLINS, @fs specifies the rule to add or update.
943 * @fs.@location either specifies the location to use or is a special 948 * @fs.@location either specifies the location to use or is a special
944 * location value with %RX_CLS_LOC_SPECIAL flag set. On return, 949 * location value with %RX_CLS_LOC_SPECIAL flag set. On return,
945 * @fs.@location is the actual rule location. 950 * @fs.@location is the actual rule location. If @fs.@flow_type
951 * includes the %FLOW_RSS flag, @rss_context is the RSS context ID to
952 * use for flow spreading traffic which matches this rule. The value
953 * from the rxfh indirection table will be added to @fs.@ring_cookie
954 * to choose which ring to deliver to.
946 * 955 *
947 * For %ETHTOOL_SRXCLSRLDEL, @fs.@location specifies the location of an 956 * For %ETHTOOL_SRXCLSRLDEL, @fs.@location specifies the location of an
948 * existing rule on entry. 957 * existing rule on entry.
@@ -963,7 +972,10 @@ struct ethtool_rxnfc {
963 __u32 flow_type; 972 __u32 flow_type;
964 __u64 data; 973 __u64 data;
965 struct ethtool_rx_flow_spec fs; 974 struct ethtool_rx_flow_spec fs;
966 __u32 rule_cnt; 975 union {
976 __u32 rule_cnt;
977 __u32 rss_context;
978 };
967 __u32 rule_locs[0]; 979 __u32 rule_locs[0];
968}; 980};
969 981
@@ -990,7 +1002,11 @@ struct ethtool_rxfh_indir {
990/** 1002/**
991 * struct ethtool_rxfh - command to get/set RX flow hash indir or/and hash key. 1003 * struct ethtool_rxfh - command to get/set RX flow hash indir or/and hash key.
992 * @cmd: Specific command number - %ETHTOOL_GRSSH or %ETHTOOL_SRSSH 1004 * @cmd: Specific command number - %ETHTOOL_GRSSH or %ETHTOOL_SRSSH
993 * @rss_context: RSS context identifier. 1005 * @rss_context: RSS context identifier. Context 0 is the default for normal
1006 * traffic; other contexts can be referenced as the destination for RX flow
1007 * classification rules. %ETH_RXFH_CONTEXT_ALLOC is used with command
1008 * %ETHTOOL_SRSSH to allocate a new RSS context; on return this field will
1009 * contain the ID of the newly allocated context.
994 * @indir_size: On entry, the array size of the user buffer for the 1010 * @indir_size: On entry, the array size of the user buffer for the
995 * indirection table, which may be zero, or (for %ETHTOOL_SRSSH), 1011 * indirection table, which may be zero, or (for %ETHTOOL_SRSSH),
996 * %ETH_RXFH_INDIR_NO_CHANGE. On return from %ETHTOOL_GRSSH, 1012 * %ETH_RXFH_INDIR_NO_CHANGE. On return from %ETHTOOL_GRSSH,
@@ -1009,7 +1025,8 @@ struct ethtool_rxfh_indir {
1009 * size should be returned. For %ETHTOOL_SRSSH, an @indir_size of 1025 * size should be returned. For %ETHTOOL_SRSSH, an @indir_size of
1010 * %ETH_RXFH_INDIR_NO_CHANGE means that indir table setting is not requested 1026 * %ETH_RXFH_INDIR_NO_CHANGE means that indir table setting is not requested
1011 * and a @indir_size of zero means the indir table should be reset to default 1027 * and a @indir_size of zero means the indir table should be reset to default
1012 * values. An hfunc of zero means that hash function setting is not requested. 1028 * values (if @rss_context == 0) or that the RSS context should be deleted.
1029 * An hfunc of zero means that hash function setting is not requested.
1013 */ 1030 */
1014struct ethtool_rxfh { 1031struct ethtool_rxfh {
1015 __u32 cmd; 1032 __u32 cmd;
@@ -1021,6 +1038,7 @@ struct ethtool_rxfh {
1021 __u32 rsvd32; 1038 __u32 rsvd32;
1022 __u32 rss_config[0]; 1039 __u32 rss_config[0];
1023}; 1040};
1041#define ETH_RXFH_CONTEXT_ALLOC 0xffffffff
1024#define ETH_RXFH_INDIR_NO_CHANGE 0xffffffff 1042#define ETH_RXFH_INDIR_NO_CHANGE 0xffffffff
1025 1043
1026/** 1044/**
@@ -1635,6 +1653,8 @@ static inline int ethtool_validate_duplex(__u8 duplex)
1635/* Flag to enable additional fields in struct ethtool_rx_flow_spec */ 1653/* Flag to enable additional fields in struct ethtool_rx_flow_spec */
1636#define FLOW_EXT 0x80000000 1654#define FLOW_EXT 0x80000000
1637#define FLOW_MAC_EXT 0x40000000 1655#define FLOW_MAC_EXT 0x40000000
1656/* Flag to enable RSS spreading of traffic matching rule (nfc only) */
1657#define FLOW_RSS 0x20000000
1638 1658
1639/* L3-L4 network traffic flow hash options */ 1659/* L3-L4 network traffic flow hash options */
1640#define RXH_L2DA (1 << 1) 1660#define RXH_L2DA (1 << 1)
diff --git a/include/uapi/linux/fib_rules.h b/include/uapi/linux/fib_rules.h
index 2b642bf9b5a0..232df14e1287 100644
--- a/include/uapi/linux/fib_rules.h
+++ b/include/uapi/linux/fib_rules.h
@@ -23,7 +23,7 @@ struct fib_rule_hdr {
23 __u8 tos; 23 __u8 tos;
24 24
25 __u8 table; 25 __u8 table;
26 __u8 res1; /* reserved */ 26 __u8 res1; /* reserved */
27 __u8 res2; /* reserved */ 27 __u8 res2; /* reserved */
28 __u8 action; 28 __u8 action;
29 29
@@ -35,6 +35,11 @@ struct fib_rule_uid_range {
35 __u32 end; 35 __u32 end;
36}; 36};
37 37
38struct fib_rule_port_range {
39 __u16 start;
40 __u16 end;
41};
42
38enum { 43enum {
39 FRA_UNSPEC, 44 FRA_UNSPEC,
40 FRA_DST, /* destination address */ 45 FRA_DST, /* destination address */
@@ -58,6 +63,10 @@ enum {
58 FRA_PAD, 63 FRA_PAD,
59 FRA_L3MDEV, /* iif or oif is l3mdev goto its table */ 64 FRA_L3MDEV, /* iif or oif is l3mdev goto its table */
60 FRA_UID_RANGE, /* UID range */ 65 FRA_UID_RANGE, /* UID range */
66 FRA_PROTOCOL, /* Originator of the rule */
67 FRA_IP_PROTO, /* ip proto */
68 FRA_SPORT_RANGE, /* sport */
69 FRA_DPORT_RANGE, /* dport */
61 __FRA_MAX 70 __FRA_MAX
62}; 71};
63 72
diff --git a/include/uapi/linux/if_ether.h b/include/uapi/linux/if_ether.h
index 820de5d222d2..3a45b4ad71a3 100644
--- a/include/uapi/linux/if_ether.h
+++ b/include/uapi/linux/if_ether.h
@@ -89,6 +89,7 @@
89#define ETH_P_AOE 0x88A2 /* ATA over Ethernet */ 89#define ETH_P_AOE 0x88A2 /* ATA over Ethernet */
90#define ETH_P_8021AD 0x88A8 /* 802.1ad Service VLAN */ 90#define ETH_P_8021AD 0x88A8 /* 802.1ad Service VLAN */
91#define ETH_P_802_EX1 0x88B5 /* 802.1 Local Experimental 1. */ 91#define ETH_P_802_EX1 0x88B5 /* 802.1 Local Experimental 1. */
92#define ETH_P_PREAUTH 0x88C7 /* 802.11 Preauthentication */
92#define ETH_P_TIPC 0x88CA /* TIPC */ 93#define ETH_P_TIPC 0x88CA /* TIPC */
93#define ETH_P_MACSEC 0x88E5 /* 802.1ae MACsec */ 94#define ETH_P_MACSEC 0x88E5 /* 802.1ae MACsec */
94#define ETH_P_8021AH 0x88E7 /* 802.1ah Backbone Service Tag */ 95#define ETH_P_8021AH 0x88E7 /* 802.1ah Backbone Service Tag */
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 6d9447700e18..68699f654118 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -941,4 +941,43 @@ enum {
941 IFLA_EVENT_BONDING_OPTIONS, /* change in bonding options */ 941 IFLA_EVENT_BONDING_OPTIONS, /* change in bonding options */
942}; 942};
943 943
944/* tun section */
945
946enum {
947 IFLA_TUN_UNSPEC,
948 IFLA_TUN_OWNER,
949 IFLA_TUN_GROUP,
950 IFLA_TUN_TYPE,
951 IFLA_TUN_PI,
952 IFLA_TUN_VNET_HDR,
953 IFLA_TUN_PERSIST,
954 IFLA_TUN_MULTI_QUEUE,
955 IFLA_TUN_NUM_QUEUES,
956 IFLA_TUN_NUM_DISABLED_QUEUES,
957 __IFLA_TUN_MAX,
958};
959
960#define IFLA_TUN_MAX (__IFLA_TUN_MAX - 1)
961
962/* rmnet section */
963
964#define RMNET_FLAGS_INGRESS_DEAGGREGATION (1U << 0)
965#define RMNET_FLAGS_INGRESS_MAP_COMMANDS (1U << 1)
966#define RMNET_FLAGS_INGRESS_MAP_CKSUMV4 (1U << 2)
967#define RMNET_FLAGS_EGRESS_MAP_CKSUMV4 (1U << 3)
968
969enum {
970 IFLA_RMNET_UNSPEC,
971 IFLA_RMNET_MUX_ID,
972 IFLA_RMNET_FLAGS,
973 __IFLA_RMNET_MAX,
974};
975
976#define IFLA_RMNET_MAX (__IFLA_RMNET_MAX - 1)
977
978struct ifla_rmnet_flags {
979 __u32 flags;
980 __u32 mask;
981};
982
944#endif /* _UAPI_LINUX_IF_LINK_H */ 983#endif /* _UAPI_LINUX_IF_LINK_H */
diff --git a/include/uapi/linux/ncsi.h b/include/uapi/linux/ncsi.h
new file mode 100644
index 000000000000..4c292ecbb748
--- /dev/null
+++ b/include/uapi/linux/ncsi.h
@@ -0,0 +1,115 @@
1/*
2 * Copyright Samuel Mendoza-Jonas, IBM Corporation 2018.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 */
9
10#ifndef __UAPI_NCSI_NETLINK_H__
11#define __UAPI_NCSI_NETLINK_H__
12
13/**
14 * enum ncsi_nl_commands - supported NCSI commands
15 *
16 * @NCSI_CMD_UNSPEC: unspecified command to catch errors
17 * @NCSI_CMD_PKG_INFO: list package and channel attributes. Requires
18 * NCSI_ATTR_IFINDEX. If NCSI_ATTR_PACKAGE_ID is specified returns the
19 * specific package and its channels - otherwise a dump request returns
20 * all packages and their associated channels.
21 * @NCSI_CMD_SET_INTERFACE: set preferred package and channel combination.
22 * Requires NCSI_ATTR_IFINDEX and the preferred NCSI_ATTR_PACKAGE_ID and
23 * optionally the preferred NCSI_ATTR_CHANNEL_ID.
24 * @NCSI_CMD_CLEAR_INTERFACE: clear any preferred package/channel combination.
25 * Requires NCSI_ATTR_IFINDEX.
26 * @NCSI_CMD_MAX: highest command number
27 */
28enum ncsi_nl_commands {
29 NCSI_CMD_UNSPEC,
30 NCSI_CMD_PKG_INFO,
31 NCSI_CMD_SET_INTERFACE,
32 NCSI_CMD_CLEAR_INTERFACE,
33
34 __NCSI_CMD_AFTER_LAST,
35 NCSI_CMD_MAX = __NCSI_CMD_AFTER_LAST - 1
36};
37
38/**
39 * enum ncsi_nl_attrs - General NCSI netlink attributes
40 *
41 * @NCSI_ATTR_UNSPEC: unspecified attributes to catch errors
42 * @NCSI_ATTR_IFINDEX: ifindex of network device using NCSI
43 * @NCSI_ATTR_PACKAGE_LIST: nested array of NCSI_PKG_ATTR attributes
44 * @NCSI_ATTR_PACKAGE_ID: package ID
45 * @NCSI_ATTR_CHANNEL_ID: channel ID
46 * @NCSI_ATTR_MAX: highest attribute number
47 */
48enum ncsi_nl_attrs {
49 NCSI_ATTR_UNSPEC,
50 NCSI_ATTR_IFINDEX,
51 NCSI_ATTR_PACKAGE_LIST,
52 NCSI_ATTR_PACKAGE_ID,
53 NCSI_ATTR_CHANNEL_ID,
54
55 __NCSI_ATTR_AFTER_LAST,
56 NCSI_ATTR_MAX = __NCSI_ATTR_AFTER_LAST - 1
57};
58
59/**
60 * enum ncsi_nl_pkg_attrs - NCSI netlink package-specific attributes
61 *
62 * @NCSI_PKG_ATTR_UNSPEC: unspecified attributes to catch errors
63 * @NCSI_PKG_ATTR: nested array of package attributes
64 * @NCSI_PKG_ATTR_ID: package ID
65 * @NCSI_PKG_ATTR_FORCED: flag signifying a package has been set as preferred
66 * @NCSI_PKG_ATTR_CHANNEL_LIST: nested array of NCSI_CHANNEL_ATTR attributes
67 * @NCSI_PKG_ATTR_MAX: highest attribute number
68 */
69enum ncsi_nl_pkg_attrs {
70 NCSI_PKG_ATTR_UNSPEC,
71 NCSI_PKG_ATTR,
72 NCSI_PKG_ATTR_ID,
73 NCSI_PKG_ATTR_FORCED,
74 NCSI_PKG_ATTR_CHANNEL_LIST,
75
76 __NCSI_PKG_ATTR_AFTER_LAST,
77 NCSI_PKG_ATTR_MAX = __NCSI_PKG_ATTR_AFTER_LAST - 1
78};
79
80/**
81 * enum ncsi_nl_channel_attrs - NCSI netlink channel-specific attributes
82 *
83 * @NCSI_CHANNEL_ATTR_UNSPEC: unspecified attributes to catch errors
84 * @NCSI_CHANNEL_ATTR: nested array of channel attributes
85 * @NCSI_CHANNEL_ATTR_ID: channel ID
86 * @NCSI_CHANNEL_ATTR_VERSION_MAJOR: channel major version number
87 * @NCSI_CHANNEL_ATTR_VERSION_MINOR: channel minor version number
88 * @NCSI_CHANNEL_ATTR_VERSION_STR: channel version string
89 * @NCSI_CHANNEL_ATTR_LINK_STATE: channel link state flags
90 * @NCSI_CHANNEL_ATTR_ACTIVE: channels with this flag are in
91 * NCSI_CHANNEL_ACTIVE state
92 * @NCSI_CHANNEL_ATTR_FORCED: flag signifying a channel has been set as
93 * preferred
94 * @NCSI_CHANNEL_ATTR_VLAN_LIST: nested array of NCSI_CHANNEL_ATTR_VLAN_IDs
95 * @NCSI_CHANNEL_ATTR_VLAN_ID: VLAN ID being filtered on this channel
96 * @NCSI_CHANNEL_ATTR_MAX: highest attribute number
97 */
98enum ncsi_nl_channel_attrs {
99 NCSI_CHANNEL_ATTR_UNSPEC,
100 NCSI_CHANNEL_ATTR,
101 NCSI_CHANNEL_ATTR_ID,
102 NCSI_CHANNEL_ATTR_VERSION_MAJOR,
103 NCSI_CHANNEL_ATTR_VERSION_MINOR,
104 NCSI_CHANNEL_ATTR_VERSION_STR,
105 NCSI_CHANNEL_ATTR_LINK_STATE,
106 NCSI_CHANNEL_ATTR_ACTIVE,
107 NCSI_CHANNEL_ATTR_FORCED,
108 NCSI_CHANNEL_ATTR_VLAN_LIST,
109 NCSI_CHANNEL_ATTR_VLAN_ID,
110
111 __NCSI_CHANNEL_ATTR_AFTER_LAST,
112 NCSI_CHANNEL_ATTR_MAX = __NCSI_CHANNEL_ATTR_AFTER_LAST - 1
113};
114
115#endif /* __UAPI_NCSI_NETLINK_H__ */
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index c587a61c32bf..c13c84304be3 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -992,6 +992,32 @@
992 * 992 *
993 * @NL80211_CMD_RELOAD_REGDB: Request that the regdb firmware file is reloaded. 993 * @NL80211_CMD_RELOAD_REGDB: Request that the regdb firmware file is reloaded.
994 * 994 *
995 * @NL80211_CMD_EXTERNAL_AUTH: This interface is exclusively defined for host
996 * drivers that do not define separate commands for authentication and
997 * association, but rely on user space for the authentication to happen.
998 * This interface acts both as the event request (driver to user space)
999 * to trigger the authentication and command response (userspace to
1000 * driver) to indicate the authentication status.
1001 *
1002 * User space uses the %NL80211_CMD_CONNECT command to the host driver to
1003 * trigger a connection. The host driver selects a BSS and further uses
1004 * this interface to offload only the authentication part to the user
1005 * space. Authentication frames are passed between the driver and user
1006 * space through the %NL80211_CMD_FRAME interface. Host driver proceeds
1007 * further with the association after getting successful authentication
1008 * status. User space indicates the authentication status through
1009 * %NL80211_ATTR_STATUS_CODE attribute in %NL80211_CMD_EXTERNAL_AUTH
1010 * command interface.
1011 *
1012 * Host driver reports this status on an authentication failure to the
1013 * user space through the connect result as the user space would have
1014 * initiated the connection through the connect request.
1015 *
1016 * @NL80211_CMD_STA_OPMODE_CHANGED: An event that notify station's
1017 * ht opmode or vht opmode changes using any of &NL80211_ATTR_SMPS_MODE,
1018 * &NL80211_ATTR_CHANNEL_WIDTH,&NL80211_ATTR_NSS attributes with its
1019 * address(specified in &NL80211_ATTR_MAC).
1020 *
995 * @NL80211_CMD_MAX: highest used command number 1021 * @NL80211_CMD_MAX: highest used command number
996 * @__NL80211_CMD_AFTER_LAST: internal use 1022 * @__NL80211_CMD_AFTER_LAST: internal use
997 */ 1023 */
@@ -1198,6 +1224,10 @@ enum nl80211_commands {
1198 1224
1199 NL80211_CMD_RELOAD_REGDB, 1225 NL80211_CMD_RELOAD_REGDB,
1200 1226
1227 NL80211_CMD_EXTERNAL_AUTH,
1228
1229 NL80211_CMD_STA_OPMODE_CHANGED,
1230
1201 /* add new commands above here */ 1231 /* add new commands above here */
1202 1232
1203 /* used to define NL80211_CMD_MAX below */ 1233 /* used to define NL80211_CMD_MAX below */
@@ -2153,6 +2183,19 @@ enum nl80211_commands {
2153 * @NL80211_ATTR_PMKR0_NAME: PMK-R0 Name for offloaded FT. 2183 * @NL80211_ATTR_PMKR0_NAME: PMK-R0 Name for offloaded FT.
2154 * @NL80211_ATTR_PORT_AUTHORIZED: (reserved) 2184 * @NL80211_ATTR_PORT_AUTHORIZED: (reserved)
2155 * 2185 *
2186 * @NL80211_ATTR_EXTERNAL_AUTH_ACTION: Identify the requested external
2187 * authentication operation (u32 attribute with an
2188 * &enum nl80211_external_auth_action value). This is used with the
2189 * &NL80211_CMD_EXTERNAL_AUTH request event.
2190 * @NL80211_ATTR_EXTERNAL_AUTH_SUPPORT: Flag attribute indicating that the user
2191 * space supports external authentication. This attribute shall be used
2192 * only with %NL80211_CMD_CONNECT request. The driver may offload
2193 * authentication processing to user space if this capability is indicated
2194 * in NL80211_CMD_CONNECT requests from the user space.
2195 *
2196 * @NL80211_ATTR_NSS: Station's New/updated RX_NSS value notified using this
2197 * u8 attribute. This is used with %NL80211_CMD_STA_OPMODE_CHANGED.
2198 *
2156 * @NUM_NL80211_ATTR: total number of nl80211_attrs available 2199 * @NUM_NL80211_ATTR: total number of nl80211_attrs available
2157 * @NL80211_ATTR_MAX: highest attribute number currently defined 2200 * @NL80211_ATTR_MAX: highest attribute number currently defined
2158 * @__NL80211_ATTR_AFTER_LAST: internal use 2201 * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2579,6 +2622,12 @@ enum nl80211_attrs {
2579 NL80211_ATTR_PMKR0_NAME, 2622 NL80211_ATTR_PMKR0_NAME,
2580 NL80211_ATTR_PORT_AUTHORIZED, 2623 NL80211_ATTR_PORT_AUTHORIZED,
2581 2624
2625 NL80211_ATTR_EXTERNAL_AUTH_ACTION,
2626 NL80211_ATTR_EXTERNAL_AUTH_SUPPORT,
2627
2628 NL80211_ATTR_NSS,
2629 NL80211_ATTR_ACK_SIGNAL,
2630
2582 /* add attributes here, update the policy in nl80211.c */ 2631 /* add attributes here, update the policy in nl80211.c */
2583 2632
2584 __NL80211_ATTR_AFTER_LAST, 2633 __NL80211_ATTR_AFTER_LAST,
@@ -2899,6 +2948,7 @@ enum nl80211_sta_bss_param {
2899 * @NL80211_STA_INFO_RX_DURATION: aggregate PPDU duration for all frames 2948 * @NL80211_STA_INFO_RX_DURATION: aggregate PPDU duration for all frames
2900 * received from the station (u64, usec) 2949 * received from the station (u64, usec)
2901 * @NL80211_STA_INFO_PAD: attribute used for padding for 64-bit alignment 2950 * @NL80211_STA_INFO_PAD: attribute used for padding for 64-bit alignment
2951 * @NL80211_STA_INFO_ACK_SIGNAL: signal strength of the last ACK frame(u8, dBm)
2902 * @__NL80211_STA_INFO_AFTER_LAST: internal 2952 * @__NL80211_STA_INFO_AFTER_LAST: internal
2903 * @NL80211_STA_INFO_MAX: highest possible station info attribute 2953 * @NL80211_STA_INFO_MAX: highest possible station info attribute
2904 */ 2954 */
@@ -2937,6 +2987,7 @@ enum nl80211_sta_info {
2937 NL80211_STA_INFO_TID_STATS, 2987 NL80211_STA_INFO_TID_STATS,
2938 NL80211_STA_INFO_RX_DURATION, 2988 NL80211_STA_INFO_RX_DURATION,
2939 NL80211_STA_INFO_PAD, 2989 NL80211_STA_INFO_PAD,
2990 NL80211_STA_INFO_ACK_SIGNAL,
2940 2991
2941 /* keep last */ 2992 /* keep last */
2942 __NL80211_STA_INFO_AFTER_LAST, 2993 __NL80211_STA_INFO_AFTER_LAST,
@@ -4945,6 +4996,9 @@ enum nl80211_feature_flags {
4945 * probe request tx deferral and suppression 4996 * probe request tx deferral and suppression
4946 * @NL80211_EXT_FEATURE_MFP_OPTIONAL: Driver supports the %NL80211_MFP_OPTIONAL 4997 * @NL80211_EXT_FEATURE_MFP_OPTIONAL: Driver supports the %NL80211_MFP_OPTIONAL
4947 * value in %NL80211_ATTR_USE_MFP. 4998 * value in %NL80211_ATTR_USE_MFP.
4999 * @NL80211_EXT_FEATURE_LOW_SPAN_SCAN: Driver supports low span scan.
5000 * @NL80211_EXT_FEATURE_LOW_POWER_SCAN: Driver supports low power scan.
5001 * @NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN: Driver supports high accuracy scan.
4948 * 5002 *
4949 * @NUM_NL80211_EXT_FEATURES: number of extended features. 5003 * @NUM_NL80211_EXT_FEATURES: number of extended features.
4950 * @MAX_NL80211_EXT_FEATURES: highest extended feature index. 5004 * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
@@ -4972,6 +5026,9 @@ enum nl80211_ext_feature_index {
4972 NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE, 5026 NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE,
4973 NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION, 5027 NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION,
4974 NL80211_EXT_FEATURE_MFP_OPTIONAL, 5028 NL80211_EXT_FEATURE_MFP_OPTIONAL,
5029 NL80211_EXT_FEATURE_LOW_SPAN_SCAN,
5030 NL80211_EXT_FEATURE_LOW_POWER_SCAN,
5031 NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN,
4975 5032
4976 /* add new features before the definition below */ 5033 /* add new features before the definition below */
4977 NUM_NL80211_EXT_FEATURES, 5034 NUM_NL80211_EXT_FEATURES,
@@ -5032,6 +5089,10 @@ enum nl80211_timeout_reason {
5032 * of NL80211_CMD_TRIGGER_SCAN and NL80211_CMD_START_SCHED_SCAN 5089 * of NL80211_CMD_TRIGGER_SCAN and NL80211_CMD_START_SCHED_SCAN
5033 * requests. 5090 * requests.
5034 * 5091 *
5092 * NL80211_SCAN_FLAG_LOW_SPAN, NL80211_SCAN_FLAG_LOW_POWER, and
5093 * NL80211_SCAN_FLAG_HIGH_ACCURACY flags are exclusive of each other, i.e., only
5094 * one of them can be used in the request.
5095 *
5035 * @NL80211_SCAN_FLAG_LOW_PRIORITY: scan request has low priority 5096 * @NL80211_SCAN_FLAG_LOW_PRIORITY: scan request has low priority
5036 * @NL80211_SCAN_FLAG_FLUSH: flush cache before scanning 5097 * @NL80211_SCAN_FLAG_FLUSH: flush cache before scanning
5037 * @NL80211_SCAN_FLAG_AP: force a scan even if the interface is configured 5098 * @NL80211_SCAN_FLAG_AP: force a scan even if the interface is configured
@@ -5059,7 +5120,20 @@ enum nl80211_timeout_reason {
5059 * and suppression (if it has received a broadcast Probe Response frame, 5120 * and suppression (if it has received a broadcast Probe Response frame,
5060 * Beacon frame or FILS Discovery frame from an AP that the STA considers 5121 * Beacon frame or FILS Discovery frame from an AP that the STA considers
5061 * a suitable candidate for (re-)association - suitable in terms of 5122 * a suitable candidate for (re-)association - suitable in terms of
5062 * SSID and/or RSSI 5123 * SSID and/or RSSI.
5124 * @NL80211_SCAN_FLAG_LOW_SPAN: Span corresponds to the total time taken to
5125 * accomplish the scan. Thus, this flag intends the driver to perform the
5126 * scan request with lesser span/duration. It is specific to the driver
5127 * implementations on how this is accomplished. Scan accuracy may get
5128 * impacted with this flag.
5129 * @NL80211_SCAN_FLAG_LOW_POWER: This flag intends the scan attempts to consume
5130 * optimal possible power. Drivers can resort to their specific means to
5131 * optimize the power. Scan accuracy may get impacted with this flag.
5132 * @NL80211_SCAN_FLAG_HIGH_ACCURACY: Accuracy here intends to the extent of scan
5133 * results obtained. Thus HIGH_ACCURACY scan flag aims to get maximum
5134 * possible scan results. This flag hints the driver to use the best
5135 * possible scan configuration to improve the accuracy in scanning.
5136 * Latency and power use may get impacted with this flag.
5063 */ 5137 */
5064enum nl80211_scan_flags { 5138enum nl80211_scan_flags {
5065 NL80211_SCAN_FLAG_LOW_PRIORITY = 1<<0, 5139 NL80211_SCAN_FLAG_LOW_PRIORITY = 1<<0,
@@ -5070,6 +5144,9 @@ enum nl80211_scan_flags {
5070 NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP = 1<<5, 5144 NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP = 1<<5,
5071 NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE = 1<<6, 5145 NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE = 1<<6,
5072 NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION = 1<<7, 5146 NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION = 1<<7,
5147 NL80211_SCAN_FLAG_LOW_SPAN = 1<<8,
5148 NL80211_SCAN_FLAG_LOW_POWER = 1<<9,
5149 NL80211_SCAN_FLAG_HIGH_ACCURACY = 1<<10,
5073}; 5150};
5074 5151
5075/** 5152/**
@@ -5469,4 +5546,15 @@ enum nl80211_nan_match_attributes {
5469 NL80211_NAN_MATCH_ATTR_MAX = NUM_NL80211_NAN_MATCH_ATTR - 1 5546 NL80211_NAN_MATCH_ATTR_MAX = NUM_NL80211_NAN_MATCH_ATTR - 1
5470}; 5547};
5471 5548
5549/**
5550 * nl80211_external_auth_action - Action to perform with external
5551 * authentication request. Used by NL80211_ATTR_EXTERNAL_AUTH_ACTION.
5552 * @NL80211_EXTERNAL_AUTH_START: Start the authentication.
5553 * @NL80211_EXTERNAL_AUTH_ABORT: Abort the ongoing authentication.
5554 */
5555enum nl80211_external_auth_action {
5556 NL80211_EXTERNAL_AUTH_START,
5557 NL80211_EXTERNAL_AUTH_ABORT,
5558};
5559
5472#endif /* __LINUX_NL80211_H */ 5560#endif /* __LINUX_NL80211_H */
diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h
index 46c506615f4a..be05e66c167b 100644
--- a/include/uapi/linux/pkt_cls.h
+++ b/include/uapi/linux/pkt_cls.h
@@ -475,6 +475,7 @@ enum {
475 475
476enum { 476enum {
477 TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT = (1 << 0), 477 TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT = (1 << 0),
478 TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST = (1 << 1),
478}; 479};
479 480
480/* Match-all classifier */ 481/* Match-all classifier */
@@ -555,7 +556,8 @@ enum {
555#define TCF_EM_VLAN 6 556#define TCF_EM_VLAN 6
556#define TCF_EM_CANID 7 557#define TCF_EM_CANID 7
557#define TCF_EM_IPSET 8 558#define TCF_EM_IPSET 8
558#define TCF_EM_MAX 8 559#define TCF_EM_IPT 9
560#define TCF_EM_MAX 9
559 561
560enum { 562enum {
561 TCF_EM_PROG_TC 563 TCF_EM_PROG_TC
diff --git a/include/uapi/linux/rds.h b/include/uapi/linux/rds.h
index e71d4491f225..a66b213de3d7 100644
--- a/include/uapi/linux/rds.h
+++ b/include/uapi/linux/rds.h
@@ -103,6 +103,8 @@
103#define RDS_CMSG_MASKED_ATOMIC_FADD 8 103#define RDS_CMSG_MASKED_ATOMIC_FADD 8
104#define RDS_CMSG_MASKED_ATOMIC_CSWP 9 104#define RDS_CMSG_MASKED_ATOMIC_CSWP 9
105#define RDS_CMSG_RXPATH_LATENCY 11 105#define RDS_CMSG_RXPATH_LATENCY 11
106#define RDS_CMSG_ZCOPY_COOKIE 12
107#define RDS_CMSG_ZCOPY_COMPLETION 13
106 108
107#define RDS_INFO_FIRST 10000 109#define RDS_INFO_FIRST 10000
108#define RDS_INFO_COUNTERS 10000 110#define RDS_INFO_COUNTERS 10000
@@ -316,6 +318,12 @@ struct rds_rdma_notify {
316#define RDS_RDMA_DROPPED 3 318#define RDS_RDMA_DROPPED 3
317#define RDS_RDMA_OTHER_ERROR 4 319#define RDS_RDMA_OTHER_ERROR 4
318 320
321#define RDS_MAX_ZCOOKIES 8
322struct rds_zcopy_cookies {
323 __u32 num;
324 __u32 cookies[RDS_MAX_ZCOOKIES];
325};
326
319/* 327/*
320 * Common set of flags for all RDMA related structs 328 * Common set of flags for all RDMA related structs
321 */ 329 */
diff --git a/include/uapi/linux/sctp.h b/include/uapi/linux/sctp.h
index 4c4db14786bd..afd4346386e0 100644
--- a/include/uapi/linux/sctp.h
+++ b/include/uapi/linux/sctp.h
@@ -99,6 +99,7 @@ typedef __s32 sctp_assoc_t;
99#define SCTP_RECVRCVINFO 32 99#define SCTP_RECVRCVINFO 32
100#define SCTP_RECVNXTINFO 33 100#define SCTP_RECVNXTINFO 33
101#define SCTP_DEFAULT_SNDINFO 34 101#define SCTP_DEFAULT_SNDINFO 34
102#define SCTP_AUTH_DEACTIVATE_KEY 35
102 103
103/* Internal Socket Options. Some of the sctp library functions are 104/* Internal Socket Options. Some of the sctp library functions are
104 * implemented using these socket options. 105 * implemented using these socket options.
@@ -260,6 +261,31 @@ struct sctp_nxtinfo {
260 sctp_assoc_t nxt_assoc_id; 261 sctp_assoc_t nxt_assoc_id;
261}; 262};
262 263
264/* 5.3.7 SCTP PR-SCTP Information Structure (SCTP_PRINFO)
265 *
266 * This cmsghdr structure specifies SCTP options for sendmsg().
267 *
268 * cmsg_level cmsg_type cmsg_data[]
269 * ------------ ------------ -------------------
270 * IPPROTO_SCTP SCTP_PRINFO struct sctp_prinfo
271 */
272struct sctp_prinfo {
273 __u16 pr_policy;
274 __u32 pr_value;
275};
276
277/* 5.3.8 SCTP AUTH Information Structure (SCTP_AUTHINFO)
278 *
279 * This cmsghdr structure specifies SCTP options for sendmsg().
280 *
281 * cmsg_level cmsg_type cmsg_data[]
282 * ------------ ------------ -------------------
283 * IPPROTO_SCTP SCTP_AUTHINFO struct sctp_authinfo
284 */
285struct sctp_authinfo {
286 __u16 auth_keynumber;
287};
288
263/* 289/*
264 * sinfo_flags: 16 bits (unsigned integer) 290 * sinfo_flags: 16 bits (unsigned integer)
265 * 291 *
@@ -271,6 +297,8 @@ enum sctp_sinfo_flags {
271 SCTP_ADDR_OVER = (1 << 1), /* Override the primary destination. */ 297 SCTP_ADDR_OVER = (1 << 1), /* Override the primary destination. */
272 SCTP_ABORT = (1 << 2), /* Send an ABORT message to the peer. */ 298 SCTP_ABORT = (1 << 2), /* Send an ABORT message to the peer. */
273 SCTP_SACK_IMMEDIATELY = (1 << 3), /* SACK should be sent without delay. */ 299 SCTP_SACK_IMMEDIATELY = (1 << 3), /* SACK should be sent without delay. */
300 /* 2 bits here have been used by SCTP_PR_SCTP_MASK */
301 SCTP_SENDALL = (1 << 6),
274 SCTP_NOTIFICATION = MSG_NOTIFICATION, /* Next message is not user msg but notification. */ 302 SCTP_NOTIFICATION = MSG_NOTIFICATION, /* Next message is not user msg but notification. */
275 SCTP_EOF = MSG_FIN, /* Initiate graceful shutdown process. */ 303 SCTP_EOF = MSG_FIN, /* Initiate graceful shutdown process. */
276}; 304};
@@ -293,6 +321,14 @@ typedef enum sctp_cmsg_type {
293#define SCTP_RCVINFO SCTP_RCVINFO 321#define SCTP_RCVINFO SCTP_RCVINFO
294 SCTP_NXTINFO, /* 5.3.6 SCTP Next Receive Information Structure */ 322 SCTP_NXTINFO, /* 5.3.6 SCTP Next Receive Information Structure */
295#define SCTP_NXTINFO SCTP_NXTINFO 323#define SCTP_NXTINFO SCTP_NXTINFO
324 SCTP_PRINFO, /* 5.3.7 SCTP PR-SCTP Information Structure */
325#define SCTP_PRINFO SCTP_PRINFO
326 SCTP_AUTHINFO, /* 5.3.8 SCTP AUTH Information Structure */
327#define SCTP_AUTHINFO SCTP_AUTHINFO
328 SCTP_DSTADDRV4, /* 5.3.9 SCTP Destination IPv4 Address Structure */
329#define SCTP_DSTADDRV4 SCTP_DSTADDRV4
330 SCTP_DSTADDRV6, /* 5.3.10 SCTP Destination IPv6 Address Structure */
331#define SCTP_DSTADDRV6 SCTP_DSTADDRV6
296} sctp_cmsg_t; 332} sctp_cmsg_t;
297 333
298/* 334/*
@@ -482,7 +518,12 @@ struct sctp_authkey_event {
482 sctp_assoc_t auth_assoc_id; 518 sctp_assoc_t auth_assoc_id;
483}; 519};
484 520
485enum { SCTP_AUTH_NEWKEY = 0, }; 521enum {
522 SCTP_AUTH_NEW_KEY,
523#define SCTP_AUTH_NEWKEY SCTP_AUTH_NEW_KEY /* compatible with before */
524 SCTP_AUTH_FREE_KEY,
525 SCTP_AUTH_NO_AUTH,
526};
486 527
487/* 528/*
488 * 6.1.9. SCTP_SENDER_DRY_EVENT 529 * 6.1.9. SCTP_SENDER_DRY_EVENT
diff --git a/include/uapi/linux/tc_ematch/tc_em_ipt.h b/include/uapi/linux/tc_ematch/tc_em_ipt.h
new file mode 100644
index 000000000000..49a65530992c
--- /dev/null
+++ b/include/uapi/linux/tc_ematch/tc_em_ipt.h
@@ -0,0 +1,20 @@
1/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
2#ifndef __LINUX_TC_EM_IPT_H
3#define __LINUX_TC_EM_IPT_H
4
5#include <linux/types.h>
6#include <linux/pkt_cls.h>
7
8enum {
9 TCA_EM_IPT_UNSPEC,
10 TCA_EM_IPT_HOOK,
11 TCA_EM_IPT_MATCH_NAME,
12 TCA_EM_IPT_MATCH_REVISION,
13 TCA_EM_IPT_NFPROTO,
14 TCA_EM_IPT_MATCH_DATA,
15 __TCA_EM_IPT_MAX
16};
17
18#define TCA_EM_IPT_MAX (__TCA_EM_IPT_MAX - 1)
19
20#endif
diff --git a/include/uapi/linux/tcp.h b/include/uapi/linux/tcp.h
index b4a4f64635fa..560374c978f9 100644
--- a/include/uapi/linux/tcp.h
+++ b/include/uapi/linux/tcp.h
@@ -241,6 +241,9 @@ enum {
241 TCP_NLA_MIN_RTT, /* minimum RTT */ 241 TCP_NLA_MIN_RTT, /* minimum RTT */
242 TCP_NLA_RECUR_RETRANS, /* Recurring retransmits for the current pkt */ 242 TCP_NLA_RECUR_RETRANS, /* Recurring retransmits for the current pkt */
243 TCP_NLA_DELIVERY_RATE_APP_LMT, /* delivery rate application limited ? */ 243 TCP_NLA_DELIVERY_RATE_APP_LMT, /* delivery rate application limited ? */
244 TCP_NLA_SNDQ_SIZE, /* Data (bytes) pending in send queue */
245 TCP_NLA_CA_STATE, /* ca_state of socket */
246 TCP_NLA_SND_SSTHRESH, /* Slow start size threshold */
244 247
245}; 248};
246 249
diff --git a/include/uapi/linux/tipc.h b/include/uapi/linux/tipc.h
index 14bacc7e6cef..4ac9f1f02b06 100644
--- a/include/uapi/linux/tipc.h
+++ b/include/uapi/linux/tipc.h
@@ -61,50 +61,6 @@ struct tipc_name_seq {
61 __u32 upper; 61 __u32 upper;
62}; 62};
63 63
64/* TIPC Address Size, Offset, Mask specification for Z.C.N
65 */
66#define TIPC_NODE_BITS 12
67#define TIPC_CLUSTER_BITS 12
68#define TIPC_ZONE_BITS 8
69
70#define TIPC_NODE_OFFSET 0
71#define TIPC_CLUSTER_OFFSET TIPC_NODE_BITS
72#define TIPC_ZONE_OFFSET (TIPC_CLUSTER_OFFSET + TIPC_CLUSTER_BITS)
73
74#define TIPC_NODE_SIZE ((1UL << TIPC_NODE_BITS) - 1)
75#define TIPC_CLUSTER_SIZE ((1UL << TIPC_CLUSTER_BITS) - 1)
76#define TIPC_ZONE_SIZE ((1UL << TIPC_ZONE_BITS) - 1)
77
78#define TIPC_NODE_MASK (TIPC_NODE_SIZE << TIPC_NODE_OFFSET)
79#define TIPC_CLUSTER_MASK (TIPC_CLUSTER_SIZE << TIPC_CLUSTER_OFFSET)
80#define TIPC_ZONE_MASK (TIPC_ZONE_SIZE << TIPC_ZONE_OFFSET)
81
82#define TIPC_ZONE_CLUSTER_MASK (TIPC_ZONE_MASK | TIPC_CLUSTER_MASK)
83
84static inline __u32 tipc_addr(unsigned int zone,
85 unsigned int cluster,
86 unsigned int node)
87{
88 return (zone << TIPC_ZONE_OFFSET) |
89 (cluster << TIPC_CLUSTER_OFFSET) |
90 node;
91}
92
93static inline unsigned int tipc_zone(__u32 addr)
94{
95 return addr >> TIPC_ZONE_OFFSET;
96}
97
98static inline unsigned int tipc_cluster(__u32 addr)
99{
100 return (addr & TIPC_CLUSTER_MASK) >> TIPC_CLUSTER_OFFSET;
101}
102
103static inline unsigned int tipc_node(__u32 addr)
104{
105 return addr & TIPC_NODE_MASK;
106}
107
108/* 64/*
109 * Application-accessible port name types 65 * Application-accessible port name types
110 */ 66 */
@@ -117,9 +73,10 @@ static inline unsigned int tipc_node(__u32 addr)
117/* 73/*
118 * Publication scopes when binding port names and port name sequences 74 * Publication scopes when binding port names and port name sequences
119 */ 75 */
120#define TIPC_ZONE_SCOPE 1 76enum tipc_scope {
121#define TIPC_CLUSTER_SCOPE 2 77 TIPC_CLUSTER_SCOPE = 2, /* 0 can also be used */
122#define TIPC_NODE_SCOPE 3 78 TIPC_NODE_SCOPE = 3
79};
123 80
124/* 81/*
125 * Limiting values for messages 82 * Limiting values for messages
@@ -243,7 +200,7 @@ struct sockaddr_tipc {
243struct tipc_group_req { 200struct tipc_group_req {
244 __u32 type; /* group id */ 201 __u32 type; /* group id */
245 __u32 instance; /* member id */ 202 __u32 instance; /* member id */
246 __u32 scope; /* zone/cluster/node */ 203 __u32 scope; /* cluster/node */
247 __u32 flags; 204 __u32 flags;
248}; 205};
249 206
@@ -268,4 +225,53 @@ struct tipc_sioc_ln_req {
268 __u32 bearer_id; 225 __u32 bearer_id;
269 char linkname[TIPC_MAX_LINK_NAME]; 226 char linkname[TIPC_MAX_LINK_NAME];
270}; 227};
228
229
230/* The macros and functions below are deprecated:
231 */
232
233#define TIPC_ZONE_SCOPE 1
234
235#define TIPC_NODE_BITS 12
236#define TIPC_CLUSTER_BITS 12
237#define TIPC_ZONE_BITS 8
238
239#define TIPC_NODE_OFFSET 0
240#define TIPC_CLUSTER_OFFSET TIPC_NODE_BITS
241#define TIPC_ZONE_OFFSET (TIPC_CLUSTER_OFFSET + TIPC_CLUSTER_BITS)
242
243#define TIPC_NODE_SIZE ((1UL << TIPC_NODE_BITS) - 1)
244#define TIPC_CLUSTER_SIZE ((1UL << TIPC_CLUSTER_BITS) - 1)
245#define TIPC_ZONE_SIZE ((1UL << TIPC_ZONE_BITS) - 1)
246
247#define TIPC_NODE_MASK (TIPC_NODE_SIZE << TIPC_NODE_OFFSET)
248#define TIPC_CLUSTER_MASK (TIPC_CLUSTER_SIZE << TIPC_CLUSTER_OFFSET)
249#define TIPC_ZONE_MASK (TIPC_ZONE_SIZE << TIPC_ZONE_OFFSET)
250
251#define TIPC_ZONE_CLUSTER_MASK (TIPC_ZONE_MASK | TIPC_CLUSTER_MASK)
252
253static inline __u32 tipc_addr(unsigned int zone,
254 unsigned int cluster,
255 unsigned int node)
256{
257 return (zone << TIPC_ZONE_OFFSET) |
258 (cluster << TIPC_CLUSTER_OFFSET) |
259 node;
260}
261
262static inline unsigned int tipc_zone(__u32 addr)
263{
264 return addr >> TIPC_ZONE_OFFSET;
265}
266
267static inline unsigned int tipc_cluster(__u32 addr)
268{
269 return (addr & TIPC_CLUSTER_MASK) >> TIPC_CLUSTER_OFFSET;
270}
271
272static inline unsigned int tipc_node(__u32 addr)
273{
274 return addr & TIPC_NODE_MASK;
275}
276
271#endif 277#endif
diff --git a/include/uapi/linux/tipc_netlink.h b/include/uapi/linux/tipc_netlink.h
index 469aa67a5ecb..d896ded51bcb 100644
--- a/include/uapi/linux/tipc_netlink.h
+++ b/include/uapi/linux/tipc_netlink.h
@@ -114,6 +114,13 @@ enum {
114 TIPC_NLA_SOCK_REF, /* u32 */ 114 TIPC_NLA_SOCK_REF, /* u32 */
115 TIPC_NLA_SOCK_CON, /* nest */ 115 TIPC_NLA_SOCK_CON, /* nest */
116 TIPC_NLA_SOCK_HAS_PUBL, /* flag */ 116 TIPC_NLA_SOCK_HAS_PUBL, /* flag */
117 TIPC_NLA_SOCK_STAT, /* nest */
118 TIPC_NLA_SOCK_TYPE, /* u32 */
119 TIPC_NLA_SOCK_INO, /* u32 */
120 TIPC_NLA_SOCK_UID, /* u32 */
121 TIPC_NLA_SOCK_TIPC_STATE, /* u32 */
122 TIPC_NLA_SOCK_COOKIE, /* u64 */
123 TIPC_NLA_SOCK_PAD, /* flag */
117 124
118 __TIPC_NLA_SOCK_MAX, 125 __TIPC_NLA_SOCK_MAX,
119 TIPC_NLA_SOCK_MAX = __TIPC_NLA_SOCK_MAX - 1 126 TIPC_NLA_SOCK_MAX = __TIPC_NLA_SOCK_MAX - 1
@@ -238,6 +245,18 @@ enum {
238 TIPC_NLA_CON_MAX = __TIPC_NLA_CON_MAX - 1 245 TIPC_NLA_CON_MAX = __TIPC_NLA_CON_MAX - 1
239}; 246};
240 247
248/* Nest, socket statistics info */
249enum {
250 TIPC_NLA_SOCK_STAT_RCVQ, /* u32 */
251 TIPC_NLA_SOCK_STAT_SENDQ, /* u32 */
252 TIPC_NLA_SOCK_STAT_LINK_CONG, /* flag */
253 TIPC_NLA_SOCK_STAT_CONN_CONG, /* flag */
254 TIPC_NLA_SOCK_STAT_DROP, /* u32 */
255
256 __TIPC_NLA_SOCK_STAT_MAX,
257 TIPC_NLA_SOCK_STAT_MAX = __TIPC_NLA_SOCK_STAT_MAX - 1
258};
259
241/* Nest, link propreties. Valid for link, media and bearer */ 260/* Nest, link propreties. Valid for link, media and bearer */
242enum { 261enum {
243 TIPC_NLA_PROP_UNSPEC, 262 TIPC_NLA_PROP_UNSPEC,
diff --git a/include/uapi/linux/tipc_sockets_diag.h b/include/uapi/linux/tipc_sockets_diag.h
new file mode 100644
index 000000000000..7678cf2f0dcc
--- /dev/null
+++ b/include/uapi/linux/tipc_sockets_diag.h
@@ -0,0 +1,17 @@
1/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
2/* AF_TIPC sock_diag interface for querying open sockets */
3
4#ifndef _UAPI__TIPC_SOCKETS_DIAG_H__
5#define _UAPI__TIPC_SOCKETS_DIAG_H__
6
7#include <linux/types.h>
8#include <linux/sock_diag.h>
9
10/* Request */
11struct tipc_sock_diag_req {
12 __u8 sdiag_family; /* must be AF_TIPC */
13 __u8 sdiag_protocol; /* must be 0 */
14 __u16 pad; /* must be 0 */
15 __u32 tidiag_states; /* query*/
16};
17#endif /* _UAPI__TIPC_SOCKETS_DIAG_H__ */
diff --git a/kernel/audit.c b/kernel/audit.c
index 227db99b0f19..5e49b614d0e6 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1526,6 +1526,7 @@ static struct pernet_operations audit_net_ops __net_initdata = {
1526 .exit = audit_net_exit, 1526 .exit = audit_net_exit,
1527 .id = &audit_net_id, 1527 .id = &audit_net_id,
1528 .size = sizeof(struct audit_net), 1528 .size = sizeof(struct audit_net),
1529 .async = true,
1529}; 1530};
1530 1531
1531/* Initialize audit support at boot time. */ 1532/* Initialize audit support at boot time. */
diff --git a/kernel/bpf/inode.c b/kernel/bpf/inode.c
index 81e2f6995adb..bf6da59ae0d0 100644
--- a/kernel/bpf/inode.c
+++ b/kernel/bpf/inode.c
@@ -178,6 +178,9 @@ static int bpf_mkmap(struct dentry *dentry, umode_t mode, void *arg)
178static struct dentry * 178static struct dentry *
179bpf_lookup(struct inode *dir, struct dentry *dentry, unsigned flags) 179bpf_lookup(struct inode *dir, struct dentry *dentry, unsigned flags)
180{ 180{
181 /* Dots in names (e.g. "/sys/fs/bpf/foo.bar") are reserved for future
182 * extensions.
183 */
181 if (strchr(dentry->d_name.name, '.')) 184 if (strchr(dentry->d_name.name, '.'))
182 return ERR_PTR(-EPERM); 185 return ERR_PTR(-EPERM);
183 186
diff --git a/kernel/bpf/sockmap.c b/kernel/bpf/sockmap.c
index a927e89dad6e..69c5bccabd22 100644
--- a/kernel/bpf/sockmap.c
+++ b/kernel/bpf/sockmap.c
@@ -38,6 +38,7 @@
38#include <linux/skbuff.h> 38#include <linux/skbuff.h>
39#include <linux/workqueue.h> 39#include <linux/workqueue.h>
40#include <linux/list.h> 40#include <linux/list.h>
41#include <linux/mm.h>
41#include <net/strparser.h> 42#include <net/strparser.h>
42#include <net/tcp.h> 43#include <net/tcp.h>
43 44
@@ -47,6 +48,7 @@
47struct bpf_stab { 48struct bpf_stab {
48 struct bpf_map map; 49 struct bpf_map map;
49 struct sock **sock_map; 50 struct sock **sock_map;
51 struct bpf_prog *bpf_tx_msg;
50 struct bpf_prog *bpf_parse; 52 struct bpf_prog *bpf_parse;
51 struct bpf_prog *bpf_verdict; 53 struct bpf_prog *bpf_verdict;
52}; 54};
@@ -62,8 +64,7 @@ struct smap_psock_map_entry {
62 64
63struct smap_psock { 65struct smap_psock {
64 struct rcu_head rcu; 66 struct rcu_head rcu;
65 /* refcnt is used inside sk_callback_lock */ 67 refcount_t refcnt;
66 u32 refcnt;
67 68
68 /* datapath variables */ 69 /* datapath variables */
69 struct sk_buff_head rxqueue; 70 struct sk_buff_head rxqueue;
@@ -74,7 +75,16 @@ struct smap_psock {
74 int save_off; 75 int save_off;
75 struct sk_buff *save_skb; 76 struct sk_buff *save_skb;
76 77
78 /* datapath variables for tx_msg ULP */
79 struct sock *sk_redir;
80 int apply_bytes;
81 int cork_bytes;
82 int sg_size;
83 int eval;
84 struct sk_msg_buff *cork;
85
77 struct strparser strp; 86 struct strparser strp;
87 struct bpf_prog *bpf_tx_msg;
78 struct bpf_prog *bpf_parse; 88 struct bpf_prog *bpf_parse;
79 struct bpf_prog *bpf_verdict; 89 struct bpf_prog *bpf_verdict;
80 struct list_head maps; 90 struct list_head maps;
@@ -92,6 +102,11 @@ struct smap_psock {
92 void (*save_write_space)(struct sock *sk); 102 void (*save_write_space)(struct sock *sk);
93}; 103};
94 104
105static void smap_release_sock(struct smap_psock *psock, struct sock *sock);
106static int bpf_tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size);
107static int bpf_tcp_sendpage(struct sock *sk, struct page *page,
108 int offset, size_t size, int flags);
109
95static inline struct smap_psock *smap_psock_sk(const struct sock *sk) 110static inline struct smap_psock *smap_psock_sk(const struct sock *sk)
96{ 111{
97 return rcu_dereference_sk_user_data(sk); 112 return rcu_dereference_sk_user_data(sk);
@@ -116,27 +131,41 @@ static int bpf_tcp_init(struct sock *sk)
116 131
117 psock->save_close = sk->sk_prot->close; 132 psock->save_close = sk->sk_prot->close;
118 psock->sk_proto = sk->sk_prot; 133 psock->sk_proto = sk->sk_prot;
134
135 if (psock->bpf_tx_msg) {
136 tcp_bpf_proto.sendmsg = bpf_tcp_sendmsg;
137 tcp_bpf_proto.sendpage = bpf_tcp_sendpage;
138 }
139
119 sk->sk_prot = &tcp_bpf_proto; 140 sk->sk_prot = &tcp_bpf_proto;
120 rcu_read_unlock(); 141 rcu_read_unlock();
121 return 0; 142 return 0;
122} 143}
123 144
145static void smap_release_sock(struct smap_psock *psock, struct sock *sock);
146static int free_start_sg(struct sock *sk, struct sk_msg_buff *md);
147
124static void bpf_tcp_release(struct sock *sk) 148static void bpf_tcp_release(struct sock *sk)
125{ 149{
126 struct smap_psock *psock; 150 struct smap_psock *psock;
127 151
128 rcu_read_lock(); 152 rcu_read_lock();
129 psock = smap_psock_sk(sk); 153 psock = smap_psock_sk(sk);
154 if (unlikely(!psock))
155 goto out;
130 156
131 if (likely(psock)) { 157 if (psock->cork) {
132 sk->sk_prot = psock->sk_proto; 158 free_start_sg(psock->sock, psock->cork);
133 psock->sk_proto = NULL; 159 kfree(psock->cork);
160 psock->cork = NULL;
134 } 161 }
162
163 sk->sk_prot = psock->sk_proto;
164 psock->sk_proto = NULL;
165out:
135 rcu_read_unlock(); 166 rcu_read_unlock();
136} 167}
137 168
138static void smap_release_sock(struct smap_psock *psock, struct sock *sock);
139
140static void bpf_tcp_close(struct sock *sk, long timeout) 169static void bpf_tcp_close(struct sock *sk, long timeout)
141{ 170{
142 void (*close_fun)(struct sock *sk, long timeout); 171 void (*close_fun)(struct sock *sk, long timeout);
@@ -175,6 +204,7 @@ enum __sk_action {
175 __SK_DROP = 0, 204 __SK_DROP = 0,
176 __SK_PASS, 205 __SK_PASS,
177 __SK_REDIRECT, 206 __SK_REDIRECT,
207 __SK_NONE,
178}; 208};
179 209
180static struct tcp_ulp_ops bpf_tcp_ulp_ops __read_mostly = { 210static struct tcp_ulp_ops bpf_tcp_ulp_ops __read_mostly = {
@@ -186,10 +216,621 @@ static struct tcp_ulp_ops bpf_tcp_ulp_ops __read_mostly = {
186 .release = bpf_tcp_release, 216 .release = bpf_tcp_release,
187}; 217};
188 218
219static int memcopy_from_iter(struct sock *sk,
220 struct sk_msg_buff *md,
221 struct iov_iter *from, int bytes)
222{
223 struct scatterlist *sg = md->sg_data;
224 int i = md->sg_curr, rc = -ENOSPC;
225
226 do {
227 int copy;
228 char *to;
229
230 if (md->sg_copybreak >= sg[i].length) {
231 md->sg_copybreak = 0;
232
233 if (++i == MAX_SKB_FRAGS)
234 i = 0;
235
236 if (i == md->sg_end)
237 break;
238 }
239
240 copy = sg[i].length - md->sg_copybreak;
241 to = sg_virt(&sg[i]) + md->sg_copybreak;
242 md->sg_copybreak += copy;
243
244 if (sk->sk_route_caps & NETIF_F_NOCACHE_COPY)
245 rc = copy_from_iter_nocache(to, copy, from);
246 else
247 rc = copy_from_iter(to, copy, from);
248
249 if (rc != copy) {
250 rc = -EFAULT;
251 goto out;
252 }
253
254 bytes -= copy;
255 if (!bytes)
256 break;
257
258 md->sg_copybreak = 0;
259 if (++i == MAX_SKB_FRAGS)
260 i = 0;
261 } while (i != md->sg_end);
262out:
263 md->sg_curr = i;
264 return rc;
265}
266
267static int bpf_tcp_push(struct sock *sk, int apply_bytes,
268 struct sk_msg_buff *md,
269 int flags, bool uncharge)
270{
271 bool apply = apply_bytes;
272 struct scatterlist *sg;
273 int offset, ret = 0;
274 struct page *p;
275 size_t size;
276
277 while (1) {
278 sg = md->sg_data + md->sg_start;
279 size = (apply && apply_bytes < sg->length) ?
280 apply_bytes : sg->length;
281 offset = sg->offset;
282
283 tcp_rate_check_app_limited(sk);
284 p = sg_page(sg);
285retry:
286 ret = do_tcp_sendpages(sk, p, offset, size, flags);
287 if (ret != size) {
288 if (ret > 0) {
289 if (apply)
290 apply_bytes -= ret;
291 size -= ret;
292 offset += ret;
293 if (uncharge)
294 sk_mem_uncharge(sk, ret);
295 goto retry;
296 }
297
298 sg->length = size;
299 sg->offset = offset;
300 return ret;
301 }
302
303 if (apply)
304 apply_bytes -= ret;
305 sg->offset += ret;
306 sg->length -= ret;
307 if (uncharge)
308 sk_mem_uncharge(sk, ret);
309
310 if (!sg->length) {
311 put_page(p);
312 md->sg_start++;
313 if (md->sg_start == MAX_SKB_FRAGS)
314 md->sg_start = 0;
315 memset(sg, 0, sizeof(*sg));
316
317 if (md->sg_start == md->sg_end)
318 break;
319 }
320
321 if (apply && !apply_bytes)
322 break;
323 }
324 return 0;
325}
326
327static inline void bpf_compute_data_pointers_sg(struct sk_msg_buff *md)
328{
329 struct scatterlist *sg = md->sg_data + md->sg_start;
330
331 if (md->sg_copy[md->sg_start]) {
332 md->data = md->data_end = 0;
333 } else {
334 md->data = sg_virt(sg);
335 md->data_end = md->data + sg->length;
336 }
337}
338
339static void return_mem_sg(struct sock *sk, int bytes, struct sk_msg_buff *md)
340{
341 struct scatterlist *sg = md->sg_data;
342 int i = md->sg_start;
343
344 do {
345 int uncharge = (bytes < sg[i].length) ? bytes : sg[i].length;
346
347 sk_mem_uncharge(sk, uncharge);
348 bytes -= uncharge;
349 if (!bytes)
350 break;
351 i++;
352 if (i == MAX_SKB_FRAGS)
353 i = 0;
354 } while (i != md->sg_end);
355}
356
357static void free_bytes_sg(struct sock *sk, int bytes, struct sk_msg_buff *md)
358{
359 struct scatterlist *sg = md->sg_data;
360 int i = md->sg_start, free;
361
362 while (bytes && sg[i].length) {
363 free = sg[i].length;
364 if (bytes < free) {
365 sg[i].length -= bytes;
366 sg[i].offset += bytes;
367 sk_mem_uncharge(sk, bytes);
368 break;
369 }
370
371 sk_mem_uncharge(sk, sg[i].length);
372 put_page(sg_page(&sg[i]));
373 bytes -= sg[i].length;
374 sg[i].length = 0;
375 sg[i].page_link = 0;
376 sg[i].offset = 0;
377 i++;
378
379 if (i == MAX_SKB_FRAGS)
380 i = 0;
381 }
382}
383
384static int free_sg(struct sock *sk, int start, struct sk_msg_buff *md)
385{
386 struct scatterlist *sg = md->sg_data;
387 int i = start, free = 0;
388
389 while (sg[i].length) {
390 free += sg[i].length;
391 sk_mem_uncharge(sk, sg[i].length);
392 put_page(sg_page(&sg[i]));
393 sg[i].length = 0;
394 sg[i].page_link = 0;
395 sg[i].offset = 0;
396 i++;
397
398 if (i == MAX_SKB_FRAGS)
399 i = 0;
400 }
401
402 return free;
403}
404
405static int free_start_sg(struct sock *sk, struct sk_msg_buff *md)
406{
407 int free = free_sg(sk, md->sg_start, md);
408
409 md->sg_start = md->sg_end;
410 return free;
411}
412
413static int free_curr_sg(struct sock *sk, struct sk_msg_buff *md)
414{
415 return free_sg(sk, md->sg_curr, md);
416}
417
418static int bpf_map_msg_verdict(int _rc, struct sk_msg_buff *md)
419{
420 return ((_rc == SK_PASS) ?
421 (md->map ? __SK_REDIRECT : __SK_PASS) :
422 __SK_DROP);
423}
424
425static unsigned int smap_do_tx_msg(struct sock *sk,
426 struct smap_psock *psock,
427 struct sk_msg_buff *md)
428{
429 struct bpf_prog *prog;
430 unsigned int rc, _rc;
431
432 preempt_disable();
433 rcu_read_lock();
434
435 /* If the policy was removed mid-send then default to 'accept' */
436 prog = READ_ONCE(psock->bpf_tx_msg);
437 if (unlikely(!prog)) {
438 _rc = SK_PASS;
439 goto verdict;
440 }
441
442 bpf_compute_data_pointers_sg(md);
443 rc = (*prog->bpf_func)(md, prog->insnsi);
444 psock->apply_bytes = md->apply_bytes;
445
446 /* Moving return codes from UAPI namespace into internal namespace */
447 _rc = bpf_map_msg_verdict(rc, md);
448
449 /* The psock has a refcount on the sock but not on the map and because
450 * we need to drop rcu read lock here its possible the map could be
451 * removed between here and when we need it to execute the sock
452 * redirect. So do the map lookup now for future use.
453 */
454 if (_rc == __SK_REDIRECT) {
455 if (psock->sk_redir)
456 sock_put(psock->sk_redir);
457 psock->sk_redir = do_msg_redirect_map(md);
458 if (!psock->sk_redir) {
459 _rc = __SK_DROP;
460 goto verdict;
461 }
462 sock_hold(psock->sk_redir);
463 }
464verdict:
465 rcu_read_unlock();
466 preempt_enable();
467
468 return _rc;
469}
470
471static int bpf_tcp_sendmsg_do_redirect(struct sock *sk, int send,
472 struct sk_msg_buff *md,
473 int flags)
474{
475 struct smap_psock *psock;
476 struct scatterlist *sg;
477 int i, err, free = 0;
478
479 sg = md->sg_data;
480
481 rcu_read_lock();
482 psock = smap_psock_sk(sk);
483 if (unlikely(!psock))
484 goto out_rcu;
485
486 if (!refcount_inc_not_zero(&psock->refcnt))
487 goto out_rcu;
488
489 rcu_read_unlock();
490 lock_sock(sk);
491 err = bpf_tcp_push(sk, send, md, flags, false);
492 release_sock(sk);
493 smap_release_sock(psock, sk);
494 if (unlikely(err))
495 goto out;
496 return 0;
497out_rcu:
498 rcu_read_unlock();
499out:
500 i = md->sg_start;
501 while (sg[i].length) {
502 free += sg[i].length;
503 put_page(sg_page(&sg[i]));
504 sg[i].length = 0;
505 i++;
506 if (i == MAX_SKB_FRAGS)
507 i = 0;
508 }
509 return free;
510}
511
512static inline void bpf_md_init(struct smap_psock *psock)
513{
514 if (!psock->apply_bytes) {
515 psock->eval = __SK_NONE;
516 if (psock->sk_redir) {
517 sock_put(psock->sk_redir);
518 psock->sk_redir = NULL;
519 }
520 }
521}
522
523static void apply_bytes_dec(struct smap_psock *psock, int i)
524{
525 if (psock->apply_bytes) {
526 if (psock->apply_bytes < i)
527 psock->apply_bytes = 0;
528 else
529 psock->apply_bytes -= i;
530 }
531}
532
533static int bpf_exec_tx_verdict(struct smap_psock *psock,
534 struct sk_msg_buff *m,
535 struct sock *sk,
536 int *copied, int flags)
537{
538 bool cork = false, enospc = (m->sg_start == m->sg_end);
539 struct sock *redir;
540 int err = 0;
541 int send;
542
543more_data:
544 if (psock->eval == __SK_NONE)
545 psock->eval = smap_do_tx_msg(sk, psock, m);
546
547 if (m->cork_bytes &&
548 m->cork_bytes > psock->sg_size && !enospc) {
549 psock->cork_bytes = m->cork_bytes - psock->sg_size;
550 if (!psock->cork) {
551 psock->cork = kcalloc(1,
552 sizeof(struct sk_msg_buff),
553 GFP_ATOMIC | __GFP_NOWARN);
554
555 if (!psock->cork) {
556 err = -ENOMEM;
557 goto out_err;
558 }
559 }
560 memcpy(psock->cork, m, sizeof(*m));
561 goto out_err;
562 }
563
564 send = psock->sg_size;
565 if (psock->apply_bytes && psock->apply_bytes < send)
566 send = psock->apply_bytes;
567
568 switch (psock->eval) {
569 case __SK_PASS:
570 err = bpf_tcp_push(sk, send, m, flags, true);
571 if (unlikely(err)) {
572 *copied -= free_start_sg(sk, m);
573 break;
574 }
575
576 apply_bytes_dec(psock, send);
577 psock->sg_size -= send;
578 break;
579 case __SK_REDIRECT:
580 redir = psock->sk_redir;
581 apply_bytes_dec(psock, send);
582
583 if (psock->cork) {
584 cork = true;
585 psock->cork = NULL;
586 }
587
588 return_mem_sg(sk, send, m);
589 release_sock(sk);
590
591 err = bpf_tcp_sendmsg_do_redirect(redir, send, m, flags);
592 lock_sock(sk);
593
594 if (cork) {
595 free_start_sg(sk, m);
596 kfree(m);
597 m = NULL;
598 }
599 if (unlikely(err))
600 *copied -= err;
601 else
602 psock->sg_size -= send;
603 break;
604 case __SK_DROP:
605 default:
606 free_bytes_sg(sk, send, m);
607 apply_bytes_dec(psock, send);
608 *copied -= send;
609 psock->sg_size -= send;
610 err = -EACCES;
611 break;
612 }
613
614 if (likely(!err)) {
615 bpf_md_init(psock);
616 if (m &&
617 m->sg_data[m->sg_start].page_link &&
618 m->sg_data[m->sg_start].length)
619 goto more_data;
620 }
621
622out_err:
623 return err;
624}
625
626static int bpf_tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
627{
628 int flags = msg->msg_flags | MSG_NO_SHARED_FRAGS;
629 struct sk_msg_buff md = {0};
630 unsigned int sg_copy = 0;
631 struct smap_psock *psock;
632 int copied = 0, err = 0;
633 struct scatterlist *sg;
634 long timeo;
635
636 /* Its possible a sock event or user removed the psock _but_ the ops
637 * have not been reprogrammed yet so we get here. In this case fallback
638 * to tcp_sendmsg. Note this only works because we _only_ ever allow
639 * a single ULP there is no hierarchy here.
640 */
641 rcu_read_lock();
642 psock = smap_psock_sk(sk);
643 if (unlikely(!psock)) {
644 rcu_read_unlock();
645 return tcp_sendmsg(sk, msg, size);
646 }
647
648 /* Increment the psock refcnt to ensure its not released while sending a
649 * message. Required because sk lookup and bpf programs are used in
650 * separate rcu critical sections. Its OK if we lose the map entry
651 * but we can't lose the sock reference.
652 */
653 if (!refcount_inc_not_zero(&psock->refcnt)) {
654 rcu_read_unlock();
655 return tcp_sendmsg(sk, msg, size);
656 }
657
658 sg = md.sg_data;
659 sg_init_table(sg, MAX_SKB_FRAGS);
660 rcu_read_unlock();
661
662 lock_sock(sk);
663 timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
664
665 while (msg_data_left(msg)) {
666 struct sk_msg_buff *m;
667 bool enospc = false;
668 int copy;
669
670 if (sk->sk_err) {
671 err = sk->sk_err;
672 goto out_err;
673 }
674
675 copy = msg_data_left(msg);
676 if (!sk_stream_memory_free(sk))
677 goto wait_for_sndbuf;
678
679 m = psock->cork_bytes ? psock->cork : &md;
680 m->sg_curr = m->sg_copybreak ? m->sg_curr : m->sg_end;
681 err = sk_alloc_sg(sk, copy, m->sg_data,
682 m->sg_start, &m->sg_end, &sg_copy,
683 m->sg_end - 1);
684 if (err) {
685 if (err != -ENOSPC)
686 goto wait_for_memory;
687 enospc = true;
688 copy = sg_copy;
689 }
690
691 err = memcopy_from_iter(sk, m, &msg->msg_iter, copy);
692 if (err < 0) {
693 free_curr_sg(sk, m);
694 goto out_err;
695 }
696
697 psock->sg_size += copy;
698 copied += copy;
699 sg_copy = 0;
700
701 /* When bytes are being corked skip running BPF program and
702 * applying verdict unless there is no more buffer space. In
703 * the ENOSPC case simply run BPF prorgram with currently
704 * accumulated data. We don't have much choice at this point
705 * we could try extending the page frags or chaining complex
706 * frags but even in these cases _eventually_ we will hit an
707 * OOM scenario. More complex recovery schemes may be
708 * implemented in the future, but BPF programs must handle
709 * the case where apply_cork requests are not honored. The
710 * canonical method to verify this is to check data length.
711 */
712 if (psock->cork_bytes) {
713 if (copy > psock->cork_bytes)
714 psock->cork_bytes = 0;
715 else
716 psock->cork_bytes -= copy;
717
718 if (psock->cork_bytes && !enospc)
719 goto out_cork;
720
721 /* All cork bytes accounted for re-run filter */
722 psock->eval = __SK_NONE;
723 psock->cork_bytes = 0;
724 }
725
726 err = bpf_exec_tx_verdict(psock, m, sk, &copied, flags);
727 if (unlikely(err < 0))
728 goto out_err;
729 continue;
730wait_for_sndbuf:
731 set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
732wait_for_memory:
733 err = sk_stream_wait_memory(sk, &timeo);
734 if (err)
735 goto out_err;
736 }
737out_err:
738 if (err < 0)
739 err = sk_stream_error(sk, msg->msg_flags, err);
740out_cork:
741 release_sock(sk);
742 smap_release_sock(psock, sk);
743 return copied ? copied : err;
744}
745
746static int bpf_tcp_sendpage(struct sock *sk, struct page *page,
747 int offset, size_t size, int flags)
748{
749 struct sk_msg_buff md = {0}, *m = NULL;
750 int err = 0, copied = 0;
751 struct smap_psock *psock;
752 struct scatterlist *sg;
753 bool enospc = false;
754
755 rcu_read_lock();
756 psock = smap_psock_sk(sk);
757 if (unlikely(!psock))
758 goto accept;
759
760 if (!refcount_inc_not_zero(&psock->refcnt))
761 goto accept;
762 rcu_read_unlock();
763
764 lock_sock(sk);
765
766 if (psock->cork_bytes)
767 m = psock->cork;
768 else
769 m = &md;
770
771 /* Catch case where ring is full and sendpage is stalled. */
772 if (unlikely(m->sg_end == m->sg_start &&
773 m->sg_data[m->sg_end].length))
774 goto out_err;
775
776 psock->sg_size += size;
777 sg = &m->sg_data[m->sg_end];
778 sg_set_page(sg, page, size, offset);
779 get_page(page);
780 m->sg_copy[m->sg_end] = true;
781 sk_mem_charge(sk, size);
782 m->sg_end++;
783 copied = size;
784
785 if (m->sg_end == MAX_SKB_FRAGS)
786 m->sg_end = 0;
787
788 if (m->sg_end == m->sg_start)
789 enospc = true;
790
791 if (psock->cork_bytes) {
792 if (size > psock->cork_bytes)
793 psock->cork_bytes = 0;
794 else
795 psock->cork_bytes -= size;
796
797 if (psock->cork_bytes && !enospc)
798 goto out_err;
799
800 /* All cork bytes accounted for re-run filter */
801 psock->eval = __SK_NONE;
802 psock->cork_bytes = 0;
803 }
804
805 err = bpf_exec_tx_verdict(psock, m, sk, &copied, flags);
806out_err:
807 release_sock(sk);
808 smap_release_sock(psock, sk);
809 return copied ? copied : err;
810accept:
811 rcu_read_unlock();
812 return tcp_sendpage(sk, page, offset, size, flags);
813}
814
815static void bpf_tcp_msg_add(struct smap_psock *psock,
816 struct sock *sk,
817 struct bpf_prog *tx_msg)
818{
819 struct bpf_prog *orig_tx_msg;
820
821 orig_tx_msg = xchg(&psock->bpf_tx_msg, tx_msg);
822 if (orig_tx_msg)
823 bpf_prog_put(orig_tx_msg);
824}
825
189static int bpf_tcp_ulp_register(void) 826static int bpf_tcp_ulp_register(void)
190{ 827{
191 tcp_bpf_proto = tcp_prot; 828 tcp_bpf_proto = tcp_prot;
192 tcp_bpf_proto.close = bpf_tcp_close; 829 tcp_bpf_proto.close = bpf_tcp_close;
830 /* Once BPF TX ULP is registered it is never unregistered. It
831 * will be in the ULP list for the lifetime of the system. Doing
832 * duplicate registers is not a problem.
833 */
193 return tcp_register_ulp(&bpf_tcp_ulp_ops); 834 return tcp_register_ulp(&bpf_tcp_ulp_ops);
194} 835}
195 836
@@ -373,15 +1014,13 @@ static void smap_destroy_psock(struct rcu_head *rcu)
373 1014
374static void smap_release_sock(struct smap_psock *psock, struct sock *sock) 1015static void smap_release_sock(struct smap_psock *psock, struct sock *sock)
375{ 1016{
376 psock->refcnt--; 1017 if (refcount_dec_and_test(&psock->refcnt)) {
377 if (psock->refcnt) 1018 tcp_cleanup_ulp(sock);
378 return; 1019 smap_stop_sock(psock, sock);
379 1020 clear_bit(SMAP_TX_RUNNING, &psock->state);
380 tcp_cleanup_ulp(sock); 1021 rcu_assign_sk_user_data(sock, NULL);
381 smap_stop_sock(psock, sock); 1022 call_rcu_sched(&psock->rcu, smap_destroy_psock);
382 clear_bit(SMAP_TX_RUNNING, &psock->state); 1023 }
383 rcu_assign_sk_user_data(sock, NULL);
384 call_rcu_sched(&psock->rcu, smap_destroy_psock);
385} 1024}
386 1025
387static int smap_parse_func_strparser(struct strparser *strp, 1026static int smap_parse_func_strparser(struct strparser *strp,
@@ -415,7 +1054,6 @@ static int smap_parse_func_strparser(struct strparser *strp,
415 return rc; 1054 return rc;
416} 1055}
417 1056
418
419static int smap_read_sock_done(struct strparser *strp, int err) 1057static int smap_read_sock_done(struct strparser *strp, int err)
420{ 1058{
421 return err; 1059 return err;
@@ -485,12 +1123,22 @@ static void smap_gc_work(struct work_struct *w)
485 bpf_prog_put(psock->bpf_parse); 1123 bpf_prog_put(psock->bpf_parse);
486 if (psock->bpf_verdict) 1124 if (psock->bpf_verdict)
487 bpf_prog_put(psock->bpf_verdict); 1125 bpf_prog_put(psock->bpf_verdict);
1126 if (psock->bpf_tx_msg)
1127 bpf_prog_put(psock->bpf_tx_msg);
1128
1129 if (psock->cork) {
1130 free_start_sg(psock->sock, psock->cork);
1131 kfree(psock->cork);
1132 }
488 1133
489 list_for_each_entry_safe(e, tmp, &psock->maps, list) { 1134 list_for_each_entry_safe(e, tmp, &psock->maps, list) {
490 list_del(&e->list); 1135 list_del(&e->list);
491 kfree(e); 1136 kfree(e);
492 } 1137 }
493 1138
1139 if (psock->sk_redir)
1140 sock_put(psock->sk_redir);
1141
494 sock_put(psock->sock); 1142 sock_put(psock->sock);
495 kfree(psock); 1143 kfree(psock);
496} 1144}
@@ -506,12 +1154,13 @@ static struct smap_psock *smap_init_psock(struct sock *sock,
506 if (!psock) 1154 if (!psock)
507 return ERR_PTR(-ENOMEM); 1155 return ERR_PTR(-ENOMEM);
508 1156
1157 psock->eval = __SK_NONE;
509 psock->sock = sock; 1158 psock->sock = sock;
510 skb_queue_head_init(&psock->rxqueue); 1159 skb_queue_head_init(&psock->rxqueue);
511 INIT_WORK(&psock->tx_work, smap_tx_work); 1160 INIT_WORK(&psock->tx_work, smap_tx_work);
512 INIT_WORK(&psock->gc_work, smap_gc_work); 1161 INIT_WORK(&psock->gc_work, smap_gc_work);
513 INIT_LIST_HEAD(&psock->maps); 1162 INIT_LIST_HEAD(&psock->maps);
514 psock->refcnt = 1; 1163 refcount_set(&psock->refcnt, 1);
515 1164
516 rcu_assign_sk_user_data(sock, psock); 1165 rcu_assign_sk_user_data(sock, psock);
517 sock_hold(sock); 1166 sock_hold(sock);
@@ -714,10 +1363,11 @@ static int sock_map_ctx_update_elem(struct bpf_sock_ops_kern *skops,
714{ 1363{
715 struct bpf_stab *stab = container_of(map, struct bpf_stab, map); 1364 struct bpf_stab *stab = container_of(map, struct bpf_stab, map);
716 struct smap_psock_map_entry *e = NULL; 1365 struct smap_psock_map_entry *e = NULL;
717 struct bpf_prog *verdict, *parse; 1366 struct bpf_prog *verdict, *parse, *tx_msg;
718 struct sock *osock, *sock; 1367 struct sock *osock, *sock;
719 struct smap_psock *psock; 1368 struct smap_psock *psock;
720 u32 i = *(u32 *)key; 1369 u32 i = *(u32 *)key;
1370 bool new = false;
721 int err; 1371 int err;
722 1372
723 if (unlikely(flags > BPF_EXIST)) 1373 if (unlikely(flags > BPF_EXIST))
@@ -740,6 +1390,7 @@ static int sock_map_ctx_update_elem(struct bpf_sock_ops_kern *skops,
740 */ 1390 */
741 verdict = READ_ONCE(stab->bpf_verdict); 1391 verdict = READ_ONCE(stab->bpf_verdict);
742 parse = READ_ONCE(stab->bpf_parse); 1392 parse = READ_ONCE(stab->bpf_parse);
1393 tx_msg = READ_ONCE(stab->bpf_tx_msg);
743 1394
744 if (parse && verdict) { 1395 if (parse && verdict) {
745 /* bpf prog refcnt may be zero if a concurrent attach operation 1396 /* bpf prog refcnt may be zero if a concurrent attach operation
@@ -758,6 +1409,17 @@ static int sock_map_ctx_update_elem(struct bpf_sock_ops_kern *skops,
758 } 1409 }
759 } 1410 }
760 1411
1412 if (tx_msg) {
1413 tx_msg = bpf_prog_inc_not_zero(stab->bpf_tx_msg);
1414 if (IS_ERR(tx_msg)) {
1415 if (verdict)
1416 bpf_prog_put(verdict);
1417 if (parse)
1418 bpf_prog_put(parse);
1419 return PTR_ERR(tx_msg);
1420 }
1421 }
1422
761 write_lock_bh(&sock->sk_callback_lock); 1423 write_lock_bh(&sock->sk_callback_lock);
762 psock = smap_psock_sk(sock); 1424 psock = smap_psock_sk(sock);
763 1425
@@ -772,7 +1434,14 @@ static int sock_map_ctx_update_elem(struct bpf_sock_ops_kern *skops,
772 err = -EBUSY; 1434 err = -EBUSY;
773 goto out_progs; 1435 goto out_progs;
774 } 1436 }
775 psock->refcnt++; 1437 if (READ_ONCE(psock->bpf_tx_msg) && tx_msg) {
1438 err = -EBUSY;
1439 goto out_progs;
1440 }
1441 if (!refcount_inc_not_zero(&psock->refcnt)) {
1442 err = -EAGAIN;
1443 goto out_progs;
1444 }
776 } else { 1445 } else {
777 psock = smap_init_psock(sock, stab); 1446 psock = smap_init_psock(sock, stab);
778 if (IS_ERR(psock)) { 1447 if (IS_ERR(psock)) {
@@ -780,11 +1449,8 @@ static int sock_map_ctx_update_elem(struct bpf_sock_ops_kern *skops,
780 goto out_progs; 1449 goto out_progs;
781 } 1450 }
782 1451
783 err = tcp_set_ulp_id(sock, TCP_ULP_BPF);
784 if (err)
785 goto out_progs;
786
787 set_bit(SMAP_TX_RUNNING, &psock->state); 1452 set_bit(SMAP_TX_RUNNING, &psock->state);
1453 new = true;
788 } 1454 }
789 1455
790 e = kzalloc(sizeof(*e), GFP_ATOMIC | __GFP_NOWARN); 1456 e = kzalloc(sizeof(*e), GFP_ATOMIC | __GFP_NOWARN);
@@ -797,6 +1463,14 @@ static int sock_map_ctx_update_elem(struct bpf_sock_ops_kern *skops,
797 /* 3. At this point we have a reference to a valid psock that is 1463 /* 3. At this point we have a reference to a valid psock that is
798 * running. Attach any BPF programs needed. 1464 * running. Attach any BPF programs needed.
799 */ 1465 */
1466 if (tx_msg)
1467 bpf_tcp_msg_add(psock, sock, tx_msg);
1468 if (new) {
1469 err = tcp_set_ulp_id(sock, TCP_ULP_BPF);
1470 if (err)
1471 goto out_free;
1472 }
1473
800 if (parse && verdict && !psock->strp_enabled) { 1474 if (parse && verdict && !psock->strp_enabled) {
801 err = smap_init_sock(psock, sock); 1475 err = smap_init_sock(psock, sock);
802 if (err) 1476 if (err)
@@ -818,8 +1492,6 @@ static int sock_map_ctx_update_elem(struct bpf_sock_ops_kern *skops,
818 struct smap_psock *opsock = smap_psock_sk(osock); 1492 struct smap_psock *opsock = smap_psock_sk(osock);
819 1493
820 write_lock_bh(&osock->sk_callback_lock); 1494 write_lock_bh(&osock->sk_callback_lock);
821 if (osock != sock && parse)
822 smap_stop_sock(opsock, osock);
823 smap_list_remove(opsock, &stab->sock_map[i]); 1495 smap_list_remove(opsock, &stab->sock_map[i]);
824 smap_release_sock(opsock, osock); 1496 smap_release_sock(opsock, osock);
825 write_unlock_bh(&osock->sk_callback_lock); 1497 write_unlock_bh(&osock->sk_callback_lock);
@@ -832,6 +1504,8 @@ out_progs:
832 bpf_prog_put(verdict); 1504 bpf_prog_put(verdict);
833 if (parse) 1505 if (parse)
834 bpf_prog_put(parse); 1506 bpf_prog_put(parse);
1507 if (tx_msg)
1508 bpf_prog_put(tx_msg);
835 write_unlock_bh(&sock->sk_callback_lock); 1509 write_unlock_bh(&sock->sk_callback_lock);
836 kfree(e); 1510 kfree(e);
837 return err; 1511 return err;
@@ -846,6 +1520,9 @@ int sock_map_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type)
846 return -EINVAL; 1520 return -EINVAL;
847 1521
848 switch (type) { 1522 switch (type) {
1523 case BPF_SK_MSG_VERDICT:
1524 orig = xchg(&stab->bpf_tx_msg, prog);
1525 break;
849 case BPF_SK_SKB_STREAM_PARSER: 1526 case BPF_SK_SKB_STREAM_PARSER:
850 orig = xchg(&stab->bpf_parse, prog); 1527 orig = xchg(&stab->bpf_parse, prog);
851 break; 1528 break;
@@ -907,6 +1584,10 @@ static void sock_map_release(struct bpf_map *map, struct file *map_file)
907 orig = xchg(&stab->bpf_verdict, NULL); 1584 orig = xchg(&stab->bpf_verdict, NULL);
908 if (orig) 1585 if (orig)
909 bpf_prog_put(orig); 1586 bpf_prog_put(orig);
1587
1588 orig = xchg(&stab->bpf_tx_msg, NULL);
1589 if (orig)
1590 bpf_prog_put(orig);
910} 1591}
911 1592
912const struct bpf_map_ops sock_map_ops = { 1593const struct bpf_map_ops sock_map_ops = {
diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c
index b0ecf43f5894..57eeb1234b67 100644
--- a/kernel/bpf/stackmap.c
+++ b/kernel/bpf/stackmap.c
@@ -9,16 +9,19 @@
9#include <linux/filter.h> 9#include <linux/filter.h>
10#include <linux/stacktrace.h> 10#include <linux/stacktrace.h>
11#include <linux/perf_event.h> 11#include <linux/perf_event.h>
12#include <linux/elf.h>
13#include <linux/pagemap.h>
12#include "percpu_freelist.h" 14#include "percpu_freelist.h"
13 15
14#define STACK_CREATE_FLAG_MASK \ 16#define STACK_CREATE_FLAG_MASK \
15 (BPF_F_NUMA_NODE | BPF_F_RDONLY | BPF_F_WRONLY) 17 (BPF_F_NUMA_NODE | BPF_F_RDONLY | BPF_F_WRONLY | \
18 BPF_F_STACK_BUILD_ID)
16 19
17struct stack_map_bucket { 20struct stack_map_bucket {
18 struct pcpu_freelist_node fnode; 21 struct pcpu_freelist_node fnode;
19 u32 hash; 22 u32 hash;
20 u32 nr; 23 u32 nr;
21 u64 ip[]; 24 u64 data[];
22}; 25};
23 26
24struct bpf_stack_map { 27struct bpf_stack_map {
@@ -29,6 +32,17 @@ struct bpf_stack_map {
29 struct stack_map_bucket *buckets[]; 32 struct stack_map_bucket *buckets[];
30}; 33};
31 34
35static inline bool stack_map_use_build_id(struct bpf_map *map)
36{
37 return (map->map_flags & BPF_F_STACK_BUILD_ID);
38}
39
40static inline int stack_map_data_size(struct bpf_map *map)
41{
42 return stack_map_use_build_id(map) ?
43 sizeof(struct bpf_stack_build_id) : sizeof(u64);
44}
45
32static int prealloc_elems_and_freelist(struct bpf_stack_map *smap) 46static int prealloc_elems_and_freelist(struct bpf_stack_map *smap)
33{ 47{
34 u32 elem_size = sizeof(struct stack_map_bucket) + smap->map.value_size; 48 u32 elem_size = sizeof(struct stack_map_bucket) + smap->map.value_size;
@@ -68,8 +82,16 @@ static struct bpf_map *stack_map_alloc(union bpf_attr *attr)
68 82
69 /* check sanity of attributes */ 83 /* check sanity of attributes */
70 if (attr->max_entries == 0 || attr->key_size != 4 || 84 if (attr->max_entries == 0 || attr->key_size != 4 ||
71 value_size < 8 || value_size % 8 || 85 value_size < 8 || value_size % 8)
72 value_size / 8 > sysctl_perf_event_max_stack) 86 return ERR_PTR(-EINVAL);
87
88 BUILD_BUG_ON(sizeof(struct bpf_stack_build_id) % sizeof(u64));
89 if (attr->map_flags & BPF_F_STACK_BUILD_ID) {
90 if (value_size % sizeof(struct bpf_stack_build_id) ||
91 value_size / sizeof(struct bpf_stack_build_id)
92 > sysctl_perf_event_max_stack)
93 return ERR_PTR(-EINVAL);
94 } else if (value_size / 8 > sysctl_perf_event_max_stack)
73 return ERR_PTR(-EINVAL); 95 return ERR_PTR(-EINVAL);
74 96
75 /* hash table size must be power of 2 */ 97 /* hash table size must be power of 2 */
@@ -114,13 +136,184 @@ free_smap:
114 return ERR_PTR(err); 136 return ERR_PTR(err);
115} 137}
116 138
139#define BPF_BUILD_ID 3
140/*
141 * Parse build id from the note segment. This logic can be shared between
142 * 32-bit and 64-bit system, because Elf32_Nhdr and Elf64_Nhdr are
143 * identical.
144 */
145static inline int stack_map_parse_build_id(void *page_addr,
146 unsigned char *build_id,
147 void *note_start,
148 Elf32_Word note_size)
149{
150 Elf32_Word note_offs = 0, new_offs;
151
152 /* check for overflow */
153 if (note_start < page_addr || note_start + note_size < note_start)
154 return -EINVAL;
155
156 /* only supports note that fits in the first page */
157 if (note_start + note_size > page_addr + PAGE_SIZE)
158 return -EINVAL;
159
160 while (note_offs + sizeof(Elf32_Nhdr) < note_size) {
161 Elf32_Nhdr *nhdr = (Elf32_Nhdr *)(note_start + note_offs);
162
163 if (nhdr->n_type == BPF_BUILD_ID &&
164 nhdr->n_namesz == sizeof("GNU") &&
165 nhdr->n_descsz == BPF_BUILD_ID_SIZE) {
166 memcpy(build_id,
167 note_start + note_offs +
168 ALIGN(sizeof("GNU"), 4) + sizeof(Elf32_Nhdr),
169 BPF_BUILD_ID_SIZE);
170 return 0;
171 }
172 new_offs = note_offs + sizeof(Elf32_Nhdr) +
173 ALIGN(nhdr->n_namesz, 4) + ALIGN(nhdr->n_descsz, 4);
174 if (new_offs <= note_offs) /* overflow */
175 break;
176 note_offs = new_offs;
177 }
178 return -EINVAL;
179}
180
181/* Parse build ID from 32-bit ELF */
182static int stack_map_get_build_id_32(void *page_addr,
183 unsigned char *build_id)
184{
185 Elf32_Ehdr *ehdr = (Elf32_Ehdr *)page_addr;
186 Elf32_Phdr *phdr;
187 int i;
188
189 /* only supports phdr that fits in one page */
190 if (ehdr->e_phnum >
191 (PAGE_SIZE - sizeof(Elf32_Ehdr)) / sizeof(Elf32_Phdr))
192 return -EINVAL;
193
194 phdr = (Elf32_Phdr *)(page_addr + sizeof(Elf32_Ehdr));
195
196 for (i = 0; i < ehdr->e_phnum; ++i)
197 if (phdr[i].p_type == PT_NOTE)
198 return stack_map_parse_build_id(page_addr, build_id,
199 page_addr + phdr[i].p_offset,
200 phdr[i].p_filesz);
201 return -EINVAL;
202}
203
204/* Parse build ID from 64-bit ELF */
205static int stack_map_get_build_id_64(void *page_addr,
206 unsigned char *build_id)
207{
208 Elf64_Ehdr *ehdr = (Elf64_Ehdr *)page_addr;
209 Elf64_Phdr *phdr;
210 int i;
211
212 /* only supports phdr that fits in one page */
213 if (ehdr->e_phnum >
214 (PAGE_SIZE - sizeof(Elf64_Ehdr)) / sizeof(Elf64_Phdr))
215 return -EINVAL;
216
217 phdr = (Elf64_Phdr *)(page_addr + sizeof(Elf64_Ehdr));
218
219 for (i = 0; i < ehdr->e_phnum; ++i)
220 if (phdr[i].p_type == PT_NOTE)
221 return stack_map_parse_build_id(page_addr, build_id,
222 page_addr + phdr[i].p_offset,
223 phdr[i].p_filesz);
224 return -EINVAL;
225}
226
227/* Parse build ID of ELF file mapped to vma */
228static int stack_map_get_build_id(struct vm_area_struct *vma,
229 unsigned char *build_id)
230{
231 Elf32_Ehdr *ehdr;
232 struct page *page;
233 void *page_addr;
234 int ret;
235
236 /* only works for page backed storage */
237 if (!vma->vm_file)
238 return -EINVAL;
239
240 page = find_get_page(vma->vm_file->f_mapping, 0);
241 if (!page)
242 return -EFAULT; /* page not mapped */
243
244 ret = -EINVAL;
245 page_addr = page_address(page);
246 ehdr = (Elf32_Ehdr *)page_addr;
247
248 /* compare magic x7f "ELF" */
249 if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0)
250 goto out;
251
252 /* only support executable file and shared object file */
253 if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN)
254 goto out;
255
256 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
257 ret = stack_map_get_build_id_32(page_addr, build_id);
258 else if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
259 ret = stack_map_get_build_id_64(page_addr, build_id);
260out:
261 put_page(page);
262 return ret;
263}
264
265static void stack_map_get_build_id_offset(struct bpf_map *map,
266 struct stack_map_bucket *bucket,
267 u64 *ips, u32 trace_nr, bool user)
268{
269 int i;
270 struct vm_area_struct *vma;
271 struct bpf_stack_build_id *id_offs;
272
273 bucket->nr = trace_nr;
274 id_offs = (struct bpf_stack_build_id *)bucket->data;
275
276 /*
277 * We cannot do up_read() in nmi context, so build_id lookup is
278 * only supported for non-nmi events. If at some point, it is
279 * possible to run find_vma() without taking the semaphore, we
280 * would like to allow build_id lookup in nmi context.
281 *
282 * Same fallback is used for kernel stack (!user) on a stackmap
283 * with build_id.
284 */
285 if (!user || !current || !current->mm || in_nmi() ||
286 down_read_trylock(&current->mm->mmap_sem) == 0) {
287 /* cannot access current->mm, fall back to ips */
288 for (i = 0; i < trace_nr; i++) {
289 id_offs[i].status = BPF_STACK_BUILD_ID_IP;
290 id_offs[i].ip = ips[i];
291 }
292 return;
293 }
294
295 for (i = 0; i < trace_nr; i++) {
296 vma = find_vma(current->mm, ips[i]);
297 if (!vma || stack_map_get_build_id(vma, id_offs[i].build_id)) {
298 /* per entry fall back to ips */
299 id_offs[i].status = BPF_STACK_BUILD_ID_IP;
300 id_offs[i].ip = ips[i];
301 continue;
302 }
303 id_offs[i].offset = (vma->vm_pgoff << PAGE_SHIFT) + ips[i]
304 - vma->vm_start;
305 id_offs[i].status = BPF_STACK_BUILD_ID_VALID;
306 }
307 up_read(&current->mm->mmap_sem);
308}
309
117BPF_CALL_3(bpf_get_stackid, struct pt_regs *, regs, struct bpf_map *, map, 310BPF_CALL_3(bpf_get_stackid, struct pt_regs *, regs, struct bpf_map *, map,
118 u64, flags) 311 u64, flags)
119{ 312{
120 struct bpf_stack_map *smap = container_of(map, struct bpf_stack_map, map); 313 struct bpf_stack_map *smap = container_of(map, struct bpf_stack_map, map);
121 struct perf_callchain_entry *trace; 314 struct perf_callchain_entry *trace;
122 struct stack_map_bucket *bucket, *new_bucket, *old_bucket; 315 struct stack_map_bucket *bucket, *new_bucket, *old_bucket;
123 u32 max_depth = map->value_size / 8; 316 u32 max_depth = map->value_size / stack_map_data_size(map);
124 /* stack_map_alloc() checks that max_depth <= sysctl_perf_event_max_stack */ 317 /* stack_map_alloc() checks that max_depth <= sysctl_perf_event_max_stack */
125 u32 init_nr = sysctl_perf_event_max_stack - max_depth; 318 u32 init_nr = sysctl_perf_event_max_stack - max_depth;
126 u32 skip = flags & BPF_F_SKIP_FIELD_MASK; 319 u32 skip = flags & BPF_F_SKIP_FIELD_MASK;
@@ -128,6 +321,7 @@ BPF_CALL_3(bpf_get_stackid, struct pt_regs *, regs, struct bpf_map *, map,
128 bool user = flags & BPF_F_USER_STACK; 321 bool user = flags & BPF_F_USER_STACK;
129 bool kernel = !user; 322 bool kernel = !user;
130 u64 *ips; 323 u64 *ips;
324 bool hash_matches;
131 325
132 if (unlikely(flags & ~(BPF_F_SKIP_FIELD_MASK | BPF_F_USER_STACK | 326 if (unlikely(flags & ~(BPF_F_SKIP_FIELD_MASK | BPF_F_USER_STACK |
133 BPF_F_FAST_STACK_CMP | BPF_F_REUSE_STACKID))) 327 BPF_F_FAST_STACK_CMP | BPF_F_REUSE_STACKID)))
@@ -156,24 +350,43 @@ BPF_CALL_3(bpf_get_stackid, struct pt_regs *, regs, struct bpf_map *, map,
156 id = hash & (smap->n_buckets - 1); 350 id = hash & (smap->n_buckets - 1);
157 bucket = READ_ONCE(smap->buckets[id]); 351 bucket = READ_ONCE(smap->buckets[id]);
158 352
159 if (bucket && bucket->hash == hash) { 353 hash_matches = bucket && bucket->hash == hash;
160 if (flags & BPF_F_FAST_STACK_CMP) 354 /* fast cmp */
355 if (hash_matches && flags & BPF_F_FAST_STACK_CMP)
356 return id;
357
358 if (stack_map_use_build_id(map)) {
359 /* for build_id+offset, pop a bucket before slow cmp */
360 new_bucket = (struct stack_map_bucket *)
361 pcpu_freelist_pop(&smap->freelist);
362 if (unlikely(!new_bucket))
363 return -ENOMEM;
364 stack_map_get_build_id_offset(map, new_bucket, ips,
365 trace_nr, user);
366 trace_len = trace_nr * sizeof(struct bpf_stack_build_id);
367 if (hash_matches && bucket->nr == trace_nr &&
368 memcmp(bucket->data, new_bucket->data, trace_len) == 0) {
369 pcpu_freelist_push(&smap->freelist, &new_bucket->fnode);
161 return id; 370 return id;
162 if (bucket->nr == trace_nr && 371 }
163 memcmp(bucket->ip, ips, trace_len) == 0) 372 if (bucket && !(flags & BPF_F_REUSE_STACKID)) {
373 pcpu_freelist_push(&smap->freelist, &new_bucket->fnode);
374 return -EEXIST;
375 }
376 } else {
377 if (hash_matches && bucket->nr == trace_nr &&
378 memcmp(bucket->data, ips, trace_len) == 0)
164 return id; 379 return id;
380 if (bucket && !(flags & BPF_F_REUSE_STACKID))
381 return -EEXIST;
382
383 new_bucket = (struct stack_map_bucket *)
384 pcpu_freelist_pop(&smap->freelist);
385 if (unlikely(!new_bucket))
386 return -ENOMEM;
387 memcpy(new_bucket->data, ips, trace_len);
165 } 388 }
166 389
167 /* this call stack is not in the map, try to add it */
168 if (bucket && !(flags & BPF_F_REUSE_STACKID))
169 return -EEXIST;
170
171 new_bucket = (struct stack_map_bucket *)
172 pcpu_freelist_pop(&smap->freelist);
173 if (unlikely(!new_bucket))
174 return -ENOMEM;
175
176 memcpy(new_bucket->ip, ips, trace_len);
177 new_bucket->hash = hash; 390 new_bucket->hash = hash;
178 new_bucket->nr = trace_nr; 391 new_bucket->nr = trace_nr;
179 392
@@ -212,8 +425,8 @@ int bpf_stackmap_copy(struct bpf_map *map, void *key, void *value)
212 if (!bucket) 425 if (!bucket)
213 return -ENOENT; 426 return -ENOENT;
214 427
215 trace_len = bucket->nr * sizeof(u64); 428 trace_len = bucket->nr * stack_map_data_size(map);
216 memcpy(value, bucket->ip, trace_len); 429 memcpy(value, bucket->data, trace_len);
217 memset(value + trace_len, 0, map->value_size - trace_len); 430 memset(value + trace_len, 0, map->value_size - trace_len);
218 431
219 old_bucket = xchg(&smap->buckets[id], bucket); 432 old_bucket = xchg(&smap->buckets[id], bucket);
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 43f95d190eea..dd172ee16716 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -1315,7 +1315,8 @@ static int bpf_obj_get(const union bpf_attr *attr)
1315 1315
1316#define BPF_PROG_ATTACH_LAST_FIELD attach_flags 1316#define BPF_PROG_ATTACH_LAST_FIELD attach_flags
1317 1317
1318static int sockmap_get_from_fd(const union bpf_attr *attr, bool attach) 1318static int sockmap_get_from_fd(const union bpf_attr *attr,
1319 int type, bool attach)
1319{ 1320{
1320 struct bpf_prog *prog = NULL; 1321 struct bpf_prog *prog = NULL;
1321 int ufd = attr->target_fd; 1322 int ufd = attr->target_fd;
@@ -1329,8 +1330,7 @@ static int sockmap_get_from_fd(const union bpf_attr *attr, bool attach)
1329 return PTR_ERR(map); 1330 return PTR_ERR(map);
1330 1331
1331 if (attach) { 1332 if (attach) {
1332 prog = bpf_prog_get_type(attr->attach_bpf_fd, 1333 prog = bpf_prog_get_type(attr->attach_bpf_fd, type);
1333 BPF_PROG_TYPE_SK_SKB);
1334 if (IS_ERR(prog)) { 1334 if (IS_ERR(prog)) {
1335 fdput(f); 1335 fdput(f);
1336 return PTR_ERR(prog); 1336 return PTR_ERR(prog);
@@ -1382,9 +1382,11 @@ static int bpf_prog_attach(const union bpf_attr *attr)
1382 case BPF_CGROUP_DEVICE: 1382 case BPF_CGROUP_DEVICE:
1383 ptype = BPF_PROG_TYPE_CGROUP_DEVICE; 1383 ptype = BPF_PROG_TYPE_CGROUP_DEVICE;
1384 break; 1384 break;
1385 case BPF_SK_MSG_VERDICT:
1386 return sockmap_get_from_fd(attr, BPF_PROG_TYPE_SK_MSG, true);
1385 case BPF_SK_SKB_STREAM_PARSER: 1387 case BPF_SK_SKB_STREAM_PARSER:
1386 case BPF_SK_SKB_STREAM_VERDICT: 1388 case BPF_SK_SKB_STREAM_VERDICT:
1387 return sockmap_get_from_fd(attr, true); 1389 return sockmap_get_from_fd(attr, BPF_PROG_TYPE_SK_SKB, true);
1388 default: 1390 default:
1389 return -EINVAL; 1391 return -EINVAL;
1390 } 1392 }
@@ -1437,9 +1439,11 @@ static int bpf_prog_detach(const union bpf_attr *attr)
1437 case BPF_CGROUP_DEVICE: 1439 case BPF_CGROUP_DEVICE:
1438 ptype = BPF_PROG_TYPE_CGROUP_DEVICE; 1440 ptype = BPF_PROG_TYPE_CGROUP_DEVICE;
1439 break; 1441 break;
1442 case BPF_SK_MSG_VERDICT:
1443 return sockmap_get_from_fd(attr, BPF_PROG_TYPE_SK_MSG, false);
1440 case BPF_SK_SKB_STREAM_PARSER: 1444 case BPF_SK_SKB_STREAM_PARSER:
1441 case BPF_SK_SKB_STREAM_VERDICT: 1445 case BPF_SK_SKB_STREAM_VERDICT:
1442 return sockmap_get_from_fd(attr, false); 1446 return sockmap_get_from_fd(attr, BPF_PROG_TYPE_SK_SKB, false);
1443 default: 1447 default:
1444 return -EINVAL; 1448 return -EINVAL;
1445 } 1449 }
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index c6eff108aa99..e9f7c20691c1 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -508,10 +508,6 @@ err:
508static const int caller_saved[CALLER_SAVED_REGS] = { 508static const int caller_saved[CALLER_SAVED_REGS] = {
509 BPF_REG_0, BPF_REG_1, BPF_REG_2, BPF_REG_3, BPF_REG_4, BPF_REG_5 509 BPF_REG_0, BPF_REG_1, BPF_REG_2, BPF_REG_3, BPF_REG_4, BPF_REG_5
510}; 510};
511#define CALLEE_SAVED_REGS 5
512static const int callee_saved[CALLEE_SAVED_REGS] = {
513 BPF_REG_6, BPF_REG_7, BPF_REG_8, BPF_REG_9
514};
515 511
516static void __mark_reg_not_init(struct bpf_reg_state *reg); 512static void __mark_reg_not_init(struct bpf_reg_state *reg);
517 513
@@ -1252,6 +1248,7 @@ static bool may_access_direct_pkt_data(struct bpf_verifier_env *env,
1252 case BPF_PROG_TYPE_XDP: 1248 case BPF_PROG_TYPE_XDP:
1253 case BPF_PROG_TYPE_LWT_XMIT: 1249 case BPF_PROG_TYPE_LWT_XMIT:
1254 case BPF_PROG_TYPE_SK_SKB: 1250 case BPF_PROG_TYPE_SK_SKB:
1251 case BPF_PROG_TYPE_SK_MSG:
1255 if (meta) 1252 if (meta)
1256 return meta->pkt_access; 1253 return meta->pkt_access;
1257 1254
@@ -2075,7 +2072,8 @@ static int check_map_func_compatibility(struct bpf_verifier_env *env,
2075 case BPF_MAP_TYPE_SOCKMAP: 2072 case BPF_MAP_TYPE_SOCKMAP:
2076 if (func_id != BPF_FUNC_sk_redirect_map && 2073 if (func_id != BPF_FUNC_sk_redirect_map &&
2077 func_id != BPF_FUNC_sock_map_update && 2074 func_id != BPF_FUNC_sock_map_update &&
2078 func_id != BPF_FUNC_map_delete_elem) 2075 func_id != BPF_FUNC_map_delete_elem &&
2076 func_id != BPF_FUNC_msg_redirect_map)
2079 goto error; 2077 goto error;
2080 break; 2078 break;
2081 default: 2079 default:
@@ -2113,6 +2111,7 @@ static int check_map_func_compatibility(struct bpf_verifier_env *env,
2113 goto error; 2111 goto error;
2114 break; 2112 break;
2115 case BPF_FUNC_sk_redirect_map: 2113 case BPF_FUNC_sk_redirect_map:
2114 case BPF_FUNC_msg_redirect_map:
2116 if (map->map_type != BPF_MAP_TYPE_SOCKMAP) 2115 if (map->map_type != BPF_MAP_TYPE_SOCKMAP)
2117 goto error; 2116 goto error;
2118 break; 2117 break;
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index 01e6b3a38871..7f9691c86b6e 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -738,8 +738,7 @@ static const struct bpf_func_proto *pe_prog_func_proto(enum bpf_func_id func_id)
738static bool pe_prog_is_valid_access(int off, int size, enum bpf_access_type type, 738static bool pe_prog_is_valid_access(int off, int size, enum bpf_access_type type,
739 struct bpf_insn_access_aux *info) 739 struct bpf_insn_access_aux *info)
740{ 740{
741 const int size_sp = FIELD_SIZEOF(struct bpf_perf_event_data, 741 const int size_u64 = sizeof(u64);
742 sample_period);
743 742
744 if (off < 0 || off >= sizeof(struct bpf_perf_event_data)) 743 if (off < 0 || off >= sizeof(struct bpf_perf_event_data))
745 return false; 744 return false;
@@ -750,8 +749,13 @@ static bool pe_prog_is_valid_access(int off, int size, enum bpf_access_type type
750 749
751 switch (off) { 750 switch (off) {
752 case bpf_ctx_range(struct bpf_perf_event_data, sample_period): 751 case bpf_ctx_range(struct bpf_perf_event_data, sample_period):
753 bpf_ctx_record_field_size(info, size_sp); 752 bpf_ctx_record_field_size(info, size_u64);
754 if (!bpf_ctx_narrow_access_ok(off, size, size_sp)) 753 if (!bpf_ctx_narrow_access_ok(off, size, size_u64))
754 return false;
755 break;
756 case bpf_ctx_range(struct bpf_perf_event_data, addr):
757 bpf_ctx_record_field_size(info, size_u64);
758 if (!bpf_ctx_narrow_access_ok(off, size, size_u64))
755 return false; 759 return false;
756 break; 760 break;
757 default: 761 default:
@@ -778,6 +782,14 @@ static u32 pe_prog_convert_ctx_access(enum bpf_access_type type,
778 bpf_target_off(struct perf_sample_data, period, 8, 782 bpf_target_off(struct perf_sample_data, period, 8,
779 target_size)); 783 target_size));
780 break; 784 break;
785 case offsetof(struct bpf_perf_event_data, addr):
786 *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct bpf_perf_event_data_kern,
787 data), si->dst_reg, si->src_reg,
788 offsetof(struct bpf_perf_event_data_kern, data));
789 *insn++ = BPF_LDX_MEM(BPF_DW, si->dst_reg, si->dst_reg,
790 bpf_target_off(struct perf_sample_data, addr, 8,
791 target_size));
792 break;
781 default: 793 default:
782 *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct bpf_perf_event_data_kern, 794 *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct bpf_perf_event_data_kern,
783 regs), si->dst_reg, si->src_reg, 795 regs), si->dst_reg, si->src_reg,
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c
index 9fe6ec8fda28..fa10ad8e9b17 100644
--- a/lib/kobject_uevent.c
+++ b/lib/kobject_uevent.c
@@ -25,6 +25,7 @@
25#include <linux/uuid.h> 25#include <linux/uuid.h>
26#include <linux/ctype.h> 26#include <linux/ctype.h>
27#include <net/sock.h> 27#include <net/sock.h>
28#include <net/netlink.h>
28#include <net/net_namespace.h> 29#include <net/net_namespace.h>
29 30
30 31
@@ -32,11 +33,13 @@ u64 uevent_seqnum;
32#ifdef CONFIG_UEVENT_HELPER 33#ifdef CONFIG_UEVENT_HELPER
33char uevent_helper[UEVENT_HELPER_PATH_LEN] = CONFIG_UEVENT_HELPER_PATH; 34char uevent_helper[UEVENT_HELPER_PATH_LEN] = CONFIG_UEVENT_HELPER_PATH;
34#endif 35#endif
35#ifdef CONFIG_NET 36
36struct uevent_sock { 37struct uevent_sock {
37 struct list_head list; 38 struct list_head list;
38 struct sock *sk; 39 struct sock *sk;
39}; 40};
41
42#ifdef CONFIG_NET
40static LIST_HEAD(uevent_sock_list); 43static LIST_HEAD(uevent_sock_list);
41#endif 44#endif
42 45
@@ -602,12 +605,88 @@ int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...)
602EXPORT_SYMBOL_GPL(add_uevent_var); 605EXPORT_SYMBOL_GPL(add_uevent_var);
603 606
604#if defined(CONFIG_NET) 607#if defined(CONFIG_NET)
608static int uevent_net_broadcast(struct sock *usk, struct sk_buff *skb,
609 struct netlink_ext_ack *extack)
610{
611 /* u64 to chars: 2^64 - 1 = 21 chars */
612 char buf[sizeof("SEQNUM=") + 21];
613 struct sk_buff *skbc;
614 int ret;
615
616 /* bump and prepare sequence number */
617 ret = snprintf(buf, sizeof(buf), "SEQNUM=%llu", ++uevent_seqnum);
618 if (ret < 0 || (size_t)ret >= sizeof(buf))
619 return -ENOMEM;
620 ret++;
621
622 /* verify message does not overflow */
623 if ((skb->len + ret) > UEVENT_BUFFER_SIZE) {
624 NL_SET_ERR_MSG(extack, "uevent message too big");
625 return -EINVAL;
626 }
627
628 /* copy skb and extend to accommodate sequence number */
629 skbc = skb_copy_expand(skb, 0, ret, GFP_KERNEL);
630 if (!skbc)
631 return -ENOMEM;
632
633 /* append sequence number */
634 skb_put_data(skbc, buf, ret);
635
636 /* remove msg header */
637 skb_pull(skbc, NLMSG_HDRLEN);
638
639 /* set portid 0 to inform userspace message comes from kernel */
640 NETLINK_CB(skbc).portid = 0;
641 NETLINK_CB(skbc).dst_group = 1;
642
643 ret = netlink_broadcast(usk, skbc, 0, 1, GFP_KERNEL);
644 /* ENOBUFS should be handled in userspace */
645 if (ret == -ENOBUFS || ret == -ESRCH)
646 ret = 0;
647
648 return ret;
649}
650
651static int uevent_net_rcv_skb(struct sk_buff *skb, struct nlmsghdr *nlh,
652 struct netlink_ext_ack *extack)
653{
654 struct net *net;
655 int ret;
656
657 if (!nlmsg_data(nlh))
658 return -EINVAL;
659
660 /*
661 * Verify that we are allowed to send messages to the target
662 * network namespace. The caller must have CAP_SYS_ADMIN in the
663 * owning user namespace of the target network namespace.
664 */
665 net = sock_net(NETLINK_CB(skb).sk);
666 if (!netlink_ns_capable(skb, net->user_ns, CAP_SYS_ADMIN)) {
667 NL_SET_ERR_MSG(extack, "missing CAP_SYS_ADMIN capability");
668 return -EPERM;
669 }
670
671 mutex_lock(&uevent_sock_mutex);
672 ret = uevent_net_broadcast(net->uevent_sock->sk, skb, extack);
673 mutex_unlock(&uevent_sock_mutex);
674
675 return ret;
676}
677
678static void uevent_net_rcv(struct sk_buff *skb)
679{
680 netlink_rcv_skb(skb, &uevent_net_rcv_skb);
681}
682
605static int uevent_net_init(struct net *net) 683static int uevent_net_init(struct net *net)
606{ 684{
607 struct uevent_sock *ue_sk; 685 struct uevent_sock *ue_sk;
608 struct netlink_kernel_cfg cfg = { 686 struct netlink_kernel_cfg cfg = {
609 .groups = 1, 687 .groups = 1,
610 .flags = NL_CFG_F_NONROOT_RECV, 688 .input = uevent_net_rcv,
689 .flags = NL_CFG_F_NONROOT_RECV
611 }; 690 };
612 691
613 ue_sk = kzalloc(sizeof(*ue_sk), GFP_KERNEL); 692 ue_sk = kzalloc(sizeof(*ue_sk), GFP_KERNEL);
@@ -621,6 +700,9 @@ static int uevent_net_init(struct net *net)
621 kfree(ue_sk); 700 kfree(ue_sk);
622 return -ENODEV; 701 return -ENODEV;
623 } 702 }
703
704 net->uevent_sock = ue_sk;
705
624 mutex_lock(&uevent_sock_mutex); 706 mutex_lock(&uevent_sock_mutex);
625 list_add_tail(&ue_sk->list, &uevent_sock_list); 707 list_add_tail(&ue_sk->list, &uevent_sock_list);
626 mutex_unlock(&uevent_sock_mutex); 708 mutex_unlock(&uevent_sock_mutex);
@@ -629,17 +711,9 @@ static int uevent_net_init(struct net *net)
629 711
630static void uevent_net_exit(struct net *net) 712static void uevent_net_exit(struct net *net)
631{ 713{
632 struct uevent_sock *ue_sk; 714 struct uevent_sock *ue_sk = net->uevent_sock;
633 715
634 mutex_lock(&uevent_sock_mutex); 716 mutex_lock(&uevent_sock_mutex);
635 list_for_each_entry(ue_sk, &uevent_sock_list, list) {
636 if (sock_net(ue_sk->sk) == net)
637 goto found;
638 }
639 mutex_unlock(&uevent_sock_mutex);
640 return;
641
642found:
643 list_del(&ue_sk->list); 717 list_del(&ue_sk->list);
644 mutex_unlock(&uevent_sock_mutex); 718 mutex_unlock(&uevent_sock_mutex);
645 719
@@ -650,6 +724,7 @@ found:
650static struct pernet_operations uevent_net_ops = { 724static struct pernet_operations uevent_net_ops = {
651 .init = uevent_net_init, 725 .init = uevent_net_init,
652 .exit = uevent_net_exit, 726 .exit = uevent_net_exit,
727 .async = true,
653}; 728};
654 729
655static int __init kobject_uevent_init(void) 730static int __init kobject_uevent_init(void)
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index bad01b14a4ad..bd0ed39f65fb 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -729,6 +729,7 @@ static struct pernet_operations vlan_net_ops = {
729 .exit = vlan_exit_net, 729 .exit = vlan_exit_net,
730 .id = &vlan_net_id, 730 .id = &vlan_net_id,
731 .size = sizeof(struct vlan_net), 731 .size = sizeof(struct vlan_net),
732 .async = true,
732}; 733};
733 734
734static int __init vlan_proto_init(void) 735static int __init vlan_proto_init(void)
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index 03a9fc0771c0..9b6bc5abe946 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -1238,7 +1238,7 @@ out:
1238 * fields into the sockaddr. 1238 * fields into the sockaddr.
1239 */ 1239 */
1240static int atalk_getname(struct socket *sock, struct sockaddr *uaddr, 1240static int atalk_getname(struct socket *sock, struct sockaddr *uaddr,
1241 int *uaddr_len, int peer) 1241 int peer)
1242{ 1242{
1243 struct sockaddr_at sat; 1243 struct sockaddr_at sat;
1244 struct sock *sk = sock->sk; 1244 struct sock *sk = sock->sk;
@@ -1251,7 +1251,6 @@ static int atalk_getname(struct socket *sock, struct sockaddr *uaddr,
1251 if (atalk_autobind(sk) < 0) 1251 if (atalk_autobind(sk) < 0)
1252 goto out; 1252 goto out;
1253 1253
1254 *uaddr_len = sizeof(struct sockaddr_at);
1255 memset(&sat, 0, sizeof(sat)); 1254 memset(&sat, 0, sizeof(sat));
1256 1255
1257 if (peer) { 1256 if (peer) {
@@ -1268,9 +1267,9 @@ static int atalk_getname(struct socket *sock, struct sockaddr *uaddr,
1268 sat.sat_port = at->src_port; 1267 sat.sat_port = at->src_port;
1269 } 1268 }
1270 1269
1271 err = 0;
1272 sat.sat_family = AF_APPLETALK; 1270 sat.sat_family = AF_APPLETALK;
1273 memcpy(uaddr, &sat, sizeof(sat)); 1271 memcpy(uaddr, &sat, sizeof(sat));
1272 err = sizeof(struct sockaddr_at);
1274 1273
1275out: 1274out:
1276 release_sock(sk); 1275 release_sock(sk);
diff --git a/net/atm/pvc.c b/net/atm/pvc.c
index e1140b3bdcaa..2cb10af16afc 100644
--- a/net/atm/pvc.c
+++ b/net/atm/pvc.c
@@ -87,21 +87,20 @@ static int pvc_getsockopt(struct socket *sock, int level, int optname,
87} 87}
88 88
89static int pvc_getname(struct socket *sock, struct sockaddr *sockaddr, 89static int pvc_getname(struct socket *sock, struct sockaddr *sockaddr,
90 int *sockaddr_len, int peer) 90 int peer)
91{ 91{
92 struct sockaddr_atmpvc *addr; 92 struct sockaddr_atmpvc *addr;
93 struct atm_vcc *vcc = ATM_SD(sock); 93 struct atm_vcc *vcc = ATM_SD(sock);
94 94
95 if (!vcc->dev || !test_bit(ATM_VF_ADDR, &vcc->flags)) 95 if (!vcc->dev || !test_bit(ATM_VF_ADDR, &vcc->flags))
96 return -ENOTCONN; 96 return -ENOTCONN;
97 *sockaddr_len = sizeof(struct sockaddr_atmpvc);
98 addr = (struct sockaddr_atmpvc *)sockaddr; 97 addr = (struct sockaddr_atmpvc *)sockaddr;
99 memset(addr, 0, sizeof(*addr)); 98 memset(addr, 0, sizeof(*addr));
100 addr->sap_family = AF_ATMPVC; 99 addr->sap_family = AF_ATMPVC;
101 addr->sap_addr.itf = vcc->dev->number; 100 addr->sap_addr.itf = vcc->dev->number;
102 addr->sap_addr.vpi = vcc->vpi; 101 addr->sap_addr.vpi = vcc->vpi;
103 addr->sap_addr.vci = vcc->vci; 102 addr->sap_addr.vci = vcc->vci;
104 return 0; 103 return sizeof(struct sockaddr_atmpvc);
105} 104}
106 105
107static const struct proto_ops pvc_proto_ops = { 106static const struct proto_ops pvc_proto_ops = {
diff --git a/net/atm/svc.c b/net/atm/svc.c
index c458adcbc177..2f91b766ac42 100644
--- a/net/atm/svc.c
+++ b/net/atm/svc.c
@@ -419,15 +419,14 @@ out:
419} 419}
420 420
421static int svc_getname(struct socket *sock, struct sockaddr *sockaddr, 421static int svc_getname(struct socket *sock, struct sockaddr *sockaddr,
422 int *sockaddr_len, int peer) 422 int peer)
423{ 423{
424 struct sockaddr_atmsvc *addr; 424 struct sockaddr_atmsvc *addr;
425 425
426 *sockaddr_len = sizeof(struct sockaddr_atmsvc);
427 addr = (struct sockaddr_atmsvc *) sockaddr; 426 addr = (struct sockaddr_atmsvc *) sockaddr;
428 memcpy(addr, peer ? &ATM_SD(sock)->remote : &ATM_SD(sock)->local, 427 memcpy(addr, peer ? &ATM_SD(sock)->remote : &ATM_SD(sock)->local,
429 sizeof(struct sockaddr_atmsvc)); 428 sizeof(struct sockaddr_atmsvc));
430 return 0; 429 return sizeof(struct sockaddr_atmsvc);
431} 430}
432 431
433int svc_change_qos(struct atm_vcc *vcc, struct atm_qos *qos) 432int svc_change_qos(struct atm_vcc *vcc, struct atm_qos *qos)
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 47fdd399626b..c8319ed48485 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -1388,7 +1388,7 @@ out:
1388} 1388}
1389 1389
1390static int ax25_getname(struct socket *sock, struct sockaddr *uaddr, 1390static int ax25_getname(struct socket *sock, struct sockaddr *uaddr,
1391 int *uaddr_len, int peer) 1391 int peer)
1392{ 1392{
1393 struct full_sockaddr_ax25 *fsa = (struct full_sockaddr_ax25 *)uaddr; 1393 struct full_sockaddr_ax25 *fsa = (struct full_sockaddr_ax25 *)uaddr;
1394 struct sock *sk = sock->sk; 1394 struct sock *sk = sock->sk;
@@ -1427,7 +1427,7 @@ static int ax25_getname(struct socket *sock, struct sockaddr *uaddr,
1427 fsa->fsa_digipeater[0] = null_ax25_address; 1427 fsa->fsa_digipeater[0] = null_ax25_address;
1428 } 1428 }
1429 } 1429 }
1430 *uaddr_len = sizeof (struct full_sockaddr_ax25); 1430 err = sizeof (struct full_sockaddr_ax25);
1431 1431
1432out: 1432out:
1433 release_sock(sk); 1433 release_sock(sk);
diff --git a/net/batman-adv/Kconfig b/net/batman-adv/Kconfig
index c44f6515be5e..e4e2e02b7380 100644
--- a/net/batman-adv/Kconfig
+++ b/net/batman-adv/Kconfig
@@ -1,5 +1,5 @@
1# SPDX-License-Identifier: GPL-2.0 1# SPDX-License-Identifier: GPL-2.0
2# Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: 2# Copyright (C) 2007-2018 B.A.T.M.A.N. contributors:
3# 3#
4# Marek Lindner, Simon Wunderlich 4# Marek Lindner, Simon Wunderlich
5# 5#
diff --git a/net/batman-adv/Makefile b/net/batman-adv/Makefile
index 022f6e77307b..b97ba6fb8353 100644
--- a/net/batman-adv/Makefile
+++ b/net/batman-adv/Makefile
@@ -1,5 +1,5 @@
1# SPDX-License-Identifier: GPL-2.0 1# SPDX-License-Identifier: GPL-2.0
2# Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: 2# Copyright (C) 2007-2018 B.A.T.M.A.N. contributors:
3# 3#
4# Marek Lindner, Simon Wunderlich 4# Marek Lindner, Simon Wunderlich
5# 5#
diff --git a/net/batman-adv/bat_algo.c b/net/batman-adv/bat_algo.c
index 80c72c7d3cad..ea309ad06175 100644
--- a/net/batman-adv/bat_algo.c
+++ b/net/batman-adv/bat_algo.c
@@ -1,5 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2007-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner, Simon Wunderlich 4 * Marek Lindner, Simon Wunderlich
5 * 5 *
diff --git a/net/batman-adv/bat_algo.h b/net/batman-adv/bat_algo.h
index 029221615ba3..534b790c3753 100644
--- a/net/batman-adv/bat_algo.h
+++ b/net/batman-adv/bat_algo.h
@@ -1,5 +1,5 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (C) 2011-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2011-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner, Linus Lüssing 4 * Marek Lindner, Linus Lüssing
5 * 5 *
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
index 99abeadf416e..be09a9883825 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -1,5 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2007-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner, Simon Wunderlich 4 * Marek Lindner, Simon Wunderlich
5 * 5 *
diff --git a/net/batman-adv/bat_iv_ogm.h b/net/batman-adv/bat_iv_ogm.h
index 9dc0dd5c83df..317cafd302cf 100644
--- a/net/batman-adv/bat_iv_ogm.h
+++ b/net/batman-adv/bat_iv_ogm.h
@@ -1,5 +1,5 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2007-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner, Simon Wunderlich 4 * Marek Lindner, Simon Wunderlich
5 * 5 *
diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c
index c74f81341dab..ec93337ee259 100644
--- a/net/batman-adv/bat_v.c
+++ b/net/batman-adv/bat_v.c
@@ -1,5 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2013-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2013-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Linus Lüssing, Marek Lindner 4 * Linus Lüssing, Marek Lindner
5 * 5 *
diff --git a/net/batman-adv/bat_v.h b/net/batman-adv/bat_v.h
index a17ab68bbce8..ec4a2a569750 100644
--- a/net/batman-adv/bat_v.h
+++ b/net/batman-adv/bat_v.h
@@ -1,5 +1,5 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (C) 2011-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2011-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner, Linus Lüssing 4 * Marek Lindner, Linus Lüssing
5 * 5 *
diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c
index a83478c46597..28687493599f 100644
--- a/net/batman-adv/bat_v_elp.c
+++ b/net/batman-adv/bat_v_elp.c
@@ -1,5 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2011-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2011-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Linus Lüssing, Marek Lindner 4 * Linus Lüssing, Marek Lindner
5 * 5 *
diff --git a/net/batman-adv/bat_v_elp.h b/net/batman-adv/bat_v_elp.h
index 5e39d0588a48..e8c7b7fd290d 100644
--- a/net/batman-adv/bat_v_elp.h
+++ b/net/batman-adv/bat_v_elp.h
@@ -1,5 +1,5 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (C) 2013-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2013-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Linus Lüssing, Marek Lindner 4 * Linus Lüssing, Marek Lindner
5 * 5 *
diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c
index ba59b77c605d..2948b41b06d4 100644
--- a/net/batman-adv/bat_v_ogm.c
+++ b/net/batman-adv/bat_v_ogm.c
@@ -1,5 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2013-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2013-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Antonio Quartulli 4 * Antonio Quartulli
5 * 5 *
diff --git a/net/batman-adv/bat_v_ogm.h b/net/batman-adv/bat_v_ogm.h
index 6a4c14ccc3c6..ed36c5e79fde 100644
--- a/net/batman-adv/bat_v_ogm.h
+++ b/net/batman-adv/bat_v_ogm.h
@@ -1,5 +1,5 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (C) 2013-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2013-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Antonio Quartulli 4 * Antonio Quartulli
5 * 5 *
diff --git a/net/batman-adv/bitarray.c b/net/batman-adv/bitarray.c
index bdc1ef06e05b..a296a4d851f5 100644
--- a/net/batman-adv/bitarray.c
+++ b/net/batman-adv/bitarray.c
@@ -1,5 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2006-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2006-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Simon Wunderlich, Marek Lindner 4 * Simon Wunderlich, Marek Lindner
5 * 5 *
diff --git a/net/batman-adv/bitarray.h b/net/batman-adv/bitarray.h
index ca9d0753dd6b..48f683289531 100644
--- a/net/batman-adv/bitarray.h
+++ b/net/batman-adv/bitarray.h
@@ -1,5 +1,5 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (C) 2006-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2006-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Simon Wunderlich, Marek Lindner 4 * Simon Wunderlich, Marek Lindner
5 * 5 *
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
index b1a08374088b..a2de5a44bd41 100644
--- a/net/batman-adv/bridge_loop_avoidance.c
+++ b/net/batman-adv/bridge_loop_avoidance.c
@@ -1,5 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2011-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2011-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Simon Wunderlich 4 * Simon Wunderlich
5 * 5 *
diff --git a/net/batman-adv/bridge_loop_avoidance.h b/net/batman-adv/bridge_loop_avoidance.h
index b27571abcd2f..71f95a3e4d3f 100644
--- a/net/batman-adv/bridge_loop_avoidance.h
+++ b/net/batman-adv/bridge_loop_avoidance.h
@@ -1,5 +1,5 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (C) 2011-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2011-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Simon Wunderlich 4 * Simon Wunderlich
5 * 5 *
diff --git a/net/batman-adv/debugfs.c b/net/batman-adv/debugfs.c
index 21d1189957a7..4229b01ac7b5 100644
--- a/net/batman-adv/debugfs.c
+++ b/net/batman-adv/debugfs.c
@@ -1,5 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2010-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2010-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner 4 * Marek Lindner
5 * 5 *
diff --git a/net/batman-adv/debugfs.h b/net/batman-adv/debugfs.h
index 90a08d35c501..37b069698b04 100644
--- a/net/batman-adv/debugfs.h
+++ b/net/batman-adv/debugfs.h
@@ -1,5 +1,5 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (C) 2010-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2010-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner 4 * Marek Lindner
5 * 5 *
diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c
index 87cd962d28d5..a60bacf7120b 100644
--- a/net/batman-adv/distributed-arp-table.c
+++ b/net/batman-adv/distributed-arp-table.c
@@ -1,5 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2011-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2011-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Antonio Quartulli 4 * Antonio Quartulli
5 * 5 *
@@ -33,6 +33,7 @@
33#include <linux/kernel.h> 33#include <linux/kernel.h>
34#include <linux/kref.h> 34#include <linux/kref.h>
35#include <linux/list.h> 35#include <linux/list.h>
36#include <linux/netlink.h>
36#include <linux/rculist.h> 37#include <linux/rculist.h>
37#include <linux/rcupdate.h> 38#include <linux/rcupdate.h>
38#include <linux/seq_file.h> 39#include <linux/seq_file.h>
@@ -43,13 +44,19 @@
43#include <linux/string.h> 44#include <linux/string.h>
44#include <linux/workqueue.h> 45#include <linux/workqueue.h>
45#include <net/arp.h> 46#include <net/arp.h>
47#include <net/genetlink.h>
48#include <net/netlink.h>
49#include <net/sock.h>
50#include <uapi/linux/batman_adv.h>
46 51
47#include "bridge_loop_avoidance.h" 52#include "bridge_loop_avoidance.h"
48#include "hard-interface.h" 53#include "hard-interface.h"
49#include "hash.h" 54#include "hash.h"
50#include "log.h" 55#include "log.h"
56#include "netlink.h"
51#include "originator.h" 57#include "originator.h"
52#include "send.h" 58#include "send.h"
59#include "soft-interface.h"
53#include "translation-table.h" 60#include "translation-table.h"
54#include "tvlv.h" 61#include "tvlv.h"
55 62
@@ -495,7 +502,7 @@ static bool batadv_is_orig_node_eligible(struct batadv_dat_candidate *res,
495 * the one with the lowest address 502 * the one with the lowest address
496 */ 503 */
497 if (tmp_max == max && max_orig_node && 504 if (tmp_max == max && max_orig_node &&
498 batadv_compare_eth(candidate->orig, max_orig_node->orig) > 0) 505 batadv_compare_eth(candidate->orig, max_orig_node->orig))
499 goto out; 506 goto out;
500 507
501 ret = true; 508 ret = true;
@@ -852,6 +859,151 @@ out:
852#endif 859#endif
853 860
854/** 861/**
862 * batadv_dat_cache_dump_entry() - dump one entry of the DAT cache table to a
863 * netlink socket
864 * @msg: buffer for the message
865 * @portid: netlink port
866 * @seq: Sequence number of netlink message
867 * @dat_entry: entry to dump
868 *
869 * Return: 0 or error code.
870 */
871static int
872batadv_dat_cache_dump_entry(struct sk_buff *msg, u32 portid, u32 seq,
873 struct batadv_dat_entry *dat_entry)
874{
875 int msecs;
876 void *hdr;
877
878 hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family,
879 NLM_F_MULTI, BATADV_CMD_GET_DAT_CACHE);
880 if (!hdr)
881 return -ENOBUFS;
882
883 msecs = jiffies_to_msecs(jiffies - dat_entry->last_update);
884
885 if (nla_put_in_addr(msg, BATADV_ATTR_DAT_CACHE_IP4ADDRESS,
886 dat_entry->ip) ||
887 nla_put(msg, BATADV_ATTR_DAT_CACHE_HWADDRESS, ETH_ALEN,
888 dat_entry->mac_addr) ||
889 nla_put_u16(msg, BATADV_ATTR_DAT_CACHE_VID, dat_entry->vid) ||
890 nla_put_u32(msg, BATADV_ATTR_LAST_SEEN_MSECS, msecs)) {
891 genlmsg_cancel(msg, hdr);
892 return -EMSGSIZE;
893 }
894
895 genlmsg_end(msg, hdr);
896 return 0;
897}
898
899/**
900 * batadv_dat_cache_dump_bucket() - dump one bucket of the DAT cache table to
901 * a netlink socket
902 * @msg: buffer for the message
903 * @portid: netlink port
904 * @seq: Sequence number of netlink message
905 * @head: bucket to dump
906 * @idx_skip: How many entries to skip
907 *
908 * Return: 0 or error code.
909 */
910static int
911batadv_dat_cache_dump_bucket(struct sk_buff *msg, u32 portid, u32 seq,
912 struct hlist_head *head, int *idx_skip)
913{
914 struct batadv_dat_entry *dat_entry;
915 int idx = 0;
916
917 rcu_read_lock();
918 hlist_for_each_entry_rcu(dat_entry, head, hash_entry) {
919 if (idx < *idx_skip)
920 goto skip;
921
922 if (batadv_dat_cache_dump_entry(msg, portid, seq,
923 dat_entry)) {
924 rcu_read_unlock();
925 *idx_skip = idx;
926
927 return -EMSGSIZE;
928 }
929
930skip:
931 idx++;
932 }
933 rcu_read_unlock();
934
935 return 0;
936}
937
938/**
939 * batadv_dat_cache_dump() - dump DAT cache table to a netlink socket
940 * @msg: buffer for the message
941 * @cb: callback structure containing arguments
942 *
943 * Return: message length.
944 */
945int batadv_dat_cache_dump(struct sk_buff *msg, struct netlink_callback *cb)
946{
947 struct batadv_hard_iface *primary_if = NULL;
948 int portid = NETLINK_CB(cb->skb).portid;
949 struct net *net = sock_net(cb->skb->sk);
950 struct net_device *soft_iface;
951 struct batadv_hashtable *hash;
952 struct batadv_priv *bat_priv;
953 int bucket = cb->args[0];
954 struct hlist_head *head;
955 int idx = cb->args[1];
956 int ifindex;
957 int ret = 0;
958
959 ifindex = batadv_netlink_get_ifindex(cb->nlh,
960 BATADV_ATTR_MESH_IFINDEX);
961 if (!ifindex)
962 return -EINVAL;
963
964 soft_iface = dev_get_by_index(net, ifindex);
965 if (!soft_iface || !batadv_softif_is_valid(soft_iface)) {
966 ret = -ENODEV;
967 goto out;
968 }
969
970 bat_priv = netdev_priv(soft_iface);
971 hash = bat_priv->dat.hash;
972
973 primary_if = batadv_primary_if_get_selected(bat_priv);
974 if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) {
975 ret = -ENOENT;
976 goto out;
977 }
978
979 while (bucket < hash->size) {
980 head = &hash->table[bucket];
981
982 if (batadv_dat_cache_dump_bucket(msg, portid,
983 cb->nlh->nlmsg_seq, head,
984 &idx))
985 break;
986
987 bucket++;
988 idx = 0;
989 }
990
991 cb->args[0] = bucket;
992 cb->args[1] = idx;
993
994 ret = msg->len;
995
996out:
997 if (primary_if)
998 batadv_hardif_put(primary_if);
999
1000 if (soft_iface)
1001 dev_put(soft_iface);
1002
1003 return ret;
1004}
1005
1006/**
855 * batadv_arp_get_type() - parse an ARP packet and gets the type 1007 * batadv_arp_get_type() - parse an ARP packet and gets the type
856 * @bat_priv: the bat priv with all the soft interface information 1008 * @bat_priv: the bat priv with all the soft interface information
857 * @skb: packet to analyse 1009 * @skb: packet to analyse
diff --git a/net/batman-adv/distributed-arp-table.h b/net/batman-adv/distributed-arp-table.h
index 12897eb46268..a04596028337 100644
--- a/net/batman-adv/distributed-arp-table.h
+++ b/net/batman-adv/distributed-arp-table.h
@@ -1,5 +1,5 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (C) 2011-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2011-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Antonio Quartulli 4 * Antonio Quartulli
5 * 5 *
@@ -28,6 +28,7 @@
28 28
29#include "originator.h" 29#include "originator.h"
30 30
31struct netlink_callback;
31struct seq_file; 32struct seq_file;
32struct sk_buff; 33struct sk_buff;
33 34
@@ -81,6 +82,7 @@ batadv_dat_init_own_addr(struct batadv_priv *bat_priv,
81int batadv_dat_init(struct batadv_priv *bat_priv); 82int batadv_dat_init(struct batadv_priv *bat_priv);
82void batadv_dat_free(struct batadv_priv *bat_priv); 83void batadv_dat_free(struct batadv_priv *bat_priv);
83int batadv_dat_cache_seq_print_text(struct seq_file *seq, void *offset); 84int batadv_dat_cache_seq_print_text(struct seq_file *seq, void *offset);
85int batadv_dat_cache_dump(struct sk_buff *msg, struct netlink_callback *cb);
84 86
85/** 87/**
86 * batadv_dat_inc_counter() - increment the correct DAT packet counter 88 * batadv_dat_inc_counter() - increment the correct DAT packet counter
@@ -169,6 +171,12 @@ static inline void batadv_dat_free(struct batadv_priv *bat_priv)
169{ 171{
170} 172}
171 173
174static inline int
175batadv_dat_cache_dump(struct sk_buff *msg, struct netlink_callback *cb)
176{
177 return -EOPNOTSUPP;
178}
179
172static inline void batadv_dat_inc_counter(struct batadv_priv *bat_priv, 180static inline void batadv_dat_inc_counter(struct batadv_priv *bat_priv,
173 u8 subtype) 181 u8 subtype)
174{ 182{
diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c
index 5afe641ee4b0..0fddc17106bd 100644
--- a/net/batman-adv/fragmentation.c
+++ b/net/batman-adv/fragmentation.c
@@ -1,5 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2013-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2013-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Martin Hundebøll <martin@hundeboll.net> 4 * Martin Hundebøll <martin@hundeboll.net>
5 * 5 *
diff --git a/net/batman-adv/fragmentation.h b/net/batman-adv/fragmentation.h
index 138b22a1836a..944512e07782 100644
--- a/net/batman-adv/fragmentation.h
+++ b/net/batman-adv/fragmentation.h
@@ -1,5 +1,5 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (C) 2013-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2013-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Martin Hundebøll <martin@hundeboll.net> 4 * Martin Hundebøll <martin@hundeboll.net>
5 * 5 *
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c
index 37fe9a644f22..c294f6fd43e0 100644
--- a/net/batman-adv/gateway_client.c
+++ b/net/batman-adv/gateway_client.c
@@ -1,5 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2009-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner 4 * Marek Lindner
5 * 5 *
diff --git a/net/batman-adv/gateway_client.h b/net/batman-adv/gateway_client.h
index 981f58421a32..f0b86fcb2493 100644
--- a/net/batman-adv/gateway_client.h
+++ b/net/batman-adv/gateway_client.h
@@ -1,5 +1,5 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (C) 2009-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner 4 * Marek Lindner
5 * 5 *
diff --git a/net/batman-adv/gateway_common.c b/net/batman-adv/gateway_common.c
index b3e156af2256..936c107f3199 100644
--- a/net/batman-adv/gateway_common.c
+++ b/net/batman-adv/gateway_common.c
@@ -1,5 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2009-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner 4 * Marek Lindner
5 * 5 *
diff --git a/net/batman-adv/gateway_common.h b/net/batman-adv/gateway_common.h
index afebd9c7edf4..80afb2793687 100644
--- a/net/batman-adv/gateway_common.h
+++ b/net/batman-adv/gateway_common.h
@@ -1,5 +1,5 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (C) 2009-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner 4 * Marek Lindner
5 * 5 *
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index 68b54a39c51d..c405d15befd6 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -1,5 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2007-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner, Simon Wunderlich 4 * Marek Lindner, Simon Wunderlich
5 * 5 *
diff --git a/net/batman-adv/hard-interface.h b/net/batman-adv/hard-interface.h
index de5e9a374ece..d1c0f6189301 100644
--- a/net/batman-adv/hard-interface.h
+++ b/net/batman-adv/hard-interface.h
@@ -1,5 +1,5 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2007-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner, Simon Wunderlich 4 * Marek Lindner, Simon Wunderlich
5 * 5 *
diff --git a/net/batman-adv/hash.c b/net/batman-adv/hash.c
index 04d964358c98..7b49e4001778 100644
--- a/net/batman-adv/hash.c
+++ b/net/batman-adv/hash.c
@@ -1,5 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2006-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2006-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Simon Wunderlich, Marek Lindner 4 * Simon Wunderlich, Marek Lindner
5 * 5 *
diff --git a/net/batman-adv/hash.h b/net/batman-adv/hash.h
index 4ce1b6d3ad5c..9490a7ca2ba6 100644
--- a/net/batman-adv/hash.h
+++ b/net/batman-adv/hash.h
@@ -1,5 +1,5 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (C) 2006-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2006-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Simon Wunderlich, Marek Lindner 4 * Simon Wunderlich, Marek Lindner
5 * 5 *
diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c
index 5daa3d50da17..55c358ad3331 100644
--- a/net/batman-adv/icmp_socket.c
+++ b/net/batman-adv/icmp_socket.c
@@ -1,5 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2007-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner 4 * Marek Lindner
5 * 5 *
diff --git a/net/batman-adv/icmp_socket.h b/net/batman-adv/icmp_socket.h
index 84cddd01eeab..958be22beda9 100644
--- a/net/batman-adv/icmp_socket.h
+++ b/net/batman-adv/icmp_socket.h
@@ -1,5 +1,5 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2007-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner 4 * Marek Lindner
5 * 5 *
diff --git a/net/batman-adv/log.c b/net/batman-adv/log.c
index cdbe0e5e208b..853773e45f79 100644
--- a/net/batman-adv/log.c
+++ b/net/batman-adv/log.c
@@ -1,5 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2010-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2010-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner 4 * Marek Lindner
5 * 5 *
diff --git a/net/batman-adv/log.h b/net/batman-adv/log.h
index 35e02b2b9e72..35f4f397ed57 100644
--- a/net/batman-adv/log.h
+++ b/net/batman-adv/log.h
@@ -1,5 +1,5 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2007-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner, Simon Wunderlich 4 * Marek Lindner, Simon Wunderlich
5 * 5 *
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index d31c8266e244..69c0d85bceb3 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -1,5 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2007-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner, Simon Wunderlich 4 * Marek Lindner, Simon Wunderlich
5 * 5 *
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h
index f7ba3f96d8f3..057a28a9fe88 100644
--- a/net/batman-adv/main.h
+++ b/net/batman-adv/main.h
@@ -1,5 +1,5 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2007-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner, Simon Wunderlich 4 * Marek Lindner, Simon Wunderlich
5 * 5 *
@@ -25,7 +25,7 @@
25#define BATADV_DRIVER_DEVICE "batman-adv" 25#define BATADV_DRIVER_DEVICE "batman-adv"
26 26
27#ifndef BATADV_SOURCE_VERSION 27#ifndef BATADV_SOURCE_VERSION
28#define BATADV_SOURCE_VERSION "2018.0" 28#define BATADV_SOURCE_VERSION "2018.1"
29#endif 29#endif
30 30
31/* B.A.T.M.A.N. parameters */ 31/* B.A.T.M.A.N. parameters */
@@ -331,11 +331,13 @@ static inline bool batadv_has_timed_out(unsigned long timestamp,
331 * 331 *
332 * Return: true when x is a predecessor of y, false otherwise 332 * Return: true when x is a predecessor of y, false otherwise
333 */ 333 */
334#define batadv_seq_before(x, y) ({typeof(x)_d1 = (x); \ 334#define batadv_seq_before(x, y) ({ \
335 typeof(y)_d2 = (y); \ 335 typeof(x)_d1 = (x); \
336 typeof(x)_dummy = (_d1 - _d2); \ 336 typeof(y)_d2 = (y); \
337 (void)(&_d1 == &_d2); \ 337 typeof(x)_dummy = (_d1 - _d2); \
338 _dummy > batadv_smallest_signed_int(_dummy); }) 338 (void)(&_d1 == &_d2); \
339 _dummy > batadv_smallest_signed_int(_dummy); \
340})
339 341
340/** 342/**
341 * batadv_seq_after() - Checks if a sequence number x is a successor of y 343 * batadv_seq_after() - Checks if a sequence number x is a successor of y
diff --git a/net/batman-adv/multicast.c b/net/batman-adv/multicast.c
index d70640135e3a..de3a055f7dd8 100644
--- a/net/batman-adv/multicast.c
+++ b/net/batman-adv/multicast.c
@@ -1,5 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2014-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2014-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Linus Lüssing 4 * Linus Lüssing
5 * 5 *
@@ -40,6 +40,7 @@
40#include <linux/list.h> 40#include <linux/list.h>
41#include <linux/lockdep.h> 41#include <linux/lockdep.h>
42#include <linux/netdevice.h> 42#include <linux/netdevice.h>
43#include <linux/netlink.h>
43#include <linux/printk.h> 44#include <linux/printk.h>
44#include <linux/rculist.h> 45#include <linux/rculist.h>
45#include <linux/rcupdate.h> 46#include <linux/rcupdate.h>
@@ -52,14 +53,20 @@
52#include <linux/types.h> 53#include <linux/types.h>
53#include <linux/workqueue.h> 54#include <linux/workqueue.h>
54#include <net/addrconf.h> 55#include <net/addrconf.h>
56#include <net/genetlink.h>
55#include <net/if_inet6.h> 57#include <net/if_inet6.h>
56#include <net/ip.h> 58#include <net/ip.h>
57#include <net/ipv6.h> 59#include <net/ipv6.h>
60#include <net/netlink.h>
61#include <net/sock.h>
58#include <uapi/linux/batadv_packet.h> 62#include <uapi/linux/batadv_packet.h>
63#include <uapi/linux/batman_adv.h>
59 64
60#include "hard-interface.h" 65#include "hard-interface.h"
61#include "hash.h" 66#include "hash.h"
62#include "log.h" 67#include "log.h"
68#include "netlink.h"
69#include "soft-interface.h"
63#include "translation-table.h" 70#include "translation-table.h"
64#include "tvlv.h" 71#include "tvlv.h"
65 72
@@ -102,7 +109,36 @@ static struct net_device *batadv_mcast_get_bridge(struct net_device *soft_iface)
102} 109}
103 110
104/** 111/**
112 * batadv_mcast_addr_is_ipv4() - check if multicast MAC is IPv4
113 * @addr: the MAC address to check
114 *
115 * Return: True, if MAC address is one reserved for IPv4 multicast, false
116 * otherwise.
117 */
118static bool batadv_mcast_addr_is_ipv4(const u8 *addr)
119{
120 static const u8 prefix[] = {0x01, 0x00, 0x5E};
121
122 return memcmp(prefix, addr, sizeof(prefix)) == 0;
123}
124
125/**
126 * batadv_mcast_addr_is_ipv6() - check if multicast MAC is IPv6
127 * @addr: the MAC address to check
128 *
129 * Return: True, if MAC address is one reserved for IPv6 multicast, false
130 * otherwise.
131 */
132static bool batadv_mcast_addr_is_ipv6(const u8 *addr)
133{
134 static const u8 prefix[] = {0x33, 0x33};
135
136 return memcmp(prefix, addr, sizeof(prefix)) == 0;
137}
138
139/**
105 * batadv_mcast_mla_softif_get() - get softif multicast listeners 140 * batadv_mcast_mla_softif_get() - get softif multicast listeners
141 * @bat_priv: the bat priv with all the soft interface information
106 * @dev: the device to collect multicast addresses from 142 * @dev: the device to collect multicast addresses from
107 * @mcast_list: a list to put found addresses into 143 * @mcast_list: a list to put found addresses into
108 * 144 *
@@ -119,9 +155,12 @@ static struct net_device *batadv_mcast_get_bridge(struct net_device *soft_iface)
119 * Return: -ENOMEM on memory allocation error or the number of 155 * Return: -ENOMEM on memory allocation error or the number of
120 * items added to the mcast_list otherwise. 156 * items added to the mcast_list otherwise.
121 */ 157 */
122static int batadv_mcast_mla_softif_get(struct net_device *dev, 158static int batadv_mcast_mla_softif_get(struct batadv_priv *bat_priv,
159 struct net_device *dev,
123 struct hlist_head *mcast_list) 160 struct hlist_head *mcast_list)
124{ 161{
162 bool all_ipv4 = bat_priv->mcast.flags & BATADV_MCAST_WANT_ALL_IPV4;
163 bool all_ipv6 = bat_priv->mcast.flags & BATADV_MCAST_WANT_ALL_IPV6;
125 struct net_device *bridge = batadv_mcast_get_bridge(dev); 164 struct net_device *bridge = batadv_mcast_get_bridge(dev);
126 struct netdev_hw_addr *mc_list_entry; 165 struct netdev_hw_addr *mc_list_entry;
127 struct batadv_hw_addr *new; 166 struct batadv_hw_addr *new;
@@ -129,6 +168,12 @@ static int batadv_mcast_mla_softif_get(struct net_device *dev,
129 168
130 netif_addr_lock_bh(bridge ? bridge : dev); 169 netif_addr_lock_bh(bridge ? bridge : dev);
131 netdev_for_each_mc_addr(mc_list_entry, bridge ? bridge : dev) { 170 netdev_for_each_mc_addr(mc_list_entry, bridge ? bridge : dev) {
171 if (all_ipv4 && batadv_mcast_addr_is_ipv4(mc_list_entry->addr))
172 continue;
173
174 if (all_ipv6 && batadv_mcast_addr_is_ipv6(mc_list_entry->addr))
175 continue;
176
132 new = kmalloc(sizeof(*new), GFP_ATOMIC); 177 new = kmalloc(sizeof(*new), GFP_ATOMIC);
133 if (!new) { 178 if (!new) {
134 ret = -ENOMEM; 179 ret = -ENOMEM;
@@ -193,6 +238,7 @@ static void batadv_mcast_mla_br_addr_cpy(char *dst, const struct br_ip *src)
193 238
194/** 239/**
195 * batadv_mcast_mla_bridge_get() - get bridged-in multicast listeners 240 * batadv_mcast_mla_bridge_get() - get bridged-in multicast listeners
241 * @bat_priv: the bat priv with all the soft interface information
196 * @dev: a bridge slave whose bridge to collect multicast addresses from 242 * @dev: a bridge slave whose bridge to collect multicast addresses from
197 * @mcast_list: a list to put found addresses into 243 * @mcast_list: a list to put found addresses into
198 * 244 *
@@ -204,10 +250,13 @@ static void batadv_mcast_mla_br_addr_cpy(char *dst, const struct br_ip *src)
204 * Return: -ENOMEM on memory allocation error or the number of 250 * Return: -ENOMEM on memory allocation error or the number of
205 * items added to the mcast_list otherwise. 251 * items added to the mcast_list otherwise.
206 */ 252 */
207static int batadv_mcast_mla_bridge_get(struct net_device *dev, 253static int batadv_mcast_mla_bridge_get(struct batadv_priv *bat_priv,
254 struct net_device *dev,
208 struct hlist_head *mcast_list) 255 struct hlist_head *mcast_list)
209{ 256{
210 struct list_head bridge_mcast_list = LIST_HEAD_INIT(bridge_mcast_list); 257 struct list_head bridge_mcast_list = LIST_HEAD_INIT(bridge_mcast_list);
258 bool all_ipv4 = bat_priv->mcast.flags & BATADV_MCAST_WANT_ALL_IPV4;
259 bool all_ipv6 = bat_priv->mcast.flags & BATADV_MCAST_WANT_ALL_IPV6;
211 struct br_ip_list *br_ip_entry, *tmp; 260 struct br_ip_list *br_ip_entry, *tmp;
212 struct batadv_hw_addr *new; 261 struct batadv_hw_addr *new;
213 u8 mcast_addr[ETH_ALEN]; 262 u8 mcast_addr[ETH_ALEN];
@@ -221,6 +270,12 @@ static int batadv_mcast_mla_bridge_get(struct net_device *dev,
221 goto out; 270 goto out;
222 271
223 list_for_each_entry(br_ip_entry, &bridge_mcast_list, list) { 272 list_for_each_entry(br_ip_entry, &bridge_mcast_list, list) {
273 if (all_ipv4 && br_ip_entry->addr.proto == htons(ETH_P_IP))
274 continue;
275
276 if (all_ipv6 && br_ip_entry->addr.proto == htons(ETH_P_IPV6))
277 continue;
278
224 batadv_mcast_mla_br_addr_cpy(mcast_addr, &br_ip_entry->addr); 279 batadv_mcast_mla_br_addr_cpy(mcast_addr, &br_ip_entry->addr);
225 if (batadv_mcast_mla_is_duplicate(mcast_addr, mcast_list)) 280 if (batadv_mcast_mla_is_duplicate(mcast_addr, mcast_list))
226 continue; 281 continue;
@@ -568,11 +623,11 @@ static void __batadv_mcast_mla_update(struct batadv_priv *bat_priv)
568 if (!batadv_mcast_mla_tvlv_update(bat_priv)) 623 if (!batadv_mcast_mla_tvlv_update(bat_priv))
569 goto update; 624 goto update;
570 625
571 ret = batadv_mcast_mla_softif_get(soft_iface, &mcast_list); 626 ret = batadv_mcast_mla_softif_get(bat_priv, soft_iface, &mcast_list);
572 if (ret < 0) 627 if (ret < 0)
573 goto out; 628 goto out;
574 629
575 ret = batadv_mcast_mla_bridge_get(soft_iface, &mcast_list); 630 ret = batadv_mcast_mla_bridge_get(bat_priv, soft_iface, &mcast_list);
576 if (ret < 0) 631 if (ret < 0)
577 goto out; 632 goto out;
578 633
@@ -1286,6 +1341,236 @@ int batadv_mcast_flags_seq_print_text(struct seq_file *seq, void *offset)
1286#endif 1341#endif
1287 1342
1288/** 1343/**
1344 * batadv_mcast_mesh_info_put() - put multicast info into a netlink message
1345 * @msg: buffer for the message
1346 * @bat_priv: the bat priv with all the soft interface information
1347 *
1348 * Return: 0 or error code.
1349 */
1350int batadv_mcast_mesh_info_put(struct sk_buff *msg,
1351 struct batadv_priv *bat_priv)
1352{
1353 u32 flags = bat_priv->mcast.flags;
1354 u32 flags_priv = BATADV_NO_FLAGS;
1355
1356 if (bat_priv->mcast.bridged) {
1357 flags_priv |= BATADV_MCAST_FLAGS_BRIDGED;
1358
1359 if (bat_priv->mcast.querier_ipv4.exists)
1360 flags_priv |= BATADV_MCAST_FLAGS_QUERIER_IPV4_EXISTS;
1361 if (bat_priv->mcast.querier_ipv6.exists)
1362 flags_priv |= BATADV_MCAST_FLAGS_QUERIER_IPV6_EXISTS;
1363 if (bat_priv->mcast.querier_ipv4.shadowing)
1364 flags_priv |= BATADV_MCAST_FLAGS_QUERIER_IPV4_SHADOWING;
1365 if (bat_priv->mcast.querier_ipv6.shadowing)
1366 flags_priv |= BATADV_MCAST_FLAGS_QUERIER_IPV6_SHADOWING;
1367 }
1368
1369 if (nla_put_u32(msg, BATADV_ATTR_MCAST_FLAGS, flags) ||
1370 nla_put_u32(msg, BATADV_ATTR_MCAST_FLAGS_PRIV, flags_priv))
1371 return -EMSGSIZE;
1372
1373 return 0;
1374}
1375
1376/**
1377 * batadv_mcast_flags_dump_entry() - dump one entry of the multicast flags table
1378 * to a netlink socket
1379 * @msg: buffer for the message
1380 * @portid: netlink port
1381 * @seq: Sequence number of netlink message
1382 * @orig_node: originator to dump the multicast flags of
1383 *
1384 * Return: 0 or error code.
1385 */
1386static int
1387batadv_mcast_flags_dump_entry(struct sk_buff *msg, u32 portid, u32 seq,
1388 struct batadv_orig_node *orig_node)
1389{
1390 void *hdr;
1391
1392 hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family,
1393 NLM_F_MULTI, BATADV_CMD_GET_MCAST_FLAGS);
1394 if (!hdr)
1395 return -ENOBUFS;
1396
1397 if (nla_put(msg, BATADV_ATTR_ORIG_ADDRESS, ETH_ALEN,
1398 orig_node->orig)) {
1399 genlmsg_cancel(msg, hdr);
1400 return -EMSGSIZE;
1401 }
1402
1403 if (test_bit(BATADV_ORIG_CAPA_HAS_MCAST,
1404 &orig_node->capabilities)) {
1405 if (nla_put_u32(msg, BATADV_ATTR_MCAST_FLAGS,
1406 orig_node->mcast_flags)) {
1407 genlmsg_cancel(msg, hdr);
1408 return -EMSGSIZE;
1409 }
1410 }
1411
1412 genlmsg_end(msg, hdr);
1413 return 0;
1414}
1415
1416/**
1417 * batadv_mcast_flags_dump_bucket() - dump one bucket of the multicast flags
1418 * table to a netlink socket
1419 * @msg: buffer for the message
1420 * @portid: netlink port
1421 * @seq: Sequence number of netlink message
1422 * @head: bucket to dump
1423 * @idx_skip: How many entries to skip
1424 *
1425 * Return: 0 or error code.
1426 */
1427static int
1428batadv_mcast_flags_dump_bucket(struct sk_buff *msg, u32 portid, u32 seq,
1429 struct hlist_head *head, long *idx_skip)
1430{
1431 struct batadv_orig_node *orig_node;
1432 long idx = 0;
1433
1434 rcu_read_lock();
1435 hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
1436 if (!test_bit(BATADV_ORIG_CAPA_HAS_MCAST,
1437 &orig_node->capa_initialized))
1438 continue;
1439
1440 if (idx < *idx_skip)
1441 goto skip;
1442
1443 if (batadv_mcast_flags_dump_entry(msg, portid, seq,
1444 orig_node)) {
1445 rcu_read_unlock();
1446 *idx_skip = idx;
1447
1448 return -EMSGSIZE;
1449 }
1450
1451skip:
1452 idx++;
1453 }
1454 rcu_read_unlock();
1455
1456 return 0;
1457}
1458
1459/**
1460 * __batadv_mcast_flags_dump() - dump multicast flags table to a netlink socket
1461 * @msg: buffer for the message
1462 * @portid: netlink port
1463 * @seq: Sequence number of netlink message
1464 * @bat_priv: the bat priv with all the soft interface information
1465 * @bucket: current bucket to dump
1466 * @idx: index in current bucket to the next entry to dump
1467 *
1468 * Return: 0 or error code.
1469 */
1470static int
1471__batadv_mcast_flags_dump(struct sk_buff *msg, u32 portid, u32 seq,
1472 struct batadv_priv *bat_priv, long *bucket, long *idx)
1473{
1474 struct batadv_hashtable *hash = bat_priv->orig_hash;
1475 long bucket_tmp = *bucket;
1476 struct hlist_head *head;
1477 long idx_tmp = *idx;
1478
1479 while (bucket_tmp < hash->size) {
1480 head = &hash->table[bucket_tmp];
1481
1482 if (batadv_mcast_flags_dump_bucket(msg, portid, seq, head,
1483 &idx_tmp))
1484 break;
1485
1486 bucket_tmp++;
1487 idx_tmp = 0;
1488 }
1489
1490 *bucket = bucket_tmp;
1491 *idx = idx_tmp;
1492
1493 return msg->len;
1494}
1495
1496/**
1497 * batadv_mcast_netlink_get_primary() - get primary interface from netlink
1498 * callback
1499 * @cb: netlink callback structure
1500 * @primary_if: the primary interface pointer to return the result in
1501 *
1502 * Return: 0 or error code.
1503 */
1504static int
1505batadv_mcast_netlink_get_primary(struct netlink_callback *cb,
1506 struct batadv_hard_iface **primary_if)
1507{
1508 struct batadv_hard_iface *hard_iface = NULL;
1509 struct net *net = sock_net(cb->skb->sk);
1510 struct net_device *soft_iface;
1511 struct batadv_priv *bat_priv;
1512 int ifindex;
1513 int ret = 0;
1514
1515 ifindex = batadv_netlink_get_ifindex(cb->nlh, BATADV_ATTR_MESH_IFINDEX);
1516 if (!ifindex)
1517 return -EINVAL;
1518
1519 soft_iface = dev_get_by_index(net, ifindex);
1520 if (!soft_iface || !batadv_softif_is_valid(soft_iface)) {
1521 ret = -ENODEV;
1522 goto out;
1523 }
1524
1525 bat_priv = netdev_priv(soft_iface);
1526
1527 hard_iface = batadv_primary_if_get_selected(bat_priv);
1528 if (!hard_iface || hard_iface->if_status != BATADV_IF_ACTIVE) {
1529 ret = -ENOENT;
1530 goto out;
1531 }
1532
1533out:
1534 if (soft_iface)
1535 dev_put(soft_iface);
1536
1537 if (!ret && primary_if)
1538 *primary_if = hard_iface;
1539 else
1540 batadv_hardif_put(hard_iface);
1541
1542 return ret;
1543}
1544
1545/**
1546 * batadv_mcast_flags_dump() - dump multicast flags table to a netlink socket
1547 * @msg: buffer for the message
1548 * @cb: callback structure containing arguments
1549 *
1550 * Return: message length.
1551 */
1552int batadv_mcast_flags_dump(struct sk_buff *msg, struct netlink_callback *cb)
1553{
1554 struct batadv_hard_iface *primary_if = NULL;
1555 int portid = NETLINK_CB(cb->skb).portid;
1556 struct batadv_priv *bat_priv;
1557 long *bucket = &cb->args[0];
1558 long *idx = &cb->args[1];
1559 int ret;
1560
1561 ret = batadv_mcast_netlink_get_primary(cb, &primary_if);
1562 if (ret)
1563 return ret;
1564
1565 bat_priv = netdev_priv(primary_if->soft_iface);
1566 ret = __batadv_mcast_flags_dump(msg, portid, cb->nlh->nlmsg_seq,
1567 bat_priv, bucket, idx);
1568
1569 batadv_hardif_put(primary_if);
1570 return ret;
1571}
1572
1573/**
1289 * batadv_mcast_free() - free the multicast optimizations structures 1574 * batadv_mcast_free() - free the multicast optimizations structures
1290 * @bat_priv: the bat priv with all the soft interface information 1575 * @bat_priv: the bat priv with all the soft interface information
1291 */ 1576 */
diff --git a/net/batman-adv/multicast.h b/net/batman-adv/multicast.h
index 3ac06337ab71..3b04ab13f0eb 100644
--- a/net/batman-adv/multicast.h
+++ b/net/batman-adv/multicast.h
@@ -1,5 +1,5 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (C) 2014-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2014-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Linus Lüssing 4 * Linus Lüssing
5 * 5 *
@@ -21,6 +21,7 @@
21 21
22#include "main.h" 22#include "main.h"
23 23
24struct netlink_callback;
24struct seq_file; 25struct seq_file;
25struct sk_buff; 26struct sk_buff;
26 27
@@ -54,6 +55,11 @@ void batadv_mcast_init(struct batadv_priv *bat_priv);
54 55
55int batadv_mcast_flags_seq_print_text(struct seq_file *seq, void *offset); 56int batadv_mcast_flags_seq_print_text(struct seq_file *seq, void *offset);
56 57
58int batadv_mcast_mesh_info_put(struct sk_buff *msg,
59 struct batadv_priv *bat_priv);
60
61int batadv_mcast_flags_dump(struct sk_buff *msg, struct netlink_callback *cb);
62
57void batadv_mcast_free(struct batadv_priv *bat_priv); 63void batadv_mcast_free(struct batadv_priv *bat_priv);
58 64
59void batadv_mcast_purge_orig(struct batadv_orig_node *orig_node); 65void batadv_mcast_purge_orig(struct batadv_orig_node *orig_node);
@@ -72,6 +78,18 @@ static inline int batadv_mcast_init(struct batadv_priv *bat_priv)
72 return 0; 78 return 0;
73} 79}
74 80
81static inline int
82batadv_mcast_mesh_info_put(struct sk_buff *msg, struct batadv_priv *bat_priv)
83{
84 return 0;
85}
86
87static inline int batadv_mcast_flags_dump(struct sk_buff *msg,
88 struct netlink_callback *cb)
89{
90 return -EOPNOTSUPP;
91}
92
75static inline void batadv_mcast_free(struct batadv_priv *bat_priv) 93static inline void batadv_mcast_free(struct batadv_priv *bat_priv)
76{ 94{
77} 95}
diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c
index a823d3899bad..0d9459b69bdb 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -1,5 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2016-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2016-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Matthias Schiffer 4 * Matthias Schiffer
5 * 5 *
@@ -45,8 +45,10 @@
45 45
46#include "bat_algo.h" 46#include "bat_algo.h"
47#include "bridge_loop_avoidance.h" 47#include "bridge_loop_avoidance.h"
48#include "distributed-arp-table.h"
48#include "gateway_client.h" 49#include "gateway_client.h"
49#include "hard-interface.h" 50#include "hard-interface.h"
51#include "multicast.h"
50#include "originator.h" 52#include "originator.h"
51#include "soft-interface.h" 53#include "soft-interface.h"
52#include "tp_meter.h" 54#include "tp_meter.h"
@@ -64,39 +66,44 @@ static const struct genl_multicast_group batadv_netlink_mcgrps[] = {
64}; 66};
65 67
66static const struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = { 68static const struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = {
67 [BATADV_ATTR_VERSION] = { .type = NLA_STRING }, 69 [BATADV_ATTR_VERSION] = { .type = NLA_STRING },
68 [BATADV_ATTR_ALGO_NAME] = { .type = NLA_STRING }, 70 [BATADV_ATTR_ALGO_NAME] = { .type = NLA_STRING },
69 [BATADV_ATTR_MESH_IFINDEX] = { .type = NLA_U32 }, 71 [BATADV_ATTR_MESH_IFINDEX] = { .type = NLA_U32 },
70 [BATADV_ATTR_MESH_IFNAME] = { .type = NLA_STRING }, 72 [BATADV_ATTR_MESH_IFNAME] = { .type = NLA_STRING },
71 [BATADV_ATTR_MESH_ADDRESS] = { .len = ETH_ALEN }, 73 [BATADV_ATTR_MESH_ADDRESS] = { .len = ETH_ALEN },
72 [BATADV_ATTR_HARD_IFINDEX] = { .type = NLA_U32 }, 74 [BATADV_ATTR_HARD_IFINDEX] = { .type = NLA_U32 },
73 [BATADV_ATTR_HARD_IFNAME] = { .type = NLA_STRING }, 75 [BATADV_ATTR_HARD_IFNAME] = { .type = NLA_STRING },
74 [BATADV_ATTR_HARD_ADDRESS] = { .len = ETH_ALEN }, 76 [BATADV_ATTR_HARD_ADDRESS] = { .len = ETH_ALEN },
75 [BATADV_ATTR_ORIG_ADDRESS] = { .len = ETH_ALEN }, 77 [BATADV_ATTR_ORIG_ADDRESS] = { .len = ETH_ALEN },
76 [BATADV_ATTR_TPMETER_RESULT] = { .type = NLA_U8 }, 78 [BATADV_ATTR_TPMETER_RESULT] = { .type = NLA_U8 },
77 [BATADV_ATTR_TPMETER_TEST_TIME] = { .type = NLA_U32 }, 79 [BATADV_ATTR_TPMETER_TEST_TIME] = { .type = NLA_U32 },
78 [BATADV_ATTR_TPMETER_BYTES] = { .type = NLA_U64 }, 80 [BATADV_ATTR_TPMETER_BYTES] = { .type = NLA_U64 },
79 [BATADV_ATTR_TPMETER_COOKIE] = { .type = NLA_U32 }, 81 [BATADV_ATTR_TPMETER_COOKIE] = { .type = NLA_U32 },
80 [BATADV_ATTR_ACTIVE] = { .type = NLA_FLAG }, 82 [BATADV_ATTR_ACTIVE] = { .type = NLA_FLAG },
81 [BATADV_ATTR_TT_ADDRESS] = { .len = ETH_ALEN }, 83 [BATADV_ATTR_TT_ADDRESS] = { .len = ETH_ALEN },
82 [BATADV_ATTR_TT_TTVN] = { .type = NLA_U8 }, 84 [BATADV_ATTR_TT_TTVN] = { .type = NLA_U8 },
83 [BATADV_ATTR_TT_LAST_TTVN] = { .type = NLA_U8 }, 85 [BATADV_ATTR_TT_LAST_TTVN] = { .type = NLA_U8 },
84 [BATADV_ATTR_TT_CRC32] = { .type = NLA_U32 }, 86 [BATADV_ATTR_TT_CRC32] = { .type = NLA_U32 },
85 [BATADV_ATTR_TT_VID] = { .type = NLA_U16 }, 87 [BATADV_ATTR_TT_VID] = { .type = NLA_U16 },
86 [BATADV_ATTR_TT_FLAGS] = { .type = NLA_U32 }, 88 [BATADV_ATTR_TT_FLAGS] = { .type = NLA_U32 },
87 [BATADV_ATTR_FLAG_BEST] = { .type = NLA_FLAG }, 89 [BATADV_ATTR_FLAG_BEST] = { .type = NLA_FLAG },
88 [BATADV_ATTR_LAST_SEEN_MSECS] = { .type = NLA_U32 }, 90 [BATADV_ATTR_LAST_SEEN_MSECS] = { .type = NLA_U32 },
89 [BATADV_ATTR_NEIGH_ADDRESS] = { .len = ETH_ALEN }, 91 [BATADV_ATTR_NEIGH_ADDRESS] = { .len = ETH_ALEN },
90 [BATADV_ATTR_TQ] = { .type = NLA_U8 }, 92 [BATADV_ATTR_TQ] = { .type = NLA_U8 },
91 [BATADV_ATTR_THROUGHPUT] = { .type = NLA_U32 }, 93 [BATADV_ATTR_THROUGHPUT] = { .type = NLA_U32 },
92 [BATADV_ATTR_BANDWIDTH_UP] = { .type = NLA_U32 }, 94 [BATADV_ATTR_BANDWIDTH_UP] = { .type = NLA_U32 },
93 [BATADV_ATTR_BANDWIDTH_DOWN] = { .type = NLA_U32 }, 95 [BATADV_ATTR_BANDWIDTH_DOWN] = { .type = NLA_U32 },
94 [BATADV_ATTR_ROUTER] = { .len = ETH_ALEN }, 96 [BATADV_ATTR_ROUTER] = { .len = ETH_ALEN },
95 [BATADV_ATTR_BLA_OWN] = { .type = NLA_FLAG }, 97 [BATADV_ATTR_BLA_OWN] = { .type = NLA_FLAG },
96 [BATADV_ATTR_BLA_ADDRESS] = { .len = ETH_ALEN }, 98 [BATADV_ATTR_BLA_ADDRESS] = { .len = ETH_ALEN },
97 [BATADV_ATTR_BLA_VID] = { .type = NLA_U16 }, 99 [BATADV_ATTR_BLA_VID] = { .type = NLA_U16 },
98 [BATADV_ATTR_BLA_BACKBONE] = { .len = ETH_ALEN }, 100 [BATADV_ATTR_BLA_BACKBONE] = { .len = ETH_ALEN },
99 [BATADV_ATTR_BLA_CRC] = { .type = NLA_U16 }, 101 [BATADV_ATTR_BLA_CRC] = { .type = NLA_U16 },
102 [BATADV_ATTR_DAT_CACHE_IP4ADDRESS] = { .type = NLA_U32 },
103 [BATADV_ATTR_DAT_CACHE_HWADDRESS] = { .len = ETH_ALEN },
104 [BATADV_ATTR_DAT_CACHE_VID] = { .type = NLA_U16 },
105 [BATADV_ATTR_MCAST_FLAGS] = { .type = NLA_U32 },
106 [BATADV_ATTR_MCAST_FLAGS_PRIV] = { .type = NLA_U32 },
100}; 107};
101 108
102/** 109/**
@@ -147,6 +154,9 @@ batadv_netlink_mesh_info_put(struct sk_buff *msg, struct net_device *soft_iface)
147 goto out; 154 goto out;
148#endif 155#endif
149 156
157 if (batadv_mcast_mesh_info_put(msg, bat_priv))
158 goto out;
159
150 primary_if = batadv_primary_if_get_selected(bat_priv); 160 primary_if = batadv_primary_if_get_selected(bat_priv);
151 if (primary_if && primary_if->if_status == BATADV_IF_ACTIVE) { 161 if (primary_if && primary_if->if_status == BATADV_IF_ACTIVE) {
152 hard_iface = primary_if->net_dev; 162 hard_iface = primary_if->net_dev;
@@ -604,6 +614,18 @@ static const struct genl_ops batadv_netlink_ops[] = {
604 .policy = batadv_netlink_policy, 614 .policy = batadv_netlink_policy,
605 .dumpit = batadv_bla_backbone_dump, 615 .dumpit = batadv_bla_backbone_dump,
606 }, 616 },
617 {
618 .cmd = BATADV_CMD_GET_DAT_CACHE,
619 .flags = GENL_ADMIN_PERM,
620 .policy = batadv_netlink_policy,
621 .dumpit = batadv_dat_cache_dump,
622 },
623 {
624 .cmd = BATADV_CMD_GET_MCAST_FLAGS,
625 .flags = GENL_ADMIN_PERM,
626 .policy = batadv_netlink_policy,
627 .dumpit = batadv_mcast_flags_dump,
628 },
607 629
608}; 630};
609 631
diff --git a/net/batman-adv/netlink.h b/net/batman-adv/netlink.h
index 0e7e57b69b54..571d9a5ae7aa 100644
--- a/net/batman-adv/netlink.h
+++ b/net/batman-adv/netlink.h
@@ -1,5 +1,5 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (C) 2016-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2016-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Matthias Schiffer 4 * Matthias Schiffer
5 * 5 *
diff --git a/net/batman-adv/network-coding.c b/net/batman-adv/network-coding.c
index b48116bb24ef..c3578444f3cb 100644
--- a/net/batman-adv/network-coding.c
+++ b/net/batman-adv/network-coding.c
@@ -1,5 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2012-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2012-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Martin Hundebøll, Jeppe Ledet-Pedersen 4 * Martin Hundebøll, Jeppe Ledet-Pedersen
5 * 5 *
diff --git a/net/batman-adv/network-coding.h b/net/batman-adv/network-coding.h
index adaeafa4f71e..65c346812bc1 100644
--- a/net/batman-adv/network-coding.h
+++ b/net/batman-adv/network-coding.h
@@ -1,5 +1,5 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (C) 2012-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2012-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Martin Hundebøll, Jeppe Ledet-Pedersen 4 * Martin Hundebøll, Jeppe Ledet-Pedersen
5 * 5 *
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index 74782426bb77..716e5b43acfa 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -1,5 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2009-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner, Simon Wunderlich 4 * Marek Lindner, Simon Wunderlich
5 * 5 *
diff --git a/net/batman-adv/originator.h b/net/batman-adv/originator.h
index 15d896b2de6f..3b3f59b881e1 100644
--- a/net/batman-adv/originator.h
+++ b/net/batman-adv/originator.h
@@ -1,5 +1,5 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2007-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner, Simon Wunderlich 4 * Marek Lindner, Simon Wunderlich
5 * 5 *
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index e61dc1293bb5..cc3ed93a6d51 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -1,5 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2007-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner, Simon Wunderlich 4 * Marek Lindner, Simon Wunderlich
5 * 5 *
diff --git a/net/batman-adv/routing.h b/net/batman-adv/routing.h
index a1289bc5f115..db54c2d9b8bf 100644
--- a/net/batman-adv/routing.h
+++ b/net/batman-adv/routing.h
@@ -1,5 +1,5 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2007-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner, Simon Wunderlich 4 * Marek Lindner, Simon Wunderlich
5 * 5 *
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c
index 2a5ab6f1076d..4a35f5c2f52b 100644
--- a/net/batman-adv/send.c
+++ b/net/batman-adv/send.c
@@ -1,5 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2007-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner, Simon Wunderlich 4 * Marek Lindner, Simon Wunderlich
5 * 5 *
diff --git a/net/batman-adv/send.h b/net/batman-adv/send.h
index 1e8c79093623..64cce07b8fe6 100644
--- a/net/batman-adv/send.h
+++ b/net/batman-adv/send.h
@@ -1,5 +1,5 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2007-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner, Simon Wunderlich 4 * Marek Lindner, Simon Wunderlich
5 * 5 *
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index 367a81fb785f..edeffcb9f3a2 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -1,5 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2007-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner, Simon Wunderlich 4 * Marek Lindner, Simon Wunderlich
5 * 5 *
diff --git a/net/batman-adv/soft-interface.h b/net/batman-adv/soft-interface.h
index 075c5b5b2ce1..daf87f07fadd 100644
--- a/net/batman-adv/soft-interface.h
+++ b/net/batman-adv/soft-interface.h
@@ -1,5 +1,5 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2007-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner 4 * Marek Lindner
5 * 5 *
diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c
index c1578fa0b952..f2eef43bd2ec 100644
--- a/net/batman-adv/sysfs.c
+++ b/net/batman-adv/sysfs.c
@@ -1,5 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2010-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2010-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner 4 * Marek Lindner
5 * 5 *
diff --git a/net/batman-adv/sysfs.h b/net/batman-adv/sysfs.h
index bbeee61221fa..c1e3fb69952d 100644
--- a/net/batman-adv/sysfs.h
+++ b/net/batman-adv/sysfs.h
@@ -1,5 +1,5 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (C) 2010-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2010-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner 4 * Marek Lindner
5 * 5 *
diff --git a/net/batman-adv/tp_meter.c b/net/batman-adv/tp_meter.c
index 8b576712d0c1..11520de96ccb 100644
--- a/net/batman-adv/tp_meter.c
+++ b/net/batman-adv/tp_meter.c
@@ -1,5 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2012-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2012-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Edo Monticelli, Antonio Quartulli 4 * Edo Monticelli, Antonio Quartulli
5 * 5 *
diff --git a/net/batman-adv/tp_meter.h b/net/batman-adv/tp_meter.h
index c8b8f2cb2c2b..68e600974759 100644
--- a/net/batman-adv/tp_meter.h
+++ b/net/batman-adv/tp_meter.h
@@ -1,5 +1,5 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (C) 2012-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2012-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Edo Monticelli, Antonio Quartulli 4 * Edo Monticelli, Antonio Quartulli
5 * 5 *
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 7550a9ccd695..0225616d5771 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -1,5 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2007-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner, Simon Wunderlich, Antonio Quartulli 4 * Marek Lindner, Simon Wunderlich, Antonio Quartulli
5 * 5 *
diff --git a/net/batman-adv/translation-table.h b/net/batman-adv/translation-table.h
index 8d9e3abec2c8..01b6c8eafaf9 100644
--- a/net/batman-adv/translation-table.h
+++ b/net/batman-adv/translation-table.h
@@ -1,5 +1,5 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2007-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner, Simon Wunderlich, Antonio Quartulli 4 * Marek Lindner, Simon Wunderlich, Antonio Quartulli
5 * 5 *
diff --git a/net/batman-adv/tvlv.c b/net/batman-adv/tvlv.c
index 5ffcb45ac6ff..a637458205d1 100644
--- a/net/batman-adv/tvlv.c
+++ b/net/batman-adv/tvlv.c
@@ -1,5 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2007-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner, Simon Wunderlich 4 * Marek Lindner, Simon Wunderlich
5 * 5 *
diff --git a/net/batman-adv/tvlv.h b/net/batman-adv/tvlv.h
index a74df33f446d..ef5867f49824 100644
--- a/net/batman-adv/tvlv.h
+++ b/net/batman-adv/tvlv.h
@@ -1,5 +1,5 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2007-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner, Simon Wunderlich 4 * Marek Lindner, Simon Wunderlich
5 * 5 *
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index a5aa6d61f4e2..476b052ad982 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -1,5 +1,5 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: 2/* Copyright (C) 2007-2018 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner, Simon Wunderlich 4 * Marek Lindner, Simon Wunderlich
5 * 5 *
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
index 3394e6791673..66c0781773df 100644
--- a/net/bluetooth/hci_request.c
+++ b/net/bluetooth/hci_request.c
@@ -934,8 +934,8 @@ static bool is_advertising_allowed(struct hci_dev *hdev, bool connectable)
934 /* Slave connection state and connectable mode bit 38 934 /* Slave connection state and connectable mode bit 38
935 * and scannable bit 21. 935 * and scannable bit 21.
936 */ 936 */
937 if (connectable && (!(hdev->le_states[4] & 0x01) || 937 if (connectable && (!(hdev->le_states[4] & 0x40) ||
938 !(hdev->le_states[2] & 0x40))) 938 !(hdev->le_states[2] & 0x20)))
939 return false; 939 return false;
940 } 940 }
941 941
@@ -948,7 +948,7 @@ static bool is_advertising_allowed(struct hci_dev *hdev, bool connectable)
948 /* Master connection state and connectable mode bit 35 and 948 /* Master connection state and connectable mode bit 35 and
949 * scannable 19. 949 * scannable 19.
950 */ 950 */
951 if (connectable && (!(hdev->le_states[4] & 0x10) || 951 if (connectable && (!(hdev->le_states[4] & 0x08) ||
952 !(hdev->le_states[2] & 0x08))) 952 !(hdev->le_states[2] & 0x08)))
953 return false; 953 return false;
954 } 954 }
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 923e9a271872..1506e1632394 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -1340,7 +1340,7 @@ done:
1340} 1340}
1341 1341
1342static int hci_sock_getname(struct socket *sock, struct sockaddr *addr, 1342static int hci_sock_getname(struct socket *sock, struct sockaddr *addr,
1343 int *addr_len, int peer) 1343 int peer)
1344{ 1344{
1345 struct sockaddr_hci *haddr = (struct sockaddr_hci *)addr; 1345 struct sockaddr_hci *haddr = (struct sockaddr_hci *)addr;
1346 struct sock *sk = sock->sk; 1346 struct sock *sk = sock->sk;
@@ -1360,10 +1360,10 @@ static int hci_sock_getname(struct socket *sock, struct sockaddr *addr,
1360 goto done; 1360 goto done;
1361 } 1361 }
1362 1362
1363 *addr_len = sizeof(*haddr);
1364 haddr->hci_family = AF_BLUETOOTH; 1363 haddr->hci_family = AF_BLUETOOTH;
1365 haddr->hci_dev = hdev->id; 1364 haddr->hci_dev = hdev->id;
1366 haddr->hci_channel= hci_pi(sk)->channel; 1365 haddr->hci_channel= hci_pi(sk)->channel;
1366 err = sizeof(*haddr);
1367 1367
1368done: 1368done:
1369 release_sock(sk); 1369 release_sock(sk);
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 67a8642f57ea..686bdc6b35b0 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -358,7 +358,7 @@ done:
358} 358}
359 359
360static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, 360static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr,
361 int *len, int peer) 361 int peer)
362{ 362{
363 struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr; 363 struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
364 struct sock *sk = sock->sk; 364 struct sock *sk = sock->sk;
@@ -373,7 +373,6 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr,
373 373
374 memset(la, 0, sizeof(struct sockaddr_l2)); 374 memset(la, 0, sizeof(struct sockaddr_l2));
375 addr->sa_family = AF_BLUETOOTH; 375 addr->sa_family = AF_BLUETOOTH;
376 *len = sizeof(struct sockaddr_l2);
377 376
378 la->l2_psm = chan->psm; 377 la->l2_psm = chan->psm;
379 378
@@ -387,7 +386,7 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr,
387 la->l2_bdaddr_type = chan->src_type; 386 la->l2_bdaddr_type = chan->src_type;
388 } 387 }
389 388
390 return 0; 389 return sizeof(struct sockaddr_l2);
391} 390}
392 391
393static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, 392static int l2cap_sock_getsockopt_old(struct socket *sock, int optname,
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 1aaccf637479..93a3b219db09 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -533,7 +533,7 @@ done:
533 return err; 533 return err;
534} 534}
535 535
536static int rfcomm_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer) 536static int rfcomm_sock_getname(struct socket *sock, struct sockaddr *addr, int peer)
537{ 537{
538 struct sockaddr_rc *sa = (struct sockaddr_rc *) addr; 538 struct sockaddr_rc *sa = (struct sockaddr_rc *) addr;
539 struct sock *sk = sock->sk; 539 struct sock *sk = sock->sk;
@@ -552,8 +552,7 @@ static int rfcomm_sock_getname(struct socket *sock, struct sockaddr *addr, int *
552 else 552 else
553 bacpy(&sa->rc_bdaddr, &rfcomm_pi(sk)->src); 553 bacpy(&sa->rc_bdaddr, &rfcomm_pi(sk)->src);
554 554
555 *len = sizeof(struct sockaddr_rc); 555 return sizeof(struct sockaddr_rc);
556 return 0;
557} 556}
558 557
559static int rfcomm_sock_sendmsg(struct socket *sock, struct msghdr *msg, 558static int rfcomm_sock_sendmsg(struct socket *sock, struct msghdr *msg,
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 08df57665e1f..413b8ee49fec 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -680,7 +680,7 @@ done:
680} 680}
681 681
682static int sco_sock_getname(struct socket *sock, struct sockaddr *addr, 682static int sco_sock_getname(struct socket *sock, struct sockaddr *addr,
683 int *len, int peer) 683 int peer)
684{ 684{
685 struct sockaddr_sco *sa = (struct sockaddr_sco *) addr; 685 struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
686 struct sock *sk = sock->sk; 686 struct sock *sk = sock->sk;
@@ -688,14 +688,13 @@ static int sco_sock_getname(struct socket *sock, struct sockaddr *addr,
688 BT_DBG("sock %p, sk %p", sock, sk); 688 BT_DBG("sock %p, sk %p", sock, sk);
689 689
690 addr->sa_family = AF_BLUETOOTH; 690 addr->sa_family = AF_BLUETOOTH;
691 *len = sizeof(struct sockaddr_sco);
692 691
693 if (peer) 692 if (peer)
694 bacpy(&sa->sco_bdaddr, &sco_pi(sk)->dst); 693 bacpy(&sa->sco_bdaddr, &sco_pi(sk)->dst);
695 else 694 else
696 bacpy(&sa->sco_bdaddr, &sco_pi(sk)->src); 695 bacpy(&sa->sco_bdaddr, &sco_pi(sk)->src);
697 696
698 return 0; 697 return sizeof(struct sockaddr_sco);
699} 698}
700 699
701static int sco_sock_sendmsg(struct socket *sock, struct msghdr *msg, 700static int sco_sock_sendmsg(struct socket *sock, struct msghdr *msg,
diff --git a/net/bridge/br.c b/net/bridge/br.c
index 6bf06e756df2..7770481a6506 100644
--- a/net/bridge/br.c
+++ b/net/bridge/br.c
@@ -188,6 +188,7 @@ static void __net_exit br_net_exit(struct net *net)
188 188
189static struct pernet_operations br_net_ops = { 189static struct pernet_operations br_net_ops = {
190 .exit = br_net_exit, 190 .exit = br_net_exit,
191 .async = true,
191}; 192};
192 193
193static const struct stp_proto br_stp_proto = { 194static const struct stp_proto br_stp_proto = {
diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c
index 9b16eaf33819..c2120eb889a9 100644
--- a/net/bridge/br_netfilter_hooks.c
+++ b/net/bridge/br_netfilter_hooks.c
@@ -969,6 +969,7 @@ static struct pernet_operations brnf_net_ops __read_mostly = {
969 .exit = brnf_exit_net, 969 .exit = brnf_exit_net,
970 .id = &brnf_net_id, 970 .id = &brnf_net_id,
971 .size = sizeof(struct brnf_net), 971 .size = sizeof(struct brnf_net),
972 .async = true,
972}; 973};
973 974
974static struct notifier_block brnf_notifier __read_mostly = { 975static struct notifier_block brnf_notifier __read_mostly = {
diff --git a/net/bridge/netfilter/ebtable_broute.c b/net/bridge/netfilter/ebtable_broute.c
index 276b60262981..f070b5e5b9dd 100644
--- a/net/bridge/netfilter/ebtable_broute.c
+++ b/net/bridge/netfilter/ebtable_broute.c
@@ -77,6 +77,7 @@ static void __net_exit broute_net_exit(struct net *net)
77static struct pernet_operations broute_net_ops = { 77static struct pernet_operations broute_net_ops = {
78 .init = broute_net_init, 78 .init = broute_net_init,
79 .exit = broute_net_exit, 79 .exit = broute_net_exit,
80 .async = true,
80}; 81};
81 82
82static int __init ebtable_broute_init(void) 83static int __init ebtable_broute_init(void)
diff --git a/net/bridge/netfilter/ebtable_filter.c b/net/bridge/netfilter/ebtable_filter.c
index c41da5fac84f..4151afc8efcc 100644
--- a/net/bridge/netfilter/ebtable_filter.c
+++ b/net/bridge/netfilter/ebtable_filter.c
@@ -105,6 +105,7 @@ static void __net_exit frame_filter_net_exit(struct net *net)
105static struct pernet_operations frame_filter_net_ops = { 105static struct pernet_operations frame_filter_net_ops = {
106 .init = frame_filter_net_init, 106 .init = frame_filter_net_init,
107 .exit = frame_filter_net_exit, 107 .exit = frame_filter_net_exit,
108 .async = true,
108}; 109};
109 110
110static int __init ebtable_filter_init(void) 111static int __init ebtable_filter_init(void)
diff --git a/net/bridge/netfilter/ebtable_nat.c b/net/bridge/netfilter/ebtable_nat.c
index 08df7406ecb3..b8da2dfe2ec5 100644
--- a/net/bridge/netfilter/ebtable_nat.c
+++ b/net/bridge/netfilter/ebtable_nat.c
@@ -105,6 +105,7 @@ static void __net_exit frame_nat_net_exit(struct net *net)
105static struct pernet_operations frame_nat_net_ops = { 105static struct pernet_operations frame_nat_net_ops = {
106 .init = frame_nat_net_init, 106 .init = frame_nat_net_init,
107 .exit = frame_nat_net_exit, 107 .exit = frame_nat_net_exit,
108 .async = true,
108}; 109};
109 110
110static int __init ebtable_nat_init(void) 111static int __init ebtable_nat_init(void)
diff --git a/net/bridge/netfilter/nf_log_bridge.c b/net/bridge/netfilter/nf_log_bridge.c
index bd2b3c78f59b..91bfc2ac055a 100644
--- a/net/bridge/netfilter/nf_log_bridge.c
+++ b/net/bridge/netfilter/nf_log_bridge.c
@@ -48,6 +48,7 @@ static void __net_exit nf_log_bridge_net_exit(struct net *net)
48static struct pernet_operations nf_log_bridge_net_ops = { 48static struct pernet_operations nf_log_bridge_net_ops = {
49 .init = nf_log_bridge_net_init, 49 .init = nf_log_bridge_net_init,
50 .exit = nf_log_bridge_net_exit, 50 .exit = nf_log_bridge_net_exit,
51 .async = true,
51}; 52};
52 53
53static int __init nf_log_bridge_init(void) 54static int __init nf_log_bridge_init(void)
diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c
index e0adcd123f48..7a78268cc572 100644
--- a/net/caif/caif_dev.c
+++ b/net/caif/caif_dev.c
@@ -544,6 +544,7 @@ static struct pernet_operations caif_net_ops = {
544 .exit = caif_exit_net, 544 .exit = caif_exit_net,
545 .id = &caif_net_id, 545 .id = &caif_net_id,
546 .size = sizeof(struct caif_net), 546 .size = sizeof(struct caif_net),
547 .async = true,
547}; 548};
548 549
549/* Initialize Caif devices list */ 550/* Initialize Caif devices list */
diff --git a/net/can/af_can.c b/net/can/af_can.c
index 6da324550eec..e899970398a1 100644
--- a/net/can/af_can.c
+++ b/net/can/af_can.c
@@ -954,6 +954,7 @@ static struct notifier_block can_netdev_notifier __read_mostly = {
954static struct pernet_operations can_pernet_ops __read_mostly = { 954static struct pernet_operations can_pernet_ops __read_mostly = {
955 .init = can_pernet_init, 955 .init = can_pernet_init,
956 .exit = can_pernet_exit, 956 .exit = can_pernet_exit,
957 .async = true,
957}; 958};
958 959
959static __init int can_init(void) 960static __init int can_init(void)
diff --git a/net/can/bcm.c b/net/can/bcm.c
index ac5e5e34fee3..26730d39e048 100644
--- a/net/can/bcm.c
+++ b/net/can/bcm.c
@@ -1717,6 +1717,7 @@ static void canbcm_pernet_exit(struct net *net)
1717static struct pernet_operations canbcm_pernet_ops __read_mostly = { 1717static struct pernet_operations canbcm_pernet_ops __read_mostly = {
1718 .init = canbcm_pernet_init, 1718 .init = canbcm_pernet_init,
1719 .exit = canbcm_pernet_exit, 1719 .exit = canbcm_pernet_exit,
1720 .async = true,
1720}; 1721};
1721 1722
1722static int __init bcm_module_init(void) 1723static int __init bcm_module_init(void)
diff --git a/net/can/gw.c b/net/can/gw.c
index 398dd0395ad9..08e97668d5cf 100644
--- a/net/can/gw.c
+++ b/net/can/gw.c
@@ -1010,6 +1010,7 @@ static void __net_exit cangw_pernet_exit(struct net *net)
1010static struct pernet_operations cangw_pernet_ops = { 1010static struct pernet_operations cangw_pernet_ops = {
1011 .init = cangw_pernet_init, 1011 .init = cangw_pernet_init,
1012 .exit = cangw_pernet_exit, 1012 .exit = cangw_pernet_exit,
1013 .async = true,
1013}; 1014};
1014 1015
1015static __init int cgw_module_init(void) 1016static __init int cgw_module_init(void)
diff --git a/net/can/raw.c b/net/can/raw.c
index f2ecc43376a1..1051eee82581 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -470,7 +470,7 @@ static int raw_bind(struct socket *sock, struct sockaddr *uaddr, int len)
470} 470}
471 471
472static int raw_getname(struct socket *sock, struct sockaddr *uaddr, 472static int raw_getname(struct socket *sock, struct sockaddr *uaddr,
473 int *len, int peer) 473 int peer)
474{ 474{
475 struct sockaddr_can *addr = (struct sockaddr_can *)uaddr; 475 struct sockaddr_can *addr = (struct sockaddr_can *)uaddr;
476 struct sock *sk = sock->sk; 476 struct sock *sk = sock->sk;
@@ -483,9 +483,7 @@ static int raw_getname(struct socket *sock, struct sockaddr *uaddr,
483 addr->can_family = AF_CAN; 483 addr->can_family = AF_CAN;
484 addr->can_ifindex = ro->ifindex; 484 addr->can_ifindex = ro->ifindex;
485 485
486 *len = sizeof(*addr); 486 return sizeof(*addr);
487
488 return 0;
489} 487}
490 488
491static int raw_setsockopt(struct socket *sock, int level, int optname, 489static int raw_setsockopt(struct socket *sock, int level, int optname,
diff --git a/net/core/dev.c b/net/core/dev.c
index 12be20535714..f9c28f44286c 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2378,7 +2378,7 @@ EXPORT_SYMBOL(netdev_set_num_tc);
2378 2378
2379/* 2379/*
2380 * Routine to help set real_num_tx_queues. To avoid skbs mapped to queues 2380 * Routine to help set real_num_tx_queues. To avoid skbs mapped to queues
2381 * greater then real_num_tx_queues stale skbs on the qdisc must be flushed. 2381 * greater than real_num_tx_queues stale skbs on the qdisc must be flushed.
2382 */ 2382 */
2383int netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq) 2383int netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq)
2384{ 2384{
@@ -4359,6 +4359,9 @@ int netdev_rx_handler_register(struct net_device *dev,
4359 if (netdev_is_rx_handler_busy(dev)) 4359 if (netdev_is_rx_handler_busy(dev))
4360 return -EBUSY; 4360 return -EBUSY;
4361 4361
4362 if (dev->priv_flags & IFF_NO_RX_HANDLER)
4363 return -EINVAL;
4364
4362 /* Note: rx_handler_data must be set before rx_handler */ 4365 /* Note: rx_handler_data must be set before rx_handler */
4363 rcu_assign_pointer(dev->rx_handler_data, rx_handler_data); 4366 rcu_assign_pointer(dev->rx_handler_data, rx_handler_data);
4364 rcu_assign_pointer(dev->rx_handler, rx_handler); 4367 rcu_assign_pointer(dev->rx_handler, rx_handler);
@@ -7554,6 +7557,19 @@ static netdev_features_t netdev_fix_features(struct net_device *dev,
7554 } 7557 }
7555 } 7558 }
7556 7559
7560 /* LRO/HW-GRO features cannot be combined with RX-FCS */
7561 if (features & NETIF_F_RXFCS) {
7562 if (features & NETIF_F_LRO) {
7563 netdev_dbg(dev, "Dropping LRO feature since RX-FCS is requested.\n");
7564 features &= ~NETIF_F_LRO;
7565 }
7566
7567 if (features & NETIF_F_GRO_HW) {
7568 netdev_dbg(dev, "Dropping HW-GRO feature since RX-FCS is requested.\n");
7569 features &= ~NETIF_F_GRO_HW;
7570 }
7571 }
7572
7557 return features; 7573 return features;
7558} 7574}
7559 7575
@@ -8010,7 +8026,8 @@ int register_netdev(struct net_device *dev)
8010{ 8026{
8011 int err; 8027 int err;
8012 8028
8013 rtnl_lock(); 8029 if (rtnl_lock_killable())
8030 return -EINTR;
8014 err = register_netdevice(dev); 8031 err = register_netdevice(dev);
8015 rtnl_unlock(); 8032 rtnl_unlock();
8016 return err; 8033 return err;
@@ -8153,8 +8170,9 @@ void netdev_run_todo(void)
8153 BUG_ON(!list_empty(&dev->ptype_specific)); 8170 BUG_ON(!list_empty(&dev->ptype_specific));
8154 WARN_ON(rcu_access_pointer(dev->ip_ptr)); 8171 WARN_ON(rcu_access_pointer(dev->ip_ptr));
8155 WARN_ON(rcu_access_pointer(dev->ip6_ptr)); 8172 WARN_ON(rcu_access_pointer(dev->ip6_ptr));
8173#if IS_ENABLED(CONFIG_DECNET)
8156 WARN_ON(dev->dn_ptr); 8174 WARN_ON(dev->dn_ptr);
8157 8175#endif
8158 if (dev->priv_destructor) 8176 if (dev->priv_destructor)
8159 dev->priv_destructor(dev); 8177 dev->priv_destructor(dev);
8160 if (dev->needs_free_netdev) 8178 if (dev->needs_free_netdev)
@@ -8852,6 +8870,7 @@ static void __net_exit netdev_exit(struct net *net)
8852static struct pernet_operations __net_initdata netdev_net_ops = { 8870static struct pernet_operations __net_initdata netdev_net_ops = {
8853 .init = netdev_init, 8871 .init = netdev_init,
8854 .exit = netdev_exit, 8872 .exit = netdev_exit,
8873 .async = true,
8855}; 8874};
8856 8875
8857static void __net_exit default_device_exit(struct net *net) 8876static void __net_exit default_device_exit(struct net *net)
@@ -8952,6 +8971,7 @@ static void __net_exit default_device_exit_batch(struct list_head *net_list)
8952static struct pernet_operations __net_initdata default_device_ops = { 8971static struct pernet_operations __net_initdata default_device_ops = {
8953 .exit = default_device_exit, 8972 .exit = default_device_exit,
8954 .exit_batch = default_device_exit_batch, 8973 .exit_batch = default_device_exit_batch,
8974 .async = true,
8955}; 8975};
8956 8976
8957/* 8977/*
diff --git a/net/core/devlink.c b/net/core/devlink.c
index effd4848c2b4..9236e421bd62 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -2331,6 +2331,32 @@ out:
2331 resource->size_valid = size_valid; 2331 resource->size_valid = size_valid;
2332} 2332}
2333 2333
2334static int
2335devlink_resource_validate_size(struct devlink_resource *resource, u64 size,
2336 struct netlink_ext_ack *extack)
2337{
2338 u64 reminder;
2339 int err = 0;
2340
2341 if (size > resource->size_params.size_max) {
2342 NL_SET_ERR_MSG_MOD(extack, "Size larger than maximum");
2343 err = -EINVAL;
2344 }
2345
2346 if (size < resource->size_params.size_min) {
2347 NL_SET_ERR_MSG_MOD(extack, "Size smaller than minimum");
2348 err = -EINVAL;
2349 }
2350
2351 div64_u64_rem(size, resource->size_params.size_granularity, &reminder);
2352 if (reminder) {
2353 NL_SET_ERR_MSG_MOD(extack, "Wrong granularity");
2354 err = -EINVAL;
2355 }
2356
2357 return err;
2358}
2359
2334static int devlink_nl_cmd_resource_set(struct sk_buff *skb, 2360static int devlink_nl_cmd_resource_set(struct sk_buff *skb,
2335 struct genl_info *info) 2361 struct genl_info *info)
2336{ 2362{
@@ -2349,12 +2375,8 @@ static int devlink_nl_cmd_resource_set(struct sk_buff *skb,
2349 if (!resource) 2375 if (!resource)
2350 return -EINVAL; 2376 return -EINVAL;
2351 2377
2352 if (!resource->resource_ops->size_validate)
2353 return -EINVAL;
2354
2355 size = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_SIZE]); 2378 size = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_SIZE]);
2356 err = resource->resource_ops->size_validate(devlink, size, 2379 err = devlink_resource_validate_size(resource, size, info->extack);
2357 info->extack);
2358 if (err) 2380 if (err)
2359 return err; 2381 return err;
2360 2382
@@ -2714,22 +2736,22 @@ static const struct genl_ops devlink_nl_ops[] = {
2714 .cmd = DEVLINK_CMD_DPIPE_TABLE_GET, 2736 .cmd = DEVLINK_CMD_DPIPE_TABLE_GET,
2715 .doit = devlink_nl_cmd_dpipe_table_get, 2737 .doit = devlink_nl_cmd_dpipe_table_get,
2716 .policy = devlink_nl_policy, 2738 .policy = devlink_nl_policy,
2717 .flags = GENL_ADMIN_PERM,
2718 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, 2739 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2740 /* can be retrieved by unprivileged users */
2719 }, 2741 },
2720 { 2742 {
2721 .cmd = DEVLINK_CMD_DPIPE_ENTRIES_GET, 2743 .cmd = DEVLINK_CMD_DPIPE_ENTRIES_GET,
2722 .doit = devlink_nl_cmd_dpipe_entries_get, 2744 .doit = devlink_nl_cmd_dpipe_entries_get,
2723 .policy = devlink_nl_policy, 2745 .policy = devlink_nl_policy,
2724 .flags = GENL_ADMIN_PERM,
2725 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, 2746 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2747 /* can be retrieved by unprivileged users */
2726 }, 2748 },
2727 { 2749 {
2728 .cmd = DEVLINK_CMD_DPIPE_HEADERS_GET, 2750 .cmd = DEVLINK_CMD_DPIPE_HEADERS_GET,
2729 .doit = devlink_nl_cmd_dpipe_headers_get, 2751 .doit = devlink_nl_cmd_dpipe_headers_get,
2730 .policy = devlink_nl_policy, 2752 .policy = devlink_nl_policy,
2731 .flags = GENL_ADMIN_PERM,
2732 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, 2753 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2754 /* can be retrieved by unprivileged users */
2733 }, 2755 },
2734 { 2756 {
2735 .cmd = DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET, 2757 .cmd = DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET,
@@ -2749,8 +2771,8 @@ static const struct genl_ops devlink_nl_ops[] = {
2749 .cmd = DEVLINK_CMD_RESOURCE_DUMP, 2771 .cmd = DEVLINK_CMD_RESOURCE_DUMP,
2750 .doit = devlink_nl_cmd_resource_dump, 2772 .doit = devlink_nl_cmd_resource_dump,
2751 .policy = devlink_nl_policy, 2773 .policy = devlink_nl_policy,
2752 .flags = GENL_ADMIN_PERM,
2753 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, 2774 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2775 /* can be retrieved by unprivileged users */
2754 }, 2776 },
2755 { 2777 {
2756 .cmd = DEVLINK_CMD_RELOAD, 2778 .cmd = DEVLINK_CMD_RELOAD,
@@ -3144,7 +3166,6 @@ EXPORT_SYMBOL_GPL(devlink_dpipe_table_unregister);
3144 */ 3166 */
3145int devlink_resource_register(struct devlink *devlink, 3167int devlink_resource_register(struct devlink *devlink,
3146 const char *resource_name, 3168 const char *resource_name,
3147 bool top_hierarchy,
3148 u64 resource_size, 3169 u64 resource_size,
3149 u64 resource_id, 3170 u64 resource_id,
3150 u64 parent_resource_id, 3171 u64 parent_resource_id,
@@ -3153,8 +3174,11 @@ int devlink_resource_register(struct devlink *devlink,
3153{ 3174{
3154 struct devlink_resource *resource; 3175 struct devlink_resource *resource;
3155 struct list_head *resource_list; 3176 struct list_head *resource_list;
3177 bool top_hierarchy;
3156 int err = 0; 3178 int err = 0;
3157 3179
3180 top_hierarchy = parent_resource_id == DEVLINK_RESOURCE_ID_PARENT_TOP;
3181
3158 mutex_lock(&devlink->lock); 3182 mutex_lock(&devlink->lock);
3159 resource = devlink_resource_find(devlink, NULL, resource_id); 3183 resource = devlink_resource_find(devlink, NULL, resource_id);
3160 if (resource) { 3184 if (resource) {
diff --git a/net/core/dst_cache.c b/net/core/dst_cache.c
index 554d36449231..64cef977484a 100644
--- a/net/core/dst_cache.c
+++ b/net/core/dst_cache.c
@@ -107,7 +107,7 @@ EXPORT_SYMBOL_GPL(dst_cache_set_ip4);
107 107
108#if IS_ENABLED(CONFIG_IPV6) 108#if IS_ENABLED(CONFIG_IPV6)
109void dst_cache_set_ip6(struct dst_cache *dst_cache, struct dst_entry *dst, 109void dst_cache_set_ip6(struct dst_cache *dst_cache, struct dst_entry *dst,
110 const struct in6_addr *addr) 110 const struct in6_addr *saddr)
111{ 111{
112 struct dst_cache_pcpu *idst; 112 struct dst_cache_pcpu *idst;
113 113
@@ -117,7 +117,7 @@ void dst_cache_set_ip6(struct dst_cache *dst_cache, struct dst_entry *dst,
117 idst = this_cpu_ptr(dst_cache->cache); 117 idst = this_cpu_ptr(dst_cache->cache);
118 dst_cache_per_cpu_dst_set(this_cpu_ptr(dst_cache->cache), dst, 118 dst_cache_per_cpu_dst_set(this_cpu_ptr(dst_cache->cache), dst,
119 rt6_get_cookie((struct rt6_info *)dst)); 119 rt6_get_cookie((struct rt6_info *)dst));
120 idst->in6_saddr = *addr; 120 idst->in6_saddr = *saddr;
121} 121}
122EXPORT_SYMBOL_GPL(dst_cache_set_ip6); 122EXPORT_SYMBOL_GPL(dst_cache_set_ip6);
123 123
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 3f89c76d5c24..157cd9efa4be 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -1022,6 +1022,15 @@ static noinline_for_stack int ethtool_get_rxnfc(struct net_device *dev,
1022 if (copy_from_user(&info, useraddr, info_size)) 1022 if (copy_from_user(&info, useraddr, info_size))
1023 return -EFAULT; 1023 return -EFAULT;
1024 1024
1025 /* If FLOW_RSS was requested then user-space must be using the
1026 * new definition, as FLOW_RSS is newer.
1027 */
1028 if (cmd == ETHTOOL_GRXFH && info.flow_type & FLOW_RSS) {
1029 info_size = sizeof(info);
1030 if (copy_from_user(&info, useraddr, info_size))
1031 return -EFAULT;
1032 }
1033
1025 if (info.cmd == ETHTOOL_GRXCLSRLALL) { 1034 if (info.cmd == ETHTOOL_GRXCLSRLALL) {
1026 if (info.rule_cnt > 0) { 1035 if (info.rule_cnt > 0) {
1027 if (info.rule_cnt <= KMALLOC_MAX_SIZE / sizeof(u32)) 1036 if (info.rule_cnt <= KMALLOC_MAX_SIZE / sizeof(u32))
@@ -1251,9 +1260,11 @@ static noinline_for_stack int ethtool_get_rxfh(struct net_device *dev,
1251 user_key_size = rxfh.key_size; 1260 user_key_size = rxfh.key_size;
1252 1261
1253 /* Check that reserved fields are 0 for now */ 1262 /* Check that reserved fields are 0 for now */
1254 if (rxfh.rss_context || rxfh.rsvd8[0] || rxfh.rsvd8[1] || 1263 if (rxfh.rsvd8[0] || rxfh.rsvd8[1] || rxfh.rsvd8[2] || rxfh.rsvd32)
1255 rxfh.rsvd8[2] || rxfh.rsvd32)
1256 return -EINVAL; 1264 return -EINVAL;
1265 /* Most drivers don't handle rss_context, check it's 0 as well */
1266 if (rxfh.rss_context && !ops->get_rxfh_context)
1267 return -EOPNOTSUPP;
1257 1268
1258 rxfh.indir_size = dev_indir_size; 1269 rxfh.indir_size = dev_indir_size;
1259 rxfh.key_size = dev_key_size; 1270 rxfh.key_size = dev_key_size;
@@ -1276,7 +1287,12 @@ static noinline_for_stack int ethtool_get_rxfh(struct net_device *dev,
1276 if (user_key_size) 1287 if (user_key_size)
1277 hkey = rss_config + indir_bytes; 1288 hkey = rss_config + indir_bytes;
1278 1289
1279 ret = dev->ethtool_ops->get_rxfh(dev, indir, hkey, &dev_hfunc); 1290 if (rxfh.rss_context)
1291 ret = dev->ethtool_ops->get_rxfh_context(dev, indir, hkey,
1292 &dev_hfunc,
1293 rxfh.rss_context);
1294 else
1295 ret = dev->ethtool_ops->get_rxfh(dev, indir, hkey, &dev_hfunc);
1280 if (ret) 1296 if (ret)
1281 goto out; 1297 goto out;
1282 1298
@@ -1306,6 +1322,7 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
1306 u8 *hkey = NULL; 1322 u8 *hkey = NULL;
1307 u8 *rss_config; 1323 u8 *rss_config;
1308 u32 rss_cfg_offset = offsetof(struct ethtool_rxfh, rss_config[0]); 1324 u32 rss_cfg_offset = offsetof(struct ethtool_rxfh, rss_config[0]);
1325 bool delete = false;
1309 1326
1310 if (!ops->get_rxnfc || !ops->set_rxfh) 1327 if (!ops->get_rxnfc || !ops->set_rxfh)
1311 return -EOPNOTSUPP; 1328 return -EOPNOTSUPP;
@@ -1319,9 +1336,11 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
1319 return -EFAULT; 1336 return -EFAULT;
1320 1337
1321 /* Check that reserved fields are 0 for now */ 1338 /* Check that reserved fields are 0 for now */
1322 if (rxfh.rss_context || rxfh.rsvd8[0] || rxfh.rsvd8[1] || 1339 if (rxfh.rsvd8[0] || rxfh.rsvd8[1] || rxfh.rsvd8[2] || rxfh.rsvd32)
1323 rxfh.rsvd8[2] || rxfh.rsvd32)
1324 return -EINVAL; 1340 return -EINVAL;
1341 /* Most drivers don't handle rss_context, check it's 0 as well */
1342 if (rxfh.rss_context && !ops->set_rxfh_context)
1343 return -EOPNOTSUPP;
1325 1344
1326 /* If either indir, hash key or function is valid, proceed further. 1345 /* If either indir, hash key or function is valid, proceed further.
1327 * Must request at least one change: indir size, hash key or function. 1346 * Must request at least one change: indir size, hash key or function.
@@ -1346,7 +1365,8 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
1346 if (ret) 1365 if (ret)
1347 goto out; 1366 goto out;
1348 1367
1349 /* rxfh.indir_size == 0 means reset the indir table to default. 1368 /* rxfh.indir_size == 0 means reset the indir table to default (master
1369 * context) or delete the context (other RSS contexts).
1350 * rxfh.indir_size == ETH_RXFH_INDIR_NO_CHANGE means leave it unchanged. 1370 * rxfh.indir_size == ETH_RXFH_INDIR_NO_CHANGE means leave it unchanged.
1351 */ 1371 */
1352 if (rxfh.indir_size && 1372 if (rxfh.indir_size &&
@@ -1359,9 +1379,13 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
1359 if (ret) 1379 if (ret)
1360 goto out; 1380 goto out;
1361 } else if (rxfh.indir_size == 0) { 1381 } else if (rxfh.indir_size == 0) {
1362 indir = (u32 *)rss_config; 1382 if (rxfh.rss_context == 0) {
1363 for (i = 0; i < dev_indir_size; i++) 1383 indir = (u32 *)rss_config;
1364 indir[i] = ethtool_rxfh_indir_default(i, rx_rings.data); 1384 for (i = 0; i < dev_indir_size; i++)
1385 indir[i] = ethtool_rxfh_indir_default(i, rx_rings.data);
1386 } else {
1387 delete = true;
1388 }
1365 } 1389 }
1366 1390
1367 if (rxfh.key_size) { 1391 if (rxfh.key_size) {
@@ -1374,15 +1398,25 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
1374 } 1398 }
1375 } 1399 }
1376 1400
1377 ret = ops->set_rxfh(dev, indir, hkey, rxfh.hfunc); 1401 if (rxfh.rss_context)
1402 ret = ops->set_rxfh_context(dev, indir, hkey, rxfh.hfunc,
1403 &rxfh.rss_context, delete);
1404 else
1405 ret = ops->set_rxfh(dev, indir, hkey, rxfh.hfunc);
1378 if (ret) 1406 if (ret)
1379 goto out; 1407 goto out;
1380 1408
1381 /* indicate whether rxfh was set to default */ 1409 if (copy_to_user(useraddr + offsetof(struct ethtool_rxfh, rss_context),
1382 if (rxfh.indir_size == 0) 1410 &rxfh.rss_context, sizeof(rxfh.rss_context)))
1383 dev->priv_flags &= ~IFF_RXFH_CONFIGURED; 1411 ret = -EFAULT;
1384 else if (rxfh.indir_size != ETH_RXFH_INDIR_NO_CHANGE) 1412
1385 dev->priv_flags |= IFF_RXFH_CONFIGURED; 1413 if (!rxfh.rss_context) {
1414 /* indicate whether rxfh was set to default */
1415 if (rxfh.indir_size == 0)
1416 dev->priv_flags &= ~IFF_RXFH_CONFIGURED;
1417 else if (rxfh.indir_size != ETH_RXFH_INDIR_NO_CHANGE)
1418 dev->priv_flags |= IFF_RXFH_CONFIGURED;
1419 }
1386 1420
1387out: 1421out:
1388 kfree(rss_config); 1422 kfree(rss_config);
diff --git a/net/core/fib_notifier.c b/net/core/fib_notifier.c
index 0c048bdeb016..5ace0705a3f9 100644
--- a/net/core/fib_notifier.c
+++ b/net/core/fib_notifier.c
@@ -171,6 +171,7 @@ static void __net_exit fib_notifier_net_exit(struct net *net)
171static struct pernet_operations fib_notifier_net_ops = { 171static struct pernet_operations fib_notifier_net_ops = {
172 .init = fib_notifier_net_init, 172 .init = fib_notifier_net_init,
173 .exit = fib_notifier_net_exit, 173 .exit = fib_notifier_net_exit,
174 .async = true,
174}; 175};
175 176
176static int __init fib_notifier_init(void) 177static int __init fib_notifier_init(void)
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
index 98e1066c3d55..f6f04fc0f629 100644
--- a/net/core/fib_rules.c
+++ b/net/core/fib_rules.c
@@ -33,6 +33,10 @@ bool fib_rule_matchall(const struct fib_rule *rule)
33 if (!uid_eq(rule->uid_range.start, fib_kuid_range_unset.start) || 33 if (!uid_eq(rule->uid_range.start, fib_kuid_range_unset.start) ||
34 !uid_eq(rule->uid_range.end, fib_kuid_range_unset.end)) 34 !uid_eq(rule->uid_range.end, fib_kuid_range_unset.end))
35 return false; 35 return false;
36 if (fib_rule_port_range_set(&rule->sport_range))
37 return false;
38 if (fib_rule_port_range_set(&rule->dport_range))
39 return false;
36 return true; 40 return true;
37} 41}
38EXPORT_SYMBOL_GPL(fib_rule_matchall); 42EXPORT_SYMBOL_GPL(fib_rule_matchall);
@@ -51,6 +55,7 @@ int fib_default_rule_add(struct fib_rules_ops *ops,
51 r->pref = pref; 55 r->pref = pref;
52 r->table = table; 56 r->table = table;
53 r->flags = flags; 57 r->flags = flags;
58 r->proto = RTPROT_KERNEL;
54 r->fr_net = ops->fro_net; 59 r->fr_net = ops->fro_net;
55 r->uid_range = fib_kuid_range_unset; 60 r->uid_range = fib_kuid_range_unset;
56 61
@@ -220,6 +225,26 @@ static int nla_put_uid_range(struct sk_buff *skb, struct fib_kuid_range *range)
220 return nla_put(skb, FRA_UID_RANGE, sizeof(out), &out); 225 return nla_put(skb, FRA_UID_RANGE, sizeof(out), &out);
221} 226}
222 227
228static int nla_get_port_range(struct nlattr *pattr,
229 struct fib_rule_port_range *port_range)
230{
231 const struct fib_rule_port_range *pr = nla_data(pattr);
232
233 if (!fib_rule_port_range_valid(pr))
234 return -EINVAL;
235
236 port_range->start = pr->start;
237 port_range->end = pr->end;
238
239 return 0;
240}
241
242static int nla_put_port_range(struct sk_buff *skb, int attrtype,
243 struct fib_rule_port_range *range)
244{
245 return nla_put(skb, attrtype, sizeof(*range), range);
246}
247
223static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops, 248static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops,
224 struct flowi *fl, int flags, 249 struct flowi *fl, int flags,
225 struct fib_lookup_arg *arg) 250 struct fib_lookup_arg *arg)
@@ -424,6 +449,17 @@ static int rule_exists(struct fib_rules_ops *ops, struct fib_rule_hdr *frh,
424 !uid_eq(r->uid_range.end, rule->uid_range.end)) 449 !uid_eq(r->uid_range.end, rule->uid_range.end))
425 continue; 450 continue;
426 451
452 if (r->ip_proto != rule->ip_proto)
453 continue;
454
455 if (!fib_rule_port_range_compare(&r->sport_range,
456 &rule->sport_range))
457 continue;
458
459 if (!fib_rule_port_range_compare(&r->dport_range,
460 &rule->dport_range))
461 continue;
462
427 if (!ops->compare(r, frh, tb)) 463 if (!ops->compare(r, frh, tb))
428 continue; 464 continue;
429 return 1; 465 return 1;
@@ -469,6 +505,9 @@ int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr *nlh,
469 rule->pref = tb[FRA_PRIORITY] ? nla_get_u32(tb[FRA_PRIORITY]) 505 rule->pref = tb[FRA_PRIORITY] ? nla_get_u32(tb[FRA_PRIORITY])
470 : fib_default_rule_pref(ops); 506 : fib_default_rule_pref(ops);
471 507
508 rule->proto = tb[FRA_PROTOCOL] ?
509 nla_get_u8(tb[FRA_PROTOCOL]) : RTPROT_UNSPEC;
510
472 if (tb[FRA_IIFNAME]) { 511 if (tb[FRA_IIFNAME]) {
473 struct net_device *dev; 512 struct net_device *dev;
474 513
@@ -565,6 +604,23 @@ int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr *nlh,
565 rule->uid_range = fib_kuid_range_unset; 604 rule->uid_range = fib_kuid_range_unset;
566 } 605 }
567 606
607 if (tb[FRA_IP_PROTO])
608 rule->ip_proto = nla_get_u8(tb[FRA_IP_PROTO]);
609
610 if (tb[FRA_SPORT_RANGE]) {
611 err = nla_get_port_range(tb[FRA_SPORT_RANGE],
612 &rule->sport_range);
613 if (err)
614 goto errout_free;
615 }
616
617 if (tb[FRA_DPORT_RANGE]) {
618 err = nla_get_port_range(tb[FRA_DPORT_RANGE],
619 &rule->dport_range);
620 if (err)
621 goto errout_free;
622 }
623
568 if ((nlh->nlmsg_flags & NLM_F_EXCL) && 624 if ((nlh->nlmsg_flags & NLM_F_EXCL) &&
569 rule_exists(ops, frh, tb, rule)) { 625 rule_exists(ops, frh, tb, rule)) {
570 err = -EEXIST; 626 err = -EEXIST;
@@ -630,6 +686,8 @@ int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr *nlh,
630{ 686{
631 struct net *net = sock_net(skb->sk); 687 struct net *net = sock_net(skb->sk);
632 struct fib_rule_hdr *frh = nlmsg_data(nlh); 688 struct fib_rule_hdr *frh = nlmsg_data(nlh);
689 struct fib_rule_port_range sprange = {0, 0};
690 struct fib_rule_port_range dprange = {0, 0};
633 struct fib_rules_ops *ops = NULL; 691 struct fib_rules_ops *ops = NULL;
634 struct fib_rule *rule, *r; 692 struct fib_rule *rule, *r;
635 struct nlattr *tb[FRA_MAX+1]; 693 struct nlattr *tb[FRA_MAX+1];
@@ -663,7 +721,25 @@ int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr *nlh,
663 range = fib_kuid_range_unset; 721 range = fib_kuid_range_unset;
664 } 722 }
665 723
724 if (tb[FRA_SPORT_RANGE]) {
725 err = nla_get_port_range(tb[FRA_SPORT_RANGE],
726 &sprange);
727 if (err)
728 goto errout;
729 }
730
731 if (tb[FRA_DPORT_RANGE]) {
732 err = nla_get_port_range(tb[FRA_DPORT_RANGE],
733 &dprange);
734 if (err)
735 goto errout;
736 }
737
666 list_for_each_entry(rule, &ops->rules_list, list) { 738 list_for_each_entry(rule, &ops->rules_list, list) {
739 if (tb[FRA_PROTOCOL] &&
740 (rule->proto != nla_get_u8(tb[FRA_PROTOCOL])))
741 continue;
742
667 if (frh->action && (frh->action != rule->action)) 743 if (frh->action && (frh->action != rule->action))
668 continue; 744 continue;
669 745
@@ -704,6 +780,18 @@ int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr *nlh,
704 !uid_eq(rule->uid_range.end, range.end))) 780 !uid_eq(rule->uid_range.end, range.end)))
705 continue; 781 continue;
706 782
783 if (tb[FRA_IP_PROTO] &&
784 (rule->ip_proto != nla_get_u8(tb[FRA_IP_PROTO])))
785 continue;
786
787 if (fib_rule_port_range_set(&sprange) &&
788 !fib_rule_port_range_compare(&rule->sport_range, &sprange))
789 continue;
790
791 if (fib_rule_port_range_set(&dprange) &&
792 !fib_rule_port_range_compare(&rule->dport_range, &dprange))
793 continue;
794
707 if (!ops->compare(rule, frh, tb)) 795 if (!ops->compare(rule, frh, tb))
708 continue; 796 continue;
709 797
@@ -781,7 +869,11 @@ static inline size_t fib_rule_nlmsg_size(struct fib_rules_ops *ops,
781 + nla_total_size(4) /* FRA_FWMARK */ 869 + nla_total_size(4) /* FRA_FWMARK */
782 + nla_total_size(4) /* FRA_FWMASK */ 870 + nla_total_size(4) /* FRA_FWMASK */
783 + nla_total_size_64bit(8) /* FRA_TUN_ID */ 871 + nla_total_size_64bit(8) /* FRA_TUN_ID */
784 + nla_total_size(sizeof(struct fib_kuid_range)); 872 + nla_total_size(sizeof(struct fib_kuid_range))
873 + nla_total_size(1) /* FRA_PROTOCOL */
874 + nla_total_size(1) /* FRA_IP_PROTO */
875 + nla_total_size(sizeof(struct fib_rule_port_range)) /* FRA_SPORT_RANGE */
876 + nla_total_size(sizeof(struct fib_rule_port_range)); /* FRA_DPORT_RANGE */
785 877
786 if (ops->nlmsg_payload) 878 if (ops->nlmsg_payload)
787 payload += ops->nlmsg_payload(rule); 879 payload += ops->nlmsg_payload(rule);
@@ -812,6 +904,9 @@ static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule,
812 frh->action = rule->action; 904 frh->action = rule->action;
813 frh->flags = rule->flags; 905 frh->flags = rule->flags;
814 906
907 if (nla_put_u8(skb, FRA_PROTOCOL, rule->proto))
908 goto nla_put_failure;
909
815 if (rule->action == FR_ACT_GOTO && 910 if (rule->action == FR_ACT_GOTO &&
816 rcu_access_pointer(rule->ctarget) == NULL) 911 rcu_access_pointer(rule->ctarget) == NULL)
817 frh->flags |= FIB_RULE_UNRESOLVED; 912 frh->flags |= FIB_RULE_UNRESOLVED;
@@ -843,7 +938,12 @@ static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule,
843 (rule->l3mdev && 938 (rule->l3mdev &&
844 nla_put_u8(skb, FRA_L3MDEV, rule->l3mdev)) || 939 nla_put_u8(skb, FRA_L3MDEV, rule->l3mdev)) ||
845 (uid_range_set(&rule->uid_range) && 940 (uid_range_set(&rule->uid_range) &&
846 nla_put_uid_range(skb, &rule->uid_range))) 941 nla_put_uid_range(skb, &rule->uid_range)) ||
942 (fib_rule_port_range_set(&rule->sport_range) &&
943 nla_put_port_range(skb, FRA_SPORT_RANGE, &rule->sport_range)) ||
944 (fib_rule_port_range_set(&rule->dport_range) &&
945 nla_put_port_range(skb, FRA_DPORT_RANGE, &rule->dport_range)) ||
946 (rule->ip_proto && nla_put_u8(skb, FRA_IP_PROTO, rule->ip_proto)))
847 goto nla_put_failure; 947 goto nla_put_failure;
848 948
849 if (rule->suppress_ifgroup != -1) { 949 if (rule->suppress_ifgroup != -1) {
@@ -1030,6 +1130,7 @@ static void __net_exit fib_rules_net_exit(struct net *net)
1030static struct pernet_operations fib_rules_net_ops = { 1130static struct pernet_operations fib_rules_net_ops = {
1031 .init = fib_rules_net_init, 1131 .init = fib_rules_net_init,
1032 .exit = fib_rules_net_exit, 1132 .exit = fib_rules_net_exit,
1133 .async = true,
1033}; 1134};
1034 1135
1035static int __init fib_rules_init(void) 1136static int __init fib_rules_init(void)
diff --git a/net/core/filter.c b/net/core/filter.c
index 48aa7c7320db..00c711c5f1a2 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -1890,6 +1890,202 @@ static const struct bpf_func_proto bpf_sk_redirect_map_proto = {
1890 .arg4_type = ARG_ANYTHING, 1890 .arg4_type = ARG_ANYTHING,
1891}; 1891};
1892 1892
1893BPF_CALL_4(bpf_msg_redirect_map, struct sk_msg_buff *, msg,
1894 struct bpf_map *, map, u32, key, u64, flags)
1895{
1896 /* If user passes invalid input drop the packet. */
1897 if (unlikely(flags))
1898 return SK_DROP;
1899
1900 msg->key = key;
1901 msg->flags = flags;
1902 msg->map = map;
1903
1904 return SK_PASS;
1905}
1906
1907struct sock *do_msg_redirect_map(struct sk_msg_buff *msg)
1908{
1909 struct sock *sk = NULL;
1910
1911 if (msg->map) {
1912 sk = __sock_map_lookup_elem(msg->map, msg->key);
1913
1914 msg->key = 0;
1915 msg->map = NULL;
1916 }
1917
1918 return sk;
1919}
1920
1921static const struct bpf_func_proto bpf_msg_redirect_map_proto = {
1922 .func = bpf_msg_redirect_map,
1923 .gpl_only = false,
1924 .ret_type = RET_INTEGER,
1925 .arg1_type = ARG_PTR_TO_CTX,
1926 .arg2_type = ARG_CONST_MAP_PTR,
1927 .arg3_type = ARG_ANYTHING,
1928 .arg4_type = ARG_ANYTHING,
1929};
1930
1931BPF_CALL_2(bpf_msg_apply_bytes, struct sk_msg_buff *, msg, u32, bytes)
1932{
1933 msg->apply_bytes = bytes;
1934 return 0;
1935}
1936
1937static const struct bpf_func_proto bpf_msg_apply_bytes_proto = {
1938 .func = bpf_msg_apply_bytes,
1939 .gpl_only = false,
1940 .ret_type = RET_INTEGER,
1941 .arg1_type = ARG_PTR_TO_CTX,
1942 .arg2_type = ARG_ANYTHING,
1943};
1944
1945BPF_CALL_2(bpf_msg_cork_bytes, struct sk_msg_buff *, msg, u32, bytes)
1946{
1947 msg->cork_bytes = bytes;
1948 return 0;
1949}
1950
1951static const struct bpf_func_proto bpf_msg_cork_bytes_proto = {
1952 .func = bpf_msg_cork_bytes,
1953 .gpl_only = false,
1954 .ret_type = RET_INTEGER,
1955 .arg1_type = ARG_PTR_TO_CTX,
1956 .arg2_type = ARG_ANYTHING,
1957};
1958
1959BPF_CALL_4(bpf_msg_pull_data,
1960 struct sk_msg_buff *, msg, u32, start, u32, end, u64, flags)
1961{
1962 unsigned int len = 0, offset = 0, copy = 0;
1963 struct scatterlist *sg = msg->sg_data;
1964 int first_sg, last_sg, i, shift;
1965 unsigned char *p, *to, *from;
1966 int bytes = end - start;
1967 struct page *page;
1968
1969 if (unlikely(flags || end <= start))
1970 return -EINVAL;
1971
1972 /* First find the starting scatterlist element */
1973 i = msg->sg_start;
1974 do {
1975 len = sg[i].length;
1976 offset += len;
1977 if (start < offset + len)
1978 break;
1979 i++;
1980 if (i == MAX_SKB_FRAGS)
1981 i = 0;
1982 } while (i != msg->sg_end);
1983
1984 if (unlikely(start >= offset + len))
1985 return -EINVAL;
1986
1987 if (!msg->sg_copy[i] && bytes <= len)
1988 goto out;
1989
1990 first_sg = i;
1991
1992 /* At this point we need to linearize multiple scatterlist
1993 * elements or a single shared page. Either way we need to
1994 * copy into a linear buffer exclusively owned by BPF. Then
1995 * place the buffer in the scatterlist and fixup the original
1996 * entries by removing the entries now in the linear buffer
1997 * and shifting the remaining entries. For now we do not try
1998 * to copy partial entries to avoid complexity of running out
1999 * of sg_entry slots. The downside is reading a single byte
2000 * will copy the entire sg entry.
2001 */
2002 do {
2003 copy += sg[i].length;
2004 i++;
2005 if (i == MAX_SKB_FRAGS)
2006 i = 0;
2007 if (bytes < copy)
2008 break;
2009 } while (i != msg->sg_end);
2010 last_sg = i;
2011
2012 if (unlikely(copy < end - start))
2013 return -EINVAL;
2014
2015 page = alloc_pages(__GFP_NOWARN | GFP_ATOMIC, get_order(copy));
2016 if (unlikely(!page))
2017 return -ENOMEM;
2018 p = page_address(page);
2019 offset = 0;
2020
2021 i = first_sg;
2022 do {
2023 from = sg_virt(&sg[i]);
2024 len = sg[i].length;
2025 to = p + offset;
2026
2027 memcpy(to, from, len);
2028 offset += len;
2029 sg[i].length = 0;
2030 put_page(sg_page(&sg[i]));
2031
2032 i++;
2033 if (i == MAX_SKB_FRAGS)
2034 i = 0;
2035 } while (i != last_sg);
2036
2037 sg[first_sg].length = copy;
2038 sg_set_page(&sg[first_sg], page, copy, 0);
2039
2040 /* To repair sg ring we need to shift entries. If we only
2041 * had a single entry though we can just replace it and
2042 * be done. Otherwise walk the ring and shift the entries.
2043 */
2044 shift = last_sg - first_sg - 1;
2045 if (!shift)
2046 goto out;
2047
2048 i = first_sg + 1;
2049 do {
2050 int move_from;
2051
2052 if (i + shift >= MAX_SKB_FRAGS)
2053 move_from = i + shift - MAX_SKB_FRAGS;
2054 else
2055 move_from = i + shift;
2056
2057 if (move_from == msg->sg_end)
2058 break;
2059
2060 sg[i] = sg[move_from];
2061 sg[move_from].length = 0;
2062 sg[move_from].page_link = 0;
2063 sg[move_from].offset = 0;
2064
2065 i++;
2066 if (i == MAX_SKB_FRAGS)
2067 i = 0;
2068 } while (1);
2069 msg->sg_end -= shift;
2070 if (msg->sg_end < 0)
2071 msg->sg_end += MAX_SKB_FRAGS;
2072out:
2073 msg->data = sg_virt(&sg[i]) + start - offset;
2074 msg->data_end = msg->data + bytes;
2075
2076 return 0;
2077}
2078
2079static const struct bpf_func_proto bpf_msg_pull_data_proto = {
2080 .func = bpf_msg_pull_data,
2081 .gpl_only = false,
2082 .ret_type = RET_INTEGER,
2083 .arg1_type = ARG_PTR_TO_CTX,
2084 .arg2_type = ARG_ANYTHING,
2085 .arg3_type = ARG_ANYTHING,
2086 .arg4_type = ARG_ANYTHING,
2087};
2088
1893BPF_CALL_1(bpf_get_cgroup_classid, const struct sk_buff *, skb) 2089BPF_CALL_1(bpf_get_cgroup_classid, const struct sk_buff *, skb)
1894{ 2090{
1895 return task_get_classid(skb); 2091 return task_get_classid(skb);
@@ -2855,7 +3051,8 @@ bool bpf_helper_changes_pkt_data(void *func)
2855 func == bpf_l3_csum_replace || 3051 func == bpf_l3_csum_replace ||
2856 func == bpf_l4_csum_replace || 3052 func == bpf_l4_csum_replace ||
2857 func == bpf_xdp_adjust_head || 3053 func == bpf_xdp_adjust_head ||
2858 func == bpf_xdp_adjust_meta) 3054 func == bpf_xdp_adjust_meta ||
3055 func == bpf_msg_pull_data)
2859 return true; 3056 return true;
2860 3057
2861 return false; 3058 return false;
@@ -3015,7 +3212,7 @@ BPF_CALL_4(bpf_skb_set_tunnel_key, struct sk_buff *, skb,
3015 struct ip_tunnel_info *info; 3212 struct ip_tunnel_info *info;
3016 3213
3017 if (unlikely(flags & ~(BPF_F_TUNINFO_IPV6 | BPF_F_ZERO_CSUM_TX | 3214 if (unlikely(flags & ~(BPF_F_TUNINFO_IPV6 | BPF_F_ZERO_CSUM_TX |
3018 BPF_F_DONT_FRAGMENT))) 3215 BPF_F_DONT_FRAGMENT | BPF_F_SEQ_NUMBER)))
3019 return -EINVAL; 3216 return -EINVAL;
3020 if (unlikely(size != sizeof(struct bpf_tunnel_key))) { 3217 if (unlikely(size != sizeof(struct bpf_tunnel_key))) {
3021 switch (size) { 3218 switch (size) {
@@ -3049,6 +3246,8 @@ BPF_CALL_4(bpf_skb_set_tunnel_key, struct sk_buff *, skb,
3049 info->key.tun_flags |= TUNNEL_DONT_FRAGMENT; 3246 info->key.tun_flags |= TUNNEL_DONT_FRAGMENT;
3050 if (flags & BPF_F_ZERO_CSUM_TX) 3247 if (flags & BPF_F_ZERO_CSUM_TX)
3051 info->key.tun_flags &= ~TUNNEL_CSUM; 3248 info->key.tun_flags &= ~TUNNEL_CSUM;
3249 if (flags & BPF_F_SEQ_NUMBER)
3250 info->key.tun_flags |= TUNNEL_SEQ;
3052 3251
3053 info->key.tun_id = cpu_to_be64(from->tunnel_id); 3252 info->key.tun_id = cpu_to_be64(from->tunnel_id);
3054 info->key.tos = from->tunnel_tos; 3253 info->key.tos = from->tunnel_tos;
@@ -3613,6 +3812,22 @@ static const struct bpf_func_proto *
3613 } 3812 }
3614} 3813}
3615 3814
3815static const struct bpf_func_proto *sk_msg_func_proto(enum bpf_func_id func_id)
3816{
3817 switch (func_id) {
3818 case BPF_FUNC_msg_redirect_map:
3819 return &bpf_msg_redirect_map_proto;
3820 case BPF_FUNC_msg_apply_bytes:
3821 return &bpf_msg_apply_bytes_proto;
3822 case BPF_FUNC_msg_cork_bytes:
3823 return &bpf_msg_cork_bytes_proto;
3824 case BPF_FUNC_msg_pull_data:
3825 return &bpf_msg_pull_data_proto;
3826 default:
3827 return bpf_base_func_proto(func_id);
3828 }
3829}
3830
3616static const struct bpf_func_proto *sk_skb_func_proto(enum bpf_func_id func_id) 3831static const struct bpf_func_proto *sk_skb_func_proto(enum bpf_func_id func_id)
3617{ 3832{
3618 switch (func_id) { 3833 switch (func_id) {
@@ -4002,6 +4217,32 @@ static bool sk_skb_is_valid_access(int off, int size,
4002 return bpf_skb_is_valid_access(off, size, type, info); 4217 return bpf_skb_is_valid_access(off, size, type, info);
4003} 4218}
4004 4219
4220static bool sk_msg_is_valid_access(int off, int size,
4221 enum bpf_access_type type,
4222 struct bpf_insn_access_aux *info)
4223{
4224 if (type == BPF_WRITE)
4225 return false;
4226
4227 switch (off) {
4228 case offsetof(struct sk_msg_md, data):
4229 info->reg_type = PTR_TO_PACKET;
4230 break;
4231 case offsetof(struct sk_msg_md, data_end):
4232 info->reg_type = PTR_TO_PACKET_END;
4233 break;
4234 }
4235
4236 if (off < 0 || off >= sizeof(struct sk_msg_md))
4237 return false;
4238 if (off % size != 0)
4239 return false;
4240 if (size != sizeof(__u64))
4241 return false;
4242
4243 return true;
4244}
4245
4005static u32 bpf_convert_ctx_access(enum bpf_access_type type, 4246static u32 bpf_convert_ctx_access(enum bpf_access_type type,
4006 const struct bpf_insn *si, 4247 const struct bpf_insn *si,
4007 struct bpf_insn *insn_buf, 4248 struct bpf_insn *insn_buf,
@@ -4800,6 +5041,29 @@ static u32 sk_skb_convert_ctx_access(enum bpf_access_type type,
4800 return insn - insn_buf; 5041 return insn - insn_buf;
4801} 5042}
4802 5043
5044static u32 sk_msg_convert_ctx_access(enum bpf_access_type type,
5045 const struct bpf_insn *si,
5046 struct bpf_insn *insn_buf,
5047 struct bpf_prog *prog, u32 *target_size)
5048{
5049 struct bpf_insn *insn = insn_buf;
5050
5051 switch (si->off) {
5052 case offsetof(struct sk_msg_md, data):
5053 *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_msg_buff, data),
5054 si->dst_reg, si->src_reg,
5055 offsetof(struct sk_msg_buff, data));
5056 break;
5057 case offsetof(struct sk_msg_md, data_end):
5058 *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_msg_buff, data_end),
5059 si->dst_reg, si->src_reg,
5060 offsetof(struct sk_msg_buff, data_end));
5061 break;
5062 }
5063
5064 return insn - insn_buf;
5065}
5066
4803const struct bpf_verifier_ops sk_filter_verifier_ops = { 5067const struct bpf_verifier_ops sk_filter_verifier_ops = {
4804 .get_func_proto = sk_filter_func_proto, 5068 .get_func_proto = sk_filter_func_proto,
4805 .is_valid_access = sk_filter_is_valid_access, 5069 .is_valid_access = sk_filter_is_valid_access,
@@ -4890,6 +5154,15 @@ const struct bpf_verifier_ops sk_skb_verifier_ops = {
4890const struct bpf_prog_ops sk_skb_prog_ops = { 5154const struct bpf_prog_ops sk_skb_prog_ops = {
4891}; 5155};
4892 5156
5157const struct bpf_verifier_ops sk_msg_verifier_ops = {
5158 .get_func_proto = sk_msg_func_proto,
5159 .is_valid_access = sk_msg_is_valid_access,
5160 .convert_ctx_access = sk_msg_convert_ctx_access,
5161};
5162
5163const struct bpf_prog_ops sk_msg_prog_ops = {
5164};
5165
4893int sk_detach_filter(struct sock *sk) 5166int sk_detach_filter(struct sock *sk)
4894{ 5167{
4895 int ret = -ENOENT; 5168 int ret = -ENOENT;
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 559db9ea8d86..d29f09bc5ff9 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -1341,22 +1341,6 @@ __u32 __get_hash_from_flowi6(const struct flowi6 *fl6, struct flow_keys *keys)
1341} 1341}
1342EXPORT_SYMBOL(__get_hash_from_flowi6); 1342EXPORT_SYMBOL(__get_hash_from_flowi6);
1343 1343
1344__u32 __get_hash_from_flowi4(const struct flowi4 *fl4, struct flow_keys *keys)
1345{
1346 memset(keys, 0, sizeof(*keys));
1347
1348 keys->addrs.v4addrs.src = fl4->saddr;
1349 keys->addrs.v4addrs.dst = fl4->daddr;
1350 keys->control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
1351 keys->ports.src = fl4->fl4_sport;
1352 keys->ports.dst = fl4->fl4_dport;
1353 keys->keyid.keyid = fl4->fl4_gre_key;
1354 keys->basic.ip_proto = fl4->flowi4_proto;
1355
1356 return flow_hash_from_keys(keys);
1357}
1358EXPORT_SYMBOL(__get_hash_from_flowi4);
1359
1360static const struct flow_dissector_key flow_keys_dissector_keys[] = { 1344static const struct flow_dissector_key flow_keys_dissector_keys[] = {
1361 { 1345 {
1362 .key_id = FLOW_DISSECTOR_KEY_CONTROL, 1346 .key_id = FLOW_DISSECTOR_KEY_CONTROL,
diff --git a/net/core/net-procfs.c b/net/core/net-procfs.c
index e010bb800d7b..65b51e778782 100644
--- a/net/core/net-procfs.c
+++ b/net/core/net-procfs.c
@@ -349,6 +349,7 @@ static void __net_exit dev_proc_net_exit(struct net *net)
349static struct pernet_operations __net_initdata dev_proc_ops = { 349static struct pernet_operations __net_initdata dev_proc_ops = {
350 .init = dev_proc_net_init, 350 .init = dev_proc_net_init,
351 .exit = dev_proc_net_exit, 351 .exit = dev_proc_net_exit,
352 .async = true,
352}; 353};
353 354
354static int dev_mc_seq_show(struct seq_file *seq, void *v) 355static int dev_mc_seq_show(struct seq_file *seq, void *v)
@@ -405,6 +406,7 @@ static void __net_exit dev_mc_net_exit(struct net *net)
405static struct pernet_operations __net_initdata dev_mc_net_ops = { 406static struct pernet_operations __net_initdata dev_mc_net_ops = {
406 .init = dev_mc_net_init, 407 .init = dev_mc_net_init,
407 .exit = dev_mc_net_exit, 408 .exit = dev_mc_net_exit,
409 .async = true,
408}; 410};
409 411
410int __init dev_proc_init(void) 412int __init dev_proc_init(void)
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 3cad5f51afd3..95ba2c53bd9a 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -29,7 +29,6 @@
29 29
30static LIST_HEAD(pernet_list); 30static LIST_HEAD(pernet_list);
31static struct list_head *first_device = &pernet_list; 31static struct list_head *first_device = &pernet_list;
32DEFINE_MUTEX(net_mutex);
33 32
34LIST_HEAD(net_namespace_list); 33LIST_HEAD(net_namespace_list);
35EXPORT_SYMBOL_GPL(net_namespace_list); 34EXPORT_SYMBOL_GPL(net_namespace_list);
@@ -41,6 +40,12 @@ struct net init_net = {
41EXPORT_SYMBOL(init_net); 40EXPORT_SYMBOL(init_net);
42 41
43static bool init_net_initialized; 42static bool init_net_initialized;
43static unsigned nr_sync_pernet_ops;
44/*
45 * net_sem: protects: pernet_list, net_generic_ids, nr_sync_pernet_ops,
46 * init_net_initialized and first_device pointer.
47 */
48DECLARE_RWSEM(net_sem);
44 49
45#define MIN_PERNET_OPS_ID \ 50#define MIN_PERNET_OPS_ID \
46 ((sizeof(struct net_generic) + sizeof(void *) - 1) / sizeof(void *)) 51 ((sizeof(struct net_generic) + sizeof(void *) - 1) / sizeof(void *))
@@ -65,11 +70,10 @@ static int net_assign_generic(struct net *net, unsigned int id, void *data)
65{ 70{
66 struct net_generic *ng, *old_ng; 71 struct net_generic *ng, *old_ng;
67 72
68 BUG_ON(!mutex_is_locked(&net_mutex));
69 BUG_ON(id < MIN_PERNET_OPS_ID); 73 BUG_ON(id < MIN_PERNET_OPS_ID);
70 74
71 old_ng = rcu_dereference_protected(net->gen, 75 old_ng = rcu_dereference_protected(net->gen,
72 lockdep_is_held(&net_mutex)); 76 lockdep_is_held(&net_sem));
73 if (old_ng->s.len > id) { 77 if (old_ng->s.len > id) {
74 old_ng->ptr[id] = data; 78 old_ng->ptr[id] = data;
75 return 0; 79 return 0;
@@ -286,7 +290,7 @@ struct net *get_net_ns_by_id(struct net *net, int id)
286 */ 290 */
287static __net_init int setup_net(struct net *net, struct user_namespace *user_ns) 291static __net_init int setup_net(struct net *net, struct user_namespace *user_ns)
288{ 292{
289 /* Must be called with net_mutex held */ 293 /* Must be called with net_sem held */
290 const struct pernet_operations *ops, *saved_ops; 294 const struct pernet_operations *ops, *saved_ops;
291 int error = 0; 295 int error = 0;
292 LIST_HEAD(net_exit_list); 296 LIST_HEAD(net_exit_list);
@@ -297,12 +301,16 @@ static __net_init int setup_net(struct net *net, struct user_namespace *user_ns)
297 net->user_ns = user_ns; 301 net->user_ns = user_ns;
298 idr_init(&net->netns_ids); 302 idr_init(&net->netns_ids);
299 spin_lock_init(&net->nsid_lock); 303 spin_lock_init(&net->nsid_lock);
304 mutex_init(&net->ipv4.ra_mutex);
300 305
301 list_for_each_entry(ops, &pernet_list, list) { 306 list_for_each_entry(ops, &pernet_list, list) {
302 error = ops_init(ops, net); 307 error = ops_init(ops, net);
303 if (error < 0) 308 if (error < 0)
304 goto out_undo; 309 goto out_undo;
305 } 310 }
311 rtnl_lock();
312 list_add_tail_rcu(&net->list, &net_namespace_list);
313 rtnl_unlock();
306out: 314out:
307 return error; 315 return error;
308 316
@@ -331,6 +339,7 @@ static int __net_init net_defaults_init_net(struct net *net)
331 339
332static struct pernet_operations net_defaults_ops = { 340static struct pernet_operations net_defaults_ops = {
333 .init = net_defaults_init_net, 341 .init = net_defaults_init_net,
342 .async = true,
334}; 343};
335 344
336static __init int net_defaults_init(void) 345static __init int net_defaults_init(void)
@@ -354,7 +363,7 @@ static void dec_net_namespaces(struct ucounts *ucounts)
354 dec_ucount(ucounts, UCOUNT_NET_NAMESPACES); 363 dec_ucount(ucounts, UCOUNT_NET_NAMESPACES);
355} 364}
356 365
357static struct kmem_cache *net_cachep; 366static struct kmem_cache *net_cachep __ro_after_init;
358static struct workqueue_struct *netns_wq; 367static struct workqueue_struct *netns_wq;
359 368
360static struct net *net_alloc(void) 369static struct net *net_alloc(void)
@@ -397,6 +406,7 @@ struct net *copy_net_ns(unsigned long flags,
397{ 406{
398 struct ucounts *ucounts; 407 struct ucounts *ucounts;
399 struct net *net; 408 struct net *net;
409 unsigned write;
400 int rv; 410 int rv;
401 411
402 if (!(flags & CLONE_NEWNET)) 412 if (!(flags & CLONE_NEWNET))
@@ -408,32 +418,38 @@ struct net *copy_net_ns(unsigned long flags,
408 418
409 net = net_alloc(); 419 net = net_alloc();
410 if (!net) { 420 if (!net) {
411 dec_net_namespaces(ucounts); 421 rv = -ENOMEM;
412 return ERR_PTR(-ENOMEM); 422 goto dec_ucounts;
413 } 423 }
414 424 refcount_set(&net->passive, 1);
425 net->ucounts = ucounts;
415 get_user_ns(user_ns); 426 get_user_ns(user_ns);
427again:
428 write = READ_ONCE(nr_sync_pernet_ops);
429 if (write)
430 rv = down_write_killable(&net_sem);
431 else
432 rv = down_read_killable(&net_sem);
433 if (rv < 0)
434 goto put_userns;
416 435
417 rv = mutex_lock_killable(&net_mutex); 436 if (!write && unlikely(READ_ONCE(nr_sync_pernet_ops))) {
418 if (rv < 0) { 437 up_read(&net_sem);
419 net_free(net); 438 goto again;
420 dec_net_namespaces(ucounts);
421 put_user_ns(user_ns);
422 return ERR_PTR(rv);
423 } 439 }
424
425 net->ucounts = ucounts;
426 rv = setup_net(net, user_ns); 440 rv = setup_net(net, user_ns);
427 if (rv == 0) { 441
428 rtnl_lock(); 442 if (write)
429 list_add_tail_rcu(&net->list, &net_namespace_list); 443 up_write(&net_sem);
430 rtnl_unlock(); 444 else
431 } 445 up_read(&net_sem);
432 mutex_unlock(&net_mutex); 446
433 if (rv < 0) { 447 if (rv < 0) {
434 dec_net_namespaces(ucounts); 448put_userns:
435 put_user_ns(user_ns); 449 put_user_ns(user_ns);
436 net_drop_ns(net); 450 net_drop_ns(net);
451dec_ucounts:
452 dec_net_namespaces(ucounts);
437 return ERR_PTR(rv); 453 return ERR_PTR(rv);
438 } 454 }
439 return net; 455 return net;
@@ -466,26 +482,33 @@ static void unhash_nsid(struct net *net, struct net *last)
466 spin_unlock_bh(&net->nsid_lock); 482 spin_unlock_bh(&net->nsid_lock);
467} 483}
468 484
469static DEFINE_SPINLOCK(cleanup_list_lock); 485static LLIST_HEAD(cleanup_list);
470static LIST_HEAD(cleanup_list); /* Must hold cleanup_list_lock to touch */
471 486
472static void cleanup_net(struct work_struct *work) 487static void cleanup_net(struct work_struct *work)
473{ 488{
474 const struct pernet_operations *ops; 489 const struct pernet_operations *ops;
475 struct net *net, *tmp, *last; 490 struct net *net, *tmp, *last;
476 struct list_head net_kill_list; 491 struct llist_node *net_kill_list;
477 LIST_HEAD(net_exit_list); 492 LIST_HEAD(net_exit_list);
493 unsigned write;
478 494
479 /* Atomically snapshot the list of namespaces to cleanup */ 495 /* Atomically snapshot the list of namespaces to cleanup */
480 spin_lock_irq(&cleanup_list_lock); 496 net_kill_list = llist_del_all(&cleanup_list);
481 list_replace_init(&cleanup_list, &net_kill_list); 497again:
482 spin_unlock_irq(&cleanup_list_lock); 498 write = READ_ONCE(nr_sync_pernet_ops);
499 if (write)
500 down_write(&net_sem);
501 else
502 down_read(&net_sem);
483 503
484 mutex_lock(&net_mutex); 504 if (!write && unlikely(READ_ONCE(nr_sync_pernet_ops))) {
505 up_read(&net_sem);
506 goto again;
507 }
485 508
486 /* Don't let anyone else find us. */ 509 /* Don't let anyone else find us. */
487 rtnl_lock(); 510 rtnl_lock();
488 list_for_each_entry(net, &net_kill_list, cleanup_list) 511 llist_for_each_entry(net, net_kill_list, cleanup_list)
489 list_del_rcu(&net->list); 512 list_del_rcu(&net->list);
490 /* Cache last net. After we unlock rtnl, no one new net 513 /* Cache last net. After we unlock rtnl, no one new net
491 * added to net_namespace_list can assign nsid pointer 514 * added to net_namespace_list can assign nsid pointer
@@ -500,7 +523,7 @@ static void cleanup_net(struct work_struct *work)
500 last = list_last_entry(&net_namespace_list, struct net, list); 523 last = list_last_entry(&net_namespace_list, struct net, list);
501 rtnl_unlock(); 524 rtnl_unlock();
502 525
503 list_for_each_entry(net, &net_kill_list, cleanup_list) { 526 llist_for_each_entry(net, net_kill_list, cleanup_list) {
504 unhash_nsid(net, last); 527 unhash_nsid(net, last);
505 list_add_tail(&net->exit_list, &net_exit_list); 528 list_add_tail(&net->exit_list, &net_exit_list);
506 } 529 }
@@ -520,7 +543,10 @@ static void cleanup_net(struct work_struct *work)
520 list_for_each_entry_reverse(ops, &pernet_list, list) 543 list_for_each_entry_reverse(ops, &pernet_list, list)
521 ops_free_list(ops, &net_exit_list); 544 ops_free_list(ops, &net_exit_list);
522 545
523 mutex_unlock(&net_mutex); 546 if (write)
547 up_write(&net_sem);
548 else
549 up_read(&net_sem);
524 550
525 /* Ensure there are no outstanding rcu callbacks using this 551 /* Ensure there are no outstanding rcu callbacks using this
526 * network namespace. 552 * network namespace.
@@ -547,8 +573,8 @@ static void cleanup_net(struct work_struct *work)
547 */ 573 */
548void net_ns_barrier(void) 574void net_ns_barrier(void)
549{ 575{
550 mutex_lock(&net_mutex); 576 down_write(&net_sem);
551 mutex_unlock(&net_mutex); 577 up_write(&net_sem);
552} 578}
553EXPORT_SYMBOL(net_ns_barrier); 579EXPORT_SYMBOL(net_ns_barrier);
554 580
@@ -557,13 +583,8 @@ static DECLARE_WORK(net_cleanup_work, cleanup_net);
557void __put_net(struct net *net) 583void __put_net(struct net *net)
558{ 584{
559 /* Cleanup the network namespace in process context */ 585 /* Cleanup the network namespace in process context */
560 unsigned long flags; 586 if (llist_add(&net->cleanup_list, &cleanup_list))
561 587 queue_work(netns_wq, &net_cleanup_work);
562 spin_lock_irqsave(&cleanup_list_lock, flags);
563 list_add(&net->cleanup_list, &cleanup_list);
564 spin_unlock_irqrestore(&cleanup_list_lock, flags);
565
566 queue_work(netns_wq, &net_cleanup_work);
567} 588}
568EXPORT_SYMBOL_GPL(__put_net); 589EXPORT_SYMBOL_GPL(__put_net);
569 590
@@ -633,6 +654,7 @@ static __net_exit void net_ns_net_exit(struct net *net)
633static struct pernet_operations __net_initdata net_ns_ops = { 654static struct pernet_operations __net_initdata net_ns_ops = {
634 .init = net_ns_net_init, 655 .init = net_ns_net_init,
635 .exit = net_ns_net_exit, 656 .exit = net_ns_net_exit,
657 .async = true,
636}; 658};
637 659
638static const struct nla_policy rtnl_net_policy[NETNSA_MAX + 1] = { 660static const struct nla_policy rtnl_net_policy[NETNSA_MAX + 1] = {
@@ -861,7 +883,7 @@ static int __init net_ns_init(void)
861#ifdef CONFIG_NET_NS 883#ifdef CONFIG_NET_NS
862 net_cachep = kmem_cache_create("net_namespace", sizeof(struct net), 884 net_cachep = kmem_cache_create("net_namespace", sizeof(struct net),
863 SMP_CACHE_BYTES, 885 SMP_CACHE_BYTES,
864 SLAB_PANIC, NULL); 886 SLAB_PANIC|SLAB_ACCOUNT, NULL);
865 887
866 /* Create workqueue for cleanup */ 888 /* Create workqueue for cleanup */
867 netns_wq = create_singlethread_workqueue("netns"); 889 netns_wq = create_singlethread_workqueue("netns");
@@ -875,17 +897,12 @@ static int __init net_ns_init(void)
875 897
876 rcu_assign_pointer(init_net.gen, ng); 898 rcu_assign_pointer(init_net.gen, ng);
877 899
878 mutex_lock(&net_mutex); 900 down_write(&net_sem);
879 if (setup_net(&init_net, &init_user_ns)) 901 if (setup_net(&init_net, &init_user_ns))
880 panic("Could not setup the initial network namespace"); 902 panic("Could not setup the initial network namespace");
881 903
882 init_net_initialized = true; 904 init_net_initialized = true;
883 905 up_write(&net_sem);
884 rtnl_lock();
885 list_add_tail_rcu(&init_net.list, &net_namespace_list);
886 rtnl_unlock();
887
888 mutex_unlock(&net_mutex);
889 906
890 register_pernet_subsys(&net_ns_ops); 907 register_pernet_subsys(&net_ns_ops);
891 908
@@ -989,6 +1006,9 @@ again:
989 rcu_barrier(); 1006 rcu_barrier();
990 if (ops->id) 1007 if (ops->id)
991 ida_remove(&net_generic_ids, *ops->id); 1008 ida_remove(&net_generic_ids, *ops->id);
1009 } else if (!ops->async) {
1010 pr_info_once("Pernet operations %ps are sync.\n", ops);
1011 nr_sync_pernet_ops++;
992 } 1012 }
993 1013
994 return error; 1014 return error;
@@ -996,7 +1016,8 @@ again:
996 1016
997static void unregister_pernet_operations(struct pernet_operations *ops) 1017static void unregister_pernet_operations(struct pernet_operations *ops)
998{ 1018{
999 1019 if (!ops->async)
1020 BUG_ON(nr_sync_pernet_ops-- == 0);
1000 __unregister_pernet_operations(ops); 1021 __unregister_pernet_operations(ops);
1001 rcu_barrier(); 1022 rcu_barrier();
1002 if (ops->id) 1023 if (ops->id)
@@ -1025,9 +1046,9 @@ static void unregister_pernet_operations(struct pernet_operations *ops)
1025int register_pernet_subsys(struct pernet_operations *ops) 1046int register_pernet_subsys(struct pernet_operations *ops)
1026{ 1047{
1027 int error; 1048 int error;
1028 mutex_lock(&net_mutex); 1049 down_write(&net_sem);
1029 error = register_pernet_operations(first_device, ops); 1050 error = register_pernet_operations(first_device, ops);
1030 mutex_unlock(&net_mutex); 1051 up_write(&net_sem);
1031 return error; 1052 return error;
1032} 1053}
1033EXPORT_SYMBOL_GPL(register_pernet_subsys); 1054EXPORT_SYMBOL_GPL(register_pernet_subsys);
@@ -1043,9 +1064,9 @@ EXPORT_SYMBOL_GPL(register_pernet_subsys);
1043 */ 1064 */
1044void unregister_pernet_subsys(struct pernet_operations *ops) 1065void unregister_pernet_subsys(struct pernet_operations *ops)
1045{ 1066{
1046 mutex_lock(&net_mutex); 1067 down_write(&net_sem);
1047 unregister_pernet_operations(ops); 1068 unregister_pernet_operations(ops);
1048 mutex_unlock(&net_mutex); 1069 up_write(&net_sem);
1049} 1070}
1050EXPORT_SYMBOL_GPL(unregister_pernet_subsys); 1071EXPORT_SYMBOL_GPL(unregister_pernet_subsys);
1051 1072
@@ -1071,11 +1092,11 @@ EXPORT_SYMBOL_GPL(unregister_pernet_subsys);
1071int register_pernet_device(struct pernet_operations *ops) 1092int register_pernet_device(struct pernet_operations *ops)
1072{ 1093{
1073 int error; 1094 int error;
1074 mutex_lock(&net_mutex); 1095 down_write(&net_sem);
1075 error = register_pernet_operations(&pernet_list, ops); 1096 error = register_pernet_operations(&pernet_list, ops);
1076 if (!error && (first_device == &pernet_list)) 1097 if (!error && (first_device == &pernet_list))
1077 first_device = &ops->list; 1098 first_device = &ops->list;
1078 mutex_unlock(&net_mutex); 1099 up_write(&net_sem);
1079 return error; 1100 return error;
1080} 1101}
1081EXPORT_SYMBOL_GPL(register_pernet_device); 1102EXPORT_SYMBOL_GPL(register_pernet_device);
@@ -1091,11 +1112,11 @@ EXPORT_SYMBOL_GPL(register_pernet_device);
1091 */ 1112 */
1092void unregister_pernet_device(struct pernet_operations *ops) 1113void unregister_pernet_device(struct pernet_operations *ops)
1093{ 1114{
1094 mutex_lock(&net_mutex); 1115 down_write(&net_sem);
1095 if (&ops->list == first_device) 1116 if (&ops->list == first_device)
1096 first_device = first_device->next; 1117 first_device = first_device->next;
1097 unregister_pernet_operations(ops); 1118 unregister_pernet_operations(ops);
1098 mutex_unlock(&net_mutex); 1119 up_write(&net_sem);
1099} 1120}
1100EXPORT_SYMBOL_GPL(unregister_pernet_device); 1121EXPORT_SYMBOL_GPL(unregister_pernet_device);
1101 1122
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index b8ab5c829511..545cf08cd558 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -906,13 +906,14 @@ static ssize_t pktgen_if_write(struct file *file,
906 i += len; 906 i += len;
907 907
908 if (debug) { 908 if (debug) {
909 size_t copy = min_t(size_t, count, 1023); 909 size_t copy = min_t(size_t, count + 1, 1024);
910 char tb[copy + 1]; 910 char *tp = strndup_user(user_buffer, copy);
911 if (copy_from_user(tb, user_buffer, copy)) 911
912 return -EFAULT; 912 if (IS_ERR(tp))
913 tb[copy] = 0; 913 return PTR_ERR(tp);
914 pr_debug("%s,%lu buffer -:%s:-\n", 914
915 name, (unsigned long)count, tb); 915 pr_debug("%s,%zu buffer -:%s:-\n", name, count, tp);
916 kfree(tp);
916 } 917 }
917 918
918 if (!strcmp(name, "min_pkt_size")) { 919 if (!strcmp(name, "min_pkt_size")) {
@@ -3851,6 +3852,7 @@ static struct pernet_operations pg_net_ops = {
3851 .exit = pg_net_exit, 3852 .exit = pg_net_exit,
3852 .id = &pg_net_id, 3853 .id = &pg_net_id,
3853 .size = sizeof(struct pktgen_net), 3854 .size = sizeof(struct pktgen_net),
3855 .async = true,
3854}; 3856};
3855 3857
3856static int __init pg_init(void) 3858static int __init pg_init(void)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index bc290413a49d..87079eaa871b 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -75,6 +75,12 @@ void rtnl_lock(void)
75} 75}
76EXPORT_SYMBOL(rtnl_lock); 76EXPORT_SYMBOL(rtnl_lock);
77 77
78int rtnl_lock_killable(void)
79{
80 return mutex_lock_killable(&rtnl_mutex);
81}
82EXPORT_SYMBOL(rtnl_lock_killable);
83
78static struct sk_buff *defer_kfree_skb_list; 84static struct sk_buff *defer_kfree_skb_list;
79void rtnl_kfree_skbs(struct sk_buff *head, struct sk_buff *tail) 85void rtnl_kfree_skbs(struct sk_buff *head, struct sk_buff *tail)
80{ 86{
@@ -454,11 +460,11 @@ static void rtnl_lock_unregistering_all(void)
454void rtnl_link_unregister(struct rtnl_link_ops *ops) 460void rtnl_link_unregister(struct rtnl_link_ops *ops)
455{ 461{
456 /* Close the race with cleanup_net() */ 462 /* Close the race with cleanup_net() */
457 mutex_lock(&net_mutex); 463 down_write(&net_sem);
458 rtnl_lock_unregistering_all(); 464 rtnl_lock_unregistering_all();
459 __rtnl_link_unregister(ops); 465 __rtnl_link_unregister(ops);
460 rtnl_unlock(); 466 rtnl_unlock();
461 mutex_unlock(&net_mutex); 467 up_write(&net_sem);
462} 468}
463EXPORT_SYMBOL_GPL(rtnl_link_unregister); 469EXPORT_SYMBOL_GPL(rtnl_link_unregister);
464 470
@@ -4724,6 +4730,7 @@ static void __net_exit rtnetlink_net_exit(struct net *net)
4724static struct pernet_operations rtnetlink_net_ops = { 4730static struct pernet_operations rtnetlink_net_ops = {
4725 .init = rtnetlink_net_init, 4731 .init = rtnetlink_net_init,
4726 .exit = rtnetlink_net_exit, 4732 .exit = rtnetlink_net_exit,
4733 .async = true,
4727}; 4734};
4728 4735
4729void __init rtnetlink_init(void) 4736void __init rtnetlink_init(void)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 1e7acdc30732..46cb22215ff4 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -77,8 +77,8 @@
77#include <linux/capability.h> 77#include <linux/capability.h>
78#include <linux/user_namespace.h> 78#include <linux/user_namespace.h>
79 79
80struct kmem_cache *skbuff_head_cache __read_mostly; 80struct kmem_cache *skbuff_head_cache __ro_after_init;
81static struct kmem_cache *skbuff_fclone_cache __read_mostly; 81static struct kmem_cache *skbuff_fclone_cache __ro_after_init;
82int sysctl_max_skb_frags __read_mostly = MAX_SKB_FRAGS; 82int sysctl_max_skb_frags __read_mostly = MAX_SKB_FRAGS;
83EXPORT_SYMBOL(sysctl_max_skb_frags); 83EXPORT_SYMBOL(sysctl_max_skb_frags);
84 84
@@ -890,7 +890,7 @@ struct sk_buff *skb_morph(struct sk_buff *dst, struct sk_buff *src)
890} 890}
891EXPORT_SYMBOL_GPL(skb_morph); 891EXPORT_SYMBOL_GPL(skb_morph);
892 892
893static int mm_account_pinned_pages(struct mmpin *mmp, size_t size) 893int mm_account_pinned_pages(struct mmpin *mmp, size_t size)
894{ 894{
895 unsigned long max_pg, num_pg, new_pg, old_pg; 895 unsigned long max_pg, num_pg, new_pg, old_pg;
896 struct user_struct *user; 896 struct user_struct *user;
@@ -919,14 +919,16 @@ static int mm_account_pinned_pages(struct mmpin *mmp, size_t size)
919 919
920 return 0; 920 return 0;
921} 921}
922EXPORT_SYMBOL_GPL(mm_account_pinned_pages);
922 923
923static void mm_unaccount_pinned_pages(struct mmpin *mmp) 924void mm_unaccount_pinned_pages(struct mmpin *mmp)
924{ 925{
925 if (mmp->user) { 926 if (mmp->user) {
926 atomic_long_sub(mmp->num_pg, &mmp->user->locked_vm); 927 atomic_long_sub(mmp->num_pg, &mmp->user->locked_vm);
927 free_uid(mmp->user); 928 free_uid(mmp->user);
928 } 929 }
929} 930}
931EXPORT_SYMBOL_GPL(mm_unaccount_pinned_pages);
930 932
931struct ubuf_info *sock_zerocopy_alloc(struct sock *sk, size_t size) 933struct ubuf_info *sock_zerocopy_alloc(struct sock *sk, size_t size)
932{ 934{
diff --git a/net/core/sock.c b/net/core/sock.c
index 85b0b64e7f9d..e689496dfd8a 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1049,16 +1049,18 @@ set_rcvbuf:
1049 break; 1049 break;
1050 1050
1051 case SO_ZEROCOPY: 1051 case SO_ZEROCOPY:
1052 if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6) 1052 if (sk->sk_family == PF_INET || sk->sk_family == PF_INET6) {
1053 if (sk->sk_protocol != IPPROTO_TCP)
1054 ret = -ENOTSUPP;
1055 } else if (sk->sk_family != PF_RDS) {
1053 ret = -ENOTSUPP; 1056 ret = -ENOTSUPP;
1054 else if (sk->sk_protocol != IPPROTO_TCP) 1057 }
1055 ret = -ENOTSUPP; 1058 if (!ret) {
1056 else if (sk->sk_state != TCP_CLOSE) 1059 if (val < 0 || val > 1)
1057 ret = -EBUSY; 1060 ret = -EINVAL;
1058 else if (val < 0 || val > 1) 1061 else
1059 ret = -EINVAL; 1062 sock_valbool_flag(sk, SOCK_ZEROCOPY, valbool);
1060 else 1063 }
1061 sock_valbool_flag(sk, SOCK_ZEROCOPY, valbool);
1062 break; 1064 break;
1063 1065
1064 default: 1066 default:
@@ -1274,7 +1276,8 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
1274 { 1276 {
1275 char address[128]; 1277 char address[128];
1276 1278
1277 if (sock->ops->getname(sock, (struct sockaddr *)address, &lv, 2)) 1279 lv = sock->ops->getname(sock, (struct sockaddr *)address, 2);
1280 if (lv < 0)
1278 return -ENOTCONN; 1281 return -ENOTCONN;
1279 if (lv < len) 1282 if (lv < len)
1280 return -EINVAL; 1283 return -EINVAL;
@@ -1773,7 +1776,7 @@ void sk_setup_caps(struct sock *sk, struct dst_entry *dst)
1773 u32 max_segs = 1; 1776 u32 max_segs = 1;
1774 1777
1775 sk_dst_set(sk, dst); 1778 sk_dst_set(sk, dst);
1776 sk->sk_route_caps = dst->dev->features; 1779 sk->sk_route_caps = dst->dev->features | sk->sk_route_forced_caps;
1777 if (sk->sk_route_caps & NETIF_F_GSO) 1780 if (sk->sk_route_caps & NETIF_F_GSO)
1778 sk->sk_route_caps |= NETIF_F_GSO_SOFTWARE; 1781 sk->sk_route_caps |= NETIF_F_GSO_SOFTWARE;
1779 sk->sk_route_caps &= ~sk->sk_route_nocaps; 1782 sk->sk_route_caps &= ~sk->sk_route_nocaps;
@@ -2234,6 +2237,67 @@ bool sk_page_frag_refill(struct sock *sk, struct page_frag *pfrag)
2234} 2237}
2235EXPORT_SYMBOL(sk_page_frag_refill); 2238EXPORT_SYMBOL(sk_page_frag_refill);
2236 2239
2240int sk_alloc_sg(struct sock *sk, int len, struct scatterlist *sg,
2241 int sg_start, int *sg_curr_index, unsigned int *sg_curr_size,
2242 int first_coalesce)
2243{
2244 int sg_curr = *sg_curr_index, use = 0, rc = 0;
2245 unsigned int size = *sg_curr_size;
2246 struct page_frag *pfrag;
2247 struct scatterlist *sge;
2248
2249 len -= size;
2250 pfrag = sk_page_frag(sk);
2251
2252 while (len > 0) {
2253 unsigned int orig_offset;
2254
2255 if (!sk_page_frag_refill(sk, pfrag)) {
2256 rc = -ENOMEM;
2257 goto out;
2258 }
2259
2260 use = min_t(int, len, pfrag->size - pfrag->offset);
2261
2262 if (!sk_wmem_schedule(sk, use)) {
2263 rc = -ENOMEM;
2264 goto out;
2265 }
2266
2267 sk_mem_charge(sk, use);
2268 size += use;
2269 orig_offset = pfrag->offset;
2270 pfrag->offset += use;
2271
2272 sge = sg + sg_curr - 1;
2273 if (sg_curr > first_coalesce && sg_page(sg) == pfrag->page &&
2274 sg->offset + sg->length == orig_offset) {
2275 sg->length += use;
2276 } else {
2277 sge = sg + sg_curr;
2278 sg_unmark_end(sge);
2279 sg_set_page(sge, pfrag->page, use, orig_offset);
2280 get_page(pfrag->page);
2281 sg_curr++;
2282
2283 if (sg_curr == MAX_SKB_FRAGS)
2284 sg_curr = 0;
2285
2286 if (sg_curr == sg_start) {
2287 rc = -ENOSPC;
2288 break;
2289 }
2290 }
2291
2292 len -= use;
2293 }
2294out:
2295 *sg_curr_size = size;
2296 *sg_curr_index = sg_curr;
2297 return rc;
2298}
2299EXPORT_SYMBOL(sk_alloc_sg);
2300
2237static void __lock_sock(struct sock *sk) 2301static void __lock_sock(struct sock *sk)
2238 __releases(&sk->sk_lock.slock) 2302 __releases(&sk->sk_lock.slock)
2239 __acquires(&sk->sk_lock.slock) 2303 __acquires(&sk->sk_lock.slock)
@@ -2497,7 +2561,7 @@ int sock_no_accept(struct socket *sock, struct socket *newsock, int flags,
2497EXPORT_SYMBOL(sock_no_accept); 2561EXPORT_SYMBOL(sock_no_accept);
2498 2562
2499int sock_no_getname(struct socket *sock, struct sockaddr *saddr, 2563int sock_no_getname(struct socket *sock, struct sockaddr *saddr,
2500 int *len, int peer) 2564 int peer)
2501{ 2565{
2502 return -EOPNOTSUPP; 2566 return -EOPNOTSUPP;
2503} 2567}
@@ -3111,6 +3175,7 @@ static void __net_exit sock_inuse_exit_net(struct net *net)
3111static struct pernet_operations net_inuse_ops = { 3175static struct pernet_operations net_inuse_ops = {
3112 .init = sock_inuse_init_net, 3176 .init = sock_inuse_init_net,
3113 .exit = sock_inuse_exit_net, 3177 .exit = sock_inuse_exit_net,
3178 .async = true,
3114}; 3179};
3115 3180
3116static __init int net_inuse_init(void) 3181static __init int net_inuse_init(void)
@@ -3405,6 +3470,7 @@ static __net_exit void proto_exit_net(struct net *net)
3405static __net_initdata struct pernet_operations proto_net_ops = { 3470static __net_initdata struct pernet_operations proto_net_ops = {
3406 .init = proto_init_net, 3471 .init = proto_init_net,
3407 .exit = proto_exit_net, 3472 .exit = proto_exit_net,
3473 .async = true,
3408}; 3474};
3409 3475
3410static int __init proto_init(void) 3476static int __init proto_init(void)
diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c
index c37b5be7c5e4..a3392a8f9276 100644
--- a/net/core/sock_diag.c
+++ b/net/core/sock_diag.c
@@ -324,6 +324,7 @@ static void __net_exit diag_net_exit(struct net *net)
324static struct pernet_operations diag_net_ops = { 324static struct pernet_operations diag_net_ops = {
325 .init = diag_net_init, 325 .init = diag_net_init,
326 .exit = diag_net_exit, 326 .exit = diag_net_exit,
327 .async = true,
327}; 328};
328 329
329static int __init sock_diag_init(void) 330static int __init sock_diag_init(void)
diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
index f2d0462611c3..4f47f92459cc 100644
--- a/net/core/sysctl_net_core.c
+++ b/net/core/sysctl_net_core.c
@@ -32,6 +32,9 @@ static int max_skb_frags = MAX_SKB_FRAGS;
32 32
33static int net_msg_warn; /* Unused, but still a sysctl */ 33static int net_msg_warn; /* Unused, but still a sysctl */
34 34
35int sysctl_fb_tunnels_only_for_init_net __read_mostly = 0;
36EXPORT_SYMBOL(sysctl_fb_tunnels_only_for_init_net);
37
35#ifdef CONFIG_RPS 38#ifdef CONFIG_RPS
36static int rps_sock_flow_sysctl(struct ctl_table *table, int write, 39static int rps_sock_flow_sysctl(struct ctl_table *table, int write,
37 void __user *buffer, size_t *lenp, loff_t *ppos) 40 void __user *buffer, size_t *lenp, loff_t *ppos)
@@ -513,6 +516,15 @@ static struct ctl_table net_core_table[] = {
513 .proc_handler = proc_dointvec_minmax, 516 .proc_handler = proc_dointvec_minmax,
514 .extra1 = &zero, 517 .extra1 = &zero,
515 }, 518 },
519 {
520 .procname = "fb_tunnels_only_for_init_net",
521 .data = &sysctl_fb_tunnels_only_for_init_net,
522 .maxlen = sizeof(int),
523 .mode = 0644,
524 .proc_handler = proc_dointvec_minmax,
525 .extra1 = &zero,
526 .extra2 = &one,
527 },
516 { } 528 { }
517}; 529};
518 530
@@ -572,6 +584,7 @@ static __net_exit void sysctl_core_net_exit(struct net *net)
572static __net_initdata struct pernet_operations sysctl_core_ops = { 584static __net_initdata struct pernet_operations sysctl_core_ops = {
573 .init = sysctl_core_net_init, 585 .init = sysctl_core_net_init,
574 .exit = sysctl_core_net_exit, 586 .exit = sysctl_core_net_exit,
587 .async = true,
575}; 588};
576 589
577static __init int sysctl_core_init(void) 590static __init int sysctl_core_init(void)
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index e65fcb45c3f6..13ad28ab1e79 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -1031,6 +1031,7 @@ static struct pernet_operations dccp_v4_ops = {
1031 .init = dccp_v4_init_net, 1031 .init = dccp_v4_init_net,
1032 .exit = dccp_v4_exit_net, 1032 .exit = dccp_v4_exit_net,
1033 .exit_batch = dccp_v4_exit_batch, 1033 .exit_batch = dccp_v4_exit_batch,
1034 .async = true,
1034}; 1035};
1035 1036
1036static int __init dccp_v4_init(void) 1037static int __init dccp_v4_init(void)
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index 5df7857fc0f3..2f48c020f8c3 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -1116,6 +1116,7 @@ static struct pernet_operations dccp_v6_ops = {
1116 .init = dccp_v6_init_net, 1116 .init = dccp_v6_init_net,
1117 .exit = dccp_v6_exit_net, 1117 .exit = dccp_v6_exit_net,
1118 .exit_batch = dccp_v6_exit_batch, 1118 .exit_batch = dccp_v6_exit_batch,
1119 .async = true,
1119}; 1120};
1120 1121
1121static int __init dccp_v6_init(void) 1122static int __init dccp_v6_init(void)
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
index 791aff68af88..2ee8306c23e3 100644
--- a/net/decnet/af_decnet.c
+++ b/net/decnet/af_decnet.c
@@ -1180,14 +1180,12 @@ static int dn_accept(struct socket *sock, struct socket *newsock, int flags,
1180} 1180}
1181 1181
1182 1182
1183static int dn_getname(struct socket *sock, struct sockaddr *uaddr,int *uaddr_len,int peer) 1183static int dn_getname(struct socket *sock, struct sockaddr *uaddr,int peer)
1184{ 1184{
1185 struct sockaddr_dn *sa = (struct sockaddr_dn *)uaddr; 1185 struct sockaddr_dn *sa = (struct sockaddr_dn *)uaddr;
1186 struct sock *sk = sock->sk; 1186 struct sock *sk = sock->sk;
1187 struct dn_scp *scp = DN_SK(sk); 1187 struct dn_scp *scp = DN_SK(sk);
1188 1188
1189 *uaddr_len = sizeof(struct sockaddr_dn);
1190
1191 lock_sock(sk); 1189 lock_sock(sk);
1192 1190
1193 if (peer) { 1191 if (peer) {
@@ -1205,7 +1203,7 @@ static int dn_getname(struct socket *sock, struct sockaddr *uaddr,int *uaddr_len
1205 1203
1206 release_sock(sk); 1204 release_sock(sk);
1207 1205
1208 return 0; 1206 return sizeof(struct sockaddr_dn);
1209} 1207}
1210 1208
1211 1209
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
index 6a9d0f50fbee..e63c554e0623 100644
--- a/net/dsa/dsa.c
+++ b/net/dsa/dsa.c
@@ -23,6 +23,7 @@
23#include <linux/netdevice.h> 23#include <linux/netdevice.h>
24#include <linux/sysfs.h> 24#include <linux/sysfs.h>
25#include <linux/phy_fixed.h> 25#include <linux/phy_fixed.h>
26#include <linux/ptp_classify.h>
26#include <linux/gpio/consumer.h> 27#include <linux/gpio/consumer.h>
27#include <linux/etherdevice.h> 28#include <linux/etherdevice.h>
28 29
@@ -122,6 +123,38 @@ struct net_device *dsa_dev_to_net_device(struct device *dev)
122} 123}
123EXPORT_SYMBOL_GPL(dsa_dev_to_net_device); 124EXPORT_SYMBOL_GPL(dsa_dev_to_net_device);
124 125
126/* Determine if we should defer delivery of skb until we have a rx timestamp.
127 *
128 * Called from dsa_switch_rcv. For now, this will only work if tagging is
129 * enabled on the switch. Normally the MAC driver would retrieve the hardware
130 * timestamp when it reads the packet out of the hardware. However in a DSA
131 * switch, the DSA driver owning the interface to which the packet is
132 * delivered is never notified unless we do so here.
133 */
134static bool dsa_skb_defer_rx_timestamp(struct dsa_slave_priv *p,
135 struct sk_buff *skb)
136{
137 struct dsa_switch *ds = p->dp->ds;
138 unsigned int type;
139
140 if (skb_headroom(skb) < ETH_HLEN)
141 return false;
142
143 __skb_push(skb, ETH_HLEN);
144
145 type = ptp_classify_raw(skb);
146
147 __skb_pull(skb, ETH_HLEN);
148
149 if (type == PTP_CLASS_NONE)
150 return false;
151
152 if (likely(ds->ops->port_rxtstamp))
153 return ds->ops->port_rxtstamp(ds, p->dp->index, skb, type);
154
155 return false;
156}
157
125static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev, 158static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev,
126 struct packet_type *pt, struct net_device *unused) 159 struct packet_type *pt, struct net_device *unused)
127{ 160{
@@ -157,6 +190,9 @@ static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev,
157 s->rx_bytes += skb->len; 190 s->rx_bytes += skb->len;
158 u64_stats_update_end(&s->syncp); 191 u64_stats_update_end(&s->syncp);
159 192
193 if (dsa_skb_defer_rx_timestamp(p, skb))
194 return 0;
195
160 netif_receive_skb(skb); 196 netif_receive_skb(skb);
161 197
162 return 0; 198 return 0;
diff --git a/net/dsa/master.c b/net/dsa/master.c
index 00589147f042..90e6df0351eb 100644
--- a/net/dsa/master.c
+++ b/net/dsa/master.c
@@ -42,7 +42,7 @@ static int dsa_master_get_sset_count(struct net_device *dev, int sset)
42 count += ops->get_sset_count(dev, sset); 42 count += ops->get_sset_count(dev, sset);
43 43
44 if (sset == ETH_SS_STATS && ds->ops->get_sset_count) 44 if (sset == ETH_SS_STATS && ds->ops->get_sset_count)
45 count += ds->ops->get_sset_count(ds); 45 count += ds->ops->get_sset_count(ds, cpu_dp->index);
46 46
47 return count; 47 return count;
48} 48}
@@ -76,7 +76,7 @@ static void dsa_master_get_strings(struct net_device *dev, uint32_t stringset,
76 * constructed earlier 76 * constructed earlier
77 */ 77 */
78 ds->ops->get_strings(ds, port, ndata); 78 ds->ops->get_strings(ds, port, ndata);
79 count = ds->ops->get_sset_count(ds); 79 count = ds->ops->get_sset_count(ds, port);
80 for (i = 0; i < count; i++) { 80 for (i = 0; i < count; i++) {
81 memmove(ndata + (i * len + sizeof(pfx)), 81 memmove(ndata + (i * len + sizeof(pfx)),
82 ndata + i * len, len - sizeof(pfx)); 82 ndata + i * len, len - sizeof(pfx));
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index f52307296de4..18561af7a8f1 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -21,6 +21,7 @@
21#include <net/tc_act/tc_mirred.h> 21#include <net/tc_act/tc_mirred.h>
22#include <linux/if_bridge.h> 22#include <linux/if_bridge.h>
23#include <linux/netpoll.h> 23#include <linux/netpoll.h>
24#include <linux/ptp_classify.h>
24 25
25#include "dsa_priv.h" 26#include "dsa_priv.h"
26 27
@@ -255,6 +256,22 @@ dsa_slave_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
255 256
256static int dsa_slave_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 257static int dsa_slave_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
257{ 258{
259 struct dsa_slave_priv *p = netdev_priv(dev);
260 struct dsa_switch *ds = p->dp->ds;
261 int port = p->dp->index;
262
263 /* Pass through to switch driver if it supports timestamping */
264 switch (cmd) {
265 case SIOCGHWTSTAMP:
266 if (ds->ops->port_hwtstamp_get)
267 return ds->ops->port_hwtstamp_get(ds, port, ifr);
268 break;
269 case SIOCSHWTSTAMP:
270 if (ds->ops->port_hwtstamp_set)
271 return ds->ops->port_hwtstamp_set(ds, port, ifr);
272 break;
273 }
274
258 if (!dev->phydev) 275 if (!dev->phydev)
259 return -ENODEV; 276 return -ENODEV;
260 277
@@ -385,6 +402,30 @@ static inline netdev_tx_t dsa_slave_netpoll_send_skb(struct net_device *dev,
385 return NETDEV_TX_OK; 402 return NETDEV_TX_OK;
386} 403}
387 404
405static void dsa_skb_tx_timestamp(struct dsa_slave_priv *p,
406 struct sk_buff *skb)
407{
408 struct dsa_switch *ds = p->dp->ds;
409 struct sk_buff *clone;
410 unsigned int type;
411
412 type = ptp_classify_raw(skb);
413 if (type == PTP_CLASS_NONE)
414 return;
415
416 if (!ds->ops->port_txtstamp)
417 return;
418
419 clone = skb_clone_sk(skb);
420 if (!clone)
421 return;
422
423 if (ds->ops->port_txtstamp(ds, p->dp->index, clone, type))
424 return;
425
426 kfree_skb(clone);
427}
428
388static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev) 429static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev)
389{ 430{
390 struct dsa_slave_priv *p = netdev_priv(dev); 431 struct dsa_slave_priv *p = netdev_priv(dev);
@@ -397,6 +438,11 @@ static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev)
397 s->tx_bytes += skb->len; 438 s->tx_bytes += skb->len;
398 u64_stats_update_end(&s->syncp); 439 u64_stats_update_end(&s->syncp);
399 440
441 /* Identify PTP protocol packets, clone them, and pass them to the
442 * switch driver
443 */
444 dsa_skb_tx_timestamp(p, skb);
445
400 /* Transmit function may have to reallocate the original SKB, 446 /* Transmit function may have to reallocate the original SKB,
401 * in which case it must have freed it. Only free it here on error. 447 * in which case it must have freed it. Only free it here on error.
402 */ 448 */
@@ -559,7 +605,7 @@ static int dsa_slave_get_sset_count(struct net_device *dev, int sset)
559 605
560 count = 4; 606 count = 4;
561 if (ds->ops->get_sset_count) 607 if (ds->ops->get_sset_count)
562 count += ds->ops->get_sset_count(ds); 608 count += ds->ops->get_sset_count(ds, dp->index);
563 609
564 return count; 610 return count;
565 } 611 }
@@ -918,6 +964,18 @@ static int dsa_slave_set_rxnfc(struct net_device *dev,
918 return ds->ops->set_rxnfc(ds, dp->index, nfc); 964 return ds->ops->set_rxnfc(ds, dp->index, nfc);
919} 965}
920 966
967static int dsa_slave_get_ts_info(struct net_device *dev,
968 struct ethtool_ts_info *ts)
969{
970 struct dsa_slave_priv *p = netdev_priv(dev);
971 struct dsa_switch *ds = p->dp->ds;
972
973 if (!ds->ops->get_ts_info)
974 return -EOPNOTSUPP;
975
976 return ds->ops->get_ts_info(ds, p->dp->index, ts);
977}
978
921static const struct ethtool_ops dsa_slave_ethtool_ops = { 979static const struct ethtool_ops dsa_slave_ethtool_ops = {
922 .get_drvinfo = dsa_slave_get_drvinfo, 980 .get_drvinfo = dsa_slave_get_drvinfo,
923 .get_regs_len = dsa_slave_get_regs_len, 981 .get_regs_len = dsa_slave_get_regs_len,
@@ -938,6 +996,7 @@ static const struct ethtool_ops dsa_slave_ethtool_ops = {
938 .set_link_ksettings = phy_ethtool_set_link_ksettings, 996 .set_link_ksettings = phy_ethtool_set_link_ksettings,
939 .get_rxnfc = dsa_slave_get_rxnfc, 997 .get_rxnfc = dsa_slave_get_rxnfc,
940 .set_rxnfc = dsa_slave_set_rxnfc, 998 .set_rxnfc = dsa_slave_set_rxnfc,
999 .get_ts_info = dsa_slave_get_ts_info,
941}; 1000};
942 1001
943/* legacy way, bypassing the bridge *****************************************/ 1002/* legacy way, bypassing the bridge *****************************************/
diff --git a/net/ieee802154/6lowpan/core.c b/net/ieee802154/6lowpan/core.c
index e9f0489e4229..275449b0d633 100644
--- a/net/ieee802154/6lowpan/core.c
+++ b/net/ieee802154/6lowpan/core.c
@@ -104,6 +104,7 @@ static void lowpan_setup(struct net_device *ldev)
104 /* We need an ipv6hdr as minimum len when calling xmit */ 104 /* We need an ipv6hdr as minimum len when calling xmit */
105 ldev->hard_header_len = sizeof(struct ipv6hdr); 105 ldev->hard_header_len = sizeof(struct ipv6hdr);
106 ldev->flags = IFF_BROADCAST | IFF_MULTICAST; 106 ldev->flags = IFF_BROADCAST | IFF_MULTICAST;
107 ldev->priv_flags |= IFF_NO_QUEUE;
107 108
108 ldev->netdev_ops = &lowpan_netdev_ops; 109 ldev->netdev_ops = &lowpan_netdev_ops;
109 ldev->header_ops = &lowpan_header_ops; 110 ldev->header_ops = &lowpan_header_ops;
diff --git a/net/ieee802154/6lowpan/reassembly.c b/net/ieee802154/6lowpan/reassembly.c
index 85bf86ad6b18..a9ccb1322f69 100644
--- a/net/ieee802154/6lowpan/reassembly.c
+++ b/net/ieee802154/6lowpan/reassembly.c
@@ -603,6 +603,7 @@ static void __net_exit lowpan_frags_exit_net(struct net *net)
603static struct pernet_operations lowpan_frags_ops = { 603static struct pernet_operations lowpan_frags_ops = {
604 .init = lowpan_frags_init_net, 604 .init = lowpan_frags_init_net,
605 .exit = lowpan_frags_exit_net, 605 .exit = lowpan_frags_exit_net,
606 .async = true,
606}; 607};
607 608
608int __init lowpan_net_frag_init(void) 609int __init lowpan_net_frag_init(void)
diff --git a/net/ieee802154/core.c b/net/ieee802154/core.c
index cb7176cd4cd6..9104943c15ba 100644
--- a/net/ieee802154/core.c
+++ b/net/ieee802154/core.c
@@ -345,6 +345,7 @@ static void __net_exit cfg802154_pernet_exit(struct net *net)
345 345
346static struct pernet_operations cfg802154_pernet_ops = { 346static struct pernet_operations cfg802154_pernet_ops = {
347 .exit = cfg802154_pernet_exit, 347 .exit = cfg802154_pernet_exit,
348 .async = true,
348}; 349};
349 350
350static int __init wpan_phy_class_init(void) 351static int __init wpan_phy_class_init(void)
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index f48fe6fc7e8c..80dad301361d 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -212,9 +212,14 @@ config NET_IPGRE_BROADCAST
212 Network), but can be distributed all over the Internet. If you want 212 Network), but can be distributed all over the Internet. If you want
213 to do that, say Y here and to "IP multicast routing" below. 213 to do that, say Y here and to "IP multicast routing" below.
214 214
215config IP_MROUTE_COMMON
216 bool
217 depends on IP_MROUTE || IPV6_MROUTE
218
215config IP_MROUTE 219config IP_MROUTE
216 bool "IP: multicast routing" 220 bool "IP: multicast routing"
217 depends on IP_MULTICAST 221 depends on IP_MULTICAST
222 select IP_MROUTE_COMMON
218 help 223 help
219 This is used if you want your machine to act as a router for IP 224 This is used if you want your machine to act as a router for IP
220 packets that have several destination addresses. It is needed on the 225 packets that have several destination addresses. It is needed on the
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index 47a0a6649a9d..a07b7dd06def 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_SYSCTL) += sysctl_net_ipv4.o
20obj-$(CONFIG_PROC_FS) += proc.o 20obj-$(CONFIG_PROC_FS) += proc.o
21obj-$(CONFIG_IP_MULTIPLE_TABLES) += fib_rules.o 21obj-$(CONFIG_IP_MULTIPLE_TABLES) += fib_rules.o
22obj-$(CONFIG_IP_MROUTE) += ipmr.o 22obj-$(CONFIG_IP_MROUTE) += ipmr.o
23obj-$(CONFIG_IP_MROUTE_COMMON) += ipmr_base.o
23obj-$(CONFIG_NET_IPIP) += ipip.o 24obj-$(CONFIG_NET_IPIP) += ipip.o
24gre-y := gre_demux.o 25gre-y := gre_demux.o
25obj-$(CONFIG_NET_FOU) += fou.o 26obj-$(CONFIG_NET_FOU) += fou.o
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index e4329e161943..e8c7fad8c329 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -723,7 +723,7 @@ EXPORT_SYMBOL(inet_accept);
723 * This does both peername and sockname. 723 * This does both peername and sockname.
724 */ 724 */
725int inet_getname(struct socket *sock, struct sockaddr *uaddr, 725int inet_getname(struct socket *sock, struct sockaddr *uaddr,
726 int *uaddr_len, int peer) 726 int peer)
727{ 727{
728 struct sock *sk = sock->sk; 728 struct sock *sk = sock->sk;
729 struct inet_sock *inet = inet_sk(sk); 729 struct inet_sock *inet = inet_sk(sk);
@@ -745,8 +745,7 @@ int inet_getname(struct socket *sock, struct sockaddr *uaddr,
745 sin->sin_addr.s_addr = addr; 745 sin->sin_addr.s_addr = addr;
746 } 746 }
747 memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); 747 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
748 *uaddr_len = sizeof(*sin); 748 return sizeof(*sin);
749 return 0;
750} 749}
751EXPORT_SYMBOL(inet_getname); 750EXPORT_SYMBOL(inet_getname);
752 751
@@ -1736,6 +1735,7 @@ static __net_exit void ipv4_mib_exit_net(struct net *net)
1736static __net_initdata struct pernet_operations ipv4_mib_ops = { 1735static __net_initdata struct pernet_operations ipv4_mib_ops = {
1737 .init = ipv4_mib_init_net, 1736 .init = ipv4_mib_init_net,
1738 .exit = ipv4_mib_exit_net, 1737 .exit = ipv4_mib_exit_net,
1738 .async = true,
1739}; 1739};
1740 1740
1741static int __init init_ipv4_mibs(void) 1741static int __init init_ipv4_mibs(void)
@@ -1789,6 +1789,7 @@ static __net_exit void inet_exit_net(struct net *net)
1789static __net_initdata struct pernet_operations af_inet_ops = { 1789static __net_initdata struct pernet_operations af_inet_ops = {
1790 .init = inet_init_net, 1790 .init = inet_init_net,
1791 .exit = inet_exit_net, 1791 .exit = inet_exit_net,
1792 .async = true,
1792}; 1793};
1793 1794
1794static int __init init_inet_pernet_ops(void) 1795static int __init init_inet_pernet_ops(void)
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index f28f06c91ead..7dc9de8444a9 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -1447,6 +1447,7 @@ static void __net_exit arp_net_exit(struct net *net)
1447static struct pernet_operations arp_net_ops = { 1447static struct pernet_operations arp_net_ops = {
1448 .init = arp_net_init, 1448 .init = arp_net_init,
1449 .exit = arp_net_exit, 1449 .exit = arp_net_exit,
1450 .async = true,
1450}; 1451};
1451 1452
1452static int __init arp_proc_init(void) 1453static int __init arp_proc_init(void)
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 40f001782c1b..5ae0d1f097ca 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -2469,6 +2469,7 @@ static __net_exit void devinet_exit_net(struct net *net)
2469static __net_initdata struct pernet_operations devinet_ops = { 2469static __net_initdata struct pernet_operations devinet_ops = {
2470 .init = devinet_init_net, 2470 .init = devinet_init_net,
2471 .exit = devinet_exit_net, 2471 .exit = devinet_exit_net,
2472 .async = true,
2472}; 2473};
2473 2474
2474static struct rtnl_af_ops inet_af_ops __read_mostly = { 2475static struct rtnl_af_ops inet_af_ops __read_mostly = {
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index f05afaf3235c..ac71c3d496c0 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -1362,6 +1362,7 @@ static void __net_exit fib_net_exit(struct net *net)
1362static struct pernet_operations fib_net_ops = { 1362static struct pernet_operations fib_net_ops = {
1363 .init = fib_net_init, 1363 .init = fib_net_init,
1364 .exit = fib_net_exit, 1364 .exit = fib_net_exit,
1365 .async = true,
1365}; 1366};
1366 1367
1367void __init ip_fib_init(void) 1368void __init ip_fib_init(void)
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
index 35d646a62ad4..737d11bc8838 100644
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -182,6 +182,17 @@ static int fib4_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
182 if (r->tos && (r->tos != fl4->flowi4_tos)) 182 if (r->tos && (r->tos != fl4->flowi4_tos))
183 return 0; 183 return 0;
184 184
185 if (rule->ip_proto && (rule->ip_proto != fl4->flowi4_proto))
186 return 0;
187
188 if (fib_rule_port_range_set(&rule->sport_range) &&
189 !fib_rule_port_inrange(&rule->sport_range, fl4->fl4_sport))
190 return 0;
191
192 if (fib_rule_port_range_set(&rule->dport_range) &&
193 !fib_rule_port_inrange(&rule->dport_range, fl4->fl4_dport))
194 return 0;
195
185 return 1; 196 return 1;
186} 197}
187 198
@@ -244,6 +255,9 @@ static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
244 } 255 }
245#endif 256#endif
246 257
258 if (fib_rule_requires_fldissect(rule))
259 net->ipv4.fib_rules_require_fldissect++;
260
247 rule4->src_len = frh->src_len; 261 rule4->src_len = frh->src_len;
248 rule4->srcmask = inet_make_mask(rule4->src_len); 262 rule4->srcmask = inet_make_mask(rule4->src_len);
249 rule4->dst_len = frh->dst_len; 263 rule4->dst_len = frh->dst_len;
@@ -272,6 +286,10 @@ static int fib4_rule_delete(struct fib_rule *rule)
272 net->ipv4.fib_num_tclassid_users--; 286 net->ipv4.fib_num_tclassid_users--;
273#endif 287#endif
274 net->ipv4.fib_has_custom_rules = true; 288 net->ipv4.fib_has_custom_rules = true;
289
290 if (net->ipv4.fib_rules_require_fldissect &&
291 fib_rule_requires_fldissect(rule))
292 net->ipv4.fib_rules_require_fldissect--;
275errout: 293errout:
276 return err; 294 return err;
277} 295}
@@ -389,6 +407,7 @@ int __net_init fib4_rules_init(struct net *net)
389 goto fail; 407 goto fail;
390 net->ipv4.rules_ops = ops; 408 net->ipv4.rules_ops = ops;
391 net->ipv4.fib_has_custom_rules = false; 409 net->ipv4.fib_has_custom_rules = false;
410 net->ipv4.fib_rules_require_fldissect = 0;
392 return 0; 411 return 0;
393 412
394fail: 413fail:
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 7d36a950d961..e7c602c600ac 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -171,7 +171,7 @@ static void free_nh_exceptions(struct fib_nh *nh)
171 fnhe = rcu_dereference_protected(hash[i].chain, 1); 171 fnhe = rcu_dereference_protected(hash[i].chain, 1);
172 while (fnhe) { 172 while (fnhe) {
173 struct fib_nh_exception *next; 173 struct fib_nh_exception *next;
174 174
175 next = rcu_dereference_protected(fnhe->fnhe_next, 1); 175 next = rcu_dereference_protected(fnhe->fnhe_next, 1);
176 176
177 rt_fibinfo_free(&fnhe->fnhe_rth_input); 177 rt_fibinfo_free(&fnhe->fnhe_rth_input);
@@ -1765,14 +1765,12 @@ void fib_select_multipath(struct fib_result *res, int hash)
1765void fib_select_path(struct net *net, struct fib_result *res, 1765void fib_select_path(struct net *net, struct fib_result *res,
1766 struct flowi4 *fl4, const struct sk_buff *skb) 1766 struct flowi4 *fl4, const struct sk_buff *skb)
1767{ 1767{
1768 bool oif_check; 1768 if (fl4->flowi4_oif && !(fl4->flowi4_flags & FLOWI_FLAG_SKIP_NH_OIF))
1769 1769 goto check_saddr;
1770 oif_check = (fl4->flowi4_oif == 0 ||
1771 fl4->flowi4_flags & FLOWI_FLAG_SKIP_NH_OIF);
1772 1770
1773#ifdef CONFIG_IP_ROUTE_MULTIPATH 1771#ifdef CONFIG_IP_ROUTE_MULTIPATH
1774 if (res->fi->fib_nhs > 1 && oif_check) { 1772 if (res->fi->fib_nhs > 1) {
1775 int h = fib_multipath_hash(res->fi, fl4, skb); 1773 int h = fib_multipath_hash(net, fl4, skb, NULL);
1776 1774
1777 fib_select_multipath(res, h); 1775 fib_select_multipath(res, h);
1778 } 1776 }
@@ -1780,10 +1778,10 @@ void fib_select_path(struct net *net, struct fib_result *res,
1780#endif 1778#endif
1781 if (!res->prefixlen && 1779 if (!res->prefixlen &&
1782 res->table->tb_num_default > 1 && 1780 res->table->tb_num_default > 1 &&
1783 res->type == RTN_UNICAST && oif_check) 1781 res->type == RTN_UNICAST)
1784 fib_select_default(fl4, res); 1782 fib_select_default(fl4, res);
1785 1783
1784check_saddr:
1786 if (!fl4->saddr) 1785 if (!fl4->saddr)
1787 fl4->saddr = FIB_RES_PREFSRC(net, *res); 1786 fl4->saddr = FIB_RES_PREFSRC(net, *res);
1788} 1787}
1789EXPORT_SYMBOL_GPL(fib_select_path);
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 5530cd6fdbc7..62243a8abf92 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -50,6 +50,7 @@
50 50
51#define VERSION "0.409" 51#define VERSION "0.409"
52 52
53#include <linux/cache.h>
53#include <linux/uaccess.h> 54#include <linux/uaccess.h>
54#include <linux/bitops.h> 55#include <linux/bitops.h>
55#include <linux/types.h> 56#include <linux/types.h>
@@ -191,8 +192,8 @@ static size_t tnode_free_size;
191 */ 192 */
192static const int sync_pages = 128; 193static const int sync_pages = 128;
193 194
194static struct kmem_cache *fn_alias_kmem __read_mostly; 195static struct kmem_cache *fn_alias_kmem __ro_after_init;
195static struct kmem_cache *trie_leaf_kmem __read_mostly; 196static struct kmem_cache *trie_leaf_kmem __ro_after_init;
196 197
197static inline struct tnode *tn_info(struct key_vector *kv) 198static inline struct tnode *tn_info(struct key_vector *kv)
198{ 199{
diff --git a/net/ipv4/fou.c b/net/ipv4/fou.c
index 1540db65241a..d3e1a9af478b 100644
--- a/net/ipv4/fou.c
+++ b/net/ipv4/fou.c
@@ -1081,6 +1081,7 @@ static struct pernet_operations fou_net_ops = {
1081 .exit = fou_exit_net, 1081 .exit = fou_exit_net,
1082 .id = &fou_net_id, 1082 .id = &fou_net_id,
1083 .size = sizeof(struct fou_net), 1083 .size = sizeof(struct fou_net),
1084 .async = true,
1084}; 1085};
1085 1086
1086static int __init fou_init(void) 1087static int __init fou_init(void)
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 1617604c9284..cc56efa64d5c 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -1257,6 +1257,7 @@ fail:
1257static struct pernet_operations __net_initdata icmp_sk_ops = { 1257static struct pernet_operations __net_initdata icmp_sk_ops = {
1258 .init = icmp_sk_init, 1258 .init = icmp_sk_init,
1259 .exit = icmp_sk_exit, 1259 .exit = icmp_sk_exit,
1260 .async = true,
1260}; 1261};
1261 1262
1262int __init icmp_init(void) 1263int __init icmp_init(void)
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index f2402581fef1..c2743763777e 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -3028,6 +3028,7 @@ static void __net_exit igmp_net_exit(struct net *net)
3028static struct pernet_operations igmp_net_ops = { 3028static struct pernet_operations igmp_net_ops = {
3029 .init = igmp_net_init, 3029 .init = igmp_net_init,
3030 .exit = igmp_net_exit, 3030 .exit = igmp_net_exit,
3031 .async = true,
3031}; 3032};
3032#endif 3033#endif
3033 3034
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
index 914d56928578..1f04bd91fc2e 100644
--- a/net/ipv4/inetpeer.c
+++ b/net/ipv4/inetpeer.c
@@ -6,6 +6,7 @@
6 * Authors: Andrey V. Savochkin <saw@msu.ru> 6 * Authors: Andrey V. Savochkin <saw@msu.ru>
7 */ 7 */
8 8
9#include <linux/cache.h>
9#include <linux/module.h> 10#include <linux/module.h>
10#include <linux/types.h> 11#include <linux/types.h>
11#include <linux/slab.h> 12#include <linux/slab.h>
@@ -51,7 +52,7 @@
51 * daddr: unchangeable 52 * daddr: unchangeable
52 */ 53 */
53 54
54static struct kmem_cache *peer_cachep __read_mostly; 55static struct kmem_cache *peer_cachep __ro_after_init;
55 56
56void inet_peer_base_init(struct inet_peer_base *bp) 57void inet_peer_base_init(struct inet_peer_base *bp)
57{ 58{
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index bbf1b94942c0..5e843ae5e468 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -885,6 +885,7 @@ static void __net_exit ipv4_frags_exit_net(struct net *net)
885static struct pernet_operations ip4_frags_ops = { 885static struct pernet_operations ip4_frags_ops = {
886 .init = ipv4_frags_init_net, 886 .init = ipv4_frags_init_net,
887 .exit = ipv4_frags_exit_net, 887 .exit = ipv4_frags_exit_net,
888 .async = true,
888}; 889};
889 890
890void __init ipfrag_init(void) 891void __init ipfrag_init(void)
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 0901de42ed85..9ab1aa2f7660 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -522,6 +522,7 @@ err_free_skb:
522static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev, 522static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev,
523 __be16 proto) 523 __be16 proto)
524{ 524{
525 struct ip_tunnel *tunnel = netdev_priv(dev);
525 struct ip_tunnel_info *tun_info; 526 struct ip_tunnel_info *tun_info;
526 const struct ip_tunnel_key *key; 527 const struct ip_tunnel_key *key;
527 struct rtable *rt = NULL; 528 struct rtable *rt = NULL;
@@ -545,9 +546,11 @@ static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev,
545 if (gre_handle_offloads(skb, !!(tun_info->key.tun_flags & TUNNEL_CSUM))) 546 if (gre_handle_offloads(skb, !!(tun_info->key.tun_flags & TUNNEL_CSUM)))
546 goto err_free_rt; 547 goto err_free_rt;
547 548
548 flags = tun_info->key.tun_flags & (TUNNEL_CSUM | TUNNEL_KEY); 549 flags = tun_info->key.tun_flags &
550 (TUNNEL_CSUM | TUNNEL_KEY | TUNNEL_SEQ);
549 gre_build_header(skb, tunnel_hlen, flags, proto, 551 gre_build_header(skb, tunnel_hlen, flags, proto,
550 tunnel_id_to_key32(tun_info->key.tun_id), 0); 552 tunnel_id_to_key32(tun_info->key.tun_id),
553 (flags & TUNNEL_SEQ) ? htonl(tunnel->o_seqno++) : 0);
551 554
552 df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0; 555 df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
553 556
@@ -1041,6 +1044,7 @@ static struct pernet_operations ipgre_net_ops = {
1041 .exit_batch = ipgre_exit_batch_net, 1044 .exit_batch = ipgre_exit_batch_net,
1042 .id = &ipgre_net_id, 1045 .id = &ipgre_net_id,
1043 .size = sizeof(struct ip_tunnel_net), 1046 .size = sizeof(struct ip_tunnel_net),
1047 .async = true,
1044}; 1048};
1045 1049
1046static int ipgre_tunnel_validate(struct nlattr *tb[], struct nlattr *data[], 1050static int ipgre_tunnel_validate(struct nlattr *tb[], struct nlattr *data[],
@@ -1317,6 +1321,12 @@ static void ipgre_tap_setup(struct net_device *dev)
1317 ip_tunnel_setup(dev, gre_tap_net_id); 1321 ip_tunnel_setup(dev, gre_tap_net_id);
1318} 1322}
1319 1323
1324bool is_gretap_dev(const struct net_device *dev)
1325{
1326 return dev->netdev_ops == &gre_tap_netdev_ops;
1327}
1328EXPORT_SYMBOL_GPL(is_gretap_dev);
1329
1320static int ipgre_newlink(struct net *src_net, struct net_device *dev, 1330static int ipgre_newlink(struct net *src_net, struct net_device *dev,
1321 struct nlattr *tb[], struct nlattr *data[], 1331 struct nlattr *tb[], struct nlattr *data[],
1322 struct netlink_ext_ack *extack) 1332 struct netlink_ext_ack *extack)
@@ -1618,6 +1628,7 @@ static struct pernet_operations ipgre_tap_net_ops = {
1618 .exit_batch = ipgre_tap_exit_batch_net, 1628 .exit_batch = ipgre_tap_exit_batch_net,
1619 .id = &gre_tap_net_id, 1629 .id = &gre_tap_net_id,
1620 .size = sizeof(struct ip_tunnel_net), 1630 .size = sizeof(struct ip_tunnel_net),
1631 .async = true,
1621}; 1632};
1622 1633
1623static int __net_init erspan_init_net(struct net *net) 1634static int __net_init erspan_init_net(struct net *net)
@@ -1636,6 +1647,7 @@ static struct pernet_operations erspan_net_ops = {
1636 .exit_batch = erspan_exit_batch_net, 1647 .exit_batch = erspan_exit_batch_net,
1637 .id = &erspan_net_id, 1648 .id = &erspan_net_id,
1638 .size = sizeof(struct ip_tunnel_net), 1649 .size = sizeof(struct ip_tunnel_net),
1650 .async = true,
1639}; 1651};
1640 1652
1641static int __init ipgre_init(void) 1653static int __init ipgre_init(void)
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index 57fc13c6ab2b..7582713dd18f 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -159,7 +159,7 @@ bool ip_call_ra_chain(struct sk_buff *skb)
159 struct net_device *dev = skb->dev; 159 struct net_device *dev = skb->dev;
160 struct net *net = dev_net(dev); 160 struct net *net = dev_net(dev);
161 161
162 for (ra = rcu_dereference(ip_ra_chain); ra; ra = rcu_dereference(ra->next)) { 162 for (ra = rcu_dereference(net->ipv4.ra_chain); ra; ra = rcu_dereference(ra->next)) {
163 struct sock *sk = ra->sk; 163 struct sock *sk = ra->sk;
164 164
165 /* If socket is bound to an interface, only report 165 /* If socket is bound to an interface, only report
@@ -167,8 +167,7 @@ bool ip_call_ra_chain(struct sk_buff *skb)
167 */ 167 */
168 if (sk && inet_sk(sk)->inet_num == protocol && 168 if (sk && inet_sk(sk)->inet_num == protocol &&
169 (!sk->sk_bound_dev_if || 169 (!sk->sk_bound_dev_if ||
170 sk->sk_bound_dev_if == dev->ifindex) && 170 sk->sk_bound_dev_if == dev->ifindex)) {
171 net_eq(sock_net(sk), net)) {
172 if (ip_is_fragment(ip_hdr(skb))) { 171 if (ip_is_fragment(ip_hdr(skb))) {
173 if (ip_defrag(net, skb, IP_DEFRAG_CALL_RA_CHAIN)) 172 if (ip_defrag(net, skb, IP_DEFRAG_CALL_RA_CHAIN))
174 return true; 173 return true;
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 74c962b9b09c..5ad2d8ed3a3f 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -322,20 +322,6 @@ int ip_cmsg_send(struct sock *sk, struct msghdr *msg, struct ipcm_cookie *ipc,
322 return 0; 322 return 0;
323} 323}
324 324
325
326/* Special input handler for packets caught by router alert option.
327 They are selected only by protocol field, and then processed likely
328 local ones; but only if someone wants them! Otherwise, router
329 not running rsvpd will kill RSVP.
330
331 It is user level problem, what it will make with them.
332 I have no idea, how it will masquearde or NAT them (it is joke, joke :-)),
333 but receiver should be enough clever f.e. to forward mtrace requests,
334 sent to multicast group to reach destination designated router.
335 */
336struct ip_ra_chain __rcu *ip_ra_chain;
337
338
339static void ip_ra_destroy_rcu(struct rcu_head *head) 325static void ip_ra_destroy_rcu(struct rcu_head *head)
340{ 326{
341 struct ip_ra_chain *ra = container_of(head, struct ip_ra_chain, rcu); 327 struct ip_ra_chain *ra = container_of(head, struct ip_ra_chain, rcu);
@@ -349,23 +335,28 @@ int ip_ra_control(struct sock *sk, unsigned char on,
349{ 335{
350 struct ip_ra_chain *ra, *new_ra; 336 struct ip_ra_chain *ra, *new_ra;
351 struct ip_ra_chain __rcu **rap; 337 struct ip_ra_chain __rcu **rap;
338 struct net *net = sock_net(sk);
352 339
353 if (sk->sk_type != SOCK_RAW || inet_sk(sk)->inet_num == IPPROTO_RAW) 340 if (sk->sk_type != SOCK_RAW || inet_sk(sk)->inet_num == IPPROTO_RAW)
354 return -EINVAL; 341 return -EINVAL;
355 342
356 new_ra = on ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL; 343 new_ra = on ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL;
357 344
358 for (rap = &ip_ra_chain; 345 mutex_lock(&net->ipv4.ra_mutex);
359 (ra = rtnl_dereference(*rap)) != NULL; 346 for (rap = &net->ipv4.ra_chain;
347 (ra = rcu_dereference_protected(*rap,
348 lockdep_is_held(&net->ipv4.ra_mutex))) != NULL;
360 rap = &ra->next) { 349 rap = &ra->next) {
361 if (ra->sk == sk) { 350 if (ra->sk == sk) {
362 if (on) { 351 if (on) {
352 mutex_unlock(&net->ipv4.ra_mutex);
363 kfree(new_ra); 353 kfree(new_ra);
364 return -EADDRINUSE; 354 return -EADDRINUSE;
365 } 355 }
366 /* dont let ip_call_ra_chain() use sk again */ 356 /* dont let ip_call_ra_chain() use sk again */
367 ra->sk = NULL; 357 ra->sk = NULL;
368 RCU_INIT_POINTER(*rap, ra->next); 358 RCU_INIT_POINTER(*rap, ra->next);
359 mutex_unlock(&net->ipv4.ra_mutex);
369 360
370 if (ra->destructor) 361 if (ra->destructor)
371 ra->destructor(sk); 362 ra->destructor(sk);
@@ -379,14 +370,17 @@ int ip_ra_control(struct sock *sk, unsigned char on,
379 return 0; 370 return 0;
380 } 371 }
381 } 372 }
382 if (!new_ra) 373 if (!new_ra) {
374 mutex_unlock(&net->ipv4.ra_mutex);
383 return -ENOBUFS; 375 return -ENOBUFS;
376 }
384 new_ra->sk = sk; 377 new_ra->sk = sk;
385 new_ra->destructor = destructor; 378 new_ra->destructor = destructor;
386 379
387 RCU_INIT_POINTER(new_ra->next, ra); 380 RCU_INIT_POINTER(new_ra->next, ra);
388 rcu_assign_pointer(*rap, new_ra); 381 rcu_assign_pointer(*rap, new_ra);
389 sock_hold(sk); 382 sock_hold(sk);
383 mutex_unlock(&net->ipv4.ra_mutex);
390 384
391 return 0; 385 return 0;
392} 386}
@@ -586,7 +580,6 @@ static bool setsockopt_needs_rtnl(int optname)
586 case MCAST_LEAVE_GROUP: 580 case MCAST_LEAVE_GROUP:
587 case MCAST_LEAVE_SOURCE_GROUP: 581 case MCAST_LEAVE_SOURCE_GROUP:
588 case MCAST_UNBLOCK_SOURCE: 582 case MCAST_UNBLOCK_SOURCE:
589 case IP_ROUTER_ALERT:
590 return true; 583 return true;
591 } 584 }
592 return false; 585 return false;
@@ -639,6 +632,8 @@ static int do_ip_setsockopt(struct sock *sk, int level,
639 632
640 /* If optlen==0, it is equivalent to val == 0 */ 633 /* If optlen==0, it is equivalent to val == 0 */
641 634
635 if (optname == IP_ROUTER_ALERT)
636 return ip_ra_control(sk, val ? 1 : 0, NULL);
642 if (ip_mroute_opt(optname)) 637 if (ip_mroute_opt(optname))
643 return ip_mroute_setsockopt(sk, optname, optval, optlen); 638 return ip_mroute_setsockopt(sk, optname, optval, optlen);
644 639
@@ -1149,9 +1144,6 @@ mc_msf_out:
1149 goto e_inval; 1144 goto e_inval;
1150 inet->mc_all = val; 1145 inet->mc_all = val;
1151 break; 1146 break;
1152 case IP_ROUTER_ALERT:
1153 err = ip_ra_control(sk, val ? 1 : 0, NULL);
1154 break;
1155 1147
1156 case IP_FREEBIND: 1148 case IP_FREEBIND:
1157 if (optlen < 1) 1149 if (optlen < 1)
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
index 6d21068f9b55..5fcb17cb426b 100644
--- a/net/ipv4/ip_tunnel.c
+++ b/net/ipv4/ip_tunnel.c
@@ -290,22 +290,6 @@ failed:
290 return ERR_PTR(err); 290 return ERR_PTR(err);
291} 291}
292 292
293static inline void init_tunnel_flow(struct flowi4 *fl4,
294 int proto,
295 __be32 daddr, __be32 saddr,
296 __be32 key, __u8 tos, int oif,
297 __u32 mark)
298{
299 memset(fl4, 0, sizeof(*fl4));
300 fl4->flowi4_oif = oif;
301 fl4->daddr = daddr;
302 fl4->saddr = saddr;
303 fl4->flowi4_tos = tos;
304 fl4->flowi4_proto = proto;
305 fl4->fl4_gre_key = key;
306 fl4->flowi4_mark = mark;
307}
308
309static int ip_tunnel_bind_dev(struct net_device *dev) 293static int ip_tunnel_bind_dev(struct net_device *dev)
310{ 294{
311 struct net_device *tdev = NULL; 295 struct net_device *tdev = NULL;
@@ -322,10 +306,10 @@ static int ip_tunnel_bind_dev(struct net_device *dev)
322 struct flowi4 fl4; 306 struct flowi4 fl4;
323 struct rtable *rt; 307 struct rtable *rt;
324 308
325 init_tunnel_flow(&fl4, iph->protocol, iph->daddr, 309 ip_tunnel_init_flow(&fl4, iph->protocol, iph->daddr,
326 iph->saddr, tunnel->parms.o_key, 310 iph->saddr, tunnel->parms.o_key,
327 RT_TOS(iph->tos), tunnel->parms.link, 311 RT_TOS(iph->tos), tunnel->parms.link,
328 tunnel->fwmark); 312 tunnel->fwmark);
329 rt = ip_route_output_key(tunnel->net, &fl4); 313 rt = ip_route_output_key(tunnel->net, &fl4);
330 314
331 if (!IS_ERR(rt)) { 315 if (!IS_ERR(rt)) {
@@ -363,8 +347,7 @@ static struct ip_tunnel *ip_tunnel_create(struct net *net,
363 struct net_device *dev; 347 struct net_device *dev;
364 int t_hlen; 348 int t_hlen;
365 349
366 BUG_ON(!itn->fb_tunnel_dev); 350 dev = __ip_tunnel_create(net, itn->rtnl_link_ops, parms);
367 dev = __ip_tunnel_create(net, itn->fb_tunnel_dev->rtnl_link_ops, parms);
368 if (IS_ERR(dev)) 351 if (IS_ERR(dev))
369 return ERR_CAST(dev); 352 return ERR_CAST(dev);
370 353
@@ -581,8 +564,8 @@ void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, u8 proto)
581 else if (skb->protocol == htons(ETH_P_IPV6)) 564 else if (skb->protocol == htons(ETH_P_IPV6))
582 tos = ipv6_get_dsfield((const struct ipv6hdr *)inner_iph); 565 tos = ipv6_get_dsfield((const struct ipv6hdr *)inner_iph);
583 } 566 }
584 init_tunnel_flow(&fl4, proto, key->u.ipv4.dst, key->u.ipv4.src, 0, 567 ip_tunnel_init_flow(&fl4, proto, key->u.ipv4.dst, key->u.ipv4.src, 0,
585 RT_TOS(tos), tunnel->parms.link, tunnel->fwmark); 568 RT_TOS(tos), tunnel->parms.link, tunnel->fwmark);
586 if (tunnel->encap.type != TUNNEL_ENCAP_NONE) 569 if (tunnel->encap.type != TUNNEL_ENCAP_NONE)
587 goto tx_error; 570 goto tx_error;
588 rt = ip_route_output_key(tunnel->net, &fl4); 571 rt = ip_route_output_key(tunnel->net, &fl4);
@@ -710,9 +693,9 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
710 } 693 }
711 } 694 }
712 695
713 init_tunnel_flow(&fl4, protocol, dst, tnl_params->saddr, 696 ip_tunnel_init_flow(&fl4, protocol, dst, tnl_params->saddr,
714 tunnel->parms.o_key, RT_TOS(tos), tunnel->parms.link, 697 tunnel->parms.o_key, RT_TOS(tos), tunnel->parms.link,
715 tunnel->fwmark); 698 tunnel->fwmark);
716 699
717 if (ip_tunnel_encap(skb, tunnel, &protocol, &fl4) < 0) 700 if (ip_tunnel_encap(skb, tunnel, &protocol, &fl4) < 0)
718 goto tx_error; 701 goto tx_error;
@@ -838,7 +821,6 @@ int ip_tunnel_ioctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd)
838 struct net *net = t->net; 821 struct net *net = t->net;
839 struct ip_tunnel_net *itn = net_generic(net, t->ip_tnl_net_id); 822 struct ip_tunnel_net *itn = net_generic(net, t->ip_tnl_net_id);
840 823
841 BUG_ON(!itn->fb_tunnel_dev);
842 switch (cmd) { 824 switch (cmd) {
843 case SIOCGETTUNNEL: 825 case SIOCGETTUNNEL:
844 if (dev == itn->fb_tunnel_dev) { 826 if (dev == itn->fb_tunnel_dev) {
@@ -863,7 +845,7 @@ int ip_tunnel_ioctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd)
863 p->o_key = 0; 845 p->o_key = 0;
864 } 846 }
865 847
866 t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type); 848 t = ip_tunnel_find(itn, p, itn->type);
867 849
868 if (cmd == SIOCADDTUNNEL) { 850 if (cmd == SIOCADDTUNNEL) {
869 if (!t) { 851 if (!t) {
@@ -1007,10 +989,15 @@ int ip_tunnel_init_net(struct net *net, unsigned int ip_tnl_net_id,
1007 struct ip_tunnel_parm parms; 989 struct ip_tunnel_parm parms;
1008 unsigned int i; 990 unsigned int i;
1009 991
992 itn->rtnl_link_ops = ops;
1010 for (i = 0; i < IP_TNL_HASH_SIZE; i++) 993 for (i = 0; i < IP_TNL_HASH_SIZE; i++)
1011 INIT_HLIST_HEAD(&itn->tunnels[i]); 994 INIT_HLIST_HEAD(&itn->tunnels[i]);
1012 995
1013 if (!ops) { 996 if (!ops || !net_has_fallback_tunnels(net)) {
997 struct ip_tunnel_net *it_init_net;
998
999 it_init_net = net_generic(&init_net, ip_tnl_net_id);
1000 itn->type = it_init_net->type;
1014 itn->fb_tunnel_dev = NULL; 1001 itn->fb_tunnel_dev = NULL;
1015 return 0; 1002 return 0;
1016 } 1003 }
@@ -1028,6 +1015,7 @@ int ip_tunnel_init_net(struct net *net, unsigned int ip_tnl_net_id,
1028 itn->fb_tunnel_dev->features |= NETIF_F_NETNS_LOCAL; 1015 itn->fb_tunnel_dev->features |= NETIF_F_NETNS_LOCAL;
1029 itn->fb_tunnel_dev->mtu = ip_tunnel_bind_dev(itn->fb_tunnel_dev); 1016 itn->fb_tunnel_dev->mtu = ip_tunnel_bind_dev(itn->fb_tunnel_dev);
1030 ip_tunnel_add(itn, netdev_priv(itn->fb_tunnel_dev)); 1017 ip_tunnel_add(itn, netdev_priv(itn->fb_tunnel_dev));
1018 itn->type = itn->fb_tunnel_dev->type;
1031 } 1019 }
1032 rtnl_unlock(); 1020 rtnl_unlock();
1033 1021
@@ -1035,10 +1023,10 @@ int ip_tunnel_init_net(struct net *net, unsigned int ip_tnl_net_id,
1035} 1023}
1036EXPORT_SYMBOL_GPL(ip_tunnel_init_net); 1024EXPORT_SYMBOL_GPL(ip_tunnel_init_net);
1037 1025
1038static void ip_tunnel_destroy(struct ip_tunnel_net *itn, struct list_head *head, 1026static void ip_tunnel_destroy(struct net *net, struct ip_tunnel_net *itn,
1027 struct list_head *head,
1039 struct rtnl_link_ops *ops) 1028 struct rtnl_link_ops *ops)
1040{ 1029{
1041 struct net *net = dev_net(itn->fb_tunnel_dev);
1042 struct net_device *dev, *aux; 1030 struct net_device *dev, *aux;
1043 int h; 1031 int h;
1044 1032
@@ -1070,7 +1058,7 @@ void ip_tunnel_delete_nets(struct list_head *net_list, unsigned int id,
1070 rtnl_lock(); 1058 rtnl_lock();
1071 list_for_each_entry(net, net_list, exit_list) { 1059 list_for_each_entry(net, net_list, exit_list) {
1072 itn = net_generic(net, id); 1060 itn = net_generic(net, id);
1073 ip_tunnel_destroy(itn, &list, ops); 1061 ip_tunnel_destroy(net, itn, &list, ops);
1074 } 1062 }
1075 unregister_netdevice_many(&list); 1063 unregister_netdevice_many(&list);
1076 rtnl_unlock(); 1064 rtnl_unlock();
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c
index 51b1669334fe..b10bf563afd9 100644
--- a/net/ipv4/ip_vti.c
+++ b/net/ipv4/ip_vti.c
@@ -454,6 +454,7 @@ static struct pernet_operations vti_net_ops = {
454 .exit_batch = vti_exit_batch_net, 454 .exit_batch = vti_exit_batch_net,
455 .id = &vti_net_id, 455 .id = &vti_net_id,
456 .size = sizeof(struct ip_tunnel_net), 456 .size = sizeof(struct ip_tunnel_net),
457 .async = true,
457}; 458};
458 459
459static int vti_tunnel_validate(struct nlattr *tb[], struct nlattr *data[], 460static int vti_tunnel_validate(struct nlattr *tb[], struct nlattr *data[],
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index c891235b4966..9c5a4d164f09 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -669,6 +669,7 @@ static struct pernet_operations ipip_net_ops = {
669 .exit_batch = ipip_exit_batch_net, 669 .exit_batch = ipip_exit_batch_net,
670 .id = &ipip_net_id, 670 .id = &ipip_net_id,
671 .size = sizeof(struct ip_tunnel_net), 671 .size = sizeof(struct ip_tunnel_net),
672 .async = true,
672}; 673};
673 674
674static int __init ipip_init(void) 675static int __init ipip_init(void)
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index b05689bbba31..f6be5db16da2 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -28,9 +28,9 @@
28 28
29#include <linux/uaccess.h> 29#include <linux/uaccess.h>
30#include <linux/types.h> 30#include <linux/types.h>
31#include <linux/cache.h>
31#include <linux/capability.h> 32#include <linux/capability.h>
32#include <linux/errno.h> 33#include <linux/errno.h>
33#include <linux/timer.h>
34#include <linux/mm.h> 34#include <linux/mm.h>
35#include <linux/kernel.h> 35#include <linux/kernel.h>
36#include <linux/fcntl.h> 36#include <linux/fcntl.h>
@@ -52,7 +52,6 @@
52#include <net/protocol.h> 52#include <net/protocol.h>
53#include <linux/skbuff.h> 53#include <linux/skbuff.h>
54#include <net/route.h> 54#include <net/route.h>
55#include <net/sock.h>
56#include <net/icmp.h> 55#include <net/icmp.h>
57#include <net/udp.h> 56#include <net/udp.h>
58#include <net/raw.h> 57#include <net/raw.h>
@@ -96,7 +95,7 @@ static DEFINE_SPINLOCK(mfc_unres_lock);
96 * In this case data path is free of exclusive locks at all. 95 * In this case data path is free of exclusive locks at all.
97 */ 96 */
98 97
99static struct kmem_cache *mrt_cachep __read_mostly; 98static struct kmem_cache *mrt_cachep __ro_after_init;
100 99
101static struct mr_table *ipmr_new_table(struct net *net, u32 id); 100static struct mr_table *ipmr_new_table(struct net *net, u32 id);
102static void ipmr_free_table(struct mr_table *mrt); 101static void ipmr_free_table(struct mr_table *mrt);
@@ -106,8 +105,6 @@ static void ip_mr_forward(struct net *net, struct mr_table *mrt,
106 struct mfc_cache *cache, int local); 105 struct mfc_cache *cache, int local);
107static int ipmr_cache_report(struct mr_table *mrt, 106static int ipmr_cache_report(struct mr_table *mrt,
108 struct sk_buff *pkt, vifi_t vifi, int assert); 107 struct sk_buff *pkt, vifi_t vifi, int assert);
109static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
110 struct mfc_cache *c, struct rtmsg *rtm);
111static void mroute_netlink_event(struct mr_table *mrt, struct mfc_cache *mfc, 108static void mroute_netlink_event(struct mr_table *mrt, struct mfc_cache *mfc,
112 int cmd); 109 int cmd);
113static void igmpmsg_netlink_event(struct mr_table *mrt, struct sk_buff *pkt); 110static void igmpmsg_netlink_event(struct mr_table *mrt, struct sk_buff *pkt);
@@ -118,6 +115,23 @@ static void ipmr_expire_process(struct timer_list *t);
118#define ipmr_for_each_table(mrt, net) \ 115#define ipmr_for_each_table(mrt, net) \
119 list_for_each_entry_rcu(mrt, &net->ipv4.mr_tables, list) 116 list_for_each_entry_rcu(mrt, &net->ipv4.mr_tables, list)
120 117
118static struct mr_table *ipmr_mr_table_iter(struct net *net,
119 struct mr_table *mrt)
120{
121 struct mr_table *ret;
122
123 if (!mrt)
124 ret = list_entry_rcu(net->ipv4.mr_tables.next,
125 struct mr_table, list);
126 else
127 ret = list_entry_rcu(mrt->list.next,
128 struct mr_table, list);
129
130 if (&ret->list == &net->ipv4.mr_tables)
131 return NULL;
132 return ret;
133}
134
121static struct mr_table *ipmr_get_table(struct net *net, u32 id) 135static struct mr_table *ipmr_get_table(struct net *net, u32 id)
122{ 136{
123 struct mr_table *mrt; 137 struct mr_table *mrt;
@@ -285,6 +299,14 @@ EXPORT_SYMBOL(ipmr_rule_default);
285#define ipmr_for_each_table(mrt, net) \ 299#define ipmr_for_each_table(mrt, net) \
286 for (mrt = net->ipv4.mrt; mrt; mrt = NULL) 300 for (mrt = net->ipv4.mrt; mrt; mrt = NULL)
287 301
302static struct mr_table *ipmr_mr_table_iter(struct net *net,
303 struct mr_table *mrt)
304{
305 if (!mrt)
306 return net->ipv4.mrt;
307 return NULL;
308}
309
288static struct mr_table *ipmr_get_table(struct net *net, u32 id) 310static struct mr_table *ipmr_get_table(struct net *net, u32 id)
289{ 311{
290 return net->ipv4.mrt; 312 return net->ipv4.mrt;
@@ -344,7 +366,7 @@ static inline int ipmr_hash_cmp(struct rhashtable_compare_arg *arg,
344} 366}
345 367
346static const struct rhashtable_params ipmr_rht_params = { 368static const struct rhashtable_params ipmr_rht_params = {
347 .head_offset = offsetof(struct mfc_cache, mnode), 369 .head_offset = offsetof(struct mr_mfc, mnode),
348 .key_offset = offsetof(struct mfc_cache, cmparg), 370 .key_offset = offsetof(struct mfc_cache, cmparg),
349 .key_len = sizeof(struct mfc_cache_cmp_arg), 371 .key_len = sizeof(struct mfc_cache_cmp_arg),
350 .nelem_hint = 3, 372 .nelem_hint = 3,
@@ -353,6 +375,24 @@ static const struct rhashtable_params ipmr_rht_params = {
353 .automatic_shrinking = true, 375 .automatic_shrinking = true,
354}; 376};
355 377
378static void ipmr_new_table_set(struct mr_table *mrt,
379 struct net *net)
380{
381#ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES
382 list_add_tail_rcu(&mrt->list, &net->ipv4.mr_tables);
383#endif
384}
385
386static struct mfc_cache_cmp_arg ipmr_mr_table_ops_cmparg_any = {
387 .mfc_mcastgrp = htonl(INADDR_ANY),
388 .mfc_origin = htonl(INADDR_ANY),
389};
390
391static struct mr_table_ops ipmr_mr_table_ops = {
392 .rht_params = &ipmr_rht_params,
393 .cmparg_any = &ipmr_mr_table_ops_cmparg_any,
394};
395
356static struct mr_table *ipmr_new_table(struct net *net, u32 id) 396static struct mr_table *ipmr_new_table(struct net *net, u32 id)
357{ 397{
358 struct mr_table *mrt; 398 struct mr_table *mrt;
@@ -365,23 +405,8 @@ static struct mr_table *ipmr_new_table(struct net *net, u32 id)
365 if (mrt) 405 if (mrt)
366 return mrt; 406 return mrt;
367 407
368 mrt = kzalloc(sizeof(*mrt), GFP_KERNEL); 408 return mr_table_alloc(net, id, &ipmr_mr_table_ops,
369 if (!mrt) 409 ipmr_expire_process, ipmr_new_table_set);
370 return ERR_PTR(-ENOMEM);
371 write_pnet(&mrt->net, net);
372 mrt->id = id;
373
374 rhltable_init(&mrt->mfc_hash, &ipmr_rht_params);
375 INIT_LIST_HEAD(&mrt->mfc_cache_list);
376 INIT_LIST_HEAD(&mrt->mfc_unres_queue);
377
378 timer_setup(&mrt->ipmr_expire_timer, ipmr_expire_process, 0);
379
380 mrt->mroute_reg_vif_num = -1;
381#ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES
382 list_add_tail_rcu(&mrt->list, &net->ipv4.mr_tables);
383#endif
384 return mrt;
385} 410}
386 411
387static void ipmr_free_table(struct mr_table *mrt) 412static void ipmr_free_table(struct mr_table *mrt)
@@ -760,14 +785,14 @@ static int vif_delete(struct mr_table *mrt, int vifi, int notify,
760 785
761static void ipmr_cache_free_rcu(struct rcu_head *head) 786static void ipmr_cache_free_rcu(struct rcu_head *head)
762{ 787{
763 struct mfc_cache *c = container_of(head, struct mfc_cache, rcu); 788 struct mr_mfc *c = container_of(head, struct mr_mfc, rcu);
764 789
765 kmem_cache_free(mrt_cachep, c); 790 kmem_cache_free(mrt_cachep, (struct mfc_cache *)c);
766} 791}
767 792
768void ipmr_cache_free(struct mfc_cache *c) 793void ipmr_cache_free(struct mfc_cache *c)
769{ 794{
770 call_rcu(&c->rcu, ipmr_cache_free_rcu); 795 call_rcu(&c->_c.rcu, ipmr_cache_free_rcu);
771} 796}
772EXPORT_SYMBOL(ipmr_cache_free); 797EXPORT_SYMBOL(ipmr_cache_free);
773 798
@@ -782,7 +807,7 @@ static void ipmr_destroy_unres(struct mr_table *mrt, struct mfc_cache *c)
782 807
783 atomic_dec(&mrt->cache_resolve_queue_len); 808 atomic_dec(&mrt->cache_resolve_queue_len);
784 809
785 while ((skb = skb_dequeue(&c->mfc_un.unres.unresolved))) { 810 while ((skb = skb_dequeue(&c->_c.mfc_un.unres.unresolved))) {
786 if (ip_hdr(skb)->version == 0) { 811 if (ip_hdr(skb)->version == 0) {
787 struct nlmsghdr *nlh = skb_pull(skb, 812 struct nlmsghdr *nlh = skb_pull(skb,
788 sizeof(struct iphdr)); 813 sizeof(struct iphdr));
@@ -806,9 +831,9 @@ static void ipmr_destroy_unres(struct mr_table *mrt, struct mfc_cache *c)
806static void ipmr_expire_process(struct timer_list *t) 831static void ipmr_expire_process(struct timer_list *t)
807{ 832{
808 struct mr_table *mrt = from_timer(mrt, t, ipmr_expire_timer); 833 struct mr_table *mrt = from_timer(mrt, t, ipmr_expire_timer);
809 unsigned long now; 834 struct mr_mfc *c, *next;
810 unsigned long expires; 835 unsigned long expires;
811 struct mfc_cache *c, *next; 836 unsigned long now;
812 837
813 if (!spin_trylock(&mfc_unres_lock)) { 838 if (!spin_trylock(&mfc_unres_lock)) {
814 mod_timer(&mrt->ipmr_expire_timer, jiffies+HZ/10); 839 mod_timer(&mrt->ipmr_expire_timer, jiffies+HZ/10);
@@ -830,8 +855,8 @@ static void ipmr_expire_process(struct timer_list *t)
830 } 855 }
831 856
832 list_del(&c->list); 857 list_del(&c->list);
833 mroute_netlink_event(mrt, c, RTM_DELROUTE); 858 mroute_netlink_event(mrt, (struct mfc_cache *)c, RTM_DELROUTE);
834 ipmr_destroy_unres(mrt, c); 859 ipmr_destroy_unres(mrt, (struct mfc_cache *)c);
835 } 860 }
836 861
837 if (!list_empty(&mrt->mfc_unres_queue)) 862 if (!list_empty(&mrt->mfc_unres_queue))
@@ -842,7 +867,7 @@ out:
842} 867}
843 868
844/* Fill oifs list. It is called under write locked mrt_lock. */ 869/* Fill oifs list. It is called under write locked mrt_lock. */
845static void ipmr_update_thresholds(struct mr_table *mrt, struct mfc_cache *cache, 870static void ipmr_update_thresholds(struct mr_table *mrt, struct mr_mfc *cache,
846 unsigned char *ttls) 871 unsigned char *ttls)
847{ 872{
848 int vifi; 873 int vifi;
@@ -944,6 +969,10 @@ static int vif_add(struct net *net, struct mr_table *mrt,
944 ip_rt_multicast_event(in_dev); 969 ip_rt_multicast_event(in_dev);
945 970
946 /* Fill in the VIF structures */ 971 /* Fill in the VIF structures */
972 vif_device_init(v, dev, vifc->vifc_rate_limit,
973 vifc->vifc_threshold,
974 vifc->vifc_flags | (!mrtsock ? VIFF_STATIC : 0),
975 (VIFF_TUNNEL | VIFF_REGISTER));
947 976
948 attr.orig_dev = dev; 977 attr.orig_dev = dev;
949 if (!switchdev_port_attr_get(dev, &attr)) { 978 if (!switchdev_port_attr_get(dev, &attr)) {
@@ -952,20 +981,9 @@ static int vif_add(struct net *net, struct mr_table *mrt,
952 } else { 981 } else {
953 v->dev_parent_id.id_len = 0; 982 v->dev_parent_id.id_len = 0;
954 } 983 }
955 v->rate_limit = vifc->vifc_rate_limit; 984
956 v->local = vifc->vifc_lcl_addr.s_addr; 985 v->local = vifc->vifc_lcl_addr.s_addr;
957 v->remote = vifc->vifc_rmt_addr.s_addr; 986 v->remote = vifc->vifc_rmt_addr.s_addr;
958 v->flags = vifc->vifc_flags;
959 if (!mrtsock)
960 v->flags |= VIFF_STATIC;
961 v->threshold = vifc->vifc_threshold;
962 v->bytes_in = 0;
963 v->bytes_out = 0;
964 v->pkt_in = 0;
965 v->pkt_out = 0;
966 v->link = dev->ifindex;
967 if (v->flags & (VIFF_TUNNEL | VIFF_REGISTER))
968 v->link = dev_get_iflink(dev);
969 987
970 /* And finish update writing critical data */ 988 /* And finish update writing critical data */
971 write_lock_bh(&mrt_lock); 989 write_lock_bh(&mrt_lock);
@@ -988,33 +1006,8 @@ static struct mfc_cache *ipmr_cache_find(struct mr_table *mrt,
988 .mfc_mcastgrp = mcastgrp, 1006 .mfc_mcastgrp = mcastgrp,
989 .mfc_origin = origin 1007 .mfc_origin = origin
990 }; 1008 };
991 struct rhlist_head *tmp, *list;
992 struct mfc_cache *c;
993
994 list = rhltable_lookup(&mrt->mfc_hash, &arg, ipmr_rht_params);
995 rhl_for_each_entry_rcu(c, tmp, list, mnode)
996 return c;
997
998 return NULL;
999}
1000
1001/* Look for a (*,*,oif) entry */
1002static struct mfc_cache *ipmr_cache_find_any_parent(struct mr_table *mrt,
1003 int vifi)
1004{
1005 struct mfc_cache_cmp_arg arg = {
1006 .mfc_mcastgrp = htonl(INADDR_ANY),
1007 .mfc_origin = htonl(INADDR_ANY)
1008 };
1009 struct rhlist_head *tmp, *list;
1010 struct mfc_cache *c;
1011
1012 list = rhltable_lookup(&mrt->mfc_hash, &arg, ipmr_rht_params);
1013 rhl_for_each_entry_rcu(c, tmp, list, mnode)
1014 if (c->mfc_un.res.ttls[vifi] < 255)
1015 return c;
1016 1009
1017 return NULL; 1010 return mr_mfc_find(mrt, &arg);
1018} 1011}
1019 1012
1020/* Look for a (*,G) entry */ 1013/* Look for a (*,G) entry */
@@ -1025,25 +1018,10 @@ static struct mfc_cache *ipmr_cache_find_any(struct mr_table *mrt,
1025 .mfc_mcastgrp = mcastgrp, 1018 .mfc_mcastgrp = mcastgrp,
1026 .mfc_origin = htonl(INADDR_ANY) 1019 .mfc_origin = htonl(INADDR_ANY)
1027 }; 1020 };
1028 struct rhlist_head *tmp, *list;
1029 struct mfc_cache *c, *proxy;
1030 1021
1031 if (mcastgrp == htonl(INADDR_ANY)) 1022 if (mcastgrp == htonl(INADDR_ANY))
1032 goto skip; 1023 return mr_mfc_find_any_parent(mrt, vifi);
1033 1024 return mr_mfc_find_any(mrt, vifi, &arg);
1034 list = rhltable_lookup(&mrt->mfc_hash, &arg, ipmr_rht_params);
1035 rhl_for_each_entry_rcu(c, tmp, list, mnode) {
1036 if (c->mfc_un.res.ttls[vifi] < 255)
1037 return c;
1038
1039 /* It's ok if the vifi is part of the static tree */
1040 proxy = ipmr_cache_find_any_parent(mrt, c->mfc_parent);
1041 if (proxy && proxy->mfc_un.res.ttls[vifi] < 255)
1042 return c;
1043 }
1044
1045skip:
1046 return ipmr_cache_find_any_parent(mrt, vifi);
1047} 1025}
1048 1026
1049/* Look for a (S,G,iif) entry if parent != -1 */ 1027/* Look for a (S,G,iif) entry if parent != -1 */
@@ -1055,15 +1033,8 @@ static struct mfc_cache *ipmr_cache_find_parent(struct mr_table *mrt,
1055 .mfc_mcastgrp = mcastgrp, 1033 .mfc_mcastgrp = mcastgrp,
1056 .mfc_origin = origin, 1034 .mfc_origin = origin,
1057 }; 1035 };
1058 struct rhlist_head *tmp, *list;
1059 struct mfc_cache *c;
1060
1061 list = rhltable_lookup(&mrt->mfc_hash, &arg, ipmr_rht_params);
1062 rhl_for_each_entry_rcu(c, tmp, list, mnode)
1063 if (parent == -1 || parent == c->mfc_parent)
1064 return c;
1065 1036
1066 return NULL; 1037 return mr_mfc_find_parent(mrt, &arg, parent);
1067} 1038}
1068 1039
1069/* Allocate a multicast cache entry */ 1040/* Allocate a multicast cache entry */
@@ -1072,9 +1043,9 @@ static struct mfc_cache *ipmr_cache_alloc(void)
1072 struct mfc_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_KERNEL); 1043 struct mfc_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_KERNEL);
1073 1044
1074 if (c) { 1045 if (c) {
1075 c->mfc_un.res.last_assert = jiffies - MFC_ASSERT_THRESH - 1; 1046 c->_c.mfc_un.res.last_assert = jiffies - MFC_ASSERT_THRESH - 1;
1076 c->mfc_un.res.minvif = MAXVIFS; 1047 c->_c.mfc_un.res.minvif = MAXVIFS;
1077 refcount_set(&c->mfc_un.res.refcount, 1); 1048 refcount_set(&c->_c.mfc_un.res.refcount, 1);
1078 } 1049 }
1079 return c; 1050 return c;
1080} 1051}
@@ -1084,8 +1055,8 @@ static struct mfc_cache *ipmr_cache_alloc_unres(void)
1084 struct mfc_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_ATOMIC); 1055 struct mfc_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_ATOMIC);
1085 1056
1086 if (c) { 1057 if (c) {
1087 skb_queue_head_init(&c->mfc_un.unres.unresolved); 1058 skb_queue_head_init(&c->_c.mfc_un.unres.unresolved);
1088 c->mfc_un.unres.expires = jiffies + 10*HZ; 1059 c->_c.mfc_un.unres.expires = jiffies + 10 * HZ;
1089 } 1060 }
1090 return c; 1061 return c;
1091} 1062}
@@ -1098,12 +1069,13 @@ static void ipmr_cache_resolve(struct net *net, struct mr_table *mrt,
1098 struct nlmsgerr *e; 1069 struct nlmsgerr *e;
1099 1070
1100 /* Play the pending entries through our router */ 1071 /* Play the pending entries through our router */
1101 while ((skb = __skb_dequeue(&uc->mfc_un.unres.unresolved))) { 1072 while ((skb = __skb_dequeue(&uc->_c.mfc_un.unres.unresolved))) {
1102 if (ip_hdr(skb)->version == 0) { 1073 if (ip_hdr(skb)->version == 0) {
1103 struct nlmsghdr *nlh = skb_pull(skb, 1074 struct nlmsghdr *nlh = skb_pull(skb,
1104 sizeof(struct iphdr)); 1075 sizeof(struct iphdr));
1105 1076
1106 if (__ipmr_fill_mroute(mrt, skb, c, nlmsg_data(nlh)) > 0) { 1077 if (mr_fill_mroute(mrt, skb, &c->_c,
1078 nlmsg_data(nlh)) > 0) {
1107 nlh->nlmsg_len = skb_tail_pointer(skb) - 1079 nlh->nlmsg_len = skb_tail_pointer(skb) -
1108 (u8 *)nlh; 1080 (u8 *)nlh;
1109 } else { 1081 } else {
@@ -1211,7 +1183,7 @@ static int ipmr_cache_unresolved(struct mr_table *mrt, vifi_t vifi,
1211 int err; 1183 int err;
1212 1184
1213 spin_lock_bh(&mfc_unres_lock); 1185 spin_lock_bh(&mfc_unres_lock);
1214 list_for_each_entry(c, &mrt->mfc_unres_queue, list) { 1186 list_for_each_entry(c, &mrt->mfc_unres_queue, _c.list) {
1215 if (c->mfc_mcastgrp == iph->daddr && 1187 if (c->mfc_mcastgrp == iph->daddr &&
1216 c->mfc_origin == iph->saddr) { 1188 c->mfc_origin == iph->saddr) {
1217 found = true; 1189 found = true;
@@ -1230,12 +1202,13 @@ static int ipmr_cache_unresolved(struct mr_table *mrt, vifi_t vifi,
1230 } 1202 }
1231 1203
1232 /* Fill in the new cache entry */ 1204 /* Fill in the new cache entry */
1233 c->mfc_parent = -1; 1205 c->_c.mfc_parent = -1;
1234 c->mfc_origin = iph->saddr; 1206 c->mfc_origin = iph->saddr;
1235 c->mfc_mcastgrp = iph->daddr; 1207 c->mfc_mcastgrp = iph->daddr;
1236 1208
1237 /* Reflect first query at mrouted. */ 1209 /* Reflect first query at mrouted. */
1238 err = ipmr_cache_report(mrt, skb, vifi, IGMPMSG_NOCACHE); 1210 err = ipmr_cache_report(mrt, skb, vifi, IGMPMSG_NOCACHE);
1211
1239 if (err < 0) { 1212 if (err < 0) {
1240 /* If the report failed throw the cache entry 1213 /* If the report failed throw the cache entry
1241 out - Brad Parker 1214 out - Brad Parker
@@ -1248,15 +1221,16 @@ static int ipmr_cache_unresolved(struct mr_table *mrt, vifi_t vifi,
1248 } 1221 }
1249 1222
1250 atomic_inc(&mrt->cache_resolve_queue_len); 1223 atomic_inc(&mrt->cache_resolve_queue_len);
1251 list_add(&c->list, &mrt->mfc_unres_queue); 1224 list_add(&c->_c.list, &mrt->mfc_unres_queue);
1252 mroute_netlink_event(mrt, c, RTM_NEWROUTE); 1225 mroute_netlink_event(mrt, c, RTM_NEWROUTE);
1253 1226
1254 if (atomic_read(&mrt->cache_resolve_queue_len) == 1) 1227 if (atomic_read(&mrt->cache_resolve_queue_len) == 1)
1255 mod_timer(&mrt->ipmr_expire_timer, c->mfc_un.unres.expires); 1228 mod_timer(&mrt->ipmr_expire_timer,
1229 c->_c.mfc_un.unres.expires);
1256 } 1230 }
1257 1231
1258 /* See if we can append the packet */ 1232 /* See if we can append the packet */
1259 if (c->mfc_un.unres.unresolved.qlen > 3) { 1233 if (c->_c.mfc_un.unres.unresolved.qlen > 3) {
1260 kfree_skb(skb); 1234 kfree_skb(skb);
1261 err = -ENOBUFS; 1235 err = -ENOBUFS;
1262 } else { 1236 } else {
@@ -1264,7 +1238,7 @@ static int ipmr_cache_unresolved(struct mr_table *mrt, vifi_t vifi,
1264 skb->dev = dev; 1238 skb->dev = dev;
1265 skb->skb_iif = dev->ifindex; 1239 skb->skb_iif = dev->ifindex;
1266 } 1240 }
1267 skb_queue_tail(&c->mfc_un.unres.unresolved, skb); 1241 skb_queue_tail(&c->_c.mfc_un.unres.unresolved, skb);
1268 err = 0; 1242 err = 0;
1269 } 1243 }
1270 1244
@@ -1286,8 +1260,8 @@ static int ipmr_mfc_delete(struct mr_table *mrt, struct mfcctl *mfc, int parent)
1286 rcu_read_unlock(); 1260 rcu_read_unlock();
1287 if (!c) 1261 if (!c)
1288 return -ENOENT; 1262 return -ENOENT;
1289 rhltable_remove(&mrt->mfc_hash, &c->mnode, ipmr_rht_params); 1263 rhltable_remove(&mrt->mfc_hash, &c->_c.mnode, ipmr_rht_params);
1290 list_del_rcu(&c->list); 1264 list_del_rcu(&c->_c.list);
1291 call_ipmr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_DEL, c, mrt->id); 1265 call_ipmr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_DEL, c, mrt->id);
1292 mroute_netlink_event(mrt, c, RTM_DELROUTE); 1266 mroute_netlink_event(mrt, c, RTM_DELROUTE);
1293 ipmr_cache_put(c); 1267 ipmr_cache_put(c);
@@ -1299,6 +1273,7 @@ static int ipmr_mfc_add(struct net *net, struct mr_table *mrt,
1299 struct mfcctl *mfc, int mrtsock, int parent) 1273 struct mfcctl *mfc, int mrtsock, int parent)
1300{ 1274{
1301 struct mfc_cache *uc, *c; 1275 struct mfc_cache *uc, *c;
1276 struct mr_mfc *_uc;
1302 bool found; 1277 bool found;
1303 int ret; 1278 int ret;
1304 1279
@@ -1312,10 +1287,10 @@ static int ipmr_mfc_add(struct net *net, struct mr_table *mrt,
1312 rcu_read_unlock(); 1287 rcu_read_unlock();
1313 if (c) { 1288 if (c) {
1314 write_lock_bh(&mrt_lock); 1289 write_lock_bh(&mrt_lock);
1315 c->mfc_parent = mfc->mfcc_parent; 1290 c->_c.mfc_parent = mfc->mfcc_parent;
1316 ipmr_update_thresholds(mrt, c, mfc->mfcc_ttls); 1291 ipmr_update_thresholds(mrt, &c->_c, mfc->mfcc_ttls);
1317 if (!mrtsock) 1292 if (!mrtsock)
1318 c->mfc_flags |= MFC_STATIC; 1293 c->_c.mfc_flags |= MFC_STATIC;
1319 write_unlock_bh(&mrt_lock); 1294 write_unlock_bh(&mrt_lock);
1320 call_ipmr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_REPLACE, c, 1295 call_ipmr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_REPLACE, c,
1321 mrt->id); 1296 mrt->id);
@@ -1333,28 +1308,29 @@ static int ipmr_mfc_add(struct net *net, struct mr_table *mrt,
1333 1308
1334 c->mfc_origin = mfc->mfcc_origin.s_addr; 1309 c->mfc_origin = mfc->mfcc_origin.s_addr;
1335 c->mfc_mcastgrp = mfc->mfcc_mcastgrp.s_addr; 1310 c->mfc_mcastgrp = mfc->mfcc_mcastgrp.s_addr;
1336 c->mfc_parent = mfc->mfcc_parent; 1311 c->_c.mfc_parent = mfc->mfcc_parent;
1337 ipmr_update_thresholds(mrt, c, mfc->mfcc_ttls); 1312 ipmr_update_thresholds(mrt, &c->_c, mfc->mfcc_ttls);
1338 if (!mrtsock) 1313 if (!mrtsock)
1339 c->mfc_flags |= MFC_STATIC; 1314 c->_c.mfc_flags |= MFC_STATIC;
1340 1315
1341 ret = rhltable_insert_key(&mrt->mfc_hash, &c->cmparg, &c->mnode, 1316 ret = rhltable_insert_key(&mrt->mfc_hash, &c->cmparg, &c->_c.mnode,
1342 ipmr_rht_params); 1317 ipmr_rht_params);
1343 if (ret) { 1318 if (ret) {
1344 pr_err("ipmr: rhtable insert error %d\n", ret); 1319 pr_err("ipmr: rhtable insert error %d\n", ret);
1345 ipmr_cache_free(c); 1320 ipmr_cache_free(c);
1346 return ret; 1321 return ret;
1347 } 1322 }
1348 list_add_tail_rcu(&c->list, &mrt->mfc_cache_list); 1323 list_add_tail_rcu(&c->_c.list, &mrt->mfc_cache_list);
1349 /* Check to see if we resolved a queued list. If so we 1324 /* Check to see if we resolved a queued list. If so we
1350 * need to send on the frames and tidy up. 1325 * need to send on the frames and tidy up.
1351 */ 1326 */
1352 found = false; 1327 found = false;
1353 spin_lock_bh(&mfc_unres_lock); 1328 spin_lock_bh(&mfc_unres_lock);
1354 list_for_each_entry(uc, &mrt->mfc_unres_queue, list) { 1329 list_for_each_entry(_uc, &mrt->mfc_unres_queue, list) {
1330 uc = (struct mfc_cache *)_uc;
1355 if (uc->mfc_origin == c->mfc_origin && 1331 if (uc->mfc_origin == c->mfc_origin &&
1356 uc->mfc_mcastgrp == c->mfc_mcastgrp) { 1332 uc->mfc_mcastgrp == c->mfc_mcastgrp) {
1357 list_del(&uc->list); 1333 list_del(&_uc->list);
1358 atomic_dec(&mrt->cache_resolve_queue_len); 1334 atomic_dec(&mrt->cache_resolve_queue_len);
1359 found = true; 1335 found = true;
1360 break; 1336 break;
@@ -1377,7 +1353,8 @@ static int ipmr_mfc_add(struct net *net, struct mr_table *mrt,
1377static void mroute_clean_tables(struct mr_table *mrt, bool all) 1353static void mroute_clean_tables(struct mr_table *mrt, bool all)
1378{ 1354{
1379 struct net *net = read_pnet(&mrt->net); 1355 struct net *net = read_pnet(&mrt->net);
1380 struct mfc_cache *c, *tmp; 1356 struct mr_mfc *c, *tmp;
1357 struct mfc_cache *cache;
1381 LIST_HEAD(list); 1358 LIST_HEAD(list);
1382 int i; 1359 int i;
1383 1360
@@ -1395,18 +1372,20 @@ static void mroute_clean_tables(struct mr_table *mrt, bool all)
1395 continue; 1372 continue;
1396 rhltable_remove(&mrt->mfc_hash, &c->mnode, ipmr_rht_params); 1373 rhltable_remove(&mrt->mfc_hash, &c->mnode, ipmr_rht_params);
1397 list_del_rcu(&c->list); 1374 list_del_rcu(&c->list);
1398 call_ipmr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_DEL, c, 1375 cache = (struct mfc_cache *)c;
1376 call_ipmr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_DEL, cache,
1399 mrt->id); 1377 mrt->id);
1400 mroute_netlink_event(mrt, c, RTM_DELROUTE); 1378 mroute_netlink_event(mrt, cache, RTM_DELROUTE);
1401 ipmr_cache_put(c); 1379 ipmr_cache_put(cache);
1402 } 1380 }
1403 1381
1404 if (atomic_read(&mrt->cache_resolve_queue_len) != 0) { 1382 if (atomic_read(&mrt->cache_resolve_queue_len) != 0) {
1405 spin_lock_bh(&mfc_unres_lock); 1383 spin_lock_bh(&mfc_unres_lock);
1406 list_for_each_entry_safe(c, tmp, &mrt->mfc_unres_queue, list) { 1384 list_for_each_entry_safe(c, tmp, &mrt->mfc_unres_queue, list) {
1407 list_del(&c->list); 1385 list_del(&c->list);
1408 mroute_netlink_event(mrt, c, RTM_DELROUTE); 1386 cache = (struct mfc_cache *)c;
1409 ipmr_destroy_unres(mrt, c); 1387 mroute_netlink_event(mrt, cache, RTM_DELROUTE);
1388 ipmr_destroy_unres(mrt, cache);
1410 } 1389 }
1411 spin_unlock_bh(&mfc_unres_lock); 1390 spin_unlock_bh(&mfc_unres_lock);
1412 } 1391 }
@@ -1420,7 +1399,7 @@ static void mrtsock_destruct(struct sock *sk)
1420 struct net *net = sock_net(sk); 1399 struct net *net = sock_net(sk);
1421 struct mr_table *mrt; 1400 struct mr_table *mrt;
1422 1401
1423 ASSERT_RTNL(); 1402 rtnl_lock();
1424 ipmr_for_each_table(mrt, net) { 1403 ipmr_for_each_table(mrt, net) {
1425 if (sk == rtnl_dereference(mrt->mroute_sk)) { 1404 if (sk == rtnl_dereference(mrt->mroute_sk)) {
1426 IPV4_DEVCONF_ALL(net, MC_FORWARDING)--; 1405 IPV4_DEVCONF_ALL(net, MC_FORWARDING)--;
@@ -1432,6 +1411,7 @@ static void mrtsock_destruct(struct sock *sk)
1432 mroute_clean_tables(mrt, false); 1411 mroute_clean_tables(mrt, false);
1433 } 1412 }
1434 } 1413 }
1414 rtnl_unlock();
1435} 1415}
1436 1416
1437/* Socket options and virtual interface manipulation. The whole 1417/* Socket options and virtual interface manipulation. The whole
@@ -1496,8 +1476,13 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval,
1496 if (sk != rcu_access_pointer(mrt->mroute_sk)) { 1476 if (sk != rcu_access_pointer(mrt->mroute_sk)) {
1497 ret = -EACCES; 1477 ret = -EACCES;
1498 } else { 1478 } else {
1479 /* We need to unlock here because mrtsock_destruct takes
1480 * care of rtnl itself and we can't change that due to
1481 * the IP_ROUTER_ALERT setsockopt which runs without it.
1482 */
1483 rtnl_unlock();
1499 ret = ip_ra_control(sk, 0, NULL); 1484 ret = ip_ra_control(sk, 0, NULL);
1500 goto out_unlock; 1485 goto out;
1501 } 1486 }
1502 break; 1487 break;
1503 case MRT_ADD_VIF: 1488 case MRT_ADD_VIF:
@@ -1609,6 +1594,7 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval,
1609 } 1594 }
1610out_unlock: 1595out_unlock:
1611 rtnl_unlock(); 1596 rtnl_unlock();
1597out:
1612 return ret; 1598 return ret;
1613} 1599}
1614 1600
@@ -1698,9 +1684,9 @@ int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg)
1698 rcu_read_lock(); 1684 rcu_read_lock();
1699 c = ipmr_cache_find(mrt, sr.src.s_addr, sr.grp.s_addr); 1685 c = ipmr_cache_find(mrt, sr.src.s_addr, sr.grp.s_addr);
1700 if (c) { 1686 if (c) {
1701 sr.pktcnt = c->mfc_un.res.pkt; 1687 sr.pktcnt = c->_c.mfc_un.res.pkt;
1702 sr.bytecnt = c->mfc_un.res.bytes; 1688 sr.bytecnt = c->_c.mfc_un.res.bytes;
1703 sr.wrong_if = c->mfc_un.res.wrong_if; 1689 sr.wrong_if = c->_c.mfc_un.res.wrong_if;
1704 rcu_read_unlock(); 1690 rcu_read_unlock();
1705 1691
1706 if (copy_to_user(arg, &sr, sizeof(sr))) 1692 if (copy_to_user(arg, &sr, sizeof(sr)))
@@ -1772,9 +1758,9 @@ int ipmr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg)
1772 rcu_read_lock(); 1758 rcu_read_lock();
1773 c = ipmr_cache_find(mrt, sr.src.s_addr, sr.grp.s_addr); 1759 c = ipmr_cache_find(mrt, sr.src.s_addr, sr.grp.s_addr);
1774 if (c) { 1760 if (c) {
1775 sr.pktcnt = c->mfc_un.res.pkt; 1761 sr.pktcnt = c->_c.mfc_un.res.pkt;
1776 sr.bytecnt = c->mfc_un.res.bytes; 1762 sr.bytecnt = c->_c.mfc_un.res.bytes;
1777 sr.wrong_if = c->mfc_un.res.wrong_if; 1763 sr.wrong_if = c->_c.mfc_un.res.wrong_if;
1778 rcu_read_unlock(); 1764 rcu_read_unlock();
1779 1765
1780 if (copy_to_user(arg, &sr, sizeof(sr))) 1766 if (copy_to_user(arg, &sr, sizeof(sr)))
@@ -1998,26 +1984,26 @@ static int ipmr_find_vif(struct mr_table *mrt, struct net_device *dev)
1998/* "local" means that we should preserve one skb (for local delivery) */ 1984/* "local" means that we should preserve one skb (for local delivery) */
1999static void ip_mr_forward(struct net *net, struct mr_table *mrt, 1985static void ip_mr_forward(struct net *net, struct mr_table *mrt,
2000 struct net_device *dev, struct sk_buff *skb, 1986 struct net_device *dev, struct sk_buff *skb,
2001 struct mfc_cache *cache, int local) 1987 struct mfc_cache *c, int local)
2002{ 1988{
2003 int true_vifi = ipmr_find_vif(mrt, dev); 1989 int true_vifi = ipmr_find_vif(mrt, dev);
2004 int psend = -1; 1990 int psend = -1;
2005 int vif, ct; 1991 int vif, ct;
2006 1992
2007 vif = cache->mfc_parent; 1993 vif = c->_c.mfc_parent;
2008 cache->mfc_un.res.pkt++; 1994 c->_c.mfc_un.res.pkt++;
2009 cache->mfc_un.res.bytes += skb->len; 1995 c->_c.mfc_un.res.bytes += skb->len;
2010 cache->mfc_un.res.lastuse = jiffies; 1996 c->_c.mfc_un.res.lastuse = jiffies;
2011 1997
2012 if (cache->mfc_origin == htonl(INADDR_ANY) && true_vifi >= 0) { 1998 if (c->mfc_origin == htonl(INADDR_ANY) && true_vifi >= 0) {
2013 struct mfc_cache *cache_proxy; 1999 struct mfc_cache *cache_proxy;
2014 2000
2015 /* For an (*,G) entry, we only check that the incomming 2001 /* For an (*,G) entry, we only check that the incomming
2016 * interface is part of the static tree. 2002 * interface is part of the static tree.
2017 */ 2003 */
2018 cache_proxy = ipmr_cache_find_any_parent(mrt, vif); 2004 cache_proxy = mr_mfc_find_any_parent(mrt, vif);
2019 if (cache_proxy && 2005 if (cache_proxy &&
2020 cache_proxy->mfc_un.res.ttls[true_vifi] < 255) 2006 cache_proxy->_c.mfc_un.res.ttls[true_vifi] < 255)
2021 goto forward; 2007 goto forward;
2022 } 2008 }
2023 2009
@@ -2038,7 +2024,7 @@ static void ip_mr_forward(struct net *net, struct mr_table *mrt,
2038 goto dont_forward; 2024 goto dont_forward;
2039 } 2025 }
2040 2026
2041 cache->mfc_un.res.wrong_if++; 2027 c->_c.mfc_un.res.wrong_if++;
2042 2028
2043 if (true_vifi >= 0 && mrt->mroute_do_assert && 2029 if (true_vifi >= 0 && mrt->mroute_do_assert &&
2044 /* pimsm uses asserts, when switching from RPT to SPT, 2030 /* pimsm uses asserts, when switching from RPT to SPT,
@@ -2047,10 +2033,11 @@ static void ip_mr_forward(struct net *net, struct mr_table *mrt,
2047 * large chunk of pimd to kernel. Ough... --ANK 2033 * large chunk of pimd to kernel. Ough... --ANK
2048 */ 2034 */
2049 (mrt->mroute_do_pim || 2035 (mrt->mroute_do_pim ||
2050 cache->mfc_un.res.ttls[true_vifi] < 255) && 2036 c->_c.mfc_un.res.ttls[true_vifi] < 255) &&
2051 time_after(jiffies, 2037 time_after(jiffies,
2052 cache->mfc_un.res.last_assert + MFC_ASSERT_THRESH)) { 2038 c->_c.mfc_un.res.last_assert +
2053 cache->mfc_un.res.last_assert = jiffies; 2039 MFC_ASSERT_THRESH)) {
2040 c->_c.mfc_un.res.last_assert = jiffies;
2054 ipmr_cache_report(mrt, skb, true_vifi, IGMPMSG_WRONGVIF); 2041 ipmr_cache_report(mrt, skb, true_vifi, IGMPMSG_WRONGVIF);
2055 } 2042 }
2056 goto dont_forward; 2043 goto dont_forward;
@@ -2061,33 +2048,33 @@ forward:
2061 mrt->vif_table[vif].bytes_in += skb->len; 2048 mrt->vif_table[vif].bytes_in += skb->len;
2062 2049
2063 /* Forward the frame */ 2050 /* Forward the frame */
2064 if (cache->mfc_origin == htonl(INADDR_ANY) && 2051 if (c->mfc_origin == htonl(INADDR_ANY) &&
2065 cache->mfc_mcastgrp == htonl(INADDR_ANY)) { 2052 c->mfc_mcastgrp == htonl(INADDR_ANY)) {
2066 if (true_vifi >= 0 && 2053 if (true_vifi >= 0 &&
2067 true_vifi != cache->mfc_parent && 2054 true_vifi != c->_c.mfc_parent &&
2068 ip_hdr(skb)->ttl > 2055 ip_hdr(skb)->ttl >
2069 cache->mfc_un.res.ttls[cache->mfc_parent]) { 2056 c->_c.mfc_un.res.ttls[c->_c.mfc_parent]) {
2070 /* It's an (*,*) entry and the packet is not coming from 2057 /* It's an (*,*) entry and the packet is not coming from
2071 * the upstream: forward the packet to the upstream 2058 * the upstream: forward the packet to the upstream
2072 * only. 2059 * only.
2073 */ 2060 */
2074 psend = cache->mfc_parent; 2061 psend = c->_c.mfc_parent;
2075 goto last_forward; 2062 goto last_forward;
2076 } 2063 }
2077 goto dont_forward; 2064 goto dont_forward;
2078 } 2065 }
2079 for (ct = cache->mfc_un.res.maxvif - 1; 2066 for (ct = c->_c.mfc_un.res.maxvif - 1;
2080 ct >= cache->mfc_un.res.minvif; ct--) { 2067 ct >= c->_c.mfc_un.res.minvif; ct--) {
2081 /* For (*,G) entry, don't forward to the incoming interface */ 2068 /* For (*,G) entry, don't forward to the incoming interface */
2082 if ((cache->mfc_origin != htonl(INADDR_ANY) || 2069 if ((c->mfc_origin != htonl(INADDR_ANY) ||
2083 ct != true_vifi) && 2070 ct != true_vifi) &&
2084 ip_hdr(skb)->ttl > cache->mfc_un.res.ttls[ct]) { 2071 ip_hdr(skb)->ttl > c->_c.mfc_un.res.ttls[ct]) {
2085 if (psend != -1) { 2072 if (psend != -1) {
2086 struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); 2073 struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
2087 2074
2088 if (skb2) 2075 if (skb2)
2089 ipmr_queue_xmit(net, mrt, true_vifi, 2076 ipmr_queue_xmit(net, mrt, true_vifi,
2090 skb2, cache, psend); 2077 skb2, c, psend);
2091 } 2078 }
2092 psend = ct; 2079 psend = ct;
2093 } 2080 }
@@ -2099,9 +2086,9 @@ last_forward:
2099 2086
2100 if (skb2) 2087 if (skb2)
2101 ipmr_queue_xmit(net, mrt, true_vifi, skb2, 2088 ipmr_queue_xmit(net, mrt, true_vifi, skb2,
2102 cache, psend); 2089 c, psend);
2103 } else { 2090 } else {
2104 ipmr_queue_xmit(net, mrt, true_vifi, skb, cache, psend); 2091 ipmr_queue_xmit(net, mrt, true_vifi, skb, c, psend);
2105 return; 2092 return;
2106 } 2093 }
2107 } 2094 }
@@ -2299,62 +2286,6 @@ drop:
2299} 2286}
2300#endif 2287#endif
2301 2288
2302static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
2303 struct mfc_cache *c, struct rtmsg *rtm)
2304{
2305 struct rta_mfc_stats mfcs;
2306 struct nlattr *mp_attr;
2307 struct rtnexthop *nhp;
2308 unsigned long lastuse;
2309 int ct;
2310
2311 /* If cache is unresolved, don't try to parse IIF and OIF */
2312 if (c->mfc_parent >= MAXVIFS) {
2313 rtm->rtm_flags |= RTNH_F_UNRESOLVED;
2314 return -ENOENT;
2315 }
2316
2317 if (VIF_EXISTS(mrt, c->mfc_parent) &&
2318 nla_put_u32(skb, RTA_IIF, mrt->vif_table[c->mfc_parent].dev->ifindex) < 0)
2319 return -EMSGSIZE;
2320
2321 if (c->mfc_flags & MFC_OFFLOAD)
2322 rtm->rtm_flags |= RTNH_F_OFFLOAD;
2323
2324 if (!(mp_attr = nla_nest_start(skb, RTA_MULTIPATH)))
2325 return -EMSGSIZE;
2326
2327 for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) {
2328 if (VIF_EXISTS(mrt, ct) && c->mfc_un.res.ttls[ct] < 255) {
2329 if (!(nhp = nla_reserve_nohdr(skb, sizeof(*nhp)))) {
2330 nla_nest_cancel(skb, mp_attr);
2331 return -EMSGSIZE;
2332 }
2333
2334 nhp->rtnh_flags = 0;
2335 nhp->rtnh_hops = c->mfc_un.res.ttls[ct];
2336 nhp->rtnh_ifindex = mrt->vif_table[ct].dev->ifindex;
2337 nhp->rtnh_len = sizeof(*nhp);
2338 }
2339 }
2340
2341 nla_nest_end(skb, mp_attr);
2342
2343 lastuse = READ_ONCE(c->mfc_un.res.lastuse);
2344 lastuse = time_after_eq(jiffies, lastuse) ? jiffies - lastuse : 0;
2345
2346 mfcs.mfcs_packets = c->mfc_un.res.pkt;
2347 mfcs.mfcs_bytes = c->mfc_un.res.bytes;
2348 mfcs.mfcs_wrong_if = c->mfc_un.res.wrong_if;
2349 if (nla_put_64bit(skb, RTA_MFC_STATS, sizeof(mfcs), &mfcs, RTA_PAD) ||
2350 nla_put_u64_64bit(skb, RTA_EXPIRES, jiffies_to_clock_t(lastuse),
2351 RTA_PAD))
2352 return -EMSGSIZE;
2353
2354 rtm->rtm_type = RTN_MULTICAST;
2355 return 1;
2356}
2357
2358int ipmr_get_route(struct net *net, struct sk_buff *skb, 2289int ipmr_get_route(struct net *net, struct sk_buff *skb,
2359 __be32 saddr, __be32 daddr, 2290 __be32 saddr, __be32 daddr,
2360 struct rtmsg *rtm, u32 portid) 2291 struct rtmsg *rtm, u32 portid)
@@ -2412,7 +2343,7 @@ int ipmr_get_route(struct net *net, struct sk_buff *skb,
2412 } 2343 }
2413 2344
2414 read_lock(&mrt_lock); 2345 read_lock(&mrt_lock);
2415 err = __ipmr_fill_mroute(mrt, skb, cache, rtm); 2346 err = mr_fill_mroute(mrt, skb, &cache->_c, rtm);
2416 read_unlock(&mrt_lock); 2347 read_unlock(&mrt_lock);
2417 rcu_read_unlock(); 2348 rcu_read_unlock();
2418 return err; 2349 return err;
@@ -2440,7 +2371,7 @@ static int ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
2440 goto nla_put_failure; 2371 goto nla_put_failure;
2441 rtm->rtm_type = RTN_MULTICAST; 2372 rtm->rtm_type = RTN_MULTICAST;
2442 rtm->rtm_scope = RT_SCOPE_UNIVERSE; 2373 rtm->rtm_scope = RT_SCOPE_UNIVERSE;
2443 if (c->mfc_flags & MFC_STATIC) 2374 if (c->_c.mfc_flags & MFC_STATIC)
2444 rtm->rtm_protocol = RTPROT_STATIC; 2375 rtm->rtm_protocol = RTPROT_STATIC;
2445 else 2376 else
2446 rtm->rtm_protocol = RTPROT_MROUTED; 2377 rtm->rtm_protocol = RTPROT_MROUTED;
@@ -2449,7 +2380,7 @@ static int ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
2449 if (nla_put_in_addr(skb, RTA_SRC, c->mfc_origin) || 2380 if (nla_put_in_addr(skb, RTA_SRC, c->mfc_origin) ||
2450 nla_put_in_addr(skb, RTA_DST, c->mfc_mcastgrp)) 2381 nla_put_in_addr(skb, RTA_DST, c->mfc_mcastgrp))
2451 goto nla_put_failure; 2382 goto nla_put_failure;
2452 err = __ipmr_fill_mroute(mrt, skb, c, rtm); 2383 err = mr_fill_mroute(mrt, skb, &c->_c, rtm);
2453 /* do not break the dump if cache is unresolved */ 2384 /* do not break the dump if cache is unresolved */
2454 if (err < 0 && err != -ENOENT) 2385 if (err < 0 && err != -ENOENT)
2455 goto nla_put_failure; 2386 goto nla_put_failure;
@@ -2462,6 +2393,14 @@ nla_put_failure:
2462 return -EMSGSIZE; 2393 return -EMSGSIZE;
2463} 2394}
2464 2395
2396static int _ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
2397 u32 portid, u32 seq, struct mr_mfc *c, int cmd,
2398 int flags)
2399{
2400 return ipmr_fill_mroute(mrt, skb, portid, seq, (struct mfc_cache *)c,
2401 cmd, flags);
2402}
2403
2465static size_t mroute_msgsize(bool unresolved, int maxvif) 2404static size_t mroute_msgsize(bool unresolved, int maxvif)
2466{ 2405{
2467 size_t len = 2406 size_t len =
@@ -2490,7 +2429,8 @@ static void mroute_netlink_event(struct mr_table *mrt, struct mfc_cache *mfc,
2490 struct sk_buff *skb; 2429 struct sk_buff *skb;
2491 int err = -ENOBUFS; 2430 int err = -ENOBUFS;
2492 2431
2493 skb = nlmsg_new(mroute_msgsize(mfc->mfc_parent >= MAXVIFS, mrt->maxvif), 2432 skb = nlmsg_new(mroute_msgsize(mfc->_c.mfc_parent >= MAXVIFS,
2433 mrt->maxvif),
2494 GFP_ATOMIC); 2434 GFP_ATOMIC);
2495 if (!skb) 2435 if (!skb)
2496 goto errout; 2436 goto errout;
@@ -2634,62 +2574,8 @@ errout_free:
2634 2574
2635static int ipmr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb) 2575static int ipmr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb)
2636{ 2576{
2637 struct net *net = sock_net(skb->sk); 2577 return mr_rtm_dumproute(skb, cb, ipmr_mr_table_iter,
2638 struct mr_table *mrt; 2578 _ipmr_fill_mroute, &mfc_unres_lock);
2639 struct mfc_cache *mfc;
2640 unsigned int t = 0, s_t;
2641 unsigned int e = 0, s_e;
2642
2643 s_t = cb->args[0];
2644 s_e = cb->args[1];
2645
2646 rcu_read_lock();
2647 ipmr_for_each_table(mrt, net) {
2648 if (t < s_t)
2649 goto next_table;
2650 list_for_each_entry_rcu(mfc, &mrt->mfc_cache_list, list) {
2651 if (e < s_e)
2652 goto next_entry;
2653 if (ipmr_fill_mroute(mrt, skb,
2654 NETLINK_CB(cb->skb).portid,
2655 cb->nlh->nlmsg_seq,
2656 mfc, RTM_NEWROUTE,
2657 NLM_F_MULTI) < 0)
2658 goto done;
2659next_entry:
2660 e++;
2661 }
2662 e = 0;
2663 s_e = 0;
2664
2665 spin_lock_bh(&mfc_unres_lock);
2666 list_for_each_entry(mfc, &mrt->mfc_unres_queue, list) {
2667 if (e < s_e)
2668 goto next_entry2;
2669 if (ipmr_fill_mroute(mrt, skb,
2670 NETLINK_CB(cb->skb).portid,
2671 cb->nlh->nlmsg_seq,
2672 mfc, RTM_NEWROUTE,
2673 NLM_F_MULTI) < 0) {
2674 spin_unlock_bh(&mfc_unres_lock);
2675 goto done;
2676 }
2677next_entry2:
2678 e++;
2679 }
2680 spin_unlock_bh(&mfc_unres_lock);
2681 e = 0;
2682 s_e = 0;
2683next_table:
2684 t++;
2685 }
2686done:
2687 rcu_read_unlock();
2688
2689 cb->args[1] = e;
2690 cb->args[0] = t;
2691
2692 return skb->len;
2693} 2579}
2694 2580
2695static const struct nla_policy rtm_ipmr_policy[RTA_MAX + 1] = { 2581static const struct nla_policy rtm_ipmr_policy[RTA_MAX + 1] = {
@@ -2946,31 +2832,11 @@ out:
2946/* The /proc interfaces to multicast routing : 2832/* The /proc interfaces to multicast routing :
2947 * /proc/net/ip_mr_cache & /proc/net/ip_mr_vif 2833 * /proc/net/ip_mr_cache & /proc/net/ip_mr_vif
2948 */ 2834 */
2949struct ipmr_vif_iter {
2950 struct seq_net_private p;
2951 struct mr_table *mrt;
2952 int ct;
2953};
2954
2955static struct vif_device *ipmr_vif_seq_idx(struct net *net,
2956 struct ipmr_vif_iter *iter,
2957 loff_t pos)
2958{
2959 struct mr_table *mrt = iter->mrt;
2960
2961 for (iter->ct = 0; iter->ct < mrt->maxvif; ++iter->ct) {
2962 if (!VIF_EXISTS(mrt, iter->ct))
2963 continue;
2964 if (pos-- == 0)
2965 return &mrt->vif_table[iter->ct];
2966 }
2967 return NULL;
2968}
2969 2835
2970static void *ipmr_vif_seq_start(struct seq_file *seq, loff_t *pos) 2836static void *ipmr_vif_seq_start(struct seq_file *seq, loff_t *pos)
2971 __acquires(mrt_lock) 2837 __acquires(mrt_lock)
2972{ 2838{
2973 struct ipmr_vif_iter *iter = seq->private; 2839 struct mr_vif_iter *iter = seq->private;
2974 struct net *net = seq_file_net(seq); 2840 struct net *net = seq_file_net(seq);
2975 struct mr_table *mrt; 2841 struct mr_table *mrt;
2976 2842
@@ -2981,26 +2847,7 @@ static void *ipmr_vif_seq_start(struct seq_file *seq, loff_t *pos)
2981 iter->mrt = mrt; 2847 iter->mrt = mrt;
2982 2848
2983 read_lock(&mrt_lock); 2849 read_lock(&mrt_lock);
2984 return *pos ? ipmr_vif_seq_idx(net, seq->private, *pos - 1) 2850 return mr_vif_seq_start(seq, pos);
2985 : SEQ_START_TOKEN;
2986}
2987
2988static void *ipmr_vif_seq_next(struct seq_file *seq, void *v, loff_t *pos)
2989{
2990 struct ipmr_vif_iter *iter = seq->private;
2991 struct net *net = seq_file_net(seq);
2992 struct mr_table *mrt = iter->mrt;
2993
2994 ++*pos;
2995 if (v == SEQ_START_TOKEN)
2996 return ipmr_vif_seq_idx(net, iter, 0);
2997
2998 while (++iter->ct < mrt->maxvif) {
2999 if (!VIF_EXISTS(mrt, iter->ct))
3000 continue;
3001 return &mrt->vif_table[iter->ct];
3002 }
3003 return NULL;
3004} 2851}
3005 2852
3006static void ipmr_vif_seq_stop(struct seq_file *seq, void *v) 2853static void ipmr_vif_seq_stop(struct seq_file *seq, void *v)
@@ -3011,7 +2858,7 @@ static void ipmr_vif_seq_stop(struct seq_file *seq, void *v)
3011 2858
3012static int ipmr_vif_seq_show(struct seq_file *seq, void *v) 2859static int ipmr_vif_seq_show(struct seq_file *seq, void *v)
3013{ 2860{
3014 struct ipmr_vif_iter *iter = seq->private; 2861 struct mr_vif_iter *iter = seq->private;
3015 struct mr_table *mrt = iter->mrt; 2862 struct mr_table *mrt = iter->mrt;
3016 2863
3017 if (v == SEQ_START_TOKEN) { 2864 if (v == SEQ_START_TOKEN) {
@@ -3019,7 +2866,8 @@ static int ipmr_vif_seq_show(struct seq_file *seq, void *v)
3019 "Interface BytesIn PktsIn BytesOut PktsOut Flags Local Remote\n"); 2866 "Interface BytesIn PktsIn BytesOut PktsOut Flags Local Remote\n");
3020 } else { 2867 } else {
3021 const struct vif_device *vif = v; 2868 const struct vif_device *vif = v;
3022 const char *name = vif->dev ? vif->dev->name : "none"; 2869 const char *name = vif->dev ?
2870 vif->dev->name : "none";
3023 2871
3024 seq_printf(seq, 2872 seq_printf(seq,
3025 "%2td %-10s %8ld %7ld %8ld %7ld %05X %08X %08X\n", 2873 "%2td %-10s %8ld %7ld %8ld %7ld %05X %08X %08X\n",
@@ -3033,7 +2881,7 @@ static int ipmr_vif_seq_show(struct seq_file *seq, void *v)
3033 2881
3034static const struct seq_operations ipmr_vif_seq_ops = { 2882static const struct seq_operations ipmr_vif_seq_ops = {
3035 .start = ipmr_vif_seq_start, 2883 .start = ipmr_vif_seq_start,
3036 .next = ipmr_vif_seq_next, 2884 .next = mr_vif_seq_next,
3037 .stop = ipmr_vif_seq_stop, 2885 .stop = ipmr_vif_seq_stop,
3038 .show = ipmr_vif_seq_show, 2886 .show = ipmr_vif_seq_show,
3039}; 2887};
@@ -3041,7 +2889,7 @@ static const struct seq_operations ipmr_vif_seq_ops = {
3041static int ipmr_vif_open(struct inode *inode, struct file *file) 2889static int ipmr_vif_open(struct inode *inode, struct file *file)
3042{ 2890{
3043 return seq_open_net(inode, file, &ipmr_vif_seq_ops, 2891 return seq_open_net(inode, file, &ipmr_vif_seq_ops,
3044 sizeof(struct ipmr_vif_iter)); 2892 sizeof(struct mr_vif_iter));
3045} 2893}
3046 2894
3047static const struct file_operations ipmr_vif_fops = { 2895static const struct file_operations ipmr_vif_fops = {
@@ -3051,40 +2899,8 @@ static const struct file_operations ipmr_vif_fops = {
3051 .release = seq_release_net, 2899 .release = seq_release_net,
3052}; 2900};
3053 2901
3054struct ipmr_mfc_iter {
3055 struct seq_net_private p;
3056 struct mr_table *mrt;
3057 struct list_head *cache;
3058};
3059
3060static struct mfc_cache *ipmr_mfc_seq_idx(struct net *net,
3061 struct ipmr_mfc_iter *it, loff_t pos)
3062{
3063 struct mr_table *mrt = it->mrt;
3064 struct mfc_cache *mfc;
3065
3066 rcu_read_lock();
3067 it->cache = &mrt->mfc_cache_list;
3068 list_for_each_entry_rcu(mfc, &mrt->mfc_cache_list, list)
3069 if (pos-- == 0)
3070 return mfc;
3071 rcu_read_unlock();
3072
3073 spin_lock_bh(&mfc_unres_lock);
3074 it->cache = &mrt->mfc_unres_queue;
3075 list_for_each_entry(mfc, it->cache, list)
3076 if (pos-- == 0)
3077 return mfc;
3078 spin_unlock_bh(&mfc_unres_lock);
3079
3080 it->cache = NULL;
3081 return NULL;
3082}
3083
3084
3085static void *ipmr_mfc_seq_start(struct seq_file *seq, loff_t *pos) 2902static void *ipmr_mfc_seq_start(struct seq_file *seq, loff_t *pos)
3086{ 2903{
3087 struct ipmr_mfc_iter *it = seq->private;
3088 struct net *net = seq_file_net(seq); 2904 struct net *net = seq_file_net(seq);
3089 struct mr_table *mrt; 2905 struct mr_table *mrt;
3090 2906
@@ -3092,54 +2908,7 @@ static void *ipmr_mfc_seq_start(struct seq_file *seq, loff_t *pos)
3092 if (!mrt) 2908 if (!mrt)
3093 return ERR_PTR(-ENOENT); 2909 return ERR_PTR(-ENOENT);
3094 2910
3095 it->mrt = mrt; 2911 return mr_mfc_seq_start(seq, pos, mrt, &mfc_unres_lock);
3096 it->cache = NULL;
3097 return *pos ? ipmr_mfc_seq_idx(net, seq->private, *pos - 1)
3098 : SEQ_START_TOKEN;
3099}
3100
3101static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
3102{
3103 struct ipmr_mfc_iter *it = seq->private;
3104 struct net *net = seq_file_net(seq);
3105 struct mr_table *mrt = it->mrt;
3106 struct mfc_cache *mfc = v;
3107
3108 ++*pos;
3109
3110 if (v == SEQ_START_TOKEN)
3111 return ipmr_mfc_seq_idx(net, seq->private, 0);
3112
3113 if (mfc->list.next != it->cache)
3114 return list_entry(mfc->list.next, struct mfc_cache, list);
3115
3116 if (it->cache == &mrt->mfc_unres_queue)
3117 goto end_of_list;
3118
3119 /* exhausted cache_array, show unresolved */
3120 rcu_read_unlock();
3121 it->cache = &mrt->mfc_unres_queue;
3122
3123 spin_lock_bh(&mfc_unres_lock);
3124 if (!list_empty(it->cache))
3125 return list_first_entry(it->cache, struct mfc_cache, list);
3126
3127end_of_list:
3128 spin_unlock_bh(&mfc_unres_lock);
3129 it->cache = NULL;
3130
3131 return NULL;
3132}
3133
3134static void ipmr_mfc_seq_stop(struct seq_file *seq, void *v)
3135{
3136 struct ipmr_mfc_iter *it = seq->private;
3137 struct mr_table *mrt = it->mrt;
3138
3139 if (it->cache == &mrt->mfc_unres_queue)
3140 spin_unlock_bh(&mfc_unres_lock);
3141 else if (it->cache == &mrt->mfc_cache_list)
3142 rcu_read_unlock();
3143} 2912}
3144 2913
3145static int ipmr_mfc_seq_show(struct seq_file *seq, void *v) 2914static int ipmr_mfc_seq_show(struct seq_file *seq, void *v)
@@ -3151,26 +2920,26 @@ static int ipmr_mfc_seq_show(struct seq_file *seq, void *v)
3151 "Group Origin Iif Pkts Bytes Wrong Oifs\n"); 2920 "Group Origin Iif Pkts Bytes Wrong Oifs\n");
3152 } else { 2921 } else {
3153 const struct mfc_cache *mfc = v; 2922 const struct mfc_cache *mfc = v;
3154 const struct ipmr_mfc_iter *it = seq->private; 2923 const struct mr_mfc_iter *it = seq->private;
3155 const struct mr_table *mrt = it->mrt; 2924 const struct mr_table *mrt = it->mrt;
3156 2925
3157 seq_printf(seq, "%08X %08X %-3hd", 2926 seq_printf(seq, "%08X %08X %-3hd",
3158 (__force u32) mfc->mfc_mcastgrp, 2927 (__force u32) mfc->mfc_mcastgrp,
3159 (__force u32) mfc->mfc_origin, 2928 (__force u32) mfc->mfc_origin,
3160 mfc->mfc_parent); 2929 mfc->_c.mfc_parent);
3161 2930
3162 if (it->cache != &mrt->mfc_unres_queue) { 2931 if (it->cache != &mrt->mfc_unres_queue) {
3163 seq_printf(seq, " %8lu %8lu %8lu", 2932 seq_printf(seq, " %8lu %8lu %8lu",
3164 mfc->mfc_un.res.pkt, 2933 mfc->_c.mfc_un.res.pkt,
3165 mfc->mfc_un.res.bytes, 2934 mfc->_c.mfc_un.res.bytes,
3166 mfc->mfc_un.res.wrong_if); 2935 mfc->_c.mfc_un.res.wrong_if);
3167 for (n = mfc->mfc_un.res.minvif; 2936 for (n = mfc->_c.mfc_un.res.minvif;
3168 n < mfc->mfc_un.res.maxvif; n++) { 2937 n < mfc->_c.mfc_un.res.maxvif; n++) {
3169 if (VIF_EXISTS(mrt, n) && 2938 if (VIF_EXISTS(mrt, n) &&
3170 mfc->mfc_un.res.ttls[n] < 255) 2939 mfc->_c.mfc_un.res.ttls[n] < 255)
3171 seq_printf(seq, 2940 seq_printf(seq,
3172 " %2d:%-3d", 2941 " %2d:%-3d",
3173 n, mfc->mfc_un.res.ttls[n]); 2942 n, mfc->_c.mfc_un.res.ttls[n]);
3174 } 2943 }
3175 } else { 2944 } else {
3176 /* unresolved mfc_caches don't contain 2945 /* unresolved mfc_caches don't contain
@@ -3185,15 +2954,15 @@ static int ipmr_mfc_seq_show(struct seq_file *seq, void *v)
3185 2954
3186static const struct seq_operations ipmr_mfc_seq_ops = { 2955static const struct seq_operations ipmr_mfc_seq_ops = {
3187 .start = ipmr_mfc_seq_start, 2956 .start = ipmr_mfc_seq_start,
3188 .next = ipmr_mfc_seq_next, 2957 .next = mr_mfc_seq_next,
3189 .stop = ipmr_mfc_seq_stop, 2958 .stop = mr_mfc_seq_stop,
3190 .show = ipmr_mfc_seq_show, 2959 .show = ipmr_mfc_seq_show,
3191}; 2960};
3192 2961
3193static int ipmr_mfc_open(struct inode *inode, struct file *file) 2962static int ipmr_mfc_open(struct inode *inode, struct file *file)
3194{ 2963{
3195 return seq_open_net(inode, file, &ipmr_mfc_seq_ops, 2964 return seq_open_net(inode, file, &ipmr_mfc_seq_ops,
3196 sizeof(struct ipmr_mfc_iter)); 2965 sizeof(struct mr_mfc_iter));
3197} 2966}
3198 2967
3199static const struct file_operations ipmr_mfc_fops = { 2968static const struct file_operations ipmr_mfc_fops = {
@@ -3229,7 +2998,7 @@ static int ipmr_dump(struct net *net, struct notifier_block *nb)
3229 2998
3230 ipmr_for_each_table(mrt, net) { 2999 ipmr_for_each_table(mrt, net) {
3231 struct vif_device *v = &mrt->vif_table[0]; 3000 struct vif_device *v = &mrt->vif_table[0];
3232 struct mfc_cache *mfc; 3001 struct mr_mfc *mfc;
3233 int vifi; 3002 int vifi;
3234 3003
3235 /* Notifiy on table VIF entries */ 3004 /* Notifiy on table VIF entries */
@@ -3246,7 +3015,8 @@ static int ipmr_dump(struct net *net, struct notifier_block *nb)
3246 /* Notify on table MFC entries */ 3015 /* Notify on table MFC entries */
3247 list_for_each_entry_rcu(mfc, &mrt->mfc_cache_list, list) 3016 list_for_each_entry_rcu(mfc, &mrt->mfc_cache_list, list)
3248 call_ipmr_mfc_entry_notifier(nb, net, 3017 call_ipmr_mfc_entry_notifier(nb, net,
3249 FIB_EVENT_ENTRY_ADD, mfc, 3018 FIB_EVENT_ENTRY_ADD,
3019 (struct mfc_cache *)mfc,
3250 mrt->id); 3020 mrt->id);
3251 } 3021 }
3252 3022
@@ -3327,6 +3097,7 @@ static void __net_exit ipmr_net_exit(struct net *net)
3327static struct pernet_operations ipmr_net_ops = { 3097static struct pernet_operations ipmr_net_ops = {
3328 .init = ipmr_net_init, 3098 .init = ipmr_net_init,
3329 .exit = ipmr_net_exit, 3099 .exit = ipmr_net_exit,
3100 .async = true,
3330}; 3101};
3331 3102
3332int __init ip_mr_init(void) 3103int __init ip_mr_init(void)
diff --git a/net/ipv4/ipmr_base.c b/net/ipv4/ipmr_base.c
new file mode 100644
index 000000000000..8ba55bfda817
--- /dev/null
+++ b/net/ipv4/ipmr_base.c
@@ -0,0 +1,323 @@
1/* Linux multicast routing support
2 * Common logic shared by IPv4 [ipmr] and IPv6 [ip6mr] implementation
3 */
4
5#include <linux/mroute_base.h>
6
7/* Sets everything common except 'dev', since that is done under locking */
8void vif_device_init(struct vif_device *v,
9 struct net_device *dev,
10 unsigned long rate_limit,
11 unsigned char threshold,
12 unsigned short flags,
13 unsigned short get_iflink_mask)
14{
15 v->dev = NULL;
16 v->bytes_in = 0;
17 v->bytes_out = 0;
18 v->pkt_in = 0;
19 v->pkt_out = 0;
20 v->rate_limit = rate_limit;
21 v->flags = flags;
22 v->threshold = threshold;
23 if (v->flags & get_iflink_mask)
24 v->link = dev_get_iflink(dev);
25 else
26 v->link = dev->ifindex;
27}
28EXPORT_SYMBOL(vif_device_init);
29
30struct mr_table *
31mr_table_alloc(struct net *net, u32 id,
32 struct mr_table_ops *ops,
33 void (*expire_func)(struct timer_list *t),
34 void (*table_set)(struct mr_table *mrt,
35 struct net *net))
36{
37 struct mr_table *mrt;
38
39 mrt = kzalloc(sizeof(*mrt), GFP_KERNEL);
40 if (!mrt)
41 return NULL;
42 mrt->id = id;
43 write_pnet(&mrt->net, net);
44
45 mrt->ops = *ops;
46 rhltable_init(&mrt->mfc_hash, mrt->ops.rht_params);
47 INIT_LIST_HEAD(&mrt->mfc_cache_list);
48 INIT_LIST_HEAD(&mrt->mfc_unres_queue);
49
50 timer_setup(&mrt->ipmr_expire_timer, expire_func, 0);
51
52 mrt->mroute_reg_vif_num = -1;
53 table_set(mrt, net);
54 return mrt;
55}
56EXPORT_SYMBOL(mr_table_alloc);
57
58void *mr_mfc_find_parent(struct mr_table *mrt, void *hasharg, int parent)
59{
60 struct rhlist_head *tmp, *list;
61 struct mr_mfc *c;
62
63 list = rhltable_lookup(&mrt->mfc_hash, hasharg, *mrt->ops.rht_params);
64 rhl_for_each_entry_rcu(c, tmp, list, mnode)
65 if (parent == -1 || parent == c->mfc_parent)
66 return c;
67
68 return NULL;
69}
70EXPORT_SYMBOL(mr_mfc_find_parent);
71
72void *mr_mfc_find_any_parent(struct mr_table *mrt, int vifi)
73{
74 struct rhlist_head *tmp, *list;
75 struct mr_mfc *c;
76
77 list = rhltable_lookup(&mrt->mfc_hash, mrt->ops.cmparg_any,
78 *mrt->ops.rht_params);
79 rhl_for_each_entry_rcu(c, tmp, list, mnode)
80 if (c->mfc_un.res.ttls[vifi] < 255)
81 return c;
82
83 return NULL;
84}
85EXPORT_SYMBOL(mr_mfc_find_any_parent);
86
87void *mr_mfc_find_any(struct mr_table *mrt, int vifi, void *hasharg)
88{
89 struct rhlist_head *tmp, *list;
90 struct mr_mfc *c, *proxy;
91
92 list = rhltable_lookup(&mrt->mfc_hash, hasharg, *mrt->ops.rht_params);
93 rhl_for_each_entry_rcu(c, tmp, list, mnode) {
94 if (c->mfc_un.res.ttls[vifi] < 255)
95 return c;
96
97 /* It's ok if the vifi is part of the static tree */
98 proxy = mr_mfc_find_any_parent(mrt, c->mfc_parent);
99 if (proxy && proxy->mfc_un.res.ttls[vifi] < 255)
100 return c;
101 }
102
103 return mr_mfc_find_any_parent(mrt, vifi);
104}
105EXPORT_SYMBOL(mr_mfc_find_any);
106
107#ifdef CONFIG_PROC_FS
108void *mr_vif_seq_idx(struct net *net, struct mr_vif_iter *iter, loff_t pos)
109{
110 struct mr_table *mrt = iter->mrt;
111
112 for (iter->ct = 0; iter->ct < mrt->maxvif; ++iter->ct) {
113 if (!VIF_EXISTS(mrt, iter->ct))
114 continue;
115 if (pos-- == 0)
116 return &mrt->vif_table[iter->ct];
117 }
118 return NULL;
119}
120EXPORT_SYMBOL(mr_vif_seq_idx);
121
122void *mr_vif_seq_next(struct seq_file *seq, void *v, loff_t *pos)
123{
124 struct mr_vif_iter *iter = seq->private;
125 struct net *net = seq_file_net(seq);
126 struct mr_table *mrt = iter->mrt;
127
128 ++*pos;
129 if (v == SEQ_START_TOKEN)
130 return mr_vif_seq_idx(net, iter, 0);
131
132 while (++iter->ct < mrt->maxvif) {
133 if (!VIF_EXISTS(mrt, iter->ct))
134 continue;
135 return &mrt->vif_table[iter->ct];
136 }
137 return NULL;
138}
139EXPORT_SYMBOL(mr_vif_seq_next);
140
141void *mr_mfc_seq_idx(struct net *net,
142 struct mr_mfc_iter *it, loff_t pos)
143{
144 struct mr_table *mrt = it->mrt;
145 struct mr_mfc *mfc;
146
147 rcu_read_lock();
148 it->cache = &mrt->mfc_cache_list;
149 list_for_each_entry_rcu(mfc, &mrt->mfc_cache_list, list)
150 if (pos-- == 0)
151 return mfc;
152 rcu_read_unlock();
153
154 spin_lock_bh(it->lock);
155 it->cache = &mrt->mfc_unres_queue;
156 list_for_each_entry(mfc, it->cache, list)
157 if (pos-- == 0)
158 return mfc;
159 spin_unlock_bh(it->lock);
160
161 it->cache = NULL;
162 return NULL;
163}
164EXPORT_SYMBOL(mr_mfc_seq_idx);
165
166void *mr_mfc_seq_next(struct seq_file *seq, void *v,
167 loff_t *pos)
168{
169 struct mr_mfc_iter *it = seq->private;
170 struct net *net = seq_file_net(seq);
171 struct mr_table *mrt = it->mrt;
172 struct mr_mfc *c = v;
173
174 ++*pos;
175
176 if (v == SEQ_START_TOKEN)
177 return mr_mfc_seq_idx(net, seq->private, 0);
178
179 if (c->list.next != it->cache)
180 return list_entry(c->list.next, struct mr_mfc, list);
181
182 if (it->cache == &mrt->mfc_unres_queue)
183 goto end_of_list;
184
185 /* exhausted cache_array, show unresolved */
186 rcu_read_unlock();
187 it->cache = &mrt->mfc_unres_queue;
188
189 spin_lock_bh(it->lock);
190 if (!list_empty(it->cache))
191 return list_first_entry(it->cache, struct mr_mfc, list);
192
193end_of_list:
194 spin_unlock_bh(it->lock);
195 it->cache = NULL;
196
197 return NULL;
198}
199EXPORT_SYMBOL(mr_mfc_seq_next);
200#endif
201
202int mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
203 struct mr_mfc *c, struct rtmsg *rtm)
204{
205 struct rta_mfc_stats mfcs;
206 struct nlattr *mp_attr;
207 struct rtnexthop *nhp;
208 unsigned long lastuse;
209 int ct;
210
211 /* If cache is unresolved, don't try to parse IIF and OIF */
212 if (c->mfc_parent >= MAXVIFS) {
213 rtm->rtm_flags |= RTNH_F_UNRESOLVED;
214 return -ENOENT;
215 }
216
217 if (VIF_EXISTS(mrt, c->mfc_parent) &&
218 nla_put_u32(skb, RTA_IIF,
219 mrt->vif_table[c->mfc_parent].dev->ifindex) < 0)
220 return -EMSGSIZE;
221
222 if (c->mfc_flags & MFC_OFFLOAD)
223 rtm->rtm_flags |= RTNH_F_OFFLOAD;
224
225 mp_attr = nla_nest_start(skb, RTA_MULTIPATH);
226 if (!mp_attr)
227 return -EMSGSIZE;
228
229 for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) {
230 if (VIF_EXISTS(mrt, ct) && c->mfc_un.res.ttls[ct] < 255) {
231 struct vif_device *vif;
232
233 nhp = nla_reserve_nohdr(skb, sizeof(*nhp));
234 if (!nhp) {
235 nla_nest_cancel(skb, mp_attr);
236 return -EMSGSIZE;
237 }
238
239 nhp->rtnh_flags = 0;
240 nhp->rtnh_hops = c->mfc_un.res.ttls[ct];
241 vif = &mrt->vif_table[ct];
242 nhp->rtnh_ifindex = vif->dev->ifindex;
243 nhp->rtnh_len = sizeof(*nhp);
244 }
245 }
246
247 nla_nest_end(skb, mp_attr);
248
249 lastuse = READ_ONCE(c->mfc_un.res.lastuse);
250 lastuse = time_after_eq(jiffies, lastuse) ? jiffies - lastuse : 0;
251
252 mfcs.mfcs_packets = c->mfc_un.res.pkt;
253 mfcs.mfcs_bytes = c->mfc_un.res.bytes;
254 mfcs.mfcs_wrong_if = c->mfc_un.res.wrong_if;
255 if (nla_put_64bit(skb, RTA_MFC_STATS, sizeof(mfcs), &mfcs, RTA_PAD) ||
256 nla_put_u64_64bit(skb, RTA_EXPIRES, jiffies_to_clock_t(lastuse),
257 RTA_PAD))
258 return -EMSGSIZE;
259
260 rtm->rtm_type = RTN_MULTICAST;
261 return 1;
262}
263EXPORT_SYMBOL(mr_fill_mroute);
264
265int mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb,
266 struct mr_table *(*iter)(struct net *net,
267 struct mr_table *mrt),
268 int (*fill)(struct mr_table *mrt,
269 struct sk_buff *skb,
270 u32 portid, u32 seq, struct mr_mfc *c,
271 int cmd, int flags),
272 spinlock_t *lock)
273{
274 unsigned int t = 0, e = 0, s_t = cb->args[0], s_e = cb->args[1];
275 struct net *net = sock_net(skb->sk);
276 struct mr_table *mrt;
277 struct mr_mfc *mfc;
278
279 rcu_read_lock();
280 for (mrt = iter(net, NULL); mrt; mrt = iter(net, mrt)) {
281 if (t < s_t)
282 goto next_table;
283 list_for_each_entry_rcu(mfc, &mrt->mfc_cache_list, list) {
284 if (e < s_e)
285 goto next_entry;
286 if (fill(mrt, skb, NETLINK_CB(cb->skb).portid,
287 cb->nlh->nlmsg_seq, mfc,
288 RTM_NEWROUTE, NLM_F_MULTI) < 0)
289 goto done;
290next_entry:
291 e++;
292 }
293 e = 0;
294 s_e = 0;
295
296 spin_lock_bh(lock);
297 list_for_each_entry(mfc, &mrt->mfc_unres_queue, list) {
298 if (e < s_e)
299 goto next_entry2;
300 if (fill(mrt, skb, NETLINK_CB(cb->skb).portid,
301 cb->nlh->nlmsg_seq, mfc,
302 RTM_NEWROUTE, NLM_F_MULTI) < 0) {
303 spin_unlock_bh(lock);
304 goto done;
305 }
306next_entry2:
307 e++;
308 }
309 spin_unlock_bh(lock);
310 e = 0;
311 s_e = 0;
312next_table:
313 t++;
314 }
315done:
316 rcu_read_unlock();
317
318 cb->args[1] = e;
319 cb->args[0] = t;
320
321 return skb->len;
322}
323EXPORT_SYMBOL(mr_rtm_dumproute);
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index e3e420f3ba7b..c36ffce3c812 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -1635,6 +1635,7 @@ static void __net_exit arp_tables_net_exit(struct net *net)
1635static struct pernet_operations arp_tables_net_ops = { 1635static struct pernet_operations arp_tables_net_ops = {
1636 .init = arp_tables_net_init, 1636 .init = arp_tables_net_init,
1637 .exit = arp_tables_net_exit, 1637 .exit = arp_tables_net_exit,
1638 .async = true,
1638}; 1639};
1639 1640
1640static int __init arp_tables_init(void) 1641static int __init arp_tables_init(void)
diff --git a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c
index 8f8713b4388f..49c2490193ae 100644
--- a/net/ipv4/netfilter/arptable_filter.c
+++ b/net/ipv4/netfilter/arptable_filter.c
@@ -65,6 +65,7 @@ static void __net_exit arptable_filter_net_exit(struct net *net)
65 65
66static struct pernet_operations arptable_filter_net_ops = { 66static struct pernet_operations arptable_filter_net_ops = {
67 .exit = arptable_filter_net_exit, 67 .exit = arptable_filter_net_exit,
68 .async = true,
68}; 69};
69 70
70static int __init arptable_filter_init(void) 71static int __init arptable_filter_init(void)
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index e38395a8dcf2..d4f7584d2dbe 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -1916,6 +1916,7 @@ static void __net_exit ip_tables_net_exit(struct net *net)
1916static struct pernet_operations ip_tables_net_ops = { 1916static struct pernet_operations ip_tables_net_ops = {
1917 .init = ip_tables_net_init, 1917 .init = ip_tables_net_init,
1918 .exit = ip_tables_net_exit, 1918 .exit = ip_tables_net_exit,
1919 .async = true,
1919}; 1920};
1920 1921
1921static int __init ip_tables_init(void) 1922static int __init ip_tables_init(void)
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index 8a8ae61cea71..0fc88fa7a4dc 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -845,6 +845,7 @@ static struct pernet_operations clusterip_net_ops = {
845 .exit = clusterip_net_exit, 845 .exit = clusterip_net_exit,
846 .id = &clusterip_net_id, 846 .id = &clusterip_net_id,
847 .size = sizeof(struct clusterip_net), 847 .size = sizeof(struct clusterip_net),
848 .async = true,
848}; 849};
849 850
850static int __init clusterip_tg_init(void) 851static int __init clusterip_tg_init(void)
diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c
index 9ac92ea7b93c..c1c136a93911 100644
--- a/net/ipv4/netfilter/iptable_filter.c
+++ b/net/ipv4/netfilter/iptable_filter.c
@@ -87,6 +87,7 @@ static void __net_exit iptable_filter_net_exit(struct net *net)
87static struct pernet_operations iptable_filter_net_ops = { 87static struct pernet_operations iptable_filter_net_ops = {
88 .init = iptable_filter_net_init, 88 .init = iptable_filter_net_init,
89 .exit = iptable_filter_net_exit, 89 .exit = iptable_filter_net_exit,
90 .async = true,
90}; 91};
91 92
92static int __init iptable_filter_init(void) 93static int __init iptable_filter_init(void)
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c
index dea138ca8925..f6074059531a 100644
--- a/net/ipv4/netfilter/iptable_mangle.c
+++ b/net/ipv4/netfilter/iptable_mangle.c
@@ -113,6 +113,7 @@ static void __net_exit iptable_mangle_net_exit(struct net *net)
113 113
114static struct pernet_operations iptable_mangle_net_ops = { 114static struct pernet_operations iptable_mangle_net_ops = {
115 .exit = iptable_mangle_net_exit, 115 .exit = iptable_mangle_net_exit,
116 .async = true,
116}; 117};
117 118
118static int __init iptable_mangle_init(void) 119static int __init iptable_mangle_init(void)
diff --git a/net/ipv4/netfilter/iptable_nat.c b/net/ipv4/netfilter/iptable_nat.c
index 0f7255cc65ee..b771af74be79 100644
--- a/net/ipv4/netfilter/iptable_nat.c
+++ b/net/ipv4/netfilter/iptable_nat.c
@@ -129,6 +129,7 @@ static void __net_exit iptable_nat_net_exit(struct net *net)
129 129
130static struct pernet_operations iptable_nat_net_ops = { 130static struct pernet_operations iptable_nat_net_ops = {
131 .exit = iptable_nat_net_exit, 131 .exit = iptable_nat_net_exit,
132 .async = true,
132}; 133};
133 134
134static int __init iptable_nat_init(void) 135static int __init iptable_nat_init(void)
diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c
index 960625aabf04..963753e50842 100644
--- a/net/ipv4/netfilter/iptable_raw.c
+++ b/net/ipv4/netfilter/iptable_raw.c
@@ -76,6 +76,7 @@ static void __net_exit iptable_raw_net_exit(struct net *net)
76 76
77static struct pernet_operations iptable_raw_net_ops = { 77static struct pernet_operations iptable_raw_net_ops = {
78 .exit = iptable_raw_net_exit, 78 .exit = iptable_raw_net_exit,
79 .async = true,
79}; 80};
80 81
81static int __init iptable_raw_init(void) 82static int __init iptable_raw_init(void)
diff --git a/net/ipv4/netfilter/iptable_security.c b/net/ipv4/netfilter/iptable_security.c
index e5379fe57b64..c40d6b3d8b6a 100644
--- a/net/ipv4/netfilter/iptable_security.c
+++ b/net/ipv4/netfilter/iptable_security.c
@@ -76,6 +76,7 @@ static void __net_exit iptable_security_net_exit(struct net *net)
76 76
77static struct pernet_operations iptable_security_net_ops = { 77static struct pernet_operations iptable_security_net_ops = {
78 .exit = iptable_security_net_exit, 78 .exit = iptable_security_net_exit,
79 .async = true,
79}; 80};
80 81
81static int __init iptable_security_init(void) 82static int __init iptable_security_init(void)
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index b50721d9d30e..6531f69db010 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -399,6 +399,7 @@ static struct pernet_operations ipv4_net_ops = {
399 .exit = ipv4_net_exit, 399 .exit = ipv4_net_exit,
400 .id = &conntrack4_net_id, 400 .id = &conntrack4_net_id,
401 .size = sizeof(struct conntrack4_net), 401 .size = sizeof(struct conntrack4_net),
402 .async = true,
402}; 403};
403 404
404static int __init nf_conntrack_l3proto_ipv4_init(void) 405static int __init nf_conntrack_l3proto_ipv4_init(void)
diff --git a/net/ipv4/netfilter/nf_defrag_ipv4.c b/net/ipv4/netfilter/nf_defrag_ipv4.c
index a0d3ad60a411..57244b62a4fc 100644
--- a/net/ipv4/netfilter/nf_defrag_ipv4.c
+++ b/net/ipv4/netfilter/nf_defrag_ipv4.c
@@ -118,6 +118,7 @@ static void __net_exit defrag4_net_exit(struct net *net)
118 118
119static struct pernet_operations defrag4_net_ops = { 119static struct pernet_operations defrag4_net_ops = {
120 .exit = defrag4_net_exit, 120 .exit = defrag4_net_exit,
121 .async = true,
121}; 122};
122 123
123static int __init nf_defrag_init(void) 124static int __init nf_defrag_init(void)
diff --git a/net/ipv4/netfilter/nf_log_arp.c b/net/ipv4/netfilter/nf_log_arp.c
index df5c2a2061a4..162293469ac2 100644
--- a/net/ipv4/netfilter/nf_log_arp.c
+++ b/net/ipv4/netfilter/nf_log_arp.c
@@ -122,6 +122,7 @@ static void __net_exit nf_log_arp_net_exit(struct net *net)
122static struct pernet_operations nf_log_arp_net_ops = { 122static struct pernet_operations nf_log_arp_net_ops = {
123 .init = nf_log_arp_net_init, 123 .init = nf_log_arp_net_init,
124 .exit = nf_log_arp_net_exit, 124 .exit = nf_log_arp_net_exit,
125 .async = true,
125}; 126};
126 127
127static int __init nf_log_arp_init(void) 128static int __init nf_log_arp_init(void)
diff --git a/net/ipv4/netfilter/nf_log_ipv4.c b/net/ipv4/netfilter/nf_log_ipv4.c
index 4388de0e5380..7a06de140f3c 100644
--- a/net/ipv4/netfilter/nf_log_ipv4.c
+++ b/net/ipv4/netfilter/nf_log_ipv4.c
@@ -358,6 +358,7 @@ static void __net_exit nf_log_ipv4_net_exit(struct net *net)
358static struct pernet_operations nf_log_ipv4_net_ops = { 358static struct pernet_operations nf_log_ipv4_net_ops = {
359 .init = nf_log_ipv4_net_init, 359 .init = nf_log_ipv4_net_init,
360 .exit = nf_log_ipv4_net_exit, 360 .exit = nf_log_ipv4_net_exit,
361 .async = true,
361}; 362};
362 363
363static int __init nf_log_ipv4_init(void) 364static int __init nf_log_ipv4_init(void)
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index b8f0db54b197..0164def9c808 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -1204,6 +1204,7 @@ static void __net_exit ping_v4_proc_exit_net(struct net *net)
1204static struct pernet_operations ping_v4_net_ops = { 1204static struct pernet_operations ping_v4_net_ops = {
1205 .init = ping_v4_proc_init_net, 1205 .init = ping_v4_proc_init_net,
1206 .exit = ping_v4_proc_exit_net, 1206 .exit = ping_v4_proc_exit_net,
1207 .async = true,
1207}; 1208};
1208 1209
1209int __init ping_proc_init(void) 1210int __init ping_proc_init(void)
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index dc5edc8f7564..d97e83b2dd33 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -549,10 +549,10 @@ static __net_exit void ip_proc_exit_net(struct net *net)
549static __net_initdata struct pernet_operations ip_proc_ops = { 549static __net_initdata struct pernet_operations ip_proc_ops = {
550 .init = ip_proc_init_net, 550 .init = ip_proc_init_net,
551 .exit = ip_proc_exit_net, 551 .exit = ip_proc_exit_net,
552 .async = true,
552}; 553};
553 554
554int __init ip_misc_proc_init(void) 555int __init ip_misc_proc_init(void)
555{ 556{
556 return register_pernet_subsys(&ip_proc_ops); 557 return register_pernet_subsys(&ip_proc_ops);
557} 558}
558
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 9b367fc48d7d..720bef7da2f6 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -711,9 +711,7 @@ static void raw_close(struct sock *sk, long timeout)
711 /* 711 /*
712 * Raw sockets may have direct kernel references. Kill them. 712 * Raw sockets may have direct kernel references. Kill them.
713 */ 713 */
714 rtnl_lock();
715 ip_ra_control(sk, 0, NULL); 714 ip_ra_control(sk, 0, NULL);
716 rtnl_unlock();
717 715
718 sk_common_release(sk); 716 sk_common_release(sk);
719} 717}
@@ -1156,6 +1154,7 @@ static __net_exit void raw_exit_net(struct net *net)
1156static __net_initdata struct pernet_operations raw_net_ops = { 1154static __net_initdata struct pernet_operations raw_net_ops = {
1157 .init = raw_init_net, 1155 .init = raw_init_net,
1158 .exit = raw_exit_net, 1156 .exit = raw_exit_net,
1157 .async = true,
1159}; 1158};
1160 1159
1161int __init raw_proc_init(void) 1160int __init raw_proc_init(void)
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 299e247b2032..4ac5728689f5 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -418,6 +418,7 @@ static void __net_exit ip_rt_do_proc_exit(struct net *net)
418static struct pernet_operations ip_rt_proc_ops __net_initdata = { 418static struct pernet_operations ip_rt_proc_ops __net_initdata = {
419 .init = ip_rt_do_proc_init, 419 .init = ip_rt_do_proc_init,
420 .exit = ip_rt_do_proc_exit, 420 .exit = ip_rt_do_proc_exit,
421 .async = true,
421}; 422};
422 423
423static int __init ip_rt_proc_init(void) 424static int __init ip_rt_proc_init(void)
@@ -1532,7 +1533,6 @@ struct rtable *rt_dst_alloc(struct net_device *dev,
1532 rt->rt_mtu_locked = 0; 1533 rt->rt_mtu_locked = 0;
1533 rt->rt_gateway = 0; 1534 rt->rt_gateway = 0;
1534 rt->rt_uses_gateway = 0; 1535 rt->rt_uses_gateway = 0;
1535 rt->rt_table_id = 0;
1536 INIT_LIST_HEAD(&rt->rt_uncached); 1536 INIT_LIST_HEAD(&rt->rt_uncached);
1537 1537
1538 rt->dst.output = ip_output; 1538 rt->dst.output = ip_output;
@@ -1668,19 +1668,6 @@ static void ip_del_fnhe(struct fib_nh *nh, __be32 daddr)
1668 spin_unlock_bh(&fnhe_lock); 1668 spin_unlock_bh(&fnhe_lock);
1669} 1669}
1670 1670
1671static void set_lwt_redirect(struct rtable *rth)
1672{
1673 if (lwtunnel_output_redirect(rth->dst.lwtstate)) {
1674 rth->dst.lwtstate->orig_output = rth->dst.output;
1675 rth->dst.output = lwtunnel_output;
1676 }
1677
1678 if (lwtunnel_input_redirect(rth->dst.lwtstate)) {
1679 rth->dst.lwtstate->orig_input = rth->dst.input;
1680 rth->dst.input = lwtunnel_input;
1681 }
1682}
1683
1684/* called in rcu_read_lock() section */ 1671/* called in rcu_read_lock() section */
1685static int __mkroute_input(struct sk_buff *skb, 1672static int __mkroute_input(struct sk_buff *skb,
1686 const struct fib_result *res, 1673 const struct fib_result *res,
@@ -1763,15 +1750,13 @@ rt_cache:
1763 } 1750 }
1764 1751
1765 rth->rt_is_input = 1; 1752 rth->rt_is_input = 1;
1766 if (res->table)
1767 rth->rt_table_id = res->table->tb_id;
1768 RT_CACHE_STAT_INC(in_slow_tot); 1753 RT_CACHE_STAT_INC(in_slow_tot);
1769 1754
1770 rth->dst.input = ip_forward; 1755 rth->dst.input = ip_forward;
1771 1756
1772 rt_set_nexthop(rth, daddr, res, fnhe, res->fi, res->type, itag, 1757 rt_set_nexthop(rth, daddr, res, fnhe, res->fi, res->type, itag,
1773 do_cache); 1758 do_cache);
1774 set_lwt_redirect(rth); 1759 lwtunnel_set_redirect(&rth->dst);
1775 skb_dst_set(skb, &rth->dst); 1760 skb_dst_set(skb, &rth->dst);
1776out: 1761out:
1777 err = 0; 1762 err = 0;
@@ -1787,44 +1772,45 @@ static void ip_multipath_l3_keys(const struct sk_buff *skb,
1787 struct flow_keys *hash_keys) 1772 struct flow_keys *hash_keys)
1788{ 1773{
1789 const struct iphdr *outer_iph = ip_hdr(skb); 1774 const struct iphdr *outer_iph = ip_hdr(skb);
1775 const struct iphdr *key_iph = outer_iph;
1790 const struct iphdr *inner_iph; 1776 const struct iphdr *inner_iph;
1791 const struct icmphdr *icmph; 1777 const struct icmphdr *icmph;
1792 struct iphdr _inner_iph; 1778 struct iphdr _inner_iph;
1793 struct icmphdr _icmph; 1779 struct icmphdr _icmph;
1794 1780
1795 hash_keys->addrs.v4addrs.src = outer_iph->saddr;
1796 hash_keys->addrs.v4addrs.dst = outer_iph->daddr;
1797 if (likely(outer_iph->protocol != IPPROTO_ICMP)) 1781 if (likely(outer_iph->protocol != IPPROTO_ICMP))
1798 return; 1782 goto out;
1799 1783
1800 if (unlikely((outer_iph->frag_off & htons(IP_OFFSET)) != 0)) 1784 if (unlikely((outer_iph->frag_off & htons(IP_OFFSET)) != 0))
1801 return; 1785 goto out;
1802 1786
1803 icmph = skb_header_pointer(skb, outer_iph->ihl * 4, sizeof(_icmph), 1787 icmph = skb_header_pointer(skb, outer_iph->ihl * 4, sizeof(_icmph),
1804 &_icmph); 1788 &_icmph);
1805 if (!icmph) 1789 if (!icmph)
1806 return; 1790 goto out;
1807 1791
1808 if (icmph->type != ICMP_DEST_UNREACH && 1792 if (icmph->type != ICMP_DEST_UNREACH &&
1809 icmph->type != ICMP_REDIRECT && 1793 icmph->type != ICMP_REDIRECT &&
1810 icmph->type != ICMP_TIME_EXCEEDED && 1794 icmph->type != ICMP_TIME_EXCEEDED &&
1811 icmph->type != ICMP_PARAMETERPROB) 1795 icmph->type != ICMP_PARAMETERPROB)
1812 return; 1796 goto out;
1813 1797
1814 inner_iph = skb_header_pointer(skb, 1798 inner_iph = skb_header_pointer(skb,
1815 outer_iph->ihl * 4 + sizeof(_icmph), 1799 outer_iph->ihl * 4 + sizeof(_icmph),
1816 sizeof(_inner_iph), &_inner_iph); 1800 sizeof(_inner_iph), &_inner_iph);
1817 if (!inner_iph) 1801 if (!inner_iph)
1818 return; 1802 goto out;
1819 hash_keys->addrs.v4addrs.src = inner_iph->saddr; 1803
1820 hash_keys->addrs.v4addrs.dst = inner_iph->daddr; 1804 key_iph = inner_iph;
1805out:
1806 hash_keys->addrs.v4addrs.src = key_iph->saddr;
1807 hash_keys->addrs.v4addrs.dst = key_iph->daddr;
1821} 1808}
1822 1809
1823/* if skb is set it will be used and fl4 can be NULL */ 1810/* if skb is set it will be used and fl4 can be NULL */
1824int fib_multipath_hash(const struct fib_info *fi, const struct flowi4 *fl4, 1811int fib_multipath_hash(const struct net *net, const struct flowi4 *fl4,
1825 const struct sk_buff *skb) 1812 const struct sk_buff *skb, struct flow_keys *flkeys)
1826{ 1813{
1827 struct net *net = fi->fib_net;
1828 struct flow_keys hash_keys; 1814 struct flow_keys hash_keys;
1829 u32 mhash; 1815 u32 mhash;
1830 1816
@@ -1848,15 +1834,20 @@ int fib_multipath_hash(const struct fib_info *fi, const struct flowi4 *fl4,
1848 /* short-circuit if we already have L4 hash present */ 1834 /* short-circuit if we already have L4 hash present */
1849 if (skb->l4_hash) 1835 if (skb->l4_hash)
1850 return skb_get_hash_raw(skb) >> 1; 1836 return skb_get_hash_raw(skb) >> 1;
1837
1851 memset(&hash_keys, 0, sizeof(hash_keys)); 1838 memset(&hash_keys, 0, sizeof(hash_keys));
1852 skb_flow_dissect_flow_keys(skb, &keys, flag); 1839
1840 if (!flkeys) {
1841 skb_flow_dissect_flow_keys(skb, &keys, flag);
1842 flkeys = &keys;
1843 }
1853 1844
1854 hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS; 1845 hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
1855 hash_keys.addrs.v4addrs.src = keys.addrs.v4addrs.src; 1846 hash_keys.addrs.v4addrs.src = flkeys->addrs.v4addrs.src;
1856 hash_keys.addrs.v4addrs.dst = keys.addrs.v4addrs.dst; 1847 hash_keys.addrs.v4addrs.dst = flkeys->addrs.v4addrs.dst;
1857 hash_keys.ports.src = keys.ports.src; 1848 hash_keys.ports.src = flkeys->ports.src;
1858 hash_keys.ports.dst = keys.ports.dst; 1849 hash_keys.ports.dst = flkeys->ports.dst;
1859 hash_keys.basic.ip_proto = keys.basic.ip_proto; 1850 hash_keys.basic.ip_proto = flkeys->basic.ip_proto;
1860 } else { 1851 } else {
1861 memset(&hash_keys, 0, sizeof(hash_keys)); 1852 memset(&hash_keys, 0, sizeof(hash_keys));
1862 hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS; 1853 hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
@@ -1872,17 +1863,17 @@ int fib_multipath_hash(const struct fib_info *fi, const struct flowi4 *fl4,
1872 1863
1873 return mhash >> 1; 1864 return mhash >> 1;
1874} 1865}
1875EXPORT_SYMBOL_GPL(fib_multipath_hash);
1876#endif /* CONFIG_IP_ROUTE_MULTIPATH */ 1866#endif /* CONFIG_IP_ROUTE_MULTIPATH */
1877 1867
1878static int ip_mkroute_input(struct sk_buff *skb, 1868static int ip_mkroute_input(struct sk_buff *skb,
1879 struct fib_result *res, 1869 struct fib_result *res,
1880 struct in_device *in_dev, 1870 struct in_device *in_dev,
1881 __be32 daddr, __be32 saddr, u32 tos) 1871 __be32 daddr, __be32 saddr, u32 tos,
1872 struct flow_keys *hkeys)
1882{ 1873{
1883#ifdef CONFIG_IP_ROUTE_MULTIPATH 1874#ifdef CONFIG_IP_ROUTE_MULTIPATH
1884 if (res->fi && res->fi->fib_nhs > 1) { 1875 if (res->fi && res->fi->fib_nhs > 1) {
1885 int h = fib_multipath_hash(res->fi, NULL, skb); 1876 int h = fib_multipath_hash(res->fi->fib_net, NULL, skb, hkeys);
1886 1877
1887 fib_select_multipath(res, h); 1878 fib_select_multipath(res, h);
1888 } 1879 }
@@ -1908,13 +1899,14 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
1908 struct fib_result *res) 1899 struct fib_result *res)
1909{ 1900{
1910 struct in_device *in_dev = __in_dev_get_rcu(dev); 1901 struct in_device *in_dev = __in_dev_get_rcu(dev);
1902 struct flow_keys *flkeys = NULL, _flkeys;
1903 struct net *net = dev_net(dev);
1911 struct ip_tunnel_info *tun_info; 1904 struct ip_tunnel_info *tun_info;
1912 struct flowi4 fl4; 1905 int err = -EINVAL;
1913 unsigned int flags = 0; 1906 unsigned int flags = 0;
1914 u32 itag = 0; 1907 u32 itag = 0;
1915 struct rtable *rth; 1908 struct rtable *rth;
1916 int err = -EINVAL; 1909 struct flowi4 fl4;
1917 struct net *net = dev_net(dev);
1918 bool do_cache; 1910 bool do_cache;
1919 1911
1920 /* IP on this device is disabled. */ 1912 /* IP on this device is disabled. */
@@ -1973,6 +1965,10 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
1973 fl4.daddr = daddr; 1965 fl4.daddr = daddr;
1974 fl4.saddr = saddr; 1966 fl4.saddr = saddr;
1975 fl4.flowi4_uid = sock_net_uid(net, NULL); 1967 fl4.flowi4_uid = sock_net_uid(net, NULL);
1968
1969 if (fib4_rules_early_flow_dissect(net, skb, &fl4, &_flkeys))
1970 flkeys = &_flkeys;
1971
1976 err = fib_lookup(net, &fl4, res, 0); 1972 err = fib_lookup(net, &fl4, res, 0);
1977 if (err != 0) { 1973 if (err != 0) {
1978 if (!IN_DEV_FORWARD(in_dev)) 1974 if (!IN_DEV_FORWARD(in_dev))
@@ -1998,7 +1994,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
1998 if (res->type != RTN_UNICAST) 1994 if (res->type != RTN_UNICAST)
1999 goto martian_destination; 1995 goto martian_destination;
2000 1996
2001 err = ip_mkroute_input(skb, res, in_dev, daddr, saddr, tos); 1997 err = ip_mkroute_input(skb, res, in_dev, daddr, saddr, tos, flkeys);
2002out: return err; 1998out: return err;
2003 1999
2004brd_input: 2000brd_input:
@@ -2040,8 +2036,6 @@ local_input:
2040 rth->dst.tclassid = itag; 2036 rth->dst.tclassid = itag;
2041#endif 2037#endif
2042 rth->rt_is_input = 1; 2038 rth->rt_is_input = 1;
2043 if (res->table)
2044 rth->rt_table_id = res->table->tb_id;
2045 2039
2046 RT_CACHE_STAT_INC(in_slow_tot); 2040 RT_CACHE_STAT_INC(in_slow_tot);
2047 if (res->type == RTN_UNREACHABLE) { 2041 if (res->type == RTN_UNREACHABLE) {
@@ -2270,8 +2264,6 @@ add:
2270 return ERR_PTR(-ENOBUFS); 2264 return ERR_PTR(-ENOBUFS);
2271 2265
2272 rth->rt_iif = orig_oif; 2266 rth->rt_iif = orig_oif;
2273 if (res->table)
2274 rth->rt_table_id = res->table->tb_id;
2275 2267
2276 RT_CACHE_STAT_INC(out_slow_tot); 2268 RT_CACHE_STAT_INC(out_slow_tot);
2277 2269
@@ -2293,7 +2285,7 @@ add:
2293 } 2285 }
2294 2286
2295 rt_set_nexthop(rth, fl4->daddr, res, fnhe, fi, type, 0, do_cache); 2287 rt_set_nexthop(rth, fl4->daddr, res, fnhe, fi, type, 0, do_cache);
2296 set_lwt_redirect(rth); 2288 lwtunnel_set_redirect(&rth->dst);
2297 2289
2298 return rth; 2290 return rth;
2299} 2291}
@@ -2804,7 +2796,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
2804 rt->rt_flags |= RTCF_NOTIFY; 2796 rt->rt_flags |= RTCF_NOTIFY;
2805 2797
2806 if (rtm->rtm_flags & RTM_F_LOOKUP_TABLE) 2798 if (rtm->rtm_flags & RTM_F_LOOKUP_TABLE)
2807 table_id = rt->rt_table_id; 2799 table_id = res.table ? res.table->tb_id : 0;
2808 2800
2809 if (rtm->rtm_flags & RTM_F_FIB_MATCH) { 2801 if (rtm->rtm_flags & RTM_F_FIB_MATCH) {
2810 if (!res.fi) { 2802 if (!res.fi) {
@@ -3025,6 +3017,7 @@ static __net_exit void sysctl_route_net_exit(struct net *net)
3025static __net_initdata struct pernet_operations sysctl_route_ops = { 3017static __net_initdata struct pernet_operations sysctl_route_ops = {
3026 .init = sysctl_route_net_init, 3018 .init = sysctl_route_net_init,
3027 .exit = sysctl_route_net_exit, 3019 .exit = sysctl_route_net_exit,
3020 .async = true,
3028}; 3021};
3029#endif 3022#endif
3030 3023
@@ -3038,6 +3031,7 @@ static __net_init int rt_genid_init(struct net *net)
3038 3031
3039static __net_initdata struct pernet_operations rt_genid_ops = { 3032static __net_initdata struct pernet_operations rt_genid_ops = {
3040 .init = rt_genid_init, 3033 .init = rt_genid_init,
3034 .async = true,
3041}; 3035};
3042 3036
3043static int __net_init ipv4_inetpeer_init(struct net *net) 3037static int __net_init ipv4_inetpeer_init(struct net *net)
@@ -3063,6 +3057,7 @@ static void __net_exit ipv4_inetpeer_exit(struct net *net)
3063static __net_initdata struct pernet_operations ipv4_inetpeer_ops = { 3057static __net_initdata struct pernet_operations ipv4_inetpeer_ops = {
3064 .init = ipv4_inetpeer_init, 3058 .init = ipv4_inetpeer_init,
3065 .exit = ipv4_inetpeer_exit, 3059 .exit = ipv4_inetpeer_exit,
3060 .async = true,
3066}; 3061};
3067 3062
3068#ifdef CONFIG_IP_ROUTE_CLASSID 3063#ifdef CONFIG_IP_ROUTE_CLASSID
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 93e172118a94..5b72d97693f8 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -400,7 +400,7 @@ static int proc_fib_multipath_hash_policy(struct ctl_table *table, int write,
400 400
401 ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); 401 ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
402 if (write && ret == 0) 402 if (write && ret == 0)
403 call_netevent_notifiers(NETEVENT_MULTIPATH_HASH_UPDATE, net); 403 call_netevent_notifiers(NETEVENT_IPV4_MPATH_HASH_UPDATE, net);
404 404
405 return ret; 405 return ret;
406} 406}
@@ -520,22 +520,6 @@ static struct ctl_table ipv4_table[] = {
520 .mode = 0644, 520 .mode = 0644,
521 .proc_handler = proc_doulongvec_minmax, 521 .proc_handler = proc_doulongvec_minmax,
522 }, 522 },
523 {
524 .procname = "udp_rmem_min",
525 .data = &sysctl_udp_rmem_min,
526 .maxlen = sizeof(sysctl_udp_rmem_min),
527 .mode = 0644,
528 .proc_handler = proc_dointvec_minmax,
529 .extra1 = &one
530 },
531 {
532 .procname = "udp_wmem_min",
533 .data = &sysctl_udp_wmem_min,
534 .maxlen = sizeof(sysctl_udp_wmem_min),
535 .mode = 0644,
536 .proc_handler = proc_dointvec_minmax,
537 .extra1 = &one
538 },
539 { } 523 { }
540}; 524};
541 525
@@ -1167,6 +1151,22 @@ static struct ctl_table ipv4_net_table[] = {
1167 .proc_handler = proc_dointvec_minmax, 1151 .proc_handler = proc_dointvec_minmax,
1168 .extra1 = &one, 1152 .extra1 = &one,
1169 }, 1153 },
1154 {
1155 .procname = "udp_rmem_min",
1156 .data = &init_net.ipv4.sysctl_udp_rmem_min,
1157 .maxlen = sizeof(init_net.ipv4.sysctl_udp_rmem_min),
1158 .mode = 0644,
1159 .proc_handler = proc_dointvec_minmax,
1160 .extra1 = &one
1161 },
1162 {
1163 .procname = "udp_wmem_min",
1164 .data = &init_net.ipv4.sysctl_udp_wmem_min,
1165 .maxlen = sizeof(init_net.ipv4.sysctl_udp_wmem_min),
1166 .mode = 0644,
1167 .proc_handler = proc_dointvec_minmax,
1168 .extra1 = &one
1169 },
1170 { } 1170 { }
1171}; 1171};
1172 1172
@@ -1219,6 +1219,7 @@ static __net_exit void ipv4_sysctl_exit_net(struct net *net)
1219static __net_initdata struct pernet_operations ipv4_sysctl_ops = { 1219static __net_initdata struct pernet_operations ipv4_sysctl_ops = {
1220 .init = ipv4_sysctl_init_net, 1220 .init = ipv4_sysctl_init_net,
1221 .exit = ipv4_sysctl_exit_net, 1221 .exit = ipv4_sysctl_exit_net,
1222 .async = true,
1222}; 1223};
1223 1224
1224static __init int sysctl_ipv4_init(void) 1225static __init int sysctl_ipv4_init(void)
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 8b8059b7af4d..0c31be306572 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -453,6 +453,7 @@ void tcp_init_sock(struct sock *sk)
453 sk->sk_rcvbuf = sock_net(sk)->ipv4.sysctl_tcp_rmem[1]; 453 sk->sk_rcvbuf = sock_net(sk)->ipv4.sysctl_tcp_rmem[1];
454 454
455 sk_sockets_allocated_inc(sk); 455 sk_sockets_allocated_inc(sk);
456 sk->sk_route_forced_caps = NETIF_F_GSO;
456} 457}
457EXPORT_SYMBOL(tcp_init_sock); 458EXPORT_SYMBOL(tcp_init_sock);
458 459
@@ -897,7 +898,7 @@ static unsigned int tcp_xmit_size_goal(struct sock *sk, u32 mss_now,
897 struct tcp_sock *tp = tcp_sk(sk); 898 struct tcp_sock *tp = tcp_sk(sk);
898 u32 new_size_goal, size_goal; 899 u32 new_size_goal, size_goal;
899 900
900 if (!large_allowed || !sk_can_gso(sk)) 901 if (!large_allowed)
901 return mss_now; 902 return mss_now;
902 903
903 /* Note : tcp_tso_autosize() will eventually split this later */ 904 /* Note : tcp_tso_autosize() will eventually split this later */
@@ -993,7 +994,9 @@ new_segment:
993 get_page(page); 994 get_page(page);
994 skb_fill_page_desc(skb, i, page, offset, copy); 995 skb_fill_page_desc(skb, i, page, offset, copy);
995 } 996 }
996 skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG; 997
998 if (!(flags & MSG_NO_SHARED_FRAGS))
999 skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG;
997 1000
998 skb->len += copy; 1001 skb->len += copy;
999 skb->data_len += copy; 1002 skb->data_len += copy;
@@ -1062,8 +1065,7 @@ EXPORT_SYMBOL_GPL(do_tcp_sendpages);
1062int tcp_sendpage_locked(struct sock *sk, struct page *page, int offset, 1065int tcp_sendpage_locked(struct sock *sk, struct page *page, int offset,
1063 size_t size, int flags) 1066 size_t size, int flags)
1064{ 1067{
1065 if (!(sk->sk_route_caps & NETIF_F_SG) || 1068 if (!(sk->sk_route_caps & NETIF_F_SG))
1066 !sk_check_csum_caps(sk))
1067 return sock_no_sendpage_locked(sk, page, offset, size, flags); 1069 return sock_no_sendpage_locked(sk, page, offset, size, flags);
1068 1070
1069 tcp_rate_check_app_limited(sk); /* is sending application-limited? */ 1071 tcp_rate_check_app_limited(sk); /* is sending application-limited? */
@@ -1102,27 +1104,11 @@ static int linear_payload_sz(bool first_skb)
1102 return 0; 1104 return 0;
1103} 1105}
1104 1106
1105static int select_size(const struct sock *sk, bool sg, bool first_skb, bool zc) 1107static int select_size(bool first_skb, bool zc)
1106{ 1108{
1107 const struct tcp_sock *tp = tcp_sk(sk); 1109 if (zc)
1108 int tmp = tp->mss_cache; 1110 return 0;
1109 1111 return linear_payload_sz(first_skb);
1110 if (sg) {
1111 if (zc)
1112 return 0;
1113
1114 if (sk_can_gso(sk)) {
1115 tmp = linear_payload_sz(first_skb);
1116 } else {
1117 int pgbreak = SKB_MAX_HEAD(MAX_TCP_HEADER);
1118
1119 if (tmp >= pgbreak &&
1120 tmp <= pgbreak + (MAX_SKB_FRAGS - 1) * PAGE_SIZE)
1121 tmp = pgbreak;
1122 }
1123 }
1124
1125 return tmp;
1126} 1112}
1127 1113
1128void tcp_free_fastopen_req(struct tcp_sock *tp) 1114void tcp_free_fastopen_req(struct tcp_sock *tp)
@@ -1187,7 +1173,7 @@ int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size)
1187 int flags, err, copied = 0; 1173 int flags, err, copied = 0;
1188 int mss_now = 0, size_goal, copied_syn = 0; 1174 int mss_now = 0, size_goal, copied_syn = 0;
1189 bool process_backlog = false; 1175 bool process_backlog = false;
1190 bool sg, zc = false; 1176 bool zc = false;
1191 long timeo; 1177 long timeo;
1192 1178
1193 flags = msg->msg_flags; 1179 flags = msg->msg_flags;
@@ -1205,7 +1191,7 @@ int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size)
1205 goto out_err; 1191 goto out_err;
1206 } 1192 }
1207 1193
1208 zc = sk_check_csum_caps(sk) && sk->sk_route_caps & NETIF_F_SG; 1194 zc = sk->sk_route_caps & NETIF_F_SG;
1209 if (!zc) 1195 if (!zc)
1210 uarg->zerocopy = 0; 1196 uarg->zerocopy = 0;
1211 } 1197 }
@@ -1268,18 +1254,12 @@ restart:
1268 if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)) 1254 if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN))
1269 goto do_error; 1255 goto do_error;
1270 1256
1271 sg = !!(sk->sk_route_caps & NETIF_F_SG);
1272
1273 while (msg_data_left(msg)) { 1257 while (msg_data_left(msg)) {
1274 int copy = 0; 1258 int copy = 0;
1275 int max = size_goal;
1276 1259
1277 skb = tcp_write_queue_tail(sk); 1260 skb = tcp_write_queue_tail(sk);
1278 if (skb) { 1261 if (skb)
1279 if (skb->ip_summed == CHECKSUM_NONE) 1262 copy = size_goal - skb->len;
1280 max = mss_now;
1281 copy = max - skb->len;
1282 }
1283 1263
1284 if (copy <= 0 || !tcp_skb_can_collapse_to(skb)) { 1264 if (copy <= 0 || !tcp_skb_can_collapse_to(skb)) {
1285 bool first_skb; 1265 bool first_skb;
@@ -1297,22 +1277,17 @@ new_segment:
1297 goto restart; 1277 goto restart;
1298 } 1278 }
1299 first_skb = tcp_rtx_and_write_queues_empty(sk); 1279 first_skb = tcp_rtx_and_write_queues_empty(sk);
1300 linear = select_size(sk, sg, first_skb, zc); 1280 linear = select_size(first_skb, zc);
1301 skb = sk_stream_alloc_skb(sk, linear, sk->sk_allocation, 1281 skb = sk_stream_alloc_skb(sk, linear, sk->sk_allocation,
1302 first_skb); 1282 first_skb);
1303 if (!skb) 1283 if (!skb)
1304 goto wait_for_memory; 1284 goto wait_for_memory;
1305 1285
1306 process_backlog = true; 1286 process_backlog = true;
1307 /* 1287 skb->ip_summed = CHECKSUM_PARTIAL;
1308 * Check whether we can use HW checksum.
1309 */
1310 if (sk_check_csum_caps(sk))
1311 skb->ip_summed = CHECKSUM_PARTIAL;
1312 1288
1313 skb_entail(sk, skb); 1289 skb_entail(sk, skb);
1314 copy = size_goal; 1290 copy = size_goal;
1315 max = size_goal;
1316 1291
1317 /* All packets are restored as if they have 1292 /* All packets are restored as if they have
1318 * already been sent. skb_mstamp isn't set to 1293 * already been sent. skb_mstamp isn't set to
@@ -1343,7 +1318,7 @@ new_segment:
1343 1318
1344 if (!skb_can_coalesce(skb, i, pfrag->page, 1319 if (!skb_can_coalesce(skb, i, pfrag->page,
1345 pfrag->offset)) { 1320 pfrag->offset)) {
1346 if (i >= sysctl_max_skb_frags || !sg) { 1321 if (i >= sysctl_max_skb_frags) {
1347 tcp_mark_push(tp, skb); 1322 tcp_mark_push(tp, skb);
1348 goto new_segment; 1323 goto new_segment;
1349 } 1324 }
@@ -1396,7 +1371,7 @@ new_segment:
1396 goto out; 1371 goto out;
1397 } 1372 }
1398 1373
1399 if (skb->len < max || (flags & MSG_OOB) || unlikely(tp->repair)) 1374 if (skb->len < size_goal || (flags & MSG_OOB) || unlikely(tp->repair))
1400 continue; 1375 continue;
1401 1376
1402 if (forced_push(tp)) { 1377 if (forced_push(tp)) {
@@ -3058,8 +3033,8 @@ struct sk_buff *tcp_get_timestamping_opt_stats(const struct sock *sk)
3058 u32 rate; 3033 u32 rate;
3059 3034
3060 stats = alloc_skb(7 * nla_total_size_64bit(sizeof(u64)) + 3035 stats = alloc_skb(7 * nla_total_size_64bit(sizeof(u64)) +
3061 3 * nla_total_size(sizeof(u32)) + 3036 5 * nla_total_size(sizeof(u32)) +
3062 2 * nla_total_size(sizeof(u8)), GFP_ATOMIC); 3037 3 * nla_total_size(sizeof(u8)), GFP_ATOMIC);
3063 if (!stats) 3038 if (!stats)
3064 return NULL; 3039 return NULL;
3065 3040
@@ -3088,6 +3063,10 @@ struct sk_buff *tcp_get_timestamping_opt_stats(const struct sock *sk)
3088 3063
3089 nla_put_u8(stats, TCP_NLA_RECUR_RETRANS, inet_csk(sk)->icsk_retransmits); 3064 nla_put_u8(stats, TCP_NLA_RECUR_RETRANS, inet_csk(sk)->icsk_retransmits);
3090 nla_put_u8(stats, TCP_NLA_DELIVERY_RATE_APP_LMT, !!tp->rate_app_limited); 3065 nla_put_u8(stats, TCP_NLA_DELIVERY_RATE_APP_LMT, !!tp->rate_app_limited);
3066 nla_put_u32(stats, TCP_NLA_SND_SSTHRESH, tp->snd_ssthresh);
3067
3068 nla_put_u32(stats, TCP_NLA_SNDQ_SIZE, tp->write_seq - tp->snd_una);
3069 nla_put_u8(stats, TCP_NLA_CA_STATE, inet_csk(sk)->icsk_ca_state);
3091 return stats; 3070 return stats;
3092} 3071}
3093 3072
diff --git a/net/ipv4/tcp_bbr.c b/net/ipv4/tcp_bbr.c
index a471f696e13c..158d105e76da 100644
--- a/net/ipv4/tcp_bbr.c
+++ b/net/ipv4/tcp_bbr.c
@@ -97,10 +97,9 @@ struct bbr {
97 packet_conservation:1, /* use packet conservation? */ 97 packet_conservation:1, /* use packet conservation? */
98 restore_cwnd:1, /* decided to revert cwnd to old value */ 98 restore_cwnd:1, /* decided to revert cwnd to old value */
99 round_start:1, /* start of packet-timed tx->ack round? */ 99 round_start:1, /* start of packet-timed tx->ack round? */
100 tso_segs_goal:7, /* segments we want in each skb we send */
101 idle_restart:1, /* restarting after idle? */ 100 idle_restart:1, /* restarting after idle? */
102 probe_rtt_round_done:1, /* a BBR_PROBE_RTT round at 4 pkts? */ 101 probe_rtt_round_done:1, /* a BBR_PROBE_RTT round at 4 pkts? */
103 unused:5, 102 unused:12,
104 lt_is_sampling:1, /* taking long-term ("LT") samples now? */ 103 lt_is_sampling:1, /* taking long-term ("LT") samples now? */
105 lt_rtt_cnt:7, /* round trips in long-term interval */ 104 lt_rtt_cnt:7, /* round trips in long-term interval */
106 lt_use_bw:1; /* use lt_bw as our bw estimate? */ 105 lt_use_bw:1; /* use lt_bw as our bw estimate? */
@@ -261,23 +260,25 @@ static void bbr_set_pacing_rate(struct sock *sk, u32 bw, int gain)
261 sk->sk_pacing_rate = rate; 260 sk->sk_pacing_rate = rate;
262} 261}
263 262
264/* Return count of segments we want in the skbs we send, or 0 for default. */ 263/* override sysctl_tcp_min_tso_segs */
265static u32 bbr_tso_segs_goal(struct sock *sk) 264static u32 bbr_min_tso_segs(struct sock *sk)
266{ 265{
267 struct bbr *bbr = inet_csk_ca(sk); 266 return sk->sk_pacing_rate < (bbr_min_tso_rate >> 3) ? 1 : 2;
268
269 return bbr->tso_segs_goal;
270} 267}
271 268
272static void bbr_set_tso_segs_goal(struct sock *sk) 269static u32 bbr_tso_segs_goal(struct sock *sk)
273{ 270{
274 struct tcp_sock *tp = tcp_sk(sk); 271 struct tcp_sock *tp = tcp_sk(sk);
275 struct bbr *bbr = inet_csk_ca(sk); 272 u32 segs, bytes;
276 u32 min_segs; 273
274 /* Sort of tcp_tso_autosize() but ignoring
275 * driver provided sk_gso_max_size.
276 */
277 bytes = min_t(u32, sk->sk_pacing_rate >> sk->sk_pacing_shift,
278 GSO_MAX_SIZE - 1 - MAX_TCP_HEADER);
279 segs = max_t(u32, bytes / tp->mss_cache, bbr_min_tso_segs(sk));
277 280
278 min_segs = sk->sk_pacing_rate < (bbr_min_tso_rate >> 3) ? 1 : 2; 281 return min(segs, 0x7FU);
279 bbr->tso_segs_goal = min(tcp_tso_autosize(sk, tp->mss_cache, min_segs),
280 0x7FU);
281} 282}
282 283
283/* Save "last known good" cwnd so we can restore it after losses or PROBE_RTT */ 284/* Save "last known good" cwnd so we can restore it after losses or PROBE_RTT */
@@ -348,7 +349,7 @@ static u32 bbr_target_cwnd(struct sock *sk, u32 bw, int gain)
348 cwnd = (((w * gain) >> BBR_SCALE) + BW_UNIT - 1) / BW_UNIT; 349 cwnd = (((w * gain) >> BBR_SCALE) + BW_UNIT - 1) / BW_UNIT;
349 350
350 /* Allow enough full-sized skbs in flight to utilize end systems. */ 351 /* Allow enough full-sized skbs in flight to utilize end systems. */
351 cwnd += 3 * bbr->tso_segs_goal; 352 cwnd += 3 * bbr_tso_segs_goal(sk);
352 353
353 /* Reduce delayed ACKs by rounding up cwnd to the next even number. */ 354 /* Reduce delayed ACKs by rounding up cwnd to the next even number. */
354 cwnd = (cwnd + 1) & ~1U; 355 cwnd = (cwnd + 1) & ~1U;
@@ -730,6 +731,8 @@ static void bbr_check_drain(struct sock *sk, const struct rate_sample *rs)
730 bbr->mode = BBR_DRAIN; /* drain queue we created */ 731 bbr->mode = BBR_DRAIN; /* drain queue we created */
731 bbr->pacing_gain = bbr_drain_gain; /* pace slow to drain */ 732 bbr->pacing_gain = bbr_drain_gain; /* pace slow to drain */
732 bbr->cwnd_gain = bbr_high_gain; /* maintain cwnd */ 733 bbr->cwnd_gain = bbr_high_gain; /* maintain cwnd */
734 tcp_sk(sk)->snd_ssthresh =
735 bbr_target_cwnd(sk, bbr_max_bw(sk), BBR_UNIT);
733 } /* fall through to check if in-flight is already small: */ 736 } /* fall through to check if in-flight is already small: */
734 if (bbr->mode == BBR_DRAIN && 737 if (bbr->mode == BBR_DRAIN &&
735 tcp_packets_in_flight(tcp_sk(sk)) <= 738 tcp_packets_in_flight(tcp_sk(sk)) <=
@@ -824,7 +827,6 @@ static void bbr_main(struct sock *sk, const struct rate_sample *rs)
824 827
825 bw = bbr_bw(sk); 828 bw = bbr_bw(sk);
826 bbr_set_pacing_rate(sk, bw, bbr->pacing_gain); 829 bbr_set_pacing_rate(sk, bw, bbr->pacing_gain);
827 bbr_set_tso_segs_goal(sk);
828 bbr_set_cwnd(sk, rs, rs->acked_sacked, bw, bbr->cwnd_gain); 830 bbr_set_cwnd(sk, rs, rs->acked_sacked, bw, bbr->cwnd_gain);
829} 831}
830 832
@@ -834,7 +836,7 @@ static void bbr_init(struct sock *sk)
834 struct bbr *bbr = inet_csk_ca(sk); 836 struct bbr *bbr = inet_csk_ca(sk);
835 837
836 bbr->prior_cwnd = 0; 838 bbr->prior_cwnd = 0;
837 bbr->tso_segs_goal = 0; /* default segs per skb until first ACK */ 839 tp->snd_ssthresh = TCP_INFINITE_SSTHRESH;
838 bbr->rtt_cnt = 0; 840 bbr->rtt_cnt = 0;
839 bbr->next_rtt_delivered = 0; 841 bbr->next_rtt_delivered = 0;
840 bbr->prev_ca_state = TCP_CA_Open; 842 bbr->prev_ca_state = TCP_CA_Open;
@@ -887,7 +889,7 @@ static u32 bbr_undo_cwnd(struct sock *sk)
887static u32 bbr_ssthresh(struct sock *sk) 889static u32 bbr_ssthresh(struct sock *sk)
888{ 890{
889 bbr_save_cwnd(sk); 891 bbr_save_cwnd(sk);
890 return TCP_INFINITE_SSTHRESH; /* BBR does not use ssthresh */ 892 return tcp_sk(sk)->snd_ssthresh;
891} 893}
892 894
893static size_t bbr_get_info(struct sock *sk, u32 ext, int *attr, 895static size_t bbr_get_info(struct sock *sk, u32 ext, int *attr,
@@ -936,7 +938,7 @@ static struct tcp_congestion_ops tcp_bbr_cong_ops __read_mostly = {
936 .undo_cwnd = bbr_undo_cwnd, 938 .undo_cwnd = bbr_undo_cwnd,
937 .cwnd_event = bbr_cwnd_event, 939 .cwnd_event = bbr_cwnd_event,
938 .ssthresh = bbr_ssthresh, 940 .ssthresh = bbr_ssthresh,
939 .tso_segs_goal = bbr_tso_segs_goal, 941 .min_tso_segs = bbr_min_tso_segs,
940 .get_info = bbr_get_info, 942 .get_info = bbr_get_info,
941 .set_state = bbr_set_state, 943 .set_state = bbr_set_state,
942}; 944};
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 9a1b3c1c1c14..451ef3012636 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -1358,9 +1358,6 @@ static struct sk_buff *tcp_shift_skb_data(struct sock *sk, struct sk_buff *skb,
1358 int len; 1358 int len;
1359 int in_sack; 1359 int in_sack;
1360 1360
1361 if (!sk_can_gso(sk))
1362 goto fallback;
1363
1364 /* Normally R but no L won't result in plain S */ 1361 /* Normally R but no L won't result in plain S */
1365 if (!dup_sack && 1362 if (!dup_sack &&
1366 (TCP_SKB_CB(skb)->sacked & (TCPCB_LOST|TCPCB_SACKED_RETRANS)) == TCPCB_SACKED_RETRANS) 1363 (TCP_SKB_CB(skb)->sacked & (TCPCB_LOST|TCPCB_SACKED_RETRANS)) == TCPCB_SACKED_RETRANS)
@@ -5862,10 +5859,12 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb)
5862 tp->rx_opt.saw_tstamp = 0; 5859 tp->rx_opt.saw_tstamp = 0;
5863 req = tp->fastopen_rsk; 5860 req = tp->fastopen_rsk;
5864 if (req) { 5861 if (req) {
5862 bool req_stolen;
5863
5865 WARN_ON_ONCE(sk->sk_state != TCP_SYN_RECV && 5864 WARN_ON_ONCE(sk->sk_state != TCP_SYN_RECV &&
5866 sk->sk_state != TCP_FIN_WAIT1); 5865 sk->sk_state != TCP_FIN_WAIT1);
5867 5866
5868 if (!tcp_check_req(sk, skb, req, true)) 5867 if (!tcp_check_req(sk, skb, req, true, &req_stolen))
5869 goto discard; 5868 goto discard;
5870 } 5869 }
5871 5870
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index f8ad397e285e..2c6aec2643e8 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -561,16 +561,9 @@ void __tcp_v4_send_check(struct sk_buff *skb, __be32 saddr, __be32 daddr)
561{ 561{
562 struct tcphdr *th = tcp_hdr(skb); 562 struct tcphdr *th = tcp_hdr(skb);
563 563
564 if (skb->ip_summed == CHECKSUM_PARTIAL) { 564 th->check = ~tcp_v4_check(skb->len, saddr, daddr, 0);
565 th->check = ~tcp_v4_check(skb->len, saddr, daddr, 0); 565 skb->csum_start = skb_transport_header(skb) - skb->head;
566 skb->csum_start = skb_transport_header(skb) - skb->head; 566 skb->csum_offset = offsetof(struct tcphdr, check);
567 skb->csum_offset = offsetof(struct tcphdr, check);
568 } else {
569 th->check = tcp_v4_check(skb->len, saddr, daddr,
570 csum_partial(th,
571 th->doff << 2,
572 skb->csum));
573 }
574} 567}
575 568
576/* This routine computes an IPv4 TCP checksum. */ 569/* This routine computes an IPv4 TCP checksum. */
@@ -1672,6 +1665,7 @@ process:
1672 1665
1673 if (sk->sk_state == TCP_NEW_SYN_RECV) { 1666 if (sk->sk_state == TCP_NEW_SYN_RECV) {
1674 struct request_sock *req = inet_reqsk(sk); 1667 struct request_sock *req = inet_reqsk(sk);
1668 bool req_stolen = false;
1675 struct sock *nsk; 1669 struct sock *nsk;
1676 1670
1677 sk = req->rsk_listener; 1671 sk = req->rsk_listener;
@@ -1694,10 +1688,20 @@ process:
1694 th = (const struct tcphdr *)skb->data; 1688 th = (const struct tcphdr *)skb->data;
1695 iph = ip_hdr(skb); 1689 iph = ip_hdr(skb);
1696 tcp_v4_fill_cb(skb, iph, th); 1690 tcp_v4_fill_cb(skb, iph, th);
1697 nsk = tcp_check_req(sk, skb, req, false); 1691 nsk = tcp_check_req(sk, skb, req, false, &req_stolen);
1698 } 1692 }
1699 if (!nsk) { 1693 if (!nsk) {
1700 reqsk_put(req); 1694 reqsk_put(req);
1695 if (req_stolen) {
1696 /* Another cpu got exclusive access to req
1697 * and created a full blown socket.
1698 * Try to feed this packet to this socket
1699 * instead of discarding it.
1700 */
1701 tcp_v4_restore_cb(skb);
1702 sock_put(sk);
1703 goto lookup;
1704 }
1701 goto discard_and_relse; 1705 goto discard_and_relse;
1702 } 1706 }
1703 if (nsk == sk) { 1707 if (nsk == sk) {
@@ -2387,6 +2391,7 @@ static void __net_exit tcp4_proc_exit_net(struct net *net)
2387static struct pernet_operations tcp4_net_ops = { 2391static struct pernet_operations tcp4_net_ops = {
2388 .init = tcp4_proc_init_net, 2392 .init = tcp4_proc_init_net,
2389 .exit = tcp4_proc_exit_net, 2393 .exit = tcp4_proc_exit_net,
2394 .async = true,
2390}; 2395};
2391 2396
2392int __init tcp4_proc_init(void) 2397int __init tcp4_proc_init(void)
@@ -2573,6 +2578,7 @@ static struct pernet_operations __net_initdata tcp_sk_ops = {
2573 .init = tcp_sk_init, 2578 .init = tcp_sk_init,
2574 .exit = tcp_sk_exit, 2579 .exit = tcp_sk_exit,
2575 .exit_batch = tcp_sk_exit_batch, 2580 .exit_batch = tcp_sk_exit_batch,
2581 .async = true,
2576}; 2582};
2577 2583
2578void __init tcp_v4_init(void) 2584void __init tcp_v4_init(void)
diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c
index 03b51cdcc731..aa6fea9f3328 100644
--- a/net/ipv4/tcp_metrics.c
+++ b/net/ipv4/tcp_metrics.c
@@ -1024,6 +1024,7 @@ static void __net_exit tcp_net_metrics_exit_batch(struct list_head *net_exit_lis
1024static __net_initdata struct pernet_operations tcp_net_metrics_ops = { 1024static __net_initdata struct pernet_operations tcp_net_metrics_ops = {
1025 .init = tcp_net_metrics_init, 1025 .init = tcp_net_metrics_init,
1026 .exit_batch = tcp_net_metrics_exit_batch, 1026 .exit_batch = tcp_net_metrics_exit_batch,
1027 .async = true,
1027}; 1028};
1028 1029
1029void __init tcp_metrics_init(void) 1030void __init tcp_metrics_init(void)
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index a8384b0c11f8..e7e36433cdb5 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -578,7 +578,7 @@ EXPORT_SYMBOL(tcp_create_openreq_child);
578 578
579struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, 579struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
580 struct request_sock *req, 580 struct request_sock *req,
581 bool fastopen) 581 bool fastopen, bool *req_stolen)
582{ 582{
583 struct tcp_options_received tmp_opt; 583 struct tcp_options_received tmp_opt;
584 struct sock *child; 584 struct sock *child;
@@ -785,6 +785,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
785 785
786 sock_rps_save_rxhash(child, skb); 786 sock_rps_save_rxhash(child, skb);
787 tcp_synack_rtt_meas(child, req); 787 tcp_synack_rtt_meas(child, req);
788 *req_stolen = !own_req;
788 return inet_csk_complete_hashdance(sk, child, req, own_req); 789 return inet_csk_complete_hashdance(sk, child, req, own_req);
789 790
790listen_overflow: 791listen_overflow:
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 6818042cd8a9..383cac0ff0ec 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -1206,7 +1206,7 @@ static void tcp_queue_skb(struct sock *sk, struct sk_buff *skb)
1206/* Initialize TSO segments for a packet. */ 1206/* Initialize TSO segments for a packet. */
1207static void tcp_set_skb_tso_segs(struct sk_buff *skb, unsigned int mss_now) 1207static void tcp_set_skb_tso_segs(struct sk_buff *skb, unsigned int mss_now)
1208{ 1208{
1209 if (skb->len <= mss_now || skb->ip_summed == CHECKSUM_NONE) { 1209 if (skb->len <= mss_now) {
1210 /* Avoid the costly divide in the normal 1210 /* Avoid the costly divide in the normal
1211 * non-TSO case. 1211 * non-TSO case.
1212 */ 1212 */
@@ -1335,21 +1335,9 @@ int tcp_fragment(struct sock *sk, enum tcp_queue tcp_queue,
1335 TCP_SKB_CB(buff)->sacked = TCP_SKB_CB(skb)->sacked; 1335 TCP_SKB_CB(buff)->sacked = TCP_SKB_CB(skb)->sacked;
1336 tcp_skb_fragment_eor(skb, buff); 1336 tcp_skb_fragment_eor(skb, buff);
1337 1337
1338 if (!skb_shinfo(skb)->nr_frags && skb->ip_summed != CHECKSUM_PARTIAL) { 1338 skb_split(skb, buff, len);
1339 /* Copy and checksum data tail into the new buffer. */
1340 buff->csum = csum_partial_copy_nocheck(skb->data + len,
1341 skb_put(buff, nsize),
1342 nsize, 0);
1343
1344 skb_trim(skb, len);
1345
1346 skb->csum = csum_block_sub(skb->csum, buff->csum, len);
1347 } else {
1348 skb->ip_summed = CHECKSUM_PARTIAL;
1349 skb_split(skb, buff, len);
1350 }
1351 1339
1352 buff->ip_summed = skb->ip_summed; 1340 buff->ip_summed = CHECKSUM_PARTIAL;
1353 1341
1354 buff->tstamp = skb->tstamp; 1342 buff->tstamp = skb->tstamp;
1355 tcp_fragment_tstamp(skb, buff); 1343 tcp_fragment_tstamp(skb, buff);
@@ -1715,8 +1703,8 @@ static bool tcp_nagle_check(bool partial, const struct tcp_sock *tp,
1715/* Return how many segs we'd like on a TSO packet, 1703/* Return how many segs we'd like on a TSO packet,
1716 * to send one TSO packet per ms 1704 * to send one TSO packet per ms
1717 */ 1705 */
1718u32 tcp_tso_autosize(const struct sock *sk, unsigned int mss_now, 1706static u32 tcp_tso_autosize(const struct sock *sk, unsigned int mss_now,
1719 int min_tso_segs) 1707 int min_tso_segs)
1720{ 1708{
1721 u32 bytes, segs; 1709 u32 bytes, segs;
1722 1710
@@ -1732,7 +1720,6 @@ u32 tcp_tso_autosize(const struct sock *sk, unsigned int mss_now,
1732 1720
1733 return segs; 1721 return segs;
1734} 1722}
1735EXPORT_SYMBOL(tcp_tso_autosize);
1736 1723
1737/* Return the number of segments we want in the skb we are transmitting. 1724/* Return the number of segments we want in the skb we are transmitting.
1738 * See if congestion control module wants to decide; otherwise, autosize. 1725 * See if congestion control module wants to decide; otherwise, autosize.
@@ -1740,11 +1727,13 @@ EXPORT_SYMBOL(tcp_tso_autosize);
1740static u32 tcp_tso_segs(struct sock *sk, unsigned int mss_now) 1727static u32 tcp_tso_segs(struct sock *sk, unsigned int mss_now)
1741{ 1728{
1742 const struct tcp_congestion_ops *ca_ops = inet_csk(sk)->icsk_ca_ops; 1729 const struct tcp_congestion_ops *ca_ops = inet_csk(sk)->icsk_ca_ops;
1743 u32 tso_segs = ca_ops->tso_segs_goal ? ca_ops->tso_segs_goal(sk) : 0; 1730 u32 min_tso, tso_segs;
1744 1731
1745 if (!tso_segs) 1732 min_tso = ca_ops->min_tso_segs ?
1746 tso_segs = tcp_tso_autosize(sk, mss_now, 1733 ca_ops->min_tso_segs(sk) :
1747 sock_net(sk)->ipv4.sysctl_tcp_min_tso_segs); 1734 sock_net(sk)->ipv4.sysctl_tcp_min_tso_segs;
1735
1736 tso_segs = tcp_tso_autosize(sk, mss_now, min_tso);
1748 return min_t(u32, tso_segs, sk->sk_gso_max_segs); 1737 return min_t(u32, tso_segs, sk->sk_gso_max_segs);
1749} 1738}
1750 1739
@@ -1902,7 +1891,7 @@ static int tso_fragment(struct sock *sk, enum tcp_queue tcp_queue,
1902 1891
1903 tcp_skb_fragment_eor(skb, buff); 1892 tcp_skb_fragment_eor(skb, buff);
1904 1893
1905 buff->ip_summed = skb->ip_summed = CHECKSUM_PARTIAL; 1894 buff->ip_summed = CHECKSUM_PARTIAL;
1906 skb_split(skb, buff, len); 1895 skb_split(skb, buff, len);
1907 tcp_fragment_tstamp(skb, buff); 1896 tcp_fragment_tstamp(skb, buff);
1908 1897
@@ -2135,7 +2124,7 @@ static int tcp_mtu_probe(struct sock *sk)
2135 TCP_SKB_CB(nskb)->tcp_flags = TCPHDR_ACK; 2124 TCP_SKB_CB(nskb)->tcp_flags = TCPHDR_ACK;
2136 TCP_SKB_CB(nskb)->sacked = 0; 2125 TCP_SKB_CB(nskb)->sacked = 0;
2137 nskb->csum = 0; 2126 nskb->csum = 0;
2138 nskb->ip_summed = skb->ip_summed; 2127 nskb->ip_summed = CHECKSUM_PARTIAL;
2139 2128
2140 tcp_insert_write_queue_before(nskb, skb, sk); 2129 tcp_insert_write_queue_before(nskb, skb, sk);
2141 tcp_highest_sack_replace(sk, skb, nskb); 2130 tcp_highest_sack_replace(sk, skb, nskb);
@@ -2143,14 +2132,7 @@ static int tcp_mtu_probe(struct sock *sk)
2143 len = 0; 2132 len = 0;
2144 tcp_for_write_queue_from_safe(skb, next, sk) { 2133 tcp_for_write_queue_from_safe(skb, next, sk) {
2145 copy = min_t(int, skb->len, probe_size - len); 2134 copy = min_t(int, skb->len, probe_size - len);
2146 if (nskb->ip_summed) { 2135 skb_copy_bits(skb, 0, skb_put(nskb, copy), copy);
2147 skb_copy_bits(skb, 0, skb_put(nskb, copy), copy);
2148 } else {
2149 __wsum csum = skb_copy_and_csum_bits(skb, 0,
2150 skb_put(nskb, copy),
2151 copy, 0);
2152 nskb->csum = csum_block_add(nskb->csum, csum, len);
2153 }
2154 2136
2155 if (skb->len <= copy) { 2137 if (skb->len <= copy) {
2156 /* We've eaten all the data from this skb. 2138 /* We've eaten all the data from this skb.
@@ -2167,9 +2149,6 @@ static int tcp_mtu_probe(struct sock *sk)
2167 ~(TCPHDR_FIN|TCPHDR_PSH); 2149 ~(TCPHDR_FIN|TCPHDR_PSH);
2168 if (!skb_shinfo(skb)->nr_frags) { 2150 if (!skb_shinfo(skb)->nr_frags) {
2169 skb_pull(skb, copy); 2151 skb_pull(skb, copy);
2170 if (skb->ip_summed != CHECKSUM_PARTIAL)
2171 skb->csum = csum_partial(skb->data,
2172 skb->len, 0);
2173 } else { 2152 } else {
2174 __pskb_trim_head(skb, copy); 2153 __pskb_trim_head(skb, copy);
2175 tcp_set_skb_tso_segs(skb, mss_now); 2154 tcp_set_skb_tso_segs(skb, mss_now);
@@ -2747,12 +2726,6 @@ static bool tcp_collapse_retrans(struct sock *sk, struct sk_buff *skb)
2747 } 2726 }
2748 tcp_highest_sack_replace(sk, next_skb, skb); 2727 tcp_highest_sack_replace(sk, next_skb, skb);
2749 2728
2750 if (next_skb->ip_summed == CHECKSUM_PARTIAL)
2751 skb->ip_summed = CHECKSUM_PARTIAL;
2752
2753 if (skb->ip_summed != CHECKSUM_PARTIAL)
2754 skb->csum = csum_block_add(skb->csum, next_skb->csum, skb_size);
2755
2756 /* Update sequence range on original skb. */ 2729 /* Update sequence range on original skb. */
2757 TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(next_skb)->end_seq; 2730 TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(next_skb)->end_seq;
2758 2731
diff --git a/net/ipv4/tunnel4.c b/net/ipv4/tunnel4.c
index ec35eaa5c029..c0630013c1ae 100644
--- a/net/ipv4/tunnel4.c
+++ b/net/ipv4/tunnel4.c
@@ -90,7 +90,7 @@ EXPORT_SYMBOL(xfrm4_tunnel_deregister);
90 for (handler = rcu_dereference(head); \ 90 for (handler = rcu_dereference(head); \
91 handler != NULL; \ 91 handler != NULL; \
92 handler = rcu_dereference(handler->next)) \ 92 handler = rcu_dereference(handler->next)) \
93 93
94static int tunnel4_rcv(struct sk_buff *skb) 94static int tunnel4_rcv(struct sk_buff *skb)
95{ 95{
96 struct xfrm_tunnel *handler; 96 struct xfrm_tunnel *handler;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index e5ef7c38c934..908fc02fb4f8 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -122,12 +122,6 @@ EXPORT_SYMBOL(udp_table);
122long sysctl_udp_mem[3] __read_mostly; 122long sysctl_udp_mem[3] __read_mostly;
123EXPORT_SYMBOL(sysctl_udp_mem); 123EXPORT_SYMBOL(sysctl_udp_mem);
124 124
125int sysctl_udp_rmem_min __read_mostly;
126EXPORT_SYMBOL(sysctl_udp_rmem_min);
127
128int sysctl_udp_wmem_min __read_mostly;
129EXPORT_SYMBOL(sysctl_udp_wmem_min);
130
131atomic_long_t udp_memory_allocated; 125atomic_long_t udp_memory_allocated;
132EXPORT_SYMBOL(udp_memory_allocated); 126EXPORT_SYMBOL(udp_memory_allocated);
133 127
@@ -2533,35 +2527,35 @@ int udp_abort(struct sock *sk, int err)
2533EXPORT_SYMBOL_GPL(udp_abort); 2527EXPORT_SYMBOL_GPL(udp_abort);
2534 2528
2535struct proto udp_prot = { 2529struct proto udp_prot = {
2536 .name = "UDP", 2530 .name = "UDP",
2537 .owner = THIS_MODULE, 2531 .owner = THIS_MODULE,
2538 .close = udp_lib_close, 2532 .close = udp_lib_close,
2539 .connect = ip4_datagram_connect, 2533 .connect = ip4_datagram_connect,
2540 .disconnect = udp_disconnect, 2534 .disconnect = udp_disconnect,
2541 .ioctl = udp_ioctl, 2535 .ioctl = udp_ioctl,
2542 .init = udp_init_sock, 2536 .init = udp_init_sock,
2543 .destroy = udp_destroy_sock, 2537 .destroy = udp_destroy_sock,
2544 .setsockopt = udp_setsockopt, 2538 .setsockopt = udp_setsockopt,
2545 .getsockopt = udp_getsockopt, 2539 .getsockopt = udp_getsockopt,
2546 .sendmsg = udp_sendmsg, 2540 .sendmsg = udp_sendmsg,
2547 .recvmsg = udp_recvmsg, 2541 .recvmsg = udp_recvmsg,
2548 .sendpage = udp_sendpage, 2542 .sendpage = udp_sendpage,
2549 .release_cb = ip4_datagram_release_cb, 2543 .release_cb = ip4_datagram_release_cb,
2550 .hash = udp_lib_hash, 2544 .hash = udp_lib_hash,
2551 .unhash = udp_lib_unhash, 2545 .unhash = udp_lib_unhash,
2552 .rehash = udp_v4_rehash, 2546 .rehash = udp_v4_rehash,
2553 .get_port = udp_v4_get_port, 2547 .get_port = udp_v4_get_port,
2554 .memory_allocated = &udp_memory_allocated, 2548 .memory_allocated = &udp_memory_allocated,
2555 .sysctl_mem = sysctl_udp_mem, 2549 .sysctl_mem = sysctl_udp_mem,
2556 .sysctl_wmem = &sysctl_udp_wmem_min, 2550 .sysctl_wmem_offset = offsetof(struct net, ipv4.sysctl_udp_wmem_min),
2557 .sysctl_rmem = &sysctl_udp_rmem_min, 2551 .sysctl_rmem_offset = offsetof(struct net, ipv4.sysctl_udp_rmem_min),
2558 .obj_size = sizeof(struct udp_sock), 2552 .obj_size = sizeof(struct udp_sock),
2559 .h.udp_table = &udp_table, 2553 .h.udp_table = &udp_table,
2560#ifdef CONFIG_COMPAT 2554#ifdef CONFIG_COMPAT
2561 .compat_setsockopt = compat_udp_setsockopt, 2555 .compat_setsockopt = compat_udp_setsockopt,
2562 .compat_getsockopt = compat_udp_getsockopt, 2556 .compat_getsockopt = compat_udp_getsockopt,
2563#endif 2557#endif
2564 .diag_destroy = udp_abort, 2558 .diag_destroy = udp_abort,
2565}; 2559};
2566EXPORT_SYMBOL(udp_prot); 2560EXPORT_SYMBOL(udp_prot);
2567 2561
@@ -2762,6 +2756,7 @@ static void __net_exit udp4_proc_exit_net(struct net *net)
2762static struct pernet_operations udp4_net_ops = { 2756static struct pernet_operations udp4_net_ops = {
2763 .init = udp4_proc_init_net, 2757 .init = udp4_proc_init_net,
2764 .exit = udp4_proc_exit_net, 2758 .exit = udp4_proc_exit_net,
2759 .async = true,
2765}; 2760};
2766 2761
2767int __init udp4_proc_init(void) 2762int __init udp4_proc_init(void)
@@ -2830,6 +2825,26 @@ u32 udp_flow_hashrnd(void)
2830} 2825}
2831EXPORT_SYMBOL(udp_flow_hashrnd); 2826EXPORT_SYMBOL(udp_flow_hashrnd);
2832 2827
2828static void __udp_sysctl_init(struct net *net)
2829{
2830 net->ipv4.sysctl_udp_rmem_min = SK_MEM_QUANTUM;
2831 net->ipv4.sysctl_udp_wmem_min = SK_MEM_QUANTUM;
2832
2833#ifdef CONFIG_NET_L3_MASTER_DEV
2834 net->ipv4.sysctl_udp_l3mdev_accept = 0;
2835#endif
2836}
2837
2838static int __net_init udp_sysctl_init(struct net *net)
2839{
2840 __udp_sysctl_init(net);
2841 return 0;
2842}
2843
2844static struct pernet_operations __net_initdata udp_sysctl_ops = {
2845 .init = udp_sysctl_init,
2846};
2847
2833void __init udp_init(void) 2848void __init udp_init(void)
2834{ 2849{
2835 unsigned long limit; 2850 unsigned long limit;
@@ -2842,8 +2857,7 @@ void __init udp_init(void)
2842 sysctl_udp_mem[1] = limit; 2857 sysctl_udp_mem[1] = limit;
2843 sysctl_udp_mem[2] = sysctl_udp_mem[0] * 2; 2858 sysctl_udp_mem[2] = sysctl_udp_mem[0] * 2;
2844 2859
2845 sysctl_udp_rmem_min = SK_MEM_QUANTUM; 2860 __udp_sysctl_init(&init_net);
2846 sysctl_udp_wmem_min = SK_MEM_QUANTUM;
2847 2861
2848 /* 16 spinlocks per cpu */ 2862 /* 16 spinlocks per cpu */
2849 udp_busylocks_log = ilog2(nr_cpu_ids) + 4; 2863 udp_busylocks_log = ilog2(nr_cpu_ids) + 4;
@@ -2853,4 +2867,7 @@ void __init udp_init(void)
2853 panic("UDP: failed to alloc udp_busylocks\n"); 2867 panic("UDP: failed to alloc udp_busylocks\n");
2854 for (i = 0; i < (1U << udp_busylocks_log); i++) 2868 for (i = 0; i < (1U << udp_busylocks_log); i++)
2855 spin_lock_init(udp_busylocks + i); 2869 spin_lock_init(udp_busylocks + i);
2870
2871 if (register_pernet_subsys(&udp_sysctl_ops))
2872 panic("UDP: failed to init sysctl parameters.\n");
2856} 2873}
diff --git a/net/ipv4/udplite.c b/net/ipv4/udplite.c
index f96614e9b9a5..72f2c3806408 100644
--- a/net/ipv4/udplite.c
+++ b/net/ipv4/udplite.c
@@ -104,6 +104,7 @@ static void __net_exit udplite4_proc_exit_net(struct net *net)
104static struct pernet_operations udplite4_net_ops = { 104static struct pernet_operations udplite4_net_ops = {
105 .init = udplite4_proc_init_net, 105 .init = udplite4_proc_init_net,
106 .exit = udplite4_proc_exit_net, 106 .exit = udplite4_proc_exit_net,
107 .async = true,
107}; 108};
108 109
109static __init int udplite4_proc_init(void) 110static __init int udplite4_proc_init(void)
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index fbebda67ac1b..6c76a757fa4a 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -101,7 +101,6 @@ static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
101 xdst->u.rt.rt_uses_gateway = rt->rt_uses_gateway; 101 xdst->u.rt.rt_uses_gateway = rt->rt_uses_gateway;
102 xdst->u.rt.rt_pmtu = rt->rt_pmtu; 102 xdst->u.rt.rt_pmtu = rt->rt_pmtu;
103 xdst->u.rt.rt_mtu_locked = rt->rt_mtu_locked; 103 xdst->u.rt.rt_mtu_locked = rt->rt_mtu_locked;
104 xdst->u.rt.rt_table_id = rt->rt_table_id;
105 INIT_LIST_HEAD(&xdst->u.rt.rt_uncached); 104 INIT_LIST_HEAD(&xdst->u.rt.rt_uncached);
106 rt_add_uncached_list(&xdst->u.rt); 105 rt_add_uncached_list(&xdst->u.rt);
107 106
@@ -368,6 +367,7 @@ static void __net_exit xfrm4_net_exit(struct net *net)
368static struct pernet_operations __net_initdata xfrm4_net_ops = { 367static struct pernet_operations __net_initdata xfrm4_net_ops = {
369 .init = xfrm4_net_init, 368 .init = xfrm4_net_init,
370 .exit = xfrm4_net_exit, 369 .exit = xfrm4_net_exit,
370 .async = true,
371}; 371};
372 372
373static void __init xfrm4_policy_init(void) 373static void __init xfrm4_policy_init(void)
@@ -382,4 +382,3 @@ void __init xfrm4_init(void)
382 xfrm4_protocol_init(); 382 xfrm4_protocol_init();
383 register_pernet_subsys(&xfrm4_net_ops); 383 register_pernet_subsys(&xfrm4_net_ops);
384} 384}
385
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig
index ea71e4b0ab7a..6794ddf0547c 100644
--- a/net/ipv6/Kconfig
+++ b/net/ipv6/Kconfig
@@ -278,6 +278,7 @@ config IPV6_SUBTREES
278config IPV6_MROUTE 278config IPV6_MROUTE
279 bool "IPv6: multicast routing" 279 bool "IPv6: multicast routing"
280 depends on IPV6 280 depends on IPV6
281 select IP_MROUTE_COMMON
281 ---help--- 282 ---help---
282 Experimental support for IPv6 multicast forwarding. 283 Experimental support for IPv6 multicast forwarding.
283 If unsure, say N. 284 If unsure, say N.
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index e1846b97ee69..6fd4bbdc444f 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1459,6 +1459,21 @@ static bool ipv6_use_optimistic_addr(struct net *net,
1459#endif 1459#endif
1460} 1460}
1461 1461
1462static bool ipv6_allow_optimistic_dad(struct net *net,
1463 struct inet6_dev *idev)
1464{
1465#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
1466 if (!idev)
1467 return false;
1468 if (!net->ipv6.devconf_all->optimistic_dad && !idev->cnf.optimistic_dad)
1469 return false;
1470
1471 return true;
1472#else
1473 return false;
1474#endif
1475}
1476
1462static int ipv6_get_saddr_eval(struct net *net, 1477static int ipv6_get_saddr_eval(struct net *net,
1463 struct ipv6_saddr_score *score, 1478 struct ipv6_saddr_score *score,
1464 struct ipv6_saddr_dst *dst, 1479 struct ipv6_saddr_dst *dst,
@@ -1836,22 +1851,42 @@ static int ipv6_count_addresses(const struct inet6_dev *idev)
1836int ipv6_chk_addr(struct net *net, const struct in6_addr *addr, 1851int ipv6_chk_addr(struct net *net, const struct in6_addr *addr,
1837 const struct net_device *dev, int strict) 1852 const struct net_device *dev, int strict)
1838{ 1853{
1839 return ipv6_chk_addr_and_flags(net, addr, dev, strict, IFA_F_TENTATIVE); 1854 return ipv6_chk_addr_and_flags(net, addr, dev, !dev,
1855 strict, IFA_F_TENTATIVE);
1840} 1856}
1841EXPORT_SYMBOL(ipv6_chk_addr); 1857EXPORT_SYMBOL(ipv6_chk_addr);
1842 1858
1859/* device argument is used to find the L3 domain of interest. If
1860 * skip_dev_check is set, then the ifp device is not checked against
1861 * the passed in dev argument. So the 2 cases for addresses checks are:
1862 * 1. does the address exist in the L3 domain that dev is part of
1863 * (skip_dev_check = true), or
1864 *
1865 * 2. does the address exist on the specific device
1866 * (skip_dev_check = false)
1867 */
1843int ipv6_chk_addr_and_flags(struct net *net, const struct in6_addr *addr, 1868int ipv6_chk_addr_and_flags(struct net *net, const struct in6_addr *addr,
1844 const struct net_device *dev, int strict, 1869 const struct net_device *dev, bool skip_dev_check,
1845 u32 banned_flags) 1870 int strict, u32 banned_flags)
1846{ 1871{
1847 unsigned int hash = inet6_addr_hash(net, addr); 1872 unsigned int hash = inet6_addr_hash(net, addr);
1873 const struct net_device *l3mdev;
1848 struct inet6_ifaddr *ifp; 1874 struct inet6_ifaddr *ifp;
1849 u32 ifp_flags; 1875 u32 ifp_flags;
1850 1876
1851 rcu_read_lock(); 1877 rcu_read_lock();
1878
1879 l3mdev = l3mdev_master_dev_rcu(dev);
1880 if (skip_dev_check)
1881 dev = NULL;
1882
1852 hlist_for_each_entry_rcu(ifp, &inet6_addr_lst[hash], addr_lst) { 1883 hlist_for_each_entry_rcu(ifp, &inet6_addr_lst[hash], addr_lst) {
1853 if (!net_eq(dev_net(ifp->idev->dev), net)) 1884 if (!net_eq(dev_net(ifp->idev->dev), net))
1854 continue; 1885 continue;
1886
1887 if (l3mdev_master_dev_rcu(ifp->idev->dev) != l3mdev)
1888 continue;
1889
1855 /* Decouple optimistic from tentative for evaluation here. 1890 /* Decouple optimistic from tentative for evaluation here.
1856 * Ban optimistic addresses explicitly, when required. 1891 * Ban optimistic addresses explicitly, when required.
1857 */ 1892 */
@@ -1968,6 +2003,8 @@ static void addrconf_dad_stop(struct inet6_ifaddr *ifp, int dad_failed)
1968 spin_lock_bh(&ifp->lock); 2003 spin_lock_bh(&ifp->lock);
1969 addrconf_del_dad_work(ifp); 2004 addrconf_del_dad_work(ifp);
1970 ifp->flags |= IFA_F_TENTATIVE; 2005 ifp->flags |= IFA_F_TENTATIVE;
2006 if (dad_failed)
2007 ifp->flags &= ~IFA_F_OPTIMISTIC;
1971 spin_unlock_bh(&ifp->lock); 2008 spin_unlock_bh(&ifp->lock);
1972 if (dad_failed) 2009 if (dad_failed)
1973 ipv6_ifa_notify(0, ifp); 2010 ipv6_ifa_notify(0, ifp);
@@ -4257,6 +4294,7 @@ static void __net_exit if6_proc_net_exit(struct net *net)
4257static struct pernet_operations if6_proc_net_ops = { 4294static struct pernet_operations if6_proc_net_ops = {
4258 .init = if6_proc_net_init, 4295 .init = if6_proc_net_init,
4259 .exit = if6_proc_net_exit, 4296 .exit = if6_proc_net_exit,
4297 .async = true,
4260}; 4298};
4261 4299
4262int __init if6_proc_init(void) 4300int __init if6_proc_init(void)
@@ -4500,6 +4538,9 @@ static int inet6_addr_modify(struct inet6_ifaddr *ifp, u32 ifa_flags,
4500 (ifp->flags & IFA_F_TEMPORARY || ifp->prefix_len != 64)) 4538 (ifp->flags & IFA_F_TEMPORARY || ifp->prefix_len != 64))
4501 return -EINVAL; 4539 return -EINVAL;
4502 4540
4541 if (!(ifp->flags & IFA_F_TENTATIVE) || ifp->flags & IFA_F_DADFAILED)
4542 ifa_flags &= ~IFA_F_OPTIMISTIC;
4543
4503 timeout = addrconf_timeout_fixup(valid_lft, HZ); 4544 timeout = addrconf_timeout_fixup(valid_lft, HZ);
4504 if (addrconf_finite_timeout(timeout)) { 4545 if (addrconf_finite_timeout(timeout)) {
4505 expires = jiffies_to_clock_t(timeout * HZ); 4546 expires = jiffies_to_clock_t(timeout * HZ);
@@ -4573,6 +4614,7 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,
4573 struct in6_addr *pfx, *peer_pfx; 4614 struct in6_addr *pfx, *peer_pfx;
4574 struct inet6_ifaddr *ifa; 4615 struct inet6_ifaddr *ifa;
4575 struct net_device *dev; 4616 struct net_device *dev;
4617 struct inet6_dev *idev;
4576 u32 valid_lft = INFINITY_LIFE_TIME, preferred_lft = INFINITY_LIFE_TIME; 4618 u32 valid_lft = INFINITY_LIFE_TIME, preferred_lft = INFINITY_LIFE_TIME;
4577 u32 ifa_flags; 4619 u32 ifa_flags;
4578 int err; 4620 int err;
@@ -4606,7 +4648,19 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,
4606 4648
4607 /* We ignore other flags so far. */ 4649 /* We ignore other flags so far. */
4608 ifa_flags &= IFA_F_NODAD | IFA_F_HOMEADDRESS | IFA_F_MANAGETEMPADDR | 4650 ifa_flags &= IFA_F_NODAD | IFA_F_HOMEADDRESS | IFA_F_MANAGETEMPADDR |
4609 IFA_F_NOPREFIXROUTE | IFA_F_MCAUTOJOIN; 4651 IFA_F_NOPREFIXROUTE | IFA_F_MCAUTOJOIN | IFA_F_OPTIMISTIC;
4652
4653 idev = ipv6_find_idev(dev);
4654 if (IS_ERR(idev))
4655 return PTR_ERR(idev);
4656
4657 if (!ipv6_allow_optimistic_dad(net, idev))
4658 ifa_flags &= ~IFA_F_OPTIMISTIC;
4659
4660 if (ifa_flags & IFA_F_NODAD && ifa_flags & IFA_F_OPTIMISTIC) {
4661 NL_SET_ERR_MSG(extack, "IFA_F_NODAD and IFA_F_OPTIMISTIC are mutually exclusive");
4662 return -EINVAL;
4663 }
4610 4664
4611 ifa = ipv6_get_ifaddr(net, pfx, dev, 1); 4665 ifa = ipv6_get_ifaddr(net, pfx, dev, 1);
4612 if (!ifa) { 4666 if (!ifa) {
@@ -6550,6 +6604,7 @@ static void __net_exit addrconf_exit_net(struct net *net)
6550static struct pernet_operations addrconf_ops = { 6604static struct pernet_operations addrconf_ops = {
6551 .init = addrconf_init_net, 6605 .init = addrconf_init_net,
6552 .exit = addrconf_exit_net, 6606 .exit = addrconf_exit_net,
6607 .async = true,
6553}; 6608};
6554 6609
6555static struct rtnl_af_ops inet6_ops __read_mostly = { 6610static struct rtnl_af_ops inet6_ops __read_mostly = {
diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c
index 1d6ced37ad71..ba2e63633370 100644
--- a/net/ipv6/addrlabel.c
+++ b/net/ipv6/addrlabel.c
@@ -344,6 +344,7 @@ static void __net_exit ip6addrlbl_net_exit(struct net *net)
344static struct pernet_operations ipv6_addr_label_ops = { 344static struct pernet_operations ipv6_addr_label_ops = {
345 .init = ip6addrlbl_net_init, 345 .init = ip6addrlbl_net_init,
346 .exit = ip6addrlbl_net_exit, 346 .exit = ip6addrlbl_net_exit,
347 .async = true,
347}; 348};
348 349
349int __init ipv6_addr_label_init(void) 350int __init ipv6_addr_label_init(void)
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 416917719a6f..dbbe04018813 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -470,7 +470,7 @@ EXPORT_SYMBOL_GPL(inet6_destroy_sock);
470 */ 470 */
471 471
472int inet6_getname(struct socket *sock, struct sockaddr *uaddr, 472int inet6_getname(struct socket *sock, struct sockaddr *uaddr,
473 int *uaddr_len, int peer) 473 int peer)
474{ 474{
475 struct sockaddr_in6 *sin = (struct sockaddr_in6 *)uaddr; 475 struct sockaddr_in6 *sin = (struct sockaddr_in6 *)uaddr;
476 struct sock *sk = sock->sk; 476 struct sock *sk = sock->sk;
@@ -500,8 +500,7 @@ int inet6_getname(struct socket *sock, struct sockaddr *uaddr,
500 } 500 }
501 sin->sin6_scope_id = ipv6_iface_scope_id(&sin->sin6_addr, 501 sin->sin6_scope_id = ipv6_iface_scope_id(&sin->sin6_addr,
502 sk->sk_bound_dev_if); 502 sk->sk_bound_dev_if);
503 *uaddr_len = sizeof(*sin); 503 return sizeof(*sin);
504 return 0;
505} 504}
506EXPORT_SYMBOL(inet6_getname); 505EXPORT_SYMBOL(inet6_getname);
507 506
@@ -858,6 +857,7 @@ static void __net_exit inet6_net_exit(struct net *net)
858static struct pernet_operations inet6_net_ops = { 857static struct pernet_operations inet6_net_ops = {
859 .init = inet6_net_init, 858 .init = inet6_net_init,
860 .exit = inet6_net_exit, 859 .exit = inet6_net_exit,
860 .async = true,
861}; 861};
862 862
863static const struct ipv6_stub ipv6_stub_impl = { 863static const struct ipv6_stub ipv6_stub_impl = {
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c
index 8e085cc05aeb..d580d4d456a5 100644
--- a/net/ipv6/anycast.c
+++ b/net/ipv6/anycast.c
@@ -66,7 +66,11 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
66 return -EPERM; 66 return -EPERM;
67 if (ipv6_addr_is_multicast(addr)) 67 if (ipv6_addr_is_multicast(addr))
68 return -EINVAL; 68 return -EINVAL;
69 if (ipv6_chk_addr(net, addr, NULL, 0)) 69
70 if (ifindex)
71 dev = __dev_get_by_index(net, ifindex);
72
73 if (ipv6_chk_addr_and_flags(net, addr, dev, true, 0, IFA_F_TENTATIVE))
70 return -EINVAL; 74 return -EINVAL;
71 75
72 pac = sock_kmalloc(sk, sizeof(struct ipv6_ac_socklist), GFP_KERNEL); 76 pac = sock_kmalloc(sk, sizeof(struct ipv6_ac_socklist), GFP_KERNEL);
@@ -78,7 +82,7 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
78 if (ifindex == 0) { 82 if (ifindex == 0) {
79 struct rt6_info *rt; 83 struct rt6_info *rt;
80 84
81 rt = rt6_lookup(net, addr, NULL, 0, 0); 85 rt = rt6_lookup(net, addr, NULL, 0, NULL, 0);
82 if (rt) { 86 if (rt) {
83 dev = rt->dst.dev; 87 dev = rt->dst.dev;
84 ip6_rt_put(rt); 88 ip6_rt_put(rt);
@@ -90,8 +94,7 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
90 dev = __dev_get_by_flags(net, IFF_UP, 94 dev = __dev_get_by_flags(net, IFF_UP,
91 IFF_UP | IFF_LOOPBACK); 95 IFF_UP | IFF_LOOPBACK);
92 } 96 }
93 } else 97 }
94 dev = __dev_get_by_index(net, ifindex);
95 98
96 if (!dev) { 99 if (!dev) {
97 err = -ENODEV; 100 err = -ENODEV;
@@ -552,4 +555,3 @@ void ac6_proc_exit(struct net *net)
552 remove_proc_entry("anycast6", net->proc_net); 555 remove_proc_entry("anycast6", net->proc_net);
553} 556}
554#endif 557#endif
555
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index a9f7eca0b6a3..88bc2ef7c7a8 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -808,8 +808,9 @@ int ip6_datagram_send_ctl(struct net *net, struct sock *sk,
808 if (addr_type != IPV6_ADDR_ANY) { 808 if (addr_type != IPV6_ADDR_ANY) {
809 int strict = __ipv6_addr_src_scope(addr_type) <= IPV6_ADDR_SCOPE_LINKLOCAL; 809 int strict = __ipv6_addr_src_scope(addr_type) <= IPV6_ADDR_SCOPE_LINKLOCAL;
810 if (!(inet_sk(sk)->freebind || inet_sk(sk)->transparent) && 810 if (!(inet_sk(sk)->freebind || inet_sk(sk)->transparent) &&
811 !ipv6_chk_addr(net, &src_info->ipi6_addr, 811 !ipv6_chk_addr_and_flags(net, &src_info->ipi6_addr,
812 strict ? dev : NULL, 0) && 812 dev, !strict, 0,
813 IFA_F_TENTATIVE) &&
813 !ipv6_chk_acast_addr_src(net, dev, 814 !ipv6_chk_acast_addr_src(net, dev,
814 &src_info->ipi6_addr)) 815 &src_info->ipi6_addr))
815 err = -EINVAL; 816 err = -EINVAL;
diff --git a/net/ipv6/exthdrs_core.c b/net/ipv6/exthdrs_core.c
index 11025f8d124b..b643f5ce6c80 100644
--- a/net/ipv6/exthdrs_core.c
+++ b/net/ipv6/exthdrs_core.c
@@ -279,4 +279,3 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
279 return nexthdr; 279 return nexthdr;
280} 280}
281EXPORT_SYMBOL(ipv6_find_hdr); 281EXPORT_SYMBOL(ipv6_find_hdr);
282
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
index b240f24a6e52..00ef9467f3c0 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -61,11 +61,13 @@ unsigned int fib6_rules_seq_read(struct net *net)
61} 61}
62 62
63struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6, 63struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
64 const struct sk_buff *skb,
64 int flags, pol_lookup_t lookup) 65 int flags, pol_lookup_t lookup)
65{ 66{
66 if (net->ipv6.fib6_has_custom_rules) { 67 if (net->ipv6.fib6_has_custom_rules) {
67 struct fib_lookup_arg arg = { 68 struct fib_lookup_arg arg = {
68 .lookup_ptr = lookup, 69 .lookup_ptr = lookup,
70 .lookup_data = skb,
69 .flags = FIB_LOOKUP_NOREF, 71 .flags = FIB_LOOKUP_NOREF,
70 }; 72 };
71 73
@@ -80,11 +82,11 @@ struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
80 } else { 82 } else {
81 struct rt6_info *rt; 83 struct rt6_info *rt;
82 84
83 rt = lookup(net, net->ipv6.fib6_local_tbl, fl6, flags); 85 rt = lookup(net, net->ipv6.fib6_local_tbl, fl6, skb, flags);
84 if (rt != net->ipv6.ip6_null_entry && rt->dst.error != -EAGAIN) 86 if (rt != net->ipv6.ip6_null_entry && rt->dst.error != -EAGAIN)
85 return &rt->dst; 87 return &rt->dst;
86 ip6_rt_put(rt); 88 ip6_rt_put(rt);
87 rt = lookup(net, net->ipv6.fib6_main_tbl, fl6, flags); 89 rt = lookup(net, net->ipv6.fib6_main_tbl, fl6, skb, flags);
88 if (rt->dst.error != -EAGAIN) 90 if (rt->dst.error != -EAGAIN)
89 return &rt->dst; 91 return &rt->dst;
90 ip6_rt_put(rt); 92 ip6_rt_put(rt);
@@ -130,7 +132,7 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
130 goto out; 132 goto out;
131 } 133 }
132 134
133 rt = lookup(net, table, flp6, flags); 135 rt = lookup(net, table, flp6, arg->lookup_data, flags);
134 if (rt != net->ipv6.ip6_null_entry) { 136 if (rt != net->ipv6.ip6_null_entry) {
135 struct fib6_rule *r = (struct fib6_rule *)rule; 137 struct fib6_rule *r = (struct fib6_rule *)rule;
136 138
@@ -223,6 +225,17 @@ static int fib6_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
223 if (r->tclass && r->tclass != ip6_tclass(fl6->flowlabel)) 225 if (r->tclass && r->tclass != ip6_tclass(fl6->flowlabel))
224 return 0; 226 return 0;
225 227
228 if (rule->ip_proto && (rule->ip_proto != fl6->flowi6_proto))
229 return 0;
230
231 if (fib_rule_port_range_set(&rule->sport_range) &&
232 !fib_rule_port_inrange(&rule->sport_range, fl6->fl6_sport))
233 return 0;
234
235 if (fib_rule_port_range_set(&rule->dport_range) &&
236 !fib_rule_port_inrange(&rule->dport_range, fl6->fl6_dport))
237 return 0;
238
226 return 1; 239 return 1;
227} 240}
228 241
@@ -258,12 +271,26 @@ static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
258 rule6->dst.plen = frh->dst_len; 271 rule6->dst.plen = frh->dst_len;
259 rule6->tclass = frh->tos; 272 rule6->tclass = frh->tos;
260 273
274 if (fib_rule_requires_fldissect(rule))
275 net->ipv6.fib6_rules_require_fldissect++;
276
261 net->ipv6.fib6_has_custom_rules = true; 277 net->ipv6.fib6_has_custom_rules = true;
262 err = 0; 278 err = 0;
263errout: 279errout:
264 return err; 280 return err;
265} 281}
266 282
283static int fib6_rule_delete(struct fib_rule *rule)
284{
285 struct net *net = rule->fr_net;
286
287 if (net->ipv6.fib6_rules_require_fldissect &&
288 fib_rule_requires_fldissect(rule))
289 net->ipv6.fib6_rules_require_fldissect--;
290
291 return 0;
292}
293
267static int fib6_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh, 294static int fib6_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh,
268 struct nlattr **tb) 295 struct nlattr **tb)
269{ 296{
@@ -323,6 +350,7 @@ static const struct fib_rules_ops __net_initconst fib6_rules_ops_template = {
323 .match = fib6_rule_match, 350 .match = fib6_rule_match,
324 .suppress = fib6_rule_suppress, 351 .suppress = fib6_rule_suppress,
325 .configure = fib6_rule_configure, 352 .configure = fib6_rule_configure,
353 .delete = fib6_rule_delete,
326 .compare = fib6_rule_compare, 354 .compare = fib6_rule_compare,
327 .fill = fib6_rule_fill, 355 .fill = fib6_rule_fill,
328 .nlmsg_payload = fib6_rule_nlmsg_payload, 356 .nlmsg_payload = fib6_rule_nlmsg_payload,
@@ -350,6 +378,7 @@ static int __net_init fib6_rules_net_init(struct net *net)
350 goto out_fib6_rules_ops; 378 goto out_fib6_rules_ops;
351 379
352 net->ipv6.fib6_rules_ops = ops; 380 net->ipv6.fib6_rules_ops = ops;
381 net->ipv6.fib6_rules_require_fldissect = 0;
353out: 382out:
354 return err; 383 return err;
355 384
@@ -368,6 +397,7 @@ static void __net_exit fib6_rules_net_exit(struct net *net)
368static struct pernet_operations fib6_rules_net_ops = { 397static struct pernet_operations fib6_rules_net_ops = {
369 .init = fib6_rules_net_init, 398 .init = fib6_rules_net_init,
370 .exit = fib6_rules_net_exit, 399 .exit = fib6_rules_net_exit,
400 .async = true,
371}; 401};
372 402
373int __init fib6_rules_init(void) 403int __init fib6_rules_init(void)
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 6ae5dd3f4d0d..6f84668be6ea 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -522,7 +522,7 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
522 fl6.fl6_icmp_type = type; 522 fl6.fl6_icmp_type = type;
523 fl6.fl6_icmp_code = code; 523 fl6.fl6_icmp_code = code;
524 fl6.flowi6_uid = sock_net_uid(net, NULL); 524 fl6.flowi6_uid = sock_net_uid(net, NULL);
525 fl6.mp_hash = rt6_multipath_hash(&fl6, skb); 525 fl6.mp_hash = rt6_multipath_hash(net, &fl6, skb, NULL);
526 security_skb_classify_flow(skb, flowi6_to_flowi(&fl6)); 526 security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
527 527
528 sk = icmpv6_xmit_lock(net); 528 sk = icmpv6_xmit_lock(net);
@@ -629,7 +629,8 @@ int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type,
629 skb_pull(skb2, nhs); 629 skb_pull(skb2, nhs);
630 skb_reset_network_header(skb2); 630 skb_reset_network_header(skb2);
631 631
632 rt = rt6_lookup(dev_net(skb->dev), &ipv6_hdr(skb2)->saddr, NULL, 0, 0); 632 rt = rt6_lookup(dev_net(skb->dev), &ipv6_hdr(skb2)->saddr, NULL, 0,
633 skb, 0);
633 634
634 if (rt && rt->dst.dev) 635 if (rt && rt->dst.dev)
635 skb2->dev = rt->dst.dev; 636 skb2->dev = rt->dst.dev;
@@ -997,6 +998,7 @@ static void __net_exit icmpv6_sk_exit(struct net *net)
997static struct pernet_operations icmpv6_sk_ops = { 998static struct pernet_operations icmpv6_sk_ops = {
998 .init = icmpv6_sk_init, 999 .init = icmpv6_sk_init,
999 .exit = icmpv6_sk_exit, 1000 .exit = icmpv6_sk_exit,
1001 .async = true,
1000}; 1002};
1001 1003
1002int __init icmpv6_init(void) 1004int __init icmpv6_init(void)
diff --git a/net/ipv6/ila/ila_xlat.c b/net/ipv6/ila/ila_xlat.c
index 44c39c5f0638..e438699f000f 100644
--- a/net/ipv6/ila/ila_xlat.c
+++ b/net/ipv6/ila/ila_xlat.c
@@ -613,6 +613,7 @@ static struct pernet_operations ila_net_ops = {
613 .exit = ila_exit_net, 613 .exit = ila_exit_net,
614 .id = &ila_net_id, 614 .id = &ila_net_id,
615 .size = sizeof(struct ila_net), 615 .size = sizeof(struct ila_net),
616 .async = true,
616}; 617};
617 618
618static int ila_xlat_addr(struct sk_buff *skb, bool sir2ila) 619static int ila_xlat_addr(struct sk_buff *skb, bool sir2ila)
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 92b8d8c75eed..2f995e9e3050 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -299,11 +299,12 @@ struct fib6_table *fib6_get_table(struct net *net, u32 id)
299} 299}
300 300
301struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6, 301struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
302 const struct sk_buff *skb,
302 int flags, pol_lookup_t lookup) 303 int flags, pol_lookup_t lookup)
303{ 304{
304 struct rt6_info *rt; 305 struct rt6_info *rt;
305 306
306 rt = lookup(net, net->ipv6.fib6_main_tbl, fl6, flags); 307 rt = lookup(net, net->ipv6.fib6_main_tbl, fl6, skb, flags);
307 if (rt->dst.error == -EAGAIN) { 308 if (rt->dst.error == -EAGAIN) {
308 ip6_rt_put(rt); 309 ip6_rt_put(rt);
309 rt = net->ipv6.ip6_null_entry; 310 rt = net->ipv6.ip6_null_entry;
@@ -2160,6 +2161,7 @@ static void fib6_net_exit(struct net *net)
2160static struct pernet_operations fib6_net_ops = { 2161static struct pernet_operations fib6_net_ops = {
2161 .init = fib6_net_init, 2162 .init = fib6_net_init,
2162 .exit = fib6_net_exit, 2163 .exit = fib6_net_exit,
2164 .async = true,
2163}; 2165};
2164 2166
2165int __init fib6_init(void) 2167int __init fib6_init(void)
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index 3dab664ff503..6ddf52282894 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -873,6 +873,7 @@ static void __net_exit ip6_flowlabel_net_exit(struct net *net)
873static struct pernet_operations ip6_flowlabel_net_ops = { 873static struct pernet_operations ip6_flowlabel_net_ops = {
874 .init = ip6_flowlabel_proc_init, 874 .init = ip6_flowlabel_proc_init,
875 .exit = ip6_flowlabel_net_exit, 875 .exit = ip6_flowlabel_net_exit,
876 .async = true,
876}; 877};
877 878
878int ip6_flowlabel_init(void) 879int ip6_flowlabel_init(void)
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 1bbd0930063e..3a98c694da5f 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -237,7 +237,7 @@ static struct ip6_tnl *ip6gre_tunnel_lookup(struct net_device *dev,
237 return t; 237 return t;
238 238
239 dev = ign->fb_tunnel_dev; 239 dev = ign->fb_tunnel_dev;
240 if (dev->flags & IFF_UP) 240 if (dev && dev->flags & IFF_UP)
241 return netdev_priv(dev); 241 return netdev_priv(dev);
242 242
243 return NULL; 243 return NULL;
@@ -696,9 +696,6 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb,
696 else 696 else
697 fl6->daddr = tunnel->parms.raddr; 697 fl6->daddr = tunnel->parms.raddr;
698 698
699 if (tunnel->parms.o_flags & TUNNEL_SEQ)
700 tunnel->o_seqno++;
701
702 /* Push GRE header. */ 699 /* Push GRE header. */
703 protocol = (dev->type == ARPHRD_ETHER) ? htons(ETH_P_TEB) : proto; 700 protocol = (dev->type == ARPHRD_ETHER) ? htons(ETH_P_TEB) : proto;
704 701
@@ -721,14 +718,20 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb,
721 fl6->flowi6_uid = sock_net_uid(dev_net(dev), NULL); 718 fl6->flowi6_uid = sock_net_uid(dev_net(dev), NULL);
722 719
723 dsfield = key->tos; 720 dsfield = key->tos;
724 flags = key->tun_flags & (TUNNEL_CSUM | TUNNEL_KEY); 721 flags = key->tun_flags &
722 (TUNNEL_CSUM | TUNNEL_KEY | TUNNEL_SEQ);
725 tunnel->tun_hlen = gre_calc_hlen(flags); 723 tunnel->tun_hlen = gre_calc_hlen(flags);
726 724
727 gre_build_header(skb, tunnel->tun_hlen, 725 gre_build_header(skb, tunnel->tun_hlen,
728 flags, protocol, 726 flags, protocol,
729 tunnel_id_to_key32(tun_info->key.tun_id), 0); 727 tunnel_id_to_key32(tun_info->key.tun_id),
728 (flags & TUNNEL_SEQ) ? htonl(tunnel->o_seqno++)
729 : 0);
730 730
731 } else { 731 } else {
732 if (tunnel->parms.o_flags & TUNNEL_SEQ)
733 tunnel->o_seqno++;
734
732 gre_build_header(skb, tunnel->tun_hlen, tunnel->parms.o_flags, 735 gre_build_header(skb, tunnel->tun_hlen, tunnel->parms.o_flags,
733 protocol, tunnel->parms.o_key, 736 protocol, tunnel->parms.o_key,
734 htonl(tunnel->o_seqno)); 737 htonl(tunnel->o_seqno));
@@ -1059,7 +1062,7 @@ static void ip6gre_tnl_link_config(struct ip6_tnl *t, int set_mtu)
1059 1062
1060 struct rt6_info *rt = rt6_lookup(t->net, 1063 struct rt6_info *rt = rt6_lookup(t->net,
1061 &p->raddr, &p->laddr, 1064 &p->raddr, &p->laddr,
1062 p->link, strict); 1065 p->link, NULL, strict);
1063 1066
1064 if (!rt) 1067 if (!rt)
1065 return; 1068 return;
@@ -1475,6 +1478,8 @@ static int __net_init ip6gre_init_net(struct net *net)
1475 struct ip6gre_net *ign = net_generic(net, ip6gre_net_id); 1478 struct ip6gre_net *ign = net_generic(net, ip6gre_net_id);
1476 int err; 1479 int err;
1477 1480
1481 if (!net_has_fallback_tunnels(net))
1482 return 0;
1478 ign->fb_tunnel_dev = alloc_netdev(sizeof(struct ip6_tnl), "ip6gre0", 1483 ign->fb_tunnel_dev = alloc_netdev(sizeof(struct ip6_tnl), "ip6gre0",
1479 NET_NAME_UNKNOWN, 1484 NET_NAME_UNKNOWN,
1480 ip6gre_tunnel_setup); 1485 ip6gre_tunnel_setup);
@@ -1523,6 +1528,7 @@ static struct pernet_operations ip6gre_net_ops = {
1523 .exit_batch = ip6gre_exit_batch_net, 1528 .exit_batch = ip6gre_exit_batch_net,
1524 .id = &ip6gre_net_id, 1529 .id = &ip6gre_net_id,
1525 .size = sizeof(struct ip6gre_net), 1530 .size = sizeof(struct ip6gre_net),
1531 .async = true,
1526}; 1532};
1527 1533
1528static int ip6gre_tunnel_validate(struct nlattr *tb[], struct nlattr *data[], 1534static int ip6gre_tunnel_validate(struct nlattr *tb[], struct nlattr *data[],
@@ -1790,6 +1796,12 @@ static void ip6gre_tap_setup(struct net_device *dev)
1790 netif_keep_dst(dev); 1796 netif_keep_dst(dev);
1791} 1797}
1792 1798
1799bool is_ip6gretap_dev(const struct net_device *dev)
1800{
1801 return dev->netdev_ops == &ip6gre_tap_netdev_ops;
1802}
1803EXPORT_SYMBOL_GPL(is_ip6gretap_dev);
1804
1793static bool ip6gre_netlink_encap_parms(struct nlattr *data[], 1805static bool ip6gre_netlink_encap_parms(struct nlattr *data[],
1794 struct ip_tunnel_encap *ipencap) 1806 struct ip_tunnel_encap *ipencap)
1795{ 1807{
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index a8a919520090..2c7f09c3c39e 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -71,7 +71,7 @@ static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff *
71 struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb)); 71 struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
72 72
73 if (!(dev->flags & IFF_LOOPBACK) && sk_mc_loop(sk) && 73 if (!(dev->flags & IFF_LOOPBACK) && sk_mc_loop(sk) &&
74 ((mroute6_socket(net, skb) && 74 ((mroute6_is_socket(net, skb) &&
75 !(IP6CB(skb)->flags & IP6SKB_FORWARDED)) || 75 !(IP6CB(skb)->flags & IP6SKB_FORWARDED)) ||
76 ipv6_chk_mcast_addr(dev, &ipv6_hdr(skb)->daddr, 76 ipv6_chk_mcast_addr(dev, &ipv6_hdr(skb)->daddr,
77 &ipv6_hdr(skb)->saddr))) { 77 &ipv6_hdr(skb)->saddr))) {
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 6e0f21eed88a..456fcf942f95 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -679,7 +679,7 @@ ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
679 679
680 /* Try to guess incoming interface */ 680 /* Try to guess incoming interface */
681 rt = rt6_lookup(dev_net(skb->dev), &ipv6_hdr(skb2)->saddr, 681 rt = rt6_lookup(dev_net(skb->dev), &ipv6_hdr(skb2)->saddr,
682 NULL, 0, 0); 682 NULL, 0, skb2, 0);
683 683
684 if (rt && rt->dst.dev) 684 if (rt && rt->dst.dev)
685 skb2->dev = rt->dst.dev; 685 skb2->dev = rt->dst.dev;
@@ -758,9 +758,11 @@ int ip6_tnl_rcv_ctl(struct ip6_tnl *t,
758 ldev = dev_get_by_index_rcu(net, p->link); 758 ldev = dev_get_by_index_rcu(net, p->link);
759 759
760 if ((ipv6_addr_is_multicast(laddr) || 760 if ((ipv6_addr_is_multicast(laddr) ||
761 likely(ipv6_chk_addr(net, laddr, ldev, 0))) && 761 likely(ipv6_chk_addr_and_flags(net, laddr, ldev, false,
762 0, IFA_F_TENTATIVE))) &&
762 ((p->flags & IP6_TNL_F_ALLOW_LOCAL_REMOTE) || 763 ((p->flags & IP6_TNL_F_ALLOW_LOCAL_REMOTE) ||
763 likely(!ipv6_chk_addr(net, raddr, NULL, 0)))) 764 likely(!ipv6_chk_addr_and_flags(net, raddr, ldev, true,
765 0, IFA_F_TENTATIVE))))
764 ret = 1; 766 ret = 1;
765 } 767 }
766 return ret; 768 return ret;
@@ -990,12 +992,14 @@ int ip6_tnl_xmit_ctl(struct ip6_tnl *t,
990 if (p->link) 992 if (p->link)
991 ldev = dev_get_by_index_rcu(net, p->link); 993 ldev = dev_get_by_index_rcu(net, p->link);
992 994
993 if (unlikely(!ipv6_chk_addr(net, laddr, ldev, 0))) 995 if (unlikely(!ipv6_chk_addr_and_flags(net, laddr, ldev, false,
996 0, IFA_F_TENTATIVE)))
994 pr_warn("%s xmit: Local address not yet configured!\n", 997 pr_warn("%s xmit: Local address not yet configured!\n",
995 p->name); 998 p->name);
996 else if (!(p->flags & IP6_TNL_F_ALLOW_LOCAL_REMOTE) && 999 else if (!(p->flags & IP6_TNL_F_ALLOW_LOCAL_REMOTE) &&
997 !ipv6_addr_is_multicast(raddr) && 1000 !ipv6_addr_is_multicast(raddr) &&
998 unlikely(ipv6_chk_addr(net, raddr, NULL, 0))) 1001 unlikely(ipv6_chk_addr_and_flags(net, raddr, ldev,
1002 true, 0, IFA_F_TENTATIVE)))
999 pr_warn("%s xmit: Routing loop! Remote address found on this node!\n", 1003 pr_warn("%s xmit: Routing loop! Remote address found on this node!\n",
1000 p->name); 1004 p->name);
1001 else 1005 else
@@ -1444,7 +1448,7 @@ static void ip6_tnl_link_config(struct ip6_tnl *t)
1444 1448
1445 struct rt6_info *rt = rt6_lookup(t->net, 1449 struct rt6_info *rt = rt6_lookup(t->net,
1446 &p->raddr, &p->laddr, 1450 &p->raddr, &p->laddr,
1447 p->link, strict); 1451 p->link, NULL, strict);
1448 1452
1449 if (!rt) 1453 if (!rt)
1450 return; 1454 return;
@@ -2205,6 +2209,8 @@ static int __net_init ip6_tnl_init_net(struct net *net)
2205 ip6n->tnls[0] = ip6n->tnls_wc; 2209 ip6n->tnls[0] = ip6n->tnls_wc;
2206 ip6n->tnls[1] = ip6n->tnls_r_l; 2210 ip6n->tnls[1] = ip6n->tnls_r_l;
2207 2211
2212 if (!net_has_fallback_tunnels(net))
2213 return 0;
2208 err = -ENOMEM; 2214 err = -ENOMEM;
2209 ip6n->fb_tnl_dev = alloc_netdev(sizeof(struct ip6_tnl), "ip6tnl0", 2215 ip6n->fb_tnl_dev = alloc_netdev(sizeof(struct ip6_tnl), "ip6tnl0",
2210 NET_NAME_UNKNOWN, ip6_tnl_dev_setup); 2216 NET_NAME_UNKNOWN, ip6_tnl_dev_setup);
@@ -2254,6 +2260,7 @@ static struct pernet_operations ip6_tnl_net_ops = {
2254 .exit_batch = ip6_tnl_exit_batch_net, 2260 .exit_batch = ip6_tnl_exit_batch_net,
2255 .id = &ip6_tnl_net_id, 2261 .id = &ip6_tnl_net_id,
2256 .size = sizeof(struct ip6_tnl_net), 2262 .size = sizeof(struct ip6_tnl_net),
2263 .async = true,
2257}; 2264};
2258 2265
2259/** 2266/**
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
index fa3ae1cb50d3..a482b854eeea 100644
--- a/net/ipv6/ip6_vti.c
+++ b/net/ipv6/ip6_vti.c
@@ -645,7 +645,7 @@ static void vti6_link_config(struct ip6_tnl *t)
645 (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL)); 645 (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL));
646 struct rt6_info *rt = rt6_lookup(t->net, 646 struct rt6_info *rt = rt6_lookup(t->net,
647 &p->raddr, &p->laddr, 647 &p->raddr, &p->laddr,
648 p->link, strict); 648 p->link, NULL, strict);
649 649
650 if (rt) 650 if (rt)
651 tdev = rt->dst.dev; 651 tdev = rt->dst.dev;
@@ -1148,6 +1148,7 @@ static struct pernet_operations vti6_net_ops = {
1148 .exit_batch = vti6_exit_batch_net, 1148 .exit_batch = vti6_exit_batch_net,
1149 .id = &vti6_net_id, 1149 .id = &vti6_net_id,
1150 .size = sizeof(struct vti6_net), 1150 .size = sizeof(struct vti6_net),
1151 .async = true,
1151}; 1152};
1152 1153
1153static struct xfrm6_protocol vti_esp6_protocol __read_mostly = { 1154static struct xfrm6_protocol vti_esp6_protocol __read_mostly = {
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 9f6cace9c817..7345bd6c4b7d 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -20,7 +20,6 @@
20#include <linux/types.h> 20#include <linux/types.h>
21#include <linux/sched.h> 21#include <linux/sched.h>
22#include <linux/errno.h> 22#include <linux/errno.h>
23#include <linux/timer.h>
24#include <linux/mm.h> 23#include <linux/mm.h>
25#include <linux/kernel.h> 24#include <linux/kernel.h>
26#include <linux/fcntl.h> 25#include <linux/fcntl.h>
@@ -32,11 +31,9 @@
32#include <linux/proc_fs.h> 31#include <linux/proc_fs.h>
33#include <linux/seq_file.h> 32#include <linux/seq_file.h>
34#include <linux/init.h> 33#include <linux/init.h>
35#include <linux/slab.h>
36#include <linux/compat.h> 34#include <linux/compat.h>
37#include <net/protocol.h> 35#include <net/protocol.h>
38#include <linux/skbuff.h> 36#include <linux/skbuff.h>
39#include <net/sock.h>
40#include <net/raw.h> 37#include <net/raw.h>
41#include <linux/notifier.h> 38#include <linux/notifier.h>
42#include <linux/if_arp.h> 39#include <linux/if_arp.h>
@@ -54,30 +51,12 @@
54#include <net/ip6_checksum.h> 51#include <net/ip6_checksum.h>
55#include <linux/netconf.h> 52#include <linux/netconf.h>
56 53
57struct mr6_table {
58 struct list_head list;
59 possible_net_t net;
60 u32 id;
61 struct sock *mroute6_sk;
62 struct timer_list ipmr_expire_timer;
63 struct list_head mfc6_unres_queue;
64 struct list_head mfc6_cache_array[MFC6_LINES];
65 struct mif_device vif6_table[MAXMIFS];
66 int maxvif;
67 atomic_t cache_resolve_queue_len;
68 bool mroute_do_assert;
69 bool mroute_do_pim;
70#ifdef CONFIG_IPV6_PIMSM_V2
71 int mroute_reg_vif_num;
72#endif
73};
74
75struct ip6mr_rule { 54struct ip6mr_rule {
76 struct fib_rule common; 55 struct fib_rule common;
77}; 56};
78 57
79struct ip6mr_result { 58struct ip6mr_result {
80 struct mr6_table *mrt; 59 struct mr_table *mrt;
81}; 60};
82 61
83/* Big lock, protecting vif table, mrt cache and mroute socket state. 62/* Big lock, protecting vif table, mrt cache and mroute socket state.
@@ -86,11 +65,7 @@ struct ip6mr_result {
86 65
87static DEFINE_RWLOCK(mrt_lock); 66static DEFINE_RWLOCK(mrt_lock);
88 67
89/* 68/* Multicast router control variables */
90 * Multicast router control variables
91 */
92
93#define MIF_EXISTS(_mrt, _idx) ((_mrt)->vif6_table[_idx].dev != NULL)
94 69
95/* Special spinlock for queue of unresolved entries */ 70/* Special spinlock for queue of unresolved entries */
96static DEFINE_SPINLOCK(mfc_unres_lock); 71static DEFINE_SPINLOCK(mfc_unres_lock);
@@ -105,30 +80,45 @@ static DEFINE_SPINLOCK(mfc_unres_lock);
105 80
106static struct kmem_cache *mrt_cachep __read_mostly; 81static struct kmem_cache *mrt_cachep __read_mostly;
107 82
108static struct mr6_table *ip6mr_new_table(struct net *net, u32 id); 83static struct mr_table *ip6mr_new_table(struct net *net, u32 id);
109static void ip6mr_free_table(struct mr6_table *mrt); 84static void ip6mr_free_table(struct mr_table *mrt);
110 85
111static void ip6_mr_forward(struct net *net, struct mr6_table *mrt, 86static void ip6_mr_forward(struct net *net, struct mr_table *mrt,
112 struct sk_buff *skb, struct mfc6_cache *cache); 87 struct sk_buff *skb, struct mfc6_cache *cache);
113static int ip6mr_cache_report(struct mr6_table *mrt, struct sk_buff *pkt, 88static int ip6mr_cache_report(struct mr_table *mrt, struct sk_buff *pkt,
114 mifi_t mifi, int assert); 89 mifi_t mifi, int assert);
115static int __ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb, 90static void mr6_netlink_event(struct mr_table *mrt, struct mfc6_cache *mfc,
116 struct mfc6_cache *c, struct rtmsg *rtm);
117static void mr6_netlink_event(struct mr6_table *mrt, struct mfc6_cache *mfc,
118 int cmd); 91 int cmd);
119static void mrt6msg_netlink_event(struct mr6_table *mrt, struct sk_buff *pkt); 92static void mrt6msg_netlink_event(struct mr_table *mrt, struct sk_buff *pkt);
120static int ip6mr_rtm_dumproute(struct sk_buff *skb, 93static int ip6mr_rtm_dumproute(struct sk_buff *skb,
121 struct netlink_callback *cb); 94 struct netlink_callback *cb);
122static void mroute_clean_tables(struct mr6_table *mrt, bool all); 95static void mroute_clean_tables(struct mr_table *mrt, bool all);
123static void ipmr_expire_process(struct timer_list *t); 96static void ipmr_expire_process(struct timer_list *t);
124 97
125#ifdef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES 98#ifdef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES
126#define ip6mr_for_each_table(mrt, net) \ 99#define ip6mr_for_each_table(mrt, net) \
127 list_for_each_entry_rcu(mrt, &net->ipv6.mr6_tables, list) 100 list_for_each_entry_rcu(mrt, &net->ipv6.mr6_tables, list)
128 101
129static struct mr6_table *ip6mr_get_table(struct net *net, u32 id) 102static struct mr_table *ip6mr_mr_table_iter(struct net *net,
103 struct mr_table *mrt)
104{
105 struct mr_table *ret;
106
107 if (!mrt)
108 ret = list_entry_rcu(net->ipv6.mr6_tables.next,
109 struct mr_table, list);
110 else
111 ret = list_entry_rcu(mrt->list.next,
112 struct mr_table, list);
113
114 if (&ret->list == &net->ipv6.mr6_tables)
115 return NULL;
116 return ret;
117}
118
119static struct mr_table *ip6mr_get_table(struct net *net, u32 id)
130{ 120{
131 struct mr6_table *mrt; 121 struct mr_table *mrt;
132 122
133 ip6mr_for_each_table(mrt, net) { 123 ip6mr_for_each_table(mrt, net) {
134 if (mrt->id == id) 124 if (mrt->id == id)
@@ -138,7 +128,7 @@ static struct mr6_table *ip6mr_get_table(struct net *net, u32 id)
138} 128}
139 129
140static int ip6mr_fib_lookup(struct net *net, struct flowi6 *flp6, 130static int ip6mr_fib_lookup(struct net *net, struct flowi6 *flp6,
141 struct mr6_table **mrt) 131 struct mr_table **mrt)
142{ 132{
143 int err; 133 int err;
144 struct ip6mr_result res; 134 struct ip6mr_result res;
@@ -159,7 +149,7 @@ static int ip6mr_rule_action(struct fib_rule *rule, struct flowi *flp,
159 int flags, struct fib_lookup_arg *arg) 149 int flags, struct fib_lookup_arg *arg)
160{ 150{
161 struct ip6mr_result *res = arg->result; 151 struct ip6mr_result *res = arg->result;
162 struct mr6_table *mrt; 152 struct mr_table *mrt;
163 153
164 switch (rule->action) { 154 switch (rule->action) {
165 case FR_ACT_TO_TBL: 155 case FR_ACT_TO_TBL:
@@ -227,7 +217,7 @@ static const struct fib_rules_ops __net_initconst ip6mr_rules_ops_template = {
227static int __net_init ip6mr_rules_init(struct net *net) 217static int __net_init ip6mr_rules_init(struct net *net)
228{ 218{
229 struct fib_rules_ops *ops; 219 struct fib_rules_ops *ops;
230 struct mr6_table *mrt; 220 struct mr_table *mrt;
231 int err; 221 int err;
232 222
233 ops = fib_rules_register(&ip6mr_rules_ops_template, net); 223 ops = fib_rules_register(&ip6mr_rules_ops_template, net);
@@ -258,7 +248,7 @@ err1:
258 248
259static void __net_exit ip6mr_rules_exit(struct net *net) 249static void __net_exit ip6mr_rules_exit(struct net *net)
260{ 250{
261 struct mr6_table *mrt, *next; 251 struct mr_table *mrt, *next;
262 252
263 rtnl_lock(); 253 rtnl_lock();
264 list_for_each_entry_safe(mrt, next, &net->ipv6.mr6_tables, list) { 254 list_for_each_entry_safe(mrt, next, &net->ipv6.mr6_tables, list) {
@@ -272,13 +262,21 @@ static void __net_exit ip6mr_rules_exit(struct net *net)
272#define ip6mr_for_each_table(mrt, net) \ 262#define ip6mr_for_each_table(mrt, net) \
273 for (mrt = net->ipv6.mrt6; mrt; mrt = NULL) 263 for (mrt = net->ipv6.mrt6; mrt; mrt = NULL)
274 264
275static struct mr6_table *ip6mr_get_table(struct net *net, u32 id) 265static struct mr_table *ip6mr_mr_table_iter(struct net *net,
266 struct mr_table *mrt)
267{
268 if (!mrt)
269 return net->ipv6.mrt6;
270 return NULL;
271}
272
273static struct mr_table *ip6mr_get_table(struct net *net, u32 id)
276{ 274{
277 return net->ipv6.mrt6; 275 return net->ipv6.mrt6;
278} 276}
279 277
280static int ip6mr_fib_lookup(struct net *net, struct flowi6 *flp6, 278static int ip6mr_fib_lookup(struct net *net, struct flowi6 *flp6,
281 struct mr6_table **mrt) 279 struct mr_table **mrt)
282{ 280{
283 *mrt = net->ipv6.mrt6; 281 *mrt = net->ipv6.mrt6;
284 return 0; 282 return 0;
@@ -299,112 +297,75 @@ static void __net_exit ip6mr_rules_exit(struct net *net)
299} 297}
300#endif 298#endif
301 299
302static struct mr6_table *ip6mr_new_table(struct net *net, u32 id) 300static int ip6mr_hash_cmp(struct rhashtable_compare_arg *arg,
301 const void *ptr)
303{ 302{
304 struct mr6_table *mrt; 303 const struct mfc6_cache_cmp_arg *cmparg = arg->key;
305 unsigned int i; 304 struct mfc6_cache *c = (struct mfc6_cache *)ptr;
306 305
307 mrt = ip6mr_get_table(net, id); 306 return !ipv6_addr_equal(&c->mf6c_mcastgrp, &cmparg->mf6c_mcastgrp) ||
308 if (mrt) 307 !ipv6_addr_equal(&c->mf6c_origin, &cmparg->mf6c_origin);
309 return mrt; 308}
310
311 mrt = kzalloc(sizeof(*mrt), GFP_KERNEL);
312 if (!mrt)
313 return NULL;
314 mrt->id = id;
315 write_pnet(&mrt->net, net);
316
317 /* Forwarding cache */
318 for (i = 0; i < MFC6_LINES; i++)
319 INIT_LIST_HEAD(&mrt->mfc6_cache_array[i]);
320
321 INIT_LIST_HEAD(&mrt->mfc6_unres_queue);
322 309
323 timer_setup(&mrt->ipmr_expire_timer, ipmr_expire_process, 0); 310static const struct rhashtable_params ip6mr_rht_params = {
311 .head_offset = offsetof(struct mr_mfc, mnode),
312 .key_offset = offsetof(struct mfc6_cache, cmparg),
313 .key_len = sizeof(struct mfc6_cache_cmp_arg),
314 .nelem_hint = 3,
315 .locks_mul = 1,
316 .obj_cmpfn = ip6mr_hash_cmp,
317 .automatic_shrinking = true,
318};
324 319
325#ifdef CONFIG_IPV6_PIMSM_V2 320static void ip6mr_new_table_set(struct mr_table *mrt,
326 mrt->mroute_reg_vif_num = -1; 321 struct net *net)
327#endif 322{
328#ifdef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES 323#ifdef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES
329 list_add_tail_rcu(&mrt->list, &net->ipv6.mr6_tables); 324 list_add_tail_rcu(&mrt->list, &net->ipv6.mr6_tables);
330#endif 325#endif
331 return mrt;
332} 326}
333 327
334static void ip6mr_free_table(struct mr6_table *mrt) 328static struct mfc6_cache_cmp_arg ip6mr_mr_table_ops_cmparg_any = {
335{ 329 .mf6c_origin = IN6ADDR_ANY_INIT,
336 del_timer_sync(&mrt->ipmr_expire_timer); 330 .mf6c_mcastgrp = IN6ADDR_ANY_INIT,
337 mroute_clean_tables(mrt, true);
338 kfree(mrt);
339}
340
341#ifdef CONFIG_PROC_FS
342
343struct ipmr_mfc_iter {
344 struct seq_net_private p;
345 struct mr6_table *mrt;
346 struct list_head *cache;
347 int ct;
348}; 331};
349 332
333static struct mr_table_ops ip6mr_mr_table_ops = {
334 .rht_params = &ip6mr_rht_params,
335 .cmparg_any = &ip6mr_mr_table_ops_cmparg_any,
336};
350 337
351static struct mfc6_cache *ipmr_mfc_seq_idx(struct net *net, 338static struct mr_table *ip6mr_new_table(struct net *net, u32 id)
352 struct ipmr_mfc_iter *it, loff_t pos)
353{ 339{
354 struct mr6_table *mrt = it->mrt; 340 struct mr_table *mrt;
355 struct mfc6_cache *mfc;
356
357 read_lock(&mrt_lock);
358 for (it->ct = 0; it->ct < MFC6_LINES; it->ct++) {
359 it->cache = &mrt->mfc6_cache_array[it->ct];
360 list_for_each_entry(mfc, it->cache, list)
361 if (pos-- == 0)
362 return mfc;
363 }
364 read_unlock(&mrt_lock);
365 341
366 spin_lock_bh(&mfc_unres_lock); 342 mrt = ip6mr_get_table(net, id);
367 it->cache = &mrt->mfc6_unres_queue; 343 if (mrt)
368 list_for_each_entry(mfc, it->cache, list) 344 return mrt;
369 if (pos-- == 0)
370 return mfc;
371 spin_unlock_bh(&mfc_unres_lock);
372 345
373 it->cache = NULL; 346 return mr_table_alloc(net, id, &ip6mr_mr_table_ops,
374 return NULL; 347 ipmr_expire_process, ip6mr_new_table_set);
375} 348}
376 349
377/* 350static void ip6mr_free_table(struct mr_table *mrt)
378 * The /proc interfaces to multicast routing /proc/ip6_mr_cache /proc/ip6_mr_vif
379 */
380
381struct ipmr_vif_iter {
382 struct seq_net_private p;
383 struct mr6_table *mrt;
384 int ct;
385};
386
387static struct mif_device *ip6mr_vif_seq_idx(struct net *net,
388 struct ipmr_vif_iter *iter,
389 loff_t pos)
390{ 351{
391 struct mr6_table *mrt = iter->mrt; 352 del_timer_sync(&mrt->ipmr_expire_timer);
392 353 mroute_clean_tables(mrt, true);
393 for (iter->ct = 0; iter->ct < mrt->maxvif; ++iter->ct) { 354 rhltable_destroy(&mrt->mfc_hash);
394 if (!MIF_EXISTS(mrt, iter->ct)) 355 kfree(mrt);
395 continue;
396 if (pos-- == 0)
397 return &mrt->vif6_table[iter->ct];
398 }
399 return NULL;
400} 356}
401 357
358#ifdef CONFIG_PROC_FS
359/* The /proc interfaces to multicast routing
360 * /proc/ip6_mr_cache /proc/ip6_mr_vif
361 */
362
402static void *ip6mr_vif_seq_start(struct seq_file *seq, loff_t *pos) 363static void *ip6mr_vif_seq_start(struct seq_file *seq, loff_t *pos)
403 __acquires(mrt_lock) 364 __acquires(mrt_lock)
404{ 365{
405 struct ipmr_vif_iter *iter = seq->private; 366 struct mr_vif_iter *iter = seq->private;
406 struct net *net = seq_file_net(seq); 367 struct net *net = seq_file_net(seq);
407 struct mr6_table *mrt; 368 struct mr_table *mrt;
408 369
409 mrt = ip6mr_get_table(net, RT6_TABLE_DFLT); 370 mrt = ip6mr_get_table(net, RT6_TABLE_DFLT);
410 if (!mrt) 371 if (!mrt)
@@ -413,26 +374,7 @@ static void *ip6mr_vif_seq_start(struct seq_file *seq, loff_t *pos)
413 iter->mrt = mrt; 374 iter->mrt = mrt;
414 375
415 read_lock(&mrt_lock); 376 read_lock(&mrt_lock);
416 return *pos ? ip6mr_vif_seq_idx(net, seq->private, *pos - 1) 377 return mr_vif_seq_start(seq, pos);
417 : SEQ_START_TOKEN;
418}
419
420static void *ip6mr_vif_seq_next(struct seq_file *seq, void *v, loff_t *pos)
421{
422 struct ipmr_vif_iter *iter = seq->private;
423 struct net *net = seq_file_net(seq);
424 struct mr6_table *mrt = iter->mrt;
425
426 ++*pos;
427 if (v == SEQ_START_TOKEN)
428 return ip6mr_vif_seq_idx(net, iter, 0);
429
430 while (++iter->ct < mrt->maxvif) {
431 if (!MIF_EXISTS(mrt, iter->ct))
432 continue;
433 return &mrt->vif6_table[iter->ct];
434 }
435 return NULL;
436} 378}
437 379
438static void ip6mr_vif_seq_stop(struct seq_file *seq, void *v) 380static void ip6mr_vif_seq_stop(struct seq_file *seq, void *v)
@@ -443,19 +385,19 @@ static void ip6mr_vif_seq_stop(struct seq_file *seq, void *v)
443 385
444static int ip6mr_vif_seq_show(struct seq_file *seq, void *v) 386static int ip6mr_vif_seq_show(struct seq_file *seq, void *v)
445{ 387{
446 struct ipmr_vif_iter *iter = seq->private; 388 struct mr_vif_iter *iter = seq->private;
447 struct mr6_table *mrt = iter->mrt; 389 struct mr_table *mrt = iter->mrt;
448 390
449 if (v == SEQ_START_TOKEN) { 391 if (v == SEQ_START_TOKEN) {
450 seq_puts(seq, 392 seq_puts(seq,
451 "Interface BytesIn PktsIn BytesOut PktsOut Flags\n"); 393 "Interface BytesIn PktsIn BytesOut PktsOut Flags\n");
452 } else { 394 } else {
453 const struct mif_device *vif = v; 395 const struct vif_device *vif = v;
454 const char *name = vif->dev ? vif->dev->name : "none"; 396 const char *name = vif->dev ? vif->dev->name : "none";
455 397
456 seq_printf(seq, 398 seq_printf(seq,
457 "%2td %-10s %8ld %7ld %8ld %7ld %05X\n", 399 "%2td %-10s %8ld %7ld %8ld %7ld %05X\n",
458 vif - mrt->vif6_table, 400 vif - mrt->vif_table,
459 name, vif->bytes_in, vif->pkt_in, 401 name, vif->bytes_in, vif->pkt_in,
460 vif->bytes_out, vif->pkt_out, 402 vif->bytes_out, vif->pkt_out,
461 vif->flags); 403 vif->flags);
@@ -465,7 +407,7 @@ static int ip6mr_vif_seq_show(struct seq_file *seq, void *v)
465 407
466static const struct seq_operations ip6mr_vif_seq_ops = { 408static const struct seq_operations ip6mr_vif_seq_ops = {
467 .start = ip6mr_vif_seq_start, 409 .start = ip6mr_vif_seq_start,
468 .next = ip6mr_vif_seq_next, 410 .next = mr_vif_seq_next,
469 .stop = ip6mr_vif_seq_stop, 411 .stop = ip6mr_vif_seq_stop,
470 .show = ip6mr_vif_seq_show, 412 .show = ip6mr_vif_seq_show,
471}; 413};
@@ -473,7 +415,7 @@ static const struct seq_operations ip6mr_vif_seq_ops = {
473static int ip6mr_vif_open(struct inode *inode, struct file *file) 415static int ip6mr_vif_open(struct inode *inode, struct file *file)
474{ 416{
475 return seq_open_net(inode, file, &ip6mr_vif_seq_ops, 417 return seq_open_net(inode, file, &ip6mr_vif_seq_ops,
476 sizeof(struct ipmr_vif_iter)); 418 sizeof(struct mr_vif_iter));
477} 419}
478 420
479static const struct file_operations ip6mr_vif_fops = { 421static const struct file_operations ip6mr_vif_fops = {
@@ -485,72 +427,14 @@ static const struct file_operations ip6mr_vif_fops = {
485 427
486static void *ipmr_mfc_seq_start(struct seq_file *seq, loff_t *pos) 428static void *ipmr_mfc_seq_start(struct seq_file *seq, loff_t *pos)
487{ 429{
488 struct ipmr_mfc_iter *it = seq->private;
489 struct net *net = seq_file_net(seq); 430 struct net *net = seq_file_net(seq);
490 struct mr6_table *mrt; 431 struct mr_table *mrt;
491 432
492 mrt = ip6mr_get_table(net, RT6_TABLE_DFLT); 433 mrt = ip6mr_get_table(net, RT6_TABLE_DFLT);
493 if (!mrt) 434 if (!mrt)
494 return ERR_PTR(-ENOENT); 435 return ERR_PTR(-ENOENT);
495 436
496 it->mrt = mrt; 437 return mr_mfc_seq_start(seq, pos, mrt, &mfc_unres_lock);
497 it->cache = NULL;
498 return *pos ? ipmr_mfc_seq_idx(net, seq->private, *pos - 1)
499 : SEQ_START_TOKEN;
500}
501
502static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
503{
504 struct mfc6_cache *mfc = v;
505 struct ipmr_mfc_iter *it = seq->private;
506 struct net *net = seq_file_net(seq);
507 struct mr6_table *mrt = it->mrt;
508
509 ++*pos;
510
511 if (v == SEQ_START_TOKEN)
512 return ipmr_mfc_seq_idx(net, seq->private, 0);
513
514 if (mfc->list.next != it->cache)
515 return list_entry(mfc->list.next, struct mfc6_cache, list);
516
517 if (it->cache == &mrt->mfc6_unres_queue)
518 goto end_of_list;
519
520 BUG_ON(it->cache != &mrt->mfc6_cache_array[it->ct]);
521
522 while (++it->ct < MFC6_LINES) {
523 it->cache = &mrt->mfc6_cache_array[it->ct];
524 if (list_empty(it->cache))
525 continue;
526 return list_first_entry(it->cache, struct mfc6_cache, list);
527 }
528
529 /* exhausted cache_array, show unresolved */
530 read_unlock(&mrt_lock);
531 it->cache = &mrt->mfc6_unres_queue;
532 it->ct = 0;
533
534 spin_lock_bh(&mfc_unres_lock);
535 if (!list_empty(it->cache))
536 return list_first_entry(it->cache, struct mfc6_cache, list);
537
538 end_of_list:
539 spin_unlock_bh(&mfc_unres_lock);
540 it->cache = NULL;
541
542 return NULL;
543}
544
545static void ipmr_mfc_seq_stop(struct seq_file *seq, void *v)
546{
547 struct ipmr_mfc_iter *it = seq->private;
548 struct mr6_table *mrt = it->mrt;
549
550 if (it->cache == &mrt->mfc6_unres_queue)
551 spin_unlock_bh(&mfc_unres_lock);
552 else if (it->cache == &mrt->mfc6_cache_array[it->ct])
553 read_unlock(&mrt_lock);
554} 438}
555 439
556static int ipmr_mfc_seq_show(struct seq_file *seq, void *v) 440static int ipmr_mfc_seq_show(struct seq_file *seq, void *v)
@@ -564,25 +448,25 @@ static int ipmr_mfc_seq_show(struct seq_file *seq, void *v)
564 "Iif Pkts Bytes Wrong Oifs\n"); 448 "Iif Pkts Bytes Wrong Oifs\n");
565 } else { 449 } else {
566 const struct mfc6_cache *mfc = v; 450 const struct mfc6_cache *mfc = v;
567 const struct ipmr_mfc_iter *it = seq->private; 451 const struct mr_mfc_iter *it = seq->private;
568 struct mr6_table *mrt = it->mrt; 452 struct mr_table *mrt = it->mrt;
569 453
570 seq_printf(seq, "%pI6 %pI6 %-3hd", 454 seq_printf(seq, "%pI6 %pI6 %-3hd",
571 &mfc->mf6c_mcastgrp, &mfc->mf6c_origin, 455 &mfc->mf6c_mcastgrp, &mfc->mf6c_origin,
572 mfc->mf6c_parent); 456 mfc->_c.mfc_parent);
573 457
574 if (it->cache != &mrt->mfc6_unres_queue) { 458 if (it->cache != &mrt->mfc_unres_queue) {
575 seq_printf(seq, " %8lu %8lu %8lu", 459 seq_printf(seq, " %8lu %8lu %8lu",
576 mfc->mfc_un.res.pkt, 460 mfc->_c.mfc_un.res.pkt,
577 mfc->mfc_un.res.bytes, 461 mfc->_c.mfc_un.res.bytes,
578 mfc->mfc_un.res.wrong_if); 462 mfc->_c.mfc_un.res.wrong_if);
579 for (n = mfc->mfc_un.res.minvif; 463 for (n = mfc->_c.mfc_un.res.minvif;
580 n < mfc->mfc_un.res.maxvif; n++) { 464 n < mfc->_c.mfc_un.res.maxvif; n++) {
581 if (MIF_EXISTS(mrt, n) && 465 if (VIF_EXISTS(mrt, n) &&
582 mfc->mfc_un.res.ttls[n] < 255) 466 mfc->_c.mfc_un.res.ttls[n] < 255)
583 seq_printf(seq, 467 seq_printf(seq,
584 " %2d:%-3d", 468 " %2d:%-3d", n,
585 n, mfc->mfc_un.res.ttls[n]); 469 mfc->_c.mfc_un.res.ttls[n]);
586 } 470 }
587 } else { 471 } else {
588 /* unresolved mfc_caches don't contain 472 /* unresolved mfc_caches don't contain
@@ -597,15 +481,15 @@ static int ipmr_mfc_seq_show(struct seq_file *seq, void *v)
597 481
598static const struct seq_operations ipmr_mfc_seq_ops = { 482static const struct seq_operations ipmr_mfc_seq_ops = {
599 .start = ipmr_mfc_seq_start, 483 .start = ipmr_mfc_seq_start,
600 .next = ipmr_mfc_seq_next, 484 .next = mr_mfc_seq_next,
601 .stop = ipmr_mfc_seq_stop, 485 .stop = mr_mfc_seq_stop,
602 .show = ipmr_mfc_seq_show, 486 .show = ipmr_mfc_seq_show,
603}; 487};
604 488
605static int ipmr_mfc_open(struct inode *inode, struct file *file) 489static int ipmr_mfc_open(struct inode *inode, struct file *file)
606{ 490{
607 return seq_open_net(inode, file, &ipmr_mfc_seq_ops, 491 return seq_open_net(inode, file, &ipmr_mfc_seq_ops,
608 sizeof(struct ipmr_mfc_iter)); 492 sizeof(struct mr_mfc_iter));
609} 493}
610 494
611static const struct file_operations ip6mr_mfc_fops = { 495static const struct file_operations ip6mr_mfc_fops = {
@@ -624,7 +508,7 @@ static int pim6_rcv(struct sk_buff *skb)
624 struct ipv6hdr *encap; 508 struct ipv6hdr *encap;
625 struct net_device *reg_dev = NULL; 509 struct net_device *reg_dev = NULL;
626 struct net *net = dev_net(skb->dev); 510 struct net *net = dev_net(skb->dev);
627 struct mr6_table *mrt; 511 struct mr_table *mrt;
628 struct flowi6 fl6 = { 512 struct flowi6 fl6 = {
629 .flowi6_iif = skb->dev->ifindex, 513 .flowi6_iif = skb->dev->ifindex,
630 .flowi6_mark = skb->mark, 514 .flowi6_mark = skb->mark,
@@ -658,7 +542,7 @@ static int pim6_rcv(struct sk_buff *skb)
658 542
659 read_lock(&mrt_lock); 543 read_lock(&mrt_lock);
660 if (reg_vif_num >= 0) 544 if (reg_vif_num >= 0)
661 reg_dev = mrt->vif6_table[reg_vif_num].dev; 545 reg_dev = mrt->vif_table[reg_vif_num].dev;
662 if (reg_dev) 546 if (reg_dev)
663 dev_hold(reg_dev); 547 dev_hold(reg_dev);
664 read_unlock(&mrt_lock); 548 read_unlock(&mrt_lock);
@@ -693,7 +577,7 @@ static netdev_tx_t reg_vif_xmit(struct sk_buff *skb,
693 struct net_device *dev) 577 struct net_device *dev)
694{ 578{
695 struct net *net = dev_net(dev); 579 struct net *net = dev_net(dev);
696 struct mr6_table *mrt; 580 struct mr_table *mrt;
697 struct flowi6 fl6 = { 581 struct flowi6 fl6 = {
698 .flowi6_oif = dev->ifindex, 582 .flowi6_oif = dev->ifindex,
699 .flowi6_iif = skb->skb_iif ? : LOOPBACK_IFINDEX, 583 .flowi6_iif = skb->skb_iif ? : LOOPBACK_IFINDEX,
@@ -736,7 +620,7 @@ static void reg_vif_setup(struct net_device *dev)
736 dev->features |= NETIF_F_NETNS_LOCAL; 620 dev->features |= NETIF_F_NETNS_LOCAL;
737} 621}
738 622
739static struct net_device *ip6mr_reg_vif(struct net *net, struct mr6_table *mrt) 623static struct net_device *ip6mr_reg_vif(struct net *net, struct mr_table *mrt)
740{ 624{
741 struct net_device *dev; 625 struct net_device *dev;
742 char name[IFNAMSIZ]; 626 char name[IFNAMSIZ];
@@ -773,17 +657,17 @@ failure:
773 * Delete a VIF entry 657 * Delete a VIF entry
774 */ 658 */
775 659
776static int mif6_delete(struct mr6_table *mrt, int vifi, int notify, 660static int mif6_delete(struct mr_table *mrt, int vifi, int notify,
777 struct list_head *head) 661 struct list_head *head)
778{ 662{
779 struct mif_device *v; 663 struct vif_device *v;
780 struct net_device *dev; 664 struct net_device *dev;
781 struct inet6_dev *in6_dev; 665 struct inet6_dev *in6_dev;
782 666
783 if (vifi < 0 || vifi >= mrt->maxvif) 667 if (vifi < 0 || vifi >= mrt->maxvif)
784 return -EADDRNOTAVAIL; 668 return -EADDRNOTAVAIL;
785 669
786 v = &mrt->vif6_table[vifi]; 670 v = &mrt->vif_table[vifi];
787 671
788 write_lock_bh(&mrt_lock); 672 write_lock_bh(&mrt_lock);
789 dev = v->dev; 673 dev = v->dev;
@@ -802,7 +686,7 @@ static int mif6_delete(struct mr6_table *mrt, int vifi, int notify,
802 if (vifi + 1 == mrt->maxvif) { 686 if (vifi + 1 == mrt->maxvif) {
803 int tmp; 687 int tmp;
804 for (tmp = vifi - 1; tmp >= 0; tmp--) { 688 for (tmp = vifi - 1; tmp >= 0; tmp--) {
805 if (MIF_EXISTS(mrt, tmp)) 689 if (VIF_EXISTS(mrt, tmp))
806 break; 690 break;
807 } 691 }
808 mrt->maxvif = tmp + 1; 692 mrt->maxvif = tmp + 1;
@@ -827,23 +711,30 @@ static int mif6_delete(struct mr6_table *mrt, int vifi, int notify,
827 return 0; 711 return 0;
828} 712}
829 713
714static inline void ip6mr_cache_free_rcu(struct rcu_head *head)
715{
716 struct mr_mfc *c = container_of(head, struct mr_mfc, rcu);
717
718 kmem_cache_free(mrt_cachep, (struct mfc6_cache *)c);
719}
720
830static inline void ip6mr_cache_free(struct mfc6_cache *c) 721static inline void ip6mr_cache_free(struct mfc6_cache *c)
831{ 722{
832 kmem_cache_free(mrt_cachep, c); 723 call_rcu(&c->_c.rcu, ip6mr_cache_free_rcu);
833} 724}
834 725
835/* Destroy an unresolved cache entry, killing queued skbs 726/* Destroy an unresolved cache entry, killing queued skbs
836 and reporting error to netlink readers. 727 and reporting error to netlink readers.
837 */ 728 */
838 729
839static void ip6mr_destroy_unres(struct mr6_table *mrt, struct mfc6_cache *c) 730static void ip6mr_destroy_unres(struct mr_table *mrt, struct mfc6_cache *c)
840{ 731{
841 struct net *net = read_pnet(&mrt->net); 732 struct net *net = read_pnet(&mrt->net);
842 struct sk_buff *skb; 733 struct sk_buff *skb;
843 734
844 atomic_dec(&mrt->cache_resolve_queue_len); 735 atomic_dec(&mrt->cache_resolve_queue_len);
845 736
846 while ((skb = skb_dequeue(&c->mfc_un.unres.unresolved)) != NULL) { 737 while ((skb = skb_dequeue(&c->_c.mfc_un.unres.unresolved)) != NULL) {
847 if (ipv6_hdr(skb)->version == 0) { 738 if (ipv6_hdr(skb)->version == 0) {
848 struct nlmsghdr *nlh = skb_pull(skb, 739 struct nlmsghdr *nlh = skb_pull(skb,
849 sizeof(struct ipv6hdr)); 740 sizeof(struct ipv6hdr));
@@ -862,13 +753,13 @@ static void ip6mr_destroy_unres(struct mr6_table *mrt, struct mfc6_cache *c)
862 753
863/* Timer process for all the unresolved queue. */ 754/* Timer process for all the unresolved queue. */
864 755
865static void ipmr_do_expire_process(struct mr6_table *mrt) 756static void ipmr_do_expire_process(struct mr_table *mrt)
866{ 757{
867 unsigned long now = jiffies; 758 unsigned long now = jiffies;
868 unsigned long expires = 10 * HZ; 759 unsigned long expires = 10 * HZ;
869 struct mfc6_cache *c, *next; 760 struct mr_mfc *c, *next;
870 761
871 list_for_each_entry_safe(c, next, &mrt->mfc6_unres_queue, list) { 762 list_for_each_entry_safe(c, next, &mrt->mfc_unres_queue, list) {
872 if (time_after(c->mfc_un.unres.expires, now)) { 763 if (time_after(c->mfc_un.unres.expires, now)) {
873 /* not yet... */ 764 /* not yet... */
874 unsigned long interval = c->mfc_un.unres.expires - now; 765 unsigned long interval = c->mfc_un.unres.expires - now;
@@ -878,24 +769,24 @@ static void ipmr_do_expire_process(struct mr6_table *mrt)
878 } 769 }
879 770
880 list_del(&c->list); 771 list_del(&c->list);
881 mr6_netlink_event(mrt, c, RTM_DELROUTE); 772 mr6_netlink_event(mrt, (struct mfc6_cache *)c, RTM_DELROUTE);
882 ip6mr_destroy_unres(mrt, c); 773 ip6mr_destroy_unres(mrt, (struct mfc6_cache *)c);
883 } 774 }
884 775
885 if (!list_empty(&mrt->mfc6_unres_queue)) 776 if (!list_empty(&mrt->mfc_unres_queue))
886 mod_timer(&mrt->ipmr_expire_timer, jiffies + expires); 777 mod_timer(&mrt->ipmr_expire_timer, jiffies + expires);
887} 778}
888 779
889static void ipmr_expire_process(struct timer_list *t) 780static void ipmr_expire_process(struct timer_list *t)
890{ 781{
891 struct mr6_table *mrt = from_timer(mrt, t, ipmr_expire_timer); 782 struct mr_table *mrt = from_timer(mrt, t, ipmr_expire_timer);
892 783
893 if (!spin_trylock(&mfc_unres_lock)) { 784 if (!spin_trylock(&mfc_unres_lock)) {
894 mod_timer(&mrt->ipmr_expire_timer, jiffies + 1); 785 mod_timer(&mrt->ipmr_expire_timer, jiffies + 1);
895 return; 786 return;
896 } 787 }
897 788
898 if (!list_empty(&mrt->mfc6_unres_queue)) 789 if (!list_empty(&mrt->mfc_unres_queue))
899 ipmr_do_expire_process(mrt); 790 ipmr_do_expire_process(mrt);
900 791
901 spin_unlock(&mfc_unres_lock); 792 spin_unlock(&mfc_unres_lock);
@@ -903,7 +794,8 @@ static void ipmr_expire_process(struct timer_list *t)
903 794
904/* Fill oifs list. It is called under write locked mrt_lock. */ 795/* Fill oifs list. It is called under write locked mrt_lock. */
905 796
906static void ip6mr_update_thresholds(struct mr6_table *mrt, struct mfc6_cache *cache, 797static void ip6mr_update_thresholds(struct mr_table *mrt,
798 struct mr_mfc *cache,
907 unsigned char *ttls) 799 unsigned char *ttls)
908{ 800{
909 int vifi; 801 int vifi;
@@ -913,7 +805,7 @@ static void ip6mr_update_thresholds(struct mr6_table *mrt, struct mfc6_cache *ca
913 memset(cache->mfc_un.res.ttls, 255, MAXMIFS); 805 memset(cache->mfc_un.res.ttls, 255, MAXMIFS);
914 806
915 for (vifi = 0; vifi < mrt->maxvif; vifi++) { 807 for (vifi = 0; vifi < mrt->maxvif; vifi++) {
916 if (MIF_EXISTS(mrt, vifi) && 808 if (VIF_EXISTS(mrt, vifi) &&
917 ttls[vifi] && ttls[vifi] < 255) { 809 ttls[vifi] && ttls[vifi] < 255) {
918 cache->mfc_un.res.ttls[vifi] = ttls[vifi]; 810 cache->mfc_un.res.ttls[vifi] = ttls[vifi];
919 if (cache->mfc_un.res.minvif > vifi) 811 if (cache->mfc_un.res.minvif > vifi)
@@ -925,17 +817,17 @@ static void ip6mr_update_thresholds(struct mr6_table *mrt, struct mfc6_cache *ca
925 cache->mfc_un.res.lastuse = jiffies; 817 cache->mfc_un.res.lastuse = jiffies;
926} 818}
927 819
928static int mif6_add(struct net *net, struct mr6_table *mrt, 820static int mif6_add(struct net *net, struct mr_table *mrt,
929 struct mif6ctl *vifc, int mrtsock) 821 struct mif6ctl *vifc, int mrtsock)
930{ 822{
931 int vifi = vifc->mif6c_mifi; 823 int vifi = vifc->mif6c_mifi;
932 struct mif_device *v = &mrt->vif6_table[vifi]; 824 struct vif_device *v = &mrt->vif_table[vifi];
933 struct net_device *dev; 825 struct net_device *dev;
934 struct inet6_dev *in6_dev; 826 struct inet6_dev *in6_dev;
935 int err; 827 int err;
936 828
937 /* Is vif busy ? */ 829 /* Is vif busy ? */
938 if (MIF_EXISTS(mrt, vifi)) 830 if (VIF_EXISTS(mrt, vifi))
939 return -EADDRINUSE; 831 return -EADDRINUSE;
940 832
941 switch (vifc->mif6c_flags) { 833 switch (vifc->mif6c_flags) {
@@ -980,21 +872,10 @@ static int mif6_add(struct net *net, struct mr6_table *mrt,
980 dev->ifindex, &in6_dev->cnf); 872 dev->ifindex, &in6_dev->cnf);
981 } 873 }
982 874
983 /* 875 /* Fill in the VIF structures */
984 * Fill in the VIF structures 876 vif_device_init(v, dev, vifc->vifc_rate_limit, vifc->vifc_threshold,
985 */ 877 vifc->mif6c_flags | (!mrtsock ? VIFF_STATIC : 0),
986 v->rate_limit = vifc->vifc_rate_limit; 878 MIFF_REGISTER);
987 v->flags = vifc->mif6c_flags;
988 if (!mrtsock)
989 v->flags |= VIFF_STATIC;
990 v->threshold = vifc->vifc_threshold;
991 v->bytes_in = 0;
992 v->bytes_out = 0;
993 v->pkt_in = 0;
994 v->pkt_out = 0;
995 v->link = dev->ifindex;
996 if (v->flags & MIFF_REGISTER)
997 v->link = dev_get_iflink(dev);
998 879
999 /* And finish update writing critical data */ 880 /* And finish update writing critical data */
1000 write_lock_bh(&mrt_lock); 881 write_lock_bh(&mrt_lock);
@@ -1009,75 +890,56 @@ static int mif6_add(struct net *net, struct mr6_table *mrt,
1009 return 0; 890 return 0;
1010} 891}
1011 892
1012static struct mfc6_cache *ip6mr_cache_find(struct mr6_table *mrt, 893static struct mfc6_cache *ip6mr_cache_find(struct mr_table *mrt,
1013 const struct in6_addr *origin, 894 const struct in6_addr *origin,
1014 const struct in6_addr *mcastgrp) 895 const struct in6_addr *mcastgrp)
1015{ 896{
1016 int line = MFC6_HASH(mcastgrp, origin); 897 struct mfc6_cache_cmp_arg arg = {
1017 struct mfc6_cache *c; 898 .mf6c_origin = *origin,
1018 899 .mf6c_mcastgrp = *mcastgrp,
1019 list_for_each_entry(c, &mrt->mfc6_cache_array[line], list) { 900 };
1020 if (ipv6_addr_equal(&c->mf6c_origin, origin) &&
1021 ipv6_addr_equal(&c->mf6c_mcastgrp, mcastgrp))
1022 return c;
1023 }
1024 return NULL;
1025}
1026
1027/* Look for a (*,*,oif) entry */
1028static struct mfc6_cache *ip6mr_cache_find_any_parent(struct mr6_table *mrt,
1029 mifi_t mifi)
1030{
1031 int line = MFC6_HASH(&in6addr_any, &in6addr_any);
1032 struct mfc6_cache *c;
1033
1034 list_for_each_entry(c, &mrt->mfc6_cache_array[line], list)
1035 if (ipv6_addr_any(&c->mf6c_origin) &&
1036 ipv6_addr_any(&c->mf6c_mcastgrp) &&
1037 (c->mfc_un.res.ttls[mifi] < 255))
1038 return c;
1039 901
1040 return NULL; 902 return mr_mfc_find(mrt, &arg);
1041} 903}
1042 904
1043/* Look for a (*,G) entry */ 905/* Look for a (*,G) entry */
1044static struct mfc6_cache *ip6mr_cache_find_any(struct mr6_table *mrt, 906static struct mfc6_cache *ip6mr_cache_find_any(struct mr_table *mrt,
1045 struct in6_addr *mcastgrp, 907 struct in6_addr *mcastgrp,
1046 mifi_t mifi) 908 mifi_t mifi)
1047{ 909{
1048 int line = MFC6_HASH(mcastgrp, &in6addr_any); 910 struct mfc6_cache_cmp_arg arg = {
1049 struct mfc6_cache *c, *proxy; 911 .mf6c_origin = in6addr_any,
912 .mf6c_mcastgrp = *mcastgrp,
913 };
1050 914
1051 if (ipv6_addr_any(mcastgrp)) 915 if (ipv6_addr_any(mcastgrp))
1052 goto skip; 916 return mr_mfc_find_any_parent(mrt, mifi);
1053 917 return mr_mfc_find_any(mrt, mifi, &arg);
1054 list_for_each_entry(c, &mrt->mfc6_cache_array[line], list) 918}
1055 if (ipv6_addr_any(&c->mf6c_origin) &&
1056 ipv6_addr_equal(&c->mf6c_mcastgrp, mcastgrp)) {
1057 if (c->mfc_un.res.ttls[mifi] < 255)
1058 return c;
1059
1060 /* It's ok if the mifi is part of the static tree */
1061 proxy = ip6mr_cache_find_any_parent(mrt,
1062 c->mf6c_parent);
1063 if (proxy && proxy->mfc_un.res.ttls[mifi] < 255)
1064 return c;
1065 }
1066 919
1067skip: 920/* Look for a (S,G,iif) entry if parent != -1 */
1068 return ip6mr_cache_find_any_parent(mrt, mifi); 921static struct mfc6_cache *
922ip6mr_cache_find_parent(struct mr_table *mrt,
923 const struct in6_addr *origin,
924 const struct in6_addr *mcastgrp,
925 int parent)
926{
927 struct mfc6_cache_cmp_arg arg = {
928 .mf6c_origin = *origin,
929 .mf6c_mcastgrp = *mcastgrp,
930 };
931
932 return mr_mfc_find_parent(mrt, &arg, parent);
1069} 933}
1070 934
1071/* 935/* Allocate a multicast cache entry */
1072 * Allocate a multicast cache entry
1073 */
1074static struct mfc6_cache *ip6mr_cache_alloc(void) 936static struct mfc6_cache *ip6mr_cache_alloc(void)
1075{ 937{
1076 struct mfc6_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_KERNEL); 938 struct mfc6_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_KERNEL);
1077 if (!c) 939 if (!c)
1078 return NULL; 940 return NULL;
1079 c->mfc_un.res.last_assert = jiffies - MFC_ASSERT_THRESH - 1; 941 c->_c.mfc_un.res.last_assert = jiffies - MFC_ASSERT_THRESH - 1;
1080 c->mfc_un.res.minvif = MAXMIFS; 942 c->_c.mfc_un.res.minvif = MAXMIFS;
1081 return c; 943 return c;
1082} 944}
1083 945
@@ -1086,8 +948,8 @@ static struct mfc6_cache *ip6mr_cache_alloc_unres(void)
1086 struct mfc6_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_ATOMIC); 948 struct mfc6_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_ATOMIC);
1087 if (!c) 949 if (!c)
1088 return NULL; 950 return NULL;
1089 skb_queue_head_init(&c->mfc_un.unres.unresolved); 951 skb_queue_head_init(&c->_c.mfc_un.unres.unresolved);
1090 c->mfc_un.unres.expires = jiffies + 10 * HZ; 952 c->_c.mfc_un.unres.expires = jiffies + 10 * HZ;
1091 return c; 953 return c;
1092} 954}
1093 955
@@ -1095,7 +957,7 @@ static struct mfc6_cache *ip6mr_cache_alloc_unres(void)
1095 * A cache entry has gone into a resolved state from queued 957 * A cache entry has gone into a resolved state from queued
1096 */ 958 */
1097 959
1098static void ip6mr_cache_resolve(struct net *net, struct mr6_table *mrt, 960static void ip6mr_cache_resolve(struct net *net, struct mr_table *mrt,
1099 struct mfc6_cache *uc, struct mfc6_cache *c) 961 struct mfc6_cache *uc, struct mfc6_cache *c)
1100{ 962{
1101 struct sk_buff *skb; 963 struct sk_buff *skb;
@@ -1104,12 +966,13 @@ static void ip6mr_cache_resolve(struct net *net, struct mr6_table *mrt,
1104 * Play the pending entries through our router 966 * Play the pending entries through our router
1105 */ 967 */
1106 968
1107 while ((skb = __skb_dequeue(&uc->mfc_un.unres.unresolved))) { 969 while ((skb = __skb_dequeue(&uc->_c.mfc_un.unres.unresolved))) {
1108 if (ipv6_hdr(skb)->version == 0) { 970 if (ipv6_hdr(skb)->version == 0) {
1109 struct nlmsghdr *nlh = skb_pull(skb, 971 struct nlmsghdr *nlh = skb_pull(skb,
1110 sizeof(struct ipv6hdr)); 972 sizeof(struct ipv6hdr));
1111 973
1112 if (__ip6mr_fill_mroute(mrt, skb, c, nlmsg_data(nlh)) > 0) { 974 if (mr_fill_mroute(mrt, skb, &c->_c,
975 nlmsg_data(nlh)) > 0) {
1113 nlh->nlmsg_len = skb_tail_pointer(skb) - (u8 *)nlh; 976 nlh->nlmsg_len = skb_tail_pointer(skb) - (u8 *)nlh;
1114 } else { 977 } else {
1115 nlh->nlmsg_type = NLMSG_ERROR; 978 nlh->nlmsg_type = NLMSG_ERROR;
@@ -1129,9 +992,10 @@ static void ip6mr_cache_resolve(struct net *net, struct mr6_table *mrt,
1129 * Called under mrt_lock. 992 * Called under mrt_lock.
1130 */ 993 */
1131 994
1132static int ip6mr_cache_report(struct mr6_table *mrt, struct sk_buff *pkt, 995static int ip6mr_cache_report(struct mr_table *mrt, struct sk_buff *pkt,
1133 mifi_t mifi, int assert) 996 mifi_t mifi, int assert)
1134{ 997{
998 struct sock *mroute6_sk;
1135 struct sk_buff *skb; 999 struct sk_buff *skb;
1136 struct mrt6msg *msg; 1000 struct mrt6msg *msg;
1137 int ret; 1001 int ret;
@@ -1201,17 +1065,19 @@ static int ip6mr_cache_report(struct mr6_table *mrt, struct sk_buff *pkt,
1201 skb->ip_summed = CHECKSUM_UNNECESSARY; 1065 skb->ip_summed = CHECKSUM_UNNECESSARY;
1202 } 1066 }
1203 1067
1204 if (!mrt->mroute6_sk) { 1068 rcu_read_lock();
1069 mroute6_sk = rcu_dereference(mrt->mroute_sk);
1070 if (!mroute6_sk) {
1071 rcu_read_unlock();
1205 kfree_skb(skb); 1072 kfree_skb(skb);
1206 return -EINVAL; 1073 return -EINVAL;
1207 } 1074 }
1208 1075
1209 mrt6msg_netlink_event(mrt, skb); 1076 mrt6msg_netlink_event(mrt, skb);
1210 1077
1211 /* 1078 /* Deliver to user space multicast routing algorithms */
1212 * Deliver to user space multicast routing algorithms 1079 ret = sock_queue_rcv_skb(mroute6_sk, skb);
1213 */ 1080 rcu_read_unlock();
1214 ret = sock_queue_rcv_skb(mrt->mroute6_sk, skb);
1215 if (ret < 0) { 1081 if (ret < 0) {
1216 net_warn_ratelimited("mroute6: pending queue full, dropping entries\n"); 1082 net_warn_ratelimited("mroute6: pending queue full, dropping entries\n");
1217 kfree_skb(skb); 1083 kfree_skb(skb);
@@ -1220,19 +1086,16 @@ static int ip6mr_cache_report(struct mr6_table *mrt, struct sk_buff *pkt,
1220 return ret; 1086 return ret;
1221} 1087}
1222 1088
1223/* 1089/* Queue a packet for resolution. It gets locked cache entry! */
1224 * Queue a packet for resolution. It gets locked cache entry! 1090static int ip6mr_cache_unresolved(struct mr_table *mrt, mifi_t mifi,
1225 */ 1091 struct sk_buff *skb)
1226
1227static int
1228ip6mr_cache_unresolved(struct mr6_table *mrt, mifi_t mifi, struct sk_buff *skb)
1229{ 1092{
1093 struct mfc6_cache *c;
1230 bool found = false; 1094 bool found = false;
1231 int err; 1095 int err;
1232 struct mfc6_cache *c;
1233 1096
1234 spin_lock_bh(&mfc_unres_lock); 1097 spin_lock_bh(&mfc_unres_lock);
1235 list_for_each_entry(c, &mrt->mfc6_unres_queue, list) { 1098 list_for_each_entry(c, &mrt->mfc_unres_queue, _c.list) {
1236 if (ipv6_addr_equal(&c->mf6c_mcastgrp, &ipv6_hdr(skb)->daddr) && 1099 if (ipv6_addr_equal(&c->mf6c_mcastgrp, &ipv6_hdr(skb)->daddr) &&
1237 ipv6_addr_equal(&c->mf6c_origin, &ipv6_hdr(skb)->saddr)) { 1100 ipv6_addr_equal(&c->mf6c_origin, &ipv6_hdr(skb)->saddr)) {
1238 found = true; 1101 found = true;
@@ -1253,10 +1116,8 @@ ip6mr_cache_unresolved(struct mr6_table *mrt, mifi_t mifi, struct sk_buff *skb)
1253 return -ENOBUFS; 1116 return -ENOBUFS;
1254 } 1117 }
1255 1118
1256 /* 1119 /* Fill in the new cache entry */
1257 * Fill in the new cache entry 1120 c->_c.mfc_parent = -1;
1258 */
1259 c->mf6c_parent = -1;
1260 c->mf6c_origin = ipv6_hdr(skb)->saddr; 1121 c->mf6c_origin = ipv6_hdr(skb)->saddr;
1261 c->mf6c_mcastgrp = ipv6_hdr(skb)->daddr; 1122 c->mf6c_mcastgrp = ipv6_hdr(skb)->daddr;
1262 1123
@@ -1276,20 +1137,18 @@ ip6mr_cache_unresolved(struct mr6_table *mrt, mifi_t mifi, struct sk_buff *skb)
1276 } 1137 }
1277 1138
1278 atomic_inc(&mrt->cache_resolve_queue_len); 1139 atomic_inc(&mrt->cache_resolve_queue_len);
1279 list_add(&c->list, &mrt->mfc6_unres_queue); 1140 list_add(&c->_c.list, &mrt->mfc_unres_queue);
1280 mr6_netlink_event(mrt, c, RTM_NEWROUTE); 1141 mr6_netlink_event(mrt, c, RTM_NEWROUTE);
1281 1142
1282 ipmr_do_expire_process(mrt); 1143 ipmr_do_expire_process(mrt);
1283 } 1144 }
1284 1145
1285 /* 1146 /* See if we can append the packet */
1286 * See if we can append the packet 1147 if (c->_c.mfc_un.unres.unresolved.qlen > 3) {
1287 */
1288 if (c->mfc_un.unres.unresolved.qlen > 3) {
1289 kfree_skb(skb); 1148 kfree_skb(skb);
1290 err = -ENOBUFS; 1149 err = -ENOBUFS;
1291 } else { 1150 } else {
1292 skb_queue_tail(&c->mfc_un.unres.unresolved, skb); 1151 skb_queue_tail(&c->_c.mfc_un.unres.unresolved, skb);
1293 err = 0; 1152 err = 0;
1294 } 1153 }
1295 1154
@@ -1301,29 +1160,24 @@ ip6mr_cache_unresolved(struct mr6_table *mrt, mifi_t mifi, struct sk_buff *skb)
1301 * MFC6 cache manipulation by user space 1160 * MFC6 cache manipulation by user space
1302 */ 1161 */
1303 1162
1304static int ip6mr_mfc_delete(struct mr6_table *mrt, struct mf6cctl *mfc, 1163static int ip6mr_mfc_delete(struct mr_table *mrt, struct mf6cctl *mfc,
1305 int parent) 1164 int parent)
1306{ 1165{
1307 int line; 1166 struct mfc6_cache *c;
1308 struct mfc6_cache *c, *next;
1309
1310 line = MFC6_HASH(&mfc->mf6cc_mcastgrp.sin6_addr, &mfc->mf6cc_origin.sin6_addr);
1311 1167
1312 list_for_each_entry_safe(c, next, &mrt->mfc6_cache_array[line], list) { 1168 /* The entries are added/deleted only under RTNL */
1313 if (ipv6_addr_equal(&c->mf6c_origin, &mfc->mf6cc_origin.sin6_addr) && 1169 rcu_read_lock();
1314 ipv6_addr_equal(&c->mf6c_mcastgrp, 1170 c = ip6mr_cache_find_parent(mrt, &mfc->mf6cc_origin.sin6_addr,
1315 &mfc->mf6cc_mcastgrp.sin6_addr) && 1171 &mfc->mf6cc_mcastgrp.sin6_addr, parent);
1316 (parent == -1 || parent == c->mf6c_parent)) { 1172 rcu_read_unlock();
1317 write_lock_bh(&mrt_lock); 1173 if (!c)
1318 list_del(&c->list); 1174 return -ENOENT;
1319 write_unlock_bh(&mrt_lock); 1175 rhltable_remove(&mrt->mfc_hash, &c->_c.mnode, ip6mr_rht_params);
1176 list_del_rcu(&c->_c.list);
1320 1177
1321 mr6_netlink_event(mrt, c, RTM_DELROUTE); 1178 mr6_netlink_event(mrt, c, RTM_DELROUTE);
1322 ip6mr_cache_free(c); 1179 ip6mr_cache_free(c);
1323 return 0; 1180 return 0;
1324 }
1325 }
1326 return -ENOENT;
1327} 1181}
1328 1182
1329static int ip6mr_device_event(struct notifier_block *this, 1183static int ip6mr_device_event(struct notifier_block *this,
@@ -1331,15 +1185,15 @@ static int ip6mr_device_event(struct notifier_block *this,
1331{ 1185{
1332 struct net_device *dev = netdev_notifier_info_to_dev(ptr); 1186 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
1333 struct net *net = dev_net(dev); 1187 struct net *net = dev_net(dev);
1334 struct mr6_table *mrt; 1188 struct mr_table *mrt;
1335 struct mif_device *v; 1189 struct vif_device *v;
1336 int ct; 1190 int ct;
1337 1191
1338 if (event != NETDEV_UNREGISTER) 1192 if (event != NETDEV_UNREGISTER)
1339 return NOTIFY_DONE; 1193 return NOTIFY_DONE;
1340 1194
1341 ip6mr_for_each_table(mrt, net) { 1195 ip6mr_for_each_table(mrt, net) {
1342 v = &mrt->vif6_table[0]; 1196 v = &mrt->vif_table[0];
1343 for (ct = 0; ct < mrt->maxvif; ct++, v++) { 1197 for (ct = 0; ct < mrt->maxvif; ct++, v++) {
1344 if (v->dev == dev) 1198 if (v->dev == dev)
1345 mif6_delete(mrt, ct, 1, NULL); 1199 mif6_delete(mrt, ct, 1, NULL);
@@ -1397,6 +1251,7 @@ static void __net_exit ip6mr_net_exit(struct net *net)
1397static struct pernet_operations ip6mr_net_ops = { 1251static struct pernet_operations ip6mr_net_ops = {
1398 .init = ip6mr_net_init, 1252 .init = ip6mr_net_init,
1399 .exit = ip6mr_net_exit, 1253 .exit = ip6mr_net_exit,
1254 .async = true,
1400}; 1255};
1401 1256
1402int __init ip6_mr_init(void) 1257int __init ip6_mr_init(void)
@@ -1452,14 +1307,14 @@ void ip6_mr_cleanup(void)
1452 kmem_cache_destroy(mrt_cachep); 1307 kmem_cache_destroy(mrt_cachep);
1453} 1308}
1454 1309
1455static int ip6mr_mfc_add(struct net *net, struct mr6_table *mrt, 1310static int ip6mr_mfc_add(struct net *net, struct mr_table *mrt,
1456 struct mf6cctl *mfc, int mrtsock, int parent) 1311 struct mf6cctl *mfc, int mrtsock, int parent)
1457{ 1312{
1458 bool found = false;
1459 int line;
1460 struct mfc6_cache *uc, *c;
1461 unsigned char ttls[MAXMIFS]; 1313 unsigned char ttls[MAXMIFS];
1462 int i; 1314 struct mfc6_cache *uc, *c;
1315 struct mr_mfc *_uc;
1316 bool found;
1317 int i, err;
1463 1318
1464 if (mfc->mf6cc_parent >= MAXMIFS) 1319 if (mfc->mf6cc_parent >= MAXMIFS)
1465 return -ENFILE; 1320 return -ENFILE;
@@ -1468,27 +1323,19 @@ static int ip6mr_mfc_add(struct net *net, struct mr6_table *mrt,
1468 for (i = 0; i < MAXMIFS; i++) { 1323 for (i = 0; i < MAXMIFS; i++) {
1469 if (IF_ISSET(i, &mfc->mf6cc_ifset)) 1324 if (IF_ISSET(i, &mfc->mf6cc_ifset))
1470 ttls[i] = 1; 1325 ttls[i] = 1;
1471
1472 }
1473
1474 line = MFC6_HASH(&mfc->mf6cc_mcastgrp.sin6_addr, &mfc->mf6cc_origin.sin6_addr);
1475
1476 list_for_each_entry(c, &mrt->mfc6_cache_array[line], list) {
1477 if (ipv6_addr_equal(&c->mf6c_origin, &mfc->mf6cc_origin.sin6_addr) &&
1478 ipv6_addr_equal(&c->mf6c_mcastgrp,
1479 &mfc->mf6cc_mcastgrp.sin6_addr) &&
1480 (parent == -1 || parent == mfc->mf6cc_parent)) {
1481 found = true;
1482 break;
1483 }
1484 } 1326 }
1485 1327
1486 if (found) { 1328 /* The entries are added/deleted only under RTNL */
1329 rcu_read_lock();
1330 c = ip6mr_cache_find_parent(mrt, &mfc->mf6cc_origin.sin6_addr,
1331 &mfc->mf6cc_mcastgrp.sin6_addr, parent);
1332 rcu_read_unlock();
1333 if (c) {
1487 write_lock_bh(&mrt_lock); 1334 write_lock_bh(&mrt_lock);
1488 c->mf6c_parent = mfc->mf6cc_parent; 1335 c->_c.mfc_parent = mfc->mf6cc_parent;
1489 ip6mr_update_thresholds(mrt, c, ttls); 1336 ip6mr_update_thresholds(mrt, &c->_c, ttls);
1490 if (!mrtsock) 1337 if (!mrtsock)
1491 c->mfc_flags |= MFC_STATIC; 1338 c->_c.mfc_flags |= MFC_STATIC;
1492 write_unlock_bh(&mrt_lock); 1339 write_unlock_bh(&mrt_lock);
1493 mr6_netlink_event(mrt, c, RTM_NEWROUTE); 1340 mr6_netlink_event(mrt, c, RTM_NEWROUTE);
1494 return 0; 1341 return 0;
@@ -1504,31 +1351,36 @@ static int ip6mr_mfc_add(struct net *net, struct mr6_table *mrt,
1504 1351
1505 c->mf6c_origin = mfc->mf6cc_origin.sin6_addr; 1352 c->mf6c_origin = mfc->mf6cc_origin.sin6_addr;
1506 c->mf6c_mcastgrp = mfc->mf6cc_mcastgrp.sin6_addr; 1353 c->mf6c_mcastgrp = mfc->mf6cc_mcastgrp.sin6_addr;
1507 c->mf6c_parent = mfc->mf6cc_parent; 1354 c->_c.mfc_parent = mfc->mf6cc_parent;
1508 ip6mr_update_thresholds(mrt, c, ttls); 1355 ip6mr_update_thresholds(mrt, &c->_c, ttls);
1509 if (!mrtsock) 1356 if (!mrtsock)
1510 c->mfc_flags |= MFC_STATIC; 1357 c->_c.mfc_flags |= MFC_STATIC;
1511 1358
1512 write_lock_bh(&mrt_lock); 1359 err = rhltable_insert_key(&mrt->mfc_hash, &c->cmparg, &c->_c.mnode,
1513 list_add(&c->list, &mrt->mfc6_cache_array[line]); 1360 ip6mr_rht_params);
1514 write_unlock_bh(&mrt_lock); 1361 if (err) {
1362 pr_err("ip6mr: rhtable insert error %d\n", err);
1363 ip6mr_cache_free(c);
1364 return err;
1365 }
1366 list_add_tail_rcu(&c->_c.list, &mrt->mfc_cache_list);
1515 1367
1516 /* 1368 /* Check to see if we resolved a queued list. If so we
1517 * Check to see if we resolved a queued list. If so we 1369 * need to send on the frames and tidy up.
1518 * need to send on the frames and tidy up.
1519 */ 1370 */
1520 found = false; 1371 found = false;
1521 spin_lock_bh(&mfc_unres_lock); 1372 spin_lock_bh(&mfc_unres_lock);
1522 list_for_each_entry(uc, &mrt->mfc6_unres_queue, list) { 1373 list_for_each_entry(_uc, &mrt->mfc_unres_queue, list) {
1374 uc = (struct mfc6_cache *)_uc;
1523 if (ipv6_addr_equal(&uc->mf6c_origin, &c->mf6c_origin) && 1375 if (ipv6_addr_equal(&uc->mf6c_origin, &c->mf6c_origin) &&
1524 ipv6_addr_equal(&uc->mf6c_mcastgrp, &c->mf6c_mcastgrp)) { 1376 ipv6_addr_equal(&uc->mf6c_mcastgrp, &c->mf6c_mcastgrp)) {
1525 list_del(&uc->list); 1377 list_del(&_uc->list);
1526 atomic_dec(&mrt->cache_resolve_queue_len); 1378 atomic_dec(&mrt->cache_resolve_queue_len);
1527 found = true; 1379 found = true;
1528 break; 1380 break;
1529 } 1381 }
1530 } 1382 }
1531 if (list_empty(&mrt->mfc6_unres_queue)) 1383 if (list_empty(&mrt->mfc_unres_queue))
1532 del_timer(&mrt->ipmr_expire_timer); 1384 del_timer(&mrt->ipmr_expire_timer);
1533 spin_unlock_bh(&mfc_unres_lock); 1385 spin_unlock_bh(&mfc_unres_lock);
1534 1386
@@ -1544,61 +1396,55 @@ static int ip6mr_mfc_add(struct net *net, struct mr6_table *mrt,
1544 * Close the multicast socket, and clear the vif tables etc 1396 * Close the multicast socket, and clear the vif tables etc
1545 */ 1397 */
1546 1398
1547static void mroute_clean_tables(struct mr6_table *mrt, bool all) 1399static void mroute_clean_tables(struct mr_table *mrt, bool all)
1548{ 1400{
1549 int i; 1401 struct mr_mfc *c, *tmp;
1550 LIST_HEAD(list); 1402 LIST_HEAD(list);
1551 struct mfc6_cache *c, *next; 1403 int i;
1552 1404
1553 /* 1405 /* Shut down all active vif entries */
1554 * Shut down all active vif entries
1555 */
1556 for (i = 0; i < mrt->maxvif; i++) { 1406 for (i = 0; i < mrt->maxvif; i++) {
1557 if (!all && (mrt->vif6_table[i].flags & VIFF_STATIC)) 1407 if (!all && (mrt->vif_table[i].flags & VIFF_STATIC))
1558 continue; 1408 continue;
1559 mif6_delete(mrt, i, 0, &list); 1409 mif6_delete(mrt, i, 0, &list);
1560 } 1410 }
1561 unregister_netdevice_many(&list); 1411 unregister_netdevice_many(&list);
1562 1412
1563 /* 1413 /* Wipe the cache */
1564 * Wipe the cache 1414 list_for_each_entry_safe(c, tmp, &mrt->mfc_cache_list, list) {
1565 */ 1415 if (!all && (c->mfc_flags & MFC_STATIC))
1566 for (i = 0; i < MFC6_LINES; i++) { 1416 continue;
1567 list_for_each_entry_safe(c, next, &mrt->mfc6_cache_array[i], list) { 1417 rhltable_remove(&mrt->mfc_hash, &c->mnode, ip6mr_rht_params);
1568 if (!all && (c->mfc_flags & MFC_STATIC)) 1418 list_del_rcu(&c->list);
1569 continue; 1419 mr6_netlink_event(mrt, (struct mfc6_cache *)c, RTM_DELROUTE);
1570 write_lock_bh(&mrt_lock); 1420 ip6mr_cache_free((struct mfc6_cache *)c);
1571 list_del(&c->list);
1572 write_unlock_bh(&mrt_lock);
1573
1574 mr6_netlink_event(mrt, c, RTM_DELROUTE);
1575 ip6mr_cache_free(c);
1576 }
1577 } 1421 }
1578 1422
1579 if (atomic_read(&mrt->cache_resolve_queue_len) != 0) { 1423 if (atomic_read(&mrt->cache_resolve_queue_len) != 0) {
1580 spin_lock_bh(&mfc_unres_lock); 1424 spin_lock_bh(&mfc_unres_lock);
1581 list_for_each_entry_safe(c, next, &mrt->mfc6_unres_queue, list) { 1425 list_for_each_entry_safe(c, tmp, &mrt->mfc_unres_queue, list) {
1582 list_del(&c->list); 1426 list_del(&c->list);
1583 mr6_netlink_event(mrt, c, RTM_DELROUTE); 1427 mr6_netlink_event(mrt, (struct mfc6_cache *)c,
1584 ip6mr_destroy_unres(mrt, c); 1428 RTM_DELROUTE);
1429 ip6mr_destroy_unres(mrt, (struct mfc6_cache *)c);
1585 } 1430 }
1586 spin_unlock_bh(&mfc_unres_lock); 1431 spin_unlock_bh(&mfc_unres_lock);
1587 } 1432 }
1588} 1433}
1589 1434
1590static int ip6mr_sk_init(struct mr6_table *mrt, struct sock *sk) 1435static int ip6mr_sk_init(struct mr_table *mrt, struct sock *sk)
1591{ 1436{
1592 int err = 0; 1437 int err = 0;
1593 struct net *net = sock_net(sk); 1438 struct net *net = sock_net(sk);
1594 1439
1595 rtnl_lock(); 1440 rtnl_lock();
1596 write_lock_bh(&mrt_lock); 1441 write_lock_bh(&mrt_lock);
1597 if (likely(mrt->mroute6_sk == NULL)) { 1442 if (rtnl_dereference(mrt->mroute_sk)) {
1598 mrt->mroute6_sk = sk;
1599 net->ipv6.devconf_all->mc_forwarding++;
1600 } else {
1601 err = -EADDRINUSE; 1443 err = -EADDRINUSE;
1444 } else {
1445 rcu_assign_pointer(mrt->mroute_sk, sk);
1446 sock_set_flag(sk, SOCK_RCU_FREE);
1447 net->ipv6.devconf_all->mc_forwarding++;
1602 } 1448 }
1603 write_unlock_bh(&mrt_lock); 1449 write_unlock_bh(&mrt_lock);
1604 1450
@@ -1616,7 +1462,7 @@ int ip6mr_sk_done(struct sock *sk)
1616{ 1462{
1617 int err = -EACCES; 1463 int err = -EACCES;
1618 struct net *net = sock_net(sk); 1464 struct net *net = sock_net(sk);
1619 struct mr6_table *mrt; 1465 struct mr_table *mrt;
1620 1466
1621 if (sk->sk_type != SOCK_RAW || 1467 if (sk->sk_type != SOCK_RAW ||
1622 inet_sk(sk)->inet_num != IPPROTO_ICMPV6) 1468 inet_sk(sk)->inet_num != IPPROTO_ICMPV6)
@@ -1624,9 +1470,13 @@ int ip6mr_sk_done(struct sock *sk)
1624 1470
1625 rtnl_lock(); 1471 rtnl_lock();
1626 ip6mr_for_each_table(mrt, net) { 1472 ip6mr_for_each_table(mrt, net) {
1627 if (sk == mrt->mroute6_sk) { 1473 if (sk == rtnl_dereference(mrt->mroute_sk)) {
1628 write_lock_bh(&mrt_lock); 1474 write_lock_bh(&mrt_lock);
1629 mrt->mroute6_sk = NULL; 1475 RCU_INIT_POINTER(mrt->mroute_sk, NULL);
1476 /* Note that mroute_sk had SOCK_RCU_FREE set,
1477 * so the RCU grace period before sk freeing
1478 * is guaranteed by sk_destruct()
1479 */
1630 net->ipv6.devconf_all->mc_forwarding--; 1480 net->ipv6.devconf_all->mc_forwarding--;
1631 write_unlock_bh(&mrt_lock); 1481 write_unlock_bh(&mrt_lock);
1632 inet6_netconf_notify_devconf(net, RTM_NEWNETCONF, 1482 inet6_netconf_notify_devconf(net, RTM_NEWNETCONF,
@@ -1644,9 +1494,9 @@ int ip6mr_sk_done(struct sock *sk)
1644 return err; 1494 return err;
1645} 1495}
1646 1496
1647struct sock *mroute6_socket(struct net *net, struct sk_buff *skb) 1497bool mroute6_is_socket(struct net *net, struct sk_buff *skb)
1648{ 1498{
1649 struct mr6_table *mrt; 1499 struct mr_table *mrt;
1650 struct flowi6 fl6 = { 1500 struct flowi6 fl6 = {
1651 .flowi6_iif = skb->skb_iif ? : LOOPBACK_IFINDEX, 1501 .flowi6_iif = skb->skb_iif ? : LOOPBACK_IFINDEX,
1652 .flowi6_oif = skb->dev->ifindex, 1502 .flowi6_oif = skb->dev->ifindex,
@@ -1656,8 +1506,9 @@ struct sock *mroute6_socket(struct net *net, struct sk_buff *skb)
1656 if (ip6mr_fib_lookup(net, &fl6, &mrt) < 0) 1506 if (ip6mr_fib_lookup(net, &fl6, &mrt) < 0)
1657 return NULL; 1507 return NULL;
1658 1508
1659 return mrt->mroute6_sk; 1509 return rcu_access_pointer(mrt->mroute_sk);
1660} 1510}
1511EXPORT_SYMBOL(mroute6_is_socket);
1661 1512
1662/* 1513/*
1663 * Socket options and virtual interface manipulation. The whole 1514 * Socket options and virtual interface manipulation. The whole
@@ -1673,7 +1524,7 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, uns
1673 struct mf6cctl mfc; 1524 struct mf6cctl mfc;
1674 mifi_t mifi; 1525 mifi_t mifi;
1675 struct net *net = sock_net(sk); 1526 struct net *net = sock_net(sk);
1676 struct mr6_table *mrt; 1527 struct mr_table *mrt;
1677 1528
1678 if (sk->sk_type != SOCK_RAW || 1529 if (sk->sk_type != SOCK_RAW ||
1679 inet_sk(sk)->inet_num != IPPROTO_ICMPV6) 1530 inet_sk(sk)->inet_num != IPPROTO_ICMPV6)
@@ -1684,7 +1535,8 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, uns
1684 return -ENOENT; 1535 return -ENOENT;
1685 1536
1686 if (optname != MRT6_INIT) { 1537 if (optname != MRT6_INIT) {
1687 if (sk != mrt->mroute6_sk && !ns_capable(net->user_ns, CAP_NET_ADMIN)) 1538 if (sk != rcu_access_pointer(mrt->mroute_sk) &&
1539 !ns_capable(net->user_ns, CAP_NET_ADMIN))
1688 return -EACCES; 1540 return -EACCES;
1689 } 1541 }
1690 1542
@@ -1706,7 +1558,8 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, uns
1706 if (vif.mif6c_mifi >= MAXMIFS) 1558 if (vif.mif6c_mifi >= MAXMIFS)
1707 return -ENFILE; 1559 return -ENFILE;
1708 rtnl_lock(); 1560 rtnl_lock();
1709 ret = mif6_add(net, mrt, &vif, sk == mrt->mroute6_sk); 1561 ret = mif6_add(net, mrt, &vif,
1562 sk == rtnl_dereference(mrt->mroute_sk));
1710 rtnl_unlock(); 1563 rtnl_unlock();
1711 return ret; 1564 return ret;
1712 1565
@@ -1741,7 +1594,9 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, uns
1741 ret = ip6mr_mfc_delete(mrt, &mfc, parent); 1594 ret = ip6mr_mfc_delete(mrt, &mfc, parent);
1742 else 1595 else
1743 ret = ip6mr_mfc_add(net, mrt, &mfc, 1596 ret = ip6mr_mfc_add(net, mrt, &mfc,
1744 sk == mrt->mroute6_sk, parent); 1597 sk ==
1598 rtnl_dereference(mrt->mroute_sk),
1599 parent);
1745 rtnl_unlock(); 1600 rtnl_unlock();
1746 return ret; 1601 return ret;
1747 1602
@@ -1793,7 +1648,7 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, uns
1793 /* "pim6reg%u" should not exceed 16 bytes (IFNAMSIZ) */ 1648 /* "pim6reg%u" should not exceed 16 bytes (IFNAMSIZ) */
1794 if (v != RT_TABLE_DEFAULT && v >= 100000000) 1649 if (v != RT_TABLE_DEFAULT && v >= 100000000)
1795 return -EINVAL; 1650 return -EINVAL;
1796 if (sk == mrt->mroute6_sk) 1651 if (sk == rcu_access_pointer(mrt->mroute_sk))
1797 return -EBUSY; 1652 return -EBUSY;
1798 1653
1799 rtnl_lock(); 1654 rtnl_lock();
@@ -1824,7 +1679,7 @@ int ip6_mroute_getsockopt(struct sock *sk, int optname, char __user *optval,
1824 int olr; 1679 int olr;
1825 int val; 1680 int val;
1826 struct net *net = sock_net(sk); 1681 struct net *net = sock_net(sk);
1827 struct mr6_table *mrt; 1682 struct mr_table *mrt;
1828 1683
1829 if (sk->sk_type != SOCK_RAW || 1684 if (sk->sk_type != SOCK_RAW ||
1830 inet_sk(sk)->inet_num != IPPROTO_ICMPV6) 1685 inet_sk(sk)->inet_num != IPPROTO_ICMPV6)
@@ -1872,10 +1727,10 @@ int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg)
1872{ 1727{
1873 struct sioc_sg_req6 sr; 1728 struct sioc_sg_req6 sr;
1874 struct sioc_mif_req6 vr; 1729 struct sioc_mif_req6 vr;
1875 struct mif_device *vif; 1730 struct vif_device *vif;
1876 struct mfc6_cache *c; 1731 struct mfc6_cache *c;
1877 struct net *net = sock_net(sk); 1732 struct net *net = sock_net(sk);
1878 struct mr6_table *mrt; 1733 struct mr_table *mrt;
1879 1734
1880 mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT); 1735 mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT);
1881 if (!mrt) 1736 if (!mrt)
@@ -1888,8 +1743,8 @@ int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg)
1888 if (vr.mifi >= mrt->maxvif) 1743 if (vr.mifi >= mrt->maxvif)
1889 return -EINVAL; 1744 return -EINVAL;
1890 read_lock(&mrt_lock); 1745 read_lock(&mrt_lock);
1891 vif = &mrt->vif6_table[vr.mifi]; 1746 vif = &mrt->vif_table[vr.mifi];
1892 if (MIF_EXISTS(mrt, vr.mifi)) { 1747 if (VIF_EXISTS(mrt, vr.mifi)) {
1893 vr.icount = vif->pkt_in; 1748 vr.icount = vif->pkt_in;
1894 vr.ocount = vif->pkt_out; 1749 vr.ocount = vif->pkt_out;
1895 vr.ibytes = vif->bytes_in; 1750 vr.ibytes = vif->bytes_in;
@@ -1906,19 +1761,19 @@ int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg)
1906 if (copy_from_user(&sr, arg, sizeof(sr))) 1761 if (copy_from_user(&sr, arg, sizeof(sr)))
1907 return -EFAULT; 1762 return -EFAULT;
1908 1763
1909 read_lock(&mrt_lock); 1764 rcu_read_lock();
1910 c = ip6mr_cache_find(mrt, &sr.src.sin6_addr, &sr.grp.sin6_addr); 1765 c = ip6mr_cache_find(mrt, &sr.src.sin6_addr, &sr.grp.sin6_addr);
1911 if (c) { 1766 if (c) {
1912 sr.pktcnt = c->mfc_un.res.pkt; 1767 sr.pktcnt = c->_c.mfc_un.res.pkt;
1913 sr.bytecnt = c->mfc_un.res.bytes; 1768 sr.bytecnt = c->_c.mfc_un.res.bytes;
1914 sr.wrong_if = c->mfc_un.res.wrong_if; 1769 sr.wrong_if = c->_c.mfc_un.res.wrong_if;
1915 read_unlock(&mrt_lock); 1770 rcu_read_unlock();
1916 1771
1917 if (copy_to_user(arg, &sr, sizeof(sr))) 1772 if (copy_to_user(arg, &sr, sizeof(sr)))
1918 return -EFAULT; 1773 return -EFAULT;
1919 return 0; 1774 return 0;
1920 } 1775 }
1921 read_unlock(&mrt_lock); 1776 rcu_read_unlock();
1922 return -EADDRNOTAVAIL; 1777 return -EADDRNOTAVAIL;
1923 default: 1778 default:
1924 return -ENOIOCTLCMD; 1779 return -ENOIOCTLCMD;
@@ -1946,10 +1801,10 @@ int ip6mr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg)
1946{ 1801{
1947 struct compat_sioc_sg_req6 sr; 1802 struct compat_sioc_sg_req6 sr;
1948 struct compat_sioc_mif_req6 vr; 1803 struct compat_sioc_mif_req6 vr;
1949 struct mif_device *vif; 1804 struct vif_device *vif;
1950 struct mfc6_cache *c; 1805 struct mfc6_cache *c;
1951 struct net *net = sock_net(sk); 1806 struct net *net = sock_net(sk);
1952 struct mr6_table *mrt; 1807 struct mr_table *mrt;
1953 1808
1954 mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT); 1809 mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT);
1955 if (!mrt) 1810 if (!mrt)
@@ -1962,8 +1817,8 @@ int ip6mr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg)
1962 if (vr.mifi >= mrt->maxvif) 1817 if (vr.mifi >= mrt->maxvif)
1963 return -EINVAL; 1818 return -EINVAL;
1964 read_lock(&mrt_lock); 1819 read_lock(&mrt_lock);
1965 vif = &mrt->vif6_table[vr.mifi]; 1820 vif = &mrt->vif_table[vr.mifi];
1966 if (MIF_EXISTS(mrt, vr.mifi)) { 1821 if (VIF_EXISTS(mrt, vr.mifi)) {
1967 vr.icount = vif->pkt_in; 1822 vr.icount = vif->pkt_in;
1968 vr.ocount = vif->pkt_out; 1823 vr.ocount = vif->pkt_out;
1969 vr.ibytes = vif->bytes_in; 1824 vr.ibytes = vif->bytes_in;
@@ -1980,19 +1835,19 @@ int ip6mr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg)
1980 if (copy_from_user(&sr, arg, sizeof(sr))) 1835 if (copy_from_user(&sr, arg, sizeof(sr)))
1981 return -EFAULT; 1836 return -EFAULT;
1982 1837
1983 read_lock(&mrt_lock); 1838 rcu_read_lock();
1984 c = ip6mr_cache_find(mrt, &sr.src.sin6_addr, &sr.grp.sin6_addr); 1839 c = ip6mr_cache_find(mrt, &sr.src.sin6_addr, &sr.grp.sin6_addr);
1985 if (c) { 1840 if (c) {
1986 sr.pktcnt = c->mfc_un.res.pkt; 1841 sr.pktcnt = c->_c.mfc_un.res.pkt;
1987 sr.bytecnt = c->mfc_un.res.bytes; 1842 sr.bytecnt = c->_c.mfc_un.res.bytes;
1988 sr.wrong_if = c->mfc_un.res.wrong_if; 1843 sr.wrong_if = c->_c.mfc_un.res.wrong_if;
1989 read_unlock(&mrt_lock); 1844 rcu_read_unlock();
1990 1845
1991 if (copy_to_user(arg, &sr, sizeof(sr))) 1846 if (copy_to_user(arg, &sr, sizeof(sr)))
1992 return -EFAULT; 1847 return -EFAULT;
1993 return 0; 1848 return 0;
1994 } 1849 }
1995 read_unlock(&mrt_lock); 1850 rcu_read_unlock();
1996 return -EADDRNOTAVAIL; 1851 return -EADDRNOTAVAIL;
1997 default: 1852 default:
1998 return -ENOIOCTLCMD; 1853 return -ENOIOCTLCMD;
@@ -2013,11 +1868,11 @@ static inline int ip6mr_forward2_finish(struct net *net, struct sock *sk, struct
2013 * Processing handlers for ip6mr_forward 1868 * Processing handlers for ip6mr_forward
2014 */ 1869 */
2015 1870
2016static int ip6mr_forward2(struct net *net, struct mr6_table *mrt, 1871static int ip6mr_forward2(struct net *net, struct mr_table *mrt,
2017 struct sk_buff *skb, struct mfc6_cache *c, int vifi) 1872 struct sk_buff *skb, struct mfc6_cache *c, int vifi)
2018{ 1873{
2019 struct ipv6hdr *ipv6h; 1874 struct ipv6hdr *ipv6h;
2020 struct mif_device *vif = &mrt->vif6_table[vifi]; 1875 struct vif_device *vif = &mrt->vif_table[vifi];
2021 struct net_device *dev; 1876 struct net_device *dev;
2022 struct dst_entry *dst; 1877 struct dst_entry *dst;
2023 struct flowi6 fl6; 1878 struct flowi6 fl6;
@@ -2087,46 +1942,50 @@ out_free:
2087 return 0; 1942 return 0;
2088} 1943}
2089 1944
2090static int ip6mr_find_vif(struct mr6_table *mrt, struct net_device *dev) 1945static int ip6mr_find_vif(struct mr_table *mrt, struct net_device *dev)
2091{ 1946{
2092 int ct; 1947 int ct;
2093 1948
2094 for (ct = mrt->maxvif - 1; ct >= 0; ct--) { 1949 for (ct = mrt->maxvif - 1; ct >= 0; ct--) {
2095 if (mrt->vif6_table[ct].dev == dev) 1950 if (mrt->vif_table[ct].dev == dev)
2096 break; 1951 break;
2097 } 1952 }
2098 return ct; 1953 return ct;
2099} 1954}
2100 1955
2101static void ip6_mr_forward(struct net *net, struct mr6_table *mrt, 1956static void ip6_mr_forward(struct net *net, struct mr_table *mrt,
2102 struct sk_buff *skb, struct mfc6_cache *cache) 1957 struct sk_buff *skb, struct mfc6_cache *c)
2103{ 1958{
2104 int psend = -1; 1959 int psend = -1;
2105 int vif, ct; 1960 int vif, ct;
2106 int true_vifi = ip6mr_find_vif(mrt, skb->dev); 1961 int true_vifi = ip6mr_find_vif(mrt, skb->dev);
2107 1962
2108 vif = cache->mf6c_parent; 1963 vif = c->_c.mfc_parent;
2109 cache->mfc_un.res.pkt++; 1964 c->_c.mfc_un.res.pkt++;
2110 cache->mfc_un.res.bytes += skb->len; 1965 c->_c.mfc_un.res.bytes += skb->len;
2111 cache->mfc_un.res.lastuse = jiffies; 1966 c->_c.mfc_un.res.lastuse = jiffies;
2112 1967
2113 if (ipv6_addr_any(&cache->mf6c_origin) && true_vifi >= 0) { 1968 if (ipv6_addr_any(&c->mf6c_origin) && true_vifi >= 0) {
2114 struct mfc6_cache *cache_proxy; 1969 struct mfc6_cache *cache_proxy;
2115 1970
2116 /* For an (*,G) entry, we only check that the incoming 1971 /* For an (*,G) entry, we only check that the incoming
2117 * interface is part of the static tree. 1972 * interface is part of the static tree.
2118 */ 1973 */
2119 cache_proxy = ip6mr_cache_find_any_parent(mrt, vif); 1974 rcu_read_lock();
1975 cache_proxy = mr_mfc_find_any_parent(mrt, vif);
2120 if (cache_proxy && 1976 if (cache_proxy &&
2121 cache_proxy->mfc_un.res.ttls[true_vifi] < 255) 1977 cache_proxy->_c.mfc_un.res.ttls[true_vifi] < 255) {
1978 rcu_read_unlock();
2122 goto forward; 1979 goto forward;
1980 }
1981 rcu_read_unlock();
2123 } 1982 }
2124 1983
2125 /* 1984 /*
2126 * Wrong interface: drop packet and (maybe) send PIM assert. 1985 * Wrong interface: drop packet and (maybe) send PIM assert.
2127 */ 1986 */
2128 if (mrt->vif6_table[vif].dev != skb->dev) { 1987 if (mrt->vif_table[vif].dev != skb->dev) {
2129 cache->mfc_un.res.wrong_if++; 1988 c->_c.mfc_un.res.wrong_if++;
2130 1989
2131 if (true_vifi >= 0 && mrt->mroute_do_assert && 1990 if (true_vifi >= 0 && mrt->mroute_do_assert &&
2132 /* pimsm uses asserts, when switching from RPT to SPT, 1991 /* pimsm uses asserts, when switching from RPT to SPT,
@@ -2135,52 +1994,55 @@ static void ip6_mr_forward(struct net *net, struct mr6_table *mrt,
2135 large chunk of pimd to kernel. Ough... --ANK 1994 large chunk of pimd to kernel. Ough... --ANK
2136 */ 1995 */
2137 (mrt->mroute_do_pim || 1996 (mrt->mroute_do_pim ||
2138 cache->mfc_un.res.ttls[true_vifi] < 255) && 1997 c->_c.mfc_un.res.ttls[true_vifi] < 255) &&
2139 time_after(jiffies, 1998 time_after(jiffies,
2140 cache->mfc_un.res.last_assert + MFC_ASSERT_THRESH)) { 1999 c->_c.mfc_un.res.last_assert +
2141 cache->mfc_un.res.last_assert = jiffies; 2000 MFC_ASSERT_THRESH)) {
2001 c->_c.mfc_un.res.last_assert = jiffies;
2142 ip6mr_cache_report(mrt, skb, true_vifi, MRT6MSG_WRONGMIF); 2002 ip6mr_cache_report(mrt, skb, true_vifi, MRT6MSG_WRONGMIF);
2143 } 2003 }
2144 goto dont_forward; 2004 goto dont_forward;
2145 } 2005 }
2146 2006
2147forward: 2007forward:
2148 mrt->vif6_table[vif].pkt_in++; 2008 mrt->vif_table[vif].pkt_in++;
2149 mrt->vif6_table[vif].bytes_in += skb->len; 2009 mrt->vif_table[vif].bytes_in += skb->len;
2150 2010
2151 /* 2011 /*
2152 * Forward the frame 2012 * Forward the frame
2153 */ 2013 */
2154 if (ipv6_addr_any(&cache->mf6c_origin) && 2014 if (ipv6_addr_any(&c->mf6c_origin) &&
2155 ipv6_addr_any(&cache->mf6c_mcastgrp)) { 2015 ipv6_addr_any(&c->mf6c_mcastgrp)) {
2156 if (true_vifi >= 0 && 2016 if (true_vifi >= 0 &&
2157 true_vifi != cache->mf6c_parent && 2017 true_vifi != c->_c.mfc_parent &&
2158 ipv6_hdr(skb)->hop_limit > 2018 ipv6_hdr(skb)->hop_limit >
2159 cache->mfc_un.res.ttls[cache->mf6c_parent]) { 2019 c->_c.mfc_un.res.ttls[c->_c.mfc_parent]) {
2160 /* It's an (*,*) entry and the packet is not coming from 2020 /* It's an (*,*) entry and the packet is not coming from
2161 * the upstream: forward the packet to the upstream 2021 * the upstream: forward the packet to the upstream
2162 * only. 2022 * only.
2163 */ 2023 */
2164 psend = cache->mf6c_parent; 2024 psend = c->_c.mfc_parent;
2165 goto last_forward; 2025 goto last_forward;
2166 } 2026 }
2167 goto dont_forward; 2027 goto dont_forward;
2168 } 2028 }
2169 for (ct = cache->mfc_un.res.maxvif - 1; ct >= cache->mfc_un.res.minvif; ct--) { 2029 for (ct = c->_c.mfc_un.res.maxvif - 1;
2030 ct >= c->_c.mfc_un.res.minvif; ct--) {
2170 /* For (*,G) entry, don't forward to the incoming interface */ 2031 /* For (*,G) entry, don't forward to the incoming interface */
2171 if ((!ipv6_addr_any(&cache->mf6c_origin) || ct != true_vifi) && 2032 if ((!ipv6_addr_any(&c->mf6c_origin) || ct != true_vifi) &&
2172 ipv6_hdr(skb)->hop_limit > cache->mfc_un.res.ttls[ct]) { 2033 ipv6_hdr(skb)->hop_limit > c->_c.mfc_un.res.ttls[ct]) {
2173 if (psend != -1) { 2034 if (psend != -1) {
2174 struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); 2035 struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
2175 if (skb2) 2036 if (skb2)
2176 ip6mr_forward2(net, mrt, skb2, cache, psend); 2037 ip6mr_forward2(net, mrt, skb2,
2038 c, psend);
2177 } 2039 }
2178 psend = ct; 2040 psend = ct;
2179 } 2041 }
2180 } 2042 }
2181last_forward: 2043last_forward:
2182 if (psend != -1) { 2044 if (psend != -1) {
2183 ip6mr_forward2(net, mrt, skb, cache, psend); 2045 ip6mr_forward2(net, mrt, skb, c, psend);
2184 return; 2046 return;
2185 } 2047 }
2186 2048
@@ -2197,7 +2059,7 @@ int ip6_mr_input(struct sk_buff *skb)
2197{ 2059{
2198 struct mfc6_cache *cache; 2060 struct mfc6_cache *cache;
2199 struct net *net = dev_net(skb->dev); 2061 struct net *net = dev_net(skb->dev);
2200 struct mr6_table *mrt; 2062 struct mr_table *mrt;
2201 struct flowi6 fl6 = { 2063 struct flowi6 fl6 = {
2202 .flowi6_iif = skb->dev->ifindex, 2064 .flowi6_iif = skb->dev->ifindex,
2203 .flowi6_mark = skb->mark, 2065 .flowi6_mark = skb->mark,
@@ -2247,66 +2109,11 @@ int ip6_mr_input(struct sk_buff *skb)
2247 return 0; 2109 return 0;
2248} 2110}
2249 2111
2250
2251static int __ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb,
2252 struct mfc6_cache *c, struct rtmsg *rtm)
2253{
2254 struct rta_mfc_stats mfcs;
2255 struct nlattr *mp_attr;
2256 struct rtnexthop *nhp;
2257 unsigned long lastuse;
2258 int ct;
2259
2260 /* If cache is unresolved, don't try to parse IIF and OIF */
2261 if (c->mf6c_parent >= MAXMIFS) {
2262 rtm->rtm_flags |= RTNH_F_UNRESOLVED;
2263 return -ENOENT;
2264 }
2265
2266 if (MIF_EXISTS(mrt, c->mf6c_parent) &&
2267 nla_put_u32(skb, RTA_IIF, mrt->vif6_table[c->mf6c_parent].dev->ifindex) < 0)
2268 return -EMSGSIZE;
2269 mp_attr = nla_nest_start(skb, RTA_MULTIPATH);
2270 if (!mp_attr)
2271 return -EMSGSIZE;
2272
2273 for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) {
2274 if (MIF_EXISTS(mrt, ct) && c->mfc_un.res.ttls[ct] < 255) {
2275 nhp = nla_reserve_nohdr(skb, sizeof(*nhp));
2276 if (!nhp) {
2277 nla_nest_cancel(skb, mp_attr);
2278 return -EMSGSIZE;
2279 }
2280
2281 nhp->rtnh_flags = 0;
2282 nhp->rtnh_hops = c->mfc_un.res.ttls[ct];
2283 nhp->rtnh_ifindex = mrt->vif6_table[ct].dev->ifindex;
2284 nhp->rtnh_len = sizeof(*nhp);
2285 }
2286 }
2287
2288 nla_nest_end(skb, mp_attr);
2289
2290 lastuse = READ_ONCE(c->mfc_un.res.lastuse);
2291 lastuse = time_after_eq(jiffies, lastuse) ? jiffies - lastuse : 0;
2292
2293 mfcs.mfcs_packets = c->mfc_un.res.pkt;
2294 mfcs.mfcs_bytes = c->mfc_un.res.bytes;
2295 mfcs.mfcs_wrong_if = c->mfc_un.res.wrong_if;
2296 if (nla_put_64bit(skb, RTA_MFC_STATS, sizeof(mfcs), &mfcs, RTA_PAD) ||
2297 nla_put_u64_64bit(skb, RTA_EXPIRES, jiffies_to_clock_t(lastuse),
2298 RTA_PAD))
2299 return -EMSGSIZE;
2300
2301 rtm->rtm_type = RTN_MULTICAST;
2302 return 1;
2303}
2304
2305int ip6mr_get_route(struct net *net, struct sk_buff *skb, struct rtmsg *rtm, 2112int ip6mr_get_route(struct net *net, struct sk_buff *skb, struct rtmsg *rtm,
2306 u32 portid) 2113 u32 portid)
2307{ 2114{
2308 int err; 2115 int err;
2309 struct mr6_table *mrt; 2116 struct mr_table *mrt;
2310 struct mfc6_cache *cache; 2117 struct mfc6_cache *cache;
2311 struct rt6_info *rt = (struct rt6_info *)skb_dst(skb); 2118 struct rt6_info *rt = (struct rt6_info *)skb_dst(skb);
2312 2119
@@ -2367,15 +2174,12 @@ int ip6mr_get_route(struct net *net, struct sk_buff *skb, struct rtmsg *rtm,
2367 return err; 2174 return err;
2368 } 2175 }
2369 2176
2370 if (rtm->rtm_flags & RTM_F_NOTIFY) 2177 err = mr_fill_mroute(mrt, skb, &cache->_c, rtm);
2371 cache->mfc_flags |= MFC_NOTIFY;
2372
2373 err = __ip6mr_fill_mroute(mrt, skb, cache, rtm);
2374 read_unlock(&mrt_lock); 2178 read_unlock(&mrt_lock);
2375 return err; 2179 return err;
2376} 2180}
2377 2181
2378static int ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb, 2182static int ip6mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
2379 u32 portid, u32 seq, struct mfc6_cache *c, int cmd, 2183 u32 portid, u32 seq, struct mfc6_cache *c, int cmd,
2380 int flags) 2184 int flags)
2381{ 2185{
@@ -2397,7 +2201,7 @@ static int ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb,
2397 goto nla_put_failure; 2201 goto nla_put_failure;
2398 rtm->rtm_type = RTN_MULTICAST; 2202 rtm->rtm_type = RTN_MULTICAST;
2399 rtm->rtm_scope = RT_SCOPE_UNIVERSE; 2203 rtm->rtm_scope = RT_SCOPE_UNIVERSE;
2400 if (c->mfc_flags & MFC_STATIC) 2204 if (c->_c.mfc_flags & MFC_STATIC)
2401 rtm->rtm_protocol = RTPROT_STATIC; 2205 rtm->rtm_protocol = RTPROT_STATIC;
2402 else 2206 else
2403 rtm->rtm_protocol = RTPROT_MROUTED; 2207 rtm->rtm_protocol = RTPROT_MROUTED;
@@ -2406,7 +2210,7 @@ static int ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb,
2406 if (nla_put_in6_addr(skb, RTA_SRC, &c->mf6c_origin) || 2210 if (nla_put_in6_addr(skb, RTA_SRC, &c->mf6c_origin) ||
2407 nla_put_in6_addr(skb, RTA_DST, &c->mf6c_mcastgrp)) 2211 nla_put_in6_addr(skb, RTA_DST, &c->mf6c_mcastgrp))
2408 goto nla_put_failure; 2212 goto nla_put_failure;
2409 err = __ip6mr_fill_mroute(mrt, skb, c, rtm); 2213 err = mr_fill_mroute(mrt, skb, &c->_c, rtm);
2410 /* do not break the dump if cache is unresolved */ 2214 /* do not break the dump if cache is unresolved */
2411 if (err < 0 && err != -ENOENT) 2215 if (err < 0 && err != -ENOENT)
2412 goto nla_put_failure; 2216 goto nla_put_failure;
@@ -2419,6 +2223,14 @@ nla_put_failure:
2419 return -EMSGSIZE; 2223 return -EMSGSIZE;
2420} 2224}
2421 2225
2226static int _ip6mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
2227 u32 portid, u32 seq, struct mr_mfc *c,
2228 int cmd, int flags)
2229{
2230 return ip6mr_fill_mroute(mrt, skb, portid, seq, (struct mfc6_cache *)c,
2231 cmd, flags);
2232}
2233
2422static int mr6_msgsize(bool unresolved, int maxvif) 2234static int mr6_msgsize(bool unresolved, int maxvif)
2423{ 2235{
2424 size_t len = 2236 size_t len =
@@ -2440,14 +2252,14 @@ static int mr6_msgsize(bool unresolved, int maxvif)
2440 return len; 2252 return len;
2441} 2253}
2442 2254
2443static void mr6_netlink_event(struct mr6_table *mrt, struct mfc6_cache *mfc, 2255static void mr6_netlink_event(struct mr_table *mrt, struct mfc6_cache *mfc,
2444 int cmd) 2256 int cmd)
2445{ 2257{
2446 struct net *net = read_pnet(&mrt->net); 2258 struct net *net = read_pnet(&mrt->net);
2447 struct sk_buff *skb; 2259 struct sk_buff *skb;
2448 int err = -ENOBUFS; 2260 int err = -ENOBUFS;
2449 2261
2450 skb = nlmsg_new(mr6_msgsize(mfc->mf6c_parent >= MAXMIFS, mrt->maxvif), 2262 skb = nlmsg_new(mr6_msgsize(mfc->_c.mfc_parent >= MAXMIFS, mrt->maxvif),
2451 GFP_ATOMIC); 2263 GFP_ATOMIC);
2452 if (!skb) 2264 if (!skb)
2453 goto errout; 2265 goto errout;
@@ -2482,7 +2294,7 @@ static size_t mrt6msg_netlink_msgsize(size_t payloadlen)
2482 return len; 2294 return len;
2483} 2295}
2484 2296
2485static void mrt6msg_netlink_event(struct mr6_table *mrt, struct sk_buff *pkt) 2297static void mrt6msg_netlink_event(struct mr_table *mrt, struct sk_buff *pkt)
2486{ 2298{
2487 struct net *net = read_pnet(&mrt->net); 2299 struct net *net = read_pnet(&mrt->net);
2488 struct nlmsghdr *nlh; 2300 struct nlmsghdr *nlh;
@@ -2532,65 +2344,6 @@ errout:
2532 2344
2533static int ip6mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb) 2345static int ip6mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb)
2534{ 2346{
2535 struct net *net = sock_net(skb->sk); 2347 return mr_rtm_dumproute(skb, cb, ip6mr_mr_table_iter,
2536 struct mr6_table *mrt; 2348 _ip6mr_fill_mroute, &mfc_unres_lock);
2537 struct mfc6_cache *mfc;
2538 unsigned int t = 0, s_t;
2539 unsigned int h = 0, s_h;
2540 unsigned int e = 0, s_e;
2541
2542 s_t = cb->args[0];
2543 s_h = cb->args[1];
2544 s_e = cb->args[2];
2545
2546 read_lock(&mrt_lock);
2547 ip6mr_for_each_table(mrt, net) {
2548 if (t < s_t)
2549 goto next_table;
2550 if (t > s_t)
2551 s_h = 0;
2552 for (h = s_h; h < MFC6_LINES; h++) {
2553 list_for_each_entry(mfc, &mrt->mfc6_cache_array[h], list) {
2554 if (e < s_e)
2555 goto next_entry;
2556 if (ip6mr_fill_mroute(mrt, skb,
2557 NETLINK_CB(cb->skb).portid,
2558 cb->nlh->nlmsg_seq,
2559 mfc, RTM_NEWROUTE,
2560 NLM_F_MULTI) < 0)
2561 goto done;
2562next_entry:
2563 e++;
2564 }
2565 e = s_e = 0;
2566 }
2567 spin_lock_bh(&mfc_unres_lock);
2568 list_for_each_entry(mfc, &mrt->mfc6_unres_queue, list) {
2569 if (e < s_e)
2570 goto next_entry2;
2571 if (ip6mr_fill_mroute(mrt, skb,
2572 NETLINK_CB(cb->skb).portid,
2573 cb->nlh->nlmsg_seq,
2574 mfc, RTM_NEWROUTE,
2575 NLM_F_MULTI) < 0) {
2576 spin_unlock_bh(&mfc_unres_lock);
2577 goto done;
2578 }
2579next_entry2:
2580 e++;
2581 }
2582 spin_unlock_bh(&mfc_unres_lock);
2583 e = s_e = 0;
2584 s_h = 0;
2585next_table:
2586 t++;
2587 }
2588done:
2589 read_unlock(&mrt_lock);
2590
2591 cb->args[2] = e;
2592 cb->args[1] = h;
2593 cb->args[0] = t;
2594
2595 return skb->len;
2596} 2349}
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 24535169663d..4d780c7f0130 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -1415,4 +1415,3 @@ int compat_ipv6_getsockopt(struct sock *sk, int level, int optname,
1415} 1415}
1416EXPORT_SYMBOL(compat_ipv6_getsockopt); 1416EXPORT_SYMBOL(compat_ipv6_getsockopt);
1417#endif 1417#endif
1418
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 9b9d2ff01b35..d1a0cefac273 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -165,7 +165,7 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
165 165
166 if (ifindex == 0) { 166 if (ifindex == 0) {
167 struct rt6_info *rt; 167 struct rt6_info *rt;
168 rt = rt6_lookup(net, addr, NULL, 0, 0); 168 rt = rt6_lookup(net, addr, NULL, 0, NULL, 0);
169 if (rt) { 169 if (rt) {
170 dev = rt->dst.dev; 170 dev = rt->dst.dev;
171 ip6_rt_put(rt); 171 ip6_rt_put(rt);
@@ -254,7 +254,7 @@ static struct inet6_dev *ip6_mc_find_dev_rcu(struct net *net,
254 struct inet6_dev *idev = NULL; 254 struct inet6_dev *idev = NULL;
255 255
256 if (ifindex == 0) { 256 if (ifindex == 0) {
257 struct rt6_info *rt = rt6_lookup(net, group, NULL, 0, 0); 257 struct rt6_info *rt = rt6_lookup(net, group, NULL, 0, NULL, 0);
258 258
259 if (rt) { 259 if (rt) {
260 dev = rt->dst.dev; 260 dev = rt->dst.dev;
@@ -2997,6 +2997,7 @@ static void __net_exit igmp6_net_exit(struct net *net)
2997static struct pernet_operations igmp6_net_ops = { 2997static struct pernet_operations igmp6_net_ops = {
2998 .init = igmp6_net_init, 2998 .init = igmp6_net_init,
2999 .exit = igmp6_net_exit, 2999 .exit = igmp6_net_exit,
3000 .async = true,
3000}; 3001};
3001 3002
3002int __init igmp6_init(void) 3003int __init igmp6_init(void)
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index ba5e04c6ae17..d1d0b2fa7a07 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -527,7 +527,7 @@ void ndisc_send_na(struct net_device *dev, const struct in6_addr *daddr,
527 } 527 }
528 528
529 if (!dev->addr_len) 529 if (!dev->addr_len)
530 inc_opt = 0; 530 inc_opt = false;
531 if (inc_opt) 531 if (inc_opt)
532 optlen += ndisc_opt_addr_space(dev, 532 optlen += ndisc_opt_addr_space(dev,
533 NDISC_NEIGHBOUR_ADVERTISEMENT); 533 NDISC_NEIGHBOUR_ADVERTISEMENT);
@@ -707,7 +707,7 @@ static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb)
707 int probes = atomic_read(&neigh->probes); 707 int probes = atomic_read(&neigh->probes);
708 708
709 if (skb && ipv6_chk_addr_and_flags(dev_net(dev), &ipv6_hdr(skb)->saddr, 709 if (skb && ipv6_chk_addr_and_flags(dev_net(dev), &ipv6_hdr(skb)->saddr,
710 dev, 1, 710 dev, false, 1,
711 IFA_F_TENTATIVE|IFA_F_OPTIMISTIC)) 711 IFA_F_TENTATIVE|IFA_F_OPTIMISTIC))
712 saddr = &ipv6_hdr(skb)->saddr; 712 saddr = &ipv6_hdr(skb)->saddr;
713 probes -= NEIGH_VAR(neigh->parms, UCAST_PROBES); 713 probes -= NEIGH_VAR(neigh->parms, UCAST_PROBES);
@@ -1883,6 +1883,7 @@ static void __net_exit ndisc_net_exit(struct net *net)
1883static struct pernet_operations ndisc_net_ops = { 1883static struct pernet_operations ndisc_net_ops = {
1884 .init = ndisc_net_init, 1884 .init = ndisc_net_init,
1885 .exit = ndisc_net_exit, 1885 .exit = ndisc_net_exit,
1886 .async = true,
1886}; 1887};
1887 1888
1888int __init ndisc_init(void) 1889int __init ndisc_init(void)
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 62358b93bbac..4de8ac1e5af4 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -1928,6 +1928,7 @@ static void __net_exit ip6_tables_net_exit(struct net *net)
1928static struct pernet_operations ip6_tables_net_ops = { 1928static struct pernet_operations ip6_tables_net_ops = {
1929 .init = ip6_tables_net_init, 1929 .init = ip6_tables_net_init,
1930 .exit = ip6_tables_net_exit, 1930 .exit = ip6_tables_net_exit,
1931 .async = true,
1931}; 1932};
1932 1933
1933static int __init ip6_tables_init(void) 1934static int __init ip6_tables_init(void)
diff --git a/net/ipv6/netfilter/ip6t_rpfilter.c b/net/ipv6/netfilter/ip6t_rpfilter.c
index 91ed25a24b79..d12f511929f5 100644
--- a/net/ipv6/netfilter/ip6t_rpfilter.c
+++ b/net/ipv6/netfilter/ip6t_rpfilter.c
@@ -49,7 +49,7 @@ static bool rpfilter_lookup_reverse6(struct net *net, const struct sk_buff *skb,
49 49
50 fl6.flowi6_mark = flags & XT_RPFILTER_VALID_MARK ? skb->mark : 0; 50 fl6.flowi6_mark = flags & XT_RPFILTER_VALID_MARK ? skb->mark : 0;
51 51
52 rt = (void *) ip6_route_lookup(net, &fl6, lookup_flags); 52 rt = (void *)ip6_route_lookup(net, &fl6, skb, lookup_flags);
53 if (rt->dst.error) 53 if (rt->dst.error)
54 goto out; 54 goto out;
55 55
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
index 1343077dde93..06561c84c0bc 100644
--- a/net/ipv6/netfilter/ip6table_filter.c
+++ b/net/ipv6/netfilter/ip6table_filter.c
@@ -87,6 +87,7 @@ static void __net_exit ip6table_filter_net_exit(struct net *net)
87static struct pernet_operations ip6table_filter_net_ops = { 87static struct pernet_operations ip6table_filter_net_ops = {
88 .init = ip6table_filter_net_init, 88 .init = ip6table_filter_net_init,
89 .exit = ip6table_filter_net_exit, 89 .exit = ip6table_filter_net_exit,
90 .async = true,
90}; 91};
91 92
92static int __init ip6table_filter_init(void) 93static int __init ip6table_filter_init(void)
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
index b0524b18c4fb..a11e25936b45 100644
--- a/net/ipv6/netfilter/ip6table_mangle.c
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -107,6 +107,7 @@ static void __net_exit ip6table_mangle_net_exit(struct net *net)
107 107
108static struct pernet_operations ip6table_mangle_net_ops = { 108static struct pernet_operations ip6table_mangle_net_ops = {
109 .exit = ip6table_mangle_net_exit, 109 .exit = ip6table_mangle_net_exit,
110 .async = true,
110}; 111};
111 112
112static int __init ip6table_mangle_init(void) 113static int __init ip6table_mangle_init(void)
diff --git a/net/ipv6/netfilter/ip6table_nat.c b/net/ipv6/netfilter/ip6table_nat.c
index 47306e45a80a..4475fd300bb6 100644
--- a/net/ipv6/netfilter/ip6table_nat.c
+++ b/net/ipv6/netfilter/ip6table_nat.c
@@ -131,6 +131,7 @@ static void __net_exit ip6table_nat_net_exit(struct net *net)
131 131
132static struct pernet_operations ip6table_nat_net_ops = { 132static struct pernet_operations ip6table_nat_net_ops = {
133 .exit = ip6table_nat_net_exit, 133 .exit = ip6table_nat_net_exit,
134 .async = true,
134}; 135};
135 136
136static int __init ip6table_nat_init(void) 137static int __init ip6table_nat_init(void)
diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c
index 710fa0806c37..a88f3b1995b1 100644
--- a/net/ipv6/netfilter/ip6table_raw.c
+++ b/net/ipv6/netfilter/ip6table_raw.c
@@ -75,6 +75,7 @@ static void __net_exit ip6table_raw_net_exit(struct net *net)
75 75
76static struct pernet_operations ip6table_raw_net_ops = { 76static struct pernet_operations ip6table_raw_net_ops = {
77 .exit = ip6table_raw_net_exit, 77 .exit = ip6table_raw_net_exit,
78 .async = true,
78}; 79};
79 80
80static int __init ip6table_raw_init(void) 81static int __init ip6table_raw_init(void)
diff --git a/net/ipv6/netfilter/ip6table_security.c b/net/ipv6/netfilter/ip6table_security.c
index cf26ccb04056..320048c008dc 100644
--- a/net/ipv6/netfilter/ip6table_security.c
+++ b/net/ipv6/netfilter/ip6table_security.c
@@ -74,6 +74,7 @@ static void __net_exit ip6table_security_net_exit(struct net *net)
74 74
75static struct pernet_operations ip6table_security_net_ops = { 75static struct pernet_operations ip6table_security_net_ops = {
76 .exit = ip6table_security_net_exit, 76 .exit = ip6table_security_net_exit,
77 .async = true,
77}; 78};
78 79
79static int __init ip6table_security_init(void) 80static int __init ip6table_security_init(void)
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 663827ee3cf8..ba54bb3bd1e4 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -401,6 +401,7 @@ static struct pernet_operations ipv6_net_ops = {
401 .exit = ipv6_net_exit, 401 .exit = ipv6_net_exit,
402 .id = &conntrack6_net_id, 402 .id = &conntrack6_net_id,
403 .size = sizeof(struct conntrack6_net), 403 .size = sizeof(struct conntrack6_net),
404 .async = true,
404}; 405};
405 406
406static int __init nf_conntrack_l3proto_ipv6_init(void) 407static int __init nf_conntrack_l3proto_ipv6_init(void)
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index b84ce3e6d728..34136fe80ed5 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -646,6 +646,7 @@ static void nf_ct_net_exit(struct net *net)
646static struct pernet_operations nf_ct_net_ops = { 646static struct pernet_operations nf_ct_net_ops = {
647 .init = nf_ct_net_init, 647 .init = nf_ct_net_init,
648 .exit = nf_ct_net_exit, 648 .exit = nf_ct_net_exit,
649 .async = true,
649}; 650};
650 651
651int nf_ct_frag6_init(void) 652int nf_ct_frag6_init(void)
diff --git a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
index c87b48359e8f..32f98bc06900 100644
--- a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
+++ b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
@@ -103,6 +103,7 @@ static void __net_exit defrag6_net_exit(struct net *net)
103 103
104static struct pernet_operations defrag6_net_ops = { 104static struct pernet_operations defrag6_net_ops = {
105 .exit = defrag6_net_exit, 105 .exit = defrag6_net_exit,
106 .async = true,
106}; 107};
107 108
108static int __init nf_defrag_init(void) 109static int __init nf_defrag_init(void)
diff --git a/net/ipv6/netfilter/nf_log_ipv6.c b/net/ipv6/netfilter/nf_log_ipv6.c
index b397a8fe88b9..0220e584589c 100644
--- a/net/ipv6/netfilter/nf_log_ipv6.c
+++ b/net/ipv6/netfilter/nf_log_ipv6.c
@@ -390,6 +390,7 @@ static void __net_exit nf_log_ipv6_net_exit(struct net *net)
390static struct pernet_operations nf_log_ipv6_net_ops = { 390static struct pernet_operations nf_log_ipv6_net_ops = {
391 .init = nf_log_ipv6_net_init, 391 .init = nf_log_ipv6_net_init,
392 .exit = nf_log_ipv6_net_exit, 392 .exit = nf_log_ipv6_net_exit,
393 .async = true,
393}; 394};
394 395
395static int __init nf_log_ipv6_init(void) 396static int __init nf_log_ipv6_init(void)
diff --git a/net/ipv6/netfilter/nft_fib_ipv6.c b/net/ipv6/netfilter/nft_fib_ipv6.c
index 62fc84d7bdff..36be3cf0adef 100644
--- a/net/ipv6/netfilter/nft_fib_ipv6.c
+++ b/net/ipv6/netfilter/nft_fib_ipv6.c
@@ -180,7 +180,8 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs,
180 } 180 }
181 181
182 *dest = 0; 182 *dest = 0;
183 rt = (void *)ip6_route_lookup(nft_net(pkt), &fl6, lookup_flags); 183 rt = (void *)ip6_route_lookup(nft_net(pkt), &fl6, pkt->skb,
184 lookup_flags);
184 if (rt->dst.error) 185 if (rt->dst.error)
185 goto put_rt_err; 186 goto put_rt_err;
186 187
diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c
index d12c55dad7d1..318c6e914234 100644
--- a/net/ipv6/ping.c
+++ b/net/ipv6/ping.c
@@ -240,6 +240,7 @@ static void __net_init ping_v6_proc_exit_net(struct net *net)
240static struct pernet_operations ping_v6_net_ops = { 240static struct pernet_operations ping_v6_net_ops = {
241 .init = ping_v6_proc_init_net, 241 .init = ping_v6_proc_init_net,
242 .exit = ping_v6_proc_exit_net, 242 .exit = ping_v6_proc_exit_net,
243 .async = true,
243}; 244};
244#endif 245#endif
245 246
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index b67814242f78..1678cf037688 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -343,6 +343,7 @@ static void __net_exit ipv6_proc_exit_net(struct net *net)
343static struct pernet_operations ipv6_proc_ops = { 343static struct pernet_operations ipv6_proc_ops = {
344 .init = ipv6_proc_init_net, 344 .init = ipv6_proc_init_net,
345 .exit = ipv6_proc_exit_net, 345 .exit = ipv6_proc_exit_net,
346 .async = true,
346}; 347};
347 348
348int __init ipv6_misc_proc_init(void) 349int __init ipv6_misc_proc_init(void)
@@ -354,4 +355,3 @@ void ipv6_misc_proc_exit(void)
354{ 355{
355 unregister_pernet_subsys(&ipv6_proc_ops); 356 unregister_pernet_subsys(&ipv6_proc_ops);
356} 357}
357
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 4c25339b1984..10a4ac4933b7 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -1332,6 +1332,7 @@ static void __net_exit raw6_exit_net(struct net *net)
1332static struct pernet_operations raw6_net_ops = { 1332static struct pernet_operations raw6_net_ops = {
1333 .init = raw6_init_net, 1333 .init = raw6_init_net,
1334 .exit = raw6_exit_net, 1334 .exit = raw6_exit_net,
1335 .async = true,
1335}; 1336};
1336 1337
1337int __init raw6_proc_init(void) 1338int __init raw6_proc_init(void)
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index afbc000ad4f2..b5da69c83123 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -733,6 +733,7 @@ static void __net_exit ipv6_frags_exit_net(struct net *net)
733static struct pernet_operations ip6_frags_ops = { 733static struct pernet_operations ip6_frags_ops = {
734 .init = ipv6_frags_init_net, 734 .init = ipv6_frags_init_net,
735 .exit = ipv6_frags_exit_net, 735 .exit = ipv6_frags_exit_net,
736 .async = true,
736}; 737};
737 738
738int __init ipv6_frag_init(void) 739int __init ipv6_frag_init(void)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index b0d5c64e1978..a2ed9fdd58d4 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -450,8 +450,10 @@ static bool rt6_check_expired(const struct rt6_info *rt)
450 return false; 450 return false;
451} 451}
452 452
453static struct rt6_info *rt6_multipath_select(struct rt6_info *match, 453static struct rt6_info *rt6_multipath_select(const struct net *net,
454 struct rt6_info *match,
454 struct flowi6 *fl6, int oif, 455 struct flowi6 *fl6, int oif,
456 const struct sk_buff *skb,
455 int strict) 457 int strict)
456{ 458{
457 struct rt6_info *sibling, *next_sibling; 459 struct rt6_info *sibling, *next_sibling;
@@ -460,7 +462,7 @@ static struct rt6_info *rt6_multipath_select(struct rt6_info *match,
460 * case it will always be non-zero. Otherwise now is the time to do it. 462 * case it will always be non-zero. Otherwise now is the time to do it.
461 */ 463 */
462 if (!fl6->mp_hash) 464 if (!fl6->mp_hash)
463 fl6->mp_hash = rt6_multipath_hash(fl6, NULL); 465 fl6->mp_hash = rt6_multipath_hash(net, fl6, skb, NULL);
464 466
465 if (fl6->mp_hash <= atomic_read(&match->rt6i_nh_upper_bound)) 467 if (fl6->mp_hash <= atomic_read(&match->rt6i_nh_upper_bound))
466 return match; 468 return match;
@@ -914,7 +916,9 @@ static bool ip6_hold_safe(struct net *net, struct rt6_info **prt,
914 916
915static struct rt6_info *ip6_pol_route_lookup(struct net *net, 917static struct rt6_info *ip6_pol_route_lookup(struct net *net,
916 struct fib6_table *table, 918 struct fib6_table *table,
917 struct flowi6 *fl6, int flags) 919 struct flowi6 *fl6,
920 const struct sk_buff *skb,
921 int flags)
918{ 922{
919 struct rt6_info *rt, *rt_cache; 923 struct rt6_info *rt, *rt_cache;
920 struct fib6_node *fn; 924 struct fib6_node *fn;
@@ -929,8 +933,8 @@ restart:
929 rt = rt6_device_match(net, rt, &fl6->saddr, 933 rt = rt6_device_match(net, rt, &fl6->saddr,
930 fl6->flowi6_oif, flags); 934 fl6->flowi6_oif, flags);
931 if (rt->rt6i_nsiblings && fl6->flowi6_oif == 0) 935 if (rt->rt6i_nsiblings && fl6->flowi6_oif == 0)
932 rt = rt6_multipath_select(rt, fl6, 936 rt = rt6_multipath_select(net, rt, fl6, fl6->flowi6_oif,
933 fl6->flowi6_oif, flags); 937 skb, flags);
934 } 938 }
935 if (rt == net->ipv6.ip6_null_entry) { 939 if (rt == net->ipv6.ip6_null_entry) {
936 fn = fib6_backtrack(fn, &fl6->saddr); 940 fn = fib6_backtrack(fn, &fl6->saddr);
@@ -954,14 +958,15 @@ restart:
954} 958}
955 959
956struct dst_entry *ip6_route_lookup(struct net *net, struct flowi6 *fl6, 960struct dst_entry *ip6_route_lookup(struct net *net, struct flowi6 *fl6,
957 int flags) 961 const struct sk_buff *skb, int flags)
958{ 962{
959 return fib6_rule_lookup(net, fl6, flags, ip6_pol_route_lookup); 963 return fib6_rule_lookup(net, fl6, skb, flags, ip6_pol_route_lookup);
960} 964}
961EXPORT_SYMBOL_GPL(ip6_route_lookup); 965EXPORT_SYMBOL_GPL(ip6_route_lookup);
962 966
963struct rt6_info *rt6_lookup(struct net *net, const struct in6_addr *daddr, 967struct rt6_info *rt6_lookup(struct net *net, const struct in6_addr *daddr,
964 const struct in6_addr *saddr, int oif, int strict) 968 const struct in6_addr *saddr, int oif,
969 const struct sk_buff *skb, int strict)
965{ 970{
966 struct flowi6 fl6 = { 971 struct flowi6 fl6 = {
967 .flowi6_oif = oif, 972 .flowi6_oif = oif,
@@ -975,7 +980,7 @@ struct rt6_info *rt6_lookup(struct net *net, const struct in6_addr *daddr,
975 flags |= RT6_LOOKUP_F_HAS_SADDR; 980 flags |= RT6_LOOKUP_F_HAS_SADDR;
976 } 981 }
977 982
978 dst = fib6_rule_lookup(net, &fl6, flags, ip6_pol_route_lookup); 983 dst = fib6_rule_lookup(net, &fl6, skb, flags, ip6_pol_route_lookup);
979 if (dst->error == 0) 984 if (dst->error == 0)
980 return (struct rt6_info *) dst; 985 return (struct rt6_info *) dst;
981 986
@@ -1672,7 +1677,8 @@ void rt6_age_exceptions(struct rt6_info *rt,
1672} 1677}
1673 1678
1674struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table, 1679struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table,
1675 int oif, struct flowi6 *fl6, int flags) 1680 int oif, struct flowi6 *fl6,
1681 const struct sk_buff *skb, int flags)
1676{ 1682{
1677 struct fib6_node *fn, *saved_fn; 1683 struct fib6_node *fn, *saved_fn;
1678 struct rt6_info *rt, *rt_cache; 1684 struct rt6_info *rt, *rt_cache;
@@ -1694,7 +1700,7 @@ struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table,
1694redo_rt6_select: 1700redo_rt6_select:
1695 rt = rt6_select(net, fn, oif, strict); 1701 rt = rt6_select(net, fn, oif, strict);
1696 if (rt->rt6i_nsiblings) 1702 if (rt->rt6i_nsiblings)
1697 rt = rt6_multipath_select(rt, fl6, oif, strict); 1703 rt = rt6_multipath_select(net, rt, fl6, oif, skb, strict);
1698 if (rt == net->ipv6.ip6_null_entry) { 1704 if (rt == net->ipv6.ip6_null_entry) {
1699 fn = fib6_backtrack(fn, &fl6->saddr); 1705 fn = fib6_backtrack(fn, &fl6->saddr);
1700 if (fn) 1706 if (fn)
@@ -1793,28 +1799,35 @@ uncached_rt_out:
1793} 1799}
1794EXPORT_SYMBOL_GPL(ip6_pol_route); 1800EXPORT_SYMBOL_GPL(ip6_pol_route);
1795 1801
1796static struct rt6_info *ip6_pol_route_input(struct net *net, struct fib6_table *table, 1802static struct rt6_info *ip6_pol_route_input(struct net *net,
1797 struct flowi6 *fl6, int flags) 1803 struct fib6_table *table,
1804 struct flowi6 *fl6,
1805 const struct sk_buff *skb,
1806 int flags)
1798{ 1807{
1799 return ip6_pol_route(net, table, fl6->flowi6_iif, fl6, flags); 1808 return ip6_pol_route(net, table, fl6->flowi6_iif, fl6, skb, flags);
1800} 1809}
1801 1810
1802struct dst_entry *ip6_route_input_lookup(struct net *net, 1811struct dst_entry *ip6_route_input_lookup(struct net *net,
1803 struct net_device *dev, 1812 struct net_device *dev,
1804 struct flowi6 *fl6, int flags) 1813 struct flowi6 *fl6,
1814 const struct sk_buff *skb,
1815 int flags)
1805{ 1816{
1806 if (rt6_need_strict(&fl6->daddr) && dev->type != ARPHRD_PIMREG) 1817 if (rt6_need_strict(&fl6->daddr) && dev->type != ARPHRD_PIMREG)
1807 flags |= RT6_LOOKUP_F_IFACE; 1818 flags |= RT6_LOOKUP_F_IFACE;
1808 1819
1809 return fib6_rule_lookup(net, fl6, flags, ip6_pol_route_input); 1820 return fib6_rule_lookup(net, fl6, skb, flags, ip6_pol_route_input);
1810} 1821}
1811EXPORT_SYMBOL_GPL(ip6_route_input_lookup); 1822EXPORT_SYMBOL_GPL(ip6_route_input_lookup);
1812 1823
1813static void ip6_multipath_l3_keys(const struct sk_buff *skb, 1824static void ip6_multipath_l3_keys(const struct sk_buff *skb,
1814 struct flow_keys *keys) 1825 struct flow_keys *keys,
1826 struct flow_keys *flkeys)
1815{ 1827{
1816 const struct ipv6hdr *outer_iph = ipv6_hdr(skb); 1828 const struct ipv6hdr *outer_iph = ipv6_hdr(skb);
1817 const struct ipv6hdr *key_iph = outer_iph; 1829 const struct ipv6hdr *key_iph = outer_iph;
1830 struct flow_keys *_flkeys = flkeys;
1818 const struct ipv6hdr *inner_iph; 1831 const struct ipv6hdr *inner_iph;
1819 const struct icmp6hdr *icmph; 1832 const struct icmp6hdr *icmph;
1820 struct ipv6hdr _inner_iph; 1833 struct ipv6hdr _inner_iph;
@@ -1836,26 +1849,76 @@ static void ip6_multipath_l3_keys(const struct sk_buff *skb,
1836 goto out; 1849 goto out;
1837 1850
1838 key_iph = inner_iph; 1851 key_iph = inner_iph;
1852 _flkeys = NULL;
1839out: 1853out:
1840 memset(keys, 0, sizeof(*keys)); 1854 if (_flkeys) {
1841 keys->control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS; 1855 keys->addrs.v6addrs.src = _flkeys->addrs.v6addrs.src;
1842 keys->addrs.v6addrs.src = key_iph->saddr; 1856 keys->addrs.v6addrs.dst = _flkeys->addrs.v6addrs.dst;
1843 keys->addrs.v6addrs.dst = key_iph->daddr; 1857 keys->tags.flow_label = _flkeys->tags.flow_label;
1844 keys->tags.flow_label = ip6_flowinfo(key_iph); 1858 keys->basic.ip_proto = _flkeys->basic.ip_proto;
1845 keys->basic.ip_proto = key_iph->nexthdr; 1859 } else {
1860 keys->addrs.v6addrs.src = key_iph->saddr;
1861 keys->addrs.v6addrs.dst = key_iph->daddr;
1862 keys->tags.flow_label = ip6_flowinfo(key_iph);
1863 keys->basic.ip_proto = key_iph->nexthdr;
1864 }
1846} 1865}
1847 1866
1848/* if skb is set it will be used and fl6 can be NULL */ 1867/* if skb is set it will be used and fl6 can be NULL */
1849u32 rt6_multipath_hash(const struct flowi6 *fl6, const struct sk_buff *skb) 1868u32 rt6_multipath_hash(const struct net *net, const struct flowi6 *fl6,
1869 const struct sk_buff *skb, struct flow_keys *flkeys)
1850{ 1870{
1851 struct flow_keys hash_keys; 1871 struct flow_keys hash_keys;
1872 u32 mhash;
1852 1873
1853 if (skb) { 1874 switch (ip6_multipath_hash_policy(net)) {
1854 ip6_multipath_l3_keys(skb, &hash_keys); 1875 case 0:
1855 return flow_hash_from_keys(&hash_keys) >> 1; 1876 memset(&hash_keys, 0, sizeof(hash_keys));
1877 hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
1878 if (skb) {
1879 ip6_multipath_l3_keys(skb, &hash_keys, flkeys);
1880 } else {
1881 hash_keys.addrs.v6addrs.src = fl6->saddr;
1882 hash_keys.addrs.v6addrs.dst = fl6->daddr;
1883 hash_keys.tags.flow_label = (__force u32)fl6->flowlabel;
1884 hash_keys.basic.ip_proto = fl6->flowi6_proto;
1885 }
1886 break;
1887 case 1:
1888 if (skb) {
1889 unsigned int flag = FLOW_DISSECTOR_F_STOP_AT_ENCAP;
1890 struct flow_keys keys;
1891
1892 /* short-circuit if we already have L4 hash present */
1893 if (skb->l4_hash)
1894 return skb_get_hash_raw(skb) >> 1;
1895
1896 memset(&hash_keys, 0, sizeof(hash_keys));
1897
1898 if (!flkeys) {
1899 skb_flow_dissect_flow_keys(skb, &keys, flag);
1900 flkeys = &keys;
1901 }
1902 hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
1903 hash_keys.addrs.v6addrs.src = flkeys->addrs.v6addrs.src;
1904 hash_keys.addrs.v6addrs.dst = flkeys->addrs.v6addrs.dst;
1905 hash_keys.ports.src = flkeys->ports.src;
1906 hash_keys.ports.dst = flkeys->ports.dst;
1907 hash_keys.basic.ip_proto = flkeys->basic.ip_proto;
1908 } else {
1909 memset(&hash_keys, 0, sizeof(hash_keys));
1910 hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
1911 hash_keys.addrs.v6addrs.src = fl6->saddr;
1912 hash_keys.addrs.v6addrs.dst = fl6->daddr;
1913 hash_keys.ports.src = fl6->fl6_sport;
1914 hash_keys.ports.dst = fl6->fl6_dport;
1915 hash_keys.basic.ip_proto = fl6->flowi6_proto;
1916 }
1917 break;
1856 } 1918 }
1919 mhash = flow_hash_from_keys(&hash_keys);
1857 1920
1858 return get_hash_from_flowi6(fl6) >> 1; 1921 return mhash >> 1;
1859} 1922}
1860 1923
1861void ip6_route_input(struct sk_buff *skb) 1924void ip6_route_input(struct sk_buff *skb)
@@ -1872,20 +1935,29 @@ void ip6_route_input(struct sk_buff *skb)
1872 .flowi6_mark = skb->mark, 1935 .flowi6_mark = skb->mark,
1873 .flowi6_proto = iph->nexthdr, 1936 .flowi6_proto = iph->nexthdr,
1874 }; 1937 };
1938 struct flow_keys *flkeys = NULL, _flkeys;
1875 1939
1876 tun_info = skb_tunnel_info(skb); 1940 tun_info = skb_tunnel_info(skb);
1877 if (tun_info && !(tun_info->mode & IP_TUNNEL_INFO_TX)) 1941 if (tun_info && !(tun_info->mode & IP_TUNNEL_INFO_TX))
1878 fl6.flowi6_tun_key.tun_id = tun_info->key.tun_id; 1942 fl6.flowi6_tun_key.tun_id = tun_info->key.tun_id;
1943
1944 if (fib6_rules_early_flow_dissect(net, skb, &fl6, &_flkeys))
1945 flkeys = &_flkeys;
1946
1879 if (unlikely(fl6.flowi6_proto == IPPROTO_ICMPV6)) 1947 if (unlikely(fl6.flowi6_proto == IPPROTO_ICMPV6))
1880 fl6.mp_hash = rt6_multipath_hash(&fl6, skb); 1948 fl6.mp_hash = rt6_multipath_hash(net, &fl6, skb, flkeys);
1881 skb_dst_drop(skb); 1949 skb_dst_drop(skb);
1882 skb_dst_set(skb, ip6_route_input_lookup(net, skb->dev, &fl6, flags)); 1950 skb_dst_set(skb,
1951 ip6_route_input_lookup(net, skb->dev, &fl6, skb, flags));
1883} 1952}
1884 1953
1885static struct rt6_info *ip6_pol_route_output(struct net *net, struct fib6_table *table, 1954static struct rt6_info *ip6_pol_route_output(struct net *net,
1886 struct flowi6 *fl6, int flags) 1955 struct fib6_table *table,
1956 struct flowi6 *fl6,
1957 const struct sk_buff *skb,
1958 int flags)
1887{ 1959{
1888 return ip6_pol_route(net, table, fl6->flowi6_oif, fl6, flags); 1960 return ip6_pol_route(net, table, fl6->flowi6_oif, fl6, skb, flags);
1889} 1961}
1890 1962
1891struct dst_entry *ip6_route_output_flags(struct net *net, const struct sock *sk, 1963struct dst_entry *ip6_route_output_flags(struct net *net, const struct sock *sk,
@@ -1913,7 +1985,7 @@ struct dst_entry *ip6_route_output_flags(struct net *net, const struct sock *sk,
1913 else if (sk) 1985 else if (sk)
1914 flags |= rt6_srcprefs2flags(inet6_sk(sk)->srcprefs); 1986 flags |= rt6_srcprefs2flags(inet6_sk(sk)->srcprefs);
1915 1987
1916 return fib6_rule_lookup(net, fl6, flags, ip6_pol_route_output); 1988 return fib6_rule_lookup(net, fl6, NULL, flags, ip6_pol_route_output);
1917} 1989}
1918EXPORT_SYMBOL_GPL(ip6_route_output_flags); 1990EXPORT_SYMBOL_GPL(ip6_route_output_flags);
1919 1991
@@ -2162,6 +2234,7 @@ struct ip6rd_flowi {
2162static struct rt6_info *__ip6_route_redirect(struct net *net, 2234static struct rt6_info *__ip6_route_redirect(struct net *net,
2163 struct fib6_table *table, 2235 struct fib6_table *table,
2164 struct flowi6 *fl6, 2236 struct flowi6 *fl6,
2237 const struct sk_buff *skb,
2165 int flags) 2238 int flags)
2166{ 2239{
2167 struct ip6rd_flowi *rdfl = (struct ip6rd_flowi *)fl6; 2240 struct ip6rd_flowi *rdfl = (struct ip6rd_flowi *)fl6;
@@ -2235,8 +2308,9 @@ out:
2235}; 2308};
2236 2309
2237static struct dst_entry *ip6_route_redirect(struct net *net, 2310static struct dst_entry *ip6_route_redirect(struct net *net,
2238 const struct flowi6 *fl6, 2311 const struct flowi6 *fl6,
2239 const struct in6_addr *gateway) 2312 const struct sk_buff *skb,
2313 const struct in6_addr *gateway)
2240{ 2314{
2241 int flags = RT6_LOOKUP_F_HAS_SADDR; 2315 int flags = RT6_LOOKUP_F_HAS_SADDR;
2242 struct ip6rd_flowi rdfl; 2316 struct ip6rd_flowi rdfl;
@@ -2244,7 +2318,7 @@ static struct dst_entry *ip6_route_redirect(struct net *net,
2244 rdfl.fl6 = *fl6; 2318 rdfl.fl6 = *fl6;
2245 rdfl.gateway = *gateway; 2319 rdfl.gateway = *gateway;
2246 2320
2247 return fib6_rule_lookup(net, &rdfl.fl6, 2321 return fib6_rule_lookup(net, &rdfl.fl6, skb,
2248 flags, __ip6_route_redirect); 2322 flags, __ip6_route_redirect);
2249} 2323}
2250 2324
@@ -2264,7 +2338,7 @@ void ip6_redirect(struct sk_buff *skb, struct net *net, int oif, u32 mark,
2264 fl6.flowlabel = ip6_flowinfo(iph); 2338 fl6.flowlabel = ip6_flowinfo(iph);
2265 fl6.flowi6_uid = uid; 2339 fl6.flowi6_uid = uid;
2266 2340
2267 dst = ip6_route_redirect(net, &fl6, &ipv6_hdr(skb)->saddr); 2341 dst = ip6_route_redirect(net, &fl6, skb, &ipv6_hdr(skb)->saddr);
2268 rt6_do_redirect(dst, NULL, skb); 2342 rt6_do_redirect(dst, NULL, skb);
2269 dst_release(dst); 2343 dst_release(dst);
2270} 2344}
@@ -2286,7 +2360,7 @@ void ip6_redirect_no_header(struct sk_buff *skb, struct net *net, int oif,
2286 fl6.saddr = iph->daddr; 2360 fl6.saddr = iph->daddr;
2287 fl6.flowi6_uid = sock_net_uid(net, NULL); 2361 fl6.flowi6_uid = sock_net_uid(net, NULL);
2288 2362
2289 dst = ip6_route_redirect(net, &fl6, &iph->saddr); 2363 dst = ip6_route_redirect(net, &fl6, skb, &iph->saddr);
2290 rt6_do_redirect(dst, NULL, skb); 2364 rt6_do_redirect(dst, NULL, skb);
2291 dst_release(dst); 2365 dst_release(dst);
2292} 2366}
@@ -2488,7 +2562,7 @@ static struct rt6_info *ip6_nh_lookup_table(struct net *net,
2488 flags |= RT6_LOOKUP_F_HAS_SADDR; 2562 flags |= RT6_LOOKUP_F_HAS_SADDR;
2489 2563
2490 flags |= RT6_LOOKUP_F_IGNORE_LINKSTATE; 2564 flags |= RT6_LOOKUP_F_IGNORE_LINKSTATE;
2491 rt = ip6_pol_route(net, table, cfg->fc_ifindex, &fl6, flags); 2565 rt = ip6_pol_route(net, table, cfg->fc_ifindex, &fl6, NULL, flags);
2492 2566
2493 /* if table lookup failed, fall back to full lookup */ 2567 /* if table lookup failed, fall back to full lookup */
2494 if (rt == net->ipv6.ip6_null_entry) { 2568 if (rt == net->ipv6.ip6_null_entry) {
@@ -2501,7 +2575,7 @@ static struct rt6_info *ip6_nh_lookup_table(struct net *net,
2501 2575
2502static int ip6_route_check_nh_onlink(struct net *net, 2576static int ip6_route_check_nh_onlink(struct net *net,
2503 struct fib6_config *cfg, 2577 struct fib6_config *cfg,
2504 struct net_device *dev, 2578 const struct net_device *dev,
2505 struct netlink_ext_ack *extack) 2579 struct netlink_ext_ack *extack)
2506{ 2580{
2507 u32 tbid = l3mdev_fib_table(dev) ? : RT_TABLE_MAIN; 2581 u32 tbid = l3mdev_fib_table(dev) ? : RT_TABLE_MAIN;
@@ -2551,7 +2625,7 @@ static int ip6_route_check_nh(struct net *net,
2551 } 2625 }
2552 2626
2553 if (!grt) 2627 if (!grt)
2554 grt = rt6_lookup(net, gw_addr, NULL, cfg->fc_ifindex, 1); 2628 grt = rt6_lookup(net, gw_addr, NULL, cfg->fc_ifindex, NULL, 1);
2555 2629
2556 if (!grt) 2630 if (!grt)
2557 goto out; 2631 goto out;
@@ -2577,6 +2651,79 @@ out:
2577 return err; 2651 return err;
2578} 2652}
2579 2653
2654static int ip6_validate_gw(struct net *net, struct fib6_config *cfg,
2655 struct net_device **_dev, struct inet6_dev **idev,
2656 struct netlink_ext_ack *extack)
2657{
2658 const struct in6_addr *gw_addr = &cfg->fc_gateway;
2659 int gwa_type = ipv6_addr_type(gw_addr);
2660 bool skip_dev = gwa_type & IPV6_ADDR_LINKLOCAL ? false : true;
2661 const struct net_device *dev = *_dev;
2662 bool need_addr_check = !dev;
2663 int err = -EINVAL;
2664
2665 /* if gw_addr is local we will fail to detect this in case
2666 * address is still TENTATIVE (DAD in progress). rt6_lookup()
2667 * will return already-added prefix route via interface that
2668 * prefix route was assigned to, which might be non-loopback.
2669 */
2670 if (dev &&
2671 ipv6_chk_addr_and_flags(net, gw_addr, dev, skip_dev, 0, 0)) {
2672 NL_SET_ERR_MSG(extack, "Gateway can not be a local address");
2673 goto out;
2674 }
2675
2676 if (gwa_type != (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_UNICAST)) {
2677 /* IPv6 strictly inhibits using not link-local
2678 * addresses as nexthop address.
2679 * Otherwise, router will not able to send redirects.
2680 * It is very good, but in some (rare!) circumstances
2681 * (SIT, PtP, NBMA NOARP links) it is handy to allow
2682 * some exceptions. --ANK
2683 * We allow IPv4-mapped nexthops to support RFC4798-type
2684 * addressing
2685 */
2686 if (!(gwa_type & (IPV6_ADDR_UNICAST | IPV6_ADDR_MAPPED))) {
2687 NL_SET_ERR_MSG(extack, "Invalid gateway address");
2688 goto out;
2689 }
2690
2691 if (cfg->fc_flags & RTNH_F_ONLINK)
2692 err = ip6_route_check_nh_onlink(net, cfg, dev, extack);
2693 else
2694 err = ip6_route_check_nh(net, cfg, _dev, idev);
2695
2696 if (err)
2697 goto out;
2698 }
2699
2700 /* reload in case device was changed */
2701 dev = *_dev;
2702
2703 err = -EINVAL;
2704 if (!dev) {
2705 NL_SET_ERR_MSG(extack, "Egress device not specified");
2706 goto out;
2707 } else if (dev->flags & IFF_LOOPBACK) {
2708 NL_SET_ERR_MSG(extack,
2709 "Egress device can not be loopback device for this route");
2710 goto out;
2711 }
2712
2713 /* if we did not check gw_addr above, do so now that the
2714 * egress device has been resolved.
2715 */
2716 if (need_addr_check &&
2717 ipv6_chk_addr_and_flags(net, gw_addr, dev, skip_dev, 0, 0)) {
2718 NL_SET_ERR_MSG(extack, "Gateway can not be a local address");
2719 goto out;
2720 }
2721
2722 err = 0;
2723out:
2724 return err;
2725}
2726
2580static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg, 2727static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg,
2581 struct netlink_ext_ack *extack) 2728 struct netlink_ext_ack *extack)
2582{ 2729{
@@ -2696,14 +2843,7 @@ static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg,
2696 if (err) 2843 if (err)
2697 goto out; 2844 goto out;
2698 rt->dst.lwtstate = lwtstate_get(lwtstate); 2845 rt->dst.lwtstate = lwtstate_get(lwtstate);
2699 if (lwtunnel_output_redirect(rt->dst.lwtstate)) { 2846 lwtunnel_set_redirect(&rt->dst);
2700 rt->dst.lwtstate->orig_output = rt->dst.output;
2701 rt->dst.output = lwtunnel_output;
2702 }
2703 if (lwtunnel_input_redirect(rt->dst.lwtstate)) {
2704 rt->dst.lwtstate->orig_input = rt->dst.input;
2705 rt->dst.input = lwtunnel_input;
2706 }
2707 } 2847 }
2708 2848
2709 ipv6_addr_prefix(&rt->rt6i_dst.addr, &cfg->fc_dst, cfg->fc_dst_len); 2849 ipv6_addr_prefix(&rt->rt6i_dst.addr, &cfg->fc_dst, cfg->fc_dst_len);
@@ -2766,61 +2906,11 @@ static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg,
2766 } 2906 }
2767 2907
2768 if (cfg->fc_flags & RTF_GATEWAY) { 2908 if (cfg->fc_flags & RTF_GATEWAY) {
2769 const struct in6_addr *gw_addr; 2909 err = ip6_validate_gw(net, cfg, &dev, &idev, extack);
2770 int gwa_type; 2910 if (err)
2771
2772 gw_addr = &cfg->fc_gateway;
2773 gwa_type = ipv6_addr_type(gw_addr);
2774
2775 /* if gw_addr is local we will fail to detect this in case
2776 * address is still TENTATIVE (DAD in progress). rt6_lookup()
2777 * will return already-added prefix route via interface that
2778 * prefix route was assigned to, which might be non-loopback.
2779 */
2780 err = -EINVAL;
2781 if (ipv6_chk_addr_and_flags(net, gw_addr,
2782 gwa_type & IPV6_ADDR_LINKLOCAL ?
2783 dev : NULL, 0, 0)) {
2784 NL_SET_ERR_MSG(extack, "Invalid gateway address");
2785 goto out; 2911 goto out;
2786 }
2787 rt->rt6i_gateway = *gw_addr;
2788
2789 if (gwa_type != (IPV6_ADDR_LINKLOCAL|IPV6_ADDR_UNICAST)) {
2790 /* IPv6 strictly inhibits using not link-local
2791 addresses as nexthop address.
2792 Otherwise, router will not able to send redirects.
2793 It is very good, but in some (rare!) circumstances
2794 (SIT, PtP, NBMA NOARP links) it is handy to allow
2795 some exceptions. --ANK
2796 We allow IPv4-mapped nexthops to support RFC4798-type
2797 addressing
2798 */
2799 if (!(gwa_type & (IPV6_ADDR_UNICAST |
2800 IPV6_ADDR_MAPPED))) {
2801 NL_SET_ERR_MSG(extack,
2802 "Invalid gateway address");
2803 goto out;
2804 }
2805 2912
2806 if (cfg->fc_flags & RTNH_F_ONLINK) { 2913 rt->rt6i_gateway = cfg->fc_gateway;
2807 err = ip6_route_check_nh_onlink(net, cfg, dev,
2808 extack);
2809 } else {
2810 err = ip6_route_check_nh(net, cfg, &dev, &idev);
2811 }
2812 if (err)
2813 goto out;
2814 }
2815 err = -EINVAL;
2816 if (!dev) {
2817 NL_SET_ERR_MSG(extack, "Egress device not specified");
2818 goto out;
2819 } else if (dev->flags & IFF_LOOPBACK) {
2820 NL_SET_ERR_MSG(extack,
2821 "Egress device can not be loopback device for this route");
2822 goto out;
2823 }
2824 } 2914 }
2825 2915
2826 err = -ENODEV; 2916 err = -ENODEV;
@@ -4612,7 +4702,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
4612 if (!ipv6_addr_any(&fl6.saddr)) 4702 if (!ipv6_addr_any(&fl6.saddr))
4613 flags |= RT6_LOOKUP_F_HAS_SADDR; 4703 flags |= RT6_LOOKUP_F_HAS_SADDR;
4614 4704
4615 dst = ip6_route_input_lookup(net, dev, &fl6, flags); 4705 dst = ip6_route_input_lookup(net, dev, &fl6, NULL, flags);
4616 4706
4617 rcu_read_unlock(); 4707 rcu_read_unlock();
4618 } else { 4708 } else {
@@ -4993,6 +5083,7 @@ static void __net_exit ip6_route_net_exit_late(struct net *net)
4993static struct pernet_operations ip6_route_net_ops = { 5083static struct pernet_operations ip6_route_net_ops = {
4994 .init = ip6_route_net_init, 5084 .init = ip6_route_net_init,
4995 .exit = ip6_route_net_exit, 5085 .exit = ip6_route_net_exit,
5086 .async = true,
4996}; 5087};
4997 5088
4998static int __net_init ipv6_inetpeer_init(struct net *net) 5089static int __net_init ipv6_inetpeer_init(struct net *net)
@@ -5018,11 +5109,13 @@ static void __net_exit ipv6_inetpeer_exit(struct net *net)
5018static struct pernet_operations ipv6_inetpeer_ops = { 5109static struct pernet_operations ipv6_inetpeer_ops = {
5019 .init = ipv6_inetpeer_init, 5110 .init = ipv6_inetpeer_init,
5020 .exit = ipv6_inetpeer_exit, 5111 .exit = ipv6_inetpeer_exit,
5112 .async = true,
5021}; 5113};
5022 5114
5023static struct pernet_operations ip6_route_net_late_ops = { 5115static struct pernet_operations ip6_route_net_late_ops = {
5024 .init = ip6_route_net_init_late, 5116 .init = ip6_route_net_init_late,
5025 .exit = ip6_route_net_exit_late, 5117 .exit = ip6_route_net_exit_late,
5118 .async = true,
5026}; 5119};
5027 5120
5028static struct notifier_block ip6_route_dev_notifier = { 5121static struct notifier_block ip6_route_dev_notifier = {
diff --git a/net/ipv6/seg6.c b/net/ipv6/seg6.c
index 7f5621d09571..c3f13c3bd8a9 100644
--- a/net/ipv6/seg6.c
+++ b/net/ipv6/seg6.c
@@ -395,6 +395,7 @@ static void __net_exit seg6_net_exit(struct net *net)
395static struct pernet_operations ip6_segments_ops = { 395static struct pernet_operations ip6_segments_ops = {
396 .init = seg6_net_init, 396 .init = seg6_net_init,
397 .exit = seg6_net_exit, 397 .exit = seg6_net_exit,
398 .async = true,
398}; 399};
399 400
400static const struct genl_ops seg6_genl_ops[] = { 401static const struct genl_ops seg6_genl_ops[] = {
diff --git a/net/ipv6/seg6_local.c b/net/ipv6/seg6_local.c
index ba3767ef5e93..45722327375a 100644
--- a/net/ipv6/seg6_local.c
+++ b/net/ipv6/seg6_local.c
@@ -161,7 +161,7 @@ static void lookup_nexthop(struct sk_buff *skb, struct in6_addr *nhaddr,
161 fl6.flowi6_flags = FLOWI_FLAG_KNOWN_NH; 161 fl6.flowi6_flags = FLOWI_FLAG_KNOWN_NH;
162 162
163 if (!tbl_id) { 163 if (!tbl_id) {
164 dst = ip6_route_input_lookup(net, skb->dev, &fl6, flags); 164 dst = ip6_route_input_lookup(net, skb->dev, &fl6, skb, flags);
165 } else { 165 } else {
166 struct fib6_table *table; 166 struct fib6_table *table;
167 167
@@ -169,7 +169,7 @@ static void lookup_nexthop(struct sk_buff *skb, struct in6_addr *nhaddr,
169 if (!table) 169 if (!table)
170 goto out; 170 goto out;
171 171
172 rt = ip6_pol_route(net, table, 0, &fl6, flags); 172 rt = ip6_pol_route(net, table, 0, &fl6, skb, flags);
173 dst = &rt->dst; 173 dst = &rt->dst;
174 } 174 }
175 175
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 0195598f7bb5..8a4f8fddd812 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -182,7 +182,7 @@ static void ipip6_tunnel_clone_6rd(struct net_device *dev, struct sit_net *sitn)
182#ifdef CONFIG_IPV6_SIT_6RD 182#ifdef CONFIG_IPV6_SIT_6RD
183 struct ip_tunnel *t = netdev_priv(dev); 183 struct ip_tunnel *t = netdev_priv(dev);
184 184
185 if (dev == sitn->fb_tunnel_dev) { 185 if (dev == sitn->fb_tunnel_dev || !sitn->fb_tunnel_dev) {
186 ipv6_addr_set(&t->ip6rd.prefix, htonl(0x20020000), 0, 0, 0); 186 ipv6_addr_set(&t->ip6rd.prefix, htonl(0x20020000), 0, 0, 0);
187 t->ip6rd.relay_prefix = 0; 187 t->ip6rd.relay_prefix = 0;
188 t->ip6rd.prefixlen = 16; 188 t->ip6rd.prefixlen = 16;
@@ -1835,6 +1835,9 @@ static int __net_init sit_init_net(struct net *net)
1835 sitn->tunnels[2] = sitn->tunnels_r; 1835 sitn->tunnels[2] = sitn->tunnels_r;
1836 sitn->tunnels[3] = sitn->tunnels_r_l; 1836 sitn->tunnels[3] = sitn->tunnels_r_l;
1837 1837
1838 if (!net_has_fallback_tunnels(net))
1839 return 0;
1840
1838 sitn->fb_tunnel_dev = alloc_netdev(sizeof(struct ip_tunnel), "sit0", 1841 sitn->fb_tunnel_dev = alloc_netdev(sizeof(struct ip_tunnel), "sit0",
1839 NET_NAME_UNKNOWN, 1842 NET_NAME_UNKNOWN,
1840 ipip6_tunnel_setup); 1843 ipip6_tunnel_setup);
@@ -1885,6 +1888,7 @@ static struct pernet_operations sit_net_ops = {
1885 .exit_batch = sit_exit_batch_net, 1888 .exit_batch = sit_exit_batch_net,
1886 .id = &sit_net_id, 1889 .id = &sit_net_id,
1887 .size = sizeof(struct sit_net), 1890 .size = sizeof(struct sit_net),
1891 .async = true,
1888}; 1892};
1889 1893
1890static void __exit sit_cleanup(void) 1894static void __exit sit_cleanup(void)
diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c
index a789a8ac6a64..966c42af92f4 100644
--- a/net/ipv6/sysctl_net_ipv6.c
+++ b/net/ipv6/sysctl_net_ipv6.c
@@ -16,14 +16,31 @@
16#include <net/ipv6.h> 16#include <net/ipv6.h>
17#include <net/addrconf.h> 17#include <net/addrconf.h>
18#include <net/inet_frag.h> 18#include <net/inet_frag.h>
19#include <net/netevent.h>
19#ifdef CONFIG_NETLABEL 20#ifdef CONFIG_NETLABEL
20#include <net/calipso.h> 21#include <net/calipso.h>
21#endif 22#endif
22 23
24static int zero;
23static int one = 1; 25static int one = 1;
24static int auto_flowlabels_min; 26static int auto_flowlabels_min;
25static int auto_flowlabels_max = IP6_AUTO_FLOW_LABEL_MAX; 27static int auto_flowlabels_max = IP6_AUTO_FLOW_LABEL_MAX;
26 28
29static int proc_rt6_multipath_hash_policy(struct ctl_table *table, int write,
30 void __user *buffer, size_t *lenp,
31 loff_t *ppos)
32{
33 struct net *net;
34 int ret;
35
36 net = container_of(table->data, struct net,
37 ipv6.sysctl.multipath_hash_policy);
38 ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
39 if (write && ret == 0)
40 call_netevent_notifiers(NETEVENT_IPV6_MPATH_HASH_UPDATE, net);
41
42 return ret;
43}
27 44
28static struct ctl_table ipv6_table_template[] = { 45static struct ctl_table ipv6_table_template[] = {
29 { 46 {
@@ -126,6 +143,15 @@ static struct ctl_table ipv6_table_template[] = {
126 .mode = 0644, 143 .mode = 0644,
127 .proc_handler = proc_dointvec 144 .proc_handler = proc_dointvec
128 }, 145 },
146 {
147 .procname = "fib_multipath_hash_policy",
148 .data = &init_net.ipv6.sysctl.multipath_hash_policy,
149 .maxlen = sizeof(int),
150 .mode = 0644,
151 .proc_handler = proc_rt6_multipath_hash_policy,
152 .extra1 = &zero,
153 .extra2 = &one,
154 },
129 { } 155 { }
130}; 156};
131 157
@@ -190,6 +216,7 @@ static int __net_init ipv6_sysctl_net_init(struct net *net)
190 ipv6_table[11].data = &net->ipv6.sysctl.max_hbh_opts_cnt; 216 ipv6_table[11].data = &net->ipv6.sysctl.max_hbh_opts_cnt;
191 ipv6_table[12].data = &net->ipv6.sysctl.max_dst_opts_len; 217 ipv6_table[12].data = &net->ipv6.sysctl.max_dst_opts_len;
192 ipv6_table[13].data = &net->ipv6.sysctl.max_hbh_opts_len; 218 ipv6_table[13].data = &net->ipv6.sysctl.max_hbh_opts_len;
219 ipv6_table[14].data = &net->ipv6.sysctl.multipath_hash_policy,
193 220
194 ipv6_route_table = ipv6_route_sysctl_init(net); 221 ipv6_route_table = ipv6_route_sysctl_init(net);
195 if (!ipv6_route_table) 222 if (!ipv6_route_table)
@@ -251,6 +278,7 @@ static void __net_exit ipv6_sysctl_net_exit(struct net *net)
251static struct pernet_operations ipv6_sysctl_net_ops = { 278static struct pernet_operations ipv6_sysctl_net_ops = {
252 .init = ipv6_sysctl_net_init, 279 .init = ipv6_sysctl_net_init,
253 .exit = ipv6_sysctl_net_exit, 280 .exit = ipv6_sysctl_net_exit,
281 .async = true,
254}; 282};
255 283
256static struct ctl_table_header *ip6_header; 284static struct ctl_table_header *ip6_header;
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 412139f4eccd..5425d7b100ee 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1451,6 +1451,7 @@ process:
1451 1451
1452 if (sk->sk_state == TCP_NEW_SYN_RECV) { 1452 if (sk->sk_state == TCP_NEW_SYN_RECV) {
1453 struct request_sock *req = inet_reqsk(sk); 1453 struct request_sock *req = inet_reqsk(sk);
1454 bool req_stolen = false;
1454 struct sock *nsk; 1455 struct sock *nsk;
1455 1456
1456 sk = req->rsk_listener; 1457 sk = req->rsk_listener;
@@ -1470,10 +1471,20 @@ process:
1470 th = (const struct tcphdr *)skb->data; 1471 th = (const struct tcphdr *)skb->data;
1471 hdr = ipv6_hdr(skb); 1472 hdr = ipv6_hdr(skb);
1472 tcp_v6_fill_cb(skb, hdr, th); 1473 tcp_v6_fill_cb(skb, hdr, th);
1473 nsk = tcp_check_req(sk, skb, req, false); 1474 nsk = tcp_check_req(sk, skb, req, false, &req_stolen);
1474 } 1475 }
1475 if (!nsk) { 1476 if (!nsk) {
1476 reqsk_put(req); 1477 reqsk_put(req);
1478 if (req_stolen) {
1479 /* Another cpu got exclusive access to req
1480 * and created a full blown socket.
1481 * Try to feed this packet to this socket
1482 * instead of discarding it.
1483 */
1484 tcp_v6_restore_cb(skb);
1485 sock_put(sk);
1486 goto lookup;
1487 }
1477 goto discard_and_relse; 1488 goto discard_and_relse;
1478 } 1489 }
1479 if (nsk == sk) { 1490 if (nsk == sk) {
@@ -1996,6 +2007,7 @@ static struct pernet_operations tcpv6_net_ops = {
1996 .init = tcpv6_net_init, 2007 .init = tcpv6_net_init,
1997 .exit = tcpv6_net_exit, 2008 .exit = tcpv6_net_exit,
1998 .exit_batch = tcpv6_net_exit_batch, 2009 .exit_batch = tcpv6_net_exit_batch,
2010 .async = true,
1999}; 2011};
2000 2012
2001int __init tcpv6_init(void) 2013int __init tcpv6_init(void)
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 52e3ea0e6f50..ad30f5e31969 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -1509,34 +1509,34 @@ void udp6_proc_exit(struct net *net)
1509/* ------------------------------------------------------------------------ */ 1509/* ------------------------------------------------------------------------ */
1510 1510
1511struct proto udpv6_prot = { 1511struct proto udpv6_prot = {
1512 .name = "UDPv6", 1512 .name = "UDPv6",
1513 .owner = THIS_MODULE, 1513 .owner = THIS_MODULE,
1514 .close = udp_lib_close, 1514 .close = udp_lib_close,
1515 .connect = ip6_datagram_connect, 1515 .connect = ip6_datagram_connect,
1516 .disconnect = udp_disconnect, 1516 .disconnect = udp_disconnect,
1517 .ioctl = udp_ioctl, 1517 .ioctl = udp_ioctl,
1518 .init = udp_init_sock, 1518 .init = udp_init_sock,
1519 .destroy = udpv6_destroy_sock, 1519 .destroy = udpv6_destroy_sock,
1520 .setsockopt = udpv6_setsockopt, 1520 .setsockopt = udpv6_setsockopt,
1521 .getsockopt = udpv6_getsockopt, 1521 .getsockopt = udpv6_getsockopt,
1522 .sendmsg = udpv6_sendmsg, 1522 .sendmsg = udpv6_sendmsg,
1523 .recvmsg = udpv6_recvmsg, 1523 .recvmsg = udpv6_recvmsg,
1524 .release_cb = ip6_datagram_release_cb, 1524 .release_cb = ip6_datagram_release_cb,
1525 .hash = udp_lib_hash, 1525 .hash = udp_lib_hash,
1526 .unhash = udp_lib_unhash, 1526 .unhash = udp_lib_unhash,
1527 .rehash = udp_v6_rehash, 1527 .rehash = udp_v6_rehash,
1528 .get_port = udp_v6_get_port, 1528 .get_port = udp_v6_get_port,
1529 .memory_allocated = &udp_memory_allocated, 1529 .memory_allocated = &udp_memory_allocated,
1530 .sysctl_mem = sysctl_udp_mem, 1530 .sysctl_mem = sysctl_udp_mem,
1531 .sysctl_wmem = &sysctl_udp_wmem_min, 1531 .sysctl_wmem_offset = offsetof(struct net, ipv4.sysctl_udp_wmem_min),
1532 .sysctl_rmem = &sysctl_udp_rmem_min, 1532 .sysctl_rmem_offset = offsetof(struct net, ipv4.sysctl_udp_rmem_min),
1533 .obj_size = sizeof(struct udp6_sock), 1533 .obj_size = sizeof(struct udp6_sock),
1534 .h.udp_table = &udp_table, 1534 .h.udp_table = &udp_table,
1535#ifdef CONFIG_COMPAT 1535#ifdef CONFIG_COMPAT
1536 .compat_setsockopt = compat_udpv6_setsockopt, 1536 .compat_setsockopt = compat_udpv6_setsockopt,
1537 .compat_getsockopt = compat_udpv6_getsockopt, 1537 .compat_getsockopt = compat_udpv6_getsockopt,
1538#endif 1538#endif
1539 .diag_destroy = udp_abort, 1539 .diag_destroy = udp_abort,
1540}; 1540};
1541 1541
1542static struct inet_protosw udpv6_protosw = { 1542static struct inet_protosw udpv6_protosw = {
diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c
index 14ae32bb1f3d..f3839780dc31 100644
--- a/net/ipv6/udplite.c
+++ b/net/ipv6/udplite.c
@@ -123,6 +123,7 @@ static void __net_exit udplite6_proc_exit_net(struct net *net)
123static struct pernet_operations udplite6_net_ops = { 123static struct pernet_operations udplite6_net_ops = {
124 .init = udplite6_proc_init_net, 124 .init = udplite6_proc_init_net,
125 .exit = udplite6_proc_exit_net, 125 .exit = udplite6_proc_exit_net,
126 .async = true,
126}; 127};
127 128
128int __init udplite6_proc_init(void) 129int __init udplite6_proc_init(void)
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 416fe67271a9..cbb270bd81b0 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -400,6 +400,7 @@ static void __net_exit xfrm6_net_exit(struct net *net)
400static struct pernet_operations xfrm6_net_ops = { 400static struct pernet_operations xfrm6_net_ops = {
401 .init = xfrm6_net_init, 401 .init = xfrm6_net_init,
402 .exit = xfrm6_net_exit, 402 .exit = xfrm6_net_exit,
403 .async = true,
403}; 404};
404 405
405int __init xfrm6_init(void) 406int __init xfrm6_init(void)
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c
index b15075a5c227..16f434791763 100644
--- a/net/ipv6/xfrm6_state.c
+++ b/net/ipv6/xfrm6_state.c
@@ -196,4 +196,3 @@ void xfrm6_state_fini(void)
196{ 196{
197 xfrm_state_unregister_afinfo(&xfrm6_state_afinfo); 197 xfrm_state_unregister_afinfo(&xfrm6_state_afinfo);
198} 198}
199
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index f85f0d7480ac..a9673619e0e9 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -353,6 +353,7 @@ static struct pernet_operations xfrm6_tunnel_net_ops = {
353 .exit = xfrm6_tunnel_net_exit, 353 .exit = xfrm6_tunnel_net_exit,
354 .id = &xfrm6_tunnel_net_id, 354 .id = &xfrm6_tunnel_net_id,
355 .size = sizeof(struct xfrm6_tunnel_net), 355 .size = sizeof(struct xfrm6_tunnel_net),
356 .async = true,
356}; 357};
357 358
358static int __init xfrm6_tunnel_init(void) 359static int __init xfrm6_tunnel_init(void)
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
index 9e2643ab4ccb..893a022f9620 100644
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -989,14 +989,13 @@ done:
989} 989}
990 990
991static int iucv_sock_getname(struct socket *sock, struct sockaddr *addr, 991static int iucv_sock_getname(struct socket *sock, struct sockaddr *addr,
992 int *len, int peer) 992 int peer)
993{ 993{
994 struct sockaddr_iucv *siucv = (struct sockaddr_iucv *) addr; 994 struct sockaddr_iucv *siucv = (struct sockaddr_iucv *) addr;
995 struct sock *sk = sock->sk; 995 struct sock *sk = sock->sk;
996 struct iucv_sock *iucv = iucv_sk(sk); 996 struct iucv_sock *iucv = iucv_sk(sk);
997 997
998 addr->sa_family = AF_IUCV; 998 addr->sa_family = AF_IUCV;
999 *len = sizeof(struct sockaddr_iucv);
1000 999
1001 if (peer) { 1000 if (peer) {
1002 memcpy(siucv->siucv_user_id, iucv->dst_user_id, 8); 1001 memcpy(siucv->siucv_user_id, iucv->dst_user_id, 8);
@@ -1009,7 +1008,7 @@ static int iucv_sock_getname(struct socket *sock, struct sockaddr *addr,
1009 memset(&siucv->siucv_addr, 0, sizeof(siucv->siucv_addr)); 1008 memset(&siucv->siucv_addr, 0, sizeof(siucv->siucv_addr));
1010 memset(&siucv->siucv_nodeid, 0, sizeof(siucv->siucv_nodeid)); 1009 memset(&siucv->siucv_nodeid, 0, sizeof(siucv->siucv_nodeid));
1011 1010
1012 return 0; 1011 return sizeof(struct sockaddr_iucv);
1013} 1012}
1014 1013
1015/** 1014/**
diff --git a/net/kcm/kcmproc.c b/net/kcm/kcmproc.c
index 9d5649e4e8b7..2c1c8b3e4452 100644
--- a/net/kcm/kcmproc.c
+++ b/net/kcm/kcmproc.c
@@ -433,6 +433,7 @@ static void kcm_proc_exit_net(struct net *net)
433static struct pernet_operations kcm_net_ops = { 433static struct pernet_operations kcm_net_ops = {
434 .init = kcm_proc_init_net, 434 .init = kcm_proc_init_net,
435 .exit = kcm_proc_exit_net, 435 .exit = kcm_proc_exit_net,
436 .async = true,
436}; 437};
437 438
438int __init kcm_proc_init(void) 439int __init kcm_proc_init(void)
diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c
index 34355fd19f27..516cfad71b85 100644
--- a/net/kcm/kcmsock.c
+++ b/net/kcm/kcmsock.c
@@ -1425,6 +1425,7 @@ static int kcm_attach(struct socket *sock, struct socket *csock,
1425 */ 1425 */
1426 if (csk->sk_user_data) { 1426 if (csk->sk_user_data) {
1427 write_unlock_bh(&csk->sk_callback_lock); 1427 write_unlock_bh(&csk->sk_callback_lock);
1428 strp_stop(&psock->strp);
1428 strp_done(&psock->strp); 1429 strp_done(&psock->strp);
1429 kmem_cache_free(kcm_psockp, psock); 1430 kmem_cache_free(kcm_psockp, psock);
1430 err = -EALREADY; 1431 err = -EALREADY;
@@ -2027,6 +2028,7 @@ static struct pernet_operations kcm_net_ops = {
2027 .exit = kcm_exit_net, 2028 .exit = kcm_exit_net,
2028 .id = &kcm_net_id, 2029 .id = &kcm_net_id,
2029 .size = sizeof(struct kcm_net), 2030 .size = sizeof(struct kcm_net),
2031 .async = true,
2030}; 2032};
2031 2033
2032static int __init kcm_init(void) 2034static int __init kcm_init(void)
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 7e2e7188e7f4..3ac08ab26207 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -3863,6 +3863,7 @@ static struct pernet_operations pfkey_net_ops = {
3863 .exit = pfkey_net_exit, 3863 .exit = pfkey_net_exit,
3864 .id = &pfkey_net_id, 3864 .id = &pfkey_net_id,
3865 .size = sizeof(struct netns_pfkey), 3865 .size = sizeof(struct netns_pfkey),
3866 .async = true,
3866}; 3867};
3867 3868
3868static void __exit ipsec_pfkey_exit(void) 3869static void __exit ipsec_pfkey_exit(void)
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index 14b67dfacc4b..b86868da50d4 100644
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@ -1789,6 +1789,7 @@ static struct pernet_operations l2tp_net_ops = {
1789 .exit = l2tp_exit_net, 1789 .exit = l2tp_exit_net,
1790 .id = &l2tp_net_id, 1790 .id = &l2tp_net_id,
1791 .size = sizeof(struct l2tp_net), 1791 .size = sizeof(struct l2tp_net),
1792 .async = true,
1792}; 1793};
1793 1794
1794static int __init l2tp_init(void) 1795static int __init l2tp_init(void)
diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c
index 3428fba6f2b7..a9c05b2bc1b0 100644
--- a/net/l2tp/l2tp_ip.c
+++ b/net/l2tp/l2tp_ip.c
@@ -345,7 +345,7 @@ static int l2tp_ip_disconnect(struct sock *sk, int flags)
345} 345}
346 346
347static int l2tp_ip_getname(struct socket *sock, struct sockaddr *uaddr, 347static int l2tp_ip_getname(struct socket *sock, struct sockaddr *uaddr,
348 int *uaddr_len, int peer) 348 int peer)
349{ 349{
350 struct sock *sk = sock->sk; 350 struct sock *sk = sock->sk;
351 struct inet_sock *inet = inet_sk(sk); 351 struct inet_sock *inet = inet_sk(sk);
@@ -366,8 +366,7 @@ static int l2tp_ip_getname(struct socket *sock, struct sockaddr *uaddr,
366 lsa->l2tp_conn_id = lsk->conn_id; 366 lsa->l2tp_conn_id = lsk->conn_id;
367 lsa->l2tp_addr.s_addr = addr; 367 lsa->l2tp_addr.s_addr = addr;
368 } 368 }
369 *uaddr_len = sizeof(*lsa); 369 return sizeof(*lsa);
370 return 0;
371} 370}
372 371
373static int l2tp_ip_backlog_recv(struct sock *sk, struct sk_buff *skb) 372static int l2tp_ip_backlog_recv(struct sock *sk, struct sk_buff *skb)
diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c
index 6f009eaa5fbe..957369192ca1 100644
--- a/net/l2tp/l2tp_ip6.c
+++ b/net/l2tp/l2tp_ip6.c
@@ -419,7 +419,7 @@ static int l2tp_ip6_disconnect(struct sock *sk, int flags)
419} 419}
420 420
421static int l2tp_ip6_getname(struct socket *sock, struct sockaddr *uaddr, 421static int l2tp_ip6_getname(struct socket *sock, struct sockaddr *uaddr,
422 int *uaddr_len, int peer) 422 int peer)
423{ 423{
424 struct sockaddr_l2tpip6 *lsa = (struct sockaddr_l2tpip6 *)uaddr; 424 struct sockaddr_l2tpip6 *lsa = (struct sockaddr_l2tpip6 *)uaddr;
425 struct sock *sk = sock->sk; 425 struct sock *sk = sock->sk;
@@ -447,8 +447,7 @@ static int l2tp_ip6_getname(struct socket *sock, struct sockaddr *uaddr,
447 } 447 }
448 if (ipv6_addr_type(&lsa->l2tp_addr) & IPV6_ADDR_LINKLOCAL) 448 if (ipv6_addr_type(&lsa->l2tp_addr) & IPV6_ADDR_LINKLOCAL)
449 lsa->l2tp_scope_id = sk->sk_bound_dev_if; 449 lsa->l2tp_scope_id = sk->sk_bound_dev_if;
450 *uaddr_len = sizeof(*lsa); 450 return sizeof(*lsa);
451 return 0;
452} 451}
453 452
454static int l2tp_ip6_backlog_recv(struct sock *sk, struct sk_buff *skb) 453static int l2tp_ip6_backlog_recv(struct sock *sk, struct sk_buff *skb)
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
index 3b02f24ea9ec..977bca659787 100644
--- a/net/l2tp/l2tp_ppp.c
+++ b/net/l2tp/l2tp_ppp.c
@@ -862,7 +862,7 @@ err:
862/* getname() support. 862/* getname() support.
863 */ 863 */
864static int pppol2tp_getname(struct socket *sock, struct sockaddr *uaddr, 864static int pppol2tp_getname(struct socket *sock, struct sockaddr *uaddr,
865 int *usockaddr_len, int peer) 865 int peer)
866{ 866{
867 int len = 0; 867 int len = 0;
868 int error = 0; 868 int error = 0;
@@ -961,8 +961,7 @@ static int pppol2tp_getname(struct socket *sock, struct sockaddr *uaddr,
961 memcpy(uaddr, &sp, len); 961 memcpy(uaddr, &sp, len);
962 } 962 }
963 963
964 *usockaddr_len = len; 964 error = len;
965 error = 0;
966 965
967 sock_put(sk); 966 sock_put(sk);
968end: 967end:
@@ -1763,6 +1762,7 @@ static struct pernet_operations pppol2tp_net_ops = {
1763 .init = pppol2tp_init_net, 1762 .init = pppol2tp_init_net,
1764 .exit = pppol2tp_exit_net, 1763 .exit = pppol2tp_exit_net,
1765 .id = &pppol2tp_net_id, 1764 .id = &pppol2tp_net_id,
1765 .async = true,
1766}; 1766};
1767 1767
1768/***************************************************************************** 1768/*****************************************************************************
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index c38d16f22d2a..01dcc0823d1f 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -971,7 +971,7 @@ release:
971 * Return the address information of a socket. 971 * Return the address information of a socket.
972 */ 972 */
973static int llc_ui_getname(struct socket *sock, struct sockaddr *uaddr, 973static int llc_ui_getname(struct socket *sock, struct sockaddr *uaddr,
974 int *uaddrlen, int peer) 974 int peer)
975{ 975{
976 struct sockaddr_llc sllc; 976 struct sockaddr_llc sllc;
977 struct sock *sk = sock->sk; 977 struct sock *sk = sock->sk;
@@ -982,7 +982,6 @@ static int llc_ui_getname(struct socket *sock, struct sockaddr *uaddr,
982 lock_sock(sk); 982 lock_sock(sk);
983 if (sock_flag(sk, SOCK_ZAPPED)) 983 if (sock_flag(sk, SOCK_ZAPPED))
984 goto out; 984 goto out;
985 *uaddrlen = sizeof(sllc);
986 if (peer) { 985 if (peer) {
987 rc = -ENOTCONN; 986 rc = -ENOTCONN;
988 if (sk->sk_state != TCP_ESTABLISHED) 987 if (sk->sk_state != TCP_ESTABLISHED)
@@ -1003,9 +1002,9 @@ static int llc_ui_getname(struct socket *sock, struct sockaddr *uaddr,
1003 IFHWADDRLEN); 1002 IFHWADDRLEN);
1004 } 1003 }
1005 } 1004 }
1006 rc = 0;
1007 sllc.sllc_family = AF_LLC; 1005 sllc.sllc_family = AF_LLC;
1008 memcpy(uaddr, &sllc, sizeof(sllc)); 1006 memcpy(uaddr, &sllc, sizeof(sllc));
1007 rc = sizeof(sllc);
1009out: 1008out:
1010 release_sock(sk); 1009 release_sock(sk);
1011 return rc; 1010 return rc;
diff --git a/net/llc/llc_sap.c b/net/llc/llc_sap.c
index d90928f50226..a7f7b8ff4729 100644
--- a/net/llc/llc_sap.c
+++ b/net/llc/llc_sap.c
@@ -394,8 +394,9 @@ static void llc_sap_mcast(struct llc_sap *sap,
394 const struct llc_addr *laddr, 394 const struct llc_addr *laddr,
395 struct sk_buff *skb) 395 struct sk_buff *skb)
396{ 396{
397 int i = 0, count = 256 / sizeof(struct sock *); 397 int i = 0;
398 struct sock *sk, *stack[count]; 398 struct sock *sk;
399 struct sock *stack[256 / sizeof(struct sock *)];
399 struct llc_sock *llc; 400 struct llc_sock *llc;
400 struct hlist_head *dev_hb = llc_sk_dev_hash(sap, skb->dev->ifindex); 401 struct hlist_head *dev_hb = llc_sk_dev_hash(sap, skb->dev->ifindex);
401 402
@@ -408,7 +409,7 @@ static void llc_sap_mcast(struct llc_sap *sap,
408 continue; 409 continue;
409 410
410 sock_hold(sk); 411 sock_hold(sk);
411 if (i < count) 412 if (i < ARRAY_SIZE(stack))
412 stack[i++] = sk; 413 stack[i++] = sk;
413 else { 414 else {
414 llc_do_mcast(sap, skb, stack, i); 415 llc_do_mcast(sap, skb, stack, i);
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index 1f3188d03840..e83c19d4c292 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -298,13 +298,23 @@ void ___ieee80211_start_rx_ba_session(struct sta_info *sta,
298 298
299 if (test_bit(tid, sta->ampdu_mlme.agg_session_valid)) { 299 if (test_bit(tid, sta->ampdu_mlme.agg_session_valid)) {
300 if (sta->ampdu_mlme.tid_rx_token[tid] == dialog_token) { 300 if (sta->ampdu_mlme.tid_rx_token[tid] == dialog_token) {
301 struct tid_ampdu_rx *tid_rx;
302
301 ht_dbg_ratelimited(sta->sdata, 303 ht_dbg_ratelimited(sta->sdata,
302 "updated AddBA Req from %pM on tid %u\n", 304 "updated AddBA Req from %pM on tid %u\n",
303 sta->sta.addr, tid); 305 sta->sta.addr, tid);
304 /* We have no API to update the timeout value in the 306 /* We have no API to update the timeout value in the
305 * driver so reject the timeout update. 307 * driver so reject the timeout update if the timeout
308 * changed. If if did not change, i.e., no real update,
309 * just reply with success.
306 */ 310 */
307 status = WLAN_STATUS_REQUEST_DECLINED; 311 rcu_read_lock();
312 tid_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]);
313 if (tid_rx && tid_rx->timeout == timeout)
314 status = WLAN_STATUS_SUCCESS;
315 else
316 status = WLAN_STATUS_REQUEST_DECLINED;
317 rcu_read_unlock();
308 goto end; 318 goto end;
309 } 319 }
310 320
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index f4195a0f0279..fd68f6fb02d7 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2685,6 +2685,7 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
2685 2685
2686 ieee80211_recalc_ps(local); 2686 ieee80211_recalc_ps(local);
2687 ieee80211_recalc_ps_vif(sdata); 2687 ieee80211_recalc_ps_vif(sdata);
2688 ieee80211_check_fast_rx_iface(sdata);
2688 2689
2689 return 0; 2690 return 0;
2690} 2691}
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index 94c7ee9df33b..b5adf3625d16 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -212,6 +212,7 @@ static const char *hw_flag_names[] = {
212 FLAG(REPORTS_LOW_ACK), 212 FLAG(REPORTS_LOW_ACK),
213 FLAG(SUPPORTS_TX_FRAG), 213 FLAG(SUPPORTS_TX_FRAG),
214 FLAG(SUPPORTS_TDLS_BUFFER_STA), 214 FLAG(SUPPORTS_TDLS_BUFFER_STA),
215 FLAG(DEAUTH_NEED_MGD_TX_PREP),
215 FLAG(DOESNT_SUPPORT_QOS_NDP), 216 FLAG(DOESNT_SUPPORT_QOS_NDP),
216#undef FLAG 217#undef FLAG
217}; 218};
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index 444ea8d127fe..4105081dc1df 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -160,12 +160,12 @@ static ssize_t sta_aqm_read(struct file *file, char __user *userbuf,
160 sta->cparams.ecn ? "yes" : "no"); 160 sta->cparams.ecn ? "yes" : "no");
161 p += scnprintf(p, 161 p += scnprintf(p,
162 bufsz+buf-p, 162 bufsz+buf-p,
163 "tid ac backlog-bytes backlog-packets new-flows drops marks overlimit collisions tx-bytes tx-packets\n"); 163 "tid ac backlog-bytes backlog-packets new-flows drops marks overlimit collisions tx-bytes tx-packets flags\n");
164 164
165 for (i = 0; i < IEEE80211_NUM_TIDS; i++) { 165 for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
166 txqi = to_txq_info(sta->sta.txq[i]); 166 txqi = to_txq_info(sta->sta.txq[i]);
167 p += scnprintf(p, bufsz+buf-p, 167 p += scnprintf(p, bufsz+buf-p,
168 "%d %d %u %u %u %u %u %u %u %u %u\n", 168 "%d %d %u %u %u %u %u %u %u %u %u 0x%lx(%s%s%s)\n",
169 txqi->txq.tid, 169 txqi->txq.tid,
170 txqi->txq.ac, 170 txqi->txq.ac,
171 txqi->tin.backlog_bytes, 171 txqi->tin.backlog_bytes,
@@ -176,7 +176,11 @@ static ssize_t sta_aqm_read(struct file *file, char __user *userbuf,
176 txqi->tin.overlimit, 176 txqi->tin.overlimit,
177 txqi->tin.collisions, 177 txqi->tin.collisions,
178 txqi->tin.tx_bytes, 178 txqi->tin.tx_bytes,
179 txqi->tin.tx_packets); 179 txqi->tin.tx_packets,
180 txqi->flags,
181 txqi->flags & (1<<IEEE80211_TXQ_STOP) ? "STOP" : "RUN",
182 txqi->flags & (1<<IEEE80211_TXQ_AMPDU) ? " AMPDU" : "",
183 txqi->flags & (1<<IEEE80211_TXQ_NO_AMSDU) ? " NO-AMSDU" : "");
180 } 184 }
181 185
182 rcu_read_unlock(); 186 rcu_read_unlock();
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 5fe01f82df12..d13ba064951f 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -1324,8 +1324,7 @@ static void ieee80211_iface_work(struct work_struct *work)
1324 mutex_lock(&local->sta_mtx); 1324 mutex_lock(&local->sta_mtx);
1325 sta = sta_info_get_bss(sdata, mgmt->sa); 1325 sta = sta_info_get_bss(sdata, mgmt->sa);
1326 if (sta) { 1326 if (sta) {
1327 u16 tid = *ieee80211_get_qos_ctl(hdr) & 1327 u16 tid = ieee80211_get_tid(hdr);
1328 IEEE80211_QOS_CTL_TID_MASK;
1329 1328
1330 __ieee80211_stop_rx_ba_session( 1329 __ieee80211_stop_rx_ba_session(
1331 sta, tid, WLAN_BACK_RECIPIENT, 1330 sta, tid, WLAN_BACK_RECIPIENT,
diff --git a/net/mac80211/michael.c b/net/mac80211/michael.c
index 408649bd4702..37e172701a63 100644
--- a/net/mac80211/michael.c
+++ b/net/mac80211/michael.c
@@ -35,7 +35,7 @@ static void michael_mic_hdr(struct michael_mic_ctx *mctx, const u8 *key,
35 da = ieee80211_get_DA(hdr); 35 da = ieee80211_get_DA(hdr);
36 sa = ieee80211_get_SA(hdr); 36 sa = ieee80211_get_SA(hdr);
37 if (ieee80211_is_data_qos(hdr->frame_control)) 37 if (ieee80211_is_data_qos(hdr->frame_control))
38 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; 38 tid = ieee80211_get_tid(hdr);
39 else 39 else
40 tid = 0; 40 tid = 0;
41 41
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 5f303abac5ad..fe4aefb06d9f 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -7,6 +7,7 @@
7 * Copyright 2007, Michael Wu <flamingice@sourmilk.net> 7 * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
8 * Copyright 2013-2014 Intel Mobile Communications GmbH 8 * Copyright 2013-2014 Intel Mobile Communications GmbH
9 * Copyright (C) 2015 - 2017 Intel Deutschland GmbH 9 * Copyright (C) 2015 - 2017 Intel Deutschland GmbH
10 * Copyright (C) 2018 Intel Corporation
10 * 11 *
11 * This program is free software; you can redistribute it and/or modify 12 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as 13 * it under the terms of the GNU General Public License version 2 as
@@ -2009,9 +2010,22 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
2009 ieee80211_flush_queues(local, sdata, true); 2010 ieee80211_flush_queues(local, sdata, true);
2010 2011
2011 /* deauthenticate/disassociate now */ 2012 /* deauthenticate/disassociate now */
2012 if (tx || frame_buf) 2013 if (tx || frame_buf) {
2014 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2015
2016 /*
2017 * In multi channel scenarios guarantee that the virtual
2018 * interface is granted immediate airtime to transmit the
2019 * deauthentication frame by calling mgd_prepare_tx, if the
2020 * driver requested so.
2021 */
2022 if (ieee80211_hw_check(&local->hw, DEAUTH_NEED_MGD_TX_PREP) &&
2023 !ifmgd->have_beacon)
2024 drv_mgd_prepare_tx(sdata->local, sdata);
2025
2013 ieee80211_send_deauth_disassoc(sdata, ifmgd->bssid, stype, 2026 ieee80211_send_deauth_disassoc(sdata, ifmgd->bssid, stype,
2014 reason, tx, frame_buf); 2027 reason, tx, frame_buf);
2028 }
2015 2029
2016 /* flush out frame - make sure the deauth was actually sent */ 2030 /* flush out frame - make sure the deauth was actually sent */
2017 if (tx) 2031 if (tx)
@@ -2152,7 +2166,7 @@ static void ieee80211_sta_tx_wmm_ac_notify(struct ieee80211_sub_if_data *sdata,
2152 u16 tx_time) 2166 u16 tx_time)
2153{ 2167{
2154 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2168 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2155 u16 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; 2169 u16 tid = ieee80211_get_tid(hdr);
2156 int ac = ieee80211_ac_from_tid(tid); 2170 int ac = ieee80211_ac_from_tid(tid);
2157 struct ieee80211_sta_tx_tspec *tx_tspec = &ifmgd->tx_tspec[ac]; 2171 struct ieee80211_sta_tx_tspec *tx_tspec = &ifmgd->tx_tspec[ac];
2158 unsigned long now = jiffies; 2172 unsigned long now = jiffies;
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index 4a5bdad9f303..fb586b6e5d49 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -669,7 +669,7 @@ minstrel_aggr_check(struct ieee80211_sta *pubsta, struct sk_buff *skb)
669 if (unlikely(skb->protocol == cpu_to_be16(ETH_P_PAE))) 669 if (unlikely(skb->protocol == cpu_to_be16(ETH_P_PAE)))
670 return; 670 return;
671 671
672 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; 672 tid = ieee80211_get_tid(hdr);
673 if (likely(sta->ampdu_mlme.tid_tx[tid])) 673 if (likely(sta->ampdu_mlme.tid_tx[tid]))
674 return; 674 return;
675 675
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 56fe16b07538..9c898a3688c6 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -439,6 +439,10 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
439 flags |= IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR; 439 flags |= IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR;
440 if (status->flag & RX_FLAG_AMPDU_DELIM_CRC_KNOWN) 440 if (status->flag & RX_FLAG_AMPDU_DELIM_CRC_KNOWN)
441 flags |= IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN; 441 flags |= IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN;
442 if (status->flag & RX_FLAG_AMPDU_EOF_BIT_KNOWN)
443 flags |= IEEE80211_RADIOTAP_AMPDU_EOF_KNOWN;
444 if (status->flag & RX_FLAG_AMPDU_EOF_BIT)
445 flags |= IEEE80211_RADIOTAP_AMPDU_EOF;
442 put_unaligned_le16(flags, pos); 446 put_unaligned_le16(flags, pos);
443 pos += 2; 447 pos += 2;
444 if (status->flag & RX_FLAG_AMPDU_DELIM_CRC_KNOWN) 448 if (status->flag & RX_FLAG_AMPDU_DELIM_CRC_KNOWN)
@@ -1185,7 +1189,7 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx,
1185 1189
1186 ack_policy = *ieee80211_get_qos_ctl(hdr) & 1190 ack_policy = *ieee80211_get_qos_ctl(hdr) &
1187 IEEE80211_QOS_CTL_ACK_POLICY_MASK; 1191 IEEE80211_QOS_CTL_ACK_POLICY_MASK;
1188 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; 1192 tid = ieee80211_get_tid(hdr);
1189 1193
1190 tid_agg_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]); 1194 tid_agg_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]);
1191 if (!tid_agg_rx) { 1195 if (!tid_agg_rx) {
@@ -1524,9 +1528,7 @@ ieee80211_rx_h_uapsd_and_pspoll(struct ieee80211_rx_data *rx)
1524 ieee80211_has_pm(hdr->frame_control) && 1528 ieee80211_has_pm(hdr->frame_control) &&
1525 (ieee80211_is_data_qos(hdr->frame_control) || 1529 (ieee80211_is_data_qos(hdr->frame_control) ||
1526 ieee80211_is_qos_nullfunc(hdr->frame_control))) { 1530 ieee80211_is_qos_nullfunc(hdr->frame_control))) {
1527 u8 tid; 1531 u8 tid = ieee80211_get_tid(hdr);
1528
1529 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
1530 1532
1531 ieee80211_sta_uapsd_trigger(&rx->sta->sta, tid); 1533 ieee80211_sta_uapsd_trigger(&rx->sta->sta, tid);
1532 } 1534 }
@@ -2351,39 +2353,17 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
2351} 2353}
2352 2354
2353static ieee80211_rx_result debug_noinline 2355static ieee80211_rx_result debug_noinline
2354ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) 2356__ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx, u8 data_offset)
2355{ 2357{
2356 struct net_device *dev = rx->sdata->dev; 2358 struct net_device *dev = rx->sdata->dev;
2357 struct sk_buff *skb = rx->skb; 2359 struct sk_buff *skb = rx->skb;
2358 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 2360 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
2359 __le16 fc = hdr->frame_control; 2361 __le16 fc = hdr->frame_control;
2360 struct sk_buff_head frame_list; 2362 struct sk_buff_head frame_list;
2361 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
2362 struct ethhdr ethhdr; 2363 struct ethhdr ethhdr;
2363 const u8 *check_da = ethhdr.h_dest, *check_sa = ethhdr.h_source; 2364 const u8 *check_da = ethhdr.h_dest, *check_sa = ethhdr.h_source;
2364 2365
2365 if (unlikely(!ieee80211_is_data(fc)))
2366 return RX_CONTINUE;
2367
2368 if (unlikely(!ieee80211_is_data_present(fc)))
2369 return RX_DROP_MONITOR;
2370
2371 if (!(status->rx_flags & IEEE80211_RX_AMSDU))
2372 return RX_CONTINUE;
2373
2374 if (unlikely(ieee80211_has_a4(hdr->frame_control))) { 2366 if (unlikely(ieee80211_has_a4(hdr->frame_control))) {
2375 switch (rx->sdata->vif.type) {
2376 case NL80211_IFTYPE_AP_VLAN:
2377 if (!rx->sdata->u.vlan.sta)
2378 return RX_DROP_UNUSABLE;
2379 break;
2380 case NL80211_IFTYPE_STATION:
2381 if (!rx->sdata->u.mgd.use_4addr)
2382 return RX_DROP_UNUSABLE;
2383 break;
2384 default:
2385 return RX_DROP_UNUSABLE;
2386 }
2387 check_da = NULL; 2367 check_da = NULL;
2388 check_sa = NULL; 2368 check_sa = NULL;
2389 } else switch (rx->sdata->vif.type) { 2369 } else switch (rx->sdata->vif.type) {
@@ -2403,15 +2383,13 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
2403 break; 2383 break;
2404 } 2384 }
2405 2385
2406 if (is_multicast_ether_addr(hdr->addr1))
2407 return RX_DROP_UNUSABLE;
2408
2409 skb->dev = dev; 2386 skb->dev = dev;
2410 __skb_queue_head_init(&frame_list); 2387 __skb_queue_head_init(&frame_list);
2411 2388
2412 if (ieee80211_data_to_8023_exthdr(skb, &ethhdr, 2389 if (ieee80211_data_to_8023_exthdr(skb, &ethhdr,
2413 rx->sdata->vif.addr, 2390 rx->sdata->vif.addr,
2414 rx->sdata->vif.type)) 2391 rx->sdata->vif.type,
2392 data_offset))
2415 return RX_DROP_UNUSABLE; 2393 return RX_DROP_UNUSABLE;
2416 2394
2417 ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr, 2395 ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr,
@@ -2433,6 +2411,44 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
2433 return RX_QUEUED; 2411 return RX_QUEUED;
2434} 2412}
2435 2413
2414static ieee80211_rx_result debug_noinline
2415ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
2416{
2417 struct sk_buff *skb = rx->skb;
2418 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
2419 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
2420 __le16 fc = hdr->frame_control;
2421
2422 if (!(status->rx_flags & IEEE80211_RX_AMSDU))
2423 return RX_CONTINUE;
2424
2425 if (unlikely(!ieee80211_is_data(fc)))
2426 return RX_CONTINUE;
2427
2428 if (unlikely(!ieee80211_is_data_present(fc)))
2429 return RX_DROP_MONITOR;
2430
2431 if (unlikely(ieee80211_has_a4(hdr->frame_control))) {
2432 switch (rx->sdata->vif.type) {
2433 case NL80211_IFTYPE_AP_VLAN:
2434 if (!rx->sdata->u.vlan.sta)
2435 return RX_DROP_UNUSABLE;
2436 break;
2437 case NL80211_IFTYPE_STATION:
2438 if (!rx->sdata->u.mgd.use_4addr)
2439 return RX_DROP_UNUSABLE;
2440 break;
2441 default:
2442 return RX_DROP_UNUSABLE;
2443 }
2444 }
2445
2446 if (is_multicast_ether_addr(hdr->addr1))
2447 return RX_DROP_UNUSABLE;
2448
2449 return __ieee80211_rx_h_amsdu(rx, 0);
2450}
2451
2436#ifdef CONFIG_MAC80211_MESH 2452#ifdef CONFIG_MAC80211_MESH
2437static ieee80211_rx_result 2453static ieee80211_rx_result
2438ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) 2454ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
@@ -2533,11 +2549,8 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
2533 2549
2534 fwd_skb = skb_copy_expand(skb, local->tx_headroom + 2550 fwd_skb = skb_copy_expand(skb, local->tx_headroom +
2535 sdata->encrypt_headroom, 0, GFP_ATOMIC); 2551 sdata->encrypt_headroom, 0, GFP_ATOMIC);
2536 if (!fwd_skb) { 2552 if (!fwd_skb)
2537 net_info_ratelimited("%s: failed to clone mesh frame\n",
2538 sdata->name);
2539 goto out; 2553 goto out;
2540 }
2541 2554
2542 fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data; 2555 fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data;
2543 fwd_hdr->frame_control &= ~cpu_to_le16(IEEE80211_FCTL_RETRY); 2556 fwd_hdr->frame_control &= ~cpu_to_le16(IEEE80211_FCTL_RETRY);
@@ -2848,6 +2861,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
2848 case WLAN_HT_ACTION_SMPS: { 2861 case WLAN_HT_ACTION_SMPS: {
2849 struct ieee80211_supported_band *sband; 2862 struct ieee80211_supported_band *sband;
2850 enum ieee80211_smps_mode smps_mode; 2863 enum ieee80211_smps_mode smps_mode;
2864 struct sta_opmode_info sta_opmode = {};
2851 2865
2852 /* convert to HT capability */ 2866 /* convert to HT capability */
2853 switch (mgmt->u.action.u.ht_smps.smps_control) { 2867 switch (mgmt->u.action.u.ht_smps.smps_control) {
@@ -2868,17 +2882,24 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
2868 if (rx->sta->sta.smps_mode == smps_mode) 2882 if (rx->sta->sta.smps_mode == smps_mode)
2869 goto handled; 2883 goto handled;
2870 rx->sta->sta.smps_mode = smps_mode; 2884 rx->sta->sta.smps_mode = smps_mode;
2885 sta_opmode.smps_mode = smps_mode;
2886 sta_opmode.changed = STA_OPMODE_SMPS_MODE_CHANGED;
2871 2887
2872 sband = rx->local->hw.wiphy->bands[status->band]; 2888 sband = rx->local->hw.wiphy->bands[status->band];
2873 2889
2874 rate_control_rate_update(local, sband, rx->sta, 2890 rate_control_rate_update(local, sband, rx->sta,
2875 IEEE80211_RC_SMPS_CHANGED); 2891 IEEE80211_RC_SMPS_CHANGED);
2892 cfg80211_sta_opmode_change_notify(sdata->dev,
2893 rx->sta->addr,
2894 &sta_opmode,
2895 GFP_KERNEL);
2876 goto handled; 2896 goto handled;
2877 } 2897 }
2878 case WLAN_HT_ACTION_NOTIFY_CHANWIDTH: { 2898 case WLAN_HT_ACTION_NOTIFY_CHANWIDTH: {
2879 struct ieee80211_supported_band *sband; 2899 struct ieee80211_supported_band *sband;
2880 u8 chanwidth = mgmt->u.action.u.ht_notify_cw.chanwidth; 2900 u8 chanwidth = mgmt->u.action.u.ht_notify_cw.chanwidth;
2881 enum ieee80211_sta_rx_bandwidth max_bw, new_bw; 2901 enum ieee80211_sta_rx_bandwidth max_bw, new_bw;
2902 struct sta_opmode_info sta_opmode = {};
2882 2903
2883 /* If it doesn't support 40 MHz it can't change ... */ 2904 /* If it doesn't support 40 MHz it can't change ... */
2884 if (!(rx->sta->sta.ht_cap.cap & 2905 if (!(rx->sta->sta.ht_cap.cap &
@@ -2899,9 +2920,15 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
2899 2920
2900 rx->sta->sta.bandwidth = new_bw; 2921 rx->sta->sta.bandwidth = new_bw;
2901 sband = rx->local->hw.wiphy->bands[status->band]; 2922 sband = rx->local->hw.wiphy->bands[status->band];
2923 sta_opmode.bw = new_bw;
2924 sta_opmode.changed = STA_OPMODE_MAX_BW_CHANGED;
2902 2925
2903 rate_control_rate_update(local, sband, rx->sta, 2926 rate_control_rate_update(local, sband, rx->sta,
2904 IEEE80211_RC_BW_CHANGED); 2927 IEEE80211_RC_BW_CHANGED);
2928 cfg80211_sta_opmode_change_notify(sdata->dev,
2929 rx->sta->addr,
2930 &sta_opmode,
2931 GFP_KERNEL);
2905 goto handled; 2932 goto handled;
2906 } 2933 }
2907 default: 2934 default:
@@ -3731,15 +3758,6 @@ void ieee80211_check_fast_rx(struct sta_info *sta)
3731 3758
3732 switch (sdata->vif.type) { 3759 switch (sdata->vif.type) {
3733 case NL80211_IFTYPE_STATION: 3760 case NL80211_IFTYPE_STATION:
3734 /* 4-addr is harder to deal with, later maybe */
3735 if (sdata->u.mgd.use_4addr)
3736 goto clear;
3737 /* software powersave is a huge mess, avoid all of it */
3738 if (ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK))
3739 goto clear;
3740 if (ieee80211_hw_check(&local->hw, SUPPORTS_PS) &&
3741 !ieee80211_hw_check(&local->hw, SUPPORTS_DYNAMIC_PS))
3742 goto clear;
3743 if (sta->sta.tdls) { 3761 if (sta->sta.tdls) {
3744 fastrx.da_offs = offsetof(struct ieee80211_hdr, addr1); 3762 fastrx.da_offs = offsetof(struct ieee80211_hdr, addr1);
3745 fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr2); 3763 fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr2);
@@ -3751,6 +3769,23 @@ void ieee80211_check_fast_rx(struct sta_info *sta)
3751 fastrx.expected_ds_bits = 3769 fastrx.expected_ds_bits =
3752 cpu_to_le16(IEEE80211_FCTL_FROMDS); 3770 cpu_to_le16(IEEE80211_FCTL_FROMDS);
3753 } 3771 }
3772
3773 if (sdata->u.mgd.use_4addr && !sta->sta.tdls) {
3774 fastrx.expected_ds_bits |=
3775 cpu_to_le16(IEEE80211_FCTL_TODS);
3776 fastrx.da_offs = offsetof(struct ieee80211_hdr, addr3);
3777 fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr4);
3778 }
3779
3780 if (!sdata->u.mgd.powersave)
3781 break;
3782
3783 /* software powersave is a huge mess, avoid all of it */
3784 if (ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK))
3785 goto clear;
3786 if (ieee80211_hw_check(&local->hw, SUPPORTS_PS) &&
3787 !ieee80211_hw_check(&local->hw, SUPPORTS_DYNAMIC_PS))
3788 goto clear;
3754 break; 3789 break;
3755 case NL80211_IFTYPE_AP_VLAN: 3790 case NL80211_IFTYPE_AP_VLAN:
3756 case NL80211_IFTYPE_AP: 3791 case NL80211_IFTYPE_AP:
@@ -3767,6 +3802,15 @@ void ieee80211_check_fast_rx(struct sta_info *sta)
3767 !(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) && 3802 !(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) &&
3768 (sdata->vif.type != NL80211_IFTYPE_AP_VLAN || 3803 (sdata->vif.type != NL80211_IFTYPE_AP_VLAN ||
3769 !sdata->u.vlan.sta); 3804 !sdata->u.vlan.sta);
3805
3806 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
3807 sdata->u.vlan.sta) {
3808 fastrx.expected_ds_bits |=
3809 cpu_to_le16(IEEE80211_FCTL_FROMDS);
3810 fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr4);
3811 fastrx.internal_forward = 0;
3812 }
3813
3770 break; 3814 break;
3771 default: 3815 default:
3772 goto clear; 3816 goto clear;
@@ -3865,7 +3909,8 @@ static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx,
3865 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 3909 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
3866 struct sta_info *sta = rx->sta; 3910 struct sta_info *sta = rx->sta;
3867 int orig_len = skb->len; 3911 int orig_len = skb->len;
3868 int snap_offs = ieee80211_hdrlen(hdr->frame_control); 3912 int hdrlen = ieee80211_hdrlen(hdr->frame_control);
3913 int snap_offs = hdrlen;
3869 struct { 3914 struct {
3870 u8 snap[sizeof(rfc1042_header)]; 3915 u8 snap[sizeof(rfc1042_header)];
3871 __be16 proto; 3916 __be16 proto;
@@ -3896,10 +3941,6 @@ static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx,
3896 (status->flag & FAST_RX_CRYPT_FLAGS) != FAST_RX_CRYPT_FLAGS) 3941 (status->flag & FAST_RX_CRYPT_FLAGS) != FAST_RX_CRYPT_FLAGS)
3897 return false; 3942 return false;
3898 3943
3899 /* we don't deal with A-MSDU deaggregation here */
3900 if (status->rx_flags & IEEE80211_RX_AMSDU)
3901 return false;
3902
3903 if (unlikely(!ieee80211_is_data_present(hdr->frame_control))) 3944 if (unlikely(!ieee80211_is_data_present(hdr->frame_control)))
3904 return false; 3945 return false;
3905 3946
@@ -3931,21 +3972,24 @@ static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx,
3931 snap_offs += IEEE80211_CCMP_HDR_LEN; 3972 snap_offs += IEEE80211_CCMP_HDR_LEN;
3932 } 3973 }
3933 3974
3934 if (!pskb_may_pull(skb, snap_offs + sizeof(*payload))) 3975 if (!(status->rx_flags & IEEE80211_RX_AMSDU)) {
3935 goto drop; 3976 if (!pskb_may_pull(skb, snap_offs + sizeof(*payload)))
3936 payload = (void *)(skb->data + snap_offs); 3977 goto drop;
3937 3978
3938 if (!ether_addr_equal(payload->snap, fast_rx->rfc1042_hdr)) 3979 payload = (void *)(skb->data + snap_offs);
3939 return false;
3940 3980
3941 /* Don't handle these here since they require special code. 3981 if (!ether_addr_equal(payload->snap, fast_rx->rfc1042_hdr))
3942 * Accept AARP and IPX even though they should come with a 3982 return false;
3943 * bridge-tunnel header - but if we get them this way then 3983
3944 * there's little point in discarding them. 3984 /* Don't handle these here since they require special code.
3945 */ 3985 * Accept AARP and IPX even though they should come with a
3946 if (unlikely(payload->proto == cpu_to_be16(ETH_P_TDLS) || 3986 * bridge-tunnel header - but if we get them this way then
3947 payload->proto == fast_rx->control_port_protocol)) 3987 * there's little point in discarding them.
3948 return false; 3988 */
3989 if (unlikely(payload->proto == cpu_to_be16(ETH_P_TDLS) ||
3990 payload->proto == fast_rx->control_port_protocol))
3991 return false;
3992 }
3949 3993
3950 /* after this point, don't punt to the slowpath! */ 3994 /* after this point, don't punt to the slowpath! */
3951 3995
@@ -3959,12 +4003,6 @@ static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx,
3959 } 4003 }
3960 4004
3961 /* statistics part of ieee80211_rx_h_sta_process() */ 4005 /* statistics part of ieee80211_rx_h_sta_process() */
3962 stats->last_rx = jiffies;
3963 stats->last_rate = sta_stats_encode_rate(status);
3964
3965 stats->fragments++;
3966 stats->packets++;
3967
3968 if (!(status->flag & RX_FLAG_NO_SIGNAL_VAL)) { 4006 if (!(status->flag & RX_FLAG_NO_SIGNAL_VAL)) {
3969 stats->last_signal = status->signal; 4007 stats->last_signal = status->signal;
3970 if (!fast_rx->uses_rss) 4008 if (!fast_rx->uses_rss)
@@ -3993,6 +4031,20 @@ static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx,
3993 if (rx->key && !ieee80211_has_protected(hdr->frame_control)) 4031 if (rx->key && !ieee80211_has_protected(hdr->frame_control))
3994 goto drop; 4032 goto drop;
3995 4033
4034 if (status->rx_flags & IEEE80211_RX_AMSDU) {
4035 if (__ieee80211_rx_h_amsdu(rx, snap_offs - hdrlen) !=
4036 RX_QUEUED)
4037 goto drop;
4038
4039 return true;
4040 }
4041
4042 stats->last_rx = jiffies;
4043 stats->last_rate = sta_stats_encode_rate(status);
4044
4045 stats->fragments++;
4046 stats->packets++;
4047
3996 /* do the header conversion - first grab the addresses */ 4048 /* do the header conversion - first grab the addresses */
3997 ether_addr_copy(addrs.da, skb->data + fast_rx->da_offs); 4049 ether_addr_copy(addrs.da, skb->data + fast_rx->da_offs);
3998 ether_addr_copy(addrs.sa, skb->data + fast_rx->sa_offs); 4050 ether_addr_copy(addrs.sa, skb->data + fast_rx->sa_offs);
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index af0b608ee8ed..655c3d8b0d80 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -2288,6 +2288,12 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
2288 sinfo->filled |= BIT(NL80211_STA_INFO_EXPECTED_THROUGHPUT); 2288 sinfo->filled |= BIT(NL80211_STA_INFO_EXPECTED_THROUGHPUT);
2289 sinfo->expected_throughput = thr; 2289 sinfo->expected_throughput = thr;
2290 } 2290 }
2291
2292 if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL)) &&
2293 sta->status_stats.ack_signal_filled) {
2294 sinfo->ack_signal = sta->status_stats.last_ack_signal;
2295 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL);
2296 }
2291} 2297}
2292 2298
2293u32 sta_get_expected_throughput(struct sta_info *sta) 2299u32 sta_get_expected_throughput(struct sta_info *sta)
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index cd53619435b6..f64eb86ca64b 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -548,6 +548,8 @@ struct sta_info {
548 u64 msdu_retries[IEEE80211_NUM_TIDS + 1]; 548 u64 msdu_retries[IEEE80211_NUM_TIDS + 1];
549 u64 msdu_failed[IEEE80211_NUM_TIDS + 1]; 549 u64 msdu_failed[IEEE80211_NUM_TIDS + 1];
550 unsigned long last_ack; 550 unsigned long last_ack;
551 s8 last_ack_signal;
552 bool ack_signal_filled;
551 } status_stats; 553 } status_stats;
552 554
553 /* Updated from TX path only, no locking requirements */ 555 /* Updated from TX path only, no locking requirements */
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index da7427a41529..743e89c5926c 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -187,9 +187,16 @@ static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb)
187 struct ieee80211_mgmt *mgmt = (void *) skb->data; 187 struct ieee80211_mgmt *mgmt = (void *) skb->data;
188 struct ieee80211_local *local = sta->local; 188 struct ieee80211_local *local = sta->local;
189 struct ieee80211_sub_if_data *sdata = sta->sdata; 189 struct ieee80211_sub_if_data *sdata = sta->sdata;
190 struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
190 191
191 if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) 192 if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) {
192 sta->status_stats.last_ack = jiffies; 193 sta->status_stats.last_ack = jiffies;
194 if (txinfo->status.is_valid_ack_signal) {
195 sta->status_stats.last_ack_signal =
196 (s8)txinfo->status.ack_signal;
197 sta->status_stats.ack_signal_filled = true;
198 }
199 }
193 200
194 if (ieee80211_is_data_qos(mgmt->frame_control)) { 201 if (ieee80211_is_data_qos(mgmt->frame_control)) {
195 struct ieee80211_hdr *hdr = (void *) skb->data; 202 struct ieee80211_hdr *hdr = (void *) skb->data;
@@ -487,6 +494,8 @@ static void ieee80211_report_ack_skb(struct ieee80211_local *local,
487 ieee80211_is_qos_nullfunc(hdr->frame_control)) 494 ieee80211_is_qos_nullfunc(hdr->frame_control))
488 cfg80211_probe_status(sdata->dev, hdr->addr1, 495 cfg80211_probe_status(sdata->dev, hdr->addr1,
489 cookie, acked, 496 cookie, acked,
497 info->status.ack_signal,
498 info->status.is_valid_ack_signal,
490 GFP_ATOMIC); 499 GFP_ATOMIC);
491 else 500 else
492 cfg80211_mgmt_tx_status(&sdata->wdev, cookie, 501 cfg80211_mgmt_tx_status(&sdata->wdev, cookie,
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 69722504e3e1..933c67b5f845 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -797,7 +797,6 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx)
797{ 797{
798 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); 798 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
799 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; 799 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
800 u8 *qc;
801 int tid; 800 int tid;
802 801
803 /* 802 /*
@@ -844,9 +843,7 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx)
844 return TX_CONTINUE; 843 return TX_CONTINUE;
845 844
846 /* include per-STA, per-TID sequence counter */ 845 /* include per-STA, per-TID sequence counter */
847 846 tid = ieee80211_get_tid(hdr);
848 qc = ieee80211_get_qos_ctl(hdr);
849 tid = *qc & IEEE80211_QOS_CTL_TID_MASK;
850 tx->sta->tx_stats.msdu[tid]++; 847 tx->sta->tx_stats.msdu[tid]++;
851 848
852 hdr->seq_ctrl = ieee80211_tx_next_seq(tx->sta, tid); 849 hdr->seq_ctrl = ieee80211_tx_next_seq(tx->sta, tid);
@@ -1158,7 +1155,6 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
1158 struct ieee80211_hdr *hdr; 1155 struct ieee80211_hdr *hdr;
1159 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1156 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1160 int tid; 1157 int tid;
1161 u8 *qc;
1162 1158
1163 memset(tx, 0, sizeof(*tx)); 1159 memset(tx, 0, sizeof(*tx));
1164 tx->skb = skb; 1160 tx->skb = skb;
@@ -1198,8 +1194,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
1198 !ieee80211_hw_check(&local->hw, TX_AMPDU_SETUP_IN_HW)) { 1194 !ieee80211_hw_check(&local->hw, TX_AMPDU_SETUP_IN_HW)) {
1199 struct tid_ampdu_tx *tid_tx; 1195 struct tid_ampdu_tx *tid_tx;
1200 1196
1201 qc = ieee80211_get_qos_ctl(hdr); 1197 tid = ieee80211_get_tid(hdr);
1202 tid = *qc & IEEE80211_QOS_CTL_TID_MASK;
1203 1198
1204 tid_tx = rcu_dereference(tx->sta->ampdu_mlme.tid_tx[tid]); 1199 tid_tx = rcu_dereference(tx->sta->ampdu_mlme.tid_tx[tid]);
1205 if (tid_tx) { 1200 if (tid_tx) {
@@ -1921,7 +1916,7 @@ void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
1921{ 1916{
1922 struct ieee80211_local *local = sdata->local; 1917 struct ieee80211_local *local = sdata->local;
1923 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1918 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1924 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 1919 struct ieee80211_hdr *hdr;
1925 int headroom; 1920 int headroom;
1926 bool may_encrypt; 1921 bool may_encrypt;
1927 1922
diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c
index b9276ac849fa..5714dee76b12 100644
--- a/net/mac80211/vht.c
+++ b/net/mac80211/vht.c
@@ -447,6 +447,7 @@ u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
447 enum nl80211_band band) 447 enum nl80211_band band)
448{ 448{
449 enum ieee80211_sta_rx_bandwidth new_bw; 449 enum ieee80211_sta_rx_bandwidth new_bw;
450 struct sta_opmode_info sta_opmode = {};
450 u32 changed = 0; 451 u32 changed = 0;
451 u8 nss; 452 u8 nss;
452 453
@@ -460,7 +461,9 @@ u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
460 461
461 if (sta->sta.rx_nss != nss) { 462 if (sta->sta.rx_nss != nss) {
462 sta->sta.rx_nss = nss; 463 sta->sta.rx_nss = nss;
464 sta_opmode.rx_nss = nss;
463 changed |= IEEE80211_RC_NSS_CHANGED; 465 changed |= IEEE80211_RC_NSS_CHANGED;
466 sta_opmode.changed |= STA_OPMODE_N_SS_CHANGED;
464 } 467 }
465 468
466 switch (opmode & IEEE80211_OPMODE_NOTIF_CHANWIDTH_MASK) { 469 switch (opmode & IEEE80211_OPMODE_NOTIF_CHANWIDTH_MASK) {
@@ -481,9 +484,15 @@ u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
481 new_bw = ieee80211_sta_cur_vht_bw(sta); 484 new_bw = ieee80211_sta_cur_vht_bw(sta);
482 if (new_bw != sta->sta.bandwidth) { 485 if (new_bw != sta->sta.bandwidth) {
483 sta->sta.bandwidth = new_bw; 486 sta->sta.bandwidth = new_bw;
487 sta_opmode.bw = new_bw;
484 changed |= IEEE80211_RC_BW_CHANGED; 488 changed |= IEEE80211_RC_BW_CHANGED;
489 sta_opmode.changed |= STA_OPMODE_MAX_BW_CHANGED;
485 } 490 }
486 491
492 if (sta_opmode.changed)
493 cfg80211_sta_opmode_change_notify(sdata->dev, sta->addr,
494 &sta_opmode, GFP_KERNEL);
495
487 return changed; 496 return changed;
488} 497}
489 498
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 785056cb76f6..58d0b258b684 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -340,7 +340,7 @@ static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad)
340 a4_included = ieee80211_has_a4(hdr->frame_control); 340 a4_included = ieee80211_has_a4(hdr->frame_control);
341 341
342 if (ieee80211_is_data_qos(hdr->frame_control)) 342 if (ieee80211_is_data_qos(hdr->frame_control))
343 qos_tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; 343 qos_tid = ieee80211_get_tid(hdr);
344 else 344 else
345 qos_tid = 0; 345 qos_tid = 0;
346 346
@@ -601,8 +601,7 @@ static void gcmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *j_0, u8 *aad)
601 aad[23] = 0; 601 aad[23] = 0;
602 602
603 if (ieee80211_is_data_qos(hdr->frame_control)) 603 if (ieee80211_is_data_qos(hdr->frame_control))
604 qos_tid = *ieee80211_get_qos_ctl(hdr) & 604 qos_tid = ieee80211_get_tid(hdr);
605 IEEE80211_QOS_CTL_TID_MASK;
606 else 605 else
607 qos_tid = 0; 606 qos_tid = 0;
608 607
@@ -867,8 +866,7 @@ ieee80211_crypto_cs_decrypt(struct ieee80211_rx_data *rx)
867 return RX_DROP_UNUSABLE; 866 return RX_DROP_UNUSABLE;
868 867
869 if (ieee80211_is_data_qos(hdr->frame_control)) 868 if (ieee80211_is_data_qos(hdr->frame_control))
870 qos_tid = *ieee80211_get_qos_ctl(hdr) & 869 qos_tid = ieee80211_get_tid(hdr);
871 IEEE80211_QOS_CTL_TID_MASK;
872 else 870 else
873 qos_tid = 0; 871 qos_tid = 0;
874 872
diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
index 7a4de6d618b1..d4a89a8be013 100644
--- a/net/mpls/af_mpls.c
+++ b/net/mpls/af_mpls.c
@@ -2488,6 +2488,7 @@ static void mpls_net_exit(struct net *net)
2488static struct pernet_operations mpls_net_ops = { 2488static struct pernet_operations mpls_net_ops = {
2489 .init = mpls_net_init, 2489 .init = mpls_net_init,
2490 .exit = mpls_net_exit, 2490 .exit = mpls_net_exit,
2491 .async = true,
2491}; 2492};
2492 2493
2493static struct rtnl_af_ops mpls_af_ops __read_mostly = { 2494static struct rtnl_af_ops mpls_af_ops __read_mostly = {
diff --git a/net/ncsi/Makefile b/net/ncsi/Makefile
index dd12b564f2e7..436ef68331f2 100644
--- a/net/ncsi/Makefile
+++ b/net/ncsi/Makefile
@@ -1,4 +1,4 @@
1# 1#
2# Makefile for NCSI API 2# Makefile for NCSI API
3# 3#
4obj-$(CONFIG_NET_NCSI) += ncsi-cmd.o ncsi-rsp.o ncsi-aen.o ncsi-manage.o 4obj-$(CONFIG_NET_NCSI) += ncsi-cmd.o ncsi-rsp.o ncsi-aen.o ncsi-manage.o ncsi-netlink.o
diff --git a/net/ncsi/internal.h b/net/ncsi/internal.h
index d30f7bd741d0..8da84312cd3b 100644
--- a/net/ncsi/internal.h
+++ b/net/ncsi/internal.h
@@ -276,6 +276,8 @@ struct ncsi_dev_priv {
276 unsigned int package_num; /* Number of packages */ 276 unsigned int package_num; /* Number of packages */
277 struct list_head packages; /* List of packages */ 277 struct list_head packages; /* List of packages */
278 struct ncsi_channel *hot_channel; /* Channel was ever active */ 278 struct ncsi_channel *hot_channel; /* Channel was ever active */
279 struct ncsi_package *force_package; /* Force a specific package */
280 struct ncsi_channel *force_channel; /* Force a specific channel */
279 struct ncsi_request requests[256]; /* Request table */ 281 struct ncsi_request requests[256]; /* Request table */
280 unsigned int request_id; /* Last used request ID */ 282 unsigned int request_id; /* Last used request ID */
281#define NCSI_REQ_START_IDX 1 283#define NCSI_REQ_START_IDX 1
@@ -318,6 +320,7 @@ extern spinlock_t ncsi_dev_lock;
318 list_for_each_entry_rcu(nc, &np->channels, node) 320 list_for_each_entry_rcu(nc, &np->channels, node)
319 321
320/* Resources */ 322/* Resources */
323u32 *ncsi_get_filter(struct ncsi_channel *nc, int table, int index);
321int ncsi_find_filter(struct ncsi_channel *nc, int table, void *data); 324int ncsi_find_filter(struct ncsi_channel *nc, int table, void *data);
322int ncsi_add_filter(struct ncsi_channel *nc, int table, void *data); 325int ncsi_add_filter(struct ncsi_channel *nc, int table, void *data);
323int ncsi_remove_filter(struct ncsi_channel *nc, int table, int index); 326int ncsi_remove_filter(struct ncsi_channel *nc, int table, int index);
diff --git a/net/ncsi/ncsi-manage.c b/net/ncsi/ncsi-manage.c
index c989211bbabc..c3695ba0cf94 100644
--- a/net/ncsi/ncsi-manage.c
+++ b/net/ncsi/ncsi-manage.c
@@ -12,7 +12,6 @@
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/netdevice.h> 13#include <linux/netdevice.h>
14#include <linux/skbuff.h> 14#include <linux/skbuff.h>
15#include <linux/netlink.h>
16 15
17#include <net/ncsi.h> 16#include <net/ncsi.h>
18#include <net/net_namespace.h> 17#include <net/net_namespace.h>
@@ -23,6 +22,7 @@
23 22
24#include "internal.h" 23#include "internal.h"
25#include "ncsi-pkt.h" 24#include "ncsi-pkt.h"
25#include "ncsi-netlink.h"
26 26
27LIST_HEAD(ncsi_dev_list); 27LIST_HEAD(ncsi_dev_list);
28DEFINE_SPINLOCK(ncsi_dev_lock); 28DEFINE_SPINLOCK(ncsi_dev_lock);
@@ -38,7 +38,7 @@ static inline int ncsi_filter_size(int table)
38 return sizes[table]; 38 return sizes[table];
39} 39}
40 40
41static u32 *ncsi_get_filter(struct ncsi_channel *nc, int table, int index) 41u32 *ncsi_get_filter(struct ncsi_channel *nc, int table, int index)
42{ 42{
43 struct ncsi_channel_filter *ncf; 43 struct ncsi_channel_filter *ncf;
44 int size; 44 int size;
@@ -965,20 +965,37 @@ error:
965 965
966static int ncsi_choose_active_channel(struct ncsi_dev_priv *ndp) 966static int ncsi_choose_active_channel(struct ncsi_dev_priv *ndp)
967{ 967{
968 struct ncsi_package *np; 968 struct ncsi_package *np, *force_package;
969 struct ncsi_channel *nc, *found, *hot_nc; 969 struct ncsi_channel *nc, *found, *hot_nc, *force_channel;
970 struct ncsi_channel_mode *ncm; 970 struct ncsi_channel_mode *ncm;
971 unsigned long flags; 971 unsigned long flags;
972 972
973 spin_lock_irqsave(&ndp->lock, flags); 973 spin_lock_irqsave(&ndp->lock, flags);
974 hot_nc = ndp->hot_channel; 974 hot_nc = ndp->hot_channel;
975 force_channel = ndp->force_channel;
976 force_package = ndp->force_package;
975 spin_unlock_irqrestore(&ndp->lock, flags); 977 spin_unlock_irqrestore(&ndp->lock, flags);
976 978
979 /* Force a specific channel whether or not it has link if we have been
980 * configured to do so
981 */
982 if (force_package && force_channel) {
983 found = force_channel;
984 ncm = &found->modes[NCSI_MODE_LINK];
985 if (!(ncm->data[2] & 0x1))
986 netdev_info(ndp->ndev.dev,
987 "NCSI: Channel %u forced, but it is link down\n",
988 found->id);
989 goto out;
990 }
991
977 /* The search is done once an inactive channel with up 992 /* The search is done once an inactive channel with up
978 * link is found. 993 * link is found.
979 */ 994 */
980 found = NULL; 995 found = NULL;
981 NCSI_FOR_EACH_PACKAGE(ndp, np) { 996 NCSI_FOR_EACH_PACKAGE(ndp, np) {
997 if (ndp->force_package && np != ndp->force_package)
998 continue;
982 NCSI_FOR_EACH_CHANNEL(np, nc) { 999 NCSI_FOR_EACH_CHANNEL(np, nc) {
983 spin_lock_irqsave(&nc->lock, flags); 1000 spin_lock_irqsave(&nc->lock, flags);
984 1001
@@ -1594,6 +1611,9 @@ struct ncsi_dev *ncsi_register_dev(struct net_device *dev,
1594 ndp->ptype.dev = dev; 1611 ndp->ptype.dev = dev;
1595 dev_add_pack(&ndp->ptype); 1612 dev_add_pack(&ndp->ptype);
1596 1613
1614 /* Set up generic netlink interface */
1615 ncsi_init_netlink(dev);
1616
1597 return nd; 1617 return nd;
1598} 1618}
1599EXPORT_SYMBOL_GPL(ncsi_register_dev); 1619EXPORT_SYMBOL_GPL(ncsi_register_dev);
@@ -1673,6 +1693,8 @@ void ncsi_unregister_dev(struct ncsi_dev *nd)
1673#endif 1693#endif
1674 spin_unlock_irqrestore(&ncsi_dev_lock, flags); 1694 spin_unlock_irqrestore(&ncsi_dev_lock, flags);
1675 1695
1696 ncsi_unregister_netlink(nd->dev);
1697
1676 kfree(ndp); 1698 kfree(ndp);
1677} 1699}
1678EXPORT_SYMBOL_GPL(ncsi_unregister_dev); 1700EXPORT_SYMBOL_GPL(ncsi_unregister_dev);
diff --git a/net/ncsi/ncsi-netlink.c b/net/ncsi/ncsi-netlink.c
new file mode 100644
index 000000000000..05fcfb4fbe1d
--- /dev/null
+++ b/net/ncsi/ncsi-netlink.c
@@ -0,0 +1,423 @@
1/*
2 * Copyright Samuel Mendoza-Jonas, IBM Corporation 2018.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 */
9
10#include <linux/module.h>
11#include <linux/kernel.h>
12#include <linux/if_arp.h>
13#include <linux/rtnetlink.h>
14#include <linux/etherdevice.h>
15#include <linux/module.h>
16#include <net/genetlink.h>
17#include <net/ncsi.h>
18#include <linux/skbuff.h>
19#include <net/sock.h>
20#include <uapi/linux/ncsi.h>
21
22#include "internal.h"
23#include "ncsi-netlink.h"
24
25static struct genl_family ncsi_genl_family;
26
27static const struct nla_policy ncsi_genl_policy[NCSI_ATTR_MAX + 1] = {
28 [NCSI_ATTR_IFINDEX] = { .type = NLA_U32 },
29 [NCSI_ATTR_PACKAGE_LIST] = { .type = NLA_NESTED },
30 [NCSI_ATTR_PACKAGE_ID] = { .type = NLA_U32 },
31 [NCSI_ATTR_CHANNEL_ID] = { .type = NLA_U32 },
32};
33
34static struct ncsi_dev_priv *ndp_from_ifindex(struct net *net, u32 ifindex)
35{
36 struct ncsi_dev_priv *ndp;
37 struct net_device *dev;
38 struct ncsi_dev *nd;
39 struct ncsi_dev;
40
41 if (!net)
42 return NULL;
43
44 dev = dev_get_by_index(net, ifindex);
45 if (!dev) {
46 pr_err("NCSI netlink: No device for ifindex %u\n", ifindex);
47 return NULL;
48 }
49
50 nd = ncsi_find_dev(dev);
51 ndp = nd ? TO_NCSI_DEV_PRIV(nd) : NULL;
52
53 dev_put(dev);
54 return ndp;
55}
56
57static int ncsi_write_channel_info(struct sk_buff *skb,
58 struct ncsi_dev_priv *ndp,
59 struct ncsi_channel *nc)
60{
61 struct nlattr *vid_nest;
62 struct ncsi_channel_filter *ncf;
63 struct ncsi_channel_mode *m;
64 u32 *data;
65 int i;
66
67 nla_put_u32(skb, NCSI_CHANNEL_ATTR_ID, nc->id);
68 m = &nc->modes[NCSI_MODE_LINK];
69 nla_put_u32(skb, NCSI_CHANNEL_ATTR_LINK_STATE, m->data[2]);
70 if (nc->state == NCSI_CHANNEL_ACTIVE)
71 nla_put_flag(skb, NCSI_CHANNEL_ATTR_ACTIVE);
72 if (ndp->force_channel == nc)
73 nla_put_flag(skb, NCSI_CHANNEL_ATTR_FORCED);
74
75 nla_put_u32(skb, NCSI_CHANNEL_ATTR_VERSION_MAJOR, nc->version.version);
76 nla_put_u32(skb, NCSI_CHANNEL_ATTR_VERSION_MINOR, nc->version.alpha2);
77 nla_put_string(skb, NCSI_CHANNEL_ATTR_VERSION_STR, nc->version.fw_name);
78
79 vid_nest = nla_nest_start(skb, NCSI_CHANNEL_ATTR_VLAN_LIST);
80 if (!vid_nest)
81 return -ENOMEM;
82 ncf = nc->filters[NCSI_FILTER_VLAN];
83 i = -1;
84 if (ncf) {
85 while ((i = find_next_bit((void *)&ncf->bitmap, ncf->total,
86 i + 1)) < ncf->total) {
87 data = ncsi_get_filter(nc, NCSI_FILTER_VLAN, i);
88 /* Uninitialised channels will have 'zero' vlan ids */
89 if (!data || !*data)
90 continue;
91 nla_put_u16(skb, NCSI_CHANNEL_ATTR_VLAN_ID,
92 *(u16 *)data);
93 }
94 }
95 nla_nest_end(skb, vid_nest);
96
97 return 0;
98}
99
100static int ncsi_write_package_info(struct sk_buff *skb,
101 struct ncsi_dev_priv *ndp, unsigned int id)
102{
103 struct nlattr *pnest, *cnest, *nest;
104 struct ncsi_package *np;
105 struct ncsi_channel *nc;
106 bool found;
107 int rc;
108
109 if (id > ndp->package_num) {
110 netdev_info(ndp->ndev.dev, "NCSI: No package with id %u\n", id);
111 return -ENODEV;
112 }
113
114 found = false;
115 NCSI_FOR_EACH_PACKAGE(ndp, np) {
116 if (np->id != id)
117 continue;
118 pnest = nla_nest_start(skb, NCSI_PKG_ATTR);
119 if (!pnest)
120 return -ENOMEM;
121 nla_put_u32(skb, NCSI_PKG_ATTR_ID, np->id);
122 if (ndp->force_package == np)
123 nla_put_flag(skb, NCSI_PKG_ATTR_FORCED);
124 cnest = nla_nest_start(skb, NCSI_PKG_ATTR_CHANNEL_LIST);
125 if (!cnest) {
126 nla_nest_cancel(skb, pnest);
127 return -ENOMEM;
128 }
129 NCSI_FOR_EACH_CHANNEL(np, nc) {
130 nest = nla_nest_start(skb, NCSI_CHANNEL_ATTR);
131 if (!nest) {
132 nla_nest_cancel(skb, cnest);
133 nla_nest_cancel(skb, pnest);
134 return -ENOMEM;
135 }
136 rc = ncsi_write_channel_info(skb, ndp, nc);
137 if (rc) {
138 nla_nest_cancel(skb, nest);
139 nla_nest_cancel(skb, cnest);
140 nla_nest_cancel(skb, pnest);
141 return rc;
142 }
143 nla_nest_end(skb, nest);
144 }
145 nla_nest_end(skb, cnest);
146 nla_nest_end(skb, pnest);
147 found = true;
148 }
149
150 if (!found)
151 return -ENODEV;
152
153 return 0;
154}
155
156static int ncsi_pkg_info_nl(struct sk_buff *msg, struct genl_info *info)
157{
158 struct ncsi_dev_priv *ndp;
159 unsigned int package_id;
160 struct sk_buff *skb;
161 struct nlattr *attr;
162 void *hdr;
163 int rc;
164
165 if (!info || !info->attrs)
166 return -EINVAL;
167
168 if (!info->attrs[NCSI_ATTR_IFINDEX])
169 return -EINVAL;
170
171 if (!info->attrs[NCSI_ATTR_PACKAGE_ID])
172 return -EINVAL;
173
174 ndp = ndp_from_ifindex(genl_info_net(info),
175 nla_get_u32(info->attrs[NCSI_ATTR_IFINDEX]));
176 if (!ndp)
177 return -ENODEV;
178
179 skb = genlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
180 if (!skb)
181 return -ENOMEM;
182
183 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
184 &ncsi_genl_family, 0, NCSI_CMD_PKG_INFO);
185 if (!hdr) {
186 kfree_skb(skb);
187 return -EMSGSIZE;
188 }
189
190 package_id = nla_get_u32(info->attrs[NCSI_ATTR_PACKAGE_ID]);
191
192 attr = nla_nest_start(skb, NCSI_ATTR_PACKAGE_LIST);
193 rc = ncsi_write_package_info(skb, ndp, package_id);
194
195 if (rc) {
196 nla_nest_cancel(skb, attr);
197 goto err;
198 }
199
200 nla_nest_end(skb, attr);
201
202 genlmsg_end(skb, hdr);
203 return genlmsg_reply(skb, info);
204
205err:
206 genlmsg_cancel(skb, hdr);
207 kfree_skb(skb);
208 return rc;
209}
210
211static int ncsi_pkg_info_all_nl(struct sk_buff *skb,
212 struct netlink_callback *cb)
213{
214 struct nlattr *attrs[NCSI_ATTR_MAX];
215 struct ncsi_package *np, *package;
216 struct ncsi_dev_priv *ndp;
217 unsigned int package_id;
218 struct nlattr *attr;
219 void *hdr;
220 int rc;
221
222 rc = genlmsg_parse(cb->nlh, &ncsi_genl_family, attrs, NCSI_ATTR_MAX,
223 ncsi_genl_policy, NULL);
224 if (rc)
225 return rc;
226
227 if (!attrs[NCSI_ATTR_IFINDEX])
228 return -EINVAL;
229
230 ndp = ndp_from_ifindex(get_net(sock_net(skb->sk)),
231 nla_get_u32(attrs[NCSI_ATTR_IFINDEX]));
232
233 if (!ndp)
234 return -ENODEV;
235
236 package_id = cb->args[0];
237 package = NULL;
238 NCSI_FOR_EACH_PACKAGE(ndp, np)
239 if (np->id == package_id)
240 package = np;
241
242 if (!package)
243 return 0; /* done */
244
245 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
246 &ncsi_genl_family, 0, NCSI_CMD_PKG_INFO);
247 if (!hdr) {
248 rc = -EMSGSIZE;
249 goto err;
250 }
251
252 attr = nla_nest_start(skb, NCSI_ATTR_PACKAGE_LIST);
253 rc = ncsi_write_package_info(skb, ndp, package->id);
254 if (rc) {
255 nla_nest_cancel(skb, attr);
256 goto err;
257 }
258
259 nla_nest_end(skb, attr);
260 genlmsg_end(skb, hdr);
261
262 cb->args[0] = package_id + 1;
263
264 return skb->len;
265err:
266 genlmsg_cancel(skb, hdr);
267 return rc;
268}
269
270static int ncsi_set_interface_nl(struct sk_buff *msg, struct genl_info *info)
271{
272 struct ncsi_package *np, *package;
273 struct ncsi_channel *nc, *channel;
274 u32 package_id, channel_id;
275 struct ncsi_dev_priv *ndp;
276 unsigned long flags;
277
278 if (!info || !info->attrs)
279 return -EINVAL;
280
281 if (!info->attrs[NCSI_ATTR_IFINDEX])
282 return -EINVAL;
283
284 if (!info->attrs[NCSI_ATTR_PACKAGE_ID])
285 return -EINVAL;
286
287 ndp = ndp_from_ifindex(get_net(sock_net(msg->sk)),
288 nla_get_u32(info->attrs[NCSI_ATTR_IFINDEX]));
289 if (!ndp)
290 return -ENODEV;
291
292 package_id = nla_get_u32(info->attrs[NCSI_ATTR_PACKAGE_ID]);
293 package = NULL;
294
295 spin_lock_irqsave(&ndp->lock, flags);
296
297 NCSI_FOR_EACH_PACKAGE(ndp, np)
298 if (np->id == package_id)
299 package = np;
300 if (!package) {
301 /* The user has set a package that does not exist */
302 spin_unlock_irqrestore(&ndp->lock, flags);
303 return -ERANGE;
304 }
305
306 channel = NULL;
307 if (!info->attrs[NCSI_ATTR_CHANNEL_ID]) {
308 /* Allow any channel */
309 channel_id = NCSI_RESERVED_CHANNEL;
310 } else {
311 channel_id = nla_get_u32(info->attrs[NCSI_ATTR_CHANNEL_ID]);
312 NCSI_FOR_EACH_CHANNEL(package, nc)
313 if (nc->id == channel_id)
314 channel = nc;
315 }
316
317 if (channel_id != NCSI_RESERVED_CHANNEL && !channel) {
318 /* The user has set a channel that does not exist on this
319 * package
320 */
321 spin_unlock_irqrestore(&ndp->lock, flags);
322 netdev_info(ndp->ndev.dev, "NCSI: Channel %u does not exist!\n",
323 channel_id);
324 return -ERANGE;
325 }
326
327 ndp->force_package = package;
328 ndp->force_channel = channel;
329 spin_unlock_irqrestore(&ndp->lock, flags);
330
331 netdev_info(ndp->ndev.dev, "Set package 0x%x, channel 0x%x%s as preferred\n",
332 package_id, channel_id,
333 channel_id == NCSI_RESERVED_CHANNEL ? " (any)" : "");
334
335 /* Bounce the NCSI channel to set changes */
336 ncsi_stop_dev(&ndp->ndev);
337 ncsi_start_dev(&ndp->ndev);
338
339 return 0;
340}
341
342static int ncsi_clear_interface_nl(struct sk_buff *msg, struct genl_info *info)
343{
344 struct ncsi_dev_priv *ndp;
345 unsigned long flags;
346
347 if (!info || !info->attrs)
348 return -EINVAL;
349
350 if (!info->attrs[NCSI_ATTR_IFINDEX])
351 return -EINVAL;
352
353 ndp = ndp_from_ifindex(get_net(sock_net(msg->sk)),
354 nla_get_u32(info->attrs[NCSI_ATTR_IFINDEX]));
355 if (!ndp)
356 return -ENODEV;
357
358 /* Clear any override */
359 spin_lock_irqsave(&ndp->lock, flags);
360 ndp->force_package = NULL;
361 ndp->force_channel = NULL;
362 spin_unlock_irqrestore(&ndp->lock, flags);
363 netdev_info(ndp->ndev.dev, "NCSI: Cleared preferred package/channel\n");
364
365 /* Bounce the NCSI channel to set changes */
366 ncsi_stop_dev(&ndp->ndev);
367 ncsi_start_dev(&ndp->ndev);
368
369 return 0;
370}
371
372static const struct genl_ops ncsi_ops[] = {
373 {
374 .cmd = NCSI_CMD_PKG_INFO,
375 .policy = ncsi_genl_policy,
376 .doit = ncsi_pkg_info_nl,
377 .dumpit = ncsi_pkg_info_all_nl,
378 .flags = 0,
379 },
380 {
381 .cmd = NCSI_CMD_SET_INTERFACE,
382 .policy = ncsi_genl_policy,
383 .doit = ncsi_set_interface_nl,
384 .flags = GENL_ADMIN_PERM,
385 },
386 {
387 .cmd = NCSI_CMD_CLEAR_INTERFACE,
388 .policy = ncsi_genl_policy,
389 .doit = ncsi_clear_interface_nl,
390 .flags = GENL_ADMIN_PERM,
391 },
392};
393
394static struct genl_family ncsi_genl_family __ro_after_init = {
395 .name = "NCSI",
396 .version = 0,
397 .maxattr = NCSI_ATTR_MAX,
398 .module = THIS_MODULE,
399 .ops = ncsi_ops,
400 .n_ops = ARRAY_SIZE(ncsi_ops),
401};
402
403int ncsi_init_netlink(struct net_device *dev)
404{
405 int rc;
406
407 rc = genl_register_family(&ncsi_genl_family);
408 if (rc)
409 netdev_err(dev, "ncsi: failed to register netlink family\n");
410
411 return rc;
412}
413
414int ncsi_unregister_netlink(struct net_device *dev)
415{
416 int rc;
417
418 rc = genl_unregister_family(&ncsi_genl_family);
419 if (rc)
420 netdev_err(dev, "ncsi: failed to unregister netlink family\n");
421
422 return rc;
423}
diff --git a/net/ncsi/ncsi-netlink.h b/net/ncsi/ncsi-netlink.h
new file mode 100644
index 000000000000..91a5c256f8c4
--- /dev/null
+++ b/net/ncsi/ncsi-netlink.h
@@ -0,0 +1,20 @@
1/*
2 * Copyright Samuel Mendoza-Jonas, IBM Corporation 2018.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 */
9
10#ifndef __NCSI_NETLINK_H__
11#define __NCSI_NETLINK_H__
12
13#include <linux/netdevice.h>
14
15#include "internal.h"
16
17int ncsi_init_netlink(struct net_device *dev);
18int ncsi_unregister_netlink(struct net_device *dev);
19
20#endif /* __NCSI_NETLINK_H__ */
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index 0f6b8172fb9a..d72cc786c7b7 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -629,6 +629,7 @@ static void __net_exit netfilter_net_exit(struct net *net)
629static struct pernet_operations netfilter_net_ops = { 629static struct pernet_operations netfilter_net_ops = {
630 .init = netfilter_net_init, 630 .init = netfilter_net_init,
631 .exit = netfilter_net_exit, 631 .exit = netfilter_net_exit,
632 .async = true,
632}; 633};
633 634
634int __init netfilter_init(void) 635int __init netfilter_init(void)
diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
index 975a85a48d39..2523ebe2b3cc 100644
--- a/net/netfilter/ipset/ip_set_core.c
+++ b/net/netfilter/ipset/ip_set_core.c
@@ -2094,7 +2094,8 @@ static struct pernet_operations ip_set_net_ops = {
2094 .init = ip_set_net_init, 2094 .init = ip_set_net_init,
2095 .exit = ip_set_net_exit, 2095 .exit = ip_set_net_exit,
2096 .id = &ip_set_net_id, 2096 .id = &ip_set_net_id,
2097 .size = sizeof(struct ip_set_net) 2097 .size = sizeof(struct ip_set_net),
2098 .async = true,
2098}; 2099};
2099 2100
2100static int __init 2101static int __init
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index 5f6f73cf2174..6a6cb9db030b 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -2289,10 +2289,12 @@ static struct pernet_operations ipvs_core_ops = {
2289 .exit = __ip_vs_cleanup, 2289 .exit = __ip_vs_cleanup,
2290 .id = &ip_vs_net_id, 2290 .id = &ip_vs_net_id,
2291 .size = sizeof(struct netns_ipvs), 2291 .size = sizeof(struct netns_ipvs),
2292 .async = true,
2292}; 2293};
2293 2294
2294static struct pernet_operations ipvs_core_dev_ops = { 2295static struct pernet_operations ipvs_core_dev_ops = {
2295 .exit = __ip_vs_dev_cleanup, 2296 .exit = __ip_vs_dev_cleanup,
2297 .async = true,
2296}; 2298};
2297 2299
2298/* 2300/*
diff --git a/net/netfilter/ipvs/ip_vs_ftp.c b/net/netfilter/ipvs/ip_vs_ftp.c
index 58d5d05aec24..8b25aab41928 100644
--- a/net/netfilter/ipvs/ip_vs_ftp.c
+++ b/net/netfilter/ipvs/ip_vs_ftp.c
@@ -479,6 +479,7 @@ static void __ip_vs_ftp_exit(struct net *net)
479static struct pernet_operations ip_vs_ftp_ops = { 479static struct pernet_operations ip_vs_ftp_ops = {
480 .init = __ip_vs_ftp_init, 480 .init = __ip_vs_ftp_init,
481 .exit = __ip_vs_ftp_exit, 481 .exit = __ip_vs_ftp_exit,
482 .async = true,
482}; 483};
483 484
484static int __init ip_vs_ftp_init(void) 485static int __init ip_vs_ftp_init(void)
diff --git a/net/netfilter/ipvs/ip_vs_lblc.c b/net/netfilter/ipvs/ip_vs_lblc.c
index d625179de485..6a340c94c4b8 100644
--- a/net/netfilter/ipvs/ip_vs_lblc.c
+++ b/net/netfilter/ipvs/ip_vs_lblc.c
@@ -604,6 +604,7 @@ static void __net_exit __ip_vs_lblc_exit(struct net *net) { }
604static struct pernet_operations ip_vs_lblc_ops = { 604static struct pernet_operations ip_vs_lblc_ops = {
605 .init = __ip_vs_lblc_init, 605 .init = __ip_vs_lblc_init,
606 .exit = __ip_vs_lblc_exit, 606 .exit = __ip_vs_lblc_exit,
607 .async = true,
607}; 608};
608 609
609static int __init ip_vs_lblc_init(void) 610static int __init ip_vs_lblc_init(void)
diff --git a/net/netfilter/ipvs/ip_vs_lblcr.c b/net/netfilter/ipvs/ip_vs_lblcr.c
index 84c57b62a588..0627881128da 100644
--- a/net/netfilter/ipvs/ip_vs_lblcr.c
+++ b/net/netfilter/ipvs/ip_vs_lblcr.c
@@ -789,6 +789,7 @@ static void __net_exit __ip_vs_lblcr_exit(struct net *net) { }
789static struct pernet_operations ip_vs_lblcr_ops = { 789static struct pernet_operations ip_vs_lblcr_ops = {
790 .init = __ip_vs_lblcr_init, 790 .init = __ip_vs_lblcr_init,
791 .exit = __ip_vs_lblcr_exit, 791 .exit = __ip_vs_lblcr_exit,
792 .async = true,
792}; 793};
793 794
794static int __init ip_vs_lblcr_init(void) 795static int __init ip_vs_lblcr_init(void)
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index dd177ebee9aa..8884d302d33a 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -3417,6 +3417,7 @@ static void __net_exit ctnetlink_net_exit_batch(struct list_head *net_exit_list)
3417static struct pernet_operations ctnetlink_net_ops = { 3417static struct pernet_operations ctnetlink_net_ops = {
3418 .init = ctnetlink_net_init, 3418 .init = ctnetlink_net_init,
3419 .exit_batch = ctnetlink_net_exit_batch, 3419 .exit_batch = ctnetlink_net_exit_batch,
3420 .async = true,
3420}; 3421};
3421 3422
3422static int __init ctnetlink_init(void) 3423static int __init ctnetlink_init(void)
diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c
index d049ea5a3770..9bcd72fe91f9 100644
--- a/net/netfilter/nf_conntrack_proto_gre.c
+++ b/net/netfilter/nf_conntrack_proto_gre.c
@@ -406,6 +406,7 @@ static struct pernet_operations proto_gre_net_ops = {
406 .exit = proto_gre_net_exit, 406 .exit = proto_gre_net_exit,
407 .id = &proto_gre_net_id, 407 .id = &proto_gre_net_id,
408 .size = sizeof(struct netns_proto_gre), 408 .size = sizeof(struct netns_proto_gre),
409 .async = true,
409}; 410};
410 411
411static int __init nf_ct_proto_gre_init(void) 412static int __init nf_ct_proto_gre_init(void)
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index 9123fdec5e14..3cdce391362e 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -705,6 +705,7 @@ static void nf_conntrack_pernet_exit(struct list_head *net_exit_list)
705static struct pernet_operations nf_conntrack_net_ops = { 705static struct pernet_operations nf_conntrack_net_ops = {
706 .init = nf_conntrack_pernet_init, 706 .init = nf_conntrack_pernet_init,
707 .exit_batch = nf_conntrack_pernet_exit, 707 .exit_batch = nf_conntrack_pernet_exit,
708 .async = true,
708}; 709};
709 710
710static int __init nf_conntrack_standalone_init(void) 711static int __init nf_conntrack_standalone_init(void)
diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
index c2c1b16b7538..1ba3da51050d 100644
--- a/net/netfilter/nf_log.c
+++ b/net/netfilter/nf_log.c
@@ -577,6 +577,7 @@ static void __net_exit nf_log_net_exit(struct net *net)
577static struct pernet_operations nf_log_net_ops = { 577static struct pernet_operations nf_log_net_ops = {
578 .init = nf_log_net_init, 578 .init = nf_log_net_init,
579 .exit = nf_log_net_exit, 579 .exit = nf_log_net_exit,
580 .async = true,
580}; 581};
581 582
582int __init netfilter_log_init(void) 583int __init netfilter_log_init(void)
diff --git a/net/netfilter/nf_log_netdev.c b/net/netfilter/nf_log_netdev.c
index 350eb147754d..254c2c6bde48 100644
--- a/net/netfilter/nf_log_netdev.c
+++ b/net/netfilter/nf_log_netdev.c
@@ -47,6 +47,7 @@ static void __net_exit nf_log_netdev_net_exit(struct net *net)
47static struct pernet_operations nf_log_netdev_net_ops = { 47static struct pernet_operations nf_log_netdev_net_ops = {
48 .init = nf_log_netdev_net_init, 48 .init = nf_log_netdev_net_init,
49 .exit = nf_log_netdev_net_exit, 49 .exit = nf_log_netdev_net_exit,
50 .async = true,
50}; 51};
51 52
52static int __init nf_log_netdev_init(void) 53static int __init nf_log_netdev_init(void)
diff --git a/net/netfilter/nf_synproxy_core.c b/net/netfilter/nf_synproxy_core.c
index 92139a087260..64b875e452ca 100644
--- a/net/netfilter/nf_synproxy_core.c
+++ b/net/netfilter/nf_synproxy_core.c
@@ -398,6 +398,7 @@ static struct pernet_operations synproxy_net_ops = {
398 .exit = synproxy_net_exit, 398 .exit = synproxy_net_exit,
399 .id = &synproxy_net_id, 399 .id = &synproxy_net_id,
400 .size = sizeof(struct synproxy_net), 400 .size = sizeof(struct synproxy_net),
401 .async = true,
401}; 402};
402 403
403static int __init synproxy_core_init(void) 404static int __init synproxy_core_init(void)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index c4acc7340eb1..fd13d28e4ca7 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -6597,6 +6597,7 @@ static void __net_exit nf_tables_exit_net(struct net *net)
6597static struct pernet_operations nf_tables_net_ops = { 6597static struct pernet_operations nf_tables_net_ops = {
6598 .init = nf_tables_init_net, 6598 .init = nf_tables_init_net,
6599 .exit = nf_tables_exit_net, 6599 .exit = nf_tables_exit_net,
6600 .async = true,
6600}; 6601};
6601 6602
6602static int __init nf_tables_module_init(void) 6603static int __init nf_tables_module_init(void)
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index 03ead8a9e90c..84fc4954862d 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -566,6 +566,7 @@ static void __net_exit nfnetlink_net_exit_batch(struct list_head *net_exit_list)
566static struct pernet_operations nfnetlink_net_ops = { 566static struct pernet_operations nfnetlink_net_ops = {
567 .init = nfnetlink_net_init, 567 .init = nfnetlink_net_init,
568 .exit_batch = nfnetlink_net_exit_batch, 568 .exit_batch = nfnetlink_net_exit_batch,
569 .async = true,
569}; 570};
570 571
571static int __init nfnetlink_init(void) 572static int __init nfnetlink_init(void)
diff --git a/net/netfilter/nfnetlink_acct.c b/net/netfilter/nfnetlink_acct.c
index 88d427f9f9e6..8d9f18bb8840 100644
--- a/net/netfilter/nfnetlink_acct.c
+++ b/net/netfilter/nfnetlink_acct.c
@@ -515,6 +515,7 @@ static void __net_exit nfnl_acct_net_exit(struct net *net)
515static struct pernet_operations nfnl_acct_ops = { 515static struct pernet_operations nfnl_acct_ops = {
516 .init = nfnl_acct_net_init, 516 .init = nfnl_acct_net_init,
517 .exit = nfnl_acct_net_exit, 517 .exit = nfnl_acct_net_exit,
518 .async = true,
518}; 519};
519 520
520static int __init nfnl_acct_init(void) 521static int __init nfnl_acct_init(void)
diff --git a/net/netfilter/nfnetlink_cttimeout.c b/net/netfilter/nfnetlink_cttimeout.c
index 95b04702a655..6819300f7fb7 100644
--- a/net/netfilter/nfnetlink_cttimeout.c
+++ b/net/netfilter/nfnetlink_cttimeout.c
@@ -586,6 +586,7 @@ static void __net_exit cttimeout_net_exit(struct net *net)
586static struct pernet_operations cttimeout_ops = { 586static struct pernet_operations cttimeout_ops = {
587 .init = cttimeout_net_init, 587 .init = cttimeout_net_init,
588 .exit = cttimeout_net_exit, 588 .exit = cttimeout_net_exit,
589 .async = true,
589}; 590};
590 591
591static int __init cttimeout_init(void) 592static int __init cttimeout_init(void)
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index 7b46aa4c478d..b21ef79849a1 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -1108,6 +1108,7 @@ static struct pernet_operations nfnl_log_net_ops = {
1108 .exit = nfnl_log_net_exit, 1108 .exit = nfnl_log_net_exit,
1109 .id = &nfnl_log_net_id, 1109 .id = &nfnl_log_net_id,
1110 .size = sizeof(struct nfnl_log_net), 1110 .size = sizeof(struct nfnl_log_net),
1111 .async = true,
1111}; 1112};
1112 1113
1113static int __init nfnetlink_log_init(void) 1114static int __init nfnetlink_log_init(void)
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index 8bba23160a68..9f572ed56208 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -833,11 +833,8 @@ nfqnl_mangle(void *data, int data_len, struct nf_queue_entry *e, int diff)
833 if (diff > skb_tailroom(e->skb)) { 833 if (diff > skb_tailroom(e->skb)) {
834 nskb = skb_copy_expand(e->skb, skb_headroom(e->skb), 834 nskb = skb_copy_expand(e->skb, skb_headroom(e->skb),
835 diff, GFP_ATOMIC); 835 diff, GFP_ATOMIC);
836 if (!nskb) { 836 if (!nskb)
837 printk(KERN_WARNING "nf_queue: OOM "
838 "in mangle, dropping packet\n");
839 return -ENOMEM; 837 return -ENOMEM;
840 }
841 kfree_skb(e->skb); 838 kfree_skb(e->skb);
842 e->skb = nskb; 839 e->skb = nskb;
843 } 840 }
@@ -1528,6 +1525,7 @@ static struct pernet_operations nfnl_queue_net_ops = {
1528 .exit_batch = nfnl_queue_net_exit_batch, 1525 .exit_batch = nfnl_queue_net_exit_batch,
1529 .id = &nfnl_queue_net_id, 1526 .id = &nfnl_queue_net_id,
1530 .size = sizeof(struct nfnl_queue_net), 1527 .size = sizeof(struct nfnl_queue_net),
1528 .async = true,
1531}; 1529};
1532 1530
1533static int __init nfnetlink_queue_init(void) 1531static int __init nfnetlink_queue_init(void)
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 4aa01c90e9d1..6de1f6a4cb80 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -1789,6 +1789,7 @@ static void __net_exit xt_net_exit(struct net *net)
1789static struct pernet_operations xt_net_ops = { 1789static struct pernet_operations xt_net_ops = {
1790 .init = xt_net_init, 1790 .init = xt_net_init,
1791 .exit = xt_net_exit, 1791 .exit = xt_net_exit,
1792 .async = true,
1792}; 1793};
1793 1794
1794static int __init xt_init(void) 1795static int __init xt_init(void)
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c
index 3360f13dc208..ef65b7a9173e 100644
--- a/net/netfilter/xt_hashlimit.c
+++ b/net/netfilter/xt_hashlimit.c
@@ -1349,6 +1349,7 @@ static struct pernet_operations hashlimit_net_ops = {
1349 .exit = hashlimit_net_exit, 1349 .exit = hashlimit_net_exit,
1350 .id = &hashlimit_net_id, 1350 .id = &hashlimit_net_id,
1351 .size = sizeof(struct hashlimit_net), 1351 .size = sizeof(struct hashlimit_net),
1352 .async = true,
1352}; 1353};
1353 1354
1354static int __init hashlimit_mt_init(void) 1355static int __init hashlimit_mt_init(void)
diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c
index 81ee1d6543b2..486dd24da78b 100644
--- a/net/netfilter/xt_recent.c
+++ b/net/netfilter/xt_recent.c
@@ -687,6 +687,7 @@ static struct pernet_operations recent_net_ops = {
687 .exit = recent_net_exit, 687 .exit = recent_net_exit,
688 .id = &recent_net_id, 688 .id = &recent_net_id,
689 .size = sizeof(struct recent_net), 689 .size = sizeof(struct recent_net),
690 .async = true,
690}; 691};
691 692
692static struct xt_match recent_mt_reg[] __read_mostly = { 693static struct xt_match recent_mt_reg[] __read_mostly = {
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 07e8478068f0..5d10dcfe6411 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -253,6 +253,7 @@ static struct pernet_operations netlink_tap_net_ops = {
253 .exit = netlink_tap_exit_net, 253 .exit = netlink_tap_exit_net,
254 .id = &netlink_tap_net_id, 254 .id = &netlink_tap_net_id,
255 .size = sizeof(struct netlink_tap_net), 255 .size = sizeof(struct netlink_tap_net),
256 .async = true,
256}; 257};
257 258
258static bool netlink_filter_tap(const struct sk_buff *skb) 259static bool netlink_filter_tap(const struct sk_buff *skb)
@@ -1105,7 +1106,7 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
1105} 1106}
1106 1107
1107static int netlink_getname(struct socket *sock, struct sockaddr *addr, 1108static int netlink_getname(struct socket *sock, struct sockaddr *addr,
1108 int *addr_len, int peer) 1109 int peer)
1109{ 1110{
1110 struct sock *sk = sock->sk; 1111 struct sock *sk = sock->sk;
1111 struct netlink_sock *nlk = nlk_sk(sk); 1112 struct netlink_sock *nlk = nlk_sk(sk);
@@ -1113,7 +1114,6 @@ static int netlink_getname(struct socket *sock, struct sockaddr *addr,
1113 1114
1114 nladdr->nl_family = AF_NETLINK; 1115 nladdr->nl_family = AF_NETLINK;
1115 nladdr->nl_pad = 0; 1116 nladdr->nl_pad = 0;
1116 *addr_len = sizeof(*nladdr);
1117 1117
1118 if (peer) { 1118 if (peer) {
1119 nladdr->nl_pid = nlk->dst_portid; 1119 nladdr->nl_pid = nlk->dst_portid;
@@ -1124,7 +1124,7 @@ static int netlink_getname(struct socket *sock, struct sockaddr *addr,
1124 nladdr->nl_groups = nlk->groups ? nlk->groups[0] : 0; 1124 nladdr->nl_groups = nlk->groups ? nlk->groups[0] : 0;
1125 netlink_unlock_table(); 1125 netlink_unlock_table();
1126 } 1126 }
1127 return 0; 1127 return sizeof(*nladdr);
1128} 1128}
1129 1129
1130static int netlink_ioctl(struct socket *sock, unsigned int cmd, 1130static int netlink_ioctl(struct socket *sock, unsigned int cmd,
@@ -2726,6 +2726,7 @@ static void __init netlink_add_usersock_entry(void)
2726static struct pernet_operations __net_initdata netlink_net_ops = { 2726static struct pernet_operations __net_initdata netlink_net_ops = {
2727 .init = netlink_net_init, 2727 .init = netlink_net_init,
2728 .exit = netlink_net_exit, 2728 .exit = netlink_net_exit,
2729 .async = true,
2729}; 2730};
2730 2731
2731static inline u32 netlink_hash(const void *data, u32 len, u32 seed) 2732static inline u32 netlink_hash(const void *data, u32 len, u32 seed)
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index b9ce82c9440f..af51b8c0a2cb 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -1035,6 +1035,7 @@ static void __net_exit genl_pernet_exit(struct net *net)
1035static struct pernet_operations genl_pernet_ops = { 1035static struct pernet_operations genl_pernet_ops = {
1036 .init = genl_pernet_init, 1036 .init = genl_pernet_init,
1037 .exit = genl_pernet_exit, 1037 .exit = genl_pernet_exit,
1038 .async = true,
1038}; 1039};
1039 1040
1040static int __init genl_init(void) 1041static int __init genl_init(void)
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index 9ba30c63be3d..35bb6807927f 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -829,11 +829,12 @@ out_release:
829} 829}
830 830
831static int nr_getname(struct socket *sock, struct sockaddr *uaddr, 831static int nr_getname(struct socket *sock, struct sockaddr *uaddr,
832 int *uaddr_len, int peer) 832 int peer)
833{ 833{
834 struct full_sockaddr_ax25 *sax = (struct full_sockaddr_ax25 *)uaddr; 834 struct full_sockaddr_ax25 *sax = (struct full_sockaddr_ax25 *)uaddr;
835 struct sock *sk = sock->sk; 835 struct sock *sk = sock->sk;
836 struct nr_sock *nr = nr_sk(sk); 836 struct nr_sock *nr = nr_sk(sk);
837 int uaddr_len;
837 838
838 memset(&sax->fsa_ax25, 0, sizeof(struct sockaddr_ax25)); 839 memset(&sax->fsa_ax25, 0, sizeof(struct sockaddr_ax25));
839 840
@@ -848,16 +849,16 @@ static int nr_getname(struct socket *sock, struct sockaddr *uaddr,
848 sax->fsa_ax25.sax25_call = nr->user_addr; 849 sax->fsa_ax25.sax25_call = nr->user_addr;
849 memset(sax->fsa_digipeater, 0, sizeof(sax->fsa_digipeater)); 850 memset(sax->fsa_digipeater, 0, sizeof(sax->fsa_digipeater));
850 sax->fsa_digipeater[0] = nr->dest_addr; 851 sax->fsa_digipeater[0] = nr->dest_addr;
851 *uaddr_len = sizeof(struct full_sockaddr_ax25); 852 uaddr_len = sizeof(struct full_sockaddr_ax25);
852 } else { 853 } else {
853 sax->fsa_ax25.sax25_family = AF_NETROM; 854 sax->fsa_ax25.sax25_family = AF_NETROM;
854 sax->fsa_ax25.sax25_ndigis = 0; 855 sax->fsa_ax25.sax25_ndigis = 0;
855 sax->fsa_ax25.sax25_call = nr->source_addr; 856 sax->fsa_ax25.sax25_call = nr->source_addr;
856 *uaddr_len = sizeof(struct sockaddr_ax25); 857 uaddr_len = sizeof(struct sockaddr_ax25);
857 } 858 }
858 release_sock(sk); 859 release_sock(sk);
859 860
860 return 0; 861 return uaddr_len;
861} 862}
862 863
863int nr_rx_frame(struct sk_buff *skb, struct net_device *dev) 864int nr_rx_frame(struct sk_buff *skb, struct net_device *dev)
diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c
index 376040092142..ea0c0c6f1874 100644
--- a/net/nfc/llcp_sock.c
+++ b/net/nfc/llcp_sock.c
@@ -497,7 +497,7 @@ error:
497} 497}
498 498
499static int llcp_sock_getname(struct socket *sock, struct sockaddr *uaddr, 499static int llcp_sock_getname(struct socket *sock, struct sockaddr *uaddr,
500 int *len, int peer) 500 int peer)
501{ 501{
502 struct sock *sk = sock->sk; 502 struct sock *sk = sock->sk;
503 struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk); 503 struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk);
@@ -510,7 +510,6 @@ static int llcp_sock_getname(struct socket *sock, struct sockaddr *uaddr,
510 llcp_sock->dsap, llcp_sock->ssap); 510 llcp_sock->dsap, llcp_sock->ssap);
511 511
512 memset(llcp_addr, 0, sizeof(*llcp_addr)); 512 memset(llcp_addr, 0, sizeof(*llcp_addr));
513 *len = sizeof(struct sockaddr_nfc_llcp);
514 513
515 lock_sock(sk); 514 lock_sock(sk);
516 if (!llcp_sock->dev) { 515 if (!llcp_sock->dev) {
@@ -528,7 +527,7 @@ static int llcp_sock_getname(struct socket *sock, struct sockaddr *uaddr,
528 llcp_addr->service_name_len); 527 llcp_addr->service_name_len);
529 release_sock(sk); 528 release_sock(sk);
530 529
531 return 0; 530 return sizeof(struct sockaddr_nfc_llcp);
532} 531}
533 532
534static inline __poll_t llcp_accept_poll(struct sock *parent) 533static inline __poll_t llcp_accept_poll(struct sock *parent)
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index ef38e5aecd28..100191df0371 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -2384,6 +2384,7 @@ static struct pernet_operations ovs_net_ops = {
2384 .exit = ovs_exit_net, 2384 .exit = ovs_exit_net,
2385 .id = &ovs_net_id, 2385 .id = &ovs_net_id,
2386 .size = sizeof(struct ovs_net), 2386 .size = sizeof(struct ovs_net),
2387 .async = true,
2387}; 2388};
2388 2389
2389static int __init dp_init(void) 2390static int __init dp_init(void)
diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c
index b6c8524032a0..f81c1d0ddff4 100644
--- a/net/openvswitch/vport.c
+++ b/net/openvswitch/vport.c
@@ -464,10 +464,10 @@ int ovs_vport_receive(struct vport *vport, struct sk_buff *skb,
464 return 0; 464 return 0;
465} 465}
466 466
467static unsigned int packet_length(const struct sk_buff *skb, 467static int packet_length(const struct sk_buff *skb,
468 struct net_device *dev) 468 struct net_device *dev)
469{ 469{
470 unsigned int length = skb->len - dev->hard_header_len; 470 int length = skb->len - dev->hard_header_len;
471 471
472 if (!skb_vlan_tag_present(skb) && 472 if (!skb_vlan_tag_present(skb) &&
473 eth_type_vlan(skb->protocol)) 473 eth_type_vlan(skb->protocol))
@@ -478,7 +478,7 @@ static unsigned int packet_length(const struct sk_buff *skb,
478 * account for 802.1ad. e.g. is_skb_forwardable(). 478 * account for 802.1ad. e.g. is_skb_forwardable().
479 */ 479 */
480 480
481 return length; 481 return length > 0 ? length : 0;
482} 482}
483 483
484void ovs_vport_send(struct vport *vport, struct sk_buff *skb, u8 mac_proto) 484void ovs_vport_send(struct vport *vport, struct sk_buff *skb, u8 mac_proto)
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index e0f3f4aeeb4f..2c5a6fe5d749 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -3409,7 +3409,7 @@ out:
3409} 3409}
3410 3410
3411static int packet_getname_spkt(struct socket *sock, struct sockaddr *uaddr, 3411static int packet_getname_spkt(struct socket *sock, struct sockaddr *uaddr,
3412 int *uaddr_len, int peer) 3412 int peer)
3413{ 3413{
3414 struct net_device *dev; 3414 struct net_device *dev;
3415 struct sock *sk = sock->sk; 3415 struct sock *sk = sock->sk;
@@ -3424,13 +3424,12 @@ static int packet_getname_spkt(struct socket *sock, struct sockaddr *uaddr,
3424 if (dev) 3424 if (dev)
3425 strlcpy(uaddr->sa_data, dev->name, sizeof(uaddr->sa_data)); 3425 strlcpy(uaddr->sa_data, dev->name, sizeof(uaddr->sa_data));
3426 rcu_read_unlock(); 3426 rcu_read_unlock();
3427 *uaddr_len = sizeof(*uaddr);
3428 3427
3429 return 0; 3428 return sizeof(*uaddr);
3430} 3429}
3431 3430
3432static int packet_getname(struct socket *sock, struct sockaddr *uaddr, 3431static int packet_getname(struct socket *sock, struct sockaddr *uaddr,
3433 int *uaddr_len, int peer) 3432 int peer)
3434{ 3433{
3435 struct net_device *dev; 3434 struct net_device *dev;
3436 struct sock *sk = sock->sk; 3435 struct sock *sk = sock->sk;
@@ -3455,9 +3454,8 @@ static int packet_getname(struct socket *sock, struct sockaddr *uaddr,
3455 sll->sll_halen = 0; 3454 sll->sll_halen = 0;
3456 } 3455 }
3457 rcu_read_unlock(); 3456 rcu_read_unlock();
3458 *uaddr_len = offsetof(struct sockaddr_ll, sll_addr) + sll->sll_halen;
3459 3457
3460 return 0; 3458 return offsetof(struct sockaddr_ll, sll_addr) + sll->sll_halen;
3461} 3459}
3462 3460
3463static int packet_dev_mc(struct net_device *dev, struct packet_mclist *i, 3461static int packet_dev_mc(struct net_device *dev, struct packet_mclist *i,
@@ -4559,6 +4557,7 @@ static void __net_exit packet_net_exit(struct net *net)
4559static struct pernet_operations packet_net_ops = { 4557static struct pernet_operations packet_net_ops = {
4560 .init = packet_net_init, 4558 .init = packet_net_init,
4561 .exit = packet_net_exit, 4559 .exit = packet_net_exit,
4560 .async = true,
4562}; 4561};
4563 4562
4564 4563
diff --git a/net/phonet/pn_dev.c b/net/phonet/pn_dev.c
index 77787512fc32..9454e8393793 100644
--- a/net/phonet/pn_dev.c
+++ b/net/phonet/pn_dev.c
@@ -342,6 +342,7 @@ static struct pernet_operations phonet_net_ops = {
342 .exit = phonet_exit_net, 342 .exit = phonet_exit_net,
343 .id = &phonet_net_id, 343 .id = &phonet_net_id,
344 .size = sizeof(struct phonet_net), 344 .size = sizeof(struct phonet_net),
345 .async = true,
345}; 346};
346 347
347/* Initialize Phonet devices list */ 348/* Initialize Phonet devices list */
diff --git a/net/phonet/socket.c b/net/phonet/socket.c
index fffcd69f63ff..f9b40e6a18a5 100644
--- a/net/phonet/socket.c
+++ b/net/phonet/socket.c
@@ -326,7 +326,7 @@ static int pn_socket_accept(struct socket *sock, struct socket *newsock,
326} 326}
327 327
328static int pn_socket_getname(struct socket *sock, struct sockaddr *addr, 328static int pn_socket_getname(struct socket *sock, struct sockaddr *addr,
329 int *sockaddr_len, int peer) 329 int peer)
330{ 330{
331 struct sock *sk = sock->sk; 331 struct sock *sk = sock->sk;
332 struct pn_sock *pn = pn_sk(sk); 332 struct pn_sock *pn = pn_sk(sk);
@@ -337,8 +337,7 @@ static int pn_socket_getname(struct socket *sock, struct sockaddr *addr,
337 pn_sockaddr_set_object((struct sockaddr_pn *)addr, 337 pn_sockaddr_set_object((struct sockaddr_pn *)addr,
338 pn->sobject); 338 pn->sobject);
339 339
340 *sockaddr_len = sizeof(struct sockaddr_pn); 340 return sizeof(struct sockaddr_pn);
341 return 0;
342} 341}
343 342
344static __poll_t pn_socket_poll(struct file *file, struct socket *sock, 343static __poll_t pn_socket_poll(struct file *file, struct socket *sock,
diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c
index 5fb3929e3d7d..b33e5aeb4c06 100644
--- a/net/qrtr/qrtr.c
+++ b/net/qrtr/qrtr.c
@@ -893,7 +893,7 @@ static int qrtr_connect(struct socket *sock, struct sockaddr *saddr,
893} 893}
894 894
895static int qrtr_getname(struct socket *sock, struct sockaddr *saddr, 895static int qrtr_getname(struct socket *sock, struct sockaddr *saddr,
896 int *len, int peer) 896 int peer)
897{ 897{
898 struct qrtr_sock *ipc = qrtr_sk(sock->sk); 898 struct qrtr_sock *ipc = qrtr_sk(sock->sk);
899 struct sockaddr_qrtr qaddr; 899 struct sockaddr_qrtr qaddr;
@@ -912,12 +912,11 @@ static int qrtr_getname(struct socket *sock, struct sockaddr *saddr,
912 } 912 }
913 release_sock(sk); 913 release_sock(sk);
914 914
915 *len = sizeof(qaddr);
916 qaddr.sq_family = AF_QIPCRTR; 915 qaddr.sq_family = AF_QIPCRTR;
917 916
918 memcpy(saddr, &qaddr, sizeof(qaddr)); 917 memcpy(saddr, &qaddr, sizeof(qaddr));
919 918
920 return 0; 919 return sizeof(qaddr);
921} 920}
922 921
923static int qrtr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) 922static int qrtr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c
index 744c637c86b0..ab751a150f70 100644
--- a/net/rds/af_rds.c
+++ b/net/rds/af_rds.c
@@ -77,6 +77,7 @@ static int rds_release(struct socket *sock)
77 rds_send_drop_to(rs, NULL); 77 rds_send_drop_to(rs, NULL);
78 rds_rdma_drop_keys(rs); 78 rds_rdma_drop_keys(rs);
79 rds_notify_queue_get(rs, NULL); 79 rds_notify_queue_get(rs, NULL);
80 rds_notify_msg_zcopy_purge(&rs->rs_zcookie_queue);
80 81
81 spin_lock_bh(&rds_sock_lock); 82 spin_lock_bh(&rds_sock_lock);
82 list_del_init(&rs->rs_item); 83 list_del_init(&rs->rs_item);
@@ -110,7 +111,7 @@ void rds_wake_sk_sleep(struct rds_sock *rs)
110} 111}
111 112
112static int rds_getname(struct socket *sock, struct sockaddr *uaddr, 113static int rds_getname(struct socket *sock, struct sockaddr *uaddr,
113 int *uaddr_len, int peer) 114 int peer)
114{ 115{
115 struct sockaddr_in *sin = (struct sockaddr_in *)uaddr; 116 struct sockaddr_in *sin = (struct sockaddr_in *)uaddr;
116 struct rds_sock *rs = rds_sk_to_rs(sock->sk); 117 struct rds_sock *rs = rds_sk_to_rs(sock->sk);
@@ -131,8 +132,7 @@ static int rds_getname(struct socket *sock, struct sockaddr *uaddr,
131 132
132 sin->sin_family = AF_INET; 133 sin->sin_family = AF_INET;
133 134
134 *uaddr_len = sizeof(*sin); 135 return sizeof(*sin);
135 return 0;
136} 136}
137 137
138/* 138/*
@@ -145,7 +145,7 @@ static int rds_getname(struct socket *sock, struct sockaddr *uaddr,
145 * - to signal that a previously congested destination may have become 145 * - to signal that a previously congested destination may have become
146 * uncongested 146 * uncongested
147 * - A notification has been queued to the socket (this can be a congestion 147 * - A notification has been queued to the socket (this can be a congestion
148 * update, or a RDMA completion). 148 * update, or a RDMA completion, or a MSG_ZEROCOPY completion).
149 * 149 *
150 * EPOLLOUT is asserted if there is room on the send queue. This does not mean 150 * EPOLLOUT is asserted if there is room on the send queue. This does not mean
151 * however, that the next sendmsg() call will succeed. If the application tries 151 * however, that the next sendmsg() call will succeed. If the application tries
@@ -179,10 +179,13 @@ static __poll_t rds_poll(struct file *file, struct socket *sock,
179 spin_unlock(&rs->rs_lock); 179 spin_unlock(&rs->rs_lock);
180 } 180 }
181 if (!list_empty(&rs->rs_recv_queue) || 181 if (!list_empty(&rs->rs_recv_queue) ||
182 !list_empty(&rs->rs_notify_queue)) 182 !list_empty(&rs->rs_notify_queue) ||
183 !list_empty(&rs->rs_zcookie_queue.zcookie_head))
183 mask |= (EPOLLIN | EPOLLRDNORM); 184 mask |= (EPOLLIN | EPOLLRDNORM);
184 if (rs->rs_snd_bytes < rds_sk_sndbuf(rs)) 185 if (rs->rs_snd_bytes < rds_sk_sndbuf(rs))
185 mask |= (EPOLLOUT | EPOLLWRNORM); 186 mask |= (EPOLLOUT | EPOLLWRNORM);
187 if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
188 mask |= POLLERR;
186 read_unlock_irqrestore(&rs->rs_recv_lock, flags); 189 read_unlock_irqrestore(&rs->rs_recv_lock, flags);
187 190
188 /* clear state any time we wake a seen-congested socket */ 191 /* clear state any time we wake a seen-congested socket */
@@ -512,6 +515,7 @@ static int __rds_create(struct socket *sock, struct sock *sk, int protocol)
512 INIT_LIST_HEAD(&rs->rs_recv_queue); 515 INIT_LIST_HEAD(&rs->rs_recv_queue);
513 INIT_LIST_HEAD(&rs->rs_notify_queue); 516 INIT_LIST_HEAD(&rs->rs_notify_queue);
514 INIT_LIST_HEAD(&rs->rs_cong_list); 517 INIT_LIST_HEAD(&rs->rs_cong_list);
518 rds_message_zcopy_queue_init(&rs->rs_zcookie_queue);
515 spin_lock_init(&rs->rs_rdma_lock); 519 spin_lock_init(&rs->rs_rdma_lock);
516 rs->rs_rdma_keys = RB_ROOT; 520 rs->rs_rdma_keys = RB_ROOT;
517 rs->rs_rx_traces = 0; 521 rs->rs_rx_traces = 0;
diff --git a/net/rds/connection.c b/net/rds/connection.c
index 2da3176bf792..abef75da89a7 100644
--- a/net/rds/connection.c
+++ b/net/rds/connection.c
@@ -540,9 +540,9 @@ void rds_for_each_conn_info(struct socket *sock, unsigned int len,
540 struct rds_info_iterator *iter, 540 struct rds_info_iterator *iter,
541 struct rds_info_lengths *lens, 541 struct rds_info_lengths *lens,
542 int (*visitor)(struct rds_connection *, void *), 542 int (*visitor)(struct rds_connection *, void *),
543 u64 *buffer,
543 size_t item_len) 544 size_t item_len)
544{ 545{
545 uint64_t buffer[(item_len + 7) / 8];
546 struct hlist_head *head; 546 struct hlist_head *head;
547 struct rds_connection *conn; 547 struct rds_connection *conn;
548 size_t i; 548 size_t i;
@@ -578,9 +578,9 @@ static void rds_walk_conn_path_info(struct socket *sock, unsigned int len,
578 struct rds_info_iterator *iter, 578 struct rds_info_iterator *iter,
579 struct rds_info_lengths *lens, 579 struct rds_info_lengths *lens,
580 int (*visitor)(struct rds_conn_path *, void *), 580 int (*visitor)(struct rds_conn_path *, void *),
581 u64 *buffer,
581 size_t item_len) 582 size_t item_len)
582{ 583{
583 u64 buffer[(item_len + 7) / 8];
584 struct hlist_head *head; 584 struct hlist_head *head;
585 struct rds_connection *conn; 585 struct rds_connection *conn;
586 size_t i; 586 size_t i;
@@ -649,8 +649,11 @@ static void rds_conn_info(struct socket *sock, unsigned int len,
649 struct rds_info_iterator *iter, 649 struct rds_info_iterator *iter,
650 struct rds_info_lengths *lens) 650 struct rds_info_lengths *lens)
651{ 651{
652 u64 buffer[(sizeof(struct rds_info_connection) + 7) / 8];
653
652 rds_walk_conn_path_info(sock, len, iter, lens, 654 rds_walk_conn_path_info(sock, len, iter, lens,
653 rds_conn_info_visitor, 655 rds_conn_info_visitor,
656 buffer,
654 sizeof(struct rds_info_connection)); 657 sizeof(struct rds_info_connection));
655} 658}
656 659
diff --git a/net/rds/ib.c b/net/rds/ib.c
index 50a88f3e7e39..02deee29e7f1 100644
--- a/net/rds/ib.c
+++ b/net/rds/ib.c
@@ -321,8 +321,11 @@ static void rds_ib_ic_info(struct socket *sock, unsigned int len,
321 struct rds_info_iterator *iter, 321 struct rds_info_iterator *iter,
322 struct rds_info_lengths *lens) 322 struct rds_info_lengths *lens)
323{ 323{
324 u64 buffer[(sizeof(struct rds_info_rdma_connection) + 7) / 8];
325
324 rds_for_each_conn_info(sock, len, iter, lens, 326 rds_for_each_conn_info(sock, len, iter, lens,
325 rds_ib_conn_info_visitor, 327 rds_ib_conn_info_visitor,
328 buffer,
326 sizeof(struct rds_info_rdma_connection)); 329 sizeof(struct rds_info_rdma_connection));
327} 330}
328 331
diff --git a/net/rds/message.c b/net/rds/message.c
index 4318cc9b78f7..a35f76971984 100644
--- a/net/rds/message.c
+++ b/net/rds/message.c
@@ -33,6 +33,9 @@
33#include <linux/kernel.h> 33#include <linux/kernel.h>
34#include <linux/slab.h> 34#include <linux/slab.h>
35#include <linux/export.h> 35#include <linux/export.h>
36#include <linux/skbuff.h>
37#include <linux/list.h>
38#include <linux/errqueue.h>
36 39
37#include "rds.h" 40#include "rds.h"
38 41
@@ -45,7 +48,6 @@ static unsigned int rds_exthdr_size[__RDS_EXTHDR_MAX] = {
45[RDS_EXTHDR_GEN_NUM] = sizeof(u32), 48[RDS_EXTHDR_GEN_NUM] = sizeof(u32),
46}; 49};
47 50
48
49void rds_message_addref(struct rds_message *rm) 51void rds_message_addref(struct rds_message *rm)
50{ 52{
51 rdsdebug("addref rm %p ref %d\n", rm, refcount_read(&rm->m_refcount)); 53 rdsdebug("addref rm %p ref %d\n", rm, refcount_read(&rm->m_refcount));
@@ -53,20 +55,107 @@ void rds_message_addref(struct rds_message *rm)
53} 55}
54EXPORT_SYMBOL_GPL(rds_message_addref); 56EXPORT_SYMBOL_GPL(rds_message_addref);
55 57
58static inline bool rds_zcookie_add(struct rds_msg_zcopy_info *info, u32 cookie)
59{
60 struct rds_zcopy_cookies *ck = &info->zcookies;
61 int ncookies = ck->num;
62
63 if (ncookies == RDS_MAX_ZCOOKIES)
64 return false;
65 ck->cookies[ncookies] = cookie;
66 ck->num = ++ncookies;
67 return true;
68}
69
70static struct rds_msg_zcopy_info *rds_info_from_znotifier(struct rds_znotifier *znotif)
71{
72 return container_of(znotif, struct rds_msg_zcopy_info, znotif);
73}
74
75void rds_notify_msg_zcopy_purge(struct rds_msg_zcopy_queue *q)
76{
77 unsigned long flags;
78 LIST_HEAD(copy);
79 struct rds_msg_zcopy_info *info, *tmp;
80
81 spin_lock_irqsave(&q->lock, flags);
82 list_splice(&q->zcookie_head, &copy);
83 INIT_LIST_HEAD(&q->zcookie_head);
84 spin_unlock_irqrestore(&q->lock, flags);
85
86 list_for_each_entry_safe(info, tmp, &copy, rs_zcookie_next) {
87 list_del(&info->rs_zcookie_next);
88 kfree(info);
89 }
90}
91
92static void rds_rm_zerocopy_callback(struct rds_sock *rs,
93 struct rds_znotifier *znotif)
94{
95 struct rds_msg_zcopy_info *info;
96 struct rds_msg_zcopy_queue *q;
97 u32 cookie = znotif->z_cookie;
98 struct rds_zcopy_cookies *ck;
99 struct list_head *head;
100 unsigned long flags;
101
102 mm_unaccount_pinned_pages(&znotif->z_mmp);
103 q = &rs->rs_zcookie_queue;
104 spin_lock_irqsave(&q->lock, flags);
105 head = &q->zcookie_head;
106 if (!list_empty(head)) {
107 info = list_entry(head, struct rds_msg_zcopy_info,
108 rs_zcookie_next);
109 if (info && rds_zcookie_add(info, cookie)) {
110 spin_unlock_irqrestore(&q->lock, flags);
111 kfree(rds_info_from_znotifier(znotif));
112 /* caller invokes rds_wake_sk_sleep() */
113 return;
114 }
115 }
116
117 info = rds_info_from_znotifier(znotif);
118 ck = &info->zcookies;
119 memset(ck, 0, sizeof(*ck));
120 WARN_ON(!rds_zcookie_add(info, cookie));
121 list_add_tail(&q->zcookie_head, &info->rs_zcookie_next);
122
123 spin_unlock_irqrestore(&q->lock, flags);
124 /* caller invokes rds_wake_sk_sleep() */
125}
126
56/* 127/*
57 * This relies on dma_map_sg() not touching sg[].page during merging. 128 * This relies on dma_map_sg() not touching sg[].page during merging.
58 */ 129 */
59static void rds_message_purge(struct rds_message *rm) 130static void rds_message_purge(struct rds_message *rm)
60{ 131{
61 unsigned long i; 132 unsigned long i, flags;
133 bool zcopy = false;
62 134
63 if (unlikely(test_bit(RDS_MSG_PAGEVEC, &rm->m_flags))) 135 if (unlikely(test_bit(RDS_MSG_PAGEVEC, &rm->m_flags)))
64 return; 136 return;
65 137
138 spin_lock_irqsave(&rm->m_rs_lock, flags);
139 if (rm->m_rs) {
140 struct rds_sock *rs = rm->m_rs;
141
142 if (rm->data.op_mmp_znotifier) {
143 zcopy = true;
144 rds_rm_zerocopy_callback(rs, rm->data.op_mmp_znotifier);
145 rds_wake_sk_sleep(rs);
146 rm->data.op_mmp_znotifier = NULL;
147 }
148 sock_put(rds_rs_to_sk(rs));
149 rm->m_rs = NULL;
150 }
151 spin_unlock_irqrestore(&rm->m_rs_lock, flags);
152
66 for (i = 0; i < rm->data.op_nents; i++) { 153 for (i = 0; i < rm->data.op_nents; i++) {
67 rdsdebug("putting data page %p\n", (void *)sg_page(&rm->data.op_sg[i]));
68 /* XXX will have to put_page for page refs */ 154 /* XXX will have to put_page for page refs */
69 __free_page(sg_page(&rm->data.op_sg[i])); 155 if (!zcopy)
156 __free_page(sg_page(&rm->data.op_sg[i]));
157 else
158 put_page(sg_page(&rm->data.op_sg[i]));
70 } 159 }
71 rm->data.op_nents = 0; 160 rm->data.op_nents = 0;
72 161
@@ -266,12 +355,13 @@ struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned in
266 return rm; 355 return rm;
267} 356}
268 357
269int rds_message_copy_from_user(struct rds_message *rm, struct iov_iter *from) 358static int rds_message_zcopy_from_user(struct rds_message *rm, struct iov_iter *from)
270{ 359{
271 unsigned long to_copy, nbytes;
272 unsigned long sg_off;
273 struct scatterlist *sg; 360 struct scatterlist *sg;
274 int ret = 0; 361 int ret = 0;
362 int length = iov_iter_count(from);
363 int total_copied = 0;
364 struct rds_msg_zcopy_info *info;
275 365
276 rm->m_inc.i_hdr.h_len = cpu_to_be32(iov_iter_count(from)); 366 rm->m_inc.i_hdr.h_len = cpu_to_be32(iov_iter_count(from));
277 367
@@ -279,8 +369,67 @@ int rds_message_copy_from_user(struct rds_message *rm, struct iov_iter *from)
279 * now allocate and copy in the data payload. 369 * now allocate and copy in the data payload.
280 */ 370 */
281 sg = rm->data.op_sg; 371 sg = rm->data.op_sg;
372
373 info = kzalloc(sizeof(*info), GFP_KERNEL);
374 if (!info)
375 return -ENOMEM;
376 INIT_LIST_HEAD(&info->rs_zcookie_next);
377 rm->data.op_mmp_znotifier = &info->znotif;
378 if (mm_account_pinned_pages(&rm->data.op_mmp_znotifier->z_mmp,
379 length)) {
380 ret = -ENOMEM;
381 goto err;
382 }
383 while (iov_iter_count(from)) {
384 struct page *pages;
385 size_t start;
386 ssize_t copied;
387
388 copied = iov_iter_get_pages(from, &pages, PAGE_SIZE,
389 1, &start);
390 if (copied < 0) {
391 struct mmpin *mmp;
392 int i;
393
394 for (i = 0; i < rm->data.op_nents; i++)
395 put_page(sg_page(&rm->data.op_sg[i]));
396 mmp = &rm->data.op_mmp_znotifier->z_mmp;
397 mm_unaccount_pinned_pages(mmp);
398 ret = -EFAULT;
399 goto err;
400 }
401 total_copied += copied;
402 iov_iter_advance(from, copied);
403 length -= copied;
404 sg_set_page(sg, pages, copied, start);
405 rm->data.op_nents++;
406 sg++;
407 }
408 WARN_ON_ONCE(length != 0);
409 return ret;
410err:
411 kfree(info);
412 rm->data.op_mmp_znotifier = NULL;
413 return ret;
414}
415
416int rds_message_copy_from_user(struct rds_message *rm, struct iov_iter *from,
417 bool zcopy)
418{
419 unsigned long to_copy, nbytes;
420 unsigned long sg_off;
421 struct scatterlist *sg;
422 int ret = 0;
423
424 rm->m_inc.i_hdr.h_len = cpu_to_be32(iov_iter_count(from));
425
426 /* now allocate and copy in the data payload. */
427 sg = rm->data.op_sg;
282 sg_off = 0; /* Dear gcc, sg->page will be null from kzalloc. */ 428 sg_off = 0; /* Dear gcc, sg->page will be null from kzalloc. */
283 429
430 if (zcopy)
431 return rds_message_zcopy_from_user(rm, from);
432
284 while (iov_iter_count(from)) { 433 while (iov_iter_count(from)) {
285 if (!sg_page(sg)) { 434 if (!sg_page(sg)) {
286 ret = rds_page_remainder_alloc(sg, iov_iter_count(from), 435 ret = rds_page_remainder_alloc(sg, iov_iter_count(from),
diff --git a/net/rds/rds.h b/net/rds/rds.h
index 7301b9b01890..b04c333d9d1c 100644
--- a/net/rds/rds.h
+++ b/net/rds/rds.h
@@ -356,6 +356,30 @@ static inline u32 rds_rdma_cookie_offset(rds_rdma_cookie_t cookie)
356#define RDS_MSG_PAGEVEC 7 356#define RDS_MSG_PAGEVEC 7
357#define RDS_MSG_FLUSH 8 357#define RDS_MSG_FLUSH 8
358 358
359struct rds_znotifier {
360 struct mmpin z_mmp;
361 u32 z_cookie;
362};
363
364struct rds_msg_zcopy_info {
365 struct list_head rs_zcookie_next;
366 union {
367 struct rds_znotifier znotif;
368 struct rds_zcopy_cookies zcookies;
369 };
370};
371
372struct rds_msg_zcopy_queue {
373 struct list_head zcookie_head;
374 spinlock_t lock; /* protects zcookie_head queue */
375};
376
377static inline void rds_message_zcopy_queue_init(struct rds_msg_zcopy_queue *q)
378{
379 spin_lock_init(&q->lock);
380 INIT_LIST_HEAD(&q->zcookie_head);
381}
382
359struct rds_message { 383struct rds_message {
360 refcount_t m_refcount; 384 refcount_t m_refcount;
361 struct list_head m_sock_item; 385 struct list_head m_sock_item;
@@ -436,6 +460,7 @@ struct rds_message {
436 unsigned int op_count; 460 unsigned int op_count;
437 unsigned int op_dmasg; 461 unsigned int op_dmasg;
438 unsigned int op_dmaoff; 462 unsigned int op_dmaoff;
463 struct rds_znotifier *op_mmp_znotifier;
439 struct scatterlist *op_sg; 464 struct scatterlist *op_sg;
440 } data; 465 } data;
441 }; 466 };
@@ -589,6 +614,7 @@ struct rds_sock {
589 /* Socket receive path trace points*/ 614 /* Socket receive path trace points*/
590 u8 rs_rx_traces; 615 u8 rs_rx_traces;
591 u8 rs_rx_trace[RDS_MSG_RX_DGRAM_TRACE_MAX]; 616 u8 rs_rx_trace[RDS_MSG_RX_DGRAM_TRACE_MAX];
617 struct rds_msg_zcopy_queue rs_zcookie_queue;
592}; 618};
593 619
594static inline struct rds_sock *rds_sk_to_rs(const struct sock *sk) 620static inline struct rds_sock *rds_sk_to_rs(const struct sock *sk)
@@ -709,6 +735,7 @@ void rds_for_each_conn_info(struct socket *sock, unsigned int len,
709 struct rds_info_iterator *iter, 735 struct rds_info_iterator *iter,
710 struct rds_info_lengths *lens, 736 struct rds_info_lengths *lens,
711 int (*visitor)(struct rds_connection *, void *), 737 int (*visitor)(struct rds_connection *, void *),
738 u64 *buffer,
712 size_t item_len); 739 size_t item_len);
713 740
714__printf(2, 3) 741__printf(2, 3)
@@ -771,7 +798,8 @@ rds_conn_connecting(struct rds_connection *conn)
771/* message.c */ 798/* message.c */
772struct rds_message *rds_message_alloc(unsigned int nents, gfp_t gfp); 799struct rds_message *rds_message_alloc(unsigned int nents, gfp_t gfp);
773struct scatterlist *rds_message_alloc_sgs(struct rds_message *rm, int nents); 800struct scatterlist *rds_message_alloc_sgs(struct rds_message *rm, int nents);
774int rds_message_copy_from_user(struct rds_message *rm, struct iov_iter *from); 801int rds_message_copy_from_user(struct rds_message *rm, struct iov_iter *from,
802 bool zcopy);
775struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned int total_len); 803struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned int total_len);
776void rds_message_populate_header(struct rds_header *hdr, __be16 sport, 804void rds_message_populate_header(struct rds_header *hdr, __be16 sport,
777 __be16 dport, u64 seq); 805 __be16 dport, u64 seq);
@@ -786,6 +814,7 @@ void rds_message_addref(struct rds_message *rm);
786void rds_message_put(struct rds_message *rm); 814void rds_message_put(struct rds_message *rm);
787void rds_message_wait(struct rds_message *rm); 815void rds_message_wait(struct rds_message *rm);
788void rds_message_unmapped(struct rds_message *rm); 816void rds_message_unmapped(struct rds_message *rm);
817void rds_notify_msg_zcopy_purge(struct rds_msg_zcopy_queue *info);
789 818
790static inline void rds_message_make_checksum(struct rds_header *hdr) 819static inline void rds_message_make_checksum(struct rds_header *hdr)
791{ 820{
diff --git a/net/rds/recv.c b/net/rds/recv.c
index b25bcfe411ca..de50e2126e40 100644
--- a/net/rds/recv.c
+++ b/net/rds/recv.c
@@ -577,6 +577,41 @@ out:
577 return ret; 577 return ret;
578} 578}
579 579
580static bool rds_recvmsg_zcookie(struct rds_sock *rs, struct msghdr *msg)
581{
582 struct rds_msg_zcopy_queue *q = &rs->rs_zcookie_queue;
583 struct rds_msg_zcopy_info *info = NULL;
584 struct rds_zcopy_cookies *done;
585 unsigned long flags;
586
587 if (!msg->msg_control)
588 return false;
589
590 if (!sock_flag(rds_rs_to_sk(rs), SOCK_ZEROCOPY) ||
591 msg->msg_controllen < CMSG_SPACE(sizeof(*done)))
592 return false;
593
594 spin_lock_irqsave(&q->lock, flags);
595 if (!list_empty(&q->zcookie_head)) {
596 info = list_entry(q->zcookie_head.next,
597 struct rds_msg_zcopy_info, rs_zcookie_next);
598 list_del(&info->rs_zcookie_next);
599 }
600 spin_unlock_irqrestore(&q->lock, flags);
601 if (!info)
602 return false;
603 done = &info->zcookies;
604 if (put_cmsg(msg, SOL_RDS, RDS_CMSG_ZCOPY_COMPLETION, sizeof(*done),
605 done)) {
606 spin_lock_irqsave(&q->lock, flags);
607 list_add(&info->rs_zcookie_next, &q->zcookie_head);
608 spin_unlock_irqrestore(&q->lock, flags);
609 return false;
610 }
611 kfree(info);
612 return true;
613}
614
580int rds_recvmsg(struct socket *sock, struct msghdr *msg, size_t size, 615int rds_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
581 int msg_flags) 616 int msg_flags)
582{ 617{
@@ -594,6 +629,8 @@ int rds_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
594 629
595 if (msg_flags & MSG_OOB) 630 if (msg_flags & MSG_OOB)
596 goto out; 631 goto out;
632 if (msg_flags & MSG_ERRQUEUE)
633 return sock_recv_errqueue(sk, msg, size, SOL_IP, IP_RECVERR);
597 634
598 while (1) { 635 while (1) {
599 /* If there are pending notifications, do those - and nothing else */ 636 /* If there are pending notifications, do those - and nothing else */
@@ -609,7 +646,9 @@ int rds_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
609 646
610 if (!rds_next_incoming(rs, &inc)) { 647 if (!rds_next_incoming(rs, &inc)) {
611 if (nonblock) { 648 if (nonblock) {
612 ret = -EAGAIN; 649 bool reaped = rds_recvmsg_zcookie(rs, msg);
650
651 ret = reaped ? 0 : -EAGAIN;
613 break; 652 break;
614 } 653 }
615 654
@@ -658,6 +697,7 @@ int rds_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
658 ret = -EFAULT; 697 ret = -EFAULT;
659 goto out; 698 goto out;
660 } 699 }
700 rds_recvmsg_zcookie(rs, msg);
661 701
662 rds_stats_inc(s_recv_delivered); 702 rds_stats_inc(s_recv_delivered);
663 703
diff --git a/net/rds/send.c b/net/rds/send.c
index b1b0022b8370..acad04243b41 100644
--- a/net/rds/send.c
+++ b/net/rds/send.c
@@ -649,7 +649,6 @@ static void rds_send_remove_from_sock(struct list_head *messages, int status)
649 rm->rdma.op_notifier = NULL; 649 rm->rdma.op_notifier = NULL;
650 } 650 }
651 was_on_sock = 1; 651 was_on_sock = 1;
652 rm->m_rs = NULL;
653 } 652 }
654 spin_unlock(&rs->rs_lock); 653 spin_unlock(&rs->rs_lock);
655 654
@@ -756,9 +755,6 @@ void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest)
756 */ 755 */
757 if (!test_and_clear_bit(RDS_MSG_ON_CONN, &rm->m_flags)) { 756 if (!test_and_clear_bit(RDS_MSG_ON_CONN, &rm->m_flags)) {
758 spin_unlock_irqrestore(&cp->cp_lock, flags); 757 spin_unlock_irqrestore(&cp->cp_lock, flags);
759 spin_lock_irqsave(&rm->m_rs_lock, flags);
760 rm->m_rs = NULL;
761 spin_unlock_irqrestore(&rm->m_rs_lock, flags);
762 continue; 758 continue;
763 } 759 }
764 list_del_init(&rm->m_conn_item); 760 list_del_init(&rm->m_conn_item);
@@ -774,7 +770,6 @@ void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest)
774 __rds_send_complete(rs, rm, RDS_RDMA_CANCELED); 770 __rds_send_complete(rs, rm, RDS_RDMA_CANCELED);
775 spin_unlock(&rs->rs_lock); 771 spin_unlock(&rs->rs_lock);
776 772
777 rm->m_rs = NULL;
778 spin_unlock_irqrestore(&rm->m_rs_lock, flags); 773 spin_unlock_irqrestore(&rm->m_rs_lock, flags);
779 774
780 rds_message_put(rm); 775 rds_message_put(rm);
@@ -798,7 +793,6 @@ void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest)
798 __rds_send_complete(rs, rm, RDS_RDMA_CANCELED); 793 __rds_send_complete(rs, rm, RDS_RDMA_CANCELED);
799 spin_unlock(&rs->rs_lock); 794 spin_unlock(&rs->rs_lock);
800 795
801 rm->m_rs = NULL;
802 spin_unlock_irqrestore(&rm->m_rs_lock, flags); 796 spin_unlock_irqrestore(&rm->m_rs_lock, flags);
803 797
804 rds_message_put(rm); 798 rds_message_put(rm);
@@ -849,6 +843,7 @@ static int rds_send_queue_rm(struct rds_sock *rs, struct rds_connection *conn,
849 list_add_tail(&rm->m_sock_item, &rs->rs_send_queue); 843 list_add_tail(&rm->m_sock_item, &rs->rs_send_queue);
850 set_bit(RDS_MSG_ON_SOCK, &rm->m_flags); 844 set_bit(RDS_MSG_ON_SOCK, &rm->m_flags);
851 rds_message_addref(rm); 845 rds_message_addref(rm);
846 sock_hold(rds_rs_to_sk(rs));
852 rm->m_rs = rs; 847 rm->m_rs = rs;
853 848
854 /* The code ordering is a little weird, but we're 849 /* The code ordering is a little weird, but we're
@@ -880,12 +875,13 @@ out:
880 * rds_message is getting to be quite complicated, and we'd like to allocate 875 * rds_message is getting to be quite complicated, and we'd like to allocate
881 * it all in one go. This figures out how big it needs to be up front. 876 * it all in one go. This figures out how big it needs to be up front.
882 */ 877 */
883static int rds_rm_size(struct msghdr *msg, int data_len) 878static int rds_rm_size(struct msghdr *msg, int num_sgs)
884{ 879{
885 struct cmsghdr *cmsg; 880 struct cmsghdr *cmsg;
886 int size = 0; 881 int size = 0;
887 int cmsg_groups = 0; 882 int cmsg_groups = 0;
888 int retval; 883 int retval;
884 bool zcopy_cookie = false;
889 885
890 for_each_cmsghdr(cmsg, msg) { 886 for_each_cmsghdr(cmsg, msg) {
891 if (!CMSG_OK(msg, cmsg)) 887 if (!CMSG_OK(msg, cmsg))
@@ -904,6 +900,10 @@ static int rds_rm_size(struct msghdr *msg, int data_len)
904 900
905 break; 901 break;
906 902
903 case RDS_CMSG_ZCOPY_COOKIE:
904 zcopy_cookie = true;
905 /* fall through */
906
907 case RDS_CMSG_RDMA_DEST: 907 case RDS_CMSG_RDMA_DEST:
908 case RDS_CMSG_RDMA_MAP: 908 case RDS_CMSG_RDMA_MAP:
909 cmsg_groups |= 2; 909 cmsg_groups |= 2;
@@ -924,7 +924,10 @@ static int rds_rm_size(struct msghdr *msg, int data_len)
924 924
925 } 925 }
926 926
927 size += ceil(data_len, PAGE_SIZE) * sizeof(struct scatterlist); 927 if ((msg->msg_flags & MSG_ZEROCOPY) && !zcopy_cookie)
928 return -EINVAL;
929
930 size += num_sgs * sizeof(struct scatterlist);
928 931
929 /* Ensure (DEST, MAP) are never used with (ARGS, ATOMIC) */ 932 /* Ensure (DEST, MAP) are never used with (ARGS, ATOMIC) */
930 if (cmsg_groups == 3) 933 if (cmsg_groups == 3)
@@ -933,6 +936,19 @@ static int rds_rm_size(struct msghdr *msg, int data_len)
933 return size; 936 return size;
934} 937}
935 938
939static int rds_cmsg_zcopy(struct rds_sock *rs, struct rds_message *rm,
940 struct cmsghdr *cmsg)
941{
942 u32 *cookie;
943
944 if (cmsg->cmsg_len < CMSG_LEN(sizeof(*cookie)) ||
945 !rm->data.op_mmp_znotifier)
946 return -EINVAL;
947 cookie = CMSG_DATA(cmsg);
948 rm->data.op_mmp_znotifier->z_cookie = *cookie;
949 return 0;
950}
951
936static int rds_cmsg_send(struct rds_sock *rs, struct rds_message *rm, 952static int rds_cmsg_send(struct rds_sock *rs, struct rds_message *rm,
937 struct msghdr *msg, int *allocated_mr) 953 struct msghdr *msg, int *allocated_mr)
938{ 954{
@@ -975,6 +991,10 @@ static int rds_cmsg_send(struct rds_sock *rs, struct rds_message *rm,
975 ret = rds_cmsg_atomic(rs, rm, cmsg); 991 ret = rds_cmsg_atomic(rs, rm, cmsg);
976 break; 992 break;
977 993
994 case RDS_CMSG_ZCOPY_COOKIE:
995 ret = rds_cmsg_zcopy(rs, rm, cmsg);
996 break;
997
978 default: 998 default:
979 return -EINVAL; 999 return -EINVAL;
980 } 1000 }
@@ -1045,10 +1065,13 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len)
1045 long timeo = sock_sndtimeo(sk, nonblock); 1065 long timeo = sock_sndtimeo(sk, nonblock);
1046 struct rds_conn_path *cpath; 1066 struct rds_conn_path *cpath;
1047 size_t total_payload_len = payload_len, rdma_payload_len = 0; 1067 size_t total_payload_len = payload_len, rdma_payload_len = 0;
1068 bool zcopy = ((msg->msg_flags & MSG_ZEROCOPY) &&
1069 sock_flag(rds_rs_to_sk(rs), SOCK_ZEROCOPY));
1070 int num_sgs = ceil(payload_len, PAGE_SIZE);
1048 1071
1049 /* Mirror Linux UDP mirror of BSD error message compatibility */ 1072 /* Mirror Linux UDP mirror of BSD error message compatibility */
1050 /* XXX: Perhaps MSG_MORE someday */ 1073 /* XXX: Perhaps MSG_MORE someday */
1051 if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_CMSG_COMPAT)) { 1074 if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_CMSG_COMPAT | MSG_ZEROCOPY)) {
1052 ret = -EOPNOTSUPP; 1075 ret = -EOPNOTSUPP;
1053 goto out; 1076 goto out;
1054 } 1077 }
@@ -1092,8 +1115,15 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len)
1092 goto out; 1115 goto out;
1093 } 1116 }
1094 1117
1118 if (zcopy) {
1119 if (rs->rs_transport->t_type != RDS_TRANS_TCP) {
1120 ret = -EOPNOTSUPP;
1121 goto out;
1122 }
1123 num_sgs = iov_iter_npages(&msg->msg_iter, INT_MAX);
1124 }
1095 /* size of rm including all sgs */ 1125 /* size of rm including all sgs */
1096 ret = rds_rm_size(msg, payload_len); 1126 ret = rds_rm_size(msg, num_sgs);
1097 if (ret < 0) 1127 if (ret < 0)
1098 goto out; 1128 goto out;
1099 1129
@@ -1105,12 +1135,12 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len)
1105 1135
1106 /* Attach data to the rm */ 1136 /* Attach data to the rm */
1107 if (payload_len) { 1137 if (payload_len) {
1108 rm->data.op_sg = rds_message_alloc_sgs(rm, ceil(payload_len, PAGE_SIZE)); 1138 rm->data.op_sg = rds_message_alloc_sgs(rm, num_sgs);
1109 if (!rm->data.op_sg) { 1139 if (!rm->data.op_sg) {
1110 ret = -ENOMEM; 1140 ret = -ENOMEM;
1111 goto out; 1141 goto out;
1112 } 1142 }
1113 ret = rds_message_copy_from_user(rm, &msg->msg_iter); 1143 ret = rds_message_copy_from_user(rm, &msg->msg_iter, zcopy);
1114 if (ret) 1144 if (ret)
1115 goto out; 1145 goto out;
1116 } 1146 }
diff --git a/net/rds/tcp.c b/net/rds/tcp.c
index 44c4652721af..4f3a32c38bf5 100644
--- a/net/rds/tcp.c
+++ b/net/rds/tcp.c
@@ -227,7 +227,6 @@ static void rds_tcp_tc_info(struct socket *rds_sock, unsigned int len,
227 struct rds_tcp_connection *tc; 227 struct rds_tcp_connection *tc;
228 unsigned long flags; 228 unsigned long flags;
229 struct sockaddr_in sin; 229 struct sockaddr_in sin;
230 int sinlen;
231 struct socket *sock; 230 struct socket *sock;
232 231
233 spin_lock_irqsave(&rds_tcp_tc_list_lock, flags); 232 spin_lock_irqsave(&rds_tcp_tc_list_lock, flags);
@@ -239,12 +238,10 @@ static void rds_tcp_tc_info(struct socket *rds_sock, unsigned int len,
239 238
240 sock = tc->t_sock; 239 sock = tc->t_sock;
241 if (sock) { 240 if (sock) {
242 sock->ops->getname(sock, (struct sockaddr *)&sin, 241 sock->ops->getname(sock, (struct sockaddr *)&sin, 0);
243 &sinlen, 0);
244 tsinfo.local_addr = sin.sin_addr.s_addr; 242 tsinfo.local_addr = sin.sin_addr.s_addr;
245 tsinfo.local_port = sin.sin_port; 243 tsinfo.local_port = sin.sin_port;
246 sock->ops->getname(sock, (struct sockaddr *)&sin, 244 sock->ops->getname(sock, (struct sockaddr *)&sin, 1);
247 &sinlen, 1);
248 tsinfo.peer_addr = sin.sin_addr.s_addr; 245 tsinfo.peer_addr = sin.sin_addr.s_addr;
249 tsinfo.peer_port = sin.sin_port; 246 tsinfo.peer_port = sin.sin_port;
250 } 247 }
@@ -275,13 +272,14 @@ static int rds_tcp_laddr_check(struct net *net, __be32 addr)
275static void rds_tcp_conn_free(void *arg) 272static void rds_tcp_conn_free(void *arg)
276{ 273{
277 struct rds_tcp_connection *tc = arg; 274 struct rds_tcp_connection *tc = arg;
275 unsigned long flags;
278 276
279 rdsdebug("freeing tc %p\n", tc); 277 rdsdebug("freeing tc %p\n", tc);
280 278
281 spin_lock_bh(&rds_tcp_conn_lock); 279 spin_lock_irqsave(&rds_tcp_conn_lock, flags);
282 if (!tc->t_tcp_node_detached) 280 if (!tc->t_tcp_node_detached)
283 list_del(&tc->t_tcp_node); 281 list_del(&tc->t_tcp_node);
284 spin_unlock_bh(&rds_tcp_conn_lock); 282 spin_unlock_irqrestore(&rds_tcp_conn_lock, flags);
285 283
286 kmem_cache_free(rds_tcp_conn_slab, tc); 284 kmem_cache_free(rds_tcp_conn_slab, tc);
287} 285}
@@ -311,13 +309,13 @@ static int rds_tcp_conn_alloc(struct rds_connection *conn, gfp_t gfp)
311 rdsdebug("rds_conn_path [%d] tc %p\n", i, 309 rdsdebug("rds_conn_path [%d] tc %p\n", i,
312 conn->c_path[i].cp_transport_data); 310 conn->c_path[i].cp_transport_data);
313 } 311 }
314 spin_lock_bh(&rds_tcp_conn_lock); 312 spin_lock_irq(&rds_tcp_conn_lock);
315 for (i = 0; i < RDS_MPATH_WORKERS; i++) { 313 for (i = 0; i < RDS_MPATH_WORKERS; i++) {
316 tc = conn->c_path[i].cp_transport_data; 314 tc = conn->c_path[i].cp_transport_data;
317 tc->t_tcp_node_detached = false; 315 tc->t_tcp_node_detached = false;
318 list_add_tail(&tc->t_tcp_node, &rds_tcp_conn_list); 316 list_add_tail(&tc->t_tcp_node, &rds_tcp_conn_list);
319 } 317 }
320 spin_unlock_bh(&rds_tcp_conn_lock); 318 spin_unlock_irq(&rds_tcp_conn_lock);
321fail: 319fail:
322 if (ret) { 320 if (ret) {
323 for (j = 0; j < i; j++) 321 for (j = 0; j < i; j++)
@@ -487,39 +485,6 @@ fail:
487 return err; 485 return err;
488} 486}
489 487
490static void __net_exit rds_tcp_exit_net(struct net *net)
491{
492 struct rds_tcp_net *rtn = net_generic(net, rds_tcp_netid);
493
494 if (rtn->rds_tcp_sysctl)
495 unregister_net_sysctl_table(rtn->rds_tcp_sysctl);
496
497 if (net != &init_net && rtn->ctl_table)
498 kfree(rtn->ctl_table);
499
500 /* If rds_tcp_exit_net() is called as a result of netns deletion,
501 * the rds_tcp_kill_sock() device notifier would already have cleaned
502 * up the listen socket, thus there is no work to do in this function.
503 *
504 * If rds_tcp_exit_net() is called as a result of module unload,
505 * i.e., due to rds_tcp_exit() -> unregister_pernet_subsys(), then
506 * we do need to clean up the listen socket here.
507 */
508 if (rtn->rds_tcp_listen_sock) {
509 struct socket *lsock = rtn->rds_tcp_listen_sock;
510
511 rtn->rds_tcp_listen_sock = NULL;
512 rds_tcp_listen_stop(lsock, &rtn->rds_tcp_accept_w);
513 }
514}
515
516static struct pernet_operations rds_tcp_net_ops = {
517 .init = rds_tcp_init_net,
518 .exit = rds_tcp_exit_net,
519 .id = &rds_tcp_netid,
520 .size = sizeof(struct rds_tcp_net),
521};
522
523static void rds_tcp_kill_sock(struct net *net) 488static void rds_tcp_kill_sock(struct net *net)
524{ 489{
525 struct rds_tcp_connection *tc, *_tc; 490 struct rds_tcp_connection *tc, *_tc;
@@ -529,7 +494,7 @@ static void rds_tcp_kill_sock(struct net *net)
529 494
530 rtn->rds_tcp_listen_sock = NULL; 495 rtn->rds_tcp_listen_sock = NULL;
531 rds_tcp_listen_stop(lsock, &rtn->rds_tcp_accept_w); 496 rds_tcp_listen_stop(lsock, &rtn->rds_tcp_accept_w);
532 spin_lock_bh(&rds_tcp_conn_lock); 497 spin_lock_irq(&rds_tcp_conn_lock);
533 list_for_each_entry_safe(tc, _tc, &rds_tcp_conn_list, t_tcp_node) { 498 list_for_each_entry_safe(tc, _tc, &rds_tcp_conn_list, t_tcp_node) {
534 struct net *c_net = read_pnet(&tc->t_cpath->cp_conn->c_net); 499 struct net *c_net = read_pnet(&tc->t_cpath->cp_conn->c_net);
535 500
@@ -542,45 +507,43 @@ static void rds_tcp_kill_sock(struct net *net)
542 tc->t_tcp_node_detached = true; 507 tc->t_tcp_node_detached = true;
543 } 508 }
544 } 509 }
545 spin_unlock_bh(&rds_tcp_conn_lock); 510 spin_unlock_irq(&rds_tcp_conn_lock);
546 list_for_each_entry_safe(tc, _tc, &tmp_list, t_tcp_node) 511 list_for_each_entry_safe(tc, _tc, &tmp_list, t_tcp_node)
547 rds_conn_destroy(tc->t_cpath->cp_conn); 512 rds_conn_destroy(tc->t_cpath->cp_conn);
548} 513}
549 514
550void *rds_tcp_listen_sock_def_readable(struct net *net) 515static void __net_exit rds_tcp_exit_net(struct net *net)
551{ 516{
552 struct rds_tcp_net *rtn = net_generic(net, rds_tcp_netid); 517 struct rds_tcp_net *rtn = net_generic(net, rds_tcp_netid);
553 struct socket *lsock = rtn->rds_tcp_listen_sock;
554 518
555 if (!lsock) 519 rds_tcp_kill_sock(net);
556 return NULL;
557 520
558 return lsock->sk->sk_user_data; 521 if (rtn->rds_tcp_sysctl)
522 unregister_net_sysctl_table(rtn->rds_tcp_sysctl);
523
524 if (net != &init_net && rtn->ctl_table)
525 kfree(rtn->ctl_table);
559} 526}
560 527
561static int rds_tcp_dev_event(struct notifier_block *this, 528static struct pernet_operations rds_tcp_net_ops = {
562 unsigned long event, void *ptr) 529 .init = rds_tcp_init_net,
530 .exit = rds_tcp_exit_net,
531 .id = &rds_tcp_netid,
532 .size = sizeof(struct rds_tcp_net),
533 .async = true,
534};
535
536void *rds_tcp_listen_sock_def_readable(struct net *net)
563{ 537{
564 struct net_device *dev = netdev_notifier_info_to_dev(ptr); 538 struct rds_tcp_net *rtn = net_generic(net, rds_tcp_netid);
539 struct socket *lsock = rtn->rds_tcp_listen_sock;
565 540
566 /* rds-tcp registers as a pernet subys, so the ->exit will only 541 if (!lsock)
567 * get invoked after network acitivity has quiesced. We need to 542 return NULL;
568 * clean up all sockets to quiesce network activity, and use
569 * the unregistration of the per-net loopback device as a trigger
570 * to start that cleanup.
571 */
572 if (event == NETDEV_UNREGISTER_FINAL &&
573 dev->ifindex == LOOPBACK_IFINDEX)
574 rds_tcp_kill_sock(dev_net(dev));
575 543
576 return NOTIFY_DONE; 544 return lsock->sk->sk_user_data;
577} 545}
578 546
579static struct notifier_block rds_tcp_dev_notifier = {
580 .notifier_call = rds_tcp_dev_event,
581 .priority = -10, /* must be called after other network notifiers */
582};
583
584/* when sysctl is used to modify some kernel socket parameters,this 547/* when sysctl is used to modify some kernel socket parameters,this
585 * function resets the RDS connections in that netns so that we can 548 * function resets the RDS connections in that netns so that we can
586 * restart with new parameters. The assumption is that such reset 549 * restart with new parameters. The assumption is that such reset
@@ -590,7 +553,7 @@ static void rds_tcp_sysctl_reset(struct net *net)
590{ 553{
591 struct rds_tcp_connection *tc, *_tc; 554 struct rds_tcp_connection *tc, *_tc;
592 555
593 spin_lock_bh(&rds_tcp_conn_lock); 556 spin_lock_irq(&rds_tcp_conn_lock);
594 list_for_each_entry_safe(tc, _tc, &rds_tcp_conn_list, t_tcp_node) { 557 list_for_each_entry_safe(tc, _tc, &rds_tcp_conn_list, t_tcp_node) {
595 struct net *c_net = read_pnet(&tc->t_cpath->cp_conn->c_net); 558 struct net *c_net = read_pnet(&tc->t_cpath->cp_conn->c_net);
596 559
@@ -600,7 +563,7 @@ static void rds_tcp_sysctl_reset(struct net *net)
600 /* reconnect with new parameters */ 563 /* reconnect with new parameters */
601 rds_conn_path_drop(tc->t_cpath, false); 564 rds_conn_path_drop(tc->t_cpath, false);
602 } 565 }
603 spin_unlock_bh(&rds_tcp_conn_lock); 566 spin_unlock_irq(&rds_tcp_conn_lock);
604} 567}
605 568
606static int rds_tcp_skbuf_handler(struct ctl_table *ctl, int write, 569static int rds_tcp_skbuf_handler(struct ctl_table *ctl, int write,
@@ -626,9 +589,7 @@ static void rds_tcp_exit(void)
626 rds_tcp_set_unloading(); 589 rds_tcp_set_unloading();
627 synchronize_rcu(); 590 synchronize_rcu();
628 rds_info_deregister_func(RDS_INFO_TCP_SOCKETS, rds_tcp_tc_info); 591 rds_info_deregister_func(RDS_INFO_TCP_SOCKETS, rds_tcp_tc_info);
629 unregister_pernet_subsys(&rds_tcp_net_ops); 592 unregister_pernet_device(&rds_tcp_net_ops);
630 if (unregister_netdevice_notifier(&rds_tcp_dev_notifier))
631 pr_warn("could not unregister rds_tcp_dev_notifier\n");
632 rds_tcp_destroy_conns(); 593 rds_tcp_destroy_conns();
633 rds_trans_unregister(&rds_tcp_transport); 594 rds_trans_unregister(&rds_tcp_transport);
634 rds_tcp_recv_exit(); 595 rds_tcp_recv_exit();
@@ -652,24 +613,15 @@ static int rds_tcp_init(void)
652 if (ret) 613 if (ret)
653 goto out_slab; 614 goto out_slab;
654 615
655 ret = register_pernet_subsys(&rds_tcp_net_ops); 616 ret = register_pernet_device(&rds_tcp_net_ops);
656 if (ret) 617 if (ret)
657 goto out_recv; 618 goto out_recv;
658 619
659 ret = register_netdevice_notifier(&rds_tcp_dev_notifier);
660 if (ret) {
661 pr_warn("could not register rds_tcp_dev_notifier\n");
662 goto out_pernet;
663 }
664
665 rds_trans_register(&rds_tcp_transport); 620 rds_trans_register(&rds_tcp_transport);
666 621
667 rds_info_register_func(RDS_INFO_TCP_SOCKETS, rds_tcp_tc_info); 622 rds_info_register_func(RDS_INFO_TCP_SOCKETS, rds_tcp_tc_info);
668 623
669 goto out; 624 goto out;
670
671out_pernet:
672 unregister_pernet_subsys(&rds_tcp_net_ops);
673out_recv: 625out_recv:
674 rds_tcp_recv_exit(); 626 rds_tcp_recv_exit();
675out_slab: 627out_slab:
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index 083bd251406f..5170373b797c 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -938,7 +938,7 @@ out_release:
938} 938}
939 939
940static int rose_getname(struct socket *sock, struct sockaddr *uaddr, 940static int rose_getname(struct socket *sock, struct sockaddr *uaddr,
941 int *uaddr_len, int peer) 941 int peer)
942{ 942{
943 struct full_sockaddr_rose *srose = (struct full_sockaddr_rose *)uaddr; 943 struct full_sockaddr_rose *srose = (struct full_sockaddr_rose *)uaddr;
944 struct sock *sk = sock->sk; 944 struct sock *sk = sock->sk;
@@ -964,8 +964,7 @@ static int rose_getname(struct socket *sock, struct sockaddr *uaddr,
964 srose->srose_digis[n] = rose->source_digis[n]; 964 srose->srose_digis[n] = rose->source_digis[n];
965 } 965 }
966 966
967 *uaddr_len = sizeof(struct full_sockaddr_rose); 967 return sizeof(struct full_sockaddr_rose);
968 return 0;
969} 968}
970 969
971int rose_rx_call_request(struct sk_buff *skb, struct net_device *dev, struct rose_neigh *neigh, unsigned int lci) 970int rose_rx_call_request(struct sk_buff *skb, struct net_device *dev, struct rose_neigh *neigh, unsigned int lci)
diff --git a/net/rxrpc/recvmsg.c b/net/rxrpc/recvmsg.c
index 9d45d8b56744..7bff716e911e 100644
--- a/net/rxrpc/recvmsg.c
+++ b/net/rxrpc/recvmsg.c
@@ -272,7 +272,7 @@ static int rxrpc_locate_data(struct rxrpc_call *call, struct sk_buff *skb,
272 unsigned int *_offset, unsigned int *_len) 272 unsigned int *_offset, unsigned int *_len)
273{ 273{
274 unsigned int offset = sizeof(struct rxrpc_wire_header); 274 unsigned int offset = sizeof(struct rxrpc_wire_header);
275 unsigned int len = *_len; 275 unsigned int len;
276 int ret; 276 int ret;
277 u8 annotation = *_annotation; 277 u8 annotation = *_annotation;
278 278
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index f24a6ae6819a..a01169fb5325 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -658,6 +658,18 @@ config NET_EMATCH_IPSET
658 To compile this code as a module, choose M here: the 658 To compile this code as a module, choose M here: the
659 module will be called em_ipset. 659 module will be called em_ipset.
660 660
661config NET_EMATCH_IPT
662 tristate "IPtables Matches"
663 depends on NET_EMATCH && NETFILTER && NETFILTER_XTABLES
664 ---help---
665 Say Y here to be able to classify packets based on iptables
666 matches.
667 Current supported match is "policy" which allows packet classification
668 based on IPsec policy that was used during decapsulation
669
670 To compile this code as a module, choose M here: the
671 module will be called em_ipt.
672
661config NET_CLS_ACT 673config NET_CLS_ACT
662 bool "Actions" 674 bool "Actions"
663 select NET_CLS 675 select NET_CLS
diff --git a/net/sched/Makefile b/net/sched/Makefile
index 5b635447e3f8..8811d3804878 100644
--- a/net/sched/Makefile
+++ b/net/sched/Makefile
@@ -75,3 +75,4 @@ obj-$(CONFIG_NET_EMATCH_META) += em_meta.o
75obj-$(CONFIG_NET_EMATCH_TEXT) += em_text.o 75obj-$(CONFIG_NET_EMATCH_TEXT) += em_text.o
76obj-$(CONFIG_NET_EMATCH_CANID) += em_canid.o 76obj-$(CONFIG_NET_EMATCH_CANID) += em_canid.o
77obj-$(CONFIG_NET_EMATCH_IPSET) += em_ipset.o 77obj-$(CONFIG_NET_EMATCH_IPSET) += em_ipset.o
78obj-$(CONFIG_NET_EMATCH_IPT) += em_ipt.o
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index eba6682727dd..57cf37145282 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -109,6 +109,42 @@ int __tcf_idr_release(struct tc_action *p, bool bind, bool strict)
109} 109}
110EXPORT_SYMBOL(__tcf_idr_release); 110EXPORT_SYMBOL(__tcf_idr_release);
111 111
112static size_t tcf_action_shared_attrs_size(const struct tc_action *act)
113{
114 u32 cookie_len = 0;
115
116 if (act->act_cookie)
117 cookie_len = nla_total_size(act->act_cookie->len);
118
119 return nla_total_size(0) /* action number nested */
120 + nla_total_size(IFNAMSIZ) /* TCA_ACT_KIND */
121 + cookie_len /* TCA_ACT_COOKIE */
122 + nla_total_size(0) /* TCA_ACT_STATS nested */
123 /* TCA_STATS_BASIC */
124 + nla_total_size_64bit(sizeof(struct gnet_stats_basic))
125 /* TCA_STATS_QUEUE */
126 + nla_total_size_64bit(sizeof(struct gnet_stats_queue))
127 + nla_total_size(0) /* TCA_OPTIONS nested */
128 + nla_total_size(sizeof(struct tcf_t)); /* TCA_GACT_TM */
129}
130
131static size_t tcf_action_full_attrs_size(size_t sz)
132{
133 return NLMSG_HDRLEN /* struct nlmsghdr */
134 + sizeof(struct tcamsg)
135 + nla_total_size(0) /* TCA_ACT_TAB nested */
136 + sz;
137}
138
139static size_t tcf_action_fill_size(const struct tc_action *act)
140{
141 size_t sz = tcf_action_shared_attrs_size(act);
142
143 if (act->ops->get_fill_size)
144 return act->ops->get_fill_size(act) + sz;
145 return sz;
146}
147
112static int tcf_dump_walker(struct tcf_idrinfo *idrinfo, struct sk_buff *skb, 148static int tcf_dump_walker(struct tcf_idrinfo *idrinfo, struct sk_buff *skb,
113 struct netlink_callback *cb) 149 struct netlink_callback *cb)
114{ 150{
@@ -202,7 +238,8 @@ nla_put_failure:
202 238
203int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb, 239int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb,
204 struct netlink_callback *cb, int type, 240 struct netlink_callback *cb, int type,
205 const struct tc_action_ops *ops) 241 const struct tc_action_ops *ops,
242 struct netlink_ext_ack *extack)
206{ 243{
207 struct tcf_idrinfo *idrinfo = tn->idrinfo; 244 struct tcf_idrinfo *idrinfo = tn->idrinfo;
208 245
@@ -211,7 +248,8 @@ int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb,
211 } else if (type == RTM_GETACTION) { 248 } else if (type == RTM_GETACTION) {
212 return tcf_dump_walker(idrinfo, skb, cb); 249 return tcf_dump_walker(idrinfo, skb, cb);
213 } else { 250 } else {
214 WARN(1, "tcf_generic_walker: unknown action %d\n", type); 251 WARN(1, "tcf_generic_walker: unknown command %d\n", type);
252 NL_SET_ERR_MSG(extack, "tcf_generic_walker: unknown command");
215 return -EINVAL; 253 return -EINVAL;
216 } 254 }
217} 255}
@@ -605,7 +643,8 @@ static struct tc_cookie *nla_memdup_cookie(struct nlattr **tb)
605 643
606struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp, 644struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
607 struct nlattr *nla, struct nlattr *est, 645 struct nlattr *nla, struct nlattr *est,
608 char *name, int ovr, int bind) 646 char *name, int ovr, int bind,
647 struct netlink_ext_ack *extack)
609{ 648{
610 struct tc_action *a; 649 struct tc_action *a;
611 struct tc_action_ops *a_o; 650 struct tc_action_ops *a_o;
@@ -616,31 +655,40 @@ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
616 int err; 655 int err;
617 656
618 if (name == NULL) { 657 if (name == NULL) {
619 err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL, NULL); 658 err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL, extack);
620 if (err < 0) 659 if (err < 0)
621 goto err_out; 660 goto err_out;
622 err = -EINVAL; 661 err = -EINVAL;
623 kind = tb[TCA_ACT_KIND]; 662 kind = tb[TCA_ACT_KIND];
624 if (kind == NULL) 663 if (!kind) {
664 NL_SET_ERR_MSG(extack, "TC action kind must be specified");
625 goto err_out; 665 goto err_out;
626 if (nla_strlcpy(act_name, kind, IFNAMSIZ) >= IFNAMSIZ) 666 }
667 if (nla_strlcpy(act_name, kind, IFNAMSIZ) >= IFNAMSIZ) {
668 NL_SET_ERR_MSG(extack, "TC action name too long");
627 goto err_out; 669 goto err_out;
670 }
628 if (tb[TCA_ACT_COOKIE]) { 671 if (tb[TCA_ACT_COOKIE]) {
629 int cklen = nla_len(tb[TCA_ACT_COOKIE]); 672 int cklen = nla_len(tb[TCA_ACT_COOKIE]);
630 673
631 if (cklen > TC_COOKIE_MAX_SIZE) 674 if (cklen > TC_COOKIE_MAX_SIZE) {
675 NL_SET_ERR_MSG(extack, "TC cookie size above the maximum");
632 goto err_out; 676 goto err_out;
677 }
633 678
634 cookie = nla_memdup_cookie(tb); 679 cookie = nla_memdup_cookie(tb);
635 if (!cookie) { 680 if (!cookie) {
681 NL_SET_ERR_MSG(extack, "No memory to generate TC cookie");
636 err = -ENOMEM; 682 err = -ENOMEM;
637 goto err_out; 683 goto err_out;
638 } 684 }
639 } 685 }
640 } else { 686 } else {
641 err = -EINVAL; 687 if (strlcpy(act_name, name, IFNAMSIZ) >= IFNAMSIZ) {
642 if (strlcpy(act_name, name, IFNAMSIZ) >= IFNAMSIZ) 688 NL_SET_ERR_MSG(extack, "TC action name too long");
689 err = -EINVAL;
643 goto err_out; 690 goto err_out;
691 }
644 } 692 }
645 693
646 a_o = tc_lookup_action_n(act_name); 694 a_o = tc_lookup_action_n(act_name);
@@ -663,15 +711,17 @@ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
663 goto err_mod; 711 goto err_mod;
664 } 712 }
665#endif 713#endif
714 NL_SET_ERR_MSG(extack, "Failed to load TC action module");
666 err = -ENOENT; 715 err = -ENOENT;
667 goto err_out; 716 goto err_out;
668 } 717 }
669 718
670 /* backward compatibility for policer */ 719 /* backward compatibility for policer */
671 if (name == NULL) 720 if (name == NULL)
672 err = a_o->init(net, tb[TCA_ACT_OPTIONS], est, &a, ovr, bind); 721 err = a_o->init(net, tb[TCA_ACT_OPTIONS], est, &a, ovr, bind,
722 extack);
673 else 723 else
674 err = a_o->init(net, nla, est, &a, ovr, bind); 724 err = a_o->init(net, nla, est, &a, ovr, bind, extack);
675 if (err < 0) 725 if (err < 0)
676 goto err_mod; 726 goto err_mod;
677 727
@@ -697,6 +747,7 @@ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
697 747
698 list_add_tail(&a->list, &actions); 748 list_add_tail(&a->list, &actions);
699 tcf_action_destroy(&actions, bind); 749 tcf_action_destroy(&actions, bind);
750 NL_SET_ERR_MSG(extack, "Failed to init TC action chain");
700 return ERR_PTR(err); 751 return ERR_PTR(err);
701 } 752 }
702 } 753 }
@@ -726,29 +777,35 @@ static void cleanup_a(struct list_head *actions, int ovr)
726 777
727int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla, 778int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
728 struct nlattr *est, char *name, int ovr, int bind, 779 struct nlattr *est, char *name, int ovr, int bind,
729 struct list_head *actions) 780 struct list_head *actions, size_t *attr_size,
781 struct netlink_ext_ack *extack)
730{ 782{
731 struct nlattr *tb[TCA_ACT_MAX_PRIO + 1]; 783 struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
732 struct tc_action *act; 784 struct tc_action *act;
785 size_t sz = 0;
733 int err; 786 int err;
734 int i; 787 int i;
735 788
736 err = nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL, NULL); 789 err = nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL, extack);
737 if (err < 0) 790 if (err < 0)
738 return err; 791 return err;
739 792
740 for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) { 793 for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
741 act = tcf_action_init_1(net, tp, tb[i], est, name, ovr, bind); 794 act = tcf_action_init_1(net, tp, tb[i], est, name, ovr, bind,
795 extack);
742 if (IS_ERR(act)) { 796 if (IS_ERR(act)) {
743 err = PTR_ERR(act); 797 err = PTR_ERR(act);
744 goto err; 798 goto err;
745 } 799 }
746 act->order = i; 800 act->order = i;
801 sz += tcf_action_fill_size(act);
747 if (ovr) 802 if (ovr)
748 act->tcfa_refcnt++; 803 act->tcfa_refcnt++;
749 list_add_tail(&act->list, actions); 804 list_add_tail(&act->list, actions);
750 } 805 }
751 806
807 *attr_size = tcf_action_full_attrs_size(sz);
808
752 /* Remove the temp refcnt which was necessary to protect against 809 /* Remove the temp refcnt which was necessary to protect against
753 * destroying an existing action which was being replaced 810 * destroying an existing action which was being replaced
754 */ 811 */
@@ -822,7 +879,7 @@ static int tca_get_fill(struct sk_buff *skb, struct list_head *actions,
822 t->tca__pad2 = 0; 879 t->tca__pad2 = 0;
823 880
824 nest = nla_nest_start(skb, TCA_ACT_TAB); 881 nest = nla_nest_start(skb, TCA_ACT_TAB);
825 if (nest == NULL) 882 if (!nest)
826 goto out_nlmsg_trim; 883 goto out_nlmsg_trim;
827 884
828 if (tcf_action_dump(skb, actions, bind, ref) < 0) 885 if (tcf_action_dump(skb, actions, bind, ref) < 0)
@@ -840,7 +897,8 @@ out_nlmsg_trim:
840 897
841static int 898static int
842tcf_get_notify(struct net *net, u32 portid, struct nlmsghdr *n, 899tcf_get_notify(struct net *net, u32 portid, struct nlmsghdr *n,
843 struct list_head *actions, int event) 900 struct list_head *actions, int event,
901 struct netlink_ext_ack *extack)
844{ 902{
845 struct sk_buff *skb; 903 struct sk_buff *skb;
846 904
@@ -849,6 +907,7 @@ tcf_get_notify(struct net *net, u32 portid, struct nlmsghdr *n,
849 return -ENOBUFS; 907 return -ENOBUFS;
850 if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, 0, event, 908 if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, 0, event,
851 0, 0) <= 0) { 909 0, 0) <= 0) {
910 NL_SET_ERR_MSG(extack, "Failed to fill netlink attributes while adding TC action");
852 kfree_skb(skb); 911 kfree_skb(skb);
853 return -EINVAL; 912 return -EINVAL;
854 } 913 }
@@ -857,7 +916,8 @@ tcf_get_notify(struct net *net, u32 portid, struct nlmsghdr *n,
857} 916}
858 917
859static struct tc_action *tcf_action_get_1(struct net *net, struct nlattr *nla, 918static struct tc_action *tcf_action_get_1(struct net *net, struct nlattr *nla,
860 struct nlmsghdr *n, u32 portid) 919 struct nlmsghdr *n, u32 portid,
920 struct netlink_ext_ack *extack)
861{ 921{
862 struct nlattr *tb[TCA_ACT_MAX + 1]; 922 struct nlattr *tb[TCA_ACT_MAX + 1];
863 const struct tc_action_ops *ops; 923 const struct tc_action_ops *ops;
@@ -865,22 +925,26 @@ static struct tc_action *tcf_action_get_1(struct net *net, struct nlattr *nla,
865 int index; 925 int index;
866 int err; 926 int err;
867 927
868 err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL, NULL); 928 err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL, extack);
869 if (err < 0) 929 if (err < 0)
870 goto err_out; 930 goto err_out;
871 931
872 err = -EINVAL; 932 err = -EINVAL;
873 if (tb[TCA_ACT_INDEX] == NULL || 933 if (tb[TCA_ACT_INDEX] == NULL ||
874 nla_len(tb[TCA_ACT_INDEX]) < sizeof(index)) 934 nla_len(tb[TCA_ACT_INDEX]) < sizeof(index)) {
935 NL_SET_ERR_MSG(extack, "Invalid TC action index value");
875 goto err_out; 936 goto err_out;
937 }
876 index = nla_get_u32(tb[TCA_ACT_INDEX]); 938 index = nla_get_u32(tb[TCA_ACT_INDEX]);
877 939
878 err = -EINVAL; 940 err = -EINVAL;
879 ops = tc_lookup_action(tb[TCA_ACT_KIND]); 941 ops = tc_lookup_action(tb[TCA_ACT_KIND]);
880 if (!ops) /* could happen in batch of actions */ 942 if (!ops) { /* could happen in batch of actions */
943 NL_SET_ERR_MSG(extack, "Specified TC action not found");
881 goto err_out; 944 goto err_out;
945 }
882 err = -ENOENT; 946 err = -ENOENT;
883 if (ops->lookup(net, &a, index) == 0) 947 if (ops->lookup(net, &a, index, extack) == 0)
884 goto err_mod; 948 goto err_mod;
885 949
886 module_put(ops->owner); 950 module_put(ops->owner);
@@ -893,7 +957,8 @@ err_out:
893} 957}
894 958
895static int tca_action_flush(struct net *net, struct nlattr *nla, 959static int tca_action_flush(struct net *net, struct nlattr *nla,
896 struct nlmsghdr *n, u32 portid) 960 struct nlmsghdr *n, u32 portid,
961 struct netlink_ext_ack *extack)
897{ 962{
898 struct sk_buff *skb; 963 struct sk_buff *skb;
899 unsigned char *b; 964 unsigned char *b;
@@ -907,39 +972,45 @@ static int tca_action_flush(struct net *net, struct nlattr *nla,
907 int err = -ENOMEM; 972 int err = -ENOMEM;
908 973
909 skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); 974 skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
910 if (!skb) { 975 if (!skb)
911 pr_debug("tca_action_flush: failed skb alloc\n");
912 return err; 976 return err;
913 }
914 977
915 b = skb_tail_pointer(skb); 978 b = skb_tail_pointer(skb);
916 979
917 err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL, NULL); 980 err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL, extack);
918 if (err < 0) 981 if (err < 0)
919 goto err_out; 982 goto err_out;
920 983
921 err = -EINVAL; 984 err = -EINVAL;
922 kind = tb[TCA_ACT_KIND]; 985 kind = tb[TCA_ACT_KIND];
923 ops = tc_lookup_action(kind); 986 ops = tc_lookup_action(kind);
924 if (!ops) /*some idjot trying to flush unknown action */ 987 if (!ops) { /*some idjot trying to flush unknown action */
988 NL_SET_ERR_MSG(extack, "Cannot flush unknown TC action");
925 goto err_out; 989 goto err_out;
990 }
926 991
927 nlh = nlmsg_put(skb, portid, n->nlmsg_seq, RTM_DELACTION, 992 nlh = nlmsg_put(skb, portid, n->nlmsg_seq, RTM_DELACTION,
928 sizeof(*t), 0); 993 sizeof(*t), 0);
929 if (!nlh) 994 if (!nlh) {
995 NL_SET_ERR_MSG(extack, "Failed to create TC action flush notification");
930 goto out_module_put; 996 goto out_module_put;
997 }
931 t = nlmsg_data(nlh); 998 t = nlmsg_data(nlh);
932 t->tca_family = AF_UNSPEC; 999 t->tca_family = AF_UNSPEC;
933 t->tca__pad1 = 0; 1000 t->tca__pad1 = 0;
934 t->tca__pad2 = 0; 1001 t->tca__pad2 = 0;
935 1002
936 nest = nla_nest_start(skb, TCA_ACT_TAB); 1003 nest = nla_nest_start(skb, TCA_ACT_TAB);
937 if (nest == NULL) 1004 if (!nest) {
1005 NL_SET_ERR_MSG(extack, "Failed to add new netlink message");
938 goto out_module_put; 1006 goto out_module_put;
1007 }
939 1008
940 err = ops->walk(net, skb, &dcb, RTM_DELACTION, ops); 1009 err = ops->walk(net, skb, &dcb, RTM_DELACTION, ops, extack);
941 if (err <= 0) 1010 if (err <= 0) {
1011 nla_nest_cancel(skb, nest);
942 goto out_module_put; 1012 goto out_module_put;
1013 }
943 1014
944 nla_nest_end(skb, nest); 1015 nla_nest_end(skb, nest);
945 1016
@@ -950,6 +1021,8 @@ static int tca_action_flush(struct net *net, struct nlattr *nla,
950 n->nlmsg_flags & NLM_F_ECHO); 1021 n->nlmsg_flags & NLM_F_ECHO);
951 if (err > 0) 1022 if (err > 0)
952 return 0; 1023 return 0;
1024 if (err < 0)
1025 NL_SET_ERR_MSG(extack, "Failed to send TC action flush notification");
953 1026
954 return err; 1027 return err;
955 1028
@@ -962,17 +1035,19 @@ err_out:
962 1035
963static int 1036static int
964tcf_del_notify(struct net *net, struct nlmsghdr *n, struct list_head *actions, 1037tcf_del_notify(struct net *net, struct nlmsghdr *n, struct list_head *actions,
965 u32 portid) 1038 u32 portid, size_t attr_size, struct netlink_ext_ack *extack)
966{ 1039{
967 int ret; 1040 int ret;
968 struct sk_buff *skb; 1041 struct sk_buff *skb;
969 1042
970 skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); 1043 skb = alloc_skb(attr_size <= NLMSG_GOODSIZE ? NLMSG_GOODSIZE : attr_size,
1044 GFP_KERNEL);
971 if (!skb) 1045 if (!skb)
972 return -ENOBUFS; 1046 return -ENOBUFS;
973 1047
974 if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, 0, RTM_DELACTION, 1048 if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, 0, RTM_DELACTION,
975 0, 1) <= 0) { 1049 0, 1) <= 0) {
1050 NL_SET_ERR_MSG(extack, "Failed to fill netlink TC action attributes");
976 kfree_skb(skb); 1051 kfree_skb(skb);
977 return -EINVAL; 1052 return -EINVAL;
978 } 1053 }
@@ -980,6 +1055,7 @@ tcf_del_notify(struct net *net, struct nlmsghdr *n, struct list_head *actions,
980 /* now do the delete */ 1055 /* now do the delete */
981 ret = tcf_action_destroy(actions, 0); 1056 ret = tcf_action_destroy(actions, 0);
982 if (ret < 0) { 1057 if (ret < 0) {
1058 NL_SET_ERR_MSG(extack, "Failed to delete TC action");
983 kfree_skb(skb); 1059 kfree_skb(skb);
984 return ret; 1060 return ret;
985 } 1061 }
@@ -993,38 +1069,43 @@ tcf_del_notify(struct net *net, struct nlmsghdr *n, struct list_head *actions,
993 1069
994static int 1070static int
995tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n, 1071tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
996 u32 portid, int event) 1072 u32 portid, int event, struct netlink_ext_ack *extack)
997{ 1073{
998 int i, ret; 1074 int i, ret;
999 struct nlattr *tb[TCA_ACT_MAX_PRIO + 1]; 1075 struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
1000 struct tc_action *act; 1076 struct tc_action *act;
1077 size_t attr_size = 0;
1001 LIST_HEAD(actions); 1078 LIST_HEAD(actions);
1002 1079
1003 ret = nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL, NULL); 1080 ret = nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL, extack);
1004 if (ret < 0) 1081 if (ret < 0)
1005 return ret; 1082 return ret;
1006 1083
1007 if (event == RTM_DELACTION && n->nlmsg_flags & NLM_F_ROOT) { 1084 if (event == RTM_DELACTION && n->nlmsg_flags & NLM_F_ROOT) {
1008 if (tb[1] != NULL) 1085 if (tb[1])
1009 return tca_action_flush(net, tb[1], n, portid); 1086 return tca_action_flush(net, tb[1], n, portid, extack);
1010 else 1087
1011 return -EINVAL; 1088 NL_SET_ERR_MSG(extack, "Invalid netlink attributes while flushing TC action");
1089 return -EINVAL;
1012 } 1090 }
1013 1091
1014 for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) { 1092 for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
1015 act = tcf_action_get_1(net, tb[i], n, portid); 1093 act = tcf_action_get_1(net, tb[i], n, portid, extack);
1016 if (IS_ERR(act)) { 1094 if (IS_ERR(act)) {
1017 ret = PTR_ERR(act); 1095 ret = PTR_ERR(act);
1018 goto err; 1096 goto err;
1019 } 1097 }
1020 act->order = i; 1098 act->order = i;
1099 attr_size += tcf_action_fill_size(act);
1021 list_add_tail(&act->list, &actions); 1100 list_add_tail(&act->list, &actions);
1022 } 1101 }
1023 1102
1103 attr_size = tcf_action_full_attrs_size(attr_size);
1104
1024 if (event == RTM_GETACTION) 1105 if (event == RTM_GETACTION)
1025 ret = tcf_get_notify(net, portid, n, &actions, event); 1106 ret = tcf_get_notify(net, portid, n, &actions, event, extack);
1026 else { /* delete */ 1107 else { /* delete */
1027 ret = tcf_del_notify(net, n, &actions, portid); 1108 ret = tcf_del_notify(net, n, &actions, portid, attr_size, extack);
1028 if (ret) 1109 if (ret)
1029 goto err; 1110 goto err;
1030 return ret; 1111 return ret;
@@ -1037,17 +1118,19 @@ err:
1037 1118
1038static int 1119static int
1039tcf_add_notify(struct net *net, struct nlmsghdr *n, struct list_head *actions, 1120tcf_add_notify(struct net *net, struct nlmsghdr *n, struct list_head *actions,
1040 u32 portid) 1121 u32 portid, size_t attr_size, struct netlink_ext_ack *extack)
1041{ 1122{
1042 struct sk_buff *skb; 1123 struct sk_buff *skb;
1043 int err = 0; 1124 int err = 0;
1044 1125
1045 skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); 1126 skb = alloc_skb(attr_size <= NLMSG_GOODSIZE ? NLMSG_GOODSIZE : attr_size,
1127 GFP_KERNEL);
1046 if (!skb) 1128 if (!skb)
1047 return -ENOBUFS; 1129 return -ENOBUFS;
1048 1130
1049 if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, n->nlmsg_flags, 1131 if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, n->nlmsg_flags,
1050 RTM_NEWACTION, 0, 0) <= 0) { 1132 RTM_NEWACTION, 0, 0) <= 0) {
1133 NL_SET_ERR_MSG(extack, "Failed to fill netlink attributes while adding TC action");
1051 kfree_skb(skb); 1134 kfree_skb(skb);
1052 return -EINVAL; 1135 return -EINVAL;
1053 } 1136 }
@@ -1060,16 +1143,19 @@ tcf_add_notify(struct net *net, struct nlmsghdr *n, struct list_head *actions,
1060} 1143}
1061 1144
1062static int tcf_action_add(struct net *net, struct nlattr *nla, 1145static int tcf_action_add(struct net *net, struct nlattr *nla,
1063 struct nlmsghdr *n, u32 portid, int ovr) 1146 struct nlmsghdr *n, u32 portid, int ovr,
1147 struct netlink_ext_ack *extack)
1064{ 1148{
1149 size_t attr_size = 0;
1065 int ret = 0; 1150 int ret = 0;
1066 LIST_HEAD(actions); 1151 LIST_HEAD(actions);
1067 1152
1068 ret = tcf_action_init(net, NULL, nla, NULL, NULL, ovr, 0, &actions); 1153 ret = tcf_action_init(net, NULL, nla, NULL, NULL, ovr, 0, &actions,
1154 &attr_size, extack);
1069 if (ret) 1155 if (ret)
1070 return ret; 1156 return ret;
1071 1157
1072 return tcf_add_notify(net, n, &actions, portid); 1158 return tcf_add_notify(net, n, &actions, portid, attr_size, extack);
1073} 1159}
1074 1160
1075static u32 tcaa_root_flags_allowed = TCA_FLAG_LARGE_DUMP_ON; 1161static u32 tcaa_root_flags_allowed = TCA_FLAG_LARGE_DUMP_ON;
@@ -1097,7 +1183,7 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n,
1097 return ret; 1183 return ret;
1098 1184
1099 if (tca[TCA_ACT_TAB] == NULL) { 1185 if (tca[TCA_ACT_TAB] == NULL) {
1100 pr_notice("tc_ctl_action: received NO action attribs\n"); 1186 NL_SET_ERR_MSG(extack, "Netlink action attributes missing");
1101 return -EINVAL; 1187 return -EINVAL;
1102 } 1188 }
1103 1189
@@ -1113,17 +1199,18 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n,
1113 if (n->nlmsg_flags & NLM_F_REPLACE) 1199 if (n->nlmsg_flags & NLM_F_REPLACE)
1114 ovr = 1; 1200 ovr = 1;
1115replay: 1201replay:
1116 ret = tcf_action_add(net, tca[TCA_ACT_TAB], n, portid, ovr); 1202 ret = tcf_action_add(net, tca[TCA_ACT_TAB], n, portid, ovr,
1203 extack);
1117 if (ret == -EAGAIN) 1204 if (ret == -EAGAIN)
1118 goto replay; 1205 goto replay;
1119 break; 1206 break;
1120 case RTM_DELACTION: 1207 case RTM_DELACTION:
1121 ret = tca_action_gd(net, tca[TCA_ACT_TAB], n, 1208 ret = tca_action_gd(net, tca[TCA_ACT_TAB], n,
1122 portid, RTM_DELACTION); 1209 portid, RTM_DELACTION, extack);
1123 break; 1210 break;
1124 case RTM_GETACTION: 1211 case RTM_GETACTION:
1125 ret = tca_action_gd(net, tca[TCA_ACT_TAB], n, 1212 ret = tca_action_gd(net, tca[TCA_ACT_TAB], n,
1126 portid, RTM_GETACTION); 1213 portid, RTM_GETACTION, extack);
1127 break; 1214 break;
1128 default: 1215 default:
1129 BUG(); 1216 BUG();
@@ -1218,7 +1305,7 @@ static int tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
1218 if (nest == NULL) 1305 if (nest == NULL)
1219 goto out_module_put; 1306 goto out_module_put;
1220 1307
1221 ret = a_o->walk(net, skb, cb, RTM_GETACTION, a_o); 1308 ret = a_o->walk(net, skb, cb, RTM_GETACTION, a_o, NULL);
1222 if (ret < 0) 1309 if (ret < 0)
1223 goto out_module_put; 1310 goto out_module_put;
1224 1311
@@ -1454,6 +1541,7 @@ static struct pernet_operations tcf_action_net_ops = {
1454 .exit = tcf_action_net_exit, 1541 .exit = tcf_action_net_exit,
1455 .id = &tcf_action_net_id, 1542 .id = &tcf_action_net_id,
1456 .size = sizeof(struct tcf_action_net), 1543 .size = sizeof(struct tcf_action_net),
1544 .async = true,
1457}; 1545};
1458 1546
1459static int __init tc_action_init(void) 1547static int __init tc_action_init(void)
diff --git a/net/sched/act_bpf.c b/net/sched/act_bpf.c
index 9d2cabf1dc7e..5cb9b268e8ff 100644
--- a/net/sched/act_bpf.c
+++ b/net/sched/act_bpf.c
@@ -272,7 +272,7 @@ static void tcf_bpf_prog_fill_cfg(const struct tcf_bpf *prog,
272 272
273static int tcf_bpf_init(struct net *net, struct nlattr *nla, 273static int tcf_bpf_init(struct net *net, struct nlattr *nla,
274 struct nlattr *est, struct tc_action **act, 274 struct nlattr *est, struct tc_action **act,
275 int replace, int bind) 275 int replace, int bind, struct netlink_ext_ack *extack)
276{ 276{
277 struct tc_action_net *tn = net_generic(net, bpf_net_id); 277 struct tc_action_net *tn = net_generic(net, bpf_net_id);
278 struct nlattr *tb[TCA_ACT_BPF_MAX + 1]; 278 struct nlattr *tb[TCA_ACT_BPF_MAX + 1];
@@ -367,14 +367,16 @@ static void tcf_bpf_cleanup(struct tc_action *act)
367 367
368static int tcf_bpf_walker(struct net *net, struct sk_buff *skb, 368static int tcf_bpf_walker(struct net *net, struct sk_buff *skb,
369 struct netlink_callback *cb, int type, 369 struct netlink_callback *cb, int type,
370 const struct tc_action_ops *ops) 370 const struct tc_action_ops *ops,
371 struct netlink_ext_ack *extack)
371{ 372{
372 struct tc_action_net *tn = net_generic(net, bpf_net_id); 373 struct tc_action_net *tn = net_generic(net, bpf_net_id);
373 374
374 return tcf_generic_walker(tn, skb, cb, type, ops); 375 return tcf_generic_walker(tn, skb, cb, type, ops, extack);
375} 376}
376 377
377static int tcf_bpf_search(struct net *net, struct tc_action **a, u32 index) 378static int tcf_bpf_search(struct net *net, struct tc_action **a, u32 index,
379 struct netlink_ext_ack *extack)
378{ 380{
379 struct tc_action_net *tn = net_generic(net, bpf_net_id); 381 struct tc_action_net *tn = net_generic(net, bpf_net_id);
380 382
@@ -411,6 +413,7 @@ static struct pernet_operations bpf_net_ops = {
411 .exit_batch = bpf_exit_net, 413 .exit_batch = bpf_exit_net,
412 .id = &bpf_net_id, 414 .id = &bpf_net_id,
413 .size = sizeof(struct tc_action_net), 415 .size = sizeof(struct tc_action_net),
416 .async = true,
414}; 417};
415 418
416static int __init bpf_init_module(void) 419static int __init bpf_init_module(void)
diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c
index 2b15ba84e0c8..371e5e4ab3e2 100644
--- a/net/sched/act_connmark.c
+++ b/net/sched/act_connmark.c
@@ -96,7 +96,8 @@ static const struct nla_policy connmark_policy[TCA_CONNMARK_MAX + 1] = {
96 96
97static int tcf_connmark_init(struct net *net, struct nlattr *nla, 97static int tcf_connmark_init(struct net *net, struct nlattr *nla,
98 struct nlattr *est, struct tc_action **a, 98 struct nlattr *est, struct tc_action **a,
99 int ovr, int bind) 99 int ovr, int bind,
100 struct netlink_ext_ack *extack)
100{ 101{
101 struct tc_action_net *tn = net_generic(net, connmark_net_id); 102 struct tc_action_net *tn = net_generic(net, connmark_net_id);
102 struct nlattr *tb[TCA_CONNMARK_MAX + 1]; 103 struct nlattr *tb[TCA_CONNMARK_MAX + 1];
@@ -176,14 +177,16 @@ nla_put_failure:
176 177
177static int tcf_connmark_walker(struct net *net, struct sk_buff *skb, 178static int tcf_connmark_walker(struct net *net, struct sk_buff *skb,
178 struct netlink_callback *cb, int type, 179 struct netlink_callback *cb, int type,
179 const struct tc_action_ops *ops) 180 const struct tc_action_ops *ops,
181 struct netlink_ext_ack *extack)
180{ 182{
181 struct tc_action_net *tn = net_generic(net, connmark_net_id); 183 struct tc_action_net *tn = net_generic(net, connmark_net_id);
182 184
183 return tcf_generic_walker(tn, skb, cb, type, ops); 185 return tcf_generic_walker(tn, skb, cb, type, ops, extack);
184} 186}
185 187
186static int tcf_connmark_search(struct net *net, struct tc_action **a, u32 index) 188static int tcf_connmark_search(struct net *net, struct tc_action **a, u32 index,
189 struct netlink_ext_ack *extack)
187{ 190{
188 struct tc_action_net *tn = net_generic(net, connmark_net_id); 191 struct tc_action_net *tn = net_generic(net, connmark_net_id);
189 192
@@ -219,6 +222,7 @@ static struct pernet_operations connmark_net_ops = {
219 .exit_batch = connmark_exit_net, 222 .exit_batch = connmark_exit_net,
220 .id = &connmark_net_id, 223 .id = &connmark_net_id,
221 .size = sizeof(struct tc_action_net), 224 .size = sizeof(struct tc_action_net),
225 .async = true,
222}; 226};
223 227
224static int __init connmark_init_module(void) 228static int __init connmark_init_module(void)
diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c
index 2a5c8fd860cf..a527e287c086 100644
--- a/net/sched/act_csum.c
+++ b/net/sched/act_csum.c
@@ -46,7 +46,7 @@ static struct tc_action_ops act_csum_ops;
46 46
47static int tcf_csum_init(struct net *net, struct nlattr *nla, 47static int tcf_csum_init(struct net *net, struct nlattr *nla,
48 struct nlattr *est, struct tc_action **a, int ovr, 48 struct nlattr *est, struct tc_action **a, int ovr,
49 int bind) 49 int bind, struct netlink_ext_ack *extack)
50{ 50{
51 struct tc_action_net *tn = net_generic(net, csum_net_id); 51 struct tc_action_net *tn = net_generic(net, csum_net_id);
52 struct tcf_csum_params *params_old, *params_new; 52 struct tcf_csum_params *params_old, *params_new;
@@ -632,14 +632,16 @@ static void tcf_csum_cleanup(struct tc_action *a)
632 632
633static int tcf_csum_walker(struct net *net, struct sk_buff *skb, 633static int tcf_csum_walker(struct net *net, struct sk_buff *skb,
634 struct netlink_callback *cb, int type, 634 struct netlink_callback *cb, int type,
635 const struct tc_action_ops *ops) 635 const struct tc_action_ops *ops,
636 struct netlink_ext_ack *extack)
636{ 637{
637 struct tc_action_net *tn = net_generic(net, csum_net_id); 638 struct tc_action_net *tn = net_generic(net, csum_net_id);
638 639
639 return tcf_generic_walker(tn, skb, cb, type, ops); 640 return tcf_generic_walker(tn, skb, cb, type, ops, extack);
640} 641}
641 642
642static int tcf_csum_search(struct net *net, struct tc_action **a, u32 index) 643static int tcf_csum_search(struct net *net, struct tc_action **a, u32 index,
644 struct netlink_ext_ack *extack)
643{ 645{
644 struct tc_action_net *tn = net_generic(net, csum_net_id); 646 struct tc_action_net *tn = net_generic(net, csum_net_id);
645 647
@@ -676,6 +678,7 @@ static struct pernet_operations csum_net_ops = {
676 .exit_batch = csum_exit_net, 678 .exit_batch = csum_exit_net,
677 .id = &csum_net_id, 679 .id = &csum_net_id,
678 .size = sizeof(struct tc_action_net), 680 .size = sizeof(struct tc_action_net),
681 .async = true,
679}; 682};
680 683
681MODULE_DESCRIPTION("Checksum updating actions"); 684MODULE_DESCRIPTION("Checksum updating actions");
diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c
index b56986d41c87..88fbb8403565 100644
--- a/net/sched/act_gact.c
+++ b/net/sched/act_gact.c
@@ -56,7 +56,7 @@ static const struct nla_policy gact_policy[TCA_GACT_MAX + 1] = {
56 56
57static int tcf_gact_init(struct net *net, struct nlattr *nla, 57static int tcf_gact_init(struct net *net, struct nlattr *nla,
58 struct nlattr *est, struct tc_action **a, 58 struct nlattr *est, struct tc_action **a,
59 int ovr, int bind) 59 int ovr, int bind, struct netlink_ext_ack *extack)
60{ 60{
61 struct tc_action_net *tn = net_generic(net, gact_net_id); 61 struct tc_action_net *tn = net_generic(net, gact_net_id);
62 struct nlattr *tb[TCA_GACT_MAX + 1]; 62 struct nlattr *tb[TCA_GACT_MAX + 1];
@@ -201,20 +201,35 @@ nla_put_failure:
201 201
202static int tcf_gact_walker(struct net *net, struct sk_buff *skb, 202static int tcf_gact_walker(struct net *net, struct sk_buff *skb,
203 struct netlink_callback *cb, int type, 203 struct netlink_callback *cb, int type,
204 const struct tc_action_ops *ops) 204 const struct tc_action_ops *ops,
205 struct netlink_ext_ack *extack)
205{ 206{
206 struct tc_action_net *tn = net_generic(net, gact_net_id); 207 struct tc_action_net *tn = net_generic(net, gact_net_id);
207 208
208 return tcf_generic_walker(tn, skb, cb, type, ops); 209 return tcf_generic_walker(tn, skb, cb, type, ops, extack);
209} 210}
210 211
211static int tcf_gact_search(struct net *net, struct tc_action **a, u32 index) 212static int tcf_gact_search(struct net *net, struct tc_action **a, u32 index,
213 struct netlink_ext_ack *extack)
212{ 214{
213 struct tc_action_net *tn = net_generic(net, gact_net_id); 215 struct tc_action_net *tn = net_generic(net, gact_net_id);
214 216
215 return tcf_idr_search(tn, a, index); 217 return tcf_idr_search(tn, a, index);
216} 218}
217 219
220static size_t tcf_gact_get_fill_size(const struct tc_action *act)
221{
222 size_t sz = nla_total_size(sizeof(struct tc_gact)); /* TCA_GACT_PARMS */
223
224#ifdef CONFIG_GACT_PROB
225 if (to_gact(act)->tcfg_ptype)
226 /* TCA_GACT_PROB */
227 sz += nla_total_size(sizeof(struct tc_gact_p));
228#endif
229
230 return sz;
231}
232
218static struct tc_action_ops act_gact_ops = { 233static struct tc_action_ops act_gact_ops = {
219 .kind = "gact", 234 .kind = "gact",
220 .type = TCA_ACT_GACT, 235 .type = TCA_ACT_GACT,
@@ -225,6 +240,7 @@ static struct tc_action_ops act_gact_ops = {
225 .init = tcf_gact_init, 240 .init = tcf_gact_init,
226 .walk = tcf_gact_walker, 241 .walk = tcf_gact_walker,
227 .lookup = tcf_gact_search, 242 .lookup = tcf_gact_search,
243 .get_fill_size = tcf_gact_get_fill_size,
228 .size = sizeof(struct tcf_gact), 244 .size = sizeof(struct tcf_gact),
229}; 245};
230 246
@@ -245,6 +261,7 @@ static struct pernet_operations gact_net_ops = {
245 .exit_batch = gact_exit_net, 261 .exit_batch = gact_exit_net,
246 .id = &gact_net_id, 262 .id = &gact_net_id,
247 .size = sizeof(struct tc_action_net), 263 .size = sizeof(struct tc_action_net),
264 .async = true,
248}; 265};
249 266
250MODULE_AUTHOR("Jamal Hadi Salim(2002-4)"); 267MODULE_AUTHOR("Jamal Hadi Salim(2002-4)");
diff --git a/net/sched/act_ife.c b/net/sched/act_ife.c
index 5954e992685a..555b1caeff72 100644
--- a/net/sched/act_ife.c
+++ b/net/sched/act_ife.c
@@ -447,7 +447,7 @@ static int populate_metalist(struct tcf_ife_info *ife, struct nlattr **tb,
447 447
448static int tcf_ife_init(struct net *net, struct nlattr *nla, 448static int tcf_ife_init(struct net *net, struct nlattr *nla,
449 struct nlattr *est, struct tc_action **a, 449 struct nlattr *est, struct tc_action **a,
450 int ovr, int bind) 450 int ovr, int bind, struct netlink_ext_ack *extack)
451{ 451{
452 struct tc_action_net *tn = net_generic(net, ife_net_id); 452 struct tc_action_net *tn = net_generic(net, ife_net_id);
453 struct nlattr *tb[TCA_IFE_MAX + 1]; 453 struct nlattr *tb[TCA_IFE_MAX + 1];
@@ -824,14 +824,16 @@ static int tcf_ife_act(struct sk_buff *skb, const struct tc_action *a,
824 824
825static int tcf_ife_walker(struct net *net, struct sk_buff *skb, 825static int tcf_ife_walker(struct net *net, struct sk_buff *skb,
826 struct netlink_callback *cb, int type, 826 struct netlink_callback *cb, int type,
827 const struct tc_action_ops *ops) 827 const struct tc_action_ops *ops,
828 struct netlink_ext_ack *extack)
828{ 829{
829 struct tc_action_net *tn = net_generic(net, ife_net_id); 830 struct tc_action_net *tn = net_generic(net, ife_net_id);
830 831
831 return tcf_generic_walker(tn, skb, cb, type, ops); 832 return tcf_generic_walker(tn, skb, cb, type, ops, extack);
832} 833}
833 834
834static int tcf_ife_search(struct net *net, struct tc_action **a, u32 index) 835static int tcf_ife_search(struct net *net, struct tc_action **a, u32 index,
836 struct netlink_ext_ack *extack)
835{ 837{
836 struct tc_action_net *tn = net_generic(net, ife_net_id); 838 struct tc_action_net *tn = net_generic(net, ife_net_id);
837 839
@@ -868,6 +870,7 @@ static struct pernet_operations ife_net_ops = {
868 .exit_batch = ife_exit_net, 870 .exit_batch = ife_exit_net,
869 .id = &ife_net_id, 871 .id = &ife_net_id,
870 .size = sizeof(struct tc_action_net), 872 .size = sizeof(struct tc_action_net),
873 .async = true,
871}; 874};
872 875
873static int __init ife_init_module(void) 876static int __init ife_init_module(void)
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c
index 7e06b9b62613..b5e8565b89c7 100644
--- a/net/sched/act_ipt.c
+++ b/net/sched/act_ipt.c
@@ -196,7 +196,7 @@ err1:
196 196
197static int tcf_ipt_init(struct net *net, struct nlattr *nla, 197static int tcf_ipt_init(struct net *net, struct nlattr *nla,
198 struct nlattr *est, struct tc_action **a, int ovr, 198 struct nlattr *est, struct tc_action **a, int ovr,
199 int bind) 199 int bind, struct netlink_ext_ack *extack)
200{ 200{
201 return __tcf_ipt_init(net, ipt_net_id, nla, est, a, &act_ipt_ops, ovr, 201 return __tcf_ipt_init(net, ipt_net_id, nla, est, a, &act_ipt_ops, ovr,
202 bind); 202 bind);
@@ -204,7 +204,7 @@ static int tcf_ipt_init(struct net *net, struct nlattr *nla,
204 204
205static int tcf_xt_init(struct net *net, struct nlattr *nla, 205static int tcf_xt_init(struct net *net, struct nlattr *nla,
206 struct nlattr *est, struct tc_action **a, int ovr, 206 struct nlattr *est, struct tc_action **a, int ovr,
207 int bind) 207 int bind, struct netlink_ext_ack *extack)
208{ 208{
209 return __tcf_ipt_init(net, xt_net_id, nla, est, a, &act_xt_ops, ovr, 209 return __tcf_ipt_init(net, xt_net_id, nla, est, a, &act_xt_ops, ovr,
210 bind); 210 bind);
@@ -306,14 +306,16 @@ nla_put_failure:
306 306
307static int tcf_ipt_walker(struct net *net, struct sk_buff *skb, 307static int tcf_ipt_walker(struct net *net, struct sk_buff *skb,
308 struct netlink_callback *cb, int type, 308 struct netlink_callback *cb, int type,
309 const struct tc_action_ops *ops) 309 const struct tc_action_ops *ops,
310 struct netlink_ext_ack *extack)
310{ 311{
311 struct tc_action_net *tn = net_generic(net, ipt_net_id); 312 struct tc_action_net *tn = net_generic(net, ipt_net_id);
312 313
313 return tcf_generic_walker(tn, skb, cb, type, ops); 314 return tcf_generic_walker(tn, skb, cb, type, ops, extack);
314} 315}
315 316
316static int tcf_ipt_search(struct net *net, struct tc_action **a, u32 index) 317static int tcf_ipt_search(struct net *net, struct tc_action **a, u32 index,
318 struct netlink_ext_ack *extack)
317{ 319{
318 struct tc_action_net *tn = net_generic(net, ipt_net_id); 320 struct tc_action_net *tn = net_generic(net, ipt_net_id);
319 321
@@ -350,18 +352,21 @@ static struct pernet_operations ipt_net_ops = {
350 .exit_batch = ipt_exit_net, 352 .exit_batch = ipt_exit_net,
351 .id = &ipt_net_id, 353 .id = &ipt_net_id,
352 .size = sizeof(struct tc_action_net), 354 .size = sizeof(struct tc_action_net),
355 .async = true,
353}; 356};
354 357
355static int tcf_xt_walker(struct net *net, struct sk_buff *skb, 358static int tcf_xt_walker(struct net *net, struct sk_buff *skb,
356 struct netlink_callback *cb, int type, 359 struct netlink_callback *cb, int type,
357 const struct tc_action_ops *ops) 360 const struct tc_action_ops *ops,
361 struct netlink_ext_ack *extack)
358{ 362{
359 struct tc_action_net *tn = net_generic(net, xt_net_id); 363 struct tc_action_net *tn = net_generic(net, xt_net_id);
360 364
361 return tcf_generic_walker(tn, skb, cb, type, ops); 365 return tcf_generic_walker(tn, skb, cb, type, ops, extack);
362} 366}
363 367
364static int tcf_xt_search(struct net *net, struct tc_action **a, u32 index) 368static int tcf_xt_search(struct net *net, struct tc_action **a, u32 index,
369 struct netlink_ext_ack *extack)
365{ 370{
366 struct tc_action_net *tn = net_generic(net, xt_net_id); 371 struct tc_action_net *tn = net_generic(net, xt_net_id);
367 372
@@ -398,6 +403,7 @@ static struct pernet_operations xt_net_ops = {
398 .exit_batch = xt_exit_net, 403 .exit_batch = xt_exit_net,
399 .id = &xt_net_id, 404 .id = &xt_net_id,
400 .size = sizeof(struct tc_action_net), 405 .size = sizeof(struct tc_action_net),
406 .async = true,
401}; 407};
402 408
403MODULE_AUTHOR("Jamal Hadi Salim(2002-13)"); 409MODULE_AUTHOR("Jamal Hadi Salim(2002-13)");
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
index e6ff88f72900..64c86579c3d9 100644
--- a/net/sched/act_mirred.c
+++ b/net/sched/act_mirred.c
@@ -69,7 +69,7 @@ static struct tc_action_ops act_mirred_ops;
69 69
70static int tcf_mirred_init(struct net *net, struct nlattr *nla, 70static int tcf_mirred_init(struct net *net, struct nlattr *nla,
71 struct nlattr *est, struct tc_action **a, int ovr, 71 struct nlattr *est, struct tc_action **a, int ovr,
72 int bind) 72 int bind, struct netlink_ext_ack *extack)
73{ 73{
74 struct tc_action_net *tn = net_generic(net, mirred_net_id); 74 struct tc_action_net *tn = net_generic(net, mirred_net_id);
75 struct nlattr *tb[TCA_MIRRED_MAX + 1]; 75 struct nlattr *tb[TCA_MIRRED_MAX + 1];
@@ -80,13 +80,17 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
80 bool exists = false; 80 bool exists = false;
81 int ret; 81 int ret;
82 82
83 if (nla == NULL) 83 if (!nla) {
84 NL_SET_ERR_MSG_MOD(extack, "Mirred requires attributes to be passed");
84 return -EINVAL; 85 return -EINVAL;
85 ret = nla_parse_nested(tb, TCA_MIRRED_MAX, nla, mirred_policy, NULL); 86 }
87 ret = nla_parse_nested(tb, TCA_MIRRED_MAX, nla, mirred_policy, extack);
86 if (ret < 0) 88 if (ret < 0)
87 return ret; 89 return ret;
88 if (tb[TCA_MIRRED_PARMS] == NULL) 90 if (!tb[TCA_MIRRED_PARMS]) {
91 NL_SET_ERR_MSG_MOD(extack, "Missing required mirred parameters");
89 return -EINVAL; 92 return -EINVAL;
93 }
90 parm = nla_data(tb[TCA_MIRRED_PARMS]); 94 parm = nla_data(tb[TCA_MIRRED_PARMS]);
91 95
92 exists = tcf_idr_check(tn, parm->index, a, bind); 96 exists = tcf_idr_check(tn, parm->index, a, bind);
@@ -102,6 +106,7 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
102 default: 106 default:
103 if (exists) 107 if (exists)
104 tcf_idr_release(*a, bind); 108 tcf_idr_release(*a, bind);
109 NL_SET_ERR_MSG_MOD(extack, "Unknown mirred option");
105 return -EINVAL; 110 return -EINVAL;
106 } 111 }
107 if (parm->ifindex) { 112 if (parm->ifindex) {
@@ -117,8 +122,10 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
117 } 122 }
118 123
119 if (!exists) { 124 if (!exists) {
120 if (dev == NULL) 125 if (!dev) {
126 NL_SET_ERR_MSG_MOD(extack, "Specified device does not exist");
121 return -EINVAL; 127 return -EINVAL;
128 }
122 ret = tcf_idr_create(tn, parm->index, est, a, 129 ret = tcf_idr_create(tn, parm->index, est, a,
123 &act_mirred_ops, bind, true); 130 &act_mirred_ops, bind, true);
124 if (ret) 131 if (ret)
@@ -265,14 +272,16 @@ nla_put_failure:
265 272
266static int tcf_mirred_walker(struct net *net, struct sk_buff *skb, 273static int tcf_mirred_walker(struct net *net, struct sk_buff *skb,
267 struct netlink_callback *cb, int type, 274 struct netlink_callback *cb, int type,
268 const struct tc_action_ops *ops) 275 const struct tc_action_ops *ops,
276 struct netlink_ext_ack *extack)
269{ 277{
270 struct tc_action_net *tn = net_generic(net, mirred_net_id); 278 struct tc_action_net *tn = net_generic(net, mirred_net_id);
271 279
272 return tcf_generic_walker(tn, skb, cb, type, ops); 280 return tcf_generic_walker(tn, skb, cb, type, ops, extack);
273} 281}
274 282
275static int tcf_mirred_search(struct net *net, struct tc_action **a, u32 index) 283static int tcf_mirred_search(struct net *net, struct tc_action **a, u32 index,
284 struct netlink_ext_ack *extack)
276{ 285{
277 struct tc_action_net *tn = net_generic(net, mirred_net_id); 286 struct tc_action_net *tn = net_generic(net, mirred_net_id);
278 287
@@ -344,6 +353,7 @@ static struct pernet_operations mirred_net_ops = {
344 .exit_batch = mirred_exit_net, 353 .exit_batch = mirred_exit_net,
345 .id = &mirred_net_id, 354 .id = &mirred_net_id,
346 .size = sizeof(struct tc_action_net), 355 .size = sizeof(struct tc_action_net),
356 .async = true,
347}; 357};
348 358
349MODULE_AUTHOR("Jamal Hadi Salim(2002)"); 359MODULE_AUTHOR("Jamal Hadi Salim(2002)");
diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c
index 98c6a4b2f523..b1bc757f6491 100644
--- a/net/sched/act_nat.c
+++ b/net/sched/act_nat.c
@@ -37,7 +37,8 @@ static const struct nla_policy nat_policy[TCA_NAT_MAX + 1] = {
37}; 37};
38 38
39static int tcf_nat_init(struct net *net, struct nlattr *nla, struct nlattr *est, 39static int tcf_nat_init(struct net *net, struct nlattr *nla, struct nlattr *est,
40 struct tc_action **a, int ovr, int bind) 40 struct tc_action **a, int ovr, int bind,
41 struct netlink_ext_ack *extack)
41{ 42{
42 struct tc_action_net *tn = net_generic(net, nat_net_id); 43 struct tc_action_net *tn = net_generic(net, nat_net_id);
43 struct nlattr *tb[TCA_NAT_MAX + 1]; 44 struct nlattr *tb[TCA_NAT_MAX + 1];
@@ -277,14 +278,16 @@ nla_put_failure:
277 278
278static int tcf_nat_walker(struct net *net, struct sk_buff *skb, 279static int tcf_nat_walker(struct net *net, struct sk_buff *skb,
279 struct netlink_callback *cb, int type, 280 struct netlink_callback *cb, int type,
280 const struct tc_action_ops *ops) 281 const struct tc_action_ops *ops,
282 struct netlink_ext_ack *extack)
281{ 283{
282 struct tc_action_net *tn = net_generic(net, nat_net_id); 284 struct tc_action_net *tn = net_generic(net, nat_net_id);
283 285
284 return tcf_generic_walker(tn, skb, cb, type, ops); 286 return tcf_generic_walker(tn, skb, cb, type, ops, extack);
285} 287}
286 288
287static int tcf_nat_search(struct net *net, struct tc_action **a, u32 index) 289static int tcf_nat_search(struct net *net, struct tc_action **a, u32 index,
290 struct netlink_ext_ack *extack)
288{ 291{
289 struct tc_action_net *tn = net_generic(net, nat_net_id); 292 struct tc_action_net *tn = net_generic(net, nat_net_id);
290 293
@@ -320,6 +323,7 @@ static struct pernet_operations nat_net_ops = {
320 .exit_batch = nat_exit_net, 323 .exit_batch = nat_exit_net,
321 .id = &nat_net_id, 324 .id = &nat_net_id,
322 .size = sizeof(struct tc_action_net), 325 .size = sizeof(struct tc_action_net),
326 .async = true,
323}; 327};
324 328
325MODULE_DESCRIPTION("Stateless NAT actions"); 329MODULE_DESCRIPTION("Stateless NAT actions");
diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c
index fef08835f26d..f392ccaaa0d8 100644
--- a/net/sched/act_pedit.c
+++ b/net/sched/act_pedit.c
@@ -132,7 +132,7 @@ static int tcf_pedit_key_ex_dump(struct sk_buff *skb,
132 132
133static int tcf_pedit_init(struct net *net, struct nlattr *nla, 133static int tcf_pedit_init(struct net *net, struct nlattr *nla,
134 struct nlattr *est, struct tc_action **a, 134 struct nlattr *est, struct tc_action **a,
135 int ovr, int bind) 135 int ovr, int bind, struct netlink_ext_ack *extack)
136{ 136{
137 struct tc_action_net *tn = net_generic(net, pedit_net_id); 137 struct tc_action_net *tn = net_generic(net, pedit_net_id);
138 struct nlattr *tb[TCA_PEDIT_MAX + 1]; 138 struct nlattr *tb[TCA_PEDIT_MAX + 1];
@@ -419,14 +419,16 @@ nla_put_failure:
419 419
420static int tcf_pedit_walker(struct net *net, struct sk_buff *skb, 420static int tcf_pedit_walker(struct net *net, struct sk_buff *skb,
421 struct netlink_callback *cb, int type, 421 struct netlink_callback *cb, int type,
422 const struct tc_action_ops *ops) 422 const struct tc_action_ops *ops,
423 struct netlink_ext_ack *extack)
423{ 424{
424 struct tc_action_net *tn = net_generic(net, pedit_net_id); 425 struct tc_action_net *tn = net_generic(net, pedit_net_id);
425 426
426 return tcf_generic_walker(tn, skb, cb, type, ops); 427 return tcf_generic_walker(tn, skb, cb, type, ops, extack);
427} 428}
428 429
429static int tcf_pedit_search(struct net *net, struct tc_action **a, u32 index) 430static int tcf_pedit_search(struct net *net, struct tc_action **a, u32 index,
431 struct netlink_ext_ack *extack)
430{ 432{
431 struct tc_action_net *tn = net_generic(net, pedit_net_id); 433 struct tc_action_net *tn = net_generic(net, pedit_net_id);
432 434
@@ -463,6 +465,7 @@ static struct pernet_operations pedit_net_ops = {
463 .exit_batch = pedit_exit_net, 465 .exit_batch = pedit_exit_net,
464 .id = &pedit_net_id, 466 .id = &pedit_net_id,
465 .size = sizeof(struct tc_action_net), 467 .size = sizeof(struct tc_action_net),
468 .async = true,
466}; 469};
467 470
468MODULE_AUTHOR("Jamal Hadi Salim(2002-4)"); 471MODULE_AUTHOR("Jamal Hadi Salim(2002-4)");
diff --git a/net/sched/act_police.c b/net/sched/act_police.c
index faebf82b99f1..7081ec75e696 100644
--- a/net/sched/act_police.c
+++ b/net/sched/act_police.c
@@ -58,11 +58,12 @@ static struct tc_action_ops act_police_ops;
58 58
59static int tcf_act_police_walker(struct net *net, struct sk_buff *skb, 59static int tcf_act_police_walker(struct net *net, struct sk_buff *skb,
60 struct netlink_callback *cb, int type, 60 struct netlink_callback *cb, int type,
61 const struct tc_action_ops *ops) 61 const struct tc_action_ops *ops,
62 struct netlink_ext_ack *extack)
62{ 63{
63 struct tc_action_net *tn = net_generic(net, police_net_id); 64 struct tc_action_net *tn = net_generic(net, police_net_id);
64 65
65 return tcf_generic_walker(tn, skb, cb, type, ops); 66 return tcf_generic_walker(tn, skb, cb, type, ops, extack);
66} 67}
67 68
68static const struct nla_policy police_policy[TCA_POLICE_MAX + 1] = { 69static const struct nla_policy police_policy[TCA_POLICE_MAX + 1] = {
@@ -74,7 +75,8 @@ static const struct nla_policy police_policy[TCA_POLICE_MAX + 1] = {
74 75
75static int tcf_act_police_init(struct net *net, struct nlattr *nla, 76static int tcf_act_police_init(struct net *net, struct nlattr *nla,
76 struct nlattr *est, struct tc_action **a, 77 struct nlattr *est, struct tc_action **a,
77 int ovr, int bind) 78 int ovr, int bind,
79 struct netlink_ext_ack *extack)
78{ 80{
79 int ret = 0, err; 81 int ret = 0, err;
80 struct nlattr *tb[TCA_POLICE_MAX + 1]; 82 struct nlattr *tb[TCA_POLICE_MAX + 1];
@@ -304,7 +306,8 @@ nla_put_failure:
304 return -1; 306 return -1;
305} 307}
306 308
307static int tcf_police_search(struct net *net, struct tc_action **a, u32 index) 309static int tcf_police_search(struct net *net, struct tc_action **a, u32 index,
310 struct netlink_ext_ack *extack)
308{ 311{
309 struct tc_action_net *tn = net_generic(net, police_net_id); 312 struct tc_action_net *tn = net_generic(net, police_net_id);
310 313
@@ -344,6 +347,7 @@ static struct pernet_operations police_net_ops = {
344 .exit_batch = police_exit_net, 347 .exit_batch = police_exit_net,
345 .id = &police_net_id, 348 .id = &police_net_id,
346 .size = sizeof(struct tc_action_net), 349 .size = sizeof(struct tc_action_net),
350 .async = true,
347}; 351};
348 352
349static int __init police_init_module(void) 353static int __init police_init_module(void)
diff --git a/net/sched/act_sample.c b/net/sched/act_sample.c
index 74c5d7e6a0fa..3a89f98f17e6 100644
--- a/net/sched/act_sample.c
+++ b/net/sched/act_sample.c
@@ -37,7 +37,7 @@ static const struct nla_policy sample_policy[TCA_SAMPLE_MAX + 1] = {
37 37
38static int tcf_sample_init(struct net *net, struct nlattr *nla, 38static int tcf_sample_init(struct net *net, struct nlattr *nla,
39 struct nlattr *est, struct tc_action **a, int ovr, 39 struct nlattr *est, struct tc_action **a, int ovr,
40 int bind) 40 int bind, struct netlink_ext_ack *extack)
41{ 41{
42 struct tc_action_net *tn = net_generic(net, sample_net_id); 42 struct tc_action_net *tn = net_generic(net, sample_net_id);
43 struct nlattr *tb[TCA_SAMPLE_MAX + 1]; 43 struct nlattr *tb[TCA_SAMPLE_MAX + 1];
@@ -203,14 +203,16 @@ nla_put_failure:
203 203
204static int tcf_sample_walker(struct net *net, struct sk_buff *skb, 204static int tcf_sample_walker(struct net *net, struct sk_buff *skb,
205 struct netlink_callback *cb, int type, 205 struct netlink_callback *cb, int type,
206 const struct tc_action_ops *ops) 206 const struct tc_action_ops *ops,
207 struct netlink_ext_ack *extack)
207{ 208{
208 struct tc_action_net *tn = net_generic(net, sample_net_id); 209 struct tc_action_net *tn = net_generic(net, sample_net_id);
209 210
210 return tcf_generic_walker(tn, skb, cb, type, ops); 211 return tcf_generic_walker(tn, skb, cb, type, ops, extack);
211} 212}
212 213
213static int tcf_sample_search(struct net *net, struct tc_action **a, u32 index) 214static int tcf_sample_search(struct net *net, struct tc_action **a, u32 index,
215 struct netlink_ext_ack *extack)
214{ 216{
215 struct tc_action_net *tn = net_generic(net, sample_net_id); 217 struct tc_action_net *tn = net_generic(net, sample_net_id);
216 218
@@ -247,6 +249,7 @@ static struct pernet_operations sample_net_ops = {
247 .exit_batch = sample_exit_net, 249 .exit_batch = sample_exit_net,
248 .id = &sample_net_id, 250 .id = &sample_net_id,
249 .size = sizeof(struct tc_action_net), 251 .size = sizeof(struct tc_action_net),
252 .async = true,
250}; 253};
251 254
252static int __init sample_init_module(void) 255static int __init sample_init_module(void)
diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c
index b1f38063ada0..e84768ae610a 100644
--- a/net/sched/act_simple.c
+++ b/net/sched/act_simple.c
@@ -79,7 +79,7 @@ static const struct nla_policy simple_policy[TCA_DEF_MAX + 1] = {
79 79
80static int tcf_simp_init(struct net *net, struct nlattr *nla, 80static int tcf_simp_init(struct net *net, struct nlattr *nla,
81 struct nlattr *est, struct tc_action **a, 81 struct nlattr *est, struct tc_action **a,
82 int ovr, int bind) 82 int ovr, int bind, struct netlink_ext_ack *extack)
83{ 83{
84 struct tc_action_net *tn = net_generic(net, simp_net_id); 84 struct tc_action_net *tn = net_generic(net, simp_net_id);
85 struct nlattr *tb[TCA_DEF_MAX + 1]; 85 struct nlattr *tb[TCA_DEF_MAX + 1];
@@ -170,14 +170,16 @@ nla_put_failure:
170 170
171static int tcf_simp_walker(struct net *net, struct sk_buff *skb, 171static int tcf_simp_walker(struct net *net, struct sk_buff *skb,
172 struct netlink_callback *cb, int type, 172 struct netlink_callback *cb, int type,
173 const struct tc_action_ops *ops) 173 const struct tc_action_ops *ops,
174 struct netlink_ext_ack *extack)
174{ 175{
175 struct tc_action_net *tn = net_generic(net, simp_net_id); 176 struct tc_action_net *tn = net_generic(net, simp_net_id);
176 177
177 return tcf_generic_walker(tn, skb, cb, type, ops); 178 return tcf_generic_walker(tn, skb, cb, type, ops, extack);
178} 179}
179 180
180static int tcf_simp_search(struct net *net, struct tc_action **a, u32 index) 181static int tcf_simp_search(struct net *net, struct tc_action **a, u32 index,
182 struct netlink_ext_ack *extack)
181{ 183{
182 struct tc_action_net *tn = net_generic(net, simp_net_id); 184 struct tc_action_net *tn = net_generic(net, simp_net_id);
183 185
@@ -214,6 +216,7 @@ static struct pernet_operations simp_net_ops = {
214 .exit_batch = simp_exit_net, 216 .exit_batch = simp_exit_net,
215 .id = &simp_net_id, 217 .id = &simp_net_id,
216 .size = sizeof(struct tc_action_net), 218 .size = sizeof(struct tc_action_net),
219 .async = true,
217}; 220};
218 221
219MODULE_AUTHOR("Jamal Hadi Salim(2005)"); 222MODULE_AUTHOR("Jamal Hadi Salim(2005)");
diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c
index 5a3f691bb545..7971510fe61b 100644
--- a/net/sched/act_skbedit.c
+++ b/net/sched/act_skbedit.c
@@ -66,7 +66,7 @@ static const struct nla_policy skbedit_policy[TCA_SKBEDIT_MAX + 1] = {
66 66
67static int tcf_skbedit_init(struct net *net, struct nlattr *nla, 67static int tcf_skbedit_init(struct net *net, struct nlattr *nla,
68 struct nlattr *est, struct tc_action **a, 68 struct nlattr *est, struct tc_action **a,
69 int ovr, int bind) 69 int ovr, int bind, struct netlink_ext_ack *extack)
70{ 70{
71 struct tc_action_net *tn = net_generic(net, skbedit_net_id); 71 struct tc_action_net *tn = net_generic(net, skbedit_net_id);
72 struct nlattr *tb[TCA_SKBEDIT_MAX + 1]; 72 struct nlattr *tb[TCA_SKBEDIT_MAX + 1];
@@ -208,14 +208,16 @@ nla_put_failure:
208 208
209static int tcf_skbedit_walker(struct net *net, struct sk_buff *skb, 209static int tcf_skbedit_walker(struct net *net, struct sk_buff *skb,
210 struct netlink_callback *cb, int type, 210 struct netlink_callback *cb, int type,
211 const struct tc_action_ops *ops) 211 const struct tc_action_ops *ops,
212 struct netlink_ext_ack *extack)
212{ 213{
213 struct tc_action_net *tn = net_generic(net, skbedit_net_id); 214 struct tc_action_net *tn = net_generic(net, skbedit_net_id);
214 215
215 return tcf_generic_walker(tn, skb, cb, type, ops); 216 return tcf_generic_walker(tn, skb, cb, type, ops, extack);
216} 217}
217 218
218static int tcf_skbedit_search(struct net *net, struct tc_action **a, u32 index) 219static int tcf_skbedit_search(struct net *net, struct tc_action **a, u32 index,
220 struct netlink_ext_ack *extack)
219{ 221{
220 struct tc_action_net *tn = net_generic(net, skbedit_net_id); 222 struct tc_action_net *tn = net_generic(net, skbedit_net_id);
221 223
@@ -251,6 +253,7 @@ static struct pernet_operations skbedit_net_ops = {
251 .exit_batch = skbedit_exit_net, 253 .exit_batch = skbedit_exit_net,
252 .id = &skbedit_net_id, 254 .id = &skbedit_net_id,
253 .size = sizeof(struct tc_action_net), 255 .size = sizeof(struct tc_action_net),
256 .async = true,
254}; 257};
255 258
256MODULE_AUTHOR("Alexander Duyck, <alexander.h.duyck@intel.com>"); 259MODULE_AUTHOR("Alexander Duyck, <alexander.h.duyck@intel.com>");
diff --git a/net/sched/act_skbmod.c b/net/sched/act_skbmod.c
index 7b0700f52b50..142a996ac776 100644
--- a/net/sched/act_skbmod.c
+++ b/net/sched/act_skbmod.c
@@ -84,7 +84,7 @@ static const struct nla_policy skbmod_policy[TCA_SKBMOD_MAX + 1] = {
84 84
85static int tcf_skbmod_init(struct net *net, struct nlattr *nla, 85static int tcf_skbmod_init(struct net *net, struct nlattr *nla,
86 struct nlattr *est, struct tc_action **a, 86 struct nlattr *est, struct tc_action **a,
87 int ovr, int bind) 87 int ovr, int bind, struct netlink_ext_ack *extack)
88{ 88{
89 struct tc_action_net *tn = net_generic(net, skbmod_net_id); 89 struct tc_action_net *tn = net_generic(net, skbmod_net_id);
90 struct nlattr *tb[TCA_SKBMOD_MAX + 1]; 90 struct nlattr *tb[TCA_SKBMOD_MAX + 1];
@@ -233,14 +233,16 @@ nla_put_failure:
233 233
234static int tcf_skbmod_walker(struct net *net, struct sk_buff *skb, 234static int tcf_skbmod_walker(struct net *net, struct sk_buff *skb,
235 struct netlink_callback *cb, int type, 235 struct netlink_callback *cb, int type,
236 const struct tc_action_ops *ops) 236 const struct tc_action_ops *ops,
237 struct netlink_ext_ack *extack)
237{ 238{
238 struct tc_action_net *tn = net_generic(net, skbmod_net_id); 239 struct tc_action_net *tn = net_generic(net, skbmod_net_id);
239 240
240 return tcf_generic_walker(tn, skb, cb, type, ops); 241 return tcf_generic_walker(tn, skb, cb, type, ops, extack);
241} 242}
242 243
243static int tcf_skbmod_search(struct net *net, struct tc_action **a, u32 index) 244static int tcf_skbmod_search(struct net *net, struct tc_action **a, u32 index,
245 struct netlink_ext_ack *extack)
244{ 246{
245 struct tc_action_net *tn = net_generic(net, skbmod_net_id); 247 struct tc_action_net *tn = net_generic(net, skbmod_net_id);
246 248
@@ -277,6 +279,7 @@ static struct pernet_operations skbmod_net_ops = {
277 .exit_batch = skbmod_exit_net, 279 .exit_batch = skbmod_exit_net,
278 .id = &skbmod_net_id, 280 .id = &skbmod_net_id,
279 .size = sizeof(struct tc_action_net), 281 .size = sizeof(struct tc_action_net),
282 .async = true,
280}; 283};
281 284
282MODULE_AUTHOR("Jamal Hadi Salim, <jhs@mojatatu.com>"); 285MODULE_AUTHOR("Jamal Hadi Salim, <jhs@mojatatu.com>");
diff --git a/net/sched/act_tunnel_key.c b/net/sched/act_tunnel_key.c
index 1281ca463727..a1c8dd406a04 100644
--- a/net/sched/act_tunnel_key.c
+++ b/net/sched/act_tunnel_key.c
@@ -70,7 +70,7 @@ static const struct nla_policy tunnel_key_policy[TCA_TUNNEL_KEY_MAX + 1] = {
70 70
71static int tunnel_key_init(struct net *net, struct nlattr *nla, 71static int tunnel_key_init(struct net *net, struct nlattr *nla,
72 struct nlattr *est, struct tc_action **a, 72 struct nlattr *est, struct tc_action **a,
73 int ovr, int bind) 73 int ovr, int bind, struct netlink_ext_ack *extack)
74{ 74{
75 struct tc_action_net *tn = net_generic(net, tunnel_key_net_id); 75 struct tc_action_net *tn = net_generic(net, tunnel_key_net_id);
76 struct nlattr *tb[TCA_TUNNEL_KEY_MAX + 1]; 76 struct nlattr *tb[TCA_TUNNEL_KEY_MAX + 1];
@@ -293,14 +293,16 @@ nla_put_failure:
293 293
294static int tunnel_key_walker(struct net *net, struct sk_buff *skb, 294static int tunnel_key_walker(struct net *net, struct sk_buff *skb,
295 struct netlink_callback *cb, int type, 295 struct netlink_callback *cb, int type,
296 const struct tc_action_ops *ops) 296 const struct tc_action_ops *ops,
297 struct netlink_ext_ack *extack)
297{ 298{
298 struct tc_action_net *tn = net_generic(net, tunnel_key_net_id); 299 struct tc_action_net *tn = net_generic(net, tunnel_key_net_id);
299 300
300 return tcf_generic_walker(tn, skb, cb, type, ops); 301 return tcf_generic_walker(tn, skb, cb, type, ops, extack);
301} 302}
302 303
303static int tunnel_key_search(struct net *net, struct tc_action **a, u32 index) 304static int tunnel_key_search(struct net *net, struct tc_action **a, u32 index,
305 struct netlink_ext_ack *extack)
304{ 306{
305 struct tc_action_net *tn = net_generic(net, tunnel_key_net_id); 307 struct tc_action_net *tn = net_generic(net, tunnel_key_net_id);
306 308
@@ -337,6 +339,7 @@ static struct pernet_operations tunnel_key_net_ops = {
337 .exit_batch = tunnel_key_exit_net, 339 .exit_batch = tunnel_key_exit_net,
338 .id = &tunnel_key_net_id, 340 .id = &tunnel_key_net_id,
339 .size = sizeof(struct tc_action_net), 341 .size = sizeof(struct tc_action_net),
342 .async = true,
340}; 343};
341 344
342static int __init tunnel_key_init_module(void) 345static int __init tunnel_key_init_module(void)
diff --git a/net/sched/act_vlan.c b/net/sched/act_vlan.c
index c49cb61adedf..4595391c2129 100644
--- a/net/sched/act_vlan.c
+++ b/net/sched/act_vlan.c
@@ -109,7 +109,7 @@ static const struct nla_policy vlan_policy[TCA_VLAN_MAX + 1] = {
109 109
110static int tcf_vlan_init(struct net *net, struct nlattr *nla, 110static int tcf_vlan_init(struct net *net, struct nlattr *nla,
111 struct nlattr *est, struct tc_action **a, 111 struct nlattr *est, struct tc_action **a,
112 int ovr, int bind) 112 int ovr, int bind, struct netlink_ext_ack *extack)
113{ 113{
114 struct tc_action_net *tn = net_generic(net, vlan_net_id); 114 struct tc_action_net *tn = net_generic(net, vlan_net_id);
115 struct nlattr *tb[TCA_VLAN_MAX + 1]; 115 struct nlattr *tb[TCA_VLAN_MAX + 1];
@@ -268,14 +268,16 @@ nla_put_failure:
268 268
269static int tcf_vlan_walker(struct net *net, struct sk_buff *skb, 269static int tcf_vlan_walker(struct net *net, struct sk_buff *skb,
270 struct netlink_callback *cb, int type, 270 struct netlink_callback *cb, int type,
271 const struct tc_action_ops *ops) 271 const struct tc_action_ops *ops,
272 struct netlink_ext_ack *extack)
272{ 273{
273 struct tc_action_net *tn = net_generic(net, vlan_net_id); 274 struct tc_action_net *tn = net_generic(net, vlan_net_id);
274 275
275 return tcf_generic_walker(tn, skb, cb, type, ops); 276 return tcf_generic_walker(tn, skb, cb, type, ops, extack);
276} 277}
277 278
278static int tcf_vlan_search(struct net *net, struct tc_action **a, u32 index) 279static int tcf_vlan_search(struct net *net, struct tc_action **a, u32 index,
280 struct netlink_ext_ack *extack)
279{ 281{
280 struct tc_action_net *tn = net_generic(net, vlan_net_id); 282 struct tc_action_net *tn = net_generic(net, vlan_net_id);
281 283
@@ -312,6 +314,7 @@ static struct pernet_operations vlan_net_ops = {
312 .exit_batch = vlan_exit_net, 314 .exit_batch = vlan_exit_net,
313 .id = &vlan_net_id, 315 .id = &vlan_net_id,
314 .size = sizeof(struct tc_action_net), 316 .size = sizeof(struct tc_action_net),
317 .async = true,
315}; 318};
316 319
317static int __init vlan_init_module(void) 320static int __init vlan_init_module(void)
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 247b7cc20c13..ec5fe8ec0c3e 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -1433,11 +1433,12 @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb,
1433#ifdef CONFIG_NET_CLS_ACT 1433#ifdef CONFIG_NET_CLS_ACT
1434 { 1434 {
1435 struct tc_action *act; 1435 struct tc_action *act;
1436 size_t attr_size = 0;
1436 1437
1437 if (exts->police && tb[exts->police]) { 1438 if (exts->police && tb[exts->police]) {
1438 act = tcf_action_init_1(net, tp, tb[exts->police], 1439 act = tcf_action_init_1(net, tp, tb[exts->police],
1439 rate_tlv, "police", ovr, 1440 rate_tlv, "police", ovr,
1440 TCA_ACT_BIND); 1441 TCA_ACT_BIND, extack);
1441 if (IS_ERR(act)) 1442 if (IS_ERR(act))
1442 return PTR_ERR(act); 1443 return PTR_ERR(act);
1443 1444
@@ -1450,7 +1451,7 @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb,
1450 1451
1451 err = tcf_action_init(net, tp, tb[exts->action], 1452 err = tcf_action_init(net, tp, tb[exts->action],
1452 rate_tlv, NULL, ovr, TCA_ACT_BIND, 1453 rate_tlv, NULL, ovr, TCA_ACT_BIND,
1453 &actions); 1454 &actions, &attr_size, extack);
1454 if (err) 1455 if (err)
1455 return err; 1456 return err;
1456 list_for_each_entry(act, &actions, list) 1457 list_for_each_entry(act, &actions, list)
@@ -1618,6 +1619,7 @@ static struct pernet_operations tcf_net_ops = {
1618 .exit = tcf_net_exit, 1619 .exit = tcf_net_exit,
1619 .id = &tcf_net_id, 1620 .id = &tcf_net_id,
1620 .size = sizeof(struct tcf_net), 1621 .size = sizeof(struct tcf_net),
1622 .async = true,
1621}; 1623};
1622 1624
1623static int __init tc_filter_init(void) 1625static int __init tc_filter_init(void)
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index 7d0ce2c40f93..d964e60c730e 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -511,6 +511,9 @@ static int fl_set_key_flags(struct nlattr **tb,
511 511
512 fl_set_key_flag(key, mask, flags_key, flags_mask, 512 fl_set_key_flag(key, mask, flags_key, flags_mask,
513 TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT, FLOW_DIS_IS_FRAGMENT); 513 TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT, FLOW_DIS_IS_FRAGMENT);
514 fl_set_key_flag(key, mask, flags_key, flags_mask,
515 TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST,
516 FLOW_DIS_FIRST_FRAG);
514 517
515 return 0; 518 return 0;
516} 519}
@@ -1130,6 +1133,9 @@ static int fl_dump_key_flags(struct sk_buff *skb, u32 flags_key, u32 flags_mask)
1130 1133
1131 fl_get_key_flag(flags_key, flags_mask, &key, &mask, 1134 fl_get_key_flag(flags_key, flags_mask, &key, &mask,
1132 TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT, FLOW_DIS_IS_FRAGMENT); 1135 TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT, FLOW_DIS_IS_FRAGMENT);
1136 fl_get_key_flag(flags_key, flags_mask, &key, &mask,
1137 TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST,
1138 FLOW_DIS_FIRST_FRAG);
1133 1139
1134 _key = cpu_to_be32(key); 1140 _key = cpu_to_be32(key);
1135 _mask = cpu_to_be32(mask); 1141 _mask = cpu_to_be32(mask);
diff --git a/net/sched/em_ipt.c b/net/sched/em_ipt.c
new file mode 100644
index 000000000000..a5f34e930eff
--- /dev/null
+++ b/net/sched/em_ipt.c
@@ -0,0 +1,257 @@
1/*
2 * net/sched/em_ipt.c IPtables matches Ematch
3 *
4 * (c) 2018 Eyal Birger <eyal.birger@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <linux/gfp.h>
13#include <linux/module.h>
14#include <linux/types.h>
15#include <linux/kernel.h>
16#include <linux/string.h>
17#include <linux/skbuff.h>
18#include <linux/tc_ematch/tc_em_ipt.h>
19#include <linux/netfilter.h>
20#include <linux/netfilter/x_tables.h>
21#include <linux/netfilter_ipv4/ip_tables.h>
22#include <linux/netfilter_ipv6/ip6_tables.h>
23#include <net/pkt_cls.h>
24
25struct em_ipt_match {
26 const struct xt_match *match;
27 u32 hook;
28 u8 match_data[0] __aligned(8);
29};
30
31struct em_ipt_xt_match {
32 char *match_name;
33 int (*validate_match_data)(struct nlattr **tb, u8 mrev);
34};
35
36static const struct nla_policy em_ipt_policy[TCA_EM_IPT_MAX + 1] = {
37 [TCA_EM_IPT_MATCH_NAME] = { .type = NLA_STRING,
38 .len = XT_EXTENSION_MAXNAMELEN },
39 [TCA_EM_IPT_MATCH_REVISION] = { .type = NLA_U8 },
40 [TCA_EM_IPT_HOOK] = { .type = NLA_U32 },
41 [TCA_EM_IPT_NFPROTO] = { .type = NLA_U8 },
42 [TCA_EM_IPT_MATCH_DATA] = { .type = NLA_UNSPEC },
43};
44
45static int check_match(struct net *net, struct em_ipt_match *im, int mdata_len)
46{
47 struct xt_mtchk_param mtpar = {};
48 union {
49 struct ipt_entry e4;
50 struct ip6t_entry e6;
51 } e = {};
52
53 mtpar.net = net;
54 mtpar.table = "filter";
55 mtpar.hook_mask = 1 << im->hook;
56 mtpar.family = im->match->family;
57 mtpar.match = im->match;
58 mtpar.entryinfo = &e;
59 mtpar.matchinfo = (void *)im->match_data;
60 return xt_check_match(&mtpar, mdata_len, 0, 0);
61}
62
63static int policy_validate_match_data(struct nlattr **tb, u8 mrev)
64{
65 if (mrev != 0) {
66 pr_err("only policy match revision 0 supported");
67 return -EINVAL;
68 }
69
70 if (nla_get_u32(tb[TCA_EM_IPT_HOOK]) != NF_INET_PRE_ROUTING) {
71 pr_err("policy can only be matched on NF_INET_PRE_ROUTING");
72 return -EINVAL;
73 }
74
75 return 0;
76}
77
78static const struct em_ipt_xt_match em_ipt_xt_matches[] = {
79 {
80 .match_name = "policy",
81 .validate_match_data = policy_validate_match_data
82 },
83 {}
84};
85
86static struct xt_match *get_xt_match(struct nlattr **tb)
87{
88 const struct em_ipt_xt_match *m;
89 struct nlattr *mname_attr;
90 u8 nfproto, mrev = 0;
91 int ret;
92
93 mname_attr = tb[TCA_EM_IPT_MATCH_NAME];
94 for (m = em_ipt_xt_matches; m->match_name; m++) {
95 if (!nla_strcmp(mname_attr, m->match_name))
96 break;
97 }
98
99 if (!m->match_name) {
100 pr_err("Unsupported xt match");
101 return ERR_PTR(-EINVAL);
102 }
103
104 if (tb[TCA_EM_IPT_MATCH_REVISION])
105 mrev = nla_get_u8(tb[TCA_EM_IPT_MATCH_REVISION]);
106
107 ret = m->validate_match_data(tb, mrev);
108 if (ret < 0)
109 return ERR_PTR(ret);
110
111 nfproto = nla_get_u8(tb[TCA_EM_IPT_NFPROTO]);
112 return xt_request_find_match(nfproto, m->match_name, mrev);
113}
114
115static int em_ipt_change(struct net *net, void *data, int data_len,
116 struct tcf_ematch *em)
117{
118 struct nlattr *tb[TCA_EM_IPT_MAX + 1];
119 struct em_ipt_match *im = NULL;
120 struct xt_match *match;
121 int mdata_len, ret;
122
123 ret = nla_parse(tb, TCA_EM_IPT_MAX, data, data_len, em_ipt_policy,
124 NULL);
125 if (ret < 0)
126 return ret;
127
128 if (!tb[TCA_EM_IPT_HOOK] || !tb[TCA_EM_IPT_MATCH_NAME] ||
129 !tb[TCA_EM_IPT_MATCH_DATA] || !tb[TCA_EM_IPT_NFPROTO])
130 return -EINVAL;
131
132 match = get_xt_match(tb);
133 if (IS_ERR(match)) {
134 pr_err("unable to load match\n");
135 return PTR_ERR(match);
136 }
137
138 mdata_len = XT_ALIGN(nla_len(tb[TCA_EM_IPT_MATCH_DATA]));
139 im = kzalloc(sizeof(*im) + mdata_len, GFP_KERNEL);
140 if (!im) {
141 ret = -ENOMEM;
142 goto err;
143 }
144
145 im->match = match;
146 im->hook = nla_get_u32(tb[TCA_EM_IPT_HOOK]);
147 nla_memcpy(im->match_data, tb[TCA_EM_IPT_MATCH_DATA], mdata_len);
148
149 ret = check_match(net, im, mdata_len);
150 if (ret)
151 goto err;
152
153 em->datalen = sizeof(*im) + mdata_len;
154 em->data = (unsigned long)im;
155 return 0;
156
157err:
158 kfree(im);
159 module_put(match->me);
160 return ret;
161}
162
163static void em_ipt_destroy(struct tcf_ematch *em)
164{
165 struct em_ipt_match *im = (void *)em->data;
166
167 if (!im)
168 return;
169
170 if (im->match->destroy) {
171 struct xt_mtdtor_param par = {
172 .net = em->net,
173 .match = im->match,
174 .matchinfo = im->match_data,
175 .family = im->match->family
176 };
177 im->match->destroy(&par);
178 }
179 module_put(im->match->me);
180 kfree((void *)im);
181}
182
183static int em_ipt_match(struct sk_buff *skb, struct tcf_ematch *em,
184 struct tcf_pkt_info *info)
185{
186 const struct em_ipt_match *im = (const void *)em->data;
187 struct xt_action_param acpar = {};
188 struct net_device *indev = NULL;
189 struct nf_hook_state state;
190 int ret;
191
192 rcu_read_lock();
193
194 if (skb->skb_iif)
195 indev = dev_get_by_index_rcu(em->net, skb->skb_iif);
196
197 nf_hook_state_init(&state, im->hook, im->match->family,
198 indev ?: skb->dev, skb->dev, NULL, em->net, NULL);
199
200 acpar.match = im->match;
201 acpar.matchinfo = im->match_data;
202 acpar.state = &state;
203
204 ret = im->match->match(skb, &acpar);
205
206 rcu_read_unlock();
207 return ret;
208}
209
210static int em_ipt_dump(struct sk_buff *skb, struct tcf_ematch *em)
211{
212 struct em_ipt_match *im = (void *)em->data;
213
214 if (nla_put_string(skb, TCA_EM_IPT_MATCH_NAME, im->match->name) < 0)
215 return -EMSGSIZE;
216 if (nla_put_u32(skb, TCA_EM_IPT_HOOK, im->hook) < 0)
217 return -EMSGSIZE;
218 if (nla_put_u8(skb, TCA_EM_IPT_MATCH_REVISION, im->match->revision) < 0)
219 return -EMSGSIZE;
220 if (nla_put_u8(skb, TCA_EM_IPT_NFPROTO, im->match->family) < 0)
221 return -EMSGSIZE;
222 if (nla_put(skb, TCA_EM_IPT_MATCH_DATA,
223 im->match->usersize ?: im->match->matchsize,
224 im->match_data) < 0)
225 return -EMSGSIZE;
226
227 return 0;
228}
229
230static struct tcf_ematch_ops em_ipt_ops = {
231 .kind = TCF_EM_IPT,
232 .change = em_ipt_change,
233 .destroy = em_ipt_destroy,
234 .match = em_ipt_match,
235 .dump = em_ipt_dump,
236 .owner = THIS_MODULE,
237 .link = LIST_HEAD_INIT(em_ipt_ops.link)
238};
239
240static int __init init_em_ipt(void)
241{
242 return tcf_em_register(&em_ipt_ops);
243}
244
245static void __exit exit_em_ipt(void)
246{
247 tcf_em_unregister(&em_ipt_ops);
248}
249
250MODULE_LICENSE("GPL");
251MODULE_AUTHOR("Eyal Birger <eyal.birger@gmail.com>");
252MODULE_DESCRIPTION("TC extended match for IPtables matches");
253
254module_init(init_em_ipt);
255module_exit(exit_em_ipt);
256
257MODULE_ALIAS_TCF_EMATCH(TCF_EM_IPT);
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index d512f49ee83c..68f9d942bed4 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -739,6 +739,7 @@ static u32 qdisc_alloc_handle(struct net_device *dev)
739void qdisc_tree_reduce_backlog(struct Qdisc *sch, unsigned int n, 739void qdisc_tree_reduce_backlog(struct Qdisc *sch, unsigned int n,
740 unsigned int len) 740 unsigned int len)
741{ 741{
742 bool qdisc_is_offloaded = sch->flags & TCQ_F_OFFLOADED;
742 const struct Qdisc_class_ops *cops; 743 const struct Qdisc_class_ops *cops;
743 unsigned long cl; 744 unsigned long cl;
744 u32 parentid; 745 u32 parentid;
@@ -760,8 +761,12 @@ void qdisc_tree_reduce_backlog(struct Qdisc *sch, unsigned int n,
760 * If child was empty even before update then backlog 761 * If child was empty even before update then backlog
761 * counter is screwed and we skip notification because 762 * counter is screwed and we skip notification because
762 * parent class is already passive. 763 * parent class is already passive.
764 *
765 * If the original child was offloaded then it is allowed
766 * to be seem as empty, so the parent is notified anyway.
763 */ 767 */
764 notify = !sch->q.qlen && !WARN_ON_ONCE(!n); 768 notify = !sch->q.qlen && !WARN_ON_ONCE(!n &&
769 !qdisc_is_offloaded);
765 /* TODO: perform the search on a per txq basis */ 770 /* TODO: perform the search on a per txq basis */
766 sch = qdisc_lookup(qdisc_dev(sch), TC_H_MAJ(parentid)); 771 sch = qdisc_lookup(qdisc_dev(sch), TC_H_MAJ(parentid));
767 if (sch == NULL) { 772 if (sch == NULL) {
@@ -2128,6 +2133,7 @@ static void __net_exit psched_net_exit(struct net *net)
2128static struct pernet_operations psched_net_ops = { 2133static struct pernet_operations psched_net_ops = {
2129 .init = psched_net_init, 2134 .init = psched_net_init,
2130 .exit = psched_net_exit, 2135 .exit = psched_net_exit,
2136 .async = true,
2131}; 2137};
2132 2138
2133static int __init pktsched_init(void) 2139static int __init pktsched_init(void)
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
index efbf51f35778..222e53d3d27a 100644
--- a/net/sched/sch_prio.c
+++ b/net/sched/sch_prio.c
@@ -142,9 +142,8 @@ prio_reset(struct Qdisc *sch)
142 sch->q.qlen = 0; 142 sch->q.qlen = 0;
143} 143}
144 144
145static int prio_offload(struct Qdisc *sch, bool enable) 145static int prio_offload(struct Qdisc *sch, struct tc_prio_qopt *qopt)
146{ 146{
147 struct prio_sched_data *q = qdisc_priv(sch);
148 struct net_device *dev = qdisc_dev(sch); 147 struct net_device *dev = qdisc_dev(sch);
149 struct tc_prio_qopt_offload opt = { 148 struct tc_prio_qopt_offload opt = {
150 .handle = sch->handle, 149 .handle = sch->handle,
@@ -154,10 +153,10 @@ static int prio_offload(struct Qdisc *sch, bool enable)
154 if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_tc) 153 if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_tc)
155 return -EOPNOTSUPP; 154 return -EOPNOTSUPP;
156 155
157 if (enable) { 156 if (qopt) {
158 opt.command = TC_PRIO_REPLACE; 157 opt.command = TC_PRIO_REPLACE;
159 opt.replace_params.bands = q->bands; 158 opt.replace_params.bands = qopt->bands;
160 memcpy(&opt.replace_params.priomap, q->prio2band, 159 memcpy(&opt.replace_params.priomap, qopt->priomap,
161 TC_PRIO_MAX + 1); 160 TC_PRIO_MAX + 1);
162 opt.replace_params.qstats = &sch->qstats; 161 opt.replace_params.qstats = &sch->qstats;
163 } else { 162 } else {
@@ -174,7 +173,7 @@ prio_destroy(struct Qdisc *sch)
174 struct prio_sched_data *q = qdisc_priv(sch); 173 struct prio_sched_data *q = qdisc_priv(sch);
175 174
176 tcf_block_put(q->block); 175 tcf_block_put(q->block);
177 prio_offload(sch, false); 176 prio_offload(sch, NULL);
178 for (prio = 0; prio < q->bands; prio++) 177 for (prio = 0; prio < q->bands; prio++)
179 qdisc_destroy(q->queues[prio]); 178 qdisc_destroy(q->queues[prio]);
180} 179}
@@ -211,6 +210,7 @@ static int prio_tune(struct Qdisc *sch, struct nlattr *opt,
211 } 210 }
212 } 211 }
213 212
213 prio_offload(sch, qopt);
214 sch_tree_lock(sch); 214 sch_tree_lock(sch);
215 q->bands = qopt->bands; 215 q->bands = qopt->bands;
216 memcpy(q->prio2band, qopt->priomap, TC_PRIO_MAX+1); 216 memcpy(q->prio2band, qopt->priomap, TC_PRIO_MAX+1);
@@ -230,7 +230,6 @@ static int prio_tune(struct Qdisc *sch, struct nlattr *opt,
230 } 230 }
231 231
232 sch_tree_unlock(sch); 232 sch_tree_unlock(sch);
233 prio_offload(sch, true);
234 return 0; 233 return 0;
235} 234}
236 235
@@ -309,12 +308,44 @@ static int prio_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
309 struct Qdisc **old, struct netlink_ext_ack *extack) 308 struct Qdisc **old, struct netlink_ext_ack *extack)
310{ 309{
311 struct prio_sched_data *q = qdisc_priv(sch); 310 struct prio_sched_data *q = qdisc_priv(sch);
311 struct tc_prio_qopt_offload graft_offload;
312 struct net_device *dev = qdisc_dev(sch);
312 unsigned long band = arg - 1; 313 unsigned long band = arg - 1;
314 bool any_qdisc_is_offloaded;
315 int err;
313 316
314 if (new == NULL) 317 if (new == NULL)
315 new = &noop_qdisc; 318 new = &noop_qdisc;
316 319
317 *old = qdisc_replace(sch, new, &q->queues[band]); 320 *old = qdisc_replace(sch, new, &q->queues[band]);
321
322 if (!tc_can_offload(dev))
323 return 0;
324
325 graft_offload.handle = sch->handle;
326 graft_offload.parent = sch->parent;
327 graft_offload.graft_params.band = band;
328 graft_offload.graft_params.child_handle = new->handle;
329 graft_offload.command = TC_PRIO_GRAFT;
330
331 err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_PRIO,
332 &graft_offload);
333
334 /* Don't report error if the graft is part of destroy operation. */
335 if (err && new != &noop_qdisc) {
336 /* Don't report error if the parent, the old child and the new
337 * one are not offloaded.
338 */
339 any_qdisc_is_offloaded = sch->flags & TCQ_F_OFFLOADED;
340 any_qdisc_is_offloaded |= new->flags & TCQ_F_OFFLOADED;
341 if (*old)
342 any_qdisc_is_offloaded |= (*old)->flags &
343 TCQ_F_OFFLOADED;
344
345 if (any_qdisc_is_offloaded)
346 NL_SET_ERR_MSG(extack, "Offloading graft operation failed.");
347 }
348
318 return 0; 349 return 0;
319} 350}
320 351
diff --git a/net/sctp/Makefile b/net/sctp/Makefile
index 6776582ec449..e845e4588535 100644
--- a/net/sctp/Makefile
+++ b/net/sctp/Makefile
@@ -15,6 +15,8 @@ sctp-y := sm_statetable.o sm_statefuns.o sm_sideeffect.o \
15 offload.o stream_sched.o stream_sched_prio.o \ 15 offload.o stream_sched.o stream_sched_prio.o \
16 stream_sched_rr.o stream_interleave.o 16 stream_sched_rr.o stream_interleave.o
17 17
18sctp_diag-y := diag.o
19
18sctp-$(CONFIG_SCTP_DBG_OBJCNT) += objcnt.o 20sctp-$(CONFIG_SCTP_DBG_OBJCNT) += objcnt.o
19sctp-$(CONFIG_PROC_FS) += proc.o 21sctp-$(CONFIG_PROC_FS) += proc.o
20sctp-$(CONFIG_SYSCTL) += sysctl.o 22sctp-$(CONFIG_SYSCTL) += sysctl.o
diff --git a/net/sctp/auth.c b/net/sctp/auth.c
index 00667c50efa7..e64630cd3331 100644
--- a/net/sctp/auth.c
+++ b/net/sctp/auth.c
@@ -101,13 +101,14 @@ struct sctp_shared_key *sctp_auth_shkey_create(__u16 key_id, gfp_t gfp)
101 return NULL; 101 return NULL;
102 102
103 INIT_LIST_HEAD(&new->key_list); 103 INIT_LIST_HEAD(&new->key_list);
104 refcount_set(&new->refcnt, 1);
104 new->key_id = key_id; 105 new->key_id = key_id;
105 106
106 return new; 107 return new;
107} 108}
108 109
109/* Free the shared key structure */ 110/* Free the shared key structure */
110static void sctp_auth_shkey_free(struct sctp_shared_key *sh_key) 111static void sctp_auth_shkey_destroy(struct sctp_shared_key *sh_key)
111{ 112{
112 BUG_ON(!list_empty(&sh_key->key_list)); 113 BUG_ON(!list_empty(&sh_key->key_list));
113 sctp_auth_key_put(sh_key->key); 114 sctp_auth_key_put(sh_key->key);
@@ -115,6 +116,17 @@ static void sctp_auth_shkey_free(struct sctp_shared_key *sh_key)
115 kfree(sh_key); 116 kfree(sh_key);
116} 117}
117 118
119void sctp_auth_shkey_release(struct sctp_shared_key *sh_key)
120{
121 if (refcount_dec_and_test(&sh_key->refcnt))
122 sctp_auth_shkey_destroy(sh_key);
123}
124
125void sctp_auth_shkey_hold(struct sctp_shared_key *sh_key)
126{
127 refcount_inc(&sh_key->refcnt);
128}
129
118/* Destroy the entire key list. This is done during the 130/* Destroy the entire key list. This is done during the
119 * associon and endpoint free process. 131 * associon and endpoint free process.
120 */ 132 */
@@ -128,7 +140,7 @@ void sctp_auth_destroy_keys(struct list_head *keys)
128 140
129 key_for_each_safe(ep_key, tmp, keys) { 141 key_for_each_safe(ep_key, tmp, keys) {
130 list_del_init(&ep_key->key_list); 142 list_del_init(&ep_key->key_list);
131 sctp_auth_shkey_free(ep_key); 143 sctp_auth_shkey_release(ep_key);
132 } 144 }
133} 145}
134 146
@@ -409,13 +421,19 @@ int sctp_auth_asoc_init_active_key(struct sctp_association *asoc, gfp_t gfp)
409 421
410 sctp_auth_key_put(asoc->asoc_shared_key); 422 sctp_auth_key_put(asoc->asoc_shared_key);
411 asoc->asoc_shared_key = secret; 423 asoc->asoc_shared_key = secret;
424 asoc->shkey = ep_key;
412 425
413 /* Update send queue in case any chunk already in there now 426 /* Update send queue in case any chunk already in there now
414 * needs authenticating 427 * needs authenticating
415 */ 428 */
416 list_for_each_entry(chunk, &asoc->outqueue.out_chunk_list, list) { 429 list_for_each_entry(chunk, &asoc->outqueue.out_chunk_list, list) {
417 if (sctp_auth_send_cid(chunk->chunk_hdr->type, asoc)) 430 if (sctp_auth_send_cid(chunk->chunk_hdr->type, asoc)) {
418 chunk->auth = 1; 431 chunk->auth = 1;
432 if (!chunk->shkey) {
433 chunk->shkey = asoc->shkey;
434 sctp_auth_shkey_hold(chunk->shkey);
435 }
436 }
419 } 437 }
420 438
421 return 0; 439 return 0;
@@ -431,8 +449,11 @@ struct sctp_shared_key *sctp_auth_get_shkey(
431 449
432 /* First search associations set of endpoint pair shared keys */ 450 /* First search associations set of endpoint pair shared keys */
433 key_for_each(key, &asoc->endpoint_shared_keys) { 451 key_for_each(key, &asoc->endpoint_shared_keys) {
434 if (key->key_id == key_id) 452 if (key->key_id == key_id) {
435 return key; 453 if (!key->deactivated)
454 return key;
455 break;
456 }
436 } 457 }
437 458
438 return NULL; 459 return NULL;
@@ -703,16 +724,15 @@ int sctp_auth_recv_cid(enum sctp_cid chunk, const struct sctp_association *asoc)
703 * after the AUTH chunk in the SCTP packet. 724 * after the AUTH chunk in the SCTP packet.
704 */ 725 */
705void sctp_auth_calculate_hmac(const struct sctp_association *asoc, 726void sctp_auth_calculate_hmac(const struct sctp_association *asoc,
706 struct sk_buff *skb, 727 struct sk_buff *skb, struct sctp_auth_chunk *auth,
707 struct sctp_auth_chunk *auth, 728 struct sctp_shared_key *ep_key, gfp_t gfp)
708 gfp_t gfp)
709{ 729{
710 struct crypto_shash *tfm;
711 struct sctp_auth_bytes *asoc_key; 730 struct sctp_auth_bytes *asoc_key;
731 struct crypto_shash *tfm;
712 __u16 key_id, hmac_id; 732 __u16 key_id, hmac_id;
713 __u8 *digest;
714 unsigned char *end; 733 unsigned char *end;
715 int free_key = 0; 734 int free_key = 0;
735 __u8 *digest;
716 736
717 /* Extract the info we need: 737 /* Extract the info we need:
718 * - hmac id 738 * - hmac id
@@ -724,12 +744,7 @@ void sctp_auth_calculate_hmac(const struct sctp_association *asoc,
724 if (key_id == asoc->active_key_id) 744 if (key_id == asoc->active_key_id)
725 asoc_key = asoc->asoc_shared_key; 745 asoc_key = asoc->asoc_shared_key;
726 else { 746 else {
727 struct sctp_shared_key *ep_key; 747 /* ep_key can't be NULL here */
728
729 ep_key = sctp_auth_get_shkey(asoc, key_id);
730 if (!ep_key)
731 return;
732
733 asoc_key = sctp_auth_asoc_create_secret(asoc, ep_key, gfp); 748 asoc_key = sctp_auth_asoc_create_secret(asoc, ep_key, gfp);
734 if (!asoc_key) 749 if (!asoc_key)
735 return; 750 return;
@@ -829,7 +844,7 @@ int sctp_auth_set_key(struct sctp_endpoint *ep,
829 struct sctp_association *asoc, 844 struct sctp_association *asoc,
830 struct sctp_authkey *auth_key) 845 struct sctp_authkey *auth_key)
831{ 846{
832 struct sctp_shared_key *cur_key = NULL; 847 struct sctp_shared_key *cur_key, *shkey;
833 struct sctp_auth_bytes *key; 848 struct sctp_auth_bytes *key;
834 struct list_head *sh_keys; 849 struct list_head *sh_keys;
835 int replace = 0; 850 int replace = 0;
@@ -842,46 +857,34 @@ int sctp_auth_set_key(struct sctp_endpoint *ep,
842 else 857 else
843 sh_keys = &ep->endpoint_shared_keys; 858 sh_keys = &ep->endpoint_shared_keys;
844 859
845 key_for_each(cur_key, sh_keys) { 860 key_for_each(shkey, sh_keys) {
846 if (cur_key->key_id == auth_key->sca_keynumber) { 861 if (shkey->key_id == auth_key->sca_keynumber) {
847 replace = 1; 862 replace = 1;
848 break; 863 break;
849 } 864 }
850 } 865 }
851 866
852 /* If we are not replacing a key id, we need to allocate 867 cur_key = sctp_auth_shkey_create(auth_key->sca_keynumber, GFP_KERNEL);
853 * a shared key. 868 if (!cur_key)
854 */ 869 return -ENOMEM;
855 if (!replace) {
856 cur_key = sctp_auth_shkey_create(auth_key->sca_keynumber,
857 GFP_KERNEL);
858 if (!cur_key)
859 return -ENOMEM;
860 }
861 870
862 /* Create a new key data based on the info passed in */ 871 /* Create a new key data based on the info passed in */
863 key = sctp_auth_create_key(auth_key->sca_keylength, GFP_KERNEL); 872 key = sctp_auth_create_key(auth_key->sca_keylength, GFP_KERNEL);
864 if (!key) 873 if (!key) {
865 goto nomem; 874 kfree(cur_key);
875 return -ENOMEM;
876 }
866 877
867 memcpy(key->data, &auth_key->sca_key[0], auth_key->sca_keylength); 878 memcpy(key->data, &auth_key->sca_key[0], auth_key->sca_keylength);
879 cur_key->key = key;
868 880
869 /* If we are replacing, remove the old keys data from the 881 if (replace) {
870 * key id. If we are adding new key id, add it to the 882 list_del_init(&shkey->key_list);
871 * list. 883 sctp_auth_shkey_release(shkey);
872 */ 884 }
873 if (replace) 885 list_add(&cur_key->key_list, sh_keys);
874 sctp_auth_key_put(cur_key->key);
875 else
876 list_add(&cur_key->key_list, sh_keys);
877 886
878 cur_key->key = key;
879 return 0; 887 return 0;
880nomem:
881 if (!replace)
882 sctp_auth_shkey_free(cur_key);
883
884 return -ENOMEM;
885} 888}
886 889
887int sctp_auth_set_active_key(struct sctp_endpoint *ep, 890int sctp_auth_set_active_key(struct sctp_endpoint *ep,
@@ -905,7 +908,7 @@ int sctp_auth_set_active_key(struct sctp_endpoint *ep,
905 } 908 }
906 } 909 }
907 910
908 if (!found) 911 if (!found || key->deactivated)
909 return -EINVAL; 912 return -EINVAL;
910 913
911 if (asoc) { 914 if (asoc) {
@@ -952,7 +955,58 @@ int sctp_auth_del_key_id(struct sctp_endpoint *ep,
952 955
953 /* Delete the shared key */ 956 /* Delete the shared key */
954 list_del_init(&key->key_list); 957 list_del_init(&key->key_list);
955 sctp_auth_shkey_free(key); 958 sctp_auth_shkey_release(key);
959
960 return 0;
961}
962
963int sctp_auth_deact_key_id(struct sctp_endpoint *ep,
964 struct sctp_association *asoc, __u16 key_id)
965{
966 struct sctp_shared_key *key;
967 struct list_head *sh_keys;
968 int found = 0;
969
970 /* The key identifier MUST NOT be the current active key
971 * The key identifier MUST correst to an existing key
972 */
973 if (asoc) {
974 if (asoc->active_key_id == key_id)
975 return -EINVAL;
976
977 sh_keys = &asoc->endpoint_shared_keys;
978 } else {
979 if (ep->active_key_id == key_id)
980 return -EINVAL;
981
982 sh_keys = &ep->endpoint_shared_keys;
983 }
984
985 key_for_each(key, sh_keys) {
986 if (key->key_id == key_id) {
987 found = 1;
988 break;
989 }
990 }
991
992 if (!found)
993 return -EINVAL;
994
995 /* refcnt == 1 and !list_empty mean it's not being used anywhere
996 * and deactivated will be set, so it's time to notify userland
997 * that this shkey can be freed.
998 */
999 if (asoc && !list_empty(&key->key_list) &&
1000 refcount_read(&key->refcnt) == 1) {
1001 struct sctp_ulpevent *ev;
1002
1003 ev = sctp_ulpevent_make_authkey(asoc, key->key_id,
1004 SCTP_AUTH_FREE_KEY, GFP_KERNEL);
1005 if (ev)
1006 asoc->stream.si->enqueue_event(&asoc->ulpq, ev);
1007 }
1008
1009 key->deactivated = 1;
956 1010
957 return 0; 1011 return 0;
958} 1012}
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
index 991a530c6b31..f889a84f264d 100644
--- a/net/sctp/chunk.c
+++ b/net/sctp/chunk.c
@@ -168,6 +168,7 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
168{ 168{
169 size_t len, first_len, max_data, remaining; 169 size_t len, first_len, max_data, remaining;
170 size_t msg_len = iov_iter_count(from); 170 size_t msg_len = iov_iter_count(from);
171 struct sctp_shared_key *shkey = NULL;
171 struct list_head *pos, *temp; 172 struct list_head *pos, *temp;
172 struct sctp_chunk *chunk; 173 struct sctp_chunk *chunk;
173 struct sctp_datamsg *msg; 174 struct sctp_datamsg *msg;
@@ -204,6 +205,17 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
204 if (hmac_desc) 205 if (hmac_desc)
205 max_data -= SCTP_PAD4(sizeof(struct sctp_auth_chunk) + 206 max_data -= SCTP_PAD4(sizeof(struct sctp_auth_chunk) +
206 hmac_desc->hmac_len); 207 hmac_desc->hmac_len);
208
209 if (sinfo->sinfo_tsn &&
210 sinfo->sinfo_ssn != asoc->active_key_id) {
211 shkey = sctp_auth_get_shkey(asoc, sinfo->sinfo_ssn);
212 if (!shkey) {
213 err = -EINVAL;
214 goto errout;
215 }
216 } else {
217 shkey = asoc->shkey;
218 }
207 } 219 }
208 220
209 /* Check what's our max considering the above */ 221 /* Check what's our max considering the above */
@@ -275,6 +287,8 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
275 if (err < 0) 287 if (err < 0)
276 goto errout_chunk_free; 288 goto errout_chunk_free;
277 289
290 chunk->shkey = shkey;
291
278 /* Put the chunk->skb back into the form expected by send. */ 292 /* Put the chunk->skb back into the form expected by send. */
279 __skb_pull(chunk->skb, (__u8 *)chunk->chunk_hdr - 293 __skb_pull(chunk->skb, (__u8 *)chunk->chunk_hdr -
280 chunk->skb->data); 294 chunk->skb->data);
diff --git a/net/sctp/sctp_diag.c b/net/sctp/diag.c
index a72a7d925d46..078f01a8d582 100644
--- a/net/sctp/sctp_diag.c
+++ b/net/sctp/diag.c
@@ -1,3 +1,34 @@
1/* SCTP kernel implementation
2 * (C) Copyright Red Hat Inc. 2017
3 *
4 * This file is part of the SCTP kernel implementation
5 *
6 * These functions implement sctp diag support.
7 *
8 * This SCTP implementation is free software;
9 * you can redistribute it and/or modify it under the terms of
10 * the GNU General Public License as published by
11 * the Free Software Foundation; either version 2, or (at your option)
12 * any later version.
13 *
14 * This SCTP implementation is distributed in the hope that it
15 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
16 * ************************
17 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 * See the GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with GNU CC; see the file COPYING. If not, see
22 * <http://www.gnu.org/licenses/>.
23 *
24 * Please send any bug reports or fixes you make to the
25 * email addresched(es):
26 * lksctp developers <linux-sctp@vger.kernel.org>
27 *
28 * Written or modified by:
29 * Xin Long <lucien.xin@gmail.com>
30 */
31
1#include <linux/module.h> 32#include <linux/module.h>
2#include <linux/inet_diag.h> 33#include <linux/inet_diag.h>
3#include <linux/sock_diag.h> 34#include <linux/sock_diag.h>
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index e35d4f73d2df..0d873c58e516 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -952,16 +952,16 @@ static int sctp_inet6_supported_addrs(const struct sctp_sock *opt,
952 952
953/* Handle SCTP_I_WANT_MAPPED_V4_ADDR for getpeername() and getsockname() */ 953/* Handle SCTP_I_WANT_MAPPED_V4_ADDR for getpeername() and getsockname() */
954static int sctp_getname(struct socket *sock, struct sockaddr *uaddr, 954static int sctp_getname(struct socket *sock, struct sockaddr *uaddr,
955 int *uaddr_len, int peer) 955 int peer)
956{ 956{
957 int rc; 957 int rc;
958 958
959 rc = inet6_getname(sock, uaddr, uaddr_len, peer); 959 rc = inet6_getname(sock, uaddr, peer);
960 960
961 if (rc != 0) 961 if (rc < 0)
962 return rc; 962 return rc;
963 963
964 *uaddr_len = sctp_v6_addr_to_user(sctp_sk(sock->sk), 964 rc = sctp_v6_addr_to_user(sctp_sk(sock->sk),
965 (union sctp_addr *)uaddr); 965 (union sctp_addr *)uaddr);
966 966
967 return rc; 967 return rc;
diff --git a/net/sctp/objcnt.c b/net/sctp/objcnt.c
index aeea6da81441..fd2684ad94c8 100644
--- a/net/sctp/objcnt.c
+++ b/net/sctp/objcnt.c
@@ -130,11 +130,3 @@ void sctp_dbg_objcnt_init(struct net *net)
130 if (!ent) 130 if (!ent)
131 pr_warn("sctp_dbg_objcnt: Unable to create /proc entry.\n"); 131 pr_warn("sctp_dbg_objcnt: Unable to create /proc entry.\n");
132} 132}
133
134/* Cleanup the objcount entry in the proc filesystem. */
135void sctp_dbg_objcnt_exit(struct net *net)
136{
137 remove_proc_entry("sctp_dbg_objcnt", net->sctp.proc_net_sctp);
138}
139
140
diff --git a/net/sctp/output.c b/net/sctp/output.c
index 01a26ee051e3..d6e1c90cc09a 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -241,10 +241,13 @@ static enum sctp_xmit sctp_packet_bundle_auth(struct sctp_packet *pkt,
241 if (!chunk->auth) 241 if (!chunk->auth)
242 return retval; 242 return retval;
243 243
244 auth = sctp_make_auth(asoc); 244 auth = sctp_make_auth(asoc, chunk->shkey->key_id);
245 if (!auth) 245 if (!auth)
246 return retval; 246 return retval;
247 247
248 auth->shkey = chunk->shkey;
249 sctp_auth_shkey_hold(auth->shkey);
250
248 retval = __sctp_packet_append_chunk(pkt, auth); 251 retval = __sctp_packet_append_chunk(pkt, auth);
249 252
250 if (retval != SCTP_XMIT_OK) 253 if (retval != SCTP_XMIT_OK)
@@ -490,7 +493,8 @@ merge:
490 } 493 }
491 494
492 if (auth) { 495 if (auth) {
493 sctp_auth_calculate_hmac(tp->asoc, nskb, auth, gfp); 496 sctp_auth_calculate_hmac(tp->asoc, nskb, auth,
497 packet->auth->shkey, gfp);
494 /* free auth if no more chunks, or add it back */ 498 /* free auth if no more chunks, or add it back */
495 if (list_empty(&packet->chunk_list)) 499 if (list_empty(&packet->chunk_list))
496 sctp_chunk_free(packet->auth); 500 sctp_chunk_free(packet->auth);
@@ -770,6 +774,16 @@ static enum sctp_xmit sctp_packet_will_fit(struct sctp_packet *packet,
770 enum sctp_xmit retval = SCTP_XMIT_OK; 774 enum sctp_xmit retval = SCTP_XMIT_OK;
771 size_t psize, pmtu, maxsize; 775 size_t psize, pmtu, maxsize;
772 776
777 /* Don't bundle in this packet if this chunk's auth key doesn't
778 * match other chunks already enqueued on this packet. Also,
779 * don't bundle the chunk with auth key if other chunks in this
780 * packet don't have auth key.
781 */
782 if ((packet->auth && chunk->shkey != packet->auth->shkey) ||
783 (!packet->auth && chunk->shkey &&
784 chunk->chunk_hdr->type != SCTP_CID_AUTH))
785 return SCTP_XMIT_PMTU_FULL;
786
773 psize = packet->size; 787 psize = packet->size;
774 if (packet->transport->asoc) 788 if (packet->transport->asoc)
775 pmtu = packet->transport->asoc->pathmtu; 789 pmtu = packet->transport->asoc->pathmtu;
diff --git a/net/sctp/proc.c b/net/sctp/proc.c
index 537545ebcb0e..17d0155d9de3 100644
--- a/net/sctp/proc.c
+++ b/net/sctp/proc.c
@@ -101,25 +101,6 @@ static const struct file_operations sctp_snmp_seq_fops = {
101 .release = single_release_net, 101 .release = single_release_net,
102}; 102};
103 103
104/* Set up the proc fs entry for 'snmp' object. */
105int __net_init sctp_snmp_proc_init(struct net *net)
106{
107 struct proc_dir_entry *p;
108
109 p = proc_create("snmp", S_IRUGO, net->sctp.proc_net_sctp,
110 &sctp_snmp_seq_fops);
111 if (!p)
112 return -ENOMEM;
113
114 return 0;
115}
116
117/* Cleanup the proc fs entry for 'snmp' object. */
118void sctp_snmp_proc_exit(struct net *net)
119{
120 remove_proc_entry("snmp", net->sctp.proc_net_sctp);
121}
122
123/* Dump local addresses of an association/endpoint. */ 104/* Dump local addresses of an association/endpoint. */
124static void sctp_seq_dump_local_addrs(struct seq_file *seq, struct sctp_ep_common *epb) 105static void sctp_seq_dump_local_addrs(struct seq_file *seq, struct sctp_ep_common *epb)
125{ 106{
@@ -259,25 +240,6 @@ static const struct file_operations sctp_eps_seq_fops = {
259 .release = seq_release_net, 240 .release = seq_release_net,
260}; 241};
261 242
262/* Set up the proc fs entry for 'eps' object. */
263int __net_init sctp_eps_proc_init(struct net *net)
264{
265 struct proc_dir_entry *p;
266
267 p = proc_create("eps", S_IRUGO, net->sctp.proc_net_sctp,
268 &sctp_eps_seq_fops);
269 if (!p)
270 return -ENOMEM;
271
272 return 0;
273}
274
275/* Cleanup the proc fs entry for 'eps' object. */
276void sctp_eps_proc_exit(struct net *net)
277{
278 remove_proc_entry("eps", net->sctp.proc_net_sctp);
279}
280
281struct sctp_ht_iter { 243struct sctp_ht_iter {
282 struct seq_net_private p; 244 struct seq_net_private p;
283 struct rhashtable_iter hti; 245 struct rhashtable_iter hti;
@@ -390,25 +352,6 @@ static const struct file_operations sctp_assocs_seq_fops = {
390 .release = seq_release_net, 352 .release = seq_release_net,
391}; 353};
392 354
393/* Set up the proc fs entry for 'assocs' object. */
394int __net_init sctp_assocs_proc_init(struct net *net)
395{
396 struct proc_dir_entry *p;
397
398 p = proc_create("assocs", S_IRUGO, net->sctp.proc_net_sctp,
399 &sctp_assocs_seq_fops);
400 if (!p)
401 return -ENOMEM;
402
403 return 0;
404}
405
406/* Cleanup the proc fs entry for 'assocs' object. */
407void sctp_assocs_proc_exit(struct net *net)
408{
409 remove_proc_entry("assocs", net->sctp.proc_net_sctp);
410}
411
412static int sctp_remaddr_seq_show(struct seq_file *seq, void *v) 355static int sctp_remaddr_seq_show(struct seq_file *seq, void *v)
413{ 356{
414 struct sctp_association *assoc; 357 struct sctp_association *assoc;
@@ -488,12 +431,6 @@ static const struct seq_operations sctp_remaddr_ops = {
488 .show = sctp_remaddr_seq_show, 431 .show = sctp_remaddr_seq_show,
489}; 432};
490 433
491/* Cleanup the proc fs entry for 'remaddr' object. */
492void sctp_remaddr_proc_exit(struct net *net)
493{
494 remove_proc_entry("remaddr", net->sctp.proc_net_sctp);
495}
496
497static int sctp_remaddr_seq_open(struct inode *inode, struct file *file) 434static int sctp_remaddr_seq_open(struct inode *inode, struct file *file)
498{ 435{
499 return seq_open_net(inode, file, &sctp_remaddr_ops, 436 return seq_open_net(inode, file, &sctp_remaddr_ops,
@@ -507,13 +444,28 @@ static const struct file_operations sctp_remaddr_seq_fops = {
507 .release = seq_release_net, 444 .release = seq_release_net,
508}; 445};
509 446
510int __net_init sctp_remaddr_proc_init(struct net *net) 447/* Set up the proc fs entry for the SCTP protocol. */
448int __net_init sctp_proc_init(struct net *net)
511{ 449{
512 struct proc_dir_entry *p; 450 net->sctp.proc_net_sctp = proc_net_mkdir(net, "sctp", net->proc_net);
513 451 if (!net->sctp.proc_net_sctp)
514 p = proc_create("remaddr", S_IRUGO, net->sctp.proc_net_sctp,
515 &sctp_remaddr_seq_fops);
516 if (!p)
517 return -ENOMEM; 452 return -ENOMEM;
453 if (!proc_create("snmp", S_IRUGO, net->sctp.proc_net_sctp,
454 &sctp_snmp_seq_fops))
455 goto cleanup;
456 if (!proc_create("eps", S_IRUGO, net->sctp.proc_net_sctp,
457 &sctp_eps_seq_fops))
458 goto cleanup;
459 if (!proc_create("assocs", S_IRUGO, net->sctp.proc_net_sctp,
460 &sctp_assocs_seq_fops))
461 goto cleanup;
462 if (!proc_create("remaddr", S_IRUGO, net->sctp.proc_net_sctp,
463 &sctp_remaddr_seq_fops))
464 goto cleanup;
518 return 0; 465 return 0;
466
467cleanup:
468 remove_proc_subtree("sctp", net->proc_net);
469 net->sctp.proc_net_sctp = NULL;
470 return -ENOMEM;
519} 471}
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 91813e686c67..493b817f6a2a 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -80,56 +80,6 @@ long sysctl_sctp_mem[3];
80int sysctl_sctp_rmem[3]; 80int sysctl_sctp_rmem[3];
81int sysctl_sctp_wmem[3]; 81int sysctl_sctp_wmem[3];
82 82
83/* Set up the proc fs entry for the SCTP protocol. */
84static int __net_init sctp_proc_init(struct net *net)
85{
86#ifdef CONFIG_PROC_FS
87 net->sctp.proc_net_sctp = proc_net_mkdir(net, "sctp", net->proc_net);
88 if (!net->sctp.proc_net_sctp)
89 goto out_proc_net_sctp;
90 if (sctp_snmp_proc_init(net))
91 goto out_snmp_proc_init;
92 if (sctp_eps_proc_init(net))
93 goto out_eps_proc_init;
94 if (sctp_assocs_proc_init(net))
95 goto out_assocs_proc_init;
96 if (sctp_remaddr_proc_init(net))
97 goto out_remaddr_proc_init;
98
99 return 0;
100
101out_remaddr_proc_init:
102 sctp_assocs_proc_exit(net);
103out_assocs_proc_init:
104 sctp_eps_proc_exit(net);
105out_eps_proc_init:
106 sctp_snmp_proc_exit(net);
107out_snmp_proc_init:
108 remove_proc_entry("sctp", net->proc_net);
109 net->sctp.proc_net_sctp = NULL;
110out_proc_net_sctp:
111 return -ENOMEM;
112#endif /* CONFIG_PROC_FS */
113 return 0;
114}
115
116/* Clean up the proc fs entry for the SCTP protocol.
117 * Note: Do not make this __exit as it is used in the init error
118 * path.
119 */
120static void sctp_proc_exit(struct net *net)
121{
122#ifdef CONFIG_PROC_FS
123 sctp_snmp_proc_exit(net);
124 sctp_eps_proc_exit(net);
125 sctp_assocs_proc_exit(net);
126 sctp_remaddr_proc_exit(net);
127
128 remove_proc_entry("sctp", net->proc_net);
129 net->sctp.proc_net_sctp = NULL;
130#endif
131}
132
133/* Private helper to extract ipv4 address and stash them in 83/* Private helper to extract ipv4 address and stash them in
134 * the protocol structure. 84 * the protocol structure.
135 */ 85 */
@@ -1285,10 +1235,12 @@ static int __net_init sctp_defaults_init(struct net *net)
1285 if (status) 1235 if (status)
1286 goto err_init_mibs; 1236 goto err_init_mibs;
1287 1237
1238#ifdef CONFIG_PROC_FS
1288 /* Initialize proc fs directory. */ 1239 /* Initialize proc fs directory. */
1289 status = sctp_proc_init(net); 1240 status = sctp_proc_init(net);
1290 if (status) 1241 if (status)
1291 goto err_init_proc; 1242 goto err_init_proc;
1243#endif
1292 1244
1293 sctp_dbg_objcnt_init(net); 1245 sctp_dbg_objcnt_init(net);
1294 1246
@@ -1320,9 +1272,10 @@ static void __net_exit sctp_defaults_exit(struct net *net)
1320 sctp_free_addr_wq(net); 1272 sctp_free_addr_wq(net);
1321 sctp_free_local_addr_list(net); 1273 sctp_free_local_addr_list(net);
1322 1274
1323 sctp_dbg_objcnt_exit(net); 1275#ifdef CONFIG_PROC_FS
1324 1276 remove_proc_subtree("sctp", net->proc_net);
1325 sctp_proc_exit(net); 1277 net->sctp.proc_net_sctp = NULL;
1278#endif
1326 cleanup_sctp_mibs(net); 1279 cleanup_sctp_mibs(net);
1327 sctp_sysctl_net_unregister(net); 1280 sctp_sysctl_net_unregister(net);
1328} 1281}
@@ -1330,6 +1283,7 @@ static void __net_exit sctp_defaults_exit(struct net *net)
1330static struct pernet_operations sctp_defaults_ops = { 1283static struct pernet_operations sctp_defaults_ops = {
1331 .init = sctp_defaults_init, 1284 .init = sctp_defaults_init,
1332 .exit = sctp_defaults_exit, 1285 .exit = sctp_defaults_exit,
1286 .async = true,
1333}; 1287};
1334 1288
1335static int __net_init sctp_ctrlsock_init(struct net *net) 1289static int __net_init sctp_ctrlsock_init(struct net *net)
@@ -1353,6 +1307,7 @@ static void __net_init sctp_ctrlsock_exit(struct net *net)
1353static struct pernet_operations sctp_ctrlsock_ops = { 1307static struct pernet_operations sctp_ctrlsock_ops = {
1354 .init = sctp_ctrlsock_init, 1308 .init = sctp_ctrlsock_init,
1355 .exit = sctp_ctrlsock_exit, 1309 .exit = sctp_ctrlsock_exit,
1310 .async = true,
1356}; 1311};
1357 1312
1358/* Initialize the universe into something sensible. */ 1313/* Initialize the universe into something sensible. */
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index d01475f5f710..cc20bc39ee7c 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -87,7 +87,28 @@ static void *sctp_addto_chunk_fixed(struct sctp_chunk *, int len,
87/* Control chunk destructor */ 87/* Control chunk destructor */
88static void sctp_control_release_owner(struct sk_buff *skb) 88static void sctp_control_release_owner(struct sk_buff *skb)
89{ 89{
90 /*TODO: do memory release */ 90 struct sctp_chunk *chunk = skb_shinfo(skb)->destructor_arg;
91
92 if (chunk->shkey) {
93 struct sctp_shared_key *shkey = chunk->shkey;
94 struct sctp_association *asoc = chunk->asoc;
95
96 /* refcnt == 2 and !list_empty mean after this release, it's
97 * not being used anywhere, and it's time to notify userland
98 * that this shkey can be freed if it's been deactivated.
99 */
100 if (shkey->deactivated && !list_empty(&shkey->key_list) &&
101 refcount_read(&shkey->refcnt) == 2) {
102 struct sctp_ulpevent *ev;
103
104 ev = sctp_ulpevent_make_authkey(asoc, shkey->key_id,
105 SCTP_AUTH_FREE_KEY,
106 GFP_KERNEL);
107 if (ev)
108 asoc->stream.si->enqueue_event(&asoc->ulpq, ev);
109 }
110 sctp_auth_shkey_release(chunk->shkey);
111 }
91} 112}
92 113
93static void sctp_control_set_owner_w(struct sctp_chunk *chunk) 114static void sctp_control_set_owner_w(struct sctp_chunk *chunk)
@@ -102,7 +123,12 @@ static void sctp_control_set_owner_w(struct sctp_chunk *chunk)
102 * 123 *
103 * For now don't do anything for now. 124 * For now don't do anything for now.
104 */ 125 */
126 if (chunk->auth) {
127 chunk->shkey = asoc->shkey;
128 sctp_auth_shkey_hold(chunk->shkey);
129 }
105 skb->sk = asoc ? asoc->base.sk : NULL; 130 skb->sk = asoc ? asoc->base.sk : NULL;
131 skb_shinfo(skb)->destructor_arg = chunk;
106 skb->destructor = sctp_control_release_owner; 132 skb->destructor = sctp_control_release_owner;
107} 133}
108 134
@@ -1271,7 +1297,8 @@ nodata:
1271 return retval; 1297 return retval;
1272} 1298}
1273 1299
1274struct sctp_chunk *sctp_make_auth(const struct sctp_association *asoc) 1300struct sctp_chunk *sctp_make_auth(const struct sctp_association *asoc,
1301 __u16 key_id)
1275{ 1302{
1276 struct sctp_authhdr auth_hdr; 1303 struct sctp_authhdr auth_hdr;
1277 struct sctp_hmac *hmac_desc; 1304 struct sctp_hmac *hmac_desc;
@@ -1289,7 +1316,7 @@ struct sctp_chunk *sctp_make_auth(const struct sctp_association *asoc)
1289 return NULL; 1316 return NULL;
1290 1317
1291 auth_hdr.hmac_id = htons(hmac_desc->hmac_id); 1318 auth_hdr.hmac_id = htons(hmac_desc->hmac_id);
1292 auth_hdr.shkey_id = htons(asoc->active_key_id); 1319 auth_hdr.shkey_id = htons(key_id);
1293 1320
1294 retval->subh.auth_hdr = sctp_addto_chunk(retval, sizeof(auth_hdr), 1321 retval->subh.auth_hdr = sctp_addto_chunk(retval, sizeof(auth_hdr),
1295 &auth_hdr); 1322 &auth_hdr);
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index b71e7fb0a20a..298112ca8c06 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -1049,6 +1049,16 @@ static void sctp_cmd_assoc_change(struct sctp_cmd_seq *commands,
1049 asoc->stream.si->enqueue_event(&asoc->ulpq, ev); 1049 asoc->stream.si->enqueue_event(&asoc->ulpq, ev);
1050} 1050}
1051 1051
1052static void sctp_cmd_peer_no_auth(struct sctp_cmd_seq *commands,
1053 struct sctp_association *asoc)
1054{
1055 struct sctp_ulpevent *ev;
1056
1057 ev = sctp_ulpevent_make_authkey(asoc, 0, SCTP_AUTH_NO_AUTH, GFP_ATOMIC);
1058 if (ev)
1059 asoc->stream.si->enqueue_event(&asoc->ulpq, ev);
1060}
1061
1052/* Helper function to generate an adaptation indication event */ 1062/* Helper function to generate an adaptation indication event */
1053static void sctp_cmd_adaptation_ind(struct sctp_cmd_seq *commands, 1063static void sctp_cmd_adaptation_ind(struct sctp_cmd_seq *commands,
1054 struct sctp_association *asoc) 1064 struct sctp_association *asoc)
@@ -1755,6 +1765,9 @@ static int sctp_cmd_interpreter(enum sctp_event event_type,
1755 case SCTP_CMD_ADAPTATION_IND: 1765 case SCTP_CMD_ADAPTATION_IND:
1756 sctp_cmd_adaptation_ind(commands, asoc); 1766 sctp_cmd_adaptation_ind(commands, asoc);
1757 break; 1767 break;
1768 case SCTP_CMD_PEER_NO_AUTH:
1769 sctp_cmd_peer_no_auth(commands, asoc);
1770 break;
1758 1771
1759 case SCTP_CMD_ASSOC_SHKEY: 1772 case SCTP_CMD_ASSOC_SHKEY:
1760 error = sctp_auth_asoc_init_active_key(asoc, 1773 error = sctp_auth_asoc_init_active_key(asoc,
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index eb7905ffe5f2..cc56a67dbb4d 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -659,7 +659,7 @@ enum sctp_disposition sctp_sf_do_5_1D_ce(struct net *net,
659 void *arg, 659 void *arg,
660 struct sctp_cmd_seq *commands) 660 struct sctp_cmd_seq *commands)
661{ 661{
662 struct sctp_ulpevent *ev, *ai_ev = NULL; 662 struct sctp_ulpevent *ev, *ai_ev = NULL, *auth_ev = NULL;
663 struct sctp_association *new_asoc; 663 struct sctp_association *new_asoc;
664 struct sctp_init_chunk *peer_init; 664 struct sctp_init_chunk *peer_init;
665 struct sctp_chunk *chunk = arg; 665 struct sctp_chunk *chunk = arg;
@@ -820,6 +820,14 @@ enum sctp_disposition sctp_sf_do_5_1D_ce(struct net *net,
820 goto nomem_aiev; 820 goto nomem_aiev;
821 } 821 }
822 822
823 if (!new_asoc->peer.auth_capable) {
824 auth_ev = sctp_ulpevent_make_authkey(new_asoc, 0,
825 SCTP_AUTH_NO_AUTH,
826 GFP_ATOMIC);
827 if (!auth_ev)
828 goto nomem_authev;
829 }
830
823 /* Add all the state machine commands now since we've created 831 /* Add all the state machine commands now since we've created
824 * everything. This way we don't introduce memory corruptions 832 * everything. This way we don't introduce memory corruptions
825 * during side-effect processing and correclty count established 833 * during side-effect processing and correclty count established
@@ -847,8 +855,14 @@ enum sctp_disposition sctp_sf_do_5_1D_ce(struct net *net,
847 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, 855 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
848 SCTP_ULPEVENT(ai_ev)); 856 SCTP_ULPEVENT(ai_ev));
849 857
858 if (auth_ev)
859 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
860 SCTP_ULPEVENT(auth_ev));
861
850 return SCTP_DISPOSITION_CONSUME; 862 return SCTP_DISPOSITION_CONSUME;
851 863
864nomem_authev:
865 sctp_ulpevent_free(ai_ev);
852nomem_aiev: 866nomem_aiev:
853 sctp_ulpevent_free(ev); 867 sctp_ulpevent_free(ev);
854nomem_ev: 868nomem_ev:
@@ -953,6 +967,15 @@ enum sctp_disposition sctp_sf_do_5_1E_ca(struct net *net,
953 SCTP_ULPEVENT(ev)); 967 SCTP_ULPEVENT(ev));
954 } 968 }
955 969
970 if (!asoc->peer.auth_capable) {
971 ev = sctp_ulpevent_make_authkey(asoc, 0, SCTP_AUTH_NO_AUTH,
972 GFP_ATOMIC);
973 if (!ev)
974 goto nomem;
975 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
976 SCTP_ULPEVENT(ev));
977 }
978
956 return SCTP_DISPOSITION_CONSUME; 979 return SCTP_DISPOSITION_CONSUME;
957nomem: 980nomem:
958 return SCTP_DISPOSITION_NOMEM; 981 return SCTP_DISPOSITION_NOMEM;
@@ -1908,6 +1931,9 @@ static enum sctp_disposition sctp_sf_do_dupcook_b(
1908 if (asoc->peer.adaptation_ind) 1931 if (asoc->peer.adaptation_ind)
1909 sctp_add_cmd_sf(commands, SCTP_CMD_ADAPTATION_IND, SCTP_NULL()); 1932 sctp_add_cmd_sf(commands, SCTP_CMD_ADAPTATION_IND, SCTP_NULL());
1910 1933
1934 if (!asoc->peer.auth_capable)
1935 sctp_add_cmd_sf(commands, SCTP_CMD_PEER_NO_AUTH, SCTP_NULL());
1936
1911 return SCTP_DISPOSITION_CONSUME; 1937 return SCTP_DISPOSITION_CONSUME;
1912 1938
1913nomem: 1939nomem:
@@ -1954,7 +1980,7 @@ static enum sctp_disposition sctp_sf_do_dupcook_d(
1954 struct sctp_cmd_seq *commands, 1980 struct sctp_cmd_seq *commands,
1955 struct sctp_association *new_asoc) 1981 struct sctp_association *new_asoc)
1956{ 1982{
1957 struct sctp_ulpevent *ev = NULL, *ai_ev = NULL; 1983 struct sctp_ulpevent *ev = NULL, *ai_ev = NULL, *auth_ev = NULL;
1958 struct sctp_chunk *repl; 1984 struct sctp_chunk *repl;
1959 1985
1960 /* Clarification from Implementor's Guide: 1986 /* Clarification from Implementor's Guide:
@@ -2001,6 +2027,14 @@ static enum sctp_disposition sctp_sf_do_dupcook_d(
2001 goto nomem; 2027 goto nomem;
2002 2028
2003 } 2029 }
2030
2031 if (!asoc->peer.auth_capable) {
2032 auth_ev = sctp_ulpevent_make_authkey(asoc, 0,
2033 SCTP_AUTH_NO_AUTH,
2034 GFP_ATOMIC);
2035 if (!auth_ev)
2036 goto nomem;
2037 }
2004 } 2038 }
2005 2039
2006 repl = sctp_make_cookie_ack(new_asoc, chunk); 2040 repl = sctp_make_cookie_ack(new_asoc, chunk);
@@ -2015,10 +2049,15 @@ static enum sctp_disposition sctp_sf_do_dupcook_d(
2015 if (ai_ev) 2049 if (ai_ev)
2016 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, 2050 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
2017 SCTP_ULPEVENT(ai_ev)); 2051 SCTP_ULPEVENT(ai_ev));
2052 if (auth_ev)
2053 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
2054 SCTP_ULPEVENT(auth_ev));
2018 2055
2019 return SCTP_DISPOSITION_CONSUME; 2056 return SCTP_DISPOSITION_CONSUME;
2020 2057
2021nomem: 2058nomem:
2059 if (auth_ev)
2060 sctp_ulpevent_free(auth_ev);
2022 if (ai_ev) 2061 if (ai_ev)
2023 sctp_ulpevent_free(ai_ev); 2062 sctp_ulpevent_free(ai_ev);
2024 if (ev) 2063 if (ev)
@@ -4114,6 +4153,7 @@ static enum sctp_ierror sctp_sf_authenticate(
4114 const union sctp_subtype type, 4153 const union sctp_subtype type,
4115 struct sctp_chunk *chunk) 4154 struct sctp_chunk *chunk)
4116{ 4155{
4156 struct sctp_shared_key *sh_key = NULL;
4117 struct sctp_authhdr *auth_hdr; 4157 struct sctp_authhdr *auth_hdr;
4118 __u8 *save_digest, *digest; 4158 __u8 *save_digest, *digest;
4119 struct sctp_hmac *hmac; 4159 struct sctp_hmac *hmac;
@@ -4135,9 +4175,11 @@ static enum sctp_ierror sctp_sf_authenticate(
4135 * configured 4175 * configured
4136 */ 4176 */
4137 key_id = ntohs(auth_hdr->shkey_id); 4177 key_id = ntohs(auth_hdr->shkey_id);
4138 if (key_id != asoc->active_key_id && !sctp_auth_get_shkey(asoc, key_id)) 4178 if (key_id != asoc->active_key_id) {
4139 return SCTP_IERROR_AUTH_BAD_KEYID; 4179 sh_key = sctp_auth_get_shkey(asoc, key_id);
4140 4180 if (!sh_key)
4181 return SCTP_IERROR_AUTH_BAD_KEYID;
4182 }
4141 4183
4142 /* Make sure that the length of the signature matches what 4184 /* Make sure that the length of the signature matches what
4143 * we expect. 4185 * we expect.
@@ -4166,7 +4208,7 @@ static enum sctp_ierror sctp_sf_authenticate(
4166 4208
4167 sctp_auth_calculate_hmac(asoc, chunk->skb, 4209 sctp_auth_calculate_hmac(asoc, chunk->skb,
4168 (struct sctp_auth_chunk *)chunk->chunk_hdr, 4210 (struct sctp_auth_chunk *)chunk->chunk_hdr,
4169 GFP_ATOMIC); 4211 sh_key, GFP_ATOMIC);
4170 4212
4171 /* Discard the packet if the digests do not match */ 4213 /* Discard the packet if the digests do not match */
4172 if (memcmp(save_digest, digest, sig_len)) { 4214 if (memcmp(save_digest, digest, sig_len)) {
@@ -4243,7 +4285,7 @@ enum sctp_disposition sctp_sf_eat_auth(struct net *net,
4243 struct sctp_ulpevent *ev; 4285 struct sctp_ulpevent *ev;
4244 4286
4245 ev = sctp_ulpevent_make_authkey(asoc, ntohs(auth_hdr->shkey_id), 4287 ev = sctp_ulpevent_make_authkey(asoc, ntohs(auth_hdr->shkey_id),
4246 SCTP_AUTH_NEWKEY, GFP_ATOMIC); 4288 SCTP_AUTH_NEW_KEY, GFP_ATOMIC);
4247 4289
4248 if (!ev) 4290 if (!ev)
4249 return -ENOMEM; 4291 return -ENOMEM;
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index bf271f8c2dc9..7a10ae3c3d82 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -156,6 +156,9 @@ static inline void sctp_set_owner_w(struct sctp_chunk *chunk)
156 /* The sndbuf space is tracked per association. */ 156 /* The sndbuf space is tracked per association. */
157 sctp_association_hold(asoc); 157 sctp_association_hold(asoc);
158 158
159 if (chunk->shkey)
160 sctp_auth_shkey_hold(chunk->shkey);
161
159 skb_set_owner_w(chunk->skb, sk); 162 skb_set_owner_w(chunk->skb, sk);
160 163
161 chunk->skb->destructor = sctp_wfree; 164 chunk->skb->destructor = sctp_wfree;
@@ -1606,396 +1609,303 @@ static int sctp_error(struct sock *sk, int flags, int err)
1606static int sctp_msghdr_parse(const struct msghdr *msg, 1609static int sctp_msghdr_parse(const struct msghdr *msg,
1607 struct sctp_cmsgs *cmsgs); 1610 struct sctp_cmsgs *cmsgs);
1608 1611
1609static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len) 1612static int sctp_sendmsg_parse(struct sock *sk, struct sctp_cmsgs *cmsgs,
1613 struct sctp_sndrcvinfo *srinfo,
1614 const struct msghdr *msg, size_t msg_len)
1610{ 1615{
1611 struct net *net = sock_net(sk); 1616 __u16 sflags;
1612 struct sctp_sock *sp;
1613 struct sctp_endpoint *ep;
1614 struct sctp_association *new_asoc = NULL, *asoc = NULL;
1615 struct sctp_transport *transport, *chunk_tp;
1616 struct sctp_chunk *chunk;
1617 union sctp_addr to;
1618 struct sockaddr *msg_name = NULL;
1619 struct sctp_sndrcvinfo default_sinfo;
1620 struct sctp_sndrcvinfo *sinfo;
1621 struct sctp_initmsg *sinit;
1622 sctp_assoc_t associd = 0;
1623 struct sctp_cmsgs cmsgs = { NULL };
1624 enum sctp_scope scope;
1625 bool fill_sinfo_ttl = false, wait_connect = false;
1626 struct sctp_datamsg *datamsg;
1627 int msg_flags = msg->msg_flags;
1628 __u16 sinfo_flags = 0;
1629 long timeo;
1630 int err; 1617 int err;
1631 1618
1632 err = 0; 1619 if (sctp_sstate(sk, LISTENING) && sctp_style(sk, TCP))
1633 sp = sctp_sk(sk); 1620 return -EPIPE;
1634 ep = sp->ep;
1635
1636 pr_debug("%s: sk:%p, msg:%p, msg_len:%zu ep:%p\n", __func__, sk,
1637 msg, msg_len, ep);
1638 1621
1639 /* We cannot send a message over a TCP-style listening socket. */ 1622 if (msg_len > sk->sk_sndbuf)
1640 if (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING)) { 1623 return -EMSGSIZE;
1641 err = -EPIPE;
1642 goto out_nounlock;
1643 }
1644 1624
1645 /* Parse out the SCTP CMSGs. */ 1625 memset(cmsgs, 0, sizeof(*cmsgs));
1646 err = sctp_msghdr_parse(msg, &cmsgs); 1626 err = sctp_msghdr_parse(msg, cmsgs);
1647 if (err) { 1627 if (err) {
1648 pr_debug("%s: msghdr parse err:%x\n", __func__, err); 1628 pr_debug("%s: msghdr parse err:%x\n", __func__, err);
1649 goto out_nounlock; 1629 return err;
1650 } 1630 }
1651 1631
1652 /* Fetch the destination address for this packet. This 1632 memset(srinfo, 0, sizeof(*srinfo));
1653 * address only selects the association--it is not necessarily 1633 if (cmsgs->srinfo) {
1654 * the address we will send to. 1634 srinfo->sinfo_stream = cmsgs->srinfo->sinfo_stream;
1655 * For a peeled-off socket, msg_name is ignored. 1635 srinfo->sinfo_flags = cmsgs->srinfo->sinfo_flags;
1656 */ 1636 srinfo->sinfo_ppid = cmsgs->srinfo->sinfo_ppid;
1657 if (!sctp_style(sk, UDP_HIGH_BANDWIDTH) && msg->msg_name) { 1637 srinfo->sinfo_context = cmsgs->srinfo->sinfo_context;
1658 int msg_namelen = msg->msg_namelen; 1638 srinfo->sinfo_assoc_id = cmsgs->srinfo->sinfo_assoc_id;
1639 srinfo->sinfo_timetolive = cmsgs->srinfo->sinfo_timetolive;
1640 }
1659 1641
1660 err = sctp_verify_addr(sk, (union sctp_addr *)msg->msg_name, 1642 if (cmsgs->sinfo) {
1661 msg_namelen); 1643 srinfo->sinfo_stream = cmsgs->sinfo->snd_sid;
1662 if (err) 1644 srinfo->sinfo_flags = cmsgs->sinfo->snd_flags;
1663 return err; 1645 srinfo->sinfo_ppid = cmsgs->sinfo->snd_ppid;
1646 srinfo->sinfo_context = cmsgs->sinfo->snd_context;
1647 srinfo->sinfo_assoc_id = cmsgs->sinfo->snd_assoc_id;
1648 }
1664 1649
1665 if (msg_namelen > sizeof(to)) 1650 if (cmsgs->prinfo) {
1666 msg_namelen = sizeof(to); 1651 srinfo->sinfo_timetolive = cmsgs->prinfo->pr_value;
1667 memcpy(&to, msg->msg_name, msg_namelen); 1652 SCTP_PR_SET_POLICY(srinfo->sinfo_flags,
1668 msg_name = msg->msg_name; 1653 cmsgs->prinfo->pr_policy);
1669 } 1654 }
1670 1655
1671 sinit = cmsgs.init; 1656 sflags = srinfo->sinfo_flags;
1672 if (cmsgs.sinfo != NULL) { 1657 if (!sflags && msg_len)
1673 memset(&default_sinfo, 0, sizeof(default_sinfo)); 1658 return 0;
1674 default_sinfo.sinfo_stream = cmsgs.sinfo->snd_sid;
1675 default_sinfo.sinfo_flags = cmsgs.sinfo->snd_flags;
1676 default_sinfo.sinfo_ppid = cmsgs.sinfo->snd_ppid;
1677 default_sinfo.sinfo_context = cmsgs.sinfo->snd_context;
1678 default_sinfo.sinfo_assoc_id = cmsgs.sinfo->snd_assoc_id;
1679 1659
1680 sinfo = &default_sinfo; 1660 if (sctp_style(sk, TCP) && (sflags & (SCTP_EOF | SCTP_ABORT)))
1681 fill_sinfo_ttl = true; 1661 return -EINVAL;
1682 } else {
1683 sinfo = cmsgs.srinfo;
1684 }
1685 /* Did the user specify SNDINFO/SNDRCVINFO? */
1686 if (sinfo) {
1687 sinfo_flags = sinfo->sinfo_flags;
1688 associd = sinfo->sinfo_assoc_id;
1689 }
1690 1662
1691 pr_debug("%s: msg_len:%zu, sinfo_flags:0x%x\n", __func__, 1663 if (((sflags & SCTP_EOF) && msg_len > 0) ||
1692 msg_len, sinfo_flags); 1664 (!(sflags & (SCTP_EOF | SCTP_ABORT)) && msg_len == 0))
1665 return -EINVAL;
1693 1666
1694 /* SCTP_EOF or SCTP_ABORT cannot be set on a TCP-style socket. */ 1667 if ((sflags & SCTP_ADDR_OVER) && !msg->msg_name)
1695 if (sctp_style(sk, TCP) && (sinfo_flags & (SCTP_EOF | SCTP_ABORT))) { 1668 return -EINVAL;
1696 err = -EINVAL;
1697 goto out_nounlock;
1698 }
1699 1669
1700 /* If SCTP_EOF is set, no data can be sent. Disallow sending zero 1670 return 0;
1701 * length messages when SCTP_EOF|SCTP_ABORT is not set. 1671}
1702 * If SCTP_ABORT is set, the message length could be non zero with
1703 * the msg_iov set to the user abort reason.
1704 */
1705 if (((sinfo_flags & SCTP_EOF) && (msg_len > 0)) ||
1706 (!(sinfo_flags & (SCTP_EOF|SCTP_ABORT)) && (msg_len == 0))) {
1707 err = -EINVAL;
1708 goto out_nounlock;
1709 }
1710 1672
1711 /* If SCTP_ADDR_OVER is set, there must be an address 1673static int sctp_sendmsg_new_asoc(struct sock *sk, __u16 sflags,
1712 * specified in msg_name. 1674 struct sctp_cmsgs *cmsgs,
1713 */ 1675 union sctp_addr *daddr,
1714 if ((sinfo_flags & SCTP_ADDR_OVER) && (!msg->msg_name)) { 1676 struct sctp_transport **tp)
1715 err = -EINVAL; 1677{
1716 goto out_nounlock; 1678 struct sctp_endpoint *ep = sctp_sk(sk)->ep;
1717 } 1679 struct net *net = sock_net(sk);
1680 struct sctp_association *asoc;
1681 enum sctp_scope scope;
1682 struct cmsghdr *cmsg;
1683 int err;
1718 1684
1719 transport = NULL; 1685 *tp = NULL;
1720 1686
1721 pr_debug("%s: about to look up association\n", __func__); 1687 if (sflags & (SCTP_EOF | SCTP_ABORT))
1688 return -EINVAL;
1722 1689
1723 lock_sock(sk); 1690 if (sctp_style(sk, TCP) && (sctp_sstate(sk, ESTABLISHED) ||
1691 sctp_sstate(sk, CLOSING)))
1692 return -EADDRNOTAVAIL;
1724 1693
1725 /* If a msg_name has been specified, assume this is to be used. */ 1694 if (sctp_endpoint_is_peeled_off(ep, daddr))
1726 if (msg_name) { 1695 return -EADDRNOTAVAIL;
1727 /* Look for a matching association on the endpoint. */
1728 asoc = sctp_endpoint_lookup_assoc(ep, &to, &transport);
1729 1696
1730 /* If we could not find a matching association on the 1697 if (!ep->base.bind_addr.port) {
1731 * endpoint, make sure that it is not a TCP-style 1698 if (sctp_autobind(sk))
1732 * socket that already has an association or there is 1699 return -EAGAIN;
1733 * no peeled-off association on another socket.
1734 */
1735 if (!asoc &&
1736 ((sctp_style(sk, TCP) &&
1737 (sctp_sstate(sk, ESTABLISHED) ||
1738 sctp_sstate(sk, CLOSING))) ||
1739 sctp_endpoint_is_peeled_off(ep, &to))) {
1740 err = -EADDRNOTAVAIL;
1741 goto out_unlock;
1742 }
1743 } else { 1700 } else {
1744 asoc = sctp_id2assoc(sk, associd); 1701 if (ep->base.bind_addr.port < inet_prot_sock(net) &&
1745 if (!asoc) { 1702 !ns_capable(net->user_ns, CAP_NET_BIND_SERVICE))
1746 err = -EPIPE; 1703 return -EACCES;
1747 goto out_unlock;
1748 }
1749 } 1704 }
1750 1705
1751 if (asoc) { 1706 scope = sctp_scope(daddr);
1752 pr_debug("%s: just looked up association:%p\n", __func__, asoc);
1753 1707
1754 /* We cannot send a message on a TCP-style SCTP_SS_ESTABLISHED 1708 asoc = sctp_association_new(ep, sk, scope, GFP_KERNEL);
1755 * socket that has an association in CLOSED state. This can 1709 if (!asoc)
1756 * happen when an accepted socket has an association that is 1710 return -ENOMEM;
1757 * already CLOSED. 1711
1758 */ 1712 if (sctp_assoc_set_bind_addr_from_ep(asoc, scope, GFP_KERNEL) < 0) {
1759 if (sctp_state(asoc, CLOSED) && sctp_style(sk, TCP)) { 1713 err = -ENOMEM;
1760 err = -EPIPE; 1714 goto free;
1761 goto out_unlock; 1715 }
1762 }
1763 1716
1764 if (sinfo_flags & SCTP_EOF) { 1717 if (cmsgs->init) {
1765 pr_debug("%s: shutting down association:%p\n", 1718 struct sctp_initmsg *init = cmsgs->init;
1766 __func__, asoc);
1767 1719
1768 sctp_primitive_SHUTDOWN(net, asoc, NULL); 1720 if (init->sinit_num_ostreams) {
1769 err = 0; 1721 __u16 outcnt = init->sinit_num_ostreams;
1770 goto out_unlock; 1722
1723 asoc->c.sinit_num_ostreams = outcnt;
1724 /* outcnt has been changed, need to re-init stream */
1725 err = sctp_stream_init(&asoc->stream, outcnt, 0,
1726 GFP_KERNEL);
1727 if (err)
1728 goto free;
1771 } 1729 }
1772 if (sinfo_flags & SCTP_ABORT) {
1773 1730
1774 chunk = sctp_make_abort_user(asoc, msg, msg_len); 1731 if (init->sinit_max_instreams)
1775 if (!chunk) { 1732 asoc->c.sinit_max_instreams = init->sinit_max_instreams;
1776 err = -ENOMEM;
1777 goto out_unlock;
1778 }
1779 1733
1780 pr_debug("%s: aborting association:%p\n", 1734 if (init->sinit_max_attempts)
1781 __func__, asoc); 1735 asoc->max_init_attempts = init->sinit_max_attempts;
1782 1736
1783 sctp_primitive_ABORT(net, asoc, chunk); 1737 if (init->sinit_max_init_timeo)
1784 err = 0; 1738 asoc->max_init_timeo =
1785 goto out_unlock; 1739 msecs_to_jiffies(init->sinit_max_init_timeo);
1786 }
1787 } 1740 }
1788 1741
1789 /* Do we need to create the association? */ 1742 *tp = sctp_assoc_add_peer(asoc, daddr, GFP_KERNEL, SCTP_UNKNOWN);
1790 if (!asoc) { 1743 if (!*tp) {
1791 pr_debug("%s: there is no association yet\n", __func__); 1744 err = -ENOMEM;
1745 goto free;
1746 }
1792 1747
1793 if (sinfo_flags & (SCTP_EOF | SCTP_ABORT)) { 1748 if (!cmsgs->addrs_msg)
1794 err = -EINVAL; 1749 return 0;
1795 goto out_unlock;
1796 }
1797 1750
1798 /* Check for invalid stream against the stream counts, 1751 /* sendv addr list parse */
1799 * either the default or the user specified stream counts. 1752 for_each_cmsghdr(cmsg, cmsgs->addrs_msg) {
1800 */ 1753 struct sctp_transport *transport;
1801 if (sinfo) { 1754 struct sctp_association *old;
1802 if (!sinit || !sinit->sinit_num_ostreams) { 1755 union sctp_addr _daddr;
1803 /* Check against the defaults. */ 1756 int dlen;
1804 if (sinfo->sinfo_stream >=
1805 sp->initmsg.sinit_num_ostreams) {
1806 err = -EINVAL;
1807 goto out_unlock;
1808 }
1809 } else {
1810 /* Check against the requested. */
1811 if (sinfo->sinfo_stream >=
1812 sinit->sinit_num_ostreams) {
1813 err = -EINVAL;
1814 goto out_unlock;
1815 }
1816 }
1817 }
1818 1757
1819 /* 1758 if (cmsg->cmsg_level != IPPROTO_SCTP ||
1820 * API 3.1.2 bind() - UDP Style Syntax 1759 (cmsg->cmsg_type != SCTP_DSTADDRV4 &&
1821 * If a bind() or sctp_bindx() is not called prior to a 1760 cmsg->cmsg_type != SCTP_DSTADDRV6))
1822 * sendmsg() call that initiates a new association, the 1761 continue;
1823 * system picks an ephemeral port and will choose an address 1762
1824 * set equivalent to binding with a wildcard address. 1763 daddr = &_daddr;
1825 */ 1764 memset(daddr, 0, sizeof(*daddr));
1826 if (!ep->base.bind_addr.port) { 1765 dlen = cmsg->cmsg_len - sizeof(struct cmsghdr);
1827 if (sctp_autobind(sk)) { 1766 if (cmsg->cmsg_type == SCTP_DSTADDRV4) {
1828 err = -EAGAIN; 1767 if (dlen < sizeof(struct in_addr)) {
1829 goto out_unlock; 1768 err = -EINVAL;
1769 goto free;
1830 } 1770 }
1771
1772 dlen = sizeof(struct in_addr);
1773 daddr->v4.sin_family = AF_INET;
1774 daddr->v4.sin_port = htons(asoc->peer.port);
1775 memcpy(&daddr->v4.sin_addr, CMSG_DATA(cmsg), dlen);
1831 } else { 1776 } else {
1832 /* 1777 if (dlen < sizeof(struct in6_addr)) {
1833 * If an unprivileged user inherits a one-to-many 1778 err = -EINVAL;
1834 * style socket with open associations on a privileged 1779 goto free;
1835 * port, it MAY be permitted to accept new associations,
1836 * but it SHOULD NOT be permitted to open new
1837 * associations.
1838 */
1839 if (ep->base.bind_addr.port < inet_prot_sock(net) &&
1840 !ns_capable(net->user_ns, CAP_NET_BIND_SERVICE)) {
1841 err = -EACCES;
1842 goto out_unlock;
1843 } 1780 }
1844 }
1845 1781
1846 scope = sctp_scope(&to); 1782 dlen = sizeof(struct in6_addr);
1847 new_asoc = sctp_association_new(ep, sk, scope, GFP_KERNEL); 1783 daddr->v6.sin6_family = AF_INET6;
1848 if (!new_asoc) { 1784 daddr->v6.sin6_port = htons(asoc->peer.port);
1849 err = -ENOMEM; 1785 memcpy(&daddr->v6.sin6_addr, CMSG_DATA(cmsg), dlen);
1850 goto out_unlock;
1851 } 1786 }
1852 asoc = new_asoc; 1787 err = sctp_verify_addr(sk, daddr, sizeof(*daddr));
1853 err = sctp_assoc_set_bind_addr_from_ep(asoc, scope, GFP_KERNEL); 1788 if (err)
1854 if (err < 0) { 1789 goto free;
1855 err = -ENOMEM; 1790
1856 goto out_free; 1791 old = sctp_endpoint_lookup_assoc(ep, daddr, &transport);
1792 if (old && old != asoc) {
1793 if (old->state >= SCTP_STATE_ESTABLISHED)
1794 err = -EISCONN;
1795 else
1796 err = -EALREADY;
1797 goto free;
1857 } 1798 }
1858 1799
1859 /* If the SCTP_INIT ancillary data is specified, set all 1800 if (sctp_endpoint_is_peeled_off(ep, daddr)) {
1860 * the association init values accordingly. 1801 err = -EADDRNOTAVAIL;
1861 */ 1802 goto free;
1862 if (sinit) {
1863 if (sinit->sinit_num_ostreams) {
1864 __u16 outcnt = sinit->sinit_num_ostreams;
1865
1866 asoc->c.sinit_num_ostreams = outcnt;
1867 /* outcnt has been changed, so re-init stream */
1868 err = sctp_stream_init(&asoc->stream, outcnt, 0,
1869 GFP_KERNEL);
1870 if (err)
1871 goto out_free;
1872 }
1873 if (sinit->sinit_max_instreams) {
1874 asoc->c.sinit_max_instreams =
1875 sinit->sinit_max_instreams;
1876 }
1877 if (sinit->sinit_max_attempts) {
1878 asoc->max_init_attempts
1879 = sinit->sinit_max_attempts;
1880 }
1881 if (sinit->sinit_max_init_timeo) {
1882 asoc->max_init_timeo =
1883 msecs_to_jiffies(sinit->sinit_max_init_timeo);
1884 }
1885 } 1803 }
1886 1804
1887 /* Prime the peer's transport structures. */ 1805 transport = sctp_assoc_add_peer(asoc, daddr, GFP_KERNEL,
1888 transport = sctp_assoc_add_peer(asoc, &to, GFP_KERNEL, SCTP_UNKNOWN); 1806 SCTP_UNKNOWN);
1889 if (!transport) { 1807 if (!transport) {
1890 err = -ENOMEM; 1808 err = -ENOMEM;
1891 goto out_free; 1809 goto free;
1892 } 1810 }
1893 } 1811 }
1894 1812
1895 /* ASSERT: we have a valid association at this point. */ 1813 return 0;
1896 pr_debug("%s: we have a valid association\n", __func__);
1897 1814
1898 if (!sinfo) { 1815free:
1899 /* If the user didn't specify SNDINFO/SNDRCVINFO, make up 1816 sctp_association_free(asoc);
1900 * one with some defaults. 1817 return err;
1901 */ 1818}
1902 memset(&default_sinfo, 0, sizeof(default_sinfo));
1903 default_sinfo.sinfo_stream = asoc->default_stream;
1904 default_sinfo.sinfo_flags = asoc->default_flags;
1905 default_sinfo.sinfo_ppid = asoc->default_ppid;
1906 default_sinfo.sinfo_context = asoc->default_context;
1907 default_sinfo.sinfo_timetolive = asoc->default_timetolive;
1908 default_sinfo.sinfo_assoc_id = sctp_assoc2id(asoc);
1909
1910 sinfo = &default_sinfo;
1911 } else if (fill_sinfo_ttl) {
1912 /* In case SNDINFO was specified, we still need to fill
1913 * it with a default ttl from the assoc here.
1914 */
1915 sinfo->sinfo_timetolive = asoc->default_timetolive;
1916 }
1917 1819
1918 /* API 7.1.7, the sndbuf size per association bounds the 1820static int sctp_sendmsg_check_sflags(struct sctp_association *asoc,
1919 * maximum size of data that can be sent in a single send call. 1821 __u16 sflags, struct msghdr *msg,
1920 */ 1822 size_t msg_len)
1921 if (msg_len > sk->sk_sndbuf) { 1823{
1922 err = -EMSGSIZE; 1824 struct sock *sk = asoc->base.sk;
1923 goto out_free; 1825 struct net *net = sock_net(sk);
1826
1827 if (sctp_state(asoc, CLOSED) && sctp_style(sk, TCP))
1828 return -EPIPE;
1829
1830 if ((sflags & SCTP_SENDALL) && sctp_style(sk, UDP) &&
1831 !sctp_state(asoc, ESTABLISHED))
1832 return 0;
1833
1834 if (sflags & SCTP_EOF) {
1835 pr_debug("%s: shutting down association:%p\n", __func__, asoc);
1836 sctp_primitive_SHUTDOWN(net, asoc, NULL);
1837
1838 return 0;
1924 } 1839 }
1925 1840
1926 if (asoc->pmtu_pending) 1841 if (sflags & SCTP_ABORT) {
1927 sctp_assoc_pending_pmtu(asoc); 1842 struct sctp_chunk *chunk;
1928 1843
1929 /* If fragmentation is disabled and the message length exceeds the 1844 chunk = sctp_make_abort_user(asoc, msg, msg_len);
1930 * association fragmentation point, return EMSGSIZE. The I-D 1845 if (!chunk)
1931 * does not specify what this error is, but this looks like 1846 return -ENOMEM;
1932 * a great fit. 1847
1933 */ 1848 pr_debug("%s: aborting association:%p\n", __func__, asoc);
1934 if (sctp_sk(sk)->disable_fragments && (msg_len > asoc->frag_point)) { 1849 sctp_primitive_ABORT(net, asoc, chunk);
1935 err = -EMSGSIZE; 1850
1936 goto out_free; 1851 return 0;
1937 } 1852 }
1938 1853
1939 /* Check for invalid stream. */ 1854 return 1;
1855}
1856
1857static int sctp_sendmsg_to_asoc(struct sctp_association *asoc,
1858 struct msghdr *msg, size_t msg_len,
1859 struct sctp_transport *transport,
1860 struct sctp_sndrcvinfo *sinfo)
1861{
1862 struct sock *sk = asoc->base.sk;
1863 struct net *net = sock_net(sk);
1864 struct sctp_datamsg *datamsg;
1865 bool wait_connect = false;
1866 struct sctp_chunk *chunk;
1867 long timeo;
1868 int err;
1869
1940 if (sinfo->sinfo_stream >= asoc->stream.outcnt) { 1870 if (sinfo->sinfo_stream >= asoc->stream.outcnt) {
1941 err = -EINVAL; 1871 err = -EINVAL;
1942 goto out_free; 1872 goto err;
1943 } 1873 }
1944 1874
1945 /* Allocate sctp_stream_out_ext if not already done */
1946 if (unlikely(!asoc->stream.out[sinfo->sinfo_stream].ext)) { 1875 if (unlikely(!asoc->stream.out[sinfo->sinfo_stream].ext)) {
1947 err = sctp_stream_init_ext(&asoc->stream, sinfo->sinfo_stream); 1876 err = sctp_stream_init_ext(&asoc->stream, sinfo->sinfo_stream);
1948 if (err) 1877 if (err)
1949 goto out_free; 1878 goto err;
1950 } 1879 }
1951 1880
1881 if (sctp_sk(sk)->disable_fragments && msg_len > asoc->frag_point) {
1882 err = -EMSGSIZE;
1883 goto err;
1884 }
1885
1886 if (asoc->pmtu_pending)
1887 sctp_assoc_pending_pmtu(asoc);
1888
1952 if (sctp_wspace(asoc) < msg_len) 1889 if (sctp_wspace(asoc) < msg_len)
1953 sctp_prsctp_prune(asoc, sinfo, msg_len - sctp_wspace(asoc)); 1890 sctp_prsctp_prune(asoc, sinfo, msg_len - sctp_wspace(asoc));
1954 1891
1955 timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
1956 if (!sctp_wspace(asoc)) { 1892 if (!sctp_wspace(asoc)) {
1957 /* sk can be changed by peel off when waiting for buf. */ 1893 timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
1958 err = sctp_wait_for_sndbuf(asoc, &timeo, msg_len); 1894 err = sctp_wait_for_sndbuf(asoc, &timeo, msg_len);
1959 if (err) { 1895 if (err)
1960 if (err == -ESRCH) { 1896 goto err;
1961 /* asoc is already dead. */
1962 new_asoc = NULL;
1963 err = -EPIPE;
1964 }
1965 goto out_free;
1966 }
1967 } 1897 }
1968 1898
1969 /* If an address is passed with the sendto/sendmsg call, it is used
1970 * to override the primary destination address in the TCP model, or
1971 * when SCTP_ADDR_OVER flag is set in the UDP model.
1972 */
1973 if ((sctp_style(sk, TCP) && msg_name) ||
1974 (sinfo_flags & SCTP_ADDR_OVER)) {
1975 chunk_tp = sctp_assoc_lookup_paddr(asoc, &to);
1976 if (!chunk_tp) {
1977 err = -EINVAL;
1978 goto out_free;
1979 }
1980 } else
1981 chunk_tp = NULL;
1982
1983 /* Auto-connect, if we aren't connected already. */
1984 if (sctp_state(asoc, CLOSED)) { 1899 if (sctp_state(asoc, CLOSED)) {
1985 err = sctp_primitive_ASSOCIATE(net, asoc, NULL); 1900 err = sctp_primitive_ASSOCIATE(net, asoc, NULL);
1986 if (err < 0) 1901 if (err)
1987 goto out_free; 1902 goto err;
1988 1903
1989 /* If stream interleave is enabled, wait_connect has to be 1904 if (sctp_sk(sk)->strm_interleave) {
1990 * done earlier than data enqueue, as it needs to make data
1991 * or idata according to asoc->intl_enable which is set
1992 * after connection is done.
1993 */
1994 if (sctp_sk(asoc->base.sk)->strm_interleave) {
1995 timeo = sock_sndtimeo(sk, 0); 1905 timeo = sock_sndtimeo(sk, 0);
1996 err = sctp_wait_for_connect(asoc, &timeo); 1906 err = sctp_wait_for_connect(asoc, &timeo);
1997 if (err) 1907 if (err)
1998 goto out_unlock; 1908 goto err;
1999 } else { 1909 } else {
2000 wait_connect = true; 1910 wait_connect = true;
2001 } 1911 }
@@ -2003,73 +1913,186 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len)
2003 pr_debug("%s: we associated primitively\n", __func__); 1913 pr_debug("%s: we associated primitively\n", __func__);
2004 } 1914 }
2005 1915
2006 /* Break the message into multiple chunks of maximum size. */
2007 datamsg = sctp_datamsg_from_user(asoc, sinfo, &msg->msg_iter); 1916 datamsg = sctp_datamsg_from_user(asoc, sinfo, &msg->msg_iter);
2008 if (IS_ERR(datamsg)) { 1917 if (IS_ERR(datamsg)) {
2009 err = PTR_ERR(datamsg); 1918 err = PTR_ERR(datamsg);
2010 goto out_free; 1919 goto err;
2011 } 1920 }
1921
2012 asoc->force_delay = !!(msg->msg_flags & MSG_MORE); 1922 asoc->force_delay = !!(msg->msg_flags & MSG_MORE);
2013 1923
2014 /* Now send the (possibly) fragmented message. */
2015 list_for_each_entry(chunk, &datamsg->chunks, frag_list) { 1924 list_for_each_entry(chunk, &datamsg->chunks, frag_list) {
2016 sctp_chunk_hold(chunk); 1925 sctp_chunk_hold(chunk);
2017
2018 /* Do accounting for the write space. */
2019 sctp_set_owner_w(chunk); 1926 sctp_set_owner_w(chunk);
2020 1927 chunk->transport = transport;
2021 chunk->transport = chunk_tp;
2022 } 1928 }
2023 1929
2024 /* Send it to the lower layers. Note: all chunks
2025 * must either fail or succeed. The lower layer
2026 * works that way today. Keep it that way or this
2027 * breaks.
2028 */
2029 err = sctp_primitive_SEND(net, asoc, datamsg); 1930 err = sctp_primitive_SEND(net, asoc, datamsg);
2030 /* Did the lower layer accept the chunk? */
2031 if (err) { 1931 if (err) {
2032 sctp_datamsg_free(datamsg); 1932 sctp_datamsg_free(datamsg);
2033 goto out_free; 1933 goto err;
2034 } 1934 }
2035 1935
2036 pr_debug("%s: we sent primitively\n", __func__); 1936 pr_debug("%s: we sent primitively\n", __func__);
2037 1937
2038 sctp_datamsg_put(datamsg); 1938 sctp_datamsg_put(datamsg);
2039 err = msg_len;
2040 1939
2041 if (unlikely(wait_connect)) { 1940 if (unlikely(wait_connect)) {
2042 timeo = sock_sndtimeo(sk, msg_flags & MSG_DONTWAIT); 1941 timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
2043 sctp_wait_for_connect(asoc, &timeo); 1942 sctp_wait_for_connect(asoc, &timeo);
2044 } 1943 }
2045 1944
2046 /* If we are already past ASSOCIATE, the lower 1945 err = msg_len;
2047 * layers are responsible for association cleanup.
2048 */
2049 goto out_unlock;
2050 1946
2051out_free: 1947err:
2052 if (new_asoc) 1948 return err;
2053 sctp_association_free(asoc); 1949}
2054out_unlock:
2055 release_sock(sk);
2056 1950
2057out_nounlock: 1951static union sctp_addr *sctp_sendmsg_get_daddr(struct sock *sk,
2058 return sctp_error(sk, msg_flags, err); 1952 const struct msghdr *msg,
1953 struct sctp_cmsgs *cmsgs)
1954{
1955 union sctp_addr *daddr = NULL;
1956 int err;
2059 1957
2060#if 0 1958 if (!sctp_style(sk, UDP_HIGH_BANDWIDTH) && msg->msg_name) {
2061do_sock_err: 1959 int len = msg->msg_namelen;
2062 if (msg_len)
2063 err = msg_len;
2064 else
2065 err = sock_error(sk);
2066 goto out;
2067 1960
2068do_interrupted: 1961 if (len > sizeof(*daddr))
2069 if (msg_len) 1962 len = sizeof(*daddr);
2070 err = msg_len; 1963
2071 goto out; 1964 daddr = (union sctp_addr *)msg->msg_name;
2072#endif /* 0 */ 1965
1966 err = sctp_verify_addr(sk, daddr, len);
1967 if (err)
1968 return ERR_PTR(err);
1969 }
1970
1971 return daddr;
1972}
1973
1974static void sctp_sendmsg_update_sinfo(struct sctp_association *asoc,
1975 struct sctp_sndrcvinfo *sinfo,
1976 struct sctp_cmsgs *cmsgs)
1977{
1978 if (!cmsgs->srinfo && !cmsgs->sinfo) {
1979 sinfo->sinfo_stream = asoc->default_stream;
1980 sinfo->sinfo_ppid = asoc->default_ppid;
1981 sinfo->sinfo_context = asoc->default_context;
1982 sinfo->sinfo_assoc_id = sctp_assoc2id(asoc);
1983
1984 if (!cmsgs->prinfo)
1985 sinfo->sinfo_flags = asoc->default_flags;
1986 }
1987
1988 if (!cmsgs->srinfo && !cmsgs->prinfo)
1989 sinfo->sinfo_timetolive = asoc->default_timetolive;
1990
1991 if (cmsgs->authinfo) {
1992 /* Reuse sinfo_tsn to indicate that authinfo was set and
1993 * sinfo_ssn to save the keyid on tx path.
1994 */
1995 sinfo->sinfo_tsn = 1;
1996 sinfo->sinfo_ssn = cmsgs->authinfo->auth_keynumber;
1997 }
1998}
1999
2000static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len)
2001{
2002 struct sctp_endpoint *ep = sctp_sk(sk)->ep;
2003 struct sctp_transport *transport = NULL;
2004 struct sctp_sndrcvinfo _sinfo, *sinfo;
2005 struct sctp_association *asoc;
2006 struct sctp_cmsgs cmsgs;
2007 union sctp_addr *daddr;
2008 bool new = false;
2009 __u16 sflags;
2010 int err;
2011
2012 /* Parse and get snd_info */
2013 err = sctp_sendmsg_parse(sk, &cmsgs, &_sinfo, msg, msg_len);
2014 if (err)
2015 goto out;
2016
2017 sinfo = &_sinfo;
2018 sflags = sinfo->sinfo_flags;
2019
2020 /* Get daddr from msg */
2021 daddr = sctp_sendmsg_get_daddr(sk, msg, &cmsgs);
2022 if (IS_ERR(daddr)) {
2023 err = PTR_ERR(daddr);
2024 goto out;
2025 }
2026
2027 lock_sock(sk);
2028
2029 /* SCTP_SENDALL process */
2030 if ((sflags & SCTP_SENDALL) && sctp_style(sk, UDP)) {
2031 list_for_each_entry(asoc, &ep->asocs, asocs) {
2032 err = sctp_sendmsg_check_sflags(asoc, sflags, msg,
2033 msg_len);
2034 if (err == 0)
2035 continue;
2036 if (err < 0)
2037 goto out_unlock;
2038
2039 sctp_sendmsg_update_sinfo(asoc, sinfo, &cmsgs);
2040
2041 err = sctp_sendmsg_to_asoc(asoc, msg, msg_len,
2042 NULL, sinfo);
2043 if (err < 0)
2044 goto out_unlock;
2045
2046 iov_iter_revert(&msg->msg_iter, err);
2047 }
2048
2049 goto out_unlock;
2050 }
2051
2052 /* Get and check or create asoc */
2053 if (daddr) {
2054 asoc = sctp_endpoint_lookup_assoc(ep, daddr, &transport);
2055 if (asoc) {
2056 err = sctp_sendmsg_check_sflags(asoc, sflags, msg,
2057 msg_len);
2058 if (err <= 0)
2059 goto out_unlock;
2060 } else {
2061 err = sctp_sendmsg_new_asoc(sk, sflags, &cmsgs, daddr,
2062 &transport);
2063 if (err)
2064 goto out_unlock;
2065
2066 asoc = transport->asoc;
2067 new = true;
2068 }
2069
2070 if (!sctp_style(sk, TCP) && !(sflags & SCTP_ADDR_OVER))
2071 transport = NULL;
2072 } else {
2073 asoc = sctp_id2assoc(sk, sinfo->sinfo_assoc_id);
2074 if (!asoc) {
2075 err = -EPIPE;
2076 goto out_unlock;
2077 }
2078
2079 err = sctp_sendmsg_check_sflags(asoc, sflags, msg, msg_len);
2080 if (err <= 0)
2081 goto out_unlock;
2082 }
2083
2084 /* Update snd_info with the asoc */
2085 sctp_sendmsg_update_sinfo(asoc, sinfo, &cmsgs);
2086
2087 /* Send msg to the asoc */
2088 err = sctp_sendmsg_to_asoc(asoc, msg, msg_len, transport, sinfo);
2089 if (err < 0 && err != -ESRCH && new)
2090 sctp_association_free(asoc);
2091
2092out_unlock:
2093 release_sock(sk);
2094out:
2095 return sctp_error(sk, msg->msg_flags, err);
2073} 2096}
2074 2097
2075/* This is an extended version of skb_pull() that removes the data from the 2098/* This is an extended version of skb_pull() that removes the data from the
@@ -3624,6 +3647,33 @@ static int sctp_setsockopt_del_key(struct sock *sk,
3624} 3647}
3625 3648
3626/* 3649/*
3650 * 8.3.4 Deactivate a Shared Key (SCTP_AUTH_DEACTIVATE_KEY)
3651 *
3652 * This set option will deactivate a shared secret key.
3653 */
3654static int sctp_setsockopt_deactivate_key(struct sock *sk, char __user *optval,
3655 unsigned int optlen)
3656{
3657 struct sctp_endpoint *ep = sctp_sk(sk)->ep;
3658 struct sctp_authkeyid val;
3659 struct sctp_association *asoc;
3660
3661 if (!ep->auth_enable)
3662 return -EACCES;
3663
3664 if (optlen != sizeof(struct sctp_authkeyid))
3665 return -EINVAL;
3666 if (copy_from_user(&val, optval, optlen))
3667 return -EFAULT;
3668
3669 asoc = sctp_id2assoc(sk, val.scact_assoc_id);
3670 if (!asoc && val.scact_assoc_id && sctp_style(sk, UDP))
3671 return -EINVAL;
3672
3673 return sctp_auth_deact_key_id(ep, asoc, val.scact_keynumber);
3674}
3675
3676/*
3627 * 8.1.23 SCTP_AUTO_ASCONF 3677 * 8.1.23 SCTP_AUTO_ASCONF
3628 * 3678 *
3629 * This option will enable or disable the use of the automatic generation of 3679 * This option will enable or disable the use of the automatic generation of
@@ -4215,6 +4265,9 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
4215 case SCTP_AUTH_DELETE_KEY: 4265 case SCTP_AUTH_DELETE_KEY:
4216 retval = sctp_setsockopt_del_key(sk, optval, optlen); 4266 retval = sctp_setsockopt_del_key(sk, optval, optlen);
4217 break; 4267 break;
4268 case SCTP_AUTH_DEACTIVATE_KEY:
4269 retval = sctp_setsockopt_deactivate_key(sk, optval, optlen);
4270 break;
4218 case SCTP_AUTO_ASCONF: 4271 case SCTP_AUTO_ASCONF:
4219 retval = sctp_setsockopt_auto_asconf(sk, optval, optlen); 4272 retval = sctp_setsockopt_auto_asconf(sk, optval, optlen);
4220 break; 4273 break;
@@ -7189,6 +7242,7 @@ static int sctp_getsockopt(struct sock *sk, int level, int optname,
7189 case SCTP_AUTH_KEY: 7242 case SCTP_AUTH_KEY:
7190 case SCTP_AUTH_CHUNK: 7243 case SCTP_AUTH_CHUNK:
7191 case SCTP_AUTH_DELETE_KEY: 7244 case SCTP_AUTH_DELETE_KEY:
7245 case SCTP_AUTH_DEACTIVATE_KEY:
7192 retval = -EOPNOTSUPP; 7246 retval = -EOPNOTSUPP;
7193 break; 7247 break;
7194 case SCTP_HMAC_IDENT: 7248 case SCTP_HMAC_IDENT:
@@ -7811,8 +7865,8 @@ static int sctp_msghdr_parse(const struct msghdr *msg, struct sctp_cmsgs *cmsgs)
7811 7865
7812 if (cmsgs->srinfo->sinfo_flags & 7866 if (cmsgs->srinfo->sinfo_flags &
7813 ~(SCTP_UNORDERED | SCTP_ADDR_OVER | 7867 ~(SCTP_UNORDERED | SCTP_ADDR_OVER |
7814 SCTP_SACK_IMMEDIATELY | SCTP_PR_SCTP_MASK | 7868 SCTP_SACK_IMMEDIATELY | SCTP_SENDALL |
7815 SCTP_ABORT | SCTP_EOF)) 7869 SCTP_PR_SCTP_MASK | SCTP_ABORT | SCTP_EOF))
7816 return -EINVAL; 7870 return -EINVAL;
7817 break; 7871 break;
7818 7872
@@ -7835,10 +7889,60 @@ static int sctp_msghdr_parse(const struct msghdr *msg, struct sctp_cmsgs *cmsgs)
7835 7889
7836 if (cmsgs->sinfo->snd_flags & 7890 if (cmsgs->sinfo->snd_flags &
7837 ~(SCTP_UNORDERED | SCTP_ADDR_OVER | 7891 ~(SCTP_UNORDERED | SCTP_ADDR_OVER |
7838 SCTP_SACK_IMMEDIATELY | SCTP_PR_SCTP_MASK | 7892 SCTP_SACK_IMMEDIATELY | SCTP_SENDALL |
7839 SCTP_ABORT | SCTP_EOF)) 7893 SCTP_PR_SCTP_MASK | SCTP_ABORT | SCTP_EOF))
7840 return -EINVAL; 7894 return -EINVAL;
7841 break; 7895 break;
7896 case SCTP_PRINFO:
7897 /* SCTP Socket API Extension
7898 * 5.3.7 SCTP PR-SCTP Information Structure (SCTP_PRINFO)
7899 *
7900 * This cmsghdr structure specifies SCTP options for sendmsg().
7901 *
7902 * cmsg_level cmsg_type cmsg_data[]
7903 * ------------ ------------ ---------------------
7904 * IPPROTO_SCTP SCTP_PRINFO struct sctp_prinfo
7905 */
7906 if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct sctp_prinfo)))
7907 return -EINVAL;
7908
7909 cmsgs->prinfo = CMSG_DATA(cmsg);
7910 if (cmsgs->prinfo->pr_policy & ~SCTP_PR_SCTP_MASK)
7911 return -EINVAL;
7912
7913 if (cmsgs->prinfo->pr_policy == SCTP_PR_SCTP_NONE)
7914 cmsgs->prinfo->pr_value = 0;
7915 break;
7916 case SCTP_AUTHINFO:
7917 /* SCTP Socket API Extension
7918 * 5.3.8 SCTP AUTH Information Structure (SCTP_AUTHINFO)
7919 *
7920 * This cmsghdr structure specifies SCTP options for sendmsg().
7921 *
7922 * cmsg_level cmsg_type cmsg_data[]
7923 * ------------ ------------ ---------------------
7924 * IPPROTO_SCTP SCTP_AUTHINFO struct sctp_authinfo
7925 */
7926 if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct sctp_authinfo)))
7927 return -EINVAL;
7928
7929 cmsgs->authinfo = CMSG_DATA(cmsg);
7930 break;
7931 case SCTP_DSTADDRV4:
7932 case SCTP_DSTADDRV6:
7933 /* SCTP Socket API Extension
7934 * 5.3.9/10 SCTP Destination IPv4/6 Address Structure (SCTP_DSTADDRV4/6)
7935 *
7936 * This cmsghdr structure specifies SCTP options for sendmsg().
7937 *
7938 * cmsg_level cmsg_type cmsg_data[]
7939 * ------------ ------------ ---------------------
7940 * IPPROTO_SCTP SCTP_DSTADDRV4 struct in_addr
7941 * ------------ ------------ ---------------------
7942 * IPPROTO_SCTP SCTP_DSTADDRV6 struct in6_addr
7943 */
7944 cmsgs->addrs_msg = my_msg;
7945 break;
7842 default: 7946 default:
7843 return -EINVAL; 7947 return -EINVAL;
7844 } 7948 }
@@ -8062,6 +8166,26 @@ static void sctp_wfree(struct sk_buff *skb)
8062 sk->sk_wmem_queued -= skb->truesize; 8166 sk->sk_wmem_queued -= skb->truesize;
8063 sk_mem_uncharge(sk, skb->truesize); 8167 sk_mem_uncharge(sk, skb->truesize);
8064 8168
8169 if (chunk->shkey) {
8170 struct sctp_shared_key *shkey = chunk->shkey;
8171
8172 /* refcnt == 2 and !list_empty mean after this release, it's
8173 * not being used anywhere, and it's time to notify userland
8174 * that this shkey can be freed if it's been deactivated.
8175 */
8176 if (shkey->deactivated && !list_empty(&shkey->key_list) &&
8177 refcount_read(&shkey->refcnt) == 2) {
8178 struct sctp_ulpevent *ev;
8179
8180 ev = sctp_ulpevent_make_authkey(asoc, shkey->key_id,
8181 SCTP_AUTH_FREE_KEY,
8182 GFP_KERNEL);
8183 if (ev)
8184 asoc->stream.si->enqueue_event(&asoc->ulpq, ev);
8185 }
8186 sctp_auth_shkey_release(chunk->shkey);
8187 }
8188
8065 sock_wfree(skb); 8189 sock_wfree(skb);
8066 sctp_wake_up_waiters(sk, asoc); 8190 sctp_wake_up_waiters(sk, asoc);
8067 8191
diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
index 1e0d780855c3..5f8046c62d90 100644
--- a/net/smc/af_smc.c
+++ b/net/smc/af_smc.c
@@ -7,13 +7,11 @@
7 * applicable with RoCE-cards only 7 * applicable with RoCE-cards only
8 * 8 *
9 * Initial restrictions: 9 * Initial restrictions:
10 * - non-blocking connect postponed
11 * - IPv6 support postponed
12 * - support for alternate links postponed 10 * - support for alternate links postponed
13 * - partial support for non-blocking sockets only 11 * - partial support for non-blocking sockets only
14 * - support for urgent data postponed 12 * - support for urgent data postponed
15 * 13 *
16 * Copyright IBM Corp. 2016 14 * Copyright IBM Corp. 2016, 2018
17 * 15 *
18 * Author(s): Ursula Braun <ubraun@linux.vnet.ibm.com> 16 * Author(s): Ursula Braun <ubraun@linux.vnet.ibm.com>
19 * based on prototype from Frank Blaschka 17 * based on prototype from Frank Blaschka
@@ -24,7 +22,6 @@
24 22
25#include <linux/module.h> 23#include <linux/module.h>
26#include <linux/socket.h> 24#include <linux/socket.h>
27#include <linux/inetdevice.h>
28#include <linux/workqueue.h> 25#include <linux/workqueue.h>
29#include <linux/in.h> 26#include <linux/in.h>
30#include <linux/sched/signal.h> 27#include <linux/sched/signal.h>
@@ -66,6 +63,10 @@ static struct smc_hashinfo smc_v4_hashinfo = {
66 .lock = __RW_LOCK_UNLOCKED(smc_v4_hashinfo.lock), 63 .lock = __RW_LOCK_UNLOCKED(smc_v4_hashinfo.lock),
67}; 64};
68 65
66static struct smc_hashinfo smc_v6_hashinfo = {
67 .lock = __RW_LOCK_UNLOCKED(smc_v6_hashinfo.lock),
68};
69
69int smc_hash_sk(struct sock *sk) 70int smc_hash_sk(struct sock *sk)
70{ 71{
71 struct smc_hashinfo *h = sk->sk_prot->h.smc_hash; 72 struct smc_hashinfo *h = sk->sk_prot->h.smc_hash;
@@ -105,6 +106,18 @@ struct proto smc_proto = {
105}; 106};
106EXPORT_SYMBOL_GPL(smc_proto); 107EXPORT_SYMBOL_GPL(smc_proto);
107 108
109struct proto smc_proto6 = {
110 .name = "SMC6",
111 .owner = THIS_MODULE,
112 .keepalive = smc_set_keepalive,
113 .hash = smc_hash_sk,
114 .unhash = smc_unhash_sk,
115 .obj_size = sizeof(struct smc_sock),
116 .h.smc_hash = &smc_v6_hashinfo,
117 .slab_flags = SLAB_TYPESAFE_BY_RCU,
118};
119EXPORT_SYMBOL_GPL(smc_proto6);
120
108static int smc_release(struct socket *sock) 121static int smc_release(struct socket *sock)
109{ 122{
110 struct sock *sk = sock->sk; 123 struct sock *sk = sock->sk;
@@ -161,19 +174,22 @@ static void smc_destruct(struct sock *sk)
161 sk_refcnt_debug_dec(sk); 174 sk_refcnt_debug_dec(sk);
162} 175}
163 176
164static struct sock *smc_sock_alloc(struct net *net, struct socket *sock) 177static struct sock *smc_sock_alloc(struct net *net, struct socket *sock,
178 int protocol)
165{ 179{
166 struct smc_sock *smc; 180 struct smc_sock *smc;
181 struct proto *prot;
167 struct sock *sk; 182 struct sock *sk;
168 183
169 sk = sk_alloc(net, PF_SMC, GFP_KERNEL, &smc_proto, 0); 184 prot = (protocol == SMCPROTO_SMC6) ? &smc_proto6 : &smc_proto;
185 sk = sk_alloc(net, PF_SMC, GFP_KERNEL, prot, 0);
170 if (!sk) 186 if (!sk)
171 return NULL; 187 return NULL;
172 188
173 sock_init_data(sock, sk); /* sets sk_refcnt to 1 */ 189 sock_init_data(sock, sk); /* sets sk_refcnt to 1 */
174 sk->sk_state = SMC_INIT; 190 sk->sk_state = SMC_INIT;
175 sk->sk_destruct = smc_destruct; 191 sk->sk_destruct = smc_destruct;
176 sk->sk_protocol = SMCPROTO_SMC; 192 sk->sk_protocol = protocol;
177 smc = smc_sk(sk); 193 smc = smc_sk(sk);
178 INIT_WORK(&smc->tcp_listen_work, smc_tcp_listen_work); 194 INIT_WORK(&smc->tcp_listen_work, smc_tcp_listen_work);
179 INIT_LIST_HEAD(&smc->accept_q); 195 INIT_LIST_HEAD(&smc->accept_q);
@@ -200,10 +216,13 @@ static int smc_bind(struct socket *sock, struct sockaddr *uaddr,
200 goto out; 216 goto out;
201 217
202 rc = -EAFNOSUPPORT; 218 rc = -EAFNOSUPPORT;
219 if (addr->sin_family != AF_INET &&
220 addr->sin_family != AF_INET6 &&
221 addr->sin_family != AF_UNSPEC)
222 goto out;
203 /* accept AF_UNSPEC (mapped to AF_INET) only if s_addr is INADDR_ANY */ 223 /* accept AF_UNSPEC (mapped to AF_INET) only if s_addr is INADDR_ANY */
204 if ((addr->sin_family != AF_INET) && 224 if (addr->sin_family == AF_UNSPEC &&
205 ((addr->sin_family != AF_UNSPEC) || 225 addr->sin_addr.s_addr != htonl(INADDR_ANY))
206 (addr->sin_addr.s_addr != htonl(INADDR_ANY))))
207 goto out; 226 goto out;
208 227
209 lock_sock(sk); 228 lock_sock(sk);
@@ -273,47 +292,7 @@ static void smc_copy_sock_settings_to_smc(struct smc_sock *smc)
273 smc_copy_sock_settings(&smc->sk, smc->clcsock->sk, SK_FLAGS_CLC_TO_SMC); 292 smc_copy_sock_settings(&smc->sk, smc->clcsock->sk, SK_FLAGS_CLC_TO_SMC);
274} 293}
275 294
276/* determine subnet and mask of internal TCP socket */ 295static int smc_clnt_conf_first_link(struct smc_sock *smc)
277int smc_netinfo_by_tcpsk(struct socket *clcsock,
278 __be32 *subnet, u8 *prefix_len)
279{
280 struct dst_entry *dst = sk_dst_get(clcsock->sk);
281 struct in_device *in_dev;
282 struct sockaddr_in addr;
283 int rc = -ENOENT;
284 int len;
285
286 if (!dst) {
287 rc = -ENOTCONN;
288 goto out;
289 }
290 if (!dst->dev) {
291 rc = -ENODEV;
292 goto out_rel;
293 }
294
295 /* get address to which the internal TCP socket is bound */
296 kernel_getsockname(clcsock, (struct sockaddr *)&addr, &len);
297 /* analyze IPv4 specific data of net_device belonging to TCP socket */
298 rcu_read_lock();
299 in_dev = __in_dev_get_rcu(dst->dev);
300 for_ifa(in_dev) {
301 if (!inet_ifa_match(addr.sin_addr.s_addr, ifa))
302 continue;
303 *prefix_len = inet_mask_len(ifa->ifa_mask);
304 *subnet = ifa->ifa_address & ifa->ifa_mask;
305 rc = 0;
306 break;
307 } endfor_ifa(in_dev);
308 rcu_read_unlock();
309
310out_rel:
311 dst_release(dst);
312out:
313 return rc;
314}
315
316static int smc_clnt_conf_first_link(struct smc_sock *smc, union ib_gid *gid)
317{ 296{
318 struct smc_link_group *lgr = smc->conn.lgr; 297 struct smc_link_group *lgr = smc->conn.lgr;
319 struct smc_link *link; 298 struct smc_link *link;
@@ -333,6 +312,9 @@ static int smc_clnt_conf_first_link(struct smc_sock *smc, union ib_gid *gid)
333 return rc; 312 return rc;
334 } 313 }
335 314
315 if (link->llc_confirm_rc)
316 return SMC_CLC_DECL_RMBE_EC;
317
336 rc = smc_ib_modify_qp_rts(link); 318 rc = smc_ib_modify_qp_rts(link);
337 if (rc) 319 if (rc)
338 return SMC_CLC_DECL_INTERR; 320 return SMC_CLC_DECL_INTERR;
@@ -347,11 +329,33 @@ static int smc_clnt_conf_first_link(struct smc_sock *smc, union ib_gid *gid)
347 /* send CONFIRM LINK response over RoCE fabric */ 329 /* send CONFIRM LINK response over RoCE fabric */
348 rc = smc_llc_send_confirm_link(link, 330 rc = smc_llc_send_confirm_link(link,
349 link->smcibdev->mac[link->ibport - 1], 331 link->smcibdev->mac[link->ibport - 1],
350 gid, SMC_LLC_RESP); 332 &link->smcibdev->gid[link->ibport - 1],
333 SMC_LLC_RESP);
351 if (rc < 0) 334 if (rc < 0)
352 return SMC_CLC_DECL_TCL; 335 return SMC_CLC_DECL_TCL;
353 336
354 return rc; 337 /* receive ADD LINK request from server over RoCE fabric */
338 rest = wait_for_completion_interruptible_timeout(&link->llc_add,
339 SMC_LLC_WAIT_TIME);
340 if (rest <= 0) {
341 struct smc_clc_msg_decline dclc;
342
343 rc = smc_clc_wait_msg(smc, &dclc, sizeof(dclc),
344 SMC_CLC_DECLINE);
345 return rc;
346 }
347
348 /* send add link reject message, only one link supported for now */
349 rc = smc_llc_send_add_link(link,
350 link->smcibdev->mac[link->ibport - 1],
351 &link->smcibdev->gid[link->ibport - 1],
352 SMC_LLC_RESP);
353 if (rc < 0)
354 return SMC_CLC_DECL_TCL;
355
356 link->state = SMC_LNK_ACTIVE;
357
358 return 0;
355} 359}
356 360
357static void smc_conn_save_peer_info(struct smc_sock *smc, 361static void smc_conn_save_peer_info(struct smc_sock *smc,
@@ -373,19 +377,9 @@ static void smc_link_save_peer_info(struct smc_link *link,
373 link->peer_mtu = clc->qp_mtu; 377 link->peer_mtu = clc->qp_mtu;
374} 378}
375 379
376static void smc_lgr_forget(struct smc_link_group *lgr)
377{
378 spin_lock_bh(&smc_lgr_list.lock);
379 /* do not use this link group for new connections */
380 if (!list_empty(&lgr->list))
381 list_del_init(&lgr->list);
382 spin_unlock_bh(&smc_lgr_list.lock);
383}
384
385/* setup for RDMA connection of client */ 380/* setup for RDMA connection of client */
386static int smc_connect_rdma(struct smc_sock *smc) 381static int smc_connect_rdma(struct smc_sock *smc)
387{ 382{
388 struct sockaddr_in *inaddr = (struct sockaddr_in *)smc->addr;
389 struct smc_clc_msg_accept_confirm aclc; 383 struct smc_clc_msg_accept_confirm aclc;
390 int local_contact = SMC_FIRST_CONTACT; 384 int local_contact = SMC_FIRST_CONTACT;
391 struct smc_ib_device *smcibdev; 385 struct smc_ib_device *smcibdev;
@@ -439,8 +433,8 @@ static int smc_connect_rdma(struct smc_sock *smc)
439 433
440 srv_first_contact = aclc.hdr.flag; 434 srv_first_contact = aclc.hdr.flag;
441 mutex_lock(&smc_create_lgr_pending); 435 mutex_lock(&smc_create_lgr_pending);
442 local_contact = smc_conn_create(smc, inaddr->sin_addr.s_addr, smcibdev, 436 local_contact = smc_conn_create(smc, smcibdev, ibport, &aclc.lcl,
443 ibport, &aclc.lcl, srv_first_contact); 437 srv_first_contact);
444 if (local_contact < 0) { 438 if (local_contact < 0) {
445 rc = local_contact; 439 rc = local_contact;
446 if (rc == -ENOMEM) 440 if (rc == -ENOMEM)
@@ -499,8 +493,7 @@ static int smc_connect_rdma(struct smc_sock *smc)
499 493
500 if (local_contact == SMC_FIRST_CONTACT) { 494 if (local_contact == SMC_FIRST_CONTACT) {
501 /* QP confirmation over RoCE fabric */ 495 /* QP confirmation over RoCE fabric */
502 reason_code = smc_clnt_conf_first_link( 496 reason_code = smc_clnt_conf_first_link(smc);
503 smc, &smcibdev->gid[ibport - 1]);
504 if (reason_code < 0) { 497 if (reason_code < 0) {
505 rc = reason_code; 498 rc = reason_code;
506 goto out_err_unlock; 499 goto out_err_unlock;
@@ -557,9 +550,8 @@ static int smc_connect(struct socket *sock, struct sockaddr *addr,
557 /* separate smc parameter checking to be safe */ 550 /* separate smc parameter checking to be safe */
558 if (alen < sizeof(addr->sa_family)) 551 if (alen < sizeof(addr->sa_family))
559 goto out_err; 552 goto out_err;
560 if (addr->sa_family != AF_INET) 553 if (addr->sa_family != AF_INET && addr->sa_family != AF_INET6)
561 goto out_err; 554 goto out_err;
562 smc->addr = addr; /* needed for nonblocking connect */
563 555
564 lock_sock(sk); 556 lock_sock(sk);
565 switch (sk->sk_state) { 557 switch (sk->sk_state) {
@@ -600,7 +592,7 @@ static int smc_clcsock_accept(struct smc_sock *lsmc, struct smc_sock **new_smc)
600 int rc; 592 int rc;
601 593
602 release_sock(lsk); 594 release_sock(lsk);
603 new_sk = smc_sock_alloc(sock_net(lsk), NULL); 595 new_sk = smc_sock_alloc(sock_net(lsk), NULL, lsk->sk_protocol);
604 if (!new_sk) { 596 if (!new_sk) {
605 rc = -ENOMEM; 597 rc = -ENOMEM;
606 lsk->sk_err = ENOMEM; 598 lsk->sk_err = ENOMEM;
@@ -749,9 +741,34 @@ static int smc_serv_conf_first_link(struct smc_sock *smc)
749 741
750 rc = smc_clc_wait_msg(smc, &dclc, sizeof(dclc), 742 rc = smc_clc_wait_msg(smc, &dclc, sizeof(dclc),
751 SMC_CLC_DECLINE); 743 SMC_CLC_DECLINE);
744 return rc;
752 } 745 }
753 746
754 return rc; 747 if (link->llc_confirm_resp_rc)
748 return SMC_CLC_DECL_RMBE_EC;
749
750 /* send ADD LINK request to client over the RoCE fabric */
751 rc = smc_llc_send_add_link(link,
752 link->smcibdev->mac[link->ibport - 1],
753 &link->smcibdev->gid[link->ibport - 1],
754 SMC_LLC_REQ);
755 if (rc < 0)
756 return SMC_CLC_DECL_TCL;
757
758 /* receive ADD LINK response from client over the RoCE fabric */
759 rest = wait_for_completion_interruptible_timeout(&link->llc_add_resp,
760 SMC_LLC_WAIT_TIME);
761 if (rest <= 0) {
762 struct smc_clc_msg_decline dclc;
763
764 rc = smc_clc_wait_msg(smc, &dclc, sizeof(dclc),
765 SMC_CLC_DECLINE);
766 return rc;
767 }
768
769 link->state = SMC_LNK_ACTIVE;
770
771 return 0;
755} 772}
756 773
757/* setup for RDMA connection of server */ 774/* setup for RDMA connection of server */
@@ -767,13 +784,10 @@ static void smc_listen_work(struct work_struct *work)
767 struct sock *newsmcsk = &new_smc->sk; 784 struct sock *newsmcsk = &new_smc->sk;
768 struct smc_clc_msg_proposal *pclc; 785 struct smc_clc_msg_proposal *pclc;
769 struct smc_ib_device *smcibdev; 786 struct smc_ib_device *smcibdev;
770 struct sockaddr_in peeraddr;
771 u8 buf[SMC_CLC_MAX_LEN]; 787 u8 buf[SMC_CLC_MAX_LEN];
772 struct smc_link *link; 788 struct smc_link *link;
773 int reason_code = 0; 789 int reason_code = 0;
774 int rc = 0, len; 790 int rc = 0;
775 __be32 subnet;
776 u8 prefix_len;
777 u8 ibport; 791 u8 ibport;
778 792
779 /* check if peer is smc capable */ 793 /* check if peer is smc capable */
@@ -808,28 +822,19 @@ static void smc_listen_work(struct work_struct *work)
808 goto decline_rdma; 822 goto decline_rdma;
809 } 823 }
810 824
811 /* determine subnet and mask from internal TCP socket */
812 rc = smc_netinfo_by_tcpsk(newclcsock, &subnet, &prefix_len);
813 if (rc) {
814 reason_code = SMC_CLC_DECL_CNFERR; /* configuration error */
815 goto decline_rdma;
816 }
817
818 pclc = (struct smc_clc_msg_proposal *)&buf; 825 pclc = (struct smc_clc_msg_proposal *)&buf;
819 pclc_prfx = smc_clc_proposal_get_prefix(pclc); 826 pclc_prfx = smc_clc_proposal_get_prefix(pclc);
820 if (pclc_prfx->outgoing_subnet != subnet || 827
821 pclc_prfx->prefix_len != prefix_len) { 828 rc = smc_clc_prfx_match(newclcsock, pclc_prfx);
829 if (rc) {
822 reason_code = SMC_CLC_DECL_CNFERR; /* configuration error */ 830 reason_code = SMC_CLC_DECL_CNFERR; /* configuration error */
823 goto decline_rdma; 831 goto decline_rdma;
824 } 832 }
825 833
826 /* get address of the peer connected to the internal TCP socket */
827 kernel_getpeername(newclcsock, (struct sockaddr *)&peeraddr, &len);
828
829 /* allocate connection / link group */ 834 /* allocate connection / link group */
830 mutex_lock(&smc_create_lgr_pending); 835 mutex_lock(&smc_create_lgr_pending);
831 local_contact = smc_conn_create(new_smc, peeraddr.sin_addr.s_addr, 836 local_contact = smc_conn_create(new_smc, smcibdev, ibport, &pclc->lcl,
832 smcibdev, ibport, &pclc->lcl, 0); 837 0);
833 if (local_contact < 0) { 838 if (local_contact < 0) {
834 rc = local_contact; 839 rc = local_contact;
835 if (rc == -ENOMEM) 840 if (rc == -ENOMEM)
@@ -1071,7 +1076,7 @@ out:
1071} 1076}
1072 1077
1073static int smc_getname(struct socket *sock, struct sockaddr *addr, 1078static int smc_getname(struct socket *sock, struct sockaddr *addr,
1074 int *len, int peer) 1079 int peer)
1075{ 1080{
1076 struct smc_sock *smc; 1081 struct smc_sock *smc;
1077 1082
@@ -1081,7 +1086,7 @@ static int smc_getname(struct socket *sock, struct sockaddr *addr,
1081 1086
1082 smc = smc_sk(sock->sk); 1087 smc = smc_sk(sock->sk);
1083 1088
1084 return smc->clcsock->ops->getname(smc->clcsock, addr, len, peer); 1089 return smc->clcsock->ops->getname(smc->clcsock, addr, peer);
1085} 1090}
1086 1091
1087static int smc_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) 1092static int smc_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
@@ -1379,6 +1384,7 @@ static const struct proto_ops smc_sock_ops = {
1379static int smc_create(struct net *net, struct socket *sock, int protocol, 1384static int smc_create(struct net *net, struct socket *sock, int protocol,
1380 int kern) 1385 int kern)
1381{ 1386{
1387 int family = (protocol == SMCPROTO_SMC6) ? PF_INET6 : PF_INET;
1382 struct smc_sock *smc; 1388 struct smc_sock *smc;
1383 struct sock *sk; 1389 struct sock *sk;
1384 int rc; 1390 int rc;
@@ -1388,20 +1394,20 @@ static int smc_create(struct net *net, struct socket *sock, int protocol,
1388 goto out; 1394 goto out;
1389 1395
1390 rc = -EPROTONOSUPPORT; 1396 rc = -EPROTONOSUPPORT;
1391 if ((protocol != IPPROTO_IP) && (protocol != IPPROTO_TCP)) 1397 if (protocol != SMCPROTO_SMC && protocol != SMCPROTO_SMC6)
1392 goto out; 1398 goto out;
1393 1399
1394 rc = -ENOBUFS; 1400 rc = -ENOBUFS;
1395 sock->ops = &smc_sock_ops; 1401 sock->ops = &smc_sock_ops;
1396 sk = smc_sock_alloc(net, sock); 1402 sk = smc_sock_alloc(net, sock, protocol);
1397 if (!sk) 1403 if (!sk)
1398 goto out; 1404 goto out;
1399 1405
1400 /* create internal TCP socket for CLC handshake and fallback */ 1406 /* create internal TCP socket for CLC handshake and fallback */
1401 smc = smc_sk(sk); 1407 smc = smc_sk(sk);
1402 smc->use_fallback = false; /* assume rdma capability first */ 1408 smc->use_fallback = false; /* assume rdma capability first */
1403 rc = sock_create_kern(net, PF_INET, SOCK_STREAM, 1409 rc = sock_create_kern(net, family, SOCK_STREAM, IPPROTO_TCP,
1404 IPPROTO_TCP, &smc->clcsock); 1410 &smc->clcsock);
1405 if (rc) { 1411 if (rc) {
1406 sk_common_release(sk); 1412 sk_common_release(sk);
1407 goto out; 1413 goto out;
@@ -1441,16 +1447,23 @@ static int __init smc_init(void)
1441 1447
1442 rc = proto_register(&smc_proto, 1); 1448 rc = proto_register(&smc_proto, 1);
1443 if (rc) { 1449 if (rc) {
1444 pr_err("%s: proto_register fails with %d\n", __func__, rc); 1450 pr_err("%s: proto_register(v4) fails with %d\n", __func__, rc);
1445 goto out_pnet; 1451 goto out_pnet;
1446 } 1452 }
1447 1453
1454 rc = proto_register(&smc_proto6, 1);
1455 if (rc) {
1456 pr_err("%s: proto_register(v6) fails with %d\n", __func__, rc);
1457 goto out_proto;
1458 }
1459
1448 rc = sock_register(&smc_sock_family_ops); 1460 rc = sock_register(&smc_sock_family_ops);
1449 if (rc) { 1461 if (rc) {
1450 pr_err("%s: sock_register fails with %d\n", __func__, rc); 1462 pr_err("%s: sock_register fails with %d\n", __func__, rc);
1451 goto out_proto; 1463 goto out_proto6;
1452 } 1464 }
1453 INIT_HLIST_HEAD(&smc_v4_hashinfo.ht); 1465 INIT_HLIST_HEAD(&smc_v4_hashinfo.ht);
1466 INIT_HLIST_HEAD(&smc_v6_hashinfo.ht);
1454 1467
1455 rc = smc_ib_register_client(); 1468 rc = smc_ib_register_client();
1456 if (rc) { 1469 if (rc) {
@@ -1463,6 +1476,8 @@ static int __init smc_init(void)
1463 1476
1464out_sock: 1477out_sock:
1465 sock_unregister(PF_SMC); 1478 sock_unregister(PF_SMC);
1479out_proto6:
1480 proto_unregister(&smc_proto6);
1466out_proto: 1481out_proto:
1467 proto_unregister(&smc_proto); 1482 proto_unregister(&smc_proto);
1468out_pnet: 1483out_pnet:
@@ -1481,11 +1496,13 @@ static void __exit smc_exit(void)
1481 spin_unlock_bh(&smc_lgr_list.lock); 1496 spin_unlock_bh(&smc_lgr_list.lock);
1482 list_for_each_entry_safe(lgr, lg, &lgr_freeing_list, list) { 1497 list_for_each_entry_safe(lgr, lg, &lgr_freeing_list, list) {
1483 list_del_init(&lgr->list); 1498 list_del_init(&lgr->list);
1499 cancel_delayed_work_sync(&lgr->free_work);
1484 smc_lgr_free(lgr); /* free link group */ 1500 smc_lgr_free(lgr); /* free link group */
1485 } 1501 }
1486 static_branch_disable(&tcp_have_smc); 1502 static_branch_disable(&tcp_have_smc);
1487 smc_ib_unregister_client(); 1503 smc_ib_unregister_client();
1488 sock_unregister(PF_SMC); 1504 sock_unregister(PF_SMC);
1505 proto_unregister(&smc_proto6);
1489 proto_unregister(&smc_proto); 1506 proto_unregister(&smc_proto);
1490 smc_pnet_exit(); 1507 smc_pnet_exit();
1491} 1508}
diff --git a/net/smc/smc.h b/net/smc/smc.h
index 9518986c97b1..e4829a2f46ba 100644
--- a/net/smc/smc.h
+++ b/net/smc/smc.h
@@ -18,11 +18,13 @@
18 18
19#include "smc_ib.h" 19#include "smc_ib.h"
20 20
21#define SMCPROTO_SMC 0 /* SMC protocol */ 21#define SMCPROTO_SMC 0 /* SMC protocol, IPv4 */
22#define SMCPROTO_SMC6 1 /* SMC protocol, IPv6 */
22 23
23#define SMC_MAX_PORTS 2 /* Max # of ports */ 24#define SMC_MAX_PORTS 2 /* Max # of ports */
24 25
25extern struct proto smc_proto; 26extern struct proto smc_proto;
27extern struct proto smc_proto6;
26 28
27#ifdef ATOMIC64_INIT 29#ifdef ATOMIC64_INIT
28#define KERNEL_HAS_ATOMIC64 30#define KERNEL_HAS_ATOMIC64
@@ -172,7 +174,6 @@ struct smc_sock { /* smc sock container */
172 struct sock sk; 174 struct sock sk;
173 struct socket *clcsock; /* internal tcp socket */ 175 struct socket *clcsock; /* internal tcp socket */
174 struct smc_connection conn; /* smc connection */ 176 struct smc_connection conn; /* smc connection */
175 struct sockaddr *addr; /* inet connect address */
176 struct smc_sock *listen_smc; /* listen parent */ 177 struct smc_sock *listen_smc; /* listen parent */
177 struct work_struct tcp_listen_work;/* handle tcp socket accepts */ 178 struct work_struct tcp_listen_work;/* handle tcp socket accepts */
178 struct work_struct smc_listen_work;/* prepare new accept socket */ 179 struct work_struct smc_listen_work;/* prepare new accept socket */
@@ -263,10 +264,8 @@ static inline bool using_ipsec(struct smc_sock *smc)
263 264
264struct smc_clc_msg_local; 265struct smc_clc_msg_local;
265 266
266int smc_netinfo_by_tcpsk(struct socket *clcsock, __be32 *subnet,
267 u8 *prefix_len);
268void smc_conn_free(struct smc_connection *conn); 267void smc_conn_free(struct smc_connection *conn);
269int smc_conn_create(struct smc_sock *smc, __be32 peer_in_addr, 268int smc_conn_create(struct smc_sock *smc,
270 struct smc_ib_device *smcibdev, u8 ibport, 269 struct smc_ib_device *smcibdev, u8 ibport,
271 struct smc_clc_msg_local *lcl, int srv_first_contact); 270 struct smc_clc_msg_local *lcl, int srv_first_contact);
272struct sock *smc_accept_dequeue(struct sock *parent, struct socket *new_sock); 271struct sock *smc_accept_dequeue(struct sock *parent, struct socket *new_sock);
diff --git a/net/smc/smc_clc.c b/net/smc/smc_clc.c
index 8ac51583a063..64fbc3230e6c 100644
--- a/net/smc/smc_clc.c
+++ b/net/smc/smc_clc.c
@@ -5,15 +5,17 @@
5 * CLC (connection layer control) handshake over initial TCP socket to 5 * CLC (connection layer control) handshake over initial TCP socket to
6 * prepare for RDMA traffic 6 * prepare for RDMA traffic
7 * 7 *
8 * Copyright IBM Corp. 2016 8 * Copyright IBM Corp. 2016, 2018
9 * 9 *
10 * Author(s): Ursula Braun <ubraun@linux.vnet.ibm.com> 10 * Author(s): Ursula Braun <ubraun@linux.vnet.ibm.com>
11 */ 11 */
12 12
13#include <linux/in.h> 13#include <linux/in.h>
14#include <linux/inetdevice.h>
14#include <linux/if_ether.h> 15#include <linux/if_ether.h>
15#include <linux/sched/signal.h> 16#include <linux/sched/signal.h>
16 17
18#include <net/addrconf.h>
17#include <net/sock.h> 19#include <net/sock.h>
18#include <net/tcp.h> 20#include <net/tcp.h>
19 21
@@ -22,6 +24,9 @@
22#include "smc_clc.h" 24#include "smc_clc.h"
23#include "smc_ib.h" 25#include "smc_ib.h"
24 26
27/* eye catcher "SMCR" EBCDIC for CLC messages */
28static const char SMC_EYECATCHER[4] = {'\xe2', '\xd4', '\xc3', '\xd9'};
29
25/* check if received message has a correct header length and contains valid 30/* check if received message has a correct header length and contains valid
26 * heading and trailing eyecatchers 31 * heading and trailing eyecatchers
27 */ 32 */
@@ -70,6 +75,172 @@ static bool smc_clc_msg_hdr_valid(struct smc_clc_msg_hdr *clcm)
70 return true; 75 return true;
71} 76}
72 77
78/* find ipv4 addr on device and get the prefix len, fill CLC proposal msg */
79static int smc_clc_prfx_set4_rcu(struct dst_entry *dst, __be32 ipv4,
80 struct smc_clc_msg_proposal_prefix *prop)
81{
82 struct in_device *in_dev = __in_dev_get_rcu(dst->dev);
83
84 if (!in_dev)
85 return -ENODEV;
86 for_ifa(in_dev) {
87 if (!inet_ifa_match(ipv4, ifa))
88 continue;
89 prop->prefix_len = inet_mask_len(ifa->ifa_mask);
90 prop->outgoing_subnet = ifa->ifa_address & ifa->ifa_mask;
91 /* prop->ipv6_prefixes_cnt = 0; already done by memset before */
92 return 0;
93 } endfor_ifa(in_dev);
94 return -ENOENT;
95}
96
97/* fill CLC proposal msg with ipv6 prefixes from device */
98static int smc_clc_prfx_set6_rcu(struct dst_entry *dst,
99 struct smc_clc_msg_proposal_prefix *prop,
100 struct smc_clc_ipv6_prefix *ipv6_prfx)
101{
102#if IS_ENABLED(CONFIG_IPV6)
103 struct inet6_dev *in6_dev = __in6_dev_get(dst->dev);
104 struct inet6_ifaddr *ifa;
105 int cnt = 0;
106
107 if (!in6_dev)
108 return -ENODEV;
109 /* use a maximum of 8 IPv6 prefixes from device */
110 list_for_each_entry(ifa, &in6_dev->addr_list, if_list) {
111 if (ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)
112 continue;
113 ipv6_addr_prefix(&ipv6_prfx[cnt].prefix,
114 &ifa->addr, ifa->prefix_len);
115 ipv6_prfx[cnt].prefix_len = ifa->prefix_len;
116 cnt++;
117 if (cnt == SMC_CLC_MAX_V6_PREFIX)
118 break;
119 }
120 prop->ipv6_prefixes_cnt = cnt;
121 if (cnt)
122 return 0;
123#endif
124 return -ENOENT;
125}
126
127/* retrieve and set prefixes in CLC proposal msg */
128static int smc_clc_prfx_set(struct socket *clcsock,
129 struct smc_clc_msg_proposal_prefix *prop,
130 struct smc_clc_ipv6_prefix *ipv6_prfx)
131{
132 struct dst_entry *dst = sk_dst_get(clcsock->sk);
133 struct sockaddr_storage addrs;
134 struct sockaddr_in6 *addr6;
135 struct sockaddr_in *addr;
136 int rc = -ENOENT;
137
138 memset(prop, 0, sizeof(*prop));
139 if (!dst) {
140 rc = -ENOTCONN;
141 goto out;
142 }
143 if (!dst->dev) {
144 rc = -ENODEV;
145 goto out_rel;
146 }
147 /* get address to which the internal TCP socket is bound */
148 kernel_getsockname(clcsock, (struct sockaddr *)&addrs);
149 /* analyze IP specific data of net_device belonging to TCP socket */
150 addr6 = (struct sockaddr_in6 *)&addrs;
151 rcu_read_lock();
152 if (addrs.ss_family == PF_INET) {
153 /* IPv4 */
154 addr = (struct sockaddr_in *)&addrs;
155 rc = smc_clc_prfx_set4_rcu(dst, addr->sin_addr.s_addr, prop);
156 } else if (ipv6_addr_v4mapped(&addr6->sin6_addr)) {
157 /* mapped IPv4 address - peer is IPv4 only */
158 rc = smc_clc_prfx_set4_rcu(dst, addr6->sin6_addr.s6_addr32[3],
159 prop);
160 } else {
161 /* IPv6 */
162 rc = smc_clc_prfx_set6_rcu(dst, prop, ipv6_prfx);
163 }
164 rcu_read_unlock();
165out_rel:
166 dst_release(dst);
167out:
168 return rc;
169}
170
171/* match ipv4 addrs of dev against addr in CLC proposal */
172static int smc_clc_prfx_match4_rcu(struct net_device *dev,
173 struct smc_clc_msg_proposal_prefix *prop)
174{
175 struct in_device *in_dev = __in_dev_get_rcu(dev);
176
177 if (!in_dev)
178 return -ENODEV;
179 for_ifa(in_dev) {
180 if (prop->prefix_len == inet_mask_len(ifa->ifa_mask) &&
181 inet_ifa_match(prop->outgoing_subnet, ifa))
182 return 0;
183 } endfor_ifa(in_dev);
184
185 return -ENOENT;
186}
187
188/* match ipv6 addrs of dev against addrs in CLC proposal */
189static int smc_clc_prfx_match6_rcu(struct net_device *dev,
190 struct smc_clc_msg_proposal_prefix *prop)
191{
192#if IS_ENABLED(CONFIG_IPV6)
193 struct inet6_dev *in6_dev = __in6_dev_get(dev);
194 struct smc_clc_ipv6_prefix *ipv6_prfx;
195 struct inet6_ifaddr *ifa;
196 int i, max;
197
198 if (!in6_dev)
199 return -ENODEV;
200 /* ipv6 prefix list starts behind smc_clc_msg_proposal_prefix */
201 ipv6_prfx = (struct smc_clc_ipv6_prefix *)((u8 *)prop + sizeof(*prop));
202 max = min_t(u8, prop->ipv6_prefixes_cnt, SMC_CLC_MAX_V6_PREFIX);
203 list_for_each_entry(ifa, &in6_dev->addr_list, if_list) {
204 if (ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)
205 continue;
206 for (i = 0; i < max; i++) {
207 if (ifa->prefix_len == ipv6_prfx[i].prefix_len &&
208 ipv6_prefix_equal(&ifa->addr, &ipv6_prfx[i].prefix,
209 ifa->prefix_len))
210 return 0;
211 }
212 }
213#endif
214 return -ENOENT;
215}
216
217/* check if proposed prefixes match one of our device prefixes */
218int smc_clc_prfx_match(struct socket *clcsock,
219 struct smc_clc_msg_proposal_prefix *prop)
220{
221 struct dst_entry *dst = sk_dst_get(clcsock->sk);
222 int rc;
223
224 if (!dst) {
225 rc = -ENOTCONN;
226 goto out;
227 }
228 if (!dst->dev) {
229 rc = -ENODEV;
230 goto out_rel;
231 }
232 rcu_read_lock();
233 if (!prop->ipv6_prefixes_cnt)
234 rc = smc_clc_prfx_match4_rcu(dst->dev, prop);
235 else
236 rc = smc_clc_prfx_match6_rcu(dst->dev, prop);
237 rcu_read_unlock();
238out_rel:
239 dst_release(dst);
240out:
241 return rc;
242}
243
73/* Wait for data on the tcp-socket, analyze received data 244/* Wait for data on the tcp-socket, analyze received data
74 * Returns: 245 * Returns:
75 * 0 if success and it was not a decline that we received. 246 * 0 if success and it was not a decline that we received.
@@ -189,16 +360,24 @@ int smc_clc_send_proposal(struct smc_sock *smc,
189 struct smc_ib_device *smcibdev, 360 struct smc_ib_device *smcibdev,
190 u8 ibport) 361 u8 ibport)
191{ 362{
363 struct smc_clc_ipv6_prefix ipv6_prfx[SMC_CLC_MAX_V6_PREFIX];
192 struct smc_clc_msg_proposal_prefix pclc_prfx; 364 struct smc_clc_msg_proposal_prefix pclc_prfx;
193 struct smc_clc_msg_proposal pclc; 365 struct smc_clc_msg_proposal pclc;
194 struct smc_clc_msg_trail trl; 366 struct smc_clc_msg_trail trl;
367 int len, i, plen, rc;
195 int reason_code = 0; 368 int reason_code = 0;
196 struct kvec vec[3]; 369 struct kvec vec[4];
197 struct msghdr msg; 370 struct msghdr msg;
198 int len, plen, rc; 371
372 /* retrieve ip prefixes for CLC proposal msg */
373 rc = smc_clc_prfx_set(smc->clcsock, &pclc_prfx, ipv6_prfx);
374 if (rc)
375 return SMC_CLC_DECL_CNFERR; /* configuration error */
199 376
200 /* send SMC Proposal CLC message */ 377 /* send SMC Proposal CLC message */
201 plen = sizeof(pclc) + sizeof(pclc_prfx) + sizeof(trl); 378 plen = sizeof(pclc) + sizeof(pclc_prfx) +
379 (pclc_prfx.ipv6_prefixes_cnt * sizeof(ipv6_prfx[0])) +
380 sizeof(trl);
202 memset(&pclc, 0, sizeof(pclc)); 381 memset(&pclc, 0, sizeof(pclc));
203 memcpy(pclc.hdr.eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER)); 382 memcpy(pclc.hdr.eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER));
204 pclc.hdr.type = SMC_CLC_PROPOSAL; 383 pclc.hdr.type = SMC_CLC_PROPOSAL;
@@ -209,23 +388,22 @@ int smc_clc_send_proposal(struct smc_sock *smc,
209 memcpy(&pclc.lcl.mac, &smcibdev->mac[ibport - 1], ETH_ALEN); 388 memcpy(&pclc.lcl.mac, &smcibdev->mac[ibport - 1], ETH_ALEN);
210 pclc.iparea_offset = htons(0); 389 pclc.iparea_offset = htons(0);
211 390
212 memset(&pclc_prfx, 0, sizeof(pclc_prfx));
213 /* determine subnet and mask from internal TCP socket */
214 rc = smc_netinfo_by_tcpsk(smc->clcsock, &pclc_prfx.outgoing_subnet,
215 &pclc_prfx.prefix_len);
216 if (rc)
217 return SMC_CLC_DECL_CNFERR; /* configuration error */
218 pclc_prfx.ipv6_prefixes_cnt = 0;
219 memcpy(trl.eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER)); 391 memcpy(trl.eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER));
220 memset(&msg, 0, sizeof(msg)); 392 memset(&msg, 0, sizeof(msg));
221 vec[0].iov_base = &pclc; 393 i = 0;
222 vec[0].iov_len = sizeof(pclc); 394 vec[i].iov_base = &pclc;
223 vec[1].iov_base = &pclc_prfx; 395 vec[i++].iov_len = sizeof(pclc);
224 vec[1].iov_len = sizeof(pclc_prfx); 396 vec[i].iov_base = &pclc_prfx;
225 vec[2].iov_base = &trl; 397 vec[i++].iov_len = sizeof(pclc_prfx);
226 vec[2].iov_len = sizeof(trl); 398 if (pclc_prfx.ipv6_prefixes_cnt > 0) {
399 vec[i].iov_base = &ipv6_prfx[0];
400 vec[i++].iov_len = pclc_prfx.ipv6_prefixes_cnt *
401 sizeof(ipv6_prfx[0]);
402 }
403 vec[i].iov_base = &trl;
404 vec[i++].iov_len = sizeof(trl);
227 /* due to the few bytes needed for clc-handshake this cannot block */ 405 /* due to the few bytes needed for clc-handshake this cannot block */
228 len = kernel_sendmsg(smc->clcsock, &msg, vec, 3, plen); 406 len = kernel_sendmsg(smc->clcsock, &msg, vec, i, plen);
229 if (len < sizeof(pclc)) { 407 if (len < sizeof(pclc)) {
230 if (len >= 0) { 408 if (len >= 0) {
231 reason_code = -ENETUNREACH; 409 reason_code = -ENETUNREACH;
diff --git a/net/smc/smc_clc.h b/net/smc/smc_clc.h
index c145a0f36a68..63bf1dc2c1f9 100644
--- a/net/smc/smc_clc.h
+++ b/net/smc/smc_clc.h
@@ -22,9 +22,6 @@
22#define SMC_CLC_CONFIRM 0x03 22#define SMC_CLC_CONFIRM 0x03
23#define SMC_CLC_DECLINE 0x04 23#define SMC_CLC_DECLINE 0x04
24 24
25/* eye catcher "SMCR" EBCDIC for CLC messages */
26static const char SMC_EYECATCHER[4] = {'\xe2', '\xd4', '\xc3', '\xd9'};
27
28#define SMC_CLC_V1 0x1 /* SMC version */ 25#define SMC_CLC_V1 0x1 /* SMC version */
29#define CLC_WAIT_TIME (6 * HZ) /* max. wait time on clcsock */ 26#define CLC_WAIT_TIME (6 * HZ) /* max. wait time on clcsock */
30#define SMC_CLC_DECL_MEM 0x01010000 /* insufficient memory resources */ 27#define SMC_CLC_DECL_MEM 0x01010000 /* insufficient memory resources */
@@ -36,6 +33,7 @@ static const char SMC_EYECATCHER[4] = {'\xe2', '\xd4', '\xc3', '\xd9'};
36#define SMC_CLC_DECL_INTERR 0x99990000 /* internal error */ 33#define SMC_CLC_DECL_INTERR 0x99990000 /* internal error */
37#define SMC_CLC_DECL_TCL 0x02040000 /* timeout w4 QP confirm */ 34#define SMC_CLC_DECL_TCL 0x02040000 /* timeout w4 QP confirm */
38#define SMC_CLC_DECL_SEND 0x07000000 /* sending problem */ 35#define SMC_CLC_DECL_SEND 0x07000000 /* sending problem */
36#define SMC_CLC_DECL_RMBE_EC 0x08000000 /* peer has eyecatcher in RMBE */
39 37
40struct smc_clc_msg_hdr { /* header1 of clc messages */ 38struct smc_clc_msg_hdr { /* header1 of clc messages */
41 u8 eyecatcher[4]; /* eye catcher */ 39 u8 eyecatcher[4]; /* eye catcher */
@@ -62,10 +60,15 @@ struct smc_clc_msg_local { /* header2 of clc messages */
62 u8 mac[6]; /* mac of ib_device port */ 60 u8 mac[6]; /* mac of ib_device port */
63}; 61};
64 62
63#define SMC_CLC_MAX_V6_PREFIX 8
64
65/* Struct would be 4 byte aligned, but it is used in an array that is sent
66 * to peers and must conform to RFC7609, hence we need to use packed here.
67 */
65struct smc_clc_ipv6_prefix { 68struct smc_clc_ipv6_prefix {
66 u8 prefix[4]; 69 struct in6_addr prefix;
67 u8 prefix_len; 70 u8 prefix_len;
68} __packed; 71} __packed; /* format defined in RFC7609 */
69 72
70struct smc_clc_msg_proposal_prefix { /* prefix part of clc proposal message*/ 73struct smc_clc_msg_proposal_prefix { /* prefix part of clc proposal message*/
71 __be32 outgoing_subnet; /* subnet mask */ 74 __be32 outgoing_subnet; /* subnet mask */
@@ -81,9 +84,11 @@ struct smc_clc_msg_proposal { /* clc proposal message sent by Linux */
81} __aligned(4); 84} __aligned(4);
82 85
83#define SMC_CLC_PROPOSAL_MAX_OFFSET 0x28 86#define SMC_CLC_PROPOSAL_MAX_OFFSET 0x28
84#define SMC_CLC_PROPOSAL_MAX_PREFIX (8 * sizeof(struct smc_clc_ipv6_prefix)) 87#define SMC_CLC_PROPOSAL_MAX_PREFIX (SMC_CLC_MAX_V6_PREFIX * \
88 sizeof(struct smc_clc_ipv6_prefix))
85#define SMC_CLC_MAX_LEN (sizeof(struct smc_clc_msg_proposal) + \ 89#define SMC_CLC_MAX_LEN (sizeof(struct smc_clc_msg_proposal) + \
86 SMC_CLC_PROPOSAL_MAX_OFFSET + \ 90 SMC_CLC_PROPOSAL_MAX_OFFSET + \
91 sizeof(struct smc_clc_msg_proposal_prefix) + \
87 SMC_CLC_PROPOSAL_MAX_PREFIX + \ 92 SMC_CLC_PROPOSAL_MAX_PREFIX + \
88 sizeof(struct smc_clc_msg_trail)) 93 sizeof(struct smc_clc_msg_trail))
89 94
@@ -124,9 +129,8 @@ smc_clc_proposal_get_prefix(struct smc_clc_msg_proposal *pclc)
124 ((u8 *)pclc + sizeof(*pclc) + ntohs(pclc->iparea_offset)); 129 ((u8 *)pclc + sizeof(*pclc) + ntohs(pclc->iparea_offset));
125} 130}
126 131
127struct smc_sock; 132int smc_clc_prfx_match(struct socket *clcsock,
128struct smc_ib_device; 133 struct smc_clc_msg_proposal_prefix *prop);
129
130int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen, 134int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen,
131 u8 expected_type); 135 u8 expected_type);
132int smc_clc_send_decline(struct smc_sock *smc, u32 peer_diag_info); 136int smc_clc_send_decline(struct smc_sock *smc, u32 peer_diag_info);
diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c
index 645dd226177b..f44f6803f7ff 100644
--- a/net/smc/smc_core.c
+++ b/net/smc/smc_core.c
@@ -32,6 +32,17 @@
32 32
33static u32 smc_lgr_num; /* unique link group number */ 33static u32 smc_lgr_num; /* unique link group number */
34 34
35static void smc_lgr_schedule_free_work(struct smc_link_group *lgr)
36{
37 /* client link group creation always follows the server link group
38 * creation. For client use a somewhat higher removal delay time,
39 * otherwise there is a risk of out-of-sync link groups.
40 */
41 mod_delayed_work(system_wq, &lgr->free_work,
42 lgr->role == SMC_CLNT ? SMC_LGR_FREE_DELAY_CLNT :
43 SMC_LGR_FREE_DELAY_SERV);
44}
45
35/* Register connection's alert token in our lookup structure. 46/* Register connection's alert token in our lookup structure.
36 * To use rbtrees we have to implement our own insert core. 47 * To use rbtrees we have to implement our own insert core.
37 * Requires @conns_lock 48 * Requires @conns_lock
@@ -111,13 +122,7 @@ static void smc_lgr_unregister_conn(struct smc_connection *conn)
111 write_unlock_bh(&lgr->conns_lock); 122 write_unlock_bh(&lgr->conns_lock);
112 if (!reduced || lgr->conns_num) 123 if (!reduced || lgr->conns_num)
113 return; 124 return;
114 /* client link group creation always follows the server link group 125 smc_lgr_schedule_free_work(lgr);
115 * creation. For client use a somewhat higher removal delay time,
116 * otherwise there is a risk of out-of-sync link groups.
117 */
118 mod_delayed_work(system_wq, &lgr->free_work,
119 lgr->role == SMC_CLNT ? SMC_LGR_FREE_DELAY_CLNT :
120 SMC_LGR_FREE_DELAY_SERV);
121} 126}
122 127
123static void smc_lgr_free_work(struct work_struct *work) 128static void smc_lgr_free_work(struct work_struct *work)
@@ -140,11 +145,12 @@ static void smc_lgr_free_work(struct work_struct *work)
140 list_del_init(&lgr->list); /* remove from smc_lgr_list */ 145 list_del_init(&lgr->list); /* remove from smc_lgr_list */
141free: 146free:
142 spin_unlock_bh(&smc_lgr_list.lock); 147 spin_unlock_bh(&smc_lgr_list.lock);
143 smc_lgr_free(lgr); 148 if (!delayed_work_pending(&lgr->free_work))
149 smc_lgr_free(lgr);
144} 150}
145 151
146/* create a new SMC link group */ 152/* create a new SMC link group */
147static int smc_lgr_create(struct smc_sock *smc, __be32 peer_in_addr, 153static int smc_lgr_create(struct smc_sock *smc,
148 struct smc_ib_device *smcibdev, u8 ibport, 154 struct smc_ib_device *smcibdev, u8 ibport,
149 char *peer_systemid, unsigned short vlan_id) 155 char *peer_systemid, unsigned short vlan_id)
150{ 156{
@@ -161,7 +167,6 @@ static int smc_lgr_create(struct smc_sock *smc, __be32 peer_in_addr,
161 } 167 }
162 lgr->role = smc->listen_smc ? SMC_SERV : SMC_CLNT; 168 lgr->role = smc->listen_smc ? SMC_SERV : SMC_CLNT;
163 lgr->sync_err = false; 169 lgr->sync_err = false;
164 lgr->daddr = peer_in_addr;
165 memcpy(lgr->peer_systemid, peer_systemid, SMC_SYSTEMID_LEN); 170 memcpy(lgr->peer_systemid, peer_systemid, SMC_SYSTEMID_LEN);
166 lgr->vlan_id = vlan_id; 171 lgr->vlan_id = vlan_id;
167 rwlock_init(&lgr->sndbufs_lock); 172 rwlock_init(&lgr->sndbufs_lock);
@@ -177,6 +182,7 @@ static int smc_lgr_create(struct smc_sock *smc, __be32 peer_in_addr,
177 182
178 lnk = &lgr->lnk[SMC_SINGLE_LINK]; 183 lnk = &lgr->lnk[SMC_SINGLE_LINK];
179 /* initialize link */ 184 /* initialize link */
185 lnk->state = SMC_LNK_ACTIVATING;
180 lnk->link_id = SMC_SINGLE_LINK; 186 lnk->link_id = SMC_SINGLE_LINK;
181 lnk->smcibdev = smcibdev; 187 lnk->smcibdev = smcibdev;
182 lnk->ibport = ibport; 188 lnk->ibport = ibport;
@@ -199,6 +205,8 @@ static int smc_lgr_create(struct smc_sock *smc, __be32 peer_in_addr,
199 goto destroy_qp; 205 goto destroy_qp;
200 init_completion(&lnk->llc_confirm); 206 init_completion(&lnk->llc_confirm);
201 init_completion(&lnk->llc_confirm_resp); 207 init_completion(&lnk->llc_confirm_resp);
208 init_completion(&lnk->llc_add);
209 init_completion(&lnk->llc_add_resp);
202 210
203 smc->conn.lgr = lgr; 211 smc->conn.lgr = lgr;
204 rwlock_init(&lgr->conns_lock); 212 rwlock_init(&lgr->conns_lock);
@@ -307,6 +315,15 @@ void smc_lgr_free(struct smc_link_group *lgr)
307 kfree(lgr); 315 kfree(lgr);
308} 316}
309 317
318void smc_lgr_forget(struct smc_link_group *lgr)
319{
320 spin_lock_bh(&smc_lgr_list.lock);
321 /* do not use this link group for new connections */
322 if (!list_empty(&lgr->list))
323 list_del_init(&lgr->list);
324 spin_unlock_bh(&smc_lgr_list.lock);
325}
326
310/* terminate linkgroup abnormally */ 327/* terminate linkgroup abnormally */
311void smc_lgr_terminate(struct smc_link_group *lgr) 328void smc_lgr_terminate(struct smc_link_group *lgr)
312{ 329{
@@ -314,15 +331,7 @@ void smc_lgr_terminate(struct smc_link_group *lgr)
314 struct smc_sock *smc; 331 struct smc_sock *smc;
315 struct rb_node *node; 332 struct rb_node *node;
316 333
317 spin_lock_bh(&smc_lgr_list.lock); 334 smc_lgr_forget(lgr);
318 if (list_empty(&lgr->list)) {
319 /* termination already triggered */
320 spin_unlock_bh(&smc_lgr_list.lock);
321 return;
322 }
323 /* do not use this link group for new connections */
324 list_del_init(&lgr->list);
325 spin_unlock_bh(&smc_lgr_list.lock);
326 335
327 write_lock_bh(&lgr->conns_lock); 336 write_lock_bh(&lgr->conns_lock);
328 node = rb_first(&lgr->conns_all); 337 node = rb_first(&lgr->conns_all);
@@ -340,6 +349,7 @@ void smc_lgr_terminate(struct smc_link_group *lgr)
340 } 349 }
341 write_unlock_bh(&lgr->conns_lock); 350 write_unlock_bh(&lgr->conns_lock);
342 wake_up(&lgr->lnk[SMC_SINGLE_LINK].wr_reg_wait); 351 wake_up(&lgr->lnk[SMC_SINGLE_LINK].wr_reg_wait);
352 smc_lgr_schedule_free_work(lgr);
343} 353}
344 354
345/* Determine vlan of internal TCP socket. 355/* Determine vlan of internal TCP socket.
@@ -401,7 +411,7 @@ static int smc_link_determine_gid(struct smc_link_group *lgr)
401} 411}
402 412
403/* create a new SMC connection (and a new link group if necessary) */ 413/* create a new SMC connection (and a new link group if necessary) */
404int smc_conn_create(struct smc_sock *smc, __be32 peer_in_addr, 414int smc_conn_create(struct smc_sock *smc,
405 struct smc_ib_device *smcibdev, u8 ibport, 415 struct smc_ib_device *smcibdev, u8 ibport,
406 struct smc_clc_msg_local *lcl, int srv_first_contact) 416 struct smc_clc_msg_local *lcl, int srv_first_contact)
407{ 417{
@@ -458,7 +468,7 @@ int smc_conn_create(struct smc_sock *smc, __be32 peer_in_addr,
458 468
459create: 469create:
460 if (local_contact == SMC_FIRST_CONTACT) { 470 if (local_contact == SMC_FIRST_CONTACT) {
461 rc = smc_lgr_create(smc, peer_in_addr, smcibdev, ibport, 471 rc = smc_lgr_create(smc, smcibdev, ibport,
462 lcl->id_for_peer, vlan_id); 472 lcl->id_for_peer, vlan_id);
463 if (rc) 473 if (rc)
464 goto out; 474 goto out;
@@ -699,27 +709,55 @@ static inline int smc_rmb_reserve_rtoken_idx(struct smc_link_group *lgr)
699 return -ENOSPC; 709 return -ENOSPC;
700} 710}
701 711
702/* save rkey and dma_addr received from peer during clc handshake */ 712/* add a new rtoken from peer */
703int smc_rmb_rtoken_handling(struct smc_connection *conn, 713int smc_rtoken_add(struct smc_link_group *lgr, __be64 nw_vaddr, __be32 nw_rkey)
704 struct smc_clc_msg_accept_confirm *clc)
705{ 714{
706 u64 dma_addr = be64_to_cpu(clc->rmb_dma_addr); 715 u64 dma_addr = be64_to_cpu(nw_vaddr);
707 struct smc_link_group *lgr = conn->lgr; 716 u32 rkey = ntohl(nw_rkey);
708 u32 rkey = ntohl(clc->rmb_rkey);
709 int i; 717 int i;
710 718
711 for (i = 0; i < SMC_RMBS_PER_LGR_MAX; i++) { 719 for (i = 0; i < SMC_RMBS_PER_LGR_MAX; i++) {
712 if ((lgr->rtokens[i][SMC_SINGLE_LINK].rkey == rkey) && 720 if ((lgr->rtokens[i][SMC_SINGLE_LINK].rkey == rkey) &&
713 (lgr->rtokens[i][SMC_SINGLE_LINK].dma_addr == dma_addr) && 721 (lgr->rtokens[i][SMC_SINGLE_LINK].dma_addr == dma_addr) &&
714 test_bit(i, lgr->rtokens_used_mask)) { 722 test_bit(i, lgr->rtokens_used_mask)) {
715 conn->rtoken_idx = i; 723 /* already in list */
724 return i;
725 }
726 }
727 i = smc_rmb_reserve_rtoken_idx(lgr);
728 if (i < 0)
729 return i;
730 lgr->rtokens[i][SMC_SINGLE_LINK].rkey = rkey;
731 lgr->rtokens[i][SMC_SINGLE_LINK].dma_addr = dma_addr;
732 return i;
733}
734
735/* delete an rtoken */
736int smc_rtoken_delete(struct smc_link_group *lgr, __be32 nw_rkey)
737{
738 u32 rkey = ntohl(nw_rkey);
739 int i;
740
741 for (i = 0; i < SMC_RMBS_PER_LGR_MAX; i++) {
742 if (lgr->rtokens[i][SMC_SINGLE_LINK].rkey == rkey &&
743 test_bit(i, lgr->rtokens_used_mask)) {
744 lgr->rtokens[i][SMC_SINGLE_LINK].rkey = 0;
745 lgr->rtokens[i][SMC_SINGLE_LINK].dma_addr = 0;
746
747 clear_bit(i, lgr->rtokens_used_mask);
716 return 0; 748 return 0;
717 } 749 }
718 } 750 }
719 conn->rtoken_idx = smc_rmb_reserve_rtoken_idx(lgr); 751 return -ENOENT;
752}
753
754/* save rkey and dma_addr received from peer during clc handshake */
755int smc_rmb_rtoken_handling(struct smc_connection *conn,
756 struct smc_clc_msg_accept_confirm *clc)
757{
758 conn->rtoken_idx = smc_rtoken_add(conn->lgr, clc->rmb_dma_addr,
759 clc->rmb_rkey);
720 if (conn->rtoken_idx < 0) 760 if (conn->rtoken_idx < 0)
721 return conn->rtoken_idx; 761 return conn->rtoken_idx;
722 lgr->rtokens[conn->rtoken_idx][SMC_SINGLE_LINK].rkey = rkey;
723 lgr->rtokens[conn->rtoken_idx][SMC_SINGLE_LINK].dma_addr = dma_addr;
724 return 0; 762 return 0;
725} 763}
diff --git a/net/smc/smc_core.h b/net/smc/smc_core.h
index fe691bf9af91..07e2a393e6d9 100644
--- a/net/smc/smc_core.h
+++ b/net/smc/smc_core.h
@@ -32,6 +32,12 @@ enum smc_lgr_role { /* possible roles of a link group */
32 SMC_SERV /* server */ 32 SMC_SERV /* server */
33}; 33};
34 34
35enum smc_link_state { /* possible states of a link */
36 SMC_LNK_INACTIVE, /* link is inactive */
37 SMC_LNK_ACTIVATING, /* link is being activated */
38 SMC_LNK_ACTIVE /* link is active */
39};
40
35#define SMC_WR_BUF_SIZE 48 /* size of work request buffer */ 41#define SMC_WR_BUF_SIZE 48 /* size of work request buffer */
36 42
37struct smc_wr_buf { 43struct smc_wr_buf {
@@ -87,8 +93,14 @@ struct smc_link {
87 u8 peer_mac[ETH_ALEN]; /* = gid[8:10||13:15] */ 93 u8 peer_mac[ETH_ALEN]; /* = gid[8:10||13:15] */
88 u8 peer_gid[sizeof(union ib_gid)]; /* gid of peer*/ 94 u8 peer_gid[sizeof(union ib_gid)]; /* gid of peer*/
89 u8 link_id; /* unique # within link group */ 95 u8 link_id; /* unique # within link group */
96
97 enum smc_link_state state; /* state of link */
90 struct completion llc_confirm; /* wait for rx of conf link */ 98 struct completion llc_confirm; /* wait for rx of conf link */
91 struct completion llc_confirm_resp; /* wait 4 rx of cnf lnk rsp */ 99 struct completion llc_confirm_resp; /* wait 4 rx of cnf lnk rsp */
100 int llc_confirm_rc; /* rc from confirm link msg */
101 int llc_confirm_resp_rc; /* rc from conf_resp msg */
102 struct completion llc_add; /* wait for rx of add link */
103 struct completion llc_add_resp; /* wait for rx of add link rsp*/
92}; 104};
93 105
94/* For now we just allow one parallel link per link group. The SMC protocol 106/* For now we just allow one parallel link per link group. The SMC protocol
@@ -124,7 +136,6 @@ struct smc_rtoken { /* address/key of remote RMB */
124struct smc_link_group { 136struct smc_link_group {
125 struct list_head list; 137 struct list_head list;
126 enum smc_lgr_role role; /* client or server */ 138 enum smc_lgr_role role; /* client or server */
127 __be32 daddr; /* destination ip address */
128 struct smc_link lnk[SMC_LINKS_PER_LGR_MAX]; /* smc link */ 139 struct smc_link lnk[SMC_LINKS_PER_LGR_MAX]; /* smc link */
129 char peer_systemid[SMC_SYSTEMID_LEN]; 140 char peer_systemid[SMC_SYSTEMID_LEN];
130 /* unique system_id of peer */ 141 /* unique system_id of peer */
@@ -186,10 +197,13 @@ struct smc_sock;
186struct smc_clc_msg_accept_confirm; 197struct smc_clc_msg_accept_confirm;
187 198
188void smc_lgr_free(struct smc_link_group *lgr); 199void smc_lgr_free(struct smc_link_group *lgr);
200void smc_lgr_forget(struct smc_link_group *lgr);
189void smc_lgr_terminate(struct smc_link_group *lgr); 201void smc_lgr_terminate(struct smc_link_group *lgr);
190int smc_buf_create(struct smc_sock *smc); 202int smc_buf_create(struct smc_sock *smc);
191int smc_rmb_rtoken_handling(struct smc_connection *conn, 203int smc_rmb_rtoken_handling(struct smc_connection *conn,
192 struct smc_clc_msg_accept_confirm *clc); 204 struct smc_clc_msg_accept_confirm *clc);
205int smc_rtoken_add(struct smc_link_group *lgr, __be64 nw_vaddr, __be32 nw_rkey);
206int smc_rtoken_delete(struct smc_link_group *lgr, __be32 nw_rkey);
193void smc_sndbuf_sync_sg_for_cpu(struct smc_connection *conn); 207void smc_sndbuf_sync_sg_for_cpu(struct smc_connection *conn);
194void smc_sndbuf_sync_sg_for_device(struct smc_connection *conn); 208void smc_sndbuf_sync_sg_for_device(struct smc_connection *conn);
195void smc_rmb_sync_sg_for_cpu(struct smc_connection *conn); 209void smc_rmb_sync_sg_for_cpu(struct smc_connection *conn);
diff --git a/net/smc/smc_ib.c b/net/smc/smc_ib.c
index 2a8957bd6d38..26df554f7588 100644
--- a/net/smc/smc_ib.c
+++ b/net/smc/smc_ib.c
@@ -23,6 +23,8 @@
23#include "smc_wr.h" 23#include "smc_wr.h"
24#include "smc.h" 24#include "smc.h"
25 25
26#define SMC_MAX_CQE 32766 /* max. # of completion queue elements */
27
26#define SMC_QP_MIN_RNR_TIMER 5 28#define SMC_QP_MIN_RNR_TIMER 5
27#define SMC_QP_TIMEOUT 15 /* 4096 * 2 ** timeout usec */ 29#define SMC_QP_TIMEOUT 15 /* 4096 * 2 ** timeout usec */
28#define SMC_QP_RETRY_CNT 7 /* 7: infinite */ 30#define SMC_QP_RETRY_CNT 7 /* 7: infinite */
@@ -438,9 +440,15 @@ out:
438long smc_ib_setup_per_ibdev(struct smc_ib_device *smcibdev) 440long smc_ib_setup_per_ibdev(struct smc_ib_device *smcibdev)
439{ 441{
440 struct ib_cq_init_attr cqattr = { 442 struct ib_cq_init_attr cqattr = {
441 .cqe = SMC_WR_MAX_CQE, .comp_vector = 0 }; 443 .cqe = SMC_MAX_CQE, .comp_vector = 0 };
444 int cqe_size_order, smc_order;
442 long rc; 445 long rc;
443 446
447 /* the calculated number of cq entries fits to mlx5 cq allocation */
448 cqe_size_order = cache_line_size() == 128 ? 7 : 6;
449 smc_order = MAX_ORDER - cqe_size_order - 1;
450 if (SMC_MAX_CQE + 2 > (0x00000001 << smc_order) * PAGE_SIZE)
451 cqattr.cqe = (0x00000001 << smc_order) * PAGE_SIZE - 2;
444 smcibdev->roce_cq_send = ib_create_cq(smcibdev->ibdev, 452 smcibdev->roce_cq_send = ib_create_cq(smcibdev->ibdev,
445 smc_wr_tx_cq_handler, NULL, 453 smc_wr_tx_cq_handler, NULL,
446 smcibdev, &cqattr); 454 smcibdev, &cqattr);
diff --git a/net/smc/smc_llc.c b/net/smc/smc_llc.c
index b4aa4fcedb96..ea4b21981b4b 100644
--- a/net/smc/smc_llc.c
+++ b/net/smc/smc_llc.c
@@ -4,9 +4,6 @@
4 * 4 *
5 * Link Layer Control (LLC) 5 * Link Layer Control (LLC)
6 * 6 *
7 * For now, we only support the necessary "confirm link" functionality
8 * which happens for the first RoCE link after successful CLC handshake.
9 *
10 * Copyright IBM Corp. 2016 7 * Copyright IBM Corp. 2016
11 * 8 *
12 * Author(s): Klaus Wacker <Klaus.Wacker@de.ibm.com> 9 * Author(s): Klaus Wacker <Klaus.Wacker@de.ibm.com>
@@ -21,6 +18,122 @@
21#include "smc_clc.h" 18#include "smc_clc.h"
22#include "smc_llc.h" 19#include "smc_llc.h"
23 20
21#define SMC_LLC_DATA_LEN 40
22
23struct smc_llc_hdr {
24 struct smc_wr_rx_hdr common;
25 u8 length; /* 44 */
26#if defined(__BIG_ENDIAN_BITFIELD)
27 u8 reserved:4,
28 add_link_rej_rsn:4;
29#elif defined(__LITTLE_ENDIAN_BITFIELD)
30 u8 add_link_rej_rsn:4,
31 reserved:4;
32#endif
33 u8 flags;
34};
35
36#define SMC_LLC_FLAG_NO_RMBE_EYEC 0x03
37
38struct smc_llc_msg_confirm_link { /* type 0x01 */
39 struct smc_llc_hdr hd;
40 u8 sender_mac[ETH_ALEN];
41 u8 sender_gid[SMC_GID_SIZE];
42 u8 sender_qp_num[3];
43 u8 link_num;
44 u8 link_uid[SMC_LGR_ID_SIZE];
45 u8 max_links;
46 u8 reserved[9];
47};
48
49#define SMC_LLC_FLAG_ADD_LNK_REJ 0x40
50#define SMC_LLC_REJ_RSN_NO_ALT_PATH 1
51
52#define SMC_LLC_ADD_LNK_MAX_LINKS 2
53
54struct smc_llc_msg_add_link { /* type 0x02 */
55 struct smc_llc_hdr hd;
56 u8 sender_mac[ETH_ALEN];
57 u8 reserved2[2];
58 u8 sender_gid[SMC_GID_SIZE];
59 u8 sender_qp_num[3];
60 u8 link_num;
61 u8 flags2; /* QP mtu */
62 u8 initial_psn[3];
63 u8 reserved[8];
64};
65
66#define SMC_LLC_FLAG_DEL_LINK_ALL 0x40
67#define SMC_LLC_FLAG_DEL_LINK_ORDERLY 0x20
68
69struct smc_llc_msg_del_link { /* type 0x04 */
70 struct smc_llc_hdr hd;
71 u8 link_num;
72 __be32 reason;
73 u8 reserved[35];
74} __packed; /* format defined in RFC7609 */
75
76struct smc_llc_msg_test_link { /* type 0x07 */
77 struct smc_llc_hdr hd;
78 u8 user_data[16];
79 u8 reserved[24];
80};
81
82struct smc_rmb_rtoken {
83 union {
84 u8 num_rkeys; /* first rtoken byte of CONFIRM LINK msg */
85 /* is actually the num of rtokens, first */
86 /* rtoken is always for the current link */
87 u8 link_id; /* link id of the rtoken */
88 };
89 __be32 rmb_key;
90 __be64 rmb_vaddr;
91} __packed; /* format defined in RFC7609 */
92
93#define SMC_LLC_RKEYS_PER_MSG 3
94
95struct smc_llc_msg_confirm_rkey { /* type 0x06 */
96 struct smc_llc_hdr hd;
97 struct smc_rmb_rtoken rtoken[SMC_LLC_RKEYS_PER_MSG];
98 u8 reserved;
99};
100
101struct smc_llc_msg_confirm_rkey_cont { /* type 0x08 */
102 struct smc_llc_hdr hd;
103 u8 num_rkeys;
104 struct smc_rmb_rtoken rtoken[SMC_LLC_RKEYS_PER_MSG];
105};
106
107#define SMC_LLC_DEL_RKEY_MAX 8
108#define SMC_LLC_FLAG_RKEY_NEG 0x20
109
110struct smc_llc_msg_delete_rkey { /* type 0x09 */
111 struct smc_llc_hdr hd;
112 u8 num_rkeys;
113 u8 err_mask;
114 u8 reserved[2];
115 __be32 rkey[8];
116 u8 reserved2[4];
117};
118
119union smc_llc_msg {
120 struct smc_llc_msg_confirm_link confirm_link;
121 struct smc_llc_msg_add_link add_link;
122 struct smc_llc_msg_del_link delete_link;
123
124 struct smc_llc_msg_confirm_rkey confirm_rkey;
125 struct smc_llc_msg_confirm_rkey_cont confirm_rkey_cont;
126 struct smc_llc_msg_delete_rkey delete_rkey;
127
128 struct smc_llc_msg_test_link test_link;
129 struct {
130 struct smc_llc_hdr hdr;
131 u8 data[SMC_LLC_DATA_LEN];
132 } raw;
133};
134
135#define SMC_LLC_FLAG_RESP 0x80
136
24/********************************** send *************************************/ 137/********************************** send *************************************/
25 138
26struct smc_llc_tx_pend { 139struct smc_llc_tx_pend {
@@ -87,6 +200,7 @@ int smc_llc_send_confirm_link(struct smc_link *link, u8 mac[],
87 memset(confllc, 0, sizeof(*confllc)); 200 memset(confllc, 0, sizeof(*confllc));
88 confllc->hd.common.type = SMC_LLC_CONFIRM_LINK; 201 confllc->hd.common.type = SMC_LLC_CONFIRM_LINK;
89 confllc->hd.length = sizeof(struct smc_llc_msg_confirm_link); 202 confllc->hd.length = sizeof(struct smc_llc_msg_confirm_link);
203 confllc->hd.flags |= SMC_LLC_FLAG_NO_RMBE_EYEC;
90 if (reqresp == SMC_LLC_RESP) 204 if (reqresp == SMC_LLC_RESP)
91 confllc->hd.flags |= SMC_LLC_FLAG_RESP; 205 confllc->hd.flags |= SMC_LLC_FLAG_RESP;
92 memcpy(confllc->sender_mac, mac, ETH_ALEN); 206 memcpy(confllc->sender_mac, mac, ETH_ALEN);
@@ -94,7 +208,104 @@ int smc_llc_send_confirm_link(struct smc_link *link, u8 mac[],
94 hton24(confllc->sender_qp_num, link->roce_qp->qp_num); 208 hton24(confllc->sender_qp_num, link->roce_qp->qp_num);
95 confllc->link_num = link->link_id; 209 confllc->link_num = link->link_id;
96 memcpy(confllc->link_uid, lgr->id, SMC_LGR_ID_SIZE); 210 memcpy(confllc->link_uid, lgr->id, SMC_LGR_ID_SIZE);
97 confllc->max_links = SMC_LINKS_PER_LGR_MAX; 211 confllc->max_links = SMC_LLC_ADD_LNK_MAX_LINKS; /* enforce peer resp. */
212 /* send llc message */
213 rc = smc_wr_tx_send(link, pend);
214 return rc;
215}
216
217/* send ADD LINK request or response */
218int smc_llc_send_add_link(struct smc_link *link, u8 mac[],
219 union ib_gid *gid,
220 enum smc_llc_reqresp reqresp)
221{
222 struct smc_llc_msg_add_link *addllc;
223 struct smc_wr_tx_pend_priv *pend;
224 struct smc_wr_buf *wr_buf;
225 int rc;
226
227 rc = smc_llc_add_pending_send(link, &wr_buf, &pend);
228 if (rc)
229 return rc;
230 addllc = (struct smc_llc_msg_add_link *)wr_buf;
231 memset(addllc, 0, sizeof(*addllc));
232 addllc->hd.common.type = SMC_LLC_ADD_LINK;
233 addllc->hd.length = sizeof(struct smc_llc_msg_add_link);
234 if (reqresp == SMC_LLC_RESP) {
235 addllc->hd.flags |= SMC_LLC_FLAG_RESP;
236 /* always reject more links for now */
237 addllc->hd.flags |= SMC_LLC_FLAG_ADD_LNK_REJ;
238 addllc->hd.add_link_rej_rsn = SMC_LLC_REJ_RSN_NO_ALT_PATH;
239 }
240 memcpy(addllc->sender_mac, mac, ETH_ALEN);
241 memcpy(addllc->sender_gid, gid, SMC_GID_SIZE);
242 /* send llc message */
243 rc = smc_wr_tx_send(link, pend);
244 return rc;
245}
246
247/* send DELETE LINK request or response */
248int smc_llc_send_delete_link(struct smc_link *link,
249 enum smc_llc_reqresp reqresp)
250{
251 struct smc_llc_msg_del_link *delllc;
252 struct smc_wr_tx_pend_priv *pend;
253 struct smc_wr_buf *wr_buf;
254 int rc;
255
256 rc = smc_llc_add_pending_send(link, &wr_buf, &pend);
257 if (rc)
258 return rc;
259 delllc = (struct smc_llc_msg_del_link *)wr_buf;
260 memset(delllc, 0, sizeof(*delllc));
261 delllc->hd.common.type = SMC_LLC_DELETE_LINK;
262 delllc->hd.length = sizeof(struct smc_llc_msg_add_link);
263 if (reqresp == SMC_LLC_RESP)
264 delllc->hd.flags |= SMC_LLC_FLAG_RESP;
265 /* DEL_LINK_ALL because only 1 link supported */
266 delllc->hd.flags |= SMC_LLC_FLAG_DEL_LINK_ALL;
267 delllc->hd.flags |= SMC_LLC_FLAG_DEL_LINK_ORDERLY;
268 delllc->link_num = link->link_id;
269 /* send llc message */
270 rc = smc_wr_tx_send(link, pend);
271 return rc;
272}
273
274/* send LLC test link request or response */
275int smc_llc_send_test_link(struct smc_link *link, u8 user_data[16],
276 enum smc_llc_reqresp reqresp)
277{
278 struct smc_llc_msg_test_link *testllc;
279 struct smc_wr_tx_pend_priv *pend;
280 struct smc_wr_buf *wr_buf;
281 int rc;
282
283 rc = smc_llc_add_pending_send(link, &wr_buf, &pend);
284 if (rc)
285 return rc;
286 testllc = (struct smc_llc_msg_test_link *)wr_buf;
287 memset(testllc, 0, sizeof(*testllc));
288 testllc->hd.common.type = SMC_LLC_TEST_LINK;
289 testllc->hd.length = sizeof(struct smc_llc_msg_test_link);
290 if (reqresp == SMC_LLC_RESP)
291 testllc->hd.flags |= SMC_LLC_FLAG_RESP;
292 memcpy(testllc->user_data, user_data, sizeof(testllc->user_data));
293 /* send llc message */
294 rc = smc_wr_tx_send(link, pend);
295 return rc;
296}
297
298/* send a prepared message */
299static int smc_llc_send_message(struct smc_link *link, void *llcbuf, int llclen)
300{
301 struct smc_wr_tx_pend_priv *pend;
302 struct smc_wr_buf *wr_buf;
303 int rc;
304
305 rc = smc_llc_add_pending_send(link, &wr_buf, &pend);
306 if (rc)
307 return rc;
308 memcpy(wr_buf, llcbuf, llclen);
98 /* send llc message */ 309 /* send llc message */
99 rc = smc_wr_tx_send(link, pend); 310 rc = smc_wr_tx_send(link, pend);
100 return rc; 311 return rc;
@@ -106,19 +317,156 @@ static void smc_llc_rx_confirm_link(struct smc_link *link,
106 struct smc_llc_msg_confirm_link *llc) 317 struct smc_llc_msg_confirm_link *llc)
107{ 318{
108 struct smc_link_group *lgr; 319 struct smc_link_group *lgr;
320 int conf_rc;
109 321
110 lgr = container_of(link, struct smc_link_group, lnk[SMC_SINGLE_LINK]); 322 lgr = container_of(link, struct smc_link_group, lnk[SMC_SINGLE_LINK]);
323
324 /* RMBE eyecatchers are not supported */
325 if (llc->hd.flags & SMC_LLC_FLAG_NO_RMBE_EYEC)
326 conf_rc = 0;
327 else
328 conf_rc = ENOTSUPP;
329
111 if (llc->hd.flags & SMC_LLC_FLAG_RESP) { 330 if (llc->hd.flags & SMC_LLC_FLAG_RESP) {
112 if (lgr->role == SMC_SERV) 331 if (lgr->role == SMC_SERV &&
332 link->state == SMC_LNK_ACTIVATING) {
333 link->llc_confirm_resp_rc = conf_rc;
113 complete(&link->llc_confirm_resp); 334 complete(&link->llc_confirm_resp);
335 }
114 } else { 336 } else {
115 if (lgr->role == SMC_CLNT) { 337 if (lgr->role == SMC_CLNT &&
338 link->state == SMC_LNK_ACTIVATING) {
339 link->llc_confirm_rc = conf_rc;
116 link->link_id = llc->link_num; 340 link->link_id = llc->link_num;
117 complete(&link->llc_confirm); 341 complete(&link->llc_confirm);
118 } 342 }
119 } 343 }
120} 344}
121 345
346static void smc_llc_rx_add_link(struct smc_link *link,
347 struct smc_llc_msg_add_link *llc)
348{
349 struct smc_link_group *lgr = container_of(link, struct smc_link_group,
350 lnk[SMC_SINGLE_LINK]);
351
352 if (llc->hd.flags & SMC_LLC_FLAG_RESP) {
353 if (link->state == SMC_LNK_ACTIVATING)
354 complete(&link->llc_add_resp);
355 } else {
356 if (link->state == SMC_LNK_ACTIVATING) {
357 complete(&link->llc_add);
358 return;
359 }
360
361 if (lgr->role == SMC_SERV) {
362 smc_llc_send_add_link(link,
363 link->smcibdev->mac[link->ibport - 1],
364 &link->smcibdev->gid[link->ibport - 1],
365 SMC_LLC_REQ);
366
367 } else {
368 smc_llc_send_add_link(link,
369 link->smcibdev->mac[link->ibport - 1],
370 &link->smcibdev->gid[link->ibport - 1],
371 SMC_LLC_RESP);
372 }
373 }
374}
375
376static void smc_llc_rx_delete_link(struct smc_link *link,
377 struct smc_llc_msg_del_link *llc)
378{
379 struct smc_link_group *lgr = container_of(link, struct smc_link_group,
380 lnk[SMC_SINGLE_LINK]);
381
382 if (llc->hd.flags & SMC_LLC_FLAG_RESP) {
383 if (lgr->role == SMC_SERV)
384 smc_lgr_terminate(lgr);
385 } else {
386 if (lgr->role == SMC_SERV) {
387 smc_lgr_forget(lgr);
388 smc_llc_send_delete_link(link, SMC_LLC_REQ);
389 } else {
390 smc_llc_send_delete_link(link, SMC_LLC_RESP);
391 smc_lgr_terminate(lgr);
392 }
393 }
394}
395
396static void smc_llc_rx_test_link(struct smc_link *link,
397 struct smc_llc_msg_test_link *llc)
398{
399 if (llc->hd.flags & SMC_LLC_FLAG_RESP) {
400 /* unused as long as we don't send this type of msg */
401 } else {
402 smc_llc_send_test_link(link, llc->user_data, SMC_LLC_RESP);
403 }
404}
405
406static void smc_llc_rx_confirm_rkey(struct smc_link *link,
407 struct smc_llc_msg_confirm_rkey *llc)
408{
409 struct smc_link_group *lgr;
410 int rc;
411
412 lgr = container_of(link, struct smc_link_group, lnk[SMC_SINGLE_LINK]);
413
414 if (llc->hd.flags & SMC_LLC_FLAG_RESP) {
415 /* unused as long as we don't send this type of msg */
416 } else {
417 rc = smc_rtoken_add(lgr,
418 llc->rtoken[0].rmb_vaddr,
419 llc->rtoken[0].rmb_key);
420
421 /* ignore rtokens for other links, we have only one link */
422
423 llc->hd.flags |= SMC_LLC_FLAG_RESP;
424 if (rc < 0)
425 llc->hd.flags |= SMC_LLC_FLAG_RKEY_NEG;
426 smc_llc_send_message(link, (void *)llc, sizeof(*llc));
427 }
428}
429
430static void smc_llc_rx_confirm_rkey_cont(struct smc_link *link,
431 struct smc_llc_msg_confirm_rkey_cont *llc)
432{
433 if (llc->hd.flags & SMC_LLC_FLAG_RESP) {
434 /* unused as long as we don't send this type of msg */
435 } else {
436 /* ignore rtokens for other links, we have only one link */
437 llc->hd.flags |= SMC_LLC_FLAG_RESP;
438 smc_llc_send_message(link, (void *)llc, sizeof(*llc));
439 }
440}
441
442static void smc_llc_rx_delete_rkey(struct smc_link *link,
443 struct smc_llc_msg_delete_rkey *llc)
444{
445 struct smc_link_group *lgr;
446 u8 err_mask = 0;
447 int i, max;
448
449 lgr = container_of(link, struct smc_link_group, lnk[SMC_SINGLE_LINK]);
450
451 if (llc->hd.flags & SMC_LLC_FLAG_RESP) {
452 /* unused as long as we don't send this type of msg */
453 } else {
454 max = min_t(u8, llc->num_rkeys, SMC_LLC_DEL_RKEY_MAX);
455 for (i = 0; i < max; i++) {
456 if (smc_rtoken_delete(lgr, llc->rkey[i]))
457 err_mask |= 1 << (SMC_LLC_DEL_RKEY_MAX - 1 - i);
458 }
459
460 if (err_mask) {
461 llc->hd.flags |= SMC_LLC_FLAG_RKEY_NEG;
462 llc->err_mask = err_mask;
463 }
464
465 llc->hd.flags |= SMC_LLC_FLAG_RESP;
466 smc_llc_send_message(link, (void *)llc, sizeof(*llc));
467 }
468}
469
122static void smc_llc_rx_handler(struct ib_wc *wc, void *buf) 470static void smc_llc_rx_handler(struct ib_wc *wc, void *buf)
123{ 471{
124 struct smc_link *link = (struct smc_link *)wc->qp->qp_context; 472 struct smc_link *link = (struct smc_link *)wc->qp->qp_context;
@@ -128,8 +476,30 @@ static void smc_llc_rx_handler(struct ib_wc *wc, void *buf)
128 return; /* short message */ 476 return; /* short message */
129 if (llc->raw.hdr.length != sizeof(*llc)) 477 if (llc->raw.hdr.length != sizeof(*llc))
130 return; /* invalid message */ 478 return; /* invalid message */
131 if (llc->raw.hdr.common.type == SMC_LLC_CONFIRM_LINK) 479
480 switch (llc->raw.hdr.common.type) {
481 case SMC_LLC_TEST_LINK:
482 smc_llc_rx_test_link(link, &llc->test_link);
483 break;
484 case SMC_LLC_CONFIRM_LINK:
132 smc_llc_rx_confirm_link(link, &llc->confirm_link); 485 smc_llc_rx_confirm_link(link, &llc->confirm_link);
486 break;
487 case SMC_LLC_ADD_LINK:
488 smc_llc_rx_add_link(link, &llc->add_link);
489 break;
490 case SMC_LLC_DELETE_LINK:
491 smc_llc_rx_delete_link(link, &llc->delete_link);
492 break;
493 case SMC_LLC_CONFIRM_RKEY:
494 smc_llc_rx_confirm_rkey(link, &llc->confirm_rkey);
495 break;
496 case SMC_LLC_CONFIRM_RKEY_CONT:
497 smc_llc_rx_confirm_rkey_cont(link, &llc->confirm_rkey_cont);
498 break;
499 case SMC_LLC_DELETE_RKEY:
500 smc_llc_rx_delete_rkey(link, &llc->delete_rkey);
501 break;
502 }
133} 503}
134 504
135/***************************** init, exit, misc ******************************/ 505/***************************** init, exit, misc ******************************/
@@ -140,6 +510,30 @@ static struct smc_wr_rx_handler smc_llc_rx_handlers[] = {
140 .type = SMC_LLC_CONFIRM_LINK 510 .type = SMC_LLC_CONFIRM_LINK
141 }, 511 },
142 { 512 {
513 .handler = smc_llc_rx_handler,
514 .type = SMC_LLC_TEST_LINK
515 },
516 {
517 .handler = smc_llc_rx_handler,
518 .type = SMC_LLC_ADD_LINK
519 },
520 {
521 .handler = smc_llc_rx_handler,
522 .type = SMC_LLC_DELETE_LINK
523 },
524 {
525 .handler = smc_llc_rx_handler,
526 .type = SMC_LLC_CONFIRM_RKEY
527 },
528 {
529 .handler = smc_llc_rx_handler,
530 .type = SMC_LLC_CONFIRM_RKEY_CONT
531 },
532 {
533 .handler = smc_llc_rx_handler,
534 .type = SMC_LLC_DELETE_RKEY
535 },
536 {
143 .handler = NULL, 537 .handler = NULL,
144 } 538 }
145}; 539};
diff --git a/net/smc/smc_llc.h b/net/smc/smc_llc.h
index 51b27ce90dbd..e4a7d5e234d5 100644
--- a/net/smc/smc_llc.h
+++ b/net/smc/smc_llc.h
@@ -18,6 +18,7 @@
18#define SMC_LLC_FLAG_RESP 0x80 18#define SMC_LLC_FLAG_RESP 0x80
19 19
20#define SMC_LLC_WAIT_FIRST_TIME (5 * HZ) 20#define SMC_LLC_WAIT_FIRST_TIME (5 * HZ)
21#define SMC_LLC_WAIT_TIME (2 * HZ)
21 22
22enum smc_llc_reqresp { 23enum smc_llc_reqresp {
23 SMC_LLC_REQ, 24 SMC_LLC_REQ,
@@ -26,39 +27,23 @@ enum smc_llc_reqresp {
26 27
27enum smc_llc_msg_type { 28enum smc_llc_msg_type {
28 SMC_LLC_CONFIRM_LINK = 0x01, 29 SMC_LLC_CONFIRM_LINK = 0x01,
29}; 30 SMC_LLC_ADD_LINK = 0x02,
30 31 SMC_LLC_DELETE_LINK = 0x04,
31#define SMC_LLC_DATA_LEN 40 32 SMC_LLC_CONFIRM_RKEY = 0x06,
32 33 SMC_LLC_TEST_LINK = 0x07,
33struct smc_llc_hdr { 34 SMC_LLC_CONFIRM_RKEY_CONT = 0x08,
34 struct smc_wr_rx_hdr common; 35 SMC_LLC_DELETE_RKEY = 0x09,
35 u8 length; /* 44 */
36 u8 reserved;
37 u8 flags;
38};
39
40struct smc_llc_msg_confirm_link { /* type 0x01 */
41 struct smc_llc_hdr hd;
42 u8 sender_mac[ETH_ALEN];
43 u8 sender_gid[SMC_GID_SIZE];
44 u8 sender_qp_num[3];
45 u8 link_num;
46 u8 link_uid[SMC_LGR_ID_SIZE];
47 u8 max_links;
48 u8 reserved[9];
49};
50
51union smc_llc_msg {
52 struct smc_llc_msg_confirm_link confirm_link;
53 struct {
54 struct smc_llc_hdr hdr;
55 u8 data[SMC_LLC_DATA_LEN];
56 } raw;
57}; 36};
58 37
59/* transmit */ 38/* transmit */
60int smc_llc_send_confirm_link(struct smc_link *lnk, u8 mac[], union ib_gid *gid, 39int smc_llc_send_confirm_link(struct smc_link *lnk, u8 mac[], union ib_gid *gid,
61 enum smc_llc_reqresp reqresp); 40 enum smc_llc_reqresp reqresp);
41int smc_llc_send_add_link(struct smc_link *link, u8 mac[], union ib_gid *gid,
42 enum smc_llc_reqresp reqresp);
43int smc_llc_send_delete_link(struct smc_link *link,
44 enum smc_llc_reqresp reqresp);
45int smc_llc_send_test_link(struct smc_link *lnk, u8 user_data[16],
46 enum smc_llc_reqresp reqresp);
62int smc_llc_init(void) __init; 47int smc_llc_init(void) __init;
63 48
64#endif /* SMC_LLC_H */ 49#endif /* SMC_LLC_H */
diff --git a/net/smc/smc_wr.h b/net/smc/smc_wr.h
index ef0c3494c9cb..210bec3c3ebe 100644
--- a/net/smc/smc_wr.h
+++ b/net/smc/smc_wr.h
@@ -19,7 +19,6 @@
19#include "smc.h" 19#include "smc.h"
20#include "smc_core.h" 20#include "smc_core.h"
21 21
22#define SMC_WR_MAX_CQE 32768 /* max. # of completion queue elements */
23#define SMC_WR_BUF_CNT 16 /* # of ctrl buffers per link */ 22#define SMC_WR_BUF_CNT 16 /* # of ctrl buffers per link */
24 23
25#define SMC_WR_TX_WAIT_FREE_SLOT_TIME (10 * HZ) 24#define SMC_WR_TX_WAIT_FREE_SLOT_TIME (10 * HZ)
diff --git a/net/socket.c b/net/socket.c
index 08847c3b8c39..3d1948d27a25 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -104,7 +104,6 @@
104#include <linux/ipv6_route.h> 104#include <linux/ipv6_route.h>
105#include <linux/route.h> 105#include <linux/route.h>
106#include <linux/sockios.h> 106#include <linux/sockios.h>
107#include <linux/atalk.h>
108#include <net/busy_poll.h> 107#include <net/busy_poll.h>
109#include <linux/errqueue.h> 108#include <linux/errqueue.h>
110 109
@@ -234,7 +233,7 @@ static int move_addr_to_user(struct sockaddr_storage *kaddr, int klen,
234 return __put_user(klen, ulen); 233 return __put_user(klen, ulen);
235} 234}
236 235
237static struct kmem_cache *sock_inode_cachep __read_mostly; 236static struct kmem_cache *sock_inode_cachep __ro_after_init;
238 237
239static struct inode *sock_alloc_inode(struct super_block *sb) 238static struct inode *sock_alloc_inode(struct super_block *sb)
240{ 239{
@@ -991,10 +990,11 @@ static long sock_do_ioctl(struct net *net, struct socket *sock,
991 * what to do with it - that's up to the protocol still. 990 * what to do with it - that's up to the protocol still.
992 */ 991 */
993 992
994static struct ns_common *get_net_ns(struct ns_common *ns) 993struct ns_common *get_net_ns(struct ns_common *ns)
995{ 994{
996 return &get_net(container_of(ns, struct net, ns))->ns; 995 return &get_net(container_of(ns, struct net, ns))->ns;
997} 996}
997EXPORT_SYMBOL_GPL(get_net_ns);
998 998
999static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg) 999static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
1000{ 1000{
@@ -1573,8 +1573,9 @@ SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr,
1573 goto out_fd; 1573 goto out_fd;
1574 1574
1575 if (upeer_sockaddr) { 1575 if (upeer_sockaddr) {
1576 if (newsock->ops->getname(newsock, (struct sockaddr *)&address, 1576 len = newsock->ops->getname(newsock,
1577 &len, 2) < 0) { 1577 (struct sockaddr *)&address, 2);
1578 if (len < 0) {
1578 err = -ECONNABORTED; 1579 err = -ECONNABORTED;
1579 goto out_fd; 1580 goto out_fd;
1580 } 1581 }
@@ -1654,7 +1655,7 @@ SYSCALL_DEFINE3(getsockname, int, fd, struct sockaddr __user *, usockaddr,
1654{ 1655{
1655 struct socket *sock; 1656 struct socket *sock;
1656 struct sockaddr_storage address; 1657 struct sockaddr_storage address;
1657 int len, err, fput_needed; 1658 int err, fput_needed;
1658 1659
1659 sock = sockfd_lookup_light(fd, &err, &fput_needed); 1660 sock = sockfd_lookup_light(fd, &err, &fput_needed);
1660 if (!sock) 1661 if (!sock)
@@ -1664,10 +1665,11 @@ SYSCALL_DEFINE3(getsockname, int, fd, struct sockaddr __user *, usockaddr,
1664 if (err) 1665 if (err)
1665 goto out_put; 1666 goto out_put;
1666 1667
1667 err = sock->ops->getname(sock, (struct sockaddr *)&address, &len, 0); 1668 err = sock->ops->getname(sock, (struct sockaddr *)&address, 0);
1668 if (err) 1669 if (err < 0)
1669 goto out_put; 1670 goto out_put;
1670 err = move_addr_to_user(&address, len, usockaddr, usockaddr_len); 1671 /* "err" is actually length in this case */
1672 err = move_addr_to_user(&address, err, usockaddr, usockaddr_len);
1671 1673
1672out_put: 1674out_put:
1673 fput_light(sock->file, fput_needed); 1675 fput_light(sock->file, fput_needed);
@@ -1685,7 +1687,7 @@ SYSCALL_DEFINE3(getpeername, int, fd, struct sockaddr __user *, usockaddr,
1685{ 1687{
1686 struct socket *sock; 1688 struct socket *sock;
1687 struct sockaddr_storage address; 1689 struct sockaddr_storage address;
1688 int len, err, fput_needed; 1690 int err, fput_needed;
1689 1691
1690 sock = sockfd_lookup_light(fd, &err, &fput_needed); 1692 sock = sockfd_lookup_light(fd, &err, &fput_needed);
1691 if (sock != NULL) { 1693 if (sock != NULL) {
@@ -1695,11 +1697,10 @@ SYSCALL_DEFINE3(getpeername, int, fd, struct sockaddr __user *, usockaddr,
1695 return err; 1697 return err;
1696 } 1698 }
1697 1699
1698 err = 1700 err = sock->ops->getname(sock, (struct sockaddr *)&address, 1);
1699 sock->ops->getname(sock, (struct sockaddr *)&address, &len, 1701 if (err >= 0)
1700 1); 1702 /* "err" is actually length in this case */
1701 if (!err) 1703 err = move_addr_to_user(&address, err, usockaddr,
1702 err = move_addr_to_user(&address, len, usockaddr,
1703 usockaddr_len); 1704 usockaddr_len);
1704 fput_light(sock->file, fput_needed); 1705 fput_light(sock->file, fput_needed);
1705 } 1706 }
@@ -2288,10 +2289,12 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
2288 if (!sock) 2289 if (!sock)
2289 return err; 2290 return err;
2290 2291
2291 err = sock_error(sock->sk); 2292 if (likely(!(flags & MSG_ERRQUEUE))) {
2292 if (err) { 2293 err = sock_error(sock->sk);
2293 datagrams = err; 2294 if (err) {
2294 goto out_put; 2295 datagrams = err;
2296 goto out_put;
2297 }
2295 } 2298 }
2296 2299
2297 entry = mmsg; 2300 entry = mmsg;
@@ -3171,17 +3174,15 @@ int kernel_connect(struct socket *sock, struct sockaddr *addr, int addrlen,
3171} 3174}
3172EXPORT_SYMBOL(kernel_connect); 3175EXPORT_SYMBOL(kernel_connect);
3173 3176
3174int kernel_getsockname(struct socket *sock, struct sockaddr *addr, 3177int kernel_getsockname(struct socket *sock, struct sockaddr *addr)
3175 int *addrlen)
3176{ 3178{
3177 return sock->ops->getname(sock, addr, addrlen, 0); 3179 return sock->ops->getname(sock, addr, 0);
3178} 3180}
3179EXPORT_SYMBOL(kernel_getsockname); 3181EXPORT_SYMBOL(kernel_getsockname);
3180 3182
3181int kernel_getpeername(struct socket *sock, struct sockaddr *addr, 3183int kernel_getpeername(struct socket *sock, struct sockaddr *addr)
3182 int *addrlen)
3183{ 3184{
3184 return sock->ops->getname(sock, addr, addrlen, 1); 3185 return sock->ops->getname(sock, addr, 1);
3185} 3186}
3186EXPORT_SYMBOL(kernel_getpeername); 3187EXPORT_SYMBOL(kernel_getpeername);
3187 3188
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 6e432ecd7f99..806395687bb6 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -1231,7 +1231,7 @@ static const struct sockaddr_in6 rpc_in6addr_loopback = {
1231 * negative errno is returned. 1231 * negative errno is returned.
1232 */ 1232 */
1233static int rpc_sockname(struct net *net, struct sockaddr *sap, size_t salen, 1233static int rpc_sockname(struct net *net, struct sockaddr *sap, size_t salen,
1234 struct sockaddr *buf, int buflen) 1234 struct sockaddr *buf)
1235{ 1235{
1236 struct socket *sock; 1236 struct socket *sock;
1237 int err; 1237 int err;
@@ -1269,7 +1269,7 @@ static int rpc_sockname(struct net *net, struct sockaddr *sap, size_t salen,
1269 goto out_release; 1269 goto out_release;
1270 } 1270 }
1271 1271
1272 err = kernel_getsockname(sock, buf, &buflen); 1272 err = kernel_getsockname(sock, buf);
1273 if (err < 0) { 1273 if (err < 0) {
1274 dprintk("RPC: getsockname failed (%d)\n", err); 1274 dprintk("RPC: getsockname failed (%d)\n", err);
1275 goto out_release; 1275 goto out_release;
@@ -1353,7 +1353,7 @@ int rpc_localaddr(struct rpc_clnt *clnt, struct sockaddr *buf, size_t buflen)
1353 rcu_read_unlock(); 1353 rcu_read_unlock();
1354 1354
1355 rpc_set_port(sap, 0); 1355 rpc_set_port(sap, 0);
1356 err = rpc_sockname(net, sap, salen, buf, buflen); 1356 err = rpc_sockname(net, sap, salen, buf);
1357 put_net(net); 1357 put_net(net);
1358 if (err != 0) 1358 if (err != 0)
1359 /* Couldn't discover local address, return ANYADDR */ 1359 /* Couldn't discover local address, return ANYADDR */
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 943f2a745cd5..08cd951aaeea 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -832,12 +832,13 @@ static struct svc_xprt *svc_tcp_accept(struct svc_xprt *xprt)
832 } 832 }
833 set_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags); 833 set_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags);
834 834
835 err = kernel_getpeername(newsock, sin, &slen); 835 err = kernel_getpeername(newsock, sin);
836 if (err < 0) { 836 if (err < 0) {
837 net_warn_ratelimited("%s: peername failed (err %d)!\n", 837 net_warn_ratelimited("%s: peername failed (err %d)!\n",
838 serv->sv_name, -err); 838 serv->sv_name, -err);
839 goto failed; /* aborted connection or whatever */ 839 goto failed; /* aborted connection or whatever */
840 } 840 }
841 slen = err;
841 842
842 /* Ideally, we would want to reject connections from unauthorized 843 /* Ideally, we would want to reject connections from unauthorized
843 * hosts here, but when we get encryption, the IP of the host won't 844 * hosts here, but when we get encryption, the IP of the host won't
@@ -866,7 +867,8 @@ static struct svc_xprt *svc_tcp_accept(struct svc_xprt *xprt)
866 if (IS_ERR(newsvsk)) 867 if (IS_ERR(newsvsk))
867 goto failed; 868 goto failed;
868 svc_xprt_set_remote(&newsvsk->sk_xprt, sin, slen); 869 svc_xprt_set_remote(&newsvsk->sk_xprt, sin, slen);
869 err = kernel_getsockname(newsock, sin, &slen); 870 err = kernel_getsockname(newsock, sin);
871 slen = err;
870 if (unlikely(err < 0)) { 872 if (unlikely(err < 0)) {
871 dprintk("svc_tcp_accept: kernel_getsockname error %d\n", -err); 873 dprintk("svc_tcp_accept: kernel_getsockname error %d\n", -err);
872 slen = offsetof(struct sockaddr, sa_data); 874 slen = offsetof(struct sockaddr, sa_data);
@@ -1465,7 +1467,8 @@ int svc_addsock(struct svc_serv *serv, const int fd, char *name_return,
1465 err = PTR_ERR(svsk); 1467 err = PTR_ERR(svsk);
1466 goto out; 1468 goto out;
1467 } 1469 }
1468 if (kernel_getsockname(svsk->sk_sock, sin, &salen) == 0) 1470 salen = kernel_getsockname(svsk->sk_sock, sin);
1471 if (salen >= 0)
1469 svc_xprt_set_local(&svsk->sk_xprt, sin, salen); 1472 svc_xprt_set_local(&svsk->sk_xprt, sin, salen);
1470 svc_add_new_perm_xprt(serv, &svsk->sk_xprt); 1473 svc_add_new_perm_xprt(serv, &svsk->sk_xprt);
1471 return svc_one_sock_name(svsk, name_return, len); 1474 return svc_one_sock_name(svsk, name_return, len);
@@ -1539,10 +1542,10 @@ static struct svc_xprt *svc_create_socket(struct svc_serv *serv,
1539 if (error < 0) 1542 if (error < 0)
1540 goto bummer; 1543 goto bummer;
1541 1544
1542 newlen = len; 1545 error = kernel_getsockname(sock, newsin);
1543 error = kernel_getsockname(sock, newsin, &newlen);
1544 if (error < 0) 1546 if (error < 0)
1545 goto bummer; 1547 goto bummer;
1548 newlen = error;
1546 1549
1547 if (protocol == IPPROTO_TCP) { 1550 if (protocol == IPPROTO_TCP) {
1548 if ((error = kernel_listen(sock, 64)) < 0) 1551 if ((error = kernel_listen(sock, 64)) < 0)
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index a6b8c1f8f92a..956e29c1438d 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -1794,10 +1794,9 @@ static void xs_sock_set_reuseport(struct socket *sock)
1794static unsigned short xs_sock_getport(struct socket *sock) 1794static unsigned short xs_sock_getport(struct socket *sock)
1795{ 1795{
1796 struct sockaddr_storage buf; 1796 struct sockaddr_storage buf;
1797 int buflen;
1798 unsigned short port = 0; 1797 unsigned short port = 0;
1799 1798
1800 if (kernel_getsockname(sock, (struct sockaddr *)&buf, &buflen) < 0) 1799 if (kernel_getsockname(sock, (struct sockaddr *)&buf) < 0)
1801 goto out; 1800 goto out;
1802 switch (buf.ss_family) { 1801 switch (buf.ss_family) {
1803 case AF_INET6: 1802 case AF_INET6:
diff --git a/net/sysctl_net.c b/net/sysctl_net.c
index 9aed6fe1bf1a..f424539829b7 100644
--- a/net/sysctl_net.c
+++ b/net/sysctl_net.c
@@ -89,6 +89,7 @@ static void __net_exit sysctl_net_exit(struct net *net)
89static struct pernet_operations sysctl_pernet_ops = { 89static struct pernet_operations sysctl_pernet_ops = {
90 .init = sysctl_net_init, 90 .init = sysctl_net_init,
91 .exit = sysctl_net_exit, 91 .exit = sysctl_net_exit,
92 .async = true,
92}; 93};
93 94
94static struct ctl_table_header *net_header; 95static struct ctl_table_header *net_header;
diff --git a/net/tipc/Kconfig b/net/tipc/Kconfig
index c25a3a149dc4..e450212121d2 100644
--- a/net/tipc/Kconfig
+++ b/net/tipc/Kconfig
@@ -34,3 +34,11 @@ config TIPC_MEDIA_UDP
34 Saying Y here will enable support for running TIPC over IP/UDP 34 Saying Y here will enable support for running TIPC over IP/UDP
35 bool 35 bool
36 default y 36 default y
37
38config TIPC_DIAG
39 tristate "TIPC: socket monitoring interface"
40 depends on TIPC
41 default y
42 ---help---
43 Support for TIPC socket monitoring interface used by ss tool.
44 If unsure, say Y.
diff --git a/net/tipc/Makefile b/net/tipc/Makefile
index 37bb0bfbd936..aca168f2abb1 100644
--- a/net/tipc/Makefile
+++ b/net/tipc/Makefile
@@ -9,8 +9,13 @@ tipc-y += addr.o bcast.o bearer.o \
9 core.o link.o discover.o msg.o \ 9 core.o link.o discover.o msg.o \
10 name_distr.o subscr.o monitor.o name_table.o net.o \ 10 name_distr.o subscr.o monitor.o name_table.o net.o \
11 netlink.o netlink_compat.o node.o socket.o eth_media.o \ 11 netlink.o netlink_compat.o node.o socket.o eth_media.o \
12 server.o socket.o group.o 12 topsrv.o socket.o group.o
13 13
14tipc-$(CONFIG_TIPC_MEDIA_UDP) += udp_media.o 14tipc-$(CONFIG_TIPC_MEDIA_UDP) += udp_media.o
15tipc-$(CONFIG_TIPC_MEDIA_IB) += ib_media.o 15tipc-$(CONFIG_TIPC_MEDIA_IB) += ib_media.o
16tipc-$(CONFIG_SYSCTL) += sysctl.o 16tipc-$(CONFIG_SYSCTL) += sysctl.o
17
18
19obj-$(CONFIG_TIPC_DIAG) += diag.o
20
21tipc_diag-y := diag.o
diff --git a/net/tipc/addr.c b/net/tipc/addr.c
index 48fd3b5a73fb..97cd857d7f43 100644
--- a/net/tipc/addr.c
+++ b/net/tipc/addr.c
@@ -64,23 +64,6 @@ int in_own_node(struct net *net, u32 addr)
64} 64}
65 65
66/** 66/**
67 * addr_domain - convert 2-bit scope value to equivalent message lookup domain
68 *
69 * Needed when address of a named message must be looked up a second time
70 * after a network hop.
71 */
72u32 addr_domain(struct net *net, u32 sc)
73{
74 struct tipc_net *tn = net_generic(net, tipc_net_id);
75
76 if (likely(sc == TIPC_NODE_SCOPE))
77 return tn->own_addr;
78 if (sc == TIPC_CLUSTER_SCOPE)
79 return tipc_cluster_mask(tn->own_addr);
80 return tipc_zone_mask(tn->own_addr);
81}
82
83/**
84 * tipc_addr_domain_valid - validates a network domain address 67 * tipc_addr_domain_valid - validates a network domain address
85 * 68 *
86 * Accepts <Z.C.N>, <Z.C.0>, <Z.0.0>, and <0.0.0>, 69 * Accepts <Z.C.N>, <Z.C.0>, <Z.0.0>, and <0.0.0>,
@@ -124,20 +107,6 @@ int tipc_in_scope(u32 domain, u32 addr)
124 return 0; 107 return 0;
125} 108}
126 109
127/**
128 * tipc_addr_scope - convert message lookup domain to a 2-bit scope value
129 */
130int tipc_addr_scope(u32 domain)
131{
132 if (likely(!domain))
133 return TIPC_ZONE_SCOPE;
134 if (tipc_node(domain))
135 return TIPC_NODE_SCOPE;
136 if (tipc_cluster(domain))
137 return TIPC_CLUSTER_SCOPE;
138 return TIPC_ZONE_SCOPE;
139}
140
141char *tipc_addr_string_fill(char *string, u32 addr) 110char *tipc_addr_string_fill(char *string, u32 addr)
142{ 111{
143 snprintf(string, 16, "<%u.%u.%u>", 112 snprintf(string, 16, "<%u.%u.%u>",
diff --git a/net/tipc/addr.h b/net/tipc/addr.h
index bebb347803ce..2ecf5a5d40dd 100644
--- a/net/tipc/addr.h
+++ b/net/tipc/addr.h
@@ -60,6 +60,16 @@ static inline u32 tipc_cluster_mask(u32 addr)
60 return addr & TIPC_ZONE_CLUSTER_MASK; 60 return addr & TIPC_ZONE_CLUSTER_MASK;
61} 61}
62 62
63static inline int tipc_node2scope(u32 node)
64{
65 return node ? TIPC_NODE_SCOPE : TIPC_CLUSTER_SCOPE;
66}
67
68static inline int tipc_scope2node(struct net *net, int sc)
69{
70 return sc != TIPC_NODE_SCOPE ? 0 : tipc_own_addr(net);
71}
72
63u32 tipc_own_addr(struct net *net); 73u32 tipc_own_addr(struct net *net);
64int in_own_cluster(struct net *net, u32 addr); 74int in_own_cluster(struct net *net, u32 addr);
65int in_own_cluster_exact(struct net *net, u32 addr); 75int in_own_cluster_exact(struct net *net, u32 addr);
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 37892b3909af..f3711176be45 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -574,5 +574,5 @@ void tipc_nlist_purge(struct tipc_nlist *nl)
574{ 574{
575 tipc_dest_list_purge(&nl->list); 575 tipc_dest_list_purge(&nl->list);
576 nl->remote = 0; 576 nl->remote = 0;
577 nl->local = 0; 577 nl->local = false;
578} 578}
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 3e3dce3d4c63..f3d2e83313e1 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -956,11 +956,11 @@ int tipc_nl_bearer_add(struct sk_buff *skb, struct genl_info *info)
956 956
957int __tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info) 957int __tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info)
958{ 958{
959 int err;
960 char *name;
961 struct tipc_bearer *b; 959 struct tipc_bearer *b;
962 struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1]; 960 struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1];
963 struct net *net = sock_net(skb->sk); 961 struct net *net = sock_net(skb->sk);
962 char *name;
963 int err;
964 964
965 if (!info->attrs[TIPC_NLA_BEARER]) 965 if (!info->attrs[TIPC_NLA_BEARER])
966 return -EINVAL; 966 return -EINVAL;
@@ -987,8 +987,10 @@ int __tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info)
987 if (err) 987 if (err)
988 return err; 988 return err;
989 989
990 if (props[TIPC_NLA_PROP_TOL]) 990 if (props[TIPC_NLA_PROP_TOL]) {
991 b->tolerance = nla_get_u32(props[TIPC_NLA_PROP_TOL]); 991 b->tolerance = nla_get_u32(props[TIPC_NLA_PROP_TOL]);
992 tipc_node_apply_tolerance(net, b);
993 }
992 if (props[TIPC_NLA_PROP_PRIO]) 994 if (props[TIPC_NLA_PROP_PRIO])
993 b->priority = nla_get_u32(props[TIPC_NLA_PROP_PRIO]); 995 b->priority = nla_get_u32(props[TIPC_NLA_PROP_PRIO]);
994 if (props[TIPC_NLA_PROP_WIN]) 996 if (props[TIPC_NLA_PROP_WIN])
diff --git a/net/tipc/core.c b/net/tipc/core.c
index 0b982d048fb9..04fd91bb11d7 100644
--- a/net/tipc/core.c
+++ b/net/tipc/core.c
@@ -105,6 +105,7 @@ static struct pernet_operations tipc_net_ops = {
105 .exit = tipc_exit_net, 105 .exit = tipc_exit_net,
106 .id = &tipc_net_id, 106 .id = &tipc_net_id,
107 .size = sizeof(struct tipc_net), 107 .size = sizeof(struct tipc_net),
108 .async = true,
108}; 109};
109 110
110static int __init tipc_init(void) 111static int __init tipc_init(void)
diff --git a/net/tipc/core.h b/net/tipc/core.h
index 20b21af2ff14..347f850dc872 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -64,7 +64,7 @@ struct tipc_bearer;
64struct tipc_bc_base; 64struct tipc_bc_base;
65struct tipc_link; 65struct tipc_link;
66struct tipc_name_table; 66struct tipc_name_table;
67struct tipc_server; 67struct tipc_topsrv;
68struct tipc_monitor; 68struct tipc_monitor;
69 69
70#define TIPC_MOD_VER "2.0.0" 70#define TIPC_MOD_VER "2.0.0"
@@ -112,7 +112,7 @@ struct tipc_net {
112 struct list_head dist_queue; 112 struct list_head dist_queue;
113 113
114 /* Topology subscription server */ 114 /* Topology subscription server */
115 struct tipc_server *topsrv; 115 struct tipc_topsrv *topsrv;
116 atomic_t subscription_count; 116 atomic_t subscription_count;
117}; 117};
118 118
@@ -131,7 +131,12 @@ static inline struct list_head *tipc_nodes(struct net *net)
131 return &tipc_net(net)->node_list; 131 return &tipc_net(net)->node_list;
132} 132}
133 133
134static inline struct tipc_server *tipc_topsrv(struct net *net) 134static inline struct name_table *tipc_name_table(struct net *net)
135{
136 return tipc_net(net)->nametbl;
137}
138
139static inline struct tipc_topsrv *tipc_topsrv(struct net *net)
135{ 140{
136 return tipc_net(net)->topsrv; 141 return tipc_net(net)->topsrv;
137} 142}
diff --git a/net/tipc/diag.c b/net/tipc/diag.c
new file mode 100644
index 000000000000..46d9cd62f781
--- /dev/null
+++ b/net/tipc/diag.c
@@ -0,0 +1,114 @@
1/*
2 * net/tipc/diag.c: TIPC socket diag
3 *
4 * Copyright (c) 2018, Ericsson AB
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the names of the copyright holders nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * Alternatively, this software may be distributed under the terms of the
20 * GNU General Public License ("GPL") version 2 as published by the Free
21 * Software Foundation.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "ASIS"
24 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 */
35
36#include "core.h"
37#include "socket.h"
38#include <linux/sock_diag.h>
39#include <linux/tipc_sockets_diag.h>
40
41static u64 __tipc_diag_gen_cookie(struct sock *sk)
42{
43 u32 res[2];
44
45 sock_diag_save_cookie(sk, res);
46 return *((u64 *)res);
47}
48
49static int __tipc_add_sock_diag(struct sk_buff *skb,
50 struct netlink_callback *cb,
51 struct tipc_sock *tsk)
52{
53 struct tipc_sock_diag_req *req = nlmsg_data(cb->nlh);
54 struct nlmsghdr *nlh;
55 int err;
56
57 nlh = nlmsg_put_answer(skb, cb, SOCK_DIAG_BY_FAMILY, 0,
58 NLM_F_MULTI);
59 if (!nlh)
60 return -EMSGSIZE;
61
62 err = tipc_sk_fill_sock_diag(skb, tsk, req->tidiag_states,
63 __tipc_diag_gen_cookie);
64 if (err)
65 return err;
66
67 nlmsg_end(skb, nlh);
68 return 0;
69}
70
71static int tipc_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
72{
73 return tipc_nl_sk_walk(skb, cb, __tipc_add_sock_diag);
74}
75
76static int tipc_sock_diag_handler_dump(struct sk_buff *skb,
77 struct nlmsghdr *h)
78{
79 int hdrlen = sizeof(struct tipc_sock_diag_req);
80 struct net *net = sock_net(skb->sk);
81
82 if (nlmsg_len(h) < hdrlen)
83 return -EINVAL;
84
85 if (h->nlmsg_flags & NLM_F_DUMP) {
86 struct netlink_dump_control c = {
87 .dump = tipc_diag_dump,
88 };
89 netlink_dump_start(net->diag_nlsk, skb, h, &c);
90 return 0;
91 }
92 return -EOPNOTSUPP;
93}
94
95static const struct sock_diag_handler tipc_sock_diag_handler = {
96 .family = AF_TIPC,
97 .dump = tipc_sock_diag_handler_dump,
98};
99
100static int __init tipc_diag_init(void)
101{
102 return sock_diag_register(&tipc_sock_diag_handler);
103}
104
105static void __exit tipc_diag_exit(void)
106{
107 sock_diag_unregister(&tipc_sock_diag_handler);
108}
109
110module_init(tipc_diag_init);
111module_exit(tipc_diag_exit);
112
113MODULE_LICENSE("Dual BSD/GPL");
114MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_NETLINK, NETLINK_SOCK_DIAG, AF_TIPC);
diff --git a/net/tipc/group.c b/net/tipc/group.c
index 04e516d18054..d7a7befeddd4 100644
--- a/net/tipc/group.c
+++ b/net/tipc/group.c
@@ -37,7 +37,7 @@
37#include "addr.h" 37#include "addr.h"
38#include "group.h" 38#include "group.h"
39#include "bcast.h" 39#include "bcast.h"
40#include "server.h" 40#include "topsrv.h"
41#include "msg.h" 41#include "msg.h"
42#include "socket.h" 42#include "socket.h"
43#include "node.h" 43#include "node.h"
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 2d6b2aed30e0..3c230466804d 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -2126,7 +2126,8 @@ void tipc_link_set_tolerance(struct tipc_link *l, u32 tol,
2126 struct sk_buff_head *xmitq) 2126 struct sk_buff_head *xmitq)
2127{ 2127{
2128 l->tolerance = tol; 2128 l->tolerance = tol;
2129 tipc_link_build_proto_msg(l, STATE_MSG, 0, 0, 0, tol, 0, xmitq); 2129 if (link_is_up(l))
2130 tipc_link_build_proto_msg(l, STATE_MSG, 0, 0, 0, tol, 0, xmitq);
2130} 2131}
2131 2132
2132void tipc_link_set_prio(struct tipc_link *l, u32 prio, 2133void tipc_link_set_prio(struct tipc_link *l, u32 prio,
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index 4e1c6f6450bb..b6c45dccba3d 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -580,7 +580,7 @@ bool tipc_msg_lookup_dest(struct net *net, struct sk_buff *skb, int *err)
580 msg = buf_msg(skb); 580 msg = buf_msg(skb);
581 if (msg_reroute_cnt(msg)) 581 if (msg_reroute_cnt(msg))
582 return false; 582 return false;
583 dnode = addr_domain(net, msg_lookup_scope(msg)); 583 dnode = tipc_scope2node(net, msg_lookup_scope(msg));
584 dport = tipc_nametbl_translate(net, msg_nametype(msg), 584 dport = tipc_nametbl_translate(net, msg_nametype(msg),
585 msg_nameinst(msg), &dnode); 585 msg_nameinst(msg), &dnode);
586 if (!dport) 586 if (!dport)
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c
index 23f8899e0f8c..28d095a7d8bb 100644
--- a/net/tipc/name_distr.c
+++ b/net/tipc/name_distr.c
@@ -56,7 +56,7 @@ static void publ_to_item(struct distr_item *i, struct publication *p)
56 i->type = htonl(p->type); 56 i->type = htonl(p->type);
57 i->lower = htonl(p->lower); 57 i->lower = htonl(p->lower);
58 i->upper = htonl(p->upper); 58 i->upper = htonl(p->upper);
59 i->ref = htonl(p->ref); 59 i->port = htonl(p->port);
60 i->key = htonl(p->key); 60 i->key = htonl(p->key);
61} 61}
62 62
@@ -86,25 +86,25 @@ static struct sk_buff *named_prepare_buf(struct net *net, u32 type, u32 size,
86 */ 86 */
87struct sk_buff *tipc_named_publish(struct net *net, struct publication *publ) 87struct sk_buff *tipc_named_publish(struct net *net, struct publication *publ)
88{ 88{
89 struct tipc_net *tn = net_generic(net, tipc_net_id); 89 struct name_table *nt = tipc_name_table(net);
90 struct sk_buff *buf;
91 struct distr_item *item; 90 struct distr_item *item;
91 struct sk_buff *skb;
92 92
93 list_add_tail_rcu(&publ->local_list, 93 if (publ->scope == TIPC_NODE_SCOPE) {
94 &tn->nametbl->publ_list[publ->scope]); 94 list_add_tail_rcu(&publ->binding_node, &nt->node_scope);
95
96 if (publ->scope == TIPC_NODE_SCOPE)
97 return NULL; 95 return NULL;
96 }
97 list_add_tail_rcu(&publ->binding_node, &nt->cluster_scope);
98 98
99 buf = named_prepare_buf(net, PUBLICATION, ITEM_SIZE, 0); 99 skb = named_prepare_buf(net, PUBLICATION, ITEM_SIZE, 0);
100 if (!buf) { 100 if (!skb) {
101 pr_warn("Publication distribution failure\n"); 101 pr_warn("Publication distribution failure\n");
102 return NULL; 102 return NULL;
103 } 103 }
104 104
105 item = (struct distr_item *)msg_data(buf_msg(buf)); 105 item = (struct distr_item *)msg_data(buf_msg(skb));
106 publ_to_item(item, publ); 106 publ_to_item(item, publ);
107 return buf; 107 return skb;
108} 108}
109 109
110/** 110/**
@@ -115,7 +115,7 @@ struct sk_buff *tipc_named_withdraw(struct net *net, struct publication *publ)
115 struct sk_buff *buf; 115 struct sk_buff *buf;
116 struct distr_item *item; 116 struct distr_item *item;
117 117
118 list_del(&publ->local_list); 118 list_del(&publ->binding_node);
119 119
120 if (publ->scope == TIPC_NODE_SCOPE) 120 if (publ->scope == TIPC_NODE_SCOPE)
121 return NULL; 121 return NULL;
@@ -147,7 +147,7 @@ static void named_distribute(struct net *net, struct sk_buff_head *list,
147 ITEM_SIZE) * ITEM_SIZE; 147 ITEM_SIZE) * ITEM_SIZE;
148 u32 msg_rem = msg_dsz; 148 u32 msg_rem = msg_dsz;
149 149
150 list_for_each_entry(publ, pls, local_list) { 150 list_for_each_entry(publ, pls, binding_node) {
151 /* Prepare next buffer: */ 151 /* Prepare next buffer: */
152 if (!skb) { 152 if (!skb) {
153 skb = named_prepare_buf(net, PUBLICATION, msg_rem, 153 skb = named_prepare_buf(net, PUBLICATION, msg_rem,
@@ -184,16 +184,13 @@ static void named_distribute(struct net *net, struct sk_buff_head *list,
184 */ 184 */
185void tipc_named_node_up(struct net *net, u32 dnode) 185void tipc_named_node_up(struct net *net, u32 dnode)
186{ 186{
187 struct tipc_net *tn = net_generic(net, tipc_net_id); 187 struct name_table *nt = tipc_name_table(net);
188 struct sk_buff_head head; 188 struct sk_buff_head head;
189 189
190 __skb_queue_head_init(&head); 190 __skb_queue_head_init(&head);
191 191
192 rcu_read_lock(); 192 rcu_read_lock();
193 named_distribute(net, &head, dnode, 193 named_distribute(net, &head, dnode, &nt->cluster_scope);
194 &tn->nametbl->publ_list[TIPC_CLUSTER_SCOPE]);
195 named_distribute(net, &head, dnode,
196 &tn->nametbl->publ_list[TIPC_ZONE_SCOPE]);
197 rcu_read_unlock(); 194 rcu_read_unlock();
198 195
199 tipc_node_xmit(net, &head, dnode, 0); 196 tipc_node_xmit(net, &head, dnode, 0);
@@ -212,15 +209,15 @@ static void tipc_publ_purge(struct net *net, struct publication *publ, u32 addr)
212 209
213 spin_lock_bh(&tn->nametbl_lock); 210 spin_lock_bh(&tn->nametbl_lock);
214 p = tipc_nametbl_remove_publ(net, publ->type, publ->lower, 211 p = tipc_nametbl_remove_publ(net, publ->type, publ->lower,
215 publ->node, publ->ref, publ->key); 212 publ->node, publ->port, publ->key);
216 if (p) 213 if (p)
217 tipc_node_unsubscribe(net, &p->nodesub_list, addr); 214 tipc_node_unsubscribe(net, &p->binding_node, addr);
218 spin_unlock_bh(&tn->nametbl_lock); 215 spin_unlock_bh(&tn->nametbl_lock);
219 216
220 if (p != publ) { 217 if (p != publ) {
221 pr_err("Unable to remove publication from failed node\n" 218 pr_err("Unable to remove publication from failed node\n"
222 " (type=%u, lower=%u, node=0x%x, ref=%u, key=%u)\n", 219 " (type=%u, lower=%u, node=0x%x, port=%u, key=%u)\n",
223 publ->type, publ->lower, publ->node, publ->ref, 220 publ->type, publ->lower, publ->node, publ->port,
224 publ->key); 221 publ->key);
225 } 222 }
226 223
@@ -249,7 +246,7 @@ void tipc_publ_notify(struct net *net, struct list_head *nsub_list, u32 addr)
249{ 246{
250 struct publication *publ, *tmp; 247 struct publication *publ, *tmp;
251 248
252 list_for_each_entry_safe(publ, tmp, nsub_list, nodesub_list) 249 list_for_each_entry_safe(publ, tmp, nsub_list, binding_node)
253 tipc_publ_purge(net, publ, addr); 250 tipc_publ_purge(net, publ, addr);
254 tipc_dist_queue_purge(net, addr); 251 tipc_dist_queue_purge(net, addr);
255} 252}
@@ -271,18 +268,18 @@ static bool tipc_update_nametbl(struct net *net, struct distr_item *i,
271 ntohl(i->lower), 268 ntohl(i->lower),
272 ntohl(i->upper), 269 ntohl(i->upper),
273 TIPC_CLUSTER_SCOPE, node, 270 TIPC_CLUSTER_SCOPE, node,
274 ntohl(i->ref), ntohl(i->key)); 271 ntohl(i->port), ntohl(i->key));
275 if (publ) { 272 if (publ) {
276 tipc_node_subscribe(net, &publ->nodesub_list, node); 273 tipc_node_subscribe(net, &publ->binding_node, node);
277 return true; 274 return true;
278 } 275 }
279 } else if (dtype == WITHDRAWAL) { 276 } else if (dtype == WITHDRAWAL) {
280 publ = tipc_nametbl_remove_publ(net, ntohl(i->type), 277 publ = tipc_nametbl_remove_publ(net, ntohl(i->type),
281 ntohl(i->lower), 278 ntohl(i->lower),
282 node, ntohl(i->ref), 279 node, ntohl(i->port),
283 ntohl(i->key)); 280 ntohl(i->key));
284 if (publ) { 281 if (publ) {
285 tipc_node_unsubscribe(net, &publ->nodesub_list, node); 282 tipc_node_unsubscribe(net, &publ->binding_node, node);
286 kfree_rcu(publ, rcu); 283 kfree_rcu(publ, rcu);
287 return true; 284 return true;
288 } 285 }
@@ -382,16 +379,16 @@ void tipc_named_rcv(struct net *net, struct sk_buff_head *inputq)
382 */ 379 */
383void tipc_named_reinit(struct net *net) 380void tipc_named_reinit(struct net *net)
384{ 381{
385 struct tipc_net *tn = net_generic(net, tipc_net_id); 382 struct name_table *nt = tipc_name_table(net);
383 struct tipc_net *tn = tipc_net(net);
386 struct publication *publ; 384 struct publication *publ;
387 int scope;
388 385
389 spin_lock_bh(&tn->nametbl_lock); 386 spin_lock_bh(&tn->nametbl_lock);
390 387
391 for (scope = TIPC_ZONE_SCOPE; scope <= TIPC_NODE_SCOPE; scope++) 388 list_for_each_entry_rcu(publ, &nt->node_scope, binding_node)
392 list_for_each_entry_rcu(publ, &tn->nametbl->publ_list[scope], 389 publ->node = tn->own_addr;
393 local_list) 390 list_for_each_entry_rcu(publ, &nt->cluster_scope, binding_node)
394 publ->node = tn->own_addr; 391 publ->node = tn->own_addr;
395 392
396 spin_unlock_bh(&tn->nametbl_lock); 393 spin_unlock_bh(&tn->nametbl_lock);
397} 394}
diff --git a/net/tipc/name_distr.h b/net/tipc/name_distr.h
index 1264ba0af937..4753e628d7c4 100644
--- a/net/tipc/name_distr.h
+++ b/net/tipc/name_distr.h
@@ -63,7 +63,7 @@ struct distr_item {
63 __be32 type; 63 __be32 type;
64 __be32 lower; 64 __be32 lower;
65 __be32 upper; 65 __be32 upper;
66 __be32 ref; 66 __be32 port;
67 __be32 key; 67 __be32 key;
68}; 68};
69 69
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index ed0457cc99d6..bbbfc0702634 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * net/tipc/name_table.c: TIPC name table code 2 * net/tipc/name_table.c: TIPC name table code
3 * 3 *
4 * Copyright (c) 2000-2006, 2014-2015, Ericsson AB 4 * Copyright (c) 2000-2006, 2014-2018, Ericsson AB
5 * Copyright (c) 2004-2008, 2010-2014, Wind River Systems 5 * Copyright (c) 2004-2008, 2010-2014, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
@@ -50,24 +50,12 @@
50 50
51/** 51/**
52 * struct name_info - name sequence publication info 52 * struct name_info - name sequence publication info
53 * @node_list: circular list of publications made by own node 53 * @node_list: list of publications on own node of this <type,lower,upper>
54 * @cluster_list: circular list of publications made by own cluster 54 * @all_publ: list of all publications of this <type,lower,upper>
55 * @zone_list: circular list of publications made by own zone
56 * @node_list_size: number of entries in "node_list"
57 * @cluster_list_size: number of entries in "cluster_list"
58 * @zone_list_size: number of entries in "zone_list"
59 *
60 * Note: The zone list always contains at least one entry, since all
61 * publications of the associated name sequence belong to it.
62 * (The cluster and node lists may be empty.)
63 */ 55 */
64struct name_info { 56struct name_info {
65 struct list_head node_list; 57 struct list_head local_publ;
66 struct list_head cluster_list; 58 struct list_head all_publ;
67 struct list_head zone_list;
68 u32 node_list_size;
69 u32 cluster_list_size;
70 u32 zone_list_size;
71}; 59};
72 60
73/** 61/**
@@ -114,7 +102,7 @@ static int hash(int x)
114 * publ_create - create a publication structure 102 * publ_create - create a publication structure
115 */ 103 */
116static struct publication *publ_create(u32 type, u32 lower, u32 upper, 104static struct publication *publ_create(u32 type, u32 lower, u32 upper,
117 u32 scope, u32 node, u32 port_ref, 105 u32 scope, u32 node, u32 port,
118 u32 key) 106 u32 key)
119{ 107{
120 struct publication *publ = kzalloc(sizeof(*publ), GFP_ATOMIC); 108 struct publication *publ = kzalloc(sizeof(*publ), GFP_ATOMIC);
@@ -128,9 +116,9 @@ static struct publication *publ_create(u32 type, u32 lower, u32 upper,
128 publ->upper = upper; 116 publ->upper = upper;
129 publ->scope = scope; 117 publ->scope = scope;
130 publ->node = node; 118 publ->node = node;
131 publ->ref = port_ref; 119 publ->port = port;
132 publ->key = key; 120 publ->key = key;
133 INIT_LIST_HEAD(&publ->pport_list); 121 INIT_LIST_HEAD(&publ->binding_sock);
134 return publ; 122 return publ;
135} 123}
136 124
@@ -249,9 +237,9 @@ static struct publication *tipc_nameseq_insert_publ(struct net *net,
249 info = sseq->info; 237 info = sseq->info;
250 238
251 /* Check if an identical publication already exists */ 239 /* Check if an identical publication already exists */
252 list_for_each_entry(publ, &info->zone_list, zone_list) { 240 list_for_each_entry(publ, &info->all_publ, all_publ) {
253 if ((publ->ref == port) && (publ->key == key) && 241 if (publ->port == port && publ->key == key &&
254 (!publ->node || (publ->node == node))) 242 (!publ->node || publ->node == node))
255 return NULL; 243 return NULL;
256 } 244 }
257 } else { 245 } else {
@@ -290,9 +278,8 @@ static struct publication *tipc_nameseq_insert_publ(struct net *net,
290 return NULL; 278 return NULL;
291 } 279 }
292 280
293 INIT_LIST_HEAD(&info->node_list); 281 INIT_LIST_HEAD(&info->local_publ);
294 INIT_LIST_HEAD(&info->cluster_list); 282 INIT_LIST_HEAD(&info->all_publ);
295 INIT_LIST_HEAD(&info->zone_list);
296 283
297 /* Insert new sub-sequence */ 284 /* Insert new sub-sequence */
298 sseq = &nseq->sseqs[inspos]; 285 sseq = &nseq->sseqs[inspos];
@@ -311,25 +298,17 @@ static struct publication *tipc_nameseq_insert_publ(struct net *net,
311 if (!publ) 298 if (!publ)
312 return NULL; 299 return NULL;
313 300
314 list_add(&publ->zone_list, &info->zone_list); 301 list_add(&publ->all_publ, &info->all_publ);
315 info->zone_list_size++;
316 302
317 if (in_own_cluster(net, node)) { 303 if (in_own_node(net, node))
318 list_add(&publ->cluster_list, &info->cluster_list); 304 list_add(&publ->local_publ, &info->local_publ);
319 info->cluster_list_size++;
320 }
321
322 if (in_own_node(net, node)) {
323 list_add(&publ->node_list, &info->node_list);
324 info->node_list_size++;
325 }
326 305
327 /* Any subscriptions waiting for notification? */ 306 /* Any subscriptions waiting for notification? */
328 list_for_each_entry_safe(s, st, &nseq->subscriptions, nameseq_list) { 307 list_for_each_entry_safe(s, st, &nseq->subscriptions, nameseq_list) {
329 tipc_subscrp_report_overlap(s, publ->lower, publ->upper, 308 tipc_sub_report_overlap(s, publ->lower, publ->upper,
330 TIPC_PUBLISHED, publ->ref, 309 TIPC_PUBLISHED, publ->port,
331 publ->node, publ->scope, 310 publ->node, publ->scope,
332 created_subseq); 311 created_subseq);
333 } 312 }
334 return publ; 313 return publ;
335} 314}
@@ -348,7 +327,7 @@ static struct publication *tipc_nameseq_insert_publ(struct net *net,
348static struct publication *tipc_nameseq_remove_publ(struct net *net, 327static struct publication *tipc_nameseq_remove_publ(struct net *net,
349 struct name_seq *nseq, 328 struct name_seq *nseq,
350 u32 inst, u32 node, 329 u32 inst, u32 node,
351 u32 ref, u32 key) 330 u32 port, u32 key)
352{ 331{
353 struct publication *publ; 332 struct publication *publ;
354 struct sub_seq *sseq = nameseq_find_subseq(nseq, inst); 333 struct sub_seq *sseq = nameseq_find_subseq(nseq, inst);
@@ -363,32 +342,20 @@ static struct publication *tipc_nameseq_remove_publ(struct net *net,
363 info = sseq->info; 342 info = sseq->info;
364 343
365 /* Locate publication, if it exists */ 344 /* Locate publication, if it exists */
366 list_for_each_entry(publ, &info->zone_list, zone_list) { 345 list_for_each_entry(publ, &info->all_publ, all_publ) {
367 if ((publ->key == key) && (publ->ref == ref) && 346 if (publ->key == key && publ->port == port &&
368 (!publ->node || (publ->node == node))) 347 (!publ->node || publ->node == node))
369 goto found; 348 goto found;
370 } 349 }
371 return NULL; 350 return NULL;
372 351
373found: 352found:
374 /* Remove publication from zone scope list */ 353 list_del(&publ->all_publ);
375 list_del(&publ->zone_list); 354 if (in_own_node(net, node))
376 info->zone_list_size--; 355 list_del(&publ->local_publ);
377
378 /* Remove publication from cluster scope list, if present */
379 if (in_own_cluster(net, node)) {
380 list_del(&publ->cluster_list);
381 info->cluster_list_size--;
382 }
383
384 /* Remove publication from node scope list, if present */
385 if (in_own_node(net, node)) {
386 list_del(&publ->node_list);
387 info->node_list_size--;
388 }
389 356
390 /* Contract subseq list if no more publications for that subseq */ 357 /* Contract subseq list if no more publications for that subseq */
391 if (list_empty(&info->zone_list)) { 358 if (list_empty(&info->all_publ)) {
392 kfree(info); 359 kfree(info);
393 free = &nseq->sseqs[nseq->first_free--]; 360 free = &nseq->sseqs[nseq->first_free--];
394 memmove(sseq, sseq + 1, (free - (sseq + 1)) * sizeof(*sseq)); 361 memmove(sseq, sseq + 1, (free - (sseq + 1)) * sizeof(*sseq));
@@ -397,10 +364,10 @@ found:
397 364
398 /* Notify any waiting subscriptions */ 365 /* Notify any waiting subscriptions */
399 list_for_each_entry_safe(s, st, &nseq->subscriptions, nameseq_list) { 366 list_for_each_entry_safe(s, st, &nseq->subscriptions, nameseq_list) {
400 tipc_subscrp_report_overlap(s, publ->lower, publ->upper, 367 tipc_sub_report_overlap(s, publ->lower, publ->upper,
401 TIPC_WITHDRAWN, publ->ref, 368 TIPC_WITHDRAWN, publ->port,
402 publ->node, publ->scope, 369 publ->node, publ->scope,
403 removed_subseq); 370 removed_subseq);
404 } 371 }
405 372
406 return publ; 373 return publ;
@@ -412,33 +379,38 @@ found:
412 * sequence overlapping with the requested sequence 379 * sequence overlapping with the requested sequence
413 */ 380 */
414static void tipc_nameseq_subscribe(struct name_seq *nseq, 381static void tipc_nameseq_subscribe(struct name_seq *nseq,
415 struct tipc_subscription *s, 382 struct tipc_subscription *sub)
416 bool status)
417{ 383{
418 struct sub_seq *sseq = nseq->sseqs; 384 struct sub_seq *sseq = nseq->sseqs;
419 struct tipc_name_seq ns; 385 struct tipc_name_seq ns;
386 struct tipc_subscr *s = &sub->evt.s;
387 bool no_status;
420 388
421 tipc_subscrp_convert_seq(&s->evt.s.seq, s->swap, &ns); 389 ns.type = tipc_sub_read(s, seq.type);
390 ns.lower = tipc_sub_read(s, seq.lower);
391 ns.upper = tipc_sub_read(s, seq.upper);
392 no_status = tipc_sub_read(s, filter) & TIPC_SUB_NO_STATUS;
422 393
423 tipc_subscrp_get(s); 394 tipc_sub_get(sub);
424 list_add(&s->nameseq_list, &nseq->subscriptions); 395 list_add(&sub->nameseq_list, &nseq->subscriptions);
425 396
426 if (!status || !sseq) 397 if (no_status || !sseq)
427 return; 398 return;
428 399
429 while (sseq != &nseq->sseqs[nseq->first_free]) { 400 while (sseq != &nseq->sseqs[nseq->first_free]) {
430 if (tipc_subscrp_check_overlap(&ns, sseq->lower, sseq->upper)) { 401 if (tipc_sub_check_overlap(&ns, sseq->lower, sseq->upper)) {
431 struct publication *crs; 402 struct publication *crs;
432 struct name_info *info = sseq->info; 403 struct name_info *info = sseq->info;
433 int must_report = 1; 404 int must_report = 1;
434 405
435 list_for_each_entry(crs, &info->zone_list, zone_list) { 406 list_for_each_entry(crs, &info->all_publ, all_publ) {
436 tipc_subscrp_report_overlap(s, sseq->lower, 407 tipc_sub_report_overlap(sub, sseq->lower,
437 sseq->upper, 408 sseq->upper,
438 TIPC_PUBLISHED, 409 TIPC_PUBLISHED,
439 crs->ref, crs->node, 410 crs->port,
440 crs->scope, 411 crs->node,
441 must_report); 412 crs->scope,
413 must_report);
442 must_report = 0; 414 must_report = 0;
443 } 415 }
444 } 416 }
@@ -470,8 +442,7 @@ struct publication *tipc_nametbl_insert_publ(struct net *net, u32 type,
470 struct name_seq *seq = nametbl_find_seq(net, type); 442 struct name_seq *seq = nametbl_find_seq(net, type);
471 int index = hash(type); 443 int index = hash(type);
472 444
473 if ((scope < TIPC_ZONE_SCOPE) || (scope > TIPC_NODE_SCOPE) || 445 if (scope > TIPC_NODE_SCOPE || lower > upper) {
474 (lower > upper)) {
475 pr_debug("Failed to publish illegal {%u,%u,%u} with scope %u\n", 446 pr_debug("Failed to publish illegal {%u,%u,%u} with scope %u\n",
476 type, lower, upper, scope); 447 type, lower, upper, scope);
477 return NULL; 448 return NULL;
@@ -490,7 +461,7 @@ struct publication *tipc_nametbl_insert_publ(struct net *net, u32 type,
490} 461}
491 462
492struct publication *tipc_nametbl_remove_publ(struct net *net, u32 type, 463struct publication *tipc_nametbl_remove_publ(struct net *net, u32 type,
493 u32 lower, u32 node, u32 ref, 464 u32 lower, u32 node, u32 port,
494 u32 key) 465 u32 key)
495{ 466{
496 struct publication *publ; 467 struct publication *publ;
@@ -500,7 +471,7 @@ struct publication *tipc_nametbl_remove_publ(struct net *net, u32 type,
500 return NULL; 471 return NULL;
501 472
502 spin_lock_bh(&seq->lock); 473 spin_lock_bh(&seq->lock);
503 publ = tipc_nameseq_remove_publ(net, seq, lower, node, ref, key); 474 publ = tipc_nameseq_remove_publ(net, seq, lower, node, port, key);
504 if (!seq->first_free && list_empty(&seq->subscriptions)) { 475 if (!seq->first_free && list_empty(&seq->subscriptions)) {
505 hlist_del_init_rcu(&seq->ns_list); 476 hlist_del_init_rcu(&seq->ns_list);
506 kfree(seq->sseqs); 477 kfree(seq->sseqs);
@@ -533,7 +504,7 @@ u32 tipc_nametbl_translate(struct net *net, u32 type, u32 instance,
533 struct name_info *info; 504 struct name_info *info;
534 struct publication *publ; 505 struct publication *publ;
535 struct name_seq *seq; 506 struct name_seq *seq;
536 u32 ref = 0; 507 u32 port = 0;
537 u32 node = 0; 508 u32 node = 0;
538 509
539 if (!tipc_in_scope(*destnode, tn->own_addr)) 510 if (!tipc_in_scope(*destnode, tn->own_addr))
@@ -551,54 +522,42 @@ u32 tipc_nametbl_translate(struct net *net, u32 type, u32 instance,
551 522
552 /* Closest-First Algorithm */ 523 /* Closest-First Algorithm */
553 if (likely(!*destnode)) { 524 if (likely(!*destnode)) {
554 if (!list_empty(&info->node_list)) { 525 if (!list_empty(&info->local_publ)) {
555 publ = list_first_entry(&info->node_list, 526 publ = list_first_entry(&info->local_publ,
556 struct publication,
557 node_list);
558 list_move_tail(&publ->node_list,
559 &info->node_list);
560 } else if (!list_empty(&info->cluster_list)) {
561 publ = list_first_entry(&info->cluster_list,
562 struct publication, 527 struct publication,
563 cluster_list); 528 local_publ);
564 list_move_tail(&publ->cluster_list, 529 list_move_tail(&publ->local_publ,
565 &info->cluster_list); 530 &info->local_publ);
566 } else { 531 } else {
567 publ = list_first_entry(&info->zone_list, 532 publ = list_first_entry(&info->all_publ,
568 struct publication, 533 struct publication,
569 zone_list); 534 all_publ);
570 list_move_tail(&publ->zone_list, 535 list_move_tail(&publ->all_publ,
571 &info->zone_list); 536 &info->all_publ);
572 } 537 }
573 } 538 }
574 539
575 /* Round-Robin Algorithm */ 540 /* Round-Robin Algorithm */
576 else if (*destnode == tn->own_addr) { 541 else if (*destnode == tn->own_addr) {
577 if (list_empty(&info->node_list)) 542 if (list_empty(&info->local_publ))
578 goto no_match; 543 goto no_match;
579 publ = list_first_entry(&info->node_list, struct publication, 544 publ = list_first_entry(&info->local_publ, struct publication,
580 node_list); 545 local_publ);
581 list_move_tail(&publ->node_list, &info->node_list); 546 list_move_tail(&publ->local_publ, &info->local_publ);
582 } else if (in_own_cluster_exact(net, *destnode)) {
583 if (list_empty(&info->cluster_list))
584 goto no_match;
585 publ = list_first_entry(&info->cluster_list, struct publication,
586 cluster_list);
587 list_move_tail(&publ->cluster_list, &info->cluster_list);
588 } else { 547 } else {
589 publ = list_first_entry(&info->zone_list, struct publication, 548 publ = list_first_entry(&info->all_publ, struct publication,
590 zone_list); 549 all_publ);
591 list_move_tail(&publ->zone_list, &info->zone_list); 550 list_move_tail(&publ->all_publ, &info->all_publ);
592 } 551 }
593 552
594 ref = publ->ref; 553 port = publ->port;
595 node = publ->node; 554 node = publ->node;
596no_match: 555no_match:
597 spin_unlock_bh(&seq->lock); 556 spin_unlock_bh(&seq->lock);
598not_found: 557not_found:
599 rcu_read_unlock(); 558 rcu_read_unlock();
600 *destnode = node; 559 *destnode = node;
601 return ref; 560 return port;
602} 561}
603 562
604bool tipc_nametbl_lookup(struct net *net, u32 type, u32 instance, u32 scope, 563bool tipc_nametbl_lookup(struct net *net, u32 type, u32 instance, u32 scope,
@@ -620,16 +579,16 @@ bool tipc_nametbl_lookup(struct net *net, u32 type, u32 instance, u32 scope,
620 sseq = nameseq_find_subseq(seq, instance); 579 sseq = nameseq_find_subseq(seq, instance);
621 if (likely(sseq)) { 580 if (likely(sseq)) {
622 info = sseq->info; 581 info = sseq->info;
623 list_for_each_entry(publ, &info->zone_list, zone_list) { 582 list_for_each_entry(publ, &info->all_publ, all_publ) {
624 if (publ->scope != scope) 583 if (publ->scope != scope)
625 continue; 584 continue;
626 if (publ->ref == exclude && publ->node == self) 585 if (publ->port == exclude && publ->node == self)
627 continue; 586 continue;
628 tipc_dest_push(dsts, publ->node, publ->ref); 587 tipc_dest_push(dsts, publ->node, publ->port);
629 (*dstcnt)++; 588 (*dstcnt)++;
630 if (all) 589 if (all)
631 continue; 590 continue;
632 list_move_tail(&publ->zone_list, &info->zone_list); 591 list_move_tail(&publ->all_publ, &info->all_publ);
633 break; 592 break;
634 } 593 }
635 } 594 }
@@ -639,15 +598,14 @@ exit:
639 return !list_empty(dsts); 598 return !list_empty(dsts);
640} 599}
641 600
642int tipc_nametbl_mc_lookup(struct net *net, u32 type, u32 lower, u32 upper, 601void tipc_nametbl_mc_lookup(struct net *net, u32 type, u32 lower, u32 upper,
643 u32 scope, bool exact, struct list_head *dports) 602 u32 scope, bool exact, struct list_head *dports)
644{ 603{
645 struct sub_seq *sseq_stop; 604 struct sub_seq *sseq_stop;
646 struct name_info *info; 605 struct name_info *info;
647 struct publication *p; 606 struct publication *p;
648 struct name_seq *seq; 607 struct name_seq *seq;
649 struct sub_seq *sseq; 608 struct sub_seq *sseq;
650 int res = 0;
651 609
652 rcu_read_lock(); 610 rcu_read_lock();
653 seq = nametbl_find_seq(net, type); 611 seq = nametbl_find_seq(net, type);
@@ -661,18 +619,14 @@ int tipc_nametbl_mc_lookup(struct net *net, u32 type, u32 lower, u32 upper,
661 if (sseq->lower > upper) 619 if (sseq->lower > upper)
662 break; 620 break;
663 info = sseq->info; 621 info = sseq->info;
664 list_for_each_entry(p, &info->node_list, node_list) { 622 list_for_each_entry(p, &info->local_publ, local_publ) {
665 if (p->scope == scope || (!exact && p->scope < scope)) 623 if (p->scope == scope || (!exact && p->scope < scope))
666 tipc_dest_push(dports, 0, p->ref); 624 tipc_dest_push(dports, 0, p->port);
667 } 625 }
668
669 if (info->cluster_list_size != info->node_list_size)
670 res = 1;
671 } 626 }
672 spin_unlock_bh(&seq->lock); 627 spin_unlock_bh(&seq->lock);
673exit: 628exit:
674 rcu_read_unlock(); 629 rcu_read_unlock();
675 return res;
676} 630}
677 631
678/* tipc_nametbl_lookup_dst_nodes - find broadcast destination nodes 632/* tipc_nametbl_lookup_dst_nodes - find broadcast destination nodes
@@ -697,7 +651,7 @@ void tipc_nametbl_lookup_dst_nodes(struct net *net, u32 type, u32 lower,
697 stop = seq->sseqs + seq->first_free; 651 stop = seq->sseqs + seq->first_free;
698 for (; sseq != stop && sseq->lower <= upper; sseq++) { 652 for (; sseq != stop && sseq->lower <= upper; sseq++) {
699 info = sseq->info; 653 info = sseq->info;
700 list_for_each_entry(publ, &info->zone_list, zone_list) { 654 list_for_each_entry(publ, &info->all_publ, all_publ) {
701 tipc_nlist_add(nodes, publ->node); 655 tipc_nlist_add(nodes, publ->node);
702 } 656 }
703 } 657 }
@@ -726,10 +680,10 @@ void tipc_nametbl_build_group(struct net *net, struct tipc_group *grp,
726 stop = seq->sseqs + seq->first_free; 680 stop = seq->sseqs + seq->first_free;
727 for (; sseq != stop; sseq++) { 681 for (; sseq != stop; sseq++) {
728 info = sseq->info; 682 info = sseq->info;
729 list_for_each_entry(p, &info->zone_list, zone_list) { 683 list_for_each_entry(p, &info->all_publ, all_publ) {
730 if (p->scope != scope) 684 if (p->scope != scope)
731 continue; 685 continue;
732 tipc_group_add_member(grp, p->node, p->ref, p->lower); 686 tipc_group_add_member(grp, p->node, p->port, p->lower);
733 } 687 }
734 } 688 }
735 spin_unlock_bh(&seq->lock); 689 spin_unlock_bh(&seq->lock);
@@ -774,7 +728,7 @@ struct publication *tipc_nametbl_publish(struct net *net, u32 type, u32 lower,
774/** 728/**
775 * tipc_nametbl_withdraw - withdraw name publication from network name tables 729 * tipc_nametbl_withdraw - withdraw name publication from network name tables
776 */ 730 */
777int tipc_nametbl_withdraw(struct net *net, u32 type, u32 lower, u32 ref, 731int tipc_nametbl_withdraw(struct net *net, u32 type, u32 lower, u32 port,
778 u32 key) 732 u32 key)
779{ 733{
780 struct publication *publ; 734 struct publication *publ;
@@ -783,18 +737,18 @@ int tipc_nametbl_withdraw(struct net *net, u32 type, u32 lower, u32 ref,
783 737
784 spin_lock_bh(&tn->nametbl_lock); 738 spin_lock_bh(&tn->nametbl_lock);
785 publ = tipc_nametbl_remove_publ(net, type, lower, tn->own_addr, 739 publ = tipc_nametbl_remove_publ(net, type, lower, tn->own_addr,
786 ref, key); 740 port, key);
787 if (likely(publ)) { 741 if (likely(publ)) {
788 tn->nametbl->local_publ_count--; 742 tn->nametbl->local_publ_count--;
789 skb = tipc_named_withdraw(net, publ); 743 skb = tipc_named_withdraw(net, publ);
790 /* Any pending external events? */ 744 /* Any pending external events? */
791 tipc_named_process_backlog(net); 745 tipc_named_process_backlog(net);
792 list_del_init(&publ->pport_list); 746 list_del_init(&publ->binding_sock);
793 kfree_rcu(publ, rcu); 747 kfree_rcu(publ, rcu);
794 } else { 748 } else {
795 pr_err("Unable to remove local publication\n" 749 pr_err("Unable to remove local publication\n"
796 "(type=%u, lower=%u, ref=%u, key=%u)\n", 750 "(type=%u, lower=%u, port=%u, key=%u)\n",
797 type, lower, ref, key); 751 type, lower, port, key);
798 } 752 }
799 spin_unlock_bh(&tn->nametbl_lock); 753 spin_unlock_bh(&tn->nametbl_lock);
800 754
@@ -808,24 +762,27 @@ int tipc_nametbl_withdraw(struct net *net, u32 type, u32 lower, u32 ref,
808/** 762/**
809 * tipc_nametbl_subscribe - add a subscription object to the name table 763 * tipc_nametbl_subscribe - add a subscription object to the name table
810 */ 764 */
811void tipc_nametbl_subscribe(struct tipc_subscription *s, bool status) 765void tipc_nametbl_subscribe(struct tipc_subscription *sub)
812{ 766{
813 struct tipc_net *tn = net_generic(s->net, tipc_net_id); 767 struct tipc_net *tn = tipc_net(sub->net);
814 u32 type = tipc_subscrp_convert_seq_type(s->evt.s.seq.type, s->swap); 768 struct tipc_subscr *s = &sub->evt.s;
769 u32 type = tipc_sub_read(s, seq.type);
815 int index = hash(type); 770 int index = hash(type);
816 struct name_seq *seq; 771 struct name_seq *seq;
817 struct tipc_name_seq ns; 772 struct tipc_name_seq ns;
818 773
819 spin_lock_bh(&tn->nametbl_lock); 774 spin_lock_bh(&tn->nametbl_lock);
820 seq = nametbl_find_seq(s->net, type); 775 seq = nametbl_find_seq(sub->net, type);
821 if (!seq) 776 if (!seq)
822 seq = tipc_nameseq_create(type, &tn->nametbl->seq_hlist[index]); 777 seq = tipc_nameseq_create(type, &tn->nametbl->seq_hlist[index]);
823 if (seq) { 778 if (seq) {
824 spin_lock_bh(&seq->lock); 779 spin_lock_bh(&seq->lock);
825 tipc_nameseq_subscribe(seq, s, status); 780 tipc_nameseq_subscribe(seq, sub);
826 spin_unlock_bh(&seq->lock); 781 spin_unlock_bh(&seq->lock);
827 } else { 782 } else {
828 tipc_subscrp_convert_seq(&s->evt.s.seq, s->swap, &ns); 783 ns.type = tipc_sub_read(s, seq.type);
784 ns.lower = tipc_sub_read(s, seq.lower);
785 ns.upper = tipc_sub_read(s, seq.upper);
829 pr_warn("Failed to create subscription for {%u,%u,%u}\n", 786 pr_warn("Failed to create subscription for {%u,%u,%u}\n",
830 ns.type, ns.lower, ns.upper); 787 ns.type, ns.lower, ns.upper);
831 } 788 }
@@ -835,18 +792,19 @@ void tipc_nametbl_subscribe(struct tipc_subscription *s, bool status)
835/** 792/**
836 * tipc_nametbl_unsubscribe - remove a subscription object from name table 793 * tipc_nametbl_unsubscribe - remove a subscription object from name table
837 */ 794 */
838void tipc_nametbl_unsubscribe(struct tipc_subscription *s) 795void tipc_nametbl_unsubscribe(struct tipc_subscription *sub)
839{ 796{
840 struct tipc_net *tn = net_generic(s->net, tipc_net_id); 797 struct tipc_subscr *s = &sub->evt.s;
798 struct tipc_net *tn = tipc_net(sub->net);
841 struct name_seq *seq; 799 struct name_seq *seq;
842 u32 type = tipc_subscrp_convert_seq_type(s->evt.s.seq.type, s->swap); 800 u32 type = tipc_sub_read(s, seq.type);
843 801
844 spin_lock_bh(&tn->nametbl_lock); 802 spin_lock_bh(&tn->nametbl_lock);
845 seq = nametbl_find_seq(s->net, type); 803 seq = nametbl_find_seq(sub->net, type);
846 if (seq != NULL) { 804 if (seq != NULL) {
847 spin_lock_bh(&seq->lock); 805 spin_lock_bh(&seq->lock);
848 list_del_init(&s->nameseq_list); 806 list_del_init(&sub->nameseq_list);
849 tipc_subscrp_put(s); 807 tipc_sub_put(sub);
850 if (!seq->first_free && list_empty(&seq->subscriptions)) { 808 if (!seq->first_free && list_empty(&seq->subscriptions)) {
851 hlist_del_init_rcu(&seq->ns_list); 809 hlist_del_init_rcu(&seq->ns_list);
852 kfree(seq->sseqs); 810 kfree(seq->sseqs);
@@ -872,9 +830,8 @@ int tipc_nametbl_init(struct net *net)
872 for (i = 0; i < TIPC_NAMETBL_SIZE; i++) 830 for (i = 0; i < TIPC_NAMETBL_SIZE; i++)
873 INIT_HLIST_HEAD(&tipc_nametbl->seq_hlist[i]); 831 INIT_HLIST_HEAD(&tipc_nametbl->seq_hlist[i]);
874 832
875 INIT_LIST_HEAD(&tipc_nametbl->publ_list[TIPC_ZONE_SCOPE]); 833 INIT_LIST_HEAD(&tipc_nametbl->node_scope);
876 INIT_LIST_HEAD(&tipc_nametbl->publ_list[TIPC_CLUSTER_SCOPE]); 834 INIT_LIST_HEAD(&tipc_nametbl->cluster_scope);
877 INIT_LIST_HEAD(&tipc_nametbl->publ_list[TIPC_NODE_SCOPE]);
878 tn->nametbl = tipc_nametbl; 835 tn->nametbl = tipc_nametbl;
879 spin_lock_init(&tn->nametbl_lock); 836 spin_lock_init(&tn->nametbl_lock);
880 return 0; 837 return 0;
@@ -894,9 +851,9 @@ static void tipc_purge_publications(struct net *net, struct name_seq *seq)
894 spin_lock_bh(&seq->lock); 851 spin_lock_bh(&seq->lock);
895 sseq = seq->sseqs; 852 sseq = seq->sseqs;
896 info = sseq->info; 853 info = sseq->info;
897 list_for_each_entry_safe(publ, safe, &info->zone_list, zone_list) { 854 list_for_each_entry_safe(publ, safe, &info->all_publ, all_publ) {
898 tipc_nameseq_remove_publ(net, seq, publ->lower, publ->node, 855 tipc_nameseq_remove_publ(net, seq, publ->lower, publ->node,
899 publ->ref, publ->key); 856 publ->port, publ->key);
900 kfree_rcu(publ, rcu); 857 kfree_rcu(publ, rcu);
901 } 858 }
902 hlist_del_init_rcu(&seq->ns_list); 859 hlist_del_init_rcu(&seq->ns_list);
@@ -943,17 +900,17 @@ static int __tipc_nl_add_nametable_publ(struct tipc_nl_msg *msg,
943 struct publication *p; 900 struct publication *p;
944 901
945 if (*last_publ) { 902 if (*last_publ) {
946 list_for_each_entry(p, &sseq->info->zone_list, zone_list) 903 list_for_each_entry(p, &sseq->info->all_publ, all_publ)
947 if (p->key == *last_publ) 904 if (p->key == *last_publ)
948 break; 905 break;
949 if (p->key != *last_publ) 906 if (p->key != *last_publ)
950 return -EPIPE; 907 return -EPIPE;
951 } else { 908 } else {
952 p = list_first_entry(&sseq->info->zone_list, struct publication, 909 p = list_first_entry(&sseq->info->all_publ, struct publication,
953 zone_list); 910 all_publ);
954 } 911 }
955 912
956 list_for_each_entry_from(p, &sseq->info->zone_list, zone_list) { 913 list_for_each_entry_from(p, &sseq->info->all_publ, all_publ) {
957 *last_publ = p->key; 914 *last_publ = p->key;
958 915
959 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, 916 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq,
@@ -980,7 +937,7 @@ static int __tipc_nl_add_nametable_publ(struct tipc_nl_msg *msg,
980 goto publ_msg_full; 937 goto publ_msg_full;
981 if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_NODE, p->node)) 938 if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_NODE, p->node))
982 goto publ_msg_full; 939 goto publ_msg_full;
983 if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_REF, p->ref)) 940 if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_REF, p->port))
984 goto publ_msg_full; 941 goto publ_msg_full;
985 if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_KEY, p->key)) 942 if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_KEY, p->key))
986 goto publ_msg_full; 943 goto publ_msg_full;
diff --git a/net/tipc/name_table.h b/net/tipc/name_table.h
index f56e7cb3d436..34a4ccb907aa 100644
--- a/net/tipc/name_table.h
+++ b/net/tipc/name_table.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * net/tipc/name_table.h: Include file for TIPC name table code 2 * net/tipc/name_table.h: Include file for TIPC name table code
3 * 3 *
4 * Copyright (c) 2000-2006, 2014-2015, Ericsson AB 4 * Copyright (c) 2000-2006, 2014-2018, Ericsson AB
5 * Copyright (c) 2004-2005, 2010-2011, Wind River Systems 5 * Copyright (c) 2004-2005, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
@@ -54,19 +54,22 @@ struct tipc_group;
54 * @type: name sequence type 54 * @type: name sequence type
55 * @lower: name sequence lower bound 55 * @lower: name sequence lower bound
56 * @upper: name sequence upper bound 56 * @upper: name sequence upper bound
57 * @scope: scope of publication 57 * @scope: scope of publication, TIPC_NODE_SCOPE or TIPC_CLUSTER_SCOPE
58 * @node: network address of publishing port's node 58 * @node: network address of publishing socket's node
59 * @ref: publishing port 59 * @port: publishing port
60 * @key: publication key 60 * @key: publication key, unique across the cluster
61 * @nodesub_list: subscription to "node down" event (off-node publication only) 61 * @binding_node: all publications from the same node which bound this one
62 * @local_list: adjacent entries in list of publications made by this node 62 * - Remote publications: in node->publ_list
63 * @pport_list: adjacent entries in list of publications made by this port 63 * Used by node/name distr to withdraw publications when node is lost
64 * @node_list: adjacent matching name seq publications with >= node scope 64 * - Local/node scope publications: in name_table->node_scope list
65 * @cluster_list: adjacent matching name seq publications with >= cluster scope 65 * - Local/cluster scope publications: in name_table->cluster_scope list
66 * @zone_list: adjacent matching name seq publications with >= zone scope 66 * @binding_sock: all publications from the same socket which bound this one
67 * Used by socket to withdraw publications when socket is unbound/released
68 * @local_publ: list of identical publications made from this node
69 * Used by closest_first and multicast receive lookup algorithms
70 * @all_publ: all publications identical to this one, whatever node and scope
71 * Used by round-robin lookup algorithm
67 * @rcu: RCU callback head used for deferred freeing 72 * @rcu: RCU callback head used for deferred freeing
68 *
69 * Note that the node list, cluster list, and zone list are circular lists.
70 */ 73 */
71struct publication { 74struct publication {
72 u32 type; 75 u32 type;
@@ -74,34 +77,37 @@ struct publication {
74 u32 upper; 77 u32 upper;
75 u32 scope; 78 u32 scope;
76 u32 node; 79 u32 node;
77 u32 ref; 80 u32 port;
78 u32 key; 81 u32 key;
79 struct list_head nodesub_list; 82 struct list_head binding_node;
80 struct list_head local_list; 83 struct list_head binding_sock;
81 struct list_head pport_list; 84 struct list_head local_publ;
82 struct list_head node_list; 85 struct list_head all_publ;
83 struct list_head cluster_list;
84 struct list_head zone_list;
85 struct rcu_head rcu; 86 struct rcu_head rcu;
86}; 87};
87 88
88/** 89/**
89 * struct name_table - table containing all existing port name publications 90 * struct name_table - table containing all existing port name publications
90 * @seq_hlist: name sequence hash lists 91 * @seq_hlist: name sequence hash lists
91 * @publ_list: pulication lists 92 * @node_scope: all local publications with node scope
93 * - used by name_distr during re-init of name table
94 * @cluster_scope: all local publications with cluster scope
95 * - used by name_distr to send bulk updates to new nodes
96 * - used by name_distr during re-init of name table
92 * @local_publ_count: number of publications issued by this node 97 * @local_publ_count: number of publications issued by this node
93 */ 98 */
94struct name_table { 99struct name_table {
95 struct hlist_head seq_hlist[TIPC_NAMETBL_SIZE]; 100 struct hlist_head seq_hlist[TIPC_NAMETBL_SIZE];
96 struct list_head publ_list[TIPC_PUBL_SCOPE_NUM]; 101 struct list_head node_scope;
102 struct list_head cluster_scope;
97 u32 local_publ_count; 103 u32 local_publ_count;
98}; 104};
99 105
100int tipc_nl_name_table_dump(struct sk_buff *skb, struct netlink_callback *cb); 106int tipc_nl_name_table_dump(struct sk_buff *skb, struct netlink_callback *cb);
101 107
102u32 tipc_nametbl_translate(struct net *net, u32 type, u32 instance, u32 *node); 108u32 tipc_nametbl_translate(struct net *net, u32 type, u32 instance, u32 *node);
103int tipc_nametbl_mc_lookup(struct net *net, u32 type, u32 lower, u32 upper, 109void tipc_nametbl_mc_lookup(struct net *net, u32 type, u32 lower, u32 upper,
104 u32 scope, bool exact, struct list_head *dports); 110 u32 scope, bool exact, struct list_head *dports);
105void tipc_nametbl_build_group(struct net *net, struct tipc_group *grp, 111void tipc_nametbl_build_group(struct net *net, struct tipc_group *grp,
106 u32 type, u32 domain); 112 u32 type, u32 domain);
107void tipc_nametbl_lookup_dst_nodes(struct net *net, u32 type, u32 lower, 113void tipc_nametbl_lookup_dst_nodes(struct net *net, u32 type, u32 lower,
@@ -120,7 +126,7 @@ struct publication *tipc_nametbl_insert_publ(struct net *net, u32 type,
120struct publication *tipc_nametbl_remove_publ(struct net *net, u32 type, 126struct publication *tipc_nametbl_remove_publ(struct net *net, u32 type,
121 u32 lower, u32 node, u32 ref, 127 u32 lower, u32 node, u32 ref,
122 u32 key); 128 u32 key);
123void tipc_nametbl_subscribe(struct tipc_subscription *s, bool status); 129void tipc_nametbl_subscribe(struct tipc_subscription *s);
124void tipc_nametbl_unsubscribe(struct tipc_subscription *s); 130void tipc_nametbl_unsubscribe(struct tipc_subscription *s);
125int tipc_nametbl_init(struct net *net); 131int tipc_nametbl_init(struct net *net);
126void tipc_nametbl_stop(struct net *net); 132void tipc_nametbl_stop(struct net *net);
diff --git a/net/tipc/net.c b/net/tipc/net.c
index 1a2fde0d6f61..5c4c4405b78e 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -118,7 +118,7 @@ int tipc_net_start(struct net *net, u32 addr)
118 tipc_sk_reinit(net); 118 tipc_sk_reinit(net);
119 119
120 tipc_nametbl_publish(net, TIPC_CFG_SRV, tn->own_addr, tn->own_addr, 120 tipc_nametbl_publish(net, TIPC_CFG_SRV, tn->own_addr, tn->own_addr,
121 TIPC_ZONE_SCOPE, 0, tn->own_addr); 121 TIPC_CLUSTER_SCOPE, 0, tn->own_addr);
122 122
123 pr_info("Started in network mode\n"); 123 pr_info("Started in network mode\n");
124 pr_info("Own node address %s, network identity %u\n", 124 pr_info("Own node address %s, network identity %u\n",
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 9036d8756e73..389193d7cf67 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -1618,6 +1618,30 @@ discard:
1618 kfree_skb(skb); 1618 kfree_skb(skb);
1619} 1619}
1620 1620
1621void tipc_node_apply_tolerance(struct net *net, struct tipc_bearer *b)
1622{
1623 struct tipc_net *tn = tipc_net(net);
1624 int bearer_id = b->identity;
1625 struct sk_buff_head xmitq;
1626 struct tipc_link_entry *e;
1627 struct tipc_node *n;
1628
1629 __skb_queue_head_init(&xmitq);
1630
1631 rcu_read_lock();
1632
1633 list_for_each_entry_rcu(n, &tn->node_list, list) {
1634 tipc_node_write_lock(n);
1635 e = &n->links[bearer_id];
1636 if (e->link)
1637 tipc_link_set_tolerance(e->link, b->tolerance, &xmitq);
1638 tipc_node_write_unlock(n);
1639 tipc_bearer_xmit(net, bearer_id, &xmitq, &e->maddr);
1640 }
1641
1642 rcu_read_unlock();
1643}
1644
1621int tipc_nl_peer_rm(struct sk_buff *skb, struct genl_info *info) 1645int tipc_nl_peer_rm(struct sk_buff *skb, struct genl_info *info)
1622{ 1646{
1623 struct net *net = sock_net(skb->sk); 1647 struct net *net = sock_net(skb->sk);
diff --git a/net/tipc/node.h b/net/tipc/node.h
index acd58d23a70e..4ce5e3a185c0 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -65,6 +65,7 @@ void tipc_node_check_dest(struct net *net, u32 onode,
65 struct tipc_media_addr *maddr, 65 struct tipc_media_addr *maddr,
66 bool *respond, bool *dupl_addr); 66 bool *respond, bool *dupl_addr);
67void tipc_node_delete_links(struct net *net, int bearer_id); 67void tipc_node_delete_links(struct net *net, int bearer_id);
68void tipc_node_apply_tolerance(struct net *net, struct tipc_bearer *b);
68int tipc_node_get_linkname(struct net *net, u32 bearer_id, u32 node, 69int tipc_node_get_linkname(struct net *net, u32 bearer_id, u32 node,
69 char *linkname, size_t len); 70 char *linkname, size_t len);
70int tipc_node_xmit(struct net *net, struct sk_buff_head *list, u32 dnode, 71int tipc_node_xmit(struct net *net, struct sk_buff_head *list, u32 dnode,
diff --git a/net/tipc/server.c b/net/tipc/server.c
deleted file mode 100644
index df0c563c90cd..000000000000
--- a/net/tipc/server.c
+++ /dev/null
@@ -1,710 +0,0 @@
1/*
2 * net/tipc/server.c: TIPC server infrastructure
3 *
4 * Copyright (c) 2012-2013, Wind River Systems
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the names of the copyright holders nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * Alternatively, this software may be distributed under the terms of the
20 * GNU General Public License ("GPL") version 2 as published by the Free
21 * Software Foundation.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 */
35
36#include "server.h"
37#include "core.h"
38#include "socket.h"
39#include "addr.h"
40#include "msg.h"
41#include <net/sock.h>
42#include <linux/module.h>
43
44/* Number of messages to send before rescheduling */
45#define MAX_SEND_MSG_COUNT 25
46#define MAX_RECV_MSG_COUNT 25
47#define CF_CONNECTED 1
48#define CF_SERVER 2
49
50#define sock2con(x) ((struct tipc_conn *)(x)->sk_user_data)
51
52/**
53 * struct tipc_conn - TIPC connection structure
54 * @kref: reference counter to connection object
55 * @conid: connection identifier
56 * @sock: socket handler associated with connection
57 * @flags: indicates connection state
58 * @server: pointer to connected server
59 * @rwork: receive work item
60 * @usr_data: user-specified field
61 * @rx_action: what to do when connection socket is active
62 * @outqueue: pointer to first outbound message in queue
63 * @outqueue_lock: control access to the outqueue
64 * @outqueue: list of connection objects for its server
65 * @swork: send work item
66 */
67struct tipc_conn {
68 struct kref kref;
69 int conid;
70 struct socket *sock;
71 unsigned long flags;
72 struct tipc_server *server;
73 struct work_struct rwork;
74 int (*rx_action) (struct tipc_conn *con);
75 void *usr_data;
76 struct list_head outqueue;
77 spinlock_t outqueue_lock;
78 struct work_struct swork;
79};
80
81/* An entry waiting to be sent */
82struct outqueue_entry {
83 struct list_head list;
84 struct kvec iov;
85 struct sockaddr_tipc dest;
86};
87
88static void tipc_recv_work(struct work_struct *work);
89static void tipc_send_work(struct work_struct *work);
90static void tipc_clean_outqueues(struct tipc_conn *con);
91
92static void tipc_conn_kref_release(struct kref *kref)
93{
94 struct tipc_conn *con = container_of(kref, struct tipc_conn, kref);
95 struct tipc_server *s = con->server;
96 struct sockaddr_tipc *saddr = s->saddr;
97 struct socket *sock = con->sock;
98 struct sock *sk;
99
100 if (sock) {
101 sk = sock->sk;
102 if (test_bit(CF_SERVER, &con->flags)) {
103 __module_get(sock->ops->owner);
104 __module_get(sk->sk_prot_creator->owner);
105 }
106 saddr->scope = -TIPC_NODE_SCOPE;
107 kernel_bind(sock, (struct sockaddr *)saddr, sizeof(*saddr));
108 sock_release(sock);
109 con->sock = NULL;
110 }
111 spin_lock_bh(&s->idr_lock);
112 idr_remove(&s->conn_idr, con->conid);
113 s->idr_in_use--;
114 spin_unlock_bh(&s->idr_lock);
115 tipc_clean_outqueues(con);
116 kfree(con);
117}
118
119static void conn_put(struct tipc_conn *con)
120{
121 kref_put(&con->kref, tipc_conn_kref_release);
122}
123
124static void conn_get(struct tipc_conn *con)
125{
126 kref_get(&con->kref);
127}
128
129static struct tipc_conn *tipc_conn_lookup(struct tipc_server *s, int conid)
130{
131 struct tipc_conn *con;
132
133 spin_lock_bh(&s->idr_lock);
134 con = idr_find(&s->conn_idr, conid);
135 if (con) {
136 if (!test_bit(CF_CONNECTED, &con->flags) ||
137 !kref_get_unless_zero(&con->kref))
138 con = NULL;
139 }
140 spin_unlock_bh(&s->idr_lock);
141 return con;
142}
143
144static void sock_data_ready(struct sock *sk)
145{
146 struct tipc_conn *con;
147
148 read_lock_bh(&sk->sk_callback_lock);
149 con = sock2con(sk);
150 if (con && test_bit(CF_CONNECTED, &con->flags)) {
151 conn_get(con);
152 if (!queue_work(con->server->rcv_wq, &con->rwork))
153 conn_put(con);
154 }
155 read_unlock_bh(&sk->sk_callback_lock);
156}
157
158static void sock_write_space(struct sock *sk)
159{
160 struct tipc_conn *con;
161
162 read_lock_bh(&sk->sk_callback_lock);
163 con = sock2con(sk);
164 if (con && test_bit(CF_CONNECTED, &con->flags)) {
165 conn_get(con);
166 if (!queue_work(con->server->send_wq, &con->swork))
167 conn_put(con);
168 }
169 read_unlock_bh(&sk->sk_callback_lock);
170}
171
172static void tipc_register_callbacks(struct socket *sock, struct tipc_conn *con)
173{
174 struct sock *sk = sock->sk;
175
176 write_lock_bh(&sk->sk_callback_lock);
177
178 sk->sk_data_ready = sock_data_ready;
179 sk->sk_write_space = sock_write_space;
180 sk->sk_user_data = con;
181
182 con->sock = sock;
183
184 write_unlock_bh(&sk->sk_callback_lock);
185}
186
187static void tipc_close_conn(struct tipc_conn *con)
188{
189 struct tipc_server *s = con->server;
190 struct sock *sk = con->sock->sk;
191 bool disconnect = false;
192
193 write_lock_bh(&sk->sk_callback_lock);
194 disconnect = test_and_clear_bit(CF_CONNECTED, &con->flags);
195 if (disconnect) {
196 sk->sk_user_data = NULL;
197 if (con->conid)
198 s->tipc_conn_release(con->conid, con->usr_data);
199 }
200 write_unlock_bh(&sk->sk_callback_lock);
201
202 /* Handle concurrent calls from sending and receiving threads */
203 if (!disconnect)
204 return;
205
206 /* Don't flush pending works, -just let them expire */
207 kernel_sock_shutdown(con->sock, SHUT_RDWR);
208 conn_put(con);
209}
210
211static struct tipc_conn *tipc_alloc_conn(struct tipc_server *s)
212{
213 struct tipc_conn *con;
214 int ret;
215
216 con = kzalloc(sizeof(struct tipc_conn), GFP_ATOMIC);
217 if (!con)
218 return ERR_PTR(-ENOMEM);
219
220 kref_init(&con->kref);
221 INIT_LIST_HEAD(&con->outqueue);
222 spin_lock_init(&con->outqueue_lock);
223 INIT_WORK(&con->swork, tipc_send_work);
224 INIT_WORK(&con->rwork, tipc_recv_work);
225
226 spin_lock_bh(&s->idr_lock);
227 ret = idr_alloc(&s->conn_idr, con, 0, 0, GFP_ATOMIC);
228 if (ret < 0) {
229 kfree(con);
230 spin_unlock_bh(&s->idr_lock);
231 return ERR_PTR(-ENOMEM);
232 }
233 con->conid = ret;
234 s->idr_in_use++;
235 spin_unlock_bh(&s->idr_lock);
236
237 set_bit(CF_CONNECTED, &con->flags);
238 con->server = s;
239
240 return con;
241}
242
243static int tipc_receive_from_sock(struct tipc_conn *con)
244{
245 struct tipc_server *s = con->server;
246 struct sock *sk = con->sock->sk;
247 struct sockaddr_tipc addr;
248 struct msghdr msg = {};
249 struct kvec iov;
250 void *buf;
251 int ret;
252
253 buf = kmem_cache_alloc(s->rcvbuf_cache, GFP_ATOMIC);
254 if (!buf) {
255 ret = -ENOMEM;
256 goto out_close;
257 }
258
259 iov.iov_base = buf;
260 iov.iov_len = s->max_rcvbuf_size;
261 msg.msg_name = &addr;
262 iov_iter_kvec(&msg.msg_iter, READ | ITER_KVEC, &iov, 1, iov.iov_len);
263 ret = sock_recvmsg(con->sock, &msg, MSG_DONTWAIT);
264 if (ret <= 0) {
265 kmem_cache_free(s->rcvbuf_cache, buf);
266 goto out_close;
267 }
268
269 read_lock_bh(&sk->sk_callback_lock);
270 if (test_bit(CF_CONNECTED, &con->flags))
271 ret = s->tipc_conn_recvmsg(sock_net(con->sock->sk), con->conid,
272 &addr, con->usr_data, buf, ret);
273 read_unlock_bh(&sk->sk_callback_lock);
274 kmem_cache_free(s->rcvbuf_cache, buf);
275 if (ret < 0)
276 tipc_conn_terminate(s, con->conid);
277 return ret;
278
279out_close:
280 if (ret != -EWOULDBLOCK)
281 tipc_close_conn(con);
282 else if (ret == 0)
283 /* Don't return success if we really got EOF */
284 ret = -EAGAIN;
285
286 return ret;
287}
288
289static int tipc_accept_from_sock(struct tipc_conn *con)
290{
291 struct tipc_server *s = con->server;
292 struct socket *sock = con->sock;
293 struct socket *newsock;
294 struct tipc_conn *newcon;
295 int ret;
296
297 ret = kernel_accept(sock, &newsock, O_NONBLOCK);
298 if (ret < 0)
299 return ret;
300
301 newcon = tipc_alloc_conn(con->server);
302 if (IS_ERR(newcon)) {
303 ret = PTR_ERR(newcon);
304 sock_release(newsock);
305 return ret;
306 }
307
308 newcon->rx_action = tipc_receive_from_sock;
309 tipc_register_callbacks(newsock, newcon);
310
311 /* Notify that new connection is incoming */
312 newcon->usr_data = s->tipc_conn_new(newcon->conid);
313 if (!newcon->usr_data) {
314 sock_release(newsock);
315 conn_put(newcon);
316 return -ENOMEM;
317 }
318
319 /* Wake up receive process in case of 'SYN+' message */
320 newsock->sk->sk_data_ready(newsock->sk);
321 return ret;
322}
323
324static struct socket *tipc_create_listen_sock(struct tipc_conn *con)
325{
326 struct tipc_server *s = con->server;
327 struct socket *sock = NULL;
328 int ret;
329
330 ret = sock_create_kern(s->net, AF_TIPC, SOCK_SEQPACKET, 0, &sock);
331 if (ret < 0)
332 return NULL;
333 ret = kernel_setsockopt(sock, SOL_TIPC, TIPC_IMPORTANCE,
334 (char *)&s->imp, sizeof(s->imp));
335 if (ret < 0)
336 goto create_err;
337 ret = kernel_bind(sock, (struct sockaddr *)s->saddr, sizeof(*s->saddr));
338 if (ret < 0)
339 goto create_err;
340
341 switch (s->type) {
342 case SOCK_STREAM:
343 case SOCK_SEQPACKET:
344 con->rx_action = tipc_accept_from_sock;
345
346 ret = kernel_listen(sock, 0);
347 if (ret < 0)
348 goto create_err;
349 break;
350 case SOCK_DGRAM:
351 case SOCK_RDM:
352 con->rx_action = tipc_receive_from_sock;
353 break;
354 default:
355 pr_err("Unknown socket type %d\n", s->type);
356 goto create_err;
357 }
358
359 /* As server's listening socket owner and creator is the same module,
360 * we have to decrease TIPC module reference count to guarantee that
361 * it remains zero after the server socket is created, otherwise,
362 * executing "rmmod" command is unable to make TIPC module deleted
363 * after TIPC module is inserted successfully.
364 *
365 * However, the reference count is ever increased twice in
366 * sock_create_kern(): one is to increase the reference count of owner
367 * of TIPC socket's proto_ops struct; another is to increment the
368 * reference count of owner of TIPC proto struct. Therefore, we must
369 * decrement the module reference count twice to ensure that it keeps
370 * zero after server's listening socket is created. Of course, we
371 * must bump the module reference count twice as well before the socket
372 * is closed.
373 */
374 module_put(sock->ops->owner);
375 module_put(sock->sk->sk_prot_creator->owner);
376 set_bit(CF_SERVER, &con->flags);
377
378 return sock;
379
380create_err:
381 kernel_sock_shutdown(sock, SHUT_RDWR);
382 sock_release(sock);
383 return NULL;
384}
385
386static int tipc_open_listening_sock(struct tipc_server *s)
387{
388 struct socket *sock;
389 struct tipc_conn *con;
390
391 con = tipc_alloc_conn(s);
392 if (IS_ERR(con))
393 return PTR_ERR(con);
394
395 sock = tipc_create_listen_sock(con);
396 if (!sock) {
397 idr_remove(&s->conn_idr, con->conid);
398 s->idr_in_use--;
399 kfree(con);
400 return -EINVAL;
401 }
402
403 tipc_register_callbacks(sock, con);
404 return 0;
405}
406
407static struct outqueue_entry *tipc_alloc_entry(void *data, int len)
408{
409 struct outqueue_entry *entry;
410 void *buf;
411
412 entry = kmalloc(sizeof(struct outqueue_entry), GFP_ATOMIC);
413 if (!entry)
414 return NULL;
415
416 buf = kmemdup(data, len, GFP_ATOMIC);
417 if (!buf) {
418 kfree(entry);
419 return NULL;
420 }
421
422 entry->iov.iov_base = buf;
423 entry->iov.iov_len = len;
424
425 return entry;
426}
427
428static void tipc_free_entry(struct outqueue_entry *e)
429{
430 kfree(e->iov.iov_base);
431 kfree(e);
432}
433
434static void tipc_clean_outqueues(struct tipc_conn *con)
435{
436 struct outqueue_entry *e, *safe;
437
438 spin_lock_bh(&con->outqueue_lock);
439 list_for_each_entry_safe(e, safe, &con->outqueue, list) {
440 list_del(&e->list);
441 tipc_free_entry(e);
442 }
443 spin_unlock_bh(&con->outqueue_lock);
444}
445
446int tipc_conn_sendmsg(struct tipc_server *s, int conid,
447 struct sockaddr_tipc *addr, void *data, size_t len)
448{
449 struct outqueue_entry *e;
450 struct tipc_conn *con;
451
452 con = tipc_conn_lookup(s, conid);
453 if (!con)
454 return -EINVAL;
455
456 if (!test_bit(CF_CONNECTED, &con->flags)) {
457 conn_put(con);
458 return 0;
459 }
460
461 e = tipc_alloc_entry(data, len);
462 if (!e) {
463 conn_put(con);
464 return -ENOMEM;
465 }
466
467 if (addr)
468 memcpy(&e->dest, addr, sizeof(struct sockaddr_tipc));
469
470 spin_lock_bh(&con->outqueue_lock);
471 list_add_tail(&e->list, &con->outqueue);
472 spin_unlock_bh(&con->outqueue_lock);
473
474 if (!queue_work(s->send_wq, &con->swork))
475 conn_put(con);
476 return 0;
477}
478
479void tipc_conn_terminate(struct tipc_server *s, int conid)
480{
481 struct tipc_conn *con;
482
483 con = tipc_conn_lookup(s, conid);
484 if (con) {
485 tipc_close_conn(con);
486 conn_put(con);
487 }
488}
489
490bool tipc_topsrv_kern_subscr(struct net *net, u32 port, u32 type, u32 lower,
491 u32 upper, u32 filter, int *conid)
492{
493 struct tipc_subscriber *scbr;
494 struct tipc_subscr sub;
495 struct tipc_server *s;
496 struct tipc_conn *con;
497
498 sub.seq.type = type;
499 sub.seq.lower = lower;
500 sub.seq.upper = upper;
501 sub.timeout = TIPC_WAIT_FOREVER;
502 sub.filter = filter;
503 *(u32 *)&sub.usr_handle = port;
504
505 con = tipc_alloc_conn(tipc_topsrv(net));
506 if (IS_ERR(con))
507 return false;
508
509 *conid = con->conid;
510 s = con->server;
511 scbr = s->tipc_conn_new(*conid);
512 if (!scbr) {
513 conn_put(con);
514 return false;
515 }
516
517 con->usr_data = scbr;
518 con->sock = NULL;
519 s->tipc_conn_recvmsg(net, *conid, NULL, scbr, &sub, sizeof(sub));
520 return true;
521}
522
523void tipc_topsrv_kern_unsubscr(struct net *net, int conid)
524{
525 struct tipc_conn *con;
526 struct tipc_server *srv;
527
528 con = tipc_conn_lookup(tipc_topsrv(net), conid);
529 if (!con)
530 return;
531
532 test_and_clear_bit(CF_CONNECTED, &con->flags);
533 srv = con->server;
534 if (con->conid)
535 srv->tipc_conn_release(con->conid, con->usr_data);
536 conn_put(con);
537 conn_put(con);
538}
539
540static void tipc_send_kern_top_evt(struct net *net, struct tipc_event *evt)
541{
542 u32 port = *(u32 *)&evt->s.usr_handle;
543 u32 self = tipc_own_addr(net);
544 struct sk_buff_head evtq;
545 struct sk_buff *skb;
546
547 skb = tipc_msg_create(TOP_SRV, 0, INT_H_SIZE, sizeof(*evt),
548 self, self, port, port, 0);
549 if (!skb)
550 return;
551 msg_set_dest_droppable(buf_msg(skb), true);
552 memcpy(msg_data(buf_msg(skb)), evt, sizeof(*evt));
553 skb_queue_head_init(&evtq);
554 __skb_queue_tail(&evtq, skb);
555 tipc_sk_rcv(net, &evtq);
556}
557
558static void tipc_send_to_sock(struct tipc_conn *con)
559{
560 struct tipc_server *s = con->server;
561 struct outqueue_entry *e;
562 struct tipc_event *evt;
563 struct msghdr msg;
564 int count = 0;
565 int ret;
566
567 spin_lock_bh(&con->outqueue_lock);
568 while (test_bit(CF_CONNECTED, &con->flags)) {
569 e = list_entry(con->outqueue.next, struct outqueue_entry, list);
570 if ((struct list_head *) e == &con->outqueue)
571 break;
572
573 spin_unlock_bh(&con->outqueue_lock);
574
575 if (con->sock) {
576 memset(&msg, 0, sizeof(msg));
577 msg.msg_flags = MSG_DONTWAIT;
578 if (s->type == SOCK_DGRAM || s->type == SOCK_RDM) {
579 msg.msg_name = &e->dest;
580 msg.msg_namelen = sizeof(struct sockaddr_tipc);
581 }
582 ret = kernel_sendmsg(con->sock, &msg, &e->iov, 1,
583 e->iov.iov_len);
584 if (ret == -EWOULDBLOCK || ret == 0) {
585 cond_resched();
586 goto out;
587 } else if (ret < 0) {
588 goto send_err;
589 }
590 } else {
591 evt = e->iov.iov_base;
592 tipc_send_kern_top_evt(s->net, evt);
593 }
594 /* Don't starve users filling buffers */
595 if (++count >= MAX_SEND_MSG_COUNT) {
596 cond_resched();
597 count = 0;
598 }
599
600 spin_lock_bh(&con->outqueue_lock);
601 list_del(&e->list);
602 tipc_free_entry(e);
603 }
604 spin_unlock_bh(&con->outqueue_lock);
605out:
606 return;
607
608send_err:
609 tipc_close_conn(con);
610}
611
612static void tipc_recv_work(struct work_struct *work)
613{
614 struct tipc_conn *con = container_of(work, struct tipc_conn, rwork);
615 int count = 0;
616
617 while (test_bit(CF_CONNECTED, &con->flags)) {
618 if (con->rx_action(con))
619 break;
620
621 /* Don't flood Rx machine */
622 if (++count >= MAX_RECV_MSG_COUNT) {
623 cond_resched();
624 count = 0;
625 }
626 }
627 conn_put(con);
628}
629
630static void tipc_send_work(struct work_struct *work)
631{
632 struct tipc_conn *con = container_of(work, struct tipc_conn, swork);
633
634 if (test_bit(CF_CONNECTED, &con->flags))
635 tipc_send_to_sock(con);
636
637 conn_put(con);
638}
639
640static void tipc_work_stop(struct tipc_server *s)
641{
642 destroy_workqueue(s->rcv_wq);
643 destroy_workqueue(s->send_wq);
644}
645
646static int tipc_work_start(struct tipc_server *s)
647{
648 s->rcv_wq = alloc_ordered_workqueue("tipc_rcv", 0);
649 if (!s->rcv_wq) {
650 pr_err("can't start tipc receive workqueue\n");
651 return -ENOMEM;
652 }
653
654 s->send_wq = alloc_ordered_workqueue("tipc_send", 0);
655 if (!s->send_wq) {
656 pr_err("can't start tipc send workqueue\n");
657 destroy_workqueue(s->rcv_wq);
658 return -ENOMEM;
659 }
660
661 return 0;
662}
663
664int tipc_server_start(struct tipc_server *s)
665{
666 int ret;
667
668 spin_lock_init(&s->idr_lock);
669 idr_init(&s->conn_idr);
670 s->idr_in_use = 0;
671
672 s->rcvbuf_cache = kmem_cache_create(s->name, s->max_rcvbuf_size,
673 0, SLAB_HWCACHE_ALIGN, NULL);
674 if (!s->rcvbuf_cache)
675 return -ENOMEM;
676
677 ret = tipc_work_start(s);
678 if (ret < 0) {
679 kmem_cache_destroy(s->rcvbuf_cache);
680 return ret;
681 }
682 ret = tipc_open_listening_sock(s);
683 if (ret < 0) {
684 tipc_work_stop(s);
685 kmem_cache_destroy(s->rcvbuf_cache);
686 return ret;
687 }
688 return ret;
689}
690
691void tipc_server_stop(struct tipc_server *s)
692{
693 struct tipc_conn *con;
694 int id;
695
696 spin_lock_bh(&s->idr_lock);
697 for (id = 0; s->idr_in_use; id++) {
698 con = idr_find(&s->conn_idr, id);
699 if (con) {
700 spin_unlock_bh(&s->idr_lock);
701 tipc_close_conn(con);
702 spin_lock_bh(&s->idr_lock);
703 }
704 }
705 spin_unlock_bh(&s->idr_lock);
706
707 tipc_work_stop(s);
708 kmem_cache_destroy(s->rcvbuf_cache);
709 idr_destroy(&s->conn_idr);
710}
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 7dfa9fc99ec3..732ec894f69f 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -644,7 +644,7 @@ static int tipc_bind(struct socket *sock, struct sockaddr *uaddr,
644 goto exit; 644 goto exit;
645 } 645 }
646 646
647 res = (addr->scope > 0) ? 647 res = (addr->scope >= 0) ?
648 tipc_sk_publish(tsk, addr->scope, &addr->addr.nameseq) : 648 tipc_sk_publish(tsk, addr->scope, &addr->addr.nameseq) :
649 tipc_sk_withdraw(tsk, -addr->scope, &addr->addr.nameseq); 649 tipc_sk_withdraw(tsk, -addr->scope, &addr->addr.nameseq);
650exit: 650exit:
@@ -666,7 +666,7 @@ exit:
666 * a completely predictable manner). 666 * a completely predictable manner).
667 */ 667 */
668static int tipc_getname(struct socket *sock, struct sockaddr *uaddr, 668static int tipc_getname(struct socket *sock, struct sockaddr *uaddr,
669 int *uaddr_len, int peer) 669 int peer)
670{ 670{
671 struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; 671 struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr;
672 struct sock *sk = sock->sk; 672 struct sock *sk = sock->sk;
@@ -685,13 +685,12 @@ static int tipc_getname(struct socket *sock, struct sockaddr *uaddr,
685 addr->addr.id.node = tn->own_addr; 685 addr->addr.id.node = tn->own_addr;
686 } 686 }
687 687
688 *uaddr_len = sizeof(*addr);
689 addr->addrtype = TIPC_ADDR_ID; 688 addr->addrtype = TIPC_ADDR_ID;
690 addr->family = AF_TIPC; 689 addr->family = AF_TIPC;
691 addr->scope = 0; 690 addr->scope = 0;
692 addr->addr.name.domain = 0; 691 addr->addr.name.domain = 0;
693 692
694 return 0; 693 return sizeof(*addr);
695} 694}
696 695
697/** 696/**
@@ -1281,8 +1280,8 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dlen)
1281 struct tipc_msg *hdr = &tsk->phdr; 1280 struct tipc_msg *hdr = &tsk->phdr;
1282 struct tipc_name_seq *seq; 1281 struct tipc_name_seq *seq;
1283 struct sk_buff_head pkts; 1282 struct sk_buff_head pkts;
1284 u32 type, inst, domain;
1285 u32 dnode, dport; 1283 u32 dnode, dport;
1284 u32 type, inst;
1286 int mtu, rc; 1285 int mtu, rc;
1287 1286
1288 if (unlikely(dlen > TIPC_MAX_USER_MSG_SIZE)) 1287 if (unlikely(dlen > TIPC_MAX_USER_MSG_SIZE))
@@ -1333,13 +1332,12 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dlen)
1333 if (dest->addrtype == TIPC_ADDR_NAME) { 1332 if (dest->addrtype == TIPC_ADDR_NAME) {
1334 type = dest->addr.name.name.type; 1333 type = dest->addr.name.name.type;
1335 inst = dest->addr.name.name.instance; 1334 inst = dest->addr.name.name.instance;
1336 domain = dest->addr.name.domain; 1335 dnode = dest->addr.name.domain;
1337 dnode = domain;
1338 msg_set_type(hdr, TIPC_NAMED_MSG); 1336 msg_set_type(hdr, TIPC_NAMED_MSG);
1339 msg_set_hdr_sz(hdr, NAMED_H_SIZE); 1337 msg_set_hdr_sz(hdr, NAMED_H_SIZE);
1340 msg_set_nametype(hdr, type); 1338 msg_set_nametype(hdr, type);
1341 msg_set_nameinst(hdr, inst); 1339 msg_set_nameinst(hdr, inst);
1342 msg_set_lookup_scope(hdr, tipc_addr_scope(domain)); 1340 msg_set_lookup_scope(hdr, tipc_node2scope(dnode));
1343 dport = tipc_nametbl_translate(net, type, inst, &dnode); 1341 dport = tipc_nametbl_translate(net, type, inst, &dnode);
1344 msg_set_destnode(hdr, dnode); 1342 msg_set_destnode(hdr, dnode);
1345 msg_set_destport(hdr, dport); 1343 msg_set_destport(hdr, dport);
@@ -2124,8 +2122,10 @@ static void tipc_sk_filter_rcv(struct sock *sk, struct sk_buff *skb,
2124 (!sk_conn && msg_connected(hdr)) || 2122 (!sk_conn && msg_connected(hdr)) ||
2125 (!grp && msg_in_group(hdr))) 2123 (!grp && msg_in_group(hdr)))
2126 err = TIPC_ERR_NO_PORT; 2124 err = TIPC_ERR_NO_PORT;
2127 else if (sk_rmem_alloc_get(sk) + skb->truesize >= limit) 2125 else if (sk_rmem_alloc_get(sk) + skb->truesize >= limit) {
2126 atomic_inc(&sk->sk_drops);
2128 err = TIPC_ERR_OVERLOAD; 2127 err = TIPC_ERR_OVERLOAD;
2128 }
2129 2129
2130 if (unlikely(err)) { 2130 if (unlikely(err)) {
2131 tipc_skb_reject(net, err, skb, xmitq); 2131 tipc_skb_reject(net, err, skb, xmitq);
@@ -2204,6 +2204,7 @@ static void tipc_sk_enqueue(struct sk_buff_head *inputq, struct sock *sk,
2204 2204
2205 /* Overload => reject message back to sender */ 2205 /* Overload => reject message back to sender */
2206 onode = tipc_own_addr(sock_net(sk)); 2206 onode = tipc_own_addr(sock_net(sk));
2207 atomic_inc(&sk->sk_drops);
2207 if (tipc_msg_reverse(onode, &skb, TIPC_ERR_OVERLOAD)) 2208 if (tipc_msg_reverse(onode, &skb, TIPC_ERR_OVERLOAD))
2208 __skb_queue_tail(xmitq, skb); 2209 __skb_queue_tail(xmitq, skb);
2209 break; 2210 break;
@@ -2593,6 +2594,9 @@ static int tipc_sk_publish(struct tipc_sock *tsk, uint scope,
2593 struct publication *publ; 2594 struct publication *publ;
2594 u32 key; 2595 u32 key;
2595 2596
2597 if (scope != TIPC_NODE_SCOPE)
2598 scope = TIPC_CLUSTER_SCOPE;
2599
2596 if (tipc_sk_connected(sk)) 2600 if (tipc_sk_connected(sk))
2597 return -EINVAL; 2601 return -EINVAL;
2598 key = tsk->portid + tsk->pub_count + 1; 2602 key = tsk->portid + tsk->pub_count + 1;
@@ -2604,7 +2608,7 @@ static int tipc_sk_publish(struct tipc_sock *tsk, uint scope,
2604 if (unlikely(!publ)) 2608 if (unlikely(!publ))
2605 return -EINVAL; 2609 return -EINVAL;
2606 2610
2607 list_add(&publ->pport_list, &tsk->publications); 2611 list_add(&publ->binding_sock, &tsk->publications);
2608 tsk->pub_count++; 2612 tsk->pub_count++;
2609 tsk->published = 1; 2613 tsk->published = 1;
2610 return 0; 2614 return 0;
@@ -2618,7 +2622,10 @@ static int tipc_sk_withdraw(struct tipc_sock *tsk, uint scope,
2618 struct publication *safe; 2622 struct publication *safe;
2619 int rc = -EINVAL; 2623 int rc = -EINVAL;
2620 2624
2621 list_for_each_entry_safe(publ, safe, &tsk->publications, pport_list) { 2625 if (scope != TIPC_NODE_SCOPE)
2626 scope = TIPC_CLUSTER_SCOPE;
2627
2628 list_for_each_entry_safe(publ, safe, &tsk->publications, binding_sock) {
2622 if (seq) { 2629 if (seq) {
2623 if (publ->scope != scope) 2630 if (publ->scope != scope)
2624 continue; 2631 continue;
@@ -2629,12 +2636,12 @@ static int tipc_sk_withdraw(struct tipc_sock *tsk, uint scope,
2629 if (publ->upper != seq->upper) 2636 if (publ->upper != seq->upper)
2630 break; 2637 break;
2631 tipc_nametbl_withdraw(net, publ->type, publ->lower, 2638 tipc_nametbl_withdraw(net, publ->type, publ->lower,
2632 publ->ref, publ->key); 2639 publ->port, publ->key);
2633 rc = 0; 2640 rc = 0;
2634 break; 2641 break;
2635 } 2642 }
2636 tipc_nametbl_withdraw(net, publ->type, publ->lower, 2643 tipc_nametbl_withdraw(net, publ->type, publ->lower,
2637 publ->ref, publ->key); 2644 publ->port, publ->key);
2638 rc = 0; 2645 rc = 0;
2639 } 2646 }
2640 if (list_empty(&tsk->publications)) 2647 if (list_empty(&tsk->publications))
@@ -3156,16 +3163,33 @@ msg_full:
3156 return -EMSGSIZE; 3163 return -EMSGSIZE;
3157} 3164}
3158 3165
3166static int __tipc_nl_add_sk_info(struct sk_buff *skb, struct tipc_sock
3167 *tsk)
3168{
3169 struct net *net = sock_net(skb->sk);
3170 struct tipc_net *tn = tipc_net(net);
3171 struct sock *sk = &tsk->sk;
3172
3173 if (nla_put_u32(skb, TIPC_NLA_SOCK_REF, tsk->portid) ||
3174 nla_put_u32(skb, TIPC_NLA_SOCK_ADDR, tn->own_addr))
3175 return -EMSGSIZE;
3176
3177 if (tipc_sk_connected(sk)) {
3178 if (__tipc_nl_add_sk_con(skb, tsk))
3179 return -EMSGSIZE;
3180 } else if (!list_empty(&tsk->publications)) {
3181 if (nla_put_flag(skb, TIPC_NLA_SOCK_HAS_PUBL))
3182 return -EMSGSIZE;
3183 }
3184 return 0;
3185}
3186
3159/* Caller should hold socket lock for the passed tipc socket. */ 3187/* Caller should hold socket lock for the passed tipc socket. */
3160static int __tipc_nl_add_sk(struct sk_buff *skb, struct netlink_callback *cb, 3188static int __tipc_nl_add_sk(struct sk_buff *skb, struct netlink_callback *cb,
3161 struct tipc_sock *tsk) 3189 struct tipc_sock *tsk)
3162{ 3190{
3163 int err;
3164 void *hdr;
3165 struct nlattr *attrs; 3191 struct nlattr *attrs;
3166 struct net *net = sock_net(skb->sk); 3192 void *hdr;
3167 struct tipc_net *tn = net_generic(net, tipc_net_id);
3168 struct sock *sk = &tsk->sk;
3169 3193
3170 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, 3194 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
3171 &tipc_genl_family, NLM_F_MULTI, TIPC_NL_SOCK_GET); 3195 &tipc_genl_family, NLM_F_MULTI, TIPC_NL_SOCK_GET);
@@ -3175,19 +3199,10 @@ static int __tipc_nl_add_sk(struct sk_buff *skb, struct netlink_callback *cb,
3175 attrs = nla_nest_start(skb, TIPC_NLA_SOCK); 3199 attrs = nla_nest_start(skb, TIPC_NLA_SOCK);
3176 if (!attrs) 3200 if (!attrs)
3177 goto genlmsg_cancel; 3201 goto genlmsg_cancel;
3178 if (nla_put_u32(skb, TIPC_NLA_SOCK_REF, tsk->portid)) 3202
3179 goto attr_msg_cancel; 3203 if (__tipc_nl_add_sk_info(skb, tsk))
3180 if (nla_put_u32(skb, TIPC_NLA_SOCK_ADDR, tn->own_addr))
3181 goto attr_msg_cancel; 3204 goto attr_msg_cancel;
3182 3205
3183 if (tipc_sk_connected(sk)) {
3184 err = __tipc_nl_add_sk_con(skb, tsk);
3185 if (err)
3186 goto attr_msg_cancel;
3187 } else if (!list_empty(&tsk->publications)) {
3188 if (nla_put_flag(skb, TIPC_NLA_SOCK_HAS_PUBL))
3189 goto attr_msg_cancel;
3190 }
3191 nla_nest_end(skb, attrs); 3206 nla_nest_end(skb, attrs);
3192 genlmsg_end(skb, hdr); 3207 genlmsg_end(skb, hdr);
3193 3208
@@ -3201,16 +3216,19 @@ msg_cancel:
3201 return -EMSGSIZE; 3216 return -EMSGSIZE;
3202} 3217}
3203 3218
3204int tipc_nl_sk_dump(struct sk_buff *skb, struct netlink_callback *cb) 3219int tipc_nl_sk_walk(struct sk_buff *skb, struct netlink_callback *cb,
3220 int (*skb_handler)(struct sk_buff *skb,
3221 struct netlink_callback *cb,
3222 struct tipc_sock *tsk))
3205{ 3223{
3206 int err;
3207 struct tipc_sock *tsk;
3208 const struct bucket_table *tbl;
3209 struct rhash_head *pos;
3210 struct net *net = sock_net(skb->sk); 3224 struct net *net = sock_net(skb->sk);
3211 struct tipc_net *tn = net_generic(net, tipc_net_id); 3225 struct tipc_net *tn = tipc_net(net);
3212 u32 tbl_id = cb->args[0]; 3226 const struct bucket_table *tbl;
3213 u32 prev_portid = cb->args[1]; 3227 u32 prev_portid = cb->args[1];
3228 u32 tbl_id = cb->args[0];
3229 struct rhash_head *pos;
3230 struct tipc_sock *tsk;
3231 int err;
3214 3232
3215 rcu_read_lock(); 3233 rcu_read_lock();
3216 tbl = rht_dereference_rcu((&tn->sk_rht)->tbl, &tn->sk_rht); 3234 tbl = rht_dereference_rcu((&tn->sk_rht)->tbl, &tn->sk_rht);
@@ -3222,12 +3240,13 @@ int tipc_nl_sk_dump(struct sk_buff *skb, struct netlink_callback *cb)
3222 continue; 3240 continue;
3223 } 3241 }
3224 3242
3225 err = __tipc_nl_add_sk(skb, cb, tsk); 3243 err = skb_handler(skb, cb, tsk);
3226 if (err) { 3244 if (err) {
3227 prev_portid = tsk->portid; 3245 prev_portid = tsk->portid;
3228 spin_unlock_bh(&tsk->sk.sk_lock.slock); 3246 spin_unlock_bh(&tsk->sk.sk_lock.slock);
3229 goto out; 3247 goto out;
3230 } 3248 }
3249
3231 prev_portid = 0; 3250 prev_portid = 0;
3232 spin_unlock_bh(&tsk->sk.sk_lock.slock); 3251 spin_unlock_bh(&tsk->sk.sk_lock.slock);
3233 } 3252 }
@@ -3239,6 +3258,75 @@ out:
3239 3258
3240 return skb->len; 3259 return skb->len;
3241} 3260}
3261EXPORT_SYMBOL(tipc_nl_sk_walk);
3262
3263int tipc_sk_fill_sock_diag(struct sk_buff *skb, struct tipc_sock *tsk,
3264 u32 sk_filter_state,
3265 u64 (*tipc_diag_gen_cookie)(struct sock *sk))
3266{
3267 struct sock *sk = &tsk->sk;
3268 struct nlattr *attrs;
3269 struct nlattr *stat;
3270
3271 /*filter response w.r.t sk_state*/
3272 if (!(sk_filter_state & (1 << sk->sk_state)))
3273 return 0;
3274
3275 attrs = nla_nest_start(skb, TIPC_NLA_SOCK);
3276 if (!attrs)
3277 goto msg_cancel;
3278
3279 if (__tipc_nl_add_sk_info(skb, tsk))
3280 goto attr_msg_cancel;
3281
3282 if (nla_put_u32(skb, TIPC_NLA_SOCK_TYPE, (u32)sk->sk_type) ||
3283 nla_put_u32(skb, TIPC_NLA_SOCK_TIPC_STATE, (u32)sk->sk_state) ||
3284 nla_put_u32(skb, TIPC_NLA_SOCK_INO, sock_i_ino(sk)) ||
3285 nla_put_u32(skb, TIPC_NLA_SOCK_UID,
3286 from_kuid_munged(sk_user_ns(sk), sock_i_uid(sk))) ||
3287 nla_put_u64_64bit(skb, TIPC_NLA_SOCK_COOKIE,
3288 tipc_diag_gen_cookie(sk),
3289 TIPC_NLA_SOCK_PAD))
3290 goto attr_msg_cancel;
3291
3292 stat = nla_nest_start(skb, TIPC_NLA_SOCK_STAT);
3293 if (!stat)
3294 goto attr_msg_cancel;
3295
3296 if (nla_put_u32(skb, TIPC_NLA_SOCK_STAT_RCVQ,
3297 skb_queue_len(&sk->sk_receive_queue)) ||
3298 nla_put_u32(skb, TIPC_NLA_SOCK_STAT_SENDQ,
3299 skb_queue_len(&sk->sk_write_queue)) ||
3300 nla_put_u32(skb, TIPC_NLA_SOCK_STAT_DROP,
3301 atomic_read(&sk->sk_drops)))
3302 goto stat_msg_cancel;
3303
3304 if (tsk->cong_link_cnt &&
3305 nla_put_flag(skb, TIPC_NLA_SOCK_STAT_LINK_CONG))
3306 goto stat_msg_cancel;
3307
3308 if (tsk_conn_cong(tsk) &&
3309 nla_put_flag(skb, TIPC_NLA_SOCK_STAT_CONN_CONG))
3310 goto stat_msg_cancel;
3311
3312 nla_nest_end(skb, stat);
3313 nla_nest_end(skb, attrs);
3314
3315 return 0;
3316
3317stat_msg_cancel:
3318 nla_nest_cancel(skb, stat);
3319attr_msg_cancel:
3320 nla_nest_cancel(skb, attrs);
3321msg_cancel:
3322 return -EMSGSIZE;
3323}
3324EXPORT_SYMBOL(tipc_sk_fill_sock_diag);
3325
3326int tipc_nl_sk_dump(struct sk_buff *skb, struct netlink_callback *cb)
3327{
3328 return tipc_nl_sk_walk(skb, cb, __tipc_nl_add_sk);
3329}
3242 3330
3243/* Caller should hold socket lock for the passed tipc socket. */ 3331/* Caller should hold socket lock for the passed tipc socket. */
3244static int __tipc_nl_add_sk_publ(struct sk_buff *skb, 3332static int __tipc_nl_add_sk_publ(struct sk_buff *skb,
@@ -3288,7 +3376,7 @@ static int __tipc_nl_list_sk_publ(struct sk_buff *skb,
3288 struct publication *p; 3376 struct publication *p;
3289 3377
3290 if (*last_publ) { 3378 if (*last_publ) {
3291 list_for_each_entry(p, &tsk->publications, pport_list) { 3379 list_for_each_entry(p, &tsk->publications, binding_sock) {
3292 if (p->key == *last_publ) 3380 if (p->key == *last_publ)
3293 break; 3381 break;
3294 } 3382 }
@@ -3305,10 +3393,10 @@ static int __tipc_nl_list_sk_publ(struct sk_buff *skb,
3305 } 3393 }
3306 } else { 3394 } else {
3307 p = list_first_entry(&tsk->publications, struct publication, 3395 p = list_first_entry(&tsk->publications, struct publication,
3308 pport_list); 3396 binding_sock);
3309 } 3397 }
3310 3398
3311 list_for_each_entry_from(p, &tsk->publications, pport_list) { 3399 list_for_each_entry_from(p, &tsk->publications, binding_sock) {
3312 err = __tipc_nl_add_sk_publ(skb, cb, p); 3400 err = __tipc_nl_add_sk_publ(skb, cb, p);
3313 if (err) { 3401 if (err) {
3314 *last_publ = p->key; 3402 *last_publ = p->key;
diff --git a/net/tipc/socket.h b/net/tipc/socket.h
index 06fb5944cf76..aae3fd4cd06c 100644
--- a/net/tipc/socket.h
+++ b/net/tipc/socket.h
@@ -49,6 +49,8 @@
49#define RCVBUF_DEF (FLOWCTL_BLK_SZ * 1024 * 2) 49#define RCVBUF_DEF (FLOWCTL_BLK_SZ * 1024 * 2)
50#define RCVBUF_MAX (FLOWCTL_BLK_SZ * 1024 * 16) 50#define RCVBUF_MAX (FLOWCTL_BLK_SZ * 1024 * 16)
51 51
52struct tipc_sock;
53
52int tipc_socket_init(void); 54int tipc_socket_init(void);
53void tipc_socket_stop(void); 55void tipc_socket_stop(void);
54void tipc_sk_rcv(struct net *net, struct sk_buff_head *inputq); 56void tipc_sk_rcv(struct net *net, struct sk_buff_head *inputq);
@@ -59,5 +61,11 @@ int tipc_sk_rht_init(struct net *net);
59void tipc_sk_rht_destroy(struct net *net); 61void tipc_sk_rht_destroy(struct net *net);
60int tipc_nl_sk_dump(struct sk_buff *skb, struct netlink_callback *cb); 62int tipc_nl_sk_dump(struct sk_buff *skb, struct netlink_callback *cb);
61int tipc_nl_publ_dump(struct sk_buff *skb, struct netlink_callback *cb); 63int tipc_nl_publ_dump(struct sk_buff *skb, struct netlink_callback *cb);
62 64int tipc_sk_fill_sock_diag(struct sk_buff *skb, struct tipc_sock *tsk,
65 u32 sk_filter_state,
66 u64 (*tipc_diag_gen_cookie)(struct sock *sk));
67int tipc_nl_sk_walk(struct sk_buff *skb, struct netlink_callback *cb,
68 int (*skb_handler)(struct sk_buff *skb,
69 struct netlink_callback *cb,
70 struct tipc_sock *tsk));
63#endif 71#endif
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c
index 68e26470c516..6925a989569b 100644
--- a/net/tipc/subscr.c
+++ b/net/tipc/subscr.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * net/tipc/subscr.c: TIPC network topology service 2 * net/tipc/subscr.c: TIPC network topology service
3 * 3 *
4 * Copyright (c) 2000-2006, Ericsson AB 4 * Copyright (c) 2000-2017, Ericsson AB
5 * Copyright (c) 2005-2007, 2010-2013, Wind River Systems 5 * Copyright (c) 2005-2007, 2010-2013, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
@@ -38,61 +38,30 @@
38#include "name_table.h" 38#include "name_table.h"
39#include "subscr.h" 39#include "subscr.h"
40 40
41/** 41static void tipc_sub_send_event(struct tipc_subscription *sub,
42 * struct tipc_subscriber - TIPC network topology subscriber 42 u32 found_lower, u32 found_upper,
43 * @kref: reference counter to tipc_subscription object 43 u32 event, u32 port, u32 node)
44 * @conid: connection identifier to server connecting to subscriber
45 * @lock: control access to subscriber
46 * @subscrp_list: list of subscription objects for this subscriber
47 */
48struct tipc_subscriber {
49 struct kref kref;
50 int conid;
51 spinlock_t lock;
52 struct list_head subscrp_list;
53};
54
55static void tipc_subscrb_put(struct tipc_subscriber *subscriber);
56
57/**
58 * htohl - convert value to endianness used by destination
59 * @in: value to convert
60 * @swap: non-zero if endianness must be reversed
61 *
62 * Returns converted value
63 */
64static u32 htohl(u32 in, int swap)
65{
66 return swap ? swab32(in) : in;
67}
68
69static void tipc_subscrp_send_event(struct tipc_subscription *sub,
70 u32 found_lower, u32 found_upper,
71 u32 event, u32 port_ref, u32 node)
72{ 44{
73 struct tipc_net *tn = net_generic(sub->net, tipc_net_id); 45 struct tipc_event *evt = &sub->evt;
74 struct tipc_subscriber *subscriber = sub->subscriber;
75 struct kvec msg_sect;
76 46
77 msg_sect.iov_base = (void *)&sub->evt; 47 if (sub->inactive)
78 msg_sect.iov_len = sizeof(struct tipc_event); 48 return;
79 sub->evt.event = htohl(event, sub->swap); 49 tipc_evt_write(evt, event, event);
80 sub->evt.found_lower = htohl(found_lower, sub->swap); 50 tipc_evt_write(evt, found_lower, found_lower);
81 sub->evt.found_upper = htohl(found_upper, sub->swap); 51 tipc_evt_write(evt, found_upper, found_upper);
82 sub->evt.port.ref = htohl(port_ref, sub->swap); 52 tipc_evt_write(evt, port.ref, port);
83 sub->evt.port.node = htohl(node, sub->swap); 53 tipc_evt_write(evt, port.node, node);
84 tipc_conn_sendmsg(tn->topsrv, subscriber->conid, NULL, 54 tipc_topsrv_queue_evt(sub->net, sub->conid, event, evt);
85 msg_sect.iov_base, msg_sect.iov_len);
86} 55}
87 56
88/** 57/**
89 * tipc_subscrp_check_overlap - test for subscription overlap with the 58 * tipc_sub_check_overlap - test for subscription overlap with the
90 * given values 59 * given values
91 * 60 *
92 * Returns 1 if there is overlap, otherwise 0. 61 * Returns 1 if there is overlap, otherwise 0.
93 */ 62 */
94int tipc_subscrp_check_overlap(struct tipc_name_seq *seq, u32 found_lower, 63int tipc_sub_check_overlap(struct tipc_name_seq *seq, u32 found_lower,
95 u32 found_upper) 64 u32 found_upper)
96{ 65{
97 if (found_lower < seq->lower) 66 if (found_lower < seq->lower)
98 found_lower = seq->lower; 67 found_lower = seq->lower;
@@ -103,298 +72,98 @@ int tipc_subscrp_check_overlap(struct tipc_name_seq *seq, u32 found_lower,
103 return 1; 72 return 1;
104} 73}
105 74
106u32 tipc_subscrp_convert_seq_type(u32 type, int swap) 75void tipc_sub_report_overlap(struct tipc_subscription *sub,
107{ 76 u32 found_lower, u32 found_upper,
108 return htohl(type, swap); 77 u32 event, u32 port, u32 node,
109} 78 u32 scope, int must)
110
111void tipc_subscrp_convert_seq(struct tipc_name_seq *in, int swap,
112 struct tipc_name_seq *out)
113{
114 out->type = htohl(in->type, swap);
115 out->lower = htohl(in->lower, swap);
116 out->upper = htohl(in->upper, swap);
117}
118
119void tipc_subscrp_report_overlap(struct tipc_subscription *sub, u32 found_lower,
120 u32 found_upper, u32 event, u32 port_ref,
121 u32 node, u32 scope, int must)
122{ 79{
123 u32 filter = htohl(sub->evt.s.filter, sub->swap); 80 struct tipc_subscr *s = &sub->evt.s;
81 u32 filter = tipc_sub_read(s, filter);
124 struct tipc_name_seq seq; 82 struct tipc_name_seq seq;
125 83
126 tipc_subscrp_convert_seq(&sub->evt.s.seq, sub->swap, &seq); 84 seq.type = tipc_sub_read(s, seq.type);
127 if (!tipc_subscrp_check_overlap(&seq, found_lower, found_upper)) 85 seq.lower = tipc_sub_read(s, seq.lower);
86 seq.upper = tipc_sub_read(s, seq.upper);
87
88 if (!tipc_sub_check_overlap(&seq, found_lower, found_upper))
128 return; 89 return;
90
129 if (!must && !(filter & TIPC_SUB_PORTS)) 91 if (!must && !(filter & TIPC_SUB_PORTS))
130 return; 92 return;
131 if (filter & TIPC_SUB_CLUSTER_SCOPE && scope == TIPC_NODE_SCOPE) 93 if (filter & TIPC_SUB_CLUSTER_SCOPE && scope == TIPC_NODE_SCOPE)
132 return; 94 return;
133 if (filter & TIPC_SUB_NODE_SCOPE && scope != TIPC_NODE_SCOPE) 95 if (filter & TIPC_SUB_NODE_SCOPE && scope != TIPC_NODE_SCOPE)
134 return; 96 return;
135 97 spin_lock(&sub->lock);
136 tipc_subscrp_send_event(sub, found_lower, found_upper, event, port_ref, 98 tipc_sub_send_event(sub, found_lower, found_upper,
137 node); 99 event, port, node);
100 spin_unlock(&sub->lock);
138} 101}
139 102
140static void tipc_subscrp_timeout(struct timer_list *t) 103static void tipc_sub_timeout(struct timer_list *t)
141{ 104{
142 struct tipc_subscription *sub = from_timer(sub, t, timer); 105 struct tipc_subscription *sub = from_timer(sub, t, timer);
143 struct tipc_subscriber *subscriber = sub->subscriber; 106 struct tipc_subscr *s = &sub->evt.s;
144
145 spin_lock_bh(&subscriber->lock);
146 tipc_nametbl_unsubscribe(sub);
147 list_del(&sub->subscrp_list);
148 spin_unlock_bh(&subscriber->lock);
149
150 /* Notify subscriber of timeout */
151 tipc_subscrp_send_event(sub, sub->evt.s.seq.lower, sub->evt.s.seq.upper,
152 TIPC_SUBSCR_TIMEOUT, 0, 0);
153
154 tipc_subscrp_put(sub);
155}
156
157static void tipc_subscrb_kref_release(struct kref *kref)
158{
159 kfree(container_of(kref,struct tipc_subscriber, kref));
160}
161
162static void tipc_subscrb_put(struct tipc_subscriber *subscriber)
163{
164 kref_put(&subscriber->kref, tipc_subscrb_kref_release);
165}
166 107
167static void tipc_subscrb_get(struct tipc_subscriber *subscriber) 108 spin_lock(&sub->lock);
168{ 109 tipc_sub_send_event(sub, s->seq.lower, s->seq.upper,
169 kref_get(&subscriber->kref); 110 TIPC_SUBSCR_TIMEOUT, 0, 0);
111 sub->inactive = true;
112 spin_unlock(&sub->lock);
170} 113}
171 114
172static void tipc_subscrp_kref_release(struct kref *kref) 115static void tipc_sub_kref_release(struct kref *kref)
173{ 116{
174 struct tipc_subscription *sub = container_of(kref, 117 kfree(container_of(kref, struct tipc_subscription, kref));
175 struct tipc_subscription,
176 kref);
177 struct tipc_net *tn = net_generic(sub->net, tipc_net_id);
178 struct tipc_subscriber *subscriber = sub->subscriber;
179
180 atomic_dec(&tn->subscription_count);
181 kfree(sub);
182 tipc_subscrb_put(subscriber);
183} 118}
184 119
185void tipc_subscrp_put(struct tipc_subscription *subscription) 120void tipc_sub_put(struct tipc_subscription *subscription)
186{ 121{
187 kref_put(&subscription->kref, tipc_subscrp_kref_release); 122 kref_put(&subscription->kref, tipc_sub_kref_release);
188} 123}
189 124
190void tipc_subscrp_get(struct tipc_subscription *subscription) 125void tipc_sub_get(struct tipc_subscription *subscription)
191{ 126{
192 kref_get(&subscription->kref); 127 kref_get(&subscription->kref);
193} 128}
194 129
195/* tipc_subscrb_subscrp_delete - delete a specific subscription or all 130struct tipc_subscription *tipc_sub_subscribe(struct net *net,
196 * subscriptions for a given subscriber. 131 struct tipc_subscr *s,
197 */ 132 int conid)
198static void tipc_subscrb_subscrp_delete(struct tipc_subscriber *subscriber,
199 struct tipc_subscr *s)
200{
201 struct list_head *subscription_list = &subscriber->subscrp_list;
202 struct tipc_subscription *sub, *temp;
203 u32 timeout;
204
205 spin_lock_bh(&subscriber->lock);
206 list_for_each_entry_safe(sub, temp, subscription_list, subscrp_list) {
207 if (s && memcmp(s, &sub->evt.s, sizeof(struct tipc_subscr)))
208 continue;
209
210 timeout = htohl(sub->evt.s.timeout, sub->swap);
211 if (timeout == TIPC_WAIT_FOREVER || del_timer(&sub->timer)) {
212 tipc_nametbl_unsubscribe(sub);
213 list_del(&sub->subscrp_list);
214 tipc_subscrp_put(sub);
215 }
216
217 if (s)
218 break;
219 }
220 spin_unlock_bh(&subscriber->lock);
221}
222
223static struct tipc_subscriber *tipc_subscrb_create(int conid)
224{
225 struct tipc_subscriber *subscriber;
226
227 subscriber = kzalloc(sizeof(*subscriber), GFP_ATOMIC);
228 if (!subscriber) {
229 pr_warn("Subscriber rejected, no memory\n");
230 return NULL;
231 }
232 INIT_LIST_HEAD(&subscriber->subscrp_list);
233 kref_init(&subscriber->kref);
234 subscriber->conid = conid;
235 spin_lock_init(&subscriber->lock);
236
237 return subscriber;
238}
239
240static void tipc_subscrb_delete(struct tipc_subscriber *subscriber)
241{
242 tipc_subscrb_subscrp_delete(subscriber, NULL);
243 tipc_subscrb_put(subscriber);
244}
245
246static void tipc_subscrp_cancel(struct tipc_subscr *s,
247 struct tipc_subscriber *subscriber)
248{
249 tipc_subscrb_get(subscriber);
250 tipc_subscrb_subscrp_delete(subscriber, s);
251 tipc_subscrb_put(subscriber);
252}
253
254static struct tipc_subscription *tipc_subscrp_create(struct net *net,
255 struct tipc_subscr *s,
256 int swap)
257{ 133{
258 struct tipc_net *tn = net_generic(net, tipc_net_id); 134 u32 filter = tipc_sub_read(s, filter);
259 struct tipc_subscription *sub; 135 struct tipc_subscription *sub;
260 u32 filter = htohl(s->filter, swap); 136 u32 timeout;
261 137
262 /* Refuse subscription if global limit exceeded */ 138 if ((filter & TIPC_SUB_PORTS && filter & TIPC_SUB_SERVICE) ||
263 if (atomic_read(&tn->subscription_count) >= TIPC_MAX_SUBSCRIPTIONS) { 139 (tipc_sub_read(s, seq.lower) > tipc_sub_read(s, seq.upper))) {
264 pr_warn("Subscription rejected, limit reached (%u)\n", 140 pr_warn("Subscription rejected, illegal request\n");
265 TIPC_MAX_SUBSCRIPTIONS);
266 return NULL; 141 return NULL;
267 } 142 }
268
269 /* Allocate subscription object */
270 sub = kmalloc(sizeof(*sub), GFP_ATOMIC); 143 sub = kmalloc(sizeof(*sub), GFP_ATOMIC);
271 if (!sub) { 144 if (!sub) {
272 pr_warn("Subscription rejected, no memory\n"); 145 pr_warn("Subscription rejected, no memory\n");
273 return NULL; 146 return NULL;
274 } 147 }
275
276 /* Initialize subscription object */
277 sub->net = net; 148 sub->net = net;
278 if (((filter & TIPC_SUB_PORTS) && (filter & TIPC_SUB_SERVICE)) || 149 sub->conid = conid;
279 (htohl(s->seq.lower, swap) > htohl(s->seq.upper, swap))) { 150 sub->inactive = false;
280 pr_warn("Subscription rejected, illegal request\n");
281 kfree(sub);
282 return NULL;
283 }
284
285 sub->swap = swap;
286 memcpy(&sub->evt.s, s, sizeof(*s)); 151 memcpy(&sub->evt.s, s, sizeof(*s));
287 atomic_inc(&tn->subscription_count); 152 spin_lock_init(&sub->lock);
288 kref_init(&sub->kref); 153 kref_init(&sub->kref);
289 return sub; 154 tipc_nametbl_subscribe(sub);
290} 155 timer_setup(&sub->timer, tipc_sub_timeout, 0);
291 156 timeout = tipc_sub_read(&sub->evt.s, timeout);
292static int tipc_subscrp_subscribe(struct net *net, struct tipc_subscr *s,
293 struct tipc_subscriber *subscriber, int swap,
294 bool status)
295{
296 struct tipc_subscription *sub = NULL;
297 u32 timeout;
298
299 sub = tipc_subscrp_create(net, s, swap);
300 if (!sub)
301 return -1;
302
303 spin_lock_bh(&subscriber->lock);
304 list_add(&sub->subscrp_list, &subscriber->subscrp_list);
305 sub->subscriber = subscriber;
306 tipc_nametbl_subscribe(sub, status);
307 tipc_subscrb_get(subscriber);
308 spin_unlock_bh(&subscriber->lock);
309
310 timer_setup(&sub->timer, tipc_subscrp_timeout, 0);
311 timeout = htohl(sub->evt.s.timeout, swap);
312
313 if (timeout != TIPC_WAIT_FOREVER) 157 if (timeout != TIPC_WAIT_FOREVER)
314 mod_timer(&sub->timer, jiffies + msecs_to_jiffies(timeout)); 158 mod_timer(&sub->timer, jiffies + msecs_to_jiffies(timeout));
315 return 0; 159 return sub;
316}
317
318/* Handle one termination request for the subscriber */
319static void tipc_subscrb_release_cb(int conid, void *usr_data)
320{
321 tipc_subscrb_delete((struct tipc_subscriber *)usr_data);
322}
323
324/* Handle one request to create a new subscription for the subscriber */
325static int tipc_subscrb_rcv_cb(struct net *net, int conid,
326 struct sockaddr_tipc *addr, void *usr_data,
327 void *buf, size_t len)
328{
329 struct tipc_subscriber *subscriber = usr_data;
330 struct tipc_subscr *s = (struct tipc_subscr *)buf;
331 bool status;
332 int swap;
333
334 /* Determine subscriber's endianness */
335 swap = !(s->filter & (TIPC_SUB_PORTS | TIPC_SUB_SERVICE |
336 TIPC_SUB_CANCEL));
337
338 /* Detect & process a subscription cancellation request */
339 if (s->filter & htohl(TIPC_SUB_CANCEL, swap)) {
340 s->filter &= ~htohl(TIPC_SUB_CANCEL, swap);
341 tipc_subscrp_cancel(s, subscriber);
342 return 0;
343 }
344 status = !(s->filter & htohl(TIPC_SUB_NO_STATUS, swap));
345 return tipc_subscrp_subscribe(net, s, subscriber, swap, status);
346}
347
348/* Handle one request to establish a new subscriber */
349static void *tipc_subscrb_connect_cb(int conid)
350{
351 return (void *)tipc_subscrb_create(conid);
352}
353
354int tipc_topsrv_start(struct net *net)
355{
356 struct tipc_net *tn = net_generic(net, tipc_net_id);
357 const char name[] = "topology_server";
358 struct tipc_server *topsrv;
359 struct sockaddr_tipc *saddr;
360
361 saddr = kzalloc(sizeof(*saddr), GFP_ATOMIC);
362 if (!saddr)
363 return -ENOMEM;
364 saddr->family = AF_TIPC;
365 saddr->addrtype = TIPC_ADDR_NAMESEQ;
366 saddr->addr.nameseq.type = TIPC_TOP_SRV;
367 saddr->addr.nameseq.lower = TIPC_TOP_SRV;
368 saddr->addr.nameseq.upper = TIPC_TOP_SRV;
369 saddr->scope = TIPC_NODE_SCOPE;
370
371 topsrv = kzalloc(sizeof(*topsrv), GFP_ATOMIC);
372 if (!topsrv) {
373 kfree(saddr);
374 return -ENOMEM;
375 }
376 topsrv->net = net;
377 topsrv->saddr = saddr;
378 topsrv->imp = TIPC_CRITICAL_IMPORTANCE;
379 topsrv->type = SOCK_SEQPACKET;
380 topsrv->max_rcvbuf_size = sizeof(struct tipc_subscr);
381 topsrv->tipc_conn_recvmsg = tipc_subscrb_rcv_cb;
382 topsrv->tipc_conn_new = tipc_subscrb_connect_cb;
383 topsrv->tipc_conn_release = tipc_subscrb_release_cb;
384
385 strncpy(topsrv->name, name, strlen(name) + 1);
386 tn->topsrv = topsrv;
387 atomic_set(&tn->subscription_count, 0);
388
389 return tipc_server_start(topsrv);
390} 160}
391 161
392void tipc_topsrv_stop(struct net *net) 162void tipc_sub_unsubscribe(struct tipc_subscription *sub)
393{ 163{
394 struct tipc_net *tn = net_generic(net, tipc_net_id); 164 tipc_nametbl_unsubscribe(sub);
395 struct tipc_server *topsrv = tn->topsrv; 165 if (sub->evt.s.timeout != TIPC_WAIT_FOREVER)
396 166 del_timer_sync(&sub->timer);
397 tipc_server_stop(topsrv); 167 list_del(&sub->sub_list);
398 kfree(topsrv->saddr); 168 tipc_sub_put(sub);
399 kfree(topsrv);
400} 169}
diff --git a/net/tipc/subscr.h b/net/tipc/subscr.h
index f3edca775d9f..8b2d22b18f22 100644
--- a/net/tipc/subscr.h
+++ b/net/tipc/subscr.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * net/tipc/subscr.h: Include file for TIPC network topology service 2 * net/tipc/subscr.h: Include file for TIPC network topology service
3 * 3 *
4 * Copyright (c) 2003-2006, Ericsson AB 4 * Copyright (c) 2003-2017, Ericsson AB
5 * Copyright (c) 2005-2007, 2012-2013, Wind River Systems 5 * Copyright (c) 2005-2007, 2012-2013, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
@@ -37,48 +37,72 @@
37#ifndef _TIPC_SUBSCR_H 37#ifndef _TIPC_SUBSCR_H
38#define _TIPC_SUBSCR_H 38#define _TIPC_SUBSCR_H
39 39
40#include "server.h" 40#include "topsrv.h"
41 41
42#define TIPC_MAX_SUBSCRIPTIONS 65535 42#define TIPC_MAX_SUBSCR 65535
43#define TIPC_MAX_PUBLICATIONS 65535 43#define TIPC_MAX_PUBLICATIONS 65535
44 44
45struct tipc_subscription; 45struct tipc_subscription;
46struct tipc_subscriber; 46struct tipc_conn;
47 47
48/** 48/**
49 * struct tipc_subscription - TIPC network topology subscription object 49 * struct tipc_subscription - TIPC network topology subscription object
50 * @subscriber: pointer to its subscriber 50 * @subscriber: pointer to its subscriber
51 * @seq: name sequence associated with subscription 51 * @seq: name sequence associated with subscription
52 * @net: point to network namespace
53 * @timer: timer governing subscription duration (optional) 52 * @timer: timer governing subscription duration (optional)
54 * @nameseq_list: adjacent subscriptions in name sequence's subscription list 53 * @nameseq_list: adjacent subscriptions in name sequence's subscription list
55 * @subscrp_list: adjacent subscriptions in subscriber's subscription list 54 * @sub_list: adjacent subscriptions in subscriber's subscription list
56 * @swap: indicates if subscriber uses opposite endianness in its messages
57 * @evt: template for events generated by subscription 55 * @evt: template for events generated by subscription
58 */ 56 */
59struct tipc_subscription { 57struct tipc_subscription {
60 struct kref kref; 58 struct kref kref;
61 struct tipc_subscriber *subscriber;
62 struct net *net; 59 struct net *net;
63 struct timer_list timer; 60 struct timer_list timer;
64 struct list_head nameseq_list; 61 struct list_head nameseq_list;
65 struct list_head subscrp_list; 62 struct list_head sub_list;
66 int swap;
67 struct tipc_event evt; 63 struct tipc_event evt;
64 int conid;
65 bool inactive;
66 spinlock_t lock; /* serialize up/down and timer events */
68}; 67};
69 68
70int tipc_subscrp_check_overlap(struct tipc_name_seq *seq, u32 found_lower, 69struct tipc_subscription *tipc_sub_subscribe(struct net *net,
71 u32 found_upper); 70 struct tipc_subscr *s,
72void tipc_subscrp_report_overlap(struct tipc_subscription *sub, 71 int conid);
73 u32 found_lower, u32 found_upper, u32 event, 72void tipc_sub_unsubscribe(struct tipc_subscription *sub);
74 u32 port_ref, u32 node, u32 scope, int must); 73
75void tipc_subscrp_convert_seq(struct tipc_name_seq *in, int swap, 74int tipc_sub_check_overlap(struct tipc_name_seq *seq, u32 found_lower,
76 struct tipc_name_seq *out); 75 u32 found_upper);
77u32 tipc_subscrp_convert_seq_type(u32 type, int swap); 76void tipc_sub_report_overlap(struct tipc_subscription *sub,
77 u32 found_lower, u32 found_upper,
78 u32 event, u32 port, u32 node,
79 u32 scope, int must);
78int tipc_topsrv_start(struct net *net); 80int tipc_topsrv_start(struct net *net);
79void tipc_topsrv_stop(struct net *net); 81void tipc_topsrv_stop(struct net *net);
80 82
81void tipc_subscrp_put(struct tipc_subscription *subscription); 83void tipc_sub_put(struct tipc_subscription *subscription);
82void tipc_subscrp_get(struct tipc_subscription *subscription); 84void tipc_sub_get(struct tipc_subscription *subscription);
85
86#define TIPC_FILTER_MASK (TIPC_SUB_PORTS | TIPC_SUB_SERVICE | TIPC_SUB_CANCEL)
87
88/* tipc_sub_read - return field_ of struct sub_ in host endian format
89 */
90#define tipc_sub_read(sub_, field_) \
91 ({ \
92 struct tipc_subscr *sub__ = sub_; \
93 u32 val__ = (sub__)->field_; \
94 int swap_ = !((sub__)->filter & TIPC_FILTER_MASK); \
95 (swap_ ? swab32(val__) : val__); \
96 })
97
98/* tipc_evt_write - write val_ to field_ of struct evt_ in user endian format
99 */
100#define tipc_evt_write(evt_, field_, val_) \
101 ({ \
102 struct tipc_event *evt__ = evt_; \
103 u32 val__ = val_; \
104 int swap_ = !((evt__)->s.filter & (TIPC_FILTER_MASK)); \
105 (evt__)->field_ = swap_ ? swab32(val__) : val__; \
106 })
83 107
84#endif 108#endif
diff --git a/net/tipc/topsrv.c b/net/tipc/topsrv.c
new file mode 100644
index 000000000000..c8e34ef22c30
--- /dev/null
+++ b/net/tipc/topsrv.c
@@ -0,0 +1,703 @@
1/*
2 * net/tipc/server.c: TIPC server infrastructure
3 *
4 * Copyright (c) 2012-2013, Wind River Systems
5 * Copyright (c) 2017-2018, Ericsson AB
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the names of the copyright holders nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * Alternatively, this software may be distributed under the terms of the
21 * GNU General Public License ("GPL") version 2 as published by the Free
22 * Software Foundation.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 */
36
37#include "subscr.h"
38#include "topsrv.h"
39#include "core.h"
40#include "socket.h"
41#include "addr.h"
42#include "msg.h"
43#include <net/sock.h>
44#include <linux/module.h>
45
46/* Number of messages to send before rescheduling */
47#define MAX_SEND_MSG_COUNT 25
48#define MAX_RECV_MSG_COUNT 25
49#define CF_CONNECTED 1
50#define CF_SERVER 2
51
52#define TIPC_SERVER_NAME_LEN 32
53
54/**
55 * struct tipc_topsrv - TIPC server structure
56 * @conn_idr: identifier set of connection
57 * @idr_lock: protect the connection identifier set
58 * @idr_in_use: amount of allocated identifier entry
59 * @net: network namspace instance
60 * @rcvbuf_cache: memory cache of server receive buffer
61 * @rcv_wq: receive workqueue
62 * @send_wq: send workqueue
63 * @max_rcvbuf_size: maximum permitted receive message length
64 * @tipc_conn_new: callback will be called when new connection is incoming
65 * @tipc_conn_release: callback will be called before releasing the connection
66 * @tipc_conn_recvmsg: callback will be called when message arrives
67 * @name: server name
68 * @imp: message importance
69 * @type: socket type
70 */
71struct tipc_topsrv {
72 struct idr conn_idr;
73 spinlock_t idr_lock; /* for idr list */
74 int idr_in_use;
75 struct net *net;
76 struct work_struct awork;
77 struct workqueue_struct *rcv_wq;
78 struct workqueue_struct *send_wq;
79 int max_rcvbuf_size;
80 struct socket *listener;
81 char name[TIPC_SERVER_NAME_LEN];
82};
83
84/**
85 * struct tipc_conn - TIPC connection structure
86 * @kref: reference counter to connection object
87 * @conid: connection identifier
88 * @sock: socket handler associated with connection
89 * @flags: indicates connection state
90 * @server: pointer to connected server
91 * @sub_list: lsit to all pertaing subscriptions
92 * @sub_lock: lock protecting the subscription list
93 * @outqueue_lock: control access to the outqueue
94 * @rwork: receive work item
95 * @rx_action: what to do when connection socket is active
96 * @outqueue: pointer to first outbound message in queue
97 * @outqueue_lock: control access to the outqueue
98 * @swork: send work item
99 */
100struct tipc_conn {
101 struct kref kref;
102 int conid;
103 struct socket *sock;
104 unsigned long flags;
105 struct tipc_topsrv *server;
106 struct list_head sub_list;
107 spinlock_t sub_lock; /* for subscription list */
108 struct work_struct rwork;
109 struct list_head outqueue;
110 spinlock_t outqueue_lock; /* for outqueue */
111 struct work_struct swork;
112};
113
114/* An entry waiting to be sent */
115struct outqueue_entry {
116 bool inactive;
117 struct tipc_event evt;
118 struct list_head list;
119};
120
121static void tipc_conn_recv_work(struct work_struct *work);
122static void tipc_conn_send_work(struct work_struct *work);
123static void tipc_topsrv_kern_evt(struct net *net, struct tipc_event *evt);
124static void tipc_conn_delete_sub(struct tipc_conn *con, struct tipc_subscr *s);
125
126static bool connected(struct tipc_conn *con)
127{
128 return con && test_bit(CF_CONNECTED, &con->flags);
129}
130
131static void tipc_conn_kref_release(struct kref *kref)
132{
133 struct tipc_conn *con = container_of(kref, struct tipc_conn, kref);
134 struct tipc_topsrv *s = con->server;
135 struct outqueue_entry *e, *safe;
136
137 spin_lock_bh(&s->idr_lock);
138 idr_remove(&s->conn_idr, con->conid);
139 s->idr_in_use--;
140 spin_unlock_bh(&s->idr_lock);
141 if (con->sock)
142 sock_release(con->sock);
143
144 spin_lock_bh(&con->outqueue_lock);
145 list_for_each_entry_safe(e, safe, &con->outqueue, list) {
146 list_del(&e->list);
147 kfree(e);
148 }
149 spin_unlock_bh(&con->outqueue_lock);
150 kfree(con);
151}
152
153static void conn_put(struct tipc_conn *con)
154{
155 kref_put(&con->kref, tipc_conn_kref_release);
156}
157
158static void conn_get(struct tipc_conn *con)
159{
160 kref_get(&con->kref);
161}
162
163static void tipc_conn_close(struct tipc_conn *con)
164{
165 struct sock *sk = con->sock->sk;
166 bool disconnect = false;
167
168 write_lock_bh(&sk->sk_callback_lock);
169 disconnect = test_and_clear_bit(CF_CONNECTED, &con->flags);
170
171 if (disconnect) {
172 sk->sk_user_data = NULL;
173 tipc_conn_delete_sub(con, NULL);
174 }
175 write_unlock_bh(&sk->sk_callback_lock);
176
177 /* Handle concurrent calls from sending and receiving threads */
178 if (!disconnect)
179 return;
180
181 /* Don't flush pending works, -just let them expire */
182 kernel_sock_shutdown(con->sock, SHUT_RDWR);
183
184 conn_put(con);
185}
186
187static struct tipc_conn *tipc_conn_alloc(struct tipc_topsrv *s)
188{
189 struct tipc_conn *con;
190 int ret;
191
192 con = kzalloc(sizeof(*con), GFP_ATOMIC);
193 if (!con)
194 return ERR_PTR(-ENOMEM);
195
196 kref_init(&con->kref);
197 INIT_LIST_HEAD(&con->outqueue);
198 INIT_LIST_HEAD(&con->sub_list);
199 spin_lock_init(&con->outqueue_lock);
200 spin_lock_init(&con->sub_lock);
201 INIT_WORK(&con->swork, tipc_conn_send_work);
202 INIT_WORK(&con->rwork, tipc_conn_recv_work);
203
204 spin_lock_bh(&s->idr_lock);
205 ret = idr_alloc(&s->conn_idr, con, 0, 0, GFP_ATOMIC);
206 if (ret < 0) {
207 kfree(con);
208 spin_unlock_bh(&s->idr_lock);
209 return ERR_PTR(-ENOMEM);
210 }
211 con->conid = ret;
212 s->idr_in_use++;
213 spin_unlock_bh(&s->idr_lock);
214
215 set_bit(CF_CONNECTED, &con->flags);
216 con->server = s;
217
218 return con;
219}
220
221static struct tipc_conn *tipc_conn_lookup(struct tipc_topsrv *s, int conid)
222{
223 struct tipc_conn *con;
224
225 spin_lock_bh(&s->idr_lock);
226 con = idr_find(&s->conn_idr, conid);
227 if (!connected(con) || !kref_get_unless_zero(&con->kref))
228 con = NULL;
229 spin_unlock_bh(&s->idr_lock);
230 return con;
231}
232
233/* tipc_conn_delete_sub - delete a specific or all subscriptions
234 * for a given subscriber
235 */
236static void tipc_conn_delete_sub(struct tipc_conn *con, struct tipc_subscr *s)
237{
238 struct tipc_net *tn = tipc_net(con->server->net);
239 struct list_head *sub_list = &con->sub_list;
240 struct tipc_subscription *sub, *tmp;
241
242 spin_lock_bh(&con->sub_lock);
243 list_for_each_entry_safe(sub, tmp, sub_list, sub_list) {
244 if (!s || !memcmp(s, &sub->evt.s, sizeof(*s))) {
245 tipc_sub_unsubscribe(sub);
246 atomic_dec(&tn->subscription_count);
247 } else if (s) {
248 break;
249 }
250 }
251 spin_unlock_bh(&con->sub_lock);
252}
253
254static void tipc_conn_send_to_sock(struct tipc_conn *con)
255{
256 struct list_head *queue = &con->outqueue;
257 struct tipc_topsrv *srv = con->server;
258 struct outqueue_entry *e;
259 struct tipc_event *evt;
260 struct msghdr msg;
261 struct kvec iov;
262 int count = 0;
263 int ret;
264
265 spin_lock_bh(&con->outqueue_lock);
266
267 while (!list_empty(queue)) {
268 e = list_first_entry(queue, struct outqueue_entry, list);
269 evt = &e->evt;
270 spin_unlock_bh(&con->outqueue_lock);
271
272 if (e->inactive)
273 tipc_conn_delete_sub(con, &evt->s);
274
275 memset(&msg, 0, sizeof(msg));
276 msg.msg_flags = MSG_DONTWAIT;
277 iov.iov_base = evt;
278 iov.iov_len = sizeof(*evt);
279 msg.msg_name = NULL;
280
281 if (con->sock) {
282 ret = kernel_sendmsg(con->sock, &msg, &iov,
283 1, sizeof(*evt));
284 if (ret == -EWOULDBLOCK || ret == 0) {
285 cond_resched();
286 return;
287 } else if (ret < 0) {
288 return tipc_conn_close(con);
289 }
290 } else {
291 tipc_topsrv_kern_evt(srv->net, evt);
292 }
293
294 /* Don't starve users filling buffers */
295 if (++count >= MAX_SEND_MSG_COUNT) {
296 cond_resched();
297 count = 0;
298 }
299 spin_lock_bh(&con->outqueue_lock);
300 list_del(&e->list);
301 kfree(e);
302 }
303 spin_unlock_bh(&con->outqueue_lock);
304}
305
306static void tipc_conn_send_work(struct work_struct *work)
307{
308 struct tipc_conn *con = container_of(work, struct tipc_conn, swork);
309
310 if (connected(con))
311 tipc_conn_send_to_sock(con);
312
313 conn_put(con);
314}
315
316/* tipc_conn_queue_evt() - interrupt level call from a subscription instance
317 * The queued work is launched into tipc_send_work()->tipc_send_to_sock()
318 */
319void tipc_topsrv_queue_evt(struct net *net, int conid,
320 u32 event, struct tipc_event *evt)
321{
322 struct tipc_topsrv *srv = tipc_topsrv(net);
323 struct outqueue_entry *e;
324 struct tipc_conn *con;
325
326 con = tipc_conn_lookup(srv, conid);
327 if (!con)
328 return;
329
330 if (!connected(con))
331 goto err;
332
333 e = kmalloc(sizeof(*e), GFP_ATOMIC);
334 if (!e)
335 goto err;
336 e->inactive = (event == TIPC_SUBSCR_TIMEOUT);
337 memcpy(&e->evt, evt, sizeof(*evt));
338 spin_lock_bh(&con->outqueue_lock);
339 list_add_tail(&e->list, &con->outqueue);
340 spin_unlock_bh(&con->outqueue_lock);
341
342 if (queue_work(srv->send_wq, &con->swork))
343 return;
344err:
345 conn_put(con);
346}
347
348/* tipc_conn_write_space - interrupt callback after a sendmsg EAGAIN
349 * Indicates that there now is more space in the send buffer
350 * The queued work is launched into tipc_send_work()->tipc_conn_send_to_sock()
351 */
352static void tipc_conn_write_space(struct sock *sk)
353{
354 struct tipc_conn *con;
355
356 read_lock_bh(&sk->sk_callback_lock);
357 con = sk->sk_user_data;
358 if (connected(con)) {
359 conn_get(con);
360 if (!queue_work(con->server->send_wq, &con->swork))
361 conn_put(con);
362 }
363 read_unlock_bh(&sk->sk_callback_lock);
364}
365
366static int tipc_conn_rcv_sub(struct tipc_topsrv *srv,
367 struct tipc_conn *con,
368 struct tipc_subscr *s)
369{
370 struct tipc_net *tn = tipc_net(srv->net);
371 struct tipc_subscription *sub;
372
373 if (tipc_sub_read(s, filter) & TIPC_SUB_CANCEL) {
374 tipc_conn_delete_sub(con, s);
375 return 0;
376 }
377 if (atomic_read(&tn->subscription_count) >= TIPC_MAX_SUBSCR) {
378 pr_warn("Subscription rejected, max (%u)\n", TIPC_MAX_SUBSCR);
379 return -1;
380 }
381 sub = tipc_sub_subscribe(srv->net, s, con->conid);
382 if (!sub)
383 return -1;
384 atomic_inc(&tn->subscription_count);
385 spin_lock_bh(&con->sub_lock);
386 list_add(&sub->sub_list, &con->sub_list);
387 spin_unlock_bh(&con->sub_lock);
388 return 0;
389}
390
391static int tipc_conn_rcv_from_sock(struct tipc_conn *con)
392{
393 struct tipc_topsrv *srv = con->server;
394 struct sock *sk = con->sock->sk;
395 struct msghdr msg = {};
396 struct tipc_subscr s;
397 struct kvec iov;
398 int ret;
399
400 iov.iov_base = &s;
401 iov.iov_len = sizeof(s);
402 msg.msg_name = NULL;
403 iov_iter_kvec(&msg.msg_iter, READ | ITER_KVEC, &iov, 1, iov.iov_len);
404 ret = sock_recvmsg(con->sock, &msg, MSG_DONTWAIT);
405 if (ret == -EWOULDBLOCK)
406 return -EWOULDBLOCK;
407 if (ret > 0) {
408 read_lock_bh(&sk->sk_callback_lock);
409 ret = tipc_conn_rcv_sub(srv, con, &s);
410 read_unlock_bh(&sk->sk_callback_lock);
411 }
412 if (ret < 0)
413 tipc_conn_close(con);
414
415 return ret;
416}
417
418static void tipc_conn_recv_work(struct work_struct *work)
419{
420 struct tipc_conn *con = container_of(work, struct tipc_conn, rwork);
421 int count = 0;
422
423 while (connected(con)) {
424 if (tipc_conn_rcv_from_sock(con))
425 break;
426
427 /* Don't flood Rx machine */
428 if (++count >= MAX_RECV_MSG_COUNT) {
429 cond_resched();
430 count = 0;
431 }
432 }
433 conn_put(con);
434}
435
436/* tipc_conn_data_ready - interrupt callback indicating the socket has data
437 * The queued work is launched into tipc_recv_work()->tipc_conn_rcv_from_sock()
438 */
439static void tipc_conn_data_ready(struct sock *sk)
440{
441 struct tipc_conn *con;
442
443 read_lock_bh(&sk->sk_callback_lock);
444 con = sk->sk_user_data;
445 if (connected(con)) {
446 conn_get(con);
447 if (!queue_work(con->server->rcv_wq, &con->rwork))
448 conn_put(con);
449 }
450 read_unlock_bh(&sk->sk_callback_lock);
451}
452
453static void tipc_topsrv_accept(struct work_struct *work)
454{
455 struct tipc_topsrv *srv = container_of(work, struct tipc_topsrv, awork);
456 struct socket *lsock = srv->listener;
457 struct socket *newsock;
458 struct tipc_conn *con;
459 struct sock *newsk;
460 int ret;
461
462 while (1) {
463 ret = kernel_accept(lsock, &newsock, O_NONBLOCK);
464 if (ret < 0)
465 return;
466 con = tipc_conn_alloc(srv);
467 if (IS_ERR(con)) {
468 ret = PTR_ERR(con);
469 sock_release(newsock);
470 return;
471 }
472 /* Register callbacks */
473 newsk = newsock->sk;
474 write_lock_bh(&newsk->sk_callback_lock);
475 newsk->sk_data_ready = tipc_conn_data_ready;
476 newsk->sk_write_space = tipc_conn_write_space;
477 newsk->sk_user_data = con;
478 con->sock = newsock;
479 write_unlock_bh(&newsk->sk_callback_lock);
480
481 /* Wake up receive process in case of 'SYN+' message */
482 newsk->sk_data_ready(newsk);
483 }
484}
485
486/* tipc_toprsv_listener_data_ready - interrupt callback with connection request
487 * The queued job is launched into tipc_topsrv_accept()
488 */
489static void tipc_topsrv_listener_data_ready(struct sock *sk)
490{
491 struct tipc_topsrv *srv;
492
493 read_lock_bh(&sk->sk_callback_lock);
494 srv = sk->sk_user_data;
495 if (srv->listener)
496 queue_work(srv->rcv_wq, &srv->awork);
497 read_unlock_bh(&sk->sk_callback_lock);
498}
499
500static int tipc_topsrv_create_listener(struct tipc_topsrv *srv)
501{
502 int imp = TIPC_CRITICAL_IMPORTANCE;
503 struct socket *lsock = NULL;
504 struct sockaddr_tipc saddr;
505 struct sock *sk;
506 int rc;
507
508 rc = sock_create_kern(srv->net, AF_TIPC, SOCK_SEQPACKET, 0, &lsock);
509 if (rc < 0)
510 return rc;
511
512 srv->listener = lsock;
513 sk = lsock->sk;
514 write_lock_bh(&sk->sk_callback_lock);
515 sk->sk_data_ready = tipc_topsrv_listener_data_ready;
516 sk->sk_user_data = srv;
517 write_unlock_bh(&sk->sk_callback_lock);
518
519 rc = kernel_setsockopt(lsock, SOL_TIPC, TIPC_IMPORTANCE,
520 (char *)&imp, sizeof(imp));
521 if (rc < 0)
522 goto err;
523
524 saddr.family = AF_TIPC;
525 saddr.addrtype = TIPC_ADDR_NAMESEQ;
526 saddr.addr.nameseq.type = TIPC_TOP_SRV;
527 saddr.addr.nameseq.lower = TIPC_TOP_SRV;
528 saddr.addr.nameseq.upper = TIPC_TOP_SRV;
529 saddr.scope = TIPC_NODE_SCOPE;
530
531 rc = kernel_bind(lsock, (struct sockaddr *)&saddr, sizeof(saddr));
532 if (rc < 0)
533 goto err;
534 rc = kernel_listen(lsock, 0);
535 if (rc < 0)
536 goto err;
537
538 /* As server's listening socket owner and creator is the same module,
539 * we have to decrease TIPC module reference count to guarantee that
540 * it remains zero after the server socket is created, otherwise,
541 * executing "rmmod" command is unable to make TIPC module deleted
542 * after TIPC module is inserted successfully.
543 *
544 * However, the reference count is ever increased twice in
545 * sock_create_kern(): one is to increase the reference count of owner
546 * of TIPC socket's proto_ops struct; another is to increment the
547 * reference count of owner of TIPC proto struct. Therefore, we must
548 * decrement the module reference count twice to ensure that it keeps
549 * zero after server's listening socket is created. Of course, we
550 * must bump the module reference count twice as well before the socket
551 * is closed.
552 */
553 module_put(lsock->ops->owner);
554 module_put(sk->sk_prot_creator->owner);
555
556 return 0;
557err:
558 sock_release(lsock);
559 return -EINVAL;
560}
561
562bool tipc_topsrv_kern_subscr(struct net *net, u32 port, u32 type, u32 lower,
563 u32 upper, u32 filter, int *conid)
564{
565 struct tipc_subscr sub;
566 struct tipc_conn *con;
567 int rc;
568
569 sub.seq.type = type;
570 sub.seq.lower = lower;
571 sub.seq.upper = upper;
572 sub.timeout = TIPC_WAIT_FOREVER;
573 sub.filter = filter;
574 *(u32 *)&sub.usr_handle = port;
575
576 con = tipc_conn_alloc(tipc_topsrv(net));
577 if (IS_ERR(con))
578 return false;
579
580 *conid = con->conid;
581 con->sock = NULL;
582 rc = tipc_conn_rcv_sub(tipc_topsrv(net), con, &sub);
583 if (rc >= 0)
584 return true;
585 conn_put(con);
586 return false;
587}
588
589void tipc_topsrv_kern_unsubscr(struct net *net, int conid)
590{
591 struct tipc_conn *con;
592
593 con = tipc_conn_lookup(tipc_topsrv(net), conid);
594 if (!con)
595 return;
596
597 test_and_clear_bit(CF_CONNECTED, &con->flags);
598 tipc_conn_delete_sub(con, NULL);
599 conn_put(con);
600 conn_put(con);
601}
602
603static void tipc_topsrv_kern_evt(struct net *net, struct tipc_event *evt)
604{
605 u32 port = *(u32 *)&evt->s.usr_handle;
606 u32 self = tipc_own_addr(net);
607 struct sk_buff_head evtq;
608 struct sk_buff *skb;
609
610 skb = tipc_msg_create(TOP_SRV, 0, INT_H_SIZE, sizeof(*evt),
611 self, self, port, port, 0);
612 if (!skb)
613 return;
614 msg_set_dest_droppable(buf_msg(skb), true);
615 memcpy(msg_data(buf_msg(skb)), evt, sizeof(*evt));
616 skb_queue_head_init(&evtq);
617 __skb_queue_tail(&evtq, skb);
618 tipc_sk_rcv(net, &evtq);
619}
620
621static int tipc_topsrv_work_start(struct tipc_topsrv *s)
622{
623 s->rcv_wq = alloc_ordered_workqueue("tipc_rcv", 0);
624 if (!s->rcv_wq) {
625 pr_err("can't start tipc receive workqueue\n");
626 return -ENOMEM;
627 }
628
629 s->send_wq = alloc_ordered_workqueue("tipc_send", 0);
630 if (!s->send_wq) {
631 pr_err("can't start tipc send workqueue\n");
632 destroy_workqueue(s->rcv_wq);
633 return -ENOMEM;
634 }
635
636 return 0;
637}
638
639static void tipc_topsrv_work_stop(struct tipc_topsrv *s)
640{
641 destroy_workqueue(s->rcv_wq);
642 destroy_workqueue(s->send_wq);
643}
644
645int tipc_topsrv_start(struct net *net)
646{
647 struct tipc_net *tn = tipc_net(net);
648 const char name[] = "topology_server";
649 struct tipc_topsrv *srv;
650 int ret;
651
652 srv = kzalloc(sizeof(*srv), GFP_ATOMIC);
653 if (!srv)
654 return -ENOMEM;
655
656 srv->net = net;
657 srv->max_rcvbuf_size = sizeof(struct tipc_subscr);
658 INIT_WORK(&srv->awork, tipc_topsrv_accept);
659
660 strncpy(srv->name, name, strlen(name) + 1);
661 tn->topsrv = srv;
662 atomic_set(&tn->subscription_count, 0);
663
664 spin_lock_init(&srv->idr_lock);
665 idr_init(&srv->conn_idr);
666 srv->idr_in_use = 0;
667
668 ret = tipc_topsrv_work_start(srv);
669 if (ret < 0)
670 return ret;
671
672 ret = tipc_topsrv_create_listener(srv);
673 if (ret < 0)
674 tipc_topsrv_work_stop(srv);
675
676 return ret;
677}
678
679void tipc_topsrv_stop(struct net *net)
680{
681 struct tipc_topsrv *srv = tipc_topsrv(net);
682 struct socket *lsock = srv->listener;
683 struct tipc_conn *con;
684 int id;
685
686 spin_lock_bh(&srv->idr_lock);
687 for (id = 0; srv->idr_in_use; id++) {
688 con = idr_find(&srv->conn_idr, id);
689 if (con) {
690 spin_unlock_bh(&srv->idr_lock);
691 tipc_conn_close(con);
692 spin_lock_bh(&srv->idr_lock);
693 }
694 }
695 __module_get(lsock->ops->owner);
696 __module_get(lsock->sk->sk_prot_creator->owner);
697 srv->listener = NULL;
698 spin_unlock_bh(&srv->idr_lock);
699 sock_release(lsock);
700 tipc_topsrv_work_stop(srv);
701 idr_destroy(&srv->conn_idr);
702 kfree(srv);
703}
diff --git a/net/tipc/server.h b/net/tipc/topsrv.h
index 64df7513cd70..c7ea71293748 100644
--- a/net/tipc/server.h
+++ b/net/tipc/topsrv.h
@@ -2,6 +2,7 @@
2 * net/tipc/server.h: Include file for TIPC server code 2 * net/tipc/server.h: Include file for TIPC server code
3 * 3 *
4 * Copyright (c) 2012-2013, Wind River Systems 4 * Copyright (c) 2012-2013, Wind River Systems
5 * Copyright (c) 2017, Ericsson AB
5 * All rights reserved. 6 * All rights reserved.
6 * 7 *
7 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -36,68 +37,18 @@
36#ifndef _TIPC_SERVER_H 37#ifndef _TIPC_SERVER_H
37#define _TIPC_SERVER_H 38#define _TIPC_SERVER_H
38 39
39#include <linux/idr.h> 40#include "core.h"
40#include <linux/tipc.h>
41#include <net/net_namespace.h>
42 41
43#define TIPC_SERVER_NAME_LEN 32 42#define TIPC_SERVER_NAME_LEN 32
44#define TIPC_SUB_CLUSTER_SCOPE 0x20 43#define TIPC_SUB_CLUSTER_SCOPE 0x20
45#define TIPC_SUB_NODE_SCOPE 0x40 44#define TIPC_SUB_NODE_SCOPE 0x40
46#define TIPC_SUB_NO_STATUS 0x80 45#define TIPC_SUB_NO_STATUS 0x80
47 46
48/** 47void tipc_topsrv_queue_evt(struct net *net, int conid,
49 * struct tipc_server - TIPC server structure 48 u32 event, struct tipc_event *evt);
50 * @conn_idr: identifier set of connection
51 * @idr_lock: protect the connection identifier set
52 * @idr_in_use: amount of allocated identifier entry
53 * @net: network namspace instance
54 * @rcvbuf_cache: memory cache of server receive buffer
55 * @rcv_wq: receive workqueue
56 * @send_wq: send workqueue
57 * @max_rcvbuf_size: maximum permitted receive message length
58 * @tipc_conn_new: callback will be called when new connection is incoming
59 * @tipc_conn_release: callback will be called before releasing the connection
60 * @tipc_conn_recvmsg: callback will be called when message arrives
61 * @saddr: TIPC server address
62 * @name: server name
63 * @imp: message importance
64 * @type: socket type
65 */
66struct tipc_server {
67 struct idr conn_idr;
68 spinlock_t idr_lock;
69 int idr_in_use;
70 struct net *net;
71 struct kmem_cache *rcvbuf_cache;
72 struct workqueue_struct *rcv_wq;
73 struct workqueue_struct *send_wq;
74 int max_rcvbuf_size;
75 void *(*tipc_conn_new)(int conid);
76 void (*tipc_conn_release)(int conid, void *usr_data);
77 int (*tipc_conn_recvmsg)(struct net *net, int conid,
78 struct sockaddr_tipc *addr, void *usr_data,
79 void *buf, size_t len);
80 struct sockaddr_tipc *saddr;
81 char name[TIPC_SERVER_NAME_LEN];
82 int imp;
83 int type;
84};
85
86int tipc_conn_sendmsg(struct tipc_server *s, int conid,
87 struct sockaddr_tipc *addr, void *data, size_t len);
88 49
89bool tipc_topsrv_kern_subscr(struct net *net, u32 port, u32 type, u32 lower, 50bool tipc_topsrv_kern_subscr(struct net *net, u32 port, u32 type, u32 lower,
90 u32 upper, u32 filter, int *conid); 51 u32 upper, u32 filter, int *conid);
91void tipc_topsrv_kern_unsubscr(struct net *net, int conid); 52void tipc_topsrv_kern_unsubscr(struct net *net, int conid);
92 53
93/**
94 * tipc_conn_terminate - terminate connection with server
95 *
96 * Note: Must call it in process context since it might sleep
97 */
98void tipc_conn_terminate(struct tipc_server *s, int conid);
99int tipc_server_start(struct tipc_server *s);
100
101void tipc_server_stop(struct tipc_server *s);
102
103#endif 54#endif
diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
index f26376e954ae..057a558ed6d7 100644
--- a/net/tls/tls_sw.c
+++ b/net/tls/tls_sw.c
@@ -87,71 +87,16 @@ static void trim_both_sgl(struct sock *sk, int target_size)
87 target_size); 87 target_size);
88} 88}
89 89
90static int alloc_sg(struct sock *sk, int len, struct scatterlist *sg,
91 int *sg_num_elem, unsigned int *sg_size,
92 int first_coalesce)
93{
94 struct page_frag *pfrag;
95 unsigned int size = *sg_size;
96 int num_elem = *sg_num_elem, use = 0, rc = 0;
97 struct scatterlist *sge;
98 unsigned int orig_offset;
99
100 len -= size;
101 pfrag = sk_page_frag(sk);
102
103 while (len > 0) {
104 if (!sk_page_frag_refill(sk, pfrag)) {
105 rc = -ENOMEM;
106 goto out;
107 }
108
109 use = min_t(int, len, pfrag->size - pfrag->offset);
110
111 if (!sk_wmem_schedule(sk, use)) {
112 rc = -ENOMEM;
113 goto out;
114 }
115
116 sk_mem_charge(sk, use);
117 size += use;
118 orig_offset = pfrag->offset;
119 pfrag->offset += use;
120
121 sge = sg + num_elem - 1;
122 if (num_elem > first_coalesce && sg_page(sg) == pfrag->page &&
123 sg->offset + sg->length == orig_offset) {
124 sg->length += use;
125 } else {
126 sge++;
127 sg_unmark_end(sge);
128 sg_set_page(sge, pfrag->page, use, orig_offset);
129 get_page(pfrag->page);
130 ++num_elem;
131 if (num_elem == MAX_SKB_FRAGS) {
132 rc = -ENOSPC;
133 break;
134 }
135 }
136
137 len -= use;
138 }
139 goto out;
140
141out:
142 *sg_size = size;
143 *sg_num_elem = num_elem;
144 return rc;
145}
146
147static int alloc_encrypted_sg(struct sock *sk, int len) 90static int alloc_encrypted_sg(struct sock *sk, int len)
148{ 91{
149 struct tls_context *tls_ctx = tls_get_ctx(sk); 92 struct tls_context *tls_ctx = tls_get_ctx(sk);
150 struct tls_sw_context *ctx = tls_sw_ctx(tls_ctx); 93 struct tls_sw_context *ctx = tls_sw_ctx(tls_ctx);
151 int rc = 0; 94 int rc = 0;
152 95
153 rc = alloc_sg(sk, len, ctx->sg_encrypted_data, 96 rc = sk_alloc_sg(sk, len,
154 &ctx->sg_encrypted_num_elem, &ctx->sg_encrypted_size, 0); 97 ctx->sg_encrypted_data, 0,
98 &ctx->sg_encrypted_num_elem,
99 &ctx->sg_encrypted_size, 0);
155 100
156 return rc; 101 return rc;
157} 102}
@@ -162,9 +107,9 @@ static int alloc_plaintext_sg(struct sock *sk, int len)
162 struct tls_sw_context *ctx = tls_sw_ctx(tls_ctx); 107 struct tls_sw_context *ctx = tls_sw_ctx(tls_ctx);
163 int rc = 0; 108 int rc = 0;
164 109
165 rc = alloc_sg(sk, len, ctx->sg_plaintext_data, 110 rc = sk_alloc_sg(sk, len, ctx->sg_plaintext_data, 0,
166 &ctx->sg_plaintext_num_elem, &ctx->sg_plaintext_size, 111 &ctx->sg_plaintext_num_elem, &ctx->sg_plaintext_size,
167 tls_ctx->pending_open_record_frags); 112 tls_ctx->pending_open_record_frags);
168 113
169 return rc; 114 return rc;
170} 115}
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 2d465bdeccbc..bc2970a8e7f3 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -637,7 +637,7 @@ static int unix_stream_connect(struct socket *, struct sockaddr *,
637 int addr_len, int flags); 637 int addr_len, int flags);
638static int unix_socketpair(struct socket *, struct socket *); 638static int unix_socketpair(struct socket *, struct socket *);
639static int unix_accept(struct socket *, struct socket *, int, bool); 639static int unix_accept(struct socket *, struct socket *, int, bool);
640static int unix_getname(struct socket *, struct sockaddr *, int *, int); 640static int unix_getname(struct socket *, struct sockaddr *, int);
641static __poll_t unix_poll(struct file *, struct socket *, poll_table *); 641static __poll_t unix_poll(struct file *, struct socket *, poll_table *);
642static __poll_t unix_dgram_poll(struct file *, struct socket *, 642static __poll_t unix_dgram_poll(struct file *, struct socket *,
643 poll_table *); 643 poll_table *);
@@ -1453,7 +1453,7 @@ out:
1453} 1453}
1454 1454
1455 1455
1456static int unix_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, int peer) 1456static int unix_getname(struct socket *sock, struct sockaddr *uaddr, int peer)
1457{ 1457{
1458 struct sock *sk = sock->sk; 1458 struct sock *sk = sock->sk;
1459 struct unix_sock *u; 1459 struct unix_sock *u;
@@ -1476,12 +1476,12 @@ static int unix_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_
1476 if (!u->addr) { 1476 if (!u->addr) {
1477 sunaddr->sun_family = AF_UNIX; 1477 sunaddr->sun_family = AF_UNIX;
1478 sunaddr->sun_path[0] = 0; 1478 sunaddr->sun_path[0] = 0;
1479 *uaddr_len = sizeof(short); 1479 err = sizeof(short);
1480 } else { 1480 } else {
1481 struct unix_address *addr = u->addr; 1481 struct unix_address *addr = u->addr;
1482 1482
1483 *uaddr_len = addr->len; 1483 err = addr->len;
1484 memcpy(sunaddr, addr->name, *uaddr_len); 1484 memcpy(sunaddr, addr->name, addr->len);
1485 } 1485 }
1486 unix_state_unlock(sk); 1486 unix_state_unlock(sk);
1487 sock_put(sk); 1487 sock_put(sk);
@@ -2913,6 +2913,7 @@ static void __net_exit unix_net_exit(struct net *net)
2913static struct pernet_operations unix_net_ops = { 2913static struct pernet_operations unix_net_ops = {
2914 .init = unix_net_init, 2914 .init = unix_net_init,
2915 .exit = unix_net_exit, 2915 .exit = unix_net_exit,
2916 .async = true,
2916}; 2917};
2917 2918
2918static int __init af_unix_init(void) 2919static int __init af_unix_init(void)
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index e0fc84daed94..aac9b8f6552e 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -759,7 +759,7 @@ vsock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
759} 759}
760 760
761static int vsock_getname(struct socket *sock, 761static int vsock_getname(struct socket *sock,
762 struct sockaddr *addr, int *addr_len, int peer) 762 struct sockaddr *addr, int peer)
763{ 763{
764 int err; 764 int err;
765 struct sock *sk; 765 struct sock *sk;
@@ -794,7 +794,7 @@ static int vsock_getname(struct socket *sock,
794 */ 794 */
795 BUILD_BUG_ON(sizeof(*vm_addr) > 128); 795 BUILD_BUG_ON(sizeof(*vm_addr) > 128);
796 memcpy(addr, vm_addr, sizeof(*vm_addr)); 796 memcpy(addr, vm_addr, sizeof(*vm_addr));
797 *addr_len = sizeof(*vm_addr); 797 err = sizeof(*vm_addr);
798 798
799out: 799out:
800 release_sock(sk); 800 release_sock(sk);
diff --git a/net/wireless/core.c b/net/wireless/core.c
index a6f3cac8c640..670aa229168a 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -1340,6 +1340,7 @@ static void __net_exit cfg80211_pernet_exit(struct net *net)
1340 1340
1341static struct pernet_operations cfg80211_pernet_ops = { 1341static struct pernet_operations cfg80211_pernet_ops = {
1342 .exit = cfg80211_pernet_exit, 1342 .exit = cfg80211_pernet_exit,
1343 .async = true,
1343}; 1344};
1344 1345
1345static int __init cfg80211_init(void) 1346static int __init cfg80211_init(void)
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 9c0dcc8324b0..a910150f8169 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -421,6 +421,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
421 [NL80211_ATTR_FILS_CACHE_ID] = { .len = 2 }, 421 [NL80211_ATTR_FILS_CACHE_ID] = { .len = 2 },
422 [NL80211_ATTR_PMK] = { .type = NLA_BINARY, .len = PMK_MAX_LEN }, 422 [NL80211_ATTR_PMK] = { .type = NLA_BINARY, .len = PMK_MAX_LEN },
423 [NL80211_ATTR_SCHED_SCAN_MULTI] = { .type = NLA_FLAG }, 423 [NL80211_ATTR_SCHED_SCAN_MULTI] = { .type = NLA_FLAG },
424 [NL80211_ATTR_EXTERNAL_AUTH_SUPPORT] = { .type = NLA_FLAG },
424}; 425};
425 426
426/* policy for the key attributes */ 427/* policy for the key attributes */
@@ -3923,9 +3924,10 @@ static bool nl80211_valid_auth_type(struct cfg80211_registered_device *rdev,
3923 return false; 3924 return false;
3924 return true; 3925 return true;
3925 case NL80211_CMD_CONNECT: 3926 case NL80211_CMD_CONNECT:
3926 /* SAE not supported yet */ 3927 if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) &&
3927 if (auth_type == NL80211_AUTHTYPE_SAE) 3928 auth_type == NL80211_AUTHTYPE_SAE)
3928 return false; 3929 return false;
3930
3929 /* FILS with SK PFS or PK not supported yet */ 3931 /* FILS with SK PFS or PK not supported yet */
3930 if (auth_type == NL80211_AUTHTYPE_FILS_SK_PFS || 3932 if (auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
3931 auth_type == NL80211_AUTHTYPE_FILS_PK) 3933 auth_type == NL80211_AUTHTYPE_FILS_PK)
@@ -4487,6 +4489,7 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
4487 PUT_SINFO_U64(RX_DROP_MISC, rx_dropped_misc); 4489 PUT_SINFO_U64(RX_DROP_MISC, rx_dropped_misc);
4488 PUT_SINFO_U64(BEACON_RX, rx_beacon); 4490 PUT_SINFO_U64(BEACON_RX, rx_beacon);
4489 PUT_SINFO(BEACON_SIGNAL_AVG, rx_beacon_signal_avg, u8); 4491 PUT_SINFO(BEACON_SIGNAL_AVG, rx_beacon_signal_avg, u8);
4492 PUT_SINFO(ACK_SIGNAL, ack_signal, u8);
4490 4493
4491#undef PUT_SINFO 4494#undef PUT_SINFO
4492#undef PUT_SINFO_U64 4495#undef PUT_SINFO_U64
@@ -5848,7 +5851,6 @@ static int nl80211_get_mesh_config(struct sk_buff *skb,
5848 return genlmsg_reply(msg, info); 5851 return genlmsg_reply(msg, info);
5849 5852
5850 nla_put_failure: 5853 nla_put_failure:
5851 genlmsg_cancel(msg, hdr);
5852 out: 5854 out:
5853 nlmsg_free(msg); 5855 nlmsg_free(msg);
5854 return -ENOBUFS; 5856 return -ENOBUFS;
@@ -6329,7 +6331,6 @@ static int nl80211_get_reg_do(struct sk_buff *skb, struct genl_info *info)
6329nla_put_failure_rcu: 6331nla_put_failure_rcu:
6330 rcu_read_unlock(); 6332 rcu_read_unlock();
6331nla_put_failure: 6333nla_put_failure:
6332 genlmsg_cancel(msg, hdr);
6333put_failure: 6334put_failure:
6334 nlmsg_free(msg); 6335 nlmsg_free(msg);
6335 return -EMSGSIZE; 6336 return -EMSGSIZE;
@@ -6718,8 +6719,17 @@ nl80211_check_scan_flags(struct wiphy *wiphy, struct wireless_dev *wdev,
6718 6719
6719 *flags = nla_get_u32(attrs[NL80211_ATTR_SCAN_FLAGS]); 6720 *flags = nla_get_u32(attrs[NL80211_ATTR_SCAN_FLAGS]);
6720 6721
6721 if ((*flags & NL80211_SCAN_FLAG_LOW_PRIORITY) && 6722 if (((*flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
6722 !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) 6723 !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) ||
6724 ((*flags & NL80211_SCAN_FLAG_LOW_SPAN) &&
6725 !wiphy_ext_feature_isset(wiphy,
6726 NL80211_EXT_FEATURE_LOW_SPAN_SCAN)) ||
6727 ((*flags & NL80211_SCAN_FLAG_LOW_POWER) &&
6728 !wiphy_ext_feature_isset(wiphy,
6729 NL80211_EXT_FEATURE_LOW_POWER_SCAN)) ||
6730 ((*flags & NL80211_SCAN_FLAG_HIGH_ACCURACY) &&
6731 !wiphy_ext_feature_isset(wiphy,
6732 NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN)))
6723 return -EOPNOTSUPP; 6733 return -EOPNOTSUPP;
6724 6734
6725 if (*flags & NL80211_SCAN_FLAG_RANDOM_ADDR) { 6735 if (*flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
@@ -9155,6 +9165,15 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
9155 return -EINVAL; 9165 return -EINVAL;
9156 } 9166 }
9157 9167
9168 if (nla_get_flag(info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT])) {
9169 if (!info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
9170 GENL_SET_ERR_MSG(info,
9171 "external auth requires connection ownership");
9172 return -EINVAL;
9173 }
9174 connect.flags |= CONNECT_REQ_EXTERNAL_AUTH_SUPPORT;
9175 }
9176
9158 wdev_lock(dev->ieee80211_ptr); 9177 wdev_lock(dev->ieee80211_ptr);
9159 9178
9160 err = cfg80211_connect(rdev, dev, &connect, connkeys, 9179 err = cfg80211_connect(rdev, dev, &connect, connkeys,
@@ -12463,6 +12482,41 @@ static int nl80211_del_pmk(struct sk_buff *skb, struct genl_info *info)
12463 return ret; 12482 return ret;
12464} 12483}
12465 12484
12485static int nl80211_external_auth(struct sk_buff *skb, struct genl_info *info)
12486{
12487 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12488 struct net_device *dev = info->user_ptr[1];
12489 struct cfg80211_external_auth_params params;
12490
12491 if (!rdev->ops->external_auth)
12492 return -EOPNOTSUPP;
12493
12494 if (!info->attrs[NL80211_ATTR_SSID])
12495 return -EINVAL;
12496
12497 if (!info->attrs[NL80211_ATTR_BSSID])
12498 return -EINVAL;
12499
12500 if (!info->attrs[NL80211_ATTR_STATUS_CODE])
12501 return -EINVAL;
12502
12503 memset(&params, 0, sizeof(params));
12504
12505 params.ssid.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
12506 if (params.ssid.ssid_len == 0 ||
12507 params.ssid.ssid_len > IEEE80211_MAX_SSID_LEN)
12508 return -EINVAL;
12509 memcpy(params.ssid.ssid, nla_data(info->attrs[NL80211_ATTR_SSID]),
12510 params.ssid.ssid_len);
12511
12512 memcpy(params.bssid, nla_data(info->attrs[NL80211_ATTR_BSSID]),
12513 ETH_ALEN);
12514
12515 params.status = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
12516
12517 return rdev_external_auth(rdev, dev, &params);
12518}
12519
12466#define NL80211_FLAG_NEED_WIPHY 0x01 12520#define NL80211_FLAG_NEED_WIPHY 0x01
12467#define NL80211_FLAG_NEED_NETDEV 0x02 12521#define NL80211_FLAG_NEED_NETDEV 0x02
12468#define NL80211_FLAG_NEED_RTNL 0x04 12522#define NL80211_FLAG_NEED_RTNL 0x04
@@ -13358,6 +13412,14 @@ static const struct genl_ops nl80211_ops[] = {
13358 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | 13412 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13359 NL80211_FLAG_NEED_RTNL, 13413 NL80211_FLAG_NEED_RTNL,
13360 }, 13414 },
13415 {
13416 .cmd = NL80211_CMD_EXTERNAL_AUTH,
13417 .doit = nl80211_external_auth,
13418 .policy = nl80211_policy,
13419 .flags = GENL_ADMIN_PERM,
13420 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13421 NL80211_FLAG_NEED_RTNL,
13422 },
13361 13423
13362}; 13424};
13363 13425
@@ -13672,7 +13734,6 @@ void nl80211_common_reg_change_event(enum nl80211_commands cmd_id,
13672 return; 13734 return;
13673 13735
13674nla_put_failure: 13736nla_put_failure:
13675 genlmsg_cancel(msg, hdr);
13676 nlmsg_free(msg); 13737 nlmsg_free(msg);
13677} 13738}
13678 13739
@@ -13720,7 +13781,6 @@ static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
13720 return; 13781 return;
13721 13782
13722 nla_put_failure: 13783 nla_put_failure:
13723 genlmsg_cancel(msg, hdr);
13724 nlmsg_free(msg); 13784 nlmsg_free(msg);
13725} 13785}
13726 13786
@@ -13808,7 +13868,6 @@ static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
13808 return; 13868 return;
13809 13869
13810 nla_put_failure: 13870 nla_put_failure:
13811 genlmsg_cancel(msg, hdr);
13812 nlmsg_free(msg); 13871 nlmsg_free(msg);
13813} 13872}
13814 13873
@@ -13884,7 +13943,6 @@ void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
13884 return; 13943 return;
13885 13944
13886 nla_put_failure: 13945 nla_put_failure:
13887 genlmsg_cancel(msg, hdr);
13888 nlmsg_free(msg); 13946 nlmsg_free(msg);
13889} 13947}
13890 13948
@@ -13924,7 +13982,6 @@ void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
13924 return; 13982 return;
13925 13983
13926 nla_put_failure: 13984 nla_put_failure:
13927 genlmsg_cancel(msg, hdr);
13928 nlmsg_free(msg); 13985 nlmsg_free(msg);
13929} 13986}
13930 13987
@@ -13954,7 +14011,6 @@ void nl80211_send_port_authorized(struct cfg80211_registered_device *rdev,
13954 return; 14011 return;
13955 14012
13956 nla_put_failure: 14013 nla_put_failure:
13957 genlmsg_cancel(msg, hdr);
13958 nlmsg_free(msg); 14014 nlmsg_free(msg);
13959} 14015}
13960 14016
@@ -13991,7 +14047,6 @@ void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
13991 return; 14047 return;
13992 14048
13993 nla_put_failure: 14049 nla_put_failure:
13994 genlmsg_cancel(msg, hdr);
13995 nlmsg_free(msg); 14050 nlmsg_free(msg);
13996} 14051}
13997 14052
@@ -14024,7 +14079,6 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
14024 return; 14079 return;
14025 14080
14026 nla_put_failure: 14081 nla_put_failure:
14027 genlmsg_cancel(msg, hdr);
14028 nlmsg_free(msg); 14082 nlmsg_free(msg);
14029} 14083}
14030 14084
@@ -14065,7 +14119,6 @@ void cfg80211_notify_new_peer_candidate(struct net_device *dev, const u8 *addr,
14065 return; 14119 return;
14066 14120
14067 nla_put_failure: 14121 nla_put_failure:
14068 genlmsg_cancel(msg, hdr);
14069 nlmsg_free(msg); 14122 nlmsg_free(msg);
14070} 14123}
14071EXPORT_SYMBOL(cfg80211_notify_new_peer_candidate); 14124EXPORT_SYMBOL(cfg80211_notify_new_peer_candidate);
@@ -14104,7 +14157,6 @@ void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
14104 return; 14157 return;
14105 14158
14106 nla_put_failure: 14159 nla_put_failure:
14107 genlmsg_cancel(msg, hdr);
14108 nlmsg_free(msg); 14160 nlmsg_free(msg);
14109} 14161}
14110 14162
@@ -14159,7 +14211,6 @@ void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
14159 return; 14211 return;
14160 14212
14161nla_put_failure: 14213nla_put_failure:
14162 genlmsg_cancel(msg, hdr);
14163 nlmsg_free(msg); 14214 nlmsg_free(msg);
14164} 14215}
14165 14216
@@ -14205,7 +14256,6 @@ static void nl80211_send_remain_on_chan_event(
14205 return; 14256 return;
14206 14257
14207 nla_put_failure: 14258 nla_put_failure:
14208 genlmsg_cancel(msg, hdr);
14209 nlmsg_free(msg); 14259 nlmsg_free(msg);
14210} 14260}
14211 14261
@@ -14319,7 +14369,6 @@ void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr,
14319 return; 14369 return;
14320 14370
14321 nla_put_failure: 14371 nla_put_failure:
14322 genlmsg_cancel(msg, hdr);
14323 nlmsg_free(msg); 14372 nlmsg_free(msg);
14324} 14373}
14325EXPORT_SYMBOL(cfg80211_conn_failed); 14374EXPORT_SYMBOL(cfg80211_conn_failed);
@@ -14356,7 +14405,6 @@ static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd,
14356 return true; 14405 return true;
14357 14406
14358 nla_put_failure: 14407 nla_put_failure:
14359 genlmsg_cancel(msg, hdr);
14360 nlmsg_free(msg); 14408 nlmsg_free(msg);
14361 return true; 14409 return true;
14362} 14410}
@@ -14440,7 +14488,6 @@ int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
14440 return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid); 14488 return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
14441 14489
14442 nla_put_failure: 14490 nla_put_failure:
14443 genlmsg_cancel(msg, hdr);
14444 nlmsg_free(msg); 14491 nlmsg_free(msg);
14445 return -ENOBUFS; 14492 return -ENOBUFS;
14446} 14493}
@@ -14484,7 +14531,6 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie,
14484 return; 14531 return;
14485 14532
14486 nla_put_failure: 14533 nla_put_failure:
14487 genlmsg_cancel(msg, hdr);
14488 nlmsg_free(msg); 14534 nlmsg_free(msg);
14489} 14535}
14490EXPORT_SYMBOL(cfg80211_mgmt_tx_status); 14536EXPORT_SYMBOL(cfg80211_mgmt_tx_status);
@@ -14693,7 +14739,6 @@ static void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev,
14693 return; 14739 return;
14694 14740
14695 nla_put_failure: 14741 nla_put_failure:
14696 genlmsg_cancel(msg, hdr);
14697 nlmsg_free(msg); 14742 nlmsg_free(msg);
14698} 14743}
14699 14744
@@ -14751,7 +14796,6 @@ nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
14751 return; 14796 return;
14752 14797
14753 nla_put_failure: 14798 nla_put_failure:
14754 genlmsg_cancel(msg, hdr);
14755 nlmsg_free(msg); 14799 nlmsg_free(msg);
14756} 14800}
14757 14801
@@ -14804,7 +14848,6 @@ static void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
14804 return; 14848 return;
14805 14849
14806 nla_put_failure: 14850 nla_put_failure:
14807 genlmsg_cancel(msg, hdr);
14808 nlmsg_free(msg); 14851 nlmsg_free(msg);
14809} 14852}
14810 14853
@@ -14886,12 +14929,67 @@ nl80211_radar_notify(struct cfg80211_registered_device *rdev,
14886 return; 14929 return;
14887 14930
14888 nla_put_failure: 14931 nla_put_failure:
14889 genlmsg_cancel(msg, hdr);
14890 nlmsg_free(msg); 14932 nlmsg_free(msg);
14891} 14933}
14892 14934
14935void cfg80211_sta_opmode_change_notify(struct net_device *dev, const u8 *mac,
14936 struct sta_opmode_info *sta_opmode,
14937 gfp_t gfp)
14938{
14939 struct sk_buff *msg;
14940 struct wireless_dev *wdev = dev->ieee80211_ptr;
14941 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
14942 void *hdr;
14943
14944 if (WARN_ON(!mac))
14945 return;
14946
14947 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
14948 if (!msg)
14949 return;
14950
14951 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_STA_OPMODE_CHANGED);
14952 if (!hdr) {
14953 nlmsg_free(msg);
14954 return;
14955 }
14956
14957 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
14958 goto nla_put_failure;
14959
14960 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
14961 goto nla_put_failure;
14962
14963 if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac))
14964 goto nla_put_failure;
14965
14966 if ((sta_opmode->changed & STA_OPMODE_SMPS_MODE_CHANGED) &&
14967 nla_put_u8(msg, NL80211_ATTR_SMPS_MODE, sta_opmode->smps_mode))
14968 goto nla_put_failure;
14969
14970 if ((sta_opmode->changed & STA_OPMODE_MAX_BW_CHANGED) &&
14971 nla_put_u8(msg, NL80211_ATTR_CHANNEL_WIDTH, sta_opmode->bw))
14972 goto nla_put_failure;
14973
14974 if ((sta_opmode->changed & STA_OPMODE_N_SS_CHANGED) &&
14975 nla_put_u8(msg, NL80211_ATTR_NSS, sta_opmode->rx_nss))
14976 goto nla_put_failure;
14977
14978 genlmsg_end(msg, hdr);
14979
14980 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
14981 NL80211_MCGRP_MLME, gfp);
14982
14983 return;
14984
14985nla_put_failure:
14986 nlmsg_free(msg);
14987}
14988EXPORT_SYMBOL(cfg80211_sta_opmode_change_notify);
14989
14893void cfg80211_probe_status(struct net_device *dev, const u8 *addr, 14990void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
14894 u64 cookie, bool acked, gfp_t gfp) 14991 u64 cookie, bool acked, s32 ack_signal,
14992 bool is_valid_ack_signal, gfp_t gfp)
14895{ 14993{
14896 struct wireless_dev *wdev = dev->ieee80211_ptr; 14994 struct wireless_dev *wdev = dev->ieee80211_ptr;
14897 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); 14995 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
@@ -14916,7 +15014,9 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
14916 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) || 15014 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
14917 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie, 15015 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
14918 NL80211_ATTR_PAD) || 15016 NL80211_ATTR_PAD) ||
14919 (acked && nla_put_flag(msg, NL80211_ATTR_ACK))) 15017 (acked && nla_put_flag(msg, NL80211_ATTR_ACK)) ||
15018 (is_valid_ack_signal && nla_put_s32(msg, NL80211_ATTR_ACK_SIGNAL,
15019 ack_signal)))
14920 goto nla_put_failure; 15020 goto nla_put_failure;
14921 15021
14922 genlmsg_end(msg, hdr); 15022 genlmsg_end(msg, hdr);
@@ -14926,7 +15026,6 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
14926 return; 15026 return;
14927 15027
14928 nla_put_failure: 15028 nla_put_failure:
14929 genlmsg_cancel(msg, hdr);
14930 nlmsg_free(msg); 15029 nlmsg_free(msg);
14931} 15030}
14932EXPORT_SYMBOL(cfg80211_probe_status); 15031EXPORT_SYMBOL(cfg80211_probe_status);
@@ -14971,8 +15070,6 @@ void cfg80211_report_obss_beacon(struct wiphy *wiphy,
14971 15070
14972 nla_put_failure: 15071 nla_put_failure:
14973 spin_unlock_bh(&rdev->beacon_registrations_lock); 15072 spin_unlock_bh(&rdev->beacon_registrations_lock);
14974 if (hdr)
14975 genlmsg_cancel(msg, hdr);
14976 nlmsg_free(msg); 15073 nlmsg_free(msg);
14977} 15074}
14978EXPORT_SYMBOL(cfg80211_report_obss_beacon); 15075EXPORT_SYMBOL(cfg80211_report_obss_beacon);
@@ -15188,7 +15285,6 @@ void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer,
15188 return; 15285 return;
15189 15286
15190 nla_put_failure: 15287 nla_put_failure:
15191 genlmsg_cancel(msg, hdr);
15192 nlmsg_free(msg); 15288 nlmsg_free(msg);
15193} 15289}
15194EXPORT_SYMBOL(cfg80211_tdls_oper_request); 15290EXPORT_SYMBOL(cfg80211_tdls_oper_request);
@@ -15333,8 +15429,6 @@ void cfg80211_crit_proto_stopped(struct wireless_dev *wdev, gfp_t gfp)
15333 return; 15429 return;
15334 15430
15335 nla_put_failure: 15431 nla_put_failure:
15336 if (hdr)
15337 genlmsg_cancel(msg, hdr);
15338 nlmsg_free(msg); 15432 nlmsg_free(msg);
15339} 15433}
15340EXPORT_SYMBOL(cfg80211_crit_proto_stopped); 15434EXPORT_SYMBOL(cfg80211_crit_proto_stopped);
@@ -15369,6 +15463,47 @@ void nl80211_send_ap_stopped(struct wireless_dev *wdev)
15369 nlmsg_free(msg); 15463 nlmsg_free(msg);
15370} 15464}
15371 15465
15466int cfg80211_external_auth_request(struct net_device *dev,
15467 struct cfg80211_external_auth_params *params,
15468 gfp_t gfp)
15469{
15470 struct wireless_dev *wdev = dev->ieee80211_ptr;
15471 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
15472 struct sk_buff *msg;
15473 void *hdr;
15474
15475 if (!wdev->conn_owner_nlportid)
15476 return -EINVAL;
15477
15478 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
15479 if (!msg)
15480 return -ENOMEM;
15481
15482 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_EXTERNAL_AUTH);
15483 if (!hdr)
15484 goto nla_put_failure;
15485
15486 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
15487 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
15488 nla_put_u32(msg, NL80211_ATTR_AKM_SUITES, params->key_mgmt_suite) ||
15489 nla_put_u32(msg, NL80211_ATTR_EXTERNAL_AUTH_ACTION,
15490 params->action) ||
15491 nla_put(msg, NL80211_ATTR_BSSID, ETH_ALEN, params->bssid) ||
15492 nla_put(msg, NL80211_ATTR_SSID, params->ssid.ssid_len,
15493 params->ssid.ssid))
15494 goto nla_put_failure;
15495
15496 genlmsg_end(msg, hdr);
15497 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
15498 wdev->conn_owner_nlportid);
15499 return 0;
15500
15501 nla_put_failure:
15502 nlmsg_free(msg);
15503 return -ENOBUFS;
15504}
15505EXPORT_SYMBOL(cfg80211_external_auth_request);
15506
15372/* initialisation/exit functions */ 15507/* initialisation/exit functions */
15373 15508
15374int __init nl80211_init(void) 15509int __init nl80211_init(void)
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index 0c06240d25af..84f23ae015fc 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -1190,4 +1190,19 @@ static inline int rdev_del_pmk(struct cfg80211_registered_device *rdev,
1190 trace_rdev_return_int(&rdev->wiphy, ret); 1190 trace_rdev_return_int(&rdev->wiphy, ret);
1191 return ret; 1191 return ret;
1192} 1192}
1193
1194static inline int
1195rdev_external_auth(struct cfg80211_registered_device *rdev,
1196 struct net_device *dev,
1197 struct cfg80211_external_auth_params *params)
1198{
1199 int ret = -EOPNOTSUPP;
1200
1201 trace_rdev_external_auth(&rdev->wiphy, dev, params);
1202 if (rdev->ops->external_auth)
1203 ret = rdev->ops->external_auth(&rdev->wiphy, dev, params);
1204 trace_rdev_return_int(&rdev->wiphy, ret);
1205 return ret;
1206}
1207
1193#endif /* __CFG80211_RDEV_OPS */ 1208#endif /* __CFG80211_RDEV_OPS */
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index bcfedd39e7a3..5152938b358d 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -2319,6 +2319,29 @@ TRACE_EVENT(rdev_del_pmk,
2319 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(aa)) 2319 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(aa))
2320); 2320);
2321 2321
2322TRACE_EVENT(rdev_external_auth,
2323 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
2324 struct cfg80211_external_auth_params *params),
2325 TP_ARGS(wiphy, netdev, params),
2326 TP_STRUCT__entry(WIPHY_ENTRY
2327 NETDEV_ENTRY
2328 MAC_ENTRY(bssid)
2329 __array(u8, ssid, IEEE80211_MAX_SSID_LEN + 1)
2330 __field(u16, status)
2331 ),
2332 TP_fast_assign(WIPHY_ASSIGN;
2333 NETDEV_ASSIGN;
2334 MAC_ASSIGN(bssid, params->bssid);
2335 memset(__entry->ssid, 0, IEEE80211_MAX_SSID_LEN + 1);
2336 memcpy(__entry->ssid, params->ssid.ssid,
2337 params->ssid.ssid_len);
2338 __entry->status = params->status;
2339 ),
2340 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", bssid: " MAC_PR_FMT
2341 ", ssid: %s, status: %u", WIPHY_PR_ARG, NETDEV_PR_ARG,
2342 __entry->bssid, __entry->ssid, __entry->status)
2343);
2344
2322/************************************************************* 2345/*************************************************************
2323 * cfg80211 exported functions traces * 2346 * cfg80211 exported functions traces *
2324 *************************************************************/ 2347 *************************************************************/
diff --git a/net/wireless/util.c b/net/wireless/util.c
index c69160694b6c..d112e9a89364 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -420,7 +420,8 @@ unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr)
420EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen); 420EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen);
421 421
422int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr, 422int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr,
423 const u8 *addr, enum nl80211_iftype iftype) 423 const u8 *addr, enum nl80211_iftype iftype,
424 u8 data_offset)
424{ 425{
425 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 426 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
426 struct { 427 struct {
@@ -434,7 +435,7 @@ int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr,
434 if (unlikely(!ieee80211_is_data_present(hdr->frame_control))) 435 if (unlikely(!ieee80211_is_data_present(hdr->frame_control)))
435 return -1; 436 return -1;
436 437
437 hdrlen = ieee80211_hdrlen(hdr->frame_control); 438 hdrlen = ieee80211_hdrlen(hdr->frame_control) + data_offset;
438 if (skb->len < hdrlen + 8) 439 if (skb->len < hdrlen + 8)
439 return -1; 440 return -1;
440 441
diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c
index 9efbfc753347..bc7064486b15 100644
--- a/net/wireless/wext-core.c
+++ b/net/wireless/wext-core.c
@@ -390,6 +390,7 @@ static void __net_exit wext_pernet_exit(struct net *net)
390static struct pernet_operations wext_pernet_ops = { 390static struct pernet_operations wext_pernet_ops = {
391 .init = wext_pernet_init, 391 .init = wext_pernet_init,
392 .exit = wext_pernet_exit, 392 .exit = wext_pernet_exit,
393 .async = true,
393}; 394};
394 395
395static int __init wireless_nlevent_init(void) 396static int __init wireless_nlevent_init(void)
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index 562cc11131f6..d49aa79b7997 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -896,7 +896,7 @@ out:
896} 896}
897 897
898static int x25_getname(struct socket *sock, struct sockaddr *uaddr, 898static int x25_getname(struct socket *sock, struct sockaddr *uaddr,
899 int *uaddr_len, int peer) 899 int peer)
900{ 900{
901 struct sockaddr_x25 *sx25 = (struct sockaddr_x25 *)uaddr; 901 struct sockaddr_x25 *sx25 = (struct sockaddr_x25 *)uaddr;
902 struct sock *sk = sock->sk; 902 struct sock *sk = sock->sk;
@@ -913,7 +913,7 @@ static int x25_getname(struct socket *sock, struct sockaddr *uaddr,
913 sx25->sx25_addr = x25->source_addr; 913 sx25->sx25_addr = x25->source_addr;
914 914
915 sx25->sx25_family = AF_X25; 915 sx25->sx25_family = AF_X25;
916 *uaddr_len = sizeof(*sx25); 916 rc = sizeof(*sx25);
917 917
918out: 918out:
919 return rc; 919 return rc;
diff --git a/net/x25/x25_subr.c b/net/x25/x25_subr.c
index db0b1315d577..9c214ec681ac 100644
--- a/net/x25/x25_subr.c
+++ b/net/x25/x25_subr.c
@@ -335,8 +335,7 @@ int x25_decode(struct sock *sk, struct sk_buff *skb, int *ns, int *nr, int *q,
335 } 335 }
336 } 336 }
337 337
338 pr_debug("invalid PLP frame %02X %02X %02X\n", 338 pr_debug("invalid PLP frame %3ph\n", frame);
339 frame[0], frame[1], frame[2]);
340 339
341 return X25_ILLEGAL; 340 return X25_ILLEGAL;
342} 341}
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 625b3fca5704..cb3bb9ae4407 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -2985,6 +2985,7 @@ static void __net_exit xfrm_net_exit(struct net *net)
2985static struct pernet_operations __net_initdata xfrm_net_ops = { 2985static struct pernet_operations __net_initdata xfrm_net_ops = {
2986 .init = xfrm_net_init, 2986 .init = xfrm_net_init,
2987 .exit = xfrm_net_exit, 2987 .exit = xfrm_net_exit,
2988 .async = true,
2988}; 2989};
2989 2990
2990void __init xfrm_init(void) 2991void __init xfrm_init(void)
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 080035f056d9..e92b8c019c88 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -3253,6 +3253,7 @@ static void __net_exit xfrm_user_net_exit(struct list_head *net_exit_list)
3253static struct pernet_operations xfrm_user_net_ops = { 3253static struct pernet_operations xfrm_user_net_ops = {
3254 .init = xfrm_user_net_init, 3254 .init = xfrm_user_net_init,
3255 .exit_batch = xfrm_user_net_exit, 3255 .exit_batch = xfrm_user_net_exit,
3256 .async = true,
3256}; 3257};
3257 3258
3258static int __init xfrm_user_init(void) 3259static int __init xfrm_user_init(void)
diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index ec3fc8d88e87..2c2a587e0942 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -43,6 +43,7 @@ hostprogs-y += xdp_redirect_cpu
43hostprogs-y += xdp_monitor 43hostprogs-y += xdp_monitor
44hostprogs-y += xdp_rxq_info 44hostprogs-y += xdp_rxq_info
45hostprogs-y += syscall_tp 45hostprogs-y += syscall_tp
46hostprogs-y += cpustat
46 47
47# Libbpf dependencies 48# Libbpf dependencies
48LIBBPF := ../../tools/lib/bpf/bpf.o ../../tools/lib/bpf/nlattr.o 49LIBBPF := ../../tools/lib/bpf/bpf.o ../../tools/lib/bpf/nlattr.o
@@ -93,6 +94,7 @@ xdp_redirect_cpu-objs := bpf_load.o $(LIBBPF) xdp_redirect_cpu_user.o
93xdp_monitor-objs := bpf_load.o $(LIBBPF) xdp_monitor_user.o 94xdp_monitor-objs := bpf_load.o $(LIBBPF) xdp_monitor_user.o
94xdp_rxq_info-objs := bpf_load.o $(LIBBPF) xdp_rxq_info_user.o 95xdp_rxq_info-objs := bpf_load.o $(LIBBPF) xdp_rxq_info_user.o
95syscall_tp-objs := bpf_load.o $(LIBBPF) syscall_tp_user.o 96syscall_tp-objs := bpf_load.o $(LIBBPF) syscall_tp_user.o
97cpustat-objs := bpf_load.o $(LIBBPF) cpustat_user.o
96 98
97# Tell kbuild to always build the programs 99# Tell kbuild to always build the programs
98always := $(hostprogs-y) 100always := $(hostprogs-y)
@@ -144,6 +146,7 @@ always += xdp_monitor_kern.o
144always += xdp_rxq_info_kern.o 146always += xdp_rxq_info_kern.o
145always += xdp2skb_meta_kern.o 147always += xdp2skb_meta_kern.o
146always += syscall_tp_kern.o 148always += syscall_tp_kern.o
149always += cpustat_kern.o
147 150
148HOSTCFLAGS += -I$(objtree)/usr/include 151HOSTCFLAGS += -I$(objtree)/usr/include
149HOSTCFLAGS += -I$(srctree)/tools/lib/ 152HOSTCFLAGS += -I$(srctree)/tools/lib/
@@ -188,6 +191,7 @@ HOSTLOADLIBES_xdp_redirect_cpu += -lelf
188HOSTLOADLIBES_xdp_monitor += -lelf 191HOSTLOADLIBES_xdp_monitor += -lelf
189HOSTLOADLIBES_xdp_rxq_info += -lelf 192HOSTLOADLIBES_xdp_rxq_info += -lelf
190HOSTLOADLIBES_syscall_tp += -lelf 193HOSTLOADLIBES_syscall_tp += -lelf
194HOSTLOADLIBES_cpustat += -lelf
191 195
192# Allows pointing LLC/CLANG to a LLVM backend with bpf support, redefine on cmdline: 196# Allows pointing LLC/CLANG to a LLVM backend with bpf support, redefine on cmdline:
193# make samples/bpf/ LLC=~/git/llvm/build/bin/llc CLANG=~/git/llvm/build/bin/clang 197# make samples/bpf/ LLC=~/git/llvm/build/bin/llc CLANG=~/git/llvm/build/bin/clang
diff --git a/samples/bpf/bpf_load.c b/samples/bpf/bpf_load.c
index 69806d74fa53..b1a310c3ae89 100644
--- a/samples/bpf/bpf_load.c
+++ b/samples/bpf/bpf_load.c
@@ -67,6 +67,7 @@ static int load_and_attach(const char *event, struct bpf_insn *prog, int size)
67 bool is_cgroup_sk = strncmp(event, "cgroup/sock", 11) == 0; 67 bool is_cgroup_sk = strncmp(event, "cgroup/sock", 11) == 0;
68 bool is_sockops = strncmp(event, "sockops", 7) == 0; 68 bool is_sockops = strncmp(event, "sockops", 7) == 0;
69 bool is_sk_skb = strncmp(event, "sk_skb", 6) == 0; 69 bool is_sk_skb = strncmp(event, "sk_skb", 6) == 0;
70 bool is_sk_msg = strncmp(event, "sk_msg", 6) == 0;
70 size_t insns_cnt = size / sizeof(struct bpf_insn); 71 size_t insns_cnt = size / sizeof(struct bpf_insn);
71 enum bpf_prog_type prog_type; 72 enum bpf_prog_type prog_type;
72 char buf[256]; 73 char buf[256];
@@ -96,6 +97,8 @@ static int load_and_attach(const char *event, struct bpf_insn *prog, int size)
96 prog_type = BPF_PROG_TYPE_SOCK_OPS; 97 prog_type = BPF_PROG_TYPE_SOCK_OPS;
97 } else if (is_sk_skb) { 98 } else if (is_sk_skb) {
98 prog_type = BPF_PROG_TYPE_SK_SKB; 99 prog_type = BPF_PROG_TYPE_SK_SKB;
100 } else if (is_sk_msg) {
101 prog_type = BPF_PROG_TYPE_SK_MSG;
99 } else { 102 } else {
100 printf("Unknown event '%s'\n", event); 103 printf("Unknown event '%s'\n", event);
101 return -1; 104 return -1;
@@ -113,7 +116,7 @@ static int load_and_attach(const char *event, struct bpf_insn *prog, int size)
113 if (is_xdp || is_perf_event || is_cgroup_skb || is_cgroup_sk) 116 if (is_xdp || is_perf_event || is_cgroup_skb || is_cgroup_sk)
114 return 0; 117 return 0;
115 118
116 if (is_socket || is_sockops || is_sk_skb) { 119 if (is_socket || is_sockops || is_sk_skb || is_sk_msg) {
117 if (is_socket) 120 if (is_socket)
118 event += 6; 121 event += 6;
119 else 122 else
@@ -589,7 +592,8 @@ static int do_load_bpf_file(const char *path, fixup_map_cb fixup_map)
589 memcmp(shname, "socket", 6) == 0 || 592 memcmp(shname, "socket", 6) == 0 ||
590 memcmp(shname, "cgroup/", 7) == 0 || 593 memcmp(shname, "cgroup/", 7) == 0 ||
591 memcmp(shname, "sockops", 7) == 0 || 594 memcmp(shname, "sockops", 7) == 0 ||
592 memcmp(shname, "sk_skb", 6) == 0) { 595 memcmp(shname, "sk_skb", 6) == 0 ||
596 memcmp(shname, "sk_msg", 6) == 0) {
593 ret = load_and_attach(shname, data->d_buf, 597 ret = load_and_attach(shname, data->d_buf,
594 data->d_size); 598 data->d_size);
595 if (ret != 0) 599 if (ret != 0)
diff --git a/samples/bpf/cpustat_kern.c b/samples/bpf/cpustat_kern.c
new file mode 100644
index 000000000000..68c84da065b1
--- /dev/null
+++ b/samples/bpf/cpustat_kern.c
@@ -0,0 +1,281 @@
1// SPDX-License-Identifier: GPL-2.0
2
3#include <linux/version.h>
4#include <linux/ptrace.h>
5#include <uapi/linux/bpf.h>
6#include "bpf_helpers.h"
7
8/*
9 * The CPU number, cstate number and pstate number are based
10 * on 96boards Hikey with octa CA53 CPUs.
11 *
12 * Every CPU have three idle states for cstate:
13 * WFI, CPU_OFF, CLUSTER_OFF
14 *
15 * Every CPU have 5 operating points:
16 * 208MHz, 432MHz, 729MHz, 960MHz, 1200MHz
17 *
18 * This code is based on these assumption and other platforms
19 * need to adjust these definitions.
20 */
21#define MAX_CPU 8
22#define MAX_PSTATE_ENTRIES 5
23#define MAX_CSTATE_ENTRIES 3
24
25static int cpu_opps[] = { 208000, 432000, 729000, 960000, 1200000 };
26
27/*
28 * my_map structure is used to record cstate and pstate index and
29 * timestamp (Idx, Ts), when new event incoming we need to update
30 * combination for new state index and timestamp (Idx`, Ts`).
31 *
32 * Based on (Idx, Ts) and (Idx`, Ts`) we can calculate the time
33 * interval for the previous state: Duration(Idx) = Ts` - Ts.
34 *
35 * Every CPU has one below array for recording state index and
36 * timestamp, and record for cstate and pstate saperately:
37 *
38 * +--------------------------+
39 * | cstate timestamp |
40 * +--------------------------+
41 * | cstate index |
42 * +--------------------------+
43 * | pstate timestamp |
44 * +--------------------------+
45 * | pstate index |
46 * +--------------------------+
47 */
48#define MAP_OFF_CSTATE_TIME 0
49#define MAP_OFF_CSTATE_IDX 1
50#define MAP_OFF_PSTATE_TIME 2
51#define MAP_OFF_PSTATE_IDX 3
52#define MAP_OFF_NUM 4
53
54struct bpf_map_def SEC("maps") my_map = {
55 .type = BPF_MAP_TYPE_ARRAY,
56 .key_size = sizeof(u32),
57 .value_size = sizeof(u64),
58 .max_entries = MAX_CPU * MAP_OFF_NUM,
59};
60
61/* cstate_duration records duration time for every idle state per CPU */
62struct bpf_map_def SEC("maps") cstate_duration = {
63 .type = BPF_MAP_TYPE_ARRAY,
64 .key_size = sizeof(u32),
65 .value_size = sizeof(u64),
66 .max_entries = MAX_CPU * MAX_CSTATE_ENTRIES,
67};
68
69/* pstate_duration records duration time for every operating point per CPU */
70struct bpf_map_def SEC("maps") pstate_duration = {
71 .type = BPF_MAP_TYPE_ARRAY,
72 .key_size = sizeof(u32),
73 .value_size = sizeof(u64),
74 .max_entries = MAX_CPU * MAX_PSTATE_ENTRIES,
75};
76
77/*
78 * The trace events for cpu_idle and cpu_frequency are taken from:
79 * /sys/kernel/debug/tracing/events/power/cpu_idle/format
80 * /sys/kernel/debug/tracing/events/power/cpu_frequency/format
81 *
82 * These two events have same format, so define one common structure.
83 */
84struct cpu_args {
85 u64 pad;
86 u32 state;
87 u32 cpu_id;
88};
89
90/* calculate pstate index, returns MAX_PSTATE_ENTRIES for failure */
91static u32 find_cpu_pstate_idx(u32 frequency)
92{
93 u32 i;
94
95 for (i = 0; i < sizeof(cpu_opps) / sizeof(u32); i++) {
96 if (frequency == cpu_opps[i])
97 return i;
98 }
99
100 return i;
101}
102
103SEC("tracepoint/power/cpu_idle")
104int bpf_prog1(struct cpu_args *ctx)
105{
106 u64 *cts, *pts, *cstate, *pstate, prev_state, cur_ts, delta;
107 u32 key, cpu, pstate_idx;
108 u64 *val;
109
110 if (ctx->cpu_id > MAX_CPU)
111 return 0;
112
113 cpu = ctx->cpu_id;
114
115 key = cpu * MAP_OFF_NUM + MAP_OFF_CSTATE_TIME;
116 cts = bpf_map_lookup_elem(&my_map, &key);
117 if (!cts)
118 return 0;
119
120 key = cpu * MAP_OFF_NUM + MAP_OFF_CSTATE_IDX;
121 cstate = bpf_map_lookup_elem(&my_map, &key);
122 if (!cstate)
123 return 0;
124
125 key = cpu * MAP_OFF_NUM + MAP_OFF_PSTATE_TIME;
126 pts = bpf_map_lookup_elem(&my_map, &key);
127 if (!pts)
128 return 0;
129
130 key = cpu * MAP_OFF_NUM + MAP_OFF_PSTATE_IDX;
131 pstate = bpf_map_lookup_elem(&my_map, &key);
132 if (!pstate)
133 return 0;
134
135 prev_state = *cstate;
136 *cstate = ctx->state;
137
138 if (!*cts) {
139 *cts = bpf_ktime_get_ns();
140 return 0;
141 }
142
143 cur_ts = bpf_ktime_get_ns();
144 delta = cur_ts - *cts;
145 *cts = cur_ts;
146
147 /*
148 * When state doesn't equal to (u32)-1, the cpu will enter
149 * one idle state; for this case we need to record interval
150 * for the pstate.
151 *
152 * OPP2
153 * +---------------------+
154 * OPP1 | |
155 * ---------+ |
156 * | Idle state
157 * +---------------
158 *
159 * |<- pstate duration ->|
160 * ^ ^
161 * pts cur_ts
162 */
163 if (ctx->state != (u32)-1) {
164
165 /* record pstate after have first cpu_frequency event */
166 if (!*pts)
167 return 0;
168
169 delta = cur_ts - *pts;
170
171 pstate_idx = find_cpu_pstate_idx(*pstate);
172 if (pstate_idx >= MAX_PSTATE_ENTRIES)
173 return 0;
174
175 key = cpu * MAX_PSTATE_ENTRIES + pstate_idx;
176 val = bpf_map_lookup_elem(&pstate_duration, &key);
177 if (val)
178 __sync_fetch_and_add((long *)val, delta);
179
180 /*
181 * When state equal to (u32)-1, the cpu just exits from one
182 * specific idle state; for this case we need to record
183 * interval for the pstate.
184 *
185 * OPP2
186 * -----------+
187 * | OPP1
188 * | +-----------
189 * | Idle state |
190 * +---------------------+
191 *
192 * |<- cstate duration ->|
193 * ^ ^
194 * cts cur_ts
195 */
196 } else {
197
198 key = cpu * MAX_CSTATE_ENTRIES + prev_state;
199 val = bpf_map_lookup_elem(&cstate_duration, &key);
200 if (val)
201 __sync_fetch_and_add((long *)val, delta);
202 }
203
204 /* Update timestamp for pstate as new start time */
205 if (*pts)
206 *pts = cur_ts;
207
208 return 0;
209}
210
211SEC("tracepoint/power/cpu_frequency")
212int bpf_prog2(struct cpu_args *ctx)
213{
214 u64 *pts, *cstate, *pstate, prev_state, cur_ts, delta;
215 u32 key, cpu, pstate_idx;
216 u64 *val;
217
218 cpu = ctx->cpu_id;
219
220 key = cpu * MAP_OFF_NUM + MAP_OFF_PSTATE_TIME;
221 pts = bpf_map_lookup_elem(&my_map, &key);
222 if (!pts)
223 return 0;
224
225 key = cpu * MAP_OFF_NUM + MAP_OFF_PSTATE_IDX;
226 pstate = bpf_map_lookup_elem(&my_map, &key);
227 if (!pstate)
228 return 0;
229
230 key = cpu * MAP_OFF_NUM + MAP_OFF_CSTATE_IDX;
231 cstate = bpf_map_lookup_elem(&my_map, &key);
232 if (!cstate)
233 return 0;
234
235 prev_state = *pstate;
236 *pstate = ctx->state;
237
238 if (!*pts) {
239 *pts = bpf_ktime_get_ns();
240 return 0;
241 }
242
243 cur_ts = bpf_ktime_get_ns();
244 delta = cur_ts - *pts;
245 *pts = cur_ts;
246
247 /* When CPU is in idle, bail out to skip pstate statistics */
248 if (*cstate != (u32)(-1))
249 return 0;
250
251 /*
252 * The cpu changes to another different OPP (in below diagram
253 * change frequency from OPP3 to OPP1), need recording interval
254 * for previous frequency OPP3 and update timestamp as start
255 * time for new frequency OPP1.
256 *
257 * OPP3
258 * +---------------------+
259 * OPP2 | |
260 * ---------+ |
261 * | OPP1
262 * +---------------
263 *
264 * |<- pstate duration ->|
265 * ^ ^
266 * pts cur_ts
267 */
268 pstate_idx = find_cpu_pstate_idx(*pstate);
269 if (pstate_idx >= MAX_PSTATE_ENTRIES)
270 return 0;
271
272 key = cpu * MAX_PSTATE_ENTRIES + pstate_idx;
273 val = bpf_map_lookup_elem(&pstate_duration, &key);
274 if (val)
275 __sync_fetch_and_add((long *)val, delta);
276
277 return 0;
278}
279
280char _license[] SEC("license") = "GPL";
281u32 _version SEC("version") = LINUX_VERSION_CODE;
diff --git a/samples/bpf/cpustat_user.c b/samples/bpf/cpustat_user.c
new file mode 100644
index 000000000000..2b4cd1ae57c5
--- /dev/null
+++ b/samples/bpf/cpustat_user.c
@@ -0,0 +1,219 @@
1// SPDX-License-Identifier: GPL-2.0
2
3#define _GNU_SOURCE
4#include <errno.h>
5#include <stdio.h>
6#include <stdlib.h>
7#include <signal.h>
8#include <sched.h>
9#include <string.h>
10#include <unistd.h>
11#include <fcntl.h>
12#include <linux/bpf.h>
13#include <locale.h>
14#include <sys/types.h>
15#include <sys/stat.h>
16#include <sys/time.h>
17#include <sys/resource.h>
18#include <sys/wait.h>
19
20#include "libbpf.h"
21#include "bpf_load.h"
22
23#define MAX_CPU 8
24#define MAX_PSTATE_ENTRIES 5
25#define MAX_CSTATE_ENTRIES 3
26#define MAX_STARS 40
27
28#define CPUFREQ_MAX_SYSFS_PATH "/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq"
29#define CPUFREQ_LOWEST_FREQ "208000"
30#define CPUFREQ_HIGHEST_FREQ "12000000"
31
32struct cpu_stat_data {
33 unsigned long cstate[MAX_CSTATE_ENTRIES];
34 unsigned long pstate[MAX_PSTATE_ENTRIES];
35};
36
37static struct cpu_stat_data stat_data[MAX_CPU];
38
39static void cpu_stat_print(void)
40{
41 int i, j;
42 char state_str[sizeof("cstate-9")];
43 struct cpu_stat_data *data;
44
45 /* Clear screen */
46 printf("\033[2J");
47
48 /* Header */
49 printf("\nCPU states statistics:\n");
50 printf("%-10s ", "state(ms)");
51
52 for (i = 0; i < MAX_CSTATE_ENTRIES; i++) {
53 sprintf(state_str, "cstate-%d", i);
54 printf("%-11s ", state_str);
55 }
56
57 for (i = 0; i < MAX_PSTATE_ENTRIES; i++) {
58 sprintf(state_str, "pstate-%d", i);
59 printf("%-11s ", state_str);
60 }
61
62 printf("\n");
63
64 for (j = 0; j < MAX_CPU; j++) {
65 data = &stat_data[j];
66
67 printf("CPU-%-6d ", j);
68 for (i = 0; i < MAX_CSTATE_ENTRIES; i++)
69 printf("%-11ld ", data->cstate[i] / 1000000);
70
71 for (i = 0; i < MAX_PSTATE_ENTRIES; i++)
72 printf("%-11ld ", data->pstate[i] / 1000000);
73
74 printf("\n");
75 }
76}
77
78static void cpu_stat_update(int cstate_fd, int pstate_fd)
79{
80 unsigned long key, value;
81 int c, i;
82
83 for (c = 0; c < MAX_CPU; c++) {
84 for (i = 0; i < MAX_CSTATE_ENTRIES; i++) {
85 key = c * MAX_CSTATE_ENTRIES + i;
86 bpf_map_lookup_elem(cstate_fd, &key, &value);
87 stat_data[c].cstate[i] = value;
88 }
89
90 for (i = 0; i < MAX_PSTATE_ENTRIES; i++) {
91 key = c * MAX_PSTATE_ENTRIES + i;
92 bpf_map_lookup_elem(pstate_fd, &key, &value);
93 stat_data[c].pstate[i] = value;
94 }
95 }
96}
97
98/*
99 * This function is copied from 'idlestat' tool function
100 * idlestat_wake_all() in idlestate.c.
101 *
102 * It sets the self running task affinity to cpus one by one so can wake up
103 * the specific CPU to handle scheduling; this results in all cpus can be
104 * waken up once and produce ftrace event 'trace_cpu_idle'.
105 */
106static int cpu_stat_inject_cpu_idle_event(void)
107{
108 int rcpu, i, ret;
109 cpu_set_t cpumask;
110 cpu_set_t original_cpumask;
111
112 ret = sysconf(_SC_NPROCESSORS_CONF);
113 if (ret < 0)
114 return -1;
115
116 rcpu = sched_getcpu();
117 if (rcpu < 0)
118 return -1;
119
120 /* Keep track of the CPUs we will run on */
121 sched_getaffinity(0, sizeof(original_cpumask), &original_cpumask);
122
123 for (i = 0; i < ret; i++) {
124
125 /* Pointless to wake up ourself */
126 if (i == rcpu)
127 continue;
128
129 /* Pointless to wake CPUs we will not run on */
130 if (!CPU_ISSET(i, &original_cpumask))
131 continue;
132
133 CPU_ZERO(&cpumask);
134 CPU_SET(i, &cpumask);
135
136 sched_setaffinity(0, sizeof(cpumask), &cpumask);
137 }
138
139 /* Enable all the CPUs of the original mask */
140 sched_setaffinity(0, sizeof(original_cpumask), &original_cpumask);
141 return 0;
142}
143
144/*
145 * It's possible to have no any frequency change for long time and cannot
146 * get ftrace event 'trace_cpu_frequency' for long period, this introduces
147 * big deviation for pstate statistics.
148 *
149 * To solve this issue, below code forces to set 'scaling_max_freq' to 208MHz
150 * for triggering ftrace event 'trace_cpu_frequency' and then recovery back to
151 * the maximum frequency value 1.2GHz.
152 */
153static int cpu_stat_inject_cpu_frequency_event(void)
154{
155 int len, fd;
156
157 fd = open(CPUFREQ_MAX_SYSFS_PATH, O_WRONLY);
158 if (fd < 0) {
159 printf("failed to open scaling_max_freq, errno=%d\n", errno);
160 return fd;
161 }
162
163 len = write(fd, CPUFREQ_LOWEST_FREQ, strlen(CPUFREQ_LOWEST_FREQ));
164 if (len < 0) {
165 printf("failed to open scaling_max_freq, errno=%d\n", errno);
166 goto err;
167 }
168
169 len = write(fd, CPUFREQ_HIGHEST_FREQ, strlen(CPUFREQ_HIGHEST_FREQ));
170 if (len < 0) {
171 printf("failed to open scaling_max_freq, errno=%d\n", errno);
172 goto err;
173 }
174
175err:
176 close(fd);
177 return len;
178}
179
180static void int_exit(int sig)
181{
182 cpu_stat_inject_cpu_idle_event();
183 cpu_stat_inject_cpu_frequency_event();
184 cpu_stat_update(map_fd[1], map_fd[2]);
185 cpu_stat_print();
186 exit(0);
187}
188
189int main(int argc, char **argv)
190{
191 char filename[256];
192 int ret;
193
194 snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
195
196 if (load_bpf_file(filename)) {
197 printf("%s", bpf_log_buf);
198 return 1;
199 }
200
201 ret = cpu_stat_inject_cpu_idle_event();
202 if (ret < 0)
203 return 1;
204
205 ret = cpu_stat_inject_cpu_frequency_event();
206 if (ret < 0)
207 return 1;
208
209 signal(SIGINT, int_exit);
210 signal(SIGTERM, int_exit);
211
212 while (1) {
213 cpu_stat_update(map_fd[1], map_fd[2]);
214 cpu_stat_print();
215 sleep(5);
216 }
217
218 return 0;
219}
diff --git a/samples/bpf/tcbpf2_kern.c b/samples/bpf/tcbpf2_kern.c
index efdc16d195ff..9a8db7bd6db4 100644
--- a/samples/bpf/tcbpf2_kern.c
+++ b/samples/bpf/tcbpf2_kern.c
@@ -52,7 +52,8 @@ int _gre_set_tunnel(struct __sk_buff *skb)
52 key.tunnel_tos = 0; 52 key.tunnel_tos = 0;
53 key.tunnel_ttl = 64; 53 key.tunnel_ttl = 64;
54 54
55 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX); 55 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
56 BPF_F_ZERO_CSUM_TX | BPF_F_SEQ_NUMBER);
56 if (ret < 0) { 57 if (ret < 0) {
57 ERROR(ret); 58 ERROR(ret);
58 return TC_ACT_SHOT; 59 return TC_ACT_SHOT;
@@ -92,7 +93,8 @@ int _ip6gretap_set_tunnel(struct __sk_buff *skb)
92 key.tunnel_label = 0xabcde; 93 key.tunnel_label = 0xabcde;
93 94
94 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), 95 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
95 BPF_F_TUNINFO_IPV6 | BPF_F_ZERO_CSUM_TX); 96 BPF_F_TUNINFO_IPV6 | BPF_F_ZERO_CSUM_TX |
97 BPF_F_SEQ_NUMBER);
96 if (ret < 0) { 98 if (ret < 0) {
97 ERROR(ret); 99 ERROR(ret);
98 return TC_ACT_SHOT; 100 return TC_ACT_SHOT;
diff --git a/samples/bpf/test_cgrp2_sock.sh b/samples/bpf/test_cgrp2_sock.sh
index 8ee0371a100a..9f6174236856 100755
--- a/samples/bpf/test_cgrp2_sock.sh
+++ b/samples/bpf/test_cgrp2_sock.sh
@@ -61,6 +61,7 @@ cleanup_and_exit()
61 61
62 [ -n "$msg" ] && echo "ERROR: $msg" 62 [ -n "$msg" ] && echo "ERROR: $msg"
63 63
64 test_cgrp2_sock -d ${CGRP_MNT}/sockopts
64 ip li del cgrp2_sock 65 ip li del cgrp2_sock
65 umount ${CGRP_MNT} 66 umount ${CGRP_MNT}
66 67
diff --git a/samples/bpf/test_cgrp2_sock2.sh b/samples/bpf/test_cgrp2_sock2.sh
index fc4e64d00cb3..0f396a86e0cb 100755
--- a/samples/bpf/test_cgrp2_sock2.sh
+++ b/samples/bpf/test_cgrp2_sock2.sh
@@ -28,6 +28,9 @@ function attach_bpf {
28} 28}
29 29
30function cleanup { 30function cleanup {
31 if [ -d /tmp/cgroupv2/foo ]; then
32 test_cgrp2_sock -d /tmp/cgroupv2/foo
33 fi
31 ip link del veth0b 34 ip link del veth0b
32 ip netns delete at_ns0 35 ip netns delete at_ns0
33 umount /tmp/cgroupv2 36 umount /tmp/cgroupv2
diff --git a/samples/bpf/test_tunnel_bpf.sh b/samples/bpf/test_tunnel_bpf.sh
index 43ce049996ee..c265863ccdf9 100755
--- a/samples/bpf/test_tunnel_bpf.sh
+++ b/samples/bpf/test_tunnel_bpf.sh
@@ -23,7 +23,8 @@ function config_device {
23function add_gre_tunnel { 23function add_gre_tunnel {
24 # in namespace 24 # in namespace
25 ip netns exec at_ns0 \ 25 ip netns exec at_ns0 \
26 ip link add dev $DEV_NS type $TYPE key 2 local 172.16.1.100 remote 172.16.1.200 26 ip link add dev $DEV_NS type $TYPE seq key 2 \
27 local 172.16.1.100 remote 172.16.1.200
27 ip netns exec at_ns0 ip link set dev $DEV_NS up 28 ip netns exec at_ns0 ip link set dev $DEV_NS up
28 ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24 29 ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
29 30
@@ -43,7 +44,7 @@ function add_ip6gretap_tunnel {
43 44
44 # in namespace 45 # in namespace
45 ip netns exec at_ns0 \ 46 ip netns exec at_ns0 \
46 ip link add dev $DEV_NS type $TYPE flowlabel 0xbcdef key 2 \ 47 ip link add dev $DEV_NS type $TYPE seq flowlabel 0xbcdef key 2 \
47 local ::11 remote ::22 48 local ::11 remote ::22
48 49
49 ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24 50 ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
diff --git a/samples/bpf/trace_event_kern.c b/samples/bpf/trace_event_kern.c
index a77a583d94d4..7068fbdde951 100644
--- a/samples/bpf/trace_event_kern.c
+++ b/samples/bpf/trace_event_kern.c
@@ -39,6 +39,7 @@ int bpf_prog1(struct bpf_perf_event_data *ctx)
39{ 39{
40 char time_fmt1[] = "Time Enabled: %llu, Time Running: %llu"; 40 char time_fmt1[] = "Time Enabled: %llu, Time Running: %llu";
41 char time_fmt2[] = "Get Time Failed, ErrCode: %d"; 41 char time_fmt2[] = "Get Time Failed, ErrCode: %d";
42 char addr_fmt[] = "Address recorded on event: %llx";
42 char fmt[] = "CPU-%d period %lld ip %llx"; 43 char fmt[] = "CPU-%d period %lld ip %llx";
43 u32 cpu = bpf_get_smp_processor_id(); 44 u32 cpu = bpf_get_smp_processor_id();
44 struct bpf_perf_event_value value_buf; 45 struct bpf_perf_event_value value_buf;
@@ -64,6 +65,9 @@ int bpf_prog1(struct bpf_perf_event_data *ctx)
64 else 65 else
65 bpf_trace_printk(time_fmt2, sizeof(time_fmt2), ret); 66 bpf_trace_printk(time_fmt2, sizeof(time_fmt2), ret);
66 67
68 if (ctx->addr != 0)
69 bpf_trace_printk(addr_fmt, sizeof(addr_fmt), ctx->addr);
70
67 val = bpf_map_lookup_elem(&counts, &key); 71 val = bpf_map_lookup_elem(&counts, &key);
68 if (val) 72 if (val)
69 (*val)++; 73 (*val)++;
diff --git a/samples/bpf/trace_event_user.c b/samples/bpf/trace_event_user.c
index bf4f1b6d9a52..56f7a259a7c9 100644
--- a/samples/bpf/trace_event_user.c
+++ b/samples/bpf/trace_event_user.c
@@ -215,6 +215,17 @@ static void test_bpf_perf_event(void)
215 /* Intel Instruction Retired */ 215 /* Intel Instruction Retired */
216 .config = 0xc0, 216 .config = 0xc0,
217 }; 217 };
218 struct perf_event_attr attr_type_raw_lock_load = {
219 .sample_freq = SAMPLE_FREQ,
220 .freq = 1,
221 .type = PERF_TYPE_RAW,
222 /* Intel MEM_UOPS_RETIRED.LOCK_LOADS */
223 .config = 0x21d0,
224 /* Request to record lock address from PEBS */
225 .sample_type = PERF_SAMPLE_ADDR,
226 /* Record address value requires precise event */
227 .precise_ip = 2,
228 };
218 229
219 printf("Test HW_CPU_CYCLES\n"); 230 printf("Test HW_CPU_CYCLES\n");
220 test_perf_event_all_cpu(&attr_type_hw); 231 test_perf_event_all_cpu(&attr_type_hw);
@@ -236,6 +247,10 @@ static void test_bpf_perf_event(void)
236 test_perf_event_all_cpu(&attr_type_raw); 247 test_perf_event_all_cpu(&attr_type_raw);
237 test_perf_event_task(&attr_type_raw); 248 test_perf_event_task(&attr_type_raw);
238 249
250 printf("Test Lock Load\n");
251 test_perf_event_all_cpu(&attr_type_raw_lock_load);
252 test_perf_event_task(&attr_type_raw_lock_load);
253
239 printf("*** PASS ***\n"); 254 printf("*** PASS ***\n");
240} 255}
241 256
diff --git a/samples/bpf/xdp_redirect_user.c b/samples/bpf/xdp_redirect_user.c
index d54e91eb6cbf..b701b5c21342 100644
--- a/samples/bpf/xdp_redirect_user.c
+++ b/samples/bpf/xdp_redirect_user.c
@@ -20,6 +20,7 @@
20#include <string.h> 20#include <string.h>
21#include <unistd.h> 21#include <unistd.h>
22#include <libgen.h> 22#include <libgen.h>
23#include <sys/resource.h>
23 24
24#include "bpf_load.h" 25#include "bpf_load.h"
25#include "bpf_util.h" 26#include "bpf_util.h"
@@ -75,6 +76,7 @@ static void usage(const char *prog)
75 76
76int main(int argc, char **argv) 77int main(int argc, char **argv)
77{ 78{
79 struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
78 const char *optstr = "SN"; 80 const char *optstr = "SN";
79 char filename[256]; 81 char filename[256];
80 int ret, opt, key = 0; 82 int ret, opt, key = 0;
@@ -98,6 +100,11 @@ int main(int argc, char **argv)
98 return 1; 100 return 1;
99 } 101 }
100 102
103 if (setrlimit(RLIMIT_MEMLOCK, &r)) {
104 perror("setrlimit(RLIMIT_MEMLOCK)");
105 return 1;
106 }
107
101 ifindex_in = strtoul(argv[optind], NULL, 0); 108 ifindex_in = strtoul(argv[optind], NULL, 0);
102 ifindex_out = strtoul(argv[optind + 1], NULL, 0); 109 ifindex_out = strtoul(argv[optind + 1], NULL, 0);
103 printf("input: %d output: %d\n", ifindex_in, ifindex_out); 110 printf("input: %d output: %d\n", ifindex_in, ifindex_out);
diff --git a/samples/sockmap/Makefile b/samples/sockmap/Makefile
index 73f1da4d116c..9bf2881bd11b 100644
--- a/samples/sockmap/Makefile
+++ b/samples/sockmap/Makefile
@@ -2,7 +2,7 @@
2hostprogs-y := sockmap 2hostprogs-y := sockmap
3 3
4# Libbpf dependencies 4# Libbpf dependencies
5LIBBPF := ../../tools/lib/bpf/bpf.o 5LIBBPF := ../../tools/lib/bpf/bpf.o ../../tools/lib/bpf/nlattr.o
6 6
7HOSTCFLAGS += -I$(objtree)/usr/include 7HOSTCFLAGS += -I$(objtree)/usr/include
8HOSTCFLAGS += -I$(srctree)/tools/lib/ 8HOSTCFLAGS += -I$(srctree)/tools/lib/
diff --git a/samples/sockmap/sockmap_kern.c b/samples/sockmap/sockmap_kern.c
index 52b0053274f4..9ad5ba79c85a 100644
--- a/samples/sockmap/sockmap_kern.c
+++ b/samples/sockmap/sockmap_kern.c
@@ -43,6 +43,42 @@ struct bpf_map_def SEC("maps") sock_map = {
43 .max_entries = 20, 43 .max_entries = 20,
44}; 44};
45 45
46struct bpf_map_def SEC("maps") sock_map_txmsg = {
47 .type = BPF_MAP_TYPE_SOCKMAP,
48 .key_size = sizeof(int),
49 .value_size = sizeof(int),
50 .max_entries = 20,
51};
52
53struct bpf_map_def SEC("maps") sock_map_redir = {
54 .type = BPF_MAP_TYPE_SOCKMAP,
55 .key_size = sizeof(int),
56 .value_size = sizeof(int),
57 .max_entries = 1,
58};
59
60struct bpf_map_def SEC("maps") sock_apply_bytes = {
61 .type = BPF_MAP_TYPE_ARRAY,
62 .key_size = sizeof(int),
63 .value_size = sizeof(int),
64 .max_entries = 1
65};
66
67struct bpf_map_def SEC("maps") sock_cork_bytes = {
68 .type = BPF_MAP_TYPE_ARRAY,
69 .key_size = sizeof(int),
70 .value_size = sizeof(int),
71 .max_entries = 1
72};
73
74struct bpf_map_def SEC("maps") sock_pull_bytes = {
75 .type = BPF_MAP_TYPE_ARRAY,
76 .key_size = sizeof(int),
77 .value_size = sizeof(int),
78 .max_entries = 2
79};
80
81
46SEC("sk_skb1") 82SEC("sk_skb1")
47int bpf_prog1(struct __sk_buff *skb) 83int bpf_prog1(struct __sk_buff *skb)
48{ 84{
@@ -105,4 +141,165 @@ int bpf_sockmap(struct bpf_sock_ops *skops)
105 141
106 return 0; 142 return 0;
107} 143}
144
145SEC("sk_msg1")
146int bpf_prog4(struct sk_msg_md *msg)
147{
148 int *bytes, zero = 0, one = 1;
149 int *start, *end;
150
151 bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
152 if (bytes)
153 bpf_msg_apply_bytes(msg, *bytes);
154 bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
155 if (bytes)
156 bpf_msg_cork_bytes(msg, *bytes);
157 start = bpf_map_lookup_elem(&sock_pull_bytes, &zero);
158 end = bpf_map_lookup_elem(&sock_pull_bytes, &one);
159 if (start && end)
160 bpf_msg_pull_data(msg, *start, *end, 0);
161 return SK_PASS;
162}
163
164SEC("sk_msg2")
165int bpf_prog5(struct sk_msg_md *msg)
166{
167 int err1 = -1, err2 = -1, zero = 0, one = 1;
168 int *bytes, *start, *end, len1, len2;
169
170 bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
171 if (bytes)
172 err1 = bpf_msg_apply_bytes(msg, *bytes);
173 bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
174 if (bytes)
175 err2 = bpf_msg_cork_bytes(msg, *bytes);
176 len1 = (__u64)msg->data_end - (__u64)msg->data;
177 start = bpf_map_lookup_elem(&sock_pull_bytes, &zero);
178 end = bpf_map_lookup_elem(&sock_pull_bytes, &one);
179 if (start && end) {
180 int err;
181
182 bpf_printk("sk_msg2: pull(%i:%i)\n",
183 start ? *start : 0, end ? *end : 0);
184 err = bpf_msg_pull_data(msg, *start, *end, 0);
185 if (err)
186 bpf_printk("sk_msg2: pull_data err %i\n",
187 err);
188 len2 = (__u64)msg->data_end - (__u64)msg->data;
189 bpf_printk("sk_msg2: length update %i->%i\n",
190 len1, len2);
191 }
192 bpf_printk("sk_msg2: data length %i err1 %i err2 %i\n",
193 len1, err1, err2);
194 return SK_PASS;
195}
196
197SEC("sk_msg3")
198int bpf_prog6(struct sk_msg_md *msg)
199{
200 int *bytes, zero = 0, one = 1;
201 int *start, *end;
202
203 bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
204 if (bytes)
205 bpf_msg_apply_bytes(msg, *bytes);
206 bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
207 if (bytes)
208 bpf_msg_cork_bytes(msg, *bytes);
209 start = bpf_map_lookup_elem(&sock_pull_bytes, &zero);
210 end = bpf_map_lookup_elem(&sock_pull_bytes, &one);
211 if (start && end)
212 bpf_msg_pull_data(msg, *start, *end, 0);
213 return bpf_msg_redirect_map(msg, &sock_map_redir, zero, 0);
214}
215
216SEC("sk_msg4")
217int bpf_prog7(struct sk_msg_md *msg)
218{
219 int err1 = 0, err2 = 0, zero = 0, one = 1;
220 int *bytes, *start, *end, len1, len2;
221
222 bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
223 if (bytes)
224 err1 = bpf_msg_apply_bytes(msg, *bytes);
225 bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
226 if (bytes)
227 err2 = bpf_msg_cork_bytes(msg, *bytes);
228 len1 = (__u64)msg->data_end - (__u64)msg->data;
229 start = bpf_map_lookup_elem(&sock_pull_bytes, &zero);
230 end = bpf_map_lookup_elem(&sock_pull_bytes, &one);
231 if (start && end) {
232 int err;
233
234 bpf_printk("sk_msg2: pull(%i:%i)\n",
235 start ? *start : 0, end ? *end : 0);
236 err = bpf_msg_pull_data(msg, *start, *end, 0);
237 if (err)
238 bpf_printk("sk_msg2: pull_data err %i\n",
239 err);
240 len2 = (__u64)msg->data_end - (__u64)msg->data;
241 bpf_printk("sk_msg2: length update %i->%i\n",
242 len1, len2);
243 }
244 bpf_printk("sk_msg3: redirect(%iB) err1=%i err2=%i\n",
245 len1, err1, err2);
246 return bpf_msg_redirect_map(msg, &sock_map_redir, zero, 0);
247}
248
249SEC("sk_msg5")
250int bpf_prog8(struct sk_msg_md *msg)
251{
252 void *data_end = (void *)(long) msg->data_end;
253 void *data = (void *)(long) msg->data;
254 int ret = 0, *bytes, zero = 0;
255
256 bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
257 if (bytes) {
258 ret = bpf_msg_apply_bytes(msg, *bytes);
259 if (ret)
260 return SK_DROP;
261 } else {
262 return SK_DROP;
263 }
264 return SK_PASS;
265}
266SEC("sk_msg6")
267int bpf_prog9(struct sk_msg_md *msg)
268{
269 void *data_end = (void *)(long) msg->data_end;
270 void *data = (void *)(long) msg->data;
271 int ret = 0, *bytes, zero = 0;
272
273 bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
274 if (bytes) {
275 if (((__u64)data_end - (__u64)data) >= *bytes)
276 return SK_PASS;
277 ret = bpf_msg_cork_bytes(msg, *bytes);
278 if (ret)
279 return SK_DROP;
280 }
281 return SK_PASS;
282}
283
284SEC("sk_msg7")
285int bpf_prog10(struct sk_msg_md *msg)
286{
287 int *bytes, zero = 0, one = 1;
288 int *start, *end;
289
290 bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
291 if (bytes)
292 bpf_msg_apply_bytes(msg, *bytes);
293 bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
294 if (bytes)
295 bpf_msg_cork_bytes(msg, *bytes);
296 start = bpf_map_lookup_elem(&sock_pull_bytes, &zero);
297 end = bpf_map_lookup_elem(&sock_pull_bytes, &one);
298 if (start && end)
299 bpf_msg_pull_data(msg, *start, *end, 0);
300
301 return SK_DROP;
302}
303
304
108char _license[] SEC("license") = "GPL"; 305char _license[] SEC("license") = "GPL";
diff --git a/samples/sockmap/sockmap_test.sh b/samples/sockmap/sockmap_test.sh
new file mode 100755
index 000000000000..6d8cc40cca22
--- /dev/null
+++ b/samples/sockmap/sockmap_test.sh
@@ -0,0 +1,450 @@
1#Test a bunch of positive cases to verify basic functionality
2for prog in "--txmsg" "--txmsg_redir" "--txmsg_drop"; do
3for t in "sendmsg" "sendpage"; do
4for r in 1 10 100; do
5 for i in 1 10 100; do
6 for l in 1 10 100; do
7 TEST="./sockmap --cgroup /mnt/cgroup2/ -t $t -r $r -i $i -l $l $prog"
8 echo $TEST
9 $TEST
10 sleep 2
11 done
12 done
13done
14done
15done
16
17#Test max iov
18t="sendmsg"
19r=1
20i=1024
21l=1
22prog="--txmsg"
23
24TEST="./sockmap --cgroup /mnt/cgroup2/ -t $t -r $r -i $i -l $l $prog"
25echo $TEST
26$TEST
27sleep 2
28prog="--txmsg_redir"
29TEST="./sockmap --cgroup /mnt/cgroup2/ -t $t -r $r -i $i -l $l $prog"
30echo $TEST
31$TEST
32
33# Test max iov with 1k send
34
35t="sendmsg"
36r=1
37i=1024
38l=1024
39prog="--txmsg"
40
41TEST="./sockmap --cgroup /mnt/cgroup2/ -t $t -r $r -i $i -l $l $prog"
42echo $TEST
43$TEST
44sleep 2
45prog="--txmsg_redir"
46TEST="./sockmap --cgroup /mnt/cgroup2/ -t $t -r $r -i $i -l $l $prog"
47echo $TEST
48$TEST
49sleep 2
50
51# Test apply with 1B
52r=1
53i=1024
54l=1024
55prog="--txmsg_apply 1"
56
57for t in "sendmsg" "sendpage"; do
58 TEST="./sockmap --cgroup /mnt/cgroup2/ -t $t -r $r -i $i -l $l $prog"
59 echo $TEST
60 $TEST
61 sleep 2
62done
63
64# Test apply with larger value than send
65r=1
66i=8
67l=1024
68prog="--txmsg_apply 2048"
69
70for t in "sendmsg" "sendpage"; do
71 TEST="./sockmap --cgroup /mnt/cgroup2/ -t $t -r $r -i $i -l $l $prog"
72 echo $TEST
73 $TEST
74 sleep 2
75done
76
77# Test apply with apply that never reaches limit
78r=1024
79i=1
80l=1
81prog="--txmsg_apply 2048"
82
83for t in "sendmsg" "sendpage"; do
84 TEST="./sockmap --cgroup /mnt/cgroup2/ -t $t -r $r -i $i -l $l $prog"
85 echo $TEST
86 $TEST
87 sleep 2
88done
89
90# Test apply and redirect with 1B
91r=1
92i=1024
93l=1024
94prog="--txmsg_redir --txmsg_apply 1"
95
96for t in "sendmsg" "sendpage"; do
97 TEST="./sockmap --cgroup /mnt/cgroup2/ -t $t -r $r -i $i -l $l $prog"
98 echo $TEST
99 $TEST
100 sleep 2
101done
102
103# Test apply and redirect with larger value than send
104r=1
105i=8
106l=1024
107prog="--txmsg_redir --txmsg_apply 2048"
108
109for t in "sendmsg" "sendpage"; do
110 TEST="./sockmap --cgroup /mnt/cgroup2/ -t $t -r $r -i $i -l $l $prog"
111 echo $TEST
112 $TEST
113 sleep 2
114done
115
116# Test apply and redirect with apply that never reaches limit
117r=1024
118i=1
119l=1
120prog="--txmsg_apply 2048"
121
122for t in "sendmsg" "sendpage"; do
123 TEST="./sockmap --cgroup /mnt/cgroup2/ -t $t -r $r -i $i -l $l $prog"
124 echo $TEST
125 $TEST
126 sleep 2
127done
128
129# Test cork with 1B not really useful but test it anyways
130r=1
131i=1024
132l=1024
133prog="--txmsg_cork 1"
134
135for t in "sendpage" "sendmsg"; do
136 TEST="./sockmap --cgroup /mnt/cgroup2/ -t $t -r $r -i $i -l $l $prog"
137 echo $TEST
138 $TEST
139 sleep 2
140done
141
142# Test cork with a more reasonable 100B
143r=1
144i=1000
145l=1000
146prog="--txmsg_cork 100"
147
148for t in "sendpage" "sendmsg"; do
149 TEST="./sockmap --cgroup /mnt/cgroup2/ -t $t -r $r -i $i -l $l $prog"
150 echo $TEST
151 $TEST
152 sleep 2
153done
154
155# Test cork with larger value than send
156r=1
157i=8
158l=1024
159prog="--txmsg_cork 2048"
160
161for t in "sendpage" "sendmsg"; do
162 TEST="./sockmap --cgroup /mnt/cgroup2/ -t $t -r $r -i $i -l $l $prog"
163 echo $TEST
164 $TEST
165 sleep 2
166done
167
168# Test cork with cork that never reaches limit
169r=1024
170i=1
171l=1
172prog="--txmsg_cork 2048"
173
174for t in "sendpage" "sendmsg"; do
175 TEST="./sockmap --cgroup /mnt/cgroup2/ -t $t -r $r -i $i -l $l $prog"
176 echo $TEST
177 $TEST
178 sleep 2
179done
180
181r=1
182i=1024
183l=1024
184prog="--txmsg_redir --txmsg_cork 1"
185
186for t in "sendpage" "sendmsg"; do
187 TEST="./sockmap --cgroup /mnt/cgroup2/ -t $t -r $r -i $i -l $l $prog"
188 echo $TEST
189 $TEST
190 sleep 2
191done
192
193# Test cork with a more reasonable 100B
194r=1
195i=1000
196l=1000
197prog="--txmsg_redir --txmsg_cork 100"
198
199for t in "sendpage" "sendmsg"; do
200 TEST="./sockmap --cgroup /mnt/cgroup2/ -t $t -r $r -i $i -l $l $prog"
201 echo $TEST
202 $TEST
203 sleep 2
204done
205
206# Test cork with larger value than send
207r=1
208i=8
209l=1024
210prog="--txmsg_redir --txmsg_cork 2048"
211
212for t in "sendpage" "sendmsg"; do
213 TEST="./sockmap --cgroup /mnt/cgroup2/ -t $t -r $r -i $i -l $l $prog"
214 echo $TEST
215 $TEST
216 sleep 2
217done
218
219# Test cork with cork that never reaches limit
220r=1024
221i=1
222l=1
223prog="--txmsg_cork 2048"
224
225for t in "sendpage" "sendmsg"; do
226 TEST="./sockmap --cgroup /mnt/cgroup2/ -t $t -r $r -i $i -l $l $prog"
227 echo $TEST
228 $TEST
229 sleep 2
230done
231
232
233# mix and match cork and apply not really useful but valid programs
234
235# Test apply < cork
236r=100
237i=1
238l=5
239prog="--txmsg_apply 10 --txmsg_cork 100"
240for t in "sendpage" "sendmsg"; do
241 TEST="./sockmap --cgroup /mnt/cgroup2/ -t $t -r $r -i $i -l $l $prog"
242 echo $TEST
243 $TEST
244 sleep 2
245done
246
247# Try again with larger sizes so we hit overflow case
248r=100
249i=1000
250l=2048
251prog="--txmsg_apply 4096 --txmsg_cork 8096"
252for t in "sendpage" "sendmsg"; do
253 TEST="./sockmap --cgroup /mnt/cgroup2/ -t $t -r $r -i $i -l $l $prog"
254 echo $TEST
255 $TEST
256 sleep 2
257done
258
259# Test apply > cork
260r=100
261i=1
262l=5
263prog="--txmsg_apply 100 --txmsg_cork 10"
264for t in "sendpage" "sendmsg"; do
265 TEST="./sockmap --cgroup /mnt/cgroup2/ -t $t -r $r -i $i -l $l $prog"
266 echo $TEST
267 $TEST
268 sleep 2
269done
270
271# Again with larger sizes so we hit overflow cases
272r=100
273i=1000
274l=2048
275prog="--txmsg_apply 8096 --txmsg_cork 4096"
276for t in "sendpage" "sendmsg"; do
277 TEST="./sockmap --cgroup /mnt/cgroup2/ -t $t -r $r -i $i -l $l $prog"
278 echo $TEST
279 $TEST
280 sleep 2
281done
282
283
284# Test apply = cork
285r=100
286i=1
287l=5
288prog="--txmsg_apply 10 --txmsg_cork 10"
289for t in "sendpage" "sendmsg"; do
290 TEST="./sockmap --cgroup /mnt/cgroup2/ -t $t -r $r -i $i -l $l $prog"
291 echo $TEST
292 $TEST
293 sleep 2
294done
295
296r=100
297i=1000
298l=2048
299prog="--txmsg_apply 4096 --txmsg_cork 4096"
300for t in "sendpage" "sendmsg"; do
301 TEST="./sockmap --cgroup /mnt/cgroup2/ -t $t -r $r -i $i -l $l $prog"
302 echo $TEST
303 $TEST
304 sleep 2
305done
306
307# Test apply < cork
308r=100
309i=1
310l=5
311prog="--txmsg_redir --txmsg_apply 10 --txmsg_cork 100"
312for t in "sendpage" "sendmsg"; do
313 TEST="./sockmap --cgroup /mnt/cgroup2/ -t $t -r $r -i $i -l $l $prog"
314 echo $TEST
315 $TEST
316 sleep 2
317done
318
319# Try again with larger sizes so we hit overflow case
320r=100
321i=1000
322l=2048
323prog="--txmsg_redir --txmsg_apply 4096 --txmsg_cork 8096"
324for t in "sendpage" "sendmsg"; do
325 TEST="./sockmap --cgroup /mnt/cgroup2/ -t $t -r $r -i $i -l $l $prog"
326 echo $TEST
327 $TEST
328 sleep 2
329done
330
331# Test apply > cork
332r=100
333i=1
334l=5
335prog="--txmsg_redir --txmsg_apply 100 --txmsg_cork 10"
336for t in "sendpage" "sendmsg"; do
337 TEST="./sockmap --cgroup /mnt/cgroup2/ -t $t -r $r -i $i -l $l $prog"
338 echo $TEST
339 $TEST
340 sleep 2
341done
342
343# Again with larger sizes so we hit overflow cases
344r=100
345i=1000
346l=2048
347prog="--txmsg_redir --txmsg_apply 8096 --txmsg_cork 4096"
348for t in "sendpage" "sendmsg"; do
349 TEST="./sockmap --cgroup /mnt/cgroup2/ -t $t -r $r -i $i -l $l $prog"
350 echo $TEST
351 $TEST
352 sleep 2
353done
354
355
356# Test apply = cork
357r=100
358i=1
359l=5
360prog="--txmsg_redir --txmsg_apply 10 --txmsg_cork 10"
361for t in "sendpage" "sendmsg"; do
362 TEST="./sockmap --cgroup /mnt/cgroup2/ -t $t -r $r -i $i -l $l $prog"
363 echo $TEST
364 $TEST
365 sleep 2
366done
367
368r=100
369i=1000
370l=2048
371prog="--txmsg_redir --txmsg_apply 4096 --txmsg_cork 4096"
372for t in "sendpage" "sendmsg"; do
373 TEST="./sockmap --cgroup /mnt/cgroup2/ -t $t -r $r -i $i -l $l $prog"
374 echo $TEST
375 $TEST
376 sleep 2
377done
378
379# Tests for bpf_msg_pull_data()
380for i in `seq 99 100 1600`; do
381 TEST="./sockmap --cgroup /mnt/cgroup2/ -t sendpage -r 16 -i 1 -l 100 \
382 --txmsg --txmsg_start 0 --txmsg_end $i --txmsg_cork 1600"
383 echo $TEST
384 $TEST
385 sleep 2
386done
387
388for i in `seq 199 100 1600`; do
389 TEST="./sockmap --cgroup /mnt/cgroup2/ -t sendpage -r 16 -i 1 -l 100 \
390 --txmsg --txmsg_start 100 --txmsg_end $i --txmsg_cork 1600"
391 echo $TEST
392 $TEST
393 sleep 2
394done
395
396TEST="./sockmap --cgroup /mnt/cgroup2/ -t sendpage -r 16 -i 1 -l 100 \
397 --txmsg --txmsg_start 1500 --txmsg_end 1600 --txmsg_cork 1600"
398echo $TEST
399$TEST
400sleep 2
401
402TEST="./sockmap --cgroup /mnt/cgroup2/ -t sendpage -r 16 -i 1 -l 100 \
403 --txmsg --txmsg_start 1111 --txmsg_end 1112 --txmsg_cork 1600"
404echo $TEST
405$TEST
406sleep 2
407
408TEST="./sockmap --cgroup /mnt/cgroup2/ -t sendpage -r 16 -i 1 -l 100 \
409 --txmsg --txmsg_start 1111 --txmsg_end 0 --txmsg_cork 1600"
410echo $TEST
411$TEST
412sleep 2
413
414TEST="./sockmap --cgroup /mnt/cgroup2/ -t sendpage -r 16 -i 1 -l 100 \
415 --txmsg --txmsg_start 0 --txmsg_end 1601 --txmsg_cork 1600"
416echo $TEST
417$TEST
418sleep 2
419
420TEST="./sockmap --cgroup /mnt/cgroup2/ -t sendpage -r 16 -i 1 -l 100 \
421 --txmsg --txmsg_start 0 --txmsg_end 1601 --txmsg_cork 1602"
422echo $TEST
423$TEST
424sleep 2
425
426# Run through gamut again with start and end
427for prog in "--txmsg" "--txmsg_redir" "--txmsg_drop"; do
428for t in "sendmsg" "sendpage"; do
429for r in 1 10 100; do
430 for i in 1 10 100; do
431 for l in 1 10 100; do
432 TEST="./sockmap --cgroup /mnt/cgroup2/ -t $t -r $r -i $i -l $l $prog --txmsg_start 1 --txmsg_end 2"
433 echo $TEST
434 $TEST
435 sleep 2
436 done
437 done
438done
439done
440done
441
442# Some specific tests to cover specific code paths
443./sockmap --cgroup /mnt/cgroup2/ -t sendpage \
444 -r 5 -i 1 -l 1 --txmsg_redir --txmsg_cork 5 --txmsg_apply 3
445./sockmap --cgroup /mnt/cgroup2/ -t sendmsg \
446 -r 5 -i 1 -l 1 --txmsg_redir --txmsg_cork 5 --txmsg_apply 3
447./sockmap --cgroup /mnt/cgroup2/ -t sendpage \
448 -r 5 -i 1 -l 1 --txmsg_redir --txmsg_cork 5 --txmsg_apply 5
449./sockmap --cgroup /mnt/cgroup2/ -t sendmsg \
450 -r 5 -i 1 -l 1 --txmsg_redir --txmsg_cork 5 --txmsg_apply 5
diff --git a/samples/sockmap/sockmap_user.c b/samples/sockmap/sockmap_user.c
index 7c25c0c112bc..07aa237221d1 100644
--- a/samples/sockmap/sockmap_user.c
+++ b/samples/sockmap/sockmap_user.c
@@ -29,6 +29,7 @@
29#include <sys/time.h> 29#include <sys/time.h>
30#include <sys/resource.h> 30#include <sys/resource.h>
31#include <sys/types.h> 31#include <sys/types.h>
32#include <sys/sendfile.h>
32 33
33#include <linux/netlink.h> 34#include <linux/netlink.h>
34#include <linux/socket.h> 35#include <linux/socket.h>
@@ -54,6 +55,16 @@ void running_handler(int a);
54/* global sockets */ 55/* global sockets */
55int s1, s2, c1, c2, p1, p2; 56int s1, s2, c1, c2, p1, p2;
56 57
58int txmsg_pass;
59int txmsg_noisy;
60int txmsg_redir;
61int txmsg_redir_noisy;
62int txmsg_drop;
63int txmsg_apply;
64int txmsg_cork;
65int txmsg_start;
66int txmsg_end;
67
57static const struct option long_options[] = { 68static const struct option long_options[] = {
58 {"help", no_argument, NULL, 'h' }, 69 {"help", no_argument, NULL, 'h' },
59 {"cgroup", required_argument, NULL, 'c' }, 70 {"cgroup", required_argument, NULL, 'c' },
@@ -62,6 +73,16 @@ static const struct option long_options[] = {
62 {"iov_count", required_argument, NULL, 'i' }, 73 {"iov_count", required_argument, NULL, 'i' },
63 {"length", required_argument, NULL, 'l' }, 74 {"length", required_argument, NULL, 'l' },
64 {"test", required_argument, NULL, 't' }, 75 {"test", required_argument, NULL, 't' },
76 {"data_test", no_argument, NULL, 'd' },
77 {"txmsg", no_argument, &txmsg_pass, 1 },
78 {"txmsg_noisy", no_argument, &txmsg_noisy, 1 },
79 {"txmsg_redir", no_argument, &txmsg_redir, 1 },
80 {"txmsg_redir_noisy", no_argument, &txmsg_redir_noisy, 1},
81 {"txmsg_drop", no_argument, &txmsg_drop, 1 },
82 {"txmsg_apply", required_argument, NULL, 'a'},
83 {"txmsg_cork", required_argument, NULL, 'k'},
84 {"txmsg_start", required_argument, NULL, 's'},
85 {"txmsg_end", required_argument, NULL, 'e'},
65 {0, 0, NULL, 0 } 86 {0, 0, NULL, 0 }
66}; 87};
67 88
@@ -195,19 +216,71 @@ struct msg_stats {
195 struct timespec end; 216 struct timespec end;
196}; 217};
197 218
219struct sockmap_options {
220 int verbose;
221 bool base;
222 bool sendpage;
223 bool data_test;
224 bool drop_expected;
225};
226
227static int msg_loop_sendpage(int fd, int iov_length, int cnt,
228 struct msg_stats *s,
229 struct sockmap_options *opt)
230{
231 bool drop = opt->drop_expected;
232 unsigned char k = 0;
233 FILE *file;
234 int i, fp;
235
236 file = fopen(".sendpage_tst.tmp", "w+");
237 for (i = 0; i < iov_length * cnt; i++, k++)
238 fwrite(&k, sizeof(char), 1, file);
239 fflush(file);
240 fseek(file, 0, SEEK_SET);
241 fclose(file);
242
243 fp = open(".sendpage_tst.tmp", O_RDONLY);
244 clock_gettime(CLOCK_MONOTONIC, &s->start);
245 for (i = 0; i < cnt; i++) {
246 int sent = sendfile(fd, fp, NULL, iov_length);
247
248 if (!drop && sent < 0) {
249 perror("send loop error:");
250 close(fp);
251 return sent;
252 } else if (drop && sent >= 0) {
253 printf("sendpage loop error expected: %i\n", sent);
254 close(fp);
255 return -EIO;
256 }
257
258 if (sent > 0)
259 s->bytes_sent += sent;
260 }
261 clock_gettime(CLOCK_MONOTONIC, &s->end);
262 close(fp);
263 return 0;
264}
265
198static int msg_loop(int fd, int iov_count, int iov_length, int cnt, 266static int msg_loop(int fd, int iov_count, int iov_length, int cnt,
199 struct msg_stats *s, bool tx) 267 struct msg_stats *s, bool tx,
268 struct sockmap_options *opt)
200{ 269{
201 struct msghdr msg = {0}; 270 struct msghdr msg = {0};
202 int err, i, flags = MSG_NOSIGNAL; 271 int err, i, flags = MSG_NOSIGNAL;
203 struct iovec *iov; 272 struct iovec *iov;
273 unsigned char k;
274 bool data_test = opt->data_test;
275 bool drop = opt->drop_expected;
204 276
205 iov = calloc(iov_count, sizeof(struct iovec)); 277 iov = calloc(iov_count, sizeof(struct iovec));
206 if (!iov) 278 if (!iov)
207 return errno; 279 return errno;
208 280
281 k = 0;
209 for (i = 0; i < iov_count; i++) { 282 for (i = 0; i < iov_count; i++) {
210 char *d = calloc(iov_length, sizeof(char)); 283 unsigned char *d = calloc(iov_length, sizeof(char));
211 284
212 if (!d) { 285 if (!d) {
213 fprintf(stderr, "iov_count %i/%i OOM\n", i, iov_count); 286 fprintf(stderr, "iov_count %i/%i OOM\n", i, iov_count);
@@ -215,21 +288,34 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt,
215 } 288 }
216 iov[i].iov_base = d; 289 iov[i].iov_base = d;
217 iov[i].iov_len = iov_length; 290 iov[i].iov_len = iov_length;
291
292 if (data_test && tx) {
293 int j;
294
295 for (j = 0; j < iov_length; j++)
296 d[j] = k++;
297 }
218 } 298 }
219 299
220 msg.msg_iov = iov; 300 msg.msg_iov = iov;
221 msg.msg_iovlen = iov_count; 301 msg.msg_iovlen = iov_count;
302 k = 0;
222 303
223 if (tx) { 304 if (tx) {
224 clock_gettime(CLOCK_MONOTONIC, &s->start); 305 clock_gettime(CLOCK_MONOTONIC, &s->start);
225 for (i = 0; i < cnt; i++) { 306 for (i = 0; i < cnt; i++) {
226 int sent = sendmsg(fd, &msg, flags); 307 int sent = sendmsg(fd, &msg, flags);
227 308
228 if (sent < 0) { 309 if (!drop && sent < 0) {
229 perror("send loop error:"); 310 perror("send loop error:");
230 goto out_errno; 311 goto out_errno;
312 } else if (drop && sent >= 0) {
313 printf("send loop error expected: %i\n", sent);
314 errno = -EIO;
315 goto out_errno;
231 } 316 }
232 s->bytes_sent += sent; 317 if (sent > 0)
318 s->bytes_sent += sent;
233 } 319 }
234 clock_gettime(CLOCK_MONOTONIC, &s->end); 320 clock_gettime(CLOCK_MONOTONIC, &s->end);
235 } else { 321 } else {
@@ -272,6 +358,26 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt,
272 } 358 }
273 359
274 s->bytes_recvd += recv; 360 s->bytes_recvd += recv;
361
362 if (data_test) {
363 int j;
364
365 for (i = 0; i < msg.msg_iovlen; i++) {
366 unsigned char *d = iov[i].iov_base;
367
368 for (j = 0;
369 j < iov[i].iov_len && recv; j++) {
370 if (d[j] != k++) {
371 errno = -EIO;
372 fprintf(stderr,
373 "detected data corruption @iov[%i]:%i %02x != %02x, %02x ?= %02x\n",
374 i, j, d[j], k - 1, d[j+1], k + 1);
375 goto out_errno;
376 }
377 recv--;
378 }
379 }
380 }
275 } 381 }
276 clock_gettime(CLOCK_MONOTONIC, &s->end); 382 clock_gettime(CLOCK_MONOTONIC, &s->end);
277 } 383 }
@@ -300,7 +406,7 @@ static inline float recvdBps(struct msg_stats s)
300} 406}
301 407
302static int sendmsg_test(int iov_count, int iov_buf, int cnt, 408static int sendmsg_test(int iov_count, int iov_buf, int cnt,
303 int verbose, bool base) 409 struct sockmap_options *opt)
304{ 410{
305 float sent_Bps = 0, recvd_Bps = 0; 411 float sent_Bps = 0, recvd_Bps = 0;
306 int rx_fd, txpid, rxpid, err = 0; 412 int rx_fd, txpid, rxpid, err = 0;
@@ -309,14 +415,20 @@ static int sendmsg_test(int iov_count, int iov_buf, int cnt,
309 415
310 errno = 0; 416 errno = 0;
311 417
312 if (base) 418 if (opt->base)
313 rx_fd = p1; 419 rx_fd = p1;
314 else 420 else
315 rx_fd = p2; 421 rx_fd = p2;
316 422
317 rxpid = fork(); 423 rxpid = fork();
318 if (rxpid == 0) { 424 if (rxpid == 0) {
319 err = msg_loop(rx_fd, iov_count, iov_buf, cnt, &s, false); 425 if (opt->drop_expected)
426 exit(1);
427
428 if (opt->sendpage)
429 iov_count = 1;
430 err = msg_loop(rx_fd, iov_count, iov_buf,
431 cnt, &s, false, opt);
320 if (err) 432 if (err)
321 fprintf(stderr, 433 fprintf(stderr,
322 "msg_loop_rx: iov_count %i iov_buf %i cnt %i err %i\n", 434 "msg_loop_rx: iov_count %i iov_buf %i cnt %i err %i\n",
@@ -339,7 +451,12 @@ static int sendmsg_test(int iov_count, int iov_buf, int cnt,
339 451
340 txpid = fork(); 452 txpid = fork();
341 if (txpid == 0) { 453 if (txpid == 0) {
342 err = msg_loop(c1, iov_count, iov_buf, cnt, &s, true); 454 if (opt->sendpage)
455 err = msg_loop_sendpage(c1, iov_buf, cnt, &s, opt);
456 else
457 err = msg_loop(c1, iov_count, iov_buf,
458 cnt, &s, true, opt);
459
343 if (err) 460 if (err)
344 fprintf(stderr, 461 fprintf(stderr,
345 "msg_loop_tx: iov_count %i iov_buf %i cnt %i err %i\n", 462 "msg_loop_tx: iov_count %i iov_buf %i cnt %i err %i\n",
@@ -364,7 +481,7 @@ static int sendmsg_test(int iov_count, int iov_buf, int cnt,
364 return err; 481 return err;
365} 482}
366 483
367static int forever_ping_pong(int rate, int verbose) 484static int forever_ping_pong(int rate, struct sockmap_options *opt)
368{ 485{
369 struct timeval timeout; 486 struct timeval timeout;
370 char buf[1024] = {0}; 487 char buf[1024] = {0};
@@ -429,7 +546,7 @@ static int forever_ping_pong(int rate, int verbose)
429 if (rate) 546 if (rate)
430 sleep(rate); 547 sleep(rate);
431 548
432 if (verbose) { 549 if (opt->verbose) {
433 printf("."); 550 printf(".");
434 fflush(stdout); 551 fflush(stdout);
435 552
@@ -443,20 +560,34 @@ enum {
443 PING_PONG, 560 PING_PONG,
444 SENDMSG, 561 SENDMSG,
445 BASE, 562 BASE,
563 BASE_SENDPAGE,
564 SENDPAGE,
446}; 565};
447 566
448int main(int argc, char **argv) 567int main(int argc, char **argv)
449{ 568{
450 int iov_count = 1, length = 1024, rate = 1, verbose = 0; 569 int iov_count = 1, length = 1024, rate = 1, tx_prog_fd;
451 struct rlimit r = {10 * 1024 * 1024, RLIM_INFINITY}; 570 struct rlimit r = {10 * 1024 * 1024, RLIM_INFINITY};
452 int opt, longindex, err, cg_fd = 0; 571 int opt, longindex, err, cg_fd = 0;
572 struct sockmap_options options = {0};
453 int test = PING_PONG; 573 int test = PING_PONG;
454 char filename[256]; 574 char filename[256];
455 575
456 while ((opt = getopt_long(argc, argv, "hvc:r:i:l:t:", 576 while ((opt = getopt_long(argc, argv, ":dhvc:r:i:l:t:",
457 long_options, &longindex)) != -1) { 577 long_options, &longindex)) != -1) {
458 switch (opt) { 578 switch (opt) {
459 /* Cgroup configuration */ 579 case 's':
580 txmsg_start = atoi(optarg);
581 break;
582 case 'e':
583 txmsg_end = atoi(optarg);
584 break;
585 case 'a':
586 txmsg_apply = atoi(optarg);
587 break;
588 case 'k':
589 txmsg_cork = atoi(optarg);
590 break;
460 case 'c': 591 case 'c':
461 cg_fd = open(optarg, O_DIRECTORY, O_RDONLY); 592 cg_fd = open(optarg, O_DIRECTORY, O_RDONLY);
462 if (cg_fd < 0) { 593 if (cg_fd < 0) {
@@ -470,7 +601,7 @@ int main(int argc, char **argv)
470 rate = atoi(optarg); 601 rate = atoi(optarg);
471 break; 602 break;
472 case 'v': 603 case 'v':
473 verbose = 1; 604 options.verbose = 1;
474 break; 605 break;
475 case 'i': 606 case 'i':
476 iov_count = atoi(optarg); 607 iov_count = atoi(optarg);
@@ -478,6 +609,9 @@ int main(int argc, char **argv)
478 case 'l': 609 case 'l':
479 length = atoi(optarg); 610 length = atoi(optarg);
480 break; 611 break;
612 case 'd':
613 options.data_test = true;
614 break;
481 case 't': 615 case 't':
482 if (strcmp(optarg, "ping") == 0) { 616 if (strcmp(optarg, "ping") == 0) {
483 test = PING_PONG; 617 test = PING_PONG;
@@ -485,11 +619,17 @@ int main(int argc, char **argv)
485 test = SENDMSG; 619 test = SENDMSG;
486 } else if (strcmp(optarg, "base") == 0) { 620 } else if (strcmp(optarg, "base") == 0) {
487 test = BASE; 621 test = BASE;
622 } else if (strcmp(optarg, "base_sendpage") == 0) {
623 test = BASE_SENDPAGE;
624 } else if (strcmp(optarg, "sendpage") == 0) {
625 test = SENDPAGE;
488 } else { 626 } else {
489 usage(argv); 627 usage(argv);
490 return -1; 628 return -1;
491 } 629 }
492 break; 630 break;
631 case 0:
632 break;
493 case 'h': 633 case 'h':
494 default: 634 default:
495 usage(argv); 635 usage(argv);
@@ -515,16 +655,16 @@ int main(int argc, char **argv)
515 /* catch SIGINT */ 655 /* catch SIGINT */
516 signal(SIGINT, running_handler); 656 signal(SIGINT, running_handler);
517 657
518 /* If base test skip BPF setup */
519 if (test == BASE)
520 goto run;
521
522 if (load_bpf_file(filename)) { 658 if (load_bpf_file(filename)) {
523 fprintf(stderr, "load_bpf_file: (%s) %s\n", 659 fprintf(stderr, "load_bpf_file: (%s) %s\n",
524 filename, strerror(errno)); 660 filename, strerror(errno));
525 return 1; 661 return 1;
526 } 662 }
527 663
664 /* If base test skip BPF setup */
665 if (test == BASE || test == BASE_SENDPAGE)
666 goto run;
667
528 /* Attach programs to sockmap */ 668 /* Attach programs to sockmap */
529 err = bpf_prog_attach(prog_fd[0], map_fd[0], 669 err = bpf_prog_attach(prog_fd[0], map_fd[0],
530 BPF_SK_SKB_STREAM_PARSER, 0); 670 BPF_SK_SKB_STREAM_PARSER, 0);
@@ -557,15 +697,129 @@ run:
557 goto out; 697 goto out;
558 } 698 }
559 699
560 if (test == PING_PONG) 700 /* Attach txmsg program to sockmap */
561 err = forever_ping_pong(rate, verbose); 701 if (txmsg_pass)
562 else if (test == SENDMSG) 702 tx_prog_fd = prog_fd[3];
563 err = sendmsg_test(iov_count, length, rate, verbose, false); 703 else if (txmsg_noisy)
564 else if (test == BASE) 704 tx_prog_fd = prog_fd[4];
565 err = sendmsg_test(iov_count, length, rate, verbose, true); 705 else if (txmsg_redir)
706 tx_prog_fd = prog_fd[5];
707 else if (txmsg_redir_noisy)
708 tx_prog_fd = prog_fd[6];
709 else if (txmsg_drop)
710 tx_prog_fd = prog_fd[9];
711 /* apply and cork must be last */
712 else if (txmsg_apply)
713 tx_prog_fd = prog_fd[7];
714 else if (txmsg_cork)
715 tx_prog_fd = prog_fd[8];
566 else 716 else
717 tx_prog_fd = 0;
718
719 if (tx_prog_fd) {
720 int redir_fd, i = 0;
721
722 err = bpf_prog_attach(tx_prog_fd,
723 map_fd[1], BPF_SK_MSG_VERDICT, 0);
724 if (err) {
725 fprintf(stderr,
726 "ERROR: bpf_prog_attach (txmsg): %d (%s)\n",
727 err, strerror(errno));
728 return err;
729 }
730
731 err = bpf_map_update_elem(map_fd[1], &i, &c1, BPF_ANY);
732 if (err) {
733 fprintf(stderr,
734 "ERROR: bpf_map_update_elem (txmsg): %d (%s\n",
735 err, strerror(errno));
736 return err;
737 }
738
739 if (txmsg_redir || txmsg_redir_noisy)
740 redir_fd = c2;
741 else
742 redir_fd = c1;
743
744 err = bpf_map_update_elem(map_fd[2], &i, &redir_fd, BPF_ANY);
745 if (err) {
746 fprintf(stderr,
747 "ERROR: bpf_map_update_elem (txmsg): %d (%s\n",
748 err, strerror(errno));
749 return err;
750 }
751
752 if (txmsg_apply) {
753 err = bpf_map_update_elem(map_fd[3],
754 &i, &txmsg_apply, BPF_ANY);
755 if (err) {
756 fprintf(stderr,
757 "ERROR: bpf_map_update_elem (apply_bytes): %d (%s\n",
758 err, strerror(errno));
759 return err;
760 }
761 }
762
763 if (txmsg_cork) {
764 err = bpf_map_update_elem(map_fd[4],
765 &i, &txmsg_cork, BPF_ANY);
766 if (err) {
767 fprintf(stderr,
768 "ERROR: bpf_map_update_elem (cork_bytes): %d (%s\n",
769 err, strerror(errno));
770 return err;
771 }
772 }
773
774 if (txmsg_start) {
775 err = bpf_map_update_elem(map_fd[5],
776 &i, &txmsg_start, BPF_ANY);
777 if (err) {
778 fprintf(stderr,
779 "ERROR: bpf_map_update_elem (txmsg_start): %d (%s)\n",
780 err, strerror(errno));
781 return err;
782 }
783 }
784
785 if (txmsg_end) {
786 i = 1;
787 err = bpf_map_update_elem(map_fd[5],
788 &i, &txmsg_end, BPF_ANY);
789 if (err) {
790 fprintf(stderr,
791 "ERROR: bpf_map_update_elem (txmsg_end): %d (%s)\n",
792 err, strerror(errno));
793 return err;
794 }
795 }
796 }
797
798 if (txmsg_drop)
799 options.drop_expected = true;
800
801 if (test == PING_PONG)
802 err = forever_ping_pong(rate, &options);
803 else if (test == SENDMSG) {
804 options.base = false;
805 options.sendpage = false;
806 err = sendmsg_test(iov_count, length, rate, &options);
807 } else if (test == SENDPAGE) {
808 options.base = false;
809 options.sendpage = true;
810 err = sendmsg_test(iov_count, length, rate, &options);
811 } else if (test == BASE) {
812 options.base = true;
813 options.sendpage = false;
814 err = sendmsg_test(iov_count, length, rate, &options);
815 } else if (test == BASE_SENDPAGE) {
816 options.base = true;
817 options.sendpage = true;
818 err = sendmsg_test(iov_count, length, rate, &options);
819 } else
567 fprintf(stderr, "unknown test\n"); 820 fprintf(stderr, "unknown test\n");
568out: 821out:
822 bpf_prog_detach2(prog_fd[2], cg_fd, BPF_CGROUP_SOCK_OPS);
569 close(s1); 823 close(s1);
570 close(s2); 824 close(s2);
571 close(p1); 825 close(p1);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 8644d864e3c1..b4d7b6242a40 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -6743,6 +6743,7 @@ static void __net_exit selinux_nf_unregister(struct net *net)
6743static struct pernet_operations selinux_net_ops = { 6743static struct pernet_operations selinux_net_ops = {
6744 .init = selinux_nf_register, 6744 .init = selinux_nf_register,
6745 .exit = selinux_nf_unregister, 6745 .exit = selinux_nf_unregister,
6746 .async = true,
6746}; 6747};
6747 6748
6748static int __init selinux_nf_ip_init(void) 6749static int __init selinux_nf_ip_init(void)
diff --git a/security/smack/smack_netfilter.c b/security/smack/smack_netfilter.c
index e36d17835d4f..3f29c03162ca 100644
--- a/security/smack/smack_netfilter.c
+++ b/security/smack/smack_netfilter.c
@@ -89,6 +89,7 @@ static void __net_exit smack_nf_unregister(struct net *net)
89static struct pernet_operations smack_net_ops = { 89static struct pernet_operations smack_net_ops = {
90 .init = smack_nf_register, 90 .init = smack_nf_register,
91 .exit = smack_nf_unregister, 91 .exit = smack_nf_unregister,
92 .async = true,
92}; 93};
93 94
94static int __init smack_nf_ip_init(void) 95static int __init smack_nf_ip_init(void)
diff --git a/security/tomoyo/network.c b/security/tomoyo/network.c
index cd6932e5225c..9094f4b3b367 100644
--- a/security/tomoyo/network.c
+++ b/security/tomoyo/network.c
@@ -655,10 +655,11 @@ int tomoyo_socket_listen_permission(struct socket *sock)
655 return 0; 655 return 0;
656 { 656 {
657 const int error = sock->ops->getname(sock, (struct sockaddr *) 657 const int error = sock->ops->getname(sock, (struct sockaddr *)
658 &addr, &addr_len, 0); 658 &addr, 0);
659 659
660 if (error) 660 if (error < 0)
661 return error; 661 return error;
662 addr_len = error;
662 } 663 }
663 address.protocol = type; 664 address.protocol = type;
664 address.operation = TOMOYO_NETWORK_LISTEN; 665 address.operation = TOMOYO_NETWORK_LISTEN;
diff --git a/tools/bpf/Makefile b/tools/bpf/Makefile
index c8ec0ae16bf0..1ea545965ee3 100644
--- a/tools/bpf/Makefile
+++ b/tools/bpf/Makefile
@@ -1,19 +1,28 @@
1# SPDX-License-Identifier: GPL-2.0 1# SPDX-License-Identifier: GPL-2.0
2prefix = /usr 2include ../scripts/Makefile.include
3
4prefix ?= /usr/local
3 5
4CC = gcc 6CC = gcc
5LEX = flex 7LEX = flex
6YACC = bison 8YACC = bison
7MAKE = make 9MAKE = make
10INSTALL ?= install
8 11
9CFLAGS += -Wall -O2 12CFLAGS += -Wall -O2
10CFLAGS += -D__EXPORTED_HEADERS__ -I../../include/uapi -I../../include 13CFLAGS += -D__EXPORTED_HEADERS__ -I$(srctree)/include/uapi -I$(srctree)/include
11 14
12ifeq ($(srctree),) 15ifeq ($(srctree),)
13srctree := $(patsubst %/,%,$(dir $(CURDIR))) 16srctree := $(patsubst %/,%,$(dir $(CURDIR)))
14srctree := $(patsubst %/,%,$(dir $(srctree))) 17srctree := $(patsubst %/,%,$(dir $(srctree)))
15endif 18endif
16 19
20ifeq ($(V),1)
21 Q =
22else
23 Q = @
24endif
25
17FEATURE_USER = .bpf 26FEATURE_USER = .bpf
18FEATURE_TESTS = libbfd disassembler-four-args 27FEATURE_TESTS = libbfd disassembler-four-args
19FEATURE_DISPLAY = libbfd disassembler-four-args 28FEATURE_DISPLAY = libbfd disassembler-four-args
@@ -38,40 +47,59 @@ ifeq ($(feature-disassembler-four-args), 1)
38CFLAGS += -DDISASM_FOUR_ARGS_SIGNATURE 47CFLAGS += -DDISASM_FOUR_ARGS_SIGNATURE
39endif 48endif
40 49
41%.yacc.c: %.y 50$(OUTPUT)%.yacc.c: $(srctree)/tools/bpf/%.y
42 $(YACC) -o $@ -d $< 51 $(QUIET_BISON)$(YACC) -o $@ -d $<
43 52
44%.lex.c: %.l 53$(OUTPUT)%.lex.c: $(srctree)/tools/bpf/%.l
45 $(LEX) -o $@ $< 54 $(QUIET_FLEX)$(LEX) -o $@ $<
46 55
47all: bpf_jit_disasm bpf_dbg bpf_asm bpftool 56$(OUTPUT)%.o: $(srctree)/tools/bpf/%.c
57 $(QUIET_CC)$(COMPILE.c) -o $@ $<
48 58
49bpf_jit_disasm : CFLAGS += -DPACKAGE='bpf_jit_disasm' 59$(OUTPUT)%.yacc.o: $(OUTPUT)%.yacc.c
50bpf_jit_disasm : LDLIBS = -lopcodes -lbfd -ldl 60 $(QUIET_CC)$(COMPILE.c) -o $@ $<
51bpf_jit_disasm : bpf_jit_disasm.o 61$(OUTPUT)%.lex.o: $(OUTPUT)%.lex.c
62 $(QUIET_CC)$(COMPILE.c) -o $@ $<
52 63
53bpf_dbg : LDLIBS = -lreadline 64PROGS = $(OUTPUT)bpf_jit_disasm $(OUTPUT)bpf_dbg $(OUTPUT)bpf_asm
54bpf_dbg : bpf_dbg.o
55 65
56bpf_asm : LDLIBS = 66all: $(PROGS) bpftool
57bpf_asm : bpf_asm.o bpf_exp.yacc.o bpf_exp.lex.o
58bpf_exp.lex.o : bpf_exp.yacc.c
59 67
60clean: bpftool_clean 68$(OUTPUT)bpf_jit_disasm: CFLAGS += -DPACKAGE='bpf_jit_disasm'
61 rm -rf *.o bpf_jit_disasm bpf_dbg bpf_asm bpf_exp.yacc.* bpf_exp.lex.* 69$(OUTPUT)bpf_jit_disasm: $(OUTPUT)bpf_jit_disasm.o
70 $(QUIET_LINK)$(CC) $(CFLAGS) -o $@ $^ -lopcodes -lbfd -ldl
62 71
63install: bpftool_install 72$(OUTPUT)bpf_dbg: $(OUTPUT)bpf_dbg.o
64 install bpf_jit_disasm $(prefix)/bin/bpf_jit_disasm 73 $(QUIET_LINK)$(CC) $(CFLAGS) -o $@ $^ -lreadline
65 install bpf_dbg $(prefix)/bin/bpf_dbg 74
66 install bpf_asm $(prefix)/bin/bpf_asm 75$(OUTPUT)bpf_asm: $(OUTPUT)bpf_asm.o $(OUTPUT)bpf_exp.yacc.o $(OUTPUT)bpf_exp.lex.o
76 $(QUIET_LINK)$(CC) $(CFLAGS) -o $@ $^
77
78$(OUTPUT)bpf_exp.lex.c: $(OUTPUT)bpf_exp.yacc.c
79
80clean: bpftool_clean
81 $(call QUIET_CLEAN, bpf-progs)
82 $(Q)rm -rf $(OUTPUT)*.o $(OUTPUT)bpf_jit_disasm $(OUTPUT)bpf_dbg \
83 $(OUTPUT)bpf_asm $(OUTPUT)bpf_exp.yacc.* $(OUTPUT)bpf_exp.lex.*
84 $(call QUIET_CLEAN, core-gen)
85 $(Q)rm -f $(OUTPUT)FEATURE-DUMP.bpf
86
87install: $(PROGS) bpftool_install
88 $(call QUIET_INSTALL, bpf_jit_disasm)
89 $(Q)$(INSTALL) -m 0755 -d $(DESTDIR)$(prefix)/bin
90 $(Q)$(INSTALL) $(OUTPUT)bpf_jit_disasm $(DESTDIR)$(prefix)/bin/bpf_jit_disasm
91 $(call QUIET_INSTALL, bpf_dbg)
92 $(Q)$(INSTALL) $(OUTPUT)bpf_dbg $(DESTDIR)$(prefix)/bin/bpf_dbg
93 $(call QUIET_INSTALL, bpf_asm)
94 $(Q)$(INSTALL) $(OUTPUT)bpf_asm $(DESTDIR)$(prefix)/bin/bpf_asm
67 95
68bpftool: 96bpftool:
69 $(MAKE) -C bpftool 97 $(call descend,bpftool)
70 98
71bpftool_install: 99bpftool_install:
72 $(MAKE) -C bpftool install 100 $(call descend,bpftool,install)
73 101
74bpftool_clean: 102bpftool_clean:
75 $(MAKE) -C bpftool clean 103 $(call descend,bpftool,clean)
76 104
77.PHONY: bpftool FORCE 105.PHONY: all install clean bpftool bpftool_install bpftool_clean
diff --git a/tools/bpf/bpftool/Documentation/bpftool-prog.rst b/tools/bpf/bpftool/Documentation/bpftool-prog.rst
index e4ceee7f2dff..67ca6c69376c 100644
--- a/tools/bpf/bpftool/Documentation/bpftool-prog.rst
+++ b/tools/bpf/bpftool/Documentation/bpftool-prog.rst
@@ -21,7 +21,7 @@ MAP COMMANDS
21============= 21=============
22 22
23| **bpftool** **prog { show | list }** [*PROG*] 23| **bpftool** **prog { show | list }** [*PROG*]
24| **bpftool** **prog dump xlated** *PROG* [{**file** *FILE* | **opcodes**}] 24| **bpftool** **prog dump xlated** *PROG* [{**file** *FILE* | **opcodes** | **visual**}]
25| **bpftool** **prog dump jited** *PROG* [{**file** *FILE* | **opcodes**}] 25| **bpftool** **prog dump jited** *PROG* [{**file** *FILE* | **opcodes**}]
26| **bpftool** **prog pin** *PROG* *FILE* 26| **bpftool** **prog pin** *PROG* *FILE*
27| **bpftool** **prog load** *OBJ* *FILE* 27| **bpftool** **prog load** *OBJ* *FILE*
@@ -39,12 +39,18 @@ DESCRIPTION
39 Output will start with program ID followed by program type and 39 Output will start with program ID followed by program type and
40 zero or more named attributes (depending on kernel version). 40 zero or more named attributes (depending on kernel version).
41 41
42 **bpftool prog dump xlated** *PROG* [{ **file** *FILE* | **opcodes** }] 42 **bpftool prog dump xlated** *PROG* [{ **file** *FILE* | **opcodes** | **visual** }]
43 Dump eBPF instructions of the program from the kernel. 43 Dump eBPF instructions of the program from the kernel. By
44 If *FILE* is specified image will be written to a file, 44 default, eBPF will be disassembled and printed to standard
45 otherwise it will be disassembled and printed to stdout. 45 output in human-readable format. In this case, **opcodes**
46 controls if raw opcodes should be printed as well.
46 47
47 **opcodes** controls if raw opcodes will be printed. 48 If **file** is specified, the binary image will instead be
49 written to *FILE*.
50
51 If **visual** is specified, control flow graph (CFG) will be
52 built instead, and eBPF instructions will be presented with
53 CFG in DOT format, on standard output.
48 54
49 **bpftool prog dump jited** *PROG* [{ **file** *FILE* | **opcodes** }] 55 **bpftool prog dump jited** *PROG* [{ **file** *FILE* | **opcodes** }]
50 Dump jited image (host machine code) of the program. 56 Dump jited image (host machine code) of the program.
diff --git a/tools/bpf/bpftool/Makefile b/tools/bpf/bpftool/Makefile
index 26901ec87361..4e69782c4a79 100644
--- a/tools/bpf/bpftool/Makefile
+++ b/tools/bpf/bpftool/Makefile
@@ -38,7 +38,7 @@ bash_compdir ?= /usr/share/bash-completion/completions
38CC = gcc 38CC = gcc
39 39
40CFLAGS += -O2 40CFLAGS += -O2
41CFLAGS += -W -Wall -Wextra -Wno-unused-parameter -Wshadow 41CFLAGS += -W -Wall -Wextra -Wno-unused-parameter -Wshadow -Wno-missing-field-initializers
42CFLAGS += -DPACKAGE='"bpftool"' -D__EXPORTED_HEADERS__ -I$(srctree)/tools/include/uapi -I$(srctree)/tools/include -I$(srctree)/tools/lib/bpf -I$(srctree)/kernel/bpf/ 42CFLAGS += -DPACKAGE='"bpftool"' -D__EXPORTED_HEADERS__ -I$(srctree)/tools/include/uapi -I$(srctree)/tools/include -I$(srctree)/tools/lib/bpf -I$(srctree)/kernel/bpf/
43CFLAGS += -DBPFTOOL_VERSION='"$(BPFTOOL_VERSION)"' 43CFLAGS += -DBPFTOOL_VERSION='"$(BPFTOOL_VERSION)"'
44LIBS = -lelf -lbfd -lopcodes $(LIBBPF) 44LIBS = -lelf -lbfd -lopcodes $(LIBBPF)
@@ -70,7 +70,7 @@ ifeq ($(feature-disassembler-four-args), 1)
70CFLAGS += -DDISASM_FOUR_ARGS_SIGNATURE 70CFLAGS += -DDISASM_FOUR_ARGS_SIGNATURE
71endif 71endif
72 72
73include $(wildcard *.d) 73include $(wildcard $(OUTPUT)*.d)
74 74
75all: $(OUTPUT)bpftool 75all: $(OUTPUT)bpftool
76 76
@@ -89,6 +89,8 @@ $(OUTPUT)%.o: %.c
89clean: $(LIBBPF)-clean 89clean: $(LIBBPF)-clean
90 $(call QUIET_CLEAN, bpftool) 90 $(call QUIET_CLEAN, bpftool)
91 $(Q)$(RM) $(OUTPUT)bpftool $(OUTPUT)*.o $(OUTPUT)*.d 91 $(Q)$(RM) $(OUTPUT)bpftool $(OUTPUT)*.o $(OUTPUT)*.d
92 $(call QUIET_CLEAN, core-gen)
93 $(Q)$(RM) $(OUTPUT)FEATURE-DUMP.bpftool
92 94
93install: $(OUTPUT)bpftool 95install: $(OUTPUT)bpftool
94 $(call QUIET_INSTALL, bpftool) 96 $(call QUIET_INSTALL, bpftool)
diff --git a/tools/bpf/bpftool/bash-completion/bpftool b/tools/bpf/bpftool/bash-completion/bpftool
index 08719c54a614..490811b45fa7 100644
--- a/tools/bpf/bpftool/bash-completion/bpftool
+++ b/tools/bpf/bpftool/bash-completion/bpftool
@@ -147,7 +147,7 @@ _bpftool()
147 147
148 # Deal with simplest keywords 148 # Deal with simplest keywords
149 case $prev in 149 case $prev in
150 help|key|opcodes) 150 help|key|opcodes|visual)
151 return 0 151 return 0
152 ;; 152 ;;
153 tag) 153 tag)
@@ -223,11 +223,16 @@ _bpftool()
223 return 0 223 return 0
224 ;; 224 ;;
225 *) 225 *)
226 _bpftool_once_attr 'file' 226 _bpftool_once_attr 'file'
227 if _bpftool_search_list 'xlated'; then
228 COMPREPLY+=( $( compgen -W 'opcodes visual' -- \
229 "$cur" ) )
230 else
227 COMPREPLY+=( $( compgen -W 'opcodes' -- \ 231 COMPREPLY+=( $( compgen -W 'opcodes' -- \
228 "$cur" ) ) 232 "$cur" ) )
229 return 0 233 fi
230 ;; 234 return 0
235 ;;
231 esac 236 esac
232 ;; 237 ;;
233 pin) 238 pin)
diff --git a/tools/bpf/bpftool/cfg.c b/tools/bpf/bpftool/cfg.c
new file mode 100644
index 000000000000..f30b3a4a840b
--- /dev/null
+++ b/tools/bpf/bpftool/cfg.c
@@ -0,0 +1,514 @@
1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2/*
3 * Copyright (C) 2018 Netronome Systems, Inc.
4 *
5 * This software is dual licensed under the GNU General License Version 2,
6 * June 1991 as shown in the file COPYING in the top-level directory of this
7 * source tree or the BSD 2-Clause License provided below. You have the
8 * option to license this software under the complete terms of either license.
9 *
10 * The BSD 2-Clause License:
11 *
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
14 * conditions are met:
15 *
16 * 1. Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
18 * disclaimer.
19 *
20 * 2. Redistributions in binary form must reproduce the above
21 * copyright notice, this list of conditions and the following
22 * disclaimer in the documentation and/or other materials
23 * provided with the distribution.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 */
37
38#include <linux/list.h>
39#include <stdlib.h>
40#include <string.h>
41
42#include "cfg.h"
43#include "main.h"
44#include "xlated_dumper.h"
45
46struct cfg {
47 struct list_head funcs;
48 int func_num;
49};
50
51struct func_node {
52 struct list_head l;
53 struct list_head bbs;
54 struct bpf_insn *start;
55 struct bpf_insn *end;
56 int idx;
57 int bb_num;
58};
59
60struct bb_node {
61 struct list_head l;
62 struct list_head e_prevs;
63 struct list_head e_succs;
64 struct bpf_insn *head;
65 struct bpf_insn *tail;
66 int idx;
67};
68
69#define EDGE_FLAG_EMPTY 0x0
70#define EDGE_FLAG_FALLTHROUGH 0x1
71#define EDGE_FLAG_JUMP 0x2
72struct edge_node {
73 struct list_head l;
74 struct bb_node *src;
75 struct bb_node *dst;
76 int flags;
77};
78
79#define ENTRY_BLOCK_INDEX 0
80#define EXIT_BLOCK_INDEX 1
81#define NUM_FIXED_BLOCKS 2
82#define func_prev(func) list_prev_entry(func, l)
83#define func_next(func) list_next_entry(func, l)
84#define bb_prev(bb) list_prev_entry(bb, l)
85#define bb_next(bb) list_next_entry(bb, l)
86#define entry_bb(func) func_first_bb(func)
87#define exit_bb(func) func_last_bb(func)
88#define cfg_first_func(cfg) \
89 list_first_entry(&cfg->funcs, struct func_node, l)
90#define cfg_last_func(cfg) \
91 list_last_entry(&cfg->funcs, struct func_node, l)
92#define func_first_bb(func) \
93 list_first_entry(&func->bbs, struct bb_node, l)
94#define func_last_bb(func) \
95 list_last_entry(&func->bbs, struct bb_node, l)
96
97static struct func_node *cfg_append_func(struct cfg *cfg, struct bpf_insn *insn)
98{
99 struct func_node *new_func, *func;
100
101 list_for_each_entry(func, &cfg->funcs, l) {
102 if (func->start == insn)
103 return func;
104 else if (func->start > insn)
105 break;
106 }
107
108 func = func_prev(func);
109 new_func = calloc(1, sizeof(*new_func));
110 if (!new_func) {
111 p_err("OOM when allocating FUNC node");
112 return NULL;
113 }
114 new_func->start = insn;
115 new_func->idx = cfg->func_num;
116 list_add(&new_func->l, &func->l);
117 cfg->func_num++;
118
119 return new_func;
120}
121
122static struct bb_node *func_append_bb(struct func_node *func,
123 struct bpf_insn *insn)
124{
125 struct bb_node *new_bb, *bb;
126
127 list_for_each_entry(bb, &func->bbs, l) {
128 if (bb->head == insn)
129 return bb;
130 else if (bb->head > insn)
131 break;
132 }
133
134 bb = bb_prev(bb);
135 new_bb = calloc(1, sizeof(*new_bb));
136 if (!new_bb) {
137 p_err("OOM when allocating BB node");
138 return NULL;
139 }
140 new_bb->head = insn;
141 INIT_LIST_HEAD(&new_bb->e_prevs);
142 INIT_LIST_HEAD(&new_bb->e_succs);
143 list_add(&new_bb->l, &bb->l);
144
145 return new_bb;
146}
147
148static struct bb_node *func_insert_dummy_bb(struct list_head *after)
149{
150 struct bb_node *bb;
151
152 bb = calloc(1, sizeof(*bb));
153 if (!bb) {
154 p_err("OOM when allocating BB node");
155 return NULL;
156 }
157
158 INIT_LIST_HEAD(&bb->e_prevs);
159 INIT_LIST_HEAD(&bb->e_succs);
160 list_add(&bb->l, after);
161
162 return bb;
163}
164
165static bool cfg_partition_funcs(struct cfg *cfg, struct bpf_insn *cur,
166 struct bpf_insn *end)
167{
168 struct func_node *func, *last_func;
169
170 func = cfg_append_func(cfg, cur);
171 if (!func)
172 return true;
173
174 for (; cur < end; cur++) {
175 if (cur->code != (BPF_JMP | BPF_CALL))
176 continue;
177 if (cur->src_reg != BPF_PSEUDO_CALL)
178 continue;
179 func = cfg_append_func(cfg, cur + cur->off + 1);
180 if (!func)
181 return true;
182 }
183
184 last_func = cfg_last_func(cfg);
185 last_func->end = end - 1;
186 func = cfg_first_func(cfg);
187 list_for_each_entry_from(func, &last_func->l, l) {
188 func->end = func_next(func)->start - 1;
189 }
190
191 return false;
192}
193
194static bool func_partition_bb_head(struct func_node *func)
195{
196 struct bpf_insn *cur, *end;
197 struct bb_node *bb;
198
199 cur = func->start;
200 end = func->end;
201 INIT_LIST_HEAD(&func->bbs);
202 bb = func_append_bb(func, cur);
203 if (!bb)
204 return true;
205
206 for (; cur <= end; cur++) {
207 if (BPF_CLASS(cur->code) == BPF_JMP) {
208 u8 opcode = BPF_OP(cur->code);
209
210 if (opcode == BPF_EXIT || opcode == BPF_CALL)
211 continue;
212
213 bb = func_append_bb(func, cur + cur->off + 1);
214 if (!bb)
215 return true;
216
217 if (opcode != BPF_JA) {
218 bb = func_append_bb(func, cur + 1);
219 if (!bb)
220 return true;
221 }
222 }
223 }
224
225 return false;
226}
227
228static void func_partition_bb_tail(struct func_node *func)
229{
230 unsigned int bb_idx = NUM_FIXED_BLOCKS;
231 struct bb_node *bb, *last;
232
233 last = func_last_bb(func);
234 last->tail = func->end;
235 bb = func_first_bb(func);
236 list_for_each_entry_from(bb, &last->l, l) {
237 bb->tail = bb_next(bb)->head - 1;
238 bb->idx = bb_idx++;
239 }
240
241 last->idx = bb_idx++;
242 func->bb_num = bb_idx;
243}
244
245static bool func_add_special_bb(struct func_node *func)
246{
247 struct bb_node *bb;
248
249 bb = func_insert_dummy_bb(&func->bbs);
250 if (!bb)
251 return true;
252 bb->idx = ENTRY_BLOCK_INDEX;
253
254 bb = func_insert_dummy_bb(&func_last_bb(func)->l);
255 if (!bb)
256 return true;
257 bb->idx = EXIT_BLOCK_INDEX;
258
259 return false;
260}
261
262static bool func_partition_bb(struct func_node *func)
263{
264 if (func_partition_bb_head(func))
265 return true;
266
267 func_partition_bb_tail(func);
268
269 return false;
270}
271
272static struct bb_node *func_search_bb_with_head(struct func_node *func,
273 struct bpf_insn *insn)
274{
275 struct bb_node *bb;
276
277 list_for_each_entry(bb, &func->bbs, l) {
278 if (bb->head == insn)
279 return bb;
280 }
281
282 return NULL;
283}
284
285static struct edge_node *new_edge(struct bb_node *src, struct bb_node *dst,
286 int flags)
287{
288 struct edge_node *e;
289
290 e = calloc(1, sizeof(*e));
291 if (!e) {
292 p_err("OOM when allocating edge node");
293 return NULL;
294 }
295
296 if (src)
297 e->src = src;
298 if (dst)
299 e->dst = dst;
300
301 e->flags |= flags;
302
303 return e;
304}
305
306static bool func_add_bb_edges(struct func_node *func)
307{
308 struct bpf_insn *insn;
309 struct edge_node *e;
310 struct bb_node *bb;
311
312 bb = entry_bb(func);
313 e = new_edge(bb, bb_next(bb), EDGE_FLAG_FALLTHROUGH);
314 if (!e)
315 return true;
316 list_add_tail(&e->l, &bb->e_succs);
317
318 bb = exit_bb(func);
319 e = new_edge(bb_prev(bb), bb, EDGE_FLAG_FALLTHROUGH);
320 if (!e)
321 return true;
322 list_add_tail(&e->l, &bb->e_prevs);
323
324 bb = entry_bb(func);
325 bb = bb_next(bb);
326 list_for_each_entry_from(bb, &exit_bb(func)->l, l) {
327 e = new_edge(bb, NULL, EDGE_FLAG_EMPTY);
328 if (!e)
329 return true;
330 e->src = bb;
331
332 insn = bb->tail;
333 if (BPF_CLASS(insn->code) != BPF_JMP ||
334 BPF_OP(insn->code) == BPF_EXIT) {
335 e->dst = bb_next(bb);
336 e->flags |= EDGE_FLAG_FALLTHROUGH;
337 list_add_tail(&e->l, &bb->e_succs);
338 continue;
339 } else if (BPF_OP(insn->code) == BPF_JA) {
340 e->dst = func_search_bb_with_head(func,
341 insn + insn->off + 1);
342 e->flags |= EDGE_FLAG_JUMP;
343 list_add_tail(&e->l, &bb->e_succs);
344 continue;
345 }
346
347 e->dst = bb_next(bb);
348 e->flags |= EDGE_FLAG_FALLTHROUGH;
349 list_add_tail(&e->l, &bb->e_succs);
350
351 e = new_edge(bb, NULL, EDGE_FLAG_JUMP);
352 if (!e)
353 return true;
354 e->src = bb;
355 e->dst = func_search_bb_with_head(func, insn + insn->off + 1);
356 list_add_tail(&e->l, &bb->e_succs);
357 }
358
359 return false;
360}
361
362static bool cfg_build(struct cfg *cfg, struct bpf_insn *insn, unsigned int len)
363{
364 int cnt = len / sizeof(*insn);
365 struct func_node *func;
366
367 INIT_LIST_HEAD(&cfg->funcs);
368
369 if (cfg_partition_funcs(cfg, insn, insn + cnt))
370 return true;
371
372 list_for_each_entry(func, &cfg->funcs, l) {
373 if (func_partition_bb(func) || func_add_special_bb(func))
374 return true;
375
376 if (func_add_bb_edges(func))
377 return true;
378 }
379
380 return false;
381}
382
383static void cfg_destroy(struct cfg *cfg)
384{
385 struct func_node *func, *func2;
386
387 list_for_each_entry_safe(func, func2, &cfg->funcs, l) {
388 struct bb_node *bb, *bb2;
389
390 list_for_each_entry_safe(bb, bb2, &func->bbs, l) {
391 struct edge_node *e, *e2;
392
393 list_for_each_entry_safe(e, e2, &bb->e_prevs, l) {
394 list_del(&e->l);
395 free(e);
396 }
397
398 list_for_each_entry_safe(e, e2, &bb->e_succs, l) {
399 list_del(&e->l);
400 free(e);
401 }
402
403 list_del(&bb->l);
404 free(bb);
405 }
406
407 list_del(&func->l);
408 free(func);
409 }
410}
411
412static void draw_bb_node(struct func_node *func, struct bb_node *bb)
413{
414 const char *shape;
415
416 if (bb->idx == ENTRY_BLOCK_INDEX || bb->idx == EXIT_BLOCK_INDEX)
417 shape = "Mdiamond";
418 else
419 shape = "record";
420
421 printf("\tfn_%d_bb_%d [shape=%s,style=filled,label=\"",
422 func->idx, bb->idx, shape);
423
424 if (bb->idx == ENTRY_BLOCK_INDEX) {
425 printf("ENTRY");
426 } else if (bb->idx == EXIT_BLOCK_INDEX) {
427 printf("EXIT");
428 } else {
429 unsigned int start_idx;
430 struct dump_data dd = {};
431
432 printf("{");
433 kernel_syms_load(&dd);
434 start_idx = bb->head - func->start;
435 dump_xlated_for_graph(&dd, bb->head, bb->tail, start_idx);
436 kernel_syms_destroy(&dd);
437 printf("}");
438 }
439
440 printf("\"];\n\n");
441}
442
443static void draw_bb_succ_edges(struct func_node *func, struct bb_node *bb)
444{
445 const char *style = "\"solid,bold\"";
446 const char *color = "black";
447 int func_idx = func->idx;
448 struct edge_node *e;
449 int weight = 10;
450
451 if (list_empty(&bb->e_succs))
452 return;
453
454 list_for_each_entry(e, &bb->e_succs, l) {
455 printf("\tfn_%d_bb_%d:s -> fn_%d_bb_%d:n [style=%s, color=%s, weight=%d, constraint=true",
456 func_idx, e->src->idx, func_idx, e->dst->idx,
457 style, color, weight);
458 printf("];\n");
459 }
460}
461
462static void func_output_bb_def(struct func_node *func)
463{
464 struct bb_node *bb;
465
466 list_for_each_entry(bb, &func->bbs, l) {
467 draw_bb_node(func, bb);
468 }
469}
470
471static void func_output_edges(struct func_node *func)
472{
473 int func_idx = func->idx;
474 struct bb_node *bb;
475
476 list_for_each_entry(bb, &func->bbs, l) {
477 draw_bb_succ_edges(func, bb);
478 }
479
480 /* Add an invisible edge from ENTRY to EXIT, this is to
481 * improve the graph layout.
482 */
483 printf("\tfn_%d_bb_%d:s -> fn_%d_bb_%d:n [style=\"invis\", constraint=true];\n",
484 func_idx, ENTRY_BLOCK_INDEX, func_idx, EXIT_BLOCK_INDEX);
485}
486
487static void cfg_dump(struct cfg *cfg)
488{
489 struct func_node *func;
490
491 printf("digraph \"DOT graph for eBPF program\" {\n");
492 list_for_each_entry(func, &cfg->funcs, l) {
493 printf("subgraph \"cluster_%d\" {\n\tstyle=\"dashed\";\n\tcolor=\"black\";\n\tlabel=\"func_%d ()\";\n",
494 func->idx, func->idx);
495 func_output_bb_def(func);
496 func_output_edges(func);
497 printf("}\n");
498 }
499 printf("}\n");
500}
501
502void dump_xlated_cfg(void *buf, unsigned int len)
503{
504 struct bpf_insn *insn = buf;
505 struct cfg cfg;
506
507 memset(&cfg, 0, sizeof(cfg));
508 if (cfg_build(&cfg, insn, len))
509 return;
510
511 cfg_dump(&cfg);
512
513 cfg_destroy(&cfg);
514}
diff --git a/tools/bpf/bpftool/cfg.h b/tools/bpf/bpftool/cfg.h
new file mode 100644
index 000000000000..2cc9bd990b13
--- /dev/null
+++ b/tools/bpf/bpftool/cfg.h
@@ -0,0 +1,43 @@
1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2/*
3 * Copyright (C) 2018 Netronome Systems, Inc.
4 *
5 * This software is dual licensed under the GNU General License Version 2,
6 * June 1991 as shown in the file COPYING in the top-level directory of this
7 * source tree or the BSD 2-Clause License provided below. You have the
8 * option to license this software under the complete terms of either license.
9 *
10 * The BSD 2-Clause License:
11 *
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
14 * conditions are met:
15 *
16 * 1. Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
18 * disclaimer.
19 *
20 * 2. Redistributions in binary form must reproduce the above
21 * copyright notice, this list of conditions and the following
22 * disclaimer in the documentation and/or other materials
23 * provided with the distribution.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 */
37
38#ifndef __BPF_TOOL_CFG_H
39#define __BPF_TOOL_CFG_H
40
41void dump_xlated_cfg(void *buf, unsigned int len);
42
43#endif /* __BPF_TOOL_CFG_H */
diff --git a/tools/bpf/bpftool/main.c b/tools/bpf/bpftool/main.c
index 185acfa229b5..1ec852d21d44 100644
--- a/tools/bpf/bpftool/main.c
+++ b/tools/bpf/bpftool/main.c
@@ -46,6 +46,9 @@
46 46
47#include "main.h" 47#include "main.h"
48 48
49#define BATCH_LINE_LEN_MAX 65536
50#define BATCH_ARG_NB_MAX 4096
51
49const char *bin_name; 52const char *bin_name;
50static int last_argc; 53static int last_argc;
51static char **last_argv; 54static char **last_argv;
@@ -157,6 +160,54 @@ void fprint_hex(FILE *f, void *arg, unsigned int n, const char *sep)
157 } 160 }
158} 161}
159 162
163/* Split command line into argument vector. */
164static int make_args(char *line, char *n_argv[], int maxargs, int cmd_nb)
165{
166 static const char ws[] = " \t\r\n";
167 char *cp = line;
168 int n_argc = 0;
169
170 while (*cp) {
171 /* Skip leading whitespace. */
172 cp += strspn(cp, ws);
173
174 if (*cp == '\0')
175 break;
176
177 if (n_argc >= (maxargs - 1)) {
178 p_err("too many arguments to command %d", cmd_nb);
179 return -1;
180 }
181
182 /* Word begins with quote. */
183 if (*cp == '\'' || *cp == '"') {
184 char quote = *cp++;
185
186 n_argv[n_argc++] = cp;
187 /* Find ending quote. */
188 cp = strchr(cp, quote);
189 if (!cp) {
190 p_err("unterminated quoted string in command %d",
191 cmd_nb);
192 return -1;
193 }
194 } else {
195 n_argv[n_argc++] = cp;
196
197 /* Find end of word. */
198 cp += strcspn(cp, ws);
199 if (*cp == '\0')
200 break;
201 }
202
203 /* Separate words. */
204 *cp++ = 0;
205 }
206 n_argv[n_argc] = NULL;
207
208 return n_argc;
209}
210
160static int do_batch(int argc, char **argv); 211static int do_batch(int argc, char **argv);
161 212
162static const struct cmd cmds[] = { 213static const struct cmd cmds[] = {
@@ -171,11 +222,12 @@ static const struct cmd cmds[] = {
171 222
172static int do_batch(int argc, char **argv) 223static int do_batch(int argc, char **argv)
173{ 224{
225 char buf[BATCH_LINE_LEN_MAX], contline[BATCH_LINE_LEN_MAX];
226 char *n_argv[BATCH_ARG_NB_MAX];
174 unsigned int lines = 0; 227 unsigned int lines = 0;
175 char *n_argv[4096];
176 char buf[65536];
177 int n_argc; 228 int n_argc;
178 FILE *fp; 229 FILE *fp;
230 char *cp;
179 int err; 231 int err;
180 int i; 232 int i;
181 233
@@ -191,7 +243,10 @@ static int do_batch(int argc, char **argv)
191 } 243 }
192 NEXT_ARG(); 244 NEXT_ARG();
193 245
194 fp = fopen(*argv, "r"); 246 if (!strcmp(*argv, "-"))
247 fp = stdin;
248 else
249 fp = fopen(*argv, "r");
195 if (!fp) { 250 if (!fp) {
196 p_err("Can't open file (%s): %s", *argv, strerror(errno)); 251 p_err("Can't open file (%s): %s", *argv, strerror(errno));
197 return -1; 252 return -1;
@@ -200,27 +255,45 @@ static int do_batch(int argc, char **argv)
200 if (json_output) 255 if (json_output)
201 jsonw_start_array(json_wtr); 256 jsonw_start_array(json_wtr);
202 while (fgets(buf, sizeof(buf), fp)) { 257 while (fgets(buf, sizeof(buf), fp)) {
258 cp = strchr(buf, '#');
259 if (cp)
260 *cp = '\0';
261
203 if (strlen(buf) == sizeof(buf) - 1) { 262 if (strlen(buf) == sizeof(buf) - 1) {
204 errno = E2BIG; 263 errno = E2BIG;
205 break; 264 break;
206 } 265 }
207 266
208 n_argc = 0; 267 /* Append continuation lines if any (coming after a line ending
209 n_argv[n_argc] = strtok(buf, " \t\n"); 268 * with '\' in the batch file).
210 269 */
211 while (n_argv[n_argc]) { 270 while ((cp = strstr(buf, "\\\n")) != NULL) {
212 n_argc++; 271 if (!fgets(contline, sizeof(contline), fp) ||
213 if (n_argc == ARRAY_SIZE(n_argv)) { 272 strlen(contline) == 0) {
214 p_err("line %d has too many arguments, skip", 273 p_err("missing continuation line on command %d",
215 lines); 274 lines);
216 n_argc = 0; 275 err = -1;
217 break; 276 goto err_close;
277 }
278
279 cp = strchr(contline, '#');
280 if (cp)
281 *cp = '\0';
282
283 if (strlen(buf) + strlen(contline) + 1 > sizeof(buf)) {
284 p_err("command %d is too long", lines);
285 err = -1;
286 goto err_close;
218 } 287 }
219 n_argv[n_argc] = strtok(NULL, " \t\n"); 288 buf[strlen(buf) - 2] = '\0';
289 strcat(buf, contline);
220 } 290 }
221 291
292 n_argc = make_args(buf, n_argv, BATCH_ARG_NB_MAX, lines);
222 if (!n_argc) 293 if (!n_argc)
223 continue; 294 continue;
295 if (n_argc < 0)
296 goto err_close;
224 297
225 if (json_output) { 298 if (json_output) {
226 jsonw_start_object(json_wtr); 299 jsonw_start_object(json_wtr);
@@ -247,11 +320,12 @@ static int do_batch(int argc, char **argv)
247 p_err("reading batch file failed: %s", strerror(errno)); 320 p_err("reading batch file failed: %s", strerror(errno));
248 err = -1; 321 err = -1;
249 } else { 322 } else {
250 p_info("processed %d lines", lines); 323 p_info("processed %d commands", lines);
251 err = 0; 324 err = 0;
252 } 325 }
253err_close: 326err_close:
254 fclose(fp); 327 if (fp != stdin)
328 fclose(fp);
255 329
256 if (json_output) 330 if (json_output)
257 jsonw_end_array(json_wtr); 331 jsonw_end_array(json_wtr);
diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c
index e549e329be82..f7a810897eac 100644
--- a/tools/bpf/bpftool/prog.c
+++ b/tools/bpf/bpftool/prog.c
@@ -47,8 +47,9 @@
47#include <bpf.h> 47#include <bpf.h>
48#include <libbpf.h> 48#include <libbpf.h>
49 49
50#include "cfg.h"
50#include "main.h" 51#include "main.h"
51#include "disasm.h" 52#include "xlated_dumper.h"
52 53
53static const char * const prog_type_name[] = { 54static const char * const prog_type_name[] = {
54 [BPF_PROG_TYPE_UNSPEC] = "unspec", 55 [BPF_PROG_TYPE_UNSPEC] = "unspec",
@@ -407,259 +408,6 @@ static int do_show(int argc, char **argv)
407 return err; 408 return err;
408} 409}
409 410
410#define SYM_MAX_NAME 256
411
412struct kernel_sym {
413 unsigned long address;
414 char name[SYM_MAX_NAME];
415};
416
417struct dump_data {
418 unsigned long address_call_base;
419 struct kernel_sym *sym_mapping;
420 __u32 sym_count;
421 char scratch_buff[SYM_MAX_NAME];
422};
423
424static int kernel_syms_cmp(const void *sym_a, const void *sym_b)
425{
426 return ((struct kernel_sym *)sym_a)->address -
427 ((struct kernel_sym *)sym_b)->address;
428}
429
430static void kernel_syms_load(struct dump_data *dd)
431{
432 struct kernel_sym *sym;
433 char buff[256];
434 void *tmp, *address;
435 FILE *fp;
436
437 fp = fopen("/proc/kallsyms", "r");
438 if (!fp)
439 return;
440
441 while (!feof(fp)) {
442 if (!fgets(buff, sizeof(buff), fp))
443 break;
444 tmp = realloc(dd->sym_mapping,
445 (dd->sym_count + 1) *
446 sizeof(*dd->sym_mapping));
447 if (!tmp) {
448out:
449 free(dd->sym_mapping);
450 dd->sym_mapping = NULL;
451 fclose(fp);
452 return;
453 }
454 dd->sym_mapping = tmp;
455 sym = &dd->sym_mapping[dd->sym_count];
456 if (sscanf(buff, "%p %*c %s", &address, sym->name) != 2)
457 continue;
458 sym->address = (unsigned long)address;
459 if (!strcmp(sym->name, "__bpf_call_base")) {
460 dd->address_call_base = sym->address;
461 /* sysctl kernel.kptr_restrict was set */
462 if (!sym->address)
463 goto out;
464 }
465 if (sym->address)
466 dd->sym_count++;
467 }
468
469 fclose(fp);
470
471 qsort(dd->sym_mapping, dd->sym_count,
472 sizeof(*dd->sym_mapping), kernel_syms_cmp);
473}
474
475static void kernel_syms_destroy(struct dump_data *dd)
476{
477 free(dd->sym_mapping);
478}
479
480static struct kernel_sym *kernel_syms_search(struct dump_data *dd,
481 unsigned long key)
482{
483 struct kernel_sym sym = {
484 .address = key,
485 };
486
487 return dd->sym_mapping ?
488 bsearch(&sym, dd->sym_mapping, dd->sym_count,
489 sizeof(*dd->sym_mapping), kernel_syms_cmp) : NULL;
490}
491
492static void print_insn(struct bpf_verifier_env *env, const char *fmt, ...)
493{
494 va_list args;
495
496 va_start(args, fmt);
497 vprintf(fmt, args);
498 va_end(args);
499}
500
501static const char *print_call_pcrel(struct dump_data *dd,
502 struct kernel_sym *sym,
503 unsigned long address,
504 const struct bpf_insn *insn)
505{
506 if (sym)
507 snprintf(dd->scratch_buff, sizeof(dd->scratch_buff),
508 "%+d#%s", insn->off, sym->name);
509 else
510 snprintf(dd->scratch_buff, sizeof(dd->scratch_buff),
511 "%+d#0x%lx", insn->off, address);
512 return dd->scratch_buff;
513}
514
515static const char *print_call_helper(struct dump_data *dd,
516 struct kernel_sym *sym,
517 unsigned long address)
518{
519 if (sym)
520 snprintf(dd->scratch_buff, sizeof(dd->scratch_buff),
521 "%s", sym->name);
522 else
523 snprintf(dd->scratch_buff, sizeof(dd->scratch_buff),
524 "0x%lx", address);
525 return dd->scratch_buff;
526}
527
528static const char *print_call(void *private_data,
529 const struct bpf_insn *insn)
530{
531 struct dump_data *dd = private_data;
532 unsigned long address = dd->address_call_base + insn->imm;
533 struct kernel_sym *sym;
534
535 sym = kernel_syms_search(dd, address);
536 if (insn->src_reg == BPF_PSEUDO_CALL)
537 return print_call_pcrel(dd, sym, address, insn);
538 else
539 return print_call_helper(dd, sym, address);
540}
541
542static const char *print_imm(void *private_data,
543 const struct bpf_insn *insn,
544 __u64 full_imm)
545{
546 struct dump_data *dd = private_data;
547
548 if (insn->src_reg == BPF_PSEUDO_MAP_FD)
549 snprintf(dd->scratch_buff, sizeof(dd->scratch_buff),
550 "map[id:%u]", insn->imm);
551 else
552 snprintf(dd->scratch_buff, sizeof(dd->scratch_buff),
553 "0x%llx", (unsigned long long)full_imm);
554 return dd->scratch_buff;
555}
556
557static void dump_xlated_plain(struct dump_data *dd, void *buf,
558 unsigned int len, bool opcodes)
559{
560 const struct bpf_insn_cbs cbs = {
561 .cb_print = print_insn,
562 .cb_call = print_call,
563 .cb_imm = print_imm,
564 .private_data = dd,
565 };
566 struct bpf_insn *insn = buf;
567 bool double_insn = false;
568 unsigned int i;
569
570 for (i = 0; i < len / sizeof(*insn); i++) {
571 if (double_insn) {
572 double_insn = false;
573 continue;
574 }
575
576 double_insn = insn[i].code == (BPF_LD | BPF_IMM | BPF_DW);
577
578 printf("% 4d: ", i);
579 print_bpf_insn(&cbs, NULL, insn + i, true);
580
581 if (opcodes) {
582 printf(" ");
583 fprint_hex(stdout, insn + i, 8, " ");
584 if (double_insn && i < len - 1) {
585 printf(" ");
586 fprint_hex(stdout, insn + i + 1, 8, " ");
587 }
588 printf("\n");
589 }
590 }
591}
592
593static void print_insn_json(struct bpf_verifier_env *env, const char *fmt, ...)
594{
595 unsigned int l = strlen(fmt);
596 char chomped_fmt[l];
597 va_list args;
598
599 va_start(args, fmt);
600 if (l > 0) {
601 strncpy(chomped_fmt, fmt, l - 1);
602 chomped_fmt[l - 1] = '\0';
603 }
604 jsonw_vprintf_enquote(json_wtr, chomped_fmt, args);
605 va_end(args);
606}
607
608static void dump_xlated_json(struct dump_data *dd, void *buf,
609 unsigned int len, bool opcodes)
610{
611 const struct bpf_insn_cbs cbs = {
612 .cb_print = print_insn_json,
613 .cb_call = print_call,
614 .cb_imm = print_imm,
615 .private_data = dd,
616 };
617 struct bpf_insn *insn = buf;
618 bool double_insn = false;
619 unsigned int i;
620
621 jsonw_start_array(json_wtr);
622 for (i = 0; i < len / sizeof(*insn); i++) {
623 if (double_insn) {
624 double_insn = false;
625 continue;
626 }
627 double_insn = insn[i].code == (BPF_LD | BPF_IMM | BPF_DW);
628
629 jsonw_start_object(json_wtr);
630 jsonw_name(json_wtr, "disasm");
631 print_bpf_insn(&cbs, NULL, insn + i, true);
632
633 if (opcodes) {
634 jsonw_name(json_wtr, "opcodes");
635 jsonw_start_object(json_wtr);
636
637 jsonw_name(json_wtr, "code");
638 jsonw_printf(json_wtr, "\"0x%02hhx\"", insn[i].code);
639
640 jsonw_name(json_wtr, "src_reg");
641 jsonw_printf(json_wtr, "\"0x%hhx\"", insn[i].src_reg);
642
643 jsonw_name(json_wtr, "dst_reg");
644 jsonw_printf(json_wtr, "\"0x%hhx\"", insn[i].dst_reg);
645
646 jsonw_name(json_wtr, "off");
647 print_hex_data_json((uint8_t *)(&insn[i].off), 2);
648
649 jsonw_name(json_wtr, "imm");
650 if (double_insn && i < len - 1)
651 print_hex_data_json((uint8_t *)(&insn[i].imm),
652 12);
653 else
654 print_hex_data_json((uint8_t *)(&insn[i].imm),
655 4);
656 jsonw_end_object(json_wtr);
657 }
658 jsonw_end_object(json_wtr);
659 }
660 jsonw_end_array(json_wtr);
661}
662
663static int do_dump(int argc, char **argv) 411static int do_dump(int argc, char **argv)
664{ 412{
665 struct bpf_prog_info info = {}; 413 struct bpf_prog_info info = {};
@@ -668,6 +416,7 @@ static int do_dump(int argc, char **argv)
668 unsigned int buf_size; 416 unsigned int buf_size;
669 char *filepath = NULL; 417 char *filepath = NULL;
670 bool opcodes = false; 418 bool opcodes = false;
419 bool visual = false;
671 unsigned char *buf; 420 unsigned char *buf;
672 __u32 *member_len; 421 __u32 *member_len;
673 __u64 *member_ptr; 422 __u64 *member_ptr;
@@ -706,6 +455,9 @@ static int do_dump(int argc, char **argv)
706 } else if (is_prefix(*argv, "opcodes")) { 455 } else if (is_prefix(*argv, "opcodes")) {
707 opcodes = true; 456 opcodes = true;
708 NEXT_ARG(); 457 NEXT_ARG();
458 } else if (is_prefix(*argv, "visual")) {
459 visual = true;
460 NEXT_ARG();
709 } 461 }
710 462
711 if (argc) { 463 if (argc) {
@@ -777,27 +529,30 @@ static int do_dump(int argc, char **argv)
777 529
778 if (json_output) 530 if (json_output)
779 jsonw_null(json_wtr); 531 jsonw_null(json_wtr);
780 } else { 532 } else if (member_len == &info.jited_prog_len) {
781 if (member_len == &info.jited_prog_len) { 533 const char *name = NULL;
782 const char *name = NULL; 534
783 535 if (info.ifindex) {
784 if (info.ifindex) { 536 name = ifindex_to_bfd_name_ns(info.ifindex,
785 name = ifindex_to_bfd_name_ns(info.ifindex, 537 info.netns_dev,
786 info.netns_dev, 538 info.netns_ino);
787 info.netns_ino); 539 if (!name)
788 if (!name) 540 goto err_free;
789 goto err_free;
790 }
791
792 disasm_print_insn(buf, *member_len, opcodes, name);
793 } else {
794 kernel_syms_load(&dd);
795 if (json_output)
796 dump_xlated_json(&dd, buf, *member_len, opcodes);
797 else
798 dump_xlated_plain(&dd, buf, *member_len, opcodes);
799 kernel_syms_destroy(&dd);
800 } 541 }
542
543 disasm_print_insn(buf, *member_len, opcodes, name);
544 } else if (visual) {
545 if (json_output)
546 jsonw_null(json_wtr);
547 else
548 dump_xlated_cfg(buf, *member_len);
549 } else {
550 kernel_syms_load(&dd);
551 if (json_output)
552 dump_xlated_json(&dd, buf, *member_len, opcodes);
553 else
554 dump_xlated_plain(&dd, buf, *member_len, opcodes);
555 kernel_syms_destroy(&dd);
801 } 556 }
802 557
803 free(buf); 558 free(buf);
@@ -851,7 +606,7 @@ static int do_help(int argc, char **argv)
851 606
852 fprintf(stderr, 607 fprintf(stderr,
853 "Usage: %s %s { show | list } [PROG]\n" 608 "Usage: %s %s { show | list } [PROG]\n"
854 " %s %s dump xlated PROG [{ file FILE | opcodes }]\n" 609 " %s %s dump xlated PROG [{ file FILE | opcodes | visual }]\n"
855 " %s %s dump jited PROG [{ file FILE | opcodes }]\n" 610 " %s %s dump jited PROG [{ file FILE | opcodes }]\n"
856 " %s %s pin PROG FILE\n" 611 " %s %s pin PROG FILE\n"
857 " %s %s load OBJ FILE\n" 612 " %s %s load OBJ FILE\n"
diff --git a/tools/bpf/bpftool/xlated_dumper.c b/tools/bpf/bpftool/xlated_dumper.c
new file mode 100644
index 000000000000..20da835e9e38
--- /dev/null
+++ b/tools/bpf/bpftool/xlated_dumper.c
@@ -0,0 +1,338 @@
1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2/*
3 * Copyright (C) 2018 Netronome Systems, Inc.
4 *
5 * This software is dual licensed under the GNU General License Version 2,
6 * June 1991 as shown in the file COPYING in the top-level directory of this
7 * source tree or the BSD 2-Clause License provided below. You have the
8 * option to license this software under the complete terms of either license.
9 *
10 * The BSD 2-Clause License:
11 *
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
14 * conditions are met:
15 *
16 * 1. Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
18 * disclaimer.
19 *
20 * 2. Redistributions in binary form must reproduce the above
21 * copyright notice, this list of conditions and the following
22 * disclaimer in the documentation and/or other materials
23 * provided with the distribution.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 */
37
38#include <stdarg.h>
39#include <stdio.h>
40#include <stdlib.h>
41#include <string.h>
42#include <sys/types.h>
43
44#include "disasm.h"
45#include "json_writer.h"
46#include "main.h"
47#include "xlated_dumper.h"
48
49static int kernel_syms_cmp(const void *sym_a, const void *sym_b)
50{
51 return ((struct kernel_sym *)sym_a)->address -
52 ((struct kernel_sym *)sym_b)->address;
53}
54
55void kernel_syms_load(struct dump_data *dd)
56{
57 struct kernel_sym *sym;
58 char buff[256];
59 void *tmp, *address;
60 FILE *fp;
61
62 fp = fopen("/proc/kallsyms", "r");
63 if (!fp)
64 return;
65
66 while (!feof(fp)) {
67 if (!fgets(buff, sizeof(buff), fp))
68 break;
69 tmp = realloc(dd->sym_mapping,
70 (dd->sym_count + 1) *
71 sizeof(*dd->sym_mapping));
72 if (!tmp) {
73out:
74 free(dd->sym_mapping);
75 dd->sym_mapping = NULL;
76 fclose(fp);
77 return;
78 }
79 dd->sym_mapping = tmp;
80 sym = &dd->sym_mapping[dd->sym_count];
81 if (sscanf(buff, "%p %*c %s", &address, sym->name) != 2)
82 continue;
83 sym->address = (unsigned long)address;
84 if (!strcmp(sym->name, "__bpf_call_base")) {
85 dd->address_call_base = sym->address;
86 /* sysctl kernel.kptr_restrict was set */
87 if (!sym->address)
88 goto out;
89 }
90 if (sym->address)
91 dd->sym_count++;
92 }
93
94 fclose(fp);
95
96 qsort(dd->sym_mapping, dd->sym_count,
97 sizeof(*dd->sym_mapping), kernel_syms_cmp);
98}
99
100void kernel_syms_destroy(struct dump_data *dd)
101{
102 free(dd->sym_mapping);
103}
104
105static struct kernel_sym *kernel_syms_search(struct dump_data *dd,
106 unsigned long key)
107{
108 struct kernel_sym sym = {
109 .address = key,
110 };
111
112 return dd->sym_mapping ?
113 bsearch(&sym, dd->sym_mapping, dd->sym_count,
114 sizeof(*dd->sym_mapping), kernel_syms_cmp) : NULL;
115}
116
117static void print_insn(struct bpf_verifier_env *env, const char *fmt, ...)
118{
119 va_list args;
120
121 va_start(args, fmt);
122 vprintf(fmt, args);
123 va_end(args);
124}
125
126static void
127print_insn_for_graph(struct bpf_verifier_env *env, const char *fmt, ...)
128{
129 char buf[64], *p;
130 va_list args;
131
132 va_start(args, fmt);
133 vsnprintf(buf, sizeof(buf), fmt, args);
134 va_end(args);
135
136 p = buf;
137 while (*p != '\0') {
138 if (*p == '\n') {
139 memmove(p + 3, p, strlen(buf) + 1 - (p - buf));
140 /* Align each instruction dump row left. */
141 *p++ = '\\';
142 *p++ = 'l';
143 /* Output multiline concatenation. */
144 *p++ = '\\';
145 } else if (*p == '<' || *p == '>' || *p == '|' || *p == '&') {
146 memmove(p + 1, p, strlen(buf) + 1 - (p - buf));
147 /* Escape special character. */
148 *p++ = '\\';
149 }
150
151 p++;
152 }
153
154 printf("%s", buf);
155}
156
157static void print_insn_json(struct bpf_verifier_env *env, const char *fmt, ...)
158{
159 unsigned int l = strlen(fmt);
160 char chomped_fmt[l];
161 va_list args;
162
163 va_start(args, fmt);
164 if (l > 0) {
165 strncpy(chomped_fmt, fmt, l - 1);
166 chomped_fmt[l - 1] = '\0';
167 }
168 jsonw_vprintf_enquote(json_wtr, chomped_fmt, args);
169 va_end(args);
170}
171
172static const char *print_call_pcrel(struct dump_data *dd,
173 struct kernel_sym *sym,
174 unsigned long address,
175 const struct bpf_insn *insn)
176{
177 if (sym)
178 snprintf(dd->scratch_buff, sizeof(dd->scratch_buff),
179 "%+d#%s", insn->off, sym->name);
180 else
181 snprintf(dd->scratch_buff, sizeof(dd->scratch_buff),
182 "%+d#0x%lx", insn->off, address);
183 return dd->scratch_buff;
184}
185
186static const char *print_call_helper(struct dump_data *dd,
187 struct kernel_sym *sym,
188 unsigned long address)
189{
190 if (sym)
191 snprintf(dd->scratch_buff, sizeof(dd->scratch_buff),
192 "%s", sym->name);
193 else
194 snprintf(dd->scratch_buff, sizeof(dd->scratch_buff),
195 "0x%lx", address);
196 return dd->scratch_buff;
197}
198
199static const char *print_call(void *private_data,
200 const struct bpf_insn *insn)
201{
202 struct dump_data *dd = private_data;
203 unsigned long address = dd->address_call_base + insn->imm;
204 struct kernel_sym *sym;
205
206 sym = kernel_syms_search(dd, address);
207 if (insn->src_reg == BPF_PSEUDO_CALL)
208 return print_call_pcrel(dd, sym, address, insn);
209 else
210 return print_call_helper(dd, sym, address);
211}
212
213static const char *print_imm(void *private_data,
214 const struct bpf_insn *insn,
215 __u64 full_imm)
216{
217 struct dump_data *dd = private_data;
218
219 if (insn->src_reg == BPF_PSEUDO_MAP_FD)
220 snprintf(dd->scratch_buff, sizeof(dd->scratch_buff),
221 "map[id:%u]", insn->imm);
222 else
223 snprintf(dd->scratch_buff, sizeof(dd->scratch_buff),
224 "0x%llx", (unsigned long long)full_imm);
225 return dd->scratch_buff;
226}
227
228void dump_xlated_json(struct dump_data *dd, void *buf, unsigned int len,
229 bool opcodes)
230{
231 const struct bpf_insn_cbs cbs = {
232 .cb_print = print_insn_json,
233 .cb_call = print_call,
234 .cb_imm = print_imm,
235 .private_data = dd,
236 };
237 struct bpf_insn *insn = buf;
238 bool double_insn = false;
239 unsigned int i;
240
241 jsonw_start_array(json_wtr);
242 for (i = 0; i < len / sizeof(*insn); i++) {
243 if (double_insn) {
244 double_insn = false;
245 continue;
246 }
247 double_insn = insn[i].code == (BPF_LD | BPF_IMM | BPF_DW);
248
249 jsonw_start_object(json_wtr);
250 jsonw_name(json_wtr, "disasm");
251 print_bpf_insn(&cbs, NULL, insn + i, true);
252
253 if (opcodes) {
254 jsonw_name(json_wtr, "opcodes");
255 jsonw_start_object(json_wtr);
256
257 jsonw_name(json_wtr, "code");
258 jsonw_printf(json_wtr, "\"0x%02hhx\"", insn[i].code);
259
260 jsonw_name(json_wtr, "src_reg");
261 jsonw_printf(json_wtr, "\"0x%hhx\"", insn[i].src_reg);
262
263 jsonw_name(json_wtr, "dst_reg");
264 jsonw_printf(json_wtr, "\"0x%hhx\"", insn[i].dst_reg);
265
266 jsonw_name(json_wtr, "off");
267 print_hex_data_json((uint8_t *)(&insn[i].off), 2);
268
269 jsonw_name(json_wtr, "imm");
270 if (double_insn && i < len - 1)
271 print_hex_data_json((uint8_t *)(&insn[i].imm),
272 12);
273 else
274 print_hex_data_json((uint8_t *)(&insn[i].imm),
275 4);
276 jsonw_end_object(json_wtr);
277 }
278 jsonw_end_object(json_wtr);
279 }
280 jsonw_end_array(json_wtr);
281}
282
283void dump_xlated_plain(struct dump_data *dd, void *buf, unsigned int len,
284 bool opcodes)
285{
286 const struct bpf_insn_cbs cbs = {
287 .cb_print = print_insn,
288 .cb_call = print_call,
289 .cb_imm = print_imm,
290 .private_data = dd,
291 };
292 struct bpf_insn *insn = buf;
293 bool double_insn = false;
294 unsigned int i;
295
296 for (i = 0; i < len / sizeof(*insn); i++) {
297 if (double_insn) {
298 double_insn = false;
299 continue;
300 }
301
302 double_insn = insn[i].code == (BPF_LD | BPF_IMM | BPF_DW);
303
304 printf("% 4d: ", i);
305 print_bpf_insn(&cbs, NULL, insn + i, true);
306
307 if (opcodes) {
308 printf(" ");
309 fprint_hex(stdout, insn + i, 8, " ");
310 if (double_insn && i < len - 1) {
311 printf(" ");
312 fprint_hex(stdout, insn + i + 1, 8, " ");
313 }
314 printf("\n");
315 }
316 }
317}
318
319void dump_xlated_for_graph(struct dump_data *dd, void *buf_start, void *buf_end,
320 unsigned int start_idx)
321{
322 const struct bpf_insn_cbs cbs = {
323 .cb_print = print_insn_for_graph,
324 .cb_call = print_call,
325 .cb_imm = print_imm,
326 .private_data = dd,
327 };
328 struct bpf_insn *insn_start = buf_start;
329 struct bpf_insn *insn_end = buf_end;
330 struct bpf_insn *cur = insn_start;
331
332 for (; cur <= insn_end; cur++) {
333 printf("% 4d: ", (int)(cur - insn_start + start_idx));
334 print_bpf_insn(&cbs, NULL, cur, true);
335 if (cur != insn_end)
336 printf(" | ");
337 }
338}
diff --git a/tools/bpf/bpftool/xlated_dumper.h b/tools/bpf/bpftool/xlated_dumper.h
new file mode 100644
index 000000000000..b34affa7ef2d
--- /dev/null
+++ b/tools/bpf/bpftool/xlated_dumper.h
@@ -0,0 +1,64 @@
1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2/*
3 * Copyright (C) 2018 Netronome Systems, Inc.
4 *
5 * This software is dual licensed under the GNU General License Version 2,
6 * June 1991 as shown in the file COPYING in the top-level directory of this
7 * source tree or the BSD 2-Clause License provided below. You have the
8 * option to license this software under the complete terms of either license.
9 *
10 * The BSD 2-Clause License:
11 *
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
14 * conditions are met:
15 *
16 * 1. Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
18 * disclaimer.
19 *
20 * 2. Redistributions in binary form must reproduce the above
21 * copyright notice, this list of conditions and the following
22 * disclaimer in the documentation and/or other materials
23 * provided with the distribution.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 */
37
38#ifndef __BPF_TOOL_XLATED_DUMPER_H
39#define __BPF_TOOL_XLATED_DUMPER_H
40
41#define SYM_MAX_NAME 256
42
43struct kernel_sym {
44 unsigned long address;
45 char name[SYM_MAX_NAME];
46};
47
48struct dump_data {
49 unsigned long address_call_base;
50 struct kernel_sym *sym_mapping;
51 __u32 sym_count;
52 char scratch_buff[SYM_MAX_NAME + 8];
53};
54
55void kernel_syms_load(struct dump_data *dd);
56void kernel_syms_destroy(struct dump_data *dd);
57void dump_xlated_json(struct dump_data *dd, void *buf, unsigned int len,
58 bool opcodes);
59void dump_xlated_plain(struct dump_data *dd, void *buf, unsigned int len,
60 bool opcodes);
61void dump_xlated_for_graph(struct dump_data *dd, void *buf, void *buf_end,
62 unsigned int start_index);
63
64#endif
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index db6bdc375126..d245c41213ac 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -133,6 +133,7 @@ enum bpf_prog_type {
133 BPF_PROG_TYPE_SOCK_OPS, 133 BPF_PROG_TYPE_SOCK_OPS,
134 BPF_PROG_TYPE_SK_SKB, 134 BPF_PROG_TYPE_SK_SKB,
135 BPF_PROG_TYPE_CGROUP_DEVICE, 135 BPF_PROG_TYPE_CGROUP_DEVICE,
136 BPF_PROG_TYPE_SK_MSG,
136}; 137};
137 138
138enum bpf_attach_type { 139enum bpf_attach_type {
@@ -143,6 +144,7 @@ enum bpf_attach_type {
143 BPF_SK_SKB_STREAM_PARSER, 144 BPF_SK_SKB_STREAM_PARSER,
144 BPF_SK_SKB_STREAM_VERDICT, 145 BPF_SK_SKB_STREAM_VERDICT,
145 BPF_CGROUP_DEVICE, 146 BPF_CGROUP_DEVICE,
147 BPF_SK_MSG_VERDICT,
146 __MAX_BPF_ATTACH_TYPE 148 __MAX_BPF_ATTACH_TYPE
147}; 149};
148 150
@@ -231,6 +233,28 @@ enum bpf_attach_type {
231#define BPF_F_RDONLY (1U << 3) 233#define BPF_F_RDONLY (1U << 3)
232#define BPF_F_WRONLY (1U << 4) 234#define BPF_F_WRONLY (1U << 4)
233 235
236/* Flag for stack_map, store build_id+offset instead of pointer */
237#define BPF_F_STACK_BUILD_ID (1U << 5)
238
239enum bpf_stack_build_id_status {
240 /* user space need an empty entry to identify end of a trace */
241 BPF_STACK_BUILD_ID_EMPTY = 0,
242 /* with valid build_id and offset */
243 BPF_STACK_BUILD_ID_VALID = 1,
244 /* couldn't get build_id, fallback to ip */
245 BPF_STACK_BUILD_ID_IP = 2,
246};
247
248#define BPF_BUILD_ID_SIZE 20
249struct bpf_stack_build_id {
250 __s32 status;
251 unsigned char build_id[BPF_BUILD_ID_SIZE];
252 union {
253 __u64 offset;
254 __u64 ip;
255 };
256};
257
234union bpf_attr { 258union bpf_attr {
235 struct { /* anonymous struct used by BPF_MAP_CREATE command */ 259 struct { /* anonymous struct used by BPF_MAP_CREATE command */
236 __u32 map_type; /* one of enum bpf_map_type */ 260 __u32 map_type; /* one of enum bpf_map_type */
@@ -696,6 +720,15 @@ union bpf_attr {
696 * int bpf_override_return(pt_regs, rc) 720 * int bpf_override_return(pt_regs, rc)
697 * @pt_regs: pointer to struct pt_regs 721 * @pt_regs: pointer to struct pt_regs
698 * @rc: the return value to set 722 * @rc: the return value to set
723 *
724 * int bpf_msg_redirect_map(map, key, flags)
725 * Redirect msg to a sock in map using key as a lookup key for the
726 * sock in map.
727 * @map: pointer to sockmap
728 * @key: key to lookup sock in map
729 * @flags: reserved for future use
730 * Return: SK_PASS
731 *
699 */ 732 */
700#define __BPF_FUNC_MAPPER(FN) \ 733#define __BPF_FUNC_MAPPER(FN) \
701 FN(unspec), \ 734 FN(unspec), \
@@ -757,7 +790,11 @@ union bpf_attr {
757 FN(perf_prog_read_value), \ 790 FN(perf_prog_read_value), \
758 FN(getsockopt), \ 791 FN(getsockopt), \
759 FN(override_return), \ 792 FN(override_return), \
760 FN(sock_ops_cb_flags_set), 793 FN(sock_ops_cb_flags_set), \
794 FN(msg_redirect_map), \
795 FN(msg_apply_bytes), \
796 FN(msg_cork_bytes), \
797 FN(msg_pull_data),
761 798
762/* integer value in 'imm' field of BPF_CALL instruction selects which helper 799/* integer value in 'imm' field of BPF_CALL instruction selects which helper
763 * function eBPF program intends to call 800 * function eBPF program intends to call
@@ -919,6 +956,14 @@ enum sk_action {
919 SK_PASS, 956 SK_PASS,
920}; 957};
921 958
959/* user accessible metadata for SK_MSG packet hook, new fields must
960 * be added to the end of this structure
961 */
962struct sk_msg_md {
963 void *data;
964 void *data_end;
965};
966
922#define BPF_TAG_SIZE 8 967#define BPF_TAG_SIZE 8
923 968
924struct bpf_prog_info { 969struct bpf_prog_info {
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 5bbbf285af74..64a8fc384186 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -1857,6 +1857,7 @@ static const struct {
1857 BPF_PROG_SEC("lwt_xmit", BPF_PROG_TYPE_LWT_XMIT), 1857 BPF_PROG_SEC("lwt_xmit", BPF_PROG_TYPE_LWT_XMIT),
1858 BPF_PROG_SEC("sockops", BPF_PROG_TYPE_SOCK_OPS), 1858 BPF_PROG_SEC("sockops", BPF_PROG_TYPE_SOCK_OPS),
1859 BPF_PROG_SEC("sk_skb", BPF_PROG_TYPE_SK_SKB), 1859 BPF_PROG_SEC("sk_skb", BPF_PROG_TYPE_SK_SKB),
1860 BPF_PROG_SEC("sk_msg", BPF_PROG_TYPE_SK_MSG),
1860}; 1861};
1861#undef BPF_PROG_SEC 1862#undef BPF_PROG_SEC
1862 1863
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index 5c43c187f27c..f35fb02bdf56 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -13,6 +13,14 @@ endif
13CFLAGS += -Wall -O2 -I$(APIDIR) -I$(LIBDIR) -I$(GENDIR) $(GENFLAGS) -I../../../include 13CFLAGS += -Wall -O2 -I$(APIDIR) -I$(LIBDIR) -I$(GENDIR) $(GENFLAGS) -I../../../include
14LDLIBS += -lcap -lelf -lrt -lpthread 14LDLIBS += -lcap -lelf -lrt -lpthread
15 15
16TEST_CUSTOM_PROGS = $(OUTPUT)/urandom_read
17all: $(TEST_CUSTOM_PROGS)
18
19$(TEST_CUSTOM_PROGS): urandom_read
20
21urandom_read: urandom_read.c
22 $(CC) -o $(TEST_CUSTOM_PROGS) -static $<
23
16# Order correspond to 'make run_tests' order 24# Order correspond to 'make run_tests' order
17TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test_progs \ 25TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test_progs \
18 test_align test_verifier_log test_dev_cgroup test_tcpbpf_user 26 test_align test_verifier_log test_dev_cgroup test_tcpbpf_user
@@ -21,7 +29,8 @@ TEST_GEN_FILES = test_pkt_access.o test_xdp.o test_l4lb.o test_tcp_estats.o test
21 test_pkt_md_access.o test_xdp_redirect.o test_xdp_meta.o sockmap_parse_prog.o \ 29 test_pkt_md_access.o test_xdp_redirect.o test_xdp_meta.o sockmap_parse_prog.o \
22 sockmap_verdict_prog.o dev_cgroup.o sample_ret0.o test_tracepoint.o \ 30 sockmap_verdict_prog.o dev_cgroup.o sample_ret0.o test_tracepoint.o \
23 test_l4lb_noinline.o test_xdp_noinline.o test_stacktrace_map.o \ 31 test_l4lb_noinline.o test_xdp_noinline.o test_stacktrace_map.o \
24 sample_map_ret0.o test_tcpbpf_kern.o 32 sample_map_ret0.o test_tcpbpf_kern.o test_stacktrace_build_id.o \
33 sockmap_tcp_msg_prog.o
25 34
26# Order correspond to 'make run_tests' order 35# Order correspond to 'make run_tests' order
27TEST_PROGS := test_kmod.sh \ 36TEST_PROGS := test_kmod.sh \
@@ -35,12 +44,14 @@ TEST_GEN_PROGS_EXTENDED = test_libbpf_open
35 44
36include ../lib.mk 45include ../lib.mk
37 46
38BPFOBJ := $(OUTPUT)/libbpf.a cgroup_helpers.c 47BPFOBJ := $(OUTPUT)/libbpf.a
39 48
40$(TEST_GEN_PROGS): $(BPFOBJ) 49$(TEST_GEN_PROGS): $(BPFOBJ)
41 50
42$(TEST_GEN_PROGS_EXTENDED): $(OUTPUT)/libbpf.a 51$(TEST_GEN_PROGS_EXTENDED): $(OUTPUT)/libbpf.a
43 52
53$(OUTPUT)/test_dev_cgroup: cgroup_helpers.c
54
44.PHONY: force 55.PHONY: force
45 56
46# force a rebuild of BPFOBJ when its dependencies are updated 57# force a rebuild of BPFOBJ when its dependencies are updated
@@ -72,3 +83,5 @@ $(OUTPUT)/%.o: %.c
72 $(CLANG) $(CLANG_FLAGS) \ 83 $(CLANG) $(CLANG_FLAGS) \
73 -O2 -target bpf -emit-llvm -c $< -o - | \ 84 -O2 -target bpf -emit-llvm -c $< -o - | \
74 $(LLC) -march=bpf -mcpu=$(CPU) -filetype=obj -o $@ 85 $(LLC) -march=bpf -mcpu=$(CPU) -filetype=obj -o $@
86
87EXTRA_CLEAN := $(TEST_CUSTOM_PROGS)
diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h
index dde2c11d7771..7cae376d8d0c 100644
--- a/tools/testing/selftests/bpf/bpf_helpers.h
+++ b/tools/testing/selftests/bpf/bpf_helpers.h
@@ -86,6 +86,14 @@ static int (*bpf_perf_prog_read_value)(void *ctx, void *buf,
86 (void *) BPF_FUNC_perf_prog_read_value; 86 (void *) BPF_FUNC_perf_prog_read_value;
87static int (*bpf_override_return)(void *ctx, unsigned long rc) = 87static int (*bpf_override_return)(void *ctx, unsigned long rc) =
88 (void *) BPF_FUNC_override_return; 88 (void *) BPF_FUNC_override_return;
89static int (*bpf_msg_redirect_map)(void *ctx, void *map, int key, int flags) =
90 (void *) BPF_FUNC_msg_redirect_map;
91static int (*bpf_msg_apply_bytes)(void *ctx, int len) =
92 (void *) BPF_FUNC_msg_apply_bytes;
93static int (*bpf_msg_cork_bytes)(void *ctx, int len) =
94 (void *) BPF_FUNC_msg_cork_bytes;
95static int (*bpf_msg_pull_data)(void *ctx, int start, int end, int flags) =
96 (void *) BPF_FUNC_msg_pull_data;
89 97
90/* llvm builtin functions that eBPF C program may use to 98/* llvm builtin functions that eBPF C program may use to
91 * emit BPF_LD_ABS and BPF_LD_IND instructions 99 * emit BPF_LD_ABS and BPF_LD_IND instructions
@@ -123,6 +131,8 @@ static int (*bpf_skb_under_cgroup)(void *ctx, void *map, int index) =
123 (void *) BPF_FUNC_skb_under_cgroup; 131 (void *) BPF_FUNC_skb_under_cgroup;
124static int (*bpf_skb_change_head)(void *, int len, int flags) = 132static int (*bpf_skb_change_head)(void *, int len, int flags) =
125 (void *) BPF_FUNC_skb_change_head; 133 (void *) BPF_FUNC_skb_change_head;
134static int (*bpf_skb_pull_data)(void *, int len) =
135 (void *) BPF_FUNC_skb_pull_data;
126 136
127/* Scan the ARCH passed in from ARCH env variable (see Makefile) */ 137/* Scan the ARCH passed in from ARCH env variable (see Makefile) */
128#if defined(__TARGET_ARCH_x86) 138#if defined(__TARGET_ARCH_x86)
diff --git a/tools/testing/selftests/bpf/bpf_rlimit.h b/tools/testing/selftests/bpf/bpf_rlimit.h
new file mode 100644
index 000000000000..9dac9b30f8ef
--- /dev/null
+++ b/tools/testing/selftests/bpf/bpf_rlimit.h
@@ -0,0 +1,28 @@
1#include <sys/resource.h>
2#include <stdio.h>
3
4static __attribute__((constructor)) void bpf_rlimit_ctor(void)
5{
6 struct rlimit rlim_old, rlim_new = {
7 .rlim_cur = RLIM_INFINITY,
8 .rlim_max = RLIM_INFINITY,
9 };
10
11 getrlimit(RLIMIT_MEMLOCK, &rlim_old);
12 /* For the sake of running the test cases, we temporarily
13 * set rlimit to infinity in order for kernel to focus on
14 * errors from actual test cases and not getting noise
15 * from hitting memlock limits. The limit is on per-process
16 * basis and not a global one, hence destructor not really
17 * needed here.
18 */
19 if (setrlimit(RLIMIT_MEMLOCK, &rlim_new) < 0) {
20 perror("Unable to lift memlock rlimit");
21 /* Trying out lower limit, but expect potential test
22 * case failures from this!
23 */
24 rlim_new.rlim_cur = rlim_old.rlim_cur + (1UL << 20);
25 rlim_new.rlim_max = rlim_old.rlim_max + (1UL << 20);
26 setrlimit(RLIMIT_MEMLOCK, &rlim_new);
27 }
28}
diff --git a/tools/testing/selftests/bpf/sockmap_parse_prog.c b/tools/testing/selftests/bpf/sockmap_parse_prog.c
index a1dec2b6d9c5..0f92858f6226 100644
--- a/tools/testing/selftests/bpf/sockmap_parse_prog.c
+++ b/tools/testing/selftests/bpf/sockmap_parse_prog.c
@@ -20,14 +20,25 @@ int bpf_prog1(struct __sk_buff *skb)
20 __u32 lport = skb->local_port; 20 __u32 lport = skb->local_port;
21 __u32 rport = skb->remote_port; 21 __u32 rport = skb->remote_port;
22 __u8 *d = data; 22 __u8 *d = data;
23 __u32 len = (__u32) data_end - (__u32) data;
24 int err;
23 25
24 if (data + 10 > data_end) 26 if (data + 10 > data_end) {
25 return skb->len; 27 err = bpf_skb_pull_data(skb, 10);
28 if (err)
29 return SK_DROP;
30
31 data_end = (void *)(long)skb->data_end;
32 data = (void *)(long)skb->data;
33 if (data + 10 > data_end)
34 return SK_DROP;
35 }
26 36
27 /* This write/read is a bit pointless but tests the verifier and 37 /* This write/read is a bit pointless but tests the verifier and
28 * strparser handler for read/write pkt data and access into sk 38 * strparser handler for read/write pkt data and access into sk
29 * fields. 39 * fields.
30 */ 40 */
41 d = data;
31 d[7] = 1; 42 d[7] = 1;
32 return skb->len; 43 return skb->len;
33} 44}
diff --git a/tools/testing/selftests/bpf/sockmap_tcp_msg_prog.c b/tools/testing/selftests/bpf/sockmap_tcp_msg_prog.c
new file mode 100644
index 000000000000..12a7b5c82ed6
--- /dev/null
+++ b/tools/testing/selftests/bpf/sockmap_tcp_msg_prog.c
@@ -0,0 +1,33 @@
1#include <linux/bpf.h>
2#include "bpf_helpers.h"
3#include "bpf_util.h"
4#include "bpf_endian.h"
5
6int _version SEC("version") = 1;
7
8#define bpf_printk(fmt, ...) \
9({ \
10 char ____fmt[] = fmt; \
11 bpf_trace_printk(____fmt, sizeof(____fmt), \
12 ##__VA_ARGS__); \
13})
14
15SEC("sk_msg1")
16int bpf_prog1(struct sk_msg_md *msg)
17{
18 void *data_end = (void *)(long) msg->data_end;
19 void *data = (void *)(long) msg->data;
20
21 char *d;
22
23 if (data + 8 > data_end)
24 return SK_DROP;
25
26 bpf_printk("data length %i\n", (__u64)msg->data_end - (__u64)msg->data);
27 d = (char *)data;
28 bpf_printk("hello sendmsg hook %i %i\n", d[0], d[1]);
29
30 return SK_PASS;
31}
32
33char _license[] SEC("license") = "GPL";
diff --git a/tools/testing/selftests/bpf/sockmap_verdict_prog.c b/tools/testing/selftests/bpf/sockmap_verdict_prog.c
index d7bea972cb21..2ce7634a4012 100644
--- a/tools/testing/selftests/bpf/sockmap_verdict_prog.c
+++ b/tools/testing/selftests/bpf/sockmap_verdict_prog.c
@@ -26,6 +26,13 @@ struct bpf_map_def SEC("maps") sock_map_tx = {
26 .max_entries = 20, 26 .max_entries = 20,
27}; 27};
28 28
29struct bpf_map_def SEC("maps") sock_map_msg = {
30 .type = BPF_MAP_TYPE_SOCKMAP,
31 .key_size = sizeof(int),
32 .value_size = sizeof(int),
33 .max_entries = 20,
34};
35
29struct bpf_map_def SEC("maps") sock_map_break = { 36struct bpf_map_def SEC("maps") sock_map_break = {
30 .type = BPF_MAP_TYPE_ARRAY, 37 .type = BPF_MAP_TYPE_ARRAY,
31 .key_size = sizeof(int), 38 .key_size = sizeof(int),
diff --git a/tools/testing/selftests/bpf/test_align.c b/tools/testing/selftests/bpf/test_align.c
index ff8bd7e3e50c..6b1b302310fe 100644
--- a/tools/testing/selftests/bpf/test_align.c
+++ b/tools/testing/selftests/bpf/test_align.c
@@ -9,8 +9,6 @@
9#include <stddef.h> 9#include <stddef.h>
10#include <stdbool.h> 10#include <stdbool.h>
11 11
12#include <sys/resource.h>
13
14#include <linux/unistd.h> 12#include <linux/unistd.h>
15#include <linux/filter.h> 13#include <linux/filter.h>
16#include <linux/bpf_perf_event.h> 14#include <linux/bpf_perf_event.h>
@@ -19,6 +17,7 @@
19#include <bpf/bpf.h> 17#include <bpf/bpf.h>
20 18
21#include "../../../include/linux/filter.h" 19#include "../../../include/linux/filter.h"
20#include "bpf_rlimit.h"
22 21
23#ifndef ARRAY_SIZE 22#ifndef ARRAY_SIZE
24# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 23# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
@@ -702,9 +701,6 @@ static int do_test(unsigned int from, unsigned int to)
702int main(int argc, char **argv) 701int main(int argc, char **argv)
703{ 702{
704 unsigned int from = 0, to = ARRAY_SIZE(tests); 703 unsigned int from = 0, to = ARRAY_SIZE(tests);
705 struct rlimit rinf = { RLIM_INFINITY, RLIM_INFINITY };
706
707 setrlimit(RLIMIT_MEMLOCK, &rinf);
708 704
709 if (argc == 3) { 705 if (argc == 3) {
710 unsigned int l = atoi(argv[argc - 2]); 706 unsigned int l = atoi(argv[argc - 2]);
diff --git a/tools/testing/selftests/bpf/test_dev_cgroup.c b/tools/testing/selftests/bpf/test_dev_cgroup.c
index 3489cc283433..9c8b50bac7e0 100644
--- a/tools/testing/selftests/bpf/test_dev_cgroup.c
+++ b/tools/testing/selftests/bpf/test_dev_cgroup.c
@@ -11,13 +11,13 @@
11#include <errno.h> 11#include <errno.h>
12#include <assert.h> 12#include <assert.h>
13#include <sys/time.h> 13#include <sys/time.h>
14#include <sys/resource.h>
15 14
16#include <linux/bpf.h> 15#include <linux/bpf.h>
17#include <bpf/bpf.h> 16#include <bpf/bpf.h>
18#include <bpf/libbpf.h> 17#include <bpf/libbpf.h>
19 18
20#include "cgroup_helpers.h" 19#include "cgroup_helpers.h"
20#include "bpf_rlimit.h"
21 21
22#define DEV_CGROUP_PROG "./dev_cgroup.o" 22#define DEV_CGROUP_PROG "./dev_cgroup.o"
23 23
@@ -25,15 +25,11 @@
25 25
26int main(int argc, char **argv) 26int main(int argc, char **argv)
27{ 27{
28 struct rlimit limit = { RLIM_INFINITY, RLIM_INFINITY };
29 struct bpf_object *obj; 28 struct bpf_object *obj;
30 int error = EXIT_FAILURE; 29 int error = EXIT_FAILURE;
31 int prog_fd, cgroup_fd; 30 int prog_fd, cgroup_fd;
32 __u32 prog_cnt; 31 __u32 prog_cnt;
33 32
34 if (setrlimit(RLIMIT_MEMLOCK, &limit) < 0)
35 perror("Unable to lift memlock rlimit");
36
37 if (bpf_prog_load(DEV_CGROUP_PROG, BPF_PROG_TYPE_CGROUP_DEVICE, 33 if (bpf_prog_load(DEV_CGROUP_PROG, BPF_PROG_TYPE_CGROUP_DEVICE,
38 &obj, &prog_fd)) { 34 &obj, &prog_fd)) {
39 printf("Failed to load DEV_CGROUP program\n"); 35 printf("Failed to load DEV_CGROUP program\n");
diff --git a/tools/testing/selftests/bpf/test_lpm_map.c b/tools/testing/selftests/bpf/test_lpm_map.c
index 2be87e9ee28d..147e34cfceb7 100644
--- a/tools/testing/selftests/bpf/test_lpm_map.c
+++ b/tools/testing/selftests/bpf/test_lpm_map.c
@@ -22,10 +22,11 @@
22#include <unistd.h> 22#include <unistd.h>
23#include <arpa/inet.h> 23#include <arpa/inet.h>
24#include <sys/time.h> 24#include <sys/time.h>
25#include <sys/resource.h>
26 25
27#include <bpf/bpf.h> 26#include <bpf/bpf.h>
27
28#include "bpf_util.h" 28#include "bpf_util.h"
29#include "bpf_rlimit.h"
29 30
30struct tlpm_node { 31struct tlpm_node {
31 struct tlpm_node *next; 32 struct tlpm_node *next;
@@ -736,17 +737,11 @@ static void test_lpm_multi_thread(void)
736 737
737int main(void) 738int main(void)
738{ 739{
739 struct rlimit limit = { RLIM_INFINITY, RLIM_INFINITY }; 740 int i;
740 int i, ret;
741 741
742 /* we want predictable, pseudo random tests */ 742 /* we want predictable, pseudo random tests */
743 srand(0xf00ba1); 743 srand(0xf00ba1);
744 744
745 /* allow unlimited locked memory */
746 ret = setrlimit(RLIMIT_MEMLOCK, &limit);
747 if (ret < 0)
748 perror("Unable to lift memlock rlimit");
749
750 test_lpm_basic(); 745 test_lpm_basic();
751 test_lpm_order(); 746 test_lpm_order();
752 747
@@ -755,11 +750,8 @@ int main(void)
755 test_lpm_map(i); 750 test_lpm_map(i);
756 751
757 test_lpm_ipaddr(); 752 test_lpm_ipaddr();
758
759 test_lpm_delete(); 753 test_lpm_delete();
760
761 test_lpm_get_next_key(); 754 test_lpm_get_next_key();
762
763 test_lpm_multi_thread(); 755 test_lpm_multi_thread();
764 756
765 printf("test_lpm: OK\n"); 757 printf("test_lpm: OK\n");
diff --git a/tools/testing/selftests/bpf/test_lru_map.c b/tools/testing/selftests/bpf/test_lru_map.c
index 8c10c9180c1a..781c7de343be 100644
--- a/tools/testing/selftests/bpf/test_lru_map.c
+++ b/tools/testing/selftests/bpf/test_lru_map.c
@@ -16,10 +16,11 @@
16#include <time.h> 16#include <time.h>
17 17
18#include <sys/wait.h> 18#include <sys/wait.h>
19#include <sys/resource.h>
20 19
21#include <bpf/bpf.h> 20#include <bpf/bpf.h>
21
22#include "bpf_util.h" 22#include "bpf_util.h"
23#include "bpf_rlimit.h"
23 24
24#define LOCAL_FREE_TARGET (128) 25#define LOCAL_FREE_TARGET (128)
25#define PERCPU_FREE_TARGET (4) 26#define PERCPU_FREE_TARGET (4)
@@ -613,7 +614,6 @@ static void test_lru_sanity6(int map_type, int map_flags, int tgt_free)
613 614
614int main(int argc, char **argv) 615int main(int argc, char **argv)
615{ 616{
616 struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
617 int map_types[] = {BPF_MAP_TYPE_LRU_HASH, 617 int map_types[] = {BPF_MAP_TYPE_LRU_HASH,
618 BPF_MAP_TYPE_LRU_PERCPU_HASH}; 618 BPF_MAP_TYPE_LRU_PERCPU_HASH};
619 int map_flags[] = {0, BPF_F_NO_COMMON_LRU}; 619 int map_flags[] = {0, BPF_F_NO_COMMON_LRU};
@@ -621,8 +621,6 @@ int main(int argc, char **argv)
621 621
622 setbuf(stdout, NULL); 622 setbuf(stdout, NULL);
623 623
624 assert(!setrlimit(RLIMIT_MEMLOCK, &r));
625
626 nr_cpus = bpf_num_possible_cpus(); 624 nr_cpus = bpf_num_possible_cpus();
627 assert(nr_cpus != -1); 625 assert(nr_cpus != -1);
628 printf("nr_cpus:%d\n\n", nr_cpus); 626 printf("nr_cpus:%d\n\n", nr_cpus);
diff --git a/tools/testing/selftests/bpf/test_maps.c b/tools/testing/selftests/bpf/test_maps.c
index 9e03a4c356a4..6c253343a6f9 100644
--- a/tools/testing/selftests/bpf/test_maps.c
+++ b/tools/testing/selftests/bpf/test_maps.c
@@ -17,13 +17,14 @@
17#include <stdlib.h> 17#include <stdlib.h>
18 18
19#include <sys/wait.h> 19#include <sys/wait.h>
20#include <sys/resource.h>
21 20
22#include <linux/bpf.h> 21#include <linux/bpf.h>
23 22
24#include <bpf/bpf.h> 23#include <bpf/bpf.h>
25#include <bpf/libbpf.h> 24#include <bpf/libbpf.h>
25
26#include "bpf_util.h" 26#include "bpf_util.h"
27#include "bpf_rlimit.h"
27 28
28static int map_flags; 29static int map_flags;
29 30
@@ -463,15 +464,17 @@ static void test_devmap(int task, void *data)
463#include <linux/err.h> 464#include <linux/err.h>
464#define SOCKMAP_PARSE_PROG "./sockmap_parse_prog.o" 465#define SOCKMAP_PARSE_PROG "./sockmap_parse_prog.o"
465#define SOCKMAP_VERDICT_PROG "./sockmap_verdict_prog.o" 466#define SOCKMAP_VERDICT_PROG "./sockmap_verdict_prog.o"
467#define SOCKMAP_TCP_MSG_PROG "./sockmap_tcp_msg_prog.o"
466static void test_sockmap(int tasks, void *data) 468static void test_sockmap(int tasks, void *data)
467{ 469{
468 int one = 1, map_fd_rx = 0, map_fd_tx = 0, map_fd_break, s, sc, rc; 470 struct bpf_map *bpf_map_rx, *bpf_map_tx, *bpf_map_msg, *bpf_map_break;
469 struct bpf_map *bpf_map_rx, *bpf_map_tx, *bpf_map_break; 471 int map_fd_msg = 0, map_fd_rx = 0, map_fd_tx = 0, map_fd_break;
470 int ports[] = {50200, 50201, 50202, 50204}; 472 int ports[] = {50200, 50201, 50202, 50204};
471 int err, i, fd, udp, sfd[6] = {0xdeadbeef}; 473 int err, i, fd, udp, sfd[6] = {0xdeadbeef};
472 u8 buf[20] = {0x0, 0x5, 0x3, 0x2, 0x1, 0x0}; 474 u8 buf[20] = {0x0, 0x5, 0x3, 0x2, 0x1, 0x0};
473 int parse_prog, verdict_prog; 475 int parse_prog, verdict_prog, msg_prog;
474 struct sockaddr_in addr; 476 struct sockaddr_in addr;
477 int one = 1, s, sc, rc;
475 struct bpf_object *obj; 478 struct bpf_object *obj;
476 struct timeval to; 479 struct timeval to;
477 __u32 key, value; 480 __u32 key, value;
@@ -583,6 +586,12 @@ static void test_sockmap(int tasks, void *data)
583 goto out_sockmap; 586 goto out_sockmap;
584 } 587 }
585 588
589 err = bpf_prog_attach(-1, fd, BPF_SK_MSG_VERDICT, 0);
590 if (!err) {
591 printf("Failed invalid msg verdict prog attach\n");
592 goto out_sockmap;
593 }
594
586 err = bpf_prog_attach(-1, fd, __MAX_BPF_ATTACH_TYPE, 0); 595 err = bpf_prog_attach(-1, fd, __MAX_BPF_ATTACH_TYPE, 0);
587 if (!err) { 596 if (!err) {
588 printf("Failed unknown prog attach\n"); 597 printf("Failed unknown prog attach\n");
@@ -601,6 +610,12 @@ static void test_sockmap(int tasks, void *data)
601 goto out_sockmap; 610 goto out_sockmap;
602 } 611 }
603 612
613 err = bpf_prog_detach(fd, BPF_SK_MSG_VERDICT);
614 if (err) {
615 printf("Failed empty msg verdict prog detach\n");
616 goto out_sockmap;
617 }
618
604 err = bpf_prog_detach(fd, __MAX_BPF_ATTACH_TYPE); 619 err = bpf_prog_detach(fd, __MAX_BPF_ATTACH_TYPE);
605 if (!err) { 620 if (!err) {
606 printf("Detach invalid prog successful\n"); 621 printf("Detach invalid prog successful\n");
@@ -615,6 +630,13 @@ static void test_sockmap(int tasks, void *data)
615 goto out_sockmap; 630 goto out_sockmap;
616 } 631 }
617 632
633 err = bpf_prog_load(SOCKMAP_TCP_MSG_PROG,
634 BPF_PROG_TYPE_SK_MSG, &obj, &msg_prog);
635 if (err) {
636 printf("Failed to load SK_SKB msg prog\n");
637 goto out_sockmap;
638 }
639
618 err = bpf_prog_load(SOCKMAP_VERDICT_PROG, 640 err = bpf_prog_load(SOCKMAP_VERDICT_PROG,
619 BPF_PROG_TYPE_SK_SKB, &obj, &verdict_prog); 641 BPF_PROG_TYPE_SK_SKB, &obj, &verdict_prog);
620 if (err) { 642 if (err) {
@@ -630,7 +652,7 @@ static void test_sockmap(int tasks, void *data)
630 652
631 map_fd_rx = bpf_map__fd(bpf_map_rx); 653 map_fd_rx = bpf_map__fd(bpf_map_rx);
632 if (map_fd_rx < 0) { 654 if (map_fd_rx < 0) {
633 printf("Failed to get map fd\n"); 655 printf("Failed to get map rx fd\n");
634 goto out_sockmap; 656 goto out_sockmap;
635 } 657 }
636 658
@@ -646,6 +668,18 @@ static void test_sockmap(int tasks, void *data)
646 goto out_sockmap; 668 goto out_sockmap;
647 } 669 }
648 670
671 bpf_map_msg = bpf_object__find_map_by_name(obj, "sock_map_msg");
672 if (IS_ERR(bpf_map_msg)) {
673 printf("Failed to load map msg from msg_verdict prog\n");
674 goto out_sockmap;
675 }
676
677 map_fd_msg = bpf_map__fd(bpf_map_msg);
678 if (map_fd_msg < 0) {
679 printf("Failed to get map msg fd\n");
680 goto out_sockmap;
681 }
682
649 bpf_map_break = bpf_object__find_map_by_name(obj, "sock_map_break"); 683 bpf_map_break = bpf_object__find_map_by_name(obj, "sock_map_break");
650 if (IS_ERR(bpf_map_break)) { 684 if (IS_ERR(bpf_map_break)) {
651 printf("Failed to load map tx from verdict prog\n"); 685 printf("Failed to load map tx from verdict prog\n");
@@ -679,6 +713,12 @@ static void test_sockmap(int tasks, void *data)
679 goto out_sockmap; 713 goto out_sockmap;
680 } 714 }
681 715
716 err = bpf_prog_attach(msg_prog, map_fd_msg, BPF_SK_MSG_VERDICT, 0);
717 if (err) {
718 printf("Failed msg verdict bpf prog attach\n");
719 goto out_sockmap;
720 }
721
682 err = bpf_prog_attach(verdict_prog, map_fd_rx, 722 err = bpf_prog_attach(verdict_prog, map_fd_rx,
683 __MAX_BPF_ATTACH_TYPE, 0); 723 __MAX_BPF_ATTACH_TYPE, 0);
684 if (!err) { 724 if (!err) {
@@ -718,6 +758,14 @@ static void test_sockmap(int tasks, void *data)
718 } 758 }
719 } 759 }
720 760
761 /* Put sfd[2] (sending fd below) into msg map to test sendmsg bpf */
762 i = 0;
763 err = bpf_map_update_elem(map_fd_msg, &i, &sfd[2], BPF_ANY);
764 if (err) {
765 printf("Failed map_fd_msg update sockmap %i\n", err);
766 goto out_sockmap;
767 }
768
721 /* Test map send/recv */ 769 /* Test map send/recv */
722 for (i = 0; i < 2; i++) { 770 for (i = 0; i < 2; i++) {
723 buf[0] = i; 771 buf[0] = i;
@@ -1126,10 +1174,6 @@ static void run_all_tests(void)
1126 1174
1127int main(void) 1175int main(void)
1128{ 1176{
1129 struct rlimit rinf = { RLIM_INFINITY, RLIM_INFINITY };
1130
1131 setrlimit(RLIMIT_MEMLOCK, &rinf);
1132
1133 map_flags = 0; 1177 map_flags = 0;
1134 run_all_tests(); 1178 run_all_tests();
1135 1179
diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c
index b549308abd19..e9df48b306df 100644
--- a/tools/testing/selftests/bpf/test_progs.c
+++ b/tools/testing/selftests/bpf/test_progs.c
@@ -26,7 +26,6 @@ typedef __u16 __sum16;
26 26
27#include <sys/ioctl.h> 27#include <sys/ioctl.h>
28#include <sys/wait.h> 28#include <sys/wait.h>
29#include <sys/resource.h>
30#include <sys/types.h> 29#include <sys/types.h>
31#include <fcntl.h> 30#include <fcntl.h>
32 31
@@ -34,9 +33,11 @@ typedef __u16 __sum16;
34#include <linux/err.h> 33#include <linux/err.h>
35#include <bpf/bpf.h> 34#include <bpf/bpf.h>
36#include <bpf/libbpf.h> 35#include <bpf/libbpf.h>
36
37#include "test_iptunnel_common.h" 37#include "test_iptunnel_common.h"
38#include "bpf_util.h" 38#include "bpf_util.h"
39#include "bpf_endian.h" 39#include "bpf_endian.h"
40#include "bpf_rlimit.h"
40 41
41static int error_cnt, pass_cnt; 42static int error_cnt, pass_cnt;
42 43
@@ -840,7 +841,8 @@ static void test_tp_attach_query(void)
840static int compare_map_keys(int map1_fd, int map2_fd) 841static int compare_map_keys(int map1_fd, int map2_fd)
841{ 842{
842 __u32 key, next_key; 843 __u32 key, next_key;
843 char val_buf[PERF_MAX_STACK_DEPTH * sizeof(__u64)]; 844 char val_buf[PERF_MAX_STACK_DEPTH *
845 sizeof(struct bpf_stack_build_id)];
844 int err; 846 int err;
845 847
846 err = bpf_map_get_next_key(map1_fd, NULL, &key); 848 err = bpf_map_get_next_key(map1_fd, NULL, &key);
@@ -963,12 +965,168 @@ out:
963 return; 965 return;
964} 966}
965 967
966int main(void) 968static int extract_build_id(char *build_id, size_t size)
969{
970 FILE *fp;
971 char *line = NULL;
972 size_t len = 0;
973
974 fp = popen("readelf -n ./urandom_read | grep 'Build ID'", "r");
975 if (fp == NULL)
976 return -1;
977
978 if (getline(&line, &len, fp) == -1)
979 goto err;
980 fclose(fp);
981
982 if (len > size)
983 len = size;
984 memcpy(build_id, line, len);
985 build_id[len] = '\0';
986 return 0;
987err:
988 fclose(fp);
989 return -1;
990}
991
992static void test_stacktrace_build_id(void)
967{ 993{
968 struct rlimit rinf = { RLIM_INFINITY, RLIM_INFINITY }; 994 int control_map_fd, stackid_hmap_fd, stackmap_fd;
995 const char *file = "./test_stacktrace_build_id.o";
996 int bytes, efd, err, pmu_fd, prog_fd;
997 struct perf_event_attr attr = {};
998 __u32 key, previous_key, val, duration = 0;
999 struct bpf_object *obj;
1000 char buf[256];
1001 int i, j;
1002 struct bpf_stack_build_id id_offs[PERF_MAX_STACK_DEPTH];
1003 int build_id_matches = 0;
969 1004
970 setrlimit(RLIMIT_MEMLOCK, &rinf); 1005 err = bpf_prog_load(file, BPF_PROG_TYPE_TRACEPOINT, &obj, &prog_fd);
1006 if (CHECK(err, "prog_load", "err %d errno %d\n", err, errno))
1007 goto out;
1008
1009 /* Get the ID for the sched/sched_switch tracepoint */
1010 snprintf(buf, sizeof(buf),
1011 "/sys/kernel/debug/tracing/events/random/urandom_read/id");
1012 efd = open(buf, O_RDONLY, 0);
1013 if (CHECK(efd < 0, "open", "err %d errno %d\n", efd, errno))
1014 goto close_prog;
971 1015
1016 bytes = read(efd, buf, sizeof(buf));
1017 close(efd);
1018 if (CHECK(bytes <= 0 || bytes >= sizeof(buf),
1019 "read", "bytes %d errno %d\n", bytes, errno))
1020 goto close_prog;
1021
1022 /* Open the perf event and attach bpf progrram */
1023 attr.config = strtol(buf, NULL, 0);
1024 attr.type = PERF_TYPE_TRACEPOINT;
1025 attr.sample_type = PERF_SAMPLE_RAW | PERF_SAMPLE_CALLCHAIN;
1026 attr.sample_period = 1;
1027 attr.wakeup_events = 1;
1028 pmu_fd = syscall(__NR_perf_event_open, &attr, -1 /* pid */,
1029 0 /* cpu 0 */, -1 /* group id */,
1030 0 /* flags */);
1031 if (CHECK(pmu_fd < 0, "perf_event_open", "err %d errno %d\n",
1032 pmu_fd, errno))
1033 goto close_prog;
1034
1035 err = ioctl(pmu_fd, PERF_EVENT_IOC_ENABLE, 0);
1036 if (CHECK(err, "perf_event_ioc_enable", "err %d errno %d\n",
1037 err, errno))
1038 goto close_pmu;
1039
1040 err = ioctl(pmu_fd, PERF_EVENT_IOC_SET_BPF, prog_fd);
1041 if (CHECK(err, "perf_event_ioc_set_bpf", "err %d errno %d\n",
1042 err, errno))
1043 goto disable_pmu;
1044
1045 /* find map fds */
1046 control_map_fd = bpf_find_map(__func__, obj, "control_map");
1047 if (CHECK(control_map_fd < 0, "bpf_find_map control_map",
1048 "err %d errno %d\n", err, errno))
1049 goto disable_pmu;
1050
1051 stackid_hmap_fd = bpf_find_map(__func__, obj, "stackid_hmap");
1052 if (CHECK(stackid_hmap_fd < 0, "bpf_find_map stackid_hmap",
1053 "err %d errno %d\n", err, errno))
1054 goto disable_pmu;
1055
1056 stackmap_fd = bpf_find_map(__func__, obj, "stackmap");
1057 if (CHECK(stackmap_fd < 0, "bpf_find_map stackmap", "err %d errno %d\n",
1058 err, errno))
1059 goto disable_pmu;
1060
1061 assert(system("dd if=/dev/urandom of=/dev/zero count=4 2> /dev/null")
1062 == 0);
1063 assert(system("./urandom_read if=/dev/urandom of=/dev/zero count=4 2> /dev/null") == 0);
1064 /* disable stack trace collection */
1065 key = 0;
1066 val = 1;
1067 bpf_map_update_elem(control_map_fd, &key, &val, 0);
1068
1069 /* for every element in stackid_hmap, we can find a corresponding one
1070 * in stackmap, and vise versa.
1071 */
1072 err = compare_map_keys(stackid_hmap_fd, stackmap_fd);
1073 if (CHECK(err, "compare_map_keys stackid_hmap vs. stackmap",
1074 "err %d errno %d\n", err, errno))
1075 goto disable_pmu;
1076
1077 err = compare_map_keys(stackmap_fd, stackid_hmap_fd);
1078 if (CHECK(err, "compare_map_keys stackmap vs. stackid_hmap",
1079 "err %d errno %d\n", err, errno))
1080 goto disable_pmu;
1081
1082 err = extract_build_id(buf, 256);
1083
1084 if (CHECK(err, "get build_id with readelf",
1085 "err %d errno %d\n", err, errno))
1086 goto disable_pmu;
1087
1088 err = bpf_map_get_next_key(stackmap_fd, NULL, &key);
1089 if (CHECK(err, "get_next_key from stackmap",
1090 "err %d, errno %d\n", err, errno))
1091 goto disable_pmu;
1092
1093 do {
1094 char build_id[64];
1095
1096 err = bpf_map_lookup_elem(stackmap_fd, &key, id_offs);
1097 if (CHECK(err, "lookup_elem from stackmap",
1098 "err %d, errno %d\n", err, errno))
1099 goto disable_pmu;
1100 for (i = 0; i < PERF_MAX_STACK_DEPTH; ++i)
1101 if (id_offs[i].status == BPF_STACK_BUILD_ID_VALID &&
1102 id_offs[i].offset != 0) {
1103 for (j = 0; j < 20; ++j)
1104 sprintf(build_id + 2 * j, "%02x",
1105 id_offs[i].build_id[j] & 0xff);
1106 if (strstr(buf, build_id) != NULL)
1107 build_id_matches = 1;
1108 }
1109 previous_key = key;
1110 } while (bpf_map_get_next_key(stackmap_fd, &previous_key, &key) == 0);
1111
1112 CHECK(build_id_matches < 1, "build id match",
1113 "Didn't find expected build ID from the map");
1114
1115disable_pmu:
1116 ioctl(pmu_fd, PERF_EVENT_IOC_DISABLE);
1117
1118close_pmu:
1119 close(pmu_fd);
1120
1121close_prog:
1122 bpf_object__close(obj);
1123
1124out:
1125 return;
1126}
1127
1128int main(void)
1129{
972 test_pkt_access(); 1130 test_pkt_access();
973 test_xdp(); 1131 test_xdp();
974 test_l4lb_all(); 1132 test_l4lb_all();
@@ -979,6 +1137,7 @@ int main(void)
979 test_obj_name(); 1137 test_obj_name();
980 test_tp_attach_query(); 1138 test_tp_attach_query();
981 test_stacktrace_map(); 1139 test_stacktrace_map();
1140 test_stacktrace_build_id();
982 1141
983 printf("Summary: %d PASSED, %d FAILED\n", pass_cnt, error_cnt); 1142 printf("Summary: %d PASSED, %d FAILED\n", pass_cnt, error_cnt);
984 return error_cnt ? EXIT_FAILURE : EXIT_SUCCESS; 1143 return error_cnt ? EXIT_FAILURE : EXIT_SUCCESS;
diff --git a/tools/testing/selftests/bpf/test_stacktrace_build_id.c b/tools/testing/selftests/bpf/test_stacktrace_build_id.c
new file mode 100644
index 000000000000..b755bd783ce5
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_stacktrace_build_id.c
@@ -0,0 +1,60 @@
1// SPDX-License-Identifier: GPL-2.0
2// Copyright (c) 2018 Facebook
3
4#include <linux/bpf.h>
5#include "bpf_helpers.h"
6
7#ifndef PERF_MAX_STACK_DEPTH
8#define PERF_MAX_STACK_DEPTH 127
9#endif
10
11struct bpf_map_def SEC("maps") control_map = {
12 .type = BPF_MAP_TYPE_ARRAY,
13 .key_size = sizeof(__u32),
14 .value_size = sizeof(__u32),
15 .max_entries = 1,
16};
17
18struct bpf_map_def SEC("maps") stackid_hmap = {
19 .type = BPF_MAP_TYPE_HASH,
20 .key_size = sizeof(__u32),
21 .value_size = sizeof(__u32),
22 .max_entries = 10000,
23};
24
25struct bpf_map_def SEC("maps") stackmap = {
26 .type = BPF_MAP_TYPE_STACK_TRACE,
27 .key_size = sizeof(__u32),
28 .value_size = sizeof(struct bpf_stack_build_id)
29 * PERF_MAX_STACK_DEPTH,
30 .max_entries = 128,
31 .map_flags = BPF_F_STACK_BUILD_ID,
32};
33
34/* taken from /sys/kernel/debug/tracing/events/random/urandom_read/format */
35struct random_urandom_args {
36 unsigned long long pad;
37 int got_bits;
38 int pool_left;
39 int input_left;
40};
41
42SEC("tracepoint/random/urandom_read")
43int oncpu(struct random_urandom_args *args)
44{
45 __u32 key = 0, val = 0, *value_p;
46
47 value_p = bpf_map_lookup_elem(&control_map, &key);
48 if (value_p && *value_p)
49 return 0; /* skip if non-zero *value_p */
50
51 /* The size of stackmap and stackid_hmap should be the same */
52 key = bpf_get_stackid(args, &stackmap, BPF_F_USER_STACK);
53 if ((int)key >= 0)
54 bpf_map_update_elem(&stackid_hmap, &key, &val, 0);
55
56 return 0;
57}
58
59char _license[] SEC("license") = "GPL";
60__u32 _version SEC("version") = 1; /* ignored by tracepoints, required by libbpf.a */
diff --git a/tools/testing/selftests/bpf/test_tag.c b/tools/testing/selftests/bpf/test_tag.c
index 8b201895c569..6272c784ca2a 100644
--- a/tools/testing/selftests/bpf/test_tag.c
+++ b/tools/testing/selftests/bpf/test_tag.c
@@ -12,7 +12,6 @@
12#include <assert.h> 12#include <assert.h>
13 13
14#include <sys/socket.h> 14#include <sys/socket.h>
15#include <sys/resource.h>
16 15
17#include <linux/filter.h> 16#include <linux/filter.h>
18#include <linux/bpf.h> 17#include <linux/bpf.h>
@@ -21,6 +20,7 @@
21#include <bpf/bpf.h> 20#include <bpf/bpf.h>
22 21
23#include "../../../include/linux/filter.h" 22#include "../../../include/linux/filter.h"
23#include "bpf_rlimit.h"
24 24
25static struct bpf_insn prog[BPF_MAXINSNS]; 25static struct bpf_insn prog[BPF_MAXINSNS];
26 26
@@ -184,11 +184,9 @@ static void do_test(uint32_t *tests, int start_insns, int fd_map,
184 184
185int main(void) 185int main(void)
186{ 186{
187 struct rlimit rinf = { RLIM_INFINITY, RLIM_INFINITY };
188 uint32_t tests = 0; 187 uint32_t tests = 0;
189 int i, fd_map; 188 int i, fd_map;
190 189
191 setrlimit(RLIMIT_MEMLOCK, &rinf);
192 fd_map = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(int), 190 fd_map = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(int),
193 sizeof(int), 1, BPF_F_NO_PREALLOC); 191 sizeof(int), 1, BPF_F_NO_PREALLOC);
194 assert(fd_map > 0); 192 assert(fd_map > 0);
diff --git a/tools/testing/selftests/bpf/test_tcpbpf_user.c b/tools/testing/selftests/bpf/test_tcpbpf_user.c
index 95a370f3d378..84ab5163c828 100644
--- a/tools/testing/selftests/bpf/test_tcpbpf_user.c
+++ b/tools/testing/selftests/bpf/test_tcpbpf_user.c
@@ -11,12 +11,14 @@
11#include <linux/ptrace.h> 11#include <linux/ptrace.h>
12#include <linux/bpf.h> 12#include <linux/bpf.h>
13#include <sys/ioctl.h> 13#include <sys/ioctl.h>
14#include <sys/time.h>
14#include <sys/types.h> 15#include <sys/types.h>
15#include <sys/stat.h> 16#include <sys/stat.h>
16#include <fcntl.h> 17#include <fcntl.h>
17#include <bpf/bpf.h> 18#include <bpf/bpf.h>
18#include <bpf/libbpf.h> 19#include <bpf/libbpf.h>
19#include "bpf_util.h" 20#include "bpf_util.h"
21#include "bpf_rlimit.h"
20#include <linux/perf_event.h> 22#include <linux/perf_event.h>
21#include "test_tcpbpf.h" 23#include "test_tcpbpf.h"
22 24
diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c
index 437c0b1c9d21..3e7718b1a9ae 100644
--- a/tools/testing/selftests/bpf/test_verifier.c
+++ b/tools/testing/selftests/bpf/test_verifier.c
@@ -24,7 +24,6 @@
24#include <limits.h> 24#include <limits.h>
25 25
26#include <sys/capability.h> 26#include <sys/capability.h>
27#include <sys/resource.h>
28 27
29#include <linux/unistd.h> 28#include <linux/unistd.h>
30#include <linux/filter.h> 29#include <linux/filter.h>
@@ -41,7 +40,7 @@
41# define CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS 1 40# define CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS 1
42# endif 41# endif
43#endif 42#endif
44 43#include "bpf_rlimit.h"
45#include "../../../include/linux/filter.h" 44#include "../../../include/linux/filter.h"
46 45
47#ifndef ARRAY_SIZE 46#ifndef ARRAY_SIZE
@@ -57,6 +56,9 @@
57#define F_NEEDS_EFFICIENT_UNALIGNED_ACCESS (1 << 0) 56#define F_NEEDS_EFFICIENT_UNALIGNED_ACCESS (1 << 0)
58#define F_LOAD_WITH_STRICT_ALIGNMENT (1 << 1) 57#define F_LOAD_WITH_STRICT_ALIGNMENT (1 << 1)
59 58
59#define UNPRIV_SYSCTL "kernel/unprivileged_bpf_disabled"
60static bool unpriv_disabled = false;
61
60struct bpf_test { 62struct bpf_test {
61 const char *descr; 63 const char *descr;
62 struct bpf_insn insns[MAX_INSNS]; 64 struct bpf_insn insns[MAX_INSNS];
@@ -1595,6 +1597,60 @@ static struct bpf_test tests[] = {
1595 .prog_type = BPF_PROG_TYPE_SK_SKB, 1597 .prog_type = BPF_PROG_TYPE_SK_SKB,
1596 }, 1598 },
1597 { 1599 {
1600 "direct packet read for SK_MSG",
1601 .insns = {
1602 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1,
1603 offsetof(struct sk_msg_md, data)),
1604 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1,
1605 offsetof(struct sk_msg_md, data_end)),
1606 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1607 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1608 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1609 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_2, 0),
1610 BPF_MOV64_IMM(BPF_REG_0, 0),
1611 BPF_EXIT_INSN(),
1612 },
1613 .result = ACCEPT,
1614 .prog_type = BPF_PROG_TYPE_SK_MSG,
1615 },
1616 {
1617 "direct packet write for SK_MSG",
1618 .insns = {
1619 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1,
1620 offsetof(struct sk_msg_md, data)),
1621 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1,
1622 offsetof(struct sk_msg_md, data_end)),
1623 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1624 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1625 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
1626 BPF_STX_MEM(BPF_B, BPF_REG_2, BPF_REG_2, 0),
1627 BPF_MOV64_IMM(BPF_REG_0, 0),
1628 BPF_EXIT_INSN(),
1629 },
1630 .result = ACCEPT,
1631 .prog_type = BPF_PROG_TYPE_SK_MSG,
1632 },
1633 {
1634 "overlapping checks for direct packet access SK_MSG",
1635 .insns = {
1636 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1,
1637 offsetof(struct sk_msg_md, data)),
1638 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1,
1639 offsetof(struct sk_msg_md, data_end)),
1640 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
1641 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
1642 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 4),
1643 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
1644 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
1645 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
1646 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_2, 6),
1647 BPF_MOV64_IMM(BPF_REG_0, 0),
1648 BPF_EXIT_INSN(),
1649 },
1650 .result = ACCEPT,
1651 .prog_type = BPF_PROG_TYPE_SK_MSG,
1652 },
1653 {
1598 "check skb->mark is not writeable by sockets", 1654 "check skb->mark is not writeable by sockets",
1599 .insns = { 1655 .insns = {
1600 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1, 1656 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
@@ -2587,17 +2643,74 @@ static struct bpf_test tests[] = {
2587 .result = ACCEPT, 2643 .result = ACCEPT,
2588 }, 2644 },
2589 { 2645 {
2646 "runtime/jit: tail_call within bounds, prog once",
2647 .insns = {
2648 BPF_MOV64_IMM(BPF_REG_3, 0),
2649 BPF_LD_MAP_FD(BPF_REG_2, 0),
2650 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2651 BPF_FUNC_tail_call),
2652 BPF_MOV64_IMM(BPF_REG_0, 1),
2653 BPF_EXIT_INSN(),
2654 },
2655 .fixup_prog = { 1 },
2656 .result = ACCEPT,
2657 .retval = 42,
2658 },
2659 {
2660 "runtime/jit: tail_call within bounds, prog loop",
2661 .insns = {
2662 BPF_MOV64_IMM(BPF_REG_3, 1),
2663 BPF_LD_MAP_FD(BPF_REG_2, 0),
2664 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2665 BPF_FUNC_tail_call),
2666 BPF_MOV64_IMM(BPF_REG_0, 1),
2667 BPF_EXIT_INSN(),
2668 },
2669 .fixup_prog = { 1 },
2670 .result = ACCEPT,
2671 .retval = 41,
2672 },
2673 {
2674 "runtime/jit: tail_call within bounds, no prog",
2675 .insns = {
2676 BPF_MOV64_IMM(BPF_REG_3, 2),
2677 BPF_LD_MAP_FD(BPF_REG_2, 0),
2678 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2679 BPF_FUNC_tail_call),
2680 BPF_MOV64_IMM(BPF_REG_0, 1),
2681 BPF_EXIT_INSN(),
2682 },
2683 .fixup_prog = { 1 },
2684 .result = ACCEPT,
2685 .retval = 1,
2686 },
2687 {
2688 "runtime/jit: tail_call out of bounds",
2689 .insns = {
2690 BPF_MOV64_IMM(BPF_REG_3, 256),
2691 BPF_LD_MAP_FD(BPF_REG_2, 0),
2692 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2693 BPF_FUNC_tail_call),
2694 BPF_MOV64_IMM(BPF_REG_0, 2),
2695 BPF_EXIT_INSN(),
2696 },
2697 .fixup_prog = { 1 },
2698 .result = ACCEPT,
2699 .retval = 2,
2700 },
2701 {
2590 "runtime/jit: pass negative index to tail_call", 2702 "runtime/jit: pass negative index to tail_call",
2591 .insns = { 2703 .insns = {
2592 BPF_MOV64_IMM(BPF_REG_3, -1), 2704 BPF_MOV64_IMM(BPF_REG_3, -1),
2593 BPF_LD_MAP_FD(BPF_REG_2, 0), 2705 BPF_LD_MAP_FD(BPF_REG_2, 0),
2594 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 2706 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2595 BPF_FUNC_tail_call), 2707 BPF_FUNC_tail_call),
2596 BPF_MOV64_IMM(BPF_REG_0, 0), 2708 BPF_MOV64_IMM(BPF_REG_0, 2),
2597 BPF_EXIT_INSN(), 2709 BPF_EXIT_INSN(),
2598 }, 2710 },
2599 .fixup_prog = { 1 }, 2711 .fixup_prog = { 1 },
2600 .result = ACCEPT, 2712 .result = ACCEPT,
2713 .retval = 2,
2601 }, 2714 },
2602 { 2715 {
2603 "runtime/jit: pass > 32bit index to tail_call", 2716 "runtime/jit: pass > 32bit index to tail_call",
@@ -2606,11 +2719,12 @@ static struct bpf_test tests[] = {
2606 BPF_LD_MAP_FD(BPF_REG_2, 0), 2719 BPF_LD_MAP_FD(BPF_REG_2, 0),
2607 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 2720 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2608 BPF_FUNC_tail_call), 2721 BPF_FUNC_tail_call),
2609 BPF_MOV64_IMM(BPF_REG_0, 0), 2722 BPF_MOV64_IMM(BPF_REG_0, 2),
2610 BPF_EXIT_INSN(), 2723 BPF_EXIT_INSN(),
2611 }, 2724 },
2612 .fixup_prog = { 2 }, 2725 .fixup_prog = { 2 },
2613 .result = ACCEPT, 2726 .result = ACCEPT,
2727 .retval = 42,
2614 }, 2728 },
2615 { 2729 {
2616 "stack pointer arithmetic", 2730 "stack pointer arithmetic",
@@ -11164,6 +11278,94 @@ static struct bpf_test tests[] = {
11164 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 11278 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
11165 }, 11279 },
11166 { 11280 {
11281 "jit: lsh, rsh, arsh by 1",
11282 .insns = {
11283 BPF_MOV64_IMM(BPF_REG_0, 1),
11284 BPF_MOV64_IMM(BPF_REG_1, 0xff),
11285 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 1),
11286 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 1),
11287 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0x3fc, 1),
11288 BPF_EXIT_INSN(),
11289 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 1),
11290 BPF_ALU32_IMM(BPF_RSH, BPF_REG_1, 1),
11291 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0xff, 1),
11292 BPF_EXIT_INSN(),
11293 BPF_ALU64_IMM(BPF_ARSH, BPF_REG_1, 1),
11294 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0x7f, 1),
11295 BPF_EXIT_INSN(),
11296 BPF_MOV64_IMM(BPF_REG_0, 2),
11297 BPF_EXIT_INSN(),
11298 },
11299 .result = ACCEPT,
11300 .retval = 2,
11301 },
11302 {
11303 "jit: mov32 for ldimm64, 1",
11304 .insns = {
11305 BPF_MOV64_IMM(BPF_REG_0, 2),
11306 BPF_LD_IMM64(BPF_REG_1, 0xfeffffffffffffffULL),
11307 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 32),
11308 BPF_LD_IMM64(BPF_REG_2, 0xfeffffffULL),
11309 BPF_JMP_REG(BPF_JEQ, BPF_REG_1, BPF_REG_2, 1),
11310 BPF_MOV64_IMM(BPF_REG_0, 1),
11311 BPF_EXIT_INSN(),
11312 },
11313 .result = ACCEPT,
11314 .retval = 2,
11315 },
11316 {
11317 "jit: mov32 for ldimm64, 2",
11318 .insns = {
11319 BPF_MOV64_IMM(BPF_REG_0, 1),
11320 BPF_LD_IMM64(BPF_REG_1, 0x1ffffffffULL),
11321 BPF_LD_IMM64(BPF_REG_2, 0xffffffffULL),
11322 BPF_JMP_REG(BPF_JEQ, BPF_REG_1, BPF_REG_2, 1),
11323 BPF_MOV64_IMM(BPF_REG_0, 2),
11324 BPF_EXIT_INSN(),
11325 },
11326 .result = ACCEPT,
11327 .retval = 2,
11328 },
11329 {
11330 "jit: various mul tests",
11331 .insns = {
11332 BPF_LD_IMM64(BPF_REG_2, 0xeeff0d413122ULL),
11333 BPF_LD_IMM64(BPF_REG_0, 0xfefefeULL),
11334 BPF_LD_IMM64(BPF_REG_1, 0xefefefULL),
11335 BPF_ALU64_REG(BPF_MUL, BPF_REG_0, BPF_REG_1),
11336 BPF_JMP_REG(BPF_JEQ, BPF_REG_0, BPF_REG_2, 2),
11337 BPF_MOV64_IMM(BPF_REG_0, 1),
11338 BPF_EXIT_INSN(),
11339 BPF_LD_IMM64(BPF_REG_3, 0xfefefeULL),
11340 BPF_ALU64_REG(BPF_MUL, BPF_REG_3, BPF_REG_1),
11341 BPF_JMP_REG(BPF_JEQ, BPF_REG_3, BPF_REG_2, 2),
11342 BPF_MOV64_IMM(BPF_REG_0, 1),
11343 BPF_EXIT_INSN(),
11344 BPF_MOV32_REG(BPF_REG_2, BPF_REG_2),
11345 BPF_LD_IMM64(BPF_REG_0, 0xfefefeULL),
11346 BPF_ALU32_REG(BPF_MUL, BPF_REG_0, BPF_REG_1),
11347 BPF_JMP_REG(BPF_JEQ, BPF_REG_0, BPF_REG_2, 2),
11348 BPF_MOV64_IMM(BPF_REG_0, 1),
11349 BPF_EXIT_INSN(),
11350 BPF_LD_IMM64(BPF_REG_3, 0xfefefeULL),
11351 BPF_ALU32_REG(BPF_MUL, BPF_REG_3, BPF_REG_1),
11352 BPF_JMP_REG(BPF_JEQ, BPF_REG_3, BPF_REG_2, 2),
11353 BPF_MOV64_IMM(BPF_REG_0, 1),
11354 BPF_EXIT_INSN(),
11355 BPF_LD_IMM64(BPF_REG_0, 0x952a7bbcULL),
11356 BPF_LD_IMM64(BPF_REG_1, 0xfefefeULL),
11357 BPF_LD_IMM64(BPF_REG_2, 0xeeff0d413122ULL),
11358 BPF_ALU32_REG(BPF_MUL, BPF_REG_2, BPF_REG_1),
11359 BPF_JMP_REG(BPF_JEQ, BPF_REG_2, BPF_REG_0, 2),
11360 BPF_MOV64_IMM(BPF_REG_0, 1),
11361 BPF_EXIT_INSN(),
11362 BPF_MOV64_IMM(BPF_REG_0, 2),
11363 BPF_EXIT_INSN(),
11364 },
11365 .result = ACCEPT,
11366 .retval = 2,
11367 },
11368 {
11167 "xadd/w check unaligned stack", 11369 "xadd/w check unaligned stack",
11168 .insns = { 11370 .insns = {
11169 BPF_MOV64_IMM(BPF_REG_0, 1), 11371 BPF_MOV64_IMM(BPF_REG_0, 1),
@@ -11245,16 +11447,61 @@ static int create_map(uint32_t size_value, uint32_t max_elem)
11245 return fd; 11447 return fd;
11246} 11448}
11247 11449
11450static int create_prog_dummy1(void)
11451{
11452 struct bpf_insn prog[] = {
11453 BPF_MOV64_IMM(BPF_REG_0, 42),
11454 BPF_EXIT_INSN(),
11455 };
11456
11457 return bpf_load_program(BPF_PROG_TYPE_SOCKET_FILTER, prog,
11458 ARRAY_SIZE(prog), "GPL", 0, NULL, 0);
11459}
11460
11461static int create_prog_dummy2(int mfd, int idx)
11462{
11463 struct bpf_insn prog[] = {
11464 BPF_MOV64_IMM(BPF_REG_3, idx),
11465 BPF_LD_MAP_FD(BPF_REG_2, mfd),
11466 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
11467 BPF_FUNC_tail_call),
11468 BPF_MOV64_IMM(BPF_REG_0, 41),
11469 BPF_EXIT_INSN(),
11470 };
11471
11472 return bpf_load_program(BPF_PROG_TYPE_SOCKET_FILTER, prog,
11473 ARRAY_SIZE(prog), "GPL", 0, NULL, 0);
11474}
11475
11248static int create_prog_array(void) 11476static int create_prog_array(void)
11249{ 11477{
11250 int fd; 11478 int p1key = 0, p2key = 1;
11479 int mfd, p1fd, p2fd;
11251 11480
11252 fd = bpf_create_map(BPF_MAP_TYPE_PROG_ARRAY, sizeof(int), 11481 mfd = bpf_create_map(BPF_MAP_TYPE_PROG_ARRAY, sizeof(int),
11253 sizeof(int), 4, 0); 11482 sizeof(int), 4, 0);
11254 if (fd < 0) 11483 if (mfd < 0) {
11255 printf("Failed to create prog array '%s'!\n", strerror(errno)); 11484 printf("Failed to create prog array '%s'!\n", strerror(errno));
11485 return -1;
11486 }
11256 11487
11257 return fd; 11488 p1fd = create_prog_dummy1();
11489 p2fd = create_prog_dummy2(mfd, p2key);
11490 if (p1fd < 0 || p2fd < 0)
11491 goto out;
11492 if (bpf_map_update_elem(mfd, &p1key, &p1fd, BPF_ANY) < 0)
11493 goto out;
11494 if (bpf_map_update_elem(mfd, &p2key, &p2fd, BPF_ANY) < 0)
11495 goto out;
11496 close(p2fd);
11497 close(p1fd);
11498
11499 return mfd;
11500out:
11501 close(p2fd);
11502 close(p1fd);
11503 close(mfd);
11504 return -1;
11258} 11505}
11259 11506
11260static int create_map_in_map(void) 11507static int create_map_in_map(void)
@@ -11375,7 +11622,8 @@ static void do_test_single(struct bpf_test *test, bool unpriv,
11375 goto fail_log; 11622 goto fail_log;
11376 } 11623 }
11377 if (!strstr(bpf_vlog, expected_err) && !reject_from_alignment) { 11624 if (!strstr(bpf_vlog, expected_err) && !reject_from_alignment) {
11378 printf("FAIL\nUnexpected error message!\n"); 11625 printf("FAIL\nUnexpected error message!\n\tEXP: %s\n\tRES: %s\n",
11626 expected_err, bpf_vlog);
11379 goto fail_log; 11627 goto fail_log;
11380 } 11628 }
11381 } 11629 }
@@ -11459,9 +11707,20 @@ out:
11459 return ret; 11707 return ret;
11460} 11708}
11461 11709
11710static void get_unpriv_disabled()
11711{
11712 char buf[2];
11713 FILE *fd;
11714
11715 fd = fopen("/proc/sys/"UNPRIV_SYSCTL, "r");
11716 if (fgets(buf, 2, fd) == buf && atoi(buf))
11717 unpriv_disabled = true;
11718 fclose(fd);
11719}
11720
11462static int do_test(bool unpriv, unsigned int from, unsigned int to) 11721static int do_test(bool unpriv, unsigned int from, unsigned int to)
11463{ 11722{
11464 int i, passes = 0, errors = 0; 11723 int i, passes = 0, errors = 0, skips = 0;
11465 11724
11466 for (i = from; i < to; i++) { 11725 for (i = from; i < to; i++) {
11467 struct bpf_test *test = &tests[i]; 11726 struct bpf_test *test = &tests[i];
@@ -11469,7 +11728,10 @@ static int do_test(bool unpriv, unsigned int from, unsigned int to)
11469 /* Program types that are not supported by non-root we 11728 /* Program types that are not supported by non-root we
11470 * skip right away. 11729 * skip right away.
11471 */ 11730 */
11472 if (!test->prog_type) { 11731 if (!test->prog_type && unpriv_disabled) {
11732 printf("#%d/u %s SKIP\n", i, test->descr);
11733 skips++;
11734 } else if (!test->prog_type) {
11473 if (!unpriv) 11735 if (!unpriv)
11474 set_admin(false); 11736 set_admin(false);
11475 printf("#%d/u %s ", i, test->descr); 11737 printf("#%d/u %s ", i, test->descr);
@@ -11478,20 +11740,22 @@ static int do_test(bool unpriv, unsigned int from, unsigned int to)
11478 set_admin(true); 11740 set_admin(true);
11479 } 11741 }
11480 11742
11481 if (!unpriv) { 11743 if (unpriv) {
11744 printf("#%d/p %s SKIP\n", i, test->descr);
11745 skips++;
11746 } else {
11482 printf("#%d/p %s ", i, test->descr); 11747 printf("#%d/p %s ", i, test->descr);
11483 do_test_single(test, false, &passes, &errors); 11748 do_test_single(test, false, &passes, &errors);
11484 } 11749 }
11485 } 11750 }
11486 11751
11487 printf("Summary: %d PASSED, %d FAILED\n", passes, errors); 11752 printf("Summary: %d PASSED, %d SKIPPED, %d FAILED\n", passes,
11753 skips, errors);
11488 return errors ? EXIT_FAILURE : EXIT_SUCCESS; 11754 return errors ? EXIT_FAILURE : EXIT_SUCCESS;
11489} 11755}
11490 11756
11491int main(int argc, char **argv) 11757int main(int argc, char **argv)
11492{ 11758{
11493 struct rlimit rinf = { RLIM_INFINITY, RLIM_INFINITY };
11494 struct rlimit rlim = { 1 << 20, 1 << 20 };
11495 unsigned int from = 0, to = ARRAY_SIZE(tests); 11759 unsigned int from = 0, to = ARRAY_SIZE(tests);
11496 bool unpriv = !is_admin(); 11760 bool unpriv = !is_admin();
11497 11761
@@ -11512,6 +11776,12 @@ int main(int argc, char **argv)
11512 } 11776 }
11513 } 11777 }
11514 11778
11515 setrlimit(RLIMIT_MEMLOCK, unpriv ? &rlim : &rinf); 11779 get_unpriv_disabled();
11780 if (unpriv && unpriv_disabled) {
11781 printf("Cannot run as unprivileged user with sysctl %s.\n",
11782 UNPRIV_SYSCTL);
11783 return EXIT_FAILURE;
11784 }
11785
11516 return do_test(unpriv, from, to); 11786 return do_test(unpriv, from, to);
11517} 11787}
diff --git a/tools/testing/selftests/bpf/test_verifier_log.c b/tools/testing/selftests/bpf/test_verifier_log.c
index e9626cf5607a..8d6918c3b4a2 100644
--- a/tools/testing/selftests/bpf/test_verifier_log.c
+++ b/tools/testing/selftests/bpf/test_verifier_log.c
@@ -4,7 +4,6 @@
4#include <string.h> 4#include <string.h>
5#include <unistd.h> 5#include <unistd.h>
6#include <sys/time.h> 6#include <sys/time.h>
7#include <sys/resource.h>
8 7
9#include <linux/bpf.h> 8#include <linux/bpf.h>
10#include <linux/filter.h> 9#include <linux/filter.h>
@@ -12,6 +11,8 @@
12 11
13#include <bpf/bpf.h> 12#include <bpf/bpf.h>
14 13
14#include "bpf_rlimit.h"
15
15#define LOG_SIZE (1 << 20) 16#define LOG_SIZE (1 << 20)
16 17
17#define err(str...) printf("ERROR: " str) 18#define err(str...) printf("ERROR: " str)
@@ -133,16 +134,11 @@ static void test_log_bad(char *log, size_t log_len, int log_level)
133 134
134int main(int argc, char **argv) 135int main(int argc, char **argv)
135{ 136{
136 struct rlimit limit = { RLIM_INFINITY, RLIM_INFINITY };
137 char full_log[LOG_SIZE]; 137 char full_log[LOG_SIZE];
138 char log[LOG_SIZE]; 138 char log[LOG_SIZE];
139 size_t want_len; 139 size_t want_len;
140 int i; 140 int i;
141 141
142 /* allow unlimited locked memory to have more consistent error code */
143 if (setrlimit(RLIMIT_MEMLOCK, &limit) < 0)
144 perror("Unable to lift memlock rlimit");
145
146 memset(log, 1, LOG_SIZE); 142 memset(log, 1, LOG_SIZE);
147 143
148 /* Test incorrect attr */ 144 /* Test incorrect attr */
diff --git a/tools/testing/selftests/bpf/urandom_read.c b/tools/testing/selftests/bpf/urandom_read.c
new file mode 100644
index 000000000000..4acfdebf36fa
--- /dev/null
+++ b/tools/testing/selftests/bpf/urandom_read.c
@@ -0,0 +1,22 @@
1#include <stdio.h>
2#include <unistd.h>
3#include <sys/types.h>
4#include <sys/stat.h>
5#include <fcntl.h>
6#include <stdlib.h>
7
8#define BUF_SIZE 256
9int main(void)
10{
11 int fd = open("/dev/urandom", O_RDONLY);
12 int i;
13 char buf[BUF_SIZE];
14
15 if (fd < 0)
16 return 1;
17 for (i = 0; i < 4; ++i)
18 read(fd, buf, BUF_SIZE);
19
20 close(fd);
21 return 0;
22}
diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile
index d7c30d366935..785fc18a16b4 100644
--- a/tools/testing/selftests/net/Makefile
+++ b/tools/testing/selftests/net/Makefile
@@ -5,7 +5,7 @@ CFLAGS = -Wall -Wl,--no-as-needed -O2 -g
5CFLAGS += -I../../../../usr/include/ 5CFLAGS += -I../../../../usr/include/
6 6
7TEST_PROGS := run_netsocktests run_afpackettests test_bpf.sh netdevice.sh rtnetlink.sh 7TEST_PROGS := run_netsocktests run_afpackettests test_bpf.sh netdevice.sh rtnetlink.sh
8TEST_PROGS += fib_tests.sh 8TEST_PROGS += fib_tests.sh fib-onlink-tests.sh pmtu.sh
9TEST_GEN_FILES = socket 9TEST_GEN_FILES = socket
10TEST_GEN_FILES += psock_fanout psock_tpacket msg_zerocopy 10TEST_GEN_FILES += psock_fanout psock_tpacket msg_zerocopy
11TEST_GEN_PROGS = reuseport_bpf reuseport_bpf_cpu reuseport_bpf_numa 11TEST_GEN_PROGS = reuseport_bpf reuseport_bpf_cpu reuseport_bpf_numa
diff --git a/tools/testing/selftests/net/config b/tools/testing/selftests/net/config
index 7177bea1fdfa..6a75a3ea44ad 100644
--- a/tools/testing/selftests/net/config
+++ b/tools/testing/selftests/net/config
@@ -2,3 +2,8 @@ CONFIG_USER_NS=y
2CONFIG_BPF_SYSCALL=y 2CONFIG_BPF_SYSCALL=y
3CONFIG_TEST_BPF=m 3CONFIG_TEST_BPF=m
4CONFIG_NUMA=y 4CONFIG_NUMA=y
5CONFIG_NET_VRF=y
6CONFIG_NET_L3_MASTER_DEV=y
7CONFIG_IPV6=y
8CONFIG_IPV6_MULTIPLE_TABLES=y
9CONFIG_VETH=y
diff --git a/tools/testing/selftests/net/fib-onlink-tests.sh b/tools/testing/selftests/net/fib-onlink-tests.sh
new file mode 100755
index 000000000000..3991ad1a368d
--- /dev/null
+++ b/tools/testing/selftests/net/fib-onlink-tests.sh
@@ -0,0 +1,467 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4# IPv4 and IPv6 onlink tests
5
6PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no}
7
8# Network interfaces
9# - odd in current namespace; even in peer ns
10declare -A NETIFS
11# default VRF
12NETIFS[p1]=veth1
13NETIFS[p2]=veth2
14NETIFS[p3]=veth3
15NETIFS[p4]=veth4
16# VRF
17NETIFS[p5]=veth5
18NETIFS[p6]=veth6
19NETIFS[p7]=veth7
20NETIFS[p8]=veth8
21
22# /24 network
23declare -A V4ADDRS
24V4ADDRS[p1]=169.254.1.1
25V4ADDRS[p2]=169.254.1.2
26V4ADDRS[p3]=169.254.3.1
27V4ADDRS[p4]=169.254.3.2
28V4ADDRS[p5]=169.254.5.1
29V4ADDRS[p6]=169.254.5.2
30V4ADDRS[p7]=169.254.7.1
31V4ADDRS[p8]=169.254.7.2
32
33# /64 network
34declare -A V6ADDRS
35V6ADDRS[p1]=2001:db8:101::1
36V6ADDRS[p2]=2001:db8:101::2
37V6ADDRS[p3]=2001:db8:301::1
38V6ADDRS[p4]=2001:db8:301::2
39V6ADDRS[p5]=2001:db8:501::1
40V6ADDRS[p6]=2001:db8:501::2
41V6ADDRS[p7]=2001:db8:701::1
42V6ADDRS[p8]=2001:db8:701::2
43
44# Test networks:
45# [1] = default table
46# [2] = VRF
47#
48# /32 host routes
49declare -A TEST_NET4
50TEST_NET4[1]=169.254.101
51TEST_NET4[2]=169.254.102
52# /128 host routes
53declare -A TEST_NET6
54TEST_NET6[1]=2001:db8:101
55TEST_NET6[2]=2001:db8:102
56
57# connected gateway
58CONGW[1]=169.254.1.254
59CONGW[2]=169.254.3.254
60CONGW[3]=169.254.5.254
61
62# recursive gateway
63RECGW4[1]=169.254.11.254
64RECGW4[2]=169.254.12.254
65RECGW6[1]=2001:db8:11::64
66RECGW6[2]=2001:db8:12::64
67
68# for v4 mapped to v6
69declare -A TEST_NET4IN6IN6
70TEST_NET4IN6[1]=10.1.1.254
71TEST_NET4IN6[2]=10.2.1.254
72
73# mcast address
74MCAST6=ff02::1
75
76
77PEER_NS=bart
78PEER_CMD="ip netns exec ${PEER_NS}"
79VRF=lisa
80VRF_TABLE=1101
81PBR_TABLE=101
82
83################################################################################
84# utilities
85
86log_test()
87{
88 local rc=$1
89 local expected=$2
90 local msg="$3"
91
92 if [ ${rc} -eq ${expected} ]; then
93 nsuccess=$((nsuccess+1))
94 printf "\n TEST: %-50s [ OK ]\n" "${msg}"
95 else
96 nfail=$((nfail+1))
97 printf "\n TEST: %-50s [FAIL]\n" "${msg}"
98 if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
99 echo
100 echo "hit enter to continue, 'q' to quit"
101 read a
102 [ "$a" = "q" ] && exit 1
103 fi
104 fi
105}
106
107log_section()
108{
109 echo
110 echo "######################################################################"
111 echo "TEST SECTION: $*"
112 echo "######################################################################"
113}
114
115log_subsection()
116{
117 echo
118 echo "#########################################"
119 echo "TEST SUBSECTION: $*"
120}
121
122run_cmd()
123{
124 echo
125 echo "COMMAND: $*"
126 eval $*
127}
128
129get_linklocal()
130{
131 local dev=$1
132 local pfx
133 local addr
134
135 addr=$(${pfx} ip -6 -br addr show dev ${dev} | \
136 awk '{
137 for (i = 3; i <= NF; ++i) {
138 if ($i ~ /^fe80/)
139 print $i
140 }
141 }'
142 )
143 addr=${addr/\/*}
144
145 [ -z "$addr" ] && return 1
146
147 echo $addr
148
149 return 0
150}
151
152################################################################################
153#
154
155setup()
156{
157 echo
158 echo "########################################"
159 echo "Configuring interfaces"
160
161 set -e
162
163 # create namespace
164 ip netns add ${PEER_NS}
165 ip -netns ${PEER_NS} li set lo up
166
167 # add vrf table
168 ip li add ${VRF} type vrf table ${VRF_TABLE}
169 ip li set ${VRF} up
170 ip ro add table ${VRF_TABLE} unreachable default
171 ip -6 ro add table ${VRF_TABLE} unreachable default
172
173 # create test interfaces
174 ip li add ${NETIFS[p1]} type veth peer name ${NETIFS[p2]}
175 ip li add ${NETIFS[p3]} type veth peer name ${NETIFS[p4]}
176 ip li add ${NETIFS[p5]} type veth peer name ${NETIFS[p6]}
177 ip li add ${NETIFS[p7]} type veth peer name ${NETIFS[p8]}
178
179 # enslave vrf interfaces
180 for n in 5 7; do
181 ip li set ${NETIFS[p${n}]} vrf ${VRF}
182 done
183
184 # add addresses
185 for n in 1 3 5 7; do
186 ip li set ${NETIFS[p${n}]} up
187 ip addr add ${V4ADDRS[p${n}]}/24 dev ${NETIFS[p${n}]}
188 ip addr add ${V6ADDRS[p${n}]}/64 dev ${NETIFS[p${n}]}
189 done
190
191 # move peer interfaces to namespace and add addresses
192 for n in 2 4 6 8; do
193 ip li set ${NETIFS[p${n}]} netns ${PEER_NS} up
194 ip -netns ${PEER_NS} addr add ${V4ADDRS[p${n}]}/24 dev ${NETIFS[p${n}]}
195 ip -netns ${PEER_NS} addr add ${V6ADDRS[p${n}]}/64 dev ${NETIFS[p${n}]}
196 done
197
198 set +e
199
200 # let DAD complete - assume default of 1 probe
201 sleep 1
202}
203
204cleanup()
205{
206 # make sure we start from a clean slate
207 ip netns del ${PEER_NS} 2>/dev/null
208 for n in 1 3 5 7; do
209 ip link del ${NETIFS[p${n}]} 2>/dev/null
210 done
211 ip link del ${VRF} 2>/dev/null
212 ip ro flush table ${VRF_TABLE}
213 ip -6 ro flush table ${VRF_TABLE}
214}
215
216################################################################################
217# IPv4 tests
218#
219
220run_ip()
221{
222 local table="$1"
223 local prefix="$2"
224 local gw="$3"
225 local dev="$4"
226 local exp_rc="$5"
227 local desc="$6"
228
229 # dev arg may be empty
230 [ -n "${dev}" ] && dev="dev ${dev}"
231
232 run_cmd ip ro add table "${table}" "${prefix}"/32 via "${gw}" "${dev}" onlink
233 log_test $? ${exp_rc} "${desc}"
234}
235
236run_ip_mpath()
237{
238 local table="$1"
239 local prefix="$2"
240 local nh1="$3"
241 local nh2="$4"
242 local exp_rc="$5"
243 local desc="$6"
244
245 # dev arg may be empty
246 [ -n "${dev}" ] && dev="dev ${dev}"
247
248 run_cmd ip ro add table "${table}" "${prefix}"/32 \
249 nexthop via ${nh1} nexthop via ${nh2}
250 log_test $? ${exp_rc} "${desc}"
251}
252
253valid_onlink_ipv4()
254{
255 # - unicast connected, unicast recursive
256 #
257 log_subsection "default VRF - main table"
258
259 run_ip 254 ${TEST_NET4[1]}.1 ${CONGW[1]} ${NETIFS[p1]} 0 "unicast connected"
260 run_ip 254 ${TEST_NET4[1]}.2 ${RECGW4[1]} ${NETIFS[p1]} 0 "unicast recursive"
261
262 log_subsection "VRF ${VRF}"
263
264 run_ip ${VRF_TABLE} ${TEST_NET4[2]}.1 ${CONGW[3]} ${NETIFS[p5]} 0 "unicast connected"
265 run_ip ${VRF_TABLE} ${TEST_NET4[2]}.2 ${RECGW4[2]} ${NETIFS[p5]} 0 "unicast recursive"
266
267 log_subsection "VRF device, PBR table"
268
269 run_ip ${PBR_TABLE} ${TEST_NET4[2]}.3 ${CONGW[3]} ${NETIFS[p5]} 0 "unicast connected"
270 run_ip ${PBR_TABLE} ${TEST_NET4[2]}.4 ${RECGW4[2]} ${NETIFS[p5]} 0 "unicast recursive"
271
272 # multipath version
273 #
274 log_subsection "default VRF - main table - multipath"
275
276 run_ip_mpath 254 ${TEST_NET4[1]}.5 \
277 "${CONGW[1]} dev ${NETIFS[p1]} onlink" \
278 "${CONGW[2]} dev ${NETIFS[p3]} onlink" \
279 0 "unicast connected - multipath"
280
281 run_ip_mpath 254 ${TEST_NET4[1]}.6 \
282 "${RECGW4[1]} dev ${NETIFS[p1]} onlink" \
283 "${RECGW4[2]} dev ${NETIFS[p3]} onlink" \
284 0 "unicast recursive - multipath"
285
286 run_ip_mpath 254 ${TEST_NET4[1]}.7 \
287 "${CONGW[1]} dev ${NETIFS[p1]}" \
288 "${CONGW[2]} dev ${NETIFS[p3]} onlink" \
289 0 "unicast connected - multipath onlink first only"
290
291 run_ip_mpath 254 ${TEST_NET4[1]}.8 \
292 "${CONGW[1]} dev ${NETIFS[p1]} onlink" \
293 "${CONGW[2]} dev ${NETIFS[p3]}" \
294 0 "unicast connected - multipath onlink second only"
295}
296
297invalid_onlink_ipv4()
298{
299 run_ip 254 ${TEST_NET4[1]}.11 ${V4ADDRS[p1]} ${NETIFS[p1]} 2 \
300 "Invalid gw - local unicast address"
301
302 run_ip ${VRF_TABLE} ${TEST_NET4[2]}.11 ${V4ADDRS[p5]} ${NETIFS[p5]} 2 \
303 "Invalid gw - local unicast address, VRF"
304
305 run_ip 254 ${TEST_NET4[1]}.101 ${V4ADDRS[p1]} "" 2 "No nexthop device given"
306
307 run_ip 254 ${TEST_NET4[1]}.102 ${V4ADDRS[p3]} ${NETIFS[p1]} 2 \
308 "Gateway resolves to wrong nexthop device"
309
310 run_ip ${VRF_TABLE} ${TEST_NET4[2]}.103 ${V4ADDRS[p7]} ${NETIFS[p5]} 2 \
311 "Gateway resolves to wrong nexthop device - VRF"
312}
313
314################################################################################
315# IPv6 tests
316#
317
318run_ip6()
319{
320 local table="$1"
321 local prefix="$2"
322 local gw="$3"
323 local dev="$4"
324 local exp_rc="$5"
325 local desc="$6"
326
327 # dev arg may be empty
328 [ -n "${dev}" ] && dev="dev ${dev}"
329
330 run_cmd ip -6 ro add table "${table}" "${prefix}"/128 via "${gw}" "${dev}" onlink
331 log_test $? ${exp_rc} "${desc}"
332}
333
334run_ip6_mpath()
335{
336 local table="$1"
337 local prefix="$2"
338 local opts="$3"
339 local nh1="$4"
340 local nh2="$5"
341 local exp_rc="$6"
342 local desc="$7"
343
344 run_cmd ip -6 ro add table "${table}" "${prefix}"/128 "${opts}" \
345 nexthop via ${nh1} nexthop via ${nh2}
346 log_test $? ${exp_rc} "${desc}"
347}
348
349valid_onlink_ipv6()
350{
351 # - unicast connected, unicast recursive, v4-mapped
352 #
353 log_subsection "default VRF - main table"
354
355 run_ip6 254 ${TEST_NET6[1]}::1 ${V6ADDRS[p1]/::*}::64 ${NETIFS[p1]} 0 "unicast connected"
356 run_ip6 254 ${TEST_NET6[1]}::2 ${RECGW6[1]} ${NETIFS[p1]} 0 "unicast recursive"
357 run_ip6 254 ${TEST_NET6[1]}::3 ::ffff:${TEST_NET4IN6[1]} ${NETIFS[p1]} 0 "v4-mapped"
358
359 log_subsection "VRF ${VRF}"
360
361 run_ip6 ${VRF_TABLE} ${TEST_NET6[2]}::1 ${V6ADDRS[p5]/::*}::64 ${NETIFS[p5]} 0 "unicast connected"
362 run_ip6 ${VRF_TABLE} ${TEST_NET6[2]}::2 ${RECGW6[2]} ${NETIFS[p5]} 0 "unicast recursive"
363 run_ip6 ${VRF_TABLE} ${TEST_NET6[2]}::3 ::ffff:${TEST_NET4IN6[2]} ${NETIFS[p5]} 0 "v4-mapped"
364
365 log_subsection "VRF device, PBR table"
366
367 run_ip6 ${PBR_TABLE} ${TEST_NET6[2]}::4 ${V6ADDRS[p5]/::*}::64 ${NETIFS[p5]} 0 "unicast connected"
368 run_ip6 ${PBR_TABLE} ${TEST_NET6[2]}::5 ${RECGW6[2]} ${NETIFS[p5]} 0 "unicast recursive"
369 run_ip6 ${PBR_TABLE} ${TEST_NET6[2]}::6 ::ffff:${TEST_NET4IN6[2]} ${NETIFS[p5]} 0 "v4-mapped"
370
371 # multipath version
372 #
373 log_subsection "default VRF - main table - multipath"
374
375 run_ip6_mpath 254 ${TEST_NET6[1]}::4 "onlink" \
376 "${V6ADDRS[p1]/::*}::64 dev ${NETIFS[p1]}" \
377 "${V6ADDRS[p3]/::*}::64 dev ${NETIFS[p3]}" \
378 0 "unicast connected - multipath onlink"
379
380 run_ip6_mpath 254 ${TEST_NET6[1]}::5 "onlink" \
381 "${RECGW6[1]} dev ${NETIFS[p1]}" \
382 "${RECGW6[2]} dev ${NETIFS[p3]}" \
383 0 "unicast recursive - multipath onlink"
384
385 run_ip6_mpath 254 ${TEST_NET6[1]}::6 "onlink" \
386 "::ffff:${TEST_NET4IN6[1]} dev ${NETIFS[p1]}" \
387 "::ffff:${TEST_NET4IN6[2]} dev ${NETIFS[p3]}" \
388 0 "v4-mapped - multipath onlink"
389
390 run_ip6_mpath 254 ${TEST_NET6[1]}::7 "" \
391 "${V6ADDRS[p1]/::*}::64 dev ${NETIFS[p1]} onlink" \
392 "${V6ADDRS[p3]/::*}::64 dev ${NETIFS[p3]} onlink" \
393 0 "unicast connected - multipath onlink both nexthops"
394
395 run_ip6_mpath 254 ${TEST_NET6[1]}::8 "" \
396 "${V6ADDRS[p1]/::*}::64 dev ${NETIFS[p1]} onlink" \
397 "${V6ADDRS[p3]/::*}::64 dev ${NETIFS[p3]}" \
398 0 "unicast connected - multipath onlink first only"
399
400 run_ip6_mpath 254 ${TEST_NET6[1]}::9 "" \
401 "${V6ADDRS[p1]/::*}::64 dev ${NETIFS[p1]}" \
402 "${V6ADDRS[p3]/::*}::64 dev ${NETIFS[p3]} onlink" \
403 0 "unicast connected - multipath onlink second only"
404}
405
406invalid_onlink_ipv6()
407{
408 local lladdr
409
410 lladdr=$(get_linklocal ${NETIFS[p1]}) || return 1
411
412 run_ip6 254 ${TEST_NET6[1]}::11 ${V6ADDRS[p1]} ${NETIFS[p1]} 2 \
413 "Invalid gw - local unicast address"
414 run_ip6 254 ${TEST_NET6[1]}::12 ${lladdr} ${NETIFS[p1]} 2 \
415 "Invalid gw - local linklocal address"
416 run_ip6 254 ${TEST_NET6[1]}::12 ${MCAST6} ${NETIFS[p1]} 2 \
417 "Invalid gw - multicast address"
418
419 lladdr=$(get_linklocal ${NETIFS[p5]}) || return 1
420 run_ip6 ${VRF_TABLE} ${TEST_NET6[2]}::11 ${V6ADDRS[p5]} ${NETIFS[p5]} 2 \
421 "Invalid gw - local unicast address, VRF"
422 run_ip6 ${VRF_TABLE} ${TEST_NET6[2]}::12 ${lladdr} ${NETIFS[p5]} 2 \
423 "Invalid gw - local linklocal address, VRF"
424 run_ip6 ${VRF_TABLE} ${TEST_NET6[2]}::12 ${MCAST6} ${NETIFS[p5]} 2 \
425 "Invalid gw - multicast address, VRF"
426
427 run_ip6 254 ${TEST_NET6[1]}::101 ${V6ADDRS[p1]} "" 2 \
428 "No nexthop device given"
429
430 # default VRF validation is done against LOCAL table
431 # run_ip6 254 ${TEST_NET6[1]}::102 ${V6ADDRS[p3]/::[0-9]/::64} ${NETIFS[p1]} 2 \
432 # "Gateway resolves to wrong nexthop device"
433
434 run_ip6 ${VRF_TABLE} ${TEST_NET6[2]}::103 ${V6ADDRS[p7]/::[0-9]/::64} ${NETIFS[p5]} 2 \
435 "Gateway resolves to wrong nexthop device - VRF"
436}
437
438run_onlink_tests()
439{
440 log_section "IPv4 onlink"
441 log_subsection "Valid onlink commands"
442 valid_onlink_ipv4
443 log_subsection "Invalid onlink commands"
444 invalid_onlink_ipv4
445
446 log_section "IPv6 onlink"
447 log_subsection "Valid onlink commands"
448 valid_onlink_ipv6
449 log_subsection "Invalid onlink commands"
450 invalid_onlink_ipv6
451}
452
453################################################################################
454# main
455
456nsuccess=0
457nfail=0
458
459cleanup
460setup
461run_onlink_tests
462cleanup
463
464if [ "$TESTS" != "none" ]; then
465 printf "\nTests passed: %3d\n" ${nsuccess}
466 printf "Tests failed: %3d\n" ${nfail}
467fi
diff --git a/tools/testing/selftests/net/fib_tests.sh b/tools/testing/selftests/net/fib_tests.sh
index a9154eefb2e2..9164e60d4b66 100755
--- a/tools/testing/selftests/net/fib_tests.sh
+++ b/tools/testing/selftests/net/fib_tests.sh
@@ -6,154 +6,179 @@
6 6
7ret=0 7ret=0
8 8
9check_err() 9VERBOSE=${VERBOSE:=0}
10{ 10PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no}
11 if [ $ret -eq 0 ]; then 11IP="ip -netns testns"
12 ret=$1
13 fi
14}
15 12
16check_fail() 13log_test()
17{ 14{
18 if [ $1 -eq 0 ]; then 15 local rc=$1
16 local expected=$2
17 local msg="$3"
18
19 if [ ${rc} -eq ${expected} ]; then
20 printf " TEST: %-60s [ OK ]\n" "${msg}"
21 else
19 ret=1 22 ret=1
23 printf " TEST: %-60s [FAIL]\n" "${msg}"
24 if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
25 echo
26 echo "hit enter to continue, 'q' to quit"
27 read a
28 [ "$a" = "q" ] && exit 1
29 fi
20 fi 30 fi
21} 31}
22 32
23netns_create() 33setup()
24{ 34{
25 local testns=$1 35 set -e
36 ip netns add testns
37 $IP link set dev lo up
38
39 $IP link add dummy0 type dummy
40 $IP link set dev dummy0 up
41 $IP address add 198.51.100.1/24 dev dummy0
42 $IP -6 address add 2001:db8:1::1/64 dev dummy0
43 set +e
26 44
27 ip netns add $testns
28 ip netns exec $testns ip link set dev lo up
29} 45}
30 46
31fib_unreg_unicast_test() 47cleanup()
32{ 48{
33 ret=0 49 $IP link del dev dummy0 &> /dev/null
50 ip netns del testns
51}
34 52
35 netns_create "testns" 53get_linklocal()
54{
55 local dev=$1
56 local addr
36 57
37 ip netns exec testns ip link add dummy0 type dummy 58 addr=$($IP -6 -br addr show dev ${dev} | \
38 ip netns exec testns ip link set dev dummy0 up 59 awk '{
60 for (i = 3; i <= NF; ++i) {
61 if ($i ~ /^fe80/)
62 print $i
63 }
64 }'
65 )
66 addr=${addr/\/*}
39 67
40 ip netns exec testns ip address add 198.51.100.1/24 dev dummy0 68 [ -z "$addr" ] && return 1
41 ip netns exec testns ip -6 address add 2001:db8:1::1/64 dev dummy0
42 69
43 ip netns exec testns ip route get fibmatch 198.51.100.2 &> /dev/null 70 echo $addr
44 check_err $?
45 ip netns exec testns ip -6 route get fibmatch 2001:db8:1::2 &> /dev/null
46 check_err $?
47 71
48 ip netns exec testns ip link del dev dummy0 72 return 0
49 check_err $? 73}
50 74
51 ip netns exec testns ip route get fibmatch 198.51.100.2 &> /dev/null 75fib_unreg_unicast_test()
52 check_fail $? 76{
53 ip netns exec testns ip -6 route get fibmatch 2001:db8:1::2 &> /dev/null 77 echo
54 check_fail $? 78 echo "Single path route test"
55 79
56 ip netns del testns 80 setup
57 81
58 if [ $ret -ne 0 ]; then 82 echo " Start point"
59 echo "FAIL: unicast route test" 83 $IP route get fibmatch 198.51.100.2 &> /dev/null
60 return 1 84 log_test $? 0 "IPv4 fibmatch"
61 fi 85 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
62 echo "PASS: unicast route test" 86 log_test $? 0 "IPv6 fibmatch"
87
88 set -e
89 $IP link del dev dummy0
90 set +e
91
92 echo " Nexthop device deleted"
93 $IP route get fibmatch 198.51.100.2 &> /dev/null
94 log_test $? 2 "IPv4 fibmatch - no route"
95 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
96 log_test $? 2 "IPv6 fibmatch - no route"
97
98 cleanup
63} 99}
64 100
65fib_unreg_multipath_test() 101fib_unreg_multipath_test()
66{ 102{
67 ret=0
68
69 netns_create "testns"
70 103
71 ip netns exec testns ip link add dummy0 type dummy 104 echo
72 ip netns exec testns ip link set dev dummy0 up 105 echo "Multipath route test"
73 106
74 ip netns exec testns ip link add dummy1 type dummy 107 setup
75 ip netns exec testns ip link set dev dummy1 up
76 108
77 ip netns exec testns ip address add 198.51.100.1/24 dev dummy0 109 set -e
78 ip netns exec testns ip -6 address add 2001:db8:1::1/64 dev dummy0 110 $IP link add dummy1 type dummy
111 $IP link set dev dummy1 up
112 $IP address add 192.0.2.1/24 dev dummy1
113 $IP -6 address add 2001:db8:2::1/64 dev dummy1
79 114
80 ip netns exec testns ip address add 192.0.2.1/24 dev dummy1 115 $IP route add 203.0.113.0/24 \
81 ip netns exec testns ip -6 address add 2001:db8:2::1/64 dev dummy1
82
83 ip netns exec testns ip route add 203.0.113.0/24 \
84 nexthop via 198.51.100.2 dev dummy0 \ 116 nexthop via 198.51.100.2 dev dummy0 \
85 nexthop via 192.0.2.2 dev dummy1 117 nexthop via 192.0.2.2 dev dummy1
86 ip netns exec testns ip -6 route add 2001:db8:3::/64 \ 118 $IP -6 route add 2001:db8:3::/64 \
87 nexthop via 2001:db8:1::2 dev dummy0 \ 119 nexthop via 2001:db8:1::2 dev dummy0 \
88 nexthop via 2001:db8:2::2 dev dummy1 120 nexthop via 2001:db8:2::2 dev dummy1
121 set +e
122
123 echo " Start point"
124 $IP route get fibmatch 203.0.113.1 &> /dev/null
125 log_test $? 0 "IPv4 fibmatch"
126 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null
127 log_test $? 0 "IPv6 fibmatch"
89 128
90 ip netns exec testns ip route get fibmatch 203.0.113.1 &> /dev/null 129 set -e
91 check_err $? 130 $IP link del dev dummy0
92 ip netns exec testns ip -6 route get fibmatch 2001:db8:3::1 &> /dev/null 131 set +e
93 check_err $?
94 132
95 ip netns exec testns ip link del dev dummy0 133 echo " One nexthop device deleted"
96 check_err $? 134 $IP route get fibmatch 203.0.113.1 &> /dev/null
135 log_test $? 2 "IPv4 - multipath route removed on delete"
97 136
98 ip netns exec testns ip route get fibmatch 203.0.113.1 &> /dev/null 137 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null
99 check_fail $?
100 ip netns exec testns ip -6 route get fibmatch 2001:db8:3::1 &> /dev/null
101 # In IPv6 we do not flush the entire multipath route. 138 # In IPv6 we do not flush the entire multipath route.
102 check_err $? 139 log_test $? 0 "IPv6 - multipath down to single path"
103 140
104 ip netns exec testns ip link del dev dummy1 141 set -e
142 $IP link del dev dummy1
143 set +e
105 144
106 ip netns del testns 145 echo " Second nexthop device deleted"
146 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null
147 log_test $? 2 "IPv6 - no route"
107 148
108 if [ $ret -ne 0 ]; then 149 cleanup
109 echo "FAIL: multipath route test"
110 return 1
111 fi
112 echo "PASS: multipath route test"
113} 150}
114 151
115fib_unreg_test() 152fib_unreg_test()
116{ 153{
117 echo "Running netdev unregister tests"
118
119 fib_unreg_unicast_test 154 fib_unreg_unicast_test
120 fib_unreg_multipath_test 155 fib_unreg_multipath_test
121} 156}
122 157
123fib_down_unicast_test() 158fib_down_unicast_test()
124{ 159{
125 ret=0 160 echo
126 161 echo "Single path, admin down"
127 netns_create "testns"
128
129 ip netns exec testns ip link add dummy0 type dummy
130 ip netns exec testns ip link set dev dummy0 up
131 162
132 ip netns exec testns ip address add 198.51.100.1/24 dev dummy0 163 setup
133 ip netns exec testns ip -6 address add 2001:db8:1::1/64 dev dummy0
134 164
135 ip netns exec testns ip route get fibmatch 198.51.100.2 &> /dev/null 165 echo " Start point"
136 check_err $? 166 $IP route get fibmatch 198.51.100.2 &> /dev/null
137 ip netns exec testns ip -6 route get fibmatch 2001:db8:1::2 &> /dev/null 167 log_test $? 0 "IPv4 fibmatch"
138 check_err $? 168 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
169 log_test $? 0 "IPv6 fibmatch"
139 170
140 ip netns exec testns ip link set dev dummy0 down 171 set -e
141 check_err $? 172 $IP link set dev dummy0 down
173 set +e
142 174
143 ip netns exec testns ip route get fibmatch 198.51.100.2 &> /dev/null 175 echo " Route deleted on down"
144 check_fail $? 176 $IP route get fibmatch 198.51.100.2 &> /dev/null
145 ip netns exec testns ip -6 route get fibmatch 2001:db8:1::2 &> /dev/null 177 log_test $? 2 "IPv4 fibmatch"
146 check_fail $? 178 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
179 log_test $? 2 "IPv6 fibmatch"
147 180
148 ip netns exec testns ip link del dev dummy0 181 cleanup
149
150 ip netns del testns
151
152 if [ $ret -ne 0 ]; then
153 echo "FAIL: unicast route test"
154 return 1
155 fi
156 echo "PASS: unicast route test"
157} 182}
158 183
159fib_down_multipath_test_do() 184fib_down_multipath_test_do()
@@ -161,251 +186,395 @@ fib_down_multipath_test_do()
161 local down_dev=$1 186 local down_dev=$1
162 local up_dev=$2 187 local up_dev=$2
163 188
164 ip netns exec testns ip route get fibmatch 203.0.113.1 \ 189 $IP route get fibmatch 203.0.113.1 \
165 oif $down_dev &> /dev/null 190 oif $down_dev &> /dev/null
166 check_fail $? 191 log_test $? 2 "IPv4 fibmatch on down device"
167 ip netns exec testns ip -6 route get fibmatch 2001:db8:3::1 \ 192 $IP -6 route get fibmatch 2001:db8:3::1 \
168 oif $down_dev &> /dev/null 193 oif $down_dev &> /dev/null
169 check_fail $? 194 log_test $? 2 "IPv6 fibmatch on down device"
170 195
171 ip netns exec testns ip route get fibmatch 203.0.113.1 \ 196 $IP route get fibmatch 203.0.113.1 \
172 oif $up_dev &> /dev/null 197 oif $up_dev &> /dev/null
173 check_err $? 198 log_test $? 0 "IPv4 fibmatch on up device"
174 ip netns exec testns ip -6 route get fibmatch 2001:db8:3::1 \ 199 $IP -6 route get fibmatch 2001:db8:3::1 \
175 oif $up_dev &> /dev/null 200 oif $up_dev &> /dev/null
176 check_err $? 201 log_test $? 0 "IPv6 fibmatch on up device"
177 202
178 ip netns exec testns ip route get fibmatch 203.0.113.1 | \ 203 $IP route get fibmatch 203.0.113.1 | \
179 grep $down_dev | grep -q "dead linkdown" 204 grep $down_dev | grep -q "dead linkdown"
180 check_err $? 205 log_test $? 0 "IPv4 flags on down device"
181 ip netns exec testns ip -6 route get fibmatch 2001:db8:3::1 | \ 206 $IP -6 route get fibmatch 2001:db8:3::1 | \
182 grep $down_dev | grep -q "dead linkdown" 207 grep $down_dev | grep -q "dead linkdown"
183 check_err $? 208 log_test $? 0 "IPv6 flags on down device"
184 209
185 ip netns exec testns ip route get fibmatch 203.0.113.1 | \ 210 $IP route get fibmatch 203.0.113.1 | \
186 grep $up_dev | grep -q "dead linkdown" 211 grep $up_dev | grep -q "dead linkdown"
187 check_fail $? 212 log_test $? 1 "IPv4 flags on up device"
188 ip netns exec testns ip -6 route get fibmatch 2001:db8:3::1 | \ 213 $IP -6 route get fibmatch 2001:db8:3::1 | \
189 grep $up_dev | grep -q "dead linkdown" 214 grep $up_dev | grep -q "dead linkdown"
190 check_fail $? 215 log_test $? 1 "IPv6 flags on up device"
191} 216}
192 217
193fib_down_multipath_test() 218fib_down_multipath_test()
194{ 219{
195 ret=0 220 echo
196 221 echo "Admin down multipath"
197 netns_create "testns"
198 222
199 ip netns exec testns ip link add dummy0 type dummy 223 setup
200 ip netns exec testns ip link set dev dummy0 up
201 224
202 ip netns exec testns ip link add dummy1 type dummy 225 set -e
203 ip netns exec testns ip link set dev dummy1 up 226 $IP link add dummy1 type dummy
227 $IP link set dev dummy1 up
204 228
205 ip netns exec testns ip address add 198.51.100.1/24 dev dummy0 229 $IP address add 192.0.2.1/24 dev dummy1
206 ip netns exec testns ip -6 address add 2001:db8:1::1/64 dev dummy0 230 $IP -6 address add 2001:db8:2::1/64 dev dummy1
207 231
208 ip netns exec testns ip address add 192.0.2.1/24 dev dummy1 232 $IP route add 203.0.113.0/24 \
209 ip netns exec testns ip -6 address add 2001:db8:2::1/64 dev dummy1
210
211 ip netns exec testns ip route add 203.0.113.0/24 \
212 nexthop via 198.51.100.2 dev dummy0 \ 233 nexthop via 198.51.100.2 dev dummy0 \
213 nexthop via 192.0.2.2 dev dummy1 234 nexthop via 192.0.2.2 dev dummy1
214 ip netns exec testns ip -6 route add 2001:db8:3::/64 \ 235 $IP -6 route add 2001:db8:3::/64 \
215 nexthop via 2001:db8:1::2 dev dummy0 \ 236 nexthop via 2001:db8:1::2 dev dummy0 \
216 nexthop via 2001:db8:2::2 dev dummy1 237 nexthop via 2001:db8:2::2 dev dummy1
238 set +e
239
240 echo " Verify start point"
241 $IP route get fibmatch 203.0.113.1 &> /dev/null
242 log_test $? 0 "IPv4 fibmatch"
217 243
218 ip netns exec testns ip route get fibmatch 203.0.113.1 &> /dev/null 244 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null
219 check_err $? 245 log_test $? 0 "IPv6 fibmatch"
220 ip netns exec testns ip -6 route get fibmatch 2001:db8:3::1 &> /dev/null
221 check_err $?
222 246
223 ip netns exec testns ip link set dev dummy0 down 247 set -e
224 check_err $? 248 $IP link set dev dummy0 down
249 set +e
225 250
251 echo " One device down, one up"
226 fib_down_multipath_test_do "dummy0" "dummy1" 252 fib_down_multipath_test_do "dummy0" "dummy1"
227 253
228 ip netns exec testns ip link set dev dummy0 up 254 set -e
229 check_err $? 255 $IP link set dev dummy0 up
230 ip netns exec testns ip link set dev dummy1 down 256 $IP link set dev dummy1 down
231 check_err $? 257 set +e
232 258
259 echo " Other device down and up"
233 fib_down_multipath_test_do "dummy1" "dummy0" 260 fib_down_multipath_test_do "dummy1" "dummy0"
234 261
235 ip netns exec testns ip link set dev dummy0 down 262 set -e
236 check_err $? 263 $IP link set dev dummy0 down
237 264 set +e
238 ip netns exec testns ip route get fibmatch 203.0.113.1 &> /dev/null
239 check_fail $?
240 ip netns exec testns ip -6 route get fibmatch 2001:db8:3::1 &> /dev/null
241 check_fail $?
242 265
243 ip netns exec testns ip link del dev dummy1 266 echo " Both devices down"
244 ip netns exec testns ip link del dev dummy0 267 $IP route get fibmatch 203.0.113.1 &> /dev/null
245 268 log_test $? 2 "IPv4 fibmatch"
246 ip netns del testns 269 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null
270 log_test $? 2 "IPv6 fibmatch"
247 271
248 if [ $ret -ne 0 ]; then 272 $IP link del dev dummy1
249 echo "FAIL: multipath route test" 273 cleanup
250 return 1
251 fi
252 echo "PASS: multipath route test"
253} 274}
254 275
255fib_down_test() 276fib_down_test()
256{ 277{
257 echo "Running netdev down tests"
258
259 fib_down_unicast_test 278 fib_down_unicast_test
260 fib_down_multipath_test 279 fib_down_multipath_test
261} 280}
262 281
282# Local routes should not be affected when carrier changes.
263fib_carrier_local_test() 283fib_carrier_local_test()
264{ 284{
265 ret=0 285 echo
266 286 echo "Local carrier tests - single path"
267 # Local routes should not be affected when carrier changes.
268 netns_create "testns"
269
270 ip netns exec testns ip link add dummy0 type dummy
271 ip netns exec testns ip link set dev dummy0 up
272 287
273 ip netns exec testns ip link set dev dummy0 carrier on 288 setup
274 289
275 ip netns exec testns ip address add 198.51.100.1/24 dev dummy0 290 set -e
276 ip netns exec testns ip -6 address add 2001:db8:1::1/64 dev dummy0 291 $IP link set dev dummy0 carrier on
292 set +e
277 293
278 ip netns exec testns ip route get fibmatch 198.51.100.1 &> /dev/null 294 echo " Start point"
279 check_err $? 295 $IP route get fibmatch 198.51.100.1 &> /dev/null
280 ip netns exec testns ip -6 route get fibmatch 2001:db8:1::1 &> /dev/null 296 log_test $? 0 "IPv4 fibmatch"
281 check_err $? 297 $IP -6 route get fibmatch 2001:db8:1::1 &> /dev/null
298 log_test $? 0 "IPv6 fibmatch"
282 299
283 ip netns exec testns ip route get fibmatch 198.51.100.1 | \ 300 $IP route get fibmatch 198.51.100.1 | \
284 grep -q "linkdown" 301 grep -q "linkdown"
285 check_fail $? 302 log_test $? 1 "IPv4 - no linkdown flag"
286 ip netns exec testns ip -6 route get fibmatch 2001:db8:1::1 | \ 303 $IP -6 route get fibmatch 2001:db8:1::1 | \
287 grep -q "linkdown" 304 grep -q "linkdown"
288 check_fail $? 305 log_test $? 1 "IPv6 - no linkdown flag"
289 306
290 ip netns exec testns ip link set dev dummy0 carrier off 307 set -e
308 $IP link set dev dummy0 carrier off
309 sleep 1
310 set +e
291 311
292 ip netns exec testns ip route get fibmatch 198.51.100.1 &> /dev/null 312 echo " Carrier off on nexthop"
293 check_err $? 313 $IP route get fibmatch 198.51.100.1 &> /dev/null
294 ip netns exec testns ip -6 route get fibmatch 2001:db8:1::1 &> /dev/null 314 log_test $? 0 "IPv4 fibmatch"
295 check_err $? 315 $IP -6 route get fibmatch 2001:db8:1::1 &> /dev/null
316 log_test $? 0 "IPv6 fibmatch"
296 317
297 ip netns exec testns ip route get fibmatch 198.51.100.1 | \ 318 $IP route get fibmatch 198.51.100.1 | \
298 grep -q "linkdown" 319 grep -q "linkdown"
299 check_fail $? 320 log_test $? 1 "IPv4 - linkdown flag set"
300 ip netns exec testns ip -6 route get fibmatch 2001:db8:1::1 | \ 321 $IP -6 route get fibmatch 2001:db8:1::1 | \
301 grep -q "linkdown" 322 grep -q "linkdown"
302 check_fail $? 323 log_test $? 1 "IPv6 - linkdown flag set"
303 324
304 ip netns exec testns ip address add 192.0.2.1/24 dev dummy0 325 set -e
305 ip netns exec testns ip -6 address add 2001:db8:2::1/64 dev dummy0 326 $IP address add 192.0.2.1/24 dev dummy0
327 $IP -6 address add 2001:db8:2::1/64 dev dummy0
328 set +e
306 329
307 ip netns exec testns ip route get fibmatch 192.0.2.1 &> /dev/null 330 echo " Route to local address with carrier down"
308 check_err $? 331 $IP route get fibmatch 192.0.2.1 &> /dev/null
309 ip netns exec testns ip -6 route get fibmatch 2001:db8:2::1 &> /dev/null 332 log_test $? 0 "IPv4 fibmatch"
310 check_err $? 333 $IP -6 route get fibmatch 2001:db8:2::1 &> /dev/null
334 log_test $? 0 "IPv6 fibmatch"
311 335
312 ip netns exec testns ip route get fibmatch 192.0.2.1 | \ 336 $IP route get fibmatch 192.0.2.1 | \
313 grep -q "linkdown" 337 grep -q "linkdown"
314 check_fail $? 338 log_test $? 1 "IPv4 linkdown flag set"
315 ip netns exec testns ip -6 route get fibmatch 2001:db8:2::1 | \ 339 $IP -6 route get fibmatch 2001:db8:2::1 | \
316 grep -q "linkdown" 340 grep -q "linkdown"
317 check_fail $? 341 log_test $? 1 "IPv6 linkdown flag set"
318 342
319 ip netns exec testns ip link del dev dummy0 343 cleanup
320
321 ip netns del testns
322
323 if [ $ret -ne 0 ]; then
324 echo "FAIL: local route carrier test"
325 return 1
326 fi
327 echo "PASS: local route carrier test"
328} 344}
329 345
330fib_carrier_unicast_test() 346fib_carrier_unicast_test()
331{ 347{
332 ret=0 348 ret=0
333 349
334 netns_create "testns" 350 echo
351 echo "Single path route carrier test"
335 352
336 ip netns exec testns ip link add dummy0 type dummy 353 setup
337 ip netns exec testns ip link set dev dummy0 up
338 354
339 ip netns exec testns ip link set dev dummy0 carrier on 355 set -e
356 $IP link set dev dummy0 carrier on
357 set +e
340 358
341 ip netns exec testns ip address add 198.51.100.1/24 dev dummy0 359 echo " Start point"
342 ip netns exec testns ip -6 address add 2001:db8:1::1/64 dev dummy0 360 $IP route get fibmatch 198.51.100.2 &> /dev/null
361 log_test $? 0 "IPv4 fibmatch"
362 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
363 log_test $? 0 "IPv6 fibmatch"
343 364
344 ip netns exec testns ip route get fibmatch 198.51.100.2 &> /dev/null 365 $IP route get fibmatch 198.51.100.2 | \
345 check_err $?
346 ip netns exec testns ip -6 route get fibmatch 2001:db8:1::2 &> /dev/null
347 check_err $?
348
349 ip netns exec testns ip route get fibmatch 198.51.100.2 | \
350 grep -q "linkdown" 366 grep -q "linkdown"
351 check_fail $? 367 log_test $? 1 "IPv4 no linkdown flag"
352 ip netns exec testns ip -6 route get fibmatch 2001:db8:1::2 | \ 368 $IP -6 route get fibmatch 2001:db8:1::2 | \
353 grep -q "linkdown" 369 grep -q "linkdown"
354 check_fail $? 370 log_test $? 1 "IPv6 no linkdown flag"
355 371
356 ip netns exec testns ip link set dev dummy0 carrier off 372 set -e
373 $IP link set dev dummy0 carrier off
374 set +e
357 375
358 ip netns exec testns ip route get fibmatch 198.51.100.2 &> /dev/null 376 echo " Carrier down"
359 check_err $? 377 $IP route get fibmatch 198.51.100.2 &> /dev/null
360 ip netns exec testns ip -6 route get fibmatch 2001:db8:1::2 &> /dev/null 378 log_test $? 0 "IPv4 fibmatch"
361 check_err $? 379 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
380 log_test $? 0 "IPv6 fibmatch"
362 381
363 ip netns exec testns ip route get fibmatch 198.51.100.2 | \ 382 $IP route get fibmatch 198.51.100.2 | \
364 grep -q "linkdown" 383 grep -q "linkdown"
365 check_err $? 384 log_test $? 0 "IPv4 linkdown flag set"
366 ip netns exec testns ip -6 route get fibmatch 2001:db8:1::2 | \ 385 $IP -6 route get fibmatch 2001:db8:1::2 | \
367 grep -q "linkdown" 386 grep -q "linkdown"
368 check_err $? 387 log_test $? 0 "IPv6 linkdown flag set"
369 388
370 ip netns exec testns ip address add 192.0.2.1/24 dev dummy0 389 set -e
371 ip netns exec testns ip -6 address add 2001:db8:2::1/64 dev dummy0 390 $IP address add 192.0.2.1/24 dev dummy0
391 $IP -6 address add 2001:db8:2::1/64 dev dummy0
392 set +e
372 393
373 ip netns exec testns ip route get fibmatch 192.0.2.2 &> /dev/null 394 echo " Second address added with carrier down"
374 check_err $? 395 $IP route get fibmatch 192.0.2.2 &> /dev/null
375 ip netns exec testns ip -6 route get fibmatch 2001:db8:2::2 &> /dev/null 396 log_test $? 0 "IPv4 fibmatch"
376 check_err $? 397 $IP -6 route get fibmatch 2001:db8:2::2 &> /dev/null
398 log_test $? 0 "IPv6 fibmatch"
377 399
378 ip netns exec testns ip route get fibmatch 192.0.2.2 | \ 400 $IP route get fibmatch 192.0.2.2 | \
379 grep -q "linkdown" 401 grep -q "linkdown"
380 check_err $? 402 log_test $? 0 "IPv4 linkdown flag set"
381 ip netns exec testns ip -6 route get fibmatch 2001:db8:2::2 | \ 403 $IP -6 route get fibmatch 2001:db8:2::2 | \
382 grep -q "linkdown" 404 grep -q "linkdown"
383 check_err $? 405 log_test $? 0 "IPv6 linkdown flag set"
384 406
385 ip netns exec testns ip link del dev dummy0 407 cleanup
408}
386 409
387 ip netns del testns 410fib_carrier_test()
411{
412 fib_carrier_local_test
413 fib_carrier_unicast_test
414}
388 415
389 if [ $ret -ne 0 ]; then 416################################################################################
390 echo "FAIL: unicast route carrier test" 417# Tests on nexthop spec
391 return 1 418
419# run 'ip route add' with given spec
420add_rt()
421{
422 local desc="$1"
423 local erc=$2
424 local vrf=$3
425 local pfx=$4
426 local gw=$5
427 local dev=$6
428 local cmd out rc
429
430 [ "$vrf" = "-" ] && vrf="default"
431 [ -n "$gw" ] && gw="via $gw"
432 [ -n "$dev" ] && dev="dev $dev"
433
434 cmd="$IP route add vrf $vrf $pfx $gw $dev"
435 if [ "$VERBOSE" = "1" ]; then
436 printf "\n COMMAND: $cmd\n"
437 fi
438
439 out=$(eval $cmd 2>&1)
440 rc=$?
441 if [ "$VERBOSE" = "1" -a -n "$out" ]; then
442 echo " $out"
392 fi 443 fi
393 echo "PASS: unicast route carrier test" 444 log_test $rc $erc "$desc"
394} 445}
395 446
396fib_carrier_test() 447fib4_nexthop()
397{ 448{
398 echo "Running netdev carrier change tests" 449 echo
450 echo "IPv4 nexthop tests"
399 451
400 fib_carrier_local_test 452 echo "<<< write me >>>"
401 fib_carrier_unicast_test
402} 453}
403 454
455fib6_nexthop()
456{
457 local lldummy=$(get_linklocal dummy0)
458 local llv1=$(get_linklocal dummy0)
459
460 if [ -z "$lldummy" ]; then
461 echo "Failed to get linklocal address for dummy0"
462 return 1
463 fi
464 if [ -z "$llv1" ]; then
465 echo "Failed to get linklocal address for veth1"
466 return 1
467 fi
468
469 echo
470 echo "IPv6 nexthop tests"
471
472 add_rt "Directly connected nexthop, unicast address" 0 \
473 - 2001:db8:101::/64 2001:db8:1::2
474 add_rt "Directly connected nexthop, unicast address with device" 0 \
475 - 2001:db8:102::/64 2001:db8:1::2 "dummy0"
476 add_rt "Gateway is linklocal address" 0 \
477 - 2001:db8:103::1/64 $llv1 "veth0"
478
479 # fails because LL address requires a device
480 add_rt "Gateway is linklocal address, no device" 2 \
481 - 2001:db8:104::1/64 $llv1
482
483 # local address can not be a gateway
484 add_rt "Gateway can not be local unicast address" 2 \
485 - 2001:db8:105::/64 2001:db8:1::1
486 add_rt "Gateway can not be local unicast address, with device" 2 \
487 - 2001:db8:106::/64 2001:db8:1::1 "dummy0"
488 add_rt "Gateway can not be a local linklocal address" 2 \
489 - 2001:db8:107::1/64 $lldummy "dummy0"
490
491 # VRF tests
492 add_rt "Gateway can be local address in a VRF" 0 \
493 - 2001:db8:108::/64 2001:db8:51::2
494 add_rt "Gateway can be local address in a VRF, with device" 0 \
495 - 2001:db8:109::/64 2001:db8:51::2 "veth0"
496 add_rt "Gateway can be local linklocal address in a VRF" 0 \
497 - 2001:db8:110::1/64 $llv1 "veth0"
498
499 add_rt "Redirect to VRF lookup" 0 \
500 - 2001:db8:111::/64 "" "red"
501
502 add_rt "VRF route, gateway can be local address in default VRF" 0 \
503 red 2001:db8:112::/64 2001:db8:51::1
504
505 # local address in same VRF fails
506 add_rt "VRF route, gateway can not be a local address" 2 \
507 red 2001:db8:113::1/64 2001:db8:2::1
508 add_rt "VRF route, gateway can not be a local addr with device" 2 \
509 red 2001:db8:114::1/64 2001:db8:2::1 "dummy1"
510}
511
512# Default VRF:
513# dummy0 - 198.51.100.1/24 2001:db8:1::1/64
514# veth0 - 192.0.2.1/24 2001:db8:51::1/64
515#
516# VRF red:
517# dummy1 - 192.168.2.1/24 2001:db8:2::1/64
518# veth1 - 192.0.2.2/24 2001:db8:51::2/64
519#
520# [ dummy0 veth0 ]--[ veth1 dummy1 ]
521
522fib_nexthop_test()
523{
524 setup
525
526 set -e
527
528 $IP -4 rule add pref 32765 table local
529 $IP -4 rule del pref 0
530 $IP -6 rule add pref 32765 table local
531 $IP -6 rule del pref 0
532
533 $IP link add red type vrf table 1
534 $IP link set red up
535 $IP -4 route add vrf red unreachable default metric 4278198272
536 $IP -6 route add vrf red unreachable default metric 4278198272
537
538 $IP link add veth0 type veth peer name veth1
539 $IP link set dev veth0 up
540 $IP address add 192.0.2.1/24 dev veth0
541 $IP -6 address add 2001:db8:51::1/64 dev veth0
542
543 $IP link set dev veth1 vrf red up
544 $IP address add 192.0.2.2/24 dev veth1
545 $IP -6 address add 2001:db8:51::2/64 dev veth1
546
547 $IP link add dummy1 type dummy
548 $IP link set dev dummy1 vrf red up
549 $IP address add 192.168.2.1/24 dev dummy1
550 $IP -6 address add 2001:db8:2::1/64 dev dummy1
551 set +e
552
553 sleep 1
554 fib4_nexthop
555 fib6_nexthop
556
557 (
558 $IP link del dev dummy1
559 $IP link del veth0
560 $IP link del red
561 ) 2>/dev/null
562 cleanup
563}
564
565################################################################################
566#
567
404fib_test() 568fib_test()
405{ 569{
406 fib_unreg_test 570 if [ -n "$TEST" ]; then
407 fib_down_test 571 eval $TEST
408 fib_carrier_test 572 else
573 fib_unreg_test
574 fib_down_test
575 fib_carrier_test
576 fib_nexthop_test
577 fi
409} 578}
410 579
411if [ "$(id -u)" -ne 0 ];then 580if [ "$(id -u)" -ne 0 ];then
@@ -424,6 +593,9 @@ if [ $? -ne 0 ]; then
424 exit 0 593 exit 0
425fi 594fi
426 595
596# start clean
597cleanup &> /dev/null
598
427fib_test 599fib_test
428 600
429exit $ret 601exit $ret
diff --git a/tools/testing/selftests/net/forwarding/.gitignore b/tools/testing/selftests/net/forwarding/.gitignore
new file mode 100644
index 000000000000..a793eef5b876
--- /dev/null
+++ b/tools/testing/selftests/net/forwarding/.gitignore
@@ -0,0 +1 @@
forwarding.config
diff --git a/tools/testing/selftests/net/forwarding/README b/tools/testing/selftests/net/forwarding/README
new file mode 100644
index 000000000000..4a0964c42860
--- /dev/null
+++ b/tools/testing/selftests/net/forwarding/README
@@ -0,0 +1,56 @@
1Motivation
2==========
3
4One of the nice things about network namespaces is that they allow one
5to easily create and test complex environments.
6
7Unfortunately, these namespaces can not be used with actual switching
8ASICs, as their ports can not be migrated to other network namespaces
9(NETIF_F_NETNS_LOCAL) and most of them probably do not support the
10L1-separation provided by namespaces.
11
12However, a similar kind of flexibility can be achieved by using VRFs and
13by looping the switch ports together. For example:
14
15 br0
16 +
17 vrf-h1 | vrf-h2
18 + +---+----+ +
19 | | | |
20 192.0.2.1/24 + + + + 192.0.2.2/24
21 swp1 swp2 swp3 swp4
22 + + + +
23 | | | |
24 +--------+ +--------+
25
26The VRFs act as lightweight namespaces representing hosts connected to
27the switch.
28
29This approach for testing switch ASICs has several advantages over the
30traditional method that requires multiple physical machines, to name a
31few:
32
331. Only the device under test (DUT) is being tested without noise from
34other system.
35
362. Ability to easily provision complex topologies. Testing bridging
37between 4-ports LAGs or 8-way ECMP requires many physical links that are
38not always available. With the VRF-based approach one merely needs to
39loopback more ports.
40
41These tests are written with switch ASICs in mind, but they can be run
42on any Linux box using veth pairs to emulate physical loopbacks.
43
44Guidelines for Writing Tests
45============================
46
47o Where possible, reuse an existing topology for different tests instead
48 of recreating the same topology.
49o Where possible, IPv6 and IPv4 addresses shall conform to RFC 3849 and
50 RFC 5737, respectively.
51o Where possible, tests shall be written so that they can be reused by
52 multiple topologies and added to lib.sh.
53o Checks shall be added to lib.sh for any external dependencies.
54o Code shall be checked using ShellCheck [1] prior to submission.
55
561. https://www.shellcheck.net/
diff --git a/tools/testing/selftests/net/forwarding/bridge_vlan_aware.sh b/tools/testing/selftests/net/forwarding/bridge_vlan_aware.sh
new file mode 100755
index 000000000000..75d922438bc9
--- /dev/null
+++ b/tools/testing/selftests/net/forwarding/bridge_vlan_aware.sh
@@ -0,0 +1,88 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4NUM_NETIFS=4
5CHECK_TC="yes"
6source lib.sh
7
8h1_create()
9{
10 simple_if_init $h1 192.0.2.1/24 2001:db8:1::1/64
11}
12
13h1_destroy()
14{
15 simple_if_fini $h1 192.0.2.1/24 2001:db8:1::1/64
16}
17
18h2_create()
19{
20 simple_if_init $h2 192.0.2.2/24 2001:db8:1::2/64
21}
22
23h2_destroy()
24{
25 simple_if_fini $h2 192.0.2.2/24 2001:db8:1::2/64
26}
27
28switch_create()
29{
30 # 10 Seconds ageing time.
31 ip link add dev br0 type bridge vlan_filtering 1 ageing_time 1000 \
32 mcast_snooping 0
33
34 ip link set dev $swp1 master br0
35 ip link set dev $swp2 master br0
36
37 ip link set dev br0 up
38 ip link set dev $swp1 up
39 ip link set dev $swp2 up
40}
41
42switch_destroy()
43{
44 ip link set dev $swp2 down
45 ip link set dev $swp1 down
46
47 ip link del dev br0
48}
49
50setup_prepare()
51{
52 h1=${NETIFS[p1]}
53 swp1=${NETIFS[p2]}
54
55 swp2=${NETIFS[p3]}
56 h2=${NETIFS[p4]}
57
58 vrf_prepare
59
60 h1_create
61 h2_create
62
63 switch_create
64}
65
66cleanup()
67{
68 pre_cleanup
69
70 switch_destroy
71
72 h2_destroy
73 h1_destroy
74
75 vrf_cleanup
76}
77
78trap cleanup EXIT
79
80setup_prepare
81setup_wait
82
83ping_test $h1 192.0.2.2
84ping6_test $h1 2001:db8:1::2
85learning_test "br0" $swp1 $h1 $h2
86flood_test $swp2 $h1 $h2
87
88exit $EXIT_STATUS
diff --git a/tools/testing/selftests/net/forwarding/bridge_vlan_unaware.sh b/tools/testing/selftests/net/forwarding/bridge_vlan_unaware.sh
new file mode 100755
index 000000000000..1cddf06f691d
--- /dev/null
+++ b/tools/testing/selftests/net/forwarding/bridge_vlan_unaware.sh
@@ -0,0 +1,86 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4NUM_NETIFS=4
5source lib.sh
6
7h1_create()
8{
9 simple_if_init $h1 192.0.2.1/24 2001:db8:1::1/64
10}
11
12h1_destroy()
13{
14 simple_if_fini $h1 192.0.2.1/24 2001:db8:1::1/64
15}
16
17h2_create()
18{
19 simple_if_init $h2 192.0.2.2/24 2001:db8:1::2/64
20}
21
22h2_destroy()
23{
24 simple_if_fini $h2 192.0.2.2/24 2001:db8:1::2/64
25}
26
27switch_create()
28{
29 # 10 Seconds ageing time.
30 ip link add dev br0 type bridge ageing_time 1000 mcast_snooping 0
31
32 ip link set dev $swp1 master br0
33 ip link set dev $swp2 master br0
34
35 ip link set dev br0 up
36 ip link set dev $swp1 up
37 ip link set dev $swp2 up
38}
39
40switch_destroy()
41{
42 ip link set dev $swp2 down
43 ip link set dev $swp1 down
44
45 ip link del dev br0
46}
47
48setup_prepare()
49{
50 h1=${NETIFS[p1]}
51 swp1=${NETIFS[p2]}
52
53 swp2=${NETIFS[p3]}
54 h2=${NETIFS[p4]}
55
56 vrf_prepare
57
58 h1_create
59 h2_create
60
61 switch_create
62}
63
64cleanup()
65{
66 pre_cleanup
67
68 switch_destroy
69
70 h2_destroy
71 h1_destroy
72
73 vrf_cleanup
74}
75
76trap cleanup EXIT
77
78setup_prepare
79setup_wait
80
81ping_test $h1 192.0.2.2
82ping6_test $h1 2001:db8:1::2
83learning_test "br0" $swp1 $h1 $h2
84flood_test $swp2 $h1 $h2
85
86exit $EXIT_STATUS
diff --git a/tools/testing/selftests/net/forwarding/config b/tools/testing/selftests/net/forwarding/config
new file mode 100644
index 000000000000..5cd2aed97958
--- /dev/null
+++ b/tools/testing/selftests/net/forwarding/config
@@ -0,0 +1,12 @@
1CONFIG_BRIDGE=m
2CONFIG_VLAN_8021Q=m
3CONFIG_BRIDGE_VLAN_FILTERING=y
4CONFIG_NET_L3_MASTER_DEV=y
5CONFIG_IPV6_MULTIPLE_TABLES=y
6CONFIG_NET_VRF=m
7CONFIG_BPF_SYSCALL=y
8CONFIG_CGROUP_BPF=y
9CONFIG_NET_CLS_FLOWER=m
10CONFIG_NET_SCH_INGRESS=m
11CONFIG_NET_ACT_GACT=m
12CONFIG_VETH=m
diff --git a/tools/testing/selftests/net/forwarding/forwarding.config.sample b/tools/testing/selftests/net/forwarding/forwarding.config.sample
new file mode 100644
index 000000000000..e819d049d9ce
--- /dev/null
+++ b/tools/testing/selftests/net/forwarding/forwarding.config.sample
@@ -0,0 +1,35 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4##############################################################################
5# Topology description. p1 looped back to p2, p3 to p4 and so on.
6declare -A NETIFS
7
8NETIFS[p1]=veth0
9NETIFS[p2]=veth1
10NETIFS[p3]=veth2
11NETIFS[p4]=veth3
12NETIFS[p5]=veth4
13NETIFS[p6]=veth5
14NETIFS[p7]=veth6
15NETIFS[p8]=veth7
16
17##############################################################################
18# Defines
19
20# IPv4 ping utility name
21PING=ping
22# IPv6 ping utility name. Some distributions use 'ping' for IPv6.
23PING6=ping6
24# Packet generator. Some distributions use 'mz'.
25MZ=mausezahn
26# Time to wait after interfaces participating in the test are all UP
27WAIT_TIME=5
28# Whether to pause on failure or not.
29PAUSE_ON_FAIL=no
30# Whether to pause on cleanup or not.
31PAUSE_ON_CLEANUP=no
32# Type of network interface to create
33NETIF_TYPE=veth
34# Whether to create virtual interfaces (veth) or not
35NETIF_CREATE=yes
diff --git a/tools/testing/selftests/net/forwarding/lib.sh b/tools/testing/selftests/net/forwarding/lib.sh
new file mode 100644
index 000000000000..1ac6c62271f3
--- /dev/null
+++ b/tools/testing/selftests/net/forwarding/lib.sh
@@ -0,0 +1,577 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4##############################################################################
5# Defines
6
7# Can be overridden by the configuration file.
8PING=${PING:=ping}
9PING6=${PING6:=ping6}
10MZ=${MZ:=mausezahn}
11WAIT_TIME=${WAIT_TIME:=5}
12PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no}
13PAUSE_ON_CLEANUP=${PAUSE_ON_CLEANUP:=no}
14NETIF_TYPE=${NETIF_TYPE:=veth}
15NETIF_CREATE=${NETIF_CREATE:=yes}
16
17if [[ -f forwarding.config ]]; then
18 source forwarding.config
19fi
20
21##############################################################################
22# Sanity checks
23
24check_tc_version()
25{
26 tc -j &> /dev/null
27 if [[ $? -ne 0 ]]; then
28 echo "SKIP: iproute2 too old; tc is missing JSON support"
29 exit 1
30 fi
31
32 tc filter help 2>&1 | grep block &> /dev/null
33 if [[ $? -ne 0 ]]; then
34 echo "SKIP: iproute2 too old; tc is missing shared block support"
35 exit 1
36 fi
37}
38
39if [[ "$(id -u)" -ne 0 ]]; then
40 echo "SKIP: need root privileges"
41 exit 0
42fi
43
44if [[ "$CHECK_TC" = "yes" ]]; then
45 check_tc_version
46fi
47
48if [[ ! -x "$(command -v jq)" ]]; then
49 echo "SKIP: jq not installed"
50 exit 1
51fi
52
53if [[ ! -x "$(command -v $MZ)" ]]; then
54 echo "SKIP: $MZ not installed"
55 exit 1
56fi
57
58if [[ ! -v NUM_NETIFS ]]; then
59 echo "SKIP: importer does not define \"NUM_NETIFS\""
60 exit 1
61fi
62
63##############################################################################
64# Command line options handling
65
66count=0
67
68while [[ $# -gt 0 ]]; do
69 if [[ "$count" -eq "0" ]]; then
70 unset NETIFS
71 declare -A NETIFS
72 fi
73 count=$((count + 1))
74 NETIFS[p$count]="$1"
75 shift
76done
77
78##############################################################################
79# Network interfaces configuration
80
81create_netif_veth()
82{
83 local i
84
85 for i in $(eval echo {1..$NUM_NETIFS}); do
86 local j=$((i+1))
87
88 ip link show dev ${NETIFS[p$i]} &> /dev/null
89 if [[ $? -ne 0 ]]; then
90 ip link add ${NETIFS[p$i]} type veth \
91 peer name ${NETIFS[p$j]}
92 if [[ $? -ne 0 ]]; then
93 echo "Failed to create netif"
94 exit 1
95 fi
96 fi
97 i=$j
98 done
99}
100
101create_netif()
102{
103 case "$NETIF_TYPE" in
104 veth) create_netif_veth
105 ;;
106 *) echo "Can not create interfaces of type \'$NETIF_TYPE\'"
107 exit 1
108 ;;
109 esac
110}
111
112if [[ "$NETIF_CREATE" = "yes" ]]; then
113 create_netif
114fi
115
116for i in $(eval echo {1..$NUM_NETIFS}); do
117 ip link show dev ${NETIFS[p$i]} &> /dev/null
118 if [[ $? -ne 0 ]]; then
119 echo "SKIP: could not find all required interfaces"
120 exit 1
121 fi
122done
123
124##############################################################################
125# Helpers
126
127# Exit status to return at the end. Set in case one of the tests fails.
128EXIT_STATUS=0
129# Per-test return value. Clear at the beginning of each test.
130RET=0
131
132check_err()
133{
134 local err=$1
135 local msg=$2
136
137 if [[ $RET -eq 0 && $err -ne 0 ]]; then
138 RET=$err
139 retmsg=$msg
140 fi
141}
142
143check_fail()
144{
145 local err=$1
146 local msg=$2
147
148 if [[ $RET -eq 0 && $err -eq 0 ]]; then
149 RET=1
150 retmsg=$msg
151 fi
152}
153
154log_test()
155{
156 local test_name=$1
157 local opt_str=$2
158
159 if [[ $# -eq 2 ]]; then
160 opt_str="($opt_str)"
161 fi
162
163 if [[ $RET -ne 0 ]]; then
164 EXIT_STATUS=1
165 printf "TEST: %-60s [FAIL]\n" "$test_name $opt_str"
166 if [[ ! -z "$retmsg" ]]; then
167 printf "\t%s\n" "$retmsg"
168 fi
169 if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
170 echo "Hit enter to continue, 'q' to quit"
171 read a
172 [ "$a" = "q" ] && exit 1
173 fi
174 return 1
175 fi
176
177 printf "TEST: %-60s [PASS]\n" "$test_name $opt_str"
178 return 0
179}
180
181log_info()
182{
183 local msg=$1
184
185 echo "INFO: $msg"
186}
187
188setup_wait()
189{
190 for i in $(eval echo {1..$NUM_NETIFS}); do
191 while true; do
192 ip link show dev ${NETIFS[p$i]} up \
193 | grep 'state UP' &> /dev/null
194 if [[ $? -ne 0 ]]; then
195 sleep 1
196 else
197 break
198 fi
199 done
200 done
201
202 # Make sure links are ready.
203 sleep $WAIT_TIME
204}
205
206pre_cleanup()
207{
208 if [ "${PAUSE_ON_CLEANUP}" = "yes" ]; then
209 echo "Pausing before cleanup, hit any key to continue"
210 read
211 fi
212}
213
214vrf_prepare()
215{
216 ip -4 rule add pref 32765 table local
217 ip -4 rule del pref 0
218 ip -6 rule add pref 32765 table local
219 ip -6 rule del pref 0
220}
221
222vrf_cleanup()
223{
224 ip -6 rule add pref 0 table local
225 ip -6 rule del pref 32765
226 ip -4 rule add pref 0 table local
227 ip -4 rule del pref 32765
228}
229
230__last_tb_id=0
231declare -A __TB_IDS
232
233__vrf_td_id_assign()
234{
235 local vrf_name=$1
236
237 __last_tb_id=$((__last_tb_id + 1))
238 __TB_IDS[$vrf_name]=$__last_tb_id
239 return $__last_tb_id
240}
241
242__vrf_td_id_lookup()
243{
244 local vrf_name=$1
245
246 return ${__TB_IDS[$vrf_name]}
247}
248
249vrf_create()
250{
251 local vrf_name=$1
252 local tb_id
253
254 __vrf_td_id_assign $vrf_name
255 tb_id=$?
256
257 ip link add dev $vrf_name type vrf table $tb_id
258 ip -4 route add table $tb_id unreachable default metric 4278198272
259 ip -6 route add table $tb_id unreachable default metric 4278198272
260}
261
262vrf_destroy()
263{
264 local vrf_name=$1
265 local tb_id
266
267 __vrf_td_id_lookup $vrf_name
268 tb_id=$?
269
270 ip -6 route del table $tb_id unreachable default metric 4278198272
271 ip -4 route del table $tb_id unreachable default metric 4278198272
272 ip link del dev $vrf_name
273}
274
275__addr_add_del()
276{
277 local if_name=$1
278 local add_del=$2
279 local array
280
281 shift
282 shift
283 array=("${@}")
284
285 for addrstr in "${array[@]}"; do
286 ip address $add_del $addrstr dev $if_name
287 done
288}
289
290simple_if_init()
291{
292 local if_name=$1
293 local vrf_name
294 local array
295
296 shift
297 vrf_name=v$if_name
298 array=("${@}")
299
300 vrf_create $vrf_name
301 ip link set dev $if_name master $vrf_name
302 ip link set dev $vrf_name up
303 ip link set dev $if_name up
304
305 __addr_add_del $if_name add "${array[@]}"
306}
307
308simple_if_fini()
309{
310 local if_name=$1
311 local vrf_name
312 local array
313
314 shift
315 vrf_name=v$if_name
316 array=("${@}")
317
318 __addr_add_del $if_name del "${array[@]}"
319
320 ip link set dev $if_name down
321 vrf_destroy $vrf_name
322}
323
324master_name_get()
325{
326 local if_name=$1
327
328 ip -j link show dev $if_name | jq -r '.[]["master"]'
329}
330
331link_stats_tx_packets_get()
332{
333 local if_name=$1
334
335 ip -j -s link show dev $if_name | jq '.[]["stats64"]["tx"]["packets"]'
336}
337
338mac_get()
339{
340 local if_name=$1
341
342 ip -j link show dev $if_name | jq -r '.[]["address"]'
343}
344
345bridge_ageing_time_get()
346{
347 local bridge=$1
348 local ageing_time
349
350 # Need to divide by 100 to convert to seconds.
351 ageing_time=$(ip -j -d link show dev $bridge \
352 | jq '.[]["linkinfo"]["info_data"]["ageing_time"]')
353 echo $((ageing_time / 100))
354}
355
356forwarding_enable()
357{
358 ipv4_fwd=$(sysctl -n net.ipv4.conf.all.forwarding)
359 ipv6_fwd=$(sysctl -n net.ipv6.conf.all.forwarding)
360
361 sysctl -q -w net.ipv4.conf.all.forwarding=1
362 sysctl -q -w net.ipv6.conf.all.forwarding=1
363}
364
365forwarding_restore()
366{
367 sysctl -q -w net.ipv6.conf.all.forwarding=$ipv6_fwd
368 sysctl -q -w net.ipv4.conf.all.forwarding=$ipv4_fwd
369}
370
371tc_offload_check()
372{
373 for i in $(eval echo {1..$NUM_NETIFS}); do
374 ethtool -k ${NETIFS[p$i]} \
375 | grep "hw-tc-offload: on" &> /dev/null
376 if [[ $? -ne 0 ]]; then
377 return 1
378 fi
379 done
380
381 return 0
382}
383
384##############################################################################
385# Tests
386
387ping_test()
388{
389 local if_name=$1
390 local dip=$2
391 local vrf_name
392
393 RET=0
394
395 vrf_name=$(master_name_get $if_name)
396 ip vrf exec $vrf_name $PING $dip -c 10 -i 0.1 -w 2 &> /dev/null
397 check_err $?
398 log_test "ping"
399}
400
401ping6_test()
402{
403 local if_name=$1
404 local dip=$2
405 local vrf_name
406
407 RET=0
408
409 vrf_name=$(master_name_get $if_name)
410 ip vrf exec $vrf_name $PING6 $dip -c 10 -i 0.1 -w 2 &> /dev/null
411 check_err $?
412 log_test "ping6"
413}
414
415learning_test()
416{
417 local bridge=$1
418 local br_port1=$2 # Connected to `host1_if`.
419 local host1_if=$3
420 local host2_if=$4
421 local mac=de:ad:be:ef:13:37
422 local ageing_time
423
424 RET=0
425
426 bridge -j fdb show br $bridge brport $br_port1 \
427 | jq -e ".[] | select(.mac == \"$mac\")" &> /dev/null
428 check_fail $? "Found FDB record when should not"
429
430 # Disable unknown unicast flooding on `br_port1` to make sure
431 # packets are only forwarded through the port after a matching
432 # FDB entry was installed.
433 bridge link set dev $br_port1 flood off
434
435 tc qdisc add dev $host1_if ingress
436 tc filter add dev $host1_if ingress protocol ip pref 1 handle 101 \
437 flower dst_mac $mac action drop
438
439 $MZ $host2_if -c 1 -p 64 -b $mac -t ip -q
440 sleep 1
441
442 tc -j -s filter show dev $host1_if ingress \
443 | jq -e ".[] | select(.options.handle == 101) \
444 | select(.options.actions[0].stats.packets == 1)" &> /dev/null
445 check_fail $? "Packet reached second host when should not"
446
447 $MZ $host1_if -c 1 -p 64 -a $mac -t ip -q
448 sleep 1
449
450 bridge -j fdb show br $bridge brport $br_port1 \
451 | jq -e ".[] | select(.mac == \"$mac\")" &> /dev/null
452 check_err $? "Did not find FDB record when should"
453
454 $MZ $host2_if -c 1 -p 64 -b $mac -t ip -q
455 sleep 1
456
457 tc -j -s filter show dev $host1_if ingress \
458 | jq -e ".[] | select(.options.handle == 101) \
459 | select(.options.actions[0].stats.packets == 1)" &> /dev/null
460 check_err $? "Packet did not reach second host when should"
461
462 # Wait for 10 seconds after the ageing time to make sure FDB
463 # record was aged-out.
464 ageing_time=$(bridge_ageing_time_get $bridge)
465 sleep $((ageing_time + 10))
466
467 bridge -j fdb show br $bridge brport $br_port1 \
468 | jq -e ".[] | select(.mac == \"$mac\")" &> /dev/null
469 check_fail $? "Found FDB record when should not"
470
471 bridge link set dev $br_port1 learning off
472
473 $MZ $host1_if -c 1 -p 64 -a $mac -t ip -q
474 sleep 1
475
476 bridge -j fdb show br $bridge brport $br_port1 \
477 | jq -e ".[] | select(.mac == \"$mac\")" &> /dev/null
478 check_fail $? "Found FDB record when should not"
479
480 bridge link set dev $br_port1 learning on
481
482 tc filter del dev $host1_if ingress protocol ip pref 1 handle 101 flower
483 tc qdisc del dev $host1_if ingress
484
485 bridge link set dev $br_port1 flood on
486
487 log_test "FDB learning"
488}
489
490flood_test_do()
491{
492 local should_flood=$1
493 local mac=$2
494 local ip=$3
495 local host1_if=$4
496 local host2_if=$5
497 local err=0
498
499 # Add an ACL on `host2_if` which will tell us whether the packet
500 # was flooded to it or not.
501 tc qdisc add dev $host2_if ingress
502 tc filter add dev $host2_if ingress protocol ip pref 1 handle 101 \
503 flower dst_mac $mac action drop
504
505 $MZ $host1_if -c 1 -p 64 -b $mac -B $ip -t ip -q
506 sleep 1
507
508 tc -j -s filter show dev $host2_if ingress \
509 | jq -e ".[] | select(.options.handle == 101) \
510 | select(.options.actions[0].stats.packets == 1)" &> /dev/null
511 if [[ $? -ne 0 && $should_flood == "true" || \
512 $? -eq 0 && $should_flood == "false" ]]; then
513 err=1
514 fi
515
516 tc filter del dev $host2_if ingress protocol ip pref 1 handle 101 flower
517 tc qdisc del dev $host2_if ingress
518
519 return $err
520}
521
522flood_unicast_test()
523{
524 local br_port=$1
525 local host1_if=$2
526 local host2_if=$3
527 local mac=de:ad:be:ef:13:37
528 local ip=192.0.2.100
529
530 RET=0
531
532 bridge link set dev $br_port flood off
533
534 flood_test_do false $mac $ip $host1_if $host2_if
535 check_err $? "Packet flooded when should not"
536
537 bridge link set dev $br_port flood on
538
539 flood_test_do true $mac $ip $host1_if $host2_if
540 check_err $? "Packet was not flooded when should"
541
542 log_test "Unknown unicast flood"
543}
544
545flood_multicast_test()
546{
547 local br_port=$1
548 local host1_if=$2
549 local host2_if=$3
550 local mac=01:00:5e:00:00:01
551 local ip=239.0.0.1
552
553 RET=0
554
555 bridge link set dev $br_port mcast_flood off
556
557 flood_test_do false $mac $ip $host1_if $host2_if
558 check_err $? "Packet flooded when should not"
559
560 bridge link set dev $br_port mcast_flood on
561
562 flood_test_do true $mac $ip $host1_if $host2_if
563 check_err $? "Packet was not flooded when should"
564
565 log_test "Unregistered multicast flood"
566}
567
568flood_test()
569{
570 # `br_port` is connected to `host2_if`
571 local br_port=$1
572 local host1_if=$2
573 local host2_if=$3
574
575 flood_unicast_test $br_port $host1_if $host2_if
576 flood_multicast_test $br_port $host1_if $host2_if
577}
diff --git a/tools/testing/selftests/net/forwarding/router.sh b/tools/testing/selftests/net/forwarding/router.sh
new file mode 100755
index 000000000000..cc6a14abfa87
--- /dev/null
+++ b/tools/testing/selftests/net/forwarding/router.sh
@@ -0,0 +1,125 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4NUM_NETIFS=4
5source lib.sh
6
7h1_create()
8{
9 vrf_create "vrf-h1"
10 ip link set dev $h1 master vrf-h1
11
12 ip link set dev vrf-h1 up
13 ip link set dev $h1 up
14
15 ip address add 192.0.2.2/24 dev $h1
16 ip address add 2001:db8:1::2/64 dev $h1
17
18 ip route add 198.51.100.0/24 vrf vrf-h1 nexthop via 192.0.2.1
19 ip route add 2001:db8:2::/64 vrf vrf-h1 nexthop via 2001:db8:1::1
20}
21
22h1_destroy()
23{
24 ip route del 2001:db8:2::/64 vrf vrf-h1
25 ip route del 198.51.100.0/24 vrf vrf-h1
26
27 ip address del 2001:db8:1::2/64 dev $h1
28 ip address del 192.0.2.2/24 dev $h1
29
30 ip link set dev $h1 down
31 vrf_destroy "vrf-h1"
32}
33
34h2_create()
35{
36 vrf_create "vrf-h2"
37 ip link set dev $h2 master vrf-h2
38
39 ip link set dev vrf-h2 up
40 ip link set dev $h2 up
41
42 ip address add 198.51.100.2/24 dev $h2
43 ip address add 2001:db8:2::2/64 dev $h2
44
45 ip route add 192.0.2.0/24 vrf vrf-h2 nexthop via 198.51.100.1
46 ip route add 2001:db8:1::/64 vrf vrf-h2 nexthop via 2001:db8:2::1
47}
48
49h2_destroy()
50{
51 ip route del 2001:db8:1::/64 vrf vrf-h2
52 ip route del 192.0.2.0/24 vrf vrf-h2
53
54 ip address del 2001:db8:2::2/64 dev $h2
55 ip address del 198.51.100.2/24 dev $h2
56
57 ip link set dev $h2 down
58 vrf_destroy "vrf-h2"
59}
60
61router_create()
62{
63 ip link set dev $rp1 up
64 ip link set dev $rp2 up
65
66 ip address add 192.0.2.1/24 dev $rp1
67 ip address add 2001:db8:1::1/64 dev $rp1
68
69 ip address add 198.51.100.1/24 dev $rp2
70 ip address add 2001:db8:2::1/64 dev $rp2
71}
72
73router_destroy()
74{
75 ip address del 2001:db8:2::1/64 dev $rp2
76 ip address del 198.51.100.1/24 dev $rp2
77
78 ip address del 2001:db8:1::1/64 dev $rp1
79 ip address del 192.0.2.1/24 dev $rp1
80
81 ip link set dev $rp2 down
82 ip link set dev $rp1 down
83}
84
85setup_prepare()
86{
87 h1=${NETIFS[p1]}
88 rp1=${NETIFS[p2]}
89
90 rp2=${NETIFS[p3]}
91 h2=${NETIFS[p4]}
92
93 vrf_prepare
94
95 h1_create
96 h2_create
97
98 router_create
99
100 forwarding_enable
101}
102
103cleanup()
104{
105 pre_cleanup
106
107 forwarding_restore
108
109 router_destroy
110
111 h2_destroy
112 h1_destroy
113
114 vrf_cleanup
115}
116
117trap cleanup EXIT
118
119setup_prepare
120setup_wait
121
122ping_test $h1 198.51.100.2
123ping6_test $h1 2001:db8:2::2
124
125exit $EXIT_STATUS
diff --git a/tools/testing/selftests/net/forwarding/router_multipath.sh b/tools/testing/selftests/net/forwarding/router_multipath.sh
new file mode 100755
index 000000000000..3bc351008db6
--- /dev/null
+++ b/tools/testing/selftests/net/forwarding/router_multipath.sh
@@ -0,0 +1,376 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4NUM_NETIFS=8
5source lib.sh
6
7h1_create()
8{
9 vrf_create "vrf-h1"
10 ip link set dev $h1 master vrf-h1
11
12 ip link set dev vrf-h1 up
13 ip link set dev $h1 up
14
15 ip address add 192.0.2.2/24 dev $h1
16 ip address add 2001:db8:1::2/64 dev $h1
17
18 ip route add 198.51.100.0/24 vrf vrf-h1 nexthop via 192.0.2.1
19 ip route add 2001:db8:2::/64 vrf vrf-h1 nexthop via 2001:db8:1::1
20}
21
22h1_destroy()
23{
24 ip route del 2001:db8:2::/64 vrf vrf-h1
25 ip route del 198.51.100.0/24 vrf vrf-h1
26
27 ip address del 2001:db8:1::2/64 dev $h1
28 ip address del 192.0.2.2/24 dev $h1
29
30 ip link set dev $h1 down
31 vrf_destroy "vrf-h1"
32}
33
34h2_create()
35{
36 vrf_create "vrf-h2"
37 ip link set dev $h2 master vrf-h2
38
39 ip link set dev vrf-h2 up
40 ip link set dev $h2 up
41
42 ip address add 198.51.100.2/24 dev $h2
43 ip address add 2001:db8:2::2/64 dev $h2
44
45 ip route add 192.0.2.0/24 vrf vrf-h2 nexthop via 198.51.100.1
46 ip route add 2001:db8:1::/64 vrf vrf-h2 nexthop via 2001:db8:2::1
47}
48
49h2_destroy()
50{
51 ip route del 2001:db8:1::/64 vrf vrf-h2
52 ip route del 192.0.2.0/24 vrf vrf-h2
53
54 ip address del 2001:db8:2::2/64 dev $h2
55 ip address del 198.51.100.2/24 dev $h2
56
57 ip link set dev $h2 down
58 vrf_destroy "vrf-h2"
59}
60
61router1_create()
62{
63 vrf_create "vrf-r1"
64 ip link set dev $rp11 master vrf-r1
65 ip link set dev $rp12 master vrf-r1
66 ip link set dev $rp13 master vrf-r1
67
68 ip link set dev vrf-r1 up
69 ip link set dev $rp11 up
70 ip link set dev $rp12 up
71 ip link set dev $rp13 up
72
73 ip address add 192.0.2.1/24 dev $rp11
74 ip address add 2001:db8:1::1/64 dev $rp11
75
76 ip address add 169.254.2.12/24 dev $rp12
77 ip address add fe80:2::12/64 dev $rp12
78
79 ip address add 169.254.3.13/24 dev $rp13
80 ip address add fe80:3::13/64 dev $rp13
81
82 ip route add 198.51.100.0/24 vrf vrf-r1 \
83 nexthop via 169.254.2.22 dev $rp12 \
84 nexthop via 169.254.3.23 dev $rp13
85 ip route add 2001:db8:2::/64 vrf vrf-r1 \
86 nexthop via fe80:2::22 dev $rp12 \
87 nexthop via fe80:3::23 dev $rp13
88}
89
90router1_destroy()
91{
92 ip route del 2001:db8:2::/64 vrf vrf-r1
93 ip route del 198.51.100.0/24 vrf vrf-r1
94
95 ip address del fe80:3::13/64 dev $rp13
96 ip address del 169.254.3.13/24 dev $rp13
97
98 ip address del fe80:2::12/64 dev $rp12
99 ip address del 169.254.2.12/24 dev $rp12
100
101 ip address del 2001:db8:1::1/64 dev $rp11
102 ip address del 192.0.2.1/24 dev $rp11
103
104 ip link set dev $rp13 down
105 ip link set dev $rp12 down
106 ip link set dev $rp11 down
107
108 vrf_destroy "vrf-r1"
109}
110
111router2_create()
112{
113 vrf_create "vrf-r2"
114 ip link set dev $rp21 master vrf-r2
115 ip link set dev $rp22 master vrf-r2
116 ip link set dev $rp23 master vrf-r2
117
118 ip link set dev vrf-r2 up
119 ip link set dev $rp21 up
120 ip link set dev $rp22 up
121 ip link set dev $rp23 up
122
123 ip address add 198.51.100.1/24 dev $rp21
124 ip address add 2001:db8:2::1/64 dev $rp21
125
126 ip address add 169.254.2.22/24 dev $rp22
127 ip address add fe80:2::22/64 dev $rp22
128
129 ip address add 169.254.3.23/24 dev $rp23
130 ip address add fe80:3::23/64 dev $rp23
131
132 ip route add 192.0.2.0/24 vrf vrf-r2 \
133 nexthop via 169.254.2.12 dev $rp22 \
134 nexthop via 169.254.3.13 dev $rp23
135 ip route add 2001:db8:1::/64 vrf vrf-r2 \
136 nexthop via fe80:2::12 dev $rp22 \
137 nexthop via fe80:3::13 dev $rp23
138}
139
140router2_destroy()
141{
142 ip route del 2001:db8:1::/64 vrf vrf-r2
143 ip route del 192.0.2.0/24 vrf vrf-r2
144
145 ip address del fe80:3::23/64 dev $rp23
146 ip address del 169.254.3.23/24 dev $rp23
147
148 ip address del fe80:2::22/64 dev $rp22
149 ip address del 169.254.2.22/24 dev $rp22
150
151 ip address del 2001:db8:2::1/64 dev $rp21
152 ip address del 198.51.100.1/24 dev $rp21
153
154 ip link set dev $rp23 down
155 ip link set dev $rp22 down
156 ip link set dev $rp21 down
157
158 vrf_destroy "vrf-r2"
159}
160
161multipath_eval()
162{
163 local desc="$1"
164 local weight_rp12=$2
165 local weight_rp13=$3
166 local packets_rp12=$4
167 local packets_rp13=$5
168 local weights_ratio packets_ratio diff
169
170 RET=0
171
172 if [[ "$packets_rp12" -eq "0" || "$packets_rp13" -eq "0" ]]; then
173 check_err 1 "Packet difference is 0"
174 log_test "Multipath"
175 log_info "Expected ratio $weights_ratio"
176 return
177 fi
178
179 if [[ "$weight_rp12" -gt "$weight_rp13" ]]; then
180 weights_ratio=$(echo "scale=2; $weight_rp12 / $weight_rp13" \
181 | bc -l)
182 packets_ratio=$(echo "scale=2; $packets_rp12 / $packets_rp13" \
183 | bc -l)
184 else
185 weights_ratio=$(echo "scale=2; $weight_rp13 / $weight_rp12" | \
186 bc -l)
187 packets_ratio=$(echo "scale=2; $packets_rp13 / $packets_rp12" | \
188 bc -l)
189 fi
190
191 diff=$(echo $weights_ratio - $packets_ratio | bc -l)
192 diff=${diff#-}
193
194 test "$(echo "$diff / $weights_ratio > 0.1" | bc -l)" -eq 0
195 check_err $? "Too large discrepancy between expected and measured ratios"
196 log_test "$desc"
197 log_info "Expected ratio $weights_ratio Measured ratio $packets_ratio"
198}
199
200multipath4_test()
201{
202 local desc="$1"
203 local weight_rp12=$2
204 local weight_rp13=$3
205 local t0_rp12 t0_rp13 t1_rp12 t1_rp13
206 local packets_rp12 packets_rp13
207 local hash_policy
208
209 # Transmit multiple flows from h1 to h2 and make sure they are
210 # distributed between both multipath links (rp12 and rp13)
211 # according to the configured weights.
212 hash_policy=$(sysctl -n net.ipv4.fib_multipath_hash_policy)
213 sysctl -q -w net.ipv4.fib_multipath_hash_policy=1
214 ip route replace 198.51.100.0/24 vrf vrf-r1 \
215 nexthop via 169.254.2.22 dev $rp12 weight $weight_rp12 \
216 nexthop via 169.254.3.23 dev $rp13 weight $weight_rp13
217
218 t0_rp12=$(link_stats_tx_packets_get $rp12)
219 t0_rp13=$(link_stats_tx_packets_get $rp13)
220
221 ip vrf exec vrf-h1 $MZ -q -p 64 -A 192.0.2.2 -B 198.51.100.2 \
222 -d 1msec -t udp "sp=1024,dp=0-32768"
223
224 t1_rp12=$(link_stats_tx_packets_get $rp12)
225 t1_rp13=$(link_stats_tx_packets_get $rp13)
226
227 let "packets_rp12 = $t1_rp12 - $t0_rp12"
228 let "packets_rp13 = $t1_rp13 - $t0_rp13"
229 multipath_eval "$desc" $weight_rp12 $weight_rp13 $packets_rp12 $packets_rp13
230
231 # Restore settings.
232 ip route replace 198.51.100.0/24 vrf vrf-r1 \
233 nexthop via 169.254.2.22 dev $rp12 \
234 nexthop via 169.254.3.23 dev $rp13
235 sysctl -q -w net.ipv4.fib_multipath_hash_policy=$hash_policy
236}
237
238multipath6_l4_test()
239{
240 local desc="$1"
241 local weight_rp12=$2
242 local weight_rp13=$3
243 local t0_rp12 t0_rp13 t1_rp12 t1_rp13
244 local packets_rp12 packets_rp13
245 local hash_policy
246
247 # Transmit multiple flows from h1 to h2 and make sure they are
248 # distributed between both multipath links (rp12 and rp13)
249 # according to the configured weights.
250 hash_policy=$(sysctl -n net.ipv6.fib_multipath_hash_policy)
251 sysctl -q -w net.ipv6.fib_multipath_hash_policy=1
252
253 ip route replace 2001:db8:2::/64 vrf vrf-r1 \
254 nexthop via fe80:2::22 dev $rp12 weight $weight_rp12 \
255 nexthop via fe80:3::23 dev $rp13 weight $weight_rp13
256
257 t0_rp12=$(link_stats_tx_packets_get $rp12)
258 t0_rp13=$(link_stats_tx_packets_get $rp13)
259
260 $MZ $h1 -6 -q -p 64 -A 2001:db8:1::2 -B 2001:db8:2::2 \
261 -d 1msec -t udp "sp=1024,dp=0-32768"
262
263 t1_rp12=$(link_stats_tx_packets_get $rp12)
264 t1_rp13=$(link_stats_tx_packets_get $rp13)
265
266 let "packets_rp12 = $t1_rp12 - $t0_rp12"
267 let "packets_rp13 = $t1_rp13 - $t0_rp13"
268 multipath_eval "$desc" $weight_rp12 $weight_rp13 $packets_rp12 $packets_rp13
269
270 ip route replace 2001:db8:2::/64 vrf vrf-r1 \
271 nexthop via fe80:2::22 dev $rp12 \
272 nexthop via fe80:3::23 dev $rp13
273
274 sysctl -q -w net.ipv6.fib_multipath_hash_policy=$hash_policy
275}
276
277multipath6_test()
278{
279 local desc="$1"
280 local weight_rp12=$2
281 local weight_rp13=$3
282 local t0_rp12 t0_rp13 t1_rp12 t1_rp13
283 local packets_rp12 packets_rp13
284
285 ip route replace 2001:db8:2::/64 vrf vrf-r1 \
286 nexthop via fe80:2::22 dev $rp12 weight $weight_rp12 \
287 nexthop via fe80:3::23 dev $rp13 weight $weight_rp13
288
289 t0_rp12=$(link_stats_tx_packets_get $rp12)
290 t0_rp13=$(link_stats_tx_packets_get $rp13)
291
292 # Generate 16384 echo requests, each with a random flow label.
293 for _ in $(seq 1 16384); do
294 ip vrf exec vrf-h1 $PING6 2001:db8:2::2 -F 0 -c 1 -q &> /dev/null
295 done
296
297 t1_rp12=$(link_stats_tx_packets_get $rp12)
298 t1_rp13=$(link_stats_tx_packets_get $rp13)
299
300 let "packets_rp12 = $t1_rp12 - $t0_rp12"
301 let "packets_rp13 = $t1_rp13 - $t0_rp13"
302 multipath_eval "$desc" $weight_rp12 $weight_rp13 $packets_rp12 $packets_rp13
303
304 ip route replace 2001:db8:2::/64 vrf vrf-r1 \
305 nexthop via fe80:2::22 dev $rp12 \
306 nexthop via fe80:3::23 dev $rp13
307}
308
309multipath_test()
310{
311 log_info "Running IPv4 multipath tests"
312 multipath4_test "ECMP" 1 1
313 multipath4_test "Weighted MP 2:1" 2 1
314 multipath4_test "Weighted MP 11:45" 11 45
315
316 log_info "Running IPv6 multipath tests"
317 multipath6_test "ECMP" 1 1
318 multipath6_test "Weighted MP 2:1" 2 1
319 multipath6_test "Weighted MP 11:45" 11 45
320
321 log_info "Running IPv6 L4 hash multipath tests"
322 multipath6_l4_test "ECMP" 1 1
323 multipath6_l4_test "Weighted MP 2:1" 2 1
324 multipath6_l4_test "Weighted MP 11:45" 11 45
325}
326
327setup_prepare()
328{
329 h1=${NETIFS[p1]}
330 rp11=${NETIFS[p2]}
331
332 rp12=${NETIFS[p3]}
333 rp22=${NETIFS[p4]}
334
335 rp13=${NETIFS[p5]}
336 rp23=${NETIFS[p6]}
337
338 rp21=${NETIFS[p7]}
339 h2=${NETIFS[p8]}
340
341 vrf_prepare
342
343 h1_create
344 h2_create
345
346 router1_create
347 router2_create
348
349 forwarding_enable
350}
351
352cleanup()
353{
354 pre_cleanup
355
356 forwarding_restore
357
358 router2_destroy
359 router1_destroy
360
361 h2_destroy
362 h1_destroy
363
364 vrf_cleanup
365}
366
367trap cleanup EXIT
368
369setup_prepare
370setup_wait
371
372ping_test $h1 198.51.100.2
373ping6_test $h1 2001:db8:2::2
374multipath_test
375
376exit $EXIT_STATUS
diff --git a/tools/testing/selftests/net/forwarding/tc_actions.sh b/tools/testing/selftests/net/forwarding/tc_actions.sh
new file mode 100755
index 000000000000..3a6385ebd5d0
--- /dev/null
+++ b/tools/testing/selftests/net/forwarding/tc_actions.sh
@@ -0,0 +1,202 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4NUM_NETIFS=4
5source tc_common.sh
6source lib.sh
7
8tcflags="skip_hw"
9
10h1_create()
11{
12 simple_if_init $h1 192.0.2.1/24
13}
14
15h1_destroy()
16{
17 simple_if_fini $h1 192.0.2.1/24
18}
19
20h2_create()
21{
22 simple_if_init $h2 192.0.2.2/24
23 tc qdisc add dev $h2 clsact
24}
25
26h2_destroy()
27{
28 tc qdisc del dev $h2 clsact
29 simple_if_fini $h2 192.0.2.2/24
30}
31
32switch_create()
33{
34 simple_if_init $swp1 192.0.2.2/24
35 tc qdisc add dev $swp1 clsact
36
37 simple_if_init $swp2 192.0.2.1/24
38}
39
40switch_destroy()
41{
42 simple_if_fini $swp2 192.0.2.1/24
43
44 tc qdisc del dev $swp1 clsact
45 simple_if_fini $swp1 192.0.2.2/24
46}
47
48mirred_egress_test()
49{
50 local action=$1
51
52 RET=0
53
54 tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \
55 $tcflags dst_ip 192.0.2.2 action drop
56
57 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
58 -t ip -q
59
60 tc_check_packets "dev $h2 ingress" 101 1
61 check_fail $? "Matched without redirect rule inserted"
62
63 tc filter add dev $swp1 ingress protocol ip pref 1 handle 101 flower \
64 $tcflags dst_ip 192.0.2.2 action mirred egress $action \
65 dev $swp2
66
67 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
68 -t ip -q
69
70 tc_check_packets "dev $h2 ingress" 101 1
71 check_err $? "Did not match incoming $action packet"
72
73 tc filter del dev $swp1 ingress protocol ip pref 1 handle 101 flower
74 tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower
75
76 log_test "mirred egress $action ($tcflags)"
77}
78
79gact_drop_and_ok_test()
80{
81 RET=0
82
83 tc filter add dev $swp1 ingress protocol ip pref 2 handle 102 flower \
84 $tcflags dst_ip 192.0.2.2 action drop
85
86 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
87 -t ip -q
88
89 tc_check_packets "dev $swp1 ingress" 102 1
90 check_err $? "Packet was not dropped"
91
92 tc filter add dev $swp1 ingress protocol ip pref 1 handle 101 flower \
93 $tcflags dst_ip 192.0.2.2 action ok
94
95 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
96 -t ip -q
97
98 tc_check_packets "dev $swp1 ingress" 101 1
99 check_err $? "Did not see passed packet"
100
101 tc_check_packets "dev $swp1 ingress" 102 2
102 check_fail $? "Packet was dropped and it should not reach here"
103
104 tc filter del dev $swp1 ingress protocol ip pref 2 handle 102 flower
105 tc filter del dev $swp1 ingress protocol ip pref 1 handle 101 flower
106
107 log_test "gact drop and ok ($tcflags)"
108}
109
110gact_trap_test()
111{
112 RET=0
113
114 tc filter add dev $swp1 ingress protocol ip pref 1 handle 101 flower \
115 skip_hw dst_ip 192.0.2.2 action drop
116 tc filter add dev $swp1 ingress protocol ip pref 3 handle 103 flower \
117 $tcflags dst_ip 192.0.2.2 action mirred egress redirect \
118 dev $swp2
119
120 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
121 -t ip -q
122
123 tc_check_packets "dev $swp1 ingress" 101 1
124 check_fail $? "Saw packet without trap rule inserted"
125
126 tc filter add dev $swp1 ingress protocol ip pref 2 handle 102 flower \
127 $tcflags dst_ip 192.0.2.2 action trap
128
129 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
130 -t ip -q
131
132 tc_check_packets "dev $swp1 ingress" 102 1
133 check_err $? "Packet was not trapped"
134
135 tc_check_packets "dev $swp1 ingress" 101 1
136 check_err $? "Did not see trapped packet"
137
138 tc filter del dev $swp1 ingress protocol ip pref 3 handle 103 flower
139 tc filter del dev $swp1 ingress protocol ip pref 2 handle 102 flower
140 tc filter del dev $swp1 ingress protocol ip pref 1 handle 101 flower
141
142 log_test "trap ($tcflags)"
143}
144
145setup_prepare()
146{
147 h1=${NETIFS[p1]}
148 swp1=${NETIFS[p2]}
149
150 swp2=${NETIFS[p3]}
151 h2=${NETIFS[p4]}
152
153 h1mac=$(mac_get $h1)
154 h2mac=$(mac_get $h2)
155
156 swp1origmac=$(mac_get $swp1)
157 swp2origmac=$(mac_get $swp2)
158 ip link set $swp1 address $h2mac
159 ip link set $swp2 address $h1mac
160
161 vrf_prepare
162
163 h1_create
164 h2_create
165 switch_create
166}
167
168cleanup()
169{
170 pre_cleanup
171
172 switch_destroy
173 h2_destroy
174 h1_destroy
175
176 vrf_cleanup
177
178 ip link set $swp2 address $swp2origmac
179 ip link set $swp1 address $swp1origmac
180}
181
182trap cleanup EXIT
183
184setup_prepare
185setup_wait
186
187gact_drop_and_ok_test
188mirred_egress_test "redirect"
189mirred_egress_test "mirror"
190
191tc_offload_check
192if [[ $? -ne 0 ]]; then
193 log_info "Could not test offloaded functionality"
194else
195 tcflags="skip_sw"
196 gact_drop_and_ok_test
197 mirred_egress_test "redirect"
198 mirred_egress_test "mirror"
199 gact_trap_test
200fi
201
202exit $EXIT_STATUS
diff --git a/tools/testing/selftests/net/forwarding/tc_chains.sh b/tools/testing/selftests/net/forwarding/tc_chains.sh
new file mode 100755
index 000000000000..2fd15226974b
--- /dev/null
+++ b/tools/testing/selftests/net/forwarding/tc_chains.sh
@@ -0,0 +1,122 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4NUM_NETIFS=2
5source tc_common.sh
6source lib.sh
7
8tcflags="skip_hw"
9
10h1_create()
11{
12 simple_if_init $h1 192.0.2.1/24
13}
14
15h1_destroy()
16{
17 simple_if_fini $h1 192.0.2.1/24
18}
19
20h2_create()
21{
22 simple_if_init $h2 192.0.2.2/24
23 tc qdisc add dev $h2 clsact
24}
25
26h2_destroy()
27{
28 tc qdisc del dev $h2 clsact
29 simple_if_fini $h2 192.0.2.2/24
30}
31
32unreachable_chain_test()
33{
34 RET=0
35
36 tc filter add dev $h2 ingress chain 1 protocol ip pref 1 handle 1101 \
37 flower $tcflags dst_mac $h2mac action drop
38
39 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
40 -t ip -q
41
42 tc_check_packets "dev $h2 ingress" 1101 1
43 check_fail $? "matched on filter in unreachable chain"
44
45 tc filter del dev $h2 ingress chain 1 protocol ip pref 1 handle 1101 \
46 flower
47
48 log_test "unreachable chain ($tcflags)"
49}
50
51gact_goto_chain_test()
52{
53 RET=0
54
55 tc filter add dev $h2 ingress chain 1 protocol ip pref 1 handle 1101 \
56 flower $tcflags dst_mac $h2mac action drop
57 tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \
58 $tcflags dst_mac $h2mac action drop
59 tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \
60 $tcflags dst_mac $h2mac action goto chain 1
61
62 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
63 -t ip -q
64
65 tc_check_packets "dev $h2 ingress" 102 1
66 check_fail $? "Matched on a wrong filter"
67
68 tc_check_packets "dev $h2 ingress" 101 1
69 check_err $? "Did not match on correct filter with goto chain action"
70
71 tc_check_packets "dev $h2 ingress" 1101 1
72 check_err $? "Did not match on correct filter in chain 1"
73
74 tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower
75 tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower
76 tc filter del dev $h2 ingress chain 1 protocol ip pref 1 handle 1101 \
77 flower
78
79 log_test "gact goto chain ($tcflags)"
80}
81
82setup_prepare()
83{
84 h1=${NETIFS[p1]}
85 h2=${NETIFS[p2]}
86 h1mac=$(mac_get $h1)
87 h2mac=$(mac_get $h2)
88
89 vrf_prepare
90
91 h1_create
92 h2_create
93}
94
95cleanup()
96{
97 pre_cleanup
98
99 h2_destroy
100 h1_destroy
101
102 vrf_cleanup
103}
104
105trap cleanup EXIT
106
107setup_prepare
108setup_wait
109
110unreachable_chain_test
111gact_goto_chain_test
112
113tc_offload_check
114if [[ $? -ne 0 ]]; then
115 log_info "Could not test offloaded functionality"
116else
117 tcflags="skip_sw"
118 unreachable_chain_test
119 gact_goto_chain_test
120fi
121
122exit $EXIT_STATUS
diff --git a/tools/testing/selftests/net/forwarding/tc_common.sh b/tools/testing/selftests/net/forwarding/tc_common.sh
new file mode 100644
index 000000000000..9d3b64a2a264
--- /dev/null
+++ b/tools/testing/selftests/net/forwarding/tc_common.sh
@@ -0,0 +1,25 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4CHECK_TC="yes"
5
6tc_check_packets()
7{
8 local id=$1
9 local handle=$2
10 local count=$3
11 local ret
12
13 output="$(tc -j -s filter show $id)"
14 # workaround the jq bug which causes jq to return 0 in case input is ""
15 ret=$?
16 if [[ $ret -ne 0 ]]; then
17 return $ret
18 fi
19 echo $output | \
20 jq -e ".[] \
21 | select(.options.handle == $handle) \
22 | select(.options.actions[0].stats.packets == $count)" \
23 &> /dev/null
24 return $?
25}
diff --git a/tools/testing/selftests/net/forwarding/tc_flower.sh b/tools/testing/selftests/net/forwarding/tc_flower.sh
new file mode 100755
index 000000000000..032b882adfc0
--- /dev/null
+++ b/tools/testing/selftests/net/forwarding/tc_flower.sh
@@ -0,0 +1,196 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4NUM_NETIFS=2
5source tc_common.sh
6source lib.sh
7
8tcflags="skip_hw"
9
10h1_create()
11{
12 simple_if_init $h1 192.0.2.1/24 198.51.100.1/24
13}
14
15h1_destroy()
16{
17 simple_if_fini $h1 192.0.2.1/24 198.51.100.1/24
18}
19
20h2_create()
21{
22 simple_if_init $h2 192.0.2.2/24 198.51.100.2/24
23 tc qdisc add dev $h2 clsact
24}
25
26h2_destroy()
27{
28 tc qdisc del dev $h2 clsact
29 simple_if_fini $h2 192.0.2.2/24 198.51.100.2/24
30}
31
32match_dst_mac_test()
33{
34 local dummy_mac=de:ad:be:ef:aa:aa
35
36 RET=0
37
38 tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \
39 $tcflags dst_mac $dummy_mac action drop
40 tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \
41 $tcflags dst_mac $h2mac action drop
42
43 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
44 -t ip -q
45
46 tc_check_packets "dev $h2 ingress" 101 1
47 check_fail $? "Matched on a wrong filter"
48
49 tc_check_packets "dev $h2 ingress" 102 1
50 check_err $? "Did not match on correct filter"
51
52 tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower
53 tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower
54
55 log_test "dst_mac match ($tcflags)"
56}
57
58match_src_mac_test()
59{
60 local dummy_mac=de:ad:be:ef:aa:aa
61
62 RET=0
63
64 tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \
65 $tcflags src_mac $dummy_mac action drop
66 tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \
67 $tcflags src_mac $h1mac action drop
68
69 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
70 -t ip -q
71
72 tc_check_packets "dev $h2 ingress" 101 1
73 check_fail $? "Matched on a wrong filter"
74
75 tc_check_packets "dev $h2 ingress" 102 1
76 check_err $? "Did not match on correct filter"
77
78 tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower
79 tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower
80
81 log_test "src_mac match ($tcflags)"
82}
83
84match_dst_ip_test()
85{
86 RET=0
87
88 tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \
89 $tcflags dst_ip 198.51.100.2 action drop
90 tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \
91 $tcflags dst_ip 192.0.2.2 action drop
92 tc filter add dev $h2 ingress protocol ip pref 3 handle 103 flower \
93 $tcflags dst_ip 192.0.2.0/24 action drop
94
95 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
96 -t ip -q
97
98 tc_check_packets "dev $h2 ingress" 101 1
99 check_fail $? "Matched on a wrong filter"
100
101 tc_check_packets "dev $h2 ingress" 102 1
102 check_err $? "Did not match on correct filter"
103
104 tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower
105
106 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
107 -t ip -q
108
109 tc_check_packets "dev $h2 ingress" 103 1
110 check_err $? "Did not match on correct filter with mask"
111
112 tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower
113 tc filter del dev $h2 ingress protocol ip pref 3 handle 103 flower
114
115 log_test "dst_ip match ($tcflags)"
116}
117
118match_src_ip_test()
119{
120 RET=0
121
122 tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \
123 $tcflags src_ip 198.51.100.1 action drop
124 tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \
125 $tcflags src_ip 192.0.2.1 action drop
126 tc filter add dev $h2 ingress protocol ip pref 3 handle 103 flower \
127 $tcflags src_ip 192.0.2.0/24 action drop
128
129 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
130 -t ip -q
131
132 tc_check_packets "dev $h2 ingress" 101 1
133 check_fail $? "Matched on a wrong filter"
134
135 tc_check_packets "dev $h2 ingress" 102 1
136 check_err $? "Did not match on correct filter"
137
138 tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower
139
140 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
141 -t ip -q
142
143 tc_check_packets "dev $h2 ingress" 103 1
144 check_err $? "Did not match on correct filter with mask"
145
146 tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower
147 tc filter del dev $h2 ingress protocol ip pref 3 handle 103 flower
148
149 log_test "src_ip match ($tcflags)"
150}
151
152setup_prepare()
153{
154 h1=${NETIFS[p1]}
155 h2=${NETIFS[p2]}
156 h1mac=$(mac_get $h1)
157 h2mac=$(mac_get $h2)
158
159 vrf_prepare
160
161 h1_create
162 h2_create
163}
164
165cleanup()
166{
167 pre_cleanup
168
169 h2_destroy
170 h1_destroy
171
172 vrf_cleanup
173}
174
175trap cleanup EXIT
176
177setup_prepare
178setup_wait
179
180match_dst_mac_test
181match_src_mac_test
182match_dst_ip_test
183match_src_ip_test
184
185tc_offload_check
186if [[ $? -ne 0 ]]; then
187 log_info "Could not test offloaded functionality"
188else
189 tcflags="skip_sw"
190 match_dst_mac_test
191 match_src_mac_test
192 match_dst_ip_test
193 match_src_ip_test
194fi
195
196exit $EXIT_STATUS
diff --git a/tools/testing/selftests/net/forwarding/tc_shblocks.sh b/tools/testing/selftests/net/forwarding/tc_shblocks.sh
new file mode 100755
index 000000000000..077b98048ef4
--- /dev/null
+++ b/tools/testing/selftests/net/forwarding/tc_shblocks.sh
@@ -0,0 +1,122 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4NUM_NETIFS=4
5source tc_common.sh
6source lib.sh
7
8tcflags="skip_hw"
9
10h1_create()
11{
12 simple_if_init $h1 192.0.2.1/24
13}
14
15h1_destroy()
16{
17 simple_if_fini $h1 192.0.2.1/24
18}
19
20h2_create()
21{
22 simple_if_init $h2 192.0.2.1/24
23}
24
25h2_destroy()
26{
27 simple_if_fini $h2 192.0.2.1/24
28}
29
30switch_create()
31{
32 simple_if_init $swp1 192.0.2.2/24
33 tc qdisc add dev $swp1 ingress_block 22 egress_block 23 clsact
34
35 simple_if_init $swp2 192.0.2.2/24
36 tc qdisc add dev $swp2 ingress_block 22 egress_block 23 clsact
37}
38
39switch_destroy()
40{
41 tc qdisc del dev $swp2 clsact
42 simple_if_fini $swp2 192.0.2.2/24
43
44 tc qdisc del dev $swp1 clsact
45 simple_if_fini $swp1 192.0.2.2/24
46}
47
48shared_block_test()
49{
50 RET=0
51
52 tc filter add block 22 protocol ip pref 1 handle 101 flower \
53 $tcflags dst_ip 192.0.2.2 action drop
54
55 $MZ $h1 -c 1 -p 64 -a $h1mac -b $swmac -A 192.0.2.1 -B 192.0.2.2 \
56 -t ip -q
57
58 tc_check_packets "block 22" 101 1
59 check_err $? "Did not match first incoming packet on a block"
60
61 $MZ $h2 -c 1 -p 64 -a $h2mac -b $swmac -A 192.0.2.1 -B 192.0.2.2 \
62 -t ip -q
63
64 tc_check_packets "block 22" 101 2
65 check_err $? "Did not match second incoming packet on a block"
66
67 tc filter del block 22 protocol ip pref 1 handle 101 flower
68
69 log_test "shared block ($tcflags)"
70}
71
72setup_prepare()
73{
74 h1=${NETIFS[p1]}
75 swp1=${NETIFS[p2]}
76
77 swp2=${NETIFS[p3]}
78 h2=${NETIFS[p4]}
79
80 h1mac=$(mac_get $h1)
81 h2mac=$(mac_get $h2)
82
83 swmac=$(mac_get $swp1)
84 swp2origmac=$(mac_get $swp2)
85 ip link set $swp2 address $swmac
86
87 vrf_prepare
88
89 h1_create
90 h2_create
91 switch_create
92}
93
94cleanup()
95{
96 pre_cleanup
97
98 switch_destroy
99 h2_destroy
100 h1_destroy
101
102 vrf_cleanup
103
104 ip link set $swp2 address $swp2origmac
105}
106
107trap cleanup EXIT
108
109setup_prepare
110setup_wait
111
112shared_block_test
113
114tc_offload_check
115if [[ $? -ne 0 ]]; then
116 log_info "Could not test offloaded functionality"
117else
118 tcflags="skip_sw"
119 shared_block_test
120fi
121
122exit $EXIT_STATUS
diff --git a/tools/testing/selftests/net/in_netns.sh b/tools/testing/selftests/net/in_netns.sh
new file mode 100755
index 000000000000..88795b510b32
--- /dev/null
+++ b/tools/testing/selftests/net/in_netns.sh
@@ -0,0 +1,23 @@
1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0
3#
4# Execute a subprocess in a network namespace
5
6set -e
7
8readonly NETNS="ns-$(mktemp -u XXXXXX)"
9
10setup() {
11 ip netns add "${NETNS}"
12 ip -netns "${NETNS}" link set lo up
13}
14
15cleanup() {
16 ip netns del "${NETNS}"
17}
18
19trap cleanup EXIT
20setup
21
22ip netns exec "${NETNS}" "$@"
23exit "$?"
diff --git a/tools/testing/selftests/net/msg_zerocopy.c b/tools/testing/selftests/net/msg_zerocopy.c
index e11fe84de0fd..406cc70c571d 100644
--- a/tools/testing/selftests/net/msg_zerocopy.c
+++ b/tools/testing/selftests/net/msg_zerocopy.c
@@ -14,6 +14,9 @@
14 * - SOCK_DGRAM 14 * - SOCK_DGRAM
15 * - SOCK_RAW 15 * - SOCK_RAW
16 * 16 *
17 * PF_RDS
18 * - SOCK_SEQPACKET
19 *
17 * Start this program on two connected hosts, one in send mode and 20 * Start this program on two connected hosts, one in send mode and
18 * the other with option '-r' to put it in receiver mode. 21 * the other with option '-r' to put it in receiver mode.
19 * 22 *
@@ -53,6 +56,7 @@
53#include <sys/types.h> 56#include <sys/types.h>
54#include <sys/wait.h> 57#include <sys/wait.h>
55#include <unistd.h> 58#include <unistd.h>
59#include <linux/rds.h>
56 60
57#ifndef SO_EE_ORIGIN_ZEROCOPY 61#ifndef SO_EE_ORIGIN_ZEROCOPY
58#define SO_EE_ORIGIN_ZEROCOPY 5 62#define SO_EE_ORIGIN_ZEROCOPY 5
@@ -164,17 +168,39 @@ static int do_accept(int fd)
164 return fd; 168 return fd;
165} 169}
166 170
167static bool do_sendmsg(int fd, struct msghdr *msg, bool do_zerocopy) 171static void add_zcopy_cookie(struct msghdr *msg, uint32_t cookie)
172{
173 struct cmsghdr *cm;
174
175 if (!msg->msg_control)
176 error(1, errno, "NULL cookie");
177 cm = (void *)msg->msg_control;
178 cm->cmsg_len = CMSG_LEN(sizeof(cookie));
179 cm->cmsg_level = SOL_RDS;
180 cm->cmsg_type = RDS_CMSG_ZCOPY_COOKIE;
181 memcpy(CMSG_DATA(cm), &cookie, sizeof(cookie));
182}
183
184static bool do_sendmsg(int fd, struct msghdr *msg, bool do_zerocopy, int domain)
168{ 185{
169 int ret, len, i, flags; 186 int ret, len, i, flags;
187 static uint32_t cookie;
188 char ckbuf[CMSG_SPACE(sizeof(cookie))];
170 189
171 len = 0; 190 len = 0;
172 for (i = 0; i < msg->msg_iovlen; i++) 191 for (i = 0; i < msg->msg_iovlen; i++)
173 len += msg->msg_iov[i].iov_len; 192 len += msg->msg_iov[i].iov_len;
174 193
175 flags = MSG_DONTWAIT; 194 flags = MSG_DONTWAIT;
176 if (do_zerocopy) 195 if (do_zerocopy) {
177 flags |= MSG_ZEROCOPY; 196 flags |= MSG_ZEROCOPY;
197 if (domain == PF_RDS) {
198 memset(&msg->msg_control, 0, sizeof(msg->msg_control));
199 msg->msg_controllen = CMSG_SPACE(sizeof(cookie));
200 msg->msg_control = (struct cmsghdr *)ckbuf;
201 add_zcopy_cookie(msg, ++cookie);
202 }
203 }
178 204
179 ret = sendmsg(fd, msg, flags); 205 ret = sendmsg(fd, msg, flags);
180 if (ret == -1 && errno == EAGAIN) 206 if (ret == -1 && errno == EAGAIN)
@@ -190,6 +216,10 @@ static bool do_sendmsg(int fd, struct msghdr *msg, bool do_zerocopy)
190 if (do_zerocopy && ret) 216 if (do_zerocopy && ret)
191 expected_completions++; 217 expected_completions++;
192 } 218 }
219 if (do_zerocopy && domain == PF_RDS) {
220 msg->msg_control = NULL;
221 msg->msg_controllen = 0;
222 }
193 223
194 return true; 224 return true;
195} 225}
@@ -216,7 +246,9 @@ static void do_sendmsg_corked(int fd, struct msghdr *msg)
216 msg->msg_iov[0].iov_len = payload_len + extra_len; 246 msg->msg_iov[0].iov_len = payload_len + extra_len;
217 extra_len = 0; 247 extra_len = 0;
218 248
219 do_sendmsg(fd, msg, do_zerocopy); 249 do_sendmsg(fd, msg, do_zerocopy,
250 (cfg_dst_addr.ss_family == AF_INET ?
251 PF_INET : PF_INET6));
220 } 252 }
221 253
222 do_setsockopt(fd, IPPROTO_UDP, UDP_CORK, 0); 254 do_setsockopt(fd, IPPROTO_UDP, UDP_CORK, 0);
@@ -300,14 +332,65 @@ static int do_setup_tx(int domain, int type, int protocol)
300 if (cfg_zerocopy) 332 if (cfg_zerocopy)
301 do_setsockopt(fd, SOL_SOCKET, SO_ZEROCOPY, 1); 333 do_setsockopt(fd, SOL_SOCKET, SO_ZEROCOPY, 1);
302 334
303 if (domain != PF_PACKET) 335 if (domain != PF_PACKET && domain != PF_RDS)
304 if (connect(fd, (void *) &cfg_dst_addr, cfg_alen)) 336 if (connect(fd, (void *) &cfg_dst_addr, cfg_alen))
305 error(1, errno, "connect"); 337 error(1, errno, "connect");
306 338
339 if (domain == PF_RDS) {
340 if (bind(fd, (void *) &cfg_src_addr, cfg_alen))
341 error(1, errno, "bind");
342 }
343
307 return fd; 344 return fd;
308} 345}
309 346
310static bool do_recv_completion(int fd) 347static uint32_t do_process_zerocopy_cookies(struct rds_zcopy_cookies *ck)
348{
349 int i;
350
351 if (ck->num > RDS_MAX_ZCOOKIES)
352 error(1, 0, "Returned %d cookies, max expected %d\n",
353 ck->num, RDS_MAX_ZCOOKIES);
354 for (i = 0; i < ck->num; i++)
355 if (cfg_verbose >= 2)
356 fprintf(stderr, "%d\n", ck->cookies[i]);
357 return ck->num;
358}
359
360static bool do_recvmsg_completion(int fd)
361{
362 char cmsgbuf[CMSG_SPACE(sizeof(struct rds_zcopy_cookies))];
363 struct rds_zcopy_cookies *ck;
364 struct cmsghdr *cmsg;
365 struct msghdr msg;
366 bool ret = false;
367
368 memset(&msg, 0, sizeof(msg));
369 msg.msg_control = cmsgbuf;
370 msg.msg_controllen = sizeof(cmsgbuf);
371
372 if (recvmsg(fd, &msg, MSG_DONTWAIT))
373 return ret;
374
375 if (msg.msg_flags & MSG_CTRUNC)
376 error(1, errno, "recvmsg notification: truncated");
377
378 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
379 if (cmsg->cmsg_level == SOL_RDS &&
380 cmsg->cmsg_type == RDS_CMSG_ZCOPY_COMPLETION) {
381
382 ck = (struct rds_zcopy_cookies *)CMSG_DATA(cmsg);
383 completions += do_process_zerocopy_cookies(ck);
384 ret = true;
385 break;
386 }
387 error(0, 0, "ignoring cmsg at level %d type %d\n",
388 cmsg->cmsg_level, cmsg->cmsg_type);
389 }
390 return ret;
391}
392
393static bool do_recv_completion(int fd, int domain)
311{ 394{
312 struct sock_extended_err *serr; 395 struct sock_extended_err *serr;
313 struct msghdr msg = {}; 396 struct msghdr msg = {};
@@ -316,6 +399,9 @@ static bool do_recv_completion(int fd)
316 int ret, zerocopy; 399 int ret, zerocopy;
317 char control[100]; 400 char control[100];
318 401
402 if (domain == PF_RDS)
403 return do_recvmsg_completion(fd);
404
319 msg.msg_control = control; 405 msg.msg_control = control;
320 msg.msg_controllen = sizeof(control); 406 msg.msg_controllen = sizeof(control);
321 407
@@ -337,6 +423,7 @@ static bool do_recv_completion(int fd)
337 cm->cmsg_level, cm->cmsg_type); 423 cm->cmsg_level, cm->cmsg_type);
338 424
339 serr = (void *) CMSG_DATA(cm); 425 serr = (void *) CMSG_DATA(cm);
426
340 if (serr->ee_origin != SO_EE_ORIGIN_ZEROCOPY) 427 if (serr->ee_origin != SO_EE_ORIGIN_ZEROCOPY)
341 error(1, 0, "serr: wrong origin: %u", serr->ee_origin); 428 error(1, 0, "serr: wrong origin: %u", serr->ee_origin);
342 if (serr->ee_errno != 0) 429 if (serr->ee_errno != 0)
@@ -371,20 +458,20 @@ static bool do_recv_completion(int fd)
371} 458}
372 459
373/* Read all outstanding messages on the errqueue */ 460/* Read all outstanding messages on the errqueue */
374static void do_recv_completions(int fd) 461static void do_recv_completions(int fd, int domain)
375{ 462{
376 while (do_recv_completion(fd)) {} 463 while (do_recv_completion(fd, domain)) {}
377} 464}
378 465
379/* Wait for all remaining completions on the errqueue */ 466/* Wait for all remaining completions on the errqueue */
380static void do_recv_remaining_completions(int fd) 467static void do_recv_remaining_completions(int fd, int domain)
381{ 468{
382 int64_t tstop = gettimeofday_ms() + cfg_waittime_ms; 469 int64_t tstop = gettimeofday_ms() + cfg_waittime_ms;
383 470
384 while (completions < expected_completions && 471 while (completions < expected_completions &&
385 gettimeofday_ms() < tstop) { 472 gettimeofday_ms() < tstop) {
386 if (do_poll(fd, POLLERR)) 473 if (do_poll(fd, domain == PF_RDS ? POLLIN : POLLERR))
387 do_recv_completions(fd); 474 do_recv_completions(fd, domain);
388 } 475 }
389 476
390 if (completions < expected_completions) 477 if (completions < expected_completions)
@@ -444,6 +531,13 @@ static void do_tx(int domain, int type, int protocol)
444 msg.msg_iovlen++; 531 msg.msg_iovlen++;
445 } 532 }
446 533
534 if (domain == PF_RDS) {
535 msg.msg_name = &cfg_dst_addr;
536 msg.msg_namelen = (cfg_dst_addr.ss_family == AF_INET ?
537 sizeof(struct sockaddr_in) :
538 sizeof(struct sockaddr_in6));
539 }
540
447 iov[2].iov_base = payload; 541 iov[2].iov_base = payload;
448 iov[2].iov_len = cfg_payload_len; 542 iov[2].iov_len = cfg_payload_len;
449 msg.msg_iovlen++; 543 msg.msg_iovlen++;
@@ -454,17 +548,17 @@ static void do_tx(int domain, int type, int protocol)
454 if (cfg_cork) 548 if (cfg_cork)
455 do_sendmsg_corked(fd, &msg); 549 do_sendmsg_corked(fd, &msg);
456 else 550 else
457 do_sendmsg(fd, &msg, cfg_zerocopy); 551 do_sendmsg(fd, &msg, cfg_zerocopy, domain);
458 552
459 while (!do_poll(fd, POLLOUT)) { 553 while (!do_poll(fd, POLLOUT)) {
460 if (cfg_zerocopy) 554 if (cfg_zerocopy)
461 do_recv_completions(fd); 555 do_recv_completions(fd, domain);
462 } 556 }
463 557
464 } while (gettimeofday_ms() < tstop); 558 } while (gettimeofday_ms() < tstop);
465 559
466 if (cfg_zerocopy) 560 if (cfg_zerocopy)
467 do_recv_remaining_completions(fd); 561 do_recv_remaining_completions(fd, domain);
468 562
469 if (close(fd)) 563 if (close(fd))
470 error(1, errno, "close"); 564 error(1, errno, "close");
@@ -610,6 +704,7 @@ static void parse_opts(int argc, char **argv)
610 40 /* max tcp options */; 704 40 /* max tcp options */;
611 int c; 705 int c;
612 char *daddr = NULL, *saddr = NULL; 706 char *daddr = NULL, *saddr = NULL;
707 char *cfg_test;
613 708
614 cfg_payload_len = max_payload_len; 709 cfg_payload_len = max_payload_len;
615 710
@@ -667,6 +762,14 @@ static void parse_opts(int argc, char **argv)
667 break; 762 break;
668 } 763 }
669 } 764 }
765
766 cfg_test = argv[argc - 1];
767 if (strcmp(cfg_test, "rds") == 0) {
768 if (!daddr)
769 error(1, 0, "-D <server addr> required for PF_RDS\n");
770 if (!cfg_rx && !saddr)
771 error(1, 0, "-S <client addr> required for PF_RDS\n");
772 }
670 setup_sockaddr(cfg_family, daddr, &cfg_dst_addr); 773 setup_sockaddr(cfg_family, daddr, &cfg_dst_addr);
671 setup_sockaddr(cfg_family, saddr, &cfg_src_addr); 774 setup_sockaddr(cfg_family, saddr, &cfg_src_addr);
672 775
@@ -699,6 +802,8 @@ int main(int argc, char **argv)
699 do_test(cfg_family, SOCK_STREAM, 0); 802 do_test(cfg_family, SOCK_STREAM, 0);
700 else if (!strcmp(cfg_test, "udp")) 803 else if (!strcmp(cfg_test, "udp"))
701 do_test(cfg_family, SOCK_DGRAM, 0); 804 do_test(cfg_family, SOCK_DGRAM, 0);
805 else if (!strcmp(cfg_test, "rds"))
806 do_test(PF_RDS, SOCK_SEQPACKET, 0);
702 else 807 else
703 error(1, 0, "unknown cfg_test %s", cfg_test); 808 error(1, 0, "unknown cfg_test %s", cfg_test);
704 809
diff --git a/tools/testing/selftests/net/pmtu.sh b/tools/testing/selftests/net/pmtu.sh
new file mode 100755
index 000000000000..1e428781a625
--- /dev/null
+++ b/tools/testing/selftests/net/pmtu.sh
@@ -0,0 +1,471 @@
1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0
3#
4# Check that route PMTU values match expectations, and that initial device MTU
5# values are assigned correctly
6#
7# Tests currently implemented:
8#
9# - pmtu_vti4_exception
10# Set up vti tunnel on top of veth, with xfrm states and policies, in two
11# namespaces with matching endpoints. Check that route exception is not
12# created if link layer MTU is not exceeded, then exceed it and check that
13# exception is created with the expected PMTU. The approach described
14# below for IPv6 doesn't apply here, because, on IPv4, administrative MTU
15# changes alone won't affect PMTU
16#
17# - pmtu_vti6_exception
18# Set up vti6 tunnel on top of veth, with xfrm states and policies, in two
19# namespaces with matching endpoints. Check that route exception is
20# created by exceeding link layer MTU with ping to other endpoint. Then
21# decrease and increase MTU of tunnel, checking that route exception PMTU
22# changes accordingly
23#
24# - pmtu_vti4_default_mtu
25# Set up vti4 tunnel on top of veth, in two namespaces with matching
26# endpoints. Check that MTU assigned to vti interface is the MTU of the
27# lower layer (veth) minus additional lower layer headers (zero, for veth)
28# minus IPv4 header length
29#
30# - pmtu_vti6_default_mtu
31# Same as above, for IPv6
32#
33# - pmtu_vti4_link_add_mtu
34# Set up vti4 interface passing MTU value at link creation, check MTU is
35# configured, and that link is not created with invalid MTU values
36#
37# - pmtu_vti6_link_add_mtu
38# Same as above, for IPv6
39#
40# - pmtu_vti6_link_change_mtu
41# Set up two dummy interfaces with different MTUs, create a vti6 tunnel
42# and check that configured MTU is used on link creation and changes, and
43# that MTU is properly calculated instead when MTU is not configured from
44# userspace
45
46tests="
47 pmtu_vti6_exception vti6: PMTU exceptions
48 pmtu_vti4_exception vti4: PMTU exceptions
49 pmtu_vti4_default_mtu vti4: default MTU assignment
50 pmtu_vti6_default_mtu vti6: default MTU assignment
51 pmtu_vti4_link_add_mtu vti4: MTU setting on link creation
52 pmtu_vti6_link_add_mtu vti6: MTU setting on link creation
53 pmtu_vti6_link_change_mtu vti6: MTU changes on link changes"
54
55NS_A="ns-$(mktemp -u XXXXXX)"
56NS_B="ns-$(mktemp -u XXXXXX)"
57ns_a="ip netns exec ${NS_A}"
58ns_b="ip netns exec ${NS_B}"
59
60veth4_a_addr="192.168.1.1"
61veth4_b_addr="192.168.1.2"
62veth4_mask="24"
63veth6_a_addr="fd00:1::a"
64veth6_b_addr="fd00:1::b"
65veth6_mask="64"
66
67vti4_a_addr="192.168.2.1"
68vti4_b_addr="192.168.2.2"
69vti4_mask="24"
70vti6_a_addr="fd00:2::a"
71vti6_b_addr="fd00:2::b"
72vti6_mask="64"
73
74dummy6_0_addr="fc00:1000::0"
75dummy6_1_addr="fc00:1001::0"
76dummy6_mask="64"
77
78cleanup_done=1
79err_buf=
80
81err() {
82 err_buf="${err_buf}${1}
83"
84}
85
86err_flush() {
87 echo -n "${err_buf}"
88 err_buf=
89}
90
91setup_namespaces() {
92 ip netns add ${NS_A} || return 1
93 ip netns add ${NS_B}
94}
95
96setup_veth() {
97 ${ns_a} ip link add veth_a type veth peer name veth_b || return 1
98 ${ns_a} ip link set veth_b netns ${NS_B}
99
100 ${ns_a} ip addr add ${veth4_a_addr}/${veth4_mask} dev veth_a
101 ${ns_b} ip addr add ${veth4_b_addr}/${veth4_mask} dev veth_b
102
103 ${ns_a} ip addr add ${veth6_a_addr}/${veth6_mask} dev veth_a
104 ${ns_b} ip addr add ${veth6_b_addr}/${veth6_mask} dev veth_b
105
106 ${ns_a} ip link set veth_a up
107 ${ns_b} ip link set veth_b up
108}
109
110setup_vti() {
111 proto=${1}
112 veth_a_addr="${2}"
113 veth_b_addr="${3}"
114 vti_a_addr="${4}"
115 vti_b_addr="${5}"
116 vti_mask=${6}
117
118 [ ${proto} -eq 6 ] && vti_type="vti6" || vti_type="vti"
119
120 ${ns_a} ip link add vti${proto}_a type ${vti_type} local ${veth_a_addr} remote ${veth_b_addr} key 10 || return 1
121 ${ns_b} ip link add vti${proto}_b type ${vti_type} local ${veth_b_addr} remote ${veth_a_addr} key 10
122
123 ${ns_a} ip addr add ${vti_a_addr}/${vti_mask} dev vti${proto}_a
124 ${ns_b} ip addr add ${vti_b_addr}/${vti_mask} dev vti${proto}_b
125
126 ${ns_a} ip link set vti${proto}_a up
127 ${ns_b} ip link set vti${proto}_b up
128
129 sleep 1
130}
131
132setup_vti4() {
133 setup_vti 4 ${veth4_a_addr} ${veth4_b_addr} ${vti4_a_addr} ${vti4_b_addr} ${vti4_mask}
134}
135
136setup_vti6() {
137 setup_vti 6 ${veth6_a_addr} ${veth6_b_addr} ${vti6_a_addr} ${vti6_b_addr} ${vti6_mask}
138}
139
140setup_xfrm() {
141 proto=${1}
142 veth_a_addr="${2}"
143 veth_b_addr="${3}"
144
145 ${ns_a} ip -${proto} xfrm state add src ${veth_a_addr} dst ${veth_b_addr} spi 0x1000 proto esp aead "rfc4106(gcm(aes))" 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f 128 mode tunnel || return 1
146 ${ns_a} ip -${proto} xfrm state add src ${veth_b_addr} dst ${veth_a_addr} spi 0x1001 proto esp aead "rfc4106(gcm(aes))" 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f 128 mode tunnel
147 ${ns_a} ip -${proto} xfrm policy add dir out mark 10 tmpl src ${veth_a_addr} dst ${veth_b_addr} proto esp mode tunnel
148 ${ns_a} ip -${proto} xfrm policy add dir in mark 10 tmpl src ${veth_b_addr} dst ${veth_a_addr} proto esp mode tunnel
149
150 ${ns_b} ip -${proto} xfrm state add src ${veth_a_addr} dst ${veth_b_addr} spi 0x1000 proto esp aead "rfc4106(gcm(aes))" 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f 128 mode tunnel
151 ${ns_b} ip -${proto} xfrm state add src ${veth_b_addr} dst ${veth_a_addr} spi 0x1001 proto esp aead "rfc4106(gcm(aes))" 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f 128 mode tunnel
152 ${ns_b} ip -${proto} xfrm policy add dir out mark 10 tmpl src ${veth_b_addr} dst ${veth_a_addr} proto esp mode tunnel
153 ${ns_b} ip -${proto} xfrm policy add dir in mark 10 tmpl src ${veth_a_addr} dst ${veth_b_addr} proto esp mode tunnel
154}
155
156setup_xfrm4() {
157 setup_xfrm 4 ${veth4_a_addr} ${veth4_b_addr}
158}
159
160setup_xfrm6() {
161 setup_xfrm 6 ${veth6_a_addr} ${veth6_b_addr}
162}
163
164setup() {
165 [ "$(id -u)" -ne 0 ] && echo " need to run as root" && return 1
166
167 cleanup_done=0
168 for arg do
169 eval setup_${arg} || { echo " ${arg} not supported"; return 1; }
170 done
171}
172
173cleanup() {
174 [ ${cleanup_done} -eq 1 ] && return
175 ip netns del ${NS_A} 2 > /dev/null
176 ip netns del ${NS_B} 2 > /dev/null
177 cleanup_done=1
178}
179
180mtu() {
181 ns_cmd="${1}"
182 dev="${2}"
183 mtu="${3}"
184
185 ${ns_cmd} ip link set dev ${dev} mtu ${mtu}
186}
187
188mtu_parse() {
189 input="${1}"
190
191 next=0
192 for i in ${input}; do
193 [ ${next} -eq 1 ] && echo "${i}" && return
194 [ "${i}" = "mtu" ] && next=1
195 done
196}
197
198link_get() {
199 ns_cmd="${1}"
200 name="${2}"
201
202 ${ns_cmd} ip link show dev "${name}"
203}
204
205link_get_mtu() {
206 ns_cmd="${1}"
207 name="${2}"
208
209 mtu_parse "$(link_get "${ns_cmd}" ${name})"
210}
211
212route_get_dst_exception() {
213 ns_cmd="${1}"
214 dst="${2}"
215
216 ${ns_cmd} ip route get "${dst}"
217}
218
219route_get_dst_pmtu_from_exception() {
220 ns_cmd="${1}"
221 dst="${2}"
222
223 mtu_parse "$(route_get_dst_exception "${ns_cmd}" ${dst})"
224}
225
226test_pmtu_vti4_exception() {
227 setup namespaces veth vti4 xfrm4 || return 2
228
229 veth_mtu=1500
230 vti_mtu=$((veth_mtu - 20))
231
232 # SPI SN IV ICV pad length next header
233 esp_payload_rfc4106=$((vti_mtu - 4 - 4 - 8 - 16 - 1 - 1))
234 ping_payload=$((esp_payload_rfc4106 - 28))
235
236 mtu "${ns_a}" veth_a ${veth_mtu}
237 mtu "${ns_b}" veth_b ${veth_mtu}
238 mtu "${ns_a}" vti4_a ${vti_mtu}
239 mtu "${ns_b}" vti4_b ${vti_mtu}
240
241 # Send DF packet without exceeding link layer MTU, check that no
242 # exception is created
243 ${ns_a} ping -q -M want -i 0.1 -w 2 -s ${ping_payload} ${vti4_b_addr} > /dev/null
244 pmtu="$(route_get_dst_pmtu_from_exception "${ns_a}" ${vti4_b_addr})"
245 if [ "${pmtu}" != "" ]; then
246 err " unexpected exception created with PMTU ${pmtu} for IP payload length ${esp_payload_rfc4106}"
247 return 1
248 fi
249
250 # Now exceed link layer MTU by one byte, check that exception is created
251 ${ns_a} ping -q -M want -i 0.1 -w 2 -s $((ping_payload + 1)) ${vti4_b_addr} > /dev/null
252 pmtu="$(route_get_dst_pmtu_from_exception "${ns_a}" ${vti4_b_addr})"
253 if [ "${pmtu}" = "" ]; then
254 err " exception not created for IP payload length $((esp_payload_rfc4106 + 1))"
255 return 1
256 fi
257
258 # ...with the right PMTU value
259 if [ ${pmtu} -ne ${esp_payload_rfc4106} ]; then
260 err " wrong PMTU ${pmtu} in exception, expected: ${esp_payload_rfc4106}"
261 return 1
262 fi
263}
264
265test_pmtu_vti6_exception() {
266 setup namespaces veth vti6 xfrm6 || return 2
267 fail=0
268
269 # Create route exception by exceeding link layer MTU
270 mtu "${ns_a}" veth_a 4000
271 mtu "${ns_b}" veth_b 4000
272 mtu "${ns_a}" vti6_a 5000
273 mtu "${ns_b}" vti6_b 5000
274 ${ns_a} ping6 -q -i 0.1 -w 2 -s 60000 ${vti6_b_addr} > /dev/null
275
276 # Check that exception was created
277 if [ "$(route_get_dst_pmtu_from_exception "${ns_a}" ${vti6_b_addr})" = "" ]; then
278 err " tunnel exceeding link layer MTU didn't create route exception"
279 return 1
280 fi
281
282 # Decrease tunnel MTU, check for PMTU decrease in route exception
283 mtu "${ns_a}" vti6_a 3000
284
285 if [ "$(route_get_dst_pmtu_from_exception "${ns_a}" ${vti6_b_addr})" -ne 3000 ]; then
286 err " decreasing tunnel MTU didn't decrease route exception PMTU"
287 fail=1
288 fi
289
290 # Increase tunnel MTU, check for PMTU increase in route exception
291 mtu "${ns_a}" vti6_a 9000
292 if [ "$(route_get_dst_pmtu_from_exception "${ns_a}" ${vti6_b_addr})" -ne 9000 ]; then
293 err " increasing tunnel MTU didn't increase route exception PMTU"
294 fail=1
295 fi
296
297 return ${fail}
298}
299
300test_pmtu_vti4_default_mtu() {
301 setup namespaces veth vti4 || return 2
302
303 # Check that MTU of vti device is MTU of veth minus IPv4 header length
304 veth_mtu="$(link_get_mtu "${ns_a}" veth_a)"
305 vti4_mtu="$(link_get_mtu "${ns_a}" vti4_a)"
306 if [ $((veth_mtu - vti4_mtu)) -ne 20 ]; then
307 err " vti MTU ${vti4_mtu} is not veth MTU ${veth_mtu} minus IPv4 header length"
308 return 1
309 fi
310}
311
312test_pmtu_vti6_default_mtu() {
313 setup namespaces veth vti6 || return 2
314
315 # Check that MTU of vti device is MTU of veth minus IPv6 header length
316 veth_mtu="$(link_get_mtu "${ns_a}" veth_a)"
317 vti6_mtu="$(link_get_mtu "${ns_a}" vti6_a)"
318 if [ $((veth_mtu - vti6_mtu)) -ne 40 ]; then
319 err " vti MTU ${vti6_mtu} is not veth MTU ${veth_mtu} minus IPv6 header length"
320 return 1
321 fi
322}
323
324test_pmtu_vti4_link_add_mtu() {
325 setup namespaces || return 2
326
327 ${ns_a} ip link add vti4_a type vti local ${veth4_a_addr} remote ${veth4_b_addr} key 10
328 [ $? -ne 0 ] && err " vti not supported" && return 2
329 ${ns_a} ip link del vti4_a
330
331 fail=0
332
333 min=68
334 max=$((65528 - 20))
335 # Check invalid values first
336 for v in $((min - 1)) $((max + 1)); do
337 ${ns_a} ip link add vti4_a mtu ${v} type vti local ${veth4_a_addr} remote ${veth4_b_addr} key 10 2>/dev/null
338 # This can fail, or MTU can be adjusted to a proper value
339 [ $? -ne 0 ] && continue
340 mtu="$(link_get_mtu "${ns_a}" vti4_a)"
341 if [ ${mtu} -lt ${min} -o ${mtu} -gt ${max} ]; then
342 err " vti tunnel created with invalid MTU ${mtu}"
343 fail=1
344 fi
345 ${ns_a} ip link del vti4_a
346 done
347
348 # Now check valid values
349 for v in ${min} 1300 ${max}; do
350 ${ns_a} ip link add vti4_a mtu ${v} type vti local ${veth4_a_addr} remote ${veth4_b_addr} key 10
351 mtu="$(link_get_mtu "${ns_a}" vti4_a)"
352 ${ns_a} ip link del vti4_a
353 if [ "${mtu}" != "${v}" ]; then
354 err " vti MTU ${mtu} doesn't match configured value ${v}"
355 fail=1
356 fi
357 done
358
359 return ${fail}
360}
361
362test_pmtu_vti6_link_add_mtu() {
363 setup namespaces || return 2
364
365 ${ns_a} ip link add vti6_a type vti6 local ${veth6_a_addr} remote ${veth6_b_addr} key 10
366 [ $? -ne 0 ] && err " vti6 not supported" && return 2
367 ${ns_a} ip link del vti6_a
368
369 fail=0
370
371 min=1280
372 max=$((65535 - 40))
373 # Check invalid values first
374 for v in $((min - 1)) $((max + 1)); do
375 ${ns_a} ip link add vti6_a mtu ${v} type vti6 local ${veth6_a_addr} remote ${veth6_b_addr} key 10 2>/dev/null
376 # This can fail, or MTU can be adjusted to a proper value
377 [ $? -ne 0 ] && continue
378 mtu="$(link_get_mtu "${ns_a}" vti6_a)"
379 if [ ${mtu} -lt ${min} -o ${mtu} -gt ${max} ]; then
380 err " vti6 tunnel created with invalid MTU ${v}"
381 fail=1
382 fi
383 ${ns_a} ip link del vti6_a
384 done
385
386 # Now check valid values
387 for v in 1280 1300 $((65535 - 40)); do
388 ${ns_a} ip link add vti6_a mtu ${v} type vti6 local ${veth6_a_addr} remote ${veth6_b_addr} key 10
389 mtu="$(link_get_mtu "${ns_a}" vti6_a)"
390 ${ns_a} ip link del vti6_a
391 if [ "${mtu}" != "${v}" ]; then
392 err " vti6 MTU ${mtu} doesn't match configured value ${v}"
393 fail=1
394 fi
395 done
396
397 return ${fail}
398}
399
400test_pmtu_vti6_link_change_mtu() {
401 setup namespaces || return 2
402
403 ${ns_a} ip link add dummy0 mtu 1500 type dummy
404 [ $? -ne 0 ] && err " dummy not supported" && return 2
405 ${ns_a} ip link add dummy1 mtu 3000 type dummy
406 ${ns_a} ip link set dummy0 up
407 ${ns_a} ip link set dummy1 up
408
409 ${ns_a} ip addr add ${dummy6_0_addr}/${dummy6_mask} dev dummy0
410 ${ns_a} ip addr add ${dummy6_1_addr}/${dummy6_mask} dev dummy1
411
412 fail=0
413
414 # Create vti6 interface bound to device, passing MTU, check it
415 ${ns_a} ip link add vti6_a mtu 1300 type vti6 remote ${dummy6_0_addr} local ${dummy6_0_addr}
416 mtu="$(link_get_mtu "${ns_a}" vti6_a)"
417 if [ ${mtu} -ne 1300 ]; then
418 err " vti6 MTU ${mtu} doesn't match configured value 1300"
419 fail=1
420 fi
421
422 # Move to another device with different MTU, without passing MTU, check
423 # MTU is adjusted
424 ${ns_a} ip link set vti6_a type vti6 remote ${dummy6_1_addr} local ${dummy6_1_addr}
425 mtu="$(link_get_mtu "${ns_a}" vti6_a)"
426 if [ ${mtu} -ne $((3000 - 40)) ]; then
427 err " vti MTU ${mtu} is not dummy MTU 3000 minus IPv6 header length"
428 fail=1
429 fi
430
431 # Move it back, passing MTU, check MTU is not overridden
432 ${ns_a} ip link set vti6_a mtu 1280 type vti6 remote ${dummy6_0_addr} local ${dummy6_0_addr}
433 mtu="$(link_get_mtu "${ns_a}" vti6_a)"
434 if [ ${mtu} -ne 1280 ]; then
435 err " vti6 MTU ${mtu} doesn't match configured value 1280"
436 fail=1
437 fi
438
439 return ${fail}
440}
441
442trap cleanup EXIT
443
444exitcode=0
445desc=0
446IFS="
447"
448for t in ${tests}; do
449 [ $desc -eq 0 ] && name="${t}" && desc=1 && continue || desc=0
450
451 (
452 unset IFS
453 eval test_${name}
454 ret=$?
455 cleanup
456
457 if [ $ret -eq 0 ]; then
458 printf "TEST: %-60s [ OK ]\n" "${t}"
459 elif [ $ret -eq 1 ]; then
460 printf "TEST: %-60s [FAIL]\n" "${t}"
461 err_flush
462 exit 1
463 elif [ $ret -eq 2 ]; then
464 printf "TEST: %-60s [SKIP]\n" "${t}"
465 err_flush
466 fi
467 )
468 [ $? -ne 0 ] && exitcode=1
469done
470
471exit ${exitcode}
diff --git a/tools/testing/selftests/net/psock_fanout.c b/tools/testing/selftests/net/psock_fanout.c
index 989f917068d1..bd9b9632c72b 100644
--- a/tools/testing/selftests/net/psock_fanout.c
+++ b/tools/testing/selftests/net/psock_fanout.c
@@ -50,6 +50,7 @@
50#include <linux/filter.h> 50#include <linux/filter.h>
51#include <linux/bpf.h> 51#include <linux/bpf.h>
52#include <linux/if_packet.h> 52#include <linux/if_packet.h>
53#include <net/if.h>
53#include <net/ethernet.h> 54#include <net/ethernet.h>
54#include <netinet/ip.h> 55#include <netinet/ip.h>
55#include <netinet/udp.h> 56#include <netinet/udp.h>
@@ -73,14 +74,29 @@
73 * @return -1 if mode is bad, a valid socket otherwise */ 74 * @return -1 if mode is bad, a valid socket otherwise */
74static int sock_fanout_open(uint16_t typeflags, uint16_t group_id) 75static int sock_fanout_open(uint16_t typeflags, uint16_t group_id)
75{ 76{
77 struct sockaddr_ll addr = {0};
76 int fd, val; 78 int fd, val;
77 79
78 fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP)); 80 fd = socket(PF_PACKET, SOCK_RAW, 0);
79 if (fd < 0) { 81 if (fd < 0) {
80 perror("socket packet"); 82 perror("socket packet");
81 exit(1); 83 exit(1);
82 } 84 }
83 85
86 pair_udp_setfilter(fd);
87
88 addr.sll_family = AF_PACKET;
89 addr.sll_protocol = htons(ETH_P_IP);
90 addr.sll_ifindex = if_nametoindex("lo");
91 if (addr.sll_ifindex == 0) {
92 perror("if_nametoindex");
93 exit(1);
94 }
95 if (bind(fd, (void *) &addr, sizeof(addr))) {
96 perror("bind packet");
97 exit(1);
98 }
99
84 val = (((int) typeflags) << 16) | group_id; 100 val = (((int) typeflags) << 16) | group_id;
85 if (setsockopt(fd, SOL_PACKET, PACKET_FANOUT, &val, sizeof(val))) { 101 if (setsockopt(fd, SOL_PACKET, PACKET_FANOUT, &val, sizeof(val))) {
86 if (close(fd)) { 102 if (close(fd)) {
@@ -90,7 +106,6 @@ static int sock_fanout_open(uint16_t typeflags, uint16_t group_id)
90 return -1; 106 return -1;
91 } 107 }
92 108
93 pair_udp_setfilter(fd);
94 return fd; 109 return fd;
95} 110}
96 111
@@ -128,6 +143,8 @@ static void sock_fanout_getopts(int fd, uint16_t *typeflags, uint16_t *group_id)
128 143
129static void sock_fanout_set_ebpf(int fd) 144static void sock_fanout_set_ebpf(int fd)
130{ 145{
146 static char log_buf[65536];
147
131 const int len_off = __builtin_offsetof(struct __sk_buff, len); 148 const int len_off = __builtin_offsetof(struct __sk_buff, len);
132 struct bpf_insn prog[] = { 149 struct bpf_insn prog[] = {
133 { BPF_ALU64 | BPF_MOV | BPF_X, 6, 1, 0, 0 }, 150 { BPF_ALU64 | BPF_MOV | BPF_X, 6, 1, 0, 0 },
@@ -140,7 +157,6 @@ static void sock_fanout_set_ebpf(int fd)
140 { BPF_ALU | BPF_MOV | BPF_K, 0, 0, 0, 0 }, 157 { BPF_ALU | BPF_MOV | BPF_K, 0, 0, 0, 0 },
141 { BPF_JMP | BPF_EXIT, 0, 0, 0, 0 } 158 { BPF_JMP | BPF_EXIT, 0, 0, 0, 0 }
142 }; 159 };
143 char log_buf[512];
144 union bpf_attr attr; 160 union bpf_attr attr;
145 int pfd; 161 int pfd;
146 162
@@ -228,7 +244,7 @@ static int sock_fanout_read(int fds[], char *rings[], const int expect[])
228 244
229 if ((!(ret[0] == expect[0] && ret[1] == expect[1])) && 245 if ((!(ret[0] == expect[0] && ret[1] == expect[1])) &&
230 (!(ret[0] == expect[1] && ret[1] == expect[0]))) { 246 (!(ret[0] == expect[1] && ret[1] == expect[0]))) {
231 fprintf(stderr, "ERROR: incorrect queue lengths\n"); 247 fprintf(stderr, "warning: incorrect queue lengths\n");
232 return 1; 248 return 1;
233 } 249 }
234 250
@@ -347,7 +363,8 @@ static int test_datapath(uint16_t typeflags, int port_off,
347 uint8_t type = typeflags & 0xFF; 363 uint8_t type = typeflags & 0xFF;
348 int fds[2], fds_udp[2][2], ret; 364 int fds[2], fds_udp[2][2], ret;
349 365
350 fprintf(stderr, "test: datapath 0x%hx\n", typeflags); 366 fprintf(stderr, "\ntest: datapath 0x%hx ports %hu,%hu\n",
367 typeflags, PORT_BASE, PORT_BASE + port_off);
351 368
352 fds[0] = sock_fanout_open(typeflags, 0); 369 fds[0] = sock_fanout_open(typeflags, 0);
353 fds[1] = sock_fanout_open(typeflags, 0); 370 fds[1] = sock_fanout_open(typeflags, 0);
@@ -418,7 +435,7 @@ int main(int argc, char **argv)
418 const int expect_cpu1[2][2] = { { 0, 20 }, { 0, 20 } }; 435 const int expect_cpu1[2][2] = { { 0, 20 }, { 0, 20 } };
419 const int expect_bpf[2][2] = { { 15, 5 }, { 15, 20 } }; 436 const int expect_bpf[2][2] = { { 15, 5 }, { 15, 20 } };
420 const int expect_uniqueid[2][2] = { { 20, 20}, { 20, 20 } }; 437 const int expect_uniqueid[2][2] = { { 20, 20}, { 20, 20 } };
421 int port_off = 2, tries = 5, ret; 438 int port_off = 2, tries = 20, ret;
422 439
423 test_control_single(); 440 test_control_single();
424 test_control_group(); 441 test_control_group();
@@ -427,10 +444,14 @@ int main(int argc, char **argv)
427 /* find a set of ports that do not collide onto the same socket */ 444 /* find a set of ports that do not collide onto the same socket */
428 ret = test_datapath(PACKET_FANOUT_HASH, port_off, 445 ret = test_datapath(PACKET_FANOUT_HASH, port_off,
429 expect_hash[0], expect_hash[1]); 446 expect_hash[0], expect_hash[1]);
430 while (ret && tries--) { 447 while (ret) {
431 fprintf(stderr, "info: trying alternate ports (%d)\n", tries); 448 fprintf(stderr, "info: trying alternate ports (%d)\n", tries);
432 ret = test_datapath(PACKET_FANOUT_HASH, ++port_off, 449 ret = test_datapath(PACKET_FANOUT_HASH, ++port_off,
433 expect_hash[0], expect_hash[1]); 450 expect_hash[0], expect_hash[1]);
451 if (!--tries) {
452 fprintf(stderr, "too many collisions\n");
453 return 1;
454 }
434 } 455 }
435 456
436 ret |= test_datapath(PACKET_FANOUT_HASH | PACKET_FANOUT_FLAG_ROLLOVER, 457 ret |= test_datapath(PACKET_FANOUT_HASH | PACKET_FANOUT_FLAG_ROLLOVER,
diff --git a/tools/testing/selftests/net/rtnetlink.sh b/tools/testing/selftests/net/rtnetlink.sh
index a622eeecc3a6..e6f485235435 100755
--- a/tools/testing/selftests/net/rtnetlink.sh
+++ b/tools/testing/selftests/net/rtnetlink.sh
@@ -517,6 +517,7 @@ kci_test_gretap()
517 ip link help gretap 2>&1 | grep -q "^Usage:" 517 ip link help gretap 2>&1 | grep -q "^Usage:"
518 if [ $? -ne 0 ];then 518 if [ $? -ne 0 ];then
519 echo "SKIP: gretap: iproute2 too old" 519 echo "SKIP: gretap: iproute2 too old"
520 ip netns del "$testns"
520 return 1 521 return 1
521 fi 522 fi
522 523
@@ -543,6 +544,7 @@ kci_test_gretap()
543 544
544 if [ $ret -ne 0 ]; then 545 if [ $ret -ne 0 ]; then
545 echo "FAIL: gretap" 546 echo "FAIL: gretap"
547 ip netns del "$testns"
546 return 1 548 return 1
547 fi 549 fi
548 echo "PASS: gretap" 550 echo "PASS: gretap"
@@ -565,6 +567,7 @@ kci_test_ip6gretap()
565 ip link help ip6gretap 2>&1 | grep -q "^Usage:" 567 ip link help ip6gretap 2>&1 | grep -q "^Usage:"
566 if [ $? -ne 0 ];then 568 if [ $? -ne 0 ];then
567 echo "SKIP: ip6gretap: iproute2 too old" 569 echo "SKIP: ip6gretap: iproute2 too old"
570 ip netns del "$testns"
568 return 1 571 return 1
569 fi 572 fi
570 573
@@ -591,6 +594,7 @@ kci_test_ip6gretap()
591 594
592 if [ $ret -ne 0 ]; then 595 if [ $ret -ne 0 ]; then
593 echo "FAIL: ip6gretap" 596 echo "FAIL: ip6gretap"
597 ip netns del "$testns"
594 return 1 598 return 1
595 fi 599 fi
596 echo "PASS: ip6gretap" 600 echo "PASS: ip6gretap"
@@ -655,6 +659,7 @@ kci_test_erspan()
655 659
656 if [ $ret -ne 0 ]; then 660 if [ $ret -ne 0 ]; then
657 echo "FAIL: erspan" 661 echo "FAIL: erspan"
662 ip netns del "$testns"
658 return 1 663 return 1
659 fi 664 fi
660 echo "PASS: erspan" 665 echo "PASS: erspan"
@@ -720,6 +725,7 @@ kci_test_ip6erspan()
720 725
721 if [ $ret -ne 0 ]; then 726 if [ $ret -ne 0 ]; then
722 echo "FAIL: ip6erspan" 727 echo "FAIL: ip6erspan"
728 ip netns del "$testns"
723 return 1 729 return 1
724 fi 730 fi
725 echo "PASS: ip6erspan" 731 echo "PASS: ip6erspan"
diff --git a/tools/testing/selftests/net/run_afpackettests b/tools/testing/selftests/net/run_afpackettests
index 21fe149e3de1..bea079edc278 100755
--- a/tools/testing/selftests/net/run_afpackettests
+++ b/tools/testing/selftests/net/run_afpackettests
@@ -9,7 +9,7 @@ fi
9echo "--------------------" 9echo "--------------------"
10echo "running psock_fanout test" 10echo "running psock_fanout test"
11echo "--------------------" 11echo "--------------------"
12./psock_fanout 12./in_netns.sh ./psock_fanout
13if [ $? -ne 0 ]; then 13if [ $? -ne 0 ]; then
14 echo "[FAIL]" 14 echo "[FAIL]"
15else 15else
@@ -19,7 +19,7 @@ fi
19echo "--------------------" 19echo "--------------------"
20echo "running psock_tpacket test" 20echo "running psock_tpacket test"
21echo "--------------------" 21echo "--------------------"
22./psock_tpacket 22./in_netns.sh ./psock_tpacket
23if [ $? -ne 0 ]; then 23if [ $? -ne 0 ]; then
24 echo "[FAIL]" 24 echo "[FAIL]"
25else 25else
diff --git a/tools/testing/selftests/networking/timestamping/txtimestamp.c b/tools/testing/selftests/networking/timestamping/txtimestamp.c
index 5df07047ca86..81a98a240456 100644
--- a/tools/testing/selftests/networking/timestamping/txtimestamp.c
+++ b/tools/testing/selftests/networking/timestamping/txtimestamp.c
@@ -68,9 +68,11 @@ static int cfg_num_pkts = 4;
68static int do_ipv4 = 1; 68static int do_ipv4 = 1;
69static int do_ipv6 = 1; 69static int do_ipv6 = 1;
70static int cfg_payload_len = 10; 70static int cfg_payload_len = 10;
71static int cfg_poll_timeout = 100;
71static bool cfg_show_payload; 72static bool cfg_show_payload;
72static bool cfg_do_pktinfo; 73static bool cfg_do_pktinfo;
73static bool cfg_loop_nodata; 74static bool cfg_loop_nodata;
75static bool cfg_no_delay;
74static uint16_t dest_port = 9000; 76static uint16_t dest_port = 9000;
75 77
76static struct sockaddr_in daddr; 78static struct sockaddr_in daddr;
@@ -171,7 +173,7 @@ static void __poll(int fd)
171 173
172 memset(&pollfd, 0, sizeof(pollfd)); 174 memset(&pollfd, 0, sizeof(pollfd));
173 pollfd.fd = fd; 175 pollfd.fd = fd;
174 ret = poll(&pollfd, 1, 100); 176 ret = poll(&pollfd, 1, cfg_poll_timeout);
175 if (ret != 1) 177 if (ret != 1)
176 error(1, errno, "poll"); 178 error(1, errno, "poll");
177} 179}
@@ -371,7 +373,8 @@ static void do_test(int family, unsigned int opt)
371 error(1, errno, "send"); 373 error(1, errno, "send");
372 374
373 /* wait for all errors to be queued, else ACKs arrive OOO */ 375 /* wait for all errors to be queued, else ACKs arrive OOO */
374 usleep(50 * 1000); 376 if (!cfg_no_delay)
377 usleep(50 * 1000);
375 378
376 __poll(fd); 379 __poll(fd);
377 380
@@ -392,6 +395,9 @@ static void __attribute__((noreturn)) usage(const char *filepath)
392 " -4: only IPv4\n" 395 " -4: only IPv4\n"
393 " -6: only IPv6\n" 396 " -6: only IPv6\n"
394 " -h: show this message\n" 397 " -h: show this message\n"
398 " -c N: number of packets for each test\n"
399 " -D: no delay between packets\n"
400 " -F: poll() waits forever for an event\n"
395 " -I: request PKTINFO\n" 401 " -I: request PKTINFO\n"
396 " -l N: send N bytes at a time\n" 402 " -l N: send N bytes at a time\n"
397 " -n: set no-payload option\n" 403 " -n: set no-payload option\n"
@@ -409,7 +415,7 @@ static void parse_opt(int argc, char **argv)
409 int proto_count = 0; 415 int proto_count = 0;
410 char c; 416 char c;
411 417
412 while ((c = getopt(argc, argv, "46hIl:np:rRux")) != -1) { 418 while ((c = getopt(argc, argv, "46c:DFhIl:np:rRux")) != -1) {
413 switch (c) { 419 switch (c) {
414 case '4': 420 case '4':
415 do_ipv6 = 0; 421 do_ipv6 = 0;
@@ -417,6 +423,15 @@ static void parse_opt(int argc, char **argv)
417 case '6': 423 case '6':
418 do_ipv4 = 0; 424 do_ipv4 = 0;
419 break; 425 break;
426 case 'c':
427 cfg_num_pkts = strtoul(optarg, NULL, 10);
428 break;
429 case 'D':
430 cfg_no_delay = true;
431 break;
432 case 'F':
433 cfg_poll_timeout = -1;
434 break;
420 case 'I': 435 case 'I':
421 cfg_do_pktinfo = true; 436 cfg_do_pktinfo = true;
422 break; 437 break;
diff --git a/tools/testing/selftests/tc-testing/README b/tools/testing/selftests/tc-testing/README
index 970ff294fec8..3a0336782d2d 100644
--- a/tools/testing/selftests/tc-testing/README
+++ b/tools/testing/selftests/tc-testing/README
@@ -14,11 +14,11 @@ REQUIREMENTS
14 14
15* The kernel must have network namespace support 15* The kernel must have network namespace support
16 16
17* The kernel must have veth support available, as a veth pair is created 17* The kernel must have veth support available, as a veth pair is created
18 prior to running the tests. 18 prior to running the tests.
19 19
20* All tc-related features must be built in or available as modules. 20* All tc-related features being tested must be built in or available as
21 To check what is required in current setup run: 21 modules. To check what is required in current setup run:
22 ./tdc.py -c 22 ./tdc.py -c
23 23
24 Note: 24 Note:
@@ -44,10 +44,13 @@ using the -p option when running tdc:
44RUNNING TDC 44RUNNING TDC
45----------- 45-----------
46 46
47To use tdc, root privileges are required. tdc will not run otherwise. 47To use tdc, root privileges are required. This is because the
48commands being tested must be run as root. The code that enforces
49execution by root uid has been moved into a plugin (see PLUGIN
50ARCHITECTURE, below).
48 51
49All tests are executed inside a network namespace to prevent conflicts 52If nsPlugin is linked, all tests are executed inside a network
50within the host. 53namespace to prevent conflicts within the host.
51 54
52Running tdc without any arguments will run all tests. Refer to the section 55Running tdc without any arguments will run all tests. Refer to the section
53on command line arguments for more information, or run: 56on command line arguments for more information, or run:
@@ -59,6 +62,33 @@ output captured from the failing test will be printed immediately following
59the failed test in the TAP output. 62the failed test in the TAP output.
60 63
61 64
65OVERVIEW OF TDC EXECUTION
66-------------------------
67
68One run of tests is considered a "test suite" (this will be refined in the
69future). A test suite has one or more test cases in it.
70
71A test case has four stages:
72
73 - setup
74 - execute
75 - verify
76 - teardown
77
78The setup and teardown stages can run zero or more commands. The setup
79stage does some setup if the test needs it. The teardown stage undoes
80the setup and returns the system to a "neutral" state so any other test
81can be run next. These two stages require any commands run to return
82success, but do not otherwise verify the results.
83
84The execute and verify stages each run one command. The execute stage
85tests the return code against one or more acceptable values. The
86verify stage checks the return code for success, and also compares
87the stdout with a regular expression.
88
89Each of the commands in any stage will run in a shell instance.
90
91
62USER-DEFINED CONSTANTS 92USER-DEFINED CONSTANTS
63---------------------- 93----------------------
64 94
@@ -70,23 +100,132 @@ executed as part of the test. More will be added as test cases require.
70Example: 100Example:
71 $TC qdisc add dev $DEV1 ingress 101 $TC qdisc add dev $DEV1 ingress
72 102
103The NAMES values are used to substitute into the commands in the test cases.
104
73 105
74COMMAND LINE ARGUMENTS 106COMMAND LINE ARGUMENTS
75---------------------- 107----------------------
76 108
77Run tdc.py -h to see the full list of available arguments. 109Run tdc.py -h to see the full list of available arguments.
78 110
79-p PATH Specify the tc executable located at PATH to be used on this 111usage: tdc.py [-h] [-p PATH] [-D DIR [DIR ...]] [-f FILE [FILE ...]]
80 test run 112 [-c [CATG [CATG ...]]] [-e ID [ID ...]] [-l] [-s] [-i] [-v]
81-c Show the available test case categories in this test file 113 [-d DEVICE] [-n NS] [-V]
82-c CATEGORY Run only tests that belong to CATEGORY 114
83-f FILE Read test cases from the JSON file named FILE 115Linux TC unit tests
84-l [CATEGORY] List all test cases in the JSON file. If CATEGORY is 116
85 specified, list test cases matching that category. 117optional arguments:
86-s ID Show the test case matching ID 118 -h, --help show this help message and exit
87-e ID Execute the test case identified by ID 119 -p PATH, --path PATH The full path to the tc executable to use
88-i Generate unique ID numbers for test cases with no existing 120 -v, --verbose Show the commands that are being run
89 ID number 121 -d DEVICE, --device DEVICE
122 Execute the test case in flower category
123
124selection:
125 select which test cases: files plus directories; filtered by categories
126 plus testids
127
128 -D DIR [DIR ...], --directory DIR [DIR ...]
129 Collect tests from the specified directory(ies)
130 (default [tc-tests])
131 -f FILE [FILE ...], --file FILE [FILE ...]
132 Run tests from the specified file(s)
133 -c [CATG [CATG ...]], --category [CATG [CATG ...]]
134 Run tests only from the specified category/ies, or if
135 no category/ies is/are specified, list known
136 categories.
137 -e ID [ID ...], --execute ID [ID ...]
138 Execute the specified test cases with specified IDs
139
140action:
141 select action to perform on selected test cases
142
143 -l, --list List all test cases, or those only within the
144 specified category
145 -s, --show Display the selected test cases
146 -i, --id Generate ID numbers for new test cases
147
148netns:
149 options for nsPlugin(run commands in net namespace)
150
151 -n NS, --namespace NS
152 Run commands in namespace NS
153
154valgrind:
155 options for valgrindPlugin (run command under test under Valgrind)
156
157 -V, --valgrind Run commands under valgrind
158
159
160PLUGIN ARCHITECTURE
161-------------------
162
163There is now a plugin architecture, and some of the functionality that
164was in the tdc.py script has been moved into the plugins.
165
166The plugins are in the directory plugin-lib. The are executed from
167directory plugins. Put symbolic links from plugins to plugin-lib,
168and name them according to the order you want them to run.
169
170Example:
171
172bjb@bee:~/work/tc-testing$ ls -l plugins
173total 4
174lrwxrwxrwx 1 bjb bjb 27 Oct 4 16:12 10-rootPlugin.py -> ../plugin-lib/rootPlugin.py
175lrwxrwxrwx 1 bjb bjb 25 Oct 12 17:55 20-nsPlugin.py -> ../plugin-lib/nsPlugin.py
176-rwxr-xr-x 1 bjb bjb 0 Sep 29 15:56 __init__.py
177
178The plugins are a subclass of TdcPlugin, defined in TdcPlugin.py and
179must be called "SubPlugin" so tdc can find them. They are
180distinguished from each other in the python program by their module
181name.
182
183This base class supplies "hooks" to run extra functions. These hooks are as follows:
184
185pre- and post-suite
186pre- and post-case
187pre- and post-execute stage
188adjust-command (runs in all stages and receives the stage name)
189
190The pre-suite hook receives the number of tests and an array of test ids.
191This allows you to dump out the list of skipped tests in the event of a
192failure during setup or teardown stage.
193
194The pre-case hook receives the ordinal number and test id of the current test.
195
196The adjust-command hook receives the stage id (see list below) and the
197full command to be executed. This allows for last-minute adjustment
198of the command.
199
200The stages are identified by the following strings:
201
202 - pre (pre-suite)
203 - setup
204 - command
205 - verify
206 - teardown
207 - post (post-suite)
208
209
210To write a plugin, you need to inherit from TdcPlugin in
211TdcPlugin.py. To use the plugin, you have to put the
212implementation file in plugin-lib, and add a symbolic link to it from
213plugins. It will be detected at run time and invoked at the
214appropriate times. There are a few examples in the plugin-lib
215directory:
216
217 - rootPlugin.py:
218 implements the enforcement of running as root
219 - nsPlugin.py:
220 sets up a network namespace and runs all commands in that namespace
221 - valgrindPlugin.py
222 runs each command in the execute stage under valgrind,
223 and checks for leaks.
224 This plugin will output an extra test for each test in the test file,
225 one is the existing output as to whether the test passed or failed,
226 and the other is a test whether the command leaked memory or not.
227 (This one is a preliminary version, it may not work quite right yet,
228 but the overall template is there and it should only need tweaks.)
90 229
91 230
92ACKNOWLEDGEMENTS 231ACKNOWLEDGEMENTS
diff --git a/tools/testing/selftests/tc-testing/TODO.txt b/tools/testing/selftests/tc-testing/TODO.txt
index 6a266d811a78..c40698557e2f 100644
--- a/tools/testing/selftests/tc-testing/TODO.txt
+++ b/tools/testing/selftests/tc-testing/TODO.txt
@@ -5,6 +5,27 @@ tc Testing Suite To-Do list:
5 5
6- Add support for multiple versions of tc to run successively 6- Add support for multiple versions of tc to run successively
7 7
8- Improve error messages when tdc aborts its run 8- Improve error messages when tdc aborts its run. Partially done - still
9 need to better handle problems in pre- and post-suite.
9 10
10- Allow tdc to write its results to file 11- Use python logger module for debug/verbose output
12
13- Allow tdc to write its results to file.
14 Maybe use python logger module for this too.
15
16- A better implementation of the "hooks". Currently, every plugin
17 will attempt to run a function at every hook point. Could be
18 changed so that plugin __init__ methods will register functions to
19 be run in the various predefined times. Then if a plugin does not
20 require action at a specific point, no penalty will be paid for
21 trying to run a function that will do nothing.
22
23- Proper exception handling - make an exception class and use it
24
25- a TestCase class, for easier testcase handling, searching, comparison
26
27- a TestSuite class
28 and a way to configure a test suite,
29 to automate running multiple "test suites" with different requirements
30
31- super simple test case example using ls, touch, etc
diff --git a/tools/testing/selftests/tc-testing/TdcPlugin.py b/tools/testing/selftests/tc-testing/TdcPlugin.py
new file mode 100644
index 000000000000..3ee9a6dacb52
--- /dev/null
+++ b/tools/testing/selftests/tc-testing/TdcPlugin.py
@@ -0,0 +1,74 @@
1#!/usr/bin/env python3
2
3class TdcPlugin:
4 def __init__(self):
5 super().__init__()
6 print(' -- {}.__init__'.format(self.sub_class))
7
8 def pre_suite(self, testcount, testidlist):
9 '''run commands before test_runner goes into a test loop'''
10 self.testcount = testcount
11 self.testidlist = testidlist
12 if self.args.verbose > 1:
13 print(' -- {}.pre_suite'.format(self.sub_class))
14
15 def post_suite(self, index):
16 '''run commands after test_runner completes the test loop
17 index is the last ordinal number of test that was attempted'''
18 if self.args.verbose > 1:
19 print(' -- {}.post_suite'.format(self.sub_class))
20
21 def pre_case(self, test_ordinal, testid):
22 '''run commands before test_runner does one test'''
23 if self.args.verbose > 1:
24 print(' -- {}.pre_case'.format(self.sub_class))
25 self.args.testid = testid
26 self.args.test_ordinal = test_ordinal
27
28 def post_case(self):
29 '''run commands after test_runner does one test'''
30 if self.args.verbose > 1:
31 print(' -- {}.post_case'.format(self.sub_class))
32
33 def pre_execute(self):
34 '''run command before test-runner does the execute step'''
35 if self.args.verbose > 1:
36 print(' -- {}.pre_execute'.format(self.sub_class))
37
38 def post_execute(self):
39 '''run command after test-runner does the execute step'''
40 if self.args.verbose > 1:
41 print(' -- {}.post_execute'.format(self.sub_class))
42
43 def adjust_command(self, stage, command):
44 '''adjust the command'''
45 if self.args.verbose > 1:
46 print(' -- {}.adjust_command {}'.format(self.sub_class, stage))
47
48 # if stage == 'pre':
49 # pass
50 # elif stage == 'setup':
51 # pass
52 # elif stage == 'execute':
53 # pass
54 # elif stage == 'verify':
55 # pass
56 # elif stage == 'teardown':
57 # pass
58 # elif stage == 'post':
59 # pass
60 # else:
61 # pass
62
63 return command
64
65 def add_args(self, parser):
66 '''Get the plugin args from the command line'''
67 self.argparser = parser
68 return self.argparser
69
70 def check_args(self, args, remaining):
71 '''Check that the args are set correctly'''
72 self.args = args
73 if self.args.verbose > 1:
74 print(' -- {}.check_args'.format(self.sub_class))
diff --git a/tools/testing/selftests/tc-testing/creating-plugins/AddingPlugins.txt b/tools/testing/selftests/tc-testing/creating-plugins/AddingPlugins.txt
new file mode 100644
index 000000000000..c18f88d09360
--- /dev/null
+++ b/tools/testing/selftests/tc-testing/creating-plugins/AddingPlugins.txt
@@ -0,0 +1,104 @@
1tdc - Adding plugins for tdc
2
3Author: Brenda J. Butler - bjb@mojatatu.com
4
5ADDING PLUGINS
6--------------
7
8A new plugin should be written in python as a class that inherits from TdcPlugin.
9There are some examples in plugin-lib.
10
11The plugin can be used to add functionality to the test framework,
12such as:
13
14- adding commands to be run before and/or after the test suite
15- adding commands to be run before and/or after the test cases
16- adding commands to be run before and/or after the execute phase of the test cases
17- ability to alter the command to be run in any phase:
18 pre (the pre-suite stage)
19 prepare
20 execute
21 verify
22 teardown
23 post (the post-suite stage)
24- ability to add to the command line args, and use them at run time
25
26
27The functions in the class should follow the following interfaces:
28
29 def __init__(self)
30 def pre_suite(self, testcount, testidlist) # see "PRE_SUITE" below
31 def post_suite(self, ordinal) # see "SKIPPING" below
32 def pre_case(self, test_ordinal, testid) # see "PRE_CASE" below
33 def post_case(self)
34 def pre_execute(self)
35 def post_execute(self)
36 def adjust_command(self, stage, command) # see "ADJUST" below
37 def add_args(self, parser) # see "ADD_ARGS" below
38 def check_args(self, args, remaining) # see "CHECK_ARGS" below
39
40
41PRE_SUITE
42
43This method takes a testcount (number of tests to be run) and
44testidlist (array of test ids for tests that will be run). This is
45useful for various things, including when an exception occurs and the
46rest of the tests must be skipped. The info is stored in the object,
47and the post_suite method can refer to it when dumping the "skipped"
48TAP output. The tdc.py script will do that for the test suite as
49defined in the test case, but if the plugin is being used to run extra
50tests on each test (eg, check for memory leaks on associated
51co-processes) then that other tap output can be generated in the
52post-suite method using this info passed in to the pre_suite method.
53
54
55SKIPPING
56
57The post_suite method will receive the ordinal number of the last
58test to be attempted. It can use this info when outputting
59the TAP output for the extra test cases.
60
61
62PRE_CASE
63
64The pre_case method will receive the ordinal number of the test
65and the test id. Useful for outputing the extra test results.
66
67
68ADJUST
69
70The adjust_command method receives a string representing
71the execution stage and a string which is the actual command to be
72executed. The plugin can adjust the command, based on the stage of
73execution.
74
75The stages are represented by the following strings:
76
77 'pre'
78 'setup'
79 'command'
80 'verify'
81 'teardown'
82 'post'
83
84The adjust_command method must return the adjusted command so tdc
85can use it.
86
87
88ADD_ARGS
89
90The add_args method receives the argparser object and can add
91arguments to it. Care should be taken that the new arguments do not
92conflict with any from tdc.py or from other plugins that will be used
93concurrently.
94
95The add_args method should return the argparser object.
96
97
98CHECK_ARGS
99
100The check_args method is so that the plugin can do validation on
101the args, if needed. If there is a problem, and Exception should
102be raised, with a string that explains the problem.
103
104eg: raise Exception('plugin xxx, arg -y is wrong, fix it')
diff --git a/tools/testing/selftests/tc-testing/creating-testcases/AddingTestCases.txt b/tools/testing/selftests/tc-testing/creating-testcases/AddingTestCases.txt
index 00438331ba47..17b267dedbd9 100644
--- a/tools/testing/selftests/tc-testing/creating-testcases/AddingTestCases.txt
+++ b/tools/testing/selftests/tc-testing/creating-testcases/AddingTestCases.txt
@@ -12,14 +12,18 @@ template.json for the required JSON format for test cases.
12Include the 'id' field, but do not assign a value. Running tdc with the -i 12Include the 'id' field, but do not assign a value. Running tdc with the -i
13option will generate a unique ID for that test case. 13option will generate a unique ID for that test case.
14 14
15tdc will recursively search the 'tc' subdirectory for .json files. Any 15tdc will recursively search the 'tc-tests' subdirectory (or the
16test case files you create in these directories will automatically be included. 16directories named with the -D option) for .json files. Any test case
17If you wish to store your custom test cases elsewhere, be sure to run tdc 17files you create in these directories will automatically be included.
18with the -f argument and the path to your file. 18If you wish to store your custom test cases elsewhere, be sure to run
19tdc with the -f argument and the path to your file, or the -D argument
20and the path to your directory(ies).
19 21
20Be aware of required escape characters in the JSON data - particularly when 22Be aware of required escape characters in the JSON data - particularly
21defining the match pattern. Refer to the tctests.json file for examples when 23when defining the match pattern. Refer to the supplied json test files
22in doubt. 24for examples when in doubt. The match pattern is written in json, and
25will be used by python. So the match pattern will be a python regular
26expression, but should be written using json syntax.
23 27
24 28
25TEST CASE STRUCTURE 29TEST CASE STRUCTURE
@@ -69,7 +73,8 @@ SETUP/TEARDOWN ERRORS
69If an error is detected during the setup/teardown process, execution of the 73If an error is detected during the setup/teardown process, execution of the
70tests will immediately stop with an error message and the namespace in which 74tests will immediately stop with an error message and the namespace in which
71the tests are run will be destroyed. This is to prevent inaccurate results 75the tests are run will be destroyed. This is to prevent inaccurate results
72in the test cases. 76in the test cases. tdc will output a series of TAP results for the skipped
77tests.
73 78
74Repeated failures of the setup/teardown may indicate a problem with the test 79Repeated failures of the setup/teardown may indicate a problem with the test
75case, or possibly even a bug in one of the commands that are not being tested. 80case, or possibly even a bug in one of the commands that are not being tested.
@@ -79,3 +84,17 @@ so that it doesn't halt the script for an error that doesn't matter. Turn the
79individual command into a list, with the command being first, followed by all 84individual command into a list, with the command being first, followed by all
80acceptable exit codes for the command. 85acceptable exit codes for the command.
81 86
87Example:
88
89A pair of setup commands. The first can have exit code 0, 1 or 255, the
90second must have exit code 0.
91
92 "setup": [
93 [
94 "$TC actions flush action gact",
95 0,
96 1,
97 255
98 ],
99 "$TC actions add action reclassify index 65536"
100 ],
diff --git a/tools/testing/selftests/tc-testing/plugin-lib/README-PLUGINS b/tools/testing/selftests/tc-testing/plugin-lib/README-PLUGINS
new file mode 100644
index 000000000000..aa8a2669702b
--- /dev/null
+++ b/tools/testing/selftests/tc-testing/plugin-lib/README-PLUGINS
@@ -0,0 +1,27 @@
1tdc.py will look for plugins in a directory plugins off the cwd.
2Make a set of numbered symbolic links from there to the actual plugins.
3Eg:
4
5tdc.py
6plugin-lib/
7plugins/
8 __init__.py
9 10-rootPlugin.py -> ../plugin-lib/rootPlugin.py
10 20-valgrindPlugin.py -> ../plugin-lib/valgrindPlugin.py
11 30-nsPlugin.py -> ../plugin-lib/nsPlugin.py
12
13
14tdc.py will find them and use them.
15
16
17rootPlugin
18 Check if the uid is root. If not, bail out.
19
20valgrindPlugin
21 Run the command under test with valgrind, and produce an extra set of TAP results for the memory tests.
22 This plugin will write files to the cwd, called vgnd-xxx.log. These will contain
23 the valgrind output for test xxx. Any file matching the glob 'vgnd-*.log' will be
24 deleted at the end of the run.
25
26nsPlugin
27 Run all the commands in a network namespace.
diff --git a/tools/testing/selftests/tc-testing/plugin-lib/nsPlugin.py b/tools/testing/selftests/tc-testing/plugin-lib/nsPlugin.py
new file mode 100644
index 000000000000..a194b1af2b30
--- /dev/null
+++ b/tools/testing/selftests/tc-testing/plugin-lib/nsPlugin.py
@@ -0,0 +1,141 @@
1import os
2import signal
3from string import Template
4import subprocess
5import time
6from TdcPlugin import TdcPlugin
7
8from tdc_config import *
9
10class SubPlugin(TdcPlugin):
11 def __init__(self):
12 self.sub_class = 'ns/SubPlugin'
13 super().__init__()
14
15 def pre_suite(self, testcount, testidlist):
16 '''run commands before test_runner goes into a test loop'''
17 super().pre_suite(testcount, testidlist)
18
19 if self.args.namespace:
20 self._ns_create()
21
22 def post_suite(self, index):
23 '''run commands after test_runner goes into a test loop'''
24 super().post_suite(index)
25 if self.args.verbose:
26 print('{}.post_suite'.format(self.sub_class))
27
28 if self.args.namespace:
29 self._ns_destroy()
30
31 def add_args(self, parser):
32 super().add_args(parser)
33 self.argparser_group = self.argparser.add_argument_group(
34 'netns',
35 'options for nsPlugin(run commands in net namespace)')
36 self.argparser_group.add_argument(
37 '-n', '--namespace', action='store_true',
38 help='Run commands in namespace')
39 return self.argparser
40
41 def adjust_command(self, stage, command):
42 super().adjust_command(stage, command)
43 cmdform = 'list'
44 cmdlist = list()
45
46 if not self.args.namespace:
47 return command
48
49 if self.args.verbose:
50 print('{}.adjust_command'.format(self.sub_class))
51
52 if not isinstance(command, list):
53 cmdform = 'str'
54 cmdlist = command.split()
55 else:
56 cmdlist = command
57 if stage == 'setup' or stage == 'execute' or stage == 'verify' or stage == 'teardown':
58 if self.args.verbose:
59 print('adjust_command: stage is {}; inserting netns stuff in command [{}] list [{}]'.format(stage, command, cmdlist))
60 cmdlist.insert(0, self.args.NAMES['NS'])
61 cmdlist.insert(0, 'exec')
62 cmdlist.insert(0, 'netns')
63 cmdlist.insert(0, 'ip')
64 else:
65 pass
66
67 if cmdform == 'str':
68 command = ' '.join(cmdlist)
69 else:
70 command = cmdlist
71
72 if self.args.verbose:
73 print('adjust_command: return command [{}]'.format(command))
74 return command
75
76 def _ns_create(self):
77 '''
78 Create the network namespace in which the tests will be run and set up
79 the required network devices for it.
80 '''
81 if self.args.namespace:
82 cmd = 'ip netns add {}'.format(self.args.NAMES['NS'])
83 self._exec_cmd('pre', cmd)
84 cmd = 'ip link add $DEV0 type veth peer name $DEV1'
85 self._exec_cmd('pre', cmd)
86 cmd = 'ip link set $DEV1 netns {}'.format(self.args.NAMES['NS'])
87 self._exec_cmd('pre', cmd)
88 cmd = 'ip link set $DEV0 up'
89 self._exec_cmd('pre', cmd)
90 cmd = 'ip -n {} link set $DEV1 up'.format(self.args.NAMES['NS'])
91 self._exec_cmd('pre', cmd)
92 if self.args.device:
93 cmd = 'ip link set $DEV2 netns {}'.format(self.args.NAMES['NS'])
94 self._exec_cmd('pre', cmd)
95 cmd = 'ip -n {} link set $DEV2 up'.format(self.args.NAMES['NS'])
96 self._exec_cmd('pre', cmd)
97
98 def _ns_destroy(self):
99 '''
100 Destroy the network namespace for testing (and any associated network
101 devices as well)
102 '''
103 if self.args.namespace:
104 cmd = 'ip netns delete {}'.format(self.args.NAMES['NS'])
105 self._exec_cmd('post', cmd)
106
107 def _exec_cmd(self, stage, command):
108 '''
109 Perform any required modifications on an executable command, then run
110 it in a subprocess and return the results.
111 '''
112 if '$' in command:
113 command = self._replace_keywords(command)
114
115 self.adjust_command(stage, command)
116 if self.args.verbose:
117 print('_exec_cmd: command "{}"'.format(command))
118 proc = subprocess.Popen(command,
119 shell=True,
120 stdout=subprocess.PIPE,
121 stderr=subprocess.PIPE,
122 env=ENVIR)
123 (rawout, serr) = proc.communicate()
124
125 if proc.returncode != 0 and len(serr) > 0:
126 foutput = serr.decode("utf-8")
127 else:
128 foutput = rawout.decode("utf-8")
129
130 proc.stdout.close()
131 proc.stderr.close()
132 return proc, foutput
133
134 def _replace_keywords(self, cmd):
135 """
136 For a given executable command, substitute any known
137 variables contained within NAMES with the correct values
138 """
139 tcmd = Template(cmd)
140 subcmd = tcmd.safe_substitute(self.args.NAMES)
141 return subcmd
diff --git a/tools/testing/selftests/tc-testing/plugin-lib/rootPlugin.py b/tools/testing/selftests/tc-testing/plugin-lib/rootPlugin.py
new file mode 100644
index 000000000000..e36775bd4d12
--- /dev/null
+++ b/tools/testing/selftests/tc-testing/plugin-lib/rootPlugin.py
@@ -0,0 +1,19 @@
1import os
2import sys
3from TdcPlugin import TdcPlugin
4
5from tdc_config import *
6
7
8class SubPlugin(TdcPlugin):
9 def __init__(self):
10 self.sub_class = 'root/SubPlugin'
11 super().__init__()
12
13 def pre_suite(self, testcount, testidlist):
14 # run commands before test_runner goes into a test loop
15 super().pre_suite(testcount, testidlist)
16
17 if os.geteuid():
18 print('This script must be run with root privileges', file=sys.stderr)
19 exit(1)
diff --git a/tools/testing/selftests/tc-testing/plugin-lib/valgrindPlugin.py b/tools/testing/selftests/tc-testing/plugin-lib/valgrindPlugin.py
new file mode 100644
index 000000000000..477a7bd7d7fb
--- /dev/null
+++ b/tools/testing/selftests/tc-testing/plugin-lib/valgrindPlugin.py
@@ -0,0 +1,142 @@
1'''
2run the command under test, under valgrind and collect memory leak info
3as a separate test.
4'''
5
6
7import os
8import re
9import signal
10from string import Template
11import subprocess
12import time
13from TdcPlugin import TdcPlugin
14
15from tdc_config import *
16
17def vp_extract_num_from_string(num_as_string_maybe_with_commas):
18 return int(num_as_string_maybe_with_commas.replace(',',''))
19
20class SubPlugin(TdcPlugin):
21 def __init__(self):
22 self.sub_class = 'valgrind/SubPlugin'
23 self.tap = ''
24 super().__init__()
25
26 def pre_suite(self, testcount, testidlist):
27 '''run commands before test_runner goes into a test loop'''
28 super().pre_suite(testcount, testidlist)
29 if self.args.verbose > 1:
30 print('{}.pre_suite'.format(self.sub_class))
31 if self.args.valgrind:
32 self._add_to_tap('1..{}\n'.format(self.testcount))
33
34 def post_suite(self, index):
35 '''run commands after test_runner goes into a test loop'''
36 super().post_suite(index)
37 self._add_to_tap('\n|---\n')
38 if self.args.verbose > 1:
39 print('{}.post_suite'.format(self.sub_class))
40 print('{}'.format(self.tap))
41 if self.args.verbose < 4:
42 subprocess.check_output('rm -f vgnd-*.log', shell=True)
43
44 def add_args(self, parser):
45 super().add_args(parser)
46 self.argparser_group = self.argparser.add_argument_group(
47 'valgrind',
48 'options for valgrindPlugin (run command under test under Valgrind)')
49
50 self.argparser_group.add_argument(
51 '-V', '--valgrind', action='store_true',
52 help='Run commands under valgrind')
53
54 return self.argparser
55
56 def adjust_command(self, stage, command):
57 super().adjust_command(stage, command)
58 cmdform = 'list'
59 cmdlist = list()
60
61 if not self.args.valgrind:
62 return command
63
64 if self.args.verbose > 1:
65 print('{}.adjust_command'.format(self.sub_class))
66
67 if not isinstance(command, list):
68 cmdform = 'str'
69 cmdlist = command.split()
70 else:
71 cmdlist = command
72
73 if stage == 'execute':
74 if self.args.verbose > 1:
75 print('adjust_command: stage is {}; inserting valgrind stuff in command [{}] list [{}]'.
76 format(stage, command, cmdlist))
77 cmdlist.insert(0, '--track-origins=yes')
78 cmdlist.insert(0, '--show-leak-kinds=definite,indirect')
79 cmdlist.insert(0, '--leak-check=full')
80 cmdlist.insert(0, '--log-file=vgnd-{}.log'.format(self.args.testid))
81 cmdlist.insert(0, '-v') # ask for summary of non-leak errors
82 cmdlist.insert(0, ENVIR['VALGRIND_BIN'])
83 else:
84 pass
85
86 if cmdform == 'str':
87 command = ' '.join(cmdlist)
88 else:
89 command = cmdlist
90
91 if self.args.verbose > 1:
92 print('adjust_command: return command [{}]'.format(command))
93 return command
94
95 def post_execute(self):
96 if not self.args.valgrind:
97 return
98
99 self.definitely_lost_re = re.compile(
100 r'definitely lost:\s+([,0-9]+)\s+bytes in\s+([,0-9]+)\sblocks', re.MULTILINE | re.DOTALL)
101 self.indirectly_lost_re = re.compile(
102 r'indirectly lost:\s+([,0-9]+)\s+bytes in\s+([,0-9]+)\s+blocks', re.MULTILINE | re.DOTALL)
103 self.possibly_lost_re = re.compile(
104 r'possibly lost:\s+([,0-9]+)bytes in\s+([,0-9]+)\s+blocks', re.MULTILINE | re.DOTALL)
105 self.non_leak_error_re = re.compile(
106 r'ERROR SUMMARY:\s+([,0-9]+) errors from\s+([,0-9]+)\s+contexts', re.MULTILINE | re.DOTALL)
107
108 def_num = 0
109 ind_num = 0
110 pos_num = 0
111 nle_num = 0
112
113 # what about concurrent test runs? Maybe force them to be in different directories?
114 with open('vgnd-{}.log'.format(self.args.testid)) as vfd:
115 content = vfd.read()
116 def_mo = self.definitely_lost_re.search(content)
117 ind_mo = self.indirectly_lost_re.search(content)
118 pos_mo = self.possibly_lost_re.search(content)
119 nle_mo = self.non_leak_error_re.search(content)
120
121 if def_mo:
122 def_num = int(def_mo.group(2))
123 if ind_mo:
124 ind_num = int(ind_mo.group(2))
125 if pos_mo:
126 pos_num = int(pos_mo.group(2))
127 if nle_mo:
128 nle_num = int(nle_mo.group(1))
129
130 mem_results = ''
131 if (def_num > 0) or (ind_num > 0) or (pos_num > 0) or (nle_num > 0):
132 mem_results += 'not '
133
134 mem_results += 'ok {} - {}-mem # {}\n'.format(
135 self.args.test_ordinal, self.args.testid, 'memory leak check')
136 self._add_to_tap(mem_results)
137 if mem_results.startswith('not '):
138 print('{}'.format(content))
139 self._add_to_tap(content)
140
141 def _add_to_tap(self, more_tap_output):
142 self.tap += more_tap_output
diff --git a/tools/testing/selftests/tc-testing/plugins/__init__.py b/tools/testing/selftests/tc-testing/plugins/__init__.py
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/tools/testing/selftests/tc-testing/plugins/__init__.py
diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/csum.json b/tools/testing/selftests/tc-testing/tc-tests/actions/csum.json
new file mode 100644
index 000000000000..93cf8fea8ae7
--- /dev/null
+++ b/tools/testing/selftests/tc-testing/tc-tests/actions/csum.json
@@ -0,0 +1,410 @@
1[
2 {
3 "id": "6d84",
4 "name": "Add csum iph action",
5 "category": [
6 "actions",
7 "csum"
8 ],
9 "setup": [
10 [
11 "$TC actions flush action csum",
12 0,
13 1,
14 255
15 ]
16 ],
17 "cmdUnderTest": "$TC actions add action csum iph index 800",
18 "expExitCode": "0",
19 "verifyCmd": "$TC actions get action csum index 800",
20 "matchPattern": "action order [0-9]*: csum \\(iph\\) action pass.*index 800 ref",
21 "matchCount": "1",
22 "teardown": [
23 "$TC actions flush action csum"
24 ]
25 },
26 {
27 "id": "1862",
28 "name": "Add csum ip4h action",
29 "category": [
30 "actions",
31 "csum"
32 ],
33 "setup": [
34 [
35 "$TC actions flush action csum",
36 0,
37 1,
38 255
39 ]
40 ],
41 "cmdUnderTest": "$TC actions add action csum ip4h index 7",
42 "expExitCode": "0",
43 "verifyCmd": "$TC actions get action csum index 7",
44 "matchPattern": "action order [0-9]*: csum \\(iph\\) action pass.*index 7 ref",
45 "matchCount": "1",
46 "teardown": [
47 "$TC actions flush action csum"
48 ]
49 },
50 {
51 "id": "15c6",
52 "name": "Add csum ipv4h action",
53 "category": [
54 "actions",
55 "csum"
56 ],
57 "setup": [
58 [
59 "$TC actions flush action csum",
60 0,
61 1,
62 255
63 ]
64 ],
65 "cmdUnderTest": "$TC actions add action csum ipv4h index 1122",
66 "expExitCode": "0",
67 "verifyCmd": "$TC actions get action csum index 1122",
68 "matchPattern": "action order [0-9]*: csum \\(iph\\) action pass.*index 1122 ref",
69 "matchCount": "1",
70 "teardown": [
71 "$TC actions flush action csum"
72 ]
73 },
74 {
75 "id": "bf47",
76 "name": "Add csum icmp action",
77 "category": [
78 "actions",
79 "csum"
80 ],
81 "setup": [
82 [
83 "$TC actions flush action csum",
84 0,
85 1,
86 255
87 ]
88 ],
89 "cmdUnderTest": "$TC actions add action csum icmp index 1",
90 "expExitCode": "0",
91 "verifyCmd": "$TC actions get action csum index 1",
92 "matchPattern": "action order [0-9]*: csum \\(icmp\\) action pass.*index 1 ref",
93 "matchCount": "1",
94 "teardown": [
95 "$TC actions flush action csum"
96 ]
97 },
98 {
99 "id": "cc1d",
100 "name": "Add csum igmp action",
101 "category": [
102 "actions",
103 "csum"
104 ],
105 "setup": [
106 [
107 "$TC actions flush action csum",
108 0,
109 1,
110 255
111 ]
112 ],
113 "cmdUnderTest": "$TC actions add action csum igmp index 999",
114 "expExitCode": "0",
115 "verifyCmd": "$TC actions get action csum index 999",
116 "matchPattern": "action order [0-9]*: csum \\(igmp\\) action pass.*index 999 ref",
117 "matchCount": "1",
118 "teardown": [
119 "$TC actions flush action csum"
120 ]
121 },
122 {
123 "id": "bccc",
124 "name": "Add csum foobar action",
125 "category": [
126 "actions",
127 "csum"
128 ],
129 "setup": [
130 [
131 "$TC actions flush action csum",
132 0,
133 1,
134 255
135 ]
136 ],
137 "cmdUnderTest": "$TC actions add action csum foobar index 1",
138 "expExitCode": "255",
139 "verifyCmd": "$TC actions ls action csum",
140 "matchPattern": "action order [0-9]*: csum \\(foobar\\) action pass.*index 1 ref",
141 "matchCount": "0",
142 "teardown": [
143 "$TC actions flush action csum"
144 ]
145 },
146 {
147 "id": "3bb4",
148 "name": "Add csum tcp action",
149 "category": [
150 "actions",
151 "csum"
152 ],
153 "setup": [
154 [
155 "$TC actions flush action csum",
156 0,
157 1,
158 255
159 ]
160 ],
161 "cmdUnderTest": "$TC actions add action csum tcp index 9999",
162 "expExitCode": "0",
163 "verifyCmd": "$TC actions get action csum index 9999",
164 "matchPattern": "action order [0-9]*: csum \\(tcp\\) action pass.*index 9999 ref",
165 "matchCount": "1",
166 "teardown": [
167 "$TC actions flush action csum"
168 ]
169 },
170 {
171 "id": "759c",
172 "name": "Add csum udp action",
173 "category": [
174 "actions",
175 "csum"
176 ],
177 "setup": [
178 [
179 "$TC actions flush action csum",
180 0,
181 1,
182 255
183 ]
184 ],
185 "cmdUnderTest": "$TC actions add action csum udp index 334455",
186 "expExitCode": "0",
187 "verifyCmd": "$TC actions get action csum index 334455",
188 "matchPattern": "action order [0-9]*: csum \\(udp\\) action pass.*index 334455 ref",
189 "matchCount": "1",
190 "teardown": [
191 "$TC actions flush action csum"
192 ]
193 },
194 {
195 "id": "bdb6",
196 "name": "Add csum udp xor iph action",
197 "category": [
198 "actions",
199 "csum"
200 ],
201 "setup": [
202 [
203 "$TC actions flush action csum",
204 0,
205 1,
206 255
207 ]
208 ],
209 "cmdUnderTest": "$TC actions add action csum udp xor iph index 3",
210 "expExitCode": "255",
211 "verifyCmd": "$TC actions ls action csum",
212 "matchPattern": "action order [0-9]*: csum \\(udp xor iph\\) action pass.*index 3 ref",
213 "matchCount": "0",
214 "teardown": [
215 "$TC actions flush action csum"
216 ]
217 },
218 {
219 "id": "c220",
220 "name": "Add csum udplite action",
221 "category": [
222 "actions",
223 "csum"
224 ],
225 "setup": [
226 [
227 "$TC actions flush action csum",
228 0,
229 1,
230 255
231 ]
232 ],
233 "cmdUnderTest": "$TC actions add action csum udplite continue index 3",
234 "expExitCode": "0",
235 "verifyCmd": "$TC actions get action csum index 3",
236 "matchPattern": "action order [0-9]*: csum \\(udplite\\) action continue.*index 3 ref",
237 "matchCount": "1",
238 "teardown": [
239 "$TC actions flush action csum"
240 ]
241 },
242 {
243 "id": "8993",
244 "name": "Add csum sctp action",
245 "category": [
246 "actions",
247 "csum"
248 ],
249 "setup": [
250 [
251 "$TC actions flush action csum",
252 0,
253 1,
254 255
255 ]
256 ],
257 "cmdUnderTest": "$TC actions add action csum sctp index 777",
258 "expExitCode": "0",
259 "verifyCmd": "$TC actions get action csum index 777",
260 "matchPattern": "action order [0-9]*: csum \\(sctp\\) action pass.*index 777 ref",
261 "matchCount": "1",
262 "teardown": [
263 "$TC actions flush action csum"
264 ]
265 },
266 {
267 "id": "b138",
268 "name": "Add csum ip & icmp action",
269 "category": [
270 "actions",
271 "csum"
272 ],
273 "setup": [
274 [
275 "$TC actions flush action csum",
276 0,
277 1,
278 255
279 ]
280 ],
281 "cmdUnderTest": "$TC actions add action csum ip and icmp pipe index 123",
282 "expExitCode": "0",
283 "verifyCmd": "$TC actions get action csum index 123",
284 "matchPattern": "action order [0-9]*: csum \\(iph, icmp\\) action pipe.*index 123 ref",
285 "matchCount": "1",
286 "teardown": [
287 "$TC actions flush action csum"
288 ]
289 },
290 {
291 "id": "eeda",
292 "name": "Add csum ip & sctp action",
293 "category": [
294 "actions",
295 "csum"
296 ],
297 "setup": [
298 [
299 "$TC actions flush action csum",
300 0,
301 1,
302 255
303 ]
304 ],
305 "cmdUnderTest": "$TC actions add action csum ipv4h sctp continue index 2",
306 "expExitCode": "0",
307 "verifyCmd": "$TC actions get action csum index 2",
308 "matchPattern": "action order [0-9]*: csum \\(iph, sctp\\) action continue.*index 2 ref",
309 "matchCount": "1",
310 "teardown": [
311 "$TC actions flush action csum"
312 ]
313 },
314 {
315 "id": "0017",
316 "name": "Add csum udp or tcp action",
317 "category": [
318 "actions",
319 "csum"
320 ],
321 "setup": [
322 [
323 "$TC actions flush action csum",
324 0,
325 1,
326 255
327 ]
328 ],
329 "cmdUnderTest": "$TC actions add action csum udp or tcp continue index 27",
330 "expExitCode": "0",
331 "verifyCmd": "$TC actions get action csum index 27",
332 "matchPattern": "action order [0-9]*: csum \\(tcp, udp\\) action continue.*index 27 ref",
333 "matchCount": "1",
334 "teardown": [
335 "$TC actions flush action csum"
336 ]
337 },
338 {
339 "id": "ce92",
340 "name": "Add csum udp action with cookie",
341 "category": [
342 "actions",
343 "csum"
344 ],
345 "setup": [
346 [
347 "$TC actions flush action csum",
348 0,
349 1,
350 255
351 ]
352 ],
353 "cmdUnderTest": "$TC actions add action csum udp pipe index 7 cookie 12345678",
354 "expExitCode": "0",
355 "verifyCmd": "$TC actions get action csum index 7",
356 "matchPattern": "action order [0-9]*: csum \\(udp\\) action pipe.*index 7.*cookie 12345678",
357 "matchCount": "1",
358 "teardown": [
359 "$TC actions flush action csum"
360 ]
361 },
362 {
363 "id": "912f",
364 "name": "Add csum icmp action with large cookie",
365 "category": [
366 "actions",
367 "csum"
368 ],
369 "setup": [
370 [
371 "$TC actions flush action csum",
372 0,
373 1,
374 255
375 ]
376 ],
377 "cmdUnderTest": "$TC actions add action csum icmp pipe index 17 cookie aabbccddeeff1122",
378 "expExitCode": "0",
379 "verifyCmd": "$TC actions get action csum index 17",
380 "matchPattern": "action order [0-9]*: csum \\(icmp\\) action pipe.*index 17.*cookie aabbccddeeff1122",
381 "matchCount": "1",
382 "teardown": [
383 "$TC actions flush action csum"
384 ]
385 },
386 {
387 "id": "879b",
388 "name": "Add batch of 32 csum tcp actions",
389 "category": [
390 "actions",
391 "csum"
392 ],
393 "setup": [
394 [
395 "$TC actions flush action csum",
396 0,
397 1,
398 255
399 ]
400 ],
401 "cmdUnderTest": "for i in `seq 1 32`; do cmd=\"action csum tcp continue index $i \"; args=\"$args$cmd\"; done && $TC actions add $args",
402 "expExitCode": "255",
403 "verifyCmd": "$TC actions ls action csum",
404 "matchPattern": "^[ \t]+index [0-9]* ref",
405 "matchCount": "32",
406 "teardown": [
407 "$TC actions flush action csum"
408 ]
409 }
410]
diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/gact.json b/tools/testing/selftests/tc-testing/tc-tests/actions/gact.json
index e2187b6e0b7a..ae96d0350d7e 100644
--- a/tools/testing/selftests/tc-testing/tc-tests/actions/gact.json
+++ b/tools/testing/selftests/tc-testing/tc-tests/actions/gact.json
@@ -465,5 +465,76 @@
465 "teardown": [ 465 "teardown": [
466 "$TC actions flush action gact" 466 "$TC actions flush action gact"
467 ] 467 ]
468 },
469 {
470 "id": "1021",
471 "name": "Add batch of 32 gact pass actions",
472 "category": [
473 "actions",
474 "gact"
475 ],
476 "setup": [
477 [
478 "$TC actions flush action gact",
479 0,
480 1,
481 255
482 ]
483 ],
484 "cmdUnderTest": "for i in `seq 1 32`; do cmd=\"action pass index $i \"; args=\"$args$cmd\"; done && $TC actions add $args",
485 "expExitCode": "0",
486 "verifyCmd": "$TC actions list action gact",
487 "matchPattern": "^[ \t]+index [0-9]+ ref",
488 "matchCount": "32",
489 "teardown": [
490 "$TC actions flush action gact"
491 ]
492 },
493 {
494 "id": "da7a",
495 "name": "Add batch of 32 gact continue actions with cookie",
496 "category": [
497 "actions",
498 "gact"
499 ],
500 "setup": [
501 [
502 "$TC actions flush action gact",
503 0,
504 1,
505 255
506 ]
507 ],
508 "cmdUnderTest": "for i in `seq 1 32`; do cmd=\"action continue index $i cookie aabbccddeeff112233445566778800a1 \"; args=\"$args$cmd\"; done && $TC actions add $args",
509 "expExitCode": "0",
510 "verifyCmd": "$TC actions list action gact",
511 "matchPattern": "^[ \t]+index [0-9]+ ref",
512 "matchCount": "32",
513 "teardown": [
514 "$TC actions flush action gact"
515 ]
516 },
517 {
518 "id": "8aa3",
519 "name": "Delete batch of 32 gact continue actions",
520 "category": [
521 "actions",
522 "gact"
523 ],
524 "setup": [
525 [
526 "$TC actions flush action gact",
527 0,
528 1,
529 255
530 ],
531 "for i in `seq 1 32`; do cmd=\"action continue index $i \"; args=\"$args$cmd\"; done && $TC actions add $args"
532 ],
533 "cmdUnderTest": "for i in `seq 1 32`; do cmd=\"action gact index $i \"; args=\"$args$cmd\"; done && $TC actions del $args",
534 "expExitCode": "0",
535 "verifyCmd": "$TC actions list action gact",
536 "matchPattern": "^[ \t]+index [0-9]+ ref",
537 "matchCount": "0",
538 "teardown": []
468 } 539 }
469] 540] \ No newline at end of file
diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/vlan.json b/tools/testing/selftests/tc-testing/tc-tests/actions/vlan.json
new file mode 100644
index 000000000000..4510ddfa6e54
--- /dev/null
+++ b/tools/testing/selftests/tc-testing/tc-tests/actions/vlan.json
@@ -0,0 +1,410 @@
1[
2 {
3 "id": "6f5a",
4 "name": "Add vlan pop action",
5 "category": [
6 "actions",
7 "vlan"
8 ],
9 "setup": [
10 [
11 "$TC actions flush action vlan",
12 0,
13 1,
14 255
15 ]
16 ],
17 "cmdUnderTest": "$TC actions add action vlan pop index 8",
18 "expExitCode": "0",
19 "verifyCmd": "$TC actions list action vlan",
20 "matchPattern": "action order [0-9]+: vlan.*pop.*index 8 ref",
21 "matchCount": "1",
22 "teardown": [
23 "$TC actions flush action vlan"
24 ]
25 },
26 {
27 "id": "ee6f",
28 "name": "Add vlan pop action with large index",
29 "category": [
30 "actions",
31 "vlan"
32 ],
33 "setup": [
34 [
35 "$TC actions flush action vlan",
36 0,
37 1,
38 255
39 ]
40 ],
41 "cmdUnderTest": "$TC actions add action vlan pop index 4294967295",
42 "expExitCode": "0",
43 "verifyCmd": "$TC actions list action vlan",
44 "matchPattern": "action order [0-9]+: vlan.*pop.*index 4294967295 ref",
45 "matchCount": "1",
46 "teardown": [
47 "$TC actions flush action vlan"
48 ]
49 },
50 {
51 "id": "b6b9",
52 "name": "Add vlan pop action with jump opcode",
53 "category": [
54 "actions",
55 "vlan"
56 ],
57 "setup": [
58 [
59 "$TC actions flush action vlan",
60 0,
61 1,
62 255
63 ]
64 ],
65 "cmdUnderTest": "$TC actions add action vlan pop jump 10 index 8",
66 "expExitCode": "0",
67 "verifyCmd": "$TC actions list action vlan",
68 "matchPattern": "action order [0-9]+: vlan.*jump 10.*index 8 ref",
69 "matchCount": "1",
70 "teardown": [
71 "$TC actions flush action vlan"
72 ]
73 },
74 {
75 "id": "87c3",
76 "name": "Add vlan pop action with trap opcode",
77 "category": [
78 "actions",
79 "vlan"
80 ],
81 "setup": [
82 [
83 "$TC actions flush action vlan",
84 0,
85 1,
86 255
87 ]
88 ],
89 "cmdUnderTest": "$TC actions add action vlan pop trap index 8",
90 "expExitCode": "0",
91 "verifyCmd": "$TC actions list action vlan",
92 "matchPattern": "action order [0-9]+: vlan.*pop trap.*index 8 ref",
93 "matchCount": "1",
94 "teardown": [
95 "$TC actions flush action vlan"
96 ]
97 },
98 {
99 "id": "2b91",
100 "name": "Add vlan invalid action",
101 "category": [
102 "actions",
103 "vlan"
104 ],
105 "setup": [
106 [
107 "$TC actions flush action vlan",
108 0,
109 1,
110 255
111 ]
112 ],
113 "cmdUnderTest": "$TC actions add action vlan bad_mode",
114 "expExitCode": "255",
115 "verifyCmd": "$TC actions list action vlan",
116 "matchPattern": "action order [0-9]+: vlan.*bad_mode",
117 "matchCount": "0",
118 "teardown": [
119 "$TC actions flush action vlan"
120 ]
121 },
122 {
123 "id": "57fc",
124 "name": "Add vlan action with invalid protocol type",
125 "category": [
126 "actions",
127 "vlan"
128 ],
129 "setup": [
130 [
131 "$TC actions flush action vlan",
132 0,
133 1,
134 255
135 ]
136 ],
137 "cmdUnderTest": "$TC actions add action vlan push protocol ABCD",
138 "expExitCode": "255",
139 "verifyCmd": "$TC actions list action vlan",
140 "matchPattern": "action order [0-9]+: vlan.*push",
141 "matchCount": "0",
142 "teardown": [
143 "$TC actions flush action vlan"
144 ]
145 },
146 {
147 "id": "3989",
148 "name": "Add vlan push action with default protocol and priority",
149 "category": [
150 "actions",
151 "vlan"
152 ],
153 "setup": [
154 [
155 "$TC actions flush action vlan",
156 0,
157 1,
158 255
159 ]
160 ],
161 "cmdUnderTest": "$TC actions add action vlan push id 123 index 18",
162 "expExitCode": "0",
163 "verifyCmd": "$TC actions get action vlan index 18",
164 "matchPattern": "action order [0-9]+: vlan.*push id 123 protocol 802.1Q priority 0 pipe.*index 18 ref",
165 "matchCount": "1",
166 "teardown": [
167 "$TC actions flush action vlan"
168 ]
169 },
170 {
171 "id": "79dc",
172 "name": "Add vlan push action with protocol 802.1Q and priority 3",
173 "category": [
174 "actions",
175 "vlan"
176 ],
177 "setup": [
178 [
179 "$TC actions flush action vlan",
180 0,
181 1,
182 255
183 ]
184 ],
185 "cmdUnderTest": "$TC actions add action vlan push id 77 protocol 802.1Q priority 3 continue index 734",
186 "expExitCode": "0",
187 "verifyCmd": "$TC actions get action vlan index 734",
188 "matchPattern": "action order [0-9]+: vlan.*push id 77 protocol 802.1Q priority 3 continue.*index 734 ref",
189 "matchCount": "1",
190 "teardown": [
191 "$TC actions flush action vlan"
192 ]
193 },
194 {
195 "id": "4d73",
196 "name": "Add vlan push action with protocol 802.1AD",
197 "category": [
198 "actions",
199 "vlan"
200 ],
201 "setup": [
202 [
203 "$TC actions flush action vlan",
204 0,
205 1,
206 255
207 ]
208 ],
209 "cmdUnderTest": "$TC actions add action vlan push id 1024 protocol 802.1AD pass index 10000",
210 "expExitCode": "0",
211 "verifyCmd": "$TC actions get action vlan index 10000",
212 "matchPattern": "action order [0-9]+: vlan.*push id 1024 protocol 802.1ad priority 0 pass.*index 10000 ref",
213 "matchCount": "1",
214 "teardown": [
215 "$TC actions flush action vlan"
216 ]
217 },
218 {
219 "id": "1f7b",
220 "name": "Add vlan push action with invalid vlan ID",
221 "category": [
222 "actions",
223 "vlan"
224 ],
225 "setup": [
226 [
227 "$TC actions flush action vlan",
228 0,
229 1,
230 255
231 ]
232 ],
233 "cmdUnderTest": "$TC actions add action vlan push id 5678 index 1",
234 "expExitCode": "255",
235 "verifyCmd": "$TC actions list action vlan",
236 "matchPattern": "action order [0-9]+: vlan.*push id 5678.*index 1 ref",
237 "matchCount": "0",
238 "teardown": [
239 "$TC actions flush action vlan"
240 ]
241 },
242 {
243 "id": "5d02",
244 "name": "Add vlan push action with invalid IEEE 802.1p priority",
245 "category": [
246 "actions",
247 "vlan"
248 ],
249 "setup": [
250 [
251 "$TC actions flush action vlan",
252 0,
253 1,
254 255
255 ]
256 ],
257 "cmdUnderTest": "$TC actions add action vlan push id 5 priority 10 index 1",
258 "expExitCode": "255",
259 "verifyCmd": "$TC actions list action vlan",
260 "matchPattern": "action order [0-9]+: vlan.*push id 5.*index 1 ref",
261 "matchCount": "0",
262 "teardown": [
263 "$TC actions flush action vlan"
264 ]
265 },
266 {
267 "id": "6812",
268 "name": "Add vlan modify action for protocol 802.1Q",
269 "category": [
270 "actions",
271 "vlan"
272 ],
273 "setup": [
274 [
275 "$TC actions flush action vlan",
276 0,
277 1,
278 255
279 ]
280 ],
281 "cmdUnderTest": "$TC actions add action vlan modify protocol 802.1Q id 5 index 100",
282 "expExitCode": "0",
283 "verifyCmd": "$TC actions get action vlan index 100",
284 "matchPattern": "action order [0-9]+: vlan.*modify id 100 protocol 802.1Q priority 0 pipe.*index 100 ref",
285 "matchCount": "0",
286 "teardown": [
287 "$TC actions flush action vlan"
288 ]
289 },
290 {
291 "id": "5a31",
292 "name": "Add vlan modify action for protocol 802.1AD",
293 "category": [
294 "actions",
295 "vlan"
296 ],
297 "setup": [
298 [
299 "$TC actions flush action vlan",
300 0,
301 1,
302 255
303 ]
304 ],
305 "cmdUnderTest": "$TC actions add action vlan modify protocol 802.1ad id 500 reclassify index 12",
306 "expExitCode": "0",
307 "verifyCmd": "$TC actions get action vlan index 12",
308 "matchPattern": "action order [0-9]+: vlan.*modify id 500 protocol 802.1ad priority 0 reclassify.*index 12 ref",
309 "matchCount": "1",
310 "teardown": [
311 "$TC actions flush action vlan"
312 ]
313 },
314 {
315 "id": "83a4",
316 "name": "Delete vlan pop action",
317 "category": [
318 "actions",
319 "vlan"
320 ],
321 "setup": [
322 [
323 "$TC actions flush action vlan",
324 0,
325 1,
326 255
327 ],
328 "$TC actions add action vlan pop index 44"
329 ],
330 "cmdUnderTest": "$TC actions del action vlan index 44",
331 "expExitCode": "0",
332 "verifyCmd": "$TC actions list action vlan",
333 "matchPattern": "action order [0-9]+: vlan.*pop.*index 44 ref",
334 "matchCount": "0",
335 "teardown": []
336 },
337 {
338 "id": "ed1e",
339 "name": "Delete vlan push action for protocol 802.1Q",
340 "category": [
341 "actions",
342 "vlan"
343 ],
344 "setup": [
345 [
346 "$TC actions flush action vlan",
347 0,
348 1,
349 255
350 ],
351 "$TC actions add action vlan push id 4094 protocol 802.1Q index 999"
352 ],
353 "cmdUnderTest": "$TC actions del action vlan index 999",
354 "expExitCode": "0",
355 "verifyCmd": "$TC actions list action vlan",
356 "matchPattern": "action order [0-9]+: vlan.*push id 4094 protocol 802.1Q priority 0 pipe.*index 999 ref",
357 "matchCount": "0",
358 "teardown": []
359 },
360 {
361 "id": "a2a3",
362 "name": "Flush vlan actions",
363 "category": [
364 "actions",
365 "vlan"
366 ],
367 "setup": [
368 [
369 "$TC actions flush action vlan",
370 0,
371 1,
372 255
373 ],
374 "$TC actions add action vlan push id 4 protocol 802.1ad index 10",
375 "$TC actions add action vlan push id 4 protocol 802.1ad index 11",
376 "$TC actions add action vlan push id 4 protocol 802.1ad index 12",
377 "$TC actions add action vlan push id 4 protocol 802.1ad index 13"
378 ],
379 "cmdUnderTest": "$TC actions flush action vlan",
380 "expExitCode": "0",
381 "verifyCmd": "$TC actions list action vlan",
382 "matchPattern": "action order [0-9]+: vlan.*push id 4 protocol 802.1ad",
383 "matchCount": "0",
384 "teardown": []
385 },
386 {
387 "id": "1d78",
388 "name": "Add vlan action with cookie",
389 "category": [
390 "actions",
391 "vlan"
392 ],
393 "setup": [
394 [
395 "$TC actions flush action vlan",
396 0,
397 1,
398 255
399 ]
400 ],
401 "cmdUnderTest": "$TC actions add action vlan push id 4 cookie a0a0a0a0a0a0a0",
402 "expExitCode": "0",
403 "verifyCmd": "$TC actions list action vlan",
404 "matchPattern": "action order [0-9]+: vlan.*push id 4.*cookie a0a0a0a0a0a0a0",
405 "matchCount": "1",
406 "teardown": [
407 "$TC actions flush action vlan"
408 ]
409 }
410]
diff --git a/tools/testing/selftests/tc-testing/tdc.py b/tools/testing/selftests/tc-testing/tdc.py
index fc373fdf2bdc..44de4a272a11 100755
--- a/tools/testing/selftests/tc-testing/tdc.py
+++ b/tools/testing/selftests/tc-testing/tdc.py
@@ -11,16 +11,96 @@ import re
11import os 11import os
12import sys 12import sys
13import argparse 13import argparse
14import importlib
14import json 15import json
15import subprocess 16import subprocess
17import time
18import traceback
16from collections import OrderedDict 19from collections import OrderedDict
17from string import Template 20from string import Template
18 21
19from tdc_config import * 22from tdc_config import *
20from tdc_helper import * 23from tdc_helper import *
21 24
22 25import TdcPlugin
23USE_NS = True 26
27
28class PluginMgrTestFail(Exception):
29 def __init__(self, stage, output, message):
30 self.stage = stage
31 self.output = output
32 self.message = message
33
34class PluginMgr:
35 def __init__(self, argparser):
36 super().__init__()
37 self.plugins = {}
38 self.plugin_instances = []
39 self.args = []
40 self.argparser = argparser
41
42 # TODO, put plugins in order
43 plugindir = os.getenv('TDC_PLUGIN_DIR', './plugins')
44 for dirpath, dirnames, filenames in os.walk(plugindir):
45 for fn in filenames:
46 if (fn.endswith('.py') and
47 not fn == '__init__.py' and
48 not fn.startswith('#') and
49 not fn.startswith('.#')):
50 mn = fn[0:-3]
51 foo = importlib.import_module('plugins.' + mn)
52 self.plugins[mn] = foo
53 self.plugin_instances.append(foo.SubPlugin())
54
55 def call_pre_suite(self, testcount, testidlist):
56 for pgn_inst in self.plugin_instances:
57 pgn_inst.pre_suite(testcount, testidlist)
58
59 def call_post_suite(self, index):
60 for pgn_inst in reversed(self.plugin_instances):
61 pgn_inst.post_suite(index)
62
63 def call_pre_case(self, test_ordinal, testid):
64 for pgn_inst in self.plugin_instances:
65 try:
66 pgn_inst.pre_case(test_ordinal, testid)
67 except Exception as ee:
68 print('exception {} in call to pre_case for {} plugin'.
69 format(ee, pgn_inst.__class__))
70 print('test_ordinal is {}'.format(test_ordinal))
71 print('testid is {}'.format(testid))
72 raise
73
74 def call_post_case(self):
75 for pgn_inst in reversed(self.plugin_instances):
76 pgn_inst.post_case()
77
78 def call_pre_execute(self):
79 for pgn_inst in self.plugin_instances:
80 pgn_inst.pre_execute()
81
82 def call_post_execute(self):
83 for pgn_inst in reversed(self.plugin_instances):
84 pgn_inst.post_execute()
85
86 def call_add_args(self, parser):
87 for pgn_inst in self.plugin_instances:
88 parser = pgn_inst.add_args(parser)
89 return parser
90
91 def call_check_args(self, args, remaining):
92 for pgn_inst in self.plugin_instances:
93 pgn_inst.check_args(args, remaining)
94
95 def call_adjust_command(self, stage, command):
96 for pgn_inst in self.plugin_instances:
97 command = pgn_inst.adjust_command(stage, command)
98 return command
99
100 @staticmethod
101 def _make_argparser(args):
102 self.argparser = argparse.ArgumentParser(
103 description='Linux TC unit tests')
24 104
25 105
26def replace_keywords(cmd): 106def replace_keywords(cmd):
@@ -33,21 +113,24 @@ def replace_keywords(cmd):
33 return subcmd 113 return subcmd
34 114
35 115
36def exec_cmd(command, nsonly=True): 116def exec_cmd(args, pm, stage, command):
37 """ 117 """
38 Perform any required modifications on an executable command, then run 118 Perform any required modifications on an executable command, then run
39 it in a subprocess and return the results. 119 it in a subprocess and return the results.
40 """ 120 """
41 if (USE_NS and nsonly): 121 if len(command.strip()) == 0:
42 command = 'ip netns exec $NS ' + command 122 return None, None
43
44 if '$' in command: 123 if '$' in command:
45 command = replace_keywords(command) 124 command = replace_keywords(command)
46 125
126 command = pm.call_adjust_command(stage, command)
127 if args.verbose > 0:
128 print('command "{}"'.format(command))
47 proc = subprocess.Popen(command, 129 proc = subprocess.Popen(command,
48 shell=True, 130 shell=True,
49 stdout=subprocess.PIPE, 131 stdout=subprocess.PIPE,
50 stderr=subprocess.PIPE) 132 stderr=subprocess.PIPE,
133 env=ENVIR)
51 (rawout, serr) = proc.communicate() 134 (rawout, serr) = proc.communicate()
52 135
53 if proc.returncode != 0 and len(serr) > 0: 136 if proc.returncode != 0 and len(serr) > 0:
@@ -60,36 +143,99 @@ def exec_cmd(command, nsonly=True):
60 return proc, foutput 143 return proc, foutput
61 144
62 145
63def prepare_env(cmdlist): 146def prepare_env(args, pm, stage, prefix, cmdlist, output = None):
64 """ 147 """
65 Execute the setup/teardown commands for a test case. Optionally 148 Execute the setup/teardown commands for a test case.
66 terminate test execution if the command fails. 149 Optionally terminate test execution if the command fails.
67 """ 150 """
151 if args.verbose > 0:
152 print('{}'.format(prefix))
68 for cmdinfo in cmdlist: 153 for cmdinfo in cmdlist:
69 if (type(cmdinfo) == list): 154 if isinstance(cmdinfo, list):
70 exit_codes = cmdinfo[1:] 155 exit_codes = cmdinfo[1:]
71 cmd = cmdinfo[0] 156 cmd = cmdinfo[0]
72 else: 157 else:
73 exit_codes = [0] 158 exit_codes = [0]
74 cmd = cmdinfo 159 cmd = cmdinfo
75 160
76 if (len(cmd) == 0): 161 if not cmd:
77 continue 162 continue
78 163
79 (proc, foutput) = exec_cmd(cmd) 164 (proc, foutput) = exec_cmd(args, pm, stage, cmd)
165
166 if proc and (proc.returncode not in exit_codes):
167 print('', file=sys.stderr)
168 print("{} *** Could not execute: \"{}\"".format(prefix, cmd),
169 file=sys.stderr)
170 print("\n{} *** Error message: \"{}\"".format(prefix, foutput),
171 file=sys.stderr)
172 print("\n{} *** Aborting test run.".format(prefix), file=sys.stderr)
173 print("\n\n{} *** stdout ***".format(proc.stdout), file=sys.stderr)
174 print("\n\n{} *** stderr ***".format(proc.stderr), file=sys.stderr)
175 raise PluginMgrTestFail(
176 stage, output,
177 '"{}" did not complete successfully'.format(prefix))
178
179def run_one_test(pm, args, index, tidx):
180 global NAMES
181 result = True
182 tresult = ""
183 tap = ""
184 if args.verbose > 0:
185 print("\t====================\n=====> ", end="")
186 print("Test " + tidx["id"] + ": " + tidx["name"])
187
188 # populate NAMES with TESTID for this test
189 NAMES['TESTID'] = tidx['id']
190
191 pm.call_pre_case(index, tidx['id'])
192 prepare_env(args, pm, 'setup', "-----> prepare stage", tidx["setup"])
193
194 if (args.verbose > 0):
195 print('-----> execute stage')
196 pm.call_pre_execute()
197 (p, procout) = exec_cmd(args, pm, 'execute', tidx["cmdUnderTest"])
198 exit_code = p.returncode
199 pm.call_post_execute()
200
201 if (exit_code != int(tidx["expExitCode"])):
202 result = False
203 print("exit:", exit_code, int(tidx["expExitCode"]))
204 print(procout)
205 else:
206 if args.verbose > 0:
207 print('-----> verify stage')
208 match_pattern = re.compile(
209 str(tidx["matchPattern"]), re.DOTALL | re.MULTILINE)
210 (p, procout) = exec_cmd(args, pm, 'verify', tidx["verifyCmd"])
211 if procout:
212 match_index = re.findall(match_pattern, procout)
213 if len(match_index) != int(tidx["matchCount"]):
214 result = False
215 elif int(tidx["matchCount"]) != 0:
216 result = False
217
218 if not result:
219 tresult += 'not '
220 tresult += 'ok {} - {} # {}\n'.format(str(index), tidx['id'], tidx['name'])
221 tap += tresult
80 222
81 if proc.returncode not in exit_codes: 223 if result == False:
82 print 224 if procout:
83 print("Could not execute:") 225 tap += procout
84 print(cmd) 226 else:
85 print("\nError message:") 227 tap += 'No output!\n'
86 print(foutput) 228
87 print("\nAborting test run.") 229 prepare_env(args, pm, 'teardown', '-----> teardown stage', tidx['teardown'], procout)
88 ns_destroy() 230 pm.call_post_case()
89 exit(1)
90 231
232 index += 1
233
234 # remove TESTID from NAMES
235 del(NAMES['TESTID'])
236 return tap
91 237
92def test_runner(filtered_tests, args): 238def test_runner(pm, args, filtered_tests):
93 """ 239 """
94 Driver function for the unit tests. 240 Driver function for the unit tests.
95 241
@@ -101,75 +247,92 @@ def test_runner(filtered_tests, args):
101 testlist = filtered_tests 247 testlist = filtered_tests
102 tcount = len(testlist) 248 tcount = len(testlist)
103 index = 1 249 index = 1
104 tap = str(index) + ".." + str(tcount) + "\n" 250 tap = ''
105 251 badtest = None
252 stage = None
253 emergency_exit = False
254 emergency_exit_message = ''
255
256 if args.notap:
257 if args.verbose:
258 tap = 'notap requested: omitting test plan\n'
259 else:
260 tap = str(index) + ".." + str(tcount) + "\n"
261 try:
262 pm.call_pre_suite(tcount, [tidx['id'] for tidx in testlist])
263 except Exception as ee:
264 ex_type, ex, ex_tb = sys.exc_info()
265 print('Exception {} {} (caught in pre_suite).'.
266 format(ex_type, ex))
267 # when the extra print statements are uncommented,
268 # the traceback does not appear between them
269 # (it appears way earlier in the tdc.py output)
270 # so don't bother ...
271 # print('--------------------(')
272 # print('traceback')
273 traceback.print_tb(ex_tb)
274 # print('--------------------)')
275 emergency_exit_message = 'EMERGENCY EXIT, call_pre_suite failed with exception {} {}\n'.format(ex_type, ex)
276 emergency_exit = True
277 stage = 'pre-SUITE'
278
279 if emergency_exit:
280 pm.call_post_suite(index)
281 return emergency_exit_message
282 if args.verbose > 1:
283 print('give test rig 2 seconds to stabilize')
284 time.sleep(2)
106 for tidx in testlist: 285 for tidx in testlist:
107 result = True
108 tresult = ""
109 if "flower" in tidx["category"] and args.device == None: 286 if "flower" in tidx["category"] and args.device == None:
287 if args.verbose > 1:
288 print('Not executing test {} {} because DEV2 not defined'.
289 format(tidx['id'], tidx['name']))
110 continue 290 continue
111 print("Test " + tidx["id"] + ": " + tidx["name"]) 291 try:
112 prepare_env(tidx["setup"]) 292 badtest = tidx # in case it goes bad
113 (p, procout) = exec_cmd(tidx["cmdUnderTest"]) 293 tap += run_one_test(pm, args, index, tidx)
114 exit_code = p.returncode 294 except PluginMgrTestFail as pmtf:
115 295 ex_type, ex, ex_tb = sys.exc_info()
116 if (exit_code != int(tidx["expExitCode"])): 296 stage = pmtf.stage
117 result = False 297 message = pmtf.message
118 print("exit:", exit_code, int(tidx["expExitCode"])) 298 output = pmtf.output
119 print(procout) 299 print(message)
120 else: 300 print('Exception {} {} (caught in test_runner, running test {} {} {} stage {})'.
121 match_pattern = re.compile(str(tidx["matchPattern"]), re.DOTALL) 301 format(ex_type, ex, index, tidx['id'], tidx['name'], stage))
122 (p, procout) = exec_cmd(tidx["verifyCmd"]) 302 print('---------------')
123 match_index = re.findall(match_pattern, procout) 303 print('traceback')
124 if len(match_index) != int(tidx["matchCount"]): 304 traceback.print_tb(ex_tb)
125 result = False 305 print('---------------')
126 306 if stage == 'teardown':
127 if result == True: 307 print('accumulated output for this test:')
128 tresult += "ok " 308 if pmtf.output:
129 else: 309 print(pmtf.output)
130 tresult += "not ok " 310 print('---------------')
131 tap += tresult + str(index) + " " + tidx["id"] + " " + tidx["name"] + "\n" 311 break
132
133 if result == False:
134 tap += procout
135
136 prepare_env(tidx["teardown"])
137 index += 1 312 index += 1
138 313
139 return tap 314 # if we failed in setup or teardown,
140 315 # fill in the remaining tests with ok-skipped
316 count = index
317 if not args.notap:
318 tap += 'about to flush the tap output if tests need to be skipped\n'
319 if tcount + 1 != index:
320 for tidx in testlist[index - 1:]:
321 msg = 'skipped - previous {} failed'.format(stage)
322 tap += 'ok {} - {} # {} {} {}\n'.format(
323 count, tidx['id'], msg, index, badtest.get('id', '--Unknown--'))
324 count += 1
141 325
142def ns_create(): 326 tap += 'done flushing skipped test tap output\n'
143 """
144 Create the network namespace in which the tests will be run and set up
145 the required network devices for it.
146 """
147 if (USE_NS):
148 cmd = 'ip netns add $NS'
149 exec_cmd(cmd, False)
150 cmd = 'ip link add $DEV0 type veth peer name $DEV1'
151 exec_cmd(cmd, False)
152 cmd = 'ip link set $DEV1 netns $NS'
153 exec_cmd(cmd, False)
154 cmd = 'ip link set $DEV0 up'
155 exec_cmd(cmd, False)
156 cmd = 'ip -n $NS link set $DEV1 up'
157 exec_cmd(cmd, False)
158 cmd = 'ip link set $DEV2 netns $NS'
159 exec_cmd(cmd, False)
160 cmd = 'ip -n $NS link set $DEV2 up'
161 exec_cmd(cmd, False)
162 327
328 if args.pause:
329 print('Want to pause\nPress enter to continue ...')
330 if input(sys.stdin):
331 print('got something on stdin')
163 332
164def ns_destroy(): 333 pm.call_post_suite(index)
165 """
166 Destroy the network namespace for testing (and any associated network
167 devices as well)
168 """
169 if (USE_NS):
170 cmd = 'ip netns delete $NS'
171 exec_cmd(cmd, False)
172 334
335 return tap
173 336
174def has_blank_ids(idlist): 337def has_blank_ids(idlist):
175 """ 338 """
@@ -209,41 +372,70 @@ def set_args(parser):
209 """ 372 """
210 Set the command line arguments for tdc. 373 Set the command line arguments for tdc.
211 """ 374 """
212 parser.add_argument('-p', '--path', type=str, 375 parser.add_argument(
213 help='The full path to the tc executable to use') 376 '-p', '--path', type=str,
214 parser.add_argument('-c', '--category', type=str, nargs='?', const='+c', 377 help='The full path to the tc executable to use')
215 help='Run tests only from the specified category, or if no category is specified, list known categories.') 378 sg = parser.add_argument_group(
216 parser.add_argument('-f', '--file', type=str, 379 'selection', 'select which test cases: ' +
217 help='Run tests from the specified file') 380 'files plus directories; filtered by categories plus testids')
218 parser.add_argument('-l', '--list', type=str, nargs='?', const="++", metavar='CATEGORY', 381 ag = parser.add_argument_group(
219 help='List all test cases, or those only within the specified category') 382 'action', 'select action to perform on selected test cases')
220 parser.add_argument('-s', '--show', type=str, nargs=1, metavar='ID', dest='showID', 383
221 help='Display the test case with specified id') 384 sg.add_argument(
222 parser.add_argument('-e', '--execute', type=str, nargs=1, metavar='ID', 385 '-D', '--directory', nargs='+', metavar='DIR',
223 help='Execute the single test case with specified ID') 386 help='Collect tests from the specified directory(ies) ' +
224 parser.add_argument('-i', '--id', action='store_true', dest='gen_id', 387 '(default [tc-tests])')
225 help='Generate ID numbers for new test cases') 388 sg.add_argument(
389 '-f', '--file', nargs='+', metavar='FILE',
390 help='Run tests from the specified file(s)')
391 sg.add_argument(
392 '-c', '--category', nargs='*', metavar='CATG', default=['+c'],
393 help='Run tests only from the specified category/ies, ' +
394 'or if no category/ies is/are specified, list known categories.')
395 sg.add_argument(
396 '-e', '--execute', nargs='+', metavar='ID',
397 help='Execute the specified test cases with specified IDs')
398 ag.add_argument(
399 '-l', '--list', action='store_true',
400 help='List all test cases, or those only within the specified category')
401 ag.add_argument(
402 '-s', '--show', action='store_true', dest='showID',
403 help='Display the selected test cases')
404 ag.add_argument(
405 '-i', '--id', action='store_true', dest='gen_id',
406 help='Generate ID numbers for new test cases')
407 parser.add_argument(
408 '-v', '--verbose', action='count', default=0,
409 help='Show the commands that are being run')
410 parser.add_argument(
411 '-N', '--notap', action='store_true',
412 help='Suppress tap results for command under test')
226 parser.add_argument('-d', '--device', 413 parser.add_argument('-d', '--device',
227 help='Execute the test case in flower category') 414 help='Execute the test case in flower category')
415 parser.add_argument(
416 '-P', '--pause', action='store_true',
417 help='Pause execution just before post-suite stage')
228 return parser 418 return parser
229 419
230 420
231def check_default_settings(args): 421def check_default_settings(args, remaining, pm):
232 """ 422 """
233 Process any arguments overriding the default settings, and ensure the 423 Process any arguments overriding the default settings,
234 settings are correct. 424 and ensure the settings are correct.
235 """ 425 """
236 # Allow for overriding specific settings 426 # Allow for overriding specific settings
237 global NAMES 427 global NAMES
238 428
239 if args.path != None: 429 if args.path != None:
240 NAMES['TC'] = args.path 430 NAMES['TC'] = args.path
241 if args.device != None: 431 if args.device != None:
242 NAMES['DEV2'] = args.device 432 NAMES['DEV2'] = args.device
243 if not os.path.isfile(NAMES['TC']): 433 if not os.path.isfile(NAMES['TC']):
244 print("The specified tc path " + NAMES['TC'] + " does not exist.") 434 print("The specified tc path " + NAMES['TC'] + " does not exist.")
245 exit(1) 435 exit(1)
246 436
437 pm.call_check_args(args, remaining)
438
247 439
248def get_id_list(alltests): 440def get_id_list(alltests):
249 """ 441 """
@@ -277,7 +469,7 @@ def generate_case_ids(alltests):
277 for c in alltests: 469 for c in alltests:
278 if (c["id"] == ""): 470 if (c["id"] == ""):
279 while True: 471 while True:
280 newid = str('%04x' % random.randrange(16**4)) 472 newid = str('{:04x}'.format(random.randrange(16**4)))
281 if (does_id_exist(alltests, newid)): 473 if (does_id_exist(alltests, newid)):
282 continue 474 continue
283 else: 475 else:
@@ -300,40 +492,107 @@ def generate_case_ids(alltests):
300 json.dump(testlist, outfile, indent=4) 492 json.dump(testlist, outfile, indent=4)
301 outfile.close() 493 outfile.close()
302 494
495def filter_tests_by_id(args, testlist):
496 '''
497 Remove tests from testlist that are not in the named id list.
498 If id list is empty, return empty list.
499 '''
500 newlist = list()
501 if testlist and args.execute:
502 target_ids = args.execute
503
504 if isinstance(target_ids, list) and (len(target_ids) > 0):
505 newlist = list(filter(lambda x: x['id'] in target_ids, testlist))
506 return newlist
507
508def filter_tests_by_category(args, testlist):
509 '''
510 Remove tests from testlist that are not in a named category.
511 '''
512 answer = list()
513 if args.category and testlist:
514 test_ids = list()
515 for catg in set(args.category):
516 if catg == '+c':
517 continue
518 print('considering category {}'.format(catg))
519 for tc in testlist:
520 if catg in tc['category'] and tc['id'] not in test_ids:
521 answer.append(tc)
522 test_ids.append(tc['id'])
523
524 return answer
303 525
304def get_test_cases(args): 526def get_test_cases(args):
305 """ 527 """
306 If a test case file is specified, retrieve tests from that file. 528 If a test case file is specified, retrieve tests from that file.
307 Otherwise, glob for all json files in subdirectories and load from 529 Otherwise, glob for all json files in subdirectories and load from
308 each one. 530 each one.
531 Also, if requested, filter by category, and add tests matching
532 certain ids.
309 """ 533 """
310 import fnmatch 534 import fnmatch
311 if args.file != None: 535
312 if not os.path.isfile(args.file): 536 flist = []
313 print("The specified test case file " + args.file + " does not exist.") 537 testdirs = ['tc-tests']
314 exit(1) 538
315 flist = [args.file] 539 if args.file:
316 else: 540 # at least one file was specified - remove the default directory
317 flist = [] 541 testdirs = []
318 for root, dirnames, filenames in os.walk('tc-tests'): 542
543 for ff in args.file:
544 if not os.path.isfile(ff):
545 print("IGNORING file " + ff + "\n\tBECAUSE does not exist.")
546 else:
547 flist.append(os.path.abspath(ff))
548
549 if args.directory:
550 testdirs = args.directory
551
552 for testdir in testdirs:
553 for root, dirnames, filenames in os.walk(testdir):
319 for filename in fnmatch.filter(filenames, '*.json'): 554 for filename in fnmatch.filter(filenames, '*.json'):
320 flist.append(os.path.join(root, filename)) 555 candidate = os.path.abspath(os.path.join(root, filename))
321 alltests = list() 556 if candidate not in testdirs:
557 flist.append(candidate)
558
559 alltestcases = list()
322 for casefile in flist: 560 for casefile in flist:
323 alltests = alltests + (load_from_file(casefile)) 561 alltestcases = alltestcases + (load_from_file(casefile))
324 return alltests 562
563 allcatlist = get_test_categories(alltestcases)
564 allidlist = get_id_list(alltestcases)
325 565
566 testcases_by_cats = get_categorized_testlist(alltestcases, allcatlist)
567 idtestcases = filter_tests_by_id(args, alltestcases)
568 cattestcases = filter_tests_by_category(args, alltestcases)
326 569
327def set_operation_mode(args): 570 cat_ids = [x['id'] for x in cattestcases]
571 if args.execute:
572 if args.category:
573 alltestcases = cattestcases + [x for x in idtestcases if x['id'] not in cat_ids]
574 else:
575 alltestcases = idtestcases
576 else:
577 if cat_ids:
578 alltestcases = cattestcases
579 else:
580 # just accept the existing value of alltestcases,
581 # which has been filtered by file/directory
582 pass
583
584 return allcatlist, allidlist, testcases_by_cats, alltestcases
585
586
587def set_operation_mode(pm, args):
328 """ 588 """
329 Load the test case data and process remaining arguments to determine 589 Load the test case data and process remaining arguments to determine
330 what the script should do for this run, and call the appropriate 590 what the script should do for this run, and call the appropriate
331 function. 591 function.
332 """ 592 """
333 alltests = get_test_cases(args) 593 ucat, idlist, testcases, alltests = get_test_cases(args)
334 594
335 if args.gen_id: 595 if args.gen_id:
336 idlist = get_id_list(alltests)
337 if (has_blank_ids(idlist)): 596 if (has_blank_ids(idlist)):
338 alltests = generate_case_ids(alltests) 597 alltests = generate_case_ids(alltests)
339 else: 598 else:
@@ -347,70 +606,29 @@ def set_operation_mode(args):
347 print("Please correct them before continuing.") 606 print("Please correct them before continuing.")
348 exit(1) 607 exit(1)
349 608
350 ucat = get_test_categories(alltests)
351
352 if args.showID: 609 if args.showID:
353 show_test_case_by_id(alltests, args.showID[0]) 610 for atest in alltests:
611 print_test_case(atest)
354 exit(0) 612 exit(0)
355 613
356 if args.execute: 614 if isinstance(args.category, list) and (len(args.category) == 0):
357 target_id = args.execute[0] 615 print("Available categories:")
358 else: 616 print_sll(ucat)
359 target_id = "" 617 exit(0)
360
361 if args.category:
362 if (args.category == '+c'):
363 print("Available categories:")
364 print_sll(ucat)
365 exit(0)
366 else:
367 target_category = args.category
368 else:
369 target_category = ""
370
371
372 testcases = get_categorized_testlist(alltests, ucat)
373 618
374 if args.list: 619 if args.list:
375 if (args.list == "++"): 620 if args.list:
376 list_test_cases(alltests) 621 list_test_cases(alltests)
377 exit(0) 622 exit(0)
378 elif(len(args.list) > 0):
379 if (args.list not in ucat):
380 print("Unknown category " + args.list)
381 print("Available categories:")
382 print_sll(ucat)
383 exit(1)
384 list_test_cases(testcases[args.list])
385 exit(0)
386
387 if (os.geteuid() != 0):
388 print("This script must be run with root privileges.\n")
389 exit(1)
390
391 ns_create()
392
393 if (len(target_category) == 0):
394 if (len(target_id) > 0):
395 alltests = list(filter(lambda x: target_id in x['id'], alltests))
396 if (len(alltests) == 0):
397 print("Cannot find a test case with ID matching " + target_id)
398 exit(1)
399 catresults = test_runner(alltests, args)
400 print("All test results: " + "\n\n" + catresults)
401 elif (len(target_category) > 0):
402 if (target_category == "flower") and args.device == None:
403 print("Please specify a NIC device (-d) to run category flower")
404 exit(1)
405 if (target_category not in ucat):
406 print("Specified category is not present in this file.")
407 exit(1)
408 else:
409 catresults = test_runner(testcases[target_category], args)
410 print("Category " + target_category + "\n\n" + catresults)
411
412 ns_destroy()
413 623
624 if len(alltests):
625 catresults = test_runner(pm, args, alltests)
626 else:
627 catresults = 'No tests found\n'
628 if args.notap:
629 print('Tap output suppression requested\n')
630 else:
631 print('All test results: \n\n{}'.format(catresults))
414 632
415def main(): 633def main():
416 """ 634 """
@@ -419,10 +637,15 @@ def main():
419 """ 637 """
420 parser = args_parse() 638 parser = args_parse()
421 parser = set_args(parser) 639 parser = set_args(parser)
640 pm = PluginMgr(parser)
641 parser = pm.call_add_args(parser)
422 (args, remaining) = parser.parse_known_args() 642 (args, remaining) = parser.parse_known_args()
423 check_default_settings(args) 643 args.NAMES = NAMES
644 check_default_settings(args, remaining, pm)
645 if args.verbose > 2:
646 print('args is {}'.format(args))
424 647
425 set_operation_mode(args) 648 set_operation_mode(pm, args)
426 649
427 exit(0) 650 exit(0)
428 651
diff --git a/tools/testing/selftests/tc-testing/tdc_batch.py b/tools/testing/selftests/tc-testing/tdc_batch.py
index 707c6bfef689..52fa539dc662 100755
--- a/tools/testing/selftests/tc-testing/tdc_batch.py
+++ b/tools/testing/selftests/tc-testing/tdc_batch.py
@@ -49,13 +49,13 @@ index = 0
49for i in range(0x100): 49for i in range(0x100):
50 for j in range(0x100): 50 for j in range(0x100):
51 for k in range(0x100): 51 for k in range(0x100):
52 mac = ("%02x:%02x:%02x" % (i, j, k)) 52 mac = ("{:02x}:{:02x}:{:02x}".format(i, j, k))
53 src_mac = "e4:11:00:" + mac 53 src_mac = "e4:11:00:" + mac
54 dst_mac = "e4:12:00:" + mac 54 dst_mac = "e4:12:00:" + mac
55 cmd = ("filter add dev %s %s protocol ip parent ffff: flower %s " 55 cmd = ("filter add dev {} {} protocol ip parent ffff: flower {} "
56 "src_mac %s dst_mac %s action drop %s" % 56 "src_mac {} dst_mac {} action drop {}".format
57 (device, prio, skip, src_mac, dst_mac, share_action)) 57 (device, prio, skip, src_mac, dst_mac, share_action))
58 file.write("%s\n" % cmd) 58 file.write("{}\n".format(cmd))
59 index += 1 59 index += 1
60 if index >= number: 60 if index >= number:
61 file.close() 61 file.close()
diff --git a/tools/testing/selftests/tc-testing/tdc_helper.py b/tools/testing/selftests/tc-testing/tdc_helper.py
index db381120a566..9f35c96c88a0 100644
--- a/tools/testing/selftests/tc-testing/tdc_helper.py
+++ b/tools/testing/selftests/tc-testing/tdc_helper.py
@@ -57,20 +57,11 @@ def print_sll(items):
57 57
58def print_test_case(tcase): 58def print_test_case(tcase):
59 """ Pretty-printing of a given test case. """ 59 """ Pretty-printing of a given test case. """
60 print('\n==============\nTest {}\t{}\n'.format(tcase['id'], tcase['name']))
60 for k in tcase.keys(): 61 for k in tcase.keys():
61 if (isinstance(tcase[k], list)): 62 if (isinstance(tcase[k], list)):
62 print(k + ":") 63 print(k + ":")
63 print_list(tcase[k]) 64 print_list(tcase[k])
64 else: 65 else:
65 print(k + ": " + tcase[k]) 66 if not ((k == 'id') or (k == 'name')):
66 67 print(k + ": " + str(tcase[k]))
67
68def show_test_case_by_id(testlist, caseID):
69 """ Find the specified test case to pretty-print. """
70 if not any(d.get('id', None) == caseID for d in testlist):
71 print("That ID does not exist.")
72 exit(1)
73 else:
74 print_test_case(next((d for d in testlist if d['id'] == caseID)))
75
76